[
  {
    "path": ".gitignore",
    "content": "# Logs\nlogs\n*.log\n\n# Runtime data\npids\n*.pid\n*.seed\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n\n# Dependency directory\n# Deployed apps should consider commenting this line out:\n# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git\nnode_modules\n\n\n.DS_Store\n\neditor/scripts/urdujs"
  },
  {
    "path": "CITATION.cff",
    "content": "cff-version: 1.2.0\nmessage: \"If you use this software, please cite it as below.\"\nauthors:\n  - family-names: Memon\n    given-names: Asad\ntitle: \"UrduScript\"\nversion: 1.0.0\ndate-released: 2019-08-24\n"
  },
  {
    "path": "LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2017 Asad Memon\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "README.md",
    "content": "# UrduScript\n\n![](docs/head.png?raw=true)\n\nUrduScript is an [Urdish](http://www.urbandictionary.com/define.php?term=Urdish) dialect of JavaScript. The goal is to make programming more accessible to beginners from South Asia. UrduScript uses informal Urdu analogies to programming concepts, making it easy to get started without remembering keywords.\n\nUrduScript transpiles to JavaScript. All JavaScript frameworks (like jQuery, UnderScore, React, etc) can be seemlessly used.\n\n### Hello World\n\n```js\n// declare variable\nrakho naam = \"Asad\"\n\n// output to console\nlikho(\"Hello, \" + naam)\n```\n\n[**Try it online here**](https://asadmemon.com/urduscript/editor/).\n\n### Installation (Web Editor)\nIf you want to run the web editor offline. Follow these steps:\n\n##### Prerequisites:\nIn order to run UrduScript on your computer, you need to install [Node.js](https://nodejs.org/en/download/) first. \n##### Installing (Windows):\n\n- Download zip or clone the repository\n\n- Inside your project directory, run:\n\n  ```sh\n  npm install\n  npm install -g nws\n  npm run windows\n  ```\n\n- Open your browser and type\n\n```js\nhttp://localhost:3030\n```\n##### Installing (MacOs, Ubuntu, Unix, etc):\n\n- Download zip or clone the repository\n- Inside your project directory, run:\n```sh\nnpm install\nnpm start\n```\n\n- Open your browser and type\n\n```js\nhttp://localhost:3030\n```\n\n### Contributing\n\nThis is an open project and I am open to all ideas and improvements. See [this page](https://asadmemon.com/urduscript/contribute).\n\n\n\n### Acknowledgments\n\n- Project is only possible due to [Sweet.js](https://github.com/sweet-js/sweet-core).\n- The online editor uses the wonderful [CodeMirror](https://github.com/codemirror/CodeMirror).\n- Special thanks to Ali Alavi, Osman Mian, Eric Bhatti for their help.\n"
  },
  {
    "path": "bin/urdujs.js",
    "content": "#!/usr/bin/env node\n\nvar argv = require('yargs')\n  .usage('Usage: urdujs [options] file')\n  .boolean(\"t\")\n  .alias('t', 'transpile')\n  .alias('o', 'out-file')\n  .alias('d', 'out-dir')\n  .describe('o', 'write output to file')\n  .describe('d', 'write output to directory')\n  .describe('t', 'only output the transpiled js code (only works when no output file defined)')\n  .nargs('out-file', 1)\n  .nargs('out-dir', 1)\n  //.nargs('transpile', 1)\n  .demand(1)\n  .help('h')\n  .alias('h', 'help')\n  .argv;\n\nvar path = require('path');\nvar fs   = require('fs');\n\n//console.log(__dirname + \"/../src/keywords\")\nvar urduHeadersPath = fs.realpathSync(__dirname + \"/../src/keywords.js\")\nvar urduHeaders = fs.readFileSync(urduHeadersPath, \"utf8\");\n\nvar compile = require('@sweet-js/core').compile;\nvar NodeLoader = require('@sweet-js/core/dist/node-loader').default;\n\nlet loaderOptions = {\n  noBabel: argv.noBabel,\n  logging: argv.outFile || argv.outDir\n};\n\nvar loader = new NodeLoader(process.cwd(), loaderOptions);\n\nargv._.forEach(function (file) {\n  // first add header file in the dir.\n  var fileStr = fs.realpathSync(file)\n  //fs.writeFileSync(path.dirname(fileStr) + \"/__urduHeaders.js\", urduHeaders, 'utf8');\n  //console.log(\"dir\", path.dirname(file))\n  \n  var output = compile(fileStr, loader, {\n    noBabel: argv.noBabel\n  }).code;\n\n  //remove the header file we added.\n  //fs.unlinkSync(path.dirname(fileStr) + \"/__urduHeaders.js\")\n\n  if (argv.outFile) {\n    fs.writeFileSync(argv.outFile, output, 'utf8');\n  } else if (argv.outDir) {\n    fs.writeFileSync(path.join(argv.outDir, path.basename(file)), output, 'utf8');\n  } else {\n    if (!argv.transpile){\n      eval(output)\n    }\n    else{\n      console.log(output);\n    }\n  }\n});\n"
  },
  {
    "path": "docs/README.md",
    "content": "# UrduScript - Urdu Mein Programming \n![](head.png?raw=true&t=4)\nUrduScript ek programming language hai. Iska goal naye programmers k liye programming ko asaan banana ha. UrduScript informal Urdu use karti hai jis se naye programmers k liye programming concepts asaan hojate hen.\n\nUrduScript transpile ho k JavaScript banjati hai. Apke saray JavaScript frameworks (jese jQuery, UnderScore, React, etc) iske saath use keeye jasakte hen.\n\n## Hello Dunya\n\n```js\n// declare variable\nrakho naam = \"Asad\"\n\n// output to console\nlikho(\"Hello, \" + naam)\n```\n\n\n\n### [Online Try Karen!](https://asadmemon.com/urduscript/editor/)\n\n## Kyun?\n\nIf you are an experienced programmer, you might find this stupid. Per ye apke liye nahin hai. \n\nRemember learning programming for the first time? Remember the analogy of `variable` being a box jis mein value rakhte hen. UrduScript is based on those analogies to the core. Removing friction for new programmers.\n\nLet me explain with an example, imagine explaining the following code to a very new learner:\n\n```js\nvar name = \"Ali\"\nconsole.log(\"Hello, \" + name)\n```\n\nYou will have to first convey the box analogy, then you will need to explain what a *console* is and what *log* is. And then finally how we concat the output.\n\nThis is the UrduScript equivalent:\n\n```js\nrakho naam = \"Ali\"\nlikho(\"Hello, \" + naam)\n```\n\nImagine explaining this to a new programmer, when you explain the variable/box analogy, `rakho` fits right in. \nie. We are making a box called `naam` and usmein `\"Ali\"` rakhrahe hen.\n\n`likho()` is also pretty self-explanatory too.\n\nYou get the idea. UrduScript is based on this concept.\n\n## Pure اردو kyu nahin?\n\nAs much as I wanted to. Here are few reasons:\n\n- Persian-like alphabets are not native to our keyboard.\n- The default non-nastaliq font is hard to read.\n- Right-to-left code style is horrible.\n- Newer generation is adapting Urdish rapidly. \n\n\nTo prove my point, here is a RTL pseudo-code hello world:\n\n<img src=\"rtl1.png\" width=\"400\">\n\nSee what I mean? The font is bad. RTL is hard to understand. Also typing this was less natural than Urdish:\n\n<img src=\"ltr1.png\" width=\"400\">\n\n\n## Other Examples\n\n### For Each\n\n```js\n// variable\nrakho list = [\"Ahmed\", \"Ali\", \"Qasim\"]\n\n// foreach loop. Iterate over 'list' array\nhar list k naam per{\n  // output to screen\n  likho(naam)\n}\n```\n\n### If-Else\n\n```js\n// declare variable\nrakho naam = \"Asad\"\n\n// if else\nagar (naam){\n  likho(\"Salam, \" + naam)\n}\nwarna {\n  likho(\"Naam khali hai\")\n}\n```\n\n### Prompt\n\n```js\n//prompt: ask for input from user\nrakho naam = pucho(\"Apna naam likhen\")\n\n// if else\nagar (naam){\n  likho(\"Salam, \" + naam)\n}\nwarna {\n  likho(\"Naam khali hai\")\n}\n```\n\n### Function\n\n```js\n// function is 'kaam'\nkaam salaam(naam){\n\tagar (naam){\n    likho(\"Salam, \" + naam)\n  }\n  warna {\n    likho(\"Naam khali hai\")\n  }\n}\n\n// calling function\nsalaam(\"Ali\")\n```\n\n### While\n\n```js\n// declare a variable\nrakho a = 10\n\n// while is 'jabtak'\njabtak( a>0 ){\n\tlikho(a)\n\ta--\n}\n```\n\n### Do-While\n\n```js\n// ask age until given\nkaro{\n  age = pucho(\"Apni age likhen\")\n}\njabtak(!age)\nlikho(\"Apki age \" + age + \" hai\")\n```\n\n\n### If-Elseif-Else\n\n```js\n// declare variable\nrakho naam = \"Asad\"\n\n// if elseif else\nagar (naam === \"Asad\"){\n  likho(\"Salam, \" + naam)\n}\nwarnaagar (naam === \"John\"){\n  likho(\"Hello, \" + naam)\n}\nwarna {\n  likho(\"Naam khali hai\")\n}\n```\n\n### Recursion (Fibonacci)\n```js\n// recursive function\nkaam fibonacci(num) {\n  // base case\n  agar (num <= 1) bhejo 1;\n\t\n  // recursion\n  bhejo fibonacci(num - 1) + fibonacci(num - 2);\n}\n\nlikho(fibonacci(5))\n```\n\n\n## Contribute\n\nYou can contribute even if you think you are not a programmer. Please read [this guide](contribute).\n\nHere are some contributors of the language:\n\n- Ali Alavi\n- Eric Bhatti\n- Azka Qaiser\n- Junaid Sarfraz\n- Mehmood Memon\n- Pavan Kumar\n- Muhammad Asif\n- Ahmed Jawed\n- Harris Irfan\n- Zayn-ul-abdin\n- Mubashar Iqbal\n- M Shaharyar Siddiqui\n- Areeba\n- Ahmer\n- Muhammad Zaid Ikhlas\n- Mian Asad\n- Junaid Nadeem\n- Shahan\n- Muhammad Noman\n- Ahsan Sohail\n- Majid Razvi\n- Hammad Siddiqui\n\n## [Source Code](https://github.com/asadm/urduscript)\n\nI have released the [code](https://github.com/asadm/urduscript) under MIT License. ⭐ the repo while you are there :P\n\nThe transpiler is written in JavaScript using [Sweet.js](https://github.com/sweet-js/sweet-core)."
  },
  {
    "path": "docs/_config.yml",
    "content": "theme: jekyll-theme-minimal\ntitle: UrduScript\ndescription: JavaScript ka Urdish dialect.\n\ngems:\n  - jekyll-seo-tag\n\nlogo: 'head.png'\n\ndefaults:\n  - scope:\n      path: \"\"\n    values:\n      image: 'head.png'"
  },
  {
    "path": "docs/contribute.md",
    "content": "# Contributing\n\nThe goal of UrduScript is to make programming more accessible to beginners from South Asia. \n\nThere are two ways to contribute.\n\n## Contribute to Grammar\n\nUrduScript uses informal Urdu analogies to programming concepts, making it easy to get started without remembering keywords.\n\nWith that in mind. If you have suggestion for a keyword (Like \"true\" should be \"sach\"). Please [record it here](https://goo.gl/forms/2yU3xylEoKAQZrbG2). I will add your name to the contributors if I use your suggestion. Thanks!\n\n\n\n## Contribute to Code\n\nThe [code](https://github.com/asadm/urduscript) is a proof of concept right now. I will put up more instructions on how things work. This section is *TODO*"
  },
  {
    "path": "docs/editor/addon/edit/matchbrackets.js",
    "content": "// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n  if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n    mod(require(\"../../lib/codemirror\"));\n  else if (typeof define == \"function\" && define.amd) // AMD\n    define([\"../../lib/codemirror\"], mod);\n  else // Plain browser env\n    mod(CodeMirror);\n})(function(CodeMirror) {\n  var ie_lt8 = /MSIE \\d/.test(navigator.userAgent) &&\n    (document.documentMode == null || document.documentMode < 8);\n\n  var Pos = CodeMirror.Pos;\n\n  var matching = {\"(\": \")>\", \")\": \"(<\", \"[\": \"]>\", \"]\": \"[<\", \"{\": \"}>\", \"}\": \"{<\"};\n\n  function findMatchingBracket(cm, where, config) {\n    var line = cm.getLineHandle(where.line), pos = where.ch - 1;\n    var afterCursor = config && config.afterCursor\n    if (afterCursor == null)\n      afterCursor = /(^| )cm-fat-cursor($| )/.test(cm.getWrapperElement().className)\n\n    // A cursor is defined as between two characters, but in in vim command mode\n    // (i.e. not insert mode), the cursor is visually represented as a\n    // highlighted box on top of the 2nd character. Otherwise, we allow matches\n    // from before or after the cursor.\n    var match = (!afterCursor && pos >= 0 && matching[line.text.charAt(pos)]) ||\n        matching[line.text.charAt(++pos)];\n    if (!match) return null;\n    var dir = match.charAt(1) == \">\" ? 1 : -1;\n    if (config && config.strict && (dir > 0) != (pos == where.ch)) return null;\n    var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));\n\n    var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);\n    if (found == null) return null;\n    return {from: Pos(where.line, pos), to: found && found.pos,\n            match: found && found.ch == match.charAt(0), forward: dir > 0};\n  }\n\n  // bracketRegex is used to specify which type of bracket to scan\n  // should be a regexp, e.g. /[[\\]]/\n  //\n  // Note: If \"where\" is on an open bracket, then this bracket is ignored.\n  //\n  // Returns false when no bracket was found, null when it reached\n  // maxScanLines and gave up\n  function scanForBracket(cm, where, dir, style, config) {\n    var maxScanLen = (config && config.maxScanLineLength) || 10000;\n    var maxScanLines = (config && config.maxScanLines) || 1000;\n\n    var stack = [];\n    var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\\]]/;\n    var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1)\n                          : Math.max(cm.firstLine() - 1, where.line - maxScanLines);\n    for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) {\n      var line = cm.getLine(lineNo);\n      if (!line) continue;\n      var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1;\n      if (line.length > maxScanLen) continue;\n      if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);\n      for (; pos != end; pos += dir) {\n        var ch = line.charAt(pos);\n        if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) {\n          var match = matching[ch];\n          if ((match.charAt(1) == \">\") == (dir > 0)) stack.push(ch);\n          else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};\n          else stack.pop();\n        }\n      }\n    }\n    return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null;\n  }\n\n  function matchBrackets(cm, autoclear, config) {\n    // Disable brace matching in long lines, since it'll cause hugely slow updates\n    var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;\n    var marks = [], ranges = cm.listSelections();\n    for (var i = 0; i < ranges.length; i++) {\n      var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, config);\n      if (match && cm.getLine(match.from.line).length <= maxHighlightLen) {\n        var style = match.match ? \"CodeMirror-matchingbracket\" : \"CodeMirror-nonmatchingbracket\";\n        marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));\n        if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen)\n          marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style}));\n      }\n    }\n\n    if (marks.length) {\n      // Kludge to work around the IE bug from issue #1193, where text\n      // input stops going to the textare whever this fires.\n      if (ie_lt8 && cm.state.focused) cm.focus();\n\n      var clear = function() {\n        cm.operation(function() {\n          for (var i = 0; i < marks.length; i++) marks[i].clear();\n        });\n      };\n      if (autoclear) setTimeout(clear, 800);\n      else return clear;\n    }\n  }\n\n  var currentlyHighlighted = null;\n  function doMatchBrackets(cm) {\n    cm.operation(function() {\n      if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}\n      currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);\n    });\n  }\n\n  CodeMirror.defineOption(\"matchBrackets\", false, function(cm, val, old) {\n    if (old && old != CodeMirror.Init) {\n      cm.off(\"cursorActivity\", doMatchBrackets);\n      if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}\n    }\n    if (val) {\n      cm.state.matchBrackets = typeof val == \"object\" ? val : {};\n      cm.on(\"cursorActivity\", doMatchBrackets);\n    }\n  });\n\n  CodeMirror.defineExtension(\"matchBrackets\", function() {matchBrackets(this, true);});\n  CodeMirror.defineExtension(\"findMatchingBracket\", function(pos, config, oldConfig){\n    // Backwards-compatibility kludge\n    if (oldConfig || typeof config == \"boolean\") {\n      if (!oldConfig) {\n        config = config ? {strict: true} : null\n      } else {\n        oldConfig.strict = config\n        config = oldConfig\n      }\n    }\n    return findMatchingBracket(this, pos, config)\n  });\n  CodeMirror.defineExtension(\"scanForBracket\", function(pos, dir, style, config){\n    return scanForBracket(this, pos, dir, style, config);\n  });\n});\n"
  },
  {
    "path": "docs/editor/css/base16-light.css",
    "content": "/*\n\n    Name:       Base16 Default Light\n    Author:     Chris Kempson (http://chriskempson.com)\n\n    CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-chrome-devtools)\n    Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)\n\n*/\n\n/* based on https://raw.githubusercontent.com/FarhadG/code-mirror-themes/master/themes/chrome-devtools.css */\n.cm-s-base16-light.CodeMirror {background: #f5f5f5; color: #202020;}\n.cm-s-base16-light div.CodeMirror-selected {background: #e0e0e0 !important;}\n.cm-s-base16-light .CodeMirror-gutters {background: #f5f5f5; border-right: 0px;}\n.cm-s-base16-light .CodeMirror-linenumber {color: #b0b0b0;}\n.cm-s-base16-light .CodeMirror-cursor {border-left: 1px solid #505050 !important;}\n\n.cm-s-base16-light span.cm-comment {color: #8f5536;}\n.cm-s-base16-light span.cm-atom {color: #aa759f;}\n.cm-s-base16-light span.cm-number {color: #aa759f;}\n\n.cm-s-base16-light span.cm-property, .cm-s-base16-light span.cm-attribute {color: #90a959;}\n.cm-s-base16-light span.cm-keyword {color: #ac4142;}\n.cm-s-base16-light span.cm-string {color: #F0A742;}\n\n.cm-s-base16-light span.cm-variable {color: #7D944C;}\n.cm-s-base16-light span.cm-variable-2 {color: #6a9fb5;}\n.cm-s-base16-light span.cm-def {color: #d28445;}\n.cm-s-base16-light span.cm-bracket {color: #202020;}\n.cm-s-base16-light span.cm-tag {color: #ac4142;}\n.cm-s-base16-light span.cm-link {color: #aa759f;}\n.cm-s-base16-light span.cm-error {background: #ac4142; color: #505050;}\n\n.cm-s-base16-light .CodeMirror-activeline-background {background: #DDDCDC !important;}\n.cm-s-base16-light .CodeMirror-matchingbracket { text-decoration: underline; color: #ff00ff !important;}\n\n/* Based on Sublime Text's Monokai theme */\n\nbody.invert .cm-s-base16-light.CodeMirror {background: rgb(22,23,25); color: #f8f8f2;}\nbody.invert .cm-s-base16-light div.CodeMirror-selected {background: #49483E !important;}\nbody.invert .cm-s-base16-light .CodeMirror-gutters {background: rgb(22,23,25); border-right: 0px;}\nbody.invert .cm-s-base16-light .CodeMirror-linenumber {color: #484848;}\nbody.invert .cm-s-base16-light .CodeMirror-cursor {border-left: 1px solid #f8f8f0 !important;}\n\nbody.invert .cm-s-base16-light span.cm-comment {color: #75715e;}\nbody.invert .cm-s-base16-light span.cm-atom {color: #ae81ff;}\nbody.invert .cm-s-base16-light span.cm-number {color: #ae81ff;}\n\nbody.invert .cm-s-base16-light span.cm-property,body.invert .cm-s-base16-light span.cm-attribute {color: #a6e22e;}\nbody.invert .cm-s-base16-light span.cm-keyword {color: #f92672;}\nbody.invert .cm-s-base16-light span.cm-string {color: #e6db74;}\n\nbody.invert .cm-s-base16-light span.cm-variable {color: #a6e22e;}\nbody.invert .cm-s-base16-light span.cm-variable-2 {color: #9effff;}\nbody.invert .cm-s-base16-light span.cm-def {color: #fd971f;}\nbody.invert .cm-s-base16-light span.cm-bracket {color: #f8f8f2;}\nbody.invert .cm-s-base16-light span.cm-tag {color: #f92672;}\nbody.invert .cm-s-base16-light span.cm-link {color: #ae81ff;}\nbody.invert .cm-s-base16-light span.cm-error {background: #f92672; color: #f8f8f0;}\n\nbody.invert .cm-s-base16-light .CodeMirror-activeline-background {background: #373831 !important;}\nbody.invert .cm-s-base16-light .CodeMirror-matchingbracket {\n  text-decoration: underline;\n  color: white !important;\n}\n"
  },
  {
    "path": "docs/editor/css/codemirror.css",
    "content": "/* BASICS */\n\n.CodeMirror {\n  /* Set height, width, borders, and global font properties here */\n  font-family: monospace;\n  height: 300px;\n  color: black;\n}\n\n/* PADDING */\n\n.CodeMirror-lines {\n  padding: 4px 0; /* Vertical padding around content */\n}\n.CodeMirror pre {\n  padding: 0 4px; /* Horizontal padding of content */\n}\n\n.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {\n  background-color: white; /* The little square between H and V scrollbars */\n}\n\n/* GUTTER */\n\n.CodeMirror-gutters {\n  border-right: 1px solid #ddd;\n  background-color: #f7f7f7;\n  white-space: nowrap;\n}\n.CodeMirror-linenumbers {}\n.CodeMirror-linenumber {\n  padding: 0 3px 0 5px;\n  min-width: 20px;\n  text-align: right;\n  color: #999;\n  white-space: nowrap;\n}\n\n.CodeMirror-guttermarker { color: black; }\n.CodeMirror-guttermarker-subtle { color: #999; }\n\n/* CURSOR */\n\n.CodeMirror-cursor {\n  border-left: 1px solid black;\n  border-right: none;\n  width: 0;\n}\n/* Shown when moving in bi-directional text */\n.CodeMirror div.CodeMirror-secondarycursor {\n  border-left: 1px solid silver;\n}\n.cm-fat-cursor .CodeMirror-cursor {\n  width: auto;\n  border: 0 !important;\n  background: #7e7;\n}\n.cm-fat-cursor div.CodeMirror-cursors {\n  z-index: 1;\n}\n\n.cm-animate-fat-cursor {\n  width: auto;\n  border: 0;\n  -webkit-animation: blink 1.06s steps(1) infinite;\n  -moz-animation: blink 1.06s steps(1) infinite;\n  animation: blink 1.06s steps(1) infinite;\n  background-color: #7e7;\n}\n@-moz-keyframes blink {\n  0% {}\n  50% { background-color: transparent; }\n  100% {}\n}\n@-webkit-keyframes blink {\n  0% {}\n  50% { background-color: transparent; }\n  100% {}\n}\n@keyframes blink {\n  0% {}\n  50% { background-color: transparent; }\n  100% {}\n}\n\n/* Can style cursor different in overwrite (non-insert) mode */\n.CodeMirror-overwrite .CodeMirror-cursor {}\n\n.cm-tab { display: inline-block; text-decoration: inherit; }\n\n.CodeMirror-rulers {\n  position: absolute;\n  left: 0; right: 0; top: -50px; bottom: -20px;\n  overflow: hidden;\n}\n.CodeMirror-ruler {\n  border-left: 1px solid #ccc;\n  top: 0; bottom: 0;\n  position: absolute;\n}\n\n/* DEFAULT THEME */\n\n.cm-s-default .cm-header {color: blue;}\n.cm-s-default .cm-quote {color: #090;}\n.cm-negative {color: #d44;}\n.cm-positive {color: #292;}\n.cm-header, .cm-strong {font-weight: bold;}\n.cm-em {font-style: italic;}\n.cm-link {text-decoration: underline;}\n.cm-strikethrough {text-decoration: line-through;}\n\n.cm-s-default .cm-keyword {color: #708;}\n.cm-s-default .cm-atom {color: #219;}\n.cm-s-default .cm-number {color: #164;}\n.cm-s-default .cm-def {color: #00f;}\n.cm-s-default .cm-variable,\n.cm-s-default .cm-punctuation,\n.cm-s-default .cm-property,\n.cm-s-default .cm-operator {}\n.cm-s-default .cm-variable-2 {color: #05a;}\n.cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;}\n.cm-s-default .cm-comment {color: #a50;}\n.cm-s-default .cm-string {color: #a11;}\n.cm-s-default .cm-string-2 {color: #f50;}\n.cm-s-default .cm-meta {color: #555;}\n.cm-s-default .cm-qualifier {color: #555;}\n.cm-s-default .cm-builtin {color: #30a;}\n.cm-s-default .cm-bracket {color: #997;}\n.cm-s-default .cm-tag {color: #170;}\n.cm-s-default .cm-attribute {color: #00c;}\n.cm-s-default .cm-hr {color: #999;}\n.cm-s-default .cm-link {color: #00c;}\n\n.cm-s-default .cm-error {color: #f00;}\n.cm-invalidchar {color: #f00;}\n\n.CodeMirror-composing { border-bottom: 2px solid; }\n\n/* Default styles for common addons */\n\ndiv.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}\ndiv.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}\n.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }\n.CodeMirror-activeline-background {background: #e8f2ff;}\n\n/* STOP */\n\n/* The rest of this file contains styles related to the mechanics of\n   the editor. You probably shouldn't touch them. */\n\n.CodeMirror {\n  position: relative;\n  overflow: hidden;\n  background: white;\n}\n\n.CodeMirror-scroll {\n  overflow: scroll !important; /* Things will break if this is overridden */\n  /* 30px is the magic margin used to hide the element's real scrollbars */\n  /* See overflow: hidden in .CodeMirror */\n  margin-bottom: -30px; margin-right: -30px;\n  padding-bottom: 30px;\n  height: 100%;\n  outline: none; /* Prevent dragging from highlighting the element */\n  position: relative;\n}\n.CodeMirror-sizer {\n  position: relative;\n  border-right: 30px solid transparent;\n}\n\n/* The fake, visible scrollbars. Used to force redraw during scrolling\n   before actual scrolling happens, thus preventing shaking and\n   flickering artifacts. */\n.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {\n  position: absolute;\n  z-index: 6;\n  display: none;\n}\n.CodeMirror-vscrollbar {\n  right: 0; top: 0;\n  overflow-x: hidden;\n  overflow-y: scroll;\n}\n.CodeMirror-hscrollbar {\n  bottom: 0; left: 0;\n  overflow-y: hidden;\n  overflow-x: scroll;\n}\n.CodeMirror-scrollbar-filler {\n  right: 0; bottom: 0;\n}\n.CodeMirror-gutter-filler {\n  left: 0; bottom: 0;\n}\n\n.CodeMirror-gutters {\n  position: absolute; left: 0; top: 0;\n  min-height: 100%;\n  z-index: 3;\n}\n.CodeMirror-gutter {\n  white-space: normal;\n  height: 100%;\n  display: inline-block;\n  vertical-align: top;\n  margin-bottom: -30px;\n}\n.CodeMirror-gutter-wrapper {\n  position: absolute;\n  z-index: 4;\n  background: none !important;\n  border: none !important;\n}\n.CodeMirror-gutter-background {\n  position: absolute;\n  top: 0; bottom: 0;\n  z-index: 4;\n}\n.CodeMirror-gutter-elt {\n  position: absolute;\n  cursor: default;\n  z-index: 4;\n}\n.CodeMirror-gutter-wrapper ::selection { background-color: transparent }\n.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }\n\n.CodeMirror-lines {\n  cursor: text;\n  min-height: 1px; /* prevents collapsing before first draw */\n}\n.CodeMirror pre {\n  /* Reset some styles that the rest of the page might have set */\n  -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;\n  border-width: 0;\n  background: transparent;\n  font-family: inherit;\n  font-size: inherit;\n  margin: 0;\n  white-space: pre;\n  word-wrap: normal;\n  line-height: inherit;\n  color: inherit;\n  z-index: 2;\n  position: relative;\n  overflow: visible;\n  -webkit-tap-highlight-color: transparent;\n  -webkit-font-variant-ligatures: contextual;\n  font-variant-ligatures: contextual;\n}\n.CodeMirror-wrap pre {\n  word-wrap: break-word;\n  white-space: pre-wrap;\n  word-break: normal;\n}\n\n.CodeMirror-linebackground {\n  position: absolute;\n  left: 0; right: 0; top: 0; bottom: 0;\n  z-index: 0;\n}\n\n.CodeMirror-linewidget {\n  position: relative;\n  z-index: 2;\n  overflow: auto;\n}\n\n.CodeMirror-widget {}\n\n.CodeMirror-rtl pre { direction: rtl; }\n\n.CodeMirror-code {\n  outline: none;\n}\n\n/* Force content-box sizing for the elements where we expect it */\n.CodeMirror-scroll,\n.CodeMirror-sizer,\n.CodeMirror-gutter,\n.CodeMirror-gutters,\n.CodeMirror-linenumber {\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n}\n\n.CodeMirror-measure {\n  position: absolute;\n  width: 100%;\n  height: 0;\n  overflow: hidden;\n  visibility: hidden;\n}\n\n.CodeMirror-cursor {\n  position: absolute;\n  pointer-events: none;\n}\n.CodeMirror-measure pre { position: static; }\n\ndiv.CodeMirror-cursors {\n  visibility: hidden;\n  position: relative;\n  z-index: 3;\n}\ndiv.CodeMirror-dragcursors {\n  visibility: visible;\n}\n\n.CodeMirror-focused div.CodeMirror-cursors {\n  visibility: visible;\n}\n\n.CodeMirror-selected { background: #d9d9d9; }\n.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }\n.CodeMirror-crosshair { cursor: crosshair; }\n.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }\n.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }\n\n.cm-searching {\n  background: #ffa;\n  background: rgba(255, 255, 0, .4);\n}\n\n/* Used to force a border model for a node */\n.cm-force-border { padding-right: .1px; }\n\n@media print {\n  /* Hide the cursor when printing */\n  .CodeMirror div.CodeMirror-cursors {\n    visibility: hidden;\n  }\n}\n\n/* See issue #2901 */\n.cm-tab-wrap-hack:after { content: ''; }\n\n/* Help users use markselection to safely style text background */\nspan.CodeMirror-selectedtext { background: none; }"
  },
  {
    "path": "docs/editor/css/style.css",
    "content": "body {\n  font-family: Droid Sans, Arial, sans-serif;\n  line-height: 1.5;\n  /*max-width: 64.3em;*/\n}\n.CodeMirror {\n  font-family: Menlo, 'Source Code Pro', monospace;\n  font-size: 15px;\n  height: 100%;\n}\n\n#options {\n  position: absolute;\n  font-size: 14px;\n  font-family: Droid Sans, Arial, sans-serif;\n  line-height: 1.5;\n  top: 20px;\n  right: 40px;\n  z-index: 1;\n\n}\n\n#header {\n  color: #fff;\n  background-color: #000;\n  position: absolute;\n  bottom: 0;\n  right: 50%;\n  left: 0;\n  height: 40px;\n  \n  \n  \n  font-family: 'Lato',Helvetica Neue,Helvetica,Arial,sans-serif;\n  font-weight: 300;\n  padding-left: 20px;\n}\n\n#header span{\n  display: inline-block;\n  margin-top: 7px;\n}\n\n#controls {\n  color: #fff;\n  background-color: #000;\n  position: absolute;;\n  height: 40px;\n  right: 0;\n  bottom: 0;\n  left: 50%;\n\n}\n\n#errors {\n  color: red;\n  position: absolute;\n  background-color: white;\n  /*right: 10;*/\n  z-index: 10;\n  bottom: 10;\n  /*left: 50%;*/\n  /*padding-top: 20px;*/\n  /*padding-left: 55px;*/\n  padding: 10px;\n}\n\n#edit-box {\n  position: absolute;\n  top: 0px;\n  right: 50%;\n  bottom: 40px;\n  left: 0;\n  border-right: 1px solid #000;\n}\n#output-box {\n  position: absolute;\n  top: 0px;\n  right: 0;\n  bottom: 40px;\n  left: 50%;\n}\n\n\n/* Small Devices, Tablets */\n@media only screen and (max-width : 768px) {\n  #edit-box{\n    right: 0;\n    bottom: 30%;\n    border-bottom: 1px solid #000;\n    border-right: 0px;\n  }\n\n  #output-box{\n    top: 70%;\n    bottom: 40px;\n    left: 0;\n  }\n\n  #header{\n    right: 0;\n    padding-left: 0;\n  }\n  #header span{\n    display: none;\n  }\n  #controls{\n    display: none;\n  }\n\n  #drop-examples{\n    margin-right: 10px;\n    margin-top: 8px;\n    float: right;\n  }\n}\n\n.btn {\n    display: inline-block;\n    padding: 6px 12px;\n    margin-bottom: 0;\n    font-size: 14px;\n    font-weight: 400;\n    line-height: 1.42857143;\n    text-align: center;\n    white-space: nowrap;\n    vertical-align: middle;\n    -ms-touch-action: manipulation;\n    touch-action: manipulation;\n    cursor: pointer;\n    -webkit-user-select: none;\n    -moz-user-select: none;\n    -ms-user-select: none;\n    user-select: none;\n    background-image: none;\n    border: 1px solid transparent;\n    border-radius: 4px;\n\n    box-shadow: none;\n    border: 1px solid rgba(0,0,0,.125);\n}\n\nbody.invert .btn-success {\n  color: #fff;\n  background-color: rgb(97, 152, 32);\n}\n\n#btn-run,\n#lbl-examples{\n  margin-left: 10px;\n}\n\n.btn-default{\n  color: #fff;\n  background-color: #000;\n  border: 1px solid #fff;\n}\n\n#chk-transpile{\n  margin-top: 15px;\n}\n\n#lbl-examples{\n  font-weight: bold;\n  font-size: 13px; \n  margin-right: 10px;\n}\n\n#drop-examples{\n  font-size: 14px;\n  min-width: 150px;\n}"
  },
  {
    "path": "docs/editor/index.html",
    "content": "<html>\n<head>\n  <meta charset=\"utf-8\">\n  <title>Play UrduScript</title>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1\">\n  <link href='https://fonts.googleapis.com/css?family=Lato:100,300' rel='stylesheet' type='text/css'>\n  <link href=\"https://fonts.googleapis.com/css?family=Source+Code+Pro:400,600\" rel=\"stylesheet\" type=\"text/css\"/>\n  <link rel=\"stylesheet\" href=\"css/codemirror.css\">\n  <link rel=\"stylesheet\" href=\"css/base16-light.css\">\n  <link rel=\"stylesheet\" href=\"css/style.css\">\n\n  <script src=\"scripts/jquery.js\"></script>\n  <script src=\"scripts/codemirror.js\"></script>\n  <script src=\"addon/edit/matchbrackets.js\"></script>\n  <script src=\"mode/urduscript/urduscript.js\"></script>\n  <script src=\"scripts/codes.js\"></script>\n  <script data-main=\"scripts/editor\" src=\"scripts/require.js\"></script>\n\n  <script>\n\t  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n\t  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\n\t  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n\t  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n\n\t  ga('create', 'UA-58030862-1', 'auto');\n\t  ga('send', 'pageview');\n\n\t</script>\n</head>\n<body class=\"invert\">\n\n<div id='header'>\n   <span>UrduScript</span>\n   <a id=\"btn-run\" class=\"btn btn-success\">Run</a>\n   <span id=\"lbl-examples\">Examples: </span>\n   <select id=\"drop-examples\">\n    \n  </select>\n   \n   \n</div>\n\n<div id=\"controls\">\n  <!--input id=\"btn-reset\" type=\"button\" class=\"btn btn-default\" value=\"Reset Code\"/-->\n  <input id=\"chk-transpile\" type=\"checkbox\" value=\"transpile\" /> Only output transpiled code.\n  \n  <!-- <input id=\"ck-builtin\" type=\"checkbox\" value=\"builtin\" /> include builtin macros -->\n</div>\n<pre id=\"errors\">\n  \n</pre>\n\n<div id='edit-box'>\n<textarea id=\"editor\">/*\nNeche UrduScript likhen. Code chalane k liye Run pe click karen.\n*/\n\n// variable\nrakho list = [\"Ahmed\", \"Ali\", \"Qasim\"]\n\n// loop (foreach)\nhar list k naam per{\n  // output to screen\n  likho(naam)\n}\n\n// function ko 'tareeka' kehte hen\ntareeka salam(naam){\n  likho(\"Salam, \" + naam)\n}\n\nsalam(\"Qasim\")\n\n</textarea>\n</div>\n\n<div id='output-box'>\n<textarea id=\"output\">//Output comes here</textarea>\n</div>\n\n\n</body>\n</html>\n"
  },
  {
    "path": "docs/editor/mode/javascript/index.html",
    "content": "<!doctype html>\n<html>\n  <head>\n    <meta charset=\"utf-8\">\n    <title>CodeMirror: JavaScript mode</title>\n    <link rel=\"stylesheet\" href=\"../../lib/codemirror.css\">\n    <script src=\"../../lib/codemirror.js\"></script>\n    <script src=\"../../addon/edit/matchbrackets.js\"></script>\n    <script src=\"../../addon/edit/continuecomment.js\"></script>\n    <script src=\"../../addon/comment/comment.js\"></script>\n    <script src=\"javascript.js\"></script>\n    <link rel=\"stylesheet\" href=\"../../doc/docs.css\">\n    <style type=\"text/css\">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>\n  </head>\n  <body>\n    <h1>CodeMirror: JavaScript mode</h1>\n\n<div><textarea id=\"code\" name=\"code\">\n// Demo code (the actual new parser character stream implementation)\n\nfunction StringStream(string) {\n  this.pos = 0;\n  this.string = string;\n}\n\nStringStream.prototype = {\n  done: function() {return this.pos >= this.string.length;},\n  peek: function() {return this.string.charAt(this.pos);},\n  next: function() {\n    if (this.pos &lt; this.string.length)\n      return this.string.charAt(this.pos++);\n  },\n  eat: function(match) {\n    var ch = this.string.charAt(this.pos);\n    if (typeof match == \"string\") var ok = ch == match;\n    else var ok = ch &amp;&amp; match.test ? match.test(ch) : match(ch);\n    if (ok) {this.pos++; return ch;}\n  },\n  eatWhile: function(match) {\n    var start = this.pos;\n    while (this.eat(match));\n    if (this.pos > start) return this.string.slice(start, this.pos);\n  },\n  backUp: function(n) {this.pos -= n;},\n  column: function() {return this.pos;},\n  eatSpace: function() {\n    var start = this.pos;\n    while (/\\s/.test(this.string.charAt(this.pos))) this.pos++;\n    return this.pos - start;\n  },\n  match: function(pattern, consume, caseInsensitive) {\n    if (typeof pattern == \"string\") {\n      function cased(str) {return caseInsensitive ? str.toLowerCase() : str;}\n      if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {\n        if (consume !== false) this.pos += str.length;\n        return true;\n      }\n    }\n    else {\n      var match = this.string.slice(this.pos).match(pattern);\n      if (match &amp;&amp; consume !== false) this.pos += match[0].length;\n      return match;\n    }\n  }\n};\n</textarea></div>\n\n    <script>\n      var editor = CodeMirror.fromTextArea(document.getElementById(\"code\"), {\n        lineNumbers: true,\n        matchBrackets: true,\n        continueComments: \"Enter\",\n        extraKeys: {\"Ctrl-Q\": \"toggleComment\"}\n      });\n    </script>\n\n    <p>\n      JavaScript mode supports a two configuration\n      options:\n      <ul>\n        <li><code>json</code> which will set the mode to expect JSON\n        data rather than a JavaScript program.</li>\n        <li><code>typescript</code> which will activate additional\n        syntax highlighting and some other things for TypeScript code\n        (<a href=\"typescript.html\">demo</a>).</li>\n        <li><code>statementIndent</code> which (given a number) will\n        determine the amount of indentation to use for statements\n        continued on a new line.</li>\n      </ul>\n    </p>\n\n    <p><strong>MIME types defined:</strong> <code>text/javascript</code>, <code>application/json</code>, <code>text/typescript</code>, <code>application/typescript</code>.</p>\n  </body>\n</html>\n"
  },
  {
    "path": "docs/editor/mode/javascript/javascript.js",
    "content": "// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n  if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n    mod(require(\"../../lib/codemirror\"));\n  else if (typeof define == \"function\" && define.amd) // AMD\n    define([\"../../lib/codemirror\"], mod);\n  else // Plain browser env\n    mod(CodeMirror);\n})(function(CodeMirror) {\n\"use strict\";\n\nfunction expressionAllowed(stream, state, backUp) {\n  return /^(?:operator|sof|keyword c|case|new|export|default|[\\[{}\\(,;:]|=>)$/.test(state.lastType) ||\n    (state.lastType == \"quasi\" && /\\{\\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))\n}\n\nCodeMirror.defineMode(\"javascript\", function(config, parserConfig) {\n  var indentUnit = config.indentUnit;\n  var statementIndent = parserConfig.statementIndent;\n  var jsonldMode = parserConfig.jsonld;\n  var jsonMode = parserConfig.json || jsonldMode;\n  var isTS = parserConfig.typescript;\n  var wordRE = parserConfig.wordCharacters || /[\\w$\\xa1-\\uffff]/;\n\n  // Tokenizer\n\n  var keywords = function(){\n    function kw(type) {return {type: type, style: \"keyword\"};}\n    var A = kw(\"keyword a\"), B = kw(\"keyword b\"), C = kw(\"keyword c\");\n    var operator = kw(\"operator\"), atom = {type: \"atom\", style: \"atom\"};\n\n    var jsKeywords = {\n      \"if\": kw(\"if\"), \"while\": A, \"with\": A, \"else\": B, \"do\": B, \"try\": B, \"finally\": B,\n      \"return\": C, \"break\": C, \"continue\": C, \"new\": kw(\"new\"), \"delete\": C, \"throw\": C, \"debugger\": C,\n      \"var\": kw(\"var\"), \"const\": kw(\"var\"), \"let\": kw(\"var\"),\n      \"function\": kw(\"function\"), \"catch\": kw(\"catch\"),\n      \"for\": kw(\"for\"), \"switch\": kw(\"switch\"), \"case\": kw(\"case\"), \"default\": kw(\"default\"),\n      \"in\": operator, \"typeof\": operator, \"instanceof\": operator,\n      \"true\": atom, \"false\": atom, \"null\": atom, \"undefined\": atom, \"NaN\": atom, \"Infinity\": atom,\n      \"this\": kw(\"this\"), \"class\": kw(\"class\"), \"super\": kw(\"atom\"),\n      \"yield\": C, \"export\": kw(\"export\"), \"import\": kw(\"import\"), \"extends\": C,\n      \"await\": C\n    };\n\n    // Extend the 'normal' keywords with the TypeScript language extensions\n    if (isTS) {\n      var type = {type: \"variable\", style: \"type\"};\n      var tsKeywords = {\n        // object-like things\n        \"interface\": kw(\"class\"),\n        \"implements\": C,\n        \"namespace\": C,\n        \"module\": kw(\"module\"),\n        \"enum\": kw(\"module\"),\n\n        // scope modifiers\n        \"public\": kw(\"modifier\"),\n        \"private\": kw(\"modifier\"),\n        \"protected\": kw(\"modifier\"),\n        \"abstract\": kw(\"modifier\"),\n\n        // types\n        \"string\": type, \"number\": type, \"boolean\": type, \"any\": type\n      };\n\n      for (var attr in tsKeywords) {\n        jsKeywords[attr] = tsKeywords[attr];\n      }\n    }\n\n    return jsKeywords;\n  }();\n\n  var isOperatorChar = /[+\\-*&%=<>!?|~^@]/;\n  var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)\"/;\n\n  function readRegexp(stream) {\n    var escaped = false, next, inSet = false;\n    while ((next = stream.next()) != null) {\n      if (!escaped) {\n        if (next == \"/\" && !inSet) return;\n        if (next == \"[\") inSet = true;\n        else if (inSet && next == \"]\") inSet = false;\n      }\n      escaped = !escaped && next == \"\\\\\";\n    }\n  }\n\n  // Used as scratch variables to communicate multiple values without\n  // consing up tons of objects.\n  var type, content;\n  function ret(tp, style, cont) {\n    type = tp; content = cont;\n    return style;\n  }\n  function tokenBase(stream, state) {\n    var ch = stream.next();\n    if (ch == '\"' || ch == \"'\") {\n      state.tokenize = tokenString(ch);\n      return state.tokenize(stream, state);\n    } else if (ch == \".\" && stream.match(/^\\d+(?:[eE][+\\-]?\\d+)?/)) {\n      return ret(\"number\", \"number\");\n    } else if (ch == \".\" && stream.match(\"..\")) {\n      return ret(\"spread\", \"meta\");\n    } else if (/[\\[\\]{}\\(\\),;\\:\\.]/.test(ch)) {\n      return ret(ch);\n    } else if (ch == \"=\" && stream.eat(\">\")) {\n      return ret(\"=>\", \"operator\");\n    } else if (ch == \"0\" && stream.eat(/x/i)) {\n      stream.eatWhile(/[\\da-f]/i);\n      return ret(\"number\", \"number\");\n    } else if (ch == \"0\" && stream.eat(/o/i)) {\n      stream.eatWhile(/[0-7]/i);\n      return ret(\"number\", \"number\");\n    } else if (ch == \"0\" && stream.eat(/b/i)) {\n      stream.eatWhile(/[01]/i);\n      return ret(\"number\", \"number\");\n    } else if (/\\d/.test(ch)) {\n      stream.match(/^\\d*(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/);\n      return ret(\"number\", \"number\");\n    } else if (ch == \"/\") {\n      if (stream.eat(\"*\")) {\n        state.tokenize = tokenComment;\n        return tokenComment(stream, state);\n      } else if (stream.eat(\"/\")) {\n        stream.skipToEnd();\n        return ret(\"comment\", \"comment\");\n      } else if (expressionAllowed(stream, state, 1)) {\n        readRegexp(stream);\n        stream.match(/^\\b(([gimyu])(?![gimyu]*\\2))+\\b/);\n        return ret(\"regexp\", \"string-2\");\n      } else {\n        stream.eatWhile(isOperatorChar);\n        return ret(\"operator\", \"operator\", stream.current());\n      }\n    } else if (ch == \"`\") {\n      state.tokenize = tokenQuasi;\n      return tokenQuasi(stream, state);\n    } else if (ch == \"#\") {\n      stream.skipToEnd();\n      return ret(\"error\", \"error\");\n    } else if (isOperatorChar.test(ch)) {\n      if (ch != \">\" || !state.lexical || state.lexical.type != \">\")\n        stream.eatWhile(isOperatorChar);\n      return ret(\"operator\", \"operator\", stream.current());\n    } else if (wordRE.test(ch)) {\n      stream.eatWhile(wordRE);\n      var word = stream.current()\n      if (state.lastType != \".\") {\n        if (keywords.propertyIsEnumerable(word)) {\n          var kw = keywords[word]\n          return ret(kw.type, kw.style, word)\n        }\n        if (word == \"async\" && stream.match(/^\\s*[\\(\\w]/, false))\n          return ret(\"async\", \"keyword\", word)\n      }\n      return ret(\"variable\", \"variable\", word)\n    }\n  }\n\n  function tokenString(quote) {\n    return function(stream, state) {\n      var escaped = false, next;\n      if (jsonldMode && stream.peek() == \"@\" && stream.match(isJsonldKeyword)){\n        state.tokenize = tokenBase;\n        return ret(\"jsonld-keyword\", \"meta\");\n      }\n      while ((next = stream.next()) != null) {\n        if (next == quote && !escaped) break;\n        escaped = !escaped && next == \"\\\\\";\n      }\n      if (!escaped) state.tokenize = tokenBase;\n      return ret(\"string\", \"string\");\n    };\n  }\n\n  function tokenComment(stream, state) {\n    var maybeEnd = false, ch;\n    while (ch = stream.next()) {\n      if (ch == \"/\" && maybeEnd) {\n        state.tokenize = tokenBase;\n        break;\n      }\n      maybeEnd = (ch == \"*\");\n    }\n    return ret(\"comment\", \"comment\");\n  }\n\n  function tokenQuasi(stream, state) {\n    var escaped = false, next;\n    while ((next = stream.next()) != null) {\n      if (!escaped && (next == \"`\" || next == \"$\" && stream.eat(\"{\"))) {\n        state.tokenize = tokenBase;\n        break;\n      }\n      escaped = !escaped && next == \"\\\\\";\n    }\n    return ret(\"quasi\", \"string-2\", stream.current());\n  }\n\n  var brackets = \"([{}])\";\n  // This is a crude lookahead trick to try and notice that we're\n  // parsing the argument patterns for a fat-arrow function before we\n  // actually hit the arrow token. It only works if the arrow is on\n  // the same line as the arguments and there's no strange noise\n  // (comments) in between. Fallback is to only notice when we hit the\n  // arrow, and not declare the arguments as locals for the arrow\n  // body.\n  function findFatArrow(stream, state) {\n    if (state.fatArrowAt) state.fatArrowAt = null;\n    var arrow = stream.string.indexOf(\"=>\", stream.start);\n    if (arrow < 0) return;\n\n    if (isTS) { // Try to skip TypeScript return type declarations after the arguments\n      var m = /:\\s*(?:\\w+(?:<[^>]*>|\\[\\])?|\\{[^}]*\\})\\s*$/.exec(stream.string.slice(stream.start, arrow))\n      if (m) arrow = m.index\n    }\n\n    var depth = 0, sawSomething = false;\n    for (var pos = arrow - 1; pos >= 0; --pos) {\n      var ch = stream.string.charAt(pos);\n      var bracket = brackets.indexOf(ch);\n      if (bracket >= 0 && bracket < 3) {\n        if (!depth) { ++pos; break; }\n        if (--depth == 0) { if (ch == \"(\") sawSomething = true; break; }\n      } else if (bracket >= 3 && bracket < 6) {\n        ++depth;\n      } else if (wordRE.test(ch)) {\n        sawSomething = true;\n      } else if (/[\"'\\/]/.test(ch)) {\n        return;\n      } else if (sawSomething && !depth) {\n        ++pos;\n        break;\n      }\n    }\n    if (sawSomething && !depth) state.fatArrowAt = pos;\n  }\n\n  // Parser\n\n  var atomicTypes = {\"atom\": true, \"number\": true, \"variable\": true, \"string\": true, \"regexp\": true, \"this\": true, \"jsonld-keyword\": true};\n\n  function JSLexical(indented, column, type, align, prev, info) {\n    this.indented = indented;\n    this.column = column;\n    this.type = type;\n    this.prev = prev;\n    this.info = info;\n    if (align != null) this.align = align;\n  }\n\n  function inScope(state, varname) {\n    for (var v = state.localVars; v; v = v.next)\n      if (v.name == varname) return true;\n    for (var cx = state.context; cx; cx = cx.prev) {\n      for (var v = cx.vars; v; v = v.next)\n        if (v.name == varname) return true;\n    }\n  }\n\n  function parseJS(state, style, type, content, stream) {\n    var cc = state.cc;\n    // Communicate our context to the combinators.\n    // (Less wasteful than consing up a hundred closures on every call.)\n    cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;\n\n    if (!state.lexical.hasOwnProperty(\"align\"))\n      state.lexical.align = true;\n\n    while(true) {\n      var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;\n      if (combinator(type, content)) {\n        while(cc.length && cc[cc.length - 1].lex)\n          cc.pop()();\n        if (cx.marked) return cx.marked;\n        if (type == \"variable\" && inScope(state, content)) return \"variable-2\";\n        return style;\n      }\n    }\n  }\n\n  // Combinator utils\n\n  var cx = {state: null, column: null, marked: null, cc: null};\n  function pass() {\n    for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);\n  }\n  function cont() {\n    pass.apply(null, arguments);\n    return true;\n  }\n  function register(varname) {\n    function inList(list) {\n      for (var v = list; v; v = v.next)\n        if (v.name == varname) return true;\n      return false;\n    }\n    var state = cx.state;\n    cx.marked = \"def\";\n    if (state.context) {\n      if (inList(state.localVars)) return;\n      state.localVars = {name: varname, next: state.localVars};\n    } else {\n      if (inList(state.globalVars)) return;\n      if (parserConfig.globalVars)\n        state.globalVars = {name: varname, next: state.globalVars};\n    }\n  }\n\n  // Combinators\n\n  var defaultVars = {name: \"this\", next: {name: \"arguments\"}};\n  function pushcontext() {\n    cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};\n    cx.state.localVars = defaultVars;\n  }\n  function popcontext() {\n    cx.state.localVars = cx.state.context.vars;\n    cx.state.context = cx.state.context.prev;\n  }\n  function pushlex(type, info) {\n    var result = function() {\n      var state = cx.state, indent = state.indented;\n      if (state.lexical.type == \"stat\") indent = state.lexical.indented;\n      else for (var outer = state.lexical; outer && outer.type == \")\" && outer.align; outer = outer.prev)\n        indent = outer.indented;\n      state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);\n    };\n    result.lex = true;\n    return result;\n  }\n  function poplex() {\n    var state = cx.state;\n    if (state.lexical.prev) {\n      if (state.lexical.type == \")\")\n        state.indented = state.lexical.indented;\n      state.lexical = state.lexical.prev;\n    }\n  }\n  poplex.lex = true;\n\n  function expect(wanted) {\n    function exp(type) {\n      if (type == wanted) return cont();\n      else if (wanted == \";\") return pass();\n      else return cont(exp);\n    };\n    return exp;\n  }\n\n  function statement(type, value) {\n    if (type == \"var\") return cont(pushlex(\"vardef\", value.length), vardef, expect(\";\"), poplex);\n    if (type == \"keyword a\") return cont(pushlex(\"form\"), parenExpr, statement, poplex);\n    if (type == \"keyword b\") return cont(pushlex(\"form\"), statement, poplex);\n    if (type == \"{\") return cont(pushlex(\"}\"), block, poplex);\n    if (type == \";\") return cont();\n    if (type == \"if\") {\n      if (cx.state.lexical.info == \"else\" && cx.state.cc[cx.state.cc.length - 1] == poplex)\n        cx.state.cc.pop()();\n      return cont(pushlex(\"form\"), parenExpr, statement, poplex, maybeelse);\n    }\n    if (type == \"function\") return cont(functiondef);\n    if (type == \"for\") return cont(pushlex(\"form\"), forspec, statement, poplex);\n    if (type == \"variable\") {\n      if (isTS && value == \"type\") {\n        cx.marked = \"keyword\"\n        return cont(typeexpr, expect(\"operator\"), typeexpr, expect(\";\"));\n      } else {\n        return cont(pushlex(\"stat\"), maybelabel);\n      }\n    }\n    if (type == \"switch\") return cont(pushlex(\"form\"), parenExpr, expect(\"{\"), pushlex(\"}\", \"switch\"),\n                                      block, poplex, poplex);\n    if (type == \"case\") return cont(expression, expect(\":\"));\n    if (type == \"default\") return cont(expect(\":\"));\n    if (type == \"catch\") return cont(pushlex(\"form\"), pushcontext, expect(\"(\"), funarg, expect(\")\"),\n                                     statement, poplex, popcontext);\n    if (type == \"class\") return cont(pushlex(\"form\"), className, poplex);\n    if (type == \"export\") return cont(pushlex(\"stat\"), afterExport, poplex);\n    if (type == \"import\") return cont(pushlex(\"stat\"), afterImport, poplex);\n    if (type == \"module\") return cont(pushlex(\"form\"), pattern, expect(\"{\"), pushlex(\"}\"), block, poplex, poplex)\n    if (type == \"async\") return cont(statement)\n    if (value == \"@\") return cont(expression, statement)\n    return pass(pushlex(\"stat\"), expression, expect(\";\"), poplex);\n  }\n  function expression(type) {\n    return expressionInner(type, false);\n  }\n  function expressionNoComma(type) {\n    return expressionInner(type, true);\n  }\n  function parenExpr(type) {\n    if (type != \"(\") return pass()\n    return cont(pushlex(\")\"), expression, expect(\")\"), poplex)\n  }\n  function expressionInner(type, noComma) {\n    if (cx.state.fatArrowAt == cx.stream.start) {\n      var body = noComma ? arrowBodyNoComma : arrowBody;\n      if (type == \"(\") return cont(pushcontext, pushlex(\")\"), commasep(pattern, \")\"), poplex, expect(\"=>\"), body, popcontext);\n      else if (type == \"variable\") return pass(pushcontext, pattern, expect(\"=>\"), body, popcontext);\n    }\n\n    var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;\n    if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);\n    if (type == \"function\") return cont(functiondef, maybeop);\n    if (type == \"class\") return cont(pushlex(\"form\"), classExpression, poplex);\n    if (type == \"keyword c\" || type == \"async\") return cont(noComma ? maybeexpressionNoComma : maybeexpression);\n    if (type == \"(\") return cont(pushlex(\")\"), maybeexpression, expect(\")\"), poplex, maybeop);\n    if (type == \"operator\" || type == \"spread\") return cont(noComma ? expressionNoComma : expression);\n    if (type == \"[\") return cont(pushlex(\"]\"), arrayLiteral, poplex, maybeop);\n    if (type == \"{\") return contCommasep(objprop, \"}\", null, maybeop);\n    if (type == \"quasi\") return pass(quasi, maybeop);\n    if (type == \"new\") return cont(maybeTarget(noComma));\n    return cont();\n  }\n  function maybeexpression(type) {\n    if (type.match(/[;\\}\\)\\],]/)) return pass();\n    return pass(expression);\n  }\n  function maybeexpressionNoComma(type) {\n    if (type.match(/[;\\}\\)\\],]/)) return pass();\n    return pass(expressionNoComma);\n  }\n\n  function maybeoperatorComma(type, value) {\n    if (type == \",\") return cont(expression);\n    return maybeoperatorNoComma(type, value, false);\n  }\n  function maybeoperatorNoComma(type, value, noComma) {\n    var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;\n    var expr = noComma == false ? expression : expressionNoComma;\n    if (type == \"=>\") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);\n    if (type == \"operator\") {\n      if (/\\+\\+|--/.test(value)) return cont(me);\n      if (value == \"?\") return cont(expression, expect(\":\"), expr);\n      return cont(expr);\n    }\n    if (type == \"quasi\") { return pass(quasi, me); }\n    if (type == \";\") return;\n    if (type == \"(\") return contCommasep(expressionNoComma, \")\", \"call\", me);\n    if (type == \".\") return cont(property, me);\n    if (type == \"[\") return cont(pushlex(\"]\"), maybeexpression, expect(\"]\"), poplex, me);\n    if (isTS && value == \"as\") { cx.marked = \"keyword\"; return cont(typeexpr, me) }\n  }\n  function quasi(type, value) {\n    if (type != \"quasi\") return pass();\n    if (value.slice(value.length - 2) != \"${\") return cont(quasi);\n    return cont(expression, continueQuasi);\n  }\n  function continueQuasi(type) {\n    if (type == \"}\") {\n      cx.marked = \"string-2\";\n      cx.state.tokenize = tokenQuasi;\n      return cont(quasi);\n    }\n  }\n  function arrowBody(type) {\n    findFatArrow(cx.stream, cx.state);\n    return pass(type == \"{\" ? statement : expression);\n  }\n  function arrowBodyNoComma(type) {\n    findFatArrow(cx.stream, cx.state);\n    return pass(type == \"{\" ? statement : expressionNoComma);\n  }\n  function maybeTarget(noComma) {\n    return function(type) {\n      if (type == \".\") return cont(noComma ? targetNoComma : target);\n      else return pass(noComma ? expressionNoComma : expression);\n    };\n  }\n  function target(_, value) {\n    if (value == \"target\") { cx.marked = \"keyword\"; return cont(maybeoperatorComma); }\n  }\n  function targetNoComma(_, value) {\n    if (value == \"target\") { cx.marked = \"keyword\"; return cont(maybeoperatorNoComma); }\n  }\n  function maybelabel(type) {\n    if (type == \":\") return cont(poplex, statement);\n    return pass(maybeoperatorComma, expect(\";\"), poplex);\n  }\n  function property(type) {\n    if (type == \"variable\") {cx.marked = \"property\"; return cont();}\n  }\n  function objprop(type, value) {\n    if (type == \"async\") {\n      cx.marked = \"property\";\n      return cont(objprop);\n    } else if (type == \"variable\" || cx.style == \"keyword\") {\n      cx.marked = \"property\";\n      if (value == \"get\" || value == \"set\") return cont(getterSetter);\n      return cont(afterprop);\n    } else if (type == \"number\" || type == \"string\") {\n      cx.marked = jsonldMode ? \"property\" : (cx.style + \" property\");\n      return cont(afterprop);\n    } else if (type == \"jsonld-keyword\") {\n      return cont(afterprop);\n    } else if (type == \"modifier\") {\n      return cont(objprop)\n    } else if (type == \"[\") {\n      return cont(expression, expect(\"]\"), afterprop);\n    } else if (type == \"spread\") {\n      return cont(expression, afterprop);\n    } else if (type == \":\") {\n      return pass(afterprop)\n    }\n  }\n  function getterSetter(type) {\n    if (type != \"variable\") return pass(afterprop);\n    cx.marked = \"property\";\n    return cont(functiondef);\n  }\n  function afterprop(type) {\n    if (type == \":\") return cont(expressionNoComma);\n    if (type == \"(\") return pass(functiondef);\n  }\n  function commasep(what, end, sep) {\n    function proceed(type, value) {\n      if (sep ? sep.indexOf(type) > -1 : type == \",\") {\n        var lex = cx.state.lexical;\n        if (lex.info == \"call\") lex.pos = (lex.pos || 0) + 1;\n        return cont(function(type, value) {\n          if (type == end || value == end) return pass()\n          return pass(what)\n        }, proceed);\n      }\n      if (type == end || value == end) return cont();\n      return cont(expect(end));\n    }\n    return function(type, value) {\n      if (type == end || value == end) return cont();\n      return pass(what, proceed);\n    };\n  }\n  function contCommasep(what, end, info) {\n    for (var i = 3; i < arguments.length; i++)\n      cx.cc.push(arguments[i]);\n    return cont(pushlex(end, info), commasep(what, end), poplex);\n  }\n  function block(type) {\n    if (type == \"}\") return cont();\n    return pass(statement, block);\n  }\n  function maybetype(type, value) {\n    if (isTS) {\n      if (type == \":\") return cont(typeexpr);\n      if (value == \"?\") return cont(maybetype);\n    }\n  }\n  function typeexpr(type) {\n    if (type == \"variable\") {cx.marked = \"type\"; return cont(afterType);}\n    if (type == \"string\" || type == \"number\" || type == \"atom\") return cont(afterType);\n    if (type == \"{\") return cont(pushlex(\"}\"), commasep(typeprop, \"}\", \",;\"), poplex, afterType)\n    if (type == \"(\") return cont(commasep(typearg, \")\"), maybeReturnType)\n  }\n  function maybeReturnType(type) {\n    if (type == \"=>\") return cont(typeexpr)\n  }\n  function typeprop(type, value) {\n    if (type == \"variable\" || cx.style == \"keyword\") {\n      cx.marked = \"property\"\n      return cont(typeprop)\n    } else if (value == \"?\") {\n      return cont(typeprop)\n    } else if (type == \":\") {\n      return cont(typeexpr)\n    } else if (type == \"[\") {\n      return cont(expression, maybetype, expect(\"]\"), typeprop)\n    }\n  }\n  function typearg(type) {\n    if (type == \"variable\") return cont(typearg)\n    else if (type == \":\") return cont(typeexpr)\n  }\n  function afterType(type, value) {\n    if (value == \"<\") return cont(pushlex(\">\"), commasep(typeexpr, \">\"), poplex, afterType)\n    if (value == \"|\" || type == \".\") return cont(typeexpr)\n    if (type == \"[\") return cont(expect(\"]\"), afterType)\n    if (value == \"extends\") return cont(typeexpr)\n  }\n  function vardef() {\n    return pass(pattern, maybetype, maybeAssign, vardefCont);\n  }\n  function pattern(type, value) {\n    if (type == \"modifier\") return cont(pattern)\n    if (type == \"variable\") { register(value); return cont(); }\n    if (type == \"spread\") return cont(pattern);\n    if (type == \"[\") return contCommasep(pattern, \"]\");\n    if (type == \"{\") return contCommasep(proppattern, \"}\");\n  }\n  function proppattern(type, value) {\n    if (type == \"variable\" && !cx.stream.match(/^\\s*:/, false)) {\n      register(value);\n      return cont(maybeAssign);\n    }\n    if (type == \"variable\") cx.marked = \"property\";\n    if (type == \"spread\") return cont(pattern);\n    if (type == \"}\") return pass();\n    return cont(expect(\":\"), pattern, maybeAssign);\n  }\n  function maybeAssign(_type, value) {\n    if (value == \"=\") return cont(expressionNoComma);\n  }\n  function vardefCont(type) {\n    if (type == \",\") return cont(vardef);\n  }\n  function maybeelse(type, value) {\n    if (type == \"keyword b\" && value == \"else\") return cont(pushlex(\"form\", \"else\"), statement, poplex);\n  }\n  function forspec(type) {\n    if (type == \"(\") return cont(pushlex(\")\"), forspec1, expect(\")\"), poplex);\n  }\n  function forspec1(type) {\n    if (type == \"var\") return cont(vardef, expect(\";\"), forspec2);\n    if (type == \";\") return cont(forspec2);\n    if (type == \"variable\") return cont(formaybeinof);\n    return pass(expression, expect(\";\"), forspec2);\n  }\n  function formaybeinof(_type, value) {\n    if (value == \"in\" || value == \"of\") { cx.marked = \"keyword\"; return cont(expression); }\n    return cont(maybeoperatorComma, forspec2);\n  }\n  function forspec2(type, value) {\n    if (type == \";\") return cont(forspec3);\n    if (value == \"in\" || value == \"of\") { cx.marked = \"keyword\"; return cont(expression); }\n    return pass(expression, expect(\";\"), forspec3);\n  }\n  function forspec3(type) {\n    if (type != \")\") cont(expression);\n  }\n  function functiondef(type, value) {\n    if (value == \"*\") {cx.marked = \"keyword\"; return cont(functiondef);}\n    if (type == \"variable\") {register(value); return cont(functiondef);}\n    if (type == \"(\") return cont(pushcontext, pushlex(\")\"), commasep(funarg, \")\"), poplex, maybetype, statement, popcontext);\n    if (isTS && value == \"<\") return cont(pushlex(\">\"), commasep(typeexpr, \">\"), poplex, functiondef)\n  }\n  function funarg(type) {\n    if (type == \"spread\") return cont(funarg);\n    return pass(pattern, maybetype, maybeAssign);\n  }\n  function classExpression(type, value) {\n    // Class expressions may have an optional name.\n    if (type == \"variable\") return className(type, value);\n    return classNameAfter(type, value);\n  }\n  function className(type, value) {\n    if (type == \"variable\") {register(value); return cont(classNameAfter);}\n  }\n  function classNameAfter(type, value) {\n    if (value == \"<\") return cont(pushlex(\">\"), commasep(typeexpr, \">\"), poplex, classNameAfter)\n    if (value == \"extends\" || value == \"implements\" || (isTS && type == \",\"))\n      return cont(isTS ? typeexpr : expression, classNameAfter);\n    if (type == \"{\") return cont(pushlex(\"}\"), classBody, poplex);\n  }\n  function classBody(type, value) {\n    if (type == \"variable\" || cx.style == \"keyword\") {\n      if ((value == \"async\" || value == \"static\" || value == \"get\" || value == \"set\" ||\n           (isTS && (value == \"public\" || value == \"private\" || value == \"protected\" || value == \"readonly\" || value == \"abstract\"))) &&\n          cx.stream.match(/^\\s+[\\w$\\xa1-\\uffff]/, false)) {\n        cx.marked = \"keyword\";\n        return cont(classBody);\n      }\n      cx.marked = \"property\";\n      return cont(isTS ? classfield : functiondef, classBody);\n    }\n    if (type == \"[\")\n      return cont(expression, expect(\"]\"), isTS ? classfield : functiondef, classBody)\n    if (value == \"*\") {\n      cx.marked = \"keyword\";\n      return cont(classBody);\n    }\n    if (type == \";\") return cont(classBody);\n    if (type == \"}\") return cont();\n    if (value == \"@\") return cont(expression, classBody)\n  }\n  function classfield(type, value) {\n    if (value == \"?\") return cont(classfield)\n    if (type == \":\") return cont(typeexpr, maybeAssign)\n    if (value == \"=\") return cont(expressionNoComma)\n    return pass(functiondef)\n  }\n  function afterExport(type, value) {\n    if (value == \"*\") { cx.marked = \"keyword\"; return cont(maybeFrom, expect(\";\")); }\n    if (value == \"default\") { cx.marked = \"keyword\"; return cont(expression, expect(\";\")); }\n    if (type == \"{\") return cont(commasep(exportField, \"}\"), maybeFrom, expect(\";\"));\n    return pass(statement);\n  }\n  function exportField(type, value) {\n    if (value == \"as\") { cx.marked = \"keyword\"; return cont(expect(\"variable\")); }\n    if (type == \"variable\") return pass(expressionNoComma, exportField);\n  }\n  function afterImport(type) {\n    if (type == \"string\") return cont();\n    return pass(importSpec, maybeMoreImports, maybeFrom);\n  }\n  function importSpec(type, value) {\n    if (type == \"{\") return contCommasep(importSpec, \"}\");\n    if (type == \"variable\") register(value);\n    if (value == \"*\") cx.marked = \"keyword\";\n    return cont(maybeAs);\n  }\n  function maybeMoreImports(type) {\n    if (type == \",\") return cont(importSpec, maybeMoreImports)\n  }\n  function maybeAs(_type, value) {\n    if (value == \"as\") { cx.marked = \"keyword\"; return cont(importSpec); }\n  }\n  function maybeFrom(_type, value) {\n    if (value == \"from\") { cx.marked = \"keyword\"; return cont(expression); }\n  }\n  function arrayLiteral(type) {\n    if (type == \"]\") return cont();\n    return pass(commasep(expressionNoComma, \"]\"));\n  }\n\n  function isContinuedStatement(state, textAfter) {\n    return state.lastType == \"operator\" || state.lastType == \",\" ||\n      isOperatorChar.test(textAfter.charAt(0)) ||\n      /[,.]/.test(textAfter.charAt(0));\n  }\n\n  // Interface\n\n  return {\n    startState: function(basecolumn) {\n      var state = {\n        tokenize: tokenBase,\n        lastType: \"sof\",\n        cc: [],\n        lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, \"block\", false),\n        localVars: parserConfig.localVars,\n        context: parserConfig.localVars && {vars: parserConfig.localVars},\n        indented: basecolumn || 0\n      };\n      if (parserConfig.globalVars && typeof parserConfig.globalVars == \"object\")\n        state.globalVars = parserConfig.globalVars;\n      return state;\n    },\n\n    token: function(stream, state) {\n      if (stream.sol()) {\n        if (!state.lexical.hasOwnProperty(\"align\"))\n          state.lexical.align = false;\n        state.indented = stream.indentation();\n        findFatArrow(stream, state);\n      }\n      if (state.tokenize != tokenComment && stream.eatSpace()) return null;\n      var style = state.tokenize(stream, state);\n      if (type == \"comment\") return style;\n      state.lastType = type == \"operator\" && (content == \"++\" || content == \"--\") ? \"incdec\" : type;\n      return parseJS(state, style, type, content, stream);\n    },\n\n    indent: function(state, textAfter) {\n      if (state.tokenize == tokenComment) return CodeMirror.Pass;\n      if (state.tokenize != tokenBase) return 0;\n      var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, top\n      // Kludge to prevent 'maybelse' from blocking lexical scope pops\n      if (!/^\\s*else\\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {\n        var c = state.cc[i];\n        if (c == poplex) lexical = lexical.prev;\n        else if (c != maybeelse) break;\n      }\n      while ((lexical.type == \"stat\" || lexical.type == \"form\") &&\n             (firstChar == \"}\" || ((top = state.cc[state.cc.length - 1]) &&\n                                   (top == maybeoperatorComma || top == maybeoperatorNoComma) &&\n                                   !/^[,\\.=+\\-*:?[\\(]/.test(textAfter))))\n        lexical = lexical.prev;\n      if (statementIndent && lexical.type == \")\" && lexical.prev.type == \"stat\")\n        lexical = lexical.prev;\n      var type = lexical.type, closing = firstChar == type;\n\n      if (type == \"vardef\") return lexical.indented + (state.lastType == \"operator\" || state.lastType == \",\" ? lexical.info + 1 : 0);\n      else if (type == \"form\" && firstChar == \"{\") return lexical.indented;\n      else if (type == \"form\") return lexical.indented + indentUnit;\n      else if (type == \"stat\")\n        return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0);\n      else if (lexical.info == \"switch\" && !closing && parserConfig.doubleIndentSwitch != false)\n        return lexical.indented + (/^(?:case|default)\\b/.test(textAfter) ? indentUnit : 2 * indentUnit);\n      else if (lexical.align) return lexical.column + (closing ? 0 : 1);\n      else return lexical.indented + (closing ? 0 : indentUnit);\n    },\n\n    electricInput: /^\\s*(?:case .*?:|default:|\\{|\\})$/,\n    blockCommentStart: jsonMode ? null : \"/*\",\n    blockCommentEnd: jsonMode ? null : \"*/\",\n    lineComment: jsonMode ? null : \"//\",\n    fold: \"brace\",\n    closeBrackets: \"()[]{}''\\\"\\\"``\",\n\n    helperType: jsonMode ? \"json\" : \"javascript\",\n    jsonldMode: jsonldMode,\n    jsonMode: jsonMode,\n\n    expressionAllowed: expressionAllowed,\n    skipExpression: function(state) {\n      var top = state.cc[state.cc.length - 1]\n      if (top == expression || top == expressionNoComma) state.cc.pop()\n    }\n  };\n});\n\nCodeMirror.registerHelper(\"wordChars\", \"javascript\", /[\\w$]/);\n\nCodeMirror.defineMIME(\"text/javascript\", \"javascript\");\nCodeMirror.defineMIME(\"text/ecmascript\", \"javascript\");\nCodeMirror.defineMIME(\"application/javascript\", \"javascript\");\nCodeMirror.defineMIME(\"application/x-javascript\", \"javascript\");\nCodeMirror.defineMIME(\"application/ecmascript\", \"javascript\");\nCodeMirror.defineMIME(\"application/json\", {name: \"javascript\", json: true});\nCodeMirror.defineMIME(\"application/x-json\", {name: \"javascript\", json: true});\nCodeMirror.defineMIME(\"application/ld+json\", {name: \"javascript\", jsonld: true});\nCodeMirror.defineMIME(\"text/typescript\", { name: \"javascript\", typescript: true });\nCodeMirror.defineMIME(\"application/typescript\", { name: \"javascript\", typescript: true });\n\n});"
  },
  {
    "path": "docs/editor/mode/javascript/typescript.html",
    "content": "<!doctype html>\n<html>\n  <head>\n    <meta charset=\"utf-8\">\n    <title>CodeMirror: TypeScript mode</title>\n    <link rel=\"stylesheet\" href=\"../../lib/codemirror.css\">\n    <script src=\"../../lib/codemirror.js\"></script>\n    <script src=\"javascript.js\"></script>\n    <link rel=\"stylesheet\" href=\"../../doc/docs.css\">\n    <style type=\"text/css\">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>\n  </head>\n  <body>\n    <h1>CodeMirror: TypeScript mode</h1>\n\n<div><textarea id=\"code\" name=\"code\">\nclass Greeter {\n\tgreeting: string;\n\tconstructor (message: string) {\n\t\tthis.greeting = message;\n\t}\n\tgreet() {\n\t\treturn \"Hello, \" + this.greeting;\n\t}\n}   \n\nvar greeter = new Greeter(\"world\");\n\nvar button = document.createElement('button')\nbutton.innerText = \"Say Hello\"\nbutton.onclick = function() {\n\talert(greeter.greet())\n}\n\ndocument.body.appendChild(button)\n\n</textarea></div>\n\n    <script>\n      var editor = CodeMirror.fromTextArea(document.getElementById(\"code\"), {\n        lineNumbers: true,\n        matchBrackets: true,\n        mode: \"text/typescript\"\n      });\n    </script>\n\n    <p>This is a specialization of the <a href=\"index.html\">JavaScript mode</a>.</p>\n  </body>\n</html>\n"
  },
  {
    "path": "docs/editor/mode/urduscript/urduscript.js",
    "content": "// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n  if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n    mod(require(\"../../lib/codemirror\"));\n  else if (typeof define == \"function\" && define.amd) // AMD\n    define([\"../../lib/codemirror\"], mod);\n  else // Plain browser env\n    mod(CodeMirror);\n})(function(CodeMirror) {\n\"use strict\";\n\nfunction expressionAllowed(stream, state, backUp) {\n  return /^(?:operator|sof|keyword c|case|new|export|default|[\\[{}\\(,;:]|=>)$/.test(state.lastType) ||\n    (state.lastType == \"quasi\" && /\\{\\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))\n}\n\nCodeMirror.defineMode(\"javascript\", function(config, parserConfig) {\n  var indentUnit = config.indentUnit;\n  var statementIndent = parserConfig.statementIndent;\n  var jsonldMode = parserConfig.jsonld;\n  var jsonMode = parserConfig.json || jsonldMode;\n  var isTS = parserConfig.typescript;\n  var wordRE = parserConfig.wordCharacters || /[\\w$\\xa1-\\uffff]/;\n\n  // Tokenizer\n\n  var keywords = function(){\n    function kw(type) {return {type: type, style: \"keyword\"};}\n    var A = kw(\"keyword a\"), B = kw(\"keyword b\"), C = kw(\"keyword c\");\n    var operator = kw(\"operator\"), atom = {type: \"atom\", style: \"atom\"};\n\n    var jsKeywords = {\n      \"if\": kw(\"if\"), \"while\": A, \"with\": A, \"else\": B, \"do\": B, \"try\": B, \"finally\": B,\n      \"return\": C, \"break\": C, \"continue\": C, \"new\": kw(\"new\"), \"delete\": C, \"throw\": C, \"debugger\": C,\n      \"var\": kw(\"var\"), \"const\": kw(\"var\"), \"let\": kw(\"var\"),\n      \"function\": kw(\"function\"), \"catch\": kw(\"catch\"),\n      \"for\": kw(\"for\"), \"switch\": kw(\"switch\"), \"case\": kw(\"case\"), \"default\": kw(\"default\"),\n      \"in\": operator, \"typeof\": operator, \"instanceof\": operator,\n      \"true\": atom, \"false\": atom, \"null\": atom, \"undefined\": atom, \"NaN\": atom, \"Infinity\": atom,\n      \"this\": kw(\"this\"), \"class\": kw(\"class\"), \"super\": kw(\"atom\"),\n      \"yield\": C, \"export\": kw(\"export\"), \"import\": kw(\"import\"), \"extends\": C,\n      \"await\": C,\n      //urduscript additions:\n      \"agar\": kw(\"if\"), \"karo\": B, \"jabtak\": A, \"warna\": B, \"warnaagar\": B,\n      \"rakho\": kw(\"var\"), \"likho\": A, \"pucho\": A,\n      \"sahi\": atom, \"galat\": atom, \"ghalat\": atom, \"khali\": atom, \"khaali\": atom,\n      \"kaam\": kw(\"function\"), \"har\": kw(\"for\"), \"k\": A, \"per\": A, \"pe\": A,\n      \"bhejo\": C, \"rukjao\": C\n    };\n\n    // Extend the 'normal' keywords with the TypeScript language extensions\n    if (isTS) {\n      var type = {type: \"variable\", style: \"type\"};\n      var tsKeywords = {\n        // object-like things\n        \"interface\": kw(\"class\"),\n        \"implements\": C,\n        \"namespace\": C,\n        \"module\": kw(\"module\"),\n        \"enum\": kw(\"module\"),\n\n        // scope modifiers\n        \"public\": kw(\"modifier\"),\n        \"private\": kw(\"modifier\"),\n        \"protected\": kw(\"modifier\"),\n        \"abstract\": kw(\"modifier\"),\n\n        // types\n        \"string\": type, \"number\": type, \"boolean\": type, \"any\": type\n      };\n\n      for (var attr in tsKeywords) {\n        jsKeywords[attr] = tsKeywords[attr];\n      }\n    }\n\n    return jsKeywords;\n  }();\n\n  var isOperatorChar = /[+\\-*&%=<>!?|~^@]/;\n  var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)\"/;\n\n  function readRegexp(stream) {\n    var escaped = false, next, inSet = false;\n    while ((next = stream.next()) != null) {\n      if (!escaped) {\n        if (next == \"/\" && !inSet) return;\n        if (next == \"[\") inSet = true;\n        else if (inSet && next == \"]\") inSet = false;\n      }\n      escaped = !escaped && next == \"\\\\\";\n    }\n  }\n\n  // Used as scratch variables to communicate multiple values without\n  // consing up tons of objects.\n  var type, content;\n  function ret(tp, style, cont) {\n    type = tp; content = cont;\n    return style;\n  }\n  function tokenBase(stream, state) {\n    var ch = stream.next();\n    if (ch == '\"' || ch == \"'\") {\n      state.tokenize = tokenString(ch);\n      return state.tokenize(stream, state);\n    } else if (ch == \".\" && stream.match(/^\\d+(?:[eE][+\\-]?\\d+)?/)) {\n      return ret(\"number\", \"number\");\n    } else if (ch == \".\" && stream.match(\"..\")) {\n      return ret(\"spread\", \"meta\");\n    } else if (/[\\[\\]{}\\(\\),;\\:\\.]/.test(ch)) {\n      return ret(ch);\n    } else if (ch == \"=\" && stream.eat(\">\")) {\n      return ret(\"=>\", \"operator\");\n    } else if (ch == \"0\" && stream.eat(/x/i)) {\n      stream.eatWhile(/[\\da-f]/i);\n      return ret(\"number\", \"number\");\n    } else if (ch == \"0\" && stream.eat(/o/i)) {\n      stream.eatWhile(/[0-7]/i);\n      return ret(\"number\", \"number\");\n    } else if (ch == \"0\" && stream.eat(/b/i)) {\n      stream.eatWhile(/[01]/i);\n      return ret(\"number\", \"number\");\n    } else if (/\\d/.test(ch)) {\n      stream.match(/^\\d*(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/);\n      return ret(\"number\", \"number\");\n    } else if (ch == \"/\") {\n      if (stream.eat(\"*\")) {\n        state.tokenize = tokenComment;\n        return tokenComment(stream, state);\n      } else if (stream.eat(\"/\")) {\n        stream.skipToEnd();\n        return ret(\"comment\", \"comment\");\n      } else if (expressionAllowed(stream, state, 1)) {\n        readRegexp(stream);\n        stream.match(/^\\b(([gimyu])(?![gimyu]*\\2))+\\b/);\n        return ret(\"regexp\", \"string-2\");\n      } else {\n        stream.eatWhile(isOperatorChar);\n        return ret(\"operator\", \"operator\", stream.current());\n      }\n    } else if (ch == \"`\") {\n      state.tokenize = tokenQuasi;\n      return tokenQuasi(stream, state);\n    } else if (ch == \"#\") {\n      stream.skipToEnd();\n      return ret(\"error\", \"error\");\n    } else if (isOperatorChar.test(ch)) {\n      if (ch != \">\" || !state.lexical || state.lexical.type != \">\")\n        stream.eatWhile(isOperatorChar);\n      return ret(\"operator\", \"operator\", stream.current());\n    } else if (wordRE.test(ch)) {\n      stream.eatWhile(wordRE);\n      var word = stream.current()\n      if (state.lastType != \".\") {\n        if (keywords.propertyIsEnumerable(word)) {\n          var kw = keywords[word]\n          return ret(kw.type, kw.style, word)\n        }\n        if (word == \"async\" && stream.match(/^\\s*[\\(\\w]/, false))\n          return ret(\"async\", \"keyword\", word)\n      }\n      return ret(\"variable\", \"variable\", word)\n    }\n  }\n\n  function tokenString(quote) {\n    return function(stream, state) {\n      var escaped = false, next;\n      if (jsonldMode && stream.peek() == \"@\" && stream.match(isJsonldKeyword)){\n        state.tokenize = tokenBase;\n        return ret(\"jsonld-keyword\", \"meta\");\n      }\n      while ((next = stream.next()) != null) {\n        if (next == quote && !escaped) break;\n        escaped = !escaped && next == \"\\\\\";\n      }\n      if (!escaped) state.tokenize = tokenBase;\n      return ret(\"string\", \"string\");\n    };\n  }\n\n  function tokenComment(stream, state) {\n    var maybeEnd = false, ch;\n    while (ch = stream.next()) {\n      if (ch == \"/\" && maybeEnd) {\n        state.tokenize = tokenBase;\n        break;\n      }\n      maybeEnd = (ch == \"*\");\n    }\n    return ret(\"comment\", \"comment\");\n  }\n\n  function tokenQuasi(stream, state) {\n    var escaped = false, next;\n    while ((next = stream.next()) != null) {\n      if (!escaped && (next == \"`\" || next == \"$\" && stream.eat(\"{\"))) {\n        state.tokenize = tokenBase;\n        break;\n      }\n      escaped = !escaped && next == \"\\\\\";\n    }\n    return ret(\"quasi\", \"string-2\", stream.current());\n  }\n\n  var brackets = \"([{}])\";\n  // This is a crude lookahead trick to try and notice that we're\n  // parsing the argument patterns for a fat-arrow function before we\n  // actually hit the arrow token. It only works if the arrow is on\n  // the same line as the arguments and there's no strange noise\n  // (comments) in between. Fallback is to only notice when we hit the\n  // arrow, and not declare the arguments as locals for the arrow\n  // body.\n  function findFatArrow(stream, state) {\n    if (state.fatArrowAt) state.fatArrowAt = null;\n    var arrow = stream.string.indexOf(\"=>\", stream.start);\n    if (arrow < 0) return;\n\n    if (isTS) { // Try to skip TypeScript return type declarations after the arguments\n      var m = /:\\s*(?:\\w+(?:<[^>]*>|\\[\\])?|\\{[^}]*\\})\\s*$/.exec(stream.string.slice(stream.start, arrow))\n      if (m) arrow = m.index\n    }\n\n    var depth = 0, sawSomething = false;\n    for (var pos = arrow - 1; pos >= 0; --pos) {\n      var ch = stream.string.charAt(pos);\n      var bracket = brackets.indexOf(ch);\n      if (bracket >= 0 && bracket < 3) {\n        if (!depth) { ++pos; break; }\n        if (--depth == 0) { if (ch == \"(\") sawSomething = true; break; }\n      } else if (bracket >= 3 && bracket < 6) {\n        ++depth;\n      } else if (wordRE.test(ch)) {\n        sawSomething = true;\n      } else if (/[\"'\\/]/.test(ch)) {\n        return;\n      } else if (sawSomething && !depth) {\n        ++pos;\n        break;\n      }\n    }\n    if (sawSomething && !depth) state.fatArrowAt = pos;\n  }\n\n  // Parser\n\n  var atomicTypes = {\"atom\": true, \"number\": true, \"variable\": true, \"string\": true, \"regexp\": true, \"this\": true, \"jsonld-keyword\": true};\n\n  function JSLexical(indented, column, type, align, prev, info) {\n    this.indented = indented;\n    this.column = column;\n    this.type = type;\n    this.prev = prev;\n    this.info = info;\n    if (align != null) this.align = align;\n  }\n\n  function inScope(state, varname) {\n    for (var v = state.localVars; v; v = v.next)\n      if (v.name == varname) return true;\n    for (var cx = state.context; cx; cx = cx.prev) {\n      for (var v = cx.vars; v; v = v.next)\n        if (v.name == varname) return true;\n    }\n  }\n\n  function parseJS(state, style, type, content, stream) {\n    var cc = state.cc;\n    // Communicate our context to the combinators.\n    // (Less wasteful than consing up a hundred closures on every call.)\n    cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;\n\n    if (!state.lexical.hasOwnProperty(\"align\"))\n      state.lexical.align = true;\n\n    while(true) {\n      var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;\n      if (combinator(type, content)) {\n        while(cc.length && cc[cc.length - 1].lex)\n          cc.pop()();\n        if (cx.marked) return cx.marked;\n        if (type == \"variable\" && inScope(state, content)) return \"variable-2\";\n        return style;\n      }\n    }\n  }\n\n  // Combinator utils\n\n  var cx = {state: null, column: null, marked: null, cc: null};\n  function pass() {\n    for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);\n  }\n  function cont() {\n    pass.apply(null, arguments);\n    return true;\n  }\n  function register(varname) {\n    function inList(list) {\n      for (var v = list; v; v = v.next)\n        if (v.name == varname) return true;\n      return false;\n    }\n    var state = cx.state;\n    cx.marked = \"def\";\n    if (state.context) {\n      if (inList(state.localVars)) return;\n      state.localVars = {name: varname, next: state.localVars};\n    } else {\n      if (inList(state.globalVars)) return;\n      if (parserConfig.globalVars)\n        state.globalVars = {name: varname, next: state.globalVars};\n    }\n  }\n\n  // Combinators\n\n  var defaultVars = {name: \"this\", next: {name: \"arguments\"}};\n  function pushcontext() {\n    cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};\n    cx.state.localVars = defaultVars;\n  }\n  function popcontext() {\n    cx.state.localVars = cx.state.context.vars;\n    cx.state.context = cx.state.context.prev;\n  }\n  function pushlex(type, info) {\n    var result = function() {\n      var state = cx.state, indent = state.indented;\n      if (state.lexical.type == \"stat\") indent = state.lexical.indented;\n      else for (var outer = state.lexical; outer && outer.type == \")\" && outer.align; outer = outer.prev)\n        indent = outer.indented;\n      state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);\n    };\n    result.lex = true;\n    return result;\n  }\n  function poplex() {\n    var state = cx.state;\n    if (state.lexical.prev) {\n      if (state.lexical.type == \")\")\n        state.indented = state.lexical.indented;\n      state.lexical = state.lexical.prev;\n    }\n  }\n  poplex.lex = true;\n\n  function expect(wanted) {\n    function exp(type) {\n      if (type == wanted) return cont();\n      else if (wanted == \";\") return pass();\n      else return cont(exp);\n    };\n    return exp;\n  }\n\n  function statement(type, value) {\n    if (type == \"var\") return cont(pushlex(\"vardef\", value.length), vardef, expect(\";\"), poplex);\n    if (type == \"keyword a\") return cont(pushlex(\"form\"), parenExpr, statement, poplex);\n    if (type == \"keyword b\") return cont(pushlex(\"form\"), statement, poplex);\n    if (type == \"{\") return cont(pushlex(\"}\"), block, poplex);\n    if (type == \";\") return cont();\n    if (type == \"if\") {\n      if (cx.state.lexical.info == \"else\" && cx.state.cc[cx.state.cc.length - 1] == poplex)\n        cx.state.cc.pop()();\n      return cont(pushlex(\"form\"), parenExpr, statement, poplex, maybeelse);\n    }\n    if (type == \"function\") return cont(functiondef);\n    if (type == \"for\") return cont(pushlex(\"form\"), forspec, statement, poplex);\n    if (type == \"variable\") {\n      if (isTS && value == \"type\") {\n        cx.marked = \"keyword\"\n        return cont(typeexpr, expect(\"operator\"), typeexpr, expect(\";\"));\n      } else {\n        return cont(pushlex(\"stat\"), maybelabel);\n      }\n    }\n    if (type == \"switch\") return cont(pushlex(\"form\"), parenExpr, expect(\"{\"), pushlex(\"}\", \"switch\"),\n                                      block, poplex, poplex);\n    if (type == \"case\") return cont(expression, expect(\":\"));\n    if (type == \"default\") return cont(expect(\":\"));\n    if (type == \"catch\") return cont(pushlex(\"form\"), pushcontext, expect(\"(\"), funarg, expect(\")\"),\n                                     statement, poplex, popcontext);\n    if (type == \"class\") return cont(pushlex(\"form\"), className, poplex);\n    if (type == \"export\") return cont(pushlex(\"stat\"), afterExport, poplex);\n    if (type == \"import\") return cont(pushlex(\"stat\"), afterImport, poplex);\n    if (type == \"module\") return cont(pushlex(\"form\"), pattern, expect(\"{\"), pushlex(\"}\"), block, poplex, poplex)\n    if (type == \"async\") return cont(statement)\n    if (value == \"@\") return cont(expression, statement)\n    return pass(pushlex(\"stat\"), expression, expect(\";\"), poplex);\n  }\n  function expression(type) {\n    return expressionInner(type, false);\n  }\n  function expressionNoComma(type) {\n    return expressionInner(type, true);\n  }\n  function parenExpr(type) {\n    if (type != \"(\") return pass()\n    return cont(pushlex(\")\"), expression, expect(\")\"), poplex)\n  }\n  function expressionInner(type, noComma) {\n    if (cx.state.fatArrowAt == cx.stream.start) {\n      var body = noComma ? arrowBodyNoComma : arrowBody;\n      if (type == \"(\") return cont(pushcontext, pushlex(\")\"), commasep(pattern, \")\"), poplex, expect(\"=>\"), body, popcontext);\n      else if (type == \"variable\") return pass(pushcontext, pattern, expect(\"=>\"), body, popcontext);\n    }\n\n    var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;\n    if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);\n    if (type == \"function\") return cont(functiondef, maybeop);\n    if (type == \"class\") return cont(pushlex(\"form\"), classExpression, poplex);\n    if (type == \"keyword c\" || type == \"async\") return cont(noComma ? maybeexpressionNoComma : maybeexpression);\n    if (type == \"(\") return cont(pushlex(\")\"), maybeexpression, expect(\")\"), poplex, maybeop);\n    if (type == \"operator\" || type == \"spread\") return cont(noComma ? expressionNoComma : expression);\n    if (type == \"[\") return cont(pushlex(\"]\"), arrayLiteral, poplex, maybeop);\n    if (type == \"{\") return contCommasep(objprop, \"}\", null, maybeop);\n    if (type == \"quasi\") return pass(quasi, maybeop);\n    if (type == \"new\") return cont(maybeTarget(noComma));\n    return cont();\n  }\n  function maybeexpression(type) {\n    if (type.match(/[;\\}\\)\\],]/)) return pass();\n    return pass(expression);\n  }\n  function maybeexpressionNoComma(type) {\n    if (type.match(/[;\\}\\)\\],]/)) return pass();\n    return pass(expressionNoComma);\n  }\n\n  function maybeoperatorComma(type, value) {\n    if (type == \",\") return cont(expression);\n    return maybeoperatorNoComma(type, value, false);\n  }\n  function maybeoperatorNoComma(type, value, noComma) {\n    var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;\n    var expr = noComma == false ? expression : expressionNoComma;\n    if (type == \"=>\") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);\n    if (type == \"operator\") {\n      if (/\\+\\+|--/.test(value)) return cont(me);\n      if (value == \"?\") return cont(expression, expect(\":\"), expr);\n      return cont(expr);\n    }\n    if (type == \"quasi\") { return pass(quasi, me); }\n    if (type == \";\") return;\n    if (type == \"(\") return contCommasep(expressionNoComma, \")\", \"call\", me);\n    if (type == \".\") return cont(property, me);\n    if (type == \"[\") return cont(pushlex(\"]\"), maybeexpression, expect(\"]\"), poplex, me);\n    if (isTS && value == \"as\") { cx.marked = \"keyword\"; return cont(typeexpr, me) }\n  }\n  function quasi(type, value) {\n    if (type != \"quasi\") return pass();\n    if (value.slice(value.length - 2) != \"${\") return cont(quasi);\n    return cont(expression, continueQuasi);\n  }\n  function continueQuasi(type) {\n    if (type == \"}\") {\n      cx.marked = \"string-2\";\n      cx.state.tokenize = tokenQuasi;\n      return cont(quasi);\n    }\n  }\n  function arrowBody(type) {\n    findFatArrow(cx.stream, cx.state);\n    return pass(type == \"{\" ? statement : expression);\n  }\n  function arrowBodyNoComma(type) {\n    findFatArrow(cx.stream, cx.state);\n    return pass(type == \"{\" ? statement : expressionNoComma);\n  }\n  function maybeTarget(noComma) {\n    return function(type) {\n      if (type == \".\") return cont(noComma ? targetNoComma : target);\n      else return pass(noComma ? expressionNoComma : expression);\n    };\n  }\n  function target(_, value) {\n    if (value == \"target\") { cx.marked = \"keyword\"; return cont(maybeoperatorComma); }\n  }\n  function targetNoComma(_, value) {\n    if (value == \"target\") { cx.marked = \"keyword\"; return cont(maybeoperatorNoComma); }\n  }\n  function maybelabel(type) {\n    if (type == \":\") return cont(poplex, statement);\n    return pass(maybeoperatorComma, expect(\";\"), poplex);\n  }\n  function property(type) {\n    if (type == \"variable\") {cx.marked = \"property\"; return cont();}\n  }\n  function objprop(type, value) {\n    if (type == \"async\") {\n      cx.marked = \"property\";\n      return cont(objprop);\n    } else if (type == \"variable\" || cx.style == \"keyword\") {\n      cx.marked = \"property\";\n      if (value == \"get\" || value == \"set\") return cont(getterSetter);\n      return cont(afterprop);\n    } else if (type == \"number\" || type == \"string\") {\n      cx.marked = jsonldMode ? \"property\" : (cx.style + \" property\");\n      return cont(afterprop);\n    } else if (type == \"jsonld-keyword\") {\n      return cont(afterprop);\n    } else if (type == \"modifier\") {\n      return cont(objprop)\n    } else if (type == \"[\") {\n      return cont(expression, expect(\"]\"), afterprop);\n    } else if (type == \"spread\") {\n      return cont(expression, afterprop);\n    } else if (type == \":\") {\n      return pass(afterprop)\n    }\n  }\n  function getterSetter(type) {\n    if (type != \"variable\") return pass(afterprop);\n    cx.marked = \"property\";\n    return cont(functiondef);\n  }\n  function afterprop(type) {\n    if (type == \":\") return cont(expressionNoComma);\n    if (type == \"(\") return pass(functiondef);\n  }\n  function commasep(what, end, sep) {\n    function proceed(type, value) {\n      if (sep ? sep.indexOf(type) > -1 : type == \",\") {\n        var lex = cx.state.lexical;\n        if (lex.info == \"call\") lex.pos = (lex.pos || 0) + 1;\n        return cont(function(type, value) {\n          if (type == end || value == end) return pass()\n          return pass(what)\n        }, proceed);\n      }\n      if (type == end || value == end) return cont();\n      return cont(expect(end));\n    }\n    return function(type, value) {\n      if (type == end || value == end) return cont();\n      return pass(what, proceed);\n    };\n  }\n  function contCommasep(what, end, info) {\n    for (var i = 3; i < arguments.length; i++)\n      cx.cc.push(arguments[i]);\n    return cont(pushlex(end, info), commasep(what, end), poplex);\n  }\n  function block(type) {\n    if (type == \"}\") return cont();\n    return pass(statement, block);\n  }\n  function maybetype(type, value) {\n    if (isTS) {\n      if (type == \":\") return cont(typeexpr);\n      if (value == \"?\") return cont(maybetype);\n    }\n  }\n  function typeexpr(type) {\n    if (type == \"variable\") {cx.marked = \"type\"; return cont(afterType);}\n    if (type == \"string\" || type == \"number\" || type == \"atom\") return cont(afterType);\n    if (type == \"{\") return cont(pushlex(\"}\"), commasep(typeprop, \"}\", \",;\"), poplex, afterType)\n    if (type == \"(\") return cont(commasep(typearg, \")\"), maybeReturnType)\n  }\n  function maybeReturnType(type) {\n    if (type == \"=>\") return cont(typeexpr)\n  }\n  function typeprop(type, value) {\n    if (type == \"variable\" || cx.style == \"keyword\") {\n      cx.marked = \"property\"\n      return cont(typeprop)\n    } else if (value == \"?\") {\n      return cont(typeprop)\n    } else if (type == \":\") {\n      return cont(typeexpr)\n    } else if (type == \"[\") {\n      return cont(expression, maybetype, expect(\"]\"), typeprop)\n    }\n  }\n  function typearg(type) {\n    if (type == \"variable\") return cont(typearg)\n    else if (type == \":\") return cont(typeexpr)\n  }\n  function afterType(type, value) {\n    if (value == \"<\") return cont(pushlex(\">\"), commasep(typeexpr, \">\"), poplex, afterType)\n    if (value == \"|\" || type == \".\") return cont(typeexpr)\n    if (type == \"[\") return cont(expect(\"]\"), afterType)\n    if (value == \"extends\") return cont(typeexpr)\n  }\n  function vardef() {\n    return pass(pattern, maybetype, maybeAssign, vardefCont);\n  }\n  function pattern(type, value) {\n    if (type == \"modifier\") return cont(pattern)\n    if (type == \"variable\") { register(value); return cont(); }\n    if (type == \"spread\") return cont(pattern);\n    if (type == \"[\") return contCommasep(pattern, \"]\");\n    if (type == \"{\") return contCommasep(proppattern, \"}\");\n  }\n  function proppattern(type, value) {\n    if (type == \"variable\" && !cx.stream.match(/^\\s*:/, false)) {\n      register(value);\n      return cont(maybeAssign);\n    }\n    if (type == \"variable\") cx.marked = \"property\";\n    if (type == \"spread\") return cont(pattern);\n    if (type == \"}\") return pass();\n    return cont(expect(\":\"), pattern, maybeAssign);\n  }\n  function maybeAssign(_type, value) {\n    if (value == \"=\") return cont(expressionNoComma);\n  }\n  function vardefCont(type) {\n    if (type == \",\") return cont(vardef);\n  }\n  function maybeelse(type, value) {\n    if (type == \"keyword b\" && value == \"else\") return cont(pushlex(\"form\", \"else\"), statement, poplex);\n  }\n  function forspec(type) {\n    if (type == \"(\") return cont(pushlex(\")\"), forspec1, expect(\")\"), poplex);\n  }\n  function forspec1(type) {\n    if (type == \"var\") return cont(vardef, expect(\";\"), forspec2);\n    if (type == \";\") return cont(forspec2);\n    if (type == \"variable\") return cont(formaybeinof);\n    return pass(expression, expect(\";\"), forspec2);\n  }\n  function formaybeinof(_type, value) {\n    if (value == \"in\" || value == \"of\") { cx.marked = \"keyword\"; return cont(expression); }\n    return cont(maybeoperatorComma, forspec2);\n  }\n  function forspec2(type, value) {\n    if (type == \";\") return cont(forspec3);\n    if (value == \"in\" || value == \"of\") { cx.marked = \"keyword\"; return cont(expression); }\n    return pass(expression, expect(\";\"), forspec3);\n  }\n  function forspec3(type) {\n    if (type != \")\") cont(expression);\n  }\n  function functiondef(type, value) {\n    if (value == \"*\") {cx.marked = \"keyword\"; return cont(functiondef);}\n    if (type == \"variable\") {register(value); return cont(functiondef);}\n    if (type == \"(\") return cont(pushcontext, pushlex(\")\"), commasep(funarg, \")\"), poplex, maybetype, statement, popcontext);\n    if (isTS && value == \"<\") return cont(pushlex(\">\"), commasep(typeexpr, \">\"), poplex, functiondef)\n  }\n  function funarg(type) {\n    if (type == \"spread\") return cont(funarg);\n    return pass(pattern, maybetype, maybeAssign);\n  }\n  function classExpression(type, value) {\n    // Class expressions may have an optional name.\n    if (type == \"variable\") return className(type, value);\n    return classNameAfter(type, value);\n  }\n  function className(type, value) {\n    if (type == \"variable\") {register(value); return cont(classNameAfter);}\n  }\n  function classNameAfter(type, value) {\n    if (value == \"<\") return cont(pushlex(\">\"), commasep(typeexpr, \">\"), poplex, classNameAfter)\n    if (value == \"extends\" || value == \"implements\" || (isTS && type == \",\"))\n      return cont(isTS ? typeexpr : expression, classNameAfter);\n    if (type == \"{\") return cont(pushlex(\"}\"), classBody, poplex);\n  }\n  function classBody(type, value) {\n    if (type == \"variable\" || cx.style == \"keyword\") {\n      if ((value == \"async\" || value == \"static\" || value == \"get\" || value == \"set\" ||\n           (isTS && (value == \"public\" || value == \"private\" || value == \"protected\" || value == \"readonly\" || value == \"abstract\"))) &&\n          cx.stream.match(/^\\s+[\\w$\\xa1-\\uffff]/, false)) {\n        cx.marked = \"keyword\";\n        return cont(classBody);\n      }\n      cx.marked = \"property\";\n      return cont(isTS ? classfield : functiondef, classBody);\n    }\n    if (type == \"[\")\n      return cont(expression, expect(\"]\"), isTS ? classfield : functiondef, classBody)\n    if (value == \"*\") {\n      cx.marked = \"keyword\";\n      return cont(classBody);\n    }\n    if (type == \";\") return cont(classBody);\n    if (type == \"}\") return cont();\n    if (value == \"@\") return cont(expression, classBody)\n  }\n  function classfield(type, value) {\n    if (value == \"?\") return cont(classfield)\n    if (type == \":\") return cont(typeexpr, maybeAssign)\n    if (value == \"=\") return cont(expressionNoComma)\n    return pass(functiondef)\n  }\n  function afterExport(type, value) {\n    if (value == \"*\") { cx.marked = \"keyword\"; return cont(maybeFrom, expect(\";\")); }\n    if (value == \"default\") { cx.marked = \"keyword\"; return cont(expression, expect(\";\")); }\n    if (type == \"{\") return cont(commasep(exportField, \"}\"), maybeFrom, expect(\";\"));\n    return pass(statement);\n  }\n  function exportField(type, value) {\n    if (value == \"as\") { cx.marked = \"keyword\"; return cont(expect(\"variable\")); }\n    if (type == \"variable\") return pass(expressionNoComma, exportField);\n  }\n  function afterImport(type) {\n    if (type == \"string\") return cont();\n    return pass(importSpec, maybeMoreImports, maybeFrom);\n  }\n  function importSpec(type, value) {\n    if (type == \"{\") return contCommasep(importSpec, \"}\");\n    if (type == \"variable\") register(value);\n    if (value == \"*\") cx.marked = \"keyword\";\n    return cont(maybeAs);\n  }\n  function maybeMoreImports(type) {\n    if (type == \",\") return cont(importSpec, maybeMoreImports)\n  }\n  function maybeAs(_type, value) {\n    if (value == \"as\") { cx.marked = \"keyword\"; return cont(importSpec); }\n  }\n  function maybeFrom(_type, value) {\n    if (value == \"from\") { cx.marked = \"keyword\"; return cont(expression); }\n  }\n  function arrayLiteral(type) {\n    if (type == \"]\") return cont();\n    return pass(commasep(expressionNoComma, \"]\"));\n  }\n\n  function isContinuedStatement(state, textAfter) {\n    return state.lastType == \"operator\" || state.lastType == \",\" ||\n      isOperatorChar.test(textAfter.charAt(0)) ||\n      /[,.]/.test(textAfter.charAt(0));\n  }\n\n  // Interface\n\n  return {\n    startState: function(basecolumn) {\n      var state = {\n        tokenize: tokenBase,\n        lastType: \"sof\",\n        cc: [],\n        lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, \"block\", false),\n        localVars: parserConfig.localVars,\n        context: parserConfig.localVars && {vars: parserConfig.localVars},\n        indented: basecolumn || 0\n      };\n      if (parserConfig.globalVars && typeof parserConfig.globalVars == \"object\")\n        state.globalVars = parserConfig.globalVars;\n      return state;\n    },\n\n    token: function(stream, state) {\n      if (stream.sol()) {\n        if (!state.lexical.hasOwnProperty(\"align\"))\n          state.lexical.align = false;\n        state.indented = stream.indentation();\n        findFatArrow(stream, state);\n      }\n      if (state.tokenize != tokenComment && stream.eatSpace()) return null;\n      var style = state.tokenize(stream, state);\n      if (type == \"comment\") return style;\n      state.lastType = type == \"operator\" && (content == \"++\" || content == \"--\") ? \"incdec\" : type;\n      return parseJS(state, style, type, content, stream);\n    },\n\n    indent: function(state, textAfter) {\n      if (state.tokenize == tokenComment) return CodeMirror.Pass;\n      if (state.tokenize != tokenBase) return 0;\n      var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, top\n      // Kludge to prevent 'maybelse' from blocking lexical scope pops\n      if (!/^\\s*else\\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {\n        var c = state.cc[i];\n        if (c == poplex) lexical = lexical.prev;\n        else if (c != maybeelse) break;\n      }\n      while ((lexical.type == \"stat\" || lexical.type == \"form\") &&\n             (firstChar == \"}\" || ((top = state.cc[state.cc.length - 1]) &&\n                                   (top == maybeoperatorComma || top == maybeoperatorNoComma) &&\n                                   !/^[,\\.=+\\-*:?[\\(]/.test(textAfter))))\n        lexical = lexical.prev;\n      if (statementIndent && lexical.type == \")\" && lexical.prev.type == \"stat\")\n        lexical = lexical.prev;\n      var type = lexical.type, closing = firstChar == type;\n\n      if (type == \"vardef\") return lexical.indented + (state.lastType == \"operator\" || state.lastType == \",\" ? lexical.info + 1 : 0);\n      else if (type == \"form\" && firstChar == \"{\") return lexical.indented;\n      else if (type == \"form\") return lexical.indented + indentUnit;\n      else if (type == \"stat\")\n        return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0);\n      else if (lexical.info == \"switch\" && !closing && parserConfig.doubleIndentSwitch != false)\n        return lexical.indented + (/^(?:case|default)\\b/.test(textAfter) ? indentUnit : 2 * indentUnit);\n      else if (lexical.align) return lexical.column + (closing ? 0 : 1);\n      else return lexical.indented + (closing ? 0 : indentUnit);\n    },\n\n    electricInput: /^\\s*(?:case .*?:|default:|\\{|\\})$/,\n    blockCommentStart: jsonMode ? null : \"/*\",\n    blockCommentEnd: jsonMode ? null : \"*/\",\n    lineComment: jsonMode ? null : \"//\",\n    fold: \"brace\",\n    closeBrackets: \"()[]{}''\\\"\\\"``\",\n\n    helperType: jsonMode ? \"json\" : \"javascript\",\n    jsonldMode: jsonldMode,\n    jsonMode: jsonMode,\n\n    expressionAllowed: expressionAllowed,\n    skipExpression: function(state) {\n      var top = state.cc[state.cc.length - 1]\n      if (top == expression || top == expressionNoComma) state.cc.pop()\n    }\n  };\n});\n\nCodeMirror.registerHelper(\"wordChars\", \"javascript\", /[\\w$]/);\n\nCodeMirror.defineMIME(\"text/javascript\", \"javascript\");\nCodeMirror.defineMIME(\"text/ecmascript\", \"javascript\");\nCodeMirror.defineMIME(\"application/javascript\", \"javascript\");\nCodeMirror.defineMIME(\"application/x-javascript\", \"javascript\");\nCodeMirror.defineMIME(\"application/ecmascript\", \"javascript\");\nCodeMirror.defineMIME(\"application/json\", {name: \"javascript\", json: true});\nCodeMirror.defineMIME(\"application/x-json\", {name: \"javascript\", json: true});\nCodeMirror.defineMIME(\"application/ld+json\", {name: \"javascript\", jsonld: true});\nCodeMirror.defineMIME(\"text/typescript\", { name: \"javascript\", typescript: true });\nCodeMirror.defineMIME(\"application/typescript\", { name: \"javascript\", typescript: true });\n\n});"
  },
  {
    "path": "docs/editor/scripts/codemirror.js",
    "content": "// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n// This is CodeMirror (http://codemirror.net), a code editor\n// implemented in JavaScript on top of the browser's DOM.\n//\n// You can find some technical background for some of the code below\n// at http://marijnhaverbeke.nl/blog/#cm-internals .\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define(factory) :\n  (global.CodeMirror = factory());\n}(this, (function () { 'use strict';\n\n// Kludges for bugs and behavior differences that can't be feature\n// detected are enabled based on userAgent etc sniffing.\nvar userAgent = navigator.userAgent\nvar platform = navigator.platform\n\nvar gecko = /gecko\\/\\d/i.test(userAgent)\nvar ie_upto10 = /MSIE \\d/.test(userAgent)\nvar ie_11up = /Trident\\/(?:[7-9]|\\d{2,})\\..*rv:(\\d+)/.exec(userAgent)\nvar edge = /Edge\\/(\\d+)/.exec(userAgent)\nvar ie = ie_upto10 || ie_11up || edge\nvar ie_version = ie && (ie_upto10 ? document.documentMode || 6 : +(edge || ie_11up)[1])\nvar webkit = !edge && /WebKit\\//.test(userAgent)\nvar qtwebkit = webkit && /Qt\\/\\d+\\.\\d+/.test(userAgent)\nvar chrome = !edge && /Chrome\\//.test(userAgent)\nvar presto = /Opera\\//.test(userAgent)\nvar safari = /Apple Computer/.test(navigator.vendor)\nvar mac_geMountainLion = /Mac OS X 1\\d\\D([8-9]|\\d\\d)\\D/.test(userAgent)\nvar phantom = /PhantomJS/.test(userAgent)\n\nvar ios = !edge && /AppleWebKit/.test(userAgent) && /Mobile\\/\\w+/.test(userAgent)\nvar android = /Android/.test(userAgent)\n// This is woefully incomplete. Suggestions for alternative methods welcome.\nvar mobile = ios || android || /webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent)\nvar mac = ios || /Mac/.test(platform)\nvar chromeOS = /\\bCrOS\\b/.test(userAgent)\nvar windows = /win/i.test(platform)\n\nvar presto_version = presto && userAgent.match(/Version\\/(\\d*\\.\\d*)/)\nif (presto_version) { presto_version = Number(presto_version[1]) }\nif (presto_version && presto_version >= 15) { presto = false; webkit = true }\n// Some browsers use the wrong event properties to signal cmd/ctrl on OS X\nvar flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11))\nvar captureRightClick = gecko || (ie && ie_version >= 9)\n\nfunction classTest(cls) { return new RegExp(\"(^|\\\\s)\" + cls + \"(?:$|\\\\s)\\\\s*\") }\n\nvar rmClass = function(node, cls) {\n  var current = node.className\n  var match = classTest(cls).exec(current)\n  if (match) {\n    var after = current.slice(match.index + match[0].length)\n    node.className = current.slice(0, match.index) + (after ? match[1] + after : \"\")\n  }\n}\n\nfunction removeChildren(e) {\n  for (var count = e.childNodes.length; count > 0; --count)\n    { e.removeChild(e.firstChild) }\n  return e\n}\n\nfunction removeChildrenAndAdd(parent, e) {\n  return removeChildren(parent).appendChild(e)\n}\n\nfunction elt(tag, content, className, style) {\n  var e = document.createElement(tag)\n  if (className) { e.className = className }\n  if (style) { e.style.cssText = style }\n  if (typeof content == \"string\") { e.appendChild(document.createTextNode(content)) }\n  else if (content) { for (var i = 0; i < content.length; ++i) { e.appendChild(content[i]) } }\n  return e\n}\n// wrapper for elt, which removes the elt from the accessibility tree\nfunction eltP(tag, content, className, style) {\n  var e = elt(tag, content, className, style)\n  e.setAttribute(\"role\", \"presentation\")\n  return e\n}\n\nvar range\nif (document.createRange) { range = function(node, start, end, endNode) {\n  var r = document.createRange()\n  r.setEnd(endNode || node, end)\n  r.setStart(node, start)\n  return r\n} }\nelse { range = function(node, start, end) {\n  var r = document.body.createTextRange()\n  try { r.moveToElementText(node.parentNode) }\n  catch(e) { return r }\n  r.collapse(true)\n  r.moveEnd(\"character\", end)\n  r.moveStart(\"character\", start)\n  return r\n} }\n\nfunction contains(parent, child) {\n  if (child.nodeType == 3) // Android browser always returns false when child is a textnode\n    { child = child.parentNode }\n  if (parent.contains)\n    { return parent.contains(child) }\n  do {\n    if (child.nodeType == 11) { child = child.host }\n    if (child == parent) { return true }\n  } while (child = child.parentNode)\n}\n\nfunction activeElt() {\n  // IE and Edge may throw an \"Unspecified Error\" when accessing document.activeElement.\n  // IE < 10 will throw when accessed while the page is loading or in an iframe.\n  // IE > 9 and Edge will throw when accessed in an iframe if document.body is unavailable.\n  var activeElement\n  try {\n    activeElement = document.activeElement\n  } catch(e) {\n    activeElement = document.body || null\n  }\n  while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement)\n    { activeElement = activeElement.shadowRoot.activeElement }\n  return activeElement\n}\n\nfunction addClass(node, cls) {\n  var current = node.className\n  if (!classTest(cls).test(current)) { node.className += (current ? \" \" : \"\") + cls }\n}\nfunction joinClasses(a, b) {\n  var as = a.split(\" \")\n  for (var i = 0; i < as.length; i++)\n    { if (as[i] && !classTest(as[i]).test(b)) { b += \" \" + as[i] } }\n  return b\n}\n\nvar selectInput = function(node) { node.select() }\nif (ios) // Mobile Safari apparently has a bug where select() is broken.\n  { selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length } }\nelse if (ie) // Suppress mysterious IE10 errors\n  { selectInput = function(node) { try { node.select() } catch(_e) {} } }\n\nfunction bind(f) {\n  var args = Array.prototype.slice.call(arguments, 1)\n  return function(){return f.apply(null, args)}\n}\n\nfunction copyObj(obj, target, overwrite) {\n  if (!target) { target = {} }\n  for (var prop in obj)\n    { if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))\n      { target[prop] = obj[prop] } }\n  return target\n}\n\n// Counts the column offset in a string, taking tabs into account.\n// Used mostly to find indentation.\nfunction countColumn(string, end, tabSize, startIndex, startValue) {\n  if (end == null) {\n    end = string.search(/[^\\s\\u00a0]/)\n    if (end == -1) { end = string.length }\n  }\n  for (var i = startIndex || 0, n = startValue || 0;;) {\n    var nextTab = string.indexOf(\"\\t\", i)\n    if (nextTab < 0 || nextTab >= end)\n      { return n + (end - i) }\n    n += nextTab - i\n    n += tabSize - (n % tabSize)\n    i = nextTab + 1\n  }\n}\n\nvar Delayed = function() {this.id = null};\nDelayed.prototype.set = function (ms, f) {\n  clearTimeout(this.id)\n  this.id = setTimeout(f, ms)\n};\n\nfunction indexOf(array, elt) {\n  for (var i = 0; i < array.length; ++i)\n    { if (array[i] == elt) { return i } }\n  return -1\n}\n\n// Number of pixels added to scroller and sizer to hide scrollbar\nvar scrollerGap = 30\n\n// Returned or thrown by various protocols to signal 'I'm not\n// handling this'.\nvar Pass = {toString: function(){return \"CodeMirror.Pass\"}}\n\n// Reused option objects for setSelection & friends\nvar sel_dontScroll = {scroll: false};\nvar sel_mouse = {origin: \"*mouse\"};\nvar sel_move = {origin: \"+move\"};\n// The inverse of countColumn -- find the offset that corresponds to\n// a particular column.\nfunction findColumn(string, goal, tabSize) {\n  for (var pos = 0, col = 0;;) {\n    var nextTab = string.indexOf(\"\\t\", pos)\n    if (nextTab == -1) { nextTab = string.length }\n    var skipped = nextTab - pos\n    if (nextTab == string.length || col + skipped >= goal)\n      { return pos + Math.min(skipped, goal - col) }\n    col += nextTab - pos\n    col += tabSize - (col % tabSize)\n    pos = nextTab + 1\n    if (col >= goal) { return pos }\n  }\n}\n\nvar spaceStrs = [\"\"]\nfunction spaceStr(n) {\n  while (spaceStrs.length <= n)\n    { spaceStrs.push(lst(spaceStrs) + \" \") }\n  return spaceStrs[n]\n}\n\nfunction lst(arr) { return arr[arr.length-1] }\n\nfunction map(array, f) {\n  var out = []\n  for (var i = 0; i < array.length; i++) { out[i] = f(array[i], i) }\n  return out\n}\n\nfunction insertSorted(array, value, score) {\n  var pos = 0, priority = score(value)\n  while (pos < array.length && score(array[pos]) <= priority) { pos++ }\n  array.splice(pos, 0, value)\n}\n\nfunction nothing() {}\n\nfunction createObj(base, props) {\n  var inst\n  if (Object.create) {\n    inst = Object.create(base)\n  } else {\n    nothing.prototype = base\n    inst = new nothing()\n  }\n  if (props) { copyObj(props, inst) }\n  return inst\n}\n\nvar nonASCIISingleCaseWordChar = /[\\u00df\\u0587\\u0590-\\u05f4\\u0600-\\u06ff\\u3040-\\u309f\\u30a0-\\u30ff\\u3400-\\u4db5\\u4e00-\\u9fcc\\uac00-\\ud7af]/\nfunction isWordCharBasic(ch) {\n  return /\\w/.test(ch) || ch > \"\\x80\" &&\n    (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch))\n}\nfunction isWordChar(ch, helper) {\n  if (!helper) { return isWordCharBasic(ch) }\n  if (helper.source.indexOf(\"\\\\w\") > -1 && isWordCharBasic(ch)) { return true }\n  return helper.test(ch)\n}\n\nfunction isEmpty(obj) {\n  for (var n in obj) { if (obj.hasOwnProperty(n) && obj[n]) { return false } }\n  return true\n}\n\n// Extending unicode characters. A series of a non-extending char +\n// any number of extending chars is treated as a single unit as far\n// as editing and measuring is concerned. This is not fully correct,\n// since some scripts/fonts/browsers also treat other configurations\n// of code points as a group.\nvar extendingChars = /[\\u0300-\\u036f\\u0483-\\u0489\\u0591-\\u05bd\\u05bf\\u05c1\\u05c2\\u05c4\\u05c5\\u05c7\\u0610-\\u061a\\u064b-\\u065e\\u0670\\u06d6-\\u06dc\\u06de-\\u06e4\\u06e7\\u06e8\\u06ea-\\u06ed\\u0711\\u0730-\\u074a\\u07a6-\\u07b0\\u07eb-\\u07f3\\u0816-\\u0819\\u081b-\\u0823\\u0825-\\u0827\\u0829-\\u082d\\u0900-\\u0902\\u093c\\u0941-\\u0948\\u094d\\u0951-\\u0955\\u0962\\u0963\\u0981\\u09bc\\u09be\\u09c1-\\u09c4\\u09cd\\u09d7\\u09e2\\u09e3\\u0a01\\u0a02\\u0a3c\\u0a41\\u0a42\\u0a47\\u0a48\\u0a4b-\\u0a4d\\u0a51\\u0a70\\u0a71\\u0a75\\u0a81\\u0a82\\u0abc\\u0ac1-\\u0ac5\\u0ac7\\u0ac8\\u0acd\\u0ae2\\u0ae3\\u0b01\\u0b3c\\u0b3e\\u0b3f\\u0b41-\\u0b44\\u0b4d\\u0b56\\u0b57\\u0b62\\u0b63\\u0b82\\u0bbe\\u0bc0\\u0bcd\\u0bd7\\u0c3e-\\u0c40\\u0c46-\\u0c48\\u0c4a-\\u0c4d\\u0c55\\u0c56\\u0c62\\u0c63\\u0cbc\\u0cbf\\u0cc2\\u0cc6\\u0ccc\\u0ccd\\u0cd5\\u0cd6\\u0ce2\\u0ce3\\u0d3e\\u0d41-\\u0d44\\u0d4d\\u0d57\\u0d62\\u0d63\\u0dca\\u0dcf\\u0dd2-\\u0dd4\\u0dd6\\u0ddf\\u0e31\\u0e34-\\u0e3a\\u0e47-\\u0e4e\\u0eb1\\u0eb4-\\u0eb9\\u0ebb\\u0ebc\\u0ec8-\\u0ecd\\u0f18\\u0f19\\u0f35\\u0f37\\u0f39\\u0f71-\\u0f7e\\u0f80-\\u0f84\\u0f86\\u0f87\\u0f90-\\u0f97\\u0f99-\\u0fbc\\u0fc6\\u102d-\\u1030\\u1032-\\u1037\\u1039\\u103a\\u103d\\u103e\\u1058\\u1059\\u105e-\\u1060\\u1071-\\u1074\\u1082\\u1085\\u1086\\u108d\\u109d\\u135f\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17b7-\\u17bd\\u17c6\\u17c9-\\u17d3\\u17dd\\u180b-\\u180d\\u18a9\\u1920-\\u1922\\u1927\\u1928\\u1932\\u1939-\\u193b\\u1a17\\u1a18\\u1a56\\u1a58-\\u1a5e\\u1a60\\u1a62\\u1a65-\\u1a6c\\u1a73-\\u1a7c\\u1a7f\\u1b00-\\u1b03\\u1b34\\u1b36-\\u1b3a\\u1b3c\\u1b42\\u1b6b-\\u1b73\\u1b80\\u1b81\\u1ba2-\\u1ba5\\u1ba8\\u1ba9\\u1c2c-\\u1c33\\u1c36\\u1c37\\u1cd0-\\u1cd2\\u1cd4-\\u1ce0\\u1ce2-\\u1ce8\\u1ced\\u1dc0-\\u1de6\\u1dfd-\\u1dff\\u200c\\u200d\\u20d0-\\u20f0\\u2cef-\\u2cf1\\u2de0-\\u2dff\\u302a-\\u302f\\u3099\\u309a\\ua66f-\\ua672\\ua67c\\ua67d\\ua6f0\\ua6f1\\ua802\\ua806\\ua80b\\ua825\\ua826\\ua8c4\\ua8e0-\\ua8f1\\ua926-\\ua92d\\ua947-\\ua951\\ua980-\\ua982\\ua9b3\\ua9b6-\\ua9b9\\ua9bc\\uaa29-\\uaa2e\\uaa31\\uaa32\\uaa35\\uaa36\\uaa43\\uaa4c\\uaab0\\uaab2-\\uaab4\\uaab7\\uaab8\\uaabe\\uaabf\\uaac1\\uabe5\\uabe8\\uabed\\udc00-\\udfff\\ufb1e\\ufe00-\\ufe0f\\ufe20-\\ufe26\\uff9e\\uff9f]/\nfunction isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch) }\n\n// Returns a number from the range [`0`; `str.length`] unless `pos` is outside that range.\nfunction skipExtendingChars(str, pos, dir) {\n  while ((dir < 0 ? pos > 0 : pos < str.length) && isExtendingChar(str.charAt(pos))) { pos += dir }\n  return pos\n}\n\n// Returns the value from the range [`from`; `to`] that satisfies\n// `pred` and is closest to `from`. Assumes that at least `to` satisfies `pred`.\nfunction findFirst(pred, from, to) {\n  for (;;) {\n    if (Math.abs(from - to) <= 1) { return pred(from) ? from : to }\n    var mid = Math.floor((from + to) / 2)\n    if (pred(mid)) { to = mid }\n    else { from = mid }\n  }\n}\n\n// The display handles the DOM integration, both for input reading\n// and content drawing. It holds references to DOM nodes and\n// display-related state.\n\nfunction Display(place, doc, input) {\n  var d = this\n  this.input = input\n\n  // Covers bottom-right square when both scrollbars are present.\n  d.scrollbarFiller = elt(\"div\", null, \"CodeMirror-scrollbar-filler\")\n  d.scrollbarFiller.setAttribute(\"cm-not-content\", \"true\")\n  // Covers bottom of gutter when coverGutterNextToScrollbar is on\n  // and h scrollbar is present.\n  d.gutterFiller = elt(\"div\", null, \"CodeMirror-gutter-filler\")\n  d.gutterFiller.setAttribute(\"cm-not-content\", \"true\")\n  // Will contain the actual code, positioned to cover the viewport.\n  d.lineDiv = eltP(\"div\", null, \"CodeMirror-code\")\n  // Elements are added to these to represent selection and cursors.\n  d.selectionDiv = elt(\"div\", null, null, \"position: relative; z-index: 1\")\n  d.cursorDiv = elt(\"div\", null, \"CodeMirror-cursors\")\n  // A visibility: hidden element used to find the size of things.\n  d.measure = elt(\"div\", null, \"CodeMirror-measure\")\n  // When lines outside of the viewport are measured, they are drawn in this.\n  d.lineMeasure = elt(\"div\", null, \"CodeMirror-measure\")\n  // Wraps everything that needs to exist inside the vertically-padded coordinate system\n  d.lineSpace = eltP(\"div\", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],\n                    null, \"position: relative; outline: none\")\n  var lines = eltP(\"div\", [d.lineSpace], \"CodeMirror-lines\")\n  // Moved around its parent to cover visible view.\n  d.mover = elt(\"div\", [lines], null, \"position: relative\")\n  // Set to the height of the document, allowing scrolling.\n  d.sizer = elt(\"div\", [d.mover], \"CodeMirror-sizer\")\n  d.sizerWidth = null\n  // Behavior of elts with overflow: auto and padding is\n  // inconsistent across browsers. This is used to ensure the\n  // scrollable area is big enough.\n  d.heightForcer = elt(\"div\", null, null, \"position: absolute; height: \" + scrollerGap + \"px; width: 1px;\")\n  // Will contain the gutters, if any.\n  d.gutters = elt(\"div\", null, \"CodeMirror-gutters\")\n  d.lineGutter = null\n  // Actual scrollable element.\n  d.scroller = elt(\"div\", [d.sizer, d.heightForcer, d.gutters], \"CodeMirror-scroll\")\n  d.scroller.setAttribute(\"tabIndex\", \"-1\")\n  // The element in which the editor lives.\n  d.wrapper = elt(\"div\", [d.scrollbarFiller, d.gutterFiller, d.scroller], \"CodeMirror\")\n\n  // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)\n  if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0 }\n  if (!webkit && !(gecko && mobile)) { d.scroller.draggable = true }\n\n  if (place) {\n    if (place.appendChild) { place.appendChild(d.wrapper) }\n    else { place(d.wrapper) }\n  }\n\n  // Current rendered range (may be bigger than the view window).\n  d.viewFrom = d.viewTo = doc.first\n  d.reportedViewFrom = d.reportedViewTo = doc.first\n  // Information about the rendered lines.\n  d.view = []\n  d.renderedView = null\n  // Holds info about a single rendered line when it was rendered\n  // for measurement, while not in view.\n  d.externalMeasured = null\n  // Empty space (in pixels) above the view\n  d.viewOffset = 0\n  d.lastWrapHeight = d.lastWrapWidth = 0\n  d.updateLineNumbers = null\n\n  d.nativeBarWidth = d.barHeight = d.barWidth = 0\n  d.scrollbarsClipped = false\n\n  // Used to only resize the line number gutter when necessary (when\n  // the amount of lines crosses a boundary that makes its width change)\n  d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null\n  // Set to true when a non-horizontal-scrolling line widget is\n  // added. As an optimization, line widget aligning is skipped when\n  // this is false.\n  d.alignWidgets = false\n\n  d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null\n\n  // Tracks the maximum line length so that the horizontal scrollbar\n  // can be kept static when scrolling.\n  d.maxLine = null\n  d.maxLineLength = 0\n  d.maxLineChanged = false\n\n  // Used for measuring wheel scrolling granularity\n  d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null\n\n  // True when shift is held down.\n  d.shift = false\n\n  // Used to track whether anything happened since the context menu\n  // was opened.\n  d.selForContextMenu = null\n\n  d.activeTouch = null\n\n  input.init(d)\n}\n\n// Find the line object corresponding to the given line number.\nfunction getLine(doc, n) {\n  n -= doc.first\n  if (n < 0 || n >= doc.size) { throw new Error(\"There is no line \" + (n + doc.first) + \" in the document.\") }\n  var chunk = doc\n  while (!chunk.lines) {\n    for (var i = 0;; ++i) {\n      var child = chunk.children[i], sz = child.chunkSize()\n      if (n < sz) { chunk = child; break }\n      n -= sz\n    }\n  }\n  return chunk.lines[n]\n}\n\n// Get the part of a document between two positions, as an array of\n// strings.\nfunction getBetween(doc, start, end) {\n  var out = [], n = start.line\n  doc.iter(start.line, end.line + 1, function (line) {\n    var text = line.text\n    if (n == end.line) { text = text.slice(0, end.ch) }\n    if (n == start.line) { text = text.slice(start.ch) }\n    out.push(text)\n    ++n\n  })\n  return out\n}\n// Get the lines between from and to, as array of strings.\nfunction getLines(doc, from, to) {\n  var out = []\n  doc.iter(from, to, function (line) { out.push(line.text) }) // iter aborts when callback returns truthy value\n  return out\n}\n\n// Update the height of a line, propagating the height change\n// upwards to parent nodes.\nfunction updateLineHeight(line, height) {\n  var diff = height - line.height\n  if (diff) { for (var n = line; n; n = n.parent) { n.height += diff } }\n}\n\n// Given a line object, find its line number by walking up through\n// its parent links.\nfunction lineNo(line) {\n  if (line.parent == null) { return null }\n  var cur = line.parent, no = indexOf(cur.lines, line)\n  for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {\n    for (var i = 0;; ++i) {\n      if (chunk.children[i] == cur) { break }\n      no += chunk.children[i].chunkSize()\n    }\n  }\n  return no + cur.first\n}\n\n// Find the line at the given vertical position, using the height\n// information in the document tree.\nfunction lineAtHeight(chunk, h) {\n  var n = chunk.first\n  outer: do {\n    for (var i$1 = 0; i$1 < chunk.children.length; ++i$1) {\n      var child = chunk.children[i$1], ch = child.height\n      if (h < ch) { chunk = child; continue outer }\n      h -= ch\n      n += child.chunkSize()\n    }\n    return n\n  } while (!chunk.lines)\n  var i = 0\n  for (; i < chunk.lines.length; ++i) {\n    var line = chunk.lines[i], lh = line.height\n    if (h < lh) { break }\n    h -= lh\n  }\n  return n + i\n}\n\nfunction isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size}\n\nfunction lineNumberFor(options, i) {\n  return String(options.lineNumberFormatter(i + options.firstLineNumber))\n}\n\n// A Pos instance represents a position within the text.\nfunction Pos(line, ch, sticky) {\n  if ( sticky === void 0 ) sticky = null;\n\n  if (!(this instanceof Pos)) { return new Pos(line, ch, sticky) }\n  this.line = line\n  this.ch = ch\n  this.sticky = sticky\n}\n\n// Compare two positions, return 0 if they are the same, a negative\n// number when a is less, and a positive number otherwise.\nfunction cmp(a, b) { return a.line - b.line || a.ch - b.ch }\n\nfunction equalCursorPos(a, b) { return a.sticky == b.sticky && cmp(a, b) == 0 }\n\nfunction copyPos(x) {return Pos(x.line, x.ch)}\nfunction maxPos(a, b) { return cmp(a, b) < 0 ? b : a }\nfunction minPos(a, b) { return cmp(a, b) < 0 ? a : b }\n\n// Most of the external API clips given positions to make sure they\n// actually exist within the document.\nfunction clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1))}\nfunction clipPos(doc, pos) {\n  if (pos.line < doc.first) { return Pos(doc.first, 0) }\n  var last = doc.first + doc.size - 1\n  if (pos.line > last) { return Pos(last, getLine(doc, last).text.length) }\n  return clipToLen(pos, getLine(doc, pos.line).text.length)\n}\nfunction clipToLen(pos, linelen) {\n  var ch = pos.ch\n  if (ch == null || ch > linelen) { return Pos(pos.line, linelen) }\n  else if (ch < 0) { return Pos(pos.line, 0) }\n  else { return pos }\n}\nfunction clipPosArray(doc, array) {\n  var out = []\n  for (var i = 0; i < array.length; i++) { out[i] = clipPos(doc, array[i]) }\n  return out\n}\n\n// Optimize some code when these features are not used.\nvar sawReadOnlySpans = false;\nvar sawCollapsedSpans = false;\nfunction seeReadOnlySpans() {\n  sawReadOnlySpans = true\n}\n\nfunction seeCollapsedSpans() {\n  sawCollapsedSpans = true\n}\n\n// TEXTMARKER SPANS\n\nfunction MarkedSpan(marker, from, to) {\n  this.marker = marker\n  this.from = from; this.to = to\n}\n\n// Search an array of spans for a span matching the given marker.\nfunction getMarkedSpanFor(spans, marker) {\n  if (spans) { for (var i = 0; i < spans.length; ++i) {\n    var span = spans[i]\n    if (span.marker == marker) { return span }\n  } }\n}\n// Remove a span from an array, returning undefined if no spans are\n// left (we don't store arrays for lines without spans).\nfunction removeMarkedSpan(spans, span) {\n  var r\n  for (var i = 0; i < spans.length; ++i)\n    { if (spans[i] != span) { (r || (r = [])).push(spans[i]) } }\n  return r\n}\n// Add a span to a line.\nfunction addMarkedSpan(line, span) {\n  line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span]\n  span.marker.attachLine(line)\n}\n\n// Used for the algorithm that adjusts markers for a change in the\n// document. These functions cut an array of spans at a given\n// character position, returning an array of remaining chunks (or\n// undefined if nothing remains).\nfunction markedSpansBefore(old, startCh, isInsert) {\n  var nw\n  if (old) { for (var i = 0; i < old.length; ++i) {\n    var span = old[i], marker = span.marker\n    var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh)\n    if (startsBefore || span.from == startCh && marker.type == \"bookmark\" && (!isInsert || !span.marker.insertLeft)) {\n      var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh)\n      ;(nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to))\n    }\n  } }\n  return nw\n}\nfunction markedSpansAfter(old, endCh, isInsert) {\n  var nw\n  if (old) { for (var i = 0; i < old.length; ++i) {\n    var span = old[i], marker = span.marker\n    var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh)\n    if (endsAfter || span.from == endCh && marker.type == \"bookmark\" && (!isInsert || span.marker.insertLeft)) {\n      var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh)\n      ;(nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh,\n                                            span.to == null ? null : span.to - endCh))\n    }\n  } }\n  return nw\n}\n\n// Given a change object, compute the new set of marker spans that\n// cover the line in which the change took place. Removes spans\n// entirely within the change, reconnects spans belonging to the\n// same marker that appear on both sides of the change, and cuts off\n// spans partially within the change. Returns an array of span\n// arrays with one element for each line in (after) the change.\nfunction stretchSpansOverChange(doc, change) {\n  if (change.full) { return null }\n  var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans\n  var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans\n  if (!oldFirst && !oldLast) { return null }\n\n  var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0\n  // Get the spans that 'stick out' on both sides\n  var first = markedSpansBefore(oldFirst, startCh, isInsert)\n  var last = markedSpansAfter(oldLast, endCh, isInsert)\n\n  // Next, merge those two ends\n  var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0)\n  if (first) {\n    // Fix up .to properties of first\n    for (var i = 0; i < first.length; ++i) {\n      var span = first[i]\n      if (span.to == null) {\n        var found = getMarkedSpanFor(last, span.marker)\n        if (!found) { span.to = startCh }\n        else if (sameLine) { span.to = found.to == null ? null : found.to + offset }\n      }\n    }\n  }\n  if (last) {\n    // Fix up .from in last (or move them into first in case of sameLine)\n    for (var i$1 = 0; i$1 < last.length; ++i$1) {\n      var span$1 = last[i$1]\n      if (span$1.to != null) { span$1.to += offset }\n      if (span$1.from == null) {\n        var found$1 = getMarkedSpanFor(first, span$1.marker)\n        if (!found$1) {\n          span$1.from = offset\n          if (sameLine) { (first || (first = [])).push(span$1) }\n        }\n      } else {\n        span$1.from += offset\n        if (sameLine) { (first || (first = [])).push(span$1) }\n      }\n    }\n  }\n  // Make sure we didn't create any zero-length spans\n  if (first) { first = clearEmptySpans(first) }\n  if (last && last != first) { last = clearEmptySpans(last) }\n\n  var newMarkers = [first]\n  if (!sameLine) {\n    // Fill gap with whole-line-spans\n    var gap = change.text.length - 2, gapMarkers\n    if (gap > 0 && first)\n      { for (var i$2 = 0; i$2 < first.length; ++i$2)\n        { if (first[i$2].to == null)\n          { (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i$2].marker, null, null)) } } }\n    for (var i$3 = 0; i$3 < gap; ++i$3)\n      { newMarkers.push(gapMarkers) }\n    newMarkers.push(last)\n  }\n  return newMarkers\n}\n\n// Remove spans that are empty and don't have a clearWhenEmpty\n// option of false.\nfunction clearEmptySpans(spans) {\n  for (var i = 0; i < spans.length; ++i) {\n    var span = spans[i]\n    if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false)\n      { spans.splice(i--, 1) }\n  }\n  if (!spans.length) { return null }\n  return spans\n}\n\n// Used to 'clip' out readOnly ranges when making a change.\nfunction removeReadOnlyRanges(doc, from, to) {\n  var markers = null\n  doc.iter(from.line, to.line + 1, function (line) {\n    if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) {\n      var mark = line.markedSpans[i].marker\n      if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))\n        { (markers || (markers = [])).push(mark) }\n    } }\n  })\n  if (!markers) { return null }\n  var parts = [{from: from, to: to}]\n  for (var i = 0; i < markers.length; ++i) {\n    var mk = markers[i], m = mk.find(0)\n    for (var j = 0; j < parts.length; ++j) {\n      var p = parts[j]\n      if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) { continue }\n      var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to)\n      if (dfrom < 0 || !mk.inclusiveLeft && !dfrom)\n        { newParts.push({from: p.from, to: m.from}) }\n      if (dto > 0 || !mk.inclusiveRight && !dto)\n        { newParts.push({from: m.to, to: p.to}) }\n      parts.splice.apply(parts, newParts)\n      j += newParts.length - 3\n    }\n  }\n  return parts\n}\n\n// Connect or disconnect spans from a line.\nfunction detachMarkedSpans(line) {\n  var spans = line.markedSpans\n  if (!spans) { return }\n  for (var i = 0; i < spans.length; ++i)\n    { spans[i].marker.detachLine(line) }\n  line.markedSpans = null\n}\nfunction attachMarkedSpans(line, spans) {\n  if (!spans) { return }\n  for (var i = 0; i < spans.length; ++i)\n    { spans[i].marker.attachLine(line) }\n  line.markedSpans = spans\n}\n\n// Helpers used when computing which overlapping collapsed span\n// counts as the larger one.\nfunction extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0 }\nfunction extraRight(marker) { return marker.inclusiveRight ? 1 : 0 }\n\n// Returns a number indicating which of two overlapping collapsed\n// spans is larger (and thus includes the other). Falls back to\n// comparing ids when the spans cover exactly the same range.\nfunction compareCollapsedMarkers(a, b) {\n  var lenDiff = a.lines.length - b.lines.length\n  if (lenDiff != 0) { return lenDiff }\n  var aPos = a.find(), bPos = b.find()\n  var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b)\n  if (fromCmp) { return -fromCmp }\n  var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b)\n  if (toCmp) { return toCmp }\n  return b.id - a.id\n}\n\n// Find out whether a line ends or starts in a collapsed span. If\n// so, return the marker for that span.\nfunction collapsedSpanAtSide(line, start) {\n  var sps = sawCollapsedSpans && line.markedSpans, found\n  if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) {\n    sp = sps[i]\n    if (sp.marker.collapsed && (start ? sp.from : sp.to) == null &&\n        (!found || compareCollapsedMarkers(found, sp.marker) < 0))\n      { found = sp.marker }\n  } }\n  return found\n}\nfunction collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true) }\nfunction collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false) }\n\n// Test whether there exists a collapsed span that partially\n// overlaps (covers the start or end, but not both) of a new span.\n// Such overlap is not allowed.\nfunction conflictingCollapsedRange(doc, lineNo, from, to, marker) {\n  var line = getLine(doc, lineNo)\n  var sps = sawCollapsedSpans && line.markedSpans\n  if (sps) { for (var i = 0; i < sps.length; ++i) {\n    var sp = sps[i]\n    if (!sp.marker.collapsed) { continue }\n    var found = sp.marker.find(0)\n    var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker)\n    var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker)\n    if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) { continue }\n    if (fromCmp <= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.to, from) >= 0 : cmp(found.to, from) > 0) ||\n        fromCmp >= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.from, to) <= 0 : cmp(found.from, to) < 0))\n      { return true }\n  } }\n}\n\n// A visual line is a line as drawn on the screen. Folding, for\n// example, can cause multiple logical lines to appear on the same\n// visual line. This finds the start of the visual line that the\n// given line is part of (usually that is the line itself).\nfunction visualLine(line) {\n  var merged\n  while (merged = collapsedSpanAtStart(line))\n    { line = merged.find(-1, true).line }\n  return line\n}\n\nfunction visualLineEnd(line) {\n  var merged\n  while (merged = collapsedSpanAtEnd(line))\n    { line = merged.find(1, true).line }\n  return line\n}\n\n// Returns an array of logical lines that continue the visual line\n// started by the argument, or undefined if there are no such lines.\nfunction visualLineContinued(line) {\n  var merged, lines\n  while (merged = collapsedSpanAtEnd(line)) {\n    line = merged.find(1, true).line\n    ;(lines || (lines = [])).push(line)\n  }\n  return lines\n}\n\n// Get the line number of the start of the visual line that the\n// given line number is part of.\nfunction visualLineNo(doc, lineN) {\n  var line = getLine(doc, lineN), vis = visualLine(line)\n  if (line == vis) { return lineN }\n  return lineNo(vis)\n}\n\n// Get the line number of the start of the next visual line after\n// the given line.\nfunction visualLineEndNo(doc, lineN) {\n  if (lineN > doc.lastLine()) { return lineN }\n  var line = getLine(doc, lineN), merged\n  if (!lineIsHidden(doc, line)) { return lineN }\n  while (merged = collapsedSpanAtEnd(line))\n    { line = merged.find(1, true).line }\n  return lineNo(line) + 1\n}\n\n// Compute whether a line is hidden. Lines count as hidden when they\n// are part of a visual line that starts with another line, or when\n// they are entirely covered by collapsed, non-widget span.\nfunction lineIsHidden(doc, line) {\n  var sps = sawCollapsedSpans && line.markedSpans\n  if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) {\n    sp = sps[i]\n    if (!sp.marker.collapsed) { continue }\n    if (sp.from == null) { return true }\n    if (sp.marker.widgetNode) { continue }\n    if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))\n      { return true }\n  } }\n}\nfunction lineIsHiddenInner(doc, line, span) {\n  if (span.to == null) {\n    var end = span.marker.find(1, true)\n    return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker))\n  }\n  if (span.marker.inclusiveRight && span.to == line.text.length)\n    { return true }\n  for (var sp = (void 0), i = 0; i < line.markedSpans.length; ++i) {\n    sp = line.markedSpans[i]\n    if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to &&\n        (sp.to == null || sp.to != span.from) &&\n        (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&\n        lineIsHiddenInner(doc, line, sp)) { return true }\n  }\n}\n\n// Find the height above the given line.\nfunction heightAtLine(lineObj) {\n  lineObj = visualLine(lineObj)\n\n  var h = 0, chunk = lineObj.parent\n  for (var i = 0; i < chunk.lines.length; ++i) {\n    var line = chunk.lines[i]\n    if (line == lineObj) { break }\n    else { h += line.height }\n  }\n  for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {\n    for (var i$1 = 0; i$1 < p.children.length; ++i$1) {\n      var cur = p.children[i$1]\n      if (cur == chunk) { break }\n      else { h += cur.height }\n    }\n  }\n  return h\n}\n\n// Compute the character length of a line, taking into account\n// collapsed ranges (see markText) that might hide parts, and join\n// other lines onto it.\nfunction lineLength(line) {\n  if (line.height == 0) { return 0 }\n  var len = line.text.length, merged, cur = line\n  while (merged = collapsedSpanAtStart(cur)) {\n    var found = merged.find(0, true)\n    cur = found.from.line\n    len += found.from.ch - found.to.ch\n  }\n  cur = line\n  while (merged = collapsedSpanAtEnd(cur)) {\n    var found$1 = merged.find(0, true)\n    len -= cur.text.length - found$1.from.ch\n    cur = found$1.to.line\n    len += cur.text.length - found$1.to.ch\n  }\n  return len\n}\n\n// Find the longest line in the document.\nfunction findMaxLine(cm) {\n  var d = cm.display, doc = cm.doc\n  d.maxLine = getLine(doc, doc.first)\n  d.maxLineLength = lineLength(d.maxLine)\n  d.maxLineChanged = true\n  doc.iter(function (line) {\n    var len = lineLength(line)\n    if (len > d.maxLineLength) {\n      d.maxLineLength = len\n      d.maxLine = line\n    }\n  })\n}\n\n// BIDI HELPERS\n\nfunction iterateBidiSections(order, from, to, f) {\n  if (!order) { return f(from, to, \"ltr\") }\n  var found = false\n  for (var i = 0; i < order.length; ++i) {\n    var part = order[i]\n    if (part.from < to && part.to > from || from == to && part.to == from) {\n      f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? \"rtl\" : \"ltr\")\n      found = true\n    }\n  }\n  if (!found) { f(from, to, \"ltr\") }\n}\n\nvar bidiOther = null\nfunction getBidiPartAt(order, ch, sticky) {\n  var found\n  bidiOther = null\n  for (var i = 0; i < order.length; ++i) {\n    var cur = order[i]\n    if (cur.from < ch && cur.to > ch) { return i }\n    if (cur.to == ch) {\n      if (cur.from != cur.to && sticky == \"before\") { found = i }\n      else { bidiOther = i }\n    }\n    if (cur.from == ch) {\n      if (cur.from != cur.to && sticky != \"before\") { found = i }\n      else { bidiOther = i }\n    }\n  }\n  return found != null ? found : bidiOther\n}\n\n// Bidirectional ordering algorithm\n// See http://unicode.org/reports/tr9/tr9-13.html for the algorithm\n// that this (partially) implements.\n\n// One-char codes used for character types:\n// L (L):   Left-to-Right\n// R (R):   Right-to-Left\n// r (AL):  Right-to-Left Arabic\n// 1 (EN):  European Number\n// + (ES):  European Number Separator\n// % (ET):  European Number Terminator\n// n (AN):  Arabic Number\n// , (CS):  Common Number Separator\n// m (NSM): Non-Spacing Mark\n// b (BN):  Boundary Neutral\n// s (B):   Paragraph Separator\n// t (S):   Segment Separator\n// w (WS):  Whitespace\n// N (ON):  Other Neutrals\n\n// Returns null if characters are ordered as they appear\n// (left-to-right), or an array of sections ({from, to, level}\n// objects) in the order in which they occur visually.\nvar bidiOrdering = (function() {\n  // Character types for codepoints 0 to 0xff\n  var lowTypes = \"bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN\"\n  // Character types for codepoints 0x600 to 0x6f9\n  var arabicTypes = \"nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111\"\n  function charType(code) {\n    if (code <= 0xf7) { return lowTypes.charAt(code) }\n    else if (0x590 <= code && code <= 0x5f4) { return \"R\" }\n    else if (0x600 <= code && code <= 0x6f9) { return arabicTypes.charAt(code - 0x600) }\n    else if (0x6ee <= code && code <= 0x8ac) { return \"r\" }\n    else if (0x2000 <= code && code <= 0x200b) { return \"w\" }\n    else if (code == 0x200c) { return \"b\" }\n    else { return \"L\" }\n  }\n\n  var bidiRE = /[\\u0590-\\u05f4\\u0600-\\u06ff\\u0700-\\u08ac]/\n  var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/\n\n  function BidiSpan(level, from, to) {\n    this.level = level\n    this.from = from; this.to = to\n  }\n\n  return function(str, direction) {\n    var outerType = direction == \"ltr\" ? \"L\" : \"R\"\n\n    if (str.length == 0 || direction == \"ltr\" && !bidiRE.test(str)) { return false }\n    var len = str.length, types = []\n    for (var i = 0; i < len; ++i)\n      { types.push(charType(str.charCodeAt(i))) }\n\n    // W1. Examine each non-spacing mark (NSM) in the level run, and\n    // change the type of the NSM to the type of the previous\n    // character. If the NSM is at the start of the level run, it will\n    // get the type of sor.\n    for (var i$1 = 0, prev = outerType; i$1 < len; ++i$1) {\n      var type = types[i$1]\n      if (type == \"m\") { types[i$1] = prev }\n      else { prev = type }\n    }\n\n    // W2. Search backwards from each instance of a European number\n    // until the first strong type (R, L, AL, or sor) is found. If an\n    // AL is found, change the type of the European number to Arabic\n    // number.\n    // W3. Change all ALs to R.\n    for (var i$2 = 0, cur = outerType; i$2 < len; ++i$2) {\n      var type$1 = types[i$2]\n      if (type$1 == \"1\" && cur == \"r\") { types[i$2] = \"n\" }\n      else if (isStrong.test(type$1)) { cur = type$1; if (type$1 == \"r\") { types[i$2] = \"R\" } }\n    }\n\n    // W4. A single European separator between two European numbers\n    // changes to a European number. A single common separator between\n    // two numbers of the same type changes to that type.\n    for (var i$3 = 1, prev$1 = types[0]; i$3 < len - 1; ++i$3) {\n      var type$2 = types[i$3]\n      if (type$2 == \"+\" && prev$1 == \"1\" && types[i$3+1] == \"1\") { types[i$3] = \"1\" }\n      else if (type$2 == \",\" && prev$1 == types[i$3+1] &&\n               (prev$1 == \"1\" || prev$1 == \"n\")) { types[i$3] = prev$1 }\n      prev$1 = type$2\n    }\n\n    // W5. A sequence of European terminators adjacent to European\n    // numbers changes to all European numbers.\n    // W6. Otherwise, separators and terminators change to Other\n    // Neutral.\n    for (var i$4 = 0; i$4 < len; ++i$4) {\n      var type$3 = types[i$4]\n      if (type$3 == \",\") { types[i$4] = \"N\" }\n      else if (type$3 == \"%\") {\n        var end = (void 0)\n        for (end = i$4 + 1; end < len && types[end] == \"%\"; ++end) {}\n        var replace = (i$4 && types[i$4-1] == \"!\") || (end < len && types[end] == \"1\") ? \"1\" : \"N\"\n        for (var j = i$4; j < end; ++j) { types[j] = replace }\n        i$4 = end - 1\n      }\n    }\n\n    // W7. Search backwards from each instance of a European number\n    // until the first strong type (R, L, or sor) is found. If an L is\n    // found, then change the type of the European number to L.\n    for (var i$5 = 0, cur$1 = outerType; i$5 < len; ++i$5) {\n      var type$4 = types[i$5]\n      if (cur$1 == \"L\" && type$4 == \"1\") { types[i$5] = \"L\" }\n      else if (isStrong.test(type$4)) { cur$1 = type$4 }\n    }\n\n    // N1. A sequence of neutrals takes the direction of the\n    // surrounding strong text if the text on both sides has the same\n    // direction. European and Arabic numbers act as if they were R in\n    // terms of their influence on neutrals. Start-of-level-run (sor)\n    // and end-of-level-run (eor) are used at level run boundaries.\n    // N2. Any remaining neutrals take the embedding direction.\n    for (var i$6 = 0; i$6 < len; ++i$6) {\n      if (isNeutral.test(types[i$6])) {\n        var end$1 = (void 0)\n        for (end$1 = i$6 + 1; end$1 < len && isNeutral.test(types[end$1]); ++end$1) {}\n        var before = (i$6 ? types[i$6-1] : outerType) == \"L\"\n        var after = (end$1 < len ? types[end$1] : outerType) == \"L\"\n        var replace$1 = before == after ? (before ? \"L\" : \"R\") : outerType\n        for (var j$1 = i$6; j$1 < end$1; ++j$1) { types[j$1] = replace$1 }\n        i$6 = end$1 - 1\n      }\n    }\n\n    // Here we depart from the documented algorithm, in order to avoid\n    // building up an actual levels array. Since there are only three\n    // levels (0, 1, 2) in an implementation that doesn't take\n    // explicit embedding into account, we can build up the order on\n    // the fly, without following the level-based algorithm.\n    var order = [], m\n    for (var i$7 = 0; i$7 < len;) {\n      if (countsAsLeft.test(types[i$7])) {\n        var start = i$7\n        for (++i$7; i$7 < len && countsAsLeft.test(types[i$7]); ++i$7) {}\n        order.push(new BidiSpan(0, start, i$7))\n      } else {\n        var pos = i$7, at = order.length\n        for (++i$7; i$7 < len && types[i$7] != \"L\"; ++i$7) {}\n        for (var j$2 = pos; j$2 < i$7;) {\n          if (countsAsNum.test(types[j$2])) {\n            if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)) }\n            var nstart = j$2\n            for (++j$2; j$2 < i$7 && countsAsNum.test(types[j$2]); ++j$2) {}\n            order.splice(at, 0, new BidiSpan(2, nstart, j$2))\n            pos = j$2\n          } else { ++j$2 }\n        }\n        if (pos < i$7) { order.splice(at, 0, new BidiSpan(1, pos, i$7)) }\n      }\n    }\n    if (order[0].level == 1 && (m = str.match(/^\\s+/))) {\n      order[0].from = m[0].length\n      order.unshift(new BidiSpan(0, 0, m[0].length))\n    }\n    if (lst(order).level == 1 && (m = str.match(/\\s+$/))) {\n      lst(order).to -= m[0].length\n      order.push(new BidiSpan(0, len - m[0].length, len))\n    }\n\n    return direction == \"rtl\" ? order.reverse() : order\n  }\n})()\n\n// Get the bidi ordering for the given line (and cache it). Returns\n// false for lines that are fully left-to-right, and an array of\n// BidiSpan objects otherwise.\nfunction getOrder(line, direction) {\n  var order = line.order\n  if (order == null) { order = line.order = bidiOrdering(line.text, direction) }\n  return order\n}\n\nfunction moveCharLogically(line, ch, dir) {\n  var target = skipExtendingChars(line.text, ch + dir, dir)\n  return target < 0 || target > line.text.length ? null : target\n}\n\nfunction moveLogically(line, start, dir) {\n  var ch = moveCharLogically(line, start.ch, dir)\n  return ch == null ? null : new Pos(start.line, ch, dir < 0 ? \"after\" : \"before\")\n}\n\nfunction endOfLine(visually, cm, lineObj, lineNo, dir) {\n  if (visually) {\n    var order = getOrder(lineObj, cm.doc.direction)\n    if (order) {\n      var part = dir < 0 ? lst(order) : order[0]\n      var moveInStorageOrder = (dir < 0) == (part.level == 1)\n      var sticky = moveInStorageOrder ? \"after\" : \"before\"\n      var ch\n      // With a wrapped rtl chunk (possibly spanning multiple bidi parts),\n      // it could be that the last bidi part is not on the last visual line,\n      // since visual lines contain content order-consecutive chunks.\n      // Thus, in rtl, we are looking for the first (content-order) character\n      // in the rtl chunk that is on the last line (that is, the same line\n      // as the last (content-order) character).\n      if (part.level > 0) {\n        var prep = prepareMeasureForLine(cm, lineObj)\n        ch = dir < 0 ? lineObj.text.length - 1 : 0\n        var targetTop = measureCharPrepared(cm, prep, ch).top\n        ch = findFirst(function (ch) { return measureCharPrepared(cm, prep, ch).top == targetTop; }, (dir < 0) == (part.level == 1) ? part.from : part.to - 1, ch)\n        if (sticky == \"before\") { ch = moveCharLogically(lineObj, ch, 1) }\n      } else { ch = dir < 0 ? part.to : part.from }\n      return new Pos(lineNo, ch, sticky)\n    }\n  }\n  return new Pos(lineNo, dir < 0 ? lineObj.text.length : 0, dir < 0 ? \"before\" : \"after\")\n}\n\nfunction moveVisually(cm, line, start, dir) {\n  var bidi = getOrder(line, cm.doc.direction)\n  if (!bidi) { return moveLogically(line, start, dir) }\n  if (start.ch >= line.text.length) {\n    start.ch = line.text.length\n    start.sticky = \"before\"\n  } else if (start.ch <= 0) {\n    start.ch = 0\n    start.sticky = \"after\"\n  }\n  var partPos = getBidiPartAt(bidi, start.ch, start.sticky), part = bidi[partPos]\n  if (cm.doc.direction == \"ltr\" && part.level % 2 == 0 && (dir > 0 ? part.to > start.ch : part.from < start.ch)) {\n    // Case 1: We move within an ltr part in an ltr editor. Even with wrapped lines,\n    // nothing interesting happens.\n    return moveLogically(line, start, dir)\n  }\n\n  var mv = function (pos, dir) { return moveCharLogically(line, pos instanceof Pos ? pos.ch : pos, dir); }\n  var prep\n  var getWrappedLineExtent = function (ch) {\n    if (!cm.options.lineWrapping) { return {begin: 0, end: line.text.length} }\n    prep = prep || prepareMeasureForLine(cm, line)\n    return wrappedLineExtentChar(cm, line, prep, ch)\n  }\n  var wrappedLineExtent = getWrappedLineExtent(start.sticky == \"before\" ? mv(start, -1) : start.ch)\n\n  if (cm.doc.direction == \"rtl\" || part.level == 1) {\n    var moveInStorageOrder = (part.level == 1) == (dir < 0)\n    var ch = mv(start, moveInStorageOrder ? 1 : -1)\n    if (ch != null && (!moveInStorageOrder ? ch >= part.from && ch >= wrappedLineExtent.begin : ch <= part.to && ch <= wrappedLineExtent.end)) {\n      // Case 2: We move within an rtl part or in an rtl editor on the same visual line\n      var sticky = moveInStorageOrder ? \"before\" : \"after\"\n      return new Pos(start.line, ch, sticky)\n    }\n  }\n\n  // Case 3: Could not move within this bidi part in this visual line, so leave\n  // the current bidi part\n\n  var searchInVisualLine = function (partPos, dir, wrappedLineExtent) {\n    var getRes = function (ch, moveInStorageOrder) { return moveInStorageOrder\n      ? new Pos(start.line, mv(ch, 1), \"before\")\n      : new Pos(start.line, ch, \"after\"); }\n\n    for (; partPos >= 0 && partPos < bidi.length; partPos += dir) {\n      var part = bidi[partPos]\n      var moveInStorageOrder = (dir > 0) == (part.level != 1)\n      var ch = moveInStorageOrder ? wrappedLineExtent.begin : mv(wrappedLineExtent.end, -1)\n      if (part.from <= ch && ch < part.to) { return getRes(ch, moveInStorageOrder) }\n      ch = moveInStorageOrder ? part.from : mv(part.to, -1)\n      if (wrappedLineExtent.begin <= ch && ch < wrappedLineExtent.end) { return getRes(ch, moveInStorageOrder) }\n    }\n  }\n\n  // Case 3a: Look for other bidi parts on the same visual line\n  var res = searchInVisualLine(partPos + dir, dir, wrappedLineExtent)\n  if (res) { return res }\n\n  // Case 3b: Look for other bidi parts on the next visual line\n  var nextCh = dir > 0 ? wrappedLineExtent.end : mv(wrappedLineExtent.begin, -1)\n  if (nextCh != null && !(dir > 0 && nextCh == line.text.length)) {\n    res = searchInVisualLine(dir > 0 ? 0 : bidi.length - 1, dir, getWrappedLineExtent(nextCh))\n    if (res) { return res }\n  }\n\n  // Case 4: Nowhere to move\n  return null\n}\n\n// EVENT HANDLING\n\n// Lightweight event framework. on/off also work on DOM nodes,\n// registering native DOM handlers.\n\nvar noHandlers = []\n\nvar on = function(emitter, type, f) {\n  if (emitter.addEventListener) {\n    emitter.addEventListener(type, f, false)\n  } else if (emitter.attachEvent) {\n    emitter.attachEvent(\"on\" + type, f)\n  } else {\n    var map = emitter._handlers || (emitter._handlers = {})\n    map[type] = (map[type] || noHandlers).concat(f)\n  }\n}\n\nfunction getHandlers(emitter, type) {\n  return emitter._handlers && emitter._handlers[type] || noHandlers\n}\n\nfunction off(emitter, type, f) {\n  if (emitter.removeEventListener) {\n    emitter.removeEventListener(type, f, false)\n  } else if (emitter.detachEvent) {\n    emitter.detachEvent(\"on\" + type, f)\n  } else {\n    var map = emitter._handlers, arr = map && map[type]\n    if (arr) {\n      var index = indexOf(arr, f)\n      if (index > -1)\n        { map[type] = arr.slice(0, index).concat(arr.slice(index + 1)) }\n    }\n  }\n}\n\nfunction signal(emitter, type /*, values...*/) {\n  var handlers = getHandlers(emitter, type)\n  if (!handlers.length) { return }\n  var args = Array.prototype.slice.call(arguments, 2)\n  for (var i = 0; i < handlers.length; ++i) { handlers[i].apply(null, args) }\n}\n\n// The DOM events that CodeMirror handles can be overridden by\n// registering a (non-DOM) handler on the editor for the event name,\n// and preventDefault-ing the event in that handler.\nfunction signalDOMEvent(cm, e, override) {\n  if (typeof e == \"string\")\n    { e = {type: e, preventDefault: function() { this.defaultPrevented = true }} }\n  signal(cm, override || e.type, cm, e)\n  return e_defaultPrevented(e) || e.codemirrorIgnore\n}\n\nfunction signalCursorActivity(cm) {\n  var arr = cm._handlers && cm._handlers.cursorActivity\n  if (!arr) { return }\n  var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = [])\n  for (var i = 0; i < arr.length; ++i) { if (indexOf(set, arr[i]) == -1)\n    { set.push(arr[i]) } }\n}\n\nfunction hasHandler(emitter, type) {\n  return getHandlers(emitter, type).length > 0\n}\n\n// Add on and off methods to a constructor's prototype, to make\n// registering events on such objects more convenient.\nfunction eventMixin(ctor) {\n  ctor.prototype.on = function(type, f) {on(this, type, f)}\n  ctor.prototype.off = function(type, f) {off(this, type, f)}\n}\n\n// Due to the fact that we still support jurassic IE versions, some\n// compatibility wrappers are needed.\n\nfunction e_preventDefault(e) {\n  if (e.preventDefault) { e.preventDefault() }\n  else { e.returnValue = false }\n}\nfunction e_stopPropagation(e) {\n  if (e.stopPropagation) { e.stopPropagation() }\n  else { e.cancelBubble = true }\n}\nfunction e_defaultPrevented(e) {\n  return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false\n}\nfunction e_stop(e) {e_preventDefault(e); e_stopPropagation(e)}\n\nfunction e_target(e) {return e.target || e.srcElement}\nfunction e_button(e) {\n  var b = e.which\n  if (b == null) {\n    if (e.button & 1) { b = 1 }\n    else if (e.button & 2) { b = 3 }\n    else if (e.button & 4) { b = 2 }\n  }\n  if (mac && e.ctrlKey && b == 1) { b = 3 }\n  return b\n}\n\n// Detect drag-and-drop\nvar dragAndDrop = function() {\n  // There is *some* kind of drag-and-drop support in IE6-8, but I\n  // couldn't get it to work yet.\n  if (ie && ie_version < 9) { return false }\n  var div = elt('div')\n  return \"draggable\" in div || \"dragDrop\" in div\n}()\n\nvar zwspSupported\nfunction zeroWidthElement(measure) {\n  if (zwspSupported == null) {\n    var test = elt(\"span\", \"\\u200b\")\n    removeChildrenAndAdd(measure, elt(\"span\", [test, document.createTextNode(\"x\")]))\n    if (measure.firstChild.offsetHeight != 0)\n      { zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8) }\n  }\n  var node = zwspSupported ? elt(\"span\", \"\\u200b\") :\n    elt(\"span\", \"\\u00a0\", null, \"display: inline-block; width: 1px; margin-right: -1px\")\n  node.setAttribute(\"cm-text\", \"\")\n  return node\n}\n\n// Feature-detect IE's crummy client rect reporting for bidi text\nvar badBidiRects\nfunction hasBadBidiRects(measure) {\n  if (badBidiRects != null) { return badBidiRects }\n  var txt = removeChildrenAndAdd(measure, document.createTextNode(\"A\\u062eA\"))\n  var r0 = range(txt, 0, 1).getBoundingClientRect()\n  var r1 = range(txt, 1, 2).getBoundingClientRect()\n  removeChildren(measure)\n  if (!r0 || r0.left == r0.right) { return false } // Safari returns null in some cases (#2780)\n  return badBidiRects = (r1.right - r0.right < 3)\n}\n\n// See if \"\".split is the broken IE version, if so, provide an\n// alternative way to split lines.\nvar splitLinesAuto = \"\\n\\nb\".split(/\\n/).length != 3 ? function (string) {\n  var pos = 0, result = [], l = string.length\n  while (pos <= l) {\n    var nl = string.indexOf(\"\\n\", pos)\n    if (nl == -1) { nl = string.length }\n    var line = string.slice(pos, string.charAt(nl - 1) == \"\\r\" ? nl - 1 : nl)\n    var rt = line.indexOf(\"\\r\")\n    if (rt != -1) {\n      result.push(line.slice(0, rt))\n      pos += rt + 1\n    } else {\n      result.push(line)\n      pos = nl + 1\n    }\n  }\n  return result\n} : function (string) { return string.split(/\\r\\n?|\\n/); }\n\nvar hasSelection = window.getSelection ? function (te) {\n  try { return te.selectionStart != te.selectionEnd }\n  catch(e) { return false }\n} : function (te) {\n  var range\n  try {range = te.ownerDocument.selection.createRange()}\n  catch(e) {}\n  if (!range || range.parentElement() != te) { return false }\n  return range.compareEndPoints(\"StartToEnd\", range) != 0\n}\n\nvar hasCopyEvent = (function () {\n  var e = elt(\"div\")\n  if (\"oncopy\" in e) { return true }\n  e.setAttribute(\"oncopy\", \"return;\")\n  return typeof e.oncopy == \"function\"\n})()\n\nvar badZoomedRects = null\nfunction hasBadZoomedRects(measure) {\n  if (badZoomedRects != null) { return badZoomedRects }\n  var node = removeChildrenAndAdd(measure, elt(\"span\", \"x\"))\n  var normal = node.getBoundingClientRect()\n  var fromRange = range(node, 0, 1).getBoundingClientRect()\n  return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1\n}\n\nvar modes = {};\nvar mimeModes = {};\n// Extra arguments are stored as the mode's dependencies, which is\n// used by (legacy) mechanisms like loadmode.js to automatically\n// load a mode. (Preferred mechanism is the require/define calls.)\nfunction defineMode(name, mode) {\n  if (arguments.length > 2)\n    { mode.dependencies = Array.prototype.slice.call(arguments, 2) }\n  modes[name] = mode\n}\n\nfunction defineMIME(mime, spec) {\n  mimeModes[mime] = spec\n}\n\n// Given a MIME type, a {name, ...options} config object, or a name\n// string, return a mode config object.\nfunction resolveMode(spec) {\n  if (typeof spec == \"string\" && mimeModes.hasOwnProperty(spec)) {\n    spec = mimeModes[spec]\n  } else if (spec && typeof spec.name == \"string\" && mimeModes.hasOwnProperty(spec.name)) {\n    var found = mimeModes[spec.name]\n    if (typeof found == \"string\") { found = {name: found} }\n    spec = createObj(found, spec)\n    spec.name = found.name\n  } else if (typeof spec == \"string\" && /^[\\w\\-]+\\/[\\w\\-]+\\+xml$/.test(spec)) {\n    return resolveMode(\"application/xml\")\n  } else if (typeof spec == \"string\" && /^[\\w\\-]+\\/[\\w\\-]+\\+json$/.test(spec)) {\n    return resolveMode(\"application/json\")\n  }\n  if (typeof spec == \"string\") { return {name: spec} }\n  else { return spec || {name: \"null\"} }\n}\n\n// Given a mode spec (anything that resolveMode accepts), find and\n// initialize an actual mode object.\nfunction getMode(options, spec) {\n  spec = resolveMode(spec)\n  var mfactory = modes[spec.name]\n  if (!mfactory) { return getMode(options, \"text/plain\") }\n  var modeObj = mfactory(options, spec)\n  if (modeExtensions.hasOwnProperty(spec.name)) {\n    var exts = modeExtensions[spec.name]\n    for (var prop in exts) {\n      if (!exts.hasOwnProperty(prop)) { continue }\n      if (modeObj.hasOwnProperty(prop)) { modeObj[\"_\" + prop] = modeObj[prop] }\n      modeObj[prop] = exts[prop]\n    }\n  }\n  modeObj.name = spec.name\n  if (spec.helperType) { modeObj.helperType = spec.helperType }\n  if (spec.modeProps) { for (var prop$1 in spec.modeProps)\n    { modeObj[prop$1] = spec.modeProps[prop$1] } }\n\n  return modeObj\n}\n\n// This can be used to attach properties to mode objects from\n// outside the actual mode definition.\nvar modeExtensions = {}\nfunction extendMode(mode, properties) {\n  var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {})\n  copyObj(properties, exts)\n}\n\nfunction copyState(mode, state) {\n  if (state === true) { return state }\n  if (mode.copyState) { return mode.copyState(state) }\n  var nstate = {}\n  for (var n in state) {\n    var val = state[n]\n    if (val instanceof Array) { val = val.concat([]) }\n    nstate[n] = val\n  }\n  return nstate\n}\n\n// Given a mode and a state (for that mode), find the inner mode and\n// state at the position that the state refers to.\nfunction innerMode(mode, state) {\n  var info\n  while (mode.innerMode) {\n    info = mode.innerMode(state)\n    if (!info || info.mode == mode) { break }\n    state = info.state\n    mode = info.mode\n  }\n  return info || {mode: mode, state: state}\n}\n\nfunction startState(mode, a1, a2) {\n  return mode.startState ? mode.startState(a1, a2) : true\n}\n\n// STRING STREAM\n\n// Fed to the mode parsers, provides helper functions to make\n// parsers more succinct.\n\nvar StringStream = function(string, tabSize, lineOracle) {\n  this.pos = this.start = 0\n  this.string = string\n  this.tabSize = tabSize || 8\n  this.lastColumnPos = this.lastColumnValue = 0\n  this.lineStart = 0\n  this.lineOracle = lineOracle\n};\n\nStringStream.prototype.eol = function () {return this.pos >= this.string.length};\nStringStream.prototype.sol = function () {return this.pos == this.lineStart};\nStringStream.prototype.peek = function () {return this.string.charAt(this.pos) || undefined};\nStringStream.prototype.next = function () {\n  if (this.pos < this.string.length)\n    { return this.string.charAt(this.pos++) }\n};\nStringStream.prototype.eat = function (match) {\n  var ch = this.string.charAt(this.pos)\n  var ok\n  if (typeof match == \"string\") { ok = ch == match }\n  else { ok = ch && (match.test ? match.test(ch) : match(ch)) }\n  if (ok) {++this.pos; return ch}\n};\nStringStream.prototype.eatWhile = function (match) {\n  var start = this.pos\n  while (this.eat(match)){}\n  return this.pos > start\n};\nStringStream.prototype.eatSpace = function () {\n    var this$1 = this;\n\n  var start = this.pos\n  while (/[\\s\\u00a0]/.test(this.string.charAt(this.pos))) { ++this$1.pos }\n  return this.pos > start\n};\nStringStream.prototype.skipToEnd = function () {this.pos = this.string.length};\nStringStream.prototype.skipTo = function (ch) {\n  var found = this.string.indexOf(ch, this.pos)\n  if (found > -1) {this.pos = found; return true}\n};\nStringStream.prototype.backUp = function (n) {this.pos -= n};\nStringStream.prototype.column = function () {\n  if (this.lastColumnPos < this.start) {\n    this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue)\n    this.lastColumnPos = this.start\n  }\n  return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)\n};\nStringStream.prototype.indentation = function () {\n  return countColumn(this.string, null, this.tabSize) -\n    (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)\n};\nStringStream.prototype.match = function (pattern, consume, caseInsensitive) {\n  if (typeof pattern == \"string\") {\n    var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; }\n    var substr = this.string.substr(this.pos, pattern.length)\n    if (cased(substr) == cased(pattern)) {\n      if (consume !== false) { this.pos += pattern.length }\n      return true\n    }\n  } else {\n    var match = this.string.slice(this.pos).match(pattern)\n    if (match && match.index > 0) { return null }\n    if (match && consume !== false) { this.pos += match[0].length }\n    return match\n  }\n};\nStringStream.prototype.current = function (){return this.string.slice(this.start, this.pos)};\nStringStream.prototype.hideFirstChars = function (n, inner) {\n  this.lineStart += n\n  try { return inner() }\n  finally { this.lineStart -= n }\n};\nStringStream.prototype.lookAhead = function (n) {\n  var oracle = this.lineOracle\n  return oracle && oracle.lookAhead(n)\n};\n\nvar SavedContext = function(state, lookAhead) {\n  this.state = state\n  this.lookAhead = lookAhead\n};\n\nvar Context = function(doc, state, line, lookAhead) {\n  this.state = state\n  this.doc = doc\n  this.line = line\n  this.maxLookAhead = lookAhead || 0\n};\n\nContext.prototype.lookAhead = function (n) {\n  var line = this.doc.getLine(this.line + n)\n  if (line != null && n > this.maxLookAhead) { this.maxLookAhead = n }\n  return line\n};\n\nContext.prototype.nextLine = function () {\n  this.line++\n  if (this.maxLookAhead > 0) { this.maxLookAhead-- }\n};\n\nContext.fromSaved = function (doc, saved, line) {\n  if (saved instanceof SavedContext)\n    { return new Context(doc, copyState(doc.mode, saved.state), line, saved.lookAhead) }\n  else\n    { return new Context(doc, copyState(doc.mode, saved), line) }\n};\n\nContext.prototype.save = function (copy) {\n  var state = copy !== false ? copyState(this.doc.mode, this.state) : this.state\n  return this.maxLookAhead > 0 ? new SavedContext(state, this.maxLookAhead) : state\n};\n\n\n// Compute a style array (an array starting with a mode generation\n// -- for invalidation -- followed by pairs of end positions and\n// style strings), which is used to highlight the tokens on the\n// line.\nfunction highlightLine(cm, line, context, forceToEnd) {\n  // A styles array always starts with a number identifying the\n  // mode/overlays that it is based on (for easy invalidation).\n  var st = [cm.state.modeGen], lineClasses = {}\n  // Compute the base array of styles\n  runMode(cm, line.text, cm.doc.mode, context, function (end, style) { return st.push(end, style); },\n          lineClasses, forceToEnd)\n  var state = context.state\n\n  // Run overlays, adjust style array.\n  var loop = function ( o ) {\n    var overlay = cm.state.overlays[o], i = 1, at = 0\n    context.state = true\n    runMode(cm, line.text, overlay.mode, context, function (end, style) {\n      var start = i\n      // Ensure there's a token end at the current position, and that i points at it\n      while (at < end) {\n        var i_end = st[i]\n        if (i_end > end)\n          { st.splice(i, 1, end, st[i+1], i_end) }\n        i += 2\n        at = Math.min(end, i_end)\n      }\n      if (!style) { return }\n      if (overlay.opaque) {\n        st.splice(start, i - start, end, \"overlay \" + style)\n        i = start + 2\n      } else {\n        for (; start < i; start += 2) {\n          var cur = st[start+1]\n          st[start+1] = (cur ? cur + \" \" : \"\") + \"overlay \" + style\n        }\n      }\n    }, lineClasses)\n  };\n\n  for (var o = 0; o < cm.state.overlays.length; ++o) loop( o );\n  context.state = state\n\n  return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null}\n}\n\nfunction getLineStyles(cm, line, updateFrontier) {\n  if (!line.styles || line.styles[0] != cm.state.modeGen) {\n    var context = getContextBefore(cm, lineNo(line))\n    var resetState = line.text.length > cm.options.maxHighlightLength && copyState(cm.doc.mode, context.state)\n    var result = highlightLine(cm, line, context)\n    if (resetState) { context.state = resetState }\n    line.stateAfter = context.save(!resetState)\n    line.styles = result.styles\n    if (result.classes) { line.styleClasses = result.classes }\n    else if (line.styleClasses) { line.styleClasses = null }\n    if (updateFrontier === cm.doc.highlightFrontier)\n      { cm.doc.modeFrontier = Math.max(cm.doc.modeFrontier, ++cm.doc.highlightFrontier) }\n  }\n  return line.styles\n}\n\nfunction getContextBefore(cm, n, precise) {\n  var doc = cm.doc, display = cm.display\n  if (!doc.mode.startState) { return new Context(doc, true, n) }\n  var start = findStartLine(cm, n, precise)\n  var saved = start > doc.first && getLine(doc, start - 1).stateAfter\n  var context = saved ? Context.fromSaved(doc, saved, start) : new Context(doc, startState(doc.mode), start)\n\n  doc.iter(start, n, function (line) {\n    processLine(cm, line.text, context)\n    var pos = context.line\n    line.stateAfter = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo ? context.save() : null\n    context.nextLine()\n  })\n  if (precise) { doc.modeFrontier = context.line }\n  return context\n}\n\n// Lightweight form of highlight -- proceed over this line and\n// update state, but don't save a style array. Used for lines that\n// aren't currently visible.\nfunction processLine(cm, text, context, startAt) {\n  var mode = cm.doc.mode\n  var stream = new StringStream(text, cm.options.tabSize, context)\n  stream.start = stream.pos = startAt || 0\n  if (text == \"\") { callBlankLine(mode, context.state) }\n  while (!stream.eol()) {\n    readToken(mode, stream, context.state)\n    stream.start = stream.pos\n  }\n}\n\nfunction callBlankLine(mode, state) {\n  if (mode.blankLine) { return mode.blankLine(state) }\n  if (!mode.innerMode) { return }\n  var inner = innerMode(mode, state)\n  if (inner.mode.blankLine) { return inner.mode.blankLine(inner.state) }\n}\n\nfunction readToken(mode, stream, state, inner) {\n  for (var i = 0; i < 10; i++) {\n    if (inner) { inner[0] = innerMode(mode, state).mode }\n    var style = mode.token(stream, state)\n    if (stream.pos > stream.start) { return style }\n  }\n  throw new Error(\"Mode \" + mode.name + \" failed to advance stream.\")\n}\n\nvar Token = function(stream, type, state) {\n  this.start = stream.start; this.end = stream.pos\n  this.string = stream.current()\n  this.type = type || null\n  this.state = state\n};\n\n// Utility for getTokenAt and getLineTokens\nfunction takeToken(cm, pos, precise, asArray) {\n  var doc = cm.doc, mode = doc.mode, style\n  pos = clipPos(doc, pos)\n  var line = getLine(doc, pos.line), context = getContextBefore(cm, pos.line, precise)\n  var stream = new StringStream(line.text, cm.options.tabSize, context), tokens\n  if (asArray) { tokens = [] }\n  while ((asArray || stream.pos < pos.ch) && !stream.eol()) {\n    stream.start = stream.pos\n    style = readToken(mode, stream, context.state)\n    if (asArray) { tokens.push(new Token(stream, style, copyState(doc.mode, context.state))) }\n  }\n  return asArray ? tokens : new Token(stream, style, context.state)\n}\n\nfunction extractLineClasses(type, output) {\n  if (type) { for (;;) {\n    var lineClass = type.match(/(?:^|\\s+)line-(background-)?(\\S+)/)\n    if (!lineClass) { break }\n    type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length)\n    var prop = lineClass[1] ? \"bgClass\" : \"textClass\"\n    if (output[prop] == null)\n      { output[prop] = lineClass[2] }\n    else if (!(new RegExp(\"(?:^|\\s)\" + lineClass[2] + \"(?:$|\\s)\")).test(output[prop]))\n      { output[prop] += \" \" + lineClass[2] }\n  } }\n  return type\n}\n\n// Run the given mode's parser over a line, calling f for each token.\nfunction runMode(cm, text, mode, context, f, lineClasses, forceToEnd) {\n  var flattenSpans = mode.flattenSpans\n  if (flattenSpans == null) { flattenSpans = cm.options.flattenSpans }\n  var curStart = 0, curStyle = null\n  var stream = new StringStream(text, cm.options.tabSize, context), style\n  var inner = cm.options.addModeClass && [null]\n  if (text == \"\") { extractLineClasses(callBlankLine(mode, context.state), lineClasses) }\n  while (!stream.eol()) {\n    if (stream.pos > cm.options.maxHighlightLength) {\n      flattenSpans = false\n      if (forceToEnd) { processLine(cm, text, context, stream.pos) }\n      stream.pos = text.length\n      style = null\n    } else {\n      style = extractLineClasses(readToken(mode, stream, context.state, inner), lineClasses)\n    }\n    if (inner) {\n      var mName = inner[0].name\n      if (mName) { style = \"m-\" + (style ? mName + \" \" + style : mName) }\n    }\n    if (!flattenSpans || curStyle != style) {\n      while (curStart < stream.start) {\n        curStart = Math.min(stream.start, curStart + 5000)\n        f(curStart, curStyle)\n      }\n      curStyle = style\n    }\n    stream.start = stream.pos\n  }\n  while (curStart < stream.pos) {\n    // Webkit seems to refuse to render text nodes longer than 57444\n    // characters, and returns inaccurate measurements in nodes\n    // starting around 5000 chars.\n    var pos = Math.min(stream.pos, curStart + 5000)\n    f(pos, curStyle)\n    curStart = pos\n  }\n}\n\n// Finds the line to start with when starting a parse. Tries to\n// find a line with a stateAfter, so that it can start with a\n// valid state. If that fails, it returns the line with the\n// smallest indentation, which tends to need the least context to\n// parse correctly.\nfunction findStartLine(cm, n, precise) {\n  var minindent, minline, doc = cm.doc\n  var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100)\n  for (var search = n; search > lim; --search) {\n    if (search <= doc.first) { return doc.first }\n    var line = getLine(doc, search - 1), after = line.stateAfter\n    if (after && (!precise || search + (after instanceof SavedContext ? after.lookAhead : 0) <= doc.modeFrontier))\n      { return search }\n    var indented = countColumn(line.text, null, cm.options.tabSize)\n    if (minline == null || minindent > indented) {\n      minline = search - 1\n      minindent = indented\n    }\n  }\n  return minline\n}\n\nfunction retreatFrontier(doc, n) {\n  doc.modeFrontier = Math.min(doc.modeFrontier, n)\n  if (doc.highlightFrontier < n - 10) { return }\n  var start = doc.first\n  for (var line = n - 1; line > start; line--) {\n    var saved = getLine(doc, line).stateAfter\n    // change is on 3\n    // state on line 1 looked ahead 2 -- so saw 3\n    // test 1 + 2 < 3 should cover this\n    if (saved && (!(saved instanceof SavedContext) || line + saved.lookAhead < n)) {\n      start = line + 1\n      break\n    }\n  }\n  doc.highlightFrontier = Math.min(doc.highlightFrontier, start)\n}\n\n// LINE DATA STRUCTURE\n\n// Line objects. These hold state related to a line, including\n// highlighting info (the styles array).\nvar Line = function(text, markedSpans, estimateHeight) {\n  this.text = text\n  attachMarkedSpans(this, markedSpans)\n  this.height = estimateHeight ? estimateHeight(this) : 1\n};\n\nLine.prototype.lineNo = function () { return lineNo(this) };\neventMixin(Line)\n\n// Change the content (text, markers) of a line. Automatically\n// invalidates cached information and tries to re-estimate the\n// line's height.\nfunction updateLine(line, text, markedSpans, estimateHeight) {\n  line.text = text\n  if (line.stateAfter) { line.stateAfter = null }\n  if (line.styles) { line.styles = null }\n  if (line.order != null) { line.order = null }\n  detachMarkedSpans(line)\n  attachMarkedSpans(line, markedSpans)\n  var estHeight = estimateHeight ? estimateHeight(line) : 1\n  if (estHeight != line.height) { updateLineHeight(line, estHeight) }\n}\n\n// Detach a line from the document tree and its markers.\nfunction cleanUpLine(line) {\n  line.parent = null\n  detachMarkedSpans(line)\n}\n\n// Convert a style as returned by a mode (either null, or a string\n// containing one or more styles) to a CSS style. This is cached,\n// and also looks for line-wide styles.\nvar styleToClassCache = {};\nvar styleToClassCacheWithMode = {};\nfunction interpretTokenStyle(style, options) {\n  if (!style || /^\\s*$/.test(style)) { return null }\n  var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache\n  return cache[style] ||\n    (cache[style] = style.replace(/\\S+/g, \"cm-$&\"))\n}\n\n// Render the DOM representation of the text of a line. Also builds\n// up a 'line map', which points at the DOM nodes that represent\n// specific stretches of text, and is used by the measuring code.\n// The returned object contains the DOM node, this map, and\n// information about line-wide styles that were set by the mode.\nfunction buildLineContent(cm, lineView) {\n  // The padding-right forces the element to have a 'border', which\n  // is needed on Webkit to be able to get line-level bounding\n  // rectangles for it (in measureChar).\n  var content = eltP(\"span\", null, null, webkit ? \"padding-right: .1px\" : null)\n  var builder = {pre: eltP(\"pre\", [content], \"CodeMirror-line\"), content: content,\n                 col: 0, pos: 0, cm: cm,\n                 trailingSpace: false,\n                 splitSpaces: (ie || webkit) && cm.getOption(\"lineWrapping\")}\n  lineView.measure = {}\n\n  // Iterate over the logical lines that make up this visual line.\n  for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) {\n    var line = i ? lineView.rest[i - 1] : lineView.line, order = (void 0)\n    builder.pos = 0\n    builder.addToken = buildToken\n    // Optionally wire in some hacks into the token-rendering\n    // algorithm, to deal with browser quirks.\n    if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line, cm.doc.direction)))\n      { builder.addToken = buildTokenBadBidi(builder.addToken, order) }\n    builder.map = []\n    var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line)\n    insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate))\n    if (line.styleClasses) {\n      if (line.styleClasses.bgClass)\n        { builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || \"\") }\n      if (line.styleClasses.textClass)\n        { builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || \"\") }\n    }\n\n    // Ensure at least a single node is present, for measuring.\n    if (builder.map.length == 0)\n      { builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))) }\n\n    // Store the map and a cache object for the current logical line\n    if (i == 0) {\n      lineView.measure.map = builder.map\n      lineView.measure.cache = {}\n    } else {\n      ;(lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map)\n      ;(lineView.measure.caches || (lineView.measure.caches = [])).push({})\n    }\n  }\n\n  // See issue #2901\n  if (webkit) {\n    var last = builder.content.lastChild\n    if (/\\bcm-tab\\b/.test(last.className) || (last.querySelector && last.querySelector(\".cm-tab\")))\n      { builder.content.className = \"cm-tab-wrap-hack\" }\n  }\n\n  signal(cm, \"renderLine\", cm, lineView.line, builder.pre)\n  if (builder.pre.className)\n    { builder.textClass = joinClasses(builder.pre.className, builder.textClass || \"\") }\n\n  return builder\n}\n\nfunction defaultSpecialCharPlaceholder(ch) {\n  var token = elt(\"span\", \"\\u2022\", \"cm-invalidchar\")\n  token.title = \"\\\\u\" + ch.charCodeAt(0).toString(16)\n  token.setAttribute(\"aria-label\", token.title)\n  return token\n}\n\n// Build up the DOM representation for a single token, and add it to\n// the line map. Takes care to render special characters separately.\nfunction buildToken(builder, text, style, startStyle, endStyle, title, css) {\n  if (!text) { return }\n  var displayText = builder.splitSpaces ? splitSpaces(text, builder.trailingSpace) : text\n  var special = builder.cm.state.specialChars, mustWrap = false\n  var content\n  if (!special.test(text)) {\n    builder.col += text.length\n    content = document.createTextNode(displayText)\n    builder.map.push(builder.pos, builder.pos + text.length, content)\n    if (ie && ie_version < 9) { mustWrap = true }\n    builder.pos += text.length\n  } else {\n    content = document.createDocumentFragment()\n    var pos = 0\n    while (true) {\n      special.lastIndex = pos\n      var m = special.exec(text)\n      var skipped = m ? m.index - pos : text.length - pos\n      if (skipped) {\n        var txt = document.createTextNode(displayText.slice(pos, pos + skipped))\n        if (ie && ie_version < 9) { content.appendChild(elt(\"span\", [txt])) }\n        else { content.appendChild(txt) }\n        builder.map.push(builder.pos, builder.pos + skipped, txt)\n        builder.col += skipped\n        builder.pos += skipped\n      }\n      if (!m) { break }\n      pos += skipped + 1\n      var txt$1 = (void 0)\n      if (m[0] == \"\\t\") {\n        var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize\n        txt$1 = content.appendChild(elt(\"span\", spaceStr(tabWidth), \"cm-tab\"))\n        txt$1.setAttribute(\"role\", \"presentation\")\n        txt$1.setAttribute(\"cm-text\", \"\\t\")\n        builder.col += tabWidth\n      } else if (m[0] == \"\\r\" || m[0] == \"\\n\") {\n        txt$1 = content.appendChild(elt(\"span\", m[0] == \"\\r\" ? \"\\u240d\" : \"\\u2424\", \"cm-invalidchar\"))\n        txt$1.setAttribute(\"cm-text\", m[0])\n        builder.col += 1\n      } else {\n        txt$1 = builder.cm.options.specialCharPlaceholder(m[0])\n        txt$1.setAttribute(\"cm-text\", m[0])\n        if (ie && ie_version < 9) { content.appendChild(elt(\"span\", [txt$1])) }\n        else { content.appendChild(txt$1) }\n        builder.col += 1\n      }\n      builder.map.push(builder.pos, builder.pos + 1, txt$1)\n      builder.pos++\n    }\n  }\n  builder.trailingSpace = displayText.charCodeAt(text.length - 1) == 32\n  if (style || startStyle || endStyle || mustWrap || css) {\n    var fullStyle = style || \"\"\n    if (startStyle) { fullStyle += startStyle }\n    if (endStyle) { fullStyle += endStyle }\n    var token = elt(\"span\", [content], fullStyle, css)\n    if (title) { token.title = title }\n    return builder.content.appendChild(token)\n  }\n  builder.content.appendChild(content)\n}\n\nfunction splitSpaces(text, trailingBefore) {\n  if (text.length > 1 && !/  /.test(text)) { return text }\n  var spaceBefore = trailingBefore, result = \"\"\n  for (var i = 0; i < text.length; i++) {\n    var ch = text.charAt(i)\n    if (ch == \" \" && spaceBefore && (i == text.length - 1 || text.charCodeAt(i + 1) == 32))\n      { ch = \"\\u00a0\" }\n    result += ch\n    spaceBefore = ch == \" \"\n  }\n  return result\n}\n\n// Work around nonsense dimensions being reported for stretches of\n// right-to-left text.\nfunction buildTokenBadBidi(inner, order) {\n  return function (builder, text, style, startStyle, endStyle, title, css) {\n    style = style ? style + \" cm-force-border\" : \"cm-force-border\"\n    var start = builder.pos, end = start + text.length\n    for (;;) {\n      // Find the part that overlaps with the start of this text\n      var part = (void 0)\n      for (var i = 0; i < order.length; i++) {\n        part = order[i]\n        if (part.to > start && part.from <= start) { break }\n      }\n      if (part.to >= end) { return inner(builder, text, style, startStyle, endStyle, title, css) }\n      inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css)\n      startStyle = null\n      text = text.slice(part.to - start)\n      start = part.to\n    }\n  }\n}\n\nfunction buildCollapsedSpan(builder, size, marker, ignoreWidget) {\n  var widget = !ignoreWidget && marker.widgetNode\n  if (widget) { builder.map.push(builder.pos, builder.pos + size, widget) }\n  if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) {\n    if (!widget)\n      { widget = builder.content.appendChild(document.createElement(\"span\")) }\n    widget.setAttribute(\"cm-marker\", marker.id)\n  }\n  if (widget) {\n    builder.cm.display.input.setUneditable(widget)\n    builder.content.appendChild(widget)\n  }\n  builder.pos += size\n  builder.trailingSpace = false\n}\n\n// Outputs a number of spans to make up a line, taking highlighting\n// and marked text into account.\nfunction insertLineContent(line, builder, styles) {\n  var spans = line.markedSpans, allText = line.text, at = 0\n  if (!spans) {\n    for (var i$1 = 1; i$1 < styles.length; i$1+=2)\n      { builder.addToken(builder, allText.slice(at, at = styles[i$1]), interpretTokenStyle(styles[i$1+1], builder.cm.options)) }\n    return\n  }\n\n  var len = allText.length, pos = 0, i = 1, text = \"\", style, css\n  var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed\n  for (;;) {\n    if (nextChange == pos) { // Update current marker set\n      spanStyle = spanEndStyle = spanStartStyle = title = css = \"\"\n      collapsed = null; nextChange = Infinity\n      var foundBookmarks = [], endStyles = (void 0)\n      for (var j = 0; j < spans.length; ++j) {\n        var sp = spans[j], m = sp.marker\n        if (m.type == \"bookmark\" && sp.from == pos && m.widgetNode) {\n          foundBookmarks.push(m)\n        } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) {\n          if (sp.to != null && sp.to != pos && nextChange > sp.to) {\n            nextChange = sp.to\n            spanEndStyle = \"\"\n          }\n          if (m.className) { spanStyle += \" \" + m.className }\n          if (m.css) { css = (css ? css + \";\" : \"\") + m.css }\n          if (m.startStyle && sp.from == pos) { spanStartStyle += \" \" + m.startStyle }\n          if (m.endStyle && sp.to == nextChange) { (endStyles || (endStyles = [])).push(m.endStyle, sp.to) }\n          if (m.title && !title) { title = m.title }\n          if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))\n            { collapsed = sp }\n        } else if (sp.from > pos && nextChange > sp.from) {\n          nextChange = sp.from\n        }\n      }\n      if (endStyles) { for (var j$1 = 0; j$1 < endStyles.length; j$1 += 2)\n        { if (endStyles[j$1 + 1] == nextChange) { spanEndStyle += \" \" + endStyles[j$1] } } }\n\n      if (!collapsed || collapsed.from == pos) { for (var j$2 = 0; j$2 < foundBookmarks.length; ++j$2)\n        { buildCollapsedSpan(builder, 0, foundBookmarks[j$2]) } }\n      if (collapsed && (collapsed.from || 0) == pos) {\n        buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos,\n                           collapsed.marker, collapsed.from == null)\n        if (collapsed.to == null) { return }\n        if (collapsed.to == pos) { collapsed = false }\n      }\n    }\n    if (pos >= len) { break }\n\n    var upto = Math.min(len, nextChange)\n    while (true) {\n      if (text) {\n        var end = pos + text.length\n        if (!collapsed) {\n          var tokenText = end > upto ? text.slice(0, upto - pos) : text\n          builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,\n                           spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : \"\", title, css)\n        }\n        if (end >= upto) {text = text.slice(upto - pos); pos = upto; break}\n        pos = end\n        spanStartStyle = \"\"\n      }\n      text = allText.slice(at, at = styles[i++])\n      style = interpretTokenStyle(styles[i++], builder.cm.options)\n    }\n  }\n}\n\n\n// These objects are used to represent the visible (currently drawn)\n// part of the document. A LineView may correspond to multiple\n// logical lines, if those are connected by collapsed ranges.\nfunction LineView(doc, line, lineN) {\n  // The starting line\n  this.line = line\n  // Continuing lines, if any\n  this.rest = visualLineContinued(line)\n  // Number of logical lines in this visual line\n  this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1\n  this.node = this.text = null\n  this.hidden = lineIsHidden(doc, line)\n}\n\n// Create a range of LineView objects for the given lines.\nfunction buildViewArray(cm, from, to) {\n  var array = [], nextPos\n  for (var pos = from; pos < to; pos = nextPos) {\n    var view = new LineView(cm.doc, getLine(cm.doc, pos), pos)\n    nextPos = pos + view.size\n    array.push(view)\n  }\n  return array\n}\n\nvar operationGroup = null\n\nfunction pushOperation(op) {\n  if (operationGroup) {\n    operationGroup.ops.push(op)\n  } else {\n    op.ownsGroup = operationGroup = {\n      ops: [op],\n      delayedCallbacks: []\n    }\n  }\n}\n\nfunction fireCallbacksForOps(group) {\n  // Calls delayed callbacks and cursorActivity handlers until no\n  // new ones appear\n  var callbacks = group.delayedCallbacks, i = 0\n  do {\n    for (; i < callbacks.length; i++)\n      { callbacks[i].call(null) }\n    for (var j = 0; j < group.ops.length; j++) {\n      var op = group.ops[j]\n      if (op.cursorActivityHandlers)\n        { while (op.cursorActivityCalled < op.cursorActivityHandlers.length)\n          { op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm) } }\n    }\n  } while (i < callbacks.length)\n}\n\nfunction finishOperation(op, endCb) {\n  var group = op.ownsGroup\n  if (!group) { return }\n\n  try { fireCallbacksForOps(group) }\n  finally {\n    operationGroup = null\n    endCb(group)\n  }\n}\n\nvar orphanDelayedCallbacks = null\n\n// Often, we want to signal events at a point where we are in the\n// middle of some work, but don't want the handler to start calling\n// other methods on the editor, which might be in an inconsistent\n// state or simply not expect any other events to happen.\n// signalLater looks whether there are any handlers, and schedules\n// them to be executed when the last operation ends, or, if no\n// operation is active, when a timeout fires.\nfunction signalLater(emitter, type /*, values...*/) {\n  var arr = getHandlers(emitter, type)\n  if (!arr.length) { return }\n  var args = Array.prototype.slice.call(arguments, 2), list\n  if (operationGroup) {\n    list = operationGroup.delayedCallbacks\n  } else if (orphanDelayedCallbacks) {\n    list = orphanDelayedCallbacks\n  } else {\n    list = orphanDelayedCallbacks = []\n    setTimeout(fireOrphanDelayed, 0)\n  }\n  var loop = function ( i ) {\n    list.push(function () { return arr[i].apply(null, args); })\n  };\n\n  for (var i = 0; i < arr.length; ++i)\n    loop( i );\n}\n\nfunction fireOrphanDelayed() {\n  var delayed = orphanDelayedCallbacks\n  orphanDelayedCallbacks = null\n  for (var i = 0; i < delayed.length; ++i) { delayed[i]() }\n}\n\n// When an aspect of a line changes, a string is added to\n// lineView.changes. This updates the relevant part of the line's\n// DOM structure.\nfunction updateLineForChanges(cm, lineView, lineN, dims) {\n  for (var j = 0; j < lineView.changes.length; j++) {\n    var type = lineView.changes[j]\n    if (type == \"text\") { updateLineText(cm, lineView) }\n    else if (type == \"gutter\") { updateLineGutter(cm, lineView, lineN, dims) }\n    else if (type == \"class\") { updateLineClasses(cm, lineView) }\n    else if (type == \"widget\") { updateLineWidgets(cm, lineView, dims) }\n  }\n  lineView.changes = null\n}\n\n// Lines with gutter elements, widgets or a background class need to\n// be wrapped, and have the extra elements added to the wrapper div\nfunction ensureLineWrapped(lineView) {\n  if (lineView.node == lineView.text) {\n    lineView.node = elt(\"div\", null, null, \"position: relative\")\n    if (lineView.text.parentNode)\n      { lineView.text.parentNode.replaceChild(lineView.node, lineView.text) }\n    lineView.node.appendChild(lineView.text)\n    if (ie && ie_version < 8) { lineView.node.style.zIndex = 2 }\n  }\n  return lineView.node\n}\n\nfunction updateLineBackground(cm, lineView) {\n  var cls = lineView.bgClass ? lineView.bgClass + \" \" + (lineView.line.bgClass || \"\") : lineView.line.bgClass\n  if (cls) { cls += \" CodeMirror-linebackground\" }\n  if (lineView.background) {\n    if (cls) { lineView.background.className = cls }\n    else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null }\n  } else if (cls) {\n    var wrap = ensureLineWrapped(lineView)\n    lineView.background = wrap.insertBefore(elt(\"div\", null, cls), wrap.firstChild)\n    cm.display.input.setUneditable(lineView.background)\n  }\n}\n\n// Wrapper around buildLineContent which will reuse the structure\n// in display.externalMeasured when possible.\nfunction getLineContent(cm, lineView) {\n  var ext = cm.display.externalMeasured\n  if (ext && ext.line == lineView.line) {\n    cm.display.externalMeasured = null\n    lineView.measure = ext.measure\n    return ext.built\n  }\n  return buildLineContent(cm, lineView)\n}\n\n// Redraw the line's text. Interacts with the background and text\n// classes because the mode may output tokens that influence these\n// classes.\nfunction updateLineText(cm, lineView) {\n  var cls = lineView.text.className\n  var built = getLineContent(cm, lineView)\n  if (lineView.text == lineView.node) { lineView.node = built.pre }\n  lineView.text.parentNode.replaceChild(built.pre, lineView.text)\n  lineView.text = built.pre\n  if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) {\n    lineView.bgClass = built.bgClass\n    lineView.textClass = built.textClass\n    updateLineClasses(cm, lineView)\n  } else if (cls) {\n    lineView.text.className = cls\n  }\n}\n\nfunction updateLineClasses(cm, lineView) {\n  updateLineBackground(cm, lineView)\n  if (lineView.line.wrapClass)\n    { ensureLineWrapped(lineView).className = lineView.line.wrapClass }\n  else if (lineView.node != lineView.text)\n    { lineView.node.className = \"\" }\n  var textClass = lineView.textClass ? lineView.textClass + \" \" + (lineView.line.textClass || \"\") : lineView.line.textClass\n  lineView.text.className = textClass || \"\"\n}\n\nfunction updateLineGutter(cm, lineView, lineN, dims) {\n  if (lineView.gutter) {\n    lineView.node.removeChild(lineView.gutter)\n    lineView.gutter = null\n  }\n  if (lineView.gutterBackground) {\n    lineView.node.removeChild(lineView.gutterBackground)\n    lineView.gutterBackground = null\n  }\n  if (lineView.line.gutterClass) {\n    var wrap = ensureLineWrapped(lineView)\n    lineView.gutterBackground = elt(\"div\", null, \"CodeMirror-gutter-background \" + lineView.line.gutterClass,\n                                    (\"left: \" + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + \"px; width: \" + (dims.gutterTotalWidth) + \"px\"))\n    cm.display.input.setUneditable(lineView.gutterBackground)\n    wrap.insertBefore(lineView.gutterBackground, lineView.text)\n  }\n  var markers = lineView.line.gutterMarkers\n  if (cm.options.lineNumbers || markers) {\n    var wrap$1 = ensureLineWrapped(lineView)\n    var gutterWrap = lineView.gutter = elt(\"div\", null, \"CodeMirror-gutter-wrapper\", (\"left: \" + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + \"px\"))\n    cm.display.input.setUneditable(gutterWrap)\n    wrap$1.insertBefore(gutterWrap, lineView.text)\n    if (lineView.line.gutterClass)\n      { gutterWrap.className += \" \" + lineView.line.gutterClass }\n    if (cm.options.lineNumbers && (!markers || !markers[\"CodeMirror-linenumbers\"]))\n      { lineView.lineNumber = gutterWrap.appendChild(\n        elt(\"div\", lineNumberFor(cm.options, lineN),\n            \"CodeMirror-linenumber CodeMirror-gutter-elt\",\n            (\"left: \" + (dims.gutterLeft[\"CodeMirror-linenumbers\"]) + \"px; width: \" + (cm.display.lineNumInnerWidth) + \"px\"))) }\n    if (markers) { for (var k = 0; k < cm.options.gutters.length; ++k) {\n      var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id]\n      if (found)\n        { gutterWrap.appendChild(elt(\"div\", [found], \"CodeMirror-gutter-elt\",\n                                   (\"left: \" + (dims.gutterLeft[id]) + \"px; width: \" + (dims.gutterWidth[id]) + \"px\"))) }\n    } }\n  }\n}\n\nfunction updateLineWidgets(cm, lineView, dims) {\n  if (lineView.alignable) { lineView.alignable = null }\n  for (var node = lineView.node.firstChild, next = (void 0); node; node = next) {\n    next = node.nextSibling\n    if (node.className == \"CodeMirror-linewidget\")\n      { lineView.node.removeChild(node) }\n  }\n  insertLineWidgets(cm, lineView, dims)\n}\n\n// Build a line's DOM representation from scratch\nfunction buildLineElement(cm, lineView, lineN, dims) {\n  var built = getLineContent(cm, lineView)\n  lineView.text = lineView.node = built.pre\n  if (built.bgClass) { lineView.bgClass = built.bgClass }\n  if (built.textClass) { lineView.textClass = built.textClass }\n\n  updateLineClasses(cm, lineView)\n  updateLineGutter(cm, lineView, lineN, dims)\n  insertLineWidgets(cm, lineView, dims)\n  return lineView.node\n}\n\n// A lineView may contain multiple logical lines (when merged by\n// collapsed spans). The widgets for all of them need to be drawn.\nfunction insertLineWidgets(cm, lineView, dims) {\n  insertLineWidgetsFor(cm, lineView.line, lineView, dims, true)\n  if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++)\n    { insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false) } }\n}\n\nfunction insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) {\n  if (!line.widgets) { return }\n  var wrap = ensureLineWrapped(lineView)\n  for (var i = 0, ws = line.widgets; i < ws.length; ++i) {\n    var widget = ws[i], node = elt(\"div\", [widget.node], \"CodeMirror-linewidget\")\n    if (!widget.handleMouseEvents) { node.setAttribute(\"cm-ignore-events\", \"true\") }\n    positionLineWidget(widget, node, lineView, dims)\n    cm.display.input.setUneditable(node)\n    if (allowAbove && widget.above)\n      { wrap.insertBefore(node, lineView.gutter || lineView.text) }\n    else\n      { wrap.appendChild(node) }\n    signalLater(widget, \"redraw\")\n  }\n}\n\nfunction positionLineWidget(widget, node, lineView, dims) {\n  if (widget.noHScroll) {\n    ;(lineView.alignable || (lineView.alignable = [])).push(node)\n    var width = dims.wrapperWidth\n    node.style.left = dims.fixedPos + \"px\"\n    if (!widget.coverGutter) {\n      width -= dims.gutterTotalWidth\n      node.style.paddingLeft = dims.gutterTotalWidth + \"px\"\n    }\n    node.style.width = width + \"px\"\n  }\n  if (widget.coverGutter) {\n    node.style.zIndex = 5\n    node.style.position = \"relative\"\n    if (!widget.noHScroll) { node.style.marginLeft = -dims.gutterTotalWidth + \"px\" }\n  }\n}\n\nfunction widgetHeight(widget) {\n  if (widget.height != null) { return widget.height }\n  var cm = widget.doc.cm\n  if (!cm) { return 0 }\n  if (!contains(document.body, widget.node)) {\n    var parentStyle = \"position: relative;\"\n    if (widget.coverGutter)\n      { parentStyle += \"margin-left: -\" + cm.display.gutters.offsetWidth + \"px;\" }\n    if (widget.noHScroll)\n      { parentStyle += \"width: \" + cm.display.wrapper.clientWidth + \"px;\" }\n    removeChildrenAndAdd(cm.display.measure, elt(\"div\", [widget.node], null, parentStyle))\n  }\n  return widget.height = widget.node.parentNode.offsetHeight\n}\n\n// Return true when the given mouse event happened in a widget\nfunction eventInWidget(display, e) {\n  for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {\n    if (!n || (n.nodeType == 1 && n.getAttribute(\"cm-ignore-events\") == \"true\") ||\n        (n.parentNode == display.sizer && n != display.mover))\n      { return true }\n  }\n}\n\n// POSITION MEASUREMENT\n\nfunction paddingTop(display) {return display.lineSpace.offsetTop}\nfunction paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight}\nfunction paddingH(display) {\n  if (display.cachedPaddingH) { return display.cachedPaddingH }\n  var e = removeChildrenAndAdd(display.measure, elt(\"pre\", \"x\"))\n  var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle\n  var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)}\n  if (!isNaN(data.left) && !isNaN(data.right)) { display.cachedPaddingH = data }\n  return data\n}\n\nfunction scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth }\nfunction displayWidth(cm) {\n  return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth\n}\nfunction displayHeight(cm) {\n  return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight\n}\n\n// Ensure the lineView.wrapping.heights array is populated. This is\n// an array of bottom offsets for the lines that make up a drawn\n// line. When lineWrapping is on, there might be more than one\n// height.\nfunction ensureLineHeights(cm, lineView, rect) {\n  var wrapping = cm.options.lineWrapping\n  var curWidth = wrapping && displayWidth(cm)\n  if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) {\n    var heights = lineView.measure.heights = []\n    if (wrapping) {\n      lineView.measure.width = curWidth\n      var rects = lineView.text.firstChild.getClientRects()\n      for (var i = 0; i < rects.length - 1; i++) {\n        var cur = rects[i], next = rects[i + 1]\n        if (Math.abs(cur.bottom - next.bottom) > 2)\n          { heights.push((cur.bottom + next.top) / 2 - rect.top) }\n      }\n    }\n    heights.push(rect.bottom - rect.top)\n  }\n}\n\n// Find a line map (mapping character offsets to text nodes) and a\n// measurement cache for the given line number. (A line view might\n// contain multiple lines when collapsed ranges are present.)\nfunction mapFromLineView(lineView, line, lineN) {\n  if (lineView.line == line)\n    { return {map: lineView.measure.map, cache: lineView.measure.cache} }\n  for (var i = 0; i < lineView.rest.length; i++)\n    { if (lineView.rest[i] == line)\n      { return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]} } }\n  for (var i$1 = 0; i$1 < lineView.rest.length; i$1++)\n    { if (lineNo(lineView.rest[i$1]) > lineN)\n      { return {map: lineView.measure.maps[i$1], cache: lineView.measure.caches[i$1], before: true} } }\n}\n\n// Render a line into the hidden node display.externalMeasured. Used\n// when measurement is needed for a line that's not in the viewport.\nfunction updateExternalMeasurement(cm, line) {\n  line = visualLine(line)\n  var lineN = lineNo(line)\n  var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN)\n  view.lineN = lineN\n  var built = view.built = buildLineContent(cm, view)\n  view.text = built.pre\n  removeChildrenAndAdd(cm.display.lineMeasure, built.pre)\n  return view\n}\n\n// Get a {top, bottom, left, right} box (in line-local coordinates)\n// for a given character.\nfunction measureChar(cm, line, ch, bias) {\n  return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias)\n}\n\n// Find a line view that corresponds to the given line number.\nfunction findViewForLine(cm, lineN) {\n  if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo)\n    { return cm.display.view[findViewIndex(cm, lineN)] }\n  var ext = cm.display.externalMeasured\n  if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size)\n    { return ext }\n}\n\n// Measurement can be split in two steps, the set-up work that\n// applies to the whole line, and the measurement of the actual\n// character. Functions like coordsChar, that need to do a lot of\n// measurements in a row, can thus ensure that the set-up work is\n// only done once.\nfunction prepareMeasureForLine(cm, line) {\n  var lineN = lineNo(line)\n  var view = findViewForLine(cm, lineN)\n  if (view && !view.text) {\n    view = null\n  } else if (view && view.changes) {\n    updateLineForChanges(cm, view, lineN, getDimensions(cm))\n    cm.curOp.forceUpdate = true\n  }\n  if (!view)\n    { view = updateExternalMeasurement(cm, line) }\n\n  var info = mapFromLineView(view, line, lineN)\n  return {\n    line: line, view: view, rect: null,\n    map: info.map, cache: info.cache, before: info.before,\n    hasHeights: false\n  }\n}\n\n// Given a prepared measurement object, measures the position of an\n// actual character (or fetches it from the cache).\nfunction measureCharPrepared(cm, prepared, ch, bias, varHeight) {\n  if (prepared.before) { ch = -1 }\n  var key = ch + (bias || \"\"), found\n  if (prepared.cache.hasOwnProperty(key)) {\n    found = prepared.cache[key]\n  } else {\n    if (!prepared.rect)\n      { prepared.rect = prepared.view.text.getBoundingClientRect() }\n    if (!prepared.hasHeights) {\n      ensureLineHeights(cm, prepared.view, prepared.rect)\n      prepared.hasHeights = true\n    }\n    found = measureCharInner(cm, prepared, ch, bias)\n    if (!found.bogus) { prepared.cache[key] = found }\n  }\n  return {left: found.left, right: found.right,\n          top: varHeight ? found.rtop : found.top,\n          bottom: varHeight ? found.rbottom : found.bottom}\n}\n\nvar nullRect = {left: 0, right: 0, top: 0, bottom: 0}\n\nfunction nodeAndOffsetInLineMap(map, ch, bias) {\n  var node, start, end, collapse, mStart, mEnd\n  // First, search the line map for the text node corresponding to,\n  // or closest to, the target character.\n  for (var i = 0; i < map.length; i += 3) {\n    mStart = map[i]\n    mEnd = map[i + 1]\n    if (ch < mStart) {\n      start = 0; end = 1\n      collapse = \"left\"\n    } else if (ch < mEnd) {\n      start = ch - mStart\n      end = start + 1\n    } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) {\n      end = mEnd - mStart\n      start = end - 1\n      if (ch >= mEnd) { collapse = \"right\" }\n    }\n    if (start != null) {\n      node = map[i + 2]\n      if (mStart == mEnd && bias == (node.insertLeft ? \"left\" : \"right\"))\n        { collapse = bias }\n      if (bias == \"left\" && start == 0)\n        { while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) {\n          node = map[(i -= 3) + 2]\n          collapse = \"left\"\n        } }\n      if (bias == \"right\" && start == mEnd - mStart)\n        { while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) {\n          node = map[(i += 3) + 2]\n          collapse = \"right\"\n        } }\n      break\n    }\n  }\n  return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd}\n}\n\nfunction getUsefulRect(rects, bias) {\n  var rect = nullRect\n  if (bias == \"left\") { for (var i = 0; i < rects.length; i++) {\n    if ((rect = rects[i]).left != rect.right) { break }\n  } } else { for (var i$1 = rects.length - 1; i$1 >= 0; i$1--) {\n    if ((rect = rects[i$1]).left != rect.right) { break }\n  } }\n  return rect\n}\n\nfunction measureCharInner(cm, prepared, ch, bias) {\n  var place = nodeAndOffsetInLineMap(prepared.map, ch, bias)\n  var node = place.node, start = place.start, end = place.end, collapse = place.collapse\n\n  var rect\n  if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates.\n    for (var i$1 = 0; i$1 < 4; i$1++) { // Retry a maximum of 4 times when nonsense rectangles are returned\n      while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) { --start }\n      while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) { ++end }\n      if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart)\n        { rect = node.parentNode.getBoundingClientRect() }\n      else\n        { rect = getUsefulRect(range(node, start, end).getClientRects(), bias) }\n      if (rect.left || rect.right || start == 0) { break }\n      end = start\n      start = start - 1\n      collapse = \"right\"\n    }\n    if (ie && ie_version < 11) { rect = maybeUpdateRectForZooming(cm.display.measure, rect) }\n  } else { // If it is a widget, simply get the box for the whole widget.\n    if (start > 0) { collapse = bias = \"right\" }\n    var rects\n    if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1)\n      { rect = rects[bias == \"right\" ? rects.length - 1 : 0] }\n    else\n      { rect = node.getBoundingClientRect() }\n  }\n  if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) {\n    var rSpan = node.parentNode.getClientRects()[0]\n    if (rSpan)\n      { rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom} }\n    else\n      { rect = nullRect }\n  }\n\n  var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top\n  var mid = (rtop + rbot) / 2\n  var heights = prepared.view.measure.heights\n  var i = 0\n  for (; i < heights.length - 1; i++)\n    { if (mid < heights[i]) { break } }\n  var top = i ? heights[i - 1] : 0, bot = heights[i]\n  var result = {left: (collapse == \"right\" ? rect.right : rect.left) - prepared.rect.left,\n                right: (collapse == \"left\" ? rect.left : rect.right) - prepared.rect.left,\n                top: top, bottom: bot}\n  if (!rect.left && !rect.right) { result.bogus = true }\n  if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot }\n\n  return result\n}\n\n// Work around problem with bounding client rects on ranges being\n// returned incorrectly when zoomed on IE10 and below.\nfunction maybeUpdateRectForZooming(measure, rect) {\n  if (!window.screen || screen.logicalXDPI == null ||\n      screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure))\n    { return rect }\n  var scaleX = screen.logicalXDPI / screen.deviceXDPI\n  var scaleY = screen.logicalYDPI / screen.deviceYDPI\n  return {left: rect.left * scaleX, right: rect.right * scaleX,\n          top: rect.top * scaleY, bottom: rect.bottom * scaleY}\n}\n\nfunction clearLineMeasurementCacheFor(lineView) {\n  if (lineView.measure) {\n    lineView.measure.cache = {}\n    lineView.measure.heights = null\n    if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++)\n      { lineView.measure.caches[i] = {} } }\n  }\n}\n\nfunction clearLineMeasurementCache(cm) {\n  cm.display.externalMeasure = null\n  removeChildren(cm.display.lineMeasure)\n  for (var i = 0; i < cm.display.view.length; i++)\n    { clearLineMeasurementCacheFor(cm.display.view[i]) }\n}\n\nfunction clearCaches(cm) {\n  clearLineMeasurementCache(cm)\n  cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null\n  if (!cm.options.lineWrapping) { cm.display.maxLineChanged = true }\n  cm.display.lineNumChars = null\n}\n\nfunction pageScrollX() {\n  // Work around https://bugs.chromium.org/p/chromium/issues/detail?id=489206\n  // which causes page_Offset and bounding client rects to use\n  // different reference viewports and invalidate our calculations.\n  if (chrome && android) { return -(document.body.getBoundingClientRect().left - parseInt(getComputedStyle(document.body).marginLeft)) }\n  return window.pageXOffset || (document.documentElement || document.body).scrollLeft\n}\nfunction pageScrollY() {\n  if (chrome && android) { return -(document.body.getBoundingClientRect().top - parseInt(getComputedStyle(document.body).marginTop)) }\n  return window.pageYOffset || (document.documentElement || document.body).scrollTop\n}\n\n// Converts a {top, bottom, left, right} box from line-local\n// coordinates into another coordinate system. Context may be one of\n// \"line\", \"div\" (display.lineDiv), \"local\"./null (editor), \"window\",\n// or \"page\".\nfunction intoCoordSystem(cm, lineObj, rect, context, includeWidgets) {\n  if (!includeWidgets && lineObj.widgets) { for (var i = 0; i < lineObj.widgets.length; ++i) { if (lineObj.widgets[i].above) {\n    var size = widgetHeight(lineObj.widgets[i])\n    rect.top += size; rect.bottom += size\n  } } }\n  if (context == \"line\") { return rect }\n  if (!context) { context = \"local\" }\n  var yOff = heightAtLine(lineObj)\n  if (context == \"local\") { yOff += paddingTop(cm.display) }\n  else { yOff -= cm.display.viewOffset }\n  if (context == \"page\" || context == \"window\") {\n    var lOff = cm.display.lineSpace.getBoundingClientRect()\n    yOff += lOff.top + (context == \"window\" ? 0 : pageScrollY())\n    var xOff = lOff.left + (context == \"window\" ? 0 : pageScrollX())\n    rect.left += xOff; rect.right += xOff\n  }\n  rect.top += yOff; rect.bottom += yOff\n  return rect\n}\n\n// Coverts a box from \"div\" coords to another coordinate system.\n// Context may be \"window\", \"page\", \"div\", or \"local\"./null.\nfunction fromCoordSystem(cm, coords, context) {\n  if (context == \"div\") { return coords }\n  var left = coords.left, top = coords.top\n  // First move into \"page\" coordinate system\n  if (context == \"page\") {\n    left -= pageScrollX()\n    top -= pageScrollY()\n  } else if (context == \"local\" || !context) {\n    var localBox = cm.display.sizer.getBoundingClientRect()\n    left += localBox.left\n    top += localBox.top\n  }\n\n  var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect()\n  return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top}\n}\n\nfunction charCoords(cm, pos, context, lineObj, bias) {\n  if (!lineObj) { lineObj = getLine(cm.doc, pos.line) }\n  return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context)\n}\n\n// Returns a box for a given cursor position, which may have an\n// 'other' property containing the position of the secondary cursor\n// on a bidi boundary.\n// A cursor Pos(line, char, \"before\") is on the same visual line as `char - 1`\n// and after `char - 1` in writing order of `char - 1`\n// A cursor Pos(line, char, \"after\") is on the same visual line as `char`\n// and before `char` in writing order of `char`\n// Examples (upper-case letters are RTL, lower-case are LTR):\n//     Pos(0, 1, ...)\n//     before   after\n// ab     a|b     a|b\n// aB     a|B     aB|\n// Ab     |Ab     A|b\n// AB     B|A     B|A\n// Every position after the last character on a line is considered to stick\n// to the last character on the line.\nfunction cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) {\n  lineObj = lineObj || getLine(cm.doc, pos.line)\n  if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj) }\n  function get(ch, right) {\n    var m = measureCharPrepared(cm, preparedMeasure, ch, right ? \"right\" : \"left\", varHeight)\n    if (right) { m.left = m.right; } else { m.right = m.left }\n    return intoCoordSystem(cm, lineObj, m, context)\n  }\n  var order = getOrder(lineObj, cm.doc.direction), ch = pos.ch, sticky = pos.sticky\n  if (ch >= lineObj.text.length) {\n    ch = lineObj.text.length\n    sticky = \"before\"\n  } else if (ch <= 0) {\n    ch = 0\n    sticky = \"after\"\n  }\n  if (!order) { return get(sticky == \"before\" ? ch - 1 : ch, sticky == \"before\") }\n\n  function getBidi(ch, partPos, invert) {\n    var part = order[partPos], right = (part.level % 2) != 0\n    return get(invert ? ch - 1 : ch, right != invert)\n  }\n  var partPos = getBidiPartAt(order, ch, sticky)\n  var other = bidiOther\n  var val = getBidi(ch, partPos, sticky == \"before\")\n  if (other != null) { val.other = getBidi(ch, other, sticky != \"before\") }\n  return val\n}\n\n// Used to cheaply estimate the coordinates for a position. Used for\n// intermediate scroll updates.\nfunction estimateCoords(cm, pos) {\n  var left = 0\n  pos = clipPos(cm.doc, pos)\n  if (!cm.options.lineWrapping) { left = charWidth(cm.display) * pos.ch }\n  var lineObj = getLine(cm.doc, pos.line)\n  var top = heightAtLine(lineObj) + paddingTop(cm.display)\n  return {left: left, right: left, top: top, bottom: top + lineObj.height}\n}\n\n// Positions returned by coordsChar contain some extra information.\n// xRel is the relative x position of the input coordinates compared\n// to the found position (so xRel > 0 means the coordinates are to\n// the right of the character position, for example). When outside\n// is true, that means the coordinates lie outside the line's\n// vertical range.\nfunction PosWithInfo(line, ch, sticky, outside, xRel) {\n  var pos = Pos(line, ch, sticky)\n  pos.xRel = xRel\n  if (outside) { pos.outside = true }\n  return pos\n}\n\n// Compute the character position closest to the given coordinates.\n// Input must be lineSpace-local (\"div\" coordinate system).\nfunction coordsChar(cm, x, y) {\n  var doc = cm.doc\n  y += cm.display.viewOffset\n  if (y < 0) { return PosWithInfo(doc.first, 0, null, true, -1) }\n  var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1\n  if (lineN > last)\n    { return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, null, true, 1) }\n  if (x < 0) { x = 0 }\n\n  var lineObj = getLine(doc, lineN)\n  for (;;) {\n    var found = coordsCharInner(cm, lineObj, lineN, x, y)\n    var merged = collapsedSpanAtEnd(lineObj)\n    var mergedPos = merged && merged.find(0, true)\n    if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))\n      { lineN = lineNo(lineObj = mergedPos.to.line) }\n    else\n      { return found }\n  }\n}\n\nfunction wrappedLineExtent(cm, lineObj, preparedMeasure, y) {\n  var measure = function (ch) { return intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, ch), \"line\"); }\n  var end = lineObj.text.length\n  var begin = findFirst(function (ch) { return measure(ch - 1).bottom <= y; }, end, 0)\n  end = findFirst(function (ch) { return measure(ch).top > y; }, begin, end)\n  return {begin: begin, end: end}\n}\n\nfunction wrappedLineExtentChar(cm, lineObj, preparedMeasure, target) {\n  var targetTop = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, target), \"line\").top\n  return wrappedLineExtent(cm, lineObj, preparedMeasure, targetTop)\n}\n\nfunction coordsCharInner(cm, lineObj, lineNo, x, y) {\n  y -= heightAtLine(lineObj)\n  var begin = 0, end = lineObj.text.length\n  var preparedMeasure = prepareMeasureForLine(cm, lineObj)\n  var pos\n  var order = getOrder(lineObj, cm.doc.direction)\n  if (order) {\n    if (cm.options.lineWrapping) {\n      ;var assign;\n      ((assign = wrappedLineExtent(cm, lineObj, preparedMeasure, y), begin = assign.begin, end = assign.end, assign))\n    }\n    pos = new Pos(lineNo, Math.floor(begin + (end - begin) / 2))\n    var beginLeft = cursorCoords(cm, pos, \"line\", lineObj, preparedMeasure).left\n    var dir = beginLeft < x ? 1 : -1\n    var prevDiff, diff = beginLeft - x, prevPos\n    var steps = Math.ceil((end - begin) / 4)\n    outer: do {\n      prevDiff = diff\n      prevPos = pos\n      var i = 0\n      for (; i < steps; ++i) {\n        var prevPos$1 = pos\n        pos = moveVisually(cm, lineObj, pos, dir)\n        if (pos == null || pos.ch < begin || end <= (pos.sticky == \"before\" ? pos.ch - 1 : pos.ch)) {\n          pos = prevPos$1\n          break outer\n        }\n      }\n      diff = cursorCoords(cm, pos, \"line\", lineObj, preparedMeasure).left - x\n      if (steps > 1) {\n        var diff_change_per_step = Math.abs(diff - prevDiff) / steps\n        steps = Math.min(steps, Math.ceil(Math.abs(diff) / diff_change_per_step))\n        dir = diff < 0 ? 1 : -1\n      }\n    } while (diff != 0 && (steps > 1 || ((dir < 0) != (diff < 0) && (Math.abs(diff) <= Math.abs(prevDiff)))))\n    if (Math.abs(diff) > Math.abs(prevDiff)) {\n      if ((diff < 0) == (prevDiff < 0)) { throw new Error(\"Broke out of infinite loop in coordsCharInner\") }\n      pos = prevPos\n    }\n  } else {\n    var ch = findFirst(function (ch) {\n      var box = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, ch), \"line\")\n      if (box.top > y) {\n        // For the cursor stickiness\n        end = Math.min(ch, end)\n        return true\n      }\n      else if (box.bottom <= y) { return false }\n      else if (box.left > x) { return true }\n      else if (box.right < x) { return false }\n      else { return (x - box.left < box.right - x) }\n    }, begin, end)\n    ch = skipExtendingChars(lineObj.text, ch, 1)\n    pos = new Pos(lineNo, ch, ch == end ? \"before\" : \"after\")\n  }\n  var coords = cursorCoords(cm, pos, \"line\", lineObj, preparedMeasure)\n  if (y < coords.top || coords.bottom < y) { pos.outside = true }\n  pos.xRel = x < coords.left ? -1 : (x > coords.right ? 1 : 0)\n  return pos\n}\n\nvar measureText\n// Compute the default text height.\nfunction textHeight(display) {\n  if (display.cachedTextHeight != null) { return display.cachedTextHeight }\n  if (measureText == null) {\n    measureText = elt(\"pre\")\n    // Measure a bunch of lines, for browsers that compute\n    // fractional heights.\n    for (var i = 0; i < 49; ++i) {\n      measureText.appendChild(document.createTextNode(\"x\"))\n      measureText.appendChild(elt(\"br\"))\n    }\n    measureText.appendChild(document.createTextNode(\"x\"))\n  }\n  removeChildrenAndAdd(display.measure, measureText)\n  var height = measureText.offsetHeight / 50\n  if (height > 3) { display.cachedTextHeight = height }\n  removeChildren(display.measure)\n  return height || 1\n}\n\n// Compute the default character width.\nfunction charWidth(display) {\n  if (display.cachedCharWidth != null) { return display.cachedCharWidth }\n  var anchor = elt(\"span\", \"xxxxxxxxxx\")\n  var pre = elt(\"pre\", [anchor])\n  removeChildrenAndAdd(display.measure, pre)\n  var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10\n  if (width > 2) { display.cachedCharWidth = width }\n  return width || 10\n}\n\n// Do a bulk-read of the DOM positions and sizes needed to draw the\n// view, so that we don't interleave reading and writing to the DOM.\nfunction getDimensions(cm) {\n  var d = cm.display, left = {}, width = {}\n  var gutterLeft = d.gutters.clientLeft\n  for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {\n    left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft\n    width[cm.options.gutters[i]] = n.clientWidth\n  }\n  return {fixedPos: compensateForHScroll(d),\n          gutterTotalWidth: d.gutters.offsetWidth,\n          gutterLeft: left,\n          gutterWidth: width,\n          wrapperWidth: d.wrapper.clientWidth}\n}\n\n// Computes display.scroller.scrollLeft + display.gutters.offsetWidth,\n// but using getBoundingClientRect to get a sub-pixel-accurate\n// result.\nfunction compensateForHScroll(display) {\n  return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left\n}\n\n// Returns a function that estimates the height of a line, to use as\n// first approximation until the line becomes visible (and is thus\n// properly measurable).\nfunction estimateHeight(cm) {\n  var th = textHeight(cm.display), wrapping = cm.options.lineWrapping\n  var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3)\n  return function (line) {\n    if (lineIsHidden(cm.doc, line)) { return 0 }\n\n    var widgetsHeight = 0\n    if (line.widgets) { for (var i = 0; i < line.widgets.length; i++) {\n      if (line.widgets[i].height) { widgetsHeight += line.widgets[i].height }\n    } }\n\n    if (wrapping)\n      { return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th }\n    else\n      { return widgetsHeight + th }\n  }\n}\n\nfunction estimateLineHeights(cm) {\n  var doc = cm.doc, est = estimateHeight(cm)\n  doc.iter(function (line) {\n    var estHeight = est(line)\n    if (estHeight != line.height) { updateLineHeight(line, estHeight) }\n  })\n}\n\n// Given a mouse event, find the corresponding position. If liberal\n// is false, it checks whether a gutter or scrollbar was clicked,\n// and returns null if it was. forRect is used by rectangular\n// selections, and tries to estimate a character position even for\n// coordinates beyond the right of the text.\nfunction posFromMouse(cm, e, liberal, forRect) {\n  var display = cm.display\n  if (!liberal && e_target(e).getAttribute(\"cm-not-content\") == \"true\") { return null }\n\n  var x, y, space = display.lineSpace.getBoundingClientRect()\n  // Fails unpredictably on IE[67] when mouse is dragged around quickly.\n  try { x = e.clientX - space.left; y = e.clientY - space.top }\n  catch (e) { return null }\n  var coords = coordsChar(cm, x, y), line\n  if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {\n    var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length\n    coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff))\n  }\n  return coords\n}\n\n// Find the view element corresponding to a given line. Return null\n// when the line isn't visible.\nfunction findViewIndex(cm, n) {\n  if (n >= cm.display.viewTo) { return null }\n  n -= cm.display.viewFrom\n  if (n < 0) { return null }\n  var view = cm.display.view\n  for (var i = 0; i < view.length; i++) {\n    n -= view[i].size\n    if (n < 0) { return i }\n  }\n}\n\nfunction updateSelection(cm) {\n  cm.display.input.showSelection(cm.display.input.prepareSelection())\n}\n\nfunction prepareSelection(cm, primary) {\n  var doc = cm.doc, result = {}\n  var curFragment = result.cursors = document.createDocumentFragment()\n  var selFragment = result.selection = document.createDocumentFragment()\n\n  for (var i = 0; i < doc.sel.ranges.length; i++) {\n    if (primary === false && i == doc.sel.primIndex) { continue }\n    var range = doc.sel.ranges[i]\n    if (range.from().line >= cm.display.viewTo || range.to().line < cm.display.viewFrom) { continue }\n    var collapsed = range.empty()\n    if (collapsed || cm.options.showCursorWhenSelecting)\n      { drawSelectionCursor(cm, range.head, curFragment) }\n    if (!collapsed)\n      { drawSelectionRange(cm, range, selFragment) }\n  }\n  return result\n}\n\n// Draws a cursor for the given range\nfunction drawSelectionCursor(cm, head, output) {\n  var pos = cursorCoords(cm, head, \"div\", null, null, !cm.options.singleCursorHeightPerLine)\n\n  var cursor = output.appendChild(elt(\"div\", \"\\u00a0\", \"CodeMirror-cursor\"))\n  cursor.style.left = pos.left + \"px\"\n  cursor.style.top = pos.top + \"px\"\n  cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + \"px\"\n\n  if (pos.other) {\n    // Secondary cursor, shown when on a 'jump' in bi-directional text\n    var otherCursor = output.appendChild(elt(\"div\", \"\\u00a0\", \"CodeMirror-cursor CodeMirror-secondarycursor\"))\n    otherCursor.style.display = \"\"\n    otherCursor.style.left = pos.other.left + \"px\"\n    otherCursor.style.top = pos.other.top + \"px\"\n    otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + \"px\"\n  }\n}\n\n// Draws the given range as a highlighted selection\nfunction drawSelectionRange(cm, range, output) {\n  var display = cm.display, doc = cm.doc\n  var fragment = document.createDocumentFragment()\n  var padding = paddingH(cm.display), leftSide = padding.left\n  var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right\n\n  function add(left, top, width, bottom) {\n    if (top < 0) { top = 0 }\n    top = Math.round(top)\n    bottom = Math.round(bottom)\n    fragment.appendChild(elt(\"div\", null, \"CodeMirror-selected\", (\"position: absolute; left: \" + left + \"px;\\n                             top: \" + top + \"px; width: \" + (width == null ? rightSide - left : width) + \"px;\\n                             height: \" + (bottom - top) + \"px\")))\n  }\n\n  function drawForLine(line, fromArg, toArg) {\n    var lineObj = getLine(doc, line)\n    var lineLen = lineObj.text.length\n    var start, end\n    function coords(ch, bias) {\n      return charCoords(cm, Pos(line, ch), \"div\", lineObj, bias)\n    }\n\n    iterateBidiSections(getOrder(lineObj, doc.direction), fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir) {\n      var leftPos = coords(from, \"left\"), rightPos, left, right\n      if (from == to) {\n        rightPos = leftPos\n        left = right = leftPos.left\n      } else {\n        rightPos = coords(to - 1, \"right\")\n        if (dir == \"rtl\") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp }\n        left = leftPos.left\n        right = rightPos.right\n      }\n      if (fromArg == null && from == 0) { left = leftSide }\n      if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part\n        add(left, leftPos.top, null, leftPos.bottom)\n        left = leftSide\n        if (leftPos.bottom < rightPos.top) { add(left, leftPos.bottom, null, rightPos.top) }\n      }\n      if (toArg == null && to == lineLen) { right = rightSide }\n      if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)\n        { start = leftPos }\n      if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)\n        { end = rightPos }\n      if (left < leftSide + 1) { left = leftSide }\n      add(left, rightPos.top, right - left, rightPos.bottom)\n    })\n    return {start: start, end: end}\n  }\n\n  var sFrom = range.from(), sTo = range.to()\n  if (sFrom.line == sTo.line) {\n    drawForLine(sFrom.line, sFrom.ch, sTo.ch)\n  } else {\n    var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line)\n    var singleVLine = visualLine(fromLine) == visualLine(toLine)\n    var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end\n    var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start\n    if (singleVLine) {\n      if (leftEnd.top < rightStart.top - 2) {\n        add(leftEnd.right, leftEnd.top, null, leftEnd.bottom)\n        add(leftSide, rightStart.top, rightStart.left, rightStart.bottom)\n      } else {\n        add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom)\n      }\n    }\n    if (leftEnd.bottom < rightStart.top)\n      { add(leftSide, leftEnd.bottom, null, rightStart.top) }\n  }\n\n  output.appendChild(fragment)\n}\n\n// Cursor-blinking\nfunction restartBlink(cm) {\n  if (!cm.state.focused) { return }\n  var display = cm.display\n  clearInterval(display.blinker)\n  var on = true\n  display.cursorDiv.style.visibility = \"\"\n  if (cm.options.cursorBlinkRate > 0)\n    { display.blinker = setInterval(function () { return display.cursorDiv.style.visibility = (on = !on) ? \"\" : \"hidden\"; },\n      cm.options.cursorBlinkRate) }\n  else if (cm.options.cursorBlinkRate < 0)\n    { display.cursorDiv.style.visibility = \"hidden\" }\n}\n\nfunction ensureFocus(cm) {\n  if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm) }\n}\n\nfunction delayBlurEvent(cm) {\n  cm.state.delayingBlurEvent = true\n  setTimeout(function () { if (cm.state.delayingBlurEvent) {\n    cm.state.delayingBlurEvent = false\n    onBlur(cm)\n  } }, 100)\n}\n\nfunction onFocus(cm, e) {\n  if (cm.state.delayingBlurEvent) { cm.state.delayingBlurEvent = false }\n\n  if (cm.options.readOnly == \"nocursor\") { return }\n  if (!cm.state.focused) {\n    signal(cm, \"focus\", cm, e)\n    cm.state.focused = true\n    addClass(cm.display.wrapper, \"CodeMirror-focused\")\n    // This test prevents this from firing when a context\n    // menu is closed (since the input reset would kill the\n    // select-all detection hack)\n    if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) {\n      cm.display.input.reset()\n      if (webkit) { setTimeout(function () { return cm.display.input.reset(true); }, 20) } // Issue #1730\n    }\n    cm.display.input.receivedFocus()\n  }\n  restartBlink(cm)\n}\nfunction onBlur(cm, e) {\n  if (cm.state.delayingBlurEvent) { return }\n\n  if (cm.state.focused) {\n    signal(cm, \"blur\", cm, e)\n    cm.state.focused = false\n    rmClass(cm.display.wrapper, \"CodeMirror-focused\")\n  }\n  clearInterval(cm.display.blinker)\n  setTimeout(function () { if (!cm.state.focused) { cm.display.shift = false } }, 150)\n}\n\n// Read the actual heights of the rendered lines, and update their\n// stored heights to match.\nfunction updateHeightsInViewport(cm) {\n  var display = cm.display\n  var prevBottom = display.lineDiv.offsetTop\n  for (var i = 0; i < display.view.length; i++) {\n    var cur = display.view[i], height = (void 0)\n    if (cur.hidden) { continue }\n    if (ie && ie_version < 8) {\n      var bot = cur.node.offsetTop + cur.node.offsetHeight\n      height = bot - prevBottom\n      prevBottom = bot\n    } else {\n      var box = cur.node.getBoundingClientRect()\n      height = box.bottom - box.top\n    }\n    var diff = cur.line.height - height\n    if (height < 2) { height = textHeight(display) }\n    if (diff > .005 || diff < -.005) {\n      updateLineHeight(cur.line, height)\n      updateWidgetHeight(cur.line)\n      if (cur.rest) { for (var j = 0; j < cur.rest.length; j++)\n        { updateWidgetHeight(cur.rest[j]) } }\n    }\n  }\n}\n\n// Read and store the height of line widgets associated with the\n// given line.\nfunction updateWidgetHeight(line) {\n  if (line.widgets) { for (var i = 0; i < line.widgets.length; ++i)\n    { line.widgets[i].height = line.widgets[i].node.parentNode.offsetHeight } }\n}\n\n// Compute the lines that are visible in a given viewport (defaults\n// the the current scroll position). viewport may contain top,\n// height, and ensure (see op.scrollToPos) properties.\nfunction visibleLines(display, doc, viewport) {\n  var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop\n  top = Math.floor(top - paddingTop(display))\n  var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight\n\n  var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom)\n  // Ensure is a {from: {line, ch}, to: {line, ch}} object, and\n  // forces those lines into the viewport (if possible).\n  if (viewport && viewport.ensure) {\n    var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line\n    if (ensureFrom < from) {\n      from = ensureFrom\n      to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight)\n    } else if (Math.min(ensureTo, doc.lastLine()) >= to) {\n      from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight)\n      to = ensureTo\n    }\n  }\n  return {from: from, to: Math.max(to, from + 1)}\n}\n\n// Re-align line numbers and gutter marks to compensate for\n// horizontal scrolling.\nfunction alignHorizontally(cm) {\n  var display = cm.display, view = display.view\n  if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) { return }\n  var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft\n  var gutterW = display.gutters.offsetWidth, left = comp + \"px\"\n  for (var i = 0; i < view.length; i++) { if (!view[i].hidden) {\n    if (cm.options.fixedGutter) {\n      if (view[i].gutter)\n        { view[i].gutter.style.left = left }\n      if (view[i].gutterBackground)\n        { view[i].gutterBackground.style.left = left }\n    }\n    var align = view[i].alignable\n    if (align) { for (var j = 0; j < align.length; j++)\n      { align[j].style.left = left } }\n  } }\n  if (cm.options.fixedGutter)\n    { display.gutters.style.left = (comp + gutterW) + \"px\" }\n}\n\n// Used to ensure that the line number gutter is still the right\n// size for the current document size. Returns true when an update\n// is needed.\nfunction maybeUpdateLineNumberWidth(cm) {\n  if (!cm.options.lineNumbers) { return false }\n  var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display\n  if (last.length != display.lineNumChars) {\n    var test = display.measure.appendChild(elt(\"div\", [elt(\"div\", last)],\n                                               \"CodeMirror-linenumber CodeMirror-gutter-elt\"))\n    var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW\n    display.lineGutter.style.width = \"\"\n    display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1\n    display.lineNumWidth = display.lineNumInnerWidth + padding\n    display.lineNumChars = display.lineNumInnerWidth ? last.length : -1\n    display.lineGutter.style.width = display.lineNumWidth + \"px\"\n    updateGutterSpace(cm)\n    return true\n  }\n  return false\n}\n\n// SCROLLING THINGS INTO VIEW\n\n// If an editor sits on the top or bottom of the window, partially\n// scrolled out of view, this ensures that the cursor is visible.\nfunction maybeScrollWindow(cm, rect) {\n  if (signalDOMEvent(cm, \"scrollCursorIntoView\")) { return }\n\n  var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null\n  if (rect.top + box.top < 0) { doScroll = true }\n  else if (rect.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) { doScroll = false }\n  if (doScroll != null && !phantom) {\n    var scrollNode = elt(\"div\", \"\\u200b\", null, (\"position: absolute;\\n                         top: \" + (rect.top - display.viewOffset - paddingTop(cm.display)) + \"px;\\n                         height: \" + (rect.bottom - rect.top + scrollGap(cm) + display.barHeight) + \"px;\\n                         left: \" + (rect.left) + \"px; width: \" + (Math.max(2, rect.right - rect.left)) + \"px;\"))\n    cm.display.lineSpace.appendChild(scrollNode)\n    scrollNode.scrollIntoView(doScroll)\n    cm.display.lineSpace.removeChild(scrollNode)\n  }\n}\n\n// Scroll a given position into view (immediately), verifying that\n// it actually became visible (as line heights are accurately\n// measured, the position of something may 'drift' during drawing).\nfunction scrollPosIntoView(cm, pos, end, margin) {\n  if (margin == null) { margin = 0 }\n  var rect\n  if (!cm.options.lineWrapping && pos == end) {\n    // Set pos and end to the cursor positions around the character pos sticks to\n    // If pos.sticky == \"before\", that is around pos.ch - 1, otherwise around pos.ch\n    // If pos == Pos(_, 0, \"before\"), pos and end are unchanged\n    pos = pos.ch ? Pos(pos.line, pos.sticky == \"before\" ? pos.ch - 1 : pos.ch, \"after\") : pos\n    end = pos.sticky == \"before\" ? Pos(pos.line, pos.ch + 1, \"before\") : pos\n  }\n  for (var limit = 0; limit < 5; limit++) {\n    var changed = false\n    var coords = cursorCoords(cm, pos)\n    var endCoords = !end || end == pos ? coords : cursorCoords(cm, end)\n    rect = {left: Math.min(coords.left, endCoords.left),\n            top: Math.min(coords.top, endCoords.top) - margin,\n            right: Math.max(coords.left, endCoords.left),\n            bottom: Math.max(coords.bottom, endCoords.bottom) + margin}\n    var scrollPos = calculateScrollPos(cm, rect)\n    var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft\n    if (scrollPos.scrollTop != null) {\n      updateScrollTop(cm, scrollPos.scrollTop)\n      if (Math.abs(cm.doc.scrollTop - startTop) > 1) { changed = true }\n    }\n    if (scrollPos.scrollLeft != null) {\n      setScrollLeft(cm, scrollPos.scrollLeft)\n      if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) { changed = true }\n    }\n    if (!changed) { break }\n  }\n  return rect\n}\n\n// Scroll a given set of coordinates into view (immediately).\nfunction scrollIntoView(cm, rect) {\n  var scrollPos = calculateScrollPos(cm, rect)\n  if (scrollPos.scrollTop != null) { updateScrollTop(cm, scrollPos.scrollTop) }\n  if (scrollPos.scrollLeft != null) { setScrollLeft(cm, scrollPos.scrollLeft) }\n}\n\n// Calculate a new scroll position needed to scroll the given\n// rectangle into view. Returns an object with scrollTop and\n// scrollLeft properties. When these are undefined, the\n// vertical/horizontal position does not need to be adjusted.\nfunction calculateScrollPos(cm, rect) {\n  var display = cm.display, snapMargin = textHeight(cm.display)\n  if (rect.top < 0) { rect.top = 0 }\n  var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop\n  var screen = displayHeight(cm), result = {}\n  if (rect.bottom - rect.top > screen) { rect.bottom = rect.top + screen }\n  var docBottom = cm.doc.height + paddingVert(display)\n  var atTop = rect.top < snapMargin, atBottom = rect.bottom > docBottom - snapMargin\n  if (rect.top < screentop) {\n    result.scrollTop = atTop ? 0 : rect.top\n  } else if (rect.bottom > screentop + screen) {\n    var newTop = Math.min(rect.top, (atBottom ? docBottom : rect.bottom) - screen)\n    if (newTop != screentop) { result.scrollTop = newTop }\n  }\n\n  var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft\n  var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0)\n  var tooWide = rect.right - rect.left > screenw\n  if (tooWide) { rect.right = rect.left + screenw }\n  if (rect.left < 10)\n    { result.scrollLeft = 0 }\n  else if (rect.left < screenleft)\n    { result.scrollLeft = Math.max(0, rect.left - (tooWide ? 0 : 10)) }\n  else if (rect.right > screenw + screenleft - 3)\n    { result.scrollLeft = rect.right + (tooWide ? 0 : 10) - screenw }\n  return result\n}\n\n// Store a relative adjustment to the scroll position in the current\n// operation (to be applied when the operation finishes).\nfunction addToScrollTop(cm, top) {\n  if (top == null) { return }\n  resolveScrollToPos(cm)\n  cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top\n}\n\n// Make sure that at the end of the operation the current cursor is\n// shown.\nfunction ensureCursorVisible(cm) {\n  resolveScrollToPos(cm)\n  var cur = cm.getCursor()\n  cm.curOp.scrollToPos = {from: cur, to: cur, margin: cm.options.cursorScrollMargin}\n}\n\nfunction scrollToCoords(cm, x, y) {\n  if (x != null || y != null) { resolveScrollToPos(cm) }\n  if (x != null) { cm.curOp.scrollLeft = x }\n  if (y != null) { cm.curOp.scrollTop = y }\n}\n\nfunction scrollToRange(cm, range) {\n  resolveScrollToPos(cm)\n  cm.curOp.scrollToPos = range\n}\n\n// When an operation has its scrollToPos property set, and another\n// scroll action is applied before the end of the operation, this\n// 'simulates' scrolling that position into view in a cheap way, so\n// that the effect of intermediate scroll commands is not ignored.\nfunction resolveScrollToPos(cm) {\n  var range = cm.curOp.scrollToPos\n  if (range) {\n    cm.curOp.scrollToPos = null\n    var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to)\n    scrollToCoordsRange(cm, from, to, range.margin)\n  }\n}\n\nfunction scrollToCoordsRange(cm, from, to, margin) {\n  var sPos = calculateScrollPos(cm, {\n    left: Math.min(from.left, to.left),\n    top: Math.min(from.top, to.top) - margin,\n    right: Math.max(from.right, to.right),\n    bottom: Math.max(from.bottom, to.bottom) + margin\n  })\n  scrollToCoords(cm, sPos.scrollLeft, sPos.scrollTop)\n}\n\n// Sync the scrollable area and scrollbars, ensure the viewport\n// covers the visible area.\nfunction updateScrollTop(cm, val) {\n  if (Math.abs(cm.doc.scrollTop - val) < 2) { return }\n  if (!gecko) { updateDisplaySimple(cm, {top: val}) }\n  setScrollTop(cm, val, true)\n  if (gecko) { updateDisplaySimple(cm) }\n  startWorker(cm, 100)\n}\n\nfunction setScrollTop(cm, val, forceScroll) {\n  val = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val)\n  if (cm.display.scroller.scrollTop == val && !forceScroll) { return }\n  cm.doc.scrollTop = val\n  cm.display.scrollbars.setScrollTop(val)\n  if (cm.display.scroller.scrollTop != val) { cm.display.scroller.scrollTop = val }\n}\n\n// Sync scroller and scrollbar, ensure the gutter elements are\n// aligned.\nfunction setScrollLeft(cm, val, isScroller, forceScroll) {\n  val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth)\n  if ((isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) && !forceScroll) { return }\n  cm.doc.scrollLeft = val\n  alignHorizontally(cm)\n  if (cm.display.scroller.scrollLeft != val) { cm.display.scroller.scrollLeft = val }\n  cm.display.scrollbars.setScrollLeft(val)\n}\n\n// SCROLLBARS\n\n// Prepare DOM reads needed to update the scrollbars. Done in one\n// shot to minimize update/measure roundtrips.\nfunction measureForScrollbars(cm) {\n  var d = cm.display, gutterW = d.gutters.offsetWidth\n  var docH = Math.round(cm.doc.height + paddingVert(cm.display))\n  return {\n    clientHeight: d.scroller.clientHeight,\n    viewHeight: d.wrapper.clientHeight,\n    scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth,\n    viewWidth: d.wrapper.clientWidth,\n    barLeft: cm.options.fixedGutter ? gutterW : 0,\n    docHeight: docH,\n    scrollHeight: docH + scrollGap(cm) + d.barHeight,\n    nativeBarWidth: d.nativeBarWidth,\n    gutterWidth: gutterW\n  }\n}\n\nvar NativeScrollbars = function(place, scroll, cm) {\n  this.cm = cm\n  var vert = this.vert = elt(\"div\", [elt(\"div\", null, null, \"min-width: 1px\")], \"CodeMirror-vscrollbar\")\n  var horiz = this.horiz = elt(\"div\", [elt(\"div\", null, null, \"height: 100%; min-height: 1px\")], \"CodeMirror-hscrollbar\")\n  place(vert); place(horiz)\n\n  on(vert, \"scroll\", function () {\n    if (vert.clientHeight) { scroll(vert.scrollTop, \"vertical\") }\n  })\n  on(horiz, \"scroll\", function () {\n    if (horiz.clientWidth) { scroll(horiz.scrollLeft, \"horizontal\") }\n  })\n\n  this.checkedZeroWidth = false\n  // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).\n  if (ie && ie_version < 8) { this.horiz.style.minHeight = this.vert.style.minWidth = \"18px\" }\n};\n\nNativeScrollbars.prototype.update = function (measure) {\n  var needsH = measure.scrollWidth > measure.clientWidth + 1\n  var needsV = measure.scrollHeight > measure.clientHeight + 1\n  var sWidth = measure.nativeBarWidth\n\n  if (needsV) {\n    this.vert.style.display = \"block\"\n    this.vert.style.bottom = needsH ? sWidth + \"px\" : \"0\"\n    var totalHeight = measure.viewHeight - (needsH ? sWidth : 0)\n    // A bug in IE8 can cause this value to be negative, so guard it.\n    this.vert.firstChild.style.height =\n      Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + \"px\"\n  } else {\n    this.vert.style.display = \"\"\n    this.vert.firstChild.style.height = \"0\"\n  }\n\n  if (needsH) {\n    this.horiz.style.display = \"block\"\n    this.horiz.style.right = needsV ? sWidth + \"px\" : \"0\"\n    this.horiz.style.left = measure.barLeft + \"px\"\n    var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0)\n    this.horiz.firstChild.style.width =\n      Math.max(0, measure.scrollWidth - measure.clientWidth + totalWidth) + \"px\"\n  } else {\n    this.horiz.style.display = \"\"\n    this.horiz.firstChild.style.width = \"0\"\n  }\n\n  if (!this.checkedZeroWidth && measure.clientHeight > 0) {\n    if (sWidth == 0) { this.zeroWidthHack() }\n    this.checkedZeroWidth = true\n  }\n\n  return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0}\n};\n\nNativeScrollbars.prototype.setScrollLeft = function (pos) {\n  if (this.horiz.scrollLeft != pos) { this.horiz.scrollLeft = pos }\n  if (this.disableHoriz) { this.enableZeroWidthBar(this.horiz, this.disableHoriz, \"horiz\") }\n};\n\nNativeScrollbars.prototype.setScrollTop = function (pos) {\n  if (this.vert.scrollTop != pos) { this.vert.scrollTop = pos }\n  if (this.disableVert) { this.enableZeroWidthBar(this.vert, this.disableVert, \"vert\") }\n};\n\nNativeScrollbars.prototype.zeroWidthHack = function () {\n  var w = mac && !mac_geMountainLion ? \"12px\" : \"18px\"\n  this.horiz.style.height = this.vert.style.width = w\n  this.horiz.style.pointerEvents = this.vert.style.pointerEvents = \"none\"\n  this.disableHoriz = new Delayed\n  this.disableVert = new Delayed\n};\n\nNativeScrollbars.prototype.enableZeroWidthBar = function (bar, delay, type) {\n  bar.style.pointerEvents = \"auto\"\n  function maybeDisable() {\n    // To find out whether the scrollbar is still visible, we\n    // check whether the element under the pixel in the bottom\n    // right corner of the scrollbar box is the scrollbar box\n    // itself (when the bar is still visible) or its filler child\n    // (when the bar is hidden). If it is still visible, we keep\n    // it enabled, if it's hidden, we disable pointer events.\n    var box = bar.getBoundingClientRect()\n    var elt = type == \"vert\" ? document.elementFromPoint(box.right - 1, (box.top + box.bottom) / 2)\n        : document.elementFromPoint((box.right + box.left) / 2, box.bottom - 1)\n    if (elt != bar) { bar.style.pointerEvents = \"none\" }\n    else { delay.set(1000, maybeDisable) }\n  }\n  delay.set(1000, maybeDisable)\n};\n\nNativeScrollbars.prototype.clear = function () {\n  var parent = this.horiz.parentNode\n  parent.removeChild(this.horiz)\n  parent.removeChild(this.vert)\n};\n\nvar NullScrollbars = function () {};\n\nNullScrollbars.prototype.update = function () { return {bottom: 0, right: 0} };\nNullScrollbars.prototype.setScrollLeft = function () {};\nNullScrollbars.prototype.setScrollTop = function () {};\nNullScrollbars.prototype.clear = function () {};\n\nfunction updateScrollbars(cm, measure) {\n  if (!measure) { measure = measureForScrollbars(cm) }\n  var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight\n  updateScrollbarsInner(cm, measure)\n  for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) {\n    if (startWidth != cm.display.barWidth && cm.options.lineWrapping)\n      { updateHeightsInViewport(cm) }\n    updateScrollbarsInner(cm, measureForScrollbars(cm))\n    startWidth = cm.display.barWidth; startHeight = cm.display.barHeight\n  }\n}\n\n// Re-synchronize the fake scrollbars with the actual size of the\n// content.\nfunction updateScrollbarsInner(cm, measure) {\n  var d = cm.display\n  var sizes = d.scrollbars.update(measure)\n\n  d.sizer.style.paddingRight = (d.barWidth = sizes.right) + \"px\"\n  d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + \"px\"\n  d.heightForcer.style.borderBottom = sizes.bottom + \"px solid transparent\"\n\n  if (sizes.right && sizes.bottom) {\n    d.scrollbarFiller.style.display = \"block\"\n    d.scrollbarFiller.style.height = sizes.bottom + \"px\"\n    d.scrollbarFiller.style.width = sizes.right + \"px\"\n  } else { d.scrollbarFiller.style.display = \"\" }\n  if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {\n    d.gutterFiller.style.display = \"block\"\n    d.gutterFiller.style.height = sizes.bottom + \"px\"\n    d.gutterFiller.style.width = measure.gutterWidth + \"px\"\n  } else { d.gutterFiller.style.display = \"\" }\n}\n\nvar scrollbarModel = {\"native\": NativeScrollbars, \"null\": NullScrollbars}\n\nfunction initScrollbars(cm) {\n  if (cm.display.scrollbars) {\n    cm.display.scrollbars.clear()\n    if (cm.display.scrollbars.addClass)\n      { rmClass(cm.display.wrapper, cm.display.scrollbars.addClass) }\n  }\n\n  cm.display.scrollbars = new scrollbarModel[cm.options.scrollbarStyle](function (node) {\n    cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller)\n    // Prevent clicks in the scrollbars from killing focus\n    on(node, \"mousedown\", function () {\n      if (cm.state.focused) { setTimeout(function () { return cm.display.input.focus(); }, 0) }\n    })\n    node.setAttribute(\"cm-not-content\", \"true\")\n  }, function (pos, axis) {\n    if (axis == \"horizontal\") { setScrollLeft(cm, pos) }\n    else { updateScrollTop(cm, pos) }\n  }, cm)\n  if (cm.display.scrollbars.addClass)\n    { addClass(cm.display.wrapper, cm.display.scrollbars.addClass) }\n}\n\n// Operations are used to wrap a series of changes to the editor\n// state in such a way that each change won't have to update the\n// cursor and display (which would be awkward, slow, and\n// error-prone). Instead, display updates are batched and then all\n// combined and executed at once.\n\nvar nextOpId = 0\n// Start a new operation.\nfunction startOperation(cm) {\n  cm.curOp = {\n    cm: cm,\n    viewChanged: false,      // Flag that indicates that lines might need to be redrawn\n    startHeight: cm.doc.height, // Used to detect need to update scrollbar\n    forceUpdate: false,      // Used to force a redraw\n    updateInput: null,       // Whether to reset the input textarea\n    typing: false,           // Whether this reset should be careful to leave existing text (for compositing)\n    changeObjs: null,        // Accumulated changes, for firing change events\n    cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on\n    cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already\n    selectionChanged: false, // Whether the selection needs to be redrawn\n    updateMaxLine: false,    // Set when the widest line needs to be determined anew\n    scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet\n    scrollToPos: null,       // Used to scroll to a specific position\n    focus: false,\n    id: ++nextOpId           // Unique ID\n  }\n  pushOperation(cm.curOp)\n}\n\n// Finish an operation, updating the display and signalling delayed events\nfunction endOperation(cm) {\n  var op = cm.curOp\n  finishOperation(op, function (group) {\n    for (var i = 0; i < group.ops.length; i++)\n      { group.ops[i].cm.curOp = null }\n    endOperations(group)\n  })\n}\n\n// The DOM updates done when an operation finishes are batched so\n// that the minimum number of relayouts are required.\nfunction endOperations(group) {\n  var ops = group.ops\n  for (var i = 0; i < ops.length; i++) // Read DOM\n    { endOperation_R1(ops[i]) }\n  for (var i$1 = 0; i$1 < ops.length; i$1++) // Write DOM (maybe)\n    { endOperation_W1(ops[i$1]) }\n  for (var i$2 = 0; i$2 < ops.length; i$2++) // Read DOM\n    { endOperation_R2(ops[i$2]) }\n  for (var i$3 = 0; i$3 < ops.length; i$3++) // Write DOM (maybe)\n    { endOperation_W2(ops[i$3]) }\n  for (var i$4 = 0; i$4 < ops.length; i$4++) // Read DOM\n    { endOperation_finish(ops[i$4]) }\n}\n\nfunction endOperation_R1(op) {\n  var cm = op.cm, display = cm.display\n  maybeClipScrollbars(cm)\n  if (op.updateMaxLine) { findMaxLine(cm) }\n\n  op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null ||\n    op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom ||\n                       op.scrollToPos.to.line >= display.viewTo) ||\n    display.maxLineChanged && cm.options.lineWrapping\n  op.update = op.mustUpdate &&\n    new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate)\n}\n\nfunction endOperation_W1(op) {\n  op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update)\n}\n\nfunction endOperation_R2(op) {\n  var cm = op.cm, display = cm.display\n  if (op.updatedDisplay) { updateHeightsInViewport(cm) }\n\n  op.barMeasure = measureForScrollbars(cm)\n\n  // If the max line changed since it was last measured, measure it,\n  // and ensure the document's width matches it.\n  // updateDisplay_W2 will use these properties to do the actual resizing\n  if (display.maxLineChanged && !cm.options.lineWrapping) {\n    op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3\n    cm.display.sizerWidth = op.adjustWidthTo\n    op.barMeasure.scrollWidth =\n      Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth)\n    op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm))\n  }\n\n  if (op.updatedDisplay || op.selectionChanged)\n    { op.preparedSelection = display.input.prepareSelection(op.focus) }\n}\n\nfunction endOperation_W2(op) {\n  var cm = op.cm\n\n  if (op.adjustWidthTo != null) {\n    cm.display.sizer.style.minWidth = op.adjustWidthTo + \"px\"\n    if (op.maxScrollLeft < cm.doc.scrollLeft)\n      { setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true) }\n    cm.display.maxLineChanged = false\n  }\n\n  var takeFocus = op.focus && op.focus == activeElt() && (!document.hasFocus || document.hasFocus())\n  if (op.preparedSelection)\n    { cm.display.input.showSelection(op.preparedSelection, takeFocus) }\n  if (op.updatedDisplay || op.startHeight != cm.doc.height)\n    { updateScrollbars(cm, op.barMeasure) }\n  if (op.updatedDisplay)\n    { setDocumentHeight(cm, op.barMeasure) }\n\n  if (op.selectionChanged) { restartBlink(cm) }\n\n  if (cm.state.focused && op.updateInput)\n    { cm.display.input.reset(op.typing) }\n  if (takeFocus) { ensureFocus(op.cm) }\n}\n\nfunction endOperation_finish(op) {\n  var cm = op.cm, display = cm.display, doc = cm.doc\n\n  if (op.updatedDisplay) { postUpdateDisplay(cm, op.update) }\n\n  // Abort mouse wheel delta measurement, when scrolling explicitly\n  if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos))\n    { display.wheelStartX = display.wheelStartY = null }\n\n  // Propagate the scroll position to the actual DOM scroller\n  if (op.scrollTop != null) { setScrollTop(cm, op.scrollTop, op.forceScroll) }\n\n  if (op.scrollLeft != null) { setScrollLeft(cm, op.scrollLeft, true, true) }\n  // If we need to scroll a specific position into view, do so.\n  if (op.scrollToPos) {\n    var rect = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from),\n                                 clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin)\n    maybeScrollWindow(cm, rect)\n  }\n\n  // Fire events for markers that are hidden/unidden by editing or\n  // undoing\n  var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers\n  if (hidden) { for (var i = 0; i < hidden.length; ++i)\n    { if (!hidden[i].lines.length) { signal(hidden[i], \"hide\") } } }\n  if (unhidden) { for (var i$1 = 0; i$1 < unhidden.length; ++i$1)\n    { if (unhidden[i$1].lines.length) { signal(unhidden[i$1], \"unhide\") } } }\n\n  if (display.wrapper.offsetHeight)\n    { doc.scrollTop = cm.display.scroller.scrollTop }\n\n  // Fire change events, and delayed event handlers\n  if (op.changeObjs)\n    { signal(cm, \"changes\", cm, op.changeObjs) }\n  if (op.update)\n    { op.update.finish() }\n}\n\n// Run the given function in an operation\nfunction runInOp(cm, f) {\n  if (cm.curOp) { return f() }\n  startOperation(cm)\n  try { return f() }\n  finally { endOperation(cm) }\n}\n// Wraps a function in an operation. Returns the wrapped function.\nfunction operation(cm, f) {\n  return function() {\n    if (cm.curOp) { return f.apply(cm, arguments) }\n    startOperation(cm)\n    try { return f.apply(cm, arguments) }\n    finally { endOperation(cm) }\n  }\n}\n// Used to add methods to editor and doc instances, wrapping them in\n// operations.\nfunction methodOp(f) {\n  return function() {\n    if (this.curOp) { return f.apply(this, arguments) }\n    startOperation(this)\n    try { return f.apply(this, arguments) }\n    finally { endOperation(this) }\n  }\n}\nfunction docMethodOp(f) {\n  return function() {\n    var cm = this.cm\n    if (!cm || cm.curOp) { return f.apply(this, arguments) }\n    startOperation(cm)\n    try { return f.apply(this, arguments) }\n    finally { endOperation(cm) }\n  }\n}\n\n// Updates the display.view data structure for a given change to the\n// document. From and to are in pre-change coordinates. Lendiff is\n// the amount of lines added or subtracted by the change. This is\n// used for changes that span multiple lines, or change the way\n// lines are divided into visual lines. regLineChange (below)\n// registers single-line changes.\nfunction regChange(cm, from, to, lendiff) {\n  if (from == null) { from = cm.doc.first }\n  if (to == null) { to = cm.doc.first + cm.doc.size }\n  if (!lendiff) { lendiff = 0 }\n\n  var display = cm.display\n  if (lendiff && to < display.viewTo &&\n      (display.updateLineNumbers == null || display.updateLineNumbers > from))\n    { display.updateLineNumbers = from }\n\n  cm.curOp.viewChanged = true\n\n  if (from >= display.viewTo) { // Change after\n    if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo)\n      { resetView(cm) }\n  } else if (to <= display.viewFrom) { // Change before\n    if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) {\n      resetView(cm)\n    } else {\n      display.viewFrom += lendiff\n      display.viewTo += lendiff\n    }\n  } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap\n    resetView(cm)\n  } else if (from <= display.viewFrom) { // Top overlap\n    var cut = viewCuttingPoint(cm, to, to + lendiff, 1)\n    if (cut) {\n      display.view = display.view.slice(cut.index)\n      display.viewFrom = cut.lineN\n      display.viewTo += lendiff\n    } else {\n      resetView(cm)\n    }\n  } else if (to >= display.viewTo) { // Bottom overlap\n    var cut$1 = viewCuttingPoint(cm, from, from, -1)\n    if (cut$1) {\n      display.view = display.view.slice(0, cut$1.index)\n      display.viewTo = cut$1.lineN\n    } else {\n      resetView(cm)\n    }\n  } else { // Gap in the middle\n    var cutTop = viewCuttingPoint(cm, from, from, -1)\n    var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1)\n    if (cutTop && cutBot) {\n      display.view = display.view.slice(0, cutTop.index)\n        .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN))\n        .concat(display.view.slice(cutBot.index))\n      display.viewTo += lendiff\n    } else {\n      resetView(cm)\n    }\n  }\n\n  var ext = display.externalMeasured\n  if (ext) {\n    if (to < ext.lineN)\n      { ext.lineN += lendiff }\n    else if (from < ext.lineN + ext.size)\n      { display.externalMeasured = null }\n  }\n}\n\n// Register a change to a single line. Type must be one of \"text\",\n// \"gutter\", \"class\", \"widget\"\nfunction regLineChange(cm, line, type) {\n  cm.curOp.viewChanged = true\n  var display = cm.display, ext = cm.display.externalMeasured\n  if (ext && line >= ext.lineN && line < ext.lineN + ext.size)\n    { display.externalMeasured = null }\n\n  if (line < display.viewFrom || line >= display.viewTo) { return }\n  var lineView = display.view[findViewIndex(cm, line)]\n  if (lineView.node == null) { return }\n  var arr = lineView.changes || (lineView.changes = [])\n  if (indexOf(arr, type) == -1) { arr.push(type) }\n}\n\n// Clear the view.\nfunction resetView(cm) {\n  cm.display.viewFrom = cm.display.viewTo = cm.doc.first\n  cm.display.view = []\n  cm.display.viewOffset = 0\n}\n\nfunction viewCuttingPoint(cm, oldN, newN, dir) {\n  var index = findViewIndex(cm, oldN), diff, view = cm.display.view\n  if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size)\n    { return {index: index, lineN: newN} }\n  var n = cm.display.viewFrom\n  for (var i = 0; i < index; i++)\n    { n += view[i].size }\n  if (n != oldN) {\n    if (dir > 0) {\n      if (index == view.length - 1) { return null }\n      diff = (n + view[index].size) - oldN\n      index++\n    } else {\n      diff = n - oldN\n    }\n    oldN += diff; newN += diff\n  }\n  while (visualLineNo(cm.doc, newN) != newN) {\n    if (index == (dir < 0 ? 0 : view.length - 1)) { return null }\n    newN += dir * view[index - (dir < 0 ? 1 : 0)].size\n    index += dir\n  }\n  return {index: index, lineN: newN}\n}\n\n// Force the view to cover a given range, adding empty view element\n// or clipping off existing ones as needed.\nfunction adjustView(cm, from, to) {\n  var display = cm.display, view = display.view\n  if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) {\n    display.view = buildViewArray(cm, from, to)\n    display.viewFrom = from\n  } else {\n    if (display.viewFrom > from)\n      { display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view) }\n    else if (display.viewFrom < from)\n      { display.view = display.view.slice(findViewIndex(cm, from)) }\n    display.viewFrom = from\n    if (display.viewTo < to)\n      { display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)) }\n    else if (display.viewTo > to)\n      { display.view = display.view.slice(0, findViewIndex(cm, to)) }\n  }\n  display.viewTo = to\n}\n\n// Count the number of lines in the view whose DOM representation is\n// out of date (or nonexistent).\nfunction countDirtyView(cm) {\n  var view = cm.display.view, dirty = 0\n  for (var i = 0; i < view.length; i++) {\n    var lineView = view[i]\n    if (!lineView.hidden && (!lineView.node || lineView.changes)) { ++dirty }\n  }\n  return dirty\n}\n\n// HIGHLIGHT WORKER\n\nfunction startWorker(cm, time) {\n  if (cm.doc.highlightFrontier < cm.display.viewTo)\n    { cm.state.highlight.set(time, bind(highlightWorker, cm)) }\n}\n\nfunction highlightWorker(cm) {\n  var doc = cm.doc\n  if (doc.highlightFrontier >= cm.display.viewTo) { return }\n  var end = +new Date + cm.options.workTime\n  var context = getContextBefore(cm, doc.highlightFrontier)\n  var changedLines = []\n\n  doc.iter(context.line, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function (line) {\n    if (context.line >= cm.display.viewFrom) { // Visible\n      var oldStyles = line.styles\n      var resetState = line.text.length > cm.options.maxHighlightLength ? copyState(doc.mode, context.state) : null\n      var highlighted = highlightLine(cm, line, context, true)\n      if (resetState) { context.state = resetState }\n      line.styles = highlighted.styles\n      var oldCls = line.styleClasses, newCls = highlighted.classes\n      if (newCls) { line.styleClasses = newCls }\n      else if (oldCls) { line.styleClasses = null }\n      var ischange = !oldStyles || oldStyles.length != line.styles.length ||\n        oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass)\n      for (var i = 0; !ischange && i < oldStyles.length; ++i) { ischange = oldStyles[i] != line.styles[i] }\n      if (ischange) { changedLines.push(context.line) }\n      line.stateAfter = context.save()\n      context.nextLine()\n    } else {\n      if (line.text.length <= cm.options.maxHighlightLength)\n        { processLine(cm, line.text, context) }\n      line.stateAfter = context.line % 5 == 0 ? context.save() : null\n      context.nextLine()\n    }\n    if (+new Date > end) {\n      startWorker(cm, cm.options.workDelay)\n      return true\n    }\n  })\n  doc.highlightFrontier = context.line\n  doc.modeFrontier = Math.max(doc.modeFrontier, context.line)\n  if (changedLines.length) { runInOp(cm, function () {\n    for (var i = 0; i < changedLines.length; i++)\n      { regLineChange(cm, changedLines[i], \"text\") }\n  }) }\n}\n\n// DISPLAY DRAWING\n\nvar DisplayUpdate = function(cm, viewport, force) {\n  var display = cm.display\n\n  this.viewport = viewport\n  // Store some values that we'll need later (but don't want to force a relayout for)\n  this.visible = visibleLines(display, cm.doc, viewport)\n  this.editorIsHidden = !display.wrapper.offsetWidth\n  this.wrapperHeight = display.wrapper.clientHeight\n  this.wrapperWidth = display.wrapper.clientWidth\n  this.oldDisplayWidth = displayWidth(cm)\n  this.force = force\n  this.dims = getDimensions(cm)\n  this.events = []\n};\n\nDisplayUpdate.prototype.signal = function (emitter, type) {\n  if (hasHandler(emitter, type))\n    { this.events.push(arguments) }\n};\nDisplayUpdate.prototype.finish = function () {\n    var this$1 = this;\n\n  for (var i = 0; i < this.events.length; i++)\n    { signal.apply(null, this$1.events[i]) }\n};\n\nfunction maybeClipScrollbars(cm) {\n  var display = cm.display\n  if (!display.scrollbarsClipped && display.scroller.offsetWidth) {\n    display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth\n    display.heightForcer.style.height = scrollGap(cm) + \"px\"\n    display.sizer.style.marginBottom = -display.nativeBarWidth + \"px\"\n    display.sizer.style.borderRightWidth = scrollGap(cm) + \"px\"\n    display.scrollbarsClipped = true\n  }\n}\n\nfunction selectionSnapshot(cm) {\n  if (cm.hasFocus()) { return null }\n  var active = activeElt()\n  if (!active || !contains(cm.display.lineDiv, active)) { return null }\n  var result = {activeElt: active}\n  if (window.getSelection) {\n    var sel = window.getSelection()\n    if (sel.anchorNode && sel.extend && contains(cm.display.lineDiv, sel.anchorNode)) {\n      result.anchorNode = sel.anchorNode\n      result.anchorOffset = sel.anchorOffset\n      result.focusNode = sel.focusNode\n      result.focusOffset = sel.focusOffset\n    }\n  }\n  return result\n}\n\nfunction restoreSelection(snapshot) {\n  if (!snapshot || !snapshot.activeElt || snapshot.activeElt == activeElt()) { return }\n  snapshot.activeElt.focus()\n  if (snapshot.anchorNode && contains(document.body, snapshot.anchorNode) && contains(document.body, snapshot.focusNode)) {\n    var sel = window.getSelection(), range = document.createRange()\n    range.setEnd(snapshot.anchorNode, snapshot.anchorOffset)\n    range.collapse(false)\n    sel.removeAllRanges()\n    sel.addRange(range)\n    sel.extend(snapshot.focusNode, snapshot.focusOffset)\n  }\n}\n\n// Does the actual updating of the line display. Bails out\n// (returning false) when there is nothing to be done and forced is\n// false.\nfunction updateDisplayIfNeeded(cm, update) {\n  var display = cm.display, doc = cm.doc\n\n  if (update.editorIsHidden) {\n    resetView(cm)\n    return false\n  }\n\n  // Bail out if the visible area is already rendered and nothing changed.\n  if (!update.force &&\n      update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo &&\n      (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) &&\n      display.renderedView == display.view && countDirtyView(cm) == 0)\n    { return false }\n\n  if (maybeUpdateLineNumberWidth(cm)) {\n    resetView(cm)\n    update.dims = getDimensions(cm)\n  }\n\n  // Compute a suitable new viewport (from & to)\n  var end = doc.first + doc.size\n  var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first)\n  var to = Math.min(end, update.visible.to + cm.options.viewportMargin)\n  if (display.viewFrom < from && from - display.viewFrom < 20) { from = Math.max(doc.first, display.viewFrom) }\n  if (display.viewTo > to && display.viewTo - to < 20) { to = Math.min(end, display.viewTo) }\n  if (sawCollapsedSpans) {\n    from = visualLineNo(cm.doc, from)\n    to = visualLineEndNo(cm.doc, to)\n  }\n\n  var different = from != display.viewFrom || to != display.viewTo ||\n    display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth\n  adjustView(cm, from, to)\n\n  display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom))\n  // Position the mover div to align with the current scroll position\n  cm.display.mover.style.top = display.viewOffset + \"px\"\n\n  var toUpdate = countDirtyView(cm)\n  if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view &&\n      (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo))\n    { return false }\n\n  // For big changes, we hide the enclosing element during the\n  // update, since that speeds up the operations on most browsers.\n  var selSnapshot = selectionSnapshot(cm)\n  if (toUpdate > 4) { display.lineDiv.style.display = \"none\" }\n  patchDisplay(cm, display.updateLineNumbers, update.dims)\n  if (toUpdate > 4) { display.lineDiv.style.display = \"\" }\n  display.renderedView = display.view\n  // There might have been a widget with a focused element that got\n  // hidden or updated, if so re-focus it.\n  restoreSelection(selSnapshot)\n\n  // Prevent selection and cursors from interfering with the scroll\n  // width and height.\n  removeChildren(display.cursorDiv)\n  removeChildren(display.selectionDiv)\n  display.gutters.style.height = display.sizer.style.minHeight = 0\n\n  if (different) {\n    display.lastWrapHeight = update.wrapperHeight\n    display.lastWrapWidth = update.wrapperWidth\n    startWorker(cm, 400)\n  }\n\n  display.updateLineNumbers = null\n\n  return true\n}\n\nfunction postUpdateDisplay(cm, update) {\n  var viewport = update.viewport\n\n  for (var first = true;; first = false) {\n    if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) {\n      // Clip forced viewport to actual scrollable area.\n      if (viewport && viewport.top != null)\n        { viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)} }\n      // Updated line heights might result in the drawn area not\n      // actually covering the viewport. Keep looping until it does.\n      update.visible = visibleLines(cm.display, cm.doc, viewport)\n      if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)\n        { break }\n    }\n    if (!updateDisplayIfNeeded(cm, update)) { break }\n    updateHeightsInViewport(cm)\n    var barMeasure = measureForScrollbars(cm)\n    updateSelection(cm)\n    updateScrollbars(cm, barMeasure)\n    setDocumentHeight(cm, barMeasure)\n    update.force = false\n  }\n\n  update.signal(cm, \"update\", cm)\n  if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) {\n    update.signal(cm, \"viewportChange\", cm, cm.display.viewFrom, cm.display.viewTo)\n    cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo\n  }\n}\n\nfunction updateDisplaySimple(cm, viewport) {\n  var update = new DisplayUpdate(cm, viewport)\n  if (updateDisplayIfNeeded(cm, update)) {\n    updateHeightsInViewport(cm)\n    postUpdateDisplay(cm, update)\n    var barMeasure = measureForScrollbars(cm)\n    updateSelection(cm)\n    updateScrollbars(cm, barMeasure)\n    setDocumentHeight(cm, barMeasure)\n    update.finish()\n  }\n}\n\n// Sync the actual display DOM structure with display.view, removing\n// nodes for lines that are no longer in view, and creating the ones\n// that are not there yet, and updating the ones that are out of\n// date.\nfunction patchDisplay(cm, updateNumbersFrom, dims) {\n  var display = cm.display, lineNumbers = cm.options.lineNumbers\n  var container = display.lineDiv, cur = container.firstChild\n\n  function rm(node) {\n    var next = node.nextSibling\n    // Works around a throw-scroll bug in OS X Webkit\n    if (webkit && mac && cm.display.currentWheelTarget == node)\n      { node.style.display = \"none\" }\n    else\n      { node.parentNode.removeChild(node) }\n    return next\n  }\n\n  var view = display.view, lineN = display.viewFrom\n  // Loop over the elements in the view, syncing cur (the DOM nodes\n  // in display.lineDiv) with the view as we go.\n  for (var i = 0; i < view.length; i++) {\n    var lineView = view[i]\n    if (lineView.hidden) {\n    } else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet\n      var node = buildLineElement(cm, lineView, lineN, dims)\n      container.insertBefore(node, cur)\n    } else { // Already drawn\n      while (cur != lineView.node) { cur = rm(cur) }\n      var updateNumber = lineNumbers && updateNumbersFrom != null &&\n        updateNumbersFrom <= lineN && lineView.lineNumber\n      if (lineView.changes) {\n        if (indexOf(lineView.changes, \"gutter\") > -1) { updateNumber = false }\n        updateLineForChanges(cm, lineView, lineN, dims)\n      }\n      if (updateNumber) {\n        removeChildren(lineView.lineNumber)\n        lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN)))\n      }\n      cur = lineView.node.nextSibling\n    }\n    lineN += lineView.size\n  }\n  while (cur) { cur = rm(cur) }\n}\n\nfunction updateGutterSpace(cm) {\n  var width = cm.display.gutters.offsetWidth\n  cm.display.sizer.style.marginLeft = width + \"px\"\n}\n\nfunction setDocumentHeight(cm, measure) {\n  cm.display.sizer.style.minHeight = measure.docHeight + \"px\"\n  cm.display.heightForcer.style.top = measure.docHeight + \"px\"\n  cm.display.gutters.style.height = (measure.docHeight + cm.display.barHeight + scrollGap(cm)) + \"px\"\n}\n\n// Rebuild the gutter elements, ensure the margin to the left of the\n// code matches their width.\nfunction updateGutters(cm) {\n  var gutters = cm.display.gutters, specs = cm.options.gutters\n  removeChildren(gutters)\n  var i = 0\n  for (; i < specs.length; ++i) {\n    var gutterClass = specs[i]\n    var gElt = gutters.appendChild(elt(\"div\", null, \"CodeMirror-gutter \" + gutterClass))\n    if (gutterClass == \"CodeMirror-linenumbers\") {\n      cm.display.lineGutter = gElt\n      gElt.style.width = (cm.display.lineNumWidth || 1) + \"px\"\n    }\n  }\n  gutters.style.display = i ? \"\" : \"none\"\n  updateGutterSpace(cm)\n}\n\n// Make sure the gutters options contains the element\n// \"CodeMirror-linenumbers\" when the lineNumbers option is true.\nfunction setGuttersForLineNumbers(options) {\n  var found = indexOf(options.gutters, \"CodeMirror-linenumbers\")\n  if (found == -1 && options.lineNumbers) {\n    options.gutters = options.gutters.concat([\"CodeMirror-linenumbers\"])\n  } else if (found > -1 && !options.lineNumbers) {\n    options.gutters = options.gutters.slice(0)\n    options.gutters.splice(found, 1)\n  }\n}\n\nvar wheelSamples = 0;\nvar wheelPixelsPerUnit = null;\n// Fill in a browser-detected starting value on browsers where we\n// know one. These don't have to be accurate -- the result of them\n// being wrong would just be a slight flicker on the first wheel\n// scroll (if it is large enough).\nif (ie) { wheelPixelsPerUnit = -.53 }\nelse if (gecko) { wheelPixelsPerUnit = 15 }\nelse if (chrome) { wheelPixelsPerUnit = -.7 }\nelse if (safari) { wheelPixelsPerUnit = -1/3 }\n\nfunction wheelEventDelta(e) {\n  var dx = e.wheelDeltaX, dy = e.wheelDeltaY\n  if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) { dx = e.detail }\n  if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) { dy = e.detail }\n  else if (dy == null) { dy = e.wheelDelta }\n  return {x: dx, y: dy}\n}\nfunction wheelEventPixels(e) {\n  var delta = wheelEventDelta(e)\n  delta.x *= wheelPixelsPerUnit\n  delta.y *= wheelPixelsPerUnit\n  return delta\n}\n\nfunction onScrollWheel(cm, e) {\n  var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y\n\n  var display = cm.display, scroll = display.scroller\n  // Quit if there's nothing to scroll here\n  var canScrollX = scroll.scrollWidth > scroll.clientWidth\n  var canScrollY = scroll.scrollHeight > scroll.clientHeight\n  if (!(dx && canScrollX || dy && canScrollY)) { return }\n\n  // Webkit browsers on OS X abort momentum scrolls when the target\n  // of the scroll event is removed from the scrollable element.\n  // This hack (see related code in patchDisplay) makes sure the\n  // element is kept around.\n  if (dy && mac && webkit) {\n    outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) {\n      for (var i = 0; i < view.length; i++) {\n        if (view[i].node == cur) {\n          cm.display.currentWheelTarget = cur\n          break outer\n        }\n      }\n    }\n  }\n\n  // On some browsers, horizontal scrolling will cause redraws to\n  // happen before the gutter has been realigned, causing it to\n  // wriggle around in a most unseemly way. When we have an\n  // estimated pixels/delta value, we just handle horizontal\n  // scrolling entirely here. It'll be slightly off from native, but\n  // better than glitching out.\n  if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {\n    if (dy && canScrollY)\n      { updateScrollTop(cm, Math.max(0, scroll.scrollTop + dy * wheelPixelsPerUnit)) }\n    setScrollLeft(cm, Math.max(0, scroll.scrollLeft + dx * wheelPixelsPerUnit))\n    // Only prevent default scrolling if vertical scrolling is\n    // actually possible. Otherwise, it causes vertical scroll\n    // jitter on OSX trackpads when deltaX is small and deltaY\n    // is large (issue #3579)\n    if (!dy || (dy && canScrollY))\n      { e_preventDefault(e) }\n    display.wheelStartX = null // Abort measurement, if in progress\n    return\n  }\n\n  // 'Project' the visible viewport to cover the area that is being\n  // scrolled into view (if we know enough to estimate it).\n  if (dy && wheelPixelsPerUnit != null) {\n    var pixels = dy * wheelPixelsPerUnit\n    var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight\n    if (pixels < 0) { top = Math.max(0, top + pixels - 50) }\n    else { bot = Math.min(cm.doc.height, bot + pixels + 50) }\n    updateDisplaySimple(cm, {top: top, bottom: bot})\n  }\n\n  if (wheelSamples < 20) {\n    if (display.wheelStartX == null) {\n      display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop\n      display.wheelDX = dx; display.wheelDY = dy\n      setTimeout(function () {\n        if (display.wheelStartX == null) { return }\n        var movedX = scroll.scrollLeft - display.wheelStartX\n        var movedY = scroll.scrollTop - display.wheelStartY\n        var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||\n          (movedX && display.wheelDX && movedX / display.wheelDX)\n        display.wheelStartX = display.wheelStartY = null\n        if (!sample) { return }\n        wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1)\n        ++wheelSamples\n      }, 200)\n    } else {\n      display.wheelDX += dx; display.wheelDY += dy\n    }\n  }\n}\n\n// Selection objects are immutable. A new one is created every time\n// the selection changes. A selection is one or more non-overlapping\n// (and non-touching) ranges, sorted, and an integer that indicates\n// which one is the primary selection (the one that's scrolled into\n// view, that getCursor returns, etc).\nvar Selection = function(ranges, primIndex) {\n  this.ranges = ranges\n  this.primIndex = primIndex\n};\n\nSelection.prototype.primary = function () { return this.ranges[this.primIndex] };\n\nSelection.prototype.equals = function (other) {\n    var this$1 = this;\n\n  if (other == this) { return true }\n  if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) { return false }\n  for (var i = 0; i < this.ranges.length; i++) {\n    var here = this$1.ranges[i], there = other.ranges[i]\n    if (!equalCursorPos(here.anchor, there.anchor) || !equalCursorPos(here.head, there.head)) { return false }\n  }\n  return true\n};\n\nSelection.prototype.deepCopy = function () {\n    var this$1 = this;\n\n  var out = []\n  for (var i = 0; i < this.ranges.length; i++)\n    { out[i] = new Range(copyPos(this$1.ranges[i].anchor), copyPos(this$1.ranges[i].head)) }\n  return new Selection(out, this.primIndex)\n};\n\nSelection.prototype.somethingSelected = function () {\n    var this$1 = this;\n\n  for (var i = 0; i < this.ranges.length; i++)\n    { if (!this$1.ranges[i].empty()) { return true } }\n  return false\n};\n\nSelection.prototype.contains = function (pos, end) {\n    var this$1 = this;\n\n  if (!end) { end = pos }\n  for (var i = 0; i < this.ranges.length; i++) {\n    var range = this$1.ranges[i]\n    if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0)\n      { return i }\n  }\n  return -1\n};\n\nvar Range = function(anchor, head) {\n  this.anchor = anchor; this.head = head\n};\n\nRange.prototype.from = function () { return minPos(this.anchor, this.head) };\nRange.prototype.to = function () { return maxPos(this.anchor, this.head) };\nRange.prototype.empty = function () { return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch };\n\n// Take an unsorted, potentially overlapping set of ranges, and\n// build a selection out of it. 'Consumes' ranges array (modifying\n// it).\nfunction normalizeSelection(ranges, primIndex) {\n  var prim = ranges[primIndex]\n  ranges.sort(function (a, b) { return cmp(a.from(), b.from()); })\n  primIndex = indexOf(ranges, prim)\n  for (var i = 1; i < ranges.length; i++) {\n    var cur = ranges[i], prev = ranges[i - 1]\n    if (cmp(prev.to(), cur.from()) >= 0) {\n      var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to())\n      var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head\n      if (i <= primIndex) { --primIndex }\n      ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to))\n    }\n  }\n  return new Selection(ranges, primIndex)\n}\n\nfunction simpleSelection(anchor, head) {\n  return new Selection([new Range(anchor, head || anchor)], 0)\n}\n\n// Compute the position of the end of a change (its 'to' property\n// refers to the pre-change end).\nfunction changeEnd(change) {\n  if (!change.text) { return change.to }\n  return Pos(change.from.line + change.text.length - 1,\n             lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0))\n}\n\n// Adjust a position to refer to the post-change position of the\n// same text, or the end of the change if the change covers it.\nfunction adjustForChange(pos, change) {\n  if (cmp(pos, change.from) < 0) { return pos }\n  if (cmp(pos, change.to) <= 0) { return changeEnd(change) }\n\n  var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch\n  if (pos.line == change.to.line) { ch += changeEnd(change).ch - change.to.ch }\n  return Pos(line, ch)\n}\n\nfunction computeSelAfterChange(doc, change) {\n  var out = []\n  for (var i = 0; i < doc.sel.ranges.length; i++) {\n    var range = doc.sel.ranges[i]\n    out.push(new Range(adjustForChange(range.anchor, change),\n                       adjustForChange(range.head, change)))\n  }\n  return normalizeSelection(out, doc.sel.primIndex)\n}\n\nfunction offsetPos(pos, old, nw) {\n  if (pos.line == old.line)\n    { return Pos(nw.line, pos.ch - old.ch + nw.ch) }\n  else\n    { return Pos(nw.line + (pos.line - old.line), pos.ch) }\n}\n\n// Used by replaceSelections to allow moving the selection to the\n// start or around the replaced test. Hint may be \"start\" or \"around\".\nfunction computeReplacedSel(doc, changes, hint) {\n  var out = []\n  var oldPrev = Pos(doc.first, 0), newPrev = oldPrev\n  for (var i = 0; i < changes.length; i++) {\n    var change = changes[i]\n    var from = offsetPos(change.from, oldPrev, newPrev)\n    var to = offsetPos(changeEnd(change), oldPrev, newPrev)\n    oldPrev = change.to\n    newPrev = to\n    if (hint == \"around\") {\n      var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0\n      out[i] = new Range(inv ? to : from, inv ? from : to)\n    } else {\n      out[i] = new Range(from, from)\n    }\n  }\n  return new Selection(out, doc.sel.primIndex)\n}\n\n// Used to get the editor into a consistent state again when options change.\n\nfunction loadMode(cm) {\n  cm.doc.mode = getMode(cm.options, cm.doc.modeOption)\n  resetModeState(cm)\n}\n\nfunction resetModeState(cm) {\n  cm.doc.iter(function (line) {\n    if (line.stateAfter) { line.stateAfter = null }\n    if (line.styles) { line.styles = null }\n  })\n  cm.doc.modeFrontier = cm.doc.highlightFrontier = cm.doc.first\n  startWorker(cm, 100)\n  cm.state.modeGen++\n  if (cm.curOp) { regChange(cm) }\n}\n\n// DOCUMENT DATA STRUCTURE\n\n// By default, updates that start and end at the beginning of a line\n// are treated specially, in order to make the association of line\n// widgets and marker elements with the text behave more intuitive.\nfunction isWholeLineUpdate(doc, change) {\n  return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == \"\" &&\n    (!doc.cm || doc.cm.options.wholeLineUpdateBefore)\n}\n\n// Perform a change on the document data structure.\nfunction updateDoc(doc, change, markedSpans, estimateHeight) {\n  function spansFor(n) {return markedSpans ? markedSpans[n] : null}\n  function update(line, text, spans) {\n    updateLine(line, text, spans, estimateHeight)\n    signalLater(line, \"change\", line, change)\n  }\n  function linesFor(start, end) {\n    var result = []\n    for (var i = start; i < end; ++i)\n      { result.push(new Line(text[i], spansFor(i), estimateHeight)) }\n    return result\n  }\n\n  var from = change.from, to = change.to, text = change.text\n  var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line)\n  var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line\n\n  // Adjust the line structure\n  if (change.full) {\n    doc.insert(0, linesFor(0, text.length))\n    doc.remove(text.length, doc.size - text.length)\n  } else if (isWholeLineUpdate(doc, change)) {\n    // This is a whole-line replace. Treated specially to make\n    // sure line objects move the way they are supposed to.\n    var added = linesFor(0, text.length - 1)\n    update(lastLine, lastLine.text, lastSpans)\n    if (nlines) { doc.remove(from.line, nlines) }\n    if (added.length) { doc.insert(from.line, added) }\n  } else if (firstLine == lastLine) {\n    if (text.length == 1) {\n      update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans)\n    } else {\n      var added$1 = linesFor(1, text.length - 1)\n      added$1.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight))\n      update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0))\n      doc.insert(from.line + 1, added$1)\n    }\n  } else if (text.length == 1) {\n    update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0))\n    doc.remove(from.line + 1, nlines)\n  } else {\n    update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0))\n    update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans)\n    var added$2 = linesFor(1, text.length - 1)\n    if (nlines > 1) { doc.remove(from.line + 1, nlines - 1) }\n    doc.insert(from.line + 1, added$2)\n  }\n\n  signalLater(doc, \"change\", doc, change)\n}\n\n// Call f for all linked documents.\nfunction linkedDocs(doc, f, sharedHistOnly) {\n  function propagate(doc, skip, sharedHist) {\n    if (doc.linked) { for (var i = 0; i < doc.linked.length; ++i) {\n      var rel = doc.linked[i]\n      if (rel.doc == skip) { continue }\n      var shared = sharedHist && rel.sharedHist\n      if (sharedHistOnly && !shared) { continue }\n      f(rel.doc, shared)\n      propagate(rel.doc, doc, shared)\n    } }\n  }\n  propagate(doc, null, true)\n}\n\n// Attach a document to an editor.\nfunction attachDoc(cm, doc) {\n  if (doc.cm) { throw new Error(\"This document is already in use.\") }\n  cm.doc = doc\n  doc.cm = cm\n  estimateLineHeights(cm)\n  loadMode(cm)\n  setDirectionClass(cm)\n  if (!cm.options.lineWrapping) { findMaxLine(cm) }\n  cm.options.mode = doc.modeOption\n  regChange(cm)\n}\n\nfunction setDirectionClass(cm) {\n  ;(cm.doc.direction == \"rtl\" ? addClass : rmClass)(cm.display.lineDiv, \"CodeMirror-rtl\")\n}\n\nfunction directionChanged(cm) {\n  runInOp(cm, function () {\n    setDirectionClass(cm)\n    regChange(cm)\n  })\n}\n\nfunction History(startGen) {\n  // Arrays of change events and selections. Doing something adds an\n  // event to done and clears undo. Undoing moves events from done\n  // to undone, redoing moves them in the other direction.\n  this.done = []; this.undone = []\n  this.undoDepth = Infinity\n  // Used to track when changes can be merged into a single undo\n  // event\n  this.lastModTime = this.lastSelTime = 0\n  this.lastOp = this.lastSelOp = null\n  this.lastOrigin = this.lastSelOrigin = null\n  // Used by the isClean() method\n  this.generation = this.maxGeneration = startGen || 1\n}\n\n// Create a history change event from an updateDoc-style change\n// object.\nfunction historyChangeFromChange(doc, change) {\n  var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)}\n  attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1)\n  linkedDocs(doc, function (doc) { return attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); }, true)\n  return histChange\n}\n\n// Pop all selection events off the end of a history array. Stop at\n// a change event.\nfunction clearSelectionEvents(array) {\n  while (array.length) {\n    var last = lst(array)\n    if (last.ranges) { array.pop() }\n    else { break }\n  }\n}\n\n// Find the top change event in the history. Pop off selection\n// events that are in the way.\nfunction lastChangeEvent(hist, force) {\n  if (force) {\n    clearSelectionEvents(hist.done)\n    return lst(hist.done)\n  } else if (hist.done.length && !lst(hist.done).ranges) {\n    return lst(hist.done)\n  } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) {\n    hist.done.pop()\n    return lst(hist.done)\n  }\n}\n\n// Register a change in the history. Merges changes that are within\n// a single operation, or are close together with an origin that\n// allows merging (starting with \"+\") into a single event.\nfunction addChangeToHistory(doc, change, selAfter, opId) {\n  var hist = doc.history\n  hist.undone.length = 0\n  var time = +new Date, cur\n  var last\n\n  if ((hist.lastOp == opId ||\n       hist.lastOrigin == change.origin && change.origin &&\n       ((change.origin.charAt(0) == \"+\" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) ||\n        change.origin.charAt(0) == \"*\")) &&\n      (cur = lastChangeEvent(hist, hist.lastOp == opId))) {\n    // Merge this change into the last event\n    last = lst(cur.changes)\n    if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) {\n      // Optimized case for simple insertion -- don't want to add\n      // new changesets for every character typed\n      last.to = changeEnd(change)\n    } else {\n      // Add new sub-event\n      cur.changes.push(historyChangeFromChange(doc, change))\n    }\n  } else {\n    // Can not be merged, start a new event.\n    var before = lst(hist.done)\n    if (!before || !before.ranges)\n      { pushSelectionToHistory(doc.sel, hist.done) }\n    cur = {changes: [historyChangeFromChange(doc, change)],\n           generation: hist.generation}\n    hist.done.push(cur)\n    while (hist.done.length > hist.undoDepth) {\n      hist.done.shift()\n      if (!hist.done[0].ranges) { hist.done.shift() }\n    }\n  }\n  hist.done.push(selAfter)\n  hist.generation = ++hist.maxGeneration\n  hist.lastModTime = hist.lastSelTime = time\n  hist.lastOp = hist.lastSelOp = opId\n  hist.lastOrigin = hist.lastSelOrigin = change.origin\n\n  if (!last) { signal(doc, \"historyAdded\") }\n}\n\nfunction selectionEventCanBeMerged(doc, origin, prev, sel) {\n  var ch = origin.charAt(0)\n  return ch == \"*\" ||\n    ch == \"+\" &&\n    prev.ranges.length == sel.ranges.length &&\n    prev.somethingSelected() == sel.somethingSelected() &&\n    new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500)\n}\n\n// Called whenever the selection changes, sets the new selection as\n// the pending selection in the history, and pushes the old pending\n// selection into the 'done' array when it was significantly\n// different (in number of selected ranges, emptiness, or time).\nfunction addSelectionToHistory(doc, sel, opId, options) {\n  var hist = doc.history, origin = options && options.origin\n\n  // A new event is started when the previous origin does not match\n  // the current, or the origins don't allow matching. Origins\n  // starting with * are always merged, those starting with + are\n  // merged when similar and close together in time.\n  if (opId == hist.lastSelOp ||\n      (origin && hist.lastSelOrigin == origin &&\n       (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin ||\n        selectionEventCanBeMerged(doc, origin, lst(hist.done), sel))))\n    { hist.done[hist.done.length - 1] = sel }\n  else\n    { pushSelectionToHistory(sel, hist.done) }\n\n  hist.lastSelTime = +new Date\n  hist.lastSelOrigin = origin\n  hist.lastSelOp = opId\n  if (options && options.clearRedo !== false)\n    { clearSelectionEvents(hist.undone) }\n}\n\nfunction pushSelectionToHistory(sel, dest) {\n  var top = lst(dest)\n  if (!(top && top.ranges && top.equals(sel)))\n    { dest.push(sel) }\n}\n\n// Used to store marked span information in the history.\nfunction attachLocalSpans(doc, change, from, to) {\n  var existing = change[\"spans_\" + doc.id], n = 0\n  doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function (line) {\n    if (line.markedSpans)\n      { (existing || (existing = change[\"spans_\" + doc.id] = {}))[n] = line.markedSpans }\n    ++n\n  })\n}\n\n// When un/re-doing restores text containing marked spans, those\n// that have been explicitly cleared should not be restored.\nfunction removeClearedSpans(spans) {\n  if (!spans) { return null }\n  var out\n  for (var i = 0; i < spans.length; ++i) {\n    if (spans[i].marker.explicitlyCleared) { if (!out) { out = spans.slice(0, i) } }\n    else if (out) { out.push(spans[i]) }\n  }\n  return !out ? spans : out.length ? out : null\n}\n\n// Retrieve and filter the old marked spans stored in a change event.\nfunction getOldSpans(doc, change) {\n  var found = change[\"spans_\" + doc.id]\n  if (!found) { return null }\n  var nw = []\n  for (var i = 0; i < change.text.length; ++i)\n    { nw.push(removeClearedSpans(found[i])) }\n  return nw\n}\n\n// Used for un/re-doing changes from the history. Combines the\n// result of computing the existing spans with the set of spans that\n// existed in the history (so that deleting around a span and then\n// undoing brings back the span).\nfunction mergeOldSpans(doc, change) {\n  var old = getOldSpans(doc, change)\n  var stretched = stretchSpansOverChange(doc, change)\n  if (!old) { return stretched }\n  if (!stretched) { return old }\n\n  for (var i = 0; i < old.length; ++i) {\n    var oldCur = old[i], stretchCur = stretched[i]\n    if (oldCur && stretchCur) {\n      spans: for (var j = 0; j < stretchCur.length; ++j) {\n        var span = stretchCur[j]\n        for (var k = 0; k < oldCur.length; ++k)\n          { if (oldCur[k].marker == span.marker) { continue spans } }\n        oldCur.push(span)\n      }\n    } else if (stretchCur) {\n      old[i] = stretchCur\n    }\n  }\n  return old\n}\n\n// Used both to provide a JSON-safe object in .getHistory, and, when\n// detaching a document, to split the history in two\nfunction copyHistoryArray(events, newGroup, instantiateSel) {\n  var copy = []\n  for (var i = 0; i < events.length; ++i) {\n    var event = events[i]\n    if (event.ranges) {\n      copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event)\n      continue\n    }\n    var changes = event.changes, newChanges = []\n    copy.push({changes: newChanges})\n    for (var j = 0; j < changes.length; ++j) {\n      var change = changes[j], m = (void 0)\n      newChanges.push({from: change.from, to: change.to, text: change.text})\n      if (newGroup) { for (var prop in change) { if (m = prop.match(/^spans_(\\d+)$/)) {\n        if (indexOf(newGroup, Number(m[1])) > -1) {\n          lst(newChanges)[prop] = change[prop]\n          delete change[prop]\n        }\n      } } }\n    }\n  }\n  return copy\n}\n\n// The 'scroll' parameter given to many of these indicated whether\n// the new cursor position should be scrolled into view after\n// modifying the selection.\n\n// If shift is held or the extend flag is set, extends a range to\n// include a given position (and optionally a second position).\n// Otherwise, simply returns the range between the given positions.\n// Used for cursor motion and such.\nfunction extendRange(range, head, other, extend) {\n  if (extend) {\n    var anchor = range.anchor\n    if (other) {\n      var posBefore = cmp(head, anchor) < 0\n      if (posBefore != (cmp(other, anchor) < 0)) {\n        anchor = head\n        head = other\n      } else if (posBefore != (cmp(head, other) < 0)) {\n        head = other\n      }\n    }\n    return new Range(anchor, head)\n  } else {\n    return new Range(other || head, head)\n  }\n}\n\n// Extend the primary selection range, discard the rest.\nfunction extendSelection(doc, head, other, options, extend) {\n  if (extend == null) { extend = doc.cm && (doc.cm.display.shift || doc.extend) }\n  setSelection(doc, new Selection([extendRange(doc.sel.primary(), head, other, extend)], 0), options)\n}\n\n// Extend all selections (pos is an array of selections with length\n// equal the number of selections)\nfunction extendSelections(doc, heads, options) {\n  var out = []\n  var extend = doc.cm && (doc.cm.display.shift || doc.extend)\n  for (var i = 0; i < doc.sel.ranges.length; i++)\n    { out[i] = extendRange(doc.sel.ranges[i], heads[i], null, extend) }\n  var newSel = normalizeSelection(out, doc.sel.primIndex)\n  setSelection(doc, newSel, options)\n}\n\n// Updates a single range in the selection.\nfunction replaceOneSelection(doc, i, range, options) {\n  var ranges = doc.sel.ranges.slice(0)\n  ranges[i] = range\n  setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options)\n}\n\n// Reset the selection to a single range.\nfunction setSimpleSelection(doc, anchor, head, options) {\n  setSelection(doc, simpleSelection(anchor, head), options)\n}\n\n// Give beforeSelectionChange handlers a change to influence a\n// selection update.\nfunction filterSelectionChange(doc, sel, options) {\n  var obj = {\n    ranges: sel.ranges,\n    update: function(ranges) {\n      var this$1 = this;\n\n      this.ranges = []\n      for (var i = 0; i < ranges.length; i++)\n        { this$1.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),\n                                   clipPos(doc, ranges[i].head)) }\n    },\n    origin: options && options.origin\n  }\n  signal(doc, \"beforeSelectionChange\", doc, obj)\n  if (doc.cm) { signal(doc.cm, \"beforeSelectionChange\", doc.cm, obj) }\n  if (obj.ranges != sel.ranges) { return normalizeSelection(obj.ranges, obj.ranges.length - 1) }\n  else { return sel }\n}\n\nfunction setSelectionReplaceHistory(doc, sel, options) {\n  var done = doc.history.done, last = lst(done)\n  if (last && last.ranges) {\n    done[done.length - 1] = sel\n    setSelectionNoUndo(doc, sel, options)\n  } else {\n    setSelection(doc, sel, options)\n  }\n}\n\n// Set a new selection.\nfunction setSelection(doc, sel, options) {\n  setSelectionNoUndo(doc, sel, options)\n  addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options)\n}\n\nfunction setSelectionNoUndo(doc, sel, options) {\n  if (hasHandler(doc, \"beforeSelectionChange\") || doc.cm && hasHandler(doc.cm, \"beforeSelectionChange\"))\n    { sel = filterSelectionChange(doc, sel, options) }\n\n  var bias = options && options.bias ||\n    (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1)\n  setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true))\n\n  if (!(options && options.scroll === false) && doc.cm)\n    { ensureCursorVisible(doc.cm) }\n}\n\nfunction setSelectionInner(doc, sel) {\n  if (sel.equals(doc.sel)) { return }\n\n  doc.sel = sel\n\n  if (doc.cm) {\n    doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true\n    signalCursorActivity(doc.cm)\n  }\n  signalLater(doc, \"cursorActivity\", doc)\n}\n\n// Verify that the selection does not partially select any atomic\n// marked ranges.\nfunction reCheckSelection(doc) {\n  setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false))\n}\n\n// Return a selection that does not partially select any atomic\n// ranges.\nfunction skipAtomicInSelection(doc, sel, bias, mayClear) {\n  var out\n  for (var i = 0; i < sel.ranges.length; i++) {\n    var range = sel.ranges[i]\n    var old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i]\n    var newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear)\n    var newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear)\n    if (out || newAnchor != range.anchor || newHead != range.head) {\n      if (!out) { out = sel.ranges.slice(0, i) }\n      out[i] = new Range(newAnchor, newHead)\n    }\n  }\n  return out ? normalizeSelection(out, sel.primIndex) : sel\n}\n\nfunction skipAtomicInner(doc, pos, oldPos, dir, mayClear) {\n  var line = getLine(doc, pos.line)\n  if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) {\n    var sp = line.markedSpans[i], m = sp.marker\n    if ((sp.from == null || (m.inclusiveLeft ? sp.from <= pos.ch : sp.from < pos.ch)) &&\n        (sp.to == null || (m.inclusiveRight ? sp.to >= pos.ch : sp.to > pos.ch))) {\n      if (mayClear) {\n        signal(m, \"beforeCursorEnter\")\n        if (m.explicitlyCleared) {\n          if (!line.markedSpans) { break }\n          else {--i; continue}\n        }\n      }\n      if (!m.atomic) { continue }\n\n      if (oldPos) {\n        var near = m.find(dir < 0 ? 1 : -1), diff = (void 0)\n        if (dir < 0 ? m.inclusiveRight : m.inclusiveLeft)\n          { near = movePos(doc, near, -dir, near && near.line == pos.line ? line : null) }\n        if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0))\n          { return skipAtomicInner(doc, near, pos, dir, mayClear) }\n      }\n\n      var far = m.find(dir < 0 ? -1 : 1)\n      if (dir < 0 ? m.inclusiveLeft : m.inclusiveRight)\n        { far = movePos(doc, far, dir, far.line == pos.line ? line : null) }\n      return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null\n    }\n  } }\n  return pos\n}\n\n// Ensure a given position is not inside an atomic range.\nfunction skipAtomic(doc, pos, oldPos, bias, mayClear) {\n  var dir = bias || 1\n  var found = skipAtomicInner(doc, pos, oldPos, dir, mayClear) ||\n      (!mayClear && skipAtomicInner(doc, pos, oldPos, dir, true)) ||\n      skipAtomicInner(doc, pos, oldPos, -dir, mayClear) ||\n      (!mayClear && skipAtomicInner(doc, pos, oldPos, -dir, true))\n  if (!found) {\n    doc.cantEdit = true\n    return Pos(doc.first, 0)\n  }\n  return found\n}\n\nfunction movePos(doc, pos, dir, line) {\n  if (dir < 0 && pos.ch == 0) {\n    if (pos.line > doc.first) { return clipPos(doc, Pos(pos.line - 1)) }\n    else { return null }\n  } else if (dir > 0 && pos.ch == (line || getLine(doc, pos.line)).text.length) {\n    if (pos.line < doc.first + doc.size - 1) { return Pos(pos.line + 1, 0) }\n    else { return null }\n  } else {\n    return new Pos(pos.line, pos.ch + dir)\n  }\n}\n\nfunction selectAll(cm) {\n  cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll)\n}\n\n// UPDATING\n\n// Allow \"beforeChange\" event handlers to influence a change\nfunction filterChange(doc, change, update) {\n  var obj = {\n    canceled: false,\n    from: change.from,\n    to: change.to,\n    text: change.text,\n    origin: change.origin,\n    cancel: function () { return obj.canceled = true; }\n  }\n  if (update) { obj.update = function (from, to, text, origin) {\n    if (from) { obj.from = clipPos(doc, from) }\n    if (to) { obj.to = clipPos(doc, to) }\n    if (text) { obj.text = text }\n    if (origin !== undefined) { obj.origin = origin }\n  } }\n  signal(doc, \"beforeChange\", doc, obj)\n  if (doc.cm) { signal(doc.cm, \"beforeChange\", doc.cm, obj) }\n\n  if (obj.canceled) { return null }\n  return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin}\n}\n\n// Apply a change to a document, and add it to the document's\n// history, and propagating it to all linked documents.\nfunction makeChange(doc, change, ignoreReadOnly) {\n  if (doc.cm) {\n    if (!doc.cm.curOp) { return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly) }\n    if (doc.cm.state.suppressEdits) { return }\n  }\n\n  if (hasHandler(doc, \"beforeChange\") || doc.cm && hasHandler(doc.cm, \"beforeChange\")) {\n    change = filterChange(doc, change, true)\n    if (!change) { return }\n  }\n\n  // Possibly split or suppress the update based on the presence\n  // of read-only spans in its range.\n  var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to)\n  if (split) {\n    for (var i = split.length - 1; i >= 0; --i)\n      { makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [\"\"] : change.text}) }\n  } else {\n    makeChangeInner(doc, change)\n  }\n}\n\nfunction makeChangeInner(doc, change) {\n  if (change.text.length == 1 && change.text[0] == \"\" && cmp(change.from, change.to) == 0) { return }\n  var selAfter = computeSelAfterChange(doc, change)\n  addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN)\n\n  makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change))\n  var rebased = []\n\n  linkedDocs(doc, function (doc, sharedHist) {\n    if (!sharedHist && indexOf(rebased, doc.history) == -1) {\n      rebaseHist(doc.history, change)\n      rebased.push(doc.history)\n    }\n    makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change))\n  })\n}\n\n// Revert a change stored in a document's history.\nfunction makeChangeFromHistory(doc, type, allowSelectionOnly) {\n  if (doc.cm && doc.cm.state.suppressEdits && !allowSelectionOnly) { return }\n\n  var hist = doc.history, event, selAfter = doc.sel\n  var source = type == \"undo\" ? hist.done : hist.undone, dest = type == \"undo\" ? hist.undone : hist.done\n\n  // Verify that there is a useable event (so that ctrl-z won't\n  // needlessly clear selection events)\n  var i = 0\n  for (; i < source.length; i++) {\n    event = source[i]\n    if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges)\n      { break }\n  }\n  if (i == source.length) { return }\n  hist.lastOrigin = hist.lastSelOrigin = null\n\n  for (;;) {\n    event = source.pop()\n    if (event.ranges) {\n      pushSelectionToHistory(event, dest)\n      if (allowSelectionOnly && !event.equals(doc.sel)) {\n        setSelection(doc, event, {clearRedo: false})\n        return\n      }\n      selAfter = event\n    }\n    else { break }\n  }\n\n  // Build up a reverse change object to add to the opposite history\n  // stack (redo when undoing, and vice versa).\n  var antiChanges = []\n  pushSelectionToHistory(selAfter, dest)\n  dest.push({changes: antiChanges, generation: hist.generation})\n  hist.generation = event.generation || ++hist.maxGeneration\n\n  var filter = hasHandler(doc, \"beforeChange\") || doc.cm && hasHandler(doc.cm, \"beforeChange\")\n\n  var loop = function ( i ) {\n    var change = event.changes[i]\n    change.origin = type\n    if (filter && !filterChange(doc, change, false)) {\n      source.length = 0\n      return {}\n    }\n\n    antiChanges.push(historyChangeFromChange(doc, change))\n\n    var after = i ? computeSelAfterChange(doc, change) : lst(source)\n    makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change))\n    if (!i && doc.cm) { doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)}) }\n    var rebased = []\n\n    // Propagate to the linked documents\n    linkedDocs(doc, function (doc, sharedHist) {\n      if (!sharedHist && indexOf(rebased, doc.history) == -1) {\n        rebaseHist(doc.history, change)\n        rebased.push(doc.history)\n      }\n      makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change))\n    })\n  };\n\n  for (var i$1 = event.changes.length - 1; i$1 >= 0; --i$1) {\n    var returned = loop( i$1 );\n\n    if ( returned ) return returned.v;\n  }\n}\n\n// Sub-views need their line numbers shifted when text is added\n// above or below them in the parent document.\nfunction shiftDoc(doc, distance) {\n  if (distance == 0) { return }\n  doc.first += distance\n  doc.sel = new Selection(map(doc.sel.ranges, function (range) { return new Range(\n    Pos(range.anchor.line + distance, range.anchor.ch),\n    Pos(range.head.line + distance, range.head.ch)\n  ); }), doc.sel.primIndex)\n  if (doc.cm) {\n    regChange(doc.cm, doc.first, doc.first - distance, distance)\n    for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++)\n      { regLineChange(doc.cm, l, \"gutter\") }\n  }\n}\n\n// More lower-level change function, handling only a single document\n// (not linked ones).\nfunction makeChangeSingleDoc(doc, change, selAfter, spans) {\n  if (doc.cm && !doc.cm.curOp)\n    { return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans) }\n\n  if (change.to.line < doc.first) {\n    shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line))\n    return\n  }\n  if (change.from.line > doc.lastLine()) { return }\n\n  // Clip the change to the size of this doc\n  if (change.from.line < doc.first) {\n    var shift = change.text.length - 1 - (doc.first - change.from.line)\n    shiftDoc(doc, shift)\n    change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),\n              text: [lst(change.text)], origin: change.origin}\n  }\n  var last = doc.lastLine()\n  if (change.to.line > last) {\n    change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),\n              text: [change.text[0]], origin: change.origin}\n  }\n\n  change.removed = getBetween(doc, change.from, change.to)\n\n  if (!selAfter) { selAfter = computeSelAfterChange(doc, change) }\n  if (doc.cm) { makeChangeSingleDocInEditor(doc.cm, change, spans) }\n  else { updateDoc(doc, change, spans) }\n  setSelectionNoUndo(doc, selAfter, sel_dontScroll)\n}\n\n// Handle the interaction of a change to a document with the editor\n// that this document is part of.\nfunction makeChangeSingleDocInEditor(cm, change, spans) {\n  var doc = cm.doc, display = cm.display, from = change.from, to = change.to\n\n  var recomputeMaxLength = false, checkWidthStart = from.line\n  if (!cm.options.lineWrapping) {\n    checkWidthStart = lineNo(visualLine(getLine(doc, from.line)))\n    doc.iter(checkWidthStart, to.line + 1, function (line) {\n      if (line == display.maxLine) {\n        recomputeMaxLength = true\n        return true\n      }\n    })\n  }\n\n  if (doc.sel.contains(change.from, change.to) > -1)\n    { signalCursorActivity(cm) }\n\n  updateDoc(doc, change, spans, estimateHeight(cm))\n\n  if (!cm.options.lineWrapping) {\n    doc.iter(checkWidthStart, from.line + change.text.length, function (line) {\n      var len = lineLength(line)\n      if (len > display.maxLineLength) {\n        display.maxLine = line\n        display.maxLineLength = len\n        display.maxLineChanged = true\n        recomputeMaxLength = false\n      }\n    })\n    if (recomputeMaxLength) { cm.curOp.updateMaxLine = true }\n  }\n\n  retreatFrontier(doc, from.line)\n  startWorker(cm, 400)\n\n  var lendiff = change.text.length - (to.line - from.line) - 1\n  // Remember that these lines changed, for updating the display\n  if (change.full)\n    { regChange(cm) }\n  else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))\n    { regLineChange(cm, from.line, \"text\") }\n  else\n    { regChange(cm, from.line, to.line + 1, lendiff) }\n\n  var changesHandler = hasHandler(cm, \"changes\"), changeHandler = hasHandler(cm, \"change\")\n  if (changeHandler || changesHandler) {\n    var obj = {\n      from: from, to: to,\n      text: change.text,\n      removed: change.removed,\n      origin: change.origin\n    }\n    if (changeHandler) { signalLater(cm, \"change\", cm, obj) }\n    if (changesHandler) { (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj) }\n  }\n  cm.display.selForContextMenu = null\n}\n\nfunction replaceRange(doc, code, from, to, origin) {\n  if (!to) { to = from }\n  if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp }\n  if (typeof code == \"string\") { code = doc.splitLines(code) }\n  makeChange(doc, {from: from, to: to, text: code, origin: origin})\n}\n\n// Rebasing/resetting history to deal with externally-sourced changes\n\nfunction rebaseHistSelSingle(pos, from, to, diff) {\n  if (to < pos.line) {\n    pos.line += diff\n  } else if (from < pos.line) {\n    pos.line = from\n    pos.ch = 0\n  }\n}\n\n// Tries to rebase an array of history events given a change in the\n// document. If the change touches the same lines as the event, the\n// event, and everything 'behind' it, is discarded. If the change is\n// before the event, the event's positions are updated. Uses a\n// copy-on-write scheme for the positions, to avoid having to\n// reallocate them all on every rebase, but also avoid problems with\n// shared position objects being unsafely updated.\nfunction rebaseHistArray(array, from, to, diff) {\n  for (var i = 0; i < array.length; ++i) {\n    var sub = array[i], ok = true\n    if (sub.ranges) {\n      if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true }\n      for (var j = 0; j < sub.ranges.length; j++) {\n        rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff)\n        rebaseHistSelSingle(sub.ranges[j].head, from, to, diff)\n      }\n      continue\n    }\n    for (var j$1 = 0; j$1 < sub.changes.length; ++j$1) {\n      var cur = sub.changes[j$1]\n      if (to < cur.from.line) {\n        cur.from = Pos(cur.from.line + diff, cur.from.ch)\n        cur.to = Pos(cur.to.line + diff, cur.to.ch)\n      } else if (from <= cur.to.line) {\n        ok = false\n        break\n      }\n    }\n    if (!ok) {\n      array.splice(0, i + 1)\n      i = 0\n    }\n  }\n}\n\nfunction rebaseHist(hist, change) {\n  var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1\n  rebaseHistArray(hist.done, from, to, diff)\n  rebaseHistArray(hist.undone, from, to, diff)\n}\n\n// Utility for applying a change to a line by handle or number,\n// returning the number and optionally registering the line as\n// changed.\nfunction changeLine(doc, handle, changeType, op) {\n  var no = handle, line = handle\n  if (typeof handle == \"number\") { line = getLine(doc, clipLine(doc, handle)) }\n  else { no = lineNo(handle) }\n  if (no == null) { return null }\n  if (op(line, no) && doc.cm) { regLineChange(doc.cm, no, changeType) }\n  return line\n}\n\n// The document is represented as a BTree consisting of leaves, with\n// chunk of lines in them, and branches, with up to ten leaves or\n// other branch nodes below them. The top node is always a branch\n// node, and is the document object itself (meaning it has\n// additional methods and properties).\n//\n// All nodes have parent links. The tree is used both to go from\n// line numbers to line objects, and to go from objects to numbers.\n// It also indexes by height, and is used to convert between height\n// and line object, and to find the total height of the document.\n//\n// See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html\n\nfunction LeafChunk(lines) {\n  var this$1 = this;\n\n  this.lines = lines\n  this.parent = null\n  var height = 0\n  for (var i = 0; i < lines.length; ++i) {\n    lines[i].parent = this$1\n    height += lines[i].height\n  }\n  this.height = height\n}\n\nLeafChunk.prototype = {\n  chunkSize: function chunkSize() { return this.lines.length },\n\n  // Remove the n lines at offset 'at'.\n  removeInner: function removeInner(at, n) {\n    var this$1 = this;\n\n    for (var i = at, e = at + n; i < e; ++i) {\n      var line = this$1.lines[i]\n      this$1.height -= line.height\n      cleanUpLine(line)\n      signalLater(line, \"delete\")\n    }\n    this.lines.splice(at, n)\n  },\n\n  // Helper used to collapse a small branch into a single leaf.\n  collapse: function collapse(lines) {\n    lines.push.apply(lines, this.lines)\n  },\n\n  // Insert the given array of lines at offset 'at', count them as\n  // having the given height.\n  insertInner: function insertInner(at, lines, height) {\n    var this$1 = this;\n\n    this.height += height\n    this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at))\n    for (var i = 0; i < lines.length; ++i) { lines[i].parent = this$1 }\n  },\n\n  // Used to iterate over a part of the tree.\n  iterN: function iterN(at, n, op) {\n    var this$1 = this;\n\n    for (var e = at + n; at < e; ++at)\n      { if (op(this$1.lines[at])) { return true } }\n  }\n}\n\nfunction BranchChunk(children) {\n  var this$1 = this;\n\n  this.children = children\n  var size = 0, height = 0\n  for (var i = 0; i < children.length; ++i) {\n    var ch = children[i]\n    size += ch.chunkSize(); height += ch.height\n    ch.parent = this$1\n  }\n  this.size = size\n  this.height = height\n  this.parent = null\n}\n\nBranchChunk.prototype = {\n  chunkSize: function chunkSize() { return this.size },\n\n  removeInner: function removeInner(at, n) {\n    var this$1 = this;\n\n    this.size -= n\n    for (var i = 0; i < this.children.length; ++i) {\n      var child = this$1.children[i], sz = child.chunkSize()\n      if (at < sz) {\n        var rm = Math.min(n, sz - at), oldHeight = child.height\n        child.removeInner(at, rm)\n        this$1.height -= oldHeight - child.height\n        if (sz == rm) { this$1.children.splice(i--, 1); child.parent = null }\n        if ((n -= rm) == 0) { break }\n        at = 0\n      } else { at -= sz }\n    }\n    // If the result is smaller than 25 lines, ensure that it is a\n    // single leaf node.\n    if (this.size - n < 25 &&\n        (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) {\n      var lines = []\n      this.collapse(lines)\n      this.children = [new LeafChunk(lines)]\n      this.children[0].parent = this\n    }\n  },\n\n  collapse: function collapse(lines) {\n    var this$1 = this;\n\n    for (var i = 0; i < this.children.length; ++i) { this$1.children[i].collapse(lines) }\n  },\n\n  insertInner: function insertInner(at, lines, height) {\n    var this$1 = this;\n\n    this.size += lines.length\n    this.height += height\n    for (var i = 0; i < this.children.length; ++i) {\n      var child = this$1.children[i], sz = child.chunkSize()\n      if (at <= sz) {\n        child.insertInner(at, lines, height)\n        if (child.lines && child.lines.length > 50) {\n          // To avoid memory thrashing when child.lines is huge (e.g. first view of a large file), it's never spliced.\n          // Instead, small slices are taken. They're taken in order because sequential memory accesses are fastest.\n          var remaining = child.lines.length % 25 + 25\n          for (var pos = remaining; pos < child.lines.length;) {\n            var leaf = new LeafChunk(child.lines.slice(pos, pos += 25))\n            child.height -= leaf.height\n            this$1.children.splice(++i, 0, leaf)\n            leaf.parent = this$1\n          }\n          child.lines = child.lines.slice(0, remaining)\n          this$1.maybeSpill()\n        }\n        break\n      }\n      at -= sz\n    }\n  },\n\n  // When a node has grown, check whether it should be split.\n  maybeSpill: function maybeSpill() {\n    if (this.children.length <= 10) { return }\n    var me = this\n    do {\n      var spilled = me.children.splice(me.children.length - 5, 5)\n      var sibling = new BranchChunk(spilled)\n      if (!me.parent) { // Become the parent node\n        var copy = new BranchChunk(me.children)\n        copy.parent = me\n        me.children = [copy, sibling]\n        me = copy\n     } else {\n        me.size -= sibling.size\n        me.height -= sibling.height\n        var myIndex = indexOf(me.parent.children, me)\n        me.parent.children.splice(myIndex + 1, 0, sibling)\n      }\n      sibling.parent = me.parent\n    } while (me.children.length > 10)\n    me.parent.maybeSpill()\n  },\n\n  iterN: function iterN(at, n, op) {\n    var this$1 = this;\n\n    for (var i = 0; i < this.children.length; ++i) {\n      var child = this$1.children[i], sz = child.chunkSize()\n      if (at < sz) {\n        var used = Math.min(n, sz - at)\n        if (child.iterN(at, used, op)) { return true }\n        if ((n -= used) == 0) { break }\n        at = 0\n      } else { at -= sz }\n    }\n  }\n}\n\n// Line widgets are block elements displayed above or below a line.\n\nvar LineWidget = function(doc, node, options) {\n  var this$1 = this;\n\n  if (options) { for (var opt in options) { if (options.hasOwnProperty(opt))\n    { this$1[opt] = options[opt] } } }\n  this.doc = doc\n  this.node = node\n};\n\nLineWidget.prototype.clear = function () {\n    var this$1 = this;\n\n  var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line)\n  if (no == null || !ws) { return }\n  for (var i = 0; i < ws.length; ++i) { if (ws[i] == this$1) { ws.splice(i--, 1) } }\n  if (!ws.length) { line.widgets = null }\n  var height = widgetHeight(this)\n  updateLineHeight(line, Math.max(0, line.height - height))\n  if (cm) {\n    runInOp(cm, function () {\n      adjustScrollWhenAboveVisible(cm, line, -height)\n      regLineChange(cm, no, \"widget\")\n    })\n    signalLater(cm, \"lineWidgetCleared\", cm, this, no)\n  }\n};\n\nLineWidget.prototype.changed = function () {\n    var this$1 = this;\n\n  var oldH = this.height, cm = this.doc.cm, line = this.line\n  this.height = null\n  var diff = widgetHeight(this) - oldH\n  if (!diff) { return }\n  updateLineHeight(line, line.height + diff)\n  if (cm) {\n    runInOp(cm, function () {\n      cm.curOp.forceUpdate = true\n      adjustScrollWhenAboveVisible(cm, line, diff)\n      signalLater(cm, \"lineWidgetChanged\", cm, this$1, lineNo(line))\n    })\n  }\n};\neventMixin(LineWidget)\n\nfunction adjustScrollWhenAboveVisible(cm, line, diff) {\n  if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop))\n    { addToScrollTop(cm, diff) }\n}\n\nfunction addLineWidget(doc, handle, node, options) {\n  var widget = new LineWidget(doc, node, options)\n  var cm = doc.cm\n  if (cm && widget.noHScroll) { cm.display.alignWidgets = true }\n  changeLine(doc, handle, \"widget\", function (line) {\n    var widgets = line.widgets || (line.widgets = [])\n    if (widget.insertAt == null) { widgets.push(widget) }\n    else { widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget) }\n    widget.line = line\n    if (cm && !lineIsHidden(doc, line)) {\n      var aboveVisible = heightAtLine(line) < doc.scrollTop\n      updateLineHeight(line, line.height + widgetHeight(widget))\n      if (aboveVisible) { addToScrollTop(cm, widget.height) }\n      cm.curOp.forceUpdate = true\n    }\n    return true\n  })\n  signalLater(cm, \"lineWidgetAdded\", cm, widget, typeof handle == \"number\" ? handle : lineNo(handle))\n  return widget\n}\n\n// TEXTMARKERS\n\n// Created with markText and setBookmark methods. A TextMarker is a\n// handle that can be used to clear or find a marked position in the\n// document. Line objects hold arrays (markedSpans) containing\n// {from, to, marker} object pointing to such marker objects, and\n// indicating that such a marker is present on that line. Multiple\n// lines may point to the same marker when it spans across lines.\n// The spans will have null for their from/to properties when the\n// marker continues beyond the start/end of the line. Markers have\n// links back to the lines they currently touch.\n\n// Collapsed markers have unique ids, in order to be able to order\n// them, which is needed for uniquely determining an outer marker\n// when they overlap (they may nest, but not partially overlap).\nvar nextMarkerId = 0\n\nvar TextMarker = function(doc, type) {\n  this.lines = []\n  this.type = type\n  this.doc = doc\n  this.id = ++nextMarkerId\n};\n\n// Clear the marker.\nTextMarker.prototype.clear = function () {\n    var this$1 = this;\n\n  if (this.explicitlyCleared) { return }\n  var cm = this.doc.cm, withOp = cm && !cm.curOp\n  if (withOp) { startOperation(cm) }\n  if (hasHandler(this, \"clear\")) {\n    var found = this.find()\n    if (found) { signalLater(this, \"clear\", found.from, found.to) }\n  }\n  var min = null, max = null\n  for (var i = 0; i < this.lines.length; ++i) {\n    var line = this$1.lines[i]\n    var span = getMarkedSpanFor(line.markedSpans, this$1)\n    if (cm && !this$1.collapsed) { regLineChange(cm, lineNo(line), \"text\") }\n    else if (cm) {\n      if (span.to != null) { max = lineNo(line) }\n      if (span.from != null) { min = lineNo(line) }\n    }\n    line.markedSpans = removeMarkedSpan(line.markedSpans, span)\n    if (span.from == null && this$1.collapsed && !lineIsHidden(this$1.doc, line) && cm)\n      { updateLineHeight(line, textHeight(cm.display)) }\n  }\n  if (cm && this.collapsed && !cm.options.lineWrapping) { for (var i$1 = 0; i$1 < this.lines.length; ++i$1) {\n    var visual = visualLine(this$1.lines[i$1]), len = lineLength(visual)\n    if (len > cm.display.maxLineLength) {\n      cm.display.maxLine = visual\n      cm.display.maxLineLength = len\n      cm.display.maxLineChanged = true\n    }\n  } }\n\n  if (min != null && cm && this.collapsed) { regChange(cm, min, max + 1) }\n  this.lines.length = 0\n  this.explicitlyCleared = true\n  if (this.atomic && this.doc.cantEdit) {\n    this.doc.cantEdit = false\n    if (cm) { reCheckSelection(cm.doc) }\n  }\n  if (cm) { signalLater(cm, \"markerCleared\", cm, this, min, max) }\n  if (withOp) { endOperation(cm) }\n  if (this.parent) { this.parent.clear() }\n};\n\n// Find the position of the marker in the document. Returns a {from,\n// to} object by default. Side can be passed to get a specific side\n// -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the\n// Pos objects returned contain a line object, rather than a line\n// number (used to prevent looking up the same line twice).\nTextMarker.prototype.find = function (side, lineObj) {\n    var this$1 = this;\n\n  if (side == null && this.type == \"bookmark\") { side = 1 }\n  var from, to\n  for (var i = 0; i < this.lines.length; ++i) {\n    var line = this$1.lines[i]\n    var span = getMarkedSpanFor(line.markedSpans, this$1)\n    if (span.from != null) {\n      from = Pos(lineObj ? line : lineNo(line), span.from)\n      if (side == -1) { return from }\n    }\n    if (span.to != null) {\n      to = Pos(lineObj ? line : lineNo(line), span.to)\n      if (side == 1) { return to }\n    }\n  }\n  return from && {from: from, to: to}\n};\n\n// Signals that the marker's widget changed, and surrounding layout\n// should be recomputed.\nTextMarker.prototype.changed = function () {\n    var this$1 = this;\n\n  var pos = this.find(-1, true), widget = this, cm = this.doc.cm\n  if (!pos || !cm) { return }\n  runInOp(cm, function () {\n    var line = pos.line, lineN = lineNo(pos.line)\n    var view = findViewForLine(cm, lineN)\n    if (view) {\n      clearLineMeasurementCacheFor(view)\n      cm.curOp.selectionChanged = cm.curOp.forceUpdate = true\n    }\n    cm.curOp.updateMaxLine = true\n    if (!lineIsHidden(widget.doc, line) && widget.height != null) {\n      var oldHeight = widget.height\n      widget.height = null\n      var dHeight = widgetHeight(widget) - oldHeight\n      if (dHeight)\n        { updateLineHeight(line, line.height + dHeight) }\n    }\n    signalLater(cm, \"markerChanged\", cm, this$1)\n  })\n};\n\nTextMarker.prototype.attachLine = function (line) {\n  if (!this.lines.length && this.doc.cm) {\n    var op = this.doc.cm.curOp\n    if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)\n      { (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this) }\n  }\n  this.lines.push(line)\n};\n\nTextMarker.prototype.detachLine = function (line) {\n  this.lines.splice(indexOf(this.lines, line), 1)\n  if (!this.lines.length && this.doc.cm) {\n    var op = this.doc.cm.curOp\n    ;(op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this)\n  }\n};\neventMixin(TextMarker)\n\n// Create a marker, wire it up to the right lines, and\nfunction markText(doc, from, to, options, type) {\n  // Shared markers (across linked documents) are handled separately\n  // (markTextShared will call out to this again, once per\n  // document).\n  if (options && options.shared) { return markTextShared(doc, from, to, options, type) }\n  // Ensure we are in an operation.\n  if (doc.cm && !doc.cm.curOp) { return operation(doc.cm, markText)(doc, from, to, options, type) }\n\n  var marker = new TextMarker(doc, type), diff = cmp(from, to)\n  if (options) { copyObj(options, marker, false) }\n  // Don't connect empty markers unless clearWhenEmpty is false\n  if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false)\n    { return marker }\n  if (marker.replacedWith) {\n    // Showing up as a widget implies collapsed (widget replaces text)\n    marker.collapsed = true\n    marker.widgetNode = eltP(\"span\", [marker.replacedWith], \"CodeMirror-widget\")\n    if (!options.handleMouseEvents) { marker.widgetNode.setAttribute(\"cm-ignore-events\", \"true\") }\n    if (options.insertLeft) { marker.widgetNode.insertLeft = true }\n  }\n  if (marker.collapsed) {\n    if (conflictingCollapsedRange(doc, from.line, from, to, marker) ||\n        from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker))\n      { throw new Error(\"Inserting collapsed marker partially overlapping an existing one\") }\n    seeCollapsedSpans()\n  }\n\n  if (marker.addToHistory)\n    { addChangeToHistory(doc, {from: from, to: to, origin: \"markText\"}, doc.sel, NaN) }\n\n  var curLine = from.line, cm = doc.cm, updateMaxLine\n  doc.iter(curLine, to.line + 1, function (line) {\n    if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine)\n      { updateMaxLine = true }\n    if (marker.collapsed && curLine != from.line) { updateLineHeight(line, 0) }\n    addMarkedSpan(line, new MarkedSpan(marker,\n                                       curLine == from.line ? from.ch : null,\n                                       curLine == to.line ? to.ch : null))\n    ++curLine\n  })\n  // lineIsHidden depends on the presence of the spans, so needs a second pass\n  if (marker.collapsed) { doc.iter(from.line, to.line + 1, function (line) {\n    if (lineIsHidden(doc, line)) { updateLineHeight(line, 0) }\n  }) }\n\n  if (marker.clearOnEnter) { on(marker, \"beforeCursorEnter\", function () { return marker.clear(); }) }\n\n  if (marker.readOnly) {\n    seeReadOnlySpans()\n    if (doc.history.done.length || doc.history.undone.length)\n      { doc.clearHistory() }\n  }\n  if (marker.collapsed) {\n    marker.id = ++nextMarkerId\n    marker.atomic = true\n  }\n  if (cm) {\n    // Sync editor state\n    if (updateMaxLine) { cm.curOp.updateMaxLine = true }\n    if (marker.collapsed)\n      { regChange(cm, from.line, to.line + 1) }\n    else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css)\n      { for (var i = from.line; i <= to.line; i++) { regLineChange(cm, i, \"text\") } }\n    if (marker.atomic) { reCheckSelection(cm.doc) }\n    signalLater(cm, \"markerAdded\", cm, marker)\n  }\n  return marker\n}\n\n// SHARED TEXTMARKERS\n\n// A shared marker spans multiple linked documents. It is\n// implemented as a meta-marker-object controlling multiple normal\n// markers.\nvar SharedTextMarker = function(markers, primary) {\n  var this$1 = this;\n\n  this.markers = markers\n  this.primary = primary\n  for (var i = 0; i < markers.length; ++i)\n    { markers[i].parent = this$1 }\n};\n\nSharedTextMarker.prototype.clear = function () {\n    var this$1 = this;\n\n  if (this.explicitlyCleared) { return }\n  this.explicitlyCleared = true\n  for (var i = 0; i < this.markers.length; ++i)\n    { this$1.markers[i].clear() }\n  signalLater(this, \"clear\")\n};\n\nSharedTextMarker.prototype.find = function (side, lineObj) {\n  return this.primary.find(side, lineObj)\n};\neventMixin(SharedTextMarker)\n\nfunction markTextShared(doc, from, to, options, type) {\n  options = copyObj(options)\n  options.shared = false\n  var markers = [markText(doc, from, to, options, type)], primary = markers[0]\n  var widget = options.widgetNode\n  linkedDocs(doc, function (doc) {\n    if (widget) { options.widgetNode = widget.cloneNode(true) }\n    markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type))\n    for (var i = 0; i < doc.linked.length; ++i)\n      { if (doc.linked[i].isParent) { return } }\n    primary = lst(markers)\n  })\n  return new SharedTextMarker(markers, primary)\n}\n\nfunction findSharedMarkers(doc) {\n  return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), function (m) { return m.parent; })\n}\n\nfunction copySharedMarkers(doc, markers) {\n  for (var i = 0; i < markers.length; i++) {\n    var marker = markers[i], pos = marker.find()\n    var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to)\n    if (cmp(mFrom, mTo)) {\n      var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type)\n      marker.markers.push(subMark)\n      subMark.parent = marker\n    }\n  }\n}\n\nfunction detachSharedMarkers(markers) {\n  var loop = function ( i ) {\n    var marker = markers[i], linked = [marker.primary.doc]\n    linkedDocs(marker.primary.doc, function (d) { return linked.push(d); })\n    for (var j = 0; j < marker.markers.length; j++) {\n      var subMarker = marker.markers[j]\n      if (indexOf(linked, subMarker.doc) == -1) {\n        subMarker.parent = null\n        marker.markers.splice(j--, 1)\n      }\n    }\n  };\n\n  for (var i = 0; i < markers.length; i++) loop( i );\n}\n\nvar nextDocId = 0\nvar Doc = function(text, mode, firstLine, lineSep, direction) {\n  if (!(this instanceof Doc)) { return new Doc(text, mode, firstLine, lineSep, direction) }\n  if (firstLine == null) { firstLine = 0 }\n\n  BranchChunk.call(this, [new LeafChunk([new Line(\"\", null)])])\n  this.first = firstLine\n  this.scrollTop = this.scrollLeft = 0\n  this.cantEdit = false\n  this.cleanGeneration = 1\n  this.modeFrontier = this.highlightFrontier = firstLine\n  var start = Pos(firstLine, 0)\n  this.sel = simpleSelection(start)\n  this.history = new History(null)\n  this.id = ++nextDocId\n  this.modeOption = mode\n  this.lineSep = lineSep\n  this.direction = (direction == \"rtl\") ? \"rtl\" : \"ltr\"\n  this.extend = false\n\n  if (typeof text == \"string\") { text = this.splitLines(text) }\n  updateDoc(this, {from: start, to: start, text: text})\n  setSelection(this, simpleSelection(start), sel_dontScroll)\n}\n\nDoc.prototype = createObj(BranchChunk.prototype, {\n  constructor: Doc,\n  // Iterate over the document. Supports two forms -- with only one\n  // argument, it calls that for each line in the document. With\n  // three, it iterates over the range given by the first two (with\n  // the second being non-inclusive).\n  iter: function(from, to, op) {\n    if (op) { this.iterN(from - this.first, to - from, op) }\n    else { this.iterN(this.first, this.first + this.size, from) }\n  },\n\n  // Non-public interface for adding and removing lines.\n  insert: function(at, lines) {\n    var height = 0\n    for (var i = 0; i < lines.length; ++i) { height += lines[i].height }\n    this.insertInner(at - this.first, lines, height)\n  },\n  remove: function(at, n) { this.removeInner(at - this.first, n) },\n\n  // From here, the methods are part of the public interface. Most\n  // are also available from CodeMirror (editor) instances.\n\n  getValue: function(lineSep) {\n    var lines = getLines(this, this.first, this.first + this.size)\n    if (lineSep === false) { return lines }\n    return lines.join(lineSep || this.lineSeparator())\n  },\n  setValue: docMethodOp(function(code) {\n    var top = Pos(this.first, 0), last = this.first + this.size - 1\n    makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),\n                      text: this.splitLines(code), origin: \"setValue\", full: true}, true)\n    if (this.cm) { scrollToCoords(this.cm, 0, 0) }\n    setSelection(this, simpleSelection(top), sel_dontScroll)\n  }),\n  replaceRange: function(code, from, to, origin) {\n    from = clipPos(this, from)\n    to = to ? clipPos(this, to) : from\n    replaceRange(this, code, from, to, origin)\n  },\n  getRange: function(from, to, lineSep) {\n    var lines = getBetween(this, clipPos(this, from), clipPos(this, to))\n    if (lineSep === false) { return lines }\n    return lines.join(lineSep || this.lineSeparator())\n  },\n\n  getLine: function(line) {var l = this.getLineHandle(line); return l && l.text},\n\n  getLineHandle: function(line) {if (isLine(this, line)) { return getLine(this, line) }},\n  getLineNumber: function(line) {return lineNo(line)},\n\n  getLineHandleVisualStart: function(line) {\n    if (typeof line == \"number\") { line = getLine(this, line) }\n    return visualLine(line)\n  },\n\n  lineCount: function() {return this.size},\n  firstLine: function() {return this.first},\n  lastLine: function() {return this.first + this.size - 1},\n\n  clipPos: function(pos) {return clipPos(this, pos)},\n\n  getCursor: function(start) {\n    var range = this.sel.primary(), pos\n    if (start == null || start == \"head\") { pos = range.head }\n    else if (start == \"anchor\") { pos = range.anchor }\n    else if (start == \"end\" || start == \"to\" || start === false) { pos = range.to() }\n    else { pos = range.from() }\n    return pos\n  },\n  listSelections: function() { return this.sel.ranges },\n  somethingSelected: function() {return this.sel.somethingSelected()},\n\n  setCursor: docMethodOp(function(line, ch, options) {\n    setSimpleSelection(this, clipPos(this, typeof line == \"number\" ? Pos(line, ch || 0) : line), null, options)\n  }),\n  setSelection: docMethodOp(function(anchor, head, options) {\n    setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options)\n  }),\n  extendSelection: docMethodOp(function(head, other, options) {\n    extendSelection(this, clipPos(this, head), other && clipPos(this, other), options)\n  }),\n  extendSelections: docMethodOp(function(heads, options) {\n    extendSelections(this, clipPosArray(this, heads), options)\n  }),\n  extendSelectionsBy: docMethodOp(function(f, options) {\n    var heads = map(this.sel.ranges, f)\n    extendSelections(this, clipPosArray(this, heads), options)\n  }),\n  setSelections: docMethodOp(function(ranges, primary, options) {\n    var this$1 = this;\n\n    if (!ranges.length) { return }\n    var out = []\n    for (var i = 0; i < ranges.length; i++)\n      { out[i] = new Range(clipPos(this$1, ranges[i].anchor),\n                         clipPos(this$1, ranges[i].head)) }\n    if (primary == null) { primary = Math.min(ranges.length - 1, this.sel.primIndex) }\n    setSelection(this, normalizeSelection(out, primary), options)\n  }),\n  addSelection: docMethodOp(function(anchor, head, options) {\n    var ranges = this.sel.ranges.slice(0)\n    ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor)))\n    setSelection(this, normalizeSelection(ranges, ranges.length - 1), options)\n  }),\n\n  getSelection: function(lineSep) {\n    var this$1 = this;\n\n    var ranges = this.sel.ranges, lines\n    for (var i = 0; i < ranges.length; i++) {\n      var sel = getBetween(this$1, ranges[i].from(), ranges[i].to())\n      lines = lines ? lines.concat(sel) : sel\n    }\n    if (lineSep === false) { return lines }\n    else { return lines.join(lineSep || this.lineSeparator()) }\n  },\n  getSelections: function(lineSep) {\n    var this$1 = this;\n\n    var parts = [], ranges = this.sel.ranges\n    for (var i = 0; i < ranges.length; i++) {\n      var sel = getBetween(this$1, ranges[i].from(), ranges[i].to())\n      if (lineSep !== false) { sel = sel.join(lineSep || this$1.lineSeparator()) }\n      parts[i] = sel\n    }\n    return parts\n  },\n  replaceSelection: function(code, collapse, origin) {\n    var dup = []\n    for (var i = 0; i < this.sel.ranges.length; i++)\n      { dup[i] = code }\n    this.replaceSelections(dup, collapse, origin || \"+input\")\n  },\n  replaceSelections: docMethodOp(function(code, collapse, origin) {\n    var this$1 = this;\n\n    var changes = [], sel = this.sel\n    for (var i = 0; i < sel.ranges.length; i++) {\n      var range = sel.ranges[i]\n      changes[i] = {from: range.from(), to: range.to(), text: this$1.splitLines(code[i]), origin: origin}\n    }\n    var newSel = collapse && collapse != \"end\" && computeReplacedSel(this, changes, collapse)\n    for (var i$1 = changes.length - 1; i$1 >= 0; i$1--)\n      { makeChange(this$1, changes[i$1]) }\n    if (newSel) { setSelectionReplaceHistory(this, newSel) }\n    else if (this.cm) { ensureCursorVisible(this.cm) }\n  }),\n  undo: docMethodOp(function() {makeChangeFromHistory(this, \"undo\")}),\n  redo: docMethodOp(function() {makeChangeFromHistory(this, \"redo\")}),\n  undoSelection: docMethodOp(function() {makeChangeFromHistory(this, \"undo\", true)}),\n  redoSelection: docMethodOp(function() {makeChangeFromHistory(this, \"redo\", true)}),\n\n  setExtending: function(val) {this.extend = val},\n  getExtending: function() {return this.extend},\n\n  historySize: function() {\n    var hist = this.history, done = 0, undone = 0\n    for (var i = 0; i < hist.done.length; i++) { if (!hist.done[i].ranges) { ++done } }\n    for (var i$1 = 0; i$1 < hist.undone.length; i$1++) { if (!hist.undone[i$1].ranges) { ++undone } }\n    return {undo: done, redo: undone}\n  },\n  clearHistory: function() {this.history = new History(this.history.maxGeneration)},\n\n  markClean: function() {\n    this.cleanGeneration = this.changeGeneration(true)\n  },\n  changeGeneration: function(forceSplit) {\n    if (forceSplit)\n      { this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null }\n    return this.history.generation\n  },\n  isClean: function (gen) {\n    return this.history.generation == (gen || this.cleanGeneration)\n  },\n\n  getHistory: function() {\n    return {done: copyHistoryArray(this.history.done),\n            undone: copyHistoryArray(this.history.undone)}\n  },\n  setHistory: function(histData) {\n    var hist = this.history = new History(this.history.maxGeneration)\n    hist.done = copyHistoryArray(histData.done.slice(0), null, true)\n    hist.undone = copyHistoryArray(histData.undone.slice(0), null, true)\n  },\n\n  setGutterMarker: docMethodOp(function(line, gutterID, value) {\n    return changeLine(this, line, \"gutter\", function (line) {\n      var markers = line.gutterMarkers || (line.gutterMarkers = {})\n      markers[gutterID] = value\n      if (!value && isEmpty(markers)) { line.gutterMarkers = null }\n      return true\n    })\n  }),\n\n  clearGutter: docMethodOp(function(gutterID) {\n    var this$1 = this;\n\n    this.iter(function (line) {\n      if (line.gutterMarkers && line.gutterMarkers[gutterID]) {\n        changeLine(this$1, line, \"gutter\", function () {\n          line.gutterMarkers[gutterID] = null\n          if (isEmpty(line.gutterMarkers)) { line.gutterMarkers = null }\n          return true\n        })\n      }\n    })\n  }),\n\n  lineInfo: function(line) {\n    var n\n    if (typeof line == \"number\") {\n      if (!isLine(this, line)) { return null }\n      n = line\n      line = getLine(this, line)\n      if (!line) { return null }\n    } else {\n      n = lineNo(line)\n      if (n == null) { return null }\n    }\n    return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,\n            textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,\n            widgets: line.widgets}\n  },\n\n  addLineClass: docMethodOp(function(handle, where, cls) {\n    return changeLine(this, handle, where == \"gutter\" ? \"gutter\" : \"class\", function (line) {\n      var prop = where == \"text\" ? \"textClass\"\n               : where == \"background\" ? \"bgClass\"\n               : where == \"gutter\" ? \"gutterClass\" : \"wrapClass\"\n      if (!line[prop]) { line[prop] = cls }\n      else if (classTest(cls).test(line[prop])) { return false }\n      else { line[prop] += \" \" + cls }\n      return true\n    })\n  }),\n  removeLineClass: docMethodOp(function(handle, where, cls) {\n    return changeLine(this, handle, where == \"gutter\" ? \"gutter\" : \"class\", function (line) {\n      var prop = where == \"text\" ? \"textClass\"\n               : where == \"background\" ? \"bgClass\"\n               : where == \"gutter\" ? \"gutterClass\" : \"wrapClass\"\n      var cur = line[prop]\n      if (!cur) { return false }\n      else if (cls == null) { line[prop] = null }\n      else {\n        var found = cur.match(classTest(cls))\n        if (!found) { return false }\n        var end = found.index + found[0].length\n        line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? \"\" : \" \") + cur.slice(end) || null\n      }\n      return true\n    })\n  }),\n\n  addLineWidget: docMethodOp(function(handle, node, options) {\n    return addLineWidget(this, handle, node, options)\n  }),\n  removeLineWidget: function(widget) { widget.clear() },\n\n  markText: function(from, to, options) {\n    return markText(this, clipPos(this, from), clipPos(this, to), options, options && options.type || \"range\")\n  },\n  setBookmark: function(pos, options) {\n    var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),\n                    insertLeft: options && options.insertLeft,\n                    clearWhenEmpty: false, shared: options && options.shared,\n                    handleMouseEvents: options && options.handleMouseEvents}\n    pos = clipPos(this, pos)\n    return markText(this, pos, pos, realOpts, \"bookmark\")\n  },\n  findMarksAt: function(pos) {\n    pos = clipPos(this, pos)\n    var markers = [], spans = getLine(this, pos.line).markedSpans\n    if (spans) { for (var i = 0; i < spans.length; ++i) {\n      var span = spans[i]\n      if ((span.from == null || span.from <= pos.ch) &&\n          (span.to == null || span.to >= pos.ch))\n        { markers.push(span.marker.parent || span.marker) }\n    } }\n    return markers\n  },\n  findMarks: function(from, to, filter) {\n    from = clipPos(this, from); to = clipPos(this, to)\n    var found = [], lineNo = from.line\n    this.iter(from.line, to.line + 1, function (line) {\n      var spans = line.markedSpans\n      if (spans) { for (var i = 0; i < spans.length; i++) {\n        var span = spans[i]\n        if (!(span.to != null && lineNo == from.line && from.ch >= span.to ||\n              span.from == null && lineNo != from.line ||\n              span.from != null && lineNo == to.line && span.from >= to.ch) &&\n            (!filter || filter(span.marker)))\n          { found.push(span.marker.parent || span.marker) }\n      } }\n      ++lineNo\n    })\n    return found\n  },\n  getAllMarks: function() {\n    var markers = []\n    this.iter(function (line) {\n      var sps = line.markedSpans\n      if (sps) { for (var i = 0; i < sps.length; ++i)\n        { if (sps[i].from != null) { markers.push(sps[i].marker) } } }\n    })\n    return markers\n  },\n\n  posFromIndex: function(off) {\n    var ch, lineNo = this.first, sepSize = this.lineSeparator().length\n    this.iter(function (line) {\n      var sz = line.text.length + sepSize\n      if (sz > off) { ch = off; return true }\n      off -= sz\n      ++lineNo\n    })\n    return clipPos(this, Pos(lineNo, ch))\n  },\n  indexFromPos: function (coords) {\n    coords = clipPos(this, coords)\n    var index = coords.ch\n    if (coords.line < this.first || coords.ch < 0) { return 0 }\n    var sepSize = this.lineSeparator().length\n    this.iter(this.first, coords.line, function (line) { // iter aborts when callback returns a truthy value\n      index += line.text.length + sepSize\n    })\n    return index\n  },\n\n  copy: function(copyHistory) {\n    var doc = new Doc(getLines(this, this.first, this.first + this.size),\n                      this.modeOption, this.first, this.lineSep, this.direction)\n    doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft\n    doc.sel = this.sel\n    doc.extend = false\n    if (copyHistory) {\n      doc.history.undoDepth = this.history.undoDepth\n      doc.setHistory(this.getHistory())\n    }\n    return doc\n  },\n\n  linkedDoc: function(options) {\n    if (!options) { options = {} }\n    var from = this.first, to = this.first + this.size\n    if (options.from != null && options.from > from) { from = options.from }\n    if (options.to != null && options.to < to) { to = options.to }\n    var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep, this.direction)\n    if (options.sharedHist) { copy.history = this.history\n    ; }(this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist})\n    copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}]\n    copySharedMarkers(copy, findSharedMarkers(this))\n    return copy\n  },\n  unlinkDoc: function(other) {\n    var this$1 = this;\n\n    if (other instanceof CodeMirror) { other = other.doc }\n    if (this.linked) { for (var i = 0; i < this.linked.length; ++i) {\n      var link = this$1.linked[i]\n      if (link.doc != other) { continue }\n      this$1.linked.splice(i, 1)\n      other.unlinkDoc(this$1)\n      detachSharedMarkers(findSharedMarkers(this$1))\n      break\n    } }\n    // If the histories were shared, split them again\n    if (other.history == this.history) {\n      var splitIds = [other.id]\n      linkedDocs(other, function (doc) { return splitIds.push(doc.id); }, true)\n      other.history = new History(null)\n      other.history.done = copyHistoryArray(this.history.done, splitIds)\n      other.history.undone = copyHistoryArray(this.history.undone, splitIds)\n    }\n  },\n  iterLinkedDocs: function(f) {linkedDocs(this, f)},\n\n  getMode: function() {return this.mode},\n  getEditor: function() {return this.cm},\n\n  splitLines: function(str) {\n    if (this.lineSep) { return str.split(this.lineSep) }\n    return splitLinesAuto(str)\n  },\n  lineSeparator: function() { return this.lineSep || \"\\n\" },\n\n  setDirection: docMethodOp(function (dir) {\n    if (dir != \"rtl\") { dir = \"ltr\" }\n    if (dir == this.direction) { return }\n    this.direction = dir\n    this.iter(function (line) { return line.order = null; })\n    if (this.cm) { directionChanged(this.cm) }\n  })\n})\n\n// Public alias.\nDoc.prototype.eachLine = Doc.prototype.iter\n\n// Kludge to work around strange IE behavior where it'll sometimes\n// re-fire a series of drag-related events right after the drop (#1551)\nvar lastDrop = 0\n\nfunction onDrop(e) {\n  var cm = this\n  clearDragCursor(cm)\n  if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))\n    { return }\n  e_preventDefault(e)\n  if (ie) { lastDrop = +new Date }\n  var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files\n  if (!pos || cm.isReadOnly()) { return }\n  // Might be a file drop, in which case we simply extract the text\n  // and insert it.\n  if (files && files.length && window.FileReader && window.File) {\n    var n = files.length, text = Array(n), read = 0\n    var loadFile = function (file, i) {\n      if (cm.options.allowDropFileTypes &&\n          indexOf(cm.options.allowDropFileTypes, file.type) == -1)\n        { return }\n\n      var reader = new FileReader\n      reader.onload = operation(cm, function () {\n        var content = reader.result\n        if (/[\\x00-\\x08\\x0e-\\x1f]{2}/.test(content)) { content = \"\" }\n        text[i] = content\n        if (++read == n) {\n          pos = clipPos(cm.doc, pos)\n          var change = {from: pos, to: pos,\n                        text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())),\n                        origin: \"paste\"}\n          makeChange(cm.doc, change)\n          setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)))\n        }\n      })\n      reader.readAsText(file)\n    }\n    for (var i = 0; i < n; ++i) { loadFile(files[i], i) }\n  } else { // Normal drop\n    // Don't do a replace if the drop happened inside of the selected text.\n    if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) {\n      cm.state.draggingText(e)\n      // Ensure the editor is re-focused\n      setTimeout(function () { return cm.display.input.focus(); }, 20)\n      return\n    }\n    try {\n      var text$1 = e.dataTransfer.getData(\"Text\")\n      if (text$1) {\n        var selected\n        if (cm.state.draggingText && !cm.state.draggingText.copy)\n          { selected = cm.listSelections() }\n        setSelectionNoUndo(cm.doc, simpleSelection(pos, pos))\n        if (selected) { for (var i$1 = 0; i$1 < selected.length; ++i$1)\n          { replaceRange(cm.doc, \"\", selected[i$1].anchor, selected[i$1].head, \"drag\") } }\n        cm.replaceSelection(text$1, \"around\", \"paste\")\n        cm.display.input.focus()\n      }\n    }\n    catch(e){}\n  }\n}\n\nfunction onDragStart(cm, e) {\n  if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return }\n  if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) { return }\n\n  e.dataTransfer.setData(\"Text\", cm.getSelection())\n  e.dataTransfer.effectAllowed = \"copyMove\"\n\n  // Use dummy image instead of default browsers image.\n  // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.\n  if (e.dataTransfer.setDragImage && !safari) {\n    var img = elt(\"img\", null, null, \"position: fixed; left: 0; top: 0;\")\n    img.src = \"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\"\n    if (presto) {\n      img.width = img.height = 1\n      cm.display.wrapper.appendChild(img)\n      // Force a relayout, or Opera won't use our image for some obscure reason\n      img._top = img.offsetTop\n    }\n    e.dataTransfer.setDragImage(img, 0, 0)\n    if (presto) { img.parentNode.removeChild(img) }\n  }\n}\n\nfunction onDragOver(cm, e) {\n  var pos = posFromMouse(cm, e)\n  if (!pos) { return }\n  var frag = document.createDocumentFragment()\n  drawSelectionCursor(cm, pos, frag)\n  if (!cm.display.dragCursor) {\n    cm.display.dragCursor = elt(\"div\", null, \"CodeMirror-cursors CodeMirror-dragcursors\")\n    cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv)\n  }\n  removeChildrenAndAdd(cm.display.dragCursor, frag)\n}\n\nfunction clearDragCursor(cm) {\n  if (cm.display.dragCursor) {\n    cm.display.lineSpace.removeChild(cm.display.dragCursor)\n    cm.display.dragCursor = null\n  }\n}\n\n// These must be handled carefully, because naively registering a\n// handler for each editor will cause the editors to never be\n// garbage collected.\n\nfunction forEachCodeMirror(f) {\n  if (!document.getElementsByClassName) { return }\n  var byClass = document.getElementsByClassName(\"CodeMirror\")\n  for (var i = 0; i < byClass.length; i++) {\n    var cm = byClass[i].CodeMirror\n    if (cm) { f(cm) }\n  }\n}\n\nvar globalsRegistered = false\nfunction ensureGlobalHandlers() {\n  if (globalsRegistered) { return }\n  registerGlobalHandlers()\n  globalsRegistered = true\n}\nfunction registerGlobalHandlers() {\n  // When the window resizes, we need to refresh active editors.\n  var resizeTimer\n  on(window, \"resize\", function () {\n    if (resizeTimer == null) { resizeTimer = setTimeout(function () {\n      resizeTimer = null\n      forEachCodeMirror(onResize)\n    }, 100) }\n  })\n  // When the window loses focus, we want to show the editor as blurred\n  on(window, \"blur\", function () { return forEachCodeMirror(onBlur); })\n}\n// Called when the window resizes\nfunction onResize(cm) {\n  var d = cm.display\n  if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth)\n    { return }\n  // Might be a text scaling operation, clear size caches.\n  d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null\n  d.scrollbarsClipped = false\n  cm.setSize()\n}\n\nvar keyNames = {\n  3: \"Enter\", 8: \"Backspace\", 9: \"Tab\", 13: \"Enter\", 16: \"Shift\", 17: \"Ctrl\", 18: \"Alt\",\n  19: \"Pause\", 20: \"CapsLock\", 27: \"Esc\", 32: \"Space\", 33: \"PageUp\", 34: \"PageDown\", 35: \"End\",\n  36: \"Home\", 37: \"Left\", 38: \"Up\", 39: \"Right\", 40: \"Down\", 44: \"PrintScrn\", 45: \"Insert\",\n  46: \"Delete\", 59: \";\", 61: \"=\", 91: \"Mod\", 92: \"Mod\", 93: \"Mod\",\n  106: \"*\", 107: \"=\", 109: \"-\", 110: \".\", 111: \"/\", 127: \"Delete\",\n  173: \"-\", 186: \";\", 187: \"=\", 188: \",\", 189: \"-\", 190: \".\", 191: \"/\", 192: \"`\", 219: \"[\", 220: \"\\\\\",\n  221: \"]\", 222: \"'\", 63232: \"Up\", 63233: \"Down\", 63234: \"Left\", 63235: \"Right\", 63272: \"Delete\",\n  63273: \"Home\", 63275: \"End\", 63276: \"PageUp\", 63277: \"PageDown\", 63302: \"Insert\"\n}\n\n// Number keys\nfor (var i = 0; i < 10; i++) { keyNames[i + 48] = keyNames[i + 96] = String(i) }\n// Alphabetic keys\nfor (var i$1 = 65; i$1 <= 90; i$1++) { keyNames[i$1] = String.fromCharCode(i$1) }\n// Function keys\nfor (var i$2 = 1; i$2 <= 12; i$2++) { keyNames[i$2 + 111] = keyNames[i$2 + 63235] = \"F\" + i$2 }\n\nvar keyMap = {}\n\nkeyMap.basic = {\n  \"Left\": \"goCharLeft\", \"Right\": \"goCharRight\", \"Up\": \"goLineUp\", \"Down\": \"goLineDown\",\n  \"End\": \"goLineEnd\", \"Home\": \"goLineStartSmart\", \"PageUp\": \"goPageUp\", \"PageDown\": \"goPageDown\",\n  \"Delete\": \"delCharAfter\", \"Backspace\": \"delCharBefore\", \"Shift-Backspace\": \"delCharBefore\",\n  \"Tab\": \"defaultTab\", \"Shift-Tab\": \"indentAuto\",\n  \"Enter\": \"newlineAndIndent\", \"Insert\": \"toggleOverwrite\",\n  \"Esc\": \"singleSelection\"\n}\n// Note that the save and find-related commands aren't defined by\n// default. User code or addons can define them. Unknown commands\n// are simply ignored.\nkeyMap.pcDefault = {\n  \"Ctrl-A\": \"selectAll\", \"Ctrl-D\": \"deleteLine\", \"Ctrl-Z\": \"undo\", \"Shift-Ctrl-Z\": \"redo\", \"Ctrl-Y\": \"redo\",\n  \"Ctrl-Home\": \"goDocStart\", \"Ctrl-End\": \"goDocEnd\", \"Ctrl-Up\": \"goLineUp\", \"Ctrl-Down\": \"goLineDown\",\n  \"Ctrl-Left\": \"goGroupLeft\", \"Ctrl-Right\": \"goGroupRight\", \"Alt-Left\": \"goLineStart\", \"Alt-Right\": \"goLineEnd\",\n  \"Ctrl-Backspace\": \"delGroupBefore\", \"Ctrl-Delete\": \"delGroupAfter\", \"Ctrl-S\": \"save\", \"Ctrl-F\": \"find\",\n  \"Ctrl-G\": \"findNext\", \"Shift-Ctrl-G\": \"findPrev\", \"Shift-Ctrl-F\": \"replace\", \"Shift-Ctrl-R\": \"replaceAll\",\n  \"Ctrl-[\": \"indentLess\", \"Ctrl-]\": \"indentMore\",\n  \"Ctrl-U\": \"undoSelection\", \"Shift-Ctrl-U\": \"redoSelection\", \"Alt-U\": \"redoSelection\",\n  fallthrough: \"basic\"\n}\n// Very basic readline/emacs-style bindings, which are standard on Mac.\nkeyMap.emacsy = {\n  \"Ctrl-F\": \"goCharRight\", \"Ctrl-B\": \"goCharLeft\", \"Ctrl-P\": \"goLineUp\", \"Ctrl-N\": \"goLineDown\",\n  \"Alt-F\": \"goWordRight\", \"Alt-B\": \"goWordLeft\", \"Ctrl-A\": \"goLineStart\", \"Ctrl-E\": \"goLineEnd\",\n  \"Ctrl-V\": \"goPageDown\", \"Shift-Ctrl-V\": \"goPageUp\", \"Ctrl-D\": \"delCharAfter\", \"Ctrl-H\": \"delCharBefore\",\n  \"Alt-D\": \"delWordAfter\", \"Alt-Backspace\": \"delWordBefore\", \"Ctrl-K\": \"killLine\", \"Ctrl-T\": \"transposeChars\",\n  \"Ctrl-O\": \"openLine\"\n}\nkeyMap.macDefault = {\n  \"Cmd-A\": \"selectAll\", \"Cmd-D\": \"deleteLine\", \"Cmd-Z\": \"undo\", \"Shift-Cmd-Z\": \"redo\", \"Cmd-Y\": \"redo\",\n  \"Cmd-Home\": \"goDocStart\", \"Cmd-Up\": \"goDocStart\", \"Cmd-End\": \"goDocEnd\", \"Cmd-Down\": \"goDocEnd\", \"Alt-Left\": \"goGroupLeft\",\n  \"Alt-Right\": \"goGroupRight\", \"Cmd-Left\": \"goLineLeft\", \"Cmd-Right\": \"goLineRight\", \"Alt-Backspace\": \"delGroupBefore\",\n  \"Ctrl-Alt-Backspace\": \"delGroupAfter\", \"Alt-Delete\": \"delGroupAfter\", \"Cmd-S\": \"save\", \"Cmd-F\": \"find\",\n  \"Cmd-G\": \"findNext\", \"Shift-Cmd-G\": \"findPrev\", \"Cmd-Alt-F\": \"replace\", \"Shift-Cmd-Alt-F\": \"replaceAll\",\n  \"Cmd-[\": \"indentLess\", \"Cmd-]\": \"indentMore\", \"Cmd-Backspace\": \"delWrappedLineLeft\", \"Cmd-Delete\": \"delWrappedLineRight\",\n  \"Cmd-U\": \"undoSelection\", \"Shift-Cmd-U\": \"redoSelection\", \"Ctrl-Up\": \"goDocStart\", \"Ctrl-Down\": \"goDocEnd\",\n  fallthrough: [\"basic\", \"emacsy\"]\n}\nkeyMap[\"default\"] = mac ? keyMap.macDefault : keyMap.pcDefault\n\n// KEYMAP DISPATCH\n\nfunction normalizeKeyName(name) {\n  var parts = name.split(/-(?!$)/)\n  name = parts[parts.length - 1]\n  var alt, ctrl, shift, cmd\n  for (var i = 0; i < parts.length - 1; i++) {\n    var mod = parts[i]\n    if (/^(cmd|meta|m)$/i.test(mod)) { cmd = true }\n    else if (/^a(lt)?$/i.test(mod)) { alt = true }\n    else if (/^(c|ctrl|control)$/i.test(mod)) { ctrl = true }\n    else if (/^s(hift)?$/i.test(mod)) { shift = true }\n    else { throw new Error(\"Unrecognized modifier name: \" + mod) }\n  }\n  if (alt) { name = \"Alt-\" + name }\n  if (ctrl) { name = \"Ctrl-\" + name }\n  if (cmd) { name = \"Cmd-\" + name }\n  if (shift) { name = \"Shift-\" + name }\n  return name\n}\n\n// This is a kludge to keep keymaps mostly working as raw objects\n// (backwards compatibility) while at the same time support features\n// like normalization and multi-stroke key bindings. It compiles a\n// new normalized keymap, and then updates the old object to reflect\n// this.\nfunction normalizeKeyMap(keymap) {\n  var copy = {}\n  for (var keyname in keymap) { if (keymap.hasOwnProperty(keyname)) {\n    var value = keymap[keyname]\n    if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) { continue }\n    if (value == \"...\") { delete keymap[keyname]; continue }\n\n    var keys = map(keyname.split(\" \"), normalizeKeyName)\n    for (var i = 0; i < keys.length; i++) {\n      var val = (void 0), name = (void 0)\n      if (i == keys.length - 1) {\n        name = keys.join(\" \")\n        val = value\n      } else {\n        name = keys.slice(0, i + 1).join(\" \")\n        val = \"...\"\n      }\n      var prev = copy[name]\n      if (!prev) { copy[name] = val }\n      else if (prev != val) { throw new Error(\"Inconsistent bindings for \" + name) }\n    }\n    delete keymap[keyname]\n  } }\n  for (var prop in copy) { keymap[prop] = copy[prop] }\n  return keymap\n}\n\nfunction lookupKey(key, map, handle, context) {\n  map = getKeyMap(map)\n  var found = map.call ? map.call(key, context) : map[key]\n  if (found === false) { return \"nothing\" }\n  if (found === \"...\") { return \"multi\" }\n  if (found != null && handle(found)) { return \"handled\" }\n\n  if (map.fallthrough) {\n    if (Object.prototype.toString.call(map.fallthrough) != \"[object Array]\")\n      { return lookupKey(key, map.fallthrough, handle, context) }\n    for (var i = 0; i < map.fallthrough.length; i++) {\n      var result = lookupKey(key, map.fallthrough[i], handle, context)\n      if (result) { return result }\n    }\n  }\n}\n\n// Modifier key presses don't count as 'real' key presses for the\n// purpose of keymap fallthrough.\nfunction isModifierKey(value) {\n  var name = typeof value == \"string\" ? value : keyNames[value.keyCode]\n  return name == \"Ctrl\" || name == \"Alt\" || name == \"Shift\" || name == \"Mod\"\n}\n\nfunction addModifierNames(name, event, noShift) {\n  var base = name\n  if (event.altKey && base != \"Alt\") { name = \"Alt-\" + name }\n  if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != \"Ctrl\") { name = \"Ctrl-\" + name }\n  if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != \"Cmd\") { name = \"Cmd-\" + name }\n  if (!noShift && event.shiftKey && base != \"Shift\") { name = \"Shift-\" + name }\n  return name\n}\n\n// Look up the name of a key as indicated by an event object.\nfunction keyName(event, noShift) {\n  if (presto && event.keyCode == 34 && event[\"char\"]) { return false }\n  var name = keyNames[event.keyCode]\n  if (name == null || event.altGraphKey) { return false }\n  return addModifierNames(name, event, noShift)\n}\n\nfunction getKeyMap(val) {\n  return typeof val == \"string\" ? keyMap[val] : val\n}\n\n// Helper for deleting text near the selection(s), used to implement\n// backspace, delete, and similar functionality.\nfunction deleteNearSelection(cm, compute) {\n  var ranges = cm.doc.sel.ranges, kill = []\n  // Build up a set of ranges to kill first, merging overlapping\n  // ranges.\n  for (var i = 0; i < ranges.length; i++) {\n    var toKill = compute(ranges[i])\n    while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) {\n      var replaced = kill.pop()\n      if (cmp(replaced.from, toKill.from) < 0) {\n        toKill.from = replaced.from\n        break\n      }\n    }\n    kill.push(toKill)\n  }\n  // Next, remove those actual ranges.\n  runInOp(cm, function () {\n    for (var i = kill.length - 1; i >= 0; i--)\n      { replaceRange(cm.doc, \"\", kill[i].from, kill[i].to, \"+delete\") }\n    ensureCursorVisible(cm)\n  })\n}\n\n// Commands are parameter-less actions that can be performed on an\n// editor, mostly used for keybindings.\nvar commands = {\n  selectAll: selectAll,\n  singleSelection: function (cm) { return cm.setSelection(cm.getCursor(\"anchor\"), cm.getCursor(\"head\"), sel_dontScroll); },\n  killLine: function (cm) { return deleteNearSelection(cm, function (range) {\n    if (range.empty()) {\n      var len = getLine(cm.doc, range.head.line).text.length\n      if (range.head.ch == len && range.head.line < cm.lastLine())\n        { return {from: range.head, to: Pos(range.head.line + 1, 0)} }\n      else\n        { return {from: range.head, to: Pos(range.head.line, len)} }\n    } else {\n      return {from: range.from(), to: range.to()}\n    }\n  }); },\n  deleteLine: function (cm) { return deleteNearSelection(cm, function (range) { return ({\n    from: Pos(range.from().line, 0),\n    to: clipPos(cm.doc, Pos(range.to().line + 1, 0))\n  }); }); },\n  delLineLeft: function (cm) { return deleteNearSelection(cm, function (range) { return ({\n    from: Pos(range.from().line, 0), to: range.from()\n  }); }); },\n  delWrappedLineLeft: function (cm) { return deleteNearSelection(cm, function (range) {\n    var top = cm.charCoords(range.head, \"div\").top + 5\n    var leftPos = cm.coordsChar({left: 0, top: top}, \"div\")\n    return {from: leftPos, to: range.from()}\n  }); },\n  delWrappedLineRight: function (cm) { return deleteNearSelection(cm, function (range) {\n    var top = cm.charCoords(range.head, \"div\").top + 5\n    var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, \"div\")\n    return {from: range.from(), to: rightPos }\n  }); },\n  undo: function (cm) { return cm.undo(); },\n  redo: function (cm) { return cm.redo(); },\n  undoSelection: function (cm) { return cm.undoSelection(); },\n  redoSelection: function (cm) { return cm.redoSelection(); },\n  goDocStart: function (cm) { return cm.extendSelection(Pos(cm.firstLine(), 0)); },\n  goDocEnd: function (cm) { return cm.extendSelection(Pos(cm.lastLine())); },\n  goLineStart: function (cm) { return cm.extendSelectionsBy(function (range) { return lineStart(cm, range.head.line); },\n    {origin: \"+move\", bias: 1}\n  ); },\n  goLineStartSmart: function (cm) { return cm.extendSelectionsBy(function (range) { return lineStartSmart(cm, range.head); },\n    {origin: \"+move\", bias: 1}\n  ); },\n  goLineEnd: function (cm) { return cm.extendSelectionsBy(function (range) { return lineEnd(cm, range.head.line); },\n    {origin: \"+move\", bias: -1}\n  ); },\n  goLineRight: function (cm) { return cm.extendSelectionsBy(function (range) {\n    var top = cm.cursorCoords(range.head, \"div\").top + 5\n    return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, \"div\")\n  }, sel_move); },\n  goLineLeft: function (cm) { return cm.extendSelectionsBy(function (range) {\n    var top = cm.cursorCoords(range.head, \"div\").top + 5\n    return cm.coordsChar({left: 0, top: top}, \"div\")\n  }, sel_move); },\n  goLineLeftSmart: function (cm) { return cm.extendSelectionsBy(function (range) {\n    var top = cm.cursorCoords(range.head, \"div\").top + 5\n    var pos = cm.coordsChar({left: 0, top: top}, \"div\")\n    if (pos.ch < cm.getLine(pos.line).search(/\\S/)) { return lineStartSmart(cm, range.head) }\n    return pos\n  }, sel_move); },\n  goLineUp: function (cm) { return cm.moveV(-1, \"line\"); },\n  goLineDown: function (cm) { return cm.moveV(1, \"line\"); },\n  goPageUp: function (cm) { return cm.moveV(-1, \"page\"); },\n  goPageDown: function (cm) { return cm.moveV(1, \"page\"); },\n  goCharLeft: function (cm) { return cm.moveH(-1, \"char\"); },\n  goCharRight: function (cm) { return cm.moveH(1, \"char\"); },\n  goColumnLeft: function (cm) { return cm.moveH(-1, \"column\"); },\n  goColumnRight: function (cm) { return cm.moveH(1, \"column\"); },\n  goWordLeft: function (cm) { return cm.moveH(-1, \"word\"); },\n  goGroupRight: function (cm) { return cm.moveH(1, \"group\"); },\n  goGroupLeft: function (cm) { return cm.moveH(-1, \"group\"); },\n  goWordRight: function (cm) { return cm.moveH(1, \"word\"); },\n  delCharBefore: function (cm) { return cm.deleteH(-1, \"char\"); },\n  delCharAfter: function (cm) { return cm.deleteH(1, \"char\"); },\n  delWordBefore: function (cm) { return cm.deleteH(-1, \"word\"); },\n  delWordAfter: function (cm) { return cm.deleteH(1, \"word\"); },\n  delGroupBefore: function (cm) { return cm.deleteH(-1, \"group\"); },\n  delGroupAfter: function (cm) { return cm.deleteH(1, \"group\"); },\n  indentAuto: function (cm) { return cm.indentSelection(\"smart\"); },\n  indentMore: function (cm) { return cm.indentSelection(\"add\"); },\n  indentLess: function (cm) { return cm.indentSelection(\"subtract\"); },\n  insertTab: function (cm) { return cm.replaceSelection(\"\\t\"); },\n  insertSoftTab: function (cm) {\n    var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize\n    for (var i = 0; i < ranges.length; i++) {\n      var pos = ranges[i].from()\n      var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize)\n      spaces.push(spaceStr(tabSize - col % tabSize))\n    }\n    cm.replaceSelections(spaces)\n  },\n  defaultTab: function (cm) {\n    if (cm.somethingSelected()) { cm.indentSelection(\"add\") }\n    else { cm.execCommand(\"insertTab\") }\n  },\n  // Swap the two chars left and right of each selection's head.\n  // Move cursor behind the two swapped characters afterwards.\n  //\n  // Doesn't consider line feeds a character.\n  // Doesn't scan more than one line above to find a character.\n  // Doesn't do anything on an empty line.\n  // Doesn't do anything with non-empty selections.\n  transposeChars: function (cm) { return runInOp(cm, function () {\n    var ranges = cm.listSelections(), newSel = []\n    for (var i = 0; i < ranges.length; i++) {\n      if (!ranges[i].empty()) { continue }\n      var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text\n      if (line) {\n        if (cur.ch == line.length) { cur = new Pos(cur.line, cur.ch - 1) }\n        if (cur.ch > 0) {\n          cur = new Pos(cur.line, cur.ch + 1)\n          cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2),\n                          Pos(cur.line, cur.ch - 2), cur, \"+transpose\")\n        } else if (cur.line > cm.doc.first) {\n          var prev = getLine(cm.doc, cur.line - 1).text\n          if (prev) {\n            cur = new Pos(cur.line, 1)\n            cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() +\n                            prev.charAt(prev.length - 1),\n                            Pos(cur.line - 1, prev.length - 1), cur, \"+transpose\")\n          }\n        }\n      }\n      newSel.push(new Range(cur, cur))\n    }\n    cm.setSelections(newSel)\n  }); },\n  newlineAndIndent: function (cm) { return runInOp(cm, function () {\n    var sels = cm.listSelections()\n    for (var i = sels.length - 1; i >= 0; i--)\n      { cm.replaceRange(cm.doc.lineSeparator(), sels[i].anchor, sels[i].head, \"+input\") }\n    sels = cm.listSelections()\n    for (var i$1 = 0; i$1 < sels.length; i$1++)\n      { cm.indentLine(sels[i$1].from().line, null, true) }\n    ensureCursorVisible(cm)\n  }); },\n  openLine: function (cm) { return cm.replaceSelection(\"\\n\", \"start\"); },\n  toggleOverwrite: function (cm) { return cm.toggleOverwrite(); }\n}\n\n\nfunction lineStart(cm, lineN) {\n  var line = getLine(cm.doc, lineN)\n  var visual = visualLine(line)\n  if (visual != line) { lineN = lineNo(visual) }\n  return endOfLine(true, cm, visual, lineN, 1)\n}\nfunction lineEnd(cm, lineN) {\n  var line = getLine(cm.doc, lineN)\n  var visual = visualLineEnd(line)\n  if (visual != line) { lineN = lineNo(visual) }\n  return endOfLine(true, cm, line, lineN, -1)\n}\nfunction lineStartSmart(cm, pos) {\n  var start = lineStart(cm, pos.line)\n  var line = getLine(cm.doc, start.line)\n  var order = getOrder(line, cm.doc.direction)\n  if (!order || order[0].level == 0) {\n    var firstNonWS = Math.max(0, line.text.search(/\\S/))\n    var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch\n    return Pos(start.line, inWS ? 0 : firstNonWS, start.sticky)\n  }\n  return start\n}\n\n// Run a handler that was bound to a key.\nfunction doHandleBinding(cm, bound, dropShift) {\n  if (typeof bound == \"string\") {\n    bound = commands[bound]\n    if (!bound) { return false }\n  }\n  // Ensure previous input has been read, so that the handler sees a\n  // consistent view of the document\n  cm.display.input.ensurePolled()\n  var prevShift = cm.display.shift, done = false\n  try {\n    if (cm.isReadOnly()) { cm.state.suppressEdits = true }\n    if (dropShift) { cm.display.shift = false }\n    done = bound(cm) != Pass\n  } finally {\n    cm.display.shift = prevShift\n    cm.state.suppressEdits = false\n  }\n  return done\n}\n\nfunction lookupKeyForEditor(cm, name, handle) {\n  for (var i = 0; i < cm.state.keyMaps.length; i++) {\n    var result = lookupKey(name, cm.state.keyMaps[i], handle, cm)\n    if (result) { return result }\n  }\n  return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm))\n    || lookupKey(name, cm.options.keyMap, handle, cm)\n}\n\n// Note that, despite the name, this function is also used to check\n// for bound mouse clicks.\n\nvar stopSeq = new Delayed\nfunction dispatchKey(cm, name, e, handle) {\n  var seq = cm.state.keySeq\n  if (seq) {\n    if (isModifierKey(name)) { return \"handled\" }\n    stopSeq.set(50, function () {\n      if (cm.state.keySeq == seq) {\n        cm.state.keySeq = null\n        cm.display.input.reset()\n      }\n    })\n    name = seq + \" \" + name\n  }\n  var result = lookupKeyForEditor(cm, name, handle)\n\n  if (result == \"multi\")\n    { cm.state.keySeq = name }\n  if (result == \"handled\")\n    { signalLater(cm, \"keyHandled\", cm, name, e) }\n\n  if (result == \"handled\" || result == \"multi\") {\n    e_preventDefault(e)\n    restartBlink(cm)\n  }\n\n  if (seq && !result && /\\'$/.test(name)) {\n    e_preventDefault(e)\n    return true\n  }\n  return !!result\n}\n\n// Handle a key from the keydown event.\nfunction handleKeyBinding(cm, e) {\n  var name = keyName(e, true)\n  if (!name) { return false }\n\n  if (e.shiftKey && !cm.state.keySeq) {\n    // First try to resolve full name (including 'Shift-'). Failing\n    // that, see if there is a cursor-motion command (starting with\n    // 'go') bound to the keyname without 'Shift-'.\n    return dispatchKey(cm, \"Shift-\" + name, e, function (b) { return doHandleBinding(cm, b, true); })\n        || dispatchKey(cm, name, e, function (b) {\n             if (typeof b == \"string\" ? /^go[A-Z]/.test(b) : b.motion)\n               { return doHandleBinding(cm, b) }\n           })\n  } else {\n    return dispatchKey(cm, name, e, function (b) { return doHandleBinding(cm, b); })\n  }\n}\n\n// Handle a key from the keypress event\nfunction handleCharBinding(cm, e, ch) {\n  return dispatchKey(cm, \"'\" + ch + \"'\", e, function (b) { return doHandleBinding(cm, b, true); })\n}\n\nvar lastStoppedKey = null\nfunction onKeyDown(e) {\n  var cm = this\n  cm.curOp.focus = activeElt()\n  if (signalDOMEvent(cm, e)) { return }\n  // IE does strange things with escape.\n  if (ie && ie_version < 11 && e.keyCode == 27) { e.returnValue = false }\n  var code = e.keyCode\n  cm.display.shift = code == 16 || e.shiftKey\n  var handled = handleKeyBinding(cm, e)\n  if (presto) {\n    lastStoppedKey = handled ? code : null\n    // Opera has no cut event... we try to at least catch the key combo\n    if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))\n      { cm.replaceSelection(\"\", null, \"cut\") }\n  }\n\n  // Turn mouse into crosshair when Alt is held on Mac.\n  if (code == 18 && !/\\bCodeMirror-crosshair\\b/.test(cm.display.lineDiv.className))\n    { showCrossHair(cm) }\n}\n\nfunction showCrossHair(cm) {\n  var lineDiv = cm.display.lineDiv\n  addClass(lineDiv, \"CodeMirror-crosshair\")\n\n  function up(e) {\n    if (e.keyCode == 18 || !e.altKey) {\n      rmClass(lineDiv, \"CodeMirror-crosshair\")\n      off(document, \"keyup\", up)\n      off(document, \"mouseover\", up)\n    }\n  }\n  on(document, \"keyup\", up)\n  on(document, \"mouseover\", up)\n}\n\nfunction onKeyUp(e) {\n  if (e.keyCode == 16) { this.doc.sel.shift = false }\n  signalDOMEvent(this, e)\n}\n\nfunction onKeyPress(e) {\n  var cm = this\n  if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) { return }\n  var keyCode = e.keyCode, charCode = e.charCode\n  if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return}\n  if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) { return }\n  var ch = String.fromCharCode(charCode == null ? keyCode : charCode)\n  // Some browsers fire keypress events for backspace\n  if (ch == \"\\x08\") { return }\n  if (handleCharBinding(cm, e, ch)) { return }\n  cm.display.input.onKeyPress(e)\n}\n\nvar DOUBLECLICK_DELAY = 400\n\nvar PastClick = function(time, pos, button) {\n  this.time = time\n  this.pos = pos\n  this.button = button\n};\n\nPastClick.prototype.compare = function (time, pos, button) {\n  return this.time + DOUBLECLICK_DELAY > time &&\n    cmp(pos, this.pos) == 0 && button == this.button\n};\n\nvar lastClick;\nvar lastDoubleClick;\nfunction clickRepeat(pos, button) {\n  var now = +new Date\n  if (lastDoubleClick && lastDoubleClick.compare(now, pos, button)) {\n    lastClick = lastDoubleClick = null\n    return \"triple\"\n  } else if (lastClick && lastClick.compare(now, pos, button)) {\n    lastDoubleClick = new PastClick(now, pos, button)\n    lastClick = null\n    return \"double\"\n  } else {\n    lastClick = new PastClick(now, pos, button)\n    lastDoubleClick = null\n    return \"single\"\n  }\n}\n\n// A mouse down can be a single click, double click, triple click,\n// start of selection drag, start of text drag, new cursor\n// (ctrl-click), rectangle drag (alt-drag), or xwin\n// middle-click-paste. Or it might be a click on something we should\n// not interfere with, such as a scrollbar or widget.\nfunction onMouseDown(e) {\n  var cm = this, display = cm.display\n  if (signalDOMEvent(cm, e) || display.activeTouch && display.input.supportsTouch()) { return }\n  display.input.ensurePolled()\n  display.shift = e.shiftKey\n\n  if (eventInWidget(display, e)) {\n    if (!webkit) {\n      // Briefly turn off draggability, to allow widgets to do\n      // normal dragging things.\n      display.scroller.draggable = false\n      setTimeout(function () { return display.scroller.draggable = true; }, 100)\n    }\n    return\n  }\n  if (clickInGutter(cm, e)) { return }\n  var pos = posFromMouse(cm, e), button = e_button(e), repeat = pos ? clickRepeat(pos, button) : \"single\"\n  window.focus()\n\n  // #3261: make sure, that we're not starting a second selection\n  if (button == 1 && cm.state.selectingText)\n    { cm.state.selectingText(e) }\n\n  if (pos && handleMappedButton(cm, button, pos, repeat, e)) { return }\n\n  if (button == 1) {\n    if (pos) { leftButtonDown(cm, pos, repeat, e) }\n    else if (e_target(e) == display.scroller) { e_preventDefault(e) }\n  } else if (button == 2) {\n    if (pos) { extendSelection(cm.doc, pos) }\n    setTimeout(function () { return display.input.focus(); }, 20)\n  } else if (button == 3) {\n    if (captureRightClick) { onContextMenu(cm, e) }\n    else { delayBlurEvent(cm) }\n  }\n}\n\nfunction handleMappedButton(cm, button, pos, repeat, event) {\n  var name = \"Click\"\n  if (repeat == \"double\") { name = \"Double\" + name }\n  else if (repeat == \"triple\") { name = \"Triple\" + name }\n  name = (button == 1 ? \"Left\" : button == 2 ? \"Middle\" : \"Right\") + name\n\n  return dispatchKey(cm,  addModifierNames(name, event), event, function (bound) {\n    if (typeof bound == \"string\") { bound = commands[bound] }\n    if (!bound) { return false }\n    var done = false\n    try {\n      if (cm.isReadOnly()) { cm.state.suppressEdits = true }\n      done = bound(cm, pos) != Pass\n    } finally {\n      cm.state.suppressEdits = false\n    }\n    return done\n  })\n}\n\nfunction configureMouse(cm, repeat, event) {\n  var option = cm.getOption(\"configureMouse\")\n  var value = option ? option(cm, repeat, event) : {}\n  if (value.unit == null) {\n    var rect = chromeOS ? event.shiftKey && event.metaKey : event.altKey\n    value.unit = rect ? \"rectangle\" : repeat == \"single\" ? \"char\" : repeat == \"double\" ? \"word\" : \"line\"\n  }\n  if (value.extend == null || cm.doc.extend) { value.extend = cm.doc.extend || event.shiftKey }\n  if (value.addNew == null) { value.addNew = mac ? event.metaKey : event.ctrlKey }\n  if (value.moveOnDrag == null) { value.moveOnDrag = !(mac ? event.altKey : event.ctrlKey) }\n  return value\n}\n\nfunction leftButtonDown(cm, pos, repeat, event) {\n  if (ie) { setTimeout(bind(ensureFocus, cm), 0) }\n  else { cm.curOp.focus = activeElt() }\n\n  var behavior = configureMouse(cm, repeat, event)\n\n  var sel = cm.doc.sel, contained\n  if (cm.options.dragDrop && dragAndDrop && !cm.isReadOnly() &&\n      repeat == \"single\" && (contained = sel.contains(pos)) > -1 &&\n      (cmp((contained = sel.ranges[contained]).from(), pos) < 0 || pos.xRel > 0) &&\n      (cmp(contained.to(), pos) > 0 || pos.xRel < 0))\n    { leftButtonStartDrag(cm, event, pos, behavior) }\n  else\n    { leftButtonSelect(cm, event, pos, behavior) }\n}\n\n// Start a text drag. When it ends, see if any dragging actually\n// happen, and treat as a click if it didn't.\nfunction leftButtonStartDrag(cm, event, pos, behavior) {\n  var display = cm.display, moved = false\n  var dragEnd = operation(cm, function (e) {\n    if (webkit) { display.scroller.draggable = false }\n    cm.state.draggingText = false\n    off(document, \"mouseup\", dragEnd)\n    off(document, \"mousemove\", mouseMove)\n    off(display.scroller, \"dragstart\", dragStart)\n    off(display.scroller, \"drop\", dragEnd)\n    if (!moved) {\n      e_preventDefault(e)\n      if (!behavior.addNew)\n        { extendSelection(cm.doc, pos, null, null, behavior.extend) }\n      // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081)\n      if (webkit || ie && ie_version == 9)\n        { setTimeout(function () {document.body.focus(); display.input.focus()}, 20) }\n      else\n        { display.input.focus() }\n    }\n  })\n  var mouseMove = function(e2) {\n    moved = moved || Math.abs(event.clientX - e2.clientX) + Math.abs(event.clientY - e2.clientY) >= 10\n  }\n  var dragStart = function () { return moved = true; }\n  // Let the drag handler handle this.\n  if (webkit) { display.scroller.draggable = true }\n  cm.state.draggingText = dragEnd\n  dragEnd.copy = !behavior.moveOnDrag\n  // IE's approach to draggable\n  if (display.scroller.dragDrop) { display.scroller.dragDrop() }\n  on(document, \"mouseup\", dragEnd)\n  on(document, \"mousemove\", mouseMove)\n  on(display.scroller, \"dragstart\", dragStart)\n  on(display.scroller, \"drop\", dragEnd)\n\n  delayBlurEvent(cm)\n  setTimeout(function () { return display.input.focus(); }, 20)\n}\n\nfunction rangeForUnit(cm, pos, unit) {\n  if (unit == \"char\") { return new Range(pos, pos) }\n  if (unit == \"word\") { return cm.findWordAt(pos) }\n  if (unit == \"line\") { return new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))) }\n  var result = unit(cm, pos)\n  return new Range(result.from, result.to)\n}\n\n// Normal selection, as opposed to text dragging.\nfunction leftButtonSelect(cm, event, start, behavior) {\n  var display = cm.display, doc = cm.doc\n  e_preventDefault(event)\n\n  var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges\n  if (behavior.addNew && !behavior.extend) {\n    ourIndex = doc.sel.contains(start)\n    if (ourIndex > -1)\n      { ourRange = ranges[ourIndex] }\n    else\n      { ourRange = new Range(start, start) }\n  } else {\n    ourRange = doc.sel.primary()\n    ourIndex = doc.sel.primIndex\n  }\n\n  if (behavior.unit == \"rectangle\") {\n    if (!behavior.addNew) { ourRange = new Range(start, start) }\n    start = posFromMouse(cm, event, true, true)\n    ourIndex = -1\n  } else {\n    var range = rangeForUnit(cm, start, behavior.unit)\n    if (behavior.extend)\n      { ourRange = extendRange(ourRange, range.anchor, range.head, behavior.extend) }\n    else\n      { ourRange = range }\n  }\n\n  if (!behavior.addNew) {\n    ourIndex = 0\n    setSelection(doc, new Selection([ourRange], 0), sel_mouse)\n    startSel = doc.sel\n  } else if (ourIndex == -1) {\n    ourIndex = ranges.length\n    setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex),\n                 {scroll: false, origin: \"*mouse\"})\n  } else if (ranges.length > 1 && ranges[ourIndex].empty() && behavior.unit == \"char\" && !behavior.extend) {\n    setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0),\n                 {scroll: false, origin: \"*mouse\"})\n    startSel = doc.sel\n  } else {\n    replaceOneSelection(doc, ourIndex, ourRange, sel_mouse)\n  }\n\n  var lastPos = start\n  function extendTo(pos) {\n    if (cmp(lastPos, pos) == 0) { return }\n    lastPos = pos\n\n    if (behavior.unit == \"rectangle\") {\n      var ranges = [], tabSize = cm.options.tabSize\n      var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize)\n      var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize)\n      var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol)\n      for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line));\n           line <= end; line++) {\n        var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize)\n        if (left == right)\n          { ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))) }\n        else if (text.length > leftPos)\n          { ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))) }\n      }\n      if (!ranges.length) { ranges.push(new Range(start, start)) }\n      setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex),\n                   {origin: \"*mouse\", scroll: false})\n      cm.scrollIntoView(pos)\n    } else {\n      var oldRange = ourRange\n      var range = rangeForUnit(cm, pos, behavior.unit)\n      var anchor = oldRange.anchor, head\n      if (cmp(range.anchor, anchor) > 0) {\n        head = range.head\n        anchor = minPos(oldRange.from(), range.anchor)\n      } else {\n        head = range.anchor\n        anchor = maxPos(oldRange.to(), range.head)\n      }\n      var ranges$1 = startSel.ranges.slice(0)\n      ranges$1[ourIndex] = new Range(clipPos(doc, anchor), head)\n      setSelection(doc, normalizeSelection(ranges$1, ourIndex), sel_mouse)\n    }\n  }\n\n  var editorSize = display.wrapper.getBoundingClientRect()\n  // Used to ensure timeout re-tries don't fire when another extend\n  // happened in the meantime (clearTimeout isn't reliable -- at\n  // least on Chrome, the timeouts still happen even when cleared,\n  // if the clear happens after their scheduled firing time).\n  var counter = 0\n\n  function extend(e) {\n    var curCount = ++counter\n    var cur = posFromMouse(cm, e, true, behavior.unit == \"rectangle\")\n    if (!cur) { return }\n    if (cmp(cur, lastPos) != 0) {\n      cm.curOp.focus = activeElt()\n      extendTo(cur)\n      var visible = visibleLines(display, doc)\n      if (cur.line >= visible.to || cur.line < visible.from)\n        { setTimeout(operation(cm, function () {if (counter == curCount) { extend(e) }}), 150) }\n    } else {\n      var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0\n      if (outside) { setTimeout(operation(cm, function () {\n        if (counter != curCount) { return }\n        display.scroller.scrollTop += outside\n        extend(e)\n      }), 50) }\n    }\n  }\n\n  function done(e) {\n    cm.state.selectingText = false\n    counter = Infinity\n    e_preventDefault(e)\n    display.input.focus()\n    off(document, \"mousemove\", move)\n    off(document, \"mouseup\", up)\n    doc.history.lastSelOrigin = null\n  }\n\n  var move = operation(cm, function (e) {\n    if (!e_button(e)) { done(e) }\n    else { extend(e) }\n  })\n  var up = operation(cm, done)\n  cm.state.selectingText = up\n  on(document, \"mousemove\", move)\n  on(document, \"mouseup\", up)\n}\n\n\n// Determines whether an event happened in the gutter, and fires the\n// handlers for the corresponding event.\nfunction gutterEvent(cm, e, type, prevent) {\n  var mX, mY\n  try { mX = e.clientX; mY = e.clientY }\n  catch(e) { return false }\n  if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) { return false }\n  if (prevent) { e_preventDefault(e) }\n\n  var display = cm.display\n  var lineBox = display.lineDiv.getBoundingClientRect()\n\n  if (mY > lineBox.bottom || !hasHandler(cm, type)) { return e_defaultPrevented(e) }\n  mY -= lineBox.top - display.viewOffset\n\n  for (var i = 0; i < cm.options.gutters.length; ++i) {\n    var g = display.gutters.childNodes[i]\n    if (g && g.getBoundingClientRect().right >= mX) {\n      var line = lineAtHeight(cm.doc, mY)\n      var gutter = cm.options.gutters[i]\n      signal(cm, type, cm, line, gutter, e)\n      return e_defaultPrevented(e)\n    }\n  }\n}\n\nfunction clickInGutter(cm, e) {\n  return gutterEvent(cm, e, \"gutterClick\", true)\n}\n\n// CONTEXT MENU HANDLING\n\n// To make the context menu work, we need to briefly unhide the\n// textarea (making it as unobtrusive as possible) to let the\n// right-click take effect on it.\nfunction onContextMenu(cm, e) {\n  if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) { return }\n  if (signalDOMEvent(cm, e, \"contextmenu\")) { return }\n  cm.display.input.onContextMenu(e)\n}\n\nfunction contextMenuInGutter(cm, e) {\n  if (!hasHandler(cm, \"gutterContextMenu\")) { return false }\n  return gutterEvent(cm, e, \"gutterContextMenu\", false)\n}\n\nfunction themeChanged(cm) {\n  cm.display.wrapper.className = cm.display.wrapper.className.replace(/\\s*cm-s-\\S+/g, \"\") +\n    cm.options.theme.replace(/(^|\\s)\\s*/g, \" cm-s-\")\n  clearCaches(cm)\n}\n\nvar Init = {toString: function(){return \"CodeMirror.Init\"}}\n\nvar defaults = {}\nvar optionHandlers = {}\n\nfunction defineOptions(CodeMirror) {\n  var optionHandlers = CodeMirror.optionHandlers\n\n  function option(name, deflt, handle, notOnInit) {\n    CodeMirror.defaults[name] = deflt\n    if (handle) { optionHandlers[name] =\n      notOnInit ? function (cm, val, old) {if (old != Init) { handle(cm, val, old) }} : handle }\n  }\n\n  CodeMirror.defineOption = option\n\n  // Passed to option handlers when there is no old value.\n  CodeMirror.Init = Init\n\n  // These two are, on init, called from the constructor because they\n  // have to be initialized before the editor can start at all.\n  option(\"value\", \"\", function (cm, val) { return cm.setValue(val); }, true)\n  option(\"mode\", null, function (cm, val) {\n    cm.doc.modeOption = val\n    loadMode(cm)\n  }, true)\n\n  option(\"indentUnit\", 2, loadMode, true)\n  option(\"indentWithTabs\", false)\n  option(\"smartIndent\", true)\n  option(\"tabSize\", 4, function (cm) {\n    resetModeState(cm)\n    clearCaches(cm)\n    regChange(cm)\n  }, true)\n  option(\"lineSeparator\", null, function (cm, val) {\n    cm.doc.lineSep = val\n    if (!val) { return }\n    var newBreaks = [], lineNo = cm.doc.first\n    cm.doc.iter(function (line) {\n      for (var pos = 0;;) {\n        var found = line.text.indexOf(val, pos)\n        if (found == -1) { break }\n        pos = found + val.length\n        newBreaks.push(Pos(lineNo, found))\n      }\n      lineNo++\n    })\n    for (var i = newBreaks.length - 1; i >= 0; i--)\n      { replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)) }\n  })\n  option(\"specialChars\", /[\\u0000-\\u001f\\u007f-\\u009f\\u00ad\\u061c\\u200b-\\u200f\\u2028\\u2029\\ufeff]/g, function (cm, val, old) {\n    cm.state.specialChars = new RegExp(val.source + (val.test(\"\\t\") ? \"\" : \"|\\t\"), \"g\")\n    if (old != Init) { cm.refresh() }\n  })\n  option(\"specialCharPlaceholder\", defaultSpecialCharPlaceholder, function (cm) { return cm.refresh(); }, true)\n  option(\"electricChars\", true)\n  option(\"inputStyle\", mobile ? \"contenteditable\" : \"textarea\", function () {\n    throw new Error(\"inputStyle can not (yet) be changed in a running editor\") // FIXME\n  }, true)\n  option(\"spellcheck\", false, function (cm, val) { return cm.getInputField().spellcheck = val; }, true)\n  option(\"rtlMoveVisually\", !windows)\n  option(\"wholeLineUpdateBefore\", true)\n\n  option(\"theme\", \"default\", function (cm) {\n    themeChanged(cm)\n    guttersChanged(cm)\n  }, true)\n  option(\"keyMap\", \"default\", function (cm, val, old) {\n    var next = getKeyMap(val)\n    var prev = old != Init && getKeyMap(old)\n    if (prev && prev.detach) { prev.detach(cm, next) }\n    if (next.attach) { next.attach(cm, prev || null) }\n  })\n  option(\"extraKeys\", null)\n  option(\"configureMouse\", null)\n\n  option(\"lineWrapping\", false, wrappingChanged, true)\n  option(\"gutters\", [], function (cm) {\n    setGuttersForLineNumbers(cm.options)\n    guttersChanged(cm)\n  }, true)\n  option(\"fixedGutter\", true, function (cm, val) {\n    cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + \"px\" : \"0\"\n    cm.refresh()\n  }, true)\n  option(\"coverGutterNextToScrollbar\", false, function (cm) { return updateScrollbars(cm); }, true)\n  option(\"scrollbarStyle\", \"native\", function (cm) {\n    initScrollbars(cm)\n    updateScrollbars(cm)\n    cm.display.scrollbars.setScrollTop(cm.doc.scrollTop)\n    cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft)\n  }, true)\n  option(\"lineNumbers\", false, function (cm) {\n    setGuttersForLineNumbers(cm.options)\n    guttersChanged(cm)\n  }, true)\n  option(\"firstLineNumber\", 1, guttersChanged, true)\n  option(\"lineNumberFormatter\", function (integer) { return integer; }, guttersChanged, true)\n  option(\"showCursorWhenSelecting\", false, updateSelection, true)\n\n  option(\"resetSelectionOnContextMenu\", true)\n  option(\"lineWiseCopyCut\", true)\n  option(\"pasteLinesPerSelection\", true)\n\n  option(\"readOnly\", false, function (cm, val) {\n    if (val == \"nocursor\") {\n      onBlur(cm)\n      cm.display.input.blur()\n    }\n    cm.display.input.readOnlyChanged(val)\n  })\n  option(\"disableInput\", false, function (cm, val) {if (!val) { cm.display.input.reset() }}, true)\n  option(\"dragDrop\", true, dragDropChanged)\n  option(\"allowDropFileTypes\", null)\n\n  option(\"cursorBlinkRate\", 530)\n  option(\"cursorScrollMargin\", 0)\n  option(\"cursorHeight\", 1, updateSelection, true)\n  option(\"singleCursorHeightPerLine\", true, updateSelection, true)\n  option(\"workTime\", 100)\n  option(\"workDelay\", 100)\n  option(\"flattenSpans\", true, resetModeState, true)\n  option(\"addModeClass\", false, resetModeState, true)\n  option(\"pollInterval\", 100)\n  option(\"undoDepth\", 200, function (cm, val) { return cm.doc.history.undoDepth = val; })\n  option(\"historyEventDelay\", 1250)\n  option(\"viewportMargin\", 10, function (cm) { return cm.refresh(); }, true)\n  option(\"maxHighlightLength\", 10000, resetModeState, true)\n  option(\"moveInputWithCursor\", true, function (cm, val) {\n    if (!val) { cm.display.input.resetPosition() }\n  })\n\n  option(\"tabindex\", null, function (cm, val) { return cm.display.input.getField().tabIndex = val || \"\"; })\n  option(\"autofocus\", null)\n  option(\"direction\", \"ltr\", function (cm, val) { return cm.doc.setDirection(val); }, true)\n}\n\nfunction guttersChanged(cm) {\n  updateGutters(cm)\n  regChange(cm)\n  alignHorizontally(cm)\n}\n\nfunction dragDropChanged(cm, value, old) {\n  var wasOn = old && old != Init\n  if (!value != !wasOn) {\n    var funcs = cm.display.dragFunctions\n    var toggle = value ? on : off\n    toggle(cm.display.scroller, \"dragstart\", funcs.start)\n    toggle(cm.display.scroller, \"dragenter\", funcs.enter)\n    toggle(cm.display.scroller, \"dragover\", funcs.over)\n    toggle(cm.display.scroller, \"dragleave\", funcs.leave)\n    toggle(cm.display.scroller, \"drop\", funcs.drop)\n  }\n}\n\nfunction wrappingChanged(cm) {\n  if (cm.options.lineWrapping) {\n    addClass(cm.display.wrapper, \"CodeMirror-wrap\")\n    cm.display.sizer.style.minWidth = \"\"\n    cm.display.sizerWidth = null\n  } else {\n    rmClass(cm.display.wrapper, \"CodeMirror-wrap\")\n    findMaxLine(cm)\n  }\n  estimateLineHeights(cm)\n  regChange(cm)\n  clearCaches(cm)\n  setTimeout(function () { return updateScrollbars(cm); }, 100)\n}\n\n// A CodeMirror instance represents an editor. This is the object\n// that user code is usually dealing with.\n\nfunction CodeMirror(place, options) {\n  var this$1 = this;\n\n  if (!(this instanceof CodeMirror)) { return new CodeMirror(place, options) }\n\n  this.options = options = options ? copyObj(options) : {}\n  // Determine effective options based on given values and defaults.\n  copyObj(defaults, options, false)\n  setGuttersForLineNumbers(options)\n\n  var doc = options.value\n  if (typeof doc == \"string\") { doc = new Doc(doc, options.mode, null, options.lineSeparator, options.direction) }\n  this.doc = doc\n\n  var input = new CodeMirror.inputStyles[options.inputStyle](this)\n  var display = this.display = new Display(place, doc, input)\n  display.wrapper.CodeMirror = this\n  updateGutters(this)\n  themeChanged(this)\n  if (options.lineWrapping)\n    { this.display.wrapper.className += \" CodeMirror-wrap\" }\n  initScrollbars(this)\n\n  this.state = {\n    keyMaps: [],  // stores maps added by addKeyMap\n    overlays: [], // highlighting overlays, as added by addOverlay\n    modeGen: 0,   // bumped when mode/overlay changes, used to invalidate highlighting info\n    overwrite: false,\n    delayingBlurEvent: false,\n    focused: false,\n    suppressEdits: false, // used to disable editing during key handlers when in readOnly mode\n    pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll\n    selectingText: false,\n    draggingText: false,\n    highlight: new Delayed(), // stores highlight worker timeout\n    keySeq: null,  // Unfinished key sequence\n    specialChars: null\n  }\n\n  if (options.autofocus && !mobile) { display.input.focus() }\n\n  // Override magic textarea content restore that IE sometimes does\n  // on our hidden textarea on reload\n  if (ie && ie_version < 11) { setTimeout(function () { return this$1.display.input.reset(true); }, 20) }\n\n  registerEventHandlers(this)\n  ensureGlobalHandlers()\n\n  startOperation(this)\n  this.curOp.forceUpdate = true\n  attachDoc(this, doc)\n\n  if ((options.autofocus && !mobile) || this.hasFocus())\n    { setTimeout(bind(onFocus, this), 20) }\n  else\n    { onBlur(this) }\n\n  for (var opt in optionHandlers) { if (optionHandlers.hasOwnProperty(opt))\n    { optionHandlers[opt](this$1, options[opt], Init) } }\n  maybeUpdateLineNumberWidth(this)\n  if (options.finishInit) { options.finishInit(this) }\n  for (var i = 0; i < initHooks.length; ++i) { initHooks[i](this$1) }\n  endOperation(this)\n  // Suppress optimizelegibility in Webkit, since it breaks text\n  // measuring on line wrapping boundaries.\n  if (webkit && options.lineWrapping &&\n      getComputedStyle(display.lineDiv).textRendering == \"optimizelegibility\")\n    { display.lineDiv.style.textRendering = \"auto\" }\n}\n\n// The default configuration options.\nCodeMirror.defaults = defaults\n// Functions to run when options are changed.\nCodeMirror.optionHandlers = optionHandlers\n\n// Attach the necessary event handlers when initializing the editor\nfunction registerEventHandlers(cm) {\n  var d = cm.display\n  on(d.scroller, \"mousedown\", operation(cm, onMouseDown))\n  // Older IE's will not fire a second mousedown for a double click\n  if (ie && ie_version < 11)\n    { on(d.scroller, \"dblclick\", operation(cm, function (e) {\n      if (signalDOMEvent(cm, e)) { return }\n      var pos = posFromMouse(cm, e)\n      if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) { return }\n      e_preventDefault(e)\n      var word = cm.findWordAt(pos)\n      extendSelection(cm.doc, word.anchor, word.head)\n    })) }\n  else\n    { on(d.scroller, \"dblclick\", function (e) { return signalDOMEvent(cm, e) || e_preventDefault(e); }) }\n  // Some browsers fire contextmenu *after* opening the menu, at\n  // which point we can't mess with it anymore. Context menu is\n  // handled in onMouseDown for these browsers.\n  if (!captureRightClick) { on(d.scroller, \"contextmenu\", function (e) { return onContextMenu(cm, e); }) }\n\n  // Used to suppress mouse event handling when a touch happens\n  var touchFinished, prevTouch = {end: 0}\n  function finishTouch() {\n    if (d.activeTouch) {\n      touchFinished = setTimeout(function () { return d.activeTouch = null; }, 1000)\n      prevTouch = d.activeTouch\n      prevTouch.end = +new Date\n    }\n  }\n  function isMouseLikeTouchEvent(e) {\n    if (e.touches.length != 1) { return false }\n    var touch = e.touches[0]\n    return touch.radiusX <= 1 && touch.radiusY <= 1\n  }\n  function farAway(touch, other) {\n    if (other.left == null) { return true }\n    var dx = other.left - touch.left, dy = other.top - touch.top\n    return dx * dx + dy * dy > 20 * 20\n  }\n  on(d.scroller, \"touchstart\", function (e) {\n    if (!signalDOMEvent(cm, e) && !isMouseLikeTouchEvent(e)) {\n      d.input.ensurePolled()\n      clearTimeout(touchFinished)\n      var now = +new Date\n      d.activeTouch = {start: now, moved: false,\n                       prev: now - prevTouch.end <= 300 ? prevTouch : null}\n      if (e.touches.length == 1) {\n        d.activeTouch.left = e.touches[0].pageX\n        d.activeTouch.top = e.touches[0].pageY\n      }\n    }\n  })\n  on(d.scroller, \"touchmove\", function () {\n    if (d.activeTouch) { d.activeTouch.moved = true }\n  })\n  on(d.scroller, \"touchend\", function (e) {\n    var touch = d.activeTouch\n    if (touch && !eventInWidget(d, e) && touch.left != null &&\n        !touch.moved && new Date - touch.start < 300) {\n      var pos = cm.coordsChar(d.activeTouch, \"page\"), range\n      if (!touch.prev || farAway(touch, touch.prev)) // Single tap\n        { range = new Range(pos, pos) }\n      else if (!touch.prev.prev || farAway(touch, touch.prev.prev)) // Double tap\n        { range = cm.findWordAt(pos) }\n      else // Triple tap\n        { range = new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))) }\n      cm.setSelection(range.anchor, range.head)\n      cm.focus()\n      e_preventDefault(e)\n    }\n    finishTouch()\n  })\n  on(d.scroller, \"touchcancel\", finishTouch)\n\n  // Sync scrolling between fake scrollbars and real scrollable\n  // area, ensure viewport is updated when scrolling.\n  on(d.scroller, \"scroll\", function () {\n    if (d.scroller.clientHeight) {\n      updateScrollTop(cm, d.scroller.scrollTop)\n      setScrollLeft(cm, d.scroller.scrollLeft, true)\n      signal(cm, \"scroll\", cm)\n    }\n  })\n\n  // Listen to wheel events in order to try and update the viewport on time.\n  on(d.scroller, \"mousewheel\", function (e) { return onScrollWheel(cm, e); })\n  on(d.scroller, \"DOMMouseScroll\", function (e) { return onScrollWheel(cm, e); })\n\n  // Prevent wrapper from ever scrolling\n  on(d.wrapper, \"scroll\", function () { return d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; })\n\n  d.dragFunctions = {\n    enter: function (e) {if (!signalDOMEvent(cm, e)) { e_stop(e) }},\n    over: function (e) {if (!signalDOMEvent(cm, e)) { onDragOver(cm, e); e_stop(e) }},\n    start: function (e) { return onDragStart(cm, e); },\n    drop: operation(cm, onDrop),\n    leave: function (e) {if (!signalDOMEvent(cm, e)) { clearDragCursor(cm) }}\n  }\n\n  var inp = d.input.getField()\n  on(inp, \"keyup\", function (e) { return onKeyUp.call(cm, e); })\n  on(inp, \"keydown\", operation(cm, onKeyDown))\n  on(inp, \"keypress\", operation(cm, onKeyPress))\n  on(inp, \"focus\", function (e) { return onFocus(cm, e); })\n  on(inp, \"blur\", function (e) { return onBlur(cm, e); })\n}\n\nvar initHooks = []\nCodeMirror.defineInitHook = function (f) { return initHooks.push(f); }\n\n// Indent the given line. The how parameter can be \"smart\",\n// \"add\"/null, \"subtract\", or \"prev\". When aggressive is false\n// (typically set to true for forced single-line indents), empty\n// lines are not indented, and places where the mode returns Pass\n// are left alone.\nfunction indentLine(cm, n, how, aggressive) {\n  var doc = cm.doc, state\n  if (how == null) { how = \"add\" }\n  if (how == \"smart\") {\n    // Fall back to \"prev\" when the mode doesn't have an indentation\n    // method.\n    if (!doc.mode.indent) { how = \"prev\" }\n    else { state = getContextBefore(cm, n).state }\n  }\n\n  var tabSize = cm.options.tabSize\n  var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize)\n  if (line.stateAfter) { line.stateAfter = null }\n  var curSpaceString = line.text.match(/^\\s*/)[0], indentation\n  if (!aggressive && !/\\S/.test(line.text)) {\n    indentation = 0\n    how = \"not\"\n  } else if (how == \"smart\") {\n    indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text)\n    if (indentation == Pass || indentation > 150) {\n      if (!aggressive) { return }\n      how = \"prev\"\n    }\n  }\n  if (how == \"prev\") {\n    if (n > doc.first) { indentation = countColumn(getLine(doc, n-1).text, null, tabSize) }\n    else { indentation = 0 }\n  } else if (how == \"add\") {\n    indentation = curSpace + cm.options.indentUnit\n  } else if (how == \"subtract\") {\n    indentation = curSpace - cm.options.indentUnit\n  } else if (typeof how == \"number\") {\n    indentation = curSpace + how\n  }\n  indentation = Math.max(0, indentation)\n\n  var indentString = \"\", pos = 0\n  if (cm.options.indentWithTabs)\n    { for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += \"\\t\"} }\n  if (pos < indentation) { indentString += spaceStr(indentation - pos) }\n\n  if (indentString != curSpaceString) {\n    replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), \"+input\")\n    line.stateAfter = null\n    return true\n  } else {\n    // Ensure that, if the cursor was in the whitespace at the start\n    // of the line, it is moved to the end of that space.\n    for (var i$1 = 0; i$1 < doc.sel.ranges.length; i$1++) {\n      var range = doc.sel.ranges[i$1]\n      if (range.head.line == n && range.head.ch < curSpaceString.length) {\n        var pos$1 = Pos(n, curSpaceString.length)\n        replaceOneSelection(doc, i$1, new Range(pos$1, pos$1))\n        break\n      }\n    }\n  }\n}\n\n// This will be set to a {lineWise: bool, text: [string]} object, so\n// that, when pasting, we know what kind of selections the copied\n// text was made out of.\nvar lastCopied = null\n\nfunction setLastCopied(newLastCopied) {\n  lastCopied = newLastCopied\n}\n\nfunction applyTextInput(cm, inserted, deleted, sel, origin) {\n  var doc = cm.doc\n  cm.display.shift = false\n  if (!sel) { sel = doc.sel }\n\n  var paste = cm.state.pasteIncoming || origin == \"paste\"\n  var textLines = splitLinesAuto(inserted), multiPaste = null\n  // When pasing N lines into N selections, insert one line per selection\n  if (paste && sel.ranges.length > 1) {\n    if (lastCopied && lastCopied.text.join(\"\\n\") == inserted) {\n      if (sel.ranges.length % lastCopied.text.length == 0) {\n        multiPaste = []\n        for (var i = 0; i < lastCopied.text.length; i++)\n          { multiPaste.push(doc.splitLines(lastCopied.text[i])) }\n      }\n    } else if (textLines.length == sel.ranges.length && cm.options.pasteLinesPerSelection) {\n      multiPaste = map(textLines, function (l) { return [l]; })\n    }\n  }\n\n  var updateInput\n  // Normal behavior is to insert the new text into every selection\n  for (var i$1 = sel.ranges.length - 1; i$1 >= 0; i$1--) {\n    var range = sel.ranges[i$1]\n    var from = range.from(), to = range.to()\n    if (range.empty()) {\n      if (deleted && deleted > 0) // Handle deletion\n        { from = Pos(from.line, from.ch - deleted) }\n      else if (cm.state.overwrite && !paste) // Handle overwrite\n        { to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)) }\n      else if (lastCopied && lastCopied.lineWise && lastCopied.text.join(\"\\n\") == inserted)\n        { from = to = Pos(from.line, 0) }\n    }\n    updateInput = cm.curOp.updateInput\n    var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i$1 % multiPaste.length] : textLines,\n                       origin: origin || (paste ? \"paste\" : cm.state.cutIncoming ? \"cut\" : \"+input\")}\n    makeChange(cm.doc, changeEvent)\n    signalLater(cm, \"inputRead\", cm, changeEvent)\n  }\n  if (inserted && !paste)\n    { triggerElectric(cm, inserted) }\n\n  ensureCursorVisible(cm)\n  cm.curOp.updateInput = updateInput\n  cm.curOp.typing = true\n  cm.state.pasteIncoming = cm.state.cutIncoming = false\n}\n\nfunction handlePaste(e, cm) {\n  var pasted = e.clipboardData && e.clipboardData.getData(\"Text\")\n  if (pasted) {\n    e.preventDefault()\n    if (!cm.isReadOnly() && !cm.options.disableInput)\n      { runInOp(cm, function () { return applyTextInput(cm, pasted, 0, null, \"paste\"); }) }\n    return true\n  }\n}\n\nfunction triggerElectric(cm, inserted) {\n  // When an 'electric' character is inserted, immediately trigger a reindent\n  if (!cm.options.electricChars || !cm.options.smartIndent) { return }\n  var sel = cm.doc.sel\n\n  for (var i = sel.ranges.length - 1; i >= 0; i--) {\n    var range = sel.ranges[i]\n    if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) { continue }\n    var mode = cm.getModeAt(range.head)\n    var indented = false\n    if (mode.electricChars) {\n      for (var j = 0; j < mode.electricChars.length; j++)\n        { if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {\n          indented = indentLine(cm, range.head.line, \"smart\")\n          break\n        } }\n    } else if (mode.electricInput) {\n      if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch)))\n        { indented = indentLine(cm, range.head.line, \"smart\") }\n    }\n    if (indented) { signalLater(cm, \"electricInput\", cm, range.head.line) }\n  }\n}\n\nfunction copyableRanges(cm) {\n  var text = [], ranges = []\n  for (var i = 0; i < cm.doc.sel.ranges.length; i++) {\n    var line = cm.doc.sel.ranges[i].head.line\n    var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)}\n    ranges.push(lineRange)\n    text.push(cm.getRange(lineRange.anchor, lineRange.head))\n  }\n  return {text: text, ranges: ranges}\n}\n\nfunction disableBrowserMagic(field, spellcheck) {\n  field.setAttribute(\"autocorrect\", \"off\")\n  field.setAttribute(\"autocapitalize\", \"off\")\n  field.setAttribute(\"spellcheck\", !!spellcheck)\n}\n\nfunction hiddenTextarea() {\n  var te = elt(\"textarea\", null, null, \"position: absolute; bottom: -1em; padding: 0; width: 1px; height: 1em; outline: none\")\n  var div = elt(\"div\", [te], null, \"overflow: hidden; position: relative; width: 3px; height: 0px;\")\n  // The textarea is kept positioned near the cursor to prevent the\n  // fact that it'll be scrolled into view on input from scrolling\n  // our fake cursor out of view. On webkit, when wrap=off, paste is\n  // very slow. So make the area wide instead.\n  if (webkit) { te.style.width = \"1000px\" }\n  else { te.setAttribute(\"wrap\", \"off\") }\n  // If border: 0; -- iOS fails to open keyboard (issue #1287)\n  if (ios) { te.style.border = \"1px solid black\" }\n  disableBrowserMagic(te)\n  return div\n}\n\n// The publicly visible API. Note that methodOp(f) means\n// 'wrap f in an operation, performed on its `this` parameter'.\n\n// This is not the complete set of editor methods. Most of the\n// methods defined on the Doc type are also injected into\n// CodeMirror.prototype, for backwards compatibility and\n// convenience.\n\nfunction addEditorMethods(CodeMirror) {\n  var optionHandlers = CodeMirror.optionHandlers\n\n  var helpers = CodeMirror.helpers = {}\n\n  CodeMirror.prototype = {\n    constructor: CodeMirror,\n    focus: function(){window.focus(); this.display.input.focus()},\n\n    setOption: function(option, value) {\n      var options = this.options, old = options[option]\n      if (options[option] == value && option != \"mode\") { return }\n      options[option] = value\n      if (optionHandlers.hasOwnProperty(option))\n        { operation(this, optionHandlers[option])(this, value, old) }\n      signal(this, \"optionChange\", this, option)\n    },\n\n    getOption: function(option) {return this.options[option]},\n    getDoc: function() {return this.doc},\n\n    addKeyMap: function(map, bottom) {\n      this.state.keyMaps[bottom ? \"push\" : \"unshift\"](getKeyMap(map))\n    },\n    removeKeyMap: function(map) {\n      var maps = this.state.keyMaps\n      for (var i = 0; i < maps.length; ++i)\n        { if (maps[i] == map || maps[i].name == map) {\n          maps.splice(i, 1)\n          return true\n        } }\n    },\n\n    addOverlay: methodOp(function(spec, options) {\n      var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec)\n      if (mode.startState) { throw new Error(\"Overlays may not be stateful.\") }\n      insertSorted(this.state.overlays,\n                   {mode: mode, modeSpec: spec, opaque: options && options.opaque,\n                    priority: (options && options.priority) || 0},\n                   function (overlay) { return overlay.priority; })\n      this.state.modeGen++\n      regChange(this)\n    }),\n    removeOverlay: methodOp(function(spec) {\n      var this$1 = this;\n\n      var overlays = this.state.overlays\n      for (var i = 0; i < overlays.length; ++i) {\n        var cur = overlays[i].modeSpec\n        if (cur == spec || typeof spec == \"string\" && cur.name == spec) {\n          overlays.splice(i, 1)\n          this$1.state.modeGen++\n          regChange(this$1)\n          return\n        }\n      }\n    }),\n\n    indentLine: methodOp(function(n, dir, aggressive) {\n      if (typeof dir != \"string\" && typeof dir != \"number\") {\n        if (dir == null) { dir = this.options.smartIndent ? \"smart\" : \"prev\" }\n        else { dir = dir ? \"add\" : \"subtract\" }\n      }\n      if (isLine(this.doc, n)) { indentLine(this, n, dir, aggressive) }\n    }),\n    indentSelection: methodOp(function(how) {\n      var this$1 = this;\n\n      var ranges = this.doc.sel.ranges, end = -1\n      for (var i = 0; i < ranges.length; i++) {\n        var range = ranges[i]\n        if (!range.empty()) {\n          var from = range.from(), to = range.to()\n          var start = Math.max(end, from.line)\n          end = Math.min(this$1.lastLine(), to.line - (to.ch ? 0 : 1)) + 1\n          for (var j = start; j < end; ++j)\n            { indentLine(this$1, j, how) }\n          var newRanges = this$1.doc.sel.ranges\n          if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0)\n            { replaceOneSelection(this$1.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll) }\n        } else if (range.head.line > end) {\n          indentLine(this$1, range.head.line, how, true)\n          end = range.head.line\n          if (i == this$1.doc.sel.primIndex) { ensureCursorVisible(this$1) }\n        }\n      }\n    }),\n\n    // Fetch the parser token for a given character. Useful for hacks\n    // that want to inspect the mode state (say, for completion).\n    getTokenAt: function(pos, precise) {\n      return takeToken(this, pos, precise)\n    },\n\n    getLineTokens: function(line, precise) {\n      return takeToken(this, Pos(line), precise, true)\n    },\n\n    getTokenTypeAt: function(pos) {\n      pos = clipPos(this.doc, pos)\n      var styles = getLineStyles(this, getLine(this.doc, pos.line))\n      var before = 0, after = (styles.length - 1) / 2, ch = pos.ch\n      var type\n      if (ch == 0) { type = styles[2] }\n      else { for (;;) {\n        var mid = (before + after) >> 1\n        if ((mid ? styles[mid * 2 - 1] : 0) >= ch) { after = mid }\n        else if (styles[mid * 2 + 1] < ch) { before = mid + 1 }\n        else { type = styles[mid * 2 + 2]; break }\n      } }\n      var cut = type ? type.indexOf(\"overlay \") : -1\n      return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1)\n    },\n\n    getModeAt: function(pos) {\n      var mode = this.doc.mode\n      if (!mode.innerMode) { return mode }\n      return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode\n    },\n\n    getHelper: function(pos, type) {\n      return this.getHelpers(pos, type)[0]\n    },\n\n    getHelpers: function(pos, type) {\n      var this$1 = this;\n\n      var found = []\n      if (!helpers.hasOwnProperty(type)) { return found }\n      var help = helpers[type], mode = this.getModeAt(pos)\n      if (typeof mode[type] == \"string\") {\n        if (help[mode[type]]) { found.push(help[mode[type]]) }\n      } else if (mode[type]) {\n        for (var i = 0; i < mode[type].length; i++) {\n          var val = help[mode[type][i]]\n          if (val) { found.push(val) }\n        }\n      } else if (mode.helperType && help[mode.helperType]) {\n        found.push(help[mode.helperType])\n      } else if (help[mode.name]) {\n        found.push(help[mode.name])\n      }\n      for (var i$1 = 0; i$1 < help._global.length; i$1++) {\n        var cur = help._global[i$1]\n        if (cur.pred(mode, this$1) && indexOf(found, cur.val) == -1)\n          { found.push(cur.val) }\n      }\n      return found\n    },\n\n    getStateAfter: function(line, precise) {\n      var doc = this.doc\n      line = clipLine(doc, line == null ? doc.first + doc.size - 1: line)\n      return getContextBefore(this, line + 1, precise).state\n    },\n\n    cursorCoords: function(start, mode) {\n      var pos, range = this.doc.sel.primary()\n      if (start == null) { pos = range.head }\n      else if (typeof start == \"object\") { pos = clipPos(this.doc, start) }\n      else { pos = start ? range.from() : range.to() }\n      return cursorCoords(this, pos, mode || \"page\")\n    },\n\n    charCoords: function(pos, mode) {\n      return charCoords(this, clipPos(this.doc, pos), mode || \"page\")\n    },\n\n    coordsChar: function(coords, mode) {\n      coords = fromCoordSystem(this, coords, mode || \"page\")\n      return coordsChar(this, coords.left, coords.top)\n    },\n\n    lineAtHeight: function(height, mode) {\n      height = fromCoordSystem(this, {top: height, left: 0}, mode || \"page\").top\n      return lineAtHeight(this.doc, height + this.display.viewOffset)\n    },\n    heightAtLine: function(line, mode, includeWidgets) {\n      var end = false, lineObj\n      if (typeof line == \"number\") {\n        var last = this.doc.first + this.doc.size - 1\n        if (line < this.doc.first) { line = this.doc.first }\n        else if (line > last) { line = last; end = true }\n        lineObj = getLine(this.doc, line)\n      } else {\n        lineObj = line\n      }\n      return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || \"page\", includeWidgets || end).top +\n        (end ? this.doc.height - heightAtLine(lineObj) : 0)\n    },\n\n    defaultTextHeight: function() { return textHeight(this.display) },\n    defaultCharWidth: function() { return charWidth(this.display) },\n\n    getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo}},\n\n    addWidget: function(pos, node, scroll, vert, horiz) {\n      var display = this.display\n      pos = cursorCoords(this, clipPos(this.doc, pos))\n      var top = pos.bottom, left = pos.left\n      node.style.position = \"absolute\"\n      node.setAttribute(\"cm-ignore-events\", \"true\")\n      this.display.input.setUneditable(node)\n      display.sizer.appendChild(node)\n      if (vert == \"over\") {\n        top = pos.top\n      } else if (vert == \"above\" || vert == \"near\") {\n        var vspace = Math.max(display.wrapper.clientHeight, this.doc.height),\n        hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth)\n        // Default to positioning above (if specified and possible); otherwise default to positioning below\n        if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight)\n          { top = pos.top - node.offsetHeight }\n        else if (pos.bottom + node.offsetHeight <= vspace)\n          { top = pos.bottom }\n        if (left + node.offsetWidth > hspace)\n          { left = hspace - node.offsetWidth }\n      }\n      node.style.top = top + \"px\"\n      node.style.left = node.style.right = \"\"\n      if (horiz == \"right\") {\n        left = display.sizer.clientWidth - node.offsetWidth\n        node.style.right = \"0px\"\n      } else {\n        if (horiz == \"left\") { left = 0 }\n        else if (horiz == \"middle\") { left = (display.sizer.clientWidth - node.offsetWidth) / 2 }\n        node.style.left = left + \"px\"\n      }\n      if (scroll)\n        { scrollIntoView(this, {left: left, top: top, right: left + node.offsetWidth, bottom: top + node.offsetHeight}) }\n    },\n\n    triggerOnKeyDown: methodOp(onKeyDown),\n    triggerOnKeyPress: methodOp(onKeyPress),\n    triggerOnKeyUp: onKeyUp,\n    triggerOnMouseDown: methodOp(onMouseDown),\n\n    execCommand: function(cmd) {\n      if (commands.hasOwnProperty(cmd))\n        { return commands[cmd].call(null, this) }\n    },\n\n    triggerElectric: methodOp(function(text) { triggerElectric(this, text) }),\n\n    findPosH: function(from, amount, unit, visually) {\n      var this$1 = this;\n\n      var dir = 1\n      if (amount < 0) { dir = -1; amount = -amount }\n      var cur = clipPos(this.doc, from)\n      for (var i = 0; i < amount; ++i) {\n        cur = findPosH(this$1.doc, cur, dir, unit, visually)\n        if (cur.hitSide) { break }\n      }\n      return cur\n    },\n\n    moveH: methodOp(function(dir, unit) {\n      var this$1 = this;\n\n      this.extendSelectionsBy(function (range) {\n        if (this$1.display.shift || this$1.doc.extend || range.empty())\n          { return findPosH(this$1.doc, range.head, dir, unit, this$1.options.rtlMoveVisually) }\n        else\n          { return dir < 0 ? range.from() : range.to() }\n      }, sel_move)\n    }),\n\n    deleteH: methodOp(function(dir, unit) {\n      var sel = this.doc.sel, doc = this.doc\n      if (sel.somethingSelected())\n        { doc.replaceSelection(\"\", null, \"+delete\") }\n      else\n        { deleteNearSelection(this, function (range) {\n          var other = findPosH(doc, range.head, dir, unit, false)\n          return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other}\n        }) }\n    }),\n\n    findPosV: function(from, amount, unit, goalColumn) {\n      var this$1 = this;\n\n      var dir = 1, x = goalColumn\n      if (amount < 0) { dir = -1; amount = -amount }\n      var cur = clipPos(this.doc, from)\n      for (var i = 0; i < amount; ++i) {\n        var coords = cursorCoords(this$1, cur, \"div\")\n        if (x == null) { x = coords.left }\n        else { coords.left = x }\n        cur = findPosV(this$1, coords, dir, unit)\n        if (cur.hitSide) { break }\n      }\n      return cur\n    },\n\n    moveV: methodOp(function(dir, unit) {\n      var this$1 = this;\n\n      var doc = this.doc, goals = []\n      var collapse = !this.display.shift && !doc.extend && doc.sel.somethingSelected()\n      doc.extendSelectionsBy(function (range) {\n        if (collapse)\n          { return dir < 0 ? range.from() : range.to() }\n        var headPos = cursorCoords(this$1, range.head, \"div\")\n        if (range.goalColumn != null) { headPos.left = range.goalColumn }\n        goals.push(headPos.left)\n        var pos = findPosV(this$1, headPos, dir, unit)\n        if (unit == \"page\" && range == doc.sel.primary())\n          { addToScrollTop(this$1, charCoords(this$1, pos, \"div\").top - headPos.top) }\n        return pos\n      }, sel_move)\n      if (goals.length) { for (var i = 0; i < doc.sel.ranges.length; i++)\n        { doc.sel.ranges[i].goalColumn = goals[i] } }\n    }),\n\n    // Find the word at the given position (as returned by coordsChar).\n    findWordAt: function(pos) {\n      var doc = this.doc, line = getLine(doc, pos.line).text\n      var start = pos.ch, end = pos.ch\n      if (line) {\n        var helper = this.getHelper(pos, \"wordChars\")\n        if ((pos.sticky == \"before\" || end == line.length) && start) { --start; } else { ++end }\n        var startChar = line.charAt(start)\n        var check = isWordChar(startChar, helper)\n          ? function (ch) { return isWordChar(ch, helper); }\n          : /\\s/.test(startChar) ? function (ch) { return /\\s/.test(ch); }\n          : function (ch) { return (!/\\s/.test(ch) && !isWordChar(ch)); }\n        while (start > 0 && check(line.charAt(start - 1))) { --start }\n        while (end < line.length && check(line.charAt(end))) { ++end }\n      }\n      return new Range(Pos(pos.line, start), Pos(pos.line, end))\n    },\n\n    toggleOverwrite: function(value) {\n      if (value != null && value == this.state.overwrite) { return }\n      if (this.state.overwrite = !this.state.overwrite)\n        { addClass(this.display.cursorDiv, \"CodeMirror-overwrite\") }\n      else\n        { rmClass(this.display.cursorDiv, \"CodeMirror-overwrite\") }\n\n      signal(this, \"overwriteToggle\", this, this.state.overwrite)\n    },\n    hasFocus: function() { return this.display.input.getField() == activeElt() },\n    isReadOnly: function() { return !!(this.options.readOnly || this.doc.cantEdit) },\n\n    scrollTo: methodOp(function (x, y) { scrollToCoords(this, x, y) }),\n    getScrollInfo: function() {\n      var scroller = this.display.scroller\n      return {left: scroller.scrollLeft, top: scroller.scrollTop,\n              height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight,\n              width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth,\n              clientHeight: displayHeight(this), clientWidth: displayWidth(this)}\n    },\n\n    scrollIntoView: methodOp(function(range, margin) {\n      if (range == null) {\n        range = {from: this.doc.sel.primary().head, to: null}\n        if (margin == null) { margin = this.options.cursorScrollMargin }\n      } else if (typeof range == \"number\") {\n        range = {from: Pos(range, 0), to: null}\n      } else if (range.from == null) {\n        range = {from: range, to: null}\n      }\n      if (!range.to) { range.to = range.from }\n      range.margin = margin || 0\n\n      if (range.from.line != null) {\n        scrollToRange(this, range)\n      } else {\n        scrollToCoordsRange(this, range.from, range.to, range.margin)\n      }\n    }),\n\n    setSize: methodOp(function(width, height) {\n      var this$1 = this;\n\n      var interpret = function (val) { return typeof val == \"number\" || /^\\d+$/.test(String(val)) ? val + \"px\" : val; }\n      if (width != null) { this.display.wrapper.style.width = interpret(width) }\n      if (height != null) { this.display.wrapper.style.height = interpret(height) }\n      if (this.options.lineWrapping) { clearLineMeasurementCache(this) }\n      var lineNo = this.display.viewFrom\n      this.doc.iter(lineNo, this.display.viewTo, function (line) {\n        if (line.widgets) { for (var i = 0; i < line.widgets.length; i++)\n          { if (line.widgets[i].noHScroll) { regLineChange(this$1, lineNo, \"widget\"); break } } }\n        ++lineNo\n      })\n      this.curOp.forceUpdate = true\n      signal(this, \"refresh\", this)\n    }),\n\n    operation: function(f){return runInOp(this, f)},\n    startOperation: function(){return startOperation(this)},\n    endOperation: function(){return endOperation(this)},\n\n    refresh: methodOp(function() {\n      var oldHeight = this.display.cachedTextHeight\n      regChange(this)\n      this.curOp.forceUpdate = true\n      clearCaches(this)\n      scrollToCoords(this, this.doc.scrollLeft, this.doc.scrollTop)\n      updateGutterSpace(this)\n      if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)\n        { estimateLineHeights(this) }\n      signal(this, \"refresh\", this)\n    }),\n\n    swapDoc: methodOp(function(doc) {\n      var old = this.doc\n      old.cm = null\n      attachDoc(this, doc)\n      clearCaches(this)\n      this.display.input.reset()\n      scrollToCoords(this, doc.scrollLeft, doc.scrollTop)\n      this.curOp.forceScroll = true\n      signalLater(this, \"swapDoc\", this, old)\n      return old\n    }),\n\n    getInputField: function(){return this.display.input.getField()},\n    getWrapperElement: function(){return this.display.wrapper},\n    getScrollerElement: function(){return this.display.scroller},\n    getGutterElement: function(){return this.display.gutters}\n  }\n  eventMixin(CodeMirror)\n\n  CodeMirror.registerHelper = function(type, name, value) {\n    if (!helpers.hasOwnProperty(type)) { helpers[type] = CodeMirror[type] = {_global: []} }\n    helpers[type][name] = value\n  }\n  CodeMirror.registerGlobalHelper = function(type, name, predicate, value) {\n    CodeMirror.registerHelper(type, name, value)\n    helpers[type]._global.push({pred: predicate, val: value})\n  }\n}\n\n// Used for horizontal relative motion. Dir is -1 or 1 (left or\n// right), unit can be \"char\", \"column\" (like char, but doesn't\n// cross line boundaries), \"word\" (across next word), or \"group\" (to\n// the start of next group of word or non-word-non-whitespace\n// chars). The visually param controls whether, in right-to-left\n// text, direction 1 means to move towards the next index in the\n// string, or towards the character to the right of the current\n// position. The resulting position will have a hitSide=true\n// property if it reached the end of the document.\nfunction findPosH(doc, pos, dir, unit, visually) {\n  var oldPos = pos\n  var origDir = dir\n  var lineObj = getLine(doc, pos.line)\n  function findNextLine() {\n    var l = pos.line + dir\n    if (l < doc.first || l >= doc.first + doc.size) { return false }\n    pos = new Pos(l, pos.ch, pos.sticky)\n    return lineObj = getLine(doc, l)\n  }\n  function moveOnce(boundToLine) {\n    var next\n    if (visually) {\n      next = moveVisually(doc.cm, lineObj, pos, dir)\n    } else {\n      next = moveLogically(lineObj, pos, dir)\n    }\n    if (next == null) {\n      if (!boundToLine && findNextLine())\n        { pos = endOfLine(visually, doc.cm, lineObj, pos.line, dir) }\n      else\n        { return false }\n    } else {\n      pos = next\n    }\n    return true\n  }\n\n  if (unit == \"char\") {\n    moveOnce()\n  } else if (unit == \"column\") {\n    moveOnce(true)\n  } else if (unit == \"word\" || unit == \"group\") {\n    var sawType = null, group = unit == \"group\"\n    var helper = doc.cm && doc.cm.getHelper(pos, \"wordChars\")\n    for (var first = true;; first = false) {\n      if (dir < 0 && !moveOnce(!first)) { break }\n      var cur = lineObj.text.charAt(pos.ch) || \"\\n\"\n      var type = isWordChar(cur, helper) ? \"w\"\n        : group && cur == \"\\n\" ? \"n\"\n        : !group || /\\s/.test(cur) ? null\n        : \"p\"\n      if (group && !first && !type) { type = \"s\" }\n      if (sawType && sawType != type) {\n        if (dir < 0) {dir = 1; moveOnce(); pos.sticky = \"after\"}\n        break\n      }\n\n      if (type) { sawType = type }\n      if (dir > 0 && !moveOnce(!first)) { break }\n    }\n  }\n  var result = skipAtomic(doc, pos, oldPos, origDir, true)\n  if (equalCursorPos(oldPos, result)) { result.hitSide = true }\n  return result\n}\n\n// For relative vertical movement. Dir may be -1 or 1. Unit can be\n// \"page\" or \"line\". The resulting position will have a hitSide=true\n// property if it reached the end of the document.\nfunction findPosV(cm, pos, dir, unit) {\n  var doc = cm.doc, x = pos.left, y\n  if (unit == \"page\") {\n    var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight)\n    var moveAmount = Math.max(pageSize - .5 * textHeight(cm.display), 3)\n    y = (dir > 0 ? pos.bottom : pos.top) + dir * moveAmount\n\n  } else if (unit == \"line\") {\n    y = dir > 0 ? pos.bottom + 3 : pos.top - 3\n  }\n  var target\n  for (;;) {\n    target = coordsChar(cm, x, y)\n    if (!target.outside) { break }\n    if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break }\n    y += dir * 5\n  }\n  return target\n}\n\n// CONTENTEDITABLE INPUT STYLE\n\nvar ContentEditableInput = function(cm) {\n  this.cm = cm\n  this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null\n  this.polling = new Delayed()\n  this.composing = null\n  this.gracePeriod = false\n  this.readDOMTimeout = null\n};\n\nContentEditableInput.prototype.init = function (display) {\n    var this$1 = this;\n\n  var input = this, cm = input.cm\n  var div = input.div = display.lineDiv\n  disableBrowserMagic(div, cm.options.spellcheck)\n\n  on(div, \"paste\", function (e) {\n    if (signalDOMEvent(cm, e) || handlePaste(e, cm)) { return }\n    // IE doesn't fire input events, so we schedule a read for the pasted content in this way\n    if (ie_version <= 11) { setTimeout(operation(cm, function () { return this$1.updateFromDOM(); }), 20) }\n  })\n\n  on(div, \"compositionstart\", function (e) {\n    this$1.composing = {data: e.data, done: false}\n  })\n  on(div, \"compositionupdate\", function (e) {\n    if (!this$1.composing) { this$1.composing = {data: e.data, done: false} }\n  })\n  on(div, \"compositionend\", function (e) {\n    if (this$1.composing) {\n      if (e.data != this$1.composing.data) { this$1.readFromDOMSoon() }\n      this$1.composing.done = true\n    }\n  })\n\n  on(div, \"touchstart\", function () { return input.forceCompositionEnd(); })\n\n  on(div, \"input\", function () {\n    if (!this$1.composing) { this$1.readFromDOMSoon() }\n  })\n\n  function onCopyCut(e) {\n    if (signalDOMEvent(cm, e)) { return }\n    if (cm.somethingSelected()) {\n      setLastCopied({lineWise: false, text: cm.getSelections()})\n      if (e.type == \"cut\") { cm.replaceSelection(\"\", null, \"cut\") }\n    } else if (!cm.options.lineWiseCopyCut) {\n      return\n    } else {\n      var ranges = copyableRanges(cm)\n      setLastCopied({lineWise: true, text: ranges.text})\n      if (e.type == \"cut\") {\n        cm.operation(function () {\n          cm.setSelections(ranges.ranges, 0, sel_dontScroll)\n          cm.replaceSelection(\"\", null, \"cut\")\n        })\n      }\n    }\n    if (e.clipboardData) {\n      e.clipboardData.clearData()\n      var content = lastCopied.text.join(\"\\n\")\n      // iOS exposes the clipboard API, but seems to discard content inserted into it\n      e.clipboardData.setData(\"Text\", content)\n      if (e.clipboardData.getData(\"Text\") == content) {\n        e.preventDefault()\n        return\n      }\n    }\n    // Old-fashioned briefly-focus-a-textarea hack\n    var kludge = hiddenTextarea(), te = kludge.firstChild\n    cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild)\n    te.value = lastCopied.text.join(\"\\n\")\n    var hadFocus = document.activeElement\n    selectInput(te)\n    setTimeout(function () {\n      cm.display.lineSpace.removeChild(kludge)\n      hadFocus.focus()\n      if (hadFocus == div) { input.showPrimarySelection() }\n    }, 50)\n  }\n  on(div, \"copy\", onCopyCut)\n  on(div, \"cut\", onCopyCut)\n};\n\nContentEditableInput.prototype.prepareSelection = function () {\n  var result = prepareSelection(this.cm, false)\n  result.focus = this.cm.state.focused\n  return result\n};\n\nContentEditableInput.prototype.showSelection = function (info, takeFocus) {\n  if (!info || !this.cm.display.view.length) { return }\n  if (info.focus || takeFocus) { this.showPrimarySelection() }\n  this.showMultipleSelections(info)\n};\n\nContentEditableInput.prototype.showPrimarySelection = function () {\n  var sel = window.getSelection(), cm = this.cm, prim = cm.doc.sel.primary()\n  var from = prim.from(), to = prim.to()\n\n  if (cm.display.viewTo == cm.display.viewFrom || from.line >= cm.display.viewTo || to.line < cm.display.viewFrom) {\n    sel.removeAllRanges()\n    return\n  }\n\n  var curAnchor = domToPos(cm, sel.anchorNode, sel.anchorOffset)\n  var curFocus = domToPos(cm, sel.focusNode, sel.focusOffset)\n  if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad &&\n      cmp(minPos(curAnchor, curFocus), from) == 0 &&\n      cmp(maxPos(curAnchor, curFocus), to) == 0)\n    { return }\n\n  var view = cm.display.view\n  var start = (from.line >= cm.display.viewFrom && posToDOM(cm, from)) ||\n      {node: view[0].measure.map[2], offset: 0}\n  var end = to.line < cm.display.viewTo && posToDOM(cm, to)\n  if (!end) {\n    var measure = view[view.length - 1].measure\n    var map = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map\n    end = {node: map[map.length - 1], offset: map[map.length - 2] - map[map.length - 3]}\n  }\n\n  if (!start || !end) {\n    sel.removeAllRanges()\n    return\n  }\n\n  var old = sel.rangeCount && sel.getRangeAt(0), rng\n  try { rng = range(start.node, start.offset, end.offset, end.node) }\n  catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible\n  if (rng) {\n    if (!gecko && cm.state.focused) {\n      sel.collapse(start.node, start.offset)\n      if (!rng.collapsed) {\n        sel.removeAllRanges()\n        sel.addRange(rng)\n      }\n    } else {\n      sel.removeAllRanges()\n      sel.addRange(rng)\n    }\n    if (old && sel.anchorNode == null) { sel.addRange(old) }\n    else if (gecko) { this.startGracePeriod() }\n  }\n  this.rememberSelection()\n};\n\nContentEditableInput.prototype.startGracePeriod = function () {\n    var this$1 = this;\n\n  clearTimeout(this.gracePeriod)\n  this.gracePeriod = setTimeout(function () {\n    this$1.gracePeriod = false\n    if (this$1.selectionChanged())\n      { this$1.cm.operation(function () { return this$1.cm.curOp.selectionChanged = true; }) }\n  }, 20)\n};\n\nContentEditableInput.prototype.showMultipleSelections = function (info) {\n  removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors)\n  removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection)\n};\n\nContentEditableInput.prototype.rememberSelection = function () {\n  var sel = window.getSelection()\n  this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset\n  this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset\n};\n\nContentEditableInput.prototype.selectionInEditor = function () {\n  var sel = window.getSelection()\n  if (!sel.rangeCount) { return false }\n  var node = sel.getRangeAt(0).commonAncestorContainer\n  return contains(this.div, node)\n};\n\nContentEditableInput.prototype.focus = function () {\n  if (this.cm.options.readOnly != \"nocursor\") {\n    if (!this.selectionInEditor())\n      { this.showSelection(this.prepareSelection(), true) }\n    this.div.focus()\n  }\n};\nContentEditableInput.prototype.blur = function () { this.div.blur() };\nContentEditableInput.prototype.getField = function () { return this.div };\n\nContentEditableInput.prototype.supportsTouch = function () { return true };\n\nContentEditableInput.prototype.receivedFocus = function () {\n  var input = this\n  if (this.selectionInEditor())\n    { this.pollSelection() }\n  else\n    { runInOp(this.cm, function () { return input.cm.curOp.selectionChanged = true; }) }\n\n  function poll() {\n    if (input.cm.state.focused) {\n      input.pollSelection()\n      input.polling.set(input.cm.options.pollInterval, poll)\n    }\n  }\n  this.polling.set(this.cm.options.pollInterval, poll)\n};\n\nContentEditableInput.prototype.selectionChanged = function () {\n  var sel = window.getSelection()\n  return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset ||\n    sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset\n};\n\nContentEditableInput.prototype.pollSelection = function () {\n  if (this.readDOMTimeout != null || this.gracePeriod || !this.selectionChanged()) { return }\n  var sel = window.getSelection(), cm = this.cm\n  // On Android Chrome (version 56, at least), backspacing into an\n  // uneditable block element will put the cursor in that element,\n  // and then, because it's not editable, hide the virtual keyboard.\n  // Because Android doesn't allow us to actually detect backspace\n  // presses in a sane way, this code checks for when that happens\n  // and simulates a backspace press in this case.\n  if (android && chrome && this.cm.options.gutters.length && isInGutter(sel.anchorNode)) {\n    this.cm.triggerOnKeyDown({type: \"keydown\", keyCode: 8, preventDefault: Math.abs})\n    this.blur()\n    this.focus()\n    return\n  }\n  if (this.composing) { return }\n  this.rememberSelection()\n  var anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset)\n  var head = domToPos(cm, sel.focusNode, sel.focusOffset)\n  if (anchor && head) { runInOp(cm, function () {\n    setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll)\n    if (anchor.bad || head.bad) { cm.curOp.selectionChanged = true }\n  }) }\n};\n\nContentEditableInput.prototype.pollContent = function () {\n  if (this.readDOMTimeout != null) {\n    clearTimeout(this.readDOMTimeout)\n    this.readDOMTimeout = null\n  }\n\n  var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary()\n  var from = sel.from(), to = sel.to()\n  if (from.ch == 0 && from.line > cm.firstLine())\n    { from = Pos(from.line - 1, getLine(cm.doc, from.line - 1).length) }\n  if (to.ch == getLine(cm.doc, to.line).text.length && to.line < cm.lastLine())\n    { to = Pos(to.line + 1, 0) }\n  if (from.line < display.viewFrom || to.line > display.viewTo - 1) { return false }\n\n  var fromIndex, fromLine, fromNode\n  if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) {\n    fromLine = lineNo(display.view[0].line)\n    fromNode = display.view[0].node\n  } else {\n    fromLine = lineNo(display.view[fromIndex].line)\n    fromNode = display.view[fromIndex - 1].node.nextSibling\n  }\n  var toIndex = findViewIndex(cm, to.line)\n  var toLine, toNode\n  if (toIndex == display.view.length - 1) {\n    toLine = display.viewTo - 1\n    toNode = display.lineDiv.lastChild\n  } else {\n    toLine = lineNo(display.view[toIndex + 1].line) - 1\n    toNode = display.view[toIndex + 1].node.previousSibling\n  }\n\n  if (!fromNode) { return false }\n  var newText = cm.doc.splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine))\n  var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length))\n  while (newText.length > 1 && oldText.length > 1) {\n    if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine-- }\n    else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++ }\n    else { break }\n  }\n\n  var cutFront = 0, cutEnd = 0\n  var newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length)\n  while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront))\n    { ++cutFront }\n  var newBot = lst(newText), oldBot = lst(oldText)\n  var maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0),\n                           oldBot.length - (oldText.length == 1 ? cutFront : 0))\n  while (cutEnd < maxCutEnd &&\n         newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1))\n    { ++cutEnd }\n  // Try to move start of change to start of selection if ambiguous\n  if (newText.length == 1 && oldText.length == 1 && fromLine == from.line) {\n    while (cutFront && cutFront > from.ch &&\n           newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1)) {\n      cutFront--\n      cutEnd++\n    }\n  }\n\n  newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd).replace(/^\\u200b+/, \"\")\n  newText[0] = newText[0].slice(cutFront).replace(/\\u200b+$/, \"\")\n\n  var chFrom = Pos(fromLine, cutFront)\n  var chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0)\n  if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) {\n    replaceRange(cm.doc, newText, chFrom, chTo, \"+input\")\n    return true\n  }\n};\n\nContentEditableInput.prototype.ensurePolled = function () {\n  this.forceCompositionEnd()\n};\nContentEditableInput.prototype.reset = function () {\n  this.forceCompositionEnd()\n};\nContentEditableInput.prototype.forceCompositionEnd = function () {\n  if (!this.composing) { return }\n  clearTimeout(this.readDOMTimeout)\n  this.composing = null\n  this.updateFromDOM()\n  this.div.blur()\n  this.div.focus()\n};\nContentEditableInput.prototype.readFromDOMSoon = function () {\n    var this$1 = this;\n\n  if (this.readDOMTimeout != null) { return }\n  this.readDOMTimeout = setTimeout(function () {\n    this$1.readDOMTimeout = null\n    if (this$1.composing) {\n      if (this$1.composing.done) { this$1.composing = null }\n      else { return }\n    }\n    this$1.updateFromDOM()\n  }, 80)\n};\n\nContentEditableInput.prototype.updateFromDOM = function () {\n    var this$1 = this;\n\n  if (this.cm.isReadOnly() || !this.pollContent())\n    { runInOp(this.cm, function () { return regChange(this$1.cm); }) }\n};\n\nContentEditableInput.prototype.setUneditable = function (node) {\n  node.contentEditable = \"false\"\n};\n\nContentEditableInput.prototype.onKeyPress = function (e) {\n  if (e.charCode == 0) { return }\n  e.preventDefault()\n  if (!this.cm.isReadOnly())\n    { operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0) }\n};\n\nContentEditableInput.prototype.readOnlyChanged = function (val) {\n  this.div.contentEditable = String(val != \"nocursor\")\n};\n\nContentEditableInput.prototype.onContextMenu = function () {};\nContentEditableInput.prototype.resetPosition = function () {};\n\nContentEditableInput.prototype.needsContentAttribute = true\n\nfunction posToDOM(cm, pos) {\n  var view = findViewForLine(cm, pos.line)\n  if (!view || view.hidden) { return null }\n  var line = getLine(cm.doc, pos.line)\n  var info = mapFromLineView(view, line, pos.line)\n\n  var order = getOrder(line, cm.doc.direction), side = \"left\"\n  if (order) {\n    var partPos = getBidiPartAt(order, pos.ch)\n    side = partPos % 2 ? \"right\" : \"left\"\n  }\n  var result = nodeAndOffsetInLineMap(info.map, pos.ch, side)\n  result.offset = result.collapse == \"right\" ? result.end : result.start\n  return result\n}\n\nfunction isInGutter(node) {\n  for (var scan = node; scan; scan = scan.parentNode)\n    { if (/CodeMirror-gutter-wrapper/.test(scan.className)) { return true } }\n  return false\n}\n\nfunction badPos(pos, bad) { if (bad) { pos.bad = true; } return pos }\n\nfunction domTextBetween(cm, from, to, fromLine, toLine) {\n  var text = \"\", closing = false, lineSep = cm.doc.lineSeparator()\n  function recognizeMarker(id) { return function (marker) { return marker.id == id; } }\n  function close() {\n    if (closing) {\n      text += lineSep\n      closing = false\n    }\n  }\n  function addText(str) {\n    if (str) {\n      close()\n      text += str\n    }\n  }\n  function walk(node) {\n    if (node.nodeType == 1) {\n      var cmText = node.getAttribute(\"cm-text\")\n      if (cmText != null) {\n        addText(cmText || node.textContent.replace(/\\u200b/g, \"\"))\n        return\n      }\n      var markerID = node.getAttribute(\"cm-marker\"), range\n      if (markerID) {\n        var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID))\n        if (found.length && (range = found[0].find()))\n          { addText(getBetween(cm.doc, range.from, range.to).join(lineSep)) }\n        return\n      }\n      if (node.getAttribute(\"contenteditable\") == \"false\") { return }\n      var isBlock = /^(pre|div|p)$/i.test(node.nodeName)\n      if (isBlock) { close() }\n      for (var i = 0; i < node.childNodes.length; i++)\n        { walk(node.childNodes[i]) }\n      if (isBlock) { closing = true }\n    } else if (node.nodeType == 3) {\n      addText(node.nodeValue)\n    }\n  }\n  for (;;) {\n    walk(from)\n    if (from == to) { break }\n    from = from.nextSibling\n  }\n  return text\n}\n\nfunction domToPos(cm, node, offset) {\n  var lineNode\n  if (node == cm.display.lineDiv) {\n    lineNode = cm.display.lineDiv.childNodes[offset]\n    if (!lineNode) { return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true) }\n    node = null; offset = 0\n  } else {\n    for (lineNode = node;; lineNode = lineNode.parentNode) {\n      if (!lineNode || lineNode == cm.display.lineDiv) { return null }\n      if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) { break }\n    }\n  }\n  for (var i = 0; i < cm.display.view.length; i++) {\n    var lineView = cm.display.view[i]\n    if (lineView.node == lineNode)\n      { return locateNodeInLineView(lineView, node, offset) }\n  }\n}\n\nfunction locateNodeInLineView(lineView, node, offset) {\n  var wrapper = lineView.text.firstChild, bad = false\n  if (!node || !contains(wrapper, node)) { return badPos(Pos(lineNo(lineView.line), 0), true) }\n  if (node == wrapper) {\n    bad = true\n    node = wrapper.childNodes[offset]\n    offset = 0\n    if (!node) {\n      var line = lineView.rest ? lst(lineView.rest) : lineView.line\n      return badPos(Pos(lineNo(line), line.text.length), bad)\n    }\n  }\n\n  var textNode = node.nodeType == 3 ? node : null, topNode = node\n  if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) {\n    textNode = node.firstChild\n    if (offset) { offset = textNode.nodeValue.length }\n  }\n  while (topNode.parentNode != wrapper) { topNode = topNode.parentNode }\n  var measure = lineView.measure, maps = measure.maps\n\n  function find(textNode, topNode, offset) {\n    for (var i = -1; i < (maps ? maps.length : 0); i++) {\n      var map = i < 0 ? measure.map : maps[i]\n      for (var j = 0; j < map.length; j += 3) {\n        var curNode = map[j + 2]\n        if (curNode == textNode || curNode == topNode) {\n          var line = lineNo(i < 0 ? lineView.line : lineView.rest[i])\n          var ch = map[j] + offset\n          if (offset < 0 || curNode != textNode) { ch = map[j + (offset ? 1 : 0)] }\n          return Pos(line, ch)\n        }\n      }\n    }\n  }\n  var found = find(textNode, topNode, offset)\n  if (found) { return badPos(found, bad) }\n\n  // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems\n  for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) {\n    found = find(after, after.firstChild, 0)\n    if (found)\n      { return badPos(Pos(found.line, found.ch - dist), bad) }\n    else\n      { dist += after.textContent.length }\n  }\n  for (var before = topNode.previousSibling, dist$1 = offset; before; before = before.previousSibling) {\n    found = find(before, before.firstChild, -1)\n    if (found)\n      { return badPos(Pos(found.line, found.ch + dist$1), bad) }\n    else\n      { dist$1 += before.textContent.length }\n  }\n}\n\n// TEXTAREA INPUT STYLE\n\nvar TextareaInput = function(cm) {\n  this.cm = cm\n  // See input.poll and input.reset\n  this.prevInput = \"\"\n\n  // Flag that indicates whether we expect input to appear real soon\n  // now (after some event like 'keypress' or 'input') and are\n  // polling intensively.\n  this.pollingFast = false\n  // Self-resetting timeout for the poller\n  this.polling = new Delayed()\n  // Used to work around IE issue with selection being forgotten when focus moves away from textarea\n  this.hasSelection = false\n  this.composing = null\n};\n\nTextareaInput.prototype.init = function (display) {\n    var this$1 = this;\n\n  var input = this, cm = this.cm\n\n  // Wraps and hides input textarea\n  var div = this.wrapper = hiddenTextarea()\n  // The semihidden textarea that is focused when the editor is\n  // focused, and receives input.\n  var te = this.textarea = div.firstChild\n  display.wrapper.insertBefore(div, display.wrapper.firstChild)\n\n  // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore)\n  if (ios) { te.style.width = \"0px\" }\n\n  on(te, \"input\", function () {\n    if (ie && ie_version >= 9 && this$1.hasSelection) { this$1.hasSelection = null }\n    input.poll()\n  })\n\n  on(te, \"paste\", function (e) {\n    if (signalDOMEvent(cm, e) || handlePaste(e, cm)) { return }\n\n    cm.state.pasteIncoming = true\n    input.fastPoll()\n  })\n\n  function prepareCopyCut(e) {\n    if (signalDOMEvent(cm, e)) { return }\n    if (cm.somethingSelected()) {\n      setLastCopied({lineWise: false, text: cm.getSelections()})\n    } else if (!cm.options.lineWiseCopyCut) {\n      return\n    } else {\n      var ranges = copyableRanges(cm)\n      setLastCopied({lineWise: true, text: ranges.text})\n      if (e.type == \"cut\") {\n        cm.setSelections(ranges.ranges, null, sel_dontScroll)\n      } else {\n        input.prevInput = \"\"\n        te.value = ranges.text.join(\"\\n\")\n        selectInput(te)\n      }\n    }\n    if (e.type == \"cut\") { cm.state.cutIncoming = true }\n  }\n  on(te, \"cut\", prepareCopyCut)\n  on(te, \"copy\", prepareCopyCut)\n\n  on(display.scroller, \"paste\", function (e) {\n    if (eventInWidget(display, e) || signalDOMEvent(cm, e)) { return }\n    cm.state.pasteIncoming = true\n    input.focus()\n  })\n\n  // Prevent normal selection in the editor (we handle our own)\n  on(display.lineSpace, \"selectstart\", function (e) {\n    if (!eventInWidget(display, e)) { e_preventDefault(e) }\n  })\n\n  on(te, \"compositionstart\", function () {\n    var start = cm.getCursor(\"from\")\n    if (input.composing) { input.composing.range.clear() }\n    input.composing = {\n      start: start,\n      range: cm.markText(start, cm.getCursor(\"to\"), {className: \"CodeMirror-composing\"})\n    }\n  })\n  on(te, \"compositionend\", function () {\n    if (input.composing) {\n      input.poll()\n      input.composing.range.clear()\n      input.composing = null\n    }\n  })\n};\n\nTextareaInput.prototype.prepareSelection = function () {\n  // Redraw the selection and/or cursor\n  var cm = this.cm, display = cm.display, doc = cm.doc\n  var result = prepareSelection(cm)\n\n  // Move the hidden textarea near the cursor to prevent scrolling artifacts\n  if (cm.options.moveInputWithCursor) {\n    var headPos = cursorCoords(cm, doc.sel.primary().head, \"div\")\n    var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect()\n    result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10,\n                                        headPos.top + lineOff.top - wrapOff.top))\n    result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10,\n                                         headPos.left + lineOff.left - wrapOff.left))\n  }\n\n  return result\n};\n\nTextareaInput.prototype.showSelection = function (drawn) {\n  var cm = this.cm, display = cm.display\n  removeChildrenAndAdd(display.cursorDiv, drawn.cursors)\n  removeChildrenAndAdd(display.selectionDiv, drawn.selection)\n  if (drawn.teTop != null) {\n    this.wrapper.style.top = drawn.teTop + \"px\"\n    this.wrapper.style.left = drawn.teLeft + \"px\"\n  }\n};\n\n// Reset the input to correspond to the selection (or to be empty,\n// when not typing and nothing is selected)\nTextareaInput.prototype.reset = function (typing) {\n  if (this.contextMenuPending || this.composing) { return }\n  var cm = this.cm\n  if (cm.somethingSelected()) {\n    this.prevInput = \"\"\n    var content = cm.getSelection()\n    this.textarea.value = content\n    if (cm.state.focused) { selectInput(this.textarea) }\n    if (ie && ie_version >= 9) { this.hasSelection = content }\n  } else if (!typing) {\n    this.prevInput = this.textarea.value = \"\"\n    if (ie && ie_version >= 9) { this.hasSelection = null }\n  }\n};\n\nTextareaInput.prototype.getField = function () { return this.textarea };\n\nTextareaInput.prototype.supportsTouch = function () { return false };\n\nTextareaInput.prototype.focus = function () {\n  if (this.cm.options.readOnly != \"nocursor\" && (!mobile || activeElt() != this.textarea)) {\n    try { this.textarea.focus() }\n    catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM\n  }\n};\n\nTextareaInput.prototype.blur = function () { this.textarea.blur() };\n\nTextareaInput.prototype.resetPosition = function () {\n  this.wrapper.style.top = this.wrapper.style.left = 0\n};\n\nTextareaInput.prototype.receivedFocus = function () { this.slowPoll() };\n\n// Poll for input changes, using the normal rate of polling. This\n// runs as long as the editor is focused.\nTextareaInput.prototype.slowPoll = function () {\n    var this$1 = this;\n\n  if (this.pollingFast) { return }\n  this.polling.set(this.cm.options.pollInterval, function () {\n    this$1.poll()\n    if (this$1.cm.state.focused) { this$1.slowPoll() }\n  })\n};\n\n// When an event has just come in that is likely to add or change\n// something in the input textarea, we poll faster, to ensure that\n// the change appears on the screen quickly.\nTextareaInput.prototype.fastPoll = function () {\n  var missed = false, input = this\n  input.pollingFast = true\n  function p() {\n    var changed = input.poll()\n    if (!changed && !missed) {missed = true; input.polling.set(60, p)}\n    else {input.pollingFast = false; input.slowPoll()}\n  }\n  input.polling.set(20, p)\n};\n\n// Read input from the textarea, and update the document to match.\n// When something is selected, it is present in the textarea, and\n// selected (unless it is huge, in which case a placeholder is\n// used). When nothing is selected, the cursor sits after previously\n// seen text (can be empty), which is stored in prevInput (we must\n// not reset the textarea when typing, because that breaks IME).\nTextareaInput.prototype.poll = function () {\n    var this$1 = this;\n\n  var cm = this.cm, input = this.textarea, prevInput = this.prevInput\n  // Since this is called a *lot*, try to bail out as cheaply as\n  // possible when it is clear that nothing happened. hasSelection\n  // will be the case when there is a lot of text in the textarea,\n  // in which case reading its value would be expensive.\n  if (this.contextMenuPending || !cm.state.focused ||\n      (hasSelection(input) && !prevInput && !this.composing) ||\n      cm.isReadOnly() || cm.options.disableInput || cm.state.keySeq)\n    { return false }\n\n  var text = input.value\n  // If nothing changed, bail.\n  if (text == prevInput && !cm.somethingSelected()) { return false }\n  // Work around nonsensical selection resetting in IE9/10, and\n  // inexplicable appearance of private area unicode characters on\n  // some key combos in Mac (#2689).\n  if (ie && ie_version >= 9 && this.hasSelection === text ||\n      mac && /[\\uf700-\\uf7ff]/.test(text)) {\n    cm.display.input.reset()\n    return false\n  }\n\n  if (cm.doc.sel == cm.display.selForContextMenu) {\n    var first = text.charCodeAt(0)\n    if (first == 0x200b && !prevInput) { prevInput = \"\\u200b\" }\n    if (first == 0x21da) { this.reset(); return this.cm.execCommand(\"undo\") }\n  }\n  // Find the part of the input that is actually new\n  var same = 0, l = Math.min(prevInput.length, text.length)\n  while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) { ++same }\n\n  runInOp(cm, function () {\n    applyTextInput(cm, text.slice(same), prevInput.length - same,\n                   null, this$1.composing ? \"*compose\" : null)\n\n    // Don't leave long text in the textarea, since it makes further polling slow\n    if (text.length > 1000 || text.indexOf(\"\\n\") > -1) { input.value = this$1.prevInput = \"\" }\n    else { this$1.prevInput = text }\n\n    if (this$1.composing) {\n      this$1.composing.range.clear()\n      this$1.composing.range = cm.markText(this$1.composing.start, cm.getCursor(\"to\"),\n                                         {className: \"CodeMirror-composing\"})\n    }\n  })\n  return true\n};\n\nTextareaInput.prototype.ensurePolled = function () {\n  if (this.pollingFast && this.poll()) { this.pollingFast = false }\n};\n\nTextareaInput.prototype.onKeyPress = function () {\n  if (ie && ie_version >= 9) { this.hasSelection = null }\n  this.fastPoll()\n};\n\nTextareaInput.prototype.onContextMenu = function (e) {\n  var input = this, cm = input.cm, display = cm.display, te = input.textarea\n  var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop\n  if (!pos || presto) { return } // Opera is difficult.\n\n  // Reset the current text selection only if the click is done outside of the selection\n  // and 'resetSelectionOnContextMenu' option is true.\n  var reset = cm.options.resetSelectionOnContextMenu\n  if (reset && cm.doc.sel.contains(pos) == -1)\n    { operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll) }\n\n  var oldCSS = te.style.cssText, oldWrapperCSS = input.wrapper.style.cssText\n  input.wrapper.style.cssText = \"position: absolute\"\n  var wrapperBox = input.wrapper.getBoundingClientRect()\n  te.style.cssText = \"position: absolute; width: 30px; height: 30px;\\n      top: \" + (e.clientY - wrapperBox.top - 5) + \"px; left: \" + (e.clientX - wrapperBox.left - 5) + \"px;\\n      z-index: 1000; background: \" + (ie ? \"rgba(255, 255, 255, .05)\" : \"transparent\") + \";\\n      outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);\"\n  var oldScrollY\n  if (webkit) { oldScrollY = window.scrollY } // Work around Chrome issue (#2712)\n  display.input.focus()\n  if (webkit) { window.scrollTo(null, oldScrollY) }\n  display.input.reset()\n  // Adds \"Select all\" to context menu in FF\n  if (!cm.somethingSelected()) { te.value = input.prevInput = \" \" }\n  input.contextMenuPending = true\n  display.selForContextMenu = cm.doc.sel\n  clearTimeout(display.detectingSelectAll)\n\n  // Select-all will be greyed out if there's nothing to select, so\n  // this adds a zero-width space so that we can later check whether\n  // it got selected.\n  function prepareSelectAllHack() {\n    if (te.selectionStart != null) {\n      var selected = cm.somethingSelected()\n      var extval = \"\\u200b\" + (selected ? te.value : \"\")\n      te.value = \"\\u21da\" // Used to catch context-menu undo\n      te.value = extval\n      input.prevInput = selected ? \"\" : \"\\u200b\"\n      te.selectionStart = 1; te.selectionEnd = extval.length\n      // Re-set this, in case some other handler touched the\n      // selection in the meantime.\n      display.selForContextMenu = cm.doc.sel\n    }\n  }\n  function rehide() {\n    input.contextMenuPending = false\n    input.wrapper.style.cssText = oldWrapperCSS\n    te.style.cssText = oldCSS\n    if (ie && ie_version < 9) { display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos) }\n\n    // Try to detect the user choosing select-all\n    if (te.selectionStart != null) {\n      if (!ie || (ie && ie_version < 9)) { prepareSelectAllHack() }\n      var i = 0, poll = function () {\n        if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 &&\n            te.selectionEnd > 0 && input.prevInput == \"\\u200b\") {\n          operation(cm, selectAll)(cm)\n        } else if (i++ < 10) {\n          display.detectingSelectAll = setTimeout(poll, 500)\n        } else {\n          display.selForContextMenu = null\n          display.input.reset()\n        }\n      }\n      display.detectingSelectAll = setTimeout(poll, 200)\n    }\n  }\n\n  if (ie && ie_version >= 9) { prepareSelectAllHack() }\n  if (captureRightClick) {\n    e_stop(e)\n    var mouseup = function () {\n      off(window, \"mouseup\", mouseup)\n      setTimeout(rehide, 20)\n    }\n    on(window, \"mouseup\", mouseup)\n  } else {\n    setTimeout(rehide, 50)\n  }\n};\n\nTextareaInput.prototype.readOnlyChanged = function (val) {\n  if (!val) { this.reset() }\n  this.textarea.disabled = val == \"nocursor\"\n};\n\nTextareaInput.prototype.setUneditable = function () {};\n\nTextareaInput.prototype.needsContentAttribute = false\n\nfunction fromTextArea(textarea, options) {\n  options = options ? copyObj(options) : {}\n  options.value = textarea.value\n  if (!options.tabindex && textarea.tabIndex)\n    { options.tabindex = textarea.tabIndex }\n  if (!options.placeholder && textarea.placeholder)\n    { options.placeholder = textarea.placeholder }\n  // Set autofocus to true if this textarea is focused, or if it has\n  // autofocus and no other element is focused.\n  if (options.autofocus == null) {\n    var hasFocus = activeElt()\n    options.autofocus = hasFocus == textarea ||\n      textarea.getAttribute(\"autofocus\") != null && hasFocus == document.body\n  }\n\n  function save() {textarea.value = cm.getValue()}\n\n  var realSubmit\n  if (textarea.form) {\n    on(textarea.form, \"submit\", save)\n    // Deplorable hack to make the submit method do the right thing.\n    if (!options.leaveSubmitMethodAlone) {\n      var form = textarea.form\n      realSubmit = form.submit\n      try {\n        var wrappedSubmit = form.submit = function () {\n          save()\n          form.submit = realSubmit\n          form.submit()\n          form.submit = wrappedSubmit\n        }\n      } catch(e) {}\n    }\n  }\n\n  options.finishInit = function (cm) {\n    cm.save = save\n    cm.getTextArea = function () { return textarea; }\n    cm.toTextArea = function () {\n      cm.toTextArea = isNaN // Prevent this from being ran twice\n      save()\n      textarea.parentNode.removeChild(cm.getWrapperElement())\n      textarea.style.display = \"\"\n      if (textarea.form) {\n        off(textarea.form, \"submit\", save)\n        if (typeof textarea.form.submit == \"function\")\n          { textarea.form.submit = realSubmit }\n      }\n    }\n  }\n\n  textarea.style.display = \"none\"\n  var cm = CodeMirror(function (node) { return textarea.parentNode.insertBefore(node, textarea.nextSibling); },\n    options)\n  return cm\n}\n\nfunction addLegacyProps(CodeMirror) {\n  CodeMirror.off = off\n  CodeMirror.on = on\n  CodeMirror.wheelEventPixels = wheelEventPixels\n  CodeMirror.Doc = Doc\n  CodeMirror.splitLines = splitLinesAuto\n  CodeMirror.countColumn = countColumn\n  CodeMirror.findColumn = findColumn\n  CodeMirror.isWordChar = isWordCharBasic\n  CodeMirror.Pass = Pass\n  CodeMirror.signal = signal\n  CodeMirror.Line = Line\n  CodeMirror.changeEnd = changeEnd\n  CodeMirror.scrollbarModel = scrollbarModel\n  CodeMirror.Pos = Pos\n  CodeMirror.cmpPos = cmp\n  CodeMirror.modes = modes\n  CodeMirror.mimeModes = mimeModes\n  CodeMirror.resolveMode = resolveMode\n  CodeMirror.getMode = getMode\n  CodeMirror.modeExtensions = modeExtensions\n  CodeMirror.extendMode = extendMode\n  CodeMirror.copyState = copyState\n  CodeMirror.startState = startState\n  CodeMirror.innerMode = innerMode\n  CodeMirror.commands = commands\n  CodeMirror.keyMap = keyMap\n  CodeMirror.keyName = keyName\n  CodeMirror.isModifierKey = isModifierKey\n  CodeMirror.lookupKey = lookupKey\n  CodeMirror.normalizeKeyMap = normalizeKeyMap\n  CodeMirror.StringStream = StringStream\n  CodeMirror.SharedTextMarker = SharedTextMarker\n  CodeMirror.TextMarker = TextMarker\n  CodeMirror.LineWidget = LineWidget\n  CodeMirror.e_preventDefault = e_preventDefault\n  CodeMirror.e_stopPropagation = e_stopPropagation\n  CodeMirror.e_stop = e_stop\n  CodeMirror.addClass = addClass\n  CodeMirror.contains = contains\n  CodeMirror.rmClass = rmClass\n  CodeMirror.keyNames = keyNames\n}\n\n// EDITOR CONSTRUCTOR\n\ndefineOptions(CodeMirror)\n\naddEditorMethods(CodeMirror)\n\n// Set up methods on CodeMirror's prototype to redirect to the editor's document.\nvar dontDelegate = \"iter insert remove copy getEditor constructor\".split(\" \")\nfor (var prop in Doc.prototype) { if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)\n  { CodeMirror.prototype[prop] = (function(method) {\n    return function() {return method.apply(this.doc, arguments)}\n  })(Doc.prototype[prop]) } }\n\neventMixin(Doc)\n\n// INPUT HANDLING\n\nCodeMirror.inputStyles = {\"textarea\": TextareaInput, \"contenteditable\": ContentEditableInput}\n\n// MODE DEFINITION AND QUERYING\n\n// Extra arguments are stored as the mode's dependencies, which is\n// used by (legacy) mechanisms like loadmode.js to automatically\n// load a mode. (Preferred mechanism is the require/define calls.)\nCodeMirror.defineMode = function(name/*, mode, …*/) {\n  if (!CodeMirror.defaults.mode && name != \"null\") { CodeMirror.defaults.mode = name }\n  defineMode.apply(this, arguments)\n}\n\nCodeMirror.defineMIME = defineMIME\n\n// Minimal default mode.\nCodeMirror.defineMode(\"null\", function () { return ({token: function (stream) { return stream.skipToEnd(); }}); })\nCodeMirror.defineMIME(\"text/plain\", \"null\")\n\n// EXTENSIONS\n\nCodeMirror.defineExtension = function (name, func) {\n  CodeMirror.prototype[name] = func\n}\nCodeMirror.defineDocExtension = function (name, func) {\n  Doc.prototype[name] = func\n}\n\nCodeMirror.fromTextArea = fromTextArea\n\naddLegacyProps(CodeMirror)\n\nCodeMirror.version = \"5.28.1\"\n\nreturn CodeMirror;\n\n})));"
  },
  {
    "path": "docs/editor/scripts/codes.js",
    "content": "var CODES = {\n//hello\n\"Hello\" : `/*\nNeche UrduScript likhen.\nCode chalane k liye Run pe click karen.\n*/\n\nlikho(\"Salam, Dunya\")\n`,\n// var\n\"Variable\": `// declare variable\nrakho naam = \"Ali\"\n\n// output to screen\nlikho(naam)\n`,\n\n// foreach\n\"ForEach\": `// variable\nrakho list = [\"Ahmed\", \"Sara\", \"Qasim\"]\n\n// foreach loop. Iterate over 'list' array\nhar list k naam per{\n  // output to screen\n  likho(naam)\n}\n`,\n\n// if-else\n\"If-Else\": `// declare variable\nrakho naam = \"Asad\"\n\n// if else\nagar (naam){\n  likho(\"Salam, \" + naam)\n}\nwarna {\n  likho(\"Naam khali hai\")\n}\n`,\n\n// prompt\n\"Prompt/GetLine\": `//prompt: ask for input from user\nrakho naam = pucho(\"Apna naam likhen\")\n\n// if else\nagar (naam){\n  likho(\"Salam, \" + naam)\n}\nwarna {\n  likho(\"Naam khali hai\")\n}\n`,\n\n// function\n\"Function\": `// function is 'kaam'\nkaam salaam(naam){\n\tagar (naam){\n    likho(\"Salam, \" + naam)\n  }\n  warna {\n    likho(\"Naam khali hai\")\n  }\n}\n\n// calling function\nsalaam(\"Asad\")\n`,\n\n\"While\": `// declare a variable\nrakho a = 10\n\n// while is 'jabtak'\njabtak( a>0 ){\n\tlikho(a)\n\ta--\n}\n`,\n\"Do-While\":`// ask age until given\nkaro{\n  age = pucho(\"Apni age likhen\")\n}\njabtak(!age)\nlikho(\"Apki age \" + age + \" hai\")\n`,\n\"Recursion(Fibonacci)\": `// recursive function\nkaam fibonacci(num) {\n\t// base case\n  agar (num <= 1) bhejo 1;\n\t\n\t// recursion\n  bhejo fibonacci(num - 1) + fibonacci(num - 2);\n}\n\nlikho(fibonacci(5))\n`\n\n}"
  },
  {
    "path": "docs/editor/scripts/editor.js",
    "content": "function replaceAll(find, replace, str) {\n    function escapeRegExp(str) {\n        return str.replace(/[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]/g, \"\\\\$&\");\n    }\n    return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);\n}\n\nrequirejs.config({\n    shim: {\n        'underscore': {\n            exports: '_'\n        }\n    }\n});\nvar HEADERS;\njQuery.get('scripts/urdujs/keywords.js.txt', function(data) {\n    data = replaceAll(\"'lang sweet.js';\", \"\", data)\n    data = replaceAll(\"export syntax\", \"syntax\", data)\n    HEADERS = data\n});\n\nvar isMac = (typeof navigator !== 'undefined' && navigator.userAgent.indexOf('Mac OS X') != -1)\nif (isMac)\n    $(\"#btn-run\").text(\"Run (⌘ + Enter)\")\nelse\n    $(\"#btn-run\").text(\"Run (Ctrl + Enter)\")\n\nrequire([\"./sweet\", \"./syntax\"], function(sweet, syn) {\n    var storage_code = 'editor_code';\n    var storage_mode = 'editor_mode';\n\n    var starting_code = CODES[\"Hello\"]\n    var compileWithSourcemap = $(\"body\").attr(\"data-sourcemap\") === \"true\";\n    CodeMirror.commands.compileCode = function(cm) {\n        updateExpand();\n    }.bind(this);\n    var editor = CodeMirror.fromTextArea($('#editor')[0], {\n        lineNumbers: true,\n        //smartIndent: true,\n        matchBrackets: true,\n        indentWithTabs: true,\n        tabSize: 2,\n        indentUnit:2,\n        autofocus: true,\n        theme: 'base16-light',\n        extraKeys: {\n            \"Backspace\": \"delSpaceToPrevTabStop\",\n            \"Cmd-Left\":\"goLineLeftSmart\",\n            \"Home\":\"goLineLeftSmart\",\n            \"Cmd-Enter\":\"compileCode\",\"Ctrl-Enter\":\"compileCode\"\n\n        }\n    });\n\n    var currentStep = 1;\n\n    if (window.location.hash) {\n        editor.setValue(decodeURI(window.location.hash.slice(1)));\n    } else {\n        editor.setValue(localStorage[storage_code] ? localStorage[storage_code] : starting_code);\n    }\n    if(localStorage[storage_mode]) {\n        editor.setOption(\"keyMap\", localStorage[storage_mode]);\n    }\n\n    var output = CodeMirror.fromTextArea($('#output')[0], {\n        lineNumbers: true,\n        theme: 'base16-light',\n        readOnly: true\n    });\n\n    $('#btn-vim').click(function() {\n        editor.setOption('keyMap', 'vim');\n        editor.focus();\n        localStorage[storage_mode] = \"vim\";\n    });\n    $('#btn-emacs').click(function() {\n        editor.setOption('keyMap', 'emacs');\n        editor.focus();\n        localStorage[storage_mode] = \"emacs\";\n    });\n\n    $('#btn-step').click(function() {\n        var unparsedString = syn.prettyPrint(\n            sweet.expand(editor.getValue(), \n                         undefined, \n                         currentStep++),\n            $(\"#ck-hygiene\").prop(\"checked\"));\n        $(\"#lab-step\").text(currentStep);\n        output.setValue(unparsedString); \n    });\n\n    //populate dropdown with examples\n    for (var i in CODES){\n        $(\"#drop-examples\").append($(`<option value=${i}>${i}</option>`))\n    }\n\n\n    $(\"#drop-examples\").change((e)=>{\n        editor.setValue( CODES[$(e.target).val()] )\n    })\n\n    /*\n    var updateTimeout;\n    editor.on(\"change\", function(e) {\n        clearTimeout(updateTimeout);\n        updateTimeout = setTimeout(updateExpand, 200);\n    });\n    */\n\n    $(\"#btn-run\").on('click', ()=>{\n        updateExpand()\n    })\n\n    $(\"#btn-reset\").on('click', ()=>{\n        delete localStorage.editor_code;\n        window.location.hash = \"\";\n        window.location.reload()\n    })\n\n    // override console.log ie. likho\n    window.console.LOG = window.console.log;\n    window.console.log = function(){\n        var args = Array.prototype.slice.call(arguments);\n        var str = args.join(\" \")\n        output.setValue(output.getValue() + \"\\n\" + str)\n    }\n    \n\n    function updateExpand() {\n        \n        var code = editor.getValue();\n        var expanded, compiled, res;\n        window.location = \"#\" + encodeURI(code);\n        localStorage[storage_code] = code;\n        try {\n            //append headers for urduscript\n            code = HEADERS + \"\\n\" + code;\n            if (compileWithSourcemap) {\n                res = sweet.compile(code, {\n                    sourceMap: true,\n                    filename: \"test.js\",\n                    readableNames: true\n                });\n            } else {\n                res = sweet.compile(code, {\n                    sourceMap: false,\n                    readableNames: true\n                });\n            }\n            compiled = res.code;\n            if ($(\"#chk-transpile\")[0].checked){\n                console.log(\"Only Transpile\")\n                output.setValue(compiled);\n            }\n            else{\n                output.setValue(\"// Output\")\n                eval(compiled)\n                /*\n                console.log(\"Compiling\")\n                output.setValue(\"// Compiling...\");\n                var json = {\n                    language: 4,\n                    code: compiled,\n                    stdin:\"\"\n                };\n                console.log(json);\n                $.post(\"https://compile-public-low.remoteinterview.io/compile\", json, function(data, error, xhr) {\n                    console.log(data);\n                    if (!data.err){\n                        output.setValue(data.output + \"\\r\\n\" + data.errors)\n                    }\n                    \n\n                });\n                */\n            }\n            \n\n            $('#errors').text('');\n            $('#errors').hide();\n        } catch (e) {\n            $('#errors').text(e);\n            $('#errors').show();\n        }\n    }\n    $('#errors').hide();\n    //updateExpand();\n});\n"
  },
  {
    "path": "docs/editor/scripts/escodegen.js",
    "content": "// Generated by CommonJS Everywhere 0.8.1\n(function (global) {\n  function require(file, parentModule) {\n    if ({}.hasOwnProperty.call(require.cache, file))\n      return require.cache[file];\n    var resolved = require.resolve(file);\n    if (!resolved)\n      throw new Error('Failed to resolve module ' + file);\n    var module$ = {\n        id: file,\n        require: require,\n        filename: file,\n        exports: {},\n        loaded: false,\n        parent: parentModule,\n        children: []\n      };\n    if (parentModule)\n      parentModule.children.push(module$);\n    var dirname = file.slice(0, file.lastIndexOf('/') + 1);\n    require.cache[file] = module$.exports;\n    resolved.call(module$.exports, module$, module$.exports, dirname, file);\n    module$.loaded = true;\n    return require.cache[file] = module$.exports;\n  }\n  require.modules = {};\n  require.cache = {};\n  require.resolve = function (file) {\n    return {}.hasOwnProperty.call(require.modules, file) ? require.modules[file] : void 0;\n  };\n  require.define = function (file, fn) {\n    require.modules[file] = fn;\n  };\n  var process = function () {\n      var cwd = '/';\n      return {\n        title: 'browser',\n        version: 'v0.10.24',\n        browser: true,\n        env: {},\n        argv: [],\n        nextTick: global.setImmediate || function (fn) {\n          setTimeout(fn, 0);\n        },\n        cwd: function () {\n          return cwd;\n        },\n        chdir: function (dir) {\n          cwd = dir;\n        }\n      };\n    }();\n  require.define('/tools/entry-point.js', function (module, exports, __dirname, __filename) {\n    (function () {\n      'use strict';\n      global.escodegen = require('/escodegen.js', module);\n      escodegen.browser = true;\n    }());\n  });\n  require.define('/escodegen.js', function (module, exports, __dirname, __filename) {\n    (function () {\n      'use strict';\n      var Syntax, Precedence, BinaryPrecedence, SourceNode, estraverse, esutils, isArray, base, indent, json, renumber, hexadecimal, quotes, escapeless, newline, space, parentheses, semicolons, safeConcatenation, directive, extra, parse, sourceMap, FORMAT_MINIFY, FORMAT_DEFAULTS;\n      estraverse = require('/node_modules/estraverse/estraverse.js', module);\n      esutils = require('/node_modules/esutils/lib/utils.js', module);\n      Syntax = {\n        AssignmentExpression: 'AssignmentExpression',\n        ArrayExpression: 'ArrayExpression',\n        ArrayPattern: 'ArrayPattern',\n        ArrowFunctionExpression: 'ArrowFunctionExpression',\n        BlockStatement: 'BlockStatement',\n        BinaryExpression: 'BinaryExpression',\n        BreakStatement: 'BreakStatement',\n        CallExpression: 'CallExpression',\n        CatchClause: 'CatchClause',\n        ComprehensionBlock: 'ComprehensionBlock',\n        ComprehensionExpression: 'ComprehensionExpression',\n        ConditionalExpression: 'ConditionalExpression',\n        ContinueStatement: 'ContinueStatement',\n        DirectiveStatement: 'DirectiveStatement',\n        DoWhileStatement: 'DoWhileStatement',\n        DebuggerStatement: 'DebuggerStatement',\n        EmptyStatement: 'EmptyStatement',\n        ExportDeclaration: 'ExportDeclaration',\n        ExpressionStatement: 'ExpressionStatement',\n        ForStatement: 'ForStatement',\n        ForInStatement: 'ForInStatement',\n        FunctionDeclaration: 'FunctionDeclaration',\n        FunctionExpression: 'FunctionExpression',\n        GeneratorExpression: 'GeneratorExpression',\n        Identifier: 'Identifier',\n        IfStatement: 'IfStatement',\n        Literal: 'Literal',\n        LabeledStatement: 'LabeledStatement',\n        LogicalExpression: 'LogicalExpression',\n        MemberExpression: 'MemberExpression',\n        NewExpression: 'NewExpression',\n        ObjectExpression: 'ObjectExpression',\n        ObjectPattern: 'ObjectPattern',\n        Program: 'Program',\n        Property: 'Property',\n        ReturnStatement: 'ReturnStatement',\n        SequenceExpression: 'SequenceExpression',\n        SwitchStatement: 'SwitchStatement',\n        SwitchCase: 'SwitchCase',\n        ThisExpression: 'ThisExpression',\n        ThrowStatement: 'ThrowStatement',\n        TryStatement: 'TryStatement',\n        UnaryExpression: 'UnaryExpression',\n        UpdateExpression: 'UpdateExpression',\n        VariableDeclaration: 'VariableDeclaration',\n        VariableDeclarator: 'VariableDeclarator',\n        WhileStatement: 'WhileStatement',\n        WithStatement: 'WithStatement',\n        YieldExpression: 'YieldExpression'\n      };\n      Precedence = {\n        Sequence: 0,\n        Yield: 1,\n        Assignment: 1,\n        Conditional: 2,\n        ArrowFunction: 2,\n        LogicalOR: 3,\n        LogicalAND: 4,\n        BitwiseOR: 5,\n        BitwiseXOR: 6,\n        BitwiseAND: 7,\n        Equality: 8,\n        Relational: 9,\n        BitwiseSHIFT: 10,\n        Additive: 11,\n        Multiplicative: 12,\n        Unary: 13,\n        Postfix: 14,\n        Call: 15,\n        New: 16,\n        Member: 17,\n        Primary: 18\n      };\n      BinaryPrecedence = {\n        '||': Precedence.LogicalOR,\n        '&&': Precedence.LogicalAND,\n        '|': Precedence.BitwiseOR,\n        '^': Precedence.BitwiseXOR,\n        '&': Precedence.BitwiseAND,\n        '==': Precedence.Equality,\n        '!=': Precedence.Equality,\n        '===': Precedence.Equality,\n        '!==': Precedence.Equality,\n        'is': Precedence.Equality,\n        'isnt': Precedence.Equality,\n        '<': Precedence.Relational,\n        '>': Precedence.Relational,\n        '<=': Precedence.Relational,\n        '>=': Precedence.Relational,\n        'in': Precedence.Relational,\n        'instanceof': Precedence.Relational,\n        '<<': Precedence.BitwiseSHIFT,\n        '>>': Precedence.BitwiseSHIFT,\n        '>>>': Precedence.BitwiseSHIFT,\n        '+': Precedence.Additive,\n        '-': Precedence.Additive,\n        '*': Precedence.Multiplicative,\n        '%': Precedence.Multiplicative,\n        '/': Precedence.Multiplicative\n      };\n      function getDefaultOptions() {\n        return {\n          indent: null,\n          base: null,\n          parse: null,\n          comment: false,\n          format: {\n            indent: {\n              style: '    ',\n              base: 0,\n              adjustMultilineComment: false\n            },\n            newline: '\\n',\n            space: ' ',\n            json: false,\n            renumber: false,\n            hexadecimal: false,\n            quotes: 'single',\n            escapeless: false,\n            compact: false,\n            parentheses: true,\n            semicolons: true,\n            safeConcatenation: false\n          },\n          moz: {\n            comprehensionExpressionStartsWithAssignment: false,\n            starlessGenerator: false,\n            parenthesizedComprehensionBlock: false\n          },\n          sourceMap: null,\n          sourceMapRoot: null,\n          sourceMapWithCode: false,\n          directive: false,\n          verbatim: null\n        };\n      }\n      function stringRepeat(str, num) {\n        var result = '';\n        for (num |= 0; num > 0; num >>>= 1, str += str) {\n          if (num & 1) {\n            result += str;\n          }\n        }\n        return result;\n      }\n      isArray = Array.isArray;\n      if (!isArray) {\n        isArray = function isArray(array) {\n          return Object.prototype.toString.call(array) === '[object Array]';\n        };\n      }\n      function hasLineTerminator(str) {\n        return /[\\r\\n]/g.test(str);\n      }\n      function endsWithLineTerminator(str) {\n        var len = str.length;\n        return len && esutils.code.isLineTerminator(str.charCodeAt(len - 1));\n      }\n      function updateDeeply(target, override) {\n        var key, val;\n        function isHashObject(target) {\n          return typeof target === 'object' && target instanceof Object && !(target instanceof RegExp);\n        }\n        for (key in override) {\n          if (override.hasOwnProperty(key)) {\n            val = override[key];\n            if (isHashObject(val)) {\n              if (isHashObject(target[key])) {\n                updateDeeply(target[key], val);\n              } else {\n                target[key] = updateDeeply({}, val);\n              }\n            } else {\n              target[key] = val;\n            }\n          }\n        }\n        return target;\n      }\n      function generateNumber(value) {\n        var result, point, temp, exponent, pos;\n        if (value !== value) {\n          throw new Error('Numeric literal whose value is NaN');\n        }\n        if (value < 0 || value === 0 && 1 / value < 0) {\n          throw new Error('Numeric literal whose value is negative');\n        }\n        if (value === 1 / 0) {\n          return json ? 'null' : renumber ? '1e400' : '1e+400';\n        }\n        result = '' + value;\n        if (!renumber || result.length < 3) {\n          return result;\n        }\n        point = result.indexOf('.');\n        if (!json && result.charCodeAt(0) === 48 && point === 1) {\n          point = 0;\n          result = result.slice(1);\n        }\n        temp = result;\n        result = result.replace('e+', 'e');\n        exponent = 0;\n        if ((pos = temp.indexOf('e')) > 0) {\n          exponent = +temp.slice(pos + 1);\n          temp = temp.slice(0, pos);\n        }\n        if (point >= 0) {\n          exponent -= temp.length - point - 1;\n          temp = +(temp.slice(0, point) + temp.slice(point + 1)) + '';\n        }\n        pos = 0;\n        while (temp.charCodeAt(temp.length + pos - 1) === 48) {\n          --pos;\n        }\n        if (pos !== 0) {\n          exponent -= pos;\n          temp = temp.slice(0, pos);\n        }\n        if (exponent !== 0) {\n          temp += 'e' + exponent;\n        }\n        if ((temp.length < result.length || hexadecimal && value > 1e12 && Math.floor(value) === value && (temp = '0x' + value.toString(16)).length < result.length) && +temp === value) {\n          result = temp;\n        }\n        return result;\n      }\n      function escapeRegExpCharacter(ch, previousIsBackslash) {\n        if ((ch & ~1) === 8232) {\n          return (previousIsBackslash ? 'u' : '\\\\u') + (ch === 8232 ? '2028' : '2029');\n        } else if (ch === 10 || ch === 13) {\n          return (previousIsBackslash ? '' : '\\\\') + (ch === 10 ? 'n' : 'r');\n        }\n        return String.fromCharCode(ch);\n      }\n      function generateRegExp(reg) {\n        var match, result, flags, i, iz, ch, characterInBrack, previousIsBackslash;\n        result = reg.toString();\n        if (reg.source) {\n          match = result.match(/\\/([^/]*)$/);\n          if (!match) {\n            return result;\n          }\n          flags = match[1];\n          result = '';\n          characterInBrack = false;\n          previousIsBackslash = false;\n          for (i = 0, iz = reg.source.length; i < iz; ++i) {\n            ch = reg.source.charCodeAt(i);\n            if (!previousIsBackslash) {\n              if (characterInBrack) {\n                if (ch === 93) {\n                  characterInBrack = false;\n                }\n              } else {\n                if (ch === 47) {\n                  result += '\\\\';\n                } else if (ch === 91) {\n                  characterInBrack = true;\n                }\n              }\n              result += escapeRegExpCharacter(ch, previousIsBackslash);\n              previousIsBackslash = ch === 92;\n            } else {\n              result += escapeRegExpCharacter(ch, previousIsBackslash);\n              previousIsBackslash = false;\n            }\n          }\n          return '/' + result + '/' + flags;\n        }\n        return result;\n      }\n      function escapeAllowedCharacter(code, next) {\n        var hex, result = '\\\\';\n        switch (code) {\n        case 8:\n          result += 'b';\n          break;\n        case 12:\n          result += 'f';\n          break;\n        case 9:\n          result += 't';\n          break;\n        default:\n          hex = code.toString(16).toUpperCase();\n          if (json || code > 255) {\n            result += 'u' + '0000'.slice(hex.length) + hex;\n          } else if (code === 0 && !esutils.code.isDecimalDigit(next)) {\n            result += '0';\n          } else if (code === 11) {\n            result += 'x0B';\n          } else {\n            result += 'x' + '00'.slice(hex.length) + hex;\n          }\n          break;\n        }\n        return result;\n      }\n      function escapeDisallowedCharacter(code) {\n        var result = '\\\\';\n        switch (code) {\n        case 92:\n          result += '\\\\';\n          break;\n        case 10:\n          result += 'n';\n          break;\n        case 13:\n          result += 'r';\n          break;\n        case 8232:\n          result += 'u2028';\n          break;\n        case 8233:\n          result += 'u2029';\n          break;\n        default:\n          throw new Error('Incorrectly classified character');\n        }\n        return result;\n      }\n      function escapeDirective(str) {\n        var i, iz, code, quote;\n        quote = quotes === 'double' ? '\"' : \"'\";\n        for (i = 0, iz = str.length; i < iz; ++i) {\n          code = str.charCodeAt(i);\n          if (code === 39) {\n            quote = '\"';\n            break;\n          } else if (code === 34) {\n            quote = \"'\";\n            break;\n          } else if (code === 92) {\n            ++i;\n          }\n        }\n        return quote + str + quote;\n      }\n      function escapeString(str) {\n        var result = '', i, len, code, singleQuotes = 0, doubleQuotes = 0, single, quote;\n        for (i = 0, len = str.length; i < len; ++i) {\n          code = str.charCodeAt(i);\n          if (code === 39) {\n            ++singleQuotes;\n          } else if (code === 34) {\n            ++doubleQuotes;\n          } else if (code === 47 && json) {\n            result += '\\\\';\n          } else if (esutils.code.isLineTerminator(code) || code === 92) {\n            result += escapeDisallowedCharacter(code);\n            continue;\n          } else if (json && code < 32 || !(json || escapeless || code >= 32 && code <= 126)) {\n            result += escapeAllowedCharacter(code, str.charCodeAt(i + 1));\n            continue;\n          }\n          result += String.fromCharCode(code);\n        }\n        single = !(quotes === 'double' || quotes === 'auto' && doubleQuotes < singleQuotes);\n        quote = single ? \"'\" : '\"';\n        if (!(single ? singleQuotes : doubleQuotes)) {\n          return quote + result + quote;\n        }\n        str = result;\n        result = quote;\n        for (i = 0, len = str.length; i < len; ++i) {\n          code = str.charCodeAt(i);\n          if (code === 39 && single || code === 34 && !single) {\n            result += '\\\\';\n          }\n          result += String.fromCharCode(code);\n        }\n        return result + quote;\n      }\n      function flattenToString(arr) {\n        var i, iz, elem, result = '';\n        for (i = 0, iz = arr.length; i < iz; ++i) {\n          elem = arr[i];\n          result += isArray(elem) ? flattenToString(elem) : elem;\n        }\n        return result;\n      }\n      function toSourceNodeWhenNeeded(generated, node) {\n        if (!sourceMap) {\n          if (isArray(generated)) {\n            return flattenToString(generated);\n          } else {\n            return generated;\n          }\n        }\n        if (node == null) {\n          if (generated instanceof SourceNode) {\n            return generated;\n          } else {\n            node = {};\n          }\n        }\n        if (node.loc == null) {\n          return new SourceNode(null, null, sourceMap, generated, node.name || null);\n        }\n        return new SourceNode(node.loc.start.line, node.loc.start.column, sourceMap === true ? node.loc.source || null : sourceMap, generated, node.name || null);\n      }\n      function noEmptySpace() {\n        return space ? space : ' ';\n      }\n      function join(left, right) {\n        var leftSource = toSourceNodeWhenNeeded(left).toString(), rightSource = toSourceNodeWhenNeeded(right).toString(), leftCharCode = leftSource.charCodeAt(leftSource.length - 1), rightCharCode = rightSource.charCodeAt(0);\n        if ((leftCharCode === 43 || leftCharCode === 45) && leftCharCode === rightCharCode || esutils.code.isIdentifierPart(leftCharCode) && esutils.code.isIdentifierPart(rightCharCode) || leftCharCode === 47 && rightCharCode === 105) {\n          return [\n            left,\n            noEmptySpace(),\n            right\n          ];\n        } else if (esutils.code.isWhiteSpace(leftCharCode) || esutils.code.isLineTerminator(leftCharCode) || esutils.code.isWhiteSpace(rightCharCode) || esutils.code.isLineTerminator(rightCharCode)) {\n          return [\n            left,\n            right\n          ];\n        }\n        return [\n          left,\n          space,\n          right\n        ];\n      }\n      function addIndent(stmt) {\n        return [\n          base,\n          stmt\n        ];\n      }\n      function withIndent(fn) {\n        var previousBase, result;\n        previousBase = base;\n        base += indent;\n        result = fn.call(this, base);\n        base = previousBase;\n        return result;\n      }\n      function calculateSpaces(str) {\n        var i;\n        for (i = str.length - 1; i >= 0; --i) {\n          if (esutils.code.isLineTerminator(str.charCodeAt(i))) {\n            break;\n          }\n        }\n        return str.length - 1 - i;\n      }\n      function adjustMultilineComment(value, specialBase) {\n        var array, i, len, line, j, spaces, previousBase, sn;\n        array = value.split(/\\r\\n|[\\r\\n]/);\n        spaces = Number.MAX_VALUE;\n        for (i = 1, len = array.length; i < len; ++i) {\n          line = array[i];\n          j = 0;\n          while (j < line.length && esutils.code.isWhiteSpace(line.charCodeAt(j))) {\n            ++j;\n          }\n          if (spaces > j) {\n            spaces = j;\n          }\n        }\n        if (typeof specialBase !== 'undefined') {\n          previousBase = base;\n          if (array[1][spaces] === '*') {\n            specialBase += ' ';\n          }\n          base = specialBase;\n        } else {\n          if (spaces & 1) {\n            --spaces;\n          }\n          previousBase = base;\n        }\n        for (i = 1, len = array.length; i < len; ++i) {\n          sn = toSourceNodeWhenNeeded(addIndent(array[i].slice(spaces)));\n          array[i] = sourceMap ? sn.join('') : sn;\n        }\n        base = previousBase;\n        return array.join('\\n');\n      }\n      function generateComment(comment, specialBase) {\n        if (comment.type === 'Line') {\n          if (endsWithLineTerminator(comment.value)) {\n            return '//' + comment.value;\n          } else {\n            return '//' + comment.value + '\\n';\n          }\n        }\n        if (extra.format.indent.adjustMultilineComment && /[\\n\\r]/.test(comment.value)) {\n          return adjustMultilineComment('/*' + comment.value + '*/', specialBase);\n        }\n        return '/*' + comment.value + '*/';\n      }\n      function addCommentsToStatement(stmt, result) {\n        var i, len, comment, save, tailingToStatement, specialBase, fragment;\n        if (stmt.leadingComments && stmt.leadingComments.length > 0) {\n          save = result;\n          comment = stmt.leadingComments[0];\n          result = [];\n          if (safeConcatenation && stmt.type === Syntax.Program && stmt.body.length === 0) {\n            result.push('\\n');\n          }\n          result.push(generateComment(comment));\n          if (!endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) {\n            result.push('\\n');\n          }\n          for (i = 1, len = stmt.leadingComments.length; i < len; ++i) {\n            comment = stmt.leadingComments[i];\n            fragment = [generateComment(comment)];\n            if (!endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) {\n              fragment.push('\\n');\n            }\n            result.push(addIndent(fragment));\n          }\n          result.push(addIndent(save));\n        }\n        if (stmt.trailingComments) {\n          tailingToStatement = !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString());\n          specialBase = stringRepeat(' ', calculateSpaces(toSourceNodeWhenNeeded([\n            base,\n            result,\n            indent\n          ]).toString()));\n          for (i = 0, len = stmt.trailingComments.length; i < len; ++i) {\n            comment = stmt.trailingComments[i];\n            if (tailingToStatement) {\n              if (i === 0) {\n                result = [\n                  result,\n                  indent\n                ];\n              } else {\n                result = [\n                  result,\n                  specialBase\n                ];\n              }\n              result.push(generateComment(comment, specialBase));\n            } else {\n              result = [\n                result,\n                addIndent(generateComment(comment))\n              ];\n            }\n            if (i !== len - 1 && !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) {\n              result = [\n                result,\n                '\\n'\n              ];\n            }\n          }\n        }\n        return result;\n      }\n      function parenthesize(text, current, should) {\n        if (current < should) {\n          return [\n            '(',\n            text,\n            ')'\n          ];\n        }\n        return text;\n      }\n      function maybeBlock(stmt, semicolonOptional, functionBody) {\n        var result, noLeadingComment;\n        noLeadingComment = !extra.comment || !stmt.leadingComments;\n        if (stmt.type === Syntax.BlockStatement && noLeadingComment) {\n          return [\n            space,\n            generateStatement(stmt, { functionBody: functionBody })\n          ];\n        }\n        if (stmt.type === Syntax.EmptyStatement && noLeadingComment) {\n          return ';';\n        }\n        withIndent(function () {\n          result = [\n            newline,\n            addIndent(generateStatement(stmt, {\n              semicolonOptional: semicolonOptional,\n              functionBody: functionBody\n            }))\n          ];\n        });\n        return result;\n      }\n      function maybeBlockSuffix(stmt, result) {\n        var ends = endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString());\n        if (stmt.type === Syntax.BlockStatement && (!extra.comment || !stmt.leadingComments) && !ends) {\n          return [\n            result,\n            space\n          ];\n        }\n        if (ends) {\n          return [\n            result,\n            base\n          ];\n        }\n        return [\n          result,\n          newline,\n          base\n        ];\n      }\n      function generateVerbatim(expr, option) {\n        var i, result;\n        result = expr[extra.verbatim].split(/\\r\\n|\\n/);\n        for (i = 1; i < result.length; i++) {\n          result[i] = newline + base + result[i];\n        }\n        result = parenthesize(result, Precedence.Sequence, option.precedence);\n        return toSourceNodeWhenNeeded(result, expr);\n      }\n      function generateIdentifier(node) {\n        return toSourceNodeWhenNeeded(node.name, node);\n      }\n      function generatePattern(node, options) {\n        var result;\n        if (node.type === Syntax.Identifier) {\n          result = generateIdentifier(node);\n        } else {\n          result = generateExpression(node, {\n            precedence: options.precedence,\n            allowIn: options.allowIn,\n            allowCall: true\n          });\n        }\n        return result;\n      }\n      function generateFunctionBody(node) {\n        var result, i, len, expr, arrow;\n        arrow = node.type === Syntax.ArrowFunctionExpression;\n        if (arrow && node.params.length === 1 && node.params[0].type === Syntax.Identifier) {\n          result = [generateIdentifier(node.params[0])];\n        } else {\n          result = ['('];\n          for (i = 0, len = node.params.length; i < len; ++i) {\n            result.push(generatePattern(node.params[i], {\n              precedence: Precedence.Assignment,\n              allowIn: true\n            }));\n            if (i + 1 < len) {\n              result.push(',' + space);\n            }\n          }\n          result.push(')');\n        }\n        if (arrow) {\n          result.push(space, '=>');\n        }\n        if (node.expression) {\n          result.push(space);\n          expr = generateExpression(node.body, {\n            precedence: Precedence.Assignment,\n            allowIn: true,\n            allowCall: true\n          });\n          if (expr.toString().charAt(0) === '{') {\n            expr = [\n              '(',\n              expr,\n              ')'\n            ];\n          }\n          result.push(expr);\n        } else {\n          result.push(maybeBlock(node.body, false, true));\n        }\n        return result;\n      }\n      function generateExpression(expr, option) {\n        var result, precedence, type, currentPrecedence, i, len, raw, fragment, multiline, leftCharCode, leftSource, rightCharCode, allowIn, allowCall, allowUnparenthesizedNew, property, isGenerator;\n        precedence = option.precedence;\n        allowIn = option.allowIn;\n        allowCall = option.allowCall;\n        type = expr.type || option.type;\n        if (extra.verbatim && expr.hasOwnProperty(extra.verbatim)) {\n          return generateVerbatim(expr, option);\n        }\n        switch (type) {\n        case Syntax.SequenceExpression:\n          result = [];\n          allowIn |= Precedence.Sequence < precedence;\n          for (i = 0, len = expr.expressions.length; i < len; ++i) {\n            result.push(generateExpression(expr.expressions[i], {\n              precedence: Precedence.Assignment,\n              allowIn: allowIn,\n              allowCall: true\n            }));\n            if (i + 1 < len) {\n              result.push(',' + space);\n            }\n          }\n          result = parenthesize(result, Precedence.Sequence, precedence);\n          break;\n        case Syntax.AssignmentExpression:\n          allowIn |= Precedence.Assignment < precedence;\n          result = parenthesize([\n            generateExpression(expr.left, {\n              precedence: Precedence.Call,\n              allowIn: allowIn,\n              allowCall: true\n            }),\n            space + expr.operator + space,\n            generateExpression(expr.right, {\n              precedence: Precedence.Assignment,\n              allowIn: allowIn,\n              allowCall: true\n            })\n          ], Precedence.Assignment, precedence);\n          break;\n        case Syntax.ArrowFunctionExpression:\n          allowIn |= Precedence.ArrowFunction < precedence;\n          result = parenthesize(generateFunctionBody(expr), Precedence.ArrowFunction, precedence);\n          break;\n        case Syntax.ConditionalExpression:\n          allowIn |= Precedence.Conditional < precedence;\n          result = parenthesize([\n            generateExpression(expr.test, {\n              precedence: Precedence.LogicalOR,\n              allowIn: allowIn,\n              allowCall: true\n            }),\n            space + '?' + space,\n            generateExpression(expr.consequent, {\n              precedence: Precedence.Assignment,\n              allowIn: allowIn,\n              allowCall: true\n            }),\n            space + ':' + space,\n            generateExpression(expr.alternate, {\n              precedence: Precedence.Assignment,\n              allowIn: allowIn,\n              allowCall: true\n            })\n          ], Precedence.Conditional, precedence);\n          break;\n        case Syntax.LogicalExpression:\n        case Syntax.BinaryExpression:\n          currentPrecedence = BinaryPrecedence[expr.operator];\n          allowIn |= currentPrecedence < precedence;\n          fragment = generateExpression(expr.left, {\n            precedence: currentPrecedence,\n            allowIn: allowIn,\n            allowCall: true\n          });\n          leftSource = fragment.toString();\n          if (leftSource.charCodeAt(leftSource.length - 1) === 47 && esutils.code.isIdentifierPart(expr.operator.charCodeAt(0))) {\n            result = [\n              fragment,\n              noEmptySpace(),\n              expr.operator\n            ];\n          } else {\n            result = join(fragment, expr.operator);\n          }\n          fragment = generateExpression(expr.right, {\n            precedence: currentPrecedence + 1,\n            allowIn: allowIn,\n            allowCall: true\n          });\n          if (expr.operator === '/' && fragment.toString().charAt(0) === '/' || expr.operator.slice(-1) === '<' && fragment.toString().slice(0, 3) === '!--') {\n            result.push(noEmptySpace(), fragment);\n          } else {\n            result = join(result, fragment);\n          }\n          if (expr.operator === 'in' && !allowIn) {\n            result = [\n              '(',\n              result,\n              ')'\n            ];\n          } else {\n            result = parenthesize(result, currentPrecedence, precedence);\n          }\n          break;\n        case Syntax.CallExpression:\n          result = [generateExpression(expr.callee, {\n              precedence: Precedence.Call,\n              allowIn: true,\n              allowCall: true,\n              allowUnparenthesizedNew: false\n            })];\n          result.push('(');\n          for (i = 0, len = expr['arguments'].length; i < len; ++i) {\n            result.push(generateExpression(expr['arguments'][i], {\n              precedence: Precedence.Assignment,\n              allowIn: true,\n              allowCall: true\n            }));\n            if (i + 1 < len) {\n              result.push(',' + space);\n            }\n          }\n          result.push(')');\n          if (!allowCall) {\n            result = [\n              '(',\n              result,\n              ')'\n            ];\n          } else {\n            result = parenthesize(result, Precedence.Call, precedence);\n          }\n          break;\n        case Syntax.NewExpression:\n          len = expr['arguments'].length;\n          allowUnparenthesizedNew = option.allowUnparenthesizedNew === undefined || option.allowUnparenthesizedNew;\n          result = join('new', generateExpression(expr.callee, {\n            precedence: Precedence.New,\n            allowIn: true,\n            allowCall: false,\n            allowUnparenthesizedNew: allowUnparenthesizedNew && !parentheses && len === 0\n          }));\n          if (!allowUnparenthesizedNew || parentheses || len > 0) {\n            result.push('(');\n            for (i = 0; i < len; ++i) {\n              result.push(generateExpression(expr['arguments'][i], {\n                precedence: Precedence.Assignment,\n                allowIn: true,\n                allowCall: true\n              }));\n              if (i + 1 < len) {\n                result.push(',' + space);\n              }\n            }\n            result.push(')');\n          }\n          result = parenthesize(result, Precedence.New, precedence);\n          break;\n        case Syntax.MemberExpression:\n          result = [generateExpression(expr.object, {\n              precedence: Precedence.Call,\n              allowIn: true,\n              allowCall: allowCall,\n              allowUnparenthesizedNew: false\n            })];\n          if (expr.computed) {\n            result.push('[', generateExpression(expr.property, {\n              precedence: Precedence.Sequence,\n              allowIn: true,\n              allowCall: allowCall\n            }), ']');\n          } else {\n            if (expr.object.type === Syntax.Literal && typeof expr.object.value === 'number') {\n              fragment = toSourceNodeWhenNeeded(result).toString();\n              if (fragment.indexOf('.') < 0 && !/[eExX]/.test(fragment) && esutils.code.isDecimalDigit(fragment.charCodeAt(fragment.length - 1)) && !(fragment.length >= 2 && fragment.charCodeAt(0) === 48)) {\n                result.push('.');\n              }\n            }\n            result.push('.', generateIdentifier(expr.property));\n          }\n          result = parenthesize(result, Precedence.Member, precedence);\n          break;\n        case Syntax.UnaryExpression:\n          fragment = generateExpression(expr.argument, {\n            precedence: Precedence.Unary,\n            allowIn: true,\n            allowCall: true\n          });\n          if (space === '') {\n            result = join(expr.operator, fragment);\n          } else {\n            result = [expr.operator];\n            if (expr.operator.length > 2) {\n              result = join(result, fragment);\n            } else {\n              leftSource = toSourceNodeWhenNeeded(result).toString();\n              leftCharCode = leftSource.charCodeAt(leftSource.length - 1);\n              rightCharCode = fragment.toString().charCodeAt(0);\n              if ((leftCharCode === 43 || leftCharCode === 45) && leftCharCode === rightCharCode || esutils.code.isIdentifierPart(leftCharCode) && esutils.code.isIdentifierPart(rightCharCode)) {\n                result.push(noEmptySpace(), fragment);\n              } else {\n                result.push(fragment);\n              }\n            }\n          }\n          result = parenthesize(result, Precedence.Unary, precedence);\n          break;\n        case Syntax.YieldExpression:\n          if (expr.delegate) {\n            result = 'yield*';\n          } else {\n            result = 'yield';\n          }\n          if (expr.argument) {\n            result = join(result, generateExpression(expr.argument, {\n              precedence: Precedence.Yield,\n              allowIn: true,\n              allowCall: true\n            }));\n          }\n          result = parenthesize(result, Precedence.Yield, precedence);\n          break;\n        case Syntax.UpdateExpression:\n          if (expr.prefix) {\n            result = parenthesize([\n              expr.operator,\n              generateExpression(expr.argument, {\n                precedence: Precedence.Unary,\n                allowIn: true,\n                allowCall: true\n              })\n            ], Precedence.Unary, precedence);\n          } else {\n            result = parenthesize([\n              generateExpression(expr.argument, {\n                precedence: Precedence.Postfix,\n                allowIn: true,\n                allowCall: true\n              }),\n              expr.operator\n            ], Precedence.Postfix, precedence);\n          }\n          break;\n        case Syntax.FunctionExpression:\n          isGenerator = expr.generator && !extra.moz.starlessGenerator;\n          result = isGenerator ? 'function*' : 'function';\n          if (expr.id) {\n            result = [\n              result,\n              isGenerator ? space : noEmptySpace(),\n              generateIdentifier(expr.id),\n              generateFunctionBody(expr)\n            ];\n          } else {\n            result = [\n              result + space,\n              generateFunctionBody(expr)\n            ];\n          }\n          break;\n        case Syntax.ArrayPattern:\n        case Syntax.ArrayExpression:\n          if (!expr.elements.length) {\n            result = '[]';\n            break;\n          }\n          multiline = expr.elements.length > 1;\n          result = [\n            '[',\n            multiline ? newline : ''\n          ];\n          withIndent(function (indent) {\n            for (i = 0, len = expr.elements.length; i < len; ++i) {\n              if (!expr.elements[i]) {\n                if (multiline) {\n                  result.push(indent);\n                }\n                if (i + 1 === len) {\n                  result.push(',');\n                }\n              } else {\n                result.push(multiline ? indent : '', generateExpression(expr.elements[i], {\n                  precedence: Precedence.Assignment,\n                  allowIn: true,\n                  allowCall: true\n                }));\n              }\n              if (i + 1 < len) {\n                result.push(',' + (multiline ? newline : space));\n              }\n            }\n          });\n          if (multiline && !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) {\n            result.push(newline);\n          }\n          result.push(multiline ? base : '', ']');\n          break;\n        case Syntax.Property:\n          if (expr.kind === 'get' || expr.kind === 'set') {\n            result = [\n              expr.kind,\n              noEmptySpace(),\n              generateExpression(expr.key, {\n                precedence: Precedence.Sequence,\n                allowIn: true,\n                allowCall: true\n              }),\n              generateFunctionBody(expr.value)\n            ];\n          } else {\n            if (expr.shorthand) {\n              result = generateExpression(expr.key, {\n                precedence: Precedence.Sequence,\n                allowIn: true,\n                allowCall: true\n              });\n            } else if (expr.method) {\n              result = [];\n              if (expr.value.generator) {\n                result.push('*');\n              }\n              result.push(generateExpression(expr.key, {\n                precedence: Precedence.Sequence,\n                allowIn: true,\n                allowCall: true\n              }), generateFunctionBody(expr.value));\n            } else {\n              result = [\n                generateExpression(expr.key, {\n                  precedence: Precedence.Sequence,\n                  allowIn: true,\n                  allowCall: true\n                }),\n                ':' + space,\n                generateExpression(expr.value, {\n                  precedence: Precedence.Assignment,\n                  allowIn: true,\n                  allowCall: true\n                })\n              ];\n            }\n          }\n          break;\n        case Syntax.ObjectExpression:\n          if (!expr.properties.length) {\n            result = '{}';\n            break;\n          }\n          multiline = expr.properties.length > 1;\n          withIndent(function () {\n            fragment = generateExpression(expr.properties[0], {\n              precedence: Precedence.Sequence,\n              allowIn: true,\n              allowCall: true,\n              type: Syntax.Property\n            });\n          });\n          if (!multiline) {\n            if (!hasLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) {\n              result = [\n                '{',\n                space,\n                fragment,\n                space,\n                '}'\n              ];\n              break;\n            }\n          }\n          withIndent(function (indent) {\n            result = [\n              '{',\n              newline,\n              indent,\n              fragment\n            ];\n            if (multiline) {\n              result.push(',' + newline);\n              for (i = 1, len = expr.properties.length; i < len; ++i) {\n                result.push(indent, generateExpression(expr.properties[i], {\n                  precedence: Precedence.Sequence,\n                  allowIn: true,\n                  allowCall: true,\n                  type: Syntax.Property\n                }));\n                if (i + 1 < len) {\n                  result.push(',' + newline);\n                }\n              }\n            }\n          });\n          if (!endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) {\n            result.push(newline);\n          }\n          result.push(base, '}');\n          break;\n        case Syntax.ObjectPattern:\n          if (!expr.properties.length) {\n            result = '{}';\n            break;\n          }\n          multiline = false;\n          if (expr.properties.length === 1) {\n            property = expr.properties[0];\n            if (property.value.type !== Syntax.Identifier) {\n              multiline = true;\n            }\n          } else {\n            for (i = 0, len = expr.properties.length; i < len; ++i) {\n              property = expr.properties[i];\n              if (!property.shorthand) {\n                multiline = true;\n                break;\n              }\n            }\n          }\n          result = [\n            '{',\n            multiline ? newline : ''\n          ];\n          withIndent(function (indent) {\n            for (i = 0, len = expr.properties.length; i < len; ++i) {\n              result.push(multiline ? indent : '', generateExpression(expr.properties[i], {\n                precedence: Precedence.Sequence,\n                allowIn: true,\n                allowCall: true\n              }));\n              if (i + 1 < len) {\n                result.push(',' + (multiline ? newline : space));\n              }\n            }\n          });\n          if (multiline && !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) {\n            result.push(newline);\n          }\n          result.push(multiline ? base : '', '}');\n          break;\n        case Syntax.ThisExpression:\n          result = 'this';\n          break;\n        case Syntax.Identifier:\n          result = generateIdentifier(expr);\n          break;\n        case Syntax.Literal:\n          if (expr.hasOwnProperty('raw') && parse) {\n            try {\n              raw = parse(expr.raw).body[0].expression;\n              if (raw.type === Syntax.Literal) {\n                if (raw.value === expr.value) {\n                  result = expr.raw;\n                  break;\n                }\n              }\n            } catch (e) {\n            }\n          }\n          if (expr.value === null) {\n            result = 'null';\n            break;\n          }\n          if (typeof expr.value === 'string') {\n            result = escapeString(expr.value);\n            break;\n          }\n          if (typeof expr.value === 'number') {\n            result = generateNumber(expr.value);\n            break;\n          }\n          if (typeof expr.value === 'boolean') {\n            result = expr.value ? 'true' : 'false';\n            break;\n          }\n          result = generateRegExp(expr.value);\n          break;\n        case Syntax.GeneratorExpression:\n        case Syntax.ComprehensionExpression:\n          result = type === Syntax.GeneratorExpression ? ['('] : ['['];\n          if (extra.moz.comprehensionExpressionStartsWithAssignment) {\n            fragment = generateExpression(expr.body, {\n              precedence: Precedence.Assignment,\n              allowIn: true,\n              allowCall: true\n            });\n            result.push(fragment);\n          }\n          if (expr.blocks) {\n            withIndent(function () {\n              for (i = 0, len = expr.blocks.length; i < len; ++i) {\n                fragment = generateExpression(expr.blocks[i], {\n                  precedence: Precedence.Sequence,\n                  allowIn: true,\n                  allowCall: true\n                });\n                if (i > 0 || extra.moz.comprehensionExpressionStartsWithAssignment) {\n                  result = join(result, fragment);\n                } else {\n                  result.push(fragment);\n                }\n              }\n            });\n          }\n          if (expr.filter) {\n            result = join(result, 'if' + space);\n            fragment = generateExpression(expr.filter, {\n              precedence: Precedence.Sequence,\n              allowIn: true,\n              allowCall: true\n            });\n            if (extra.moz.parenthesizedComprehensionBlock) {\n              result = join(result, [\n                '(',\n                fragment,\n                ')'\n              ]);\n            } else {\n              result = join(result, fragment);\n            }\n          }\n          if (!extra.moz.comprehensionExpressionStartsWithAssignment) {\n            fragment = generateExpression(expr.body, {\n              precedence: Precedence.Assignment,\n              allowIn: true,\n              allowCall: true\n            });\n            result = join(result, fragment);\n          }\n          result.push(type === Syntax.GeneratorExpression ? ')' : ']');\n          break;\n        case Syntax.ComprehensionBlock:\n          if (expr.left.type === Syntax.VariableDeclaration) {\n            fragment = [\n              expr.left.kind,\n              noEmptySpace(),\n              generateStatement(expr.left.declarations[0], { allowIn: false })\n            ];\n          } else {\n            fragment = generateExpression(expr.left, {\n              precedence: Precedence.Call,\n              allowIn: true,\n              allowCall: true\n            });\n          }\n          fragment = join(fragment, expr.of ? 'of' : 'in');\n          fragment = join(fragment, generateExpression(expr.right, {\n            precedence: Precedence.Sequence,\n            allowIn: true,\n            allowCall: true\n          }));\n          if (extra.moz.parenthesizedComprehensionBlock) {\n            result = [\n              'for' + space + '(',\n              fragment,\n              ')'\n            ];\n          } else {\n            result = join('for' + space, fragment);\n          }\n          break;\n        default:\n          throw new Error('Unknown expression type: ' + expr.type);\n        }\n        return toSourceNodeWhenNeeded(result, expr);\n      }\n      function generateStatement(stmt, option) {\n        var i, len, result, node, allowIn, functionBody, directiveContext, fragment, semicolon, isGenerator;\n        allowIn = true;\n        semicolon = ';';\n        functionBody = false;\n        directiveContext = false;\n        if (option) {\n          allowIn = option.allowIn === undefined || option.allowIn;\n          if (!semicolons && option.semicolonOptional === true) {\n            semicolon = '';\n          }\n          functionBody = option.functionBody;\n          directiveContext = option.directiveContext;\n        }\n        switch (stmt.type) {\n        case Syntax.BlockStatement:\n          result = [\n            '{',\n            newline\n          ];\n          withIndent(function () {\n            for (i = 0, len = stmt.body.length; i < len; ++i) {\n              fragment = addIndent(generateStatement(stmt.body[i], {\n                semicolonOptional: i === len - 1,\n                directiveContext: functionBody\n              }));\n              result.push(fragment);\n              if (!endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) {\n                result.push(newline);\n              }\n            }\n          });\n          result.push(addIndent('}'));\n          break;\n        case Syntax.BreakStatement:\n          if (stmt.label) {\n            result = 'break ' + stmt.label.name + semicolon;\n          } else {\n            result = 'break' + semicolon;\n          }\n          break;\n        case Syntax.ContinueStatement:\n          if (stmt.label) {\n            result = 'continue ' + stmt.label.name + semicolon;\n          } else {\n            result = 'continue' + semicolon;\n          }\n          break;\n        case Syntax.DirectiveStatement:\n          if (stmt.raw) {\n            result = stmt.raw + semicolon;\n          } else {\n            result = escapeDirective(stmt.directive) + semicolon;\n          }\n          break;\n        case Syntax.DoWhileStatement:\n          result = join('do', maybeBlock(stmt.body));\n          result = maybeBlockSuffix(stmt.body, result);\n          result = join(result, [\n            'while' + space + '(',\n            generateExpression(stmt.test, {\n              precedence: Precedence.Sequence,\n              allowIn: true,\n              allowCall: true\n            }),\n            ')' + semicolon\n          ]);\n          break;\n        case Syntax.CatchClause:\n          withIndent(function () {\n            var guard;\n            result = [\n              'catch' + space + '(',\n              generateExpression(stmt.param, {\n                precedence: Precedence.Sequence,\n                allowIn: true,\n                allowCall: true\n              }),\n              ')'\n            ];\n            if (stmt.guard) {\n              guard = generateExpression(stmt.guard, {\n                precedence: Precedence.Sequence,\n                allowIn: true,\n                allowCall: true\n              });\n              result.splice(2, 0, ' if ', guard);\n            }\n          });\n          result.push(maybeBlock(stmt.body));\n          break;\n        case Syntax.DebuggerStatement:\n          result = 'debugger' + semicolon;\n          break;\n        case Syntax.EmptyStatement:\n          result = ';';\n          break;\n        case Syntax.ExportDeclaration:\n          result = 'export ';\n          if (stmt.declaration) {\n            result = [\n              result,\n              generateStatement(stmt.declaration, { semicolonOptional: semicolon === '' })\n            ];\n            break;\n          }\n          break;\n        case Syntax.ExpressionStatement:\n          result = [generateExpression(stmt.expression, {\n              precedence: Precedence.Sequence,\n              allowIn: true,\n              allowCall: true\n            })];\n          fragment = toSourceNodeWhenNeeded(result).toString();\n          if (fragment.charAt(0) === '{' || fragment.slice(0, 8) === 'function' && '* ('.indexOf(fragment.charAt(8)) >= 0 || directive && directiveContext && stmt.expression.type === Syntax.Literal && typeof stmt.expression.value === 'string') {\n            result = [\n              '(',\n              result,\n              ')' + semicolon\n            ];\n          } else {\n            result.push(semicolon);\n          }\n          break;\n        case Syntax.VariableDeclarator:\n          if (stmt.init) {\n            result = [\n              generateExpression(stmt.id, {\n                precedence: Precedence.Assignment,\n                allowIn: allowIn,\n                allowCall: true\n              }),\n              space,\n              '=',\n              space,\n              generateExpression(stmt.init, {\n                precedence: Precedence.Assignment,\n                allowIn: allowIn,\n                allowCall: true\n              })\n            ];\n          } else {\n            result = generatePattern(stmt.id, {\n              precedence: Precedence.Assignment,\n              allowIn: allowIn\n            });\n          }\n          break;\n        case Syntax.VariableDeclaration:\n          result = [stmt.kind];\n          if (stmt.declarations.length === 1 && stmt.declarations[0].init && stmt.declarations[0].init.type === Syntax.FunctionExpression) {\n            result.push(noEmptySpace(), generateStatement(stmt.declarations[0], { allowIn: allowIn }));\n          } else {\n            withIndent(function () {\n              node = stmt.declarations[0];\n              if (extra.comment && node.leadingComments) {\n                result.push('\\n', addIndent(generateStatement(node, { allowIn: allowIn })));\n              } else {\n                result.push(noEmptySpace(), generateStatement(node, { allowIn: allowIn }));\n              }\n              for (i = 1, len = stmt.declarations.length; i < len; ++i) {\n                node = stmt.declarations[i];\n                if (extra.comment && node.leadingComments) {\n                  result.push(',' + newline, addIndent(generateStatement(node, { allowIn: allowIn })));\n                } else {\n                  result.push(',' + space, generateStatement(node, { allowIn: allowIn }));\n                }\n              }\n            });\n          }\n          result.push(semicolon);\n          break;\n        case Syntax.ThrowStatement:\n          result = [\n            join('throw', generateExpression(stmt.argument, {\n              precedence: Precedence.Sequence,\n              allowIn: true,\n              allowCall: true\n            })),\n            semicolon\n          ];\n          break;\n        case Syntax.TryStatement:\n          result = [\n            'try',\n            maybeBlock(stmt.block)\n          ];\n          result = maybeBlockSuffix(stmt.block, result);\n          if (stmt.handlers) {\n            for (i = 0, len = stmt.handlers.length; i < len; ++i) {\n              result = join(result, generateStatement(stmt.handlers[i]));\n              if (stmt.finalizer || i + 1 !== len) {\n                result = maybeBlockSuffix(stmt.handlers[i].body, result);\n              }\n            }\n          } else {\n            stmt.guardedHandlers = stmt.guardedHandlers || [];\n            for (i = 0, len = stmt.guardedHandlers.length; i < len; ++i) {\n              result = join(result, generateStatement(stmt.guardedHandlers[i]));\n              if (stmt.finalizer || i + 1 !== len) {\n                result = maybeBlockSuffix(stmt.guardedHandlers[i].body, result);\n              }\n            }\n            if (stmt.handler) {\n              if (isArray(stmt.handler)) {\n                for (i = 0, len = stmt.handler.length; i < len; ++i) {\n                  result = join(result, generateStatement(stmt.handler[i]));\n                  if (stmt.finalizer || i + 1 !== len) {\n                    result = maybeBlockSuffix(stmt.handler[i].body, result);\n                  }\n                }\n              } else {\n                result = join(result, generateStatement(stmt.handler));\n                if (stmt.finalizer) {\n                  result = maybeBlockSuffix(stmt.handler.body, result);\n                }\n              }\n            }\n          }\n          if (stmt.finalizer) {\n            result = join(result, [\n              'finally',\n              maybeBlock(stmt.finalizer)\n            ]);\n          }\n          break;\n        case Syntax.SwitchStatement:\n          withIndent(function () {\n            result = [\n              'switch' + space + '(',\n              generateExpression(stmt.discriminant, {\n                precedence: Precedence.Sequence,\n                allowIn: true,\n                allowCall: true\n              }),\n              ')' + space + '{' + newline\n            ];\n          });\n          if (stmt.cases) {\n            for (i = 0, len = stmt.cases.length; i < len; ++i) {\n              fragment = addIndent(generateStatement(stmt.cases[i], { semicolonOptional: i === len - 1 }));\n              result.push(fragment);\n              if (!endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) {\n                result.push(newline);\n              }\n            }\n          }\n          result.push(addIndent('}'));\n          break;\n        case Syntax.SwitchCase:\n          withIndent(function () {\n            if (stmt.test) {\n              result = [\n                join('case', generateExpression(stmt.test, {\n                  precedence: Precedence.Sequence,\n                  allowIn: true,\n                  allowCall: true\n                })),\n                ':'\n              ];\n            } else {\n              result = ['default:'];\n            }\n            i = 0;\n            len = stmt.consequent.length;\n            if (len && stmt.consequent[0].type === Syntax.BlockStatement) {\n              fragment = maybeBlock(stmt.consequent[0]);\n              result.push(fragment);\n              i = 1;\n            }\n            if (i !== len && !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) {\n              result.push(newline);\n            }\n            for (; i < len; ++i) {\n              fragment = addIndent(generateStatement(stmt.consequent[i], { semicolonOptional: i === len - 1 && semicolon === '' }));\n              result.push(fragment);\n              if (i + 1 !== len && !endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) {\n                result.push(newline);\n              }\n            }\n          });\n          break;\n        case Syntax.IfStatement:\n          withIndent(function () {\n            result = [\n              'if' + space + '(',\n              generateExpression(stmt.test, {\n                precedence: Precedence.Sequence,\n                allowIn: true,\n                allowCall: true\n              }),\n              ')'\n            ];\n          });\n          if (stmt.alternate) {\n            result.push(maybeBlock(stmt.consequent));\n            result = maybeBlockSuffix(stmt.consequent, result);\n            if (stmt.alternate.type === Syntax.IfStatement) {\n              result = join(result, [\n                'else ',\n                generateStatement(stmt.alternate, { semicolonOptional: semicolon === '' })\n              ]);\n            } else {\n              result = join(result, join('else', maybeBlock(stmt.alternate, semicolon === '')));\n            }\n          } else {\n            result.push(maybeBlock(stmt.consequent, semicolon === ''));\n          }\n          break;\n        case Syntax.ForStatement:\n          withIndent(function () {\n            result = ['for' + space + '('];\n            if (stmt.init) {\n              if (stmt.init.type === Syntax.VariableDeclaration) {\n                result.push(generateStatement(stmt.init, { allowIn: false }));\n              } else {\n                result.push(generateExpression(stmt.init, {\n                  precedence: Precedence.Sequence,\n                  allowIn: false,\n                  allowCall: true\n                }), ';');\n              }\n            } else {\n              result.push(';');\n            }\n            if (stmt.test) {\n              result.push(space, generateExpression(stmt.test, {\n                precedence: Precedence.Sequence,\n                allowIn: true,\n                allowCall: true\n              }), ';');\n            } else {\n              result.push(';');\n            }\n            if (stmt.update) {\n              result.push(space, generateExpression(stmt.update, {\n                precedence: Precedence.Sequence,\n                allowIn: true,\n                allowCall: true\n              }), ')');\n            } else {\n              result.push(')');\n            }\n          });\n          result.push(maybeBlock(stmt.body, semicolon === ''));\n          break;\n        case Syntax.ForInStatement:\n          result = ['for' + space + '('];\n          withIndent(function () {\n            if (stmt.left.type === Syntax.VariableDeclaration) {\n              withIndent(function () {\n                result.push(stmt.left.kind + noEmptySpace(), generateStatement(stmt.left.declarations[0], { allowIn: false }));\n              });\n            } else {\n              result.push(generateExpression(stmt.left, {\n                precedence: Precedence.Call,\n                allowIn: true,\n                allowCall: true\n              }));\n            }\n            result = join(result, 'in');\n            result = [\n              join(result, generateExpression(stmt.right, {\n                precedence: Precedence.Sequence,\n                allowIn: true,\n                allowCall: true\n              })),\n              ')'\n            ];\n          });\n          result.push(maybeBlock(stmt.body, semicolon === ''));\n          break;\n        case Syntax.LabeledStatement:\n          result = [\n            stmt.label.name + ':',\n            maybeBlock(stmt.body, semicolon === '')\n          ];\n          break;\n        case Syntax.Program:\n          len = stmt.body.length;\n          result = [safeConcatenation && len > 0 ? '\\n' : ''];\n          for (i = 0; i < len; ++i) {\n            fragment = addIndent(generateStatement(stmt.body[i], {\n              semicolonOptional: !safeConcatenation && i === len - 1,\n              directiveContext: true\n            }));\n            result.push(fragment);\n            if (i + 1 < len && !endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) {\n              result.push(newline);\n            }\n          }\n          break;\n        case Syntax.FunctionDeclaration:\n          isGenerator = stmt.generator && !extra.moz.starlessGenerator;\n          result = [\n            isGenerator ? 'function*' : 'function',\n            isGenerator ? space : noEmptySpace(),\n            generateIdentifier(stmt.id),\n            generateFunctionBody(stmt)\n          ];\n          break;\n        case Syntax.ReturnStatement:\n          if (stmt.argument) {\n            result = [\n              join('return', generateExpression(stmt.argument, {\n                precedence: Precedence.Sequence,\n                allowIn: true,\n                allowCall: true\n              })),\n              semicolon\n            ];\n          } else {\n            result = ['return' + semicolon];\n          }\n          break;\n        case Syntax.WhileStatement:\n          withIndent(function () {\n            result = [\n              'while' + space + '(',\n              generateExpression(stmt.test, {\n                precedence: Precedence.Sequence,\n                allowIn: true,\n                allowCall: true\n              }),\n              ')'\n            ];\n          });\n          result.push(maybeBlock(stmt.body, semicolon === ''));\n          break;\n        case Syntax.WithStatement:\n          withIndent(function () {\n            result = [\n              'with' + space + '(',\n              generateExpression(stmt.object, {\n                precedence: Precedence.Sequence,\n                allowIn: true,\n                allowCall: true\n              }),\n              ')'\n            ];\n          });\n          result.push(maybeBlock(stmt.body, semicolon === ''));\n          break;\n        default:\n          throw new Error('Unknown statement type: ' + stmt.type);\n        }\n        if (extra.comment) {\n          result = addCommentsToStatement(stmt, result);\n        }\n        fragment = toSourceNodeWhenNeeded(result).toString();\n        if (stmt.type === Syntax.Program && !safeConcatenation && newline === '' && fragment.charAt(fragment.length - 1) === '\\n') {\n          result = sourceMap ? toSourceNodeWhenNeeded(result).replaceRight(/\\s+$/, '') : fragment.replace(/\\s+$/, '');\n        }\n        return toSourceNodeWhenNeeded(result, stmt);\n      }\n      function generate(node, options) {\n        var defaultOptions = getDefaultOptions(), result, pair;\n        if (options != null) {\n          if (typeof options.indent === 'string') {\n            defaultOptions.format.indent.style = options.indent;\n          }\n          if (typeof options.base === 'number') {\n            defaultOptions.format.indent.base = options.base;\n          }\n          options = updateDeeply(defaultOptions, options);\n          indent = options.format.indent.style;\n          if (typeof options.base === 'string') {\n            base = options.base;\n          } else {\n            base = stringRepeat(indent, options.format.indent.base);\n          }\n        } else {\n          options = defaultOptions;\n          indent = options.format.indent.style;\n          base = stringRepeat(indent, options.format.indent.base);\n        }\n        json = options.format.json;\n        renumber = options.format.renumber;\n        hexadecimal = json ? false : options.format.hexadecimal;\n        quotes = json ? 'double' : options.format.quotes;\n        escapeless = options.format.escapeless;\n        newline = options.format.newline;\n        space = options.format.space;\n        if (options.format.compact) {\n          newline = space = indent = base = '';\n        }\n        parentheses = options.format.parentheses;\n        semicolons = options.format.semicolons;\n        safeConcatenation = options.format.safeConcatenation;\n        directive = options.directive;\n        parse = json ? null : options.parse;\n        sourceMap = options.sourceMap;\n        extra = options;\n        if (sourceMap) {\n          if (!exports.browser) {\n            SourceNode = require('/node_modules/source-map/lib/source-map.js', module).SourceNode;\n          } else {\n            SourceNode = global.sourceMap.SourceNode;\n          }\n        }\n        switch (node.type) {\n        case Syntax.BlockStatement:\n        case Syntax.BreakStatement:\n        case Syntax.CatchClause:\n        case Syntax.ContinueStatement:\n        case Syntax.DirectiveStatement:\n        case Syntax.DoWhileStatement:\n        case Syntax.DebuggerStatement:\n        case Syntax.EmptyStatement:\n        case Syntax.ExpressionStatement:\n        case Syntax.ForStatement:\n        case Syntax.ForInStatement:\n        case Syntax.FunctionDeclaration:\n        case Syntax.IfStatement:\n        case Syntax.LabeledStatement:\n        case Syntax.Program:\n        case Syntax.ReturnStatement:\n        case Syntax.SwitchStatement:\n        case Syntax.SwitchCase:\n        case Syntax.ThrowStatement:\n        case Syntax.TryStatement:\n        case Syntax.VariableDeclaration:\n        case Syntax.VariableDeclarator:\n        case Syntax.WhileStatement:\n        case Syntax.WithStatement:\n          result = generateStatement(node);\n          break;\n        case Syntax.AssignmentExpression:\n        case Syntax.ArrayExpression:\n        case Syntax.ArrayPattern:\n        case Syntax.BinaryExpression:\n        case Syntax.CallExpression:\n        case Syntax.ConditionalExpression:\n        case Syntax.FunctionExpression:\n        case Syntax.Identifier:\n        case Syntax.Literal:\n        case Syntax.LogicalExpression:\n        case Syntax.MemberExpression:\n        case Syntax.NewExpression:\n        case Syntax.ObjectExpression:\n        case Syntax.ObjectPattern:\n        case Syntax.Property:\n        case Syntax.SequenceExpression:\n        case Syntax.ThisExpression:\n        case Syntax.UnaryExpression:\n        case Syntax.UpdateExpression:\n        case Syntax.YieldExpression:\n          result = generateExpression(node, {\n            precedence: Precedence.Sequence,\n            allowIn: true,\n            allowCall: true\n          });\n          break;\n        default:\n          throw new Error('Unknown node type: ' + node.type);\n        }\n        if (!sourceMap) {\n          return result.toString();\n        }\n        pair = result.toStringWithSourceMap({\n          file: options.file,\n          sourceRoot: options.sourceMapRoot\n        });\n        if (options.sourceContent) {\n          pair.map.setSourceContent(options.sourceMap, options.sourceContent);\n        }\n        if (options.sourceMapWithCode) {\n          return pair;\n        }\n        return pair.map.toString();\n      }\n      FORMAT_MINIFY = {\n        indent: {\n          style: '',\n          base: 0\n        },\n        renumber: true,\n        hexadecimal: true,\n        quotes: 'auto',\n        escapeless: true,\n        compact: true,\n        parentheses: false,\n        semicolons: false\n      };\n      FORMAT_DEFAULTS = getDefaultOptions().format;\n      exports.version = require('/package.json', module).version;\n      exports.generate = generate;\n      exports.attachComments = estraverse.attachComments;\n      exports.browser = false;\n      exports.FORMAT_MINIFY = FORMAT_MINIFY;\n      exports.FORMAT_DEFAULTS = FORMAT_DEFAULTS;\n    }());\n  });\n  require.define('/package.json', function (module, exports, __dirname, __filename) {\n    module.exports = {\n      'name': 'escodegen',\n      'description': 'ECMAScript code generator',\n      'homepage': 'http://github.com/Constellation/escodegen',\n      'main': 'escodegen.js',\n      'bin': {\n        'esgenerate': './bin/esgenerate.js',\n        'escodegen': './bin/escodegen.js'\n      },\n      'version': '1.1.0-dev',\n      'engines': { 'node': '>=0.4.0' },\n      'maintainers': [{\n          'name': 'Yusuke Suzuki',\n          'email': 'utatane.tea@gmail.com',\n          'web': 'http://github.com/Constellation'\n        }],\n      'repository': {\n        'type': 'git',\n        'url': 'http://github.com/Constellation/escodegen.git'\n      },\n      'dependencies': {\n        'esprima': '~1.0.4',\n        'estraverse': '~1.5.0',\n        'esutils': '~1.0.0'\n      },\n      'optionalDependencies': { 'source-map': '~0.1.30' },\n      'devDependencies': {\n        'esprima-moz': '*',\n        'commonjs-everywhere': '~0.8.0',\n        'q': '*',\n        'bower': '*',\n        'semver': '*',\n        'chai': '~1.7.2',\n        'grunt-contrib-jshint': '~0.5.0',\n        'grunt-cli': '~0.1.9',\n        'grunt': '~0.4.1',\n        'grunt-mocha-test': '~0.6.2'\n      },\n      'licenses': [{\n          'type': 'BSD',\n          'url': 'http://github.com/Constellation/escodegen/raw/master/LICENSE.BSD'\n        }],\n      'scripts': {\n        'test': 'grunt travis',\n        'unit-test': 'grunt test',\n        'lint': 'grunt lint',\n        'release': 'node tools/release.js',\n        'build-min': './node_modules/.bin/cjsify -ma path: tools/entry-point.js > escodegen.browser.min.js',\n        'build': './node_modules/.bin/cjsify -a path: tools/entry-point.js > escodegen.browser.js'\n      }\n    };\n  });\n  require.define('/node_modules/source-map/lib/source-map.js', function (module, exports, __dirname, __filename) {\n    exports.SourceMapGenerator = require('/node_modules/source-map/lib/source-map/source-map-generator.js', module).SourceMapGenerator;\n    exports.SourceMapConsumer = require('/node_modules/source-map/lib/source-map/source-map-consumer.js', module).SourceMapConsumer;\n    exports.SourceNode = require('/node_modules/source-map/lib/source-map/source-node.js', module).SourceNode;\n  });\n  require.define('/node_modules/source-map/lib/source-map/source-node.js', function (module, exports, __dirname, __filename) {\n    if (typeof define !== 'function') {\n      var define = require('/node_modules/source-map/node_modules/amdefine/amdefine.js', module)(module, require);\n    }\n    define(function (require, exports, module) {\n      var SourceMapGenerator = require('/node_modules/source-map/lib/source-map/source-map-generator.js', module).SourceMapGenerator;\n      var util = require('/node_modules/source-map/lib/source-map/util.js', module);\n      function SourceNode(aLine, aColumn, aSource, aChunks, aName) {\n        this.children = [];\n        this.sourceContents = {};\n        this.line = aLine === undefined ? null : aLine;\n        this.column = aColumn === undefined ? null : aColumn;\n        this.source = aSource === undefined ? null : aSource;\n        this.name = aName === undefined ? null : aName;\n        if (aChunks != null)\n          this.add(aChunks);\n      }\n      SourceNode.fromStringWithSourceMap = function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer) {\n        var node = new SourceNode;\n        var remainingLines = aGeneratedCode.split('\\n');\n        var lastGeneratedLine = 1, lastGeneratedColumn = 0;\n        var lastMapping = null;\n        aSourceMapConsumer.eachMapping(function (mapping) {\n          if (lastMapping === null) {\n            while (lastGeneratedLine < mapping.generatedLine) {\n              node.add(remainingLines.shift() + '\\n');\n              lastGeneratedLine++;\n            }\n            if (lastGeneratedColumn < mapping.generatedColumn) {\n              var nextLine = remainingLines[0];\n              node.add(nextLine.substr(0, mapping.generatedColumn));\n              remainingLines[0] = nextLine.substr(mapping.generatedColumn);\n              lastGeneratedColumn = mapping.generatedColumn;\n            }\n          } else {\n            if (lastGeneratedLine < mapping.generatedLine) {\n              var code = '';\n              do {\n                code += remainingLines.shift() + '\\n';\n                lastGeneratedLine++;\n                lastGeneratedColumn = 0;\n              } while (lastGeneratedLine < mapping.generatedLine);\n              if (lastGeneratedColumn < mapping.generatedColumn) {\n                var nextLine = remainingLines[0];\n                code += nextLine.substr(0, mapping.generatedColumn);\n                remainingLines[0] = nextLine.substr(mapping.generatedColumn);\n                lastGeneratedColumn = mapping.generatedColumn;\n              }\n              addMappingWithCode(lastMapping, code);\n            } else {\n              var nextLine = remainingLines[0];\n              var code = nextLine.substr(0, mapping.generatedColumn - lastGeneratedColumn);\n              remainingLines[0] = nextLine.substr(mapping.generatedColumn - lastGeneratedColumn);\n              lastGeneratedColumn = mapping.generatedColumn;\n              addMappingWithCode(lastMapping, code);\n            }\n          }\n          lastMapping = mapping;\n        }, this);\n        addMappingWithCode(lastMapping, remainingLines.join('\\n'));\n        aSourceMapConsumer.sources.forEach(function (sourceFile) {\n          var content = aSourceMapConsumer.sourceContentFor(sourceFile);\n          if (content) {\n            node.setSourceContent(sourceFile, content);\n          }\n        });\n        return node;\n        function addMappingWithCode(mapping, code) {\n          if (mapping === null || mapping.source === undefined) {\n            node.add(code);\n          } else {\n            node.add(new SourceNode(mapping.originalLine, mapping.originalColumn, mapping.source, code, mapping.name));\n          }\n        }\n      };\n      SourceNode.prototype.add = function SourceNode_add(aChunk) {\n        if (Array.isArray(aChunk)) {\n          aChunk.forEach(function (chunk) {\n            this.add(chunk);\n          }, this);\n        } else if (aChunk instanceof SourceNode || typeof aChunk === 'string') {\n          if (aChunk) {\n            this.children.push(aChunk);\n          }\n        } else {\n          throw new TypeError('Expected a SourceNode, string, or an array of SourceNodes and strings. Got ' + aChunk);\n        }\n        return this;\n      };\n      SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) {\n        if (Array.isArray(aChunk)) {\n          for (var i = aChunk.length - 1; i >= 0; i--) {\n            this.prepend(aChunk[i]);\n          }\n        } else if (aChunk instanceof SourceNode || typeof aChunk === 'string') {\n          this.children.unshift(aChunk);\n        } else {\n          throw new TypeError('Expected a SourceNode, string, or an array of SourceNodes and strings. Got ' + aChunk);\n        }\n        return this;\n      };\n      SourceNode.prototype.walk = function SourceNode_walk(aFn) {\n        var chunk;\n        for (var i = 0, len = this.children.length; i < len; i++) {\n          chunk = this.children[i];\n          if (chunk instanceof SourceNode) {\n            chunk.walk(aFn);\n          } else {\n            if (chunk !== '') {\n              aFn(chunk, {\n                source: this.source,\n                line: this.line,\n                column: this.column,\n                name: this.name\n              });\n            }\n          }\n        }\n      };\n      SourceNode.prototype.join = function SourceNode_join(aSep) {\n        var newChildren;\n        var i;\n        var len = this.children.length;\n        if (len > 0) {\n          newChildren = [];\n          for (i = 0; i < len - 1; i++) {\n            newChildren.push(this.children[i]);\n            newChildren.push(aSep);\n          }\n          newChildren.push(this.children[i]);\n          this.children = newChildren;\n        }\n        return this;\n      };\n      SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) {\n        var lastChild = this.children[this.children.length - 1];\n        if (lastChild instanceof SourceNode) {\n          lastChild.replaceRight(aPattern, aReplacement);\n        } else if (typeof lastChild === 'string') {\n          this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement);\n        } else {\n          this.children.push(''.replace(aPattern, aReplacement));\n        }\n        return this;\n      };\n      SourceNode.prototype.setSourceContent = function SourceNode_setSourceContent(aSourceFile, aSourceContent) {\n        this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent;\n      };\n      SourceNode.prototype.walkSourceContents = function SourceNode_walkSourceContents(aFn) {\n        for (var i = 0, len = this.children.length; i < len; i++) {\n          if (this.children[i] instanceof SourceNode) {\n            this.children[i].walkSourceContents(aFn);\n          }\n        }\n        var sources = Object.keys(this.sourceContents);\n        for (var i = 0, len = sources.length; i < len; i++) {\n          aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]);\n        }\n      };\n      SourceNode.prototype.toString = function SourceNode_toString() {\n        var str = '';\n        this.walk(function (chunk) {\n          str += chunk;\n        });\n        return str;\n      };\n      SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) {\n        var generated = {\n            code: '',\n            line: 1,\n            column: 0\n          };\n        var map = new SourceMapGenerator(aArgs);\n        var sourceMappingActive = false;\n        var lastOriginalSource = null;\n        var lastOriginalLine = null;\n        var lastOriginalColumn = null;\n        var lastOriginalName = null;\n        this.walk(function (chunk, original) {\n          generated.code += chunk;\n          if (original.source !== null && original.line !== null && original.column !== null) {\n            if (lastOriginalSource !== original.source || lastOriginalLine !== original.line || lastOriginalColumn !== original.column || lastOriginalName !== original.name) {\n              map.addMapping({\n                source: original.source,\n                original: {\n                  line: original.line,\n                  column: original.column\n                },\n                generated: {\n                  line: generated.line,\n                  column: generated.column\n                },\n                name: original.name\n              });\n            }\n            lastOriginalSource = original.source;\n            lastOriginalLine = original.line;\n            lastOriginalColumn = original.column;\n            lastOriginalName = original.name;\n            sourceMappingActive = true;\n          } else if (sourceMappingActive) {\n            map.addMapping({\n              generated: {\n                line: generated.line,\n                column: generated.column\n              }\n            });\n            lastOriginalSource = null;\n            sourceMappingActive = false;\n          }\n          chunk.split('').forEach(function (ch) {\n            if (ch === '\\n') {\n              generated.line++;\n              generated.column = 0;\n            } else {\n              generated.column++;\n            }\n          });\n        });\n        this.walkSourceContents(function (sourceFile, sourceContent) {\n          map.setSourceContent(sourceFile, sourceContent);\n        });\n        return {\n          code: generated.code,\n          map: map\n        };\n      };\n      exports.SourceNode = SourceNode;\n    });\n  });\n  require.define('/node_modules/source-map/lib/source-map/util.js', function (module, exports, __dirname, __filename) {\n    if (typeof define !== 'function') {\n      var define = require('/node_modules/source-map/node_modules/amdefine/amdefine.js', module)(module, require);\n    }\n    define(function (require, exports, module) {\n      function getArg(aArgs, aName, aDefaultValue) {\n        if (aName in aArgs) {\n          return aArgs[aName];\n        } else if (arguments.length === 3) {\n          return aDefaultValue;\n        } else {\n          throw new Error('\"' + aName + '\" is a required argument.');\n        }\n      }\n      exports.getArg = getArg;\n      var urlRegexp = /([\\w+\\-.]+):\\/\\/((\\w+:\\w+)@)?([\\w.]+)?(:(\\d+))?(\\S+)?/;\n      var dataUrlRegexp = /^data:.+\\,.+/;\n      function urlParse(aUrl) {\n        var match = aUrl.match(urlRegexp);\n        if (!match) {\n          return null;\n        }\n        return {\n          scheme: match[1],\n          auth: match[3],\n          host: match[4],\n          port: match[6],\n          path: match[7]\n        };\n      }\n      exports.urlParse = urlParse;\n      function urlGenerate(aParsedUrl) {\n        var url = aParsedUrl.scheme + '://';\n        if (aParsedUrl.auth) {\n          url += aParsedUrl.auth + '@';\n        }\n        if (aParsedUrl.host) {\n          url += aParsedUrl.host;\n        }\n        if (aParsedUrl.port) {\n          url += ':' + aParsedUrl.port;\n        }\n        if (aParsedUrl.path) {\n          url += aParsedUrl.path;\n        }\n        return url;\n      }\n      exports.urlGenerate = urlGenerate;\n      function join(aRoot, aPath) {\n        var url;\n        if (aPath.match(urlRegexp) || aPath.match(dataUrlRegexp)) {\n          return aPath;\n        }\n        if (aPath.charAt(0) === '/' && (url = urlParse(aRoot))) {\n          url.path = aPath;\n          return urlGenerate(url);\n        }\n        return aRoot.replace(/\\/$/, '') + '/' + aPath;\n      }\n      exports.join = join;\n      function toSetString(aStr) {\n        return '$' + aStr;\n      }\n      exports.toSetString = toSetString;\n      function fromSetString(aStr) {\n        return aStr.substr(1);\n      }\n      exports.fromSetString = fromSetString;\n      function relative(aRoot, aPath) {\n        aRoot = aRoot.replace(/\\/$/, '');\n        var url = urlParse(aRoot);\n        if (aPath.charAt(0) == '/' && url && url.path == '/') {\n          return aPath.slice(1);\n        }\n        return aPath.indexOf(aRoot + '/') === 0 ? aPath.substr(aRoot.length + 1) : aPath;\n      }\n      exports.relative = relative;\n      function strcmp(aStr1, aStr2) {\n        var s1 = aStr1 || '';\n        var s2 = aStr2 || '';\n        return (s1 > s2) - (s1 < s2);\n      }\n      function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {\n        var cmp;\n        cmp = strcmp(mappingA.source, mappingB.source);\n        if (cmp) {\n          return cmp;\n        }\n        cmp = mappingA.originalLine - mappingB.originalLine;\n        if (cmp) {\n          return cmp;\n        }\n        cmp = mappingA.originalColumn - mappingB.originalColumn;\n        if (cmp || onlyCompareOriginal) {\n          return cmp;\n        }\n        cmp = strcmp(mappingA.name, mappingB.name);\n        if (cmp) {\n          return cmp;\n        }\n        cmp = mappingA.generatedLine - mappingB.generatedLine;\n        if (cmp) {\n          return cmp;\n        }\n        return mappingA.generatedColumn - mappingB.generatedColumn;\n      }\n      ;\n      exports.compareByOriginalPositions = compareByOriginalPositions;\n      function compareByGeneratedPositions(mappingA, mappingB, onlyCompareGenerated) {\n        var cmp;\n        cmp = mappingA.generatedLine - mappingB.generatedLine;\n        if (cmp) {\n          return cmp;\n        }\n        cmp = mappingA.generatedColumn - mappingB.generatedColumn;\n        if (cmp || onlyCompareGenerated) {\n          return cmp;\n        }\n        cmp = strcmp(mappingA.source, mappingB.source);\n        if (cmp) {\n          return cmp;\n        }\n        cmp = mappingA.originalLine - mappingB.originalLine;\n        if (cmp) {\n          return cmp;\n        }\n        cmp = mappingA.originalColumn - mappingB.originalColumn;\n        if (cmp) {\n          return cmp;\n        }\n        return strcmp(mappingA.name, mappingB.name);\n      }\n      ;\n      exports.compareByGeneratedPositions = compareByGeneratedPositions;\n    });\n  });\n  require.define('/node_modules/source-map/node_modules/amdefine/amdefine.js', function (module, exports, __dirname, __filename) {\n    'use strict';\n    function amdefine(module, requireFn) {\n      'use strict';\n      var defineCache = {}, loaderCache = {}, alreadyCalled = false, path = require('path', module), makeRequire, stringRequire;\n      function trimDots(ary) {\n        var i, part;\n        for (i = 0; ary[i]; i += 1) {\n          part = ary[i];\n          if (part === '.') {\n            ary.splice(i, 1);\n            i -= 1;\n          } else if (part === '..') {\n            if (i === 1 && (ary[2] === '..' || ary[0] === '..')) {\n              break;\n            } else if (i > 0) {\n              ary.splice(i - 1, 2);\n              i -= 2;\n            }\n          }\n        }\n      }\n      function normalize(name, baseName) {\n        var baseParts;\n        if (name && name.charAt(0) === '.') {\n          if (baseName) {\n            baseParts = baseName.split('/');\n            baseParts = baseParts.slice(0, baseParts.length - 1);\n            baseParts = baseParts.concat(name.split('/'));\n            trimDots(baseParts);\n            name = baseParts.join('/');\n          }\n        }\n        return name;\n      }\n      function makeNormalize(relName) {\n        return function (name) {\n          return normalize(name, relName);\n        };\n      }\n      function makeLoad(id) {\n        function load(value) {\n          loaderCache[id] = value;\n        }\n        load.fromText = function (id, text) {\n          throw new Error('amdefine does not implement load.fromText');\n        };\n        return load;\n      }\n      makeRequire = function (systemRequire, exports, module, relId) {\n        function amdRequire(deps, callback) {\n          if (typeof deps === 'string') {\n            return stringRequire(systemRequire, exports, module, deps, relId);\n          } else {\n            deps = deps.map(function (depName) {\n              return stringRequire(systemRequire, exports, module, depName, relId);\n            });\n            process.nextTick(function () {\n              callback.apply(null, deps);\n            });\n          }\n        }\n        amdRequire.toUrl = function (filePath) {\n          if (filePath.indexOf('.') === 0) {\n            return normalize(filePath, path.dirname(module.filename));\n          } else {\n            return filePath;\n          }\n        };\n        return amdRequire;\n      };\n      requireFn = requireFn || function req() {\n        return module.require.apply(module, arguments);\n      };\n      function runFactory(id, deps, factory) {\n        var r, e, m, result;\n        if (id) {\n          e = loaderCache[id] = {};\n          m = {\n            id: id,\n            uri: __filename,\n            exports: e\n          };\n          r = makeRequire(requireFn, e, m, id);\n        } else {\n          if (alreadyCalled) {\n            throw new Error('amdefine with no module ID cannot be called more than once per file.');\n          }\n          alreadyCalled = true;\n          e = module.exports;\n          m = module;\n          r = makeRequire(requireFn, e, m, module.id);\n        }\n        if (deps) {\n          deps = deps.map(function (depName) {\n            return r(depName);\n          });\n        }\n        if (typeof factory === 'function') {\n          result = factory.apply(m.exports, deps);\n        } else {\n          result = factory;\n        }\n        if (result !== undefined) {\n          m.exports = result;\n          if (id) {\n            loaderCache[id] = m.exports;\n          }\n        }\n      }\n      stringRequire = function (systemRequire, exports, module, id, relId) {\n        var index = id.indexOf('!'), originalId = id, prefix, plugin;\n        if (index === -1) {\n          id = normalize(id, relId);\n          if (id === 'require') {\n            return makeRequire(systemRequire, exports, module, relId);\n          } else if (id === 'exports') {\n            return exports;\n          } else if (id === 'module') {\n            return module;\n          } else if (loaderCache.hasOwnProperty(id)) {\n            return loaderCache[id];\n          } else if (defineCache[id]) {\n            runFactory.apply(null, defineCache[id]);\n            return loaderCache[id];\n          } else {\n            if (systemRequire) {\n              return systemRequire(originalId);\n            } else {\n              throw new Error('No module with ID: ' + id);\n            }\n          }\n        } else {\n          prefix = id.substring(0, index);\n          id = id.substring(index + 1, id.length);\n          plugin = stringRequire(systemRequire, exports, module, prefix, relId);\n          if (plugin.normalize) {\n            id = plugin.normalize(id, makeNormalize(relId));\n          } else {\n            id = normalize(id, relId);\n          }\n          if (loaderCache[id]) {\n            return loaderCache[id];\n          } else {\n            plugin.load(id, makeRequire(systemRequire, exports, module, relId), makeLoad(id), {});\n            return loaderCache[id];\n          }\n        }\n      };\n      function define(id, deps, factory) {\n        if (Array.isArray(id)) {\n          factory = deps;\n          deps = id;\n          id = undefined;\n        } else if (typeof id !== 'string') {\n          factory = id;\n          id = deps = undefined;\n        }\n        if (deps && !Array.isArray(deps)) {\n          factory = deps;\n          deps = undefined;\n        }\n        if (!deps) {\n          deps = [\n            'require',\n            'exports',\n            'module'\n          ];\n        }\n        if (id) {\n          defineCache[id] = [\n            id,\n            deps,\n            factory\n          ];\n        } else {\n          runFactory(id, deps, factory);\n        }\n      }\n      define.require = function (id) {\n        if (loaderCache[id]) {\n          return loaderCache[id];\n        }\n        if (defineCache[id]) {\n          runFactory.apply(null, defineCache[id]);\n          return loaderCache[id];\n        }\n      };\n      define.amd = {};\n      return define;\n    }\n    module.exports = amdefine;\n  });\n  require.define('/node_modules/source-map/lib/source-map/source-map-generator.js', function (module, exports, __dirname, __filename) {\n    if (typeof define !== 'function') {\n      var define = require('/node_modules/source-map/node_modules/amdefine/amdefine.js', module)(module, require);\n    }\n    define(function (require, exports, module) {\n      var base64VLQ = require('/node_modules/source-map/lib/source-map/base64-vlq.js', module);\n      var util = require('/node_modules/source-map/lib/source-map/util.js', module);\n      var ArraySet = require('/node_modules/source-map/lib/source-map/array-set.js', module).ArraySet;\n      function SourceMapGenerator(aArgs) {\n        this._file = util.getArg(aArgs, 'file');\n        this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);\n        this._sources = new ArraySet;\n        this._names = new ArraySet;\n        this._mappings = [];\n        this._sourcesContents = null;\n      }\n      SourceMapGenerator.prototype._version = 3;\n      SourceMapGenerator.fromSourceMap = function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {\n        var sourceRoot = aSourceMapConsumer.sourceRoot;\n        var generator = new SourceMapGenerator({\n            file: aSourceMapConsumer.file,\n            sourceRoot: sourceRoot\n          });\n        aSourceMapConsumer.eachMapping(function (mapping) {\n          var newMapping = {\n              generated: {\n                line: mapping.generatedLine,\n                column: mapping.generatedColumn\n              }\n            };\n          if (mapping.source) {\n            newMapping.source = mapping.source;\n            if (sourceRoot) {\n              newMapping.source = util.relative(sourceRoot, newMapping.source);\n            }\n            newMapping.original = {\n              line: mapping.originalLine,\n              column: mapping.originalColumn\n            };\n            if (mapping.name) {\n              newMapping.name = mapping.name;\n            }\n          }\n          generator.addMapping(newMapping);\n        });\n        aSourceMapConsumer.sources.forEach(function (sourceFile) {\n          var content = aSourceMapConsumer.sourceContentFor(sourceFile);\n          if (content) {\n            generator.setSourceContent(sourceFile, content);\n          }\n        });\n        return generator;\n      };\n      SourceMapGenerator.prototype.addMapping = function SourceMapGenerator_addMapping(aArgs) {\n        var generated = util.getArg(aArgs, 'generated');\n        var original = util.getArg(aArgs, 'original', null);\n        var source = util.getArg(aArgs, 'source', null);\n        var name = util.getArg(aArgs, 'name', null);\n        this._validateMapping(generated, original, source, name);\n        if (source && !this._sources.has(source)) {\n          this._sources.add(source);\n        }\n        if (name && !this._names.has(name)) {\n          this._names.add(name);\n        }\n        this._mappings.push({\n          generatedLine: generated.line,\n          generatedColumn: generated.column,\n          originalLine: original != null && original.line,\n          originalColumn: original != null && original.column,\n          source: source,\n          name: name\n        });\n      };\n      SourceMapGenerator.prototype.setSourceContent = function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {\n        var source = aSourceFile;\n        if (this._sourceRoot) {\n          source = util.relative(this._sourceRoot, source);\n        }\n        if (aSourceContent !== null) {\n          if (!this._sourcesContents) {\n            this._sourcesContents = {};\n          }\n          this._sourcesContents[util.toSetString(source)] = aSourceContent;\n        } else {\n          delete this._sourcesContents[util.toSetString(source)];\n          if (Object.keys(this._sourcesContents).length === 0) {\n            this._sourcesContents = null;\n          }\n        }\n      };\n      SourceMapGenerator.prototype.applySourceMap = function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile) {\n        if (!aSourceFile) {\n          aSourceFile = aSourceMapConsumer.file;\n        }\n        var sourceRoot = this._sourceRoot;\n        if (sourceRoot) {\n          aSourceFile = util.relative(sourceRoot, aSourceFile);\n        }\n        var newSources = new ArraySet;\n        var newNames = new ArraySet;\n        this._mappings.forEach(function (mapping) {\n          if (mapping.source === aSourceFile && mapping.originalLine) {\n            var original = aSourceMapConsumer.originalPositionFor({\n                line: mapping.originalLine,\n                column: mapping.originalColumn\n              });\n            if (original.source !== null) {\n              if (sourceRoot) {\n                mapping.source = util.relative(sourceRoot, original.source);\n              } else {\n                mapping.source = original.source;\n              }\n              mapping.originalLine = original.line;\n              mapping.originalColumn = original.column;\n              if (original.name !== null && mapping.name !== null) {\n                mapping.name = original.name;\n              }\n            }\n          }\n          var source = mapping.source;\n          if (source && !newSources.has(source)) {\n            newSources.add(source);\n          }\n          var name = mapping.name;\n          if (name && !newNames.has(name)) {\n            newNames.add(name);\n          }\n        }, this);\n        this._sources = newSources;\n        this._names = newNames;\n        aSourceMapConsumer.sources.forEach(function (sourceFile) {\n          var content = aSourceMapConsumer.sourceContentFor(sourceFile);\n          if (content) {\n            if (sourceRoot) {\n              sourceFile = util.relative(sourceRoot, sourceFile);\n            }\n            this.setSourceContent(sourceFile, content);\n          }\n        }, this);\n      };\n      SourceMapGenerator.prototype._validateMapping = function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, aName) {\n        if (aGenerated && 'line' in aGenerated && 'column' in aGenerated && aGenerated.line > 0 && aGenerated.column >= 0 && !aOriginal && !aSource && !aName) {\n          return;\n        } else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated && aOriginal && 'line' in aOriginal && 'column' in aOriginal && aGenerated.line > 0 && aGenerated.column >= 0 && aOriginal.line > 0 && aOriginal.column >= 0 && aSource) {\n          return;\n        } else {\n          throw new Error('Invalid mapping: ' + JSON.stringify({\n            generated: aGenerated,\n            source: aSource,\n            orginal: aOriginal,\n            name: aName\n          }));\n        }\n      };\n      SourceMapGenerator.prototype._serializeMappings = function SourceMapGenerator_serializeMappings() {\n        var previousGeneratedColumn = 0;\n        var previousGeneratedLine = 1;\n        var previousOriginalColumn = 0;\n        var previousOriginalLine = 0;\n        var previousName = 0;\n        var previousSource = 0;\n        var result = '';\n        var mapping;\n        this._mappings.sort(util.compareByGeneratedPositions);\n        for (var i = 0, len = this._mappings.length; i < len; i++) {\n          mapping = this._mappings[i];\n          if (mapping.generatedLine !== previousGeneratedLine) {\n            previousGeneratedColumn = 0;\n            while (mapping.generatedLine !== previousGeneratedLine) {\n              result += ';';\n              previousGeneratedLine++;\n            }\n          } else {\n            if (i > 0) {\n              if (!util.compareByGeneratedPositions(mapping, this._mappings[i - 1])) {\n                continue;\n              }\n              result += ',';\n            }\n          }\n          result += base64VLQ.encode(mapping.generatedColumn - previousGeneratedColumn);\n          previousGeneratedColumn = mapping.generatedColumn;\n          if (mapping.source) {\n            result += base64VLQ.encode(this._sources.indexOf(mapping.source) - previousSource);\n            previousSource = this._sources.indexOf(mapping.source);\n            result += base64VLQ.encode(mapping.originalLine - 1 - previousOriginalLine);\n            previousOriginalLine = mapping.originalLine - 1;\n            result += base64VLQ.encode(mapping.originalColumn - previousOriginalColumn);\n            previousOriginalColumn = mapping.originalColumn;\n            if (mapping.name) {\n              result += base64VLQ.encode(this._names.indexOf(mapping.name) - previousName);\n              previousName = this._names.indexOf(mapping.name);\n            }\n          }\n        }\n        return result;\n      };\n      SourceMapGenerator.prototype._generateSourcesContent = function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {\n        return aSources.map(function (source) {\n          if (!this._sourcesContents) {\n            return null;\n          }\n          if (aSourceRoot) {\n            source = util.relative(aSourceRoot, source);\n          }\n          var key = util.toSetString(source);\n          return Object.prototype.hasOwnProperty.call(this._sourcesContents, key) ? this._sourcesContents[key] : null;\n        }, this);\n      };\n      SourceMapGenerator.prototype.toJSON = function SourceMapGenerator_toJSON() {\n        var map = {\n            version: this._version,\n            file: this._file,\n            sources: this._sources.toArray(),\n            names: this._names.toArray(),\n            mappings: this._serializeMappings()\n          };\n        if (this._sourceRoot) {\n          map.sourceRoot = this._sourceRoot;\n        }\n        if (this._sourcesContents) {\n          map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);\n        }\n        return map;\n      };\n      SourceMapGenerator.prototype.toString = function SourceMapGenerator_toString() {\n        return JSON.stringify(this);\n      };\n      exports.SourceMapGenerator = SourceMapGenerator;\n    });\n  });\n  require.define('/node_modules/source-map/lib/source-map/array-set.js', function (module, exports, __dirname, __filename) {\n    if (typeof define !== 'function') {\n      var define = require('/node_modules/source-map/node_modules/amdefine/amdefine.js', module)(module, require);\n    }\n    define(function (require, exports, module) {\n      var util = require('/node_modules/source-map/lib/source-map/util.js', module);\n      function ArraySet() {\n        this._array = [];\n        this._set = {};\n      }\n      ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {\n        var set = new ArraySet;\n        for (var i = 0, len = aArray.length; i < len; i++) {\n          set.add(aArray[i], aAllowDuplicates);\n        }\n        return set;\n      };\n      ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {\n        var isDuplicate = this.has(aStr);\n        var idx = this._array.length;\n        if (!isDuplicate || aAllowDuplicates) {\n          this._array.push(aStr);\n        }\n        if (!isDuplicate) {\n          this._set[util.toSetString(aStr)] = idx;\n        }\n      };\n      ArraySet.prototype.has = function ArraySet_has(aStr) {\n        return Object.prototype.hasOwnProperty.call(this._set, util.toSetString(aStr));\n      };\n      ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {\n        if (this.has(aStr)) {\n          return this._set[util.toSetString(aStr)];\n        }\n        throw new Error('\"' + aStr + '\" is not in the set.');\n      };\n      ArraySet.prototype.at = function ArraySet_at(aIdx) {\n        if (aIdx >= 0 && aIdx < this._array.length) {\n          return this._array[aIdx];\n        }\n        throw new Error('No element indexed by ' + aIdx);\n      };\n      ArraySet.prototype.toArray = function ArraySet_toArray() {\n        return this._array.slice();\n      };\n      exports.ArraySet = ArraySet;\n    });\n  });\n  require.define('/node_modules/source-map/lib/source-map/base64-vlq.js', function (module, exports, __dirname, __filename) {\n    if (typeof define !== 'function') {\n      var define = require('/node_modules/source-map/node_modules/amdefine/amdefine.js', module)(module, require);\n    }\n    define(function (require, exports, module) {\n      var base64 = require('/node_modules/source-map/lib/source-map/base64.js', module);\n      var VLQ_BASE_SHIFT = 5;\n      var VLQ_BASE = 1 << VLQ_BASE_SHIFT;\n      var VLQ_BASE_MASK = VLQ_BASE - 1;\n      var VLQ_CONTINUATION_BIT = VLQ_BASE;\n      function toVLQSigned(aValue) {\n        return aValue < 0 ? (-aValue << 1) + 1 : (aValue << 1) + 0;\n      }\n      function fromVLQSigned(aValue) {\n        var isNegative = (aValue & 1) === 1;\n        var shifted = aValue >> 1;\n        return isNegative ? -shifted : shifted;\n      }\n      exports.encode = function base64VLQ_encode(aValue) {\n        var encoded = '';\n        var digit;\n        var vlq = toVLQSigned(aValue);\n        do {\n          digit = vlq & VLQ_BASE_MASK;\n          vlq >>>= VLQ_BASE_SHIFT;\n          if (vlq > 0) {\n            digit |= VLQ_CONTINUATION_BIT;\n          }\n          encoded += base64.encode(digit);\n        } while (vlq > 0);\n        return encoded;\n      };\n      exports.decode = function base64VLQ_decode(aStr) {\n        var i = 0;\n        var strLen = aStr.length;\n        var result = 0;\n        var shift = 0;\n        var continuation, digit;\n        do {\n          if (i >= strLen) {\n            throw new Error('Expected more digits in base 64 VLQ value.');\n          }\n          digit = base64.decode(aStr.charAt(i++));\n          continuation = !!(digit & VLQ_CONTINUATION_BIT);\n          digit &= VLQ_BASE_MASK;\n          result = result + (digit << shift);\n          shift += VLQ_BASE_SHIFT;\n        } while (continuation);\n        return {\n          value: fromVLQSigned(result),\n          rest: aStr.slice(i)\n        };\n      };\n    });\n  });\n  require.define('/node_modules/source-map/lib/source-map/base64.js', function (module, exports, __dirname, __filename) {\n    if (typeof define !== 'function') {\n      var define = require('/node_modules/source-map/node_modules/amdefine/amdefine.js', module)(module, require);\n    }\n    define(function (require, exports, module) {\n      var charToIntMap = {};\n      var intToCharMap = {};\n      'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('').forEach(function (ch, index) {\n        charToIntMap[ch] = index;\n        intToCharMap[index] = ch;\n      });\n      exports.encode = function base64_encode(aNumber) {\n        if (aNumber in intToCharMap) {\n          return intToCharMap[aNumber];\n        }\n        throw new TypeError('Must be between 0 and 63: ' + aNumber);\n      };\n      exports.decode = function base64_decode(aChar) {\n        if (aChar in charToIntMap) {\n          return charToIntMap[aChar];\n        }\n        throw new TypeError('Not a valid base 64 digit: ' + aChar);\n      };\n    });\n  });\n  require.define('/node_modules/source-map/lib/source-map/source-map-consumer.js', function (module, exports, __dirname, __filename) {\n    if (typeof define !== 'function') {\n      var define = require('/node_modules/source-map/node_modules/amdefine/amdefine.js', module)(module, require);\n    }\n    define(function (require, exports, module) {\n      var util = require('/node_modules/source-map/lib/source-map/util.js', module);\n      var binarySearch = require('/node_modules/source-map/lib/source-map/binary-search.js', module);\n      var ArraySet = require('/node_modules/source-map/lib/source-map/array-set.js', module).ArraySet;\n      var base64VLQ = require('/node_modules/source-map/lib/source-map/base64-vlq.js', module);\n      function SourceMapConsumer(aSourceMap) {\n        var sourceMap = aSourceMap;\n        if (typeof aSourceMap === 'string') {\n          sourceMap = JSON.parse(aSourceMap.replace(/^\\)\\]\\}'/, ''));\n        }\n        var version = util.getArg(sourceMap, 'version');\n        var sources = util.getArg(sourceMap, 'sources');\n        var names = util.getArg(sourceMap, 'names', []);\n        var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null);\n        var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null);\n        var mappings = util.getArg(sourceMap, 'mappings');\n        var file = util.getArg(sourceMap, 'file', null);\n        if (version != this._version) {\n          throw new Error('Unsupported version: ' + version);\n        }\n        this._names = ArraySet.fromArray(names, true);\n        this._sources = ArraySet.fromArray(sources, true);\n        this.sourceRoot = sourceRoot;\n        this.sourcesContent = sourcesContent;\n        this._mappings = mappings;\n        this.file = file;\n      }\n      SourceMapConsumer.fromSourceMap = function SourceMapConsumer_fromSourceMap(aSourceMap) {\n        var smc = Object.create(SourceMapConsumer.prototype);\n        smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);\n        smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true);\n        smc.sourceRoot = aSourceMap._sourceRoot;\n        smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(), smc.sourceRoot);\n        smc.file = aSourceMap._file;\n        smc.__generatedMappings = aSourceMap._mappings.slice().sort(util.compareByGeneratedPositions);\n        smc.__originalMappings = aSourceMap._mappings.slice().sort(util.compareByOriginalPositions);\n        return smc;\n      };\n      SourceMapConsumer.prototype._version = 3;\n      Object.defineProperty(SourceMapConsumer.prototype, 'sources', {\n        get: function () {\n          return this._sources.toArray().map(function (s) {\n            return this.sourceRoot ? util.join(this.sourceRoot, s) : s;\n          }, this);\n        }\n      });\n      SourceMapConsumer.prototype.__generatedMappings = null;\n      Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {\n        get: function () {\n          if (!this.__generatedMappings) {\n            this.__generatedMappings = [];\n            this.__originalMappings = [];\n            this._parseMappings(this._mappings, this.sourceRoot);\n          }\n          return this.__generatedMappings;\n        }\n      });\n      SourceMapConsumer.prototype.__originalMappings = null;\n      Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {\n        get: function () {\n          if (!this.__originalMappings) {\n            this.__generatedMappings = [];\n            this.__originalMappings = [];\n            this._parseMappings(this._mappings, this.sourceRoot);\n          }\n          return this.__originalMappings;\n        }\n      });\n      SourceMapConsumer.prototype._parseMappings = function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {\n        var generatedLine = 1;\n        var previousGeneratedColumn = 0;\n        var previousOriginalLine = 0;\n        var previousOriginalColumn = 0;\n        var previousSource = 0;\n        var previousName = 0;\n        var mappingSeparator = /^[,;]/;\n        var str = aStr;\n        var mapping;\n        var temp;\n        while (str.length > 0) {\n          if (str.charAt(0) === ';') {\n            generatedLine++;\n            str = str.slice(1);\n            previousGeneratedColumn = 0;\n          } else if (str.charAt(0) === ',') {\n            str = str.slice(1);\n          } else {\n            mapping = {};\n            mapping.generatedLine = generatedLine;\n            temp = base64VLQ.decode(str);\n            mapping.generatedColumn = previousGeneratedColumn + temp.value;\n            previousGeneratedColumn = mapping.generatedColumn;\n            str = temp.rest;\n            if (str.length > 0 && !mappingSeparator.test(str.charAt(0))) {\n              temp = base64VLQ.decode(str);\n              mapping.source = this._sources.at(previousSource + temp.value);\n              previousSource += temp.value;\n              str = temp.rest;\n              if (str.length === 0 || mappingSeparator.test(str.charAt(0))) {\n                throw new Error('Found a source, but no line and column');\n              }\n              temp = base64VLQ.decode(str);\n              mapping.originalLine = previousOriginalLine + temp.value;\n              previousOriginalLine = mapping.originalLine;\n              mapping.originalLine += 1;\n              str = temp.rest;\n              if (str.length === 0 || mappingSeparator.test(str.charAt(0))) {\n                throw new Error('Found a source and line, but no column');\n              }\n              temp = base64VLQ.decode(str);\n              mapping.originalColumn = previousOriginalColumn + temp.value;\n              previousOriginalColumn = mapping.originalColumn;\n              str = temp.rest;\n              if (str.length > 0 && !mappingSeparator.test(str.charAt(0))) {\n                temp = base64VLQ.decode(str);\n                mapping.name = this._names.at(previousName + temp.value);\n                previousName += temp.value;\n                str = temp.rest;\n              }\n            }\n            this.__generatedMappings.push(mapping);\n            if (typeof mapping.originalLine === 'number') {\n              this.__originalMappings.push(mapping);\n            }\n          }\n        }\n        this.__originalMappings.sort(util.compareByOriginalPositions);\n      };\n      SourceMapConsumer.prototype._findMapping = function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, aColumnName, aComparator) {\n        if (aNeedle[aLineName] <= 0) {\n          throw new TypeError('Line must be greater than or equal to 1, got ' + aNeedle[aLineName]);\n        }\n        if (aNeedle[aColumnName] < 0) {\n          throw new TypeError('Column must be greater than or equal to 0, got ' + aNeedle[aColumnName]);\n        }\n        return binarySearch.search(aNeedle, aMappings, aComparator);\n      };\n      SourceMapConsumer.prototype.originalPositionFor = function SourceMapConsumer_originalPositionFor(aArgs) {\n        var needle = {\n            generatedLine: util.getArg(aArgs, 'line'),\n            generatedColumn: util.getArg(aArgs, 'column')\n          };\n        var mapping = this._findMapping(needle, this._generatedMappings, 'generatedLine', 'generatedColumn', util.compareByGeneratedPositions);\n        if (mapping) {\n          var source = util.getArg(mapping, 'source', null);\n          if (source && this.sourceRoot) {\n            source = util.join(this.sourceRoot, source);\n          }\n          return {\n            source: source,\n            line: util.getArg(mapping, 'originalLine', null),\n            column: util.getArg(mapping, 'originalColumn', null),\n            name: util.getArg(mapping, 'name', null)\n          };\n        }\n        return {\n          source: null,\n          line: null,\n          column: null,\n          name: null\n        };\n      };\n      SourceMapConsumer.prototype.sourceContentFor = function SourceMapConsumer_sourceContentFor(aSource) {\n        if (!this.sourcesContent) {\n          return null;\n        }\n        if (this.sourceRoot) {\n          aSource = util.relative(this.sourceRoot, aSource);\n        }\n        if (this._sources.has(aSource)) {\n          return this.sourcesContent[this._sources.indexOf(aSource)];\n        }\n        var url;\n        if (this.sourceRoot && (url = util.urlParse(this.sourceRoot))) {\n          var fileUriAbsPath = aSource.replace(/^file:\\/\\//, '');\n          if (url.scheme == 'file' && this._sources.has(fileUriAbsPath)) {\n            return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)];\n          }\n          if ((!url.path || url.path == '/') && this._sources.has('/' + aSource)) {\n            return this.sourcesContent[this._sources.indexOf('/' + aSource)];\n          }\n        }\n        throw new Error('\"' + aSource + '\" is not in the SourceMap.');\n      };\n      SourceMapConsumer.prototype.generatedPositionFor = function SourceMapConsumer_generatedPositionFor(aArgs) {\n        var needle = {\n            source: util.getArg(aArgs, 'source'),\n            originalLine: util.getArg(aArgs, 'line'),\n            originalColumn: util.getArg(aArgs, 'column')\n          };\n        if (this.sourceRoot) {\n          needle.source = util.relative(this.sourceRoot, needle.source);\n        }\n        var mapping = this._findMapping(needle, this._originalMappings, 'originalLine', 'originalColumn', util.compareByOriginalPositions);\n        if (mapping) {\n          return {\n            line: util.getArg(mapping, 'generatedLine', null),\n            column: util.getArg(mapping, 'generatedColumn', null)\n          };\n        }\n        return {\n          line: null,\n          column: null\n        };\n      };\n      SourceMapConsumer.GENERATED_ORDER = 1;\n      SourceMapConsumer.ORIGINAL_ORDER = 2;\n      SourceMapConsumer.prototype.eachMapping = function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) {\n        var context = aContext || null;\n        var order = aOrder || SourceMapConsumer.GENERATED_ORDER;\n        var mappings;\n        switch (order) {\n        case SourceMapConsumer.GENERATED_ORDER:\n          mappings = this._generatedMappings;\n          break;\n        case SourceMapConsumer.ORIGINAL_ORDER:\n          mappings = this._originalMappings;\n          break;\n        default:\n          throw new Error('Unknown order of iteration.');\n        }\n        var sourceRoot = this.sourceRoot;\n        mappings.map(function (mapping) {\n          var source = mapping.source;\n          if (source && sourceRoot) {\n            source = util.join(sourceRoot, source);\n          }\n          return {\n            source: source,\n            generatedLine: mapping.generatedLine,\n            generatedColumn: mapping.generatedColumn,\n            originalLine: mapping.originalLine,\n            originalColumn: mapping.originalColumn,\n            name: mapping.name\n          };\n        }).forEach(aCallback, context);\n      };\n      exports.SourceMapConsumer = SourceMapConsumer;\n    });\n  });\n  require.define('/node_modules/source-map/lib/source-map/binary-search.js', function (module, exports, __dirname, __filename) {\n    if (typeof define !== 'function') {\n      var define = require('/node_modules/source-map/node_modules/amdefine/amdefine.js', module)(module, require);\n    }\n    define(function (require, exports, module) {\n      function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare) {\n        var mid = Math.floor((aHigh - aLow) / 2) + aLow;\n        var cmp = aCompare(aNeedle, aHaystack[mid], true);\n        if (cmp === 0) {\n          return aHaystack[mid];\n        } else if (cmp > 0) {\n          if (aHigh - mid > 1) {\n            return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare);\n          }\n          return aHaystack[mid];\n        } else {\n          if (mid - aLow > 1) {\n            return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare);\n          }\n          return aLow < 0 ? null : aHaystack[aLow];\n        }\n      }\n      exports.search = function search(aNeedle, aHaystack, aCompare) {\n        return aHaystack.length > 0 ? recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, aCompare) : null;\n      };\n    });\n  });\n  require.define('/node_modules/esutils/lib/utils.js', function (module, exports, __dirname, __filename) {\n    (function () {\n      'use strict';\n      exports.code = require('/node_modules/esutils/lib/code.js', module);\n      exports.keyword = require('/node_modules/esutils/lib/keyword.js', module);\n    }());\n  });\n  require.define('/node_modules/esutils/lib/keyword.js', function (module, exports, __dirname, __filename) {\n    (function () {\n      'use strict';\n      var code = require('/node_modules/esutils/lib/code.js', module);\n      function isStrictModeReservedWordES6(id) {\n        switch (id) {\n        case 'implements':\n        case 'interface':\n        case 'package':\n        case 'private':\n        case 'protected':\n        case 'public':\n        case 'static':\n        case 'let':\n          return true;\n        default:\n          return false;\n        }\n      }\n      function isKeywordES5(id, strict) {\n        if (!strict && id === 'yield') {\n          return false;\n        }\n        return isKeywordES6(id, strict);\n      }\n      function isKeywordES6(id, strict) {\n        if (strict && isStrictModeReservedWordES6(id)) {\n          return true;\n        }\n        switch (id.length) {\n        case 2:\n          return id === 'if' || id === 'in' || id === 'do';\n        case 3:\n          return id === 'var' || id === 'for' || id === 'new' || id === 'try';\n        case 4:\n          return id === 'this' || id === 'else' || id === 'case' || id === 'void' || id === 'with' || id === 'enum';\n        case 5:\n          return id === 'while' || id === 'break' || id === 'catch' || id === 'throw' || id === 'const' || id === 'yield' || id === 'class' || id === 'super';\n        case 6:\n          return id === 'return' || id === 'typeof' || id === 'delete' || id === 'switch' || id === 'export' || id === 'import';\n        case 7:\n          return id === 'default' || id === 'finally' || id === 'extends';\n        case 8:\n          return id === 'function' || id === 'continue' || id === 'debugger';\n        case 10:\n          return id === 'instanceof';\n        default:\n          return false;\n        }\n      }\n      function isRestrictedWord(id) {\n        return id === 'eval' || id === 'arguments';\n      }\n      function isIdentifierName(id) {\n        var i, iz, ch;\n        if (id.length === 0) {\n          return false;\n        }\n        ch = id.charCodeAt(0);\n        if (!code.isIdentifierStart(ch) || ch === 92) {\n          return false;\n        }\n        for (i = 1, iz = id.length; i < iz; ++i) {\n          ch = id.charCodeAt(i);\n          if (!code.isIdentifierPart(ch) || ch === 92) {\n            return false;\n          }\n        }\n        return true;\n      }\n      module.exports = {\n        isKeywordES5: isKeywordES5,\n        isKeywordES6: isKeywordES6,\n        isRestrictedWord: isRestrictedWord,\n        isIdentifierName: isIdentifierName\n      };\n    }());\n  });\n  require.define('/node_modules/esutils/lib/code.js', function (module, exports, __dirname, __filename) {\n    (function () {\n      'use strict';\n      var Regex;\n      Regex = {\n        NonAsciiIdentifierStart: new RegExp('[\\xaa\\xb5\\xba\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\u02c1\\u02c6-\\u02d1\\u02e0-\\u02e4\\u02ec\\u02ee\\u0370-\\u0374\\u0376\\u0377\\u037a-\\u037d\\u0386\\u0388-\\u038a\\u038c\\u038e-\\u03a1\\u03a3-\\u03f5\\u03f7-\\u0481\\u048a-\\u0527\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05d0-\\u05ea\\u05f0-\\u05f2\\u0620-\\u064a\\u066e\\u066f\\u0671-\\u06d3\\u06d5\\u06e5\\u06e6\\u06ee\\u06ef\\u06fa-\\u06fc\\u06ff\\u0710\\u0712-\\u072f\\u074d-\\u07a5\\u07b1\\u07ca-\\u07ea\\u07f4\\u07f5\\u07fa\\u0800-\\u0815\\u081a\\u0824\\u0828\\u0840-\\u0858\\u08a0\\u08a2-\\u08ac\\u0904-\\u0939\\u093d\\u0950\\u0958-\\u0961\\u0971-\\u0977\\u0979-\\u097f\\u0985-\\u098c\\u098f\\u0990\\u0993-\\u09a8\\u09aa-\\u09b0\\u09b2\\u09b6-\\u09b9\\u09bd\\u09ce\\u09dc\\u09dd\\u09df-\\u09e1\\u09f0\\u09f1\\u0a05-\\u0a0a\\u0a0f\\u0a10\\u0a13-\\u0a28\\u0a2a-\\u0a30\\u0a32\\u0a33\\u0a35\\u0a36\\u0a38\\u0a39\\u0a59-\\u0a5c\\u0a5e\\u0a72-\\u0a74\\u0a85-\\u0a8d\\u0a8f-\\u0a91\\u0a93-\\u0aa8\\u0aaa-\\u0ab0\\u0ab2\\u0ab3\\u0ab5-\\u0ab9\\u0abd\\u0ad0\\u0ae0\\u0ae1\\u0b05-\\u0b0c\\u0b0f\\u0b10\\u0b13-\\u0b28\\u0b2a-\\u0b30\\u0b32\\u0b33\\u0b35-\\u0b39\\u0b3d\\u0b5c\\u0b5d\\u0b5f-\\u0b61\\u0b71\\u0b83\\u0b85-\\u0b8a\\u0b8e-\\u0b90\\u0b92-\\u0b95\\u0b99\\u0b9a\\u0b9c\\u0b9e\\u0b9f\\u0ba3\\u0ba4\\u0ba8-\\u0baa\\u0bae-\\u0bb9\\u0bd0\\u0c05-\\u0c0c\\u0c0e-\\u0c10\\u0c12-\\u0c28\\u0c2a-\\u0c33\\u0c35-\\u0c39\\u0c3d\\u0c58\\u0c59\\u0c60\\u0c61\\u0c85-\\u0c8c\\u0c8e-\\u0c90\\u0c92-\\u0ca8\\u0caa-\\u0cb3\\u0cb5-\\u0cb9\\u0cbd\\u0cde\\u0ce0\\u0ce1\\u0cf1\\u0cf2\\u0d05-\\u0d0c\\u0d0e-\\u0d10\\u0d12-\\u0d3a\\u0d3d\\u0d4e\\u0d60\\u0d61\\u0d7a-\\u0d7f\\u0d85-\\u0d96\\u0d9a-\\u0db1\\u0db3-\\u0dbb\\u0dbd\\u0dc0-\\u0dc6\\u0e01-\\u0e30\\u0e32\\u0e33\\u0e40-\\u0e46\\u0e81\\u0e82\\u0e84\\u0e87\\u0e88\\u0e8a\\u0e8d\\u0e94-\\u0e97\\u0e99-\\u0e9f\\u0ea1-\\u0ea3\\u0ea5\\u0ea7\\u0eaa\\u0eab\\u0ead-\\u0eb0\\u0eb2\\u0eb3\\u0ebd\\u0ec0-\\u0ec4\\u0ec6\\u0edc-\\u0edf\\u0f00\\u0f40-\\u0f47\\u0f49-\\u0f6c\\u0f88-\\u0f8c\\u1000-\\u102a\\u103f\\u1050-\\u1055\\u105a-\\u105d\\u1061\\u1065\\u1066\\u106e-\\u1070\\u1075-\\u1081\\u108e\\u10a0-\\u10c5\\u10c7\\u10cd\\u10d0-\\u10fa\\u10fc-\\u1248\\u124a-\\u124d\\u1250-\\u1256\\u1258\\u125a-\\u125d\\u1260-\\u1288\\u128a-\\u128d\\u1290-\\u12b0\\u12b2-\\u12b5\\u12b8-\\u12be\\u12c0\\u12c2-\\u12c5\\u12c8-\\u12d6\\u12d8-\\u1310\\u1312-\\u1315\\u1318-\\u135a\\u1380-\\u138f\\u13a0-\\u13f4\\u1401-\\u166c\\u166f-\\u167f\\u1681-\\u169a\\u16a0-\\u16ea\\u16ee-\\u16f0\\u1700-\\u170c\\u170e-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176c\\u176e-\\u1770\\u1780-\\u17b3\\u17d7\\u17dc\\u1820-\\u1877\\u1880-\\u18a8\\u18aa\\u18b0-\\u18f5\\u1900-\\u191c\\u1950-\\u196d\\u1970-\\u1974\\u1980-\\u19ab\\u19c1-\\u19c7\\u1a00-\\u1a16\\u1a20-\\u1a54\\u1aa7\\u1b05-\\u1b33\\u1b45-\\u1b4b\\u1b83-\\u1ba0\\u1bae\\u1baf\\u1bba-\\u1be5\\u1c00-\\u1c23\\u1c4d-\\u1c4f\\u1c5a-\\u1c7d\\u1ce9-\\u1cec\\u1cee-\\u1cf1\\u1cf5\\u1cf6\\u1d00-\\u1dbf\\u1e00-\\u1f15\\u1f18-\\u1f1d\\u1f20-\\u1f45\\u1f48-\\u1f4d\\u1f50-\\u1f57\\u1f59\\u1f5b\\u1f5d\\u1f5f-\\u1f7d\\u1f80-\\u1fb4\\u1fb6-\\u1fbc\\u1fbe\\u1fc2-\\u1fc4\\u1fc6-\\u1fcc\\u1fd0-\\u1fd3\\u1fd6-\\u1fdb\\u1fe0-\\u1fec\\u1ff2-\\u1ff4\\u1ff6-\\u1ffc\\u2071\\u207f\\u2090-\\u209c\\u2102\\u2107\\u210a-\\u2113\\u2115\\u2119-\\u211d\\u2124\\u2126\\u2128\\u212a-\\u212d\\u212f-\\u2139\\u213c-\\u213f\\u2145-\\u2149\\u214e\\u2160-\\u2188\\u2c00-\\u2c2e\\u2c30-\\u2c5e\\u2c60-\\u2ce4\\u2ceb-\\u2cee\\u2cf2\\u2cf3\\u2d00-\\u2d25\\u2d27\\u2d2d\\u2d30-\\u2d67\\u2d6f\\u2d80-\\u2d96\\u2da0-\\u2da6\\u2da8-\\u2dae\\u2db0-\\u2db6\\u2db8-\\u2dbe\\u2dc0-\\u2dc6\\u2dc8-\\u2dce\\u2dd0-\\u2dd6\\u2dd8-\\u2dde\\u2e2f\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303c\\u3041-\\u3096\\u309d-\\u309f\\u30a1-\\u30fa\\u30fc-\\u30ff\\u3105-\\u312d\\u3131-\\u318e\\u31a0-\\u31ba\\u31f0-\\u31ff\\u3400-\\u4db5\\u4e00-\\u9fcc\\ua000-\\ua48c\\ua4d0-\\ua4fd\\ua500-\\ua60c\\ua610-\\ua61f\\ua62a\\ua62b\\ua640-\\ua66e\\ua67f-\\ua697\\ua6a0-\\ua6ef\\ua717-\\ua71f\\ua722-\\ua788\\ua78b-\\ua78e\\ua790-\\ua793\\ua7a0-\\ua7aa\\ua7f8-\\ua801\\ua803-\\ua805\\ua807-\\ua80a\\ua80c-\\ua822\\ua840-\\ua873\\ua882-\\ua8b3\\ua8f2-\\ua8f7\\ua8fb\\ua90a-\\ua925\\ua930-\\ua946\\ua960-\\ua97c\\ua984-\\ua9b2\\ua9cf\\uaa00-\\uaa28\\uaa40-\\uaa42\\uaa44-\\uaa4b\\uaa60-\\uaa76\\uaa7a\\uaa80-\\uaaaf\\uaab1\\uaab5\\uaab6\\uaab9-\\uaabd\\uaac0\\uaac2\\uaadb-\\uaadd\\uaae0-\\uaaea\\uaaf2-\\uaaf4\\uab01-\\uab06\\uab09-\\uab0e\\uab11-\\uab16\\uab20-\\uab26\\uab28-\\uab2e\\uabc0-\\uabe2\\uac00-\\ud7a3\\ud7b0-\\ud7c6\\ud7cb-\\ud7fb\\uf900-\\ufa6d\\ufa70-\\ufad9\\ufb00-\\ufb06\\ufb13-\\ufb17\\ufb1d\\ufb1f-\\ufb28\\ufb2a-\\ufb36\\ufb38-\\ufb3c\\ufb3e\\ufb40\\ufb41\\ufb43\\ufb44\\ufb46-\\ufbb1\\ufbd3-\\ufd3d\\ufd50-\\ufd8f\\ufd92-\\ufdc7\\ufdf0-\\ufdfb\\ufe70-\\ufe74\\ufe76-\\ufefc\\uff21-\\uff3a\\uff41-\\uff5a\\uff66-\\uffbe\\uffc2-\\uffc7\\uffca-\\uffcf\\uffd2-\\uffd7\\uffda-\\uffdc]'),\n        NonAsciiIdentifierPart: new RegExp('[\\xaa\\xb5\\xba\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\u02c1\\u02c6-\\u02d1\\u02e0-\\u02e4\\u02ec\\u02ee\\u0300-\\u0374\\u0376\\u0377\\u037a-\\u037d\\u0386\\u0388-\\u038a\\u038c\\u038e-\\u03a1\\u03a3-\\u03f5\\u03f7-\\u0481\\u0483-\\u0487\\u048a-\\u0527\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u0591-\\u05bd\\u05bf\\u05c1\\u05c2\\u05c4\\u05c5\\u05c7\\u05d0-\\u05ea\\u05f0-\\u05f2\\u0610-\\u061a\\u0620-\\u0669\\u066e-\\u06d3\\u06d5-\\u06dc\\u06df-\\u06e8\\u06ea-\\u06fc\\u06ff\\u0710-\\u074a\\u074d-\\u07b1\\u07c0-\\u07f5\\u07fa\\u0800-\\u082d\\u0840-\\u085b\\u08a0\\u08a2-\\u08ac\\u08e4-\\u08fe\\u0900-\\u0963\\u0966-\\u096f\\u0971-\\u0977\\u0979-\\u097f\\u0981-\\u0983\\u0985-\\u098c\\u098f\\u0990\\u0993-\\u09a8\\u09aa-\\u09b0\\u09b2\\u09b6-\\u09b9\\u09bc-\\u09c4\\u09c7\\u09c8\\u09cb-\\u09ce\\u09d7\\u09dc\\u09dd\\u09df-\\u09e3\\u09e6-\\u09f1\\u0a01-\\u0a03\\u0a05-\\u0a0a\\u0a0f\\u0a10\\u0a13-\\u0a28\\u0a2a-\\u0a30\\u0a32\\u0a33\\u0a35\\u0a36\\u0a38\\u0a39\\u0a3c\\u0a3e-\\u0a42\\u0a47\\u0a48\\u0a4b-\\u0a4d\\u0a51\\u0a59-\\u0a5c\\u0a5e\\u0a66-\\u0a75\\u0a81-\\u0a83\\u0a85-\\u0a8d\\u0a8f-\\u0a91\\u0a93-\\u0aa8\\u0aaa-\\u0ab0\\u0ab2\\u0ab3\\u0ab5-\\u0ab9\\u0abc-\\u0ac5\\u0ac7-\\u0ac9\\u0acb-\\u0acd\\u0ad0\\u0ae0-\\u0ae3\\u0ae6-\\u0aef\\u0b01-\\u0b03\\u0b05-\\u0b0c\\u0b0f\\u0b10\\u0b13-\\u0b28\\u0b2a-\\u0b30\\u0b32\\u0b33\\u0b35-\\u0b39\\u0b3c-\\u0b44\\u0b47\\u0b48\\u0b4b-\\u0b4d\\u0b56\\u0b57\\u0b5c\\u0b5d\\u0b5f-\\u0b63\\u0b66-\\u0b6f\\u0b71\\u0b82\\u0b83\\u0b85-\\u0b8a\\u0b8e-\\u0b90\\u0b92-\\u0b95\\u0b99\\u0b9a\\u0b9c\\u0b9e\\u0b9f\\u0ba3\\u0ba4\\u0ba8-\\u0baa\\u0bae-\\u0bb9\\u0bbe-\\u0bc2\\u0bc6-\\u0bc8\\u0bca-\\u0bcd\\u0bd0\\u0bd7\\u0be6-\\u0bef\\u0c01-\\u0c03\\u0c05-\\u0c0c\\u0c0e-\\u0c10\\u0c12-\\u0c28\\u0c2a-\\u0c33\\u0c35-\\u0c39\\u0c3d-\\u0c44\\u0c46-\\u0c48\\u0c4a-\\u0c4d\\u0c55\\u0c56\\u0c58\\u0c59\\u0c60-\\u0c63\\u0c66-\\u0c6f\\u0c82\\u0c83\\u0c85-\\u0c8c\\u0c8e-\\u0c90\\u0c92-\\u0ca8\\u0caa-\\u0cb3\\u0cb5-\\u0cb9\\u0cbc-\\u0cc4\\u0cc6-\\u0cc8\\u0cca-\\u0ccd\\u0cd5\\u0cd6\\u0cde\\u0ce0-\\u0ce3\\u0ce6-\\u0cef\\u0cf1\\u0cf2\\u0d02\\u0d03\\u0d05-\\u0d0c\\u0d0e-\\u0d10\\u0d12-\\u0d3a\\u0d3d-\\u0d44\\u0d46-\\u0d48\\u0d4a-\\u0d4e\\u0d57\\u0d60-\\u0d63\\u0d66-\\u0d6f\\u0d7a-\\u0d7f\\u0d82\\u0d83\\u0d85-\\u0d96\\u0d9a-\\u0db1\\u0db3-\\u0dbb\\u0dbd\\u0dc0-\\u0dc6\\u0dca\\u0dcf-\\u0dd4\\u0dd6\\u0dd8-\\u0ddf\\u0df2\\u0df3\\u0e01-\\u0e3a\\u0e40-\\u0e4e\\u0e50-\\u0e59\\u0e81\\u0e82\\u0e84\\u0e87\\u0e88\\u0e8a\\u0e8d\\u0e94-\\u0e97\\u0e99-\\u0e9f\\u0ea1-\\u0ea3\\u0ea5\\u0ea7\\u0eaa\\u0eab\\u0ead-\\u0eb9\\u0ebb-\\u0ebd\\u0ec0-\\u0ec4\\u0ec6\\u0ec8-\\u0ecd\\u0ed0-\\u0ed9\\u0edc-\\u0edf\\u0f00\\u0f18\\u0f19\\u0f20-\\u0f29\\u0f35\\u0f37\\u0f39\\u0f3e-\\u0f47\\u0f49-\\u0f6c\\u0f71-\\u0f84\\u0f86-\\u0f97\\u0f99-\\u0fbc\\u0fc6\\u1000-\\u1049\\u1050-\\u109d\\u10a0-\\u10c5\\u10c7\\u10cd\\u10d0-\\u10fa\\u10fc-\\u1248\\u124a-\\u124d\\u1250-\\u1256\\u1258\\u125a-\\u125d\\u1260-\\u1288\\u128a-\\u128d\\u1290-\\u12b0\\u12b2-\\u12b5\\u12b8-\\u12be\\u12c0\\u12c2-\\u12c5\\u12c8-\\u12d6\\u12d8-\\u1310\\u1312-\\u1315\\u1318-\\u135a\\u135d-\\u135f\\u1380-\\u138f\\u13a0-\\u13f4\\u1401-\\u166c\\u166f-\\u167f\\u1681-\\u169a\\u16a0-\\u16ea\\u16ee-\\u16f0\\u1700-\\u170c\\u170e-\\u1714\\u1720-\\u1734\\u1740-\\u1753\\u1760-\\u176c\\u176e-\\u1770\\u1772\\u1773\\u1780-\\u17d3\\u17d7\\u17dc\\u17dd\\u17e0-\\u17e9\\u180b-\\u180d\\u1810-\\u1819\\u1820-\\u1877\\u1880-\\u18aa\\u18b0-\\u18f5\\u1900-\\u191c\\u1920-\\u192b\\u1930-\\u193b\\u1946-\\u196d\\u1970-\\u1974\\u1980-\\u19ab\\u19b0-\\u19c9\\u19d0-\\u19d9\\u1a00-\\u1a1b\\u1a20-\\u1a5e\\u1a60-\\u1a7c\\u1a7f-\\u1a89\\u1a90-\\u1a99\\u1aa7\\u1b00-\\u1b4b\\u1b50-\\u1b59\\u1b6b-\\u1b73\\u1b80-\\u1bf3\\u1c00-\\u1c37\\u1c40-\\u1c49\\u1c4d-\\u1c7d\\u1cd0-\\u1cd2\\u1cd4-\\u1cf6\\u1d00-\\u1de6\\u1dfc-\\u1f15\\u1f18-\\u1f1d\\u1f20-\\u1f45\\u1f48-\\u1f4d\\u1f50-\\u1f57\\u1f59\\u1f5b\\u1f5d\\u1f5f-\\u1f7d\\u1f80-\\u1fb4\\u1fb6-\\u1fbc\\u1fbe\\u1fc2-\\u1fc4\\u1fc6-\\u1fcc\\u1fd0-\\u1fd3\\u1fd6-\\u1fdb\\u1fe0-\\u1fec\\u1ff2-\\u1ff4\\u1ff6-\\u1ffc\\u200c\\u200d\\u203f\\u2040\\u2054\\u2071\\u207f\\u2090-\\u209c\\u20d0-\\u20dc\\u20e1\\u20e5-\\u20f0\\u2102\\u2107\\u210a-\\u2113\\u2115\\u2119-\\u211d\\u2124\\u2126\\u2128\\u212a-\\u212d\\u212f-\\u2139\\u213c-\\u213f\\u2145-\\u2149\\u214e\\u2160-\\u2188\\u2c00-\\u2c2e\\u2c30-\\u2c5e\\u2c60-\\u2ce4\\u2ceb-\\u2cf3\\u2d00-\\u2d25\\u2d27\\u2d2d\\u2d30-\\u2d67\\u2d6f\\u2d7f-\\u2d96\\u2da0-\\u2da6\\u2da8-\\u2dae\\u2db0-\\u2db6\\u2db8-\\u2dbe\\u2dc0-\\u2dc6\\u2dc8-\\u2dce\\u2dd0-\\u2dd6\\u2dd8-\\u2dde\\u2de0-\\u2dff\\u2e2f\\u3005-\\u3007\\u3021-\\u302f\\u3031-\\u3035\\u3038-\\u303c\\u3041-\\u3096\\u3099\\u309a\\u309d-\\u309f\\u30a1-\\u30fa\\u30fc-\\u30ff\\u3105-\\u312d\\u3131-\\u318e\\u31a0-\\u31ba\\u31f0-\\u31ff\\u3400-\\u4db5\\u4e00-\\u9fcc\\ua000-\\ua48c\\ua4d0-\\ua4fd\\ua500-\\ua60c\\ua610-\\ua62b\\ua640-\\ua66f\\ua674-\\ua67d\\ua67f-\\ua697\\ua69f-\\ua6f1\\ua717-\\ua71f\\ua722-\\ua788\\ua78b-\\ua78e\\ua790-\\ua793\\ua7a0-\\ua7aa\\ua7f8-\\ua827\\ua840-\\ua873\\ua880-\\ua8c4\\ua8d0-\\ua8d9\\ua8e0-\\ua8f7\\ua8fb\\ua900-\\ua92d\\ua930-\\ua953\\ua960-\\ua97c\\ua980-\\ua9c0\\ua9cf-\\ua9d9\\uaa00-\\uaa36\\uaa40-\\uaa4d\\uaa50-\\uaa59\\uaa60-\\uaa76\\uaa7a\\uaa7b\\uaa80-\\uaac2\\uaadb-\\uaadd\\uaae0-\\uaaef\\uaaf2-\\uaaf6\\uab01-\\uab06\\uab09-\\uab0e\\uab11-\\uab16\\uab20-\\uab26\\uab28-\\uab2e\\uabc0-\\uabea\\uabec\\uabed\\uabf0-\\uabf9\\uac00-\\ud7a3\\ud7b0-\\ud7c6\\ud7cb-\\ud7fb\\uf900-\\ufa6d\\ufa70-\\ufad9\\ufb00-\\ufb06\\ufb13-\\ufb17\\ufb1d-\\ufb28\\ufb2a-\\ufb36\\ufb38-\\ufb3c\\ufb3e\\ufb40\\ufb41\\ufb43\\ufb44\\ufb46-\\ufbb1\\ufbd3-\\ufd3d\\ufd50-\\ufd8f\\ufd92-\\ufdc7\\ufdf0-\\ufdfb\\ufe00-\\ufe0f\\ufe20-\\ufe26\\ufe33\\ufe34\\ufe4d-\\ufe4f\\ufe70-\\ufe74\\ufe76-\\ufefc\\uff10-\\uff19\\uff21-\\uff3a\\uff3f\\uff41-\\uff5a\\uff66-\\uffbe\\uffc2-\\uffc7\\uffca-\\uffcf\\uffd2-\\uffd7\\uffda-\\uffdc]')\n      };\n      function isDecimalDigit(ch) {\n        return ch >= 48 && ch <= 57;\n      }\n      function isHexDigit(ch) {\n        return isDecimalDigit(ch) || 97 <= ch && ch <= 102 || 65 <= ch && ch <= 70;\n      }\n      function isOctalDigit(ch) {\n        return ch >= 48 && ch <= 55;\n      }\n      function isWhiteSpace(ch) {\n        return ch === 32 || ch === 9 || ch === 11 || ch === 12 || ch === 160 || ch >= 5760 && [\n          5760,\n          6158,\n          8192,\n          8193,\n          8194,\n          8195,\n          8196,\n          8197,\n          8198,\n          8199,\n          8200,\n          8201,\n          8202,\n          8239,\n          8287,\n          12288,\n          65279\n        ].indexOf(ch) >= 0;\n      }\n      function isLineTerminator(ch) {\n        return ch === 10 || ch === 13 || ch === 8232 || ch === 8233;\n      }\n      function isIdentifierStart(ch) {\n        return ch === 36 || ch === 95 || ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122 || ch === 92 || ch >= 128 && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch));\n      }\n      function isIdentifierPart(ch) {\n        return ch === 36 || ch === 95 || ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122 || ch >= 48 && ch <= 57 || ch === 92 || ch >= 128 && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch));\n      }\n      module.exports = {\n        isDecimalDigit: isDecimalDigit,\n        isHexDigit: isHexDigit,\n        isOctalDigit: isOctalDigit,\n        isWhiteSpace: isWhiteSpace,\n        isLineTerminator: isLineTerminator,\n        isIdentifierStart: isIdentifierStart,\n        isIdentifierPart: isIdentifierPart\n      };\n    }());\n  });\n  require.define('/node_modules/estraverse/estraverse.js', function (module, exports, __dirname, __filename) {\n    (function (root, factory) {\n      'use strict';\n      if (typeof define === 'function' && define.amd) {\n        define(['exports'], factory);\n      } else if (typeof exports !== 'undefined') {\n        factory(exports);\n      } else {\n        factory(root.estraverse = {});\n      }\n    }(this, function (exports) {\n      'use strict';\n      var Syntax, isArray, VisitorOption, VisitorKeys, BREAK, SKIP;\n      Syntax = {\n        AssignmentExpression: 'AssignmentExpression',\n        ArrayExpression: 'ArrayExpression',\n        ArrayPattern: 'ArrayPattern',\n        ArrowFunctionExpression: 'ArrowFunctionExpression',\n        BlockStatement: 'BlockStatement',\n        BinaryExpression: 'BinaryExpression',\n        BreakStatement: 'BreakStatement',\n        CallExpression: 'CallExpression',\n        CatchClause: 'CatchClause',\n        ClassBody: 'ClassBody',\n        ClassDeclaration: 'ClassDeclaration',\n        ClassExpression: 'ClassExpression',\n        ConditionalExpression: 'ConditionalExpression',\n        ContinueStatement: 'ContinueStatement',\n        DebuggerStatement: 'DebuggerStatement',\n        DirectiveStatement: 'DirectiveStatement',\n        DoWhileStatement: 'DoWhileStatement',\n        EmptyStatement: 'EmptyStatement',\n        ExpressionStatement: 'ExpressionStatement',\n        ForStatement: 'ForStatement',\n        ForInStatement: 'ForInStatement',\n        FunctionDeclaration: 'FunctionDeclaration',\n        FunctionExpression: 'FunctionExpression',\n        Identifier: 'Identifier',\n        IfStatement: 'IfStatement',\n        Literal: 'Literal',\n        LabeledStatement: 'LabeledStatement',\n        LogicalExpression: 'LogicalExpression',\n        MemberExpression: 'MemberExpression',\n        MethodDefinition: 'MethodDefinition',\n        NewExpression: 'NewExpression',\n        ObjectExpression: 'ObjectExpression',\n        ObjectPattern: 'ObjectPattern',\n        Program: 'Program',\n        Property: 'Property',\n        ReturnStatement: 'ReturnStatement',\n        SequenceExpression: 'SequenceExpression',\n        SwitchStatement: 'SwitchStatement',\n        SwitchCase: 'SwitchCase',\n        ThisExpression: 'ThisExpression',\n        ThrowStatement: 'ThrowStatement',\n        TryStatement: 'TryStatement',\n        UnaryExpression: 'UnaryExpression',\n        UpdateExpression: 'UpdateExpression',\n        VariableDeclaration: 'VariableDeclaration',\n        VariableDeclarator: 'VariableDeclarator',\n        WhileStatement: 'WhileStatement',\n        WithStatement: 'WithStatement',\n        YieldExpression: 'YieldExpression'\n      };\n      function ignoreJSHintError() {\n      }\n      isArray = Array.isArray;\n      if (!isArray) {\n        isArray = function isArray(array) {\n          return Object.prototype.toString.call(array) === '[object Array]';\n        };\n      }\n      function deepCopy(obj) {\n        var ret = {}, key, val;\n        for (key in obj) {\n          if (obj.hasOwnProperty(key)) {\n            val = obj[key];\n            if (typeof val === 'object' && val !== null) {\n              ret[key] = deepCopy(val);\n            } else {\n              ret[key] = val;\n            }\n          }\n        }\n        return ret;\n      }\n      function shallowCopy(obj) {\n        var ret = {}, key;\n        for (key in obj) {\n          if (obj.hasOwnProperty(key)) {\n            ret[key] = obj[key];\n          }\n        }\n        return ret;\n      }\n      ignoreJSHintError(shallowCopy);\n      function upperBound(array, func) {\n        var diff, len, i, current;\n        len = array.length;\n        i = 0;\n        while (len) {\n          diff = len >>> 1;\n          current = i + diff;\n          if (func(array[current])) {\n            len = diff;\n          } else {\n            i = current + 1;\n            len -= diff + 1;\n          }\n        }\n        return i;\n      }\n      function lowerBound(array, func) {\n        var diff, len, i, current;\n        len = array.length;\n        i = 0;\n        while (len) {\n          diff = len >>> 1;\n          current = i + diff;\n          if (func(array[current])) {\n            i = current + 1;\n            len -= diff + 1;\n          } else {\n            len = diff;\n          }\n        }\n        return i;\n      }\n      ignoreJSHintError(lowerBound);\n      VisitorKeys = {\n        AssignmentExpression: [\n          'left',\n          'right'\n        ],\n        ArrayExpression: ['elements'],\n        ArrayPattern: ['elements'],\n        ArrowFunctionExpression: [\n          'params',\n          'defaults',\n          'rest',\n          'body'\n        ],\n        BlockStatement: ['body'],\n        BinaryExpression: [\n          'left',\n          'right'\n        ],\n        BreakStatement: ['label'],\n        CallExpression: [\n          'callee',\n          'arguments'\n        ],\n        CatchClause: [\n          'param',\n          'body'\n        ],\n        ClassBody: ['body'],\n        ClassDeclaration: [\n          'id',\n          'body',\n          'superClass'\n        ],\n        ClassExpression: [\n          'id',\n          'body',\n          'superClass'\n        ],\n        ConditionalExpression: [\n          'test',\n          'consequent',\n          'alternate'\n        ],\n        ContinueStatement: ['label'],\n        DebuggerStatement: [],\n        DirectiveStatement: [],\n        DoWhileStatement: [\n          'body',\n          'test'\n        ],\n        EmptyStatement: [],\n        ExpressionStatement: ['expression'],\n        ForStatement: [\n          'init',\n          'test',\n          'update',\n          'body'\n        ],\n        ForInStatement: [\n          'left',\n          'right',\n          'body'\n        ],\n        FunctionDeclaration: [\n          'id',\n          'params',\n          'defaults',\n          'rest',\n          'body'\n        ],\n        FunctionExpression: [\n          'id',\n          'params',\n          'defaults',\n          'rest',\n          'body'\n        ],\n        Identifier: [],\n        IfStatement: [\n          'test',\n          'consequent',\n          'alternate'\n        ],\n        Literal: [],\n        LabeledStatement: [\n          'label',\n          'body'\n        ],\n        LogicalExpression: [\n          'left',\n          'right'\n        ],\n        MemberExpression: [\n          'object',\n          'property'\n        ],\n        MethodDefinition: [\n          'key',\n          'value'\n        ],\n        NewExpression: [\n          'callee',\n          'arguments'\n        ],\n        ObjectExpression: ['properties'],\n        ObjectPattern: ['properties'],\n        Program: ['body'],\n        Property: [\n          'key',\n          'value'\n        ],\n        ReturnStatement: ['argument'],\n        SequenceExpression: ['expressions'],\n        SwitchStatement: [\n          'discriminant',\n          'cases'\n        ],\n        SwitchCase: [\n          'test',\n          'consequent'\n        ],\n        ThisExpression: [],\n        ThrowStatement: ['argument'],\n        TryStatement: [\n          'block',\n          'handlers',\n          'handler',\n          'guardedHandlers',\n          'finalizer'\n        ],\n        UnaryExpression: ['argument'],\n        UpdateExpression: ['argument'],\n        VariableDeclaration: ['declarations'],\n        VariableDeclarator: [\n          'id',\n          'init'\n        ],\n        WhileStatement: [\n          'test',\n          'body'\n        ],\n        WithStatement: [\n          'object',\n          'body'\n        ],\n        YieldExpression: ['argument']\n      };\n      BREAK = {};\n      SKIP = {};\n      VisitorOption = {\n        Break: BREAK,\n        Skip: SKIP\n      };\n      function Reference(parent, key) {\n        this.parent = parent;\n        this.key = key;\n      }\n      Reference.prototype.replace = function replace(node) {\n        this.parent[this.key] = node;\n      };\n      function Element(node, path, wrap, ref) {\n        this.node = node;\n        this.path = path;\n        this.wrap = wrap;\n        this.ref = ref;\n      }\n      function Controller() {\n      }\n      Controller.prototype.path = function path() {\n        var i, iz, j, jz, result, element;\n        function addToPath(result, path) {\n          if (isArray(path)) {\n            for (j = 0, jz = path.length; j < jz; ++j) {\n              result.push(path[j]);\n            }\n          } else {\n            result.push(path);\n          }\n        }\n        if (!this.__current.path) {\n          return null;\n        }\n        result = [];\n        for (i = 2, iz = this.__leavelist.length; i < iz; ++i) {\n          element = this.__leavelist[i];\n          addToPath(result, element.path);\n        }\n        addToPath(result, this.__current.path);\n        return result;\n      };\n      Controller.prototype.parents = function parents() {\n        var i, iz, result;\n        result = [];\n        for (i = 1, iz = this.__leavelist.length; i < iz; ++i) {\n          result.push(this.__leavelist[i].node);\n        }\n        return result;\n      };\n      Controller.prototype.current = function current() {\n        return this.__current.node;\n      };\n      Controller.prototype.__execute = function __execute(callback, element) {\n        var previous, result;\n        result = undefined;\n        previous = this.__current;\n        this.__current = element;\n        this.__state = null;\n        if (callback) {\n          result = callback.call(this, element.node, this.__leavelist[this.__leavelist.length - 1].node);\n        }\n        this.__current = previous;\n        return result;\n      };\n      Controller.prototype.notify = function notify(flag) {\n        this.__state = flag;\n      };\n      Controller.prototype.skip = function () {\n        this.notify(SKIP);\n      };\n      Controller.prototype['break'] = function () {\n        this.notify(BREAK);\n      };\n      Controller.prototype.__initialize = function (root, visitor) {\n        this.visitor = visitor;\n        this.root = root;\n        this.__worklist = [];\n        this.__leavelist = [];\n        this.__current = null;\n        this.__state = null;\n      };\n      Controller.prototype.traverse = function traverse(root, visitor) {\n        var worklist, leavelist, element, node, nodeType, ret, key, current, current2, candidates, candidate, sentinel;\n        this.__initialize(root, visitor);\n        sentinel = {};\n        worklist = this.__worklist;\n        leavelist = this.__leavelist;\n        worklist.push(new Element(root, null, null, null));\n        leavelist.push(new Element(null, null, null, null));\n        while (worklist.length) {\n          element = worklist.pop();\n          if (element === sentinel) {\n            element = leavelist.pop();\n            ret = this.__execute(visitor.leave, element);\n            if (this.__state === BREAK || ret === BREAK) {\n              return;\n            }\n            continue;\n          }\n          if (element.node) {\n            ret = this.__execute(visitor.enter, element);\n            if (this.__state === BREAK || ret === BREAK) {\n              return;\n            }\n            worklist.push(sentinel);\n            leavelist.push(element);\n            if (this.__state === SKIP || ret === SKIP) {\n              continue;\n            }\n            node = element.node;\n            nodeType = element.wrap || node.type;\n            candidates = VisitorKeys[nodeType];\n            current = candidates.length;\n            while ((current -= 1) >= 0) {\n              key = candidates[current];\n              candidate = node[key];\n              if (!candidate) {\n                continue;\n              }\n              if (!isArray(candidate)) {\n                worklist.push(new Element(candidate, key, null, null));\n                continue;\n              }\n              current2 = candidate.length;\n              while ((current2 -= 1) >= 0) {\n                if (!candidate[current2]) {\n                  continue;\n                }\n                if ((nodeType === Syntax.ObjectExpression || nodeType === Syntax.ObjectPattern) && 'properties' === candidates[current]) {\n                  element = new Element(candidate[current2], [\n                    key,\n                    current2\n                  ], 'Property', null);\n                } else {\n                  element = new Element(candidate[current2], [\n                    key,\n                    current2\n                  ], null, null);\n                }\n                worklist.push(element);\n              }\n            }\n          }\n        }\n      };\n      Controller.prototype.replace = function replace(root, visitor) {\n        var worklist, leavelist, node, nodeType, target, element, current, current2, candidates, candidate, sentinel, outer, key;\n        this.__initialize(root, visitor);\n        sentinel = {};\n        worklist = this.__worklist;\n        leavelist = this.__leavelist;\n        outer = { root: root };\n        element = new Element(root, null, null, new Reference(outer, 'root'));\n        worklist.push(element);\n        leavelist.push(element);\n        while (worklist.length) {\n          element = worklist.pop();\n          if (element === sentinel) {\n            element = leavelist.pop();\n            target = this.__execute(visitor.leave, element);\n            if (target !== undefined && target !== BREAK && target !== SKIP) {\n              element.ref.replace(target);\n            }\n            if (this.__state === BREAK || target === BREAK) {\n              return outer.root;\n            }\n            continue;\n          }\n          target = this.__execute(visitor.enter, element);\n          if (target !== undefined && target !== BREAK && target !== SKIP) {\n            element.ref.replace(target);\n            element.node = target;\n          }\n          if (this.__state === BREAK || target === BREAK) {\n            return outer.root;\n          }\n          node = element.node;\n          if (!node) {\n            continue;\n          }\n          worklist.push(sentinel);\n          leavelist.push(element);\n          if (this.__state === SKIP || target === SKIP) {\n            continue;\n          }\n          nodeType = element.wrap || node.type;\n          candidates = VisitorKeys[nodeType];\n          current = candidates.length;\n          while ((current -= 1) >= 0) {\n            key = candidates[current];\n            candidate = node[key];\n            if (!candidate) {\n              continue;\n            }\n            if (!isArray(candidate)) {\n              worklist.push(new Element(candidate, key, null, new Reference(node, key)));\n              continue;\n            }\n            current2 = candidate.length;\n            while ((current2 -= 1) >= 0) {\n              if (!candidate[current2]) {\n                continue;\n              }\n              if (nodeType === Syntax.ObjectExpression && 'properties' === candidates[current]) {\n                element = new Element(candidate[current2], [\n                  key,\n                  current2\n                ], 'Property', new Reference(candidate, current2));\n              } else {\n                element = new Element(candidate[current2], [\n                  key,\n                  current2\n                ], null, new Reference(candidate, current2));\n              }\n              worklist.push(element);\n            }\n          }\n        }\n        return outer.root;\n      };\n      function traverse(root, visitor) {\n        var controller = new Controller;\n        return controller.traverse(root, visitor);\n      }\n      function replace(root, visitor) {\n        var controller = new Controller;\n        return controller.replace(root, visitor);\n      }\n      function extendCommentRange(comment, tokens) {\n        var target;\n        target = upperBound(tokens, function search(token) {\n          return token.range[0] > comment.range[0];\n        });\n        comment.extendedRange = [\n          comment.range[0],\n          comment.range[1]\n        ];\n        if (target !== tokens.length) {\n          comment.extendedRange[1] = tokens[target].range[0];\n        }\n        target -= 1;\n        if (target >= 0) {\n          comment.extendedRange[0] = tokens[target].range[1];\n        }\n        return comment;\n      }\n      function attachComments(tree, providedComments, tokens) {\n        var comments = [], comment, len, i, cursor;\n        if (!tree.range) {\n          throw new Error('attachComments needs range information');\n        }\n        if (!tokens.length) {\n          if (providedComments.length) {\n            for (i = 0, len = providedComments.length; i < len; i += 1) {\n              comment = deepCopy(providedComments[i]);\n              comment.extendedRange = [\n                0,\n                tree.range[0]\n              ];\n              comments.push(comment);\n            }\n            tree.leadingComments = comments;\n          }\n          return tree;\n        }\n        for (i = 0, len = providedComments.length; i < len; i += 1) {\n          comments.push(extendCommentRange(deepCopy(providedComments[i]), tokens));\n        }\n        cursor = 0;\n        traverse(tree, {\n          enter: function (node) {\n            var comment;\n            while (cursor < comments.length) {\n              comment = comments[cursor];\n              if (comment.extendedRange[1] > node.range[0]) {\n                break;\n              }\n              if (comment.extendedRange[1] === node.range[0]) {\n                if (!node.leadingComments) {\n                  node.leadingComments = [];\n                }\n                node.leadingComments.push(comment);\n                comments.splice(cursor, 1);\n              } else {\n                cursor += 1;\n              }\n            }\n            if (cursor === comments.length) {\n              return VisitorOption.Break;\n            }\n            if (comments[cursor].extendedRange[0] > node.range[1]) {\n              return VisitorOption.Skip;\n            }\n          }\n        });\n        cursor = 0;\n        traverse(tree, {\n          leave: function (node) {\n            var comment;\n            while (cursor < comments.length) {\n              comment = comments[cursor];\n              if (node.range[1] < comment.extendedRange[0]) {\n                break;\n              }\n              if (node.range[1] === comment.extendedRange[0]) {\n                if (!node.trailingComments) {\n                  node.trailingComments = [];\n                }\n                node.trailingComments.push(comment);\n                comments.splice(cursor, 1);\n              } else {\n                cursor += 1;\n              }\n            }\n            if (cursor === comments.length) {\n              return VisitorOption.Break;\n            }\n            if (comments[cursor].extendedRange[0] > node.range[1]) {\n              return VisitorOption.Skip;\n            }\n          }\n        });\n        return tree;\n      }\n      exports.version = '1.3.3-dev';\n      exports.Syntax = Syntax;\n      exports.traverse = traverse;\n      exports.replace = replace;\n      exports.attachComments = attachComments;\n      exports.VisitorKeys = VisitorKeys;\n      exports.VisitorOption = VisitorOption;\n      exports.Controller = Controller;\n    }));\n  });\n  require('/tools/entry-point.js');\n}.call(this, this));\n"
  },
  {
    "path": "docs/editor/scripts/expander.js",
    "content": "/*\n  Copyright (C) 2012 Tim Disney <tim@disnet.me>\n\n\n  Redistribution and use in source and binary forms, with or without\n  modification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\n  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n(function (root, factory) {\n    if (typeof exports === 'object') {\n        // CommonJS\n        factory(exports, require('underscore'), require('./parser'), require('./syntax'), require('./scopedEval'), require('./patterns'), require('escodegen'));\n    } else if (typeof define === 'function' && define.amd) {\n        // AMD. Register as an anonymous module.\n        define([\n            'exports',\n            'underscore',\n            'parser',\n            'syntax',\n            'scopedEval',\n            'patterns',\n            'escodegen'\n        ], factory);\n    }\n}(this, function (exports$2, _, parser, syn, se, patternModule, gen) {\n    'use strict';\n    // escodegen still doesn't quite support AMD: https://github.com/Constellation/escodegen/issues/115\n    var codegen = typeof escodegen !== 'undefined' ? escodegen : gen;\n    var assert = syn.assert;\n    var throwSyntaxError = syn.throwSyntaxError;\n    var throwSyntaxCaseError = syn.throwSyntaxCaseError;\n    var SyntaxCaseError = syn.SyntaxCaseError;\n    var unwrapSyntax = syn.unwrapSyntax;\n    // used to export \"private\" methods for unit testing\n    exports$2._test = {};\n    function StringMap(o) {\n        this.__data = o || {};\n    }\n    StringMap.prototype = {\n        has: function (key) {\n            return Object.prototype.hasOwnProperty.call(this.__data, key);\n        },\n        get: function (key) {\n            return this.has(key) ? this.__data[key] : void 0;\n        },\n        set: function (key, value) {\n            this.__data[key] = value;\n        },\n        extend: function () {\n            var args = _.map(_.toArray(arguments), function (x) {\n                    return x.__data;\n                });\n            _.extend.apply(_, [this.__data].concat(args));\n            return this;\n        }\n    };\n    var scopedEval = se.scopedEval;\n    var Rename = syn.Rename;\n    var Mark = syn.Mark;\n    var Def = syn.Def;\n    var syntaxFromToken = syn.syntaxFromToken;\n    var joinSyntax = syn.joinSyntax;\n    var builtinMode = false;\n    var expandCount = 0;\n    var maxExpands;\n    var push = Array.prototype.push;\n    function remdup(mark, mlist) {\n        if (mark === _.first(mlist)) {\n            return _.rest(mlist, 1);\n        }\n        return [mark].concat(mlist);\n    }\n    // (CSyntax) -> [...Num]\n    function marksof(ctx, stopName, originalName) {\n        while (ctx) {\n            if (ctx.constructor === Mark) {\n                return remdup(ctx.mark, marksof(ctx.context, stopName, originalName));\n            }\n            if (ctx.constructor === Def) {\n                ctx = ctx.context;\n                continue;\n            }\n            if (ctx.constructor === Rename) {\n                if (stopName === originalName + '$' + ctx.name) {\n                    return [];\n                }\n                ctx = ctx.context;\n                continue;\n            }\n        }\n        return [];\n    }\n    function resolve(stx) {\n        return resolveCtx(stx.token.value, stx.context, [], [], {});\n    }\n    // This call memoizes intermediate results in the recursive invocation.\n    // The scope of the memo cache is the resolve() call, so that multiple\n    // resolve() calls don't walk all over each other, and memory used for\n    // the memoization can be garbage collected.\n    //\n    // The memoization addresses issue #232.\n    //\n    // It looks like the memoization uses only the context and doesn't look\n    // at originalName, stop_spine and stop_branch arguments. This is valid\n    // because whenever in every recursive call operates on a \"deeper\" or\n    // else a newly created context.  Therefore the collection of\n    // [originalName, stop_spine, stop_branch] can all be associated with a\n    // unique context. This argument is easier to see in a recursive\n    // rewrite of the resolveCtx function than with the while loop\n    // optimization - https://gist.github.com/srikumarks/9847260 - where the\n    // recursive steps always operate on a different context.\n    //\n    // This might make it seem that the resolution results can be stored on\n    // the context object itself, but that would not work in general\n    // because multiple resolve() calls will walk over each other's cache\n    // results, which fails tests. So the memoization uses only a context's\n    // unique instance numbers as the memoization key and is local to each\n    // resolve() call.\n    //\n    // With this memoization, the time complexity of the resolveCtx call is\n    // no longer exponential for the cases in issue #232.\n    function resolveCtx(originalName, ctx, stop_spine, stop_branch, cache) {\n        if (!ctx) {\n            return originalName;\n        }\n        var key = ctx.instNum;\n        return cache[key] || (cache[key] = resolveCtxFull(originalName, ctx, stop_spine, stop_branch, cache));\n    }\n    // (Syntax) -> String\n    function resolveCtxFull(originalName, ctx, stop_spine, stop_branch, cache) {\n        while (true) {\n            if (!ctx) {\n                return originalName;\n            }\n            if (ctx.constructor === Mark) {\n                ctx = ctx.context;\n                continue;\n            }\n            if (ctx.constructor === Def) {\n                if (stop_spine.indexOf(ctx.defctx) !== -1) {\n                    ctx = ctx.context;\n                    continue;\n                } else {\n                    stop_branch = unionEl(stop_branch, ctx.defctx);\n                    ctx = renames(ctx.defctx, ctx.context, originalName);\n                    continue;\n                }\n            }\n            if (ctx.constructor === Rename) {\n                if (originalName === ctx.id.token.value) {\n                    var idName = resolveCtx(ctx.id.token.value, ctx.id.context, stop_branch, stop_branch, cache);\n                    var subName = resolveCtx(originalName, ctx.context, unionEl(stop_spine, ctx.def), stop_branch, cache);\n                    if (idName === subName) {\n                        var idMarks = marksof(ctx.id.context, originalName + '$' + ctx.name, originalName);\n                        var subMarks = marksof(ctx.context, originalName + '$' + ctx.name, originalName);\n                        if (arraysEqual(idMarks, subMarks)) {\n                            return originalName + '$' + ctx.name;\n                        }\n                    }\n                }\n                ctx = ctx.context;\n                continue;\n            }\n            return originalName;\n        }\n    }\n    function arraysEqual(a, b) {\n        if (a.length !== b.length) {\n            return false;\n        }\n        for (var i = 0; i < a.length; i++) {\n            if (a[i] !== b[i]) {\n                return false;\n            }\n        }\n        return true;\n    }\n    function renames(defctx, oldctx, originalName) {\n        var acc = oldctx;\n        for (var i = 0; i < defctx.length; i++) {\n            if (defctx[i].id.token.value === originalName) {\n                acc = new Rename(defctx[i].id, defctx[i].name, acc, defctx);\n            }\n        }\n        return acc;\n    }\n    function unionEl(arr, el) {\n        if (arr.indexOf(el) === -1) {\n            var res = arr.slice(0);\n            res.push(el);\n            return res;\n        }\n        return arr;\n    }\n    var nextFresh = 0;\n    // fun () -> Num\n    function fresh() {\n        return nextFresh++;\n    }\n    // wraps the array of syntax objects in the delimiters given by the second argument\n    // ([...CSyntax], CSyntax) -> [...CSyntax]\n    function wrapDelim(towrap, delimSyntax) {\n        assert(delimSyntax.token.type === parser.Token.Delimiter, 'expecting a delimiter token');\n        return syntaxFromToken({\n            type: parser.Token.Delimiter,\n            value: delimSyntax.token.value,\n            inner: towrap,\n            range: delimSyntax.token.range,\n            startLineNumber: delimSyntax.token.startLineNumber,\n            lineStart: delimSyntax.token.lineStart\n        }, delimSyntax);\n    }\n    // (CSyntax) -> [...CSyntax]\n    function getParamIdentifiers(argSyntax) {\n        if (argSyntax.token.type === parser.Token.Delimiter) {\n            return _.filter(argSyntax.token.inner, function (stx) {\n                return stx.token.value !== ',';\n            });\n        } else if (argSyntax.token.type === parser.Token.Identifier) {\n            return [argSyntax];\n        } else {\n            assert(false, 'expecting a delimiter or a single identifier for function parameters');\n        }\n    }\n    function inherit(parent, child, methods) {\n        var P = function () {\n        };\n        P.prototype = parent.prototype;\n        child.prototype = new P();\n        child.prototype.constructor = child;\n        _.extend(child.prototype, methods);\n    }\n    // A TermTree is the core data structure for the macro expansion process.\n    // It acts as a semi-structured representation of the syntax.\n    function TermTree() {\n    }\n    TermTree.properties = [];\n    TermTree.create = function () {\n        return new TermTree();\n    };\n    TermTree.prototype = {\n        'isTermTree': true,\n        'destruct': function () {\n            var self = this;\n            return _.reduce(this.constructor.properties, function (acc, prop) {\n                if (self[prop] && self[prop].isTermTree) {\n                    push.apply(acc, self[prop].destruct());\n                    return acc;\n                } else if (self[prop] && self[prop].token && self[prop].token.inner) {\n                    var src = self[prop].token;\n                    var keys = Object.keys(src);\n                    var newtok = {};\n                    for (var i = 0, len = keys.length, key; i < len; i++) {\n                        key = keys[i];\n                        newtok[key] = src[key];\n                    }\n                    var clone = syntaxFromToken(newtok, self[prop]);\n                    clone.token.inner = _.reduce(clone.token.inner, function (acc$2, t) {\n                        if (t && t.isTermTree) {\n                            push.apply(acc$2, t.destruct());\n                            return acc$2;\n                        }\n                        acc$2.push(t);\n                        return acc$2;\n                    }, []);\n                    acc.push(clone);\n                    return acc;\n                } else if (Array.isArray(self[prop])) {\n                    var destArr = _.reduce(self[prop], function (acc$2, t) {\n                            if (t && t.isTermTree) {\n                                push.apply(acc$2, t.destruct());\n                                return acc$2;\n                            }\n                            acc$2.push(t);\n                            return acc$2;\n                        }, []);\n                    push.apply(acc, destArr);\n                    return acc;\n                } else if (self[prop]) {\n                    acc.push(self[prop]);\n                    return acc;\n                } else {\n                    return acc;\n                }\n            }, []);\n        },\n        'addDefCtx': function (def) {\n            var self = this;\n            _.each(this.constructor.properties, function (prop) {\n                if (Array.isArray(self[prop])) {\n                    self[prop] = _.map(self[prop], function (item) {\n                        return item.addDefCtx(def);\n                    });\n                } else if (self[prop]) {\n                    self[prop] = self[prop].addDefCtx(def);\n                }\n            });\n            return this;\n        },\n        'rename': function (id, name) {\n            var self = this;\n            _.each(this.constructor.properties, function (prop) {\n                if (Array.isArray(self[prop])) {\n                    self[prop] = _.map(self[prop], function (item) {\n                        return item.rename(id, name);\n                    });\n                } else if (self[prop]) {\n                    self[prop] = self[prop].rename(id, name);\n                }\n            });\n            return this;\n        }\n    };\n    function EOF(eof) {\n        this.eof = eof;\n    }\n    EOF.properties = ['eof'];\n    EOF.create = function (eof) {\n        return new EOF(eof);\n    };\n    inherit(TermTree, EOF, { 'isEOF': true });\n    function Keyword(keyword) {\n        this.keyword = keyword;\n    }\n    Keyword.properties = ['keyword'];\n    Keyword.create = function (keyword) {\n        return new Keyword(keyword);\n    };\n    inherit(TermTree, Keyword, { 'isKeyword': true });\n    function Punc(punc) {\n        this.punc = punc;\n    }\n    Punc.properties = ['punc'];\n    Punc.create = function (punc) {\n        return new Punc(punc);\n    };\n    inherit(TermTree, Punc, { 'isPunc': true });\n    function Delimiter(delim) {\n        this.delim = delim;\n    }\n    Delimiter.properties = ['delim'];\n    Delimiter.create = function (delim) {\n        return new Delimiter(delim);\n    };\n    inherit(TermTree, Delimiter, { 'isDelimiter': true });\n    function LetMacro(name, body) {\n        this.name = name;\n        this.body = body;\n    }\n    LetMacro.properties = [\n        'name',\n        'body'\n    ];\n    LetMacro.create = function (name, body) {\n        return new LetMacro(name, body);\n    };\n    inherit(TermTree, LetMacro, { 'isLetMacro': true });\n    function Macro(name, body) {\n        this.name = name;\n        this.body = body;\n    }\n    Macro.properties = [\n        'name',\n        'body'\n    ];\n    Macro.create = function (name, body) {\n        return new Macro(name, body);\n    };\n    inherit(TermTree, Macro, { 'isMacro': true });\n    function AnonMacro(body) {\n        this.body = body;\n    }\n    AnonMacro.properties = ['body'];\n    AnonMacro.create = function (body) {\n        return new AnonMacro(body);\n    };\n    inherit(TermTree, AnonMacro, { 'isAnonMacro': true });\n    function OperatorDefinition(type, name, prec, assoc, body) {\n        this.type = type;\n        this.name = name;\n        this.prec = prec;\n        this.assoc = assoc;\n        this.body = body;\n    }\n    OperatorDefinition.properties = [\n        'type',\n        'name',\n        'prec',\n        'assoc',\n        'body'\n    ];\n    OperatorDefinition.create = function (type, name, prec, assoc, body) {\n        return new OperatorDefinition(type, name, prec, assoc, body);\n    };\n    inherit(TermTree, OperatorDefinition, { 'isOperatorDefinition': true });\n    function Module(body, exports$3) {\n        this.body = body;\n        this.exports = exports$3;\n    }\n    Module.properties = [\n        'body',\n        'exports'\n    ];\n    Module.create = function (body, exports$3) {\n        return new Module(body, exports$3);\n    };\n    inherit(TermTree, Module, { 'isModule': true });\n    function Export(name) {\n        this.name = name;\n    }\n    Export.properties = ['name'];\n    Export.create = function (name) {\n        return new Export(name);\n    };\n    inherit(TermTree, Export, { 'isExport': true });\n    function VariableDeclaration(ident, eq, init, comma) {\n        this.ident = ident;\n        this.eq = eq;\n        this.init = init;\n        this.comma = comma;\n    }\n    VariableDeclaration.properties = [\n        'ident',\n        'eq',\n        'init',\n        'comma'\n    ];\n    VariableDeclaration.create = function (ident, eq, init, comma) {\n        return new VariableDeclaration(ident, eq, init, comma);\n    };\n    inherit(TermTree, VariableDeclaration, { 'isVariableDeclaration': true });\n    function Statement() {\n    }\n    Statement.properties = [];\n    Statement.create = function () {\n        return new Statement();\n    };\n    inherit(TermTree, Statement, { 'isStatement': true });\n    function Empty() {\n    }\n    Empty.properties = [];\n    Empty.create = function () {\n        return new Empty();\n    };\n    inherit(Statement, Empty, { 'isEmpty': true });\n    function CatchClause(keyword, params, body) {\n        this.keyword = keyword;\n        this.params = params;\n        this.body = body;\n    }\n    CatchClause.properties = [\n        'keyword',\n        'params',\n        'body'\n    ];\n    CatchClause.create = function (keyword, params, body) {\n        return new CatchClause(keyword, params, body);\n    };\n    inherit(Statement, CatchClause, { 'isCatchClause': true });\n    function ForStatement(keyword, cond) {\n        this.keyword = keyword;\n        this.cond = cond;\n    }\n    ForStatement.properties = [\n        'keyword',\n        'cond'\n    ];\n    ForStatement.create = function (keyword, cond) {\n        return new ForStatement(keyword, cond);\n    };\n    inherit(Statement, ForStatement, { 'isForStatement': true });\n    function Expr() {\n    }\n    Expr.properties = [];\n    Expr.create = function () {\n        return new Expr();\n    };\n    inherit(Statement, Expr, { 'isExpr': true });\n    function UnaryOp(op, expr) {\n        this.op = op;\n        this.expr = expr;\n    }\n    UnaryOp.properties = [\n        'op',\n        'expr'\n    ];\n    UnaryOp.create = function (op, expr) {\n        return new UnaryOp(op, expr);\n    };\n    inherit(Expr, UnaryOp, { 'isUnaryOp': true });\n    function PostfixOp(expr, op) {\n        this.expr = expr;\n        this.op = op;\n    }\n    PostfixOp.properties = [\n        'expr',\n        'op'\n    ];\n    PostfixOp.create = function (expr, op) {\n        return new PostfixOp(expr, op);\n    };\n    inherit(Expr, PostfixOp, { 'isPostfixOp': true });\n    function BinOp(left, op, right) {\n        this.left = left;\n        this.op = op;\n        this.right = right;\n    }\n    BinOp.properties = [\n        'left',\n        'op',\n        'right'\n    ];\n    BinOp.create = function (left, op, right) {\n        return new BinOp(left, op, right);\n    };\n    inherit(Expr, BinOp, { 'isBinOp': true });\n    function AssignmentExpression(left, op, right) {\n        this.left = left;\n        this.op = op;\n        this.right = right;\n    }\n    AssignmentExpression.properties = [\n        'left',\n        'op',\n        'right'\n    ];\n    AssignmentExpression.create = function (left, op, right) {\n        return new AssignmentExpression(left, op, right);\n    };\n    inherit(Expr, AssignmentExpression, { 'isAssignmentExpression': true });\n    function ConditionalExpression(cond, question, tru, colon, fls) {\n        this.cond = cond;\n        this.question = question;\n        this.tru = tru;\n        this.colon = colon;\n        this.fls = fls;\n    }\n    ConditionalExpression.properties = [\n        'cond',\n        'question',\n        'tru',\n        'colon',\n        'fls'\n    ];\n    ConditionalExpression.create = function (cond, question, tru, colon, fls) {\n        return new ConditionalExpression(cond, question, tru, colon, fls);\n    };\n    inherit(Expr, ConditionalExpression, { 'isConditionalExpression': true });\n    function NamedFun(keyword, star, name, params, body) {\n        this.keyword = keyword;\n        this.star = star;\n        this.name = name;\n        this.params = params;\n        this.body = body;\n    }\n    NamedFun.properties = [\n        'keyword',\n        'star',\n        'name',\n        'params',\n        'body'\n    ];\n    NamedFun.create = function (keyword, star, name, params, body) {\n        return new NamedFun(keyword, star, name, params, body);\n    };\n    inherit(Expr, NamedFun, { 'isNamedFun': true });\n    function AnonFun(keyword, star, params, body) {\n        this.keyword = keyword;\n        this.star = star;\n        this.params = params;\n        this.body = body;\n    }\n    AnonFun.properties = [\n        'keyword',\n        'star',\n        'params',\n        'body'\n    ];\n    AnonFun.create = function (keyword, star, params, body) {\n        return new AnonFun(keyword, star, params, body);\n    };\n    inherit(Expr, AnonFun, { 'isAnonFun': true });\n    function ArrowFun(params, arrow, body) {\n        this.params = params;\n        this.arrow = arrow;\n        this.body = body;\n    }\n    ArrowFun.properties = [\n        'params',\n        'arrow',\n        'body'\n    ];\n    ArrowFun.create = function (params, arrow, body) {\n        return new ArrowFun(params, arrow, body);\n    };\n    inherit(Expr, ArrowFun, { 'isArrowFun': true });\n    function Const(keyword, call) {\n        this.keyword = keyword;\n        this.call = call;\n    }\n    Const.properties = [\n        'keyword',\n        'call'\n    ];\n    Const.create = function (keyword, call) {\n        return new Const(keyword, call);\n    };\n    inherit(Expr, Const, { 'isConst': true });\n    function ObjDotGet(left, dot, right) {\n        this.left = left;\n        this.dot = dot;\n        this.right = right;\n    }\n    ObjDotGet.properties = [\n        'left',\n        'dot',\n        'right'\n    ];\n    ObjDotGet.create = function (left, dot, right) {\n        return new ObjDotGet(left, dot, right);\n    };\n    inherit(Expr, ObjDotGet, { 'isObjDotGet': true });\n    function ObjGet(left, right) {\n        this.left = left;\n        this.right = right;\n    }\n    ObjGet.properties = [\n        'left',\n        'right'\n    ];\n    ObjGet.create = function (left, right) {\n        return new ObjGet(left, right);\n    };\n    inherit(Expr, ObjGet, { 'isObjGet': true });\n    function YieldExpression(keyword, expr) {\n        this.keyword = keyword;\n        this.expr = expr;\n    }\n    YieldExpression.properties = [\n        'keyword',\n        'expr'\n    ];\n    YieldExpression.create = function (keyword, expr) {\n        return new YieldExpression(keyword, expr);\n    };\n    inherit(Expr, YieldExpression, { 'isYieldExpression': true });\n    function Template(template) {\n        this.template = template;\n    }\n    Template.properties = ['template'];\n    Template.create = function (template) {\n        return new Template(template);\n    };\n    inherit(Expr, Template, { 'isTemplate': true });\n    function PrimaryExpression() {\n    }\n    PrimaryExpression.properties = [];\n    PrimaryExpression.create = function () {\n        return new PrimaryExpression();\n    };\n    inherit(Expr, PrimaryExpression, { 'isPrimaryExpression': true });\n    function ThisExpression(keyword) {\n        this.keyword = keyword;\n    }\n    ThisExpression.properties = ['keyword'];\n    ThisExpression.create = function (keyword) {\n        return new ThisExpression(keyword);\n    };\n    inherit(PrimaryExpression, ThisExpression, { 'isThisExpression': true });\n    function Lit(lit) {\n        this.lit = lit;\n    }\n    Lit.properties = ['lit'];\n    Lit.create = function (lit) {\n        return new Lit(lit);\n    };\n    inherit(PrimaryExpression, Lit, { 'isLit': true });\n    function Block(body) {\n        this.body = body;\n    }\n    Block.properties = ['body'];\n    Block.create = function (body) {\n        return new Block(body);\n    };\n    inherit(PrimaryExpression, Block, { 'isBlock': true });\n    function ArrayLiteral(array) {\n        this.array = array;\n    }\n    ArrayLiteral.properties = ['array'];\n    ArrayLiteral.create = function (array) {\n        return new ArrayLiteral(array);\n    };\n    inherit(PrimaryExpression, ArrayLiteral, { 'isArrayLiteral': true });\n    function ParenExpression(expr) {\n        this.expr = expr;\n    }\n    ParenExpression.properties = ['expr'];\n    ParenExpression.create = function (expr) {\n        return new ParenExpression(expr);\n    };\n    inherit(PrimaryExpression, ParenExpression, { 'isParenExpression': true });\n    function Id(id) {\n        this.id = id;\n    }\n    Id.properties = ['id'];\n    Id.create = function (id) {\n        return new Id(id);\n    };\n    inherit(PrimaryExpression, Id, { 'isId': true });\n    function Partial() {\n    }\n    Partial.properties = [];\n    Partial.create = function () {\n        return new Partial();\n    };\n    inherit(TermTree, Partial, { 'isPartial': true });\n    function PartialOperation(stx, left) {\n        this.stx = stx;\n        this.left = left;\n    }\n    PartialOperation.properties = [\n        'stx',\n        'left'\n    ];\n    PartialOperation.create = function (stx, left) {\n        return new PartialOperation(stx, left);\n    };\n    inherit(Partial, PartialOperation, { 'isPartialOperation': true });\n    function PartialExpression(stx, left, combine) {\n        this.stx = stx;\n        this.left = left;\n        this.combine = combine;\n    }\n    PartialExpression.properties = [\n        'stx',\n        'left',\n        'combine'\n    ];\n    PartialExpression.create = function (stx, left, combine) {\n        return new PartialExpression(stx, left, combine);\n    };\n    inherit(Partial, PartialExpression, { 'isPartialExpression': true });\n    function BindingStatement(keyword, decls) {\n        this.keyword = keyword;\n        this.decls = decls;\n    }\n    BindingStatement.properties = [\n        'keyword',\n        'decls'\n    ];\n    BindingStatement.create = function (keyword, decls) {\n        return new BindingStatement(keyword, decls);\n    };\n    inherit(Statement, BindingStatement, {\n        'isBindingStatement': true,\n        'destruct': function () {\n            return this.keyword.destruct().concat(_.reduce(this.decls, function (acc, decl) {\n                push.apply(acc, decl.destruct());\n                return acc;\n            }, []));\n        }\n    });\n    function VariableStatement(keyword, decls) {\n        this.keyword = keyword;\n        this.decls = decls;\n    }\n    VariableStatement.properties = [\n        'keyword',\n        'decls'\n    ];\n    VariableStatement.create = function (keyword, decls) {\n        return new VariableStatement(keyword, decls);\n    };\n    inherit(BindingStatement, VariableStatement, { 'isVariableStatement': true });\n    function LetStatement(keyword, decls) {\n        this.keyword = keyword;\n        this.decls = decls;\n    }\n    LetStatement.properties = [\n        'keyword',\n        'decls'\n    ];\n    LetStatement.create = function (keyword, decls) {\n        return new LetStatement(keyword, decls);\n    };\n    inherit(BindingStatement, LetStatement, { 'isLetStatement': true });\n    function ConstStatement(keyword, decls) {\n        this.keyword = keyword;\n        this.decls = decls;\n    }\n    ConstStatement.properties = [\n        'keyword',\n        'decls'\n    ];\n    ConstStatement.create = function (keyword, decls) {\n        return new ConstStatement(keyword, decls);\n    };\n    inherit(BindingStatement, ConstStatement, { 'isConstStatement': true });\n    function Call(fun, args, delim, commas) {\n        this.fun = fun;\n        this.args = args;\n        this.delim = delim;\n        this.commas = commas;\n    }\n    Call.properties = [\n        'fun',\n        'args',\n        'delim',\n        'commas'\n    ];\n    Call.create = function (fun, args, delim, commas) {\n        return new Call(fun, args, delim, commas);\n    };\n    inherit(Expr, Call, {\n        'isCall': true,\n        'destruct': function () {\n            assert(this.fun.isTermTree, 'expecting a term tree in destruct of call');\n            var commas = this.commas.slice();\n            var src = this.delim.token;\n            var keys = Object.keys(src);\n            var newtok = {};\n            for (var i = 0, len = keys.length, key; i < len; i++) {\n                key = keys[i];\n                newtok[key] = src[key];\n            }\n            var delim = syntaxFromToken(newtok, this.delim);\n            delim.token.inner = _.reduce(this.args, function (acc, term) {\n                assert(term && term.isTermTree, 'expecting term trees in destruct of Call');\n                push.apply(acc, term.destruct());\n                // add all commas except for the last one\n                if (commas.length > 0) {\n                    acc.push(commas.shift());\n                }\n                return acc;\n            }, []);\n            var res = this.fun.destruct();\n            push.apply(res, Delimiter.create(delim).destruct());\n            return res;\n        }\n    });\n    function stxIsUnaryOp(stx) {\n        var staticOperators = [\n                '+',\n                '-',\n                '~',\n                '!',\n                'delete',\n                'void',\n                'typeof',\n                '++',\n                '--'\n            ];\n        return _.contains(staticOperators, unwrapSyntax(stx));\n    }\n    function stxIsBinOp(stx) {\n        var staticOperators = [\n                '+',\n                '-',\n                '*',\n                '/',\n                '%',\n                '||',\n                '&&',\n                '|',\n                '&',\n                '^',\n                '==',\n                '!=',\n                '===',\n                '!==',\n                '<',\n                '>',\n                '<=',\n                '>=',\n                'in',\n                'instanceof',\n                '<<',\n                '>>',\n                '>>>'\n            ];\n        return _.contains(staticOperators, unwrapSyntax(stx));\n    }\n    function getUnaryOpPrec(op) {\n        var operatorPrecedence = {\n                'new': 16,\n                '++': 15,\n                '--': 15,\n                '!': 14,\n                '~': 14,\n                '+': 14,\n                '-': 14,\n                'typeof': 14,\n                'void': 14,\n                'delete': 14,\n                'yield': 2\n            };\n        return operatorPrecedence[op];\n    }\n    function getBinaryOpPrec(op) {\n        var operatorPrecedence = {\n                '*': 13,\n                '/': 13,\n                '%': 13,\n                '+': 12,\n                '-': 12,\n                '>>': 11,\n                '<<': 11,\n                '>>>': 11,\n                '<': 10,\n                '<=': 10,\n                '>': 10,\n                '>=': 10,\n                'in': 10,\n                'instanceof': 10,\n                '==': 9,\n                '!=': 9,\n                '===': 9,\n                '!==': 9,\n                '&': 8,\n                '^': 7,\n                '|': 6,\n                '&&': 5,\n                '||': 4\n            };\n        return operatorPrecedence[op];\n    }\n    function getBinaryOpAssoc(op) {\n        var operatorAssoc = {\n                '*': 'left',\n                '/': 'left',\n                '%': 'left',\n                '+': 'left',\n                '-': 'left',\n                '>>': 'left',\n                '<<': 'left',\n                '>>>': 'left',\n                '<': 'left',\n                '<=': 'left',\n                '>': 'left',\n                '>=': 'left',\n                'in': 'left',\n                'instanceof': 'left',\n                '==': 'left',\n                '!=': 'left',\n                '===': 'left',\n                '!==': 'left',\n                '&': 'left',\n                '^': 'left',\n                '|': 'left',\n                '&&': 'left',\n                '||': 'left'\n            };\n        return operatorAssoc[op];\n    }\n    function stxIsAssignOp(stx) {\n        var staticOperators = [\n                '=',\n                '+=',\n                '-=',\n                '*=',\n                '/=',\n                '%=',\n                '<<=',\n                '>>=',\n                '>>>=',\n                '|=',\n                '^=',\n                '&='\n            ];\n        return _.contains(staticOperators, unwrapSyntax(stx));\n    }\n    function enforestVarStatement(stx, context, varStx) {\n        var decls = [];\n        var rest = stx;\n        var rhs;\n        if (!rest.length) {\n            throwSyntaxError('enforest', 'Unexpected end of input', varStx);\n        }\n        if (expandCount >= maxExpands) {\n            return null;\n        }\n        while (rest.length) {\n            if (rest[0].token.type === parser.Token.Identifier) {\n                if (rest[1] && rest[1].token.type === parser.Token.Punctuator && rest[1].token.value === '=') {\n                    rhs = get_expression(rest.slice(2), context);\n                    if (rhs.result == null) {\n                        throwSyntaxError('enforest', 'Unexpected token', rhs.rest[0]);\n                    }\n                    if (rhs.rest[0].token.type === parser.Token.Punctuator && rhs.rest[0].token.value === ',') {\n                        decls.push(VariableDeclaration.create(rest[0], rest[1], rhs.result, rhs.rest[0]));\n                        rest = rhs.rest.slice(1);\n                        continue;\n                    } else {\n                        decls.push(VariableDeclaration.create(rest[0], rest[1], rhs.result, null));\n                        rest = rhs.rest;\n                        break;\n                    }\n                } else if (rest[1] && rest[1].token.type === parser.Token.Punctuator && rest[1].token.value === ',') {\n                    decls.push(VariableDeclaration.create(rest[0], null, null, rest[1]));\n                    rest = rest.slice(2);\n                } else {\n                    decls.push(VariableDeclaration.create(rest[0], null, null, null));\n                    rest = rest.slice(1);\n                    break;\n                }\n            } else {\n                throwSyntaxError('enforest', 'Unexpected token', rest[0]);\n            }\n        }\n        return {\n            result: decls,\n            rest: rest\n        };\n    }\n    function enforestAssignment(stx, context, left, prevStx, prevTerms) {\n        var op = stx[0];\n        var rightStx = stx.slice(1);\n        var opTerm = Punc.create(stx[0]);\n        var opPrevStx = tagWithTerm(opTerm, [stx[0]]).concat(tagWithTerm(left, left.destruct().reverse()), prevStx);\n        var opPrevTerms = [\n                opTerm,\n                left\n            ].concat(prevTerms);\n        var opRes = enforest(rightStx, context, opPrevStx, opPrevTerms);\n        if (opRes.result) {\n            // Lookbehind was matched, so it may not even be a binop anymore.\n            if (opRes.prevTerms.length < opPrevTerms.length) {\n                return opRes;\n            }\n            var right = opRes.result;\n            // only a binop if the right is a real expression\n            // so 2+2++ will only match 2+2\n            if (right.isExpr) {\n                var term = AssignmentExpression.create(left, op, right);\n                return {\n                    result: term,\n                    rest: opRes.rest,\n                    prevStx: prevStx,\n                    prevTerms: prevTerms\n                };\n            }\n        } else {\n            return opRes;\n        }\n    }\n    function adjustLineContext(stx, original, current) {\n        current = current || {\n            lastLineNumber: original.token.lineNumber,\n            lineNumber: original.token.lineNumber - 1\n        };\n        return _.map(stx, function (stx$2) {\n            if (stx$2.token.type === parser.Token.Delimiter) {\n                // handle tokens with missing line info\n                stx$2.token.startLineNumber = typeof stx$2.token.startLineNumber == 'undefined' ? original.token.lineNumber : stx$2.token.startLineNumber;\n                stx$2.token.endLineNumber = typeof stx$2.token.endLineNumber == 'undefined' ? original.token.lineNumber : stx$2.token.endLineNumber;\n                stx$2.token.startLineStart = typeof stx$2.token.startLineStart == 'undefined' ? original.token.lineStart : stx$2.token.startLineStart;\n                stx$2.token.endLineStart = typeof stx$2.token.endLineStart == 'undefined' ? original.token.lineStart : stx$2.token.endLineStart;\n                stx$2.token.startRange = typeof stx$2.token.startRange == 'undefined' ? original.token.range : stx$2.token.startRange;\n                stx$2.token.endRange = typeof stx$2.token.endRange == 'undefined' ? original.token.range : stx$2.token.endRange;\n                stx$2.token.sm_startLineNumber = typeof stx$2.token.sm_startLineNumber == 'undefined' ? stx$2.token.startLineNumber : stx$2.token.sm_startLineNumber;\n                stx$2.token.sm_endLineNumber = typeof stx$2.token.sm_endLineNumber == 'undefined' ? stx$2.token.endLineNumber : stx$2.token.sm_endLineNumber;\n                stx$2.token.sm_startLineStart = typeof stx$2.token.sm_startLineStart == 'undefined' ? stx$2.token.startLineStart : stx$2.token.sm_startLineStart;\n                stx$2.token.sm_endLineStart = typeof stx$2.token.sm_endLineStart == 'undefined' ? stx$2.token.endLineStart : stx$2.token.sm_endLineStart;\n                stx$2.token.sm_startRange = typeof stx$2.token.sm_startRange == 'undefined' ? stx$2.token.startRange : stx$2.token.sm_startRange;\n                stx$2.token.sm_endRange = typeof stx$2.token.sm_endRange == 'undefined' ? stx$2.token.endRange : stx$2.token.sm_endRange;\n                if (stx$2.token.startLineNumber === current.lastLineNumber && current.lastLineNumber !== current.lineNumber) {\n                    stx$2.token.startLineNumber = current.lineNumber;\n                } else if (stx$2.token.startLineNumber !== current.lastLineNumber) {\n                    current.lineNumber++;\n                    current.lastLineNumber = stx$2.token.startLineNumber;\n                    stx$2.token.startLineNumber = current.lineNumber;\n                }\n                if (stx$2.token.inner.length > 0) {\n                    stx$2.token.inner = adjustLineContext(stx$2.token.inner, original, current);\n                }\n                return stx$2;\n            }\n            // handle tokens with missing line info\n            stx$2.token.lineNumber = typeof stx$2.token.lineNumber == 'undefined' ? original.token.lineNumber : stx$2.token.lineNumber;\n            stx$2.token.lineStart = typeof stx$2.token.lineStart == 'undefined' ? original.token.lineStart : stx$2.token.lineStart;\n            stx$2.token.range = typeof stx$2.token.range == 'undefined' ? original.token.range : stx$2.token.range;\n            // Only set the sourcemap line info once. Necessary because a single\n            // syntax object can go through expansion multiple times. If at some point\n            // we want to write an expansion stepper this might be a good place to store\n            // intermediate expansion line info (ie push to a stack instead of\n            // just write once).\n            stx$2.token.sm_lineNumber = typeof stx$2.token.sm_lineNumber == 'undefined' ? stx$2.token.lineNumber : stx$2.token.sm_lineNumber;\n            stx$2.token.sm_lineStart = typeof stx$2.token.sm_lineStart == 'undefined' ? stx$2.token.lineStart : stx$2.token.sm_lineStart;\n            stx$2.token.sm_range = typeof stx$2.token.sm_range == 'undefined' ? stx$2.token.range.slice() : stx$2.token.sm_range;\n            // move the line info to line up with the macro name\n            // (line info starting from the macro name)\n            if (stx$2.token.lineNumber === current.lastLineNumber && current.lastLineNumber !== current.lineNumber) {\n                stx$2.token.lineNumber = current.lineNumber;\n            } else if (stx$2.token.lineNumber !== current.lastLineNumber) {\n                current.lineNumber++;\n                current.lastLineNumber = stx$2.token.lineNumber;\n                stx$2.token.lineNumber = current.lineNumber;\n            }\n            return stx$2;\n        });\n    }\n    function getName(head, rest) {\n        var idx = 0;\n        var curr = head;\n        var next = rest[idx];\n        var name = [head];\n        while (true) {\n            if (next && (next.token.type === parser.Token.Punctuator || next.token.type === parser.Token.Identifier || next.token.type === parser.Token.Keyword) && curr.token.range[1] === next.token.range[0]) {\n                name.push(next);\n                curr = next;\n                next = rest[++idx];\n            } else {\n                return name;\n            }\n        }\n    }\n    function getMacroInEnv(head, rest, env) {\n        if (!(head.token.type === parser.Token.Identifier || head.token.type === parser.Token.Keyword || head.token.type === parser.Token.Punctuator)) {\n            return null;\n        }\n        var name = getName(head, rest);\n        // simple case, don't need to create a new syntax object\n        if (name.length === 1) {\n            if (env.names.get(unwrapSyntax(name[0]))) {\n                var resolvedName = resolve(name[0]);\n                if (env.has(resolvedName)) {\n                    return env.get(resolvedName);\n                }\n            }\n            return null;\n        } else {\n            while (name.length > 0) {\n                var nameStr = name.map(unwrapSyntax).join('');\n                if (env.names.get(nameStr)) {\n                    var nameStx = syn.makeIdent(nameStr, name[0]);\n                    var resolvedName = resolve(nameStx);\n                    if (env.has(resolvedName)) {\n                        return env.get(resolvedName);\n                    }\n                }\n                name.pop();\n            }\n            return null;\n        }\n    }\n    function nameInEnv(head, rest, env) {\n        return getMacroInEnv(head, rest, env) !== null;\n    }\n    // This should only be used on things that can't be rebound except by\n    // macros (puncs, keywords).\n    function resolveFast(stx, env) {\n        var name = unwrapSyntax(stx);\n        return env.names.get(name) ? resolve(stx) : name;\n    }\n    function expandMacro(stx, context, opCtx, opType, macroObj) {\n        // pull the macro transformer out the environment\n        var head = stx[0];\n        var rest = stx.slice(1);\n        macroObj = macroObj || getMacroInEnv(head, rest, context.env);\n        var stxArg = rest.slice(macroObj.fullName.length - 1);\n        var transformer;\n        if (opType != null) {\n            assert(opType === 'binary' || opType === 'unary', 'operator type should be either unary or binary: ' + opType);\n            transformer = macroObj[opType].fn;\n        } else {\n            transformer = macroObj.fn;\n        }\n        // create a new mark to be used for the input to\n        // the macro\n        var newMark = fresh();\n        var transformerContext = makeExpanderContext(_.defaults({ mark: newMark }, context));\n        // apply the transformer\n        var rt;\n        try {\n            rt = transformer([head].concat(stxArg), transformerContext, opCtx.prevStx, opCtx.prevTerms);\n        } catch (e) {\n            if (e instanceof SyntaxCaseError) {\n                // add a nicer error for syntax case\n                var nameStr = macroObj.fullName.map(function (stx$2) {\n                        return stx$2.token.value;\n                    }).join('');\n                if (opType != null) {\n                    var argumentString = '`' + stxArg.slice(0, 5).map(function (stx$2) {\n                            return stx$2.token.value;\n                        }).join(' ') + '...`';\n                    throwSyntaxError('operator', 'Operator `' + nameStr + '` could not be matched with ' + argumentString, head);\n                } else {\n                    var argumentString = '`' + stxArg.slice(0, 5).map(function (stx$2) {\n                            return stx$2.token.value;\n                        }).join(' ') + '...`';\n                    throwSyntaxError('macro', 'Macro `' + nameStr + '` could not be matched with ' + argumentString, head);\n                }\n            } else {\n                // just rethrow it\n                throw e;\n            }\n        }\n        if (!builtinMode && !macroObj.builtin) {\n            expandCount++;\n        }\n        if (!Array.isArray(rt.result)) {\n            throwSyntaxError('enforest', 'Macro must return a syntax array', stx[0]);\n        }\n        if (rt.result.length > 0) {\n            var adjustedResult = adjustLineContext(rt.result, head);\n            if (stx[0].token.leadingComments) {\n                if (adjustedResult[0].token.leadingComments) {\n                    adjustedResult[0].token.leadingComments = adjustedResult[0].token.leadingComments.concat(head.token.leadingComments);\n                } else {\n                    adjustedResult[0].token.leadingComments = head.token.leadingComments;\n                }\n            }\n            rt.result = adjustedResult;\n        }\n        return rt;\n    }\n    function comparePrec(left, right, assoc) {\n        if (assoc === 'left') {\n            return left <= right;\n        }\n        return left < right;\n    }\n    // enforest the tokens, returns an object with the `result` TermTree and\n    // the uninterpreted `rest` of the syntax\n    function enforest(toks, context, prevStx, prevTerms) {\n        assert(toks.length > 0, 'enforest assumes there are tokens to work with');\n        prevStx = prevStx || [];\n        prevTerms = prevTerms || [];\n        if (expandCount >= maxExpands) {\n            return {\n                result: null,\n                rest: toks\n            };\n        }\n        function step(head, rest, opCtx) {\n            var innerTokens;\n            assert(Array.isArray(rest), 'result must at least be an empty array');\n            if (head.isTermTree) {\n                var isCustomOp = false;\n                var uopMacroObj;\n                var uopSyntax;\n                if (head.isPunc || head.isKeyword || head.isId) {\n                    if (head.isPunc) {\n                        uopSyntax = head.punc;\n                    } else if (head.isKeyword) {\n                        uopSyntax = head.keyword;\n                    } else if (head.isId) {\n                        uopSyntax = head.id;\n                    }\n                    uopMacroObj = getMacroInEnv(uopSyntax, rest, context.env);\n                    isCustomOp = uopMacroObj && uopMacroObj.isOp;\n                }\n                // look up once (we want to check multiple properties on bopMacroObj\n                // without repeatedly calling getMacroInEnv)\n                var bopMacroObj;\n                if (rest[0] && rest[1]) {\n                    bopMacroObj = getMacroInEnv(rest[0], rest.slice(1), context.env);\n                }\n                // unary operator\n                if (isCustomOp && uopMacroObj.unary || uopSyntax && stxIsUnaryOp(uopSyntax)) {\n                    var uopPrec;\n                    if (isCustomOp && uopMacroObj.unary) {\n                        uopPrec = uopMacroObj.unary.prec;\n                    } else {\n                        uopPrec = getUnaryOpPrec(unwrapSyntax(uopSyntax));\n                    }\n                    var opRest = rest;\n                    var uopMacroName;\n                    if (uopMacroObj) {\n                        uopMacroName = [uopSyntax].concat(rest.slice(0, uopMacroObj.fullName.length - 1));\n                        opRest = rest.slice(uopMacroObj.fullName.length - 1);\n                    }\n                    var leftLeft = opCtx.prevTerms[0] && opCtx.prevTerms[0].isPartial ? opCtx.prevTerms[0] : null;\n                    var unopTerm = PartialOperation.create(head, leftLeft);\n                    var unopPrevStx = tagWithTerm(unopTerm, head.destruct().reverse()).concat(opCtx.prevStx);\n                    var unopPrevTerms = [unopTerm].concat(opCtx.prevTerms);\n                    var unopOpCtx = _.extend({}, opCtx, {\n                            combine: function (t) {\n                                if (t.isExpr) {\n                                    if (isCustomOp && uopMacroObj.unary) {\n                                        var rt$2 = expandMacro(uopMacroName.concat(t.destruct()), context, opCtx, 'unary');\n                                        var newt = get_expression(rt$2.result, context);\n                                        assert(newt.rest.length === 0, 'should never have left over syntax');\n                                        return opCtx.combine(newt.result);\n                                    }\n                                    return opCtx.combine(UnaryOp.create(uopSyntax, t));\n                                } else {\n                                    // not actually an expression so don't create\n                                    // a UnaryOp term just return with the punctuator\n                                    return opCtx.combine(head);\n                                }\n                            },\n                            prec: uopPrec,\n                            prevStx: unopPrevStx,\n                            prevTerms: unopPrevTerms,\n                            op: unopTerm\n                        });\n                    return step(opRest[0], opRest.slice(1), unopOpCtx);\n                }    // BinOp\n                else if (head.isExpr && (rest[0] && rest[1] && (stxIsBinOp(rest[0]) && !bopMacroObj || bopMacroObj && bopMacroObj.isOp && bopMacroObj.binary))) {\n                    var opRes;\n                    var op = rest[0];\n                    var left = head;\n                    var rightStx = rest.slice(1);\n                    var leftLeft = opCtx.prevTerms[0] && opCtx.prevTerms[0].isPartial ? opCtx.prevTerms[0] : null;\n                    var leftTerm = PartialExpression.create(head.destruct(), leftLeft, function () {\n                            return step(head, [], opCtx);\n                        });\n                    var opTerm = PartialOperation.create(op, leftTerm);\n                    var opPrevStx = tagWithTerm(opTerm, [rest[0]]).concat(tagWithTerm(leftTerm, head.destruct()).reverse(), opCtx.prevStx);\n                    var opPrevTerms = [\n                            opTerm,\n                            leftTerm\n                        ].concat(opCtx.prevTerms);\n                    var isCustomOp = bopMacroObj && bopMacroObj.isOp && bopMacroObj.binary;\n                    var bopPrec;\n                    var bopAssoc;\n                    if (isCustomOp && bopMacroObj.binary) {\n                        bopPrec = bopMacroObj.binary.prec;\n                        bopAssoc = bopMacroObj.binary.assoc;\n                    } else {\n                        bopPrec = getBinaryOpPrec(unwrapSyntax(op));\n                        bopAssoc = getBinaryOpAssoc(unwrapSyntax(op));\n                    }\n                    assert(bopPrec !== undefined, 'expecting a precedence for operator: ' + op);\n                    var newStack;\n                    if (comparePrec(bopPrec, opCtx.prec, bopAssoc)) {\n                        var bopCtx = opCtx;\n                        var combResult = opCtx.combine(head);\n                        if (opCtx.stack.length > 0) {\n                            return step(combResult.term, rest, opCtx.stack[0]);\n                        }\n                        left = combResult.term;\n                        newStack = opCtx.stack;\n                        opPrevStx = combResult.prevStx;\n                        opPrevTerms = combResult.prevTerms;\n                    } else {\n                        newStack = [opCtx].concat(opCtx.stack);\n                    }\n                    assert(opCtx.combine !== undefined, 'expecting a combine function');\n                    var opRightStx = rightStx;\n                    var bopMacroName;\n                    if (isCustomOp) {\n                        bopMacroName = rest.slice(0, bopMacroObj.fullName.length);\n                        opRightStx = rightStx.slice(bopMacroObj.fullName.length - 1);\n                    }\n                    var bopOpCtx = _.extend({}, opCtx, {\n                            combine: function (right) {\n                                if (right.isExpr) {\n                                    if (isCustomOp && bopMacroObj.binary) {\n                                        var leftStx = left.destruct();\n                                        var rightStx$2 = right.destruct();\n                                        var rt$2 = expandMacro(bopMacroName.concat(syn.makeDelim('()', leftStx, leftStx[0]), syn.makeDelim('()', rightStx$2, rightStx$2[0])), context, opCtx, 'binary');\n                                        var newt = get_expression(rt$2.result, context);\n                                        assert(newt.rest.length === 0, 'should never have left over syntax');\n                                        return {\n                                            term: newt.result,\n                                            prevStx: opCtx.prevStx,\n                                            prevTerms: opCtx.prevTerms\n                                        };\n                                    }\n                                    return {\n                                        term: BinOp.create(left, op, right),\n                                        prevStx: opCtx.prevStx,\n                                        prevTerms: opCtx.prevTerms\n                                    };\n                                } else {\n                                    return {\n                                        term: head,\n                                        prevStx: opCtx.prevStx,\n                                        prevTerms: opCtx.prevTerms\n                                    };\n                                }\n                            },\n                            prec: bopPrec,\n                            op: opTerm,\n                            stack: newStack,\n                            prevStx: opPrevStx,\n                            prevTerms: opPrevTerms\n                        });\n                    return step(opRightStx[0], opRightStx.slice(1), bopOpCtx);\n                }    // Call\n                else if (head.isExpr && (rest[0] && rest[0].token.type === parser.Token.Delimiter && rest[0].token.value === '()')) {\n                    var argRes, enforestedArgs = [], commas = [];\n                    rest[0].expose();\n                    innerTokens = rest[0].token.inner;\n                    while (innerTokens.length > 0) {\n                        argRes = enforest(innerTokens, context);\n                        if (!argRes.result) {\n                            break;\n                        }\n                        enforestedArgs.push(argRes.result);\n                        innerTokens = argRes.rest;\n                        if (innerTokens[0] && innerTokens[0].token.value === ',') {\n                            // record the comma for later\n                            commas.push(innerTokens[0]);\n                            // but dump it for the next loop turn\n                            innerTokens = innerTokens.slice(1);\n                        } else {\n                            // either there are no more tokens or\n                            // they aren't a comma, either way we\n                            // are done with the loop\n                            break;\n                        }\n                    }\n                    var argsAreExprs = _.all(enforestedArgs, function (argTerm) {\n                            return argTerm.isExpr;\n                        });\n                    // only a call if we can completely enforest each argument and\n                    // each argument is an expression\n                    if (innerTokens.length === 0 && argsAreExprs) {\n                        return step(Call.create(head, enforestedArgs, rest[0], commas), rest.slice(1), opCtx);\n                    }\n                }    // Conditional ( x ? true : false)\n                else if (head.isExpr && (rest[0] && resolveFast(rest[0], context.env) === '?')) {\n                    var question = rest[0];\n                    var condRes = enforest(rest.slice(1), context);\n                    if (condRes.result) {\n                        var truExpr = condRes.result;\n                        var condRight = condRes.rest;\n                        if (truExpr.isExpr && condRight[0] && resolveFast(condRight[0], context.env) === ':') {\n                            var colon = condRight[0];\n                            var flsRes = enforest(condRight.slice(1), context);\n                            var flsExpr = flsRes.result;\n                            if (flsExpr.isExpr) {\n                                return step(ConditionalExpression.create(head, question, truExpr, colon, flsExpr), flsRes.rest, opCtx);\n                            }\n                        }\n                    }\n                }    // Constructor\n                else if (head.isKeyword && resolveFast(head.keyword, context.env) === 'new' && rest[0]) {\n                    var newCallRes = enforest(rest, context);\n                    if (newCallRes && newCallRes.result.isExpr) {\n                        return step(Const.create(head, newCallRes.result), newCallRes.rest, opCtx);\n                    }\n                }    // Arrow functions with expression bodies\n                else if (head.isDelimiter && head.delim.token.value === '()' && rest[0] && rest[0].token.type === parser.Token.Punctuator && resolveFast(rest[0], context.env) === '=>') {\n                    var arrowRes = enforest(rest.slice(1), context);\n                    if (arrowRes.result && arrowRes.result.isExpr) {\n                        return step(ArrowFun.create(head.delim, rest[0], arrowRes.result.destruct()), arrowRes.rest, opCtx);\n                    } else {\n                        throwSyntaxError('enforest', 'Body of arrow function must be an expression', rest.slice(1));\n                    }\n                }    // Arrow functions with expression bodies\n                else if (head.isId && rest[0] && rest[0].token.type === parser.Token.Punctuator && resolveFast(rest[0], context.env) === '=>') {\n                    var res = enforest(rest.slice(1), context);\n                    if (res.result && res.result.isExpr) {\n                        return step(ArrowFun.create(head.id, rest[0], res.result.destruct()), res.rest, opCtx);\n                    } else {\n                        throwSyntaxError('enforest', 'Body of arrow function must be an expression', rest.slice(1));\n                    }\n                }    // ParenExpr\n                else if (head.isDelimiter && head.delim.token.value === '()') {\n                    innerTokens = head.delim.expose().token.inner;\n                    // empty parens are acceptable but enforest\n                    // doesn't accept empty arrays so short\n                    // circuit here\n                    if (innerTokens.length === 0) {\n                        head.delim.token.inner = [Empty.create()];\n                        return step(ParenExpression.create(head), rest, opCtx);\n                    } else {\n                        var innerTerm = get_expression(innerTokens, context);\n                        if (innerTerm.result && innerTerm.result.isExpr && innerTerm.rest.length === 0) {\n                            head.delim.token.inner = [innerTerm.result];\n                            return step(ParenExpression.create(head), rest, opCtx);\n                        }\n                    }    // if the tokens inside the paren aren't an expression\n                         // we just leave it as a delimiter\n                }    // AssignmentExpression\n                else if (head.isExpr && ((head.isId || head.isObjGet || head.isObjDotGet || head.isThisExpression) && rest[0] && rest[1] && !bopMacroObj && stxIsAssignOp(rest[0]))) {\n                    var opRes = enforestAssignment(rest, context, head, prevStx, prevTerms);\n                    if (opRes && opRes.result) {\n                        return step(opRes.result, opRes.rest, _.extend({}, opCtx, {\n                            prevStx: opRes.prevStx,\n                            prevTerms: opRes.prevTerms\n                        }));\n                    }\n                }    // Postfix\n                else if (head.isExpr && (rest[0] && (unwrapSyntax(rest[0]) === '++' || unwrapSyntax(rest[0]) === '--'))) {\n                    // Check if the operator is a macro first.\n                    if (context.env.has(resolveFast(rest[0], context.env))) {\n                        var headStx = tagWithTerm(head, head.destruct().reverse());\n                        var opPrevStx = headStx.concat(prevStx);\n                        var opPrevTerms = [head].concat(prevTerms);\n                        var opRes = enforest(rest, context, opPrevStx, opPrevTerms);\n                        if (opRes.prevTerms.length < opPrevTerms.length) {\n                            return opRes;\n                        } else if (opRes.result) {\n                            return step(head, opRes.result.destruct().concat(opRes.rest), opCtx);\n                        }\n                    }\n                    return step(PostfixOp.create(head, rest[0]), rest.slice(1), opCtx);\n                }    // ObjectGet (computed)\n                else if (head.isExpr && (rest[0] && rest[0].token.value === '[]')) {\n                    return step(ObjGet.create(head, Delimiter.create(rest[0].expose())), rest.slice(1), opCtx);\n                }    // ObjectGet\n                else if (head.isExpr && (rest[0] && unwrapSyntax(rest[0]) === '.' && !context.env.has(resolveFast(rest[0], context.env)) && rest[1] && (rest[1].token.type === parser.Token.Identifier || rest[1].token.type === parser.Token.Keyword))) {\n                    // Check if the identifier is a macro first.\n                    if (context.env.has(resolveFast(rest[1], context.env))) {\n                        var headStx = tagWithTerm(head, head.destruct().reverse());\n                        var dotTerm = Punc.create(rest[0]);\n                        var dotTerms = [dotTerm].concat(head, prevTerms);\n                        var dotStx = tagWithTerm(dotTerm, [rest[0]]).concat(headStx, prevStx);\n                        var dotRes = enforest(rest.slice(1), context, dotStx, dotTerms);\n                        if (dotRes.prevTerms.length < dotTerms.length) {\n                            return dotRes;\n                        } else if (dotRes.result) {\n                            return step(head, [rest[0]].concat(dotRes.result.destruct(), dotRes.rest), opCtx);\n                        }\n                    }\n                    return step(ObjDotGet.create(head, rest[0], rest[1]), rest.slice(2), opCtx);\n                }    // ArrayLiteral\n                else if (head.isDelimiter && head.delim.token.value === '[]') {\n                    return step(ArrayLiteral.create(head), rest, opCtx);\n                }    // Block\n                else if (head.isDelimiter && head.delim.token.value === '{}') {\n                    return step(Block.create(head), rest, opCtx);\n                }    // quote syntax\n                else if (head.isId && unwrapSyntax(head.id) === '#quoteSyntax' && rest[0] && rest[0].token.value === '{}') {\n                    var tempId = fresh();\n                    context.templateMap.set(tempId, rest[0].token.inner);\n                    return step(syn.makeIdent('getTemplate', head.id), [syn.makeDelim('()', [syn.makeValue(tempId, head.id)], head.id)].concat(rest.slice(1)), opCtx);\n                }    // let statements\n                else if (head.isKeyword && unwrapSyntax(head.keyword) === 'let') {\n                    var nameTokens = [];\n                    if (rest[0] && rest[0].token.type === parser.Token.Delimiter && rest[0].token.value === '()') {\n                        nameTokens = rest[0].token.inner;\n                    } else {\n                        nameTokens.push(rest[0]);\n                    }\n                    // Let macro\n                    if (rest[1] && rest[1].token.value === '=' && rest[2] && rest[2].token.value === 'macro') {\n                        var mac = enforest(rest.slice(2), context);\n                        if (mac.result) {\n                            if (!mac.result.isAnonMacro) {\n                                throwSyntaxError('enforest', 'expecting an anonymous macro definition in syntax let binding', rest.slice(2));\n                            }\n                            return step(LetMacro.create(nameTokens, mac.result.body), mac.rest, opCtx);\n                        }\n                    }    // Let statement\n                    else {\n                        var lsRes = enforestVarStatement(rest, context, head.keyword);\n                        if (lsRes && lsRes.result) {\n                            return step(LetStatement.create(head, lsRes.result), lsRes.rest, opCtx);\n                        }\n                    }\n                }    // VariableStatement\n                else if (head.isKeyword && unwrapSyntax(head.keyword) === 'var' && rest[0]) {\n                    var vsRes = enforestVarStatement(rest, context, head.keyword);\n                    if (vsRes && vsRes.result) {\n                        return step(VariableStatement.create(head, vsRes.result), vsRes.rest, opCtx);\n                    }\n                }    // Const Statement\n                else if (head.isKeyword && unwrapSyntax(head.keyword) === 'const' && rest[0]) {\n                    var csRes = enforestVarStatement(rest, context, head.keyword);\n                    if (csRes && csRes.result) {\n                        return step(ConstStatement.create(head, csRes.result), csRes.rest, opCtx);\n                    }\n                }    // for statement\n                else if (head.isKeyword && unwrapSyntax(head.keyword) === 'for' && rest[0] && rest[0].token.value === '()') {\n                    return step(ForStatement.create(head.keyword, rest[0]), rest.slice(1), opCtx);\n                }    // yield statement\n                else if (head.isKeyword && unwrapSyntax(head.keyword) === 'yield') {\n                    var yieldExprRes = enforest(rest, context);\n                    if (yieldExprRes.result && yieldExprRes.result.isExpr) {\n                        return step(YieldExpression.create(head.keyword, yieldExprRes.result), yieldExprRes.rest, opCtx);\n                    }\n                }\n            } else {\n                assert(head && head.token, 'assuming head is a syntax object');\n                var macroObj = expandCount < maxExpands && getMacroInEnv(head, rest, context.env);\n                // macro invocation\n                if (macroObj && !macroObj.isOp) {\n                    var rt = expandMacro([head].concat(rest), context, opCtx, null, macroObj);\n                    var newOpCtx = opCtx;\n                    if (rt.prevTerms && rt.prevTerms.length < opCtx.prevTerms.length) {\n                        newOpCtx = rewindOpCtx(opCtx, rt);\n                    }\n                    if (rt.result.length > 0) {\n                        return step(rt.result[0], rt.result.slice(1).concat(rt.rest), newOpCtx);\n                    } else {\n                        return step(Empty.create(), rt.rest, newOpCtx);\n                    }\n                }    // anon macro definition\n                else if (head.token.type === parser.Token.Identifier && resolve(head) === 'macro' && rest[0] && rest[0].token.value === '{}') {\n                    return step(AnonMacro.create(rest[0].expose().token.inner), rest.slice(1), opCtx);\n                }    // macro definition\n                else if (head.token.type === parser.Token.Identifier && resolve(head) === 'macro') {\n                    var nameTokens = [];\n                    if (rest[0] && rest[0].token.type === parser.Token.Delimiter && rest[0].token.value === '()') {\n                        nameTokens = rest[0].expose().token.inner;\n                    } else {\n                        nameTokens.push(rest[0]);\n                    }\n                    if (rest[1] && rest[1].token.type === parser.Token.Delimiter) {\n                        return step(Macro.create(nameTokens, rest[1].expose().token.inner), rest.slice(2), opCtx);\n                    } else {\n                        throwSyntaxError('enforest', 'Macro declaration must include body', rest[1]);\n                    }\n                }    // operator definition\n                     // unaryop (neg) 1 { macro { rule { $op:expr } => { $op } } }\n                else if (head.token.type === parser.Token.Identifier && head.token.value === 'unaryop' && rest[0] && rest[0].token.type === parser.Token.Delimiter && rest[0].token.value === '()' && rest[1] && rest[1].token.type === parser.Token.NumericLiteral && rest[2] && rest[2].token.type === parser.Token.Delimiter && rest[2] && rest[2].token.value === '{}') {\n                    var trans = enforest(rest[2].expose().token.inner, context);\n                    return step(OperatorDefinition.create('unary', rest[0].expose().token.inner, rest[1], null, trans.result.body), rest.slice(3), opCtx);\n                }    // operator definition\n                     // binaryop (neg) 1 left { macro { rule { $op:expr } => { $op } } }\n                else if (head.token.type === parser.Token.Identifier && head.token.value === 'binaryop' && rest[0] && rest[0].token.type === parser.Token.Delimiter && rest[0].token.value === '()' && rest[1] && rest[1].token.type === parser.Token.NumericLiteral && rest[2] && rest[2].token.type === parser.Token.Identifier && rest[3] && rest[3].token.type === parser.Token.Delimiter && rest[3] && rest[3].token.value === '{}') {\n                    var trans = enforest(rest[3].expose().token.inner, context);\n                    return step(OperatorDefinition.create('binary', rest[0].expose().token.inner, rest[1], rest[2], trans.result.body), rest.slice(4), opCtx);\n                }    // module definition\n                else if (unwrapSyntax(head) === 'module' && rest[0] && rest[0].token.value === '{}') {\n                    return step(Module.create(rest[0], []), rest.slice(1), opCtx);\n                }    // function definition\n                else if (head.token.type === parser.Token.Keyword && unwrapSyntax(head) === 'function' && rest[0] && rest[0].token.type === parser.Token.Identifier && rest[1] && rest[1].token.type === parser.Token.Delimiter && rest[1].token.value === '()' && rest[2] && rest[2].token.type === parser.Token.Delimiter && rest[2].token.value === '{}') {\n                    rest[1].token.inner = rest[1].expose().token.inner;\n                    rest[2].token.inner = rest[2].expose().token.inner;\n                    return step(NamedFun.create(head, null, rest[0], rest[1], rest[2]), rest.slice(3), opCtx);\n                }    // generator function definition\n                else if (head.token.type === parser.Token.Keyword && unwrapSyntax(head) === 'function' && rest[0] && rest[0].token.type === parser.Token.Punctuator && rest[0].token.value === '*' && rest[1] && rest[1].token.type === parser.Token.Identifier && rest[2] && rest[2].token.type === parser.Token.Delimiter && rest[2].token.value === '()' && rest[3] && rest[3].token.type === parser.Token.Delimiter && rest[3].token.value === '{}') {\n                    rest[2].token.inner = rest[2].expose().token.inner;\n                    rest[3].token.inner = rest[3].expose().token.inner;\n                    return step(NamedFun.create(head, rest[0], rest[1], rest[2], rest[3]), rest.slice(4), opCtx);\n                }    // anonymous function definition\n                else if (head.token.type === parser.Token.Keyword && unwrapSyntax(head) === 'function' && rest[0] && rest[0].token.type === parser.Token.Delimiter && rest[0].token.value === '()' && rest[1] && rest[1].token.type === parser.Token.Delimiter && rest[1].token.value === '{}') {\n                    rest[0].token.inner = rest[0].expose().token.inner;\n                    rest[1].token.inner = rest[1].expose().token.inner;\n                    return step(AnonFun.create(head, null, rest[0], rest[1]), rest.slice(2), opCtx);\n                }    // anonymous generator function definition\n                else if (head.token.type === parser.Token.Keyword && unwrapSyntax(head) === 'function' && rest[0] && rest[0].token.type === parser.Token.Punctuator && rest[0].token.value === '*' && rest[1] && rest[1].token.type === parser.Token.Delimiter && rest[1].token.value === '()' && rest[2] && rest[2].token.type === parser.Token.Delimiter && rest[2].token.value === '{}') {\n                    rest[1].token.inner = rest[1].expose().token.inner;\n                    rest[2].token.inner = rest[2].expose().token.inner;\n                    return step(AnonFun.create(head, rest[0], rest[1], rest[2]), rest.slice(3), opCtx);\n                }    // arrow function\n                else if ((head.token.type === parser.Token.Delimiter && head.token.value === '()' || head.token.type === parser.Token.Identifier) && rest[0] && rest[0].token.type === parser.Token.Punctuator && resolveFast(rest[0], context.env) === '=>' && rest[1] && rest[1].token.type === parser.Token.Delimiter && rest[1].token.value === '{}') {\n                    return step(ArrowFun.create(head, rest[0], rest[1]), rest.slice(2), opCtx);\n                }    // catch statement\n                else if (head.token.type === parser.Token.Keyword && unwrapSyntax(head) === 'catch' && rest[0] && rest[0].token.type === parser.Token.Delimiter && rest[0].token.value === '()' && rest[1] && rest[1].token.type === parser.Token.Delimiter && rest[1].token.value === '{}') {\n                    rest[0].token.inner = rest[0].expose().token.inner;\n                    rest[1].token.inner = rest[1].expose().token.inner;\n                    return step(CatchClause.create(head, rest[0], rest[1]), rest.slice(2), opCtx);\n                }    // this expression\n                else if (head.token.type === parser.Token.Keyword && unwrapSyntax(head) === 'this') {\n                    return step(ThisExpression.create(head), rest, opCtx);\n                }    // literal\n                else if (head.token.type === parser.Token.NumericLiteral || head.token.type === parser.Token.StringLiteral || head.token.type === parser.Token.BooleanLiteral || head.token.type === parser.Token.RegularExpression || head.token.type === parser.Token.NullLiteral) {\n                    return step(Lit.create(head), rest, opCtx);\n                }    // export\n                else if (head.token.type === parser.Token.Keyword && unwrapSyntax(head) === 'export' && rest[0] && (rest[0].token.type === parser.Token.Identifier || rest[0].token.type === parser.Token.Keyword || rest[0].token.type === parser.Token.Punctuator || rest[0].token.type === parser.Token.Delimiter && rest[0].token.value === '()')) {\n                    return step(Export.create(rest[0]), rest.slice(1), opCtx);\n                }    // identifier\n                else if (head.token.type === parser.Token.Identifier) {\n                    return step(Id.create(head), rest, opCtx);\n                }    // punctuator\n                else if (head.token.type === parser.Token.Punctuator) {\n                    return step(Punc.create(head), rest, opCtx);\n                } else if (head.token.type === parser.Token.Keyword && unwrapSyntax(head) === 'with') {\n                    throwSyntaxError('enforest', 'with is not supported in sweet.js', head);\n                }    // keyword\n                else if (head.token.type === parser.Token.Keyword) {\n                    return step(Keyword.create(head), rest, opCtx);\n                }    // Delimiter\n                else if (head.token.type === parser.Token.Delimiter) {\n                    return step(Delimiter.create(head.expose()), rest, opCtx);\n                } else if (head.token.type === parser.Token.Template) {\n                    return step(Template.create(head), rest, opCtx);\n                }    // end of file\n                else if (head.token.type === parser.Token.EOF) {\n                    assert(rest.length === 0, 'nothing should be after an EOF');\n                    return step(EOF.create(head), [], opCtx);\n                } else {\n                    // todo: are we missing cases?\n                    assert(false, 'not implemented');\n                }\n            }\n            // Potentially an infix macro\n            if (head.isExpr && rest.length && nameInEnv(rest[0], rest.slice(1), context.env)) {\n                var infLeftTerm = opCtx.prevTerms[0] && opCtx.prevTerms[0].isPartial ? opCtx.prevTerms[0] : null;\n                var infTerm = PartialExpression.create(head.destruct(), infLeftTerm, function () {\n                        return step(head, [], opCtx);\n                    });\n                var infPrevStx = tagWithTerm(infTerm, head.destruct()).reverse().concat(opCtx.prevStx);\n                var infPrevTerms = [infTerm].concat(opCtx.prevTerms);\n                var infRes = expandMacro(rest, context, {\n                        prevStx: infPrevStx,\n                        prevTerms: infPrevTerms\n                    });\n                if (infRes.prevTerms && infRes.prevTerms.length < infPrevTerms.length) {\n                    var infOpCtx = rewindOpCtx(opCtx, infRes);\n                    return step(infRes.result[0], infRes.result.slice(1).concat(infRes.rest), infOpCtx);\n                } else {\n                    return step(head, infRes.result.concat(infRes.rest), opCtx);\n                }\n            }\n            // done with current step so combine and continue on\n            var combResult = opCtx.combine(head);\n            if (opCtx.stack.length === 0) {\n                return {\n                    result: combResult.term,\n                    rest: rest,\n                    prevStx: combResult.prevStx,\n                    prevTerms: combResult.prevTerms\n                };\n            } else {\n                return step(combResult.term, rest, opCtx.stack[0]);\n            }\n        }\n        return step(toks[0], toks.slice(1), {\n            combine: function (t) {\n                return {\n                    term: t,\n                    prevStx: prevStx,\n                    prevTerms: prevTerms\n                };\n            },\n            prec: 0,\n            stack: [],\n            op: null,\n            prevStx: prevStx,\n            prevTerms: prevTerms\n        });\n    }\n    function rewindOpCtx(opCtx, res) {\n        // If we've consumed all pending operators, we can just start over.\n        // It's important that we always thread the new prevStx and prevTerms\n        // through, otherwise the old ones will still persist.\n        if (!res.prevTerms.length || !res.prevTerms[0].isPartial) {\n            return _.extend({}, opCtx, {\n                combine: function (t) {\n                    return {\n                        term: t,\n                        prevStx: res.prevStx,\n                        prevTerms: res.prevTerms\n                    };\n                },\n                prec: 0,\n                op: null,\n                stack: [],\n                prevStx: res.prevStx,\n                prevTerms: res.prevTerms\n            });\n        }\n        // To rewind, we need to find the first (previous) pending operator. It\n        // acts as a marker in the opCtx to let us know how far we need to go\n        // back.\n        var op = null;\n        for (var i = 0; i < res.prevTerms.length; i++) {\n            if (!res.prevTerms[i].isPartial) {\n                break;\n            }\n            if (res.prevTerms[i].isPartialOperation) {\n                op = res.prevTerms[i];\n                break;\n            }\n        }\n        // If the op matches the current opCtx, we don't need to rewind\n        // anything, but we still need to persist the prevStx and prevTerms.\n        if (opCtx.op === op) {\n            return _.extend({}, opCtx, {\n                prevStx: res.prevStx,\n                prevTerms: res.prevTerms\n            });\n        }\n        for (var i = 0; i < opCtx.stack.length; i++) {\n            if (opCtx.stack[i].op === op) {\n                return _.extend({}, opCtx.stack[i], {\n                    prevStx: res.prevStx,\n                    prevTerms: res.prevTerms\n                });\n            }\n        }\n        assert(false, 'Rewind failed.');\n    }\n    function get_expression(stx, context) {\n        if (stx[0].term) {\n            for (var termLen = 1; termLen < stx.length; termLen++) {\n                if (stx[termLen].term !== stx[0].term) {\n                    break;\n                }\n            }\n            // Guard the termLen because we can have a multi-token term that\n            // we don't want to split. TODO: is there something we can do to\n            // get around this safely?\n            if (stx[0].term.isPartialExpression && termLen === stx[0].term.stx.length) {\n                var expr = stx[0].term.combine().result;\n                for (var i = 1, term = stx[0].term; i < stx.length; i++) {\n                    if (stx[i].term !== term) {\n                        if (term && term.isPartial) {\n                            term = term.left;\n                            i--;\n                        } else {\n                            break;\n                        }\n                    }\n                }\n                return {\n                    result: expr,\n                    rest: stx.slice(i)\n                };\n            } else if (stx[0].term.isExpr) {\n                return {\n                    result: stx[0].term,\n                    rest: stx.slice(termLen)\n                };\n            } else {\n                return {\n                    result: null,\n                    rest: stx\n                };\n            }\n        }\n        var res = enforest(stx, context);\n        if (!res.result || !res.result.isExpr) {\n            return {\n                result: null,\n                rest: stx\n            };\n        }\n        return res;\n    }\n    function tagWithTerm(term, stx) {\n        return stx.map(function (s) {\n            var src = s.token;\n            var keys = Object.keys(src);\n            var newtok = {};\n            for (var i = 0, len = keys.length, key; i < len; i++) {\n                key = keys[i];\n                newtok[key] = src[key];\n            }\n            s = syntaxFromToken(newtok, s);\n            s.term = term;\n            return s;\n        });\n    }\n    // mark each syntax object in the pattern environment,\n    // mutating the environment\n    function applyMarkToPatternEnv(newMark, env) {\n        /*\n        Takes a `match` object:\n\n            {\n                level: <num>,\n                match: [<match> or <syntax>]\n            }\n\n        where the match property is an array of syntax objects at the bottom (0) level.\n        Does a depth-first search and applys the mark to each syntax object.\n        */\n        function dfs(match) {\n            if (match.level === 0) {\n                // replace the match property with the marked syntax\n                match.match = _.map(match.match, function (stx) {\n                    return stx.mark(newMark);\n                });\n            } else {\n                _.each(match.match, function (match$2) {\n                    dfs(match$2);\n                });\n            }\n        }\n        _.keys(env).forEach(function (key) {\n            dfs(env[key]);\n        });\n    }\n    // given the syntax for a macro, produce a macro transformer\n    // (Macro) -> (([...CSyntax]) -> ReadTree)\n    function loadMacroDef(body, context) {\n        // raw function primitive form\n        if (!(body[0] && body[0].token.type === parser.Token.Keyword && body[0].token.value === 'function')) {\n            throwSyntaxError('load macro', 'Primitive macro form must contain a function for the macro body', body);\n        }\n        var stub = parser.read('()');\n        stub[0].token.inner = body;\n        var expanded = expand(stub, context);\n        expanded = expanded[0].destruct().concat(expanded[1].eof);\n        var flattend = flatten(expanded);\n        var bodyCode = codegen.generate(parser.parse(flattend));\n        var macroFn = scopedEval(bodyCode, {\n                makeValue: syn.makeValue,\n                makeRegex: syn.makeRegex,\n                makeIdent: syn.makeIdent,\n                makeKeyword: syn.makeKeyword,\n                makePunc: syn.makePunc,\n                makeDelim: syn.makeDelim,\n                require: function (id) {\n                    if (context.requireModule) {\n                        return context.requireModule(id, context.filename);\n                    }\n                    return require(id);\n                },\n                getExpr: function (stx) {\n                    var r;\n                    if (stx.length === 0) {\n                        return {\n                            success: false,\n                            result: [],\n                            rest: []\n                        };\n                    }\n                    r = get_expression(stx, context);\n                    return {\n                        success: r.result !== null,\n                        result: r.result === null ? [] : r.result.destruct(),\n                        rest: r.rest\n                    };\n                },\n                getIdent: function (stx) {\n                    if (stx[0] && stx[0].token.type === parser.Token.Identifier) {\n                        return {\n                            success: true,\n                            result: [stx[0]],\n                            rest: stx.slice(1)\n                        };\n                    }\n                    return {\n                        success: false,\n                        result: [],\n                        rest: stx\n                    };\n                },\n                getLit: function (stx) {\n                    if (stx[0] && patternModule.typeIsLiteral(stx[0].token.type)) {\n                        return {\n                            success: true,\n                            result: [stx[0]],\n                            rest: stx.slice(1)\n                        };\n                    }\n                    return {\n                        success: false,\n                        result: [],\n                        rest: stx\n                    };\n                },\n                unwrapSyntax: syn.unwrapSyntax,\n                throwSyntaxError: throwSyntaxError,\n                throwSyntaxCaseError: throwSyntaxCaseError,\n                prettyPrint: syn.prettyPrint,\n                parser: parser,\n                __fresh: fresh,\n                _: _,\n                patternModule: patternModule,\n                getPattern: function (id) {\n                    return context.patternMap.get(id);\n                },\n                getTemplate: function (id) {\n                    return syn.cloneSyntaxArray(context.templateMap.get(id));\n                },\n                applyMarkToPatternEnv: applyMarkToPatternEnv,\n                mergeMatches: function (newMatch, oldMatch) {\n                    newMatch.patternEnv = _.extend({}, oldMatch.patternEnv, newMatch.patternEnv);\n                    return newMatch;\n                }\n            });\n        return macroFn;\n    }\n    // similar to `parse1` in the honu paper\n    // ([Syntax], Map) -> {terms: [TermTree], env: Map}\n    function expandToTermTree(stx, context) {\n        assert(context, 'expander context is required');\n        var f, head, prevStx, restStx, prevTerms, macroDefinition;\n        var rest = stx;\n        while (rest.length > 0) {\n            assert(rest[0].token, 'expecting a syntax object');\n            f = enforest(rest, context, prevStx, prevTerms);\n            // head :: TermTree\n            head = f.result;\n            // rest :: [Syntax]\n            rest = f.rest;\n            if (!head) {\n                // no head means the expansions stopped prematurely (for stepping)\n                restStx = rest;\n                break;\n            }\n            if (head.isMacro && expandCount < maxExpands) {\n                // load the macro definition into the environment and continue expanding\n                macroDefinition = loadMacroDef(head.body, context);\n                var name = head.name.map(unwrapSyntax).join('');\n                var nameStx = syn.makeIdent(name, head.name[0]);\n                addToDefinitionCtx([nameStx], context.defscope, false);\n                context.env.names.set(name, true);\n                context.env.set(resolve(nameStx), {\n                    fn: macroDefinition,\n                    isOp: false,\n                    builtin: builtinMode,\n                    fullName: head.name\n                });\n                continue;\n            }\n            if (head.isLetMacro && expandCount < maxExpands) {\n                // load the macro definition into the environment and continue expanding\n                macroDefinition = loadMacroDef(head.body, context);\n                var freshName = fresh();\n                var name = head.name.map(unwrapSyntax).join('');\n                var nameStx = syn.makeIdent(name, head.name[0]);\n                var renamedName = nameStx.rename(nameStx, freshName);\n                rest = _.map(rest, function (stx$2) {\n                    return stx$2.rename(nameStx, freshName);\n                });\n                context.env.names.set(name, true);\n                context.env.set(resolve(renamedName), {\n                    fn: macroDefinition,\n                    isOp: false,\n                    builtin: builtinMode,\n                    fullName: head.name\n                });\n                continue;\n            }\n            if (head.isOperatorDefinition) {\n                var opDefinition = loadMacroDef(head.body, context);\n                var name = head.name.map(unwrapSyntax).join('');\n                var nameStx = syn.makeIdent(name, head.name[0]);\n                addToDefinitionCtx([nameStx], context.defscope, false);\n                var resolvedName = resolve(nameStx);\n                var opObj = context.env.get(resolvedName);\n                if (!opObj) {\n                    opObj = {\n                        isOp: true,\n                        builtin: builtinMode,\n                        fullName: head.name\n                    };\n                }\n                assert(head.type === 'binary' || head.type === 'unary', 'operator must either be binary or unary');\n                opObj[head.type] = {\n                    fn: opDefinition,\n                    prec: head.prec.token.value,\n                    assoc: head.assoc ? head.assoc.token.value : null\n                };\n                context.env.names.set(name, true);\n                context.env.set(resolvedName, opObj);\n                continue;\n            }\n            // We build the newPrevTerms/Stx here (instead of at the beginning) so\n            // that macro definitions don't get added to it.\n            var destructed = tagWithTerm(head, f.result.destruct());\n            prevTerms = [head].concat(f.prevTerms);\n            prevStx = destructed.reverse().concat(f.prevStx);\n            if (head.isNamedFun) {\n                addToDefinitionCtx([head.name], context.defscope, true);\n            }\n            if (head.isVariableStatement || head.isLetStatement || head.isConstStatement) {\n                addToDefinitionCtx(_.map(head.decls, function (decl) {\n                    return decl.ident;\n                }), context.defscope, true);\n            }\n            if (head.isBlock && head.body.isDelimiter) {\n                head.body.delim.token.inner.forEach(function (term) {\n                    if (term.isVariableStatement) {\n                        addToDefinitionCtx(_.map(term.decls, function (decl) {\n                            return decl.ident;\n                        }), context.defscope, true);\n                    }\n                });\n            }\n            if (head.isDelimiter) {\n                head.delim.token.inner.forEach(function (term) {\n                    if (term.isVariableStatement) {\n                        addToDefinitionCtx(_.map(term.decls, function (decl) {\n                            return decl.ident;\n                        }), context.defscope, true);\n                    }\n                });\n            }\n            if (head.isForStatement) {\n                head.cond.expose();\n                var forCond = head.cond.token.inner;\n                if (forCond[0] && resolve(forCond[0]) === 'let' && forCond[1] && forCond[1].token.type === parser.Token.Identifier) {\n                    var letNew = fresh();\n                    var letId = forCond[1];\n                    forCond = forCond.map(function (stx$2) {\n                        return stx$2.rename(letId, letNew);\n                    });\n                    // hack: we want to do the let renaming here, not\n                    // in the expansion of `for (...)` so just remove the `let`\n                    // keyword\n                    head.cond.token.inner = expand([forCond[0]], context).concat(expand(forCond.slice(1), context));\n                    // nice and easy case: `for (...) { ... }`\n                    if (rest[0] && rest[0].token.value === '{}') {\n                        rest[0] = rest[0].rename(letId, letNew);\n                    } else {\n                        // need to deal with things like `for (...) if (...) log(...)`\n                        var bodyEnf = enforest(rest, context);\n                        var bodyDestructed = bodyEnf.result.destruct();\n                        var renamedBodyTerm = bodyEnf.result.rename(letId, letNew);\n                        tagWithTerm(renamedBodyTerm, bodyDestructed);\n                        rest = bodyEnf.rest;\n                        prevStx = bodyDestructed.reverse().concat(prevStx);\n                        prevTerms = [renamedBodyTerm].concat(prevTerms);\n                    }\n                } else {\n                    head.cond.token.inner = expand(head.cond.token.inner, context);\n                }\n            }\n        }\n        return {\n            terms: prevTerms ? prevTerms.reverse() : [],\n            restStx: restStx,\n            context: context\n        };\n    }\n    function addToDefinitionCtx(idents, defscope, skipRep) {\n        assert(idents && idents.length > 0, 'expecting some variable identifiers');\n        skipRep = skipRep || false;\n        _.each(idents, function (id) {\n            var skip = false;\n            if (skipRep) {\n                var declRepeat = _.find(defscope, function (def) {\n                        return def.id.token.value === id.token.value && arraysEqual(marksof(def.id.context), marksof(id.context));\n                    });\n                skip = typeof declRepeat !== 'undefined';\n            }\n            /*\n               When var declarations repeat in the same function scope:\n\n               var x = 24;\n               ...\n               var x = 42;\n\n               we just need to use the first renaming and leave the\n               definition context as is.\n            */\n            if (!skip) {\n                var name = fresh();\n                defscope.push({\n                    id: id,\n                    name: name\n                });\n            }\n        });\n    }\n    // similar to `parse2` in the honu paper except here we\n    // don't generate an AST yet\n    // (TermTree, Map, Map) -> TermTree\n    function expandTermTreeToFinal(term, context) {\n        assert(context && context.env, 'environment map is required');\n        if (term.isArrayLiteral) {\n            term.array.delim.token.inner = expand(term.array.delim.expose().token.inner, context);\n            return term;\n        } else if (term.isBlock) {\n            term.body.delim.token.inner = expand(term.body.delim.expose().token.inner, context);\n            return term;\n        } else if (term.isParenExpression) {\n            assert(term.expr.delim.token.inner.length === 1, 'Paren expressions always have a single term inside the delimiter');\n            term.expr.delim.token.inner = [expandTermTreeToFinal(term.expr.delim.token.inner[0], context)];\n            return term;\n        } else if (term.isCall) {\n            term.fun = expandTermTreeToFinal(term.fun, context);\n            term.args = _.map(term.args, function (arg) {\n                return expandTermTreeToFinal(arg, context);\n            });\n            return term;\n        } else if (term.isConst) {\n            term.call = expandTermTreeToFinal(term.call, context);\n            return term;\n        } else if (term.isUnaryOp) {\n            term.expr = expandTermTreeToFinal(term.expr, context);\n            return term;\n        } else if (term.isBinOp || term.isAssignmentExpression) {\n            term.left = expandTermTreeToFinal(term.left, context);\n            term.right = expandTermTreeToFinal(term.right, context);\n            return term;\n        } else if (term.isObjGet) {\n            term.left = expandTermTreeToFinal(term.left, context);\n            term.right.delim.token.inner = expand(term.right.delim.expose().token.inner, context);\n            return term;\n        } else if (term.isObjDotGet) {\n            term.left = expandTermTreeToFinal(term.left, context);\n            term.right = expandTermTreeToFinal(term.right, context);\n            return term;\n        } else if (term.isConditionalExpression) {\n            term.cond = expandTermTreeToFinal(term.cond, context);\n            term.tru = expandTermTreeToFinal(term.tru, context);\n            term.fls = expandTermTreeToFinal(term.fls, context);\n            return term;\n        } else if (term.isVariableDeclaration) {\n            if (term.init) {\n                term.init = expandTermTreeToFinal(term.init, context);\n            }\n            return term;\n        } else if (term.isVariableStatement) {\n            term.decls = _.map(term.decls, function (decl) {\n                return expandTermTreeToFinal(decl, context);\n            });\n            return term;\n        } else if (term.isDelimiter) {\n            // expand inside the delimiter and then continue on\n            term.delim.token.inner = expand(term.delim.expose().token.inner, context);\n            return term;\n        } else if (term.isNamedFun || term.isAnonFun || term.isCatchClause || term.isArrowFun || term.isModule) {\n            // function definitions need a bunch of hygiene logic\n            // push down a fresh definition context\n            var newDef = [];\n            var bodyContext = makeExpanderContext(_.defaults({ defscope: newDef }, context));\n            var paramSingleIdent = term.params && term.params.token.type === parser.Token.Identifier;\n            var params;\n            if (term.params && term.params.token.type === parser.Token.Delimiter) {\n                params = term.params.expose();\n            } else if (paramSingleIdent) {\n                params = term.params;\n            } else {\n                params = syn.makeDelim('()', [], null);\n            }\n            var bodies;\n            if (Array.isArray(term.body)) {\n                bodies = syn.makeDelim('{}', term.body, null);\n            } else {\n                bodies = term.body;\n            }\n            bodies = bodies.addDefCtx(newDef);\n            var paramNames = _.map(getParamIdentifiers(params), function (param) {\n                    var freshName = fresh();\n                    return {\n                        freshName: freshName,\n                        originalParam: param,\n                        renamedParam: param.rename(param, freshName)\n                    };\n                });\n            // rename the function body for each of the parameters\n            var renamedBody = _.reduce(paramNames, function (accBody, p) {\n                    return accBody.rename(p.originalParam, p.freshName);\n                }, bodies);\n            renamedBody = renamedBody.expose();\n            var expandedResult = expandToTermTree(renamedBody.token.inner, bodyContext);\n            var bodyTerms = expandedResult.terms;\n            if (expandedResult.restStx) {\n                // The expansion was halted prematurely. Just stop and\n                // return what we have so far, along with the rest of the syntax\n                renamedBody.token.inner = expandedResult.terms.concat(expandedResult.restStx);\n                if (Array.isArray(term.body)) {\n                    term.body = renamedBody.token.inner;\n                } else {\n                    term.body = renamedBody;\n                }\n                return term;\n            }\n            var renamedParams = _.map(paramNames, function (p) {\n                    return p.renamedParam;\n                });\n            var flatArgs;\n            if (paramSingleIdent) {\n                flatArgs = renamedParams[0];\n            } else {\n                flatArgs = syn.makeDelim('()', joinSyntax(renamedParams, ','), term.params || null);\n            }\n            var expandedArgs = expand([flatArgs], bodyContext);\n            assert(expandedArgs.length === 1, 'should only get back one result');\n            // stitch up the function with all the renamings\n            if (term.params) {\n                term.params = expandedArgs[0];\n            }\n            bodyTerms = _.map(bodyTerms, function (bodyTerm) {\n                // add the definition context to the result of\n                // expansion (this makes sure that syntax objects\n                // introduced by expansion have the def context)\n                if (bodyTerm.isBlock) {\n                    // we need to expand blocks before adding the defctx since\n                    // blocks defer macro expansion.\n                    var blockFinal = expandTermTreeToFinal(bodyTerm, expandedResult.context);\n                    return blockFinal.addDefCtx(newDef);\n                } else {\n                    var termWithCtx = bodyTerm.addDefCtx(newDef);\n                    // finish expansion\n                    return expandTermTreeToFinal(termWithCtx, expandedResult.context);\n                }\n            });\n            if (term.isModule) {\n                bodyTerms = _.filter(bodyTerms, function (bodyTerm) {\n                    if (bodyTerm.isExport) {\n                        term.exports.push(bodyTerm);\n                        return false;\n                    } else {\n                        return true;\n                    }\n                });\n            }\n            renamedBody.token.inner = bodyTerms;\n            if (Array.isArray(term.body)) {\n                term.body = renamedBody.token.inner;\n            } else {\n                term.body = renamedBody;\n            }\n            // and continue expand the rest\n            return term;\n        }\n        // the term is fine as is\n        return term;\n    }\n    // similar to `parse` in the honu paper\n    // ([Syntax], Map, Map) -> [TermTree]\n    function expand(stx, context) {\n        assert(context, 'must provide an expander context');\n        var trees = expandToTermTree(stx, context);\n        var terms = _.map(trees.terms, function (term) {\n                return expandTermTreeToFinal(term, trees.context);\n            });\n        if (trees.restStx) {\n            terms.push.apply(terms, trees.restStx);\n        }\n        return terms;\n    }\n    function makeExpanderContext(o) {\n        o = o || {};\n        var env = o.env || new StringMap();\n        if (!env.names) {\n            env.names = new StringMap();\n        }\n        // read-only but can enumerate\n        return Object.create(Object.prototype, {\n            filename: {\n                value: o.filename,\n                writable: false,\n                enumerable: true,\n                configurable: false\n            },\n            requireModule: {\n                value: o.requireModule,\n                writable: false,\n                enumerable: true,\n                configurable: false\n            },\n            env: {\n                value: env,\n                writable: false,\n                enumerable: true,\n                configurable: false\n            },\n            defscope: {\n                value: o.defscope,\n                writable: false,\n                enumerable: true,\n                configurable: false\n            },\n            templateMap: {\n                value: o.templateMap || new StringMap(),\n                writable: false,\n                enumerable: true,\n                configurable: false\n            },\n            patternMap: {\n                value: o.patternMap || new StringMap(),\n                writable: false,\n                enumerable: true,\n                configurable: false\n            },\n            mark: {\n                value: o.mark,\n                writable: false,\n                enumerable: true,\n                configurable: false\n            }\n        });\n    }\n    function makeTopLevelExpanderContext(options) {\n        var requireModule = options ? options.requireModule : undefined;\n        var filename = options ? options.filename : undefined;\n        return makeExpanderContext({\n            filename: filename,\n            requireModule: requireModule\n        });\n    }\n    // a hack to make the top level hygiene work out\n    function expandTopLevel(stx, moduleContexts, options) {\n        moduleContexts = moduleContexts || [];\n        maxExpands = (_.isNumber(options) ? options : options && options._maxExpands) || Infinity;\n        expandCount = 0;\n        var context = makeTopLevelExpanderContext(options);\n        var modBody = syn.makeDelim('{}', stx, null);\n        modBody = _.reduce(moduleContexts, function (acc, mod) {\n            context.env.extend(mod.env);\n            context.env.names.extend(mod.env.names);\n            return loadModuleExports(acc, context.env, mod.exports, mod.env);\n        }, modBody);\n        var res = expand([\n                syn.makeIdent('module', null),\n                modBody\n            ], context);\n        res = res[0].destruct();\n        return flatten(res[0].token.inner);\n    }\n    function expandModule(stx, moduleContexts, options) {\n        moduleContexts = moduleContexts || [];\n        maxExpands = Infinity;\n        expandCount = 0;\n        var context = makeTopLevelExpanderContext(options);\n        var modBody = syn.makeDelim('{}', stx, null);\n        modBody = _.reduce(moduleContexts, function (acc, mod) {\n            context.env.extend(mod.env);\n            context.env.names.extend(mod.env.names);\n            return loadModuleExports(acc, context.env, mod.exports, mod.env);\n        }, modBody);\n        builtinMode = true;\n        var moduleRes = expand([\n                syn.makeIdent('module', null),\n                modBody\n            ], context);\n        builtinMode = false;\n        context.exports = _.map(moduleRes[0].exports, function (term) {\n            var nameStr, name;\n            if (term.name.token.type === parser.Token.Delimiter) {\n                nameStr = term.name.token.inner.map(unwrapSyntax).join('');\n                name = syn.makeIdent(nameStr, term.name);\n            } else {\n                name = term.name;\n                nameStr = unwrapSyntax(name);\n            }\n            return {\n                oldExport: name,\n                newParam: syn.makeIdent(nameStr, null)\n            };\n        });\n        return context;\n    }\n    function loadModuleExports(stx, newEnv, exports$3, oldEnv) {\n        return _.reduce(exports$3, function (acc, param) {\n            var newName = fresh();\n            var transformer = oldEnv.get(resolve(param.oldExport));\n            if (transformer) {\n                newEnv.set(resolve(param.newParam.rename(param.newParam, newName)), transformer);\n                return acc.rename(param.newParam, newName);\n            } else {\n                return acc;\n            }\n        }, stx);\n    }\n    // break delimiter tree structure down to flat array of syntax objects\n    function flatten(stx) {\n        return _.reduce(stx, function (acc, stx$2) {\n            if (stx$2.token.type === parser.Token.Delimiter) {\n                var exposed = stx$2.expose();\n                var openParen = syntaxFromToken({\n                        type: parser.Token.Punctuator,\n                        value: stx$2.token.value[0],\n                        range: stx$2.token.startRange,\n                        sm_range: typeof stx$2.token.sm_startRange == 'undefined' ? stx$2.token.startRange : stx$2.token.sm_startRange,\n                        lineNumber: stx$2.token.startLineNumber,\n                        sm_lineNumber: typeof stx$2.token.sm_startLineNumber == 'undefined' ? stx$2.token.startLineNumber : stx$2.token.sm_startLineNumber,\n                        lineStart: stx$2.token.startLineStart,\n                        sm_lineStart: typeof stx$2.token.sm_startLineStart == 'undefined' ? stx$2.token.startLineStart : stx$2.token.sm_startLineStart\n                    }, exposed);\n                var closeParen = syntaxFromToken({\n                        type: parser.Token.Punctuator,\n                        value: stx$2.token.value[1],\n                        range: stx$2.token.endRange,\n                        sm_range: typeof stx$2.token.sm_endRange == 'undefined' ? stx$2.token.endRange : stx$2.token.sm_endRange,\n                        lineNumber: stx$2.token.endLineNumber,\n                        sm_lineNumber: typeof stx$2.token.sm_endLineNumber == 'undefined' ? stx$2.token.endLineNumber : stx$2.token.sm_endLineNumber,\n                        lineStart: stx$2.token.endLineStart,\n                        sm_lineStart: typeof stx$2.token.sm_endLineStart == 'undefined' ? stx$2.token.endLineStart : stx$2.token.sm_endLineStart\n                    }, exposed);\n                if (stx$2.token.leadingComments) {\n                    openParen.token.leadingComments = stx$2.token.leadingComments;\n                }\n                if (stx$2.token.trailingComments) {\n                    openParen.token.trailingComments = stx$2.token.trailingComments;\n                }\n                acc.push(openParen);\n                push.apply(acc, flatten(exposed.token.inner));\n                acc.push(closeParen);\n                return acc;\n            }\n            stx$2.token.sm_lineNumber = stx$2.token.sm_lineNumber ? stx$2.token.sm_lineNumber : stx$2.token.lineNumber;\n            stx$2.token.sm_lineStart = stx$2.token.sm_lineStart ? stx$2.token.sm_lineStart : stx$2.token.lineStart;\n            stx$2.token.sm_range = stx$2.token.sm_range ? stx$2.token.sm_range : stx$2.token.range;\n            acc.push(stx$2);\n            return acc;\n        }, []);\n    }\n    exports$2.StringMap = StringMap;\n    exports$2.enforest = enforest;\n    exports$2.expand = expandTopLevel;\n    exports$2.expandModule = expandModule;\n    exports$2.resolve = resolve;\n    exports$2.get_expression = get_expression;\n    exports$2.getName = getName;\n    exports$2.getMacroInEnv = getMacroInEnv;\n    exports$2.nameInEnv = nameInEnv;\n    exports$2.makeExpanderContext = makeExpanderContext;\n    exports$2.Expr = Expr;\n    exports$2.VariableStatement = VariableStatement;\n    exports$2.tokensToSyntax = syn.tokensToSyntax;\n    exports$2.syntaxToTokens = syn.syntaxToTokens;\n}));\n//# sourceMappingURL=expander.js.map"
  },
  {
    "path": "docs/editor/scripts/jquery.js",
    "content": "/*!\n * jQuery JavaScript Library v2.0.3\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2013-07-03T13:30Z\n */\n(function( window, undefined ) {\n\n// Can't do this because several apps including ASP.NET trace\n// the stack via arguments.caller.callee and Firefox dies if\n// you try to trace through \"use strict\" call chains. (#13335)\n// Support: Firefox 18+\n//\"use strict\";\nvar\n\t// A central reference to the root jQuery(document)\n\trootjQuery,\n\n\t// The deferred used on DOM ready\n\treadyList,\n\n\t// Support: IE9\n\t// For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`\n\tcore_strundefined = typeof undefined,\n\n\t// Use the correct document accordingly with window argument (sandbox)\n\tlocation = window.location,\n\tdocument = window.document,\n\tdocElem = document.documentElement,\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$,\n\n\t// [[Class]] -> type pairs\n\tclass2type = {},\n\n\t// List of deleted data cache ids, so we can reuse them\n\tcore_deletedIds = [],\n\n\tcore_version = \"2.0.3\",\n\n\t// Save a reference to some core methods\n\tcore_concat = core_deletedIds.concat,\n\tcore_push = core_deletedIds.push,\n\tcore_slice = core_deletedIds.slice,\n\tcore_indexOf = core_deletedIds.indexOf,\n\tcore_toString = class2type.toString,\n\tcore_hasOwn = class2type.hasOwnProperty,\n\tcore_trim = core_version.trim,\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\treturn new jQuery.fn.init( selector, context, rootjQuery );\n\t},\n\n\t// Used for matching numbers\n\tcore_pnum = /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,\n\n\t// Used for splitting on whitespace\n\tcore_rnotwhite = /\\S+/g,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,\n\n\t// Match a standalone tag\n\trsingleTag = /^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/,\n\n\t// Matches dashed string for camelizing\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([\\da-z])/gi,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t},\n\n\t// The ready event handler and self cleanup method\n\tcompleted = function() {\n\t\tdocument.removeEventListener( \"DOMContentLoaded\", completed, false );\n\t\twindow.removeEventListener( \"load\", completed, false );\n\t\tjQuery.ready();\n\t};\n\njQuery.fn = jQuery.prototype = {\n\t// The current version of jQuery being used\n\tjquery: core_version,\n\n\tconstructor: jQuery,\n\tinit: function( selector, context, rootjQuery ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && (match[1] || !context) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[1] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[0] : context;\n\n\t\t\t\t\t// scripts is true for back-compat\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[1],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( jQuery.isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[2] );\n\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[0] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || rootjQuery ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis.context = this[0] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn rootjQuery.ready( selector );\n\t\t}\n\n\t\tif ( selector.selector !== undefined ) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t},\n\n\t// Start with an empty selector\n\tselector: \"\",\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn core_slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num == null ?\n\n\t\t\t// Return a 'clean' array\n\t\t\tthis.toArray() :\n\n\t\t\t// Return just the object\n\t\t\t( num < 0 ? this[ this.length + num ] : this[ num ] );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\t\tret.context = this.context;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\t// (You can seed the arguments with an array of args, but this is\n\t// only used internally.)\n\teach: function( callback, args ) {\n\t\treturn jQuery.each( this, callback, args );\n\t},\n\n\tready: function( fn ) {\n\t\t// Add the callback\n\t\tjQuery.ready.promise().done( fn );\n\n\t\treturn this;\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( core_slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map(this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t}));\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor(null);\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: core_push,\n\tsort: [].sort,\n\tsplice: [].splice\n};\n\n// Give the init function the jQuery prototype for later instantiation\njQuery.fn.init.prototype = jQuery.fn;\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[0] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\t\ttarget = arguments[1] || {};\n\t\t// skip the boolean and the target\n\t\ti = 2;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n\t\ttarget = {};\n\t}\n\n\t// extend jQuery itself if only one argument is passed\n\tif ( length === i ) {\n\t\ttarget = this;\n\t\t--i;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\t\t// Only deal with non-null/undefined values\n\t\tif ( (options = arguments[ i ]) != null ) {\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray(src) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject(src) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend({\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( core_version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\tnoConflict: function( deep ) {\n\t\tif ( window.$ === jQuery ) {\n\t\t\twindow.$ = _$;\n\t\t}\n\n\t\tif ( deep && window.jQuery === jQuery ) {\n\t\t\twindow.jQuery = _jQuery;\n\t\t}\n\n\t\treturn jQuery;\n\t},\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\n\t\t// Trigger any bound ready events\n\t\tif ( jQuery.fn.trigger ) {\n\t\t\tjQuery( document ).trigger(\"ready\").off(\"ready\");\n\t\t}\n\t},\n\n\t// See test/unit/core.js for details concerning isFunction.\n\t// Since version 1.3, DOM methods and functions like alert\n\t// aren't supported. They return false on IE (#2968).\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type(obj) === \"function\";\n\t},\n\n\tisArray: Array.isArray,\n\n\tisWindow: function( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\t\treturn !isNaN( parseFloat(obj) ) && isFinite( obj );\n\t},\n\n\ttype: function( obj ) {\n\t\tif ( obj == null ) {\n\t\t\treturn String( obj );\n\t\t}\n\t\t// Support: Safari <= 5.1 (functionish RegExp)\n\t\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\t\tclass2type[ core_toString.call(obj) ] || \"object\" :\n\t\t\ttypeof obj;\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\t// Not plain objects:\n\t\t// - Any object or value whose internal [[Class]] property is not \"[object Object]\"\n\t\t// - DOM nodes\n\t\t// - window\n\t\tif ( jQuery.type( obj ) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Support: Firefox <20\n\t\t// The try/catch suppresses exceptions thrown when attempting to access\n\t\t// the \"constructor\" property of certain host objects, ie. |window.location|\n\t\t// https://bugzilla.mozilla.org/show_bug.cgi?id=814622\n\t\ttry {\n\t\t\tif ( obj.constructor &&\n\t\t\t\t\t!core_hasOwn.call( obj.constructor.prototype, \"isPrototypeOf\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If the function hasn't returned already, we're confident that\n\t\t// |obj| is a plain object, created by {} or constructed with new Object\n\t\treturn true;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\t// data: string of html\n\t// context (optional): If specified, the fragment will be created in this context, defaults to document\n\t// keepScripts (optional): If true, will include scripts passed in the html string\n\tparseHTML: function( data, context, keepScripts ) {\n\t\tif ( !data || typeof data !== \"string\" ) {\n\t\t\treturn null;\n\t\t}\n\t\tif ( typeof context === \"boolean\" ) {\n\t\t\tkeepScripts = context;\n\t\t\tcontext = false;\n\t\t}\n\t\tcontext = context || document;\n\n\t\tvar parsed = rsingleTag.exec( data ),\n\t\t\tscripts = !keepScripts && [];\n\n\t\t// Single tag\n\t\tif ( parsed ) {\n\t\t\treturn [ context.createElement( parsed[1] ) ];\n\t\t}\n\n\t\tparsed = jQuery.buildFragment( [ data ], context, scripts );\n\n\t\tif ( scripts ) {\n\t\t\tjQuery( scripts ).remove();\n\t\t}\n\n\t\treturn jQuery.merge( [], parsed.childNodes );\n\t},\n\n\tparseJSON: JSON.parse,\n\n\t// Cross-browser xml parsing\n\tparseXML: function( data ) {\n\t\tvar xml, tmp;\n\t\tif ( !data || typeof data !== \"string\" ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Support: IE9\n\t\ttry {\n\t\t\ttmp = new DOMParser();\n\t\t\txml = tmp.parseFromString( data , \"text/xml\" );\n\t\t} catch ( e ) {\n\t\t\txml = undefined;\n\t\t}\n\n\t\tif ( !xml || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\t\tjQuery.error( \"Invalid XML: \" + data );\n\t\t}\n\t\treturn xml;\n\t},\n\n\tnoop: function() {},\n\n\t// Evaluates a script in a global context\n\tglobalEval: function( code ) {\n\t\tvar script,\n\t\t\t\tindirect = eval;\n\n\t\tcode = jQuery.trim( code );\n\n\t\tif ( code ) {\n\t\t\t// If the code includes a valid, prologue position\n\t\t\t// strict mode pragma, execute code by injecting a\n\t\t\t// script tag into the document.\n\t\t\tif ( code.indexOf(\"use strict\") === 1 ) {\n\t\t\t\tscript = document.createElement(\"script\");\n\t\t\t\tscript.text = code;\n\t\t\t\tdocument.head.appendChild( script ).parentNode.removeChild( script );\n\t\t\t} else {\n\t\t\t// Otherwise, avoid the DOM node creation, insertion\n\t\t\t// and removal by using an indirect global eval\n\t\t\t\tindirect( code );\n\t\t\t}\n\t\t}\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\n\t// args is for internal usage only\n\teach: function( obj, callback, args ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = obj.length,\n\t\t\tisArray = isArraylike( obj );\n\n\t\tif ( args ) {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// A special, fast, case for the most common use of each\n\t\t} else {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\ttrim: function( text ) {\n\t\treturn text == null ? \"\" : core_trim.call( text );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArraylike( Object(arr) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tcore_push.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : core_indexOf.call( arr, elem, i );\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar l = second.length,\n\t\t\ti = first.length,\n\t\t\tj = 0;\n\n\t\tif ( typeof l === \"number\" ) {\n\t\t\tfor ( ; j < l; j++ ) {\n\t\t\t\tfirst[ i++ ] = second[ j ];\n\t\t\t}\n\t\t} else {\n\t\t\twhile ( second[j] !== undefined ) {\n\t\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t\t}\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, inv ) {\n\t\tvar retVal,\n\t\t\tret = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length;\n\t\tinv = !!inv;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tretVal = !!callback( elems[ i ], i );\n\t\t\tif ( inv !== retVal ) {\n\t\t\t\tret.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tisArray = isArraylike( elems ),\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their\n\t\tif ( isArray ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret[ ret.length ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret[ ret.length ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn core_concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tvar tmp, args, proxy;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\targs = core_slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );\n\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\t// Multifunctional method to get and set values of a collection\n\t// The value/s can optionally be executed if it's a function\n\taccess: function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\t\tvar i = 0,\n\t\t\tlength = elems.length,\n\t\t\tbulk = key == null;\n\n\t\t// Sets many values\n\t\tif ( jQuery.type( key ) === \"object\" ) {\n\t\t\tchainable = true;\n\t\t\tfor ( i in key ) {\n\t\t\t\tjQuery.access( elems, fn, i, key[i], true, emptyGet, raw );\n\t\t\t}\n\n\t\t// Sets one value\n\t\t} else if ( value !== undefined ) {\n\t\t\tchainable = true;\n\n\t\t\tif ( !jQuery.isFunction( value ) ) {\n\t\t\t\traw = true;\n\t\t\t}\n\n\t\t\tif ( bulk ) {\n\t\t\t\t// Bulk operations run against the entire set\n\t\t\t\tif ( raw ) {\n\t\t\t\t\tfn.call( elems, value );\n\t\t\t\t\tfn = null;\n\n\t\t\t\t// ...except when executing function values\n\t\t\t\t} else {\n\t\t\t\t\tbulk = fn;\n\t\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( fn ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tfn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn chainable ?\n\t\t\telems :\n\n\t\t\t// Gets\n\t\t\tbulk ?\n\t\t\t\tfn.call( elems ) :\n\t\t\t\tlength ? fn( elems[0], key ) : emptyGet;\n\t},\n\n\tnow: Date.now,\n\n\t// A method for quickly swapping in/out CSS properties to get correct calculations.\n\t// Note: this method belongs to the css module but it's needed here for the support module.\n\t// If support gets modularized, this method should be moved back to the css module.\n\tswap: function( elem, options, callback, args ) {\n\t\tvar ret, name,\n\t\t\told = {};\n\n\t\t// Remember the old values, and insert the new ones\n\t\tfor ( name in options ) {\n\t\t\told[ name ] = elem.style[ name ];\n\t\t\telem.style[ name ] = options[ name ];\n\t\t}\n\n\t\tret = callback.apply( elem, args || [] );\n\n\t\t// Revert the old values\n\t\tfor ( name in options ) {\n\t\t\telem.style[ name ] = old[ name ];\n\t\t}\n\n\t\treturn ret;\n\t}\n});\n\njQuery.ready.promise = function( obj ) {\n\tif ( !readyList ) {\n\n\t\treadyList = jQuery.Deferred();\n\n\t\t// Catch cases where $(document).ready() is called after the browser event has already occurred.\n\t\t// we once tried to use readyState \"interactive\" here, but it caused issues like the one\n\t\t// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\t\t\tsetTimeout( jQuery.ready );\n\n\t\t} else {\n\n\t\t\t// Use the handy event callback\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", completed, false );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.addEventListener( \"load\", completed, false );\n\t\t}\n\t}\n\treturn readyList.promise( obj );\n};\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"), function(i, name) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\nfunction isArraylike( obj ) {\n\tvar length = obj.length,\n\t\ttype = jQuery.type( obj );\n\n\tif ( jQuery.isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\tif ( obj.nodeType === 1 && length ) {\n\t\treturn true;\n\t}\n\n\treturn type === \"array\" || type !== \"function\" &&\n\t\t( length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj );\n}\n\n// All jQuery objects should point back to these\nrootjQuery = jQuery(document);\n/*!\n * Sizzle CSS Selector Engine v1.9.4-pre\n * http://sizzlejs.com/\n *\n * Copyright 2013 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2013-06-03\n */\n(function( window, undefined ) {\n\nvar i,\n\tsupport,\n\tcachedruns,\n\tExpr,\n\tgetText,\n\tisXML,\n\tcompile,\n\toutermostContext,\n\tsortInput,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + -(new Date()),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\thasDuplicate = false,\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// General-purpose constants\n\tstrundefined = typeof undefined,\n\tMAX_NEGATIVE = 1 << 31,\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf if we can't use a native one\n\tindexOf = arr.indexOf || function( elem ) {\n\t\tvar i = 0,\n\t\t\tlen = this.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( this[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\t// http://www.w3.org/TR/css3-syntax/#characters\n\tcharacterEncoding = \"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",\n\n\t// Loosely modeled on CSS identifier characters\n\t// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors\n\t// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = characterEncoding.replace( \"w\", \"w#\" ),\n\n\t// Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")\" + whitespace +\n\t\t\"*(?:([*^$|!~]?=)\" + whitespace + \"*(?:(['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\3|(\" + identifier + \")|)|)\" + whitespace + \"*\\\\]\",\n\n\t// Prefer arguments quoted,\n\t//   then not containing pseudos/brackets,\n\t//   then attribute selectors/non-parenthetical expressions,\n\t//   then anything else\n\t// These preferences are here to reduce the number of selectors\n\t//   needing tokenize in the PSEUDO preFilter\n\tpseudos = \":(\" + characterEncoding + \")(?:\\\\(((['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\3|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes.replace( 3, 8 ) + \")*)|.*)\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trsibling = new RegExp( whitespace + \"*[+~]\" ),\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trescape = /'|\\\\/g,\n\n\t// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\t// BMP codepoint\n\t\t\thigh < 0 ?\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t};\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar match, elem, m, nodeType,\n\t\t// QSA vars\n\t\ti, groups, old, nid, newContext, newSelector;\n\n\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\n\tcontext = context || document;\n\tresults = results || [];\n\n\tif ( !selector || typeof selector !== \"string\" ) {\n\t\treturn results;\n\t}\n\n\tif ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {\n\t\treturn [];\n\t}\n\n\tif ( documentIsHTML && !seed ) {\n\n\t\t// Shortcuts\n\t\tif ( (match = rquickExpr.exec( selector )) ) {\n\t\t\t// Speed-up: Sizzle(\"#ID\")\n\t\t\tif ( (m = match[1]) ) {\n\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\telem = context.getElementById( m );\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE, Opera, and Webkit return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Context is not a document\n\t\t\t\t\tif ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\n\t\t\t\t\t\tcontains( context, elem ) && elem.id === m ) {\n\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Speed-up: Sizzle(\"TAG\")\n\t\t\t} else if ( match[2] ) {\n\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\treturn results;\n\n\t\t\t// Speed-up: Sizzle(\".CLASS\")\n\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {\n\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\treturn results;\n\t\t\t}\n\t\t}\n\n\t\t// QSA path\n\t\tif ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\t\t\tnid = old = expando;\n\t\t\tnewContext = context;\n\t\t\tnewSelector = nodeType === 9 && selector;\n\n\t\t\t// qSA works strangely on Element-rooted queries\n\t\t\t// We can work around this by specifying an extra ID on the root\n\t\t\t// and working up from there (Thanks to Andrew Dupont for the technique)\n\t\t\t// IE 8 doesn't work on object elements\n\t\t\tif ( nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n\t\t\t\tgroups = tokenize( selector );\n\n\t\t\t\tif ( (old = context.getAttribute(\"id\")) ) {\n\t\t\t\t\tnid = old.replace( rescape, \"\\\\$&\" );\n\t\t\t\t} else {\n\t\t\t\t\tcontext.setAttribute( \"id\", nid );\n\t\t\t\t}\n\t\t\t\tnid = \"[id='\" + nid + \"'] \";\n\n\t\t\t\ti = groups.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tgroups[i] = nid + toSelector( groups[i] );\n\t\t\t\t}\n\t\t\t\tnewContext = rsibling.test( selector ) && context.parentNode || context;\n\t\t\t\tnewSelector = groups.join(\",\");\n\t\t\t}\n\n\t\t\tif ( newSelector ) {\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch(qsaError) {\n\t\t\t\t} finally {\n\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\tcontext.removeAttribute(\"id\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {Function(string, Object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key += \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created div and expects a boolean result\n */\nfunction assert( fn ) {\n\tvar div = document.createElement(\"div\");\n\n\ttry {\n\t\treturn !!fn( div );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( div.parentNode ) {\n\t\t\tdiv.parentNode.removeChild( div );\n\t\t}\n\t\t// release memory in IE\n\t\tdiv = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = attrs.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\t( ~b.sourceIndex || MAX_NEGATIVE ) -\n\t\t\t( ~a.sourceIndex || MAX_NEGATIVE );\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Detect xml\n * @param {Element|Object} elem An element or a document\n */\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar doc = node ? node.ownerDocument || node : preferredDoc,\n\t\tparent = doc.defaultView;\n\n\t// If no document and documentElement is available, return\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Set our document\n\tdocument = doc;\n\tdocElem = doc.documentElement;\n\n\t// Support tests\n\tdocumentIsHTML = !isXML( doc );\n\n\t// Support: IE>8\n\t// If iframe document is assigned to \"document\" variable and if iframe has been reloaded,\n\t// IE will throw \"permission denied\" error when accessing \"document\" variable, see jQuery #13936\n\t// IE6-8 do not support the defaultView property so parent will be undefined\n\tif ( parent && parent.attachEvent && parent !== parent.top ) {\n\t\tparent.attachEvent( \"onbeforeunload\", function() {\n\t\t\tsetDocument();\n\t\t});\n\t}\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)\n\tsupport.attributes = assert(function( div ) {\n\t\tdiv.className = \"i\";\n\t\treturn !div.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( div ) {\n\t\tdiv.appendChild( doc.createComment(\"\") );\n\t\treturn !div.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Check if getElementsByClassName can be trusted\n\tsupport.getElementsByClassName = assert(function( div ) {\n\t\tdiv.innerHTML = \"<div class='a'></div><div class='a i'></div>\";\n\n\t\t// Support: Safari<4\n\t\t// Catch class over-caching\n\t\tdiv.firstChild.className = \"i\";\n\t\t// Support: Opera<10\n\t\t// Catch gEBCN failure to find non-leading classes\n\t\treturn div.getElementsByClassName(\"i\").length === 2;\n\t});\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( div ) {\n\t\tdocElem.appendChild( div ).id = expando;\n\t\treturn !doc.getElementsByName || !doc.getElementsByName( expando ).length;\n\t});\n\n\t// ID find and filter\n\tif ( support.getById ) {\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== strundefined && documentIsHTML ) {\n\t\t\t\tvar m = context.getElementById( id );\n\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\treturn m && m.parentNode ? [m] : [];\n\t\t\t}\n\t\t};\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t} else {\n\t\t// Support: IE6/7\n\t\t// getElementById is not reliable as a find shortcut\n\t\tdelete Expr.find[\"ID\"];\n\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== strundefined ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\t\t\t}\n\t\t} :\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See http://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( div ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// http://bugs.jquery.com/ticket/12359\n\t\t\tdiv.innerHTML = \"<select><option selected=''></option></select>\";\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !div.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( div ) {\n\n\t\t\t// Support: Opera 10-12/IE8\n\t\t\t// ^= $= *= and empty values\n\t\t\t// Should not select anything\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type attribute is restricted during .innerHTML assignment\n\t\t\tvar input = doc.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tdiv.appendChild( input ).setAttribute( \"t\", \"\" );\n\n\t\t\tif ( div.querySelectorAll(\"[t^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":enabled\").length ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tdiv.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( div ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( div, \"div\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( div, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\n\t// Element contains another\n\t// Purposefully does not implement inclusive descendent\n\t// As in, an element does not contain itself\n\tcontains = rnative.test( docElem.contains ) || docElem.compareDocumentPosition ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = docElem.compareDocumentPosition ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b );\n\n\t\tif ( compare ) {\n\t\t\t// Disconnected nodes\n\t\t\tif ( compare & 1 ||\n\t\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t\t// Choose the first element that is related to our preferred document\n\t\t\t\tif ( a === doc || contains(preferredDoc, a) ) {\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t\tif ( b === doc || contains(preferredDoc, b) ) {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\n\t\t\t\t// Maintain original order\n\t\t\t\treturn sortInput ?\n\t\t\t\t\t( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :\n\t\t\t\t\t0;\n\t\t\t}\n\n\t\t\treturn compare & 4 ? -1 : 1;\n\t\t}\n\n\t\t// Not directly comparable, sort on existence of method\n\t\treturn a.compareDocumentPosition ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\t} else if ( !aup || !bup ) {\n\t\t\treturn a === doc ? -1 :\n\t\t\t\tb === doc ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn doc;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\t// Make sure that attribute selectors are quoted\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch(e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [elem] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val === undefined ?\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull :\n\t\tval;\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\tfor ( ; (node = elem[i]); i++ ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (see #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[5] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] && match[4] !== undefined ) {\n\t\t\t\tmatch[2] = match[4];\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, outerCache, node, diff, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\t\t\t\t\t\t\touterCache = parent[ expando ] || (parent[ expando ] = {});\n\t\t\t\t\t\t\tcache = outerCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[0] === dirruns && cache[1];\n\t\t\t\t\t\t\tdiff = cache[0] === dirruns && cache[2];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\touterCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {\n\t\t\t\t\t\t\tdiff = cache[1];\n\n\t\t\t\t\t\t// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\tif ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {\n\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf.call( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": function( elem ) {\n\t\t\treturn elem.disabled === false;\n\t\t},\n\n\t\t\"disabled\": function( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),\n\t\t\t//   not comment, processing instructions, or others\n\t\t\t// Thanks to Diego Perini for the nodeName shortcut\n\t\t\t//   Greater than \"@\" means alpha characters (specifically not starting with \"#\" or \"?\")\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeName > \"@\" || elem.nodeType === 3 || elem.nodeType === 4 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\t// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)\n\t\t\t// use getAttribute instead to test this case\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === elem.type );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\nfunction tokenize( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( tokens = [] );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n}\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tcheckNonElements = base && dir === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar data, cache, outerCache,\n\t\t\t\tdirkey = dirruns + \" \" + doneName;\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\t\t\t\t\t\tif ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) {\n\t\t\t\t\t\t\tif ( (data = cache[1]) === true || data === cachedruns ) {\n\t\t\t\t\t\t\t\treturn data === true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcache = outerCache[ dir ] = [ dirkey ];\n\t\t\t\t\t\t\tcache[1] = matcher( elem, context, xml ) || cachedruns;\n\t\t\t\t\t\t\tif ( cache[1] === true ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf.call( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\treturn ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\t// A counter to specify which element is currently being matched\n\tvar matcherCachedRuns = 0,\n\t\tbySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, expandContext ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tsetMatched = [],\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\toutermost = expandContext != null,\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", expandContext && context.parentNode || context ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1);\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context !== document && context;\n\t\t\t\tcachedruns = matcherCachedRuns;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Keep `i` a string if there are no elements so `matchedCount` will be \"00\" below\n\t\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t\tcachedruns = ++matcherCachedRuns;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\tmatchedCount += i;\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !group ) {\n\t\t\tgroup = tokenize( selector );\n\t\t}\n\t\ti = group.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( group[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\t}\n\treturn cached;\n};\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction select( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tmatch = tokenize( selector );\n\n\tif ( !seed ) {\n\t\t// Try to minimize operations if there is only one group\n\t\tif ( match.length === 1 ) {\n\n\t\t\t// Take a shortcut and set the context if the root selector is an ID\n\t\t\ttokens = match[0] = match[0].slice( 0 );\n\t\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\t\tsupport.getById && context.nodeType === 9 && documentIsHTML &&\n\t\t\t\t\tExpr.relative[ tokens[1].type ] ) {\n\n\t\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\t\tif ( !context ) {\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t\t}\n\n\t\t\t// Fetch a seed set for right-to-left matching\n\t\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\ttoken = tokens[i];\n\n\t\t\t\t// Abort if we hit a combinator\n\t\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\t\tif ( (seed = find(\n\t\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\t\trsibling.test( tokens[0].type ) && context.parentNode || context\n\t\t\t\t\t)) ) {\n\n\t\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\tcompile( selector, match )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\trsibling.test( selector )\n\t);\n\treturn results;\n}\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome<14\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( div1 ) {\n\t// Should return 1, but returns 4 (following)\n\treturn div1.compareDocumentPosition( document.createElement(\"div\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( div ) {\n\tdiv.innerHTML = \"<a href='#'></a>\";\n\treturn div.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( div ) {\n\tdiv.innerHTML = \"<input/>\";\n\tdiv.firstChild.setAttribute( \"value\", \"\" );\n\treturn div.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( div ) {\n\treturn div.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn (val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\telem[ name ] === true ? name.toLowerCase() : null;\n\t\t}\n\t});\n}\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n})( window );\n// String to Object options format cache\nvar optionsCache = {};\n\n// Convert String-formatted options into Object-formatted ones and store in cache\nfunction createOptions( options ) {\n\tvar object = optionsCache[ options ] = {};\n\tjQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t});\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\t( optionsCache[ options ] || createOptions( options ) ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Last fire value (for non-forgettable lists)\n\t\tmemory,\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\t\t// Flag to know if list is currently firing\n\t\tfiring,\n\t\t// First callback to fire (used internally by add and fireWith)\n\t\tfiringStart,\n\t\t// End of the loop when firing\n\t\tfiringLength,\n\t\t// Index of currently firing callback (modified by remove if needed)\n\t\tfiringIndex,\n\t\t// Actual callback list\n\t\tlist = [],\n\t\t// Stack of fire calls for repeatable lists\n\t\tstack = !options.once && [],\n\t\t// Fire callbacks\n\t\tfire = function( data ) {\n\t\t\tmemory = options.memory && data;\n\t\t\tfired = true;\n\t\t\tfiringIndex = firingStart || 0;\n\t\t\tfiringStart = 0;\n\t\t\tfiringLength = list.length;\n\t\t\tfiring = true;\n\t\t\tfor ( ; list && firingIndex < firingLength; firingIndex++ ) {\n\t\t\t\tif ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n\t\t\t\t\tmemory = false; // To prevent further calls using add\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfiring = false;\n\t\t\tif ( list ) {\n\t\t\t\tif ( stack ) {\n\t\t\t\t\tif ( stack.length ) {\n\t\t\t\t\t\tfire( stack.shift() );\n\t\t\t\t\t}\n\t\t\t\t} else if ( memory ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t} else {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// Actual Callbacks object\n\t\tself = {\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\t// First, we save the current length\n\t\t\t\t\tvar start = list.length;\n\t\t\t\t\t(function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tvar type = jQuery.type( arg );\n\t\t\t\t\t\t\tif ( type === \"function\" ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && type !== \"string\" ) {\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t})( arguments );\n\t\t\t\t\t// Do we need to add the callbacks to the\n\t\t\t\t\t// current firing batch?\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tfiringLength = list.length;\n\t\t\t\t\t// With memory, if we're not firing then\n\t\t\t\t\t// we should call right away\n\t\t\t\t\t} else if ( memory ) {\n\t\t\t\t\t\tfiringStart = start;\n\t\t\t\t\t\tfire( memory );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\t\tvar index;\n\t\t\t\t\t\twhile( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\t\tlist.splice( index, 1 );\n\t\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\t\t\tif ( index <= firingLength ) {\n\t\t\t\t\t\t\t\t\tfiringLength--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );\n\t\t\t},\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tlist = [];\n\t\t\t\tfiringLength = 0;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Have the list do nothing anymore\n\t\t\tdisable: function() {\n\t\t\t\tlist = stack = memory = undefined;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it disabled?\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\t\t\t// Lock the list in its current state\n\t\t\tlock: function() {\n\t\t\t\tstack = undefined;\n\t\t\t\tif ( !memory ) {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it locked?\n\t\t\tlocked: function() {\n\t\t\t\treturn !stack;\n\t\t\t},\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( list && ( !fired || stack ) ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tstack.push( args );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfire( args );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\njQuery.extend({\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\t\t\t\t// action, add listener, listener list, final state\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tthen: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\t\t\t\t\treturn jQuery.Deferred(function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\t\t\t\t\tvar action = tuple[ 0 ],\n\t\t\t\t\t\t\t\tfn = jQuery.isFunction( fns[ i ] ) && fns[ i ];\n\t\t\t\t\t\t\t// deferred[ done | fail | progress ] for forwarding actions to newDefer\n\t\t\t\t\t\t\tdeferred[ tuple[1] ](function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject )\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ action + \"With\" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t}).promise();\n\t\t\t\t},\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Keep pipe for back-compat\n\t\tpromise.pipe = promise.then;\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 3 ];\n\n\t\t\t// promise[ done | fail | progress ] = list.add\n\t\t\tpromise[ tuple[1] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(function() {\n\t\t\t\t\t// state = [ resolved | rejected ]\n\t\t\t\t\tstate = stateString;\n\n\t\t\t\t// [ reject_list | resolve_list ].disable; progress_list.lock\n\t\t\t\t}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n\t\t\t}\n\n\t\t\t// deferred[ resolve | reject | notify ]\n\t\t\tdeferred[ tuple[0] ] = function() {\n\t\t\t\tdeferred[ tuple[0] + \"With\" ]( this === deferred ? promise : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tdeferred[ tuple[0] + \"With\" ] = list.fireWith;\n\t\t});\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( subordinate /* , ..., subordinateN */ ) {\n\t\tvar i = 0,\n\t\t\tresolveValues = core_slice.call( arguments ),\n\t\t\tlength = resolveValues.length,\n\n\t\t\t// the count of uncompleted subordinates\n\t\t\tremaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\n\t\t\t// the master Deferred. If resolveValues consist of only a single Deferred, just use that.\n\t\t\tdeferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n\t\t\t// Update function for both resolve and progress values\n\t\t\tupdateFunc = function( i, contexts, values ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tcontexts[ i ] = this;\n\t\t\t\t\tvalues[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;\n\t\t\t\t\tif( values === progressValues ) {\n\t\t\t\t\t\tdeferred.notifyWith( contexts, values );\n\t\t\t\t\t} else if ( !( --remaining ) ) {\n\t\t\t\t\t\tdeferred.resolveWith( contexts, values );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\n\t\t\tprogressValues, progressContexts, resolveContexts;\n\n\t\t// add listeners to Deferred subordinates; treat others as resolved\n\t\tif ( length > 1 ) {\n\t\t\tprogressValues = new Array( length );\n\t\t\tprogressContexts = new Array( length );\n\t\t\tresolveContexts = new Array( length );\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n\t\t\t\t\tresolveValues[ i ].promise()\n\t\t\t\t\t\t.done( updateFunc( i, resolveContexts, resolveValues ) )\n\t\t\t\t\t\t.fail( deferred.reject )\n\t\t\t\t\t\t.progress( updateFunc( i, progressContexts, progressValues ) );\n\t\t\t\t} else {\n\t\t\t\t\t--remaining;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// if we're not waiting on anything, resolve the master\n\t\tif ( !remaining ) {\n\t\t\tdeferred.resolveWith( resolveContexts, resolveValues );\n\t\t}\n\n\t\treturn deferred.promise();\n\t}\n});\njQuery.support = (function( support ) {\n\tvar input = document.createElement(\"input\"),\n\t\tfragment = document.createDocumentFragment(),\n\t\tdiv = document.createElement(\"div\"),\n\t\tselect = document.createElement(\"select\"),\n\t\topt = select.appendChild( document.createElement(\"option\") );\n\n\t// Finish early in limited environments\n\tif ( !input.type ) {\n\t\treturn support;\n\t}\n\n\tinput.type = \"checkbox\";\n\n\t// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3\n\t// Check the default checkbox/radio value (\"\" on old WebKit; \"on\" elsewhere)\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Must access the parent to make an option select properly\n\t// Support: IE9, IE10\n\tsupport.optSelected = opt.selected;\n\n\t// Will be defined later\n\tsupport.reliableMarginRight = true;\n\tsupport.boxSizingReliable = true;\n\tsupport.pixelPosition = false;\n\n\t// Make sure checked status is properly cloned\n\t// Support: IE9, IE10\n\tinput.checked = true;\n\tsupport.noCloneChecked = input.cloneNode( true ).checked;\n\n\t// Make sure that the options inside disabled selects aren't marked as disabled\n\t// (WebKit marks them as disabled)\n\tselect.disabled = true;\n\tsupport.optDisabled = !opt.disabled;\n\n\t// Check if an input maintains its value after becoming a radio\n\t// Support: IE9, IE10\n\tinput = document.createElement(\"input\");\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n\n\t// #11217 - WebKit loses check when the name is after the checked attribute\n\tinput.setAttribute( \"checked\", \"t\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tfragment.appendChild( input );\n\n\t// Support: Safari 5.1, Android 4.x, Android 2.3\n\t// old WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: Firefox, Chrome, Safari\n\t// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)\n\tsupport.focusinBubbles = \"onfocusin\" in window;\n\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\t// Run tests that need a body at doc ready\n\tjQuery(function() {\n\t\tvar container, marginDiv,\n\t\t\t// Support: Firefox, Android 2.3 (Prefixed box-sizing versions).\n\t\t\tdivReset = \"padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box\",\n\t\t\tbody = document.getElementsByTagName(\"body\")[ 0 ];\n\n\t\tif ( !body ) {\n\t\t\t// Return for frameset docs that don't have a body\n\t\t\treturn;\n\t\t}\n\n\t\tcontainer = document.createElement(\"div\");\n\t\tcontainer.style.cssText = \"border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px\";\n\n\t\t// Check box-sizing and margin behavior.\n\t\tbody.appendChild( container ).appendChild( div );\n\t\tdiv.innerHTML = \"\";\n\t\t// Support: Firefox, Android 2.3 (Prefixed box-sizing versions).\n\t\tdiv.style.cssText = \"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%\";\n\n\t\t// Workaround failing boxSizing test due to offsetWidth returning wrong value\n\t\t// with some non-1 values of body zoom, ticket #13543\n\t\tjQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() {\n\t\t\tsupport.boxSizing = div.offsetWidth === 4;\n\t\t});\n\n\t\t// Use window.getComputedStyle because jsdom on node.js will break without it.\n\t\tif ( window.getComputedStyle ) {\n\t\t\tsupport.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== \"1%\";\n\t\t\tsupport.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: \"4px\" } ).width === \"4px\";\n\n\t\t\t// Support: Android 2.3\n\t\t\t// Check if div with explicit width and no margin-right incorrectly\n\t\t\t// gets computed margin-right based on width of container. (#3333)\n\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\tmarginDiv = div.appendChild( document.createElement(\"div\") );\n\t\t\tmarginDiv.style.cssText = div.style.cssText = divReset;\n\t\t\tmarginDiv.style.marginRight = marginDiv.style.width = \"0\";\n\t\t\tdiv.style.width = \"1px\";\n\n\t\t\tsupport.reliableMarginRight =\n\t\t\t\t!parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );\n\t\t}\n\n\t\tbody.removeChild( container );\n\t});\n\n\treturn support;\n})( {} );\n\n/*\n\tImplementation Summary\n\n\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n\t2. Improve the module's maintainability by reducing the storage\n\t\tpaths to a single mechanism.\n\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n*/\nvar data_user, data_priv,\n\trbrace = /(?:\\{[\\s\\S]*\\}|\\[[\\s\\S]*\\])$/,\n\trmultiDash = /([A-Z])/g;\n\nfunction Data() {\n\t// Support: Android < 4,\n\t// Old WebKit does not have Object.preventExtensions/freeze method,\n\t// return new empty object instead with no [[set]] accessor\n\tObject.defineProperty( this.cache = {}, 0, {\n\t\tget: function() {\n\t\t\treturn {};\n\t\t}\n\t});\n\n\tthis.expando = jQuery.expando + Math.random();\n}\n\nData.uid = 1;\n\nData.accepts = function( owner ) {\n\t// Accepts only:\n\t//  - Node\n\t//    - Node.ELEMENT_NODE\n\t//    - Node.DOCUMENT_NODE\n\t//  - Object\n\t//    - Any\n\treturn owner.nodeType ?\n\t\towner.nodeType === 1 || owner.nodeType === 9 : true;\n};\n\nData.prototype = {\n\tkey: function( owner ) {\n\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t// but we should not, see #8335.\n\t\t// Always return the key for a frozen object.\n\t\tif ( !Data.accepts( owner ) ) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar descriptor = {},\n\t\t\t// Check if the owner object already has a cache key\n\t\t\tunlock = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !unlock ) {\n\t\t\tunlock = Data.uid++;\n\n\t\t\t// Secure it in a non-enumerable, non-writable property\n\t\t\ttry {\n\t\t\t\tdescriptor[ this.expando ] = { value: unlock };\n\t\t\t\tObject.defineProperties( owner, descriptor );\n\n\t\t\t// Support: Android < 4\n\t\t\t// Fallback to a less secure definition\n\t\t\t} catch ( e ) {\n\t\t\t\tdescriptor[ this.expando ] = unlock;\n\t\t\t\tjQuery.extend( owner, descriptor );\n\t\t\t}\n\t\t}\n\n\t\t// Ensure the cache object\n\t\tif ( !this.cache[ unlock ] ) {\n\t\t\tthis.cache[ unlock ] = {};\n\t\t}\n\n\t\treturn unlock;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\t// There may be an unlock assigned to this node,\n\t\t\t// if there is no entry for this \"owner\", create one inline\n\t\t\t// and set the unlock as though an owner entry had always existed\n\t\t\tunlock = this.key( owner ),\n\t\t\tcache = this.cache[ unlock ];\n\n\t\t// Handle: [ owner, key, value ] args\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ data ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\t\t\t// Fresh assignments by object are shallow copied\n\t\t\tif ( jQuery.isEmptyObject( cache ) ) {\n\t\t\t\tjQuery.extend( this.cache[ unlock ], data );\n\t\t\t// Otherwise, copy the properties one-by-one to the cache object\n\t\t\t} else {\n\t\t\t\tfor ( prop in data ) {\n\t\t\t\t\tcache[ prop ] = data[ prop ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\t// Either a valid cache is found, or will be created.\n\t\t// New caches will be created and the unlock returned,\n\t\t// allowing direct access to the newly created\n\t\t// empty data object. A valid owner object must be provided.\n\t\tvar cache = this.cache[ this.key( owner ) ];\n\n\t\treturn key === undefined ?\n\t\t\tcache : cache[ key ];\n\t},\n\taccess: function( owner, key, value ) {\n\t\tvar stored;\n\t\t// In cases where either:\n\t\t//\n\t\t//   1. No key was specified\n\t\t//   2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t//   1. The entire cache object\n\t\t//   2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t((key && typeof key === \"string\") && value === undefined) ) {\n\n\t\t\tstored = this.get( owner, key );\n\n\t\t\treturn stored !== undefined ?\n\t\t\t\tstored : this.get( owner, jQuery.camelCase(key) );\n\t\t}\n\n\t\t// [*]When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t//   1. An object of properties\n\t\t//   2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i, name, camel,\n\t\t\tunlock = this.key( owner ),\n\t\t\tcache = this.cache[ unlock ];\n\n\t\tif ( key === undefined ) {\n\t\t\tthis.cache[ unlock ] = {};\n\n\t\t} else {\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( jQuery.isArray( key ) ) {\n\t\t\t\t// If \"name\" is an array of keys...\n\t\t\t\t// When data is initially created, via (\"key\", \"val\") signature,\n\t\t\t\t// keys will be converted to camelCase.\n\t\t\t\t// Since there is no way to tell _how_ a key was added, remove\n\t\t\t\t// both plain key and camelCase key. #12786\n\t\t\t\t// This will only penalize the array argument path.\n\t\t\t\tname = key.concat( key.map( jQuery.camelCase ) );\n\t\t\t} else {\n\t\t\t\tcamel = jQuery.camelCase( key );\n\t\t\t\t// Try the string as a key before any manipulation\n\t\t\t\tif ( key in cache ) {\n\t\t\t\t\tname = [ key, camel ];\n\t\t\t\t} else {\n\t\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\t\tname = camel;\n\t\t\t\t\tname = name in cache ?\n\t\t\t\t\t\t[ name ] : ( name.match( core_rnotwhite ) || [] );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ti = name.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ name[ i ] ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\treturn !jQuery.isEmptyObject(\n\t\t\tthis.cache[ owner[ this.expando ] ] || {}\n\t\t);\n\t},\n\tdiscard: function( owner ) {\n\t\tif ( owner[ this.expando ] ) {\n\t\t\tdelete this.cache[ owner[ this.expando ] ];\n\t\t}\n\t}\n};\n\n// These may be used throughout the jQuery core codebase\ndata_user = new Data();\ndata_priv = new Data();\n\n\njQuery.extend({\n\tacceptData: Data.accepts,\n\n\thasData: function( elem ) {\n\t\treturn data_user.hasData( elem ) || data_priv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn data_user.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdata_user.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to data_priv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn data_priv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdata_priv.remove( elem, name );\n\t}\n});\n\njQuery.fn.extend({\n\tdata: function( key, value ) {\n\t\tvar attrs, name,\n\t\t\telem = this[ 0 ],\n\t\t\ti = 0,\n\t\t\tdata = null;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = data_user.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !data_priv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\tattrs = elem.attributes;\n\t\t\t\t\tfor ( ; i < attrs.length; i++ ) {\n\t\t\t\t\t\tname = attrs[ i ].name;\n\n\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\tname = jQuery.camelCase( name.slice(5) );\n\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdata_priv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tdata_user.set( this, key );\n\t\t\t});\n\t\t}\n\n\t\treturn jQuery.access( this, function( value ) {\n\t\t\tvar data,\n\t\t\t\tcamelKey = jQuery.camelCase( key );\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// with the key as-is\n\t\t\t\tdata = data_user.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// with the key camelized\n\t\t\t\tdata = data_user.get( elem, camelKey );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, camelKey, undefined );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tthis.each(function() {\n\t\t\t\t// First, attempt to store a copy or reference of any\n\t\t\t\t// data that might've been store with a camelCased key.\n\t\t\t\tvar data = data_user.get( this, camelKey );\n\n\t\t\t\t// For HTML5 data-* attribute interop, we have to\n\t\t\t\t// store property names with dashes in a camelCase form.\n\t\t\t\t// This might not apply to all properties...*\n\t\t\t\tdata_user.set( this, camelKey, value );\n\n\t\t\t\t// *... In the case of properties that might _actually_\n\t\t\t\t// have dashes, we need to also store a copy of that\n\t\t\t\t// unchanged property.\n\t\t\t\tif ( key.indexOf(\"-\") !== -1 && data !== undefined ) {\n\t\t\t\t\tdata_user.set( this, key, value );\n\t\t\t\t}\n\t\t\t});\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each(function() {\n\t\t\tdata_user.remove( this, key );\n\t\t});\n\t}\n});\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\t\tdata === \"false\" ? false :\n\t\t\t\t\tdata === \"null\" ? null :\n\t\t\t\t\t// Only convert to a number if it doesn't change the string\n\t\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\t\trbrace.test( data ) ? JSON.parse( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdata_user.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\njQuery.extend({\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = data_priv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray( data ) ) {\n\t\t\t\t\tqueue = data_priv.access( elem, type, jQuery.makeArray(data) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// not intended for public consumption - generates a queueHooks object, or returns the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn data_priv.get( elem, key ) || data_priv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks(\"once memory\").add(function() {\n\t\t\t\tdata_priv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t})\n\t\t});\n\t}\n});\n\njQuery.fn.extend({\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[0], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t});\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t});\n\t},\n\t// Based off of the plugin by Clint Helfers, with permission.\n\t// http://blindsignals.com/index.php/2009/07/jquery-delay/\n\tdelay: function( time, type ) {\n\t\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\t\ttype = type || \"fx\";\n\n\t\treturn this.queue( type, function( next, hooks ) {\n\t\t\tvar timeout = setTimeout( next, time );\n\t\t\thooks.stop = function() {\n\t\t\t\tclearTimeout( timeout );\n\t\t\t};\n\t\t});\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile( i-- ) {\n\t\t\ttmp = data_priv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n});\nvar nodeHook, boolHook,\n\trclass = /[\\t\\r\\n\\f]/g,\n\trreturn = /\\r/g,\n\trfocusable = /^(?:input|select|textarea|button)$/i;\n\njQuery.fn.extend({\n\tattr: function( name, value ) {\n\t\treturn jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t});\n\t},\n\n\tprop: function( name, value ) {\n\t\treturn jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each(function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t});\n\t},\n\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j,\n\t\t\ti = 0,\n\t\t\tlen = this.length,\n\t\t\tproceed = typeof value === \"string\" && value;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\n\t\tif ( proceed ) {\n\t\t\t// The disjunction here is for better compressibility (see removeClass)\n\t\t\tclasses = ( value || \"\" ).match( core_rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\" \"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telem.className = jQuery.trim( cur );\n\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j,\n\t\t\ti = 0,\n\t\t\tlen = this.length,\n\t\t\tproceed = arguments.length === 0 || typeof value === \"string\" && value;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\t\tif ( proceed ) {\n\t\t\tclasses = ( value || \"\" ).match( core_rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\"\"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) >= 0 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telem.className = value ? jQuery.trim( cur ) : \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value;\n\n\t\tif ( typeof stateVal === \"boolean\" && type === \"string\" ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( type === \"string\" ) {\n\t\t\t\t// toggle individual class names\n\t\t\t\tvar className,\n\t\t\t\t\ti = 0,\n\t\t\t\t\tself = jQuery( this ),\n\t\t\t\t\tclassNames = value.match( core_rnotwhite ) || [];\n\n\t\t\t\twhile ( (className = classNames[ i++ ]) ) {\n\t\t\t\t\t// check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( type === core_strundefined || type === \"boolean\" ) {\n\t\t\t\tif ( this.className ) {\n\t\t\t\t\t// store className if set\n\t\t\t\t\tdata_priv.set( this, \"__className__\", this.className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed \"false\",\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tthis.className = this.className || value === false ? \"\" : data_priv.get( this, \"__className__\" ) || \"\";\n\t\t\t}\n\t\t});\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className = \" \" + selector + \" \",\n\t\t\ti = 0,\n\t\t\tl = this.length;\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tif ( this[i].nodeType === 1 && (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) >= 0 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t},\n\n\tval: function( value ) {\n\t\tvar hooks, ret, isFunction,\n\t\t\telem = this[0];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, \"value\" )) !== undefined ) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\treturn typeof ret === \"string\" ?\n\t\t\t\t\t// handle most common string cases\n\t\t\t\t\tret.replace(rreturn, \"\") :\n\t\t\t\t\t// handle cases where value is null/undef or number\n\t\t\t\t\tret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tisFunction = jQuery.isFunction( value );\n\n\t\treturn this.each(function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\t\t\t} else if ( jQuery.isArray( val ) ) {\n\t\t\t\tval = jQuery.map(val, function ( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !(\"set\" in hooks) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\t\t\t\t// attributes.value is undefined in Blackberry 4.7 but\n\t\t\t\t// uses .value. See #6932\n\t\t\t\tvar val = elem.attributes.value;\n\t\t\t\treturn !val || val.specified ? elem.value : elem.text;\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\" || index < 0,\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length,\n\t\t\t\t\ti = index < 0 ?\n\t\t\t\t\t\tmax :\n\t\t\t\t\t\tone ? index : 0;\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// IE6-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t( jQuery.support.optDisabled ? !option.disabled : option.getAttribute(\"disabled\") === null ) &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\t\t\t\t\tif ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t},\n\n\tattr: function( elem, name, value ) {\n\t\tvar hooks, ret,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set attributes on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === core_strundefined ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// All attributes are lowercase\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\tname = name.toLowerCase();\n\t\t\thooks = jQuery.attrHooks[ name ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\n\t\t\t} else if ( hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t} else if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ) {\n\t\t\treturn ret;\n\n\t\t} else {\n\t\t\tret = jQuery.find.attr( elem, name );\n\n\t\t\t// Non-existent attributes return null, we normalize to undefined\n\t\t\treturn ret == null ?\n\t\t\t\tundefined :\n\t\t\t\tret;\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name, propName,\n\t\t\ti = 0,\n\t\t\tattrNames = value && value.match( core_rnotwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( (name = attrNames[i++]) ) {\n\t\t\t\tpropName = jQuery.propFix[ name ] || name;\n\n\t\t\t\t// Boolean attributes get special treatment (#10870)\n\t\t\t\tif ( jQuery.expr.match.bool.test( name ) ) {\n\t\t\t\t\t// Set corresponding property to false\n\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t}\n\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !jQuery.support.radioValue && value === \"radio\" && jQuery.nodeName(elem, \"input\") ) {\n\t\t\t\t\t// Setting the type on a radio button after the value resets the value in IE6-9\n\t\t\t\t\t// Reset value to default in case type is set after value during creation\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t},\n\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks, notxml,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set properties on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tnotxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n\t\tif ( notxml ) {\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\treturn hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?\n\t\t\t\tret :\n\t\t\t\t( elem[ name ] = value );\n\n\t\t} else {\n\t\t\treturn hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ?\n\t\t\t\tret :\n\t\t\t\telem[ name ];\n\t\t}\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\t\t\t\treturn elem.hasAttribute( \"tabindex\" ) || rfocusable.test( elem.nodeName ) || elem.href ?\n\t\t\t\t\telem.tabIndex :\n\t\t\t\t\t-1;\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\tvar getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr;\n\n\tjQuery.expr.attrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar fn = jQuery.expr.attrHandle[ name ],\n\t\t\tret = isXML ?\n\t\t\t\tundefined :\n\t\t\t\t/* jshint eqeqeq: false */\n\t\t\t\t// Temporarily disable this handler to check existence\n\t\t\t\t(jQuery.expr.attrHandle[ name ] = undefined) !=\n\t\t\t\t\tgetter( elem, name, isXML ) ?\n\n\t\t\t\t\tname.toLowerCase() :\n\t\t\t\t\tnull;\n\n\t\t// Restore handler\n\t\tjQuery.expr.attrHandle[ name ] = fn;\n\n\t\treturn ret;\n\t};\n});\n\n// Support: IE9+\n// Selectedness for an option in an optgroup can be inaccurate\nif ( !jQuery.support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t};\n}\n\njQuery.each([\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n});\n\n// Radios and checkboxes getter/setter\njQuery.each([ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( jQuery.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !jQuery.support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\t// Support: Webkit\n\t\t\t// \"\" is returned instead of \"on\" if a value isn't specified\n\t\t\treturn elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n\t\t};\n\t}\n});\nvar rkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|contextmenu)|click/,\n\trfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)$/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = data_priv.get( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !(events = elemData.events) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !(eventHandle = elemData.handle) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ?\n\t\t\t\t\tjQuery.event.dispatch.apply( eventHandle.elem, arguments ) :\n\t\t\t\t\tundefined;\n\t\t\t};\n\t\t\t// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events\n\t\t\teventHandle.elem = elem;\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( core_rnotwhite ) || [\"\"];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend({\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join(\".\")\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !(handlers = events[ type ]) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle, false );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t\t// Nullify elem to prevent memory leaks in IE\n\t\telem = null;\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = data_priv.hasData( elem ) && data_priv.get( elem );\n\n\t\tif ( !elemData || !(events = elemData.events) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( core_rnotwhite ) || [\"\"];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[2] && new RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdelete elemData.handle;\n\t\t\tdata_priv.remove( elem, \"events\" );\n\t\t}\n\t},\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = core_hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = core_hasOwn.call( event, \"namespace\" ) ? event.namespace.split(\".\") : [];\n\n\t\tcur = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf(\".\") >= 0 ) {\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split(\".\");\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf(\":\") < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join(\".\");\n\t\tevent.namespace_re = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === (elem.ownerDocument || document) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {\n\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( data_priv.get( cur, \"events\" ) || {} )[ event.type ] && data_priv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&\n\t\t\t\tjQuery.acceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\telem[ type ]();\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\tdispatch: function( event ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tevent = jQuery.event.fix( event );\n\n\t\tvar i, j, ret, matched, handleObj,\n\t\t\thandlerQueue = [],\n\t\t\targs = core_slice.call( arguments ),\n\t\t\thandlers = ( data_priv.get( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[0] = event;\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// Triggered event must either 1) have no namespace, or\n\t\t\t\t// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n\t\t\t\t\t\t\t.apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( (event.result = ret) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, matches, sel, handleObj,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\t// Black-hole SVG <use> instance trees (#13180)\n\t\t// Avoid non-left-click bubbling in Firefox (#3861)\n\t\tif ( delegateCount && cur.nodeType && (!event.button || event.type !== \"click\") ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.disabled !== true || event.type !== \"click\" ) {\n\t\t\t\t\tmatches = [];\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matches[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatches[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) >= 0 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matches[ sel ] ) {\n\t\t\t\t\t\t\tmatches.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matches.length ) {\n\t\t\t\t\t\thandlerQueue.push({ elem: cur, handlers: matches });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\t// Includes some event props shared by KeyEvent and MouseEvent\n\tprops: \"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n\tfixHooks: {},\n\n\tkeyHooks: {\n\t\tprops: \"char charCode key keyCode\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\n\t\t\t// Add which for key events\n\t\t\tif ( event.which == null ) {\n\t\t\t\tevent.which = original.charCode != null ? original.charCode : original.keyCode;\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tmouseHooks: {\n\t\tprops: \"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\t\t\tvar eventDoc, doc, body,\n\t\t\t\tbutton = original.button;\n\n\t\t\t// Calculate pageX/Y if missing and clientX/Y available\n\t\t\tif ( event.pageX == null && original.clientX != null ) {\n\t\t\t\teventDoc = event.target.ownerDocument || document;\n\t\t\t\tdoc = eventDoc.documentElement;\n\t\t\t\tbody = eventDoc.body;\n\n\t\t\t\tevent.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n\t\t\t\tevent.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );\n\t\t\t}\n\n\t\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\t\t// Note: button is not normalized, so don't use it\n\t\t\tif ( !event.which && button !== undefined ) {\n\t\t\t\tevent.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tfix: function( event ) {\n\t\tif ( event[ jQuery.expando ] ) {\n\t\t\treturn event;\n\t\t}\n\n\t\t// Create a writable copy of the event object and normalize some properties\n\t\tvar i, prop, copy,\n\t\t\ttype = event.type,\n\t\t\toriginalEvent = event,\n\t\t\tfixHook = this.fixHooks[ type ];\n\n\t\tif ( !fixHook ) {\n\t\t\tthis.fixHooks[ type ] = fixHook =\n\t\t\t\trmouseEvent.test( type ) ? this.mouseHooks :\n\t\t\t\trkeyEvent.test( type ) ? this.keyHooks :\n\t\t\t\t{};\n\t\t}\n\t\tcopy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n\t\tevent = new jQuery.Event( originalEvent );\n\n\t\ti = copy.length;\n\t\twhile ( i-- ) {\n\t\t\tprop = copy[ i ];\n\t\t\tevent[ prop ] = originalEvent[ prop ];\n\t\t}\n\n\t\t// Support: Cordova 2.5 (WebKit) (#13255)\n\t\t// All events should have a target; Cordova deviceready doesn't\n\t\tif ( !event.target ) {\n\t\t\tevent.target = document;\n\t\t}\n\n\t\t// Support: Safari 6.0+, Chrome < 28\n\t\t// Target should not be a text node (#504, #13143)\n\t\tif ( event.target.nodeType === 3 ) {\n\t\t\tevent.target = event.target.parentNode;\n\t\t}\n\n\t\treturn fixHook.filter? fixHook.filter( event, originalEvent ) : event;\n\t},\n\n\tspecial: {\n\t\tload: {\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\t\t\t// Fire native event if possible so blur/focus sequence is correct\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\tthis.focus();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\t\t\t// For checkbox, fire native event so checked state will be right\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this.type === \"checkbox\" && this.click && jQuery.nodeName( this, \"input\" ) ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, don't fire native .click() on links\n\t\t\t_default: function( event ) {\n\t\t\t\treturn jQuery.nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tsimulate: function( type, elem, event, bubble ) {\n\t\t// Piggyback on a donor event to simulate a different one.\n\t\t// Fake originalEvent to avoid donor's stopPropagation, but if the\n\t\t// simulated event prevents default then we do the same on the donor.\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true,\n\t\t\t\toriginalEvent: {}\n\t\t\t}\n\t\t);\n\t\tif ( bubble ) {\n\t\t\tjQuery.event.trigger( e, null, elem );\n\t\t} else {\n\t\t\tjQuery.event.dispatch.call( elem, e );\n\t\t}\n\t\tif ( e.isDefaultPrevented() ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n};\n\njQuery.removeEvent = function( elem, type, handle ) {\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle, false );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\t// Allow instantiation without the 'new' keyword\n\tif ( !(this instanceof jQuery.Event) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = ( src.defaultPrevented ||\n\t\t\tsrc.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && e.preventDefault ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && e.stopPropagation ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// Support: Chrome 15+\njQuery.each({\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mousenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || (related !== target && !jQuery.contains( target, related )) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n});\n\n// Create \"bubbling\" focus and blur events\n// Support: Firefox, Chrome, Safari\nif ( !jQuery.support.focusinBubbles ) {\n\tjQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler while someone wants focusin/focusout\n\t\tvar attaches = 0,\n\t\t\thandler = function( event ) {\n\t\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );\n\t\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tif ( attaches++ === 0 ) {\n\t\t\t\t\tdocument.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tif ( --attaches === 0 ) {\n\t\t\t\t\tdocument.removeEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\njQuery.fn.extend({\n\n\ton: function( types, selector, data, fn, /*INTERNAL*/ one ) {\n\t\tvar origFn, type;\n\n\t\t// Types can be a map of types/handlers\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-Object, selector, data )\n\t\t\tif ( typeof selector !== \"string\" ) {\n\t\t\t\t// ( types-Object, data )\n\t\t\t\tdata = data || selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.on( type, selector, data, types[ type ], one );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( data == null && fn == null ) {\n\t\t\t// ( types, fn )\n\t\t\tfn = selector;\n\t\t\tdata = selector = undefined;\n\t\t} else if ( fn == null ) {\n\t\t\tif ( typeof selector === \"string\" ) {\n\t\t\t\t// ( types, selector, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = undefined;\n\t\t\t} else {\n\t\t\t\t// ( types, data, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t} else if ( !fn ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( one === 1 ) {\n\t\t\torigFn = fn;\n\t\t\tfn = function( event ) {\n\t\t\t\t// Can use an empty set, since event contains the info\n\t\t\t\tjQuery().off( event );\n\t\t\t\treturn origFn.apply( this, arguments );\n\t\t\t};\n\t\t\t// Use same guid so caller can remove using origFn\n\t\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.add( this, types, fn, data, selector );\n\t\t});\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn this.on( types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t});\n\t},\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t});\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[0];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n});\nvar isSimple = /^.[^:#\\[\\.,]*$/,\n\trparentsprev = /^(?:parents|prev(?:Until|All))/,\n\trneedsContext = jQuery.expr.match.needsContext,\n\t// methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend({\n\tfind: function( selector ) {\n\t\tvar i,\n\t\t\tret = [],\n\t\t\tself = this,\n\t\t\tlen = self.length;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter(function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}) );\n\t\t}\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\t// Needed because $( selector, context ) becomes $( context ).find( selector )\n\t\tret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );\n\t\tret.selector = this.selector ? this.selector + \" \" + selector : selector;\n\t\treturn ret;\n\t},\n\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter(function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[i] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], true) );\n\t},\n\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], false) );\n\t},\n\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\tpos = ( rneedsContext.test( selectors ) || typeof selectors !== \"string\" ) ?\n\t\t\t\tjQuery( selectors, context || this.context ) :\n\t\t\t\t0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tfor ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {\n\t\t\t\t// Always skip document fragments\n\t\t\t\tif ( cur.nodeType < 11 && (pos ?\n\t\t\t\t\tpos.index(cur) > -1 :\n\n\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\tjQuery.find.matchesSelector(cur, selectors)) ) {\n\n\t\t\t\t\tcur = matched.push( cur );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within\n\t// the matched set of elements\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn core_indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn core_indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\tvar set = typeof selector === \"string\" ?\n\t\t\t\tjQuery( selector, context ) :\n\t\t\t\tjQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),\n\t\t\tall = jQuery.merge( this.get(), set );\n\n\t\treturn this.pushStack( jQuery.unique(all) );\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter(selector)\n\t\t);\n\t}\n});\n\nfunction sibling( cur, dir ) {\n\twhile ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}\n\n\treturn cur;\n}\n\njQuery.each({\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn jQuery.dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn jQuery.sibling( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn elem.contentDocument || jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.unique( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n});\n\njQuery.extend({\n\tfilter: function( expr, elems, not ) {\n\t\tvar elem = elems[ 0 ];\n\n\t\tif ( not ) {\n\t\t\texpr = \":not(\" + expr + \")\";\n\t\t}\n\n\t\treturn elems.length === 1 && elem.nodeType === 1 ?\n\t\t\tjQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :\n\t\t\tjQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\t\t\treturn elem.nodeType === 1;\n\t\t\t}));\n\t},\n\n\tdir: function( elem, dir, until ) {\n\t\tvar matched = [],\n\t\t\ttruncate = until !== undefined;\n\n\t\twhile ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tmatched.push( elem );\n\t\t\t}\n\t\t}\n\t\treturn matched;\n\t},\n\n\tsibling: function( n, elem ) {\n\t\tvar matched = [];\n\n\t\tfor ( ; n; n = n.nextSibling ) {\n\t\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\t\tmatched.push( n );\n\t\t\t}\n\t\t}\n\n\t\treturn matched;\n\t}\n});\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\t/* jshint -W018 */\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t});\n\n\t}\n\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t});\n\n\t}\n\n\tif ( typeof qualifier === \"string\" ) {\n\t\tif ( isSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter( qualifier, elements, not );\n\t\t}\n\n\t\tqualifier = jQuery.filter( qualifier, elements );\n\t}\n\n\treturn jQuery.grep( elements, function( elem ) {\n\t\treturn ( core_indexOf.call( qualifier, elem ) >= 0 ) !== not;\n\t});\n}\nvar rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n\trtagName = /<([\\w:]+)/,\n\trhtml = /<|&#?\\w+;/,\n\trnoInnerhtml = /<(?:script|style|link)/i,\n\tmanipulation_rcheckableType = /^(?:checkbox|radio)$/i,\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptType = /^$|\\/(?:java|ecma)script/i,\n\trscriptTypeMasked = /^true\\/(.*)/,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,\n\n\t// We have to close these tags to support XHTML (#13200)\n\twrapMap = {\n\n\t\t// Support: IE 9\n\t\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\n\t\tthead: [ 1, \"<table>\", \"</table>\" ],\n\t\tcol: [ 2, \"<table><colgroup>\", \"</colgroup></table>\" ],\n\t\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\t\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t\t_default: [ 0, \"\", \"\" ]\n\t};\n\n// Support: IE 9\nwrapMap.optgroup = wrapMap.option;\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\njQuery.fn.extend({\n\ttext: function( value ) {\n\t\treturn jQuery.access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().append( ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value ) );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t});\n\t},\n\n\tprepend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t});\n\t},\n\n\tbefore: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t});\n\t},\n\n\tafter: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t});\n\t},\n\n\t// keepData is for internal use only--do not document\n\tremove: function( selector, keepData ) {\n\t\tvar elem,\n\t\t\telems = selector ? jQuery.filter( selector, this ) : this,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( !keepData && elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem ) );\n\t\t\t}\n\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\tif ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\t\tsetGlobalEval( getAll( elem, \"script\" ) );\n\t\t\t\t}\n\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = this[i]) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function () {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t});\n\t},\n\n\thtml: function( value ) {\n\t\treturn jQuery.access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = value.replace( rxhtmlTag, \"<$1></$2>\" );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar\n\t\t\t// Snapshot the DOM in case .domManip sweeps something relevant into its fragment\n\t\t\targs = jQuery.map( this, function( elem ) {\n\t\t\t\treturn [ elem.nextSibling, elem.parentNode ];\n\t\t\t}),\n\t\t\ti = 0;\n\n\t\t// Make the changes, replacing each context element with the new content\n\t\tthis.domManip( arguments, function( elem ) {\n\t\t\tvar next = args[ i++ ],\n\t\t\t\tparent = args[ i++ ];\n\n\t\t\tif ( parent ) {\n\t\t\t\t// Don't use the snapshot next if it has moved (#13810)\n\t\t\t\tif ( next && next.parentNode !== parent ) {\n\t\t\t\t\tnext = this.nextSibling;\n\t\t\t\t}\n\t\t\t\tjQuery( this ).remove();\n\t\t\t\tparent.insertBefore( elem, next );\n\t\t\t}\n\t\t// Allow new content to include elements from the context set\n\t\t}, true );\n\n\t\t// Force removal if there was no new content (e.g., from empty arguments)\n\t\treturn i ? this : this.remove();\n\t},\n\n\tdetach: function( selector ) {\n\t\treturn this.remove( selector, true );\n\t},\n\n\tdomManip: function( args, callback, allowIntersection ) {\n\n\t\t// Flatten any nested arrays\n\t\targs = core_concat.apply( [], args );\n\n\t\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tset = this,\n\t\t\tiNoClone = l - 1,\n\t\t\tvalue = args[ 0 ],\n\t\t\tisFunction = jQuery.isFunction( value );\n\n\t\t// We can't cloneNode fragments that contain checked, in WebKit\n\t\tif ( isFunction || !( l <= 1 || typeof value !== \"string\" || jQuery.support.checkClone || !rchecked.test( value ) ) ) {\n\t\t\treturn this.each(function( index ) {\n\t\t\t\tvar self = set.eq( index );\n\t\t\t\tif ( isFunction ) {\n\t\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t\t}\n\t\t\t\tself.domManip( args, callback, allowIntersection );\n\t\t\t});\n\t\t}\n\n\t\tif ( l ) {\n\t\t\tfragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, !allowIntersection && this );\n\t\t\tfirst = fragment.firstChild;\n\n\t\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\t\tfragment = first;\n\t\t\t}\n\n\t\t\tif ( first ) {\n\t\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\t\thasScripts = scripts.length;\n\n\t\t\t\t// Use the original fragment for the last item instead of the first because it can end up\n\t\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\tnode = fragment;\n\n\t\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\t\t\t// Support: QtWebKit\n\t\t\t\t\t\t\t// jQuery.merge because core_push.apply(_, arraylike) throws\n\t\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcallback.call( this[ i ], node, i );\n\t\t\t\t}\n\n\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t\t// Reenable scripts\n\t\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t\t!data_priv.access( node, \"globalEval\" ) && jQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\t\tif ( node.src ) {\n\t\t\t\t\t\t\t\t// Hope ajax is available...\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.globalEval( node.textContent.replace( rcleanScript, \"\" ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n});\n\njQuery.each({\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: QtWebKit\n\t\t\t// .get() because core_push.apply(_, arraylike) throws\n\t\t\tcore_push.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\n\njQuery.extend({\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t// Support: IE >= 9\n\t\t// Fix Cloning issues\n\t\tif ( !jQuery.support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tbuildFragment: function( elems, context, scripts, selection ) {\n\t\tvar elem, tmp, tag, wrap, contains, j,\n\t\t\ti = 0,\n\t\t\tl = elems.length,\n\t\t\tfragment = context.createDocumentFragment(),\n\t\t\tnodes = [];\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\telem = elems[ i ];\n\n\t\t\tif ( elem || elem === 0 ) {\n\n\t\t\t\t// Add nodes directly\n\t\t\t\tif ( jQuery.type( elem ) === \"object\" ) {\n\t\t\t\t\t// Support: QtWebKit\n\t\t\t\t\t// jQuery.merge because core_push.apply(_, arraylike) throws\n\t\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t\t// Convert non-html into a text node\n\t\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t\t// Convert html into DOM nodes\n\t\t\t\t} else {\n\t\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement(\"div\") );\n\n\t\t\t\t\t// Deserialize a standard representation\n\t\t\t\t\ttag = ( rtagName.exec( elem ) || [\"\", \"\"] )[ 1 ].toLowerCase();\n\t\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\t\ttmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, \"<$1></$2>\" ) + wrap[ 2 ];\n\n\t\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\t\tj = wrap[ 0 ];\n\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: QtWebKit\n\t\t\t\t\t// jQuery.merge because core_push.apply(_, arraylike) throws\n\t\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t\t// Remember the top-level container\n\t\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t\t// Fixes #12346\n\t\t\t\t\t// Support: Webkit, IE\n\t\t\t\t\ttmp.textContent = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Remove wrapper from fragment\n\t\tfragment.textContent = \"\";\n\n\t\ti = 0;\n\t\twhile ( (elem = nodes[ i++ ]) ) {\n\n\t\t\t// #4087 - If origin and destination elements are the same, and this is\n\t\t\t// that element, do not do anything\n\t\t\tif ( selection && jQuery.inArray( elem, selection ) !== -1 ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t\t// Append to fragment\n\t\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t\t// Preserve script evaluation history\n\t\t\tif ( contains ) {\n\t\t\t\tsetGlobalEval( tmp );\n\t\t\t}\n\n\t\t\t// Capture executables\n\t\t\tif ( scripts ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (elem = tmp[ j++ ]) ) {\n\t\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\t\tscripts.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn fragment;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, events, type, key, j,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = elems[ i ]) !== undefined; i++ ) {\n\t\t\tif ( Data.accepts( elem ) ) {\n\t\t\t\tkey = elem[ data_priv.expando ];\n\n\t\t\t\tif ( key && (data = data_priv.cache[ key ]) ) {\n\t\t\t\t\tevents = Object.keys( data.events || {} );\n\t\t\t\t\tif ( events.length ) {\n\t\t\t\t\t\tfor ( j = 0; (type = events[j]) !== undefined; j++ ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( data_priv.cache[ key ] ) {\n\t\t\t\t\t\t// Discard any remaining `private` data\n\t\t\t\t\t\tdelete data_priv.cache[ key ];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Discard any remaining `user` data\n\t\t\tdelete data_user.cache[ elem[ data_user.expando ] ];\n\t\t}\n\t},\n\n\t_evalUrl: function( url ) {\n\t\treturn jQuery.ajax({\n\t\t\turl: url,\n\t\t\ttype: \"GET\",\n\t\t\tdataType: \"script\",\n\t\t\tasync: false,\n\t\t\tglobal: false,\n\t\t\t\"throws\": true\n\t\t});\n\t}\n});\n\n// Support: 1.x compatibility\n// Manipulating tables requires a tbody\nfunction manipulationTarget( elem, content ) {\n\treturn jQuery.nodeName( elem, \"table\" ) &&\n\t\tjQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, \"tr\" ) ?\n\n\t\telem.getElementsByTagName(\"tbody\")[0] ||\n\t\t\telem.appendChild( elem.ownerDocument.createElement(\"tbody\") ) :\n\t\telem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = (elem.getAttribute(\"type\") !== null) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tvar match = rscriptTypeMasked.exec( elem.type );\n\n\tif ( match ) {\n\t\telem.type = match[ 1 ];\n\t} else {\n\t\telem.removeAttribute(\"type\");\n\t}\n\n\treturn elem;\n}\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar l = elems.length,\n\t\ti = 0;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdata_priv.set(\n\t\t\telems[ i ], \"globalEval\", !refElements || data_priv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( data_priv.hasData( src ) ) {\n\t\tpdataOld = data_priv.access( src );\n\t\tpdataCur = data_priv.set( dest, pdataOld );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdelete pdataCur.handle;\n\t\t\tpdataCur.events = {};\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( data_user.hasData( src ) ) {\n\t\tudataOld = data_user.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdata_user.set( dest, udataCur );\n\t}\n}\n\n\nfunction getAll( context, tag ) {\n\tvar ret = context.getElementsByTagName ? context.getElementsByTagName( tag || \"*\" ) :\n\t\t\tcontext.querySelectorAll ? context.querySelectorAll( tag || \"*\" ) :\n\t\t\t[];\n\n\treturn tag === undefined || tag && jQuery.nodeName( context, tag ) ?\n\t\tjQuery.merge( [ context ], ret ) :\n\t\tret;\n}\n\n// Support: IE >= 9\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && manipulation_rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\njQuery.fn.extend({\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).wrapAll( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[ 0 ] ) {\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map(function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t}).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t});\n\t},\n\n\twrap: function( html ) {\n\t\tvar isFunction = jQuery.isFunction( html );\n\n\t\treturn this.each(function( i ) {\n\t\t\tjQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );\n\t\t});\n\t},\n\n\tunwrap: function() {\n\t\treturn this.parent().each(function() {\n\t\t\tif ( !jQuery.nodeName( this, \"body\" ) ) {\n\t\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t\t}\n\t\t}).end();\n\t}\n});\nvar curCSS, iframe,\n\t// swappable if display is none or starts with table except \"table\", \"table-cell\", or \"table-caption\"\n\t// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trmargin = /^margin/,\n\trnumsplit = new RegExp( \"^(\" + core_pnum + \")(.*)$\", \"i\" ),\n\trnumnonpx = new RegExp( \"^(\" + core_pnum + \")(?!px)[a-z%]+$\", \"i\" ),\n\trrelNum = new RegExp( \"^([+-])=(\" + core_pnum + \")\", \"i\" ),\n\telemdisplay = { BODY: \"block\" },\n\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: 0,\n\t\tfontWeight: 400\n\t},\n\n\tcssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ],\n\tcssPrefixes = [ \"Webkit\", \"O\", \"Moz\", \"ms\" ];\n\n// return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( style, name ) {\n\n\t// shortcut for names that are not vendor prefixed\n\tif ( name in style ) {\n\t\treturn name;\n\t}\n\n\t// check for vendor prefixed names\n\tvar capName = name.charAt(0).toUpperCase() + name.slice(1),\n\t\torigName = name,\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in style ) {\n\t\t\treturn name;\n\t\t}\n\t}\n\n\treturn origName;\n}\n\nfunction isHidden( elem, el ) {\n\t// isHidden might be called from jQuery#filter function;\n\t// in that case, element will be second argument\n\telem = el || elem;\n\treturn jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n}\n\n// NOTE: we've included the \"window\" in window.getComputedStyle\n// because jsdom on node.js will break without it.\nfunction getStyles( elem ) {\n\treturn window.getComputedStyle( elem, null );\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem, hidden,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tvalues[ index ] = data_priv.get( elem, \"olddisplay\" );\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\t\t\t// Reset the inline display of this element to learn if it is\n\t\t\t// being hidden by cascaded rules or not\n\t\t\tif ( !values[ index ] && display === \"none\" ) {\n\t\t\t\telem.style.display = \"\";\n\t\t\t}\n\n\t\t\t// Set elements which have been overridden with display: none\n\t\t\t// in a stylesheet to whatever the default browser style is\n\t\t\t// for such an element\n\t\t\tif ( elem.style.display === \"\" && isHidden( elem ) ) {\n\t\t\t\tvalues[ index ] = data_priv.access( elem, \"olddisplay\", css_defaultDisplay(elem.nodeName) );\n\t\t\t}\n\t\t} else {\n\n\t\t\tif ( !values[ index ] ) {\n\t\t\t\thidden = isHidden( elem );\n\n\t\t\t\tif ( display && display !== \"none\" || !hidden ) {\n\t\t\t\t\tdata_priv.set( elem, \"olddisplay\", hidden ? display : jQuery.css(elem, \"display\") );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of most of the elements in a second loop\n\t// to avoid the constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( !show || elem.style.display === \"none\" || elem.style.display === \"\" ) {\n\t\t\telem.style.display = show ? values[ index ] || \"\" : \"none\";\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend({\n\tcss: function( name, value ) {\n\t\treturn jQuery.access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( jQuery.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t},\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( isHidden( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {\n\t\t// normalize float css property\n\t\t\"float\": \"cssFloat\"\n\t},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style;\n\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// convert relative number strings (+= or -=) to relative numbers. #7345\n\t\t\tif ( type === \"string\" && (ret = rrelNum.exec( value )) ) {\n\t\t\t\tvalue = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that NaN and null values aren't set. See: #7116\n\t\t\tif ( value == null || type === \"number\" && isNaN( value ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add 'px' to the (except for certain CSS properties)\n\t\t\tif ( type === \"number\" && !jQuery.cssNumber[ origName ] ) {\n\t\t\t\tvalue += \"px\";\n\t\t\t}\n\n\t\t\t// Fixes #8908, it can be done more correctly by specifying setters in cssHooks,\n\t\t\t// but it would mean to define eight (for every problematic property) identical functions\n\t\t\tif ( !jQuery.support.clearCloneStyle && value === \"\" && name.indexOf(\"background\") === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {\n\t\t\t\tstyle[ name ] = value;\n\t\t\t}\n\n\t\t} else {\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = jQuery.camelCase( name );\n\n\t\t// Make sure that we're working with the right name\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t//convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Return, converting to number if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || jQuery.isNumeric( num ) ? num || 0 : val;\n\t\t}\n\t\treturn val;\n\t}\n});\n\ncurCSS = function( elem, name, _computed ) {\n\tvar width, minWidth, maxWidth,\n\t\tcomputed = _computed || getStyles( elem ),\n\n\t\t// Support: IE9\n\t\t// getPropertyValue is only needed for .css('filter') in IE9, see #12537\n\t\tret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,\n\t\tstyle = elem.style;\n\n\tif ( computed ) {\n\n\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// Support: Safari 5.1\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels\n\t\t// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values\n\t\tif ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret;\n};\n\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\tvar matches = rnumsplit.exec( value );\n\treturn matches ?\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {\n\tvar i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n\t\t// If we already have the right measurement, avoid augmentation\n\t\t4 :\n\t\t// Otherwise initialize for horizontal or vertical properties\n\t\tname === \"width\" ? 1 : 0,\n\n\t\tval = 0;\n\n\tfor ( ; i < 4; i += 2 ) {\n\t\t// both box models exclude margin, so add it if we want it\n\t\tif ( extra === \"margin\" ) {\n\t\t\tval += jQuery.css( elem, extra + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\tif ( isBorderBox ) {\n\t\t\t// border-box includes padding, so remove it if we want content\n\t\t\tif ( extra === \"content\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// at this point, extra isn't border nor margin, so remove border\n\t\t\tif ( extra !== \"margin\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t} else {\n\t\t\t// at this point, extra isn't content, so add padding\n\t\t\tval += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// at this point, extra isn't content nor padding, so add border\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n\t// Start with offset property, which is equivalent to the border-box value\n\tvar valueIsBorderBox = true,\n\t\tval = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n\t\tstyles = getStyles( elem ),\n\t\tisBorderBox = jQuery.support.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t// some non-html elements return undefined for offsetWidth, so check for null/undefined\n\t// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n\t// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n\tif ( val <= 0 || val == null ) {\n\t\t// Fall back to computed then uncomputed css if necessary\n\t\tval = curCSS( elem, name, styles );\n\t\tif ( val < 0 || val == null ) {\n\t\t\tval = elem.style[ name ];\n\t\t}\n\n\t\t// Computed unit is not pixels. Stop here and return.\n\t\tif ( rnumnonpx.test(val) ) {\n\t\t\treturn val;\n\t\t}\n\n\t\t// we need the check for style in case a browser which returns unreliable values\n\t\t// for getComputedStyle silently falls back to the reliable elem.style\n\t\tvalueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );\n\n\t\t// Normalize \"\", auto, and prepare for extra\n\t\tval = parseFloat( val ) || 0;\n\t}\n\n\t// use the active box-sizing model to add/subtract irrelevant styles\n\treturn ( val +\n\t\taugmentWidthOrHeight(\n\t\t\telem,\n\t\t\tname,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles\n\t\t)\n\t) + \"px\";\n}\n\n// Try to determine the default display value of an element\nfunction css_defaultDisplay( nodeName ) {\n\tvar doc = document,\n\t\tdisplay = elemdisplay[ nodeName ];\n\n\tif ( !display ) {\n\t\tdisplay = actualDisplay( nodeName, doc );\n\n\t\t// If the simple way fails, read from inside an iframe\n\t\tif ( display === \"none\" || !display ) {\n\t\t\t// Use the already-created iframe if possible\n\t\t\tiframe = ( iframe ||\n\t\t\t\tjQuery(\"<iframe frameborder='0' width='0' height='0'/>\")\n\t\t\t\t.css( \"cssText\", \"display:block !important\" )\n\t\t\t).appendTo( doc.documentElement );\n\n\t\t\t// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse\n\t\t\tdoc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;\n\t\t\tdoc.write(\"<!doctype html><html><body>\");\n\t\t\tdoc.close();\n\n\t\t\tdisplay = actualDisplay( nodeName, doc );\n\t\t\tiframe.detach();\n\t\t}\n\n\t\t// Store the correct default display\n\t\telemdisplay[ nodeName ] = display;\n\t}\n\n\treturn display;\n}\n\n// Called ONLY from within css_defaultDisplay\nfunction actualDisplay( name, doc ) {\n\tvar elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),\n\t\tdisplay = jQuery.css( elem[0], \"display\" );\n\telem.remove();\n\treturn display;\n}\n\njQuery.each([ \"height\", \"width\" ], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\t\t\t\t// certain elements can have dimension info if we invisibly show them\n\t\t\t\t// however, it must have a current display style that would benefit from this\n\t\t\t\treturn elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, \"display\" ) ) ?\n\t\t\t\t\tjQuery.swap( elem, cssShow, function() {\n\t\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t\t}) :\n\t\t\t\t\tgetWidthOrHeight( elem, name, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar styles = extra && getStyles( elem );\n\t\t\treturn setPositiveNumber( elem, value, extra ?\n\t\t\t\taugmentWidthOrHeight(\n\t\t\t\t\telem,\n\t\t\t\t\tname,\n\t\t\t\t\textra,\n\t\t\t\t\tjQuery.support.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\t\tstyles\n\t\t\t\t) : 0\n\t\t\t);\n\t\t}\n\t};\n});\n\n// These hooks cannot be added until DOM ready because the support test\n// for it is not run until after DOM ready\njQuery(function() {\n\t// Support: Android 2.3\n\tif ( !jQuery.support.reliableMarginRight ) {\n\t\tjQuery.cssHooks.marginRight = {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\t\t\t\t\t// Support: Android 2.3\n\t\t\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\t\t\t// Work around by temporarily setting element display to inline-block\n\t\t\t\t\treturn jQuery.swap( elem, { \"display\": \"inline-block\" },\n\t\t\t\t\t\tcurCSS, [ elem, \"marginRight\" ] );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\t// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n\t// getComputedStyle returns percent when specified for top/left/bottom/right\n\t// rather than make the css module depend on the offset module, we just check for it here\n\tif ( !jQuery.support.pixelPosition && jQuery.fn.position ) {\n\t\tjQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\t\t\tjQuery.cssHooks[ prop ] = {\n\t\t\t\tget: function( elem, computed ) {\n\t\t\t\t\tif ( computed ) {\n\t\t\t\t\t\tcomputed = curCSS( elem, prop );\n\t\t\t\t\t\t// if curCSS returns percentage, fallback to offset\n\t\t\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\t\t\tcomputed;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t});\n\t}\n\n});\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n\tjQuery.expr.filters.hidden = function( elem ) {\n\t\t// Support: Opera <= 12.12\n\t\t// Opera reports offsetWidths and offsetHeights less than zero on some elements\n\t\treturn elem.offsetWidth <= 0 && elem.offsetHeight <= 0;\n\t};\n\n\tjQuery.expr.filters.visible = function( elem ) {\n\t\treturn !jQuery.expr.filters.hidden( elem );\n\t};\n}\n\n// These hooks are used by animate to expand properties\njQuery.each({\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split(\" \") : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( !rmargin.test( prefix ) ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n});\nvar r20 = /%20/g,\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\njQuery.fn.extend({\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map(function(){\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t})\n\t\t.filter(function(){\n\t\t\tvar type = this.type;\n\t\t\t// Use .is(\":disabled\") so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !manipulation_rcheckableType.test( type ) );\n\t\t})\n\t\t.map(function( i, elem ){\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val ){\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t}) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t}).get();\n\t}\n});\n\n//Serialize an array of form elements or a set of\n//key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, value ) {\n\t\t\t// If value is a function, invoke it and return its value\n\t\t\tvalue = jQuery.isFunction( value ) ? value() : ( value == null ? \"\" : value );\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n\t\t};\n\n\t// Set traditional to true for jQuery <= 1.3.2 behavior.\n\tif ( traditional === undefined ) {\n\t\ttraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t});\n\n\t} else {\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" ).replace( r20, \"+\" );\n};\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( jQuery.isArray( obj ) ) {\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams( prefix + \"[\" + ( typeof v === \"object\" ? i : \"\" ) + \"]\", v, traditional, add );\n\t\t\t}\n\t\t});\n\n\t} else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup error contextmenu\").split(\" \"), function( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n});\n\njQuery.fn.extend({\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t},\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ? this.off( selector, \"**\" ) : this.off( types, selector || \"**\", fn );\n\t}\n});\nvar\n\t// Document location\n\tajaxLocParts,\n\tajaxLocation,\n\n\tajax_nonce = jQuery.now(),\n\n\tajax_rquery = /\\?/,\n\trhash = /#.*$/,\n\trts = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\trurl = /^([\\w.+-]+:)(?:\\/\\/([^\\/?#:]*)(?::(\\d+)|)|)/,\n\n\t// Keep a copy of the old load method\n\t_load = jQuery.fn.load,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat(\"*\");\n\n// #8138, IE may throw an exception when accessing\n// a field from window.location if document.domain has been set\ntry {\n\tajaxLocation = location.href;\n} catch( e ) {\n\t// Use the href attribute of an A element\n\t// since IE will modify it given document.location\n\tajaxLocation = document.createElement( \"a\" );\n\tajaxLocation.href = \"\";\n\tajaxLocation = ajaxLocation.href;\n}\n\n// Segment location into parts\najaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( core_rnotwhite ) || [];\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( (dataType = dataTypes[i++]) ) {\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[0] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif( typeof dataTypeOrTransport === \"string\" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t});\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\njQuery.fn.load = function( url, params, callback ) {\n\tif ( typeof url !== \"string\" && _load ) {\n\t\treturn _load.apply( this, arguments );\n\t}\n\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf(\" \");\n\n\tif ( off >= 0 ) {\n\t\tselector = url.slice( off );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( jQuery.isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax({\n\t\t\turl: url,\n\n\t\t\t// if \"type\" variable is undefined, then \"GET\" method will be used\n\t\t\ttype: type,\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t}).done(function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery(\"<div>\").append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t}).complete( callback && function( jqXHR, status ) {\n\t\t\tself.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t});\n\t}\n\n\treturn this;\n};\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( [ \"ajaxStart\", \"ajaxStop\", \"ajaxComplete\", \"ajaxError\", \"ajaxSuccess\", \"ajaxSend\" ], function( i, type ){\n\tjQuery.fn[ type ] = function( fn ){\n\t\treturn this.on( type, fn );\n\t};\n});\n\njQuery.extend({\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: ajaxLocation,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /xml/,\n\t\t\thtml: /html/,\n\t\t\tjson: /json/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": jQuery.parseJSON,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\t\t\t// Cross-domain detection vars\n\t\t\tparts,\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\t\t\t// Loop variable\n\t\t\ti,\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\tjQuery.event,\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks(\"once memory\"),\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\t\t\t// The jqXHR state\n\t\t\tstate = 0,\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( state === 2 ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( (match = rheaders.exec( responseHeadersString )) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn state === 2 ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tvar lname = name.toLowerCase();\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\tname = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\t// Lazy-add the new callback in a way that preserves old ones\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR ).complete = completeDeferred.add;\n\t\tjqXHR.success = jqXHR.done;\n\t\tjqXHR.error = jqXHR.fail;\n\n\t\t// Remove hash character (#7531: and string promotion)\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || ajaxLocation ) + \"\" ).replace( rhash, \"\" )\n\t\t\t.replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().match( core_rnotwhite ) || [\"\"];\n\n\t\t// A cross-domain request is in order when we have a protocol:host:port mismatch\n\t\tif ( s.crossDomain == null ) {\n\t\t\tparts = rurl.exec( s.url.toLowerCase() );\n\t\t\ts.crossDomain = !!( parts &&\n\t\t\t\t( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||\n\t\t\t\t\t( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) !==\n\t\t\t\t\t\t( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) )\n\t\t\t);\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( state === 2 ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\tfireGlobals = s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger(\"ajaxStart\");\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\tcacheURL = s.url;\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// If data is available, append data to url\n\t\t\tif ( s.data ) {\n\t\t\t\tcacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data );\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add anti-cache in url if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\ts.url = rts.test( cacheURL ) ?\n\n\t\t\t\t\t// If there is already a '_' parameter, set its value\n\t\t\t\t\tcacheURL.replace( rts, \"$1_=\" + ajax_nonce++ ) :\n\n\t\t\t\t\t// Otherwise add one to the end\n\t\t\t\t\tcacheURL + ( ajax_rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ajax_nonce++;\n\t\t\t}\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tfor ( i in { success: 1, error: 1, complete: 1 } ) {\n\t\t\tjqXHR[ i ]( s[ i ] );\n\t\t}\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = setTimeout(function() {\n\t\t\t\t\tjqXHR.abort(\"timeout\");\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tstate = 1;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\t\t\t\t// Propagate exception as error if not done\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tdone( -1, e );\n\t\t\t\t// Simply rethrow otherwise\n\t\t\t\t} else {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Called once\n\t\t\tif ( state === 2 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// State is \"done\" now\n\t\t\tstate = 2;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\tclearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"Last-Modified\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"etag\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// We extract error from statusText\n\t\t\t\t// then normalize statusText and status for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger(\"ajaxStop\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n});\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\t\t// shift arguments if data argument was omitted\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\treturn jQuery.ajax({\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t});\n\t};\n});\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader(\"Content-Type\");\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s[ \"throws\" ] ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn { state: \"parsererror\", error: conv ? e : \"No conversion from \" + prev + \" to \" + current };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n// Install script dataType\njQuery.ajaxSetup({\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /(?:java|ecma)script/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n});\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n});\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery(\"<script>\").prop({\n\t\t\t\t\tasync: true,\n\t\t\t\t\tcharset: s.scriptCharset,\n\t\t\t\t\tsrc: s.url\n\t\t\t\t}).on(\n\t\t\t\t\t\"load error\",\n\t\t\t\t\tcallback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === \"error\" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n});\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup({\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( ajax_nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n});\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" && !( s.contentType || \"\" ).indexOf(\"application/x-www-form-urlencoded\") && rjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( ajax_rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[\"script json\"] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always(function() {\n\t\t\t// Restore preexisting value\n\t\t\twindow[ callbackName ] = overwritten;\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\t\t\t\t// make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && jQuery.isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t});\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n});\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new XMLHttpRequest();\n\t} catch( e ) {}\n};\n\nvar xhrSupported = jQuery.ajaxSettings.xhr(),\n\txhrSuccessStatus = {\n\t\t// file protocol always yields status code 0, assume 200\n\t\t0: 200,\n\t\t// Support: IE9\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\t// Support: IE9\n\t// We need to keep track of outbound xhr and abort them manually\n\t// because IE is not smart enough to do it all by itself\n\txhrId = 0,\n\txhrCallbacks = {};\n\nif ( window.ActiveXObject ) {\n\tjQuery( window ).on( \"unload\", function() {\n\t\tfor( var key in xhrCallbacks ) {\n\t\t\txhrCallbacks[ key ]();\n\t\t}\n\t\txhrCallbacks = undefined;\n\t});\n}\n\njQuery.support.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\njQuery.support.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport(function( options ) {\n\tvar callback;\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( jQuery.support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i, id,\n\t\t\t\t\txhr = options.xhr();\n\t\t\t\txhr.open( options.type, options.url, options.async, options.username, options.password );\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[\"X-Requested-With\"] ) {\n\t\t\t\t\theaders[\"X-Requested-With\"] = \"XMLHttpRequest\";\n\t\t\t\t}\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tdelete xhrCallbacks[ id ];\n\t\t\t\t\t\t\tcallback = xhr.onload = xhr.onerror = null;\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\t// file protocol always yields status 0, assume 404\n\t\t\t\t\t\t\t\t\txhr.status || 404,\n\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\t\t\t\t\t\t\t\t\t// Support: IE9\n\t\t\t\t\t\t\t\t\t// #11426: When requesting binary data, IE9 will throw an exception\n\t\t\t\t\t\t\t\t\t// on any attempt to access responseText\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText === \"string\" ? {\n\t\t\t\t\t\t\t\t\t\ttext: xhr.responseText\n\t\t\t\t\t\t\t\t\t} : undefined,\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\txhr.onerror = callback(\"error\");\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = xhrCallbacks[( id = xhrId++ )] = callback(\"abort\");\n\t\t\t\t// Do send the request\n\t\t\t\t// This may raise an exception which is actually\n\t\t\t\t// handled in jQuery.ajax (so no try/catch here)\n\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n});\nvar fxNow, timerId,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trfxnum = new RegExp( \"^(?:([+-])=|)(\" + core_pnum + \")([a-z%]*)$\", \"i\" ),\n\trrun = /queueHooks$/,\n\tanimationPrefilters = [ defaultPrefilter ],\n\ttweeners = {\n\t\t\"*\": [function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value ),\n\t\t\t\ttarget = tween.cur(),\n\t\t\t\tparts = rfxnum.exec( value ),\n\t\t\t\tunit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t\t\t// Starting value computation is required for potential unit mismatches\n\t\t\t\tstart = ( jQuery.cssNumber[ prop ] || unit !== \"px\" && +target ) &&\n\t\t\t\t\trfxnum.exec( jQuery.css( tween.elem, prop ) ),\n\t\t\t\tscale = 1,\n\t\t\t\tmaxIterations = 20;\n\n\t\t\tif ( start && start[ 3 ] !== unit ) {\n\t\t\t\t// Trust units reported by jQuery.css\n\t\t\t\tunit = unit || start[ 3 ];\n\n\t\t\t\t// Make sure we update the tween properties later on\n\t\t\t\tparts = parts || [];\n\n\t\t\t\t// Iteratively approximate from a nonzero starting point\n\t\t\t\tstart = +target || 1;\n\n\t\t\t\tdo {\n\t\t\t\t\t// If previous iteration zeroed out, double until we get *something*\n\t\t\t\t\t// Use a string for doubling factor so we don't accidentally see scale as unchanged below\n\t\t\t\t\tscale = scale || \".5\";\n\n\t\t\t\t\t// Adjust and apply\n\t\t\t\t\tstart = start / scale;\n\t\t\t\t\tjQuery.style( tween.elem, prop, start + unit );\n\n\t\t\t\t// Update scale, tolerating zero or NaN from tween.cur()\n\t\t\t\t// And breaking the loop if scale is unchanged or perfect, or if we've just had enough\n\t\t\t\t} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );\n\t\t\t}\n\n\t\t\t// Update tween properties\n\t\t\tif ( parts ) {\n\t\t\t\tstart = tween.start = +start || +target || 0;\n\t\t\t\ttween.unit = unit;\n\t\t\t\t// If a +=/-= token was provided, we're doing a relative animation\n\t\t\t\ttween.end = parts[ 1 ] ?\n\t\t\t\t\tstart + ( parts[ 1 ] + 1 ) * parts[ 2 ] :\n\t\t\t\t\t+parts[ 2 ];\n\t\t\t}\n\n\t\t\treturn tween;\n\t\t}]\n\t};\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\tsetTimeout(function() {\n\t\tfxNow = undefined;\n\t});\n\treturn ( fxNow = jQuery.now() );\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( tweeners[ prop ] || [] ).concat( tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( (tween = collection[ index ].call( animation, prop, value )) ) {\n\n\t\t\t// we're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = animationPrefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\t\t\t// don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t}),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\t\t\t\t// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ]);\n\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t} else {\n\t\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tanimation = deferred.promise({\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, { specialEasing: {} }, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\t\t\t\t\t// if we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// resolve when we played the last frame\n\t\t\t\t// otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length ; index++ ) {\n\t\tresult = animationPrefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( jQuery.isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t})\n\t);\n\n\t// attach callbacks from options\n\treturn animation.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = jQuery.camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( jQuery.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// not quite $.extend, this wont overwrite keys already present.\n\t\t\t// also - reusing 'index' from above because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweener: function( props, callback ) {\n\t\tif ( jQuery.isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.split(\" \");\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length ; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\ttweeners[ prop ] = tweeners[ prop ] || [];\n\t\t\ttweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tanimationPrefilters.unshift( callback );\n\t\t} else {\n\t\t\tanimationPrefilters.push( callback );\n\t\t}\n\t}\n});\n\nfunction defaultPrefilter( elem, props, opts ) {\n\t/* jshint validthis: true */\n\tvar prop, value, toggle, tween, hooks, oldfire,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHidden( elem ),\n\t\tdataShow = data_priv.get( elem, \"fxshow\" );\n\n\t// handle queue: false promises\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always(function() {\n\t\t\t// doing this makes sure that the complete handler will be called\n\t\t\t// before this completes\n\t\t\tanim.always(function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t// height/width overflow pass\n\tif ( elem.nodeType === 1 && ( \"height\" in props || \"width\" in props ) ) {\n\t\t// Make sure that nothing sneaks out\n\t\t// Record all 3 overflow attributes because IE9-10 do not\n\t\t// change the overflow attribute when overflowX and\n\t\t// overflowY are set to the same value\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Set display property to inline-block for height/width\n\t\t// animations on inline elements that are having width/height animated\n\t\tif ( jQuery.css( elem, \"display\" ) === \"inline\" &&\n\t\t\t\tjQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\tstyle.display = \"inline-block\";\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always(function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t});\n\t}\n\n\n\t// show/hide pass\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.exec( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\tif ( !jQuery.isEmptyObject( orig ) ) {\n\t\tif ( dataShow ) {\n\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\thidden = dataShow.hidden;\n\t\t\t}\n\t\t} else {\n\t\t\tdataShow = data_priv.access( elem, \"fxshow\", {} );\n\t\t}\n\n\t\t// store state if its toggle - enables .stop().toggle() to \"reverse\"\n\t\tif ( toggle ) {\n\t\t\tdataShow.hidden = !hidden;\n\t\t}\n\t\tif ( hidden ) {\n\t\t\tjQuery( elem ).show();\n\t\t} else {\n\t\t\tanim.done(function() {\n\t\t\t\tjQuery( elem ).hide();\n\t\t\t});\n\t\t}\n\t\tanim.done(function() {\n\t\t\tvar prop;\n\n\t\t\tdata_priv.remove( elem, \"fxshow\" );\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t}\n\t\t});\n\t\tfor ( prop in orig ) {\n\t\t\ttween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\n\t\t\tif ( !( prop in dataShow ) ) {\n\t\t\t\tdataShow[ prop ] = tween.start;\n\t\t\t\tif ( hidden ) {\n\t\t\t\t\ttween.end = tween.start;\n\t\t\t\t\ttween.start = prop === \"width\" || prop === \"height\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || \"swing\";\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\tif ( tween.elem[ tween.prop ] != null &&\n\t\t\t\t(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails\n\t\t\t// so, simple values such as \"10px\" are parsed to Float.\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\t\t\t// use step hook for back compat - use cssHook if its there - use .style if its\n\t\t\t// available and use plain properties where available\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE9\n// Panic based approach to setting things on disconnected nodes\n\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.each([ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n});\n\njQuery.fn.extend({\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHidden ).css( \"opacity\", 0 ).show()\n\n\t\t\t// animate to the value specified\n\t\t\t.end().animate({ opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || data_priv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = data_priv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// start the next in the queue if the last step wasn't forced\n\t\t\t// timers currently will call their complete callbacks, which will dequeue\n\t\t\t// but only if they were gotoEnd\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t});\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tvar index,\n\t\t\t\tdata = data_priv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t});\n\t}\n});\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\tattrs = { height: type },\n\t\ti = 0;\n\n\t// if we include width, step value is 1 to do all cssExpand values,\n\t// if we don't include width, step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth? 1 : 0;\n\tfor( ; i < 4 ; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\n// Generate shortcuts for custom animations\njQuery.each({\n\tslideDown: genFx(\"show\"),\n\tslideUp: genFx(\"hide\"),\n\tslideToggle: genFx(\"toggle\"),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n});\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tjQuery.isFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n\t};\n\n\topt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n\t\topt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\n\t// normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p*Math.PI ) / 2;\n\t}\n};\n\njQuery.timers = [];\njQuery.fx = Tween.prototype.init;\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ttimers = jQuery.timers,\n\t\ti = 0;\n\n\tfxNow = jQuery.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\t\t// Checks the timer has not already been removed\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tif ( timer() && jQuery.timers.push( timer ) ) {\n\t\tjQuery.fx.start();\n\t}\n};\n\njQuery.fx.interval = 13;\n\njQuery.fx.start = function() {\n\tif ( !timerId ) {\n\t\ttimerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );\n\t}\n};\n\njQuery.fx.stop = function() {\n\tclearInterval( timerId );\n\ttimerId = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\t// Default speed\n\t_default: 400\n};\n\n// Back Compat <1.8 extension point\njQuery.fx.step = {};\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n\tjQuery.expr.filters.animated = function( elem ) {\n\t\treturn jQuery.grep(jQuery.timers, function( fn ) {\n\t\t\treturn elem === fn.elem;\n\t\t}).length;\n\t};\n}\njQuery.fn.offset = function( options ) {\n\tif ( arguments.length ) {\n\t\treturn options === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function( i ) {\n\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t});\n\t}\n\n\tvar docElem, win,\n\t\telem = this[ 0 ],\n\t\tbox = { top: 0, left: 0 },\n\t\tdoc = elem && elem.ownerDocument;\n\n\tif ( !doc ) {\n\t\treturn;\n\t}\n\n\tdocElem = doc.documentElement;\n\n\t// Make sure it's not a disconnected DOM node\n\tif ( !jQuery.contains( docElem, elem ) ) {\n\t\treturn box;\n\t}\n\n\t// If we don't have gBCR, just use 0,0 rather than error\n\t// BlackBerry 5, iOS 3 (original iPhone)\n\tif ( typeof elem.getBoundingClientRect !== core_strundefined ) {\n\t\tbox = elem.getBoundingClientRect();\n\t}\n\twin = getWindow( doc );\n\treturn {\n\t\ttop: box.top + win.pageYOffset - docElem.clientTop,\n\t\tleft: box.left + win.pageXOffset - docElem.clientLeft\n\t};\n};\n\njQuery.offset = {\n\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) && ( curCSSTop + curCSSLeft ).indexOf(\"auto\") > -1;\n\n\t\t// Need to be able to calculate position if either top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\t\t\toptions = options.call( elem, i, curOffset );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\n\njQuery.fn.extend({\n\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\t\t\t// We assume that getBoundingClientRect is available when computed position is fixed\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\t\t\t// Get *real* offsetParent\n\t\t\toffsetParent = this.offsetParent();\n\n\t\t\t// Get correct offsets\n\t\t\toffset = this.offset();\n\t\t\tif ( !jQuery.nodeName( offsetParent[ 0 ], \"html\" ) ) {\n\t\t\t\tparentOffset = offsetParent.offset();\n\t\t\t}\n\n\t\t\t// Add offsetParent borders\n\t\t\tparentOffset.top += jQuery.css( offsetParent[ 0 ], \"borderTopWidth\", true );\n\t\t\tparentOffset.left += jQuery.css( offsetParent[ 0 ], \"borderLeftWidth\", true );\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true )\n\t\t};\n\t},\n\n\toffsetParent: function() {\n\t\treturn this.map(function() {\n\t\t\tvar offsetParent = this.offsetParent || docElem;\n\n\t\t\twhile ( offsetParent && ( !jQuery.nodeName( offsetParent, \"html\" ) && jQuery.css( offsetParent, \"position\") === \"static\" ) ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || docElem;\n\t\t});\n\t}\n});\n\n\n// Create scrollLeft and scrollTop methods\njQuery.each( {scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\"}, function( method, prop ) {\n\tvar top = \"pageYOffset\" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn jQuery.access( this, function( elem, method, val ) {\n\t\t\tvar win = getWindow( elem );\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : window.pageXOffset,\n\t\t\t\t\ttop ? val : window.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length, null );\n\t};\n});\n\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;\n}\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name }, function( defaultExtra, funcName ) {\n\t\t// margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn jQuery.access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( jQuery.isWindow( elem ) ) {\n\t\t\t\t\t// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there\n\t\t\t\t\t// isn't a whole lot we can do. See pull request at this URL for discussion:\n\t\t\t\t\t// https://github.com/jquery/jquery/pull/764\n\t\t\t\t\treturn elem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable, null );\n\t\t};\n\t});\n});\n// Limit scope pollution from any deprecated API\n// (function() {\n\n// The number of elements contained in the matched element set\njQuery.fn.size = function() {\n\treturn this.length;\n};\n\njQuery.fn.andSelf = jQuery.fn.addBack;\n\n// })();\nif ( typeof module === \"object\" && module && typeof module.exports === \"object\" ) {\n\t// Expose jQuery as module.exports in loaders that implement the Node\n\t// module pattern (including browserify). Do not create the global, since\n\t// the user will be storing it themselves locally, and globals are frowned\n\t// upon in the Node module world.\n\tmodule.exports = jQuery;\n} else {\n\t// Register as a named AMD module, since jQuery can be concatenated with other\n\t// files that may use define, but not via a proper concatenation script that\n\t// understands anonymous AMD modules. A named AMD is safest and most robust\n\t// way to register. Lowercase jquery is used because AMD module names are\n\t// derived from file names, and jQuery is normally delivered in a lowercase\n\t// file name. Do this after creating the global so that if an AMD module wants\n\t// to call noConflict to hide this version of jQuery, it will work.\n\tif ( typeof define === \"function\" && define.amd ) {\n\t\tdefine( \"jquery\", [], function () { return jQuery; } );\n\t}\n}\n\n// If there is a window object, that at least has a document property,\n// define jQuery and $ identifiers\nif ( typeof window === \"object\" && typeof window.document === \"object\" ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n})( window );\n"
  },
  {
    "path": "docs/editor/scripts/parser.js",
    "content": "/*\n  Copyright (C) 2013 Ariya Hidayat <ariya.hidayat@gmail.com>\n  Copyright (C) 2013 Thaddee Tyl <thaddee.tyl@gmail.com>\n  Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>\n  Copyright (C) 2012 Mathias Bynens <mathias@qiwi.be>\n  Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>\n  Copyright (C) 2012 Kris Kowal <kris.kowal@cixar.com>\n  Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>\n  Copyright (C) 2012 Arpad Borsos <arpad.borsos@googlemail.com>\n  Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>\n\n  Redistribution and use in source and binary forms, with or without\n  modification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\n  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n/*global esprima:true, define:true, exports:true, window: true,\nthrowError: true, generateStatement: true, peek: true,\nparseAssignmentExpression: true, parseBlock: true,\nparseClassExpression: true, parseClassDeclaration: true, parseExpression: true,\nparseForStatement: true,\nparseFunctionDeclaration: true, parseFunctionExpression: true,\nparseFunctionSourceElements: true, parseVariableIdentifier: true,\nparseImportSpecifier: true,\nparseLeftHandSideExpression: true, parseParams: true, validateParam: true,\nparseSpreadOrAssignmentExpression: true,\nparseStatement: true, parseSourceElement: true, parseModuleBlock: true, parseConciseBody: true,\nparseYieldExpression: true\n*/\n(function (root, factory) {\n    'use strict';\n    // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,\n    // Rhino, and plain browser loading.\n    if (typeof define === 'function' && define.amd) {\n        define([\n            'exports',\n            'expander'\n        ], factory);\n    } else if (typeof exports !== 'undefined') {\n        factory(exports, require('./expander'));\n    } else {\n        factory(root.esprima = {});\n    }\n}(this, function (exports$2, expander) {\n    'use strict';\n    var Token, TokenName, FnExprTokens, Syntax, PropertyKind, Messages, Regex, SyntaxTreeDelegate, ClassPropertyType, source, strict, index, lineNumber, lineStart, sm_lineNumber, sm_lineStart, sm_range, sm_index, length, delegate, tokenStream, streamIndex, lookahead, lookaheadIndex, state, extra;\n    Token = {\n        BooleanLiteral: 1,\n        EOF: 2,\n        Identifier: 3,\n        Keyword: 4,\n        NullLiteral: 5,\n        NumericLiteral: 6,\n        Punctuator: 7,\n        StringLiteral: 8,\n        RegularExpression: 9,\n        Template: 10,\n        Delimiter: 11\n    };\n    TokenName = {};\n    TokenName[Token.BooleanLiteral] = 'Boolean';\n    TokenName[Token.EOF] = '<end>';\n    TokenName[Token.Identifier] = 'Identifier';\n    TokenName[Token.Keyword] = 'Keyword';\n    TokenName[Token.NullLiteral] = 'Null';\n    TokenName[Token.NumericLiteral] = 'Numeric';\n    TokenName[Token.Punctuator] = 'Punctuator';\n    TokenName[Token.StringLiteral] = 'String';\n    TokenName[Token.RegularExpression] = 'RegularExpression';\n    TokenName[Token.Delimiter] = 'Delimiter';\n    // A function following one of those tokens is an expression.\n    FnExprTokens = [\n        '(',\n        '{',\n        '[',\n        'in',\n        'typeof',\n        'instanceof',\n        'new',\n        'return',\n        'case',\n        'delete',\n        'throw',\n        'void',\n        '=',\n        '+=',\n        '-=',\n        '*=',\n        '/=',\n        '%=',\n        '<<=',\n        '>>=',\n        '>>>=',\n        '&=',\n        '|=',\n        '^=',\n        ',',\n        '+',\n        '-',\n        '*',\n        '/',\n        '%',\n        '++',\n        '--',\n        '<<',\n        '>>',\n        '>>>',\n        '&',\n        '|',\n        '^',\n        '!',\n        '~',\n        '&&',\n        '||',\n        '?',\n        ':',\n        '===',\n        '==',\n        '>=',\n        '<=',\n        '<',\n        '>',\n        '!=',\n        '!=='\n    ];\n    Syntax = {\n        ArrayExpression: 'ArrayExpression',\n        ArrayPattern: 'ArrayPattern',\n        ArrowFunctionExpression: 'ArrowFunctionExpression',\n        AssignmentExpression: 'AssignmentExpression',\n        BinaryExpression: 'BinaryExpression',\n        BlockStatement: 'BlockStatement',\n        BreakStatement: 'BreakStatement',\n        CallExpression: 'CallExpression',\n        CatchClause: 'CatchClause',\n        ClassBody: 'ClassBody',\n        ClassDeclaration: 'ClassDeclaration',\n        ClassExpression: 'ClassExpression',\n        ClassHeritage: 'ClassHeritage',\n        ComprehensionBlock: 'ComprehensionBlock',\n        ComprehensionExpression: 'ComprehensionExpression',\n        ConditionalExpression: 'ConditionalExpression',\n        ContinueStatement: 'ContinueStatement',\n        DebuggerStatement: 'DebuggerStatement',\n        DoWhileStatement: 'DoWhileStatement',\n        EmptyStatement: 'EmptyStatement',\n        ExportDeclaration: 'ExportDeclaration',\n        ExportBatchSpecifier: 'ExportBatchSpecifier',\n        ExportSpecifier: 'ExportSpecifier',\n        ExpressionStatement: 'ExpressionStatement',\n        ForInStatement: 'ForInStatement',\n        ForOfStatement: 'ForOfStatement',\n        ForStatement: 'ForStatement',\n        FunctionDeclaration: 'FunctionDeclaration',\n        FunctionExpression: 'FunctionExpression',\n        Identifier: 'Identifier',\n        IfStatement: 'IfStatement',\n        ImportDeclaration: 'ImportDeclaration',\n        ImportSpecifier: 'ImportSpecifier',\n        LabeledStatement: 'LabeledStatement',\n        Literal: 'Literal',\n        LogicalExpression: 'LogicalExpression',\n        MemberExpression: 'MemberExpression',\n        MethodDefinition: 'MethodDefinition',\n        ModuleDeclaration: 'ModuleDeclaration',\n        NewExpression: 'NewExpression',\n        ObjectExpression: 'ObjectExpression',\n        ObjectPattern: 'ObjectPattern',\n        Program: 'Program',\n        Property: 'Property',\n        ReturnStatement: 'ReturnStatement',\n        SequenceExpression: 'SequenceExpression',\n        SpreadElement: 'SpreadElement',\n        SwitchCase: 'SwitchCase',\n        SwitchStatement: 'SwitchStatement',\n        TaggedTemplateExpression: 'TaggedTemplateExpression',\n        TemplateElement: 'TemplateElement',\n        TemplateLiteral: 'TemplateLiteral',\n        ThisExpression: 'ThisExpression',\n        ThrowStatement: 'ThrowStatement',\n        TryStatement: 'TryStatement',\n        UnaryExpression: 'UnaryExpression',\n        UpdateExpression: 'UpdateExpression',\n        VariableDeclaration: 'VariableDeclaration',\n        VariableDeclarator: 'VariableDeclarator',\n        WhileStatement: 'WhileStatement',\n        WithStatement: 'WithStatement',\n        YieldExpression: 'YieldExpression'\n    };\n    PropertyKind = {\n        Data: 1,\n        Get: 2,\n        Set: 4\n    };\n    ClassPropertyType = {\n        'static': 'static',\n        prototype: 'prototype'\n    };\n    // Error messages should be identical to V8.\n    Messages = {\n        UnexpectedToken: 'Unexpected token %0',\n        UnexpectedNumber: 'Unexpected number',\n        UnexpectedString: 'Unexpected string',\n        UnexpectedIdentifier: 'Unexpected identifier',\n        UnexpectedReserved: 'Unexpected reserved word',\n        UnexpectedTemplate: 'Unexpected quasi %0',\n        UnexpectedEOS: 'Unexpected end of input',\n        NewlineAfterThrow: 'Illegal newline after throw',\n        InvalidRegExp: 'Invalid regular expression',\n        UnterminatedRegExp: 'Invalid regular expression: missing /',\n        InvalidLHSInAssignment: 'Invalid left-hand side in assignment',\n        InvalidLHSInFormalsList: 'Invalid left-hand side in formals list',\n        InvalidLHSInForIn: 'Invalid left-hand side in for-in',\n        MultipleDefaultsInSwitch: 'More than one default clause in switch statement',\n        NoCatchOrFinally: 'Missing catch or finally after try',\n        UnknownLabel: 'Undefined label \\'%0\\'',\n        Redeclaration: '%0 \\'%1\\' has already been declared',\n        IllegalContinue: 'Illegal continue statement',\n        IllegalBreak: 'Illegal break statement',\n        IllegalDuplicateClassProperty: 'Illegal duplicate property in class definition',\n        IllegalReturn: 'Illegal return statement',\n        IllegalYield: 'Illegal yield expression',\n        IllegalSpread: 'Illegal spread element',\n        StrictModeWith: 'Strict mode code may not include a with statement',\n        StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode',\n        StrictVarName: 'Variable name may not be eval or arguments in strict mode',\n        StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',\n        StrictParamDupe: 'Strict mode function may not have duplicate parameter names',\n        ParameterAfterRestParameter: 'Rest parameter must be final parameter of an argument list',\n        DefaultRestParameter: 'Rest parameter can not have a default value',\n        ElementAfterSpreadElement: 'Spread must be the final element of an element list',\n        ObjectPatternAsRestParameter: 'Invalid rest parameter',\n        ObjectPatternAsSpread: 'Invalid spread argument',\n        StrictFunctionName: 'Function name may not be eval or arguments in strict mode',\n        StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',\n        StrictDelete: 'Delete of an unqualified identifier in strict mode.',\n        StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode',\n        AccessorDataProperty: 'Object literal may not have data and accessor property with the same name',\n        AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name',\n        StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode',\n        StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode',\n        StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',\n        StrictReservedWord: 'Use of future reserved word in strict mode',\n        NewlineAfterModule: 'Illegal newline after module',\n        NoFromAfterImport: 'Missing from after import',\n        InvalidModuleSpecifier: 'Invalid module specifier',\n        NestedModule: 'Module declaration can not be nested',\n        NoYieldInGenerator: 'Missing yield in generator',\n        NoUnintializedConst: 'Const must be initialized',\n        ComprehensionRequiresBlock: 'Comprehension must have at least one block',\n        ComprehensionError: 'Comprehension Error',\n        EachNotAllowed: 'Each is not supported',\n        UnmatchedDelimiter: 'Unmatched Delimiter'\n    };\n    // See also tools/generate-unicode-regex.py.\n    Regex = {\n        NonAsciiIdentifierStart: new RegExp('[\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u0527\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u08A0\\u08A2-\\u08AC\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0977\\u0979-\\u097F\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F0\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191C\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1CF5\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA697\\uA6A0-\\uA6EF\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA793\\uA7A0-\\uA7AA\\uA7F8-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA80-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uABC0-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]'),\n        NonAsciiIdentifierPart: new RegExp('[\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0300-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u0483-\\u0487\\u048A-\\u0527\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0610-\\u061A\\u0620-\\u0669\\u066E-\\u06D3\\u06D5-\\u06DC\\u06DF-\\u06E8\\u06EA-\\u06FC\\u06FF\\u0710-\\u074A\\u074D-\\u07B1\\u07C0-\\u07F5\\u07FA\\u0800-\\u082D\\u0840-\\u085B\\u08A0\\u08A2-\\u08AC\\u08E4-\\u08FE\\u0900-\\u0963\\u0966-\\u096F\\u0971-\\u0977\\u0979-\\u097F\\u0981-\\u0983\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BC-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CE\\u09D7\\u09DC\\u09DD\\u09DF-\\u09E3\\u09E6-\\u09F1\\u0A01-\\u0A03\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A59-\\u0A5C\\u0A5E\\u0A66-\\u0A75\\u0A81-\\u0A83\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABC-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0AD0\\u0AE0-\\u0AE3\\u0AE6-\\u0AEF\\u0B01-\\u0B03\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3C-\\u0B44\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B5C\\u0B5D\\u0B5F-\\u0B63\\u0B66-\\u0B6F\\u0B71\\u0B82\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD0\\u0BD7\\u0BE6-\\u0BEF\\u0C01-\\u0C03\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C58\\u0C59\\u0C60-\\u0C63\\u0C66-\\u0C6F\\u0C82\\u0C83\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBC-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0CDE\\u0CE0-\\u0CE3\\u0CE6-\\u0CEF\\u0CF1\\u0CF2\\u0D02\\u0D03\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D-\\u0D44\\u0D46-\\u0D48\\u0D4A-\\u0D4E\\u0D57\\u0D60-\\u0D63\\u0D66-\\u0D6F\\u0D7A-\\u0D7F\\u0D82\\u0D83\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0DCA\\u0DCF-\\u0DD4\\u0DD6\\u0DD8-\\u0DDF\\u0DF2\\u0DF3\\u0E01-\\u0E3A\\u0E40-\\u0E4E\\u0E50-\\u0E59\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB9\\u0EBB-\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EC8-\\u0ECD\\u0ED0-\\u0ED9\\u0EDC-\\u0EDF\\u0F00\\u0F18\\u0F19\\u0F20-\\u0F29\\u0F35\\u0F37\\u0F39\\u0F3E-\\u0F47\\u0F49-\\u0F6C\\u0F71-\\u0F84\\u0F86-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u1000-\\u1049\\u1050-\\u109D\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u135D-\\u135F\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F0\\u1700-\\u170C\\u170E-\\u1714\\u1720-\\u1734\\u1740-\\u1753\\u1760-\\u176C\\u176E-\\u1770\\u1772\\u1773\\u1780-\\u17D3\\u17D7\\u17DC\\u17DD\\u17E0-\\u17E9\\u180B-\\u180D\\u1810-\\u1819\\u1820-\\u1877\\u1880-\\u18AA\\u18B0-\\u18F5\\u1900-\\u191C\\u1920-\\u192B\\u1930-\\u193B\\u1946-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u19D0-\\u19D9\\u1A00-\\u1A1B\\u1A20-\\u1A5E\\u1A60-\\u1A7C\\u1A7F-\\u1A89\\u1A90-\\u1A99\\u1AA7\\u1B00-\\u1B4B\\u1B50-\\u1B59\\u1B6B-\\u1B73\\u1B80-\\u1BF3\\u1C00-\\u1C37\\u1C40-\\u1C49\\u1C4D-\\u1C7D\\u1CD0-\\u1CD2\\u1CD4-\\u1CF6\\u1D00-\\u1DE6\\u1DFC-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u200C\\u200D\\u203F\\u2040\\u2054\\u2071\\u207F\\u2090-\\u209C\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D7F-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2DE0-\\u2DFF\\u2E2F\\u3005-\\u3007\\u3021-\\u302F\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u3099\\u309A\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA62B\\uA640-\\uA66F\\uA674-\\uA67D\\uA67F-\\uA697\\uA69F-\\uA6F1\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA793\\uA7A0-\\uA7AA\\uA7F8-\\uA827\\uA840-\\uA873\\uA880-\\uA8C4\\uA8D0-\\uA8D9\\uA8E0-\\uA8F7\\uA8FB\\uA900-\\uA92D\\uA930-\\uA953\\uA960-\\uA97C\\uA980-\\uA9C0\\uA9CF-\\uA9D9\\uAA00-\\uAA36\\uAA40-\\uAA4D\\uAA50-\\uAA59\\uAA60-\\uAA76\\uAA7A\\uAA7B\\uAA80-\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEF\\uAAF2-\\uAAF6\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uABC0-\\uABEA\\uABEC\\uABED\\uABF0-\\uABF9\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE00-\\uFE0F\\uFE20-\\uFE26\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF10-\\uFF19\\uFF21-\\uFF3A\\uFF3F\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]')\n    };\n    // Ensure the condition is true, otherwise throw an error.\n    // This is only to have a better contract semantic, i.e. another safety net\n    // to catch a logic error. The condition shall be fulfilled in normal case.\n    // Do NOT use this to enforce a certain condition on any user input.\n    function assert(condition, message) {\n        if (!condition) {\n            throw new Error('ASSERT: ' + message);\n        }\n    }\n    function isIn(el, list) {\n        return list.indexOf(el) !== -1;\n    }\n    function isDecimalDigit(ch) {\n        return ch >= 48 && ch <= 57;\n    }    // 0..9\n    function isHexDigit(ch) {\n        return '0123456789abcdefABCDEF'.indexOf(ch) >= 0;\n    }\n    function isOctalDigit(ch) {\n        return '01234567'.indexOf(ch) >= 0;\n    }\n    // 7.2 White Space\n    function isWhiteSpace(ch) {\n        return ch === 32 || ch === 9 || ch === 11 || ch === 12 || ch === 160 || ch >= 5760 && '\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\uFEFF'.indexOf(String.fromCharCode(ch)) > 0;\n    }\n    // 7.3 Line Terminators\n    function isLineTerminator(ch) {\n        return ch === 10 || ch === 13 || ch === 8232 || ch === 8233;\n    }\n    // 7.6 Identifier Names and Identifiers\n    function isIdentifierStart(ch) {\n        return ch === 36 || ch === 95 || ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122 || ch === 92 || ch >= 128 && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch));\n    }\n    function isIdentifierPart(ch) {\n        return ch === 36 || ch === 95 || ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122 || ch >= 48 && ch <= 57 || ch === 92 || ch >= 128 && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch));\n    }\n    // 7.6.1.2 Future Reserved Words\n    function isFutureReservedWord(id) {\n        switch (id) {\n        case 'class':\n        case 'enum':\n        case 'export':\n        case 'extends':\n        case 'import':\n        case 'super':\n            return true;\n        default:\n            return false;\n        }\n    }\n    function isStrictModeReservedWord(id) {\n        switch (id) {\n        case 'implements':\n        case 'interface':\n        case 'package':\n        case 'private':\n        case 'protected':\n        case 'public':\n        case 'static':\n        case 'yield':\n        case 'let':\n            return true;\n        default:\n            return false;\n        }\n    }\n    function isRestrictedWord(id) {\n        return id === 'eval' || id === 'arguments';\n    }\n    // 7.6.1.1 Keywords\n    function isKeyword(id) {\n        if (strict && isStrictModeReservedWord(id)) {\n            return true;\n        }\n        // 'const' is specialized as Keyword in V8.\n        // 'yield' and 'let' are for compatiblity with SpiderMonkey and ES.next.\n        // Some others are from future reserved words.\n        switch (id.length) {\n        case 2:\n            return id === 'if' || id === 'in' || id === 'do';\n        case 3:\n            return id === 'var' || id === 'for' || id === 'new' || id === 'try' || id === 'let';\n        case 4:\n            return id === 'this' || id === 'else' || id === 'case' || id === 'void' || id === 'with' || id === 'enum';\n        case 5:\n            return id === 'while' || id === 'break' || id === 'catch' || id === 'throw' || id === 'const' || id === 'yield' || id === 'class' || id === 'super';\n        case 6:\n            return id === 'return' || id === 'typeof' || id === 'delete' || id === 'switch' || id === 'export' || id === 'import';\n        case 7:\n            return id === 'default' || id === 'finally' || id === 'extends';\n        case 8:\n            return id === 'function' || id === 'continue' || id === 'debugger';\n        case 10:\n            return id === 'instanceof';\n        default:\n            return false;\n        }\n    }\n    // 7.4 Comments\n    function skipComment() {\n        var ch, blockComment, lineComment;\n        blockComment = false;\n        lineComment = false;\n        while (index < length) {\n            ch = source.charCodeAt(index);\n            if (lineComment) {\n                ++index;\n                if (isLineTerminator(ch)) {\n                    lineComment = false;\n                    if (ch === 13 && source.charCodeAt(index) === 10) {\n                        ++index;\n                    }\n                    ++lineNumber;\n                    lineStart = index;\n                }\n            } else if (blockComment) {\n                if (isLineTerminator(ch)) {\n                    if (ch === 13 && source.charCodeAt(index + 1) === 10) {\n                        ++index;\n                    }\n                    ++lineNumber;\n                    ++index;\n                    lineStart = index;\n                    if (index >= length) {\n                        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n                    }\n                } else {\n                    ch = source.charCodeAt(index++);\n                    if (index >= length) {\n                        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n                    }\n                    // Block comment ends with '*/' (char #42, char #47).\n                    if (ch === 42) {\n                        ch = source.charCodeAt(index);\n                        if (ch === 47) {\n                            ++index;\n                            blockComment = false;\n                        }\n                    }\n                }\n            } else if (ch === 47) {\n                ch = source.charCodeAt(index + 1);\n                // Line comment starts with '//' (char #47, char #47).\n                if (ch === 47) {\n                    index += 2;\n                    lineComment = true;\n                } else if (ch === 42) {\n                    // Block comment starts with '/*' (char #47, char #42).\n                    index += 2;\n                    blockComment = true;\n                    if (index >= length) {\n                        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n                    }\n                } else {\n                    break;\n                }\n            } else if (isWhiteSpace(ch)) {\n                ++index;\n            } else if (isLineTerminator(ch)) {\n                ++index;\n                if (ch === 13 && source.charCodeAt(index) === 10) {\n                    ++index;\n                }\n                ++lineNumber;\n                lineStart = index;\n            } else {\n                break;\n            }\n        }\n    }\n    function scanHexEscape(prefix) {\n        var i, len, ch, code = 0;\n        len = prefix === 'u' ? 4 : 2;\n        for (i = 0; i < len; ++i) {\n            if (index < length && isHexDigit(source[index])) {\n                ch = source[index++];\n                code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());\n            } else {\n                return '';\n            }\n        }\n        return String.fromCharCode(code);\n    }\n    function scanUnicodeCodePointEscape() {\n        var ch, code, cu1, cu2;\n        ch = source[index];\n        code = 0;\n        // At least, one hex digit is required.\n        if (ch === '}') {\n            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n        }\n        while (index < length) {\n            ch = source[index++];\n            if (!isHexDigit(ch)) {\n                break;\n            }\n            code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());\n        }\n        if (code > 1114111 || ch !== '}') {\n            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n        }\n        // UTF-16 Encoding\n        if (code <= 65535) {\n            return String.fromCharCode(code);\n        }\n        cu1 = (code - 65536 >> 10) + 55296;\n        cu2 = (code - 65536 & 1023) + 56320;\n        return String.fromCharCode(cu1, cu2);\n    }\n    function getEscapedIdentifier() {\n        var ch, id;\n        ch = source.charCodeAt(index++);\n        id = String.fromCharCode(ch);\n        // '\\u' (char #92, char #117) denotes an escaped character.\n        if (ch === 92) {\n            if (source.charCodeAt(index) !== 117) {\n                throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n            }\n            ++index;\n            ch = scanHexEscape('u');\n            if (!ch || ch === '\\\\' || !isIdentifierStart(ch.charCodeAt(0))) {\n                throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n            }\n            id = ch;\n        }\n        while (index < length) {\n            ch = source.charCodeAt(index);\n            if (!isIdentifierPart(ch)) {\n                break;\n            }\n            ++index;\n            id += String.fromCharCode(ch);\n            // '\\u' (char #92, char #117) denotes an escaped character.\n            if (ch === 92) {\n                id = id.substr(0, id.length - 1);\n                if (source.charCodeAt(index) !== 117) {\n                    throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n                }\n                ++index;\n                ch = scanHexEscape('u');\n                if (!ch || ch === '\\\\' || !isIdentifierPart(ch.charCodeAt(0))) {\n                    throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n                }\n                id += ch;\n            }\n        }\n        return id;\n    }\n    function getIdentifier() {\n        var start, ch;\n        start = index++;\n        while (index < length) {\n            ch = source.charCodeAt(index);\n            if (ch === 92) {\n                // Blackslash (char #92) marks Unicode escape sequence.\n                index = start;\n                return getEscapedIdentifier();\n            }\n            if (isIdentifierPart(ch)) {\n                ++index;\n            } else {\n                break;\n            }\n        }\n        return source.slice(start, index);\n    }\n    function scanIdentifier() {\n        var start, id, type;\n        start = index;\n        // Backslash (char #92) starts an escaped character.\n        id = source.charCodeAt(index) === 92 ? getEscapedIdentifier() : getIdentifier();\n        // There is no keyword or literal with only one character.\n        // Thus, it must be an identifier.\n        if (id.length === 1) {\n            type = Token.Identifier;\n        } else if (isKeyword(id)) {\n            type = Token.Keyword;\n        } else if (id === 'null') {\n            type = Token.NullLiteral;\n        } else if (id === 'true' || id === 'false') {\n            type = Token.BooleanLiteral;\n        } else {\n            type = Token.Identifier;\n        }\n        return {\n            type: type,\n            value: id,\n            lineNumber: lineNumber,\n            lineStart: lineStart,\n            range: [\n                start,\n                index\n            ]\n        };\n    }\n    // 7.7 Punctuators\n    function scanPunctuator() {\n        var start = index, code = source.charCodeAt(index), code2, ch1 = source[index], ch2, ch3, ch4;\n        switch (code) {\n        // Check for most common single-character punctuators.\n        case 40:\n        // ( open bracket\n        case 41:\n        // ) close bracket\n        case 59:\n        // ; semicolon\n        case 44:\n        // , comma\n        case 123:\n        // { open curly brace\n        case 125:\n        // } close curly brace\n        case 91:\n        // [\n        case 93:\n        // ]\n        case 58:\n        // :\n        case 63:\n        // ?\n        case 126:\n            // ~\n            ++index;\n            if (extra.tokenize) {\n                if (code === 40) {\n                    extra.openParenToken = extra.tokens.length;\n                } else if (code === 123) {\n                    extra.openCurlyToken = extra.tokens.length;\n                }\n            }\n            return {\n                type: Token.Punctuator,\n                value: String.fromCharCode(code),\n                lineNumber: lineNumber,\n                lineStart: lineStart,\n                range: [\n                    start,\n                    index\n                ]\n            };\n        default:\n            code2 = source.charCodeAt(index + 1);\n            // '=' (char #61) marks an assignment or comparison operator.\n            if (code2 === 61) {\n                switch (code) {\n                case 37:\n                // %\n                case 38:\n                // &\n                case 42:\n                // *:\n                case 43:\n                // +\n                case 45:\n                // -\n                case 47:\n                // /\n                case 60:\n                // <\n                case 62:\n                // >\n                case 94:\n                // ^\n                case 124:\n                    // |\n                    index += 2;\n                    return {\n                        type: Token.Punctuator,\n                        value: String.fromCharCode(code) + String.fromCharCode(code2),\n                        lineNumber: lineNumber,\n                        lineStart: lineStart,\n                        range: [\n                            start,\n                            index\n                        ]\n                    };\n                case 33:\n                // !\n                case 61:\n                    // =\n                    index += 2;\n                    // !== and ===\n                    if (source.charCodeAt(index) === 61) {\n                        ++index;\n                    }\n                    return {\n                        type: Token.Punctuator,\n                        value: source.slice(start, index),\n                        lineNumber: lineNumber,\n                        lineStart: lineStart,\n                        range: [\n                            start,\n                            index\n                        ]\n                    };\n                default:\n                    break;\n                }\n            }\n            break;\n        }\n        // Peek more characters.\n        ch2 = source[index + 1];\n        ch3 = source[index + 2];\n        ch4 = source[index + 3];\n        // 4-character punctuator: >>>=\n        if (ch1 === '>' && ch2 === '>' && ch3 === '>') {\n            if (ch4 === '=') {\n                index += 4;\n                return {\n                    type: Token.Punctuator,\n                    value: '>>>=',\n                    lineNumber: lineNumber,\n                    lineStart: lineStart,\n                    range: [\n                        start,\n                        index\n                    ]\n                };\n            }\n        }\n        // 3-character punctuators: === !== >>> <<= >>=\n        if (ch1 === '>' && ch2 === '>' && ch3 === '>') {\n            index += 3;\n            return {\n                type: Token.Punctuator,\n                value: '>>>',\n                lineNumber: lineNumber,\n                lineStart: lineStart,\n                range: [\n                    start,\n                    index\n                ]\n            };\n        }\n        if (ch1 === '<' && ch2 === '<' && ch3 === '=') {\n            index += 3;\n            return {\n                type: Token.Punctuator,\n                value: '<<=',\n                lineNumber: lineNumber,\n                lineStart: lineStart,\n                range: [\n                    start,\n                    index\n                ]\n            };\n        }\n        if (ch1 === '>' && ch2 === '>' && ch3 === '=') {\n            index += 3;\n            return {\n                type: Token.Punctuator,\n                value: '>>=',\n                lineNumber: lineNumber,\n                lineStart: lineStart,\n                range: [\n                    start,\n                    index\n                ]\n            };\n        }\n        if (ch1 === '.' && ch2 === '.' && ch3 === '.') {\n            index += 3;\n            return {\n                type: Token.Punctuator,\n                value: '...',\n                lineNumber: lineNumber,\n                lineStart: lineStart,\n                range: [\n                    start,\n                    index\n                ]\n            };\n        }\n        // Other 2-character punctuators: ++ -- << >> && ||\n        if (ch1 === ch2 && '+-<>&|'.indexOf(ch1) >= 0) {\n            index += 2;\n            return {\n                type: Token.Punctuator,\n                value: ch1 + ch2,\n                lineNumber: lineNumber,\n                lineStart: lineStart,\n                range: [\n                    start,\n                    index\n                ]\n            };\n        }\n        if (ch1 === '=' && ch2 === '>') {\n            index += 2;\n            return {\n                type: Token.Punctuator,\n                value: '=>',\n                lineNumber: lineNumber,\n                lineStart: lineStart,\n                range: [\n                    start,\n                    index\n                ]\n            };\n        }\n        if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) {\n            ++index;\n            return {\n                type: Token.Punctuator,\n                value: ch1,\n                lineNumber: lineNumber,\n                lineStart: lineStart,\n                range: [\n                    start,\n                    index\n                ]\n            };\n        }\n        if (ch1 === '.') {\n            ++index;\n            return {\n                type: Token.Punctuator,\n                value: ch1,\n                lineNumber: lineNumber,\n                lineStart: lineStart,\n                range: [\n                    start,\n                    index\n                ]\n            };\n        }\n        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n    }\n    // 7.8.3 Numeric Literals\n    function scanHexLiteral(start) {\n        var number = '';\n        while (index < length) {\n            if (!isHexDigit(source[index])) {\n                break;\n            }\n            number += source[index++];\n        }\n        if (number.length === 0) {\n            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n        }\n        if (isIdentifierStart(source.charCodeAt(index))) {\n            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n        }\n        return {\n            type: Token.NumericLiteral,\n            value: parseInt('0x' + number, 16),\n            lineNumber: lineNumber,\n            lineStart: lineStart,\n            range: [\n                start,\n                index\n            ]\n        };\n    }\n    function scanOctalLiteral(prefix, start) {\n        var number, octal;\n        if (isOctalDigit(prefix)) {\n            octal = true;\n            number = '0' + source[index++];\n        } else {\n            octal = false;\n            ++index;\n            number = '';\n        }\n        while (index < length) {\n            if (!isOctalDigit(source[index])) {\n                break;\n            }\n            number += source[index++];\n        }\n        if (!octal && number.length === 0) {\n            // only 0o or 0O\n            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n        }\n        if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) {\n            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n        }\n        return {\n            type: Token.NumericLiteral,\n            value: parseInt(number, 8),\n            octal: octal,\n            lineNumber: lineNumber,\n            lineStart: lineStart,\n            range: [\n                start,\n                index\n            ]\n        };\n    }\n    function scanNumericLiteral() {\n        var number, start, ch, octal;\n        ch = source[index];\n        assert(isDecimalDigit(ch.charCodeAt(0)) || ch === '.', 'Numeric literal must start with a decimal digit or a decimal point');\n        start = index;\n        number = '';\n        if (ch !== '.') {\n            number = source[index++];\n            ch = source[index];\n            // Hex number starts with '0x'.\n            // Octal number starts with '0'.\n            // Octal number in ES6 starts with '0o'.\n            // Binary number in ES6 starts with '0b'.\n            if (number === '0') {\n                if (ch === 'x' || ch === 'X') {\n                    ++index;\n                    return scanHexLiteral(start);\n                }\n                if (ch === 'b' || ch === 'B') {\n                    ++index;\n                    number = '';\n                    while (index < length) {\n                        ch = source[index];\n                        if (ch !== '0' && ch !== '1') {\n                            break;\n                        }\n                        number += source[index++];\n                    }\n                    if (number.length === 0) {\n                        // only 0b or 0B\n                        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n                    }\n                    if (index < length) {\n                        ch = source.charCodeAt(index);\n                        if (isIdentifierStart(ch) || isDecimalDigit(ch)) {\n                            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n                        }\n                    }\n                    return {\n                        type: Token.NumericLiteral,\n                        value: parseInt(number, 2),\n                        lineNumber: lineNumber,\n                        lineStart: lineStart,\n                        range: [\n                            start,\n                            index\n                        ]\n                    };\n                }\n                if (ch === 'o' || ch === 'O' || isOctalDigit(ch)) {\n                    return scanOctalLiteral(ch, start);\n                }\n                // decimal number starts with '0' such as '09' is illegal.\n                if (ch && isDecimalDigit(ch.charCodeAt(0))) {\n                    throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n                }\n            }\n            while (isDecimalDigit(source.charCodeAt(index))) {\n                number += source[index++];\n            }\n            ch = source[index];\n        }\n        if (ch === '.') {\n            number += source[index++];\n            while (isDecimalDigit(source.charCodeAt(index))) {\n                number += source[index++];\n            }\n            ch = source[index];\n        }\n        if (ch === 'e' || ch === 'E') {\n            number += source[index++];\n            ch = source[index];\n            if (ch === '+' || ch === '-') {\n                number += source[index++];\n            }\n            if (isDecimalDigit(source.charCodeAt(index))) {\n                while (isDecimalDigit(source.charCodeAt(index))) {\n                    number += source[index++];\n                }\n            } else {\n                throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n            }\n        }\n        if (isIdentifierStart(source.charCodeAt(index))) {\n            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n        }\n        return {\n            type: Token.NumericLiteral,\n            value: parseFloat(number),\n            lineNumber: lineNumber,\n            lineStart: lineStart,\n            range: [\n                start,\n                index\n            ]\n        };\n    }\n    // 7.8.4 String Literals\n    function scanStringLiteral() {\n        var str = '', quote, start, ch, code, unescaped, restore, octal = false;\n        quote = source[index];\n        assert(quote === '\\'' || quote === '\"', 'String literal must starts with a quote');\n        start = index;\n        ++index;\n        while (index < length) {\n            ch = source[index++];\n            if (ch === quote) {\n                quote = '';\n                break;\n            } else if (ch === '\\\\') {\n                ch = source[index++];\n                if (!ch || !isLineTerminator(ch.charCodeAt(0))) {\n                    switch (ch) {\n                    case 'n':\n                        str += '\\n';\n                        break;\n                    case 'r':\n                        str += '\\r';\n                        break;\n                    case 't':\n                        str += '\\t';\n                        break;\n                    case 'u':\n                    case 'x':\n                        if (source[index] === '{') {\n                            ++index;\n                            str += scanUnicodeCodePointEscape();\n                        } else {\n                            restore = index;\n                            unescaped = scanHexEscape(ch);\n                            if (unescaped) {\n                                str += unescaped;\n                            } else {\n                                index = restore;\n                                str += ch;\n                            }\n                        }\n                        break;\n                    case 'b':\n                        str += '\\b';\n                        break;\n                    case 'f':\n                        str += '\\f';\n                        break;\n                    case 'v':\n                        str += '\\x0B';\n                        break;\n                    default:\n                        if (isOctalDigit(ch)) {\n                            code = '01234567'.indexOf(ch);\n                            // \\0 is not octal escape sequence\n                            if (code !== 0) {\n                                octal = true;\n                            }\n                            if (index < length && isOctalDigit(source[index])) {\n                                octal = true;\n                                code = code * 8 + '01234567'.indexOf(source[index++]);\n                                // 3 digits are only allowed when string starts\n                                // with 0, 1, 2, 3\n                                if ('0123'.indexOf(ch) >= 0 && index < length && isOctalDigit(source[index])) {\n                                    code = code * 8 + '01234567'.indexOf(source[index++]);\n                                }\n                            }\n                            str += String.fromCharCode(code);\n                        } else {\n                            str += ch;\n                        }\n                        break;\n                    }\n                } else {\n                    ++lineNumber;\n                    if (ch === '\\r' && source[index] === '\\n') {\n                        ++index;\n                    }\n                }\n            } else if (isLineTerminator(ch.charCodeAt(0))) {\n                break;\n            } else {\n                str += ch;\n            }\n        }\n        if (quote !== '') {\n            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n        }\n        return {\n            type: Token.StringLiteral,\n            value: str,\n            octal: octal,\n            lineNumber: lineNumber,\n            lineStart: lineStart,\n            range: [\n                start,\n                index\n            ]\n        };\n    }\n    function scanTemplate() {\n        var cooked = '', ch, start, terminated, tail, restore, unescaped, code, octal;\n        terminated = false;\n        tail = false;\n        start = index;\n        ++index;\n        while (index < length) {\n            ch = source[index++];\n            if (ch === '`') {\n                tail = true;\n                terminated = true;\n                break;\n            } else if (ch === '$') {\n                if (source[index] === '{') {\n                    ++index;\n                    terminated = true;\n                    break;\n                }\n                cooked += ch;\n            } else if (ch === '\\\\') {\n                ch = source[index++];\n                if (!isLineTerminator(ch.charCodeAt(0))) {\n                    switch (ch) {\n                    case 'n':\n                        cooked += '\\n';\n                        break;\n                    case 'r':\n                        cooked += '\\r';\n                        break;\n                    case 't':\n                        cooked += '\\t';\n                        break;\n                    case 'u':\n                    case 'x':\n                        if (source[index] === '{') {\n                            ++index;\n                            cooked += scanUnicodeCodePointEscape();\n                        } else {\n                            restore = index;\n                            unescaped = scanHexEscape(ch);\n                            if (unescaped) {\n                                cooked += unescaped;\n                            } else {\n                                index = restore;\n                                cooked += ch;\n                            }\n                        }\n                        break;\n                    case 'b':\n                        cooked += '\\b';\n                        break;\n                    case 'f':\n                        cooked += '\\f';\n                        break;\n                    case 'v':\n                        cooked += '\\x0B';\n                        break;\n                    default:\n                        if (isOctalDigit(ch)) {\n                            code = '01234567'.indexOf(ch);\n                            // \\0 is not octal escape sequence\n                            if (code !== 0) {\n                                octal = true;\n                            }\n                            if (index < length && isOctalDigit(source[index])) {\n                                octal = true;\n                                code = code * 8 + '01234567'.indexOf(source[index++]);\n                                // 3 digits are only allowed when string starts\n                                // with 0, 1, 2, 3\n                                if ('0123'.indexOf(ch) >= 0 && index < length && isOctalDigit(source[index])) {\n                                    code = code * 8 + '01234567'.indexOf(source[index++]);\n                                }\n                            }\n                            cooked += String.fromCharCode(code);\n                        } else {\n                            cooked += ch;\n                        }\n                        break;\n                    }\n                } else {\n                    ++lineNumber;\n                    if (ch === '\\r' && source[index] === '\\n') {\n                        ++index;\n                    }\n                }\n            } else if (isLineTerminator(ch.charCodeAt(0))) {\n                ++lineNumber;\n                if (ch === '\\r' && source[index] === '\\n') {\n                    ++index;\n                }\n                cooked += '\\n';\n            } else {\n                cooked += ch;\n            }\n        }\n        if (!terminated) {\n            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n        }\n        return {\n            type: Token.Template,\n            value: {\n                cooked: cooked,\n                raw: source.slice(start + 1, index - (tail ? 1 : 2))\n            },\n            tail: tail,\n            octal: octal,\n            lineNumber: lineNumber,\n            lineStart: lineStart,\n            range: [\n                start,\n                index\n            ]\n        };\n    }\n    function scanTemplateElement(option) {\n        var startsWith, template;\n        lookahead = null;\n        skipComment();\n        startsWith = option.head ? '`' : '}';\n        if (source[index] !== startsWith) {\n            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n        }\n        template = scanTemplate();\n        peek();\n        return template;\n    }\n    function scanRegExp() {\n        var str, ch, start, pattern, flags, value, classMarker = false, restore, terminated = false;\n        lookahead = null;\n        skipComment();\n        start = index;\n        ch = source[index];\n        assert(ch === '/', 'Regular expression literal must start with a slash');\n        str = source[index++];\n        while (index < length) {\n            ch = source[index++];\n            str += ch;\n            if (classMarker) {\n                if (ch === ']') {\n                    classMarker = false;\n                }\n            } else {\n                if (ch === '\\\\') {\n                    ch = source[index++];\n                    // ECMA-262 7.8.5\n                    if (isLineTerminator(ch.charCodeAt(0))) {\n                        throwError({}, Messages.UnterminatedRegExp);\n                    }\n                    str += ch;\n                } else if (ch === '/') {\n                    terminated = true;\n                    break;\n                } else if (ch === '[') {\n                    classMarker = true;\n                } else if (isLineTerminator(ch.charCodeAt(0))) {\n                    throwError({}, Messages.UnterminatedRegExp);\n                }\n            }\n        }\n        if (!terminated) {\n            throwError({}, Messages.UnterminatedRegExp);\n        }\n        // Exclude leading and trailing slash.\n        pattern = str.substr(1, str.length - 2);\n        flags = '';\n        while (index < length) {\n            ch = source[index];\n            if (!isIdentifierPart(ch.charCodeAt(0))) {\n                break;\n            }\n            ++index;\n            if (ch === '\\\\' && index < length) {\n                ch = source[index];\n                if (ch === 'u') {\n                    ++index;\n                    restore = index;\n                    ch = scanHexEscape('u');\n                    if (ch) {\n                        flags += ch;\n                        for (str += '\\\\u'; restore < index; ++restore) {\n                            str += source[restore];\n                        }\n                    } else {\n                        index = restore;\n                        flags += 'u';\n                        str += '\\\\u';\n                    }\n                } else {\n                    str += '\\\\';\n                }\n            } else {\n                flags += ch;\n                str += ch;\n            }\n        }\n        try {\n            value = new RegExp(pattern, flags);\n        } catch (e) {\n            throwError({}, Messages.InvalidRegExp);\n        }\n        // peek();\n        if (extra.tokenize) {\n            return {\n                type: Token.RegularExpression,\n                value: value,\n                lineNumber: lineNumber,\n                lineStart: lineStart,\n                range: [\n                    start,\n                    index\n                ]\n            };\n        }\n        return {\n            type: Token.RegularExpression,\n            literal: str,\n            value: value,\n            range: [\n                start,\n                index\n            ]\n        };\n    }\n    function isIdentifierName(token) {\n        return token.type === Token.Identifier || token.type === Token.Keyword || token.type === Token.BooleanLiteral || token.type === Token.NullLiteral;\n    }\n    function advanceSlash() {\n        var prevToken, checkToken;\n        // Using the following algorithm:\n        // https://github.com/mozilla/sweet.js/wiki/design\n        prevToken = extra.tokens[extra.tokens.length - 1];\n        if (!prevToken) {\n            // Nothing before that: it cannot be a division.\n            return scanRegExp();\n        }\n        if (prevToken.type === 'Punctuator') {\n            if (prevToken.value === ')') {\n                checkToken = extra.tokens[extra.openParenToken - 1];\n                if (checkToken && checkToken.type === 'Keyword' && (checkToken.value === 'if' || checkToken.value === 'while' || checkToken.value === 'for' || checkToken.value === 'with')) {\n                    return scanRegExp();\n                }\n                return scanPunctuator();\n            }\n            if (prevToken.value === '}') {\n                // Dividing a function by anything makes little sense,\n                // but we have to check for that.\n                if (extra.tokens[extra.openCurlyToken - 3] && extra.tokens[extra.openCurlyToken - 3].type === 'Keyword') {\n                    // Anonymous function.\n                    checkToken = extra.tokens[extra.openCurlyToken - 4];\n                    if (!checkToken) {\n                        return scanPunctuator();\n                    }\n                } else if (extra.tokens[extra.openCurlyToken - 4] && extra.tokens[extra.openCurlyToken - 4].type === 'Keyword') {\n                    // Named function.\n                    checkToken = extra.tokens[extra.openCurlyToken - 5];\n                    if (!checkToken) {\n                        return scanRegExp();\n                    }\n                } else {\n                    return scanPunctuator();\n                }\n                // checkToken determines whether the function is\n                // a declaration or an expression.\n                if (FnExprTokens.indexOf(checkToken.value) >= 0) {\n                    // It is an expression.\n                    return scanPunctuator();\n                }\n                // It is a declaration.\n                return scanRegExp();\n            }\n            return scanRegExp();\n        }\n        if (prevToken.type === 'Keyword') {\n            return scanRegExp();\n        }\n        return scanPunctuator();\n    }\n    function advance() {\n        var ch;\n        skipComment();\n        if (index >= length) {\n            return {\n                type: Token.EOF,\n                lineNumber: lineNumber,\n                lineStart: lineStart,\n                range: [\n                    index,\n                    index\n                ]\n            };\n        }\n        ch = source.charCodeAt(index);\n        // Very common: ( and ) and ;\n        if (ch === 40 || ch === 41 || ch === 58) {\n            return scanPunctuator();\n        }\n        // String literal starts with single quote (#39) or double quote (#34).\n        if (ch === 39 || ch === 34) {\n            return scanStringLiteral();\n        }\n        if (ch === 96) {\n            return scanTemplate();\n        }\n        if (isIdentifierStart(ch)) {\n            return scanIdentifier();\n        }\n        // # and @ are allowed for sweet.js\n        if (ch === 35 || ch === 64) {\n            ++index;\n            return {\n                type: Token.Punctuator,\n                value: String.fromCharCode(ch),\n                lineNumber: lineNumber,\n                lineStart: lineStart,\n                range: [\n                    index - 1,\n                    index\n                ]\n            };\n        }\n        // Dot (.) char #46 can also start a floating-point number, hence the need\n        // to check the next character.\n        if (ch === 46) {\n            if (isDecimalDigit(source.charCodeAt(index + 1))) {\n                return scanNumericLiteral();\n            }\n            return scanPunctuator();\n        }\n        if (isDecimalDigit(ch)) {\n            return scanNumericLiteral();\n        }\n        // Slash (/) char #47 can also start a regex.\n        if (extra.tokenize && ch === 47) {\n            return advanceSlash();\n        }\n        return scanPunctuator();\n    }\n    function lex() {\n        var token;\n        token = lookahead;\n        streamIndex = lookaheadIndex;\n        lineNumber = token.lineNumber;\n        lineStart = token.lineStart;\n        sm_lineNumber = lookahead.sm_lineNumber;\n        sm_lineStart = lookahead.sm_lineStart;\n        sm_range = lookahead.sm_range;\n        sm_index = lookahead.sm_range[0];\n        lookahead = tokenStream[++streamIndex].token;\n        lookaheadIndex = streamIndex;\n        index = lookahead.range[0];\n        return token;\n    }\n    function peek() {\n        lookaheadIndex = streamIndex + 1;\n        if (lookaheadIndex >= length) {\n            lookahead = {\n                type: Token.EOF,\n                lineNumber: lineNumber,\n                lineStart: lineStart,\n                range: [\n                    index,\n                    index\n                ]\n            };\n            return;\n        }\n        lookahead = tokenStream[lookaheadIndex].token;\n        index = lookahead.range[0];\n    }\n    function lookahead2() {\n        var adv, pos, line, start, result;\n        if (streamIndex + 1 >= length || streamIndex + 2 >= length) {\n            return {\n                type: Token.EOF,\n                lineNumber: lineNumber,\n                lineStart: lineStart,\n                range: [\n                    index,\n                    index\n                ]\n            };\n        }\n        // Scan for the next immediate token.\n        if (lookahead === null) {\n            lookaheadIndex = streamIndex + 1;\n            lookahead = tokenStream[lookaheadIndex].token;\n            index = lookahead.range[0];\n        }\n        result = tokenStream[lookaheadIndex + 1].token;\n        return result;\n    }\n    SyntaxTreeDelegate = {\n        name: 'SyntaxTree',\n        postProcess: function (node) {\n            return node;\n        },\n        createArrayExpression: function (elements) {\n            return {\n                type: Syntax.ArrayExpression,\n                elements: elements\n            };\n        },\n        createAssignmentExpression: function (operator, left, right) {\n            return {\n                type: Syntax.AssignmentExpression,\n                operator: operator,\n                left: left,\n                right: right\n            };\n        },\n        createBinaryExpression: function (operator, left, right) {\n            var type = operator === '||' || operator === '&&' ? Syntax.LogicalExpression : Syntax.BinaryExpression;\n            return {\n                type: type,\n                operator: operator,\n                left: left,\n                right: right\n            };\n        },\n        createBlockStatement: function (body) {\n            return {\n                type: Syntax.BlockStatement,\n                body: body\n            };\n        },\n        createBreakStatement: function (label) {\n            return {\n                type: Syntax.BreakStatement,\n                label: label\n            };\n        },\n        createCallExpression: function (callee, args) {\n            return {\n                type: Syntax.CallExpression,\n                callee: callee,\n                'arguments': args\n            };\n        },\n        createCatchClause: function (param, body) {\n            return {\n                type: Syntax.CatchClause,\n                param: param,\n                body: body\n            };\n        },\n        createConditionalExpression: function (test, consequent, alternate) {\n            return {\n                type: Syntax.ConditionalExpression,\n                test: test,\n                consequent: consequent,\n                alternate: alternate\n            };\n        },\n        createContinueStatement: function (label) {\n            return {\n                type: Syntax.ContinueStatement,\n                label: label\n            };\n        },\n        createDebuggerStatement: function () {\n            return { type: Syntax.DebuggerStatement };\n        },\n        createDoWhileStatement: function (body, test) {\n            return {\n                type: Syntax.DoWhileStatement,\n                body: body,\n                test: test\n            };\n        },\n        createEmptyStatement: function () {\n            return { type: Syntax.EmptyStatement };\n        },\n        createExpressionStatement: function (expression) {\n            return {\n                type: Syntax.ExpressionStatement,\n                expression: expression\n            };\n        },\n        createForStatement: function (init, test, update, body) {\n            return {\n                type: Syntax.ForStatement,\n                init: init,\n                test: test,\n                update: update,\n                body: body\n            };\n        },\n        createForInStatement: function (left, right, body) {\n            return {\n                type: Syntax.ForInStatement,\n                left: left,\n                right: right,\n                body: body,\n                each: false\n            };\n        },\n        createForOfStatement: function (left, right, body) {\n            return {\n                type: Syntax.ForOfStatement,\n                left: left,\n                right: right,\n                body: body\n            };\n        },\n        createFunctionDeclaration: function (id, params, defaults, body, rest, generator, expression) {\n            return {\n                type: Syntax.FunctionDeclaration,\n                id: id,\n                params: params,\n                defaults: defaults,\n                body: body,\n                rest: rest,\n                generator: generator,\n                expression: expression\n            };\n        },\n        createFunctionExpression: function (id, params, defaults, body, rest, generator, expression) {\n            return {\n                type: Syntax.FunctionExpression,\n                id: id,\n                params: params,\n                defaults: defaults,\n                body: body,\n                rest: rest,\n                generator: generator,\n                expression: expression\n            };\n        },\n        createIdentifier: function (name) {\n            return {\n                type: Syntax.Identifier,\n                name: name\n            };\n        },\n        createIfStatement: function (test, consequent, alternate) {\n            return {\n                type: Syntax.IfStatement,\n                test: test,\n                consequent: consequent,\n                alternate: alternate\n            };\n        },\n        createLabeledStatement: function (label, body) {\n            return {\n                type: Syntax.LabeledStatement,\n                label: label,\n                body: body\n            };\n        },\n        createLiteral: function (token) {\n            return {\n                type: Syntax.Literal,\n                value: token.value,\n                raw: String(token.value)\n            };\n        },\n        createMemberExpression: function (accessor, object, property) {\n            return {\n                type: Syntax.MemberExpression,\n                computed: accessor === '[',\n                object: object,\n                property: property\n            };\n        },\n        createNewExpression: function (callee, args) {\n            return {\n                type: Syntax.NewExpression,\n                callee: callee,\n                'arguments': args\n            };\n        },\n        createObjectExpression: function (properties) {\n            return {\n                type: Syntax.ObjectExpression,\n                properties: properties\n            };\n        },\n        createPostfixExpression: function (operator, argument) {\n            return {\n                type: Syntax.UpdateExpression,\n                operator: operator,\n                argument: argument,\n                prefix: false\n            };\n        },\n        createProgram: function (body) {\n            return {\n                type: Syntax.Program,\n                body: body\n            };\n        },\n        createProperty: function (kind, key, value, method, shorthand) {\n            return {\n                type: Syntax.Property,\n                key: key,\n                value: value,\n                kind: kind,\n                method: method,\n                shorthand: shorthand\n            };\n        },\n        createReturnStatement: function (argument) {\n            return {\n                type: Syntax.ReturnStatement,\n                argument: argument\n            };\n        },\n        createSequenceExpression: function (expressions) {\n            return {\n                type: Syntax.SequenceExpression,\n                expressions: expressions\n            };\n        },\n        createSwitchCase: function (test, consequent) {\n            return {\n                type: Syntax.SwitchCase,\n                test: test,\n                consequent: consequent\n            };\n        },\n        createSwitchStatement: function (discriminant, cases) {\n            return {\n                type: Syntax.SwitchStatement,\n                discriminant: discriminant,\n                cases: cases\n            };\n        },\n        createThisExpression: function () {\n            return { type: Syntax.ThisExpression };\n        },\n        createThrowStatement: function (argument) {\n            return {\n                type: Syntax.ThrowStatement,\n                argument: argument\n            };\n        },\n        createTryStatement: function (block, guardedHandlers, handlers, finalizer) {\n            return {\n                type: Syntax.TryStatement,\n                block: block,\n                guardedHandlers: guardedHandlers,\n                handlers: handlers,\n                finalizer: finalizer\n            };\n        },\n        createUnaryExpression: function (operator, argument) {\n            if (operator === '++' || operator === '--') {\n                return {\n                    type: Syntax.UpdateExpression,\n                    operator: operator,\n                    argument: argument,\n                    prefix: true\n                };\n            }\n            return {\n                type: Syntax.UnaryExpression,\n                operator: operator,\n                argument: argument\n            };\n        },\n        createVariableDeclaration: function (declarations, kind) {\n            return {\n                type: Syntax.VariableDeclaration,\n                declarations: declarations,\n                kind: kind\n            };\n        },\n        createVariableDeclarator: function (id, init) {\n            return {\n                type: Syntax.VariableDeclarator,\n                id: id,\n                init: init\n            };\n        },\n        createWhileStatement: function (test, body) {\n            return {\n                type: Syntax.WhileStatement,\n                test: test,\n                body: body\n            };\n        },\n        createWithStatement: function (object, body) {\n            return {\n                type: Syntax.WithStatement,\n                object: object,\n                body: body\n            };\n        },\n        createTemplateElement: function (value, tail) {\n            return {\n                type: Syntax.TemplateElement,\n                value: value,\n                tail: tail\n            };\n        },\n        createTemplateLiteral: function (quasis, expressions) {\n            return {\n                type: Syntax.TemplateLiteral,\n                quasis: quasis,\n                expressions: expressions\n            };\n        },\n        createSpreadElement: function (argument) {\n            return {\n                type: Syntax.SpreadElement,\n                argument: argument\n            };\n        },\n        createTaggedTemplateExpression: function (tag, quasi) {\n            return {\n                type: Syntax.TaggedTemplateExpression,\n                tag: tag,\n                quasi: quasi\n            };\n        },\n        createArrowFunctionExpression: function (params, defaults, body, rest, expression) {\n            return {\n                type: Syntax.ArrowFunctionExpression,\n                id: null,\n                params: params,\n                defaults: defaults,\n                body: body,\n                rest: rest,\n                generator: false,\n                expression: expression\n            };\n        },\n        createMethodDefinition: function (propertyType, kind, key, value) {\n            return {\n                type: Syntax.MethodDefinition,\n                key: key,\n                value: value,\n                kind: kind,\n                'static': propertyType === ClassPropertyType.static\n            };\n        },\n        createClassBody: function (body) {\n            return {\n                type: Syntax.ClassBody,\n                body: body\n            };\n        },\n        createClassExpression: function (id, superClass, body) {\n            return {\n                type: Syntax.ClassExpression,\n                id: id,\n                superClass: superClass,\n                body: body\n            };\n        },\n        createClassDeclaration: function (id, superClass, body) {\n            return {\n                type: Syntax.ClassDeclaration,\n                id: id,\n                superClass: superClass,\n                body: body\n            };\n        },\n        createExportSpecifier: function (id, name) {\n            return {\n                type: Syntax.ExportSpecifier,\n                id: id,\n                name: name\n            };\n        },\n        createExportBatchSpecifier: function () {\n            return { type: Syntax.ExportBatchSpecifier };\n        },\n        createExportDeclaration: function (declaration, specifiers, source$2) {\n            return {\n                type: Syntax.ExportDeclaration,\n                declaration: declaration,\n                specifiers: specifiers,\n                source: source$2\n            };\n        },\n        createImportSpecifier: function (id, name) {\n            return {\n                type: Syntax.ImportSpecifier,\n                id: id,\n                name: name\n            };\n        },\n        createImportDeclaration: function (specifiers, kind, source$2) {\n            return {\n                type: Syntax.ImportDeclaration,\n                specifiers: specifiers,\n                kind: kind,\n                source: source$2\n            };\n        },\n        createYieldExpression: function (argument, delegate$2) {\n            return {\n                type: Syntax.YieldExpression,\n                argument: argument,\n                delegate: delegate$2\n            };\n        },\n        createModuleDeclaration: function (id, source$2, body) {\n            return {\n                type: Syntax.ModuleDeclaration,\n                id: id,\n                source: source$2,\n                body: body\n            };\n        }\n    };\n    // Return true if there is a line terminator before the next token.\n    function peekLineTerminator() {\n        return lookahead.lineNumber !== lineNumber;\n    }\n    // Throw an exception\n    function throwError(token, messageFormat) {\n        var error, args = Array.prototype.slice.call(arguments, 2), msg = messageFormat.replace(/%(\\d)/g, function (whole, index$2) {\n                assert(index$2 < args.length, 'Message reference must be in range');\n                return args[index$2];\n            });\n        var startIndex = streamIndex > 3 ? streamIndex - 3 : 0;\n        var toks = '', tailingMsg = '';\n        if (tokenStream) {\n            toks = tokenStream.slice(startIndex, streamIndex + 3).map(function (stx) {\n                return stx.token.value;\n            }).join(' ');\n            tailingMsg = '\\n[... ' + toks + ' ...]';\n        }\n        if (typeof token.lineNumber === 'number') {\n            error = new Error('Line ' + token.lineNumber + ': ' + msg + tailingMsg);\n            error.index = token.range[0];\n            error.lineNumber = token.lineNumber;\n            error.column = token.range[0] - lineStart + 1;\n        } else {\n            error = new Error('Line ' + lineNumber + ': ' + msg + tailingMsg);\n            error.index = index;\n            error.lineNumber = lineNumber;\n            error.column = index - lineStart + 1;\n        }\n        error.description = msg;\n        throw error;\n    }\n    function throwErrorTolerant() {\n        try {\n            throwError.apply(null, arguments);\n        } catch (e) {\n            if (extra.errors) {\n                extra.errors.push(e);\n            } else {\n                throw e;\n            }\n        }\n    }\n    // Throw an exception because of the token.\n    function throwUnexpected(token) {\n        if (token.type === Token.EOF) {\n            throwError(token, Messages.UnexpectedEOS);\n        }\n        if (token.type === Token.NumericLiteral) {\n            throwError(token, Messages.UnexpectedNumber);\n        }\n        if (token.type === Token.StringLiteral) {\n            throwError(token, Messages.UnexpectedString);\n        }\n        if (token.type === Token.Identifier) {\n            throwError(token, Messages.UnexpectedIdentifier);\n        }\n        if (token.type === Token.Keyword) {\n            if (isFutureReservedWord(token.value)) {\n            }    // sweet.js allows future reserved words\n                 // throwError(token, Messages.UnexpectedReserved);\n            else if (strict && isStrictModeReservedWord(token.value)) {\n                throwErrorTolerant(token, Messages.StrictReservedWord);\n                return;\n            }\n            throwError(token, Messages.UnexpectedToken, token.value);\n        }\n        if (token.type === Token.Template) {\n            throwError(token, Messages.UnexpectedTemplate, token.value.raw);\n        }\n        // BooleanLiteral, NullLiteral, or Punctuator.\n        throwError(token, Messages.UnexpectedToken, token.value);\n    }\n    // Expect the next token to match the specified punctuator.\n    // If not, an exception will be thrown.\n    function expect(value) {\n        var token = lex();\n        if (token.type !== Token.Punctuator || token.value !== value) {\n            throwUnexpected(token);\n        }\n    }\n    // Expect the next token to match the specified keyword.\n    // If not, an exception will be thrown.\n    function expectKeyword(keyword) {\n        var token = lex();\n        if (token.type !== Token.Keyword || token.value !== keyword) {\n            throwUnexpected(token);\n        }\n    }\n    // Return true if the next token matches the specified punctuator.\n    function match(value) {\n        return lookahead.type === Token.Punctuator && lookahead.value === value;\n    }\n    // Return true if the next token matches the specified keyword\n    function matchKeyword(keyword) {\n        return lookahead.type === Token.Keyword && lookahead.value === keyword;\n    }\n    // Return true if the next token matches the specified contextual keyword\n    function matchContextualKeyword(keyword) {\n        return lookahead.type === Token.Identifier && lookahead.value === keyword;\n    }\n    // Return true if the next token is an assignment operator\n    function matchAssign() {\n        var op;\n        if (lookahead.type !== Token.Punctuator) {\n            return false;\n        }\n        op = lookahead.value;\n        return op === '=' || op === '*=' || op === '/=' || op === '%=' || op === '+=' || op === '-=' || op === '<<=' || op === '>>=' || op === '>>>=' || op === '&=' || op === '^=' || op === '|=';\n    }\n    function consumeSemicolon() {\n        var line, ch;\n        ch = lookahead.value ? String(lookahead.value).charCodeAt(0) : -1;\n        // Catch the very common case first: immediately a semicolon (char #59).\n        if (ch === 59) {\n            lex();\n            return;\n        }\n        if (lookahead.lineNumber !== lineNumber) {\n            return;\n        }\n        if (match(';')) {\n            lex();\n            return;\n        }\n        if (lookahead.type !== Token.EOF && !match('}')) {\n            throwUnexpected(lookahead);\n        }\n    }\n    // Return true if provided expression is LeftHandSideExpression\n    function isLeftHandSide(expr) {\n        return expr.type === Syntax.Identifier || expr.type === Syntax.MemberExpression;\n    }\n    function isAssignableLeftHandSide(expr) {\n        return isLeftHandSide(expr) || expr.type === Syntax.ObjectPattern || expr.type === Syntax.ArrayPattern;\n    }\n    // 11.1.4 Array Initialiser\n    function parseArrayInitialiser() {\n        var elements = [], blocks = [], filter = null, tmp, possiblecomprehension = true, body;\n        expect('[');\n        while (!match(']')) {\n            if (lookahead.value === 'for' && lookahead.type === Token.Keyword) {\n                if (!possiblecomprehension) {\n                    throwError({}, Messages.ComprehensionError);\n                }\n                matchKeyword('for');\n                tmp = parseForStatement({ ignoreBody: true });\n                tmp.of = tmp.type === Syntax.ForOfStatement;\n                tmp.type = Syntax.ComprehensionBlock;\n                if (tmp.left.kind) {\n                    // can't be let or const\n                    throwError({}, Messages.ComprehensionError);\n                }\n                blocks.push(tmp);\n            } else if (lookahead.value === 'if' && lookahead.type === Token.Keyword) {\n                if (!possiblecomprehension) {\n                    throwError({}, Messages.ComprehensionError);\n                }\n                expectKeyword('if');\n                expect('(');\n                filter = parseExpression();\n                expect(')');\n            } else if (lookahead.value === ',' && lookahead.type === Token.Punctuator) {\n                possiblecomprehension = false;\n                // no longer allowed.\n                lex();\n                elements.push(null);\n            } else {\n                tmp = parseSpreadOrAssignmentExpression();\n                elements.push(tmp);\n                if (tmp && tmp.type === Syntax.SpreadElement) {\n                    if (!match(']')) {\n                        throwError({}, Messages.ElementAfterSpreadElement);\n                    }\n                } else if (!(match(']') || matchKeyword('for') || matchKeyword('if'))) {\n                    expect(',');\n                    // this lexes.\n                    possiblecomprehension = false;\n                }\n            }\n        }\n        expect(']');\n        if (filter && !blocks.length) {\n            throwError({}, Messages.ComprehensionRequiresBlock);\n        }\n        if (blocks.length) {\n            if (elements.length !== 1) {\n                throwError({}, Messages.ComprehensionError);\n            }\n            return {\n                type: Syntax.ComprehensionExpression,\n                filter: filter,\n                blocks: blocks,\n                body: elements[0]\n            };\n        }\n        return delegate.createArrayExpression(elements);\n    }\n    // 11.1.5 Object Initialiser\n    function parsePropertyFunction(options) {\n        var previousStrict, previousYieldAllowed, params, defaults, body;\n        previousStrict = strict;\n        previousYieldAllowed = state.yieldAllowed;\n        state.yieldAllowed = options.generator;\n        params = options.params || [];\n        defaults = options.defaults || [];\n        body = parseConciseBody();\n        if (options.name && strict && isRestrictedWord(params[0].name)) {\n            throwErrorTolerant(options.name, Messages.StrictParamName);\n        }\n        if (state.yieldAllowed && !state.yieldFound) {\n            throwErrorTolerant({}, Messages.NoYieldInGenerator);\n        }\n        strict = previousStrict;\n        state.yieldAllowed = previousYieldAllowed;\n        return delegate.createFunctionExpression(null, params, defaults, body, options.rest || null, options.generator, body.type !== Syntax.BlockStatement);\n    }\n    function parsePropertyMethodFunction(options) {\n        var previousStrict, tmp, method;\n        previousStrict = strict;\n        strict = true;\n        tmp = parseParams();\n        if (tmp.stricted) {\n            throwErrorTolerant(tmp.stricted, tmp.message);\n        }\n        method = parsePropertyFunction({\n            params: tmp.params,\n            defaults: tmp.defaults,\n            rest: tmp.rest,\n            generator: options.generator\n        });\n        strict = previousStrict;\n        return method;\n    }\n    function parseObjectPropertyKey() {\n        var token = lex();\n        // Note: This function is called only from parseObjectProperty(), where\n        // EOF and Punctuator tokens are already filtered out.\n        if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) {\n            if (strict && token.octal) {\n                throwErrorTolerant(token, Messages.StrictOctalLiteral);\n            }\n            return delegate.createLiteral(token);\n        }\n        // SWEET.JS: object keys are not resolved\n        return delegate.createIdentifier(token.value);\n    }\n    function parseObjectProperty() {\n        var token, key, id, value, param;\n        token = lookahead;\n        if (token.type === Token.Identifier) {\n            id = parseObjectPropertyKey();\n            // Property Assignment: Getter and Setter.\n            if (token.value === 'get' && !(match(':') || match('('))) {\n                key = parseObjectPropertyKey();\n                expect('(');\n                expect(')');\n                return delegate.createProperty('get', key, parsePropertyFunction({ generator: false }), false, false);\n            }\n            if (token.value === 'set' && !(match(':') || match('('))) {\n                key = parseObjectPropertyKey();\n                expect('(');\n                token = lookahead;\n                param = [parseVariableIdentifier()];\n                expect(')');\n                return delegate.createProperty('set', key, parsePropertyFunction({\n                    params: param,\n                    generator: false,\n                    name: token\n                }), false, false);\n            }\n            if (match(':')) {\n                lex();\n                return delegate.createProperty('init', id, parseAssignmentExpression(), false, false);\n            }\n            if (match('(')) {\n                return delegate.createProperty('init', id, parsePropertyMethodFunction({ generator: false }), true, false);\n            }\n            return delegate.createProperty('init', id, id, false, true);\n        }\n        if (token.type === Token.EOF || token.type === Token.Punctuator) {\n            if (!match('*')) {\n                throwUnexpected(token);\n            }\n            lex();\n            id = parseObjectPropertyKey();\n            if (!match('(')) {\n                throwUnexpected(lex());\n            }\n            return delegate.createProperty('init', id, parsePropertyMethodFunction({ generator: true }), true, false);\n        }\n        key = parseObjectPropertyKey();\n        if (match(':')) {\n            lex();\n            return delegate.createProperty('init', key, parseAssignmentExpression(), false, false);\n        }\n        if (match('(')) {\n            return delegate.createProperty('init', key, parsePropertyMethodFunction({ generator: false }), true, false);\n        }\n        throwUnexpected(lex());\n    }\n    function parseObjectInitialiser() {\n        var properties = [], property, name, key, kind, map = {}, toString = String;\n        expect('{');\n        while (!match('}')) {\n            property = parseObjectProperty();\n            if (property.key.type === Syntax.Identifier) {\n                name = property.key.name;\n            } else {\n                name = toString(property.key.value);\n            }\n            kind = property.kind === 'init' ? PropertyKind.Data : property.kind === 'get' ? PropertyKind.Get : PropertyKind.Set;\n            key = '$' + name;\n            if (Object.prototype.hasOwnProperty.call(map, key)) {\n                if (map[key] === PropertyKind.Data) {\n                    if (strict && kind === PropertyKind.Data) {\n                        throwErrorTolerant({}, Messages.StrictDuplicateProperty);\n                    } else if (kind !== PropertyKind.Data) {\n                        throwErrorTolerant({}, Messages.AccessorDataProperty);\n                    }\n                } else {\n                    if (kind === PropertyKind.Data) {\n                        throwErrorTolerant({}, Messages.AccessorDataProperty);\n                    } else if (map[key] & kind) {\n                        throwErrorTolerant({}, Messages.AccessorGetSet);\n                    }\n                }\n                map[key] |= kind;\n            } else {\n                map[key] = kind;\n            }\n            properties.push(property);\n            if (!match('}')) {\n                expect(',');\n            }\n        }\n        expect('}');\n        return delegate.createObjectExpression(properties);\n    }\n    function parseTemplateElement(option) {\n        var token = lex();\n        if (strict && token.octal) {\n            throwError(token, Messages.StrictOctalLiteral);\n        }\n        return delegate.createTemplateElement({\n            raw: token.value.raw,\n            cooked: token.value.cooked\n        }, token.tail);\n    }\n    function parseTemplateLiteral() {\n        var quasi, quasis, expressions;\n        quasi = parseTemplateElement({ head: true });\n        quasis = [quasi];\n        expressions = [];\n        while (!quasi.tail) {\n            expressions.push(parseExpression());\n            quasi = parseTemplateElement({ head: false });\n            quasis.push(quasi);\n        }\n        return delegate.createTemplateLiteral(quasis, expressions);\n    }\n    // 11.1.6 The Grouping Operator\n    function parseGroupExpression() {\n        var expr;\n        expect('(');\n        ++state.parenthesizedCount;\n        expr = parseExpression();\n        expect(')');\n        return expr;\n    }\n    // 11.1 Primary Expressions\n    function parsePrimaryExpression() {\n        var type, token, resolvedIdent;\n        token = lookahead;\n        type = lookahead.type;\n        if (type === Token.Identifier) {\n            resolvedIdent = expander.resolve(tokenStream[lookaheadIndex]);\n            lex();\n            return delegate.createIdentifier(resolvedIdent);\n        }\n        if (type === Token.StringLiteral || type === Token.NumericLiteral) {\n            if (strict && lookahead.octal) {\n                throwErrorTolerant(lookahead, Messages.StrictOctalLiteral);\n            }\n            return delegate.createLiteral(lex());\n        }\n        if (type === Token.Keyword) {\n            if (matchKeyword('this')) {\n                lex();\n                return delegate.createThisExpression();\n            }\n            if (matchKeyword('function')) {\n                return parseFunctionExpression();\n            }\n            if (matchKeyword('class')) {\n                return parseClassExpression();\n            }\n            if (matchKeyword('super')) {\n                lex();\n                return delegate.createIdentifier('super');\n            }\n        }\n        if (type === Token.BooleanLiteral) {\n            token = lex();\n            token.value = token.value === 'true';\n            return delegate.createLiteral(token);\n        }\n        if (type === Token.NullLiteral) {\n            token = lex();\n            token.value = null;\n            return delegate.createLiteral(token);\n        }\n        if (match('[')) {\n            return parseArrayInitialiser();\n        }\n        if (match('{')) {\n            return parseObjectInitialiser();\n        }\n        if (match('(')) {\n            return parseGroupExpression();\n        }\n        if (lookahead.type === Token.RegularExpression) {\n            return delegate.createLiteral(lex());\n        }\n        if (type === Token.Template) {\n            return parseTemplateLiteral();\n        }\n        return throwUnexpected(lex());\n    }\n    // 11.2 Left-Hand-Side Expressions\n    function parseArguments() {\n        var args = [], arg;\n        expect('(');\n        if (!match(')')) {\n            while (streamIndex < length) {\n                arg = parseSpreadOrAssignmentExpression();\n                args.push(arg);\n                if (match(')')) {\n                    break;\n                } else if (arg.type === Syntax.SpreadElement) {\n                    throwError({}, Messages.ElementAfterSpreadElement);\n                }\n                expect(',');\n            }\n        }\n        expect(')');\n        return args;\n    }\n    function parseSpreadOrAssignmentExpression() {\n        if (match('...')) {\n            lex();\n            return delegate.createSpreadElement(parseAssignmentExpression());\n        }\n        return parseAssignmentExpression();\n    }\n    function parseNonComputedProperty() {\n        var token = lex();\n        if (!isIdentifierName(token)) {\n            throwUnexpected(token);\n        }\n        return delegate.createIdentifier(token.value);\n    }\n    function parseNonComputedMember() {\n        expect('.');\n        return parseNonComputedProperty();\n    }\n    function parseComputedMember() {\n        var expr;\n        expect('[');\n        expr = parseExpression();\n        expect(']');\n        return expr;\n    }\n    function parseNewExpression() {\n        var callee, args;\n        expectKeyword('new');\n        callee = parseLeftHandSideExpression();\n        args = match('(') ? parseArguments() : [];\n        return delegate.createNewExpression(callee, args);\n    }\n    function parseLeftHandSideExpressionAllowCall() {\n        var expr, args, property;\n        expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();\n        while (match('.') || match('[') || match('(') || lookahead.type === Token.Template) {\n            if (match('(')) {\n                args = parseArguments();\n                expr = delegate.createCallExpression(expr, args);\n            } else if (match('[')) {\n                expr = delegate.createMemberExpression('[', expr, parseComputedMember());\n            } else if (match('.')) {\n                expr = delegate.createMemberExpression('.', expr, parseNonComputedMember());\n            } else {\n                expr = delegate.createTaggedTemplateExpression(expr, parseTemplateLiteral());\n            }\n        }\n        return expr;\n    }\n    function parseLeftHandSideExpression() {\n        var expr, property;\n        expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();\n        while (match('.') || match('[') || lookahead.type === Token.Template) {\n            if (match('[')) {\n                expr = delegate.createMemberExpression('[', expr, parseComputedMember());\n            } else if (match('.')) {\n                expr = delegate.createMemberExpression('.', expr, parseNonComputedMember());\n            } else {\n                expr = delegate.createTaggedTemplateExpression(expr, parseTemplateLiteral());\n            }\n        }\n        return expr;\n    }\n    // 11.3 Postfix Expressions\n    function parsePostfixExpression() {\n        var expr = parseLeftHandSideExpressionAllowCall(), token = lookahead;\n        if (lookahead.type !== Token.Punctuator) {\n            return expr;\n        }\n        if ((match('++') || match('--')) && !peekLineTerminator()) {\n            // 11.3.1, 11.3.2\n            if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {\n                throwErrorTolerant({}, Messages.StrictLHSPostfix);\n            }\n            if (!isLeftHandSide(expr)) {\n                throwError({}, Messages.InvalidLHSInAssignment);\n            }\n            token = lex();\n            expr = delegate.createPostfixExpression(token.value, expr);\n        }\n        return expr;\n    }\n    // 11.4 Unary Operators\n    function parseUnaryExpression() {\n        var token, expr;\n        if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) {\n            return parsePostfixExpression();\n        }\n        if (match('++') || match('--')) {\n            token = lex();\n            expr = parseUnaryExpression();\n            // 11.4.4, 11.4.5\n            if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {\n                throwErrorTolerant({}, Messages.StrictLHSPrefix);\n            }\n            if (!isLeftHandSide(expr)) {\n                throwError({}, Messages.InvalidLHSInAssignment);\n            }\n            return delegate.createUnaryExpression(token.value, expr);\n        }\n        if (match('+') || match('-') || match('~') || match('!')) {\n            token = lex();\n            expr = parseUnaryExpression();\n            return delegate.createUnaryExpression(token.value, expr);\n        }\n        if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {\n            token = lex();\n            expr = parseUnaryExpression();\n            expr = delegate.createUnaryExpression(token.value, expr);\n            if (expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) {\n                throwErrorTolerant({}, Messages.StrictDelete);\n            }\n            return expr;\n        }\n        return parsePostfixExpression();\n    }\n    function binaryPrecedence(token, allowIn) {\n        var prec = 0;\n        if (token.type !== Token.Punctuator && token.type !== Token.Keyword) {\n            return 0;\n        }\n        switch (token.value) {\n        case '||':\n            prec = 1;\n            break;\n        case '&&':\n            prec = 2;\n            break;\n        case '|':\n            prec = 3;\n            break;\n        case '^':\n            prec = 4;\n            break;\n        case '&':\n            prec = 5;\n            break;\n        case '==':\n        case '!=':\n        case '===':\n        case '!==':\n            prec = 6;\n            break;\n        case '<':\n        case '>':\n        case '<=':\n        case '>=':\n        case 'instanceof':\n            prec = 7;\n            break;\n        case 'in':\n            prec = allowIn ? 7 : 0;\n            break;\n        case '<<':\n        case '>>':\n        case '>>>':\n            prec = 8;\n            break;\n        case '+':\n        case '-':\n            prec = 9;\n            break;\n        case '*':\n        case '/':\n        case '%':\n            prec = 11;\n            break;\n        default:\n            break;\n        }\n        return prec;\n    }\n    // 11.5 Multiplicative Operators\n    // 11.6 Additive Operators\n    // 11.7 Bitwise Shift Operators\n    // 11.8 Relational Operators\n    // 11.9 Equality Operators\n    // 11.10 Binary Bitwise Operators\n    // 11.11 Binary Logical Operators\n    function parseBinaryExpression() {\n        var expr, token, prec, previousAllowIn, stack, right, operator, left, i;\n        previousAllowIn = state.allowIn;\n        state.allowIn = true;\n        expr = parseUnaryExpression();\n        token = lookahead;\n        prec = binaryPrecedence(token, previousAllowIn);\n        if (prec === 0) {\n            return expr;\n        }\n        token.prec = prec;\n        lex();\n        stack = [\n            expr,\n            token,\n            parseUnaryExpression()\n        ];\n        while ((prec = binaryPrecedence(lookahead, previousAllowIn)) > 0) {\n            // Reduce: make a binary expression from the three topmost entries.\n            while (stack.length > 2 && prec <= stack[stack.length - 2].prec) {\n                right = stack.pop();\n                operator = stack.pop().value;\n                left = stack.pop();\n                stack.push(delegate.createBinaryExpression(operator, left, right));\n            }\n            // Shift.\n            token = lex();\n            token.prec = prec;\n            stack.push(token);\n            stack.push(parseUnaryExpression());\n        }\n        state.allowIn = previousAllowIn;\n        // Final reduce to clean-up the stack.\n        i = stack.length - 1;\n        expr = stack[i];\n        while (i > 1) {\n            expr = delegate.createBinaryExpression(stack[i - 1].value, stack[i - 2], expr);\n            i -= 2;\n        }\n        return expr;\n    }\n    // 11.12 Conditional Operator\n    function parseConditionalExpression() {\n        var expr, previousAllowIn, consequent, alternate;\n        expr = parseBinaryExpression();\n        if (match('?')) {\n            lex();\n            previousAllowIn = state.allowIn;\n            state.allowIn = true;\n            consequent = parseAssignmentExpression();\n            state.allowIn = previousAllowIn;\n            expect(':');\n            alternate = parseAssignmentExpression();\n            expr = delegate.createConditionalExpression(expr, consequent, alternate);\n        }\n        return expr;\n    }\n    // 11.13 Assignment Operators\n    function reinterpretAsAssignmentBindingPattern(expr) {\n        var i, len, property, element;\n        if (expr.type === Syntax.ObjectExpression) {\n            expr.type = Syntax.ObjectPattern;\n            for (i = 0, len = expr.properties.length; i < len; i += 1) {\n                property = expr.properties[i];\n                if (property.kind !== 'init') {\n                    throwError({}, Messages.InvalidLHSInAssignment);\n                }\n                reinterpretAsAssignmentBindingPattern(property.value);\n            }\n        } else if (expr.type === Syntax.ArrayExpression) {\n            expr.type = Syntax.ArrayPattern;\n            for (i = 0, len = expr.elements.length; i < len; i += 1) {\n                element = expr.elements[i];\n                if (element) {\n                    reinterpretAsAssignmentBindingPattern(element);\n                }\n            }\n        } else if (expr.type === Syntax.Identifier) {\n            if (isRestrictedWord(expr.name)) {\n                throwError({}, Messages.InvalidLHSInAssignment);\n            }\n        } else if (expr.type === Syntax.SpreadElement) {\n            reinterpretAsAssignmentBindingPattern(expr.argument);\n            if (expr.argument.type === Syntax.ObjectPattern) {\n                throwError({}, Messages.ObjectPatternAsSpread);\n            }\n        } else {\n            if (expr.type !== Syntax.MemberExpression && expr.type !== Syntax.CallExpression && expr.type !== Syntax.NewExpression) {\n                throwError({}, Messages.InvalidLHSInAssignment);\n            }\n        }\n    }\n    function reinterpretAsDestructuredParameter(options, expr) {\n        var i, len, property, element;\n        if (expr.type === Syntax.ObjectExpression) {\n            expr.type = Syntax.ObjectPattern;\n            for (i = 0, len = expr.properties.length; i < len; i += 1) {\n                property = expr.properties[i];\n                if (property.kind !== 'init') {\n                    throwError({}, Messages.InvalidLHSInFormalsList);\n                }\n                reinterpretAsDestructuredParameter(options, property.value);\n            }\n        } else if (expr.type === Syntax.ArrayExpression) {\n            expr.type = Syntax.ArrayPattern;\n            for (i = 0, len = expr.elements.length; i < len; i += 1) {\n                element = expr.elements[i];\n                if (element) {\n                    reinterpretAsDestructuredParameter(options, element);\n                }\n            }\n        } else if (expr.type === Syntax.Identifier) {\n            validateParam(options, expr, expr.name);\n        } else {\n            if (expr.type !== Syntax.MemberExpression) {\n                throwError({}, Messages.InvalidLHSInFormalsList);\n            }\n        }\n    }\n    function reinterpretAsCoverFormalsList(expressions) {\n        var i, len, param, params, defaults, defaultCount, options, rest;\n        params = [];\n        defaults = [];\n        defaultCount = 0;\n        rest = null;\n        options = { paramSet: {} };\n        for (i = 0, len = expressions.length; i < len; i += 1) {\n            param = expressions[i];\n            if (param.type === Syntax.Identifier) {\n                params.push(param);\n                defaults.push(null);\n                validateParam(options, param, param.name);\n            } else if (param.type === Syntax.ObjectExpression || param.type === Syntax.ArrayExpression) {\n                reinterpretAsDestructuredParameter(options, param);\n                params.push(param);\n                defaults.push(null);\n            } else if (param.type === Syntax.SpreadElement) {\n                assert(i === len - 1, 'It is guaranteed that SpreadElement is last element by parseExpression');\n                reinterpretAsDestructuredParameter(options, param.argument);\n                rest = param.argument;\n            } else if (param.type === Syntax.AssignmentExpression) {\n                params.push(param.left);\n                defaults.push(param.right);\n                ++defaultCount;\n                validateParam(options, param.left, param.left.name);\n            } else {\n                return null;\n            }\n        }\n        if (options.message === Messages.StrictParamDupe) {\n            throwError(strict ? options.stricted : options.firstRestricted, options.message);\n        }\n        if (defaultCount === 0) {\n            defaults = [];\n        }\n        return {\n            params: params,\n            defaults: defaults,\n            rest: rest,\n            stricted: options.stricted,\n            firstRestricted: options.firstRestricted,\n            message: options.message\n        };\n    }\n    function parseArrowFunctionExpression(options) {\n        var previousStrict, previousYieldAllowed, body;\n        expect('=>');\n        previousStrict = strict;\n        previousYieldAllowed = state.yieldAllowed;\n        state.yieldAllowed = false;\n        body = parseConciseBody();\n        if (strict && options.firstRestricted) {\n            throwError(options.firstRestricted, options.message);\n        }\n        if (strict && options.stricted) {\n            throwErrorTolerant(options.stricted, options.message);\n        }\n        strict = previousStrict;\n        state.yieldAllowed = previousYieldAllowed;\n        return delegate.createArrowFunctionExpression(options.params, options.defaults, body, options.rest, body.type !== Syntax.BlockStatement);\n    }\n    function parseAssignmentExpression() {\n        var expr, token, params, oldParenthesizedCount;\n        if (matchKeyword('yield')) {\n            return parseYieldExpression();\n        }\n        oldParenthesizedCount = state.parenthesizedCount;\n        if (match('(')) {\n            token = lookahead2();\n            if (token.type === Token.Punctuator && token.value === ')' || token.value === '...') {\n                params = parseParams();\n                if (!match('=>')) {\n                    throwUnexpected(lex());\n                }\n                return parseArrowFunctionExpression(params);\n            }\n        }\n        token = lookahead;\n        expr = parseConditionalExpression();\n        if (match('=>') && (state.parenthesizedCount === oldParenthesizedCount || state.parenthesizedCount === oldParenthesizedCount + 1)) {\n            if (expr.type === Syntax.Identifier) {\n                params = reinterpretAsCoverFormalsList([expr]);\n            } else if (expr.type === Syntax.SequenceExpression) {\n                params = reinterpretAsCoverFormalsList(expr.expressions);\n            }\n            if (params) {\n                return parseArrowFunctionExpression(params);\n            }\n        }\n        if (matchAssign()) {\n            // 11.13.1\n            if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {\n                throwErrorTolerant(token, Messages.StrictLHSAssignment);\n            }\n            // ES.next draf 11.13 Runtime Semantics step 1\n            if (match('=') && (expr.type === Syntax.ObjectExpression || expr.type === Syntax.ArrayExpression)) {\n                reinterpretAsAssignmentBindingPattern(expr);\n            } else if (!isLeftHandSide(expr)) {\n                throwError({}, Messages.InvalidLHSInAssignment);\n            }\n            expr = delegate.createAssignmentExpression(lex().value, expr, parseAssignmentExpression());\n        }\n        return expr;\n    }\n    // 11.14 Comma Operator\n    function parseExpression() {\n        var expr, expressions, sequence, coverFormalsList, spreadFound, oldParenthesizedCount;\n        oldParenthesizedCount = state.parenthesizedCount;\n        expr = parseAssignmentExpression();\n        expressions = [expr];\n        if (match(',')) {\n            while (streamIndex < length) {\n                if (!match(',')) {\n                    break;\n                }\n                lex();\n                expr = parseSpreadOrAssignmentExpression();\n                expressions.push(expr);\n                if (expr.type === Syntax.SpreadElement) {\n                    spreadFound = true;\n                    if (!match(')')) {\n                        throwError({}, Messages.ElementAfterSpreadElement);\n                    }\n                    break;\n                }\n            }\n            sequence = delegate.createSequenceExpression(expressions);\n        }\n        if (match('=>')) {\n            // Do not allow nested parentheses on the LHS of the =>.\n            if (state.parenthesizedCount === oldParenthesizedCount || state.parenthesizedCount === oldParenthesizedCount + 1) {\n                expr = expr.type === Syntax.SequenceExpression ? expr.expressions : expressions;\n                coverFormalsList = reinterpretAsCoverFormalsList(expr);\n                if (coverFormalsList) {\n                    return parseArrowFunctionExpression(coverFormalsList);\n                }\n            }\n            throwUnexpected(lex());\n        }\n        if (spreadFound && lookahead2().value !== '=>') {\n            throwError({}, Messages.IllegalSpread);\n        }\n        return sequence || expr;\n    }\n    // 12.1 Block\n    function parseStatementList() {\n        var list = [], statement;\n        while (streamIndex < length) {\n            if (match('}')) {\n                break;\n            }\n            statement = parseSourceElement();\n            if (typeof statement === 'undefined') {\n                break;\n            }\n            list.push(statement);\n        }\n        return list;\n    }\n    function parseBlock() {\n        var block;\n        expect('{');\n        block = parseStatementList();\n        expect('}');\n        return delegate.createBlockStatement(block);\n    }\n    // 12.2 Variable Statement\n    function parseVariableIdentifier() {\n        var token = lookahead, resolvedIdent;\n        if (token.type !== Token.Identifier) {\n            throwUnexpected(token);\n        }\n        resolvedIdent = expander.resolve(tokenStream[lookaheadIndex]);\n        lex();\n        return delegate.createIdentifier(resolvedIdent);\n    }\n    function parseVariableDeclaration(kind) {\n        var id, init = null;\n        if (match('{')) {\n            id = parseObjectInitialiser();\n            reinterpretAsAssignmentBindingPattern(id);\n        } else if (match('[')) {\n            id = parseArrayInitialiser();\n            reinterpretAsAssignmentBindingPattern(id);\n        } else {\n            id = state.allowKeyword ? parseNonComputedProperty() : parseVariableIdentifier();\n            // 12.2.1\n            if (strict && isRestrictedWord(id.name)) {\n                throwErrorTolerant({}, Messages.StrictVarName);\n            }\n        }\n        if (kind === 'const') {\n            if (!match('=')) {\n                throwError({}, Messages.NoUnintializedConst);\n            }\n            expect('=');\n            init = parseAssignmentExpression();\n        } else if (match('=')) {\n            lex();\n            init = parseAssignmentExpression();\n        }\n        return delegate.createVariableDeclarator(id, init);\n    }\n    function parseVariableDeclarationList(kind) {\n        var list = [];\n        do {\n            list.push(parseVariableDeclaration(kind));\n            if (!match(',')) {\n                break;\n            }\n            lex();\n        } while (streamIndex < length);\n        return list;\n    }\n    function parseVariableStatement() {\n        var declarations;\n        expectKeyword('var');\n        declarations = parseVariableDeclarationList();\n        consumeSemicolon();\n        return delegate.createVariableDeclaration(declarations, 'var');\n    }\n    // kind may be `const` or `let`\n    // Both are experimental and not in the specification yet.\n    // see http://wiki.ecmascript.org/doku.php?id=harmony:const\n    // and http://wiki.ecmascript.org/doku.php?id=harmony:let\n    function parseConstLetDeclaration(kind) {\n        var declarations;\n        expectKeyword(kind);\n        declarations = parseVariableDeclarationList(kind);\n        consumeSemicolon();\n        return delegate.createVariableDeclaration(declarations, kind);\n    }\n    // http://wiki.ecmascript.org/doku.php?id=harmony:modules\n    function parseModuleDeclaration() {\n        var id, src, body;\n        lex();\n        // 'module'\n        if (peekLineTerminator()) {\n            throwError({}, Messages.NewlineAfterModule);\n        }\n        switch (lookahead.type) {\n        case Token.StringLiteral:\n            id = parsePrimaryExpression();\n            body = parseModuleBlock();\n            src = null;\n            break;\n        case Token.Identifier:\n            id = parseVariableIdentifier();\n            body = null;\n            if (!matchContextualKeyword('from')) {\n                throwUnexpected(lex());\n            }\n            lex();\n            src = parsePrimaryExpression();\n            if (src.type !== Syntax.Literal) {\n                throwError({}, Messages.InvalidModuleSpecifier);\n            }\n            break;\n        }\n        consumeSemicolon();\n        return delegate.createModuleDeclaration(id, src, body);\n    }\n    function parseExportBatchSpecifier() {\n        expect('*');\n        return delegate.createExportBatchSpecifier();\n    }\n    function parseExportSpecifier() {\n        var id, name = null;\n        id = parseVariableIdentifier();\n        if (matchContextualKeyword('as')) {\n            lex();\n            name = parseNonComputedProperty();\n        }\n        return delegate.createExportSpecifier(id, name);\n    }\n    function parseExportDeclaration() {\n        var previousAllowKeyword, decl, def, src, specifiers;\n        expectKeyword('export');\n        if (lookahead.type === Token.Keyword) {\n            switch (lookahead.value) {\n            case 'let':\n            case 'const':\n            case 'var':\n            case 'class':\n            case 'function':\n                return delegate.createExportDeclaration(parseSourceElement(), null, null);\n            }\n        }\n        if (isIdentifierName(lookahead)) {\n            previousAllowKeyword = state.allowKeyword;\n            state.allowKeyword = true;\n            decl = parseVariableDeclarationList('let');\n            state.allowKeyword = previousAllowKeyword;\n            return delegate.createExportDeclaration(decl, null, null);\n        }\n        specifiers = [];\n        src = null;\n        if (match('*')) {\n            specifiers.push(parseExportBatchSpecifier());\n        } else {\n            expect('{');\n            do {\n                specifiers.push(parseExportSpecifier());\n            } while (match(',') && lex());\n            expect('}');\n        }\n        if (matchContextualKeyword('from')) {\n            lex();\n            src = parsePrimaryExpression();\n            if (src.type !== Syntax.Literal) {\n                throwError({}, Messages.InvalidModuleSpecifier);\n            }\n        }\n        consumeSemicolon();\n        return delegate.createExportDeclaration(null, specifiers, src);\n    }\n    function parseImportDeclaration() {\n        var specifiers, kind, src;\n        expectKeyword('import');\n        specifiers = [];\n        if (isIdentifierName(lookahead)) {\n            kind = 'default';\n            specifiers.push(parseImportSpecifier());\n            if (!matchContextualKeyword('from')) {\n                throwError({}, Messages.NoFromAfterImport);\n            }\n            lex();\n        } else if (match('{')) {\n            kind = 'named';\n            lex();\n            do {\n                specifiers.push(parseImportSpecifier());\n            } while (match(',') && lex());\n            expect('}');\n            if (!matchContextualKeyword('from')) {\n                throwError({}, Messages.NoFromAfterImport);\n            }\n            lex();\n        }\n        src = parsePrimaryExpression();\n        if (src.type !== Syntax.Literal) {\n            throwError({}, Messages.InvalidModuleSpecifier);\n        }\n        consumeSemicolon();\n        return delegate.createImportDeclaration(specifiers, kind, src);\n    }\n    function parseImportSpecifier() {\n        var id, name = null;\n        id = parseNonComputedProperty();\n        if (matchContextualKeyword('as')) {\n            lex();\n            name = parseVariableIdentifier();\n        }\n        return delegate.createImportSpecifier(id, name);\n    }\n    // 12.3 Empty Statement\n    function parseEmptyStatement() {\n        expect(';');\n        return delegate.createEmptyStatement();\n    }\n    // 12.4 Expression Statement\n    function parseExpressionStatement() {\n        var expr = parseExpression();\n        consumeSemicolon();\n        return delegate.createExpressionStatement(expr);\n    }\n    // 12.5 If statement\n    function parseIfStatement() {\n        var test, consequent, alternate;\n        expectKeyword('if');\n        expect('(');\n        test = parseExpression();\n        expect(')');\n        consequent = parseStatement();\n        if (matchKeyword('else')) {\n            lex();\n            alternate = parseStatement();\n        } else {\n            alternate = null;\n        }\n        return delegate.createIfStatement(test, consequent, alternate);\n    }\n    // 12.6 Iteration Statements\n    function parseDoWhileStatement() {\n        var body, test, oldInIteration;\n        expectKeyword('do');\n        oldInIteration = state.inIteration;\n        state.inIteration = true;\n        body = parseStatement();\n        state.inIteration = oldInIteration;\n        expectKeyword('while');\n        expect('(');\n        test = parseExpression();\n        expect(')');\n        if (match(';')) {\n            lex();\n        }\n        return delegate.createDoWhileStatement(body, test);\n    }\n    function parseWhileStatement() {\n        var test, body, oldInIteration;\n        expectKeyword('while');\n        expect('(');\n        test = parseExpression();\n        expect(')');\n        oldInIteration = state.inIteration;\n        state.inIteration = true;\n        body = parseStatement();\n        state.inIteration = oldInIteration;\n        return delegate.createWhileStatement(test, body);\n    }\n    function parseForVariableDeclaration() {\n        var token = lex(), declarations = parseVariableDeclarationList();\n        return delegate.createVariableDeclaration(declarations, token.value);\n    }\n    function parseForStatement(opts) {\n        var init, test, update, left, right, body, operator, oldInIteration;\n        init = test = update = null;\n        expectKeyword('for');\n        // http://wiki.ecmascript.org/doku.php?id=proposals:iterators_and_generators&s=each\n        if (matchContextualKeyword('each')) {\n            throwError({}, Messages.EachNotAllowed);\n        }\n        expect('(');\n        if (match(';')) {\n            lex();\n        } else {\n            if (matchKeyword('var') || matchKeyword('let') || matchKeyword('const')) {\n                state.allowIn = false;\n                init = parseForVariableDeclaration();\n                state.allowIn = true;\n                if (init.declarations.length === 1) {\n                    if (matchKeyword('in') || matchContextualKeyword('of')) {\n                        operator = lookahead;\n                        if (!((operator.value === 'in' || init.kind !== 'var') && init.declarations[0].init)) {\n                            lex();\n                            left = init;\n                            right = parseExpression();\n                            init = null;\n                        }\n                    }\n                }\n            } else {\n                state.allowIn = false;\n                init = parseExpression();\n                state.allowIn = true;\n                if (matchContextualKeyword('of')) {\n                    operator = lex();\n                    left = init;\n                    right = parseExpression();\n                    init = null;\n                } else if (matchKeyword('in')) {\n                    // LeftHandSideExpression\n                    if (!isAssignableLeftHandSide(init)) {\n                        throwError({}, Messages.InvalidLHSInForIn);\n                    }\n                    operator = lex();\n                    left = init;\n                    right = parseExpression();\n                    init = null;\n                }\n            }\n            if (typeof left === 'undefined') {\n                expect(';');\n            }\n        }\n        if (typeof left === 'undefined') {\n            if (!match(';')) {\n                test = parseExpression();\n            }\n            expect(';');\n            if (!match(')')) {\n                update = parseExpression();\n            }\n        }\n        expect(')');\n        oldInIteration = state.inIteration;\n        state.inIteration = true;\n        if (!(opts !== undefined && opts.ignoreBody)) {\n            body = parseStatement();\n        }\n        state.inIteration = oldInIteration;\n        if (typeof left === 'undefined') {\n            return delegate.createForStatement(init, test, update, body);\n        }\n        if (operator.value === 'in') {\n            return delegate.createForInStatement(left, right, body);\n        }\n        return delegate.createForOfStatement(left, right, body);\n    }\n    // 12.7 The continue statement\n    function parseContinueStatement() {\n        var label = null, key;\n        expectKeyword('continue');\n        // Optimize the most common form: 'continue;'.\n        if (lookahead.value.charCodeAt(0) === 59) {\n            lex();\n            if (!state.inIteration) {\n                throwError({}, Messages.IllegalContinue);\n            }\n            return delegate.createContinueStatement(null);\n        }\n        if (peekLineTerminator()) {\n            if (!state.inIteration) {\n                throwError({}, Messages.IllegalContinue);\n            }\n            return delegate.createContinueStatement(null);\n        }\n        if (lookahead.type === Token.Identifier) {\n            label = parseVariableIdentifier();\n            key = '$' + label.name;\n            if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {\n                throwError({}, Messages.UnknownLabel, label.name);\n            }\n        }\n        consumeSemicolon();\n        if (label === null && !state.inIteration) {\n            throwError({}, Messages.IllegalContinue);\n        }\n        return delegate.createContinueStatement(label);\n    }\n    // 12.8 The break statement\n    function parseBreakStatement() {\n        var label = null, key;\n        expectKeyword('break');\n        // Catch the very common case first: immediately a semicolon (char #59).\n        if (lookahead.value.charCodeAt(0) === 59) {\n            lex();\n            if (!(state.inIteration || state.inSwitch)) {\n                throwError({}, Messages.IllegalBreak);\n            }\n            return delegate.createBreakStatement(null);\n        }\n        if (peekLineTerminator()) {\n            if (!(state.inIteration || state.inSwitch)) {\n                throwError({}, Messages.IllegalBreak);\n            }\n            return delegate.createBreakStatement(null);\n        }\n        if (lookahead.type === Token.Identifier) {\n            label = parseVariableIdentifier();\n            key = '$' + label.name;\n            if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {\n                throwError({}, Messages.UnknownLabel, label.name);\n            }\n        }\n        consumeSemicolon();\n        if (label === null && !(state.inIteration || state.inSwitch)) {\n            throwError({}, Messages.IllegalBreak);\n        }\n        return delegate.createBreakStatement(label);\n    }\n    // 12.9 The return statement\n    function parseReturnStatement() {\n        var argument = null;\n        expectKeyword('return');\n        if (!state.inFunctionBody) {\n            throwErrorTolerant({}, Messages.IllegalReturn);\n        }\n        // 'return' followed by a space and an identifier is very common.\n        if (isIdentifierStart(String(lookahead.value).charCodeAt(0))) {\n            argument = parseExpression();\n            consumeSemicolon();\n            return delegate.createReturnStatement(argument);\n        }\n        if (peekLineTerminator()) {\n            return delegate.createReturnStatement(null);\n        }\n        if (!match(';')) {\n            if (!match('}') && lookahead.type !== Token.EOF) {\n                argument = parseExpression();\n            }\n        }\n        consumeSemicolon();\n        return delegate.createReturnStatement(argument);\n    }\n    // 12.10 The with statement\n    function parseWithStatement() {\n        var object, body;\n        if (strict) {\n            throwErrorTolerant({}, Messages.StrictModeWith);\n        }\n        expectKeyword('with');\n        expect('(');\n        object = parseExpression();\n        expect(')');\n        body = parseStatement();\n        return delegate.createWithStatement(object, body);\n    }\n    // 12.10 The swith statement\n    function parseSwitchCase() {\n        var test, consequent = [], sourceElement;\n        if (matchKeyword('default')) {\n            lex();\n            test = null;\n        } else {\n            expectKeyword('case');\n            test = parseExpression();\n        }\n        expect(':');\n        while (streamIndex < length) {\n            if (match('}') || matchKeyword('default') || matchKeyword('case')) {\n                break;\n            }\n            sourceElement = parseSourceElement();\n            if (typeof sourceElement === 'undefined') {\n                break;\n            }\n            consequent.push(sourceElement);\n        }\n        return delegate.createSwitchCase(test, consequent);\n    }\n    function parseSwitchStatement() {\n        var discriminant, cases, clause, oldInSwitch, defaultFound;\n        expectKeyword('switch');\n        expect('(');\n        discriminant = parseExpression();\n        expect(')');\n        expect('{');\n        cases = [];\n        if (match('}')) {\n            lex();\n            return delegate.createSwitchStatement(discriminant, cases);\n        }\n        oldInSwitch = state.inSwitch;\n        state.inSwitch = true;\n        defaultFound = false;\n        while (streamIndex < length) {\n            if (match('}')) {\n                break;\n            }\n            clause = parseSwitchCase();\n            if (clause.test === null) {\n                if (defaultFound) {\n                    throwError({}, Messages.MultipleDefaultsInSwitch);\n                }\n                defaultFound = true;\n            }\n            cases.push(clause);\n        }\n        state.inSwitch = oldInSwitch;\n        expect('}');\n        return delegate.createSwitchStatement(discriminant, cases);\n    }\n    // 12.13 The throw statement\n    function parseThrowStatement() {\n        var argument;\n        expectKeyword('throw');\n        if (peekLineTerminator()) {\n            throwError({}, Messages.NewlineAfterThrow);\n        }\n        argument = parseExpression();\n        consumeSemicolon();\n        return delegate.createThrowStatement(argument);\n    }\n    // 12.14 The try statement\n    function parseCatchClause() {\n        var param, body;\n        expectKeyword('catch');\n        expect('(');\n        if (match(')')) {\n            throwUnexpected(lookahead);\n        }\n        param = parseExpression();\n        // 12.14.1\n        if (strict && param.type === Syntax.Identifier && isRestrictedWord(param.name)) {\n            throwErrorTolerant({}, Messages.StrictCatchVariable);\n        }\n        expect(')');\n        body = parseBlock();\n        return delegate.createCatchClause(param, body);\n    }\n    function parseTryStatement() {\n        var block, handlers = [], finalizer = null;\n        expectKeyword('try');\n        block = parseBlock();\n        if (matchKeyword('catch')) {\n            handlers.push(parseCatchClause());\n        }\n        if (matchKeyword('finally')) {\n            lex();\n            finalizer = parseBlock();\n        }\n        if (handlers.length === 0 && !finalizer) {\n            throwError({}, Messages.NoCatchOrFinally);\n        }\n        return delegate.createTryStatement(block, [], handlers, finalizer);\n    }\n    // 12.15 The debugger statement\n    function parseDebuggerStatement() {\n        expectKeyword('debugger');\n        consumeSemicolon();\n        return delegate.createDebuggerStatement();\n    }\n    // 12 Statements\n    function parseStatement() {\n        var type = lookahead.type, expr, labeledBody, key;\n        if (type === Token.EOF) {\n            throwUnexpected(lookahead);\n        }\n        if (type === Token.Punctuator) {\n            switch (lookahead.value) {\n            case ';':\n                return parseEmptyStatement();\n            case '{':\n                return parseBlock();\n            case '(':\n                return parseExpressionStatement();\n            default:\n                break;\n            }\n        }\n        if (type === Token.Keyword) {\n            switch (lookahead.value) {\n            case 'break':\n                return parseBreakStatement();\n            case 'continue':\n                return parseContinueStatement();\n            case 'debugger':\n                return parseDebuggerStatement();\n            case 'do':\n                return parseDoWhileStatement();\n            case 'for':\n                return parseForStatement();\n            case 'function':\n                return parseFunctionDeclaration();\n            case 'class':\n                return parseClassDeclaration();\n            case 'if':\n                return parseIfStatement();\n            case 'return':\n                return parseReturnStatement();\n            case 'switch':\n                return parseSwitchStatement();\n            case 'throw':\n                return parseThrowStatement();\n            case 'try':\n                return parseTryStatement();\n            case 'var':\n                return parseVariableStatement();\n            case 'while':\n                return parseWhileStatement();\n            case 'with':\n                return parseWithStatement();\n            default:\n                break;\n            }\n        }\n        expr = parseExpression();\n        // 12.12 Labelled Statements\n        if (expr.type === Syntax.Identifier && match(':')) {\n            lex();\n            key = '$' + expr.name;\n            if (Object.prototype.hasOwnProperty.call(state.labelSet, key)) {\n                throwError({}, Messages.Redeclaration, 'Label', expr.name);\n            }\n            state.labelSet[key] = true;\n            labeledBody = parseStatement();\n            delete state.labelSet[key];\n            return delegate.createLabeledStatement(expr, labeledBody);\n        }\n        consumeSemicolon();\n        return delegate.createExpressionStatement(expr);\n    }\n    // 13 Function Definition\n    function parseConciseBody() {\n        if (match('{')) {\n            return parseFunctionSourceElements();\n        }\n        return parseAssignmentExpression();\n    }\n    function parseFunctionSourceElements() {\n        var sourceElement, sourceElements = [], token, directive, firstRestricted, oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody, oldParenthesizedCount;\n        expect('{');\n        while (streamIndex < length) {\n            if (lookahead.type !== Token.StringLiteral) {\n                break;\n            }\n            token = lookahead;\n            sourceElement = parseSourceElement();\n            sourceElements.push(sourceElement);\n            if (sourceElement.expression.type !== Syntax.Literal) {\n                // this is not directive\n                break;\n            }\n            directive = token.value;\n            if (directive === 'use strict') {\n                strict = true;\n                if (firstRestricted) {\n                    throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);\n                }\n            } else {\n                if (!firstRestricted && token.octal) {\n                    firstRestricted = token;\n                }\n            }\n        }\n        oldLabelSet = state.labelSet;\n        oldInIteration = state.inIteration;\n        oldInSwitch = state.inSwitch;\n        oldInFunctionBody = state.inFunctionBody;\n        oldParenthesizedCount = state.parenthesizedCount;\n        state.labelSet = {};\n        state.inIteration = false;\n        state.inSwitch = false;\n        state.inFunctionBody = true;\n        state.parenthesizedCount = 0;\n        while (streamIndex < length) {\n            if (match('}')) {\n                break;\n            }\n            sourceElement = parseSourceElement();\n            if (typeof sourceElement === 'undefined') {\n                break;\n            }\n            sourceElements.push(sourceElement);\n        }\n        expect('}');\n        state.labelSet = oldLabelSet;\n        state.inIteration = oldInIteration;\n        state.inSwitch = oldInSwitch;\n        state.inFunctionBody = oldInFunctionBody;\n        state.parenthesizedCount = oldParenthesizedCount;\n        return delegate.createBlockStatement(sourceElements);\n    }\n    function validateParam(options, param, name) {\n        var key = '$' + name;\n        if (strict) {\n            if (isRestrictedWord(name)) {\n                options.stricted = param;\n                options.message = Messages.StrictParamName;\n            }\n            if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {\n                options.stricted = param;\n                options.message = Messages.StrictParamDupe;\n            }\n        } else if (!options.firstRestricted) {\n            if (isRestrictedWord(name)) {\n                options.firstRestricted = param;\n                options.message = Messages.StrictParamName;\n            } else if (isStrictModeReservedWord(name)) {\n                options.firstRestricted = param;\n                options.message = Messages.StrictReservedWord;\n            } else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) {\n                options.firstRestricted = param;\n                options.message = Messages.StrictParamDupe;\n            }\n        }\n        options.paramSet[key] = true;\n    }\n    function parseParam(options) {\n        var token, rest, param, def;\n        token = lookahead;\n        if (token.value === '...') {\n            token = lex();\n            rest = true;\n        }\n        if (match('[')) {\n            param = parseArrayInitialiser();\n            reinterpretAsDestructuredParameter(options, param);\n        } else if (match('{')) {\n            if (rest) {\n                throwError({}, Messages.ObjectPatternAsRestParameter);\n            }\n            param = parseObjectInitialiser();\n            reinterpretAsDestructuredParameter(options, param);\n        } else {\n            param = parseVariableIdentifier();\n            validateParam(options, token, token.value);\n            if (match('=')) {\n                if (rest) {\n                    throwErrorTolerant(lookahead, Messages.DefaultRestParameter);\n                }\n                lex();\n                def = parseAssignmentExpression();\n                ++options.defaultCount;\n            }\n        }\n        if (rest) {\n            if (!match(')')) {\n                throwError({}, Messages.ParameterAfterRestParameter);\n            }\n            options.rest = param;\n            return false;\n        }\n        options.params.push(param);\n        options.defaults.push(def);\n        return !match(')');\n    }\n    function parseParams(firstRestricted) {\n        var options;\n        options = {\n            params: [],\n            defaultCount: 0,\n            defaults: [],\n            rest: null,\n            firstRestricted: firstRestricted\n        };\n        expect('(');\n        if (!match(')')) {\n            options.paramSet = {};\n            while (streamIndex < length) {\n                if (!parseParam(options)) {\n                    break;\n                }\n                expect(',');\n            }\n        }\n        expect(')');\n        if (options.defaultCount === 0) {\n            options.defaults = [];\n        }\n        return options;\n    }\n    function parseFunctionDeclaration() {\n        var id, body, token, tmp, firstRestricted, message, previousStrict, previousYieldAllowed, generator, expression;\n        expectKeyword('function');\n        generator = false;\n        if (match('*')) {\n            lex();\n            generator = true;\n        }\n        token = lookahead;\n        id = parseVariableIdentifier();\n        if (strict) {\n            if (isRestrictedWord(token.value)) {\n                throwErrorTolerant(token, Messages.StrictFunctionName);\n            }\n        } else {\n            if (isRestrictedWord(token.value)) {\n                firstRestricted = token;\n                message = Messages.StrictFunctionName;\n            } else if (isStrictModeReservedWord(token.value)) {\n                firstRestricted = token;\n                message = Messages.StrictReservedWord;\n            }\n        }\n        tmp = parseParams(firstRestricted);\n        firstRestricted = tmp.firstRestricted;\n        if (tmp.message) {\n            message = tmp.message;\n        }\n        previousStrict = strict;\n        previousYieldAllowed = state.yieldAllowed;\n        state.yieldAllowed = generator;\n        // here we redo some work in order to set 'expression'\n        expression = !match('{');\n        body = parseConciseBody();\n        if (strict && firstRestricted) {\n            throwError(firstRestricted, message);\n        }\n        if (strict && tmp.stricted) {\n            throwErrorTolerant(tmp.stricted, message);\n        }\n        if (state.yieldAllowed && !state.yieldFound) {\n            throwErrorTolerant({}, Messages.NoYieldInGenerator);\n        }\n        strict = previousStrict;\n        state.yieldAllowed = previousYieldAllowed;\n        return delegate.createFunctionDeclaration(id, tmp.params, tmp.defaults, body, tmp.rest, generator, expression);\n    }\n    function parseFunctionExpression() {\n        var token, id = null, firstRestricted, message, tmp, body, previousStrict, previousYieldAllowed, generator, expression;\n        expectKeyword('function');\n        generator = false;\n        if (match('*')) {\n            lex();\n            generator = true;\n        }\n        if (!match('(')) {\n            token = lookahead;\n            id = parseVariableIdentifier();\n            if (strict) {\n                if (isRestrictedWord(token.value)) {\n                    throwErrorTolerant(token, Messages.StrictFunctionName);\n                }\n            } else {\n                if (isRestrictedWord(token.value)) {\n                    firstRestricted = token;\n                    message = Messages.StrictFunctionName;\n                } else if (isStrictModeReservedWord(token.value)) {\n                    firstRestricted = token;\n                    message = Messages.StrictReservedWord;\n                }\n            }\n        }\n        tmp = parseParams(firstRestricted);\n        firstRestricted = tmp.firstRestricted;\n        if (tmp.message) {\n            message = tmp.message;\n        }\n        previousStrict = strict;\n        previousYieldAllowed = state.yieldAllowed;\n        state.yieldAllowed = generator;\n        // here we redo some work in order to set 'expression'\n        expression = !match('{');\n        body = parseConciseBody();\n        if (strict && firstRestricted) {\n            throwError(firstRestricted, message);\n        }\n        if (strict && tmp.stricted) {\n            throwErrorTolerant(tmp.stricted, message);\n        }\n        if (state.yieldAllowed && !state.yieldFound) {\n            throwErrorTolerant({}, Messages.NoYieldInGenerator);\n        }\n        strict = previousStrict;\n        state.yieldAllowed = previousYieldAllowed;\n        return delegate.createFunctionExpression(id, tmp.params, tmp.defaults, body, tmp.rest, generator, expression);\n    }\n    function parseYieldExpression() {\n        var delegateFlag, expr, previousYieldAllowed;\n        expectKeyword('yield');\n        if (!state.yieldAllowed) {\n            throwErrorTolerant({}, Messages.IllegalYield);\n        }\n        delegateFlag = false;\n        if (match('*')) {\n            lex();\n            delegateFlag = true;\n        }\n        // It is a Syntax Error if any AssignmentExpression Contains YieldExpression.\n        previousYieldAllowed = state.yieldAllowed;\n        state.yieldAllowed = false;\n        expr = parseAssignmentExpression();\n        state.yieldAllowed = previousYieldAllowed;\n        state.yieldFound = true;\n        return delegate.createYieldExpression(expr, delegateFlag);\n    }\n    // 14 Classes\n    function parseMethodDefinition(existingPropNames) {\n        var token, key, param, propType, isValidDuplicateProp = false;\n        if (lookahead.value === 'static') {\n            propType = ClassPropertyType.static;\n            lex();\n        } else {\n            propType = ClassPropertyType.prototype;\n        }\n        if (match('*')) {\n            lex();\n            return delegate.createMethodDefinition(propType, '', parseObjectPropertyKey(), parsePropertyMethodFunction({ generator: true }));\n        }\n        token = lookahead;\n        key = parseObjectPropertyKey();\n        if (token.value === 'get' && !match('(')) {\n            key = parseObjectPropertyKey();\n            // It is a syntax error if any other properties have a name\n            // duplicating this one unless they are a setter\n            if (existingPropNames[propType].hasOwnProperty(key.name)) {\n                isValidDuplicateProp = existingPropNames[propType][key.name].get === undefined && existingPropNames[propType][key.name].data === undefined && existingPropNames[propType][key.name].set !== undefined;\n                if (!isValidDuplicateProp) {\n                    throwError(key, Messages.IllegalDuplicateClassProperty);\n                }\n            } else {\n                existingPropNames[propType][key.name] = {};\n            }\n            existingPropNames[propType][key.name].get = true;\n            expect('(');\n            expect(')');\n            return delegate.createMethodDefinition(propType, 'get', key, parsePropertyFunction({ generator: false }));\n        }\n        if (token.value === 'set' && !match('(')) {\n            key = parseObjectPropertyKey();\n            // It is a syntax error if any other properties have a name\n            // duplicating this one unless they are a getter\n            if (existingPropNames[propType].hasOwnProperty(key.name)) {\n                isValidDuplicateProp = existingPropNames[propType][key.name].set === undefined && existingPropNames[propType][key.name].data === undefined && existingPropNames[propType][key.name].get !== undefined;\n                if (!isValidDuplicateProp) {\n                    throwError(key, Messages.IllegalDuplicateClassProperty);\n                }\n            } else {\n                existingPropNames[propType][key.name] = {};\n            }\n            existingPropNames[propType][key.name].set = true;\n            expect('(');\n            token = lookahead;\n            param = [parseVariableIdentifier()];\n            expect(')');\n            return delegate.createMethodDefinition(propType, 'set', key, parsePropertyFunction({\n                params: param,\n                generator: false,\n                name: token\n            }));\n        }\n        // It is a syntax error if any other properties have the same name as a\n        // non-getter, non-setter method\n        if (existingPropNames[propType].hasOwnProperty(key.name)) {\n            throwError(key, Messages.IllegalDuplicateClassProperty);\n        } else {\n            existingPropNames[propType][key.name] = {};\n        }\n        existingPropNames[propType][key.name].data = true;\n        return delegate.createMethodDefinition(propType, '', key, parsePropertyMethodFunction({ generator: false }));\n    }\n    function parseClassElement(existingProps) {\n        if (match(';')) {\n            lex();\n            return;\n        }\n        return parseMethodDefinition(existingProps);\n    }\n    function parseClassBody() {\n        var classElement, classElements = [], existingProps = {};\n        existingProps[ClassPropertyType.static] = {};\n        existingProps[ClassPropertyType.prototype] = {};\n        expect('{');\n        while (streamIndex < length) {\n            if (match('}')) {\n                break;\n            }\n            classElement = parseClassElement(existingProps);\n            if (typeof classElement !== 'undefined') {\n                classElements.push(classElement);\n            }\n        }\n        expect('}');\n        return delegate.createClassBody(classElements);\n    }\n    function parseClassExpression() {\n        var id, previousYieldAllowed, superClass = null;\n        expectKeyword('class');\n        if (!matchKeyword('extends') && !match('{')) {\n            id = parseVariableIdentifier();\n        }\n        if (matchKeyword('extends')) {\n            expectKeyword('extends');\n            previousYieldAllowed = state.yieldAllowed;\n            state.yieldAllowed = false;\n            superClass = parseAssignmentExpression();\n            state.yieldAllowed = previousYieldAllowed;\n        }\n        return delegate.createClassExpression(id, superClass, parseClassBody());\n    }\n    function parseClassDeclaration() {\n        var id, previousYieldAllowed, superClass = null;\n        expectKeyword('class');\n        id = parseVariableIdentifier();\n        if (matchKeyword('extends')) {\n            expectKeyword('extends');\n            previousYieldAllowed = state.yieldAllowed;\n            state.yieldAllowed = false;\n            superClass = parseAssignmentExpression();\n            state.yieldAllowed = previousYieldAllowed;\n        }\n        return delegate.createClassDeclaration(id, superClass, parseClassBody());\n    }\n    // 15 Program\n    function matchModuleDeclaration() {\n        var id;\n        if (matchContextualKeyword('module')) {\n            id = lookahead2();\n            return id.type === Token.StringLiteral || id.type === Token.Identifier;\n        }\n        return false;\n    }\n    function parseSourceElement() {\n        if (lookahead.type === Token.Keyword) {\n            switch (lookahead.value) {\n            case 'const':\n            case 'let':\n                return parseConstLetDeclaration(lookahead.value);\n            case 'function':\n                return parseFunctionDeclaration();\n            case 'export':\n                return parseExportDeclaration();\n            case 'import':\n                return parseImportDeclaration();\n            default:\n                return parseStatement();\n            }\n        }\n        if (matchModuleDeclaration()) {\n            throwError({}, Messages.NestedModule);\n        }\n        if (lookahead.type !== Token.EOF) {\n            return parseStatement();\n        }\n    }\n    function parseProgramElement() {\n        if (lookahead.type === Token.Keyword) {\n            switch (lookahead.value) {\n            case 'export':\n                return parseExportDeclaration();\n            case 'import':\n                return parseImportDeclaration();\n            }\n        }\n        if (matchModuleDeclaration()) {\n            return parseModuleDeclaration();\n        }\n        return parseSourceElement();\n    }\n    function parseProgramElements() {\n        var sourceElement, sourceElements = [], token, directive, firstRestricted;\n        while (streamIndex < length) {\n            token = lookahead;\n            if (token.type !== Token.StringLiteral) {\n                break;\n            }\n            sourceElement = parseProgramElement();\n            sourceElements.push(sourceElement);\n            if (sourceElement.expression.type !== Syntax.Literal) {\n                // this is not directive\n                break;\n            }\n            directive = token.value;\n            if (directive === 'use strict') {\n                strict = true;\n                if (firstRestricted) {\n                    throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);\n                }\n            } else {\n                if (!firstRestricted && token.octal) {\n                    firstRestricted = token;\n                }\n            }\n        }\n        while (streamIndex < length) {\n            sourceElement = parseProgramElement();\n            if (typeof sourceElement === 'undefined') {\n                break;\n            }\n            sourceElements.push(sourceElement);\n        }\n        return sourceElements;\n    }\n    function parseModuleElement() {\n        return parseSourceElement();\n    }\n    function parseModuleElements() {\n        var list = [], statement;\n        while (streamIndex < length) {\n            if (match('}')) {\n                break;\n            }\n            statement = parseModuleElement();\n            if (typeof statement === 'undefined') {\n                break;\n            }\n            list.push(statement);\n        }\n        return list;\n    }\n    function parseModuleBlock() {\n        var block;\n        expect('{');\n        block = parseModuleElements();\n        expect('}');\n        return delegate.createBlockStatement(block);\n    }\n    function parseProgram() {\n        var body;\n        strict = false;\n        peek();\n        body = parseProgramElements();\n        return delegate.createProgram(body);\n    }\n    // The following functions are needed only when the option to preserve\n    // the comments is active.\n    function addComment(type, value, start, end, loc) {\n        assert(typeof start === 'number', 'Comment must have valid position');\n        // Because the way the actual token is scanned, often the comments\n        // (if any) are skipped twice during the lexical analysis.\n        // Thus, we need to skip adding a comment if the comment array already\n        // handled it.\n        if (extra.comments.length > 0) {\n            if (extra.comments[extra.comments.length - 1].range[1] > start) {\n                return;\n            }\n        }\n        extra.comments.push({\n            type: type,\n            value: value,\n            range: [\n                start,\n                end\n            ],\n            loc: loc\n        });\n    }\n    function scanComment() {\n        var comment, ch, loc, start, blockComment, lineComment;\n        comment = '';\n        blockComment = false;\n        lineComment = false;\n        while (index < length) {\n            ch = source[index];\n            if (lineComment) {\n                ch = source[index++];\n                if (isLineTerminator(ch.charCodeAt(0))) {\n                    loc.end = {\n                        line: lineNumber,\n                        column: index - lineStart - 1\n                    };\n                    lineComment = false;\n                    addComment('Line', comment, start, index - 1, loc);\n                    if (ch === '\\r' && source[index] === '\\n') {\n                        ++index;\n                    }\n                    ++lineNumber;\n                    lineStart = index;\n                    comment = '';\n                } else if (index >= length) {\n                    lineComment = false;\n                    comment += ch;\n                    loc.end = {\n                        line: lineNumber,\n                        column: length - lineStart\n                    };\n                    addComment('Line', comment, start, length, loc);\n                } else {\n                    comment += ch;\n                }\n            } else if (blockComment) {\n                if (isLineTerminator(ch.charCodeAt(0))) {\n                    if (ch === '\\r' && source[index + 1] === '\\n') {\n                        ++index;\n                        comment += '\\r\\n';\n                    } else {\n                        comment += ch;\n                    }\n                    ++lineNumber;\n                    ++index;\n                    lineStart = index;\n                    if (index >= length) {\n                        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n                    }\n                } else {\n                    ch = source[index++];\n                    if (index >= length) {\n                        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n                    }\n                    comment += ch;\n                    if (ch === '*') {\n                        ch = source[index];\n                        if (ch === '/') {\n                            comment = comment.substr(0, comment.length - 1);\n                            blockComment = false;\n                            ++index;\n                            loc.end = {\n                                line: lineNumber,\n                                column: index - lineStart\n                            };\n                            addComment('Block', comment, start, index, loc);\n                            comment = '';\n                        }\n                    }\n                }\n            } else if (ch === '/') {\n                ch = source[index + 1];\n                if (ch === '/') {\n                    loc = {\n                        start: {\n                            line: lineNumber,\n                            column: index - lineStart\n                        }\n                    };\n                    start = index;\n                    index += 2;\n                    lineComment = true;\n                    if (index >= length) {\n                        loc.end = {\n                            line: lineNumber,\n                            column: index - lineStart\n                        };\n                        lineComment = false;\n                        addComment('Line', comment, start, index, loc);\n                    }\n                } else if (ch === '*') {\n                    start = index;\n                    index += 2;\n                    blockComment = true;\n                    loc = {\n                        start: {\n                            line: lineNumber,\n                            column: index - lineStart - 2\n                        }\n                    };\n                    if (index >= length) {\n                        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');\n                    }\n                } else {\n                    break;\n                }\n            } else if (isWhiteSpace(ch.charCodeAt(0))) {\n                ++index;\n            } else if (isLineTerminator(ch.charCodeAt(0))) {\n                ++index;\n                if (ch === '\\r' && source[index] === '\\n') {\n                    ++index;\n                }\n                ++lineNumber;\n                lineStart = index;\n            } else {\n                break;\n            }\n        }\n    }\n    function filterCommentLocation() {\n        var i, entry, comment, comments = [];\n        for (i = 0; i < extra.comments.length; ++i) {\n            entry = extra.comments[i];\n            comment = {\n                type: entry.type,\n                value: entry.value\n            };\n            if (extra.range) {\n                comment.range = entry.range;\n            }\n            if (extra.loc) {\n                comment.loc = entry.loc;\n            }\n            comments.push(comment);\n        }\n        extra.comments = comments;\n    }\n    function collectToken() {\n        var start, loc, token, range, value;\n        skipComment();\n        start = index;\n        loc = {\n            start: {\n                line: lineNumber,\n                column: index - lineStart\n            }\n        };\n        token = extra.advance();\n        loc.end = {\n            line: lineNumber,\n            column: index - lineStart\n        };\n        if (token.type !== Token.EOF) {\n            range = [\n                token.range[0],\n                token.range[1]\n            ];\n            value = source.slice(token.range[0], token.range[1]);\n            extra.tokens.push({\n                type: TokenName[token.type],\n                value: value,\n                range: range,\n                loc: loc\n            });\n        }\n        return token;\n    }\n    function collectRegex() {\n        var pos, loc, regex, token;\n        skipComment();\n        pos = index;\n        loc = {\n            start: {\n                line: lineNumber,\n                column: index - lineStart\n            }\n        };\n        regex = extra.scanRegExp();\n        loc.end = {\n            line: lineNumber,\n            column: index - lineStart\n        };\n        if (!extra.tokenize) {\n            // Pop the previous token, which is likely '/' or '/='\n            if (extra.tokens.length > 0) {\n                token = extra.tokens[extra.tokens.length - 1];\n                if (token.range[0] === pos && token.type === 'Punctuator') {\n                    if (token.value === '/' || token.value === '/=') {\n                        extra.tokens.pop();\n                    }\n                }\n            }\n            extra.tokens.push({\n                type: 'RegularExpression',\n                value: regex.literal,\n                range: [\n                    pos,\n                    index\n                ],\n                loc: loc\n            });\n        }\n        return regex;\n    }\n    function filterTokenLocation() {\n        var i, entry, token, tokens = [];\n        for (i = 0; i < extra.tokens.length; ++i) {\n            entry = extra.tokens[i];\n            token = {\n                type: entry.type,\n                value: entry.value\n            };\n            if (extra.range) {\n                token.range = entry.range;\n            }\n            if (extra.loc) {\n                token.loc = entry.loc;\n            }\n            tokens.push(token);\n        }\n        extra.tokens = tokens;\n    }\n    function LocationMarker() {\n        var sm_index$2 = lookahead ? lookahead.sm_range[0] : 0;\n        var sm_lineStart$2 = lookahead ? lookahead.sm_lineStart : 0;\n        var sm_lineNumber$2 = lookahead ? lookahead.sm_lineNumber : 1;\n        this.range = [\n            sm_index$2,\n            sm_index$2\n        ];\n        this.loc = {\n            start: {\n                line: sm_lineNumber$2,\n                column: sm_index$2 - sm_lineStart$2\n            },\n            end: {\n                line: sm_lineNumber$2,\n                column: sm_index$2 - sm_lineStart$2\n            }\n        };\n    }\n    LocationMarker.prototype = {\n        constructor: LocationMarker,\n        end: function () {\n            this.range[1] = sm_index;\n            this.loc.end.line = sm_lineNumber;\n            this.loc.end.column = sm_index - sm_lineStart;\n        },\n        applyGroup: function (node) {\n            if (extra.range) {\n                node.groupRange = [\n                    this.range[0],\n                    this.range[1]\n                ];\n            }\n            if (extra.loc) {\n                node.groupLoc = {\n                    start: {\n                        line: this.loc.start.line,\n                        column: this.loc.start.column\n                    },\n                    end: {\n                        line: this.loc.end.line,\n                        column: this.loc.end.column\n                    }\n                };\n                node = delegate.postProcess(node);\n            }\n        },\n        apply: function (node) {\n            var nodeType = typeof node;\n            assert(nodeType === 'object', 'Applying location marker to an unexpected node type: ' + nodeType);\n            if (extra.range) {\n                node.range = [\n                    this.range[0],\n                    this.range[1]\n                ];\n            }\n            if (extra.loc) {\n                node.loc = {\n                    start: {\n                        line: this.loc.start.line,\n                        column: this.loc.start.column\n                    },\n                    end: {\n                        line: this.loc.end.line,\n                        column: this.loc.end.column\n                    }\n                };\n                node = delegate.postProcess(node);\n            }\n        }\n    };\n    function createLocationMarker() {\n        return new LocationMarker();\n    }\n    function trackGroupExpression() {\n        var marker, expr;\n        marker = createLocationMarker();\n        expect('(');\n        ++state.parenthesizedCount;\n        expr = parseExpression();\n        expect(')');\n        marker.end();\n        marker.applyGroup(expr);\n        return expr;\n    }\n    function trackLeftHandSideExpression() {\n        var marker, expr;\n        // skipComment();\n        marker = createLocationMarker();\n        expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();\n        while (match('.') || match('[') || lookahead.type === Token.Template) {\n            if (match('[')) {\n                expr = delegate.createMemberExpression('[', expr, parseComputedMember());\n                marker.end();\n                marker.apply(expr);\n            } else if (match('.')) {\n                expr = delegate.createMemberExpression('.', expr, parseNonComputedMember());\n                marker.end();\n                marker.apply(expr);\n            } else {\n                expr = delegate.createTaggedTemplateExpression(expr, parseTemplateLiteral());\n                marker.end();\n                marker.apply(expr);\n            }\n        }\n        return expr;\n    }\n    function trackLeftHandSideExpressionAllowCall() {\n        var marker, expr, args;\n        // skipComment();\n        marker = createLocationMarker();\n        expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();\n        while (match('.') || match('[') || match('(') || lookahead.type === Token.Template) {\n            if (match('(')) {\n                args = parseArguments();\n                expr = delegate.createCallExpression(expr, args);\n                marker.end();\n                marker.apply(expr);\n            } else if (match('[')) {\n                expr = delegate.createMemberExpression('[', expr, parseComputedMember());\n                marker.end();\n                marker.apply(expr);\n            } else if (match('.')) {\n                expr = delegate.createMemberExpression('.', expr, parseNonComputedMember());\n                marker.end();\n                marker.apply(expr);\n            } else {\n                expr = delegate.createTaggedTemplateExpression(expr, parseTemplateLiteral());\n                marker.end();\n                marker.apply(expr);\n            }\n        }\n        return expr;\n    }\n    function filterGroup(node) {\n        var n, i, entry;\n        n = Object.prototype.toString.apply(node) === '[object Array]' ? [] : {};\n        for (i in node) {\n            if (node.hasOwnProperty(i) && i !== 'groupRange' && i !== 'groupLoc') {\n                entry = node[i];\n                if (entry === null || typeof entry !== 'object' || entry instanceof RegExp) {\n                    n[i] = entry;\n                } else {\n                    n[i] = filterGroup(entry);\n                }\n            }\n        }\n        return n;\n    }\n    function wrapTrackingFunction(range, loc) {\n        return function (parseFunction) {\n            function isBinary(node) {\n                return node.type === Syntax.LogicalExpression || node.type === Syntax.BinaryExpression;\n            }\n            function visit(node) {\n                var start, end;\n                if (isBinary(node.left)) {\n                    visit(node.left);\n                }\n                if (isBinary(node.right)) {\n                    visit(node.right);\n                }\n                if (range) {\n                    if (node.left.groupRange || node.right.groupRange) {\n                        start = node.left.groupRange ? node.left.groupRange[0] : node.left.range[0];\n                        end = node.right.groupRange ? node.right.groupRange[1] : node.right.range[1];\n                        node.range = [\n                            start,\n                            end\n                        ];\n                    } else if (typeof node.range === 'undefined') {\n                        start = node.left.range[0];\n                        end = node.right.range[1];\n                        node.range = [\n                            start,\n                            end\n                        ];\n                    }\n                }\n                if (loc) {\n                    if (node.left.groupLoc || node.right.groupLoc) {\n                        start = node.left.groupLoc ? node.left.groupLoc.start : node.left.loc.start;\n                        end = node.right.groupLoc ? node.right.groupLoc.end : node.right.loc.end;\n                        node.loc = {\n                            start: start,\n                            end: end\n                        };\n                        node = delegate.postProcess(node);\n                    } else if (typeof node.loc === 'undefined') {\n                        node.loc = {\n                            start: node.left.loc.start,\n                            end: node.right.loc.end\n                        };\n                        node = delegate.postProcess(node);\n                    }\n                }\n            }\n            return function () {\n                var marker, node, curr = lookahead;\n                marker = createLocationMarker();\n                node = parseFunction.apply(null, arguments);\n                marker.end();\n                if (node.type !== Syntax.Program) {\n                    if (curr.leadingComments) {\n                        node.leadingComments = curr.leadingComments;\n                    }\n                    if (curr.trailingComments) {\n                        node.trailingComments = curr.trailingComments;\n                    }\n                }\n                if (range && typeof node.range === 'undefined') {\n                    marker.apply(node);\n                }\n                if (loc && typeof node.loc === 'undefined') {\n                    marker.apply(node);\n                }\n                if (isBinary(node)) {\n                    visit(node);\n                }\n                return node;\n            };\n        };\n    }\n    function patch() {\n        var wrapTracking;\n        if (extra.comments) {\n            extra.skipComment = skipComment;\n            skipComment = scanComment;\n        }\n        if (extra.range || extra.loc) {\n            extra.parseGroupExpression = parseGroupExpression;\n            extra.parseLeftHandSideExpression = parseLeftHandSideExpression;\n            extra.parseLeftHandSideExpressionAllowCall = parseLeftHandSideExpressionAllowCall;\n            parseGroupExpression = trackGroupExpression;\n            parseLeftHandSideExpression = trackLeftHandSideExpression;\n            parseLeftHandSideExpressionAllowCall = trackLeftHandSideExpressionAllowCall;\n            wrapTracking = wrapTrackingFunction(extra.range, extra.loc);\n            extra.parseArrayInitialiser = parseArrayInitialiser;\n            extra.parseAssignmentExpression = parseAssignmentExpression;\n            extra.parseBinaryExpression = parseBinaryExpression;\n            extra.parseBlock = parseBlock;\n            extra.parseFunctionSourceElements = parseFunctionSourceElements;\n            extra.parseCatchClause = parseCatchClause;\n            extra.parseComputedMember = parseComputedMember;\n            extra.parseConditionalExpression = parseConditionalExpression;\n            extra.parseConstLetDeclaration = parseConstLetDeclaration;\n            extra.parseExportBatchSpecifier = parseExportBatchSpecifier;\n            extra.parseExportDeclaration = parseExportDeclaration;\n            extra.parseExportSpecifier = parseExportSpecifier;\n            extra.parseExpression = parseExpression;\n            extra.parseForVariableDeclaration = parseForVariableDeclaration;\n            extra.parseFunctionDeclaration = parseFunctionDeclaration;\n            extra.parseFunctionExpression = parseFunctionExpression;\n            extra.parseParams = parseParams;\n            extra.parseImportDeclaration = parseImportDeclaration;\n            extra.parseImportSpecifier = parseImportSpecifier;\n            extra.parseModuleDeclaration = parseModuleDeclaration;\n            extra.parseModuleBlock = parseModuleBlock;\n            extra.parseNewExpression = parseNewExpression;\n            extra.parseNonComputedProperty = parseNonComputedProperty;\n            extra.parseObjectInitialiser = parseObjectInitialiser;\n            extra.parseObjectProperty = parseObjectProperty;\n            extra.parseObjectPropertyKey = parseObjectPropertyKey;\n            extra.parsePostfixExpression = parsePostfixExpression;\n            extra.parsePrimaryExpression = parsePrimaryExpression;\n            extra.parseProgram = parseProgram;\n            extra.parsePropertyFunction = parsePropertyFunction;\n            extra.parseSpreadOrAssignmentExpression = parseSpreadOrAssignmentExpression;\n            extra.parseTemplateElement = parseTemplateElement;\n            extra.parseTemplateLiteral = parseTemplateLiteral;\n            extra.parseStatement = parseStatement;\n            extra.parseSwitchCase = parseSwitchCase;\n            extra.parseUnaryExpression = parseUnaryExpression;\n            extra.parseVariableDeclaration = parseVariableDeclaration;\n            extra.parseVariableIdentifier = parseVariableIdentifier;\n            extra.parseMethodDefinition = parseMethodDefinition;\n            extra.parseClassDeclaration = parseClassDeclaration;\n            extra.parseClassExpression = parseClassExpression;\n            extra.parseClassBody = parseClassBody;\n            parseArrayInitialiser = wrapTracking(extra.parseArrayInitialiser);\n            parseAssignmentExpression = wrapTracking(extra.parseAssignmentExpression);\n            parseBinaryExpression = wrapTracking(extra.parseBinaryExpression);\n            parseBlock = wrapTracking(extra.parseBlock);\n            parseFunctionSourceElements = wrapTracking(extra.parseFunctionSourceElements);\n            parseCatchClause = wrapTracking(extra.parseCatchClause);\n            parseComputedMember = wrapTracking(extra.parseComputedMember);\n            parseConditionalExpression = wrapTracking(extra.parseConditionalExpression);\n            parseConstLetDeclaration = wrapTracking(extra.parseConstLetDeclaration);\n            parseExportBatchSpecifier = wrapTracking(parseExportBatchSpecifier);\n            parseExportDeclaration = wrapTracking(parseExportDeclaration);\n            parseExportSpecifier = wrapTracking(parseExportSpecifier);\n            parseExpression = wrapTracking(extra.parseExpression);\n            parseForVariableDeclaration = wrapTracking(extra.parseForVariableDeclaration);\n            parseFunctionDeclaration = wrapTracking(extra.parseFunctionDeclaration);\n            parseFunctionExpression = wrapTracking(extra.parseFunctionExpression);\n            parseParams = wrapTracking(extra.parseParams);\n            parseImportDeclaration = wrapTracking(extra.parseImportDeclaration);\n            parseImportSpecifier = wrapTracking(extra.parseImportSpecifier);\n            parseModuleDeclaration = wrapTracking(extra.parseModuleDeclaration);\n            parseModuleBlock = wrapTracking(extra.parseModuleBlock);\n            parseLeftHandSideExpression = wrapTracking(parseLeftHandSideExpression);\n            parseNewExpression = wrapTracking(extra.parseNewExpression);\n            parseNonComputedProperty = wrapTracking(extra.parseNonComputedProperty);\n            parseObjectInitialiser = wrapTracking(extra.parseObjectInitialiser);\n            parseObjectProperty = wrapTracking(extra.parseObjectProperty);\n            parseObjectPropertyKey = wrapTracking(extra.parseObjectPropertyKey);\n            parsePostfixExpression = wrapTracking(extra.parsePostfixExpression);\n            parsePrimaryExpression = wrapTracking(extra.parsePrimaryExpression);\n            parseProgram = wrapTracking(extra.parseProgram);\n            parsePropertyFunction = wrapTracking(extra.parsePropertyFunction);\n            parseTemplateElement = wrapTracking(extra.parseTemplateElement);\n            parseTemplateLiteral = wrapTracking(extra.parseTemplateLiteral);\n            parseSpreadOrAssignmentExpression = wrapTracking(extra.parseSpreadOrAssignmentExpression);\n            parseStatement = wrapTracking(extra.parseStatement);\n            parseSwitchCase = wrapTracking(extra.parseSwitchCase);\n            parseUnaryExpression = wrapTracking(extra.parseUnaryExpression);\n            parseVariableDeclaration = wrapTracking(extra.parseVariableDeclaration);\n            parseVariableIdentifier = wrapTracking(extra.parseVariableIdentifier);\n            parseMethodDefinition = wrapTracking(extra.parseMethodDefinition);\n            parseClassDeclaration = wrapTracking(extra.parseClassDeclaration);\n            parseClassExpression = wrapTracking(extra.parseClassExpression);\n            parseClassBody = wrapTracking(extra.parseClassBody);\n        }\n        if (typeof extra.tokens !== 'undefined') {\n            extra.advance = advance;\n            extra.scanRegExp = scanRegExp;\n            advance = collectToken;\n            scanRegExp = collectRegex;\n        }\n    }\n    function unpatch() {\n        if (typeof extra.skipComment === 'function') {\n            skipComment = extra.skipComment;\n        }\n        if (extra.range || extra.loc) {\n            parseArrayInitialiser = extra.parseArrayInitialiser;\n            parseAssignmentExpression = extra.parseAssignmentExpression;\n            parseBinaryExpression = extra.parseBinaryExpression;\n            parseBlock = extra.parseBlock;\n            parseFunctionSourceElements = extra.parseFunctionSourceElements;\n            parseCatchClause = extra.parseCatchClause;\n            parseComputedMember = extra.parseComputedMember;\n            parseConditionalExpression = extra.parseConditionalExpression;\n            parseConstLetDeclaration = extra.parseConstLetDeclaration;\n            parseExportBatchSpecifier = extra.parseExportBatchSpecifier;\n            parseExportDeclaration = extra.parseExportDeclaration;\n            parseExportSpecifier = extra.parseExportSpecifier;\n            parseExpression = extra.parseExpression;\n            parseForVariableDeclaration = extra.parseForVariableDeclaration;\n            parseFunctionDeclaration = extra.parseFunctionDeclaration;\n            parseFunctionExpression = extra.parseFunctionExpression;\n            parseImportDeclaration = extra.parseImportDeclaration;\n            parseImportSpecifier = extra.parseImportSpecifier;\n            parseGroupExpression = extra.parseGroupExpression;\n            parseLeftHandSideExpression = extra.parseLeftHandSideExpression;\n            parseLeftHandSideExpressionAllowCall = extra.parseLeftHandSideExpressionAllowCall;\n            parseModuleDeclaration = extra.parseModuleDeclaration;\n            parseModuleBlock = extra.parseModuleBlock;\n            parseNewExpression = extra.parseNewExpression;\n            parseNonComputedProperty = extra.parseNonComputedProperty;\n            parseObjectInitialiser = extra.parseObjectInitialiser;\n            parseObjectProperty = extra.parseObjectProperty;\n            parseObjectPropertyKey = extra.parseObjectPropertyKey;\n            parsePostfixExpression = extra.parsePostfixExpression;\n            parsePrimaryExpression = extra.parsePrimaryExpression;\n            parseProgram = extra.parseProgram;\n            parsePropertyFunction = extra.parsePropertyFunction;\n            parseTemplateElement = extra.parseTemplateElement;\n            parseTemplateLiteral = extra.parseTemplateLiteral;\n            parseSpreadOrAssignmentExpression = extra.parseSpreadOrAssignmentExpression;\n            parseStatement = extra.parseStatement;\n            parseSwitchCase = extra.parseSwitchCase;\n            parseUnaryExpression = extra.parseUnaryExpression;\n            parseVariableDeclaration = extra.parseVariableDeclaration;\n            parseVariableIdentifier = extra.parseVariableIdentifier;\n            parseMethodDefinition = extra.parseMethodDefinition;\n            parseClassDeclaration = extra.parseClassDeclaration;\n            parseClassExpression = extra.parseClassExpression;\n            parseClassBody = extra.parseClassBody;\n        }\n        if (typeof extra.scanRegExp === 'function') {\n            advance = extra.advance;\n            scanRegExp = extra.scanRegExp;\n        }\n    }\n    // This is used to modify the delegate.\n    function extend(object, properties) {\n        var entry, result = {};\n        for (entry in object) {\n            if (object.hasOwnProperty(entry)) {\n                result[entry] = object[entry];\n            }\n        }\n        for (entry in properties) {\n            if (properties.hasOwnProperty(entry)) {\n                result[entry] = properties[entry];\n            }\n        }\n        return result;\n    }\n    function tokenize(code, options) {\n        var toString, token, tokens;\n        toString = String;\n        if (typeof code !== 'string' && !(code instanceof String)) {\n            code = toString(code);\n        }\n        delegate = SyntaxTreeDelegate;\n        source = code;\n        index = 0;\n        lineNumber = source.length > 0 ? 1 : 0;\n        lineStart = 0;\n        length = source.length;\n        lookahead = null;\n        state = {\n            allowKeyword: true,\n            allowIn: true,\n            labelSet: {},\n            inFunctionBody: false,\n            inIteration: false,\n            inSwitch: false\n        };\n        extra = {};\n        // Options matching.\n        options = options || {};\n        // Of course we collect tokens here.\n        options.tokens = true;\n        extra.tokens = [];\n        extra.tokenize = true;\n        // The following two fields are necessary to compute the Regex tokens.\n        extra.openParenToken = -1;\n        extra.openCurlyToken = -1;\n        extra.range = typeof options.range === 'boolean' && options.range;\n        extra.loc = typeof options.loc === 'boolean' && options.loc;\n        if (typeof options.comment === 'boolean' && options.comment) {\n            extra.comments = [];\n        }\n        if (typeof options.tolerant === 'boolean' && options.tolerant) {\n            extra.errors = [];\n        }\n        if (length > 0) {\n            if (typeof source[0] === 'undefined') {\n                // Try first to convert to a string. This is good as fast path\n                // for old IE which understands string indexing for string\n                // literals only and not for string object.\n                if (code instanceof String) {\n                    source = code.valueOf();\n                }\n            }\n        }\n        patch();\n        try {\n            peek();\n            if (lookahead.type === Token.EOF) {\n                return extra.tokens;\n            }\n            token = lex();\n            while (lookahead.type !== Token.EOF) {\n                try {\n                    token = lex();\n                } catch (lexError) {\n                    token = lookahead;\n                    if (extra.errors) {\n                        extra.errors.push(lexError);\n                        // We have to break on the first error\n                        // to avoid infinite loops.\n                        break;\n                    } else {\n                        throw lexError;\n                    }\n                }\n            }\n            filterTokenLocation();\n            tokens = extra.tokens;\n            if (typeof extra.comments !== 'undefined') {\n                filterCommentLocation();\n                tokens.comments = extra.comments;\n            }\n            if (typeof extra.errors !== 'undefined') {\n                tokens.errors = extra.errors;\n            }\n        } catch (e) {\n            throw e;\n        } finally {\n            unpatch();\n            extra = {};\n        }\n        return tokens;\n    }\n    // Determines if the {} delimiter is a block or an expression.\n    function blockAllowed(toks, start, inExprDelim, parentIsBlock) {\n        var assignOps = [\n                '=',\n                '+=',\n                '-=',\n                '*=',\n                '/=',\n                '%=',\n                '<<=',\n                '>>=',\n                '>>>=',\n                '&=',\n                '|=',\n                '^=',\n                ','\n            ];\n        var binaryOps = [\n                '+',\n                '-',\n                '*',\n                '/',\n                '%',\n                '<<',\n                '>>',\n                '>>>',\n                '&',\n                '|',\n                '^',\n                '&&',\n                '||',\n                '?',\n                ':',\n                '===',\n                '==',\n                '>=',\n                '<=',\n                '<',\n                '>',\n                '!=',\n                '!==',\n                'instanceof'\n            ];\n        var unaryOps = [\n                '++',\n                '--',\n                '~',\n                '!',\n                'delete',\n                'void',\n                'typeof',\n                'yield',\n                'throw',\n                'new'\n            ];\n        function back(n) {\n            var idx = toks.length - n > 0 ? toks.length - n : 0;\n            return toks[idx];\n        }\n        if (inExprDelim && toks.length - (start + 2) <= 0) {\n            // ... ({...} ...)\n            return false;\n        } else if (back(start + 2).value === ':' && parentIsBlock) {\n            // ...{a:{b:{...}}}\n            return true;\n        } else if (isIn(back(start + 2).value, unaryOps.concat(binaryOps).concat(assignOps))) {\n            // ... + {...}\n            return false;\n        } else if (back(start + 2).value === 'return') {\n            // ASI makes `{}` a block in:\n            //\n            //    return\n            //    { ... }\n            //\n            // otherwise an object literal, so it's an\n            // expression and thus / is divide\n            var currLineNumber = typeof back(start + 1).startLineNumber !== 'undefined' ? back(start + 1).startLineNumber : back(start + 1).lineNumber;\n            if (back(start + 2).lineNumber !== currLineNumber) {\n                return true;\n            } else {\n                return false;\n            }\n        } else if (isIn(back(start + 2).value, [\n                'void',\n                'typeof',\n                'in',\n                'case',\n                'delete'\n            ])) {\n            // ... in {}\n            return false;\n        } else {\n            return true;\n        }\n    }\n    // Read the next token. Takes the previously read tokens, a\n    // boolean indicating if the parent delimiter is () or [], and a\n    // boolean indicating if the parent delimiter is {} a block\n    function readToken(toks, inExprDelim, parentIsBlock) {\n        var delimiters = [\n                '(',\n                '{',\n                '['\n            ];\n        var parenIdents = [\n                'if',\n                'while',\n                'for',\n                'with'\n            ];\n        var last = toks.length - 1;\n        var comments, commentsLen = extra.comments.length;\n        function back(n) {\n            var idx = toks.length - n > 0 ? toks.length - n : 0;\n            return toks[idx];\n        }\n        function attachComments(token) {\n            if (comments) {\n                token.leadingComments = comments;\n            }\n            return token;\n        }\n        function _advance() {\n            return attachComments(advance());\n        }\n        function _scanRegExp() {\n            return attachComments(scanRegExp());\n        }\n        skipComment();\n        if (extra.comments.length > commentsLen) {\n            comments = extra.comments.slice(commentsLen);\n        }\n        if (isIn(source[index], delimiters)) {\n            return attachComments(readDelim(toks, inExprDelim, parentIsBlock));\n        }\n        if (source[index] === '/') {\n            var prev = back(1);\n            if (prev) {\n                if (prev.value === '()') {\n                    if (isIn(back(2).value, parenIdents)) {\n                        // ... if (...) / ...\n                        return _scanRegExp();\n                    }\n                    // ... (...) / ...\n                    return _advance();\n                }\n                if (prev.value === '{}') {\n                    if (blockAllowed(toks, 0, inExprDelim, parentIsBlock)) {\n                        if (back(2).value === '()') {\n                            // named function\n                            if (back(4).value === 'function') {\n                                if (!blockAllowed(toks, 3, inExprDelim, parentIsBlock)) {\n                                    // new function foo (...) {...} / ...\n                                    return _advance();\n                                }\n                                if (toks.length - 5 <= 0 && inExprDelim) {\n                                    // (function foo (...) {...} /...)\n                                    // [function foo (...) {...} /...]\n                                    return _advance();\n                                }\n                            }\n                            // unnamed function\n                            if (back(3).value === 'function') {\n                                if (!blockAllowed(toks, 2, inExprDelim, parentIsBlock)) {\n                                    // new function (...) {...} / ...\n                                    return _advance();\n                                }\n                                if (toks.length - 4 <= 0 && inExprDelim) {\n                                    // (function (...) {...} /...)\n                                    // [function (...) {...} /...]\n                                    return _advance();\n                                }\n                            }\n                        }\n                        // ...; {...} /...\n                        return _scanRegExp();\n                    } else {\n                        // ... + {...} / ...\n                        return _advance();\n                    }\n                }\n                if (prev.type === Token.Punctuator) {\n                    // ... + /...\n                    return _scanRegExp();\n                }\n                if (isKeyword(prev.value) && prev.value !== 'this' && prev.value !== 'let') {\n                    // typeof /...\n                    return _scanRegExp();\n                }\n                return _advance();\n            }\n            return _scanRegExp();\n        }\n        return _advance();\n    }\n    function readDelim(toks, inExprDelim, parentIsBlock) {\n        var startDelim = advance(), matchDelim = {\n                '(': ')',\n                '{': '}',\n                '[': ']'\n            }, inner = [];\n        var delimiters = [\n                '(',\n                '{',\n                '['\n            ];\n        assert(delimiters.indexOf(startDelim.value) !== -1, 'Need to begin at the delimiter');\n        var token = startDelim;\n        var startLineNumber = token.lineNumber;\n        var startLineStart = token.lineStart;\n        var startRange = token.range;\n        var delimToken = {};\n        delimToken.type = Token.Delimiter;\n        delimToken.value = startDelim.value + matchDelim[startDelim.value];\n        delimToken.startLineNumber = startLineNumber;\n        delimToken.startLineStart = startLineStart;\n        delimToken.startRange = startRange;\n        var delimIsBlock = false;\n        if (startDelim.value === '{') {\n            delimIsBlock = blockAllowed(toks.concat(delimToken), 0, inExprDelim, parentIsBlock);\n        }\n        while (index <= length) {\n            token = readToken(inner, startDelim.value === '(' || startDelim.value === '[', delimIsBlock);\n            if (token.type === Token.Punctuator && token.value === matchDelim[startDelim.value]) {\n                if (token.leadingComments) {\n                    delimToken.trailingComments = token.leadingComments;\n                }\n                break;\n            } else if (token.type === Token.EOF) {\n                throwError({}, Messages.UnexpectedEOS);\n            } else {\n                inner.push(token);\n            }\n        }\n        // at the end of the stream but the very last char wasn't the closing delimiter\n        if (index >= length && matchDelim[startDelim.value] !== source[length - 1]) {\n            throwError({}, Messages.UnexpectedEOS);\n        }\n        var endLineNumber = token.lineNumber;\n        var endLineStart = token.lineStart;\n        var endRange = token.range;\n        delimToken.inner = inner;\n        delimToken.endLineNumber = endLineNumber;\n        delimToken.endLineStart = endLineStart;\n        delimToken.endRange = endRange;\n        return delimToken;\n    }\n    // (Str) -> [...CSyntax]\n    function read(code) {\n        var token, tokenTree = [];\n        extra = {};\n        extra.comments = [];\n        patch();\n        source = code;\n        index = 0;\n        lineNumber = source.length > 0 ? 1 : 0;\n        lineStart = 0;\n        length = source.length;\n        state = {\n            allowIn: true,\n            labelSet: {},\n            lastParenthesized: null,\n            inFunctionBody: false,\n            inIteration: false,\n            inSwitch: false\n        };\n        while (index < length) {\n            tokenTree.push(readToken(tokenTree, false, false));\n        }\n        var last = tokenTree[tokenTree.length - 1];\n        if (last && last.type !== Token.EOF) {\n            tokenTree.push({\n                type: Token.EOF,\n                value: '',\n                lineNumber: last.lineNumber,\n                lineStart: last.lineStart,\n                range: [\n                    index,\n                    index\n                ]\n            });\n        }\n        return expander.tokensToSyntax(tokenTree);\n    }\n    function parse(code, options) {\n        var program, toString;\n        extra = {};\n        // given an array of tokens instead of a string\n        if (Array.isArray(code)) {\n            tokenStream = code;\n            length = tokenStream.length;\n            lineNumber = tokenStream.length > 0 ? 1 : 0;\n            source = undefined;\n        } else {\n            toString = String;\n            if (typeof code !== 'string' && !(code instanceof String)) {\n                code = toString(code);\n            }\n            source = code;\n            length = source.length;\n            lineNumber = source.length > 0 ? 1 : 0;\n        }\n        delegate = SyntaxTreeDelegate;\n        streamIndex = -1;\n        index = 0;\n        lineStart = 0;\n        sm_lineStart = 0;\n        sm_lineNumber = lineNumber;\n        sm_index = 0;\n        sm_range = [\n            0,\n            0\n        ];\n        lookahead = null;\n        state = {\n            allowKeyword: false,\n            allowIn: true,\n            labelSet: {},\n            parenthesizedCount: 0,\n            inFunctionBody: false,\n            inIteration: false,\n            inSwitch: false,\n            yieldAllowed: false,\n            yieldFound: false\n        };\n        if (typeof options !== 'undefined') {\n            extra.range = typeof options.range === 'boolean' && options.range;\n            extra.loc = typeof options.loc === 'boolean' && options.loc;\n            if (extra.loc && options.source !== null && options.source !== undefined) {\n                delegate = extend(delegate, {\n                    'postProcess': function (node) {\n                        node.loc.source = toString(options.source);\n                        return node;\n                    }\n                });\n            }\n            if (typeof options.tokens === 'boolean' && options.tokens) {\n                extra.tokens = [];\n            }\n            if (typeof options.comment === 'boolean' && options.comment) {\n                extra.comments = [];\n            }\n            if (typeof options.tolerant === 'boolean' && options.tolerant) {\n                extra.errors = [];\n            }\n        }\n        if (length > 0) {\n            if (source && typeof source[0] === 'undefined') {\n                // Try first to convert to a string. This is good as fast path\n                // for old IE which understands string indexing for string\n                // literals only and not for string object.\n                if (code instanceof String) {\n                    source = code.valueOf();\n                }\n            }\n        }\n        extra = {\n            loc: true,\n            errors: []\n        };\n        patch();\n        try {\n            program = parseProgram();\n            if (typeof extra.comments !== 'undefined') {\n                filterCommentLocation();\n                program.comments = extra.comments;\n            }\n            if (typeof extra.tokens !== 'undefined') {\n                filterTokenLocation();\n                program.tokens = extra.tokens;\n            }\n            if (typeof extra.errors !== 'undefined') {\n                program.errors = extra.errors;\n            }\n            if (extra.range || extra.loc) {\n                program.body = filterGroup(program.body);\n            }\n        } catch (e) {\n            throw e;\n        } finally {\n            unpatch();\n            extra = {};\n        }\n        return program;\n    }\n    exports$2.tokenize = tokenize;\n    exports$2.read = read;\n    exports$2.Token = Token;\n    exports$2.parse = parse;\n    // Deep copy.\n    exports$2.Syntax = function () {\n        var name, types = {};\n        if (typeof Object.create === 'function') {\n            types = Object.create(null);\n        }\n        for (name in Syntax) {\n            if (Syntax.hasOwnProperty(name)) {\n                types[name] = Syntax[name];\n            }\n        }\n        if (typeof Object.freeze === 'function') {\n            Object.freeze(types);\n        }\n        return types;\n    }();\n}));\n//# sourceMappingURL=parser.js.map"
  },
  {
    "path": "docs/editor/scripts/patterns.js",
    "content": "(function (root, factory) {\n    if (typeof exports === 'object') {\n        // CommonJS\n        factory(exports, require('underscore'), require('./parser'), require('./expander'), require('./syntax'));\n    } else if (typeof define === 'function' && define.amd) {\n        // AMD. Register as an anonymous module.\n        define([\n            'exports',\n            'underscore',\n            'parser',\n            'expander',\n            'syntax'\n        ], factory);\n    }\n}(this, function (exports$2, _, parser, expander, syntax) {\n    var get_expression = expander.get_expression;\n    var syntaxFromToken = syntax.syntaxFromToken;\n    var makePunc = syntax.makePunc;\n    var joinSyntax = syntax.joinSyntax;\n    var joinSyntaxArray = syntax.joinSyntaxArray;\n    var cloneSyntaxArray = syntax.cloneSyntaxArray;\n    var assert = syntax.assert;\n    var throwSyntaxError = syntax.throwSyntaxError;\n    var push = Array.prototype.push;\n    // ([...CSyntax]) -> [...Str]\n    function freeVarsInPattern(pattern) {\n        var fv = [];\n        _.each(pattern, function (pat) {\n            if (isPatternVar(pat)) {\n                fv.push(pat.token.value);\n            } else if (pat.token.type === parser.Token.Delimiter) {\n                push.apply(fv, freeVarsInPattern(pat.token.inner));\n            }\n        });\n        return fv;\n    }\n    function typeIsLiteral(type) {\n        return type === parser.Token.NullLiteral || type === parser.Token.NumericLiteral || type === parser.Token.StringLiteral || type === parser.Token.RegexLiteral || type === parser.Token.BooleanLiteral;\n    }\n    function containsPatternVar(patterns) {\n        return _.any(patterns, function (pat) {\n            if (pat.token.type === parser.Token.Delimiter) {\n                return containsPatternVar(pat.token.inner);\n            }\n            return isPatternVar(pat);\n        });\n    }\n    function delimIsSeparator(delim) {\n        return delim && delim.token && delim.token.type === parser.Token.Delimiter && delim.token.value === '()' && delim.token.inner.length === 1 && delim.token.inner[0].token.type !== parser.Token.Delimiter && !containsPatternVar(delim.token.inner);\n    }\n    function isPatternVar(stx) {\n        return stx.token.value[0] === '$' && stx.token.value !== '$';\n    }\n    // ([...{level: Num, match: [...CSyntax]}], Str) -> [...CSyntax]\n    function joinRepeatedMatch(tojoin, punc) {\n        return _.reduce(_.rest(tojoin, 1), function (acc, join) {\n            if (punc === ' ') {\n                return acc.concat(cloneSyntaxArray(join.match));\n            }\n            return acc.concat(makePunc(punc, _.first(join.match)), cloneSyntaxArray(join.match));\n        }, cloneSyntaxArray(_.first(tojoin).match));\n    }\n    // take the line context (range, lineNumber)\n    // (CSyntax, [...CSyntax]) -> [...CSyntax]\n    function takeLineContext(from, to) {\n        return _.map(to, function (stx) {\n            return takeLine(from, stx);\n        });\n    }\n    // (CSyntax, CSyntax) -> CSyntax\n    function takeLine(from, to) {\n        var next;\n        if (to.token.type === parser.Token.Delimiter) {\n            var sm_startLineNumber = typeof to.token.sm_startLineNumber !== 'undefined' ? to.token.sm_startLineNumber : to.token.startLineNumber;\n            var sm_endLineNumber = typeof to.token.sm_endLineNumber !== 'undefined' ? to.token.sm_endLineNumber : to.token.endLineNumber;\n            var sm_startLineStart = typeof to.token.sm_startLineStart !== 'undefined' ? to.token.sm_startLineStart : to.token.startLineStart;\n            var sm_endLineStart = typeof to.token.sm_endLineStart !== 'undefined' ? to.token.sm_endLineStart : to.token.endLineStart;\n            var sm_startRange = typeof to.token.sm_startRange !== 'undefined' ? to.token.sm_startRange : to.token.startRange;\n            var sm_endRange = typeof to.token.sm_endRange !== 'undefined' ? to.token.sm_endRange : to.token.endRange;\n            if (from.token.type === parser.Token.Delimiter) {\n                next = syntaxFromToken({\n                    type: parser.Token.Delimiter,\n                    value: to.token.value,\n                    inner: takeLineContext(from, to.token.inner),\n                    startRange: from.token.startRange,\n                    endRange: from.token.endRange,\n                    startLineNumber: from.token.startLineNumber,\n                    startLineStart: from.token.startLineStart,\n                    endLineNumber: from.token.endLineNumber,\n                    endLineStart: from.token.endLineStart,\n                    sm_startLineNumber: sm_startLineNumber,\n                    sm_endLineNumber: sm_endLineNumber,\n                    sm_startLineStart: sm_startLineStart,\n                    sm_endLineStart: sm_endLineStart,\n                    sm_startRange: sm_startRange,\n                    sm_endRange: sm_endRange\n                }, to);\n            } else {\n                next = syntaxFromToken({\n                    type: parser.Token.Delimiter,\n                    value: to.token.value,\n                    inner: takeLineContext(from, to.token.inner),\n                    startRange: from.token.range,\n                    endRange: from.token.range,\n                    startLineNumber: from.token.lineNumber,\n                    startLineStart: from.token.lineStart,\n                    endLineNumber: from.token.lineNumber,\n                    endLineStart: from.token.lineStart,\n                    sm_startLineNumber: sm_startLineNumber,\n                    sm_endLineNumber: sm_endLineNumber,\n                    sm_startLineStart: sm_startLineStart,\n                    sm_endLineStart: sm_endLineStart,\n                    sm_startRange: sm_startRange,\n                    sm_endRange: sm_endRange\n                }, to);\n            }\n        } else {\n            var sm_lineNumber = typeof to.token.sm_lineNumber !== 'undefined' ? to.token.sm_lineNumber : to.token.lineNumber;\n            var sm_lineStart = typeof to.token.sm_lineStart !== 'undefined' ? to.token.sm_lineStart : to.token.lineStart;\n            var sm_range = typeof to.token.sm_range !== 'undefined' ? to.token.sm_range : to.token.range;\n            if (from.token.type === parser.Token.Delimiter) {\n                next = syntaxFromToken({\n                    value: to.token.value,\n                    type: to.token.type,\n                    lineNumber: from.token.startLineNumber,\n                    lineStart: from.token.startLineStart,\n                    range: from.token.startRange,\n                    sm_lineNumber: sm_lineNumber,\n                    sm_lineStart: sm_lineStart,\n                    sm_range: sm_range\n                }, to);\n            } else {\n                next = syntaxFromToken({\n                    value: to.token.value,\n                    type: to.token.type,\n                    lineNumber: from.token.lineNumber,\n                    lineStart: from.token.lineStart,\n                    range: from.token.range,\n                    sm_lineNumber: sm_lineNumber,\n                    sm_lineStart: sm_lineStart,\n                    sm_range: sm_range\n                }, to);\n            }\n        }\n        if (to.token.leadingComments) {\n            next.token.leadingComments = to.token.leadingComments;\n        }\n        if (to.token.trailingComments) {\n            next.token.trailingComments = to.token.trailingComments;\n        }\n        return next;\n    }\n    function reversePattern(patterns) {\n        var len = patterns.length;\n        var pat;\n        return _.reduceRight(patterns, function (acc, pat$2) {\n            if (pat$2.class === 'pattern_group') {\n                pat$2.token.inner = reversePattern(pat$2.token.inner);\n            }\n            if (pat$2.repeat) {\n                pat$2.leading = !pat$2.leading;\n            }\n            acc.push(pat$2);\n            return acc;\n        }, []);\n    }\n    function loadLiteralGroup(patterns) {\n        _.forEach(patterns, function (patStx) {\n            if (patStx.token.type === parser.Token.Delimiter) {\n                patStx.token.inner = loadLiteralGroup(patStx.token.inner);\n            } else {\n                patStx.class = 'pattern_literal';\n            }\n        });\n        return patterns;\n    }\n    function isPrimaryClass(name) {\n        return [\n            'expr',\n            'lit',\n            'ident',\n            'token',\n            'invoke',\n            'invokeRec'\n        ].indexOf(name) > -1;\n    }\n    function loadPattern(patterns, reverse) {\n        var patts = [];\n        for (var i = 0; i < patterns.length; i++) {\n            var tok1 = patterns[i];\n            var tok2 = patterns[i + 1];\n            var tok3 = patterns[i + 2];\n            var tok4 = patterns[i + 3];\n            var last = patts[patts.length - 1];\n            var patt;\n            assert(tok1, 'Expecting syntax object');\n            // Repeaters\n            if (tok1.token.type === parser.Token.Delimiter && tok1.token.value === '()' && tok2 && tok2.token.type === parser.Token.Punctuator && tok2.token.value === '...' && last) {\n                assert(tok1.token.inner.length === 1, 'currently assuming all separators are a single token');\n                i += 1;\n                last.repeat = true;\n                last.separator = tok1.token.inner[0].token.value;\n                continue;\n            } else if (tok1.token.type === parser.Token.Punctuator && tok1.token.value === '...' && last) {\n                last.repeat = true;\n                last.separator = ' ';\n                continue;\n            } else if (isPatternVar(tok1)) {\n                patt = tok1;\n                if (tok2 && tok2.token.type === parser.Token.Punctuator && tok2.token.value === ':' && tok3 && tok3.token.type === parser.Token.Identifier) {\n                    i += 2;\n                    if (isPrimaryClass(tok3.token.value)) {\n                        patt.class = tok3.token.value;\n                        if (patt.class === 'invokeRec' || patt.class === 'invoke') {\n                            i += 1;\n                            if (tok4.token.value === '()' && tok4.token.inner.length) {\n                                patt.macroName = tok4.expose().token.inner;\n                            } else {\n                                throwSyntaxError(patt.class, 'Expected macro parameter', tok3);\n                            }\n                        }\n                    } else {\n                        patt.class = 'invoke';\n                        patt.macroName = [tok3];\n                    }\n                } else {\n                    patt.class = 'token';\n                }\n            } else if (tok1.token.type === parser.Token.Identifier && tok1.token.value === '$' && tok2.token.type === parser.Token.Delimiter) {\n                i += 1;\n                patt = tok2;\n                patt.class = 'pattern_group';\n                if (patt.token.value === '[]') {\n                    patt.token.inner = loadLiteralGroup(patt.token.inner);\n                } else {\n                    patt.token.inner = loadPattern(patt.expose().token.inner);\n                }\n            } else if (tok1.token.type === parser.Token.Identifier && tok1.token.value === '_') {\n                patt = tok1;\n                patt.class = 'wildcard';\n            } else {\n                patt = tok1;\n                patt.class = 'pattern_literal';\n                if (patt.token.inner) {\n                    patt.token.inner = loadPattern(patt.expose().token.inner);\n                }\n            }\n            // Macro classes aren't allowed in lookbehind because we wouldn't\n            // know where to insert the macro, and you can't use a L->R macro\n            // to match R->L.\n            if (reverse && patt.macroName) {\n                throwSyntaxError(patt.class, 'Not allowed in top-level lookbehind', patt.macroName[0]);\n            }\n            patts.push(patt);\n        }\n        return reverse ? reversePattern(patts) : patts;\n    }\n    function cachedTermMatch(stx, term) {\n        var res = [];\n        var i = 0;\n        while (stx[i] && stx[i].term === term) {\n            res.unshift(stx[i]);\n            i++;\n        }\n        return {\n            result: term,\n            destructed: res,\n            rest: stx.slice(res.length)\n        };\n    }\n    function expandWithMacro(macroName, stx, env, rec) {\n        var name = macroName.map(syntax.unwrapSyntax).join('');\n        var ident = syntax.makeIdent(name, macroName[0]);\n        var macroObj = env.get(expander.resolve(ident));\n        var newContext = expander.makeExpanderContext({ env: env });\n        if (!macroObj) {\n            throwSyntaxError('invoke', 'Macro not in scope', macroName[0]);\n        }\n        var next = macroName.slice(-1).concat(stx);\n        var rest, result, rt, patternEnv;\n        while (macroObj && next) {\n            try {\n                rt = macroObj.fn(next, newContext, [], []);\n                result = rt.result;\n                rest = rt.rest;\n                patternEnv = rt.patterns;\n            } catch (e) {\n                if (e instanceof syntax.SyntaxCaseError) {\n                    result = null;\n                    rest = stx;\n                    break;\n                } else {\n                    throw e;\n                }\n            }\n            if (rec && result.length >= 1) {\n                var resultHead = result[0];\n                var resultRest = result.slice(1);\n                var nextName = expander.getName(resultHead, resultRest);\n                var nextMacro = expander.getMacroInEnv(resultHead, resultRest, env);\n                if (nextName && nextMacro) {\n                    macroObj = nextMacro;\n                    next = result.concat(rest);\n                } else {\n                    break;\n                }\n            } else {\n                break;\n            }\n        }\n        return {\n            result: result,\n            rest: rest,\n            patternEnv: patternEnv\n        };\n    }\n    // (Pattern, [...CSyntax], MacroEnv) -> {result: null or [...CSyntax], rest: [...CSyntax]}\n    function matchPatternClass(patternObj, stx, env) {\n        var result, rest, match, patternEnv;\n        // pattern has no parse class\n        if (patternObj.class === 'token' && stx[0] && stx[0].token.type !== parser.Token.EOF) {\n            result = [stx[0]];\n            rest = stx.slice(1);\n        } else if (patternObj.class === 'lit' && stx[0] && typeIsLiteral(stx[0].token.type)) {\n            result = [stx[0]];\n            rest = stx.slice(1);\n        } else if (patternObj.class === 'ident' && stx[0] && stx[0].token.type === parser.Token.Identifier) {\n            result = [stx[0]];\n            rest = stx.slice(1);\n        } else if (stx.length > 0 && patternObj.class === 'VariableStatement') {\n            match = stx[0].term ? cachedTermMatch(stx, stx[0].term) : expander.enforest(stx, expander.makeExpanderContext({ env: env }));\n            if (match.result && match.result.isVariableStatement) {\n                result = match.destructed || match.result.destruct(false);\n                rest = match.rest;\n            } else {\n                result = null;\n                rest = stx;\n            }\n        } else if (stx.length > 0 && patternObj.class === 'expr') {\n            match = expander.get_expression(stx, expander.makeExpanderContext({ env: env }));\n            if (match.result === null || !match.result.isExpr) {\n                result = null;\n                rest = stx;\n            } else {\n                result = match.destructed || match.result.destruct(false);\n                result = [syntax.makeDelim('()', result, result[0])];\n                rest = match.rest;\n            }\n        } else if (stx.length > 0 && (patternObj.class === 'invoke' || patternObj.class === 'invokeRec')) {\n            match = expandWithMacro(patternObj.macroName, stx, env, patternObj.class === 'invokeRec');\n            result = match.result;\n            rest = match.result ? match.rest : stx;\n            patternEnv = match.patternEnv;\n        } else {\n            result = null;\n            rest = stx;\n        }\n        return {\n            result: result,\n            rest: rest,\n            patternEnv: patternEnv\n        };\n    }\n    // attempt to match patterns against stx\n    // ([...Pattern], [...Syntax], Env) -> { result: [...Syntax], rest: [...Syntax], patternEnv: PatternEnv }\n    function matchPatterns(patterns, stx, env, topLevel) {\n        // topLevel lets us know if the patterns are on the top level or nested inside\n        // a delimiter:\n        //     case $topLevel (,) ... => { }\n        //     case ($nested (,) ...) => { }\n        // This matters for how we deal with trailing unmatched syntax when the pattern\n        // has an ellipses:\n        //     m 1,2,3 foo\n        // should match 1,2,3 and leave foo alone but:\n        //     m (1,2,3 foo)\n        // should fail to match entirely.\n        topLevel = topLevel || false;\n        // note that there are two environments floating around,\n        // one is the mapping of identifiers to macro definitions (env)\n        // and the other is the pattern environment (patternEnv) that maps\n        // patterns in a macro case to syntax.\n        var result = [];\n        var patternEnv = {};\n        var match;\n        var pattern;\n        var rest = stx;\n        var success = true;\n        var inLeading;\n        patternLoop:\n            for (var i = 0; i < patterns.length; i++) {\n                if (success === false) {\n                    break;\n                }\n                pattern = patterns[i];\n                inLeading = false;\n                do {\n                    // handles cases where patterns trail a repeated pattern like `$x ... ;`\n                    if (pattern.repeat && i + 1 < patterns.length) {\n                        var restMatch = matchPatterns(patterns.slice(i + 1), rest, env, topLevel);\n                        if (restMatch.success) {\n                            // match the repeat pattern on the empty array to fill in its\n                            // pattern variable in the environment\n                            match = matchPattern(pattern, [], env, patternEnv, topLevel);\n                            patternEnv = _.extend(restMatch.patternEnv, match.patternEnv);\n                            rest = restMatch.rest;\n                            break patternLoop;\n                        }\n                    }\n                    if (pattern.repeat && pattern.leading && pattern.separator !== ' ') {\n                        if (rest[0].token.value === pattern.separator) {\n                            if (!inLeading) {\n                                inLeading = true;\n                            }\n                            rest = rest.slice(1);\n                        } else {\n                            // If we are in a leading repeat, the separator is required.\n                            if (inLeading) {\n                                success = false;\n                                break;\n                            }\n                        }\n                    }\n                    match = matchPattern(pattern, rest, env, patternEnv, topLevel);\n                    if (!match.success && pattern.repeat) {\n                        // a repeat can match zero tokens and still be a\n                        // \"success\" so break out of the inner loop and\n                        // try the next pattern\n                        break;\n                    }\n                    if (!match.success) {\n                        success = false;\n                        break;\n                    }\n                    rest = match.rest;\n                    patternEnv = match.patternEnv;\n                    if (success && !(topLevel || pattern.repeat)) {\n                        // the very last pattern matched, inside a\n                        // delimiter, not a repeat, *and* there are more\n                        // unmatched bits of syntax\n                        if (i == patterns.length - 1 && rest.length !== 0) {\n                            success = false;\n                            break;\n                        }\n                    }\n                    if (pattern.repeat && !pattern.leading && success) {\n                        // if (i < patterns.length - 1 && rest.length > 0) {\n                        //     var restMatch = matchPatterns(patterns.slice(i+1), rest, env, topLevel);\n                        //     if (restMatch.success) {\n                        //         patternEnv = _.extend(patternEnv, restMatch.patternEnv);\n                        //         rest = restMatch.rest;\n                        //         break patternLoop;\n                        //     }\n                        // }\n                        if (pattern.separator === ' ') {\n                            // no separator specified (using the empty string for this)\n                            // so keep going\n                            continue;\n                        } else if (rest[0] && rest[0].token.value === pattern.separator) {\n                            // more tokens and the next token matches the separator\n                            rest = rest.slice(1);\n                        } else if (pattern.separator !== ' ' && rest.length > 0 && i === patterns.length - 1 && topLevel === false) {\n                            // separator is specified, there is a next token, the\n                            // next token doesn't match the separator, there are\n                            // no more patterns, and this is a top level pattern\n                            // so the match has failed\n                            success = false;\n                            break;\n                        } else {\n                            break;\n                        }\n                    }\n                } while (pattern.repeat && success && rest.length > 0);\n            }\n        // If we are in a delimiter and we haven't matched all the syntax, it\n        // was a failed match.\n        if (!topLevel && rest.length) {\n            success = false;\n        }\n        var result;\n        if (success) {\n            result = rest.length ? stx.slice(0, -rest.length) : stx;\n        } else {\n            result = [];\n        }\n        return {\n            success: success,\n            result: result,\n            rest: rest,\n            patternEnv: patternEnv\n        };\n    }\n    /* the pattern environment will look something like:\n    {\n        \"$x\": {\n            level: 2,\n            match: [{\n                level: 1,\n                match: [{\n                    level: 0,\n                    match: [tok1, tok2, ...]\n                }, {\n                    level: 0,\n                    match: [tok1, tok2, ...]\n                }]\n            }, {\n                level: 1,\n                match: [{\n                    level: 0,\n                    match: [tok1, tok2, ...]\n                }]\n            }]\n        },\n        \"$y\" : ...\n    }\n    */\n    function matchPattern(pattern, stx, env, patternEnv, topLevel) {\n        var subMatch;\n        var match, matchEnv;\n        var rest;\n        var success;\n        if (typeof pattern.inner !== 'undefined') {\n            if (pattern.class === 'pattern_group') {\n                // pattern groups don't match the delimiters\n                subMatch = matchPatterns(pattern.inner, stx, env, true);\n                rest = subMatch.rest;\n            } else if (stx[0] && stx[0].token.type === parser.Token.Delimiter && stx[0].token.value === pattern.value) {\n                stx[0].expose();\n                if (pattern.inner.length === 0 && stx[0].token.inner.length !== 0) {\n                    return {\n                        success: false,\n                        rest: stx,\n                        patternEnv: patternEnv\n                    };\n                }\n                subMatch = matchPatterns(pattern.inner, stx[0].token.inner, env, false);\n                rest = stx.slice(1);\n            } else {\n                return {\n                    success: false,\n                    rest: stx,\n                    patternEnv: patternEnv\n                };\n            }\n            success = subMatch.success;\n            patternEnv = loadPatternEnv(patternEnv, subMatch.patternEnv, topLevel, pattern.repeat);\n        } else {\n            if (pattern.class === 'wildcard') {\n                success = true;\n                rest = stx.slice(1);\n            } else if (pattern.class === 'pattern_literal') {\n                // match the literal but don't update the pattern environment\n                if (stx[0] && pattern.value === stx[0].token.value) {\n                    success = true;\n                    rest = stx.slice(1);\n                } else {\n                    success = false;\n                    rest = stx;\n                }\n            } else {\n                match = matchPatternClass(pattern, stx, env);\n                success = match.result !== null;\n                rest = match.rest;\n                matchEnv = {\n                    level: 0,\n                    match: match.result,\n                    topLevel: topLevel\n                };\n                // push the match onto this value's slot in the environment\n                if (pattern.repeat) {\n                    if (patternEnv[pattern.value] && success) {\n                        patternEnv[pattern.value].match.push(matchEnv);\n                    } else if (patternEnv[pattern.value] === undefined) {\n                        // initialize if necessary\n                        patternEnv[pattern.value] = {\n                            level: 1,\n                            match: [matchEnv],\n                            topLevel: topLevel\n                        };\n                    }\n                } else {\n                    patternEnv[pattern.value] = matchEnv;\n                }\n                patternEnv = loadPatternEnv(patternEnv, match.patternEnv, topLevel, pattern.repeat, pattern.value);\n            }\n        }\n        return {\n            success: success,\n            rest: rest,\n            patternEnv: patternEnv\n        };\n    }\n    function loadPatternEnv(toEnv, fromEnv, topLevel, repeat, prefix) {\n        prefix = prefix || '';\n        _.forEach(fromEnv, function (patternVal, patternKey) {\n            var patternName = prefix + patternKey;\n            if (repeat) {\n                var nextLevel = patternVal.level + 1;\n                if (toEnv[patternName]) {\n                    toEnv[patternName].level = nextLevel;\n                    toEnv[patternName].match.push(patternVal);\n                } else {\n                    toEnv[patternName] = {\n                        level: nextLevel,\n                        match: [patternVal],\n                        topLevel: topLevel\n                    };\n                }\n            } else {\n                toEnv[patternName] = patternVal;\n            }\n        });\n        return toEnv;\n    }\n    function matchLookbehind(patterns, stx, terms, env) {\n        var success, patternEnv, prevStx, prevTerms;\n        // No lookbehind, noop.\n        if (!patterns.length) {\n            success = true;\n            patternEnv = {};\n            prevStx = stx;\n            prevTerms = terms;\n        } else {\n            var match = matchPatterns(patterns, stx, env, true);\n            var last = match.result[match.result.length - 1];\n            success = match.success;\n            patternEnv = match.patternEnv;\n            if (success) {\n                if (match.rest.length) {\n                    if (last && last.term && last.term === match.rest[0].term) {\n                        // The term tree was split, so its a failed match;\n                        success = false;\n                    } else {\n                        prevStx = match.rest;\n                        // Find where to slice the prevTerms to match up with\n                        // the state of prevStx.\n                        for (var i = 0, len = terms.length; i < len; i++) {\n                            if (terms[i] === prevStx[0].term) {\n                                prevTerms = terms.slice(i);\n                                break;\n                            }\n                        }\n                        assert(prevTerms, 'No matching previous term found');\n                    }\n                } else {\n                    prevTerms = [];\n                    prevStx = [];\n                }\n            }\n        }\n        // We need to reverse the matches for any top level repeaters because\n        // they match in reverse, and thus put their results in backwards.\n        _.forEach(patternEnv, function (val, key) {\n            if (val.level && val.match && val.topLevel) {\n                val.match.reverse();\n            }\n        });\n        return {\n            success: success,\n            patternEnv: patternEnv,\n            prevStx: prevStx,\n            prevTerms: prevTerms\n        };\n    }\n    function hasMatch(m) {\n        if (m.level === 0) {\n            return m.match.length > 0;\n        }\n        return m.match.every(function (m$2) {\n            return hasMatch(m$2);\n        });\n    }\n    // given the given the macroBody (list of Pattern syntax objects) and the\n    // environment (a mapping of patterns to syntax) return the body with the\n    // appropriate patterns replaces with their value in the environment\n    function transcribe(macroBody, macroNameStx, env) {\n        return _.chain(macroBody).reduce(function (acc, bodyStx, idx, original) {\n            // first find the ellipses and mark the syntax objects\n            // (note that this step does not eagerly go into delimiter bodies)\n            var last = original[idx - 1];\n            var next = original[idx + 1];\n            var nextNext = original[idx + 2];\n            // drop `...`\n            if (bodyStx.token.value === '...') {\n                return acc;\n            }\n            // drop `(<separator)` when followed by an ellipse\n            if (delimIsSeparator(bodyStx) && next && next.token.value === '...') {\n                return acc;\n            }\n            // skip the $ in $(...)\n            if (bodyStx.token.value === '$' && next && next.token.type === parser.Token.Delimiter && next.token.value === '()') {\n                return acc;\n            }\n            // mark $[...] as a literal\n            if (bodyStx.token.value === '$' && next && next.token.type === parser.Token.Delimiter && next.token.value === '[]') {\n                next.literal = true;\n                return acc;\n            }\n            if (bodyStx.token.type === parser.Token.Delimiter && bodyStx.token.value === '()' && last && last.token.value === '$') {\n                bodyStx.group = true;\n            }\n            // literal [] delimiters have their bodies just\n            // directly passed along\n            if (bodyStx.literal === true) {\n                assert(bodyStx.token.type === parser.Token.Delimiter, 'expecting a literal to be surrounded by []');\n                return acc.concat(bodyStx.token.inner);\n            }\n            if (next && next.token.value === '...') {\n                bodyStx.repeat = true;\n                bodyStx.separator = ' ';\n            }    // default to space separated\n            else if (delimIsSeparator(next) && nextNext && nextNext.token.value === '...') {\n                bodyStx.repeat = true;\n                bodyStx.separator = next.token.inner[0].token.value;\n            }\n            acc.push(bodyStx);\n            return acc;\n        }, []).reduce(function (acc, bodyStx, idx) {\n            // then do the actual transcription\n            if (bodyStx.repeat) {\n                if (bodyStx.token.type === parser.Token.Delimiter) {\n                    bodyStx.expose();\n                    var fv = _.filter(freeVarsInPattern(bodyStx.token.inner), function (pat) {\n                            // ignore \"patterns\"\n                            // that aren't in the\n                            // environment (treat\n                            // them like literals)\n                            return env.hasOwnProperty(pat);\n                        });\n                    var restrictedEnv = [];\n                    var nonScalar = _.find(fv, function (pat) {\n                            return env[pat].level > 0;\n                        });\n                    assert(typeof nonScalar !== 'undefined', 'must have a least one non-scalar in repeat');\n                    var repeatLength = env[nonScalar].match.length;\n                    var sameLength = _.all(fv, function (pat) {\n                            return env[pat].level === 0 || env[pat].match.length === repeatLength;\n                        });\n                    assert(sameLength, 'all non-scalars must have the same length');\n                    // create a list of envs restricted to the free vars\n                    _.each(_.range(repeatLength), function (idx$2) {\n                        var renv = {};\n                        _.each(fv, function (pat) {\n                            if (env[pat].level === 0) {\n                                // copy scalars over\n                                renv[pat] = env[pat];\n                            } else {\n                                // grab the match at this index\n                                renv[pat] = env[pat].match[idx$2];\n                            }\n                        });\n                        var allHaveMatch = Object.keys(renv).every(function (pat) {\n                                return hasMatch(renv[pat]);\n                            });\n                        if (allHaveMatch) {\n                            restrictedEnv.push(renv);\n                        }\n                    });\n                    var transcribed = _.map(restrictedEnv, function (renv) {\n                            if (bodyStx.group) {\n                                return transcribe(bodyStx.token.inner, macroNameStx, renv);\n                            } else {\n                                var newBody$2 = syntaxFromToken(_.clone(bodyStx.token), bodyStx);\n                                newBody$2.token.inner = transcribe(bodyStx.token.inner, macroNameStx, renv);\n                                return newBody$2;\n                            }\n                        });\n                    var joined;\n                    if (bodyStx.group) {\n                        joined = joinSyntaxArray(transcribed, bodyStx.separator);\n                    } else {\n                        joined = joinSyntax(transcribed, bodyStx.separator);\n                    }\n                    push.apply(acc, joined);\n                    return acc;\n                }\n                if (!env[bodyStx.token.value]) {\n                    throwSyntaxError('patterns', 'The pattern variable is not bound for the template', bodyStx);\n                } else if (env[bodyStx.token.value].level !== 1) {\n                    throwSyntaxError('patterns', 'Ellipses level does not match in the template', bodyStx);\n                }\n                push.apply(acc, joinRepeatedMatch(env[bodyStx.token.value].match, bodyStx.separator));\n                return acc;\n            } else {\n                if (bodyStx.token.type === parser.Token.Delimiter) {\n                    bodyStx.expose();\n                    var newBody = syntaxFromToken(_.clone(bodyStx.token), macroBody);\n                    newBody.token.inner = transcribe(bodyStx.token.inner, macroNameStx, env);\n                    acc.push(newBody);\n                    return acc;\n                }\n                if (isPatternVar(bodyStx) && Object.prototype.hasOwnProperty.bind(env)(bodyStx.token.value)) {\n                    if (!env[bodyStx.token.value]) {\n                        throwSyntaxError('patterns', 'The pattern variable is not bound for the template', bodyStx);\n                    } else if (env[bodyStx.token.value].level !== 0) {\n                        throwSyntaxError('patterns', 'Ellipses level does not match in the template', bodyStx);\n                    }\n                    push.apply(acc, takeLineContext(bodyStx, env[bodyStx.token.value].match));\n                    return acc;\n                }\n                acc.push(syntaxFromToken(_.clone(bodyStx.token), bodyStx));\n                return acc;\n            }\n        }, []).value();\n    }\n    function cloneMatch(oldMatch) {\n        var newMatch = {\n                success: oldMatch.success,\n                rest: oldMatch.rest,\n                patternEnv: {}\n            };\n        for (var pat in oldMatch.patternEnv) {\n            if (oldMatch.patternEnv.hasOwnProperty(pat)) {\n                newMatch.patternEnv[pat] = oldMatch.patternEnv[pat];\n            }\n        }\n        return newMatch;\n    }\n    function makeIdentityRule(pattern, isInfix) {\n        var _s = 1;\n        function traverse(s, infix) {\n            var pat = [];\n            var stx = [];\n            for (var i = 0; i < s.length; i++) {\n                var tok1 = s[i];\n                var tok2 = s[i + 1];\n                var tok3 = s[i + 2];\n                var tok4 = s[i + 3];\n                // Pattern vars, ignore classes\n                if (isPatternVar(tok1)) {\n                    pat.push(tok1);\n                    stx.push(tok1);\n                    if (tok2 && tok2.token.type === parser.Token.Punctuator && tok2.token.value === ':' && tok3 && tok3.token.type === parser.Token.Identifier) {\n                        pat.push(tok2, tok3);\n                        i += 2;\n                        if (tok3.token.value === 'invoke' || tok3.token.value === 'invokeRec' && tok4) {\n                            pat.push(tok4);\n                            i += 1;\n                        }\n                    }\n                } else if (tok1.token.type === parser.Token.Identifier && tok1.token.value === '_') {\n                    var uident = syntax.makeIdent('$__wildcard' + _s++, tok1);\n                    pat.push(uident);\n                    stx.push(uident);\n                } else if (tok1.token.type === parser.Token.Identifier && tok1.token.value === '$' && tok2 && tok2.token.type === parser.Token.Delimiter && tok2.token.value === '[]') {\n                    pat.push(tok1, tok2);\n                    stx.push(tok1, tok2);\n                    i += 1;\n                } else if (tok1.token.type === parser.Token.Delimiter) {\n                    var sub = traverse(tok1.token.inner, false);\n                    var clone = syntaxFromToken(_.clone(tok1.token), tok1);\n                    tok1.token.inner = sub.pattern;\n                    clone.token.inner = sub.body;\n                    pat.push(tok1);\n                    stx.push(clone);\n                } else if (infix && tok1.token.type === parser.Token.Punctuator && tok1.token.value === '|') {\n                    infix = false;\n                    pat.push(tok1);\n                } else {\n                    pat.push(tok1);\n                    stx.push(tok1);\n                }\n            }\n            return {\n                pattern: pat,\n                body: stx\n            };\n        }\n        return traverse(pattern, isInfix);\n    }\n    exports$2.loadPattern = loadPattern;\n    exports$2.matchPatterns = matchPatterns;\n    exports$2.matchLookbehind = matchLookbehind;\n    exports$2.transcribe = transcribe;\n    exports$2.matchPatternClass = matchPatternClass;\n    exports$2.takeLineContext = takeLineContext;\n    exports$2.takeLine = takeLine;\n    exports$2.typeIsLiteral = typeIsLiteral;\n    exports$2.cloneMatch = cloneMatch;\n    exports$2.makeIdentityRule = makeIdentityRule;\n}));\n//# sourceMappingURL=patterns.js.map"
  },
  {
    "path": "docs/editor/scripts/require.js",
    "content": "/*\n RequireJS 2.1.1 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.\n Available via the MIT or new BSD license.\n see: http://github.com/jrburke/requirejs for details\n*/\nvar requirejs,require,define;\n(function(W){function D(b){return M.call(b)===\"[object Function]\"}function E(b){return M.call(b)===\"[object Array]\"}function t(b,c){if(b){var d;for(d=0;d<b.length;d+=1)if(b[d]&&c(b[d],d,b))break}}function N(b,c){if(b){var d;for(d=b.length-1;d>-1;d-=1)if(b[d]&&c(b[d],d,b))break}}function A(b,c){for(var d in b)if(b.hasOwnProperty(d)&&c(b[d],d))break}function O(b,c,d,g){c&&A(c,function(c,j){if(d||!F.call(b,j))g&&typeof c!==\"string\"?(b[j]||(b[j]={}),O(b[j],c,d,g)):b[j]=c});return b}function r(b,c){return function(){return c.apply(b,\narguments)}}function X(b){if(!b)return b;var c=W;t(b.split(\".\"),function(b){c=c[b]});return c}function G(b,c,d,g){c=Error(c+\"\\nhttp://requirejs.org/docs/errors.html#\"+b);c.requireType=b;c.requireModules=g;if(d)c.originalError=d;return c}function ba(){if(H&&H.readyState===\"interactive\")return H;N(document.getElementsByTagName(\"script\"),function(b){if(b.readyState===\"interactive\")return H=b});return H}var g,s,u,y,q,B,H,I,Y,Z,ca=/(\\/\\*([\\s\\S]*?)\\*\\/|([^:]|^)\\/\\/(.*)$)/mg,da=/[^.]\\s*require\\s*\\(\\s*[\"']([^'\"\\s]+)[\"']\\s*\\)/g,\n$=/\\.js$/,ea=/^\\.\\//;s=Object.prototype;var M=s.toString,F=s.hasOwnProperty,fa=Array.prototype.splice,v=!!(typeof window!==\"undefined\"&&navigator&&document),aa=!v&&typeof importScripts!==\"undefined\",ga=v&&navigator.platform===\"PLAYSTATION 3\"?/^complete$/:/^(complete|loaded)$/,R=typeof opera!==\"undefined\"&&opera.toString()===\"[object Opera]\",w={},n={},P=[],J=!1;if(typeof define===\"undefined\"){if(typeof requirejs!==\"undefined\"){if(D(requirejs))return;n=requirejs;requirejs=void 0}typeof require!==\"undefined\"&&\n!D(require)&&(n=require,require=void 0);g=requirejs=function(b,c,d,p){var i,j=\"_\";!E(b)&&typeof b!==\"string\"&&(i=b,E(c)?(b=c,c=d,d=p):b=[]);if(i&&i.context)j=i.context;(p=w[j])||(p=w[j]=g.s.newContext(j));i&&p.configure(i);return p.require(b,c,d)};g.config=function(b){return g(b)};g.nextTick=typeof setTimeout!==\"undefined\"?function(b){setTimeout(b,4)}:function(b){b()};require||(require=g);g.version=\"2.1.1\";g.jsExtRegExp=/^\\/|:|\\?|\\.js$/;g.isBrowser=v;s=g.s={contexts:w,newContext:function(b){function c(a,\nf,x){var e,m,b,c,d,h,i,g=f&&f.split(\"/\");e=g;var j=k.map,l=j&&j[\"*\"];if(a&&a.charAt(0)===\".\")if(f){e=k.pkgs[f]?g=[f]:g.slice(0,g.length-1);f=a=e.concat(a.split(\"/\"));for(e=0;f[e];e+=1)if(m=f[e],m===\".\")f.splice(e,1),e-=1;else if(m===\"..\")if(e===1&&(f[2]===\"..\"||f[0]===\"..\"))break;else e>0&&(f.splice(e-1,2),e-=2);e=k.pkgs[f=a[0]];a=a.join(\"/\");e&&a===f+\"/\"+e.main&&(a=f)}else a.indexOf(\"./\")===0&&(a=a.substring(2));if(x&&(g||l)&&j){f=a.split(\"/\");for(e=f.length;e>0;e-=1){b=f.slice(0,e).join(\"/\");if(g)for(m=\ng.length;m>0;m-=1)if(x=j[g.slice(0,m).join(\"/\")])if(x=x[b]){c=x;d=e;break}if(c)break;!h&&l&&l[b]&&(h=l[b],i=e)}!c&&h&&(c=h,d=i);c&&(f.splice(0,d,c),a=f.join(\"/\"))}return a}function d(a){v&&t(document.getElementsByTagName(\"script\"),function(f){if(f.getAttribute(\"data-requiremodule\")===a&&f.getAttribute(\"data-requirecontext\")===h.contextName)return f.parentNode.removeChild(f),!0})}function p(a){var f=k.paths[a];if(f&&E(f)&&f.length>1)return d(a),f.shift(),h.require.undef(a),h.require([a]),!0}function i(a){var f,\nb=a?a.indexOf(\"!\"):-1;b>-1&&(f=a.substring(0,b),a=a.substring(b+1,a.length));return[f,a]}function j(a,f,b,e){var m,K,d=null,g=f?f.name:null,j=a,l=!0,k=\"\";a||(l=!1,a=\"_@r\"+(M+=1));a=i(a);d=a[0];a=a[1];d&&(d=c(d,g,e),K=o[d]);a&&(d?k=K&&K.normalize?K.normalize(a,function(a){return c(a,g,e)}):c(a,g,e):(k=c(a,g,e),a=i(k),d=a[0],k=a[1],b=!0,m=h.nameToUrl(k)));b=d&&!K&&!b?\"_unnormalized\"+(N+=1):\"\";return{prefix:d,name:k,parentMap:f,unnormalized:!!b,url:m,originalName:j,isDefine:l,id:(d?d+\"!\"+k:k)+b}}function n(a){var f=\na.id,b=l[f];b||(b=l[f]=new h.Module(a));return b}function q(a,f,b){var e=a.id,m=l[e];if(F.call(o,e)&&(!m||m.defineEmitComplete))f===\"defined\"&&b(o[e]);else n(a).on(f,b)}function z(a,f){var b=a.requireModules,e=!1;if(f)f(a);else if(t(b,function(f){if(f=l[f])f.error=a,f.events.error&&(e=!0,f.emit(\"error\",a))}),!e)g.onError(a)}function s(){P.length&&(fa.apply(C,[C.length-1,0].concat(P)),P=[])}function u(a,f,b){var e=a.map.id;a.error?a.emit(\"error\",a.error):(f[e]=!0,t(a.depMaps,function(e,c){var d=e.id,\ng=l[d];g&&!a.depMatched[c]&&!b[d]&&(f[d]?(a.defineDep(c,o[d]),a.check()):u(g,f,b))}),b[e]=!0)}function w(){var a,f,b,e,m=(b=k.waitSeconds*1E3)&&h.startTime+b<(new Date).getTime(),c=[],g=[],i=!1,j=!0;if(!S){S=!0;A(l,function(b){a=b.map;f=a.id;if(b.enabled&&(a.isDefine||g.push(b),!b.error))if(!b.inited&&m)p(f)?i=e=!0:(c.push(f),d(f));else if(!b.inited&&b.fetched&&a.isDefine&&(i=!0,!a.prefix))return j=!1});if(m&&c.length)return b=G(\"timeout\",\"Load timeout for modules: \"+c,null,c),b.contextName=h.contextName,\nz(b);j&&t(g,function(a){u(a,{},{})});if((!m||e)&&i)if((v||aa)&&!T)T=setTimeout(function(){T=0;w()},50);S=!1}}function y(a){n(j(a[0],null,!0)).init(a[1],a[2])}function B(a){var a=a.currentTarget||a.srcElement,b=h.onScriptLoad;a.detachEvent&&!R?a.detachEvent(\"onreadystatechange\",b):a.removeEventListener(\"load\",b,!1);b=h.onScriptError;a.detachEvent&&!R||a.removeEventListener(\"error\",b,!1);return{node:a,id:a&&a.getAttribute(\"data-requiremodule\")}}function I(){var a;for(s();C.length;)if(a=C.shift(),a[0]===\nnull)return z(G(\"mismatch\",\"Mismatched anonymous define() module: \"+a[a.length-1]));else y(a)}var S,U,h,L,T,k={waitSeconds:7,baseUrl:\"./\",paths:{},pkgs:{},shim:{},map:{},config:{}},l={},V={},C=[],o={},Q={},M=1,N=1;L={require:function(a){return a.require?a.require:a.require=h.makeRequire(a.map)},exports:function(a){a.usingExports=!0;if(a.map.isDefine)return a.exports?a.exports:a.exports=o[a.map.id]={}},module:function(a){return a.module?a.module:a.module={id:a.map.id,uri:a.map.url,config:function(){return k.config&&\nk.config[a.map.id]||{}},exports:o[a.map.id]}}};U=function(a){this.events=V[a.id]||{};this.map=a;this.shim=k.shim[a.id];this.depExports=[];this.depMaps=[];this.depMatched=[];this.pluginMaps={};this.depCount=0};U.prototype={init:function(a,b,c,e){e=e||{};if(!this.inited){this.factory=b;if(c)this.on(\"error\",c);else this.events.error&&(c=r(this,function(a){this.emit(\"error\",a)}));this.depMaps=a&&a.slice(0);this.errback=c;this.inited=!0;this.ignore=e.ignore;e.enabled||this.enabled?this.enable():this.check()}},\ndefineDep:function(a,b){this.depMatched[a]||(this.depMatched[a]=!0,this.depCount-=1,this.depExports[a]=b)},fetch:function(){if(!this.fetched){this.fetched=!0;h.startTime=(new Date).getTime();var a=this.map;if(this.shim)h.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],r(this,function(){return a.prefix?this.callPlugin():this.load()}));else return a.prefix?this.callPlugin():this.load()}},load:function(){var a=this.map.url;Q[a]||(Q[a]=!0,h.load(this.map.id,a))},check:function(){if(this.enabled&&\n!this.enabling){var a,b,c=this.map.id;b=this.depExports;var e=this.exports,m=this.factory;if(this.inited)if(this.error)this.emit(\"error\",this.error);else{if(!this.defining){this.defining=!0;if(this.depCount<1&&!this.defined){if(D(m)){if(this.events.error)try{e=h.execCb(c,m,b,e)}catch(d){a=d}else e=h.execCb(c,m,b,e);if(this.map.isDefine)if((b=this.module)&&b.exports!==void 0&&b.exports!==this.exports)e=b.exports;else if(e===void 0&&this.usingExports)e=this.exports;if(a)return a.requireMap=this.map,\na.requireModules=[this.map.id],a.requireType=\"define\",z(this.error=a)}else e=m;this.exports=e;if(this.map.isDefine&&!this.ignore&&(o[c]=e,g.onResourceLoad))g.onResourceLoad(h,this.map,this.depMaps);delete l[c];this.defined=!0}this.defining=!1;if(this.defined&&!this.defineEmitted)this.defineEmitted=!0,this.emit(\"defined\",this.exports),this.defineEmitComplete=!0}}else this.fetch()}},callPlugin:function(){var a=this.map,b=a.id,d=j(a.prefix);this.depMaps.push(d);q(d,\"defined\",r(this,function(e){var m,\nd;d=this.map.name;var x=this.map.parentMap?this.map.parentMap.name:null,i=h.makeRequire(a.parentMap,{enableBuildCallback:!0,skipMap:!0});if(this.map.unnormalized){if(e.normalize&&(d=e.normalize(d,function(a){return c(a,x,!0)})||\"\"),e=j(a.prefix+\"!\"+d,this.map.parentMap),q(e,\"defined\",r(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),d=l[e.id]){this.depMaps.push(e);if(this.events.error)d.on(\"error\",r(this,function(a){this.emit(\"error\",a)}));d.enable()}}else m=r(this,\nfunction(a){this.init([],function(){return a},null,{enabled:!0})}),m.error=r(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];A(l,function(a){a.map.id.indexOf(b+\"_unnormalized\")===0&&delete l[a.map.id]});z(a)}),m.fromText=r(this,function(b,e){var f=a.name,c=j(f),d=J;e&&(b=e);d&&(J=!1);n(c);try{g.exec(b)}catch(x){throw Error(\"fromText eval for \"+f+\" failed: \"+x);}d&&(J=!0);this.depMaps.push(c);h.completeLoad(f);i([f],m)}),e.load(a.name,i,m,k)}));h.enable(d,this);this.pluginMaps[d.id]=\nd},enable:function(){this.enabling=this.enabled=!0;t(this.depMaps,r(this,function(a,b){var c,e;if(typeof a===\"string\"){a=j(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=L[a.id]){this.depExports[b]=c(this);return}this.depCount+=1;q(a,\"defined\",r(this,function(a){this.defineDep(b,a);this.check()}));this.errback&&q(a,\"error\",this.errback)}c=a.id;e=l[c];!L[c]&&e&&!e.enabled&&h.enable(a,this)}));A(this.pluginMaps,r(this,function(a){var b=l[a.id];b&&!b.enabled&&\nh.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){t(this.events[a],function(a){a(b)});a===\"error\"&&delete this.events[a]}};h={config:k,contextName:b,registry:l,defined:o,urlFetched:Q,defQueue:C,Module:U,makeModuleMap:j,nextTick:g.nextTick,configure:function(a){a.baseUrl&&a.baseUrl.charAt(a.baseUrl.length-1)!==\"/\"&&(a.baseUrl+=\"/\");var b=k.pkgs,c=k.shim,e={paths:!0,config:!0,map:!0};A(a,function(a,b){e[b]?\nb===\"map\"?O(k[b],a,!0,!0):O(k[b],a,!0):k[b]=a});if(a.shim)A(a.shim,function(a,b){E(a)&&(a={deps:a});if(a.exports&&!a.exportsFn)a.exportsFn=h.makeShimExports(a);c[b]=a}),k.shim=c;if(a.packages)t(a.packages,function(a){a=typeof a===\"string\"?{name:a}:a;b[a.name]={name:a.name,location:a.location||a.name,main:(a.main||\"main\").replace(ea,\"\").replace($,\"\")}}),k.pkgs=b;A(l,function(a,b){if(!a.inited&&!a.map.unnormalized)a.map=j(b)});if(a.deps||a.callback)h.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;\na.init&&(b=a.init.apply(W,arguments));return b||X(a.exports)}},makeRequire:function(a,f){function d(e,c,i){var k,p;if(f.enableBuildCallback&&c&&D(c))c.__requireJsBuild=!0;if(typeof e===\"string\"){if(D(c))return z(G(\"requireargs\",\"Invalid require call\"),i);if(a&&L[e])return L[e](l[a.id]);if(g.get)return g.get(h,e,a);k=j(e,a,!1,!0);k=k.id;return!F.call(o,k)?z(G(\"notloaded\",'Module name \"'+k+'\" has not been loaded yet for context: '+b+(a?\"\":\". Use require([])\"))):o[k]}I();h.nextTick(function(){I();p=\nn(j(null,a));p.skipMap=f.skipMap;p.init(e,c,i,{enabled:!0});w()});return d}f=f||{};O(d,{isBrowser:v,toUrl:function(b){var d=b.lastIndexOf(\".\"),f=null;d!==-1&&(f=b.substring(d,b.length),b=b.substring(0,d));return h.nameToUrl(c(b,a&&a.id,!0),f)},defined:function(b){b=j(b,a,!1,!0).id;return F.call(o,b)},specified:function(b){b=j(b,a,!1,!0).id;return F.call(o,b)||F.call(l,b)}});if(!a)d.undef=function(b){s();var c=j(b,a,!0),d=l[b];delete o[b];delete Q[c.url];delete V[b];if(d){if(d.events.defined)V[b]=\nd.events;delete l[b]}};return d},enable:function(a){l[a.id]&&n(a).enable()},completeLoad:function(a){var b,c,d=k.shim[a]||{},g=d.exports;for(s();C.length;){c=C.shift();if(c[0]===null){c[0]=a;if(b)break;b=!0}else c[0]===a&&(b=!0);y(c)}c=l[a];if(!b&&!o[a]&&c&&!c.inited)if(k.enforceDefine&&(!g||!X(g)))if(p(a))return;else return z(G(\"nodefine\",\"No define call for \"+a,null,[a]));else y([a,d.deps||[],d.exportsFn]);w()},nameToUrl:function(a,b){var c,d,i,h,j,l;if(g.jsExtRegExp.test(a))h=a+(b||\"\");else{c=\nk.paths;d=k.pkgs;h=a.split(\"/\");for(j=h.length;j>0;j-=1)if(l=h.slice(0,j).join(\"/\"),i=d[l],l=c[l]){E(l)&&(l=l[0]);h.splice(0,j,l);break}else if(i){c=a===i.name?i.location+\"/\"+i.main:i.location;h.splice(0,j,c);break}h=h.join(\"/\");h+=b||(/\\?/.test(h)?\"\":\".js\");h=(h.charAt(0)===\"/\"||h.match(/^[\\w\\+\\.\\-]+:/)?\"\":k.baseUrl)+h}return k.urlArgs?h+((h.indexOf(\"?\")===-1?\"?\":\"&\")+k.urlArgs):h},load:function(a,b){g.load(h,a,b)},execCb:function(a,b,c,d){return b.apply(d,c)},onScriptLoad:function(a){if(a.type===\n\"load\"||ga.test((a.currentTarget||a.srcElement).readyState))H=null,a=B(a),h.completeLoad(a.id)},onScriptError:function(a){var b=B(a);if(!p(b.id))return z(G(\"scripterror\",\"Script error\",a,[b.id]))}};h.require=h.makeRequire();return h}};g({});t([\"toUrl\",\"undef\",\"defined\",\"specified\"],function(b){g[b]=function(){var c=w._;return c.require[b].apply(c,arguments)}});if(v&&(u=s.head=document.getElementsByTagName(\"head\")[0],y=document.getElementsByTagName(\"base\")[0]))u=s.head=y.parentNode;g.onError=function(b){throw b;\n};g.load=function(b,c,d){var g=b&&b.config||{},i;if(v)return i=g.xhtml?document.createElementNS(\"http://www.w3.org/1999/xhtml\",\"html:script\"):document.createElement(\"script\"),i.type=g.scriptType||\"text/javascript\",i.charset=\"utf-8\",i.async=!0,i.setAttribute(\"data-requirecontext\",b.contextName),i.setAttribute(\"data-requiremodule\",c),i.attachEvent&&!(i.attachEvent.toString&&i.attachEvent.toString().indexOf(\"[native code\")<0)&&!R?(J=!0,i.attachEvent(\"onreadystatechange\",b.onScriptLoad)):(i.addEventListener(\"load\",\nb.onScriptLoad,!1),i.addEventListener(\"error\",b.onScriptError,!1)),i.src=d,I=i,y?u.insertBefore(i,y):u.appendChild(i),I=null,i;else aa&&(importScripts(d),b.completeLoad(c))};v&&N(document.getElementsByTagName(\"script\"),function(b){if(!u)u=b.parentNode;if(q=b.getAttribute(\"data-main\")){if(!n.baseUrl)B=q.split(\"/\"),Y=B.pop(),Z=B.length?B.join(\"/\")+\"/\":\"./\",n.baseUrl=Z,q=Y;q=q.replace($,\"\");n.deps=n.deps?n.deps.concat(q):[q];return!0}});define=function(b,c,d){var g,i;typeof b!==\"string\"&&(d=c,c=b,b=\nnull);E(c)||(d=c,c=[]);!c.length&&D(d)&&d.length&&(d.toString().replace(ca,\"\").replace(da,function(b,d){c.push(d)}),c=(d.length===1?[\"require\"]:[\"require\",\"exports\",\"module\"]).concat(c));if(J&&(g=I||ba()))b||(b=g.getAttribute(\"data-requiremodule\")),i=w[g.getAttribute(\"data-requirecontext\")];(i?i.defQueue:P).push([b,c,d])};define.amd={jQuery:!0};g.exec=function(b){return eval(b)};g(n)}})(this);\n"
  },
  {
    "path": "docs/editor/scripts/scopedEval.js",
    "content": "// thou shalt not macro expand me...all kinds of hygiene hackary\n// with strings and `with`.\n\n\n(function (root, factory) {\n    if (typeof exports === 'object') {\n        // CommonJS\n        factory(exports);\n    } else if (typeof define === 'function' && define.amd) {\n        // AMD. Register as an anonymous module.\n        define(['exports'], factory);\n    }\n}(this, function(exports) {\n\n    exports.scopedEval = function(source, global) {\n        return eval('(function() { with(global) { return ' + source + ' } }).call(global, global);');\n    };\n\n}));\n\n"
  },
  {
    "path": "docs/editor/scripts/sweet.js",
    "content": "(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"sweet\"] = factory();\n\telse\n\t\troot[\"sweet\"] = factory();\n})(this, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n\n\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t__webpack_require__(1);\n\tmodule.exports = __webpack_require__(1);\n\n\n/***/ },\n/* 1 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.compile = compile;\n\n\tvar _sweet = __webpack_require__(2);\n\n\tvar _storeLoader = __webpack_require__(4);\n\n\tvar _storeLoader2 = _interopRequireDefault(_storeLoader);\n\n\tvar _store = __webpack_require__(73);\n\n\tvar _store2 = _interopRequireDefault(_store);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tclass BrowserStoreLoader extends _storeLoader2.default {\n\n\t  constructor(baseDir, store) {\n\t    super(baseDir, store, true);\n\t  }\n\n\t  fetch({ name, address }) {\n\t    if (this.store.has(address.path)) {\n\t      return this.store.get(address.path);\n\t    }\n\t    throw new Error(`The module ${ name } is not in the debug store: addr.path is ${ address.path }`);\n\t  }\n\n\t  freshStore() {\n\t    return new _store2.default({});\n\t  }\n\n\t  eval(source, store) {\n\t    return (0, eval)(source);\n\t  }\n\t}\n\n\tfunction compile(source, helpers) {\n\t  let s = new Map();\n\t  s.set('main.js', source);\n\t  s.set('sweet.js/helpers.js', helpers);\n\t  s.set('sweet.js/helpers', helpers);\n\t  let loader = new BrowserStoreLoader('.', s);\n\t  return (0, _sweet.compile)('main.js', loader);\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9icm93c2VyLXN3ZWV0LmpzIl0sIm5hbWVzIjpbImNvbXBpbGUiLCJCcm93c2VyU3RvcmVMb2FkZXIiLCJjb25zdHJ1Y3RvciIsImJhc2VEaXIiLCJzdG9yZSIsImZldGNoIiwibmFtZSIsImFkZHJlc3MiLCJoYXMiLCJwYXRoIiwiZ2V0IiwiRXJyb3IiLCJmcmVzaFN0b3JlIiwiZXZhbCIsInNvdXJjZSIsImhlbHBlcnMiLCJzIiwiTWFwIiwic2V0IiwibG9hZGVyIl0sIm1hcHBpbmdzIjoiOzs7OztRQTZCZ0JBLE8sR0FBQUEsTzs7QUE3QmhCOztBQUNBOzs7O0FBQ0E7Ozs7OztBQUVBLE1BQU1DLGtCQUFOLCtCQUE2Qzs7QUFHM0NDLGNBQVlDLE9BQVosRUFBNkJDLEtBQTdCLEVBQXlEO0FBQ3ZELFVBQU1ELE9BQU4sRUFBZUMsS0FBZixFQUFzQixJQUF0QjtBQUNEOztBQUVEQyxRQUFNLEVBQUVDLElBQUYsRUFBUUMsT0FBUixFQUFOLEVBQXlEO0FBQ3ZELFFBQUksS0FBS0gsS0FBTCxDQUFXSSxHQUFYLENBQWVELFFBQVFFLElBQXZCLENBQUosRUFBa0M7QUFDaEMsYUFBTyxLQUFLTCxLQUFMLENBQVdNLEdBQVgsQ0FBZUgsUUFBUUUsSUFBdkIsQ0FBUDtBQUNEO0FBQ0QsVUFBTSxJQUFJRSxLQUFKLENBQ0gsZUFBYUwsSUFBSyw4Q0FBMkNDLFFBQVFFLElBQUssR0FEdkUsQ0FBTjtBQUdEOztBQUVERyxlQUFhO0FBQ1gsV0FBTyxvQkFBVSxFQUFWLENBQVA7QUFDRDs7QUFFREMsT0FBS0MsTUFBTCxFQUFxQlYsS0FBckIsRUFBbUM7QUFDakMsV0FBTyxDQUFDLEdBQUdTLElBQUosRUFBVUMsTUFBVixDQUFQO0FBQ0Q7QUF0QjBDOztBQXlCdEMsU0FBU2QsT0FBVCxDQUFpQmMsTUFBakIsRUFBeUJDLE9BQXpCLEVBQWtDO0FBQ3ZDLE1BQUlDLElBQUksSUFBSUMsR0FBSixFQUFSO0FBQ0FELElBQUVFLEdBQUYsQ0FBTSxTQUFOLEVBQWlCSixNQUFqQjtBQUNBRSxJQUFFRSxHQUFGLENBQU0scUJBQU4sRUFBNkJILE9BQTdCO0FBQ0FDLElBQUVFLEdBQUYsQ0FBTSxrQkFBTixFQUEwQkgsT0FBMUI7QUFDQSxNQUFJSSxTQUFTLElBQUlsQixrQkFBSixDQUF1QixHQUF2QixFQUE0QmUsQ0FBNUIsQ0FBYjtBQUNBLFNBQU8sb0JBQWEsU0FBYixFQUF3QkcsTUFBeEIsQ0FBUDtBQUNEIiwiZmlsZSI6ImJyb3dzZXItc3dlZXQuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjb21waWxlIGFzIHN3ZWV0Q29tcGlsZSB9IGZyb20gJy4vc3dlZXQnO1xuaW1wb3J0IFN0b3JlTG9hZGVyIGZyb20gJy4vc3RvcmUtbG9hZGVyJztcbmltcG9ydCBTdG9yZSBmcm9tICcuL3N0b3JlJztcblxuY2xhc3MgQnJvd3NlclN0b3JlTG9hZGVyIGV4dGVuZHMgU3RvcmVMb2FkZXIge1xuICBzdG9yZTogTWFwPHN0cmluZywgc3RyaW5nPjtcblxuICBjb25zdHJ1Y3RvcihiYXNlRGlyOiBzdHJpbmcsIHN0b3JlOiBNYXA8c3RyaW5nLCBzdHJpbmc+KSB7XG4gICAgc3VwZXIoYmFzZURpciwgc3RvcmUsIHRydWUpO1xuICB9XG5cbiAgZmV0Y2goeyBuYW1lLCBhZGRyZXNzIH06IHsgbmFtZTogc3RyaW5nLCBhZGRyZXNzOiBhbnkgfSkge1xuICAgIGlmICh0aGlzLnN0b3JlLmhhcyhhZGRyZXNzLnBhdGgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5zdG9yZS5nZXQoYWRkcmVzcy5wYXRoKTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYFRoZSBtb2R1bGUgJHtuYW1lfSBpcyBub3QgaW4gdGhlIGRlYnVnIHN0b3JlOiBhZGRyLnBhdGggaXMgJHthZGRyZXNzLnBhdGh9YCxcbiAgICApO1xuICB9XG5cbiAgZnJlc2hTdG9yZSgpIHtcbiAgICByZXR1cm4gbmV3IFN0b3JlKHt9KTtcbiAgfVxuXG4gIGV2YWwoc291cmNlOiBzdHJpbmcsIHN0b3JlOiBTdG9yZSkge1xuICAgIHJldHVybiAoMCwgZXZhbCkoc291cmNlKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY29tcGlsZShzb3VyY2UsIGhlbHBlcnMpIHtcbiAgbGV0IHMgPSBuZXcgTWFwKCk7XG4gIHMuc2V0KCdtYWluLmpzJywgc291cmNlKTtcbiAgcy5zZXQoJ3N3ZWV0LmpzL2hlbHBlcnMuanMnLCBoZWxwZXJzKTtcbiAgcy5zZXQoJ3N3ZWV0LmpzL2hlbHBlcnMnLCBoZWxwZXJzKTtcbiAgbGV0IGxvYWRlciA9IG5ldyBCcm93c2VyU3RvcmVMb2FkZXIoJy4nLCBzKTtcbiAgcmV0dXJuIHN3ZWV0Q29tcGlsZSgnbWFpbi5qcycsIGxvYWRlcik7XG59XG4iXX0=\n\n/***/ },\n/* 2 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.parse = parse;\n\texports.compile = compile;\n\n\tvar _babelCore = __webpack_require__(3);\n\n\tfunction compileModule(entryPath, loader, refererName) {\n\t  return loader.compile(entryPath, refererName, false);\n\t}\n\n\tfunction parse(entryPath, loader, options) {\n\t  let refererName;\n\t  if (options != null) {\n\t    refererName = options.refererName;\n\t  }\n\t  return compileModule(entryPath, loader, refererName).parse();\n\t}\n\n\tfunction compile(entryPath, loader, options) {\n\t  let refererName,\n\t      noBabel = true;\n\t  if (options != null) {\n\t    refererName = options.refererName;\n\t    noBabel = options.noBabel;\n\t  }\n\t  let code = compileModule(entryPath, loader, refererName).codegen();\n\t  if (noBabel) {\n\t    return {\n\t      code\n\t    };\n\t  }\n\t  return (0, _babelCore.transform)(code, {\n\t    babelrc: true\n\t  });\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zd2VldC5qcyJdLCJuYW1lcyI6WyJwYXJzZSIsImNvbXBpbGUiLCJjb21waWxlTW9kdWxlIiwiZW50cnlQYXRoIiwibG9hZGVyIiwicmVmZXJlck5hbWUiLCJvcHRpb25zIiwibm9CYWJlbCIsImNvZGUiLCJjb2RlZ2VuIiwiYmFiZWxyYyJdLCJtYXBwaW5ncyI6Ijs7Ozs7UUFtQmdCQSxLLEdBQUFBLEs7UUFZQUMsTyxHQUFBQSxPOztBQTdCaEI7O0FBU0EsU0FBU0MsYUFBVCxDQUNFQyxTQURGLEVBRUVDLE1BRkYsRUFHRUMsV0FIRixFQUlFO0FBQ0EsU0FBT0QsT0FBT0gsT0FBUCxDQUFlRSxTQUFmLEVBQTBCRSxXQUExQixFQUF1QyxLQUF2QyxDQUFQO0FBQ0Q7O0FBRU0sU0FBU0wsS0FBVCxDQUNMRyxTQURLLEVBRUxDLE1BRkssRUFHTEUsT0FISyxFQUlMO0FBQ0EsTUFBSUQsV0FBSjtBQUNBLE1BQUlDLFdBQVcsSUFBZixFQUFxQjtBQUNuQkQsa0JBQWNDLFFBQVFELFdBQXRCO0FBQ0Q7QUFDRCxTQUFPSCxjQUFjQyxTQUFkLEVBQXlCQyxNQUF6QixFQUFpQ0MsV0FBakMsRUFBOENMLEtBQTlDLEVBQVA7QUFDRDs7QUFFTSxTQUFTQyxPQUFULENBQ0xFLFNBREssRUFFTEMsTUFGSyxFQUdMRSxPQUhLLEVBSUw7QUFDQSxNQUFJRCxXQUFKO0FBQUEsTUFBaUJFLFVBQVUsSUFBM0I7QUFDQSxNQUFJRCxXQUFXLElBQWYsRUFBcUI7QUFDbkJELGtCQUFjQyxRQUFRRCxXQUF0QjtBQUNBRSxjQUFVRCxRQUFRQyxPQUFsQjtBQUNEO0FBQ0QsTUFBSUMsT0FBT04sY0FBY0MsU0FBZCxFQUF5QkMsTUFBekIsRUFBaUNDLFdBQWpDLEVBQThDSSxPQUE5QyxFQUFYO0FBQ0EsTUFBSUYsT0FBSixFQUFhO0FBQ1gsV0FBTztBQUNMQztBQURLLEtBQVA7QUFHRDtBQUNELFNBQU8sMEJBQU1BLElBQU4sRUFBWTtBQUNqQkUsYUFBUztBQURRLEdBQVosQ0FBUDtBQUdEIiwiZmlsZSI6InN3ZWV0LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbmltcG9ydCB0eXBlIFN3ZWV0TG9hZGVyIGZyb20gJy4vc3dlZXQtbG9hZGVyJztcbmltcG9ydCB7IHRyYW5zZm9ybSBhcyBiYWJlbCB9IGZyb20gJ2JhYmVsLWNvcmUnO1xuXG50eXBlIENvbXBpbGVPcHRpb25zID0ge1xuICByZWZlcmVyTmFtZT86IHN0cmluZyxcbiAgZGVidWdTdG9yZT86IE1hcDxzdHJpbmcsIHN0cmluZz4sXG4gIG5vQmFiZWw/OiBib29sZWFuLFxuICBsb2FkZXI6IFN3ZWV0TG9hZGVyLFxufTtcblxuZnVuY3Rpb24gY29tcGlsZU1vZHVsZShcbiAgZW50cnlQYXRoOiBzdHJpbmcsXG4gIGxvYWRlcjogU3dlZXRMb2FkZXIsXG4gIHJlZmVyZXJOYW1lPzogc3RyaW5nLFxuKSB7XG4gIHJldHVybiBsb2FkZXIuY29tcGlsZShlbnRyeVBhdGgsIHJlZmVyZXJOYW1lLCBmYWxzZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZShcbiAgZW50cnlQYXRoOiBzdHJpbmcsXG4gIGxvYWRlcjogU3dlZXRMb2FkZXIsXG4gIG9wdGlvbnM/OiBDb21waWxlT3B0aW9ucyxcbikge1xuICBsZXQgcmVmZXJlck5hbWU7XG4gIGlmIChvcHRpb25zICE9IG51bGwpIHtcbiAgICByZWZlcmVyTmFtZSA9IG9wdGlvbnMucmVmZXJlck5hbWU7XG4gIH1cbiAgcmV0dXJuIGNvbXBpbGVNb2R1bGUoZW50cnlQYXRoLCBsb2FkZXIsIHJlZmVyZXJOYW1lKS5wYXJzZSgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29tcGlsZShcbiAgZW50cnlQYXRoOiBzdHJpbmcsXG4gIGxvYWRlcjogU3dlZXRMb2FkZXIsXG4gIG9wdGlvbnM/OiBDb21waWxlT3B0aW9ucyxcbikge1xuICBsZXQgcmVmZXJlck5hbWUsIG5vQmFiZWwgPSB0cnVlO1xuICBpZiAob3B0aW9ucyAhPSBudWxsKSB7XG4gICAgcmVmZXJlck5hbWUgPSBvcHRpb25zLnJlZmVyZXJOYW1lO1xuICAgIG5vQmFiZWwgPSBvcHRpb25zLm5vQmFiZWw7XG4gIH1cbiAgbGV0IGNvZGUgPSBjb21waWxlTW9kdWxlKGVudHJ5UGF0aCwgbG9hZGVyLCByZWZlcmVyTmFtZSkuY29kZWdlbigpO1xuICBpZiAobm9CYWJlbCkge1xuICAgIHJldHVybiB7XG4gICAgICBjb2RlLFxuICAgIH07XG4gIH1cbiAgcmV0dXJuIGJhYmVsKGNvZGUsIHtcbiAgICBiYWJlbHJjOiB0cnVlLFxuICB9KTtcbn1cbiJdfQ==\n\n/***/ },\n/* 3 */\n/***/ function(module, exports) {\n\n\t/* (ignored) */\n\n/***/ },\n/* 4 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\n\tvar _sweetLoader = __webpack_require__(5);\n\n\tvar _sweetLoader2 = _interopRequireDefault(_sweetLoader);\n\n\tvar _vm = __webpack_require__(74);\n\n\tvar _vm2 = _interopRequireDefault(_vm);\n\n\tvar _store = __webpack_require__(73);\n\n\tvar _store2 = _interopRequireDefault(_store);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.default = class extends _sweetLoader2.default {\n\n\t  constructor(baseDir, store, noBabel = false) {\n\t    super(baseDir, { noBabel });\n\t    this.store = store;\n\t  }\n\n\t  fetch({ name, address }) {\n\t    if (this.store.has(address.path)) {\n\t      return this.store.get(address.path);\n\t    }\n\t    throw new Error(`The module ${ name } is not in the debug store: addr.path is ${ address.path }`);\n\t  }\n\n\t  freshStore() {\n\t    return new _store2.default(_vm2.default.createContext());\n\t  }\n\n\t  eval(source, store) {\n\t    return _vm2.default.runInContext(source, store.getBackingObject());\n\t  }\n\t};\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yZS1sb2FkZXIuanMiXSwibmFtZXMiOlsiY29uc3RydWN0b3IiLCJiYXNlRGlyIiwic3RvcmUiLCJub0JhYmVsIiwiZmV0Y2giLCJuYW1lIiwiYWRkcmVzcyIsImhhcyIsInBhdGgiLCJnZXQiLCJFcnJvciIsImZyZXNoU3RvcmUiLCJjcmVhdGVDb250ZXh0IiwiZXZhbCIsInNvdXJjZSIsInJ1bkluQ29udGV4dCIsImdldEJhY2tpbmdPYmplY3QiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7O2tCQUVlLG9DQUEwQjs7QUFHdkNBLGNBQ0VDLE9BREYsRUFFRUMsS0FGRixFQUdFQyxVQUFtQixLQUhyQixFQUlFO0FBQ0EsVUFBTUYsT0FBTixFQUFlLEVBQUVFLE9BQUYsRUFBZjtBQUNBLFNBQUtELEtBQUwsR0FBYUEsS0FBYjtBQUNEOztBQUVERSxRQUFNLEVBQUVDLElBQUYsRUFBUUMsT0FBUixFQUFOLEVBQXlEO0FBQ3ZELFFBQUksS0FBS0osS0FBTCxDQUFXSyxHQUFYLENBQWVELFFBQVFFLElBQXZCLENBQUosRUFBa0M7QUFDaEMsYUFBTyxLQUFLTixLQUFMLENBQVdPLEdBQVgsQ0FBZUgsUUFBUUUsSUFBdkIsQ0FBUDtBQUNEO0FBQ0QsVUFBTSxJQUFJRSxLQUFKLENBQ0gsZUFBYUwsSUFBSyw4Q0FBMkNDLFFBQVFFLElBQUssR0FEdkUsQ0FBTjtBQUdEOztBQUVERyxlQUFhO0FBQ1gsV0FBTyxvQkFBVSxhQUFHQyxhQUFILEVBQVYsQ0FBUDtBQUNEOztBQUVEQyxPQUFLQyxNQUFMLEVBQXFCWixLQUFyQixFQUFtQztBQUNqQyxXQUFPLGFBQUdhLFlBQUgsQ0FBZ0JELE1BQWhCLEVBQXdCWixNQUFNYyxnQkFBTixFQUF4QixDQUFQO0FBQ0Q7QUEzQnNDLEMiLCJmaWxlIjoic3RvcmUtbG9hZGVyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbmltcG9ydCBTd2VldExvYWRlciBmcm9tICcuL3N3ZWV0LWxvYWRlcic7XG5pbXBvcnQgdm0gZnJvbSAndm0nO1xuaW1wb3J0IFN0b3JlIGZyb20gJy4vc3RvcmUnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBleHRlbmRzIFN3ZWV0TG9hZGVyIHtcbiAgc3RvcmU6IE1hcDxzdHJpbmcsIHN0cmluZz47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgYmFzZURpcjogc3RyaW5nLFxuICAgIHN0b3JlOiBNYXA8c3RyaW5nLCBzdHJpbmc+LFxuICAgIG5vQmFiZWw6IGJvb2xlYW4gPSBmYWxzZSxcbiAgKSB7XG4gICAgc3VwZXIoYmFzZURpciwgeyBub0JhYmVsIH0pO1xuICAgIHRoaXMuc3RvcmUgPSBzdG9yZTtcbiAgfVxuXG4gIGZldGNoKHsgbmFtZSwgYWRkcmVzcyB9OiB7IG5hbWU6IHN0cmluZywgYWRkcmVzczogYW55IH0pIHtcbiAgICBpZiAodGhpcy5zdG9yZS5oYXMoYWRkcmVzcy5wYXRoKSkge1xuICAgICAgcmV0dXJuIHRoaXMuc3RvcmUuZ2V0KGFkZHJlc3MucGF0aCk7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBUaGUgbW9kdWxlICR7bmFtZX0gaXMgbm90IGluIHRoZSBkZWJ1ZyBzdG9yZTogYWRkci5wYXRoIGlzICR7YWRkcmVzcy5wYXRofWAsXG4gICAgKTtcbiAgfVxuXG4gIGZyZXNoU3RvcmUoKSB7XG4gICAgcmV0dXJuIG5ldyBTdG9yZSh2bS5jcmVhdGVDb250ZXh0KCkpO1xuICB9XG5cbiAgZXZhbChzb3VyY2U6IHN0cmluZywgc3RvcmU6IFN0b3JlKSB7XG4gICAgcmV0dXJuIHZtLnJ1bkluQ29udGV4dChzb3VyY2UsIHN0b3JlLmdldEJhY2tpbmdPYmplY3QoKSk7XG4gIH1cbn1cbiJdfQ==\n\n/***/ },\n/* 5 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.phaseInModulePathRegexp = undefined;\n\n\tvar _tokenReader = __webpack_require__(6);\n\n\tvar _tokenReader2 = _interopRequireDefault(_tokenReader);\n\n\tvar _scope = __webpack_require__(38);\n\n\tvar _env = __webpack_require__(40);\n\n\tvar _env2 = _interopRequireDefault(_env);\n\n\tvar _immutable = __webpack_require__(12);\n\n\tvar _compiler = __webpack_require__(61);\n\n\tvar _compiler2 = _interopRequireDefault(_compiler);\n\n\tvar _syntax = __webpack_require__(58);\n\n\tvar _bindingMap = __webpack_require__(60);\n\n\tvar _bindingMap2 = _interopRequireDefault(_bindingMap);\n\n\tvar _sweetSpec = __webpack_require__(43);\n\n\tvar _sweetSpec2 = _interopRequireDefault(_sweetSpec);\n\n\tvar _sweetModule = __webpack_require__(42);\n\n\tvar _sweetModule2 = _interopRequireDefault(_sweetModule);\n\n\tvar _ramda = __webpack_require__(20);\n\n\tvar _ = _interopRequireWildcard(_ramda);\n\n\tvar _scopeReducer = __webpack_require__(64);\n\n\tvar _scopeReducer2 = _interopRequireDefault(_scopeReducer);\n\n\tvar _macroContext = __webpack_require__(68);\n\n\tvar _babelCore = __webpack_require__(3);\n\n\tvar _store = __webpack_require__(73);\n\n\tvar _store2 = _interopRequireDefault(_store);\n\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tconst phaseInModulePathRegexp = exports.phaseInModulePathRegexp = /(.*):(\\d+)\\s*$/;\n\n\tclass SweetLoader {\n\n\t  constructor(baseDir, options = {}) {\n\t    this.sourceCache = new Map();\n\t    this.compiledCache = new Map();\n\t    this.baseDir = baseDir;\n\t    this.logging = options.logging || false;\n\n\t    let bindings = new _bindingMap2.default();\n\t    let templateMap = new Map();\n\t    let tempIdent = 0;\n\t    this.context = {\n\t      phase: 0,\n\t      bindings,\n\t      templateMap,\n\t      getTemplateIdentifier: () => ++tempIdent,\n\t      loader: this,\n\t      transform: c => {\n\t        if (options.noBabel) {\n\t          return {\n\t            code: c\n\t          };\n\t        }\n\t        return (0, _babelCore.transform)(c, {\n\t          babelrc: true\n\t        });\n\t      }\n\t    };\n\t  }\n\n\t  normalize(name, refererName, refererAddress) {\n\t    // takes `..path/to/source.js:<phase>`\n\t    // gives `/abs/path/to/source.js:<phase>`\n\t    // missing phases are turned into 0\n\t    if (!phaseInModulePathRegexp.test(name)) {\n\t      return `${ name }:0`;\n\t    }\n\t    return name;\n\t  }\n\n\t  locate({ name, metadata }) {\n\t    // takes `/abs/path/to/source.js:<phase>`\n\t    // gives { path: '/abs/path/to/source.js', phase: <phase> }\n\t    let match = name.match(phaseInModulePathRegexp);\n\t    if (match && match.length >= 3) {\n\t      return {\n\t        path: match[1],\n\t        phase: parseInt(match[2], 10)\n\t      };\n\t    }\n\t    throw new Error(`Module ${ name } is missing phase information`);\n\t  }\n\n\t  fetch({\n\t    name,\n\t    address,\n\t    metadata\n\t  }) {\n\t    throw new Error('No default fetch defined');\n\t  }\n\n\t  translate({\n\t    name,\n\t    address,\n\t    source,\n\t    metadata\n\t  }) {\n\t    let src = this.compiledCache.get(address.path);\n\t    if (src != null) {\n\t      return src;\n\t    }\n\t    let compiledModule = this.compileSource(source, metadata);\n\t    this.compiledCache.set(address.path, compiledModule);\n\t    return compiledModule;\n\t  }\n\n\t  instantiate({\n\t    name,\n\t    address,\n\t    source,\n\t    metadata\n\t  }) {\n\t    throw new Error('Not implemented yet');\n\t  }\n\n\t  eval(source) {\n\t    return (0, eval)(source);\n\t  }\n\n\t  load(entryPath) {\n\t    let metadata = {};\n\t    let name = this.normalize(entryPath);\n\t    let address = this.locate({ name, metadata });\n\t    let source = this.fetch({ name, address, metadata });\n\t    source = this.translate({ name, address, source, metadata });\n\t    return this.instantiate({ name, address, source, metadata });\n\t  }\n\n\t  // skip instantiate\n\t  compile(entryPath, refererName, enforceLangPragma = true) {\n\t    let metadata = {\n\t      enforceLangPragma,\n\t      entryPath\n\t    };\n\t    let name = this.normalize(entryPath, refererName);\n\t    let address = this.locate({ name, metadata });\n\t    let source = this.fetch({ name, address, metadata });\n\t    return this.translate({ name, address, source, metadata });\n\t  }\n\n\t  get(entryPath, entryPhase) {\n\t    return this.compile(`${ entryPath }:${ entryPhase }`);\n\t  }\n\n\t  read(source) {\n\t    return (0, _macroContext.wrapInTerms)((0, _tokenReader2.default)(source));\n\t  }\n\n\t  freshStore() {\n\t    return new _store2.default({});\n\t  }\n\n\t  compileSource(source, metadata) {\n\t    let directive = getLangDirective(source);\n\t    if (directive == null && metadata.enforceLangPragma) {\n\t      if (this.logging) console.log(`skipping module ${ metadata.entryPath }`);\n\t      return new _sweetModule2.default(_immutable.List.of());\n\t    }\n\t    let stxl = this.read(source);\n\t    let outScope = (0, _scope.freshScope)('outsideEdge');\n\t    let inScope = (0, _scope.freshScope)('insideEdge0');\n\t    // the compiler starts at phase 0, with an empty environment and store\n\t    let compiler = new _compiler2.default(0, new _env2.default(), this.freshStore(), _.merge(this.context, {\n\t      currentScope: [outScope, inScope]\n\t    }));\n\t    return new _sweetModule2.default(compiler.compile(stxl.map(s => s.reduce(new _scopeReducer2.default([{ scope: outScope, phase: _syntax.ALL_PHASES, flip: false }, { scope: inScope, phase: 0, flip: false }], this.context.bindings)))));\n\t  }\n\t}\n\n\texports.default = SweetLoader;\n\tconst langDirectiveRegexp = /\\s*('lang .*')/;\n\tfunction getLangDirective(source) {\n\t  let match = source.match(langDirectiveRegexp);\n\t  if (match) {\n\t    return match[1];\n\t  }\n\t  return null;\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zd2VldC1sb2FkZXIuanMiXSwibmFtZXMiOlsiXyIsInBoYXNlSW5Nb2R1bGVQYXRoUmVnZXhwIiwiU3dlZXRMb2FkZXIiLCJjb25zdHJ1Y3RvciIsImJhc2VEaXIiLCJvcHRpb25zIiwic291cmNlQ2FjaGUiLCJNYXAiLCJjb21waWxlZENhY2hlIiwibG9nZ2luZyIsImJpbmRpbmdzIiwidGVtcGxhdGVNYXAiLCJ0ZW1wSWRlbnQiLCJjb250ZXh0IiwicGhhc2UiLCJnZXRUZW1wbGF0ZUlkZW50aWZpZXIiLCJsb2FkZXIiLCJ0cmFuc2Zvcm0iLCJjIiwibm9CYWJlbCIsImNvZGUiLCJiYWJlbHJjIiwibm9ybWFsaXplIiwibmFtZSIsInJlZmVyZXJOYW1lIiwicmVmZXJlckFkZHJlc3MiLCJ0ZXN0IiwibG9jYXRlIiwibWV0YWRhdGEiLCJtYXRjaCIsImxlbmd0aCIsInBhdGgiLCJwYXJzZUludCIsIkVycm9yIiwiZmV0Y2giLCJhZGRyZXNzIiwidHJhbnNsYXRlIiwic291cmNlIiwic3JjIiwiZ2V0IiwiY29tcGlsZWRNb2R1bGUiLCJjb21waWxlU291cmNlIiwic2V0IiwiaW5zdGFudGlhdGUiLCJldmFsIiwibG9hZCIsImVudHJ5UGF0aCIsImNvbXBpbGUiLCJlbmZvcmNlTGFuZ1ByYWdtYSIsImVudHJ5UGhhc2UiLCJyZWFkIiwiZnJlc2hTdG9yZSIsImRpcmVjdGl2ZSIsImdldExhbmdEaXJlY3RpdmUiLCJjb25zb2xlIiwibG9nIiwib2YiLCJzdHhsIiwib3V0U2NvcGUiLCJpblNjb3BlIiwiY29tcGlsZXIiLCJtZXJnZSIsImN1cnJlbnRTY29wZSIsIm1hcCIsInMiLCJyZWR1Y2UiLCJzY29wZSIsImZsaXAiLCJsYW5nRGlyZWN0aXZlUmVnZXhwIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7Ozs7QUFDQTs7QUFDQTs7OztBQUNBOztBQUNBOzs7O0FBQ0E7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7O0lBQVlBLEM7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UUFBUVEsT0FBT1IsS0FBUCxDQUFhdUMsbUJBQWIsQ0FBWjtBQUNBLE1BQUl2QyxLQUFKLEVBQVc7QUFDVCxXQUFPQSxNQUFNLENBQU4sQ0FBUDtBQUNEO0FBQ0QsU0FBTyxJQUFQO0FBQ0QiLCJmaWxlIjoic3dlZXQtbG9hZGVyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbmltcG9ydCByZWFkIGZyb20gJy4vcmVhZGVyL3Rva2VuLXJlYWRlcic7XG5pbXBvcnQgeyBmcmVzaFNjb3BlIH0gZnJvbSAnLi9zY29wZSc7XG5pbXBvcnQgRW52IGZyb20gJy4vZW52JztcbmltcG9ydCB7IExpc3QgfSBmcm9tICdpbW11dGFibGUnO1xuaW1wb3J0IENvbXBpbGVyIGZyb20gJy4vY29tcGlsZXInO1xuaW1wb3J0IHsgQUxMX1BIQVNFUyB9IGZyb20gJy4vc3ludGF4JztcbmltcG9ydCBCaW5kaW5nTWFwIGZyb20gJy4vYmluZGluZy1tYXAuanMnO1xuaW1wb3J0IFRlcm0gZnJvbSAnc3dlZXQtc3BlYyc7XG5pbXBvcnQgU3dlZXRNb2R1bGUgZnJvbSAnLi9zd2VldC1tb2R1bGUnO1xuaW1wb3J0ICogYXMgXyBmcm9tICdyYW1kYSc7XG5pbXBvcnQgU2NvcGVSZWR1Y2VyIGZyb20gJy4vc2NvcGUtcmVkdWNlcic7XG5pbXBvcnQgeyB3cmFwSW5UZXJtcyB9IGZyb20gJy4vbWFjcm8tY29udGV4dCc7XG5pbXBvcnQgeyB0cmFuc2Zvcm0gYXMgYmFiZWwgfSBmcm9tICdiYWJlbC1jb3JlJztcbmltcG9ydCBTdG9yZSBmcm9tICcuL3N0b3JlJztcblxuZXhwb3J0IGNvbnN0IHBoYXNlSW5Nb2R1bGVQYXRoUmVnZXhwID0gLyguKik6KFxcZCspXFxzKiQvO1xuXG5leHBvcnQgdHlwZSBDb250ZXh0ID0ge1xuICBiaW5kaW5nczogYW55LFxuICB0ZW1wbGF0ZU1hcDogYW55LFxuICBnZXRUZW1wbGF0ZUlkZW50aWZpZXI6IGFueSxcbiAgbG9hZGVyOiBhbnksXG4gIHRyYW5zZm9ybTogYW55LFxuICBwaGFzZTogbnVtYmVyLFxuICBzdG9yZTogU3RvcmUsXG59O1xuXG5leHBvcnQgdHlwZSBMb2FkZXJPcHRpb25zID0ge1xuICBub0JhYmVsPzogYm9vbGVhbixcbiAgbG9nZ2luZz86IGJvb2xlYW4sXG59O1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTd2VldExvYWRlciB7XG4gIHNvdXJjZUNhY2hlOiBNYXA8c3RyaW5nLCBzdHJpbmc+O1xuICBjb21waWxlZENhY2hlOiBNYXA8c3RyaW5nLCBTd2VldE1vZHVsZT47XG4gIGNvbnRleHQ6IGFueTtcbiAgYmFzZURpcjogc3RyaW5nO1xuICBsb2dnaW5nOiBib29sZWFuO1xuXG4gIGNvbnN0cnVjdG9yKGJhc2VEaXI6IHN0cmluZywgb3B0aW9ucz86IExvYWRlck9wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMuc291cmNlQ2FjaGUgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5jb21waWxlZENhY2hlID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuYmFzZURpciA9IGJhc2VEaXI7XG4gICAgdGhpcy5sb2dnaW5nID0gb3B0aW9ucy5sb2dnaW5nIHx8IGZhbHNlO1xuXG4gICAgbGV0IGJpbmRpbmdzID0gbmV3IEJpbmRpbmdNYXAoKTtcbiAgICBsZXQgdGVtcGxhdGVNYXAgPSBuZXcgTWFwKCk7XG4gICAgbGV0IHRlbXBJZGVudCA9IDA7XG4gICAgdGhpcy5jb250ZXh0ID0ge1xuICAgICAgcGhhc2U6IDAsXG4gICAgICBiaW5kaW5ncyxcbiAgICAgIHRlbXBsYXRlTWFwLFxuICAgICAgZ2V0VGVtcGxhdGVJZGVudGlmaWVyOiAoKSA9PiArK3RlbXBJZGVudCxcbiAgICAgIGxvYWRlcjogdGhpcyxcbiAgICAgIHRyYW5zZm9ybTogYyA9PiB7XG4gICAgICAgIGlmIChvcHRpb25zLm5vQmFiZWwpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29kZTogYyxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiYWJlbChjLCB7XG4gICAgICAgICAgYmFiZWxyYzogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBub3JtYWxpemUobmFtZTogc3RyaW5nLCByZWZlcmVyTmFtZT86IHN0cmluZywgcmVmZXJlckFkZHJlc3M/OiBzdHJpbmcpIHtcbiAgICAvLyB0YWtlcyBgLi5wYXRoL3RvL3NvdXJjZS5qczo8cGhhc2U+YFxuICAgIC8vIGdpdmVzIGAvYWJzL3BhdGgvdG8vc291cmNlLmpzOjxwaGFzZT5gXG4gICAgLy8gbWlzc2luZyBwaGFzZXMgYXJlIHR1cm5lZCBpbnRvIDBcbiAgICBpZiAoIXBoYXNlSW5Nb2R1bGVQYXRoUmVnZXhwLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiBgJHtuYW1lfTowYDtcbiAgICB9XG4gICAgcmV0dXJuIG5hbWU7XG4gIH1cblxuICBsb2NhdGUoeyBuYW1lLCBtZXRhZGF0YSB9OiB7IG5hbWU6IHN0cmluZywgbWV0YWRhdGE6IHt9IH0pIHtcbiAgICAvLyB0YWtlcyBgL2Ficy9wYXRoL3RvL3NvdXJjZS5qczo8cGhhc2U+YFxuICAgIC8vIGdpdmVzIHsgcGF0aDogJy9hYnMvcGF0aC90by9zb3VyY2UuanMnLCBwaGFzZTogPHBoYXNlPiB9XG4gICAgbGV0IG1hdGNoID0gbmFtZS5tYXRjaChwaGFzZUluTW9kdWxlUGF0aFJlZ2V4cCk7XG4gICAgaWYgKG1hdGNoICYmIG1hdGNoLmxlbmd0aCA+PSAzKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwYXRoOiBtYXRjaFsxXSxcbiAgICAgICAgcGhhc2U6IHBhcnNlSW50KG1hdGNoWzJdLCAxMCksXG4gICAgICB9O1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoYE1vZHVsZSAke25hbWV9IGlzIG1pc3NpbmcgcGhhc2UgaW5mb3JtYXRpb25gKTtcbiAgfVxuXG4gIGZldGNoKFxuICAgIHtcbiAgICAgIG5hbWUsXG4gICAgICBhZGRyZXNzLFxuICAgICAgbWV0YWRhdGEsXG4gICAgfTogeyBuYW1lOiBzdHJpbmcsIGFkZHJlc3M6IHsgcGF0aDogc3RyaW5nLCBwaGFzZTogbnVtYmVyIH0sIG1ldGFkYXRhOiB7fSB9LFxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGRlZmF1bHQgZmV0Y2ggZGVmaW5lZCcpO1xuICB9XG5cbiAgdHJhbnNsYXRlKFxuICAgIHtcbiAgICAgIG5hbWUsXG4gICAgICBhZGRyZXNzLFxuICAgICAgc291cmNlLFxuICAgICAgbWV0YWRhdGEsXG4gICAgfToge1xuICAgICAgbmFtZTogc3RyaW5nLFxuICAgICAgYWRkcmVzczogeyBwYXRoOiBzdHJpbmcsIHBoYXNlOiBudW1iZXIgfSxcbiAgICAgIHNvdXJjZTogc3RyaW5nLFxuICAgICAgbWV0YWRhdGE6IHt9LFxuICAgIH0sXG4gICkge1xuICAgIGxldCBzcmMgPSB0aGlzLmNvbXBpbGVkQ2FjaGUuZ2V0KGFkZHJlc3MucGF0aCk7XG4gICAgaWYgKHNyYyAhPSBudWxsKSB7XG4gICAgICByZXR1cm4gc3JjO1xuICAgIH1cbiAgICBsZXQgY29tcGlsZWRNb2R1bGUgPSB0aGlzLmNvbXBpbGVTb3VyY2Uoc291cmNlLCBtZXRhZGF0YSk7XG4gICAgdGhpcy5jb21waWxlZENhY2hlLnNldChhZGRyZXNzLnBhdGgsIGNvbXBpbGVkTW9kdWxlKTtcbiAgICByZXR1cm4gY29tcGlsZWRNb2R1bGU7XG4gIH1cblxuICBpbnN0YW50aWF0ZShcbiAgICB7XG4gICAgICBuYW1lLFxuICAgICAgYWRkcmVzcyxcbiAgICAgIHNvdXJjZSxcbiAgICAgIG1ldGFkYXRhLFxuICAgIH06IHtcbiAgICAgIG5hbWU6IHN0cmluZyxcbiAgICAgIGFkZHJlc3M6IHsgcGF0aDogc3RyaW5nLCBwaGFzZTogbnVtYmVyIH0sXG4gICAgICBzb3VyY2U6IFN3ZWV0TW9kdWxlLFxuICAgICAgbWV0YWRhdGE6IHt9LFxuICAgIH0sXG4gICkge1xuICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkIHlldCcpO1xuICB9XG5cbiAgZXZhbChzb3VyY2U6IHN0cmluZykge1xuICAgIHJldHVybiAoMCwgZXZhbCkoc291cmNlKTtcbiAgfVxuXG4gIGxvYWQoZW50cnlQYXRoOiBzdHJpbmcpIHtcbiAgICBsZXQgbWV0YWRhdGEgPSB7fTtcbiAgICBsZXQgbmFtZSA9IHRoaXMubm9ybWFsaXplKGVudHJ5UGF0aCk7XG4gICAgbGV0IGFkZHJlc3MgPSB0aGlzLmxvY2F0ZSh7IG5hbWUsIG1ldGFkYXRhIH0pO1xuICAgIGxldCBzb3VyY2UgPSB0aGlzLmZldGNoKHsgbmFtZSwgYWRkcmVzcywgbWV0YWRhdGEgfSk7XG4gICAgc291cmNlID0gdGhpcy50cmFuc2xhdGUoeyBuYW1lLCBhZGRyZXNzLCBzb3VyY2UsIG1ldGFkYXRhIH0pO1xuICAgIHJldHVybiB0aGlzLmluc3RhbnRpYXRlKHsgbmFtZSwgYWRkcmVzcywgc291cmNlLCBtZXRhZGF0YSB9KTtcbiAgfVxuXG4gIC8vIHNraXAgaW5zdGFudGlhdGVcbiAgY29tcGlsZShcbiAgICBlbnRyeVBhdGg6IHN0cmluZyxcbiAgICByZWZlcmVyTmFtZT86IHN0cmluZyxcbiAgICBlbmZvcmNlTGFuZ1ByYWdtYT86IGJvb2xlYW4gPSB0cnVlLFxuICApIHtcbiAgICBsZXQgbWV0YWRhdGEgPSB7XG4gICAgICBlbmZvcmNlTGFuZ1ByYWdtYSxcbiAgICAgIGVudHJ5UGF0aCxcbiAgICB9O1xuICAgIGxldCBuYW1lID0gdGhpcy5ub3JtYWxpemUoZW50cnlQYXRoLCByZWZlcmVyTmFtZSk7XG4gICAgbGV0IGFkZHJlc3MgPSB0aGlzLmxvY2F0ZSh7IG5hbWUsIG1ldGFkYXRhIH0pO1xuICAgIGxldCBzb3VyY2UgPSB0aGlzLmZldGNoKHsgbmFtZSwgYWRkcmVzcywgbWV0YWRhdGEgfSk7XG4gICAgcmV0dXJuIHRoaXMudHJhbnNsYXRlKHsgbmFtZSwgYWRkcmVzcywgc291cmNlLCBtZXRhZGF0YSB9KTtcbiAgfVxuXG4gIGdldChlbnRyeVBhdGg6IHN0cmluZywgZW50cnlQaGFzZTogbnVtYmVyKSB7XG4gICAgcmV0dXJuIHRoaXMuY29tcGlsZShgJHtlbnRyeVBhdGh9OiR7ZW50cnlQaGFzZX1gKTtcbiAgfVxuXG4gIHJlYWQoc291cmNlOiBzdHJpbmcpOiBMaXN0PFRlcm0+IHtcbiAgICByZXR1cm4gd3JhcEluVGVybXMocmVhZChzb3VyY2UpKTtcbiAgfVxuXG4gIGZyZXNoU3RvcmUoKSB7XG4gICAgcmV0dXJuIG5ldyBTdG9yZSh7fSk7XG4gIH1cblxuICBjb21waWxlU291cmNlKHNvdXJjZTogc3RyaW5nLCBtZXRhZGF0YTogYW55KSB7XG4gICAgbGV0IGRpcmVjdGl2ZSA9IGdldExhbmdEaXJlY3RpdmUoc291cmNlKTtcbiAgICBpZiAoZGlyZWN0aXZlID09IG51bGwgJiYgbWV0YWRhdGEuZW5mb3JjZUxhbmdQcmFnbWEpIHtcbiAgICAgIGlmICh0aGlzLmxvZ2dpbmcpIGNvbnNvbGUubG9nKGBza2lwcGluZyBtb2R1bGUgJHttZXRhZGF0YS5lbnRyeVBhdGh9YCk7XG4gICAgICByZXR1cm4gbmV3IFN3ZWV0TW9kdWxlKExpc3Qub2YoKSk7XG4gICAgfVxuICAgIGxldCBzdHhsID0gdGhpcy5yZWFkKHNvdXJjZSk7XG4gICAgbGV0IG91dFNjb3BlID0gZnJlc2hTY29wZSgnb3V0c2lkZUVkZ2UnKTtcbiAgICBsZXQgaW5TY29wZSA9IGZyZXNoU2NvcGUoJ2luc2lkZUVkZ2UwJyk7XG4gICAgLy8gdGhlIGNvbXBpbGVyIHN0YXJ0cyBhdCBwaGFzZSAwLCB3aXRoIGFuIGVtcHR5IGVudmlyb25tZW50IGFuZCBzdG9yZVxuICAgIGxldCBjb21waWxlciA9IG5ldyBDb21waWxlcihcbiAgICAgIDAsXG4gICAgICBuZXcgRW52KCksXG4gICAgICB0aGlzLmZyZXNoU3RvcmUoKSxcbiAgICAgIF8ubWVyZ2UodGhpcy5jb250ZXh0LCB7XG4gICAgICAgIGN1cnJlbnRTY29wZTogW291dFNjb3BlLCBpblNjb3BlXSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgcmV0dXJuIG5ldyBTd2VldE1vZHVsZShcbiAgICAgIGNvbXBpbGVyLmNvbXBpbGUoXG4gICAgICAgIHN0eGwubWFwKHMgPT5cbiAgICAgICAgICBzLnJlZHVjZShcbiAgICAgICAgICAgIG5ldyBTY29wZVJlZHVjZXIoXG4gICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICB7IHNjb3BlOiBvdXRTY29wZSwgcGhhc2U6IEFMTF9QSEFTRVMsIGZsaXA6IGZhbHNlIH0sXG4gICAgICAgICAgICAgICAgeyBzY29wZTogaW5TY29wZSwgcGhhc2U6IDAsIGZsaXA6IGZhbHNlIH0sXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIHRoaXMuY29udGV4dC5iaW5kaW5ncyxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKSksXG4gICAgICApLFxuICAgICk7XG4gIH1cbn1cblxuY29uc3QgbGFuZ0RpcmVjdGl2ZVJlZ2V4cCA9IC9cXHMqKCdsYW5nIC4qJykvO1xuZnVuY3Rpb24gZ2V0TGFuZ0RpcmVjdGl2ZShzb3VyY2U6IHN0cmluZykge1xuICBsZXQgbWF0Y2ggPSBzb3VyY2UubWF0Y2gobGFuZ0RpcmVjdGl2ZVJlZ2V4cCk7XG4gIGlmIChtYXRjaCkge1xuICAgIHJldHVybiBtYXRjaFsxXTtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cbiJdfQ==\n\n/***/ },\n/* 6 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.getSlice = getSlice;\n\texports.default = read;\n\n\tvar _readtable = __webpack_require__(7);\n\n\tvar _defaultReadtable = __webpack_require__(11);\n\n\tvar _defaultReadtable2 = _interopRequireDefault(_defaultReadtable);\n\n\tvar _immutable = __webpack_require__(12);\n\n\tvar _tokens = __webpack_require__(19);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\t(0, _readtable.setCurrentReadtable)(_defaultReadtable2.default);\n\n\tfunction getSlice(stream, startLocation) {\n\t  return {\n\t    text: stream.getSlice(startLocation.position),\n\t    start: startLocation.position,\n\t    startLocation,\n\t    end: stream.sourceInfo.position\n\t  };\n\t}\n\n\tconst streams = new WeakMap();\n\n\tclass ReadError extends Error {\n\t  constructor({\n\t    index,\n\t    line,\n\t    column,\n\t    message\n\t  }) {\n\t    super(message);\n\t    this.index = index;\n\t    this.line = line;\n\t    this.column = column;\n\t    this.message = `[${ line }:${ column }] ${ message }`;\n\t  }\n\t}\n\n\tclass TokenReader extends _readtable.Reader {\n\t  constructor(stream, context) {\n\t    super();\n\t    this.context = context;\n\t    streams.set(this, stream);\n\t    this.locationInfo = {\n\t      line: 1,\n\t      column: 1\n\t    };\n\t  }\n\n\t  createError(msg) {\n\t    let message = msg.replace(/\\{(\\d+)\\}/g, (_, n) => JSON.stringify(arguments[+n + 1]));\n\t    return new ReadError({\n\t      message,\n\t      // $FlowFixMe: decide on how to handle possible nullability\n\t      index: streams.get(this).sourceInfo.position,\n\t      line: this.locationInfo.line,\n\t      column: this.locationInfo.column\n\t    });\n\t  }\n\n\t  createILLEGAL(char) {\n\t    return !(0, _readtable.isEOS)(char) ? this.createError('Unexpected {0}', char) : this.createError('Unexpected end of input');\n\t  }\n\n\t  readToken(stream, ...rest) {\n\t    const startLocation = Object.assign({}, this.locationInfo, stream.sourceInfo);\n\t    const result = super.read(stream, ...rest);\n\n\t    if (startLocation.column === this.locationInfo.column && startLocation.line === this.locationInfo.line) {\n\t      this.locationInfo.column += stream.sourceInfo.position - startLocation.position;\n\t    }\n\n\t    if (result === _tokens.EmptyToken) return result;\n\n\t    if (!_immutable.List.isList(result)) result.slice = getSlice(stream, startLocation);\n\n\t    return result;\n\t  }\n\n\t  readUntil(close, stream, prefix, exprAllowed) {\n\t    let result,\n\t        results = prefix,\n\t        done = false;\n\t    do {\n\t      if ((0, _readtable.isEOS)(stream.peek())) break;\n\t      done = typeof close === 'function' ? close() : stream.peek() === close;\n\t      result = this.readToken(stream, results, exprAllowed);\n\n\t      if (result !== _tokens.EmptyToken) {\n\t        results = results.push(result);\n\t      }\n\t    } while (!done);\n\t    return results;\n\t  }\n\n\t  incrementLine() {\n\t    this.locationInfo.line += 1;\n\t    this.locationInfo.column = 1;\n\t  }\n\t}\n\n\tfunction read(source, context) {\n\t  const stream = typeof source === 'string' ? new _readtable.CharStream(source) : source;\n\t  if ((0, _readtable.isEOS)(stream.peek())) return (0, _immutable.List)();\n\t  return new TokenReader(stream, context).readUntil(null, stream, (0, _immutable.List)(), false);\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9yZWFkZXIvdG9rZW4tcmVhZGVyLmpzIl0sIm5hbWVzIjpbImdldFNsaWNlIiwicmVhZCIsInN0cmVhbSIsInN0YXJ0TG9jYXRpb24iLCJ0ZXh0IiwicG9zaXRpb24iLCJzdGFydCIsImVuZCIsInNvdXJjZUluZm8iLCJzdHJlYW1zIiwiV2Vha01hcCIsIlJlYWRFcnJvciIsIkVycm9yIiwiY29uc3RydWN0b3IiLCJpbmRleCIsImxpbmUiLCJjb2x1bW4iLCJtZXNzYWdlIiwiVG9rZW5SZWFkZXIiLCJjb250ZXh0Iiwic2V0IiwibG9jYXRpb25JbmZvIiwiY3JlYXRlRXJyb3IiLCJtc2ciLCJyZXBsYWNlIiwiXyIsIm4iLCJKU09OIiwic3RyaW5naWZ5IiwiYXJndW1lbnRzIiwiZ2V0IiwiY3JlYXRlSUxMRUdBTCIsImNoYXIiLCJyZWFkVG9rZW4iLCJyZXN0IiwiT2JqZWN0IiwiYXNzaWduIiwicmVzdWx0IiwiaXNMaXN0Iiwic2xpY2UiLCJyZWFkVW50aWwiLCJjbG9zZSIsInByZWZpeCIsImV4cHJBbGxvd2VkIiwicmVzdWx0cyIsImRvbmUiLCJwZWVrIiwicHVzaCIsImluY3JlbWVudExpbmUiLCJzb3VyY2UiXSwibWFwcGluZ3MiOiI7Ozs7O1FBcUJnQkEsUSxHQUFBQSxRO2tCQWtIUUMsSTs7QUFySXhCOztBQUNBOzs7O0FBQ0E7O0FBQ0E7Ozs7QUFJQTs7QUFZTyxTQUFTRCxRQUFULENBQ0xFLE1BREssRUFFTEMsYUFGSyxFQUdFO0FBQ1AsU0FBTztBQUNMQyxVQUFNRixPQUFPRixRQUFQLENBQWdCRyxjQUFjRSxRQUE5QixDQUREO0FBRUxDLFdBQU9ILGNBQWNFLFFBRmhCO0FBR0xGLGlCQUhLO0FBSUxJLFNBQUtMLE9BQU9NLFVBQVAsQ0FBa0JIO0FBSmxCLEdBQVA7QUFNRDs7QUFFRCxNQUFNSSxVQUFVLElBQUlDLE9BQUosRUFBaEI7O0FBRUEsTUFBTUMsU0FBTixTQUF3QkMsS0FBeEIsQ0FBOEI7QUFLNUJDLGNBQ0U7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NkJBQUosRUFBMkI7QUFDekJPLGtCQUFVQSxRQUFRRyxJQUFSLENBQWFWLE1BQWIsQ0FBVjtBQUNEO0FBQ0YsS0FSRCxRQVFTLENBQUNRLElBUlY7QUFTQSxXQUFPRCxPQUFQO0FBQ0Q7O0FBRURJLGtCQUFzQjtBQUNwQixTQUFLM0IsWUFBTCxDQUFrQk4sSUFBbEIsSUFBMEIsQ0FBMUI7QUFDQSxTQUFLTSxZQUFMLENBQWtCTCxNQUFsQixHQUEyQixDQUEzQjtBQUNEO0FBNUU4Qjs7QUErRWxCLFNBQVNmLElBQVQsQ0FDYmdELE1BRGEsRUFFYjlCLE9BRmEsRUFHRjtBQUNYLFFBQU1qQixTQUFTLE9BQU8rQyxNQUFQLEtBQWtCLFFBQWxCLEdBQTZCLDBCQUFlQSxNQUFmLENBQTdCLEdBQXNEQSxNQUFyRTtBQUNBLE1BQUksc0JBQU0vQyxPQUFPNEMsSUFBUCxFQUFOLENBQUosRUFBMEIsT0FBTyxzQkFBUDtBQUMxQixTQUFPLElBQUk1QixXQUFKLENBQWdCaEIsTUFBaEIsRUFBd0JpQixPQUF4QixFQUFpQ3FCLFNBQWpDLENBQ0wsSUFESyxFQUVMdEMsTUFGSyxFQUdMLHNCQUhLLEVBSUwsS0FKSyxDQUFQO0FBTUQiLCJmaWxlIjoidG9rZW4tcmVhZGVyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcblxuaW1wb3J0IHsgQ2hhclN0cmVhbSwgaXNFT1MsIFJlYWRlciwgc2V0Q3VycmVudFJlYWR0YWJsZSB9IGZyb20gJ3JlYWR0YWJsZSc7XG5pbXBvcnQgZGVmYXVsdFJlYWR0YWJsZSBmcm9tICcuL2RlZmF1bHQtcmVhZHRhYmxlJztcbmltcG9ydCB7IExpc3QgfSBmcm9tICdpbW11dGFibGUnO1xuaW1wb3J0IHsgRW1wdHlUb2tlbiB9IGZyb20gJy4uL3Rva2Vucyc7XG5cbmltcG9ydCB0eXBlIHsgU3RhcnRMb2NhdGlvbiwgU2xpY2UgfSBmcm9tICcuLi90b2tlbnMnO1xuXG5zZXRDdXJyZW50UmVhZHRhYmxlKGRlZmF1bHRSZWFkdGFibGUpO1xuXG5leHBvcnQgdHlwZSBMb2NhdGlvbkluZm8gPSB7XG4gIGxpbmU6IG51bWJlcixcbiAgY29sdW1uOiBudW1iZXIsXG59O1xuXG50eXBlIENvbnRleHQgPSB7XG4gIGJpbmRpbmdzOiBhbnksXG4gIHNjb3Blc2V0czogYW55LFxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNsaWNlKFxuICBzdHJlYW06IENoYXJTdHJlYW0sXG4gIHN0YXJ0TG9jYXRpb246IFN0YXJ0TG9jYXRpb24sXG4pOiBTbGljZSB7XG4gIHJldHVybiB7XG4gICAgdGV4dDogc3RyZWFtLmdldFNsaWNlKHN0YXJ0TG9jYXRpb24ucG9zaXRpb24pLFxuICAgIHN0YXJ0OiBzdGFydExvY2F0aW9uLnBvc2l0aW9uLFxuICAgIHN0YXJ0TG9jYXRpb24sXG4gICAgZW5kOiBzdHJlYW0uc291cmNlSW5mby5wb3NpdGlvbixcbiAgfTtcbn1cblxuY29uc3Qgc3RyZWFtcyA9IG5ldyBXZWFrTWFwKCk7XG5cbmNsYXNzIFJlYWRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgaW5kZXg6IG51bWJlcjtcbiAgbGluZTogbnVtYmVyO1xuICBjb2x1bW46IG51bWJlcjtcbiAgbWVzc2FnZTogc3RyaW5nO1xuICBjb25zdHJ1Y3RvcihcbiAgICB7XG4gICAgICBpbmRleCxcbiAgICAgIGxpbmUsXG4gICAgICBjb2x1bW4sXG4gICAgICBtZXNzYWdlLFxuICAgIH06IHsgaW5kZXg6IG51bWJlciwgbGluZTogbnVtYmVyLCBjb2x1bW46IG51bWJlciwgbWVzc2FnZTogc3RyaW5nIH0sXG4gICkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMuaW5kZXggPSBpbmRleDtcbiAgICB0aGlzLmxpbmUgPSBsaW5lO1xuICAgIHRoaXMuY29sdW1uID0gY29sdW1uO1xuICAgIHRoaXMubWVzc2FnZSA9IGBbJHtsaW5lfToke2NvbHVtbn1dICR7bWVzc2FnZX1gO1xuICB9XG59XG5cbmNsYXNzIFRva2VuUmVhZGVyIGV4dGVuZHMgUmVhZGVyIHtcbiAgbG9jYXRpb25JbmZvOiBMb2NhdGlvbkluZm87XG4gIGNvbnRleHQ6ID9Db250ZXh0O1xuICBjb25zdHJ1Y3RvcihzdHJlYW06IENoYXJTdHJlYW0sIGNvbnRleHQ/OiBDb250ZXh0KSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgIHN0cmVhbXMuc2V0KHRoaXMsIHN0cmVhbSk7XG4gICAgdGhpcy5sb2NhdGlvbkluZm8gPSB7XG4gICAgICBsaW5lOiAxLFxuICAgICAgY29sdW1uOiAxLFxuICAgIH07XG4gIH1cblxuICBjcmVhdGVFcnJvcihtc2c6IHN0cmluZyk6IFJlYWRFcnJvciB7XG4gICAgbGV0IG1lc3NhZ2UgPSBtc2cucmVwbGFjZSgvXFx7KFxcZCspXFx9L2csIChfLCBuKSA9PlxuICAgICAgSlNPTi5zdHJpbmdpZnkoYXJndW1lbnRzWytuICsgMV0pKTtcbiAgICByZXR1cm4gbmV3IFJlYWRFcnJvcih7XG4gICAgICBtZXNzYWdlLFxuICAgICAgLy8gJEZsb3dGaXhNZTogZGVjaWRlIG9uIGhvdyB0byBoYW5kbGUgcG9zc2libGUgbnVsbGFiaWxpdHlcbiAgICAgIGluZGV4OiBzdHJlYW1zLmdldCh0aGlzKS5zb3VyY2VJbmZvLnBvc2l0aW9uLFxuICAgICAgbGluZTogdGhpcy5sb2NhdGlvbkluZm8ubGluZSxcbiAgICAgIGNvbHVtbjogdGhpcy5sb2NhdGlvbkluZm8uY29sdW1uLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlSUxMRUdBTChjaGFyKSB7XG4gICAgcmV0dXJuICFpc0VPUyhjaGFyKVxuICAgICAgPyB0aGlzLmNyZWF0ZUVycm9yKCdVbmV4cGVjdGVkIHswfScsIGNoYXIpXG4gICAgICA6IHRoaXMuY3JlYXRlRXJyb3IoJ1VuZXhwZWN0ZWQgZW5kIG9mIGlucHV0Jyk7XG4gIH1cblxuICByZWFkVG9rZW4oc3RyZWFtOiBDaGFyU3RyZWFtLCAuLi5yZXN0OiBBcnJheTxhbnk+KSB7XG4gICAgY29uc3Qgc3RhcnRMb2NhdGlvbiA9IE9iamVjdC5hc3NpZ24oXG4gICAgICB7fSxcbiAgICAgIHRoaXMubG9jYXRpb25JbmZvLFxuICAgICAgc3RyZWFtLnNvdXJjZUluZm8sXG4gICAgKTtcbiAgICBjb25zdCByZXN1bHQgPSBzdXBlci5yZWFkKHN0cmVhbSwgLi4ucmVzdCk7XG5cbiAgICBpZiAoXG4gICAgICBzdGFydExvY2F0aW9uLmNvbHVtbiA9PT0gdGhpcy5sb2NhdGlvbkluZm8uY29sdW1uICYmXG4gICAgICBzdGFydExvY2F0aW9uLmxpbmUgPT09IHRoaXMubG9jYXRpb25JbmZvLmxpbmVcbiAgICApIHtcbiAgICAgIHRoaXMubG9jYXRpb25JbmZvLmNvbHVtbiArPSBzdHJlYW0uc291cmNlSW5mby5wb3NpdGlvbiAtXG4gICAgICAgIHN0YXJ0TG9jYXRpb24ucG9zaXRpb247XG4gICAgfVxuXG4gICAgaWYgKHJlc3VsdCA9PT0gRW1wdHlUb2tlbikgcmV0dXJuIHJlc3VsdDtcblxuICAgIGlmICghTGlzdC5pc0xpc3QocmVzdWx0KSkgcmVzdWx0LnNsaWNlID0gZ2V0U2xpY2Uoc3RyZWFtLCBzdGFydExvY2F0aW9uKTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICByZWFkVW50aWwoXG4gICAgY2xvc2U6ID9GdW5jdGlvbiB8ID9zdHJpbmcsXG4gICAgc3RyZWFtOiBDaGFyU3RyZWFtLFxuICAgIHByZWZpeDogTGlzdDxhbnk+LFxuICAgIGV4cHJBbGxvd2VkOiBib29sZWFuLFxuICApOiBMaXN0PGFueT4ge1xuICAgIGxldCByZXN1bHQsIHJlc3VsdHMgPSBwcmVmaXgsIGRvbmUgPSBmYWxzZTtcbiAgICBkbyB7XG4gICAgICBpZiAoaXNFT1Moc3RyZWFtLnBlZWsoKSkpIGJyZWFrO1xuICAgICAgZG9uZSA9IHR5cGVvZiBjbG9zZSA9PT0gJ2Z1bmN0aW9uJyA/IGNsb3NlKCkgOiBzdHJlYW0ucGVlaygpID09PSBjbG9zZTtcbiAgICAgIHJlc3VsdCA9IHRoaXMucmVhZFRva2VuKHN0cmVhbSwgcmVzdWx0cywgZXhwckFsbG93ZWQpO1xuXG4gICAgICBpZiAocmVzdWx0ICE9PSBFbXB0eVRva2VuKSB7XG4gICAgICAgIHJlc3VsdHMgPSByZXN1bHRzLnB1c2gocmVzdWx0KTtcbiAgICAgIH1cbiAgICB9IHdoaWxlICghZG9uZSk7XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICBpbmNyZW1lbnRMaW5lKCk6IHZvaWQge1xuICAgIHRoaXMubG9jYXRpb25JbmZvLmxpbmUgKz0gMTtcbiAgICB0aGlzLmxvY2F0aW9uSW5mby5jb2x1bW4gPSAxO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHJlYWQoXG4gIHNvdXJjZTogc3RyaW5nIHwgQ2hhclN0cmVhbSxcbiAgY29udGV4dD86IENvbnRleHQsXG4pOiBMaXN0PGFueT4ge1xuICBjb25zdCBzdHJlYW0gPSB0eXBlb2Ygc291cmNlID09PSAnc3RyaW5nJyA/IG5ldyBDaGFyU3RyZWFtKHNvdXJjZSkgOiBzb3VyY2U7XG4gIGlmIChpc0VPUyhzdHJlYW0ucGVlaygpKSkgcmV0dXJuIExpc3QoKTtcbiAgcmV0dXJuIG5ldyBUb2tlblJlYWRlcihzdHJlYW0sIGNvbnRleHQpLnJlYWRVbnRpbChcbiAgICBudWxsLFxuICAgIHN0cmVhbSxcbiAgICBMaXN0KCksXG4gICAgZmFsc2UsXG4gICk7XG59XG4iXX0=\n\n/***/ },\n/* 7 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.setCurrentReadtable = exports.getCurrentReadtable = exports.isEOS = exports.EmptyReadtable = exports.Readtable = exports.Reader = exports.CharStream = undefined;\n\n\tvar _charStream = __webpack_require__(8);\n\n\tvar _charStream2 = _interopRequireDefault(_charStream);\n\n\tvar _reader = __webpack_require__(9);\n\n\tvar _reader2 = _interopRequireDefault(_reader);\n\n\tvar _readtable = __webpack_require__(10);\n\n\tvar _readtable2 = _interopRequireDefault(_readtable);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\texports.CharStream = _charStream2.default;\n\texports.Reader = _reader2.default;\n\texports.Readtable = _readtable2.default;\n\texports.EmptyReadtable = _readtable.EmptyReadtable;\n\texports.isEOS = _charStream.isEOS;\n\texports.getCurrentReadtable = _reader.getCurrentReadtable;\n\texports.setCurrentReadtable = _reader.setCurrentReadtable;\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC5qcyJdLCJuYW1lcyI6WyJDaGFyU3RyZWFtIiwiUmVhZGVyIiwiUmVhZHRhYmxlIiwiRW1wdHlSZWFkdGFibGUiLCJpc0VPUyIsImdldEN1cnJlbnRSZWFkdGFibGUiLCJzZXRDdXJyZW50UmVhZHRhYmxlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7Ozs7QUFDQTs7OztBQUNBOzs7Ozs7UUFFU0EsVTtRQUFZQyxNO1FBQVFDLFM7UUFBV0MsYztRQUFnQkMsSztRQUFPQyxtQjtRQUFxQkMsbUIiLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQ2hhclN0cmVhbSwgeyBpc0VPUyB9IGZyb20gJy4vY2hhci1zdHJlYW0nO1xuaW1wb3J0IFJlYWRlciwgeyBnZXRDdXJyZW50UmVhZHRhYmxlLCBzZXRDdXJyZW50UmVhZHRhYmxlIH0gZnJvbSAnLi9yZWFkZXInO1xuaW1wb3J0IFJlYWR0YWJsZSwgeyBFbXB0eVJlYWR0YWJsZSB9IGZyb20gJy4vcmVhZHRhYmxlJztcblxuZXhwb3J0IHsgQ2hhclN0cmVhbSwgUmVhZGVyLCBSZWFkdGFibGUsIEVtcHR5UmVhZHRhYmxlLCBpc0VPUywgZ2V0Q3VycmVudFJlYWR0YWJsZSwgc2V0Q3VycmVudFJlYWR0YWJsZSB9O1xuIl19\n\n/***/ },\n/* 8 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.isEOS = isEOS;\n\n\n\tconst sourceInfo = new WeakMap();\n\tclass CharStream {\n\t  constructor(source, filename = '') {\n\t    sourceInfo.set(this, {\n\t      source,\n\t      filename,\n\t      position: 0\n\t    });\n\t  }\n\n\t  get sourceInfo() {\n\t    // $FlowFixMe: decide on how to handle possible nullability\n\t    const { filename, position } = sourceInfo.get(this);\n\t    return { filename, position };\n\t  }\n\n\t  // returns the Unicode character charsToSkip ahead.\n\t  peek(charsToSkip = 0) {\n\t    // $FlowFixMe: decide on how to handle possible nullability\n\t    const { source, position } = sourceInfo.get(this);\n\t    if (position + charsToSkip >= source.length) return '';\n\t    return source[position + charsToSkip];\n\t  }\n\n\t  // returns a string containing the next numChars characters.\n\t  readString(numChars = 1) {\n\t    const info = sourceInfo.get(this);\n\t    // $FlowFixMe: decide on how to handle possible nullability\n\t    const { source, position } = info;\n\t    const str = source.slice(position, position + numChars);\n\t    // $FlowFixMe: decide on how to handle possible nullability\n\t    info.position += str.length;\n\t    return str;\n\t  }\n\n\t  getSlice(start) {\n\t    // $FlowFixMe: decide on how to handle possible nullability\n\t    const { source, position } = sourceInfo.get(this);\n\t    return source.slice(start, position);\n\t  }\n\t}\n\n\texports.default = CharStream;\n\tfunction isEOS(char) {\n\t  return char === '';\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jaGFyLXN0cmVhbS5qcyJdLCJuYW1lcyI6WyJpc0VPUyIsInNvdXJjZUluZm8iLCJXZWFrTWFwIiwiQ2hhclN0cmVhbSIsImNvbnN0cnVjdG9yIiwic291cmNlIiwiZmlsZW5hbWUiLCJzZXQiLCJwb3NpdGlvbiIsImdldCIsInBlZWsiLCJjaGFyc1RvU2tpcCIsImxlbmd0aCIsInJlYWRTdHJpbmciLCJudW1DaGFycyIsImluZm8iLCJzdHIiLCJzbGljZSIsImdldFNsaWNlIiwic3RhcnQiLCJjaGFyIl0sIm1hcHBpbmdzIjoiOzs7OztRQWlEZ0JBLEssR0FBQUEsSzs7O0FBM0NoQixNQUFNQyxhQUFhLElBQUlDLE9BQUosRUFBbkI7QUFFZSxNQUFNQyxVQUFOLENBQWlCO0FBQzlCQyxjQUFZQyxNQUFaLEVBQTRCQyxXQUFtQixFQUEvQyxFQUFtRDtBQUNqREwsZUFBV00sR0FBWCxDQUFlLElBQWYsRUFBcUI7QUFDbkJGLFlBRG1CO0FBRW5CQyxjQUZtQjtBQUduQkUsZ0JBQVU7QUFIUyxLQUFyQjtBQUtEOztBQUVELE1BQUlQLFVBQUosR0FBNkI7QUFDM0I7QUFDQSxVQUFNLEVBQUVLLFFBQUYsRUFBWUUsUUFBWixLQUF5QlAsV0FBV1EsR0FBWCxDQUFlLElBQWYsQ0FBL0I7QUFDQSxXQUFPLEVBQUVILFFBQUYsRUFBWUUsUUFBWixFQUFQO0FBQ0Q7O0FBRUQ7QUFDQUUsT0FBS0MsY0FBc0IsQ0FBM0IsRUFBc0M7QUFDcEM7QUFDQSxVQUFNLEVBQUVOLE1BQUYsRUFBVUcsUUFBVixLQUF1QlAsV0FBV1EsR0FBWCxDQUFlLElBQWYsQ0FBN0I7QUFDQSxRQUFJRCxXQUFXRyxXQUFYLElBQTBCTixPQUFPTyxNQUFyQyxFQUE2QyxPQUFPLEVBQVA7QUFDN0MsV0FBT1AsT0FBT0csV0FBV0csV0FBbEIsQ0FBUDtBQUNEOztBQUVEO0FBQ0FFLGFBQVdDLFdBQW1CLENBQTlCLEVBQXlDO0FBQ3ZDLFVBQU1DLE9BQU9kLFdBQVdRLEdBQVgsQ0FBZSxJQUFmLENBQWI7QUFDQTtBQUNBLFVBQU0sRUFBRUosTUFBRixFQUFVRyxRQUFWLEtBQXVCTyxJQUE3QjtBQUNBLFVBQU1DLE1BQU1YLE9BQU9ZLEtBQVAsQ0FBYVQsUUFBYixFQUF1QkEsV0FBV00sUUFBbEMsQ0FBWjtBQUNBO0FBQ0FDLFNBQUtQLFFBQUwsSUFBaUJRLElBQUlKLE1BQXJCO0FBQ0EsV0FBT0ksR0FBUDtBQUNEOztBQUVERSxXQUFTQyxLQUFULEVBQWdDO0FBQzlCO0FBQ0EsVUFBTSxFQUFFZCxNQUFGLEVBQVVHLFFBQVYsS0FBdUJQLFdBQVdRLEdBQVgsQ0FBZSxJQUFmLENBQTdCO0FBQ0EsV0FBT0osT0FBT1ksS0FBUCxDQUFhRSxLQUFiLEVBQW9CWCxRQUFwQixDQUFQO0FBQ0Q7QUF0QzZCOztrQkFBWEwsVTtBQXlDZCxTQUFTSCxLQUFULENBQWVvQixJQUFmLEVBQXNDO0FBQzNDLFNBQU9BLFNBQVMsRUFBaEI7QUFDRCIsImZpbGUiOiJjaGFyLXN0cmVhbS5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG5leHBvcnQgdHlwZSBTb3VyY2VJbmZvID0ge1xuICBmaWxlbmFtZTogc3RyaW5nLFxuICBwb3NpdGlvbjogbnVtYmVyXG59O1xuXG5jb25zdCBzb3VyY2VJbmZvID0gbmV3IFdlYWtNYXAoKTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ2hhclN0cmVhbSB7XG4gIGNvbnN0cnVjdG9yKHNvdXJjZTogc3RyaW5nLCBmaWxlbmFtZTogc3RyaW5nID0gJycpIHtcbiAgICBzb3VyY2VJbmZvLnNldCh0aGlzLCB7XG4gICAgICBzb3VyY2UsXG4gICAgICBmaWxlbmFtZSxcbiAgICAgIHBvc2l0aW9uOiAwXG4gICAgfSk7XG4gIH1cblxuICBnZXQgc291cmNlSW5mbygpOiBTb3VyY2VJbmZvIHtcbiAgICAvLyAkRmxvd0ZpeE1lOiBkZWNpZGUgb24gaG93IHRvIGhhbmRsZSBwb3NzaWJsZSBudWxsYWJpbGl0eVxuICAgIGNvbnN0IHsgZmlsZW5hbWUsIHBvc2l0aW9uIH0gPSBzb3VyY2VJbmZvLmdldCh0aGlzKTtcbiAgICByZXR1cm4geyBmaWxlbmFtZSwgcG9zaXRpb24gfTtcbiAgfVxuXG4gIC8vIHJldHVybnMgdGhlIFVuaWNvZGUgY2hhcmFjdGVyIGNoYXJzVG9Ta2lwIGFoZWFkLlxuICBwZWVrKGNoYXJzVG9Ta2lwOiBudW1iZXIgPSAwKTogc3RyaW5nIHtcbiAgICAvLyAkRmxvd0ZpeE1lOiBkZWNpZGUgb24gaG93IHRvIGhhbmRsZSBwb3NzaWJsZSBudWxsYWJpbGl0eVxuICAgIGNvbnN0IHsgc291cmNlLCBwb3NpdGlvbiB9ID0gc291cmNlSW5mby5nZXQodGhpcyk7XG4gICAgaWYgKHBvc2l0aW9uICsgY2hhcnNUb1NraXAgPj0gc291cmNlLmxlbmd0aCkgcmV0dXJuICcnO1xuICAgIHJldHVybiBzb3VyY2VbcG9zaXRpb24gKyBjaGFyc1RvU2tpcF07XG4gIH1cblxuICAvLyByZXR1cm5zIGEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIG5leHQgbnVtQ2hhcnMgY2hhcmFjdGVycy5cbiAgcmVhZFN0cmluZyhudW1DaGFyczogbnVtYmVyID0gMSk6IHN0cmluZyB7XG4gICAgY29uc3QgaW5mbyA9IHNvdXJjZUluZm8uZ2V0KHRoaXMpO1xuICAgIC8vICRGbG93Rml4TWU6IGRlY2lkZSBvbiBob3cgdG8gaGFuZGxlIHBvc3NpYmxlIG51bGxhYmlsaXR5XG4gICAgY29uc3QgeyBzb3VyY2UsIHBvc2l0aW9uIH0gPSBpbmZvO1xuICAgIGNvbnN0IHN0ciA9IHNvdXJjZS5zbGljZShwb3NpdGlvbiwgcG9zaXRpb24gKyBudW1DaGFycyk7XG4gICAgLy8gJEZsb3dGaXhNZTogZGVjaWRlIG9uIGhvdyB0byBoYW5kbGUgcG9zc2libGUgbnVsbGFiaWxpdHlcbiAgICBpbmZvLnBvc2l0aW9uICs9IHN0ci5sZW5ndGg7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxuXG4gIGdldFNsaWNlKHN0YXJ0OiBudW1iZXIpOiBzdHJpbmcge1xuICAgIC8vICRGbG93Rml4TWU6IGRlY2lkZSBvbiBob3cgdG8gaGFuZGxlIHBvc3NpYmxlIG51bGxhYmlsaXR5XG4gICAgY29uc3QgeyBzb3VyY2UsIHBvc2l0aW9uIH0gPSBzb3VyY2VJbmZvLmdldCh0aGlzKTtcbiAgICByZXR1cm4gc291cmNlLnNsaWNlKHN0YXJ0LCBwb3NpdGlvbik7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRU9TKGNoYXI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gY2hhciA9PT0gJyc7XG59XG4iXX0=\n\n/***/ },\n/* 9 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.setCurrentReadtable = setCurrentReadtable;\n\texports.getCurrentReadtable = getCurrentReadtable;\n\n\tvar _charStream = __webpack_require__(8);\n\n\tvar _readtable = __webpack_require__(10);\n\n\tconst defaultDispatchKey = '#';\n\tlet dispatching = false;\n\n\tlet currentReadtable = _readtable.EmptyReadtable.extend({\n\t  key: defaultDispatchKey,\n\t  mode: 'non-terminating',\n\t  action: function readDispatchChar(stream, ...rest) {\n\t    stream.readString();\n\t    dispatching = true;\n\t    return this.read(stream, ...rest, defaultDispatchKey);\n\t  }\n\t});\n\n\tclass Reader {\n\t  read(stream, ...rest) {\n\t    let key = stream.peek();\n\t    if (!(0, _charStream.isEOS)(key)) {\n\t      const entry = currentReadtable.getMapping(key);\n\t      const action = dispatching ? (dispatching = false, entry.dispatchAction) : entry.action;\n\n\t      return action.call(this, stream, ...rest);\n\t    }\n\t    throw Error('Unexpected end of input');\n\t  }\n\t}\n\n\texports.default = Reader;\n\tfunction setCurrentReadtable(readtable) {\n\t  currentReadtable = readtable;\n\t}\n\n\tfunction getCurrentReadtable() {\n\t  return currentReadtable;\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9yZWFkZXIuanMiXSwibmFtZXMiOlsic2V0Q3VycmVudFJlYWR0YWJsZSIsImdldEN1cnJlbnRSZWFkdGFibGUiLCJkZWZhdWx0RGlzcGF0Y2hLZXkiLCJkaXNwYXRjaGluZyIsImN1cnJlbnRSZWFkdGFibGUiLCJleHRlbmQiLCJrZXkiLCJtb2RlIiwiYWN0aW9uIiwicmVhZERpc3BhdGNoQ2hhciIsInN0cmVhbSIsInJlc3QiLCJyZWFkU3RyaW5nIiwicmVhZCIsIlJlYWRlciIsInBlZWsiLCJlbnRyeSIsImdldE1hcHBpbmciLCJkaXNwYXRjaEFjdGlvbiIsImNhbGwiLCJFcnJvciIsInJlYWR0YWJsZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7UUFrQ2dCQSxtQixHQUFBQSxtQjtRQUlBQyxtQixHQUFBQSxtQjs7QUFqQ2hCOztBQUNBOztBQUVBLE1BQU1DLHFCQUFxQixHQUEzQjtBQUNBLElBQUlDLGNBQWMsS0FBbEI7O0FBRUEsSUFBSUMsbUJBQW1CLDBCQUFlQyxNQUFmLENBQXNCO0FBQzNDQyxPQUFLSixrQkFEc0M7QUFFM0NLLFFBQU0saUJBRnFDO0FBRzNDQyxVQUFRLFNBQVNDLGdCQUFULENBQTBCQyxNQUExQixFQUFrQyxHQUFHQyxJQUFyQyxFQUEyQztBQUNqREQsV0FBT0UsVUFBUDtBQUNBVCxrQkFBYyxJQUFkO0FBQ0EsV0FBTyxLQUFLVSxJQUFMLENBQVVILE1BQVYsRUFBa0IsR0FBR0MsSUFBckIsRUFBMkJULGtCQUEzQixDQUFQO0FBQ0Q7QUFQMEMsQ0FBdEIsQ0FBdkI7O0FBVWUsTUFBTVksTUFBTixDQUFhO0FBQzFCRCxPQUFLSCxNQUFMLEVBQXlCLEdBQUdDLElBQTVCLEVBQW9EO0FBQ2xELFFBQUlMLE1BQU1JLE9BQU9LLElBQVAsRUFBVjtBQUNBLFFBQUksQ0FBQyx1QkFBTVQsR0FBTixDQUFMLEVBQWlCO0FBQ2YsWUFBTVUsUUFBUVosaUJBQWlCYSxVQUFqQixDQUE0QlgsR0FBNUIsQ0FBZDtBQUNBLFlBQU1FLFNBQVNMLGVBQWVBLGNBQWMsS0FBZCxFQUFxQmEsTUFBTUUsY0FBMUMsSUFBNERGLE1BQU1SLE1BQWpGOztBQUVBLGFBQU9BLE9BQU9XLElBQVAsQ0FBWSxJQUFaLEVBQWtCVCxNQUFsQixFQUEwQixHQUFHQyxJQUE3QixDQUFQO0FBQ0Q7QUFDRCxVQUFNUyxNQUFNLHlCQUFOLENBQU47QUFDRDtBQVZ5Qjs7a0JBQVBOLE07QUFhZCxTQUFTZCxtQkFBVCxDQUE2QnFCLFNBQTdCLEVBQXlEO0FBQzlEakIscUJBQW1CaUIsU0FBbkI7QUFDRDs7QUFFTSxTQUFTcEIsbUJBQVQsR0FBMEM7QUFDL0MsU0FBT0csZ0JBQVA7QUFDRCIsImZpbGUiOiJyZWFkZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAZmxvd1xuXG5pbXBvcnQgdHlwZSBSZWFkdGFibGUgZnJvbSAnLi9yZWFkdGFibGUnO1xuaW1wb3J0IHR5cGUgQ2hhclN0cmVhbSBmcm9tICcuL2NoYXItc3RyZWFtJztcblxuaW1wb3J0IHsgaXNFT1MgfSBmcm9tICcuL2NoYXItc3RyZWFtJztcbmltcG9ydCB7IEVtcHR5UmVhZHRhYmxlIH0gZnJvbSAnLi9yZWFkdGFibGUnO1xuXG5jb25zdCBkZWZhdWx0RGlzcGF0Y2hLZXkgPSAnIyc7XG5sZXQgZGlzcGF0Y2hpbmcgPSBmYWxzZTtcblxubGV0IGN1cnJlbnRSZWFkdGFibGUgPSBFbXB0eVJlYWR0YWJsZS5leHRlbmQoe1xuICBrZXk6IGRlZmF1bHREaXNwYXRjaEtleSxcbiAgbW9kZTogJ25vbi10ZXJtaW5hdGluZycsXG4gIGFjdGlvbjogZnVuY3Rpb24gcmVhZERpc3BhdGNoQ2hhcihzdHJlYW0sIC4uLnJlc3QpIHtcbiAgICBzdHJlYW0ucmVhZFN0cmluZygpO1xuICAgIGRpc3BhdGNoaW5nID0gdHJ1ZTtcbiAgICByZXR1cm4gdGhpcy5yZWFkKHN0cmVhbSwgLi4ucmVzdCwgZGVmYXVsdERpc3BhdGNoS2V5KTtcbiAgfVxufSk7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlYWRlciB7XG4gIHJlYWQoc3RyZWFtOiBDaGFyU3RyZWFtLCAuLi5yZXN0PzogQXJyYXk8YW55Pik6IGFueSB7XG4gICAgbGV0IGtleSA9IHN0cmVhbS5wZWVrKCk7XG4gICAgaWYgKCFpc0VPUyhrZXkpKSB7XG4gICAgICBjb25zdCBlbnRyeSA9IGN1cnJlbnRSZWFkdGFibGUuZ2V0TWFwcGluZyhrZXkpO1xuICAgICAgY29uc3QgYWN0aW9uID0gZGlzcGF0Y2hpbmcgPyAoZGlzcGF0Y2hpbmcgPSBmYWxzZSwgZW50cnkuZGlzcGF0Y2hBY3Rpb24pIDogZW50cnkuYWN0aW9uO1xuXG4gICAgICByZXR1cm4gYWN0aW9uLmNhbGwodGhpcywgc3RyZWFtLCAuLi5yZXN0KTtcbiAgICB9XG4gICAgdGhyb3cgRXJyb3IoJ1VuZXhwZWN0ZWQgZW5kIG9mIGlucHV0Jyk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldEN1cnJlbnRSZWFkdGFibGUocmVhZHRhYmxlOiBSZWFkdGFibGUpOiB2b2lkIHtcbiAgY3VycmVudFJlYWR0YWJsZSA9IHJlYWR0YWJsZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEN1cnJlbnRSZWFkdGFibGUoKTogUmVhZHRhYmxlIHtcbiAgcmV0dXJuIGN1cnJlbnRSZWFkdGFibGU7XG59XG4iXX0=\n\n/***/ },\n/* 10 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\n\n\t/*\n\t * 1. { key, mode: 'terminating', action } - creates a delimiter must return an Array/List\n\t * 2. { key, mode: 'non-terminating', action } - must return a Token or null/undefined. null/undefined simply consumes the read charstream.\n\t * 3. { key, mode: 'dispatch', action } - triggered by reading #. otherwise like 2\n\t * 4. { key: null | undefined, mode: 'non-terminating', action } - sets the default behavior for unmatched characters (identifiers/numbers)\n\t */\n\n\tconst DISPATCH_OFFSET = 0x110000;\n\n\tclass Readtable {\n\t  constructor(entries = []) {\n\t    this._entries = entries;\n\t  }\n\n\t  getMapping(key) {\n\t    if (!isValidKey(key)) throw Error('Invalid key type:', key);\n\t    key = convertKey(key);\n\t    const { action, mode } = this._entries[key] || this._entries[0];\n\t    const dispatchEntry = this._entries[key + DISPATCH_OFFSET] || this._entries[DISPATCH_OFFSET] || {};\n\t    return { action, mode, dispatchAction: dispatchEntry.action };\n\t  }\n\n\t  extend(...entries) {\n\t    const newTable = this._entries.slice();\n\t    return new Readtable(entries.reduce(addEntry, newTable));\n\t  }\n\t}\n\n\texports.default = Readtable;\n\tfunction addEntry(table, { key, mode, action }) {\n\t  if (!isValidEntry({ key, mode, action })) throw Error('Invalid readtable entry:', { key, mode, action });\n\n\t  // null/undefined key is the default and will be converted to 0\n\t  // chars will be converted via codePointAt\n\t  // numbers are...numbers\n\t  // to accommodate default (null) 1 will be added to all and default will be at 0\n\t  // if is a dispatch macro, we have to convert the key and bump it up by DISPATCH_OFFSET\n\t  table[convertKey(key) + (mode === 'dispatch' ? DISPATCH_OFFSET : 0)] = { action, mode };\n\n\t  return table;\n\t}\n\n\tconst EmptyReadtable = exports.EmptyReadtable = new Readtable([{\n\t  mode: 'non-terminating',\n\t  action: function defaultAction() {\n\t    throw Error('A default readtable entry must be added');\n\t  }\n\t}]);\n\n\tfunction isValidKey(key) {\n\t  return key == null || typeof key === 'number' && key < DISPATCH_OFFSET || typeof key === 'string' && key.length >= 0 && key.length <= 2;\n\t}\n\n\tfunction isValidMode(mode) {\n\t  return mode === 'terminating' || mode === 'non-terminating' || mode === 'dispatch';\n\t}\n\n\tfunction isValidAction(action) {\n\t  return typeof action === 'function';\n\t}\n\n\tfunction isValidEntry(entry) {\n\t  return entry && isValidKey(entry.key) && isValidMode(entry.mode) && isValidAction(entry.action);\n\t}\n\n\tfunction convertKey(key) {\n\t  return key == null ? 0 : (typeof key === 'number' ? key : key.codePointAt(0)) + 1;\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9yZWFkdGFibGUuanMiXSwibmFtZXMiOlsiRElTUEFUQ0hfT0ZGU0VUIiwiUmVhZHRhYmxlIiwiY29uc3RydWN0b3IiLCJlbnRyaWVzIiwiX2VudHJpZXMiLCJnZXRNYXBwaW5nIiwia2V5IiwiaXNWYWxpZEtleSIsIkVycm9yIiwiY29udmVydEtleSIsImFjdGlvbiIsIm1vZGUiLCJkaXNwYXRjaEVudHJ5IiwiZGlzcGF0Y2hBY3Rpb24iLCJleHRlbmQiLCJuZXdUYWJsZSIsInNsaWNlIiwicmVkdWNlIiwiYWRkRW50cnkiLCJ0YWJsZSIsImlzVmFsaWRFbnRyeSIsIkVtcHR5UmVhZHRhYmxlIiwiZGVmYXVsdEFjdGlvbiIsImxlbmd0aCIsImlzVmFsaWRNb2RlIiwiaXNWYWxpZEFjdGlvbiIsImVudHJ5IiwiY29kZVBvaW50QXQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFFQTs7Ozs7OztBQU9BLE1BQU1BLGtCQUFrQixRQUF4Qjs7QUFvQmUsTUFBTUMsU0FBTixDQUFnQjtBQUU3QkMsY0FBWUMsVUFBaUMsRUFBN0MsRUFBaUQ7QUFDL0MsU0FBS0MsUUFBTCxHQUFnQkQsT0FBaEI7QUFDRDs7QUFFREUsYUFBV0MsR0FBWCxFQUFpRDtBQUMvQyxRQUFJLENBQUNDLFdBQVdELEdBQVgsQ0FBTCxFQUFzQixNQUFNRSxNQUFNLG1CQUFOLEVBQTJCRixHQUEzQixDQUFOO0FBQ3RCQSxVQUFNRyxXQUFXSCxHQUFYLENBQU47QUFDQSxVQUFNLEVBQUVJLE1BQUYsRUFBVUMsSUFBVixLQUFtQixLQUFLUCxRQUFMLENBQWNFLEdBQWQsS0FBc0IsS0FBS0YsUUFBTCxDQUFjLENBQWQsQ0FBL0M7QUFDQSxVQUFNUSxnQkFBZ0IsS0FBS1IsUUFBTCxDQUFjRSxNQUFNTixlQUFwQixLQUF3QyxLQUFLSSxRQUFMLENBQWNKLGVBQWQsQ0FBeEMsSUFBMEUsRUFBaEc7QUFDQSxXQUFPLEVBQUVVLE1BQUYsRUFBVUMsSUFBVixFQUFnQkUsZ0JBQWdCRCxjQUFjRixNQUE5QyxFQUFQO0FBQ0Q7O0FBRURJLFNBQU8sR0FBR1gsT0FBVixFQUFxRDtBQUNuRCxVQUFNWSxXQUFXLEtBQUtYLFFBQUwsQ0FBY1ksS0FBZCxFQUFqQjtBQUNBLFdBQU8sSUFBSWYsU0FBSixDQUFjRSxRQUFRYyxNQUFSLENBQWVDLFFBQWYsRUFBeUJILFFBQXpCLENBQWQsQ0FBUDtBQUNEO0FBakI0Qjs7a0JBQVZkLFM7QUFvQnJCLFNBQVNpQixRQUFULENBQWtCQyxLQUFsQixFQUFnRCxFQUFFYixHQUFGLEVBQU9LLElBQVAsRUFBYUQsTUFBYixFQUFoRCxFQUE4RztBQUM1RyxNQUFJLENBQUNVLGFBQWEsRUFBQ2QsR0FBRCxFQUFNSyxJQUFOLEVBQVlELE1BQVosRUFBYixDQUFMLEVBQXdDLE1BQU1GLE1BQU0sMEJBQU4sRUFBa0MsRUFBQ0YsR0FBRCxFQUFNSyxJQUFOLEVBQVlELE1BQVosRUFBbEMsQ0FBTjs7QUFFeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBUyxRQUFNVixXQUFXSCxHQUFYLEtBQW1CSyxTQUFTLFVBQVQsR0FBc0JYLGVBQXRCLEdBQXdDLENBQTNELENBQU4sSUFBdUUsRUFBRVUsTUFBRixFQUFVQyxJQUFWLEVBQXZFOztBQUVBLFNBQU9RLEtBQVA7QUFDRDs7QUFFTSxNQUFNRSwwQ0FBaUIsSUFBSXBCLFNBQUosQ0FBYyxDQUFDO0FBQzNDVSxRQUFNLGlCQURxQztBQUUzQ0QsVUFBUSxTQUFTWSxhQUFULEdBQXlCO0FBQy9CLFVBQU1kLE1BQU0seUNBQU4sQ0FBTjtBQUNEO0FBSjBDLENBQUQsQ0FBZCxDQUF2Qjs7QUFPUCxTQUFTRCxVQUFULENBQW9CRCxHQUFwQixFQUF5QjtBQUN2QixTQUFPQSxPQUFPLElBQVAsSUFDSixPQUFPQSxHQUFQLEtBQWUsUUFBZixJQUEyQkEsTUFBTU4sZUFEN0IsSUFFSixPQUFPTSxHQUFQLEtBQWUsUUFBZixJQUE0QkEsSUFBSWlCLE1BQUosSUFBYyxDQUFkLElBQW1CakIsSUFBSWlCLE1BQUosSUFBYyxDQUZoRTtBQUdEOztBQUVELFNBQVNDLFdBQVQsQ0FBcUJiLElBQXJCLEVBQTRDO0FBQzFDLFNBQU9BLFNBQVMsYUFBVCxJQUEwQkEsU0FBUyxpQkFBbkMsSUFBd0RBLFNBQVMsVUFBeEU7QUFDRDs7QUFFRCxTQUFTYyxhQUFULENBQXVCZixNQUF2QixFQUErQjtBQUM3QixTQUFPLE9BQU9BLE1BQVAsS0FBa0IsVUFBekI7QUFDRDs7QUFFRCxTQUFTVSxZQUFULENBQXNCTSxLQUF0QixFQUE2QztBQUMzQyxTQUFPQSxTQUFTbkIsV0FBV21CLE1BQU1wQixHQUFqQixDQUFULElBQWtDa0IsWUFBWUUsTUFBTWYsSUFBbEIsQ0FBbEMsSUFBNkRjLGNBQWNDLE1BQU1oQixNQUFwQixDQUFwRTtBQUNEOztBQUVELFNBQVNELFVBQVQsQ0FBb0JILEdBQXBCLEVBQWdEO0FBQzlDLFNBQU9BLE9BQU8sSUFBUCxHQUFjLENBQWQsR0FBa0IsQ0FBQyxPQUFPQSxHQUFQLEtBQWUsUUFBZixHQUEwQkEsR0FBMUIsR0FBZ0NBLElBQUlxQixXQUFKLENBQWdCLENBQWhCLENBQWpDLElBQXVELENBQWhGO0FBQ0QiLCJmaWxlIjoicmVhZHRhYmxlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcblxuLypcbiAqIDEuIHsga2V5LCBtb2RlOiAndGVybWluYXRpbmcnLCBhY3Rpb24gfSAtIGNyZWF0ZXMgYSBkZWxpbWl0ZXIgbXVzdCByZXR1cm4gYW4gQXJyYXkvTGlzdFxuICogMi4geyBrZXksIG1vZGU6ICdub24tdGVybWluYXRpbmcnLCBhY3Rpb24gfSAtIG11c3QgcmV0dXJuIGEgVG9rZW4gb3IgbnVsbC91bmRlZmluZWQuIG51bGwvdW5kZWZpbmVkIHNpbXBseSBjb25zdW1lcyB0aGUgcmVhZCBjaGFyc3RyZWFtLlxuICogMy4geyBrZXksIG1vZGU6ICdkaXNwYXRjaCcsIGFjdGlvbiB9IC0gdHJpZ2dlcmVkIGJ5IHJlYWRpbmcgIy4gb3RoZXJ3aXNlIGxpa2UgMlxuICogNC4geyBrZXk6IG51bGwgfCB1bmRlZmluZWQsIG1vZGU6ICdub24tdGVybWluYXRpbmcnLCBhY3Rpb24gfSAtIHNldHMgdGhlIGRlZmF1bHQgYmVoYXZpb3IgZm9yIHVubWF0Y2hlZCBjaGFyYWN0ZXJzIChpZGVudGlmaWVycy9udW1iZXJzKVxuICovXG5cbmNvbnN0IERJU1BBVENIX09GRlNFVCA9IDB4MTEwMDAwO1xuXG50eXBlIFJlYWR0YWJsZUtleSA9IHN0cmluZyB8IG51bWJlciB8IG51bGw7XG5cbnR5cGUgQWN0aW9uID0gKC4uLmFyZ3M6IEFycmF5PGFueT4pID0+IGFueTtcblxudHlwZSBSZWFkdGFibGVNb2RlID0gJ3Rlcm1pbmF0aW5nJyB8ICdub24tdGVybWluYXRpbmcnIHwgJ2Rpc3BhdGNoJztcblxudHlwZSBSZWFkdGFibGVFbnRyeSA9IHtcbiAga2V5PzogP1JlYWR0YWJsZUtleSxcbiAgbW9kZTogUmVhZHRhYmxlTW9kZSxcbiAgYWN0aW9uOiBBY3Rpb25cbn07XG5cbnR5cGUgUmVhZHRhYmxlTWFwcGluZyA9IHtcbiAgbW9kZTogUmVhZHRhYmxlTW9kZSxcbiAgYWN0aW9uOiBBY3Rpb24sXG4gIGRpc3BhdGNoQWN0aW9uOiBBY3Rpb25cbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlYWR0YWJsZSB7XG4gIF9lbnRyaWVzOiBBcnJheTxSZWFkdGFibGVFbnRyeT47XG4gIGNvbnN0cnVjdG9yKGVudHJpZXM6IEFycmF5PFJlYWR0YWJsZUVudHJ5PiA9IFtdKSB7XG4gICAgdGhpcy5fZW50cmllcyA9IGVudHJpZXM7XG4gIH1cblxuICBnZXRNYXBwaW5nKGtleT86IFJlYWR0YWJsZUtleSk6IFJlYWR0YWJsZU1hcHBpbmcge1xuICAgIGlmICghaXNWYWxpZEtleShrZXkpKSB0aHJvdyBFcnJvcignSW52YWxpZCBrZXkgdHlwZTonLCBrZXkpO1xuICAgIGtleSA9IGNvbnZlcnRLZXkoa2V5KTtcbiAgICBjb25zdCB7IGFjdGlvbiwgbW9kZSB9ID0gdGhpcy5fZW50cmllc1trZXldIHx8IHRoaXMuX2VudHJpZXNbMF07XG4gICAgY29uc3QgZGlzcGF0Y2hFbnRyeSA9IHRoaXMuX2VudHJpZXNba2V5ICsgRElTUEFUQ0hfT0ZGU0VUXSB8fCB0aGlzLl9lbnRyaWVzW0RJU1BBVENIX09GRlNFVF0gfHwge307XG4gICAgcmV0dXJuIHsgYWN0aW9uLCBtb2RlLCBkaXNwYXRjaEFjdGlvbjogZGlzcGF0Y2hFbnRyeS5hY3Rpb24gfTtcbiAgfVxuXG4gIGV4dGVuZCguLi5lbnRyaWVzOiBBcnJheTxSZWFkdGFibGVFbnRyeT4pOiBSZWFkdGFibGUge1xuICAgIGNvbnN0IG5ld1RhYmxlID0gdGhpcy5fZW50cmllcy5zbGljZSgpO1xuICAgIHJldHVybiBuZXcgUmVhZHRhYmxlKGVudHJpZXMucmVkdWNlKGFkZEVudHJ5LCBuZXdUYWJsZSkpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGFkZEVudHJ5KHRhYmxlOiBBcnJheTxSZWFkdGFibGVFbnRyeT4sIHsga2V5LCBtb2RlLCBhY3Rpb24gfTogUmVhZHRhYmxlRW50cnkpOiBBcnJheTxSZWFkdGFibGVFbnRyeT4ge1xuICBpZiAoIWlzVmFsaWRFbnRyeSh7a2V5LCBtb2RlLCBhY3Rpb259KSkgdGhyb3cgRXJyb3IoJ0ludmFsaWQgcmVhZHRhYmxlIGVudHJ5OicsIHtrZXksIG1vZGUsIGFjdGlvbn0pO1xuXG4gIC8vIG51bGwvdW5kZWZpbmVkIGtleSBpcyB0aGUgZGVmYXVsdCBhbmQgd2lsbCBiZSBjb252ZXJ0ZWQgdG8gMFxuICAvLyBjaGFycyB3aWxsIGJlIGNvbnZlcnRlZCB2aWEgY29kZVBvaW50QXRcbiAgLy8gbnVtYmVycyBhcmUuLi5udW1iZXJzXG4gIC8vIHRvIGFjY29tbW9kYXRlIGRlZmF1bHQgKG51bGwpIDEgd2lsbCBiZSBhZGRlZCB0byBhbGwgYW5kIGRlZmF1bHQgd2lsbCBiZSBhdCAwXG4gIC8vIGlmIGlzIGEgZGlzcGF0Y2ggbWFjcm8sIHdlIGhhdmUgdG8gY29udmVydCB0aGUga2V5IGFuZCBidW1wIGl0IHVwIGJ5IERJU1BBVENIX09GRlNFVFxuICB0YWJsZVtjb252ZXJ0S2V5KGtleSkgKyAobW9kZSA9PT0gJ2Rpc3BhdGNoJyA/IERJU1BBVENIX09GRlNFVCA6IDApXSA9IHsgYWN0aW9uLCBtb2RlIH07XG5cbiAgcmV0dXJuIHRhYmxlO1xufVxuXG5leHBvcnQgY29uc3QgRW1wdHlSZWFkdGFibGUgPSBuZXcgUmVhZHRhYmxlKFt7XG4gIG1vZGU6ICdub24tdGVybWluYXRpbmcnLFxuICBhY3Rpb246IGZ1bmN0aW9uIGRlZmF1bHRBY3Rpb24oKSB7XG4gICAgdGhyb3cgRXJyb3IoJ0EgZGVmYXVsdCByZWFkdGFibGUgZW50cnkgbXVzdCBiZSBhZGRlZCcpO1xuICB9XG59XSk7XG5cbmZ1bmN0aW9uIGlzVmFsaWRLZXkoa2V5KSB7XG4gIHJldHVybiBrZXkgPT0gbnVsbCB8fFxuICAgICh0eXBlb2Yga2V5ID09PSAnbnVtYmVyJyAmJiBrZXkgPCBESVNQQVRDSF9PRkZTRVQpIHx8XG4gICAgKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnICYmIChrZXkubGVuZ3RoID49IDAgJiYga2V5Lmxlbmd0aCA8PSAyKSk7XG59XG5cbmZ1bmN0aW9uIGlzVmFsaWRNb2RlKG1vZGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gbW9kZSA9PT0gJ3Rlcm1pbmF0aW5nJyB8fCBtb2RlID09PSAnbm9uLXRlcm1pbmF0aW5nJyB8fCBtb2RlID09PSAnZGlzcGF0Y2gnO1xufVxuXG5mdW5jdGlvbiBpc1ZhbGlkQWN0aW9uKGFjdGlvbikge1xuICByZXR1cm4gdHlwZW9mIGFjdGlvbiA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuZnVuY3Rpb24gaXNWYWxpZEVudHJ5KGVudHJ5OiBSZWFkdGFibGVFbnRyeSkge1xuICByZXR1cm4gZW50cnkgJiYgaXNWYWxpZEtleShlbnRyeS5rZXkpICYmIGlzVmFsaWRNb2RlKGVudHJ5Lm1vZGUpICYmIGlzVmFsaWRBY3Rpb24oZW50cnkuYWN0aW9uKTtcbn1cblxuZnVuY3Rpb24gY29udmVydEtleShrZXk/OiBSZWFkdGFibGVLZXkpOiBudW1iZXIge1xuICByZXR1cm4ga2V5ID09IG51bGwgPyAwIDogKHR5cGVvZiBrZXkgPT09ICdudW1iZXInID8ga2V5IDoga2V5LmNvZGVQb2ludEF0KDApKSArIDE7XG59XG4iXX0=\n\n/***/ },\n/* 11 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\n\tvar _immutable = __webpack_require__(12);\n\n\tvar _readtable = __webpack_require__(7);\n\n\tvar _readIdentifier = __webpack_require__(13);\n\n\tvar _readIdentifier2 = _interopRequireDefault(_readIdentifier);\n\n\tvar _readNumeric = __webpack_require__(32);\n\n\tvar _readNumeric2 = _interopRequireDefault(_readNumeric);\n\n\tvar _readString = __webpack_require__(33);\n\n\tvar _readString2 = _interopRequireDefault(_readString);\n\n\tvar _readTemplate = __webpack_require__(34);\n\n\tvar _readTemplate2 = _interopRequireDefault(_readTemplate);\n\n\tvar _readRegexp = __webpack_require__(35);\n\n\tvar _readRegexp2 = _interopRequireDefault(_readRegexp);\n\n\tvar _readComment = __webpack_require__(36);\n\n\tvar _readComment2 = _interopRequireDefault(_readComment);\n\n\tvar _readDispatch = __webpack_require__(37);\n\n\tvar _tokens = __webpack_require__(19);\n\n\tvar _utils = __webpack_require__(14);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\t// use https://github.com/mathiasbynens/regenerate to generate the Unicode code points when implementing modes\n\n\tfunction eatWhitespace(stream) {\n\t  stream.readString();\n\t  return _tokens.EmptyToken;\n\t}\n\n\tconst punctuatorTable = Object.keys(_tokens.punctuatorTable).reduce(_utils.insertSequence, {});\n\n\tfunction readPunctuator(stream) {\n\t  const len = (0, _utils.retrieveSequenceLength)(punctuatorTable, stream, 0);\n\t  if (len > 0) {\n\t    return new _tokens.PunctuatorToken({\n\t      value: stream.readString(len)\n\t    });\n\t  }\n\t  throw Error('Unknown punctuator');\n\t}\n\n\tconst punctuatorEntries = Object.keys(punctuatorTable).map(p => ({\n\t  key: p,\n\t  mode: 'terminating',\n\t  action: readPunctuator\n\t}));\n\n\tconst whiteSpaceTable = [0x20, 0x09, 0x0b, 0x0c, 0xa0, 0x1680, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200a, 0x202f, 0x205f, 0x3000, 0xfeff];\n\n\tconst whiteSpaceEntries = whiteSpaceTable.map(w => ({\n\t  key: w,\n\t  mode: 'terminating',\n\t  action: eatWhitespace\n\t}));\n\n\tconst lineTerminatorTable = [0x0a, 0x0d, 0x2028, 0x2029];\n\n\tconst lineTerminatorEntries = lineTerminatorTable.map(lt => ({\n\t  key: lt,\n\t  mode: 'terminating',\n\t  action: function readLineTerminator(stream) {\n\t    this.incrementLine();\n\t    return eatWhitespace(stream);\n\t  }\n\t}));\n\n\tconst digits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];\n\n\tconst numericEntries = digits.map(d => ({\n\t  key: d,\n\t  mode: 'non-terminating',\n\t  action: _readNumeric2.default\n\t}));\n\n\tconst quotes = ['\\'', '\"'];\n\n\tconst stringEntries = quotes.map(q => ({\n\t  key: q,\n\t  mode: 'terminating',\n\t  action: _readString2.default\n\t}));\n\n\tconst identifierEntry = {\n\t  mode: 'non-terminating',\n\t  action: _readIdentifier2.default\n\t};\n\n\tconst templateEntry = {\n\t  key: '`',\n\t  mode: 'terminating',\n\t  action: _readTemplate2.default\n\t};\n\n\tconst primitiveReadtable = (0, _readtable.getCurrentReadtable)().extend(...[identifierEntry, ...whiteSpaceEntries, templateEntry, ...punctuatorEntries, ...lineTerminatorEntries, ...numericEntries, ...stringEntries]);\n\n\tconst dotEntry = {\n\t  key: '.',\n\t  mode: 'terminating',\n\t  action: function readDot(stream, ...rest) {\n\t    const nxt = stream.peek(1).charCodeAt(0);\n\t    if ((0, _utils.isDecimalDigit)(nxt)) {\n\t      return (0, _readNumeric2.default)(stream, ...rest);\n\t    }\n\t    return readPunctuator.call(this, stream);\n\t  }\n\t};\n\n\tconst keywordTable = Object.keys(_tokens.keywordTable).reduce(_utils.insertSequence, {});\n\n\tconst keywordEntries = Object.keys(keywordTable).map(k => ({\n\t  key: k,\n\t  mode: 'non-terminating',\n\t  action: function readKeyword(stream) {\n\t    const len = (0, _utils.retrieveSequenceLength)(keywordTable, stream, 0);\n\t    if (len > 0 && !(0, _utils.isIdentifierPart)(stream.peek(len).charCodeAt(0))) {\n\t      return new _tokens.KeywordToken({\n\t        value: stream.readString(len)\n\t      });\n\t    }\n\t    return _readIdentifier2.default.call(this, stream);\n\t  }\n\t}));\n\n\tconst delimiterPairs = [['[', ']'], ['(', ')']];\n\n\tfunction readDelimiters(closing, stream, prefix, b) {\n\t  const currentReadtable = (0, _readtable.getCurrentReadtable)();\n\t  (0, _readtable.setCurrentReadtable)(primitiveReadtable);\n\n\t  let results = _immutable.List.of(this.readToken(stream, (0, _immutable.List)(), b));\n\n\t  (0, _readtable.setCurrentReadtable)(currentReadtable);\n\t  return this.readUntil(closing, stream, results, b);\n\t}\n\n\tconst delimiterEntries = delimiterPairs.map(p => ({\n\t  key: p[0],\n\t  mode: 'terminating',\n\t  action: function readDefaultDelimiters(stream, prefix, b) {\n\t    return readDelimiters.call(this, p[1], stream, prefix, true);\n\t  }\n\t}));\n\n\tconst bracesEntry = {\n\t  key: '{',\n\t  mode: 'terminating',\n\t  action: function readBraces(stream, prefix, b) {\n\t    const line = this.locationInfo.line;\n\t    const innerB = (0, _utils.isExprPrefix)(line, b, prefix);\n\t    return readDelimiters.call(this, '}', stream, prefix, innerB);\n\t  }\n\t};\n\n\tfunction readClosingDelimiter(opening, closing, stream, prefix, b) {\n\t  if (prefix.first().value !== opening) {\n\t    throw Error('Unmatched delimiter:', closing);\n\t  }\n\t  return readPunctuator.call(this, stream);\n\t}\n\n\tconst unmatchedDelimiterEntries = [['{', '}'], ['[', ']'], ['(', ')']].map(p => ({\n\t  key: p[1],\n\t  mode: 'terminating',\n\t  action: function readClosingDelimiters(stream, prefix, b) {\n\t    return readClosingDelimiter.call(this, ...p, stream, prefix, b);\n\t  }\n\t}));\n\n\tconst divEntry = {\n\t  key: '/',\n\t  mode: 'terminating',\n\t  action: function readDiv(stream, prefix, b) {\n\t    let nxt = stream.peek(1);\n\t    if (nxt === '/' || nxt === '*') {\n\t      const result = _readComment2.default.call(this, stream);\n\t      return result;\n\t    }\n\t    if ((0, _utils.isRegexPrefix)(b, prefix)) {\n\t      return _readRegexp2.default.call(this, stream, prefix, b);\n\t    }\n\t    return readPunctuator.call(this, stream);\n\t  }\n\t};\n\n\tconst dispatchBacktickEntry = {\n\t  key: '`',\n\t  mode: 'dispatch',\n\t  action: _readDispatch.readSyntaxTemplate\n\t};\n\n\tconst defaultDispatchEntry = {\n\t  mode: 'dispatch',\n\t  action: function readDefaultDispatch(...args) {\n\t    this.readToken(...args);\n\t    return _tokens.EmptyToken;\n\t  }\n\t};\n\n\tconst dispatchWhiteSpaceEntries = whiteSpaceTable.concat(lineTerminatorTable).map(w => ({\n\t  key: w,\n\t  mode: 'dispatch',\n\t  action: function readDispatchWhitespace(stream, prefix, allowExprs, dispatchKey) {\n\t    this.readToken(stream, prefix, allowExprs);\n\t    return new _tokens.IdentifierToken({ value: dispatchKey });\n\t  }\n\t}));\n\n\tconst atEntry = {\n\t  key: '@',\n\t  mode: 'terminating',\n\t  action: function readAt(stream, prefix) {\n\t    const nxt = stream.peek(1),\n\t          nxtCode = nxt.charCodeAt(0);\n\t    if ((0, _readtable.isEOS)(nxt) || (0, _utils.isWhiteSpace)(nxtCode) || (0, _utils.isLineTerminator)(nxtCode)) {\n\t      return new _tokens.IdentifierToken({ value: stream.readString() });\n\t    }\n\t    throw new SyntaxError('Invalid or unexpected token');\n\t  }\n\t};\n\n\tconst defaultReadtable = primitiveReadtable.extend(...[dotEntry, ...delimiterEntries, ...unmatchedDelimiterEntries, bracesEntry, divEntry, ...keywordEntries, defaultDispatchEntry, dispatchBacktickEntry, ...dispatchWhiteSpaceEntries, atEntry]);\n\n\texports.default = defaultReadtable;\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9yZWFkZXIvZGVmYXVsdC1yZWFkdGFibGUuanMiXSwibmFtZXMiOlsiZWF0V2hpdGVzcGFjZSIsInN0cmVhbSIsInJlYWRTdHJpbmciLCJwdW5jdHVhdG9yVGFibGUiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwicmVhZFB1bmN0dWF0b3IiLCJsZW4iLCJ2YWx1ZSIsIkVycm9yIiwicHVuY3R1YXRvckVudHJpZXMiLCJtYXAiLCJwIiwia2V5IiwibW9kZSIsImFjdGlvbiIsIndoaXRlU3BhY2VUYWJsZSIsIndoaXRlU3BhY2VFbnRyaWVzIiwidyIsImxpbmVUZXJtaW5hdG9yVGFibGUiLCJsaW5lVGVybWluYXRvckVudHJpZXMiLCJsdCIsInJlYWRMaW5lVGVybWluYXRvciIsImluY3JlbWVudExpbmUiLCJkaWdpdHMiLCJudW1lcmljRW50cmllcyIsImQiLCJxdW90ZXMiLCJzdHJpbmdFbnRyaWVzIiwicSIsImlkZW50aWZpZXJFbnRyeSIsInRlbXBsYXRlRW50cnkiLCJwcmltaXRpdmVSZWFkdGFibGUiLCJleHRlbmQiLCJkb3RFbnRyeSIsInJlYWREb3QiLCJyZXN0Iiwibnh0IiwicGVlayIsImNoYXJDb2RlQXQiLCJjYWxsIiwia2V5d29yZFRhYmxlIiwia2V5d29yZEVudHJpZXMiLCJrIiwicmVhZEtleXdvcmQiLCJkZWxpbWl0ZXJQYWlycyIsInJlYWREZWxpbWl0ZXJzIiwiY2xvc2luZyIsInByZWZpeCIsImIiLCJjdXJyZW50UmVhZHRhYmxlIiwicmVzdWx0cyIsIm9mIiwicmVhZFRva2VuIiwicmVhZFVudGlsIiwiZGVsaW1pdGVyRW50cmllcyIsInJlYWREZWZhdWx0RGVsaW1pdGVycyIsImJyYWNlc0VudHJ5IiwicmVhZEJyYWNlcyIsImxpbmUiLCJsb2NhdGlvbkluZm8iLCJpbm5lckIiLCJyZWFkQ2xvc2luZ0RlbGltaXRlciIsIm9wZW5pbmciLCJmaXJzdCIsInVubWF0Y2hlZERlbGltaXRlckVudHJpZXMiLCJyZWFkQ2xvc2luZ0RlbGltaXRlcnMiLCJkaXZFbnRyeSIsInJlYWREaXYiLCJyZXN1bHQiLCJkaXNwYXRjaEJhY2t0aWNrRW50cnkiLCJkZWZhdWx0RGlzcGF0Y2hFbnRyeSIsInJlYWREZWZhdWx0RGlzcGF0Y2giLCJhcmdzIiwiZGlzcGF0Y2hXaGl0ZVNwYWNlRW50cmllcyIsImNvbmNhdCIsInJlYWREaXNwYXRjaFdoaXRlc3BhY2UiLCJhbGxvd0V4cHJzIiwiZGlzcGF0Y2hLZXkiLCJhdEVudHJ5IiwicmVhZEF0Iiwibnh0Q29kZSIsIlN5bnRheEVycm9yIiwiZGVmYXVsdFJlYWR0YWJsZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBRUE7O0FBQ0E7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7O0FBQ0E7O0FBUUE7Ozs7QUFhQTs7QUFFQSxTQUFTQSxhQUFULENBQXVCQyxNQUF2QixFQUEyQztBQUN6Q0EsU0FBT0MsVUFBUDtBQUNBO0FBQ0Q7O0FBRUQsTUFBTUMsa0JBQWtCQyxPQUFPQyxJQUFQLDBCQUErQkMsTUFBL0Isd0JBQXNELEVBQXRELENBQXhCOztBQUdBLFNBQVNDLGNBQVQsQ0FBd0JOLE1BQXhCLEVBQWdDO0FBQzlCLFFBQU1PLE1BQU0sbUNBQXVCTCxlQUF2QixFQUF3Q0YsTUFBeEMsRUFBZ0QsQ0FBaEQsQ0FBWjtBQUNBLE1BQUlPLE1BQU0sQ0FBVixFQUFhO0FBQ1gsV0FBTyw0QkFBb0I7QUFDekJDLGFBQU9SLE9BQU9DLFVBQVAsQ0FBa0JNLEdBQWxCO0FBRGtCLEtBQXBCLENBQVA7QUFHRDtBQUNELFFBQU1FLE1BQU0sb0JBQU4sQ0FBTjtBQUNEOztBQUVELE1BQU1DLG9CQUFvQlAsT0FBT0MsSUFBUCxDQUFZRixlQUFaLEVBQTZCUyxHQUE3QixDQUFpQ0MsTUFBTTtBQUMvREMsT0FBS0QsQ0FEMEQ7QUFFL0RFLFFBQU0sYUFGeUQ7QUFHL0RDLFVBQVFUO0FBSHVELENBQU4sQ0FBakMsQ0FBMUI7O0FBTUEsTUFBTVUsa0JBQWtC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QUFHLENBQ0RDLFFBREMsRUFFRCxHQUFHcUIsZ0JBRkYsRUFHRCxHQUFHVSx5QkFIRixFQUlEUixXQUpDLEVBS0RVLFFBTEMsRUFNRCxHQUFHekIsY0FORixFQU9ENkIsb0JBUEMsRUFRREQscUJBUkMsRUFTRCxHQUFHSSx5QkFURixFQVVESyxPQVZDLENBRG9CLENBQXpCOztrQkFlZUksZ0IiLCJmaWxlIjoiZGVmYXVsdC1yZWFkdGFibGUuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAZmxvd1xuXG5pbXBvcnQgeyBMaXN0IH0gZnJvbSAnaW1tdXRhYmxlJztcbmltcG9ydCB7IGlzRU9TLCBnZXRDdXJyZW50UmVhZHRhYmxlLCBzZXRDdXJyZW50UmVhZHRhYmxlIH0gZnJvbSAncmVhZHRhYmxlJztcbmltcG9ydCByZWFkSWRlbnRpZmllciBmcm9tICcuL3JlYWQtaWRlbnRpZmllcic7XG5pbXBvcnQgcmVhZE51bWVyaWNMaXRlcmFsIGZyb20gJy4vcmVhZC1udW1lcmljJztcbmltcG9ydCByZWFkU3RyaW5nTGl0ZXJhbCBmcm9tICcuL3JlYWQtc3RyaW5nJztcbmltcG9ydCByZWFkVGVtcGxhdGVMaXRlcmFsIGZyb20gJy4vcmVhZC10ZW1wbGF0ZSc7XG5pbXBvcnQgcmVhZFJlZ0V4cCBmcm9tICcuL3JlYWQtcmVnZXhwLmpzJztcbmltcG9ydCByZWFkQ29tbWVudCBmcm9tICcuL3JlYWQtY29tbWVudCc7XG5pbXBvcnQgeyByZWFkU3ludGF4VGVtcGxhdGUgfSBmcm9tICcuL3JlYWQtZGlzcGF0Y2gnO1xuaW1wb3J0IHtcbiAgcHVuY3R1YXRvclRhYmxlIGFzIHB1bmN0dWF0b3JNYXBwaW5nLFxuICBrZXl3b3JkVGFibGUgYXMga2V5d29yZE1hcHBpbmcsXG4gIEtleXdvcmRUb2tlbixcbiAgUHVuY3R1YXRvclRva2VuLFxuICBFbXB0eVRva2VuLFxuICBJZGVudGlmaWVyVG9rZW4sXG59IGZyb20gJy4uL3Rva2Vucyc7XG5pbXBvcnQge1xuICBpbnNlcnRTZXF1ZW5jZSxcbiAgcmV0cmlldmVTZXF1ZW5jZUxlbmd0aCxcbiAgaXNFeHByUHJlZml4LFxuICBpc1JlZ2V4UHJlZml4LFxuICBpc0lkZW50aWZpZXJQYXJ0LFxuICBpc1doaXRlU3BhY2UsXG4gIGlzTGluZVRlcm1pbmF0b3IsXG4gIGlzRGVjaW1hbERpZ2l0LFxufSBmcm9tICcuL3V0aWxzJztcblxuaW1wb3J0IHR5cGUgeyBDaGFyU3RyZWFtIH0gZnJvbSAncmVhZHRhYmxlJztcblxuLy8gdXNlIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXRoaWFzYnluZW5zL3JlZ2VuZXJhdGUgdG8gZ2VuZXJhdGUgdGhlIFVuaWNvZGUgY29kZSBwb2ludHMgd2hlbiBpbXBsZW1lbnRpbmcgbW9kZXNcblxuZnVuY3Rpb24gZWF0V2hpdGVzcGFjZShzdHJlYW06IENoYXJTdHJlYW0pIHtcbiAgc3RyZWFtLnJlYWRTdHJpbmcoKTtcbiAgcmV0dXJuIEVtcHR5VG9rZW47XG59XG5cbmNvbnN0IHB1bmN0dWF0b3JUYWJsZSA9IE9iamVjdC5rZXlzKHB1bmN0dWF0b3JNYXBwaW5nKS5yZWR1Y2UoaW5zZXJ0U2VxdWVuY2UsIHtcbn0pO1xuXG5mdW5jdGlvbiByZWFkUHVuY3R1YXRvcihzdHJlYW0pIHtcbiAgY29uc3QgbGVuID0gcmV0cmlldmVTZXF1ZW5jZUxlbmd0aChwdW5jdHVhdG9yVGFibGUsIHN0cmVhbSwgMCk7XG4gIGlmIChsZW4gPiAwKSB7XG4gICAgcmV0dXJuIG5ldyBQdW5jdHVhdG9yVG9rZW4oe1xuICAgICAgdmFsdWU6IHN0cmVhbS5yZWFkU3RyaW5nKGxlbiksXG4gICAgfSk7XG4gIH1cbiAgdGhyb3cgRXJyb3IoJ1Vua25vd24gcHVuY3R1YXRvcicpO1xufVxuXG5jb25zdCBwdW5jdHVhdG9yRW50cmllcyA9IE9iamVjdC5rZXlzKHB1bmN0dWF0b3JUYWJsZSkubWFwKHAgPT4gKHtcbiAga2V5OiBwLFxuICBtb2RlOiAndGVybWluYXRpbmcnLFxuICBhY3Rpb246IHJlYWRQdW5jdHVhdG9yLFxufSkpO1xuXG5jb25zdCB3aGl0ZVNwYWNlVGFibGUgPSBbXG4gIDB4MjAsXG4gIDB4MDksXG4gIDB4MGIsXG4gIDB4MGMsXG4gIDB4YTAsXG4gIDB4MTY4MCxcbiAgMHgyMDAwLFxuICAweDIwMDEsXG4gIDB4MjAwMixcbiAgMHgyMDAzLFxuICAweDIwMDQsXG4gIDB4MjAwNSxcbiAgMHgyMDA2LFxuICAweDIwMDcsXG4gIDB4MjAwOCxcbiAgMHgyMDA5LFxuICAweDIwMGEsXG4gIDB4MjAyZixcbiAgMHgyMDVmLFxuICAweDMwMDAsXG4gIDB4ZmVmZixcbl07XG5cbmNvbnN0IHdoaXRlU3BhY2VFbnRyaWVzID0gd2hpdGVTcGFjZVRhYmxlLm1hcCh3ID0+ICh7XG4gIGtleTogdyxcbiAgbW9kZTogJ3Rlcm1pbmF0aW5nJyxcbiAgYWN0aW9uOiBlYXRXaGl0ZXNwYWNlLFxufSkpO1xuXG5jb25zdCBsaW5lVGVybWluYXRvclRhYmxlID0gWzB4MGEsIDB4MGQsIDB4MjAyOCwgMHgyMDI5XTtcblxuY29uc3QgbGluZVRlcm1pbmF0b3JFbnRyaWVzID0gbGluZVRlcm1pbmF0b3JUYWJsZS5tYXAobHQgPT4gKHtcbiAga2V5OiBsdCxcbiAgbW9kZTogJ3Rlcm1pbmF0aW5nJyxcbiAgYWN0aW9uOiBmdW5jdGlvbiByZWFkTGluZVRlcm1pbmF0b3Ioc3RyZWFtKSB7XG4gICAgdGhpcy5pbmNyZW1lbnRMaW5lKCk7XG4gICAgcmV0dXJuIGVhdFdoaXRlc3BhY2Uoc3RyZWFtKTtcbiAgfSxcbn0pKTtcblxuY29uc3QgZGlnaXRzID0gWycwJywgJzEnLCAnMicsICczJywgJzQnLCAnNScsICc2JywgJzcnLCAnOCcsICc5J107XG5cbmNvbnN0IG51bWVyaWNFbnRyaWVzID0gZGlnaXRzLm1hcChkID0+ICh7XG4gIGtleTogZCxcbiAgbW9kZTogJ25vbi10ZXJtaW5hdGluZycsXG4gIGFjdGlvbjogcmVhZE51bWVyaWNMaXRlcmFsLFxufSkpO1xuXG5jb25zdCBxdW90ZXMgPSBbJ1xcJycsICdcIiddO1xuXG5jb25zdCBzdHJpbmdFbnRyaWVzID0gcXVvdGVzLm1hcChxID0+ICh7XG4gIGtleTogcSxcbiAgbW9kZTogJ3Rlcm1pbmF0aW5nJyxcbiAgYWN0aW9uOiByZWFkU3RyaW5nTGl0ZXJhbCxcbn0pKTtcblxuY29uc3QgaWRlbnRpZmllckVudHJ5ID0ge1xuICBtb2RlOiAnbm9uLXRlcm1pbmF0aW5nJyxcbiAgYWN0aW9uOiByZWFkSWRlbnRpZmllcixcbn07XG5cbmNvbnN0IHRlbXBsYXRlRW50cnkgPSB7XG4gIGtleTogJ2AnLFxuICBtb2RlOiAndGVybWluYXRpbmcnLFxuICBhY3Rpb246IHJlYWRUZW1wbGF0ZUxpdGVyYWwsXG59O1xuXG5jb25zdCBwcmltaXRpdmVSZWFkdGFibGUgPSBnZXRDdXJyZW50UmVhZHRhYmxlKCkuZXh0ZW5kKFxuICAuLi5bXG4gICAgaWRlbnRpZmllckVudHJ5LFxuICAgIC4uLndoaXRlU3BhY2VFbnRyaWVzLFxuICAgIHRlbXBsYXRlRW50cnksXG4gICAgLi4ucHVuY3R1YXRvckVudHJpZXMsXG4gICAgLi4ubGluZVRlcm1pbmF0b3JFbnRyaWVzLFxuICAgIC4uLm51bWVyaWNFbnRyaWVzLFxuICAgIC4uLnN0cmluZ0VudHJpZXMsXG4gIF0sXG4pO1xuXG5jb25zdCBkb3RFbnRyeSA9IHtcbiAga2V5OiAnLicsXG4gIG1vZGU6ICd0ZXJtaW5hdGluZycsXG4gIGFjdGlvbjogZnVuY3Rpb24gcmVhZERvdChzdHJlYW0sIC4uLnJlc3QpIHtcbiAgICBjb25zdCBueHQgPSBzdHJlYW0ucGVlaygxKS5jaGFyQ29kZUF0KDApO1xuICAgIGlmIChpc0RlY2ltYWxEaWdpdChueHQpKSB7XG4gICAgICByZXR1cm4gcmVhZE51bWVyaWNMaXRlcmFsKHN0cmVhbSwgLi4ucmVzdCk7XG4gICAgfVxuICAgIHJldHVybiByZWFkUHVuY3R1YXRvci5jYWxsKHRoaXMsIHN0cmVhbSk7XG4gIH0sXG59O1xuXG5jb25zdCBrZXl3b3JkVGFibGUgPSBPYmplY3Qua2V5cyhrZXl3b3JkTWFwcGluZykucmVkdWNlKGluc2VydFNlcXVlbmNlLCB7fSk7XG5cbmNvbnN0IGtleXdvcmRFbnRyaWVzID0gT2JqZWN0LmtleXMoa2V5d29yZFRhYmxlKS5tYXAoayA9PiAoe1xuICBrZXk6IGssXG4gIG1vZGU6ICdub24tdGVybWluYXRpbmcnLFxuICBhY3Rpb246IGZ1bmN0aW9uIHJlYWRLZXl3b3JkKHN0cmVhbSkge1xuICAgIGNvbnN0IGxlbiA9IHJldHJpZXZlU2VxdWVuY2VMZW5ndGgoa2V5d29yZFRhYmxlLCBzdHJlYW0sIDApO1xuICAgIGlmIChsZW4gPiAwICYmICFpc0lkZW50aWZpZXJQYXJ0KHN0cmVhbS5wZWVrKGxlbikuY2hhckNvZGVBdCgwKSkpIHtcbiAgICAgIHJldHVybiBuZXcgS2V5d29yZFRva2VuKHtcbiAgICAgICAgdmFsdWU6IHN0cmVhbS5yZWFkU3RyaW5nKGxlbiksXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlYWRJZGVudGlmaWVyLmNhbGwodGhpcywgc3RyZWFtKTtcbiAgfSxcbn0pKTtcblxuY29uc3QgZGVsaW1pdGVyUGFpcnMgPSBbWydbJywgJ10nXSwgWycoJywgJyknXV07XG5cbmZ1bmN0aW9uIHJlYWREZWxpbWl0ZXJzKGNsb3NpbmcsIHN0cmVhbSwgcHJlZml4LCBiKSB7XG4gIGNvbnN0IGN1cnJlbnRSZWFkdGFibGUgPSBnZXRDdXJyZW50UmVhZHRhYmxlKCk7XG4gIHNldEN1cnJlbnRSZWFkdGFibGUocHJpbWl0aXZlUmVhZHRhYmxlKTtcblxuICBsZXQgcmVzdWx0cyA9IExpc3Qub2YodGhpcy5yZWFkVG9rZW4oc3RyZWFtLCBMaXN0KCksIGIpKTtcblxuICBzZXRDdXJyZW50UmVhZHRhYmxlKGN1cnJlbnRSZWFkdGFibGUpO1xuICByZXR1cm4gdGhpcy5yZWFkVW50aWwoY2xvc2luZywgc3RyZWFtLCByZXN1bHRzLCBiKTtcbn1cblxuY29uc3QgZGVsaW1pdGVyRW50cmllcyA9IGRlbGltaXRlclBhaXJzLm1hcChwID0+ICh7XG4gIGtleTogcFswXSxcbiAgbW9kZTogJ3Rlcm1pbmF0aW5nJyxcbiAgYWN0aW9uOiBmdW5jdGlvbiByZWFkRGVmYXVsdERlbGltaXRlcnMoc3RyZWFtLCBwcmVmaXgsIGIpIHtcbiAgICByZXR1cm4gcmVhZERlbGltaXRlcnMuY2FsbCh0aGlzLCBwWzFdLCBzdHJlYW0sIHByZWZpeCwgdHJ1ZSk7XG4gIH0sXG59KSk7XG5cbmNvbnN0IGJyYWNlc0VudHJ5ID0ge1xuICBrZXk6ICd7JyxcbiAgbW9kZTogJ3Rlcm1pbmF0aW5nJyxcbiAgYWN0aW9uOiBmdW5jdGlvbiByZWFkQnJhY2VzKHN0cmVhbSwgcHJlZml4LCBiKSB7XG4gICAgY29uc3QgbGluZSA9IHRoaXMubG9jYXRpb25JbmZvLmxpbmU7XG4gICAgY29uc3QgaW5uZXJCID0gaXNFeHByUHJlZml4KGxpbmUsIGIsIHByZWZpeCk7XG4gICAgcmV0dXJuIHJlYWREZWxpbWl0ZXJzLmNhbGwodGhpcywgJ30nLCBzdHJlYW0sIHByZWZpeCwgaW5uZXJCKTtcbiAgfSxcbn07XG5cbmZ1bmN0aW9uIHJlYWRDbG9zaW5nRGVsaW1pdGVyKG9wZW5pbmcsIGNsb3NpbmcsIHN0cmVhbSwgcHJlZml4LCBiKSB7XG4gIGlmIChwcmVmaXguZmlyc3QoKS52YWx1ZSAhPT0gb3BlbmluZykge1xuICAgIHRocm93IEVycm9yKCdVbm1hdGNoZWQgZGVsaW1pdGVyOicsIGNsb3NpbmcpO1xuICB9XG4gIHJldHVybiByZWFkUHVuY3R1YXRvci5jYWxsKHRoaXMsIHN0cmVhbSk7XG59XG5cbmNvbnN0IHVubWF0Y2hlZERlbGltaXRlckVudHJpZXMgPSBbXG4gIFsneycsICd9J10sXG4gIFsnWycsICddJ10sXG4gIFsnKCcsICcpJ10sXG5dLm1hcChwID0+ICh7XG4gIGtleTogcFsxXSxcbiAgbW9kZTogJ3Rlcm1pbmF0aW5nJyxcbiAgYWN0aW9uOiBmdW5jdGlvbiByZWFkQ2xvc2luZ0RlbGltaXRlcnMoc3RyZWFtLCBwcmVmaXgsIGIpIHtcbiAgICByZXR1cm4gcmVhZENsb3NpbmdEZWxpbWl0ZXIuY2FsbCh0aGlzLCAuLi5wLCBzdHJlYW0sIHByZWZpeCwgYik7XG4gIH0sXG59KSk7XG5cbmNvbnN0IGRpdkVudHJ5ID0ge1xuICBrZXk6ICcvJyxcbiAgbW9kZTogJ3Rlcm1pbmF0aW5nJyxcbiAgYWN0aW9uOiBmdW5jdGlvbiByZWFkRGl2KHN0cmVhbSwgcHJlZml4LCBiKSB7XG4gICAgbGV0IG54dCA9IHN0cmVhbS5wZWVrKDEpO1xuICAgIGlmIChueHQgPT09ICcvJyB8fCBueHQgPT09ICcqJykge1xuICAgICAgY29uc3QgcmVzdWx0ID0gcmVhZENvbW1lbnQuY2FsbCh0aGlzLCBzdHJlYW0pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgaWYgKGlzUmVnZXhQcmVmaXgoYiwgcHJlZml4KSkge1xuICAgICAgcmV0dXJuIHJlYWRSZWdFeHAuY2FsbCh0aGlzLCBzdHJlYW0sIHByZWZpeCwgYik7XG4gICAgfVxuICAgIHJldHVybiByZWFkUHVuY3R1YXRvci5jYWxsKHRoaXMsIHN0cmVhbSk7XG4gIH0sXG59O1xuXG5jb25zdCBkaXNwYXRjaEJhY2t0aWNrRW50cnkgPSB7XG4gIGtleTogJ2AnLFxuICBtb2RlOiAnZGlzcGF0Y2gnLFxuICBhY3Rpb246IHJlYWRTeW50YXhUZW1wbGF0ZSxcbn07XG5cbmNvbnN0IGRlZmF1bHREaXNwYXRjaEVudHJ5ID0ge1xuICBtb2RlOiAnZGlzcGF0Y2gnLFxuICBhY3Rpb246IGZ1bmN0aW9uIHJlYWREZWZhdWx0RGlzcGF0Y2goLi4uYXJncykge1xuICAgIHRoaXMucmVhZFRva2VuKC4uLmFyZ3MpO1xuICAgIHJldHVybiBFbXB0eVRva2VuO1xuICB9LFxufTtcblxuY29uc3QgZGlzcGF0Y2hXaGl0ZVNwYWNlRW50cmllcyA9IHdoaXRlU3BhY2VUYWJsZVxuICAuY29uY2F0KGxpbmVUZXJtaW5hdG9yVGFibGUpXG4gIC5tYXAodyA9PiAoe1xuICAgIGtleTogdyxcbiAgICBtb2RlOiAnZGlzcGF0Y2gnLFxuICAgIGFjdGlvbjogZnVuY3Rpb24gcmVhZERpc3BhdGNoV2hpdGVzcGFjZShcbiAgICAgIHN0cmVhbSxcbiAgICAgIHByZWZpeCxcbiAgICAgIGFsbG93RXhwcnMsXG4gICAgICBkaXNwYXRjaEtleSxcbiAgICApIHtcbiAgICAgIHRoaXMucmVhZFRva2VuKHN0cmVhbSwgcHJlZml4LCBhbGxvd0V4cHJzKTtcbiAgICAgIHJldHVybiBuZXcgSWRlbnRpZmllclRva2VuKHsgdmFsdWU6IGRpc3BhdGNoS2V5IH0pO1xuICAgIH0sXG4gIH0pKTtcblxuY29uc3QgYXRFbnRyeSA9IHtcbiAga2V5OiAnQCcsXG4gIG1vZGU6ICd0ZXJtaW5hdGluZycsXG4gIGFjdGlvbjogZnVuY3Rpb24gcmVhZEF0KHN0cmVhbSwgcHJlZml4KSB7XG4gICAgY29uc3Qgbnh0ID0gc3RyZWFtLnBlZWsoMSksIG54dENvZGUgPSBueHQuY2hhckNvZGVBdCgwKTtcbiAgICBpZiAoaXNFT1Mobnh0KSB8fCBpc1doaXRlU3BhY2Uobnh0Q29kZSkgfHwgaXNMaW5lVGVybWluYXRvcihueHRDb2RlKSkge1xuICAgICAgcmV0dXJuIG5ldyBJZGVudGlmaWVyVG9rZW4oeyB2YWx1ZTogc3RyZWFtLnJlYWRTdHJpbmcoKSB9KTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCdJbnZhbGlkIG9yIHVuZXhwZWN0ZWQgdG9rZW4nKTtcbiAgfSxcbn07XG5cbmNvbnN0IGRlZmF1bHRSZWFkdGFibGUgPSBwcmltaXRpdmVSZWFkdGFibGUuZXh0ZW5kKFxuICAuLi5bXG4gICAgZG90RW50cnksXG4gICAgLi4uZGVsaW1pdGVyRW50cmllcyxcbiAgICAuLi51bm1hdGNoZWREZWxpbWl0ZXJFbnRyaWVzLFxuICAgIGJyYWNlc0VudHJ5LFxuICAgIGRpdkVudHJ5LFxuICAgIC4uLmtleXdvcmRFbnRyaWVzLFxuICAgIGRlZmF1bHREaXNwYXRjaEVudHJ5LFxuICAgIGRpc3BhdGNoQmFja3RpY2tFbnRyeSxcbiAgICAuLi5kaXNwYXRjaFdoaXRlU3BhY2VFbnRyaWVzLFxuICAgIGF0RW50cnksXG4gIF0sXG4pO1xuXG5leHBvcnQgZGVmYXVsdCBkZWZhdWx0UmVhZHRhYmxlO1xuIl19\n\n/***/ },\n/* 12 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/**\n\t *  Copyright (c) 2014-2015, Facebook, Inc.\n\t *  All rights reserved.\n\t *\n\t *  This source code is licensed under the BSD-style license found in the\n\t *  LICENSE file in the root directory of this source tree. An additional grant\n\t *  of patent rights can be found in the PATENTS file in the same directory.\n\t */\n\n\t(function (global, factory) {\n\t   true ? module.exports = factory() :\n\t  typeof define === 'function' && define.amd ? define(factory) :\n\t  (global.Immutable = factory());\n\t}(this, function () { 'use strict';var SLICE$0 = Array.prototype.slice;\n\n\t  function createClass(ctor, superClass) {\n\t    if (superClass) {\n\t      ctor.prototype = Object.create(superClass.prototype);\n\t    }\n\t    ctor.prototype.constructor = ctor;\n\t  }\n\n\t  function Iterable(value) {\n\t      return isIterable(value) ? value : Seq(value);\n\t    }\n\n\n\t  createClass(KeyedIterable, Iterable);\n\t    function KeyedIterable(value) {\n\t      return isKeyed(value) ? value : KeyedSeq(value);\n\t    }\n\n\n\t  createClass(IndexedIterable, Iterable);\n\t    function IndexedIterable(value) {\n\t      return isIndexed(value) ? value : IndexedSeq(value);\n\t    }\n\n\n\t  createClass(SetIterable, Iterable);\n\t    function SetIterable(value) {\n\t      return isIterable(value) && !isAssociative(value) ? value : SetSeq(value);\n\t    }\n\n\n\n\t  function isIterable(maybeIterable) {\n\t    return !!(maybeIterable && maybeIterable[IS_ITERABLE_SENTINEL]);\n\t  }\n\n\t  function isKeyed(maybeKeyed) {\n\t    return !!(maybeKeyed && maybeKeyed[IS_KEYED_SENTINEL]);\n\t  }\n\n\t  function isIndexed(maybeIndexed) {\n\t    return !!(maybeIndexed && maybeIndexed[IS_INDEXED_SENTINEL]);\n\t  }\n\n\t  function isAssociative(maybeAssociative) {\n\t    return isKeyed(maybeAssociative) || isIndexed(maybeAssociative);\n\t  }\n\n\t  function isOrdered(maybeOrdered) {\n\t    return !!(maybeOrdered && maybeOrdered[IS_ORDERED_SENTINEL]);\n\t  }\n\n\t  Iterable.isIterable = isIterable;\n\t  Iterable.isKeyed = isKeyed;\n\t  Iterable.isIndexed = isIndexed;\n\t  Iterable.isAssociative = isAssociative;\n\t  Iterable.isOrdered = isOrdered;\n\n\t  Iterable.Keyed = KeyedIterable;\n\t  Iterable.Indexed = IndexedIterable;\n\t  Iterable.Set = SetIterable;\n\n\n\t  var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@';\n\t  var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@';\n\t  var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@';\n\t  var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@';\n\n\t  // Used for setting prototype methods that IE8 chokes on.\n\t  var DELETE = 'delete';\n\n\t  // Constants describing the size of trie nodes.\n\t  var SHIFT = 5; // Resulted in best performance after ______?\n\t  var SIZE = 1 << SHIFT;\n\t  var MASK = SIZE - 1;\n\n\t  // A consistent shared value representing \"not set\" which equals nothing other\n\t  // than itself, and nothing that could be provided externally.\n\t  var NOT_SET = {};\n\n\t  // Boolean references, Rough equivalent of `bool &`.\n\t  var CHANGE_LENGTH = { value: false };\n\t  var DID_ALTER = { value: false };\n\n\t  function MakeRef(ref) {\n\t    ref.value = false;\n\t    return ref;\n\t  }\n\n\t  function SetRef(ref) {\n\t    ref && (ref.value = true);\n\t  }\n\n\t  // A function which returns a value representing an \"owner\" for transient writes\n\t  // to tries. The return value will only ever equal itself, and will not equal\n\t  // the return of any subsequent call of this function.\n\t  function OwnerID() {}\n\n\t  // http://jsperf.com/copy-array-inline\n\t  function arrCopy(arr, offset) {\n\t    offset = offset || 0;\n\t    var len = Math.max(0, arr.length - offset);\n\t    var newArr = new Array(len);\n\t    for (var ii = 0; ii < len; ii++) {\n\t      newArr[ii] = arr[ii + offset];\n\t    }\n\t    return newArr;\n\t  }\n\n\t  function ensureSize(iter) {\n\t    if (iter.size === undefined) {\n\t      iter.size = iter.__iterate(returnTrue);\n\t    }\n\t    return iter.size;\n\t  }\n\n\t  function wrapIndex(iter, index) {\n\t    // This implements \"is array index\" which the ECMAString spec defines as:\n\t    //\n\t    //     A String property name P is an array index if and only if\n\t    //     ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal\n\t    //     to 2^32−1.\n\t    //\n\t    // http://www.ecma-international.org/ecma-262/6.0/#sec-array-exotic-objects\n\t    if (typeof index !== 'number') {\n\t      var uint32Index = index >>> 0; // N >>> 0 is shorthand for ToUint32\n\t      if ('' + uint32Index !== index || uint32Index === 4294967295) {\n\t        return NaN;\n\t      }\n\t      index = uint32Index;\n\t    }\n\t    return index < 0 ? ensureSize(iter) + index : index;\n\t  }\n\n\t  function returnTrue() {\n\t    return true;\n\t  }\n\n\t  function wholeSlice(begin, end, size) {\n\t    return (begin === 0 || (size !== undefined && begin <= -size)) &&\n\t      (end === undefined || (size !== undefined && end >= size));\n\t  }\n\n\t  function resolveBegin(begin, size) {\n\t    return resolveIndex(begin, size, 0);\n\t  }\n\n\t  function resolveEnd(end, size) {\n\t    return resolveIndex(end, size, size);\n\t  }\n\n\t  function resolveIndex(index, size, defaultIndex) {\n\t    return index === undefined ?\n\t      defaultIndex :\n\t      index < 0 ?\n\t        Math.max(0, size + index) :\n\t        size === undefined ?\n\t          index :\n\t          Math.min(size, index);\n\t  }\n\n\t  /* global Symbol */\n\n\t  var ITERATE_KEYS = 0;\n\t  var ITERATE_VALUES = 1;\n\t  var ITERATE_ENTRIES = 2;\n\n\t  var REAL_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;\n\t  var FAUX_ITERATOR_SYMBOL = '@@iterator';\n\n\t  var ITERATOR_SYMBOL = REAL_ITERATOR_SYMBOL || FAUX_ITERATOR_SYMBOL;\n\n\n\t  function Iterator(next) {\n\t      this.next = next;\n\t    }\n\n\t    Iterator.prototype.toString = function() {\n\t      return '[Iterator]';\n\t    };\n\n\n\t  Iterator.KEYS = ITERATE_KEYS;\n\t  Iterator.VALUES = ITERATE_VALUES;\n\t  Iterator.ENTRIES = ITERATE_ENTRIES;\n\n\t  Iterator.prototype.inspect =\n\t  Iterator.prototype.toSource = function () { return this.toString(); }\n\t  Iterator.prototype[ITERATOR_SYMBOL] = function () {\n\t    return this;\n\t  };\n\n\n\t  function iteratorValue(type, k, v, iteratorResult) {\n\t    var value = type === 0 ? k : type === 1 ? v : [k, v];\n\t    iteratorResult ? (iteratorResult.value = value) : (iteratorResult = {\n\t      value: value, done: false\n\t    });\n\t    return iteratorResult;\n\t  }\n\n\t  function iteratorDone() {\n\t    return { value: undefined, done: true };\n\t  }\n\n\t  function hasIterator(maybeIterable) {\n\t    return !!getIteratorFn(maybeIterable);\n\t  }\n\n\t  function isIterator(maybeIterator) {\n\t    return maybeIterator && typeof maybeIterator.next === 'function';\n\t  }\n\n\t  function getIterator(iterable) {\n\t    var iteratorFn = getIteratorFn(iterable);\n\t    return iteratorFn && iteratorFn.call(iterable);\n\t  }\n\n\t  function getIteratorFn(iterable) {\n\t    var iteratorFn = iterable && (\n\t      (REAL_ITERATOR_SYMBOL && iterable[REAL_ITERATOR_SYMBOL]) ||\n\t      iterable[FAUX_ITERATOR_SYMBOL]\n\t    );\n\t    if (typeof iteratorFn === 'function') {\n\t      return iteratorFn;\n\t    }\n\t  }\n\n\t  function isArrayLike(value) {\n\t    return value && typeof value.length === 'number';\n\t  }\n\n\t  createClass(Seq, Iterable);\n\t    function Seq(value) {\n\t      return value === null || value === undefined ? emptySequence() :\n\t        isIterable(value) ? value.toSeq() : seqFromValue(value);\n\t    }\n\n\t    Seq.of = function(/*...values*/) {\n\t      return Seq(arguments);\n\t    };\n\n\t    Seq.prototype.toSeq = function() {\n\t      return this;\n\t    };\n\n\t    Seq.prototype.toString = function() {\n\t      return this.__toString('Seq {', '}');\n\t    };\n\n\t    Seq.prototype.cacheResult = function() {\n\t      if (!this._cache && this.__iterateUncached) {\n\t        this._cache = this.entrySeq().toArray();\n\t        this.size = this._cache.length;\n\t      }\n\t      return this;\n\t    };\n\n\t    // abstract __iterateUncached(fn, reverse)\n\n\t    Seq.prototype.__iterate = function(fn, reverse) {\n\t      return seqIterate(this, fn, reverse, true);\n\t    };\n\n\t    // abstract __iteratorUncached(type, reverse)\n\n\t    Seq.prototype.__iterator = function(type, reverse) {\n\t      return seqIterator(this, type, reverse, true);\n\t    };\n\n\n\n\t  createClass(KeyedSeq, Seq);\n\t    function KeyedSeq(value) {\n\t      return value === null || value === undefined ?\n\t        emptySequence().toKeyedSeq() :\n\t        isIterable(value) ?\n\t          (isKeyed(value) ? value.toSeq() : value.fromEntrySeq()) :\n\t          keyedSeqFromValue(value);\n\t    }\n\n\t    KeyedSeq.prototype.toKeyedSeq = function() {\n\t      return this;\n\t    };\n\n\n\n\t  createClass(IndexedSeq, Seq);\n\t    function IndexedSeq(value) {\n\t      return value === null || value === undefined ? emptySequence() :\n\t        !isIterable(value) ? indexedSeqFromValue(value) :\n\t        isKeyed(value) ? value.entrySeq() : value.toIndexedSeq();\n\t    }\n\n\t    IndexedSeq.of = function(/*...values*/) {\n\t      return IndexedSeq(arguments);\n\t    };\n\n\t    IndexedSeq.prototype.toIndexedSeq = function() {\n\t      return this;\n\t    };\n\n\t    IndexedSeq.prototype.toString = function() {\n\t      return this.__toString('Seq [', ']');\n\t    };\n\n\t    IndexedSeq.prototype.__iterate = function(fn, reverse) {\n\t      return seqIterate(this, fn, reverse, false);\n\t    };\n\n\t    IndexedSeq.prototype.__iterator = function(type, reverse) {\n\t      return seqIterator(this, type, reverse, false);\n\t    };\n\n\n\n\t  createClass(SetSeq, Seq);\n\t    function SetSeq(value) {\n\t      return (\n\t        value === null || value === undefined ? emptySequence() :\n\t        !isIterable(value) ? indexedSeqFromValue(value) :\n\t        isKeyed(value) ? value.entrySeq() : value\n\t      ).toSetSeq();\n\t    }\n\n\t    SetSeq.of = function(/*...values*/) {\n\t      return SetSeq(arguments);\n\t    };\n\n\t    SetSeq.prototype.toSetSeq = function() {\n\t      return this;\n\t    };\n\n\n\n\t  Seq.isSeq = isSeq;\n\t  Seq.Keyed = KeyedSeq;\n\t  Seq.Set = SetSeq;\n\t  Seq.Indexed = IndexedSeq;\n\n\t  var IS_SEQ_SENTINEL = '@@__IMMUTABLE_SEQ__@@';\n\n\t  Seq.prototype[IS_SEQ_SENTINEL] = true;\n\n\n\n\t  createClass(ArraySeq, IndexedSeq);\n\t    function ArraySeq(array) {\n\t      this._array = array;\n\t      this.size = array.length;\n\t    }\n\n\t    ArraySeq.prototype.get = function(index, notSetValue) {\n\t      return this.has(index) ? this._array[wrapIndex(this, index)] : notSetValue;\n\t    };\n\n\t    ArraySeq.prototype.__iterate = function(fn, reverse) {\n\t      var array = this._array;\n\t      var maxIndex = array.length - 1;\n\t      for (var ii = 0; ii <= maxIndex; ii++) {\n\t        if (fn(array[reverse ? maxIndex - ii : ii], ii, this) === false) {\n\t          return ii + 1;\n\t        }\n\t      }\n\t      return ii;\n\t    };\n\n\t    ArraySeq.prototype.__iterator = function(type, reverse) {\n\t      var array = this._array;\n\t      var maxIndex = array.length - 1;\n\t      var ii = 0;\n\t      return new Iterator(function() \n\t        {return ii > maxIndex ?\n\t          iteratorDone() :\n\t          iteratorValue(type, ii, array[reverse ? maxIndex - ii++ : ii++])}\n\t      );\n\t    };\n\n\n\n\t  createClass(ObjectSeq, KeyedSeq);\n\t    function ObjectSeq(object) {\n\t      var keys = Object.keys(object);\n\t      this._object = object;\n\t      this._keys = keys;\n\t      this.size = keys.length;\n\t    }\n\n\t    ObjectSeq.prototype.get = function(key, notSetValue) {\n\t      if (notSetValue !== undefined && !this.has(key)) {\n\t        return notSetValue;\n\t      }\n\t      return this._object[key];\n\t    };\n\n\t    ObjectSeq.prototype.has = function(key) {\n\t      return this._object.hasOwnProperty(key);\n\t    };\n\n\t    ObjectSeq.prototype.__iterate = function(fn, reverse) {\n\t      var object = this._object;\n\t      var keys = this._keys;\n\t      var maxIndex = keys.length - 1;\n\t      for (var ii = 0; ii <= maxIndex; ii++) {\n\t        var key = keys[reverse ? maxIndex - ii : ii];\n\t        if (fn(object[key], key, this) === false) {\n\t          return ii + 1;\n\t        }\n\t      }\n\t      return ii;\n\t    };\n\n\t    ObjectSeq.prototype.__iterator = function(type, reverse) {\n\t      var object = this._object;\n\t      var keys = this._keys;\n\t      var maxIndex = keys.length - 1;\n\t      var ii = 0;\n\t      return new Iterator(function()  {\n\t        var key = keys[reverse ? maxIndex - ii : ii];\n\t        return ii++ > maxIndex ?\n\t          iteratorDone() :\n\t          iteratorValue(type, key, object[key]);\n\t      });\n\t    };\n\n\t  ObjectSeq.prototype[IS_ORDERED_SENTINEL] = true;\n\n\n\t  createClass(IterableSeq, IndexedSeq);\n\t    function IterableSeq(iterable) {\n\t      this._iterable = iterable;\n\t      this.size = iterable.length || iterable.size;\n\t    }\n\n\t    IterableSeq.prototype.__iterateUncached = function(fn, reverse) {\n\t      if (reverse) {\n\t        return this.cacheResult().__iterate(fn, reverse);\n\t      }\n\t      var iterable = this._iterable;\n\t      var iterator = getIterator(iterable);\n\t      var iterations = 0;\n\t      if (isIterator(iterator)) {\n\t        var step;\n\t        while (!(step = iterator.next()).done) {\n\t          if (fn(step.value, iterations++, this) === false) {\n\t            break;\n\t          }\n\t        }\n\t      }\n\t      return iterations;\n\t    };\n\n\t    IterableSeq.prototype.__iteratorUncached = function(type, reverse) {\n\t      if (reverse) {\n\t        return this.cacheResult().__iterator(type, reverse);\n\t      }\n\t      var iterable = this._iterable;\n\t      var iterator = getIterator(iterable);\n\t      if (!isIterator(iterator)) {\n\t        return new Iterator(iteratorDone);\n\t      }\n\t      var iterations = 0;\n\t      return new Iterator(function()  {\n\t        var step = iterator.next();\n\t        return step.done ? step : iteratorValue(type, iterations++, step.value);\n\t      });\n\t    };\n\n\n\n\t  createClass(IteratorSeq, IndexedSeq);\n\t    function IteratorSeq(iterator) {\n\t      this._iterator = iterator;\n\t      this._iteratorCache = [];\n\t    }\n\n\t    IteratorSeq.prototype.__iterateUncached = function(fn, reverse) {\n\t      if (reverse) {\n\t        return this.cacheResult().__iterate(fn, reverse);\n\t      }\n\t      var iterator = this._iterator;\n\t      var cache = this._iteratorCache;\n\t      var iterations = 0;\n\t      while (iterations < cache.length) {\n\t        if (fn(cache[iterations], iterations++, this) === false) {\n\t          return iterations;\n\t        }\n\t      }\n\t      var step;\n\t      while (!(step = iterator.next()).done) {\n\t        var val = step.value;\n\t        cache[iterations] = val;\n\t        if (fn(val, iterations++, this) === false) {\n\t          break;\n\t        }\n\t      }\n\t      return iterations;\n\t    };\n\n\t    IteratorSeq.prototype.__iteratorUncached = function(type, reverse) {\n\t      if (reverse) {\n\t        return this.cacheResult().__iterator(type, reverse);\n\t      }\n\t      var iterator = this._iterator;\n\t      var cache = this._iteratorCache;\n\t      var iterations = 0;\n\t      return new Iterator(function()  {\n\t        if (iterations >= cache.length) {\n\t          var step = iterator.next();\n\t          if (step.done) {\n\t            return step;\n\t          }\n\t          cache[iterations] = step.value;\n\t        }\n\t        return iteratorValue(type, iterations, cache[iterations++]);\n\t      });\n\t    };\n\n\n\n\n\t  // # pragma Helper functions\n\n\t  function isSeq(maybeSeq) {\n\t    return !!(maybeSeq && maybeSeq[IS_SEQ_SENTINEL]);\n\t  }\n\n\t  var EMPTY_SEQ;\n\n\t  function emptySequence() {\n\t    return EMPTY_SEQ || (EMPTY_SEQ = new ArraySeq([]));\n\t  }\n\n\t  function keyedSeqFromValue(value) {\n\t    var seq =\n\t      Array.isArray(value) ? new ArraySeq(value).fromEntrySeq() :\n\t      isIterator(value) ? new IteratorSeq(value).fromEntrySeq() :\n\t      hasIterator(value) ? new IterableSeq(value).fromEntrySeq() :\n\t      typeof value === 'object' ? new ObjectSeq(value) :\n\t      undefined;\n\t    if (!seq) {\n\t      throw new TypeError(\n\t        'Expected Array or iterable object of [k, v] entries, '+\n\t        'or keyed object: ' + value\n\t      );\n\t    }\n\t    return seq;\n\t  }\n\n\t  function indexedSeqFromValue(value) {\n\t    var seq = maybeIndexedSeqFromValue(value);\n\t    if (!seq) {\n\t      throw new TypeError(\n\t        'Expected Array or iterable object of values: ' + value\n\t      );\n\t    }\n\t    return seq;\n\t  }\n\n\t  function seqFromValue(value) {\n\t    var seq = maybeIndexedSeqFromValue(value) ||\n\t      (typeof value === 'object' && new ObjectSeq(value));\n\t    if (!seq) {\n\t      throw new TypeError(\n\t        'Expected Array or iterable object of values, or keyed object: ' + value\n\t      );\n\t    }\n\t    return seq;\n\t  }\n\n\t  function maybeIndexedSeqFromValue(value) {\n\t    return (\n\t      isArrayLike(value) ? new ArraySeq(value) :\n\t      isIterator(value) ? new IteratorSeq(value) :\n\t      hasIterator(value) ? new IterableSeq(value) :\n\t      undefined\n\t    );\n\t  }\n\n\t  function seqIterate(seq, fn, reverse, useKeys) {\n\t    var cache = seq._cache;\n\t    if (cache) {\n\t      var maxIndex = cache.length - 1;\n\t      for (var ii = 0; ii <= maxIndex; ii++) {\n\t        var entry = cache[reverse ? maxIndex - ii : ii];\n\t        if (fn(entry[1], useKeys ? entry[0] : ii, seq) === false) {\n\t          return ii + 1;\n\t        }\n\t      }\n\t      return ii;\n\t    }\n\t    return seq.__iterateUncached(fn, reverse);\n\t  }\n\n\t  function seqIterator(seq, type, reverse, useKeys) {\n\t    var cache = seq._cache;\n\t    if (cache) {\n\t      var maxIndex = cache.length - 1;\n\t      var ii = 0;\n\t      return new Iterator(function()  {\n\t        var entry = cache[reverse ? maxIndex - ii : ii];\n\t        return ii++ > maxIndex ?\n\t          iteratorDone() :\n\t          iteratorValue(type, useKeys ? entry[0] : ii - 1, entry[1]);\n\t      });\n\t    }\n\t    return seq.__iteratorUncached(type, reverse);\n\t  }\n\n\t  function fromJS(json, converter) {\n\t    return converter ?\n\t      fromJSWith(converter, json, '', {'': json}) :\n\t      fromJSDefault(json);\n\t  }\n\n\t  function fromJSWith(converter, json, key, parentJSON) {\n\t    if (Array.isArray(json)) {\n\t      return converter.call(parentJSON, key, IndexedSeq(json).map(function(v, k)  {return fromJSWith(converter, v, k, json)}));\n\t    }\n\t    if (isPlainObj(json)) {\n\t      return converter.call(parentJSON, key, KeyedSeq(json).map(function(v, k)  {return fromJSWith(converter, v, k, json)}));\n\t    }\n\t    return json;\n\t  }\n\n\t  function fromJSDefault(json) {\n\t    if (Array.isArray(json)) {\n\t      return IndexedSeq(json).map(fromJSDefault).toList();\n\t    }\n\t    if (isPlainObj(json)) {\n\t      return KeyedSeq(json).map(fromJSDefault).toMap();\n\t    }\n\t    return json;\n\t  }\n\n\t  function isPlainObj(value) {\n\t    return value && (value.constructor === Object || value.constructor === undefined);\n\t  }\n\n\t  /**\n\t   * An extension of the \"same-value\" algorithm as [described for use by ES6 Map\n\t   * and Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Key_equality)\n\t   *\n\t   * NaN is considered the same as NaN, however -0 and 0 are considered the same\n\t   * value, which is different from the algorithm described by\n\t   * [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is).\n\t   *\n\t   * This is extended further to allow Objects to describe the values they\n\t   * represent, by way of `valueOf` or `equals` (and `hashCode`).\n\t   *\n\t   * Note: because of this extension, the key equality of Immutable.Map and the\n\t   * value equality of Immutable.Set will differ from ES6 Map and Set.\n\t   *\n\t   * ### Defining custom values\n\t   *\n\t   * The easiest way to describe the value an object represents is by implementing\n\t   * `valueOf`. For example, `Date` represents a value by returning a unix\n\t   * timestamp for `valueOf`:\n\t   *\n\t   *     var date1 = new Date(1234567890000); // Fri Feb 13 2009 ...\n\t   *     var date2 = new Date(1234567890000);\n\t   *     date1.valueOf(); // 1234567890000\n\t   *     assert( date1 !== date2 );\n\t   *     assert( Immutable.is( date1, date2 ) );\n\t   *\n\t   * Note: overriding `valueOf` may have other implications if you use this object\n\t   * where JavaScript expects a primitive, such as implicit string coercion.\n\t   *\n\t   * For more complex types, especially collections, implementing `valueOf` may\n\t   * not be performant. An alternative is to implement `equals` and `hashCode`.\n\t   *\n\t   * `equals` takes another object, presumably of similar type, and returns true\n\t   * if the it is equal. Equality is symmetrical, so the same result should be\n\t   * returned if this and the argument are flipped.\n\t   *\n\t   *     assert( a.equals(b) === b.equals(a) );\n\t   *\n\t   * `hashCode` returns a 32bit integer number representing the object which will\n\t   * be used to determine how to store the value object in a Map or Set. You must\n\t   * provide both or neither methods, one must not exist without the other.\n\t   *\n\t   * Also, an important relationship between these methods must be upheld: if two\n\t   * values are equal, they *must* return the same hashCode. If the values are not\n\t   * equal, they might have the same hashCode; this is called a hash collision,\n\t   * and while undesirable for performance reasons, it is acceptable.\n\t   *\n\t   *     if (a.equals(b)) {\n\t   *       assert( a.hashCode() === b.hashCode() );\n\t   *     }\n\t   *\n\t   * All Immutable collections implement `equals` and `hashCode`.\n\t   *\n\t   */\n\t  function is(valueA, valueB) {\n\t    if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) {\n\t      return true;\n\t    }\n\t    if (!valueA || !valueB) {\n\t      return false;\n\t    }\n\t    if (typeof valueA.valueOf === 'function' &&\n\t        typeof valueB.valueOf === 'function') {\n\t      valueA = valueA.valueOf();\n\t      valueB = valueB.valueOf();\n\t      if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) {\n\t        return true;\n\t      }\n\t      if (!valueA || !valueB) {\n\t        return false;\n\t      }\n\t    }\n\t    if (typeof valueA.equals === 'function' &&\n\t        typeof valueB.equals === 'function' &&\n\t        valueA.equals(valueB)) {\n\t      return true;\n\t    }\n\t    return false;\n\t  }\n\n\t  function deepEqual(a, b) {\n\t    if (a === b) {\n\t      return true;\n\t    }\n\n\t    if (\n\t      !isIterable(b) ||\n\t      a.size !== undefined && b.size !== undefined && a.size !== b.size ||\n\t      a.__hash !== undefined && b.__hash !== undefined && a.__hash !== b.__hash ||\n\t      isKeyed(a) !== isKeyed(b) ||\n\t      isIndexed(a) !== isIndexed(b) ||\n\t      isOrdered(a) !== isOrdered(b)\n\t    ) {\n\t      return false;\n\t    }\n\n\t    if (a.size === 0 && b.size === 0) {\n\t      return true;\n\t    }\n\n\t    var notAssociative = !isAssociative(a);\n\n\t    if (isOrdered(a)) {\n\t      var entries = a.entries();\n\t      return b.every(function(v, k)  {\n\t        var entry = entries.next().value;\n\t        return entry && is(entry[1], v) && (notAssociative || is(entry[0], k));\n\t      }) && entries.next().done;\n\t    }\n\n\t    var flipped = false;\n\n\t    if (a.size === undefined) {\n\t      if (b.size === undefined) {\n\t        if (typeof a.cacheResult === 'function') {\n\t          a.cacheResult();\n\t        }\n\t      } else {\n\t        flipped = true;\n\t        var _ = a;\n\t        a = b;\n\t        b = _;\n\t      }\n\t    }\n\n\t    var allEqual = true;\n\t    var bSize = b.__iterate(function(v, k)  {\n\t      if (notAssociative ? !a.has(v) :\n\t          flipped ? !is(v, a.get(k, NOT_SET)) : !is(a.get(k, NOT_SET), v)) {\n\t        allEqual = false;\n\t        return false;\n\t      }\n\t    });\n\n\t    return allEqual && a.size === bSize;\n\t  }\n\n\t  createClass(Repeat, IndexedSeq);\n\n\t    function Repeat(value, times) {\n\t      if (!(this instanceof Repeat)) {\n\t        return new Repeat(value, times);\n\t      }\n\t      this._value = value;\n\t      this.size = times === undefined ? Infinity : Math.max(0, times);\n\t      if (this.size === 0) {\n\t        if (EMPTY_REPEAT) {\n\t          return EMPTY_REPEAT;\n\t        }\n\t        EMPTY_REPEAT = this;\n\t      }\n\t    }\n\n\t    Repeat.prototype.toString = function() {\n\t      if (this.size === 0) {\n\t        return 'Repeat []';\n\t      }\n\t      return 'Repeat [ ' + this._value + ' ' + this.size + ' times ]';\n\t    };\n\n\t    Repeat.prototype.get = function(index, notSetValue) {\n\t      return this.has(index) ? this._value : notSetValue;\n\t    };\n\n\t    Repeat.prototype.includes = function(searchValue) {\n\t      return is(this._value, searchValue);\n\t    };\n\n\t    Repeat.prototype.slice = function(begin, end) {\n\t      var size = this.size;\n\t      return wholeSlice(begin, end, size) ? this :\n\t        new Repeat(this._value, resolveEnd(end, size) - resolveBegin(begin, size));\n\t    };\n\n\t    Repeat.prototype.reverse = function() {\n\t      return this;\n\t    };\n\n\t    Repeat.prototype.indexOf = function(searchValue) {\n\t      if (is(this._value, searchValue)) {\n\t        return 0;\n\t      }\n\t      return -1;\n\t    };\n\n\t    Repeat.prototype.lastIndexOf = function(searchValue) {\n\t      if (is(this._value, searchValue)) {\n\t        return this.size;\n\t      }\n\t      return -1;\n\t    };\n\n\t    Repeat.prototype.__iterate = function(fn, reverse) {\n\t      for (var ii = 0; ii < this.size; ii++) {\n\t        if (fn(this._value, ii, this) === false) {\n\t          return ii + 1;\n\t        }\n\t      }\n\t      return ii;\n\t    };\n\n\t    Repeat.prototype.__iterator = function(type, reverse) {var this$0 = this;\n\t      var ii = 0;\n\t      return new Iterator(function() \n\t        {return ii < this$0.size ? iteratorValue(type, ii++, this$0._value) : iteratorDone()}\n\t      );\n\t    };\n\n\t    Repeat.prototype.equals = function(other) {\n\t      return other instanceof Repeat ?\n\t        is(this._value, other._value) :\n\t        deepEqual(other);\n\t    };\n\n\n\t  var EMPTY_REPEAT;\n\n\t  function invariant(condition, error) {\n\t    if (!condition) throw new Error(error);\n\t  }\n\n\t  createClass(Range, IndexedSeq);\n\n\t    function Range(start, end, step) {\n\t      if (!(this instanceof Range)) {\n\t        return new Range(start, end, step);\n\t      }\n\t      invariant(step !== 0, 'Cannot step a Range by 0');\n\t      start = start || 0;\n\t      if (end === undefined) {\n\t        end = Infinity;\n\t      }\n\t      step = step === undefined ? 1 : Math.abs(step);\n\t      if (end < start) {\n\t        step = -step;\n\t      }\n\t      this._start = start;\n\t      this._end = end;\n\t      this._step = step;\n\t      this.size = Math.max(0, Math.ceil((end - start) / step - 1) + 1);\n\t      if (this.size === 0) {\n\t        if (EMPTY_RANGE) {\n\t          return EMPTY_RANGE;\n\t        }\n\t        EMPTY_RANGE = this;\n\t      }\n\t    }\n\n\t    Range.prototype.toString = function() {\n\t      if (this.size === 0) {\n\t        return 'Range []';\n\t      }\n\t      return 'Range [ ' +\n\t        this._start + '...' + this._end +\n\t        (this._step !== 1 ? ' by ' + this._step : '') +\n\t      ' ]';\n\t    };\n\n\t    Range.prototype.get = function(index, notSetValue) {\n\t      return this.has(index) ?\n\t        this._start + wrapIndex(this, index) * this._step :\n\t        notSetValue;\n\t    };\n\n\t    Range.prototype.includes = function(searchValue) {\n\t      var possibleIndex = (searchValue - this._start) / this._step;\n\t      return possibleIndex >= 0 &&\n\t        possibleIndex < this.size &&\n\t        possibleIndex === Math.floor(possibleIndex);\n\t    };\n\n\t    Range.prototype.slice = function(begin, end) {\n\t      if (wholeSlice(begin, end, this.size)) {\n\t        return this;\n\t      }\n\t      begin = resolveBegin(begin, this.size);\n\t      end = resolveEnd(end, this.size);\n\t      if (end <= begin) {\n\t        return new Range(0, 0);\n\t      }\n\t      return new Range(this.get(begin, this._end), this.get(end, this._end), this._step);\n\t    };\n\n\t    Range.prototype.indexOf = function(searchValue) {\n\t      var offsetValue = searchValue - this._start;\n\t      if (offsetValue % this._step === 0) {\n\t        var index = offsetValue / this._step;\n\t        if (index >= 0 && index < this.size) {\n\t          return index\n\t        }\n\t      }\n\t      return -1;\n\t    };\n\n\t    Range.prototype.lastIndexOf = function(searchValue) {\n\t      return this.indexOf(searchValue);\n\t    };\n\n\t    Range.prototype.__iterate = function(fn, reverse) {\n\t      var maxIndex = this.size - 1;\n\t      var step = this._step;\n\t      var value = reverse ? this._start + maxIndex * step : this._start;\n\t      for (var ii = 0; ii <= maxIndex; ii++) {\n\t        if (fn(value, ii, this) === false) {\n\t          return ii + 1;\n\t        }\n\t        value += reverse ? -step : step;\n\t      }\n\t      return ii;\n\t    };\n\n\t    Range.prototype.__iterator = function(type, reverse) {\n\t      var maxIndex = this.size - 1;\n\t      var step = this._step;\n\t      var value = reverse ? this._start + maxIndex * step : this._start;\n\t      var ii = 0;\n\t      return new Iterator(function()  {\n\t        var v = value;\n\t        value += reverse ? -step : step;\n\t        return ii > maxIndex ? iteratorDone() : iteratorValue(type, ii++, v);\n\t      });\n\t    };\n\n\t    Range.prototype.equals = function(other) {\n\t      return other instanceof Range ?\n\t        this._start === other._start &&\n\t        this._end === other._end &&\n\t        this._step === other._step :\n\t        deepEqual(this, other);\n\t    };\n\n\n\t  var EMPTY_RANGE;\n\n\t  createClass(Collection, Iterable);\n\t    function Collection() {\n\t      throw TypeError('Abstract');\n\t    }\n\n\n\t  createClass(KeyedCollection, Collection);function KeyedCollection() {}\n\n\t  createClass(IndexedCollection, Collection);function IndexedCollection() {}\n\n\t  createClass(SetCollection, Collection);function SetCollection() {}\n\n\n\t  Collection.Keyed = KeyedCollection;\n\t  Collection.Indexed = IndexedCollection;\n\t  Collection.Set = SetCollection;\n\n\t  var imul =\n\t    typeof Math.imul === 'function' && Math.imul(0xffffffff, 2) === -2 ?\n\t    Math.imul :\n\t    function imul(a, b) {\n\t      a = a | 0; // int\n\t      b = b | 0; // int\n\t      var c = a & 0xffff;\n\t      var d = b & 0xffff;\n\t      // Shift by 0 fixes the sign on the high part.\n\t      return (c * d) + ((((a >>> 16) * d + c * (b >>> 16)) << 16) >>> 0) | 0; // int\n\t    };\n\n\t  // v8 has an optimization for storing 31-bit signed numbers.\n\t  // Values which have either 00 or 11 as the high order bits qualify.\n\t  // This function drops the highest order bit in a signed number, maintaining\n\t  // the sign bit.\n\t  function smi(i32) {\n\t    return ((i32 >>> 1) & 0x40000000) | (i32 & 0xBFFFFFFF);\n\t  }\n\n\t  function hash(o) {\n\t    if (o === false || o === null || o === undefined) {\n\t      return 0;\n\t    }\n\t    if (typeof o.valueOf === 'function') {\n\t      o = o.valueOf();\n\t      if (o === false || o === null || o === undefined) {\n\t        return 0;\n\t      }\n\t    }\n\t    if (o === true) {\n\t      return 1;\n\t    }\n\t    var type = typeof o;\n\t    if (type === 'number') {\n\t      if (o !== o || o === Infinity) {\n\t        return 0;\n\t      }\n\t      var h = o | 0;\n\t      if (h !== o) {\n\t        h ^= o * 0xFFFFFFFF;\n\t      }\n\t      while (o > 0xFFFFFFFF) {\n\t        o /= 0xFFFFFFFF;\n\t        h ^= o;\n\t      }\n\t      return smi(h);\n\t    }\n\t    if (type === 'string') {\n\t      return o.length > STRING_HASH_CACHE_MIN_STRLEN ? cachedHashString(o) : hashString(o);\n\t    }\n\t    if (typeof o.hashCode === 'function') {\n\t      return o.hashCode();\n\t    }\n\t    if (type === 'object') {\n\t      return hashJSObj(o);\n\t    }\n\t    if (typeof o.toString === 'function') {\n\t      return hashString(o.toString());\n\t    }\n\t    throw new Error('Value type ' + type + ' cannot be hashed.');\n\t  }\n\n\t  function cachedHashString(string) {\n\t    var hash = stringHashCache[string];\n\t    if (hash === undefined) {\n\t      hash = hashString(string);\n\t      if (STRING_HASH_CACHE_SIZE === STRING_HASH_CACHE_MAX_SIZE) {\n\t        STRING_HASH_CACHE_SIZE = 0;\n\t        stringHashCache = {};\n\t      }\n\t      STRING_HASH_CACHE_SIZE++;\n\t      stringHashCache[string] = hash;\n\t    }\n\t    return hash;\n\t  }\n\n\t  // http://jsperf.com/hashing-strings\n\t  function hashString(string) {\n\t    // This is the hash from JVM\n\t    // The hash code for a string is computed as\n\t    // s[0] * 31 ^ (n - 1) + s[1] * 31 ^ (n - 2) + ... + s[n - 1],\n\t    // where s[i] is the ith character of the string and n is the length of\n\t    // the string. We \"mod\" the result to make it between 0 (inclusive) and 2^31\n\t    // (exclusive) by dropping high bits.\n\t    var hash = 0;\n\t    for (var ii = 0; ii < string.length; ii++) {\n\t      hash = 31 * hash + string.charCodeAt(ii) | 0;\n\t    }\n\t    return smi(hash);\n\t  }\n\n\t  function hashJSObj(obj) {\n\t    var hash;\n\t    if (usingWeakMap) {\n\t      hash = weakMap.get(obj);\n\t      if (hash !== undefined) {\n\t        return hash;\n\t      }\n\t    }\n\n\t    hash = obj[UID_HASH_KEY];\n\t    if (hash !== undefined) {\n\t      return hash;\n\t    }\n\n\t    if (!canDefineProperty) {\n\t      hash = obj.propertyIsEnumerable && obj.propertyIsEnumerable[UID_HASH_KEY];\n\t      if (hash !== undefined) {\n\t        return hash;\n\t      }\n\n\t      hash = getIENodeHash(obj);\n\t      if (hash !== undefined) {\n\t        return hash;\n\t      }\n\t    }\n\n\t    hash = ++objHashUID;\n\t    if (objHashUID & 0x40000000) {\n\t      objHashUID = 0;\n\t    }\n\n\t    if (usingWeakMap) {\n\t      weakMap.set(obj, hash);\n\t    } else if (isExtensible !== undefined && isExtensible(obj) === false) {\n\t      throw new Error('Non-extensible objects are not allowed as keys.');\n\t    } else if (canDefineProperty) {\n\t      Object.defineProperty(obj, UID_HASH_KEY, {\n\t        'enumerable': false,\n\t        'configurable': false,\n\t        'writable': false,\n\t        'value': hash\n\t      });\n\t    } else if (obj.propertyIsEnumerable !== undefined &&\n\t               obj.propertyIsEnumerable === obj.constructor.prototype.propertyIsEnumerable) {\n\t      // Since we can't define a non-enumerable property on the object\n\t      // we'll hijack one of the less-used non-enumerable properties to\n\t      // save our hash on it. Since this is a function it will not show up in\n\t      // `JSON.stringify` which is what we want.\n\t      obj.propertyIsEnumerable = function() {\n\t        return this.constructor.prototype.propertyIsEnumerable.apply(this, arguments);\n\t      };\n\t      obj.propertyIsEnumerable[UID_HASH_KEY] = hash;\n\t    } else if (obj.nodeType !== undefined) {\n\t      // At this point we couldn't get the IE `uniqueID` to use as a hash\n\t      // and we couldn't use a non-enumerable property to exploit the\n\t      // dontEnum bug so we simply add the `UID_HASH_KEY` on the node\n\t      // itself.\n\t      obj[UID_HASH_KEY] = hash;\n\t    } else {\n\t      throw new Error('Unable to set a non-enumerable property on object.');\n\t    }\n\n\t    return hash;\n\t  }\n\n\t  // Get references to ES5 object methods.\n\t  var isExtensible = Object.isExtensible;\n\n\t  // True if Object.defineProperty works as expected. IE8 fails this test.\n\t  var canDefineProperty = (function() {\n\t    try {\n\t      Object.defineProperty({}, '@', {});\n\t      return true;\n\t    } catch (e) {\n\t      return false;\n\t    }\n\t  }());\n\n\t  // IE has a `uniqueID` property on DOM nodes. We can construct the hash from it\n\t  // and avoid memory leaks from the IE cloneNode bug.\n\t  function getIENodeHash(node) {\n\t    if (node && node.nodeType > 0) {\n\t      switch (node.nodeType) {\n\t        case 1: // Element\n\t          return node.uniqueID;\n\t        case 9: // Document\n\t          return node.documentElement && node.documentElement.uniqueID;\n\t      }\n\t    }\n\t  }\n\n\t  // If possible, use a WeakMap.\n\t  var usingWeakMap = typeof WeakMap === 'function';\n\t  var weakMap;\n\t  if (usingWeakMap) {\n\t    weakMap = new WeakMap();\n\t  }\n\n\t  var objHashUID = 0;\n\n\t  var UID_HASH_KEY = '__immutablehash__';\n\t  if (typeof Symbol === 'function') {\n\t    UID_HASH_KEY = Symbol(UID_HASH_KEY);\n\t  }\n\n\t  var STRING_HASH_CACHE_MIN_STRLEN = 16;\n\t  var STRING_HASH_CACHE_MAX_SIZE = 255;\n\t  var STRING_HASH_CACHE_SIZE = 0;\n\t  var stringHashCache = {};\n\n\t  function assertNotInfinite(size) {\n\t    invariant(\n\t      size !== Infinity,\n\t      'Cannot perform this action with an infinite size.'\n\t    );\n\t  }\n\n\t  createClass(Map, KeyedCollection);\n\n\t    // @pragma Construction\n\n\t    function Map(value) {\n\t      return value === null || value === undefined ? emptyMap() :\n\t        isMap(value) && !isOrdered(value) ? value :\n\t        emptyMap().withMutations(function(map ) {\n\t          var iter = KeyedIterable(value);\n\t          assertNotInfinite(iter.size);\n\t          iter.forEach(function(v, k)  {return map.set(k, v)});\n\t        });\n\t    }\n\n\t    Map.of = function() {var keyValues = SLICE$0.call(arguments, 0);\n\t      return emptyMap().withMutations(function(map ) {\n\t        for (var i = 0; i < keyValues.length; i += 2) {\n\t          if (i + 1 >= keyValues.length) {\n\t            throw new Error('Missing value for key: ' + keyValues[i]);\n\t          }\n\t          map.set(keyValues[i], keyValues[i + 1]);\n\t        }\n\t      });\n\t    };\n\n\t    Map.prototype.toString = function() {\n\t      return this.__toString('Map {', '}');\n\t    };\n\n\t    // @pragma Access\n\n\t    Map.prototype.get = function(k, notSetValue) {\n\t      return this._root ?\n\t        this._root.get(0, undefined, k, notSetValue) :\n\t        notSetValue;\n\t    };\n\n\t    // @pragma Modification\n\n\t    Map.prototype.set = function(k, v) {\n\t      return updateMap(this, k, v);\n\t    };\n\n\t    Map.prototype.setIn = function(keyPath, v) {\n\t      return this.updateIn(keyPath, NOT_SET, function()  {return v});\n\t    };\n\n\t    Map.prototype.remove = function(k) {\n\t      return updateMap(this, k, NOT_SET);\n\t    };\n\n\t    Map.prototype.deleteIn = function(keyPath) {\n\t      return this.updateIn(keyPath, function()  {return NOT_SET});\n\t    };\n\n\t    Map.prototype.update = function(k, notSetValue, updater) {\n\t      return arguments.length === 1 ?\n\t        k(this) :\n\t        this.updateIn([k], notSetValue, updater);\n\t    };\n\n\t    Map.prototype.updateIn = function(keyPath, notSetValue, updater) {\n\t      if (!updater) {\n\t        updater = notSetValue;\n\t        notSetValue = undefined;\n\t      }\n\t      var updatedValue = updateInDeepMap(\n\t        this,\n\t        forceIterator(keyPath),\n\t        notSetValue,\n\t        updater\n\t      );\n\t      return updatedValue === NOT_SET ? undefined : updatedValue;\n\t    };\n\n\t    Map.prototype.clear = function() {\n\t      if (this.size === 0) {\n\t        return this;\n\t      }\n\t      if (this.__ownerID) {\n\t        this.size = 0;\n\t        this._root = null;\n\t        this.__hash = undefined;\n\t        this.__altered = true;\n\t        return this;\n\t      }\n\t      return emptyMap();\n\t    };\n\n\t    // @pragma Composition\n\n\t    Map.prototype.merge = function(/*...iters*/) {\n\t      return mergeIntoMapWith(this, undefined, arguments);\n\t    };\n\n\t    Map.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1);\n\t      return mergeIntoMapWith(this, merger, iters);\n\t    };\n\n\t    Map.prototype.mergeIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1);\n\t      return this.updateIn(\n\t        keyPath,\n\t        emptyMap(),\n\t        function(m ) {return typeof m.merge === 'function' ?\n\t          m.merge.apply(m, iters) :\n\t          iters[iters.length - 1]}\n\t      );\n\t    };\n\n\t    Map.prototype.mergeDeep = function(/*...iters*/) {\n\t      return mergeIntoMapWith(this, deepMerger, arguments);\n\t    };\n\n\t    Map.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1);\n\t      return mergeIntoMapWith(this, deepMergerWith(merger), iters);\n\t    };\n\n\t    Map.prototype.mergeDeepIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1);\n\t      return this.updateIn(\n\t        keyPath,\n\t        emptyMap(),\n\t        function(m ) {return typeof m.mergeDeep === 'function' ?\n\t          m.mergeDeep.apply(m, iters) :\n\t          iters[iters.length - 1]}\n\t      );\n\t    };\n\n\t    Map.prototype.sort = function(comparator) {\n\t      // Late binding\n\t      return OrderedMap(sortFactory(this, comparator));\n\t    };\n\n\t    Map.prototype.sortBy = function(mapper, comparator) {\n\t      // Late binding\n\t      return OrderedMap(sortFactory(this, comparator, mapper));\n\t    };\n\n\t    // @pragma Mutability\n\n\t    Map.prototype.withMutations = function(fn) {\n\t      var mutable = this.asMutable();\n\t      fn(mutable);\n\t      return mutable.wasAltered() ? mutable.__ensureOwner(this.__ownerID) : this;\n\t    };\n\n\t    Map.prototype.asMutable = function() {\n\t      return this.__ownerID ? this : this.__ensureOwner(new OwnerID());\n\t    };\n\n\t    Map.prototype.asImmutable = function() {\n\t      return this.__ensureOwner();\n\t    };\n\n\t    Map.prototype.wasAltered = function() {\n\t      return this.__altered;\n\t    };\n\n\t    Map.prototype.__iterator = function(type, reverse) {\n\t      return new MapIterator(this, type, reverse);\n\t    };\n\n\t    Map.prototype.__iterate = function(fn, reverse) {var this$0 = this;\n\t      var iterations = 0;\n\t      this._root && this._root.iterate(function(entry ) {\n\t        iterations++;\n\t        return fn(entry[1], entry[0], this$0);\n\t      }, reverse);\n\t      return iterations;\n\t    };\n\n\t    Map.prototype.__ensureOwner = function(ownerID) {\n\t      if (ownerID === this.__ownerID) {\n\t        return this;\n\t      }\n\t      if (!ownerID) {\n\t        this.__ownerID = ownerID;\n\t        this.__altered = false;\n\t        return this;\n\t      }\n\t      return makeMap(this.size, this._root, ownerID, this.__hash);\n\t    };\n\n\n\t  function isMap(maybeMap) {\n\t    return !!(maybeMap && maybeMap[IS_MAP_SENTINEL]);\n\t  }\n\n\t  Map.isMap = isMap;\n\n\t  var IS_MAP_SENTINEL = '@@__IMMUTABLE_MAP__@@';\n\n\t  var MapPrototype = Map.prototype;\n\t  MapPrototype[IS_MAP_SENTINEL] = true;\n\t  MapPrototype[DELETE] = MapPrototype.remove;\n\t  MapPrototype.removeIn = MapPrototype.deleteIn;\n\n\n\t  // #pragma Trie Nodes\n\n\n\n\t    function ArrayMapNode(ownerID, entries) {\n\t      this.ownerID = ownerID;\n\t      this.entries = entries;\n\t    }\n\n\t    ArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) {\n\t      var entries = this.entries;\n\t      for (var ii = 0, len = entries.length; ii < len; ii++) {\n\t        if (is(key, entries[ii][0])) {\n\t          return entries[ii][1];\n\t        }\n\t      }\n\t      return notSetValue;\n\t    };\n\n\t    ArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {\n\t      var removed = value === NOT_SET;\n\n\t      var entries = this.entries;\n\t      var idx = 0;\n\t      for (var len = entries.length; idx < len; idx++) {\n\t        if (is(key, entries[idx][0])) {\n\t          break;\n\t        }\n\t      }\n\t      var exists = idx < len;\n\n\t      if (exists ? entries[idx][1] === value : removed) {\n\t        return this;\n\t      }\n\n\t      SetRef(didAlter);\n\t      (removed || !exists) && SetRef(didChangeSize);\n\n\t      if (removed && entries.length === 1) {\n\t        return; // undefined\n\t      }\n\n\t      if (!exists && !removed && entries.length >= MAX_ARRAY_MAP_SIZE) {\n\t        return createNodes(ownerID, entries, key, value);\n\t      }\n\n\t      var isEditable = ownerID && ownerID === this.ownerID;\n\t      var newEntries = isEditable ? entries : arrCopy(entries);\n\n\t      if (exists) {\n\t        if (removed) {\n\t          idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop());\n\t        } else {\n\t          newEntries[idx] = [key, value];\n\t        }\n\t      } else {\n\t        newEntries.push([key, value]);\n\t      }\n\n\t      if (isEditable) {\n\t        this.entries = newEntries;\n\t        return this;\n\t      }\n\n\t      return new ArrayMapNode(ownerID, newEntries);\n\t    };\n\n\n\n\n\t    function BitmapIndexedNode(ownerID, bitmap, nodes) {\n\t      this.ownerID = ownerID;\n\t      this.bitmap = bitmap;\n\t      this.nodes = nodes;\n\t    }\n\n\t    BitmapIndexedNode.prototype.get = function(shift, keyHash, key, notSetValue) {\n\t      if (keyHash === undefined) {\n\t        keyHash = hash(key);\n\t      }\n\t      var bit = (1 << ((shift === 0 ? keyHash : keyHash >>> shift) & MASK));\n\t      var bitmap = this.bitmap;\n\t      return (bitmap & bit) === 0 ? notSetValue :\n\t        this.nodes[popCount(bitmap & (bit - 1))].get(shift + SHIFT, keyHash, key, notSetValue);\n\t    };\n\n\t    BitmapIndexedNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {\n\t      if (keyHash === undefined) {\n\t        keyHash = hash(key);\n\t      }\n\t      var keyHashFrag = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;\n\t      var bit = 1 << keyHashFrag;\n\t      var bitmap = this.bitmap;\n\t      var exists = (bitmap & bit) !== 0;\n\n\t      if (!exists && value === NOT_SET) {\n\t        return this;\n\t      }\n\n\t      var idx = popCount(bitmap & (bit - 1));\n\t      var nodes = this.nodes;\n\t      var node = exists ? nodes[idx] : undefined;\n\t      var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter);\n\n\t      if (newNode === node) {\n\t        return this;\n\t      }\n\n\t      if (!exists && newNode && nodes.length >= MAX_BITMAP_INDEXED_SIZE) {\n\t        return expandNodes(ownerID, nodes, bitmap, keyHashFrag, newNode);\n\t      }\n\n\t      if (exists && !newNode && nodes.length === 2 && isLeafNode(nodes[idx ^ 1])) {\n\t        return nodes[idx ^ 1];\n\t      }\n\n\t      if (exists && newNode && nodes.length === 1 && isLeafNode(newNode)) {\n\t        return newNode;\n\t      }\n\n\t      var isEditable = ownerID && ownerID === this.ownerID;\n\t      var newBitmap = exists ? newNode ? bitmap : bitmap ^ bit : bitmap | bit;\n\t      var newNodes = exists ? newNode ?\n\t        setIn(nodes, idx, newNode, isEditable) :\n\t        spliceOut(nodes, idx, isEditable) :\n\t        spliceIn(nodes, idx, newNode, isEditable);\n\n\t      if (isEditable) {\n\t        this.bitmap = newBitmap;\n\t        this.nodes = newNodes;\n\t        return this;\n\t      }\n\n\t      return new BitmapIndexedNode(ownerID, newBitmap, newNodes);\n\t    };\n\n\n\n\n\t    function HashArrayMapNode(ownerID, count, nodes) {\n\t      this.ownerID = ownerID;\n\t      this.count = count;\n\t      this.nodes = nodes;\n\t    }\n\n\t    HashArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) {\n\t      if (keyHash === undefined) {\n\t        keyHash = hash(key);\n\t      }\n\t      var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;\n\t      var node = this.nodes[idx];\n\t      return node ? node.get(shift + SHIFT, keyHash, key, notSetValue) : notSetValue;\n\t    };\n\n\t    HashArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {\n\t      if (keyHash === undefined) {\n\t        keyHash = hash(key);\n\t      }\n\t      var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;\n\t      var removed = value === NOT_SET;\n\t      var nodes = this.nodes;\n\t      var node = nodes[idx];\n\n\t      if (removed && !node) {\n\t        return this;\n\t      }\n\n\t      var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter);\n\t      if (newNode === node) {\n\t        return this;\n\t      }\n\n\t      var newCount = this.count;\n\t      if (!node) {\n\t        newCount++;\n\t      } else if (!newNode) {\n\t        newCount--;\n\t        if (newCount < MIN_HASH_ARRAY_MAP_SIZE) {\n\t          return packNodes(ownerID, nodes, newCount, idx);\n\t        }\n\t      }\n\n\t      var isEditable = ownerID && ownerID === this.ownerID;\n\t      var newNodes = setIn(nodes, idx, newNode, isEditable);\n\n\t      if (isEditable) {\n\t        this.count = newCount;\n\t        this.nodes = newNodes;\n\t        return this;\n\t      }\n\n\t      return new HashArrayMapNode(ownerID, newCount, newNodes);\n\t    };\n\n\n\n\n\t    function HashCollisionNode(ownerID, keyHash, entries) {\n\t      this.ownerID = ownerID;\n\t      this.keyHash = keyHash;\n\t      this.entries = entries;\n\t    }\n\n\t    HashCollisionNode.prototype.get = function(shift, keyHash, key, notSetValue) {\n\t      var entries = this.entries;\n\t      for (var ii = 0, len = entries.length; ii < len; ii++) {\n\t        if (is(key, entries[ii][0])) {\n\t          return entries[ii][1];\n\t        }\n\t      }\n\t      return notSetValue;\n\t    };\n\n\t    HashCollisionNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {\n\t      if (keyHash === undefined) {\n\t        keyHash = hash(key);\n\t      }\n\n\t      var removed = value === NOT_SET;\n\n\t      if (keyHash !== this.keyHash) {\n\t        if (removed) {\n\t          return this;\n\t        }\n\t        SetRef(didAlter);\n\t        SetRef(didChangeSize);\n\t        return mergeIntoNode(this, ownerID, shift, keyHash, [key, value]);\n\t      }\n\n\t      var entries = this.entries;\n\t      var idx = 0;\n\t      for (var len = entries.length; idx < len; idx++) {\n\t        if (is(key, entries[idx][0])) {\n\t          break;\n\t        }\n\t      }\n\t      var exists = idx < len;\n\n\t      if (exists ? entries[idx][1] === value : removed) {\n\t        return this;\n\t      }\n\n\t      SetRef(didAlter);\n\t      (removed || !exists) && SetRef(didChangeSize);\n\n\t      if (removed && len === 2) {\n\t        return new ValueNode(ownerID, this.keyHash, entries[idx ^ 1]);\n\t      }\n\n\t      var isEditable = ownerID && ownerID === this.ownerID;\n\t      var newEntries = isEditable ? entries : arrCopy(entries);\n\n\t      if (exists) {\n\t        if (removed) {\n\t          idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop());\n\t        } else {\n\t          newEntries[idx] = [key, value];\n\t        }\n\t      } else {\n\t        newEntries.push([key, value]);\n\t      }\n\n\t      if (isEditable) {\n\t        this.entries = newEntries;\n\t        return this;\n\t      }\n\n\t      return new HashCollisionNode(ownerID, this.keyHash, newEntries);\n\t    };\n\n\n\n\n\t    function ValueNode(ownerID, keyHash, entry) {\n\t      this.ownerID = ownerID;\n\t      this.keyHash = keyHash;\n\t      this.entry = entry;\n\t    }\n\n\t    ValueNode.prototype.get = function(shift, keyHash, key, notSetValue) {\n\t      return is(key, this.entry[0]) ? this.entry[1] : notSetValue;\n\t    };\n\n\t    ValueNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {\n\t      var removed = value === NOT_SET;\n\t      var keyMatch = is(key, this.entry[0]);\n\t      if (keyMatch ? value === this.entry[1] : removed) {\n\t        return this;\n\t      }\n\n\t      SetRef(didAlter);\n\n\t      if (removed) {\n\t        SetRef(didChangeSize);\n\t        return; // undefined\n\t      }\n\n\t      if (keyMatch) {\n\t        if (ownerID && ownerID === this.ownerID) {\n\t          this.entry[1] = value;\n\t          return this;\n\t        }\n\t        return new ValueNode(ownerID, this.keyHash, [key, value]);\n\t      }\n\n\t      SetRef(didChangeSize);\n\t      return mergeIntoNode(this, ownerID, shift, hash(key), [key, value]);\n\t    };\n\n\n\n\t  // #pragma Iterators\n\n\t  ArrayMapNode.prototype.iterate =\n\t  HashCollisionNode.prototype.iterate = function (fn, reverse) {\n\t    var entries = this.entries;\n\t    for (var ii = 0, maxIndex = entries.length - 1; ii <= maxIndex; ii++) {\n\t      if (fn(entries[reverse ? maxIndex - ii : ii]) === false) {\n\t        return false;\n\t      }\n\t    }\n\t  }\n\n\t  BitmapIndexedNode.prototype.iterate =\n\t  HashArrayMapNode.prototype.iterate = function (fn, reverse) {\n\t    var nodes = this.nodes;\n\t    for (var ii = 0, maxIndex = nodes.length - 1; ii <= maxIndex; ii++) {\n\t      var node = nodes[reverse ? maxIndex - ii : ii];\n\t      if (node && node.iterate(fn, reverse) === false) {\n\t        return false;\n\t      }\n\t    }\n\t  }\n\n\t  ValueNode.prototype.iterate = function (fn, reverse) {\n\t    return fn(this.entry);\n\t  }\n\n\t  createClass(MapIterator, Iterator);\n\n\t    function MapIterator(map, type, reverse) {\n\t      this._type = type;\n\t      this._reverse = reverse;\n\t      this._stack = map._root && mapIteratorFrame(map._root);\n\t    }\n\n\t    MapIterator.prototype.next = function() {\n\t      var type = this._type;\n\t      var stack = this._stack;\n\t      while (stack) {\n\t        var node = stack.node;\n\t        var index = stack.index++;\n\t        var maxIndex;\n\t        if (node.entry) {\n\t          if (index === 0) {\n\t            return mapIteratorValue(type, node.entry);\n\t          }\n\t        } else if (node.entries) {\n\t          maxIndex = node.entries.length - 1;\n\t          if (index <= maxIndex) {\n\t            return mapIteratorValue(type, node.entries[this._reverse ? maxIndex - index : index]);\n\t          }\n\t        } else {\n\t          maxIndex = node.nodes.length - 1;\n\t          if (index <= maxIndex) {\n\t            var subNode = node.nodes[this._reverse ? maxIndex - index : index];\n\t            if (subNode) {\n\t              if (subNode.entry) {\n\t                return mapIteratorValue(type, subNode.entry);\n\t              }\n\t              stack = this._stack = mapIteratorFrame(subNode, stack);\n\t            }\n\t            continue;\n\t          }\n\t        }\n\t        stack = this._stack = this._stack.__prev;\n\t      }\n\t      return iteratorDone();\n\t    };\n\n\n\t  function mapIteratorValue(type, entry) {\n\t    return iteratorValue(type, entry[0], entry[1]);\n\t  }\n\n\t  function mapIteratorFrame(node, prev) {\n\t    return {\n\t      node: node,\n\t      index: 0,\n\t      __prev: prev\n\t    };\n\t  }\n\n\t  function makeMap(size, root, ownerID, hash) {\n\t    var map = Object.create(MapPrototype);\n\t    map.size = size;\n\t    map._root = root;\n\t    map.__ownerID = ownerID;\n\t    map.__hash = hash;\n\t    map.__altered = false;\n\t    return map;\n\t  }\n\n\t  var EMPTY_MAP;\n\t  function emptyMap() {\n\t    return EMPTY_MAP || (EMPTY_MAP = makeMap(0));\n\t  }\n\n\t  function updateMap(map, k, v) {\n\t    var newRoot;\n\t    var newSize;\n\t    if (!map._root) {\n\t      if (v === NOT_SET) {\n\t        return map;\n\t      }\n\t      newSize = 1;\n\t      newRoot = new ArrayMapNode(map.__ownerID, [[k, v]]);\n\t    } else {\n\t      var didChangeSize = MakeRef(CHANGE_LENGTH);\n\t      var didAlter = MakeRef(DID_ALTER);\n\t      newRoot = updateNode(map._root, map.__ownerID, 0, undefined, k, v, didChangeSize, didAlter);\n\t      if (!didAlter.value) {\n\t        return map;\n\t      }\n\t      newSize = map.size + (didChangeSize.value ? v === NOT_SET ? -1 : 1 : 0);\n\t    }\n\t    if (map.__ownerID) {\n\t      map.size = newSize;\n\t      map._root = newRoot;\n\t      map.__hash = undefined;\n\t      map.__altered = true;\n\t      return map;\n\t    }\n\t    return newRoot ? makeMap(newSize, newRoot) : emptyMap();\n\t  }\n\n\t  function updateNode(node, ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {\n\t    if (!node) {\n\t      if (value === NOT_SET) {\n\t        return node;\n\t      }\n\t      SetRef(didAlter);\n\t      SetRef(didChangeSize);\n\t      return new ValueNode(ownerID, keyHash, [key, value]);\n\t    }\n\t    return node.update(ownerID, shift, keyHash, key, value, didChangeSize, didAlter);\n\t  }\n\n\t  function isLeafNode(node) {\n\t    return node.constructor === ValueNode || node.constructor === HashCollisionNode;\n\t  }\n\n\t  function mergeIntoNode(node, ownerID, shift, keyHash, entry) {\n\t    if (node.keyHash === keyHash) {\n\t      return new HashCollisionNode(ownerID, keyHash, [node.entry, entry]);\n\t    }\n\n\t    var idx1 = (shift === 0 ? node.keyHash : node.keyHash >>> shift) & MASK;\n\t    var idx2 = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;\n\n\t    var newNode;\n\t    var nodes = idx1 === idx2 ?\n\t      [mergeIntoNode(node, ownerID, shift + SHIFT, keyHash, entry)] :\n\t      ((newNode = new ValueNode(ownerID, keyHash, entry)), idx1 < idx2 ? [node, newNode] : [newNode, node]);\n\n\t    return new BitmapIndexedNode(ownerID, (1 << idx1) | (1 << idx2), nodes);\n\t  }\n\n\t  function createNodes(ownerID, entries, key, value) {\n\t    if (!ownerID) {\n\t      ownerID = new OwnerID();\n\t    }\n\t    var node = new ValueNode(ownerID, hash(key), [key, value]);\n\t    for (var ii = 0; ii < entries.length; ii++) {\n\t      var entry = entries[ii];\n\t      node = node.update(ownerID, 0, undefined, entry[0], entry[1]);\n\t    }\n\t    return node;\n\t  }\n\n\t  function packNodes(ownerID, nodes, count, excluding) {\n\t    var bitmap = 0;\n\t    var packedII = 0;\n\t    var packedNodes = new Array(count);\n\t    for (var ii = 0, bit = 1, len = nodes.length; ii < len; ii++, bit <<= 1) {\n\t      var node = nodes[ii];\n\t      if (node !== undefined && ii !== excluding) {\n\t        bitmap |= bit;\n\t        packedNodes[packedII++] = node;\n\t      }\n\t    }\n\t    return new BitmapIndexedNode(ownerID, bitmap, packedNodes);\n\t  }\n\n\t  function expandNodes(ownerID, nodes, bitmap, including, node) {\n\t    var count = 0;\n\t    var expandedNodes = new Array(SIZE);\n\t    for (var ii = 0; bitmap !== 0; ii++, bitmap >>>= 1) {\n\t      expandedNodes[ii] = bitmap & 1 ? nodes[count++] : undefined;\n\t    }\n\t    expandedNodes[including] = node;\n\t    return new HashArrayMapNode(ownerID, count + 1, expandedNodes);\n\t  }\n\n\t  function mergeIntoMapWith(map, merger, iterables) {\n\t    var iters = [];\n\t    for (var ii = 0; ii < iterables.length; ii++) {\n\t      var value = iterables[ii];\n\t      var iter = KeyedIterable(value);\n\t      if (!isIterable(value)) {\n\t        iter = iter.map(function(v ) {return fromJS(v)});\n\t      }\n\t      iters.push(iter);\n\t    }\n\t    return mergeIntoCollectionWith(map, merger, iters);\n\t  }\n\n\t  function deepMerger(existing, value, key) {\n\t    return existing && existing.mergeDeep && isIterable(value) ?\n\t      existing.mergeDeep(value) :\n\t      is(existing, value) ? existing : value;\n\t  }\n\n\t  function deepMergerWith(merger) {\n\t    return function(existing, value, key)  {\n\t      if (existing && existing.mergeDeepWith && isIterable(value)) {\n\t        return existing.mergeDeepWith(merger, value);\n\t      }\n\t      var nextValue = merger(existing, value, key);\n\t      return is(existing, nextValue) ? existing : nextValue;\n\t    };\n\t  }\n\n\t  function mergeIntoCollectionWith(collection, merger, iters) {\n\t    iters = iters.filter(function(x ) {return x.size !== 0});\n\t    if (iters.length === 0) {\n\t      return collection;\n\t    }\n\t    if (collection.size === 0 && !collection.__ownerID && iters.length === 1) {\n\t      return collection.constructor(iters[0]);\n\t    }\n\t    return collection.withMutations(function(collection ) {\n\t      var mergeIntoMap = merger ?\n\t        function(value, key)  {\n\t          collection.update(key, NOT_SET, function(existing )\n\t            {return existing === NOT_SET ? value : merger(existing, value, key)}\n\t          );\n\t        } :\n\t        function(value, key)  {\n\t          collection.set(key, value);\n\t        }\n\t      for (var ii = 0; ii < iters.length; ii++) {\n\t        iters[ii].forEach(mergeIntoMap);\n\t      }\n\t    });\n\t  }\n\n\t  function updateInDeepMap(existing, keyPathIter, notSetValue, updater) {\n\t    var isNotSet = existing === NOT_SET;\n\t    var step = keyPathIter.next();\n\t    if (step.done) {\n\t      var existingValue = isNotSet ? notSetValue : existing;\n\t      var newValue = updater(existingValue);\n\t      return newValue === existingValue ? existing : newValue;\n\t    }\n\t    invariant(\n\t      isNotSet || (existing && existing.set),\n\t      'invalid keyPath'\n\t    );\n\t    var key = step.value;\n\t    var nextExisting = isNotSet ? NOT_SET : existing.get(key, NOT_SET);\n\t    var nextUpdated = updateInDeepMap(\n\t      nextExisting,\n\t      keyPathIter,\n\t      notSetValue,\n\t      updater\n\t    );\n\t    return nextUpdated === nextExisting ? existing :\n\t      nextUpdated === NOT_SET ? existing.remove(key) :\n\t      (isNotSet ? emptyMap() : existing).set(key, nextUpdated);\n\t  }\n\n\t  function popCount(x) {\n\t    x = x - ((x >> 1) & 0x55555555);\n\t    x = (x & 0x33333333) + ((x >> 2) & 0x33333333);\n\t    x = (x + (x >> 4)) & 0x0f0f0f0f;\n\t    x = x + (x >> 8);\n\t    x = x + (x >> 16);\n\t    return x & 0x7f;\n\t  }\n\n\t  function setIn(array, idx, val, canEdit) {\n\t    var newArray = canEdit ? array : arrCopy(array);\n\t    newArray[idx] = val;\n\t    return newArray;\n\t  }\n\n\t  function spliceIn(array, idx, val, canEdit) {\n\t    var newLen = array.length + 1;\n\t    if (canEdit && idx + 1 === newLen) {\n\t      array[idx] = val;\n\t      return array;\n\t    }\n\t    var newArray = new Array(newLen);\n\t    var after = 0;\n\t    for (var ii = 0; ii < newLen; ii++) {\n\t      if (ii === idx) {\n\t        newArray[ii] = val;\n\t        after = -1;\n\t      } else {\n\t        newArray[ii] = array[ii + after];\n\t      }\n\t    }\n\t    return newArray;\n\t  }\n\n\t  function spliceOut(array, idx, canEdit) {\n\t    var newLen = array.length - 1;\n\t    if (canEdit && idx === newLen) {\n\t      array.pop();\n\t      return array;\n\t    }\n\t    var newArray = new Array(newLen);\n\t    var after = 0;\n\t    for (var ii = 0; ii < newLen; ii++) {\n\t      if (ii === idx) {\n\t        after = 1;\n\t      }\n\t      newArray[ii] = array[ii + after];\n\t    }\n\t    return newArray;\n\t  }\n\n\t  var MAX_ARRAY_MAP_SIZE = SIZE / 4;\n\t  var MAX_BITMAP_INDEXED_SIZE = SIZE / 2;\n\t  var MIN_HASH_ARRAY_MAP_SIZE = SIZE / 4;\n\n\t  createClass(List, IndexedCollection);\n\n\t    // @pragma Construction\n\n\t    function List(value) {\n\t      var empty = emptyList();\n\t      if (value === null || value === undefined) {\n\t        return empty;\n\t      }\n\t      if (isList(value)) {\n\t        return value;\n\t      }\n\t      var iter = IndexedIterable(value);\n\t      var size = iter.size;\n\t      if (size === 0) {\n\t        return empty;\n\t      }\n\t      assertNotInfinite(size);\n\t      if (size > 0 && size < SIZE) {\n\t        return makeList(0, size, SHIFT, null, new VNode(iter.toArray()));\n\t      }\n\t      return empty.withMutations(function(list ) {\n\t        list.setSize(size);\n\t        iter.forEach(function(v, i)  {return list.set(i, v)});\n\t      });\n\t    }\n\n\t    List.of = function(/*...values*/) {\n\t      return this(arguments);\n\t    };\n\n\t    List.prototype.toString = function() {\n\t      return this.__toString('List [', ']');\n\t    };\n\n\t    // @pragma Access\n\n\t    List.prototype.get = function(index, notSetValue) {\n\t      index = wrapIndex(this, index);\n\t      if (index >= 0 && index < this.size) {\n\t        index += this._origin;\n\t        var node = listNodeFor(this, index);\n\t        return node && node.array[index & MASK];\n\t      }\n\t      return notSetValue;\n\t    };\n\n\t    // @pragma Modification\n\n\t    List.prototype.set = function(index, value) {\n\t      return updateList(this, index, value);\n\t    };\n\n\t    List.prototype.remove = function(index) {\n\t      return !this.has(index) ? this :\n\t        index === 0 ? this.shift() :\n\t        index === this.size - 1 ? this.pop() :\n\t        this.splice(index, 1);\n\t    };\n\n\t    List.prototype.insert = function(index, value) {\n\t      return this.splice(index, 0, value);\n\t    };\n\n\t    List.prototype.clear = function() {\n\t      if (this.size === 0) {\n\t        return this;\n\t      }\n\t      if (this.__ownerID) {\n\t        this.size = this._origin = this._capacity = 0;\n\t        this._level = SHIFT;\n\t        this._root = this._tail = null;\n\t        this.__hash = undefined;\n\t        this.__altered = true;\n\t        return this;\n\t      }\n\t      return emptyList();\n\t    };\n\n\t    List.prototype.push = function(/*...values*/) {\n\t      var values = arguments;\n\t      var oldSize = this.size;\n\t      return this.withMutations(function(list ) {\n\t        setListBounds(list, 0, oldSize + values.length);\n\t        for (var ii = 0; ii < values.length; ii++) {\n\t          list.set(oldSize + ii, values[ii]);\n\t        }\n\t      });\n\t    };\n\n\t    List.prototype.pop = function() {\n\t      return setListBounds(this, 0, -1);\n\t    };\n\n\t    List.prototype.unshift = function(/*...values*/) {\n\t      var values = arguments;\n\t      return this.withMutations(function(list ) {\n\t        setListBounds(list, -values.length);\n\t        for (var ii = 0; ii < values.length; ii++) {\n\t          list.set(ii, values[ii]);\n\t        }\n\t      });\n\t    };\n\n\t    List.prototype.shift = function() {\n\t      return setListBounds(this, 1);\n\t    };\n\n\t    // @pragma Composition\n\n\t    List.prototype.merge = function(/*...iters*/) {\n\t      return mergeIntoListWith(this, undefined, arguments);\n\t    };\n\n\t    List.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1);\n\t      return mergeIntoListWith(this, merger, iters);\n\t    };\n\n\t    List.prototype.mergeDeep = function(/*...iters*/) {\n\t      return mergeIntoListWith(this, deepMerger, arguments);\n\t    };\n\n\t    List.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1);\n\t      return mergeIntoListWith(this, deepMergerWith(merger), iters);\n\t    };\n\n\t    List.prototype.setSize = function(size) {\n\t      return setListBounds(this, 0, size);\n\t    };\n\n\t    // @pragma Iteration\n\n\t    List.prototype.slice = function(begin, end) {\n\t      var size = this.size;\n\t      if (wholeSlice(begin, end, size)) {\n\t        return this;\n\t      }\n\t      return setListBounds(\n\t        this,\n\t        resolveBegin(begin, size),\n\t        resolveEnd(end, size)\n\t      );\n\t    };\n\n\t    List.prototype.__iterator = function(type, reverse) {\n\t      var index = 0;\n\t      var values = iterateList(this, reverse);\n\t      return new Iterator(function()  {\n\t        var value = values();\n\t        return value === DONE ?\n\t          iteratorDone() :\n\t          iteratorValue(type, index++, value);\n\t      });\n\t    };\n\n\t    List.prototype.__iterate = function(fn, reverse) {\n\t      var index = 0;\n\t      var values = iterateList(this, reverse);\n\t      var value;\n\t      while ((value = values()) !== DONE) {\n\t        if (fn(value, index++, this) === false) {\n\t          break;\n\t        }\n\t      }\n\t      return index;\n\t    };\n\n\t    List.prototype.__ensureOwner = function(ownerID) {\n\t      if (ownerID === this.__ownerID) {\n\t        return this;\n\t      }\n\t      if (!ownerID) {\n\t        this.__ownerID = ownerID;\n\t        return this;\n\t      }\n\t      return makeList(this._origin, this._capacity, this._level, this._root, this._tail, ownerID, this.__hash);\n\t    };\n\n\n\t  function isList(maybeList) {\n\t    return !!(maybeList && maybeList[IS_LIST_SENTINEL]);\n\t  }\n\n\t  List.isList = isList;\n\n\t  var IS_LIST_SENTINEL = '@@__IMMUTABLE_LIST__@@';\n\n\t  var ListPrototype = List.prototype;\n\t  ListPrototype[IS_LIST_SENTINEL] = true;\n\t  ListPrototype[DELETE] = ListPrototype.remove;\n\t  ListPrototype.setIn = MapPrototype.setIn;\n\t  ListPrototype.deleteIn =\n\t  ListPrototype.removeIn = MapPrototype.removeIn;\n\t  ListPrototype.update = MapPrototype.update;\n\t  ListPrototype.updateIn = MapPrototype.updateIn;\n\t  ListPrototype.mergeIn = MapPrototype.mergeIn;\n\t  ListPrototype.mergeDeepIn = MapPrototype.mergeDeepIn;\n\t  ListPrototype.withMutations = MapPrototype.withMutations;\n\t  ListPrototype.asMutable = MapPrototype.asMutable;\n\t  ListPrototype.asImmutable = MapPrototype.asImmutable;\n\t  ListPrototype.wasAltered = MapPrototype.wasAltered;\n\n\n\n\t    function VNode(array, ownerID) {\n\t      this.array = array;\n\t      this.ownerID = ownerID;\n\t    }\n\n\t    // TODO: seems like these methods are very similar\n\n\t    VNode.prototype.removeBefore = function(ownerID, level, index) {\n\t      if (index === level ? 1 << level : 0 || this.array.length === 0) {\n\t        return this;\n\t      }\n\t      var originIndex = (index >>> level) & MASK;\n\t      if (originIndex >= this.array.length) {\n\t        return new VNode([], ownerID);\n\t      }\n\t      var removingFirst = originIndex === 0;\n\t      var newChild;\n\t      if (level > 0) {\n\t        var oldChild = this.array[originIndex];\n\t        newChild = oldChild && oldChild.removeBefore(ownerID, level - SHIFT, index);\n\t        if (newChild === oldChild && removingFirst) {\n\t          return this;\n\t        }\n\t      }\n\t      if (removingFirst && !newChild) {\n\t        return this;\n\t      }\n\t      var editable = editableVNode(this, ownerID);\n\t      if (!removingFirst) {\n\t        for (var ii = 0; ii < originIndex; ii++) {\n\t          editable.array[ii] = undefined;\n\t        }\n\t      }\n\t      if (newChild) {\n\t        editable.array[originIndex] = newChild;\n\t      }\n\t      return editable;\n\t    };\n\n\t    VNode.prototype.removeAfter = function(ownerID, level, index) {\n\t      if (index === (level ? 1 << level : 0) || this.array.length === 0) {\n\t        return this;\n\t      }\n\t      var sizeIndex = ((index - 1) >>> level) & MASK;\n\t      if (sizeIndex >= this.array.length) {\n\t        return this;\n\t      }\n\n\t      var newChild;\n\t      if (level > 0) {\n\t        var oldChild = this.array[sizeIndex];\n\t        newChild = oldChild && oldChild.removeAfter(ownerID, level - SHIFT, index);\n\t        if (newChild === oldChild && sizeIndex === this.array.length - 1) {\n\t          return this;\n\t        }\n\t      }\n\n\t      var editable = editableVNode(this, ownerID);\n\t      editable.array.splice(sizeIndex + 1);\n\t      if (newChild) {\n\t        editable.array[sizeIndex] = newChild;\n\t      }\n\t      return editable;\n\t    };\n\n\n\n\t  var DONE = {};\n\n\t  function iterateList(list, reverse) {\n\t    var left = list._origin;\n\t    var right = list._capacity;\n\t    var tailPos = getTailOffset(right);\n\t    var tail = list._tail;\n\n\t    return iterateNodeOrLeaf(list._root, list._level, 0);\n\n\t    function iterateNodeOrLeaf(node, level, offset) {\n\t      return level === 0 ?\n\t        iterateLeaf(node, offset) :\n\t        iterateNode(node, level, offset);\n\t    }\n\n\t    function iterateLeaf(node, offset) {\n\t      var array = offset === tailPos ? tail && tail.array : node && node.array;\n\t      var from = offset > left ? 0 : left - offset;\n\t      var to = right - offset;\n\t      if (to > SIZE) {\n\t        to = SIZE;\n\t      }\n\t      return function()  {\n\t        if (from === to) {\n\t          return DONE;\n\t        }\n\t        var idx = reverse ? --to : from++;\n\t        return array && array[idx];\n\t      };\n\t    }\n\n\t    function iterateNode(node, level, offset) {\n\t      var values;\n\t      var array = node && node.array;\n\t      var from = offset > left ? 0 : (left - offset) >> level;\n\t      var to = ((right - offset) >> level) + 1;\n\t      if (to > SIZE) {\n\t        to = SIZE;\n\t      }\n\t      return function()  {\n\t        do {\n\t          if (values) {\n\t            var value = values();\n\t            if (value !== DONE) {\n\t              return value;\n\t            }\n\t            values = null;\n\t          }\n\t          if (from === to) {\n\t            return DONE;\n\t          }\n\t          var idx = reverse ? --to : from++;\n\t          values = iterateNodeOrLeaf(\n\t            array && array[idx], level - SHIFT, offset + (idx << level)\n\t          );\n\t        } while (true);\n\t      };\n\t    }\n\t  }\n\n\t  function makeList(origin, capacity, level, root, tail, ownerID, hash) {\n\t    var list = Object.create(ListPrototype);\n\t    list.size = capacity - origin;\n\t    list._origin = origin;\n\t    list._capacity = capacity;\n\t    list._level = level;\n\t    list._root = root;\n\t    list._tail = tail;\n\t    list.__ownerID = ownerID;\n\t    list.__hash = hash;\n\t    list.__altered = false;\n\t    return list;\n\t  }\n\n\t  var EMPTY_LIST;\n\t  function emptyList() {\n\t    return EMPTY_LIST || (EMPTY_LIST = makeList(0, 0, SHIFT));\n\t  }\n\n\t  function updateList(list, index, value) {\n\t    index = wrapIndex(list, index);\n\n\t    if (index !== index) {\n\t      return list;\n\t    }\n\n\t    if (index >= list.size || index < 0) {\n\t      return list.withMutations(function(list ) {\n\t        index < 0 ?\n\t          setListBounds(list, index).set(0, value) :\n\t          setListBounds(list, 0, index + 1).set(index, value)\n\t      });\n\t    }\n\n\t    index += list._origin;\n\n\t    var newTail = list._tail;\n\t    var newRoot = list._root;\n\t    var didAlter = MakeRef(DID_ALTER);\n\t    if (index >= getTailOffset(list._capacity)) {\n\t      newTail = updateVNode(newTail, list.__ownerID, 0, index, value, didAlter);\n\t    } else {\n\t      newRoot = updateVNode(newRoot, list.__ownerID, list._level, index, value, didAlter);\n\t    }\n\n\t    if (!didAlter.value) {\n\t      return list;\n\t    }\n\n\t    if (list.__ownerID) {\n\t      list._root = newRoot;\n\t      list._tail = newTail;\n\t      list.__hash = undefined;\n\t      list.__altered = true;\n\t      return list;\n\t    }\n\t    return makeList(list._origin, list._capacity, list._level, newRoot, newTail);\n\t  }\n\n\t  function updateVNode(node, ownerID, level, index, value, didAlter) {\n\t    var idx = (index >>> level) & MASK;\n\t    var nodeHas = node && idx < node.array.length;\n\t    if (!nodeHas && value === undefined) {\n\t      return node;\n\t    }\n\n\t    var newNode;\n\n\t    if (level > 0) {\n\t      var lowerNode = node && node.array[idx];\n\t      var newLowerNode = updateVNode(lowerNode, ownerID, level - SHIFT, index, value, didAlter);\n\t      if (newLowerNode === lowerNode) {\n\t        return node;\n\t      }\n\t      newNode = editableVNode(node, ownerID);\n\t      newNode.array[idx] = newLowerNode;\n\t      return newNode;\n\t    }\n\n\t    if (nodeHas && node.array[idx] === value) {\n\t      return node;\n\t    }\n\n\t    SetRef(didAlter);\n\n\t    newNode = editableVNode(node, ownerID);\n\t    if (value === undefined && idx === newNode.array.length - 1) {\n\t      newNode.array.pop();\n\t    } else {\n\t      newNode.array[idx] = value;\n\t    }\n\t    return newNode;\n\t  }\n\n\t  function editableVNode(node, ownerID) {\n\t    if (ownerID && node && ownerID === node.ownerID) {\n\t      return node;\n\t    }\n\t    return new VNode(node ? node.array.slice() : [], ownerID);\n\t  }\n\n\t  function listNodeFor(list, rawIndex) {\n\t    if (rawIndex >= getTailOffset(list._capacity)) {\n\t      return list._tail;\n\t    }\n\t    if (rawIndex < 1 << (list._level + SHIFT)) {\n\t      var node = list._root;\n\t      var level = list._level;\n\t      while (node && level > 0) {\n\t        node = node.array[(rawIndex >>> level) & MASK];\n\t        level -= SHIFT;\n\t      }\n\t      return node;\n\t    }\n\t  }\n\n\t  function setListBounds(list, begin, end) {\n\t    // Sanitize begin & end using this shorthand for ToInt32(argument)\n\t    // http://www.ecma-international.org/ecma-262/6.0/#sec-toint32\n\t    if (begin !== undefined) {\n\t      begin = begin | 0;\n\t    }\n\t    if (end !== undefined) {\n\t      end = end | 0;\n\t    }\n\t    var owner = list.__ownerID || new OwnerID();\n\t    var oldOrigin = list._origin;\n\t    var oldCapacity = list._capacity;\n\t    var newOrigin = oldOrigin + begin;\n\t    var newCapacity = end === undefined ? oldCapacity : end < 0 ? oldCapacity + end : oldOrigin + end;\n\t    if (newOrigin === oldOrigin && newCapacity === oldCapacity) {\n\t      return list;\n\t    }\n\n\t    // If it's going to end after it starts, it's empty.\n\t    if (newOrigin >= newCapacity) {\n\t      return list.clear();\n\t    }\n\n\t    var newLevel = list._level;\n\t    var newRoot = list._root;\n\n\t    // New origin might need creating a higher root.\n\t    var offsetShift = 0;\n\t    while (newOrigin + offsetShift < 0) {\n\t      newRoot = new VNode(newRoot && newRoot.array.length ? [undefined, newRoot] : [], owner);\n\t      newLevel += SHIFT;\n\t      offsetShift += 1 << newLevel;\n\t    }\n\t    if (offsetShift) {\n\t      newOrigin += offsetShift;\n\t      oldOrigin += offsetShift;\n\t      newCapacity += offsetShift;\n\t      oldCapacity += offsetShift;\n\t    }\n\n\t    var oldTailOffset = getTailOffset(oldCapacity);\n\t    var newTailOffset = getTailOffset(newCapacity);\n\n\t    // New size might need creating a higher root.\n\t    while (newTailOffset >= 1 << (newLevel + SHIFT)) {\n\t      newRoot = new VNode(newRoot && newRoot.array.length ? [newRoot] : [], owner);\n\t      newLevel += SHIFT;\n\t    }\n\n\t    // Locate or create the new tail.\n\t    var oldTail = list._tail;\n\t    var newTail = newTailOffset < oldTailOffset ?\n\t      listNodeFor(list, newCapacity - 1) :\n\t      newTailOffset > oldTailOffset ? new VNode([], owner) : oldTail;\n\n\t    // Merge Tail into tree.\n\t    if (oldTail && newTailOffset > oldTailOffset && newOrigin < oldCapacity && oldTail.array.length) {\n\t      newRoot = editableVNode(newRoot, owner);\n\t      var node = newRoot;\n\t      for (var level = newLevel; level > SHIFT; level -= SHIFT) {\n\t        var idx = (oldTailOffset >>> level) & MASK;\n\t        node = node.array[idx] = editableVNode(node.array[idx], owner);\n\t      }\n\t      node.array[(oldTailOffset >>> SHIFT) & MASK] = oldTail;\n\t    }\n\n\t    // If the size has been reduced, there's a chance the tail needs to be trimmed.\n\t    if (newCapacity < oldCapacity) {\n\t      newTail = newTail && newTail.removeAfter(owner, 0, newCapacity);\n\t    }\n\n\t    // If the new origin is within the tail, then we do not need a root.\n\t    if (newOrigin >= newTailOffset) {\n\t      newOrigin -= newTailOffset;\n\t      newCapacity -= newTailOffset;\n\t      newLevel = SHIFT;\n\t      newRoot = null;\n\t      newTail = newTail && newTail.removeBefore(owner, 0, newOrigin);\n\n\t    // Otherwise, if the root has been trimmed, garbage collect.\n\t    } else if (newOrigin > oldOrigin || newTailOffset < oldTailOffset) {\n\t      offsetShift = 0;\n\n\t      // Identify the new top root node of the subtree of the old root.\n\t      while (newRoot) {\n\t        var beginIndex = (newOrigin >>> newLevel) & MASK;\n\t        if (beginIndex !== (newTailOffset >>> newLevel) & MASK) {\n\t          break;\n\t        }\n\t        if (beginIndex) {\n\t          offsetShift += (1 << newLevel) * beginIndex;\n\t        }\n\t        newLevel -= SHIFT;\n\t        newRoot = newRoot.array[beginIndex];\n\t      }\n\n\t      // Trim the new sides of the new root.\n\t      if (newRoot && newOrigin > oldOrigin) {\n\t        newRoot = newRoot.removeBefore(owner, newLevel, newOrigin - offsetShift);\n\t      }\n\t      if (newRoot && newTailOffset < oldTailOffset) {\n\t        newRoot = newRoot.removeAfter(owner, newLevel, newTailOffset - offsetShift);\n\t      }\n\t      if (offsetShift) {\n\t        newOrigin -= offsetShift;\n\t        newCapacity -= offsetShift;\n\t      }\n\t    }\n\n\t    if (list.__ownerID) {\n\t      list.size = newCapacity - newOrigin;\n\t      list._origin = newOrigin;\n\t      list._capacity = newCapacity;\n\t      list._level = newLevel;\n\t      list._root = newRoot;\n\t      list._tail = newTail;\n\t      list.__hash = undefined;\n\t      list.__altered = true;\n\t      return list;\n\t    }\n\t    return makeList(newOrigin, newCapacity, newLevel, newRoot, newTail);\n\t  }\n\n\t  function mergeIntoListWith(list, merger, iterables) {\n\t    var iters = [];\n\t    var maxSize = 0;\n\t    for (var ii = 0; ii < iterables.length; ii++) {\n\t      var value = iterables[ii];\n\t      var iter = IndexedIterable(value);\n\t      if (iter.size > maxSize) {\n\t        maxSize = iter.size;\n\t      }\n\t      if (!isIterable(value)) {\n\t        iter = iter.map(function(v ) {return fromJS(v)});\n\t      }\n\t      iters.push(iter);\n\t    }\n\t    if (maxSize > list.size) {\n\t      list = list.setSize(maxSize);\n\t    }\n\t    return mergeIntoCollectionWith(list, merger, iters);\n\t  }\n\n\t  function getTailOffset(size) {\n\t    return size < SIZE ? 0 : (((size - 1) >>> SHIFT) << SHIFT);\n\t  }\n\n\t  createClass(OrderedMap, Map);\n\n\t    // @pragma Construction\n\n\t    function OrderedMap(value) {\n\t      return value === null || value === undefined ? emptyOrderedMap() :\n\t        isOrderedMap(value) ? value :\n\t        emptyOrderedMap().withMutations(function(map ) {\n\t          var iter = KeyedIterable(value);\n\t          assertNotInfinite(iter.size);\n\t          iter.forEach(function(v, k)  {return map.set(k, v)});\n\t        });\n\t    }\n\n\t    OrderedMap.of = function(/*...values*/) {\n\t      return this(arguments);\n\t    };\n\n\t    OrderedMap.prototype.toString = function() {\n\t      return this.__toString('OrderedMap {', '}');\n\t    };\n\n\t    // @pragma Access\n\n\t    OrderedMap.prototype.get = function(k, notSetValue) {\n\t      var index = this._map.get(k);\n\t      return index !== undefined ? this._list.get(index)[1] : notSetValue;\n\t    };\n\n\t    // @pragma Modification\n\n\t    OrderedMap.prototype.clear = function() {\n\t      if (this.size === 0) {\n\t        return this;\n\t      }\n\t      if (this.__ownerID) {\n\t        this.size = 0;\n\t        this._map.clear();\n\t        this._list.clear();\n\t        return this;\n\t      }\n\t      return emptyOrderedMap();\n\t    };\n\n\t    OrderedMap.prototype.set = function(k, v) {\n\t      return updateOrderedMap(this, k, v);\n\t    };\n\n\t    OrderedMap.prototype.remove = function(k) {\n\t      return updateOrderedMap(this, k, NOT_SET);\n\t    };\n\n\t    OrderedMap.prototype.wasAltered = function() {\n\t      return this._map.wasAltered() || this._list.wasAltered();\n\t    };\n\n\t    OrderedMap.prototype.__iterate = function(fn, reverse) {var this$0 = this;\n\t      return this._list.__iterate(\n\t        function(entry ) {return entry && fn(entry[1], entry[0], this$0)},\n\t        reverse\n\t      );\n\t    };\n\n\t    OrderedMap.prototype.__iterator = function(type, reverse) {\n\t      return this._list.fromEntrySeq().__iterator(type, reverse);\n\t    };\n\n\t    OrderedMap.prototype.__ensureOwner = function(ownerID) {\n\t      if (ownerID === this.__ownerID) {\n\t        return this;\n\t      }\n\t      var newMap = this._map.__ensureOwner(ownerID);\n\t      var newList = this._list.__ensureOwner(ownerID);\n\t      if (!ownerID) {\n\t        this.__ownerID = ownerID;\n\t        this._map = newMap;\n\t        this._list = newList;\n\t        return this;\n\t      }\n\t      return makeOrderedMap(newMap, newList, ownerID, this.__hash);\n\t    };\n\n\n\t  function isOrderedMap(maybeOrderedMap) {\n\t    return isMap(maybeOrderedMap) && isOrdered(maybeOrderedMap);\n\t  }\n\n\t  OrderedMap.isOrderedMap = isOrderedMap;\n\n\t  OrderedMap.prototype[IS_ORDERED_SENTINEL] = true;\n\t  OrderedMap.prototype[DELETE] = OrderedMap.prototype.remove;\n\n\n\n\t  function makeOrderedMap(map, list, ownerID, hash) {\n\t    var omap = Object.create(OrderedMap.prototype);\n\t    omap.size = map ? map.size : 0;\n\t    omap._map = map;\n\t    omap._list = list;\n\t    omap.__ownerID = ownerID;\n\t    omap.__hash = hash;\n\t    return omap;\n\t  }\n\n\t  var EMPTY_ORDERED_MAP;\n\t  function emptyOrderedMap() {\n\t    return EMPTY_ORDERED_MAP || (EMPTY_ORDERED_MAP = makeOrderedMap(emptyMap(), emptyList()));\n\t  }\n\n\t  function updateOrderedMap(omap, k, v) {\n\t    var map = omap._map;\n\t    var list = omap._list;\n\t    var i = map.get(k);\n\t    var has = i !== undefined;\n\t    var newMap;\n\t    var newList;\n\t    if (v === NOT_SET) { // removed\n\t      if (!has) {\n\t        return omap;\n\t      }\n\t      if (list.size >= SIZE && list.size >= map.size * 2) {\n\t        newList = list.filter(function(entry, idx)  {return entry !== undefined && i !== idx});\n\t        newMap = newList.toKeyedSeq().map(function(entry ) {return entry[0]}).flip().toMap();\n\t        if (omap.__ownerID) {\n\t          newMap.__ownerID = newList.__ownerID = omap.__ownerID;\n\t        }\n\t      } else {\n\t        newMap = map.remove(k);\n\t        newList = i === list.size - 1 ? list.pop() : list.set(i, undefined);\n\t      }\n\t    } else {\n\t      if (has) {\n\t        if (v === list.get(i)[1]) {\n\t          return omap;\n\t        }\n\t        newMap = map;\n\t        newList = list.set(i, [k, v]);\n\t      } else {\n\t        newMap = map.set(k, list.size);\n\t        newList = list.set(list.size, [k, v]);\n\t      }\n\t    }\n\t    if (omap.__ownerID) {\n\t      omap.size = newMap.size;\n\t      omap._map = newMap;\n\t      omap._list = newList;\n\t      omap.__hash = undefined;\n\t      return omap;\n\t    }\n\t    return makeOrderedMap(newMap, newList);\n\t  }\n\n\t  createClass(ToKeyedSequence, KeyedSeq);\n\t    function ToKeyedSequence(indexed, useKeys) {\n\t      this._iter = indexed;\n\t      this._useKeys = useKeys;\n\t      this.size = indexed.size;\n\t    }\n\n\t    ToKeyedSequence.prototype.get = function(key, notSetValue) {\n\t      return this._iter.get(key, notSetValue);\n\t    };\n\n\t    ToKeyedSequence.prototype.has = function(key) {\n\t      return this._iter.has(key);\n\t    };\n\n\t    ToKeyedSequence.prototype.valueSeq = function() {\n\t      return this._iter.valueSeq();\n\t    };\n\n\t    ToKeyedSequence.prototype.reverse = function() {var this$0 = this;\n\t      var reversedSequence = reverseFactory(this, true);\n\t      if (!this._useKeys) {\n\t        reversedSequence.valueSeq = function()  {return this$0._iter.toSeq().reverse()};\n\t      }\n\t      return reversedSequence;\n\t    };\n\n\t    ToKeyedSequence.prototype.map = function(mapper, context) {var this$0 = this;\n\t      var mappedSequence = mapFactory(this, mapper, context);\n\t      if (!this._useKeys) {\n\t        mappedSequence.valueSeq = function()  {return this$0._iter.toSeq().map(mapper, context)};\n\t      }\n\t      return mappedSequence;\n\t    };\n\n\t    ToKeyedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;\n\t      var ii;\n\t      return this._iter.__iterate(\n\t        this._useKeys ?\n\t          function(v, k)  {return fn(v, k, this$0)} :\n\t          ((ii = reverse ? resolveSize(this) : 0),\n\t            function(v ) {return fn(v, reverse ? --ii : ii++, this$0)}),\n\t        reverse\n\t      );\n\t    };\n\n\t    ToKeyedSequence.prototype.__iterator = function(type, reverse) {\n\t      if (this._useKeys) {\n\t        return this._iter.__iterator(type, reverse);\n\t      }\n\t      var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);\n\t      var ii = reverse ? resolveSize(this) : 0;\n\t      return new Iterator(function()  {\n\t        var step = iterator.next();\n\t        return step.done ? step :\n\t          iteratorValue(type, reverse ? --ii : ii++, step.value, step);\n\t      });\n\t    };\n\n\t  ToKeyedSequence.prototype[IS_ORDERED_SENTINEL] = true;\n\n\n\t  createClass(ToIndexedSequence, IndexedSeq);\n\t    function ToIndexedSequence(iter) {\n\t      this._iter = iter;\n\t      this.size = iter.size;\n\t    }\n\n\t    ToIndexedSequence.prototype.includes = function(value) {\n\t      return this._iter.includes(value);\n\t    };\n\n\t    ToIndexedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;\n\t      var iterations = 0;\n\t      return this._iter.__iterate(function(v ) {return fn(v, iterations++, this$0)}, reverse);\n\t    };\n\n\t    ToIndexedSequence.prototype.__iterator = function(type, reverse) {\n\t      var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);\n\t      var iterations = 0;\n\t      return new Iterator(function()  {\n\t        var step = iterator.next();\n\t        return step.done ? step :\n\t          iteratorValue(type, iterations++, step.value, step)\n\t      });\n\t    };\n\n\n\n\t  createClass(ToSetSequence, SetSeq);\n\t    function ToSetSequence(iter) {\n\t      this._iter = iter;\n\t      this.size = iter.size;\n\t    }\n\n\t    ToSetSequence.prototype.has = function(key) {\n\t      return this._iter.includes(key);\n\t    };\n\n\t    ToSetSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;\n\t      return this._iter.__iterate(function(v ) {return fn(v, v, this$0)}, reverse);\n\t    };\n\n\t    ToSetSequence.prototype.__iterator = function(type, reverse) {\n\t      var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);\n\t      return new Iterator(function()  {\n\t        var step = iterator.next();\n\t        return step.done ? step :\n\t          iteratorValue(type, step.value, step.value, step);\n\t      });\n\t    };\n\n\n\n\t  createClass(FromEntriesSequence, KeyedSeq);\n\t    function FromEntriesSequence(entries) {\n\t      this._iter = entries;\n\t      this.size = entries.size;\n\t    }\n\n\t    FromEntriesSequence.prototype.entrySeq = function() {\n\t      return this._iter.toSeq();\n\t    };\n\n\t    FromEntriesSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;\n\t      return this._iter.__iterate(function(entry ) {\n\t        // Check if entry exists first so array access doesn't throw for holes\n\t        // in the parent iteration.\n\t        if (entry) {\n\t          validateEntry(entry);\n\t          var indexedIterable = isIterable(entry);\n\t          return fn(\n\t            indexedIterable ? entry.get(1) : entry[1],\n\t            indexedIterable ? entry.get(0) : entry[0],\n\t            this$0\n\t          );\n\t        }\n\t      }, reverse);\n\t    };\n\n\t    FromEntriesSequence.prototype.__iterator = function(type, reverse) {\n\t      var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);\n\t      return new Iterator(function()  {\n\t        while (true) {\n\t          var step = iterator.next();\n\t          if (step.done) {\n\t            return step;\n\t          }\n\t          var entry = step.value;\n\t          // Check if entry exists first so array access doesn't throw for holes\n\t          // in the parent iteration.\n\t          if (entry) {\n\t            validateEntry(entry);\n\t            var indexedIterable = isIterable(entry);\n\t            return iteratorValue(\n\t              type,\n\t              indexedIterable ? entry.get(0) : entry[0],\n\t              indexedIterable ? entry.get(1) : entry[1],\n\t              step\n\t            );\n\t          }\n\t        }\n\t      });\n\t    };\n\n\n\t  ToIndexedSequence.prototype.cacheResult =\n\t  ToKeyedSequence.prototype.cacheResult =\n\t  ToSetSequence.prototype.cacheResult =\n\t  FromEntriesSequence.prototype.cacheResult =\n\t    cacheResultThrough;\n\n\n\t  function flipFactory(iterable) {\n\t    var flipSequence = makeSequence(iterable);\n\t    flipSequence._iter = iterable;\n\t    flipSequence.size = iterable.size;\n\t    flipSequence.flip = function()  {return iterable};\n\t    flipSequence.reverse = function () {\n\t      var reversedSequence = iterable.reverse.apply(this); // super.reverse()\n\t      reversedSequence.flip = function()  {return iterable.reverse()};\n\t      return reversedSequence;\n\t    };\n\t    flipSequence.has = function(key ) {return iterable.includes(key)};\n\t    flipSequence.includes = function(key ) {return iterable.has(key)};\n\t    flipSequence.cacheResult = cacheResultThrough;\n\t    flipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;\n\t      return iterable.__iterate(function(v, k)  {return fn(k, v, this$0) !== false}, reverse);\n\t    }\n\t    flipSequence.__iteratorUncached = function(type, reverse) {\n\t      if (type === ITERATE_ENTRIES) {\n\t        var iterator = iterable.__iterator(type, reverse);\n\t        return new Iterator(function()  {\n\t          var step = iterator.next();\n\t          if (!step.done) {\n\t            var k = step.value[0];\n\t            step.value[0] = step.value[1];\n\t            step.value[1] = k;\n\t          }\n\t          return step;\n\t        });\n\t      }\n\t      return iterable.__iterator(\n\t        type === ITERATE_VALUES ? ITERATE_KEYS : ITERATE_VALUES,\n\t        reverse\n\t      );\n\t    }\n\t    return flipSequence;\n\t  }\n\n\n\t  function mapFactory(iterable, mapper, context) {\n\t    var mappedSequence = makeSequence(iterable);\n\t    mappedSequence.size = iterable.size;\n\t    mappedSequence.has = function(key ) {return iterable.has(key)};\n\t    mappedSequence.get = function(key, notSetValue)  {\n\t      var v = iterable.get(key, NOT_SET);\n\t      return v === NOT_SET ?\n\t        notSetValue :\n\t        mapper.call(context, v, key, iterable);\n\t    };\n\t    mappedSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;\n\t      return iterable.__iterate(\n\t        function(v, k, c)  {return fn(mapper.call(context, v, k, c), k, this$0) !== false},\n\t        reverse\n\t      );\n\t    }\n\t    mappedSequence.__iteratorUncached = function (type, reverse) {\n\t      var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);\n\t      return new Iterator(function()  {\n\t        var step = iterator.next();\n\t        if (step.done) {\n\t          return step;\n\t        }\n\t        var entry = step.value;\n\t        var key = entry[0];\n\t        return iteratorValue(\n\t          type,\n\t          key,\n\t          mapper.call(context, entry[1], key, iterable),\n\t          step\n\t        );\n\t      });\n\t    }\n\t    return mappedSequence;\n\t  }\n\n\n\t  function reverseFactory(iterable, useKeys) {\n\t    var reversedSequence = makeSequence(iterable);\n\t    reversedSequence._iter = iterable;\n\t    reversedSequence.size = iterable.size;\n\t    reversedSequence.reverse = function()  {return iterable};\n\t    if (iterable.flip) {\n\t      reversedSequence.flip = function () {\n\t        var flipSequence = flipFactory(iterable);\n\t        flipSequence.reverse = function()  {return iterable.flip()};\n\t        return flipSequence;\n\t      };\n\t    }\n\t    reversedSequence.get = function(key, notSetValue) \n\t      {return iterable.get(useKeys ? key : -1 - key, notSetValue)};\n\t    reversedSequence.has = function(key )\n\t      {return iterable.has(useKeys ? key : -1 - key)};\n\t    reversedSequence.includes = function(value ) {return iterable.includes(value)};\n\t    reversedSequence.cacheResult = cacheResultThrough;\n\t    reversedSequence.__iterate = function (fn, reverse) {var this$0 = this;\n\t      return iterable.__iterate(function(v, k)  {return fn(v, k, this$0)}, !reverse);\n\t    };\n\t    reversedSequence.__iterator =\n\t      function(type, reverse)  {return iterable.__iterator(type, !reverse)};\n\t    return reversedSequence;\n\t  }\n\n\n\t  function filterFactory(iterable, predicate, context, useKeys) {\n\t    var filterSequence = makeSequence(iterable);\n\t    if (useKeys) {\n\t      filterSequence.has = function(key ) {\n\t        var v = iterable.get(key, NOT_SET);\n\t        return v !== NOT_SET && !!predicate.call(context, v, key, iterable);\n\t      };\n\t      filterSequence.get = function(key, notSetValue)  {\n\t        var v = iterable.get(key, NOT_SET);\n\t        return v !== NOT_SET && predicate.call(context, v, key, iterable) ?\n\t          v : notSetValue;\n\t      };\n\t    }\n\t    filterSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;\n\t      var iterations = 0;\n\t      iterable.__iterate(function(v, k, c)  {\n\t        if (predicate.call(context, v, k, c)) {\n\t          iterations++;\n\t          return fn(v, useKeys ? k : iterations - 1, this$0);\n\t        }\n\t      }, reverse);\n\t      return iterations;\n\t    };\n\t    filterSequence.__iteratorUncached = function (type, reverse) {\n\t      var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);\n\t      var iterations = 0;\n\t      return new Iterator(function()  {\n\t        while (true) {\n\t          var step = iterator.next();\n\t          if (step.done) {\n\t            return step;\n\t          }\n\t          var entry = step.value;\n\t          var key = entry[0];\n\t          var value = entry[1];\n\t          if (predicate.call(context, value, key, iterable)) {\n\t            return iteratorValue(type, useKeys ? key : iterations++, value, step);\n\t          }\n\t        }\n\t      });\n\t    }\n\t    return filterSequence;\n\t  }\n\n\n\t  function countByFactory(iterable, grouper, context) {\n\t    var groups = Map().asMutable();\n\t    iterable.__iterate(function(v, k)  {\n\t      groups.update(\n\t        grouper.call(context, v, k, iterable),\n\t        0,\n\t        function(a ) {return a + 1}\n\t      );\n\t    });\n\t    return groups.asImmutable();\n\t  }\n\n\n\t  function groupByFactory(iterable, grouper, context) {\n\t    var isKeyedIter = isKeyed(iterable);\n\t    var groups = (isOrdered(iterable) ? OrderedMap() : Map()).asMutable();\n\t    iterable.__iterate(function(v, k)  {\n\t      groups.update(\n\t        grouper.call(context, v, k, iterable),\n\t        function(a ) {return (a = a || [], a.push(isKeyedIter ? [k, v] : v), a)}\n\t      );\n\t    });\n\t    var coerce = iterableClass(iterable);\n\t    return groups.map(function(arr ) {return reify(iterable, coerce(arr))});\n\t  }\n\n\n\t  function sliceFactory(iterable, begin, end, useKeys) {\n\t    var originalSize = iterable.size;\n\n\t    // Sanitize begin & end using this shorthand for ToInt32(argument)\n\t    // http://www.ecma-international.org/ecma-262/6.0/#sec-toint32\n\t    if (begin !== undefined) {\n\t      begin = begin | 0;\n\t    }\n\t    if (end !== undefined) {\n\t      if (end === Infinity) {\n\t        end = originalSize;\n\t      } else {\n\t        end = end | 0;\n\t      }\n\t    }\n\n\t    if (wholeSlice(begin, end, originalSize)) {\n\t      return iterable;\n\t    }\n\n\t    var resolvedBegin = resolveBegin(begin, originalSize);\n\t    var resolvedEnd = resolveEnd(end, originalSize);\n\n\t    // begin or end will be NaN if they were provided as negative numbers and\n\t    // this iterable's size is unknown. In that case, cache first so there is\n\t    // a known size and these do not resolve to NaN.\n\t    if (resolvedBegin !== resolvedBegin || resolvedEnd !== resolvedEnd) {\n\t      return sliceFactory(iterable.toSeq().cacheResult(), begin, end, useKeys);\n\t    }\n\n\t    // Note: resolvedEnd is undefined when the original sequence's length is\n\t    // unknown and this slice did not supply an end and should contain all\n\t    // elements after resolvedBegin.\n\t    // In that case, resolvedSize will be NaN and sliceSize will remain undefined.\n\t    var resolvedSize = resolvedEnd - resolvedBegin;\n\t    var sliceSize;\n\t    if (resolvedSize === resolvedSize) {\n\t      sliceSize = resolvedSize < 0 ? 0 : resolvedSize;\n\t    }\n\n\t    var sliceSeq = makeSequence(iterable);\n\n\t    // If iterable.size is undefined, the size of the realized sliceSeq is\n\t    // unknown at this point unless the number of items to slice is 0\n\t    sliceSeq.size = sliceSize === 0 ? sliceSize : iterable.size && sliceSize || undefined;\n\n\t    if (!useKeys && isSeq(iterable) && sliceSize >= 0) {\n\t      sliceSeq.get = function (index, notSetValue) {\n\t        index = wrapIndex(this, index);\n\t        return index >= 0 && index < sliceSize ?\n\t          iterable.get(index + resolvedBegin, notSetValue) :\n\t          notSetValue;\n\t      }\n\t    }\n\n\t    sliceSeq.__iterateUncached = function(fn, reverse) {var this$0 = this;\n\t      if (sliceSize === 0) {\n\t        return 0;\n\t      }\n\t      if (reverse) {\n\t        return this.cacheResult().__iterate(fn, reverse);\n\t      }\n\t      var skipped = 0;\n\t      var isSkipping = true;\n\t      var iterations = 0;\n\t      iterable.__iterate(function(v, k)  {\n\t        if (!(isSkipping && (isSkipping = skipped++ < resolvedBegin))) {\n\t          iterations++;\n\t          return fn(v, useKeys ? k : iterations - 1, this$0) !== false &&\n\t                 iterations !== sliceSize;\n\t        }\n\t      });\n\t      return iterations;\n\t    };\n\n\t    sliceSeq.__iteratorUncached = function(type, reverse) {\n\t      if (sliceSize !== 0 && reverse) {\n\t        return this.cacheResult().__iterator(type, reverse);\n\t      }\n\t      // Don't bother instantiating parent iterator if taking 0.\n\t      var iterator = sliceSize !== 0 && iterable.__iterator(type, reverse);\n\t      var skipped = 0;\n\t      var iterations = 0;\n\t      return new Iterator(function()  {\n\t        while (skipped++ < resolvedBegin) {\n\t          iterator.next();\n\t        }\n\t        if (++iterations > sliceSize) {\n\t          return iteratorDone();\n\t        }\n\t        var step = iterator.next();\n\t        if (useKeys || type === ITERATE_VALUES) {\n\t          return step;\n\t        } else if (type === ITERATE_KEYS) {\n\t          return iteratorValue(type, iterations - 1, undefined, step);\n\t        } else {\n\t          return iteratorValue(type, iterations - 1, step.value[1], step);\n\t        }\n\t      });\n\t    }\n\n\t    return sliceSeq;\n\t  }\n\n\n\t  function takeWhileFactory(iterable, predicate, context) {\n\t    var takeSequence = makeSequence(iterable);\n\t    takeSequence.__iterateUncached = function(fn, reverse) {var this$0 = this;\n\t      if (reverse) {\n\t        return this.cacheResult().__iterate(fn, reverse);\n\t      }\n\t      var iterations = 0;\n\t      iterable.__iterate(function(v, k, c) \n\t        {return predicate.call(context, v, k, c) && ++iterations && fn(v, k, this$0)}\n\t      );\n\t      return iterations;\n\t    };\n\t    takeSequence.__iteratorUncached = function(type, reverse) {var this$0 = this;\n\t      if (reverse) {\n\t        return this.cacheResult().__iterator(type, reverse);\n\t      }\n\t      var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);\n\t      var iterating = true;\n\t      return new Iterator(function()  {\n\t        if (!iterating) {\n\t          return iteratorDone();\n\t        }\n\t        var step = iterator.next();\n\t        if (step.done) {\n\t          return step;\n\t        }\n\t        var entry = step.value;\n\t        var k = entry[0];\n\t        var v = entry[1];\n\t        if (!predicate.call(context, v, k, this$0)) {\n\t          iterating = false;\n\t          return iteratorDone();\n\t        }\n\t        return type === ITERATE_ENTRIES ? step :\n\t          iteratorValue(type, k, v, step);\n\t      });\n\t    };\n\t    return takeSequence;\n\t  }\n\n\n\t  function skipWhileFactory(iterable, predicate, context, useKeys) {\n\t    var skipSequence = makeSequence(iterable);\n\t    skipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;\n\t      if (reverse) {\n\t        return this.cacheResult().__iterate(fn, reverse);\n\t      }\n\t      var isSkipping = true;\n\t      var iterations = 0;\n\t      iterable.__iterate(function(v, k, c)  {\n\t        if (!(isSkipping && (isSkipping = predicate.call(context, v, k, c)))) {\n\t          iterations++;\n\t          return fn(v, useKeys ? k : iterations - 1, this$0);\n\t        }\n\t      });\n\t      return iterations;\n\t    };\n\t    skipSequence.__iteratorUncached = function(type, reverse) {var this$0 = this;\n\t      if (reverse) {\n\t        return this.cacheResult().__iterator(type, reverse);\n\t      }\n\t      var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);\n\t      var skipping = true;\n\t      var iterations = 0;\n\t      return new Iterator(function()  {\n\t        var step, k, v;\n\t        do {\n\t          step = iterator.next();\n\t          if (step.done) {\n\t            if (useKeys || type === ITERATE_VALUES) {\n\t              return step;\n\t            } else if (type === ITERATE_KEYS) {\n\t              return iteratorValue(type, iterations++, undefined, step);\n\t            } else {\n\t              return iteratorValue(type, iterations++, step.value[1], step);\n\t            }\n\t          }\n\t          var entry = step.value;\n\t          k = entry[0];\n\t          v = entry[1];\n\t          skipping && (skipping = predicate.call(context, v, k, this$0));\n\t        } while (skipping);\n\t        return type === ITERATE_ENTRIES ? step :\n\t          iteratorValue(type, k, v, step);\n\t      });\n\t    };\n\t    return skipSequence;\n\t  }\n\n\n\t  function concatFactory(iterable, values) {\n\t    var isKeyedIterable = isKeyed(iterable);\n\t    var iters = [iterable].concat(values).map(function(v ) {\n\t      if (!isIterable(v)) {\n\t        v = isKeyedIterable ?\n\t          keyedSeqFromValue(v) :\n\t          indexedSeqFromValue(Array.isArray(v) ? v : [v]);\n\t      } else if (isKeyedIterable) {\n\t        v = KeyedIterable(v);\n\t      }\n\t      return v;\n\t    }).filter(function(v ) {return v.size !== 0});\n\n\t    if (iters.length === 0) {\n\t      return iterable;\n\t    }\n\n\t    if (iters.length === 1) {\n\t      var singleton = iters[0];\n\t      if (singleton === iterable ||\n\t          isKeyedIterable && isKeyed(singleton) ||\n\t          isIndexed(iterable) && isIndexed(singleton)) {\n\t        return singleton;\n\t      }\n\t    }\n\n\t    var concatSeq = new ArraySeq(iters);\n\t    if (isKeyedIterable) {\n\t      concatSeq = concatSeq.toKeyedSeq();\n\t    } else if (!isIndexed(iterable)) {\n\t      concatSeq = concatSeq.toSetSeq();\n\t    }\n\t    concatSeq = concatSeq.flatten(true);\n\t    concatSeq.size = iters.reduce(\n\t      function(sum, seq)  {\n\t        if (sum !== undefined) {\n\t          var size = seq.size;\n\t          if (size !== undefined) {\n\t            return sum + size;\n\t          }\n\t        }\n\t      },\n\t      0\n\t    );\n\t    return concatSeq;\n\t  }\n\n\n\t  function flattenFactory(iterable, depth, useKeys) {\n\t    var flatSequence = makeSequence(iterable);\n\t    flatSequence.__iterateUncached = function(fn, reverse) {\n\t      var iterations = 0;\n\t      var stopped = false;\n\t      function flatDeep(iter, currentDepth) {var this$0 = this;\n\t        iter.__iterate(function(v, k)  {\n\t          if ((!depth || currentDepth < depth) && isIterable(v)) {\n\t            flatDeep(v, currentDepth + 1);\n\t          } else if (fn(v, useKeys ? k : iterations++, this$0) === false) {\n\t            stopped = true;\n\t          }\n\t          return !stopped;\n\t        }, reverse);\n\t      }\n\t      flatDeep(iterable, 0);\n\t      return iterations;\n\t    }\n\t    flatSequence.__iteratorUncached = function(type, reverse) {\n\t      var iterator = iterable.__iterator(type, reverse);\n\t      var stack = [];\n\t      var iterations = 0;\n\t      return new Iterator(function()  {\n\t        while (iterator) {\n\t          var step = iterator.next();\n\t          if (step.done !== false) {\n\t            iterator = stack.pop();\n\t            continue;\n\t          }\n\t          var v = step.value;\n\t          if (type === ITERATE_ENTRIES) {\n\t            v = v[1];\n\t          }\n\t          if ((!depth || stack.length < depth) && isIterable(v)) {\n\t            stack.push(iterator);\n\t            iterator = v.__iterator(type, reverse);\n\t          } else {\n\t            return useKeys ? step : iteratorValue(type, iterations++, v, step);\n\t          }\n\t        }\n\t        return iteratorDone();\n\t      });\n\t    }\n\t    return flatSequence;\n\t  }\n\n\n\t  function flatMapFactory(iterable, mapper, context) {\n\t    var coerce = iterableClass(iterable);\n\t    return iterable.toSeq().map(\n\t      function(v, k)  {return coerce(mapper.call(context, v, k, iterable))}\n\t    ).flatten(true);\n\t  }\n\n\n\t  function interposeFactory(iterable, separator) {\n\t    var interposedSequence = makeSequence(iterable);\n\t    interposedSequence.size = iterable.size && iterable.size * 2 -1;\n\t    interposedSequence.__iterateUncached = function(fn, reverse) {var this$0 = this;\n\t      var iterations = 0;\n\t      iterable.__iterate(function(v, k) \n\t        {return (!iterations || fn(separator, iterations++, this$0) !== false) &&\n\t        fn(v, iterations++, this$0) !== false},\n\t        reverse\n\t      );\n\t      return iterations;\n\t    };\n\t    interposedSequence.__iteratorUncached = function(type, reverse) {\n\t      var iterator = iterable.__iterator(ITERATE_VALUES, reverse);\n\t      var iterations = 0;\n\t      var step;\n\t      return new Iterator(function()  {\n\t        if (!step || iterations % 2) {\n\t          step = iterator.next();\n\t          if (step.done) {\n\t            return step;\n\t          }\n\t        }\n\t        return iterations % 2 ?\n\t          iteratorValue(type, iterations++, separator) :\n\t          iteratorValue(type, iterations++, step.value, step);\n\t      });\n\t    };\n\t    return interposedSequence;\n\t  }\n\n\n\t  function sortFactory(iterable, comparator, mapper) {\n\t    if (!comparator) {\n\t      comparator = defaultComparator;\n\t    }\n\t    var isKeyedIterable = isKeyed(iterable);\n\t    var index = 0;\n\t    var entries = iterable.toSeq().map(\n\t      function(v, k)  {return [k, v, index++, mapper ? mapper(v, k, iterable) : v]}\n\t    ).toArray();\n\t    entries.sort(function(a, b)  {return comparator(a[3], b[3]) || a[2] - b[2]}).forEach(\n\t      isKeyedIterable ?\n\t      function(v, i)  { entries[i].length = 2; } :\n\t      function(v, i)  { entries[i] = v[1]; }\n\t    );\n\t    return isKeyedIterable ? KeyedSeq(entries) :\n\t      isIndexed(iterable) ? IndexedSeq(entries) :\n\t      SetSeq(entries);\n\t  }\n\n\n\t  function maxFactory(iterable, comparator, mapper) {\n\t    if (!comparator) {\n\t      comparator = defaultComparator;\n\t    }\n\t    if (mapper) {\n\t      var entry = iterable.toSeq()\n\t        .map(function(v, k)  {return [v, mapper(v, k, iterable)]})\n\t        .reduce(function(a, b)  {return maxCompare(comparator, a[1], b[1]) ? b : a});\n\t      return entry && entry[0];\n\t    } else {\n\t      return iterable.reduce(function(a, b)  {return maxCompare(comparator, a, b) ? b : a});\n\t    }\n\t  }\n\n\t  function maxCompare(comparator, a, b) {\n\t    var comp = comparator(b, a);\n\t    // b is considered the new max if the comparator declares them equal, but\n\t    // they are not equal and b is in fact a nullish value.\n\t    return (comp === 0 && b !== a && (b === undefined || b === null || b !== b)) || comp > 0;\n\t  }\n\n\n\t  function zipWithFactory(keyIter, zipper, iters) {\n\t    var zipSequence = makeSequence(keyIter);\n\t    zipSequence.size = new ArraySeq(iters).map(function(i ) {return i.size}).min();\n\t    // Note: this a generic base implementation of __iterate in terms of\n\t    // __iterator which may be more generically useful in the future.\n\t    zipSequence.__iterate = function(fn, reverse) {\n\t      /* generic:\n\t      var iterator = this.__iterator(ITERATE_ENTRIES, reverse);\n\t      var step;\n\t      var iterations = 0;\n\t      while (!(step = iterator.next()).done) {\n\t        iterations++;\n\t        if (fn(step.value[1], step.value[0], this) === false) {\n\t          break;\n\t        }\n\t      }\n\t      return iterations;\n\t      */\n\t      // indexed:\n\t      var iterator = this.__iterator(ITERATE_VALUES, reverse);\n\t      var step;\n\t      var iterations = 0;\n\t      while (!(step = iterator.next()).done) {\n\t        if (fn(step.value, iterations++, this) === false) {\n\t          break;\n\t        }\n\t      }\n\t      return iterations;\n\t    };\n\t    zipSequence.__iteratorUncached = function(type, reverse) {\n\t      var iterators = iters.map(function(i )\n\t        {return (i = Iterable(i), getIterator(reverse ? i.reverse() : i))}\n\t      );\n\t      var iterations = 0;\n\t      var isDone = false;\n\t      return new Iterator(function()  {\n\t        var steps;\n\t        if (!isDone) {\n\t          steps = iterators.map(function(i ) {return i.next()});\n\t          isDone = steps.some(function(s ) {return s.done});\n\t        }\n\t        if (isDone) {\n\t          return iteratorDone();\n\t        }\n\t        return iteratorValue(\n\t          type,\n\t          iterations++,\n\t          zipper.apply(null, steps.map(function(s ) {return s.value}))\n\t        );\n\t      });\n\t    };\n\t    return zipSequence\n\t  }\n\n\n\t  // #pragma Helper Functions\n\n\t  function reify(iter, seq) {\n\t    return isSeq(iter) ? seq : iter.constructor(seq);\n\t  }\n\n\t  function validateEntry(entry) {\n\t    if (entry !== Object(entry)) {\n\t      throw new TypeError('Expected [K, V] tuple: ' + entry);\n\t    }\n\t  }\n\n\t  function resolveSize(iter) {\n\t    assertNotInfinite(iter.size);\n\t    return ensureSize(iter);\n\t  }\n\n\t  function iterableClass(iterable) {\n\t    return isKeyed(iterable) ? KeyedIterable :\n\t      isIndexed(iterable) ? IndexedIterable :\n\t      SetIterable;\n\t  }\n\n\t  function makeSequence(iterable) {\n\t    return Object.create(\n\t      (\n\t        isKeyed(iterable) ? KeyedSeq :\n\t        isIndexed(iterable) ? IndexedSeq :\n\t        SetSeq\n\t      ).prototype\n\t    );\n\t  }\n\n\t  function cacheResultThrough() {\n\t    if (this._iter.cacheResult) {\n\t      this._iter.cacheResult();\n\t      this.size = this._iter.size;\n\t      return this;\n\t    } else {\n\t      return Seq.prototype.cacheResult.call(this);\n\t    }\n\t  }\n\n\t  function defaultComparator(a, b) {\n\t    return a > b ? 1 : a < b ? -1 : 0;\n\t  }\n\n\t  function forceIterator(keyPath) {\n\t    var iter = getIterator(keyPath);\n\t    if (!iter) {\n\t      // Array might not be iterable in this environment, so we need a fallback\n\t      // to our wrapped type.\n\t      if (!isArrayLike(keyPath)) {\n\t        throw new TypeError('Expected iterable or array-like: ' + keyPath);\n\t      }\n\t      iter = getIterator(Iterable(keyPath));\n\t    }\n\t    return iter;\n\t  }\n\n\t  createClass(Record, KeyedCollection);\n\n\t    function Record(defaultValues, name) {\n\t      var hasInitialized;\n\n\t      var RecordType = function Record(values) {\n\t        if (values instanceof RecordType) {\n\t          return values;\n\t        }\n\t        if (!(this instanceof RecordType)) {\n\t          return new RecordType(values);\n\t        }\n\t        if (!hasInitialized) {\n\t          hasInitialized = true;\n\t          var keys = Object.keys(defaultValues);\n\t          setProps(RecordTypePrototype, keys);\n\t          RecordTypePrototype.size = keys.length;\n\t          RecordTypePrototype._name = name;\n\t          RecordTypePrototype._keys = keys;\n\t          RecordTypePrototype._defaultValues = defaultValues;\n\t        }\n\t        this._map = Map(values);\n\t      };\n\n\t      var RecordTypePrototype = RecordType.prototype = Object.create(RecordPrototype);\n\t      RecordTypePrototype.constructor = RecordType;\n\n\t      return RecordType;\n\t    }\n\n\t    Record.prototype.toString = function() {\n\t      return this.__toString(recordName(this) + ' {', '}');\n\t    };\n\n\t    // @pragma Access\n\n\t    Record.prototype.has = function(k) {\n\t      return this._defaultValues.hasOwnProperty(k);\n\t    };\n\n\t    Record.prototype.get = function(k, notSetValue) {\n\t      if (!this.has(k)) {\n\t        return notSetValue;\n\t      }\n\t      var defaultVal = this._defaultValues[k];\n\t      return this._map ? this._map.get(k, defaultVal) : defaultVal;\n\t    };\n\n\t    // @pragma Modification\n\n\t    Record.prototype.clear = function() {\n\t      if (this.__ownerID) {\n\t        this._map && this._map.clear();\n\t        return this;\n\t      }\n\t      var RecordType = this.constructor;\n\t      return RecordType._empty || (RecordType._empty = makeRecord(this, emptyMap()));\n\t    };\n\n\t    Record.prototype.set = function(k, v) {\n\t      if (!this.has(k)) {\n\t        throw new Error('Cannot set unknown key \"' + k + '\" on ' + recordName(this));\n\t      }\n\t      if (this._map && !this._map.has(k)) {\n\t        var defaultVal = this._defaultValues[k];\n\t        if (v === defaultVal) {\n\t          return this;\n\t        }\n\t      }\n\t      var newMap = this._map && this._map.set(k, v);\n\t      if (this.__ownerID || newMap === this._map) {\n\t        return this;\n\t      }\n\t      return makeRecord(this, newMap);\n\t    };\n\n\t    Record.prototype.remove = function(k) {\n\t      if (!this.has(k)) {\n\t        return this;\n\t      }\n\t      var newMap = this._map && this._map.remove(k);\n\t      if (this.__ownerID || newMap === this._map) {\n\t        return this;\n\t      }\n\t      return makeRecord(this, newMap);\n\t    };\n\n\t    Record.prototype.wasAltered = function() {\n\t      return this._map.wasAltered();\n\t    };\n\n\t    Record.prototype.__iterator = function(type, reverse) {var this$0 = this;\n\t      return KeyedIterable(this._defaultValues).map(function(_, k)  {return this$0.get(k)}).__iterator(type, reverse);\n\t    };\n\n\t    Record.prototype.__iterate = function(fn, reverse) {var this$0 = this;\n\t      return KeyedIterable(this._defaultValues).map(function(_, k)  {return this$0.get(k)}).__iterate(fn, reverse);\n\t    };\n\n\t    Record.prototype.__ensureOwner = function(ownerID) {\n\t      if (ownerID === this.__ownerID) {\n\t        return this;\n\t      }\n\t      var newMap = this._map && this._map.__ensureOwner(ownerID);\n\t      if (!ownerID) {\n\t        this.__ownerID = ownerID;\n\t        this._map = newMap;\n\t        return this;\n\t      }\n\t      return makeRecord(this, newMap, ownerID);\n\t    };\n\n\n\t  var RecordPrototype = Record.prototype;\n\t  RecordPrototype[DELETE] = RecordPrototype.remove;\n\t  RecordPrototype.deleteIn =\n\t  RecordPrototype.removeIn = MapPrototype.removeIn;\n\t  RecordPrototype.merge = MapPrototype.merge;\n\t  RecordPrototype.mergeWith = MapPrototype.mergeWith;\n\t  RecordPrototype.mergeIn = MapPrototype.mergeIn;\n\t  RecordPrototype.mergeDeep = MapPrototype.mergeDeep;\n\t  RecordPrototype.mergeDeepWith = MapPrototype.mergeDeepWith;\n\t  RecordPrototype.mergeDeepIn = MapPrototype.mergeDeepIn;\n\t  RecordPrototype.setIn = MapPrototype.setIn;\n\t  RecordPrototype.update = MapPrototype.update;\n\t  RecordPrototype.updateIn = MapPrototype.updateIn;\n\t  RecordPrototype.withMutations = MapPrototype.withMutations;\n\t  RecordPrototype.asMutable = MapPrototype.asMutable;\n\t  RecordPrototype.asImmutable = MapPrototype.asImmutable;\n\n\n\t  function makeRecord(likeRecord, map, ownerID) {\n\t    var record = Object.create(Object.getPrototypeOf(likeRecord));\n\t    record._map = map;\n\t    record.__ownerID = ownerID;\n\t    return record;\n\t  }\n\n\t  function recordName(record) {\n\t    return record._name || record.constructor.name || 'Record';\n\t  }\n\n\t  function setProps(prototype, names) {\n\t    try {\n\t      names.forEach(setProp.bind(undefined, prototype));\n\t    } catch (error) {\n\t      // Object.defineProperty failed. Probably IE8.\n\t    }\n\t  }\n\n\t  function setProp(prototype, name) {\n\t    Object.defineProperty(prototype, name, {\n\t      get: function() {\n\t        return this.get(name);\n\t      },\n\t      set: function(value) {\n\t        invariant(this.__ownerID, 'Cannot set on an immutable record.');\n\t        this.set(name, value);\n\t      }\n\t    });\n\t  }\n\n\t  createClass(Set, SetCollection);\n\n\t    // @pragma Construction\n\n\t    function Set(value) {\n\t      return value === null || value === undefined ? emptySet() :\n\t        isSet(value) && !isOrdered(value) ? value :\n\t        emptySet().withMutations(function(set ) {\n\t          var iter = SetIterable(value);\n\t          assertNotInfinite(iter.size);\n\t          iter.forEach(function(v ) {return set.add(v)});\n\t        });\n\t    }\n\n\t    Set.of = function(/*...values*/) {\n\t      return this(arguments);\n\t    };\n\n\t    Set.fromKeys = function(value) {\n\t      return this(KeyedIterable(value).keySeq());\n\t    };\n\n\t    Set.prototype.toString = function() {\n\t      return this.__toString('Set {', '}');\n\t    };\n\n\t    // @pragma Access\n\n\t    Set.prototype.has = function(value) {\n\t      return this._map.has(value);\n\t    };\n\n\t    // @pragma Modification\n\n\t    Set.prototype.add = function(value) {\n\t      return updateSet(this, this._map.set(value, true));\n\t    };\n\n\t    Set.prototype.remove = function(value) {\n\t      return updateSet(this, this._map.remove(value));\n\t    };\n\n\t    Set.prototype.clear = function() {\n\t      return updateSet(this, this._map.clear());\n\t    };\n\n\t    // @pragma Composition\n\n\t    Set.prototype.union = function() {var iters = SLICE$0.call(arguments, 0);\n\t      iters = iters.filter(function(x ) {return x.size !== 0});\n\t      if (iters.length === 0) {\n\t        return this;\n\t      }\n\t      if (this.size === 0 && !this.__ownerID && iters.length === 1) {\n\t        return this.constructor(iters[0]);\n\t      }\n\t      return this.withMutations(function(set ) {\n\t        for (var ii = 0; ii < iters.length; ii++) {\n\t          SetIterable(iters[ii]).forEach(function(value ) {return set.add(value)});\n\t        }\n\t      });\n\t    };\n\n\t    Set.prototype.intersect = function() {var iters = SLICE$0.call(arguments, 0);\n\t      if (iters.length === 0) {\n\t        return this;\n\t      }\n\t      iters = iters.map(function(iter ) {return SetIterable(iter)});\n\t      var originalSet = this;\n\t      return this.withMutations(function(set ) {\n\t        originalSet.forEach(function(value ) {\n\t          if (!iters.every(function(iter ) {return iter.includes(value)})) {\n\t            set.remove(value);\n\t          }\n\t        });\n\t      });\n\t    };\n\n\t    Set.prototype.subtract = function() {var iters = SLICE$0.call(arguments, 0);\n\t      if (iters.length === 0) {\n\t        return this;\n\t      }\n\t      iters = iters.map(function(iter ) {return SetIterable(iter)});\n\t      var originalSet = this;\n\t      return this.withMutations(function(set ) {\n\t        originalSet.forEach(function(value ) {\n\t          if (iters.some(function(iter ) {return iter.includes(value)})) {\n\t            set.remove(value);\n\t          }\n\t        });\n\t      });\n\t    };\n\n\t    Set.prototype.merge = function() {\n\t      return this.union.apply(this, arguments);\n\t    };\n\n\t    Set.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1);\n\t      return this.union.apply(this, iters);\n\t    };\n\n\t    Set.prototype.sort = function(comparator) {\n\t      // Late binding\n\t      return OrderedSet(sortFactory(this, comparator));\n\t    };\n\n\t    Set.prototype.sortBy = function(mapper, comparator) {\n\t      // Late binding\n\t      return OrderedSet(sortFactory(this, comparator, mapper));\n\t    };\n\n\t    Set.prototype.wasAltered = function() {\n\t      return this._map.wasAltered();\n\t    };\n\n\t    Set.prototype.__iterate = function(fn, reverse) {var this$0 = this;\n\t      return this._map.__iterate(function(_, k)  {return fn(k, k, this$0)}, reverse);\n\t    };\n\n\t    Set.prototype.__iterator = function(type, reverse) {\n\t      return this._map.map(function(_, k)  {return k}).__iterator(type, reverse);\n\t    };\n\n\t    Set.prototype.__ensureOwner = function(ownerID) {\n\t      if (ownerID === this.__ownerID) {\n\t        return this;\n\t      }\n\t      var newMap = this._map.__ensureOwner(ownerID);\n\t      if (!ownerID) {\n\t        this.__ownerID = ownerID;\n\t        this._map = newMap;\n\t        return this;\n\t      }\n\t      return this.__make(newMap, ownerID);\n\t    };\n\n\n\t  function isSet(maybeSet) {\n\t    return !!(maybeSet && maybeSet[IS_SET_SENTINEL]);\n\t  }\n\n\t  Set.isSet = isSet;\n\n\t  var IS_SET_SENTINEL = '@@__IMMUTABLE_SET__@@';\n\n\t  var SetPrototype = Set.prototype;\n\t  SetPrototype[IS_SET_SENTINEL] = true;\n\t  SetPrototype[DELETE] = SetPrototype.remove;\n\t  SetPrototype.mergeDeep = SetPrototype.merge;\n\t  SetPrototype.mergeDeepWith = SetPrototype.mergeWith;\n\t  SetPrototype.withMutations = MapPrototype.withMutations;\n\t  SetPrototype.asMutable = MapPrototype.asMutable;\n\t  SetPrototype.asImmutable = MapPrototype.asImmutable;\n\n\t  SetPrototype.__empty = emptySet;\n\t  SetPrototype.__make = makeSet;\n\n\t  function updateSet(set, newMap) {\n\t    if (set.__ownerID) {\n\t      set.size = newMap.size;\n\t      set._map = newMap;\n\t      return set;\n\t    }\n\t    return newMap === set._map ? set :\n\t      newMap.size === 0 ? set.__empty() :\n\t      set.__make(newMap);\n\t  }\n\n\t  function makeSet(map, ownerID) {\n\t    var set = Object.create(SetPrototype);\n\t    set.size = map ? map.size : 0;\n\t    set._map = map;\n\t    set.__ownerID = ownerID;\n\t    return set;\n\t  }\n\n\t  var EMPTY_SET;\n\t  function emptySet() {\n\t    return EMPTY_SET || (EMPTY_SET = makeSet(emptyMap()));\n\t  }\n\n\t  createClass(OrderedSet, Set);\n\n\t    // @pragma Construction\n\n\t    function OrderedSet(value) {\n\t      return value === null || value === undefined ? emptyOrderedSet() :\n\t        isOrderedSet(value) ? value :\n\t        emptyOrderedSet().withMutations(function(set ) {\n\t          var iter = SetIterable(value);\n\t          assertNotInfinite(iter.size);\n\t          iter.forEach(function(v ) {return set.add(v)});\n\t        });\n\t    }\n\n\t    OrderedSet.of = function(/*...values*/) {\n\t      return this(arguments);\n\t    };\n\n\t    OrderedSet.fromKeys = function(value) {\n\t      return this(KeyedIterable(value).keySeq());\n\t    };\n\n\t    OrderedSet.prototype.toString = function() {\n\t      return this.__toString('OrderedSet {', '}');\n\t    };\n\n\n\t  function isOrderedSet(maybeOrderedSet) {\n\t    return isSet(maybeOrderedSet) && isOrdered(maybeOrderedSet);\n\t  }\n\n\t  OrderedSet.isOrderedSet = isOrderedSet;\n\n\t  var OrderedSetPrototype = OrderedSet.prototype;\n\t  OrderedSetPrototype[IS_ORDERED_SENTINEL] = true;\n\n\t  OrderedSetPrototype.__empty = emptyOrderedSet;\n\t  OrderedSetPrototype.__make = makeOrderedSet;\n\n\t  function makeOrderedSet(map, ownerID) {\n\t    var set = Object.create(OrderedSetPrototype);\n\t    set.size = map ? map.size : 0;\n\t    set._map = map;\n\t    set.__ownerID = ownerID;\n\t    return set;\n\t  }\n\n\t  var EMPTY_ORDERED_SET;\n\t  function emptyOrderedSet() {\n\t    return EMPTY_ORDERED_SET || (EMPTY_ORDERED_SET = makeOrderedSet(emptyOrderedMap()));\n\t  }\n\n\t  createClass(Stack, IndexedCollection);\n\n\t    // @pragma Construction\n\n\t    function Stack(value) {\n\t      return value === null || value === undefined ? emptyStack() :\n\t        isStack(value) ? value :\n\t        emptyStack().unshiftAll(value);\n\t    }\n\n\t    Stack.of = function(/*...values*/) {\n\t      return this(arguments);\n\t    };\n\n\t    Stack.prototype.toString = function() {\n\t      return this.__toString('Stack [', ']');\n\t    };\n\n\t    // @pragma Access\n\n\t    Stack.prototype.get = function(index, notSetValue) {\n\t      var head = this._head;\n\t      index = wrapIndex(this, index);\n\t      while (head && index--) {\n\t        head = head.next;\n\t      }\n\t      return head ? head.value : notSetValue;\n\t    };\n\n\t    Stack.prototype.peek = function() {\n\t      return this._head && this._head.value;\n\t    };\n\n\t    // @pragma Modification\n\n\t    Stack.prototype.push = function(/*...values*/) {\n\t      if (arguments.length === 0) {\n\t        return this;\n\t      }\n\t      var newSize = this.size + arguments.length;\n\t      var head = this._head;\n\t      for (var ii = arguments.length - 1; ii >= 0; ii--) {\n\t        head = {\n\t          value: arguments[ii],\n\t          next: head\n\t        };\n\t      }\n\t      if (this.__ownerID) {\n\t        this.size = newSize;\n\t        this._head = head;\n\t        this.__hash = undefined;\n\t        this.__altered = true;\n\t        return this;\n\t      }\n\t      return makeStack(newSize, head);\n\t    };\n\n\t    Stack.prototype.pushAll = function(iter) {\n\t      iter = IndexedIterable(iter);\n\t      if (iter.size === 0) {\n\t        return this;\n\t      }\n\t      assertNotInfinite(iter.size);\n\t      var newSize = this.size;\n\t      var head = this._head;\n\t      iter.reverse().forEach(function(value ) {\n\t        newSize++;\n\t        head = {\n\t          value: value,\n\t          next: head\n\t        };\n\t      });\n\t      if (this.__ownerID) {\n\t        this.size = newSize;\n\t        this._head = head;\n\t        this.__hash = undefined;\n\t        this.__altered = true;\n\t        return this;\n\t      }\n\t      return makeStack(newSize, head);\n\t    };\n\n\t    Stack.prototype.pop = function() {\n\t      return this.slice(1);\n\t    };\n\n\t    Stack.prototype.unshift = function(/*...values*/) {\n\t      return this.push.apply(this, arguments);\n\t    };\n\n\t    Stack.prototype.unshiftAll = function(iter) {\n\t      return this.pushAll(iter);\n\t    };\n\n\t    Stack.prototype.shift = function() {\n\t      return this.pop.apply(this, arguments);\n\t    };\n\n\t    Stack.prototype.clear = function() {\n\t      if (this.size === 0) {\n\t        return this;\n\t      }\n\t      if (this.__ownerID) {\n\t        this.size = 0;\n\t        this._head = undefined;\n\t        this.__hash = undefined;\n\t        this.__altered = true;\n\t        return this;\n\t      }\n\t      return emptyStack();\n\t    };\n\n\t    Stack.prototype.slice = function(begin, end) {\n\t      if (wholeSlice(begin, end, this.size)) {\n\t        return this;\n\t      }\n\t      var resolvedBegin = resolveBegin(begin, this.size);\n\t      var resolvedEnd = resolveEnd(end, this.size);\n\t      if (resolvedEnd !== this.size) {\n\t        // super.slice(begin, end);\n\t        return IndexedCollection.prototype.slice.call(this, begin, end);\n\t      }\n\t      var newSize = this.size - resolvedBegin;\n\t      var head = this._head;\n\t      while (resolvedBegin--) {\n\t        head = head.next;\n\t      }\n\t      if (this.__ownerID) {\n\t        this.size = newSize;\n\t        this._head = head;\n\t        this.__hash = undefined;\n\t        this.__altered = true;\n\t        return this;\n\t      }\n\t      return makeStack(newSize, head);\n\t    };\n\n\t    // @pragma Mutability\n\n\t    Stack.prototype.__ensureOwner = function(ownerID) {\n\t      if (ownerID === this.__ownerID) {\n\t        return this;\n\t      }\n\t      if (!ownerID) {\n\t        this.__ownerID = ownerID;\n\t        this.__altered = false;\n\t        return this;\n\t      }\n\t      return makeStack(this.size, this._head, ownerID, this.__hash);\n\t    };\n\n\t    // @pragma Iteration\n\n\t    Stack.prototype.__iterate = function(fn, reverse) {\n\t      if (reverse) {\n\t        return this.reverse().__iterate(fn);\n\t      }\n\t      var iterations = 0;\n\t      var node = this._head;\n\t      while (node) {\n\t        if (fn(node.value, iterations++, this) === false) {\n\t          break;\n\t        }\n\t        node = node.next;\n\t      }\n\t      return iterations;\n\t    };\n\n\t    Stack.prototype.__iterator = function(type, reverse) {\n\t      if (reverse) {\n\t        return this.reverse().__iterator(type);\n\t      }\n\t      var iterations = 0;\n\t      var node = this._head;\n\t      return new Iterator(function()  {\n\t        if (node) {\n\t          var value = node.value;\n\t          node = node.next;\n\t          return iteratorValue(type, iterations++, value);\n\t        }\n\t        return iteratorDone();\n\t      });\n\t    };\n\n\n\t  function isStack(maybeStack) {\n\t    return !!(maybeStack && maybeStack[IS_STACK_SENTINEL]);\n\t  }\n\n\t  Stack.isStack = isStack;\n\n\t  var IS_STACK_SENTINEL = '@@__IMMUTABLE_STACK__@@';\n\n\t  var StackPrototype = Stack.prototype;\n\t  StackPrototype[IS_STACK_SENTINEL] = true;\n\t  StackPrototype.withMutations = MapPrototype.withMutations;\n\t  StackPrototype.asMutable = MapPrototype.asMutable;\n\t  StackPrototype.asImmutable = MapPrototype.asImmutable;\n\t  StackPrototype.wasAltered = MapPrototype.wasAltered;\n\n\n\t  function makeStack(size, head, ownerID, hash) {\n\t    var map = Object.create(StackPrototype);\n\t    map.size = size;\n\t    map._head = head;\n\t    map.__ownerID = ownerID;\n\t    map.__hash = hash;\n\t    map.__altered = false;\n\t    return map;\n\t  }\n\n\t  var EMPTY_STACK;\n\t  function emptyStack() {\n\t    return EMPTY_STACK || (EMPTY_STACK = makeStack(0));\n\t  }\n\n\t  /**\n\t   * Contributes additional methods to a constructor\n\t   */\n\t  function mixin(ctor, methods) {\n\t    var keyCopier = function(key ) { ctor.prototype[key] = methods[key]; };\n\t    Object.keys(methods).forEach(keyCopier);\n\t    Object.getOwnPropertySymbols &&\n\t      Object.getOwnPropertySymbols(methods).forEach(keyCopier);\n\t    return ctor;\n\t  }\n\n\t  Iterable.Iterator = Iterator;\n\n\t  mixin(Iterable, {\n\n\t    // ### Conversion to other types\n\n\t    toArray: function() {\n\t      assertNotInfinite(this.size);\n\t      var array = new Array(this.size || 0);\n\t      this.valueSeq().__iterate(function(v, i)  { array[i] = v; });\n\t      return array;\n\t    },\n\n\t    toIndexedSeq: function() {\n\t      return new ToIndexedSequence(this);\n\t    },\n\n\t    toJS: function() {\n\t      return this.toSeq().map(\n\t        function(value ) {return value && typeof value.toJS === 'function' ? value.toJS() : value}\n\t      ).__toJS();\n\t    },\n\n\t    toJSON: function() {\n\t      return this.toSeq().map(\n\t        function(value ) {return value && typeof value.toJSON === 'function' ? value.toJSON() : value}\n\t      ).__toJS();\n\t    },\n\n\t    toKeyedSeq: function() {\n\t      return new ToKeyedSequence(this, true);\n\t    },\n\n\t    toMap: function() {\n\t      // Use Late Binding here to solve the circular dependency.\n\t      return Map(this.toKeyedSeq());\n\t    },\n\n\t    toObject: function() {\n\t      assertNotInfinite(this.size);\n\t      var object = {};\n\t      this.__iterate(function(v, k)  { object[k] = v; });\n\t      return object;\n\t    },\n\n\t    toOrderedMap: function() {\n\t      // Use Late Binding here to solve the circular dependency.\n\t      return OrderedMap(this.toKeyedSeq());\n\t    },\n\n\t    toOrderedSet: function() {\n\t      // Use Late Binding here to solve the circular dependency.\n\t      return OrderedSet(isKeyed(this) ? this.valueSeq() : this);\n\t    },\n\n\t    toSet: function() {\n\t      // Use Late Binding here to solve the circular dependency.\n\t      return Set(isKeyed(this) ? this.valueSeq() : this);\n\t    },\n\n\t    toSetSeq: function() {\n\t      return new ToSetSequence(this);\n\t    },\n\n\t    toSeq: function() {\n\t      return isIndexed(this) ? this.toIndexedSeq() :\n\t        isKeyed(this) ? this.toKeyedSeq() :\n\t        this.toSetSeq();\n\t    },\n\n\t    toStack: function() {\n\t      // Use Late Binding here to solve the circular dependency.\n\t      return Stack(isKeyed(this) ? this.valueSeq() : this);\n\t    },\n\n\t    toList: function() {\n\t      // Use Late Binding here to solve the circular dependency.\n\t      return List(isKeyed(this) ? this.valueSeq() : this);\n\t    },\n\n\n\t    // ### Common JavaScript methods and properties\n\n\t    toString: function() {\n\t      return '[Iterable]';\n\t    },\n\n\t    __toString: function(head, tail) {\n\t      if (this.size === 0) {\n\t        return head + tail;\n\t      }\n\t      return head + ' ' + this.toSeq().map(this.__toStringMapper).join(', ') + ' ' + tail;\n\t    },\n\n\n\t    // ### ES6 Collection methods (ES6 Array and Map)\n\n\t    concat: function() {var values = SLICE$0.call(arguments, 0);\n\t      return reify(this, concatFactory(this, values));\n\t    },\n\n\t    includes: function(searchValue) {\n\t      return this.some(function(value ) {return is(value, searchValue)});\n\t    },\n\n\t    entries: function() {\n\t      return this.__iterator(ITERATE_ENTRIES);\n\t    },\n\n\t    every: function(predicate, context) {\n\t      assertNotInfinite(this.size);\n\t      var returnValue = true;\n\t      this.__iterate(function(v, k, c)  {\n\t        if (!predicate.call(context, v, k, c)) {\n\t          returnValue = false;\n\t          return false;\n\t        }\n\t      });\n\t      return returnValue;\n\t    },\n\n\t    filter: function(predicate, context) {\n\t      return reify(this, filterFactory(this, predicate, context, true));\n\t    },\n\n\t    find: function(predicate, context, notSetValue) {\n\t      var entry = this.findEntry(predicate, context);\n\t      return entry ? entry[1] : notSetValue;\n\t    },\n\n\t    forEach: function(sideEffect, context) {\n\t      assertNotInfinite(this.size);\n\t      return this.__iterate(context ? sideEffect.bind(context) : sideEffect);\n\t    },\n\n\t    join: function(separator) {\n\t      assertNotInfinite(this.size);\n\t      separator = separator !== undefined ? '' + separator : ',';\n\t      var joined = '';\n\t      var isFirst = true;\n\t      this.__iterate(function(v ) {\n\t        isFirst ? (isFirst = false) : (joined += separator);\n\t        joined += v !== null && v !== undefined ? v.toString() : '';\n\t      });\n\t      return joined;\n\t    },\n\n\t    keys: function() {\n\t      return this.__iterator(ITERATE_KEYS);\n\t    },\n\n\t    map: function(mapper, context) {\n\t      return reify(this, mapFactory(this, mapper, context));\n\t    },\n\n\t    reduce: function(reducer, initialReduction, context) {\n\t      assertNotInfinite(this.size);\n\t      var reduction;\n\t      var useFirst;\n\t      if (arguments.length < 2) {\n\t        useFirst = true;\n\t      } else {\n\t        reduction = initialReduction;\n\t      }\n\t      this.__iterate(function(v, k, c)  {\n\t        if (useFirst) {\n\t          useFirst = false;\n\t          reduction = v;\n\t        } else {\n\t          reduction = reducer.call(context, reduction, v, k, c);\n\t        }\n\t      });\n\t      return reduction;\n\t    },\n\n\t    reduceRight: function(reducer, initialReduction, context) {\n\t      var reversed = this.toKeyedSeq().reverse();\n\t      return reversed.reduce.apply(reversed, arguments);\n\t    },\n\n\t    reverse: function() {\n\t      return reify(this, reverseFactory(this, true));\n\t    },\n\n\t    slice: function(begin, end) {\n\t      return reify(this, sliceFactory(this, begin, end, true));\n\t    },\n\n\t    some: function(predicate, context) {\n\t      return !this.every(not(predicate), context);\n\t    },\n\n\t    sort: function(comparator) {\n\t      return reify(this, sortFactory(this, comparator));\n\t    },\n\n\t    values: function() {\n\t      return this.__iterator(ITERATE_VALUES);\n\t    },\n\n\n\t    // ### More sequential methods\n\n\t    butLast: function() {\n\t      return this.slice(0, -1);\n\t    },\n\n\t    isEmpty: function() {\n\t      return this.size !== undefined ? this.size === 0 : !this.some(function()  {return true});\n\t    },\n\n\t    count: function(predicate, context) {\n\t      return ensureSize(\n\t        predicate ? this.toSeq().filter(predicate, context) : this\n\t      );\n\t    },\n\n\t    countBy: function(grouper, context) {\n\t      return countByFactory(this, grouper, context);\n\t    },\n\n\t    equals: function(other) {\n\t      return deepEqual(this, other);\n\t    },\n\n\t    entrySeq: function() {\n\t      var iterable = this;\n\t      if (iterable._cache) {\n\t        // We cache as an entries array, so we can just return the cache!\n\t        return new ArraySeq(iterable._cache);\n\t      }\n\t      var entriesSequence = iterable.toSeq().map(entryMapper).toIndexedSeq();\n\t      entriesSequence.fromEntrySeq = function()  {return iterable.toSeq()};\n\t      return entriesSequence;\n\t    },\n\n\t    filterNot: function(predicate, context) {\n\t      return this.filter(not(predicate), context);\n\t    },\n\n\t    findEntry: function(predicate, context, notSetValue) {\n\t      var found = notSetValue;\n\t      this.__iterate(function(v, k, c)  {\n\t        if (predicate.call(context, v, k, c)) {\n\t          found = [k, v];\n\t          return false;\n\t        }\n\t      });\n\t      return found;\n\t    },\n\n\t    findKey: function(predicate, context) {\n\t      var entry = this.findEntry(predicate, context);\n\t      return entry && entry[0];\n\t    },\n\n\t    findLast: function(predicate, context, notSetValue) {\n\t      return this.toKeyedSeq().reverse().find(predicate, context, notSetValue);\n\t    },\n\n\t    findLastEntry: function(predicate, context, notSetValue) {\n\t      return this.toKeyedSeq().reverse().findEntry(predicate, context, notSetValue);\n\t    },\n\n\t    findLastKey: function(predicate, context) {\n\t      return this.toKeyedSeq().reverse().findKey(predicate, context);\n\t    },\n\n\t    first: function() {\n\t      return this.find(returnTrue);\n\t    },\n\n\t    flatMap: function(mapper, context) {\n\t      return reify(this, flatMapFactory(this, mapper, context));\n\t    },\n\n\t    flatten: function(depth) {\n\t      return reify(this, flattenFactory(this, depth, true));\n\t    },\n\n\t    fromEntrySeq: function() {\n\t      return new FromEntriesSequence(this);\n\t    },\n\n\t    get: function(searchKey, notSetValue) {\n\t      return this.find(function(_, key)  {return is(key, searchKey)}, undefined, notSetValue);\n\t    },\n\n\t    getIn: function(searchKeyPath, notSetValue) {\n\t      var nested = this;\n\t      // Note: in an ES6 environment, we would prefer:\n\t      // for (var key of searchKeyPath) {\n\t      var iter = forceIterator(searchKeyPath);\n\t      var step;\n\t      while (!(step = iter.next()).done) {\n\t        var key = step.value;\n\t        nested = nested && nested.get ? nested.get(key, NOT_SET) : NOT_SET;\n\t        if (nested === NOT_SET) {\n\t          return notSetValue;\n\t        }\n\t      }\n\t      return nested;\n\t    },\n\n\t    groupBy: function(grouper, context) {\n\t      return groupByFactory(this, grouper, context);\n\t    },\n\n\t    has: function(searchKey) {\n\t      return this.get(searchKey, NOT_SET) !== NOT_SET;\n\t    },\n\n\t    hasIn: function(searchKeyPath) {\n\t      return this.getIn(searchKeyPath, NOT_SET) !== NOT_SET;\n\t    },\n\n\t    isSubset: function(iter) {\n\t      iter = typeof iter.includes === 'function' ? iter : Iterable(iter);\n\t      return this.every(function(value ) {return iter.includes(value)});\n\t    },\n\n\t    isSuperset: function(iter) {\n\t      iter = typeof iter.isSubset === 'function' ? iter : Iterable(iter);\n\t      return iter.isSubset(this);\n\t    },\n\n\t    keyOf: function(searchValue) {\n\t      return this.findKey(function(value ) {return is(value, searchValue)});\n\t    },\n\n\t    keySeq: function() {\n\t      return this.toSeq().map(keyMapper).toIndexedSeq();\n\t    },\n\n\t    last: function() {\n\t      return this.toSeq().reverse().first();\n\t    },\n\n\t    lastKeyOf: function(searchValue) {\n\t      return this.toKeyedSeq().reverse().keyOf(searchValue);\n\t    },\n\n\t    max: function(comparator) {\n\t      return maxFactory(this, comparator);\n\t    },\n\n\t    maxBy: function(mapper, comparator) {\n\t      return maxFactory(this, comparator, mapper);\n\t    },\n\n\t    min: function(comparator) {\n\t      return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator);\n\t    },\n\n\t    minBy: function(mapper, comparator) {\n\t      return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator, mapper);\n\t    },\n\n\t    rest: function() {\n\t      return this.slice(1);\n\t    },\n\n\t    skip: function(amount) {\n\t      return this.slice(Math.max(0, amount));\n\t    },\n\n\t    skipLast: function(amount) {\n\t      return reify(this, this.toSeq().reverse().skip(amount).reverse());\n\t    },\n\n\t    skipWhile: function(predicate, context) {\n\t      return reify(this, skipWhileFactory(this, predicate, context, true));\n\t    },\n\n\t    skipUntil: function(predicate, context) {\n\t      return this.skipWhile(not(predicate), context);\n\t    },\n\n\t    sortBy: function(mapper, comparator) {\n\t      return reify(this, sortFactory(this, comparator, mapper));\n\t    },\n\n\t    take: function(amount) {\n\t      return this.slice(0, Math.max(0, amount));\n\t    },\n\n\t    takeLast: function(amount) {\n\t      return reify(this, this.toSeq().reverse().take(amount).reverse());\n\t    },\n\n\t    takeWhile: function(predicate, context) {\n\t      return reify(this, takeWhileFactory(this, predicate, context));\n\t    },\n\n\t    takeUntil: function(predicate, context) {\n\t      return this.takeWhile(not(predicate), context);\n\t    },\n\n\t    valueSeq: function() {\n\t      return this.toIndexedSeq();\n\t    },\n\n\n\t    // ### Hashable Object\n\n\t    hashCode: function() {\n\t      return this.__hash || (this.__hash = hashIterable(this));\n\t    }\n\n\n\t    // ### Internal\n\n\t    // abstract __iterate(fn, reverse)\n\n\t    // abstract __iterator(type, reverse)\n\t  });\n\n\t  // var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@';\n\t  // var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@';\n\t  // var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@';\n\t  // var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@';\n\n\t  var IterablePrototype = Iterable.prototype;\n\t  IterablePrototype[IS_ITERABLE_SENTINEL] = true;\n\t  IterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.values;\n\t  IterablePrototype.__toJS = IterablePrototype.toArray;\n\t  IterablePrototype.__toStringMapper = quoteString;\n\t  IterablePrototype.inspect =\n\t  IterablePrototype.toSource = function() { return this.toString(); };\n\t  IterablePrototype.chain = IterablePrototype.flatMap;\n\t  IterablePrototype.contains = IterablePrototype.includes;\n\n\t  mixin(KeyedIterable, {\n\n\t    // ### More sequential methods\n\n\t    flip: function() {\n\t      return reify(this, flipFactory(this));\n\t    },\n\n\t    mapEntries: function(mapper, context) {var this$0 = this;\n\t      var iterations = 0;\n\t      return reify(this,\n\t        this.toSeq().map(\n\t          function(v, k)  {return mapper.call(context, [k, v], iterations++, this$0)}\n\t        ).fromEntrySeq()\n\t      );\n\t    },\n\n\t    mapKeys: function(mapper, context) {var this$0 = this;\n\t      return reify(this,\n\t        this.toSeq().flip().map(\n\t          function(k, v)  {return mapper.call(context, k, v, this$0)}\n\t        ).flip()\n\t      );\n\t    }\n\n\t  });\n\n\t  var KeyedIterablePrototype = KeyedIterable.prototype;\n\t  KeyedIterablePrototype[IS_KEYED_SENTINEL] = true;\n\t  KeyedIterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.entries;\n\t  KeyedIterablePrototype.__toJS = IterablePrototype.toObject;\n\t  KeyedIterablePrototype.__toStringMapper = function(v, k)  {return JSON.stringify(k) + ': ' + quoteString(v)};\n\n\n\n\t  mixin(IndexedIterable, {\n\n\t    // ### Conversion to other types\n\n\t    toKeyedSeq: function() {\n\t      return new ToKeyedSequence(this, false);\n\t    },\n\n\n\t    // ### ES6 Collection methods (ES6 Array and Map)\n\n\t    filter: function(predicate, context) {\n\t      return reify(this, filterFactory(this, predicate, context, false));\n\t    },\n\n\t    findIndex: function(predicate, context) {\n\t      var entry = this.findEntry(predicate, context);\n\t      return entry ? entry[0] : -1;\n\t    },\n\n\t    indexOf: function(searchValue) {\n\t      var key = this.keyOf(searchValue);\n\t      return key === undefined ? -1 : key;\n\t    },\n\n\t    lastIndexOf: function(searchValue) {\n\t      var key = this.lastKeyOf(searchValue);\n\t      return key === undefined ? -1 : key;\n\t    },\n\n\t    reverse: function() {\n\t      return reify(this, reverseFactory(this, false));\n\t    },\n\n\t    slice: function(begin, end) {\n\t      return reify(this, sliceFactory(this, begin, end, false));\n\t    },\n\n\t    splice: function(index, removeNum /*, ...values*/) {\n\t      var numArgs = arguments.length;\n\t      removeNum = Math.max(removeNum | 0, 0);\n\t      if (numArgs === 0 || (numArgs === 2 && !removeNum)) {\n\t        return this;\n\t      }\n\t      // If index is negative, it should resolve relative to the size of the\n\t      // collection. However size may be expensive to compute if not cached, so\n\t      // only call count() if the number is in fact negative.\n\t      index = resolveBegin(index, index < 0 ? this.count() : this.size);\n\t      var spliced = this.slice(0, index);\n\t      return reify(\n\t        this,\n\t        numArgs === 1 ?\n\t          spliced :\n\t          spliced.concat(arrCopy(arguments, 2), this.slice(index + removeNum))\n\t      );\n\t    },\n\n\n\t    // ### More collection methods\n\n\t    findLastIndex: function(predicate, context) {\n\t      var entry = this.findLastEntry(predicate, context);\n\t      return entry ? entry[0] : -1;\n\t    },\n\n\t    first: function() {\n\t      return this.get(0);\n\t    },\n\n\t    flatten: function(depth) {\n\t      return reify(this, flattenFactory(this, depth, false));\n\t    },\n\n\t    get: function(index, notSetValue) {\n\t      index = wrapIndex(this, index);\n\t      return (index < 0 || (this.size === Infinity ||\n\t          (this.size !== undefined && index > this.size))) ?\n\t        notSetValue :\n\t        this.find(function(_, key)  {return key === index}, undefined, notSetValue);\n\t    },\n\n\t    has: function(index) {\n\t      index = wrapIndex(this, index);\n\t      return index >= 0 && (this.size !== undefined ?\n\t        this.size === Infinity || index < this.size :\n\t        this.indexOf(index) !== -1\n\t      );\n\t    },\n\n\t    interpose: function(separator) {\n\t      return reify(this, interposeFactory(this, separator));\n\t    },\n\n\t    interleave: function(/*...iterables*/) {\n\t      var iterables = [this].concat(arrCopy(arguments));\n\t      var zipped = zipWithFactory(this.toSeq(), IndexedSeq.of, iterables);\n\t      var interleaved = zipped.flatten(true);\n\t      if (zipped.size) {\n\t        interleaved.size = zipped.size * iterables.length;\n\t      }\n\t      return reify(this, interleaved);\n\t    },\n\n\t    keySeq: function() {\n\t      return Range(0, this.size);\n\t    },\n\n\t    last: function() {\n\t      return this.get(-1);\n\t    },\n\n\t    skipWhile: function(predicate, context) {\n\t      return reify(this, skipWhileFactory(this, predicate, context, false));\n\t    },\n\n\t    zip: function(/*, ...iterables */) {\n\t      var iterables = [this].concat(arrCopy(arguments));\n\t      return reify(this, zipWithFactory(this, defaultZipper, iterables));\n\t    },\n\n\t    zipWith: function(zipper/*, ...iterables */) {\n\t      var iterables = arrCopy(arguments);\n\t      iterables[0] = this;\n\t      return reify(this, zipWithFactory(this, zipper, iterables));\n\t    }\n\n\t  });\n\n\t  IndexedIterable.prototype[IS_INDEXED_SENTINEL] = true;\n\t  IndexedIterable.prototype[IS_ORDERED_SENTINEL] = true;\n\n\n\n\t  mixin(SetIterable, {\n\n\t    // ### ES6 Collection methods (ES6 Array and Map)\n\n\t    get: function(value, notSetValue) {\n\t      return this.has(value) ? value : notSetValue;\n\t    },\n\n\t    includes: function(value) {\n\t      return this.has(value);\n\t    },\n\n\n\t    // ### More sequential methods\n\n\t    keySeq: function() {\n\t      return this.valueSeq();\n\t    }\n\n\t  });\n\n\t  SetIterable.prototype.has = IterablePrototype.includes;\n\t  SetIterable.prototype.contains = SetIterable.prototype.includes;\n\n\n\t  // Mixin subclasses\n\n\t  mixin(KeyedSeq, KeyedIterable.prototype);\n\t  mixin(IndexedSeq, IndexedIterable.prototype);\n\t  mixin(SetSeq, SetIterable.prototype);\n\n\t  mixin(KeyedCollection, KeyedIterable.prototype);\n\t  mixin(IndexedCollection, IndexedIterable.prototype);\n\t  mixin(SetCollection, SetIterable.prototype);\n\n\n\t  // #pragma Helper functions\n\n\t  function keyMapper(v, k) {\n\t    return k;\n\t  }\n\n\t  function entryMapper(v, k) {\n\t    return [k, v];\n\t  }\n\n\t  function not(predicate) {\n\t    return function() {\n\t      return !predicate.apply(this, arguments);\n\t    }\n\t  }\n\n\t  function neg(predicate) {\n\t    return function() {\n\t      return -predicate.apply(this, arguments);\n\t    }\n\t  }\n\n\t  function quoteString(value) {\n\t    return typeof value === 'string' ? JSON.stringify(value) : String(value);\n\t  }\n\n\t  function defaultZipper() {\n\t    return arrCopy(arguments);\n\t  }\n\n\t  function defaultNegComparator(a, b) {\n\t    return a < b ? 1 : a > b ? -1 : 0;\n\t  }\n\n\t  function hashIterable(iterable) {\n\t    if (iterable.size === Infinity) {\n\t      return 0;\n\t    }\n\t    var ordered = isOrdered(iterable);\n\t    var keyed = isKeyed(iterable);\n\t    var h = ordered ? 1 : 0;\n\t    var size = iterable.__iterate(\n\t      keyed ?\n\t        ordered ?\n\t          function(v, k)  { h = 31 * h + hashMerge(hash(v), hash(k)) | 0; } :\n\t          function(v, k)  { h = h + hashMerge(hash(v), hash(k)) | 0; } :\n\t        ordered ?\n\t          function(v ) { h = 31 * h + hash(v) | 0; } :\n\t          function(v ) { h = h + hash(v) | 0; }\n\t    );\n\t    return murmurHashOfSize(size, h);\n\t  }\n\n\t  function murmurHashOfSize(size, h) {\n\t    h = imul(h, 0xCC9E2D51);\n\t    h = imul(h << 15 | h >>> -15, 0x1B873593);\n\t    h = imul(h << 13 | h >>> -13, 5);\n\t    h = (h + 0xE6546B64 | 0) ^ size;\n\t    h = imul(h ^ h >>> 16, 0x85EBCA6B);\n\t    h = imul(h ^ h >>> 13, 0xC2B2AE35);\n\t    h = smi(h ^ h >>> 16);\n\t    return h;\n\t  }\n\n\t  function hashMerge(a, b) {\n\t    return a ^ b + 0x9E3779B9 + (a << 6) + (a >> 2) | 0; // int\n\t  }\n\n\t  var Immutable = {\n\n\t    Iterable: Iterable,\n\n\t    Seq: Seq,\n\t    Collection: Collection,\n\t    Map: Map,\n\t    OrderedMap: OrderedMap,\n\t    List: List,\n\t    Stack: Stack,\n\t    Set: Set,\n\t    OrderedSet: OrderedSet,\n\n\t    Record: Record,\n\t    Range: Range,\n\t    Repeat: Repeat,\n\n\t    is: is,\n\t    fromJS: fromJS\n\n\t  };\n\n\t  return Immutable;\n\n\t}));\n\n/***/ },\n/* 13 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.default = readIdentifier;\n\n\tvar _utils = __webpack_require__(14);\n\n\tvar _readtable = __webpack_require__(7);\n\n\tvar _tokens = __webpack_require__(19);\n\n\tlet terminates;\n\n\tfunction readIdentifier(stream) {\n\t  terminates = (0, _utils.isTerminating)((0, _readtable.getCurrentReadtable)());\n\t  let char = stream.peek();\n\t  let code;\n\t  let check = _utils.isIdentifierStart;\n\t  let idx = 0;\n\t  while (!terminates(char) && !(0, _readtable.isEOS)(char)) {\n\t    code = char.charCodeAt(0);\n\t    if (char === '\\\\' || 0xd800 <= code && code <= 0xdbff) {\n\t      return new _tokens.IdentifierToken({\n\t        value: getEscapedIdentifier.call(this, stream)\n\t      });\n\t    }\n\t    if (!check(code)) {\n\t      return new _tokens.IdentifierToken({\n\t        value: stream.readString(idx)\n\t      });\n\t    }\n\t    char = stream.peek(++idx);\n\t    check = _utils.isIdentifierPart;\n\t  }\n\t  return new _tokens.IdentifierToken({\n\t    value: stream.readString(idx)\n\t  });\n\t}\n\n\tfunction getEscapedIdentifier(stream) {\n\t  const sPeek = stream.peek.bind(stream);\n\t  let id = '';\n\t  let check = _utils.isIdentifierStart;\n\t  let char = sPeek();\n\t  let code = char.charCodeAt(0);\n\t  while (!terminates(char) && !(0, _readtable.isEOS)(char)) {\n\t    let streamRead = false;\n\t    if (char === '\\\\') {\n\t      let nxt = sPeek(1);\n\t      if ((0, _readtable.isEOS)(nxt)) {\n\t        throw this.createILLEGAL(char);\n\t      }\n\t      if (nxt !== 'u') {\n\t        throw this.createILLEGAL(char);\n\t      }\n\t      code = (0, _utils.scanUnicode)(stream, 2);\n\t      streamRead = true;\n\t      if (code < 0) {\n\t        throw this.createILLEGAL(char);\n\t      }\n\t    } else if (0xd800 <= code && code <= 0xdbff) {\n\t      if ((0, _readtable.isEOS)(char)) {\n\t        throw this.createILLEGAL(char);\n\t      }\n\t      let lowSurrogateCode = sPeek(1).charCodeAt(0);\n\t      if (0xdc00 > lowSurrogateCode || lowSurrogateCode > 0xdfff) {\n\t        throw this.createILLEGAL(char);\n\t      }\n\t      stream.readString(2);\n\t      code = decodeUtf16(code, lowSurrogateCode);\n\t      streamRead = true;\n\t    }\n\t    if (!check(code)) {\n\t      if (id.length < 1) {\n\t        throw this.createILLEGAL(char);\n\t      }\n\t      return id;\n\t    }\n\n\t    if (!streamRead) stream.readString();\n\n\t    id += String.fromCodePoint(code);\n\t    char = sPeek();\n\t    code = char.charCodeAt(0);\n\t    check = _utils.isIdentifierPart;\n\t  }\n\t  return id;\n\t}\n\n\tfunction decodeUtf16(lead, trail) {\n\t  return (lead - 0xd800) * 0x400 + (trail - 0xdc00) + 0x10000;\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9yZWFkZXIvcmVhZC1pZGVudGlmaWVyLmpzIl0sIm5hbWVzIjpbInJlYWRJZGVudGlmaWVyIiwidGVybWluYXRlcyIsInN0cmVhbSIsImNoYXIiLCJwZWVrIiwiY29kZSIsImNoZWNrIiwiaWR4IiwiY2hhckNvZGVBdCIsInZhbHVlIiwiZ2V0RXNjYXBlZElkZW50aWZpZXIiLCJjYWxsIiwicmVhZFN0cmluZyIsInNQZWVrIiwiYmluZCIsImlkIiwic3RyZWFtUmVhZCIsIm54dCIsImNyZWF0ZUlMTEVHQUwiLCJsb3dTdXJyb2dhdGVDb2RlIiwiZGVjb2RlVXRmMTYiLCJsZW5ndGgiLCJTdHJpbmciLCJmcm9tQ29kZVBvaW50IiwibGVhZCIsInRyYWlsIl0sIm1hcHBpbmdzIjoiOzs7OztrQkFhd0JBLGM7O0FBWHhCOztBQUVBOztBQUdBOztBQUlBLElBQUlDLFVBQUo7O0FBRWUsU0FBU0QsY0FBVCxDQUF3QkUsTUFBeEIsRUFBNEM7QUFDekRELGVBQWEsMEJBQWMscUNBQWQsQ0FBYjtBQUNBLE1BQUlFLE9BQU9ELE9BQU9FLElBQVAsRUFBWDtBQUNBLE1BQUlDLElBQUo7QUFDQSxNQUFJQyxnQ0FBSjtBQUNBLE1BQUlDLE1BQU0sQ0FBVjtBQUNBLFNBQU8sQ0FBQ04sV0FBV0UsSUFBWCxDQUFELElBQXFCLENBQUMsc0JBQU1BLElBQU4sQ0FBN0IsRUFBMEM7QUFDeENFLFdBQU9GLEtBQUtLLFVBQUwsQ0FBZ0IsQ0FBaEIsQ0FBUDtBQUNBLFFBQUlMLFNBQVMsSUFBVCxJQUFrQixVQUFVRSxJQUFWLElBQWtCQSxRQUFRLE1BQWhELEVBQXlEO0FBQ3ZELGFBQU8sNEJBQW9CO0FBQ3pCSSxlQUFPQyxxQkFBcUJDLElBQXJCLENBQTBCLElBQTFCLEVBQWdDVCxNQUFoQztBQURrQixPQUFwQixDQUFQO0FBR0Q7QUFDRCxRQUFJLENBQUNJLE1BQU1ELElBQU4sQ0FBTCxFQUFrQjtBQUNoQixhQUFPLDRCQUFvQjtBQUN6QkksZUFBT1AsT0FBT1UsVUFBUCxDQUFrQkwsR0FBbEI7QUFEa0IsT0FBcEIsQ0FBUDtBQUdEO0FBQ0RKLFdBQU9ELE9BQU9FLElBQVAsQ0FBWSxFQUFFRyxHQUFkLENBQVA7QUFDQUQ7QUFDRDtBQUNELFNBQU8sNEJBQW9CO0FBQ3pCRyxXQUFPUCxPQUFPVSxVQUFQLENBQWtCTCxHQUFsQjtBQURrQixHQUFwQixDQUFQO0FBR0Q7O0FBRUQsU0FBU0csb0JBQVQsQ0FBOEJSLE1BQTlCLEVBQXNDO0FBQ3BDLFFBQU1XLFFBQVFYLE9BQU9FLElBQVAsQ0FBWVUsSUFBWixDQUFpQlosTUFBakIsQ0FBZDtBQUNBLE1BQUlhLEtBQUssRUFBVDtBQUNBLE1BQUlULGdDQUFKO0FBQ0EsTUFBSUgsT0FBT1UsT0FBWDtBQUNBLE1BQUlSLE9BQU9GLEtBQUtLLFVBQUwsQ0FBZ0IsQ0FBaEIsQ0FBWDtBQUNBLFNBQU8sQ0FBQ1AsV0FBV0UsSUFBWCxDQUFELElBQXFCLENBQUMsc0JBQU1BLElBQU4sQ0FBN0IsRUFBMEM7QUFDeEMsUUFBSWEsYUFBYSxLQUFqQjtBQUNBLFFBQUliLFNBQVMsSUFBYixFQUFtQjtBQUNqQixVQUFJYyxNQUFNSixNQUFNLENBQU4sQ0FBVjtBQUNBLFVBQUksc0JBQU1JLEdBQU4sQ0FBSixFQUFnQjtBQUNkLGNBQU0sS0FBS0MsYUFBTCxDQUFtQmYsSUFBbkIsQ0FBTjtBQUNEO0FBQ0QsVUFBSWMsUUFBUSxHQUFaLEVBQWlCO0FBQ2YsY0FBTSxLQUFLQyxhQUFMLENBQW1CZixJQUFuQixDQUFOO0FBQ0Q7QUFDREUsYUFBTyx3QkFBWUgsTUFBWixFQUFvQixDQUFwQixDQUFQO0FBQ0FjLG1CQUFhLElBQWI7QUFDQSxVQUFJWCxPQUFPLENBQVgsRUFBYztBQUNaLGNBQU0sS0FBS2EsYUFBTCxDQUFtQmYsSUFBbkIsQ0FBTjtBQUNEO0FBQ0YsS0FiRCxNQWFPLElBQUksVUFBVUUsSUFBVixJQUFrQkEsUUFBUSxNQUE5QixFQUFzQztBQUMzQyxVQUFJLHNCQUFNRixJQUFOLENBQUosRUFBaUI7QUFDZixjQUFNLEtBQUtlLGFBQUwsQ0FBbUJmLElBQW5CLENBQU47QUFDRDtBQUNELFVBQUlnQixtQkFBbUJOLE1BQU0sQ0FBTixFQUFTTCxVQUFULENBQW9CLENBQXBCLENBQXZCO0FBQ0EsVUFBSSxTQUFTVyxnQkFBVCxJQUE2QkEsbUJBQW1CLE1BQXBELEVBQTREO0FBQzFELGNBQU0sS0FBS0QsYUFBTCxDQUFtQmYsSUFBbkIsQ0FBTjtBQUNEO0FBQ0RELGFBQU9VLFVBQVAsQ0FBa0IsQ0FBbEI7QUFDQVAsYUFBT2UsWUFBWWYsSUFBWixFQUFrQmMsZ0JBQWxCLENBQVA7QUFDQUgsbUJBQWEsSUFBYjtBQUNEO0FBQ0QsUUFBSSxDQUFDVixNQUFNRCxJQUFOLENBQUwsRUFBa0I7QUFDaEIsVUFBSVUsR0FBR00sTUFBSCxHQUFZLENBQWhCLEVBQW1CO0FBQ2pCLGNBQU0sS0FBS0gsYUFBTCxDQUFtQmYsSUFBbkIsQ0FBTjtBQUNEO0FBQ0QsYUFBT1ksRUFBUDtBQUNEOztBQUVELFFBQUksQ0FBQ0MsVUFBTCxFQUFpQmQsT0FBT1UsVUFBUDs7QUFFakJHLFVBQU1PLE9BQU9DLGFBQVAsQ0FBcUJsQixJQUFyQixDQUFOO0FBQ0FGLFdBQU9VLE9BQVA7QUFDQVIsV0FBT0YsS0FBS0ssVUFBTCxDQUFnQixDQUFoQixDQUFQO0FBQ0FGO0FBQ0Q7QUFDRCxTQUFPUyxFQUFQO0FBQ0Q7O0FBRUQsU0FBU0ssV0FBVCxDQUFxQkksSUFBckIsRUFBMkJDLEtBQTNCLEVBQWtDO0FBQ2hDLFNBQU8sQ0FBQ0QsT0FBTyxNQUFSLElBQWtCLEtBQWxCLElBQTJCQyxRQUFRLE1BQW5DLElBQTZDLE9BQXBEO0FBQ0QiLCJmaWxlIjoicmVhZC1pZGVudGlmaWVyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcblxuaW1wb3J0IHsgc2NhblVuaWNvZGUgfSBmcm9tICcuL3V0aWxzJztcblxuaW1wb3J0IHsgaXNFT1MsIGdldEN1cnJlbnRSZWFkdGFibGUgfSBmcm9tICdyZWFkdGFibGUnO1xuaW1wb3J0IHR5cGUgeyBDaGFyU3RyZWFtIH0gZnJvbSAncmVhZHRhYmxlJztcblxuaW1wb3J0IHsgSWRlbnRpZmllclRva2VuIH0gZnJvbSAnLi4vdG9rZW5zJztcblxuaW1wb3J0IHsgaXNUZXJtaW5hdGluZywgaXNJZGVudGlmaWVyUGFydCwgaXNJZGVudGlmaWVyU3RhcnQgfSBmcm9tICcuL3V0aWxzJztcblxubGV0IHRlcm1pbmF0ZXM7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHJlYWRJZGVudGlmaWVyKHN0cmVhbTogQ2hhclN0cmVhbSkge1xuICB0ZXJtaW5hdGVzID0gaXNUZXJtaW5hdGluZyhnZXRDdXJyZW50UmVhZHRhYmxlKCkpO1xuICBsZXQgY2hhciA9IHN0cmVhbS5wZWVrKCk7XG4gIGxldCBjb2RlO1xuICBsZXQgY2hlY2sgPSBpc0lkZW50aWZpZXJTdGFydDtcbiAgbGV0IGlkeCA9IDA7XG4gIHdoaWxlICghdGVybWluYXRlcyhjaGFyKSAmJiAhaXNFT1MoY2hhcikpIHtcbiAgICBjb2RlID0gY2hhci5jaGFyQ29kZUF0KDApO1xuICAgIGlmIChjaGFyID09PSAnXFxcXCcgfHwgKDB4ZDgwMCA8PSBjb2RlICYmIGNvZGUgPD0gMHhkYmZmKSkge1xuICAgICAgcmV0dXJuIG5ldyBJZGVudGlmaWVyVG9rZW4oe1xuICAgICAgICB2YWx1ZTogZ2V0RXNjYXBlZElkZW50aWZpZXIuY2FsbCh0aGlzLCBzdHJlYW0pLFxuICAgICAgfSk7XG4gICAgfVxuICAgIGlmICghY2hlY2soY29kZSkpIHtcbiAgICAgIHJldHVybiBuZXcgSWRlbnRpZmllclRva2VuKHtcbiAgICAgICAgdmFsdWU6IHN0cmVhbS5yZWFkU3RyaW5nKGlkeCksXG4gICAgICB9KTtcbiAgICB9XG4gICAgY2hhciA9IHN0cmVhbS5wZWVrKCsraWR4KTtcbiAgICBjaGVjayA9IGlzSWRlbnRpZmllclBhcnQ7XG4gIH1cbiAgcmV0dXJuIG5ldyBJZGVudGlmaWVyVG9rZW4oe1xuICAgIHZhbHVlOiBzdHJlYW0ucmVhZFN0cmluZyhpZHgpLFxuICB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0RXNjYXBlZElkZW50aWZpZXIoc3RyZWFtKSB7XG4gIGNvbnN0IHNQZWVrID0gc3RyZWFtLnBlZWsuYmluZChzdHJlYW0pO1xuICBsZXQgaWQgPSAnJztcbiAgbGV0IGNoZWNrID0gaXNJZGVudGlmaWVyU3RhcnQ7XG4gIGxldCBjaGFyID0gc1BlZWsoKTtcbiAgbGV0IGNvZGUgPSBjaGFyLmNoYXJDb2RlQXQoMCk7XG4gIHdoaWxlICghdGVybWluYXRlcyhjaGFyKSAmJiAhaXNFT1MoY2hhcikpIHtcbiAgICBsZXQgc3RyZWFtUmVhZCA9IGZhbHNlO1xuICAgIGlmIChjaGFyID09PSAnXFxcXCcpIHtcbiAgICAgIGxldCBueHQgPSBzUGVlaygxKTtcbiAgICAgIGlmIChpc0VPUyhueHQpKSB7XG4gICAgICAgIHRocm93IHRoaXMuY3JlYXRlSUxMRUdBTChjaGFyKTtcbiAgICAgIH1cbiAgICAgIGlmIChueHQgIT09ICd1Jykge1xuICAgICAgICB0aHJvdyB0aGlzLmNyZWF0ZUlMTEVHQUwoY2hhcik7XG4gICAgICB9XG4gICAgICBjb2RlID0gc2NhblVuaWNvZGUoc3RyZWFtLCAyKTtcbiAgICAgIHN0cmVhbVJlYWQgPSB0cnVlO1xuICAgICAgaWYgKGNvZGUgPCAwKSB7XG4gICAgICAgIHRocm93IHRoaXMuY3JlYXRlSUxMRUdBTChjaGFyKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKDB4ZDgwMCA8PSBjb2RlICYmIGNvZGUgPD0gMHhkYmZmKSB7XG4gICAgICBpZiAoaXNFT1MoY2hhcikpIHtcbiAgICAgICAgdGhyb3cgdGhpcy5jcmVhdGVJTExFR0FMKGNoYXIpO1xuICAgICAgfVxuICAgICAgbGV0IGxvd1N1cnJvZ2F0ZUNvZGUgPSBzUGVlaygxKS5jaGFyQ29kZUF0KDApO1xuICAgICAgaWYgKDB4ZGMwMCA+IGxvd1N1cnJvZ2F0ZUNvZGUgfHwgbG93U3Vycm9nYXRlQ29kZSA+IDB4ZGZmZikge1xuICAgICAgICB0aHJvdyB0aGlzLmNyZWF0ZUlMTEVHQUwoY2hhcik7XG4gICAgICB9XG4gICAgICBzdHJlYW0ucmVhZFN0cmluZygyKTtcbiAgICAgIGNvZGUgPSBkZWNvZGVVdGYxNihjb2RlLCBsb3dTdXJyb2dhdGVDb2RlKTtcbiAgICAgIHN0cmVhbVJlYWQgPSB0cnVlO1xuICAgIH1cbiAgICBpZiAoIWNoZWNrKGNvZGUpKSB7XG4gICAgICBpZiAoaWQubGVuZ3RoIDwgMSkge1xuICAgICAgICB0aHJvdyB0aGlzLmNyZWF0ZUlMTEVHQUwoY2hhcik7XG4gICAgICB9XG4gICAgICByZXR1cm4gaWQ7XG4gICAgfVxuXG4gICAgaWYgKCFzdHJlYW1SZWFkKSBzdHJlYW0ucmVhZFN0cmluZygpO1xuXG4gICAgaWQgKz0gU3RyaW5nLmZyb21Db2RlUG9pbnQoY29kZSk7XG4gICAgY2hhciA9IHNQZWVrKCk7XG4gICAgY29kZSA9IGNoYXIuY2hhckNvZGVBdCgwKTtcbiAgICBjaGVjayA9IGlzSWRlbnRpZmllclBhcnQ7XG4gIH1cbiAgcmV0dXJuIGlkO1xufVxuXG5mdW5jdGlvbiBkZWNvZGVVdGYxNihsZWFkLCB0cmFpbCkge1xuICByZXR1cm4gKGxlYWQgLSAweGQ4MDApICogMHg0MDAgKyAodHJhaWwgLSAweGRjMDApICsgMHgxMDAwMDtcbn1cbiJdfQ==\n\n/***/ },\n/* 14 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.isTerminating = exports.isIdentifierPart = exports.isIdentifierStart = exports.isDecimalDigit = exports.isWhiteSpace = exports.isLineTerminator = undefined;\n\texports.getHexValue = getHexValue;\n\texports.skipSingleLineComment = skipSingleLineComment;\n\texports.scanUnicode = scanUnicode;\n\texports.readStringEscape = readStringEscape;\n\texports.insertSequence = insertSequence;\n\texports.retrieveSequenceLength = retrieveSequenceLength;\n\texports.isExprPrefix = isExprPrefix;\n\texports.isRegexPrefix = isRegexPrefix;\n\n\tvar _readtable = __webpack_require__(7);\n\n\tvar _immutable = __webpack_require__(12);\n\n\tvar _esutils = __webpack_require__(15);\n\n\tvar _tokens = __webpack_require__(19);\n\n\tvar _ramda = __webpack_require__(20);\n\n\tvar R = _interopRequireWildcard(_ramda);\n\n\tvar _ramdaFantasy = __webpack_require__(21);\n\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\n\tconst {\n\t  isLineTerminator,\n\t  isWhiteSpace,\n\t  isDecimalDigit,\n\t  isIdentifierPartES6: isIdentifierPart,\n\t  isIdentifierStartES6: isIdentifierStart\n\t} = _esutils.code;\n\n\tconst Nothing = _ramdaFantasy.Maybe.Nothing;\n\n\t// TODO: also, need to handle contextual yield\n\tconst literalKeywords = ['this', 'null', 'true', 'false'];\n\n\texports.isLineTerminator = isLineTerminator;\n\texports.isWhiteSpace = isWhiteSpace;\n\texports.isDecimalDigit = isDecimalDigit;\n\texports.isIdentifierStart = isIdentifierStart;\n\texports.isIdentifierPart = isIdentifierPart;\n\tfunction getHexValue(rune) {\n\t  if ('0' <= rune && rune <= '9') {\n\t    return rune.charCodeAt(0) - 48;\n\t  }\n\t  if ('a' <= rune && rune <= 'f') {\n\t    return rune.charCodeAt(0) - 87;\n\t  }\n\t  if ('A' <= rune && rune <= 'F') {\n\t    return rune.charCodeAt(0) - 55;\n\t  }\n\t  return -1;\n\t}\n\n\tfunction skipSingleLineComment(stream) {\n\t  let idx = 0;\n\t  let char = stream.peek(idx);\n\t  while (!(0, _readtable.isEOS)(char)) {\n\t    let chCode = char.charCodeAt(0);\n\t    if (isLineTerminator(chCode)) {\n\t      ++idx;\n\t      if (chCode === 0xd /* \"\\r\" */ && stream.peek(idx).charCodeAt(0) === 0xa) {\n\t        /*\"\\n\" */++idx;\n\t      }\n\t      this.incrementLine();\n\t      break;\n\t    }\n\t    ++idx;\n\t    char = stream.peek(idx);\n\t  }\n\t  stream.readString(idx);\n\t}\n\n\tfunction scanUnicode(stream, start) {\n\t  const sPeek = stream.peek.bind(stream);\n\t  let idx = start;\n\t  let hexDigits = 0;\n\t  if (sPeek(idx) === '{') {\n\t    //\\u{HexDigits}\n\t    ++idx;\n\t    let char = sPeek(idx);\n\t    while (!(0, _readtable.isEOS)(char)) {\n\t      let hex = getHexValue(char);\n\t      if (hex === -1) break;\n\t      hexDigits = hexDigits << 4 | hex;\n\t      if (hexDigits > 0x10ffff) {\n\t        throw this.createILLEGAL(char);\n\t      }\n\t      char = sPeek(++idx);\n\t    }\n\t    if (char !== '}') {\n\t      throw this.createILLEGAL(char);\n\t    }\n\t    if (idx === start + 1) {\n\t      throw this.createILLEGAL(stream.peek(idx + 1));\n\t    }\n\t    ++idx;\n\t  } else {\n\t    //\\uHex4Digits\n\t    if ((0, _readtable.isEOS)(sPeek(idx + 3))) return -1;\n\t    let r;\n\t    for (; idx < start + 4; ++idx) {\n\t      r = getHexValue(sPeek(idx));\n\t      if (r === -1) return -1;\n\t      hexDigits = hexDigits << 4 | r;\n\t    }\n\t  }\n\t  stream.readString(idx);\n\n\t  return hexDigits;\n\t}\n\n\tfunction readStringEscape(str, stream, start, octal) {\n\t  let idx = start + 1,\n\t      char = stream.peek(idx),\n\t      lineStart;\n\t  if ((0, _readtable.isEOS)(char)) throw this.createILLEGAL(char);\n\n\t  if (!isLineTerminator(char.charCodeAt(0))) {\n\t    switch (char) {\n\t      case 'b':\n\t        str += '\\b';\n\t        ++idx;\n\t        break;\n\t      case 'f':\n\t        str += '\\f';\n\t        ++idx;\n\t        break;\n\t      case 'n':\n\t        str += '\\n';\n\t        ++idx;\n\t        break;\n\t      case 'r':\n\t        str += '\\r';\n\t        ++idx;\n\t        break;\n\t      case 't':\n\t        str += '\\t';\n\t        ++idx;\n\t        break;\n\t      case 'v':\n\t        str += '\\u000B';\n\t        ++idx;\n\t        break;\n\t      case 'u':\n\t      case 'x':\n\t        {\n\t          let unescaped;\n\t          ++idx;\n\t          let nxt = stream.peek(idx);\n\t          if ((0, _readtable.isEOS)(nxt)) {\n\t            throw this.createILLEGAL(nxt);\n\t          }\n\t          unescaped = char === 'u' ? scanUnicode.call(this, stream, idx) : scanHexEscape2.call(this, stream);\n\t          if (unescaped === -1) throw this.createILLEGAL(char);\n\t          idx = 0; // stream is read in scanUnicode and scanHexEscape2\n\n\t          str += String.fromCodePoint(unescaped);\n\t          break;\n\t        }\n\t      default:\n\t        {\n\t          if ('0' <= char && char <= '7') {\n\t            [str, idx, octal] = scanOctal.call(this, str, stream, char, idx, octal);\n\t          } else if (char === '8' || char === '9') {\n\t            throw this.createILLEGAL(char);\n\t          } else {\n\t            str += char;\n\t            ++idx;\n\t          }\n\t        }\n\t    }\n\t  } else {\n\t    if (char === '\\r' && stream.peek(idx + 1) === '\\n') {\n\t      ++idx;\n\t    }\n\t    ++idx;\n\t    this.incrementLine();\n\t    lineStart = idx;\n\t  }\n\t  return [str, idx, octal, lineStart];\n\t}\n\n\tfunction scanOctal(str, stream, char, start, octal) {\n\t  let len = 1,\n\t      idx = start;\n\t  if ('0' <= char && char <= '3') {\n\t    len = 0;\n\t  }\n\t  let code = 0;\n\n\t  while (len < 3 && '0' <= char && char <= '7') {\n\t    ++idx;\n\t    if (len > 0 || char !== '0') {\n\t      if (octal == null) octal = '';\n\t      octal += char;\n\t    }\n\t    code *= 8;\n\t    code += +char; //coersion\n\t    ++len;\n\t    char = stream.peek(idx);\n\t    if ((0, _readtable.isEOS)(char)) {\n\t      throw this.createILLEGAL(char);\n\t    }\n\t  }\n\t  str += String.fromCharCode(code);\n\t  return [str, idx, octal];\n\t}\n\n\tfunction scanHexEscape2(stream, idx) {\n\t  let char = stream.peek(idx);\n\n\t  if ((0, _readtable.isEOS)(char)) return -1;\n\n\t  let r1 = getHexValue(stream.peek());\n\t  if (r1 === -1) return r1;\n\n\t  let r2 = getHexValue(stream.peek(1));\n\t  if (r2 === -1) return r2;\n\n\t  stream.readString(2);\n\t  return r1 << 4 | r2;\n\t}\n\n\tfunction insertSequence(coll, seq) {\n\t  const char = seq[0];\n\t  if (!coll[char]) {\n\t    coll[char] = {};\n\t  }\n\t  if (seq.length === 1) {\n\t    coll[char].isValue = true;\n\t    return coll;\n\t  } else {\n\t    coll[char] = insertSequence(coll[char], seq.slice(1));\n\t    return coll;\n\t  }\n\t}\n\n\tconst isTerminating = exports.isTerminating = table => char => table.getMapping(char).mode === 'terminating';\n\n\t// check for terminating doesn't work if it's at the start\n\tfunction retrieveSequenceLength(table, stream, idx) {\n\t  const char = stream.peek(idx);\n\t  if (!table[char]) {\n\t    if (table.isValue) return idx;\n\t    return -1;\n\t  } else {\n\t    return retrieveSequenceLength(table[char], stream, ++idx);\n\t  }\n\t}\n\n\tconst assignOps = ['=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '>>>=', '&=', '|=', '^=', ','];\n\n\tconst binaryOps = ['+', '-', '*', '/', '%', '<<', '>>', '>>>', '&', '|', '^', '&&', '||', '?', ':', '===', '==', '>=', '<=', '<', '>', '!=', '!==', 'instanceof'];\n\n\tconst unaryOps = ['++', '--', '~', '!', 'delete', 'void', 'typeof', 'yield', 'throw', 'new'];\n\n\tconst allOps = assignOps.concat(binaryOps).concat(unaryOps);\n\n\tfunction isNonLiteralKeyword(t) {\n\t  return (0, _tokens.isKeyword)(t) && t.value && !R.contains(t.value, literalKeywords);\n\t}\n\tconst exprPrefixKeywords = ['instanceof', 'typeof', 'delete', 'void', 'yield', 'throw', 'new', 'case'];\n\n\tfunction isExprReturn(l, p) {\n\t  // ... return {x: 42} /r /i\n\t  // ... return\\n{x: 42} /r /i\n\t  return popRestMaybe(p).map(([retKwd, rest]) => (0, _tokens.isKeyword)(retKwd, 'return') && (0, _tokens.getLineNumber)(retKwd) === l).getOrElse(false);\n\t}\n\n\t// List a -> Boolean\n\tfunction isTopPunctuator(p) {\n\t  return popMaybe(p).map(punc => (0, _tokens.isPunctuator)(punc)).getOrElse(false);\n\t}\n\n\tfunction isOperator(op) {\n\t  if (((0, _tokens.isPunctuator)(op) || (0, _tokens.isKeyword)(op)) && op.value != null) {\n\t    const opVal = op.value; // the const is because flow doesn't know op.value isn't mutated\n\t    return allOps.some(o => o === opVal);\n\t  }\n\t  return false;\n\t}\n\n\tfunction isTopOperator(p) {\n\t  return popMaybe(p).map(op => {\n\t    return isOperator(op);\n\t  }).getOrElse(false);\n\t}\n\n\tfunction isExprPrefixKeyword(kwd) {\n\t  return (0, _tokens.isKeyword)(kwd, exprPrefixKeywords);\n\t}\n\n\tfunction isTopKeywordExprPrefix(p) {\n\t  return popMaybe(p).map(kwd => {\n\t    return isExprPrefixKeyword(kwd);\n\t  }).getOrElse(false);\n\t}\n\n\tfunction isTopColon(p) {\n\t  return popMaybe(p).map(colon => {\n\t    if ((0, _tokens.isPunctuator)(colon, ':')) {\n\t      return true;\n\t    }\n\t    return false;\n\t  }).getOrElse(false);\n\t}\n\n\tfunction isExprPrefix(l, b, p) {\n\t  if (p.size === 0) {\n\t    // ... ({x: 42} /r/i)\n\t    return b;\n\t  } else if (isTopColon(p)) {\n\t    // ... ({x: {x: 42} /r/i })\n\t    return b;\n\t  } else if (isTopKeywordExprPrefix(p)) {\n\t    // ... throw {x: 42} /r/i\n\t    return true;\n\t  } else if (isTopOperator(p)) {\n\t    // ... 42 + {x: 42} /r/i\n\t    return true;\n\t  } else if (isTopPunctuator(p)) {\n\t    // ... for ( ; {x: 42}/r/i)\n\t    return b;\n\t  } else if (isExprReturn(l, p)) {\n\t    // ... return {x: 42} /r /i\n\t    // ... return\\n{x: 42} /r /i\n\t    return true;\n\t  }\n\t  return false;\n\t}\n\n\tfunction popMaybe(p) {\n\t  if (p.size >= 1) {\n\t    return _ramdaFantasy.Maybe.of(p.last());\n\t  }\n\t  return Nothing();\n\t}\n\n\tfunction isTopStandaloneKeyword(prefix) {\n\t  // P . t . t'  where t \\not = \".\" and t' ∈ (Keyword \\setminus  LiteralKeyword)\n\t  return popRestMaybe(prefix).map(([kwd, rest]) => {\n\t    if (isNonLiteralKeyword(kwd)) {\n\t      return _ramdaFantasy.Maybe.maybe(true, dot => !(0, _tokens.isPunctuator)(dot, '.'), popMaybe(rest));\n\t    }\n\t    return false;\n\t  }).getOrElse(false);\n\t}\n\n\tfunction isTopParensWithKeyword(prefix) {\n\t  // P . t . t' . (T)  where t \\not = \".\" and t' ∈ (Keyword \\setminus LiteralKeyword)\n\t  return popRestMaybe(prefix).chain(([paren, rest]) => (0, _tokens.isParens)(paren) ? popRestMaybe(rest) : Nothing()).map(([kwd, rest]) => {\n\t    if (isNonLiteralKeyword(kwd)) {\n\t      return _ramdaFantasy.Maybe.maybe(true, dot => !(0, _tokens.isPunctuator)(dot, '.'), popMaybe(rest));\n\t    }\n\t    return false;\n\t  }).getOrElse(false);\n\t}\n\n\tfunction popRestMaybe(p) {\n\t  if (p.size > 0) {\n\t    let last = p.last();\n\t    let rest = p.pop();\n\t    return _ramdaFantasy.Maybe.of([last, rest]);\n\t  }\n\t  return Nothing();\n\t}\n\n\tfunction isTopFunctionExpression(prefix, exprAllowed) {\n\t  // P . function^l . x? . () . {}     where isExprPrefix(P, b, l) = false\n\t  return popRestMaybe(prefix).chain(([curly, rest]) => {\n\t    if ((0, _tokens.isBraces)(curly)) {\n\t      return popRestMaybe(rest);\n\t    }\n\t    return Nothing();\n\t  }).chain(([paren, rest]) => {\n\t    if ((0, _tokens.isParens)(paren)) {\n\t      return popRestMaybe(rest);\n\t    }\n\t    return Nothing();\n\t  }).chain(([optIdent, rest]) => {\n\t    if ((0, _tokens.isIdentifier)(optIdent)) {\n\t      return popRestMaybe(rest);\n\t    }\n\t    return _ramdaFantasy.Maybe.of([optIdent, rest]);\n\t  }).chain(([fnKwd, rest]) => {\n\t    if ((0, _tokens.isKeyword)(fnKwd, 'function')) {\n\t      let l = (0, _tokens.getLineNumber)(fnKwd);\n\t      if (l == null) {\n\t        throw new Error('Un-expected null line number');\n\t      }\n\t      return _ramdaFantasy.Maybe.of(!isExprPrefix(l, exprAllowed, rest));\n\t    }\n\t    return _ramdaFantasy.Maybe.of(false);\n\t  }).getOrElse(false);\n\t}\n\n\tfunction isTopObjectLiteral(prefix, exprAllowed) {\n\t  // P . {T}^l  where isExprPrefix(P, b, l) = false\n\t  return popRestMaybe(prefix).chain(([braces, rest]) => {\n\t    if ((0, _tokens.isBraces)(braces)) {\n\t      let l = (0, _tokens.getLineNumber)(braces);\n\t      if (l == null) {\n\t        throw new Error('Un-expected null line number');\n\t      }\n\t      return _ramdaFantasy.Maybe.of(!isExprPrefix(l, exprAllowed, rest));\n\t    }\n\t    return _ramdaFantasy.Maybe.of(false);\n\t  }).getOrElse(false);\n\t}\n\n\tfunction isTopFunction(prefix) {\n\t  // P . function^l . x? . () . {}     where isExprPrefix(P, b, l) = false\n\t  return popRestMaybe(prefix).chain(([curly, rest]) => {\n\t    if ((0, _tokens.isBraces)(curly)) {\n\t      return popRestMaybe(rest);\n\t    }\n\t    return Nothing();\n\t  }).chain(([paren, rest]) => {\n\t    if ((0, _tokens.isParens)(paren)) {\n\t      return popRestMaybe(rest);\n\t    }\n\t    return Nothing();\n\t  }).chain(([optIdent, rest]) => {\n\t    if ((0, _tokens.isIdentifier)(optIdent)) {\n\t      return popRestMaybe(rest);\n\t    }\n\t    return _ramdaFantasy.Maybe.of([optIdent, rest]);\n\t  }).chain(([fnKwd, rest]) => {\n\t    if ((0, _tokens.isKeyword)(fnKwd, 'function')) {\n\t      return _ramdaFantasy.Maybe.of(true);\n\t    }\n\t    return _ramdaFantasy.Maybe.of(false);\n\t  }).getOrElse(false);\n\t}\n\n\tfunction isRegexPrefix(exprAllowed, prefix) {\n\t  if (prefix.isEmpty()) {\n\t    // ε\n\t    return true;\n\t  } else if (isTopPunctuator(prefix)) {\n\t    // P . t   where t ∈ Punctuator\n\t    return true;\n\t  } else if (isTopStandaloneKeyword(prefix)) {\n\t    // P . t . t'  where t \\not = \".\" and t' ∈ (Keyword \\setminus  LiteralKeyword)\n\t    return true;\n\t  } else if (isTopParensWithKeyword(prefix)) {\n\t    // P . t . t' . (T)  where t \\not = \".\" and t' ∈ (Keyword \\setminus LiteralKeyword)\n\t    return true;\n\t  } else if (isTopFunction(prefix)) {\n\t    // P . function^l . x? . () . {}     where isExprPrefix(P, b, l) = false\n\t    return isTopFunctionExpression(prefix, exprAllowed);\n\t  } else if (isTopObjectLiteral(prefix, exprAllowed)) {\n\t    // P . {T}^l  where isExprPrefix(P, b, l) = false\n\t    return true;\n\t  }\n\t  return false;\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9yZWFkZXIvdXRpbHMuanMiXSwibmFtZXMiOlsiZ2V0SGV4VmFsdWUiLCJza2lwU2luZ2xlTGluZUNvbW1lbnQiLCJzY2FuVW5pY29kZSIsInJlYWRTdHJpbmdFc2NhcGUiLCJpbnNlcnRTZXF1ZW5jZSIsInJldHJpZXZlU2VxdWVuY2VMZW5ndGgiLCJpc0V4cHJQcmVmaXgiLCJpc1JlZ2V4UHJlZml4IiwiUiIsImlzTGluZVRlcm1pbmF0b3IiLCJpc1doaXRlU3BhY2UiLCJpc0RlY2ltYWxEaWdpdCIsImlzSWRlbnRpZmllclBhcnRFUzYiLCJpc0lkZW50aWZpZXJQYXJ0IiwiaXNJZGVudGlmaWVyU3RhcnRFUzYiLCJpc0lkZW50aWZpZXJTdGFydCIsIk5vdGhpbmciLCJsaXRlcmFsS2V5d29yZHMiLCJydW5lIiwiY2hhckNvZGVBdCIsInN0cmVhbSIsImlkeCIsImNoYXIiLCJwZWVrIiwiY2hDb2RlIiwiaW5jcmVtZW50TGluZSIsInJlYWRTdHJpbmciLCJzdGFydCIsInNQZWVrIiwiYmluZCIsImhleERpZ2l0cyIsImhleCIsImNyZWF0ZUlMTEVHQUwiLCJyIiwic3RyIiwib2N0YWwiLCJsaW5lU3RhcnQiLCJ1bmVzY2FwZWQiLCJueHQiLCJjYWxsIiwic2NhbkhleEVzY2FwZTIiLCJTdHJpbmciLCJmcm9tQ29kZVBvaW50Iiwic2Nhbk9jdGFsIiwibGVuIiwiY29kZSIsImZyb21DaGFyQ29kZSIsInIxIiwicjIiLCJjb2xsIiwic2VxIiwibGVuZ3RoIiwiaXNWYWx1ZSIsInNsaWNlIiwiaXNUZXJtaW5hdGluZyIsInRhYmxlIiwiZ2V0TWFwcGluZyIsIm1vZGUiLCJhc3NpZ25PcHMiLCJiaW5hcnlPcHMiLCJ1bmFyeU9wcyIsImFsbE9wcyIsImNvbmNhdCIsImlzTm9uTGl0ZXJhbEtleXdvcmQiLCJ0IiwidmFsdWUiLCJjb250YWlucyIsImV4cHJQcmVmaXhLZXl3b3JkcyIsImlzRXhwclJldHVybiIsImwiLCJwIiwicG9wUmVzdE1heWJlIiwibWFwIiwicmV0S3dkIiwicmVzdCIsImdldE9yRWxzZSIsImlzVG9wUHVuY3R1YXRvciIsInBvcE1heWJlIiwicHVuYyIsImlzT3BlcmF0b3IiLCJvcCIsIm9wVmFsIiwic29tZSIsIm8iLCJpc1RvcE9wZXJhdG9yIiwiaXNFeHByUHJlZml4S2V5d29yZCIsImt3ZCIsImlzVG9wS2V5d29yZEV4cHJQcmVmaXgiLCJpc1RvcENvbG9uIiwiY29sb24iLCJiIiwic2l6ZSIsIm9mIiwibGFzdCIsImlzVG9wU3RhbmRhbG9uZUtleXdvcmQiLCJwcmVmaXgiLCJtYXliZSIsImRvdCIsImlzVG9wUGFyZW5zV2l0aEtleXdvcmQiLCJjaGFpbiIsInBhcmVuIiwicG9wIiwiaXNUb3BGdW5jdGlvbkV4cHJlc3Npb24iLCJleHByQWxsb3dlZCIsImN1cmx5Iiwib3B0SWRlbnQiLCJmbkt3ZCIsIkVycm9yIiwiaXNUb3BPYmplY3RMaXRlcmFsIiwiYnJhY2VzIiwiaXNUb3BGdW5jdGlvbiIsImlzRW1wdHkiXSwibWFwcGluZ3MiOiI7Ozs7OztRQXlDZ0JBLFcsR0FBQUEsVztRQWFBQyxxQixHQUFBQSxxQjtRQW1CQUMsVyxHQUFBQSxXO1FBdUNBQyxnQixHQUFBQSxnQjtRQXlIQUMsYyxHQUFBQSxjO1FBa0JBQyxzQixHQUFBQSxzQjtRQTZJQUMsWSxHQUFBQSxZO1FBNEpBQyxhLEdBQUFBLGE7O0FBbGlCaEI7O0FBQ0E7O0FBSUE7O0FBRUE7O0FBaUJBOztJQUFZQyxDOztBQUNaOzs7O0FBVEEsTUFBTTtBQUNKQyxrQkFESTtBQUVKQyxjQUZJO0FBR0pDLGdCQUhJO0FBSUpDLHVCQUFxQkMsZ0JBSmpCO0FBS0pDLHdCQUFzQkM7QUFMbEIsaUJBQU47O0FBVUEsTUFBTUMsVUFBVSxvQkFBTUEsT0FBdEI7O0FBRUE7QUFDQSxNQUFNQyxrQkFBa0IsQ0FBQyxNQUFELEVBQVMsTUFBVCxFQUFpQixNQUFqQixFQUF5QixPQUF6QixDQUF4Qjs7UUFHRVIsZ0IsR0FBQUEsZ0I7UUFDQUMsWSxHQUFBQSxZO1FB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QUosRUFBNkI7QUFDbEM7QUFDQSxXQUFPLElBQVA7QUFDRCxHQUhNLE1BR0EsSUFBSUQsdUJBQXVCQyxNQUF2QixDQUFKLEVBQW9DO0FBQ3pDO0FBQ0EsV0FBTyxJQUFQO0FBQ0QsR0FITSxNQUdBLElBQUlHLHVCQUF1QkgsTUFBdkIsQ0FBSixFQUFvQztBQUN6QztBQUNBLFdBQU8sSUFBUDtBQUNELEdBSE0sTUFHQSxJQUFJZSxjQUFjZixNQUFkLENBQUosRUFBMkI7QUFDaEM7QUFDQSxXQUFPTyx3QkFBd0JQLE1BQXhCLEVBQWdDUSxXQUFoQyxDQUFQO0FBQ0QsR0FITSxNQUdBLElBQUlLLG1CQUFtQmIsTUFBbkIsRUFBMkJRLFdBQTNCLENBQUosRUFBNkM7QUFDbEQ7QUFDQSxXQUFPLElBQVA7QUFDRDtBQUNELFNBQU8sS0FBUDtBQUNEIiwiZmlsZSI6InV0aWxzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcblxuaW1wb3J0IHsgaXNFT1MgfSBmcm9tICdyZWFkdGFibGUnO1xuaW1wb3J0IHsgTGlzdCB9IGZyb20gJ2ltbXV0YWJsZSc7XG5cbmltcG9ydCB0eXBlIHsgUmVhZHRhYmxlLCBDaGFyU3RyZWFtIH0gZnJvbSAncmVhZHRhYmxlJztcblxuaW1wb3J0IHsgY29kZSB9IGZyb20gJ2VzdXRpbHMnO1xuaW1wb3J0IHR5cGUgeyBUb2tlblRyZWUgfSBmcm9tICcuLi90b2tlbnMnO1xuaW1wb3J0IHtcbiAgZ2V0TGluZU51bWJlcixcbiAgaXNQdW5jdHVhdG9yLFxuICBpc0tleXdvcmQsXG4gIGlzQnJhY2VzLFxuICBpc1BhcmVucyxcbiAgaXNJZGVudGlmaWVyLFxufSBmcm9tICcuLi90b2tlbnMnO1xuXG5jb25zdCB7XG4gIGlzTGluZVRlcm1pbmF0b3IsXG4gIGlzV2hpdGVTcGFjZSxcbiAgaXNEZWNpbWFsRGlnaXQsXG4gIGlzSWRlbnRpZmllclBhcnRFUzY6IGlzSWRlbnRpZmllclBhcnQsXG4gIGlzSWRlbnRpZmllclN0YXJ0RVM2OiBpc0lkZW50aWZpZXJTdGFydCxcbn0gPSBjb2RlO1xuXG5pbXBvcnQgKiBhcyBSIGZyb20gJ3JhbWRhJztcbmltcG9ydCB7IE1heWJlIH0gZnJvbSAncmFtZGEtZmFudGFzeSc7XG5jb25zdCBOb3RoaW5nID0gTWF5YmUuTm90aGluZztcblxuLy8gVE9ETzogYWxzbywgbmVlZCB0byBoYW5kbGUgY29udGV4dHVhbCB5aWVsZFxuY29uc3QgbGl0ZXJhbEtleXdvcmRzID0gWyd0aGlzJywgJ251bGwnLCAndHJ1ZScsICdmYWxzZSddO1xuXG5leHBvcnQge1xuICBpc0xpbmVUZXJtaW5hdG9yLFxuICBpc1doaXRlU3BhY2UsXG4gIGlzRGVjaW1hbERpZ2l0LFxuICBpc0lkZW50aWZpZXJTdGFydCxcbiAgaXNJZGVudGlmaWVyUGFydCxcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRIZXhWYWx1ZShydW5lOiBzdHJpbmcpIHtcbiAgaWYgKCcwJyA8PSBydW5lICYmIHJ1bmUgPD0gJzknKSB7XG4gICAgcmV0dXJuIHJ1bmUuY2hhckNvZGVBdCgwKSAtIDQ4O1xuICB9XG4gIGlmICgnYScgPD0gcnVuZSAmJiBydW5lIDw9ICdmJykge1xuICAgIHJldHVybiBydW5lLmNoYXJDb2RlQXQoMCkgLSA4NztcbiAgfVxuICBpZiAoJ0EnIDw9IHJ1bmUgJiYgcnVuZSA8PSAnRicpIHtcbiAgICByZXR1cm4gcnVuZS5jaGFyQ29kZUF0KDApIC0gNTU7XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2tpcFNpbmdsZUxpbmVDb21tZW50KHN0cmVhbTogQ2hhclN0cmVhbSk6IHZvaWQge1xuICBsZXQgaWR4ID0gMDtcbiAgbGV0IGNoYXIgPSBzdHJlYW0ucGVlayhpZHgpO1xuICB3aGlsZSAoIWlzRU9TKGNoYXIpKSB7XG4gICAgbGV0IGNoQ29kZSA9IGNoYXIuY2hhckNvZGVBdCgwKTtcbiAgICBpZiAoaXNMaW5lVGVybWluYXRvcihjaENvZGUpKSB7XG4gICAgICArK2lkeDtcbiAgICAgIGlmIChjaENvZGUgPT09IDB4ZCAvKiBcIlxcclwiICovICYmIHN0cmVhbS5wZWVrKGlkeCkuY2hhckNvZGVBdCgwKSA9PT0gMHhhKSB7XG4gICAgICAgIC8qXCJcXG5cIiAqLyArK2lkeDtcbiAgICAgIH1cbiAgICAgIHRoaXMuaW5jcmVtZW50TGluZSgpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgICsraWR4O1xuICAgIGNoYXIgPSBzdHJlYW0ucGVlayhpZHgpO1xuICB9XG4gIHN0cmVhbS5yZWFkU3RyaW5nKGlkeCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzY2FuVW5pY29kZShzdHJlYW06IENoYXJTdHJlYW0sIHN0YXJ0OiBudW1iZXIpIHtcbiAgY29uc3Qgc1BlZWsgPSBzdHJlYW0ucGVlay5iaW5kKHN0cmVhbSk7XG4gIGxldCBpZHggPSBzdGFydDtcbiAgbGV0IGhleERpZ2l0cyA9IDA7XG4gIGlmIChzUGVlayhpZHgpID09PSAneycpIHtcbiAgICAvL1xcdXtIZXhEaWdpdHN9XG4gICAgKytpZHg7XG4gICAgbGV0IGNoYXIgPSBzUGVlayhpZHgpO1xuICAgIHdoaWxlICghaXNFT1MoY2hhcikpIHtcbiAgICAgIGxldCBoZXggPSBnZXRIZXhWYWx1ZShjaGFyKTtcbiAgICAgIGlmIChoZXggPT09IC0xKSBicmVhaztcbiAgICAgIGhleERpZ2l0cyA9IGhleERpZ2l0cyA8PCA0IHwgaGV4O1xuICAgICAgaWYgKGhleERpZ2l0cyA+IDB4MTBmZmZmKSB7XG4gICAgICAgIHRocm93IHRoaXMuY3JlYXRlSUxMRUdBTChjaGFyKTtcbiAgICAgIH1cbiAgICAgIGNoYXIgPSBzUGVlaygrK2lkeCk7XG4gICAgfVxuICAgIGlmIChjaGFyICE9PSAnfScpIHtcbiAgICAgIHRocm93IHRoaXMuY3JlYXRlSUxMRUdBTChjaGFyKTtcbiAgICB9XG4gICAgaWYgKGlkeCA9PT0gc3RhcnQgKyAxKSB7XG4gICAgICB0aHJvdyB0aGlzLmNyZWF0ZUlMTEVHQUwoc3RyZWFtLnBlZWsoaWR4ICsgMSkpO1xuICAgIH1cbiAgICArK2lkeDtcbiAgfSBlbHNlIHtcbiAgICAvL1xcdUhleDREaWdpdHNcbiAgICBpZiAoaXNFT1Moc1BlZWsoaWR4ICsgMykpKSByZXR1cm4gLTE7XG4gICAgbGV0IHI7XG4gICAgZm9yICg7IGlkeCA8IHN0YXJ0ICsgNDsgKytpZHgpIHtcbiAgICAgIHIgPSBnZXRIZXhWYWx1ZShzUGVlayhpZHgpKTtcbiAgICAgIGlmIChyID09PSAtMSkgcmV0dXJuIC0xO1xuICAgICAgaGV4RGlnaXRzID0gaGV4RGlnaXRzIDw8IDQgfCByO1xuICAgIH1cbiAgfVxuICBzdHJlYW0ucmVhZFN0cmluZyhpZHgpO1xuXG4gIHJldHVybiBoZXhEaWdpdHM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWFkU3RyaW5nRXNjYXBlKFxuICBzdHI6IHN0cmluZyxcbiAgc3RyZWFtOiBDaGFyU3RyZWFtLFxuICBzdGFydDogbnVtYmVyLFxuICBvY3RhbDogP3N0cmluZyxcbikge1xuICBsZXQgaWR4ID0gc3RhcnQgKyAxLCBjaGFyID0gc3RyZWFtLnBlZWsoaWR4KSwgbGluZVN0YXJ0O1xuICBpZiAoaXNFT1MoY2hhcikpIHRocm93IHRoaXMuY3JlYXRlSUxMRUdBTChjaGFyKTtcblxuICBpZiAoIWlzTGluZVRlcm1pbmF0b3IoY2hhci5jaGFyQ29kZUF0KDApKSkge1xuICAgIHN3aXRjaCAoY2hhcikge1xuICAgICAgY2FzZSAnYic6XG4gICAgICAgIHN0ciArPSAnXFxiJztcbiAgICAgICAgKytpZHg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnZic6XG4gICAgICAgIHN0ciArPSAnXFxmJztcbiAgICAgICAgKytpZHg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbic6XG4gICAgICAgIHN0ciArPSAnXFxuJztcbiAgICAgICAgKytpZHg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAncic6XG4gICAgICAgIHN0ciArPSAnXFxyJztcbiAgICAgICAgKytpZHg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndCc6XG4gICAgICAgIHN0ciArPSAnXFx0JztcbiAgICAgICAgKytpZHg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndic6XG4gICAgICAgIHN0ciArPSAnXFx1MDAwQic7XG4gICAgICAgICsraWR4O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3UnOlxuICAgICAgY2FzZSAneCc6IHtcbiAgICAgICAgbGV0IHVuZXNjYXBlZDtcbiAgICAgICAgKytpZHg7XG4gICAgICAgIGxldCBueHQgPSBzdHJlYW0ucGVlayhpZHgpO1xuICAgICAgICBpZiAoaXNFT1Mobnh0KSkge1xuICAgICAgICAgIHRocm93IHRoaXMuY3JlYXRlSUxMRUdBTChueHQpO1xuICAgICAgICB9XG4gICAgICAgIHVuZXNjYXBlZCA9IGNoYXIgPT09ICd1J1xuICAgICAgICAgID8gc2NhblVuaWNvZGUuY2FsbCh0aGlzLCBzdHJlYW0sIGlkeClcbiAgICAgICAgICA6IHNjYW5IZXhFc2NhcGUyLmNhbGwodGhpcywgc3RyZWFtKTtcbiAgICAgICAgaWYgKHVuZXNjYXBlZCA9PT0gLTEpIHRocm93IHRoaXMuY3JlYXRlSUxMRUdBTChjaGFyKTtcbiAgICAgICAgaWR4ID0gMDsgLy8gc3RyZWFtIGlzIHJlYWQgaW4gc2NhblVuaWNvZGUgYW5kIHNjYW5IZXhFc2NhcGUyXG5cbiAgICAgICAgc3RyICs9IFN0cmluZy5mcm9tQ29kZVBvaW50KHVuZXNjYXBlZCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgZGVmYXVsdDoge1xuICAgICAgICBpZiAoJzAnIDw9IGNoYXIgJiYgY2hhciA8PSAnNycpIHtcbiAgICAgICAgICBbc3RyLCBpZHgsIG9jdGFsXSA9IHNjYW5PY3RhbC5jYWxsKFxuICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgIHN0cixcbiAgICAgICAgICAgIHN0cmVhbSxcbiAgICAgICAgICAgIGNoYXIsXG4gICAgICAgICAgICBpZHgsXG4gICAgICAgICAgICBvY3RhbCxcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYgKGNoYXIgPT09ICc4JyB8fCBjaGFyID09PSAnOScpIHtcbiAgICAgICAgICB0aHJvdyB0aGlzLmNyZWF0ZUlMTEVHQUwoY2hhcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RyICs9IGNoYXI7XG4gICAgICAgICAgKytpZHg7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGNoYXIgPT09ICdcXHInICYmIHN0cmVhbS5wZWVrKGlkeCArIDEpID09PSAnXFxuJykge1xuICAgICAgKytpZHg7XG4gICAgfVxuICAgICsraWR4O1xuICAgIHRoaXMuaW5jcmVtZW50TGluZSgpO1xuICAgIGxpbmVTdGFydCA9IGlkeDtcbiAgfVxuICByZXR1cm4gW3N0ciwgaWR4LCBvY3RhbCwgbGluZVN0YXJ0XTtcbn1cblxuZnVuY3Rpb24gc2Nhbk9jdGFsKHN0ciwgc3RyZWFtLCBjaGFyLCBzdGFydCwgb2N0YWwpIHtcbiAgbGV0IGxlbiA9IDEsIGlkeCA9IHN0YXJ0O1xuICBpZiAoJzAnIDw9IGNoYXIgJiYgY2hhciA8PSAnMycpIHtcbiAgICBsZW4gPSAwO1xuICB9XG4gIGxldCBjb2RlID0gMDtcblxuICB3aGlsZSAobGVuIDwgMyAmJiAnMCcgPD0gY2hhciAmJiBjaGFyIDw9ICc3Jykge1xuICAgICsraWR4O1xuICAgIGlmIChsZW4gPiAwIHx8IGNoYXIgIT09ICcwJykge1xuICAgICAgaWYgKG9jdGFsID09IG51bGwpIG9jdGFsID0gJyc7XG4gICAgICBvY3RhbCArPSBjaGFyO1xuICAgIH1cbiAgICBjb2RlICo9IDg7XG4gICAgY29kZSArPSArY2hhcjsgLy9jb2Vyc2lvblxuICAgICsrbGVuO1xuICAgIGNoYXIgPSBzdHJlYW0ucGVlayhpZHgpO1xuICAgIGlmIChpc0VPUyhjaGFyKSkge1xuICAgICAgdGhyb3cgdGhpcy5jcmVhdGVJTExFR0FMKGNoYXIpO1xuICAgIH1cbiAgfVxuICBzdHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShjb2RlKTtcbiAgcmV0dXJuIFtzdHIsIGlkeCwgb2N0YWxdO1xufVxuXG5mdW5jdGlvbiBzY2FuSGV4RXNjYXBlMihzdHJlYW0sIGlkeCkge1xuICBsZXQgY2hhciA9IHN0cmVhbS5wZWVrKGlkeCk7XG5cbiAgaWYgKGlzRU9TKGNoYXIpKSByZXR1cm4gLTE7XG5cbiAgbGV0IHIxID0gZ2V0SGV4VmFsdWUoc3RyZWFtLnBlZWsoKSk7XG4gIGlmIChyMSA9PT0gLTEpIHJldHVybiByMTtcblxuICBsZXQgcjIgPSBnZXRIZXhWYWx1ZShzdHJlYW0ucGVlaygxKSk7XG4gIGlmIChyMiA9PT0gLTEpIHJldHVybiByMjtcblxuICBzdHJlYW0ucmVhZFN0cmluZygyKTtcbiAgcmV0dXJuIHIxIDw8IDQgfCByMjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluc2VydFNlcXVlbmNlKGNvbGw6IE9iamVjdCwgc2VxOiBzdHJpbmcpIHtcbiAgY29uc3QgY2hhciA9IHNlcVswXTtcbiAgaWYgKCFjb2xsW2NoYXJdKSB7XG4gICAgY29sbFtjaGFyXSA9IHt9O1xuICB9XG4gIGlmIChzZXEubGVuZ3RoID09PSAxKSB7XG4gICAgY29sbFtjaGFyXS5pc1ZhbHVlID0gdHJ1ZTtcbiAgICByZXR1cm4gY29sbDtcbiAgfSBlbHNlIHtcbiAgICBjb2xsW2NoYXJdID0gaW5zZXJ0U2VxdWVuY2UoY29sbFtjaGFyXSwgc2VxLnNsaWNlKDEpKTtcbiAgICByZXR1cm4gY29sbDtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgaXNUZXJtaW5hdGluZyA9ICh0YWJsZTogUmVhZHRhYmxlKSA9PlxuICAoY2hhcjogc3RyaW5nKTogYm9vbGVhbiA9PiB0YWJsZS5nZXRNYXBwaW5nKGNoYXIpLm1vZGUgPT09ICd0ZXJtaW5hdGluZyc7XG5cbi8vIGNoZWNrIGZvciB0ZXJtaW5hdGluZyBkb2Vzbid0IHdvcmsgaWYgaXQncyBhdCB0aGUgc3RhcnRcbmV4cG9ydCBmdW5jdGlvbiByZXRyaWV2ZVNlcXVlbmNlTGVuZ3RoKFxuICB0YWJsZTogT2JqZWN0LFxuICBzdHJlYW06IENoYXJTdHJlYW0sXG4gIGlkeDogbnVtYmVyLFxuKTogbnVtYmVyIHtcbiAgY29uc3QgY2hhciA9IHN0cmVhbS5wZWVrKGlkeCk7XG4gIGlmICghdGFibGVbY2hhcl0pIHtcbiAgICBpZiAodGFibGUuaXNWYWx1ZSkgcmV0dXJuIGlkeDtcbiAgICByZXR1cm4gLTE7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHJldHJpZXZlU2VxdWVuY2VMZW5ndGgodGFibGVbY2hhcl0sIHN0cmVhbSwgKytpZHgpO1xuICB9XG59XG5cbmNvbnN0IGFzc2lnbk9wcyA9IFtcbiAgJz0nLFxuICAnKz0nLFxuICAnLT0nLFxuICAnKj0nLFxuICAnLz0nLFxuICAnJT0nLFxuICAnPDw9JyxcbiAgJz4+PScsXG4gICc+Pj49JyxcbiAgJyY9JyxcbiAgJ3w9JyxcbiAgJ149JyxcbiAgJywnLFxuXTtcblxuY29uc3QgYmluYXJ5T3BzID0gW1xuICAnKycsXG4gICctJyxcbiAgJyonLFxuICAnLycsXG4gICclJyxcbiAgJzw8JyxcbiAgJz4+JyxcbiAgJz4+PicsXG4gICcmJyxcbiAgJ3wnLFxuICAnXicsXG4gICcmJicsXG4gICd8fCcsXG4gICc/JyxcbiAgJzonLFxuICAnPT09JyxcbiAgJz09JyxcbiAgJz49JyxcbiAgJzw9JyxcbiAgJzwnLFxuICAnPicsXG4gICchPScsXG4gICchPT0nLFxuICAnaW5zdGFuY2VvZicsXG5dO1xuXG5jb25zdCB1bmFyeU9wcyA9IFtcbiAgJysrJyxcbiAgJy0tJyxcbiAgJ34nLFxuICAnIScsXG4gICdkZWxldGUnLFxuICAndm9pZCcsXG4gICd0eXBlb2YnLFxuICAneWllbGQnLFxuICAndGhyb3cnLFxuICAnbmV3Jyxcbl07XG5cbmNvbnN0IGFsbE9wcyA9IGFzc2lnbk9wcy5jb25jYXQoYmluYXJ5T3BzKS5jb25jYXQodW5hcnlPcHMpO1xuXG5mdW5jdGlvbiBpc05vbkxpdGVyYWxLZXl3b3JkKHQ6IFRva2VuVHJlZSkge1xuICByZXR1cm4gaXNLZXl3b3JkKHQpICYmIHQudmFsdWUgJiYgIVIuY29udGFpbnModC52YWx1ZSwgbGl0ZXJhbEtleXdvcmRzKTtcbn1cbmNvbnN0IGV4cHJQcmVmaXhLZXl3b3JkcyA9IFtcbiAgJ2luc3RhbmNlb2YnLFxuICAndHlwZW9mJyxcbiAgJ2RlbGV0ZScsXG4gICd2b2lkJyxcbiAgJ3lpZWxkJyxcbiAgJ3Rocm93JyxcbiAgJ25ldycsXG4gICdjYXNlJyxcbl07XG5cbmZ1bmN0aW9uIGlzRXhwclJldHVybihsOiBudW1iZXIsIHA6IExpc3Q8VG9rZW5UcmVlPikge1xuICAvLyAuLi4gcmV0dXJuIHt4OiA0Mn0gL3IgL2lcbiAgLy8gLi4uIHJldHVyblxcbnt4OiA0Mn0gL3IgL2lcbiAgcmV0dXJuIHBvcFJlc3RNYXliZShwKVxuICAgIC5tYXAoXG4gICAgICAoW3JldEt3ZCwgcmVzdF0pID0+XG4gICAgICAgIGlzS2V5d29yZChyZXRLd2QsICdyZXR1cm4nKSAmJiBnZXRMaW5lTnVtYmVyKHJldEt3ZCkgPT09IGwsXG4gICAgKVxuICAgIC5nZXRPckVsc2UoZmFsc2UpO1xufVxuXG4vLyBMaXN0IGEgLT4gQm9vbGVhblxuZnVuY3Rpb24gaXNUb3BQdW5jdHVhdG9yKHA6IExpc3Q8VG9rZW5UcmVlPikge1xuICByZXR1cm4gcG9wTWF5YmUocCkubWFwKHB1bmMgPT4gaXNQdW5jdHVhdG9yKHB1bmMpKS5nZXRPckVsc2UoZmFsc2UpO1xufVxuXG5mdW5jdGlvbiBpc09wZXJhdG9yKG9wOiBUb2tlblRyZWUpIHtcbiAgaWYgKChpc1B1bmN0dWF0b3Iob3ApIHx8IGlzS2V5d29yZChvcCkpICYmIG9wLnZhbHVlICE9IG51bGwpIHtcbiAgICBjb25zdCBvcFZhbCA9IG9wLnZhbHVlOyAvLyB0aGUgY29uc3QgaXMgYmVjYXVzZSBmbG93IGRvZXNuJ3Qga25vdyBvcC52YWx1ZSBpc24ndCBtdXRhdGVkXG4gICAgcmV0dXJuIGFsbE9wcy5zb21lKG8gPT4gbyA9PT0gb3BWYWwpO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNUb3BPcGVyYXRvcihwOiBMaXN0PFRva2VuVHJlZT4pIHtcbiAgcmV0dXJuIHBvcE1heWJlKHApXG4gICAgLm1hcChvcCA9PiB7XG4gICAgICByZXR1cm4gaXNPcGVyYXRvcihvcCk7XG4gICAgfSlcbiAgICAuZ2V0T3JFbHNlKGZhbHNlKTtcbn1cblxuZnVuY3Rpb24gaXNFeHByUHJlZml4S2V5d29yZChrd2Q6IFRva2VuVHJlZSkge1xuICByZXR1cm4gaXNLZXl3b3JkKGt3ZCwgZXhwclByZWZpeEtleXdvcmRzKTtcbn1cblxuZnVuY3Rpb24gaXNUb3BLZXl3b3JkRXhwclByZWZpeChwOiBMaXN0PFRva2VuVHJlZT4pIHtcbiAgcmV0dXJuIHBvcE1heWJlKHApXG4gICAgLm1hcChrd2QgPT4ge1xuICAgICAgcmV0dXJuIGlzRXhwclByZWZpeEtleXdvcmQoa3dkKTtcbiAgICB9KVxuICAgIC5nZXRPckVsc2UoZmFsc2UpO1xufVxuXG5mdW5jdGlvbiBpc1RvcENvbG9uKHA6IExpc3Q8VG9rZW5UcmVlPikge1xuICByZXR1cm4gcG9wTWF5YmUocClcbiAgICAubWFwKGNvbG9uID0+IHtcbiAgICAgIGlmIChpc1B1bmN0dWF0b3IoY29sb24sICc6JykpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSlcbiAgICAuZ2V0T3JFbHNlKGZhbHNlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRXhwclByZWZpeChsOiBudW1iZXIsIGI6IGJvb2xlYW4sIHA6IExpc3Q8VG9rZW5UcmVlPikge1xuICBpZiAocC5zaXplID09PSAwKSB7XG4gICAgLy8gLi4uICh7eDogNDJ9IC9yL2kpXG4gICAgcmV0dXJuIGI7XG4gIH0gZWxzZSBpZiAoaXNUb3BDb2xvbihwKSkge1xuICAgIC8vIC4uLiAoe3g6IHt4OiA0Mn0gL3IvaSB9KVxuICAgIHJldHVybiBiO1xuICB9IGVsc2UgaWYgKGlzVG9wS2V5d29yZEV4cHJQcmVmaXgocCkpIHtcbiAgICAvLyAuLi4gdGhyb3cge3g6IDQyfSAvci9pXG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSBpZiAoaXNUb3BPcGVyYXRvcihwKSkge1xuICAgIC8vIC4uLiA0MiArIHt4OiA0Mn0gL3IvaVxuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2UgaWYgKGlzVG9wUHVuY3R1YXRvcihwKSkge1xuICAgIC8vIC4uLiBmb3IgKCA7IHt4OiA0Mn0vci9pKVxuICAgIHJldHVybiBiO1xuICB9IGVsc2UgaWYgKGlzRXhwclJldHVybihsLCBwKSkge1xuICAgIC8vIC4uLiByZXR1cm4ge3g6IDQyfSAvciAvaVxuICAgIC8vIC4uLiByZXR1cm5cXG57eDogNDJ9IC9yIC9pXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBwb3BNYXliZTxUPihwOiBMaXN0PFQ+KTogTWF5YmU8VD4ge1xuICBpZiAocC5zaXplID49IDEpIHtcbiAgICByZXR1cm4gTWF5YmUub2YocC5sYXN0KCkpO1xuICB9XG4gIHJldHVybiBOb3RoaW5nKCk7XG59XG5cbmZ1bmN0aW9uIGlzVG9wU3RhbmRhbG9uZUtleXdvcmQocHJlZml4OiBMaXN0PFRva2VuVHJlZT4pIHtcbiAgLy8gUCAuIHQgLiB0JyAgd2hlcmUgdCBcXG5vdCA9IFwiLlwiIGFuZCB0JyDiiIggKEtleXdvcmQgXFxzZXRtaW51cyAgTGl0ZXJhbEtleXdvcmQpXG4gIHJldHVybiBwb3BSZXN0TWF5YmUocHJlZml4KVxuICAgIC5tYXAoKFtrd2QsIHJlc3RdKSA9PiB7XG4gICAgICBpZiAoaXNOb25MaXRlcmFsS2V5d29yZChrd2QpKSB7XG4gICAgICAgIHJldHVybiBNYXliZS5tYXliZShcbiAgICAgICAgICB0cnVlLFxuICAgICAgICAgIGRvdCA9PiAhaXNQdW5jdHVhdG9yKGRvdCwgJy4nKSxcbiAgICAgICAgICBwb3BNYXliZShyZXN0KSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9KVxuICAgIC5nZXRPckVsc2UoZmFsc2UpO1xufVxuXG5mdW5jdGlvbiBpc1RvcFBhcmVuc1dpdGhLZXl3b3JkKHByZWZpeDogTGlzdDxUb2tlblRyZWU+KSB7XG4gIC8vIFAgLiB0IC4gdCcgLiAoVCkgIHdoZXJlIHQgXFxub3QgPSBcIi5cIiBhbmQgdCcg4oiIIChLZXl3b3JkIFxcc2V0bWludXMgTGl0ZXJhbEtleXdvcmQpXG4gIHJldHVybiBwb3BSZXN0TWF5YmUocHJlZml4KVxuICAgIC5jaGFpbigoW3BhcmVuLCByZXN0XSkgPT4gaXNQYXJlbnMocGFyZW4pID8gcG9wUmVzdE1heWJlKHJlc3QpIDogTm90aGluZygpKVxuICAgIC5tYXAoKFtrd2QsIHJlc3RdKSA9PiB7XG4gICAgICBpZiAoaXNOb25MaXRlcmFsS2V5d29yZChrd2QpKSB7XG4gICAgICAgIHJldHVybiBNYXliZS5tYXliZShcbiAgICAgICAgICB0cnVlLFxuICAgICAgICAgIGRvdCA9PiAhaXNQdW5jdHVhdG9yKGRvdCwgJy4nKSxcbiAgICAgICAgICBwb3BNYXliZShyZXN0KSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9KVxuICAgIC5nZXRPckVsc2UoZmFsc2UpO1xufVxuXG5mdW5jdGlvbiBwb3BSZXN0TWF5YmUocDogTGlzdDxUb2tlblRyZWU+KTogTWF5YmU8W1Rva2VuVHJlZSwgTGlzdDxUb2tlblRyZWU+XT4ge1xuICBpZiAocC5zaXplID4gMCkge1xuICAgIGxldCBsYXN0ID0gcC5sYXN0KCk7XG4gICAgbGV0IHJlc3QgPSBwLnBvcCgpO1xuICAgIHJldHVybiBNYXliZS5vZihbbGFzdCwgcmVzdF0pO1xuICB9XG4gIHJldHVybiBOb3RoaW5nKCk7XG59XG5cbmZ1bmN0aW9uIGlzVG9wRnVuY3Rpb25FeHByZXNzaW9uKFxuICBwcmVmaXg6IExpc3Q8VG9rZW5UcmVlPixcbiAgZXhwckFsbG93ZWQ6IGJvb2xlYW4sXG4pIHtcbiAgLy8gUCAuIGZ1bmN0aW9uXmwgLiB4PyAuICgpIC4ge30gICAgIHdoZXJlIGlzRXhwclByZWZpeChQLCBiLCBsKSA9IGZhbHNlXG4gIHJldHVybiBwb3BSZXN0TWF5YmUocHJlZml4KVxuICAgIC5jaGFpbigoW2N1cmx5LCByZXN0XSkgPT4ge1xuICAgICAgaWYgKGlzQnJhY2VzKGN1cmx5KSkge1xuICAgICAgICByZXR1cm4gcG9wUmVzdE1heWJlKHJlc3QpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIE5vdGhpbmcoKTtcbiAgICB9KVxuICAgIC5jaGFpbigoW3BhcmVuLCByZXN0XSkgPT4ge1xuICAgICAgaWYgKGlzUGFyZW5zKHBhcmVuKSkge1xuICAgICAgICByZXR1cm4gcG9wUmVzdE1heWJlKHJlc3QpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIE5vdGhpbmcoKTtcbiAgICB9KVxuICAgIC5jaGFpbigoW29wdElkZW50LCByZXN0XSkgPT4ge1xuICAgICAgaWYgKGlzSWRlbnRpZmllcihvcHRJZGVudCkpIHtcbiAgICAgICAgcmV0dXJuIHBvcFJlc3RNYXliZShyZXN0KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBNYXliZS5vZihbb3B0SWRlbnQsIHJlc3RdKTtcbiAgICB9KVxuICAgIC5jaGFpbigoW2ZuS3dkLCByZXN0XSkgPT4ge1xuICAgICAgaWYgKGlzS2V5d29yZChmbkt3ZCwgJ2Z1bmN0aW9uJykpIHtcbiAgICAgICAgbGV0IGwgPSBnZXRMaW5lTnVtYmVyKGZuS3dkKTtcbiAgICAgICAgaWYgKGwgPT0gbnVsbCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW4tZXhwZWN0ZWQgbnVsbCBsaW5lIG51bWJlcicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBNYXliZS5vZighaXNFeHByUHJlZml4KGwsIGV4cHJBbGxvd2VkLCByZXN0KSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gTWF5YmUub2YoZmFsc2UpO1xuICAgIH0pXG4gICAgLmdldE9yRWxzZShmYWxzZSk7XG59XG5cbmZ1bmN0aW9uIGlzVG9wT2JqZWN0TGl0ZXJhbChwcmVmaXg6IExpc3Q8VG9rZW5UcmVlPiwgZXhwckFsbG93ZWQ6IGJvb2xlYW4pIHtcbiAgLy8gUCAuIHtUfV5sICB3aGVyZSBpc0V4cHJQcmVmaXgoUCwgYiwgbCkgPSBmYWxzZVxuICByZXR1cm4gcG9wUmVzdE1heWJlKHByZWZpeClcbiAgICAuY2hhaW4oKFticmFjZXMsIHJlc3RdKSA9PiB7XG4gICAgICBpZiAoaXNCcmFjZXMoYnJhY2VzKSkge1xuICAgICAgICBsZXQgbCA9IGdldExpbmVOdW1iZXIoYnJhY2VzKTtcbiAgICAgICAgaWYgKGwgPT0gbnVsbCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW4tZXhwZWN0ZWQgbnVsbCBsaW5lIG51bWJlcicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBNYXliZS5vZighaXNFeHByUHJlZml4KGwsIGV4cHJBbGxvd2VkLCByZXN0KSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gTWF5YmUub2YoZmFsc2UpO1xuICAgIH0pXG4gICAgLmdldE9yRWxzZShmYWxzZSk7XG59XG5cbmZ1bmN0aW9uIGlzVG9wRnVuY3Rpb24ocHJlZml4OiBMaXN0PFRva2VuVHJlZT4pIHtcbiAgLy8gUCAuIGZ1bmN0aW9uXmwgLiB4PyAuICgpIC4ge30gICAgIHdoZXJlIGlzRXhwclByZWZpeChQLCBiLCBsKSA9IGZhbHNlXG4gIHJldHVybiBwb3BSZXN0TWF5YmUocHJlZml4KVxuICAgIC5jaGFpbigoW2N1cmx5LCByZXN0XSkgPT4ge1xuICAgICAgaWYgKGlzQnJhY2VzKGN1cmx5KSkge1xuICAgICAgICByZXR1cm4gcG9wUmVzdE1heWJlKHJlc3QpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIE5vdGhpbmcoKTtcbiAgICB9KVxuICAgIC5jaGFpbigoW3BhcmVuLCByZXN0XSkgPT4ge1xuICAgICAgaWYgKGlzUGFyZW5zKHBhcmVuKSkge1xuICAgICAgICByZXR1cm4gcG9wUmVzdE1heWJlKHJlc3QpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIE5vdGhpbmcoKTtcbiAgICB9KVxuICAgIC5jaGFpbigoW29wdElkZW50LCByZXN0XSkgPT4ge1xuICAgICAgaWYgKGlzSWRlbnRpZmllcihvcHRJZGVudCkpIHtcbiAgICAgICAgcmV0dXJuIHBvcFJlc3RNYXliZShyZXN0KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBNYXliZS5vZihbb3B0SWRlbnQsIHJlc3RdKTtcbiAgICB9KVxuICAgIC5jaGFpbigoW2ZuS3dkLCByZXN0XSkgPT4ge1xuICAgICAgaWYgKGlzS2V5d29yZChmbkt3ZCwgJ2Z1bmN0aW9uJykpIHtcbiAgICAgICAgcmV0dXJuIE1heWJlLm9mKHRydWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIE1heWJlLm9mKGZhbHNlKTtcbiAgICB9KVxuICAgIC5nZXRPckVsc2UoZmFsc2UpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNSZWdleFByZWZpeChleHByQWxsb3dlZDogYm9vbGVhbiwgcHJlZml4OiBMaXN0PFRva2VuVHJlZT4pIHtcbiAgaWYgKHByZWZpeC5pc0VtcHR5KCkpIHtcbiAgICAvLyDOtVxuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2UgaWYgKGlzVG9wUHVuY3R1YXRvcihwcmVmaXgpKSB7XG4gICAgLy8gUCAuIHQgICB3aGVyZSB0IOKIiCBQdW5jdHVhdG9yXG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSBpZiAoaXNUb3BTdGFuZGFsb25lS2V5d29yZChwcmVmaXgpKSB7XG4gICAgLy8gUCAuIHQgLiB0JyAgd2hlcmUgdCBcXG5vdCA9IFwiLlwiIGFuZCB0JyDiiIggKEtleXdvcmQgXFxzZXRtaW51cyAgTGl0ZXJhbEtleXdvcmQpXG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSBpZiAoaXNUb3BQYXJlbnNXaXRoS2V5d29yZChwcmVmaXgpKSB7XG4gICAgLy8gUCAuIHQgLiB0JyAuIChUKSAgd2hlcmUgdCBcXG5vdCA9IFwiLlwiIGFuZCB0JyDiiIggKEtleXdvcmQgXFxzZXRtaW51cyBMaXRlcmFsS2V5d29yZClcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmIChpc1RvcEZ1bmN0aW9uKHByZWZpeCkpIHtcbiAgICAvLyBQIC4gZnVuY3Rpb25ebCAuIHg/IC4gKCkgLiB7fSAgICAgd2hlcmUgaXNFeHByUHJlZml4KFAsIGIsIGwpID0gZmFsc2VcbiAgICByZXR1cm4gaXNUb3BGdW5jdGlvbkV4cHJlc3Npb24ocHJlZml4LCBleHByQWxsb3dlZCk7XG4gIH0gZWxzZSBpZiAoaXNUb3BPYmplY3RMaXRlcmFsKHByZWZpeCwgZXhwckFsbG93ZWQpKSB7XG4gICAgLy8gUCAuIHtUfV5sICB3aGVyZSBpc0V4cHJQcmVmaXgoUCwgYiwgbCkgPSBmYWxzZVxuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cbiJdfQ==\n\n/***/ },\n/* 15 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/*\n\t  Copyright (C) 2013 Yusuke Suzuki <utatane.tea@gmail.com>\n\n\t  Redistribution and use in source and binary forms, with or without\n\t  modification, are permitted provided that the following conditions are met:\n\n\t    * Redistributions of source code must retain the above copyright\n\t      notice, this list of conditions and the following disclaimer.\n\t    * Redistributions in binary form must reproduce the above copyright\n\t      notice, this list of conditions and the following disclaimer in the\n\t      documentation and/or other materials provided with the distribution.\n\n\t  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n\t  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\t  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n\t  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\n\t  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n\t  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n\t  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n\t  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\t  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n\t  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\t*/\n\n\n\t(function () {\n\t    'use strict';\n\n\t    exports.ast = __webpack_require__(16);\n\t    exports.code = __webpack_require__(17);\n\t    exports.keyword = __webpack_require__(18);\n\t}());\n\t/* vim: set sw=4 ts=4 et tw=80 : */\n\n\n/***/ },\n/* 16 */\n/***/ function(module, exports) {\n\n\t/*\n\t  Copyright (C) 2013 Yusuke Suzuki <utatane.tea@gmail.com>\n\n\t  Redistribution and use in source and binary forms, with or without\n\t  modification, are permitted provided that the following conditions are met:\n\n\t    * Redistributions of source code must retain the above copyright\n\t      notice, this list of conditions and the following disclaimer.\n\t    * Redistributions in binary form must reproduce the above copyright\n\t      notice, this list of conditions and the following disclaimer in the\n\t      documentation and/or other materials provided with the distribution.\n\n\t  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'\n\t  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\t  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n\t  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\n\t  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n\t  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n\t  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n\t  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\t  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n\t  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\t*/\n\n\t(function () {\n\t    'use strict';\n\n\t    function isExpression(node) {\n\t        if (node == null) { return false; }\n\t        switch (node.type) {\n\t            case 'ArrayExpression':\n\t            case 'AssignmentExpression':\n\t            case 'BinaryExpression':\n\t            case 'CallExpression':\n\t            case 'ConditionalExpression':\n\t            case 'FunctionExpression':\n\t            case 'Identifier':\n\t            case 'Literal':\n\t            case 'LogicalExpression':\n\t            case 'MemberExpression':\n\t            case 'NewExpression':\n\t            case 'ObjectExpression':\n\t            case 'SequenceExpression':\n\t            case 'ThisExpression':\n\t            case 'UnaryExpression':\n\t            case 'UpdateExpression':\n\t                return true;\n\t        }\n\t        return false;\n\t    }\n\n\t    function isIterationStatement(node) {\n\t        if (node == null) { return false; }\n\t        switch (node.type) {\n\t            case 'DoWhileStatement':\n\t            case 'ForInStatement':\n\t            case 'ForStatement':\n\t            case 'WhileStatement':\n\t                return true;\n\t        }\n\t        return false;\n\t    }\n\n\t    function isStatement(node) {\n\t        if (node == null) { return false; }\n\t        switch (node.type) {\n\t            case 'BlockStatement':\n\t            case 'BreakStatement':\n\t            case 'ContinueStatement':\n\t            case 'DebuggerStatement':\n\t            case 'DoWhileStatement':\n\t            case 'EmptyStatement':\n\t            case 'ExpressionStatement':\n\t            case 'ForInStatement':\n\t            case 'ForStatement':\n\t            case 'IfStatement':\n\t            case 'LabeledStatement':\n\t            case 'ReturnStatement':\n\t            case 'SwitchStatement':\n\t            case 'ThrowStatement':\n\t            case 'TryStatement':\n\t            case 'VariableDeclaration':\n\t            case 'WhileStatement':\n\t            case 'WithStatement':\n\t                return true;\n\t        }\n\t        return false;\n\t    }\n\n\t    function isSourceElement(node) {\n\t      return isStatement(node) || node != null && node.type === 'FunctionDeclaration';\n\t    }\n\n\t    function trailingStatement(node) {\n\t        switch (node.type) {\n\t        case 'IfStatement':\n\t            if (node.alternate != null) {\n\t                return node.alternate;\n\t            }\n\t            return node.consequent;\n\n\t        case 'LabeledStatement':\n\t        case 'ForStatement':\n\t        case 'ForInStatement':\n\t        case 'WhileStatement':\n\t        case 'WithStatement':\n\t            return node.body;\n\t        }\n\t        return null;\n\t    }\n\n\t    function isProblematicIfStatement(node) {\n\t        var current;\n\n\t        if (node.type !== 'IfStatement') {\n\t            return false;\n\t        }\n\t        if (node.alternate == null) {\n\t            return false;\n\t        }\n\t        current = node.consequent;\n\t        do {\n\t            if (current.type === 'IfStatement') {\n\t                if (current.alternate == null)  {\n\t                    return true;\n\t                }\n\t            }\n\t            current = trailingStatement(current);\n\t        } while (current);\n\n\t        return false;\n\t    }\n\n\t    module.exports = {\n\t        isExpression: isExpression,\n\t        isStatement: isStatement,\n\t        isIterationStatement: isIterationStatement,\n\t        isSourceElement: isSourceElement,\n\t        isProblematicIfStatement: isProblematicIfStatement,\n\n\t        trailingStatement: trailingStatement\n\t    };\n\t}());\n\t/* vim: set sw=4 ts=4 et tw=80 : */\n\n\n/***/ },\n/* 17 */\n/***/ function(module, exports) {\n\n\t/*\n\t  Copyright (C) 2013-2014 Yusuke Suzuki <utatane.tea@gmail.com>\n\t  Copyright (C) 2014 Ivan Nikulin <ifaaan@gmail.com>\n\n\t  Redistribution and use in source and binary forms, with or without\n\t  modification, are permitted provided that the following conditions are met:\n\n\t    * Redistributions of source code must retain the above copyright\n\t      notice, this list of conditions and the following disclaimer.\n\t    * Redistributions in binary form must reproduce the above copyright\n\t      notice, this list of conditions and the following disclaimer in the\n\t      documentation and/or other materials provided with the distribution.\n\n\t  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n\t  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\t  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n\t  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\n\t  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n\t  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n\t  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n\t  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\t  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n\t  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\t*/\n\n\t(function () {\n\t    'use strict';\n\n\t    var ES6Regex, ES5Regex, NON_ASCII_WHITESPACES, IDENTIFIER_START, IDENTIFIER_PART, ch;\n\n\t    // See `tools/generate-identifier-regex.js`.\n\t    ES5Regex = {\n\t        // ECMAScript 5.1/Unicode v7.0.0 NonAsciiIdentifierStart:\n\t        NonAsciiIdentifierStart: /[\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u08A0-\\u08B2\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F8\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1CF5\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6EF\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA7AD\\uA7B0\\uA7B1\\uA7F7-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB5F\\uAB64\\uAB65\\uABC0-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]/,\n\t        // ECMAScript 5.1/Unicode v7.0.0 NonAsciiIdentifierPart:\n\t        NonAsciiIdentifierPart: /[\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0300-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u0483-\\u0487\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0610-\\u061A\\u0620-\\u0669\\u066E-\\u06D3\\u06D5-\\u06DC\\u06DF-\\u06E8\\u06EA-\\u06FC\\u06FF\\u0710-\\u074A\\u074D-\\u07B1\\u07C0-\\u07F5\\u07FA\\u0800-\\u082D\\u0840-\\u085B\\u08A0-\\u08B2\\u08E4-\\u0963\\u0966-\\u096F\\u0971-\\u0983\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BC-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CE\\u09D7\\u09DC\\u09DD\\u09DF-\\u09E3\\u09E6-\\u09F1\\u0A01-\\u0A03\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A59-\\u0A5C\\u0A5E\\u0A66-\\u0A75\\u0A81-\\u0A83\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABC-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0AD0\\u0AE0-\\u0AE3\\u0AE6-\\u0AEF\\u0B01-\\u0B03\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3C-\\u0B44\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B5C\\u0B5D\\u0B5F-\\u0B63\\u0B66-\\u0B6F\\u0B71\\u0B82\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD0\\u0BD7\\u0BE6-\\u0BEF\\u0C00-\\u0C03\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C58\\u0C59\\u0C60-\\u0C63\\u0C66-\\u0C6F\\u0C81-\\u0C83\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBC-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0CDE\\u0CE0-\\u0CE3\\u0CE6-\\u0CEF\\u0CF1\\u0CF2\\u0D01-\\u0D03\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D-\\u0D44\\u0D46-\\u0D48\\u0D4A-\\u0D4E\\u0D57\\u0D60-\\u0D63\\u0D66-\\u0D6F\\u0D7A-\\u0D7F\\u0D82\\u0D83\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0DCA\\u0DCF-\\u0DD4\\u0DD6\\u0DD8-\\u0DDF\\u0DE6-\\u0DEF\\u0DF2\\u0DF3\\u0E01-\\u0E3A\\u0E40-\\u0E4E\\u0E50-\\u0E59\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB9\\u0EBB-\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EC8-\\u0ECD\\u0ED0-\\u0ED9\\u0EDC-\\u0EDF\\u0F00\\u0F18\\u0F19\\u0F20-\\u0F29\\u0F35\\u0F37\\u0F39\\u0F3E-\\u0F47\\u0F49-\\u0F6C\\u0F71-\\u0F84\\u0F86-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u1000-\\u1049\\u1050-\\u109D\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u135D-\\u135F\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F8\\u1700-\\u170C\\u170E-\\u1714\\u1720-\\u1734\\u1740-\\u1753\\u1760-\\u176C\\u176E-\\u1770\\u1772\\u1773\\u1780-\\u17D3\\u17D7\\u17DC\\u17DD\\u17E0-\\u17E9\\u180B-\\u180D\\u1810-\\u1819\\u1820-\\u1877\\u1880-\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1920-\\u192B\\u1930-\\u193B\\u1946-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u19D0-\\u19D9\\u1A00-\\u1A1B\\u1A20-\\u1A5E\\u1A60-\\u1A7C\\u1A7F-\\u1A89\\u1A90-\\u1A99\\u1AA7\\u1AB0-\\u1ABD\\u1B00-\\u1B4B\\u1B50-\\u1B59\\u1B6B-\\u1B73\\u1B80-\\u1BF3\\u1C00-\\u1C37\\u1C40-\\u1C49\\u1C4D-\\u1C7D\\u1CD0-\\u1CD2\\u1CD4-\\u1CF6\\u1CF8\\u1CF9\\u1D00-\\u1DF5\\u1DFC-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u200C\\u200D\\u203F\\u2040\\u2054\\u2071\\u207F\\u2090-\\u209C\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D7F-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2DE0-\\u2DFF\\u2E2F\\u3005-\\u3007\\u3021-\\u302F\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u3099\\u309A\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA62B\\uA640-\\uA66F\\uA674-\\uA67D\\uA67F-\\uA69D\\uA69F-\\uA6F1\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA7AD\\uA7B0\\uA7B1\\uA7F7-\\uA827\\uA840-\\uA873\\uA880-\\uA8C4\\uA8D0-\\uA8D9\\uA8E0-\\uA8F7\\uA8FB\\uA900-\\uA92D\\uA930-\\uA953\\uA960-\\uA97C\\uA980-\\uA9C0\\uA9CF-\\uA9D9\\uA9E0-\\uA9FE\\uAA00-\\uAA36\\uAA40-\\uAA4D\\uAA50-\\uAA59\\uAA60-\\uAA76\\uAA7A-\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEF\\uAAF2-\\uAAF6\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB5F\\uAB64\\uAB65\\uABC0-\\uABEA\\uABEC\\uABED\\uABF0-\\uABF9\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE00-\\uFE0F\\uFE20-\\uFE2D\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF10-\\uFF19\\uFF21-\\uFF3A\\uFF3F\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]/\n\t    };\n\n\t    ES6Regex = {\n\t        // ECMAScript 6/Unicode v7.0.0 NonAsciiIdentifierStart:\n\t        NonAsciiIdentifierStart: /[\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u08A0-\\u08B2\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F8\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1CF5\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2118-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u309B-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6EF\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA7AD\\uA7B0\\uA7B1\\uA7F7-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB5F\\uAB64\\uAB65\\uABC0-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDD40-\\uDD74\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDF00-\\uDF1F\\uDF30-\\uDF4A\\uDF50-\\uDF75\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF\\uDFD1-\\uDFD5]|\\uD801[\\uDC00-\\uDC9D\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00\\uDE10-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE33\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE4\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48]|\\uD804[\\uDC03-\\uDC37\\uDC83-\\uDCAF\\uDCD0-\\uDCE8\\uDD03-\\uDD26\\uDD50-\\uDD72\\uDD76\\uDD83-\\uDDB2\\uDDC1-\\uDDC4\\uDDDA\\uDE00-\\uDE11\\uDE13-\\uDE2B\\uDEB0-\\uDEDE\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3D\\uDF5D-\\uDF61]|\\uD805[\\uDC80-\\uDCAF\\uDCC4\\uDCC5\\uDCC7\\uDD80-\\uDDAE\\uDE00-\\uDE2F\\uDE44\\uDE80-\\uDEAA]|\\uD806[\\uDCA0-\\uDCDF\\uDCFF\\uDEC0-\\uDEF8]|\\uD808[\\uDC00-\\uDF98]|\\uD809[\\uDC00-\\uDC6E]|[\\uD80C\\uD840-\\uD868\\uD86A-\\uD86C][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDED0-\\uDEED\\uDF00-\\uDF2F\\uDF40-\\uDF43\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDF00-\\uDF44\\uDF50\\uDF93-\\uDF9F]|\\uD82C[\\uDC00\\uDC01]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB]|\\uD83A[\\uDC00-\\uDCC4]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDED6\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF34\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D]|\\uD87E[\\uDC00-\\uDE1D]/,\n\t        // ECMAScript 6/Unicode v7.0.0 NonAsciiIdentifierPart:\n\t        NonAsciiIdentifierPart: /[\\xAA\\xB5\\xB7\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0300-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u0483-\\u0487\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0610-\\u061A\\u0620-\\u0669\\u066E-\\u06D3\\u06D5-\\u06DC\\u06DF-\\u06E8\\u06EA-\\u06FC\\u06FF\\u0710-\\u074A\\u074D-\\u07B1\\u07C0-\\u07F5\\u07FA\\u0800-\\u082D\\u0840-\\u085B\\u08A0-\\u08B2\\u08E4-\\u0963\\u0966-\\u096F\\u0971-\\u0983\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BC-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CE\\u09D7\\u09DC\\u09DD\\u09DF-\\u09E3\\u09E6-\\u09F1\\u0A01-\\u0A03\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A59-\\u0A5C\\u0A5E\\u0A66-\\u0A75\\u0A81-\\u0A83\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABC-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0AD0\\u0AE0-\\u0AE3\\u0AE6-\\u0AEF\\u0B01-\\u0B03\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3C-\\u0B44\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B5C\\u0B5D\\u0B5F-\\u0B63\\u0B66-\\u0B6F\\u0B71\\u0B82\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD0\\u0BD7\\u0BE6-\\u0BEF\\u0C00-\\u0C03\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C58\\u0C59\\u0C60-\\u0C63\\u0C66-\\u0C6F\\u0C81-\\u0C83\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBC-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0CDE\\u0CE0-\\u0CE3\\u0CE6-\\u0CEF\\u0CF1\\u0CF2\\u0D01-\\u0D03\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D-\\u0D44\\u0D46-\\u0D48\\u0D4A-\\u0D4E\\u0D57\\u0D60-\\u0D63\\u0D66-\\u0D6F\\u0D7A-\\u0D7F\\u0D82\\u0D83\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0DCA\\u0DCF-\\u0DD4\\u0DD6\\u0DD8-\\u0DDF\\u0DE6-\\u0DEF\\u0DF2\\u0DF3\\u0E01-\\u0E3A\\u0E40-\\u0E4E\\u0E50-\\u0E59\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB9\\u0EBB-\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EC8-\\u0ECD\\u0ED0-\\u0ED9\\u0EDC-\\u0EDF\\u0F00\\u0F18\\u0F19\\u0F20-\\u0F29\\u0F35\\u0F37\\u0F39\\u0F3E-\\u0F47\\u0F49-\\u0F6C\\u0F71-\\u0F84\\u0F86-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u1000-\\u1049\\u1050-\\u109D\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u135D-\\u135F\\u1369-\\u1371\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F8\\u1700-\\u170C\\u170E-\\u1714\\u1720-\\u1734\\u1740-\\u1753\\u1760-\\u176C\\u176E-\\u1770\\u1772\\u1773\\u1780-\\u17D3\\u17D7\\u17DC\\u17DD\\u17E0-\\u17E9\\u180B-\\u180D\\u1810-\\u1819\\u1820-\\u1877\\u1880-\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1920-\\u192B\\u1930-\\u193B\\u1946-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u19D0-\\u19DA\\u1A00-\\u1A1B\\u1A20-\\u1A5E\\u1A60-\\u1A7C\\u1A7F-\\u1A89\\u1A90-\\u1A99\\u1AA7\\u1AB0-\\u1ABD\\u1B00-\\u1B4B\\u1B50-\\u1B59\\u1B6B-\\u1B73\\u1B80-\\u1BF3\\u1C00-\\u1C37\\u1C40-\\u1C49\\u1C4D-\\u1C7D\\u1CD0-\\u1CD2\\u1CD4-\\u1CF6\\u1CF8\\u1CF9\\u1D00-\\u1DF5\\u1DFC-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u200C\\u200D\\u203F\\u2040\\u2054\\u2071\\u207F\\u2090-\\u209C\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2118-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D7F-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2DE0-\\u2DFF\\u3005-\\u3007\\u3021-\\u302F\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u3099-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA62B\\uA640-\\uA66F\\uA674-\\uA67D\\uA67F-\\uA69D\\uA69F-\\uA6F1\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA7AD\\uA7B0\\uA7B1\\uA7F7-\\uA827\\uA840-\\uA873\\uA880-\\uA8C4\\uA8D0-\\uA8D9\\uA8E0-\\uA8F7\\uA8FB\\uA900-\\uA92D\\uA930-\\uA953\\uA960-\\uA97C\\uA980-\\uA9C0\\uA9CF-\\uA9D9\\uA9E0-\\uA9FE\\uAA00-\\uAA36\\uAA40-\\uAA4D\\uAA50-\\uAA59\\uAA60-\\uAA76\\uAA7A-\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEF\\uAAF2-\\uAAF6\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB5F\\uAB64\\uAB65\\uABC0-\\uABEA\\uABEC\\uABED\\uABF0-\\uABF9\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE00-\\uFE0F\\uFE20-\\uFE2D\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF10-\\uFF19\\uFF21-\\uFF3A\\uFF3F\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]|\\uD800[\\uDC00-\\uDC0B\\uDC0D-\\uDC26\\uDC28-\\uDC3A\\uDC3C\\uDC3D\\uDC3F-\\uDC4D\\uDC50-\\uDC5D\\uDC80-\\uDCFA\\uDD40-\\uDD74\\uDDFD\\uDE80-\\uDE9C\\uDEA0-\\uDED0\\uDEE0\\uDF00-\\uDF1F\\uDF30-\\uDF4A\\uDF50-\\uDF7A\\uDF80-\\uDF9D\\uDFA0-\\uDFC3\\uDFC8-\\uDFCF\\uDFD1-\\uDFD5]|\\uD801[\\uDC00-\\uDC9D\\uDCA0-\\uDCA9\\uDD00-\\uDD27\\uDD30-\\uDD63\\uDE00-\\uDF36\\uDF40-\\uDF55\\uDF60-\\uDF67]|\\uD802[\\uDC00-\\uDC05\\uDC08\\uDC0A-\\uDC35\\uDC37\\uDC38\\uDC3C\\uDC3F-\\uDC55\\uDC60-\\uDC76\\uDC80-\\uDC9E\\uDD00-\\uDD15\\uDD20-\\uDD39\\uDD80-\\uDDB7\\uDDBE\\uDDBF\\uDE00-\\uDE03\\uDE05\\uDE06\\uDE0C-\\uDE13\\uDE15-\\uDE17\\uDE19-\\uDE33\\uDE38-\\uDE3A\\uDE3F\\uDE60-\\uDE7C\\uDE80-\\uDE9C\\uDEC0-\\uDEC7\\uDEC9-\\uDEE6\\uDF00-\\uDF35\\uDF40-\\uDF55\\uDF60-\\uDF72\\uDF80-\\uDF91]|\\uD803[\\uDC00-\\uDC48]|\\uD804[\\uDC00-\\uDC46\\uDC66-\\uDC6F\\uDC7F-\\uDCBA\\uDCD0-\\uDCE8\\uDCF0-\\uDCF9\\uDD00-\\uDD34\\uDD36-\\uDD3F\\uDD50-\\uDD73\\uDD76\\uDD80-\\uDDC4\\uDDD0-\\uDDDA\\uDE00-\\uDE11\\uDE13-\\uDE37\\uDEB0-\\uDEEA\\uDEF0-\\uDEF9\\uDF01-\\uDF03\\uDF05-\\uDF0C\\uDF0F\\uDF10\\uDF13-\\uDF28\\uDF2A-\\uDF30\\uDF32\\uDF33\\uDF35-\\uDF39\\uDF3C-\\uDF44\\uDF47\\uDF48\\uDF4B-\\uDF4D\\uDF57\\uDF5D-\\uDF63\\uDF66-\\uDF6C\\uDF70-\\uDF74]|\\uD805[\\uDC80-\\uDCC5\\uDCC7\\uDCD0-\\uDCD9\\uDD80-\\uDDB5\\uDDB8-\\uDDC0\\uDE00-\\uDE40\\uDE44\\uDE50-\\uDE59\\uDE80-\\uDEB7\\uDEC0-\\uDEC9]|\\uD806[\\uDCA0-\\uDCE9\\uDCFF\\uDEC0-\\uDEF8]|\\uD808[\\uDC00-\\uDF98]|\\uD809[\\uDC00-\\uDC6E]|[\\uD80C\\uD840-\\uD868\\uD86A-\\uD86C][\\uDC00-\\uDFFF]|\\uD80D[\\uDC00-\\uDC2E]|\\uD81A[\\uDC00-\\uDE38\\uDE40-\\uDE5E\\uDE60-\\uDE69\\uDED0-\\uDEED\\uDEF0-\\uDEF4\\uDF00-\\uDF36\\uDF40-\\uDF43\\uDF50-\\uDF59\\uDF63-\\uDF77\\uDF7D-\\uDF8F]|\\uD81B[\\uDF00-\\uDF44\\uDF50-\\uDF7E\\uDF8F-\\uDF9F]|\\uD82C[\\uDC00\\uDC01]|\\uD82F[\\uDC00-\\uDC6A\\uDC70-\\uDC7C\\uDC80-\\uDC88\\uDC90-\\uDC99\\uDC9D\\uDC9E]|\\uD834[\\uDD65-\\uDD69\\uDD6D-\\uDD72\\uDD7B-\\uDD82\\uDD85-\\uDD8B\\uDDAA-\\uDDAD\\uDE42-\\uDE44]|\\uD835[\\uDC00-\\uDC54\\uDC56-\\uDC9C\\uDC9E\\uDC9F\\uDCA2\\uDCA5\\uDCA6\\uDCA9-\\uDCAC\\uDCAE-\\uDCB9\\uDCBB\\uDCBD-\\uDCC3\\uDCC5-\\uDD05\\uDD07-\\uDD0A\\uDD0D-\\uDD14\\uDD16-\\uDD1C\\uDD1E-\\uDD39\\uDD3B-\\uDD3E\\uDD40-\\uDD44\\uDD46\\uDD4A-\\uDD50\\uDD52-\\uDEA5\\uDEA8-\\uDEC0\\uDEC2-\\uDEDA\\uDEDC-\\uDEFA\\uDEFC-\\uDF14\\uDF16-\\uDF34\\uDF36-\\uDF4E\\uDF50-\\uDF6E\\uDF70-\\uDF88\\uDF8A-\\uDFA8\\uDFAA-\\uDFC2\\uDFC4-\\uDFCB\\uDFCE-\\uDFFF]|\\uD83A[\\uDC00-\\uDCC4\\uDCD0-\\uDCD6]|\\uD83B[\\uDE00-\\uDE03\\uDE05-\\uDE1F\\uDE21\\uDE22\\uDE24\\uDE27\\uDE29-\\uDE32\\uDE34-\\uDE37\\uDE39\\uDE3B\\uDE42\\uDE47\\uDE49\\uDE4B\\uDE4D-\\uDE4F\\uDE51\\uDE52\\uDE54\\uDE57\\uDE59\\uDE5B\\uDE5D\\uDE5F\\uDE61\\uDE62\\uDE64\\uDE67-\\uDE6A\\uDE6C-\\uDE72\\uDE74-\\uDE77\\uDE79-\\uDE7C\\uDE7E\\uDE80-\\uDE89\\uDE8B-\\uDE9B\\uDEA1-\\uDEA3\\uDEA5-\\uDEA9\\uDEAB-\\uDEBB]|\\uD869[\\uDC00-\\uDED6\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF34\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D]|\\uD87E[\\uDC00-\\uDE1D]|\\uDB40[\\uDD00-\\uDDEF]/\n\t    };\n\n\t    function isDecimalDigit(ch) {\n\t        return 0x30 <= ch && ch <= 0x39;  // 0..9\n\t    }\n\n\t    function isHexDigit(ch) {\n\t        return 0x30 <= ch && ch <= 0x39 ||  // 0..9\n\t            0x61 <= ch && ch <= 0x66 ||     // a..f\n\t            0x41 <= ch && ch <= 0x46;       // A..F\n\t    }\n\n\t    function isOctalDigit(ch) {\n\t        return ch >= 0x30 && ch <= 0x37;  // 0..7\n\t    }\n\n\t    // 7.2 White Space\n\n\t    NON_ASCII_WHITESPACES = [\n\t        0x1680, 0x180E,\n\t        0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A,\n\t        0x202F, 0x205F,\n\t        0x3000,\n\t        0xFEFF\n\t    ];\n\n\t    function isWhiteSpace(ch) {\n\t        return ch === 0x20 || ch === 0x09 || ch === 0x0B || ch === 0x0C || ch === 0xA0 ||\n\t            ch >= 0x1680 && NON_ASCII_WHITESPACES.indexOf(ch) >= 0;\n\t    }\n\n\t    // 7.3 Line Terminators\n\n\t    function isLineTerminator(ch) {\n\t        return ch === 0x0A || ch === 0x0D || ch === 0x2028 || ch === 0x2029;\n\t    }\n\n\t    // 7.6 Identifier Names and Identifiers\n\n\t    function fromCodePoint(cp) {\n\t        if (cp <= 0xFFFF) { return String.fromCharCode(cp); }\n\t        var cu1 = String.fromCharCode(Math.floor((cp - 0x10000) / 0x400) + 0xD800);\n\t        var cu2 = String.fromCharCode(((cp - 0x10000) % 0x400) + 0xDC00);\n\t        return cu1 + cu2;\n\t    }\n\n\t    IDENTIFIER_START = new Array(0x80);\n\t    for(ch = 0; ch < 0x80; ++ch) {\n\t        IDENTIFIER_START[ch] =\n\t            ch >= 0x61 && ch <= 0x7A ||  // a..z\n\t            ch >= 0x41 && ch <= 0x5A ||  // A..Z\n\t            ch === 0x24 || ch === 0x5F;  // $ (dollar) and _ (underscore)\n\t    }\n\n\t    IDENTIFIER_PART = new Array(0x80);\n\t    for(ch = 0; ch < 0x80; ++ch) {\n\t        IDENTIFIER_PART[ch] =\n\t            ch >= 0x61 && ch <= 0x7A ||  // a..z\n\t            ch >= 0x41 && ch <= 0x5A ||  // A..Z\n\t            ch >= 0x30 && ch <= 0x39 ||  // 0..9\n\t            ch === 0x24 || ch === 0x5F;  // $ (dollar) and _ (underscore)\n\t    }\n\n\t    function isIdentifierStartES5(ch) {\n\t        return ch < 0x80 ? IDENTIFIER_START[ch] : ES5Regex.NonAsciiIdentifierStart.test(fromCodePoint(ch));\n\t    }\n\n\t    function isIdentifierPartES5(ch) {\n\t        return ch < 0x80 ? IDENTIFIER_PART[ch] : ES5Regex.NonAsciiIdentifierPart.test(fromCodePoint(ch));\n\t    }\n\n\t    function isIdentifierStartES6(ch) {\n\t        return ch < 0x80 ? IDENTIFIER_START[ch] : ES6Regex.NonAsciiIdentifierStart.test(fromCodePoint(ch));\n\t    }\n\n\t    function isIdentifierPartES6(ch) {\n\t        return ch < 0x80 ? IDENTIFIER_PART[ch] : ES6Regex.NonAsciiIdentifierPart.test(fromCodePoint(ch));\n\t    }\n\n\t    module.exports = {\n\t        isDecimalDigit: isDecimalDigit,\n\t        isHexDigit: isHexDigit,\n\t        isOctalDigit: isOctalDigit,\n\t        isWhiteSpace: isWhiteSpace,\n\t        isLineTerminator: isLineTerminator,\n\t        isIdentifierStartES5: isIdentifierStartES5,\n\t        isIdentifierPartES5: isIdentifierPartES5,\n\t        isIdentifierStartES6: isIdentifierStartES6,\n\t        isIdentifierPartES6: isIdentifierPartES6\n\t    };\n\t}());\n\t/* vim: set sw=4 ts=4 et tw=80 : */\n\n\n/***/ },\n/* 18 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/*\n\t  Copyright (C) 2013 Yusuke Suzuki <utatane.tea@gmail.com>\n\n\t  Redistribution and use in source and binary forms, with or without\n\t  modification, are permitted provided that the following conditions are met:\n\n\t    * Redistributions of source code must retain the above copyright\n\t      notice, this list of conditions and the following disclaimer.\n\t    * Redistributions in binary form must reproduce the above copyright\n\t      notice, this list of conditions and the following disclaimer in the\n\t      documentation and/or other materials provided with the distribution.\n\n\t  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n\t  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\t  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n\t  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\n\t  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n\t  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n\t  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n\t  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\t  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n\t  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\t*/\n\n\t(function () {\n\t    'use strict';\n\n\t    var code = __webpack_require__(17);\n\n\t    function isStrictModeReservedWordES6(id) {\n\t        switch (id) {\n\t        case 'implements':\n\t        case 'interface':\n\t        case 'package':\n\t        case 'private':\n\t        case 'protected':\n\t        case 'public':\n\t        case 'static':\n\t        case 'let':\n\t            return true;\n\t        default:\n\t            return false;\n\t        }\n\t    }\n\n\t    function isKeywordES5(id, strict) {\n\t        // yield should not be treated as keyword under non-strict mode.\n\t        if (!strict && id === 'yield') {\n\t            return false;\n\t        }\n\t        return isKeywordES6(id, strict);\n\t    }\n\n\t    function isKeywordES6(id, strict) {\n\t        if (strict && isStrictModeReservedWordES6(id)) {\n\t            return true;\n\t        }\n\n\t        switch (id.length) {\n\t        case 2:\n\t            return (id === 'if') || (id === 'in') || (id === 'do');\n\t        case 3:\n\t            return (id === 'var') || (id === 'for') || (id === 'new') || (id === 'try');\n\t        case 4:\n\t            return (id === 'this') || (id === 'else') || (id === 'case') ||\n\t                (id === 'void') || (id === 'with') || (id === 'enum');\n\t        case 5:\n\t            return (id === 'while') || (id === 'break') || (id === 'catch') ||\n\t                (id === 'throw') || (id === 'const') || (id === 'yield') ||\n\t                (id === 'class') || (id === 'super');\n\t        case 6:\n\t            return (id === 'return') || (id === 'typeof') || (id === 'delete') ||\n\t                (id === 'switch') || (id === 'export') || (id === 'import');\n\t        case 7:\n\t            return (id === 'default') || (id === 'finally') || (id === 'extends');\n\t        case 8:\n\t            return (id === 'function') || (id === 'continue') || (id === 'debugger');\n\t        case 10:\n\t            return (id === 'instanceof');\n\t        default:\n\t            return false;\n\t        }\n\t    }\n\n\t    function isReservedWordES5(id, strict) {\n\t        return id === 'null' || id === 'true' || id === 'false' || isKeywordES5(id, strict);\n\t    }\n\n\t    function isReservedWordES6(id, strict) {\n\t        return id === 'null' || id === 'true' || id === 'false' || isKeywordES6(id, strict);\n\t    }\n\n\t    function isRestrictedWord(id) {\n\t        return id === 'eval' || id === 'arguments';\n\t    }\n\n\t    function isIdentifierNameES5(id) {\n\t        var i, iz, ch;\n\n\t        if (id.length === 0) { return false; }\n\n\t        ch = id.charCodeAt(0);\n\t        if (!code.isIdentifierStartES5(ch)) {\n\t            return false;\n\t        }\n\n\t        for (i = 1, iz = id.length; i < iz; ++i) {\n\t            ch = id.charCodeAt(i);\n\t            if (!code.isIdentifierPartES5(ch)) {\n\t                return false;\n\t            }\n\t        }\n\t        return true;\n\t    }\n\n\t    function decodeUtf16(lead, trail) {\n\t        return (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;\n\t    }\n\n\t    function isIdentifierNameES6(id) {\n\t        var i, iz, ch, lowCh, check;\n\n\t        if (id.length === 0) { return false; }\n\n\t        check = code.isIdentifierStartES6;\n\t        for (i = 0, iz = id.length; i < iz; ++i) {\n\t            ch = id.charCodeAt(i);\n\t            if (0xD800 <= ch && ch <= 0xDBFF) {\n\t                ++i;\n\t                if (i >= iz) { return false; }\n\t                lowCh = id.charCodeAt(i);\n\t                if (!(0xDC00 <= lowCh && lowCh <= 0xDFFF)) {\n\t                    return false;\n\t                }\n\t                ch = decodeUtf16(ch, lowCh);\n\t            }\n\t            if (!check(ch)) {\n\t                return false;\n\t            }\n\t            check = code.isIdentifierPartES6;\n\t        }\n\t        return true;\n\t    }\n\n\t    function isIdentifierES5(id, strict) {\n\t        return isIdentifierNameES5(id) && !isReservedWordES5(id, strict);\n\t    }\n\n\t    function isIdentifierES6(id, strict) {\n\t        return isIdentifierNameES6(id) && !isReservedWordES6(id, strict);\n\t    }\n\n\t    module.exports = {\n\t        isKeywordES5: isKeywordES5,\n\t        isKeywordES6: isKeywordES6,\n\t        isReservedWordES5: isReservedWordES5,\n\t        isReservedWordES6: isReservedWordES6,\n\t        isRestrictedWord: isRestrictedWord,\n\t        isIdentifierNameES5: isIdentifierNameES5,\n\t        isIdentifierNameES6: isIdentifierNameES6,\n\t        isIdentifierES5: isIdentifierES5,\n\t        isIdentifierES6: isIdentifierES6\n\t    };\n\t}());\n\t/* vim: set sw=4 ts=4 et tw=80 : */\n\n\n/***/ },\n/* 19 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.isString = isString;\n\texports.isIdentifier = isIdentifier;\n\texports.isKeyword = isKeyword;\n\texports.isPunctuator = isPunctuator;\n\texports.isNumeric = isNumeric;\n\texports.isTemplateElement = isTemplateElement;\n\texports.isTemplate = isTemplate;\n\texports.isRegExp = isRegExp;\n\texports.getKind = getKind;\n\texports.getLineNumber = getLineNumber;\n\tconst TokenClass = exports.TokenClass = {\n\t  Eof: { name: '<End>' },\n\t  Ident: { name: 'Identifier', isIdentifierName: true },\n\t  Keyword: { name: 'Keyword', isIdentifierName: true },\n\t  NumericLiteral: { name: 'Numeric' },\n\t  TemplateElement: { name: 'Template' },\n\t  Punctuator: { name: 'Punctuator' },\n\t  StringLiteral: { name: 'String' },\n\t  RegularExpression: { name: 'RegularExpression' },\n\t  Illegal: { name: 'Illegal' }\n\t};\n\n\tconst TC = TokenClass;\n\n\tconst TokenType = exports.TokenType = {\n\t  EOS: { klass: TC.Eof, name: 'EOS' },\n\t  LPAREN: { klass: TC.Punctuator, name: '(' },\n\t  RPAREN: { klass: TC.Punctuator, name: ')' },\n\t  LBRACK: { klass: TC.Punctuator, name: '[' },\n\t  RBRACK: { klass: TC.Punctuator, name: ']' },\n\t  LBRACE: { klass: TC.Punctuator, name: '{' },\n\t  RBRACE: { klass: TC.Punctuator, name: '}' },\n\t  LSYNTAX: { klass: TC.Punctuator, name: 'left-syntax' },\n\t  RSYNTAX: { klass: TC.Punctuator, name: 'right-syntax' },\n\t  COLON: { klass: TC.Punctuator, name: ':' },\n\t  SEMICOLON: { klass: TC.Punctuator, name: ';' },\n\t  PERIOD: { klass: TC.Punctuator, name: '.' },\n\t  ELLIPSIS: { klass: TC.Punctuator, name: '...' },\n\t  ARROW: { klass: TC.Punctuator, name: '=>' },\n\t  CONDITIONAL: { klass: TC.Punctuator, name: '?' },\n\t  INC: { klass: TC.Punctuator, name: '++' },\n\t  DEC: { klass: TC.Punctuator, name: '--' },\n\t  ASSIGN: { klass: TC.Punctuator, name: '=' },\n\t  ASSIGN_BIT_OR: { klass: TC.Punctuator, name: '|=' },\n\t  ASSIGN_BIT_XOR: { klass: TC.Punctuator, name: '^=' },\n\t  ASSIGN_BIT_AND: { klass: TC.Punctuator, name: '&=' },\n\t  ASSIGN_SHL: { klass: TC.Punctuator, name: '<<=' },\n\t  ASSIGN_SHR: { klass: TC.Punctuator, name: '>>=' },\n\t  ASSIGN_SHR_UNSIGNED: { klass: TC.Punctuator, name: '>>>=' },\n\t  ASSIGN_ADD: { klass: TC.Punctuator, name: '+=' },\n\t  ASSIGN_SUB: { klass: TC.Punctuator, name: '-=' },\n\t  ASSIGN_MUL: { klass: TC.Punctuator, name: '*=' },\n\t  ASSIGN_DIV: { klass: TC.Punctuator, name: '/=' },\n\t  ASSIGN_MOD: { klass: TC.Punctuator, name: '%=' },\n\t  ASSIGN_EXP: { klass: TC.Punctuator, name: '**=' },\n\t  COMMA: { klass: TC.Punctuator, name: ',' },\n\t  OR: { klass: TC.Punctuator, name: '||' },\n\t  AND: { klass: TC.Punctuator, name: '&&' },\n\t  BIT_OR: { klass: TC.Punctuator, name: '|' },\n\t  BIT_XOR: { klass: TC.Punctuator, name: '^' },\n\t  BIT_AND: { klass: TC.Punctuator, name: '&' },\n\t  SHL: { klass: TC.Punctuator, name: '<<' },\n\t  SHR: { klass: TC.Punctuator, name: '>>' },\n\t  SHR_UNSIGNED: { klass: TC.Punctuator, name: '>>>' },\n\t  ADD: { klass: TC.Punctuator, name: '+' },\n\t  SUB: { klass: TC.Punctuator, name: '-' },\n\t  MUL: { klass: TC.Punctuator, name: '*' },\n\t  DIV: { klass: TC.Punctuator, name: '/' },\n\t  MOD: { klass: TC.Punctuator, name: '%' },\n\t  EXP: { klass: TC.Punctuator, name: '**' },\n\t  EQ: { klass: TC.Punctuator, name: '==' },\n\t  NE: { klass: TC.Punctuator, name: '!=' },\n\t  EQ_STRICT: { klass: TC.Punctuator, name: '===' },\n\t  NE_STRICT: { klass: TC.Punctuator, name: '!==' },\n\t  LT: { klass: TC.Punctuator, name: '<' },\n\t  GT: { klass: TC.Punctuator, name: '>' },\n\t  LTE: { klass: TC.Punctuator, name: '<=' },\n\t  GTE: { klass: TC.Punctuator, name: '>=' },\n\t  INSTANCEOF: { klass: TC.Keyword, name: 'instanceof' },\n\t  IN: { klass: TC.Keyword, name: 'in' },\n\t  NOT: { klass: TC.Punctuator, name: '!' },\n\t  BIT_NOT: { klass: TC.Punctuator, name: '~' },\n\t  AWAIT: { klass: TC.Keyword, name: 'await' },\n\t  DELETE: { klass: TC.Keyword, name: 'delete' },\n\t  TYPEOF: { klass: TC.Keyword, name: 'typeof' },\n\t  VOID: { klass: TC.Keyword, name: 'void' },\n\t  BREAK: { klass: TC.Keyword, name: 'break' },\n\t  CASE: { klass: TC.Keyword, name: 'case' },\n\t  CATCH: { klass: TC.Keyword, name: 'catch' },\n\t  CLASS: { klass: TC.Keyword, name: 'class' },\n\t  CONTINUE: { klass: TC.Keyword, name: 'continue' },\n\t  DEBUGGER: { klass: TC.Keyword, name: 'debugger' },\n\t  DEFAULT: { klass: TC.Keyword, name: 'default' },\n\t  DO: { klass: TC.Keyword, name: 'do' },\n\t  ELSE: { klass: TC.Keyword, name: 'else' },\n\t  EXPORT: { klass: TC.Keyword, name: 'export' },\n\t  EXTENDS: { klass: TC.Keyword, name: 'extends' },\n\t  FINALLY: { klass: TC.Keyword, name: 'finally' },\n\t  FOR: { klass: TC.Keyword, name: 'for' },\n\t  FUNCTION: { klass: TC.Keyword, name: 'function' },\n\t  IF: { klass: TC.Keyword, name: 'if' },\n\t  IMPORT: { klass: TC.Keyword, name: 'import' },\n\t  LET: { klass: TC.Keyword, name: 'let' },\n\t  NEW: { klass: TC.Keyword, name: 'new' },\n\t  RETURN: { klass: TC.Keyword, name: 'return' },\n\t  SUPER: { klass: TC.Keyword, name: 'super' },\n\t  SWITCH: { klass: TC.Keyword, name: 'switch' },\n\t  THIS: { klass: TC.Keyword, name: 'this' },\n\t  THROW: { klass: TC.Keyword, name: 'throw' },\n\t  TRY: { klass: TC.Keyword, name: 'try' },\n\t  VAR: { klass: TC.Keyword, name: 'var' },\n\t  WHILE: { klass: TC.Keyword, name: 'while' },\n\t  WITH: { klass: TC.Keyword, name: 'with' },\n\t  NULL: { klass: TC.Keyword, name: 'null' },\n\t  TRUE: { klass: TC.Keyword, name: 'true' },\n\t  FALSE: { klass: TC.Keyword, name: 'false' },\n\t  YIELD: { klass: TC.Keyword, name: 'yield' },\n\t  NUMBER: { klass: TC.NumericLiteral, name: '' },\n\t  STRING: { klass: TC.StringLiteral, name: '' },\n\t  REGEXP: { klass: TC.RegularExpression, name: '' },\n\t  IDENTIFIER: { klass: TC.Ident, name: '' },\n\t  CONST: { klass: TC.Keyword, name: 'const' },\n\t  TEMPLATE: { klass: TC.TemplateElement, name: '' },\n\t  ILLEGAL: { klass: TC.Illegal, name: '' }\n\t};\n\n\tconst TT = TokenType;\n\n\tconst punctuatorTable = exports.punctuatorTable = {\n\t  '(': TT.LPAREN,\n\t  ')': TT.RPAREN,\n\t  '[': TT.LBRACK,\n\t  ']': TT.RBRACK,\n\t  '{': TT.LBRACE,\n\t  '}': TT.RBRACE,\n\t  ':': TT.COLON,\n\t  ';': TT.SEMICOLON,\n\t  '.': TT.PERIOD,\n\t  '...': TT.ELLIPSIS,\n\t  '=>': TT.ARROW,\n\t  '?': TT.CONDITIONAL,\n\t  '++': TT.INC,\n\t  '--': TT.DEC,\n\t  '=': TT.ASSIGN,\n\t  '|=': TT.ASSIGN_BIT_OR,\n\t  '^=': TT.ASSIGN_BIT_XOR,\n\t  '&=': TT.ASSIGN_BIT_AND,\n\t  '<<=': TT.ASSIGN_SHL,\n\t  '>>=': TT.ASSIGN_SHR,\n\t  '>>>=': TT.ASSIGN_SHR_UNSIGNED,\n\t  '+=': TT.ASSIGN_ADD,\n\t  '-=': TT.ASSIGN_SUB,\n\t  '*=': TT.ASSIGN_MUL,\n\t  '/=': TT.ASSIGN_DIV,\n\t  '%=': TT.ASSIGN_MOD,\n\t  '**=': TT.ASSIGN_EXP,\n\t  ',': TT.COMMA,\n\t  '||': TT.OR,\n\t  '&&': TT.AND,\n\t  '|': TT.BIT_OR,\n\t  '&': TT.BIT_AND,\n\t  '^': TT.BIT_XOR,\n\t  '<<': TT.SHL,\n\t  '>>': TT.SHR,\n\t  '>>>': TT.SHR_UNSIGNED,\n\t  '+': TT.ADD,\n\t  '-': TT.SUB,\n\t  '*': TT.MUL,\n\t  '/': TT.DIV,\n\t  '%': TT.MOD,\n\t  '**': TT.EXP,\n\t  '==': TT.EQ,\n\t  '!=': TT.NE,\n\t  '===': TT.EQ_STRICT,\n\t  '!==': TT.NE_STRICT,\n\t  '<': TT.LT,\n\t  '>': TT.GT,\n\t  '<=': TT.LTE,\n\t  '>=': TT.GTE,\n\t  '!': TT.NOT,\n\t  '~': TT.BIT_NOT\n\t};\n\n\tconst keywordTable = exports.keywordTable = {\n\t  // 'await': TT.AWAIT, TODO: uncomment when new version of shift is used\n\t  // TODO: add 'async'\n\t  break: TT.BREAK,\n\t  case: TT.CASE,\n\t  catch: TT.CATCH,\n\t  class: TT.CLASS,\n\t  const: TT.CONST,\n\t  continue: TT.CONTINUE,\n\t  delete: TT.DELETE,\n\t  debugger: TT.DEBUGGER,\n\t  default: TT.DEFAULT,\n\t  do: TT.DO,\n\t  else: TT.ELSE,\n\t  export: TT.EXPORT,\n\t  extends: TT.EXTENDS,\n\t  false: TT.FALSE,\n\t  finally: TT.FINALLY,\n\t  for: TT.FOR,\n\t  function: TT.FUNCTION,\n\t  if: TT.IF,\n\t  import: TT.IMPORT,\n\t  in: TT.IN,\n\t  instanceof: TT.INSTANCEOF,\n\t  let: TT.LET,\n\t  new: TT.NEW,\n\t  null: TT.NULL,\n\t  return: TT.RETURN,\n\t  super: TT.SUPER,\n\t  switch: TT.SWITCH,\n\t  this: TT.THIS,\n\t  throw: TT.THROW,\n\t  true: TT.TRUE,\n\t  try: TT.TRY,\n\t  typeof: TT.TYPEOF,\n\t  var: TT.VAR,\n\t  void: TT.VOID,\n\t  while: TT.WHILE,\n\t  with: TT.WITH,\n\t  yield: TT.YIELD\n\t};\n\n\tconst EmptyToken = exports.EmptyToken = {};\n\n\tfunction hasType(x, type) {\n\t  if (type) {\n\t    return x && typeof x.type === 'object' && x.type === type;\n\t  }\n\t  return x && typeof x.type === 'object';\n\t}\n\n\tfunction hasKlass(x, klass) {\n\t  if (klass) {\n\t    return hasType(x) && x.type.klass === klass;\n\t  }\n\t  return hasType(x) && typeof x.type.klass === 'object';\n\t}\n\n\tclass BaseToken {\n\n\t  constructor({\n\t    typeCode,\n\t    type,\n\t    value,\n\t    slice\n\t  }) {\n\t    this.typeCode = typeCode;\n\t    this.type = type;\n\t    this.value = value;\n\t    this.slice = slice;\n\t  }\n\t}\n\n\tfunction isString(x, value) {\n\t  let r = hasType(x, TT.STRING);\n\t  if (value != null) {\n\t    return r && x.str === value;\n\t  }\n\t  return r;\n\t}\n\n\tclass StringToken {\n\t  constructor({ str, octal, slice }) {\n\t    this.type = TT.STRING;\n\t    this.typeCode = TypeCodes.StringLiteral;\n\t    this.str = str;\n\t    this.octal = octal;\n\t    this.slice = slice;\n\t  }\n\t}\n\n\texports.StringToken = StringToken;\n\tconst TypeCodes = exports.TypeCodes = {\n\t  Identifier: 0,\n\t  Keyword: 1,\n\t  Punctuator: 2,\n\t  NumericLiteral: 3,\n\t  StringLiteral: 4,\n\t  TemplateElement: 5,\n\t  Template: 6,\n\t  RegExp: 7\n\t};\n\n\tfunction isIdentifier(x, value) {\n\t  let r = hasType(x, TT.IDENTIFIER);\n\t  if (value != null) {\n\t    return r && x.value === value;\n\t  }\n\t  return r;\n\t}\n\n\tclass IdentifierToken extends BaseToken {\n\t  constructor({ value, slice }) {\n\t    super({\n\t      typeCode: TypeCodes.Identifier,\n\t      type: TT.IDENTIFIER,\n\t      value,\n\t      slice\n\t    });\n\t  }\n\t}\n\n\texports.IdentifierToken = IdentifierToken;\n\tfunction isKeyword(x, value) {\n\t  let r = hasKlass(x, TC.Keyword);\n\t  if (value != null) {\n\t    if (typeof value === 'string') {\n\t      return r && x.value === value;\n\t    } else if (typeof value.some === 'function') {\n\t      return value.some(v => v === x.value);\n\t    }\n\t  }\n\t  return r;\n\t}\n\n\tclass KeywordToken extends BaseToken {\n\t  constructor({ value, slice }) {\n\t    super({\n\t      typeCode: TypeCodes.Keyword,\n\t      type: keywordTable[value],\n\t      value,\n\t      slice\n\t    });\n\t  }\n\t}\n\n\texports.KeywordToken = KeywordToken;\n\tfunction isPunctuator(x, value) {\n\t  let r = hasKlass(x, TC.Punctuator);\n\t  if (value != null) {\n\t    return r && x.value === value;\n\t  }\n\t  return r;\n\t}\n\tclass PunctuatorToken extends BaseToken {\n\t  constructor({ value, slice }) {\n\t    super({\n\t      typeCode: TypeCodes.Punctuator,\n\t      type: punctuatorTable[value],\n\t      value,\n\t      slice\n\t    });\n\t  }\n\t}\n\n\texports.PunctuatorToken = PunctuatorToken;\n\tfunction isNumeric(x, value) {\n\t  let r = hasType(x, TT.NUMBER);\n\t  if (value != null) {\n\t    return r && x.value === value;\n\t  }\n\t  return r;\n\t}\n\tclass NumericToken extends BaseToken {\n\n\t  constructor({\n\t    value,\n\t    octal = false,\n\t    noctal = false,\n\t    slice\n\t  }) {\n\t    super({\n\t      typeCode: TypeCodes.NumericLiteral,\n\t      type: TT.NUMBER,\n\t      value,\n\t      slice\n\t    });\n\t    this.octal = octal;\n\t    this.noctal = noctal;\n\t  }\n\t}\n\n\texports.NumericToken = NumericToken;\n\tfunction isTemplateElement(x, value) {\n\t  let r = hasType(x, TT.TEMPLATE) && x.items == null;\n\t  if (value != null) {\n\t    return r && x.value === value;\n\t  }\n\t  return r;\n\t}\n\n\tclass TemplateElementToken extends BaseToken {\n\n\t  constructor({\n\t    value,\n\t    tail,\n\t    interp,\n\t    slice\n\t  }) {\n\t    super({\n\t      type: TT.TEMPLATE,\n\t      typeCode: TypeCodes.TemplateElement,\n\t      value,\n\t      slice\n\t    });\n\t    this.tail = tail;\n\t    this.interp = interp;\n\t  }\n\t}\n\n\texports.TemplateElementToken = TemplateElementToken;\n\tfunction isTemplate(x) {\n\t  return hasType(x, TT.TEMPLATE) && x.items != null;\n\t}\n\tclass TemplateToken extends BaseToken {\n\n\t  constructor({ items, slice }) {\n\t    super({ type: TT.TEMPLATE, typeCode: TypeCodes.Template, slice });\n\t    this.items = items;\n\t  }\n\t}\n\n\texports.TemplateToken = TemplateToken;\n\tfunction isRegExp(x, value) {\n\t  let r = hasType(x, TT.REGEXP);\n\t  if (value != null) {\n\t    return r && x.value === value;\n\t  }\n\t  return r;\n\t}\n\tclass RegExpToken extends BaseToken {\n\t  constructor({ value, slice }) {\n\t    super({ type: TT.REGEXP, typeCode: TypeCodes.RegExp, value, slice });\n\t  }\n\t}\n\n\texports.RegExpToken = RegExpToken;\n\tconst isDelimiterType = (x, type) => {\n\t  if (x && x[Symbol.iterator] && ([x] = x)) {\n\t    return x && hasType(x, type);\n\t  }\n\t  return false;\n\t};\n\n\tconst isParens = exports.isParens = x => isDelimiterType(x, TT.LPAREN);\n\tconst isBraces = exports.isBraces = x => isDelimiterType(x, TT.LBRACE);\n\tconst isBrackets = exports.isBrackets = x => isDelimiterType(x, TT.LBRACK);\n\tconst isSyntaxTemplate = exports.isSyntaxTemplate = x => isDelimiterType(x, TT.LSYNTAX);\n\n\tconst isDelimiter = exports.isDelimiter = x => isParens(x) || isBraces(x) || isBrackets(x) || isSyntaxTemplate(x);\n\n\tfunction getKind(x) {\n\t  return isParens(x) ? 'parens' : isBraces(x) ? 'braces' : isBrackets(x) ? 'brackets' : isSyntaxTemplate(x) ? 'syntaxTemplate' : '';\n\t}\n\n\tfunction getLineNumber(t) {\n\t  if (t.slice && t.slice.startLocation) {\n\t    return t.slice.startLocation.line;\n\t  } else if (t[Symbol.iterator] && ([t] = t)) {\n\t    return getLineNumber(t);\n\t  }\n\t  return null;\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90b2tlbnMuanMiXSwibmFtZXMiOlsiaXNTdHJpbmciLCJpc0lkZW50aWZpZXIiLCJpc0tleXdvcmQiLCJpc1B1bmN0dWF0b3IiLCJpc051bWVyaWMiLCJpc1RlbXBsYXRlRWxlbWVudCIsImlzVGVtcGxhdGUiLCJpc1JlZ0V4cCIsImdldEtpbmQiLCJnZXRMaW5lTnVtYmVyIiwiVG9rZW5DbGFzcyIsIkVvZiIsIm5hbWUiLCJJZGVudCIsImlzSWRlbnRpZmllck5hbWUiLCJLZXl3b3JkIiwiTnVtZXJpY0xpdGVyYWwiLCJUZW1wbGF0ZUVsZW1lbnQiLCJQdW5jdHVhdG9yIiwiU3RyaW5nTGl0ZXJhbCIsIlJlZ3VsYXJFeHByZXNzaW9uIiwiSWxsZWdhbCIsIlRDIiwiVG9rZW5UeXBlIiwiRU9TIiwia2xhc3MiLCJMUEFSRU4iLCJSUEFSRU4iLCJMQlJBQ0siLCJSQlJBQ0siLCJMQlJBQ0UiLCJSQlJBQ0UiLCJMU1lOVEFYIiwiUlNZTlRBWCIsIkNPTE9OIiwiU0VNSUNPTE9OIiwiUEVSSU9EIiwiRUxMSVBTSVMiLCJBUlJPVyIsIkNPTkRJVElPTkFMIiwiSU5DIiwiREVDIiwiQVNTSUdOIiwiQVNTSUdOX0JJVF9PUiIsIkFTU0lHTl9CSVRfWE9SIiwiQVNTSUdOX0JJVF9BTkQiLCJBU1NJR05fU0hMIiwiQVNTSUdOX1NIUiIsIkFTU0lHTl9TSFJfVU5TSUdORUQiLCJBU1NJR05fQUREIiwiQVNTSUdOX1NVQiIsIkFTU0lHTl9NVUwiLCJBU1NJR05fRElWIiwiQVNTSUdOX01PRCIsIkFTU0lHTl9FWFAiLCJDT01NQSIsIk9SIiwiQU5EIiwiQklUX09SIiwiQklUX1hPUiIsIkJJVF9BTkQiLCJTSEwiLCJTSFIiLCJTSFJfVU5TSUdORUQiLCJBREQiLCJTVUIiLCJNVUwiLCJESVYiLCJNT0QiLCJFWFAiLCJFUSIsIk5FIiwiRVFfU1RSSUNUIiwiTkVfU1RSSUNUIiwiTFQiLCJHVCIsIkxURSIsIkdURSIsIklOU1RBTkNFT0YiLCJJTiIsIk5PVCIsIkJJVF9OT1QiLCJBV0FJVCIsIkRFTEVURSIsIlRZUEVPRiIsIlZPSUQiLCJCUkVBSyIsIkNBU0UiLCJDQVRDSCIsIkNMQVNTIiwiQ09OVElOVUUiLCJERUJVR0dFUiIsIkRFRkFVTFQiLCJETyIsIkVMU0UiLCJFWFBPUlQiLCJFWFRFTkRTIiwiRklOQUxMWSIsIkZPUiIsIkZVTkNUSU9OIiwiSUYiLCJJTVBPUlQiLCJMRVQiLCJORVciLCJSRVRVUk4iLCJTVVBFUiIsIlNXSVRDSCIsIlRISVMiLCJUSFJPVyIsIlRSWSIsIlZBUiIsIldISUxFIiwiV0lUSCIsIk5VTEwiLCJUUlVFIiwiRkFMU0UiLCJZSUVMRCIsIk5VTUJFUiIsIlNUUklORyIsIlJFR0VYUCIsIklERU5USUZJRVIiLCJDT05TVCIsIlRFTVBMQVRFIiwiSUxMRUdBTCIsIlRUIiwicHVuY3R1YXRvclRhYmxlIiwia2V5d29yZFRhYmxlIiwiYnJlYWsiLCJjYXNlIiwiY2F0Y2giLCJjbGFzcyIsImNvbnN0IiwiY29udGludWUiLCJkZWxldGUiLCJkZWJ1Z2dlciIsImRlZmF1bHQiLCJkbyIsImVsc2UiLCJleHBvcnQiLCJleHRlbmRzIiwiZmFsc2UiLCJmaW5hbGx5IiwiZm9yIiwiZnVuY3Rpb24iLCJpZiIsImltcG9ydCIsImluIiwiaW5zdGFuY2VvZiIsImxldCIsIm5ldyIsIm51bGwiLCJyZXR1cm4iLCJzdXBlciIsInN3aXRjaCIsInRoaXMiLCJ0aHJvdyIsInRydWUiLCJ0cnkiLCJ0eXBlb2YiLCJ2YXIiLCJ2b2lkIiwid2hpbGUiLCJ3aXRoIiwieWllbGQiLCJFbXB0eVRva2VuIiwiaGFzVHlwZSIsIngiLCJ0eXBlIiwiaGFzS2xhc3MiLCJCYXNlVG9rZW4iLCJjb25zdHJ1Y3RvciIsInR5cGVDb2RlIiwidmFsdWUiLCJzbGljZSIsInIiLCJzdHIiLCJTdHJpbmdUb2tlbiIsIm9jdGFsIiwiVHlwZUNvZGVzIiwiSWRlbnRpZmllciIsIlRlbXBsYXRlIiwiUmVnRXhwIiwiSWRlbnRpZmllclRva2VuIiwic29tZSIsInYiLCJLZXl3b3JkVG9rZW4iLCJQdW5jdHVhdG9yVG9rZW4iLCJOdW1lcmljVG9rZW4iLCJub2N0YWwiLCJpdGVtcyIsIlRlbXBsYXRlRWxlbWVudFRva2VuIiwidGFpbCIsImludGVycCIsIlRlbXBsYXRlVG9rZW4iLCJSZWdFeHBUb2tlbiIsImlzRGVsaW1pdGVyVHlwZSIsIlN5bWJvbCIsIml0ZXJhdG9yIiwiaXNQYXJlbnMiLCJpc0JyYWNlcyIsImlzQnJhY2tldHMiLCJpc1N5bnRheFRlbXBsYXRlIiwiaXNEZWxpbWl0ZXIiLCJ0Iiwic3RhcnRMb2NhdGlvbiIsImxpbmUiXSwibWFwcGluZ3MiOiI7Ozs7O1FBK1JnQkEsUSxHQUFBQSxRO1FBb0NBQyxZLEdBQUFBLFk7UUFtQkFDLFMsR0FBQUEsUztRQXVCQUMsWSxHQUFBQSxZO1FBa0JBQyxTLEdBQUFBLFM7UUE4QkFDLGlCLEdBQUFBLGlCO1FBK0JBQyxVLEdBQUFBLFU7UUFZQUMsUSxHQUFBQSxRO1FBNEJBQyxPLEdBQUFBLE87UUFVQUMsYSxHQUFBQSxhO0FBbmVULE1BQU1DLGtDQUFhO0FBQ3hCQyxPQUFLLEVBQUVDLE1BQU0sT0FBUixFQURtQjtBQUV4QkMsU0FBTyxFQUFFRCxNQUFNLFlBQVIsRUFBc0JFLGtCQUFrQixJQUF4QyxFQUZpQjtBQUd4QkMsV0FBUyxFQUFFSCxNQUFNLFNBQVIsRUFBbUJFLGtCQUFrQixJQUFyQyxFQUhlO0FBSXhCRSxrQkFBZ0IsRUFBRUosTUFBTSxTQUFSLEVBSlE7QUFLeEJLLG1CQUFpQixFQUFFTCxNQUFNLFVBQVIsRUFMTztBQU14Qk0sY0FBWSxFQUFFTixNQUFNLFlBQVIsRUFOWTtBQU94Qk8saUJBQWUsRUFBRVAsTUFBTSxRQUFSLEVBUFM7QUFReEJRLHFCQUFtQixFQUFFUixNQUFNLG1CQUFSLEVBUks7QUFTeEJTLFdBQVMsRUFBRVQsTUFBTSxTQUFSO0FBVGUsQ0FBbkI7O0FBWVAsTUFBTVUsS0FBS1osVUFBWDs7QUFFTyxNQUFNYSxnQ0FBWTtBQUN2QkMsT0FBSyxFQUFFQyxPQUFPSCxHQUFHWCxHQUFaLEVBQWlCQyxNQUFNLEtBQXZCLEVBRGtCO0FBRXZCYyxVQUFRLEVBQUVELE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sR0FBOUIsRUFGZTtBQUd2QmUsVUFBUSxFQUFFRixPQUFPSCxHQUFHSixVQUFaLEVBQXdCTixNQUFNLEdBQTlCLEVBSGU7QUFJdkJnQixVQUFRLEVBQUVILE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sR0FBOUIsRUFKZTtBQUt2QmlCLFVBQVEsRUFBRUosT0FBT0gsR0FBR0osVUFBWixFQUF3Qk4sTUFBTSxHQUE5QixFQUxlO0FBTXZCa0IsVUFBUSxFQUFFTCxPQUFPSCxHQUFHSixVQUFaLEVBQXdCTixNQUFNLEdBQTlCLEVBTmU7QUFPdkJtQixVQUFRLEVBQUVOLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sR0FBOUIsRUFQZTtBQVF2Qm9CLFdBQVMsRUFBRVAsT0FBT0gsR0FBR0osVUFBWixFQUF3Qk4sTUFBTSxhQUE5QixFQVJjO0FBU3ZCcUIsV0FBUyxFQUFFUixPQUFPSCxHQUFHSixVQUFaLEVBQXdCTixNQUFNLGNBQTlCLEVBVGM7QUFVdkJzQixTQUFPLEVBQUVULE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sR0FBOUIsRUFWZ0I7QUFXdkJ1QixhQUFXLEVBQUVWLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sR0FBOUIsRUFYWTtBQVl2QndCLFVBQVEsRUFBRVgsT0FBT0gsR0FBR0osVUFBWixFQUF3Qk4sTUFBTSxHQUE5QixFQVplO0FBYXZCeUIsWUFBVSxFQUFFWixPQUFPSCxHQUFHSixVQUFaLEVBQXdCTixNQUFNLEtBQTlCLEVBYmE7QUFjdkIwQixTQUFPLEVBQUViLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sSUFBOUIsRUFkZ0I7QUFldkIyQixlQUFhLEVBQUVkLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sR0FBOUIsRUFmVTtBQWdCdkI0QixPQUFLLEVBQUVmLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sSUFBOUIsRUFoQmtCO0FBaUJ2QjZCLE9BQUssRUFBRWhCLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sSUFBOUIsRUFqQmtCO0FBa0J2QjhCLFVBQVEsRUFBRWpCLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sR0FBOUIsRUFsQmU7QUFtQnZCK0IsaUJBQWUsRUFBRWxCLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sSUFBOUIsRUFuQlE7QUFvQnZCZ0Msa0JBQWdCLEVBQUVuQixPQUFPSCxHQUFHSixVQUFaLEVBQXdCTixNQUFNLElBQTlCLEVBcEJPO0FBcUJ2QmlDLGtCQUFnQixFQUFFcEIsT0FBT0gsR0FBR0osVUFBWixFQUF3Qk4sTUFBTSxJQUE5QixFQXJCTztBQXNCdkJrQyxjQUFZLEVBQUVyQixPQUFPSCxHQUFHSixVQUFaLEVBQXdCTixNQUFNLEtBQTlCLEVBdEJXO0FBdUJ2Qm1DLGNBQVksRUFBRXRCLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sS0FBOUIsRUF2Qlc7QUF3QnZCb0MsdUJBQXFCLEVBQUV2QixPQUFPSCxHQUFHSixVQUFaLEVBQXdCTixNQUFNLE1BQTlCLEVBeEJFO0FBeUJ2QnFDLGNBQVksRUFBRXhCLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sSUFBOUIsRUF6Qlc7QUEwQnZCc0MsY0FBWSxFQUFFekIsT0FBT0gsR0FBR0osVUFBWixFQUF3Qk4sTUFBTSxJQUE5QixFQTFCVztBQTJCdkJ1QyxjQUFZLEVBQUUxQixPQUFPSCxHQUFHSixVQUFaLEVBQXdCTixNQUFNLElBQTlCLEVBM0JXO0FBNEJ2QndDLGNBQVksRUFBRTNCLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sSUFBOUIsRUE1Qlc7QUE2QnZCeUMsY0FBWSxFQUFFNUIsT0FBT0gsR0FBR0osVUFBWixFQUF3Qk4sTUFBTSxJQUE5QixFQTdCVztBQThCdkIwQyxjQUFZLEVBQUU3QixPQUFPSCxHQUFHSixVQUFaLEVBQXdCTixNQUFNLEtBQTlCLEVBOUJXO0FBK0J2QjJDLFNBQU8sRUFBRTlCLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sR0FBOUIsRUEvQmdCO0FBZ0N2QjRDLE1BQUksRUFBRS9CLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sSUFBOUIsRUFoQ21CO0FBaUN2QjZDLE9BQUssRUFBRWhDLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sSUFBOUIsRUFqQ2tCO0FBa0N2QjhDLFVBQVEsRUFBRWpDLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sR0FBOUIsRUFsQ2U7QUFtQ3ZCK0MsV0FBUyxFQUFFbEMsT0FBT0gsR0FBR0osVUFBWixFQUF3Qk4sTUFBTSxHQUE5QixFQW5DYztBQW9DdkJnRCxXQUFTLEVBQUVuQyxPQUFPSCxHQUFHSixVQUFaLEVBQXdCTixNQUFNLEdBQTlCLEVBcENjO0FBcUN2QmlELE9BQUssRUFBRXBDLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sSUFBOUIsRUFyQ2tCO0FBc0N2QmtELE9BQUssRUFBRXJDLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sSUFBOUIsRUF0Q2tCO0FBdUN2Qm1ELGdCQUFjLEVBQUV0QyxPQUFPSCxHQUFHSixVQUFaLEVBQXdCTixNQUFNLEtBQTlCLEVBdkNTO0FBd0N2Qm9ELE9BQUssRUFBRXZDLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sR0FBOUIsRUF4Q2tCO0FBeUN2QnFELE9BQUssRUFBRXhDLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sR0FBOUIsRUF6Q2tCO0FBMEN2QnNELE9BQUssRUFBRXpDLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sR0FBOUIsRUExQ2tCO0FBMkN2QnVELE9BQUssRUFBRTFDLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sR0FBOUIsRUEzQ2tCO0FBNEN2QndELE9BQUssRUFBRTNDLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sR0FBOUIsRUE1Q2tCO0FBNkN2QnlELE9BQUssRUFBRTVDLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sSUFBOUIsRUE3Q2tCO0FBOEN2QjBELE1BQUksRUFBRTdDLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sSUFBOUIsRUE5Q21CO0FBK0N2QjJELE1BQUksRUFBRTlDLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sSUFBOUIsRUEvQ21CO0FBZ0R2QjRELGFBQVcsRUFBRS9DLE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sS0FBOUIsRUFoRFk7QUFpRHZCNkQsYUFBVyxFQUFFaEQsT0FBT0gsR0FBR0osVUFBWixFQUF3Qk4sTUFBTSxLQUE5QixFQWpEWTtBQWtEdkI4RCxNQUFJLEVBQUVqRCxPQUFPSCxHQUFHSixVQUFaLEVBQXdCTixNQUFNLEdBQTlCLEVBbERtQjtBQW1EdkIrRCxNQUFJLEVBQUVsRCxPQUFPSCxHQUFHSixVQUFaLEVBQXdCTixNQUFNLEdBQTlCLEVBbkRtQjtBQW9EdkJnRSxPQUFLLEVBQUVuRCxPQUFPSCxHQUFHSixVQUFaLEVBQXdCTixNQUFNLElBQTlCLEVBcERrQjtBQXFEdkJpRSxPQUFLLEVBQUVwRCxPQUFPSCxHQUFHSixVQUFaLEVBQXdCTixNQUFNLElBQTlCLEVBckRrQjtBQXNEdkJrRSxjQUFZLEVBQUVyRCxPQUFPSCxHQUFHUCxPQUFaLEVBQXFCSCxNQUFNLFlBQTNCLEVBdERXO0FBdUR2Qm1FLE1BQUksRUFBRXRELE9BQU9ILEdBQUdQLE9BQVosRUFBcUJILE1BQU0sSUFBM0IsRUF2RG1CO0FBd0R2Qm9FLE9BQUssRUFBRXZELE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sR0FBOUIsRUF4RGtCO0FBeUR2QnFFLFdBQVMsRUFBRXhELE9BQU9ILEdBQUdKLFVBQVosRUFBd0JOLE1BQU0sR0FBOUIsRUF6RGM7QUEwRHZCc0UsU0FBTyxFQUFFekQsT0FBT0gsR0FBR1AsT0FBWixFQUFxQkgsTUFBTSxPQUEzQixFQTFEZ0I7QUEyRHZCdUUsVUFBUSxFQUFFMUQsT0FBT0gsR0FBR1AsT0FBWixFQUFxQkgsTUFBTSxRQUEzQixFQTNEZTtBQTREdkJ3RSxVQUFRLEVBQUUzRCxPQUFPSCxHQUFHUCxPQUFaLEVBQXFCSCxNQUFNLFFBQTNCLEVBNURlO0FBNkR2QnlFLFFBQU0sRUFBRTVELE9BQU9ILEdBQUdQLE9BQVosRUFBcUJILE1BQU0sTUFBM0IsRUE3RGlCO0FBOER2QjBFLFNBQU8sRUFBRTdELE9BQU9ILEdBQUdQLE9BQVosRUFBcUJILE1BQU0sT0FBM0IsRUE5RGdCO0FBK0R2QjJFLFFBQU0sRUFBRTlELE9BQU9ILEdBQUdQLE9BQVosRUFBcUJILE1BQU0sTUFBM0IsRUEvRGlCO0FBZ0V2QjRFLFNBQU8sRUFBRS9ELE9BQU9ILEdBQUdQLE9BQVosRUFBcUJILE1BQU0sT0FBM0IsRUFoRWdCO0FBaUV2QjZFLFNBQU8sRUFBRWhFLE9BQU9ILEdBQUdQLE9BQVosRUFBcUJILE1BQU0sT0FBM0IsRUFqRWdCO0FBa0V2QjhFLFlBQVUsRUFBRWpFLE9BQU9ILEdBQUdQLE9BQVosRUFBcUJILE1BQU0sVUFBM0IsRUFsRWE7QUFtRXZCK0UsWUFBVSxFQUFFbEUsT0FBT0gsR0FBR1AsT0FBWixFQUFxQkgsTUFBTSxVQUEzQixFQW5FYTtBQW9FdkJnRixXQUFTLEVBQUVuRSxPQUFPSCxHQUFHUCxPQUFaLEVBQXFCSCxNQUFNLFNBQTNCLEVBcEVjO0FBcUV2QmlGLE1BQUksRUFBRXBFLE9BQU9ILEdBQUdQLE9BQVosRUFBcUJILE1BQU0sSUFBM0IsRUFyRW1CO0FBc0V2QmtGLFFBQU0sRUFBRXJFLE9BQU9ILEdBQUdQLE9BQVosRUFBcUJILE1BQU0sTUFBM0IsRUF0RWlCO0FBdUV2Qm1GLFVBQVEsRUFBRXRFLE9BQU9ILEdBQUdQLE9BQVosRUFBcUJILE1BQU0sUUFBM0IsRUF2RWU7QUF3RXZCb0YsV0FBUyxFQUFFdkUsT0FBT0gsR0FBR1AsT0FBWixFQUFxQkgsTUFBTSxTQUEzQixFQXhFYztBQXlFdkJxRixXQUFTLEVBQUV4RSxPQUFPSCxHQUFHUCxPQUFaLEVBQXFCSCxNQUFNLFNBQTNCLEVBekVjO0FBMEV2QnNGLE9BQUssRUFBRXpFLE9BQU9ILEdBQUdQLE9BQVosRUFBcUJILE1BQU0sS0FBM0IsRUExRWtCO0FBMkV2QnVGLFlBQVUsRUFBRTFFLE9BQU9ILEdBQUdQLE9BQVosRUFBcUJILE1BQU0sVUFBM0IsRUEzRWE7QUE0RXZCd0YsTUFBSSxFQUFFM0UsT0FBT0gsR0FBR1AsT0FBWixFQUFxQkgsTUFBTSxJQUEzQixFQTVFbUI7QUE2RXZCeUYsVUFBUSxFQUFFNUUsT0FBT0gsR0FBR1AsT0FBWixFQUFxQkgsTUFBTSxRQUEzQixFQTdFZTtBQThFdkIwRixPQUFLLEVBQUU3RSxPQUFPSCxHQUFHUCxPQUFaLEVBQXFCSCxNQUFNLEtBQTNCLEVBOUVrQjtBQStFdkIyRixPQUFLLEVBQUU5RSxPQUFPSCxHQUFHUCxPQUFaLEVBQXFCSCxNQUFNLEtBQTNCLEVBL0VrQjtBQWdGdkI0RixVQUFRLEVBQUUvRSxPQUFPSCxHQUFHUCxPQUFaLEVBQXFCSCxNQUFNLFFBQTNCLEVBaEZlO0FBaUZ2QjZGLFNBQU8sRUFBRWhGLE9BQU9ILEdBQUdQLE9BQVosRUFBcUJILE1BQU0sT0FBM0IsRUFqRmdCO0FBa0Z2QjhGLFVBQVEsRUFBRWpGLE9BQU9ILEdBQUdQLE9BQVosRUFBcUJILE1BQU0sUUFBM0IsRUFsRmU7QUFtRnZCK0YsUUFBTSxFQUFFbEYsT0FBT0gsR0FBR1AsT0FBWixFQUFxQkgsTUFBTSxNQUEzQixFQW5GaUI7QUFvRnZCZ0csU0FBTyxFQUFFbkYsT0FBT0gsR0FBR1AsT0FBWixFQUFxQkgsTUFBTSxPQUEzQixFQXBGZ0I7QUFxRnZCaUcsT0FBSyxFQUFFcEYsT0FBT0gsR0FBR1AsT0FBWixFQUFxQkgsTUFBTSxLQUEzQixFQXJGa0I7QUFzRnZCa0csT0FBSyxFQUFFckYsT0FBT0gsR0FBR1AsT0FBWixFQUFxQkgsTUFBTSxLQUEzQixFQXRGa0I7QUF1RnZCbUcsU0FBTyxFQUFFdEYsT0FBT0gsR0FBR1AsT0FBWixFQUFxQkgsTUFBTSxPQUEzQixFQXZGZ0I7QUF3RnZCb0csUUFBTSxFQUFFdkYsT0FBT0gsR0FBR1AsT0FBWixFQUFxQkgsTUFBTSxNQUEzQixFQXhGaUI7QUF5RnZCcUcsUUFBTSxFQUFFeEYsT0FBT0gsR0FBR1AsT0FBWixFQUFxQkgsTUFBTSxNQUEzQixFQXpGaUI7QUEwRnZCc0csUUFBTSxFQUFFekYsT0FBT0gsR0FBR1AsT0FBWixFQUFxQkgsTUFBTSxNQUEzQixFQTFGaUI7QUEyRnZCdUcsU0FBTyxFQUFFMUYsT0FBT0gsR0FBR1AsT0FBWixFQUFxQkgsTUFBTSxPQUEzQixFQTNGZ0I7QUE0RnZCd0csU0FBTyxFQUFFM0YsT0FBT0gsR0FBR1AsT0FBWixFQUFxQkgsTUFBTSxPQUEzQixFQTVGZ0I7QUE2RnZCeUcsVUFBUSxFQUFFNUYsT0FBT0gsR0FBR04sY0FBWixFQUE0QkosTUFBTSxFQUFsQyxFQTdGZTtBQThGdkIwRyxVQUFRLEVBQUU3RixPQUFPSCxHQUFHSCxhQUFaLEVBQTJCUCxNQUFNLEVBQWpDLEVBOUZlO0FBK0Z2QjJHLFVBQVEsRUFBRTlGLE9BQU9ILEdBQUdGLGlCQUFaLEVBQStCUixNQUFNLEVBQXJDLEVBL0ZlO0FBZ0d2QjRHLGNBQVksRUFBRS9GLE9BQU9ILEdBQUdULEtBQVosRUFBbUJELE1BQU0sRUFBekIsRUFoR1c7QUFpR3ZCNkcsU0FBTyxFQUFFaEcsT0FBT0gsR0FBR1AsT0FBWixFQUFxQkgsTUFBTSxPQUEzQixFQWpHZ0I7QUFrR3ZCOEcsWUFBVSxFQUFFakcsT0FBT0gsR0FBR0wsZUFBWixFQUE2QkwsTUFBTSxFQUFuQyxFQWxHYTtBQW1HdkIrRyxXQUFTLEVBQUVsRyxPQUFPSCxHQUFHRCxPQUFaLEVBQXFCVCxNQUFNLEVBQTNCO0FBbkdjLENBQWxCOztBQXNHUCxNQUFNZ0gsS0FBS3JHLFNBQVg7O0FBRU8sTUFBTXNHLDRDQUFrQjtBQUM3QixPQUFLRCxHQUFHbEcsTUFEcUI7QUFFN0IsT0FBS2tHLEdBQUdqRyxNQUZxQjtBQUc3QixPQUFLaUcsR0FBR2hHLE1BSHFCO0FBSTdCLE9BQUtnRyxHQUFHL0YsTUFKcUI7QUFLN0IsT0FBSytGLEdBQUc5RixNQUxxQjtBQU03QixPQUFLOEYsR0FBRzdGLE1BTnFCO0FBTzdCLE9BQUs2RixHQUFHMUYsS0FQcUI7QUFRN0IsT0FBSzBGLEdBQUd6RixTQVJxQjtBQVM3QixPQUFLeUYsR0FBR3hGLE1BVHFCO0FBVTdCLFNBQU93RixHQUFHdkYsUUFWbUI7QUFXN0IsUUFBTXVGLEdBQUd0RixLQVhvQjtBQVk3QixPQUFLc0YsR0FBR3JGLFdBWnFCO0FBYTdCLFFBQU1xRixHQUFHcEYsR0Fib0I7QUFjN0IsUUFBTW9GLEdBQUduRixHQWRvQjtBQWU3QixPQUFLbUYsR0FBR2xGLE1BZnFCO0FBZ0I3QixRQUFNa0YsR0FBR2pGLGFBaEJvQjtBQWlCN0IsUUFBTWlGLEdBQUdoRixjQWpCb0I7QUFrQjdCLFFBQU1nRixHQUFHL0UsY0FsQm9CO0FBbUI3QixTQUFPK0UsR0FBRzlFLFVBbkJtQjtBQW9CN0IsU0FBTzhFLEdBQUc3RSxVQXBCbUI7QUFxQjdCLFVBQVE2RSxHQUFHNUUsbUJBckJrQjtBQXNCN0IsUUFBTTRFLEdBQUczRSxVQXRCb0I7QUF1QjdCLFFBQU0yRSxHQUFHMUUsVUF2Qm9CO0FBd0I3QixRQUFNMEUsR0FBR3pFLFVBeEJvQjtBQXlCN0IsUUFBTXlFLEdBQUd4RSxVQXpCb0I7QUEwQjdCLFFBQU13RSxHQUFHdkUsVUExQm9CO0FBMkI3QixTQUFPdUUsR0FBR3RFLFVBM0JtQjtBQTRCN0IsT0FBS3NFLEdBQUdyRSxLQTVCcUI7QUE2QjdCLFFBQU1xRSxHQUFHcEUsRUE3Qm9CO0FBOEI3QixRQUFNb0UsR0FBR25FLEdBOUJvQjtBQStCN0IsT0FBS21FLEdBQUdsRSxNQS9CcUI7QUFnQzdCLE9BQUtrRSxHQUFHaEUsT0FoQ3FCO0FBaUM3QixPQUFLZ0UsR0FBR2pFLE9BakNxQjtBQWtDN0IsUUFBTWlFLEdBQUcvRCxHQWxDb0I7QUFtQzdCLFFBQU0rRCxHQUFHOUQsR0FuQ29CO0FBb0M3QixTQUFPOEQsR0FBRzdELFlBcENtQjtBQXFDN0IsT0FBSzZELEdBQUc1RCxHQXJDcUI7QUFzQzdCLE9BQUs0RCxHQUFHM0QsR0F0Q3FCO0FBdUM3QixPQUFLMkQsR0FBRzFELEdBdkNxQjtBQXdDN0IsT0FBSzBELEdBQUd6RCxHQXhDcUI7QUF5QzdCLE9BQUt5RCxHQUFHeEQsR0F6Q3FCO0FBMEM3QixRQUFNd0QsR0FBR3ZELEdBMUNvQjtBQTJDN0IsUUFBTXVELEdBQUd0RCxFQTNDb0I7QUE0QzdCLFFBQU1zRCxHQUFHckQsRUE1Q29CO0FBNkM3QixTQUFPcUQsR0FBR3BELFNBN0NtQjtBQThDN0IsU0FBT29ELEdBQUduRCxTQTlDbUI7QUErQzdCLE9BQUttRCxHQUFHbEQsRUEvQ3FCO0FBZ0Q3QixPQUFLa0QsR0FBR2pELEVBaERxQjtBQWlEN0IsUUFBTWlELEdBQUdoRCxHQWpEb0I7QUFrRDdCLFFBQU1nRCxHQUFHL0MsR0FsRG9CO0FBbUQ3QixPQUFLK0MsR0FBRzVDLEdBbkRxQjtBQW9EN0IsT0FBSzRDLEdBQUczQztBQXBEcUIsQ0FBeEI7O0FBdURBLE1BQU02QyxzQ0FBZTtBQUMxQjtBQUNBO0FBQ0FDLFNBQU9ILEdBQUd0QyxLQUhnQjtBQUkxQjBDLFFBQU1KLEdBQUdyQyxJQUppQjtBQUsxQjBDLFNBQU9MLEdBQUdwQyxLQUxnQjtBQU0xQjBDLFNBQU9OLEdBQUduQyxLQU5nQjtBQU8xQjBDLFNBQU9QLEdBQUdILEtBUGdCO0FBUTFCVyxZQUFVUixHQUFHbEMsUUFSYTtBQVMxQjJDLFVBQVFULEdBQUd6QyxNQVRlO0FBVTFCbUQsWUFBVVYsR0FBR2pDLFFBVmE7QUFXMUI0QyxXQUFTWCxHQUFHaEMsT0FYYztBQVkxQjRDLE1BQUlaLEdBQUcvQixFQVptQjtBQWExQjRDLFFBQU1iLEdBQUc5QixJQWJpQjtBQWMxQjRDLFVBQVFkLEdBQUc3QixNQWRlO0FBZTFCNEMsV0FBU2YsR0FBRzVCLE9BZmM7QUFnQjFCNEMsU0FBT2hCLEdBQUdULEtBaEJnQjtBQWlCMUIwQixXQUFTakIsR0FBRzNCLE9BakJjO0FBa0IxQjZDLE9BQUtsQixHQUFHMUIsR0FsQmtCO0FBbUIxQjZDLFlBQVVuQixHQUFHekIsUUFuQmE7QUFvQjFCNkMsTUFBSXBCLEdBQUd4QixFQXBCbUI7QUFxQjFCNkMsVUFBUXJCLEdBQUd2QixNQXJCZTtBQXNCMUI2QyxNQUFJdEIsR0FBRzdDLEVBdEJtQjtBQXVCMUJvRSxjQUFZdkIsR0FBRzlDLFVBdkJXO0FBd0IxQnNFLE9BQUt4QixHQUFHdEIsR0F4QmtCO0FBeUIxQitDLE9BQUt6QixHQUFHckIsR0F6QmtCO0FBMEIxQitDLFFBQU0xQixHQUFHWCxJQTFCaUI7QUEyQjFCc0MsVUFBUTNCLEdBQUdwQixNQTNCZTtBQTRCMUJnRCxTQUFPNUIsR0FBR25CLEtBNUJnQjtBQTZCMUJnRCxVQUFRN0IsR0FBR2xCLE1BN0JlO0FBOEIxQmdELFFBQU05QixHQUFHakIsSUE5QmlCO0FBK0IxQmdELFNBQU8vQixHQUFHaEIsS0EvQmdCO0FBZ0MxQmdELFFBQU1oQyxHQUFHVixJQWhDaUI7QUFpQzFCMkMsT0FBS2pDLEdBQUdmLEdBakNrQjtBQWtDMUJpRCxVQUFRbEMsR0FBR3hDLE1BbENlO0FBbUMxQjJFLE9BQUtuQyxHQUFHZCxHQW5Da0I7QUFvQzFCa0QsUUFBTXBDLEdBQUd2QyxJQXBDaUI7QUFxQzFCNEUsU0FBT3JDLEdBQUdiLEtBckNnQjtBQXNDMUJtRCxRQUFNdEMsR0FBR1osSUF0Q2lCO0FBdUMxQm1ELFNBQU92QyxHQUFHUjtBQXZDZ0IsQ0FBckI7O0FBMENBLE1BQU1nRCxrQ0FBYSxFQUFuQjs7QUFxQlAsU0FBU0MsT0FBVCxDQUFpQkMsQ0FBakIsRUFBeUJDLElBQXpCLEVBQW9DO0FBQ2xDLE1BQUlBLElBQUosRUFBVTtBQUNSLFdBQU9ELEtBQUssT0FBT0EsRUFBRUMsSUFBVCxLQUFrQixRQUF2QixJQUFtQ0QsRUFBRUMsSUFBRixLQUFXQSxJQUFyRDtBQUNEO0FBQ0QsU0FBT0QsS0FBSyxPQUFPQSxFQUFFQyxJQUFULEtBQWtCLFFBQTlCO0FBQ0Q7O0FBRUQsU0FBU0MsUUFBVCxDQUFrQkYsQ0FBbEIsRUFBMEI3SSxLQUExQixFQUFzQztBQUNwQyxNQUFJQSxLQUFKLEVBQVc7QUFDVCxXQUFPNEksUUFBUUMsQ0FBUixLQUFjQSxFQUFFQyxJQUFGLENBQU85SSxLQUFQLEtBQWlCQSxLQUF0QztBQUNEO0FBQ0QsU0FBTzRJLFFBQVFDLENBQVIsS0FBYyxPQUFPQSxFQUFFQyxJQUFGLENBQU85SSxLQUFkLEtBQXdCLFFBQTdDO0FBQ0Q7O0FBRUQsTUFBTWdKLFNBQU4sQ0FBZ0I7O0FBTWRDLGNBQ0U7QUFDRUMsWUFERjtBQUVFSixRQUZGO0FBR0VLLFNBSEY7QUFJRUM7QUFKRixHQURGLEVBWUU7QUFDQSxTQUFLRixRQUFMLEdBQWdCQSxRQUFoQjtBQUNBLFNBQUtKLElBQUwsR0FBWUEsSUFBWjtBQUNBLFNBQUtLLEtBQUwsR0FBYUEsS0FBYjtBQUNBLFNBQUtDLEtBQUwsR0FBYUEsS0FBYjtBQUNEO0FBdkJhOztBQTBCVCxTQUFTN0ssUUFBVCxDQUFrQnNLLENBQWxCLEVBQTBCTSxLQUExQixFQUEwQztBQUMvQyxNQUFJRSxJQUFJVCxRQUFRQyxDQUFSLEVBQVcxQyxHQUFHTixNQUFkLENBQVI7QUFDQSxNQUFJc0QsU0FBUyxJQUFiLEVBQW1CO0FBQ2pCLFdBQU9FLEtBQUtSLEVBQUVTLEdBQUYsS0FBVUgsS0FBdEI7QUFDRDtBQUNELFNBQU9FLENBQVA7QUFDRDs7QUFFTSxNQUFNRSxXQUFOLENBQWtCO0FBTXZCTixjQUNFLEVBQUVLLEdBQUYsRUFBT0UsS0FBUCxFQUFjSixLQUFkLEVBREYsRUFFRTtBQUNBLFNBQUtOLElBQUwsR0FBWTNDLEdBQUdOLE1BQWY7QUFDQSxTQUFLcUQsUUFBTCxHQUFnQk8sVUFBVS9KLGFBQTFCO0FBQ0EsU0FBSzRKLEdBQUwsR0FBV0EsR0FBWDtBQUNBLFNBQUtFLEtBQUwsR0FBYUEsS0FBYjtBQUNBLFNBQUtKLEtBQUwsR0FBYUEsS0FBYjtBQUNEO0FBZHNCOztRQUFaRyxXLEdBQUFBLFc7QUFpQk4sTUFBTUUsZ0NBQVk7QUFDdkJDLGNBQVksQ0FEVztBQUV2QnBLLFdBQVMsQ0FGYztBQUd2QkcsY0FBWSxDQUhXO0FBSXZCRixrQkFBZ0IsQ0FKTztBQUt2QkcsaUJBQWUsQ0FMUTtBQU12QkYsbUJBQWlCLENBTk07QUFPdkJtSyxZQUFVLENBUGE7QUFRdkJDLFVBQVE7QUFSZSxDQUFsQjs7QUFXQSxTQUFTcEwsWUFBVCxDQUFzQnFLLENBQXRCLEVBQThCTSxLQUE5QixFQUE4QztBQUNuRCxNQUFJRSxJQUFJVCxRQUFRQyxDQUFSLEVBQVcxQyxHQUFHSixVQUFkLENBQVI7QUFDQSxNQUFJb0QsU0FBUyxJQUFiLEVBQW1CO0FBQ2pCLFdBQU9FLEtBQUtSLEVBQUVNLEtBQUYsS0FBWUEsS0FBeEI7QUFDRDtBQUNELFNBQU9FLENBQVA7QUFDRDs7QUFFTSxNQUFNUSxlQUFOLFNBQThCYixTQUE5QixDQUF3QztBQUM3Q0MsY0FBWSxFQUFFRSxLQUFGLEVBQVNDLEtBQVQsRUFBWixFQUFnRTtBQUM5RCxVQUFNO0FBQ0pGLGdCQUFVTyxVQUFVQyxVQURoQjtBQUVKWixZQUFNM0MsR0FBR0osVUFGTDtBQUdKb0QsV0FISTtBQUlKQztBQUpJLEtBQU47QUFNRDtBQVI0Qzs7UUFBbENTLGUsR0FBQUEsZTtBQVdOLFNBQVNwTCxTQUFULENBQW1Cb0ssQ0FBbkIsRUFBMkJNLEtBQTNCLEVBQXNEO0FBQzNELE1BQUlFLElBQUlOLFNBQVNGLENBQVQsRUFBWWhKLEdBQUdQLE9BQWYsQ0FBUjtBQUNBLE1BQUk2SixTQUFTLElBQWIsRUFBbUI7QUFDakIsUUFBSSxPQUFPQSxLQUFQLEtBQWlCLFFBQXJCLEVBQStCO0FBQzdCLGFBQU9FLEtBQUtSLEVBQUVNLEtBQUYsS0FBWUEsS0FBeEI7QUFDRCxLQUZELE1BRU8sSUFBSSxPQUFPQSxNQUFNVyxJQUFiLEtBQXNCLFVBQTFCLEVBQXNDO0FBQzNDLGFBQU9YLE1BQU1XLElBQU4sQ0FBV0MsS0FBS0EsTUFBTWxCLEVBQUVNLEtBQXhCLENBQVA7QUFDRDtBQUNGO0FBQ0QsU0FBT0UsQ0FBUDtBQUNEOztBQUVNLE1BQU1XLFlBQU4sU0FBMkJoQixTQUEzQixDQUFxQztBQUMxQ0MsY0FBWSxFQUFFRSxLQUFGLEVBQVNDLEtBQVQsRUFBWixFQUFnRTtBQUM5RCxVQUFNO0FBQ0pGLGdCQUFVTyxVQUFVbkssT0FEaEI7QUFFSndKLFlBQU16QyxhQUFhOEMsS0FBYixDQUZGO0FBR0pBLFdBSEk7QUFJSkM7QUFKSSxLQUFOO0FBTUQ7QUFSeUM7O1FBQS9CWSxZLEdBQUFBLFk7QUFXTixTQUFTdEwsWUFBVCxDQUFzQm1LLENBQXRCLEVBQThCTSxLQUE5QixFQUE4QztBQUNuRCxNQUFJRSxJQUFJTixTQUFTRixDQUFULEVBQVloSixHQUFHSixVQUFmLENBQVI7QUFDQSxNQUFJMEosU0FBUyxJQUFiLEVBQW1CO0FBQ2pCLFdBQU9FLEtBQUtSLEVBQUVNLEtBQUYsS0FBWUEsS0FBeEI7QUFDRDtBQUNELFNBQU9FLENBQVA7QUFDRDtBQUNNLE1BQU1ZLGVBQU4sU0FBOEJqQixTQUE5QixDQUF3QztBQUM3Q0MsY0FBWSxFQUFFRSxLQUFGLEVBQVNDLEtBQVQsRUFBWixFQUFnRTtBQUM5RCxVQUFNO0FBQ0pGLGdCQUFVTyxVQUFVaEssVUFEaEI7QUFFSnFKLFlBQU0xQyxnQkFBZ0IrQyxLQUFoQixDQUZGO0FBR0pBLFdBSEk7QUFJSkM7QUFKSSxLQUFOO0FBTUQ7QUFSNEM7O1FBQWxDYSxlLEdBQUFBLGU7QUFXTixTQUFTdEwsU0FBVCxDQUFtQmtLLENBQW5CLEVBQTJCTSxLQUEzQixFQUEyQztBQUNoRCxNQUFJRSxJQUFJVCxRQUFRQyxDQUFSLEVBQVcxQyxHQUFHUCxNQUFkLENBQVI7QUFDQSxNQUFJdUQsU0FBUyxJQUFiLEVBQW1CO0FBQ2pCLFdBQU9FLEtBQUtSLEVBQUVNLEtBQUYsS0FBWUEsS0FBeEI7QUFDRDtBQUNELFNBQU9FLENBQVA7QUFDRDtBQUNNLE1BQU1hLFlBQU4sU0FBMkJsQixTQUEzQixDQUFxQzs7QUFJMUNDLGNBQ0U7QUFDRUUsU0FERjtBQUVFSyxZQUFRLEtBRlY7QUFHRVcsYUFBUyxLQUhYO0FBSUVmO0FBSkYsR0FERixFQU9FO0FBQ0EsVUFBTTtBQUNKRixnQkFBVU8sVUFBVWxLLGNBRGhCO0FBRUp1SixZQUFNM0MsR0FBR1AsTUFGTDtBQUdKdUQsV0FISTtBQUlKQztBQUpJLEtBQU47QUFNQSxTQUFLSSxLQUFMLEdBQWFBLEtBQWI7QUFDQSxTQUFLVyxNQUFMLEdBQWNBLE1BQWQ7QUFDRDtBQXBCeUM7O1FBQS9CRCxZLEdBQUFBLFk7QUF1Qk4sU0FBU3RMLGlCQUFULENBQTJCaUssQ0FBM0IsRUFBbUNNLEtBQW5DLEVBQW1EO0FBQ3hELE1BQUlFLElBQUlULFFBQVFDLENBQVIsRUFBVzFDLEdBQUdGLFFBQWQsS0FBMkI0QyxFQUFFdUIsS0FBRixJQUFXLElBQTlDO0FBQ0EsTUFBSWpCLFNBQVMsSUFBYixFQUFtQjtBQUNqQixXQUFPRSxLQUFLUixFQUFFTSxLQUFGLEtBQVlBLEtBQXhCO0FBQ0Q7QUFDRCxTQUFPRSxDQUFQO0FBQ0Q7O0FBRU0sTUFBTWdCLG9CQUFOLFNBQW1DckIsU0FBbkMsQ0FBNkM7O0FBSWxEQyxjQUNFO0FBQ0VFLFNBREY7QUFFRW1CLFFBRkY7QUFHRUMsVUFIRjtBQUlFbkI7QUFKRixHQURGLEVBT0U7QUFDQSxVQUFNO0FBQ0pOLFlBQU0zQyxHQUFHRixRQURMO0FBRUppRCxnQkFBVU8sVUFBVWpLLGVBRmhCO0FBR0oySixXQUhJO0FBSUpDO0FBSkksS0FBTjtBQU1BLFNBQUtrQixJQUFMLEdBQVlBLElBQVo7QUFDQSxTQUFLQyxNQUFMLEdBQWNBLE1BQWQ7QUFDRDtBQXBCaUQ7O1FBQXZDRixvQixHQUFBQSxvQjtBQXVCTixTQUFTeEwsVUFBVCxDQUFvQmdLLENBQXBCLEVBQTRCO0FBQ2pDLFNBQU9ELFFBQVFDLENBQVIsRUFBVzFDLEdBQUdGLFFBQWQsS0FBMkI0QyxFQUFFdUIsS0FBRixJQUFXLElBQTdDO0FBQ0Q7QUFDTSxNQUFNSSxhQUFOLFNBQTRCeEIsU0FBNUIsQ0FBc0M7O0FBRzNDQyxjQUFZLEVBQUVtQixLQUFGLEVBQVNoQixLQUFULEVBQVosRUFBcUU7QUFDbkUsVUFBTSxFQUFFTixNQUFNM0MsR0FBR0YsUUFBWCxFQUFxQmlELFVBQVVPLFVBQVVFLFFBQXpDLEVBQW1EUCxLQUFuRCxFQUFOO0FBQ0EsU0FBS2dCLEtBQUwsR0FBYUEsS0FBYjtBQUNEO0FBTjBDOztRQUFoQ0ksYSxHQUFBQSxhO0FBU04sU0FBUzFMLFFBQVQsQ0FBa0IrSixDQUFsQixFQUEwQk0sS0FBMUIsRUFBMEM7QUFDL0MsTUFBSUUsSUFBSVQsUUFBUUMsQ0FBUixFQUFXMUMsR0FBR0wsTUFBZCxDQUFSO0FBQ0EsTUFBSXFELFNBQVMsSUFBYixFQUFtQjtBQUNqQixXQUFPRSxLQUFLUixFQUFFTSxLQUFGLEtBQVlBLEtBQXhCO0FBQ0Q7QUFDRCxTQUFPRSxDQUFQO0FBQ0Q7QUFDTSxNQUFNb0IsV0FBTixTQUEwQnpCLFNBQTFCLENBQW9DO0FBQ3pDQyxjQUFZLEVBQUVFLEtBQUYsRUFBU0MsS0FBVCxFQUFaLEVBQWdFO0FBQzlELFVBQU0sRUFBRU4sTUFBTTNDLEdBQUdMLE1BQVgsRUFBbUJvRCxVQUFVTyxVQUFVRyxNQUF2QyxFQUErQ1QsS0FBL0MsRUFBc0RDLEtBQXRELEVBQU47QUFDRDtBQUh3Qzs7UUFBOUJxQixXLEdBQUFBLFc7QUFNYixNQUFNQyxrQkFBa0IsQ0FBQzdCLENBQUQsRUFBSUMsSUFBSixLQUFhO0FBQ25DLE1BQUlELEtBQUtBLEVBQUU4QixPQUFPQyxRQUFULENBQUwsS0FBNEIsQ0FBQy9CLENBQUQsSUFBTUEsQ0FBbEMsQ0FBSixFQUEwQztBQUN4QyxXQUFPQSxLQUFLRCxRQUFRQyxDQUFSLEVBQVdDLElBQVgsQ0FBWjtBQUNEO0FBQ0QsU0FBTyxLQUFQO0FBQ0QsQ0FMRDs7QUFPTyxNQUFNK0IsOEJBQVloQyxDQUFELElBQVk2QixnQkFBZ0I3QixDQUFoQixFQUFtQjFDLEdBQUdsRyxNQUF0QixDQUE3QjtBQUNBLE1BQU02Syw4QkFBWWpDLENBQUQsSUFBWTZCLGdCQUFnQjdCLENBQWhCLEVBQW1CMUMsR0FBRzlGLE1BQXRCLENBQTdCO0FBQ0EsTUFBTTBLLGtDQUFjbEMsQ0FBRCxJQUFZNkIsZ0JBQWdCN0IsQ0FBaEIsRUFBbUIxQyxHQUFHaEcsTUFBdEIsQ0FBL0I7QUFDQSxNQUFNNkssOENBQW9CbkMsQ0FBRCxJQUFZNkIsZ0JBQWdCN0IsQ0FBaEIsRUFBbUIxQyxHQUFHNUYsT0FBdEIsQ0FBckM7O0FBRUEsTUFBTTBLLG9DQUFlcEMsQ0FBRCxJQUN6QmdDLFNBQVNoQyxDQUFULEtBQWVpQyxTQUFTakMsQ0FBVCxDQUFmLElBQThCa0MsV0FBV2xDLENBQVgsQ0FBOUIsSUFBK0NtQyxpQkFBaUJuQyxDQUFqQixDQUQxQzs7QUFHQSxTQUFTOUosT0FBVCxDQUFpQjhKLENBQWpCLEVBQXFDO0FBQzFDLFNBQU9nQyxTQUFTaEMsQ0FBVCxJQUNILFFBREcsR0FFSGlDLFNBQVNqQyxDQUFULElBQ0ksUUFESixHQUVJa0MsV0FBV2xDLENBQVgsSUFDSSxVQURKLEdBRUltQyxpQkFBaUJuQyxDQUFqQixJQUFzQixnQkFBdEIsR0FBeUMsRUFOckQ7QUFPRDs7QUFFTSxTQUFTN0osYUFBVCxDQUF1QmtNLENBQXZCLEVBQStCO0FBQ3BDLE1BQUlBLEVBQUU5QixLQUFGLElBQVc4QixFQUFFOUIsS0FBRixDQUFRK0IsYUFBdkIsRUFBc0M7QUFDcEMsV0FBT0QsRUFBRTlCLEtBQUYsQ0FBUStCLGFBQVIsQ0FBc0JDLElBQTdCO0FBQ0QsR0FGRCxNQUVPLElBQUlGLEVBQUVQLE9BQU9DLFFBQVQsTUFBdUIsQ0FBQ00sQ0FBRCxJQUFNQSxDQUE3QixDQUFKLEVBQXFDO0FBQzFDLFdBQU9sTSxjQUFja00sQ0FBZCxDQUFQO0FBQ0Q7QUFDRCxTQUFPLElBQVA7QUFDRCIsImZpbGUiOiJ0b2tlbnMuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAZmxvd1xuXG5pbXBvcnQgdHlwZSB7IExpc3QgfSBmcm9tICdpbW11dGFibGUnO1xuXG5leHBvcnQgdHlwZSBMb2NhdGlvbkluZm8gPSB7XG4gIGZpbGVuYW1lOiBzdHJpbmcsXG4gIHBvc2l0aW9uOiBudW1iZXIsXG4gIGxpbmU6IG51bWJlcixcbiAgY29sdW1uOiBudW1iZXIsXG59O1xuXG5leHBvcnQgY29uc3QgVG9rZW5DbGFzcyA9IHtcbiAgRW9mOiB7IG5hbWU6ICc8RW5kPicgfSxcbiAgSWRlbnQ6IHsgbmFtZTogJ0lkZW50aWZpZXInLCBpc0lkZW50aWZpZXJOYW1lOiB0cnVlIH0sXG4gIEtleXdvcmQ6IHsgbmFtZTogJ0tleXdvcmQnLCBpc0lkZW50aWZpZXJOYW1lOiB0cnVlIH0sXG4gIE51bWVyaWNMaXRlcmFsOiB7IG5hbWU6ICdOdW1lcmljJyB9LFxuICBUZW1wbGF0ZUVsZW1lbnQ6IHsgbmFtZTogJ1RlbXBsYXRlJyB9LFxuICBQdW5jdHVhdG9yOiB7IG5hbWU6ICdQdW5jdHVhdG9yJyB9LFxuICBTdHJpbmdMaXRlcmFsOiB7IG5hbWU6ICdTdHJpbmcnIH0sXG4gIFJlZ3VsYXJFeHByZXNzaW9uOiB7IG5hbWU6ICdSZWd1bGFyRXhwcmVzc2lvbicgfSxcbiAgSWxsZWdhbDogeyBuYW1lOiAnSWxsZWdhbCcgfSxcbn07XG5cbmNvbnN0IFRDID0gVG9rZW5DbGFzcztcblxuZXhwb3J0IGNvbnN0IFRva2VuVHlwZSA9IHtcbiAgRU9TOiB7IGtsYXNzOiBUQy5Fb2YsIG5hbWU6ICdFT1MnIH0sXG4gIExQQVJFTjogeyBrbGFzczogVEMuUHVuY3R1YXRvciwgbmFtZTogJygnIH0sXG4gIFJQQVJFTjogeyBrbGFzczogVEMuUHVuY3R1YXRvciwgbmFtZTogJyknIH0sXG4gIExCUkFDSzogeyBrbGFzczogVEMuUHVuY3R1YXRvciwgbmFtZTogJ1snIH0sXG4gIFJCUkFDSzogeyBrbGFzczogVEMuUHVuY3R1YXRvciwgbmFtZTogJ10nIH0sXG4gIExCUkFDRTogeyBrbGFzczogVEMuUHVuY3R1YXRvciwgbmFtZTogJ3snIH0sXG4gIFJCUkFDRTogeyBrbGFzczogVEMuUHVuY3R1YXRvciwgbmFtZTogJ30nIH0sXG4gIExTWU5UQVg6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICdsZWZ0LXN5bnRheCcgfSxcbiAgUlNZTlRBWDogeyBrbGFzczogVEMuUHVuY3R1YXRvciwgbmFtZTogJ3JpZ2h0LXN5bnRheCcgfSxcbiAgQ09MT046IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICc6JyB9LFxuICBTRU1JQ09MT046IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICc7JyB9LFxuICBQRVJJT0Q6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICcuJyB9LFxuICBFTExJUFNJUzogeyBrbGFzczogVEMuUHVuY3R1YXRvciwgbmFtZTogJy4uLicgfSxcbiAgQVJST1c6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICc9PicgfSxcbiAgQ09ORElUSU9OQUw6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICc/JyB9LFxuICBJTkM6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICcrKycgfSxcbiAgREVDOiB7IGtsYXNzOiBUQy5QdW5jdHVhdG9yLCBuYW1lOiAnLS0nIH0sXG4gIEFTU0lHTjogeyBrbGFzczogVEMuUHVuY3R1YXRvciwgbmFtZTogJz0nIH0sXG4gIEFTU0lHTl9CSVRfT1I6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICd8PScgfSxcbiAgQVNTSUdOX0JJVF9YT1I6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICdePScgfSxcbiAgQVNTSUdOX0JJVF9BTkQ6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICcmPScgfSxcbiAgQVNTSUdOX1NITDogeyBrbGFzczogVEMuUHVuY3R1YXRvciwgbmFtZTogJzw8PScgfSxcbiAgQVNTSUdOX1NIUjogeyBrbGFzczogVEMuUHVuY3R1YXRvciwgbmFtZTogJz4+PScgfSxcbiAgQVNTSUdOX1NIUl9VTlNJR05FRDogeyBrbGFzczogVEMuUHVuY3R1YXRvciwgbmFtZTogJz4+Pj0nIH0sXG4gIEFTU0lHTl9BREQ6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICcrPScgfSxcbiAgQVNTSUdOX1NVQjogeyBrbGFzczogVEMuUHVuY3R1YXRvciwgbmFtZTogJy09JyB9LFxuICBBU1NJR05fTVVMOiB7IGtsYXNzOiBUQy5QdW5jdHVhdG9yLCBuYW1lOiAnKj0nIH0sXG4gIEFTU0lHTl9ESVY6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICcvPScgfSxcbiAgQVNTSUdOX01PRDogeyBrbGFzczogVEMuUHVuY3R1YXRvciwgbmFtZTogJyU9JyB9LFxuICBBU1NJR05fRVhQOiB7IGtsYXNzOiBUQy5QdW5jdHVhdG9yLCBuYW1lOiAnKio9JyB9LFxuICBDT01NQTogeyBrbGFzczogVEMuUHVuY3R1YXRvciwgbmFtZTogJywnIH0sXG4gIE9SOiB7IGtsYXNzOiBUQy5QdW5jdHVhdG9yLCBuYW1lOiAnfHwnIH0sXG4gIEFORDogeyBrbGFzczogVEMuUHVuY3R1YXRvciwgbmFtZTogJyYmJyB9LFxuICBCSVRfT1I6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICd8JyB9LFxuICBCSVRfWE9SOiB7IGtsYXNzOiBUQy5QdW5jdHVhdG9yLCBuYW1lOiAnXicgfSxcbiAgQklUX0FORDogeyBrbGFzczogVEMuUHVuY3R1YXRvciwgbmFtZTogJyYnIH0sXG4gIFNITDogeyBrbGFzczogVEMuUHVuY3R1YXRvciwgbmFtZTogJzw8JyB9LFxuICBTSFI6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICc+PicgfSxcbiAgU0hSX1VOU0lHTkVEOiB7IGtsYXNzOiBUQy5QdW5jdHVhdG9yLCBuYW1lOiAnPj4+JyB9LFxuICBBREQ6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICcrJyB9LFxuICBTVUI6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICctJyB9LFxuICBNVUw6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICcqJyB9LFxuICBESVY6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICcvJyB9LFxuICBNT0Q6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICclJyB9LFxuICBFWFA6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICcqKicgfSxcbiAgRVE6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICc9PScgfSxcbiAgTkU6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICchPScgfSxcbiAgRVFfU1RSSUNUOiB7IGtsYXNzOiBUQy5QdW5jdHVhdG9yLCBuYW1lOiAnPT09JyB9LFxuICBORV9TVFJJQ1Q6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICchPT0nIH0sXG4gIExUOiB7IGtsYXNzOiBUQy5QdW5jdHVhdG9yLCBuYW1lOiAnPCcgfSxcbiAgR1Q6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICc+JyB9LFxuICBMVEU6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICc8PScgfSxcbiAgR1RFOiB7IGtsYXNzOiBUQy5QdW5jdHVhdG9yLCBuYW1lOiAnPj0nIH0sXG4gIElOU1RBTkNFT0Y6IHsga2xhc3M6IFRDLktleXdvcmQsIG5hbWU6ICdpbnN0YW5jZW9mJyB9LFxuICBJTjogeyBrbGFzczogVEMuS2V5d29yZCwgbmFtZTogJ2luJyB9LFxuICBOT1Q6IHsga2xhc3M6IFRDLlB1bmN0dWF0b3IsIG5hbWU6ICchJyB9LFxuICBCSVRfTk9UOiB7IGtsYXNzOiBUQy5QdW5jdHVhdG9yLCBuYW1lOiAnficgfSxcbiAgQVdBSVQ6IHsga2xhc3M6IFRDLktleXdvcmQsIG5hbWU6ICdhd2FpdCcgfSxcbiAgREVMRVRFOiB7IGtsYXNzOiBUQy5LZXl3b3JkLCBuYW1lOiAnZGVsZXRlJyB9LFxuICBUWVBFT0Y6IHsga2xhc3M6IFRDLktleXdvcmQsIG5hbWU6ICd0eXBlb2YnIH0sXG4gIFZPSUQ6IHsga2xhc3M6IFRDLktleXdvcmQsIG5hbWU6ICd2b2lkJyB9LFxuICBCUkVBSzogeyBrbGFzczogVEMuS2V5d29yZCwgbmFtZTogJ2JyZWFrJyB9LFxuICBDQVNFOiB7IGtsYXNzOiBUQy5LZXl3b3JkLCBuYW1lOiAnY2FzZScgfSxcbiAgQ0FUQ0g6IHsga2xhc3M6IFRDLktleXdvcmQsIG5hbWU6ICdjYXRjaCcgfSxcbiAgQ0xBU1M6IHsga2xhc3M6IFRDLktleXdvcmQsIG5hbWU6ICdjbGFzcycgfSxcbiAgQ09OVElOVUU6IHsga2xhc3M6IFRDLktleXdvcmQsIG5hbWU6ICdjb250aW51ZScgfSxcbiAgREVCVUdHRVI6IHsga2xhc3M6IFRDLktleXdvcmQsIG5hbWU6ICdkZWJ1Z2dlcicgfSxcbiAgREVGQVVMVDogeyBrbGFzczogVEMuS2V5d29yZCwgbmFtZTogJ2RlZmF1bHQnIH0sXG4gIERPOiB7IGtsYXNzOiBUQy5LZXl3b3JkLCBuYW1lOiAnZG8nIH0sXG4gIEVMU0U6IHsga2xhc3M6IFRDLktleXdvcmQsIG5hbWU6ICdlbHNlJyB9LFxuICBFWFBPUlQ6IHsga2xhc3M6IFRDLktleXdvcmQsIG5hbWU6ICdleHBvcnQnIH0sXG4gIEVYVEVORFM6IHsga2xhc3M6IFRDLktleXdvcmQsIG5hbWU6ICdleHRlbmRzJyB9LFxuICBGSU5BTExZOiB7IGtsYXNzOiBUQy5LZXl3b3JkLCBuYW1lOiAnZmluYWxseScgfSxcbiAgRk9SOiB7IGtsYXNzOiBUQy5LZXl3b3JkLCBuYW1lOiAnZm9yJyB9LFxuICBGVU5DVElPTjogeyBrbGFzczogVEMuS2V5d29yZCwgbmFtZTogJ2Z1bmN0aW9uJyB9LFxuICBJRjogeyBrbGFzczogVEMuS2V5d29yZCwgbmFtZTogJ2lmJyB9LFxuICBJTVBPUlQ6IHsga2xhc3M6IFRDLktleXdvcmQsIG5hbWU6ICdpbXBvcnQnIH0sXG4gIExFVDogeyBrbGFzczogVEMuS2V5d29yZCwgbmFtZTogJ2xldCcgfSxcbiAgTkVXOiB7IGtsYXNzOiBUQy5LZXl3b3JkLCBuYW1lOiAnbmV3JyB9LFxuICBSRVRVUk46IHsga2xhc3M6IFRDLktleXdvcmQsIG5hbWU6ICdyZXR1cm4nIH0sXG4gIFNVUEVSOiB7IGtsYXNzOiBUQy5LZXl3b3JkLCBuYW1lOiAnc3VwZXInIH0sXG4gIFNXSVRDSDogeyBrbGFzczogVEMuS2V5d29yZCwgbmFtZTogJ3N3aXRjaCcgfSxcbiAgVEhJUzogeyBrbGFzczogVEMuS2V5d29yZCwgbmFtZTogJ3RoaXMnIH0sXG4gIFRIUk9XOiB7IGtsYXNzOiBUQy5LZXl3b3JkLCBuYW1lOiAndGhyb3cnIH0sXG4gIFRSWTogeyBrbGFzczogVEMuS2V5d29yZCwgbmFtZTogJ3RyeScgfSxcbiAgVkFSOiB7IGtsYXNzOiBUQy5LZXl3b3JkLCBuYW1lOiAndmFyJyB9LFxuICBXSElMRTogeyBrbGFzczogVEMuS2V5d29yZCwgbmFtZTogJ3doaWxlJyB9LFxuICBXSVRIOiB7IGtsYXNzOiBUQy5LZXl3b3JkLCBuYW1lOiAnd2l0aCcgfSxcbiAgTlVMTDogeyBrbGFzczogVEMuS2V5d29yZCwgbmFtZTogJ251bGwnIH0sXG4gIFRSVUU6IHsga2xhc3M6IFRDLktleXdvcmQsIG5hbWU6ICd0cnVlJyB9LFxuICBGQUxTRTogeyBrbGFzczogVEMuS2V5d29yZCwgbmFtZTogJ2ZhbHNlJyB9LFxuICBZSUVMRDogeyBrbGFzczogVEMuS2V5d29yZCwgbmFtZTogJ3lpZWxkJyB9LFxuICBOVU1CRVI6IHsga2xhc3M6IFRDLk51bWVyaWNMaXRlcmFsLCBuYW1lOiAnJyB9LFxuICBTVFJJTkc6IHsga2xhc3M6IFRDLlN0cmluZ0xpdGVyYWwsIG5hbWU6ICcnIH0sXG4gIFJFR0VYUDogeyBrbGFzczogVEMuUmVndWxhckV4cHJlc3Npb24sIG5hbWU6ICcnIH0sXG4gIElERU5USUZJRVI6IHsga2xhc3M6IFRDLklkZW50LCBuYW1lOiAnJyB9LFxuICBDT05TVDogeyBrbGFzczogVEMuS2V5d29yZCwgbmFtZTogJ2NvbnN0JyB9LFxuICBURU1QTEFURTogeyBrbGFzczogVEMuVGVtcGxhdGVFbGVtZW50LCBuYW1lOiAnJyB9LFxuICBJTExFR0FMOiB7IGtsYXNzOiBUQy5JbGxlZ2FsLCBuYW1lOiAnJyB9LFxufTtcblxuY29uc3QgVFQgPSBUb2tlblR5cGU7XG5cbmV4cG9ydCBjb25zdCBwdW5jdHVhdG9yVGFibGUgPSB7XG4gICcoJzogVFQuTFBBUkVOLFxuICAnKSc6IFRULlJQQVJFTixcbiAgJ1snOiBUVC5MQlJBQ0ssXG4gICddJzogVFQuUkJSQUNLLFxuICAneyc6IFRULkxCUkFDRSxcbiAgJ30nOiBUVC5SQlJBQ0UsXG4gICc6JzogVFQuQ09MT04sXG4gICc7JzogVFQuU0VNSUNPTE9OLFxuICAnLic6IFRULlBFUklPRCxcbiAgJy4uLic6IFRULkVMTElQU0lTLFxuICAnPT4nOiBUVC5BUlJPVyxcbiAgJz8nOiBUVC5DT05ESVRJT05BTCxcbiAgJysrJzogVFQuSU5DLFxuICAnLS0nOiBUVC5ERUMsXG4gICc9JzogVFQuQVNTSUdOLFxuICAnfD0nOiBUVC5BU1NJR05fQklUX09SLFxuICAnXj0nOiBUVC5BU1NJR05fQklUX1hPUixcbiAgJyY9JzogVFQuQVNTSUdOX0JJVF9BTkQsXG4gICc8PD0nOiBUVC5BU1NJR05fU0hMLFxuICAnPj49JzogVFQuQVNTSUdOX1NIUixcbiAgJz4+Pj0nOiBUVC5BU1NJR05fU0hSX1VOU0lHTkVELFxuICAnKz0nOiBUVC5BU1NJR05fQURELFxuICAnLT0nOiBUVC5BU1NJR05fU1VCLFxuICAnKj0nOiBUVC5BU1NJR05fTVVMLFxuICAnLz0nOiBUVC5BU1NJR05fRElWLFxuICAnJT0nOiBUVC5BU1NJR05fTU9ELFxuICAnKio9JzogVFQuQVNTSUdOX0VYUCxcbiAgJywnOiBUVC5DT01NQSxcbiAgJ3x8JzogVFQuT1IsXG4gICcmJic6IFRULkFORCxcbiAgJ3wnOiBUVC5CSVRfT1IsXG4gICcmJzogVFQuQklUX0FORCxcbiAgJ14nOiBUVC5CSVRfWE9SLFxuICAnPDwnOiBUVC5TSEwsXG4gICc+Pic6IFRULlNIUixcbiAgJz4+Pic6IFRULlNIUl9VTlNJR05FRCxcbiAgJysnOiBUVC5BREQsXG4gICctJzogVFQuU1VCLFxuICAnKic6IFRULk1VTCxcbiAgJy8nOiBUVC5ESVYsXG4gICclJzogVFQuTU9ELFxuICAnKionOiBUVC5FWFAsXG4gICc9PSc6IFRULkVRLFxuICAnIT0nOiBUVC5ORSxcbiAgJz09PSc6IFRULkVRX1NUUklDVCxcbiAgJyE9PSc6IFRULk5FX1NUUklDVCxcbiAgJzwnOiBUVC5MVCxcbiAgJz4nOiBUVC5HVCxcbiAgJzw9JzogVFQuTFRFLFxuICAnPj0nOiBUVC5HVEUsXG4gICchJzogVFQuTk9ULFxuICAnfic6IFRULkJJVF9OT1QsXG59O1xuXG5leHBvcnQgY29uc3Qga2V5d29yZFRhYmxlID0ge1xuICAvLyAnYXdhaXQnOiBUVC5BV0FJVCwgVE9ETzogdW5jb21tZW50IHdoZW4gbmV3IHZlcnNpb24gb2Ygc2hpZnQgaXMgdXNlZFxuICAvLyBUT0RPOiBhZGQgJ2FzeW5jJ1xuICBicmVhazogVFQuQlJFQUssXG4gIGNhc2U6IFRULkNBU0UsXG4gIGNhdGNoOiBUVC5DQVRDSCxcbiAgY2xhc3M6IFRULkNMQVNTLFxuICBjb25zdDogVFQuQ09OU1QsXG4gIGNvbnRpbnVlOiBUVC5DT05USU5VRSxcbiAgZGVsZXRlOiBUVC5ERUxFVEUsXG4gIGRlYnVnZ2VyOiBUVC5ERUJVR0dFUixcbiAgZGVmYXVsdDogVFQuREVGQVVMVCxcbiAgZG86IFRULkRPLFxuICBlbHNlOiBUVC5FTFNFLFxuICBleHBvcnQ6IFRULkVYUE9SVCxcbiAgZXh0ZW5kczogVFQuRVhURU5EUyxcbiAgZmFsc2U6IFRULkZBTFNFLFxuICBmaW5hbGx5OiBUVC5GSU5BTExZLFxuICBmb3I6IFRULkZPUixcbiAgZnVuY3Rpb246IFRULkZVTkNUSU9OLFxuICBpZjogVFQuSUYsXG4gIGltcG9ydDogVFQuSU1QT1JULFxuICBpbjogVFQuSU4sXG4gIGluc3RhbmNlb2Y6IFRULklOU1RBTkNFT0YsXG4gIGxldDogVFQuTEVULFxuICBuZXc6IFRULk5FVyxcbiAgbnVsbDogVFQuTlVMTCxcbiAgcmV0dXJuOiBUVC5SRVRVUk4sXG4gIHN1cGVyOiBUVC5TVVBFUixcbiAgc3dpdGNoOiBUVC5TV0lUQ0gsXG4gIHRoaXM6IFRULlRISVMsXG4gIHRocm93OiBUVC5USFJPVyxcbiAgdHJ1ZTogVFQuVFJVRSxcbiAgdHJ5OiBUVC5UUlksXG4gIHR5cGVvZjogVFQuVFlQRU9GLFxuICB2YXI6IFRULlZBUixcbiAgdm9pZDogVFQuVk9JRCxcbiAgd2hpbGU6IFRULldISUxFLFxuICB3aXRoOiBUVC5XSVRILFxuICB5aWVsZDogVFQuWUlFTEQsXG59O1xuXG5leHBvcnQgY29uc3QgRW1wdHlUb2tlbiA9IHt9O1xuXG5leHBvcnQgdHlwZSBTdGFydExvY2F0aW9uID0ge1xuICBsaW5lOiBudW1iZXIsXG4gIGNvbHVtbjogbnVtYmVyLFxuICBmaWxlbmFtZTogc3RyaW5nLFxuICBwb3NpdGlvbjogbnVtYmVyLFxufTtcblxuZXhwb3J0IHR5cGUgU2xpY2UgPSB7XG4gIHRleHQ6IHN0cmluZyxcbiAgc3RhcnQ6IG51bWJlcixcbiAgc3RhcnRMb2NhdGlvbjogU3RhcnRMb2NhdGlvbixcbiAgZW5kOiBudW1iZXIsXG59O1xuXG50eXBlIFRva2VuVHlwZVR5cGUgPSB7XG4gIGtsYXNzOiB7IG5hbWU6IHN0cmluZywgaXNJZGVudGlmaWVyTmFtZT86IGJvb2xlYW4gfSxcbiAgbmFtZTogc3RyaW5nLFxufTtcblxuZnVuY3Rpb24gaGFzVHlwZSh4OiBhbnksIHR5cGU/OiB7fSkge1xuICBpZiAodHlwZSkge1xuICAgIHJldHVybiB4ICYmIHR5cGVvZiB4LnR5cGUgPT09ICdvYmplY3QnICYmIHgudHlwZSA9PT0gdHlwZTtcbiAgfVxuICByZXR1cm4geCAmJiB0eXBlb2YgeC50eXBlID09PSAnb2JqZWN0Jztcbn1cblxuZnVuY3Rpb24gaGFzS2xhc3MoeDogYW55LCBrbGFzcz86IHt9KSB7XG4gIGlmIChrbGFzcykge1xuICAgIHJldHVybiBoYXNUeXBlKHgpICYmIHgudHlwZS5rbGFzcyA9PT0ga2xhc3M7XG4gIH1cbiAgcmV0dXJuIGhhc1R5cGUoeCkgJiYgdHlwZW9mIHgudHlwZS5rbGFzcyA9PT0gJ29iamVjdCc7XG59XG5cbmNsYXNzIEJhc2VUb2tlbiB7XG4gIHR5cGVDb2RlOiBudW1iZXI7XG4gIHR5cGU6IFRva2VuVHlwZVR5cGU7XG4gIHZhbHVlOiA/c3RyaW5nIHwgP251bWJlcjtcbiAgc2xpY2U6ID9TbGljZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICB7XG4gICAgICB0eXBlQ29kZSxcbiAgICAgIHR5cGUsXG4gICAgICB2YWx1ZSxcbiAgICAgIHNsaWNlLFxuICAgIH06IHtcbiAgICAgIHR5cGVDb2RlOiBudW1iZXIsXG4gICAgICB0eXBlOiBUb2tlblR5cGVUeXBlLFxuICAgICAgdmFsdWU/OiBzdHJpbmcgfCBudW1iZXIsXG4gICAgICBzbGljZT86IFNsaWNlLFxuICAgIH0sXG4gICkge1xuICAgIHRoaXMudHlwZUNvZGUgPSB0eXBlQ29kZTtcbiAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLnNsaWNlID0gc2xpY2U7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzU3RyaW5nKHg6IGFueSwgdmFsdWU/OiBzdHJpbmcpIHtcbiAgbGV0IHIgPSBoYXNUeXBlKHgsIFRULlNUUklORyk7XG4gIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgcmV0dXJuIHIgJiYgeC5zdHIgPT09IHZhbHVlO1xuICB9XG4gIHJldHVybiByO1xufVxuXG5leHBvcnQgY2xhc3MgU3RyaW5nVG9rZW4ge1xuICB0eXBlOiBUb2tlblR5cGVUeXBlO1xuICBzdHI6IHN0cmluZztcbiAgb2N0YWw6ID9zdHJpbmc7XG4gIHNsaWNlOiA/U2xpY2U7XG4gIHR5cGVDb2RlOiBudW1iZXI7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHsgc3RyLCBvY3RhbCwgc2xpY2UgfTogeyBzdHI6IHN0cmluZywgb2N0YWw6ID9zdHJpbmcsIHNsaWNlPzogU2xpY2UgfSxcbiAgKSB7XG4gICAgdGhpcy50eXBlID0gVFQuU1RSSU5HO1xuICAgIHRoaXMudHlwZUNvZGUgPSBUeXBlQ29kZXMuU3RyaW5nTGl0ZXJhbDtcbiAgICB0aGlzLnN0ciA9IHN0cjtcbiAgICB0aGlzLm9jdGFsID0gb2N0YWw7XG4gICAgdGhpcy5zbGljZSA9IHNsaWNlO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBUeXBlQ29kZXMgPSB7XG4gIElkZW50aWZpZXI6IDAsXG4gIEtleXdvcmQ6IDEsXG4gIFB1bmN0dWF0b3I6IDIsXG4gIE51bWVyaWNMaXRlcmFsOiAzLFxuICBTdHJpbmdMaXRlcmFsOiA0LFxuICBUZW1wbGF0ZUVsZW1lbnQ6IDUsXG4gIFRlbXBsYXRlOiA2LFxuICBSZWdFeHA6IDcsXG59O1xuXG5leHBvcnQgZnVuY3Rpb24gaXNJZGVudGlmaWVyKHg6IGFueSwgdmFsdWU/OiBzdHJpbmcpIHtcbiAgbGV0IHIgPSBoYXNUeXBlKHgsIFRULklERU5USUZJRVIpO1xuICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgIHJldHVybiByICYmIHgudmFsdWUgPT09IHZhbHVlO1xuICB9XG4gIHJldHVybiByO1xufVxuXG5leHBvcnQgY2xhc3MgSWRlbnRpZmllclRva2VuIGV4dGVuZHMgQmFzZVRva2VuIHtcbiAgY29uc3RydWN0b3IoeyB2YWx1ZSwgc2xpY2UgfTogeyB2YWx1ZTogc3RyaW5nLCBzbGljZT86IFNsaWNlIH0pIHtcbiAgICBzdXBlcih7XG4gICAgICB0eXBlQ29kZTogVHlwZUNvZGVzLklkZW50aWZpZXIsXG4gICAgICB0eXBlOiBUVC5JREVOVElGSUVSLFxuICAgICAgdmFsdWUsXG4gICAgICBzbGljZSxcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNLZXl3b3JkKHg6IGFueSwgdmFsdWU/OiBzdHJpbmcgfCBzdHJpbmdbXSkge1xuICBsZXQgciA9IGhhc0tsYXNzKHgsIFRDLktleXdvcmQpO1xuICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gciAmJiB4LnZhbHVlID09PSB2YWx1ZTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZS5zb21lID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gdmFsdWUuc29tZSh2ID0+IHYgPT09IHgudmFsdWUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcjtcbn1cblxuZXhwb3J0IGNsYXNzIEtleXdvcmRUb2tlbiBleHRlbmRzIEJhc2VUb2tlbiB7XG4gIGNvbnN0cnVjdG9yKHsgdmFsdWUsIHNsaWNlIH06IHsgdmFsdWU6IHN0cmluZywgc2xpY2U/OiBTbGljZSB9KSB7XG4gICAgc3VwZXIoe1xuICAgICAgdHlwZUNvZGU6IFR5cGVDb2Rlcy5LZXl3b3JkLFxuICAgICAgdHlwZToga2V5d29yZFRhYmxlW3ZhbHVlXSxcbiAgICAgIHZhbHVlLFxuICAgICAgc2xpY2UsXG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzUHVuY3R1YXRvcih4OiBhbnksIHZhbHVlPzogc3RyaW5nKSB7XG4gIGxldCByID0gaGFzS2xhc3MoeCwgVEMuUHVuY3R1YXRvcik7XG4gIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgcmV0dXJuIHIgJiYgeC52YWx1ZSA9PT0gdmFsdWU7XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5leHBvcnQgY2xhc3MgUHVuY3R1YXRvclRva2VuIGV4dGVuZHMgQmFzZVRva2VuIHtcbiAgY29uc3RydWN0b3IoeyB2YWx1ZSwgc2xpY2UgfTogeyB2YWx1ZTogc3RyaW5nLCBzbGljZT86IFNsaWNlIH0pIHtcbiAgICBzdXBlcih7XG4gICAgICB0eXBlQ29kZTogVHlwZUNvZGVzLlB1bmN0dWF0b3IsXG4gICAgICB0eXBlOiBwdW5jdHVhdG9yVGFibGVbdmFsdWVdLFxuICAgICAgdmFsdWUsXG4gICAgICBzbGljZSxcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNOdW1lcmljKHg6IGFueSwgdmFsdWU/OiBudW1iZXIpIHtcbiAgbGV0IHIgPSBoYXNUeXBlKHgsIFRULk5VTUJFUik7XG4gIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgcmV0dXJuIHIgJiYgeC52YWx1ZSA9PT0gdmFsdWU7XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5leHBvcnQgY2xhc3MgTnVtZXJpY1Rva2VuIGV4dGVuZHMgQmFzZVRva2VuIHtcbiAgb2N0YWw6IGJvb2xlYW47XG4gIG5vY3RhbDogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICB7XG4gICAgICB2YWx1ZSxcbiAgICAgIG9jdGFsID0gZmFsc2UsXG4gICAgICBub2N0YWwgPSBmYWxzZSxcbiAgICAgIHNsaWNlLFxuICAgIH06IHsgdmFsdWU6IG51bWJlciwgb2N0YWw/OiBib29sZWFuLCBub2N0YWw/OiBib29sZWFuLCBzbGljZT86IFNsaWNlIH0sXG4gICkge1xuICAgIHN1cGVyKHtcbiAgICAgIHR5cGVDb2RlOiBUeXBlQ29kZXMuTnVtZXJpY0xpdGVyYWwsXG4gICAgICB0eXBlOiBUVC5OVU1CRVIsXG4gICAgICB2YWx1ZSxcbiAgICAgIHNsaWNlLFxuICAgIH0pO1xuICAgIHRoaXMub2N0YWwgPSBvY3RhbDtcbiAgICB0aGlzLm5vY3RhbCA9IG5vY3RhbDtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNUZW1wbGF0ZUVsZW1lbnQoeDogYW55LCB2YWx1ZT86IHN0cmluZykge1xuICBsZXQgciA9IGhhc1R5cGUoeCwgVFQuVEVNUExBVEUpICYmIHguaXRlbXMgPT0gbnVsbDtcbiAgaWYgKHZhbHVlICE9IG51bGwpIHtcbiAgICByZXR1cm4gciAmJiB4LnZhbHVlID09PSB2YWx1ZTtcbiAgfVxuICByZXR1cm4gcjtcbn1cblxuZXhwb3J0IGNsYXNzIFRlbXBsYXRlRWxlbWVudFRva2VuIGV4dGVuZHMgQmFzZVRva2VuIHtcbiAgdGFpbDogYm9vbGVhbjtcbiAgaW50ZXJwOiBib29sZWFuO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHtcbiAgICAgIHZhbHVlLFxuICAgICAgdGFpbCxcbiAgICAgIGludGVycCxcbiAgICAgIHNsaWNlLFxuICAgIH06IHsgdmFsdWU6IHN0cmluZywgdGFpbDogYm9vbGVhbiwgaW50ZXJwOiBib29sZWFuLCBzbGljZT86IFNsaWNlIH0sXG4gICkge1xuICAgIHN1cGVyKHtcbiAgICAgIHR5cGU6IFRULlRFTVBMQVRFLFxuICAgICAgdHlwZUNvZGU6IFR5cGVDb2Rlcy5UZW1wbGF0ZUVsZW1lbnQsXG4gICAgICB2YWx1ZSxcbiAgICAgIHNsaWNlLFxuICAgIH0pO1xuICAgIHRoaXMudGFpbCA9IHRhaWw7XG4gICAgdGhpcy5pbnRlcnAgPSBpbnRlcnA7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzVGVtcGxhdGUoeDogYW55KSB7XG4gIHJldHVybiBoYXNUeXBlKHgsIFRULlRFTVBMQVRFKSAmJiB4Lml0ZW1zICE9IG51bGw7XG59XG5leHBvcnQgY2xhc3MgVGVtcGxhdGVUb2tlbiBleHRlbmRzIEJhc2VUb2tlbiB7XG4gIGl0ZW1zOiBMaXN0PFRva2VuPjtcblxuICBjb25zdHJ1Y3Rvcih7IGl0ZW1zLCBzbGljZSB9OiB7IGl0ZW1zOiBMaXN0PFRva2VuPiwgc2xpY2U/OiBTbGljZSB9KSB7XG4gICAgc3VwZXIoeyB0eXBlOiBUVC5URU1QTEFURSwgdHlwZUNvZGU6IFR5cGVDb2Rlcy5UZW1wbGF0ZSwgc2xpY2UgfSk7XG4gICAgdGhpcy5pdGVtcyA9IGl0ZW1zO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1JlZ0V4cCh4OiBhbnksIHZhbHVlPzogc3RyaW5nKSB7XG4gIGxldCByID0gaGFzVHlwZSh4LCBUVC5SRUdFWFApO1xuICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgIHJldHVybiByICYmIHgudmFsdWUgPT09IHZhbHVlO1xuICB9XG4gIHJldHVybiByO1xufVxuZXhwb3J0IGNsYXNzIFJlZ0V4cFRva2VuIGV4dGVuZHMgQmFzZVRva2VuIHtcbiAgY29uc3RydWN0b3IoeyB2YWx1ZSwgc2xpY2UgfTogeyB2YWx1ZTogc3RyaW5nLCBzbGljZT86IFNsaWNlIH0pIHtcbiAgICBzdXBlcih7IHR5cGU6IFRULlJFR0VYUCwgdHlwZUNvZGU6IFR5cGVDb2Rlcy5SZWdFeHAsIHZhbHVlLCBzbGljZSB9KTtcbiAgfVxufVxuXG5jb25zdCBpc0RlbGltaXRlclR5cGUgPSAoeCwgdHlwZSkgPT4ge1xuICBpZiAoeCAmJiB4W1N5bWJvbC5pdGVyYXRvcl0gJiYgKFt4XSA9IHgpKSB7XG4gICAgcmV0dXJuIHggJiYgaGFzVHlwZSh4LCB0eXBlKTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59O1xuXG5leHBvcnQgY29uc3QgaXNQYXJlbnMgPSAoeDogYW55KSA9PiBpc0RlbGltaXRlclR5cGUoeCwgVFQuTFBBUkVOKTtcbmV4cG9ydCBjb25zdCBpc0JyYWNlcyA9ICh4OiBhbnkpID0+IGlzRGVsaW1pdGVyVHlwZSh4LCBUVC5MQlJBQ0UpO1xuZXhwb3J0IGNvbnN0IGlzQnJhY2tldHMgPSAoeDogYW55KSA9PiBpc0RlbGltaXRlclR5cGUoeCwgVFQuTEJSQUNLKTtcbmV4cG9ydCBjb25zdCBpc1N5bnRheFRlbXBsYXRlID0gKHg6IGFueSkgPT4gaXNEZWxpbWl0ZXJUeXBlKHgsIFRULkxTWU5UQVgpO1xuXG5leHBvcnQgY29uc3QgaXNEZWxpbWl0ZXIgPSAoeDogYW55KSA9PlxuICBpc1BhcmVucyh4KSB8fCBpc0JyYWNlcyh4KSB8fCBpc0JyYWNrZXRzKHgpIHx8IGlzU3ludGF4VGVtcGxhdGUoeCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRLaW5kKHg6IExpc3Q8VG9rZW5UcmVlPikge1xuICByZXR1cm4gaXNQYXJlbnMoeClcbiAgICA/ICdwYXJlbnMnXG4gICAgOiBpc0JyYWNlcyh4KVxuICAgICAgICA/ICdicmFjZXMnXG4gICAgICAgIDogaXNCcmFja2V0cyh4KVxuICAgICAgICAgICAgPyAnYnJhY2tldHMnXG4gICAgICAgICAgICA6IGlzU3ludGF4VGVtcGxhdGUoeCkgPyAnc3ludGF4VGVtcGxhdGUnIDogJyc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRMaW5lTnVtYmVyKHQ6IGFueSkge1xuICBpZiAodC5zbGljZSAmJiB0LnNsaWNlLnN0YXJ0TG9jYXRpb24pIHtcbiAgICByZXR1cm4gdC5zbGljZS5zdGFydExvY2F0aW9uLmxpbmU7XG4gIH0gZWxzZSBpZiAodFtTeW1ib2wuaXRlcmF0b3JdICYmIChbdF0gPSB0KSkge1xuICAgIHJldHVybiBnZXRMaW5lTnVtYmVyKHQpO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG5leHBvcnQgdHlwZSBUb2tlbiA9XG4gIHwgU3RyaW5nVG9rZW5cbiAgfCBJZGVudGlmaWVyVG9rZW5cbiAgfCBLZXl3b3JkVG9rZW5cbiAgfCBQdW5jdHVhdG9yVG9rZW5cbiAgfCBOdW1lcmljVG9rZW5cbiAgfCBUZW1wbGF0ZUVsZW1lbnRUb2tlblxuICB8IFRlbXBsYXRlVG9rZW5cbiAgfCBSZWdFeHBUb2tlbjtcbmV4cG9ydCB0eXBlIFRva2VuVHJlZSA9IFRva2VuIHwgTGlzdDxUb2tlblRyZWU+O1xuIl19\n\n/***/ },\n/* 20 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t//  Ramda v0.22.1\n\t//  https://github.com/ramda/ramda\n\t//  (c) 2013-2016 Scott Sauyet, Michael Hurley, and David Chambers\n\t//  Ramda may be freely distributed under the MIT license.\n\n\t;(function() {\n\n\t  'use strict';\n\n\t  /**\n\t     * A special placeholder value used to specify \"gaps\" within curried functions,\n\t     * allowing partial application of any combination of arguments, regardless of\n\t     * their positions.\n\t     *\n\t     * If `g` is a curried ternary function and `_` is `R.__`, the following are\n\t     * equivalent:\n\t     *\n\t     *   - `g(1, 2, 3)`\n\t     *   - `g(_, 2, 3)(1)`\n\t     *   - `g(_, _, 3)(1)(2)`\n\t     *   - `g(_, _, 3)(1, 2)`\n\t     *   - `g(_, 2, _)(1, 3)`\n\t     *   - `g(_, 2)(1)(3)`\n\t     *   - `g(_, 2)(1, 3)`\n\t     *   - `g(_, 2)(_, 3)(1)`\n\t     *\n\t     * @constant\n\t     * @memberOf R\n\t     * @since v0.6.0\n\t     * @category Function\n\t     * @example\n\t     *\n\t     *      var greet = R.replace('{name}', R.__, 'Hello, {name}!');\n\t     *      greet('Alice'); //=> 'Hello, Alice!'\n\t     */\n\t    var __ = { '@@functional/placeholder': true };\n\n\t    /* eslint-disable no-unused-vars */\n\t    var _arity = function _arity(n, fn) {\n\t        /* eslint-disable no-unused-vars */\n\t        switch (n) {\n\t        case 0:\n\t            return function () {\n\t                return fn.apply(this, arguments);\n\t            };\n\t        case 1:\n\t            return function (a0) {\n\t                return fn.apply(this, arguments);\n\t            };\n\t        case 2:\n\t            return function (a0, a1) {\n\t                return fn.apply(this, arguments);\n\t            };\n\t        case 3:\n\t            return function (a0, a1, a2) {\n\t                return fn.apply(this, arguments);\n\t            };\n\t        case 4:\n\t            return function (a0, a1, a2, a3) {\n\t                return fn.apply(this, arguments);\n\t            };\n\t        case 5:\n\t            return function (a0, a1, a2, a3, a4) {\n\t                return fn.apply(this, arguments);\n\t            };\n\t        case 6:\n\t            return function (a0, a1, a2, a3, a4, a5) {\n\t                return fn.apply(this, arguments);\n\t            };\n\t        case 7:\n\t            return function (a0, a1, a2, a3, a4, a5, a6) {\n\t                return fn.apply(this, arguments);\n\t            };\n\t        case 8:\n\t            return function (a0, a1, a2, a3, a4, a5, a6, a7) {\n\t                return fn.apply(this, arguments);\n\t            };\n\t        case 9:\n\t            return function (a0, a1, a2, a3, a4, a5, a6, a7, a8) {\n\t                return fn.apply(this, arguments);\n\t            };\n\t        case 10:\n\t            return function (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {\n\t                return fn.apply(this, arguments);\n\t            };\n\t        default:\n\t            throw new Error('First argument to _arity must be a non-negative integer no greater than ten');\n\t        }\n\t    };\n\n\t    var _arrayFromIterator = function _arrayFromIterator(iter) {\n\t        var list = [];\n\t        var next;\n\t        while (!(next = iter.next()).done) {\n\t            list.push(next.value);\n\t        }\n\t        return list;\n\t    };\n\n\t    var _arrayOf = function _arrayOf() {\n\t        return Array.prototype.slice.call(arguments);\n\t    };\n\n\t    var _cloneRegExp = function _cloneRegExp(pattern) {\n\t        return new RegExp(pattern.source, (pattern.global ? 'g' : '') + (pattern.ignoreCase ? 'i' : '') + (pattern.multiline ? 'm' : '') + (pattern.sticky ? 'y' : '') + (pattern.unicode ? 'u' : ''));\n\t    };\n\n\t    var _complement = function _complement(f) {\n\t        return function () {\n\t            return !f.apply(this, arguments);\n\t        };\n\t    };\n\n\t    /**\n\t     * Private `concat` function to merge two array-like objects.\n\t     *\n\t     * @private\n\t     * @param {Array|Arguments} [set1=[]] An array-like object.\n\t     * @param {Array|Arguments} [set2=[]] An array-like object.\n\t     * @return {Array} A new, merged array.\n\t     * @example\n\t     *\n\t     *      _concat([4, 5, 6], [1, 2, 3]); //=> [4, 5, 6, 1, 2, 3]\n\t     */\n\t    var _concat = function _concat(set1, set2) {\n\t        set1 = set1 || [];\n\t        set2 = set2 || [];\n\t        var idx;\n\t        var len1 = set1.length;\n\t        var len2 = set2.length;\n\t        var result = [];\n\t        idx = 0;\n\t        while (idx < len1) {\n\t            result[result.length] = set1[idx];\n\t            idx += 1;\n\t        }\n\t        idx = 0;\n\t        while (idx < len2) {\n\t            result[result.length] = set2[idx];\n\t            idx += 1;\n\t        }\n\t        return result;\n\t    };\n\n\t    var _containsWith = function _containsWith(pred, x, list) {\n\t        var idx = 0;\n\t        var len = list.length;\n\t        while (idx < len) {\n\t            if (pred(x, list[idx])) {\n\t                return true;\n\t            }\n\t            idx += 1;\n\t        }\n\t        return false;\n\t    };\n\n\t    var _filter = function _filter(fn, list) {\n\t        var idx = 0;\n\t        var len = list.length;\n\t        var result = [];\n\t        while (idx < len) {\n\t            if (fn(list[idx])) {\n\t                result[result.length] = list[idx];\n\t            }\n\t            idx += 1;\n\t        }\n\t        return result;\n\t    };\n\n\t    var _forceReduced = function _forceReduced(x) {\n\t        return {\n\t            '@@transducer/value': x,\n\t            '@@transducer/reduced': true\n\t        };\n\t    };\n\n\t    // String(x => x) evaluates to \"x => x\", so the pattern may not match.\n\t    var _functionName = function _functionName(f) {\n\t        // String(x => x) evaluates to \"x => x\", so the pattern may not match.\n\t        var match = String(f).match(/^function (\\w*)/);\n\t        return match == null ? '' : match[1];\n\t    };\n\n\t    var _has = function _has(prop, obj) {\n\t        return Object.prototype.hasOwnProperty.call(obj, prop);\n\t    };\n\n\t    var _identity = function _identity(x) {\n\t        return x;\n\t    };\n\n\t    var _isArguments = function () {\n\t        var toString = Object.prototype.toString;\n\t        return toString.call(arguments) === '[object Arguments]' ? function _isArguments(x) {\n\t            return toString.call(x) === '[object Arguments]';\n\t        } : function _isArguments(x) {\n\t            return _has('callee', x);\n\t        };\n\t    }();\n\n\t    /**\n\t     * Tests whether or not an object is an array.\n\t     *\n\t     * @private\n\t     * @param {*} val The object to test.\n\t     * @return {Boolean} `true` if `val` is an array, `false` otherwise.\n\t     * @example\n\t     *\n\t     *      _isArray([]); //=> true\n\t     *      _isArray(null); //=> false\n\t     *      _isArray({}); //=> false\n\t     */\n\t    var _isArray = Array.isArray || function _isArray(val) {\n\t        return val != null && val.length >= 0 && Object.prototype.toString.call(val) === '[object Array]';\n\t    };\n\n\t    var _isFunction = function _isFunction(x) {\n\t        return Object.prototype.toString.call(x) === '[object Function]';\n\t    };\n\n\t    /**\n\t     * Determine if the passed argument is an integer.\n\t     *\n\t     * @private\n\t     * @param {*} n\n\t     * @category Type\n\t     * @return {Boolean}\n\t     */\n\t    var _isInteger = Number.isInteger || function _isInteger(n) {\n\t        return n << 0 === n;\n\t    };\n\n\t    var _isNumber = function _isNumber(x) {\n\t        return Object.prototype.toString.call(x) === '[object Number]';\n\t    };\n\n\t    var _isObject = function _isObject(x) {\n\t        return Object.prototype.toString.call(x) === '[object Object]';\n\t    };\n\n\t    var _isPlaceholder = function _isPlaceholder(a) {\n\t        return a != null && typeof a === 'object' && a['@@functional/placeholder'] === true;\n\t    };\n\n\t    var _isRegExp = function _isRegExp(x) {\n\t        return Object.prototype.toString.call(x) === '[object RegExp]';\n\t    };\n\n\t    var _isString = function _isString(x) {\n\t        return Object.prototype.toString.call(x) === '[object String]';\n\t    };\n\n\t    var _isTransformer = function _isTransformer(obj) {\n\t        return typeof obj['@@transducer/step'] === 'function';\n\t    };\n\n\t    var _map = function _map(fn, functor) {\n\t        var idx = 0;\n\t        var len = functor.length;\n\t        var result = Array(len);\n\t        while (idx < len) {\n\t            result[idx] = fn(functor[idx]);\n\t            idx += 1;\n\t        }\n\t        return result;\n\t    };\n\n\t    // Based on https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\n\t    var _objectAssign = function _objectAssign(target) {\n\t        if (target == null) {\n\t            throw new TypeError('Cannot convert undefined or null to object');\n\t        }\n\t        var output = Object(target);\n\t        var idx = 1;\n\t        var length = arguments.length;\n\t        while (idx < length) {\n\t            var source = arguments[idx];\n\t            if (source != null) {\n\t                for (var nextKey in source) {\n\t                    if (_has(nextKey, source)) {\n\t                        output[nextKey] = source[nextKey];\n\t                    }\n\t                }\n\t            }\n\t            idx += 1;\n\t        }\n\t        return output;\n\t    };\n\n\t    var _of = function _of(x) {\n\t        return [x];\n\t    };\n\n\t    var _pipe = function _pipe(f, g) {\n\t        return function () {\n\t            return g.call(this, f.apply(this, arguments));\n\t        };\n\t    };\n\n\t    var _pipeP = function _pipeP(f, g) {\n\t        return function () {\n\t            var ctx = this;\n\t            return f.apply(ctx, arguments).then(function (x) {\n\t                return g.call(ctx, x);\n\t            });\n\t        };\n\t    };\n\n\t    // \\b matches word boundary; [\\b] matches backspace\n\t    var _quote = function _quote(s) {\n\t        var escaped = s.replace(/\\\\/g, '\\\\\\\\').replace(/[\\b]/g, '\\\\b')    // \\b matches word boundary; [\\b] matches backspace\n\t    .replace(/\\f/g, '\\\\f').replace(/\\n/g, '\\\\n').replace(/\\r/g, '\\\\r').replace(/\\t/g, '\\\\t').replace(/\\v/g, '\\\\v').replace(/\\0/g, '\\\\0');\n\t        return '\"' + escaped.replace(/\"/g, '\\\\\"') + '\"';\n\t    };\n\n\t    var _reduced = function _reduced(x) {\n\t        return x && x['@@transducer/reduced'] ? x : {\n\t            '@@transducer/value': x,\n\t            '@@transducer/reduced': true\n\t        };\n\t    };\n\n\t    /**\n\t     * An optimized, private array `slice` implementation.\n\t     *\n\t     * @private\n\t     * @param {Arguments|Array} args The array or arguments object to consider.\n\t     * @param {Number} [from=0] The array index to slice from, inclusive.\n\t     * @param {Number} [to=args.length] The array index to slice to, exclusive.\n\t     * @return {Array} A new, sliced array.\n\t     * @example\n\t     *\n\t     *      _slice([1, 2, 3, 4, 5], 1, 3); //=> [2, 3]\n\t     *\n\t     *      var firstThreeArgs = function(a, b, c, d) {\n\t     *        return _slice(arguments, 0, 3);\n\t     *      };\n\t     *      firstThreeArgs(1, 2, 3, 4); //=> [1, 2, 3]\n\t     */\n\t    var _slice = function _slice(args, from, to) {\n\t        switch (arguments.length) {\n\t        case 1:\n\t            return _slice(args, 0, args.length);\n\t        case 2:\n\t            return _slice(args, from, args.length);\n\t        default:\n\t            var list = [];\n\t            var idx = 0;\n\t            var len = Math.max(0, Math.min(args.length, to) - from);\n\t            while (idx < len) {\n\t                list[idx] = args[from + idx];\n\t                idx += 1;\n\t            }\n\t            return list;\n\t        }\n\t    };\n\n\t    /**\n\t     * Polyfill from <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString>.\n\t     */\n\t    var _toISOString = function () {\n\t        var pad = function pad(n) {\n\t            return (n < 10 ? '0' : '') + n;\n\t        };\n\t        return typeof Date.prototype.toISOString === 'function' ? function _toISOString(d) {\n\t            return d.toISOString();\n\t        } : function _toISOString(d) {\n\t            return d.getUTCFullYear() + '-' + pad(d.getUTCMonth() + 1) + '-' + pad(d.getUTCDate()) + 'T' + pad(d.getUTCHours()) + ':' + pad(d.getUTCMinutes()) + ':' + pad(d.getUTCSeconds()) + '.' + (d.getUTCMilliseconds() / 1000).toFixed(3).slice(2, 5) + 'Z';\n\t        };\n\t    }();\n\n\t    var _xfBase = {\n\t        init: function () {\n\t            return this.xf['@@transducer/init']();\n\t        },\n\t        result: function (result) {\n\t            return this.xf['@@transducer/result'](result);\n\t        }\n\t    };\n\n\t    var _xwrap = function () {\n\t        function XWrap(fn) {\n\t            this.f = fn;\n\t        }\n\t        XWrap.prototype['@@transducer/init'] = function () {\n\t            throw new Error('init not implemented on XWrap');\n\t        };\n\t        XWrap.prototype['@@transducer/result'] = function (acc) {\n\t            return acc;\n\t        };\n\t        XWrap.prototype['@@transducer/step'] = function (acc, x) {\n\t            return this.f(acc, x);\n\t        };\n\t        return function _xwrap(fn) {\n\t            return new XWrap(fn);\n\t        };\n\t    }();\n\n\t    var _aperture = function _aperture(n, list) {\n\t        var idx = 0;\n\t        var limit = list.length - (n - 1);\n\t        var acc = new Array(limit >= 0 ? limit : 0);\n\t        while (idx < limit) {\n\t            acc[idx] = _slice(list, idx, idx + n);\n\t            idx += 1;\n\t        }\n\t        return acc;\n\t    };\n\n\t    var _assign = typeof Object.assign === 'function' ? Object.assign : _objectAssign;\n\n\t    /**\n\t     * Similar to hasMethod, this checks whether a function has a [methodname]\n\t     * function. If it isn't an array it will execute that function otherwise it\n\t     * will default to the ramda implementation.\n\t     *\n\t     * @private\n\t     * @param {Function} fn ramda implemtation\n\t     * @param {String} methodname property to check for a custom implementation\n\t     * @return {Object} Whatever the return value of the method is.\n\t     */\n\t    var _checkForMethod = function _checkForMethod(methodname, fn) {\n\t        return function () {\n\t            var length = arguments.length;\n\t            if (length === 0) {\n\t                return fn();\n\t            }\n\t            var obj = arguments[length - 1];\n\t            return _isArray(obj) || typeof obj[methodname] !== 'function' ? fn.apply(this, arguments) : obj[methodname].apply(obj, _slice(arguments, 0, length - 1));\n\t        };\n\t    };\n\n\t    /**\n\t     * Optimized internal one-arity curry function.\n\t     *\n\t     * @private\n\t     * @category Function\n\t     * @param {Function} fn The function to curry.\n\t     * @return {Function} The curried function.\n\t     */\n\t    var _curry1 = function _curry1(fn) {\n\t        return function f1(a) {\n\t            if (arguments.length === 0 || _isPlaceholder(a)) {\n\t                return f1;\n\t            } else {\n\t                return fn.apply(this, arguments);\n\t            }\n\t        };\n\t    };\n\n\t    /**\n\t     * Optimized internal two-arity curry function.\n\t     *\n\t     * @private\n\t     * @category Function\n\t     * @param {Function} fn The function to curry.\n\t     * @return {Function} The curried function.\n\t     */\n\t    var _curry2 = function _curry2(fn) {\n\t        return function f2(a, b) {\n\t            switch (arguments.length) {\n\t            case 0:\n\t                return f2;\n\t            case 1:\n\t                return _isPlaceholder(a) ? f2 : _curry1(function (_b) {\n\t                    return fn(a, _b);\n\t                });\n\t            default:\n\t                return _isPlaceholder(a) && _isPlaceholder(b) ? f2 : _isPlaceholder(a) ? _curry1(function (_a) {\n\t                    return fn(_a, b);\n\t                }) : _isPlaceholder(b) ? _curry1(function (_b) {\n\t                    return fn(a, _b);\n\t                }) : fn(a, b);\n\t            }\n\t        };\n\t    };\n\n\t    /**\n\t     * Optimized internal three-arity curry function.\n\t     *\n\t     * @private\n\t     * @category Function\n\t     * @param {Function} fn The function to curry.\n\t     * @return {Function} The curried function.\n\t     */\n\t    var _curry3 = function _curry3(fn) {\n\t        return function f3(a, b, c) {\n\t            switch (arguments.length) {\n\t            case 0:\n\t                return f3;\n\t            case 1:\n\t                return _isPlaceholder(a) ? f3 : _curry2(function (_b, _c) {\n\t                    return fn(a, _b, _c);\n\t                });\n\t            case 2:\n\t                return _isPlaceholder(a) && _isPlaceholder(b) ? f3 : _isPlaceholder(a) ? _curry2(function (_a, _c) {\n\t                    return fn(_a, b, _c);\n\t                }) : _isPlaceholder(b) ? _curry2(function (_b, _c) {\n\t                    return fn(a, _b, _c);\n\t                }) : _curry1(function (_c) {\n\t                    return fn(a, b, _c);\n\t                });\n\t            default:\n\t                return _isPlaceholder(a) && _isPlaceholder(b) && _isPlaceholder(c) ? f3 : _isPlaceholder(a) && _isPlaceholder(b) ? _curry2(function (_a, _b) {\n\t                    return fn(_a, _b, c);\n\t                }) : _isPlaceholder(a) && _isPlaceholder(c) ? _curry2(function (_a, _c) {\n\t                    return fn(_a, b, _c);\n\t                }) : _isPlaceholder(b) && _isPlaceholder(c) ? _curry2(function (_b, _c) {\n\t                    return fn(a, _b, _c);\n\t                }) : _isPlaceholder(a) ? _curry1(function (_a) {\n\t                    return fn(_a, b, c);\n\t                }) : _isPlaceholder(b) ? _curry1(function (_b) {\n\t                    return fn(a, _b, c);\n\t                }) : _isPlaceholder(c) ? _curry1(function (_c) {\n\t                    return fn(a, b, _c);\n\t                }) : fn(a, b, c);\n\t            }\n\t        };\n\t    };\n\n\t    /**\n\t     * Internal curryN function.\n\t     *\n\t     * @private\n\t     * @category Function\n\t     * @param {Number} length The arity of the curried function.\n\t     * @param {Array} received An array of arguments received thus far.\n\t     * @param {Function} fn The function to curry.\n\t     * @return {Function} The curried function.\n\t     */\n\t    var _curryN = function _curryN(length, received, fn) {\n\t        return function () {\n\t            var combined = [];\n\t            var argsIdx = 0;\n\t            var left = length;\n\t            var combinedIdx = 0;\n\t            while (combinedIdx < received.length || argsIdx < arguments.length) {\n\t                var result;\n\t                if (combinedIdx < received.length && (!_isPlaceholder(received[combinedIdx]) || argsIdx >= arguments.length)) {\n\t                    result = received[combinedIdx];\n\t                } else {\n\t                    result = arguments[argsIdx];\n\t                    argsIdx += 1;\n\t                }\n\t                combined[combinedIdx] = result;\n\t                if (!_isPlaceholder(result)) {\n\t                    left -= 1;\n\t                }\n\t                combinedIdx += 1;\n\t            }\n\t            return left <= 0 ? fn.apply(this, combined) : _arity(left, _curryN(length, combined, fn));\n\t        };\n\t    };\n\n\t    /**\n\t     * Returns a function that dispatches with different strategies based on the\n\t     * object in list position (last argument). If it is an array, executes [fn].\n\t     * Otherwise, if it has a function with [methodname], it will execute that\n\t     * function (functor case). Otherwise, if it is a transformer, uses transducer\n\t     * [xf] to return a new transformer (transducer case). Otherwise, it will\n\t     * default to executing [fn].\n\t     *\n\t     * @private\n\t     * @param {String} methodname property to check for a custom implementation\n\t     * @param {Function} xf transducer to initialize if object is transformer\n\t     * @param {Function} fn default ramda implementation\n\t     * @return {Function} A function that dispatches on object in list position\n\t     */\n\t    var _dispatchable = function _dispatchable(methodname, xf, fn) {\n\t        return function () {\n\t            var length = arguments.length;\n\t            if (length === 0) {\n\t                return fn();\n\t            }\n\t            var obj = arguments[length - 1];\n\t            if (!_isArray(obj)) {\n\t                var args = _slice(arguments, 0, length - 1);\n\t                if (typeof obj[methodname] === 'function') {\n\t                    return obj[methodname].apply(obj, args);\n\t                }\n\t                if (_isTransformer(obj)) {\n\t                    var transducer = xf.apply(null, args);\n\t                    return transducer(obj);\n\t                }\n\t            }\n\t            return fn.apply(this, arguments);\n\t        };\n\t    };\n\n\t    var _dropLastWhile = function dropLastWhile(pred, list) {\n\t        var idx = list.length - 1;\n\t        while (idx >= 0 && pred(list[idx])) {\n\t            idx -= 1;\n\t        }\n\t        return _slice(list, 0, idx + 1);\n\t    };\n\n\t    var _xall = function () {\n\t        function XAll(f, xf) {\n\t            this.xf = xf;\n\t            this.f = f;\n\t            this.all = true;\n\t        }\n\t        XAll.prototype['@@transducer/init'] = _xfBase.init;\n\t        XAll.prototype['@@transducer/result'] = function (result) {\n\t            if (this.all) {\n\t                result = this.xf['@@transducer/step'](result, true);\n\t            }\n\t            return this.xf['@@transducer/result'](result);\n\t        };\n\t        XAll.prototype['@@transducer/step'] = function (result, input) {\n\t            if (!this.f(input)) {\n\t                this.all = false;\n\t                result = _reduced(this.xf['@@transducer/step'](result, false));\n\t            }\n\t            return result;\n\t        };\n\t        return _curry2(function _xall(f, xf) {\n\t            return new XAll(f, xf);\n\t        });\n\t    }();\n\n\t    var _xany = function () {\n\t        function XAny(f, xf) {\n\t            this.xf = xf;\n\t            this.f = f;\n\t            this.any = false;\n\t        }\n\t        XAny.prototype['@@transducer/init'] = _xfBase.init;\n\t        XAny.prototype['@@transducer/result'] = function (result) {\n\t            if (!this.any) {\n\t                result = this.xf['@@transducer/step'](result, false);\n\t            }\n\t            return this.xf['@@transducer/result'](result);\n\t        };\n\t        XAny.prototype['@@transducer/step'] = function (result, input) {\n\t            if (this.f(input)) {\n\t                this.any = true;\n\t                result = _reduced(this.xf['@@transducer/step'](result, true));\n\t            }\n\t            return result;\n\t        };\n\t        return _curry2(function _xany(f, xf) {\n\t            return new XAny(f, xf);\n\t        });\n\t    }();\n\n\t    var _xaperture = function () {\n\t        function XAperture(n, xf) {\n\t            this.xf = xf;\n\t            this.pos = 0;\n\t            this.full = false;\n\t            this.acc = new Array(n);\n\t        }\n\t        XAperture.prototype['@@transducer/init'] = _xfBase.init;\n\t        XAperture.prototype['@@transducer/result'] = function (result) {\n\t            this.acc = null;\n\t            return this.xf['@@transducer/result'](result);\n\t        };\n\t        XAperture.prototype['@@transducer/step'] = function (result, input) {\n\t            this.store(input);\n\t            return this.full ? this.xf['@@transducer/step'](result, this.getCopy()) : result;\n\t        };\n\t        XAperture.prototype.store = function (input) {\n\t            this.acc[this.pos] = input;\n\t            this.pos += 1;\n\t            if (this.pos === this.acc.length) {\n\t                this.pos = 0;\n\t                this.full = true;\n\t            }\n\t        };\n\t        XAperture.prototype.getCopy = function () {\n\t            return _concat(_slice(this.acc, this.pos), _slice(this.acc, 0, this.pos));\n\t        };\n\t        return _curry2(function _xaperture(n, xf) {\n\t            return new XAperture(n, xf);\n\t        });\n\t    }();\n\n\t    var _xdrop = function () {\n\t        function XDrop(n, xf) {\n\t            this.xf = xf;\n\t            this.n = n;\n\t        }\n\t        XDrop.prototype['@@transducer/init'] = _xfBase.init;\n\t        XDrop.prototype['@@transducer/result'] = _xfBase.result;\n\t        XDrop.prototype['@@transducer/step'] = function (result, input) {\n\t            if (this.n > 0) {\n\t                this.n -= 1;\n\t                return result;\n\t            }\n\t            return this.xf['@@transducer/step'](result, input);\n\t        };\n\t        return _curry2(function _xdrop(n, xf) {\n\t            return new XDrop(n, xf);\n\t        });\n\t    }();\n\n\t    var _xdropLast = function () {\n\t        function XDropLast(n, xf) {\n\t            this.xf = xf;\n\t            this.pos = 0;\n\t            this.full = false;\n\t            this.acc = new Array(n);\n\t        }\n\t        XDropLast.prototype['@@transducer/init'] = _xfBase.init;\n\t        XDropLast.prototype['@@transducer/result'] = function (result) {\n\t            this.acc = null;\n\t            return this.xf['@@transducer/result'](result);\n\t        };\n\t        XDropLast.prototype['@@transducer/step'] = function (result, input) {\n\t            if (this.full) {\n\t                result = this.xf['@@transducer/step'](result, this.acc[this.pos]);\n\t            }\n\t            this.store(input);\n\t            return result;\n\t        };\n\t        XDropLast.prototype.store = function (input) {\n\t            this.acc[this.pos] = input;\n\t            this.pos += 1;\n\t            if (this.pos === this.acc.length) {\n\t                this.pos = 0;\n\t                this.full = true;\n\t            }\n\t        };\n\t        return _curry2(function _xdropLast(n, xf) {\n\t            return new XDropLast(n, xf);\n\t        });\n\t    }();\n\n\t    var _xdropRepeatsWith = function () {\n\t        function XDropRepeatsWith(pred, xf) {\n\t            this.xf = xf;\n\t            this.pred = pred;\n\t            this.lastValue = undefined;\n\t            this.seenFirstValue = false;\n\t        }\n\t        XDropRepeatsWith.prototype['@@transducer/init'] = function () {\n\t            return this.xf['@@transducer/init']();\n\t        };\n\t        XDropRepeatsWith.prototype['@@transducer/result'] = function (result) {\n\t            return this.xf['@@transducer/result'](result);\n\t        };\n\t        XDropRepeatsWith.prototype['@@transducer/step'] = function (result, input) {\n\t            var sameAsLast = false;\n\t            if (!this.seenFirstValue) {\n\t                this.seenFirstValue = true;\n\t            } else if (this.pred(this.lastValue, input)) {\n\t                sameAsLast = true;\n\t            }\n\t            this.lastValue = input;\n\t            return sameAsLast ? result : this.xf['@@transducer/step'](result, input);\n\t        };\n\t        return _curry2(function _xdropRepeatsWith(pred, xf) {\n\t            return new XDropRepeatsWith(pred, xf);\n\t        });\n\t    }();\n\n\t    var _xdropWhile = function () {\n\t        function XDropWhile(f, xf) {\n\t            this.xf = xf;\n\t            this.f = f;\n\t        }\n\t        XDropWhile.prototype['@@transducer/init'] = _xfBase.init;\n\t        XDropWhile.prototype['@@transducer/result'] = _xfBase.result;\n\t        XDropWhile.prototype['@@transducer/step'] = function (result, input) {\n\t            if (this.f) {\n\t                if (this.f(input)) {\n\t                    return result;\n\t                }\n\t                this.f = null;\n\t            }\n\t            return this.xf['@@transducer/step'](result, input);\n\t        };\n\t        return _curry2(function _xdropWhile(f, xf) {\n\t            return new XDropWhile(f, xf);\n\t        });\n\t    }();\n\n\t    var _xfilter = function () {\n\t        function XFilter(f, xf) {\n\t            this.xf = xf;\n\t            this.f = f;\n\t        }\n\t        XFilter.prototype['@@transducer/init'] = _xfBase.init;\n\t        XFilter.prototype['@@transducer/result'] = _xfBase.result;\n\t        XFilter.prototype['@@transducer/step'] = function (result, input) {\n\t            return this.f(input) ? this.xf['@@transducer/step'](result, input) : result;\n\t        };\n\t        return _curry2(function _xfilter(f, xf) {\n\t            return new XFilter(f, xf);\n\t        });\n\t    }();\n\n\t    var _xfind = function () {\n\t        function XFind(f, xf) {\n\t            this.xf = xf;\n\t            this.f = f;\n\t            this.found = false;\n\t        }\n\t        XFind.prototype['@@transducer/init'] = _xfBase.init;\n\t        XFind.prototype['@@transducer/result'] = function (result) {\n\t            if (!this.found) {\n\t                result = this.xf['@@transducer/step'](result, void 0);\n\t            }\n\t            return this.xf['@@transducer/result'](result);\n\t        };\n\t        XFind.prototype['@@transducer/step'] = function (result, input) {\n\t            if (this.f(input)) {\n\t                this.found = true;\n\t                result = _reduced(this.xf['@@transducer/step'](result, input));\n\t            }\n\t            return result;\n\t        };\n\t        return _curry2(function _xfind(f, xf) {\n\t            return new XFind(f, xf);\n\t        });\n\t    }();\n\n\t    var _xfindIndex = function () {\n\t        function XFindIndex(f, xf) {\n\t            this.xf = xf;\n\t            this.f = f;\n\t            this.idx = -1;\n\t            this.found = false;\n\t        }\n\t        XFindIndex.prototype['@@transducer/init'] = _xfBase.init;\n\t        XFindIndex.prototype['@@transducer/result'] = function (result) {\n\t            if (!this.found) {\n\t                result = this.xf['@@transducer/step'](result, -1);\n\t            }\n\t            return this.xf['@@transducer/result'](result);\n\t        };\n\t        XFindIndex.prototype['@@transducer/step'] = function (result, input) {\n\t            this.idx += 1;\n\t            if (this.f(input)) {\n\t                this.found = true;\n\t                result = _reduced(this.xf['@@transducer/step'](result, this.idx));\n\t            }\n\t            return result;\n\t        };\n\t        return _curry2(function _xfindIndex(f, xf) {\n\t            return new XFindIndex(f, xf);\n\t        });\n\t    }();\n\n\t    var _xfindLast = function () {\n\t        function XFindLast(f, xf) {\n\t            this.xf = xf;\n\t            this.f = f;\n\t        }\n\t        XFindLast.prototype['@@transducer/init'] = _xfBase.init;\n\t        XFindLast.prototype['@@transducer/result'] = function (result) {\n\t            return this.xf['@@transducer/result'](this.xf['@@transducer/step'](result, this.last));\n\t        };\n\t        XFindLast.prototype['@@transducer/step'] = function (result, input) {\n\t            if (this.f(input)) {\n\t                this.last = input;\n\t            }\n\t            return result;\n\t        };\n\t        return _curry2(function _xfindLast(f, xf) {\n\t            return new XFindLast(f, xf);\n\t        });\n\t    }();\n\n\t    var _xfindLastIndex = function () {\n\t        function XFindLastIndex(f, xf) {\n\t            this.xf = xf;\n\t            this.f = f;\n\t            this.idx = -1;\n\t            this.lastIdx = -1;\n\t        }\n\t        XFindLastIndex.prototype['@@transducer/init'] = _xfBase.init;\n\t        XFindLastIndex.prototype['@@transducer/result'] = function (result) {\n\t            return this.xf['@@transducer/result'](this.xf['@@transducer/step'](result, this.lastIdx));\n\t        };\n\t        XFindLastIndex.prototype['@@transducer/step'] = function (result, input) {\n\t            this.idx += 1;\n\t            if (this.f(input)) {\n\t                this.lastIdx = this.idx;\n\t            }\n\t            return result;\n\t        };\n\t        return _curry2(function _xfindLastIndex(f, xf) {\n\t            return new XFindLastIndex(f, xf);\n\t        });\n\t    }();\n\n\t    var _xmap = function () {\n\t        function XMap(f, xf) {\n\t            this.xf = xf;\n\t            this.f = f;\n\t        }\n\t        XMap.prototype['@@transducer/init'] = _xfBase.init;\n\t        XMap.prototype['@@transducer/result'] = _xfBase.result;\n\t        XMap.prototype['@@transducer/step'] = function (result, input) {\n\t            return this.xf['@@transducer/step'](result, this.f(input));\n\t        };\n\t        return _curry2(function _xmap(f, xf) {\n\t            return new XMap(f, xf);\n\t        });\n\t    }();\n\n\t    var _xreduceBy = function () {\n\t        function XReduceBy(valueFn, valueAcc, keyFn, xf) {\n\t            this.valueFn = valueFn;\n\t            this.valueAcc = valueAcc;\n\t            this.keyFn = keyFn;\n\t            this.xf = xf;\n\t            this.inputs = {};\n\t        }\n\t        XReduceBy.prototype['@@transducer/init'] = _xfBase.init;\n\t        XReduceBy.prototype['@@transducer/result'] = function (result) {\n\t            var key;\n\t            for (key in this.inputs) {\n\t                if (_has(key, this.inputs)) {\n\t                    result = this.xf['@@transducer/step'](result, this.inputs[key]);\n\t                    if (result['@@transducer/reduced']) {\n\t                        result = result['@@transducer/value'];\n\t                        break;\n\t                    }\n\t                }\n\t            }\n\t            this.inputs = null;\n\t            return this.xf['@@transducer/result'](result);\n\t        };\n\t        XReduceBy.prototype['@@transducer/step'] = function (result, input) {\n\t            var key = this.keyFn(input);\n\t            this.inputs[key] = this.inputs[key] || [\n\t                key,\n\t                this.valueAcc\n\t            ];\n\t            this.inputs[key][1] = this.valueFn(this.inputs[key][1], input);\n\t            return result;\n\t        };\n\t        return _curryN(4, [], function _xreduceBy(valueFn, valueAcc, keyFn, xf) {\n\t            return new XReduceBy(valueFn, valueAcc, keyFn, xf);\n\t        });\n\t    }();\n\n\t    var _xtake = function () {\n\t        function XTake(n, xf) {\n\t            this.xf = xf;\n\t            this.n = n;\n\t            this.i = 0;\n\t        }\n\t        XTake.prototype['@@transducer/init'] = _xfBase.init;\n\t        XTake.prototype['@@transducer/result'] = _xfBase.result;\n\t        XTake.prototype['@@transducer/step'] = function (result, input) {\n\t            this.i += 1;\n\t            var ret = this.n === 0 ? result : this.xf['@@transducer/step'](result, input);\n\t            return this.i >= this.n ? _reduced(ret) : ret;\n\t        };\n\t        return _curry2(function _xtake(n, xf) {\n\t            return new XTake(n, xf);\n\t        });\n\t    }();\n\n\t    var _xtakeWhile = function () {\n\t        function XTakeWhile(f, xf) {\n\t            this.xf = xf;\n\t            this.f = f;\n\t        }\n\t        XTakeWhile.prototype['@@transducer/init'] = _xfBase.init;\n\t        XTakeWhile.prototype['@@transducer/result'] = _xfBase.result;\n\t        XTakeWhile.prototype['@@transducer/step'] = function (result, input) {\n\t            return this.f(input) ? this.xf['@@transducer/step'](result, input) : _reduced(result);\n\t        };\n\t        return _curry2(function _xtakeWhile(f, xf) {\n\t            return new XTakeWhile(f, xf);\n\t        });\n\t    }();\n\n\t    /**\n\t     * Adds two values.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Math\n\t     * @sig Number -> Number -> Number\n\t     * @param {Number} a\n\t     * @param {Number} b\n\t     * @return {Number}\n\t     * @see R.subtract\n\t     * @example\n\t     *\n\t     *      R.add(2, 3);       //=>  5\n\t     *      R.add(7)(10);      //=> 17\n\t     */\n\t    var add = _curry2(function add(a, b) {\n\t        return Number(a) + Number(b);\n\t    });\n\n\t    /**\n\t     * Applies a function to the value at the given index of an array, returning a\n\t     * new copy of the array with the element at the given index replaced with the\n\t     * result of the function application.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.14.0\n\t     * @category List\n\t     * @sig (a -> a) -> Number -> [a] -> [a]\n\t     * @param {Function} fn The function to apply.\n\t     * @param {Number} idx The index.\n\t     * @param {Array|Arguments} list An array-like object whose value\n\t     *        at the supplied index will be replaced.\n\t     * @return {Array} A copy of the supplied array-like object with\n\t     *         the element at index `idx` replaced with the value\n\t     *         returned by applying `fn` to the existing element.\n\t     * @see R.update\n\t     * @example\n\t     *\n\t     *      R.adjust(R.add(10), 1, [0, 1, 2]);     //=> [0, 11, 2]\n\t     *      R.adjust(R.add(10))(1)([0, 1, 2]);     //=> [0, 11, 2]\n\t     */\n\t    var adjust = _curry3(function adjust(fn, idx, list) {\n\t        if (idx >= list.length || idx < -list.length) {\n\t            return list;\n\t        }\n\t        var start = idx < 0 ? list.length : 0;\n\t        var _idx = start + idx;\n\t        var _list = _concat(list);\n\t        _list[_idx] = fn(list[_idx]);\n\t        return _list;\n\t    });\n\n\t    /**\n\t     * Returns `true` if all elements of the list match the predicate, `false` if\n\t     * there are any that don't.\n\t     *\n\t     * Dispatches to the `all` method of the second argument, if present.\n\t     *\n\t     * Acts as a transducer if a transformer is given in list position.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig (a -> Boolean) -> [a] -> Boolean\n\t     * @param {Function} fn The predicate function.\n\t     * @param {Array} list The array to consider.\n\t     * @return {Boolean} `true` if the predicate is satisfied by every element, `false`\n\t     *         otherwise.\n\t     * @see R.any, R.none, R.transduce\n\t     * @example\n\t     *\n\t     *      var lessThan2 = R.flip(R.lt)(2);\n\t     *      var lessThan3 = R.flip(R.lt)(3);\n\t     *      R.all(lessThan2)([1, 2]); //=> false\n\t     *      R.all(lessThan3)([1, 2]); //=> true\n\t     */\n\t    var all = _curry2(_dispatchable('all', _xall, function all(fn, list) {\n\t        var idx = 0;\n\t        while (idx < list.length) {\n\t            if (!fn(list[idx])) {\n\t                return false;\n\t            }\n\t            idx += 1;\n\t        }\n\t        return true;\n\t    }));\n\n\t    /**\n\t     * Returns a function that always returns the given value. Note that for\n\t     * non-primitives the value returned is a reference to the original value.\n\t     *\n\t     * This function is known as `const`, `constant`, or `K` (for K combinator) in\n\t     * other languages and libraries.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Function\n\t     * @sig a -> (* -> a)\n\t     * @param {*} val The value to wrap in a function\n\t     * @return {Function} A Function :: * -> val.\n\t     * @example\n\t     *\n\t     *      var t = R.always('Tee');\n\t     *      t(); //=> 'Tee'\n\t     */\n\t    var always = _curry1(function always(val) {\n\t        return function () {\n\t            return val;\n\t        };\n\t    });\n\n\t    /**\n\t     * Returns `true` if both arguments are `true`; `false` otherwise.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Logic\n\t     * @sig * -> * -> *\n\t     * @param {Boolean} a A boolean value\n\t     * @param {Boolean} b A boolean value\n\t     * @return {Boolean} `true` if both arguments are `true`, `false` otherwise\n\t     * @see R.both\n\t     * @example\n\t     *\n\t     *      R.and(true, true); //=> true\n\t     *      R.and(true, false); //=> false\n\t     *      R.and(false, true); //=> false\n\t     *      R.and(false, false); //=> false\n\t     */\n\t    var and = _curry2(function and(a, b) {\n\t        return a && b;\n\t    });\n\n\t    /**\n\t     * Returns `true` if at least one of elements of the list match the predicate,\n\t     * `false` otherwise.\n\t     *\n\t     * Dispatches to the `any` method of the second argument, if present.\n\t     *\n\t     * Acts as a transducer if a transformer is given in list position.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig (a -> Boolean) -> [a] -> Boolean\n\t     * @param {Function} fn The predicate function.\n\t     * @param {Array} list The array to consider.\n\t     * @return {Boolean} `true` if the predicate is satisfied by at least one element, `false`\n\t     *         otherwise.\n\t     * @see R.all, R.none, R.transduce\n\t     * @example\n\t     *\n\t     *      var lessThan0 = R.flip(R.lt)(0);\n\t     *      var lessThan2 = R.flip(R.lt)(2);\n\t     *      R.any(lessThan0)([1, 2]); //=> false\n\t     *      R.any(lessThan2)([1, 2]); //=> true\n\t     */\n\t    var any = _curry2(_dispatchable('any', _xany, function any(fn, list) {\n\t        var idx = 0;\n\t        while (idx < list.length) {\n\t            if (fn(list[idx])) {\n\t                return true;\n\t            }\n\t            idx += 1;\n\t        }\n\t        return false;\n\t    }));\n\n\t    /**\n\t     * Returns a new list, composed of n-tuples of consecutive elements If `n` is\n\t     * greater than the length of the list, an empty list is returned.\n\t     *\n\t     * Dispatches to the `aperture` method of the second argument, if present.\n\t     *\n\t     * Acts as a transducer if a transformer is given in list position.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.12.0\n\t     * @category List\n\t     * @sig Number -> [a] -> [[a]]\n\t     * @param {Number} n The size of the tuples to create\n\t     * @param {Array} list The list to split into `n`-tuples\n\t     * @return {Array} The new list.\n\t     * @see R.transduce\n\t     * @example\n\t     *\n\t     *      R.aperture(2, [1, 2, 3, 4, 5]); //=> [[1, 2], [2, 3], [3, 4], [4, 5]]\n\t     *      R.aperture(3, [1, 2, 3, 4, 5]); //=> [[1, 2, 3], [2, 3, 4], [3, 4, 5]]\n\t     *      R.aperture(7, [1, 2, 3, 4, 5]); //=> []\n\t     */\n\t    var aperture = _curry2(_dispatchable('aperture', _xaperture, _aperture));\n\n\t    /**\n\t     * Returns a new list containing the contents of the given list, followed by\n\t     * the given element.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig a -> [a] -> [a]\n\t     * @param {*} el The element to add to the end of the new list.\n\t     * @param {Array} list The list whose contents will be added to the beginning of the output\n\t     *        list.\n\t     * @return {Array} A new list containing the contents of the old list followed by `el`.\n\t     * @see R.prepend\n\t     * @example\n\t     *\n\t     *      R.append('tests', ['write', 'more']); //=> ['write', 'more', 'tests']\n\t     *      R.append('tests', []); //=> ['tests']\n\t     *      R.append(['tests'], ['write', 'more']); //=> ['write', 'more', ['tests']]\n\t     */\n\t    var append = _curry2(function append(el, list) {\n\t        return _concat(list, [el]);\n\t    });\n\n\t    /**\n\t     * Applies function `fn` to the argument list `args`. This is useful for\n\t     * creating a fixed-arity function from a variadic function. `fn` should be a\n\t     * bound function if context is significant.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.7.0\n\t     * @category Function\n\t     * @sig (*... -> a) -> [*] -> a\n\t     * @param {Function} fn\n\t     * @param {Array} args\n\t     * @return {*}\n\t     * @see R.call, R.unapply\n\t     * @example\n\t     *\n\t     *      var nums = [1, 2, 3, -99, 42, 6, 7];\n\t     *      R.apply(Math.max, nums); //=> 42\n\t     */\n\t    var apply = _curry2(function apply(fn, args) {\n\t        return fn.apply(this, args);\n\t    });\n\n\t    /**\n\t     * Makes a shallow clone of an object, setting or overriding the specified\n\t     * property with the given value. Note that this copies and flattens prototype\n\t     * properties onto the new object as well. All non-primitive properties are\n\t     * copied by reference.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.8.0\n\t     * @category Object\n\t     * @sig String -> a -> {k: v} -> {k: v}\n\t     * @param {String} prop the property name to set\n\t     * @param {*} val the new value\n\t     * @param {Object} obj the object to clone\n\t     * @return {Object} a new object similar to the original except for the specified property.\n\t     * @see R.dissoc\n\t     * @example\n\t     *\n\t     *      R.assoc('c', 3, {a: 1, b: 2}); //=> {a: 1, b: 2, c: 3}\n\t     */\n\t    var assoc = _curry3(function assoc(prop, val, obj) {\n\t        var result = {};\n\t        for (var p in obj) {\n\t            result[p] = obj[p];\n\t        }\n\t        result[prop] = val;\n\t        return result;\n\t    });\n\n\t    /**\n\t     * Makes a shallow clone of an object, setting or overriding the nodes required\n\t     * to create the given path, and placing the specific value at the tail end of\n\t     * that path. Note that this copies and flattens prototype properties onto the\n\t     * new object as well. All non-primitive properties are copied by reference.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.8.0\n\t     * @category Object\n\t     * @sig [String] -> a -> {k: v} -> {k: v}\n\t     * @param {Array} path the path to set\n\t     * @param {*} val the new value\n\t     * @param {Object} obj the object to clone\n\t     * @return {Object} a new object similar to the original except along the specified path.\n\t     * @see R.dissocPath\n\t     * @example\n\t     *\n\t     *      R.assocPath(['a', 'b', 'c'], 42, {a: {b: {c: 0}}}); //=> {a: {b: {c: 42}}}\n\t     */\n\t    var assocPath = _curry3(function assocPath(path, val, obj) {\n\t        switch (path.length) {\n\t        case 0:\n\t            return val;\n\t        case 1:\n\t            return assoc(path[0], val, obj);\n\t        default:\n\t            return assoc(path[0], assocPath(_slice(path, 1), val, Object(obj[path[0]])), obj);\n\t        }\n\t    });\n\n\t    /**\n\t     * Creates a function that is bound to a context.\n\t     * Note: `R.bind` does not provide the additional argument-binding capabilities of\n\t     * [Function.prototype.bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind).\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.6.0\n\t     * @category Function\n\t     * @category Object\n\t     * @sig (* -> *) -> {*} -> (* -> *)\n\t     * @param {Function} fn The function to bind to context\n\t     * @param {Object} thisObj The context to bind `fn` to\n\t     * @return {Function} A function that will execute in the context of `thisObj`.\n\t     * @see R.partial\n\t     * @example\n\t     *\n\t     *      var log = R.bind(console.log, console);\n\t     *      R.pipe(R.assoc('a', 2), R.tap(log), R.assoc('a', 3))({a: 1}); //=> {a: 3}\n\t     *      // logs {a: 2}\n\t     */\n\t    var bind = _curry2(function bind(fn, thisObj) {\n\t        return _arity(fn.length, function () {\n\t            return fn.apply(thisObj, arguments);\n\t        });\n\t    });\n\n\t    /**\n\t     * Restricts a number to be within a range.\n\t     *\n\t     * Also works for other ordered types such as Strings and Dates.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.20.0\n\t     * @category Relation\n\t     * @sig Ord a => a -> a -> a -> a\n\t     * @param {Number} minimum number\n\t     * @param {Number} maximum number\n\t     * @param {Number} value to be clamped\n\t     * @return {Number} Returns the clamped value\n\t     * @example\n\t     *\n\t     *      R.clamp(1, 10, -1) // => 1\n\t     *      R.clamp(1, 10, 11) // => 10\n\t     *      R.clamp(1, 10, 4)  // => 4\n\t     */\n\t    var clamp = _curry3(function clamp(min, max, value) {\n\t        if (min > max) {\n\t            throw new Error('min must not be greater than max in clamp(min, max, value)');\n\t        }\n\t        return value < min ? min : value > max ? max : value;\n\t    });\n\n\t    /**\n\t     * Makes a comparator function out of a function that reports whether the first\n\t     * element is less than the second.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Function\n\t     * @sig (a, b -> Boolean) -> (a, b -> Number)\n\t     * @param {Function} pred A predicate function of arity two.\n\t     * @return {Function} A Function :: a -> b -> Int that returns `-1` if a < b, `1` if b < a, otherwise `0`.\n\t     * @example\n\t     *\n\t     *      var cmp = R.comparator((a, b) => a.age < b.age);\n\t     *      var people = [\n\t     *        // ...\n\t     *      ];\n\t     *      R.sort(cmp, people);\n\t     */\n\t    var comparator = _curry1(function comparator(pred) {\n\t        return function (a, b) {\n\t            return pred(a, b) ? -1 : pred(b, a) ? 1 : 0;\n\t        };\n\t    });\n\n\t    /**\n\t     * Returns a curried equivalent of the provided function, with the specified\n\t     * arity. The curried function has two unusual capabilities. First, its\n\t     * arguments needn't be provided one at a time. If `g` is `R.curryN(3, f)`, the\n\t     * following are equivalent:\n\t     *\n\t     *   - `g(1)(2)(3)`\n\t     *   - `g(1)(2, 3)`\n\t     *   - `g(1, 2)(3)`\n\t     *   - `g(1, 2, 3)`\n\t     *\n\t     * Secondly, the special placeholder value `R.__` may be used to specify\n\t     * \"gaps\", allowing partial application of any combination of arguments,\n\t     * regardless of their positions. If `g` is as above and `_` is `R.__`, the\n\t     * following are equivalent:\n\t     *\n\t     *   - `g(1, 2, 3)`\n\t     *   - `g(_, 2, 3)(1)`\n\t     *   - `g(_, _, 3)(1)(2)`\n\t     *   - `g(_, _, 3)(1, 2)`\n\t     *   - `g(_, 2)(1)(3)`\n\t     *   - `g(_, 2)(1, 3)`\n\t     *   - `g(_, 2)(_, 3)(1)`\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.5.0\n\t     * @category Function\n\t     * @sig Number -> (* -> a) -> (* -> a)\n\t     * @param {Number} length The arity for the returned function.\n\t     * @param {Function} fn The function to curry.\n\t     * @return {Function} A new, curried function.\n\t     * @see R.curry\n\t     * @example\n\t     *\n\t     *      var sumArgs = (...args) => R.sum(args);\n\t     *\n\t     *      var curriedAddFourNumbers = R.curryN(4, sumArgs);\n\t     *      var f = curriedAddFourNumbers(1, 2);\n\t     *      var g = f(3);\n\t     *      g(4); //=> 10\n\t     */\n\t    var curryN = _curry2(function curryN(length, fn) {\n\t        if (length === 1) {\n\t            return _curry1(fn);\n\t        }\n\t        return _arity(length, _curryN(length, [], fn));\n\t    });\n\n\t    /**\n\t     * Decrements its argument.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.9.0\n\t     * @category Math\n\t     * @sig Number -> Number\n\t     * @param {Number} n\n\t     * @return {Number}\n\t     * @see R.inc\n\t     * @example\n\t     *\n\t     *      R.dec(42); //=> 41\n\t     */\n\t    var dec = add(-1);\n\n\t    /**\n\t     * Returns the second argument if it is not `null`, `undefined` or `NaN`\n\t     * otherwise the first argument is returned.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.10.0\n\t     * @category Logic\n\t     * @sig a -> b -> a | b\n\t     * @param {a} val The default value.\n\t     * @param {b} val The value to return if it is not null or undefined\n\t     * @return {*} The the second value or the default value\n\t     * @example\n\t     *\n\t     *      var defaultTo42 = R.defaultTo(42);\n\t     *\n\t     *      defaultTo42(null);  //=> 42\n\t     *      defaultTo42(undefined);  //=> 42\n\t     *      defaultTo42('Ramda');  //=> 'Ramda'\n\t     *      defaultTo42(parseInt('string')); //=> 42\n\t     */\n\t    var defaultTo = _curry2(function defaultTo(d, v) {\n\t        return v == null || v !== v ? d : v;\n\t    });\n\n\t    /**\n\t     * Finds the set (i.e. no duplicates) of all elements in the first list not\n\t     * contained in the second list. Duplication is determined according to the\n\t     * value returned by applying the supplied predicate to two list elements.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Relation\n\t     * @sig (a -> a -> Boolean) -> [*] -> [*] -> [*]\n\t     * @param {Function} pred A predicate used to test whether two items are equal.\n\t     * @param {Array} list1 The first list.\n\t     * @param {Array} list2 The second list.\n\t     * @return {Array} The elements in `list1` that are not in `list2`.\n\t     * @see R.difference, R.symmetricDifference, R.symmetricDifferenceWith\n\t     * @example\n\t     *\n\t     *      var cmp = (x, y) => x.a === y.a;\n\t     *      var l1 = [{a: 1}, {a: 2}, {a: 3}];\n\t     *      var l2 = [{a: 3}, {a: 4}];\n\t     *      R.differenceWith(cmp, l1, l2); //=> [{a: 1}, {a: 2}]\n\t     */\n\t    var differenceWith = _curry3(function differenceWith(pred, first, second) {\n\t        var out = [];\n\t        var idx = 0;\n\t        var firstLen = first.length;\n\t        while (idx < firstLen) {\n\t            if (!_containsWith(pred, first[idx], second) && !_containsWith(pred, first[idx], out)) {\n\t                out.push(first[idx]);\n\t            }\n\t            idx += 1;\n\t        }\n\t        return out;\n\t    });\n\n\t    /**\n\t     * Returns a new object that does not contain a `prop` property.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.10.0\n\t     * @category Object\n\t     * @sig String -> {k: v} -> {k: v}\n\t     * @param {String} prop the name of the property to dissociate\n\t     * @param {Object} obj the object to clone\n\t     * @return {Object} a new object similar to the original but without the specified property\n\t     * @see R.assoc\n\t     * @example\n\t     *\n\t     *      R.dissoc('b', {a: 1, b: 2, c: 3}); //=> {a: 1, c: 3}\n\t     */\n\t    var dissoc = _curry2(function dissoc(prop, obj) {\n\t        var result = {};\n\t        for (var p in obj) {\n\t            if (p !== prop) {\n\t                result[p] = obj[p];\n\t            }\n\t        }\n\t        return result;\n\t    });\n\n\t    /**\n\t     * Makes a shallow clone of an object, omitting the property at the given path.\n\t     * Note that this copies and flattens prototype properties onto the new object\n\t     * as well. All non-primitive properties are copied by reference.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.11.0\n\t     * @category Object\n\t     * @sig [String] -> {k: v} -> {k: v}\n\t     * @param {Array} path the path to set\n\t     * @param {Object} obj the object to clone\n\t     * @return {Object} a new object without the property at path\n\t     * @see R.assocPath\n\t     * @example\n\t     *\n\t     *      R.dissocPath(['a', 'b', 'c'], {a: {b: {c: 42}}}); //=> {a: {b: {}}}\n\t     */\n\t    var dissocPath = _curry2(function dissocPath(path, obj) {\n\t        switch (path.length) {\n\t        case 0:\n\t            return obj;\n\t        case 1:\n\t            return dissoc(path[0], obj);\n\t        default:\n\t            var head = path[0];\n\t            var tail = _slice(path, 1);\n\t            return obj[head] == null ? obj : assoc(head, dissocPath(tail, obj[head]), obj);\n\t        }\n\t    });\n\n\t    /**\n\t     * Divides two numbers. Equivalent to `a / b`.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Math\n\t     * @sig Number -> Number -> Number\n\t     * @param {Number} a The first value.\n\t     * @param {Number} b The second value.\n\t     * @return {Number} The result of `a / b`.\n\t     * @see R.multiply\n\t     * @example\n\t     *\n\t     *      R.divide(71, 100); //=> 0.71\n\t     *\n\t     *      var half = R.divide(R.__, 2);\n\t     *      half(42); //=> 21\n\t     *\n\t     *      var reciprocal = R.divide(1);\n\t     *      reciprocal(4);   //=> 0.25\n\t     */\n\t    var divide = _curry2(function divide(a, b) {\n\t        return a / b;\n\t    });\n\n\t    /**\n\t     * Returns a new list excluding the leading elements of a given list which\n\t     * satisfy the supplied predicate function. It passes each value to the supplied\n\t     * predicate function, skipping elements while the predicate function returns\n\t     * `true`. The predicate function is applied to one argument: *(value)*.\n\t     *\n\t     * Dispatches to the `dropWhile` method of the second argument, if present.\n\t     *\n\t     * Acts as a transducer if a transformer is given in list position.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.9.0\n\t     * @category List\n\t     * @sig (a -> Boolean) -> [a] -> [a]\n\t     * @param {Function} fn The function called per iteration.\n\t     * @param {Array} list The collection to iterate over.\n\t     * @return {Array} A new array.\n\t     * @see R.takeWhile, R.transduce, R.addIndex\n\t     * @example\n\t     *\n\t     *      var lteTwo = x => x <= 2;\n\t     *\n\t     *      R.dropWhile(lteTwo, [1, 2, 3, 4, 3, 2, 1]); //=> [3, 4, 3, 2, 1]\n\t     */\n\t    var dropWhile = _curry2(_dispatchable('dropWhile', _xdropWhile, function dropWhile(pred, list) {\n\t        var idx = 0;\n\t        var len = list.length;\n\t        while (idx < len && pred(list[idx])) {\n\t            idx += 1;\n\t        }\n\t        return _slice(list, idx);\n\t    }));\n\n\t    /**\n\t     * Returns the empty value of its argument's type. Ramda defines the empty\n\t     * value of Array (`[]`), Object (`{}`), String (`''`), and Arguments. Other\n\t     * types are supported if they define `<Type>.empty` and/or\n\t     * `<Type>.prototype.empty`.\n\t     *\n\t     * Dispatches to the `empty` method of the first argument, if present.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.3.0\n\t     * @category Function\n\t     * @sig a -> a\n\t     * @param {*} x\n\t     * @return {*}\n\t     * @example\n\t     *\n\t     *      R.empty(Just(42));      //=> Nothing()\n\t     *      R.empty([1, 2, 3]);     //=> []\n\t     *      R.empty('unicorns');    //=> ''\n\t     *      R.empty({x: 1, y: 2});  //=> {}\n\t     */\n\t    // else\n\t    var empty = _curry1(function empty(x) {\n\t        return x != null && typeof x.empty === 'function' ? x.empty() : x != null && x.constructor != null && typeof x.constructor.empty === 'function' ? x.constructor.empty() : _isArray(x) ? [] : _isString(x) ? '' : _isObject(x) ? {} : _isArguments(x) ? function () {\n\t            return arguments;\n\t        }() : // else\n\t        void 0;\n\t    });\n\n\t    /**\n\t     * Creates a new object by recursively evolving a shallow copy of `object`,\n\t     * according to the `transformation` functions. All non-primitive properties\n\t     * are copied by reference.\n\t     *\n\t     * A `transformation` function will not be invoked if its corresponding key\n\t     * does not exist in the evolved object.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.9.0\n\t     * @category Object\n\t     * @sig {k: (v -> v)} -> {k: v} -> {k: v}\n\t     * @param {Object} transformations The object specifying transformation functions to apply\n\t     *        to the object.\n\t     * @param {Object} object The object to be transformed.\n\t     * @return {Object} The transformed object.\n\t     * @example\n\t     *\n\t     *      var tomato  = {firstName: '  Tomato ', data: {elapsed: 100, remaining: 1400}, id:123};\n\t     *      var transformations = {\n\t     *        firstName: R.trim,\n\t     *        lastName: R.trim, // Will not get invoked.\n\t     *        data: {elapsed: R.add(1), remaining: R.add(-1)}\n\t     *      };\n\t     *      R.evolve(transformations, tomato); //=> {firstName: 'Tomato', data: {elapsed: 101, remaining: 1399}, id:123}\n\t     */\n\t    var evolve = _curry2(function evolve(transformations, object) {\n\t        var result = {};\n\t        var transformation, key, type;\n\t        for (key in object) {\n\t            transformation = transformations[key];\n\t            type = typeof transformation;\n\t            result[key] = type === 'function' ? transformation(object[key]) : type === 'object' ? evolve(transformations[key], object[key]) : object[key];\n\t        }\n\t        return result;\n\t    });\n\n\t    /**\n\t     * Returns the first element of the list which matches the predicate, or\n\t     * `undefined` if no element matches.\n\t     *\n\t     * Dispatches to the `find` method of the second argument, if present.\n\t     *\n\t     * Acts as a transducer if a transformer is given in list position.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig (a -> Boolean) -> [a] -> a | undefined\n\t     * @param {Function} fn The predicate function used to determine if the element is the\n\t     *        desired one.\n\t     * @param {Array} list The array to consider.\n\t     * @return {Object} The element found, or `undefined`.\n\t     * @see R.transduce\n\t     * @example\n\t     *\n\t     *      var xs = [{a: 1}, {a: 2}, {a: 3}];\n\t     *      R.find(R.propEq('a', 2))(xs); //=> {a: 2}\n\t     *      R.find(R.propEq('a', 4))(xs); //=> undefined\n\t     */\n\t    var find = _curry2(_dispatchable('find', _xfind, function find(fn, list) {\n\t        var idx = 0;\n\t        var len = list.length;\n\t        while (idx < len) {\n\t            if (fn(list[idx])) {\n\t                return list[idx];\n\t            }\n\t            idx += 1;\n\t        }\n\t    }));\n\n\t    /**\n\t     * Returns the index of the first element of the list which matches the\n\t     * predicate, or `-1` if no element matches.\n\t     *\n\t     * Dispatches to the `findIndex` method of the second argument, if present.\n\t     *\n\t     * Acts as a transducer if a transformer is given in list position.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.1\n\t     * @category List\n\t     * @sig (a -> Boolean) -> [a] -> Number\n\t     * @param {Function} fn The predicate function used to determine if the element is the\n\t     * desired one.\n\t     * @param {Array} list The array to consider.\n\t     * @return {Number} The index of the element found, or `-1`.\n\t     * @see R.transduce\n\t     * @example\n\t     *\n\t     *      var xs = [{a: 1}, {a: 2}, {a: 3}];\n\t     *      R.findIndex(R.propEq('a', 2))(xs); //=> 1\n\t     *      R.findIndex(R.propEq('a', 4))(xs); //=> -1\n\t     */\n\t    var findIndex = _curry2(_dispatchable('findIndex', _xfindIndex, function findIndex(fn, list) {\n\t        var idx = 0;\n\t        var len = list.length;\n\t        while (idx < len) {\n\t            if (fn(list[idx])) {\n\t                return idx;\n\t            }\n\t            idx += 1;\n\t        }\n\t        return -1;\n\t    }));\n\n\t    /**\n\t     * Returns the last element of the list which matches the predicate, or\n\t     * `undefined` if no element matches.\n\t     *\n\t     * Dispatches to the `findLast` method of the second argument, if present.\n\t     *\n\t     * Acts as a transducer if a transformer is given in list position.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.1\n\t     * @category List\n\t     * @sig (a -> Boolean) -> [a] -> a | undefined\n\t     * @param {Function} fn The predicate function used to determine if the element is the\n\t     * desired one.\n\t     * @param {Array} list The array to consider.\n\t     * @return {Object} The element found, or `undefined`.\n\t     * @see R.transduce\n\t     * @example\n\t     *\n\t     *      var xs = [{a: 1, b: 0}, {a:1, b: 1}];\n\t     *      R.findLast(R.propEq('a', 1))(xs); //=> {a: 1, b: 1}\n\t     *      R.findLast(R.propEq('a', 4))(xs); //=> undefined\n\t     */\n\t    var findLast = _curry2(_dispatchable('findLast', _xfindLast, function findLast(fn, list) {\n\t        var idx = list.length - 1;\n\t        while (idx >= 0) {\n\t            if (fn(list[idx])) {\n\t                return list[idx];\n\t            }\n\t            idx -= 1;\n\t        }\n\t    }));\n\n\t    /**\n\t     * Returns the index of the last element of the list which matches the\n\t     * predicate, or `-1` if no element matches.\n\t     *\n\t     * Dispatches to the `findLastIndex` method of the second argument, if present.\n\t     *\n\t     * Acts as a transducer if a transformer is given in list position.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.1\n\t     * @category List\n\t     * @sig (a -> Boolean) -> [a] -> Number\n\t     * @param {Function} fn The predicate function used to determine if the element is the\n\t     * desired one.\n\t     * @param {Array} list The array to consider.\n\t     * @return {Number} The index of the element found, or `-1`.\n\t     * @see R.transduce\n\t     * @example\n\t     *\n\t     *      var xs = [{a: 1, b: 0}, {a:1, b: 1}];\n\t     *      R.findLastIndex(R.propEq('a', 1))(xs); //=> 1\n\t     *      R.findLastIndex(R.propEq('a', 4))(xs); //=> -1\n\t     */\n\t    var findLastIndex = _curry2(_dispatchable('findLastIndex', _xfindLastIndex, function findLastIndex(fn, list) {\n\t        var idx = list.length - 1;\n\t        while (idx >= 0) {\n\t            if (fn(list[idx])) {\n\t                return idx;\n\t            }\n\t            idx -= 1;\n\t        }\n\t        return -1;\n\t    }));\n\n\t    /**\n\t     * Iterate over an input `list`, calling a provided function `fn` for each\n\t     * element in the list.\n\t     *\n\t     * `fn` receives one argument: *(value)*.\n\t     *\n\t     * Note: `R.forEach` does not skip deleted or unassigned indices (sparse\n\t     * arrays), unlike the native `Array.prototype.forEach` method. For more\n\t     * details on this behavior, see:\n\t     * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Description\n\t     *\n\t     * Also note that, unlike `Array.prototype.forEach`, Ramda's `forEach` returns\n\t     * the original array. In some libraries this function is named `each`.\n\t     *\n\t     * Dispatches to the `forEach` method of the second argument, if present.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.1\n\t     * @category List\n\t     * @sig (a -> *) -> [a] -> [a]\n\t     * @param {Function} fn The function to invoke. Receives one argument, `value`.\n\t     * @param {Array} list The list to iterate over.\n\t     * @return {Array} The original list.\n\t     * @see R.addIndex\n\t     * @example\n\t     *\n\t     *      var printXPlusFive = x => console.log(x + 5);\n\t     *      R.forEach(printXPlusFive, [1, 2, 3]); //=> [1, 2, 3]\n\t     *      // logs 6\n\t     *      // logs 7\n\t     *      // logs 8\n\t     */\n\t    var forEach = _curry2(_checkForMethod('forEach', function forEach(fn, list) {\n\t        var len = list.length;\n\t        var idx = 0;\n\t        while (idx < len) {\n\t            fn(list[idx]);\n\t            idx += 1;\n\t        }\n\t        return list;\n\t    }));\n\n\t    /**\n\t     * Creates a new object from a list key-value pairs. If a key appears in\n\t     * multiple pairs, the rightmost pair is included in the object.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.3.0\n\t     * @category List\n\t     * @sig [[k,v]] -> {k: v}\n\t     * @param {Array} pairs An array of two-element arrays that will be the keys and values of the output object.\n\t     * @return {Object} The object made by pairing up `keys` and `values`.\n\t     * @see R.toPairs, R.pair\n\t     * @example\n\t     *\n\t     *      R.fromPairs([['a', 1], ['b', 2], ['c', 3]]); //=> {a: 1, b: 2, c: 3}\n\t     */\n\t    var fromPairs = _curry1(function fromPairs(pairs) {\n\t        var result = {};\n\t        var idx = 0;\n\t        while (idx < pairs.length) {\n\t            result[pairs[idx][0]] = pairs[idx][1];\n\t            idx += 1;\n\t        }\n\t        return result;\n\t    });\n\n\t    /**\n\t     * Takes a list and returns a list of lists where each sublist's elements are\n\t     * all \"equal\" according to the provided equality function.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.21.0\n\t     * @category List\n\t     * @sig ((a, a) → Boolean) → [a] → [[a]]\n\t     * @param {Function} fn Function for determining whether two given (adjacent)\n\t     *        elements should be in the same group\n\t     * @param {Array} list The array to group. Also accepts a string, which will be\n\t     *        treated as a list of characters.\n\t     * @return {List} A list that contains sublists of equal elements,\n\t     *         whose concatenations are equal to the original list.\n\t     * @example\n\t     *\n\t     * R.groupWith(R.equals, [0, 1, 1, 2, 3, 5, 8, 13, 21])\n\t     * //=> [[0], [1, 1], [2], [3], [5], [8], [13], [21]]\n\t     *\n\t     * R.groupWith((a, b) => a % 2 === b % 2, [0, 1, 1, 2, 3, 5, 8, 13, 21])\n\t     * //=> [[0], [1, 1], [2], [3, 5], [8], [13, 21]]\n\t     *\n\t     * R.groupWith(R.eqBy(isVowel), 'aestiou')\n\t     * //=> ['ae', 'st', 'iou']\n\t     */\n\t    var groupWith = _curry2(function (fn, list) {\n\t        var res = [];\n\t        var idx = 0;\n\t        var len = list.length;\n\t        while (idx < len) {\n\t            var nextidx = idx + 1;\n\t            while (nextidx < len && fn(list[idx], list[nextidx])) {\n\t                nextidx += 1;\n\t            }\n\t            res.push(list.slice(idx, nextidx));\n\t            idx = nextidx;\n\t        }\n\t        return res;\n\t    });\n\n\t    /**\n\t     * Returns `true` if the first argument is greater than the second; `false`\n\t     * otherwise.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Relation\n\t     * @sig Ord a => a -> a -> Boolean\n\t     * @param {*} a\n\t     * @param {*} b\n\t     * @return {Boolean}\n\t     * @see R.lt\n\t     * @example\n\t     *\n\t     *      R.gt(2, 1); //=> true\n\t     *      R.gt(2, 2); //=> false\n\t     *      R.gt(2, 3); //=> false\n\t     *      R.gt('a', 'z'); //=> false\n\t     *      R.gt('z', 'a'); //=> true\n\t     */\n\t    var gt = _curry2(function gt(a, b) {\n\t        return a > b;\n\t    });\n\n\t    /**\n\t     * Returns `true` if the first argument is greater than or equal to the second;\n\t     * `false` otherwise.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Relation\n\t     * @sig Ord a => a -> a -> Boolean\n\t     * @param {Number} a\n\t     * @param {Number} b\n\t     * @return {Boolean}\n\t     * @see R.lte\n\t     * @example\n\t     *\n\t     *      R.gte(2, 1); //=> true\n\t     *      R.gte(2, 2); //=> true\n\t     *      R.gte(2, 3); //=> false\n\t     *      R.gte('a', 'z'); //=> false\n\t     *      R.gte('z', 'a'); //=> true\n\t     */\n\t    var gte = _curry2(function gte(a, b) {\n\t        return a >= b;\n\t    });\n\n\t    /**\n\t     * Returns whether or not an object has an own property with the specified name\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.7.0\n\t     * @category Object\n\t     * @sig s -> {s: x} -> Boolean\n\t     * @param {String} prop The name of the property to check for.\n\t     * @param {Object} obj The object to query.\n\t     * @return {Boolean} Whether the property exists.\n\t     * @example\n\t     *\n\t     *      var hasName = R.has('name');\n\t     *      hasName({name: 'alice'});   //=> true\n\t     *      hasName({name: 'bob'});     //=> true\n\t     *      hasName({});                //=> false\n\t     *\n\t     *      var point = {x: 0, y: 0};\n\t     *      var pointHas = R.has(R.__, point);\n\t     *      pointHas('x');  //=> true\n\t     *      pointHas('y');  //=> true\n\t     *      pointHas('z');  //=> false\n\t     */\n\t    var has = _curry2(_has);\n\n\t    /**\n\t     * Returns whether or not an object or its prototype chain has a property with\n\t     * the specified name\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.7.0\n\t     * @category Object\n\t     * @sig s -> {s: x} -> Boolean\n\t     * @param {String} prop The name of the property to check for.\n\t     * @param {Object} obj The object to query.\n\t     * @return {Boolean} Whether the property exists.\n\t     * @example\n\t     *\n\t     *      function Rectangle(width, height) {\n\t     *        this.width = width;\n\t     *        this.height = height;\n\t     *      }\n\t     *      Rectangle.prototype.area = function() {\n\t     *        return this.width * this.height;\n\t     *      };\n\t     *\n\t     *      var square = new Rectangle(2, 2);\n\t     *      R.hasIn('width', square);  //=> true\n\t     *      R.hasIn('area', square);  //=> true\n\t     */\n\t    var hasIn = _curry2(function hasIn(prop, obj) {\n\t        return prop in obj;\n\t    });\n\n\t    /**\n\t     * Returns true if its arguments are identical, false otherwise. Values are\n\t     * identical if they reference the same memory. `NaN` is identical to `NaN`;\n\t     * `0` and `-0` are not identical.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.15.0\n\t     * @category Relation\n\t     * @sig a -> a -> Boolean\n\t     * @param {*} a\n\t     * @param {*} b\n\t     * @return {Boolean}\n\t     * @example\n\t     *\n\t     *      var o = {};\n\t     *      R.identical(o, o); //=> true\n\t     *      R.identical(1, 1); //=> true\n\t     *      R.identical(1, '1'); //=> false\n\t     *      R.identical([], []); //=> false\n\t     *      R.identical(0, -0); //=> false\n\t     *      R.identical(NaN, NaN); //=> true\n\t     */\n\t    // SameValue algorithm\n\t    // Steps 1-5, 7-10\n\t    // Steps 6.b-6.e: +0 != -0\n\t    // Step 6.a: NaN == NaN\n\t    var identical = _curry2(function identical(a, b) {\n\t        // SameValue algorithm\n\t        if (a === b) {\n\t            // Steps 1-5, 7-10\n\t            // Steps 6.b-6.e: +0 != -0\n\t            return a !== 0 || 1 / a === 1 / b;\n\t        } else {\n\t            // Step 6.a: NaN == NaN\n\t            return a !== a && b !== b;\n\t        }\n\t    });\n\n\t    /**\n\t     * A function that does nothing but return the parameter supplied to it. Good\n\t     * as a default or placeholder function.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Function\n\t     * @sig a -> a\n\t     * @param {*} x The value to return.\n\t     * @return {*} The input value, `x`.\n\t     * @example\n\t     *\n\t     *      R.identity(1); //=> 1\n\t     *\n\t     *      var obj = {};\n\t     *      R.identity(obj) === obj; //=> true\n\t     */\n\t    var identity = _curry1(_identity);\n\n\t    /**\n\t     * Creates a function that will process either the `onTrue` or the `onFalse`\n\t     * function depending upon the result of the `condition` predicate.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.8.0\n\t     * @category Logic\n\t     * @sig (*... -> Boolean) -> (*... -> *) -> (*... -> *) -> (*... -> *)\n\t     * @param {Function} condition A predicate function\n\t     * @param {Function} onTrue A function to invoke when the `condition` evaluates to a truthy value.\n\t     * @param {Function} onFalse A function to invoke when the `condition` evaluates to a falsy value.\n\t     * @return {Function} A new unary function that will process either the `onTrue` or the `onFalse`\n\t     *                    function depending upon the result of the `condition` predicate.\n\t     * @see R.unless, R.when\n\t     * @example\n\t     *\n\t     *      var incCount = R.ifElse(\n\t     *        R.has('count'),\n\t     *        R.over(R.lensProp('count'), R.inc),\n\t     *        R.assoc('count', 1)\n\t     *      );\n\t     *      incCount({});           //=> { count: 1 }\n\t     *      incCount({ count: 1 }); //=> { count: 2 }\n\t     */\n\t    var ifElse = _curry3(function ifElse(condition, onTrue, onFalse) {\n\t        return curryN(Math.max(condition.length, onTrue.length, onFalse.length), function _ifElse() {\n\t            return condition.apply(this, arguments) ? onTrue.apply(this, arguments) : onFalse.apply(this, arguments);\n\t        });\n\t    });\n\n\t    /**\n\t     * Increments its argument.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.9.0\n\t     * @category Math\n\t     * @sig Number -> Number\n\t     * @param {Number} n\n\t     * @return {Number}\n\t     * @see R.dec\n\t     * @example\n\t     *\n\t     *      R.inc(42); //=> 43\n\t     */\n\t    var inc = add(1);\n\n\t    /**\n\t     * Inserts the supplied element into the list, at index `index`. _Note that\n\t     * this is not destructive_: it returns a copy of the list with the changes.\n\t     * <small>No lists have been harmed in the application of this function.</small>\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.2.2\n\t     * @category List\n\t     * @sig Number -> a -> [a] -> [a]\n\t     * @param {Number} index The position to insert the element\n\t     * @param {*} elt The element to insert into the Array\n\t     * @param {Array} list The list to insert into\n\t     * @return {Array} A new Array with `elt` inserted at `index`.\n\t     * @example\n\t     *\n\t     *      R.insert(2, 'x', [1,2,3,4]); //=> [1,2,'x',3,4]\n\t     */\n\t    var insert = _curry3(function insert(idx, elt, list) {\n\t        idx = idx < list.length && idx >= 0 ? idx : list.length;\n\t        var result = _slice(list);\n\t        result.splice(idx, 0, elt);\n\t        return result;\n\t    });\n\n\t    /**\n\t     * Inserts the sub-list into the list, at index `index`. _Note that this is not\n\t     * destructive_: it returns a copy of the list with the changes.\n\t     * <small>No lists have been harmed in the application of this function.</small>\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.9.0\n\t     * @category List\n\t     * @sig Number -> [a] -> [a] -> [a]\n\t     * @param {Number} index The position to insert the sub-list\n\t     * @param {Array} elts The sub-list to insert into the Array\n\t     * @param {Array} list The list to insert the sub-list into\n\t     * @return {Array} A new Array with `elts` inserted starting at `index`.\n\t     * @example\n\t     *\n\t     *      R.insertAll(2, ['x','y','z'], [1,2,3,4]); //=> [1,2,'x','y','z',3,4]\n\t     */\n\t    var insertAll = _curry3(function insertAll(idx, elts, list) {\n\t        idx = idx < list.length && idx >= 0 ? idx : list.length;\n\t        return _concat(_concat(_slice(list, 0, idx), elts), _slice(list, idx));\n\t    });\n\n\t    /**\n\t     * Creates a new list with the separator interposed between elements.\n\t     *\n\t     * Dispatches to the `intersperse` method of the second argument, if present.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.14.0\n\t     * @category List\n\t     * @sig a -> [a] -> [a]\n\t     * @param {*} separator The element to add to the list.\n\t     * @param {Array} list The list to be interposed.\n\t     * @return {Array} The new list.\n\t     * @example\n\t     *\n\t     *      R.intersperse('n', ['ba', 'a', 'a']); //=> ['ba', 'n', 'a', 'n', 'a']\n\t     */\n\t    var intersperse = _curry2(_checkForMethod('intersperse', function intersperse(separator, list) {\n\t        var out = [];\n\t        var idx = 0;\n\t        var length = list.length;\n\t        while (idx < length) {\n\t            if (idx === length - 1) {\n\t                out.push(list[idx]);\n\t            } else {\n\t                out.push(list[idx], separator);\n\t            }\n\t            idx += 1;\n\t        }\n\t        return out;\n\t    }));\n\n\t    /**\n\t     * See if an object (`val`) is an instance of the supplied constructor. This\n\t     * function will check up the inheritance chain, if any.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.3.0\n\t     * @category Type\n\t     * @sig (* -> {*}) -> a -> Boolean\n\t     * @param {Object} ctor A constructor\n\t     * @param {*} val The value to test\n\t     * @return {Boolean}\n\t     * @example\n\t     *\n\t     *      R.is(Object, {}); //=> true\n\t     *      R.is(Number, 1); //=> true\n\t     *      R.is(Object, 1); //=> false\n\t     *      R.is(String, 's'); //=> true\n\t     *      R.is(String, new String('')); //=> true\n\t     *      R.is(Object, new String('')); //=> true\n\t     *      R.is(Object, 's'); //=> false\n\t     *      R.is(Number, {}); //=> false\n\t     */\n\t    var is = _curry2(function is(Ctor, val) {\n\t        return val != null && val.constructor === Ctor || val instanceof Ctor;\n\t    });\n\n\t    /**\n\t     * Tests whether or not an object is similar to an array.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.5.0\n\t     * @category Type\n\t     * @category List\n\t     * @sig * -> Boolean\n\t     * @param {*} x The object to test.\n\t     * @return {Boolean} `true` if `x` has a numeric length property and extreme indices defined; `false` otherwise.\n\t     * @example\n\t     *\n\t     *      R.isArrayLike([]); //=> true\n\t     *      R.isArrayLike(true); //=> false\n\t     *      R.isArrayLike({}); //=> false\n\t     *      R.isArrayLike({length: 10}); //=> false\n\t     *      R.isArrayLike({0: 'zero', 9: 'nine', length: 10}); //=> true\n\t     */\n\t    var isArrayLike = _curry1(function isArrayLike(x) {\n\t        if (_isArray(x)) {\n\t            return true;\n\t        }\n\t        if (!x) {\n\t            return false;\n\t        }\n\t        if (typeof x !== 'object') {\n\t            return false;\n\t        }\n\t        if (_isString(x)) {\n\t            return false;\n\t        }\n\t        if (x.nodeType === 1) {\n\t            return !!x.length;\n\t        }\n\t        if (x.length === 0) {\n\t            return true;\n\t        }\n\t        if (x.length > 0) {\n\t            return x.hasOwnProperty(0) && x.hasOwnProperty(x.length - 1);\n\t        }\n\t        return false;\n\t    });\n\n\t    /**\n\t     * Checks if the input value is `null` or `undefined`.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.9.0\n\t     * @category Type\n\t     * @sig * -> Boolean\n\t     * @param {*} x The value to test.\n\t     * @return {Boolean} `true` if `x` is `undefined` or `null`, otherwise `false`.\n\t     * @example\n\t     *\n\t     *      R.isNil(null); //=> true\n\t     *      R.isNil(undefined); //=> true\n\t     *      R.isNil(0); //=> false\n\t     *      R.isNil([]); //=> false\n\t     */\n\t    var isNil = _curry1(function isNil(x) {\n\t        return x == null;\n\t    });\n\n\t    /**\n\t     * Returns a list containing the names of all the enumerable own properties of\n\t     * the supplied object.\n\t     * Note that the order of the output array is not guaranteed to be consistent\n\t     * across different JS platforms.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Object\n\t     * @sig {k: v} -> [k]\n\t     * @param {Object} obj The object to extract properties from\n\t     * @return {Array} An array of the object's own properties.\n\t     * @example\n\t     *\n\t     *      R.keys({a: 1, b: 2, c: 3}); //=> ['a', 'b', 'c']\n\t     */\n\t    // cover IE < 9 keys issues\n\t    // Safari bug\n\t    var keys = function () {\n\t        // cover IE < 9 keys issues\n\t        var hasEnumBug = !{ toString: null }.propertyIsEnumerable('toString');\n\t        var nonEnumerableProps = [\n\t            'constructor',\n\t            'valueOf',\n\t            'isPrototypeOf',\n\t            'toString',\n\t            'propertyIsEnumerable',\n\t            'hasOwnProperty',\n\t            'toLocaleString'\n\t        ];\n\t        // Safari bug\n\t        var hasArgsEnumBug = function () {\n\t            'use strict';\n\t            return arguments.propertyIsEnumerable('length');\n\t        }();\n\t        var contains = function contains(list, item) {\n\t            var idx = 0;\n\t            while (idx < list.length) {\n\t                if (list[idx] === item) {\n\t                    return true;\n\t                }\n\t                idx += 1;\n\t            }\n\t            return false;\n\t        };\n\t        return typeof Object.keys === 'function' && !hasArgsEnumBug ? _curry1(function keys(obj) {\n\t            return Object(obj) !== obj ? [] : Object.keys(obj);\n\t        }) : _curry1(function keys(obj) {\n\t            if (Object(obj) !== obj) {\n\t                return [];\n\t            }\n\t            var prop, nIdx;\n\t            var ks = [];\n\t            var checkArgsLength = hasArgsEnumBug && _isArguments(obj);\n\t            for (prop in obj) {\n\t                if (_has(prop, obj) && (!checkArgsLength || prop !== 'length')) {\n\t                    ks[ks.length] = prop;\n\t                }\n\t            }\n\t            if (hasEnumBug) {\n\t                nIdx = nonEnumerableProps.length - 1;\n\t                while (nIdx >= 0) {\n\t                    prop = nonEnumerableProps[nIdx];\n\t                    if (_has(prop, obj) && !contains(ks, prop)) {\n\t                        ks[ks.length] = prop;\n\t                    }\n\t                    nIdx -= 1;\n\t                }\n\t            }\n\t            return ks;\n\t        });\n\t    }();\n\n\t    /**\n\t     * Returns a list containing the names of all the properties of the supplied\n\t     * object, including prototype properties.\n\t     * Note that the order of the output array is not guaranteed to be consistent\n\t     * across different JS platforms.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.2.0\n\t     * @category Object\n\t     * @sig {k: v} -> [k]\n\t     * @param {Object} obj The object to extract properties from\n\t     * @return {Array} An array of the object's own and prototype properties.\n\t     * @example\n\t     *\n\t     *      var F = function() { this.x = 'X'; };\n\t     *      F.prototype.y = 'Y';\n\t     *      var f = new F();\n\t     *      R.keysIn(f); //=> ['x', 'y']\n\t     */\n\t    var keysIn = _curry1(function keysIn(obj) {\n\t        var prop;\n\t        var ks = [];\n\t        for (prop in obj) {\n\t            ks[ks.length] = prop;\n\t        }\n\t        return ks;\n\t    });\n\n\t    /**\n\t     * Returns the number of elements in the array by returning `list.length`.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.3.0\n\t     * @category List\n\t     * @sig [a] -> Number\n\t     * @param {Array} list The array to inspect.\n\t     * @return {Number} The length of the array.\n\t     * @example\n\t     *\n\t     *      R.length([]); //=> 0\n\t     *      R.length([1, 2, 3]); //=> 3\n\t     */\n\t    var length = _curry1(function length(list) {\n\t        return list != null && _isNumber(list.length) ? list.length : NaN;\n\t    });\n\n\t    /**\n\t     * Returns `true` if the first argument is less than the second; `false`\n\t     * otherwise.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Relation\n\t     * @sig Ord a => a -> a -> Boolean\n\t     * @param {*} a\n\t     * @param {*} b\n\t     * @return {Boolean}\n\t     * @see R.gt\n\t     * @example\n\t     *\n\t     *      R.lt(2, 1); //=> false\n\t     *      R.lt(2, 2); //=> false\n\t     *      R.lt(2, 3); //=> true\n\t     *      R.lt('a', 'z'); //=> true\n\t     *      R.lt('z', 'a'); //=> false\n\t     */\n\t    var lt = _curry2(function lt(a, b) {\n\t        return a < b;\n\t    });\n\n\t    /**\n\t     * Returns `true` if the first argument is less than or equal to the second;\n\t     * `false` otherwise.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Relation\n\t     * @sig Ord a => a -> a -> Boolean\n\t     * @param {Number} a\n\t     * @param {Number} b\n\t     * @return {Boolean}\n\t     * @see R.gte\n\t     * @example\n\t     *\n\t     *      R.lte(2, 1); //=> false\n\t     *      R.lte(2, 2); //=> true\n\t     *      R.lte(2, 3); //=> true\n\t     *      R.lte('a', 'z'); //=> true\n\t     *      R.lte('z', 'a'); //=> false\n\t     */\n\t    var lte = _curry2(function lte(a, b) {\n\t        return a <= b;\n\t    });\n\n\t    /**\n\t     * The mapAccum function behaves like a combination of map and reduce; it\n\t     * applies a function to each element of a list, passing an accumulating\n\t     * parameter from left to right, and returning a final value of this\n\t     * accumulator together with the new list.\n\t     *\n\t     * The iterator function receives two arguments, *acc* and *value*, and should\n\t     * return a tuple *[acc, value]*.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.10.0\n\t     * @category List\n\t     * @sig (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])\n\t     * @param {Function} fn The function to be called on every element of the input `list`.\n\t     * @param {*} acc The accumulator value.\n\t     * @param {Array} list The list to iterate over.\n\t     * @return {*} The final, accumulated value.\n\t     * @see R.addIndex\n\t     * @example\n\t     *\n\t     *      var digits = ['1', '2', '3', '4'];\n\t     *      var appender = (a, b) => [a + b, a + b];\n\t     *\n\t     *      R.mapAccum(appender, 0, digits); //=> ['01234', ['01', '012', '0123', '01234']]\n\t     */\n\t    var mapAccum = _curry3(function mapAccum(fn, acc, list) {\n\t        var idx = 0;\n\t        var len = list.length;\n\t        var result = [];\n\t        var tuple = [acc];\n\t        while (idx < len) {\n\t            tuple = fn(tuple[0], list[idx]);\n\t            result[idx] = tuple[1];\n\t            idx += 1;\n\t        }\n\t        return [\n\t            tuple[0],\n\t            result\n\t        ];\n\t    });\n\n\t    /**\n\t     * The mapAccumRight function behaves like a combination of map and reduce; it\n\t     * applies a function to each element of a list, passing an accumulating\n\t     * parameter from right to left, and returning a final value of this\n\t     * accumulator together with the new list.\n\t     *\n\t     * Similar to `mapAccum`, except moves through the input list from the right to\n\t     * the left.\n\t     *\n\t     * The iterator function receives two arguments, *acc* and *value*, and should\n\t     * return a tuple *[acc, value]*.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.10.0\n\t     * @category List\n\t     * @sig (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])\n\t     * @param {Function} fn The function to be called on every element of the input `list`.\n\t     * @param {*} acc The accumulator value.\n\t     * @param {Array} list The list to iterate over.\n\t     * @return {*} The final, accumulated value.\n\t     * @see R.addIndex\n\t     * @example\n\t     *\n\t     *      var digits = ['1', '2', '3', '4'];\n\t     *      var append = (a, b) => [a + b, a + b];\n\t     *\n\t     *      R.mapAccumRight(append, 0, digits); //=> ['04321', ['04321', '0432', '043', '04']]\n\t     */\n\t    var mapAccumRight = _curry3(function mapAccumRight(fn, acc, list) {\n\t        var idx = list.length - 1;\n\t        var result = [];\n\t        var tuple = [acc];\n\t        while (idx >= 0) {\n\t            tuple = fn(tuple[0], list[idx]);\n\t            result[idx] = tuple[1];\n\t            idx -= 1;\n\t        }\n\t        return [\n\t            tuple[0],\n\t            result\n\t        ];\n\t    });\n\n\t    /**\n\t     * Tests a regular expression against a String. Note that this function will\n\t     * return an empty array when there are no matches. This differs from\n\t     * [`String.prototype.match`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match)\n\t     * which returns `null` when there are no matches.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category String\n\t     * @sig RegExp -> String -> [String | Undefined]\n\t     * @param {RegExp} rx A regular expression.\n\t     * @param {String} str The string to match against\n\t     * @return {Array} The list of matches or empty array.\n\t     * @see R.test\n\t     * @example\n\t     *\n\t     *      R.match(/([a-z]a)/g, 'bananas'); //=> ['ba', 'na', 'na']\n\t     *      R.match(/a/, 'b'); //=> []\n\t     *      R.match(/a/, null); //=> TypeError: null does not have a method named \"match\"\n\t     */\n\t    var match = _curry2(function match(rx, str) {\n\t        return str.match(rx) || [];\n\t    });\n\n\t    /**\n\t     * mathMod behaves like the modulo operator should mathematically, unlike the\n\t     * `%` operator (and by extension, R.modulo). So while \"-17 % 5\" is -2,\n\t     * mathMod(-17, 5) is 3. mathMod requires Integer arguments, and returns NaN\n\t     * when the modulus is zero or negative.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.3.0\n\t     * @category Math\n\t     * @sig Number -> Number -> Number\n\t     * @param {Number} m The dividend.\n\t     * @param {Number} p the modulus.\n\t     * @return {Number} The result of `b mod a`.\n\t     * @example\n\t     *\n\t     *      R.mathMod(-17, 5);  //=> 3\n\t     *      R.mathMod(17, 5);   //=> 2\n\t     *      R.mathMod(17, -5);  //=> NaN\n\t     *      R.mathMod(17, 0);   //=> NaN\n\t     *      R.mathMod(17.2, 5); //=> NaN\n\t     *      R.mathMod(17, 5.3); //=> NaN\n\t     *\n\t     *      var clock = R.mathMod(R.__, 12);\n\t     *      clock(15); //=> 3\n\t     *      clock(24); //=> 0\n\t     *\n\t     *      var seventeenMod = R.mathMod(17);\n\t     *      seventeenMod(3);  //=> 2\n\t     *      seventeenMod(4);  //=> 1\n\t     *      seventeenMod(10); //=> 7\n\t     */\n\t    var mathMod = _curry2(function mathMod(m, p) {\n\t        if (!_isInteger(m)) {\n\t            return NaN;\n\t        }\n\t        if (!_isInteger(p) || p < 1) {\n\t            return NaN;\n\t        }\n\t        return (m % p + p) % p;\n\t    });\n\n\t    /**\n\t     * Returns the larger of its two arguments.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Relation\n\t     * @sig Ord a => a -> a -> a\n\t     * @param {*} a\n\t     * @param {*} b\n\t     * @return {*}\n\t     * @see R.maxBy, R.min\n\t     * @example\n\t     *\n\t     *      R.max(789, 123); //=> 789\n\t     *      R.max('a', 'b'); //=> 'b'\n\t     */\n\t    var max = _curry2(function max(a, b) {\n\t        return b > a ? b : a;\n\t    });\n\n\t    /**\n\t     * Takes a function and two values, and returns whichever value produces the\n\t     * larger result when passed to the provided function.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.8.0\n\t     * @category Relation\n\t     * @sig Ord b => (a -> b) -> a -> a -> a\n\t     * @param {Function} f\n\t     * @param {*} a\n\t     * @param {*} b\n\t     * @return {*}\n\t     * @see R.max, R.minBy\n\t     * @example\n\t     *\n\t     *      //  square :: Number -> Number\n\t     *      var square = n => n * n;\n\t     *\n\t     *      R.maxBy(square, -3, 2); //=> -3\n\t     *\n\t     *      R.reduce(R.maxBy(square), 0, [3, -5, 4, 1, -2]); //=> -5\n\t     *      R.reduce(R.maxBy(square), 0, []); //=> 0\n\t     */\n\t    var maxBy = _curry3(function maxBy(f, a, b) {\n\t        return f(b) > f(a) ? b : a;\n\t    });\n\n\t    /**\n\t     * Create a new object with the own properties of the first object merged with\n\t     * the own properties of the second object. If a key exists in both objects,\n\t     * the value from the second object will be used.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Object\n\t     * @sig {k: v} -> {k: v} -> {k: v}\n\t     * @param {Object} l\n\t     * @param {Object} r\n\t     * @return {Object}\n\t     * @see R.mergeWith, R.mergeWithKey\n\t     * @example\n\t     *\n\t     *      R.merge({ 'name': 'fred', 'age': 10 }, { 'age': 40 });\n\t     *      //=> { 'name': 'fred', 'age': 40 }\n\t     *\n\t     *      var resetToDefault = R.merge(R.__, {x: 0});\n\t     *      resetToDefault({x: 5, y: 2}); //=> {x: 0, y: 2}\n\t     */\n\t    var merge = _curry2(function merge(l, r) {\n\t        return _assign({}, l, r);\n\t    });\n\n\t    /**\n\t     * Merges a list of objects together into one object.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.10.0\n\t     * @category List\n\t     * @sig [{k: v}] -> {k: v}\n\t     * @param {Array} list An array of objects\n\t     * @return {Object} A merged object.\n\t     * @see R.reduce\n\t     * @example\n\t     *\n\t     *      R.mergeAll([{foo:1},{bar:2},{baz:3}]); //=> {foo:1,bar:2,baz:3}\n\t     *      R.mergeAll([{foo:1},{foo:2},{bar:2}]); //=> {foo:2,bar:2}\n\t     */\n\t    var mergeAll = _curry1(function mergeAll(list) {\n\t        return _assign.apply(null, [{}].concat(list));\n\t    });\n\n\t    /**\n\t     * Creates a new object with the own properties of the two provided objects. If\n\t     * a key exists in both objects, the provided function is applied to the key\n\t     * and the values associated with the key in each object, with the result being\n\t     * used as the value associated with the key in the returned object. The key\n\t     * will be excluded from the returned object if the resulting value is\n\t     * `undefined`.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.19.0\n\t     * @category Object\n\t     * @sig (String -> a -> a -> a) -> {a} -> {a} -> {a}\n\t     * @param {Function} fn\n\t     * @param {Object} l\n\t     * @param {Object} r\n\t     * @return {Object}\n\t     * @see R.merge, R.mergeWith\n\t     * @example\n\t     *\n\t     *      let concatValues = (k, l, r) => k == 'values' ? R.concat(l, r) : r\n\t     *      R.mergeWithKey(concatValues,\n\t     *                     { a: true, thing: 'foo', values: [10, 20] },\n\t     *                     { b: true, thing: 'bar', values: [15, 35] });\n\t     *      //=> { a: true, b: true, thing: 'bar', values: [10, 20, 15, 35] }\n\t     */\n\t    var mergeWithKey = _curry3(function mergeWithKey(fn, l, r) {\n\t        var result = {};\n\t        var k;\n\t        for (k in l) {\n\t            if (_has(k, l)) {\n\t                result[k] = _has(k, r) ? fn(k, l[k], r[k]) : l[k];\n\t            }\n\t        }\n\t        for (k in r) {\n\t            if (_has(k, r) && !_has(k, result)) {\n\t                result[k] = r[k];\n\t            }\n\t        }\n\t        return result;\n\t    });\n\n\t    /**\n\t     * Returns the smaller of its two arguments.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Relation\n\t     * @sig Ord a => a -> a -> a\n\t     * @param {*} a\n\t     * @param {*} b\n\t     * @return {*}\n\t     * @see R.minBy, R.max\n\t     * @example\n\t     *\n\t     *      R.min(789, 123); //=> 123\n\t     *      R.min('a', 'b'); //=> 'a'\n\t     */\n\t    var min = _curry2(function min(a, b) {\n\t        return b < a ? b : a;\n\t    });\n\n\t    /**\n\t     * Takes a function and two values, and returns whichever value produces the\n\t     * smaller result when passed to the provided function.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.8.0\n\t     * @category Relation\n\t     * @sig Ord b => (a -> b) -> a -> a -> a\n\t     * @param {Function} f\n\t     * @param {*} a\n\t     * @param {*} b\n\t     * @return {*}\n\t     * @see R.min, R.maxBy\n\t     * @example\n\t     *\n\t     *      //  square :: Number -> Number\n\t     *      var square = n => n * n;\n\t     *\n\t     *      R.minBy(square, -3, 2); //=> 2\n\t     *\n\t     *      R.reduce(R.minBy(square), Infinity, [3, -5, 4, 1, -2]); //=> 1\n\t     *      R.reduce(R.minBy(square), Infinity, []); //=> Infinity\n\t     */\n\t    var minBy = _curry3(function minBy(f, a, b) {\n\t        return f(b) < f(a) ? b : a;\n\t    });\n\n\t    /**\n\t     * Divides the first parameter by the second and returns the remainder. Note\n\t     * that this function preserves the JavaScript-style behavior for modulo. For\n\t     * mathematical modulo see `mathMod`.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.1\n\t     * @category Math\n\t     * @sig Number -> Number -> Number\n\t     * @param {Number} a The value to the divide.\n\t     * @param {Number} b The pseudo-modulus\n\t     * @return {Number} The result of `b % a`.\n\t     * @see R.mathMod\n\t     * @example\n\t     *\n\t     *      R.modulo(17, 3); //=> 2\n\t     *      // JS behavior:\n\t     *      R.modulo(-17, 3); //=> -2\n\t     *      R.modulo(17, -3); //=> 2\n\t     *\n\t     *      var isOdd = R.modulo(R.__, 2);\n\t     *      isOdd(42); //=> 0\n\t     *      isOdd(21); //=> 1\n\t     */\n\t    var modulo = _curry2(function modulo(a, b) {\n\t        return a % b;\n\t    });\n\n\t    /**\n\t     * Multiplies two numbers. Equivalent to `a * b` but curried.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Math\n\t     * @sig Number -> Number -> Number\n\t     * @param {Number} a The first value.\n\t     * @param {Number} b The second value.\n\t     * @return {Number} The result of `a * b`.\n\t     * @see R.divide\n\t     * @example\n\t     *\n\t     *      var double = R.multiply(2);\n\t     *      var triple = R.multiply(3);\n\t     *      double(3);       //=>  6\n\t     *      triple(4);       //=> 12\n\t     *      R.multiply(2, 5);  //=> 10\n\t     */\n\t    var multiply = _curry2(function multiply(a, b) {\n\t        return a * b;\n\t    });\n\n\t    /**\n\t     * Wraps a function of any arity (including nullary) in a function that accepts\n\t     * exactly `n` parameters. Any extraneous parameters will not be passed to the\n\t     * supplied function.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Function\n\t     * @sig Number -> (* -> a) -> (* -> a)\n\t     * @param {Number} n The desired arity of the new function.\n\t     * @param {Function} fn The function to wrap.\n\t     * @return {Function} A new function wrapping `fn`. The new function is guaranteed to be of\n\t     *         arity `n`.\n\t     * @example\n\t     *\n\t     *      var takesTwoArgs = (a, b) => [a, b];\n\t     *\n\t     *      takesTwoArgs.length; //=> 2\n\t     *      takesTwoArgs(1, 2); //=> [1, 2]\n\t     *\n\t     *      var takesOneArg = R.nAry(1, takesTwoArgs);\n\t     *      takesOneArg.length; //=> 1\n\t     *      // Only `n` arguments are passed to the wrapped function\n\t     *      takesOneArg(1, 2); //=> [1, undefined]\n\t     */\n\t    var nAry = _curry2(function nAry(n, fn) {\n\t        switch (n) {\n\t        case 0:\n\t            return function () {\n\t                return fn.call(this);\n\t            };\n\t        case 1:\n\t            return function (a0) {\n\t                return fn.call(this, a0);\n\t            };\n\t        case 2:\n\t            return function (a0, a1) {\n\t                return fn.call(this, a0, a1);\n\t            };\n\t        case 3:\n\t            return function (a0, a1, a2) {\n\t                return fn.call(this, a0, a1, a2);\n\t            };\n\t        case 4:\n\t            return function (a0, a1, a2, a3) {\n\t                return fn.call(this, a0, a1, a2, a3);\n\t            };\n\t        case 5:\n\t            return function (a0, a1, a2, a3, a4) {\n\t                return fn.call(this, a0, a1, a2, a3, a4);\n\t            };\n\t        case 6:\n\t            return function (a0, a1, a2, a3, a4, a5) {\n\t                return fn.call(this, a0, a1, a2, a3, a4, a5);\n\t            };\n\t        case 7:\n\t            return function (a0, a1, a2, a3, a4, a5, a6) {\n\t                return fn.call(this, a0, a1, a2, a3, a4, a5, a6);\n\t            };\n\t        case 8:\n\t            return function (a0, a1, a2, a3, a4, a5, a6, a7) {\n\t                return fn.call(this, a0, a1, a2, a3, a4, a5, a6, a7);\n\t            };\n\t        case 9:\n\t            return function (a0, a1, a2, a3, a4, a5, a6, a7, a8) {\n\t                return fn.call(this, a0, a1, a2, a3, a4, a5, a6, a7, a8);\n\t            };\n\t        case 10:\n\t            return function (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {\n\t                return fn.call(this, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);\n\t            };\n\t        default:\n\t            throw new Error('First argument to nAry must be a non-negative integer no greater than ten');\n\t        }\n\t    });\n\n\t    /**\n\t     * Negates its argument.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.9.0\n\t     * @category Math\n\t     * @sig Number -> Number\n\t     * @param {Number} n\n\t     * @return {Number}\n\t     * @example\n\t     *\n\t     *      R.negate(42); //=> -42\n\t     */\n\t    var negate = _curry1(function negate(n) {\n\t        return -n;\n\t    });\n\n\t    /**\n\t     * Returns `true` if no elements of the list match the predicate, `false`\n\t     * otherwise.\n\t     *\n\t     * Dispatches to the `any` method of the second argument, if present.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.12.0\n\t     * @category List\n\t     * @sig (a -> Boolean) -> [a] -> Boolean\n\t     * @param {Function} fn The predicate function.\n\t     * @param {Array} list The array to consider.\n\t     * @return {Boolean} `true` if the predicate is not satisfied by every element, `false` otherwise.\n\t     * @see R.all, R.any\n\t     * @example\n\t     *\n\t     *      var isEven = n => n % 2 === 0;\n\t     *\n\t     *      R.none(isEven, [1, 3, 5, 7, 9, 11]); //=> true\n\t     *      R.none(isEven, [1, 3, 5, 7, 8, 11]); //=> false\n\t     */\n\t    var none = _curry2(_complement(_dispatchable('any', _xany, any)));\n\n\t    /**\n\t     * A function that returns the `!` of its argument. It will return `true` when\n\t     * passed false-y value, and `false` when passed a truth-y one.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Logic\n\t     * @sig * -> Boolean\n\t     * @param {*} a any value\n\t     * @return {Boolean} the logical inverse of passed argument.\n\t     * @see R.complement\n\t     * @example\n\t     *\n\t     *      R.not(true); //=> false\n\t     *      R.not(false); //=> true\n\t     *      R.not(0); //=> true\n\t     *      R.not(1); //=> false\n\t     */\n\t    var not = _curry1(function not(a) {\n\t        return !a;\n\t    });\n\n\t    /**\n\t     * Returns the nth element of the given list or string. If n is negative the\n\t     * element at index length + n is returned.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig Number -> [a] -> a | Undefined\n\t     * @sig Number -> String -> String\n\t     * @param {Number} offset\n\t     * @param {*} list\n\t     * @return {*}\n\t     * @example\n\t     *\n\t     *      var list = ['foo', 'bar', 'baz', 'quux'];\n\t     *      R.nth(1, list); //=> 'bar'\n\t     *      R.nth(-1, list); //=> 'quux'\n\t     *      R.nth(-99, list); //=> undefined\n\t     *\n\t     *      R.nth(2, 'abc'); //=> 'c'\n\t     *      R.nth(3, 'abc'); //=> ''\n\t     */\n\t    var nth = _curry2(function nth(offset, list) {\n\t        var idx = offset < 0 ? list.length + offset : offset;\n\t        return _isString(list) ? list.charAt(idx) : list[idx];\n\t    });\n\n\t    /**\n\t     * Returns a function which returns its nth argument.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.9.0\n\t     * @category Function\n\t     * @sig Number -> *... -> *\n\t     * @param {Number} n\n\t     * @return {Function}\n\t     * @example\n\t     *\n\t     *      R.nthArg(1)('a', 'b', 'c'); //=> 'b'\n\t     *      R.nthArg(-1)('a', 'b', 'c'); //=> 'c'\n\t     */\n\t    var nthArg = _curry1(function nthArg(n) {\n\t        var arity = n < 0 ? 1 : n + 1;\n\t        return curryN(arity, function () {\n\t            return nth(n, arguments);\n\t        });\n\t    });\n\n\t    /**\n\t     * Creates an object containing a single key:value pair.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.18.0\n\t     * @category Object\n\t     * @sig String -> a -> {String:a}\n\t     * @param {String} key\n\t     * @param {*} val\n\t     * @return {Object}\n\t     * @see R.pair\n\t     * @example\n\t     *\n\t     *      var matchPhrases = R.compose(\n\t     *        R.objOf('must'),\n\t     *        R.map(R.objOf('match_phrase'))\n\t     *      );\n\t     *      matchPhrases(['foo', 'bar', 'baz']); //=> {must: [{match_phrase: 'foo'}, {match_phrase: 'bar'}, {match_phrase: 'baz'}]}\n\t     */\n\t    var objOf = _curry2(function objOf(key, val) {\n\t        var obj = {};\n\t        obj[key] = val;\n\t        return obj;\n\t    });\n\n\t    /**\n\t     * Returns a singleton array containing the value provided.\n\t     *\n\t     * Note this `of` is different from the ES6 `of`; See\n\t     * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.3.0\n\t     * @category Function\n\t     * @sig a -> [a]\n\t     * @param {*} x any value\n\t     * @return {Array} An array wrapping `x`.\n\t     * @example\n\t     *\n\t     *      R.of(null); //=> [null]\n\t     *      R.of([42]); //=> [[42]]\n\t     */\n\t    var of = _curry1(_of);\n\n\t    /**\n\t     * Accepts a function `fn` and returns a function that guards invocation of\n\t     * `fn` such that `fn` can only ever be called once, no matter how many times\n\t     * the returned function is invoked. The first value calculated is returned in\n\t     * subsequent invocations.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Function\n\t     * @sig (a... -> b) -> (a... -> b)\n\t     * @param {Function} fn The function to wrap in a call-only-once wrapper.\n\t     * @return {Function} The wrapped function.\n\t     * @example\n\t     *\n\t     *      var addOneOnce = R.once(x => x + 1);\n\t     *      addOneOnce(10); //=> 11\n\t     *      addOneOnce(addOneOnce(50)); //=> 11\n\t     */\n\t    var once = _curry1(function once(fn) {\n\t        var called = false;\n\t        var result;\n\t        return _arity(fn.length, function () {\n\t            if (called) {\n\t                return result;\n\t            }\n\t            called = true;\n\t            result = fn.apply(this, arguments);\n\t            return result;\n\t        });\n\t    });\n\n\t    /**\n\t     * Returns `true` if one or both of its arguments are `true`. Returns `false`\n\t     * if both arguments are `false`.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Logic\n\t     * @sig * -> * -> *\n\t     * @param {Boolean} a A boolean value\n\t     * @param {Boolean} b A boolean value\n\t     * @return {Boolean} `true` if one or both arguments are `true`, `false` otherwise\n\t     * @see R.either\n\t     * @example\n\t     *\n\t     *      R.or(true, true); //=> true\n\t     *      R.or(true, false); //=> true\n\t     *      R.or(false, true); //=> true\n\t     *      R.or(false, false); //=> false\n\t     */\n\t    var or = _curry2(function or(a, b) {\n\t        return a || b;\n\t    });\n\n\t    /**\n\t     * Returns the result of \"setting\" the portion of the given data structure\n\t     * focused by the given lens to the result of applying the given function to\n\t     * the focused value.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.16.0\n\t     * @category Object\n\t     * @typedefn Lens s a = Functor f => (a -> f a) -> s -> f s\n\t     * @sig Lens s a -> (a -> a) -> s -> s\n\t     * @param {Lens} lens\n\t     * @param {*} v\n\t     * @param {*} x\n\t     * @return {*}\n\t     * @see R.prop, R.lensIndex, R.lensProp\n\t     * @example\n\t     *\n\t     *      var headLens = R.lensIndex(0);\n\t     *\n\t     *      R.over(headLens, R.toUpper, ['foo', 'bar', 'baz']); //=> ['FOO', 'bar', 'baz']\n\t     */\n\t    // `Identity` is a functor that holds a single value, where `map` simply\n\t    // transforms the held value with the provided function.\n\t    // The value returned by the getter function is first transformed with `f`,\n\t    // then set as the value of an `Identity`. This is then mapped over with the\n\t    // setter function of the lens.\n\t    var over = function () {\n\t        // `Identity` is a functor that holds a single value, where `map` simply\n\t        // transforms the held value with the provided function.\n\t        var Identity = function (x) {\n\t            return {\n\t                value: x,\n\t                map: function (f) {\n\t                    return Identity(f(x));\n\t                }\n\t            };\n\t        };\n\t        return _curry3(function over(lens, f, x) {\n\t            // The value returned by the getter function is first transformed with `f`,\n\t            // then set as the value of an `Identity`. This is then mapped over with the\n\t            // setter function of the lens.\n\t            return lens(function (y) {\n\t                return Identity(f(y));\n\t            })(x).value;\n\t        });\n\t    }();\n\n\t    /**\n\t     * Takes two arguments, `fst` and `snd`, and returns `[fst, snd]`.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.18.0\n\t     * @category List\n\t     * @sig a -> b -> (a,b)\n\t     * @param {*} fst\n\t     * @param {*} snd\n\t     * @return {Array}\n\t     * @see R.objOf, R.of\n\t     * @example\n\t     *\n\t     *      R.pair('foo', 'bar'); //=> ['foo', 'bar']\n\t     */\n\t    var pair = _curry2(function pair(fst, snd) {\n\t        return [\n\t            fst,\n\t            snd\n\t        ];\n\t    });\n\n\t    /**\n\t     * Retrieve the value at a given path.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.2.0\n\t     * @category Object\n\t     * @sig [String] -> {k: v} -> v | Undefined\n\t     * @param {Array} path The path to use.\n\t     * @param {Object} obj The object to retrieve the nested property from.\n\t     * @return {*} The data at `path`.\n\t     * @see R.prop\n\t     * @example\n\t     *\n\t     *      R.path(['a', 'b'], {a: {b: 2}}); //=> 2\n\t     *      R.path(['a', 'b'], {c: {b: 2}}); //=> undefined\n\t     */\n\t    var path = _curry2(function path(paths, obj) {\n\t        var val = obj;\n\t        var idx = 0;\n\t        while (idx < paths.length) {\n\t            if (val == null) {\n\t                return;\n\t            }\n\t            val = val[paths[idx]];\n\t            idx += 1;\n\t        }\n\t        return val;\n\t    });\n\n\t    /**\n\t     * If the given, non-null object has a value at the given path, returns the\n\t     * value at that path. Otherwise returns the provided default value.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.18.0\n\t     * @category Object\n\t     * @sig a -> [String] -> Object -> a\n\t     * @param {*} d The default value.\n\t     * @param {Array} p The path to use.\n\t     * @param {Object} obj The object to retrieve the nested property from.\n\t     * @return {*} The data at `path` of the supplied object or the default value.\n\t     * @example\n\t     *\n\t     *      R.pathOr('N/A', ['a', 'b'], {a: {b: 2}}); //=> 2\n\t     *      R.pathOr('N/A', ['a', 'b'], {c: {b: 2}}); //=> \"N/A\"\n\t     */\n\t    var pathOr = _curry3(function pathOr(d, p, obj) {\n\t        return defaultTo(d, path(p, obj));\n\t    });\n\n\t    /**\n\t     * Returns `true` if the specified object property at given path satisfies the\n\t     * given predicate; `false` otherwise.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.19.0\n\t     * @category Logic\n\t     * @sig (a -> Boolean) -> [String] -> Object -> Boolean\n\t     * @param {Function} pred\n\t     * @param {Array} propPath\n\t     * @param {*} obj\n\t     * @return {Boolean}\n\t     * @see R.propSatisfies, R.path\n\t     * @example\n\t     *\n\t     *      R.pathSatisfies(y => y > 0, ['x', 'y'], {x: {y: 2}}); //=> true\n\t     */\n\t    var pathSatisfies = _curry3(function pathSatisfies(pred, propPath, obj) {\n\t        return propPath.length > 0 && pred(path(propPath, obj));\n\t    });\n\n\t    /**\n\t     * Returns a partial copy of an object containing only the keys specified. If\n\t     * the key does not exist, the property is ignored.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Object\n\t     * @sig [k] -> {k: v} -> {k: v}\n\t     * @param {Array} names an array of String property names to copy onto a new object\n\t     * @param {Object} obj The object to copy from\n\t     * @return {Object} A new object with only properties from `names` on it.\n\t     * @see R.omit, R.props\n\t     * @example\n\t     *\n\t     *      R.pick(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {a: 1, d: 4}\n\t     *      R.pick(['a', 'e', 'f'], {a: 1, b: 2, c: 3, d: 4}); //=> {a: 1}\n\t     */\n\t    var pick = _curry2(function pick(names, obj) {\n\t        var result = {};\n\t        var idx = 0;\n\t        while (idx < names.length) {\n\t            if (names[idx] in obj) {\n\t                result[names[idx]] = obj[names[idx]];\n\t            }\n\t            idx += 1;\n\t        }\n\t        return result;\n\t    });\n\n\t    /**\n\t     * Similar to `pick` except that this one includes a `key: undefined` pair for\n\t     * properties that don't exist.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Object\n\t     * @sig [k] -> {k: v} -> {k: v}\n\t     * @param {Array} names an array of String property names to copy onto a new object\n\t     * @param {Object} obj The object to copy from\n\t     * @return {Object} A new object with only properties from `names` on it.\n\t     * @see R.pick\n\t     * @example\n\t     *\n\t     *      R.pickAll(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {a: 1, d: 4}\n\t     *      R.pickAll(['a', 'e', 'f'], {a: 1, b: 2, c: 3, d: 4}); //=> {a: 1, e: undefined, f: undefined}\n\t     */\n\t    var pickAll = _curry2(function pickAll(names, obj) {\n\t        var result = {};\n\t        var idx = 0;\n\t        var len = names.length;\n\t        while (idx < len) {\n\t            var name = names[idx];\n\t            result[name] = obj[name];\n\t            idx += 1;\n\t        }\n\t        return result;\n\t    });\n\n\t    /**\n\t     * Returns a partial copy of an object containing only the keys that satisfy\n\t     * the supplied predicate.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.8.0\n\t     * @category Object\n\t     * @sig (v, k -> Boolean) -> {k: v} -> {k: v}\n\t     * @param {Function} pred A predicate to determine whether or not a key\n\t     *        should be included on the output object.\n\t     * @param {Object} obj The object to copy from\n\t     * @return {Object} A new object with only properties that satisfy `pred`\n\t     *         on it.\n\t     * @see R.pick, R.filter\n\t     * @example\n\t     *\n\t     *      var isUpperCase = (val, key) => key.toUpperCase() === key;\n\t     *      R.pickBy(isUpperCase, {a: 1, b: 2, A: 3, B: 4}); //=> {A: 3, B: 4}\n\t     */\n\t    var pickBy = _curry2(function pickBy(test, obj) {\n\t        var result = {};\n\t        for (var prop in obj) {\n\t            if (test(obj[prop], prop, obj)) {\n\t                result[prop] = obj[prop];\n\t            }\n\t        }\n\t        return result;\n\t    });\n\n\t    /**\n\t     * Returns a new list with the given element at the front, followed by the\n\t     * contents of the list.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig a -> [a] -> [a]\n\t     * @param {*} el The item to add to the head of the output list.\n\t     * @param {Array} list The array to add to the tail of the output list.\n\t     * @return {Array} A new array.\n\t     * @see R.append\n\t     * @example\n\t     *\n\t     *      R.prepend('fee', ['fi', 'fo', 'fum']); //=> ['fee', 'fi', 'fo', 'fum']\n\t     */\n\t    var prepend = _curry2(function prepend(el, list) {\n\t        return _concat([el], list);\n\t    });\n\n\t    /**\n\t     * Returns a function that when supplied an object returns the indicated\n\t     * property of that object, if it exists.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Object\n\t     * @sig s -> {s: a} -> a | Undefined\n\t     * @param {String} p The property name\n\t     * @param {Object} obj The object to query\n\t     * @return {*} The value at `obj.p`.\n\t     * @see R.path\n\t     * @example\n\t     *\n\t     *      R.prop('x', {x: 100}); //=> 100\n\t     *      R.prop('x', {}); //=> undefined\n\t     */\n\t    var prop = _curry2(function prop(p, obj) {\n\t        return obj[p];\n\t    });\n\n\t    /**\n\t     * Returns `true` if the specified object property is of the given type;\n\t     * `false` otherwise.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.16.0\n\t     * @category Type\n\t     * @sig Type -> String -> Object -> Boolean\n\t     * @param {Function} type\n\t     * @param {String} name\n\t     * @param {*} obj\n\t     * @return {Boolean}\n\t     * @see R.is, R.propSatisfies\n\t     * @example\n\t     *\n\t     *      R.propIs(Number, 'x', {x: 1, y: 2});  //=> true\n\t     *      R.propIs(Number, 'x', {x: 'foo'});    //=> false\n\t     *      R.propIs(Number, 'x', {});            //=> false\n\t     */\n\t    var propIs = _curry3(function propIs(type, name, obj) {\n\t        return is(type, obj[name]);\n\t    });\n\n\t    /**\n\t     * If the given, non-null object has an own property with the specified name,\n\t     * returns the value of that property. Otherwise returns the provided default\n\t     * value.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.6.0\n\t     * @category Object\n\t     * @sig a -> String -> Object -> a\n\t     * @param {*} val The default value.\n\t     * @param {String} p The name of the property to return.\n\t     * @param {Object} obj The object to query.\n\t     * @return {*} The value of given property of the supplied object or the default value.\n\t     * @example\n\t     *\n\t     *      var alice = {\n\t     *        name: 'ALICE',\n\t     *        age: 101\n\t     *      };\n\t     *      var favorite = R.prop('favoriteLibrary');\n\t     *      var favoriteWithDefault = R.propOr('Ramda', 'favoriteLibrary');\n\t     *\n\t     *      favorite(alice);  //=> undefined\n\t     *      favoriteWithDefault(alice);  //=> 'Ramda'\n\t     */\n\t    var propOr = _curry3(function propOr(val, p, obj) {\n\t        return obj != null && _has(p, obj) ? obj[p] : val;\n\t    });\n\n\t    /**\n\t     * Returns `true` if the specified object property satisfies the given\n\t     * predicate; `false` otherwise.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.16.0\n\t     * @category Logic\n\t     * @sig (a -> Boolean) -> String -> {String: a} -> Boolean\n\t     * @param {Function} pred\n\t     * @param {String} name\n\t     * @param {*} obj\n\t     * @return {Boolean}\n\t     * @see R.propEq, R.propIs\n\t     * @example\n\t     *\n\t     *      R.propSatisfies(x => x > 0, 'x', {x: 1, y: 2}); //=> true\n\t     */\n\t    var propSatisfies = _curry3(function propSatisfies(pred, name, obj) {\n\t        return pred(obj[name]);\n\t    });\n\n\t    /**\n\t     * Acts as multiple `prop`: array of keys in, array of values out. Preserves\n\t     * order.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Object\n\t     * @sig [k] -> {k: v} -> [v]\n\t     * @param {Array} ps The property names to fetch\n\t     * @param {Object} obj The object to query\n\t     * @return {Array} The corresponding values or partially applied function.\n\t     * @example\n\t     *\n\t     *      R.props(['x', 'y'], {x: 1, y: 2}); //=> [1, 2]\n\t     *      R.props(['c', 'a', 'b'], {b: 2, a: 1}); //=> [undefined, 1, 2]\n\t     *\n\t     *      var fullName = R.compose(R.join(' '), R.props(['first', 'last']));\n\t     *      fullName({last: 'Bullet-Tooth', age: 33, first: 'Tony'}); //=> 'Tony Bullet-Tooth'\n\t     */\n\t    var props = _curry2(function props(ps, obj) {\n\t        var len = ps.length;\n\t        var out = [];\n\t        var idx = 0;\n\t        while (idx < len) {\n\t            out[idx] = obj[ps[idx]];\n\t            idx += 1;\n\t        }\n\t        return out;\n\t    });\n\n\t    /**\n\t     * Returns a list of numbers from `from` (inclusive) to `to` (exclusive).\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig Number -> Number -> [Number]\n\t     * @param {Number} from The first number in the list.\n\t     * @param {Number} to One more than the last number in the list.\n\t     * @return {Array} The list of numbers in tthe set `[a, b)`.\n\t     * @example\n\t     *\n\t     *      R.range(1, 5);    //=> [1, 2, 3, 4]\n\t     *      R.range(50, 53);  //=> [50, 51, 52]\n\t     */\n\t    var range = _curry2(function range(from, to) {\n\t        if (!(_isNumber(from) && _isNumber(to))) {\n\t            throw new TypeError('Both arguments to range must be numbers');\n\t        }\n\t        var result = [];\n\t        var n = from;\n\t        while (n < to) {\n\t            result.push(n);\n\t            n += 1;\n\t        }\n\t        return result;\n\t    });\n\n\t    /**\n\t     * Returns a single item by iterating through the list, successively calling\n\t     * the iterator function and passing it an accumulator value and the current\n\t     * value from the array, and then passing the result to the next call.\n\t     *\n\t     * Similar to `reduce`, except moves through the input list from the right to\n\t     * the left.\n\t     *\n\t     * The iterator function receives two values: *(acc, value)*\n\t     *\n\t     * Note: `R.reduceRight` does not skip deleted or unassigned indices (sparse\n\t     * arrays), unlike the native `Array.prototype.reduce` method. For more details\n\t     * on this behavior, see:\n\t     * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight#Description\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig (a,b -> a) -> a -> [b] -> a\n\t     * @param {Function} fn The iterator function. Receives two values, the accumulator and the\n\t     *        current element from the array.\n\t     * @param {*} acc The accumulator value.\n\t     * @param {Array} list The list to iterate over.\n\t     * @return {*} The final, accumulated value.\n\t     * @see R.addIndex\n\t     * @example\n\t     *\n\t     *      var pairs = [ ['a', 1], ['b', 2], ['c', 3] ];\n\t     *      var flattenPairs = (acc, pair) => acc.concat(pair);\n\t     *\n\t     *      R.reduceRight(flattenPairs, [], pairs); //=> [ 'c', 3, 'b', 2, 'a', 1 ]\n\t     */\n\t    var reduceRight = _curry3(function reduceRight(fn, acc, list) {\n\t        var idx = list.length - 1;\n\t        while (idx >= 0) {\n\t            acc = fn(acc, list[idx]);\n\t            idx -= 1;\n\t        }\n\t        return acc;\n\t    });\n\n\t    /**\n\t     * Returns a value wrapped to indicate that it is the final value of the reduce\n\t     * and transduce functions. The returned value should be considered a black\n\t     * box: the internal structure is not guaranteed to be stable.\n\t     *\n\t     * Note: this optimization is unavailable to functions not explicitly listed\n\t     * above. For instance, it is not currently supported by reduceRight.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.15.0\n\t     * @category List\n\t     * @sig a -> *\n\t     * @param {*} x The final value of the reduce.\n\t     * @return {*} The wrapped value.\n\t     * @see R.reduce, R.transduce\n\t     * @example\n\t     *\n\t     *      R.reduce(\n\t     *        R.pipe(R.add, R.when(R.gte(R.__, 10), R.reduced)),\n\t     *        0,\n\t     *        [1, 2, 3, 4, 5]) // 10\n\t     */\n\t    var reduced = _curry1(_reduced);\n\n\t    /**\n\t     * Removes the sub-list of `list` starting at index `start` and containing\n\t     * `count` elements. _Note that this is not destructive_: it returns a copy of\n\t     * the list with the changes.\n\t     * <small>No lists have been harmed in the application of this function.</small>\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.2.2\n\t     * @category List\n\t     * @sig Number -> Number -> [a] -> [a]\n\t     * @param {Number} start The position to start removing elements\n\t     * @param {Number} count The number of elements to remove\n\t     * @param {Array} list The list to remove from\n\t     * @return {Array} A new Array with `count` elements from `start` removed.\n\t     * @example\n\t     *\n\t     *      R.remove(2, 3, [1,2,3,4,5,6,7,8]); //=> [1,2,6,7,8]\n\t     */\n\t    var remove = _curry3(function remove(start, count, list) {\n\t        return _concat(_slice(list, 0, Math.min(start, list.length)), _slice(list, Math.min(list.length, start + count)));\n\t    });\n\n\t    /**\n\t     * Replace a substring or regex match in a string with a replacement.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.7.0\n\t     * @category String\n\t     * @sig RegExp|String -> String -> String -> String\n\t     * @param {RegExp|String} pattern A regular expression or a substring to match.\n\t     * @param {String} replacement The string to replace the matches with.\n\t     * @param {String} str The String to do the search and replacement in.\n\t     * @return {String} The result.\n\t     * @example\n\t     *\n\t     *      R.replace('foo', 'bar', 'foo foo foo'); //=> 'bar foo foo'\n\t     *      R.replace(/foo/, 'bar', 'foo foo foo'); //=> 'bar foo foo'\n\t     *\n\t     *      // Use the \"g\" (global) flag to replace all occurrences:\n\t     *      R.replace(/foo/g, 'bar', 'foo foo foo'); //=> 'bar bar bar'\n\t     */\n\t    var replace = _curry3(function replace(regex, replacement, str) {\n\t        return str.replace(regex, replacement);\n\t    });\n\n\t    /**\n\t     * Returns a new list or string with the elements or characters in reverse\n\t     * order.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig [a] -> [a]\n\t     * @sig String -> String\n\t     * @param {Array|String} list\n\t     * @return {Array|String}\n\t     * @example\n\t     *\n\t     *      R.reverse([1, 2, 3]);  //=> [3, 2, 1]\n\t     *      R.reverse([1, 2]);     //=> [2, 1]\n\t     *      R.reverse([1]);        //=> [1]\n\t     *      R.reverse([]);         //=> []\n\t     *\n\t     *      R.reverse('abc');      //=> 'cba'\n\t     *      R.reverse('ab');       //=> 'ba'\n\t     *      R.reverse('a');        //=> 'a'\n\t     *      R.reverse('');         //=> ''\n\t     */\n\t    var reverse = _curry1(function reverse(list) {\n\t        return _isString(list) ? list.split('').reverse().join('') : _slice(list).reverse();\n\t    });\n\n\t    /**\n\t     * Scan is similar to reduce, but returns a list of successively reduced values\n\t     * from the left\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.10.0\n\t     * @category List\n\t     * @sig (a,b -> a) -> a -> [b] -> [a]\n\t     * @param {Function} fn The iterator function. Receives two values, the accumulator and the\n\t     *        current element from the array\n\t     * @param {*} acc The accumulator value.\n\t     * @param {Array} list The list to iterate over.\n\t     * @return {Array} A list of all intermediately reduced values.\n\t     * @example\n\t     *\n\t     *      var numbers = [1, 2, 3, 4];\n\t     *      var factorials = R.scan(R.multiply, 1, numbers); //=> [1, 1, 2, 6, 24]\n\t     */\n\t    var scan = _curry3(function scan(fn, acc, list) {\n\t        var idx = 0;\n\t        var len = list.length;\n\t        var result = [acc];\n\t        while (idx < len) {\n\t            acc = fn(acc, list[idx]);\n\t            result[idx + 1] = acc;\n\t            idx += 1;\n\t        }\n\t        return result;\n\t    });\n\n\t    /**\n\t     * Returns the result of \"setting\" the portion of the given data structure\n\t     * focused by the given lens to the given value.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.16.0\n\t     * @category Object\n\t     * @typedefn Lens s a = Functor f => (a -> f a) -> s -> f s\n\t     * @sig Lens s a -> a -> s -> s\n\t     * @param {Lens} lens\n\t     * @param {*} v\n\t     * @param {*} x\n\t     * @return {*}\n\t     * @see R.prop, R.lensIndex, R.lensProp\n\t     * @example\n\t     *\n\t     *      var xLens = R.lensProp('x');\n\t     *\n\t     *      R.set(xLens, 4, {x: 1, y: 2});  //=> {x: 4, y: 2}\n\t     *      R.set(xLens, 8, {x: 1, y: 2});  //=> {x: 8, y: 2}\n\t     */\n\t    var set = _curry3(function set(lens, v, x) {\n\t        return over(lens, always(v), x);\n\t    });\n\n\t    /**\n\t     * Returns the elements of the given list or string (or object with a `slice`\n\t     * method) from `fromIndex` (inclusive) to `toIndex` (exclusive).\n\t     *\n\t     * Dispatches to the `slice` method of the third argument, if present.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.4\n\t     * @category List\n\t     * @sig Number -> Number -> [a] -> [a]\n\t     * @sig Number -> Number -> String -> String\n\t     * @param {Number} fromIndex The start index (inclusive).\n\t     * @param {Number} toIndex The end index (exclusive).\n\t     * @param {*} list\n\t     * @return {*}\n\t     * @example\n\t     *\n\t     *      R.slice(1, 3, ['a', 'b', 'c', 'd']);        //=> ['b', 'c']\n\t     *      R.slice(1, Infinity, ['a', 'b', 'c', 'd']); //=> ['b', 'c', 'd']\n\t     *      R.slice(0, -1, ['a', 'b', 'c', 'd']);       //=> ['a', 'b', 'c']\n\t     *      R.slice(-3, -1, ['a', 'b', 'c', 'd']);      //=> ['b', 'c']\n\t     *      R.slice(0, 3, 'ramda');                     //=> 'ram'\n\t     */\n\t    var slice = _curry3(_checkForMethod('slice', function slice(fromIndex, toIndex, list) {\n\t        return Array.prototype.slice.call(list, fromIndex, toIndex);\n\t    }));\n\n\t    /**\n\t     * Returns a copy of the list, sorted according to the comparator function,\n\t     * which should accept two values at a time and return a negative number if the\n\t     * first value is smaller, a positive number if it's larger, and zero if they\n\t     * are equal. Please note that this is a **copy** of the list. It does not\n\t     * modify the original.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig (a,a -> Number) -> [a] -> [a]\n\t     * @param {Function} comparator A sorting function :: a -> b -> Int\n\t     * @param {Array} list The list to sort\n\t     * @return {Array} a new array with its elements sorted by the comparator function.\n\t     * @example\n\t     *\n\t     *      var diff = function(a, b) { return a - b; };\n\t     *      R.sort(diff, [4,2,7,5]); //=> [2, 4, 5, 7]\n\t     */\n\t    var sort = _curry2(function sort(comparator, list) {\n\t        return _slice(list).sort(comparator);\n\t    });\n\n\t    /**\n\t     * Sorts the list according to the supplied function.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Relation\n\t     * @sig Ord b => (a -> b) -> [a] -> [a]\n\t     * @param {Function} fn\n\t     * @param {Array} list The list to sort.\n\t     * @return {Array} A new list sorted by the keys generated by `fn`.\n\t     * @example\n\t     *\n\t     *      var sortByFirstItem = R.sortBy(R.prop(0));\n\t     *      var sortByNameCaseInsensitive = R.sortBy(R.compose(R.toLower, R.prop('name')));\n\t     *      var pairs = [[-1, 1], [-2, 2], [-3, 3]];\n\t     *      sortByFirstItem(pairs); //=> [[-3, 3], [-2, 2], [-1, 1]]\n\t     *      var alice = {\n\t     *        name: 'ALICE',\n\t     *        age: 101\n\t     *      };\n\t     *      var bob = {\n\t     *        name: 'Bob',\n\t     *        age: -10\n\t     *      };\n\t     *      var clara = {\n\t     *        name: 'clara',\n\t     *        age: 314.159\n\t     *      };\n\t     *      var people = [clara, bob, alice];\n\t     *      sortByNameCaseInsensitive(people); //=> [alice, bob, clara]\n\t     */\n\t    var sortBy = _curry2(function sortBy(fn, list) {\n\t        return _slice(list).sort(function (a, b) {\n\t            var aa = fn(a);\n\t            var bb = fn(b);\n\t            return aa < bb ? -1 : aa > bb ? 1 : 0;\n\t        });\n\t    });\n\n\t    /**\n\t     * Splits a given list or string at a given index.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.19.0\n\t     * @category List\n\t     * @sig Number -> [a] -> [[a], [a]]\n\t     * @sig Number -> String -> [String, String]\n\t     * @param {Number} index The index where the array/string is split.\n\t     * @param {Array|String} array The array/string to be split.\n\t     * @return {Array}\n\t     * @example\n\t     *\n\t     *      R.splitAt(1, [1, 2, 3]);          //=> [[1], [2, 3]]\n\t     *      R.splitAt(5, 'hello world');      //=> ['hello', ' world']\n\t     *      R.splitAt(-1, 'foobar');          //=> ['fooba', 'r']\n\t     */\n\t    var splitAt = _curry2(function splitAt(index, array) {\n\t        return [\n\t            slice(0, index, array),\n\t            slice(index, length(array), array)\n\t        ];\n\t    });\n\n\t    /**\n\t     * Splits a collection into slices of the specified length.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.16.0\n\t     * @category List\n\t     * @sig Number -> [a] -> [[a]]\n\t     * @sig Number -> String -> [String]\n\t     * @param {Number} n\n\t     * @param {Array} list\n\t     * @return {Array}\n\t     * @example\n\t     *\n\t     *      R.splitEvery(3, [1, 2, 3, 4, 5, 6, 7]); //=> [[1, 2, 3], [4, 5, 6], [7]]\n\t     *      R.splitEvery(3, 'foobarbaz'); //=> ['foo', 'bar', 'baz']\n\t     */\n\t    var splitEvery = _curry2(function splitEvery(n, list) {\n\t        if (n <= 0) {\n\t            throw new Error('First argument to splitEvery must be a positive integer');\n\t        }\n\t        var result = [];\n\t        var idx = 0;\n\t        while (idx < list.length) {\n\t            result.push(slice(idx, idx += n, list));\n\t        }\n\t        return result;\n\t    });\n\n\t    /**\n\t     * Takes a list and a predicate and returns a pair of lists with the following properties:\n\t     *\n\t     *  - the result of concatenating the two output lists is equivalent to the input list;\n\t     *  - none of the elements of the first output list satisfies the predicate; and\n\t     *  - if the second output list is non-empty, its first element satisfies the predicate.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.19.0\n\t     * @category List\n\t     * @sig (a -> Boolean) -> [a] -> [[a], [a]]\n\t     * @param {Function} pred The predicate that determines where the array is split.\n\t     * @param {Array} list The array to be split.\n\t     * @return {Array}\n\t     * @example\n\t     *\n\t     *      R.splitWhen(R.equals(2), [1, 2, 3, 1, 2, 3]);   //=> [[1], [2, 3, 1, 2, 3]]\n\t     */\n\t    var splitWhen = _curry2(function splitWhen(pred, list) {\n\t        var idx = 0;\n\t        var len = list.length;\n\t        var prefix = [];\n\t        while (idx < len && !pred(list[idx])) {\n\t            prefix.push(list[idx]);\n\t            idx += 1;\n\t        }\n\t        return [\n\t            prefix,\n\t            _slice(list, idx)\n\t        ];\n\t    });\n\n\t    /**\n\t     * Subtracts its second argument from its first argument.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Math\n\t     * @sig Number -> Number -> Number\n\t     * @param {Number} a The first value.\n\t     * @param {Number} b The second value.\n\t     * @return {Number} The result of `a - b`.\n\t     * @see R.add\n\t     * @example\n\t     *\n\t     *      R.subtract(10, 8); //=> 2\n\t     *\n\t     *      var minus5 = R.subtract(R.__, 5);\n\t     *      minus5(17); //=> 12\n\t     *\n\t     *      var complementaryAngle = R.subtract(90);\n\t     *      complementaryAngle(30); //=> 60\n\t     *      complementaryAngle(72); //=> 18\n\t     */\n\t    var subtract = _curry2(function subtract(a, b) {\n\t        return Number(a) - Number(b);\n\t    });\n\n\t    /**\n\t     * Returns all but the first element of the given list or string (or object\n\t     * with a `tail` method).\n\t     *\n\t     * Dispatches to the `slice` method of the first argument, if present.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig [a] -> [a]\n\t     * @sig String -> String\n\t     * @param {*} list\n\t     * @return {*}\n\t     * @see R.head, R.init, R.last\n\t     * @example\n\t     *\n\t     *      R.tail([1, 2, 3]);  //=> [2, 3]\n\t     *      R.tail([1, 2]);     //=> [2]\n\t     *      R.tail([1]);        //=> []\n\t     *      R.tail([]);         //=> []\n\t     *\n\t     *      R.tail('abc');  //=> 'bc'\n\t     *      R.tail('ab');   //=> 'b'\n\t     *      R.tail('a');    //=> ''\n\t     *      R.tail('');     //=> ''\n\t     */\n\t    var tail = _checkForMethod('tail', slice(1, Infinity));\n\n\t    /**\n\t     * Returns the first `n` elements of the given list, string, or\n\t     * transducer/transformer (or object with a `take` method).\n\t     *\n\t     * Dispatches to the `take` method of the second argument, if present.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig Number -> [a] -> [a]\n\t     * @sig Number -> String -> String\n\t     * @param {Number} n\n\t     * @param {*} list\n\t     * @return {*}\n\t     * @see R.drop\n\t     * @example\n\t     *\n\t     *      R.take(1, ['foo', 'bar', 'baz']); //=> ['foo']\n\t     *      R.take(2, ['foo', 'bar', 'baz']); //=> ['foo', 'bar']\n\t     *      R.take(3, ['foo', 'bar', 'baz']); //=> ['foo', 'bar', 'baz']\n\t     *      R.take(4, ['foo', 'bar', 'baz']); //=> ['foo', 'bar', 'baz']\n\t     *      R.take(3, 'ramda');               //=> 'ram'\n\t     *\n\t     *      var personnel = [\n\t     *        'Dave Brubeck',\n\t     *        'Paul Desmond',\n\t     *        'Eugene Wright',\n\t     *        'Joe Morello',\n\t     *        'Gerry Mulligan',\n\t     *        'Bob Bates',\n\t     *        'Joe Dodge',\n\t     *        'Ron Crotty'\n\t     *      ];\n\t     *\n\t     *      var takeFive = R.take(5);\n\t     *      takeFive(personnel);\n\t     *      //=> ['Dave Brubeck', 'Paul Desmond', 'Eugene Wright', 'Joe Morello', 'Gerry Mulligan']\n\t     */\n\t    var take = _curry2(_dispatchable('take', _xtake, function take(n, xs) {\n\t        return slice(0, n < 0 ? Infinity : n, xs);\n\t    }));\n\n\t    /**\n\t     * Returns a new list containing the last `n` elements of a given list, passing\n\t     * each value to the supplied predicate function, and terminating when the\n\t     * predicate function returns `false`. Excludes the element that caused the\n\t     * predicate function to fail. The predicate function is passed one argument:\n\t     * *(value)*.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.16.0\n\t     * @category List\n\t     * @sig (a -> Boolean) -> [a] -> [a]\n\t     * @param {Function} fn The function called per iteration.\n\t     * @param {Array} list The collection to iterate over.\n\t     * @return {Array} A new array.\n\t     * @see R.dropLastWhile, R.addIndex\n\t     * @example\n\t     *\n\t     *      var isNotOne = x => x !== 1;\n\t     *\n\t     *      R.takeLastWhile(isNotOne, [1, 2, 3, 4]); //=> [2, 3, 4]\n\t     */\n\t    var takeLastWhile = _curry2(function takeLastWhile(fn, list) {\n\t        var idx = list.length - 1;\n\t        while (idx >= 0 && fn(list[idx])) {\n\t            idx -= 1;\n\t        }\n\t        return _slice(list, idx + 1, Infinity);\n\t    });\n\n\t    /**\n\t     * Returns a new list containing the first `n` elements of a given list,\n\t     * passing each value to the supplied predicate function, and terminating when\n\t     * the predicate function returns `false`. Excludes the element that caused the\n\t     * predicate function to fail. The predicate function is passed one argument:\n\t     * *(value)*.\n\t     *\n\t     * Dispatches to the `takeWhile` method of the second argument, if present.\n\t     *\n\t     * Acts as a transducer if a transformer is given in list position.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig (a -> Boolean) -> [a] -> [a]\n\t     * @param {Function} fn The function called per iteration.\n\t     * @param {Array} list The collection to iterate over.\n\t     * @return {Array} A new array.\n\t     * @see R.dropWhile, R.transduce, R.addIndex\n\t     * @example\n\t     *\n\t     *      var isNotFour = x => x !== 4;\n\t     *\n\t     *      R.takeWhile(isNotFour, [1, 2, 3, 4, 3, 2, 1]); //=> [1, 2, 3]\n\t     */\n\t    var takeWhile = _curry2(_dispatchable('takeWhile', _xtakeWhile, function takeWhile(fn, list) {\n\t        var idx = 0;\n\t        var len = list.length;\n\t        while (idx < len && fn(list[idx])) {\n\t            idx += 1;\n\t        }\n\t        return _slice(list, 0, idx);\n\t    }));\n\n\t    /**\n\t     * Runs the given function with the supplied object, then returns the object.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Function\n\t     * @sig (a -> *) -> a -> a\n\t     * @param {Function} fn The function to call with `x`. The return value of `fn` will be thrown away.\n\t     * @param {*} x\n\t     * @return {*} `x`.\n\t     * @example\n\t     *\n\t     *      var sayX = x => console.log('x is ' + x);\n\t     *      R.tap(sayX, 100); //=> 100\n\t     *      // logs 'x is 100'\n\t     */\n\t    var tap = _curry2(function tap(fn, x) {\n\t        fn(x);\n\t        return x;\n\t    });\n\n\t    /**\n\t     * Calls an input function `n` times, returning an array containing the results\n\t     * of those function calls.\n\t     *\n\t     * `fn` is passed one argument: The current value of `n`, which begins at `0`\n\t     * and is gradually incremented to `n - 1`.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.2.3\n\t     * @category List\n\t     * @sig (Number -> a) -> Number -> [a]\n\t     * @param {Function} fn The function to invoke. Passed one argument, the current value of `n`.\n\t     * @param {Number} n A value between `0` and `n - 1`. Increments after each function call.\n\t     * @return {Array} An array containing the return values of all calls to `fn`.\n\t     * @example\n\t     *\n\t     *      R.times(R.identity, 5); //=> [0, 1, 2, 3, 4]\n\t     */\n\t    var times = _curry2(function times(fn, n) {\n\t        var len = Number(n);\n\t        var idx = 0;\n\t        var list;\n\t        if (len < 0 || isNaN(len)) {\n\t            throw new RangeError('n must be a non-negative number');\n\t        }\n\t        list = new Array(len);\n\t        while (idx < len) {\n\t            list[idx] = fn(idx);\n\t            idx += 1;\n\t        }\n\t        return list;\n\t    });\n\n\t    /**\n\t     * Converts an object into an array of key, value arrays. Only the object's\n\t     * own properties are used.\n\t     * Note that the order of the output array is not guaranteed to be consistent\n\t     * across different JS platforms.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.4.0\n\t     * @category Object\n\t     * @sig {String: *} -> [[String,*]]\n\t     * @param {Object} obj The object to extract from\n\t     * @return {Array} An array of key, value arrays from the object's own properties.\n\t     * @see R.fromPairs\n\t     * @example\n\t     *\n\t     *      R.toPairs({a: 1, b: 2, c: 3}); //=> [['a', 1], ['b', 2], ['c', 3]]\n\t     */\n\t    var toPairs = _curry1(function toPairs(obj) {\n\t        var pairs = [];\n\t        for (var prop in obj) {\n\t            if (_has(prop, obj)) {\n\t                pairs[pairs.length] = [\n\t                    prop,\n\t                    obj[prop]\n\t                ];\n\t            }\n\t        }\n\t        return pairs;\n\t    });\n\n\t    /**\n\t     * Converts an object into an array of key, value arrays. The object's own\n\t     * properties and prototype properties are used. Note that the order of the\n\t     * output array is not guaranteed to be consistent across different JS\n\t     * platforms.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.4.0\n\t     * @category Object\n\t     * @sig {String: *} -> [[String,*]]\n\t     * @param {Object} obj The object to extract from\n\t     * @return {Array} An array of key, value arrays from the object's own\n\t     *         and prototype properties.\n\t     * @example\n\t     *\n\t     *      var F = function() { this.x = 'X'; };\n\t     *      F.prototype.y = 'Y';\n\t     *      var f = new F();\n\t     *      R.toPairsIn(f); //=> [['x','X'], ['y','Y']]\n\t     */\n\t    var toPairsIn = _curry1(function toPairsIn(obj) {\n\t        var pairs = [];\n\t        for (var prop in obj) {\n\t            pairs[pairs.length] = [\n\t                prop,\n\t                obj[prop]\n\t            ];\n\t        }\n\t        return pairs;\n\t    });\n\n\t    /**\n\t     * Transposes the rows and columns of a 2D list.\n\t     * When passed a list of `n` lists of length `x`,\n\t     * returns a list of `x` lists of length `n`.\n\t     *\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.19.0\n\t     * @category List\n\t     * @sig [[a]] -> [[a]]\n\t     * @param {Array} list A 2D list\n\t     * @return {Array} A 2D list\n\t     * @example\n\t     *\n\t     *      R.transpose([[1, 'a'], [2, 'b'], [3, 'c']]) //=> [[1, 2, 3], ['a', 'b', 'c']]\n\t     *      R.transpose([[1, 2, 3], ['a', 'b', 'c']]) //=> [[1, 'a'], [2, 'b'], [3, 'c']]\n\t     *\n\t     * If some of the rows are shorter than the following rows, their elements are skipped:\n\t     *\n\t     *      R.transpose([[10, 11], [20], [], [30, 31, 32]]) //=> [[10, 20, 30], [11, 31], [32]]\n\t     */\n\t    var transpose = _curry1(function transpose(outerlist) {\n\t        var i = 0;\n\t        var result = [];\n\t        while (i < outerlist.length) {\n\t            var innerlist = outerlist[i];\n\t            var j = 0;\n\t            while (j < innerlist.length) {\n\t                if (typeof result[j] === 'undefined') {\n\t                    result[j] = [];\n\t                }\n\t                result[j].push(innerlist[j]);\n\t                j += 1;\n\t            }\n\t            i += 1;\n\t        }\n\t        return result;\n\t    });\n\n\t    /**\n\t     * Removes (strips) whitespace from both ends of the string.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.6.0\n\t     * @category String\n\t     * @sig String -> String\n\t     * @param {String} str The string to trim.\n\t     * @return {String} Trimmed version of `str`.\n\t     * @example\n\t     *\n\t     *      R.trim('   xyz  '); //=> 'xyz'\n\t     *      R.map(R.trim, R.split(',', 'x, y, z')); //=> ['x', 'y', 'z']\n\t     */\n\t    var trim = function () {\n\t        var ws = '\\t\\n\\x0B\\f\\r \\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003' + '\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028' + '\\u2029\\uFEFF';\n\t        var zeroWidth = '\\u200B';\n\t        var hasProtoTrim = typeof String.prototype.trim === 'function';\n\t        if (!hasProtoTrim || (ws.trim() || !zeroWidth.trim())) {\n\t            return _curry1(function trim(str) {\n\t                var beginRx = new RegExp('^[' + ws + '][' + ws + ']*');\n\t                var endRx = new RegExp('[' + ws + '][' + ws + ']*$');\n\t                return str.replace(beginRx, '').replace(endRx, '');\n\t            });\n\t        } else {\n\t            return _curry1(function trim(str) {\n\t                return str.trim();\n\t            });\n\t        }\n\t    }();\n\n\t    /**\n\t     * `tryCatch` takes two functions, a `tryer` and a `catcher`. The returned\n\t     * function evaluates the `tryer`; if it does not throw, it simply returns the\n\t     * result. If the `tryer` *does* throw, the returned function evaluates the\n\t     * `catcher` function and returns its result. Note that for effective\n\t     * composition with this function, both the `tryer` and `catcher` functions\n\t     * must return the same type of results.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.20.0\n\t     * @category Function\n\t     * @sig (...x -> a) -> ((e, ...x) -> a) -> (...x -> a)\n\t     * @param {Function} tryer The function that may throw.\n\t     * @param {Function} catcher The function that will be evaluated if `tryer` throws.\n\t     * @return {Function} A new function that will catch exceptions and send then to the catcher.\n\t     * @example\n\t     *\n\t     *      R.tryCatch(R.prop('x'), R.F)({x: true}); //=> true\n\t     *      R.tryCatch(R.prop('x'), R.F)(null);      //=> false\n\t     */\n\t    var tryCatch = _curry2(function _tryCatch(tryer, catcher) {\n\t        return _arity(tryer.length, function () {\n\t            try {\n\t                return tryer.apply(this, arguments);\n\t            } catch (e) {\n\t                return catcher.apply(this, _concat([e], arguments));\n\t            }\n\t        });\n\t    });\n\n\t    /**\n\t     * Gives a single-word string description of the (native) type of a value,\n\t     * returning such answers as 'Object', 'Number', 'Array', or 'Null'. Does not\n\t     * attempt to distinguish user Object types any further, reporting them all as\n\t     * 'Object'.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.8.0\n\t     * @category Type\n\t     * @sig (* -> {*}) -> String\n\t     * @param {*} val The value to test\n\t     * @return {String}\n\t     * @example\n\t     *\n\t     *      R.type({}); //=> \"Object\"\n\t     *      R.type(1); //=> \"Number\"\n\t     *      R.type(false); //=> \"Boolean\"\n\t     *      R.type('s'); //=> \"String\"\n\t     *      R.type(null); //=> \"Null\"\n\t     *      R.type([]); //=> \"Array\"\n\t     *      R.type(/[A-z]/); //=> \"RegExp\"\n\t     */\n\t    var type = _curry1(function type(val) {\n\t        return val === null ? 'Null' : val === undefined ? 'Undefined' : Object.prototype.toString.call(val).slice(8, -1);\n\t    });\n\n\t    /**\n\t     * Takes a function `fn`, which takes a single array argument, and returns a\n\t     * function which:\n\t     *\n\t     *   - takes any number of positional arguments;\n\t     *   - passes these arguments to `fn` as an array; and\n\t     *   - returns the result.\n\t     *\n\t     * In other words, R.unapply derives a variadic function from a function which\n\t     * takes an array. R.unapply is the inverse of R.apply.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.8.0\n\t     * @category Function\n\t     * @sig ([*...] -> a) -> (*... -> a)\n\t     * @param {Function} fn\n\t     * @return {Function}\n\t     * @see R.apply\n\t     * @example\n\t     *\n\t     *      R.unapply(JSON.stringify)(1, 2, 3); //=> '[1,2,3]'\n\t     */\n\t    var unapply = _curry1(function unapply(fn) {\n\t        return function () {\n\t            return fn(_slice(arguments));\n\t        };\n\t    });\n\n\t    /**\n\t     * Wraps a function of any arity (including nullary) in a function that accepts\n\t     * exactly 1 parameter. Any extraneous parameters will not be passed to the\n\t     * supplied function.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.2.0\n\t     * @category Function\n\t     * @sig (* -> b) -> (a -> b)\n\t     * @param {Function} fn The function to wrap.\n\t     * @return {Function} A new function wrapping `fn`. The new function is guaranteed to be of\n\t     *         arity 1.\n\t     * @example\n\t     *\n\t     *      var takesTwoArgs = function(a, b) {\n\t     *        return [a, b];\n\t     *      };\n\t     *      takesTwoArgs.length; //=> 2\n\t     *      takesTwoArgs(1, 2); //=> [1, 2]\n\t     *\n\t     *      var takesOneArg = R.unary(takesTwoArgs);\n\t     *      takesOneArg.length; //=> 1\n\t     *      // Only 1 argument is passed to the wrapped function\n\t     *      takesOneArg(1, 2); //=> [1, undefined]\n\t     */\n\t    var unary = _curry1(function unary(fn) {\n\t        return nAry(1, fn);\n\t    });\n\n\t    /**\n\t     * Returns a function of arity `n` from a (manually) curried function.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.14.0\n\t     * @category Function\n\t     * @sig Number -> (a -> b) -> (a -> c)\n\t     * @param {Number} length The arity for the returned function.\n\t     * @param {Function} fn The function to uncurry.\n\t     * @return {Function} A new function.\n\t     * @see R.curry\n\t     * @example\n\t     *\n\t     *      var addFour = a => b => c => d => a + b + c + d;\n\t     *\n\t     *      var uncurriedAddFour = R.uncurryN(4, addFour);\n\t     *      uncurriedAddFour(1, 2, 3, 4); //=> 10\n\t     */\n\t    var uncurryN = _curry2(function uncurryN(depth, fn) {\n\t        return curryN(depth, function () {\n\t            var currentDepth = 1;\n\t            var value = fn;\n\t            var idx = 0;\n\t            var endIdx;\n\t            while (currentDepth <= depth && typeof value === 'function') {\n\t                endIdx = currentDepth === depth ? arguments.length : idx + value.length;\n\t                value = value.apply(this, _slice(arguments, idx, endIdx));\n\t                currentDepth += 1;\n\t                idx = endIdx;\n\t            }\n\t            return value;\n\t        });\n\t    });\n\n\t    /**\n\t     * Builds a list from a seed value. Accepts an iterator function, which returns\n\t     * either false to stop iteration or an array of length 2 containing the value\n\t     * to add to the resulting list and the seed to be used in the next call to the\n\t     * iterator function.\n\t     *\n\t     * The iterator function receives one argument: *(seed)*.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.10.0\n\t     * @category List\n\t     * @sig (a -> [b]) -> * -> [b]\n\t     * @param {Function} fn The iterator function. receives one argument, `seed`, and returns\n\t     *        either false to quit iteration or an array of length two to proceed. The element\n\t     *        at index 0 of this array will be added to the resulting array, and the element\n\t     *        at index 1 will be passed to the next call to `fn`.\n\t     * @param {*} seed The seed value.\n\t     * @return {Array} The final list.\n\t     * @example\n\t     *\n\t     *      var f = n => n > 50 ? false : [-n, n + 10];\n\t     *      R.unfold(f, 10); //=> [-10, -20, -30, -40, -50]\n\t     */\n\t    var unfold = _curry2(function unfold(fn, seed) {\n\t        var pair = fn(seed);\n\t        var result = [];\n\t        while (pair && pair.length) {\n\t            result[result.length] = pair[0];\n\t            pair = fn(pair[1]);\n\t        }\n\t        return result;\n\t    });\n\n\t    /**\n\t     * Returns a new list containing only one copy of each element in the original\n\t     * list, based upon the value returned by applying the supplied predicate to\n\t     * two list elements. Prefers the first item if two items compare equal based\n\t     * on the predicate.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.2.0\n\t     * @category List\n\t     * @sig (a, a -> Boolean) -> [a] -> [a]\n\t     * @param {Function} pred A predicate used to test whether two items are equal.\n\t     * @param {Array} list The array to consider.\n\t     * @return {Array} The list of unique items.\n\t     * @example\n\t     *\n\t     *      var strEq = R.eqBy(String);\n\t     *      R.uniqWith(strEq)([1, '1', 2, 1]); //=> [1, 2]\n\t     *      R.uniqWith(strEq)([{}, {}]);       //=> [{}]\n\t     *      R.uniqWith(strEq)([1, '1', 1]);    //=> [1]\n\t     *      R.uniqWith(strEq)(['1', 1, 1]);    //=> ['1']\n\t     */\n\t    var uniqWith = _curry2(function uniqWith(pred, list) {\n\t        var idx = 0;\n\t        var len = list.length;\n\t        var result = [];\n\t        var item;\n\t        while (idx < len) {\n\t            item = list[idx];\n\t            if (!_containsWith(pred, item, result)) {\n\t                result[result.length] = item;\n\t            }\n\t            idx += 1;\n\t        }\n\t        return result;\n\t    });\n\n\t    /**\n\t     * Tests the final argument by passing it to the given predicate function. If\n\t     * the predicate is not satisfied, the function will return the result of\n\t     * calling the `whenFalseFn` function with the same argument. If the predicate\n\t     * is satisfied, the argument is returned as is.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.18.0\n\t     * @category Logic\n\t     * @sig (a -> Boolean) -> (a -> a) -> a -> a\n\t     * @param {Function} pred        A predicate function\n\t     * @param {Function} whenFalseFn A function to invoke when the `pred` evaluates\n\t     *                               to a falsy value.\n\t     * @param {*}        x           An object to test with the `pred` function and\n\t     *                               pass to `whenFalseFn` if necessary.\n\t     * @return {*} Either `x` or the result of applying `x` to `whenFalseFn`.\n\t     * @see R.ifElse, R.when\n\t     * @example\n\t     *\n\t     *      // coerceArray :: (a|[a]) -> [a]\n\t     *      var coerceArray = R.unless(R.isArrayLike, R.of);\n\t     *      coerceArray([1, 2, 3]); //=> [1, 2, 3]\n\t     *      coerceArray(1);         //=> [1]\n\t     */\n\t    var unless = _curry3(function unless(pred, whenFalseFn, x) {\n\t        return pred(x) ? x : whenFalseFn(x);\n\t    });\n\n\t    /**\n\t     * Takes a predicate, a transformation function, and an initial value,\n\t     * and returns a value of the same type as the initial value.\n\t     * It does so by applying the transformation until the predicate is satisfied,\n\t     * at which point it returns the satisfactory value.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.20.0\n\t     * @category Logic\n\t     * @sig (a -> Boolean) -> (a -> a) -> a -> a\n\t     * @param {Function} pred A predicate function\n\t     * @param {Function} fn The iterator function\n\t     * @param {*} init Initial value\n\t     * @return {*} Final value that satisfies predicate\n\t     * @example\n\t     *\n\t     *      R.until(R.gt(R.__, 100), R.multiply(2))(1) // => 128\n\t     */\n\t    var until = _curry3(function until(pred, fn, init) {\n\t        var val = init;\n\t        while (!pred(val)) {\n\t            val = fn(val);\n\t        }\n\t        return val;\n\t    });\n\n\t    /**\n\t     * Returns a new copy of the array with the element at the provided index\n\t     * replaced with the given value.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.14.0\n\t     * @category List\n\t     * @sig Number -> a -> [a] -> [a]\n\t     * @param {Number} idx The index to update.\n\t     * @param {*} x The value to exist at the given index of the returned array.\n\t     * @param {Array|Arguments} list The source array-like object to be updated.\n\t     * @return {Array} A copy of `list` with the value at index `idx` replaced with `x`.\n\t     * @see R.adjust\n\t     * @example\n\t     *\n\t     *      R.update(1, 11, [0, 1, 2]);     //=> [0, 11, 2]\n\t     *      R.update(1)(11)([0, 1, 2]);     //=> [0, 11, 2]\n\t     */\n\t    var update = _curry3(function update(idx, x, list) {\n\t        return adjust(always(x), idx, list);\n\t    });\n\n\t    /**\n\t     * Accepts a function `fn` and a list of transformer functions and returns a\n\t     * new curried function. When the new function is invoked, it calls the\n\t     * function `fn` with parameters consisting of the result of calling each\n\t     * supplied handler on successive arguments to the new function.\n\t     *\n\t     * If more arguments are passed to the returned function than transformer\n\t     * functions, those arguments are passed directly to `fn` as additional\n\t     * parameters. If you expect additional arguments that don't need to be\n\t     * transformed, although you can ignore them, it's best to pass an identity\n\t     * function so that the new function reports the correct arity.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Function\n\t     * @sig (x1 -> x2 -> ... -> z) -> [(a -> x1), (b -> x2), ...] -> (a -> b -> ... -> z)\n\t     * @param {Function} fn The function to wrap.\n\t     * @param {Array} transformers A list of transformer functions\n\t     * @return {Function} The wrapped function.\n\t     * @example\n\t     *\n\t     *      R.useWith(Math.pow, [R.identity, R.identity])(3, 4); //=> 81\n\t     *      R.useWith(Math.pow, [R.identity, R.identity])(3)(4); //=> 81\n\t     *      R.useWith(Math.pow, [R.dec, R.inc])(3, 4); //=> 32\n\t     *      R.useWith(Math.pow, [R.dec, R.inc])(3)(4); //=> 32\n\t     */\n\t    var useWith = _curry2(function useWith(fn, transformers) {\n\t        return curryN(transformers.length, function () {\n\t            var args = [];\n\t            var idx = 0;\n\t            while (idx < transformers.length) {\n\t                args.push(transformers[idx].call(this, arguments[idx]));\n\t                idx += 1;\n\t            }\n\t            return fn.apply(this, args.concat(_slice(arguments, transformers.length)));\n\t        });\n\t    });\n\n\t    /**\n\t     * Returns a list of all the enumerable own properties of the supplied object.\n\t     * Note that the order of the output array is not guaranteed across different\n\t     * JS platforms.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Object\n\t     * @sig {k: v} -> [v]\n\t     * @param {Object} obj The object to extract values from\n\t     * @return {Array} An array of the values of the object's own properties.\n\t     * @example\n\t     *\n\t     *      R.values({a: 1, b: 2, c: 3}); //=> [1, 2, 3]\n\t     */\n\t    var values = _curry1(function values(obj) {\n\t        var props = keys(obj);\n\t        var len = props.length;\n\t        var vals = [];\n\t        var idx = 0;\n\t        while (idx < len) {\n\t            vals[idx] = obj[props[idx]];\n\t            idx += 1;\n\t        }\n\t        return vals;\n\t    });\n\n\t    /**\n\t     * Returns a list of all the properties, including prototype properties, of the\n\t     * supplied object.\n\t     * Note that the order of the output array is not guaranteed to be consistent\n\t     * across different JS platforms.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.2.0\n\t     * @category Object\n\t     * @sig {k: v} -> [v]\n\t     * @param {Object} obj The object to extract values from\n\t     * @return {Array} An array of the values of the object's own and prototype properties.\n\t     * @example\n\t     *\n\t     *      var F = function() { this.x = 'X'; };\n\t     *      F.prototype.y = 'Y';\n\t     *      var f = new F();\n\t     *      R.valuesIn(f); //=> ['X', 'Y']\n\t     */\n\t    var valuesIn = _curry1(function valuesIn(obj) {\n\t        var prop;\n\t        var vs = [];\n\t        for (prop in obj) {\n\t            vs[vs.length] = obj[prop];\n\t        }\n\t        return vs;\n\t    });\n\n\t    /**\n\t     * Returns a \"view\" of the given data structure, determined by the given lens.\n\t     * The lens's focus determines which portion of the data structure is visible.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.16.0\n\t     * @category Object\n\t     * @typedefn Lens s a = Functor f => (a -> f a) -> s -> f s\n\t     * @sig Lens s a -> s -> a\n\t     * @param {Lens} lens\n\t     * @param {*} x\n\t     * @return {*}\n\t     * @see R.prop, R.lensIndex, R.lensProp\n\t     * @example\n\t     *\n\t     *      var xLens = R.lensProp('x');\n\t     *\n\t     *      R.view(xLens, {x: 1, y: 2});  //=> 1\n\t     *      R.view(xLens, {x: 4, y: 2});  //=> 4\n\t     */\n\t    // `Const` is a functor that effectively ignores the function given to `map`.\n\t    // Using `Const` effectively ignores the setter function of the `lens`,\n\t    // leaving the value returned by the getter function unmodified.\n\t    var view = function () {\n\t        // `Const` is a functor that effectively ignores the function given to `map`.\n\t        var Const = function (x) {\n\t            return {\n\t                value: x,\n\t                map: function () {\n\t                    return this;\n\t                }\n\t            };\n\t        };\n\t        return _curry2(function view(lens, x) {\n\t            // Using `Const` effectively ignores the setter function of the `lens`,\n\t            // leaving the value returned by the getter function unmodified.\n\t            return lens(Const)(x).value;\n\t        });\n\t    }();\n\n\t    /**\n\t     * Tests the final argument by passing it to the given predicate function. If\n\t     * the predicate is satisfied, the function will return the result of calling\n\t     * the `whenTrueFn` function with the same argument. If the predicate is not\n\t     * satisfied, the argument is returned as is.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.18.0\n\t     * @category Logic\n\t     * @sig (a -> Boolean) -> (a -> a) -> a -> a\n\t     * @param {Function} pred       A predicate function\n\t     * @param {Function} whenTrueFn A function to invoke when the `condition`\n\t     *                              evaluates to a truthy value.\n\t     * @param {*}        x          An object to test with the `pred` function and\n\t     *                              pass to `whenTrueFn` if necessary.\n\t     * @return {*} Either `x` or the result of applying `x` to `whenTrueFn`.\n\t     * @see R.ifElse, R.unless\n\t     * @example\n\t     *\n\t     *      // truncate :: String -> String\n\t     *      var truncate = R.when(\n\t     *        R.propSatisfies(R.gt(R.__, 10), 'length'),\n\t     *        R.pipe(R.take(10), R.append('…'), R.join(''))\n\t     *      );\n\t     *      truncate('12345');         //=> '12345'\n\t     *      truncate('0123456789ABC'); //=> '0123456789…'\n\t     */\n\t    var when = _curry3(function when(pred, whenTrueFn, x) {\n\t        return pred(x) ? whenTrueFn(x) : x;\n\t    });\n\n\t    /**\n\t     * Takes a spec object and a test object; returns true if the test satisfies\n\t     * the spec. Each of the spec's own properties must be a predicate function.\n\t     * Each predicate is applied to the value of the corresponding property of the\n\t     * test object. `where` returns true if all the predicates return true, false\n\t     * otherwise.\n\t     *\n\t     * `where` is well suited to declaratively expressing constraints for other\n\t     * functions such as `filter` and `find`.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.1\n\t     * @category Object\n\t     * @sig {String: (* -> Boolean)} -> {String: *} -> Boolean\n\t     * @param {Object} spec\n\t     * @param {Object} testObj\n\t     * @return {Boolean}\n\t     * @example\n\t     *\n\t     *      // pred :: Object -> Boolean\n\t     *      var pred = where({\n\t     *        a: equals('foo'),\n\t     *        b: complement(equals('bar')),\n\t     *        x: gt(__, 10),\n\t     *        y: lt(__, 20)\n\t     *      });\n\t     *\n\t     *      pred({a: 'foo', b: 'xxx', x: 11, y: 19}); //=> true\n\t     *      pred({a: 'xxx', b: 'xxx', x: 11, y: 19}); //=> false\n\t     *      pred({a: 'foo', b: 'bar', x: 11, y: 19}); //=> false\n\t     *      pred({a: 'foo', b: 'xxx', x: 10, y: 19}); //=> false\n\t     *      pred({a: 'foo', b: 'xxx', x: 11, y: 20}); //=> false\n\t     */\n\t    var where = _curry2(function where(spec, testObj) {\n\t        for (var prop in spec) {\n\t            if (_has(prop, spec) && !spec[prop](testObj[prop])) {\n\t                return false;\n\t            }\n\t        }\n\t        return true;\n\t    });\n\n\t    /**\n\t     * Wrap a function inside another to allow you to make adjustments to the\n\t     * parameters, or do other processing either before the internal function is\n\t     * called or with its results.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Function\n\t     * @sig (a... -> b) -> ((a... -> b) -> a... -> c) -> (a... -> c)\n\t     * @param {Function} fn The function to wrap.\n\t     * @param {Function} wrapper The wrapper function.\n\t     * @return {Function} The wrapped function.\n\t     * @deprecated since v0.22.0\n\t     * @example\n\t     *\n\t     *      var greet = name => 'Hello ' + name;\n\t     *\n\t     *      var shoutedGreet = R.wrap(greet, (gr, name) => gr(name).toUpperCase());\n\t     *\n\t     *      shoutedGreet(\"Kathy\"); //=> \"HELLO KATHY\"\n\t     *\n\t     *      var shortenedGreet = R.wrap(greet, function(gr, name) {\n\t     *        return gr(name.substring(0, 3));\n\t     *      });\n\t     *      shortenedGreet(\"Robert\"); //=> \"Hello Rob\"\n\t     */\n\t    var wrap = _curry2(function wrap(fn, wrapper) {\n\t        return curryN(fn.length, function () {\n\t            return wrapper.apply(this, _concat([fn], arguments));\n\t        });\n\t    });\n\n\t    /**\n\t     * Creates a new list out of the two supplied by creating each possible pair\n\t     * from the lists.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig [a] -> [b] -> [[a,b]]\n\t     * @param {Array} as The first list.\n\t     * @param {Array} bs The second list.\n\t     * @return {Array} The list made by combining each possible pair from\n\t     *         `as` and `bs` into pairs (`[a, b]`).\n\t     * @example\n\t     *\n\t     *      R.xprod([1, 2], ['a', 'b']); //=> [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']]\n\t     */\n\t    // = xprodWith(prepend); (takes about 3 times as long...)\n\t    var xprod = _curry2(function xprod(a, b) {\n\t        // = xprodWith(prepend); (takes about 3 times as long...)\n\t        var idx = 0;\n\t        var ilen = a.length;\n\t        var j;\n\t        var jlen = b.length;\n\t        var result = [];\n\t        while (idx < ilen) {\n\t            j = 0;\n\t            while (j < jlen) {\n\t                result[result.length] = [\n\t                    a[idx],\n\t                    b[j]\n\t                ];\n\t                j += 1;\n\t            }\n\t            idx += 1;\n\t        }\n\t        return result;\n\t    });\n\n\t    /**\n\t     * Creates a new list out of the two supplied by pairing up equally-positioned\n\t     * items from both lists. The returned list is truncated to the length of the\n\t     * shorter of the two input lists.\n\t     * Note: `zip` is equivalent to `zipWith(function(a, b) { return [a, b] })`.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig [a] -> [b] -> [[a,b]]\n\t     * @param {Array} list1 The first array to consider.\n\t     * @param {Array} list2 The second array to consider.\n\t     * @return {Array} The list made by pairing up same-indexed elements of `list1` and `list2`.\n\t     * @example\n\t     *\n\t     *      R.zip([1, 2, 3], ['a', 'b', 'c']); //=> [[1, 'a'], [2, 'b'], [3, 'c']]\n\t     */\n\t    var zip = _curry2(function zip(a, b) {\n\t        var rv = [];\n\t        var idx = 0;\n\t        var len = Math.min(a.length, b.length);\n\t        while (idx < len) {\n\t            rv[idx] = [\n\t                a[idx],\n\t                b[idx]\n\t            ];\n\t            idx += 1;\n\t        }\n\t        return rv;\n\t    });\n\n\t    /**\n\t     * Creates a new object out of a list of keys and a list of values.\n\t     * Key/value pairing is truncated to the length of the shorter of the two lists.\n\t     * Note: `zipObj` is equivalent to `pipe(zipWith(pair), fromPairs)`.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.3.0\n\t     * @category List\n\t     * @sig [String] -> [*] -> {String: *}\n\t     * @param {Array} keys The array that will be properties on the output object.\n\t     * @param {Array} values The list of values on the output object.\n\t     * @return {Object} The object made by pairing up same-indexed elements of `keys` and `values`.\n\t     * @example\n\t     *\n\t     *      R.zipObj(['a', 'b', 'c'], [1, 2, 3]); //=> {a: 1, b: 2, c: 3}\n\t     */\n\t    var zipObj = _curry2(function zipObj(keys, values) {\n\t        var idx = 0;\n\t        var len = Math.min(keys.length, values.length);\n\t        var out = {};\n\t        while (idx < len) {\n\t            out[keys[idx]] = values[idx];\n\t            idx += 1;\n\t        }\n\t        return out;\n\t    });\n\n\t    /**\n\t     * Creates a new list out of the two supplied by applying the function to each\n\t     * equally-positioned pair in the lists. The returned list is truncated to the\n\t     * length of the shorter of the two input lists.\n\t     *\n\t     * @function\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig (a,b -> c) -> [a] -> [b] -> [c]\n\t     * @param {Function} fn The function used to combine the two elements into one value.\n\t     * @param {Array} list1 The first array to consider.\n\t     * @param {Array} list2 The second array to consider.\n\t     * @return {Array} The list made by combining same-indexed elements of `list1` and `list2`\n\t     *         using `fn`.\n\t     * @example\n\t     *\n\t     *      var f = (x, y) => {\n\t     *        // ...\n\t     *      };\n\t     *      R.zipWith(f, [1, 2, 3], ['a', 'b', 'c']);\n\t     *      //=> [f(1, 'a'), f(2, 'b'), f(3, 'c')]\n\t     */\n\t    var zipWith = _curry3(function zipWith(fn, a, b) {\n\t        var rv = [];\n\t        var idx = 0;\n\t        var len = Math.min(a.length, b.length);\n\t        while (idx < len) {\n\t            rv[idx] = fn(a[idx], b[idx]);\n\t            idx += 1;\n\t        }\n\t        return rv;\n\t    });\n\n\t    /**\n\t     * A function that always returns `false`. Any passed in parameters are ignored.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.9.0\n\t     * @category Function\n\t     * @sig * -> Boolean\n\t     * @param {*}\n\t     * @return {Boolean}\n\t     * @see R.always, R.T\n\t     * @example\n\t     *\n\t     *      R.F(); //=> false\n\t     */\n\t    var F = always(false);\n\n\t    /**\n\t     * A function that always returns `true`. Any passed in parameters are ignored.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.9.0\n\t     * @category Function\n\t     * @sig * -> Boolean\n\t     * @param {*}\n\t     * @return {Boolean}\n\t     * @see R.always, R.F\n\t     * @example\n\t     *\n\t     *      R.T(); //=> true\n\t     */\n\t    var T = always(true);\n\n\t    /**\n\t     * Copies an object.\n\t     *\n\t     * @private\n\t     * @param {*} value The value to be copied\n\t     * @param {Array} refFrom Array containing the source references\n\t     * @param {Array} refTo Array containing the copied source references\n\t     * @param {Boolean} deep Whether or not to perform deep cloning.\n\t     * @return {*} The copied value.\n\t     */\n\t    var _clone = function _clone(value, refFrom, refTo, deep) {\n\t        var copy = function copy(copiedValue) {\n\t            var len = refFrom.length;\n\t            var idx = 0;\n\t            while (idx < len) {\n\t                if (value === refFrom[idx]) {\n\t                    return refTo[idx];\n\t                }\n\t                idx += 1;\n\t            }\n\t            refFrom[idx + 1] = value;\n\t            refTo[idx + 1] = copiedValue;\n\t            for (var key in value) {\n\t                copiedValue[key] = deep ? _clone(value[key], refFrom, refTo, true) : value[key];\n\t            }\n\t            return copiedValue;\n\t        };\n\t        switch (type(value)) {\n\t        case 'Object':\n\t            return copy({});\n\t        case 'Array':\n\t            return copy([]);\n\t        case 'Date':\n\t            return new Date(value.valueOf());\n\t        case 'RegExp':\n\t            return _cloneRegExp(value);\n\t        default:\n\t            return value;\n\t        }\n\t    };\n\n\t    var _createPartialApplicator = function _createPartialApplicator(concat) {\n\t        return _curry2(function (fn, args) {\n\t            return _arity(Math.max(0, fn.length - args.length), function () {\n\t                return fn.apply(this, concat(args, arguments));\n\t            });\n\t        });\n\t    };\n\n\t    var _dropLast = function dropLast(n, xs) {\n\t        return take(n < xs.length ? xs.length - n : 0, xs);\n\t    };\n\n\t    // Values of other types are only equal if identical.\n\t    var _equals = function _equals(a, b, stackA, stackB) {\n\t        if (identical(a, b)) {\n\t            return true;\n\t        }\n\t        if (type(a) !== type(b)) {\n\t            return false;\n\t        }\n\t        if (a == null || b == null) {\n\t            return false;\n\t        }\n\t        if (typeof a.equals === 'function' || typeof b.equals === 'function') {\n\t            return typeof a.equals === 'function' && a.equals(b) && typeof b.equals === 'function' && b.equals(a);\n\t        }\n\t        switch (type(a)) {\n\t        case 'Arguments':\n\t        case 'Array':\n\t        case 'Object':\n\t            if (typeof a.constructor === 'function' && _functionName(a.constructor) === 'Promise') {\n\t                return a === b;\n\t            }\n\t            break;\n\t        case 'Boolean':\n\t        case 'Number':\n\t        case 'String':\n\t            if (!(typeof a === typeof b && identical(a.valueOf(), b.valueOf()))) {\n\t                return false;\n\t            }\n\t            break;\n\t        case 'Date':\n\t            if (!identical(a.valueOf(), b.valueOf())) {\n\t                return false;\n\t            }\n\t            break;\n\t        case 'Error':\n\t            return a.name === b.name && a.message === b.message;\n\t        case 'RegExp':\n\t            if (!(a.source === b.source && a.global === b.global && a.ignoreCase === b.ignoreCase && a.multiline === b.multiline && a.sticky === b.sticky && a.unicode === b.unicode)) {\n\t                return false;\n\t            }\n\t            break;\n\t        case 'Map':\n\t        case 'Set':\n\t            if (!_equals(_arrayFromIterator(a.entries()), _arrayFromIterator(b.entries()), stackA, stackB)) {\n\t                return false;\n\t            }\n\t            break;\n\t        case 'Int8Array':\n\t        case 'Uint8Array':\n\t        case 'Uint8ClampedArray':\n\t        case 'Int16Array':\n\t        case 'Uint16Array':\n\t        case 'Int32Array':\n\t        case 'Uint32Array':\n\t        case 'Float32Array':\n\t        case 'Float64Array':\n\t            break;\n\t        case 'ArrayBuffer':\n\t            break;\n\t        default:\n\t            // Values of other types are only equal if identical.\n\t            return false;\n\t        }\n\t        var keysA = keys(a);\n\t        if (keysA.length !== keys(b).length) {\n\t            return false;\n\t        }\n\t        var idx = stackA.length - 1;\n\t        while (idx >= 0) {\n\t            if (stackA[idx] === a) {\n\t                return stackB[idx] === b;\n\t            }\n\t            idx -= 1;\n\t        }\n\t        stackA.push(a);\n\t        stackB.push(b);\n\t        idx = keysA.length - 1;\n\t        while (idx >= 0) {\n\t            var key = keysA[idx];\n\t            if (!(_has(key, b) && _equals(b[key], a[key], stackA, stackB))) {\n\t                return false;\n\t            }\n\t            idx -= 1;\n\t        }\n\t        stackA.pop();\n\t        stackB.pop();\n\t        return true;\n\t    };\n\n\t    /**\n\t     * `_makeFlat` is a helper function that returns a one-level or fully recursive\n\t     * function based on the flag passed in.\n\t     *\n\t     * @private\n\t     */\n\t    var _makeFlat = function _makeFlat(recursive) {\n\t        return function flatt(list) {\n\t            var value, jlen, j;\n\t            var result = [];\n\t            var idx = 0;\n\t            var ilen = list.length;\n\t            while (idx < ilen) {\n\t                if (isArrayLike(list[idx])) {\n\t                    value = recursive ? flatt(list[idx]) : list[idx];\n\t                    j = 0;\n\t                    jlen = value.length;\n\t                    while (j < jlen) {\n\t                        result[result.length] = value[j];\n\t                        j += 1;\n\t                    }\n\t                } else {\n\t                    result[result.length] = list[idx];\n\t                }\n\t                idx += 1;\n\t            }\n\t            return result;\n\t        };\n\t    };\n\n\t    var _reduce = function () {\n\t        function _arrayReduce(xf, acc, list) {\n\t            var idx = 0;\n\t            var len = list.length;\n\t            while (idx < len) {\n\t                acc = xf['@@transducer/step'](acc, list[idx]);\n\t                if (acc && acc['@@transducer/reduced']) {\n\t                    acc = acc['@@transducer/value'];\n\t                    break;\n\t                }\n\t                idx += 1;\n\t            }\n\t            return xf['@@transducer/result'](acc);\n\t        }\n\t        function _iterableReduce(xf, acc, iter) {\n\t            var step = iter.next();\n\t            while (!step.done) {\n\t                acc = xf['@@transducer/step'](acc, step.value);\n\t                if (acc && acc['@@transducer/reduced']) {\n\t                    acc = acc['@@transducer/value'];\n\t                    break;\n\t                }\n\t                step = iter.next();\n\t            }\n\t            return xf['@@transducer/result'](acc);\n\t        }\n\t        function _methodReduce(xf, acc, obj) {\n\t            return xf['@@transducer/result'](obj.reduce(bind(xf['@@transducer/step'], xf), acc));\n\t        }\n\t        var symIterator = typeof Symbol !== 'undefined' ? Symbol.iterator : '@@iterator';\n\t        return function _reduce(fn, acc, list) {\n\t            if (typeof fn === 'function') {\n\t                fn = _xwrap(fn);\n\t            }\n\t            if (isArrayLike(list)) {\n\t                return _arrayReduce(fn, acc, list);\n\t            }\n\t            if (typeof list.reduce === 'function') {\n\t                return _methodReduce(fn, acc, list);\n\t            }\n\t            if (list[symIterator] != null) {\n\t                return _iterableReduce(fn, acc, list[symIterator]());\n\t            }\n\t            if (typeof list.next === 'function') {\n\t                return _iterableReduce(fn, acc, list);\n\t            }\n\t            throw new TypeError('reduce: list must be array or iterable');\n\t        };\n\t    }();\n\n\t    var _stepCat = function () {\n\t        var _stepCatArray = {\n\t            '@@transducer/init': Array,\n\t            '@@transducer/step': function (xs, x) {\n\t                xs.push(x);\n\t                return xs;\n\t            },\n\t            '@@transducer/result': _identity\n\t        };\n\t        var _stepCatString = {\n\t            '@@transducer/init': String,\n\t            '@@transducer/step': function (a, b) {\n\t                return a + b;\n\t            },\n\t            '@@transducer/result': _identity\n\t        };\n\t        var _stepCatObject = {\n\t            '@@transducer/init': Object,\n\t            '@@transducer/step': function (result, input) {\n\t                return _assign(result, isArrayLike(input) ? objOf(input[0], input[1]) : input);\n\t            },\n\t            '@@transducer/result': _identity\n\t        };\n\t        return function _stepCat(obj) {\n\t            if (_isTransformer(obj)) {\n\t                return obj;\n\t            }\n\t            if (isArrayLike(obj)) {\n\t                return _stepCatArray;\n\t            }\n\t            if (typeof obj === 'string') {\n\t                return _stepCatString;\n\t            }\n\t            if (typeof obj === 'object') {\n\t                return _stepCatObject;\n\t            }\n\t            throw new Error('Cannot create transformer for ' + obj);\n\t        };\n\t    }();\n\n\t    var _xdropLastWhile = function () {\n\t        function XDropLastWhile(fn, xf) {\n\t            this.f = fn;\n\t            this.retained = [];\n\t            this.xf = xf;\n\t        }\n\t        XDropLastWhile.prototype['@@transducer/init'] = _xfBase.init;\n\t        XDropLastWhile.prototype['@@transducer/result'] = function (result) {\n\t            this.retained = null;\n\t            return this.xf['@@transducer/result'](result);\n\t        };\n\t        XDropLastWhile.prototype['@@transducer/step'] = function (result, input) {\n\t            return this.f(input) ? this.retain(result, input) : this.flush(result, input);\n\t        };\n\t        XDropLastWhile.prototype.flush = function (result, input) {\n\t            result = _reduce(this.xf['@@transducer/step'], result, this.retained);\n\t            this.retained = [];\n\t            return this.xf['@@transducer/step'](result, input);\n\t        };\n\t        XDropLastWhile.prototype.retain = function (result, input) {\n\t            this.retained.push(input);\n\t            return result;\n\t        };\n\t        return _curry2(function _xdropLastWhile(fn, xf) {\n\t            return new XDropLastWhile(fn, xf);\n\t        });\n\t    }();\n\n\t    /**\n\t     * Creates a new list iteration function from an existing one by adding two new\n\t     * parameters to its callback function: the current index, and the entire list.\n\t     *\n\t     * This would turn, for instance, Ramda's simple `map` function into one that\n\t     * more closely resembles `Array.prototype.map`. Note that this will only work\n\t     * for functions in which the iteration callback function is the first\n\t     * parameter, and where the list is the last parameter. (This latter might be\n\t     * unimportant if the list parameter is not used.)\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.15.0\n\t     * @category Function\n\t     * @category List\n\t     * @sig ((a ... -> b) ... -> [a] -> *) -> (a ..., Int, [a] -> b) ... -> [a] -> *)\n\t     * @param {Function} fn A list iteration function that does not pass index or list to its callback\n\t     * @return {Function} An altered list iteration function that passes (item, index, list) to its callback\n\t     * @example\n\t     *\n\t     *      var mapIndexed = R.addIndex(R.map);\n\t     *      mapIndexed((val, idx) => idx + '-' + val, ['f', 'o', 'o', 'b', 'a', 'r']);\n\t     *      //=> ['0-f', '1-o', '2-o', '3-b', '4-a', '5-r']\n\t     */\n\t    var addIndex = _curry1(function addIndex(fn) {\n\t        return curryN(fn.length, function () {\n\t            var idx = 0;\n\t            var origFn = arguments[0];\n\t            var list = arguments[arguments.length - 1];\n\t            var args = _slice(arguments);\n\t            args[0] = function () {\n\t                var result = origFn.apply(this, _concat(arguments, [\n\t                    idx,\n\t                    list\n\t                ]));\n\t                idx += 1;\n\t                return result;\n\t            };\n\t            return fn.apply(this, args);\n\t        });\n\t    });\n\n\t    /**\n\t     * Wraps a function of any arity (including nullary) in a function that accepts\n\t     * exactly 2 parameters. Any extraneous parameters will not be passed to the\n\t     * supplied function.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.2.0\n\t     * @category Function\n\t     * @sig (* -> c) -> (a, b -> c)\n\t     * @param {Function} fn The function to wrap.\n\t     * @return {Function} A new function wrapping `fn`. The new function is guaranteed to be of\n\t     *         arity 2.\n\t     * @example\n\t     *\n\t     *      var takesThreeArgs = function(a, b, c) {\n\t     *        return [a, b, c];\n\t     *      };\n\t     *      takesThreeArgs.length; //=> 3\n\t     *      takesThreeArgs(1, 2, 3); //=> [1, 2, 3]\n\t     *\n\t     *      var takesTwoArgs = R.binary(takesThreeArgs);\n\t     *      takesTwoArgs.length; //=> 2\n\t     *      // Only 2 arguments are passed to the wrapped function\n\t     *      takesTwoArgs(1, 2, 3); //=> [1, 2, undefined]\n\t     */\n\t    var binary = _curry1(function binary(fn) {\n\t        return nAry(2, fn);\n\t    });\n\n\t    /**\n\t     * Creates a deep copy of the value which may contain (nested) `Array`s and\n\t     * `Object`s, `Number`s, `String`s, `Boolean`s and `Date`s. `Function`s are not\n\t     * copied, but assigned by their reference.\n\t     *\n\t     * Dispatches to a `clone` method if present.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Object\n\t     * @sig {*} -> {*}\n\t     * @param {*} value The object or array to clone\n\t     * @return {*} A new object or array.\n\t     * @example\n\t     *\n\t     *      var objects = [{}, {}, {}];\n\t     *      var objectsClone = R.clone(objects);\n\t     *      objects[0] === objectsClone[0]; //=> false\n\t     */\n\t    var clone = _curry1(function clone(value) {\n\t        return value != null && typeof value.clone === 'function' ? value.clone() : _clone(value, [], [], true);\n\t    });\n\n\t    /**\n\t     * Returns a curried equivalent of the provided function. The curried function\n\t     * has two unusual capabilities. First, its arguments needn't be provided one\n\t     * at a time. If `f` is a ternary function and `g` is `R.curry(f)`, the\n\t     * following are equivalent:\n\t     *\n\t     *   - `g(1)(2)(3)`\n\t     *   - `g(1)(2, 3)`\n\t     *   - `g(1, 2)(3)`\n\t     *   - `g(1, 2, 3)`\n\t     *\n\t     * Secondly, the special placeholder value `R.__` may be used to specify\n\t     * \"gaps\", allowing partial application of any combination of arguments,\n\t     * regardless of their positions. If `g` is as above and `_` is `R.__`, the\n\t     * following are equivalent:\n\t     *\n\t     *   - `g(1, 2, 3)`\n\t     *   - `g(_, 2, 3)(1)`\n\t     *   - `g(_, _, 3)(1)(2)`\n\t     *   - `g(_, _, 3)(1, 2)`\n\t     *   - `g(_, 2)(1)(3)`\n\t     *   - `g(_, 2)(1, 3)`\n\t     *   - `g(_, 2)(_, 3)(1)`\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Function\n\t     * @sig (* -> a) -> (* -> a)\n\t     * @param {Function} fn The function to curry.\n\t     * @return {Function} A new, curried function.\n\t     * @see R.curryN\n\t     * @example\n\t     *\n\t     *      var addFourNumbers = (a, b, c, d) => a + b + c + d;\n\t     *\n\t     *      var curriedAddFourNumbers = R.curry(addFourNumbers);\n\t     *      var f = curriedAddFourNumbers(1, 2);\n\t     *      var g = f(3);\n\t     *      g(4); //=> 10\n\t     */\n\t    var curry = _curry1(function curry(fn) {\n\t        return curryN(fn.length, fn);\n\t    });\n\n\t    /**\n\t     * Returns all but the first `n` elements of the given list, string, or\n\t     * transducer/transformer (or object with a `drop` method).\n\t     *\n\t     * Dispatches to the `drop` method of the second argument, if present.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig Number -> [a] -> [a]\n\t     * @sig Number -> String -> String\n\t     * @param {Number} n\n\t     * @param {*} list\n\t     * @return {*}\n\t     * @see R.take, R.transduce\n\t     * @example\n\t     *\n\t     *      R.drop(1, ['foo', 'bar', 'baz']); //=> ['bar', 'baz']\n\t     *      R.drop(2, ['foo', 'bar', 'baz']); //=> ['baz']\n\t     *      R.drop(3, ['foo', 'bar', 'baz']); //=> []\n\t     *      R.drop(4, ['foo', 'bar', 'baz']); //=> []\n\t     *      R.drop(3, 'ramda');               //=> 'da'\n\t     */\n\t    var drop = _curry2(_dispatchable('drop', _xdrop, function drop(n, xs) {\n\t        return slice(Math.max(0, n), Infinity, xs);\n\t    }));\n\n\t    /**\n\t     * Returns a list containing all but the last `n` elements of the given `list`.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.16.0\n\t     * @category List\n\t     * @sig Number -> [a] -> [a]\n\t     * @sig Number -> String -> String\n\t     * @param {Number} n The number of elements of `xs` to skip.\n\t     * @param {Array} xs The collection to consider.\n\t     * @return {Array}\n\t     * @see R.takeLast\n\t     * @example\n\t     *\n\t     *      R.dropLast(1, ['foo', 'bar', 'baz']); //=> ['foo', 'bar']\n\t     *      R.dropLast(2, ['foo', 'bar', 'baz']); //=> ['foo']\n\t     *      R.dropLast(3, ['foo', 'bar', 'baz']); //=> []\n\t     *      R.dropLast(4, ['foo', 'bar', 'baz']); //=> []\n\t     *      R.dropLast(3, 'ramda');               //=> 'ra'\n\t     */\n\t    var dropLast = _curry2(_dispatchable('dropLast', _xdropLast, _dropLast));\n\n\t    /**\n\t     * Returns a new list excluding all the tailing elements of a given list which\n\t     * satisfy the supplied predicate function. It passes each value from the right\n\t     * to the supplied predicate function, skipping elements while the predicate\n\t     * function returns `true`. The predicate function is applied to one argument:\n\t     * *(value)*.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.16.0\n\t     * @category List\n\t     * @sig (a -> Boolean) -> [a] -> [a]\n\t     * @param {Function} fn The function called per iteration.\n\t     * @param {Array} list The collection to iterate over.\n\t     * @return {Array} A new array.\n\t     * @see R.takeLastWhile, R.addIndex\n\t     * @example\n\t     *\n\t     *      var lteThree = x => x <= 3;\n\t     *\n\t     *      R.dropLastWhile(lteThree, [1, 2, 3, 4, 3, 2, 1]); //=> [1, 2, 3, 4]\n\t     */\n\t    var dropLastWhile = _curry2(_dispatchable('dropLastWhile', _xdropLastWhile, _dropLastWhile));\n\n\t    /**\n\t     * Returns `true` if its arguments are equivalent, `false` otherwise. Handles\n\t     * cyclical data structures.\n\t     *\n\t     * Dispatches symmetrically to the `equals` methods of both arguments, if\n\t     * present.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.15.0\n\t     * @category Relation\n\t     * @sig a -> b -> Boolean\n\t     * @param {*} a\n\t     * @param {*} b\n\t     * @return {Boolean}\n\t     * @example\n\t     *\n\t     *      R.equals(1, 1); //=> true\n\t     *      R.equals(1, '1'); //=> false\n\t     *      R.equals([1, 2, 3], [1, 2, 3]); //=> true\n\t     *\n\t     *      var a = {}; a.v = a;\n\t     *      var b = {}; b.v = b;\n\t     *      R.equals(a, b); //=> true\n\t     */\n\t    var equals = _curry2(function equals(a, b) {\n\t        return _equals(a, b, [], []);\n\t    });\n\n\t    /**\n\t     * Takes a predicate and a \"filterable\", and returns a new filterable of the\n\t     * same type containing the members of the given filterable which satisfy the\n\t     * given predicate.\n\t     *\n\t     * Dispatches to the `filter` method of the second argument, if present.\n\t     *\n\t     * Acts as a transducer if a transformer is given in list position.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig Filterable f => (a -> Boolean) -> f a -> f a\n\t     * @param {Function} pred\n\t     * @param {Array} filterable\n\t     * @return {Array}\n\t     * @see R.reject, R.transduce, R.addIndex\n\t     * @example\n\t     *\n\t     *      var isEven = n => n % 2 === 0;\n\t     *\n\t     *      R.filter(isEven, [1, 2, 3, 4]); //=> [2, 4]\n\t     *\n\t     *      R.filter(isEven, {a: 1, b: 2, c: 3, d: 4}); //=> {b: 2, d: 4}\n\t     */\n\t    // else\n\t    var filter = _curry2(_dispatchable('filter', _xfilter, function (pred, filterable) {\n\t        return _isObject(filterable) ? _reduce(function (acc, key) {\n\t            if (pred(filterable[key])) {\n\t                acc[key] = filterable[key];\n\t            }\n\t            return acc;\n\t        }, {}, keys(filterable)) : // else\n\t        _filter(pred, filterable);\n\t    }));\n\n\t    /**\n\t     * Returns a new list by pulling every item out of it (and all its sub-arrays)\n\t     * and putting them in a new array, depth-first.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig [a] -> [b]\n\t     * @param {Array} list The array to consider.\n\t     * @return {Array} The flattened list.\n\t     * @see R.unnest\n\t     * @example\n\t     *\n\t     *      R.flatten([1, 2, [3, 4], 5, [6, [7, 8, [9, [10, 11], 12]]]]);\n\t     *      //=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]\n\t     */\n\t    var flatten = _curry1(_makeFlat(true));\n\n\t    /**\n\t     * Returns a new function much like the supplied one, except that the first two\n\t     * arguments' order is reversed.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Function\n\t     * @sig (a -> b -> c -> ... -> z) -> (b -> a -> c -> ... -> z)\n\t     * @param {Function} fn The function to invoke with its first two parameters reversed.\n\t     * @return {*} The result of invoking `fn` with its first two parameters' order reversed.\n\t     * @example\n\t     *\n\t     *      var mergeThree = (a, b, c) => [].concat(a, b, c);\n\t     *\n\t     *      mergeThree(1, 2, 3); //=> [1, 2, 3]\n\t     *\n\t     *      R.flip(mergeThree)(1, 2, 3); //=> [2, 1, 3]\n\t     */\n\t    var flip = _curry1(function flip(fn) {\n\t        return curry(function (a, b) {\n\t            var args = _slice(arguments);\n\t            args[0] = b;\n\t            args[1] = a;\n\t            return fn.apply(this, args);\n\t        });\n\t    });\n\n\t    /**\n\t     * Returns the first element of the given list or string. In some libraries\n\t     * this function is named `first`.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig [a] -> a | Undefined\n\t     * @sig String -> String\n\t     * @param {Array|String} list\n\t     * @return {*}\n\t     * @see R.tail, R.init, R.last\n\t     * @example\n\t     *\n\t     *      R.head(['fi', 'fo', 'fum']); //=> 'fi'\n\t     *      R.head([]); //=> undefined\n\t     *\n\t     *      R.head('abc'); //=> 'a'\n\t     *      R.head(''); //=> ''\n\t     */\n\t    var head = nth(0);\n\n\t    /**\n\t     * Returns all but the last element of the given list or string.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.9.0\n\t     * @category List\n\t     * @sig [a] -> [a]\n\t     * @sig String -> String\n\t     * @param {*} list\n\t     * @return {*}\n\t     * @see R.last, R.head, R.tail\n\t     * @example\n\t     *\n\t     *      R.init([1, 2, 3]);  //=> [1, 2]\n\t     *      R.init([1, 2]);     //=> [1]\n\t     *      R.init([1]);        //=> []\n\t     *      R.init([]);         //=> []\n\t     *\n\t     *      R.init('abc');  //=> 'ab'\n\t     *      R.init('ab');   //=> 'a'\n\t     *      R.init('a');    //=> ''\n\t     *      R.init('');     //=> ''\n\t     */\n\t    var init = slice(0, -1);\n\n\t    /**\n\t     * Combines two lists into a set (i.e. no duplicates) composed of those\n\t     * elements common to both lists. Duplication is determined according to the\n\t     * value returned by applying the supplied predicate to two list elements.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Relation\n\t     * @sig (a -> a -> Boolean) -> [*] -> [*] -> [*]\n\t     * @param {Function} pred A predicate function that determines whether\n\t     *        the two supplied elements are equal.\n\t     * @param {Array} list1 One list of items to compare\n\t     * @param {Array} list2 A second list of items to compare\n\t     * @return {Array} A new list containing those elements common to both lists.\n\t     * @see R.intersection\n\t     * @example\n\t     *\n\t     *      var buffaloSpringfield = [\n\t     *        {id: 824, name: 'Richie Furay'},\n\t     *        {id: 956, name: 'Dewey Martin'},\n\t     *        {id: 313, name: 'Bruce Palmer'},\n\t     *        {id: 456, name: 'Stephen Stills'},\n\t     *        {id: 177, name: 'Neil Young'}\n\t     *      ];\n\t     *      var csny = [\n\t     *        {id: 204, name: 'David Crosby'},\n\t     *        {id: 456, name: 'Stephen Stills'},\n\t     *        {id: 539, name: 'Graham Nash'},\n\t     *        {id: 177, name: 'Neil Young'}\n\t     *      ];\n\t     *\n\t     *      R.intersectionWith(R.eqBy(R.prop('id')), buffaloSpringfield, csny);\n\t     *      //=> [{id: 456, name: 'Stephen Stills'}, {id: 177, name: 'Neil Young'}]\n\t     */\n\t    var intersectionWith = _curry3(function intersectionWith(pred, list1, list2) {\n\t        var lookupList, filteredList;\n\t        if (list1.length > list2.length) {\n\t            lookupList = list1;\n\t            filteredList = list2;\n\t        } else {\n\t            lookupList = list2;\n\t            filteredList = list1;\n\t        }\n\t        var results = [];\n\t        var idx = 0;\n\t        while (idx < filteredList.length) {\n\t            if (_containsWith(pred, filteredList[idx], lookupList)) {\n\t                results[results.length] = filteredList[idx];\n\t            }\n\t            idx += 1;\n\t        }\n\t        return uniqWith(pred, results);\n\t    });\n\n\t    /**\n\t     * Transforms the items of the list with the transducer and appends the\n\t     * transformed items to the accumulator using an appropriate iterator function\n\t     * based on the accumulator type.\n\t     *\n\t     * The accumulator can be an array, string, object or a transformer. Iterated\n\t     * items will be appended to arrays and concatenated to strings. Objects will\n\t     * be merged directly or 2-item arrays will be merged as key, value pairs.\n\t     *\n\t     * The accumulator can also be a transformer object that provides a 2-arity\n\t     * reducing iterator function, step, 0-arity initial value function, init, and\n\t     * 1-arity result extraction function result. The step function is used as the\n\t     * iterator function in reduce. The result function is used to convert the\n\t     * final accumulator into the return type and in most cases is R.identity. The\n\t     * init function is used to provide the initial accumulator.\n\t     *\n\t     * The iteration is performed with R.reduce after initializing the transducer.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.12.0\n\t     * @category List\n\t     * @sig a -> (b -> b) -> [c] -> a\n\t     * @param {*} acc The initial accumulator value.\n\t     * @param {Function} xf The transducer function. Receives a transformer and returns a transformer.\n\t     * @param {Array} list The list to iterate over.\n\t     * @return {*} The final, accumulated value.\n\t     * @example\n\t     *\n\t     *      var numbers = [1, 2, 3, 4];\n\t     *      var transducer = R.compose(R.map(R.add(1)), R.take(2));\n\t     *\n\t     *      R.into([], transducer, numbers); //=> [2, 3]\n\t     *\n\t     *      var intoArray = R.into([]);\n\t     *      intoArray(transducer, numbers); //=> [2, 3]\n\t     */\n\t    var into = _curry3(function into(acc, xf, list) {\n\t        return _isTransformer(acc) ? _reduce(xf(acc), acc['@@transducer/init'](), list) : _reduce(xf(_stepCat(acc)), _clone(acc, [], [], false), list);\n\t    });\n\n\t    /**\n\t     * Same as R.invertObj, however this accounts for objects with duplicate values\n\t     * by putting the values into an array.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.9.0\n\t     * @category Object\n\t     * @sig {s: x} -> {x: [ s, ... ]}\n\t     * @param {Object} obj The object or array to invert\n\t     * @return {Object} out A new object with keys\n\t     * in an array.\n\t     * @example\n\t     *\n\t     *      var raceResultsByFirstName = {\n\t     *        first: 'alice',\n\t     *        second: 'jake',\n\t     *        third: 'alice',\n\t     *      };\n\t     *      R.invert(raceResultsByFirstName);\n\t     *      //=> { 'alice': ['first', 'third'], 'jake':['second'] }\n\t     */\n\t    var invert = _curry1(function invert(obj) {\n\t        var props = keys(obj);\n\t        var len = props.length;\n\t        var idx = 0;\n\t        var out = {};\n\t        while (idx < len) {\n\t            var key = props[idx];\n\t            var val = obj[key];\n\t            var list = _has(val, out) ? out[val] : out[val] = [];\n\t            list[list.length] = key;\n\t            idx += 1;\n\t        }\n\t        return out;\n\t    });\n\n\t    /**\n\t     * Returns a new object with the keys of the given object as values, and the\n\t     * values of the given object, which are coerced to strings, as keys. Note\n\t     * that the last key found is preferred when handling the same value.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.9.0\n\t     * @category Object\n\t     * @sig {s: x} -> {x: s}\n\t     * @param {Object} obj The object or array to invert\n\t     * @return {Object} out A new object\n\t     * @example\n\t     *\n\t     *      var raceResults = {\n\t     *        first: 'alice',\n\t     *        second: 'jake'\n\t     *      };\n\t     *      R.invertObj(raceResults);\n\t     *      //=> { 'alice': 'first', 'jake':'second' }\n\t     *\n\t     *      // Alternatively:\n\t     *      var raceResults = ['alice', 'jake'];\n\t     *      R.invertObj(raceResults);\n\t     *      //=> { 'alice': '0', 'jake':'1' }\n\t     */\n\t    var invertObj = _curry1(function invertObj(obj) {\n\t        var props = keys(obj);\n\t        var len = props.length;\n\t        var idx = 0;\n\t        var out = {};\n\t        while (idx < len) {\n\t            var key = props[idx];\n\t            out[obj[key]] = key;\n\t            idx += 1;\n\t        }\n\t        return out;\n\t    });\n\n\t    /**\n\t     * Returns `true` if the given value is its type's empty value; `false`\n\t     * otherwise.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Logic\n\t     * @sig a -> Boolean\n\t     * @param {*} x\n\t     * @return {Boolean}\n\t     * @see R.empty\n\t     * @example\n\t     *\n\t     *      R.isEmpty([1, 2, 3]);   //=> false\n\t     *      R.isEmpty([]);          //=> true\n\t     *      R.isEmpty('');          //=> true\n\t     *      R.isEmpty(null);        //=> false\n\t     *      R.isEmpty({});          //=> true\n\t     *      R.isEmpty({length: 0}); //=> false\n\t     */\n\t    var isEmpty = _curry1(function isEmpty(x) {\n\t        return x != null && equals(x, empty(x));\n\t    });\n\n\t    /**\n\t     * Returns the last element of the given list or string.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.4\n\t     * @category List\n\t     * @sig [a] -> a | Undefined\n\t     * @sig String -> String\n\t     * @param {*} list\n\t     * @return {*}\n\t     * @see R.init, R.head, R.tail\n\t     * @example\n\t     *\n\t     *      R.last(['fi', 'fo', 'fum']); //=> 'fum'\n\t     *      R.last([]); //=> undefined\n\t     *\n\t     *      R.last('abc'); //=> 'c'\n\t     *      R.last(''); //=> ''\n\t     */\n\t    var last = nth(-1);\n\n\t    /**\n\t     * Returns the position of the last occurrence of an item in an array, or -1 if\n\t     * the item is not included in the array. `R.equals` is used to determine\n\t     * equality.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig a -> [a] -> Number\n\t     * @param {*} target The item to find.\n\t     * @param {Array} xs The array to search in.\n\t     * @return {Number} the index of the target, or -1 if the target is not found.\n\t     * @see R.indexOf\n\t     * @example\n\t     *\n\t     *      R.lastIndexOf(3, [-1,3,3,0,1,2,3,4]); //=> 6\n\t     *      R.lastIndexOf(10, [1,2,3,4]); //=> -1\n\t     */\n\t    var lastIndexOf = _curry2(function lastIndexOf(target, xs) {\n\t        if (typeof xs.lastIndexOf === 'function' && !_isArray(xs)) {\n\t            return xs.lastIndexOf(target);\n\t        } else {\n\t            var idx = xs.length - 1;\n\t            while (idx >= 0) {\n\t                if (equals(xs[idx], target)) {\n\t                    return idx;\n\t                }\n\t                idx -= 1;\n\t            }\n\t            return -1;\n\t        }\n\t    });\n\n\t    /**\n\t     * Takes a function and\n\t     * a [functor](https://github.com/fantasyland/fantasy-land#functor),\n\t     * applies the function to each of the functor's values, and returns\n\t     * a functor of the same shape.\n\t     *\n\t     * Ramda provides suitable `map` implementations for `Array` and `Object`,\n\t     * so this function may be applied to `[1, 2, 3]` or `{x: 1, y: 2, z: 3}`.\n\t     *\n\t     * Dispatches to the `map` method of the second argument, if present.\n\t     *\n\t     * Acts as a transducer if a transformer is given in list position.\n\t     *\n\t     * Also treats functions as functors and will compose them together.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig Functor f => (a -> b) -> f a -> f b\n\t     * @param {Function} fn The function to be called on every element of the input `list`.\n\t     * @param {Array} list The list to be iterated over.\n\t     * @return {Array} The new list.\n\t     * @see R.transduce, R.addIndex\n\t     * @example\n\t     *\n\t     *      var double = x => x * 2;\n\t     *\n\t     *      R.map(double, [1, 2, 3]); //=> [2, 4, 6]\n\t     *\n\t     *      R.map(double, {x: 1, y: 2, z: 3}); //=> {x: 2, y: 4, z: 6}\n\t     */\n\t    var map = _curry2(_dispatchable('map', _xmap, function map(fn, functor) {\n\t        switch (Object.prototype.toString.call(functor)) {\n\t        case '[object Function]':\n\t            return curryN(functor.length, function () {\n\t                return fn.call(this, functor.apply(this, arguments));\n\t            });\n\t        case '[object Object]':\n\t            return _reduce(function (acc, key) {\n\t                acc[key] = fn(functor[key]);\n\t                return acc;\n\t            }, {}, keys(functor));\n\t        default:\n\t            return _map(fn, functor);\n\t        }\n\t    }));\n\n\t    /**\n\t     * An Object-specific version of `map`. The function is applied to three\n\t     * arguments: *(value, key, obj)*. If only the value is significant, use\n\t     * `map` instead.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.9.0\n\t     * @category Object\n\t     * @sig ((*, String, Object) -> *) -> Object -> Object\n\t     * @param {Function} fn\n\t     * @param {Object} obj\n\t     * @return {Object}\n\t     * @see R.map\n\t     * @example\n\t     *\n\t     *      var values = { x: 1, y: 2, z: 3 };\n\t     *      var prependKeyAndDouble = (num, key, obj) => key + (num * 2);\n\t     *\n\t     *      R.mapObjIndexed(prependKeyAndDouble, values); //=> { x: 'x2', y: 'y4', z: 'z6' }\n\t     */\n\t    var mapObjIndexed = _curry2(function mapObjIndexed(fn, obj) {\n\t        return _reduce(function (acc, key) {\n\t            acc[key] = fn(obj[key], key, obj);\n\t            return acc;\n\t        }, {}, keys(obj));\n\t    });\n\n\t    /**\n\t     * Creates a new object with the own properties of the two provided objects. If\n\t     * a key exists in both objects, the provided function is applied to the values\n\t     * associated with the key in each object, with the result being used as the\n\t     * value associated with the key in the returned object. The key will be\n\t     * excluded from the returned object if the resulting value is `undefined`.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.19.0\n\t     * @category Object\n\t     * @sig (a -> a -> a) -> {a} -> {a} -> {a}\n\t     * @param {Function} fn\n\t     * @param {Object} l\n\t     * @param {Object} r\n\t     * @return {Object}\n\t     * @see R.merge, R.mergeWithKey\n\t     * @example\n\t     *\n\t     *      R.mergeWith(R.concat,\n\t     *                  { a: true, values: [10, 20] },\n\t     *                  { b: true, values: [15, 35] });\n\t     *      //=> { a: true, b: true, values: [10, 20, 15, 35] }\n\t     */\n\t    var mergeWith = _curry3(function mergeWith(fn, l, r) {\n\t        return mergeWithKey(function (_, _l, _r) {\n\t            return fn(_l, _r);\n\t        }, l, r);\n\t    });\n\n\t    /**\n\t     * Takes a function `f` and a list of arguments, and returns a function `g`.\n\t     * When applied, `g` returns the result of applying `f` to the arguments\n\t     * provided initially followed by the arguments provided to `g`.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.10.0\n\t     * @category Function\n\t     * @sig ((a, b, c, ..., n) -> x) -> [a, b, c, ...] -> ((d, e, f, ..., n) -> x)\n\t     * @param {Function} f\n\t     * @param {Array} args\n\t     * @return {Function}\n\t     * @see R.partialRight\n\t     * @example\n\t     *\n\t     *      var multiply = (a, b) => a * b;\n\t     *      var double = R.partial(multiply, [2]);\n\t     *      double(2); //=> 4\n\t     *\n\t     *      var greet = (salutation, title, firstName, lastName) =>\n\t     *        salutation + ', ' + title + ' ' + firstName + ' ' + lastName + '!';\n\t     *\n\t     *      var sayHello = R.partial(greet, ['Hello']);\n\t     *      var sayHelloToMs = R.partial(sayHello, ['Ms.']);\n\t     *      sayHelloToMs('Jane', 'Jones'); //=> 'Hello, Ms. Jane Jones!'\n\t     */\n\t    var partial = _createPartialApplicator(_concat);\n\n\t    /**\n\t     * Takes a function `f` and a list of arguments, and returns a function `g`.\n\t     * When applied, `g` returns the result of applying `f` to the arguments\n\t     * provided to `g` followed by the arguments provided initially.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.10.0\n\t     * @category Function\n\t     * @sig ((a, b, c, ..., n) -> x) -> [d, e, f, ..., n] -> ((a, b, c, ...) -> x)\n\t     * @param {Function} f\n\t     * @param {Array} args\n\t     * @return {Function}\n\t     * @see R.partial\n\t     * @example\n\t     *\n\t     *      var greet = (salutation, title, firstName, lastName) =>\n\t     *        salutation + ', ' + title + ' ' + firstName + ' ' + lastName + '!';\n\t     *\n\t     *      var greetMsJaneJones = R.partialRight(greet, ['Ms.', 'Jane', 'Jones']);\n\t     *\n\t     *      greetMsJaneJones('Hello'); //=> 'Hello, Ms. Jane Jones!'\n\t     */\n\t    var partialRight = _createPartialApplicator(flip(_concat));\n\n\t    /**\n\t     * Determines whether a nested path on an object has a specific value, in\n\t     * `R.equals` terms. Most likely used to filter a list.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.7.0\n\t     * @category Relation\n\t     * @sig [String] -> * -> {String: *} -> Boolean\n\t     * @param {Array} path The path of the nested property to use\n\t     * @param {*} val The value to compare the nested property with\n\t     * @param {Object} obj The object to check the nested property in\n\t     * @return {Boolean} `true` if the value equals the nested object property,\n\t     *         `false` otherwise.\n\t     * @example\n\t     *\n\t     *      var user1 = { address: { zipCode: 90210 } };\n\t     *      var user2 = { address: { zipCode: 55555 } };\n\t     *      var user3 = { name: 'Bob' };\n\t     *      var users = [ user1, user2, user3 ];\n\t     *      var isFamous = R.pathEq(['address', 'zipCode'], 90210);\n\t     *      R.filter(isFamous, users); //=> [ user1 ]\n\t     */\n\t    var pathEq = _curry3(function pathEq(_path, val, obj) {\n\t        return equals(path(_path, obj), val);\n\t    });\n\n\t    /**\n\t     * Returns a new list by plucking the same named property off all objects in\n\t     * the list supplied.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig k -> [{k: v}] -> [v]\n\t     * @param {Number|String} key The key name to pluck off of each object.\n\t     * @param {Array} list The array to consider.\n\t     * @return {Array} The list of values for the given key.\n\t     * @see R.props\n\t     * @example\n\t     *\n\t     *      R.pluck('a')([{a: 1}, {a: 2}]); //=> [1, 2]\n\t     *      R.pluck(0)([[1, 2], [3, 4]]);   //=> [1, 3]\n\t     */\n\t    var pluck = _curry2(function pluck(p, list) {\n\t        return map(prop(p), list);\n\t    });\n\n\t    /**\n\t     * Reasonable analog to SQL `select` statement.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Object\n\t     * @category Relation\n\t     * @sig [k] -> [{k: v}] -> [{k: v}]\n\t     * @param {Array} props The property names to project\n\t     * @param {Array} objs The objects to query\n\t     * @return {Array} An array of objects with just the `props` properties.\n\t     * @example\n\t     *\n\t     *      var abby = {name: 'Abby', age: 7, hair: 'blond', grade: 2};\n\t     *      var fred = {name: 'Fred', age: 12, hair: 'brown', grade: 7};\n\t     *      var kids = [abby, fred];\n\t     *      R.project(['name', 'grade'], kids); //=> [{name: 'Abby', grade: 2}, {name: 'Fred', grade: 7}]\n\t     */\n\t    // passing `identity` gives correct arity\n\t    var project = useWith(_map, [\n\t        pickAll,\n\t        identity\n\t    ]);\n\n\t    /**\n\t     * Returns `true` if the specified object property is equal, in `R.equals`\n\t     * terms, to the given value; `false` otherwise.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Relation\n\t     * @sig String -> a -> Object -> Boolean\n\t     * @param {String} name\n\t     * @param {*} val\n\t     * @param {*} obj\n\t     * @return {Boolean}\n\t     * @see R.equals, R.propSatisfies\n\t     * @example\n\t     *\n\t     *      var abby = {name: 'Abby', age: 7, hair: 'blond'};\n\t     *      var fred = {name: 'Fred', age: 12, hair: 'brown'};\n\t     *      var rusty = {name: 'Rusty', age: 10, hair: 'brown'};\n\t     *      var alois = {name: 'Alois', age: 15, disposition: 'surly'};\n\t     *      var kids = [abby, fred, rusty, alois];\n\t     *      var hasBrownHair = R.propEq('hair', 'brown');\n\t     *      R.filter(hasBrownHair, kids); //=> [fred, rusty]\n\t     */\n\t    var propEq = _curry3(function propEq(name, val, obj) {\n\t        return equals(val, obj[name]);\n\t    });\n\n\t    /**\n\t     * Returns a single item by iterating through the list, successively calling\n\t     * the iterator function and passing it an accumulator value and the current\n\t     * value from the array, and then passing the result to the next call.\n\t     *\n\t     * The iterator function receives two values: *(acc, value)*. It may use\n\t     * `R.reduced` to shortcut the iteration.\n\t     *\n\t     * Note: `R.reduce` does not skip deleted or unassigned indices (sparse\n\t     * arrays), unlike the native `Array.prototype.reduce` method. For more details\n\t     * on this behavior, see:\n\t     * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#Description\n\t     *\n\t     * Dispatches to the `reduce` method of the third argument, if present.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig ((a, b) -> a) -> a -> [b] -> a\n\t     * @param {Function} fn The iterator function. Receives two values, the accumulator and the\n\t     *        current element from the array.\n\t     * @param {*} acc The accumulator value.\n\t     * @param {Array} list The list to iterate over.\n\t     * @return {*} The final, accumulated value.\n\t     * @see R.reduced, R.addIndex\n\t     * @example\n\t     *\n\t     *      var numbers = [1, 2, 3];\n\t     *      var plus = (a, b) => a + b;\n\t     *\n\t     *      R.reduce(plus, 10, numbers); //=> 16\n\t     */\n\t    var reduce = _curry3(_reduce);\n\n\t    /**\n\t     * Groups the elements of the list according to the result of calling\n\t     * the String-returning function `keyFn` on each element and reduces the elements\n\t     * of each group to a single value via the reducer function `valueFn`.\n\t     *\n\t     * This function is basically a more general `groupBy` function.\n\t     *\n\t     * Acts as a transducer if a transformer is given in list position.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.20.0\n\t     * @category List\n\t     * @sig ((a, b) -> a) -> a -> (b -> String) -> [b] -> {String: a}\n\t     * @param {Function} valueFn The function that reduces the elements of each group to a single\n\t     *        value. Receives two values, accumulator for a particular group and the current element.\n\t     * @param {*} acc The (initial) accumulator value for each group.\n\t     * @param {Function} keyFn The function that maps the list's element into a key.\n\t     * @param {Array} list The array to group.\n\t     * @return {Object} An object with the output of `keyFn` for keys, mapped to the output of\n\t     *         `valueFn` for elements which produced that key when passed to `keyFn`.\n\t     * @see R.groupBy, R.reduce\n\t     * @example\n\t     *\n\t     *      var reduceToNamesBy = R.reduceBy((acc, student) => acc.concat(student.name), []);\n\t     *      var namesByGrade = reduceToNamesBy(function(student) {\n\t     *        var score = student.score;\n\t     *        return score < 65 ? 'F' :\n\t     *               score < 70 ? 'D' :\n\t     *               score < 80 ? 'C' :\n\t     *               score < 90 ? 'B' : 'A';\n\t     *      });\n\t     *      var students = [{name: 'Lucy', score: 92},\n\t     *                      {name: 'Drew', score: 85},\n\t     *                      // ...\n\t     *                      {name: 'Bart', score: 62}];\n\t     *      namesByGrade(students);\n\t     *      // {\n\t     *      //   'A': ['Lucy'],\n\t     *      //   'B': ['Drew']\n\t     *      //   // ...,\n\t     *      //   'F': ['Bart']\n\t     *      // }\n\t     */\n\t    var reduceBy = _curryN(4, [], _dispatchable('reduceBy', _xreduceBy, function reduceBy(valueFn, valueAcc, keyFn, list) {\n\t        return _reduce(function (acc, elt) {\n\t            var key = keyFn(elt);\n\t            acc[key] = valueFn(_has(key, acc) ? acc[key] : valueAcc, elt);\n\t            return acc;\n\t        }, {}, list);\n\t    }));\n\n\t    /**\n\t     * Like `reduce`, `reduceWhile` returns a single item by iterating through\n\t     * the list, successively calling the iterator function. `reduceWhile` also\n\t     * takes a predicate that is evaluated before each step. If the predicate returns\n\t     * `false`, it \"short-circuits\" the iteration and returns the current value\n\t     * of the accumulator.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.22.0\n\t     * @category List\n\t     * @sig ((a, b) -> Boolean) -> ((a, b) -> a) -> a -> [b] -> a\n\t     * @param {Function} pred The predicate. It is passed the accumulator and the\n\t     *        current element.\n\t     * @param {Function} fn The iterator function. Receives two values, the\n\t     *        accumulator and the current element.\n\t     * @param {*} a The accumulator value.\n\t     * @param {Array} list The list to iterate over.\n\t     * @return {*} The final, accumulated value.\n\t     * @see R.reduce, R.reduced\n\t     * @example\n\t     *\n\t     *      var isOdd = (acc, x) => x % 2 === 1;\n\t     *      var xs = [1, 3, 5, 60, 777, 800];\n\t     *      R.reduceWhile(isOdd, R.add, 0, xs); //=> 9\n\t     *\n\t     *      var ys = [2, 4, 6]\n\t     *      R.reduceWhile(isOdd, R.add, 111, ys); //=> 111\n\t     */\n\t    var reduceWhile = _curryN(4, [], function _reduceWhile(pred, fn, a, list) {\n\t        return _reduce(function (acc, x) {\n\t            return pred(acc, x) ? fn(acc, x) : _reduced(acc);\n\t        }, a, list);\n\t    });\n\n\t    /**\n\t     * The complement of `filter`.\n\t     *\n\t     * Acts as a transducer if a transformer is given in list position.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig Filterable f => (a -> Boolean) -> f a -> f a\n\t     * @param {Function} pred\n\t     * @param {Array} filterable\n\t     * @return {Array}\n\t     * @see R.filter, R.transduce, R.addIndex\n\t     * @example\n\t     *\n\t     *      var isOdd = (n) => n % 2 === 1;\n\t     *\n\t     *      R.reject(isOdd, [1, 2, 3, 4]); //=> [2, 4]\n\t     *\n\t     *      R.reject(isOdd, {a: 1, b: 2, c: 3, d: 4}); //=> {b: 2, d: 4}\n\t     */\n\t    var reject = _curry2(function reject(pred, filterable) {\n\t        return filter(_complement(pred), filterable);\n\t    });\n\n\t    /**\n\t     * Returns a fixed list of size `n` containing a specified identical value.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.1\n\t     * @category List\n\t     * @sig a -> n -> [a]\n\t     * @param {*} value The value to repeat.\n\t     * @param {Number} n The desired size of the output list.\n\t     * @return {Array} A new array containing `n` `value`s.\n\t     * @example\n\t     *\n\t     *      R.repeat('hi', 5); //=> ['hi', 'hi', 'hi', 'hi', 'hi']\n\t     *\n\t     *      var obj = {};\n\t     *      var repeatedObjs = R.repeat(obj, 5); //=> [{}, {}, {}, {}, {}]\n\t     *      repeatedObjs[0] === repeatedObjs[1]; //=> true\n\t     */\n\t    var repeat = _curry2(function repeat(value, n) {\n\t        return times(always(value), n);\n\t    });\n\n\t    /**\n\t     * Adds together all the elements of a list.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Math\n\t     * @sig [Number] -> Number\n\t     * @param {Array} list An array of numbers\n\t     * @return {Number} The sum of all the numbers in the list.\n\t     * @see R.reduce\n\t     * @example\n\t     *\n\t     *      R.sum([2,4,6,8,100,1]); //=> 121\n\t     */\n\t    var sum = reduce(add, 0);\n\n\t    /**\n\t     * Returns a new list containing the last `n` elements of the given list.\n\t     * If `n > list.length`, returns a list of `list.length` elements.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.16.0\n\t     * @category List\n\t     * @sig Number -> [a] -> [a]\n\t     * @sig Number -> String -> String\n\t     * @param {Number} n The number of elements to return.\n\t     * @param {Array} xs The collection to consider.\n\t     * @return {Array}\n\t     * @see R.dropLast\n\t     * @example\n\t     *\n\t     *      R.takeLast(1, ['foo', 'bar', 'baz']); //=> ['baz']\n\t     *      R.takeLast(2, ['foo', 'bar', 'baz']); //=> ['bar', 'baz']\n\t     *      R.takeLast(3, ['foo', 'bar', 'baz']); //=> ['foo', 'bar', 'baz']\n\t     *      R.takeLast(4, ['foo', 'bar', 'baz']); //=> ['foo', 'bar', 'baz']\n\t     *      R.takeLast(3, 'ramda');               //=> 'mda'\n\t     */\n\t    var takeLast = _curry2(function takeLast(n, xs) {\n\t        return drop(n >= 0 ? xs.length - n : 0, xs);\n\t    });\n\n\t    /**\n\t     * Initializes a transducer using supplied iterator function. Returns a single\n\t     * item by iterating through the list, successively calling the transformed\n\t     * iterator function and passing it an accumulator value and the current value\n\t     * from the array, and then passing the result to the next call.\n\t     *\n\t     * The iterator function receives two values: *(acc, value)*. It will be\n\t     * wrapped as a transformer to initialize the transducer. A transformer can be\n\t     * passed directly in place of an iterator function. In both cases, iteration\n\t     * may be stopped early with the `R.reduced` function.\n\t     *\n\t     * A transducer is a function that accepts a transformer and returns a\n\t     * transformer and can be composed directly.\n\t     *\n\t     * A transformer is an an object that provides a 2-arity reducing iterator\n\t     * function, step, 0-arity initial value function, init, and 1-arity result\n\t     * extraction function, result. The step function is used as the iterator\n\t     * function in reduce. The result function is used to convert the final\n\t     * accumulator into the return type and in most cases is R.identity. The init\n\t     * function can be used to provide an initial accumulator, but is ignored by\n\t     * transduce.\n\t     *\n\t     * The iteration is performed with R.reduce after initializing the transducer.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.12.0\n\t     * @category List\n\t     * @sig (c -> c) -> (a,b -> a) -> a -> [b] -> a\n\t     * @param {Function} xf The transducer function. Receives a transformer and returns a transformer.\n\t     * @param {Function} fn The iterator function. Receives two values, the accumulator and the\n\t     *        current element from the array. Wrapped as transformer, if necessary, and used to\n\t     *        initialize the transducer\n\t     * @param {*} acc The initial accumulator value.\n\t     * @param {Array} list The list to iterate over.\n\t     * @return {*} The final, accumulated value.\n\t     * @see R.reduce, R.reduced, R.into\n\t     * @example\n\t     *\n\t     *      var numbers = [1, 2, 3, 4];\n\t     *      var transducer = R.compose(R.map(R.add(1)), R.take(2));\n\t     *\n\t     *      R.transduce(transducer, R.flip(R.append), [], numbers); //=> [2, 3]\n\t     */\n\t    var transduce = curryN(4, function transduce(xf, fn, acc, list) {\n\t        return _reduce(xf(typeof fn === 'function' ? _xwrap(fn) : fn), acc, list);\n\t    });\n\n\t    /**\n\t     * Combines two lists into a set (i.e. no duplicates) composed of the elements\n\t     * of each list. Duplication is determined according to the value returned by\n\t     * applying the supplied predicate to two list elements.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Relation\n\t     * @sig (a -> a -> Boolean) -> [*] -> [*] -> [*]\n\t     * @param {Function} pred A predicate used to test whether two items are equal.\n\t     * @param {Array} list1 The first list.\n\t     * @param {Array} list2 The second list.\n\t     * @return {Array} The first and second lists concatenated, with\n\t     *         duplicates removed.\n\t     * @see R.union\n\t     * @example\n\t     *\n\t     *      var l1 = [{a: 1}, {a: 2}];\n\t     *      var l2 = [{a: 1}, {a: 4}];\n\t     *      R.unionWith(R.eqBy(R.prop('a')), l1, l2); //=> [{a: 1}, {a: 2}, {a: 4}]\n\t     */\n\t    var unionWith = _curry3(function unionWith(pred, list1, list2) {\n\t        return uniqWith(pred, _concat(list1, list2));\n\t    });\n\n\t    /**\n\t     * Takes a spec object and a test object; returns true if the test satisfies\n\t     * the spec, false otherwise. An object satisfies the spec if, for each of the\n\t     * spec's own properties, accessing that property of the object gives the same\n\t     * value (in `R.equals` terms) as accessing that property of the spec.\n\t     *\n\t     * `whereEq` is a specialization of [`where`](#where).\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.14.0\n\t     * @category Object\n\t     * @sig {String: *} -> {String: *} -> Boolean\n\t     * @param {Object} spec\n\t     * @param {Object} testObj\n\t     * @return {Boolean}\n\t     * @see R.where\n\t     * @example\n\t     *\n\t     *      // pred :: Object -> Boolean\n\t     *      var pred = R.whereEq({a: 1, b: 2});\n\t     *\n\t     *      pred({a: 1});              //=> false\n\t     *      pred({a: 1, b: 2});        //=> true\n\t     *      pred({a: 1, b: 2, c: 3});  //=> true\n\t     *      pred({a: 1, b: 1});        //=> false\n\t     */\n\t    var whereEq = _curry2(function whereEq(spec, testObj) {\n\t        return where(map(equals, spec), testObj);\n\t    });\n\n\t    var _flatCat = function () {\n\t        var preservingReduced = function (xf) {\n\t            return {\n\t                '@@transducer/init': _xfBase.init,\n\t                '@@transducer/result': function (result) {\n\t                    return xf['@@transducer/result'](result);\n\t                },\n\t                '@@transducer/step': function (result, input) {\n\t                    var ret = xf['@@transducer/step'](result, input);\n\t                    return ret['@@transducer/reduced'] ? _forceReduced(ret) : ret;\n\t                }\n\t            };\n\t        };\n\t        return function _xcat(xf) {\n\t            var rxf = preservingReduced(xf);\n\t            return {\n\t                '@@transducer/init': _xfBase.init,\n\t                '@@transducer/result': function (result) {\n\t                    return rxf['@@transducer/result'](result);\n\t                },\n\t                '@@transducer/step': function (result, input) {\n\t                    return !isArrayLike(input) ? _reduce(rxf, result, [input]) : _reduce(rxf, result, input);\n\t                }\n\t            };\n\t        };\n\t    }();\n\n\t    // Array.prototype.indexOf doesn't exist below IE9\n\t    // manually crawl the list to distinguish between +0 and -0\n\t    // NaN\n\t    // non-zero numbers can utilise Set\n\t    // all these types can utilise Set\n\t    // null can utilise Set\n\t    // anything else not covered above, defer to R.equals\n\t    var _indexOf = function _indexOf(list, a, idx) {\n\t        var inf, item;\n\t        // Array.prototype.indexOf doesn't exist below IE9\n\t        if (typeof list.indexOf === 'function') {\n\t            switch (typeof a) {\n\t            case 'number':\n\t                if (a === 0) {\n\t                    // manually crawl the list to distinguish between +0 and -0\n\t                    inf = 1 / a;\n\t                    while (idx < list.length) {\n\t                        item = list[idx];\n\t                        if (item === 0 && 1 / item === inf) {\n\t                            return idx;\n\t                        }\n\t                        idx += 1;\n\t                    }\n\t                    return -1;\n\t                } else if (a !== a) {\n\t                    // NaN\n\t                    while (idx < list.length) {\n\t                        item = list[idx];\n\t                        if (typeof item === 'number' && item !== item) {\n\t                            return idx;\n\t                        }\n\t                        idx += 1;\n\t                    }\n\t                    return -1;\n\t                }\n\t                // non-zero numbers can utilise Set\n\t                return list.indexOf(a, idx);\n\t            // all these types can utilise Set\n\t            case 'string':\n\t            case 'boolean':\n\t            case 'function':\n\t            case 'undefined':\n\t                return list.indexOf(a, idx);\n\t            case 'object':\n\t                if (a === null) {\n\t                    // null can utilise Set\n\t                    return list.indexOf(a, idx);\n\t                }\n\t            }\n\t        }\n\t        // anything else not covered above, defer to R.equals\n\t        while (idx < list.length) {\n\t            if (equals(list[idx], a)) {\n\t                return idx;\n\t            }\n\t            idx += 1;\n\t        }\n\t        return -1;\n\t    };\n\n\t    var _xchain = _curry2(function _xchain(f, xf) {\n\t        return map(f, _flatCat(xf));\n\t    });\n\n\t    /**\n\t     * Takes a list of predicates and returns a predicate that returns true for a\n\t     * given list of arguments if every one of the provided predicates is satisfied\n\t     * by those arguments.\n\t     *\n\t     * The function returned is a curried function whose arity matches that of the\n\t     * highest-arity predicate.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.9.0\n\t     * @category Logic\n\t     * @sig [(*... -> Boolean)] -> (*... -> Boolean)\n\t     * @param {Array} preds\n\t     * @return {Function}\n\t     * @see R.anyPass\n\t     * @example\n\t     *\n\t     *      var isQueen = R.propEq('rank', 'Q');\n\t     *      var isSpade = R.propEq('suit', '♠︎');\n\t     *      var isQueenOfSpades = R.allPass([isQueen, isSpade]);\n\t     *\n\t     *      isQueenOfSpades({rank: 'Q', suit: '♣︎'}); //=> false\n\t     *      isQueenOfSpades({rank: 'Q', suit: '♠︎'}); //=> true\n\t     */\n\t    var allPass = _curry1(function allPass(preds) {\n\t        return curryN(reduce(max, 0, pluck('length', preds)), function () {\n\t            var idx = 0;\n\t            var len = preds.length;\n\t            while (idx < len) {\n\t                if (!preds[idx].apply(this, arguments)) {\n\t                    return false;\n\t                }\n\t                idx += 1;\n\t            }\n\t            return true;\n\t        });\n\t    });\n\n\t    /**\n\t     * Takes a list of predicates and returns a predicate that returns true for a\n\t     * given list of arguments if at least one of the provided predicates is\n\t     * satisfied by those arguments.\n\t     *\n\t     * The function returned is a curried function whose arity matches that of the\n\t     * highest-arity predicate.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.9.0\n\t     * @category Logic\n\t     * @sig [(*... -> Boolean)] -> (*... -> Boolean)\n\t     * @param {Array} preds\n\t     * @return {Function}\n\t     * @see R.allPass\n\t     * @example\n\t     *\n\t     *      var gte = R.anyPass([R.gt, R.equals]);\n\t     *\n\t     *      gte(3, 2); //=> true\n\t     *      gte(2, 2); //=> true\n\t     *      gte(2, 3); //=> false\n\t     */\n\t    var anyPass = _curry1(function anyPass(preds) {\n\t        return curryN(reduce(max, 0, pluck('length', preds)), function () {\n\t            var idx = 0;\n\t            var len = preds.length;\n\t            while (idx < len) {\n\t                if (preds[idx].apply(this, arguments)) {\n\t                    return true;\n\t                }\n\t                idx += 1;\n\t            }\n\t            return false;\n\t        });\n\t    });\n\n\t    /**\n\t     * ap applies a list of functions to a list of values.\n\t     *\n\t     * Dispatches to the `ap` method of the second argument, if present. Also\n\t     * treats curried functions as applicatives.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.3.0\n\t     * @category Function\n\t     * @sig [a -> b] -> [a] -> [b]\n\t     * @sig Apply f => f (a -> b) -> f a -> f b\n\t     * @param {Array} fns An array of functions\n\t     * @param {Array} vs An array of values\n\t     * @return {Array} An array of results of applying each of `fns` to all of `vs` in turn.\n\t     * @example\n\t     *\n\t     *      R.ap([R.multiply(2), R.add(3)], [1,2,3]); //=> [2, 4, 6, 4, 5, 6]\n\t     */\n\t    // else\n\t    var ap = _curry2(function ap(applicative, fn) {\n\t        return typeof applicative.ap === 'function' ? applicative.ap(fn) : typeof applicative === 'function' ? function (x) {\n\t            return applicative(x)(fn(x));\n\t        } : // else\n\t        _reduce(function (acc, f) {\n\t            return _concat(acc, map(f, fn));\n\t        }, [], applicative);\n\t    });\n\n\t    /**\n\t     * Given a spec object recursively mapping properties to functions, creates a\n\t     * function producing an object of the same structure, by mapping each property\n\t     * to the result of calling its associated function with the supplied arguments.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.20.0\n\t     * @category Function\n\t     * @sig {k: ((a, b, ..., m) -> v)} -> ((a, b, ..., m) -> {k: v})\n\t     * @param {Object} spec an object recursively mapping properties to functions for\n\t     *        producing the values for these properties.\n\t     * @return {Function} A function that returns an object of the same structure\n\t     * as `spec', with each property set to the value returned by calling its\n\t     * associated function with the supplied arguments.\n\t     * @see R.converge, R.juxt\n\t     * @example\n\t     *\n\t     *      var getMetrics = R.applySpec({\n\t     *                                      sum: R.add,\n\t     *                                      nested: { mul: R.multiply }\n\t     *                                   });\n\t     *      getMetrics(2, 4); // => { sum: 6, nested: { mul: 8 } }\n\t     */\n\t    var applySpec = _curry1(function applySpec(spec) {\n\t        spec = map(function (v) {\n\t            return typeof v == 'function' ? v : applySpec(v);\n\t        }, spec);\n\t        return curryN(reduce(max, 0, pluck('length', values(spec))), function () {\n\t            var args = arguments;\n\t            return map(function (f) {\n\t                return apply(f, args);\n\t            }, spec);\n\t        });\n\t    });\n\n\t    /**\n\t     * Returns the result of calling its first argument with the remaining\n\t     * arguments. This is occasionally useful as a converging function for\n\t     * `R.converge`: the left branch can produce a function while the right branch\n\t     * produces a value to be passed to that function as an argument.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.9.0\n\t     * @category Function\n\t     * @sig (*... -> a),*... -> a\n\t     * @param {Function} fn The function to apply to the remaining arguments.\n\t     * @param {...*} args Any number of positional arguments.\n\t     * @return {*}\n\t     * @see R.apply\n\t     * @example\n\t     *\n\t     *      var indentN = R.pipe(R.times(R.always(' ')),\n\t     *                           R.join(''),\n\t     *                           R.replace(/^(?!$)/gm));\n\t     *\n\t     *      var format = R.converge(R.call, [\n\t     *                                  R.pipe(R.prop('indent'), indentN),\n\t     *                                  R.prop('value')\n\t     *                              ]);\n\t     *\n\t     *      format({indent: 2, value: 'foo\\nbar\\nbaz\\n'}); //=> '  foo\\n  bar\\n  baz\\n'\n\t     */\n\t    var call = curry(function call(fn) {\n\t        return fn.apply(this, _slice(arguments, 1));\n\t    });\n\n\t    /**\n\t     * `chain` maps a function over a list and concatenates the results. `chain`\n\t     * is also known as `flatMap` in some libraries\n\t     *\n\t     * Dispatches to the `chain` method of the second argument, if present,\n\t     * according to the [FantasyLand Chain spec](https://github.com/fantasyland/fantasy-land#chain).\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.3.0\n\t     * @category List\n\t     * @sig Chain m => (a -> m b) -> m a -> m b\n\t     * @param {Function} fn\n\t     * @param {Array} list\n\t     * @return {Array}\n\t     * @example\n\t     *\n\t     *      var duplicate = n => [n, n];\n\t     *      R.chain(duplicate, [1, 2, 3]); //=> [1, 1, 2, 2, 3, 3]\n\t     */\n\t    var chain = _curry2(_dispatchable('chain', _xchain, function chain(fn, monad) {\n\t        if (typeof monad === 'function') {\n\t            return function () {\n\t                return monad.call(this, fn.apply(this, arguments)).apply(this, arguments);\n\t            };\n\t        }\n\t        return _makeFlat(false)(map(fn, monad));\n\t    }));\n\n\t    /**\n\t     * Returns a function, `fn`, which encapsulates if/else-if/else logic.\n\t     * `R.cond` takes a list of [predicate, transform] pairs. All of the arguments\n\t     * to `fn` are applied to each of the predicates in turn until one returns a\n\t     * \"truthy\" value, at which point `fn` returns the result of applying its\n\t     * arguments to the corresponding transformer. If none of the predicates\n\t     * matches, `fn` returns undefined.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.6.0\n\t     * @category Logic\n\t     * @sig [[(*... -> Boolean),(*... -> *)]] -> (*... -> *)\n\t     * @param {Array} pairs\n\t     * @return {Function}\n\t     * @example\n\t     *\n\t     *      var fn = R.cond([\n\t     *        [R.equals(0),   R.always('water freezes at 0°C')],\n\t     *        [R.equals(100), R.always('water boils at 100°C')],\n\t     *        [R.T,           temp => 'nothing special happens at ' + temp + '°C']\n\t     *      ]);\n\t     *      fn(0); //=> 'water freezes at 0°C'\n\t     *      fn(50); //=> 'nothing special happens at 50°C'\n\t     *      fn(100); //=> 'water boils at 100°C'\n\t     */\n\t    var cond = _curry1(function cond(pairs) {\n\t        var arity = reduce(max, 0, map(function (pair) {\n\t            return pair[0].length;\n\t        }, pairs));\n\t        return _arity(arity, function () {\n\t            var idx = 0;\n\t            while (idx < pairs.length) {\n\t                if (pairs[idx][0].apply(this, arguments)) {\n\t                    return pairs[idx][1].apply(this, arguments);\n\t                }\n\t                idx += 1;\n\t            }\n\t        });\n\t    });\n\n\t    /**\n\t     * Wraps a constructor function inside a curried function that can be called\n\t     * with the same arguments and returns the same type. The arity of the function\n\t     * returned is specified to allow using variadic constructor functions.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.4.0\n\t     * @category Function\n\t     * @sig Number -> (* -> {*}) -> (* -> {*})\n\t     * @param {Number} n The arity of the constructor function.\n\t     * @param {Function} Fn The constructor function to wrap.\n\t     * @return {Function} A wrapped, curried constructor function.\n\t     * @example\n\t     *\n\t     *      // Variadic constructor function\n\t     *      var Widget = () => {\n\t     *        this.children = Array.prototype.slice.call(arguments);\n\t     *        // ...\n\t     *      };\n\t     *      Widget.prototype = {\n\t     *        // ...\n\t     *      };\n\t     *      var allConfigs = [\n\t     *        // ...\n\t     *      ];\n\t     *      R.map(R.constructN(1, Widget), allConfigs); // a list of Widgets\n\t     */\n\t    var constructN = _curry2(function constructN(n, Fn) {\n\t        if (n > 10) {\n\t            throw new Error('Constructor with greater than ten arguments');\n\t        }\n\t        if (n === 0) {\n\t            return function () {\n\t                return new Fn();\n\t            };\n\t        }\n\t        return curry(nAry(n, function ($0, $1, $2, $3, $4, $5, $6, $7, $8, $9) {\n\t            switch (arguments.length) {\n\t            case 1:\n\t                return new Fn($0);\n\t            case 2:\n\t                return new Fn($0, $1);\n\t            case 3:\n\t                return new Fn($0, $1, $2);\n\t            case 4:\n\t                return new Fn($0, $1, $2, $3);\n\t            case 5:\n\t                return new Fn($0, $1, $2, $3, $4);\n\t            case 6:\n\t                return new Fn($0, $1, $2, $3, $4, $5);\n\t            case 7:\n\t                return new Fn($0, $1, $2, $3, $4, $5, $6);\n\t            case 8:\n\t                return new Fn($0, $1, $2, $3, $4, $5, $6, $7);\n\t            case 9:\n\t                return new Fn($0, $1, $2, $3, $4, $5, $6, $7, $8);\n\t            case 10:\n\t                return new Fn($0, $1, $2, $3, $4, $5, $6, $7, $8, $9);\n\t            }\n\t        }));\n\t    });\n\n\t    /**\n\t     * Accepts a converging function and a list of branching functions and returns\n\t     * a new function. When invoked, this new function is applied to some\n\t     * arguments, each branching function is applied to those same arguments. The\n\t     * results of each branching function are passed as arguments to the converging\n\t     * function to produce the return value.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.4.2\n\t     * @category Function\n\t     * @sig (x1 -> x2 -> ... -> z) -> [(a -> b -> ... -> x1), (a -> b -> ... -> x2), ...] -> (a -> b -> ... -> z)\n\t     * @param {Function} after A function. `after` will be invoked with the return values of\n\t     *        `fn1` and `fn2` as its arguments.\n\t     * @param {Array} functions A list of functions.\n\t     * @return {Function} A new function.\n\t     * @example\n\t     *\n\t     *      var add = (a, b) => a + b;\n\t     *      var multiply = (a, b) => a * b;\n\t     *      var subtract = (a, b) => a - b;\n\t     *\n\t     *      //≅ multiply( add(1, 2), subtract(1, 2) );\n\t     *      R.converge(multiply, [add, subtract])(1, 2); //=> -3\n\t     *\n\t     *      var add3 = (a, b, c) => a + b + c;\n\t     *      R.converge(add3, [multiply, add, subtract])(1, 2); //=> 4\n\t     */\n\t    var converge = _curry2(function converge(after, fns) {\n\t        return curryN(reduce(max, 0, pluck('length', fns)), function () {\n\t            var args = arguments;\n\t            var context = this;\n\t            return after.apply(context, _map(function (fn) {\n\t                return fn.apply(context, args);\n\t            }, fns));\n\t        });\n\t    });\n\n\t    /**\n\t     * Counts the elements of a list according to how many match each value of a\n\t     * key generated by the supplied function. Returns an object mapping the keys\n\t     * produced by `fn` to the number of occurrences in the list. Note that all\n\t     * keys are coerced to strings because of how JavaScript objects work.\n\t     *\n\t     * Acts as a transducer if a transformer is given in list position.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Relation\n\t     * @sig (a -> String) -> [a] -> {*}\n\t     * @param {Function} fn The function used to map values to keys.\n\t     * @param {Array} list The list to count elements from.\n\t     * @return {Object} An object mapping keys to number of occurrences in the list.\n\t     * @example\n\t     *\n\t     *      var numbers = [1.0, 1.1, 1.2, 2.0, 3.0, 2.2];\n\t     *      var letters = R.split('', 'abcABCaaaBBc');\n\t     *      R.countBy(Math.floor)(numbers);    //=> {'1': 3, '2': 2, '3': 1}\n\t     *      R.countBy(R.toLower)(letters);   //=> {'a': 5, 'b': 4, 'c': 3}\n\t     */\n\t    var countBy = reduceBy(function (acc, elem) {\n\t        return acc + 1;\n\t    }, 0);\n\n\t    /**\n\t     * Returns a new list without any consecutively repeating elements. Equality is\n\t     * determined by applying the supplied predicate two consecutive elements. The\n\t     * first element in a series of equal element is the one being preserved.\n\t     *\n\t     * Dispatches to the `dropRepeatsWith` method of the second argument, if present.\n\t     *\n\t     * Acts as a transducer if a transformer is given in list position.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.14.0\n\t     * @category List\n\t     * @sig (a, a -> Boolean) -> [a] -> [a]\n\t     * @param {Function} pred A predicate used to test whether two items are equal.\n\t     * @param {Array} list The array to consider.\n\t     * @return {Array} `list` without repeating elements.\n\t     * @see R.transduce\n\t     * @example\n\t     *\n\t     *      var l = [1, -1, 1, 3, 4, -4, -4, -5, 5, 3, 3];\n\t     *      R.dropRepeatsWith(R.eqBy(Math.abs), l); //=> [1, 3, 4, -5, 3]\n\t     */\n\t    var dropRepeatsWith = _curry2(_dispatchable('dropRepeatsWith', _xdropRepeatsWith, function dropRepeatsWith(pred, list) {\n\t        var result = [];\n\t        var idx = 1;\n\t        var len = list.length;\n\t        if (len !== 0) {\n\t            result[0] = list[0];\n\t            while (idx < len) {\n\t                if (!pred(last(result), list[idx])) {\n\t                    result[result.length] = list[idx];\n\t                }\n\t                idx += 1;\n\t            }\n\t        }\n\t        return result;\n\t    }));\n\n\t    /**\n\t     * Takes a function and two values in its domain and returns `true` if the\n\t     * values map to the same value in the codomain; `false` otherwise.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.18.0\n\t     * @category Relation\n\t     * @sig (a -> b) -> a -> a -> Boolean\n\t     * @param {Function} f\n\t     * @param {*} x\n\t     * @param {*} y\n\t     * @return {Boolean}\n\t     * @example\n\t     *\n\t     *      R.eqBy(Math.abs, 5, -5); //=> true\n\t     */\n\t    var eqBy = _curry3(function eqBy(f, x, y) {\n\t        return equals(f(x), f(y));\n\t    });\n\n\t    /**\n\t     * Reports whether two objects have the same value, in `R.equals` terms, for\n\t     * the specified property. Useful as a curried predicate.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Object\n\t     * @sig k -> {k: v} -> {k: v} -> Boolean\n\t     * @param {String} prop The name of the property to compare\n\t     * @param {Object} obj1\n\t     * @param {Object} obj2\n\t     * @return {Boolean}\n\t     *\n\t     * @example\n\t     *\n\t     *      var o1 = { a: 1, b: 2, c: 3, d: 4 };\n\t     *      var o2 = { a: 10, b: 20, c: 3, d: 40 };\n\t     *      R.eqProps('a', o1, o2); //=> false\n\t     *      R.eqProps('c', o1, o2); //=> true\n\t     */\n\t    var eqProps = _curry3(function eqProps(prop, obj1, obj2) {\n\t        return equals(obj1[prop], obj2[prop]);\n\t    });\n\n\t    /**\n\t     * Splits a list into sub-lists stored in an object, based on the result of\n\t     * calling a String-returning function on each element, and grouping the\n\t     * results according to values returned.\n\t     *\n\t     * Dispatches to the `groupBy` method of the second argument, if present.\n\t     *\n\t     * Acts as a transducer if a transformer is given in list position.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig (a -> String) -> [a] -> {String: [a]}\n\t     * @param {Function} fn Function :: a -> String\n\t     * @param {Array} list The array to group\n\t     * @return {Object} An object with the output of `fn` for keys, mapped to arrays of elements\n\t     *         that produced that key when passed to `fn`.\n\t     * @see R.transduce\n\t     * @example\n\t     *\n\t     *      var byGrade = R.groupBy(function(student) {\n\t     *        var score = student.score;\n\t     *        return score < 65 ? 'F' :\n\t     *               score < 70 ? 'D' :\n\t     *               score < 80 ? 'C' :\n\t     *               score < 90 ? 'B' : 'A';\n\t     *      });\n\t     *      var students = [{name: 'Abby', score: 84},\n\t     *                      {name: 'Eddy', score: 58},\n\t     *                      // ...\n\t     *                      {name: 'Jack', score: 69}];\n\t     *      byGrade(students);\n\t     *      // {\n\t     *      //   'A': [{name: 'Dianne', score: 99}],\n\t     *      //   'B': [{name: 'Abby', score: 84}]\n\t     *      //   // ...,\n\t     *      //   'F': [{name: 'Eddy', score: 58}]\n\t     *      // }\n\t     */\n\t    var groupBy = _curry2(_checkForMethod('groupBy', reduceBy(function (acc, item) {\n\t        if (acc == null) {\n\t            acc = [];\n\t        }\n\t        acc.push(item);\n\t        return acc;\n\t    }, null)));\n\n\t    /**\n\t     * Given a function that generates a key, turns a list of objects into an\n\t     * object indexing the objects by the given key. Note that if multiple\n\t     * objects generate the same value for the indexing key only the last value\n\t     * will be included in the generated object.\n\t     *\n\t     * Acts as a transducer if a transformer is given in list position.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.19.0\n\t     * @category List\n\t     * @sig (a -> String) -> [{k: v}] -> {k: {k: v}}\n\t     * @param {Function} fn Function :: a -> String\n\t     * @param {Array} array The array of objects to index\n\t     * @return {Object} An object indexing each array element by the given property.\n\t     * @example\n\t     *\n\t     *      var list = [{id: 'xyz', title: 'A'}, {id: 'abc', title: 'B'}];\n\t     *      R.indexBy(R.prop('id'), list);\n\t     *      //=> {abc: {id: 'abc', title: 'B'}, xyz: {id: 'xyz', title: 'A'}}\n\t     */\n\t    var indexBy = reduceBy(function (acc, elem) {\n\t        return elem;\n\t    }, null);\n\n\t    /**\n\t     * Returns the position of the first occurrence of an item in an array, or -1\n\t     * if the item is not included in the array. `R.equals` is used to determine\n\t     * equality.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig a -> [a] -> Number\n\t     * @param {*} target The item to find.\n\t     * @param {Array} xs The array to search in.\n\t     * @return {Number} the index of the target, or -1 if the target is not found.\n\t     * @see R.lastIndexOf\n\t     * @example\n\t     *\n\t     *      R.indexOf(3, [1,2,3,4]); //=> 2\n\t     *      R.indexOf(10, [1,2,3,4]); //=> -1\n\t     */\n\t    var indexOf = _curry2(function indexOf(target, xs) {\n\t        return typeof xs.indexOf === 'function' && !_isArray(xs) ? xs.indexOf(target) : _indexOf(xs, target, 0);\n\t    });\n\n\t    /**\n\t     * juxt applies a list of functions to a list of values.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.19.0\n\t     * @category Function\n\t     * @sig [(a, b, ..., m) -> n] -> ((a, b, ..., m) -> [n])\n\t     * @param {Array} fns An array of functions\n\t     * @return {Function} A function that returns a list of values after applying each of the original `fns` to its parameters.\n\t     * @see R.applySpec\n\t     * @example\n\t     *\n\t     *      var getRange = R.juxt([Math.min, Math.max]);\n\t     *      getRange(3, 4, 9, -3); //=> [-3, 9]\n\t     */\n\t    var juxt = _curry1(function juxt(fns) {\n\t        return converge(_arrayOf, fns);\n\t    });\n\n\t    /**\n\t     * Returns a lens for the given getter and setter functions. The getter \"gets\"\n\t     * the value of the focus; the setter \"sets\" the value of the focus. The setter\n\t     * should not mutate the data structure.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.8.0\n\t     * @category Object\n\t     * @typedefn Lens s a = Functor f => (a -> f a) -> s -> f s\n\t     * @sig (s -> a) -> ((a, s) -> s) -> Lens s a\n\t     * @param {Function} getter\n\t     * @param {Function} setter\n\t     * @return {Lens}\n\t     * @see R.view, R.set, R.over, R.lensIndex, R.lensProp\n\t     * @example\n\t     *\n\t     *      var xLens = R.lens(R.prop('x'), R.assoc('x'));\n\t     *\n\t     *      R.view(xLens, {x: 1, y: 2});            //=> 1\n\t     *      R.set(xLens, 4, {x: 1, y: 2});          //=> {x: 4, y: 2}\n\t     *      R.over(xLens, R.negate, {x: 1, y: 2});  //=> {x: -1, y: 2}\n\t     */\n\t    var lens = _curry2(function lens(getter, setter) {\n\t        return function (toFunctorFn) {\n\t            return function (target) {\n\t                return map(function (focus) {\n\t                    return setter(focus, target);\n\t                }, toFunctorFn(getter(target)));\n\t            };\n\t        };\n\t    });\n\n\t    /**\n\t     * Returns a lens whose focus is the specified index.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.14.0\n\t     * @category Object\n\t     * @typedefn Lens s a = Functor f => (a -> f a) -> s -> f s\n\t     * @sig Number -> Lens s a\n\t     * @param {Number} n\n\t     * @return {Lens}\n\t     * @see R.view, R.set, R.over\n\t     * @example\n\t     *\n\t     *      var headLens = R.lensIndex(0);\n\t     *\n\t     *      R.view(headLens, ['a', 'b', 'c']);            //=> 'a'\n\t     *      R.set(headLens, 'x', ['a', 'b', 'c']);        //=> ['x', 'b', 'c']\n\t     *      R.over(headLens, R.toUpper, ['a', 'b', 'c']); //=> ['A', 'b', 'c']\n\t     */\n\t    var lensIndex = _curry1(function lensIndex(n) {\n\t        return lens(nth(n), update(n));\n\t    });\n\n\t    /**\n\t     * Returns a lens whose focus is the specified path.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.19.0\n\t     * @category Object\n\t     * @typedefn Lens s a = Functor f => (a -> f a) -> s -> f s\n\t     * @sig [String] -> Lens s a\n\t     * @param {Array} path The path to use.\n\t     * @return {Lens}\n\t     * @see R.view, R.set, R.over\n\t     * @example\n\t     *\n\t     *      var xyLens = R.lensPath(['x', 'y']);\n\t     *\n\t     *      R.view(xyLens, {x: {y: 2, z: 3}});            //=> 2\n\t     *      R.set(xyLens, 4, {x: {y: 2, z: 3}});          //=> {x: {y: 4, z: 3}}\n\t     *      R.over(xyLens, R.negate, {x: {y: 2, z: 3}});  //=> {x: {y: -2, z: 3}}\n\t     */\n\t    var lensPath = _curry1(function lensPath(p) {\n\t        return lens(path(p), assocPath(p));\n\t    });\n\n\t    /**\n\t     * Returns a lens whose focus is the specified property.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.14.0\n\t     * @category Object\n\t     * @typedefn Lens s a = Functor f => (a -> f a) -> s -> f s\n\t     * @sig String -> Lens s a\n\t     * @param {String} k\n\t     * @return {Lens}\n\t     * @see R.view, R.set, R.over\n\t     * @example\n\t     *\n\t     *      var xLens = R.lensProp('x');\n\t     *\n\t     *      R.view(xLens, {x: 1, y: 2});            //=> 1\n\t     *      R.set(xLens, 4, {x: 1, y: 2});          //=> {x: 4, y: 2}\n\t     *      R.over(xLens, R.negate, {x: 1, y: 2});  //=> {x: -1, y: 2}\n\t     */\n\t    var lensProp = _curry1(function lensProp(k) {\n\t        return lens(prop(k), assoc(k));\n\t    });\n\n\t    /**\n\t     * \"lifts\" a function to be the specified arity, so that it may \"map over\" that\n\t     * many lists, Functions or other objects that satisfy the [FantasyLand Apply spec](https://github.com/fantasyland/fantasy-land#apply).\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.7.0\n\t     * @category Function\n\t     * @sig Number -> (*... -> *) -> ([*]... -> [*])\n\t     * @param {Function} fn The function to lift into higher context\n\t     * @return {Function} The lifted function.\n\t     * @see R.lift, R.ap\n\t     * @example\n\t     *\n\t     *      var madd3 = R.liftN(3, R.curryN(3, (...args) => R.sum(args)));\n\t     *      madd3([1,2,3], [1,2,3], [1]); //=> [3, 4, 5, 4, 5, 6, 5, 6, 7]\n\t     */\n\t    var liftN = _curry2(function liftN(arity, fn) {\n\t        var lifted = curryN(arity, fn);\n\t        return curryN(arity, function () {\n\t            return _reduce(ap, map(lifted, arguments[0]), _slice(arguments, 1));\n\t        });\n\t    });\n\n\t    /**\n\t     * Returns the mean of the given list of numbers.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.14.0\n\t     * @category Math\n\t     * @sig [Number] -> Number\n\t     * @param {Array} list\n\t     * @return {Number}\n\t     * @example\n\t     *\n\t     *      R.mean([2, 7, 9]); //=> 6\n\t     *      R.mean([]); //=> NaN\n\t     */\n\t    var mean = _curry1(function mean(list) {\n\t        return sum(list) / list.length;\n\t    });\n\n\t    /**\n\t     * Returns the median of the given list of numbers.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.14.0\n\t     * @category Math\n\t     * @sig [Number] -> Number\n\t     * @param {Array} list\n\t     * @return {Number}\n\t     * @example\n\t     *\n\t     *      R.median([2, 9, 7]); //=> 7\n\t     *      R.median([7, 2, 10, 9]); //=> 8\n\t     *      R.median([]); //=> NaN\n\t     */\n\t    var median = _curry1(function median(list) {\n\t        var len = list.length;\n\t        if (len === 0) {\n\t            return NaN;\n\t        }\n\t        var width = 2 - len % 2;\n\t        var idx = (len - width) / 2;\n\t        return mean(_slice(list).sort(function (a, b) {\n\t            return a < b ? -1 : a > b ? 1 : 0;\n\t        }).slice(idx, idx + width));\n\t    });\n\n\t    /**\n\t     * Takes a predicate and a list or other \"filterable\" object and returns the\n\t     * pair of filterable objects of the same type of elements which do and do not\n\t     * satisfy, the predicate, respectively.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.4\n\t     * @category List\n\t     * @sig Filterable f => (a -> Boolean) -> f a -> [f a, f a]\n\t     * @param {Function} pred A predicate to determine which side the element belongs to.\n\t     * @param {Array} filterable the list (or other filterable) to partition.\n\t     * @return {Array} An array, containing first the subset of elements that satisfy the\n\t     *         predicate, and second the subset of elements that do not satisfy.\n\t     * @see R.filter, R.reject\n\t     * @example\n\t     *\n\t     *      R.partition(R.contains('s'), ['sss', 'ttt', 'foo', 'bars']);\n\t     *      // => [ [ 'sss', 'bars' ],  [ 'ttt', 'foo' ] ]\n\t     *\n\t     *      R.partition(R.contains('s'), { a: 'sss', b: 'ttt', foo: 'bars' });\n\t     *      // => [ { a: 'sss', foo: 'bars' }, { b: 'ttt' }  ]\n\t     */\n\t    var partition = juxt([\n\t        filter,\n\t        reject\n\t    ]);\n\n\t    /**\n\t     * Performs left-to-right function composition. The leftmost function may have\n\t     * any arity; the remaining functions must be unary.\n\t     *\n\t     * In some libraries this function is named `sequence`.\n\t     *\n\t     * **Note:** The result of pipe is not automatically curried.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Function\n\t     * @sig (((a, b, ..., n) -> o), (o -> p), ..., (x -> y), (y -> z)) -> ((a, b, ..., n) -> z)\n\t     * @param {...Function} functions\n\t     * @return {Function}\n\t     * @see R.compose\n\t     * @example\n\t     *\n\t     *      var f = R.pipe(Math.pow, R.negate, R.inc);\n\t     *\n\t     *      f(3, 4); // -(3^4) + 1\n\t     */\n\t    var pipe = function pipe() {\n\t        if (arguments.length === 0) {\n\t            throw new Error('pipe requires at least one argument');\n\t        }\n\t        return _arity(arguments[0].length, reduce(_pipe, arguments[0], tail(arguments)));\n\t    };\n\n\t    /**\n\t     * Performs left-to-right composition of one or more Promise-returning\n\t     * functions. The leftmost function may have any arity; the remaining functions\n\t     * must be unary.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.10.0\n\t     * @category Function\n\t     * @sig ((a -> Promise b), (b -> Promise c), ..., (y -> Promise z)) -> (a -> Promise z)\n\t     * @param {...Function} functions\n\t     * @return {Function}\n\t     * @see R.composeP\n\t     * @example\n\t     *\n\t     *      //  followersForUser :: String -> Promise [User]\n\t     *      var followersForUser = R.pipeP(db.getUserById, db.getFollowers);\n\t     */\n\t    var pipeP = function pipeP() {\n\t        if (arguments.length === 0) {\n\t            throw new Error('pipeP requires at least one argument');\n\t        }\n\t        return _arity(arguments[0].length, reduce(_pipeP, arguments[0], tail(arguments)));\n\t    };\n\n\t    /**\n\t     * Multiplies together all the elements of a list.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Math\n\t     * @sig [Number] -> Number\n\t     * @param {Array} list An array of numbers\n\t     * @return {Number} The product of all the numbers in the list.\n\t     * @see R.reduce\n\t     * @example\n\t     *\n\t     *      R.product([2,4,6,8,100,1]); //=> 38400\n\t     */\n\t    var product = reduce(multiply, 1);\n\n\t    /**\n\t     * Transforms a [Traversable](https://github.com/fantasyland/fantasy-land#traversable)\n\t     * of [Applicative](https://github.com/fantasyland/fantasy-land#applicative) into an\n\t     * Applicative of Traversable.\n\t     *\n\t     * Dispatches to the `sequence` method of the second argument, if present.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.19.0\n\t     * @category List\n\t     * @sig (Applicative f, Traversable t) => (a -> f a) -> t (f a) -> f (t a)\n\t     * @param {Function} of\n\t     * @param {*} traversable\n\t     * @return {*}\n\t     * @see R.traverse\n\t     * @example\n\t     *\n\t     *      R.sequence(Maybe.of, [Just(1), Just(2), Just(3)]);   //=> Just([1, 2, 3])\n\t     *      R.sequence(Maybe.of, [Just(1), Just(2), Nothing()]); //=> Nothing()\n\t     *\n\t     *      R.sequence(R.of, Just([1, 2, 3])); //=> [Just(1), Just(2), Just(3)]\n\t     *      R.sequence(R.of, Nothing());       //=> [Nothing()]\n\t     */\n\t    var sequence = _curry2(function sequence(of, traversable) {\n\t        return typeof traversable.sequence === 'function' ? traversable.sequence(of) : reduceRight(function (acc, x) {\n\t            return ap(map(prepend, x), acc);\n\t        }, of([]), traversable);\n\t    });\n\n\t    /**\n\t     * Maps an [Applicative](https://github.com/fantasyland/fantasy-land#applicative)-returning\n\t     * function over a [Traversable](https://github.com/fantasyland/fantasy-land#traversable),\n\t     * then uses [`sequence`](#sequence) to transform the resulting Traversable of Applicative\n\t     * into an Applicative of Traversable.\n\t     *\n\t     * Dispatches to the `sequence` method of the third argument, if present.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.19.0\n\t     * @category List\n\t     * @sig (Applicative f, Traversable t) => (a -> f a) -> (a -> f b) -> t a -> f (t b)\n\t     * @param {Function} of\n\t     * @param {Function} f\n\t     * @param {*} traversable\n\t     * @return {*}\n\t     * @see R.sequence\n\t     * @example\n\t     *\n\t     *      // Returns `Nothing` if the given divisor is `0`\n\t     *      safeDiv = n => d => d === 0 ? Nothing() : Just(n / d)\n\t     *\n\t     *      R.traverse(Maybe.of, safeDiv(10), [2, 4, 5]); //=> Just([5, 2.5, 2])\n\t     *      R.traverse(Maybe.of, safeDiv(10), [2, 0, 5]); //=> Nothing\n\t     */\n\t    var traverse = _curry3(function traverse(of, f, traversable) {\n\t        return sequence(of, map(f, traversable));\n\t    });\n\n\t    /**\n\t     * Shorthand for `R.chain(R.identity)`, which removes one level of nesting from\n\t     * any [Chain](https://github.com/fantasyland/fantasy-land#chain).\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.3.0\n\t     * @category List\n\t     * @sig Chain c => c (c a) -> c a\n\t     * @param {*} list\n\t     * @return {*}\n\t     * @see R.flatten, R.chain\n\t     * @example\n\t     *\n\t     *      R.unnest([1, [2], [[3]]]); //=> [1, 2, [3]]\n\t     *      R.unnest([[1, 2], [3, 4], [5, 6]]); //=> [1, 2, 3, 4, 5, 6]\n\t     */\n\t    var unnest = chain(_identity);\n\n\t    var _contains = function _contains(a, list) {\n\t        return _indexOf(list, a, 0) >= 0;\n\t    };\n\n\t    //  mapPairs :: (Object, [String]) -> [String]\n\t    var _toString = function _toString(x, seen) {\n\t        var recur = function recur(y) {\n\t            var xs = seen.concat([x]);\n\t            return _contains(y, xs) ? '<Circular>' : _toString(y, xs);\n\t        };\n\t        //  mapPairs :: (Object, [String]) -> [String]\n\t        var mapPairs = function (obj, keys) {\n\t            return _map(function (k) {\n\t                return _quote(k) + ': ' + recur(obj[k]);\n\t            }, keys.slice().sort());\n\t        };\n\t        switch (Object.prototype.toString.call(x)) {\n\t        case '[object Arguments]':\n\t            return '(function() { return arguments; }(' + _map(recur, x).join(', ') + '))';\n\t        case '[object Array]':\n\t            return '[' + _map(recur, x).concat(mapPairs(x, reject(function (k) {\n\t                return /^\\d+$/.test(k);\n\t            }, keys(x)))).join(', ') + ']';\n\t        case '[object Boolean]':\n\t            return typeof x === 'object' ? 'new Boolean(' + recur(x.valueOf()) + ')' : x.toString();\n\t        case '[object Date]':\n\t            return 'new Date(' + (isNaN(x.valueOf()) ? recur(NaN) : _quote(_toISOString(x))) + ')';\n\t        case '[object Null]':\n\t            return 'null';\n\t        case '[object Number]':\n\t            return typeof x === 'object' ? 'new Number(' + recur(x.valueOf()) + ')' : 1 / x === -Infinity ? '-0' : x.toString(10);\n\t        case '[object String]':\n\t            return typeof x === 'object' ? 'new String(' + recur(x.valueOf()) + ')' : _quote(x);\n\t        case '[object Undefined]':\n\t            return 'undefined';\n\t        default:\n\t            if (typeof x.toString === 'function') {\n\t                var repr = x.toString();\n\t                if (repr !== '[object Object]') {\n\t                    return repr;\n\t                }\n\t            }\n\t            return '{' + mapPairs(x, keys(x)).join(', ') + '}';\n\t        }\n\t    };\n\n\t    /**\n\t     * Performs right-to-left function composition. The rightmost function may have\n\t     * any arity; the remaining functions must be unary.\n\t     *\n\t     * **Note:** The result of compose is not automatically curried.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Function\n\t     * @sig ((y -> z), (x -> y), ..., (o -> p), ((a, b, ..., n) -> o)) -> ((a, b, ..., n) -> z)\n\t     * @param {...Function} functions\n\t     * @return {Function}\n\t     * @see R.pipe\n\t     * @example\n\t     *\n\t     *      var f = R.compose(R.inc, R.negate, Math.pow);\n\t     *\n\t     *      f(3, 4); // -(3^4) + 1\n\t     */\n\t    var compose = function compose() {\n\t        if (arguments.length === 0) {\n\t            throw new Error('compose requires at least one argument');\n\t        }\n\t        return pipe.apply(this, reverse(arguments));\n\t    };\n\n\t    /**\n\t     * Returns the right-to-left Kleisli composition of the provided functions,\n\t     * each of which must return a value of a type supported by [`chain`](#chain).\n\t     *\n\t     * `R.composeK(h, g, f)` is equivalent to `R.compose(R.chain(h), R.chain(g), R.chain(f))`.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.16.0\n\t     * @category Function\n\t     * @sig Chain m => ((y -> m z), (x -> m y), ..., (a -> m b)) -> (m a -> m z)\n\t     * @param {...Function}\n\t     * @return {Function}\n\t     * @see R.pipeK\n\t     * @example\n\t     *\n\t     *      //  parseJson :: String -> Maybe *\n\t     *      //  get :: String -> Object -> Maybe *\n\t     *\n\t     *      //  getStateCode :: Maybe String -> Maybe String\n\t     *      var getStateCode = R.composeK(\n\t     *        R.compose(Maybe.of, R.toUpper),\n\t     *        get('state'),\n\t     *        get('address'),\n\t     *        get('user'),\n\t     *        parseJson\n\t     *      );\n\t     *\n\t     *      getStateCode(Maybe.of('{\"user\":{\"address\":{\"state\":\"ny\"}}}'));\n\t     *      //=> Just('NY')\n\t     *      getStateCode(Maybe.of('[Invalid JSON]'));\n\t     *      //=> Nothing()\n\t     */\n\t    var composeK = function composeK() {\n\t        return compose.apply(this, prepend(identity, map(chain, arguments)));\n\t    };\n\n\t    /**\n\t     * Performs right-to-left composition of one or more Promise-returning\n\t     * functions. The rightmost function may have any arity; the remaining\n\t     * functions must be unary.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.10.0\n\t     * @category Function\n\t     * @sig ((y -> Promise z), (x -> Promise y), ..., (a -> Promise b)) -> (a -> Promise z)\n\t     * @param {...Function} functions\n\t     * @return {Function}\n\t     * @see R.pipeP\n\t     * @example\n\t     *\n\t     *      //  followersForUser :: String -> Promise [User]\n\t     *      var followersForUser = R.composeP(db.getFollowers, db.getUserById);\n\t     */\n\t    var composeP = function composeP() {\n\t        if (arguments.length === 0) {\n\t            throw new Error('composeP requires at least one argument');\n\t        }\n\t        return pipeP.apply(this, reverse(arguments));\n\t    };\n\n\t    /**\n\t     * Wraps a constructor function inside a curried function that can be called\n\t     * with the same arguments and returns the same type.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Function\n\t     * @sig (* -> {*}) -> (* -> {*})\n\t     * @param {Function} Fn The constructor function to wrap.\n\t     * @return {Function} A wrapped, curried constructor function.\n\t     * @example\n\t     *\n\t     *      // Constructor function\n\t     *      var Widget = config => {\n\t     *        // ...\n\t     *      };\n\t     *      Widget.prototype = {\n\t     *        // ...\n\t     *      };\n\t     *      var allConfigs = [\n\t     *        // ...\n\t     *      ];\n\t     *      R.map(R.construct(Widget), allConfigs); // a list of Widgets\n\t     */\n\t    var construct = _curry1(function construct(Fn) {\n\t        return constructN(Fn.length, Fn);\n\t    });\n\n\t    /**\n\t     * Returns `true` if the specified value is equal, in `R.equals` terms, to at\n\t     * least one element of the given list; `false` otherwise.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig a -> [a] -> Boolean\n\t     * @param {Object} a The item to compare against.\n\t     * @param {Array} list The array to consider.\n\t     * @return {Boolean} `true` if the item is in the list, `false` otherwise.\n\t     * @see R.any\n\t     * @example\n\t     *\n\t     *      R.contains(3, [1, 2, 3]); //=> true\n\t     *      R.contains(4, [1, 2, 3]); //=> false\n\t     *      R.contains([42], [[42]]); //=> true\n\t     */\n\t    var contains = _curry2(_contains);\n\n\t    /**\n\t     * Finds the set (i.e. no duplicates) of all elements in the first list not\n\t     * contained in the second list.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Relation\n\t     * @sig [*] -> [*] -> [*]\n\t     * @param {Array} list1 The first list.\n\t     * @param {Array} list2 The second list.\n\t     * @return {Array} The elements in `list1` that are not in `list2`.\n\t     * @see R.differenceWith, R.symmetricDifference, R.symmetricDifferenceWith\n\t     * @example\n\t     *\n\t     *      R.difference([1,2,3,4], [7,6,5,4,3]); //=> [1,2]\n\t     *      R.difference([7,6,5,4,3], [1,2,3,4]); //=> [7,6,5]\n\t     */\n\t    var difference = _curry2(function difference(first, second) {\n\t        var out = [];\n\t        var idx = 0;\n\t        var firstLen = first.length;\n\t        while (idx < firstLen) {\n\t            if (!_contains(first[idx], second) && !_contains(first[idx], out)) {\n\t                out[out.length] = first[idx];\n\t            }\n\t            idx += 1;\n\t        }\n\t        return out;\n\t    });\n\n\t    /**\n\t     * Returns a new list without any consecutively repeating elements. `R.equals`\n\t     * is used to determine equality.\n\t     *\n\t     * Dispatches to the `dropRepeats` method of the first argument, if present.\n\t     *\n\t     * Acts as a transducer if a transformer is given in list position.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.14.0\n\t     * @category List\n\t     * @sig [a] -> [a]\n\t     * @param {Array} list The array to consider.\n\t     * @return {Array} `list` without repeating elements.\n\t     * @see R.transduce\n\t     * @example\n\t     *\n\t     *     R.dropRepeats([1, 1, 1, 2, 3, 4, 4, 2, 2]); //=> [1, 2, 3, 4, 2]\n\t     */\n\t    var dropRepeats = _curry1(_dispatchable('dropRepeats', _xdropRepeatsWith(equals), dropRepeatsWith(equals)));\n\n\t    /**\n\t     * \"lifts\" a function of arity > 1 so that it may \"map over\" a list, Function or other\n\t     * object that satisfies the [FantasyLand Apply spec](https://github.com/fantasyland/fantasy-land#apply).\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.7.0\n\t     * @category Function\n\t     * @sig (*... -> *) -> ([*]... -> [*])\n\t     * @param {Function} fn The function to lift into higher context\n\t     * @return {Function} The lifted function.\n\t     * @see R.liftN\n\t     * @example\n\t     *\n\t     *      var madd3 = R.lift(R.curry((a, b, c) => a + b + c));\n\t     *\n\t     *      madd3([1,2,3], [1,2,3], [1]); //=> [3, 4, 5, 4, 5, 6, 5, 6, 7]\n\t     *\n\t     *      var madd5 = R.lift(R.curry((a, b, c, d, e) => a + b + c + d + e));\n\t     *\n\t     *      madd5([1,2], [3], [4, 5], [6], [7, 8]); //=> [21, 22, 22, 23, 22, 23, 23, 24]\n\t     */\n\t    var lift = _curry1(function lift(fn) {\n\t        return liftN(fn.length, fn);\n\t    });\n\n\t    /**\n\t     * Returns a partial copy of an object omitting the keys specified.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Object\n\t     * @sig [String] -> {String: *} -> {String: *}\n\t     * @param {Array} names an array of String property names to omit from the new object\n\t     * @param {Object} obj The object to copy from\n\t     * @return {Object} A new object with properties from `names` not on it.\n\t     * @see R.pick\n\t     * @example\n\t     *\n\t     *      R.omit(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {b: 2, c: 3}\n\t     */\n\t    var omit = _curry2(function omit(names, obj) {\n\t        var result = {};\n\t        for (var prop in obj) {\n\t            if (!_contains(prop, names)) {\n\t                result[prop] = obj[prop];\n\t            }\n\t        }\n\t        return result;\n\t    });\n\n\t    /**\n\t     * Returns the left-to-right Kleisli composition of the provided functions,\n\t     * each of which must return a value of a type supported by [`chain`](#chain).\n\t     *\n\t     * `R.pipeK(f, g, h)` is equivalent to `R.pipe(R.chain(f), R.chain(g), R.chain(h))`.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.16.0\n\t     * @category Function\n\t     * @sig Chain m => ((a -> m b), (b -> m c), ..., (y -> m z)) -> (m a -> m z)\n\t     * @param {...Function}\n\t     * @return {Function}\n\t     * @see R.composeK\n\t     * @example\n\t     *\n\t     *      //  parseJson :: String -> Maybe *\n\t     *      //  get :: String -> Object -> Maybe *\n\t     *\n\t     *      //  getStateCode :: Maybe String -> Maybe String\n\t     *      var getStateCode = R.pipeK(\n\t     *        parseJson,\n\t     *        get('user'),\n\t     *        get('address'),\n\t     *        get('state'),\n\t     *        R.compose(Maybe.of, R.toUpper)\n\t     *      );\n\t     *\n\t     *      getStateCode(Maybe.of('{\"user\":{\"address\":{\"state\":\"ny\"}}}'));\n\t     *      //=> Just('NY')\n\t     *      getStateCode(Maybe.of('[Invalid JSON]'));\n\t     *      //=> Nothing()\n\t     */\n\t    var pipeK = function pipeK() {\n\t        return composeK.apply(this, reverse(arguments));\n\t    };\n\n\t    /**\n\t     * Returns the string representation of the given value. `eval`'ing the output\n\t     * should result in a value equivalent to the input value. Many of the built-in\n\t     * `toString` methods do not satisfy this requirement.\n\t     *\n\t     * If the given value is an `[object Object]` with a `toString` method other\n\t     * than `Object.prototype.toString`, this method is invoked with no arguments\n\t     * to produce the return value. This means user-defined constructor functions\n\t     * can provide a suitable `toString` method. For example:\n\t     *\n\t     *     function Point(x, y) {\n\t     *       this.x = x;\n\t     *       this.y = y;\n\t     *     }\n\t     *\n\t     *     Point.prototype.toString = function() {\n\t     *       return 'new Point(' + this.x + ', ' + this.y + ')';\n\t     *     };\n\t     *\n\t     *     R.toString(new Point(1, 2)); //=> 'new Point(1, 2)'\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.14.0\n\t     * @category String\n\t     * @sig * -> String\n\t     * @param {*} val\n\t     * @return {String}\n\t     * @example\n\t     *\n\t     *      R.toString(42); //=> '42'\n\t     *      R.toString('abc'); //=> '\"abc\"'\n\t     *      R.toString([1, 2, 3]); //=> '[1, 2, 3]'\n\t     *      R.toString({foo: 1, bar: 2, baz: 3}); //=> '{\"bar\": 2, \"baz\": 3, \"foo\": 1}'\n\t     *      R.toString(new Date('2001-02-03T04:05:06Z')); //=> 'new Date(\"2001-02-03T04:05:06.000Z\")'\n\t     */\n\t    var toString = _curry1(function toString(val) {\n\t        return _toString(val, []);\n\t    });\n\n\t    /**\n\t     * Returns a new list without values in the first argument.\n\t     * `R.equals` is used to determine equality.\n\t     *\n\t     * Acts as a transducer if a transformer is given in list position.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.19.0\n\t     * @category List\n\t     * @sig [a] -> [a] -> [a]\n\t     * @param {Array} list1 The values to be removed from `list2`.\n\t     * @param {Array} list2 The array to remove values from.\n\t     * @return {Array} The new array without values in `list1`.\n\t     * @see R.transduce\n\t     * @example\n\t     *\n\t     *      R.without([1, 2], [1, 2, 1, 3, 4]); //=> [3, 4]\n\t     */\n\t    var without = _curry2(function (xs, list) {\n\t        return reject(flip(_contains)(xs), list);\n\t    });\n\n\t    // A simple Set type that honours R.equals semantics\n\t    /* globals Set */\n\t    // until we figure out why jsdoc chokes on this\n\t    // @param item The item to add to the Set\n\t    // @returns {boolean} true if the item did not exist prior, otherwise false\n\t    //\n\t    //\n\t    // @param item The item to check for existence in the Set\n\t    // @returns {boolean} true if the item exists in the Set, otherwise false\n\t    //\n\t    //\n\t    // Combines the logic for checking whether an item is a member of the set and\n\t    // for adding a new item to the set.\n\t    //\n\t    // @param item       The item to check or add to the Set instance.\n\t    // @param shouldAdd  If true, the item will be added to the set if it doesn't\n\t    //                   already exist.\n\t    // @param set        The set instance to check or add to.\n\t    // @return {boolean} true if the item already existed, otherwise false.\n\t    //\n\t    // distinguish between +0 and -0\n\t    // these types can all utilise the native Set\n\t    // set._items['boolean'] holds a two element array\n\t    // representing [ falseExists, trueExists ]\n\t    // compare functions for reference equality\n\t    /* falls through */\n\t    // reduce the search size of heterogeneous sets by creating buckets\n\t    // for each type.\n\t    // scan through all previously applied items\n\t    var _Set = function () {\n\t        function _Set() {\n\t            /* globals Set */\n\t            this._nativeSet = typeof Set === 'function' ? new Set() : null;\n\t            this._items = {};\n\t        }\n\t        // until we figure out why jsdoc chokes on this\n\t        // @param item The item to add to the Set\n\t        // @returns {boolean} true if the item did not exist prior, otherwise false\n\t        //\n\t        _Set.prototype.add = function (item) {\n\t            return !hasOrAdd(item, true, this);\n\t        };\n\t        //\n\t        // @param item The item to check for existence in the Set\n\t        // @returns {boolean} true if the item exists in the Set, otherwise false\n\t        //\n\t        _Set.prototype.has = function (item) {\n\t            return hasOrAdd(item, false, this);\n\t        };\n\t        //\n\t        // Combines the logic for checking whether an item is a member of the set and\n\t        // for adding a new item to the set.\n\t        //\n\t        // @param item       The item to check or add to the Set instance.\n\t        // @param shouldAdd  If true, the item will be added to the set if it doesn't\n\t        //                   already exist.\n\t        // @param set        The set instance to check or add to.\n\t        // @return {boolean} true if the item already existed, otherwise false.\n\t        //\n\t        function hasOrAdd(item, shouldAdd, set) {\n\t            var type = typeof item;\n\t            var prevSize, newSize;\n\t            switch (type) {\n\t            case 'string':\n\t            case 'number':\n\t                // distinguish between +0 and -0\n\t                if (item === 0 && 1 / item === -Infinity) {\n\t                    if (set._items['-0']) {\n\t                        return true;\n\t                    } else {\n\t                        if (shouldAdd) {\n\t                            set._items['-0'] = true;\n\t                        }\n\t                        return false;\n\t                    }\n\t                }\n\t                // these types can all utilise the native Set\n\t                if (set._nativeSet !== null) {\n\t                    if (shouldAdd) {\n\t                        prevSize = set._nativeSet.size;\n\t                        set._nativeSet.add(item);\n\t                        newSize = set._nativeSet.size;\n\t                        return newSize === prevSize;\n\t                    } else {\n\t                        return set._nativeSet.has(item);\n\t                    }\n\t                } else {\n\t                    if (!(type in set._items)) {\n\t                        if (shouldAdd) {\n\t                            set._items[type] = {};\n\t                            set._items[type][item] = true;\n\t                        }\n\t                        return false;\n\t                    } else if (item in set._items[type]) {\n\t                        return true;\n\t                    } else {\n\t                        if (shouldAdd) {\n\t                            set._items[type][item] = true;\n\t                        }\n\t                        return false;\n\t                    }\n\t                }\n\t            case 'boolean':\n\t                // set._items['boolean'] holds a two element array\n\t                // representing [ falseExists, trueExists ]\n\t                if (type in set._items) {\n\t                    var bIdx = item ? 1 : 0;\n\t                    if (set._items[type][bIdx]) {\n\t                        return true;\n\t                    } else {\n\t                        if (shouldAdd) {\n\t                            set._items[type][bIdx] = true;\n\t                        }\n\t                        return false;\n\t                    }\n\t                } else {\n\t                    if (shouldAdd) {\n\t                        set._items[type] = item ? [\n\t                            false,\n\t                            true\n\t                        ] : [\n\t                            true,\n\t                            false\n\t                        ];\n\t                    }\n\t                    return false;\n\t                }\n\t            case 'function':\n\t                // compare functions for reference equality\n\t                if (set._nativeSet !== null) {\n\t                    if (shouldAdd) {\n\t                        prevSize = set._nativeSet.size;\n\t                        set._nativeSet.add(item);\n\t                        newSize = set._nativeSet.size;\n\t                        return newSize > prevSize;\n\t                    } else {\n\t                        return set._nativeSet.has(item);\n\t                    }\n\t                } else {\n\t                    if (!(type in set._items)) {\n\t                        if (shouldAdd) {\n\t                            set._items[type] = [item];\n\t                        }\n\t                        return false;\n\t                    }\n\t                    if (!_contains(item, set._items[type])) {\n\t                        if (shouldAdd) {\n\t                            set._items[type].push(item);\n\t                        }\n\t                        return false;\n\t                    }\n\t                    return true;\n\t                }\n\t            case 'undefined':\n\t                if (set._items[type]) {\n\t                    return true;\n\t                } else {\n\t                    if (shouldAdd) {\n\t                        set._items[type] = true;\n\t                    }\n\t                    return false;\n\t                }\n\t            case 'object':\n\t                if (item === null) {\n\t                    if (!set._items['null']) {\n\t                        if (shouldAdd) {\n\t                            set._items['null'] = true;\n\t                        }\n\t                        return false;\n\t                    }\n\t                    return true;\n\t                }\n\t            /* falls through */\n\t            default:\n\t                // reduce the search size of heterogeneous sets by creating buckets\n\t                // for each type.\n\t                type = Object.prototype.toString.call(item);\n\t                if (!(type in set._items)) {\n\t                    if (shouldAdd) {\n\t                        set._items[type] = [item];\n\t                    }\n\t                    return false;\n\t                }\n\t                // scan through all previously applied items\n\t                if (!_contains(item, set._items[type])) {\n\t                    if (shouldAdd) {\n\t                        set._items[type].push(item);\n\t                    }\n\t                    return false;\n\t                }\n\t                return true;\n\t            }\n\t        }\n\t        return _Set;\n\t    }();\n\n\t    /**\n\t     * A function wrapping calls to the two functions in an `&&` operation,\n\t     * returning the result of the first function if it is false-y and the result\n\t     * of the second function otherwise. Note that this is short-circuited,\n\t     * meaning that the second function will not be invoked if the first returns a\n\t     * false-y value.\n\t     *\n\t     * In addition to functions, `R.both` also accepts any fantasy-land compatible\n\t     * applicative functor.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.12.0\n\t     * @category Logic\n\t     * @sig (*... -> Boolean) -> (*... -> Boolean) -> (*... -> Boolean)\n\t     * @param {Function} f a predicate\n\t     * @param {Function} g another predicate\n\t     * @return {Function} a function that applies its arguments to `f` and `g` and `&&`s their outputs together.\n\t     * @see R.and\n\t     * @example\n\t     *\n\t     *      var gt10 = x => x > 10;\n\t     *      var even = x => x % 2 === 0;\n\t     *      var f = R.both(gt10, even);\n\t     *      f(100); //=> true\n\t     *      f(101); //=> false\n\t     */\n\t    var both = _curry2(function both(f, g) {\n\t        return _isFunction(f) ? function _both() {\n\t            return f.apply(this, arguments) && g.apply(this, arguments);\n\t        } : lift(and)(f, g);\n\t    });\n\n\t    /**\n\t     * Takes a function `f` and returns a function `g` such that:\n\t     *\n\t     *   - applying `g` to zero or more arguments will give __true__ if applying\n\t     *     the same arguments to `f` gives a logical __false__ value; and\n\t     *\n\t     *   - applying `g` to zero or more arguments will give __false__ if applying\n\t     *     the same arguments to `f` gives a logical __true__ value.\n\t     *\n\t     * `R.complement` will work on all other functors as well.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.12.0\n\t     * @category Logic\n\t     * @sig (*... -> *) -> (*... -> Boolean)\n\t     * @param {Function} f\n\t     * @return {Function}\n\t     * @see R.not\n\t     * @example\n\t     *\n\t     *      var isEven = n => n % 2 === 0;\n\t     *      var isOdd = R.complement(isEven);\n\t     *      isOdd(21); //=> true\n\t     *      isOdd(42); //=> false\n\t     */\n\t    var complement = lift(not);\n\n\t    /**\n\t     * Returns the result of concatenating the given lists or strings.\n\t     *\n\t     * Note: `R.concat` expects both arguments to be of the same type,\n\t     * unlike the native `Array.prototype.concat` method. It will throw\n\t     * an error if you `concat` an Array with a non-Array value.\n\t     *\n\t     * Dispatches to the `concat` method of the first argument, if present.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig [a] -> [a] -> [a]\n\t     * @sig String -> String -> String\n\t     * @param {Array|String} a\n\t     * @param {Array|String} b\n\t     * @return {Array|String}\n\t     *\n\t     * @example\n\t     *\n\t     *      R.concat([], []); //=> []\n\t     *      R.concat([4, 5, 6], [1, 2, 3]); //=> [4, 5, 6, 1, 2, 3]\n\t     *      R.concat('ABC', 'DEF'); // 'ABCDEF'\n\t     */\n\t    var concat = _curry2(function concat(a, b) {\n\t        if (a == null || !_isFunction(a.concat)) {\n\t            throw new TypeError(toString(a) + ' does not have a method named \"concat\"');\n\t        }\n\t        if (_isArray(a) && !_isArray(b)) {\n\t            throw new TypeError(toString(b) + ' is not an array');\n\t        }\n\t        return a.concat(b);\n\t    });\n\n\t    /**\n\t     * A function wrapping calls to the two functions in an `||` operation,\n\t     * returning the result of the first function if it is truth-y and the result\n\t     * of the second function otherwise. Note that this is short-circuited,\n\t     * meaning that the second function will not be invoked if the first returns a\n\t     * truth-y value.\n\t     *\n\t     * In addition to functions, `R.either` also accepts any fantasy-land compatible\n\t     * applicative functor.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.12.0\n\t     * @category Logic\n\t     * @sig (*... -> Boolean) -> (*... -> Boolean) -> (*... -> Boolean)\n\t     * @param {Function} f a predicate\n\t     * @param {Function} g another predicate\n\t     * @return {Function} a function that applies its arguments to `f` and `g` and `||`s their outputs together.\n\t     * @see R.or\n\t     * @example\n\t     *\n\t     *      var gt10 = x => x > 10;\n\t     *      var even = x => x % 2 === 0;\n\t     *      var f = R.either(gt10, even);\n\t     *      f(101); //=> true\n\t     *      f(8); //=> true\n\t     */\n\t    var either = _curry2(function either(f, g) {\n\t        return _isFunction(f) ? function _either() {\n\t            return f.apply(this, arguments) || g.apply(this, arguments);\n\t        } : lift(or)(f, g);\n\t    });\n\n\t    /**\n\t     * Turns a named method with a specified arity into a function that can be\n\t     * called directly supplied with arguments and a target object.\n\t     *\n\t     * The returned function is curried and accepts `arity + 1` parameters where\n\t     * the final parameter is the target object.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Function\n\t     * @sig Number -> String -> (a -> b -> ... -> n -> Object -> *)\n\t     * @param {Number} arity Number of arguments the returned function should take\n\t     *        before the target object.\n\t     * @param {String} method Name of the method to call.\n\t     * @return {Function} A new curried function.\n\t     * @example\n\t     *\n\t     *      var sliceFrom = R.invoker(1, 'slice');\n\t     *      sliceFrom(6, 'abcdefghijklm'); //=> 'ghijklm'\n\t     *      var sliceFrom6 = R.invoker(2, 'slice')(6);\n\t     *      sliceFrom6(8, 'abcdefghijklm'); //=> 'gh'\n\t     */\n\t    var invoker = _curry2(function invoker(arity, method) {\n\t        return curryN(arity + 1, function () {\n\t            var target = arguments[arity];\n\t            if (target != null && _isFunction(target[method])) {\n\t                return target[method].apply(target, _slice(arguments, 0, arity));\n\t            }\n\t            throw new TypeError(toString(target) + ' does not have a method named \"' + method + '\"');\n\t        });\n\t    });\n\n\t    /**\n\t     * Returns a string made by inserting the `separator` between each element and\n\t     * concatenating all the elements into a single string.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig String -> [a] -> String\n\t     * @param {Number|String} separator The string used to separate the elements.\n\t     * @param {Array} xs The elements to join into a string.\n\t     * @return {String} str The string made by concatenating `xs` with `separator`.\n\t     * @see R.split\n\t     * @example\n\t     *\n\t     *      var spacer = R.join(' ');\n\t     *      spacer(['a', 2, 3.4]);   //=> 'a 2 3.4'\n\t     *      R.join('|', [1, 2, 3]);    //=> '1|2|3'\n\t     */\n\t    var join = invoker(1, 'join');\n\n\t    /**\n\t     * Creates a new function that, when invoked, caches the result of calling `fn`\n\t     * for a given argument set and returns the result. Subsequent calls to the\n\t     * memoized `fn` with the same argument set will not result in an additional\n\t     * call to `fn`; instead, the cached result for that set of arguments will be\n\t     * returned.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Function\n\t     * @sig (*... -> a) -> (*... -> a)\n\t     * @param {Function} fn The function to memoize.\n\t     * @return {Function} Memoized version of `fn`.\n\t     * @example\n\t     *\n\t     *      var count = 0;\n\t     *      var factorial = R.memoize(n => {\n\t     *        count += 1;\n\t     *        return R.product(R.range(1, n + 1));\n\t     *      });\n\t     *      factorial(5); //=> 120\n\t     *      factorial(5); //=> 120\n\t     *      factorial(5); //=> 120\n\t     *      count; //=> 1\n\t     */\n\t    var memoize = _curry1(function memoize(fn) {\n\t        var cache = {};\n\t        return _arity(fn.length, function () {\n\t            var key = toString(arguments);\n\t            if (!_has(key, cache)) {\n\t                cache[key] = fn.apply(this, arguments);\n\t            }\n\t            return cache[key];\n\t        });\n\t    });\n\n\t    /**\n\t     * Splits a string into an array of strings based on the given\n\t     * separator.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category String\n\t     * @sig (String | RegExp) -> String -> [String]\n\t     * @param {String|RegExp} sep The pattern.\n\t     * @param {String} str The string to separate into an array.\n\t     * @return {Array} The array of strings from `str` separated by `str`.\n\t     * @see R.join\n\t     * @example\n\t     *\n\t     *      var pathComponents = R.split('/');\n\t     *      R.tail(pathComponents('/usr/local/bin/node')); //=> ['usr', 'local', 'bin', 'node']\n\t     *\n\t     *      R.split('.', 'a.b.c.xyz.d'); //=> ['a', 'b', 'c', 'xyz', 'd']\n\t     */\n\t    var split = invoker(1, 'split');\n\n\t    /**\n\t     * Finds the set (i.e. no duplicates) of all elements contained in the first or\n\t     * second list, but not both.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.19.0\n\t     * @category Relation\n\t     * @sig [*] -> [*] -> [*]\n\t     * @param {Array} list1 The first list.\n\t     * @param {Array} list2 The second list.\n\t     * @return {Array} The elements in `list1` or `list2`, but not both.\n\t     * @see R.symmetricDifferenceWith, R.difference, R.differenceWith\n\t     * @example\n\t     *\n\t     *      R.symmetricDifference([1,2,3,4], [7,6,5,4,3]); //=> [1,2,7,6,5]\n\t     *      R.symmetricDifference([7,6,5,4,3], [1,2,3,4]); //=> [7,6,5,1,2]\n\t     */\n\t    var symmetricDifference = _curry2(function symmetricDifference(list1, list2) {\n\t        return concat(difference(list1, list2), difference(list2, list1));\n\t    });\n\n\t    /**\n\t     * Finds the set (i.e. no duplicates) of all elements contained in the first or\n\t     * second list, but not both. Duplication is determined according to the value\n\t     * returned by applying the supplied predicate to two list elements.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.19.0\n\t     * @category Relation\n\t     * @sig (a -> a -> Boolean) -> [a] -> [a] -> [a]\n\t     * @param {Function} pred A predicate used to test whether two items are equal.\n\t     * @param {Array} list1 The first list.\n\t     * @param {Array} list2 The second list.\n\t     * @return {Array} The elements in `list1` or `list2`, but not both.\n\t     * @see R.symmetricDifference, R.difference, R.differenceWith\n\t     * @example\n\t     *\n\t     *      var eqA = R.eqBy(R.prop('a'));\n\t     *      var l1 = [{a: 1}, {a: 2}, {a: 3}, {a: 4}];\n\t     *      var l2 = [{a: 3}, {a: 4}, {a: 5}, {a: 6}];\n\t     *      R.symmetricDifferenceWith(eqA, l1, l2); //=> [{a: 1}, {a: 2}, {a: 5}, {a: 6}]\n\t     */\n\t    var symmetricDifferenceWith = _curry3(function symmetricDifferenceWith(pred, list1, list2) {\n\t        return concat(differenceWith(pred, list1, list2), differenceWith(pred, list2, list1));\n\t    });\n\n\t    /**\n\t     * Determines whether a given string matches a given regular expression.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.12.0\n\t     * @category String\n\t     * @sig RegExp -> String -> Boolean\n\t     * @param {RegExp} pattern\n\t     * @param {String} str\n\t     * @return {Boolean}\n\t     * @see R.match\n\t     * @example\n\t     *\n\t     *      R.test(/^x/, 'xyz'); //=> true\n\t     *      R.test(/^y/, 'xyz'); //=> false\n\t     */\n\t    var test = _curry2(function test(pattern, str) {\n\t        if (!_isRegExp(pattern)) {\n\t            throw new TypeError('\\u2018test\\u2019 requires a value of type RegExp as its first argument; received ' + toString(pattern));\n\t        }\n\t        return _cloneRegExp(pattern).test(str);\n\t    });\n\n\t    /**\n\t     * The lower case version of a string.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.9.0\n\t     * @category String\n\t     * @sig String -> String\n\t     * @param {String} str The string to lower case.\n\t     * @return {String} The lower case version of `str`.\n\t     * @see R.toUpper\n\t     * @example\n\t     *\n\t     *      R.toLower('XYZ'); //=> 'xyz'\n\t     */\n\t    var toLower = invoker(0, 'toLowerCase');\n\n\t    /**\n\t     * The upper case version of a string.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.9.0\n\t     * @category String\n\t     * @sig String -> String\n\t     * @param {String} str The string to upper case.\n\t     * @return {String} The upper case version of `str`.\n\t     * @see R.toLower\n\t     * @example\n\t     *\n\t     *      R.toUpper('abc'); //=> 'ABC'\n\t     */\n\t    var toUpper = invoker(0, 'toUpperCase');\n\n\t    /**\n\t     * Returns a new list containing only one copy of each element in the original\n\t     * list, based upon the value returned by applying the supplied function to\n\t     * each list element. Prefers the first item if the supplied function produces\n\t     * the same value on two items. `R.equals` is used for comparison.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.16.0\n\t     * @category List\n\t     * @sig (a -> b) -> [a] -> [a]\n\t     * @param {Function} fn A function used to produce a value to use during comparisons.\n\t     * @param {Array} list The array to consider.\n\t     * @return {Array} The list of unique items.\n\t     * @example\n\t     *\n\t     *      R.uniqBy(Math.abs, [-1, -5, 2, 10, 1, 2]); //=> [-1, -5, 2, 10]\n\t     */\n\t    var uniqBy = _curry2(function uniqBy(fn, list) {\n\t        var set = new _Set();\n\t        var result = [];\n\t        var idx = 0;\n\t        var appliedItem, item;\n\t        while (idx < list.length) {\n\t            item = list[idx];\n\t            appliedItem = fn(item);\n\t            if (set.add(appliedItem)) {\n\t                result.push(item);\n\t            }\n\t            idx += 1;\n\t        }\n\t        return result;\n\t    });\n\n\t    /**\n\t     * Returns a new list containing only one copy of each element in the original\n\t     * list. `R.equals` is used to determine equality.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category List\n\t     * @sig [a] -> [a]\n\t     * @param {Array} list The array to consider.\n\t     * @return {Array} The list of unique items.\n\t     * @example\n\t     *\n\t     *      R.uniq([1, 1, 2, 1]); //=> [1, 2]\n\t     *      R.uniq([1, '1']);     //=> [1, '1']\n\t     *      R.uniq([[42], [42]]); //=> [[42]]\n\t     */\n\t    var uniq = uniqBy(identity);\n\n\t    /**\n\t     * Combines two lists into a set (i.e. no duplicates) composed of those\n\t     * elements common to both lists.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Relation\n\t     * @sig [*] -> [*] -> [*]\n\t     * @param {Array} list1 The first list.\n\t     * @param {Array} list2 The second list.\n\t     * @return {Array} The list of elements found in both `list1` and `list2`.\n\t     * @see R.intersectionWith\n\t     * @example\n\t     *\n\t     *      R.intersection([1,2,3,4], [7,6,5,4,3]); //=> [4, 3]\n\t     */\n\t    var intersection = _curry2(function intersection(list1, list2) {\n\t        var lookupList, filteredList;\n\t        if (list1.length > list2.length) {\n\t            lookupList = list1;\n\t            filteredList = list2;\n\t        } else {\n\t            lookupList = list2;\n\t            filteredList = list1;\n\t        }\n\t        return uniq(_filter(flip(_contains)(lookupList), filteredList));\n\t    });\n\n\t    /**\n\t     * Combines two lists into a set (i.e. no duplicates) composed of the elements\n\t     * of each list.\n\t     *\n\t     * @func\n\t     * @memberOf R\n\t     * @since v0.1.0\n\t     * @category Relation\n\t     * @sig [*] -> [*] -> [*]\n\t     * @param {Array} as The first list.\n\t     * @param {Array} bs The second list.\n\t     * @return {Array} The first and second lists concatenated, with\n\t     *         duplicates removed.\n\t     * @example\n\t     *\n\t     *      R.union([1, 2, 3], [2, 3, 4]); //=> [1, 2, 3, 4]\n\t     */\n\t    var union = _curry2(compose(uniq, _concat));\n\n\t    var R = {\n\t        F: F,\n\t        T: T,\n\t        __: __,\n\t        add: add,\n\t        addIndex: addIndex,\n\t        adjust: adjust,\n\t        all: all,\n\t        allPass: allPass,\n\t        always: always,\n\t        and: and,\n\t        any: any,\n\t        anyPass: anyPass,\n\t        ap: ap,\n\t        aperture: aperture,\n\t        append: append,\n\t        apply: apply,\n\t        applySpec: applySpec,\n\t        assoc: assoc,\n\t        assocPath: assocPath,\n\t        binary: binary,\n\t        bind: bind,\n\t        both: both,\n\t        call: call,\n\t        chain: chain,\n\t        clamp: clamp,\n\t        clone: clone,\n\t        comparator: comparator,\n\t        complement: complement,\n\t        compose: compose,\n\t        composeK: composeK,\n\t        composeP: composeP,\n\t        concat: concat,\n\t        cond: cond,\n\t        construct: construct,\n\t        constructN: constructN,\n\t        contains: contains,\n\t        converge: converge,\n\t        countBy: countBy,\n\t        curry: curry,\n\t        curryN: curryN,\n\t        dec: dec,\n\t        defaultTo: defaultTo,\n\t        difference: difference,\n\t        differenceWith: differenceWith,\n\t        dissoc: dissoc,\n\t        dissocPath: dissocPath,\n\t        divide: divide,\n\t        drop: drop,\n\t        dropLast: dropLast,\n\t        dropLastWhile: dropLastWhile,\n\t        dropRepeats: dropRepeats,\n\t        dropRepeatsWith: dropRepeatsWith,\n\t        dropWhile: dropWhile,\n\t        either: either,\n\t        empty: empty,\n\t        eqBy: eqBy,\n\t        eqProps: eqProps,\n\t        equals: equals,\n\t        evolve: evolve,\n\t        filter: filter,\n\t        find: find,\n\t        findIndex: findIndex,\n\t        findLast: findLast,\n\t        findLastIndex: findLastIndex,\n\t        flatten: flatten,\n\t        flip: flip,\n\t        forEach: forEach,\n\t        fromPairs: fromPairs,\n\t        groupBy: groupBy,\n\t        groupWith: groupWith,\n\t        gt: gt,\n\t        gte: gte,\n\t        has: has,\n\t        hasIn: hasIn,\n\t        head: head,\n\t        identical: identical,\n\t        identity: identity,\n\t        ifElse: ifElse,\n\t        inc: inc,\n\t        indexBy: indexBy,\n\t        indexOf: indexOf,\n\t        init: init,\n\t        insert: insert,\n\t        insertAll: insertAll,\n\t        intersection: intersection,\n\t        intersectionWith: intersectionWith,\n\t        intersperse: intersperse,\n\t        into: into,\n\t        invert: invert,\n\t        invertObj: invertObj,\n\t        invoker: invoker,\n\t        is: is,\n\t        isArrayLike: isArrayLike,\n\t        isEmpty: isEmpty,\n\t        isNil: isNil,\n\t        join: join,\n\t        juxt: juxt,\n\t        keys: keys,\n\t        keysIn: keysIn,\n\t        last: last,\n\t        lastIndexOf: lastIndexOf,\n\t        length: length,\n\t        lens: lens,\n\t        lensIndex: lensIndex,\n\t        lensPath: lensPath,\n\t        lensProp: lensProp,\n\t        lift: lift,\n\t        liftN: liftN,\n\t        lt: lt,\n\t        lte: lte,\n\t        map: map,\n\t        mapAccum: mapAccum,\n\t        mapAccumRight: mapAccumRight,\n\t        mapObjIndexed: mapObjIndexed,\n\t        match: match,\n\t        mathMod: mathMod,\n\t        max: max,\n\t        maxBy: maxBy,\n\t        mean: mean,\n\t        median: median,\n\t        memoize: memoize,\n\t        merge: merge,\n\t        mergeAll: mergeAll,\n\t        mergeWith: mergeWith,\n\t        mergeWithKey: mergeWithKey,\n\t        min: min,\n\t        minBy: minBy,\n\t        modulo: modulo,\n\t        multiply: multiply,\n\t        nAry: nAry,\n\t        negate: negate,\n\t        none: none,\n\t        not: not,\n\t        nth: nth,\n\t        nthArg: nthArg,\n\t        objOf: objOf,\n\t        of: of,\n\t        omit: omit,\n\t        once: once,\n\t        or: or,\n\t        over: over,\n\t        pair: pair,\n\t        partial: partial,\n\t        partialRight: partialRight,\n\t        partition: partition,\n\t        path: path,\n\t        pathEq: pathEq,\n\t        pathOr: pathOr,\n\t        pathSatisfies: pathSatisfies,\n\t        pick: pick,\n\t        pickAll: pickAll,\n\t        pickBy: pickBy,\n\t        pipe: pipe,\n\t        pipeK: pipeK,\n\t        pipeP: pipeP,\n\t        pluck: pluck,\n\t        prepend: prepend,\n\t        product: product,\n\t        project: project,\n\t        prop: prop,\n\t        propEq: propEq,\n\t        propIs: propIs,\n\t        propOr: propOr,\n\t        propSatisfies: propSatisfies,\n\t        props: props,\n\t        range: range,\n\t        reduce: reduce,\n\t        reduceBy: reduceBy,\n\t        reduceRight: reduceRight,\n\t        reduceWhile: reduceWhile,\n\t        reduced: reduced,\n\t        reject: reject,\n\t        remove: remove,\n\t        repeat: repeat,\n\t        replace: replace,\n\t        reverse: reverse,\n\t        scan: scan,\n\t        sequence: sequence,\n\t        set: set,\n\t        slice: slice,\n\t        sort: sort,\n\t        sortBy: sortBy,\n\t        split: split,\n\t        splitAt: splitAt,\n\t        splitEvery: splitEvery,\n\t        splitWhen: splitWhen,\n\t        subtract: subtract,\n\t        sum: sum,\n\t        symmetricDifference: symmetricDifference,\n\t        symmetricDifferenceWith: symmetricDifferenceWith,\n\t        tail: tail,\n\t        take: take,\n\t        takeLast: takeLast,\n\t        takeLastWhile: takeLastWhile,\n\t        takeWhile: takeWhile,\n\t        tap: tap,\n\t        test: test,\n\t        times: times,\n\t        toLower: toLower,\n\t        toPairs: toPairs,\n\t        toPairsIn: toPairsIn,\n\t        toString: toString,\n\t        toUpper: toUpper,\n\t        transduce: transduce,\n\t        transpose: transpose,\n\t        traverse: traverse,\n\t        trim: trim,\n\t        tryCatch: tryCatch,\n\t        type: type,\n\t        unapply: unapply,\n\t        unary: unary,\n\t        uncurryN: uncurryN,\n\t        unfold: unfold,\n\t        union: union,\n\t        unionWith: unionWith,\n\t        uniq: uniq,\n\t        uniqBy: uniqBy,\n\t        uniqWith: uniqWith,\n\t        unless: unless,\n\t        unnest: unnest,\n\t        until: until,\n\t        update: update,\n\t        useWith: useWith,\n\t        values: values,\n\t        valuesIn: valuesIn,\n\t        view: view,\n\t        when: when,\n\t        where: where,\n\t        whereEq: whereEq,\n\t        without: without,\n\t        wrap: wrap,\n\t        xprod: xprod,\n\t        zip: zip,\n\t        zipObj: zipObj,\n\t        zipWith: zipWith\n\t    };\n\t  /* eslint-env amd */\n\n\t  /* TEST_ENTRY_POINT */\n\n\t  if (true) {\n\t    module.exports = R;\n\t  } else if (typeof define === 'function' && define.amd) {\n\t    define(function() { return R; });\n\t  } else {\n\t    this.R = R;\n\t  }\n\n\t}.call(this));\n\n\n/***/ },\n/* 21 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports = {\n\t    Either: __webpack_require__(22),\n\t    Future: __webpack_require__(24),\n\t    Identity: __webpack_require__(25),\n\t    IO: __webpack_require__(26),\n\t    lift2: __webpack_require__(27),\n\t    lift3: __webpack_require__(28),\n\t    Maybe: __webpack_require__(29),\n\t    Tuple: __webpack_require__(30),\n\t    Reader: __webpack_require__(31)\n\t};\n\n\n/***/ },\n/* 22 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar R = __webpack_require__(20);\n\n\tvar util = __webpack_require__(23);\n\n\n\tfunction Either(left, right) {\n\t  switch (arguments.length) {\n\t    case 0:\n\t      throw new TypeError('no arguments to Either');\n\t    case 1:\n\t      return function(right) {\n\t        return right == null ? Either.Left(left) : Either.Right(right);\n\t      };\n\t    default:\n\t      return right == null ? Either.Left(left) : Either.Right(right);\n\t  }\n\t}\n\n\tEither.prototype['@@type'] = 'ramda-fantasy/Either';\n\n\tEither.prototype.map = util.returnThis;\n\n\tEither.of = Either.prototype.of = function(value) {\n\t  return Either.Right(value);\n\t};\n\n\tEither.prototype.chain = util.returnThis; // throw?\n\n\n\tEither.equals = Either.prototype.equals = util.getEquals(Either);\n\n\tEither.either = R.curry(function either(leftFn, rightFn, e) {\n\t  if (e instanceof _Left) {\n\t    return leftFn(e.value);\n\t  } else if (e instanceof _Right) {\n\t    return rightFn(e.value);\n\t  } else {\n\t    throw new TypeError('invalid type given to Either.either');\n\t  }\n\t});\n\n\tEither.isLeft = function(x) {\n\t  return x.isLeft;\n\t};\n\n\tEither.isRight = function(x) {\n\t  return x.isRight;\n\t};\n\n\n\t// Right\n\tfunction _Right(x) {\n\t  this.value = x;\n\t}\n\tutil.extend(_Right, Either);\n\n\t_Right.prototype.isRight = true;\n\t_Right.prototype.isLeft = false;\n\n\t_Right.prototype.map = function(fn) {\n\t  return new _Right(fn(this.value));\n\t};\n\n\t_Right.prototype.ap = function(that) {\n\t  return that.map(this.value);\n\t};\n\n\t_Right.prototype.chain = function(f) {\n\t  return f(this.value);\n\t};\n\n\t_Right.prototype.bimap = function(_, f) {\n\t  return new _Right(f(this.value));\n\t};\n\n\t_Right.prototype.extend = function(f) {\n\t  return new _Right(f(this));\n\t};\n\n\t_Right.prototype.toString = function() {\n\t  return 'Either.Right(' + R.toString(this.value) + ')';\n\t};\n\n\tEither.Right = function(value) {\n\t  return new _Right(value);\n\t};\n\n\n\t// Left\n\tfunction _Left(x) {\n\t  this.value = x;\n\t}\n\tutil.extend(_Left, Either);\n\n\t_Left.prototype.isLeft = true;\n\t_Left.prototype.isRight = false;\n\n\t_Left.prototype.ap = util.returnThis;\n\n\t_Left.prototype.bimap = function(f) {\n\t  return new _Left(f(this.value));\n\t};\n\n\t_Left.prototype.extend = util.returnThis;\n\n\t_Left.prototype.toString = function() {\n\t  return 'Either.Left(' + R.toString(this.value) + ')';\n\t};\n\n\tEither.Left = function(value) {\n\t  return new _Left(value);\n\t};\n\n\n\tmodule.exports = Either;\n\n\n/***/ },\n/* 23 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar _equals = __webpack_require__(20).equals;\n\n\n\tmodule.exports = {\n\n\t  baseMap: function(f) {\n\t    return f(this.value);\n\t  },\n\n\t  getEquals: function(constructor) {\n\t    return function equals(that) {\n\t      return that instanceof constructor && _equals(this.value, that.value);\n\t    };\n\t  },\n\n\t  extend: function(Child, Parent) {\n\t    function Ctor() {\n\t      this.constructor = Child;\n\t    }\n\t    Ctor.prototype = Parent.prototype;\n\t    Child.prototype = new Ctor();\n\t    Child.super_ = Parent.prototype;\n\t  },\n\n\t  identity: function(x) { return x; },\n\n\t  notImplemented: function(str) {\n\t    return function() {\n\t      throw new Error(str + ' is not implemented');\n\t    };\n\t  },\n\n\t  notCallable: function(fn) {\n\t    return function() {\n\t      throw new Error(fn + ' cannot be called directly');\n\t    };\n\t  },\n\n\t  returnThis: function() { return this; }\n\n\t};\n\n\n/***/ },\n/* 24 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar R = __webpack_require__(20);\n\n\tfunction jail(handler, f){\n\t  return function(a){\n\t    try{\n\t      return f(a);\n\t    } catch(err) {\n\t      handler(err);\n\t    }\n\t  };\n\t}\n\n\t// `f` is a function that takes two function arguments: `reject` (failure) and `resolve` (success)\n\tfunction Future(f) {\n\t  if (!(this instanceof Future)) {\n\t    return new Future(f);\n\t  }\n\t  this._fork = f;\n\t}\n\n\tFuture.prototype['@@type'] = 'ramda-fantasy/Future';\n\n\tFuture.prototype.fork = function(reject, resolve) {\n\t  this._fork(reject, jail(reject, resolve));\n\t};\n\n\t// functor\n\tFuture.prototype.map = function(f) {\n\t  return this.chain(function(a) { return Future.of(f(a)); });\n\t};\n\n\t// apply\n\tFuture.prototype.ap = function(m) {\n\t  var self = this;\n\n\t  return new Future(function(rej, res) {\n\t    var applyFn, val;\n\t    var doReject = R.once(rej);\n\n\t    var resolveIfDone = jail(doReject, function() {\n\t      if (applyFn != null && val != null) {\n\t        return res(applyFn(val));\n\t      }\n\t    });\n\n\t    self._fork(doReject, function(fn) {\n\t      applyFn = fn;\n\t      resolveIfDone();\n\t    });\n\n\t    m._fork(doReject, function(v) {\n\t      val = v;\n\t      resolveIfDone();\n\t    });\n\n\t  });\n\n\t};\n\n\t// applicative\n\tFuture.of = function(x) {\n\t  // should include a default rejection?\n\t  return new Future(function(_, resolve) { return resolve(x); });\n\t};\n\n\tFuture.prototype.of = Future.of;\n\n\t// chain\n\t//  f must be a function which returns a value\n\t//  f must return a value of the same Chain\n\t//  chain must return a value of the same Chain\n\t//:: Future a, b => (b -> Future c) -> Future c\n\tFuture.prototype.chain = function(f) {  // Sorella's:\n\t  return new Future(function(reject, resolve) {\n\t    return this._fork(\n\t      function(a) { return reject(a); },\n\t      jail(reject, function(b) { return f(b)._fork(reject, resolve); })\n\t    );\n\t  }.bind(this));\n\t};\n\n\t// chainReject\n\t// Like chain but operates on the reject instead of the resolve case.\n\t//:: Future a, b => (a -> Future c) -> Future c\n\tFuture.prototype.chainReject = function(f) {\n\t  return new Future(function(reject, resolve) {\n\t    return this._fork(\n\t      jail(reject, function(a) { return f(a)._fork(reject, resolve); }),\n\t      function(b) { return resolve(b); }\n\t    );\n\t  }.bind(this));\n\t};\n\n\t// monad\n\t// A value that implements the Monad specification must also implement the Applicative and Chain specifications.\n\t// see above.\n\n\tFuture.prototype.bimap = function(errFn, successFn) {\n\t  var self = this;\n\t  return new Future(function(reject, resolve) {\n\t    self._fork(\n\t      jail(reject, function(err) { reject(errFn(err)); }),\n\t      jail(reject, function(val) { resolve(successFn(val)); })\n\t    );\n\t  });\n\t};\n\n\tFuture.reject = function(val) {\n\t  return new Future(function(reject) {\n\t    reject(val);\n\t  });\n\t};\n\n\tFuture.prototype.toString = function() {\n\t  return 'Future(' + R.toString(this._fork) + ')';\n\t};\n\n\tFuture.cache = function(f) {\n\t  var status = 'IDLE';\n\t  var listeners = [];\n\t  var cachedValue;\n\n\t  var handleCompletion = R.curry(function(newStatus, cb, val) {\n\t    status = newStatus;\n\t    cachedValue = val;\n\t    cb(val);\n\t    R.forEach(function(listener) {\n\t      listener[status](cachedValue);\n\t    }, listeners);\n\t  });\n\n\t  function addListeners(reject, resolve) {\n\t    listeners.push({ REJECTED: reject, RESOLVED: resolve } );\n\t  }\n\n\t  function doResolve(reject, resolve) {\n\t    status = 'PENDING';\n\t    return f._fork(\n\t      handleCompletion('REJECTED', reject),\n\t      handleCompletion('RESOLVED', resolve)\n\t    );\n\t  }\n\n\t  return new Future(function(reject, resolve) {\n\n\t    switch(status) {\n\t      case 'IDLE': doResolve(reject, resolve); break;\n\t      case 'PENDING': addListeners(reject, resolve); break;\n\t      case 'REJECTED': reject(cachedValue); break;\n\t      case 'RESOLVED': resolve(cachedValue); break;\n\t    }\n\n\t  });\n\t};\n\n\tmodule.exports = Future;\n\n\n/***/ },\n/* 25 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar R = __webpack_require__(20);\n\n\tvar util = __webpack_require__(23);\n\n\n\t/**\n\t * A data type that holds a value and exposes a monadic api.\n\t */\n\n\t/**\n\t * Constructs a new `Identity[a]` data type that holds a single\n\t * value `a`.\n\t * @param {*} a Value of any type\n\t * @sig a -> Identity[a]\n\t */\n\tfunction Identity(x) {\n\t  if (!(this instanceof Identity)) {\n\t    return new Identity(x);\n\t  }\n\t  this.value = x;\n\t}\n\n\tIdentity.prototype['@@type'] = 'ramda-fantasy/Identity';\n\n\t/**\n\t * Applicative specification. Creates a new `Identity[a]` holding the value `a`.\n\t * @param {*} a Value of any type\n\t * @returns Identity[a]\n\t * @sig a -> Identity[a]\n\t */\n\tIdentity.of = function(x) {\n\t  return new Identity(x);\n\t};\n\tIdentity.prototype.of = Identity.of;\n\n\t/**\n\t * Functor specification. Creates a new `Identity[a]` mapping function `f` onto\n\t * `a` returning any value b.\n\t * @param {Function} f Maps `a` to any value `b`\n\t * @returns Identity[b]\n\t * @sig @Identity[a] => (a -> b) -> Identity[b]\n\t */\n\tIdentity.prototype.map = function(f) {\n\t  return new Identity(f(this.value));\n\t};\n\n\t/**\n\t * Apply specification. Applies the function inside the `Identity[a]`\n\t * type to another applicative type.\n\t * @param {Applicative[a]} app Applicative that will apply its function\n\t * @returns Applicative[b]\n\t * @sig (Identity[a -> b], f: Applicative[_]) => f[a] -> f[b]\n\t */\n\tIdentity.prototype.ap = function(app) {\n\t  return app.map(this.value);\n\t};\n\n\t/**\n\t * Chain specification. Transforms the value of the `Identity[a]`\n\t * type using an unary function to monads. The `Identity[a]` type\n\t * should contain a function, otherwise an error is thrown.\n\t *\n\t * @param {Function} fn Transforms `a` into a `Monad[b]`\n\t * @returns Monad[b]\n\t * @sig (Identity[a], m: Monad[_]) => (a -> m[b]) -> m[b]\n\t */\n\tIdentity.prototype.chain = function(fn) {\n\t  return fn(this.value);\n\t};\n\n\t/**\n\t * Returns the value of `Identity[a]`\n\t *\n\t * @returns a\n\t * @sig (Identity[a]) => a\n\t */\n\tIdentity.prototype.get = function() {\n\t  return this.value;\n\t};\n\n\t// equality method to enable testing\n\tIdentity.prototype.equals = util.getEquals(Identity);\n\n\tIdentity.prototype.toString = function() {\n\t  return 'Identity(' + R.toString(this.value) + ')';\n\t};\n\n\tmodule.exports = Identity;\n\n\n/***/ },\n/* 26 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar R = __webpack_require__(20);\n\n\tmodule.exports = IO;\n\n\tvar compose = R.compose;\n\n\tfunction IO(fn) {\n\t  if (!(this instanceof IO)) {\n\t    return new IO(fn);\n\t  }\n\t  this.fn = fn;\n\t}\n\n\tIO.prototype['@@type'] = 'ramda-fantasy/IO';\n\n\t// `f` must return an IO\n\tIO.prototype.chain = function(f) {\n\t  var io = this;\n\t  return new IO(function() {\n\t    var next = f(io.fn.apply(io, arguments));\n\t    return next.fn.apply(next, arguments);\n\t  });\n\t};\n\n\tIO.prototype.map = function(f) {\n\t  var io = this;\n\t  return new IO(compose(f, io.fn));\n\t};\n\n\t// `this` IO must wrap a function `f` that takes an IO (`thatIo`) as input\n\t// `f` must return an IO\n\tIO.prototype.ap = function(thatIo) {\n\t  return this.chain(function(f) {\n\t    return thatIo.map(f);\n\t  });\n\t};\n\n\tIO.runIO = function(io) {\n\t  return io.runIO.apply(io, [].slice.call(arguments, 1));\n\t};\n\n\tIO.prototype.runIO = function() {\n\t  return this.fn.apply(this, arguments);\n\t};\n\n\tIO.prototype.of = function(x) {\n\t  return new IO(function() { return x; });\n\t};\n\n\tIO.of = IO.prototype.of;\n\n\tIO.prototype.toString = function() {\n\t  return 'IO(' + R.toString(this.fn) + ')';\n\t};\n\n\n/***/ },\n/* 27 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar R = __webpack_require__(20);\n\n\tmodule.exports = R.curryN(3, function lift2(f, a1, a2) {\n\t  return a1.map(f).ap(a2);\n\t});\n\n\n/***/ },\n/* 28 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar R = __webpack_require__(20);\n\n\tmodule.exports = R.curryN(4, function lift3(f, a1, a2, a3) {\n\t  return a1.map(f).ap(a2).ap(a3);\n\t});\n\n\n/***/ },\n/* 29 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar R = __webpack_require__(20);\n\n\tvar util = __webpack_require__(23);\n\n\tfunction Maybe(x) {\n\t  return x == null ? _nothing : Maybe.Just(x);\n\t}\n\n\tMaybe.prototype['@@type'] = 'ramda-fantasy/Maybe';\n\n\tfunction Just(x) {\n\t  this.value = x;\n\t}\n\tutil.extend(Just, Maybe);\n\n\tJust.prototype.isJust = true;\n\tJust.prototype.isNothing = false;\n\n\tfunction Nothing() {}\n\tutil.extend(Nothing, Maybe);\n\n\tNothing.prototype.isNothing = true;\n\tNothing.prototype.isJust = false;\n\n\tvar _nothing = new Nothing();\n\n\tMaybe.Nothing = function() {\n\t  return _nothing;\n\t};\n\n\tMaybe.Just = function(x) {\n\t  return new Just(x);\n\t};\n\n\tMaybe.of = Maybe.Just;\n\n\tMaybe.prototype.of = Maybe.Just;\n\n\tMaybe.isJust = function(x) {\n\t  return x.isJust;\n\t};\n\n\tMaybe.isNothing = function(x) {\n\t  return x.isNothing;\n\t};\n\n\tMaybe.maybe = R.curry(function(nothingVal, justFn, m) {\n\t  return m.reduce(function(_, x) {\n\t    return justFn(x);\n\t  }, nothingVal);\n\t});\n\n\t// functor\n\tJust.prototype.map = function(f) {\n\t  return this.of(f(this.value));\n\t};\n\n\tNothing.prototype.map = util.returnThis;\n\n\t// apply\n\t// takes a Maybe that wraps a function (`app`) and applies its `map`\n\t// method to this Maybe's value, which must be a function.\n\tJust.prototype.ap = function(m) {\n\t  return m.map(this.value);\n\t};\n\n\tNothing.prototype.ap = util.returnThis;\n\n\t// applicative\n\t// `of` inherited from `Maybe`\n\n\n\t// chain\n\t//  f must be a function which returns a value\n\t//  f must return a value of the same Chain\n\t//  chain must return a value of the same Chain\n\tJust.prototype.chain = util.baseMap;\n\n\tNothing.prototype.chain = util.returnThis;\n\n\n\t//\n\tJust.prototype.datatype = Just;\n\n\tNothing.prototype.datatype = Nothing;\n\n\t// monad\n\t// A value that implements the Monad specification must also implement the Applicative and Chain specifications.\n\t// see above.\n\n\t// equality method to enable testing\n\tJust.prototype.equals = util.getEquals(Just);\n\n\tNothing.prototype.equals = function(that) {\n\t  return that === _nothing;\n\t};\n\n\tMaybe.prototype.isNothing = function() {\n\t  return this === _nothing;\n\t};\n\n\tMaybe.prototype.isJust = function() {\n\t  return this instanceof Just;\n\t};\n\n\tJust.prototype.getOrElse = function() {\n\t  return this.value;\n\t};\n\n\tNothing.prototype.getOrElse = function(a) {\n\t  return a;\n\t};\n\n\tJust.prototype.reduce = function(f, x) {\n\t  return f(x, this.value);\n\t};\n\n\tNothing.prototype.reduce = function(f, x) {\n\t  return x;\n\t};\n\n\tJust.prototype.toString = function() {\n\t  return 'Maybe.Just(' + R.toString(this.value) + ')';\n\t};\n\n\tNothing.prototype.toString = function() {\n\t  return 'Maybe.Nothing()';\n\t};\n\n\tmodule.exports = Maybe;\n\n\n/***/ },\n/* 30 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar R = __webpack_require__(20);\n\n\n\tfunction Tuple(x, y) {\n\t  switch (arguments.length) {\n\t    case 0:\n\t      throw new TypeError('no arguments to Tuple');\n\t    case 1:\n\t      return function(y) {\n\t        return new _Tuple(x, y);\n\t      };\n\t    default:\n\t      return new _Tuple(x, y);\n\t  }\n\t}\n\n\tfunction _Tuple(x, y) {\n\t  this[0] = x;\n\t  this[1] = y;\n\t  this.length = 2;\n\t}\n\n\tfunction ensureConcat(xs) {\n\t  xs.forEach(function(x) {\n\t    if (typeof x.concat != 'function') {\n\t      throw new TypeError(R.toString(x) + ' must be a semigroup to perform this operation');\n\t    }\n\t  });\n\t}\n\n\tTuple.fst = function(x) {\n\t  return x[0];\n\t};\n\n\tTuple.snd = function(x) {\n\t  return x[1];\n\t};\n\n\t_Tuple.prototype['@@type'] = 'ramda-fantasy/Tuple';\n\n\t// semigroup\n\t_Tuple.prototype.concat = function(x) {\n\t  ensureConcat([this[0], this[1]]);\n\t  return Tuple(this[0].concat(x[0]), this[1].concat(x[1]));\n\t};\n\n\t// functor\n\t_Tuple.prototype.map = function(f) {\n\t  return Tuple(this[0], f(this[1]));\n\t};\n\n\t// apply\n\t_Tuple.prototype.ap = function(m) {\n\t  ensureConcat([this[0]]);\n\t  return Tuple(this[0].concat(m[0]), this[1](m[1]));\n\t};\n\n\t// setoid\n\t_Tuple.prototype.equals = function(that) {\n\t  return that instanceof _Tuple && R.equals(this[0], that[0]) && R.equals(this[1], that[1]);\n\t};\n\n\t_Tuple.prototype.toString = function() {\n\t  return 'Tuple(' + R.toString(this[0]) + ', ' + R.toString(this[1]) + ')';\n\t};\n\n\tmodule.exports = Tuple;\n\n\n/***/ },\n/* 31 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar R = __webpack_require__(20);\n\n\n\tfunction Reader(run) {\n\t  if (!(this instanceof Reader)) {\n\t    return new Reader(run);\n\t  }\n\t  this.run = run;\n\t}\n\n\tReader.run = function(reader) {\n\t  return reader.run.apply(reader, [].slice.call(arguments, 1));\n\t};\n\n\tReader.prototype['@@type'] = 'ramda-fantasy/Reader';\n\n\tReader.prototype.chain = function(f) {\n\t  var reader = this;\n\t  return new Reader(function(r) {\n\t    return f(reader.run(r)).run(r);\n\t  });\n\t};\n\n\tReader.prototype.ap = function(a) {\n\t  return this.chain(function(f) {\n\t    return a.map(f);\n\t  });\n\t};\n\n\tReader.prototype.map = function(f) {\n\t  return this.chain(function(a) {\n\t    return Reader.of(f(a));\n\t  });\n\t};\n\n\tReader.prototype.of = function(a) {\n\t  return new Reader(function() {\n\t    return a;\n\t  });\n\t};\n\tReader.of = Reader.prototype.of;\n\n\tReader.ask = Reader(R.identity);\n\n\tReader.prototype.toString = function() {\n\t  return 'Reader(' + R.toString(this.run) + ')';\n\t};\n\n\tReader.T = function(M) {\n\t  var ReaderT = function ReaderT(run) {\n\t    if (!(this instanceof ReaderT)) {\n\t      return new ReaderT(run);\n\t    }\n\t    this.run = run;\n\t  };\n\n\t  ReaderT.lift = R.compose(ReaderT, R.always);\n\n\t  ReaderT.ask = ReaderT(M.of);\n\n\t  ReaderT.prototype.of = ReaderT.of = function(a) {\n\t    return ReaderT(function() {\n\t      return M.of(a);\n\t    });\n\t  };\n\n\t  ReaderT.prototype.chain = function(f) {\n\t    var readerT = this;\n\t    return ReaderT(function(e) {\n\t      var m = readerT.run(e);\n\t      return m.chain(function(a) {\n\t        return f(a).run(e);\n\t      });\n\t    });\n\t  };\n\n\t  ReaderT.prototype.map = function(f) {\n\t    return this.chain(function(a) {\n\t      return ReaderT.of(f(a));\n\t    });\n\t  };\n\n\t  ReaderT.prototype.ap = function(a) {\n\t    var readerT = this;\n\t    return ReaderT(function(e) {\n\t      return readerT.run(e).ap(a.run(e));\n\t    });\n\t  };\n\n\t  ReaderT.prototype.equals = function(that) {\n\t    return this === that ||\n\t      this.run === that.run ||\n\t      R.equals(this.run().get(), that.run().get());\n\t  };\n\n\t  ReaderT.prototype.toString = function() {\n\t    return 'ReaderT[' + M.name + '](' + R.toString(this.run) + ')';\n\t  };\n\n\t  return ReaderT;\n\t};\n\n\tmodule.exports = Reader;\n\n\n/***/ },\n/* 32 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.default = readNumericLiteral;\n\n\tvar _readtable = __webpack_require__(7);\n\n\tvar _esutils = __webpack_require__(15);\n\n\tvar _utils = __webpack_require__(14);\n\n\tvar _tokens = __webpack_require__(19);\n\n\tconst {\n\t  isIdentifierPartES6: isIdentifierPart,\n\t  isIdentifierStartES6: isIdentifierStart\n\t} = _esutils.code;\n\n\tlet terminates;\n\n\tfunction readNumericLiteral(stream) {\n\t  terminates = (0, _utils.isTerminating)((0, _readtable.getCurrentReadtable)());\n\t  let idx = 0,\n\t      char = stream.peek();\n\n\t  if (char === '0') {\n\t    char = stream.peek(++idx);\n\t    if (!(0, _readtable.isEOS)(char)) {\n\t      char = char.toLowerCase();\n\t      switch (char) {\n\t        case 'x':\n\t          return readHexLiteral.call(this, stream);\n\t        case 'b':\n\t          return readBinaryLiteral.call(this, stream);\n\t        case 'o':\n\t          return readOctalLiteral.call(this, stream);\n\t        default:\n\t          if (isDecimalChar(char)) {\n\t            return readLegacyOctalLiteral.call(this, stream); // reads legacy octal and decimal\n\t          }\n\t      }\n\t    } else {\n\t      return new _tokens.NumericToken({\n\t        value: +stream.readString()\n\t      });\n\t    }\n\t  } else if (char !== '.') {\n\t    while (!terminates(char) && isDecimalChar(char)) {\n\t      char = stream.peek(++idx);\n\t    }\n\t    if ((0, _readtable.isEOS)(char)) {\n\t      return new _tokens.NumericToken({\n\t        value: +stream.readString(idx)\n\t      });\n\t    }\n\t  }\n\n\t  idx = addDecimalLiteralSuffixLength.call(this, stream, idx);\n\n\t  char = stream.peek(idx);\n\t  if (!(0, _readtable.isEOS)(char) && !terminates(char) && isIdentifierStart(char)) {\n\t    throw this.createILLEGAL(char);\n\t  }\n\n\t  return new _tokens.NumericToken({\n\t    value: +stream.readString(idx)\n\t  });\n\t}\n\n\tfunction addDecimalLiteralSuffixLength(stream, idx) {\n\t  let char = stream.peek(idx);\n\t  if (char === '.') {\n\t    char = stream.peek(++idx);\n\t    if ((0, _readtable.isEOS)(char)) return idx;\n\n\t    while (isDecimalChar(char)) {\n\t      char = stream.peek(++idx);\n\t      if (terminates(char) || (0, _readtable.isEOS)(char)) return idx;\n\t    }\n\t  }\n\n\t  if (char.toLowerCase() === 'e') {\n\t    char = stream.peek(++idx);\n\t    if ((0, _readtable.isEOS)(char)) throw this.createILLEGAL(char);\n\n\t    if (char === '+' || char === '-') {\n\t      char = stream.peek(++idx);\n\t      if ((0, _readtable.isEOS)(char)) throw this.createILLEGAL(char);\n\t    }\n\n\t    while (isDecimalChar(char)) {\n\t      char = stream.peek(++idx);\n\t      if (terminates(char) || (0, _readtable.isEOS)(char)) break;\n\t    }\n\t  }\n\t  return idx;\n\t}\n\n\tfunction readLegacyOctalLiteral(stream) {\n\t  let idx = 0,\n\t      isOctal = true,\n\t      char = stream.peek();\n\n\t  while (!terminates(char) && !(0, _readtable.isEOS)(char)) {\n\t    if ('0' <= char && char <= '7') {\n\t      idx++;\n\t    } else if (char === '8' || char === '9') {\n\t      isOctal = false;\n\t      idx++;\n\t    } else if (isIdentifierPart(char.charCodeAt(0))) {\n\t      throw this.createILLEGAL(char);\n\t    } else {\n\t      break;\n\t    }\n\n\t    char = stream.peek(idx);\n\t  }\n\n\t  if (!isOctal) return new _tokens.NumericToken({\n\t    value: parseNumeric(stream, idx, 10),\n\t    octal: true,\n\t    noctal: !isOctal\n\t  });\n\n\t  return new _tokens.NumericToken({\n\t    value: parseNumeric(stream, idx, 8),\n\t    octal: true,\n\t    noctal: !isOctal\n\t  });\n\t}\n\n\tfunction readOctalLiteral(stream) {\n\t  let start,\n\t      idx = start = 2,\n\t      char = stream.peek(idx);\n\t  while (!terminates(char) && !(0, _readtable.isEOS)(char)) {\n\t    if ('0' <= char && char <= '7') {\n\t      char = stream.peek(++idx);\n\t    } else if (isIdentifierPart(char.charCodeAt(0))) {\n\t      throw this.createILLEGAL(char);\n\t    } else {\n\t      break;\n\t    }\n\t  }\n\n\t  if (idx === start) {\n\t    throw this.createILLEGAL(char);\n\t  }\n\n\t  return new _tokens.NumericToken({\n\t    value: parseNumeric(stream, idx, 8, start)\n\t  });\n\t}\n\n\tfunction readBinaryLiteral(stream) {\n\t  let start,\n\t      idx = start = 2;\n\t  let char = stream.peek(idx);\n\n\t  while (!terminates(char) && !(0, _readtable.isEOS)(char)) {\n\t    if (char !== '0' && char !== '1') {\n\t      break;\n\t    }\n\t    char = stream.peek(idx);\n\t    idx++;\n\t  }\n\n\t  if (idx === start) {\n\t    throw this.createILLEGAL(char);\n\t  }\n\n\t  if (!(0, _readtable.isEOS)(char) && !terminates(char) && (isIdentifierStart(char) || isDecimalChar(char))) {\n\t    throw this.createILLEGAL(char);\n\t  }\n\n\t  return new _tokens.NumericToken({\n\t    value: parseNumeric(stream, idx, 2, start)\n\t  });\n\t}\n\n\tfunction readHexLiteral(stream) {\n\t  let start,\n\t      idx = start = 2,\n\t      char = stream.peek(idx);\n\t  while (!terminates(char)) {\n\t    let hex = (0, _utils.getHexValue)(char);\n\t    if (hex === -1) {\n\t      break;\n\t    }\n\t    char = stream.peek(++idx);\n\t  }\n\n\t  if (idx === start) {\n\t    throw this.createILLEGAL(char);\n\t  }\n\n\t  if (!(0, _readtable.isEOS)(char) && !terminates(char) && isIdentifierStart(char)) {\n\t    throw this.createILLEGAL(char);\n\t  }\n\n\t  return new _tokens.NumericToken({\n\t    value: parseNumeric(stream, idx, 16, start)\n\t  });\n\t}\n\n\tfunction parseNumeric(stream, len, radix, start = 0) {\n\t  stream.readString(start);\n\t  return parseInt(stream.readString(len - start), radix);\n\t}\n\n\tfunction isDecimalChar(char) {\n\t  return '0' <= char && char <= '9';\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9yZWFkZXIvcmVhZC1udW1lcmljLmpzIl0sIm5hbWVzIjpbInJlYWROdW1lcmljTGl0ZXJhbCIsImlzSWRlbnRpZmllclBhcnRFUzYiLCJpc0lkZW50aWZpZXJQYXJ0IiwiaXNJZGVudGlmaWVyU3RhcnRFUzYiLCJpc0lkZW50aWZpZXJTdGFydCIsInRlcm1pbmF0ZXMiLCJzdHJlYW0iLCJpZHgiLCJjaGFyIiwicGVlayIsInRvTG93ZXJDYXNlIiwicmVhZEhleExpdGVyYWwiLCJjYWxsIiwicmVhZEJpbmFyeUxpdGVyYWwiLCJyZWFkT2N0YWxMaXRlcmFsIiwiaXNEZWNpbWFsQ2hhciIsInJlYWRMZWdhY3lPY3RhbExpdGVyYWwiLCJ2YWx1ZSIsInJlYWRTdHJpbmciLCJhZGREZWNpbWFsTGl0ZXJhbFN1ZmZpeExlbmd0aCIsImNyZWF0ZUlMTEVHQUwiLCJpc09jdGFsIiwiY2hhckNvZGVBdCIsInBhcnNlTnVtZXJpYyIsIm9jdGFsIiwibm9jdGFsIiwic3RhcnQiLCJoZXgiLCJsZW4iLCJyYWRpeCIsInBhcnNlSW50Il0sIm1hcHBpbmdzIjoiOzs7OztrQkFnQndCQSxrQjs7QUFkeEI7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBSUEsTUFBTTtBQUNKQyx1QkFBcUJDLGdCQURqQjtBQUVKQyx3QkFBc0JDO0FBRmxCLGlCQUFOOztBQUtBLElBQUlDLFVBQUo7O0FBRWUsU0FBU0wsa0JBQVQsQ0FBNEJNLE1BQTVCLEVBQWdEO0FBQzdERCxlQUFhLDBCQUFjLHFDQUFkLENBQWI7QUFDQSxNQUFJRSxNQUFNLENBQVY7QUFBQSxNQUFhQyxPQUFPRixPQUFPRyxJQUFQLEVBQXBCOztBQUVBLE1BQUlELFNBQVMsR0FBYixFQUFrQjtBQUNoQkEsV0FBT0YsT0FBT0csSUFBUCxDQUFZLEVBQUVGLEdBQWQsQ0FBUDtBQUNBLFFBQUksQ0FBQyxzQkFBTUMsSUFBTixDQUFMLEVBQWtCO0FBQ2hCQSxhQUFPQSxLQUFLRSxXQUFMLEVBQVA7QUFDQSxjQUFR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RCxTQUFTSCxZQUFULENBQXNCakIsTUFBdEIsRUFBOEJzQixHQUE5QixFQUFtQ0MsS0FBbkMsRUFBMENILFFBQVEsQ0FBbEQsRUFBcUQ7QUFDbkRwQixTQUFPWSxVQUFQLENBQWtCUSxLQUFsQjtBQUNBLFNBQU9JLFNBQVN4QixPQUFPWSxVQUFQLENBQWtCVSxNQUFNRixLQUF4QixDQUFULEVBQXlDRyxLQUF6QyxDQUFQO0FBQ0Q7O0FBRUQsU0FBU2QsYUFBVCxDQUF1QlAsSUFBdkIsRUFBNkI7QUFDM0IsU0FBTyxPQUFPQSxJQUFQLElBQWVBLFFBQVEsR0FBOUI7QUFDRCIsImZpbGUiOiJyZWFkLW51bWVyaWMuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAZmxvd1xuXG5pbXBvcnQgeyBpc0VPUywgZ2V0Q3VycmVudFJlYWR0YWJsZSB9IGZyb20gJ3JlYWR0YWJsZSc7XG5pbXBvcnQgeyBjb2RlIH0gZnJvbSAnZXN1dGlscyc7XG5pbXBvcnQgeyBpc1Rlcm1pbmF0aW5nLCBnZXRIZXhWYWx1ZSB9IGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHsgTnVtZXJpY1Rva2VuIH0gZnJvbSAnLi4vdG9rZW5zJztcblxuaW1wb3J0IHR5cGUgeyBDaGFyU3RyZWFtIH0gZnJvbSAncmVhZHRhYmxlJztcblxuY29uc3Qge1xuICBpc0lkZW50aWZpZXJQYXJ0RVM2OiBpc0lkZW50aWZpZXJQYXJ0LFxuICBpc0lkZW50aWZpZXJTdGFydEVTNjogaXNJZGVudGlmaWVyU3RhcnQsXG59ID0gY29kZTtcblxubGV0IHRlcm1pbmF0ZXM7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHJlYWROdW1lcmljTGl0ZXJhbChzdHJlYW06IENoYXJTdHJlYW0pIHtcbiAgdGVybWluYXRlcyA9IGlzVGVybWluYXRpbmcoZ2V0Q3VycmVudFJlYWR0YWJsZSgpKTtcbiAgbGV0IGlkeCA9IDAsIGNoYXIgPSBzdHJlYW0ucGVlaygpO1xuXG4gIGlmIChjaGFyID09PSAnMCcpIHtcbiAgICBjaGFyID0gc3RyZWFtLnBlZWsoKytpZHgpO1xuICAgIGlmICghaXNFT1MoY2hhcikpIHtcbiAgICAgIGNoYXIgPSBjaGFyLnRvTG93ZXJDYXNlKCk7XG4gICAgICBzd2l0Y2ggKGNoYXIpIHtcbiAgICAgICAgY2FzZSAneCc6XG4gICAgICAgICAgcmV0dXJuIHJlYWRIZXhMaXRlcmFsLmNhbGwodGhpcywgc3RyZWFtKTtcbiAgICAgICAgY2FzZSAnYic6XG4gICAgICAgICAgcmV0dXJuIHJlYWRCaW5hcnlMaXRlcmFsLmNhbGwodGhpcywgc3RyZWFtKTtcbiAgICAgICAgY2FzZSAnbyc6XG4gICAgICAgICAgcmV0dXJuIHJlYWRPY3RhbExpdGVyYWwuY2FsbCh0aGlzLCBzdHJlYW0pO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGlmIChpc0RlY2ltYWxDaGFyKGNoYXIpKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVhZExlZ2FjeU9jdGFsTGl0ZXJhbC5jYWxsKHRoaXMsIHN0cmVhbSk7IC8vIHJlYWRzIGxlZ2FjeSBvY3RhbCBhbmQgZGVjaW1hbFxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG5ldyBOdW1lcmljVG9rZW4oe1xuICAgICAgICB2YWx1ZTogK3N0cmVhbS5yZWFkU3RyaW5nKCksXG4gICAgICB9KTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoY2hhciAhPT0gJy4nKSB7XG4gICAgd2hpbGUgKCF0ZXJtaW5hdGVzKGNoYXIpICYmIGlzRGVjaW1hbENoYXIoY2hhcikpIHtcbiAgICAgIGNoYXIgPSBzdHJlYW0ucGVlaygrK2lkeCk7XG4gICAgfVxuICAgIGlmIChpc0VPUyhjaGFyKSkge1xuICAgICAgcmV0dXJuIG5ldyBOdW1lcmljVG9rZW4oe1xuICAgICAgICB2YWx1ZTogK3N0cmVhbS5yZWFkU3RyaW5nKGlkeCksXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBpZHggPSBhZGREZWNpbWFsTGl0ZXJhbFN1ZmZpeExlbmd0aC5jYWxsKHRoaXMsIHN0cmVhbSwgaWR4KTtcblxuICBjaGFyID0gc3RyZWFtLnBlZWsoaWR4KTtcbiAgaWYgKCFpc0VPUyhjaGFyKSAmJiAhdGVybWluYXRlcyhjaGFyKSAmJiBpc0lkZW50aWZpZXJTdGFydChjaGFyKSkge1xuICAgIHRocm93IHRoaXMuY3JlYXRlSUxMRUdBTChjaGFyKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgTnVtZXJpY1Rva2VuKHtcbiAgICB2YWx1ZTogK3N0cmVhbS5yZWFkU3RyaW5nKGlkeCksXG4gIH0pO1xufVxuXG5mdW5jdGlvbiBhZGREZWNpbWFsTGl0ZXJhbFN1ZmZpeExlbmd0aChzdHJlYW0sIGlkeCkge1xuICBsZXQgY2hhciA9IHN0cmVhbS5wZWVrKGlkeCk7XG4gIGlmIChjaGFyID09PSAnLicpIHtcbiAgICBjaGFyID0gc3RyZWFtLnBlZWsoKytpZHgpO1xuICAgIGlmIChpc0VPUyhjaGFyKSkgcmV0dXJuIGlkeDtcblxuICAgIHdoaWxlIChpc0RlY2ltYWxDaGFyKGNoYXIpKSB7XG4gICAgICBjaGFyID0gc3RyZWFtLnBlZWsoKytpZHgpO1xuICAgICAgaWYgKHRlcm1pbmF0ZXMoY2hhcikgfHwgaXNFT1MoY2hhcikpIHJldHVybiBpZHg7XG4gICAgfVxuICB9XG5cbiAgaWYgKGNoYXIudG9Mb3dlckNhc2UoKSA9PT0gJ2UnKSB7XG4gICAgY2hhciA9IHN0cmVhbS5wZWVrKCsraWR4KTtcbiAgICBpZiAoaXNFT1MoY2hhcikpIHRocm93IHRoaXMuY3JlYXRlSUxMRUdBTChjaGFyKTtcblxuICAgIGlmIChjaGFyID09PSAnKycgfHwgY2hhciA9PT0gJy0nKSB7XG4gICAgICBjaGFyID0gc3RyZWFtLnBlZWsoKytpZHgpO1xuICAgICAgaWYgKGlzRU9TKGNoYXIpKSB0aHJvdyB0aGlzLmNyZWF0ZUlMTEVHQUwoY2hhcik7XG4gICAgfVxuXG4gICAgd2hpbGUgKGlzRGVjaW1hbENoYXIoY2hhcikpIHtcbiAgICAgIGNoYXIgPSBzdHJlYW0ucGVlaygrK2lkeCk7XG4gICAgICBpZiAodGVybWluYXRlcyhjaGFyKSB8fCBpc0VPUyhjaGFyKSkgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiBpZHg7XG59XG5cbmZ1bmN0aW9uIHJlYWRMZWdhY3lPY3RhbExpdGVyYWwoc3RyZWFtKSB7XG4gIGxldCBpZHggPSAwLCBpc09jdGFsID0gdHJ1ZSwgY2hhciA9IHN0cmVhbS5wZWVrKCk7XG5cbiAgd2hpbGUgKCF0ZXJtaW5hdGVzKGNoYXIpICYmICFpc0VPUyhjaGFyKSkge1xuICAgIGlmICgnMCcgPD0gY2hhciAmJiBjaGFyIDw9ICc3Jykge1xuICAgICAgaWR4Kys7XG4gICAgfSBlbHNlIGlmIChjaGFyID09PSAnOCcgfHwgY2hhciA9PT0gJzknKSB7XG4gICAgICBpc09jdGFsID0gZmFsc2U7XG4gICAgICBpZHgrKztcbiAgICB9IGVsc2UgaWYgKGlzSWRlbnRpZmllclBhcnQoY2hhci5jaGFyQ29kZUF0KDApKSkge1xuICAgICAgdGhyb3cgdGhpcy5jcmVhdGVJTExFR0FMKGNoYXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBjaGFyID0gc3RyZWFtLnBlZWsoaWR4KTtcbiAgfVxuXG4gIGlmICghaXNPY3RhbClcbiAgICByZXR1cm4gbmV3IE51bWVyaWNUb2tlbih7XG4gICAgICB2YWx1ZTogcGFyc2VOdW1lcmljKHN0cmVhbSwgaWR4LCAxMCksXG4gICAgICBvY3RhbDogdHJ1ZSxcbiAgICAgIG5vY3RhbDogIWlzT2N0YWwsXG4gICAgfSk7XG5cbiAgcmV0dXJuIG5ldyBOdW1lcmljVG9rZW4oe1xuICAgIHZhbHVlOiBwYXJzZU51bWVyaWMoc3RyZWFtLCBpZHgsIDgpLFxuICAgIG9jdGFsOiB0cnVlLFxuICAgIG5vY3RhbDogIWlzT2N0YWwsXG4gIH0pO1xufVxuXG5mdW5jdGlvbiByZWFkT2N0YWxMaXRlcmFsKHN0cmVhbSkge1xuICBsZXQgc3RhcnQsIGlkeCA9IChzdGFydCA9IDIpLCBjaGFyID0gc3RyZWFtLnBlZWsoaWR4KTtcbiAgd2hpbGUgKCF0ZXJtaW5hdGVzKGNoYXIpICYmICFpc0VPUyhjaGFyKSkge1xuICAgIGlmICgnMCcgPD0gY2hhciAmJiBjaGFyIDw9ICc3Jykge1xuICAgICAgY2hhciA9IHN0cmVhbS5wZWVrKCsraWR4KTtcbiAgICB9IGVsc2UgaWYgKGlzSWRlbnRpZmllclBhcnQoY2hhci5jaGFyQ29kZUF0KDApKSkge1xuICAgICAgdGhyb3cgdGhpcy5jcmVhdGVJTExFR0FMKGNoYXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAoaWR4ID09PSBzdGFydCkge1xuICAgIHRocm93IHRoaXMuY3JlYXRlSUxMRUdBTChjaGFyKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgTnVtZXJpY1Rva2VuKHtcbiAgICB2YWx1ZTogcGFyc2VOdW1lcmljKHN0cmVhbSwgaWR4LCA4LCBzdGFydCksXG4gIH0pO1xufVxuXG5mdW5jdGlvbiByZWFkQmluYXJ5TGl0ZXJhbChzdHJlYW0pIHtcbiAgbGV0IHN0YXJ0LCBpZHggPSAoc3RhcnQgPSAyKTtcbiAgbGV0IGNoYXIgPSBzdHJlYW0ucGVlayhpZHgpO1xuXG4gIHdoaWxlICghdGVybWluYXRlcyhjaGFyKSAmJiAhaXNFT1MoY2hhcikpIHtcbiAgICBpZiAoY2hhciAhPT0gJzAnICYmIGNoYXIgIT09ICcxJykge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGNoYXIgPSBzdHJlYW0ucGVlayhpZHgpO1xuICAgIGlkeCsrO1xuICB9XG5cbiAgaWYgKGlkeCA9PT0gc3RhcnQpIHtcbiAgICB0aHJvdyB0aGlzLmNyZWF0ZUlMTEVHQUwoY2hhcik7XG4gIH1cblxuICBpZiAoXG4gICAgIWlzRU9TKGNoYXIpICYmXG4gICAgIXRlcm1pbmF0ZXMoY2hhcikgJiZcbiAgICAoaXNJZGVudGlmaWVyU3RhcnQoY2hhcikgfHwgaXNEZWNpbWFsQ2hhcihjaGFyKSlcbiAgKSB7XG4gICAgdGhyb3cgdGhpcy5jcmVhdGVJTExFR0FMKGNoYXIpO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBOdW1lcmljVG9rZW4oe1xuICAgIHZhbHVlOiBwYXJzZU51bWVyaWMoc3RyZWFtLCBpZHgsIDIsIHN0YXJ0KSxcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHJlYWRIZXhMaXRlcmFsKHN0cmVhbSkge1xuICBsZXQgc3RhcnQsIGlkeCA9IChzdGFydCA9IDIpLCBjaGFyID0gc3RyZWFtLnBlZWsoaWR4KTtcbiAgd2hpbGUgKCF0ZXJtaW5hdGVzKGNoYXIpKSB7XG4gICAgbGV0IGhleCA9IGdldEhleFZhbHVlKGNoYXIpO1xuICAgIGlmIChoZXggPT09IC0xKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgY2hhciA9IHN0cmVhbS5wZWVrKCsraWR4KTtcbiAgfVxuXG4gIGlmIChpZHggPT09IHN0YXJ0KSB7XG4gICAgdGhyb3cgdGhpcy5jcmVhdGVJTExFR0FMKGNoYXIpO1xuICB9XG5cbiAgaWYgKCFpc0VPUyhjaGFyKSAmJiAhdGVybWluYXRlcyhjaGFyKSAmJiBpc0lkZW50aWZpZXJTdGFydChjaGFyKSkge1xuICAgIHRocm93IHRoaXMuY3JlYXRlSUxMRUdBTChjaGFyKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgTnVtZXJpY1Rva2VuKHtcbiAgICB2YWx1ZTogcGFyc2VOdW1lcmljKHN0cmVhbSwgaWR4LCAxNiwgc3RhcnQpLFxuICB9KTtcbn1cblxuZnVuY3Rpb24gcGFyc2VOdW1lcmljKHN0cmVhbSwgbGVuLCByYWRpeCwgc3RhcnQgPSAwKSB7XG4gIHN0cmVhbS5yZWFkU3RyaW5nKHN0YXJ0KTtcbiAgcmV0dXJuIHBhcnNlSW50KHN0cmVhbS5yZWFkU3RyaW5nKGxlbiAtIHN0YXJ0KSwgcmFkaXgpO1xufVxuXG5mdW5jdGlvbiBpc0RlY2ltYWxDaGFyKGNoYXIpIHtcbiAgcmV0dXJuICcwJyA8PSBjaGFyICYmIGNoYXIgPD0gJzknO1xufVxuIl19\n\n/***/ },\n/* 33 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.default = readStringLiteral;\n\n\tvar _utils = __webpack_require__(14);\n\n\tvar _readtable = __webpack_require__(7);\n\n\tvar _tokens = __webpack_require__(19);\n\n\tfunction readStringLiteral(stream) {\n\t  let str = '',\n\t      octal = null,\n\t      idx = 0,\n\t      quote = stream.readString(),\n\t      char = stream.peek(),\n\t      lineStart;\n\n\t  while (!(0, _readtable.isEOS)(char)) {\n\t    if (char === quote) {\n\t      stream.readString(++idx);\n\t      if (lineStart != null) this.locationInfo.column += idx - lineStart;\n\t      return new _tokens.StringToken({ str, octal });\n\t    } else if (char === '\\\\') {\n\t      [str, idx, octal, lineStart] = _utils.readStringEscape.call(this, str, stream, idx, octal);\n\t    } else if ((0, _utils.isLineTerminator)(char.charCodeAt(0))) {\n\t      throw this.createILLEGAL(char);\n\t    } else {\n\t      ++idx;\n\t      str += char;\n\t    }\n\t    char = stream.peek(idx);\n\t  }\n\t  throw this.createILLEGAL(char);\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9yZWFkZXIvcmVhZC1zdHJpbmcuanMiXSwibmFtZXMiOlsicmVhZFN0cmluZ0xpdGVyYWwiLCJzdHJlYW0iLCJzdHIiLCJvY3RhbCIsImlkeCIsInF1b3RlIiwicmVhZFN0cmluZyIsImNoYXIiLCJwZWVrIiwibGluZVN0YXJ0IiwibG9jYXRpb25JbmZvIiwiY29sdW1uIiwiY2FsbCIsImNoYXJDb2RlQXQiLCJjcmVhdGVJTExFR0FMIl0sIm1hcHBpbmdzIjoiOzs7OztrQkFPd0JBLGlCOztBQUp4Qjs7QUFDQTs7QUFDQTs7QUFFZSxTQUFTQSxpQkFBVCxDQUEyQkMsTUFBM0IsRUFBNEQ7QUFDekUsTUFBSUMsTUFBTSxFQUFWO0FBQUEsTUFDRUMsUUFBUSxJQURWO0FBQUEsTUFFRUMsTUFBYyxDQUZoQjtBQUFBLE1BR0VDLFFBQVFKLE9BQU9LLFVBQVAsRUFIVjtBQUFBLE1BSUVDLE9BQU9OLE9BQU9PLElBQVAsRUFKVDtBQUFBLE1BS0VDLFNBTEY7O0FBT0EsU0FBTyxDQUFDLHNCQUFNRixJQUFOLENBQVIsRUFBcUI7QUFDbkIsUUFBSUEsU0FBU0YsS0FBYixFQUFvQjtBQUNsQkosYUFBT0ssVUFBUCxDQUFrQixFQUFFRixHQUFwQjtBQUNBLFVBQUlLLGFBQWEsSUFBakIsRUFBdUIsS0FBS0MsWUFBTCxDQUFrQkMsTUFBbEIsSUFBNEJQLE1BQU1LLFNBQWxDO0FBQ3ZCLGFBQU8sd0JBQWdCLEVBQUVQLEdBQUYsRUFBT0MsS0FBUCxFQUFoQixDQUFQO0FBQ0QsS0FKRCxNQUlPLElBQUlJLFNBQVMsSUFBYixFQUFtQjtBQUN4QixPQUFDTCxHQUFELEVBQU1FLEdBQU4sRUFBV0QsS0FBWCxFQUFrQk0sU0FBbEIsSUFBK0Isd0JBQWlCRyxJQUFqQixDQUM3QixJQUQ2QixFQUU3QlYsR0FGNkIsRUFHN0JELE1BSDZCLEVBSTdCRyxHQUo2QixFQUs3QkQsS0FMNkIsQ0FBL0I7QUFPRCxLQVJNLE1BUUEsSUFBSSw2QkFBaUJJLEtBQUtNLFVBQUwsQ0FBZ0IsQ0FBaEIsQ0FBakIsQ0FBSixFQUEwQztBQUMvQyxZQUFNLEtBQUtDLGFBQUwsQ0FBbUJQLElBQW5CLENBQU47QUFDRCxLQUZNLE1BRUE7QUFDTCxRQUFFSCxHQUFGO0FBQ0FGLGFBQU9LLElBQVA7QUFDRDtBQUNEQSxXQUFPTixPQUFPTyxJQUFQLENBQVlKLEdBQVosQ0FBUDtBQUNEO0FBQ0QsUUFBTSxLQUFLVSxhQUFMLENBQW1CUCxJQUFuQixDQUFOO0FBQ0QiLCJmaWxlIjoicmVhZC1zdHJpbmcuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAZmxvd1xuaW1wb3J0IHR5cGUgeyBDaGFyU3RyZWFtIH0gZnJvbSAncmVhZHRhYmxlJztcblxuaW1wb3J0IHsgcmVhZFN0cmluZ0VzY2FwZSwgaXNMaW5lVGVybWluYXRvciB9IGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHsgaXNFT1MgfSBmcm9tICdyZWFkdGFibGUnO1xuaW1wb3J0IHsgU3RyaW5nVG9rZW4gfSBmcm9tICcuLi90b2tlbnMnO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiByZWFkU3RyaW5nTGl0ZXJhbChzdHJlYW06IENoYXJTdHJlYW0pOiBTdHJpbmdUb2tlbiB7XG4gIGxldCBzdHIgPSAnJyxcbiAgICBvY3RhbCA9IG51bGwsXG4gICAgaWR4OiBudW1iZXIgPSAwLFxuICAgIHF1b3RlID0gc3RyZWFtLnJlYWRTdHJpbmcoKSxcbiAgICBjaGFyID0gc3RyZWFtLnBlZWsoKSxcbiAgICBsaW5lU3RhcnQ7XG5cbiAgd2hpbGUgKCFpc0VPUyhjaGFyKSkge1xuICAgIGlmIChjaGFyID09PSBxdW90ZSkge1xuICAgICAgc3RyZWFtLnJlYWRTdHJpbmcoKytpZHgpO1xuICAgICAgaWYgKGxpbmVTdGFydCAhPSBudWxsKSB0aGlzLmxvY2F0aW9uSW5mby5jb2x1bW4gKz0gaWR4IC0gbGluZVN0YXJ0O1xuICAgICAgcmV0dXJuIG5ldyBTdHJpbmdUb2tlbih7IHN0ciwgb2N0YWwgfSk7XG4gICAgfSBlbHNlIGlmIChjaGFyID09PSAnXFxcXCcpIHtcbiAgICAgIFtzdHIsIGlkeCwgb2N0YWwsIGxpbmVTdGFydF0gPSByZWFkU3RyaW5nRXNjYXBlLmNhbGwoXG4gICAgICAgIHRoaXMsXG4gICAgICAgIHN0cixcbiAgICAgICAgc3RyZWFtLFxuICAgICAgICBpZHgsXG4gICAgICAgIG9jdGFsLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKGlzTGluZVRlcm1pbmF0b3IoY2hhci5jaGFyQ29kZUF0KDApKSkge1xuICAgICAgdGhyb3cgdGhpcy5jcmVhdGVJTExFR0FMKGNoYXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICArK2lkeDtcbiAgICAgIHN0ciArPSBjaGFyO1xuICAgIH1cbiAgICBjaGFyID0gc3RyZWFtLnBlZWsoaWR4KTtcbiAgfVxuICB0aHJvdyB0aGlzLmNyZWF0ZUlMTEVHQUwoY2hhcik7XG59XG4iXX0=\n\n/***/ },\n/* 34 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.default = readTemplateLiteral;\n\n\tvar _immutable = __webpack_require__(12);\n\n\tvar _readtable = __webpack_require__(7);\n\n\tvar _utils = __webpack_require__(14);\n\n\tvar _tokenReader = __webpack_require__(6);\n\n\tvar _tokens = __webpack_require__(19);\n\n\tfunction readTemplateLiteral(stream, prefix) {\n\t  let element,\n\t      items = [];\n\t  stream.readString();\n\n\t  do {\n\t    element = readTemplateElement.call(this, stream);\n\t    items.push(element);\n\t    if (element.interp) {\n\t      element = this.readToken(stream, (0, _immutable.List)(), false);\n\t      items.push(element);\n\t    }\n\t  } while (!element.tail);\n\n\t  return new _tokens.TemplateToken({\n\t    items: (0, _immutable.List)(items)\n\t  });\n\t}\n\n\n\tfunction readTemplateElement(stream) {\n\t  let char = stream.peek(),\n\t      idx = 0,\n\t      value = '',\n\t      octal = null;\n\t  const startLocation = Object.assign({}, this.locationInfo, stream.sourceInfo);\n\t  while (!(0, _readtable.isEOS)(char)) {\n\t    switch (char) {\n\t      case '`':\n\t        {\n\t          stream.readString(idx);\n\t          const slice = (0, _tokenReader.getSlice)(stream, startLocation);\n\t          stream.readString();\n\t          return new _tokens.TemplateElementToken({\n\t            tail: true,\n\t            interp: false,\n\t            value,\n\t            slice\n\t          });\n\t        }\n\t      case '$':\n\t        {\n\t          if (stream.peek(idx + 1) === '{') {\n\t            stream.readString(idx);\n\t            const slice = (0, _tokenReader.getSlice)(stream, startLocation);\n\t            stream.readString();\n\n\t            return new _tokens.TemplateElementToken({\n\t              tail: false,\n\t              interp: true,\n\t              value,\n\t              slice\n\t            });\n\t          }\n\t          break;\n\t        }\n\t      case '\\\\':\n\t        {\n\t          let newVal;\n\t          [newVal, idx, octal] = _utils.readStringEscape.call(this, '', stream, idx, octal);\n\t          if (octal != null) throw this.createILLEGAL(octal);\n\t          value += newVal;\n\t          --idx;\n\t          break;\n\t        }\n\t      default:\n\t        {\n\t          value += char;\n\t        }\n\t    }\n\t    char = stream.peek(++idx);\n\t  }\n\t  throw this.createILLEGAL(char);\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9yZWFkZXIvcmVhZC10ZW1wbGF0ZS5qcyJdLCJuYW1lcyI6WyJyZWFkVGVtcGxhdGVMaXRlcmFsIiwic3RyZWFtIiwicHJlZml4IiwiZWxlbWVudCIsIml0ZW1zIiwicmVhZFN0cmluZyIsInJlYWRUZW1wbGF0ZUVsZW1lbnQiLCJjYWxsIiwicHVzaCIsImludGVycCIsInJlYWRUb2tlbiIsInRhaWwiLCJjaGFyIiwicGVlayIsImlkeCIsInZhbHVlIiwib2N0YWwiLCJzdGFydExvY2F0aW9uIiwiT2JqZWN0IiwiYXNzaWduIiwibG9jYXRpb25JbmZvIiwic291cmNlSW5mbyIsInNsaWNlIiwibmV3VmFsIiwiY3JlYXRlSUxMRUdBTCJdLCJtYXBwaW5ncyI6Ijs7Ozs7a0JBVXdCQSxtQjs7QUFUeEI7O0FBR0E7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBRWUsU0FBU0EsbUJBQVQsQ0FDYkMsTUFEYSxFQUViQyxNQUZhLEVBR0U7QUFDZixNQUFJQyxPQUFKO0FBQUEsTUFBYUMsUUFBUSxFQUFyQjtBQUNBSCxTQUFPSSxVQUFQOztBQUVBLEtBQUc7QUFDREYsY0FBVUcsb0JBQW9CQyxJQUFwQixDQUF5QixJQUF6QixFQUErQk4sTUFBL0IsQ0FBVjtBQUNBRyxVQUFNSSxJQUFOLENBQVdMLE9BQVg7QUFDQSxRQUFJQSxRQUFRTSxNQUFaLEVBQW9CO0FBQ2xCTixnQkFBVSxLQUFLTyxTQUFMLENBQWVULE1BQWYsRUFBdUIsc0JBQXZCLEVBQStCLEtBQS9CLENBQVY7QUFDQUcsWUFBTUksSUFBTixDQUFXTCxPQUFYO0FBQ0Q7QUFDRixHQVBELFFBT1MsQ0FBQ0EsUUFBUVEsSUFQbEI7O0FBU0EsU0FBTywwQkFBa0I7QUFDdkJQLFdBQU8scUJBQUtBLEtBQUw7QUFEZ0IsR0FBbEIsQ0FBUDtBQUdEOzs7QUFFRCxTQUFTRSxtQkFBVCxDQUE2QkwsTUFBN0IsRUFBdUU7QUFDckUsTUFBSVcsT0FBT1gsT0FBT1ksSUFBUCxFQUFYO0FBQUEsTUFBMEJDLE1BQU0sQ0FBaEM7QUFBQSxNQUFtQ0MsUUFBUSxFQUEzQztBQUFBLE1BQStDQyxRQUFRLElBQXZEO0FBQ0EsUUFBTUMsZ0JBQWdCQyxPQUFPQyxNQUFQLENBQWMsRUFBZCxFQUFrQixLQUFLQyxZQUF2QixFQUFxQ25CLE9BQU9vQixVQUE1QyxDQUF0QjtBQUNBLFNBQU8sQ0FBQyxzQkFBTVQsSUFBTixDQUFSLEVBQXFCO0FBQ25CLFlBQVFBLElBQVI7QUFDRSxXQUFLLEdBQUw7QUFBVTtBQUNSWCxpQkFBT0ksVUFBUCxDQUFrQlMsR0FBbEI7QUFDQSxnQkFBTVEsUUFBUSwyQkFBU3JCLE1BQVQsRUFBaUJnQixhQUFqQixDQUFkO0FBQ0FoQixpQkFBT0ksVUFBUDtBQUNBLGlCQUFPLGlDQUF5QjtBQUM5Qk0sa0JBQU0sSUFEd0I7QUFFOUJGLG9CQUFRLEtBRnNCO0FBRzlCTSxpQkFIOEI7QUFJOUJPO0FBSjhCLFdBQXpCLENBQVA7QUFNRDtBQUNELFdBQUssR0FBTDtBQUFVO0FBQ1IsY0FBSXJCLE9BQU9ZLElBQVAsQ0FBWUMsTUFBTSxDQUFsQixNQUF5QixHQUE3QixFQUFrQztBQUNoQ2IsbUJBQU9JLFVBQVAsQ0FBa0JTLEdBQWxCO0FBQ0Esa0JBQU1RLFFBQVEsMkJBQVNyQixNQUFULEVBQWlCZ0IsYUFBakIsQ0FBZDtBQUNBaEIsbUJBQU9JLFVBQVA7O0FBRUEsbUJBQU8saUNBQXlCO0FBQzlCTSxvQkFBTSxLQUR3QjtBQUU5QkYsc0JBQVEsSUFGc0I7QUFHOUJNLG1CQUg4QjtBQUk5Qk87QUFKOEIsYUFBekIsQ0FBUDtBQU1EO0FBQ0Q7QUFDRDtBQUNELFdBQUssSUFBTDtBQUFXO0FBQ1QsY0FBSUMsTUFBSjtBQUNBLFdBQUNBLE1BQUQsRUFBU1QsR0FBVCxFQUFjRSxLQUFkLElBQXVCLHdCQUFpQlQsSUFBakIsQ0FDckIsSUFEcUIsRUFFckIsRUFGcUIsRUFHckJOLE1BSHFCLEVBSXJCYSxHQUpxQixFQUtyQkUsS0FMcUIsQ0FBdkI7QUFPQSxjQUFJQSxTQUFTLElBQWIsRUFBbUIsTUFBTSxLQUFLUSxhQUFMLENBQW1CUixLQUFuQixDQUFOO0FBQ25CRCxtQkFBU1EsTUFBVDtBQUNBLFlBQUVULEdBQUY7QUFDQTtBQUNEO0FBQ0Q7QUFBUztBQUNQQyxtQkFBU0gsSUFBVDtBQUNEO0FBM0NIO0FBNkNBQSxXQUFPWCxPQUFPWSxJQUFQLENBQVksRUFBRUMsR0FBZCxDQUFQO0FBQ0Q7QUFDRCxRQUFNLEtBQUtVLGFBQUwsQ0FBbUJaLElBQW5CLENBQU47QUFDRCIsImZpbGUiOiJyZWFkLXRlbXBsYXRlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbmltcG9ydCB7IExpc3QgfSBmcm9tICdpbW11dGFibGUnO1xuXG5pbXBvcnQgdHlwZSB7IENoYXJTdHJlYW0gfSBmcm9tICdyZWFkdGFibGUnO1xuaW1wb3J0IHsgaXNFT1MgfSBmcm9tICdyZWFkdGFibGUnO1xuXG5pbXBvcnQgeyByZWFkU3RyaW5nRXNjYXBlIH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgeyBnZXRTbGljZSB9IGZyb20gJy4vdG9rZW4tcmVhZGVyJztcbmltcG9ydCB7IFRlbXBsYXRlVG9rZW4sIFRlbXBsYXRlRWxlbWVudFRva2VuIH0gZnJvbSAnLi4vdG9rZW5zJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcmVhZFRlbXBsYXRlTGl0ZXJhbChcbiAgc3RyZWFtOiBDaGFyU3RyZWFtLFxuICBwcmVmaXg6IExpc3Q8YW55Pixcbik6IFRlbXBsYXRlVG9rZW4ge1xuICBsZXQgZWxlbWVudCwgaXRlbXMgPSBbXTtcbiAgc3RyZWFtLnJlYWRTdHJpbmcoKTtcblxuICBkbyB7XG4gICAgZWxlbWVudCA9IHJlYWRUZW1wbGF0ZUVsZW1lbnQuY2FsbCh0aGlzLCBzdHJlYW0pO1xuICAgIGl0ZW1zLnB1c2goZWxlbWVudCk7XG4gICAgaWYgKGVsZW1lbnQuaW50ZXJwKSB7XG4gICAgICBlbGVtZW50ID0gdGhpcy5yZWFkVG9rZW4oc3RyZWFtLCBMaXN0KCksIGZhbHNlKTtcbiAgICAgIGl0ZW1zLnB1c2goZWxlbWVudCk7XG4gICAgfVxuICB9IHdoaWxlICghZWxlbWVudC50YWlsKTtcblxuICByZXR1cm4gbmV3IFRlbXBsYXRlVG9rZW4oe1xuICAgIGl0ZW1zOiBMaXN0KGl0ZW1zKSxcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHJlYWRUZW1wbGF0ZUVsZW1lbnQoc3RyZWFtOiBDaGFyU3RyZWFtKTogVGVtcGxhdGVFbGVtZW50VG9rZW4ge1xuICBsZXQgY2hhciA9IHN0cmVhbS5wZWVrKCksIGlkeCA9IDAsIHZhbHVlID0gJycsIG9jdGFsID0gbnVsbDtcbiAgY29uc3Qgc3RhcnRMb2NhdGlvbiA9IE9iamVjdC5hc3NpZ24oe30sIHRoaXMubG9jYXRpb25JbmZvLCBzdHJlYW0uc291cmNlSW5mbyk7XG4gIHdoaWxlICghaXNFT1MoY2hhcikpIHtcbiAgICBzd2l0Y2ggKGNoYXIpIHtcbiAgICAgIGNhc2UgJ2AnOiB7XG4gICAgICAgIHN0cmVhbS5yZWFkU3RyaW5nKGlkeCk7XG4gICAgICAgIGNvbnN0IHNsaWNlID0gZ2V0U2xpY2Uoc3RyZWFtLCBzdGFydExvY2F0aW9uKTtcbiAgICAgICAgc3RyZWFtLnJlYWRTdHJpbmcoKTtcbiAgICAgICAgcmV0dXJuIG5ldyBUZW1wbGF0ZUVsZW1lbnRUb2tlbih7XG4gICAgICAgICAgdGFpbDogdHJ1ZSxcbiAgICAgICAgICBpbnRlcnA6IGZhbHNlLFxuICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgIHNsaWNlLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNhc2UgJyQnOiB7XG4gICAgICAgIGlmIChzdHJlYW0ucGVlayhpZHggKyAxKSA9PT0gJ3snKSB7XG4gICAgICAgICAgc3RyZWFtLnJlYWRTdHJpbmcoaWR4KTtcbiAgICAgICAgICBjb25zdCBzbGljZSA9IGdldFNsaWNlKHN0cmVhbSwgc3RhcnRMb2NhdGlvbik7XG4gICAgICAgICAgc3RyZWFtLnJlYWRTdHJpbmcoKTtcblxuICAgICAgICAgIHJldHVybiBuZXcgVGVtcGxhdGVFbGVtZW50VG9rZW4oe1xuICAgICAgICAgICAgdGFpbDogZmFsc2UsXG4gICAgICAgICAgICBpbnRlcnA6IHRydWUsXG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIHNsaWNlLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnXFxcXCc6IHtcbiAgICAgICAgbGV0IG5ld1ZhbDtcbiAgICAgICAgW25ld1ZhbCwgaWR4LCBvY3RhbF0gPSByZWFkU3RyaW5nRXNjYXBlLmNhbGwoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICAnJyxcbiAgICAgICAgICBzdHJlYW0sXG4gICAgICAgICAgaWR4LFxuICAgICAgICAgIG9jdGFsLFxuICAgICAgICApO1xuICAgICAgICBpZiAob2N0YWwgIT0gbnVsbCkgdGhyb3cgdGhpcy5jcmVhdGVJTExFR0FMKG9jdGFsKTtcbiAgICAgICAgdmFsdWUgKz0gbmV3VmFsO1xuICAgICAgICAtLWlkeDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIHZhbHVlICs9IGNoYXI7XG4gICAgICB9XG4gICAgfVxuICAgIGNoYXIgPSBzdHJlYW0ucGVlaygrK2lkeCk7XG4gIH1cbiAgdGhyb3cgdGhpcy5jcmVhdGVJTExFR0FMKGNoYXIpO1xufVxuIl19\n\n/***/ },\n/* 35 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.default = readRegExp;\n\n\tvar _readtable = __webpack_require__(7);\n\n\tvar _tokens = __webpack_require__(19);\n\n\tvar _utils = __webpack_require__(14);\n\n\tfunction readRegExp(stream) {\n\t  let value = stream.readString(),\n\t      char = stream.peek(),\n\t      idx = 0,\n\t      classMarker = false,\n\t      terminated = false;\n\n\t  const UNTERMINATED_REGEXP_MSG = 'Invalid regular expression: missing /';\n\n\t  while (!(0, _readtable.isEOS)(char)) {\n\t    if (char === '\\\\') {\n\t      value += char;\n\t      ++idx;\n\t      char = stream.peek(idx);\n\n\t      if ((0, _utils.isLineTerminator)(char.charCodeAt(0))) {\n\t        throw this.createError(UNTERMINATED_REGEXP_MSG);\n\t      }\n\t      value += char;\n\t      ++idx;\n\t    } else if ((0, _utils.isLineTerminator)(char.charCodeAt(0))) {\n\t      throw this.createError(UNTERMINATED_REGEXP_MSG);\n\t    } else {\n\t      if (classMarker) {\n\t        if (char === ']') {\n\t          classMarker = false;\n\t        }\n\t      } else {\n\t        if (char === '/') {\n\t          terminated = true;\n\t          value += char;\n\t          ++idx;\n\t          char = stream.peek(idx);\n\t          break;\n\t        } else if (char === '[') {\n\t          classMarker = true;\n\t        }\n\t      }\n\t      value += char;\n\t      ++idx;\n\t    }\n\t    char = stream.peek(idx);\n\t  }\n\n\t  if (!terminated) {\n\t    throw this.createError(UNTERMINATED_REGEXP_MSG);\n\t  }\n\n\t  while (!(0, _readtable.isEOS)(char)) {\n\t    if (char === '\\\\') {\n\t      throw this.createError('Invalid regular expression flags');\n\t    }\n\t    if (!(0, _utils.isIdentifierPart)(char.charCodeAt(0))) {\n\t      break;\n\t    }\n\t    value += char;\n\t    ++idx;\n\t    char = stream.peek(idx);\n\t  }\n\n\t  stream.readString(idx);\n\n\t  return new _tokens.RegExpToken({\n\t    value\n\t  });\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9yZWFkZXIvcmVhZC1yZWdleHAuanMiXSwibmFtZXMiOlsicmVhZFJlZ0V4cCIsInN0cmVhbSIsInZhbHVlIiwicmVhZFN0cmluZyIsImNoYXIiLCJwZWVrIiwiaWR4IiwiY2xhc3NNYXJrZXIiLCJ0ZXJtaW5hdGVkIiwiVU5URVJNSU5BVEVEX1JFR0VYUF9NU0ciLCJjaGFyQ29kZUF0IiwiY3JlYXRlRXJyb3IiXSwibWFwcGluZ3MiOiI7Ozs7O2tCQU93QkEsVTs7QUFKeEI7O0FBQ0E7O0FBQ0E7O0FBRWUsU0FBU0EsVUFBVCxDQUFvQkMsTUFBcEIsRUFBd0M7QUFDckQsTUFBSUMsUUFBUUQsT0FBT0UsVUFBUCxFQUFaO0FBQUEsTUFDRUMsT0FBT0gsT0FBT0ksSUFBUCxFQURUO0FBQUEsTUFFRUMsTUFBTSxDQUZSO0FBQUEsTUFHRUMsY0FBYyxLQUhoQjtBQUFBLE1BSUVDLGFBQWEsS0FKZjs7QUFNQSxRQUFNQywwQkFBMEIsdUNBQWhDOztBQUVBLFNBQU8sQ0FBQyxzQkFBTUwsSUFBTixDQUFSLEVBQXFCO0FBQ25CLFFBQUlBLFNBQVMsSUFBYixFQUFtQjtBQUNqQkYsZUFBU0UsSUFBVDtBQUNBLFFBQUVFLEdBQUY7QUFDQUYsYUFBT0gsT0FBT0ksSUFBUCxDQUFZQyxHQUFaLENBQVA7O0FBRUEsVUFBSSw2QkFBaUJGLEtBQUtNLFVBQUwsQ0FBZ0IsQ0FBaEIsQ0FBakIsQ0FBSixFQUEwQztBQUN4QyxjQUFNLEtBQUtDLFdBQUwsQ0FBaUJGLHVCQUFqQixDQUFOO0FBQ0Q7QUFDRFAsZUFBU0UsSUFBVDtBQUNBLFFBQUVFLEdBQUY7QUFDRCxLQVZELE1BVU8sSUFBSSw2QkFBaUJGLEtBQUtNLFVBQUwsQ0FBZ0IsQ0FBaEIsQ0FBakIsQ0FBSixFQUEwQztBQUMvQyxZQUFNLEtBQUtDLFdBQUwsQ0FBaUJGLHVCQUFqQixDQUFOO0FBQ0QsS0FGTSxNQUVBO0FBQ0wsVUFBSUYsV0FBSixFQUFpQjtBQUNmLFlBQUlILFNBQVMsR0FBYixFQUFrQjtBQUNoQkcsd0JBQWMsS0FBZDtBQUNEO0FBQ0YsT0FKRCxNQUlPO0FBQ0wsWUFBSUgsU0FBUyxHQUFiLEVBQWtCO0FBQ2hCSSx1QkFBYSxJQUFiO0FBQ0FOLG1CQUFTRSxJQUFUO0FBQ0EsWUFBRUUsR0FBRjtBQUNBRixpQkFBT0gsT0FBT0ksSUFBUCxDQUFZQyxHQUFaLENBQVA7QUFDQTtBQUNELFNBTkQsTUFNTyxJQUFJRixTQUFTLEdBQWIsRUFBa0I7QUFDdkJHLHdCQUFjLElBQWQ7QUFDRDtBQUNGO0FBQ0RMLGVBQVNFLElBQVQ7QUFDQSxRQUFFRSxHQUFGO0FBQ0Q7QUFDREYsV0FBT0gsT0FBT0ksSUFBUCxDQUFZQyxHQUFaLENBQVA7QUFDRDs7QUFFRCxNQUFJLENBQUNFLFVBQUwsRUFBaUI7QUFDZixVQUFNLEtBQUtHLFdBQUwsQ0FBaUJGLHVCQUFqQixDQUFOO0FBQ0Q7O0FBRUQsU0FBTyxDQUFDLHNCQUFNTCxJQUFOLENBQVIsRUFBcUI7QUFDbkIsUUFBSUEsU0FBUyxJQUFiLEVBQW1CO0FBQ2pCLFlBQU0sS0FBS08sV0FBTCxDQUFpQixrQ0FBakIsQ0FBTjtBQUNEO0FBQ0QsUUFBSSxDQUFDLDZCQUFpQlAsS0FBS00sVUFBTCxDQUFnQixDQUFoQixDQUFqQixDQUFMLEVBQTJDO0FBQ3pDO0FBQ0Q7QUFDRFIsYUFBU0UsSUFBVDtBQUNBLE1BQUVFLEdBQUY7QUFDQUYsV0FBT0gsT0FBT0ksSUFBUCxDQUFZQyxHQUFaLENBQVA7QUFDRDs7QUFFREwsU0FBT0UsVUFBUCxDQUFrQkcsR0FBbEI7O0FBRUEsU0FBTyx3QkFBZ0I7QUFDckJKO0FBRHFCLEdBQWhCLENBQVA7QUFHRCIsImZpbGUiOiJyZWFkLXJlZ2V4cC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG5pbXBvcnQgdHlwZSB7IENoYXJTdHJlYW0gfSBmcm9tICdyZWFkdGFibGUnO1xuXG5pbXBvcnQgeyBpc0VPUyB9IGZyb20gJ3JlYWR0YWJsZSc7XG5pbXBvcnQgeyBSZWdFeHBUb2tlbiB9IGZyb20gJy4uL3Rva2Vucyc7XG5pbXBvcnQgeyBpc0xpbmVUZXJtaW5hdG9yLCBpc0lkZW50aWZpZXJQYXJ0IH0gZnJvbSAnLi91dGlscyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHJlYWRSZWdFeHAoc3RyZWFtOiBDaGFyU3RyZWFtKSB7XG4gIGxldCB2YWx1ZSA9IHN0cmVhbS5yZWFkU3RyaW5nKCksXG4gICAgY2hhciA9IHN0cmVhbS5wZWVrKCksXG4gICAgaWR4ID0gMCxcbiAgICBjbGFzc01hcmtlciA9IGZhbHNlLFxuICAgIHRlcm1pbmF0ZWQgPSBmYWxzZTtcblxuICBjb25zdCBVTlRFUk1JTkFURURfUkVHRVhQX01TRyA9ICdJbnZhbGlkIHJlZ3VsYXIgZXhwcmVzc2lvbjogbWlzc2luZyAvJztcblxuICB3aGlsZSAoIWlzRU9TKGNoYXIpKSB7XG4gICAgaWYgKGNoYXIgPT09ICdcXFxcJykge1xuICAgICAgdmFsdWUgKz0gY2hhcjtcbiAgICAgICsraWR4O1xuICAgICAgY2hhciA9IHN0cmVhbS5wZWVrKGlkeCk7XG5cbiAgICAgIGlmIChpc0xpbmVUZXJtaW5hdG9yKGNoYXIuY2hhckNvZGVBdCgwKSkpIHtcbiAgICAgICAgdGhyb3cgdGhpcy5jcmVhdGVFcnJvcihVTlRFUk1JTkFURURfUkVHRVhQX01TRyk7XG4gICAgICB9XG4gICAgICB2YWx1ZSArPSBjaGFyO1xuICAgICAgKytpZHg7XG4gICAgfSBlbHNlIGlmIChpc0xpbmVUZXJtaW5hdG9yKGNoYXIuY2hhckNvZGVBdCgwKSkpIHtcbiAgICAgIHRocm93IHRoaXMuY3JlYXRlRXJyb3IoVU5URVJNSU5BVEVEX1JFR0VYUF9NU0cpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoY2xhc3NNYXJrZXIpIHtcbiAgICAgICAgaWYgKGNoYXIgPT09ICddJykge1xuICAgICAgICAgIGNsYXNzTWFya2VyID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChjaGFyID09PSAnLycpIHtcbiAgICAgICAgICB0ZXJtaW5hdGVkID0gdHJ1ZTtcbiAgICAgICAgICB2YWx1ZSArPSBjaGFyO1xuICAgICAgICAgICsraWR4O1xuICAgICAgICAgIGNoYXIgPSBzdHJlYW0ucGVlayhpZHgpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9IGVsc2UgaWYgKGNoYXIgPT09ICdbJykge1xuICAgICAgICAgIGNsYXNzTWFya2VyID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdmFsdWUgKz0gY2hhcjtcbiAgICAgICsraWR4O1xuICAgIH1cbiAgICBjaGFyID0gc3RyZWFtLnBlZWsoaWR4KTtcbiAgfVxuXG4gIGlmICghdGVybWluYXRlZCkge1xuICAgIHRocm93IHRoaXMuY3JlYXRlRXJyb3IoVU5URVJNSU5BVEVEX1JFR0VYUF9NU0cpO1xuICB9XG5cbiAgd2hpbGUgKCFpc0VPUyhjaGFyKSkge1xuICAgIGlmIChjaGFyID09PSAnXFxcXCcpIHtcbiAgICAgIHRocm93IHRoaXMuY3JlYXRlRXJyb3IoJ0ludmFsaWQgcmVndWxhciBleHByZXNzaW9uIGZsYWdzJyk7XG4gICAgfVxuICAgIGlmICghaXNJZGVudGlmaWVyUGFydChjaGFyLmNoYXJDb2RlQXQoMCkpKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgdmFsdWUgKz0gY2hhcjtcbiAgICArK2lkeDtcbiAgICBjaGFyID0gc3RyZWFtLnBlZWsoaWR4KTtcbiAgfVxuXG4gIHN0cmVhbS5yZWFkU3RyaW5nKGlkeCk7XG5cbiAgcmV0dXJuIG5ldyBSZWdFeHBUb2tlbih7XG4gICAgdmFsdWUsXG4gIH0pO1xufVxuIl19\n\n/***/ },\n/* 36 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.default = readComment;\n\n\tvar _readtable = __webpack_require__(7);\n\n\tvar _utils = __webpack_require__(14);\n\n\tvar _tokens = __webpack_require__(19);\n\n\tfunction readComment(stream) {\n\t  let char = stream.peek();\n\n\t  while (!(0, _readtable.isEOS)(char)) {\n\t    let chCode = char.charCodeAt(0);\n\t    if (chCode === 47) {\n\t      /* \"/\" */const nxt = stream.peek(1);\n\t      if ((0, _readtable.isEOS)(nxt)) {\n\t        break;\n\t      }\n\t      chCode = nxt.charCodeAt(0);\n\t      if (chCode === 47) {\n\t        /* \"/\" */_utils.skipSingleLineComment.call(this, stream);\n\t      } else if (chCode === 42) {\n\t        /* \"*\" */skipMultiLineComment.call(this, stream);\n\t      } else {\n\t        break;\n\t      }\n\t    } else {\n\t      break;\n\t    }\n\t    char = stream.peek();\n\t  }\n\n\t  return _tokens.EmptyToken;\n\t}\n\n\tfunction skipMultiLineComment(stream) {\n\t  let idx = 2;\n\t  let char = stream.peek(idx);\n\t  const { position: startPosition } = stream.sourceInfo;\n\t  let lineStart;\n\t  while (!(0, _readtable.isEOS)(char)) {\n\t    let chCode = char.charCodeAt(0);\n\t    if (chCode < 0x80) {\n\t      switch (chCode) {\n\t        case 42:\n\t          // \"*\"\n\t          // Block comment ends with \"*/\".\n\t          if (stream.peek(idx + 1).charAt(0) === '/') {\n\t            stream.readString(idx + 2);\n\t            if (lineStart) this.locationInfo.column = stream.sourceInfo.position - lineStart;\n\t            return;\n\t          }\n\t          ++idx;\n\t          break;\n\t        case 10:\n\t          // \"\\n\"\n\t          this.incrementLine();\n\t          lineStart = startPosition + idx;\n\t          ++idx;\n\t          break;\n\t        case 13:\n\t          {\n\t            // \"\\r\":\n\t            let startIdx = idx;\n\t            if (stream.peek(idx + 1).charAt(0) === '\\n') {\n\t              ++idx;\n\t            }\n\t            ++idx;\n\t            this.incrementLine();\n\t            lineStart = startPosition + startIdx;\n\t            break;\n\t          }\n\t        default:\n\t          ++idx;\n\t      }\n\t    } else if (chCode === 0x2028 || chCode === 0x2029) {\n\t      this.incrementLine();\n\t      lineStart = startPosition + idx;\n\t      ++idx;\n\t    } else {\n\t      ++idx;\n\t    }\n\t    char = stream.peek(idx);\n\t  }\n\t  throw this.createILLEGAL(char);\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9yZWFkZXIvcmVhZC1jb21tZW50LmpzIl0sIm5hbWVzIjpbInJlYWRDb21tZW50Iiwic3RyZWFtIiwiY2hhciIsInBlZWsiLCJjaENvZGUiLCJjaGFyQ29kZUF0Iiwibnh0IiwiY2FsbCIsInNraXBNdWx0aUxpbmVDb21tZW50IiwiaWR4IiwicG9zaXRpb24iLCJzdGFydFBvc2l0aW9uIiwic291cmNlSW5mbyIsImxpbmVTdGFydCIsImNoYXJBdCIsInJlYWRTdHJpbmciLCJsb2NhdGlvbkluZm8iLCJjb2x1bW4iLCJpbmNyZW1lbnRMaW5lIiwic3RhcnRJZHgiLCJjcmVhdGVJTExFR0FMIl0sIm1hcHBpbmdzIjoiOzs7OztrQkFPd0JBLFc7O0FBSnhCOztBQUNBOztBQUNBOztBQUVlLFNBQVNBLFdBQVQsQ0FBcUJDLE1BQXJCLEVBQTREO0FBQ3pFLE1BQUlDLE9BQU9ELE9BQU9FLElBQVAsRUFBWDs7QUFFQSxTQUFPLENBQUMsc0JBQU1ELElBQU4sQ0FBUixFQUFxQjtBQUNuQixRQUFJRSxTQUFTRixLQUFLRyxVQUFMLENBQWdCLENBQWhCLENBQWI7QUFDQSxRQUFJRCxXQUFXLEVBQWYsRUFBbUI7QUFDakIsZUFBVSxNQUFNRSxNQUFNTCxPQUFPRSxJQUFQLENBQVksQ0FBWixDQUFaO0FBQ1YsVUFBSSxzQkFBTUcsR0FBTixDQUFKLEVBQWdCO0FBQ2Q7QUFDRDtBQUNERixlQUFTRSxJQUFJRCxVQUFKLENBQWUsQ0FBZixDQUFUO0FBQ0EsVUFBSUQsV0FBVyxFQUFmLEVBQW1CO0FBQ2pCLGlCQUFVLDZCQUFzQkcsSUFBdEIsQ0FBMkIsSUFBM0IsRUFBaUNOLE1BQWpDO0FBQ1gsT0FGRCxNQUVPLElBQUlHLFdBQVcsRUFBZixFQUFtQjtBQUN4QixpQkFBVUkscUJBQXFCRCxJQUFyQixDQUEwQixJQUExQixFQUFnQ04sTUFBaEM7QUFDWCxPQUZNLE1BRUE7QUFDTDtBQUNEO0FBQ0YsS0FiRCxNQWFPO0FBQ0w7QUFDRDtBQUNEQyxXQUFPRCxPQUFPRSxJQUFQLEVBQVA7QUFDRDs7QUFFRDtBQUNEOztBQUVELFNBQVNLLG9CQUFULENBQThCUCxNQUE5QixFQUF3RDtBQUN0RCxNQUFJUSxNQUFNLENBQVY7QUFDQSxNQUFJUCxPQUFPRCxPQUFPRSxJQUFQLENBQVlNLEdBQVosQ0FBWDtBQUNBLFFBQU0sRUFBRUMsVUFBVUMsYUFBWixLQUE4QlYsT0FBT1csVUFBM0M7QUFDQSxNQUFJQyxTQUFKO0FBQ0EsU0FBTyxDQUFDLHNCQUFNWCxJQUFOLENBQVIsRUFBcUI7QUFDbkIsUUFBSUUsU0FBU0YsS0FBS0csVUFBTCxDQUFnQixDQUFoQixDQUFiO0FBQ0EsUUFBSUQsU0FBUyxJQUFiLEVBQW1CO0FBQ2pCLGNBQVFBLE1BQVI7QUFDRSxhQUFLLEVBQUw7QUFBUztBQUNQO0FBQ0EsY0FBSUgsT0FBT0UsSUFBUCxDQUFZTSxNQUFNLENBQWxCLEVBQXFCSyxNQUFyQixDQUE0QixDQUE1QixNQUFtQyxHQUF2QyxFQUE0QztBQUMxQ2IsbUJBQU9jLFVBQVAsQ0FBa0JOLE1BQU0sQ0FBeEI7QUFDQSxnQkFBSUksU0FBSixFQUNFLEtBQUtHLFlBQUwsQ0FBa0JDLE1BQWxCLEdBQTJCaEIsT0FBT1csVUFBUCxDQUFrQkYsUUFBbEIsR0FBNkJHLFNBQXhEO0FBQ0Y7QUFDRDtBQUNELFlBQUVKLEdBQUY7QUFDQTtBQUNGLGFBQUssRUFBTDtBQUFTO0FBQ1AsZUFBS1MsYUFBTDtBQUNBTCxzQkFBWUYsZ0JBQWdCRixHQUE1QjtBQUNBLFlBQUVBLEdBQUY7QUFDQTtBQUNGLGFBQUssRUFBTDtBQUFTO0FBQ1A7QUFDQSxnQkFBSVUsV0FBV1YsR0FBZjtBQUNBLGdCQUFJUixPQUFPRSxJQUFQLENBQVlNLE1BQU0sQ0FBbEIsRUFBcUJLLE1BQXJCLENBQTRCLENBQTVCLE1BQW1DLElBQXZDLEVBQTZDO0FBQzNDLGdCQUFFTCxHQUFGO0FBQ0Q7QUFDRCxjQUFFQSxHQUFGO0FBQ0EsaUJBQUtTLGFBQUw7QUFDQUwsd0JBQVlGLGdCQUFnQlEsUUFBNUI7QUFDQTtBQUNEO0FBQ0Q7QUFDRSxZQUFFVixHQUFGO0FBNUJKO0FBOEJELEtBL0JELE1BK0JPLElBQUlMLFdBQVcsTUFBWCxJQUFxQkEsV0FBVyxNQUFwQyxFQUE0QztBQUNqRCxXQUFLYyxhQUFMO0FBQ0FMLGtCQUFZRixnQkFBZ0JGLEdBQTVCO0FBQ0EsUUFBRUEsR0FBRjtBQUNELEtBSk0sTUFJQTtBQUNMLFFBQUVBLEdBQUY7QUFDRDtBQUNEUCxXQUFPRCxPQUFPRSxJQUFQLENBQVlNLEdBQVosQ0FBUDtBQUNEO0FBQ0QsUUFBTSxLQUFLVyxhQUFMLENBQW1CbEIsSUFBbkIsQ0FBTjtBQUNEIiwiZmlsZSI6InJlYWQtY29tbWVudC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG5pbXBvcnQgdHlwZSB7IENoYXJTdHJlYW0gfSBmcm9tICdyZWFkdGFibGUnO1xuXG5pbXBvcnQgeyBpc0VPUyB9IGZyb20gJ3JlYWR0YWJsZSc7XG5pbXBvcnQgeyBza2lwU2luZ2xlTGluZUNvbW1lbnQgfSBmcm9tICcuL3V0aWxzJztcbmltcG9ydCB7IEVtcHR5VG9rZW4gfSBmcm9tICcuLi90b2tlbnMnO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiByZWFkQ29tbWVudChzdHJlYW06IENoYXJTdHJlYW0pOiB0eXBlb2YgRW1wdHlUb2tlbiB7XG4gIGxldCBjaGFyID0gc3RyZWFtLnBlZWsoKTtcblxuICB3aGlsZSAoIWlzRU9TKGNoYXIpKSB7XG4gICAgbGV0IGNoQ29kZSA9IGNoYXIuY2hhckNvZGVBdCgwKTtcbiAgICBpZiAoY2hDb2RlID09PSA0Nykge1xuICAgICAgLyogXCIvXCIgKi8gY29uc3Qgbnh0ID0gc3RyZWFtLnBlZWsoMSk7XG4gICAgICBpZiAoaXNFT1Mobnh0KSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNoQ29kZSA9IG54dC5jaGFyQ29kZUF0KDApO1xuICAgICAgaWYgKGNoQ29kZSA9PT0gNDcpIHtcbiAgICAgICAgLyogXCIvXCIgKi8gc2tpcFNpbmdsZUxpbmVDb21tZW50LmNhbGwodGhpcywgc3RyZWFtKTtcbiAgICAgIH0gZWxzZSBpZiAoY2hDb2RlID09PSA0Mikge1xuICAgICAgICAvKiBcIipcIiAqLyBza2lwTXVsdGlMaW5lQ29tbWVudC5jYWxsKHRoaXMsIHN0cmVhbSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGNoYXIgPSBzdHJlYW0ucGVlaygpO1xuICB9XG5cbiAgcmV0dXJuIEVtcHR5VG9rZW47XG59XG5cbmZ1bmN0aW9uIHNraXBNdWx0aUxpbmVDb21tZW50KHN0cmVhbTogQ2hhclN0cmVhbSk6IHZvaWQge1xuICBsZXQgaWR4ID0gMjtcbiAgbGV0IGNoYXIgPSBzdHJlYW0ucGVlayhpZHgpO1xuICBjb25zdCB7IHBvc2l0aW9uOiBzdGFydFBvc2l0aW9uIH0gPSBzdHJlYW0uc291cmNlSW5mbztcbiAgbGV0IGxpbmVTdGFydDtcbiAgd2hpbGUgKCFpc0VPUyhjaGFyKSkge1xuICAgIGxldCBjaENvZGUgPSBjaGFyLmNoYXJDb2RlQXQoMCk7XG4gICAgaWYgKGNoQ29kZSA8IDB4ODApIHtcbiAgICAgIHN3aXRjaCAoY2hDb2RlKSB7XG4gICAgICAgIGNhc2UgNDI6IC8vIFwiKlwiXG4gICAgICAgICAgLy8gQmxvY2sgY29tbWVudCBlbmRzIHdpdGggXCIqL1wiLlxuICAgICAgICAgIGlmIChzdHJlYW0ucGVlayhpZHggKyAxKS5jaGFyQXQoMCkgPT09ICcvJykge1xuICAgICAgICAgICAgc3RyZWFtLnJlYWRTdHJpbmcoaWR4ICsgMik7XG4gICAgICAgICAgICBpZiAobGluZVN0YXJ0KVxuICAgICAgICAgICAgICB0aGlzLmxvY2F0aW9uSW5mby5jb2x1bW4gPSBzdHJlYW0uc291cmNlSW5mby5wb3NpdGlvbiAtIGxpbmVTdGFydDtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgKytpZHg7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMTA6IC8vIFwiXFxuXCJcbiAgICAgICAgICB0aGlzLmluY3JlbWVudExpbmUoKTtcbiAgICAgICAgICBsaW5lU3RhcnQgPSBzdGFydFBvc2l0aW9uICsgaWR4O1xuICAgICAgICAgICsraWR4O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDEzOiB7XG4gICAgICAgICAgLy8gXCJcXHJcIjpcbiAgICAgICAgICBsZXQgc3RhcnRJZHggPSBpZHg7XG4gICAgICAgICAgaWYgKHN0cmVhbS5wZWVrKGlkeCArIDEpLmNoYXJBdCgwKSA9PT0gJ1xcbicpIHtcbiAgICAgICAgICAgICsraWR4O1xuICAgICAgICAgIH1cbiAgICAgICAgICArK2lkeDtcbiAgICAgICAgICB0aGlzLmluY3JlbWVudExpbmUoKTtcbiAgICAgICAgICBsaW5lU3RhcnQgPSBzdGFydFBvc2l0aW9uICsgc3RhcnRJZHg7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICArK2lkeDtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGNoQ29kZSA9PT0gMHgyMDI4IHx8IGNoQ29kZSA9PT0gMHgyMDI5KSB7XG4gICAgICB0aGlzLmluY3JlbWVudExpbmUoKTtcbiAgICAgIGxpbmVTdGFydCA9IHN0YXJ0UG9zaXRpb24gKyBpZHg7XG4gICAgICArK2lkeDtcbiAgICB9IGVsc2Uge1xuICAgICAgKytpZHg7XG4gICAgfVxuICAgIGNoYXIgPSBzdHJlYW0ucGVlayhpZHgpO1xuICB9XG4gIHRocm93IHRoaXMuY3JlYXRlSUxMRUdBTChjaGFyKTtcbn1cbiJdfQ==\n\n/***/ },\n/* 37 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.readSyntaxTemplate = readSyntaxTemplate;\n\n\tvar _readtable = __webpack_require__(7);\n\n\tvar _immutable = __webpack_require__(12);\n\n\tvar _tokens = __webpack_require__(19);\n\n\tconst backtickEntry = {\n\t  key: '`',\n\t  mode: 'terminating',\n\t  action: function readBacktick(stream, prefix, e) {\n\t    if (prefix.isEmpty()) {\n\t      return {\n\t        type: _tokens.TokenType.LSYNTAX,\n\t        value: stream.readString()\n\t      };\n\t    }\n\n\t    return {\n\t      type: _tokens.TokenType.RSYNTAX,\n\t      value: stream.readString()\n\t    };\n\t  }\n\t};\n\n\tfunction readSyntaxTemplate(stream, prefix, exprAllowed, dispatchChar) {\n\t  // return read('syntaxTemplate').first().token;\n\t  // TODO: Can we simply tack 'syntaxTemplate' on the front and process it as a\n\t  //       syntax macro?\n\t  const prevTable = (0, _readtable.getCurrentReadtable)();\n\t  (0, _readtable.setCurrentReadtable)(prevTable.extend(backtickEntry));\n\n\t  const result = this.readUntil('`', stream, _immutable.List.of(updateSyntax(dispatchChar, this.readToken(stream, (0, _immutable.List)(), exprAllowed))), exprAllowed);\n\n\t  (0, _readtable.setCurrentReadtable)(prevTable);\n\t  return result;\n\t}\n\n\tfunction updateSyntax(prefix, token) {\n\t  token.value = prefix + token.value;\n\t  token.slice.text = prefix + token.slice.text;\n\t  token.slice.start -= 1;\n\t  token.slice.startLocation.position -= 1;\n\t  return token;\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9yZWFkZXIvcmVhZC1kaXNwYXRjaC5qcyJdLCJuYW1lcyI6WyJyZWFkU3ludGF4VGVtcGxhdGUiLCJiYWNrdGlja0VudHJ5Iiwia2V5IiwibW9kZSIsImFjdGlvbiIsInJlYWRCYWNrdGljayIsInN0cmVhbSIsInByZWZpeCIsImUiLCJpc0VtcHR5IiwidHlwZSIsIkxTWU5UQVgiLCJ2YWx1ZSIsInJlYWRTdHJpbmciLCJSU1lOVEFYIiwiZXhwckFsbG93ZWQiLCJkaXNwYXRjaENoYXIiLCJwcmV2VGFibGUiLCJleHRlbmQiLCJyZXN1bHQiLCJyZWFkVW50aWwiLCJvZiIsInVwZGF0ZVN5bnRheCIsInJlYWRUb2tlbiIsInRva2VuIiwic2xpY2UiLCJ0ZXh0Iiwic3RhcnQiLCJzdGFydExvY2F0aW9uIiwicG9zaXRpb24iXSwibWFwcGluZ3MiOiI7Ozs7O1FBOEJnQkEsa0IsR0FBQUEsa0I7O0FBNUJoQjs7QUFDQTs7QUFDQTs7QUFJQSxNQUFNQyxnQkFBZ0I7QUFDcEJDLE9BQUssR0FEZTtBQUVwQkMsUUFBTSxhQUZjO0FBR3BCQyxVQUFRLFNBQVNDLFlBQVQsQ0FDTkMsTUFETSxFQUVOQyxNQUZNLEVBR05DLENBSE0sRUFJTjtBQUNBLFFBQUlELE9BQU9FLE9BQVAsRUFBSixFQUFzQjtBQUNwQixhQUFPO0FBQ0xDLGNBQU0sa0JBQUdDLE9BREo7QUFFTEMsZUFBT04sT0FBT08sVUFBUDtBQUZGLE9BQVA7QUFJRDs7QUFFRCxXQUFPO0FBQ0xILFlBQU0sa0JBQUdJLE9BREo7QUFFTEYsYUFBT04sT0FBT08sVUFBUDtBQUZGLEtBQVA7QUFJRDtBQW5CbUIsQ0FBdEI7O0FBc0JPLFNBQVNiLGtCQUFULENBQ0xNLE1BREssRUFFTEMsTUFGSyxFQUdMUSxXQUhLLEVBSUxDLFlBSkssRUFLbUQ7QUFDeEQ7QUFDQTtBQUNBO0FBQ0EsUUFBTUMsWUFBWSxxQ0FBbEI7QUFDQSxzQ0FBb0JBLFVBQVVDLE1BQVYsQ0FBaUJqQixhQUFqQixDQUFwQjs7QUFFQSxRQUFNa0IsU0FBUyxLQUFLQyxTQUFMLENBQ2IsR0FEYSxFQUViZCxNQUZhLEVBR2IsZ0JBQUtlLEVBQUwsQ0FDRUMsYUFBYU4sWUFBYixFQUEyQixLQUFLTyxTQUFMLENBQWVqQixNQUFmLEVBQXVCLHNCQUF2QixFQUErQlMsV0FBL0IsQ0FBM0IsQ0FERixDQUhhLEVBTWJBLFdBTmEsQ0FBZjs7QUFTQSxzQ0FBb0JFLFNBQXBCO0FBQ0EsU0FBT0UsTUFBUDtBQUNEOztBQUVELFNBQVNHLFlBQVQsQ0FBc0JmLE1BQXRCLEVBQThCaUIsS0FBOUIsRUFBcUM7QUFDbkNBLFFBQU1aLEtBQU4sR0FBY0wsU0FBU2lCLE1BQU1aLEtBQTdCO0FBQ0FZLFFBQU1DLEtBQU4sQ0FBWUMsSUFBWixHQUFtQm5CLFNBQVNpQixNQUFNQyxLQUFOLENBQVlDLElBQXhDO0FBQ0FGLFFBQU1DLEtBQU4sQ0FBWUUsS0FBWixJQUFxQixDQUFyQjtBQUNBSCxRQUFNQyxLQUFOLENBQVlHLGFBQVosQ0FBMEJDLFFBQTFCLElBQXNDLENBQXRDO0FBQ0EsU0FBT0wsS0FBUDtBQUNEIiwiZmlsZSI6InJlYWQtZGlzcGF0Y2guanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAZmxvd1xuXG5pbXBvcnQgeyBnZXRDdXJyZW50UmVhZHRhYmxlLCBzZXRDdXJyZW50UmVhZHRhYmxlIH0gZnJvbSAncmVhZHRhYmxlJztcbmltcG9ydCB7IExpc3QgfSBmcm9tICdpbW11dGFibGUnO1xuaW1wb3J0IHsgVG9rZW5UeXBlIGFzIFRUIH0gZnJvbSAnLi4vdG9rZW5zJztcblxuaW1wb3J0IHR5cGUgeyBDaGFyU3RyZWFtIH0gZnJvbSAncmVhZHRhYmxlJztcblxuY29uc3QgYmFja3RpY2tFbnRyeSA9IHtcbiAga2V5OiAnYCcsXG4gIG1vZGU6ICd0ZXJtaW5hdGluZycsXG4gIGFjdGlvbjogZnVuY3Rpb24gcmVhZEJhY2t0aWNrKFxuICAgIHN0cmVhbTogQ2hhclN0cmVhbSxcbiAgICBwcmVmaXg6IExpc3Q8YW55PixcbiAgICBlOiBib29sZWFuLFxuICApIHtcbiAgICBpZiAocHJlZml4LmlzRW1wdHkoKSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogVFQuTFNZTlRBWCxcbiAgICAgICAgdmFsdWU6IHN0cmVhbS5yZWFkU3RyaW5nKCksXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiBUVC5SU1lOVEFYLFxuICAgICAgdmFsdWU6IHN0cmVhbS5yZWFkU3RyaW5nKCksXG4gICAgfTtcbiAgfSxcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiByZWFkU3ludGF4VGVtcGxhdGUoXG4gIHN0cmVhbTogQ2hhclN0cmVhbSxcbiAgcHJlZml4OiBMaXN0PGFueT4sXG4gIGV4cHJBbGxvd2VkOiBib29sZWFuLFxuICBkaXNwYXRjaENoYXI6IHN0cmluZyxcbik6IExpc3Q8YW55PiB8IHsgdHlwZTogdHlwZW9mIFRULlJTWU5UQVgsIHZhbHVlOiBzdHJpbmcgfSB7XG4gIC8vIHJldHVybiByZWFkKCdzeW50YXhUZW1wbGF0ZScpLmZpcnN0KCkudG9rZW47XG4gIC8vIFRPRE86IENhbiB3ZSBzaW1wbHkgdGFjayAnc3ludGF4VGVtcGxhdGUnIG9uIHRoZSBmcm9udCBhbmQgcHJvY2VzcyBpdCBhcyBhXG4gIC8vICAgICAgIHN5bnRheCBtYWNybz9cbiAgY29uc3QgcHJldlRhYmxlID0gZ2V0Q3VycmVudFJlYWR0YWJsZSgpO1xuICBzZXRDdXJyZW50UmVhZHRhYmxlKHByZXZUYWJsZS5leHRlbmQoYmFja3RpY2tFbnRyeSkpO1xuXG4gIGNvbnN0IHJlc3VsdCA9IHRoaXMucmVhZFVudGlsKFxuICAgICdgJyxcbiAgICBzdHJlYW0sXG4gICAgTGlzdC5vZihcbiAgICAgIHVwZGF0ZVN5bnRheChkaXNwYXRjaENoYXIsIHRoaXMucmVhZFRva2VuKHN0cmVhbSwgTGlzdCgpLCBleHByQWxsb3dlZCkpLFxuICAgICksXG4gICAgZXhwckFsbG93ZWQsXG4gICk7XG5cbiAgc2V0Q3VycmVudFJlYWR0YWJsZShwcmV2VGFibGUpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiB1cGRhdGVTeW50YXgocHJlZml4LCB0b2tlbikge1xuICB0b2tlbi52YWx1ZSA9IHByZWZpeCArIHRva2VuLnZhbHVlO1xuICB0b2tlbi5zbGljZS50ZXh0ID0gcHJlZml4ICsgdG9rZW4uc2xpY2UudGV4dDtcbiAgdG9rZW4uc2xpY2Uuc3RhcnQgLT0gMTtcbiAgdG9rZW4uc2xpY2Uuc3RhcnRMb2NhdGlvbi5wb3NpdGlvbiAtPSAxO1xuICByZXR1cm4gdG9rZW47XG59XG4iXX0=\n\n/***/ },\n/* 38 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.freshScope = freshScope;\n\texports.Scope = Scope;\n\n\tvar _symbol = __webpack_require__(39);\n\n\tlet scopeIndex = 0;\n\tfunction freshScope(name = 'scope') {\n\t  scopeIndex++;\n\t  return (0, _symbol.Symbol)(name + '_' + scopeIndex);\n\t}\n\n\tfunction Scope(name) {\n\t  return (0, _symbol.Symbol)(name);\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY29wZS5qcyJdLCJuYW1lcyI6WyJmcmVzaFNjb3BlIiwiU2NvcGUiLCJzY29wZUluZGV4IiwibmFtZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7UUFLZ0JBLFUsR0FBQUEsVTtRQUtBQyxLLEdBQUFBLEs7O0FBVGhCOztBQUVBLElBQUlDLGFBQWEsQ0FBakI7QUFFTyxTQUFTRixVQUFULENBQW9CRyxPQUFlLE9BQW5DLEVBQTRDO0FBQ2pERDtBQUNBLFNBQU8sb0JBQU9DLE9BQU8sR0FBUCxHQUFhRCxVQUFwQixDQUFQO0FBQ0Q7O0FBRU0sU0FBU0QsS0FBVCxDQUFlRSxJQUFmLEVBQTZCO0FBQ2xDLFNBQU8sb0JBQU9BLElBQVAsQ0FBUDtBQUNEIiwiZmlsZSI6InNjb3BlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbmltcG9ydCB7IFN5bWJvbCB9IGZyb20gJy4vc3ltYm9sJztcblxubGV0IHNjb3BlSW5kZXggPSAwO1xuXG5leHBvcnQgZnVuY3Rpb24gZnJlc2hTY29wZShuYW1lOiBzdHJpbmcgPSAnc2NvcGUnKSB7XG4gIHNjb3BlSW5kZXgrKztcbiAgcmV0dXJuIFN5bWJvbChuYW1lICsgJ18nICsgc2NvcGVJbmRleCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBTY29wZShuYW1lOiBzdHJpbmcpIHtcbiAgcmV0dXJuIFN5bWJvbChuYW1lKTtcbn1cbiJdfQ==\n\n/***/ },\n/* 39 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.gensym = gensym;\n\tlet internedMap = new Map();\n\n\tlet counter = 0;\n\n\tfunction gensym(name) {\n\t  let prefix = name == null ? 's_' : name + '_';\n\t  let sym = new Symbol(prefix + counter);\n\t  counter++;\n\t  return sym;\n\t}\n\n\tclass Symbol {\n\n\t  constructor(name) {\n\t    this.name = name;\n\t  }\n\t  toString() {\n\t    return this.name;\n\t  }\n\t}\n\n\tfunction makeSymbol(name) {\n\t  let s = internedMap.get(name);\n\t  if (s) {\n\t    return s;\n\t  } else {\n\t    let sym = new Symbol(name);\n\t    internedMap.set(name, sym);\n\t    return sym;\n\t  }\n\t}\n\n\texports.Symbol = makeSymbol;\n\texports.SymbolClass = Symbol;\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zeW1ib2wuanMiXSwibmFtZXMiOlsiZ2Vuc3ltIiwiaW50ZXJuZWRNYXAiLCJNYXAiLCJjb3VudGVyIiwibmFtZSIsInByZWZpeCIsInN5bSIsIlN5bWJvbCIsImNvbnN0cnVjdG9yIiwidG9TdHJpbmciLCJtYWtlU3ltYm9sIiwicyIsImdldCIsInNldCIsIlN5bWJvbENsYXNzIl0sIm1hcHBpbmdzIjoiOzs7OztRQUtnQkEsTSxHQUFBQSxNO0FBSmhCLElBQUlDLGNBQW1DLElBQUlDLEdBQUosRUFBdkM7O0FBRUEsSUFBSUMsVUFBVSxDQUFkOztBQUVPLFNBQVNILE1BQVQsQ0FBZ0JJLElBQWhCLEVBQThCO0FBQ25DLE1BQUlDLFNBQVNELFFBQVEsSUFBUixHQUFlLElBQWYsR0FBc0JBLE9BQU8sR0FBMUM7QUFDQSxNQUFJRSxNQUFNLElBQUlDLE1BQUosQ0FBV0YsU0FBU0YsT0FBcEIsQ0FBVjtBQUNBQTtBQUNBLFNBQU9HLEdBQVA7QUFDRDs7QUFFRCxNQUFNQyxNQUFOLENBQWE7O0FBR1hDLGNBQVlKLElBQVosRUFBMEI7QUFDeEIsU0FBS0EsSUFBTCxHQUFZQSxJQUFaO0FBQ0Q7QUFDREssYUFBVztBQUNULFdBQU8sS0FBS0wsSUFBWjtBQUNEO0FBUlU7O0FBV2IsU0FBU00sVUFBVCxDQUFvQk4sSUFBcEIsRUFBMEM7QUFDeEMsTUFBSU8sSUFBSVYsWUFBWVcsR0FBWixDQUFnQlIsSUFBaEIsQ0FBUjtBQUNBLE1BQUlPLENBQUosRUFBTztBQUNMLFdBQU9BLENBQVA7QUFDRCxHQUZELE1BRU87QUFDTCxRQUFJTCxNQUFNLElBQUlDLE1BQUosQ0FBV0gsSUFBWCxDQUFWO0FBQ0FILGdCQUFZWSxHQUFaLENBQWdCVCxJQUFoQixFQUFzQkUsR0FBdEI7QUFDQSxXQUFPQSxHQUFQO0FBQ0Q7QUFDRjs7UUFFc0JDLE0sR0FBZEcsVTtRQUFnQ0ksVyxHQUFWUCxNIiwiZmlsZSI6InN5bWJvbC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG5sZXQgaW50ZXJuZWRNYXA6IE1hcDxzdHJpbmcsIFN5bWJvbD4gPSBuZXcgTWFwKCk7XG5cbmxldCBjb3VudGVyID0gMDtcblxuZXhwb3J0IGZ1bmN0aW9uIGdlbnN5bShuYW1lOiBzdHJpbmcpIHtcbiAgbGV0IHByZWZpeCA9IG5hbWUgPT0gbnVsbCA/ICdzXycgOiBuYW1lICsgJ18nO1xuICBsZXQgc3ltID0gbmV3IFN5bWJvbChwcmVmaXggKyBjb3VudGVyKTtcbiAgY291bnRlcisrO1xuICByZXR1cm4gc3ltO1xufVxuXG5jbGFzcyBTeW1ib2wge1xuICBuYW1lOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IobmFtZTogc3RyaW5nKSB7XG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgfVxuICB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gdGhpcy5uYW1lO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1ha2VTeW1ib2wobmFtZTogc3RyaW5nKTogU3ltYm9sIHtcbiAgbGV0IHMgPSBpbnRlcm5lZE1hcC5nZXQobmFtZSk7XG4gIGlmIChzKSB7XG4gICAgcmV0dXJuIHM7XG4gIH0gZWxzZSB7XG4gICAgbGV0IHN5bSA9IG5ldyBTeW1ib2wobmFtZSk7XG4gICAgaW50ZXJuZWRNYXAuc2V0KG5hbWUsIHN5bSk7XG4gICAgcmV0dXJuIHN5bTtcbiAgfVxufVxuXG5leHBvcnQgeyBtYWtlU3ltYm9sIGFzIFN5bWJvbCwgU3ltYm9sIGFzIFN5bWJvbENsYXNzIH07XG4iXX0=\n\n/***/ },\n/* 40 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\n\tvar _transforms = __webpack_require__(41);\n\n\tclass Env {\n\t  constructor() {\n\t    this.map = new Map();\n\t    this.map.set('function', _transforms.FunctionDeclTransform);\n\t    this.map.set('var', _transforms.VariableDeclTransform);\n\t    this.map.set('let', _transforms.LetDeclTransform);\n\t    this.map.set('const', _transforms.ConstDeclTransform);\n\t    this.map.set('syntaxrec', _transforms.SyntaxrecDeclTransform);\n\t    this.map.set('syntax', _transforms.SyntaxDeclTransform);\n\t    this.map.set('operator', _transforms.OperatorDeclTransform);\n\t    this.map.set('return', _transforms.ReturnStatementTransform);\n\t    this.map.set('while', _transforms.WhileTransform);\n\t    this.map.set('if', _transforms.IfTransform);\n\t    this.map.set('for', _transforms.ForTransform);\n\t    this.map.set('switch', _transforms.SwitchTransform);\n\t    this.map.set('break', _transforms.BreakTransform);\n\t    this.map.set('continue', _transforms.ContinueTransform);\n\t    this.map.set('do', _transforms.DoTransform);\n\t    this.map.set('debugger', _transforms.DebuggerTransform);\n\t    this.map.set('with', _transforms.WithTransform);\n\t    this.map.set('import', _transforms.ImportTransform);\n\t    this.map.set('export', _transforms.ExportTransform);\n\t    this.map.set('super', _transforms.SuperTransform);\n\t    this.map.set('this', _transforms.ThisTransform);\n\t    this.map.set('class', _transforms.ClassTransform);\n\t    this.map.set('default', _transforms.DefaultTransform);\n\t    this.map.set('try', _transforms.TryTransform);\n\t    this.map.set('yield', _transforms.YieldTransform);\n\t    this.map.set('throw', _transforms.ThrowTransform);\n\t    this.map.set('new', _transforms.NewTransform);\n\t  }\n\n\t  has(key) {\n\t    return this.map.has(key);\n\t  }\n\n\t  get(key) {\n\t    return this.map.get(key);\n\t  }\n\n\t  set(key, val) {\n\t    return this.map.set(key, val);\n\t  }\n\t}\n\texports.default = Env;\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lbnYuanMiXSwibmFtZXMiOlsiRW52IiwiY29uc3RydWN0b3IiLCJtYXAiLCJNYXAiLCJzZXQiLCJoYXMiLCJrZXkiLCJnZXQiLCJ2YWwiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBOztBQThCZSxNQUFNQSxHQUFOLENBQVU7QUFDdkJDLGdCQUFjO0FBQ1osU0FBS0MsR0FBTCxHQUFXLElBQUlDLEdBQUosRUFBWDtBQUNBLFNBQUtELEdBQUwsQ0FBU0UsR0FBVCxDQUFhLFVBQWI7QUFDQSxTQUFLRixHQUFMLENBQVNFLEdBQVQsQ0FBYSxLQUFiO0FBQ0EsU0FBS0YsR0FBTCxDQUFTRSxHQUFULENBQWEsS0FBYjtBQUNBLFNBQUtGLEdBQUwsQ0FBU0UsR0FBVCxDQUFhLE9BQWI7QUFDQSxTQUFLRixHQUFMLENBQVNFLEdBQVQsQ0FBYSxXQUFiO0FBQ0EsU0FBS0YsR0FBTCxDQUFTRSxHQUFULENBQWEsUUFBYjtBQUNBLFNBQUtGLEdBQUwsQ0FBU0UsR0FBVCxDQUFhLFVBQWI7QUFDQSxTQUFLRixHQUFMLENBQVNFLEdBQVQsQ0FBYSxRQUFiO0FBQ0EsU0FBS0YsR0FBTCxDQUFTRSxHQUFULENBQWEsT0FBYjtBQUNBLFNBQUtGLEdBQUwsQ0FBU0UsR0FBVCxDQUFhLElBQWI7QUFDQSxTQUFLRixHQUFMLENBQVNFLEdBQVQsQ0FBYSxLQUFiO0FBQ0EsU0FBS0YsR0FBTCxDQUFTRSxHQUFULENBQWEsUUFBYjtBQUNBLFNBQUtGLEdBQUwsQ0FBU0UsR0FBVCxDQUFhLE9BQWI7QUFDQSxTQUFLRixHQUFMLENBQVNFLEdBQVQsQ0FBYSxVQUFiO0FBQ0EsU0FBS0YsR0FBTCxDQUFTRSxHQUFULENBQWEsSUFBYjtBQUNBLFNBQUtGLEdBQUwsQ0FBU0UsR0FBVCxDQUFhLFVBQWI7QUFDQSxTQUFLRixHQUFMLENBQVNFLEdBQVQsQ0FBYSxNQUFiO0FBQ0EsU0FBS0YsR0FBTCxDQUFTRSxHQUFULENBQWEsUUFBYjtBQUNBLFNBQUtGLEdBQUwsQ0FBU0UsR0FBVCxDQUFhLFFBQWI7QUFDQSxTQUFLRixHQUFMLENBQVNFLEdBQVQsQ0FBYSxPQUFiO0FBQ0EsU0FBS0YsR0FBTCxDQUFTRSxHQUFULENBQWEsTUFBYjtBQUNBLFNBQUtGLEdBQUwsQ0FBU0UsR0FBVCxDQUFhLE9BQWI7QUFDQSxTQUFLRixHQUFMLENBQVNFLEdBQVQsQ0FBYSxTQUFiO0FBQ0EsU0FBS0YsR0FBTCxDQUFTRSxHQUFULENBQWEsS0FBYjtBQUNBLFNBQUtGLEdBQUwsQ0FBU0UsR0FBVCxDQUFhLE9BQWI7QUFDQSxTQUFLRixHQUFMLENBQVNFLEdBQVQsQ0FBYSxPQUFiO0FBQ0EsU0FBS0YsR0FBTCxDQUFTRSxHQUFULENBQWEsS0FBYjtBQUNEOztBQUVEQyxNQUFJQyxHQUFKLEVBQVM7QUFDUCxXQUFPLEtBQUtKLEdBQUwsQ0FBU0csR0FBVCxDQUFhQyxHQUFiLENBQVA7QUFDRDs7QUFFREMsTUFBSUQsR0FBSixFQUFTO0FBQ1AsV0FBTyxLQUFLSixHQUFMLENBQVNLLEdBQVQsQ0FBYUQsR0FBYixDQUFQO0FBQ0Q7O0FBRURGLE1BQUlFLEdBQUosRUFBU0UsR0FBVCxFQUFjO0FBQ1osV0FBTyxLQUFLTixHQUFMLENBQVNFLEdBQVQsQ0FBYUUsR0FBYixFQUFrQkUsR0FBbEIsQ0FBUDtBQUNEO0FBMUNzQjtrQkFBSlIsRyIsImZpbGUiOiJlbnYuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBGdW5jdGlvbkRlY2xUcmFuc2Zvcm0sXG4gIFZhcmlhYmxlRGVjbFRyYW5zZm9ybSxcbiAgTGV0RGVjbFRyYW5zZm9ybSxcbiAgQ29uc3REZWNsVHJhbnNmb3JtLFxuICBTeW50YXhEZWNsVHJhbnNmb3JtLFxuICBTeW50YXhyZWNEZWNsVHJhbnNmb3JtLFxuICBPcGVyYXRvckRlY2xUcmFuc2Zvcm0sXG4gIFJldHVyblN0YXRlbWVudFRyYW5zZm9ybSxcbiAgSWZUcmFuc2Zvcm0sXG4gIEZvclRyYW5zZm9ybSxcbiAgU3dpdGNoVHJhbnNmb3JtLFxuICBCcmVha1RyYW5zZm9ybSxcbiAgQ29udGludWVUcmFuc2Zvcm0sXG4gIERvVHJhbnNmb3JtLFxuICBEZWJ1Z2dlclRyYW5zZm9ybSxcbiAgV2l0aFRyYW5zZm9ybSxcbiAgSW1wb3J0VHJhbnNmb3JtLFxuICBFeHBvcnRUcmFuc2Zvcm0sXG4gIFN1cGVyVHJhbnNmb3JtLFxuICBUaGlzVHJhbnNmb3JtLFxuICBZaWVsZFRyYW5zZm9ybSxcbiAgQ2xhc3NUcmFuc2Zvcm0sXG4gIERlZmF1bHRUcmFuc2Zvcm0sXG4gIFRyeVRyYW5zZm9ybSxcbiAgVGhyb3dUcmFuc2Zvcm0sXG4gIE5ld1RyYW5zZm9ybSxcbiAgV2hpbGVUcmFuc2Zvcm0sXG59IGZyb20gJy4vdHJhbnNmb3Jtcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEVudiB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMubWFwID0gbmV3IE1hcCgpO1xuICAgIHRoaXMubWFwLnNldCgnZnVuY3Rpb24nLCBGdW5jdGlvbkRlY2xUcmFuc2Zvcm0pO1xuICAgIHRoaXMubWFwLnNldCgndmFyJywgVmFyaWFibGVEZWNsVHJhbnNmb3JtKTtcbiAgICB0aGlzLm1hcC5zZXQoJ2xldCcsIExldERlY2xUcmFuc2Zvcm0pO1xuICAgIHRoaXMubWFwLnNldCgnY29uc3QnLCBDb25zdERlY2xUcmFuc2Zvcm0pO1xuICAgIHRoaXMubWFwLnNldCgnc3ludGF4cmVjJywgU3ludGF4cmVjRGVjbFRyYW5zZm9ybSk7XG4gICAgdGhpcy5tYXAuc2V0KCdzeW50YXgnLCBTeW50YXhEZWNsVHJhbnNmb3JtKTtcbiAgICB0aGlzLm1hcC5zZXQoJ29wZXJhdG9yJywgT3BlcmF0b3JEZWNsVHJhbnNmb3JtKTtcbiAgICB0aGlzLm1hcC5zZXQoJ3JldHVybicsIFJldHVyblN0YXRlbWVudFRyYW5zZm9ybSk7XG4gICAgdGhpcy5tYXAuc2V0KCd3aGlsZScsIFdoaWxlVHJhbnNmb3JtKTtcbiAgICB0aGlzLm1hcC5zZXQoJ2lmJywgSWZUcmFuc2Zvcm0pO1xuICAgIHRoaXMubWFwLnNldCgnZm9yJywgRm9yVHJhbnNmb3JtKTtcbiAgICB0aGlzLm1hcC5zZXQoJ3N3aXRjaCcsIFN3aXRjaFRyYW5zZm9ybSk7XG4gICAgdGhpcy5tYXAuc2V0KCdicmVhaycsIEJyZWFrVHJhbnNmb3JtKTtcbiAgICB0aGlzLm1hcC5zZXQoJ2NvbnRpbnVlJywgQ29udGludWVUcmFuc2Zvcm0pO1xuICAgIHRoaXMubWFwLnNldCgnZG8nLCBEb1RyYW5zZm9ybSk7XG4gICAgdGhpcy5tYXAuc2V0KCdkZWJ1Z2dlcicsIERlYnVnZ2VyVHJhbnNmb3JtKTtcbiAgICB0aGlzLm1hcC5zZXQoJ3dpdGgnLCBXaXRoVHJhbnNmb3JtKTtcbiAgICB0aGlzLm1hcC5zZXQoJ2ltcG9ydCcsIEltcG9ydFRyYW5zZm9ybSk7XG4gICAgdGhpcy5tYXAuc2V0KCdleHBvcnQnLCBFeHBvcnRUcmFuc2Zvcm0pO1xuICAgIHRoaXMubWFwLnNldCgnc3VwZXInLCBTdXBlclRyYW5zZm9ybSk7XG4gICAgdGhpcy5tYXAuc2V0KCd0aGlzJywgVGhpc1RyYW5zZm9ybSk7XG4gICAgdGhpcy5tYXAuc2V0KCdjbGFzcycsIENsYXNzVHJhbnNmb3JtKTtcbiAgICB0aGlzLm1hcC5zZXQoJ2RlZmF1bHQnLCBEZWZhdWx0VHJhbnNmb3JtKTtcbiAgICB0aGlzLm1hcC5zZXQoJ3RyeScsIFRyeVRyYW5zZm9ybSk7XG4gICAgdGhpcy5tYXAuc2V0KCd5aWVsZCcsIFlpZWxkVHJhbnNmb3JtKTtcbiAgICB0aGlzLm1hcC5zZXQoJ3Rocm93JywgVGhyb3dUcmFuc2Zvcm0pO1xuICAgIHRoaXMubWFwLnNldCgnbmV3JywgTmV3VHJhbnNmb3JtKTtcbiAgfVxuXG4gIGhhcyhrZXkpIHtcbiAgICByZXR1cm4gdGhpcy5tYXAuaGFzKGtleSk7XG4gIH1cblxuICBnZXQoa2V5KSB7XG4gICAgcmV0dXJuIHRoaXMubWFwLmdldChrZXkpO1xuICB9XG5cbiAgc2V0KGtleSwgdmFsKSB7XG4gICAgcmV0dXJuIHRoaXMubWFwLnNldChrZXksIHZhbCk7XG4gIH1cbn1cbiJdfQ==\n\n/***/ },\n/* 41 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.CompiletimeTransform = exports.VarBindingTransform = exports.ModuleNamespaceTransform = exports.ReturnStatementTransform = exports.OperatorDeclTransform = exports.SyntaxDeclTransform = exports.SyntaxrecDeclTransform = exports.DebuggerTransform = exports.DefaultTransform = exports.ClassTransform = exports.ThisTransform = exports.YieldTransform = exports.SuperTransform = exports.ExportTransform = exports.ImportTransform = exports.WithTransform = exports.DoTransform = exports.ContinueTransform = exports.BreakTransform = exports.SwitchTransform = exports.ForTransform = exports.IfTransform = exports.WhileTransform = exports.TryTransform = exports.ConstDeclTransform = exports.LetDeclTransform = exports.ThrowTransform = exports.NewTransform = exports.VariableDeclTransform = exports.FunctionDeclTransform = undefined;\n\n\tvar _sweetModule = __webpack_require__(42);\n\n\tvar _sweetModule2 = _interopRequireDefault(_sweetModule);\n\n\tvar _syntax = __webpack_require__(58);\n\n\tvar _syntax2 = _interopRequireDefault(_syntax);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tclass FunctionDeclTransform {}\n\texports.FunctionDeclTransform = FunctionDeclTransform;\n\tclass VariableDeclTransform {}\n\texports.VariableDeclTransform = VariableDeclTransform;\n\tclass NewTransform {}\n\texports.NewTransform = NewTransform;\n\tclass ThrowTransform {}\n\texports.ThrowTransform = ThrowTransform;\n\tclass LetDeclTransform {}\n\texports.LetDeclTransform = LetDeclTransform;\n\tclass ConstDeclTransform {}\n\texports.ConstDeclTransform = ConstDeclTransform;\n\tclass TryTransform {}\n\texports.TryTransform = TryTransform;\n\tclass WhileTransform {}\n\texports.WhileTransform = WhileTransform;\n\tclass IfTransform {}\n\texports.IfTransform = IfTransform;\n\tclass ForTransform {}\n\texports.ForTransform = ForTransform;\n\tclass SwitchTransform {}\n\texports.SwitchTransform = SwitchTransform;\n\tclass BreakTransform {}\n\texports.BreakTransform = BreakTransform;\n\tclass ContinueTransform {}\n\texports.ContinueTransform = ContinueTransform;\n\tclass DoTransform {}\n\texports.DoTransform = DoTransform;\n\tclass WithTransform {}\n\texports.WithTransform = WithTransform;\n\tclass ImportTransform {}\n\texports.ImportTransform = ImportTransform;\n\tclass ExportTransform {}\n\texports.ExportTransform = ExportTransform;\n\tclass SuperTransform {}\n\texports.SuperTransform = SuperTransform;\n\tclass YieldTransform {}\n\texports.YieldTransform = YieldTransform;\n\tclass ThisTransform {}\n\texports.ThisTransform = ThisTransform;\n\tclass ClassTransform {}\n\texports.ClassTransform = ClassTransform;\n\tclass DefaultTransform {}\n\texports.DefaultTransform = DefaultTransform;\n\tclass DebuggerTransform {}\n\texports.DebuggerTransform = DebuggerTransform;\n\tclass SyntaxrecDeclTransform {}\n\texports.SyntaxrecDeclTransform = SyntaxrecDeclTransform;\n\tclass SyntaxDeclTransform {}\n\texports.SyntaxDeclTransform = SyntaxDeclTransform;\n\tclass OperatorDeclTransform {}\n\texports.OperatorDeclTransform = OperatorDeclTransform;\n\tclass ReturnStatementTransform {}\n\texports.ReturnStatementTransform = ReturnStatementTransform;\n\tclass ModuleNamespaceTransform {\n\n\t  constructor(namespace, mod) {\n\t    this.namespace = namespace;\n\t    this.mod = mod;\n\t  }\n\t}\n\texports.ModuleNamespaceTransform = ModuleNamespaceTransform;\n\tclass VarBindingTransform {\n\n\t  constructor(id) {\n\t    this.id = id;\n\t  }\n\t}\n\texports.VarBindingTransform = VarBindingTransform;\n\tclass CompiletimeTransform {\n\n\t  constructor(value) {\n\t    this.value = value;\n\t  }\n\t}\n\texports.CompiletimeTransform = CompiletimeTransform;\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90cmFuc2Zvcm1zLmpzIl0sIm5hbWVzIjpbIkZ1bmN0aW9uRGVjbFRyYW5zZm9ybSIsIlZhcmlhYmxlRGVjbFRyYW5zZm9ybSIsIk5ld1RyYW5zZm9ybSIsIlRocm93VHJhbnNmb3JtIiwiTGV0RGVjbFRyYW5zZm9ybSIsIkNvbnN0RGVjbFRyYW5zZm9ybSIsIlRyeVRyYW5zZm9ybSIsIldoaWxlVHJhbnNmb3JtIiwiSWZUcmFuc2Zvcm0iLCJGb3JUcmFuc2Zvcm0iLCJTd2l0Y2hUcmFuc2Zvcm0iLCJCcmVha1RyYW5zZm9ybSIsIkNvbnRpbnVlVHJhbnNmb3JtIiwiRG9UcmFuc2Zvcm0iLCJXaXRoVHJhbnNmb3JtIiwiSW1wb3J0VHJhbnNmb3JtIiwiRXhwb3J0VHJhbnNmb3JtIiwiU3VwZXJUcmFuc2Zvcm0iLCJZaWVsZFRyYW5zZm9ybSIsIlRoaXNUcmFuc2Zvcm0iLCJDbGFzc1RyYW5zZm9ybSIsIkRlZmF1bHRUcmFuc2Zvcm0iLCJEZWJ1Z2dlclRyYW5zZm9ybSIsIlN5bnRheHJlY0RlY2xUcmFuc2Zvcm0iLCJTeW50YXhEZWNsVHJhbnNmb3JtIiwiT3BlcmF0b3JEZWNsVHJhbnNmb3JtIiwiUmV0dXJuU3RhdGVtZW50VHJhbnNmb3JtIiwiTW9kdWxlTmFtZXNwYWNlVHJhbnNmb3JtIiwiY29uc3RydWN0b3IiLCJuYW1lc3BhY2UiLCJtb2QiLCJWYXJCaW5kaW5nVHJhbnNmb3JtIiwiaWQiLCJDb21waWxldGltZVRyYW5zZm9ybSIsInZhbHVlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7Ozs7QUFDQTs7Ozs7O0FBRU8sTUFBTUEscUJBQU4sQ0FBNEI7UUFBdEJBLHFCLEdBQUFBLHFCO0FBQ04sTUFBTUMscUJBQU4sQ0FBNEI7UUFBdEJBLHFCLEdBQUFBLHFCO0FBQ04sTUFBTUMsWUFBTixDQUFtQjtRQUFiQSxZLEdBQUFBLFk7QUFDTixNQUFNQyxjQUFOLENBQXFCO1FBQWZBLGMsR0FBQUEsYztBQUNOLE1BQU1DLGdCQUFOLENBQXVCO1FBQWpCQSxnQixHQUFBQSxnQjtBQUNOLE1BQU1DLGtCQUFOLENBQXlCO1FBQW5CQSxrQixHQUFBQSxrQjtBQUNOLE1BQU1DLFlBQU4sQ0FBbUI7UUFBYkEsWSxHQUFBQSxZO0FBQ04sTUFBTUMsY0FBTixDQUFxQjtRQUFmQSxjLEdBQUFBLGM7QUFDTixNQUFNQyxXQUFOLENBQWtCO1FBQVpBLFcsR0FBQUEsVztBQUNOLE1BQU1DLFlBQU4sQ0FBbUI7UUFBYkEsWSxHQUFBQSxZO0FBQ04sTUFBTUMsZUFBTixDQUFzQjtRQUFoQkEsZSxHQUFBQSxlO0FBQ04sTUFBTUMsY0FBTixDQUFxQjtRQUFmQSxjLEdBQUFBLGM7QUFDTixNQUFNQyxpQkFBTixDQUF3QjtRQUFsQkEsaUIsR0FBQUEsaUI7QUFDTixNQUFNQyxXQUFOLENBQWtCO1FBQVpBLFcsR0FBQUEsVztBQUNOLE1BQU1DLGFBQU4sQ0FBb0I7UUFBZEEsYSxHQUFBQSxhO0FBQ04sTUFBTUMsZUFBTixDQUFzQjtRQUFoQkEsZSxHQUFBQSxlO0FBQ04sTUFBTUMsZUFBTixDQUFzQjtRQUFoQkEsZSxHQUFBQSxlO0FBQ04sTUFBTUMsY0FBTixDQUFxQjtRQUFmQSxjLEdBQUFBLGM7QUFDTixNQUFNQyxjQUFOLENBQXFCO1FBQWZBLGMsR0FBQUEsYztBQUNOLE1BQU1DLGFBQU4sQ0FBb0I7UUFBZEEsYSxHQUFBQSxhO0FBQ04sTUFBTUMsY0FBTixDQUFxQjtRQUFmQSxjLEdBQUFBLGM7QUFDTixNQUFNQyxnQkFBTixDQUF1QjtRQUFqQkEsZ0IsR0FBQUEsZ0I7QUFDTixNQUFNQyxpQkFBTixDQUF3QjtRQUFsQkEsaUIsR0FBQUEsaUI7QUFDTixNQUFNQyxzQkFBTixDQUE2QjtRQUF2QkEsc0IsR0FBQUEsc0I7QUFDTixNQUFNQyxtQkFBTixDQUEwQjtRQUFwQkEsbUIsR0FBQUEsbUI7QUFDTixNQUFNQyxxQkFBTixDQUE0QjtRQUF0QkEscUIsR0FBQUEscUI7QUFDTixNQUFNQyx3QkFBTixDQUErQjtRQUF6QkEsd0IsR0FBQUEsd0I7QUFDTixNQUFNQyx3QkFBTixDQUErQjs7QUFJcENDLGNBQVlDLFNBQVosRUFBK0JDLEdBQS9CLEVBQWlEO0FBQy9DLFNBQUtELFNBQUwsR0FBaUJBLFNBQWpCO0FBQ0EsU0FBS0MsR0FBTCxHQUFXQSxHQUFYO0FBQ0Q7QUFQbUM7UUFBekJILHdCLEdBQUFBLHdCO0FBU04sTUFBTUksbUJBQU4sQ0FBMEI7O0FBRy9CSCxjQUFZSSxFQUFaLEVBQXdCO0FBQ3RCLFNBQUtBLEVBQUwsR0FBVUEsRUFBVjtBQUNEO0FBTDhCO1FBQXBCRCxtQixHQUFBQSxtQjtBQU9OLE1BQU1FLG9CQUFOLENBQTJCOztBQUdoQ0wsY0FBWU0sS0FBWixFQUF3QjtBQUN0QixTQUFLQSxLQUFMLEdBQWFBLEtBQWI7QUFDRDtBQUwrQjtRQUFyQkQsb0IsR0FBQUEsb0IiLCJmaWxlIjoidHJhbnNmb3Jtcy5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG5pbXBvcnQgU3dlZXRNb2R1bGUgZnJvbSAnLi9zd2VldC1tb2R1bGUnO1xuaW1wb3J0IFN5bnRheCBmcm9tICcuL3N5bnRheCc7XG5cbmV4cG9ydCBjbGFzcyBGdW5jdGlvbkRlY2xUcmFuc2Zvcm0ge31cbmV4cG9ydCBjbGFzcyBWYXJpYWJsZURlY2xUcmFuc2Zvcm0ge31cbmV4cG9ydCBjbGFzcyBOZXdUcmFuc2Zvcm0ge31cbmV4cG9ydCBjbGFzcyBUaHJvd1RyYW5zZm9ybSB7fVxuZXhwb3J0IGNsYXNzIExldERlY2xUcmFuc2Zvcm0ge31cbmV4cG9ydCBjbGFzcyBDb25zdERlY2xUcmFuc2Zvcm0ge31cbmV4cG9ydCBjbGFzcyBUcnlUcmFuc2Zvcm0ge31cbmV4cG9ydCBjbGFzcyBXaGlsZVRyYW5zZm9ybSB7fVxuZXhwb3J0IGNsYXNzIElmVHJhbnNmb3JtIHt9XG5leHBvcnQgY2xhc3MgRm9yVHJhbnNmb3JtIHt9XG5leHBvcnQgY2xhc3MgU3dpdGNoVHJhbnNmb3JtIHt9XG5leHBvcnQgY2xhc3MgQnJlYWtUcmFuc2Zvcm0ge31cbmV4cG9ydCBjbGFzcyBDb250aW51ZVRyYW5zZm9ybSB7fVxuZXhwb3J0IGNsYXNzIERvVHJhbnNmb3JtIHt9XG5leHBvcnQgY2xhc3MgV2l0aFRyYW5zZm9ybSB7fVxuZXhwb3J0IGNsYXNzIEltcG9ydFRyYW5zZm9ybSB7fVxuZXhwb3J0IGNsYXNzIEV4cG9ydFRyYW5zZm9ybSB7fVxuZXhwb3J0IGNsYXNzIFN1cGVyVHJhbnNmb3JtIHt9XG5leHBvcnQgY2xhc3MgWWllbGRUcmFuc2Zvcm0ge31cbmV4cG9ydCBjbGFzcyBUaGlzVHJhbnNmb3JtIHt9XG5leHBvcnQgY2xhc3MgQ2xhc3NUcmFuc2Zvcm0ge31cbmV4cG9ydCBjbGFzcyBEZWZhdWx0VHJhbnNmb3JtIHt9XG5leHBvcnQgY2xhc3MgRGVidWdnZXJUcmFuc2Zvcm0ge31cbmV4cG9ydCBjbGFzcyBTeW50YXhyZWNEZWNsVHJhbnNmb3JtIHt9XG5leHBvcnQgY2xhc3MgU3ludGF4RGVjbFRyYW5zZm9ybSB7fVxuZXhwb3J0IGNsYXNzIE9wZXJhdG9yRGVjbFRyYW5zZm9ybSB7fVxuZXhwb3J0IGNsYXNzIFJldHVyblN0YXRlbWVudFRyYW5zZm9ybSB7fVxuZXhwb3J0IGNsYXNzIE1vZHVsZU5hbWVzcGFjZVRyYW5zZm9ybSB7XG4gIG5hbWVzcGFjZTogU3ludGF4O1xuICBtb2Q6IFN3ZWV0TW9kdWxlO1xuXG4gIGNvbnN0cnVjdG9yKG5hbWVzcGFjZTogU3ludGF4LCBtb2Q6IFN3ZWV0TW9kdWxlKSB7XG4gICAgdGhpcy5uYW1lc3BhY2UgPSBuYW1lc3BhY2U7XG4gICAgdGhpcy5tb2QgPSBtb2Q7XG4gIH1cbn1cbmV4cG9ydCBjbGFzcyBWYXJCaW5kaW5nVHJhbnNmb3JtIHtcbiAgaWQ6IFN5bnRheDtcblxuICBjb25zdHJ1Y3RvcihpZDogU3ludGF4KSB7XG4gICAgdGhpcy5pZCA9IGlkO1xuICB9XG59XG5leHBvcnQgY2xhc3MgQ29tcGlsZXRpbWVUcmFuc2Zvcm0ge1xuICB2YWx1ZTogYW55O1xuXG4gIGNvbnN0cnVjdG9yKHZhbHVlOiBhbnkpIHtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gIH1cbn1cbiJdfQ==\n\n/***/ },\n/* 42 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\n\tvar _sweetSpec = __webpack_require__(43);\n\n\tvar T = _interopRequireWildcard(_sweetSpec);\n\n\tvar _ramda = __webpack_require__(20);\n\n\tvar _ = _interopRequireWildcard(_ramda);\n\n\tvar _sweetSpecUtils = __webpack_require__(44);\n\n\tvar S = _interopRequireWildcard(_sweetSpecUtils);\n\n\tvar _codegen = __webpack_require__(45);\n\n\tvar _codegen2 = _interopRequireDefault(_codegen);\n\n\tvar _immutable = __webpack_require__(12);\n\n\tvar _sweetToShiftReducer = __webpack_require__(56);\n\n\tvar _sweetToShiftReducer2 = _interopRequireDefault(_sweetToShiftReducer);\n\n\tvar _syntax = __webpack_require__(58);\n\n\tvar _syntax2 = _interopRequireDefault(_syntax);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\n\tconst extractDeclaration = _.cond([[S.isExport, _.prop('declaration')], [S.isExportDefault, _.prop('body')], [_.T, term => {\n\t  throw new Error(`Expecting an Export or ExportDefault but got ${ term }`);\n\t}]]);\n\n\n\tconst ExpSpec = x => ({ exportedName: x });\n\n\tconst extractDeclarationNames = _.cond([[S.isVariableDeclarator, ({ binding }) => _immutable.List.of(ExpSpec(binding.name))], [S.isVariableDeclaration, ({ declarators }) => declarators.flatMap(extractDeclarationNames)], [S.isFunctionDeclaration, ({ name }) => _immutable.List.of(ExpSpec(name.name))], [S.isClassDeclaration, ({ name }) => _immutable.List.of(ExpSpec(name.name))]]);\n\n\tfunction extractNames(term) {\n\t  if (S.isExport(term)) {\n\t    return extractDeclarationNames(term.declaration);\n\t  } else if (S.isExportDefault(term)) {\n\t    return (0, _immutable.List)();\n\t  } else if (S.isExportFrom(term)) {\n\t    return term.namedExports;\n\t  }\n\t  throw new Error(`Unknown export type`);\n\t}\n\n\tfunction wrapStatement(declaration) {\n\t  if (S.isVariableDeclaration(declaration)) {\n\t    return new T.VariableDeclarationStatement({ declaration });\n\t  }\n\t  return declaration;\n\t}\n\n\tconst memoSym = Symbol('memo');\n\n\tfunction makeVarDeclStmt(name, expr) {\n\t  return new T.VariableDeclarationStatement({\n\t    declaration: new T.VariableDeclaration({\n\t      kind: 'var',\n\t      declarators: _immutable.List.of(new T.VariableDeclarator({\n\t        binding: name,\n\t        init: expr\n\t      }))\n\t    })\n\t  });\n\t}\n\n\tclass SweetModule {\n\n\t  constructor(items) {\n\t    let body = [];\n\t    let imports = [];\n\t    let exports = [];\n\t    this.exportedNames = (0, _immutable.List)();\n\t    for (let item of items) {\n\t      if (S.isImportDeclaration(item)) {\n\t        imports.push(item);\n\t      } else if (S.isExportDeclaration(item)) {\n\t        exports.push(item);\n\t        this.exportedNames = this.exportedNames.concat(extractNames(item));\n\t        if (S.isExport(item)) {\n\t          body.push(wrapStatement(extractDeclaration(item)));\n\t        } else if (S.isExportDefault(item)) {\n\t          let decl = extractDeclaration(item);\n\t          let defStx = _syntax2.default.fromIdentifier('_default');\n\t          let def = new T.BindingIdentifier({\n\t            name: defStx\n\t          });\n\t          this.exportedNames = this.exportedNames.push(ExpSpec(defStx));\n\t          if (S.isFunctionDeclaration(decl) || S.isClassDeclaration(decl)) {\n\t            body.push(decl);\n\t            // extract name and bind it to _default\n\t            body.push(makeVarDeclStmt(def, new T.IdentifierExpression({ name: decl.name.name })));\n\t          } else {\n\t            // expression so bind it to _default\n\t            body.push(makeVarDeclStmt(def, decl));\n\t          }\n\t        }\n\t      } else {\n\t        body.push(item);\n\t      }\n\t    }\n\t    this.items = (0, _immutable.List)(body);\n\t    this.imports = (0, _immutable.List)(imports);\n\t    this.exports = (0, _immutable.List)(exports);\n\t  }\n\n\t  // $FlowFixMe: flow doesn't support computed property keys yet\n\t  [memoSym]() {\n\t    let runtime = [],\n\t        compiletime = [];\n\t    for (let item of this.items) {\n\t      if (S.isCompiletimeStatement(item)) {\n\t        compiletime.push(item);\n\t      } else {\n\t        runtime.push(item);\n\t      }\n\t    }\n\t    this.runtime = (0, _immutable.List)(runtime);\n\t    this.compiletime = (0, _immutable.List)(compiletime);\n\t  }\n\n\t  runtimeItems() {\n\t    if (this.runtime == null) {\n\t      // $FlowFixMe: flow doesn't support computed property keys yet\n\t      this[memoSym]();\n\t    }\n\t    return this.runtime;\n\t  }\n\n\t  compiletimeItems() {\n\t    if (this.compiletime == null) {\n\t      // $FlowFixMe: flow doesn't support computed property keys yet\n\t      this[memoSym]();\n\t    }\n\t    return this.compiletime;\n\t  }\n\n\t  parse() {\n\t    return new T.Module({\n\t      items: this.items,\n\t      directives: (0, _immutable.List)()\n\t    }).reduce(new _sweetToShiftReducer2.default(0));\n\t  }\n\n\t  codegen() {\n\t    return (0, _codegen2.default)(this.parse()).code;\n\t  }\n\t}\n\texports.default = SweetModule;\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zd2VldC1tb2R1bGUuanMiXSwibmFtZXMiOlsiVCIsIl8iLCJTIiwiZXh0cmFjdERlY2xhcmF0aW9uIiwiY29uZCIsImlzRXhwb3J0IiwicHJvcCIsImlzRXhwb3J0RGVmYXVsdCIsInRlcm0iLCJFcnJvciIsIkV4cFNwZWMiLCJ4IiwiZXhwb3J0ZWROYW1lIiwiZXh0cmFjdERlY2xhcmF0aW9uTmFtZXMiLCJpc1ZhcmlhYmxlRGVjbGFyYXRvciIsImJpbmRpbmciLCJvZiIsIm5hbWUiLCJpc1ZhcmlhYmxlRGVjbGFyYXRpb24iLCJkZWNsYXJhdG9ycyIsImZsYXRNYXAiLCJpc0Z1bmN0aW9uRGVjbGFyYXRpb24iLCJpc0NsYXNzRGVjbGFyYXRpb24iLCJleHRyYWN0TmFtZXMiLCJkZWNsYXJhdGlvbiIsImlzRXhwb3J0RnJvbSIsIm5hbWVkRXhwb3J0cyIsIndyYXBTdGF0ZW1lbnQiLCJWYXJpYWJsZURlY2xhcmF0aW9uU3RhdGVtZW50IiwibWVtb1N5bSIsIlN5bWJvbCIsIm1ha2VWYXJEZWNsU3RtdCIsImV4cHIiLCJWYXJpYWJsZURlY2xhcmF0aW9uIiwia2luZCIsIlZhcmlhYmxlRGVjbGFyYXRvciIsImluaXQiLCJTd2VldE1vZHVsZSIsImNvbnN0cnVjdG9yIiwiaXRlbXMiLCJib2R5IiwiaW1wb3J0cyIsImV4cG9ydHMiLCJleHBvcnRlZE5hbWVzIiwiaXRlbSIsImlzSW1wb3J0RGVjbGFyYXRpb24iLCJwdXNoIiwiaXNFeHBvcnREZWNsYXJhdGlvbiIsImNvbmNhdCIsImRlY2wiLCJkZWZTdHgiLCJmcm9tSWRlbnRpZmllciIsImRlZiIsIkJpbmRpbmdJZGVudGlmaWVyIiwiSWRlbnRpZmllckV4cHJlc3Npb24iLCJydW50aW1lIiwiY29tcGlsZXRpbWUiLCJpc0NvbXBpbGV0aW1lU3RhdGVtZW50IiwicnVudGltZUl0ZW1zIiwiY29tcGlsZXRpbWVJdGVtcyIsInBhcnNlIiwiTW9kdWxlIiwiZGlyZWN0aXZlcyIsInJlZHVj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QUFDRDs7QUFFREksVUFBUTtBQUNOLFdBQU8sSUFBSTVELEVBQUU2RCxNQUFOLENBQWE7QUFDbEJ0QixhQUFPLEtBQUtBLEtBRE07QUFFbEJ1QixrQkFBWTtBQUZNLEtBQWIsRUFHSkMsTUFISSxDQUdHLGtDQUF3QixDQUF4QixDQUhILENBQVA7QUFJRDs7QUFFREMsWUFBVTtBQUNSLFdBQU8sdUJBQVEsS0FBS0osS0FBTCxFQUFSLEVBQXNCSyxJQUE3QjtBQUNEO0FBM0Y4QjtrQkFBWjVCLFciLCJmaWxlIjoic3dlZXQtbW9kdWxlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbmltcG9ydCAqIGFzIFQgZnJvbSAnc3dlZXQtc3BlYyc7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ3JhbWRhJztcbmltcG9ydCAqIGFzIFMgZnJvbSAnLi9zd2VldC1zcGVjLXV0aWxzJztcbmltcG9ydCBjb2RlZ2VuIGZyb20gJy4vY29kZWdlbic7XG5pbXBvcnQgeyBMaXN0IH0gZnJvbSAnaW1tdXRhYmxlJztcbmltcG9ydCBTd2VldFRvU2hpZnRSZWR1Y2VyIGZyb20gJy4vc3dlZXQtdG8tc2hpZnQtcmVkdWNlci5qcyc7XG5pbXBvcnQgU3ludGF4IGZyb20gJy4vc3ludGF4JztcblxuY29uc3QgZXh0cmFjdERlY2xhcmF0aW9uID0gXy5jb25kKFtcbiAgW1MuaXNFeHBvcnQsIF8ucHJvcCgnZGVjbGFyYXRpb24nKV0sXG4gIFtTLmlzRXhwb3J0RGVmYXVsdCwgXy5wcm9wKCdib2R5JyldLFxuICBbXG4gICAgXy5ULFxuICAgIHRlcm0gPT4ge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RpbmcgYW4gRXhwb3J0IG9yIEV4cG9ydERlZmF1bHQgYnV0IGdvdCAke3Rlcm19YCk7XG4gICAgfSxcbiAgXSxcbl0pO1xuXG5jb25zdCBFeHBTcGVjID0geCA9PiAoeyBleHBvcnRlZE5hbWU6IHggfSk7XG5cbmNvbnN0IGV4dHJhY3REZWNsYXJhdGlvbk5hbWVzID0gXy5jb25kKFtcbiAgW1MuaXNWYXJpYWJsZURlY2xhcmF0b3IsICh7IGJpbmRpbmcgfSkgPT4gTGlzdC5vZihFeHBTcGVjKGJpbmRpbmcubmFtZSkpXSxcbiAgW1xuICAgIFMuaXNWYXJpYWJsZURlY2xhcmF0aW9uLFxuICAgICh7IGRlY2xhcmF0b3JzIH0pID0+IGRlY2xhcmF0b3JzLmZsYXRNYXAoZXh0cmFjdERlY2xhcmF0aW9uTmFtZXMpLFxuICBdLFxuICBbUy5pc0Z1bmN0aW9uRGVjbGFyYXRpb24sICh7IG5hbWUgfSkgPT4gTGlzdC5vZihFeHBTcGVjKG5hbWUubmFtZSkpXSxcbiAgW1MuaXNDbGFzc0RlY2xhcmF0aW9uLCAoeyBuYW1lIH0pID0+IExpc3Qub2YoRXhwU3BlYyhuYW1lLm5hbWUpKV0sXG5dKTtcblxudHlwZSBFeHBvcnRTcGVjaWZpZXIgPSB7XG4gIG5hbWU/OiBTeW50YXgsXG4gIGV4cG9ydGVkTmFtZTogU3ludGF4LFxufTtcblxuZnVuY3Rpb24gZXh0cmFjdE5hbWVzKHRlcm06IFQuRXhwb3J0RGVjbGFyYXRpb24pOiBMaXN0PEV4cG9ydFNwZWNpZmllcj4ge1xuICBpZiAoUy5pc0V4cG9ydCh0ZXJtKSkge1xuICAgIHJldHVybiBleHRyYWN0RGVjbGFyYXRpb25OYW1lcyh0ZXJtLmRlY2xhcmF0aW9uKTtcbiAgfSBlbHNlIGlmIChTLmlzRXhwb3J0RGVmYXVsdCh0ZXJtKSkge1xuICAgIHJldHVybiBMaXN0KCk7XG4gIH0gZWxzZSBpZiAoUy5pc0V4cG9ydEZyb20odGVybSkpIHtcbiAgICByZXR1cm4gdGVybS5uYW1lZEV4cG9ydHM7XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGV4cG9ydCB0eXBlYCk7XG59XG5cbmZ1bmN0aW9uIHdyYXBTdGF0ZW1lbnQoZGVjbGFyYXRpb246IFQuVGVybSkge1xuICBpZiAoUy5pc1ZhcmlhYmxlRGVjbGFyYXRpb24oZGVjbGFyYXRpb24pKSB7XG4gICAgcmV0dXJuIG5ldyBULlZhcmlhYmxlRGVjbGFyYXRpb25TdGF0ZW1lbnQoeyBkZWNsYXJhdGlvbiB9KTtcbiAgfVxuICByZXR1cm4gZGVjbGFyYXRpb247XG59XG5cbmNvbnN0IG1lbW9TeW0gPSBTeW1ib2woJ21lbW8nKTtcblxuZnVuY3Rpb24gbWFrZVZhckRlY2xTdG10KG5hbWU6IFQuQmluZGluZ0lkZW50aWZpZXIsIGV4cHI6IFQuRXhwcmVzc2lvbikge1xuICByZXR1cm4gbmV3IFQuVmFyaWFibGVEZWNsYXJhdGlvblN0YXRlbWVudCh7XG4gICAgZGVjbGFyYXRpb246IG5ldyBULlZhcmlhYmxlRGVjbGFyYXRpb24oe1xuICAgICAga2luZDogJ3ZhcicsXG4gICAgICBkZWNsYXJhdG9yczogTGlzdC5vZihcbiAgICAgICAgbmV3IFQuVmFyaWFibGVEZWNsYXJhdG9yKHtcbiAgICAgICAgICBiaW5kaW5nOiBuYW1lLFxuICAgICAgICAgIGluaXQ6IGV4cHIsXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICB9KSxcbiAgfSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFN3ZWV0TW9kdWxlIHtcbiAgaXRlbXM6IExpc3Q8VC5UZXJtPjtcbiAgaW1wb3J0czogTGlzdDxULkltcG9ydERlY2xhcmF0aW9uPjtcbiAgZXhwb3J0czogTGlzdDxULkV4cG9ydERlY2xhcmF0aW9uPjtcbiAgZXhwb3J0ZWROYW1lczogTGlzdDxFeHBvcnRTcGVjaWZpZXI+O1xuXG4gIHJ1bnRpbWU6IExpc3Q8VC5UZXJtPjtcbiAgY29tcGlsZXRpbWU6IExpc3Q8VC5UZXJtPjtcblxuICBjb25zdHJ1Y3RvcihpdGVtczogTGlzdDxULlRlcm0+KSB7XG4gICAgbGV0IGJvZHkgPSBbXTtcbiAgICBsZXQgaW1wb3J0cyA9IFtdO1xuICAgIGxldCBleHBvcnRzID0gW107XG4gICAgdGhpcy5leHBvcnRlZE5hbWVzID0gTGlzdCgpO1xuICAgIGZvciAobGV0IGl0ZW0gb2YgaXRlbXMpIHtcbiAgICAgIGlmIChTLmlzSW1wb3J0RGVjbGFyYXRpb24oaXRlbSkpIHtcbiAgICAgICAgaW1wb3J0cy5wdXNoKGl0ZW0pO1xuICAgICAgfSBlbHNlIGlmIChTLmlzRXhwb3J0RGVjbGFyYXRpb24oaXRlbSkpIHtcbiAgICAgICAgZXhwb3J0cy5wdXNoKGl0ZW0pO1xuICAgICAgICB0aGlzLmV4cG9ydGVkTmFtZXMgPSB0aGlzLmV4cG9ydGVkTmFtZXMuY29uY2F0KGV4dHJhY3ROYW1lcyhpdGVtKSk7XG4gICAgICAgIGlmIChTLmlzRXhwb3J0KGl0ZW0pKSB7XG4gICAgICAgICAgYm9keS5wdXNoKHdyYXBTdGF0ZW1lbnQoZXh0cmFjdERlY2xhcmF0aW9uKGl0ZW0pKSk7XG4gICAgICAgIH0gZWxzZSBpZiAoUy5pc0V4cG9ydERlZmF1bHQoaXRlbSkpIHtcbiAgICAgICAgICBsZXQgZGVjbCA9IGV4dHJhY3REZWNsYXJhdGlvbihpdGVtKTtcbiAgICAgICAgICBsZXQgZGVmU3R4ID0gU3ludGF4LmZyb21JZGVudGlmaWVyKCdfZGVmYXVsdCcpO1xuICAgICAgICAgIGxldCBkZWYgPSBuZXcgVC5CaW5kaW5nSWRlbnRpZmllcih7XG4gICAgICAgICAgICBuYW1lOiBkZWZTdHgsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhpcy5leHBvcnRlZE5hbWVzID0gdGhpcy5leHBvcnRlZE5hbWVzLnB1c2goRXhwU3BlYyhkZWZTdHgpKTtcbiAgICAgICAgICBpZiAoUy5pc0Z1bmN0aW9uRGVjbGFyYXRpb24oZGVjbCkgfHwgUy5pc0NsYXNzRGVjbGFyYXRpb24oZGVjbCkpIHtcbiAgICAgICAgICAgIGJvZHkucHVzaChkZWNsKTtcbiAgICAgICAgICAgIC8vIGV4dHJhY3QgbmFtZSBhbmQgYmluZCBpdCB0byBfZGVmYXVsdFxuICAgICAgICAgICAgYm9keS5wdXNoKFxuICAgICAgICAgICAgICBtYWtlVmFyRGVjbFN0bXQoXG4gICAgICAgICAgICAgICAgZGVmLFxuICAgICAgICAgICAgICAgIG5ldyBULklkZW50aWZpZXJFeHByZXNzaW9uKHsgbmFtZTogZGVjbC5uYW1lLm5hbWUgfSksXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBleHByZXNzaW9uIHNvIGJpbmQgaXQgdG8gX2RlZmF1bHRcbiAgICAgICAgICAgIGJvZHkucHVzaChtYWtlVmFyRGVjbFN0bXQoZGVmLCBkZWNsKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBib2R5LnB1c2goaXRlbSk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuaXRlbXMgPSBMaXN0KGJvZHkpO1xuICAgIHRoaXMuaW1wb3J0cyA9IExpc3QoaW1wb3J0cyk7XG4gICAgdGhpcy5leHBvcnRzID0gTGlzdChleHBvcnRzKTtcbiAgfVxuXG4gIC8vICRGbG93Rml4TWU6IGZsb3cgZG9lc24ndCBzdXBwb3J0IGNvbXB1dGVkIHByb3BlcnR5IGtleXMgeWV0XG4gIFttZW1vU3ltXSgpIHtcbiAgICBsZXQgcnVudGltZSA9IFtdLCBjb21waWxldGltZSA9IFtdO1xuICAgIGZvciAobGV0IGl0ZW0gb2YgdGhpcy5pdGVtcykge1xuICAgICAgaWYgKFMuaXNDb21waWxldGltZVN0YXRlbWVudChpdGVtKSkge1xuICAgICAgICBjb21waWxldGltZS5wdXNoKGl0ZW0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcnVudGltZS5wdXNoKGl0ZW0pO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnJ1bnRpbWUgPSBMaXN0KHJ1bnRpbWUpO1xuICAgIHRoaXMuY29tcGlsZXRpbWUgPSBMaXN0KGNvbXBpbGV0aW1lKTtcbiAgfVxuXG4gIHJ1bnRpbWVJdGVtcygpIHtcbiAgICBpZiAodGhpcy5ydW50aW1lID09IG51bGwpIHtcbiAgICAgIC8vICRGbG93Rml4TWU6IGZsb3cgZG9lc24ndCBzdXBwb3J0IGNvbXB1dGVkIHByb3BlcnR5IGtleXMgeWV0XG4gICAgICB0aGlzW21lbW9TeW1dKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnJ1bnRpbWU7XG4gIH1cblxuICBjb21waWxldGltZUl0ZW1zKCkge1xuICAgIGlmICh0aGlzLmNvbXBpbGV0aW1lID09IG51bGwpIHtcbiAgICAgIC8vICRGbG93Rml4TWU6IGZsb3cgZG9lc24ndCBzdXBwb3J0IGNvbXB1dGVkIHByb3BlcnR5IGtleXMgeWV0XG4gICAgICB0aGlzW21lbW9TeW1dKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNvbXBpbGV0aW1lO1xuICB9XG5cbiAgcGFyc2UoKSB7XG4gICAgcmV0dXJuIG5ldyBULk1vZHVsZSh7XG4gICAgICBpdGVtczogdGhpcy5pdGVtcyxcbiAgICAgIGRpcmVjdGl2ZXM6IExpc3QoKSxcbiAgICB9KS5yZWR1Y2UobmV3IFN3ZWV0VG9TaGlmdFJlZHVjZXIoMCkpO1xuICB9XG5cbiAgY29kZWdlbigpIHtcbiAgICByZXR1cm4gY29kZWdlbih0aGlzLnBhcnNlKCkpLmNvZGU7XG4gIH1cbn1cbiJdfQ==\n\n/***/ },\n/* 43 */\n/***/ function(module, exports) {\n\n\t\"use strict\";\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\tclass Term {\n\t  constructor(attrs_63, type_64) {\n\t    Object.assign(this, attrs_63);\n\t    this.type = type_64 || \"Term\";\n\t    this.loc = null;\n\t    Object.freeze(this);\n\t  }\n\t  _reduceState(reducer_65, state_66 = {}) {\n\t    return state_66;\n\t  }\n\t  _cloneAttrs() {\n\t    return {};\n\t  }\n\t  reduce(reducer_67) {\n\t    let state_68 = this._reduceState(reducer_67);\n\t    return reducer_67.reduceTerm(this, state_68);\n\t  }\n\t  extend(attrs_69) {\n\t    return new Term(Object.assign(this._cloneAttrs(), attrs_69));\n\t  }\n\t  from(type_70, value_71) {\n\t    if (this.value && typeof this.value.from === \"function\") {\n\t      return this.value.from(type_70, value_71);\n\t    }\n\t    throw new Error(\"Not implemented yet\");\n\t  }\n\t  fromNull() {\n\t    return this.from(\"null\", null);\n\t  }\n\t  fromNumber(value_72) {\n\t    return this.from(\"number\", value_72);\n\t  }\n\t  fromString(value_73) {\n\t    return this.from(\"string\", value_73);\n\t  }\n\t  fromPunctuator(value_74) {\n\t    return this.from(\"punctuator\", value_74);\n\t  }\n\t  fromKeyword(value_75) {\n\t    return this.from(\"keyword\", value_75);\n\t  }\n\t  fromIdentifier(value_76) {\n\t    return this.from(\"identifier\", value_76);\n\t  }\n\t  fromRegularExpression(value_77) {\n\t    return this.from(\"regularExpression\", value_77);\n\t  }\n\t  fromBraces(inner_78) {\n\t    return this.from(\"braces\", inner_78);\n\t  }\n\t  fromBrackets(inner_79) {\n\t    return this.from(\"brackets\", inner_79);\n\t  }\n\t  fromParens(inner_80) {\n\t    return this.from(\"parens\", inner_80);\n\t  }\n\t}\n\tTerm.CloneReducer = class {\n\t  reduceTerm(term_81, state_82) {\n\t    return new Term(state_82);\n\t  }\n\t};\n\texports.default = Term;\n\n\tclass SyntaxTerm extends Term {\n\t  constructor(attrs_83, type_84) {\n\t    super(attrs_83, type_84 || \"SyntaxTerm\");\n\t  }\n\t  _reduceState(reducer_85, state_86 = {}) {\n\t    ;\n\t    return super._reduceState(reducer_85, state_86);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({}, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_87) {\n\t    let state_88 = this._reduceState(reducer_87);\n\t    return reducer_87.reduceSyntaxTerm(this, state_88);\n\t  }\n\t  extend(attrs_89) {\n\t    return new SyntaxTerm(Object.assign(this._cloneAttrs(), attrs_89));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceSyntaxTerm = function (term_90, state_91) {\n\t  return new SyntaxTerm(state_91);\n\t};\n\texports.SyntaxTerm = SyntaxTerm;\n\n\tclass RawDelimiter extends SyntaxTerm {\n\t  constructor(attrs_92, type_93) {\n\t    super(attrs_92, type_93 || \"RawDelimiter\");\n\t    if (!{}.hasOwnProperty.call(attrs_92, \"kind\")) {\n\t      throw new Error(\"Missing attribute: \" + \"kind\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_92, \"inner\")) {\n\t      throw new Error(\"Missing attribute: \" + \"inner\");\n\t    }\n\t  }\n\t  _reduceState(reducer_94, state_95 = {}) {\n\t    state_95.kind = this.kind;\n\t    state_95.inner = this.inner.map(a_96 => a_96 instanceof Term ? a_96.reduce(reducer_94) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_96));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_94, state_95);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ kind: this.kind, inner: this.inner }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_97) {\n\t    let state_98 = this._reduceState(reducer_97);\n\t    return reducer_97.reduceRawDelimiter(this, state_98);\n\t  }\n\t  extend(attrs_99) {\n\t    return new RawDelimiter(Object.assign(this._cloneAttrs(), attrs_99));\n\t  }\n\t}\n\tSyntaxTerm.CloneReducer.prototype.reduceRawDelimiter = function (term_100, state_101) {\n\t  return new RawDelimiter(state_101);\n\t};\n\texports.RawDelimiter = RawDelimiter;\n\n\tclass RawSyntax extends SyntaxTerm {\n\t  constructor(attrs_102, type_103) {\n\t    super(attrs_102, type_103 || \"RawSyntax\");\n\t    if (!{}.hasOwnProperty.call(attrs_102, \"value\")) {\n\t      throw new Error(\"Missing attribute: \" + \"value\");\n\t    }\n\t  }\n\t  _reduceState(reducer_104, state_105 = {}) {\n\t    state_105.value = this.value;\n\t    ;\n\t    return super._reduceState(reducer_104, state_105);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ value: this.value }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_106) {\n\t    let state_107 = this._reduceState(reducer_106);\n\t    return reducer_106.reduceRawSyntax(this, state_107);\n\t  }\n\t  extend(attrs_108) {\n\t    return new RawSyntax(Object.assign(this._cloneAttrs(), attrs_108));\n\t  }\n\t}\n\tSyntaxTerm.CloneReducer.prototype.reduceRawSyntax = function (term_109, state_110) {\n\t  return new RawSyntax(state_110);\n\t};\n\texports.RawSyntax = RawSyntax;\n\n\tclass Statement extends Term {\n\t  constructor(attrs_111, type_112) {\n\t    super(attrs_111, type_112 || \"Statement\");\n\t  }\n\t  _reduceState(reducer_113, state_114 = {}) {\n\t    ;\n\t    return super._reduceState(reducer_113, state_114);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({}, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_115) {\n\t    let state_116 = this._reduceState(reducer_115);\n\t    return reducer_115.reduceStatement(this, state_116);\n\t  }\n\t  extend(attrs_117) {\n\t    return new Statement(Object.assign(this._cloneAttrs(), attrs_117));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceStatement = function (term_118, state_119) {\n\t  return new Statement(state_119);\n\t};\n\texports.Statement = Statement;\n\n\tclass IterationStatement extends Statement {\n\t  constructor(attrs_120, type_121) {\n\t    super(attrs_120, type_121 || \"IterationStatement\");\n\t    if (!{}.hasOwnProperty.call(attrs_120, \"body\")) {\n\t      throw new Error(\"Missing attribute: \" + \"body\");\n\t    }\n\t  }\n\t  _reduceState(reducer_122, state_123 = {}) {\n\t    state_123.body = this.body instanceof Statement ? this.body.reduce(reducer_122) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.body));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_122, state_123);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ body: this.body }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_124) {\n\t    let state_125 = this._reduceState(reducer_124);\n\t    return reducer_124.reduceIterationStatement(this, state_125);\n\t  }\n\t  extend(attrs_126) {\n\t    return new IterationStatement(Object.assign(this._cloneAttrs(), attrs_126));\n\t  }\n\t}\n\tStatement.CloneReducer.prototype.reduceIterationStatement = function (term_127, state_128) {\n\t  return new IterationStatement(state_128);\n\t};\n\texports.IterationStatement = IterationStatement;\n\n\tclass Expression extends Term {\n\t  constructor(attrs_129, type_130) {\n\t    super(attrs_129, type_130 || \"Expression\");\n\t  }\n\t  _reduceState(reducer_131, state_132 = {}) {\n\t    ;\n\t    return super._reduceState(reducer_131, state_132);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({}, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_133) {\n\t    let state_134 = this._reduceState(reducer_133);\n\t    return reducer_133.reduceExpression(this, state_134);\n\t  }\n\t  extend(attrs_135) {\n\t    return new Expression(Object.assign(this._cloneAttrs(), attrs_135));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceExpression = function (term_136, state_137) {\n\t  return new Expression(state_137);\n\t};\n\texports.Expression = Expression;\n\n\tclass MemberExpression extends Expression {\n\t  constructor(attrs_138, type_139) {\n\t    super(attrs_138, type_139 || \"MemberExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_138, \"object\")) {\n\t      throw new Error(\"Missing attribute: \" + \"object\");\n\t    }\n\t  }\n\t  _reduceState(reducer_140, state_141 = {}) {\n\t    state_141.object = this.object instanceof Expression ? this.object.reduce(reducer_140) : this.object instanceof Super ? this.object.reduce(reducer_140) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.object));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_140, state_141);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ object: this.object }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_142) {\n\t    let state_143 = this._reduceState(reducer_142);\n\t    return reducer_142.reduceMemberExpression(this, state_143);\n\t  }\n\t  extend(attrs_144) {\n\t    return new MemberExpression(Object.assign(this._cloneAttrs(), attrs_144));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceMemberExpression = function (term_145, state_146) {\n\t  return new MemberExpression(state_146);\n\t};\n\texports.MemberExpression = MemberExpression;\n\n\tclass PropertyName extends Term {\n\t  constructor(attrs_147, type_148) {\n\t    super(attrs_147, type_148 || \"PropertyName\");\n\t  }\n\t  _reduceState(reducer_149, state_150 = {}) {\n\t    ;\n\t    return super._reduceState(reducer_149, state_150);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({}, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_151) {\n\t    let state_152 = this._reduceState(reducer_151);\n\t    return reducer_151.reducePropertyName(this, state_152);\n\t  }\n\t  extend(attrs_153) {\n\t    return new PropertyName(Object.assign(this._cloneAttrs(), attrs_153));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reducePropertyName = function (term_154, state_155) {\n\t  return new PropertyName(state_155);\n\t};\n\texports.PropertyName = PropertyName;\n\n\tclass ObjectProperty extends Term {\n\t  constructor(attrs_156, type_157) {\n\t    super(attrs_156, type_157 || \"ObjectProperty\");\n\t  }\n\t  _reduceState(reducer_158, state_159 = {}) {\n\t    ;\n\t    return super._reduceState(reducer_158, state_159);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({}, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_160) {\n\t    let state_161 = this._reduceState(reducer_160);\n\t    return reducer_160.reduceObjectProperty(this, state_161);\n\t  }\n\t  extend(attrs_162) {\n\t    return new ObjectProperty(Object.assign(this._cloneAttrs(), attrs_162));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceObjectProperty = function (term_163, state_164) {\n\t  return new ObjectProperty(state_164);\n\t};\n\texports.ObjectProperty = ObjectProperty;\n\n\tclass NamedObjectProperty extends ObjectProperty {\n\t  constructor(attrs_165, type_166) {\n\t    super(attrs_165, type_166 || \"NamedObjectProperty\");\n\t    if (!{}.hasOwnProperty.call(attrs_165, \"name\")) {\n\t      throw new Error(\"Missing attribute: \" + \"name\");\n\t    }\n\t  }\n\t  _reduceState(reducer_167, state_168 = {}) {\n\t    state_168.name = this.name instanceof PropertyName ? this.name.reduce(reducer_167) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.name));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_167, state_168);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ name: this.name }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_169) {\n\t    let state_170 = this._reduceState(reducer_169);\n\t    return reducer_169.reduceNamedObjectProperty(this, state_170);\n\t  }\n\t  extend(attrs_171) {\n\t    return new NamedObjectProperty(Object.assign(this._cloneAttrs(), attrs_171));\n\t  }\n\t}\n\tObjectProperty.CloneReducer.prototype.reduceNamedObjectProperty = function (term_172, state_173) {\n\t  return new NamedObjectProperty(state_173);\n\t};\n\texports.NamedObjectProperty = NamedObjectProperty;\n\n\tclass MethodDefinition extends NamedObjectProperty {\n\t  constructor(attrs_174, type_175) {\n\t    super(attrs_174, type_175 || \"MethodDefinition\");\n\t    if (!{}.hasOwnProperty.call(attrs_174, \"body\")) {\n\t      throw new Error(\"Missing attribute: \" + \"body\");\n\t    }\n\t  }\n\t  _reduceState(reducer_176, state_177 = {}) {\n\t    state_177.body = this.body instanceof FunctionBody ? this.body.reduce(reducer_176) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.body));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_176, state_177);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ body: this.body }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_178) {\n\t    let state_179 = this._reduceState(reducer_178);\n\t    return reducer_178.reduceMethodDefinition(this, state_179);\n\t  }\n\t  extend(attrs_180) {\n\t    return new MethodDefinition(Object.assign(this._cloneAttrs(), attrs_180));\n\t  }\n\t}\n\tNamedObjectProperty.CloneReducer.prototype.reduceMethodDefinition = function (term_181, state_182) {\n\t  return new MethodDefinition(state_182);\n\t};\n\texports.MethodDefinition = MethodDefinition;\n\n\tclass BindingWithDefault extends Term {\n\t  constructor(attrs_183, type_184) {\n\t    super(attrs_183, type_184 || \"BindingWithDefault\");\n\t    if (!{}.hasOwnProperty.call(attrs_183, \"binding\")) {\n\t      throw new Error(\"Missing attribute: \" + \"binding\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_183, \"init\")) {\n\t      throw new Error(\"Missing attribute: \" + \"init\");\n\t    }\n\t  }\n\t  _reduceState(reducer_185, state_186 = {}) {\n\t    state_186.binding = this.binding instanceof ObjectBinding ? this.binding.reduce(reducer_185) : this.binding instanceof ArrayBinding ? this.binding.reduce(reducer_185) : this.binding instanceof BindingIdentifier ? this.binding.reduce(reducer_185) : this.binding instanceof MemberExpression ? this.binding.reduce(reducer_185) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.binding));\n\t    }.call(this);\n\t    state_186.init = this.init instanceof Expression ? this.init.reduce(reducer_185) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.init));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_185, state_186);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ binding: this.binding, init: this.init }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_187) {\n\t    let state_188 = this._reduceState(reducer_187);\n\t    return reducer_187.reduceBindingWithDefault(this, state_188);\n\t  }\n\t  extend(attrs_189) {\n\t    return new BindingWithDefault(Object.assign(this._cloneAttrs(), attrs_189));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceBindingWithDefault = function (term_190, state_191) {\n\t  return new BindingWithDefault(state_191);\n\t};\n\texports.BindingWithDefault = BindingWithDefault;\n\n\tclass BindingIdentifier extends Term {\n\t  constructor(attrs_192, type_193) {\n\t    super(attrs_192, type_193 || \"BindingIdentifier\");\n\t    if (!{}.hasOwnProperty.call(attrs_192, \"name\")) {\n\t      throw new Error(\"Missing attribute: \" + \"name\");\n\t    }\n\t  }\n\t  _reduceState(reducer_194, state_195 = {}) {\n\t    state_195.name = this.name;\n\t    ;\n\t    return super._reduceState(reducer_194, state_195);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ name: this.name }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_196) {\n\t    let state_197 = this._reduceState(reducer_196);\n\t    return reducer_196.reduceBindingIdentifier(this, state_197);\n\t  }\n\t  extend(attrs_198) {\n\t    return new BindingIdentifier(Object.assign(this._cloneAttrs(), attrs_198));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceBindingIdentifier = function (term_199, state_200) {\n\t  return new BindingIdentifier(state_200);\n\t};\n\texports.BindingIdentifier = BindingIdentifier;\n\n\tclass ArrayBinding extends Term {\n\t  constructor(attrs_201, type_202) {\n\t    super(attrs_201, type_202 || \"ArrayBinding\");\n\t    if (!{}.hasOwnProperty.call(attrs_201, \"elements\")) {\n\t      throw new Error(\"Missing attribute: \" + \"elements\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_201, \"restElement\")) {\n\t      throw new Error(\"Missing attribute: \" + \"restElement\");\n\t    }\n\t  }\n\t  _reduceState(reducer_203, state_204 = {}) {\n\t    state_204.elements = this.elements.map(a_205 => a_205 instanceof ObjectBinding ? a_205.reduce(reducer_203) : a_205 instanceof ArrayBinding ? a_205.reduce(reducer_203) : a_205 instanceof BindingIdentifier ? a_205.reduce(reducer_203) : a_205 instanceof MemberExpression ? a_205.reduce(reducer_203) : a_205 instanceof BindingWithDefault ? a_205.reduce(reducer_203) : a_205 == null ? null : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_205));\n\t    }.call(this));\n\t    state_204.restElement = this.restElement == null ? null : this.restElement instanceof ObjectBinding ? this.restElement.reduce(reducer_203) : this.restElement instanceof ArrayBinding ? this.restElement.reduce(reducer_203) : this.restElement instanceof BindingIdentifier ? this.restElement.reduce(reducer_203) : this.restElement instanceof MemberExpression ? this.restElement.reduce(reducer_203) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.restElement));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_203, state_204);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ elements: this.elements, restElement: this.restElement }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_206) {\n\t    let state_207 = this._reduceState(reducer_206);\n\t    return reducer_206.reduceArrayBinding(this, state_207);\n\t  }\n\t  extend(attrs_208) {\n\t    return new ArrayBinding(Object.assign(this._cloneAttrs(), attrs_208));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceArrayBinding = function (term_209, state_210) {\n\t  return new ArrayBinding(state_210);\n\t};\n\texports.ArrayBinding = ArrayBinding;\n\n\tclass ObjectBinding extends Term {\n\t  constructor(attrs_211, type_212) {\n\t    super(attrs_211, type_212 || \"ObjectBinding\");\n\t    if (!{}.hasOwnProperty.call(attrs_211, \"properties\")) {\n\t      throw new Error(\"Missing attribute: \" + \"properties\");\n\t    }\n\t  }\n\t  _reduceState(reducer_213, state_214 = {}) {\n\t    state_214.properties = this.properties.map(a_215 => a_215 instanceof BindingProperty ? a_215.reduce(reducer_213) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_215));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_213, state_214);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ properties: this.properties }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_216) {\n\t    let state_217 = this._reduceState(reducer_216);\n\t    return reducer_216.reduceObjectBinding(this, state_217);\n\t  }\n\t  extend(attrs_218) {\n\t    return new ObjectBinding(Object.assign(this._cloneAttrs(), attrs_218));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceObjectBinding = function (term_219, state_220) {\n\t  return new ObjectBinding(state_220);\n\t};\n\texports.ObjectBinding = ObjectBinding;\n\n\tclass BindingProperty extends Term {\n\t  constructor(attrs_221, type_222) {\n\t    super(attrs_221, type_222 || \"BindingProperty\");\n\t  }\n\t  _reduceState(reducer_223, state_224 = {}) {\n\t    ;\n\t    return super._reduceState(reducer_223, state_224);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({}, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_225) {\n\t    let state_226 = this._reduceState(reducer_225);\n\t    return reducer_225.reduceBindingProperty(this, state_226);\n\t  }\n\t  extend(attrs_227) {\n\t    return new BindingProperty(Object.assign(this._cloneAttrs(), attrs_227));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceBindingProperty = function (term_228, state_229) {\n\t  return new BindingProperty(state_229);\n\t};\n\texports.BindingProperty = BindingProperty;\n\n\tclass BindingPropertyIdentifier extends BindingProperty {\n\t  constructor(attrs_230, type_231) {\n\t    super(attrs_230, type_231 || \"BindingPropertyIdentifier\");\n\t    if (!{}.hasOwnProperty.call(attrs_230, \"binding\")) {\n\t      throw new Error(\"Missing attribute: \" + \"binding\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_230, \"init\")) {\n\t      throw new Error(\"Missing attribute: \" + \"init\");\n\t    }\n\t  }\n\t  _reduceState(reducer_232, state_233 = {}) {\n\t    state_233.binding = this.binding instanceof BindingIdentifier ? this.binding.reduce(reducer_232) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.binding));\n\t    }.call(this);\n\t    state_233.init = this.init == null ? null : this.init instanceof Expression ? this.init.reduce(reducer_232) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.init));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_232, state_233);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ binding: this.binding, init: this.init }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_234) {\n\t    let state_235 = this._reduceState(reducer_234);\n\t    return reducer_234.reduceBindingPropertyIdentifier(this, state_235);\n\t  }\n\t  extend(attrs_236) {\n\t    return new BindingPropertyIdentifier(Object.assign(this._cloneAttrs(), attrs_236));\n\t  }\n\t}\n\tBindingProperty.CloneReducer.prototype.reduceBindingPropertyIdentifier = function (term_237, state_238) {\n\t  return new BindingPropertyIdentifier(state_238);\n\t};\n\texports.BindingPropertyIdentifier = BindingPropertyIdentifier;\n\n\tclass BindingPropertyProperty extends BindingProperty {\n\t  constructor(attrs_239, type_240) {\n\t    super(attrs_239, type_240 || \"BindingPropertyProperty\");\n\t    if (!{}.hasOwnProperty.call(attrs_239, \"name\")) {\n\t      throw new Error(\"Missing attribute: \" + \"name\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_239, \"binding\")) {\n\t      throw new Error(\"Missing attribute: \" + \"binding\");\n\t    }\n\t  }\n\t  _reduceState(reducer_241, state_242 = {}) {\n\t    state_242.name = this.name instanceof PropertyName ? this.name.reduce(reducer_241) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.name));\n\t    }.call(this);\n\t    state_242.binding = this.binding instanceof ObjectBinding ? this.binding.reduce(reducer_241) : this.binding instanceof ArrayBinding ? this.binding.reduce(reducer_241) : this.binding instanceof BindingIdentifier ? this.binding.reduce(reducer_241) : this.binding instanceof MemberExpression ? this.binding.reduce(reducer_241) : this.binding instanceof BindingWithDefault ? this.binding.reduce(reducer_241) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.binding));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_241, state_242);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ name: this.name, binding: this.binding }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_243) {\n\t    let state_244 = this._reduceState(reducer_243);\n\t    return reducer_243.reduceBindingPropertyProperty(this, state_244);\n\t  }\n\t  extend(attrs_245) {\n\t    return new BindingPropertyProperty(Object.assign(this._cloneAttrs(), attrs_245));\n\t  }\n\t}\n\tBindingProperty.CloneReducer.prototype.reduceBindingPropertyProperty = function (term_246, state_247) {\n\t  return new BindingPropertyProperty(state_247);\n\t};\n\texports.BindingPropertyProperty = BindingPropertyProperty;\n\n\tclass ClassExpression extends Expression {\n\t  constructor(attrs_248, type_249) {\n\t    super(attrs_248, type_249 || \"ClassExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_248, \"name\")) {\n\t      throw new Error(\"Missing attribute: \" + \"name\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_248, \"super\")) {\n\t      throw new Error(\"Missing attribute: \" + \"super\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_248, \"elements\")) {\n\t      throw new Error(\"Missing attribute: \" + \"elements\");\n\t    }\n\t  }\n\t  _reduceState(reducer_250, state_251 = {}) {\n\t    state_251.name = this.name == null ? null : this.name instanceof BindingIdentifier ? this.name.reduce(reducer_250) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.name));\n\t    }.call(this);\n\t    state_251.super = this.super == null ? null : this.super instanceof Expression ? this.super.reduce(reducer_250) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.super));\n\t    }.call(this);\n\t    state_251.elements = this.elements.map(a_252 => a_252 instanceof ClassElement ? a_252.reduce(reducer_250) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_252));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_250, state_251);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ name: this.name, super: this.super, elements: this.elements }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_253) {\n\t    let state_254 = this._reduceState(reducer_253);\n\t    return reducer_253.reduceClassExpression(this, state_254);\n\t  }\n\t  extend(attrs_255) {\n\t    return new ClassExpression(Object.assign(this._cloneAttrs(), attrs_255));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceClassExpression = function (term_256, state_257) {\n\t  return new ClassExpression(state_257);\n\t};\n\texports.ClassExpression = ClassExpression;\n\n\tclass ClassDeclaration extends Statement {\n\t  constructor(attrs_258, type_259) {\n\t    super(attrs_258, type_259 || \"ClassDeclaration\");\n\t    if (!{}.hasOwnProperty.call(attrs_258, \"name\")) {\n\t      throw new Error(\"Missing attribute: \" + \"name\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_258, \"super\")) {\n\t      throw new Error(\"Missing attribute: \" + \"super\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_258, \"elements\")) {\n\t      throw new Error(\"Missing attribute: \" + \"elements\");\n\t    }\n\t  }\n\t  _reduceState(reducer_260, state_261 = {}) {\n\t    state_261.name = this.name instanceof BindingIdentifier ? this.name.reduce(reducer_260) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.name));\n\t    }.call(this);\n\t    state_261.super = this.super == null ? null : this.super instanceof Expression ? this.super.reduce(reducer_260) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.super));\n\t    }.call(this);\n\t    state_261.elements = this.elements.map(a_262 => a_262 instanceof ClassElement ? a_262.reduce(reducer_260) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_262));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_260, state_261);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ name: this.name, super: this.super, elements: this.elements }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_263) {\n\t    let state_264 = this._reduceState(reducer_263);\n\t    return reducer_263.reduceClassDeclaration(this, state_264);\n\t  }\n\t  extend(attrs_265) {\n\t    return new ClassDeclaration(Object.assign(this._cloneAttrs(), attrs_265));\n\t  }\n\t}\n\tStatement.CloneReducer.prototype.reduceClassDeclaration = function (term_266, state_267) {\n\t  return new ClassDeclaration(state_267);\n\t};\n\texports.ClassDeclaration = ClassDeclaration;\n\n\tclass ClassElement extends Term {\n\t  constructor(attrs_268, type_269) {\n\t    super(attrs_268, type_269 || \"ClassElement\");\n\t    if (!{}.hasOwnProperty.call(attrs_268, \"isStatic\")) {\n\t      throw new Error(\"Missing attribute: \" + \"isStatic\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_268, \"method\")) {\n\t      throw new Error(\"Missing attribute: \" + \"method\");\n\t    }\n\t  }\n\t  _reduceState(reducer_270, state_271 = {}) {\n\t    state_271.isStatic = this.isStatic;\n\t    state_271.method = this.method instanceof MethodDefinition ? this.method.reduce(reducer_270) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.method));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_270, state_271);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ isStatic: this.isStatic, method: this.method }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_272) {\n\t    let state_273 = this._reduceState(reducer_272);\n\t    return reducer_272.reduceClassElement(this, state_273);\n\t  }\n\t  extend(attrs_274) {\n\t    return new ClassElement(Object.assign(this._cloneAttrs(), attrs_274));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceClassElement = function (term_275, state_276) {\n\t  return new ClassElement(state_276);\n\t};\n\texports.ClassElement = ClassElement;\n\n\tclass Module extends Term {\n\t  constructor(attrs_277, type_278) {\n\t    super(attrs_277, type_278 || \"Module\");\n\t    if (!{}.hasOwnProperty.call(attrs_277, \"directives\")) {\n\t      throw new Error(\"Missing attribute: \" + \"directives\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_277, \"items\")) {\n\t      throw new Error(\"Missing attribute: \" + \"items\");\n\t    }\n\t  }\n\t  _reduceState(reducer_279, state_280 = {}) {\n\t    state_280.directives = this.directives.map(a_281 => a_281);\n\t    state_280.items = this.items.map(a_282 => a_282 instanceof Term ? a_282.reduce(reducer_279) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_282));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_279, state_280);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ directives: this.directives, items: this.items }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_283) {\n\t    let state_284 = this._reduceState(reducer_283);\n\t    return reducer_283.reduceModule(this, state_284);\n\t  }\n\t  extend(attrs_285) {\n\t    return new Module(Object.assign(this._cloneAttrs(), attrs_285));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceModule = function (term_286, state_287) {\n\t  return new Module(state_287);\n\t};\n\texports.Module = Module;\n\n\tclass ImportDeclaration extends Term {\n\t  constructor(attrs_288, type_289) {\n\t    super(attrs_288, type_289 || \"ImportDeclaration\");\n\t    if (!{}.hasOwnProperty.call(attrs_288, \"moduleSpecifier\")) {\n\t      throw new Error(\"Missing attribute: \" + \"moduleSpecifier\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_288, \"forSyntax\")) {\n\t      throw new Error(\"Missing attribute: \" + \"forSyntax\");\n\t    }\n\t  }\n\t  _reduceState(reducer_290, state_291 = {}) {\n\t    state_291.moduleSpecifier = this.moduleSpecifier;\n\t    state_291.forSyntax = this.forSyntax;\n\t    ;\n\t    return super._reduceState(reducer_290, state_291);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ moduleSpecifier: this.moduleSpecifier, forSyntax: this.forSyntax }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_292) {\n\t    let state_293 = this._reduceState(reducer_292);\n\t    return reducer_292.reduceImportDeclaration(this, state_293);\n\t  }\n\t  extend(attrs_294) {\n\t    return new ImportDeclaration(Object.assign(this._cloneAttrs(), attrs_294));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceImportDeclaration = function (term_295, state_296) {\n\t  return new ImportDeclaration(state_296);\n\t};\n\texports.ImportDeclaration = ImportDeclaration;\n\n\tclass ExportDeclaration extends Term {\n\t  constructor(attrs_297, type_298) {\n\t    super(attrs_297, type_298 || \"ExportDeclaration\");\n\t  }\n\t  _reduceState(reducer_299, state_300 = {}) {\n\t    ;\n\t    return super._reduceState(reducer_299, state_300);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({}, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_301) {\n\t    let state_302 = this._reduceState(reducer_301);\n\t    return reducer_301.reduceExportDeclaration(this, state_302);\n\t  }\n\t  extend(attrs_303) {\n\t    return new ExportDeclaration(Object.assign(this._cloneAttrs(), attrs_303));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceExportDeclaration = function (term_304, state_305) {\n\t  return new ExportDeclaration(state_305);\n\t};\n\texports.ExportDeclaration = ExportDeclaration;\n\n\tclass Import extends ImportDeclaration {\n\t  constructor(attrs_306, type_307) {\n\t    super(attrs_306, type_307 || \"Import\");\n\t    if (!{}.hasOwnProperty.call(attrs_306, \"defaultBinding\")) {\n\t      throw new Error(\"Missing attribute: \" + \"defaultBinding\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_306, \"namedImports\")) {\n\t      throw new Error(\"Missing attribute: \" + \"namedImports\");\n\t    }\n\t  }\n\t  _reduceState(reducer_308, state_309 = {}) {\n\t    state_309.defaultBinding = this.defaultBinding == null ? null : this.defaultBinding instanceof BindingIdentifier ? this.defaultBinding.reduce(reducer_308) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.defaultBinding));\n\t    }.call(this);\n\t    state_309.namedImports = this.namedImports.map(a_310 => a_310 instanceof ImportSpecifier ? a_310.reduce(reducer_308) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_310));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_308, state_309);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ defaultBinding: this.defaultBinding, namedImports: this.namedImports }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_311) {\n\t    let state_312 = this._reduceState(reducer_311);\n\t    return reducer_311.reduceImport(this, state_312);\n\t  }\n\t  extend(attrs_313) {\n\t    return new Import(Object.assign(this._cloneAttrs(), attrs_313));\n\t  }\n\t}\n\tImportDeclaration.CloneReducer.prototype.reduceImport = function (term_314, state_315) {\n\t  return new Import(state_315);\n\t};\n\texports.Import = Import;\n\n\tclass ImportNamespace extends ImportDeclaration {\n\t  constructor(attrs_316, type_317) {\n\t    super(attrs_316, type_317 || \"ImportNamespace\");\n\t    if (!{}.hasOwnProperty.call(attrs_316, \"defaultBinding\")) {\n\t      throw new Error(\"Missing attribute: \" + \"defaultBinding\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_316, \"namespaceBinding\")) {\n\t      throw new Error(\"Missing attribute: \" + \"namespaceBinding\");\n\t    }\n\t  }\n\t  _reduceState(reducer_318, state_319 = {}) {\n\t    state_319.defaultBinding = this.defaultBinding == null ? null : this.defaultBinding instanceof BindingIdentifier ? this.defaultBinding.reduce(reducer_318) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.defaultBinding));\n\t    }.call(this);\n\t    state_319.namespaceBinding = this.namespaceBinding instanceof BindingIdentifier ? this.namespaceBinding.reduce(reducer_318) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.namespaceBinding));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_318, state_319);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ defaultBinding: this.defaultBinding, namespaceBinding: this.namespaceBinding }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_320) {\n\t    let state_321 = this._reduceState(reducer_320);\n\t    return reducer_320.reduceImportNamespace(this, state_321);\n\t  }\n\t  extend(attrs_322) {\n\t    return new ImportNamespace(Object.assign(this._cloneAttrs(), attrs_322));\n\t  }\n\t}\n\tImportDeclaration.CloneReducer.prototype.reduceImportNamespace = function (term_323, state_324) {\n\t  return new ImportNamespace(state_324);\n\t};\n\texports.ImportNamespace = ImportNamespace;\n\n\tclass ImportSpecifier extends Term {\n\t  constructor(attrs_325, type_326) {\n\t    super(attrs_325, type_326 || \"ImportSpecifier\");\n\t    if (!{}.hasOwnProperty.call(attrs_325, \"name\")) {\n\t      throw new Error(\"Missing attribute: \" + \"name\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_325, \"binding\")) {\n\t      throw new Error(\"Missing attribute: \" + \"binding\");\n\t    }\n\t  }\n\t  _reduceState(reducer_327, state_328 = {}) {\n\t    state_328.name = this.name == null ? null : this.name;\n\t    state_328.binding = this.binding instanceof BindingIdentifier ? this.binding.reduce(reducer_327) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.binding));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_327, state_328);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ name: this.name, binding: this.binding }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_329) {\n\t    let state_330 = this._reduceState(reducer_329);\n\t    return reducer_329.reduceImportSpecifier(this, state_330);\n\t  }\n\t  extend(attrs_331) {\n\t    return new ImportSpecifier(Object.assign(this._cloneAttrs(), attrs_331));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceImportSpecifier = function (term_332, state_333) {\n\t  return new ImportSpecifier(state_333);\n\t};\n\texports.ImportSpecifier = ImportSpecifier;\n\n\tclass ExportAllFrom extends ExportDeclaration {\n\t  constructor(attrs_334, type_335) {\n\t    super(attrs_334, type_335 || \"ExportAllFrom\");\n\t    if (!{}.hasOwnProperty.call(attrs_334, \"moduleSpecifier\")) {\n\t      throw new Error(\"Missing attribute: \" + \"moduleSpecifier\");\n\t    }\n\t  }\n\t  _reduceState(reducer_336, state_337 = {}) {\n\t    state_337.moduleSpecifier = this.moduleSpecifier;\n\t    ;\n\t    return super._reduceState(reducer_336, state_337);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ moduleSpecifier: this.moduleSpecifier }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_338) {\n\t    let state_339 = this._reduceState(reducer_338);\n\t    return reducer_338.reduceExportAllFrom(this, state_339);\n\t  }\n\t  extend(attrs_340) {\n\t    return new ExportAllFrom(Object.assign(this._cloneAttrs(), attrs_340));\n\t  }\n\t}\n\tExportDeclaration.CloneReducer.prototype.reduceExportAllFrom = function (term_341, state_342) {\n\t  return new ExportAllFrom(state_342);\n\t};\n\texports.ExportAllFrom = ExportAllFrom;\n\n\tclass ExportFrom extends ExportDeclaration {\n\t  constructor(attrs_343, type_344) {\n\t    super(attrs_343, type_344 || \"ExportFrom\");\n\t    if (!{}.hasOwnProperty.call(attrs_343, \"namedExports\")) {\n\t      throw new Error(\"Missing attribute: \" + \"namedExports\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_343, \"moduleSpecifier\")) {\n\t      throw new Error(\"Missing attribute: \" + \"moduleSpecifier\");\n\t    }\n\t  }\n\t  _reduceState(reducer_345, state_346 = {}) {\n\t    state_346.namedExports = this.namedExports.map(a_347 => a_347 instanceof ExportSpecifier ? a_347.reduce(reducer_345) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_347));\n\t    }.call(this));\n\t    state_346.moduleSpecifier = this.moduleSpecifier == null ? null : this.moduleSpecifier;\n\t    ;\n\t    return super._reduceState(reducer_345, state_346);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ namedExports: this.namedExports, moduleSpecifier: this.moduleSpecifier }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_348) {\n\t    let state_349 = this._reduceState(reducer_348);\n\t    return reducer_348.reduceExportFrom(this, state_349);\n\t  }\n\t  extend(attrs_350) {\n\t    return new ExportFrom(Object.assign(this._cloneAttrs(), attrs_350));\n\t  }\n\t}\n\tExportDeclaration.CloneReducer.prototype.reduceExportFrom = function (term_351, state_352) {\n\t  return new ExportFrom(state_352);\n\t};\n\texports.ExportFrom = ExportFrom;\n\n\tclass Export extends ExportDeclaration {\n\t  constructor(attrs_353, type_354) {\n\t    super(attrs_353, type_354 || \"Export\");\n\t    if (!{}.hasOwnProperty.call(attrs_353, \"declaration\")) {\n\t      throw new Error(\"Missing attribute: \" + \"declaration\");\n\t    }\n\t  }\n\t  _reduceState(reducer_355, state_356 = {}) {\n\t    state_356.declaration = this.declaration instanceof FunctionDeclaration ? this.declaration.reduce(reducer_355) : this.declaration instanceof ClassDeclaration ? this.declaration.reduce(reducer_355) : this.declaration instanceof VariableDeclaration ? this.declaration.reduce(reducer_355) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.declaration));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_355, state_356);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ declaration: this.declaration }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_357) {\n\t    let state_358 = this._reduceState(reducer_357);\n\t    return reducer_357.reduceExport(this, state_358);\n\t  }\n\t  extend(attrs_359) {\n\t    return new Export(Object.assign(this._cloneAttrs(), attrs_359));\n\t  }\n\t}\n\tExportDeclaration.CloneReducer.prototype.reduceExport = function (term_360, state_361) {\n\t  return new Export(state_361);\n\t};\n\texports.Export = Export;\n\n\tclass ExportDefault extends ExportDeclaration {\n\t  constructor(attrs_362, type_363) {\n\t    super(attrs_362, type_363 || \"ExportDefault\");\n\t    if (!{}.hasOwnProperty.call(attrs_362, \"body\")) {\n\t      throw new Error(\"Missing attribute: \" + \"body\");\n\t    }\n\t  }\n\t  _reduceState(reducer_364, state_365 = {}) {\n\t    state_365.body = this.body instanceof FunctionDeclaration ? this.body.reduce(reducer_364) : this.body instanceof ClassDeclaration ? this.body.reduce(reducer_364) : this.body instanceof Expression ? this.body.reduce(reducer_364) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.body));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_364, state_365);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ body: this.body }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_366) {\n\t    let state_367 = this._reduceState(reducer_366);\n\t    return reducer_366.reduceExportDefault(this, state_367);\n\t  }\n\t  extend(attrs_368) {\n\t    return new ExportDefault(Object.assign(this._cloneAttrs(), attrs_368));\n\t  }\n\t}\n\tExportDeclaration.CloneReducer.prototype.reduceExportDefault = function (term_369, state_370) {\n\t  return new ExportDefault(state_370);\n\t};\n\texports.ExportDefault = ExportDefault;\n\n\tclass ExportSpecifier extends Term {\n\t  constructor(attrs_371, type_372) {\n\t    super(attrs_371, type_372 || \"ExportSpecifier\");\n\t    if (!{}.hasOwnProperty.call(attrs_371, \"name\")) {\n\t      throw new Error(\"Missing attribute: \" + \"name\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_371, \"exportedName\")) {\n\t      throw new Error(\"Missing attribute: \" + \"exportedName\");\n\t    }\n\t  }\n\t  _reduceState(reducer_373, state_374 = {}) {\n\t    state_374.name = this.name == null ? null : this.name;\n\t    state_374.exportedName = this.exportedName;\n\t    ;\n\t    return super._reduceState(reducer_373, state_374);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ name: this.name, exportedName: this.exportedName }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_375) {\n\t    let state_376 = this._reduceState(reducer_375);\n\t    return reducer_375.reduceExportSpecifier(this, state_376);\n\t  }\n\t  extend(attrs_377) {\n\t    return new ExportSpecifier(Object.assign(this._cloneAttrs(), attrs_377));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceExportSpecifier = function (term_378, state_379) {\n\t  return new ExportSpecifier(state_379);\n\t};\n\texports.ExportSpecifier = ExportSpecifier;\n\n\tclass Method extends MethodDefinition {\n\t  constructor(attrs_380, type_381) {\n\t    super(attrs_380, type_381 || \"Method\");\n\t    if (!{}.hasOwnProperty.call(attrs_380, \"isGenerator\")) {\n\t      throw new Error(\"Missing attribute: \" + \"isGenerator\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_380, \"params\")) {\n\t      throw new Error(\"Missing attribute: \" + \"params\");\n\t    }\n\t  }\n\t  _reduceState(reducer_382, state_383 = {}) {\n\t    state_383.isGenerator = this.isGenerator;\n\t    state_383.params = this.params instanceof FormalParameters ? this.params.reduce(reducer_382) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.params));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_382, state_383);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ isGenerator: this.isGenerator, params: this.params }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_384) {\n\t    let state_385 = this._reduceState(reducer_384);\n\t    return reducer_384.reduceMethod(this, state_385);\n\t  }\n\t  extend(attrs_386) {\n\t    return new Method(Object.assign(this._cloneAttrs(), attrs_386));\n\t  }\n\t}\n\tMethodDefinition.CloneReducer.prototype.reduceMethod = function (term_387, state_388) {\n\t  return new Method(state_388);\n\t};\n\texports.Method = Method;\n\n\tclass Getter extends MethodDefinition {\n\t  constructor(attrs_389, type_390) {\n\t    super(attrs_389, type_390 || \"Getter\");\n\t  }\n\t  _reduceState(reducer_391, state_392 = {}) {\n\t    ;\n\t    return super._reduceState(reducer_391, state_392);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({}, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_393) {\n\t    let state_394 = this._reduceState(reducer_393);\n\t    return reducer_393.reduceGetter(this, state_394);\n\t  }\n\t  extend(attrs_395) {\n\t    return new Getter(Object.assign(this._cloneAttrs(), attrs_395));\n\t  }\n\t}\n\tMethodDefinition.CloneReducer.prototype.reduceGetter = function (term_396, state_397) {\n\t  return new Getter(state_397);\n\t};\n\texports.Getter = Getter;\n\n\tclass Setter extends MethodDefinition {\n\t  constructor(attrs_398, type_399) {\n\t    super(attrs_398, type_399 || \"Setter\");\n\t    if (!{}.hasOwnProperty.call(attrs_398, \"param\")) {\n\t      throw new Error(\"Missing attribute: \" + \"param\");\n\t    }\n\t  }\n\t  _reduceState(reducer_400, state_401 = {}) {\n\t    state_401.param = this.param instanceof ObjectBinding ? this.param.reduce(reducer_400) : this.param instanceof ArrayBinding ? this.param.reduce(reducer_400) : this.param instanceof BindingIdentifier ? this.param.reduce(reducer_400) : this.param instanceof MemberExpression ? this.param.reduce(reducer_400) : this.param instanceof BindingWithDefault ? this.param.reduce(reducer_400) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.param));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_400, state_401);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ param: this.param }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_402) {\n\t    let state_403 = this._reduceState(reducer_402);\n\t    return reducer_402.reduceSetter(this, state_403);\n\t  }\n\t  extend(attrs_404) {\n\t    return new Setter(Object.assign(this._cloneAttrs(), attrs_404));\n\t  }\n\t}\n\tMethodDefinition.CloneReducer.prototype.reduceSetter = function (term_405, state_406) {\n\t  return new Setter(state_406);\n\t};\n\texports.Setter = Setter;\n\n\tclass DataProperty extends NamedObjectProperty {\n\t  constructor(attrs_407, type_408) {\n\t    super(attrs_407, type_408 || \"DataProperty\");\n\t    if (!{}.hasOwnProperty.call(attrs_407, \"expression\")) {\n\t      throw new Error(\"Missing attribute: \" + \"expression\");\n\t    }\n\t  }\n\t  _reduceState(reducer_409, state_410 = {}) {\n\t    state_410.expression = this.expression instanceof Expression ? this.expression.reduce(reducer_409) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.expression));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_409, state_410);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ expression: this.expression }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_411) {\n\t    let state_412 = this._reduceState(reducer_411);\n\t    return reducer_411.reduceDataProperty(this, state_412);\n\t  }\n\t  extend(attrs_413) {\n\t    return new DataProperty(Object.assign(this._cloneAttrs(), attrs_413));\n\t  }\n\t}\n\tNamedObjectProperty.CloneReducer.prototype.reduceDataProperty = function (term_414, state_415) {\n\t  return new DataProperty(state_415);\n\t};\n\texports.DataProperty = DataProperty;\n\n\tclass ShorthandProperty extends ObjectProperty {\n\t  constructor(attrs_416, type_417) {\n\t    super(attrs_416, type_417 || \"ShorthandProperty\");\n\t    if (!{}.hasOwnProperty.call(attrs_416, \"name\")) {\n\t      throw new Error(\"Missing attribute: \" + \"name\");\n\t    }\n\t  }\n\t  _reduceState(reducer_418, state_419 = {}) {\n\t    state_419.name = this.name;\n\t    ;\n\t    return super._reduceState(reducer_418, state_419);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ name: this.name }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_420) {\n\t    let state_421 = this._reduceState(reducer_420);\n\t    return reducer_420.reduceShorthandProperty(this, state_421);\n\t  }\n\t  extend(attrs_422) {\n\t    return new ShorthandProperty(Object.assign(this._cloneAttrs(), attrs_422));\n\t  }\n\t}\n\tObjectProperty.CloneReducer.prototype.reduceShorthandProperty = function (term_423, state_424) {\n\t  return new ShorthandProperty(state_424);\n\t};\n\texports.ShorthandProperty = ShorthandProperty;\n\n\tclass StaticPropertyName extends PropertyName {\n\t  constructor(attrs_425, type_426) {\n\t    super(attrs_425, type_426 || \"StaticPropertyName\");\n\t    if (!{}.hasOwnProperty.call(attrs_425, \"value\")) {\n\t      throw new Error(\"Missing attribute: \" + \"value\");\n\t    }\n\t  }\n\t  _reduceState(reducer_427, state_428 = {}) {\n\t    state_428.value = this.value;\n\t    ;\n\t    return super._reduceState(reducer_427, state_428);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ value: this.value }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_429) {\n\t    let state_430 = this._reduceState(reducer_429);\n\t    return reducer_429.reduceStaticPropertyName(this, state_430);\n\t  }\n\t  extend(attrs_431) {\n\t    return new StaticPropertyName(Object.assign(this._cloneAttrs(), attrs_431));\n\t  }\n\t}\n\tPropertyName.CloneReducer.prototype.reduceStaticPropertyName = function (term_432, state_433) {\n\t  return new StaticPropertyName(state_433);\n\t};\n\texports.StaticPropertyName = StaticPropertyName;\n\n\tclass ComputedPropertyName extends PropertyName {\n\t  constructor(attrs_434, type_435) {\n\t    super(attrs_434, type_435 || \"ComputedPropertyName\");\n\t    if (!{}.hasOwnProperty.call(attrs_434, \"expression\")) {\n\t      throw new Error(\"Missing attribute: \" + \"expression\");\n\t    }\n\t  }\n\t  _reduceState(reducer_436, state_437 = {}) {\n\t    state_437.expression = this.expression instanceof Expression ? this.expression.reduce(reducer_436) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.expression));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_436, state_437);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ expression: this.expression }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_438) {\n\t    let state_439 = this._reduceState(reducer_438);\n\t    return reducer_438.reduceComputedPropertyName(this, state_439);\n\t  }\n\t  extend(attrs_440) {\n\t    return new ComputedPropertyName(Object.assign(this._cloneAttrs(), attrs_440));\n\t  }\n\t}\n\tPropertyName.CloneReducer.prototype.reduceComputedPropertyName = function (term_441, state_442) {\n\t  return new ComputedPropertyName(state_442);\n\t};\n\texports.ComputedPropertyName = ComputedPropertyName;\n\n\tclass LiteralBooleanExpression extends Expression {\n\t  constructor(attrs_443, type_444) {\n\t    super(attrs_443, type_444 || \"LiteralBooleanExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_443, \"value\")) {\n\t      throw new Error(\"Missing attribute: \" + \"value\");\n\t    }\n\t  }\n\t  _reduceState(reducer_445, state_446 = {}) {\n\t    state_446.value = this.value;\n\t    ;\n\t    return super._reduceState(reducer_445, state_446);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ value: this.value }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_447) {\n\t    let state_448 = this._reduceState(reducer_447);\n\t    return reducer_447.reduceLiteralBooleanExpression(this, state_448);\n\t  }\n\t  extend(attrs_449) {\n\t    return new LiteralBooleanExpression(Object.assign(this._cloneAttrs(), attrs_449));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceLiteralBooleanExpression = function (term_450, state_451) {\n\t  return new LiteralBooleanExpression(state_451);\n\t};\n\texports.LiteralBooleanExpression = LiteralBooleanExpression;\n\n\tclass LiteralInfinityExpression extends Expression {\n\t  constructor(attrs_452, type_453) {\n\t    super(attrs_452, type_453 || \"LiteralInfinityExpression\");\n\t  }\n\t  _reduceState(reducer_454, state_455 = {}) {\n\t    ;\n\t    return super._reduceState(reducer_454, state_455);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({}, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_456) {\n\t    let state_457 = this._reduceState(reducer_456);\n\t    return reducer_456.reduceLiteralInfinityExpression(this, state_457);\n\t  }\n\t  extend(attrs_458) {\n\t    return new LiteralInfinityExpression(Object.assign(this._cloneAttrs(), attrs_458));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceLiteralInfinityExpression = function (term_459, state_460) {\n\t  return new LiteralInfinityExpression(state_460);\n\t};\n\texports.LiteralInfinityExpression = LiteralInfinityExpression;\n\n\tclass LiteralNullExpression extends Expression {\n\t  constructor(attrs_461, type_462) {\n\t    super(attrs_461, type_462 || \"LiteralNullExpression\");\n\t  }\n\t  _reduceState(reducer_463, state_464 = {}) {\n\t    ;\n\t    return super._reduceState(reducer_463, state_464);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({}, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_465) {\n\t    let state_466 = this._reduceState(reducer_465);\n\t    return reducer_465.reduceLiteralNullExpression(this, state_466);\n\t  }\n\t  extend(attrs_467) {\n\t    return new LiteralNullExpression(Object.assign(this._cloneAttrs(), attrs_467));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceLiteralNullExpression = function (term_468, state_469) {\n\t  return new LiteralNullExpression(state_469);\n\t};\n\texports.LiteralNullExpression = LiteralNullExpression;\n\n\tclass LiteralNumericExpression extends Expression {\n\t  constructor(attrs_470, type_471) {\n\t    super(attrs_470, type_471 || \"LiteralNumericExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_470, \"value\")) {\n\t      throw new Error(\"Missing attribute: \" + \"value\");\n\t    }\n\t  }\n\t  _reduceState(reducer_472, state_473 = {}) {\n\t    state_473.value = this.value;\n\t    ;\n\t    return super._reduceState(reducer_472, state_473);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ value: this.value }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_474) {\n\t    let state_475 = this._reduceState(reducer_474);\n\t    return reducer_474.reduceLiteralNumericExpression(this, state_475);\n\t  }\n\t  extend(attrs_476) {\n\t    return new LiteralNumericExpression(Object.assign(this._cloneAttrs(), attrs_476));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceLiteralNumericExpression = function (term_477, state_478) {\n\t  return new LiteralNumericExpression(state_478);\n\t};\n\texports.LiteralNumericExpression = LiteralNumericExpression;\n\n\tclass LiteralRegExpExpression extends Expression {\n\t  constructor(attrs_479, type_480) {\n\t    super(attrs_479, type_480 || \"LiteralRegExpExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_479, \"pattern\")) {\n\t      throw new Error(\"Missing attribute: \" + \"pattern\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_479, \"flags\")) {\n\t      throw new Error(\"Missing attribute: \" + \"flags\");\n\t    }\n\t  }\n\t  _reduceState(reducer_481, state_482 = {}) {\n\t    state_482.pattern = this.pattern;\n\t    state_482.flags = this.flags;\n\t    ;\n\t    return super._reduceState(reducer_481, state_482);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ pattern: this.pattern, flags: this.flags }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_483) {\n\t    let state_484 = this._reduceState(reducer_483);\n\t    return reducer_483.reduceLiteralRegExpExpression(this, state_484);\n\t  }\n\t  extend(attrs_485) {\n\t    return new LiteralRegExpExpression(Object.assign(this._cloneAttrs(), attrs_485));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceLiteralRegExpExpression = function (term_486, state_487) {\n\t  return new LiteralRegExpExpression(state_487);\n\t};\n\texports.LiteralRegExpExpression = LiteralRegExpExpression;\n\n\tclass LiteralStringExpression extends Expression {\n\t  constructor(attrs_488, type_489) {\n\t    super(attrs_488, type_489 || \"LiteralStringExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_488, \"value\")) {\n\t      throw new Error(\"Missing attribute: \" + \"value\");\n\t    }\n\t  }\n\t  _reduceState(reducer_490, state_491 = {}) {\n\t    state_491.value = this.value;\n\t    ;\n\t    return super._reduceState(reducer_490, state_491);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ value: this.value }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_492) {\n\t    let state_493 = this._reduceState(reducer_492);\n\t    return reducer_492.reduceLiteralStringExpression(this, state_493);\n\t  }\n\t  extend(attrs_494) {\n\t    return new LiteralStringExpression(Object.assign(this._cloneAttrs(), attrs_494));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceLiteralStringExpression = function (term_495, state_496) {\n\t  return new LiteralStringExpression(state_496);\n\t};\n\texports.LiteralStringExpression = LiteralStringExpression;\n\n\tclass ArrayExpression extends Expression {\n\t  constructor(attrs_497, type_498) {\n\t    super(attrs_497, type_498 || \"ArrayExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_497, \"elements\")) {\n\t      throw new Error(\"Missing attribute: \" + \"elements\");\n\t    }\n\t  }\n\t  _reduceState(reducer_499, state_500 = {}) {\n\t    state_500.elements = this.elements.map(a_501 => a_501 instanceof SpreadElement ? a_501.reduce(reducer_499) : a_501 instanceof Expression ? a_501.reduce(reducer_499) : a_501 == null ? null : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_501));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_499, state_500);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ elements: this.elements }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_502) {\n\t    let state_503 = this._reduceState(reducer_502);\n\t    return reducer_502.reduceArrayExpression(this, state_503);\n\t  }\n\t  extend(attrs_504) {\n\t    return new ArrayExpression(Object.assign(this._cloneAttrs(), attrs_504));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceArrayExpression = function (term_505, state_506) {\n\t  return new ArrayExpression(state_506);\n\t};\n\texports.ArrayExpression = ArrayExpression;\n\n\tclass ArrowExpression extends Expression {\n\t  constructor(attrs_507, type_508) {\n\t    super(attrs_507, type_508 || \"ArrowExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_507, \"params\")) {\n\t      throw new Error(\"Missing attribute: \" + \"params\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_507, \"body\")) {\n\t      throw new Error(\"Missing attribute: \" + \"body\");\n\t    }\n\t  }\n\t  _reduceState(reducer_509, state_510 = {}) {\n\t    state_510.params = this.params instanceof FormalParameters ? this.params.reduce(reducer_509) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.params));\n\t    }.call(this);\n\t    state_510.body = this.body instanceof FunctionBody ? this.body.reduce(reducer_509) : this.body instanceof Expression ? this.body.reduce(reducer_509) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.body));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_509, state_510);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ params: this.params, body: this.body }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_511) {\n\t    let state_512 = this._reduceState(reducer_511);\n\t    return reducer_511.reduceArrowExpression(this, state_512);\n\t  }\n\t  extend(attrs_513) {\n\t    return new ArrowExpression(Object.assign(this._cloneAttrs(), attrs_513));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceArrowExpression = function (term_514, state_515) {\n\t  return new ArrowExpression(state_515);\n\t};\n\texports.ArrowExpression = ArrowExpression;\n\n\tclass ArrowExpressionE extends Expression {\n\t  constructor(attrs_516, type_517) {\n\t    super(attrs_516, type_517 || \"ArrowExpressionE\");\n\t    if (!{}.hasOwnProperty.call(attrs_516, \"params\")) {\n\t      throw new Error(\"Missing attribute: \" + \"params\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_516, \"body\")) {\n\t      throw new Error(\"Missing attribute: \" + \"body\");\n\t    }\n\t  }\n\t  _reduceState(reducer_518, state_519 = {}) {\n\t    state_519.params = this.params instanceof FormalParameters ? this.params.reduce(reducer_518) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.params));\n\t    }.call(this);\n\t    state_519.body = this.body.map(a_520 => a_520 instanceof Term ? a_520.reduce(reducer_518) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_520));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_518, state_519);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ params: this.params, body: this.body }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_521) {\n\t    let state_522 = this._reduceState(reducer_521);\n\t    return reducer_521.reduceArrowExpressionE(this, state_522);\n\t  }\n\t  extend(attrs_523) {\n\t    return new ArrowExpressionE(Object.assign(this._cloneAttrs(), attrs_523));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceArrowExpressionE = function (term_524, state_525) {\n\t  return new ArrowExpressionE(state_525);\n\t};\n\texports.ArrowExpressionE = ArrowExpressionE;\n\n\tclass AssignmentExpression extends Expression {\n\t  constructor(attrs_526, type_527) {\n\t    super(attrs_526, type_527 || \"AssignmentExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_526, \"binding\")) {\n\t      throw new Error(\"Missing attribute: \" + \"binding\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_526, \"expression\")) {\n\t      throw new Error(\"Missing attribute: \" + \"expression\");\n\t    }\n\t  }\n\t  _reduceState(reducer_528, state_529 = {}) {\n\t    state_529.binding = this.binding instanceof BindingIdentifier ? this.binding.reduce(reducer_528) : this.binding instanceof BindingPropertyProperty ? this.binding.reduce(reducer_528) : this.binding instanceof BindingPropertyIdentifier ? this.binding.reduce(reducer_528) : this.binding instanceof ObjectBinding ? this.binding.reduce(reducer_528) : this.binding instanceof ArrayBinding ? this.binding.reduce(reducer_528) : this.binding instanceof MemberExpression ? this.binding.reduce(reducer_528) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.binding));\n\t    }.call(this);\n\t    state_529.expression = this.expression instanceof Expression ? this.expression.reduce(reducer_528) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.expression));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_528, state_529);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ binding: this.binding, expression: this.expression }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_530) {\n\t    let state_531 = this._reduceState(reducer_530);\n\t    return reducer_530.reduceAssignmentExpression(this, state_531);\n\t  }\n\t  extend(attrs_532) {\n\t    return new AssignmentExpression(Object.assign(this._cloneAttrs(), attrs_532));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceAssignmentExpression = function (term_533, state_534) {\n\t  return new AssignmentExpression(state_534);\n\t};\n\texports.AssignmentExpression = AssignmentExpression;\n\n\tclass BinaryExpression extends Expression {\n\t  constructor(attrs_535, type_536) {\n\t    super(attrs_535, type_536 || \"BinaryExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_535, \"operator\")) {\n\t      throw new Error(\"Missing attribute: \" + \"operator\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_535, \"left\")) {\n\t      throw new Error(\"Missing attribute: \" + \"left\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_535, \"right\")) {\n\t      throw new Error(\"Missing attribute: \" + \"right\");\n\t    }\n\t  }\n\t  _reduceState(reducer_537, state_538 = {}) {\n\t    state_538.operator = this.operator;\n\t    state_538.left = this.left instanceof Expression ? this.left.reduce(reducer_537) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.left));\n\t    }.call(this);\n\t    state_538.right = this.right instanceof Expression ? this.right.reduce(reducer_537) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.right));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_537, state_538);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ operator: this.operator, left: this.left, right: this.right }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_539) {\n\t    let state_540 = this._reduceState(reducer_539);\n\t    return reducer_539.reduceBinaryExpression(this, state_540);\n\t  }\n\t  extend(attrs_541) {\n\t    return new BinaryExpression(Object.assign(this._cloneAttrs(), attrs_541));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceBinaryExpression = function (term_542, state_543) {\n\t  return new BinaryExpression(state_543);\n\t};\n\texports.BinaryExpression = BinaryExpression;\n\n\tclass CallExpression extends Expression {\n\t  constructor(attrs_544, type_545) {\n\t    super(attrs_544, type_545 || \"CallExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_544, \"callee\")) {\n\t      throw new Error(\"Missing attribute: \" + \"callee\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_544, \"arguments\")) {\n\t      throw new Error(\"Missing attribute: \" + \"arguments\");\n\t    }\n\t  }\n\t  _reduceState(reducer_546, state_547 = {}) {\n\t    state_547.callee = this.callee instanceof Expression ? this.callee.reduce(reducer_546) : this.callee instanceof Super ? this.callee.reduce(reducer_546) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.callee));\n\t    }.call(this);\n\t    state_547.arguments = this.arguments.map(a_548 => a_548 instanceof SpreadElement ? a_548.reduce(reducer_546) : a_548 instanceof Expression ? a_548.reduce(reducer_546) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_548));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_546, state_547);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ callee: this.callee, arguments: this.arguments }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_549) {\n\t    let state_550 = this._reduceState(reducer_549);\n\t    return reducer_549.reduceCallExpression(this, state_550);\n\t  }\n\t  extend(attrs_551) {\n\t    return new CallExpression(Object.assign(this._cloneAttrs(), attrs_551));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceCallExpression = function (term_552, state_553) {\n\t  return new CallExpression(state_553);\n\t};\n\texports.CallExpression = CallExpression;\n\n\tclass CallExpressionE extends Expression {\n\t  constructor(attrs_554, type_555) {\n\t    super(attrs_554, type_555 || \"CallExpressionE\");\n\t    if (!{}.hasOwnProperty.call(attrs_554, \"callee\")) {\n\t      throw new Error(\"Missing attribute: \" + \"callee\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_554, \"arguments\")) {\n\t      throw new Error(\"Missing attribute: \" + \"arguments\");\n\t    }\n\t  }\n\t  _reduceState(reducer_556, state_557 = {}) {\n\t    state_557.callee = this.callee instanceof Expression ? this.callee.reduce(reducer_556) : this.callee instanceof Super ? this.callee.reduce(reducer_556) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.callee));\n\t    }.call(this);\n\t    state_557.arguments = this.arguments.map(a_558 => a_558 instanceof Term ? a_558.reduce(reducer_556) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_558));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_556, state_557);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ callee: this.callee, arguments: this.arguments }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_559) {\n\t    let state_560 = this._reduceState(reducer_559);\n\t    return reducer_559.reduceCallExpressionE(this, state_560);\n\t  }\n\t  extend(attrs_561) {\n\t    return new CallExpressionE(Object.assign(this._cloneAttrs(), attrs_561));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceCallExpressionE = function (term_562, state_563) {\n\t  return new CallExpressionE(state_563);\n\t};\n\texports.CallExpressionE = CallExpressionE;\n\n\tclass CompoundAssignmentExpression extends Expression {\n\t  constructor(attrs_564, type_565) {\n\t    super(attrs_564, type_565 || \"CompoundAssignmentExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_564, \"binding\")) {\n\t      throw new Error(\"Missing attribute: \" + \"binding\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_564, \"operator\")) {\n\t      throw new Error(\"Missing attribute: \" + \"operator\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_564, \"expression\")) {\n\t      throw new Error(\"Missing attribute: \" + \"expression\");\n\t    }\n\t  }\n\t  _reduceState(reducer_566, state_567 = {}) {\n\t    state_567.binding = this.binding instanceof BindingIdentifier ? this.binding.reduce(reducer_566) : this.binding instanceof MemberExpression ? this.binding.reduce(reducer_566) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.binding));\n\t    }.call(this);\n\t    state_567.operator = this.operator;\n\t    state_567.expression = this.expression instanceof Expression ? this.expression.reduce(reducer_566) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.expression));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_566, state_567);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ binding: this.binding, operator: this.operator, expression: this.expression }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_568) {\n\t    let state_569 = this._reduceState(reducer_568);\n\t    return reducer_568.reduceCompoundAssignmentExpression(this, state_569);\n\t  }\n\t  extend(attrs_570) {\n\t    return new CompoundAssignmentExpression(Object.assign(this._cloneAttrs(), attrs_570));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceCompoundAssignmentExpression = function (term_571, state_572) {\n\t  return new CompoundAssignmentExpression(state_572);\n\t};\n\texports.CompoundAssignmentExpression = CompoundAssignmentExpression;\n\n\tclass ComputedMemberExpression extends MemberExpression {\n\t  constructor(attrs_573, type_574) {\n\t    super(attrs_573, type_574 || \"ComputedMemberExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_573, \"expression\")) {\n\t      throw new Error(\"Missing attribute: \" + \"expression\");\n\t    }\n\t  }\n\t  _reduceState(reducer_575, state_576 = {}) {\n\t    state_576.expression = this.expression instanceof Expression ? this.expression.reduce(reducer_575) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.expression));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_575, state_576);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ expression: this.expression }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_577) {\n\t    let state_578 = this._reduceState(reducer_577);\n\t    return reducer_577.reduceComputedMemberExpression(this, state_578);\n\t  }\n\t  extend(attrs_579) {\n\t    return new ComputedMemberExpression(Object.assign(this._cloneAttrs(), attrs_579));\n\t  }\n\t}\n\tMemberExpression.CloneReducer.prototype.reduceComputedMemberExpression = function (term_580, state_581) {\n\t  return new ComputedMemberExpression(state_581);\n\t};\n\texports.ComputedMemberExpression = ComputedMemberExpression;\n\n\tclass ConditionalExpression extends Expression {\n\t  constructor(attrs_582, type_583) {\n\t    super(attrs_582, type_583 || \"ConditionalExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_582, \"test\")) {\n\t      throw new Error(\"Missing attribute: \" + \"test\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_582, \"consequent\")) {\n\t      throw new Error(\"Missing attribute: \" + \"consequent\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_582, \"alternate\")) {\n\t      throw new Error(\"Missing attribute: \" + \"alternate\");\n\t    }\n\t  }\n\t  _reduceState(reducer_584, state_585 = {}) {\n\t    state_585.test = this.test instanceof Expression ? this.test.reduce(reducer_584) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.test));\n\t    }.call(this);\n\t    state_585.consequent = this.consequent instanceof Expression ? this.consequent.reduce(reducer_584) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.consequent));\n\t    }.call(this);\n\t    state_585.alternate = this.alternate instanceof Expression ? this.alternate.reduce(reducer_584) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.alternate));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_584, state_585);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ test: this.test, consequent: this.consequent, alternate: this.alternate }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_586) {\n\t    let state_587 = this._reduceState(reducer_586);\n\t    return reducer_586.reduceConditionalExpression(this, state_587);\n\t  }\n\t  extend(attrs_588) {\n\t    return new ConditionalExpression(Object.assign(this._cloneAttrs(), attrs_588));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceConditionalExpression = function (term_589, state_590) {\n\t  return new ConditionalExpression(state_590);\n\t};\n\texports.ConditionalExpression = ConditionalExpression;\n\n\tclass FunctionExpression extends Expression {\n\t  constructor(attrs_591, type_592) {\n\t    super(attrs_591, type_592 || \"FunctionExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_591, \"name\")) {\n\t      throw new Error(\"Missing attribute: \" + \"name\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_591, \"isGenerator\")) {\n\t      throw new Error(\"Missing attribute: \" + \"isGenerator\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_591, \"params\")) {\n\t      throw new Error(\"Missing attribute: \" + \"params\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_591, \"body\")) {\n\t      throw new Error(\"Missing attribute: \" + \"body\");\n\t    }\n\t  }\n\t  _reduceState(reducer_593, state_594 = {}) {\n\t    state_594.name = this.name == null ? null : this.name instanceof BindingIdentifier ? this.name.reduce(reducer_593) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.name));\n\t    }.call(this);\n\t    state_594.isGenerator = this.isGenerator;\n\t    state_594.params = this.params instanceof FormalParameters ? this.params.reduce(reducer_593) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.params));\n\t    }.call(this);\n\t    state_594.body = this.body instanceof FunctionBody ? this.body.reduce(reducer_593) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.body));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_593, state_594);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ name: this.name, isGenerator: this.isGenerator, params: this.params, body: this.body }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_595) {\n\t    let state_596 = this._reduceState(reducer_595);\n\t    return reducer_595.reduceFunctionExpression(this, state_596);\n\t  }\n\t  extend(attrs_597) {\n\t    return new FunctionExpression(Object.assign(this._cloneAttrs(), attrs_597));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceFunctionExpression = function (term_598, state_599) {\n\t  return new FunctionExpression(state_599);\n\t};\n\texports.FunctionExpression = FunctionExpression;\n\n\tclass FunctionExpressionE extends Expression {\n\t  constructor(attrs_600, type_601) {\n\t    super(attrs_600, type_601 || \"FunctionExpressionE\");\n\t    if (!{}.hasOwnProperty.call(attrs_600, \"name\")) {\n\t      throw new Error(\"Missing attribute: \" + \"name\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_600, \"isGenerator\")) {\n\t      throw new Error(\"Missing attribute: \" + \"isGenerator\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_600, \"params\")) {\n\t      throw new Error(\"Missing attribute: \" + \"params\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_600, \"body\")) {\n\t      throw new Error(\"Missing attribute: \" + \"body\");\n\t    }\n\t  }\n\t  _reduceState(reducer_602, state_603 = {}) {\n\t    state_603.name = this.name == null ? null : this.name instanceof BindingIdentifier ? this.name.reduce(reducer_602) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.name));\n\t    }.call(this);\n\t    state_603.isGenerator = this.isGenerator;\n\t    state_603.params = this.params instanceof FormalParameters ? this.params.reduce(reducer_602) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.params));\n\t    }.call(this);\n\t    state_603.body = this.body.map(a_604 => a_604 instanceof Term ? a_604.reduce(reducer_602) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_604));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_602, state_603);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ name: this.name, isGenerator: this.isGenerator, params: this.params, body: this.body }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_605) {\n\t    let state_606 = this._reduceState(reducer_605);\n\t    return reducer_605.reduceFunctionExpressionE(this, state_606);\n\t  }\n\t  extend(attrs_607) {\n\t    return new FunctionExpressionE(Object.assign(this._cloneAttrs(), attrs_607));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceFunctionExpressionE = function (term_608, state_609) {\n\t  return new FunctionExpressionE(state_609);\n\t};\n\texports.FunctionExpressionE = FunctionExpressionE;\n\n\tclass IdentifierExpression extends Expression {\n\t  constructor(attrs_610, type_611) {\n\t    super(attrs_610, type_611 || \"IdentifierExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_610, \"name\")) {\n\t      throw new Error(\"Missing attribute: \" + \"name\");\n\t    }\n\t  }\n\t  _reduceState(reducer_612, state_613 = {}) {\n\t    state_613.name = this.name;\n\t    ;\n\t    return super._reduceState(reducer_612, state_613);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ name: this.name }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_614) {\n\t    let state_615 = this._reduceState(reducer_614);\n\t    return reducer_614.reduceIdentifierExpression(this, state_615);\n\t  }\n\t  extend(attrs_616) {\n\t    return new IdentifierExpression(Object.assign(this._cloneAttrs(), attrs_616));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceIdentifierExpression = function (term_617, state_618) {\n\t  return new IdentifierExpression(state_618);\n\t};\n\texports.IdentifierExpression = IdentifierExpression;\n\n\tclass NewExpression extends Expression {\n\t  constructor(attrs_619, type_620) {\n\t    super(attrs_619, type_620 || \"NewExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_619, \"callee\")) {\n\t      throw new Error(\"Missing attribute: \" + \"callee\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_619, \"arguments\")) {\n\t      throw new Error(\"Missing attribute: \" + \"arguments\");\n\t    }\n\t  }\n\t  _reduceState(reducer_621, state_622 = {}) {\n\t    state_622.callee = this.callee instanceof Expression ? this.callee.reduce(reducer_621) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.callee));\n\t    }.call(this);\n\t    state_622.arguments = this.arguments.map(a_623 => a_623 instanceof SpreadElement ? a_623.reduce(reducer_621) : a_623 instanceof Expression ? a_623.reduce(reducer_621) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_623));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_621, state_622);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ callee: this.callee, arguments: this.arguments }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_624) {\n\t    let state_625 = this._reduceState(reducer_624);\n\t    return reducer_624.reduceNewExpression(this, state_625);\n\t  }\n\t  extend(attrs_626) {\n\t    return new NewExpression(Object.assign(this._cloneAttrs(), attrs_626));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceNewExpression = function (term_627, state_628) {\n\t  return new NewExpression(state_628);\n\t};\n\texports.NewExpression = NewExpression;\n\n\tclass NewTargetExpression extends Expression {\n\t  constructor(attrs_629, type_630) {\n\t    super(attrs_629, type_630 || \"NewTargetExpression\");\n\t  }\n\t  _reduceState(reducer_631, state_632 = {}) {\n\t    ;\n\t    return super._reduceState(reducer_631, state_632);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({}, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_633) {\n\t    let state_634 = this._reduceState(reducer_633);\n\t    return reducer_633.reduceNewTargetExpression(this, state_634);\n\t  }\n\t  extend(attrs_635) {\n\t    return new NewTargetExpression(Object.assign(this._cloneAttrs(), attrs_635));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceNewTargetExpression = function (term_636, state_637) {\n\t  return new NewTargetExpression(state_637);\n\t};\n\texports.NewTargetExpression = NewTargetExpression;\n\n\tclass ObjectExpression extends Expression {\n\t  constructor(attrs_638, type_639) {\n\t    super(attrs_638, type_639 || \"ObjectExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_638, \"properties\")) {\n\t      throw new Error(\"Missing attribute: \" + \"properties\");\n\t    }\n\t  }\n\t  _reduceState(reducer_640, state_641 = {}) {\n\t    state_641.properties = this.properties.map(a_642 => a_642 instanceof ObjectProperty ? a_642.reduce(reducer_640) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_642));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_640, state_641);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ properties: this.properties }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_643) {\n\t    let state_644 = this._reduceState(reducer_643);\n\t    return reducer_643.reduceObjectExpression(this, state_644);\n\t  }\n\t  extend(attrs_645) {\n\t    return new ObjectExpression(Object.assign(this._cloneAttrs(), attrs_645));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceObjectExpression = function (term_646, state_647) {\n\t  return new ObjectExpression(state_647);\n\t};\n\texports.ObjectExpression = ObjectExpression;\n\n\tclass UnaryExpression extends Expression {\n\t  constructor(attrs_648, type_649) {\n\t    super(attrs_648, type_649 || \"UnaryExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_648, \"operator\")) {\n\t      throw new Error(\"Missing attribute: \" + \"operator\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_648, \"operand\")) {\n\t      throw new Error(\"Missing attribute: \" + \"operand\");\n\t    }\n\t  }\n\t  _reduceState(reducer_650, state_651 = {}) {\n\t    state_651.operator = this.operator;\n\t    state_651.operand = this.operand instanceof Expression ? this.operand.reduce(reducer_650) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.operand));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_650, state_651);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ operator: this.operator, operand: this.operand }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_652) {\n\t    let state_653 = this._reduceState(reducer_652);\n\t    return reducer_652.reduceUnaryExpression(this, state_653);\n\t  }\n\t  extend(attrs_654) {\n\t    return new UnaryExpression(Object.assign(this._cloneAttrs(), attrs_654));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceUnaryExpression = function (term_655, state_656) {\n\t  return new UnaryExpression(state_656);\n\t};\n\texports.UnaryExpression = UnaryExpression;\n\n\tclass StaticMemberExpression extends MemberExpression {\n\t  constructor(attrs_657, type_658) {\n\t    super(attrs_657, type_658 || \"StaticMemberExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_657, \"property\")) {\n\t      throw new Error(\"Missing attribute: \" + \"property\");\n\t    }\n\t  }\n\t  _reduceState(reducer_659, state_660 = {}) {\n\t    state_660.property = this.property;\n\t    ;\n\t    return super._reduceState(reducer_659, state_660);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ property: this.property }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_661) {\n\t    let state_662 = this._reduceState(reducer_661);\n\t    return reducer_661.reduceStaticMemberExpression(this, state_662);\n\t  }\n\t  extend(attrs_663) {\n\t    return new StaticMemberExpression(Object.assign(this._cloneAttrs(), attrs_663));\n\t  }\n\t}\n\tMemberExpression.CloneReducer.prototype.reduceStaticMemberExpression = function (term_664, state_665) {\n\t  return new StaticMemberExpression(state_665);\n\t};\n\texports.StaticMemberExpression = StaticMemberExpression;\n\n\tclass TemplateExpression extends Expression {\n\t  constructor(attrs_666, type_667) {\n\t    super(attrs_666, type_667 || \"TemplateExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_666, \"tag\")) {\n\t      throw new Error(\"Missing attribute: \" + \"tag\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_666, \"elements\")) {\n\t      throw new Error(\"Missing attribute: \" + \"elements\");\n\t    }\n\t  }\n\t  _reduceState(reducer_668, state_669 = {}) {\n\t    state_669.tag = this.tag == null ? null : this.tag instanceof Expression ? this.tag.reduce(reducer_668) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.tag));\n\t    }.call(this);\n\t    state_669.elements = this.elements.map(a_670 => a_670 instanceof Expression ? a_670.reduce(reducer_668) : a_670 instanceof TemplateElement ? a_670.reduce(reducer_668) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_670));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_668, state_669);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ tag: this.tag, elements: this.elements }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_671) {\n\t    let state_672 = this._reduceState(reducer_671);\n\t    return reducer_671.reduceTemplateExpression(this, state_672);\n\t  }\n\t  extend(attrs_673) {\n\t    return new TemplateExpression(Object.assign(this._cloneAttrs(), attrs_673));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceTemplateExpression = function (term_674, state_675) {\n\t  return new TemplateExpression(state_675);\n\t};\n\texports.TemplateExpression = TemplateExpression;\n\n\tclass ThisExpression extends Expression {\n\t  constructor(attrs_676, type_677) {\n\t    super(attrs_676, type_677 || \"ThisExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_676, \"stx\")) {\n\t      throw new Error(\"Missing attribute: \" + \"stx\");\n\t    }\n\t  }\n\t  _reduceState(reducer_678, state_679 = {}) {\n\t    state_679.stx = this.stx;\n\t    ;\n\t    return super._reduceState(reducer_678, state_679);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ stx: this.stx }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_680) {\n\t    let state_681 = this._reduceState(reducer_680);\n\t    return reducer_680.reduceThisExpression(this, state_681);\n\t  }\n\t  extend(attrs_682) {\n\t    return new ThisExpression(Object.assign(this._cloneAttrs(), attrs_682));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceThisExpression = function (term_683, state_684) {\n\t  return new ThisExpression(state_684);\n\t};\n\texports.ThisExpression = ThisExpression;\n\n\tclass UpdateExpression extends Expression {\n\t  constructor(attrs_685, type_686) {\n\t    super(attrs_685, type_686 || \"UpdateExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_685, \"isPrefix\")) {\n\t      throw new Error(\"Missing attribute: \" + \"isPrefix\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_685, \"operator\")) {\n\t      throw new Error(\"Missing attribute: \" + \"operator\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_685, \"operand\")) {\n\t      throw new Error(\"Missing attribute: \" + \"operand\");\n\t    }\n\t  }\n\t  _reduceState(reducer_687, state_688 = {}) {\n\t    state_688.isPrefix = this.isPrefix;\n\t    state_688.operator = this.operator;\n\t    state_688.operand = this.operand instanceof BindingIdentifier ? this.operand.reduce(reducer_687) : this.operand instanceof MemberExpression ? this.operand.reduce(reducer_687) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.operand));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_687, state_688);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ isPrefix: this.isPrefix, operator: this.operator, operand: this.operand }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_689) {\n\t    let state_690 = this._reduceState(reducer_689);\n\t    return reducer_689.reduceUpdateExpression(this, state_690);\n\t  }\n\t  extend(attrs_691) {\n\t    return new UpdateExpression(Object.assign(this._cloneAttrs(), attrs_691));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceUpdateExpression = function (term_692, state_693) {\n\t  return new UpdateExpression(state_693);\n\t};\n\texports.UpdateExpression = UpdateExpression;\n\n\tclass YieldExpression extends Expression {\n\t  constructor(attrs_694, type_695) {\n\t    super(attrs_694, type_695 || \"YieldExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_694, \"expression\")) {\n\t      throw new Error(\"Missing attribute: \" + \"expression\");\n\t    }\n\t  }\n\t  _reduceState(reducer_696, state_697 = {}) {\n\t    state_697.expression = this.expression == null ? null : this.expression instanceof Expression ? this.expression.reduce(reducer_696) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.expression));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_696, state_697);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ expression: this.expression }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_698) {\n\t    let state_699 = this._reduceState(reducer_698);\n\t    return reducer_698.reduceYieldExpression(this, state_699);\n\t  }\n\t  extend(attrs_700) {\n\t    return new YieldExpression(Object.assign(this._cloneAttrs(), attrs_700));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceYieldExpression = function (term_701, state_702) {\n\t  return new YieldExpression(state_702);\n\t};\n\texports.YieldExpression = YieldExpression;\n\n\tclass YieldGeneratorExpression extends Expression {\n\t  constructor(attrs_703, type_704) {\n\t    super(attrs_703, type_704 || \"YieldGeneratorExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_703, \"expression\")) {\n\t      throw new Error(\"Missing attribute: \" + \"expression\");\n\t    }\n\t  }\n\t  _reduceState(reducer_705, state_706 = {}) {\n\t    state_706.expression = this.expression instanceof Expression ? this.expression.reduce(reducer_705) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.expression));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_705, state_706);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ expression: this.expression }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_707) {\n\t    let state_708 = this._reduceState(reducer_707);\n\t    return reducer_707.reduceYieldGeneratorExpression(this, state_708);\n\t  }\n\t  extend(attrs_709) {\n\t    return new YieldGeneratorExpression(Object.assign(this._cloneAttrs(), attrs_709));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceYieldGeneratorExpression = function (term_710, state_711) {\n\t  return new YieldGeneratorExpression(state_711);\n\t};\n\texports.YieldGeneratorExpression = YieldGeneratorExpression;\n\n\tclass ParenthesizedExpression extends Expression {\n\t  constructor(attrs_712, type_713) {\n\t    super(attrs_712, type_713 || \"ParenthesizedExpression\");\n\t    if (!{}.hasOwnProperty.call(attrs_712, \"inner\")) {\n\t      throw new Error(\"Missing attribute: \" + \"inner\");\n\t    }\n\t  }\n\t  _reduceState(reducer_714, state_715 = {}) {\n\t    state_715.inner = this.inner;\n\t    ;\n\t    return super._reduceState(reducer_714, state_715);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ inner: this.inner }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_716) {\n\t    let state_717 = this._reduceState(reducer_716);\n\t    return reducer_716.reduceParenthesizedExpression(this, state_717);\n\t  }\n\t  extend(attrs_718) {\n\t    return new ParenthesizedExpression(Object.assign(this._cloneAttrs(), attrs_718));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceParenthesizedExpression = function (term_719, state_720) {\n\t  return new ParenthesizedExpression(state_720);\n\t};\n\texports.ParenthesizedExpression = ParenthesizedExpression;\n\n\tclass BlockStatement extends Statement {\n\t  constructor(attrs_721, type_722) {\n\t    super(attrs_721, type_722 || \"BlockStatement\");\n\t    if (!{}.hasOwnProperty.call(attrs_721, \"block\")) {\n\t      throw new Error(\"Missing attribute: \" + \"block\");\n\t    }\n\t  }\n\t  _reduceState(reducer_723, state_724 = {}) {\n\t    state_724.block = this.block instanceof Block ? this.block.reduce(reducer_723) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.block));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_723, state_724);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ block: this.block }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_725) {\n\t    let state_726 = this._reduceState(reducer_725);\n\t    return reducer_725.reduceBlockStatement(this, state_726);\n\t  }\n\t  extend(attrs_727) {\n\t    return new BlockStatement(Object.assign(this._cloneAttrs(), attrs_727));\n\t  }\n\t}\n\tStatement.CloneReducer.prototype.reduceBlockStatement = function (term_728, state_729) {\n\t  return new BlockStatement(state_729);\n\t};\n\texports.BlockStatement = BlockStatement;\n\n\tclass BreakStatement extends Statement {\n\t  constructor(attrs_730, type_731) {\n\t    super(attrs_730, type_731 || \"BreakStatement\");\n\t    if (!{}.hasOwnProperty.call(attrs_730, \"label\")) {\n\t      throw new Error(\"Missing attribute: \" + \"label\");\n\t    }\n\t  }\n\t  _reduceState(reducer_732, state_733 = {}) {\n\t    state_733.label = this.label == null ? null : this.label;\n\t    ;\n\t    return super._reduceState(reducer_732, state_733);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ label: this.label }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_734) {\n\t    let state_735 = this._reduceState(reducer_734);\n\t    return reducer_734.reduceBreakStatement(this, state_735);\n\t  }\n\t  extend(attrs_736) {\n\t    return new BreakStatement(Object.assign(this._cloneAttrs(), attrs_736));\n\t  }\n\t}\n\tStatement.CloneReducer.prototype.reduceBreakStatement = function (term_737, state_738) {\n\t  return new BreakStatement(state_738);\n\t};\n\texports.BreakStatement = BreakStatement;\n\n\tclass ContinueStatement extends Statement {\n\t  constructor(attrs_739, type_740) {\n\t    super(attrs_739, type_740 || \"ContinueStatement\");\n\t    if (!{}.hasOwnProperty.call(attrs_739, \"label\")) {\n\t      throw new Error(\"Missing attribute: \" + \"label\");\n\t    }\n\t  }\n\t  _reduceState(reducer_741, state_742 = {}) {\n\t    state_742.label = this.label == null ? null : this.label;\n\t    ;\n\t    return super._reduceState(reducer_741, state_742);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ label: this.label }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_743) {\n\t    let state_744 = this._reduceState(reducer_743);\n\t    return reducer_743.reduceContinueStatement(this, state_744);\n\t  }\n\t  extend(attrs_745) {\n\t    return new ContinueStatement(Object.assign(this._cloneAttrs(), attrs_745));\n\t  }\n\t}\n\tStatement.CloneReducer.prototype.reduceContinueStatement = function (term_746, state_747) {\n\t  return new ContinueStatement(state_747);\n\t};\n\texports.ContinueStatement = ContinueStatement;\n\n\tclass DebuggerStatement extends Statement {\n\t  constructor(attrs_748, type_749) {\n\t    super(attrs_748, type_749 || \"DebuggerStatement\");\n\t  }\n\t  _reduceState(reducer_750, state_751 = {}) {\n\t    ;\n\t    return super._reduceState(reducer_750, state_751);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({}, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_752) {\n\t    let state_753 = this._reduceState(reducer_752);\n\t    return reducer_752.reduceDebuggerStatement(this, state_753);\n\t  }\n\t  extend(attrs_754) {\n\t    return new DebuggerStatement(Object.assign(this._cloneAttrs(), attrs_754));\n\t  }\n\t}\n\tStatement.CloneReducer.prototype.reduceDebuggerStatement = function (term_755, state_756) {\n\t  return new DebuggerStatement(state_756);\n\t};\n\texports.DebuggerStatement = DebuggerStatement;\n\n\tclass DoWhileStatement extends IterationStatement {\n\t  constructor(attrs_757, type_758) {\n\t    super(attrs_757, type_758 || \"DoWhileStatement\");\n\t    if (!{}.hasOwnProperty.call(attrs_757, \"test\")) {\n\t      throw new Error(\"Missing attribute: \" + \"test\");\n\t    }\n\t  }\n\t  _reduceState(reducer_759, state_760 = {}) {\n\t    state_760.test = this.test instanceof Expression ? this.test.reduce(reducer_759) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.test));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_759, state_760);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ test: this.test }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_761) {\n\t    let state_762 = this._reduceState(reducer_761);\n\t    return reducer_761.reduceDoWhileStatement(this, state_762);\n\t  }\n\t  extend(attrs_763) {\n\t    return new DoWhileStatement(Object.assign(this._cloneAttrs(), attrs_763));\n\t  }\n\t}\n\tIterationStatement.CloneReducer.prototype.reduceDoWhileStatement = function (term_764, state_765) {\n\t  return new DoWhileStatement(state_765);\n\t};\n\texports.DoWhileStatement = DoWhileStatement;\n\n\tclass EmptyStatement extends Statement {\n\t  constructor(attrs_766, type_767) {\n\t    super(attrs_766, type_767 || \"EmptyStatement\");\n\t  }\n\t  _reduceState(reducer_768, state_769 = {}) {\n\t    ;\n\t    return super._reduceState(reducer_768, state_769);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({}, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_770) {\n\t    let state_771 = this._reduceState(reducer_770);\n\t    return reducer_770.reduceEmptyStatement(this, state_771);\n\t  }\n\t  extend(attrs_772) {\n\t    return new EmptyStatement(Object.assign(this._cloneAttrs(), attrs_772));\n\t  }\n\t}\n\tStatement.CloneReducer.prototype.reduceEmptyStatement = function (term_773, state_774) {\n\t  return new EmptyStatement(state_774);\n\t};\n\texports.EmptyStatement = EmptyStatement;\n\n\tclass ExpressionStatement extends Statement {\n\t  constructor(attrs_775, type_776) {\n\t    super(attrs_775, type_776 || \"ExpressionStatement\");\n\t    if (!{}.hasOwnProperty.call(attrs_775, \"expression\")) {\n\t      throw new Error(\"Missing attribute: \" + \"expression\");\n\t    }\n\t  }\n\t  _reduceState(reducer_777, state_778 = {}) {\n\t    state_778.expression = this.expression instanceof Expression ? this.expression.reduce(reducer_777) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.expression));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_777, state_778);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ expression: this.expression }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_779) {\n\t    let state_780 = this._reduceState(reducer_779);\n\t    return reducer_779.reduceExpressionStatement(this, state_780);\n\t  }\n\t  extend(attrs_781) {\n\t    return new ExpressionStatement(Object.assign(this._cloneAttrs(), attrs_781));\n\t  }\n\t}\n\tStatement.CloneReducer.prototype.reduceExpressionStatement = function (term_782, state_783) {\n\t  return new ExpressionStatement(state_783);\n\t};\n\texports.ExpressionStatement = ExpressionStatement;\n\n\tclass ForInStatement extends IterationStatement {\n\t  constructor(attrs_784, type_785) {\n\t    super(attrs_784, type_785 || \"ForInStatement\");\n\t    if (!{}.hasOwnProperty.call(attrs_784, \"left\")) {\n\t      throw new Error(\"Missing attribute: \" + \"left\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_784, \"right\")) {\n\t      throw new Error(\"Missing attribute: \" + \"right\");\n\t    }\n\t  }\n\t  _reduceState(reducer_786, state_787 = {}) {\n\t    state_787.left = this.left instanceof VariableDeclaration ? this.left.reduce(reducer_786) : this.left instanceof ObjectBinding ? this.left.reduce(reducer_786) : this.left instanceof ArrayBinding ? this.left.reduce(reducer_786) : this.left instanceof BindingIdentifier ? this.left.reduce(reducer_786) : this.left instanceof MemberExpression ? this.left.reduce(reducer_786) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.left));\n\t    }.call(this);\n\t    state_787.right = this.right instanceof Expression ? this.right.reduce(reducer_786) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.right));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_786, state_787);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ left: this.left, right: this.right }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_788) {\n\t    let state_789 = this._reduceState(reducer_788);\n\t    return reducer_788.reduceForInStatement(this, state_789);\n\t  }\n\t  extend(attrs_790) {\n\t    return new ForInStatement(Object.assign(this._cloneAttrs(), attrs_790));\n\t  }\n\t}\n\tIterationStatement.CloneReducer.prototype.reduceForInStatement = function (term_791, state_792) {\n\t  return new ForInStatement(state_792);\n\t};\n\texports.ForInStatement = ForInStatement;\n\n\tclass ForOfStatement extends IterationStatement {\n\t  constructor(attrs_793, type_794) {\n\t    super(attrs_793, type_794 || \"ForOfStatement\");\n\t    if (!{}.hasOwnProperty.call(attrs_793, \"left\")) {\n\t      throw new Error(\"Missing attribute: \" + \"left\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_793, \"right\")) {\n\t      throw new Error(\"Missing attribute: \" + \"right\");\n\t    }\n\t  }\n\t  _reduceState(reducer_795, state_796 = {}) {\n\t    state_796.left = this.left instanceof VariableDeclaration ? this.left.reduce(reducer_795) : this.left instanceof ObjectBinding ? this.left.reduce(reducer_795) : this.left instanceof ArrayBinding ? this.left.reduce(reducer_795) : this.left instanceof BindingIdentifier ? this.left.reduce(reducer_795) : this.left instanceof MemberExpression ? this.left.reduce(reducer_795) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.left));\n\t    }.call(this);\n\t    state_796.right = this.right instanceof Expression ? this.right.reduce(reducer_795) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.right));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_795, state_796);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ left: this.left, right: this.right }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_797) {\n\t    let state_798 = this._reduceState(reducer_797);\n\t    return reducer_797.reduceForOfStatement(this, state_798);\n\t  }\n\t  extend(attrs_799) {\n\t    return new ForOfStatement(Object.assign(this._cloneAttrs(), attrs_799));\n\t  }\n\t}\n\tIterationStatement.CloneReducer.prototype.reduceForOfStatement = function (term_800, state_801) {\n\t  return new ForOfStatement(state_801);\n\t};\n\texports.ForOfStatement = ForOfStatement;\n\n\tclass ForStatement extends IterationStatement {\n\t  constructor(attrs_802, type_803) {\n\t    super(attrs_802, type_803 || \"ForStatement\");\n\t    if (!{}.hasOwnProperty.call(attrs_802, \"init\")) {\n\t      throw new Error(\"Missing attribute: \" + \"init\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_802, \"test\")) {\n\t      throw new Error(\"Missing attribute: \" + \"test\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_802, \"update\")) {\n\t      throw new Error(\"Missing attribute: \" + \"update\");\n\t    }\n\t  }\n\t  _reduceState(reducer_804, state_805 = {}) {\n\t    state_805.init = this.init == null ? null : this.init instanceof VariableDeclaration ? this.init.reduce(reducer_804) : this.init instanceof Expression ? this.init.reduce(reducer_804) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.init));\n\t    }.call(this);\n\t    state_805.test = this.test == null ? null : this.test instanceof Expression ? this.test.reduce(reducer_804) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.test));\n\t    }.call(this);\n\t    state_805.update = this.update == null ? null : this.update instanceof Expression ? this.update.reduce(reducer_804) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.update));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_804, state_805);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ init: this.init, test: this.test, update: this.update }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_806) {\n\t    let state_807 = this._reduceState(reducer_806);\n\t    return reducer_806.reduceForStatement(this, state_807);\n\t  }\n\t  extend(attrs_808) {\n\t    return new ForStatement(Object.assign(this._cloneAttrs(), attrs_808));\n\t  }\n\t}\n\tIterationStatement.CloneReducer.prototype.reduceForStatement = function (term_809, state_810) {\n\t  return new ForStatement(state_810);\n\t};\n\texports.ForStatement = ForStatement;\n\n\tclass IfStatement extends Statement {\n\t  constructor(attrs_811, type_812) {\n\t    super(attrs_811, type_812 || \"IfStatement\");\n\t    if (!{}.hasOwnProperty.call(attrs_811, \"test\")) {\n\t      throw new Error(\"Missing attribute: \" + \"test\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_811, \"consequent\")) {\n\t      throw new Error(\"Missing attribute: \" + \"consequent\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_811, \"alternate\")) {\n\t      throw new Error(\"Missing attribute: \" + \"alternate\");\n\t    }\n\t  }\n\t  _reduceState(reducer_813, state_814 = {}) {\n\t    state_814.test = this.test instanceof Expression ? this.test.reduce(reducer_813) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.test));\n\t    }.call(this);\n\t    state_814.consequent = this.consequent instanceof Statement ? this.consequent.reduce(reducer_813) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.consequent));\n\t    }.call(this);\n\t    state_814.alternate = this.alternate == null ? null : this.alternate instanceof Statement ? this.alternate.reduce(reducer_813) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.alternate));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_813, state_814);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ test: this.test, consequent: this.consequent, alternate: this.alternate }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_815) {\n\t    let state_816 = this._reduceState(reducer_815);\n\t    return reducer_815.reduceIfStatement(this, state_816);\n\t  }\n\t  extend(attrs_817) {\n\t    return new IfStatement(Object.assign(this._cloneAttrs(), attrs_817));\n\t  }\n\t}\n\tStatement.CloneReducer.prototype.reduceIfStatement = function (term_818, state_819) {\n\t  return new IfStatement(state_819);\n\t};\n\texports.IfStatement = IfStatement;\n\n\tclass LabeledStatement extends Statement {\n\t  constructor(attrs_820, type_821) {\n\t    super(attrs_820, type_821 || \"LabeledStatement\");\n\t    if (!{}.hasOwnProperty.call(attrs_820, \"label\")) {\n\t      throw new Error(\"Missing attribute: \" + \"label\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_820, \"body\")) {\n\t      throw new Error(\"Missing attribute: \" + \"body\");\n\t    }\n\t  }\n\t  _reduceState(reducer_822, state_823 = {}) {\n\t    state_823.label = this.label;\n\t    state_823.body = this.body instanceof Statement ? this.body.reduce(reducer_822) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.body));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_822, state_823);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ label: this.label, body: this.body }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_824) {\n\t    let state_825 = this._reduceState(reducer_824);\n\t    return reducer_824.reduceLabeledStatement(this, state_825);\n\t  }\n\t  extend(attrs_826) {\n\t    return new LabeledStatement(Object.assign(this._cloneAttrs(), attrs_826));\n\t  }\n\t}\n\tStatement.CloneReducer.prototype.reduceLabeledStatement = function (term_827, state_828) {\n\t  return new LabeledStatement(state_828);\n\t};\n\texports.LabeledStatement = LabeledStatement;\n\n\tclass ReturnStatement extends Statement {\n\t  constructor(attrs_829, type_830) {\n\t    super(attrs_829, type_830 || \"ReturnStatement\");\n\t    if (!{}.hasOwnProperty.call(attrs_829, \"expression\")) {\n\t      throw new Error(\"Missing attribute: \" + \"expression\");\n\t    }\n\t  }\n\t  _reduceState(reducer_831, state_832 = {}) {\n\t    state_832.expression = this.expression == null ? null : this.expression instanceof Expression ? this.expression.reduce(reducer_831) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.expression));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_831, state_832);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ expression: this.expression }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_833) {\n\t    let state_834 = this._reduceState(reducer_833);\n\t    return reducer_833.reduceReturnStatement(this, state_834);\n\t  }\n\t  extend(attrs_835) {\n\t    return new ReturnStatement(Object.assign(this._cloneAttrs(), attrs_835));\n\t  }\n\t}\n\tStatement.CloneReducer.prototype.reduceReturnStatement = function (term_836, state_837) {\n\t  return new ReturnStatement(state_837);\n\t};\n\texports.ReturnStatement = ReturnStatement;\n\n\tclass SwitchStatement extends Statement {\n\t  constructor(attrs_838, type_839) {\n\t    super(attrs_838, type_839 || \"SwitchStatement\");\n\t    if (!{}.hasOwnProperty.call(attrs_838, \"discriminant\")) {\n\t      throw new Error(\"Missing attribute: \" + \"discriminant\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_838, \"cases\")) {\n\t      throw new Error(\"Missing attribute: \" + \"cases\");\n\t    }\n\t  }\n\t  _reduceState(reducer_840, state_841 = {}) {\n\t    state_841.discriminant = this.discriminant instanceof Expression ? this.discriminant.reduce(reducer_840) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.discriminant));\n\t    }.call(this);\n\t    state_841.cases = this.cases.map(a_842 => a_842 instanceof SwitchCase ? a_842.reduce(reducer_840) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_842));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_840, state_841);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ discriminant: this.discriminant, cases: this.cases }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_843) {\n\t    let state_844 = this._reduceState(reducer_843);\n\t    return reducer_843.reduceSwitchStatement(this, state_844);\n\t  }\n\t  extend(attrs_845) {\n\t    return new SwitchStatement(Object.assign(this._cloneAttrs(), attrs_845));\n\t  }\n\t}\n\tStatement.CloneReducer.prototype.reduceSwitchStatement = function (term_846, state_847) {\n\t  return new SwitchStatement(state_847);\n\t};\n\texports.SwitchStatement = SwitchStatement;\n\n\tclass SwitchStatementWithDefault extends Statement {\n\t  constructor(attrs_848, type_849) {\n\t    super(attrs_848, type_849 || \"SwitchStatementWithDefault\");\n\t    if (!{}.hasOwnProperty.call(attrs_848, \"discriminant\")) {\n\t      throw new Error(\"Missing attribute: \" + \"discriminant\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_848, \"preDefaultCases\")) {\n\t      throw new Error(\"Missing attribute: \" + \"preDefaultCases\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_848, \"defaultCase\")) {\n\t      throw new Error(\"Missing attribute: \" + \"defaultCase\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_848, \"postDefaultCases\")) {\n\t      throw new Error(\"Missing attribute: \" + \"postDefaultCases\");\n\t    }\n\t  }\n\t  _reduceState(reducer_850, state_851 = {}) {\n\t    state_851.discriminant = this.discriminant instanceof Expression ? this.discriminant.reduce(reducer_850) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.discriminant));\n\t    }.call(this);\n\t    state_851.preDefaultCases = this.preDefaultCases.map(a_852 => a_852 instanceof SwitchCase ? a_852.reduce(reducer_850) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_852));\n\t    }.call(this));\n\t    state_851.defaultCase = this.defaultCase instanceof SwitchDefault ? this.defaultCase.reduce(reducer_850) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.defaultCase));\n\t    }.call(this);\n\t    state_851.postDefaultCases = this.postDefaultCases.map(a_853 => a_853 instanceof SwitchCase ? a_853.reduce(reducer_850) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_853));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_850, state_851);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ discriminant: this.discriminant, preDefaultCases: this.preDefaultCases, defaultCase: this.defaultCase, postDefaultCases: this.postDefaultCases }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_854) {\n\t    let state_855 = this._reduceState(reducer_854);\n\t    return reducer_854.reduceSwitchStatementWithDefault(this, state_855);\n\t  }\n\t  extend(attrs_856) {\n\t    return new SwitchStatementWithDefault(Object.assign(this._cloneAttrs(), attrs_856));\n\t  }\n\t}\n\tStatement.CloneReducer.prototype.reduceSwitchStatementWithDefault = function (term_857, state_858) {\n\t  return new SwitchStatementWithDefault(state_858);\n\t};\n\texports.SwitchStatementWithDefault = SwitchStatementWithDefault;\n\n\tclass ThrowStatement extends Statement {\n\t  constructor(attrs_859, type_860) {\n\t    super(attrs_859, type_860 || \"ThrowStatement\");\n\t    if (!{}.hasOwnProperty.call(attrs_859, \"expression\")) {\n\t      throw new Error(\"Missing attribute: \" + \"expression\");\n\t    }\n\t  }\n\t  _reduceState(reducer_861, state_862 = {}) {\n\t    state_862.expression = this.expression instanceof Expression ? this.expression.reduce(reducer_861) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.expression));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_861, state_862);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ expression: this.expression }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_863) {\n\t    let state_864 = this._reduceState(reducer_863);\n\t    return reducer_863.reduceThrowStatement(this, state_864);\n\t  }\n\t  extend(attrs_865) {\n\t    return new ThrowStatement(Object.assign(this._cloneAttrs(), attrs_865));\n\t  }\n\t}\n\tStatement.CloneReducer.prototype.reduceThrowStatement = function (term_866, state_867) {\n\t  return new ThrowStatement(state_867);\n\t};\n\texports.ThrowStatement = ThrowStatement;\n\n\tclass TryCatchStatement extends Statement {\n\t  constructor(attrs_868, type_869) {\n\t    super(attrs_868, type_869 || \"TryCatchStatement\");\n\t    if (!{}.hasOwnProperty.call(attrs_868, \"body\")) {\n\t      throw new Error(\"Missing attribute: \" + \"body\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_868, \"catchClause\")) {\n\t      throw new Error(\"Missing attribute: \" + \"catchClause\");\n\t    }\n\t  }\n\t  _reduceState(reducer_870, state_871 = {}) {\n\t    state_871.body = this.body instanceof Block ? this.body.reduce(reducer_870) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.body));\n\t    }.call(this);\n\t    state_871.catchClause = this.catchClause instanceof CatchClause ? this.catchClause.reduce(reducer_870) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.catchClause));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_870, state_871);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ body: this.body, catchClause: this.catchClause }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_872) {\n\t    let state_873 = this._reduceState(reducer_872);\n\t    return reducer_872.reduceTryCatchStatement(this, state_873);\n\t  }\n\t  extend(attrs_874) {\n\t    return new TryCatchStatement(Object.assign(this._cloneAttrs(), attrs_874));\n\t  }\n\t}\n\tStatement.CloneReducer.prototype.reduceTryCatchStatement = function (term_875, state_876) {\n\t  return new TryCatchStatement(state_876);\n\t};\n\texports.TryCatchStatement = TryCatchStatement;\n\n\tclass TryFinallyStatement extends Statement {\n\t  constructor(attrs_877, type_878) {\n\t    super(attrs_877, type_878 || \"TryFinallyStatement\");\n\t    if (!{}.hasOwnProperty.call(attrs_877, \"body\")) {\n\t      throw new Error(\"Missing attribute: \" + \"body\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_877, \"catchClause\")) {\n\t      throw new Error(\"Missing attribute: \" + \"catchClause\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_877, \"finalizer\")) {\n\t      throw new Error(\"Missing attribute: \" + \"finalizer\");\n\t    }\n\t  }\n\t  _reduceState(reducer_879, state_880 = {}) {\n\t    state_880.body = this.body instanceof Block ? this.body.reduce(reducer_879) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.body));\n\t    }.call(this);\n\t    state_880.catchClause = this.catchClause == null ? null : this.catchClause instanceof CatchClause ? this.catchClause.reduce(reducer_879) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.catchClause));\n\t    }.call(this);\n\t    state_880.finalizer = this.finalizer instanceof Block ? this.finalizer.reduce(reducer_879) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.finalizer));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_879, state_880);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ body: this.body, catchClause: this.catchClause, finalizer: this.finalizer }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_881) {\n\t    let state_882 = this._reduceState(reducer_881);\n\t    return reducer_881.reduceTryFinallyStatement(this, state_882);\n\t  }\n\t  extend(attrs_883) {\n\t    return new TryFinallyStatement(Object.assign(this._cloneAttrs(), attrs_883));\n\t  }\n\t}\n\tStatement.CloneReducer.prototype.reduceTryFinallyStatement = function (term_884, state_885) {\n\t  return new TryFinallyStatement(state_885);\n\t};\n\texports.TryFinallyStatement = TryFinallyStatement;\n\n\tclass VariableDeclarationStatement extends Statement {\n\t  constructor(attrs_886, type_887) {\n\t    super(attrs_886, type_887 || \"VariableDeclarationStatement\");\n\t    if (!{}.hasOwnProperty.call(attrs_886, \"declaration\")) {\n\t      throw new Error(\"Missing attribute: \" + \"declaration\");\n\t    }\n\t  }\n\t  _reduceState(reducer_888, state_889 = {}) {\n\t    state_889.declaration = this.declaration instanceof VariableDeclaration ? this.declaration.reduce(reducer_888) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.declaration));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_888, state_889);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ declaration: this.declaration }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_890) {\n\t    let state_891 = this._reduceState(reducer_890);\n\t    return reducer_890.reduceVariableDeclarationStatement(this, state_891);\n\t  }\n\t  extend(attrs_892) {\n\t    return new VariableDeclarationStatement(Object.assign(this._cloneAttrs(), attrs_892));\n\t  }\n\t}\n\tStatement.CloneReducer.prototype.reduceVariableDeclarationStatement = function (term_893, state_894) {\n\t  return new VariableDeclarationStatement(state_894);\n\t};\n\texports.VariableDeclarationStatement = VariableDeclarationStatement;\n\n\tclass WithStatement extends Statement {\n\t  constructor(attrs_895, type_896) {\n\t    super(attrs_895, type_896 || \"WithStatement\");\n\t    if (!{}.hasOwnProperty.call(attrs_895, \"object\")) {\n\t      throw new Error(\"Missing attribute: \" + \"object\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_895, \"body\")) {\n\t      throw new Error(\"Missing attribute: \" + \"body\");\n\t    }\n\t  }\n\t  _reduceState(reducer_897, state_898 = {}) {\n\t    state_898.object = this.object instanceof Expression ? this.object.reduce(reducer_897) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.object));\n\t    }.call(this);\n\t    state_898.body = this.body instanceof Statement ? this.body.reduce(reducer_897) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.body));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_897, state_898);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ object: this.object, body: this.body }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_899) {\n\t    let state_900 = this._reduceState(reducer_899);\n\t    return reducer_899.reduceWithStatement(this, state_900);\n\t  }\n\t  extend(attrs_901) {\n\t    return new WithStatement(Object.assign(this._cloneAttrs(), attrs_901));\n\t  }\n\t}\n\tStatement.CloneReducer.prototype.reduceWithStatement = function (term_902, state_903) {\n\t  return new WithStatement(state_903);\n\t};\n\texports.WithStatement = WithStatement;\n\n\tclass WhileStatement extends IterationStatement {\n\t  constructor(attrs_904, type_905) {\n\t    super(attrs_904, type_905 || \"WhileStatement\");\n\t    if (!{}.hasOwnProperty.call(attrs_904, \"test\")) {\n\t      throw new Error(\"Missing attribute: \" + \"test\");\n\t    }\n\t  }\n\t  _reduceState(reducer_906, state_907 = {}) {\n\t    state_907.test = this.test instanceof Expression ? this.test.reduce(reducer_906) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.test));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_906, state_907);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ test: this.test }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_908) {\n\t    let state_909 = this._reduceState(reducer_908);\n\t    return reducer_908.reduceWhileStatement(this, state_909);\n\t  }\n\t  extend(attrs_910) {\n\t    return new WhileStatement(Object.assign(this._cloneAttrs(), attrs_910));\n\t  }\n\t}\n\tIterationStatement.CloneReducer.prototype.reduceWhileStatement = function (term_911, state_912) {\n\t  return new WhileStatement(state_912);\n\t};\n\texports.WhileStatement = WhileStatement;\n\n\tclass Pragma extends Term {\n\t  constructor(attrs_913, type_914) {\n\t    super(attrs_913, type_914 || \"Pragma\");\n\t    if (!{}.hasOwnProperty.call(attrs_913, \"kind\")) {\n\t      throw new Error(\"Missing attribute: \" + \"kind\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_913, \"items\")) {\n\t      throw new Error(\"Missing attribute: \" + \"items\");\n\t    }\n\t  }\n\t  _reduceState(reducer_915, state_916 = {}) {\n\t    state_916.kind = this.kind;\n\t    state_916.items = this.items;\n\t    ;\n\t    return super._reduceState(reducer_915, state_916);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ kind: this.kind, items: this.items }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_917) {\n\t    let state_918 = this._reduceState(reducer_917);\n\t    return reducer_917.reducePragma(this, state_918);\n\t  }\n\t  extend(attrs_919) {\n\t    return new Pragma(Object.assign(this._cloneAttrs(), attrs_919));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reducePragma = function (term_920, state_921) {\n\t  return new Pragma(state_921);\n\t};\n\texports.Pragma = Pragma;\n\n\tclass Block extends Term {\n\t  constructor(attrs_922, type_923) {\n\t    super(attrs_922, type_923 || \"Block\");\n\t    if (!{}.hasOwnProperty.call(attrs_922, \"statements\")) {\n\t      throw new Error(\"Missing attribute: \" + \"statements\");\n\t    }\n\t  }\n\t  _reduceState(reducer_924, state_925 = {}) {\n\t    state_925.statements = this.statements.map(a_926 => a_926 instanceof Statement ? a_926.reduce(reducer_924) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_926));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_924, state_925);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ statements: this.statements }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_927) {\n\t    let state_928 = this._reduceState(reducer_927);\n\t    return reducer_927.reduceBlock(this, state_928);\n\t  }\n\t  extend(attrs_929) {\n\t    return new Block(Object.assign(this._cloneAttrs(), attrs_929));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceBlock = function (term_930, state_931) {\n\t  return new Block(state_931);\n\t};\n\texports.Block = Block;\n\n\tclass CatchClause extends Term {\n\t  constructor(attrs_932, type_933) {\n\t    super(attrs_932, type_933 || \"CatchClause\");\n\t    if (!{}.hasOwnProperty.call(attrs_932, \"binding\")) {\n\t      throw new Error(\"Missing attribute: \" + \"binding\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_932, \"body\")) {\n\t      throw new Error(\"Missing attribute: \" + \"body\");\n\t    }\n\t  }\n\t  _reduceState(reducer_934, state_935 = {}) {\n\t    state_935.binding = this.binding instanceof ObjectBinding ? this.binding.reduce(reducer_934) : this.binding instanceof ArrayBinding ? this.binding.reduce(reducer_934) : this.binding instanceof BindingIdentifier ? this.binding.reduce(reducer_934) : this.binding instanceof MemberExpression ? this.binding.reduce(reducer_934) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.binding));\n\t    }.call(this);\n\t    state_935.body = this.body instanceof Block ? this.body.reduce(reducer_934) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.body));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_934, state_935);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ binding: this.binding, body: this.body }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_936) {\n\t    let state_937 = this._reduceState(reducer_936);\n\t    return reducer_936.reduceCatchClause(this, state_937);\n\t  }\n\t  extend(attrs_938) {\n\t    return new CatchClause(Object.assign(this._cloneAttrs(), attrs_938));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceCatchClause = function (term_939, state_940) {\n\t  return new CatchClause(state_940);\n\t};\n\texports.CatchClause = CatchClause;\n\n\tclass Directive extends Term {\n\t  constructor(attrs_941, type_942) {\n\t    super(attrs_941, type_942 || \"Directive\");\n\t    if (!{}.hasOwnProperty.call(attrs_941, \"rawValue\")) {\n\t      throw new Error(\"Missing attribute: \" + \"rawValue\");\n\t    }\n\t  }\n\t  _reduceState(reducer_943, state_944 = {}) {\n\t    state_944.rawValue = this.rawValue;\n\t    ;\n\t    return super._reduceState(reducer_943, state_944);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ rawValue: this.rawValue }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_945) {\n\t    let state_946 = this._reduceState(reducer_945);\n\t    return reducer_945.reduceDirective(this, state_946);\n\t  }\n\t  extend(attrs_947) {\n\t    return new Directive(Object.assign(this._cloneAttrs(), attrs_947));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceDirective = function (term_948, state_949) {\n\t  return new Directive(state_949);\n\t};\n\texports.Directive = Directive;\n\n\tclass FormalParameters extends Term {\n\t  constructor(attrs_950, type_951) {\n\t    super(attrs_950, type_951 || \"FormalParameters\");\n\t    if (!{}.hasOwnProperty.call(attrs_950, \"items\")) {\n\t      throw new Error(\"Missing attribute: \" + \"items\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_950, \"rest\")) {\n\t      throw new Error(\"Missing attribute: \" + \"rest\");\n\t    }\n\t  }\n\t  _reduceState(reducer_952, state_953 = {}) {\n\t    state_953.items = this.items.map(a_954 => a_954 instanceof ObjectBinding ? a_954.reduce(reducer_952) : a_954 instanceof ArrayBinding ? a_954.reduce(reducer_952) : a_954 instanceof BindingIdentifier ? a_954.reduce(reducer_952) : a_954 instanceof MemberExpression ? a_954.reduce(reducer_952) : a_954 instanceof BindingWithDefault ? a_954.reduce(reducer_952) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_954));\n\t    }.call(this));\n\t    state_953.rest = this.rest == null ? null : this.rest instanceof BindingIdentifier ? this.rest.reduce(reducer_952) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.rest));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_952, state_953);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ items: this.items, rest: this.rest }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_955) {\n\t    let state_956 = this._reduceState(reducer_955);\n\t    return reducer_955.reduceFormalParameters(this, state_956);\n\t  }\n\t  extend(attrs_957) {\n\t    return new FormalParameters(Object.assign(this._cloneAttrs(), attrs_957));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceFormalParameters = function (term_958, state_959) {\n\t  return new FormalParameters(state_959);\n\t};\n\texports.FormalParameters = FormalParameters;\n\n\tclass FunctionBody extends Term {\n\t  constructor(attrs_960, type_961) {\n\t    super(attrs_960, type_961 || \"FunctionBody\");\n\t    if (!{}.hasOwnProperty.call(attrs_960, \"directives\")) {\n\t      throw new Error(\"Missing attribute: \" + \"directives\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_960, \"statements\")) {\n\t      throw new Error(\"Missing attribute: \" + \"statements\");\n\t    }\n\t  }\n\t  _reduceState(reducer_962, state_963 = {}) {\n\t    state_963.directives = this.directives.map(a_964 => a_964);\n\t    state_963.statements = this.statements.map(a_965 => a_965 instanceof Statement ? a_965.reduce(reducer_962) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_965));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_962, state_963);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ directives: this.directives, statements: this.statements }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_966) {\n\t    let state_967 = this._reduceState(reducer_966);\n\t    return reducer_966.reduceFunctionBody(this, state_967);\n\t  }\n\t  extend(attrs_968) {\n\t    return new FunctionBody(Object.assign(this._cloneAttrs(), attrs_968));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceFunctionBody = function (term_969, state_970) {\n\t  return new FunctionBody(state_970);\n\t};\n\texports.FunctionBody = FunctionBody;\n\n\tclass FunctionDeclaration extends Statement {\n\t  constructor(attrs_971, type_972) {\n\t    super(attrs_971, type_972 || \"FunctionDeclaration\");\n\t    if (!{}.hasOwnProperty.call(attrs_971, \"name\")) {\n\t      throw new Error(\"Missing attribute: \" + \"name\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_971, \"isGenerator\")) {\n\t      throw new Error(\"Missing attribute: \" + \"isGenerator\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_971, \"params\")) {\n\t      throw new Error(\"Missing attribute: \" + \"params\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_971, \"body\")) {\n\t      throw new Error(\"Missing attribute: \" + \"body\");\n\t    }\n\t  }\n\t  _reduceState(reducer_973, state_974 = {}) {\n\t    state_974.name = this.name instanceof BindingIdentifier ? this.name.reduce(reducer_973) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.name));\n\t    }.call(this);\n\t    state_974.isGenerator = this.isGenerator;\n\t    state_974.params = this.params instanceof FormalParameters ? this.params.reduce(reducer_973) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.params));\n\t    }.call(this);\n\t    state_974.body = this.body instanceof FunctionBody ? this.body.reduce(reducer_973) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.body));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_973, state_974);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ name: this.name, isGenerator: this.isGenerator, params: this.params, body: this.body }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_975) {\n\t    let state_976 = this._reduceState(reducer_975);\n\t    return reducer_975.reduceFunctionDeclaration(this, state_976);\n\t  }\n\t  extend(attrs_977) {\n\t    return new FunctionDeclaration(Object.assign(this._cloneAttrs(), attrs_977));\n\t  }\n\t}\n\tStatement.CloneReducer.prototype.reduceFunctionDeclaration = function (term_978, state_979) {\n\t  return new FunctionDeclaration(state_979);\n\t};\n\texports.FunctionDeclaration = FunctionDeclaration;\n\n\tclass FunctionDeclarationE extends Statement {\n\t  constructor(attrs_980, type_981) {\n\t    super(attrs_980, type_981 || \"FunctionDeclarationE\");\n\t    if (!{}.hasOwnProperty.call(attrs_980, \"name\")) {\n\t      throw new Error(\"Missing attribute: \" + \"name\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_980, \"isGenerator\")) {\n\t      throw new Error(\"Missing attribute: \" + \"isGenerator\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_980, \"params\")) {\n\t      throw new Error(\"Missing attribute: \" + \"params\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_980, \"body\")) {\n\t      throw new Error(\"Missing attribute: \" + \"body\");\n\t    }\n\t  }\n\t  _reduceState(reducer_982, state_983 = {}) {\n\t    state_983.name = this.name instanceof BindingIdentifier ? this.name.reduce(reducer_982) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.name));\n\t    }.call(this);\n\t    state_983.isGenerator = this.isGenerator;\n\t    state_983.params = this.params instanceof FormalParameters ? this.params.reduce(reducer_982) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.params));\n\t    }.call(this);\n\t    state_983.body = this.body.map(a_984 => a_984 instanceof Term ? a_984.reduce(reducer_982) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_984));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_982, state_983);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ name: this.name, isGenerator: this.isGenerator, params: this.params, body: this.body }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_985) {\n\t    let state_986 = this._reduceState(reducer_985);\n\t    return reducer_985.reduceFunctionDeclarationE(this, state_986);\n\t  }\n\t  extend(attrs_987) {\n\t    return new FunctionDeclarationE(Object.assign(this._cloneAttrs(), attrs_987));\n\t  }\n\t}\n\tStatement.CloneReducer.prototype.reduceFunctionDeclarationE = function (term_988, state_989) {\n\t  return new FunctionDeclarationE(state_989);\n\t};\n\texports.FunctionDeclarationE = FunctionDeclarationE;\n\n\tclass Script extends Term {\n\t  constructor(attrs_990, type_991) {\n\t    super(attrs_990, type_991 || \"Script\");\n\t    if (!{}.hasOwnProperty.call(attrs_990, \"directives\")) {\n\t      throw new Error(\"Missing attribute: \" + \"directives\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_990, \"statements\")) {\n\t      throw new Error(\"Missing attribute: \" + \"statements\");\n\t    }\n\t  }\n\t  _reduceState(reducer_992, state_993 = {}) {\n\t    state_993.directives = this.directives.map(a_994 => a_994);\n\t    state_993.statements = this.statements.map(a_995 => a_995 instanceof Statement ? a_995.reduce(reducer_992) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_995));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_992, state_993);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ directives: this.directives, statements: this.statements }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_996) {\n\t    let state_997 = this._reduceState(reducer_996);\n\t    return reducer_996.reduceScript(this, state_997);\n\t  }\n\t  extend(attrs_998) {\n\t    return new Script(Object.assign(this._cloneAttrs(), attrs_998));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceScript = function (term_999, state_1000) {\n\t  return new Script(state_1000);\n\t};\n\texports.Script = Script;\n\n\tclass SpreadElement extends Term {\n\t  constructor(attrs_1001, type_1002) {\n\t    super(attrs_1001, type_1002 || \"SpreadElement\");\n\t    if (!{}.hasOwnProperty.call(attrs_1001, \"expression\")) {\n\t      throw new Error(\"Missing attribute: \" + \"expression\");\n\t    }\n\t  }\n\t  _reduceState(reducer_1003, state_1004 = {}) {\n\t    state_1004.expression = this.expression instanceof Expression ? this.expression.reduce(reducer_1003) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.expression));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_1003, state_1004);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ expression: this.expression }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_1005) {\n\t    let state_1006 = this._reduceState(reducer_1005);\n\t    return reducer_1005.reduceSpreadElement(this, state_1006);\n\t  }\n\t  extend(attrs_1007) {\n\t    return new SpreadElement(Object.assign(this._cloneAttrs(), attrs_1007));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceSpreadElement = function (term_1008, state_1009) {\n\t  return new SpreadElement(state_1009);\n\t};\n\texports.SpreadElement = SpreadElement;\n\n\tclass Super extends Term {\n\t  constructor(attrs_1010, type_1011) {\n\t    super(attrs_1010, type_1011 || \"Super\");\n\t  }\n\t  _reduceState(reducer_1012, state_1013 = {}) {\n\t    ;\n\t    return super._reduceState(reducer_1012, state_1013);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({}, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_1014) {\n\t    let state_1015 = this._reduceState(reducer_1014);\n\t    return reducer_1014.reduceSuper(this, state_1015);\n\t  }\n\t  extend(attrs_1016) {\n\t    return new Super(Object.assign(this._cloneAttrs(), attrs_1016));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceSuper = function (term_1017, state_1018) {\n\t  return new Super(state_1018);\n\t};\n\texports.Super = Super;\n\n\tclass SwitchCase extends Term {\n\t  constructor(attrs_1019, type_1020) {\n\t    super(attrs_1019, type_1020 || \"SwitchCase\");\n\t    if (!{}.hasOwnProperty.call(attrs_1019, \"test\")) {\n\t      throw new Error(\"Missing attribute: \" + \"test\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_1019, \"consequent\")) {\n\t      throw new Error(\"Missing attribute: \" + \"consequent\");\n\t    }\n\t  }\n\t  _reduceState(reducer_1021, state_1022 = {}) {\n\t    state_1022.test = this.test instanceof Expression ? this.test.reduce(reducer_1021) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.test));\n\t    }.call(this);\n\t    state_1022.consequent = this.consequent.map(a_1023 => a_1023 instanceof Statement ? a_1023.reduce(reducer_1021) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_1023));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_1021, state_1022);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ test: this.test, consequent: this.consequent }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_1024) {\n\t    let state_1025 = this._reduceState(reducer_1024);\n\t    return reducer_1024.reduceSwitchCase(this, state_1025);\n\t  }\n\t  extend(attrs_1026) {\n\t    return new SwitchCase(Object.assign(this._cloneAttrs(), attrs_1026));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceSwitchCase = function (term_1027, state_1028) {\n\t  return new SwitchCase(state_1028);\n\t};\n\texports.SwitchCase = SwitchCase;\n\n\tclass SwitchDefault extends Term {\n\t  constructor(attrs_1029, type_1030) {\n\t    super(attrs_1029, type_1030 || \"SwitchDefault\");\n\t    if (!{}.hasOwnProperty.call(attrs_1029, \"consequent\")) {\n\t      throw new Error(\"Missing attribute: \" + \"consequent\");\n\t    }\n\t  }\n\t  _reduceState(reducer_1031, state_1032 = {}) {\n\t    state_1032.consequent = this.consequent.map(a_1033 => a_1033 instanceof Statement ? a_1033.reduce(reducer_1031) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_1033));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_1031, state_1032);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ consequent: this.consequent }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_1034) {\n\t    let state_1035 = this._reduceState(reducer_1034);\n\t    return reducer_1034.reduceSwitchDefault(this, state_1035);\n\t  }\n\t  extend(attrs_1036) {\n\t    return new SwitchDefault(Object.assign(this._cloneAttrs(), attrs_1036));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceSwitchDefault = function (term_1037, state_1038) {\n\t  return new SwitchDefault(state_1038);\n\t};\n\texports.SwitchDefault = SwitchDefault;\n\n\tclass TemplateElement extends Term {\n\t  constructor(attrs_1039, type_1040) {\n\t    super(attrs_1039, type_1040 || \"TemplateElement\");\n\t    if (!{}.hasOwnProperty.call(attrs_1039, \"rawValue\")) {\n\t      throw new Error(\"Missing attribute: \" + \"rawValue\");\n\t    }\n\t  }\n\t  _reduceState(reducer_1041, state_1042 = {}) {\n\t    state_1042.rawValue = this.rawValue;\n\t    ;\n\t    return super._reduceState(reducer_1041, state_1042);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ rawValue: this.rawValue }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_1043) {\n\t    let state_1044 = this._reduceState(reducer_1043);\n\t    return reducer_1043.reduceTemplateElement(this, state_1044);\n\t  }\n\t  extend(attrs_1045) {\n\t    return new TemplateElement(Object.assign(this._cloneAttrs(), attrs_1045));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceTemplateElement = function (term_1046, state_1047) {\n\t  return new TemplateElement(state_1047);\n\t};\n\texports.TemplateElement = TemplateElement;\n\n\tclass SyntaxTemplate extends Expression {\n\t  constructor(attrs_1048, type_1049) {\n\t    super(attrs_1048, type_1049 || \"SyntaxTemplate\");\n\t    if (!{}.hasOwnProperty.call(attrs_1048, \"template\")) {\n\t      throw new Error(\"Missing attribute: \" + \"template\");\n\t    }\n\t  }\n\t  _reduceState(reducer_1050, state_1051 = {}) {\n\t    state_1051.template = this.template.map(a_1052 => a_1052 instanceof SyntaxTerm ? a_1052.reduce(reducer_1050) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_1052));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_1050, state_1051);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ template: this.template }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_1053) {\n\t    let state_1054 = this._reduceState(reducer_1053);\n\t    return reducer_1053.reduceSyntaxTemplate(this, state_1054);\n\t  }\n\t  extend(attrs_1055) {\n\t    return new SyntaxTemplate(Object.assign(this._cloneAttrs(), attrs_1055));\n\t  }\n\t}\n\tExpression.CloneReducer.prototype.reduceSyntaxTemplate = function (term_1056, state_1057) {\n\t  return new SyntaxTemplate(state_1057);\n\t};\n\texports.SyntaxTemplate = SyntaxTemplate;\n\n\tclass SyntaxQuote extends Term {\n\t  constructor(attrs_1058, type_1059) {\n\t    super(attrs_1058, type_1059 || \"SyntaxQuote\");\n\t    if (!{}.hasOwnProperty.call(attrs_1058, \"name\")) {\n\t      throw new Error(\"Missing attribute: \" + \"name\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_1058, \"template\")) {\n\t      throw new Error(\"Missing attribute: \" + \"template\");\n\t    }\n\t  }\n\t  _reduceState(reducer_1060, state_1061 = {}) {\n\t    state_1061.name = this.name;\n\t    state_1061.template = this.template;\n\t    ;\n\t    return super._reduceState(reducer_1060, state_1061);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ name: this.name, template: this.template }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_1062) {\n\t    let state_1063 = this._reduceState(reducer_1062);\n\t    return reducer_1062.reduceSyntaxQuote(this, state_1063);\n\t  }\n\t  extend(attrs_1064) {\n\t    return new SyntaxQuote(Object.assign(this._cloneAttrs(), attrs_1064));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceSyntaxQuote = function (term_1065, state_1066) {\n\t  return new SyntaxQuote(state_1066);\n\t};\n\texports.SyntaxQuote = SyntaxQuote;\n\n\tclass VariableDeclaration extends Term {\n\t  constructor(attrs_1067, type_1068) {\n\t    super(attrs_1067, type_1068 || \"VariableDeclaration\");\n\t    if (!{}.hasOwnProperty.call(attrs_1067, \"kind\")) {\n\t      throw new Error(\"Missing attribute: \" + \"kind\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_1067, \"declarators\")) {\n\t      throw new Error(\"Missing attribute: \" + \"declarators\");\n\t    }\n\t  }\n\t  _reduceState(reducer_1069, state_1070 = {}) {\n\t    state_1070.kind = this.kind;\n\t    state_1070.declarators = this.declarators.map(a_1071 => a_1071 instanceof VariableDeclarator ? a_1071.reduce(reducer_1069) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(a_1071));\n\t    }.call(this));\n\t    ;\n\t    return super._reduceState(reducer_1069, state_1070);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ kind: this.kind, declarators: this.declarators }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_1072) {\n\t    let state_1073 = this._reduceState(reducer_1072);\n\t    return reducer_1072.reduceVariableDeclaration(this, state_1073);\n\t  }\n\t  extend(attrs_1074) {\n\t    return new VariableDeclaration(Object.assign(this._cloneAttrs(), attrs_1074));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceVariableDeclaration = function (term_1075, state_1076) {\n\t  return new VariableDeclaration(state_1076);\n\t};\n\texports.VariableDeclaration = VariableDeclaration;\n\n\tclass VariableDeclarator extends Term {\n\t  constructor(attrs_1077, type_1078) {\n\t    super(attrs_1077, type_1078 || \"VariableDeclarator\");\n\t    if (!{}.hasOwnProperty.call(attrs_1077, \"binding\")) {\n\t      throw new Error(\"Missing attribute: \" + \"binding\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_1077, \"init\")) {\n\t      throw new Error(\"Missing attribute: \" + \"init\");\n\t    }\n\t  }\n\t  _reduceState(reducer_1079, state_1080 = {}) {\n\t    state_1080.binding = this.binding instanceof ObjectBinding ? this.binding.reduce(reducer_1079) : this.binding instanceof ArrayBinding ? this.binding.reduce(reducer_1079) : this.binding instanceof BindingIdentifier ? this.binding.reduce(reducer_1079) : this.binding instanceof MemberExpression ? this.binding.reduce(reducer_1079) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.binding));\n\t    }.call(this);\n\t    state_1080.init = this.init == null ? null : this.init instanceof Expression ? this.init.reduce(reducer_1079) : function () {\n\t      throw new Error(\"Unknown object: \" + JSON.stringify(this.init));\n\t    }.call(this);\n\t    ;\n\t    return super._reduceState(reducer_1079, state_1080);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ binding: this.binding, init: this.init }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_1081) {\n\t    let state_1082 = this._reduceState(reducer_1081);\n\t    return reducer_1081.reduceVariableDeclarator(this, state_1082);\n\t  }\n\t  extend(attrs_1083) {\n\t    return new VariableDeclarator(Object.assign(this._cloneAttrs(), attrs_1083));\n\t  }\n\t}\n\tTerm.CloneReducer.prototype.reduceVariableDeclarator = function (term_1084, state_1085) {\n\t  return new VariableDeclarator(state_1085);\n\t};\n\texports.VariableDeclarator = VariableDeclarator;\n\n\tclass OperatorDeclarator extends VariableDeclarator {\n\t  constructor(attrs_1086, type_1087) {\n\t    super(attrs_1086, type_1087 || \"OperatorDeclarator\");\n\t    if (!{}.hasOwnProperty.call(attrs_1086, \"prec\")) {\n\t      throw new Error(\"Missing attribute: \" + \"prec\");\n\t    }\n\t    if (!{}.hasOwnProperty.call(attrs_1086, \"assoc\")) {\n\t      throw new Error(\"Missing attribute: \" + \"assoc\");\n\t    }\n\t  }\n\t  _reduceState(reducer_1088, state_1089 = {}) {\n\t    state_1089.prec = this.prec;\n\t    state_1089.assoc = this.assoc;\n\t    ;\n\t    return super._reduceState(reducer_1088, state_1089);\n\t  }\n\t  _cloneAttrs() {\n\t    return Object.assign({ prec: this.prec, assoc: this.assoc }, super._cloneAttrs());\n\t  }\n\t  reduce(reducer_1090) {\n\t    let state_1091 = this._reduceState(reducer_1090);\n\t    return reducer_1090.reduceOperatorDeclarator(this, state_1091);\n\t  }\n\t  extend(attrs_1092) {\n\t    return new OperatorDeclarator(Object.assign(this._cloneAttrs(), attrs_1092));\n\t  }\n\t}\n\tVariableDeclarator.CloneReducer.prototype.reduceOperatorDeclarator = function (term_1093, state_1094) {\n\t  return new OperatorDeclarator(state_1094);\n\t};\n\texports.OperatorDeclarator = OperatorDeclarator;\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL2J1aWxkL3Rlcm0tc3BlYy5qcyJdLCJuYW1lcyI6WyJUZXJtIiwiY29uc3RydWN0b3IiLCJhdHRyc182MyIsInR5cGVfNjQiLCJPYmplY3QiLCJhc3NpZ24iLCJ0eXBlIiwibG9jIiwiZnJlZXplIiwiX3JlZHVjZVN0YXRlIiwicmVkdWNlcl82NSIsInN0YXRlXzY2IiwiX2Nsb25lQXR0cnMiLCJyZWR1Y2UiLCJyZWR1Y2VyXzY3Iiwic3RhdGVfNjgiLCJyZWR1Y2VUZXJtIiwiZXh0ZW5kIiwiYXR0cnNfNjkiLCJmcm9tIiwidHlwZV83MCIsInZhbHVlXzcxIiwidmFsdWUiLCJFcnJvciIsImZyb21OdWxsIiwiZnJvbU51bWJlciIsInZhbHVlXzcyIiwiZnJvbVN0cmluZyIsInZhbHVlXzczIiwiZnJvbVB1bmN0dWF0b3IiLCJ2YWx1ZV83NCIsImZyb21LZXl3b3JkIiwidmFsdWVfNzUiLCJmcm9tSWRlbnRpZmllciIsInZhbHVlXzc2IiwiZnJvbVJlZ3VsYXJFeHByZXNzaW9uIiwidmFsdWVfNzciLCJmcm9tQnJhY2VzIiwiaW5uZXJfNzgiLCJmcm9tQnJhY2tldHMiLCJpbm5lcl83OSIsImZyb21QYXJlbnMiLCJpbm5lcl84MCIsIkNsb25lUmVkdWNlciIsInRlcm1fODEiLCJzdGF0ZV84MiIsIlN5bnRheFRlcm0iLCJhdHRyc184MyIsInR5cGVfODQiLCJyZWR1Y2VyXzg1Iiwic3RhdGVfODYiLCJyZWR1Y2VyXzg3Iiwic3RhdGVfODgiLCJyZWR1Y2VTeW50YXhUZXJtIiwiYXR0cnNfODkiLCJwcm90b3R5cGUiLCJ0ZXJtXzkwIiwic3RhdGVfOTEiLCJSYXdEZWxpbWl0ZXIiLCJhdHRyc185MiIsInR5cGVfOTMiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJyZWR1Y2VyXzk0Iiwic3RhdGVfOTUiLCJraW5kIiwiaW5uZXIiLCJtYXAiLCJhXzk2IiwiSlNPTiIsInN0cmluZ2lmeSIsInJlZHVjZXJfOTciLCJzdGF0ZV85OCIsInJlZHVjZVJhd0RlbGltaXRlciIsImF0dHJzXzk5IiwidGVybV8xMDAiLCJzdGF0ZV8xMDEiLCJSYXdTeW50YXgiLCJhdHRyc18xMDIiLCJ0eXBlXzEwMyIsInJlZHVjZXJfMTA0Iiwic3RhdGVfMTA1IiwicmVkdWNlcl8xMDYiLCJzdGF0ZV8xMDciLCJyZWR1Y2VSYXdTeW50YXgiLCJhdHRyc18xMDgiLCJ0ZXJtXzEwOSIsInN0YXRlXzExMCIsIlN0YXRlbWVudCIsImF0dHJzXzExMSIsInR5cGVfMTEyIiwicmVkdWNlcl8xMTMiLCJzdGF0ZV8xMTQiLCJyZWR1Y2VyXzExNSIsInN0YXRlXzExNiIsInJlZHVjZVN0YXRlbWVudCIsImF0dHJzXzExNyIsInRlcm1fMTE4Iiwic3RhdGVfMTE5IiwiSXRlcmF0aW9uU3RhdGVtZW50IiwiYXR0cnNfMTIwIiwidHlwZV8xMjEiLCJyZWR1Y2VyXzEyMiIsInN0YXRlXzEyMyIsImJvZHkiLCJyZWR1Y2VyXzEyNCIsInN0YXRlXzEyNSIsInJlZHVjZUl0ZXJhdGlvblN0YXRlbWVudCIsImF0dHJzXzEyNiIsInRlcm1fMTI3Iiwic3RhdGVfMTI4IiwiRXhwcmVzc2lvbiIsImF0dHJzXzEyOSIsInR5cGVfMTMwIiwicmVkdWNlcl8xMzEiLCJzdGF0ZV8xMzIiLCJyZWR1Y2VyXzEzMyIsInN0YXRlXzEzNCIsInJlZHVjZUV4cHJlc3Npb24iLCJhdHRyc18xMzUiLCJ0ZXJtXzEzNiIsInN0YXRlXzEzNyIsIk1lbWJlckV4cHJlc3Npb24iLCJhdHRyc18xMzgiLCJ0eXBlXzEzOSIsInJlZHVjZXJfMTQwIiwic3RhdGVfMTQxIiwib2JqZWN0IiwiU3VwZXIiLCJyZWR1Y2VyXzE0MiIsInN0YXRlXzE0MyIsInJlZHVjZU1lbWJlckV4cHJlc3Npb24iLCJhdHRyc18xNDQiLCJ0ZXJtXzE0NSIsInN0YXRlXzE0NiIsIlByb3BlcnR5TmFtZSIsImF0dHJzXzE0NyIsInR5cGVfMTQ4IiwicmVkdWNlcl8xNDkiLCJzdGF0ZV8xNTAiLCJyZWR1Y2VyXzE1MSIsInN0YXRlXzE1MiIsInJlZHVjZVByb3BlcnR5TmFtZSIsImF0dHJzXzE1MyIsInRlcm1fMTU0Iiwic3RhdGVfMTU1IiwiT2JqZWN0UHJvcGVydHkiLCJhdHRyc18xNTYiLCJ0eXBlXzE1NyIsInJlZHVjZXJfMTU4Iiwic3RhdGVfMTU5IiwicmVkdWNlcl8xNjAiLCJzdGF0ZV8xNjEiLCJyZWR1Y2VPYmplY3RQcm9wZXJ0eSIsImF0dHJzXzE2MiIsInRlcm1fMTYzIiwic3RhdGVfMTY0IiwiTmFtZWRPYmplY3RQcm9wZXJ0eSIsImF0dHJzXzE2NSIsInR5cGVfMTY2IiwicmVkdWNlcl8xNjciLCJzdGF0ZV8xNjgiLCJuYW1lIiwicmVkdWNlcl8xNjkiLCJzdGF0ZV8xNzAiLCJyZWR1Y2VOYW1lZE9iamVjdFByb3BlcnR5IiwiYXR0cnNfMTcxIiwidGVybV8xNzIiLCJzdGF0ZV8xNzMiLCJNZXRob2REZWZpbml0aW9uIiwiYXR0cnNfMTc0IiwidHlwZV8xNzUiLCJyZWR1Y2VyXzE3NiIsInN0YXRlXzE3NyIsIkZ1bmN0aW9uQm9keSIsInJlZHVjZXJfMTc4Iiwic3RhdGVfMTc5IiwicmVkdWNlTWV0aG9kRGVmaW5pdGlvbiIsImF0dHJzXzE4MCIsInRlcm1fMTgxIiwic3RhdGVfMTgyIiwiQmluZGluZ1dpdGhEZWZhdWx0IiwiYXR0cnNfMTgzIiwidHlwZV8xODQiLCJyZWR1Y2VyXzE4NSIsInN0YXRlXzE4NiIsImJpbmRpbmciLCJPYmplY3RCaW5kaW5nIiwiQXJyYXlCaW5kaW5nIiwiQmluZGluZ0lkZW50aWZpZXIiLCJpbml0IiwicmVkdWNlcl8xODciLCJzdGF0ZV8xODgiLCJyZWR1Y2VCaW5kaW5nV2l0aERlZmF1bHQiLCJhdHRyc18xODkiLCJ0ZXJtXzE5MCIsInN0YXRlXzE5MSIsImF0dHJzXzE5MiIsInR5cGVfMTkzIiwicmVkdWNlcl8xOTQiLCJzdGF0ZV8xOTUiLCJyZWR1Y2VyXzE5NiIsInN0YXRlXzE5NyIsInJlZHVjZUJpbmRpbmdJZGVudGlmaWVyIiwiYXR0cnNfMTk4IiwidGVybV8xOTkiLCJzdGF0ZV8yMDAiLCJhdHRyc18yMDEiLCJ0eXBlXzIwMiIsInJlZHVjZXJfMjAzIiwic3RhdGVfMjA0IiwiZWxlbWVudHMiLCJhXzIwNSIsInJlc3RFbGVtZW50IiwicmVkdWNlcl8yMDYiLCJzdGF0ZV8yMDciLCJyZWR1Y2VBcnJheUJpbmRpbmciLCJhdHRyc18yMDgiLCJ0ZXJtXzIwOSIsInN0YXRlXzIxMCIsImF0dHJzXzIxMSIsInR5cGVfMjEyIiwicmVkdWNlcl8yMTMiLCJzdGF0ZV8yMTQiLCJwcm9wZXJ0aWVzIiwiYV8yMTUiLCJCaW5kaW5nUHJvcGVydHkiLCJyZWR1Y2VyXzIxNiIsInN0YXRlXzIxNyIsInJlZHVjZU9iamVjdEJpbmRpbmciLCJhdHRyc18yMTgiLCJ0ZXJtXzIxOSIsInN0YXRlXzIyMCIsImF0dHJzXzIyMSIsInR5cGVfMjIyIiwicmVkdWNlcl8yMjMiLCJzdGF0ZV8yMjQiLCJyZWR1Y2VyXzIyNSIsInN0YXRlXzIyNiIsInJlZHVjZUJpbmRpbmdQcm9wZXJ0eSIsImF0dHJzXzIyNyIsInRlcm1fMjI4Iiwic3RhdGVfMjI5IiwiQmluZGluZ1Byb3BlcnR5SWRlbnRpZmllciIsImF0dHJzXzIzMCIsInR5cGVfMjMxIiwicmVkdWNlcl8yMzIiLCJzdGF0ZV8yMzMiLCJyZWR1Y2VyXzIzNCIsInN0YXRlXzIzNSIsInJlZHVjZUJpbmRpbmdQcm9wZXJ0eUlkZW50aWZpZXIiLCJhdHRyc18yMzYiLCJ0ZXJtXzIzNyIsInN0YXRlXzIzOCIsIkJpbmRpbmdQcm9wZXJ0eVByb3BlcnR5IiwiYXR0cnNfMjM5IiwidHlwZV8yNDAiLCJyZWR1Y2VyXzI0MSIsInN0YXRlXzI0MiIsInJlZHVjZXJfMjQzIiwic3RhdGVfMjQ0IiwicmVkdWNlQmluZGluZ1Byb3BlcnR5UHJvcGVydHkiLCJhdHRyc18yNDUiLCJ0ZXJtXzI0NiIsInN0YXRlXzI0NyIsIkNsYXNzRXhwcmVzc2lvbiIsImF0dHJzXzI0OCIsInR5cGVfMjQ5IiwicmVkdWNlcl8yNTAiLCJzdGF0ZV8yNTEiLCJzdXBlciIsImFfMjUyIiwiQ2xhc3NFbGVtZW50IiwicmVkdWNlcl8yNTMiLCJzdGF0ZV8yNTQiLCJyZWR1Y2VDbGFzc0V4cHJlc3Npb24iLCJhdHRyc18yNTUiLCJ0ZXJtXzI1NiIsInN0YXRlXzI1NyIsIkNsYXNzRGVjbGFyYXRpb24iLCJhdHRyc18yNTgiLCJ0eXBlXzI1OSIsInJlZHVjZXJfMjYwIiwic3RhdGVfMjYxIiwiYV8yNjIiLCJyZWR1Y2VyXzI2MyIsInN0YXRlXzI2NCIsInJlZHVjZUNsYXNzRGVjbGFyYXRpb24iLCJhdHRyc18yNjUiLCJ0ZXJtXzI2NiIsInN0YXRlXzI2NyIsImF0dHJzXzI2OCIsInR5cGVfMjY5IiwicmVkdWNlcl8yNzAiLCJzdGF0ZV8yNzEiLCJpc1N0YXRpYyIsIm1ldGhvZCIsInJlZHVjZXJfMjcyIiwic3RhdGVfMjczIiwicmVkdWNlQ2xhc3NFbGVtZW50IiwiYXR0cnNfMjc0IiwidGVybV8yNzUiLCJzdGF0ZV8yNzYiLCJNb2R1bGUiLCJhdHRyc18yNzciLCJ0eXBlXzI3OCIsInJlZHVjZXJfMjc5Iiwic3RhdGVfMjgwIiwiZGlyZWN0aXZlcyIsImFfMjgxIiwiaXRlbXMiLCJhXzI4MiIsInJlZHVjZXJfMjgzIiwic3RhdGVfMjg0IiwicmVkdWNlTW9kdWxlIiwiYXR0cnNfMjg1IiwidGVybV8yODYiLCJzdGF0ZV8yODciLCJJbXBvcnREZWNsYXJhdGlvbiIsImF0dHJzXzI4OCIsInR5cGVfMjg5IiwicmVkdWNlcl8yOTAiLCJzdGF0ZV8yOTEiLCJtb2R1bGVTcGVjaWZpZXIiLCJmb3JTeW50YXgiLCJyZWR1Y2VyXzI5MiIsInN0YXRlXzI5MyIsInJlZHVjZUltcG9ydERlY2xhcmF0aW9uIiwiYXR0cnNfMjk0IiwidGVybV8yOTUiLCJzdGF0ZV8yOTYiLCJFeHBvcnREZWNsYXJhdGlvbiIsImF0dHJzXzI5NyIsInR5cGVfMjk4IiwicmVkdWNlcl8yOTkiLCJzdGF0ZV8zMDAiLCJyZWR1Y2VyXzMwMSIsInN0YXRlXzMwMiIsInJlZHVjZUV4cG9ydERlY2xhcmF0aW9uIiwiYXR0cnNfMzAzIiwidGVybV8zMDQiLCJzdGF0ZV8zMDUiLCJJbXBvcnQiLCJhdHRyc18zMDYiLCJ0eXBlXzMwNyIsInJlZHVjZXJfMzA4Iiwic3RhdGVfMzA5IiwiZGVmYXVsdEJpbmRpbmciLCJuYW1lZEltcG9ydHMiLCJhXzMxMCIsIkltcG9ydFNwZWNpZmllciIsInJlZHVjZXJfMzExIiwic3RhdGVfMzEyIiwicmVkdWNlSW1wb3J0IiwiYXR0cnNfMzEzIiwidGVybV8zMTQiLCJzdGF0ZV8zMTUiLCJJbXBvcnROYW1lc3BhY2UiLCJhdHRyc18zMTYiLCJ0eXBlXzMxNyIsInJlZHVjZXJfMzE4Iiwic3RhdGVfMzE5IiwibmFtZXNwYWNlQmluZGluZyIsInJlZHVjZXJfMzIwIiwic3RhdGVfMzIxIiwicmVkdWNlSW1wb3J0TmFtZXNwYWNlIiwiYXR0cnNfMzIyIiwidGVybV8zMjMiLCJzdGF0ZV8zMjQiLCJhdHRyc18zMjUiLCJ0eXBlXzMyNiIsInJlZHVjZXJfMzI3Iiwic3RhdGVfMzI4IiwicmVkdWNlcl8zMjkiLCJzdGF0ZV8zMzAiLCJyZWR1Y2VJbXBvcnRTcGVjaWZpZXIiLCJhdHRyc18zMzEiLCJ0ZXJtXzMzMiIsInN0YXRlXzMzMyIsIkV4cG9ydEFsbEZyb20iLCJhdHRyc18zMzQiLCJ0eXBlXzMzNSIsInJlZHVjZXJfMzM2Iiwic3RhdGVfMzM3IiwicmVkdWNlcl8zMzgiLCJzdGF0ZV8zMzkiLCJyZWR1Y2VFeHBvcnRBbGxGcm9tIiwiYXR0cnNfMzQwIiwidGVybV8zNDEiLCJzdGF0ZV8zNDIiLCJFeHBvcnRGcm9tIiwiYXR0cnNfMzQzIiwidHlwZV8zNDQiLCJyZWR1Y2VyXzM0NSIsInN0YXRlXzM0NiIsIm5hbWVkRXhwb3J0cyIsImFfMzQ3IiwiRXhwb3J0U3BlY2lmaWVyIiwicmVkdWNlcl8zNDgiLCJzdGF0ZV8zNDkiLCJyZWR1Y2VFeHBvcnRGcm9tIiwiYXR0cnNfMzUwIiwidGVybV8zNTEiLCJzdGF0ZV8zNTIiLCJFeHBvcnQiLCJhdHRyc18zNTMiLCJ0eXBlXzM1NCIsInJlZHVjZXJfMzU1Iiwic3RhdGVfMzU2IiwiZGVjbGFyYXRpb24iLCJGdW5jdGlvbkRlY2xhcmF0aW9uIiwiVmFyaWFibGVEZWNsYXJhdGlvbiIsInJlZHVjZXJfMzU3Iiwic3RhdGVfMzU4IiwicmVkdWNlRXhwb3J0IiwiYXR0cnNfMzU5IiwidGVybV8zNjAiLCJzdGF0ZV8zNjEiLCJFeHBvcnREZWZhdWx0IiwiYXR0cnNfMzYyIiwidHlwZV8zNjMiLCJyZWR1Y2VyXzM2NCIsInN0YXRlXzM2NSIsInJlZHVjZXJfMzY2Iiwic3RhdGVfMzY3IiwicmVkdWNlRXhwb3J0RGVmYXVsdCIsImF0dHJzXzM2OCIsInRlcm1fMzY5Iiwic3RhdGVfMzcwIiwiYXR0cnNfMzcxIiwidHlwZV8zNzIiLCJyZWR1Y2VyXzM3MyIsInN0YXRlXzM3NCIsImV4cG9ydGVkTmFtZSIsInJlZHVjZXJfMzc1Iiwic3RhdGVfMzc2IiwicmVkdWNlRXhwb3J0U3BlY2lmaWVyIiwiYXR0cnNfMzc3IiwidGVybV8zNzgiLCJzdGF0ZV8zNzkiLCJNZXRob2QiLCJhdHRyc18zODAiLCJ0eXBlXzM4MSIsInJlZHVjZXJfMzgyIiwic3RhdGVfMzgzIiwiaXNHZW5lcmF0b3IiLCJwYXJhbXMiLCJGb3JtYWxQYXJhbWV0ZXJzIiwicmVkdWNlcl8zODQiLCJzdGF0ZV8zODUiLCJyZWR1Y2VNZXRob2QiLCJhdHRyc18zODYiLCJ0ZXJtXzM4NyIsInN0YXRlXzM4OCIsIkdldHRlciIsImF0dHJzXzM4OSIsInR5cGVfMzkwIiwicmVkdWNlcl8zOTEiLCJzdGF0ZV8zOTIiLCJyZWR1Y2VyXzM5MyIsInN0YXRlXzM5NCIsInJlZHVjZUdldHRlciIsImF0dHJzXzM5NSIsInRlcm1fMzk2Iiwic3RhdGVfMzk3IiwiU2V0dGVyIiwiYXR0cnNfMzk4IiwidHlwZV8zOTkiLCJyZWR1Y2VyXzQwMCIsInN0YXRlXzQwMSIsInBhcmFtIiwicmVkdWNlcl80MDIiLCJzdGF0ZV80MDMiLCJyZWR1Y2VTZXR0ZXIiLCJhdHRyc180MDQiLCJ0ZXJtXzQwNSIsInN0YXRlXzQwNiIsIkRhdGFQcm9wZXJ0eSIsImF0dHJzXzQwNyIsInR5cGVfNDA4IiwicmVkdWNlcl80MDkiLCJzdGF0ZV80MTAiLCJleHByZXNzaW9uIiwicmVkdWNlcl80MTEiLCJzdGF0ZV80MTIiLCJyZWR1Y2VEYXRhUHJvcGVydHkiLCJhdHRyc180MTMiLCJ0ZXJtXzQxNCIsInN0YXRlXzQxNSIsIlNob3J0aGFuZFByb3BlcnR5IiwiYXR0cnNfNDE2IiwidHlwZV80MTciLCJyZWR1Y2VyXzQxOCIsInN0YXRlXzQxOSIsInJlZHVjZXJfNDIwIiwic3RhdGVfNDIxIiwicmVkdWNlU2hvcnRoYW5kUHJvcGVydHkiLCJhdHRyc180MjIiLCJ0ZXJtXzQyMyIsInN0YXRlXzQyNCIsIlN0YXRpY1Byb3BlcnR5TmFtZSIsImF0dHJzXzQyNSIsInR5cGVfNDI2IiwicmVkdWNlcl80MjciLCJzdGF0ZV80MjgiLCJyZWR1Y2VyXzQyOSIsInN0YXRlXzQzMCIsInJlZHVjZVN0YXRpY1Byb3BlcnR5TmFtZSIsImF0dHJzXzQzMSIsInRlcm1fNDMyIiwic3RhdGVfNDMzIiwiQ29tcHV0ZWRQcm9wZXJ0eU5hbWUiLCJhdHRyc180MzQiLCJ0eXBlXzQzNSIsInJlZHVjZXJfNDM2Iiwic3RhdGVfNDM3IiwicmVkdWNlcl80MzgiLCJzdGF0ZV80MzkiLCJyZWR1Y2VDb21wdXRlZFByb3BlcnR5TmFtZSIsImF0dHJzXzQ0MCIsInRlcm1fNDQxIiwic3RhdGVfNDQyIiwiTGl0ZXJhbEJvb2xlYW5FeHByZXNzaW9uIiwiYXR0cnNfNDQzIiwidHlwZV80NDQiLCJyZWR1Y2VyXzQ0NSIsInN0YXRlXzQ0NiIsInJlZHVjZXJfNDQ3Iiwic3RhdGVfNDQ4IiwicmVkdWNlTGl0ZXJhbEJvb2xlYW5FeHByZXNzaW9uIiwiYXR0cnNfNDQ5IiwidGVybV80NTAiLCJzdGF0ZV80NTEiLCJMaXRlcmFsSW5maW5pdHlFeHByZXNzaW9uIiwiYXR0cnNfNDUyIiwidHlwZV80NTMiLCJyZWR1Y2VyXzQ1NCIsInN0YXRlXzQ1NSIsInJlZHVjZXJfNDU2Iiwic3RhdGVfNDU3IiwicmVkdWNlTGl0ZXJhbEluZmluaXR5RXhwcmVzc2lvbiIsImF0dHJzXzQ1OCIsInRlcm1fNDU5Iiwic3RhdGVfNDYwIiwiTGl0ZXJhbE51bGxFeHByZXNzaW9uIiwiYXR0cnNfNDYxIiwidHlwZV80NjIiLCJyZWR1Y2VyXzQ2MyIsInN0YXRlXzQ2NCIsInJlZHVjZXJfNDY1Iiwic3RhdGVfNDY2IiwicmVkdWNlTGl0ZXJhbE51bGxFeHByZXNzaW9uIiwiYXR0cnNfNDY3IiwidGVybV80NjgiLCJzdGF0ZV80NjkiLCJMaXRlcmFsTnVtZXJpY0V4cHJlc3Npb24iLCJhdHRyc180NzAiLCJ0eXBlXzQ3MSIsInJlZHVjZXJfNDcyIiwic3RhdGVfNDczIiwicmVkdWNlcl80NzQiLCJzdGF0ZV80NzUiLCJyZWR1Y2VMaXRlcmFsTnVtZXJpY0V4cHJlc3Npb24iLCJhdHRyc180NzYiLCJ0ZXJtXzQ3NyIsInN0YXRlXzQ3OCIsIkxpdGVyYWxSZWdFeHBFeHByZXNzaW9uIiwiYXR0cnNfNDc5IiwidHlwZV80ODAiLCJyZWR1Y2VyXzQ4MSIsInN0YXRlXzQ4MiIsInBhdHRlcm4iLCJmbGFncyIsInJlZHVjZXJfNDgzIiwic3RhdGVfNDg0IiwicmVkdWNlTGl0ZXJhbFJlZ0V4cEV4cHJlc3Npb24iLCJhdHRyc180ODUiLCJ0ZXJtXzQ4NiIsInN0YXRlXzQ4NyIsIkxpdGVyYWxTdHJpbmdFeHByZXNzaW9uIiwiYXR0cnNfNDg4IiwidHlwZV80ODkiLCJyZWR1Y2VyXzQ5MCIsInN0YXRlXzQ5MSIsInJlZHVjZXJfNDkyIiwic3RhdGVfNDkzIiwicmVkdWNlTGl0ZXJhbFN0cmluZ0V4cHJlc3Npb24iLCJhdHRyc180OTQiLCJ0ZXJtXzQ5NSIsInN0YXRlXzQ5NiIsIkFycmF5RXhwcmVzc2lvbiIsImF0dHJzXzQ5NyIsInR5cGVfNDk4IiwicmVkdWNlcl80OTkiLCJzdGF0ZV81MDAiLCJhXzUwMSIsIlNwcmVhZEVsZW1lbnQiLCJyZWR1Y2VyXzUwMiIsInN0YXRlXzUwMyIsInJlZHVjZUFycmF5RXhwcmVzc2lvbiIsImF0dHJzXzUwNCIsInRlcm1fNTA1Iiwic3RhdGVfNTA2IiwiQXJyb3dFeHByZXNzaW9uIiwiYXR0cnNfNTA3IiwidHlwZV81MDgiLCJyZWR1Y2VyXzUwOSIsInN0YXRlXzUxMCIsInJlZHVjZXJfNTExIiwic3RhdGVfNTEyIiwicmVkdWNlQXJyb3dFeHByZXNzaW9uIiwiYXR0cnNfNTEzIiwidGVybV81MTQiLCJzdGF0ZV81MTUiLCJBcnJvd0V4cHJlc3Npb25FIiwiYXR0cnNfNTE2IiwidHlwZV81MTciLCJyZWR1Y2VyXzUxOCIsInN0YXRlXzUxOSIsImFfNTIwIiwicmVkdWNlcl81MjEiLCJzdGF0ZV81MjIiLCJyZWR1Y2VBcnJvd0V4cHJlc3Npb25FIiwiYXR0cnNfNTIzIiwidGVybV81MjQiLCJzdGF0ZV81MjUiLCJBc3NpZ25tZW50RXhwcmVzc2lvbiIsImF0dHJzXzUyNiIsInR5cGVfNTI3IiwicmVkdWNlcl81MjgiLCJzdGF0ZV81MjkiLCJyZWR1Y2VyXzUzMCIsInN0YXRlXzUzMSIsInJlZHVjZUFzc2lnbm1lbnRFeHByZXNzaW9uIiwiYXR0cnNfNTMyIiwidGVybV81MzMiLCJzdGF0ZV81MzQiLCJCaW5hcnlFeHByZXNzaW9uIiwiYXR0cnNfNTM1IiwidHlwZV81MzYiLCJyZWR1Y2VyXzUzNyIsInN0YXRlXzUzOCIsIm9wZXJhdG9yIiwibGVmdCIsInJpZ2h0IiwicmVkdWNlcl81MzkiLCJzdGF0ZV81NDAiLCJyZWR1Y2VCaW5hcnlFeHByZXNzaW9uIiwiYXR0cnNfNTQxIiwidGVybV81NDIiLCJzdGF0ZV81NDMiLCJDYWxsRXhwcmVzc2lvbiIsImF0dHJzXzU0NCIsInR5cGVfNTQ1IiwicmVkdWNlcl81NDYiLCJzdGF0ZV81NDciLCJjYWxsZWUiLCJhcmd1bWVudHMiLCJhXzU0OCIsInJlZHVjZXJfNTQ5Iiwic3RhdGVfNTUwIiwicmVkdWNlQ2FsbEV4cHJlc3Npb24iLCJhdHRyc181NTEiLCJ0ZXJtXzU1MiIsInN0YXRlXzU1MyIsIkNhbGxFeHByZXNzaW9uRSIsImF0dHJzXzU1NCIsInR5cGVfNTU1IiwicmVkdWNlcl81NTYiLCJzdGF0ZV81NTciLCJhXzU1OCIsInJlZHVjZXJfNTU5Iiwic3RhdGVfNTYwIiwicmVkdWNlQ2FsbEV4cHJlc3Npb25FIiwiYXR0cnNfNTYxIiwidGVybV81NjIiLCJzdGF0ZV81NjMiLCJDb21wb3VuZEFzc2lnbm1lbnRFeHByZXNzaW9uIiwiYXR0cnNfNTY0IiwidHlwZV81NjUiLCJyZWR1Y2VyXzU2NiIsInN0YXRlXzU2NyIsInJlZHVjZXJfNTY4Iiwic3RhdGVfNTY5IiwicmVkdWNlQ29tcG91bmRBc3NpZ25tZW50RXhwcmVzc2lvbiIsImF0dHJzXzU3MCIsInRlcm1fNTcxIiwic3RhdGVfNTcyIiwiQ29tcHV0ZWRNZW1iZXJFeHByZXNzaW9uIiwiYXR0cnNfNTczIiwidHlwZV81NzQiLCJyZWR1Y2VyXzU3NSIsInN0YXRlXzU3NiIsInJlZHVjZXJfNTc3Iiwic3RhdGVfNTc4IiwicmVkdWNlQ29tcHV0ZWRNZW1iZXJFeHByZXNzaW9uIiwiYXR0cnNfNTc5IiwidGVybV81ODAiLCJzdGF0ZV81ODEiLCJDb25kaXRpb25hbEV4cHJlc3Npb24iLCJhdHRyc181ODIiLCJ0eXBlXzU4MyIsInJlZHVjZXJfNTg0Iiwic3RhdGVfNTg1IiwidGVzdCIsImNvbnNlcXVlbnQiLCJhbHRlcm5hdGUiLCJyZWR1Y2VyXzU4NiIsInN0YXRlXzU4NyIsInJlZHVjZUNvbmRpdGlvbmFsRXhwcmVzc2lvbiIsImF0dHJzXzU4OCIsInRlcm1fNTg5Iiwic3RhdGVfNTkwIiwiRnVuY3Rpb25FeHByZXNzaW9uIiwiYXR0cnNfNTkxIiwidHlwZV81OTIiLCJyZWR1Y2VyXzU5MyIsInN0YXRlXzU5NCIsInJlZHVjZXJfNTk1Iiwic3RhdGVfNTk2IiwicmVkdWNlRnVuY3Rpb25FeHByZXNzaW9uIiwiYXR0cnNfNTk3IiwidGVybV81OTgiLCJzdGF0ZV81OTkiLCJGdW5jdGlvbkV4cHJlc3Npb25FIiwiYXR0cnNfNjAwIiwidHlwZV82MDEiLCJyZWR1Y2VyXzYwMiIsInN0YXRlXzYwMyIsImFfNjA0IiwicmVkdWNlcl82MDUiLCJzdGF0ZV82MDYiLCJyZWR1Y2VGdW5jdGlvbkV4cHJlc3Npb25FIiwiYXR0cnNfNjA3IiwidGVybV82MDgiLCJzdGF0ZV82MDkiLCJJZGVudGlmaWVyRXhwcmVzc2lvbiIsImF0dHJzXzYxMCIsInR5cGVfNjExIiwicmVkdWNlcl82MTIiLCJzdGF0ZV82MTMiLCJyZWR1Y2VyXzYxNCIsInN0YXRlXzYxNSIsInJlZHVjZUlkZW50aWZpZXJFeHByZXNzaW9uIiwiYXR0cnNfNjE2IiwidGVybV82MTciLCJzdGF0ZV82MTgiLCJOZXdFeHByZXNzaW9uIiwiYXR0cnNfNjE5IiwidHlwZV82MjAiLCJyZWR1Y2VyXzYyMSIsInN0YXRlXzYyMiIsImFfNjIzIiwicmVkdWNlcl82MjQiLCJzdGF0ZV82MjUiLCJyZWR1Y2VOZXdFeHByZXNzaW9uIiwiYXR0cnNfNjI2IiwidGVybV82MjciLCJzdGF0ZV82MjgiLCJOZXdUYXJnZXRFeHByZXNzaW9uIiwiYXR0cnNfNjI5IiwidHlwZV82MzAiLCJyZWR1Y2VyXzYzMSIsInN0YXRlXzYzMiIsInJlZHVjZXJfNjMzIiwic3RhdGVfNjM0IiwicmVkdWNlTmV3VGFyZ2V0RXhwcmVzc2lvbiIsImF0dHJzXzYzNSIsInRlcm1fNjM2Iiwic3RhdGVfNjM3IiwiT2JqZWN0RXhwcmVzc2lvbiIsImF0dHJzXzYzOCIsInR5cGVfNjM5IiwicmVkdWNlcl82NDAiLCJzdGF0ZV82NDEiLCJhXzY0MiIsInJlZHVjZXJfNjQzIiwic3RhdGVfNjQ0IiwicmVkdWNlT2JqZWN0RXhwcmVzc2lvbiIsImF0dHJzXzY0NSIsInRlcm1fNjQ2Iiwic3RhdGVfNjQ3IiwiVW5hcnlFeHByZXNzaW9uIiwiYXR0cnNfNjQ4IiwidHlwZV82NDkiLCJyZWR1Y2VyXzY1MCIsInN0YXRlXzY1MSIsIm9wZXJhbmQiLCJyZWR1Y2VyXzY1MiIsInN0YXRlXzY1MyIsInJlZHVjZVVuYXJ5RXhwcmVzc2lvbiIsImF0dHJzXzY1NCIsInRlcm1fNjU1Iiwic3RhdGVfNjU2IiwiU3RhdGljTWVtYmVyRXhwcmVzc2lvbiIsImF0dHJzXzY1NyIsInR5cGVfNjU4IiwicmVkdWNlcl82NTkiLCJzdGF0ZV82NjAiLCJwcm9wZXJ0eSIsInJlZHVjZXJfNjYxIiwic3RhdGVfNjYyIiwicmVkdWNlU3RhdGljTWVtYmVyRXhwcmVzc2lvbiIsImF0dHJzXzY2MyIsInRlcm1fNjY0Iiwic3RhdGVfNjY1IiwiVGVtcGxhdGVFeHByZXNzaW9uIiwiYXR0cnNfNjY2IiwidHlwZV82NjciLCJyZWR1Y2VyXzY2OCIsInN0YXRlXzY2OSIsInRhZyIsImFfNjcwIiwiVGVtcGxhdGVFbGVtZW50IiwicmVkdWNlcl82NzEiLCJzdGF0ZV82NzIiLCJyZWR1Y2VUZW1wbGF0ZUV4cHJlc3Npb24iLCJhdHRyc182NzMiLCJ0ZXJtXzY3NCIsInN0YXRlXzY3NSIsIlRoaXNFeHByZXNzaW9uIiwiYXR0cnNfNjc2IiwidHlwZV82NzciLCJyZWR1Y2VyXzY3OCIsInN0YXRlXzY3OSIsInN0eCIsInJlZHVjZXJfNjgwIiwic3RhdGVfNjgxIiwicmVkdWNlVGhpc0V4cHJlc3Npb24iLCJhdHRyc182ODIiLCJ0ZXJtXzY4MyIsInN0YXRlXzY4NCIsIlVwZGF0ZUV4cHJlc3Npb24iLCJhdHRyc182ODUiLCJ0eXBlXzY4NiIsInJlZHVjZXJfNjg3Iiwic3RhdGVfNjg4IiwiaXNQcmVmaXgiLCJyZWR1Y2VyXzY4OSIsInN0YXRlXzY5MCIsInJlZHVjZVVwZGF0ZUV4cHJlc3Npb24iLCJhdHRyc182OTEiLCJ0ZXJtXzY5MiIsInN0YXRlXzY5MyIsIllpZWxkRXhwcmVzc2lvbiIsImF0dHJzXzY5NCIsInR5cGVfNjk1IiwicmVkdWNlcl82OTYiLCJzdGF0ZV82OTciLCJyZWR1Y2VyXzY5OCIsInN0YXRlXzY5OSIsInJlZHVjZVlpZWxkRXhwcmVzc2lvbiIsImF0dHJzXzcwMCIsInRlcm1fNzAxIiwic3RhdGVfNzAyIiwiWWllbGRHZW5lcmF0b3JFeHByZXNzaW9uIiwiYXR0cnNfNzAzIiwidHlwZV83MDQiLCJyZWR1Y2VyXzcwNSIsInN0YXRlXzcwNiIsInJlZHVjZXJfNzA3Iiwic3RhdGVfNzA4IiwicmVkdWNlWWllbGRHZW5lcmF0b3JFeHByZXNzaW9uIiwiYXR0cnNfNzA5IiwidGVybV83MTAiLCJzdGF0ZV83MTEiLCJQYXJlbnRoZXNpemVkRXhwcmVzc2lvbiIsImF0dHJzXzcxMiIsInR5cGVfNzEzIiwicmVkdWNlcl83MTQiLCJzdGF0ZV83MTUiLCJyZWR1Y2VyXzcxNiIsInN0YXRlXzcxNyIsInJlZHVjZVBhcmVudGhlc2l6ZWRFeHByZXNzaW9uIiwiYXR0cnNfNzE4IiwidGVybV83MTkiLCJzdGF0ZV83MjAiLCJCbG9ja1N0YXRlbWVudCIsImF0dHJzXzcyMSIsInR5cGVfNzIyIiwicmVkdWNlcl83MjMiLCJzdGF0ZV83MjQiLCJibG9jayIsIkJsb2NrIiwicmVkdWNlcl83MjUiLCJzdGF0ZV83MjYiLCJyZWR1Y2VCbG9ja1N0YXRlbWVudCIsImF0dHJzXzcyNyIsInRlcm1fNzI4Iiwic3RhdGVfNzI5IiwiQnJlYWtTdGF0ZW1lbnQiLCJhdHRyc183MzAiLCJ0eXBlXzczMSIsInJlZHVjZXJfNzMyIiwic3RhdGVfNzMzIiwibGFiZWwiLCJyZWR1Y2VyXzczNCIsInN0YXRlXzczNSIsInJlZHVjZUJyZWFrU3RhdGVtZW50IiwiYXR0cnNfNzM2IiwidGVybV83MzciLCJzdGF0ZV83MzgiLCJDb250aW51ZVN0YXRlbWVudCIsImF0dHJzXzczOSIsInR5cGVfNzQwIiwicmVkdWNlcl83NDEiLCJzdGF0ZV83NDIiLCJyZWR1Y2VyXzc0MyIsInN0YXRlXzc0NCIsInJlZHVjZUNvbnRpbnVlU3RhdGVtZW50IiwiYXR0cnNfNzQ1IiwidGVybV83NDYiLCJzdGF0ZV83NDciLCJEZWJ1Z2dlclN0YXRlbWVudCIsImF0dHJzXzc0OCIsInR5cGVfNzQ5IiwicmVkdWNlcl83NTAiLCJzdGF0ZV83NTEiLCJyZWR1Y2VyXzc1MiIsInN0YXRlXzc1MyIsInJlZHVjZURlYnVnZ2VyU3RhdGVtZW50IiwiYXR0cnNfNzU0IiwidGVybV83NTUiLCJzdGF0ZV83NTYiLCJEb1doaWxlU3RhdGVtZW50IiwiYXR0cnNfNzU3IiwidHlwZV83NTgiLCJyZWR1Y2VyXzc1OSIsInN0YXRlXzc2MCIsInJlZHVjZXJfNzYxIiwic3RhdGVfNzYyIiwicmVkdWNlRG9XaGlsZVN0YXRlbWVudCIsImF0dHJzXzc2MyIsInRlcm1fNzY0Iiwic3RhdGVfNzY1IiwiRW1wdHlTdGF0ZW1lbnQiLCJhdHRyc183NjYiLCJ0eXBlXzc2NyIsInJlZHVjZXJfNzY4Iiwic3RhdGVfNzY5IiwicmVkdWNlcl83NzAiLCJzdGF0ZV83NzEiLCJyZWR1Y2VFbXB0eVN0YXRlbWVudCIsImF0dHJzXzc3MiIsInRlcm1fNzczIiwic3RhdGVfNzc0IiwiRXhwcmVzc2lvblN0YXRlbWVudCIsImF0dHJzXzc3NSIsInR5cGVfNzc2IiwicmVkdWNlcl83NzciLCJzdGF0ZV83NzgiLCJyZWR1Y2VyXzc3OSIsInN0YXRlXzc4MCIsInJlZHVjZUV4cHJlc3Npb25TdGF0ZW1lbnQiLCJhdHRyc183ODEiLCJ0ZXJtXzc4MiIsInN0YXRlXzc4MyIsIkZvckluU3RhdGVtZW50IiwiYXR0cnNfNzg0IiwidHlwZV83ODUiLCJyZWR1Y2VyXzc4NiIsInN0YXRlXzc4NyIsInJlZHVjZXJfNzg4Iiwic3RhdGVfNzg5IiwicmVkdWNlRm9ySW5TdGF0ZW1lbnQiLCJhdHRyc183OTAiLCJ0ZXJtXzc5MSIsInN0YXRlXzc5MiIsIkZvck9mU3RhdGVtZW50IiwiYXR0cnNfNzkzIiwidHlwZV83OTQiLCJyZWR1Y2VyXzc5NSIsInN0YXRlXzc5NiIsInJlZHVjZXJfNzk3Iiwic3RhdGVfNzk4IiwicmVkdWNlRm9yT2ZTdGF0ZW1lbnQiLCJhdHRyc183OTkiLCJ0ZXJtXzgwMCIsInN0YXRlXzgwMSIsIkZvclN0YXRlbWVudCIsImF0dHJzXzgwMiIsInR5cGVfODAzIiwicmVkdWNlcl84MDQiLCJzdGF0ZV84MDUiLCJ1cGRhdGUiLCJyZWR1Y2VyXzgwNiIsInN0YXRlXzgwNyIsInJlZHVjZUZvclN0YXRlbWVudCIsImF0dHJzXzgwOCIsInRlcm1fODA5Iiwic3RhdGVfODEwIiwiSWZTdGF0ZW1lbnQiLCJhdHRyc184MTEiLCJ0eXBlXzgxMiIsInJlZHVjZXJfODEzIiwic3RhdGVfODE0IiwicmVkdWNlcl84MTUiLCJzdGF0ZV84MTYiLCJyZWR1Y2VJZlN0YXRlbWVudCIsImF0dHJzXzgxNyIsInRlcm1fODE4Iiwic3RhdGVfODE5IiwiTGFiZWxlZFN0YXRlbWVudCIsImF0dHJzXzgyMCIsInR5cGVfODIxIiwicmVkdWNlcl84MjIiLCJzdGF0ZV84MjMiLCJyZWR1Y2VyXzgyNCIsInN0YXRlXzgyNSIsInJlZHVjZUxhYmVsZWRTdGF0ZW1lbnQiLCJhdHRyc184MjYiLCJ0ZXJtXzgyNyIsInN0YXRlXzgyOCIsIlJldHVyblN0YXRlbWVudCIsImF0dHJzXzgyOSIsInR5cGVfODMwIiwicmVkdWNlcl84MzEiLCJzdGF0ZV84MzIiLCJyZWR1Y2VyXzgzMyIsInN0YXRlXzgzNCIsInJlZHVjZVJldHVyblN0YXRlbWVudCIsImF0dHJzXzgzNSIsInRlcm1fODM2Iiwic3RhdGVfODM3IiwiU3dpdGNoU3RhdGVtZW50IiwiYXR0cnNfODM4IiwidHlwZV84MzkiLCJyZWR1Y2VyXzg0MCIsInN0YXRlXzg0MSIsImRpc2NyaW1pbmFudCIsImNhc2VzIiwiYV84NDIiLCJTd2l0Y2hDYXNlIiwicmVkdWNlcl84NDMiLCJzdGF0ZV84NDQiLCJyZWR1Y2VTd2l0Y2hTdGF0ZW1lbnQiLCJhdHRyc184NDUiLCJ0ZXJtXzg0NiIsInN0YXRlXzg0NyIsIlN3aXRjaFN0YXRlbWVudFdpdGhEZWZhdWx0IiwiYXR0cnNfODQ4IiwidHlwZV84NDkiLCJyZWR1Y2VyXzg1MCIsInN0YXRlXzg1MSIsInByZURlZmF1bHRDYXNlcyIsImFfODUyIiwiZGVmYXVsdENhc2UiLCJTd2l0Y2hEZWZhdWx0IiwicG9zdERlZmF1bHRDYXNlcyIsImFfODUzIiwicmVkdWNlcl84NTQiLCJzdGF0ZV84NTUiLCJyZWR1Y2VTd2l0Y2hTdGF0ZW1lbnRXaXRoRGVmYXVsdCIsImF0dHJzXzg1NiIsInRlcm1fODU3Iiwic3RhdGVfODU4IiwiVGhyb3dTdGF0ZW1lbnQiLCJhdHRyc184NTkiLCJ0eXBlXzg2MCIsInJlZHVjZXJfODYxIiwic3RhdGVfODYyIiwicmVkdWNlcl84NjMiLCJzdGF0ZV84NjQiLCJyZWR1Y2VUaHJvd1N0YXRlbWVudCIsImF0dHJzXzg2NSIsInRlcm1fODY2Iiwic3RhdGVfODY3IiwiVHJ5Q2F0Y2hTdGF0ZW1lbnQiLCJhdHRyc184NjgiLCJ0eXBlXzg2OSIsInJlZHVjZXJfODcwIiwic3RhdGVfODcxIiwiY2F0Y2hDbGF1c2UiLCJDYXRjaENsYXVzZSIsInJlZHVjZXJfODcyIiwic3RhdGVfODczIiwicmVkdWNlVHJ5Q2F0Y2hTdGF0ZW1lbnQiLCJhdHRyc184NzQiLCJ0ZXJtXzg3NSIsInN0YXRlXzg3NiIsIlRyeUZpbmFsbHlTdGF0ZW1lbnQiLCJhdHRyc184NzciLCJ0eXBlXzg3OCIsInJlZHVjZXJfODc5Iiwic3RhdGVfODgwIiwiZmluYWxpemVyIiwicmVkdWNlcl84ODEiLCJzdGF0ZV84ODIiLCJyZWR1Y2VUcnlGaW5hbGx5U3RhdGVtZW50IiwiYXR0cnNfODgzIiwidGVybV84ODQiLCJzdGF0ZV84ODUiLCJWYXJpYWJsZURlY2xhcmF0aW9uU3RhdGVtZW50IiwiYXR0cnNfODg2IiwidHlwZV84ODciLCJyZWR1Y2VyXzg4OCIsInN0YXRlXzg4OSIsInJlZHVjZXJfODkwIiwic3RhdGVfODkxIiwicmVkdWNlVmFyaWFibGVEZWNsYXJhdGlvblN0YXRlbWVudCIsImF0dHJzXzg5MiIsInRlcm1fODkzIiwic3RhdGVfODk0IiwiV2l0aFN0YXRlbWVudCIsImF0dHJzXzg5NSIsInR5cGVfODk2IiwicmVkdWNlcl84OTciLCJzdGF0ZV84OTgiLCJyZWR1Y2VyXzg5OSIsInN0YXRlXzkwMCIsInJlZHVjZVdpdGhTdGF0ZW1lbnQiLCJhdHRyc185MDEiLCJ0ZXJtXzkwMiIsInN0YXRlXzkwMyIsIldoaWxlU3RhdGVtZW50IiwiYXR0cnNfOTA0IiwidHlwZV85MDUiLCJyZWR1Y2VyXzkwNiIsInN0YXRlXzkwNyIsInJlZHVjZXJfOTA4Iiwic3RhdGVfOTA5IiwicmVkdWNlV2hpbGVTdGF0ZW1lbnQiLCJhdHRyc185MTAiLCJ0ZXJtXzkxMSIsInN0YXRlXzkxMiIsIlByYWdtYSIsImF0dHJzXzkxMyIsInR5cGVfOTE0IiwicmVkdWNlcl85MTUiLCJzdGF0ZV85MTYiLCJyZWR1Y2VyXzkxNyIsInN0YXRlXzkxOCIsInJlZHVjZVByYWdtYSIsImF0dHJzXzkxOSIsInRlcm1fOTIwIiwic3RhdGVfOTIxIiwiYXR0cnNfOTIyIiwidHlwZV85MjMiLCJyZWR1Y2VyXzkyNCIsInN0YXRlXzkyNSIsInN0YXRlbWVudHMiLCJhXzkyNiIsInJlZHVjZXJfOTI3Iiwic3RhdGVfOTI4IiwicmVkdWNlQmxvY2siLCJhdHRyc185MjkiLCJ0ZXJtXzkzMCIsInN0YXRlXzkzMSIsImF0dHJzXzkzMiIsInR5cGVfOTMzIiwicmVkdWNlcl85MzQiLCJzdGF0ZV85MzUiLCJyZWR1Y2VyXzkzNiIsInN0YXRlXzkzNyIsInJlZHVjZUNhdGNoQ2xhdXNlIiwiYXR0cnNfOTM4IiwidGVybV85MzkiLCJzdGF0ZV85NDAiLCJEaXJlY3RpdmUiLCJhdHRyc185NDEiLCJ0eXBlXzk0MiIsInJlZHVjZXJfOTQzIiwic3RhdGVfOTQ0IiwicmF3VmFsdWUiLCJyZWR1Y2VyXzk0NSIsInN0YXRlXzk0NiIsInJlZHVjZURpcmVjdGl2ZSIsImF0dHJzXzk0NyIsInRlcm1fOTQ4Iiwic3RhdGVfOTQ5IiwiYXR0cnNfOTUwIiwidHlwZV85NTEiLCJyZWR1Y2VyXzk1MiIsInN0YXRlXzk1MyIsImFfOTU0IiwicmVzdCIsInJlZHVjZXJfOTU1Iiwic3RhdGVfOTU2IiwicmVkdWNlRm9ybWFsUGFyYW1ldGVycyIsImF0dHJzXzk1NyIsInRlcm1fOTU4Iiwic3RhdGVfOTU5IiwiYXR0cnNfOTYwIiwidHlwZV85NjEiLCJyZWR1Y2VyXzk2MiIsInN0YXRlXzk2MyIsImFfOTY0IiwiYV85NjUiLCJyZWR1Y2VyXzk2NiIsInN0YXRlXzk2NyIsInJlZHVjZUZ1bmN0aW9uQm9keSIsImF0dHJzXzk2OCIsInRlcm1fOTY5Iiwic3RhdGVfOTcwIiwiYXR0cnNfOTcxIiwidHlwZV85NzIiLCJyZWR1Y2VyXzk3MyIsInN0YXRlXzk3NCIsInJlZHVjZXJfOTc1Iiwic3RhdGVfOTc2IiwicmVkdWNlRnVuY3Rpb25EZWNsYXJhdGlvbiIsImF0dHJzXzk3NyIsInRlcm1fOTc4Iiwic3RhdGVfOTc5IiwiRnVuY3Rpb25EZWNsYXJhdGlvbkUiLCJhdHRyc185ODAiLCJ0eXBlXzk4MSIsInJlZHVjZXJfOTgyIiwic3RhdGVfOTgzIiwiYV85ODQiLCJyZWR1Y2VyXzk4NSIsInN0YXRlXzk4NiIsInJlZHVjZUZ1bmN0aW9uRGVjbGFyYXRpb25FIiwiYXR0cnNfOTg3IiwidGVybV85ODgiLCJzdGF0ZV85ODkiLCJTY3JpcHQiLCJhdHRyc185OTAiLCJ0eXBlXzk5MSIsInJlZHVjZXJfOTkyIiwic3RhdGVfOTkzIiwiYV85OTQiLCJhXzk5NSIsInJlZHVjZXJfOTk2Iiwic3RhdGVfOTk3IiwicmVkdWNlU2NyaXB0IiwiYXR0cnNfOTk4IiwidGVybV85OTkiLCJzdGF0ZV8xMDAwIiwiYXR0cnNfMTAwMSIsInR5cGVfMTAwMiIsInJlZHVjZXJfMTAwMyIsInN0YXRlXzEwMDQiLCJyZWR1Y2VyXzEwMDUiLCJzdGF0ZV8xMDA2IiwicmVkdWNlU3ByZWFkRWxlbWVudCIsImF0dHJzXzEwMDciLCJ0ZXJtXzEwMDgiLCJzdGF0ZV8xMDA5IiwiYXR0cnNfMTAxMCIsInR5cGVfMTAxMSIsInJlZHVjZXJfMTAxMiIsInN0YXRlXzEwMTMiLCJyZWR1Y2VyXzEwMTQiLCJzdGF0ZV8xMDE1IiwicmVkdWNlU3VwZXIiLCJhdHRyc18xMDE2IiwidGVybV8xMDE3Iiwic3RhdGVfMTAxOCIsImF0dHJzXzEwMTkiLCJ0eXBlXzEwMjAiLCJyZWR1Y2VyXzEwMjEiLCJzdGF0ZV8xMDIyIiwiYV8xMDIzIiwicmVkdWNlcl8xMDI0Iiwic3RhdGVfMTAyNSIsInJlZHVjZVN3aXRjaENhc2UiLCJhdHRyc18xMDI2IiwidGVybV8xMDI3Iiwic3RhdGVfMTAyOCIsImF0dHJzXzEwMjkiLCJ0eXBlXzEwMzAiLCJyZWR1Y2VyXzEwMzEiLCJzdGF0ZV8xMDMyIiwiYV8xMDMzIiwicmVkdWNlcl8xMDM0Iiwic3RhdGVfMTAzNSIsInJlZHVjZVN3aXRjaERlZmF1bHQiLCJhdHRyc18xMDM2IiwidGVybV8xMDM3Iiwic3RhdGVfMTAzOCIsImF0dHJzXzEwMzkiLCJ0eXBlXzEwNDAiLCJyZWR1Y2VyXzEwNDEiLCJzdGF0ZV8xMDQyIiwicmVkdWNlcl8xMDQzIiwic3RhdGVfMTA0NCIsInJlZHVjZVRlbXBsYXRlRWxlbWVudCIsImF0dHJzXzEwNDUiLCJ0ZXJtXzEwNDYiLCJzdGF0ZV8xMDQ3IiwiU3ludGF4VGVtcGxhdGUiLCJhdHRyc18xMDQ4IiwidHlwZV8xMDQ5IiwicmVkdWNlcl8xMDUwIiwic3RhdGVfMTA1MSIsInRlbXBsYXRlIiwiYV8xMDUyIiwicmVkdWNlcl8xMDUzIiwic3RhdGVfMTA1NCIsInJlZHVjZVN5bnRheFRlbXBsYXRlIiwiYXR0cnNfMTA1NSIsInRlcm1fMTA1NiIsInN0YXRlXzEwNTciLCJTeW50YXhRdW90ZSIsImF0dHJzXzEwNTgiLCJ0eXBlXzEwNTkiLCJyZWR1Y2VyXzEwNjAiLCJzdGF0ZV8xMDYxIiwicmVkdWNlcl8xMDYyIiwic3RhdGVfMTA2MyIsInJlZHVjZVN5bnRheFF1b3RlIiwiYXR0cnNfMTA2NCIsInRlcm1fMTA2NSIsInN0YXRlXzEwNjYiLCJhdHRyc18xMDY3IiwidHlwZV8xMDY4IiwicmVkdWNlcl8xMDY5Iiwic3RhdGVfMTA3MCIsImRlY2xhcmF0b3JzIiwiYV8xMDcxIiwiVmFyaWFibGVEZWNsYXJhdG9yIiwicmVkdWNlcl8xMDcyIiwic3RhdGVfMTA3MyIsInJlZHVjZVZhcmlhYmxlRGVjbGFyYXRpb24iLCJhdHRyc18xMDc0IiwidGVybV8xMDc1Iiwic3RhdGVfMTA3NiIsImF0dHJzXzEwNzciLCJ0eXBlXzEwNzgiLCJyZWR1Y2VyXzEwNzkiLCJzdGF0ZV8xMDgwIiwicmVkdWNlcl8xMDgxIiwic3RhdGVfMTA4MiIsInJlZHVjZVZhcmlhYmxlRGVjbGFyYXRvciIsImF0dHJzXzEwODMiLCJ0ZXJtXzEwODQiLCJzdGF0ZV8xMDg1IiwiT3BlcmF0b3JEZWNsYXJhdG9yIiwiYXR0cnNfMTA4NiIsInR5cGVfMTA4NyIsInJlZHVjZXJfMTA4OCIsInN0YXRlXzEwODkiLCJwcmVjIiwiYXNzb2MiLCJyZWR1Y2VyXzEwOTAiLCJzdGF0ZV8xMDkxIiwicmVkdWNlT3BlcmF0b3JEZWNsYXJhdG9yIiwiYXR0cnNfMTA5MiIsInRlcm1fMTA5MyIsInN0YXRlXzEwOTQiXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsTUFBTUEsSUFBTixDQUFXO0FBQ1RDLGNBQVlDLFFBQVosRUFBc0JDLE9BQXRCLEVBQStCO0FBQzdCQyxXQUFPQyxNQUFQLENBQWMsSUFBZCxFQUFvQkgsUUFBcEI7QUFDQSxTQUFLSSxJQUFMLEdBQVlILFdBQVcsTUFBdkI7QUFDQSxTQUFLSSxHQUFMLEdBQVcsSUFBWDtBQUNBSCxXQUFPSSxNQUFQLENBQWMsSUFBZDtBQUNEO0FBQ0RDLGVBQWFDLFVBQWIsRUFBeUJDLFdBQVcsRUFBcEMsRUFBd0M7QUFDdEMsV0FBT0EsUUFBUDtBQUNEO0FBQ0RDLGdCQUFjO0FBQ1osV0FBTyxFQUFQO0FBQ0Q7QUFDREMsU0FBT0MsVUFBUCxFQUFtQjtBQUNqQixRQUFJQyxXQUFXLEtBQUtOLFlBQUwsQ0FBa0JLLFVBQWxCLENBQWY7QUFDQSxXQUFPQSxXQUFXRSxVQUFYLENBQXNCLElBQXRCLEVBQTRCRCxRQUE1QixDQUFQO0FBQ0Q7QUFDREUsU0FBT0MsUUFBUCxFQUFpQjtBQUNmLFdBQU8sSUFBSWxCLElBQUosQ0FBU0ksT0FBT0MsTUFBUCxDQUFjLEtBQUtPLFdBQUwsRUFBZCxFQUFrQ00sUUFBbEMsQ0FBVCxDQUFQO0FBQ0Q7QUFDREMsT0FBS0MsT0FBTCxFQUFjQyxRQUFkLEVBQXdCO0FBQ3RCLFFBQUksS0FBS0MsS0FBTCxJQUFjLE9BQU8sS0FBS0Es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LFNBQU8sSUFBSVosa0JBQUosQ0FBdUJZLFVBQXZCLENBQVA7QUFDRCxDQUZEO1FBRzhCWixrQixHQUF0QkEsa0IiLCJmaWxlIjoidGVybS1zcGVjLmpzIiwic291cmNlc0NvbnRlbnQiOlsiY2xhc3MgVGVybSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzYzLCB0eXBlXzY0KSB7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLCBhdHRyc182Myk7XG4gICAgdGhpcy50eXBlID0gdHlwZV82NCB8fCBcIlRlcm1cIjtcbiAgICB0aGlzLmxvYyA9IG51bGw7XG4gICAgT2JqZWN0LmZyZWV6ZSh0aGlzKTtcbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl82NSwgc3RhdGVfNjYgPSB7fSkge1xuICAgIHJldHVybiBzdGF0ZV82NjtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4ge307XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfNjcpIHtcbiAgICBsZXQgc3RhdGVfNjggPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzY3KTtcbiAgICByZXR1cm4gcmVkdWNlcl82Ny5yZWR1Y2VUZXJtKHRoaXMsIHN0YXRlXzY4KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfNjkpIHtcbiAgICByZXR1cm4gbmV3IFRlcm0oT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzY5KSk7XG4gIH1cbiAgZnJvbSh0eXBlXzcwLCB2YWx1ZV83MSkge1xuICAgIGlmICh0aGlzLnZhbHVlICYmIHR5cGVvZiB0aGlzLnZhbHVlLmZyb20gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgcmV0dXJuIHRoaXMudmFsdWUuZnJvbSh0eXBlXzcwLCB2YWx1ZV83MSk7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihcIk5vdCBpbXBsZW1lbnRlZCB5ZXRcIik7XG4gIH1cbiAgZnJvbU51bGwoKSB7XG4gICAgcmV0dXJuIHRoaXMuZnJvbShcIm51bGxcIiwgbnVsbCk7XG4gIH1cbiAgZnJvbU51bWJlcih2YWx1ZV83Mikge1xuICAgIHJldHVybiB0aGlzLmZyb20oXCJudW1iZXJcIiwgdmFsdWVfNzIpO1xuICB9XG4gIGZyb21TdHJpbmcodmFsdWVfNzMpIHtcbiAgICByZXR1cm4gdGhpcy5mcm9tKFwic3RyaW5nXCIsIHZhbHVlXzczKTtcbiAgfVxuICBmcm9tUHVuY3R1YXRvcih2YWx1ZV83NCkge1xuICAgIHJldHVybiB0aGlzLmZyb20oXCJwdW5jdHVhdG9yXCIsIHZhbHVlXzc0KTtcbiAgfVxuICBmcm9tS2V5d29yZCh2YWx1ZV83NSkge1xuICAgIHJldHVybiB0aGlzLmZyb20oXCJrZXl3b3JkXCIsIHZhbHVlXzc1KTtcbiAgfVxuICBmcm9tSWRlbnRpZmllcih2YWx1ZV83Nikge1xuICAgIHJldHVybiB0aGlzLmZyb20oXCJpZGVudGlmaWVyXCIsIHZhbHVlXzc2KTtcbiAgfVxuICBmcm9tUmVndWxhckV4cHJlc3Npb24odmFsdWVfNzcpIHtcbiAgICByZXR1cm4gdGhpcy5mcm9tKFwicmVndWxhckV4cHJlc3Npb25cIiwgdmFsdWVfNzcpO1xuICB9XG4gIGZyb21CcmFjZXMoaW5uZXJfNzgpIHtcbiAgICByZXR1cm4gdGhpcy5mcm9tKFwiYnJhY2VzXCIsIGlubmVyXzc4KTtcbiAgfVxuICBmcm9tQnJhY2tldHMoaW5uZXJfNzkpIHtcbiAgICByZXR1cm4gdGhpcy5mcm9tKFwiYnJhY2tldHNcIiwgaW5uZXJfNzkpO1xuICB9XG4gIGZyb21QYXJlbnMoaW5uZXJfODApIHtcbiAgICByZXR1cm4gdGhpcy5mcm9tKFwicGFyZW5zXCIsIGlubmVyXzgwKTtcbiAgfVxufVxuVGVybS5DbG9uZVJlZHVjZXIgPSBjbGFzcyB7XG4gIHJlZHVjZVRlcm0odGVybV84MSwgc3RhdGVfODIpIHtcbiAgICByZXR1cm4gbmV3IFRlcm0oc3RhdGVfODIpO1xuICB9XG59O1xuZXhwb3J0IGRlZmF1bHQgVGVybTtcbmNsYXNzIFN5bnRheFRlcm0gZXh0ZW5kcyBUZXJtIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfODMsIHR5cGVfODQpIHtcbiAgICBzdXBlcihhdHRyc184MywgdHlwZV84NCB8fCBcIlN5bnRheFRlcm1cIik7XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfODUsIHN0YXRlXzg2ID0ge30pIHtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzg1LCBzdGF0ZV84Nik7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzg3KSB7XG4gICAgbGV0IHN0YXRlXzg4ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl84Nyk7XG4gICAgcmV0dXJuIHJlZHVjZXJfODcucmVkdWNlU3ludGF4VGVybSh0aGlzLCBzdGF0ZV84OCk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzg5KSB7XG4gICAgcmV0dXJuIG5ldyBTeW50YXhUZXJtKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc184OSkpO1xuICB9XG59XG5UZXJtLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlU3ludGF4VGVybSA9IGZ1bmN0aW9uICh0ZXJtXzkwLCBzdGF0ZV85MSkge1xuICByZXR1cm4gbmV3IFN5bnRheFRlcm0oc3RhdGVfOTEpO1xufTtcbmV4cG9ydCB7U3ludGF4VGVybSBhcyBTeW50YXhUZXJtfTtcbmNsYXNzIFJhd0RlbGltaXRlciBleHRlbmRzIFN5bnRheFRlcm0ge1xuICBjb25zdHJ1Y3RvcihhdHRyc185MiwgdHlwZV85Mykge1xuICAgIHN1cGVyKGF0dHJzXzkyLCB0eXBlXzkzIHx8IFwiUmF3RGVsaW1pdGVyXCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc185MiwgXCJraW5kXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImtpbmRcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc185MiwgXCJpbm5lclwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJpbm5lclwiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfOTQsIHN0YXRlXzk1ID0ge30pIHtcbiAgICBzdGF0ZV85NS5raW5kID0gdGhpcy5raW5kO1xuICAgIHN0YXRlXzk1LmlubmVyID0gdGhpcy5pbm5lci5tYXAoYV85NiA9PiBhXzk2IGluc3RhbmNlb2YgVGVybSA/IGFfOTYucmVkdWNlKHJlZHVjZXJfOTQpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkoYV85NikpO1xuICAgIH0uY2FsbCh0aGlzKSk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl85NCwgc3RhdGVfOTUpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtraW5kOiB0aGlzLmtpbmQsIGlubmVyOiB0aGlzLmlubmVyfSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfOTcpIHtcbiAgICBsZXQgc3RhdGVfOTggPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzk3KTtcbiAgICByZXR1cm4gcmVkdWNlcl85Ny5yZWR1Y2VSYXdEZWxpbWl0ZXIodGhpcywgc3RhdGVfOTgpO1xuICB9XG4gIGV4dGVuZChhdHRyc185OSkge1xuICAgIHJldHVybiBuZXcgUmF3RGVsaW1pdGVyKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc185OSkpO1xuICB9XG59XG5TeW50YXhUZXJtLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlUmF3RGVsaW1pdGVyID0gZnVuY3Rpb24gKHRlcm1fMTAwLCBzdGF0ZV8xMDEpIHtcbiAgcmV0dXJuIG5ldyBSYXdEZWxpbWl0ZXIoc3RhdGVfMTAxKTtcbn07XG5leHBvcnQge1Jhd0RlbGltaXRlciBhcyBSYXdEZWxpbWl0ZXJ9O1xuY2xhc3MgUmF3U3ludGF4IGV4dGVuZHMgU3ludGF4VGVybSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzEwMiwgdHlwZV8xMDMpIHtcbiAgICBzdXBlcihhdHRyc18xMDIsIHR5cGVfMTAzIHx8IFwiUmF3U3ludGF4XCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc18xMDIsIFwidmFsdWVcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwidmFsdWVcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzEwNCwgc3RhdGVfMTA1ID0ge30pIHtcbiAgICBzdGF0ZV8xMDUudmFsdWUgPSB0aGlzLnZhbHVlO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTA0LCBzdGF0ZV8xMDUpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt2YWx1ZTogdGhpcy52YWx1ZX0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzEwNikge1xuICAgIGxldCBzdGF0ZV8xMDcgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzEwNik7XG4gICAgcmV0dXJuIHJlZHVjZXJfMTA2LnJlZHVjZVJhd1N5bnRheCh0aGlzLCBzdGF0ZV8xMDcpO1xuICB9XG4gIGV4dGVuZChhdHRyc18xMDgpIHtcbiAgICByZXR1cm4gbmV3IFJhd1N5bnRheChPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfMTA4KSk7XG4gIH1cbn1cblN5bnRheFRlcm0uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VSYXdTeW50YXggPSBmdW5jdGlvbiAodGVybV8xMDksIHN0YXRlXzExMCkge1xuICByZXR1cm4gbmV3IFJhd1N5bnRheChzdGF0ZV8xMTApO1xufTtcbmV4cG9ydCB7UmF3U3ludGF4IGFzIFJhd1N5bnRheH07XG5jbGFzcyBTdGF0ZW1lbnQgZXh0ZW5kcyBUZXJtIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfMTExLCB0eXBlXzExMikge1xuICAgIHN1cGVyKGF0dHJzXzExMSwgdHlwZV8xMTIgfHwgXCJTdGF0ZW1lbnRcIik7XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTEzLCBzdGF0ZV8xMTQgPSB7fSkge1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTEzLCBzdGF0ZV8xMTQpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl8xMTUpIHtcbiAgICBsZXQgc3RhdGVfMTE2ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl8xMTUpO1xuICAgIHJldHVybiByZWR1Y2VyXzExNS5yZWR1Y2VTdGF0ZW1lbnQodGhpcywgc3RhdGVfMTE2KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfMTE3KSB7XG4gICAgcmV0dXJuIG5ldyBTdGF0ZW1lbnQoT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzExNykpO1xuICB9XG59XG5UZXJtLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlU3RhdGVtZW50ID0gZnVuY3Rpb24gKHRlcm1fMTE4LCBzdGF0ZV8xMTkpIHtcbiAgcmV0dXJuIG5ldyBTdGF0ZW1lbnQoc3RhdGVfMTE5KTtcbn07XG5leHBvcnQge1N0YXRlbWVudCBhcyBTdGF0ZW1lbnR9O1xuY2xhc3MgSXRlcmF0aW9uU3RhdGVtZW50IGV4dGVuZHMgU3RhdGVtZW50IHtcbiAgY29uc3RydWN0b3IoYXR0cnNfMTIwLCB0eXBlXzEyMSkge1xuICAgIHN1cGVyKGF0dHJzXzEyMCwgdHlwZV8xMjEgfHwgXCJJdGVyYXRpb25TdGF0ZW1lbnRcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzEyMCwgXCJib2R5XCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImJvZHlcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzEyMiwgc3RhdGVfMTIzID0ge30pIHtcbiAgICBzdGF0ZV8xMjMuYm9keSA9IHRoaXMuYm9keSBpbnN0YW5jZW9mIFN0YXRlbWVudCA/IHRoaXMuYm9keS5yZWR1Y2UocmVkdWNlcl8xMjIpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5ib2R5KSk7XG4gICAgfS5jYWxsKHRoaXMpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTIyLCBzdGF0ZV8xMjMpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtib2R5OiB0aGlzLmJvZHl9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl8xMjQpIHtcbiAgICBsZXQgc3RhdGVfMTI1ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl8xMjQpO1xuICAgIHJldHVybiByZWR1Y2VyXzEyNC5yZWR1Y2VJdGVyYXRpb25TdGF0ZW1lbnQodGhpcywgc3RhdGVfMTI1KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfMTI2KSB7XG4gICAgcmV0dXJuIG5ldyBJdGVyYXRpb25TdGF0ZW1lbnQoT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzEyNikpO1xuICB9XG59XG5TdGF0ZW1lbnQuQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VJdGVyYXRpb25TdGF0ZW1lbnQgPSBmdW5jdGlvbiAodGVybV8xMjcsIHN0YXRlXzEyOCkge1xuICByZXR1cm4gbmV3IEl0ZXJhdGlvblN0YXRlbWVudChzdGF0ZV8xMjgpO1xufTtcbmV4cG9ydCB7SXRlcmF0aW9uU3RhdGVtZW50IGFzIEl0ZXJhdGlvblN0YXRlbWVudH07XG5jbGFzcyBFeHByZXNzaW9uIGV4dGVuZHMgVGVybSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzEyOSwgdHlwZV8xMzApIHtcbiAgICBzdXBlcihhdHRyc18xMjksIHR5cGVfMTMwIHx8IFwiRXhwcmVzc2lvblwiKTtcbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl8xMzEsIHN0YXRlXzEzMiA9IHt9KSB7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl8xMzEsIHN0YXRlXzEzMik7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzEzMykge1xuICAgIGxldCBzdGF0ZV8xMzQgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzEzMyk7XG4gICAgcmV0dXJuIHJlZHVjZXJfMTMzLnJlZHVjZUV4cHJlc3Npb24odGhpcywgc3RhdGVfMTM0KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfMTM1KSB7XG4gICAgcmV0dXJuIG5ldyBFeHByZXNzaW9uKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc18xMzUpKTtcbiAgfVxufVxuVGVybS5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZUV4cHJlc3Npb24gPSBmdW5jdGlvbiAodGVybV8xMzYsIHN0YXRlXzEzNykge1xuICByZXR1cm4gbmV3IEV4cHJlc3Npb24oc3RhdGVfMTM3KTtcbn07XG5leHBvcnQge0V4cHJlc3Npb24gYXMgRXhwcmVzc2lvbn07XG5jbGFzcyBNZW1iZXJFeHByZXNzaW9uIGV4dGVuZHMgRXhwcmVzc2lvbiB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzEzOCwgdHlwZV8xMzkpIHtcbiAgICBzdXBlcihhdHRyc18xMzgsIHR5cGVfMTM5IHx8IFwiTWVtYmVyRXhwcmVzc2lvblwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfMTM4LCBcIm9iamVjdFwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJvYmplY3RcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzE0MCwgc3RhdGVfMTQxID0ge30pIHtcbiAgICBzdGF0ZV8xNDEub2JqZWN0ID0gdGhpcy5vYmplY3QgaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gdGhpcy5vYmplY3QucmVkdWNlKHJlZHVjZXJfMTQwKSA6IHRoaXMub2JqZWN0IGluc3RhbmNlb2YgU3VwZXIgPyB0aGlzLm9iamVjdC5yZWR1Y2UocmVkdWNlcl8xNDApIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5vYmplY3QpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl8xNDAsIHN0YXRlXzE0MSk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe29iamVjdDogdGhpcy5vYmplY3R9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl8xNDIpIHtcbiAgICBsZXQgc3RhdGVfMTQzID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl8xNDIpO1xuICAgIHJldHVybiByZWR1Y2VyXzE0Mi5yZWR1Y2VNZW1iZXJFeHByZXNzaW9uKHRoaXMsIHN0YXRlXzE0Myk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzE0NCkge1xuICAgIHJldHVybiBuZXcgTWVtYmVyRXhwcmVzc2lvbihPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfMTQ0KSk7XG4gIH1cbn1cbkV4cHJlc3Npb24uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VNZW1iZXJFeHByZXNzaW9uID0gZnVuY3Rpb24gKHRlcm1fMTQ1LCBzdGF0ZV8xNDYpIHtcbiAgcmV0dXJuIG5ldyBNZW1iZXJFeHByZXNzaW9uKHN0YXRlXzE0Nik7XG59O1xuZXhwb3J0IHtNZW1iZXJFeHByZXNzaW9uIGFzIE1lbWJlckV4cHJlc3Npb259O1xuY2xhc3MgUHJvcGVydHlOYW1lIGV4dGVuZHMgVGVybSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzE0NywgdHlwZV8xNDgpIHtcbiAgICBzdXBlcihhdHRyc18xNDcsIHR5cGVfMTQ4IHx8IFwiUHJvcGVydHlOYW1lXCIpO1xuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzE0OSwgc3RhdGVfMTUwID0ge30pIHtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzE0OSwgc3RhdGVfMTUwKTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfMTUxKSB7XG4gICAgbGV0IHN0YXRlXzE1MiA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTUxKTtcbiAgICByZXR1cm4gcmVkdWNlcl8xNTEucmVkdWNlUHJvcGVydHlOYW1lKHRoaXMsIHN0YXRlXzE1Mik7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzE1Mykge1xuICAgIHJldHVybiBuZXcgUHJvcGVydHlOYW1lKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc18xNTMpKTtcbiAgfVxufVxuVGVybS5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZVByb3BlcnR5TmFtZSA9IGZ1bmN0aW9uICh0ZXJtXzE1NCwgc3RhdGVfMTU1KSB7XG4gIHJldHVybiBuZXcgUHJvcGVydHlOYW1lKHN0YXRlXzE1NSk7XG59O1xuZXhwb3J0IHtQcm9wZXJ0eU5hbWUgYXMgUHJvcGVydHlOYW1lfTtcbmNsYXNzIE9iamVjdFByb3BlcnR5IGV4dGVuZHMgVGVybSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzE1NiwgdHlwZV8xNTcpIHtcbiAgICBzdXBlcihhdHRyc18xNTYsIHR5cGVfMTU3IHx8IFwiT2JqZWN0UHJvcGVydHlcIik7XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTU4LCBzdGF0ZV8xNTkgPSB7fSkge1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTU4LCBzdGF0ZV8xNTkpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl8xNjApIHtcbiAgICBsZXQgc3RhdGVfMTYxID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl8xNjApO1xuICAgIHJldHVybiByZWR1Y2VyXzE2MC5yZWR1Y2VPYmplY3RQcm9wZXJ0eSh0aGlzLCBzdGF0ZV8xNjEpO1xuICB9XG4gIGV4dGVuZChhdHRyc18xNjIpIHtcbiAgICByZXR1cm4gbmV3IE9iamVjdFByb3BlcnR5KE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc18xNjIpKTtcbiAgfVxufVxuVGVybS5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZU9iamVjdFByb3BlcnR5ID0gZnVuY3Rpb24gKHRlcm1fMTYzLCBzdGF0ZV8xNjQpIHtcbiAgcmV0dXJuIG5ldyBPYmplY3RQcm9wZXJ0eShzdGF0ZV8xNjQpO1xufTtcbmV4cG9ydCB7T2JqZWN0UHJvcGVydHkgYXMgT2JqZWN0UHJvcGVydHl9O1xuY2xhc3MgTmFtZWRPYmplY3RQcm9wZXJ0eSBleHRlbmRzIE9iamVjdFByb3BlcnR5IHtcbiAgY29uc3RydWN0b3IoYXR0cnNfMTY1LCB0eXBlXzE2Nikge1xuICAgIHN1cGVyKGF0dHJzXzE2NSwgdHlwZV8xNjYgfHwgXCJOYW1lZE9iamVjdFByb3BlcnR5XCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc18xNjUsIFwibmFtZVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJuYW1lXCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl8xNjcsIHN0YXRlXzE2OCA9IHt9KSB7XG4gICAgc3RhdGVfMTY4Lm5hbWUgPSB0aGlzLm5hbWUgaW5zdGFuY2VvZiBQcm9wZXJ0eU5hbWUgPyB0aGlzLm5hbWUucmVkdWNlKHJlZHVjZXJfMTY3KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMubmFtZSkpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzE2Nywgc3RhdGVfMTY4KTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7bmFtZTogdGhpcy5uYW1lfSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfMTY5KSB7XG4gICAgbGV0IHN0YXRlXzE3MCA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTY5KTtcbiAgICByZXR1cm4gcmVkdWNlcl8xNjkucmVkdWNlTmFtZWRPYmplY3RQcm9wZXJ0eSh0aGlzLCBzdGF0ZV8xNzApO1xuICB9XG4gIGV4dGVuZChhdHRyc18xNzEpIHtcbiAgICByZXR1cm4gbmV3IE5hbWVkT2JqZWN0UHJvcGVydHkoT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzE3MSkpO1xuICB9XG59XG5PYmplY3RQcm9wZXJ0eS5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZU5hbWVkT2JqZWN0UHJvcGVydHkgPSBmdW5jdGlvbiAodGVybV8xNzIsIHN0YXRlXzE3Mykge1xuICByZXR1cm4gbmV3IE5hbWVkT2JqZWN0UHJvcGVydHkoc3RhdGVfMTczKTtcbn07XG5leHBvcnQge05hbWVkT2JqZWN0UHJvcGVydHkgYXMgTmFtZWRPYmplY3RQcm9wZXJ0eX07XG5jbGFzcyBNZXRob2REZWZpbml0aW9uIGV4dGVuZHMgTmFtZWRPYmplY3RQcm9wZXJ0eSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzE3NCwgdHlwZV8xNzUpIHtcbiAgICBzdXBlcihhdHRyc18xNzQsIHR5cGVfMTc1IHx8IFwiTWV0aG9kRGVmaW5pdGlvblwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfMTc0LCBcImJvZHlcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiYm9keVwiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTc2LCBzdGF0ZV8xNzcgPSB7fSkge1xuICAgIHN0YXRlXzE3Ny5ib2R5ID0gdGhpcy5ib2R5IGluc3RhbmNlb2YgRnVuY3Rpb25Cb2R5ID8gdGhpcy5ib2R5LnJlZHVjZShyZWR1Y2VyXzE3NikgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmJvZHkpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl8xNzYsIHN0YXRlXzE3Nyk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe2JvZHk6IHRoaXMuYm9keX0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzE3OCkge1xuICAgIGxldCBzdGF0ZV8xNzkgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzE3OCk7XG4gICAgcmV0dXJuIHJlZHVjZXJfMTc4LnJlZHVjZU1ldGhvZERlZmluaXRpb24odGhpcywgc3RhdGVfMTc5KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfMTgwKSB7XG4gICAgcmV0dXJuIG5ldyBNZXRob2REZWZpbml0aW9uKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc18xODApKTtcbiAgfVxufVxuTmFtZWRPYmplY3RQcm9wZXJ0eS5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZU1ldGhvZERlZmluaXRpb24gPSBmdW5jdGlvbiAodGVybV8xODEsIHN0YXRlXzE4Mikge1xuICByZXR1cm4gbmV3IE1ldGhvZERlZmluaXRpb24oc3RhdGVfMTgyKTtcbn07XG5leHBvcnQge01ldGhvZERlZmluaXRpb24gYXMgTWV0aG9kRGVmaW5pdGlvbn07XG5jbGFzcyBCaW5kaW5nV2l0aERlZmF1bHQgZXh0ZW5kcyBUZXJtIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfMTgzLCB0eXBlXzE4NCkge1xuICAgIHN1cGVyKGF0dHJzXzE4MywgdHlwZV8xODQgfHwgXCJCaW5kaW5nV2l0aERlZmF1bHRcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzE4MywgXCJiaW5kaW5nXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImJpbmRpbmdcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc18xODMsIFwiaW5pdFwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJpbml0XCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl8xODUsIHN0YXRlXzE4NiA9IHt9KSB7XG4gICAgc3RhdGVfMTg2LmJpbmRpbmcgPSB0aGlzLmJpbmRpbmcgaW5zdGFuY2VvZiBPYmplY3RCaW5kaW5nID8gdGhpcy5iaW5kaW5nLnJlZHVjZShyZWR1Y2VyXzE4NSkgOiB0aGlzLmJpbmRpbmcgaW5zdGFuY2VvZiBBcnJheUJpbmRpbmcgPyB0aGlzLmJpbmRpbmcucmVkdWNlKHJlZHVjZXJfMTg1KSA6IHRoaXMuYmluZGluZyBpbnN0YW5jZW9mIEJpbmRpbmdJZGVudGlmaWVyID8gdGhpcy5iaW5kaW5nLnJlZHVjZShyZWR1Y2VyXzE4NSkgOiB0aGlzLmJpbmRpbmcgaW5zdGFuY2VvZiBNZW1iZXJFeHByZXNzaW9uID8gdGhpcy5iaW5kaW5nLnJlZHVjZShyZWR1Y2VyXzE4NSkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmJpbmRpbmcpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfMTg2LmluaXQgPSB0aGlzLmluaXQgaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gdGhpcy5pbml0LnJlZHVjZShyZWR1Y2VyXzE4NSkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmluaXQpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl8xODUsIHN0YXRlXzE4Nik7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe2JpbmRpbmc6IHRoaXMuYmluZGluZywgaW5pdDogdGhpcy5pbml0fSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfMTg3KSB7XG4gICAgbGV0IHN0YXRlXzE4OCA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTg3KTtcbiAgICByZXR1cm4gcmVkdWNlcl8xODcucmVkdWNlQmluZGluZ1dpdGhEZWZhdWx0KHRoaXMsIHN0YXRlXzE4OCk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzE4OSkge1xuICAgIHJldHVybiBuZXcgQmluZGluZ1dpdGhEZWZhdWx0KE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc18xODkpKTtcbiAgfVxufVxuVGVybS5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZUJpbmRpbmdXaXRoRGVmYXVsdCA9IGZ1bmN0aW9uICh0ZXJtXzE5MCwgc3RhdGVfMTkxKSB7XG4gIHJldHVybiBuZXcgQmluZGluZ1dpdGhEZWZhdWx0KHN0YXRlXzE5MSk7XG59O1xuZXhwb3J0IHtCaW5kaW5nV2l0aERlZmF1bHQgYXMgQmluZGluZ1dpdGhEZWZhdWx0fTtcbmNsYXNzIEJpbmRpbmdJZGVudGlmaWVyIGV4dGVuZHMgVGVybSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzE5MiwgdHlwZV8xOTMpIHtcbiAgICBzdXBlcihhdHRyc18xOTIsIHR5cGVfMTkzIHx8IFwiQmluZGluZ0lkZW50aWZpZXJcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzE5MiwgXCJuYW1lXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcIm5hbWVcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzE5NCwgc3RhdGVfMTk1ID0ge30pIHtcbiAgICBzdGF0ZV8xOTUubmFtZSA9IHRoaXMubmFtZTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzE5NCwgc3RhdGVfMTk1KTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7bmFtZTogdGhpcy5uYW1lfSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfMTk2KSB7XG4gICAgbGV0IHN0YXRlXzE5NyA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTk2KTtcbiAgICByZXR1cm4gcmVkdWNlcl8xOTYucmVkdWNlQmluZGluZ0lkZW50aWZpZXIodGhpcywgc3RhdGVfMTk3KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfMTk4KSB7XG4gICAgcmV0dXJuIG5ldyBCaW5kaW5nSWRlbnRpZmllcihPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfMTk4KSk7XG4gIH1cbn1cblRlcm0uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VCaW5kaW5nSWRlbnRpZmllciA9IGZ1bmN0aW9uICh0ZXJtXzE5OSwgc3RhdGVfMjAwKSB7XG4gIHJldHVybiBuZXcgQmluZGluZ0lkZW50aWZpZXIoc3RhdGVfMjAwKTtcbn07XG5leHBvcnQge0JpbmRpbmdJZGVudGlmaWVyIGFzIEJpbmRpbmdJZGVudGlmaWVyfTtcbmNsYXNzIEFycmF5QmluZGluZyBleHRlbmRzIFRlcm0ge1xuICBjb25zdHJ1Y3RvcihhdHRyc18yMDEsIHR5cGVfMjAyKSB7XG4gICAgc3VwZXIoYXR0cnNfMjAxLCB0eXBlXzIwMiB8fCBcIkFycmF5QmluZGluZ1wiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfMjAxLCBcImVsZW1lbnRzXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImVsZW1lbnRzXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfMjAxLCBcInJlc3RFbGVtZW50XCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcInJlc3RFbGVtZW50XCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl8yMDMsIHN0YXRlXzIwNCA9IHt9KSB7XG4gICAgc3RhdGVfMjA0LmVsZW1lbnRzID0gdGhpcy5lbGVtZW50cy5tYXAoYV8yMDUgPT4gYV8yMDUgaW5zdGFuY2VvZiBPYmplY3RCaW5kaW5nID8gYV8yMDUucmVkdWNlKHJlZHVjZXJfMjAzKSA6IGFfMjA1IGluc3RhbmNlb2YgQXJyYXlCaW5kaW5nID8gYV8yMDUucmVkdWNlKHJlZHVjZXJfMjAzKSA6IGFfMjA1IGluc3RhbmNlb2YgQmluZGluZ0lkZW50aWZpZXIgPyBhXzIwNS5yZWR1Y2UocmVkdWNlcl8yMDMpIDogYV8yMDUgaW5zdGFuY2VvZiBNZW1iZXJFeHByZXNzaW9uID8gYV8yMDUucmVkdWNlKHJlZHVjZXJfMjAzKSA6IGFfMjA1IGluc3RhbmNlb2YgQmluZGluZ1dpdGhEZWZhdWx0ID8gYV8yMDUucmVkdWNlKHJlZHVjZXJfMjAzKSA6IGFfMjA1ID09IG51bGwgPyBudWxsIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkoYV8yMDUpKTtcbiAgICB9LmNhbGwodGhpcykpO1xuICAgIHN0YXRlXzIwNC5yZXN0RWxlbWVudCA9IHRoaXMucmVzdEVsZW1lbnQgPT0gbnVsbCA/IG51bGwgOiB0aGlzLnJlc3RFbGVtZW50IGluc3RhbmNlb2YgT2JqZWN0QmluZGluZyA/IHRoaXMucmVzdEVsZW1lbnQucmVkdWNlKHJlZHVjZXJfMjAzKSA6IHRoaXMucmVzdEVsZW1lbnQgaW5zdGFuY2VvZiBBcnJheUJpbmRpbmcgPyB0aGlzLnJlc3RFbGVtZW50LnJlZHVjZShyZWR1Y2VyXzIwMykgOiB0aGlzLnJlc3RFbGVtZW50IGluc3RhbmNlb2YgQmluZGluZ0lkZW50aWZpZXIgPyB0aGlzLnJlc3RFbGVtZW50LnJlZHVjZShyZWR1Y2VyXzIwMykgOiB0aGlzLnJlc3RFbGVtZW50IGluc3RhbmNlb2YgTWVtYmVyRXhwcmVzc2lvbiA/IHRoaXMucmVzdEVsZW1lbnQucmVkdWNlKHJlZHVjZXJfMjAzKSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMucmVzdEVsZW1lbnQpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl8yMDMsIHN0YXRlXzIwNCk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe2VsZW1lbnRzOiB0aGlzLmVsZW1lbnRzLCByZXN0RWxlbWVudDogdGhpcy5yZXN0RWxlbWVudH0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzIwNikge1xuICAgIGxldCBzdGF0ZV8yMDcgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzIwNik7XG4gICAgcmV0dXJuIHJlZHVjZXJfMjA2LnJlZHVjZUFycmF5QmluZGluZyh0aGlzLCBzdGF0ZV8yMDcpO1xuICB9XG4gIGV4dGVuZChhdHRyc18yMDgpIHtcbiAgICByZXR1cm4gbmV3IEFycmF5QmluZGluZyhPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfMjA4KSk7XG4gIH1cbn1cblRlcm0uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VBcnJheUJpbmRpbmcgPSBmdW5jdGlvbiAodGVybV8yMDksIHN0YXRlXzIxMCkge1xuICByZXR1cm4gbmV3IEFycmF5QmluZGluZyhzdGF0ZV8yMTApO1xufTtcbmV4cG9ydCB7QXJyYXlCaW5kaW5nIGFzIEFycmF5QmluZGluZ307XG5jbGFzcyBPYmplY3RCaW5kaW5nIGV4dGVuZHMgVGVybSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzIxMSwgdHlwZV8yMTIpIHtcbiAgICBzdXBlcihhdHRyc18yMTEsIHR5cGVfMjEyIHx8IFwiT2JqZWN0QmluZGluZ1wiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfMjExLCBcInByb3BlcnRpZXNcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwicHJvcGVydGllc1wiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfMjEzLCBzdGF0ZV8yMTQgPSB7fSkge1xuICAgIHN0YXRlXzIxNC5wcm9wZXJ0aWVzID0gdGhpcy5wcm9wZXJ0aWVzLm1hcChhXzIxNSA9PiBhXzIxNSBpbnN0YW5jZW9mIEJpbmRpbmdQcm9wZXJ0eSA/IGFfMjE1LnJlZHVjZShyZWR1Y2VyXzIxMykgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeShhXzIxNSkpO1xuICAgIH0uY2FsbCh0aGlzKSk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl8yMTMsIHN0YXRlXzIxNCk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe3Byb3BlcnRpZXM6IHRoaXMucHJvcGVydGllc30sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzIxNikge1xuICAgIGxldCBzdGF0ZV8yMTcgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzIxNik7XG4gICAgcmV0dXJuIHJlZHVjZXJfMjE2LnJlZHVjZU9iamVjdEJpbmRpbmcodGhpcywgc3RhdGVfMjE3KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfMjE4KSB7XG4gICAgcmV0dXJuIG5ldyBPYmplY3RCaW5kaW5nKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc18yMTgpKTtcbiAgfVxufVxuVGVybS5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZU9iamVjdEJpbmRpbmcgPSBmdW5jdGlvbiAodGVybV8yMTksIHN0YXRlXzIyMCkge1xuICByZXR1cm4gbmV3IE9iamVjdEJpbmRpbmcoc3RhdGVfMjIwKTtcbn07XG5leHBvcnQge09iamVjdEJpbmRpbmcgYXMgT2JqZWN0QmluZGluZ307XG5jbGFzcyBCaW5kaW5nUHJvcGVydHkgZXh0ZW5kcyBUZXJtIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfMjIxLCB0eXBlXzIyMikge1xuICAgIHN1cGVyKGF0dHJzXzIyMSwgdHlwZV8yMjIgfHwgXCJCaW5kaW5nUHJvcGVydHlcIik7XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfMjIzLCBzdGF0ZV8yMjQgPSB7fSkge1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMjIzLCBzdGF0ZV8yMjQpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl8yMjUpIHtcbiAgICBsZXQgc3RhdGVfMjI2ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl8yMjUpO1xuICAgIHJldHVybiByZWR1Y2VyXzIyNS5yZWR1Y2VCaW5kaW5nUHJvcGVydHkodGhpcywgc3RhdGVfMjI2KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfMjI3KSB7XG4gICAgcmV0dXJuIG5ldyBCaW5kaW5nUHJvcGVydHkoT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzIyNykpO1xuICB9XG59XG5UZXJtLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlQmluZGluZ1Byb3BlcnR5ID0gZnVuY3Rpb24gKHRlcm1fMjI4LCBzdGF0ZV8yMjkpIHtcbiAgcmV0dXJuIG5ldyBCaW5kaW5nUHJvcGVydHkoc3RhdGVfMjI5KTtcbn07XG5leHBvcnQge0JpbmRpbmdQcm9wZXJ0eSBhcyBCaW5kaW5nUHJvcGVydHl9O1xuY2xhc3MgQmluZGluZ1Byb3BlcnR5SWRlbnRpZmllciBleHRlbmRzIEJpbmRpbmdQcm9wZXJ0eSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzIzMCwgdHlwZV8yMzEpIHtcbiAgICBzdXBlcihhdHRyc18yMzAsIHR5cGVfMjMxIHx8IFwiQmluZGluZ1Byb3BlcnR5SWRlbnRpZmllclwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfMjMwLCBcImJpbmRpbmdcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiYmluZGluZ1wiKTtcbiAgICB9XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzIzMCwgXCJpbml0XCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImluaXRcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzIzMiwgc3RhdGVfMjMzID0ge30pIHtcbiAgICBzdGF0ZV8yMzMuYmluZGluZyA9IHRoaXMuYmluZGluZyBpbnN0YW5jZW9mIEJpbmRpbmdJZGVudGlmaWVyID8gdGhpcy5iaW5kaW5nLnJlZHVjZShyZWR1Y2VyXzIzMikgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmJpbmRpbmcpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfMjMzLmluaXQgPSB0aGlzLmluaXQgPT0gbnVsbCA/IG51bGwgOiB0aGlzLmluaXQgaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gdGhpcy5pbml0LnJlZHVjZShyZWR1Y2VyXzIzMikgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmluaXQpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl8yMzIsIHN0YXRlXzIzMyk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe2JpbmRpbmc6IHRoaXMuYmluZGluZywgaW5pdDogdGhpcy5pbml0fSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfMjM0KSB7XG4gICAgbGV0IHN0YXRlXzIzNSA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMjM0KTtcbiAgICByZXR1cm4gcmVkdWNlcl8yMzQucmVkdWNlQmluZGluZ1Byb3BlcnR5SWRlbnRpZmllcih0aGlzLCBzdGF0ZV8yMzUpO1xuICB9XG4gIGV4dGVuZChhdHRyc18yMzYpIHtcbiAgICByZXR1cm4gbmV3IEJpbmRpbmdQcm9wZXJ0eUlkZW50aWZpZXIoT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzIzNikpO1xuICB9XG59XG5CaW5kaW5nUHJvcGVydHkuQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VCaW5kaW5nUHJvcGVydHlJZGVudGlmaWVyID0gZnVuY3Rpb24gKHRlcm1fMjM3LCBzdGF0ZV8yMzgpIHtcbiAgcmV0dXJuIG5ldyBCaW5kaW5nUHJvcGVydHlJZGVudGlmaWVyKHN0YXRlXzIzOCk7XG59O1xuZXhwb3J0IHtCaW5kaW5nUHJvcGVydHlJZGVudGlmaWVyIGFzIEJpbmRpbmdQcm9wZXJ0eUlkZW50aWZpZXJ9O1xuY2xhc3MgQmluZGluZ1Byb3BlcnR5UHJvcGVydHkgZXh0ZW5kcyBCaW5kaW5nUHJvcGVydHkge1xuICBjb25zdHJ1Y3RvcihhdHRyc18yMzksIHR5cGVfMjQwKSB7XG4gICAgc3VwZXIoYXR0cnNfMjM5LCB0eXBlXzI0MCB8fCBcIkJpbmRpbmdQcm9wZXJ0eVByb3BlcnR5XCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc18yMzksIFwibmFtZVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJuYW1lXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfMjM5LCBcImJpbmRpbmdcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiYmluZGluZ1wiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfMjQxLCBzdGF0ZV8yNDIgPSB7fSkge1xuICAgIHN0YXRlXzI0Mi5uYW1lID0gdGhpcy5uYW1lIGluc3RhbmNlb2YgUHJvcGVydHlOYW1lID8gdGhpcy5uYW1lLnJlZHVjZShyZWR1Y2VyXzI0MSkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLm5hbWUpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfMjQyLmJpbmRpbmcgPSB0aGlzLmJpbmRpbmcgaW5zdGFuY2VvZiBPYmplY3RCaW5kaW5nID8gdGhpcy5iaW5kaW5nLnJlZHVjZShyZWR1Y2VyXzI0MSkgOiB0aGlzLmJpbmRpbmcgaW5zdGFuY2VvZiBBcnJheUJpbmRpbmcgPyB0aGlzLmJpbmRpbmcucmVkdWNlKHJlZHVjZXJfMjQxKSA6IHRoaXMuYmluZGluZyBpbnN0YW5jZW9mIEJpbmRpbmdJZGVudGlmaWVyID8gdGhpcy5iaW5kaW5nLnJlZHVjZShyZWR1Y2VyXzI0MSkgOiB0aGlzLmJpbmRpbmcgaW5zdGFuY2VvZiBNZW1iZXJFeHByZXNzaW9uID8gdGhpcy5iaW5kaW5nLnJlZHVjZShyZWR1Y2VyXzI0MSkgOiB0aGlzLmJpbmRpbmcgaW5zdGFuY2VvZiBCaW5kaW5nV2l0aERlZmF1bHQgPyB0aGlzLmJpbmRpbmcucmVkdWNlKHJlZHVjZXJfMjQxKSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMuYmluZGluZykpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzI0MSwgc3RhdGVfMjQyKTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7bmFtZTogdGhpcy5uYW1lLCBiaW5kaW5nOiB0aGlzLmJpbmRpbmd9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl8yNDMpIHtcbiAgICBsZXQgc3RhdGVfMjQ0ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl8yNDMpO1xuICAgIHJldHVybiByZWR1Y2VyXzI0My5yZWR1Y2VCaW5kaW5nUHJvcGVydHlQcm9wZXJ0eSh0aGlzLCBzdGF0ZV8yNDQpO1xuICB9XG4gIGV4dGVuZChhdHRyc18yNDUpIHtcbiAgICByZXR1cm4gbmV3IEJpbmRpbmdQcm9wZXJ0eVByb3BlcnR5KE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc18yNDUpKTtcbiAgfVxufVxuQmluZGluZ1Byb3BlcnR5LkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlQmluZGluZ1Byb3BlcnR5UHJvcGVydHkgPSBmdW5jdGlvbiAodGVybV8yNDYsIHN0YXRlXzI0Nykge1xuICByZXR1cm4gbmV3IEJpbmRpbmdQcm9wZXJ0eVByb3BlcnR5KHN0YXRlXzI0Nyk7XG59O1xuZXhwb3J0IHtCaW5kaW5nUHJvcGVydHlQcm9wZXJ0eSBhcyBCaW5kaW5nUHJvcGVydHlQcm9wZXJ0eX07XG5jbGFzcyBDbGFzc0V4cHJlc3Npb24gZXh0ZW5kcyBFeHByZXNzaW9uIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfMjQ4LCB0eXBlXzI0OSkge1xuICAgIHN1cGVyKGF0dHJzXzI0OCwgdHlwZV8yNDkgfHwgXCJDbGFzc0V4cHJlc3Npb25cIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzI0OCwgXCJuYW1lXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcIm5hbWVcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc18yNDgsIFwic3VwZXJcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwic3VwZXJcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc18yNDgsIFwiZWxlbWVudHNcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiZWxlbWVudHNcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzI1MCwgc3RhdGVfMjUxID0ge30pIHtcbiAgICBzdGF0ZV8yNTEubmFtZSA9IHRoaXMubmFtZSA9PSBudWxsID8gbnVsbCA6IHRoaXMubmFtZSBpbnN0YW5jZW9mIEJpbmRpbmdJZGVudGlmaWVyID8gdGhpcy5uYW1lLnJlZHVjZShyZWR1Y2VyXzI1MCkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLm5hbWUpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfMjUxLnN1cGVyID0gdGhpcy5zdXBlciA9PSBudWxsID8gbnVsbCA6IHRoaXMuc3VwZXIgaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gdGhpcy5zdXBlci5yZWR1Y2UocmVkdWNlcl8yNTApIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5zdXBlcikpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICBzdGF0ZV8yNTEuZWxlbWVudHMgPSB0aGlzLmVsZW1lbnRzLm1hcChhXzI1MiA9PiBhXzI1MiBpbnN0YW5jZW9mIENsYXNzRWxlbWVudCA/IGFfMjUyLnJlZHVjZShyZWR1Y2VyXzI1MCkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeShhXzI1MikpO1xuICAgIH0uY2FsbCh0aGlzKSk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl8yNTAsIHN0YXRlXzI1MSk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe25hbWU6IHRoaXMubmFtZSwgc3VwZXI6IHRoaXMuc3VwZXIsIGVsZW1lbnRzOiB0aGlzLmVsZW1lbnRzfSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfMjUzKSB7XG4gICAgbGV0IHN0YXRlXzI1NCA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMjUzKTtcbiAgICByZXR1cm4gcmVkdWNlcl8yNTMucmVkdWNlQ2xhc3NFeHByZXNzaW9uKHRoaXMsIHN0YXRlXzI1NCk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzI1NSkge1xuICAgIHJldHVybiBuZXcgQ2xhc3NFeHByZXNzaW9uKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc18yNTUpKTtcbiAgfVxufVxuRXhwcmVzc2lvbi5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZUNsYXNzRXhwcmVzc2lvbiA9IGZ1bmN0aW9uICh0ZXJtXzI1Niwgc3RhdGVfMjU3KSB7XG4gIHJldHVybiBuZXcgQ2xhc3NFeHByZXNzaW9uKHN0YXRlXzI1Nyk7XG59O1xuZXhwb3J0IHtDbGFzc0V4cHJlc3Npb24gYXMgQ2xhc3NFeHByZXNzaW9ufTtcbmNsYXNzIENsYXNzRGVjbGFyYXRpb24gZXh0ZW5kcyBTdGF0ZW1lbnQge1xuICBjb25zdHJ1Y3RvcihhdHRyc18yNTgsIHR5cGVfMjU5KSB7XG4gICAgc3VwZXIoYXR0cnNfMjU4LCB0eXBlXzI1OSB8fCBcIkNsYXNzRGVjbGFyYXRpb25cIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzI1OCwgXCJuYW1lXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcIm5hbWVcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc18yNTgsIFwic3VwZXJcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwic3VwZXJcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc18yNTgsIFwiZWxlbWVudHNcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiZWxlbWVudHNcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzI2MCwgc3RhdGVfMjYxID0ge30pIHtcbiAgICBzdGF0ZV8yNjEubmFtZSA9IHRoaXMubmFtZSBpbnN0YW5jZW9mIEJpbmRpbmdJZGVudGlmaWVyID8gdGhpcy5uYW1lLnJlZHVjZShyZWR1Y2VyXzI2MCkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLm5hbWUpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfMjYxLnN1cGVyID0gdGhpcy5zdXBlciA9PSBudWxsID8gbnVsbCA6IHRoaXMuc3VwZXIgaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gdGhpcy5zdXBlci5yZWR1Y2UocmVkdWNlcl8yNjApIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5zdXBlcikpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICBzdGF0ZV8yNjEuZWxlbWVudHMgPSB0aGlzLmVsZW1lbnRzLm1hcChhXzI2MiA9PiBhXzI2MiBpbnN0YW5jZW9mIENsYXNzRWxlbWVudCA/IGFfMjYyLnJlZHVjZShyZWR1Y2VyXzI2MCkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeShhXzI2MikpO1xuICAgIH0uY2FsbCh0aGlzKSk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl8yNjAsIHN0YXRlXzI2MSk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe25hbWU6IHRoaXMubmFtZSwgc3VwZXI6IHRoaXMuc3VwZXIsIGVsZW1lbnRzOiB0aGlzLmVsZW1lbnRzfSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfMjYzKSB7XG4gICAgbGV0IHN0YXRlXzI2NCA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMjYzKTtcbiAgICByZXR1cm4gcmVkdWNlcl8yNjMucmVkdWNlQ2xhc3NEZWNsYXJhdGlvbih0aGlzLCBzdGF0ZV8yNjQpO1xuICB9XG4gIGV4dGVuZChhdHRyc18yNjUpIHtcbiAgICByZXR1cm4gbmV3IENsYXNzRGVjbGFyYXRpb24oT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzI2NSkpO1xuICB9XG59XG5TdGF0ZW1lbnQuQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VDbGFzc0RlY2xhcmF0aW9uID0gZnVuY3Rpb24gKHRlcm1fMjY2LCBzdGF0ZV8yNjcpIHtcbiAgcmV0dXJuIG5ldyBDbGFzc0RlY2xhcmF0aW9uKHN0YXRlXzI2Nyk7XG59O1xuZXhwb3J0IHtDbGFzc0RlY2xhcmF0aW9uIGFzIENsYXNzRGVjbGFyYXRpb259O1xuY2xhc3MgQ2xhc3NFbGVtZW50IGV4dGVuZHMgVGVybSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzI2OCwgdHlwZV8yNjkpIHtcbiAgICBzdXBlcihhdHRyc18yNjgsIHR5cGVfMjY5IHx8IFwiQ2xhc3NFbGVtZW50XCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc18yNjgsIFwiaXNTdGF0aWNcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiaXNTdGF0aWNcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc18yNjgsIFwibWV0aG9kXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcIm1ldGhvZFwiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfMjcwLCBzdGF0ZV8yNzEgPSB7fSkge1xuICAgIHN0YXRlXzI3MS5pc1N0YXRpYyA9IHRoaXMuaXNTdGF0aWM7XG4gICAgc3RhdGVfMjcxLm1ldGhvZCA9IHRoaXMubWV0aG9kIGluc3RhbmNlb2YgTWV0aG9kRGVmaW5pdGlvbiA/IHRoaXMubWV0aG9kLnJlZHVjZShyZWR1Y2VyXzI3MCkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLm1ldGhvZCkpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzI3MCwgc3RhdGVfMjcxKTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7aXNTdGF0aWM6IHRoaXMuaXNTdGF0aWMsIG1ldGhvZDogdGhpcy5tZXRob2R9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl8yNzIpIHtcbiAgICBsZXQgc3RhdGVfMjczID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl8yNzIpO1xuICAgIHJldHVybiByZWR1Y2VyXzI3Mi5yZWR1Y2VDbGFzc0VsZW1lbnQodGhpcywgc3RhdGVfMjczKTtcbiAgfVxuICBleHRlbmQoYXR0cnNfMjc0KSB7XG4gICAgcmV0dXJuIG5ldyBDbGFzc0VsZW1lbnQoT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzI3NCkpO1xuICB9XG59XG5UZXJtLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlQ2xhc3NFbGVtZW50ID0gZnVuY3Rpb24gKHRlcm1fMjc1LCBzdGF0ZV8yNzYpIHtcbiAgcmV0dXJuIG5ldyBDbGFzc0VsZW1lbnQoc3RhdGVfMjc2KTtcbn07XG5leHBvcnQge0NsYXNzRWxlbWVudCBhcyBDbGFzc0VsZW1lbnR9O1xuY2xhc3MgTW9kdWxlIGV4dGVuZHMgVGVybSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzI3NywgdHlwZV8yNzgpIHtcbiAgICBzdXBlcihhdHRyc18yNzcsIHR5cGVfMjc4IHx8IFwiTW9kdWxlXCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc18yNzcsIFwiZGlyZWN0aXZlc1wiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJkaXJlY3RpdmVzXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfMjc3LCBcIml0ZW1zXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcIml0ZW1zXCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl8yNzksIHN0YXRlXzI4MCA9IHt9KSB7XG4gICAgc3RhdGVfMjgwLmRpcmVjdGl2ZXMgPSB0aGlzLmRpcmVjdGl2ZXMubWFwKGFfMjgxID0+IGFfMjgxKTtcbiAgICBzdGF0ZV8yODAuaXRlbXMgPSB0aGlzLml0ZW1zLm1hcChhXzI4MiA9PiBhXzI4MiBpbnN0YW5jZW9mIFRlcm0gPyBhXzI4Mi5yZWR1Y2UocmVkdWNlcl8yNzkpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkoYV8yODIpKTtcbiAgICB9LmNhbGwodGhpcykpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMjc5LCBzdGF0ZV8yODApO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtkaXJlY3RpdmVzOiB0aGlzLmRpcmVjdGl2ZXMsIGl0ZW1zOiB0aGlzLml0ZW1zfSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfMjgzKSB7XG4gICAgbGV0IHN0YXRlXzI4NCA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMjgzKTtcbiAgICByZXR1cm4gcmVkdWNlcl8yODMucmVkdWNlTW9kdWxlKHRoaXMsIHN0YXRlXzI4NCk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzI4NSkge1xuICAgIHJldHVybiBuZXcgTW9kdWxlKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc18yODUpKTtcbiAgfVxufVxuVGVybS5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZU1vZHVsZSA9IGZ1bmN0aW9uICh0ZXJtXzI4Niwgc3RhdGVfMjg3KSB7XG4gIHJldHVybiBuZXcgTW9kdWxlKHN0YXRlXzI4Nyk7XG59O1xuZXhwb3J0IHtNb2R1bGUgYXMgTW9kdWxlfTtcbmNsYXNzIEltcG9ydERlY2xhcmF0aW9uIGV4dGVuZHMgVGVybSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzI4OCwgdHlwZV8yODkpIHtcbiAgICBzdXBlcihhdHRyc18yODgsIHR5cGVfMjg5IHx8IFwiSW1wb3J0RGVjbGFyYXRpb25cIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzI4OCwgXCJtb2R1bGVTcGVjaWZpZXJcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwibW9kdWxlU3BlY2lmaWVyXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfMjg4LCBcImZvclN5bnRheFwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJmb3JTeW50YXhcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzI5MCwgc3RhdGVfMjkxID0ge30pIHtcbiAgICBzdGF0ZV8yOTEubW9kdWxlU3BlY2lmaWVyID0gdGhpcy5tb2R1bGVTcGVjaWZpZXI7XG4gICAgc3RhdGVfMjkxLmZvclN5bnRheCA9IHRoaXMuZm9yU3ludGF4O1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMjkwLCBzdGF0ZV8yOTEpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHttb2R1bGVTcGVjaWZpZXI6IHRoaXMubW9kdWxlU3BlY2lmaWVyLCBmb3JTeW50YXg6IHRoaXMuZm9yU3ludGF4fSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfMjkyKSB7XG4gICAgbGV0IHN0YXRlXzI5MyA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMjkyKTtcbiAgICByZXR1cm4gcmVkdWNlcl8yOTIucmVkdWNlSW1wb3J0RGVjbGFyYXRpb24odGhpcywgc3RhdGVfMjkzKTtcbiAgfVxuICBleHRlbmQoYXR0cnNfMjk0KSB7XG4gICAgcmV0dXJuIG5ldyBJbXBvcnREZWNsYXJhdGlvbihPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfMjk0KSk7XG4gIH1cbn1cblRlcm0uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VJbXBvcnREZWNsYXJhdGlvbiA9IGZ1bmN0aW9uICh0ZXJtXzI5NSwgc3RhdGVfMjk2KSB7XG4gIHJldHVybiBuZXcgSW1wb3J0RGVjbGFyYXRpb24oc3RhdGVfMjk2KTtcbn07XG5leHBvcnQge0ltcG9ydERlY2xhcmF0aW9uIGFzIEltcG9ydERlY2xhcmF0aW9ufTtcbmNsYXNzIEV4cG9ydERlY2xhcmF0aW9uIGV4dGVuZHMgVGVybSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzI5NywgdHlwZV8yOTgpIHtcbiAgICBzdXBlcihhdHRyc18yOTcsIHR5cGVfMjk4IHx8IFwiRXhwb3J0RGVjbGFyYXRpb25cIik7XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfMjk5LCBzdGF0ZV8zMDAgPSB7fSkge1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMjk5LCBzdGF0ZV8zMDApO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl8zMDEpIHtcbiAgICBsZXQgc3RhdGVfMzAyID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl8zMDEpO1xuICAgIHJldHVybiByZWR1Y2VyXzMwMS5yZWR1Y2VFeHBvcnREZWNsYXJhdGlvbih0aGlzLCBzdGF0ZV8zMDIpO1xuICB9XG4gIGV4dGVuZChhdHRyc18zMDMpIHtcbiAgICByZXR1cm4gbmV3IEV4cG9ydERlY2xhcmF0aW9uKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc18zMDMpKTtcbiAgfVxufVxuVGVybS5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZUV4cG9ydERlY2xhcmF0aW9uID0gZnVuY3Rpb24gKHRlcm1fMzA0LCBzdGF0ZV8zMDUpIHtcbiAgcmV0dXJuIG5ldyBFeHBvcnREZWNsYXJhdGlvbihzdGF0ZV8zMDUpO1xufTtcbmV4cG9ydCB7RXhwb3J0RGVjbGFyYXRpb24gYXMgRXhwb3J0RGVjbGFyYXRpb259O1xuY2xhc3MgSW1wb3J0IGV4dGVuZHMgSW1wb3J0RGVjbGFyYXRpb24ge1xuICBjb25zdHJ1Y3RvcihhdHRyc18zMDYsIHR5cGVfMzA3KSB7XG4gICAgc3VwZXIoYXR0cnNfMzA2LCB0eXBlXzMwNyB8fCBcIkltcG9ydFwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfMzA2LCBcImRlZmF1bHRCaW5kaW5nXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImRlZmF1bHRCaW5kaW5nXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfMzA2LCBcIm5hbWVkSW1wb3J0c1wiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJuYW1lZEltcG9ydHNcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzMwOCwgc3RhdGVfMzA5ID0ge30pIHtcbiAgICBzdGF0ZV8zMDkuZGVmYXVsdEJpbmRpbmcgPSB0aGlzLmRlZmF1bHRCaW5kaW5nID09IG51bGwgPyBudWxsIDogdGhpcy5kZWZhdWx0QmluZGluZyBpbnN0YW5jZW9mIEJpbmRpbmdJZGVudGlmaWVyID8gdGhpcy5kZWZhdWx0QmluZGluZy5yZWR1Y2UocmVkdWNlcl8zMDgpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5kZWZhdWx0QmluZGluZykpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICBzdGF0ZV8zMDkubmFtZWRJbXBvcnRzID0gdGhpcy5uYW1lZEltcG9ydHMubWFwKGFfMzEwID0+IGFfMzEwIGluc3RhbmNlb2YgSW1wb3J0U3BlY2lmaWVyID8gYV8zMTAucmVkdWNlKHJlZHVjZXJfMzA4KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KGFfMzEwKSk7XG4gICAgfS5jYWxsKHRoaXMpKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzMwOCwgc3RhdGVfMzA5KTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7ZGVmYXVsdEJpbmRpbmc6IHRoaXMuZGVmYXVsdEJpbmRpbmcsIG5hbWVkSW1wb3J0czogdGhpcy5uYW1lZEltcG9ydHN9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl8zMTEpIHtcbiAgICBsZXQgc3RhdGVfMzEyID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl8zMTEpO1xuICAgIHJldHVybiByZWR1Y2VyXzMxMS5yZWR1Y2VJbXBvcnQodGhpcywgc3RhdGVfMzEyKTtcbiAgfVxuICBleHRlbmQoYXR0cnNfMzEzKSB7XG4gICAgcmV0dXJuIG5ldyBJbXBvcnQoT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzMxMykpO1xuICB9XG59XG5JbXBvcnREZWNsYXJhdGlvbi5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZUltcG9ydCA9IGZ1bmN0aW9uICh0ZXJtXzMxNCwgc3RhdGVfMzE1KSB7XG4gIHJldHVybiBuZXcgSW1wb3J0KHN0YXRlXzMxNSk7XG59O1xuZXhwb3J0IHtJbXBvcnQgYXMgSW1wb3J0fTtcbmNsYXNzIEltcG9ydE5hbWVzcGFjZSBleHRlbmRzIEltcG9ydERlY2xhcmF0aW9uIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfMzE2LCB0eXBlXzMxNykge1xuICAgIHN1cGVyKGF0dHJzXzMxNiwgdHlwZV8zMTcgfHwgXCJJbXBvcnROYW1lc3BhY2VcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzMxNiwgXCJkZWZhdWx0QmluZGluZ1wiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJkZWZhdWx0QmluZGluZ1wiKTtcbiAgICB9XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzMxNiwgXCJuYW1lc3BhY2VCaW5kaW5nXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcIm5hbWVzcGFjZUJpbmRpbmdcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzMxOCwgc3RhdGVfMzE5ID0ge30pIHtcbiAgICBzdGF0ZV8zMTkuZGVmYXVsdEJpbmRpbmcgPSB0aGlzLmRlZmF1bHRCaW5kaW5nID09IG51bGwgPyBudWxsIDogdGhpcy5kZWZhdWx0QmluZGluZyBpbnN0YW5jZW9mIEJpbmRpbmdJZGVudGlmaWVyID8gdGhpcy5kZWZhdWx0QmluZGluZy5yZWR1Y2UocmVkdWNlcl8zMTgpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5kZWZhdWx0QmluZGluZykpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICBzdGF0ZV8zMTkubmFtZXNwYWNlQmluZGluZyA9IHRoaXMubmFtZXNwYWNlQmluZGluZyBpbnN0YW5jZW9mIEJpbmRpbmdJZGVudGlmaWVyID8gdGhpcy5uYW1lc3BhY2VCaW5kaW5nLnJlZHVjZShyZWR1Y2VyXzMxOCkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLm5hbWVzcGFjZUJpbmRpbmcpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl8zMTgsIHN0YXRlXzMxOSk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe2RlZmF1bHRCaW5kaW5nOiB0aGlzLmRlZmF1bHRCaW5kaW5nLCBuYW1lc3BhY2VCaW5kaW5nOiB0aGlzLm5hbWVzcGFjZUJpbmRpbmd9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl8zMjApIHtcbiAgICBsZXQgc3RhdGVfMzIxID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl8zMjApO1xuICAgIHJldHVybiByZWR1Y2VyXzMyMC5yZWR1Y2VJbXBvcnROYW1lc3BhY2UodGhpcywgc3RhdGVfMzIxKTtcbiAgfVxuICBleHRlbmQoYXR0cnNfMzIyKSB7XG4gICAgcmV0dXJuIG5ldyBJbXBvcnROYW1lc3BhY2UoT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzMyMikpO1xuICB9XG59XG5JbXBvcnREZWNsYXJhdGlvbi5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZUltcG9ydE5hbWVzcGFjZSA9IGZ1bmN0aW9uICh0ZXJtXzMyMywgc3RhdGVfMzI0KSB7XG4gIHJldHVybiBuZXcgSW1wb3J0TmFtZXNwYWNlKHN0YXRlXzMyNCk7XG59O1xuZXhwb3J0IHtJbXBvcnROYW1lc3BhY2UgYXMgSW1wb3J0TmFtZXNwYWNlfTtcbmNsYXNzIEltcG9ydFNwZWNpZmllciBleHRlbmRzIFRlcm0ge1xuICBjb25zdHJ1Y3RvcihhdHRyc18zMjUsIHR5cGVfMzI2KSB7XG4gICAgc3VwZXIoYXR0cnNfMzI1LCB0eXBlXzMyNiB8fCBcIkltcG9ydFNwZWNpZmllclwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfMzI1LCBcIm5hbWVcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwibmFtZVwiKTtcbiAgICB9XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzMyNSwgXCJiaW5kaW5nXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImJpbmRpbmdcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzMyNywgc3RhdGVfMzI4ID0ge30pIHtcbiAgICBzdGF0ZV8zMjgubmFtZSA9IHRoaXMubmFtZSA9PSBudWxsID8gbnVsbCA6IHRoaXMubmFtZTtcbiAgICBzdGF0ZV8zMjguYmluZGluZyA9IHRoaXMuYmluZGluZyBpbnN0YW5jZW9mIEJpbmRpbmdJZGVudGlmaWVyID8gdGhpcy5iaW5kaW5nLnJlZHVjZShyZWR1Y2VyXzMyNykgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmJpbmRpbmcpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl8zMjcsIHN0YXRlXzMyOCk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe25hbWU6IHRoaXMubmFtZSwgYmluZGluZzogdGhpcy5iaW5kaW5nfSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfMzI5KSB7XG4gICAgbGV0IHN0YXRlXzMzMCA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMzI5KTtcbiAgICByZXR1cm4gcmVkdWNlcl8zMjkucmVkdWNlSW1wb3J0U3BlY2lmaWVyKHRoaXMsIHN0YXRlXzMzMCk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzMzMSkge1xuICAgIHJldHVybiBuZXcgSW1wb3J0U3BlY2lmaWVyKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc18zMzEpKTtcbiAgfVxufVxuVGVybS5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZUltcG9ydFNwZWNpZmllciA9IGZ1bmN0aW9uICh0ZXJtXzMzMiwgc3RhdGVfMzMzKSB7XG4gIHJldHVybiBuZXcgSW1wb3J0U3BlY2lmaWVyKHN0YXRlXzMzMyk7XG59O1xuZXhwb3J0IHtJbXBvcnRTcGVjaWZpZXIgYXMgSW1wb3J0U3BlY2lmaWVyfTtcbmNsYXNzIEV4cG9ydEFsbEZyb20gZXh0ZW5kcyBFeHBvcnREZWNsYXJhdGlvbiB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzMzNCwgdHlwZV8zMzUpIHtcbiAgICBzdXBlcihhdHRyc18zMzQsIHR5cGVfMzM1IHx8IFwiRXhwb3J0QWxsRnJvbVwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfMzM0LCBcIm1vZHVsZVNwZWNpZmllclwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJtb2R1bGVTcGVjaWZpZXJcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzMzNiwgc3RhdGVfMzM3ID0ge30pIHtcbiAgICBzdGF0ZV8zMzcubW9kdWxlU3BlY2lmaWVyID0gdGhpcy5tb2R1bGVTcGVjaWZpZXI7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl8zMzYsIHN0YXRlXzMzNyk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe21vZHVsZVNwZWNpZmllcjogdGhpcy5tb2R1bGVTcGVjaWZpZXJ9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl8zMzgpIHtcbiAgICBsZXQgc3RhdGVfMzM5ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl8zMzgpO1xuICAgIHJldHVybiByZWR1Y2VyXzMzOC5yZWR1Y2VFeHBvcnRBbGxGcm9tKHRoaXMsIHN0YXRlXzMzOSk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzM0MCkge1xuICAgIHJldHVybiBuZXcgRXhwb3J0QWxsRnJvbShPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfMzQwKSk7XG4gIH1cbn1cbkV4cG9ydERlY2xhcmF0aW9uLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlRXhwb3J0QWxsRnJvbSA9IGZ1bmN0aW9uICh0ZXJtXzM0MSwgc3RhdGVfMzQyKSB7XG4gIHJldHVybiBuZXcgRXhwb3J0QWxsRnJvbShzdGF0ZV8zNDIpO1xufTtcbmV4cG9ydCB7RXhwb3J0QWxsRnJvbSBhcyBFeHBvcnRBbGxGcm9tfTtcbmNsYXNzIEV4cG9ydEZyb20gZXh0ZW5kcyBFeHBvcnREZWNsYXJhdGlvbiB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzM0MywgdHlwZV8zNDQpIHtcbiAgICBzdXBlcihhdHRyc18zNDMsIHR5cGVfMzQ0IHx8IFwiRXhwb3J0RnJvbVwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfMzQzLCBcIm5hbWVkRXhwb3J0c1wiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJuYW1lZEV4cG9ydHNcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc18zNDMsIFwibW9kdWxlU3BlY2lmaWVyXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcIm1vZHVsZVNwZWNpZmllclwiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfMzQ1LCBzdGF0ZV8zNDYgPSB7fSkge1xuICAgIHN0YXRlXzM0Ni5uYW1lZEV4cG9ydHMgPSB0aGlzLm5hbWVkRXhwb3J0cy5tYXAoYV8zNDcgPT4gYV8zNDcgaW5zdGFuY2VvZiBFeHBvcnRTcGVjaWZpZXIgPyBhXzM0Ny5yZWR1Y2UocmVkdWNlcl8zNDUpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkoYV8zNDcpKTtcbiAgICB9LmNhbGwodGhpcykpO1xuICAgIHN0YXRlXzM0Ni5tb2R1bGVTcGVjaWZpZXIgPSB0aGlzLm1vZHVsZVNwZWNpZmllciA9PSBudWxsID8gbnVsbCA6IHRoaXMubW9kdWxlU3BlY2lmaWVyO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMzQ1LCBzdGF0ZV8zNDYpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtuYW1lZEV4cG9ydHM6IHRoaXMubmFtZWRFeHBvcnRzLCBtb2R1bGVTcGVjaWZpZXI6IHRoaXMubW9kdWxlU3BlY2lmaWVyfSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfMzQ4KSB7XG4gICAgbGV0IHN0YXRlXzM0OSA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMzQ4KTtcbiAgICByZXR1cm4gcmVkdWNlcl8zNDgucmVkdWNlRXhwb3J0RnJvbSh0aGlzLCBzdGF0ZV8zNDkpO1xuICB9XG4gIGV4dGVuZChhdHRyc18zNTApIHtcbiAgICByZXR1cm4gbmV3IEV4cG9ydEZyb20oT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzM1MCkpO1xuICB9XG59XG5FeHBvcnREZWNsYXJhdGlvbi5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZUV4cG9ydEZyb20gPSBmdW5jdGlvbiAodGVybV8zNTEsIHN0YXRlXzM1Mikge1xuICByZXR1cm4gbmV3IEV4cG9ydEZyb20oc3RhdGVfMzUyKTtcbn07XG5leHBvcnQge0V4cG9ydEZyb20gYXMgRXhwb3J0RnJvbX07XG5jbGFzcyBFeHBvcnQgZXh0ZW5kcyBFeHBvcnREZWNsYXJhdGlvbiB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzM1MywgdHlwZV8zNTQpIHtcbiAgICBzdXBlcihhdHRyc18zNTMsIHR5cGVfMzU0IHx8IFwiRXhwb3J0XCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc18zNTMsIFwiZGVjbGFyYXRpb25cIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiZGVjbGFyYXRpb25cIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzM1NSwgc3RhdGVfMzU2ID0ge30pIHtcbiAgICBzdGF0ZV8zNTYuZGVjbGFyYXRpb24gPSB0aGlzLmRlY2xhcmF0aW9uIGluc3RhbmNlb2YgRnVuY3Rpb25EZWNsYXJhdGlvbiA/IHRoaXMuZGVjbGFyYXRpb24ucmVkdWNlKHJlZHVjZXJfMzU1KSA6IHRoaXMuZGVjbGFyYXRpb24gaW5zdGFuY2VvZiBDbGFzc0RlY2xhcmF0aW9uID8gdGhpcy5kZWNsYXJhdGlvbi5yZWR1Y2UocmVkdWNlcl8zNTUpIDogdGhpcy5kZWNsYXJhdGlvbiBpbnN0YW5jZW9mIFZhcmlhYmxlRGVjbGFyYXRpb24gPyB0aGlzLmRlY2xhcmF0aW9uLnJlZHVjZShyZWR1Y2VyXzM1NSkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmRlY2xhcmF0aW9uKSk7XG4gICAgfS5jYWxsKHRoaXMpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMzU1LCBzdGF0ZV8zNTYpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtkZWNsYXJhdGlvbjogdGhpcy5kZWNsYXJhdGlvbn0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzM1Nykge1xuICAgIGxldCBzdGF0ZV8zNTggPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzM1Nyk7XG4gICAgcmV0dXJuIHJlZHVjZXJfMzU3LnJlZHVjZUV4cG9ydCh0aGlzLCBzdGF0ZV8zNTgpO1xuICB9XG4gIGV4dGVuZChhdHRyc18zNTkpIHtcbiAgICByZXR1cm4gbmV3IEV4cG9ydChPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfMzU5KSk7XG4gIH1cbn1cbkV4cG9ydERlY2xhcmF0aW9uLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlRXhwb3J0ID0gZnVuY3Rpb24gKHRlcm1fMzYwLCBzdGF0ZV8zNjEpIHtcbiAgcmV0dXJuIG5ldyBFeHBvcnQoc3RhdGVfMzYxKTtcbn07XG5leHBvcnQge0V4cG9ydCBhcyBFeHBvcnR9O1xuY2xhc3MgRXhwb3J0RGVmYXVsdCBleHRlbmRzIEV4cG9ydERlY2xhcmF0aW9uIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfMzYyLCB0eXBlXzM2Mykge1xuICAgIHN1cGVyKGF0dHJzXzM2MiwgdHlwZV8zNjMgfHwgXCJFeHBvcnREZWZhdWx0XCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc18zNjIsIFwiYm9keVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJib2R5XCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl8zNjQsIHN0YXRlXzM2NSA9IHt9KSB7XG4gICAgc3RhdGVfMzY1LmJvZHkgPSB0aGlzLmJvZHkgaW5zdGFuY2VvZiBGdW5jdGlvbkRlY2xhcmF0aW9uID8gdGhpcy5ib2R5LnJlZHVjZShyZWR1Y2VyXzM2NCkgOiB0aGlzLmJvZHkgaW5zdGFuY2VvZiBDbGFzc0RlY2xhcmF0aW9uID8gdGhpcy5ib2R5LnJlZHVjZShyZWR1Y2VyXzM2NCkgOiB0aGlzLmJvZHkgaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gdGhpcy5ib2R5LnJlZHVjZShyZWR1Y2VyXzM2NCkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmJvZHkpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl8zNjQsIHN0YXRlXzM2NSk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe2JvZHk6IHRoaXMuYm9keX0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzM2Nikge1xuICAgIGxldCBzdGF0ZV8zNjcgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzM2Nik7XG4gICAgcmV0dXJuIHJlZHVjZXJfMzY2LnJlZHVjZUV4cG9ydERlZmF1bHQodGhpcywgc3RhdGVfMzY3KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfMzY4KSB7XG4gICAgcmV0dXJuIG5ldyBFeHBvcnREZWZhdWx0KE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc18zNjgpKTtcbiAgfVxufVxuRXhwb3J0RGVjbGFyYXRpb24uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VFeHBvcnREZWZhdWx0ID0gZnVuY3Rpb24gKHRlcm1fMzY5LCBzdGF0ZV8zNzApIHtcbiAgcmV0dXJuIG5ldyBFeHBvcnREZWZhdWx0KHN0YXRlXzM3MCk7XG59O1xuZXhwb3J0IHtFeHBvcnREZWZhdWx0IGFzIEV4cG9ydERlZmF1bHR9O1xuY2xhc3MgRXhwb3J0U3BlY2lmaWVyIGV4dGVuZHMgVGVybSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzM3MSwgdHlwZV8zNzIpIHtcbiAgICBzdXBlcihhdHRyc18zNzEsIHR5cGVfMzcyIHx8IFwiRXhwb3J0U3BlY2lmaWVyXCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc18zNzEsIFwibmFtZVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJuYW1lXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfMzcxLCBcImV4cG9ydGVkTmFtZVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJleHBvcnRlZE5hbWVcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzM3Mywgc3RhdGVfMzc0ID0ge30pIHtcbiAgICBzdGF0ZV8zNzQubmFtZSA9IHRoaXMubmFtZSA9PSBudWxsID8gbnVsbCA6IHRoaXMubmFtZTtcbiAgICBzdGF0ZV8zNzQuZXhwb3J0ZWROYW1lID0gdGhpcy5leHBvcnRlZE5hbWU7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl8zNzMsIHN0YXRlXzM3NCk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe25hbWU6IHRoaXMubmFtZSwgZXhwb3J0ZWROYW1lOiB0aGlzLmV4cG9ydGVkTmFtZX0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzM3NSkge1xuICAgIGxldCBzdGF0ZV8zNzYgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzM3NSk7XG4gICAgcmV0dXJuIHJlZHVjZXJfMzc1LnJlZHVjZUV4cG9ydFNwZWNpZmllcih0aGlzLCBzdGF0ZV8zNzYpO1xuICB9XG4gIGV4dGVuZChhdHRyc18zNzcpIHtcbiAgICByZXR1cm4gbmV3IEV4cG9ydFNwZWNpZmllcihPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfMzc3KSk7XG4gIH1cbn1cblRlcm0uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VFeHBvcnRTcGVjaWZpZXIgPSBmdW5jdGlvbiAodGVybV8zNzgsIHN0YXRlXzM3OSkge1xuICByZXR1cm4gbmV3IEV4cG9ydFNwZWNpZmllcihzdGF0ZV8zNzkpO1xufTtcbmV4cG9ydCB7RXhwb3J0U3BlY2lmaWVyIGFzIEV4cG9ydFNwZWNpZmllcn07XG5jbGFzcyBNZXRob2QgZXh0ZW5kcyBNZXRob2REZWZpbml0aW9uIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfMzgwLCB0eXBlXzM4MSkge1xuICAgIHN1cGVyKGF0dHJzXzM4MCwgdHlwZV8zODEgfHwgXCJNZXRob2RcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzM4MCwgXCJpc0dlbmVyYXRvclwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJpc0dlbmVyYXRvclwiKTtcbiAgICB9XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzM4MCwgXCJwYXJhbXNcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwicGFyYW1zXCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl8zODIsIHN0YXRlXzM4MyA9IHt9KSB7XG4gICAgc3RhdGVfMzgzLmlzR2VuZXJhdG9yID0gdGhpcy5pc0dlbmVyYXRvcjtcbiAgICBzdGF0ZV8zODMucGFyYW1zID0gdGhpcy5wYXJhbXMgaW5zdGFuY2VvZiBGb3JtYWxQYXJhbWV0ZXJzID8gdGhpcy5wYXJhbXMucmVkdWNlKHJlZHVjZXJfMzgyKSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMucGFyYW1zKSk7XG4gICAgfS5jYWxsKHRoaXMpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMzgyLCBzdGF0ZV8zODMpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtpc0dlbmVyYXRvcjogdGhpcy5pc0dlbmVyYXRvciwgcGFyYW1zOiB0aGlzLnBhcmFtc30sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzM4NCkge1xuICAgIGxldCBzdGF0ZV8zODUgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzM4NCk7XG4gICAgcmV0dXJuIHJlZHVjZXJfMzg0LnJlZHVjZU1ldGhvZCh0aGlzLCBzdGF0ZV8zODUpO1xuICB9XG4gIGV4dGVuZChhdHRyc18zODYpIHtcbiAgICByZXR1cm4gbmV3IE1ldGhvZChPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfMzg2KSk7XG4gIH1cbn1cbk1ldGhvZERlZmluaXRpb24uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VNZXRob2QgPSBmdW5jdGlvbiAodGVybV8zODcsIHN0YXRlXzM4OCkge1xuICByZXR1cm4gbmV3IE1ldGhvZChzdGF0ZV8zODgpO1xufTtcbmV4cG9ydCB7TWV0aG9kIGFzIE1ldGhvZH07XG5jbGFzcyBHZXR0ZXIgZXh0ZW5kcyBNZXRob2REZWZpbml0aW9uIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfMzg5LCB0eXBlXzM5MCkge1xuICAgIHN1cGVyKGF0dHJzXzM4OSwgdHlwZV8zOTAgfHwgXCJHZXR0ZXJcIik7XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfMzkxLCBzdGF0ZV8zOTIgPSB7fSkge1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMzkxLCBzdGF0ZV8zOTIpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl8zOTMpIHtcbiAgICBsZXQgc3RhdGVfMzk0ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl8zOTMpO1xuICAgIHJldHVybiByZWR1Y2VyXzM5My5yZWR1Y2VHZXR0ZXIodGhpcywgc3RhdGVfMzk0KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfMzk1KSB7XG4gICAgcmV0dXJuIG5ldyBHZXR0ZXIoT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzM5NSkpO1xuICB9XG59XG5NZXRob2REZWZpbml0aW9uLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlR2V0dGVyID0gZnVuY3Rpb24gKHRlcm1fMzk2LCBzdGF0ZV8zOTcpIHtcbiAgcmV0dXJuIG5ldyBHZXR0ZXIoc3RhdGVfMzk3KTtcbn07XG5leHBvcnQge0dldHRlciBhcyBHZXR0ZXJ9O1xuY2xhc3MgU2V0dGVyIGV4dGVuZHMgTWV0aG9kRGVmaW5pdGlvbiB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzM5OCwgdHlwZV8zOTkpIHtcbiAgICBzdXBlcihhdHRyc18zOTgsIHR5cGVfMzk5IHx8IFwiU2V0dGVyXCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc18zOTgsIFwicGFyYW1cIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwicGFyYW1cIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzQwMCwgc3RhdGVfNDAxID0ge30pIHtcbiAgICBzdGF0ZV80MDEucGFyYW0gPSB0aGlzLnBhcmFtIGluc3RhbmNlb2YgT2JqZWN0QmluZGluZyA/IHRoaXMucGFyYW0ucmVkdWNlKHJlZHVjZXJfNDAwKSA6IHRoaXMucGFyYW0gaW5zdGFuY2VvZiBBcnJheUJpbmRpbmcgPyB0aGlzLnBhcmFtLnJlZHVjZShyZWR1Y2VyXzQwMCkgOiB0aGlzLnBhcmFtIGluc3RhbmNlb2YgQmluZGluZ0lkZW50aWZpZXIgPyB0aGlzLnBhcmFtLnJlZHVjZShyZWR1Y2VyXzQwMCkgOiB0aGlzLnBhcmFtIGluc3RhbmNlb2YgTWVtYmVyRXhwcmVzc2lvbiA/IHRoaXMucGFyYW0ucmVkdWNlKHJlZHVjZXJfNDAwKSA6IHRoaXMucGFyYW0gaW5zdGFuY2VvZiBCaW5kaW5nV2l0aERlZmF1bHQgPyB0aGlzLnBhcmFtLnJlZHVjZShyZWR1Y2VyXzQwMCkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLnBhcmFtKSk7XG4gICAgfS5jYWxsKHRoaXMpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNDAwLCBzdGF0ZV80MDEpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtwYXJhbTogdGhpcy5wYXJhbX0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzQwMikge1xuICAgIGxldCBzdGF0ZV80MDMgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzQwMik7XG4gICAgcmV0dXJuIHJlZHVjZXJfNDAyLnJlZHVjZVNldHRlcih0aGlzLCBzdGF0ZV80MDMpO1xuICB9XG4gIGV4dGVuZChhdHRyc180MDQpIHtcbiAgICByZXR1cm4gbmV3IFNldHRlcihPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfNDA0KSk7XG4gIH1cbn1cbk1ldGhvZERlZmluaXRpb24uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VTZXR0ZXIgPSBmdW5jdGlvbiAodGVybV80MDUsIHN0YXRlXzQwNikge1xuICByZXR1cm4gbmV3IFNldHRlcihzdGF0ZV80MDYpO1xufTtcbmV4cG9ydCB7U2V0dGVyIGFzIFNldHRlcn07XG5jbGFzcyBEYXRhUHJvcGVydHkgZXh0ZW5kcyBOYW1lZE9iamVjdFByb3BlcnR5IHtcbiAgY29uc3RydWN0b3IoYXR0cnNfNDA3LCB0eXBlXzQwOCkge1xuICAgIHN1cGVyKGF0dHJzXzQwNywgdHlwZV80MDggfHwgXCJEYXRhUHJvcGVydHlcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzQwNywgXCJleHByZXNzaW9uXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImV4cHJlc3Npb25cIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzQwOSwgc3RhdGVfNDEwID0ge30pIHtcbiAgICBzdGF0ZV80MTAuZXhwcmVzc2lvbiA9IHRoaXMuZXhwcmVzc2lvbiBpbnN0YW5jZW9mIEV4cHJlc3Npb24gPyB0aGlzLmV4cHJlc3Npb24ucmVkdWNlKHJlZHVjZXJfNDA5KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMuZXhwcmVzc2lvbikpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzQwOSwgc3RhdGVfNDEwKTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7ZXhwcmVzc2lvbjogdGhpcy5leHByZXNzaW9ufSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfNDExKSB7XG4gICAgbGV0IHN0YXRlXzQxMiA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNDExKTtcbiAgICByZXR1cm4gcmVkdWNlcl80MTEucmVkdWNlRGF0YVByb3BlcnR5KHRoaXMsIHN0YXRlXzQxMik7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzQxMykge1xuICAgIHJldHVybiBuZXcgRGF0YVByb3BlcnR5KE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc180MTMpKTtcbiAgfVxufVxuTmFtZWRPYmplY3RQcm9wZXJ0eS5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZURhdGFQcm9wZXJ0eSA9IGZ1bmN0aW9uICh0ZXJtXzQxNCwgc3RhdGVfNDE1KSB7XG4gIHJldHVybiBuZXcgRGF0YVByb3BlcnR5KHN0YXRlXzQxNSk7XG59O1xuZXhwb3J0IHtEYXRhUHJvcGVydHkgYXMgRGF0YVByb3BlcnR5fTtcbmNsYXNzIFNob3J0aGFuZFByb3BlcnR5IGV4dGVuZHMgT2JqZWN0UHJvcGVydHkge1xuICBjb25zdHJ1Y3RvcihhdHRyc180MTYsIHR5cGVfNDE3KSB7XG4gICAgc3VwZXIoYXR0cnNfNDE2LCB0eXBlXzQxNyB8fCBcIlNob3J0aGFuZFByb3BlcnR5XCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc180MTYsIFwibmFtZVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJuYW1lXCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl80MTgsIHN0YXRlXzQxOSA9IHt9KSB7XG4gICAgc3RhdGVfNDE5Lm5hbWUgPSB0aGlzLm5hbWU7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl80MTgsIHN0YXRlXzQxOSk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe25hbWU6IHRoaXMubmFtZX0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzQyMCkge1xuICAgIGxldCBzdGF0ZV80MjEgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzQyMCk7XG4gICAgcmV0dXJuIHJlZHVjZXJfNDIwLnJlZHVjZVNob3J0aGFuZFByb3BlcnR5KHRoaXMsIHN0YXRlXzQyMSk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzQyMikge1xuICAgIHJldHVybiBuZXcgU2hvcnRoYW5kUHJvcGVydHkoT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzQyMikpO1xuICB9XG59XG5PYmplY3RQcm9wZXJ0eS5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZVNob3J0aGFuZFByb3BlcnR5ID0gZnVuY3Rpb24gKHRlcm1fNDIzLCBzdGF0ZV80MjQpIHtcbiAgcmV0dXJuIG5ldyBTaG9ydGhhbmRQcm9wZXJ0eShzdGF0ZV80MjQpO1xufTtcbmV4cG9ydCB7U2hvcnRoYW5kUHJvcGVydHkgYXMgU2hvcnRoYW5kUHJvcGVydHl9O1xuY2xhc3MgU3RhdGljUHJvcGVydHlOYW1lIGV4dGVuZHMgUHJvcGVydHlOYW1lIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfNDI1LCB0eXBlXzQyNikge1xuICAgIHN1cGVyKGF0dHJzXzQyNSwgdHlwZV80MjYgfHwgXCJTdGF0aWNQcm9wZXJ0eU5hbWVcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzQyNSwgXCJ2YWx1ZVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJ2YWx1ZVwiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfNDI3LCBzdGF0ZV80MjggPSB7fSkge1xuICAgIHN0YXRlXzQyOC52YWx1ZSA9IHRoaXMudmFsdWU7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl80MjcsIHN0YXRlXzQyOCk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe3ZhbHVlOiB0aGlzLnZhbHVlfSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfNDI5KSB7XG4gICAgbGV0IHN0YXRlXzQzMCA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNDI5KTtcbiAgICByZXR1cm4gcmVkdWNlcl80MjkucmVkdWNlU3RhdGljUHJvcGVydHlOYW1lKHRoaXMsIHN0YXRlXzQzMCk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzQzMSkge1xuICAgIHJldHVybiBuZXcgU3RhdGljUHJvcGVydHlOYW1lKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc180MzEpKTtcbiAgfVxufVxuUHJvcGVydHlOYW1lLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlU3RhdGljUHJvcGVydHlOYW1lID0gZnVuY3Rpb24gKHRlcm1fNDMyLCBzdGF0ZV80MzMpIHtcbiAgcmV0dXJuIG5ldyBTdGF0aWNQcm9wZXJ0eU5hbWUoc3RhdGVfNDMzKTtcbn07XG5leHBvcnQge1N0YXRpY1Byb3BlcnR5TmFtZSBhcyBTdGF0aWNQcm9wZXJ0eU5hbWV9O1xuY2xhc3MgQ29tcHV0ZWRQcm9wZXJ0eU5hbWUgZXh0ZW5kcyBQcm9wZXJ0eU5hbWUge1xuICBjb25zdHJ1Y3RvcihhdHRyc180MzQsIHR5cGVfNDM1KSB7XG4gICAgc3VwZXIoYXR0cnNfNDM0LCB0eXBlXzQzNSB8fCBcIkNvbXB1dGVkUHJvcGVydHlOYW1lXCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc180MzQsIFwiZXhwcmVzc2lvblwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJleHByZXNzaW9uXCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl80MzYsIHN0YXRlXzQzNyA9IHt9KSB7XG4gICAgc3RhdGVfNDM3LmV4cHJlc3Npb24gPSB0aGlzLmV4cHJlc3Npb24gaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gdGhpcy5leHByZXNzaW9uLnJlZHVjZShyZWR1Y2VyXzQzNikgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmV4cHJlc3Npb24pKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl80MzYsIHN0YXRlXzQzNyk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe2V4cHJlc3Npb246IHRoaXMuZXhwcmVzc2lvbn0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzQzOCkge1xuICAgIGxldCBzdGF0ZV80MzkgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzQzOCk7XG4gICAgcmV0dXJuIHJlZHVjZXJfNDM4LnJlZHVjZUNvbXB1dGVkUHJvcGVydHlOYW1lKHRoaXMsIHN0YXRlXzQzOSk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzQ0MCkge1xuICAgIHJldHVybiBuZXcgQ29tcHV0ZWRQcm9wZXJ0eU5hbWUoT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzQ0MCkpO1xuICB9XG59XG5Qcm9wZXJ0eU5hbWUuQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VDb21wdXRlZFByb3BlcnR5TmFtZSA9IGZ1bmN0aW9uICh0ZXJtXzQ0MSwgc3RhdGVfNDQyKSB7XG4gIHJldHVybiBuZXcgQ29tcHV0ZWRQcm9wZXJ0eU5hbWUoc3RhdGVfNDQyKTtcbn07XG5leHBvcnQge0NvbXB1dGVkUHJvcGVydHlOYW1lIGFzIENvbXB1dGVkUHJvcGVydHlOYW1lfTtcbmNsYXNzIExpdGVyYWxCb29sZWFuRXhwcmVzc2lvbiBleHRlbmRzIEV4cHJlc3Npb24ge1xuICBjb25zdHJ1Y3RvcihhdHRyc180NDMsIHR5cGVfNDQ0KSB7XG4gICAgc3VwZXIoYXR0cnNfNDQzLCB0eXBlXzQ0NCB8fCBcIkxpdGVyYWxCb29sZWFuRXhwcmVzc2lvblwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNDQzLCBcInZhbHVlXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcInZhbHVlXCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl80NDUsIHN0YXRlXzQ0NiA9IHt9KSB7XG4gICAgc3RhdGVfNDQ2LnZhbHVlID0gdGhpcy52YWx1ZTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzQ0NSwgc3RhdGVfNDQ2KTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7dmFsdWU6IHRoaXMudmFsdWV9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl80NDcpIHtcbiAgICBsZXQgc3RhdGVfNDQ4ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl80NDcpO1xuICAgIHJldHVybiByZWR1Y2VyXzQ0Ny5yZWR1Y2VMaXRlcmFsQm9vbGVhbkV4cHJlc3Npb24odGhpcywgc3RhdGVfNDQ4KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfNDQ5KSB7XG4gICAgcmV0dXJuIG5ldyBMaXRlcmFsQm9vbGVhbkV4cHJlc3Npb24oT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzQ0OSkpO1xuICB9XG59XG5FeHByZXNzaW9uLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlTGl0ZXJhbEJvb2xlYW5FeHByZXNzaW9uID0gZnVuY3Rpb24gKHRlcm1fNDUwLCBzdGF0ZV80NTEpIHtcbiAgcmV0dXJuIG5ldyBMaXRlcmFsQm9vbGVhbkV4cHJlc3Npb24oc3RhdGVfNDUxKTtcbn07XG5leHBvcnQge0xpdGVyYWxCb29sZWFuRXhwcmVzc2lvbiBhcyBMaXRlcmFsQm9vbGVhbkV4cHJlc3Npb259O1xuY2xhc3MgTGl0ZXJhbEluZmluaXR5RXhwcmVzc2lvbiBleHRlbmRzIEV4cHJlc3Npb24ge1xuICBjb25zdHJ1Y3RvcihhdHRyc180NTIsIHR5cGVfNDUzKSB7XG4gICAgc3VwZXIoYXR0cnNfNDUyLCB0eXBlXzQ1MyB8fCBcIkxpdGVyYWxJbmZpbml0eUV4cHJlc3Npb25cIik7XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfNDU0LCBzdGF0ZV80NTUgPSB7fSkge1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNDU0LCBzdGF0ZV80NTUpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl80NTYpIHtcbiAgICBsZXQgc3RhdGVfNDU3ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl80NTYpO1xuICAgIHJldHVybiByZWR1Y2VyXzQ1Ni5yZWR1Y2VMaXRlcmFsSW5maW5pdHlFeHByZXNzaW9uKHRoaXMsIHN0YXRlXzQ1Nyk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzQ1OCkge1xuICAgIHJldHVybiBuZXcgTGl0ZXJhbEluZmluaXR5RXhwcmVzc2lvbihPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfNDU4KSk7XG4gIH1cbn1cbkV4cHJlc3Npb24uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VMaXRlcmFsSW5maW5pdHlFeHByZXNzaW9uID0gZnVuY3Rpb24gKHRlcm1fNDU5LCBzdGF0ZV80NjApIHtcbiAgcmV0dXJuIG5ldyBMaXRlcmFsSW5maW5pdHlFeHByZXNzaW9uKHN0YXRlXzQ2MCk7XG59O1xuZXhwb3J0IHtMaXRlcmFsSW5maW5pdHlFeHByZXNzaW9uIGFzIExpdGVyYWxJbmZpbml0eUV4cHJlc3Npb259O1xuY2xhc3MgTGl0ZXJhbE51bGxFeHByZXNzaW9uIGV4dGVuZHMgRXhwcmVzc2lvbiB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzQ2MSwgdHlwZV80NjIpIHtcbiAgICBzdXBlcihhdHRyc180NjEsIHR5cGVfNDYyIHx8IFwiTGl0ZXJhbE51bGxFeHByZXNzaW9uXCIpO1xuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzQ2Mywgc3RhdGVfNDY0ID0ge30pIHtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzQ2Mywgc3RhdGVfNDY0KTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfNDY1KSB7XG4gICAgbGV0IHN0YXRlXzQ2NiA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNDY1KTtcbiAgICByZXR1cm4gcmVkdWNlcl80NjUucmVkdWNlTGl0ZXJhbE51bGxFeHByZXNzaW9uKHRoaXMsIHN0YXRlXzQ2Nik7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzQ2Nykge1xuICAgIHJldHVybiBuZXcgTGl0ZXJhbE51bGxFeHByZXNzaW9uKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc180NjcpKTtcbiAgfVxufVxuRXhwcmVzc2lvbi5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZUxpdGVyYWxOdWxsRXhwcmVzc2lvbiA9IGZ1bmN0aW9uICh0ZXJtXzQ2OCwgc3RhdGVfNDY5KSB7XG4gIHJldHVybiBuZXcgTGl0ZXJhbE51bGxFeHByZXNzaW9uKHN0YXRlXzQ2OSk7XG59O1xuZXhwb3J0IHtMaXRlcmFsTnVsbEV4cHJlc3Npb24gYXMgTGl0ZXJhbE51bGxFeHByZXNzaW9ufTtcbmNsYXNzIExpdGVyYWxOdW1lcmljRXhwcmVzc2lvbiBleHRlbmRzIEV4cHJlc3Npb24ge1xuICBjb25zdHJ1Y3RvcihhdHRyc180NzAsIHR5cGVfNDcxKSB7XG4gICAgc3VwZXIoYXR0cnNfNDcwLCB0eXBlXzQ3MSB8fCBcIkxpdGVyYWxOdW1lcmljRXhwcmVzc2lvblwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNDcwLCBcInZhbHVlXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcInZhbHVlXCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl80NzIsIHN0YXRlXzQ3MyA9IHt9KSB7XG4gICAgc3RhdGVfNDczLnZhbHVlID0gdGhpcy52YWx1ZTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzQ3Miwgc3RhdGVfNDczKTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7dmFsdWU6IHRoaXMudmFsdWV9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl80NzQpIHtcbiAgICBsZXQgc3RhdGVfNDc1ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl80NzQpO1xuICAgIHJldHVybiByZWR1Y2VyXzQ3NC5yZWR1Y2VMaXRlcmFsTnVtZXJpY0V4cHJlc3Npb24odGhpcywgc3RhdGVfNDc1KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfNDc2KSB7XG4gICAgcmV0dXJuIG5ldyBMaXRlcmFsTnVtZXJpY0V4cHJlc3Npb24oT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzQ3NikpO1xuICB9XG59XG5FeHByZXNzaW9uLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlTGl0ZXJhbE51bWVyaWNFeHByZXNzaW9uID0gZnVuY3Rpb24gKHRlcm1fNDc3LCBzdGF0ZV80NzgpIHtcbiAgcmV0dXJuIG5ldyBMaXRlcmFsTnVtZXJpY0V4cHJlc3Npb24oc3RhdGVfNDc4KTtcbn07XG5leHBvcnQge0xpdGVyYWxOdW1lcmljRXhwcmVzc2lvbiBhcyBMaXRlcmFsTnVtZXJpY0V4cHJlc3Npb259O1xuY2xhc3MgTGl0ZXJhbFJlZ0V4cEV4cHJlc3Npb24gZXh0ZW5kcyBFeHByZXNzaW9uIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfNDc5LCB0eXBlXzQ4MCkge1xuICAgIHN1cGVyKGF0dHJzXzQ3OSwgdHlwZV80ODAgfHwgXCJMaXRlcmFsUmVnRXhwRXhwcmVzc2lvblwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNDc5LCBcInBhdHRlcm5cIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwicGF0dGVyblwiKTtcbiAgICB9XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzQ3OSwgXCJmbGFnc1wiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJmbGFnc1wiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfNDgxLCBzdGF0ZV80ODIgPSB7fSkge1xuICAgIHN0YXRlXzQ4Mi5wYXR0ZXJuID0gdGhpcy5wYXR0ZXJuO1xuICAgIHN0YXRlXzQ4Mi5mbGFncyA9IHRoaXMuZmxhZ3M7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl80ODEsIHN0YXRlXzQ4Mik7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe3BhdHRlcm46IHRoaXMucGF0dGVybiwgZmxhZ3M6IHRoaXMuZmxhZ3N9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl80ODMpIHtcbiAgICBsZXQgc3RhdGVfNDg0ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl80ODMpO1xuICAgIHJldHVybiByZWR1Y2VyXzQ4My5yZWR1Y2VMaXRlcmFsUmVnRXhwRXhwcmVzc2lvbih0aGlzLCBzdGF0ZV80ODQpO1xuICB9XG4gIGV4dGVuZChhdHRyc180ODUpIHtcbiAgICByZXR1cm4gbmV3IExpdGVyYWxSZWdFeHBFeHByZXNzaW9uKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc180ODUpKTtcbiAgfVxufVxuRXhwcmVzc2lvbi5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZUxpdGVyYWxSZWdFeHBFeHByZXNzaW9uID0gZnVuY3Rpb24gKHRlcm1fNDg2LCBzdGF0ZV80ODcpIHtcbiAgcmV0dXJuIG5ldyBMaXRlcmFsUmVnRXhwRXhwcmVzc2lvbihzdGF0ZV80ODcpO1xufTtcbmV4cG9ydCB7TGl0ZXJhbFJlZ0V4cEV4cHJlc3Npb24gYXMgTGl0ZXJhbFJlZ0V4cEV4cHJlc3Npb259O1xuY2xhc3MgTGl0ZXJhbFN0cmluZ0V4cHJlc3Npb24gZXh0ZW5kcyBFeHByZXNzaW9uIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfNDg4LCB0eXBlXzQ4OSkge1xuICAgIHN1cGVyKGF0dHJzXzQ4OCwgdHlwZV80ODkgfHwgXCJMaXRlcmFsU3RyaW5nRXhwcmVzc2lvblwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNDg4LCBcInZhbHVlXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcInZhbHVlXCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl80OTAsIHN0YXRlXzQ5MSA9IHt9KSB7XG4gICAgc3RhdGVfNDkxLnZhbHVlID0gdGhpcy52YWx1ZTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzQ5MCwgc3RhdGVfNDkxKTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7dmFsdWU6IHRoaXMudmFsdWV9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl80OTIpIHtcbiAgICBsZXQgc3RhdGVfNDkzID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl80OTIpO1xuICAgIHJldHVybiByZWR1Y2VyXzQ5Mi5yZWR1Y2VMaXRlcmFsU3RyaW5nRXhwcmVzc2lvbih0aGlzLCBzdGF0ZV80OTMpO1xuICB9XG4gIGV4dGVuZChhdHRyc180OTQpIHtcbiAgICByZXR1cm4gbmV3IExpdGVyYWxTdHJpbmdFeHByZXNzaW9uKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc180OTQpKTtcbiAgfVxufVxuRXhwcmVzc2lvbi5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZUxpdGVyYWxTdHJpbmdFeHByZXNzaW9uID0gZnVuY3Rpb24gKHRlcm1fNDk1LCBzdGF0ZV80OTYpIHtcbiAgcmV0dXJuIG5ldyBMaXRlcmFsU3RyaW5nRXhwcmVzc2lvbihzdGF0ZV80OTYpO1xufTtcbmV4cG9ydCB7TGl0ZXJhbFN0cmluZ0V4cHJlc3Npb24gYXMgTGl0ZXJhbFN0cmluZ0V4cHJlc3Npb259O1xuY2xhc3MgQXJyYXlFeHByZXNzaW9uIGV4dGVuZHMgRXhwcmVzc2lvbiB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzQ5NywgdHlwZV80OTgpIHtcbiAgICBzdXBlcihhdHRyc180OTcsIHR5cGVfNDk4IHx8IFwiQXJyYXlFeHByZXNzaW9uXCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc180OTcsIFwiZWxlbWVudHNcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiZWxlbWVudHNcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzQ5OSwgc3RhdGVfNTAwID0ge30pIHtcbiAgICBzdGF0ZV81MDAuZWxlbWVudHMgPSB0aGlzLmVsZW1lbnRzLm1hcChhXzUwMSA9PiBhXzUwMSBpbnN0YW5jZW9mIFNwcmVhZEVsZW1lbnQgPyBhXzUwMS5yZWR1Y2UocmVkdWNlcl80OTkpIDogYV81MDEgaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gYV81MDEucmVkdWNlKHJlZHVjZXJfNDk5KSA6IGFfNTAxID09IG51bGwgPyBudWxsIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkoYV81MDEpKTtcbiAgICB9LmNhbGwodGhpcykpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNDk5LCBzdGF0ZV81MDApO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtlbGVtZW50czogdGhpcy5lbGVtZW50c30sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzUwMikge1xuICAgIGxldCBzdGF0ZV81MDMgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzUwMik7XG4gICAgcmV0dXJuIHJlZHVjZXJfNTAyLnJlZHVjZUFycmF5RXhwcmVzc2lvbih0aGlzLCBzdGF0ZV81MDMpO1xuICB9XG4gIGV4dGVuZChhdHRyc181MDQpIHtcbiAgICByZXR1cm4gbmV3IEFycmF5RXhwcmVzc2lvbihPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfNTA0KSk7XG4gIH1cbn1cbkV4cHJlc3Npb24uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VBcnJheUV4cHJlc3Npb24gPSBmdW5jdGlvbiAodGVybV81MDUsIHN0YXRlXzUwNikge1xuICByZXR1cm4gbmV3IEFycmF5RXhwcmVzc2lvbihzdGF0ZV81MDYpO1xufTtcbmV4cG9ydCB7QXJyYXlFeHByZXNzaW9uIGFzIEFycmF5RXhwcmVzc2lvbn07XG5jbGFzcyBBcnJvd0V4cHJlc3Npb24gZXh0ZW5kcyBFeHByZXNzaW9uIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfNTA3LCB0eXBlXzUwOCkge1xuICAgIHN1cGVyKGF0dHJzXzUwNywgdHlwZV81MDggfHwgXCJBcnJvd0V4cHJlc3Npb25cIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzUwNywgXCJwYXJhbXNcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwicGFyYW1zXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNTA3LCBcImJvZHlcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiYm9keVwiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfNTA5LCBzdGF0ZV81MTAgPSB7fSkge1xuICAgIHN0YXRlXzUxMC5wYXJhbXMgPSB0aGlzLnBhcmFtcyBpbnN0YW5jZW9mIEZvcm1hbFBhcmFtZXRlcnMgPyB0aGlzLnBhcmFtcy5yZWR1Y2UocmVkdWNlcl81MDkpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5wYXJhbXMpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfNTEwLmJvZHkgPSB0aGlzLmJvZHkgaW5zdGFuY2VvZiBGdW5jdGlvbkJvZHkgPyB0aGlzLmJvZHkucmVkdWNlKHJlZHVjZXJfNTA5KSA6IHRoaXMuYm9keSBpbnN0YW5jZW9mIEV4cHJlc3Npb24gPyB0aGlzLmJvZHkucmVkdWNlKHJlZHVjZXJfNTA5KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMuYm9keSkpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzUwOSwgc3RhdGVfNTEwKTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7cGFyYW1zOiB0aGlzLnBhcmFtcywgYm9keTogdGhpcy5ib2R5fSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfNTExKSB7XG4gICAgbGV0IHN0YXRlXzUxMiA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNTExKTtcbiAgICByZXR1cm4gcmVkdWNlcl81MTEucmVkdWNlQXJyb3dFeHByZXNzaW9uKHRoaXMsIHN0YXRlXzUxMik7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzUxMykge1xuICAgIHJldHVybiBuZXcgQXJyb3dFeHByZXNzaW9uKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc181MTMpKTtcbiAgfVxufVxuRXhwcmVzc2lvbi5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZUFycm93RXhwcmVzc2lvbiA9IGZ1bmN0aW9uICh0ZXJtXzUxNCwgc3RhdGVfNTE1KSB7XG4gIHJldHVybiBuZXcgQXJyb3dFeHByZXNzaW9uKHN0YXRlXzUxNSk7XG59O1xuZXhwb3J0IHtBcnJvd0V4cHJlc3Npb24gYXMgQXJyb3dFeHByZXNzaW9ufTtcbmNsYXNzIEFycm93RXhwcmVzc2lvbkUgZXh0ZW5kcyBFeHByZXNzaW9uIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfNTE2LCB0eXBlXzUxNykge1xuICAgIHN1cGVyKGF0dHJzXzUxNiwgdHlwZV81MTcgfHwgXCJBcnJvd0V4cHJlc3Npb25FXCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc181MTYsIFwicGFyYW1zXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcInBhcmFtc1wiKTtcbiAgICB9XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzUxNiwgXCJib2R5XCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImJvZHlcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzUxOCwgc3RhdGVfNTE5ID0ge30pIHtcbiAgICBzdGF0ZV81MTkucGFyYW1zID0gdGhpcy5wYXJhbXMgaW5zdGFuY2VvZiBGb3JtYWxQYXJhbWV0ZXJzID8gdGhpcy5wYXJhbXMucmVkdWNlKHJlZHVjZXJfNTE4KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMucGFyYW1zKSk7XG4gICAgfS5jYWxsKHRoaXMpO1xuICAgIHN0YXRlXzUxOS5ib2R5ID0gdGhpcy5ib2R5Lm1hcChhXzUyMCA9PiBhXzUyMCBpbnN0YW5jZW9mIFRlcm0gPyBhXzUyMC5yZWR1Y2UocmVkdWNlcl81MTgpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkoYV81MjApKTtcbiAgICB9LmNhbGwodGhpcykpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNTE4LCBzdGF0ZV81MTkpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtwYXJhbXM6IHRoaXMucGFyYW1zLCBib2R5OiB0aGlzLmJvZHl9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl81MjEpIHtcbiAgICBsZXQgc3RhdGVfNTIyID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl81MjEpO1xuICAgIHJldHVybiByZWR1Y2VyXzUyMS5yZWR1Y2VBcnJvd0V4cHJlc3Npb25FKHRoaXMsIHN0YXRlXzUyMik7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzUyMykge1xuICAgIHJldHVybiBuZXcgQXJyb3dFeHByZXNzaW9uRShPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfNTIzKSk7XG4gIH1cbn1cbkV4cHJlc3Npb24uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VBcnJvd0V4cHJlc3Npb25FID0gZnVuY3Rpb24gKHRlcm1fNTI0LCBzdGF0ZV81MjUpIHtcbiAgcmV0dXJuIG5ldyBBcnJvd0V4cHJlc3Npb25FKHN0YXRlXzUyNSk7XG59O1xuZXhwb3J0IHtBcnJvd0V4cHJlc3Npb25FIGFzIEFycm93RXhwcmVzc2lvbkV9O1xuY2xhc3MgQXNzaWdubWVudEV4cHJlc3Npb24gZXh0ZW5kcyBFeHByZXNzaW9uIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfNTI2LCB0eXBlXzUyNykge1xuICAgIHN1cGVyKGF0dHJzXzUyNiwgdHlwZV81MjcgfHwgXCJBc3NpZ25tZW50RXhwcmVzc2lvblwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNTI2LCBcImJpbmRpbmdcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiYmluZGluZ1wiKTtcbiAgICB9XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzUyNiwgXCJleHByZXNzaW9uXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImV4cHJlc3Npb25cIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzUyOCwgc3RhdGVfNTI5ID0ge30pIHtcbiAgICBzdGF0ZV81MjkuYmluZGluZyA9IHRoaXMuYmluZGluZyBpbnN0YW5jZW9mIEJpbmRpbmdJZGVudGlmaWVyID8gdGhpcy5iaW5kaW5nLnJlZHVjZShyZWR1Y2VyXzUyOCkgOiB0aGlzLmJpbmRpbmcgaW5zdGFuY2VvZiBCaW5kaW5nUHJvcGVydHlQcm9wZXJ0eSA/IHRoaXMuYmluZGluZy5yZWR1Y2UocmVkdWNlcl81MjgpIDogdGhpcy5iaW5kaW5nIGluc3RhbmNlb2YgQmluZGluZ1Byb3BlcnR5SWRlbnRpZmllciA/IHRoaXMuYmluZGluZy5yZWR1Y2UocmVkdWNlcl81MjgpIDogdGhpcy5iaW5kaW5nIGluc3RhbmNlb2YgT2JqZWN0QmluZGluZyA/IHRoaXMuYmluZGluZy5yZWR1Y2UocmVkdWNlcl81MjgpIDogdGhpcy5iaW5kaW5nIGluc3RhbmNlb2YgQXJyYXlCaW5kaW5nID8gdGhpcy5iaW5kaW5nLnJlZHVjZShyZWR1Y2VyXzUyOCkgOiB0aGlzLmJpbmRpbmcgaW5zdGFuY2VvZiBNZW1iZXJFeHByZXNzaW9uID8gdGhpcy5iaW5kaW5nLnJlZHVjZShyZWR1Y2VyXzUyOCkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmJpbmRpbmcpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfNTI5LmV4cHJlc3Npb24gPSB0aGlzLmV4cHJlc3Npb24gaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gdGhpcy5leHByZXNzaW9uLnJlZHVjZShyZWR1Y2VyXzUyOCkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmV4cHJlc3Npb24pKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl81MjgsIHN0YXRlXzUyOSk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe2JpbmRpbmc6IHRoaXMuYmluZGluZywgZXhwcmVzc2lvbjogdGhpcy5leHByZXNzaW9ufSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfNTMwKSB7XG4gICAgbGV0IHN0YXRlXzUzMSA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNTMwKTtcbiAgICByZXR1cm4gcmVkdWNlcl81MzAucmVkdWNlQXNzaWdubWVudEV4cHJlc3Npb24odGhpcywgc3RhdGVfNTMxKTtcbiAgfVxuICBleHRlbmQoYXR0cnNfNTMyKSB7XG4gICAgcmV0dXJuIG5ldyBBc3NpZ25tZW50RXhwcmVzc2lvbihPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfNTMyKSk7XG4gIH1cbn1cbkV4cHJlc3Npb24uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VBc3NpZ25tZW50RXhwcmVzc2lvbiA9IGZ1bmN0aW9uICh0ZXJtXzUzMywgc3RhdGVfNTM0KSB7XG4gIHJldHVybiBuZXcgQXNzaWdubWVudEV4cHJlc3Npb24oc3RhdGVfNTM0KTtcbn07XG5leHBvcnQge0Fzc2lnbm1lbnRFeHByZXNzaW9uIGFzIEFzc2lnbm1lbnRFeHByZXNzaW9ufTtcbmNsYXNzIEJpbmFyeUV4cHJlc3Npb24gZXh0ZW5kcyBFeHByZXNzaW9uIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfNTM1LCB0eXBlXzUzNikge1xuICAgIHN1cGVyKGF0dHJzXzUzNSwgdHlwZV81MzYgfHwgXCJCaW5hcnlFeHByZXNzaW9uXCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc181MzUsIFwib3BlcmF0b3JcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwib3BlcmF0b3JcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc181MzUsIFwibGVmdFwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJsZWZ0XCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNTM1LCBcInJpZ2h0XCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcInJpZ2h0XCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl81MzcsIHN0YXRlXzUzOCA9IHt9KSB7XG4gICAgc3RhdGVfNTM4Lm9wZXJhdG9yID0gdGhpcy5vcGVyYXRvcjtcbiAgICBzdGF0ZV81MzgubGVmdCA9IHRoaXMubGVmdCBpbnN0YW5jZW9mIEV4cHJlc3Npb24gPyB0aGlzLmxlZnQucmVkdWNlKHJlZHVjZXJfNTM3KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMubGVmdCkpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICBzdGF0ZV81MzgucmlnaHQgPSB0aGlzLnJpZ2h0IGluc3RhbmNlb2YgRXhwcmVzc2lvbiA/IHRoaXMucmlnaHQucmVkdWNlKHJlZHVjZXJfNTM3KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMucmlnaHQpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl81MzcsIHN0YXRlXzUzOCk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe29wZXJhdG9yOiB0aGlzLm9wZXJhdG9yLCBsZWZ0OiB0aGlzLmxlZnQsIHJpZ2h0OiB0aGlzLnJpZ2h0fSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfNTM5KSB7XG4gICAgbGV0IHN0YXRlXzU0MCA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNTM5KTtcbiAgICByZXR1cm4gcmVkdWNlcl81MzkucmVkdWNlQmluYXJ5RXhwcmVzc2lvbih0aGlzLCBzdGF0ZV81NDApO1xuICB9XG4gIGV4dGVuZChhdHRyc181NDEpIHtcbiAgICByZXR1cm4gbmV3IEJpbmFyeUV4cHJlc3Npb24oT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzU0MSkpO1xuICB9XG59XG5FeHByZXNzaW9uLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlQmluYXJ5RXhwcmVzc2lvbiA9IGZ1bmN0aW9uICh0ZXJtXzU0Miwgc3RhdGVfNTQzKSB7XG4gIHJldHVybiBuZXcgQmluYXJ5RXhwcmVzc2lvbihzdGF0ZV81NDMpO1xufTtcbmV4cG9ydCB7QmluYXJ5RXhwcmVzc2lvbiBhcyBCaW5hcnlFeHByZXNzaW9ufTtcbmNsYXNzIENhbGxFeHByZXNzaW9uIGV4dGVuZHMgRXhwcmVzc2lvbiB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzU0NCwgdHlwZV81NDUpIHtcbiAgICBzdXBlcihhdHRyc181NDQsIHR5cGVfNTQ1IHx8IFwiQ2FsbEV4cHJlc3Npb25cIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzU0NCwgXCJjYWxsZWVcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiY2FsbGVlXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNTQ0LCBcImFyZ3VtZW50c1wiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJhcmd1bWVudHNcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzU0Niwgc3RhdGVfNTQ3ID0ge30pIHtcbiAgICBzdGF0ZV81NDcuY2FsbGVlID0gdGhpcy5jYWxsZWUgaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gdGhpcy5jYWxsZWUucmVkdWNlKHJlZHVjZXJfNTQ2KSA6IHRoaXMuY2FsbGVlIGluc3RhbmNlb2YgU3VwZXIgPyB0aGlzLmNhbGxlZS5yZWR1Y2UocmVkdWNlcl81NDYpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5jYWxsZWUpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfNTQ3LmFyZ3VtZW50cyA9IHRoaXMuYXJndW1lbnRzLm1hcChhXzU0OCA9PiBhXzU0OCBpbnN0YW5jZW9mIFNwcmVhZEVsZW1lbnQgPyBhXzU0OC5yZWR1Y2UocmVkdWNlcl81NDYpIDogYV81NDggaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gYV81NDgucmVkdWNlKHJlZHVjZXJfNTQ2KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KGFfNTQ4KSk7XG4gICAgfS5jYWxsKHRoaXMpKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzU0Niwgc3RhdGVfNTQ3KTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7Y2FsbGVlOiB0aGlzLmNhbGxlZSwgYXJndW1lbnRzOiB0aGlzLmFyZ3VtZW50c30sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzU0OSkge1xuICAgIGxldCBzdGF0ZV81NTAgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzU0OSk7XG4gICAgcmV0dXJuIHJlZHVjZXJfNTQ5LnJlZHVjZUNhbGxFeHByZXNzaW9uKHRoaXMsIHN0YXRlXzU1MCk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzU1MSkge1xuICAgIHJldHVybiBuZXcgQ2FsbEV4cHJlc3Npb24oT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzU1MSkpO1xuICB9XG59XG5FeHByZXNzaW9uLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlQ2FsbEV4cHJlc3Npb24gPSBmdW5jdGlvbiAodGVybV81NTIsIHN0YXRlXzU1Mykge1xuICByZXR1cm4gbmV3IENhbGxFeHByZXNzaW9uKHN0YXRlXzU1Myk7XG59O1xuZXhwb3J0IHtDYWxsRXhwcmVzc2lvbiBhcyBDYWxsRXhwcmVzc2lvbn07XG5jbGFzcyBDYWxsRXhwcmVzc2lvbkUgZXh0ZW5kcyBFeHByZXNzaW9uIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfNTU0LCB0eXBlXzU1NSkge1xuICAgIHN1cGVyKGF0dHJzXzU1NCwgdHlwZV81NTUgfHwgXCJDYWxsRXhwcmVzc2lvbkVcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzU1NCwgXCJjYWxsZWVcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiY2FsbGVlXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNTU0LCBcImFyZ3VtZW50c1wiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJhcmd1bWVudHNcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzU1Niwgc3RhdGVfNTU3ID0ge30pIHtcbiAgICBzdGF0ZV81NTcuY2FsbGVlID0gdGhpcy5jYWxsZWUgaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gdGhpcy5jYWxsZWUucmVkdWNlKHJlZHVjZXJfNTU2KSA6IHRoaXMuY2FsbGVlIGluc3RhbmNlb2YgU3VwZXIgPyB0aGlzLmNhbGxlZS5yZWR1Y2UocmVkdWNlcl81NTYpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5jYWxsZWUpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfNTU3LmFyZ3VtZW50cyA9IHRoaXMuYXJndW1lbnRzLm1hcChhXzU1OCA9PiBhXzU1OCBpbnN0YW5jZW9mIFRlcm0gPyBhXzU1OC5yZWR1Y2UocmVkdWNlcl81NTYpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkoYV81NTgpKTtcbiAgICB9LmNhbGwodGhpcykpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNTU2LCBzdGF0ZV81NTcpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtjYWxsZWU6IHRoaXMuY2FsbGVlLCBhcmd1bWVudHM6IHRoaXMuYXJndW1lbnRzfSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfNTU5KSB7XG4gICAgbGV0IHN0YXRlXzU2MCA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNTU5KTtcbiAgICByZXR1cm4gcmVkdWNlcl81NTkucmVkdWNlQ2FsbEV4cHJlc3Npb25FKHRoaXMsIHN0YXRlXzU2MCk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzU2MSkge1xuICAgIHJldHVybiBuZXcgQ2FsbEV4cHJlc3Npb25FKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc181NjEpKTtcbiAgfVxufVxuRXhwcmVzc2lvbi5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZUNhbGxFeHByZXNzaW9uRSA9IGZ1bmN0aW9uICh0ZXJtXzU2Miwgc3RhdGVfNTYzKSB7XG4gIHJldHVybiBuZXcgQ2FsbEV4cHJlc3Npb25FKHN0YXRlXzU2Myk7XG59O1xuZXhwb3J0IHtDYWxsRXhwcmVzc2lvbkUgYXMgQ2FsbEV4cHJlc3Npb25FfTtcbmNsYXNzIENvbXBvdW5kQXNzaWdubWVudEV4cHJlc3Npb24gZXh0ZW5kcyBFeHByZXNzaW9uIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfNTY0LCB0eXBlXzU2NSkge1xuICAgIHN1cGVyKGF0dHJzXzU2NCwgdHlwZV81NjUgfHwgXCJDb21wb3VuZEFzc2lnbm1lbnRFeHByZXNzaW9uXCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc181NjQsIFwiYmluZGluZ1wiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJiaW5kaW5nXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNTY0LCBcIm9wZXJhdG9yXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcIm9wZXJhdG9yXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNTY0LCBcImV4cHJlc3Npb25cIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiZXhwcmVzc2lvblwiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfNTY2LCBzdGF0ZV81NjcgPSB7fSkge1xuICAgIHN0YXRlXzU2Ny5iaW5kaW5nID0gdGhpcy5iaW5kaW5nIGluc3RhbmNlb2YgQmluZGluZ0lkZW50aWZpZXIgPyB0aGlzLmJpbmRpbmcucmVkdWNlKHJlZHVjZXJfNTY2KSA6IHRoaXMuYmluZGluZyBpbnN0YW5jZW9mIE1lbWJlckV4cHJlc3Npb24gPyB0aGlzLmJpbmRpbmcucmVkdWNlKHJlZHVjZXJfNTY2KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMuYmluZGluZykpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICBzdGF0ZV81Njcub3BlcmF0b3IgPSB0aGlzLm9wZXJhdG9yO1xuICAgIHN0YXRlXzU2Ny5leHByZXNzaW9uID0gdGhpcy5leHByZXNzaW9uIGluc3RhbmNlb2YgRXhwcmVzc2lvbiA/IHRoaXMuZXhwcmVzc2lvbi5yZWR1Y2UocmVkdWNlcl81NjYpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5leHByZXNzaW9uKSk7XG4gICAgfS5jYWxsKHRoaXMpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNTY2LCBzdGF0ZV81NjcpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtiaW5kaW5nOiB0aGlzLmJpbmRpbmcsIG9wZXJhdG9yOiB0aGlzLm9wZXJhdG9yLCBleHByZXNzaW9uOiB0aGlzLmV4cHJlc3Npb259LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl81NjgpIHtcbiAgICBsZXQgc3RhdGVfNTY5ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl81NjgpO1xuICAgIHJldHVybiByZWR1Y2VyXzU2OC5yZWR1Y2VDb21wb3VuZEFzc2lnbm1lbnRFeHByZXNzaW9uKHRoaXMsIHN0YXRlXzU2OSk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzU3MCkge1xuICAgIHJldHVybiBuZXcgQ29tcG91bmRBc3NpZ25tZW50RXhwcmVzc2lvbihPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfNTcwKSk7XG4gIH1cbn1cbkV4cHJlc3Npb24uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VDb21wb3VuZEFzc2lnbm1lbnRFeHByZXNzaW9uID0gZnVuY3Rpb24gKHRlcm1fNTcxLCBzdGF0ZV81NzIpIHtcbiAgcmV0dXJuIG5ldyBDb21wb3VuZEFzc2lnbm1lbnRFeHByZXNzaW9uKHN0YXRlXzU3Mik7XG59O1xuZXhwb3J0IHtDb21wb3VuZEFzc2lnbm1lbnRFeHByZXNzaW9uIGFzIENvbXBvdW5kQXNzaWdubWVudEV4cHJlc3Npb259O1xuY2xhc3MgQ29tcHV0ZWRNZW1iZXJFeHByZXNzaW9uIGV4dGVuZHMgTWVtYmVyRXhwcmVzc2lvbiB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzU3MywgdHlwZV81NzQpIHtcbiAgICBzdXBlcihhdHRyc181NzMsIHR5cGVfNTc0IHx8IFwiQ29tcHV0ZWRNZW1iZXJFeHByZXNzaW9uXCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc181NzMsIFwiZXhwcmVzc2lvblwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJleHByZXNzaW9uXCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl81NzUsIHN0YXRlXzU3NiA9IHt9KSB7XG4gICAgc3RhdGVfNTc2LmV4cHJlc3Npb24gPSB0aGlzLmV4cHJlc3Npb24gaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gdGhpcy5leHByZXNzaW9uLnJlZHVjZShyZWR1Y2VyXzU3NSkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmV4cHJlc3Npb24pKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl81NzUsIHN0YXRlXzU3Nik7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe2V4cHJlc3Npb246IHRoaXMuZXhwcmVzc2lvbn0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzU3Nykge1xuICAgIGxldCBzdGF0ZV81NzggPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzU3Nyk7XG4gICAgcmV0dXJuIHJlZHVjZXJfNTc3LnJlZHVjZUNvbXB1dGVkTWVtYmVyRXhwcmVzc2lvbih0aGlzLCBzdGF0ZV81NzgpO1xuICB9XG4gIGV4dGVuZChhdHRyc181NzkpIHtcbiAgICByZXR1cm4gbmV3IENvbXB1dGVkTWVtYmVyRXhwcmVzc2lvbihPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfNTc5KSk7XG4gIH1cbn1cbk1lbWJlckV4cHJlc3Npb24uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VDb21wdXRlZE1lbWJlckV4cHJlc3Npb24gPSBmdW5jdGlvbiAodGVybV81ODAsIHN0YXRlXzU4MSkge1xuICByZXR1cm4gbmV3IENvbXB1dGVkTWVtYmVyRXhwcmVzc2lvbihzdGF0ZV81ODEpO1xufTtcbmV4cG9ydCB7Q29tcHV0ZWRNZW1iZXJFeHByZXNzaW9uIGFzIENvbXB1dGVkTWVtYmVyRXhwcmVzc2lvbn07XG5jbGFzcyBDb25kaXRpb25hbEV4cHJlc3Npb24gZXh0ZW5kcyBFeHByZXNzaW9uIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfNTgyLCB0eXBlXzU4Mykge1xuICAgIHN1cGVyKGF0dHJzXzU4MiwgdHlwZV81ODMgfHwgXCJDb25kaXRpb25hbEV4cHJlc3Npb25cIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzU4MiwgXCJ0ZXN0XCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcInRlc3RcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc181ODIsIFwiY29uc2VxdWVudFwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJjb25zZXF1ZW50XCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNTgyLCBcImFsdGVybmF0ZVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJhbHRlcm5hdGVcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzU4NCwgc3RhdGVfNTg1ID0ge30pIHtcbiAgICBzdGF0ZV81ODUudGVzdCA9IHRoaXMudGVzdCBpbnN0YW5jZW9mIEV4cHJlc3Npb24gPyB0aGlzLnRlc3QucmVkdWNlKHJlZHVjZXJfNTg0KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMudGVzdCkpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICBzdGF0ZV81ODUuY29uc2VxdWVudCA9IHRoaXMuY29uc2VxdWVudCBpbnN0YW5jZW9mIEV4cHJlc3Npb24gPyB0aGlzLmNvbnNlcXVlbnQucmVkdWNlKHJlZHVjZXJfNTg0KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMuY29uc2VxdWVudCkpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICBzdGF0ZV81ODUuYWx0ZXJuYXRlID0gdGhpcy5hbHRlcm5hdGUgaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gdGhpcy5hbHRlcm5hdGUucmVkdWNlKHJlZHVjZXJfNTg0KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMuYWx0ZXJuYXRlKSk7XG4gICAgfS5jYWxsKHRoaXMpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNTg0LCBzdGF0ZV81ODUpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt0ZXN0OiB0aGlzLnRlc3QsIGNvbnNlcXVlbnQ6IHRoaXMuY29uc2VxdWVudCwgYWx0ZXJuYXRlOiB0aGlzLmFsdGVybmF0ZX0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzU4Nikge1xuICAgIGxldCBzdGF0ZV81ODcgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzU4Nik7XG4gICAgcmV0dXJuIHJlZHVjZXJfNTg2LnJlZHVjZUNvbmRpdGlvbmFsRXhwcmVzc2lvbih0aGlzLCBzdGF0ZV81ODcpO1xuICB9XG4gIGV4dGVuZChhdHRyc181ODgpIHtcbiAgICByZXR1cm4gbmV3IENvbmRpdGlvbmFsRXhwcmVzc2lvbihPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfNTg4KSk7XG4gIH1cbn1cbkV4cHJlc3Npb24uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VDb25kaXRpb25hbEV4cHJlc3Npb24gPSBmdW5jdGlvbiAodGVybV81ODksIHN0YXRlXzU5MCkge1xuICByZXR1cm4gbmV3IENvbmRpdGlvbmFsRXhwcmVzc2lvbihzdGF0ZV81OTApO1xufTtcbmV4cG9ydCB7Q29uZGl0aW9uYWxFeHByZXNzaW9uIGFzIENvbmRpdGlvbmFsRXhwcmVzc2lvbn07XG5jbGFzcyBGdW5jdGlvbkV4cHJlc3Npb24gZXh0ZW5kcyBFeHByZXNzaW9uIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfNTkxLCB0eXBlXzU5Mikge1xuICAgIHN1cGVyKGF0dHJzXzU5MSwgdHlwZV81OTIgfHwgXCJGdW5jdGlvbkV4cHJlc3Npb25cIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzU5MSwgXCJuYW1lXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcIm5hbWVcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc181OTEsIFwiaXNHZW5lcmF0b3JcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiaXNHZW5lcmF0b3JcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc181OTEsIFwicGFyYW1zXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcInBhcmFtc1wiKTtcbiAgICB9XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzU5MSwgXCJib2R5XCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImJvZHlcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzU5Mywgc3RhdGVfNTk0ID0ge30pIHtcbiAgICBzdGF0ZV81OTQubmFtZSA9IHRoaXMubmFtZSA9PSBudWxsID8gbnVsbCA6IHRoaXMubmFtZSBpbnN0YW5jZW9mIEJpbmRpbmdJZGVudGlmaWVyID8gdGhpcy5uYW1lLnJlZHVjZShyZWR1Y2VyXzU5MykgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLm5hbWUpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfNTk0LmlzR2VuZXJhdG9yID0gdGhpcy5pc0dlbmVyYXRvcjtcbiAgICBzdGF0ZV81OTQucGFyYW1zID0gdGhpcy5wYXJhbXMgaW5zdGFuY2VvZiBGb3JtYWxQYXJhbWV0ZXJzID8gdGhpcy5wYXJhbXMucmVkdWNlKHJlZHVjZXJfNTkzKSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMucGFyYW1zKSk7XG4gICAgfS5jYWxsKHRoaXMpO1xuICAgIHN0YXRlXzU5NC5ib2R5ID0gdGhpcy5ib2R5IGluc3RhbmNlb2YgRnVuY3Rpb25Cb2R5ID8gdGhpcy5ib2R5LnJlZHVjZShyZWR1Y2VyXzU5MykgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmJvZHkpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl81OTMsIHN0YXRlXzU5NCk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe25hbWU6IHRoaXMubmFtZSwgaXNHZW5lcmF0b3I6IHRoaXMuaXNHZW5lcmF0b3IsIHBhcmFtczogdGhpcy5wYXJhbXMsIGJvZHk6IHRoaXMuYm9keX0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzU5NSkge1xuICAgIGxldCBzdGF0ZV81OTYgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzU5NSk7XG4gICAgcmV0dXJuIHJlZHVjZXJfNTk1LnJlZHVjZUZ1bmN0aW9uRXhwcmVzc2lvbih0aGlzLCBzdGF0ZV81OTYpO1xuICB9XG4gIGV4dGVuZChhdHRyc181OTcpIHtcbiAgICByZXR1cm4gbmV3IEZ1bmN0aW9uRXhwcmVzc2lvbihPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfNTk3KSk7XG4gIH1cbn1cbkV4cHJlc3Npb24uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VGdW5jdGlvbkV4cHJlc3Npb24gPSBmdW5jdGlvbiAodGVybV81OTgsIHN0YXRlXzU5OSkge1xuICByZXR1cm4gbmV3IEZ1bmN0aW9uRXhwcmVzc2lvbihzdGF0ZV81OTkpO1xufTtcbmV4cG9ydCB7RnVuY3Rpb25FeHByZXNzaW9uIGFzIEZ1bmN0aW9uRXhwcmVzc2lvbn07XG5jbGFzcyBGdW5jdGlvbkV4cHJlc3Npb25FIGV4dGVuZHMgRXhwcmVzc2lvbiB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzYwMCwgdHlwZV82MDEpIHtcbiAgICBzdXBlcihhdHRyc182MDAsIHR5cGVfNjAxIHx8IFwiRnVuY3Rpb25FeHByZXNzaW9uRVwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNjAwLCBcIm5hbWVcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwibmFtZVwiKTtcbiAgICB9XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzYwMCwgXCJpc0dlbmVyYXRvclwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJpc0dlbmVyYXRvclwiKTtcbiAgICB9XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzYwMCwgXCJwYXJhbXNcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwicGFyYW1zXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNjAwLCBcImJvZHlcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiYm9keVwiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfNjAyLCBzdGF0ZV82MDMgPSB7fSkge1xuICAgIHN0YXRlXzYwMy5uYW1lID0gdGhpcy5uYW1lID09IG51bGwgPyBudWxsIDogdGhpcy5uYW1lIGluc3RhbmNlb2YgQmluZGluZ0lkZW50aWZpZXIgPyB0aGlzLm5hbWUucmVkdWNlKHJlZHVjZXJfNjAyKSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMubmFtZSkpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICBzdGF0ZV82MDMuaXNHZW5lcmF0b3IgPSB0aGlzLmlzR2VuZXJhdG9yO1xuICAgIHN0YXRlXzYwMy5wYXJhbXMgPSB0aGlzLnBhcmFtcyBpbnN0YW5jZW9mIEZvcm1hbFBhcmFtZXRlcnMgPyB0aGlzLnBhcmFtcy5yZWR1Y2UocmVkdWNlcl82MDIpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5wYXJhbXMpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfNjAzLmJvZHkgPSB0aGlzLmJvZHkubWFwKGFfNjA0ID0+IGFfNjA0IGluc3RhbmNlb2YgVGVybSA/IGFfNjA0LnJlZHVjZShyZWR1Y2VyXzYwMikgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeShhXzYwNCkpO1xuICAgIH0uY2FsbCh0aGlzKSk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl82MDIsIHN0YXRlXzYwMyk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe25hbWU6IHRoaXMubmFtZSwgaXNHZW5lcmF0b3I6IHRoaXMuaXNHZW5lcmF0b3IsIHBhcmFtczogdGhpcy5wYXJhbXMsIGJvZHk6IHRoaXMuYm9keX0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzYwNSkge1xuICAgIGxldCBzdGF0ZV82MDYgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzYwNSk7XG4gICAgcmV0dXJuIHJlZHVjZXJfNjA1LnJlZHVjZUZ1bmN0aW9uRXhwcmVzc2lvbkUodGhpcywgc3RhdGVfNjA2KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfNjA3KSB7XG4gICAgcmV0dXJuIG5ldyBGdW5jdGlvbkV4cHJlc3Npb25FKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc182MDcpKTtcbiAgfVxufVxuRXhwcmVzc2lvbi5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZUZ1bmN0aW9uRXhwcmVzc2lvbkUgPSBmdW5jdGlvbiAodGVybV82MDgsIHN0YXRlXzYwOSkge1xuICByZXR1cm4gbmV3IEZ1bmN0aW9uRXhwcmVzc2lvbkUoc3RhdGVfNjA5KTtcbn07XG5leHBvcnQge0Z1bmN0aW9uRXhwcmVzc2lvbkUgYXMgRnVuY3Rpb25FeHByZXNzaW9uRX07XG5jbGFzcyBJZGVudGlmaWVyRXhwcmVzc2lvbiBleHRlbmRzIEV4cHJlc3Npb24ge1xuICBjb25zdHJ1Y3RvcihhdHRyc182MTAsIHR5cGVfNjExKSB7XG4gICAgc3VwZXIoYXR0cnNfNjEwLCB0eXBlXzYxMSB8fCBcIklkZW50aWZpZXJFeHByZXNzaW9uXCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc182MTAsIFwibmFtZVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJuYW1lXCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl82MTIsIHN0YXRlXzYxMyA9IHt9KSB7XG4gICAgc3RhdGVfNjEzLm5hbWUgPSB0aGlzLm5hbWU7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl82MTIsIHN0YXRlXzYxMyk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe25hbWU6IHRoaXMubmFtZX0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzYxNCkge1xuICAgIGxldCBzdGF0ZV82MTUgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzYxNCk7XG4gICAgcmV0dXJuIHJlZHVjZXJfNjE0LnJlZHVjZUlkZW50aWZpZXJFeHByZXNzaW9uKHRoaXMsIHN0YXRlXzYxNSk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzYxNikge1xuICAgIHJldHVybiBuZXcgSWRlbnRpZmllckV4cHJlc3Npb24oT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzYxNikpO1xuICB9XG59XG5FeHByZXNzaW9uLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlSWRlbnRpZmllckV4cHJlc3Npb24gPSBmdW5jdGlvbiAodGVybV82MTcsIHN0YXRlXzYxOCkge1xuICByZXR1cm4gbmV3IElkZW50aWZpZXJFeHByZXNzaW9uKHN0YXRlXzYxOCk7XG59O1xuZXhwb3J0IHtJZGVudGlmaWVyRXhwcmVzc2lvbiBhcyBJZGVudGlmaWVyRXhwcmVzc2lvbn07XG5jbGFzcyBOZXdFeHByZXNzaW9uIGV4dGVuZHMgRXhwcmVzc2lvbiB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzYxOSwgdHlwZV82MjApIHtcbiAgICBzdXBlcihhdHRyc182MTksIHR5cGVfNjIwIHx8IFwiTmV3RXhwcmVzc2lvblwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNjE5LCBcImNhbGxlZVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJjYWxsZWVcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc182MTksIFwiYXJndW1lbnRzXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImFyZ3VtZW50c1wiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfNjIxLCBzdGF0ZV82MjIgPSB7fSkge1xuICAgIHN0YXRlXzYyMi5jYWxsZWUgPSB0aGlzLmNhbGxlZSBpbnN0YW5jZW9mIEV4cHJlc3Npb24gPyB0aGlzLmNhbGxlZS5yZWR1Y2UocmVkdWNlcl82MjEpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5jYWxsZWUpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfNjIyLmFyZ3VtZW50cyA9IHRoaXMuYXJndW1lbnRzLm1hcChhXzYyMyA9PiBhXzYyMyBpbnN0YW5jZW9mIFNwcmVhZEVsZW1lbnQgPyBhXzYyMy5yZWR1Y2UocmVkdWNlcl82MjEpIDogYV82MjMgaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gYV82MjMucmVkdWNlKHJlZHVjZXJfNjIxKSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KGFfNjIzKSk7XG4gICAgfS5jYWxsKHRoaXMpKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzYyMSwgc3RhdGVfNjIyKTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7Y2FsbGVlOiB0aGlzLmNhbGxlZSwgYXJndW1lbnRzOiB0aGlzLmFyZ3VtZW50c30sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzYyNCkge1xuICAgIGxldCBzdGF0ZV82MjUgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzYyNCk7XG4gICAgcmV0dXJuIHJlZHVjZXJfNjI0LnJlZHVjZU5ld0V4cHJlc3Npb24odGhpcywgc3RhdGVfNjI1KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfNjI2KSB7XG4gICAgcmV0dXJuIG5ldyBOZXdFeHByZXNzaW9uKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc182MjYpKTtcbiAgfVxufVxuRXhwcmVzc2lvbi5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZU5ld0V4cHJlc3Npb24gPSBmdW5jdGlvbiAodGVybV82MjcsIHN0YXRlXzYyOCkge1xuICByZXR1cm4gbmV3IE5ld0V4cHJlc3Npb24oc3RhdGVfNjI4KTtcbn07XG5leHBvcnQge05ld0V4cHJlc3Npb24gYXMgTmV3RXhwcmVzc2lvbn07XG5jbGFzcyBOZXdUYXJnZXRFeHByZXNzaW9uIGV4dGVuZHMgRXhwcmVzc2lvbiB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzYyOSwgdHlwZV82MzApIHtcbiAgICBzdXBlcihhdHRyc182MjksIHR5cGVfNjMwIHx8IFwiTmV3VGFyZ2V0RXhwcmVzc2lvblwiKTtcbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl82MzEsIHN0YXRlXzYzMiA9IHt9KSB7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl82MzEsIHN0YXRlXzYzMik7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzYzMykge1xuICAgIGxldCBzdGF0ZV82MzQgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzYzMyk7XG4gICAgcmV0dXJuIHJlZHVjZXJfNjMzLnJlZHVjZU5ld1RhcmdldEV4cHJlc3Npb24odGhpcywgc3RhdGVfNjM0KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfNjM1KSB7XG4gICAgcmV0dXJuIG5ldyBOZXdUYXJnZXRFeHByZXNzaW9uKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc182MzUpKTtcbiAgfVxufVxuRXhwcmVzc2lvbi5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZU5ld1RhcmdldEV4cHJlc3Npb24gPSBmdW5jdGlvbiAodGVybV82MzYsIHN0YXRlXzYzNykge1xuICByZXR1cm4gbmV3IE5ld1RhcmdldEV4cHJlc3Npb24oc3RhdGVfNjM3KTtcbn07XG5leHBvcnQge05ld1RhcmdldEV4cHJlc3Npb24gYXMgTmV3VGFyZ2V0RXhwcmVzc2lvbn07XG5jbGFzcyBPYmplY3RFeHByZXNzaW9uIGV4dGVuZHMgRXhwcmVzc2lvbiB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzYzOCwgdHlwZV82MzkpIHtcbiAgICBzdXBlcihhdHRyc182MzgsIHR5cGVfNjM5IHx8IFwiT2JqZWN0RXhwcmVzc2lvblwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNjM4LCBcInByb3BlcnRpZXNcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwicHJvcGVydGllc1wiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfNjQwLCBzdGF0ZV82NDEgPSB7fSkge1xuICAgIHN0YXRlXzY0MS5wcm9wZXJ0aWVzID0gdGhpcy5wcm9wZXJ0aWVzLm1hcChhXzY0MiA9PiBhXzY0MiBpbnN0YW5jZW9mIE9iamVjdFByb3BlcnR5ID8gYV82NDIucmVkdWNlKHJlZHVjZXJfNjQwKSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KGFfNjQyKSk7XG4gICAgfS5jYWxsKHRoaXMpKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzY0MCwgc3RhdGVfNjQxKTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7cHJvcGVydGllczogdGhpcy5wcm9wZXJ0aWVzfSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfNjQzKSB7XG4gICAgbGV0IHN0YXRlXzY0NCA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNjQzKTtcbiAgICByZXR1cm4gcmVkdWNlcl82NDMucmVkdWNlT2JqZWN0RXhwcmVzc2lvbih0aGlzLCBzdGF0ZV82NDQpO1xuICB9XG4gIGV4dGVuZChhdHRyc182NDUpIHtcbiAgICByZXR1cm4gbmV3IE9iamVjdEV4cHJlc3Npb24oT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzY0NSkpO1xuICB9XG59XG5FeHByZXNzaW9uLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlT2JqZWN0RXhwcmVzc2lvbiA9IGZ1bmN0aW9uICh0ZXJtXzY0Niwgc3RhdGVfNjQ3KSB7XG4gIHJldHVybiBuZXcgT2JqZWN0RXhwcmVzc2lvbihzdGF0ZV82NDcpO1xufTtcbmV4cG9ydCB7T2JqZWN0RXhwcmVzc2lvbiBhcyBPYmplY3RFeHByZXNzaW9ufTtcbmNsYXNzIFVuYXJ5RXhwcmVzc2lvbiBleHRlbmRzIEV4cHJlc3Npb24ge1xuICBjb25zdHJ1Y3RvcihhdHRyc182NDgsIHR5cGVfNjQ5KSB7XG4gICAgc3VwZXIoYXR0cnNfNjQ4LCB0eXBlXzY0OSB8fCBcIlVuYXJ5RXhwcmVzc2lvblwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNjQ4LCBcIm9wZXJhdG9yXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcIm9wZXJhdG9yXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNjQ4LCBcIm9wZXJhbmRcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwib3BlcmFuZFwiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfNjUwLCBzdGF0ZV82NTEgPSB7fSkge1xuICAgIHN0YXRlXzY1MS5vcGVyYXRvciA9IHRoaXMub3BlcmF0b3I7XG4gICAgc3RhdGVfNjUxLm9wZXJhbmQgPSB0aGlzLm9wZXJhbmQgaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gdGhpcy5vcGVyYW5kLnJlZHVjZShyZWR1Y2VyXzY1MCkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLm9wZXJhbmQpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl82NTAsIHN0YXRlXzY1MSk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe29wZXJhdG9yOiB0aGlzLm9wZXJhdG9yLCBvcGVyYW5kOiB0aGlzLm9wZXJhbmR9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl82NTIpIHtcbiAgICBsZXQgc3RhdGVfNjUzID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl82NTIpO1xuICAgIHJldHVybiByZWR1Y2VyXzY1Mi5yZWR1Y2VVbmFyeUV4cHJlc3Npb24odGhpcywgc3RhdGVfNjUzKTtcbiAgfVxuICBleHRlbmQoYXR0cnNfNjU0KSB7XG4gICAgcmV0dXJuIG5ldyBVbmFyeUV4cHJlc3Npb24oT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzY1NCkpO1xuICB9XG59XG5FeHByZXNzaW9uLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlVW5hcnlFeHByZXNzaW9uID0gZnVuY3Rpb24gKHRlcm1fNjU1LCBzdGF0ZV82NTYpIHtcbiAgcmV0dXJuIG5ldyBVbmFyeUV4cHJlc3Npb24oc3RhdGVfNjU2KTtcbn07XG5leHBvcnQge1VuYXJ5RXhwcmVzc2lvbiBhcyBVbmFyeUV4cHJlc3Npb259O1xuY2xhc3MgU3RhdGljTWVtYmVyRXhwcmVzc2lvbiBleHRlbmRzIE1lbWJlckV4cHJlc3Npb24ge1xuICBjb25zdHJ1Y3RvcihhdHRyc182NTcsIHR5cGVfNjU4KSB7XG4gICAgc3VwZXIoYXR0cnNfNjU3LCB0eXBlXzY1OCB8fCBcIlN0YXRpY01lbWJlckV4cHJlc3Npb25cIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzY1NywgXCJwcm9wZXJ0eVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJwcm9wZXJ0eVwiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfNjU5LCBzdGF0ZV82NjAgPSB7fSkge1xuICAgIHN0YXRlXzY2MC5wcm9wZXJ0eSA9IHRoaXMucHJvcGVydHk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl82NTksIHN0YXRlXzY2MCk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe3Byb3BlcnR5OiB0aGlzLnByb3BlcnR5fSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfNjYxKSB7XG4gICAgbGV0IHN0YXRlXzY2MiA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNjYxKTtcbiAgICByZXR1cm4gcmVkdWNlcl82NjEucmVkdWNlU3RhdGljTWVtYmVyRXhwcmVzc2lvbih0aGlzLCBzdGF0ZV82NjIpO1xuICB9XG4gIGV4dGVuZChhdHRyc182NjMpIHtcbiAgICByZXR1cm4gbmV3IFN0YXRpY01lbWJlckV4cHJlc3Npb24oT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzY2MykpO1xuICB9XG59XG5NZW1iZXJFeHByZXNzaW9uLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlU3RhdGljTWVtYmVyRXhwcmVzc2lvbiA9IGZ1bmN0aW9uICh0ZXJtXzY2NCwgc3RhdGVfNjY1KSB7XG4gIHJldHVybiBuZXcgU3RhdGljTWVtYmVyRXhwcmVzc2lvbihzdGF0ZV82NjUpO1xufTtcbmV4cG9ydCB7U3RhdGljTWVtYmVyRXhwcmVzc2lvbiBhcyBTdGF0aWNNZW1iZXJFeHByZXNzaW9ufTtcbmNsYXNzIFRlbXBsYXRlRXhwcmVzc2lvbiBleHRlbmRzIEV4cHJlc3Npb24ge1xuICBjb25zdHJ1Y3RvcihhdHRyc182NjYsIHR5cGVfNjY3KSB7XG4gICAgc3VwZXIoYXR0cnNfNjY2LCB0eXBlXzY2NyB8fCBcIlRlbXBsYXRlRXhwcmVzc2lvblwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNjY2LCBcInRhZ1wiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJ0YWdcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc182NjYsIFwiZWxlbWVudHNcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiZWxlbWVudHNcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzY2OCwgc3RhdGVfNjY5ID0ge30pIHtcbiAgICBzdGF0ZV82NjkudGFnID0gdGhpcy50YWcgPT0gbnVsbCA/IG51bGwgOiB0aGlzLnRhZyBpbnN0YW5jZW9mIEV4cHJlc3Npb24gPyB0aGlzLnRhZy5yZWR1Y2UocmVkdWNlcl82NjgpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy50YWcpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfNjY5LmVsZW1lbnRzID0gdGhpcy5lbGVtZW50cy5tYXAoYV82NzAgPT4gYV82NzAgaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gYV82NzAucmVkdWNlKHJlZHVjZXJfNjY4KSA6IGFfNjcwIGluc3RhbmNlb2YgVGVtcGxhdGVFbGVtZW50ID8gYV82NzAucmVkdWNlKHJlZHVjZXJfNjY4KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KGFfNjcwKSk7XG4gICAgfS5jYWxsKHRoaXMpKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzY2OCwgc3RhdGVfNjY5KTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7dGFnOiB0aGlzLnRhZywgZWxlbWVudHM6IHRoaXMuZWxlbWVudHN9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl82NzEpIHtcbiAgICBsZXQgc3RhdGVfNjcyID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl82NzEpO1xuICAgIHJldHVybiByZWR1Y2VyXzY3MS5yZWR1Y2VUZW1wbGF0ZUV4cHJlc3Npb24odGhpcywgc3RhdGVfNjcyKTtcbiAgfVxuICBleHRlbmQoYXR0cnNfNjczKSB7XG4gICAgcmV0dXJuIG5ldyBUZW1wbGF0ZUV4cHJlc3Npb24oT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzY3MykpO1xuICB9XG59XG5FeHByZXNzaW9uLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlVGVtcGxhdGVFeHByZXNzaW9uID0gZnVuY3Rpb24gKHRlcm1fNjc0LCBzdGF0ZV82NzUpIHtcbiAgcmV0dXJuIG5ldyBUZW1wbGF0ZUV4cHJlc3Npb24oc3RhdGVfNjc1KTtcbn07XG5leHBvcnQge1RlbXBsYXRlRXhwcmVzc2lvbiBhcyBUZW1wbGF0ZUV4cHJlc3Npb259O1xuY2xhc3MgVGhpc0V4cHJlc3Npb24gZXh0ZW5kcyBFeHByZXNzaW9uIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfNjc2LCB0eXBlXzY3Nykge1xuICAgIHN1cGVyKGF0dHJzXzY3NiwgdHlwZV82NzcgfHwgXCJUaGlzRXhwcmVzc2lvblwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNjc2LCBcInN0eFwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJzdHhcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzY3OCwgc3RhdGVfNjc5ID0ge30pIHtcbiAgICBzdGF0ZV82Nzkuc3R4ID0gdGhpcy5zdHg7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl82NzgsIHN0YXRlXzY3OSk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe3N0eDogdGhpcy5zdHh9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl82ODApIHtcbiAgICBsZXQgc3RhdGVfNjgxID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl82ODApO1xuICAgIHJldHVybiByZWR1Y2VyXzY4MC5yZWR1Y2VUaGlzRXhwcmVzc2lvbih0aGlzLCBzdGF0ZV82ODEpO1xuICB9XG4gIGV4dGVuZChhdHRyc182ODIpIHtcbiAgICByZXR1cm4gbmV3IFRoaXNFeHByZXNzaW9uKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc182ODIpKTtcbiAgfVxufVxuRXhwcmVzc2lvbi5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZVRoaXNFeHByZXNzaW9uID0gZnVuY3Rpb24gKHRlcm1fNjgzLCBzdGF0ZV82ODQpIHtcbiAgcmV0dXJuIG5ldyBUaGlzRXhwcmVzc2lvbihzdGF0ZV82ODQpO1xufTtcbmV4cG9ydCB7VGhpc0V4cHJlc3Npb24gYXMgVGhpc0V4cHJlc3Npb259O1xuY2xhc3MgVXBkYXRlRXhwcmVzc2lvbiBleHRlbmRzIEV4cHJlc3Npb24ge1xuICBjb25zdHJ1Y3RvcihhdHRyc182ODUsIHR5cGVfNjg2KSB7XG4gICAgc3VwZXIoYXR0cnNfNjg1LCB0eXBlXzY4NiB8fCBcIlVwZGF0ZUV4cHJlc3Npb25cIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzY4NSwgXCJpc1ByZWZpeFwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJpc1ByZWZpeFwiKTtcbiAgICB9XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzY4NSwgXCJvcGVyYXRvclwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJvcGVyYXRvclwiKTtcbiAgICB9XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzY4NSwgXCJvcGVyYW5kXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcIm9wZXJhbmRcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzY4Nywgc3RhdGVfNjg4ID0ge30pIHtcbiAgICBzdGF0ZV82ODguaXNQcmVmaXggPSB0aGlzLmlzUHJlZml4O1xuICAgIHN0YXRlXzY4OC5vcGVyYXRvciA9IHRoaXMub3BlcmF0b3I7XG4gICAgc3RhdGVfNjg4Lm9wZXJhbmQgPSB0aGlzLm9wZXJhbmQgaW5zdGFuY2VvZiBCaW5kaW5nSWRlbnRpZmllciA/IHRoaXMub3BlcmFuZC5yZWR1Y2UocmVkdWNlcl82ODcpIDogdGhpcy5vcGVyYW5kIGluc3RhbmNlb2YgTWVtYmVyRXhwcmVzc2lvbiA/IHRoaXMub3BlcmFuZC5yZWR1Y2UocmVkdWNlcl82ODcpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5vcGVyYW5kKSk7XG4gICAgfS5jYWxsKHRoaXMpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNjg3LCBzdGF0ZV82ODgpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtpc1ByZWZpeDogdGhpcy5pc1ByZWZpeCwgb3BlcmF0b3I6IHRoaXMub3BlcmF0b3IsIG9wZXJhbmQ6IHRoaXMub3BlcmFuZH0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzY4OSkge1xuICAgIGxldCBzdGF0ZV82OTAgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzY4OSk7XG4gICAgcmV0dXJuIHJlZHVjZXJfNjg5LnJlZHVjZVVwZGF0ZUV4cHJlc3Npb24odGhpcywgc3RhdGVfNjkwKTtcbiAgfVxuICBleHRlbmQoYXR0cnNfNjkxKSB7XG4gICAgcmV0dXJuIG5ldyBVcGRhdGVFeHByZXNzaW9uKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc182OTEpKTtcbiAgfVxufVxuRXhwcmVzc2lvbi5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZVVwZGF0ZUV4cHJlc3Npb24gPSBmdW5jdGlvbiAodGVybV82OTIsIHN0YXRlXzY5Mykge1xuICByZXR1cm4gbmV3IFVwZGF0ZUV4cHJlc3Npb24oc3RhdGVfNjkzKTtcbn07XG5leHBvcnQge1VwZGF0ZUV4cHJlc3Npb24gYXMgVXBkYXRlRXhwcmVzc2lvbn07XG5jbGFzcyBZaWVsZEV4cHJlc3Npb24gZXh0ZW5kcyBFeHByZXNzaW9uIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfNjk0LCB0eXBlXzY5NSkge1xuICAgIHN1cGVyKGF0dHJzXzY5NCwgdHlwZV82OTUgfHwgXCJZaWVsZEV4cHJlc3Npb25cIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzY5NCwgXCJleHByZXNzaW9uXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImV4cHJlc3Npb25cIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzY5Niwgc3RhdGVfNjk3ID0ge30pIHtcbiAgICBzdGF0ZV82OTcuZXhwcmVzc2lvbiA9IHRoaXMuZXhwcmVzc2lvbiA9PSBudWxsID8gbnVsbCA6IHRoaXMuZXhwcmVzc2lvbiBpbnN0YW5jZW9mIEV4cHJlc3Npb24gPyB0aGlzLmV4cHJlc3Npb24ucmVkdWNlKHJlZHVjZXJfNjk2KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMuZXhwcmVzc2lvbikpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzY5Niwgc3RhdGVfNjk3KTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7ZXhwcmVzc2lvbjogdGhpcy5leHByZXNzaW9ufSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfNjk4KSB7XG4gICAgbGV0IHN0YXRlXzY5OSA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNjk4KTtcbiAgICByZXR1cm4gcmVkdWNlcl82OTgucmVkdWNlWWllbGRFeHByZXNzaW9uKHRoaXMsIHN0YXRlXzY5OSk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzcwMCkge1xuICAgIHJldHVybiBuZXcgWWllbGRFeHByZXNzaW9uKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc183MDApKTtcbiAgfVxufVxuRXhwcmVzc2lvbi5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZVlpZWxkRXhwcmVzc2lvbiA9IGZ1bmN0aW9uICh0ZXJtXzcwMSwgc3RhdGVfNzAyKSB7XG4gIHJldHVybiBuZXcgWWllbGRFeHByZXNzaW9uKHN0YXRlXzcwMik7XG59O1xuZXhwb3J0IHtZaWVsZEV4cHJlc3Npb24gYXMgWWllbGRFeHByZXNzaW9ufTtcbmNsYXNzIFlpZWxkR2VuZXJhdG9yRXhwcmVzc2lvbiBleHRlbmRzIEV4cHJlc3Npb24ge1xuICBjb25zdHJ1Y3RvcihhdHRyc183MDMsIHR5cGVfNzA0KSB7XG4gICAgc3VwZXIoYXR0cnNfNzAzLCB0eXBlXzcwNCB8fCBcIllpZWxkR2VuZXJhdG9yRXhwcmVzc2lvblwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNzAzLCBcImV4cHJlc3Npb25cIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiZXhwcmVzc2lvblwiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfNzA1LCBzdGF0ZV83MDYgPSB7fSkge1xuICAgIHN0YXRlXzcwNi5leHByZXNzaW9uID0gdGhpcy5leHByZXNzaW9uIGluc3RhbmNlb2YgRXhwcmVzc2lvbiA/IHRoaXMuZXhwcmVzc2lvbi5yZWR1Y2UocmVkdWNlcl83MDUpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5leHByZXNzaW9uKSk7XG4gICAgfS5jYWxsKHRoaXMpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNzA1LCBzdGF0ZV83MDYpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtleHByZXNzaW9uOiB0aGlzLmV4cHJlc3Npb259LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl83MDcpIHtcbiAgICBsZXQgc3RhdGVfNzA4ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl83MDcpO1xuICAgIHJldHVybiByZWR1Y2VyXzcwNy5yZWR1Y2VZaWVsZEdlbmVyYXRvckV4cHJlc3Npb24odGhpcywgc3RhdGVfNzA4KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfNzA5KSB7XG4gICAgcmV0dXJuIG5ldyBZaWVsZEdlbmVyYXRvckV4cHJlc3Npb24oT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzcwOSkpO1xuICB9XG59XG5FeHByZXNzaW9uLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlWWllbGRHZW5lcmF0b3JFeHByZXNzaW9uID0gZnVuY3Rpb24gKHRlcm1fNzEwLCBzdGF0ZV83MTEpIHtcbiAgcmV0dXJuIG5ldyBZaWVsZEdlbmVyYXRvckV4cHJlc3Npb24oc3RhdGVfNzExKTtcbn07XG5leHBvcnQge1lpZWxkR2VuZXJhdG9yRXhwcmVzc2lvbiBhcyBZaWVsZEdlbmVyYXRvckV4cHJlc3Npb259O1xuY2xhc3MgUGFyZW50aGVzaXplZEV4cHJlc3Npb24gZXh0ZW5kcyBFeHByZXNzaW9uIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfNzEyLCB0eXBlXzcxMykge1xuICAgIHN1cGVyKGF0dHJzXzcxMiwgdHlwZV83MTMgfHwgXCJQYXJlbnRoZXNpemVkRXhwcmVzc2lvblwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNzEyLCBcImlubmVyXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImlubmVyXCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl83MTQsIHN0YXRlXzcxNSA9IHt9KSB7XG4gICAgc3RhdGVfNzE1LmlubmVyID0gdGhpcy5pbm5lcjtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzcxNCwgc3RhdGVfNzE1KTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7aW5uZXI6IHRoaXMuaW5uZXJ9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl83MTYpIHtcbiAgICBsZXQgc3RhdGVfNzE3ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl83MTYpO1xuICAgIHJldHVybiByZWR1Y2VyXzcxNi5yZWR1Y2VQYXJlbnRoZXNpemVkRXhwcmVzc2lvbih0aGlzLCBzdGF0ZV83MTcpO1xuICB9XG4gIGV4dGVuZChhdHRyc183MTgpIHtcbiAgICByZXR1cm4gbmV3IFBhcmVudGhlc2l6ZWRFeHByZXNzaW9uKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc183MTgpKTtcbiAgfVxufVxuRXhwcmVzc2lvbi5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZVBhcmVudGhlc2l6ZWRFeHByZXNzaW9uID0gZnVuY3Rpb24gKHRlcm1fNzE5LCBzdGF0ZV83MjApIHtcbiAgcmV0dXJuIG5ldyBQYXJlbnRoZXNpemVkRXhwcmVzc2lvbihzdGF0ZV83MjApO1xufTtcbmV4cG9ydCB7UGFyZW50aGVzaXplZEV4cHJlc3Npb24gYXMgUGFyZW50aGVzaXplZEV4cHJlc3Npb259O1xuY2xhc3MgQmxvY2tTdGF0ZW1lbnQgZXh0ZW5kcyBTdGF0ZW1lbnQge1xuICBjb25zdHJ1Y3RvcihhdHRyc183MjEsIHR5cGVfNzIyKSB7XG4gICAgc3VwZXIoYXR0cnNfNzIxLCB0eXBlXzcyMiB8fCBcIkJsb2NrU3RhdGVtZW50XCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc183MjEsIFwiYmxvY2tcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiYmxvY2tcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzcyMywgc3RhdGVfNzI0ID0ge30pIHtcbiAgICBzdGF0ZV83MjQuYmxvY2sgPSB0aGlzLmJsb2NrIGluc3RhbmNlb2YgQmxvY2sgPyB0aGlzLmJsb2NrLnJlZHVjZShyZWR1Y2VyXzcyMykgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmJsb2NrKSk7XG4gICAgfS5jYWxsKHRoaXMpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNzIzLCBzdGF0ZV83MjQpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtibG9jazogdGhpcy5ibG9ja30sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzcyNSkge1xuICAgIGxldCBzdGF0ZV83MjYgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzcyNSk7XG4gICAgcmV0dXJuIHJlZHVjZXJfNzI1LnJlZHVjZUJsb2NrU3RhdGVtZW50KHRoaXMsIHN0YXRlXzcyNik7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzcyNykge1xuICAgIHJldHVybiBuZXcgQmxvY2tTdGF0ZW1lbnQoT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzcyNykpO1xuICB9XG59XG5TdGF0ZW1lbnQuQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VCbG9ja1N0YXRlbWVudCA9IGZ1bmN0aW9uICh0ZXJtXzcyOCwgc3RhdGVfNzI5KSB7XG4gIHJldHVybiBuZXcgQmxvY2tTdGF0ZW1lbnQoc3RhdGVfNzI5KTtcbn07XG5leHBvcnQge0Jsb2NrU3RhdGVtZW50IGFzIEJsb2NrU3RhdGVtZW50fTtcbmNsYXNzIEJyZWFrU3RhdGVtZW50IGV4dGVuZHMgU3RhdGVtZW50IHtcbiAgY29uc3RydWN0b3IoYXR0cnNfNzMwLCB0eXBlXzczMSkge1xuICAgIHN1cGVyKGF0dHJzXzczMCwgdHlwZV83MzEgfHwgXCJCcmVha1N0YXRlbWVudFwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNzMwLCBcImxhYmVsXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImxhYmVsXCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl83MzIsIHN0YXRlXzczMyA9IHt9KSB7XG4gICAgc3RhdGVfNzMzLmxhYmVsID0gdGhpcy5sYWJlbCA9PSBudWxsID8gbnVsbCA6IHRoaXMubGFiZWw7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl83MzIsIHN0YXRlXzczMyk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe2xhYmVsOiB0aGlzLmxhYmVsfSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfNzM0KSB7XG4gICAgbGV0IHN0YXRlXzczNSA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNzM0KTtcbiAgICByZXR1cm4gcmVkdWNlcl83MzQucmVkdWNlQnJlYWtTdGF0ZW1lbnQodGhpcywgc3RhdGVfNzM1KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfNzM2KSB7XG4gICAgcmV0dXJuIG5ldyBCcmVha1N0YXRlbWVudChPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfNzM2KSk7XG4gIH1cbn1cblN0YXRlbWVudC5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZUJyZWFrU3RhdGVtZW50ID0gZnVuY3Rpb24gKHRlcm1fNzM3LCBzdGF0ZV83MzgpIHtcbiAgcmV0dXJuIG5ldyBCcmVha1N0YXRlbWVudChzdGF0ZV83MzgpO1xufTtcbmV4cG9ydCB7QnJlYWtTdGF0ZW1lbnQgYXMgQnJlYWtTdGF0ZW1lbnR9O1xuY2xhc3MgQ29udGludWVTdGF0ZW1lbnQgZXh0ZW5kcyBTdGF0ZW1lbnQge1xuICBjb25zdHJ1Y3RvcihhdHRyc183MzksIHR5cGVfNzQwKSB7XG4gICAgc3VwZXIoYXR0cnNfNzM5LCB0eXBlXzc0MCB8fCBcIkNvbnRpbnVlU3RhdGVtZW50XCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc183MzksIFwibGFiZWxcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwibGFiZWxcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzc0MSwgc3RhdGVfNzQyID0ge30pIHtcbiAgICBzdGF0ZV83NDIubGFiZWwgPSB0aGlzLmxhYmVsID09IG51bGwgPyBudWxsIDogdGhpcy5sYWJlbDtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzc0MSwgc3RhdGVfNzQyKTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7bGFiZWw6IHRoaXMubGFiZWx9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl83NDMpIHtcbiAgICBsZXQgc3RhdGVfNzQ0ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl83NDMpO1xuICAgIHJldHVybiByZWR1Y2VyXzc0My5yZWR1Y2VDb250aW51ZVN0YXRlbWVudCh0aGlzLCBzdGF0ZV83NDQpO1xuICB9XG4gIGV4dGVuZChhdHRyc183NDUpIHtcbiAgICByZXR1cm4gbmV3IENvbnRpbnVlU3RhdGVtZW50KE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc183NDUpKTtcbiAgfVxufVxuU3RhdGVtZW50LkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlQ29udGludWVTdGF0ZW1lbnQgPSBmdW5jdGlvbiAodGVybV83NDYsIHN0YXRlXzc0Nykge1xuICByZXR1cm4gbmV3IENvbnRpbnVlU3RhdGVtZW50KHN0YXRlXzc0Nyk7XG59O1xuZXhwb3J0IHtDb250aW51ZVN0YXRlbWVudCBhcyBDb250aW51ZVN0YXRlbWVudH07XG5jbGFzcyBEZWJ1Z2dlclN0YXRlbWVudCBleHRlbmRzIFN0YXRlbWVudCB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzc0OCwgdHlwZV83NDkpIHtcbiAgICBzdXBlcihhdHRyc183NDgsIHR5cGVfNzQ5IHx8IFwiRGVidWdnZXJTdGF0ZW1lbnRcIik7XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfNzUwLCBzdGF0ZV83NTEgPSB7fSkge1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNzUwLCBzdGF0ZV83NTEpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl83NTIpIHtcbiAgICBsZXQgc3RhdGVfNzUzID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl83NTIpO1xuICAgIHJldHVybiByZWR1Y2VyXzc1Mi5yZWR1Y2VEZWJ1Z2dlclN0YXRlbWVudCh0aGlzLCBzdGF0ZV83NTMpO1xuICB9XG4gIGV4dGVuZChhdHRyc183NTQpIHtcbiAgICByZXR1cm4gbmV3IERlYnVnZ2VyU3RhdGVtZW50KE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc183NTQpKTtcbiAgfVxufVxuU3RhdGVtZW50LkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlRGVidWdnZXJTdGF0ZW1lbnQgPSBmdW5jdGlvbiAodGVybV83NTUsIHN0YXRlXzc1Nikge1xuICByZXR1cm4gbmV3IERlYnVnZ2VyU3RhdGVtZW50KHN0YXRlXzc1Nik7XG59O1xuZXhwb3J0IHtEZWJ1Z2dlclN0YXRlbWVudCBhcyBEZWJ1Z2dlclN0YXRlbWVudH07XG5jbGFzcyBEb1doaWxlU3RhdGVtZW50IGV4dGVuZHMgSXRlcmF0aW9uU3RhdGVtZW50IHtcbiAgY29uc3RydWN0b3IoYXR0cnNfNzU3LCB0eXBlXzc1OCkge1xuICAgIHN1cGVyKGF0dHJzXzc1NywgdHlwZV83NTggfHwgXCJEb1doaWxlU3RhdGVtZW50XCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc183NTcsIFwidGVzdFwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJ0ZXN0XCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl83NTksIHN0YXRlXzc2MCA9IHt9KSB7XG4gICAgc3RhdGVfNzYwLnRlc3QgPSB0aGlzLnRlc3QgaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gdGhpcy50ZXN0LnJlZHVjZShyZWR1Y2VyXzc1OSkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLnRlc3QpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl83NTksIHN0YXRlXzc2MCk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe3Rlc3Q6IHRoaXMudGVzdH0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzc2MSkge1xuICAgIGxldCBzdGF0ZV83NjIgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzc2MSk7XG4gICAgcmV0dXJuIHJlZHVjZXJfNzYxLnJlZHVjZURvV2hpbGVTdGF0ZW1lbnQodGhpcywgc3RhdGVfNzYyKTtcbiAgfVxuICBleHRlbmQoYXR0cnNfNzYzKSB7XG4gICAgcmV0dXJuIG5ldyBEb1doaWxlU3RhdGVtZW50KE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc183NjMpKTtcbiAgfVxufVxuSXRlcmF0aW9uU3RhdGVtZW50LkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlRG9XaGlsZVN0YXRlbWVudCA9IGZ1bmN0aW9uICh0ZXJtXzc2NCwgc3RhdGVfNzY1KSB7XG4gIHJldHVybiBuZXcgRG9XaGlsZVN0YXRlbWVudChzdGF0ZV83NjUpO1xufTtcbmV4cG9ydCB7RG9XaGlsZVN0YXRlbWVudCBhcyBEb1doaWxlU3RhdGVtZW50fTtcbmNsYXNzIEVtcHR5U3RhdGVtZW50IGV4dGVuZHMgU3RhdGVtZW50IHtcbiAgY29uc3RydWN0b3IoYXR0cnNfNzY2LCB0eXBlXzc2Nykge1xuICAgIHN1cGVyKGF0dHJzXzc2NiwgdHlwZV83NjcgfHwgXCJFbXB0eVN0YXRlbWVudFwiKTtcbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl83NjgsIHN0YXRlXzc2OSA9IHt9KSB7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl83NjgsIHN0YXRlXzc2OSk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzc3MCkge1xuICAgIGxldCBzdGF0ZV83NzEgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzc3MCk7XG4gICAgcmV0dXJuIHJlZHVjZXJfNzcwLnJlZHVjZUVtcHR5U3RhdGVtZW50KHRoaXMsIHN0YXRlXzc3MSk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzc3Mikge1xuICAgIHJldHVybiBuZXcgRW1wdHlTdGF0ZW1lbnQoT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzc3MikpO1xuICB9XG59XG5TdGF0ZW1lbnQuQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VFbXB0eVN0YXRlbWVudCA9IGZ1bmN0aW9uICh0ZXJtXzc3Mywgc3RhdGVfNzc0KSB7XG4gIHJldHVybiBuZXcgRW1wdHlTdGF0ZW1lbnQoc3RhdGVfNzc0KTtcbn07XG5leHBvcnQge0VtcHR5U3RhdGVtZW50IGFzIEVtcHR5U3RhdGVtZW50fTtcbmNsYXNzIEV4cHJlc3Npb25TdGF0ZW1lbnQgZXh0ZW5kcyBTdGF0ZW1lbnQge1xuICBjb25zdHJ1Y3RvcihhdHRyc183NzUsIHR5cGVfNzc2KSB7XG4gICAgc3VwZXIoYXR0cnNfNzc1LCB0eXBlXzc3NiB8fCBcIkV4cHJlc3Npb25TdGF0ZW1lbnRcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzc3NSwgXCJleHByZXNzaW9uXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImV4cHJlc3Npb25cIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzc3Nywgc3RhdGVfNzc4ID0ge30pIHtcbiAgICBzdGF0ZV83NzguZXhwcmVzc2lvbiA9IHRoaXMuZXhwcmVzc2lvbiBpbnN0YW5jZW9mIEV4cHJlc3Npb24gPyB0aGlzLmV4cHJlc3Npb24ucmVkdWNlKHJlZHVjZXJfNzc3KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMuZXhwcmVzc2lvbikpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzc3Nywgc3RhdGVfNzc4KTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7ZXhwcmVzc2lvbjogdGhpcy5leHByZXNzaW9ufSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfNzc5KSB7XG4gICAgbGV0IHN0YXRlXzc4MCA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNzc5KTtcbiAgICByZXR1cm4gcmVkdWNlcl83NzkucmVkdWNlRXhwcmVzc2lvblN0YXRlbWVudCh0aGlzLCBzdGF0ZV83ODApO1xuICB9XG4gIGV4dGVuZChhdHRyc183ODEpIHtcbiAgICByZXR1cm4gbmV3IEV4cHJlc3Npb25TdGF0ZW1lbnQoT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzc4MSkpO1xuICB9XG59XG5TdGF0ZW1lbnQuQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VFeHByZXNzaW9uU3RhdGVtZW50ID0gZnVuY3Rpb24gKHRlcm1fNzgyLCBzdGF0ZV83ODMpIHtcbiAgcmV0dXJuIG5ldyBFeHByZXNzaW9uU3RhdGVtZW50KHN0YXRlXzc4Myk7XG59O1xuZXhwb3J0IHtFeHByZXNzaW9uU3RhdGVtZW50IGFzIEV4cHJlc3Npb25TdGF0ZW1lbnR9O1xuY2xhc3MgRm9ySW5TdGF0ZW1lbnQgZXh0ZW5kcyBJdGVyYXRpb25TdGF0ZW1lbnQge1xuICBjb25zdHJ1Y3RvcihhdHRyc183ODQsIHR5cGVfNzg1KSB7XG4gICAgc3VwZXIoYXR0cnNfNzg0LCB0eXBlXzc4NSB8fCBcIkZvckluU3RhdGVtZW50XCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc183ODQsIFwibGVmdFwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJsZWZ0XCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNzg0LCBcInJpZ2h0XCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcInJpZ2h0XCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl83ODYsIHN0YXRlXzc4NyA9IHt9KSB7XG4gICAgc3RhdGVfNzg3LmxlZnQgPSB0aGlzLmxlZnQgaW5zdGFuY2VvZiBWYXJpYWJsZURlY2xhcmF0aW9uID8gdGhpcy5sZWZ0LnJlZHVjZShyZWR1Y2VyXzc4NikgOiB0aGlzLmxlZnQgaW5zdGFuY2VvZiBPYmplY3RCaW5kaW5nID8gdGhpcy5sZWZ0LnJlZHVjZShyZWR1Y2VyXzc4NikgOiB0aGlzLmxlZnQgaW5zdGFuY2VvZiBBcnJheUJpbmRpbmcgPyB0aGlzLmxlZnQucmVkdWNlKHJlZHVjZXJfNzg2KSA6IHRoaXMubGVmdCBpbnN0YW5jZW9mIEJpbmRpbmdJZGVudGlmaWVyID8gdGhpcy5sZWZ0LnJlZHVjZShyZWR1Y2VyXzc4NikgOiB0aGlzLmxlZnQgaW5zdGFuY2VvZiBNZW1iZXJFeHByZXNzaW9uID8gdGhpcy5sZWZ0LnJlZHVjZShyZWR1Y2VyXzc4NikgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmxlZnQpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfNzg3LnJpZ2h0ID0gdGhpcy5yaWdodCBpbnN0YW5jZW9mIEV4cHJlc3Npb24gPyB0aGlzLnJpZ2h0LnJlZHVjZShyZWR1Y2VyXzc4NikgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLnJpZ2h0KSk7XG4gICAgfS5jYWxsKHRoaXMpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNzg2LCBzdGF0ZV83ODcpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtsZWZ0OiB0aGlzLmxlZnQsIHJpZ2h0OiB0aGlzLnJpZ2h0fSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfNzg4KSB7XG4gICAgbGV0IHN0YXRlXzc4OSA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNzg4KTtcbiAgICByZXR1cm4gcmVkdWNlcl83ODgucmVkdWNlRm9ySW5TdGF0ZW1lbnQodGhpcywgc3RhdGVfNzg5KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfNzkwKSB7XG4gICAgcmV0dXJuIG5ldyBGb3JJblN0YXRlbWVudChPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfNzkwKSk7XG4gIH1cbn1cbkl0ZXJhdGlvblN0YXRlbWVudC5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZUZvckluU3RhdGVtZW50ID0gZnVuY3Rpb24gKHRlcm1fNzkxLCBzdGF0ZV83OTIpIHtcbiAgcmV0dXJuIG5ldyBGb3JJblN0YXRlbWVudChzdGF0ZV83OTIpO1xufTtcbmV4cG9ydCB7Rm9ySW5TdGF0ZW1lbnQgYXMgRm9ySW5TdGF0ZW1lbnR9O1xuY2xhc3MgRm9yT2ZTdGF0ZW1lbnQgZXh0ZW5kcyBJdGVyYXRpb25TdGF0ZW1lbnQge1xuICBjb25zdHJ1Y3RvcihhdHRyc183OTMsIHR5cGVfNzk0KSB7XG4gICAgc3VwZXIoYXR0cnNfNzkzLCB0eXBlXzc5NCB8fCBcIkZvck9mU3RhdGVtZW50XCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc183OTMsIFwibGVmdFwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJsZWZ0XCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfNzkzLCBcInJpZ2h0XCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcInJpZ2h0XCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl83OTUsIHN0YXRlXzc5NiA9IHt9KSB7XG4gICAgc3RhdGVfNzk2LmxlZnQgPSB0aGlzLmxlZnQgaW5zdGFuY2VvZiBWYXJpYWJsZURlY2xhcmF0aW9uID8gdGhpcy5sZWZ0LnJlZHVjZShyZWR1Y2VyXzc5NSkgOiB0aGlzLmxlZnQgaW5zdGFuY2VvZiBPYmplY3RCaW5kaW5nID8gdGhpcy5sZWZ0LnJlZHVjZShyZWR1Y2VyXzc5NSkgOiB0aGlzLmxlZnQgaW5zdGFuY2VvZiBBcnJheUJpbmRpbmcgPyB0aGlzLmxlZnQucmVkdWNlKHJlZHVjZXJfNzk1KSA6IHRoaXMubGVmdCBpbnN0YW5jZW9mIEJpbmRpbmdJZGVudGlmaWVyID8gdGhpcy5sZWZ0LnJlZHVjZShyZWR1Y2VyXzc5NSkgOiB0aGlzLmxlZnQgaW5zdGFuY2VvZiBNZW1iZXJFeHByZXNzaW9uID8gdGhpcy5sZWZ0LnJlZHVjZShyZWR1Y2VyXzc5NSkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmxlZnQpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfNzk2LnJpZ2h0ID0gdGhpcy5yaWdodCBpbnN0YW5jZW9mIEV4cHJlc3Npb24gPyB0aGlzLnJpZ2h0LnJlZHVjZShyZWR1Y2VyXzc5NSkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLnJpZ2h0KSk7XG4gICAgfS5jYWxsKHRoaXMpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNzk1LCBzdGF0ZV83OTYpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtsZWZ0OiB0aGlzLmxlZnQsIHJpZ2h0OiB0aGlzLnJpZ2h0fSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfNzk3KSB7XG4gICAgbGV0IHN0YXRlXzc5OCA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfNzk3KTtcbiAgICByZXR1cm4gcmVkdWNlcl83OTcucmVkdWNlRm9yT2ZTdGF0ZW1lbnQodGhpcywgc3RhdGVfNzk4KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfNzk5KSB7XG4gICAgcmV0dXJuIG5ldyBGb3JPZlN0YXRlbWVudChPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfNzk5KSk7XG4gIH1cbn1cbkl0ZXJhdGlvblN0YXRlbWVudC5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZUZvck9mU3RhdGVtZW50ID0gZnVuY3Rpb24gKHRlcm1fODAwLCBzdGF0ZV84MDEpIHtcbiAgcmV0dXJuIG5ldyBGb3JPZlN0YXRlbWVudChzdGF0ZV84MDEpO1xufTtcbmV4cG9ydCB7Rm9yT2ZTdGF0ZW1lbnQgYXMgRm9yT2ZTdGF0ZW1lbnR9O1xuY2xhc3MgRm9yU3RhdGVtZW50IGV4dGVuZHMgSXRlcmF0aW9uU3RhdGVtZW50IHtcbiAgY29uc3RydWN0b3IoYXR0cnNfODAyLCB0eXBlXzgwMykge1xuICAgIHN1cGVyKGF0dHJzXzgwMiwgdHlwZV84MDMgfHwgXCJGb3JTdGF0ZW1lbnRcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzgwMiwgXCJpbml0XCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImluaXRcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc184MDIsIFwidGVzdFwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJ0ZXN0XCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfODAyLCBcInVwZGF0ZVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJ1cGRhdGVcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzgwNCwgc3RhdGVfODA1ID0ge30pIHtcbiAgICBzdGF0ZV84MDUuaW5pdCA9IHRoaXMuaW5pdCA9PSBudWxsID8gbnVsbCA6IHRoaXMuaW5pdCBpbnN0YW5jZW9mIFZhcmlhYmxlRGVjbGFyYXRpb24gPyB0aGlzLmluaXQucmVkdWNlKHJlZHVjZXJfODA0KSA6IHRoaXMuaW5pdCBpbnN0YW5jZW9mIEV4cHJlc3Npb24gPyB0aGlzLmluaXQucmVkdWNlKHJlZHVjZXJfODA0KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMuaW5pdCkpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICBzdGF0ZV84MDUudGVzdCA9IHRoaXMudGVzdCA9PSBudWxsID8gbnVsbCA6IHRoaXMudGVzdCBpbnN0YW5jZW9mIEV4cHJlc3Npb24gPyB0aGlzLnRlc3QucmVkdWNlKHJlZHVjZXJfODA0KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMudGVzdCkpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICBzdGF0ZV84MDUudXBkYXRlID0gdGhpcy51cGRhdGUgPT0gbnVsbCA/IG51bGwgOiB0aGlzLnVwZGF0ZSBpbnN0YW5jZW9mIEV4cHJlc3Npb24gPyB0aGlzLnVwZGF0ZS5yZWR1Y2UocmVkdWNlcl84MDQpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy51cGRhdGUpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl84MDQsIHN0YXRlXzgwNSk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe2luaXQ6IHRoaXMuaW5pdCwgdGVzdDogdGhpcy50ZXN0LCB1cGRhdGU6IHRoaXMudXBkYXRlfSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfODA2KSB7XG4gICAgbGV0IHN0YXRlXzgwNyA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfODA2KTtcbiAgICByZXR1cm4gcmVkdWNlcl84MDYucmVkdWNlRm9yU3RhdGVtZW50KHRoaXMsIHN0YXRlXzgwNyk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzgwOCkge1xuICAgIHJldHVybiBuZXcgRm9yU3RhdGVtZW50KE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc184MDgpKTtcbiAgfVxufVxuSXRlcmF0aW9uU3RhdGVtZW50LkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlRm9yU3RhdGVtZW50ID0gZnVuY3Rpb24gKHRlcm1fODA5LCBzdGF0ZV84MTApIHtcbiAgcmV0dXJuIG5ldyBGb3JTdGF0ZW1lbnQoc3RhdGVfODEwKTtcbn07XG5leHBvcnQge0ZvclN0YXRlbWVudCBhcyBGb3JTdGF0ZW1lbnR9O1xuY2xhc3MgSWZTdGF0ZW1lbnQgZXh0ZW5kcyBTdGF0ZW1lbnQge1xuICBjb25zdHJ1Y3RvcihhdHRyc184MTEsIHR5cGVfODEyKSB7XG4gICAgc3VwZXIoYXR0cnNfODExLCB0eXBlXzgxMiB8fCBcIklmU3RhdGVtZW50XCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc184MTEsIFwidGVzdFwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJ0ZXN0XCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfODExLCBcImNvbnNlcXVlbnRcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiY29uc2VxdWVudFwiKTtcbiAgICB9XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzgxMSwgXCJhbHRlcm5hdGVcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiYWx0ZXJuYXRlXCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl84MTMsIHN0YXRlXzgxNCA9IHt9KSB7XG4gICAgc3RhdGVfODE0LnRlc3QgPSB0aGlzLnRlc3QgaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gdGhpcy50ZXN0LnJlZHVjZShyZWR1Y2VyXzgxMykgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLnRlc3QpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfODE0LmNvbnNlcXVlbnQgPSB0aGlzLmNvbnNlcXVlbnQgaW5zdGFuY2VvZiBTdGF0ZW1lbnQgPyB0aGlzLmNvbnNlcXVlbnQucmVkdWNlKHJlZHVjZXJfODEzKSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMuY29uc2VxdWVudCkpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICBzdGF0ZV84MTQuYWx0ZXJuYXRlID0gdGhpcy5hbHRlcm5hdGUgPT0gbnVsbCA/IG51bGwgOiB0aGlzLmFsdGVybmF0ZSBpbnN0YW5jZW9mIFN0YXRlbWVudCA/IHRoaXMuYWx0ZXJuYXRlLnJlZHVjZShyZWR1Y2VyXzgxMykgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmFsdGVybmF0ZSkpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzgxMywgc3RhdGVfODE0KTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7dGVzdDogdGhpcy50ZXN0LCBjb25zZXF1ZW50OiB0aGlzLmNvbnNlcXVlbnQsIGFsdGVybmF0ZTogdGhpcy5hbHRlcm5hdGV9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl84MTUpIHtcbiAgICBsZXQgc3RhdGVfODE2ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl84MTUpO1xuICAgIHJldHVybiByZWR1Y2VyXzgxNS5yZWR1Y2VJZlN0YXRlbWVudCh0aGlzLCBzdGF0ZV84MTYpO1xuICB9XG4gIGV4dGVuZChhdHRyc184MTcpIHtcbiAgICByZXR1cm4gbmV3IElmU3RhdGVtZW50KE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc184MTcpKTtcbiAgfVxufVxuU3RhdGVtZW50LkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlSWZTdGF0ZW1lbnQgPSBmdW5jdGlvbiAodGVybV84MTgsIHN0YXRlXzgxOSkge1xuICByZXR1cm4gbmV3IElmU3RhdGVtZW50KHN0YXRlXzgxOSk7XG59O1xuZXhwb3J0IHtJZlN0YXRlbWVudCBhcyBJZlN0YXRlbWVudH07XG5jbGFzcyBMYWJlbGVkU3RhdGVtZW50IGV4dGVuZHMgU3RhdGVtZW50IHtcbiAgY29uc3RydWN0b3IoYXR0cnNfODIwLCB0eXBlXzgyMSkge1xuICAgIHN1cGVyKGF0dHJzXzgyMCwgdHlwZV84MjEgfHwgXCJMYWJlbGVkU3RhdGVtZW50XCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc184MjAsIFwibGFiZWxcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwibGFiZWxcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc184MjAsIFwiYm9keVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJib2R5XCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl84MjIsIHN0YXRlXzgyMyA9IHt9KSB7XG4gICAgc3RhdGVfODIzLmxhYmVsID0gdGhpcy5sYWJlbDtcbiAgICBzdGF0ZV84MjMuYm9keSA9IHRoaXMuYm9keSBpbnN0YW5jZW9mIFN0YXRlbWVudCA/IHRoaXMuYm9keS5yZWR1Y2UocmVkdWNlcl84MjIpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5ib2R5KSk7XG4gICAgfS5jYWxsKHRoaXMpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfODIyLCBzdGF0ZV84MjMpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtsYWJlbDogdGhpcy5sYWJlbCwgYm9keTogdGhpcy5ib2R5fSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfODI0KSB7XG4gICAgbGV0IHN0YXRlXzgyNSA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfODI0KTtcbiAgICByZXR1cm4gcmVkdWNlcl84MjQucmVkdWNlTGFiZWxlZFN0YXRlbWVudCh0aGlzLCBzdGF0ZV84MjUpO1xuICB9XG4gIGV4dGVuZChhdHRyc184MjYpIHtcbiAgICByZXR1cm4gbmV3IExhYmVsZWRTdGF0ZW1lbnQoT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzgyNikpO1xuICB9XG59XG5TdGF0ZW1lbnQuQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VMYWJlbGVkU3RhdGVtZW50ID0gZnVuY3Rpb24gKHRlcm1fODI3LCBzdGF0ZV84MjgpIHtcbiAgcmV0dXJuIG5ldyBMYWJlbGVkU3RhdGVtZW50KHN0YXRlXzgyOCk7XG59O1xuZXhwb3J0IHtMYWJlbGVkU3RhdGVtZW50IGFzIExhYmVsZWRTdGF0ZW1lbnR9O1xuY2xhc3MgUmV0dXJuU3RhdGVtZW50IGV4dGVuZHMgU3RhdGVtZW50IHtcbiAgY29uc3RydWN0b3IoYXR0cnNfODI5LCB0eXBlXzgzMCkge1xuICAgIHN1cGVyKGF0dHJzXzgyOSwgdHlwZV84MzAgfHwgXCJSZXR1cm5TdGF0ZW1lbnRcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzgyOSwgXCJleHByZXNzaW9uXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImV4cHJlc3Npb25cIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzgzMSwgc3RhdGVfODMyID0ge30pIHtcbiAgICBzdGF0ZV84MzIuZXhwcmVzc2lvbiA9IHRoaXMuZXhwcmVzc2lvbiA9PSBudWxsID8gbnVsbCA6IHRoaXMuZXhwcmVzc2lvbiBpbnN0YW5jZW9mIEV4cHJlc3Npb24gPyB0aGlzLmV4cHJlc3Npb24ucmVkdWNlKHJlZHVjZXJfODMxKSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMuZXhwcmVzc2lvbikpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzgzMSwgc3RhdGVfODMyKTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7ZXhwcmVzc2lvbjogdGhpcy5leHByZXNzaW9ufSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfODMzKSB7XG4gICAgbGV0IHN0YXRlXzgzNCA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfODMzKTtcbiAgICByZXR1cm4gcmVkdWNlcl84MzMucmVkdWNlUmV0dXJuU3RhdGVtZW50KHRoaXMsIHN0YXRlXzgzNCk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzgzNSkge1xuICAgIHJldHVybiBuZXcgUmV0dXJuU3RhdGVtZW50KE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc184MzUpKTtcbiAgfVxufVxuU3RhdGVtZW50LkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlUmV0dXJuU3RhdGVtZW50ID0gZnVuY3Rpb24gKHRlcm1fODM2LCBzdGF0ZV84MzcpIHtcbiAgcmV0dXJuIG5ldyBSZXR1cm5TdGF0ZW1lbnQoc3RhdGVfODM3KTtcbn07XG5leHBvcnQge1JldHVyblN0YXRlbWVudCBhcyBSZXR1cm5TdGF0ZW1lbnR9O1xuY2xhc3MgU3dpdGNoU3RhdGVtZW50IGV4dGVuZHMgU3RhdGVtZW50IHtcbiAgY29uc3RydWN0b3IoYXR0cnNfODM4LCB0eXBlXzgzOSkge1xuICAgIHN1cGVyKGF0dHJzXzgzOCwgdHlwZV84MzkgfHwgXCJTd2l0Y2hTdGF0ZW1lbnRcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzgzOCwgXCJkaXNjcmltaW5hbnRcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiZGlzY3JpbWluYW50XCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfODM4LCBcImNhc2VzXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImNhc2VzXCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl84NDAsIHN0YXRlXzg0MSA9IHt9KSB7XG4gICAgc3RhdGVfODQxLmRpc2NyaW1pbmFudCA9IHRoaXMuZGlzY3JpbWluYW50IGluc3RhbmNlb2YgRXhwcmVzc2lvbiA/IHRoaXMuZGlzY3JpbWluYW50LnJlZHVjZShyZWR1Y2VyXzg0MCkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmRpc2NyaW1pbmFudCkpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICBzdGF0ZV84NDEuY2FzZXMgPSB0aGlzLmNhc2VzLm1hcChhXzg0MiA9PiBhXzg0MiBpbnN0YW5jZW9mIFN3aXRjaENhc2UgPyBhXzg0Mi5yZWR1Y2UocmVkdWNlcl84NDApIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkoYV84NDIpKTtcbiAgICB9LmNhbGwodGhpcykpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfODQwLCBzdGF0ZV84NDEpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtkaXNjcmltaW5hbnQ6IHRoaXMuZGlzY3JpbWluYW50LCBjYXNlczogdGhpcy5jYXNlc30sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzg0Mykge1xuICAgIGxldCBzdGF0ZV84NDQgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzg0Myk7XG4gICAgcmV0dXJuIHJlZHVjZXJfODQzLnJlZHVjZVN3aXRjaFN0YXRlbWVudCh0aGlzLCBzdGF0ZV84NDQpO1xuICB9XG4gIGV4dGVuZChhdHRyc184NDUpIHtcbiAgICByZXR1cm4gbmV3IFN3aXRjaFN0YXRlbWVudChPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfODQ1KSk7XG4gIH1cbn1cblN0YXRlbWVudC5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZVN3aXRjaFN0YXRlbWVudCA9IGZ1bmN0aW9uICh0ZXJtXzg0Niwgc3RhdGVfODQ3KSB7XG4gIHJldHVybiBuZXcgU3dpdGNoU3RhdGVtZW50KHN0YXRlXzg0Nyk7XG59O1xuZXhwb3J0IHtTd2l0Y2hTdGF0ZW1lbnQgYXMgU3dpdGNoU3RhdGVtZW50fTtcbmNsYXNzIFN3aXRjaFN0YXRlbWVudFdpdGhEZWZhdWx0IGV4dGVuZHMgU3RhdGVtZW50IHtcbiAgY29uc3RydWN0b3IoYXR0cnNfODQ4LCB0eXBlXzg0OSkge1xuICAgIHN1cGVyKGF0dHJzXzg0OCwgdHlwZV84NDkgfHwgXCJTd2l0Y2hTdGF0ZW1lbnRXaXRoRGVmYXVsdFwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfODQ4LCBcImRpc2NyaW1pbmFudFwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJkaXNjcmltaW5hbnRcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc184NDgsIFwicHJlRGVmYXVsdENhc2VzXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcInByZURlZmF1bHRDYXNlc1wiKTtcbiAgICB9XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzg0OCwgXCJkZWZhdWx0Q2FzZVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJkZWZhdWx0Q2FzZVwiKTtcbiAgICB9XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzg0OCwgXCJwb3N0RGVmYXVsdENhc2VzXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcInBvc3REZWZhdWx0Q2FzZXNcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzg1MCwgc3RhdGVfODUxID0ge30pIHtcbiAgICBzdGF0ZV84NTEuZGlzY3JpbWluYW50ID0gdGhpcy5kaXNjcmltaW5hbnQgaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gdGhpcy5kaXNjcmltaW5hbnQucmVkdWNlKHJlZHVjZXJfODUwKSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMuZGlzY3JpbWluYW50KSk7XG4gICAgfS5jYWxsKHRoaXMpO1xuICAgIHN0YXRlXzg1MS5wcmVEZWZhdWx0Q2FzZXMgPSB0aGlzLnByZURlZmF1bHRDYXNlcy5tYXAoYV84NTIgPT4gYV84NTIgaW5zdGFuY2VvZiBTd2l0Y2hDYXNlID8gYV84NTIucmVkdWNlKHJlZHVjZXJfODUwKSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KGFfODUyKSk7XG4gICAgfS5jYWxsKHRoaXMpKTtcbiAgICBzdGF0ZV84NTEuZGVmYXVsdENhc2UgPSB0aGlzLmRlZmF1bHRDYXNlIGluc3RhbmNlb2YgU3dpdGNoRGVmYXVsdCA/IHRoaXMuZGVmYXVsdENhc2UucmVkdWNlKHJlZHVjZXJfODUwKSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMuZGVmYXVsdENhc2UpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfODUxLnBvc3REZWZhdWx0Q2FzZXMgPSB0aGlzLnBvc3REZWZhdWx0Q2FzZXMubWFwKGFfODUzID0+IGFfODUzIGluc3RhbmNlb2YgU3dpdGNoQ2FzZSA/IGFfODUzLnJlZHVjZShyZWR1Y2VyXzg1MCkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeShhXzg1MykpO1xuICAgIH0uY2FsbCh0aGlzKSk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl84NTAsIHN0YXRlXzg1MSk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe2Rpc2NyaW1pbmFudDogdGhpcy5kaXNjcmltaW5hbnQsIHByZURlZmF1bHRDYXNlczogdGhpcy5wcmVEZWZhdWx0Q2FzZXMsIGRlZmF1bHRDYXNlOiB0aGlzLmRlZmF1bHRDYXNlLCBwb3N0RGVmYXVsdENhc2VzOiB0aGlzLnBvc3REZWZhdWx0Q2FzZXN9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl84NTQpIHtcbiAgICBsZXQgc3RhdGVfODU1ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl84NTQpO1xuICAgIHJldHVybiByZWR1Y2VyXzg1NC5yZWR1Y2VTd2l0Y2hTdGF0ZW1lbnRXaXRoRGVmYXVsdCh0aGlzLCBzdGF0ZV84NTUpO1xuICB9XG4gIGV4dGVuZChhdHRyc184NTYpIHtcbiAgICByZXR1cm4gbmV3IFN3aXRjaFN0YXRlbWVudFdpdGhEZWZhdWx0KE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc184NTYpKTtcbiAgfVxufVxuU3RhdGVtZW50LkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlU3dpdGNoU3RhdGVtZW50V2l0aERlZmF1bHQgPSBmdW5jdGlvbiAodGVybV84NTcsIHN0YXRlXzg1OCkge1xuICByZXR1cm4gbmV3IFN3aXRjaFN0YXRlbWVudFdpdGhEZWZhdWx0KHN0YXRlXzg1OCk7XG59O1xuZXhwb3J0IHtTd2l0Y2hTdGF0ZW1lbnRXaXRoRGVmYXVsdCBhcyBTd2l0Y2hTdGF0ZW1lbnRXaXRoRGVmYXVsdH07XG5jbGFzcyBUaHJvd1N0YXRlbWVudCBleHRlbmRzIFN0YXRlbWVudCB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzg1OSwgdHlwZV84NjApIHtcbiAgICBzdXBlcihhdHRyc184NTksIHR5cGVfODYwIHx8IFwiVGhyb3dTdGF0ZW1lbnRcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzg1OSwgXCJleHByZXNzaW9uXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImV4cHJlc3Npb25cIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzg2MSwgc3RhdGVfODYyID0ge30pIHtcbiAgICBzdGF0ZV84NjIuZXhwcmVzc2lvbiA9IHRoaXMuZXhwcmVzc2lvbiBpbnN0YW5jZW9mIEV4cHJlc3Npb24gPyB0aGlzLmV4cHJlc3Npb24ucmVkdWNlKHJlZHVjZXJfODYxKSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMuZXhwcmVzc2lvbikpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzg2MSwgc3RhdGVfODYyKTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7ZXhwcmVzc2lvbjogdGhpcy5leHByZXNzaW9ufSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfODYzKSB7XG4gICAgbGV0IHN0YXRlXzg2NCA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfODYzKTtcbiAgICByZXR1cm4gcmVkdWNlcl84NjMucmVkdWNlVGhyb3dTdGF0ZW1lbnQodGhpcywgc3RhdGVfODY0KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfODY1KSB7XG4gICAgcmV0dXJuIG5ldyBUaHJvd1N0YXRlbWVudChPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfODY1KSk7XG4gIH1cbn1cblN0YXRlbWVudC5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZVRocm93U3RhdGVtZW50ID0gZnVuY3Rpb24gKHRlcm1fODY2LCBzdGF0ZV84NjcpIHtcbiAgcmV0dXJuIG5ldyBUaHJvd1N0YXRlbWVudChzdGF0ZV84NjcpO1xufTtcbmV4cG9ydCB7VGhyb3dTdGF0ZW1lbnQgYXMgVGhyb3dTdGF0ZW1lbnR9O1xuY2xhc3MgVHJ5Q2F0Y2hTdGF0ZW1lbnQgZXh0ZW5kcyBTdGF0ZW1lbnQge1xuICBjb25zdHJ1Y3RvcihhdHRyc184NjgsIHR5cGVfODY5KSB7XG4gICAgc3VwZXIoYXR0cnNfODY4LCB0eXBlXzg2OSB8fCBcIlRyeUNhdGNoU3RhdGVtZW50XCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc184NjgsIFwiYm9keVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJib2R5XCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfODY4LCBcImNhdGNoQ2xhdXNlXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImNhdGNoQ2xhdXNlXCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl84NzAsIHN0YXRlXzg3MSA9IHt9KSB7XG4gICAgc3RhdGVfODcxLmJvZHkgPSB0aGlzLmJvZHkgaW5zdGFuY2VvZiBCbG9jayA/IHRoaXMuYm9keS5yZWR1Y2UocmVkdWNlcl84NzApIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5ib2R5KSk7XG4gICAgfS5jYWxsKHRoaXMpO1xuICAgIHN0YXRlXzg3MS5jYXRjaENsYXVzZSA9IHRoaXMuY2F0Y2hDbGF1c2UgaW5zdGFuY2VvZiBDYXRjaENsYXVzZSA/IHRoaXMuY2F0Y2hDbGF1c2UucmVkdWNlKHJlZHVjZXJfODcwKSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMuY2F0Y2hDbGF1c2UpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl84NzAsIHN0YXRlXzg3MSk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe2JvZHk6IHRoaXMuYm9keSwgY2F0Y2hDbGF1c2U6IHRoaXMuY2F0Y2hDbGF1c2V9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl84NzIpIHtcbiAgICBsZXQgc3RhdGVfODczID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl84NzIpO1xuICAgIHJldHVybiByZWR1Y2VyXzg3Mi5yZWR1Y2VUcnlDYXRjaFN0YXRlbWVudCh0aGlzLCBzdGF0ZV84NzMpO1xuICB9XG4gIGV4dGVuZChhdHRyc184NzQpIHtcbiAgICByZXR1cm4gbmV3IFRyeUNhdGNoU3RhdGVtZW50KE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc184NzQpKTtcbiAgfVxufVxuU3RhdGVtZW50LkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlVHJ5Q2F0Y2hTdGF0ZW1lbnQgPSBmdW5jdGlvbiAodGVybV84NzUsIHN0YXRlXzg3Nikge1xuICByZXR1cm4gbmV3IFRyeUNhdGNoU3RhdGVtZW50KHN0YXRlXzg3Nik7XG59O1xuZXhwb3J0IHtUcnlDYXRjaFN0YXRlbWVudCBhcyBUcnlDYXRjaFN0YXRlbWVudH07XG5jbGFzcyBUcnlGaW5hbGx5U3RhdGVtZW50IGV4dGVuZHMgU3RhdGVtZW50IHtcbiAgY29uc3RydWN0b3IoYXR0cnNfODc3LCB0eXBlXzg3OCkge1xuICAgIHN1cGVyKGF0dHJzXzg3NywgdHlwZV84NzggfHwgXCJUcnlGaW5hbGx5U3RhdGVtZW50XCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc184NzcsIFwiYm9keVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJib2R5XCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfODc3LCBcImNhdGNoQ2xhdXNlXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImNhdGNoQ2xhdXNlXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfODc3LCBcImZpbmFsaXplclwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJmaW5hbGl6ZXJcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzg3OSwgc3RhdGVfODgwID0ge30pIHtcbiAgICBzdGF0ZV84ODAuYm9keSA9IHRoaXMuYm9keSBpbnN0YW5jZW9mIEJsb2NrID8gdGhpcy5ib2R5LnJlZHVjZShyZWR1Y2VyXzg3OSkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmJvZHkpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfODgwLmNhdGNoQ2xhdXNlID0gdGhpcy5jYXRjaENsYXVzZSA9PSBudWxsID8gbnVsbCA6IHRoaXMuY2F0Y2hDbGF1c2UgaW5zdGFuY2VvZiBDYXRjaENsYXVzZSA/IHRoaXMuY2F0Y2hDbGF1c2UucmVkdWNlKHJlZHVjZXJfODc5KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMuY2F0Y2hDbGF1c2UpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfODgwLmZpbmFsaXplciA9IHRoaXMuZmluYWxpemVyIGluc3RhbmNlb2YgQmxvY2sgPyB0aGlzLmZpbmFsaXplci5yZWR1Y2UocmVkdWNlcl84NzkpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5maW5hbGl6ZXIpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl84NzksIHN0YXRlXzg4MCk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe2JvZHk6IHRoaXMuYm9keSwgY2F0Y2hDbGF1c2U6IHRoaXMuY2F0Y2hDbGF1c2UsIGZpbmFsaXplcjogdGhpcy5maW5hbGl6ZXJ9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl84ODEpIHtcbiAgICBsZXQgc3RhdGVfODgyID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl84ODEpO1xuICAgIHJldHVybiByZWR1Y2VyXzg4MS5yZWR1Y2VUcnlGaW5hbGx5U3RhdGVtZW50KHRoaXMsIHN0YXRlXzg4Mik7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzg4Mykge1xuICAgIHJldHVybiBuZXcgVHJ5RmluYWxseVN0YXRlbWVudChPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfODgzKSk7XG4gIH1cbn1cblN0YXRlbWVudC5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZVRyeUZpbmFsbHlTdGF0ZW1lbnQgPSBmdW5jdGlvbiAodGVybV84ODQsIHN0YXRlXzg4NSkge1xuICByZXR1cm4gbmV3IFRyeUZpbmFsbHlTdGF0ZW1lbnQoc3RhdGVfODg1KTtcbn07XG5leHBvcnQge1RyeUZpbmFsbHlTdGF0ZW1lbnQgYXMgVHJ5RmluYWxseVN0YXRlbWVudH07XG5jbGFzcyBWYXJpYWJsZURlY2xhcmF0aW9uU3RhdGVtZW50IGV4dGVuZHMgU3RhdGVtZW50IHtcbiAgY29uc3RydWN0b3IoYXR0cnNfODg2LCB0eXBlXzg4Nykge1xuICAgIHN1cGVyKGF0dHJzXzg4NiwgdHlwZV84ODcgfHwgXCJWYXJpYWJsZURlY2xhcmF0aW9uU3RhdGVtZW50XCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc184ODYsIFwiZGVjbGFyYXRpb25cIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiZGVjbGFyYXRpb25cIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzg4OCwgc3RhdGVfODg5ID0ge30pIHtcbiAgICBzdGF0ZV84ODkuZGVjbGFyYXRpb24gPSB0aGlzLmRlY2xhcmF0aW9uIGluc3RhbmNlb2YgVmFyaWFibGVEZWNsYXJhdGlvbiA/IHRoaXMuZGVjbGFyYXRpb24ucmVkdWNlKHJlZHVjZXJfODg4KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMuZGVjbGFyYXRpb24pKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl84ODgsIHN0YXRlXzg4OSk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe2RlY2xhcmF0aW9uOiB0aGlzLmRlY2xhcmF0aW9ufSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfODkwKSB7XG4gICAgbGV0IHN0YXRlXzg5MSA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfODkwKTtcbiAgICByZXR1cm4gcmVkdWNlcl84OTAucmVkdWNlVmFyaWFibGVEZWNsYXJhdGlvblN0YXRlbWVudCh0aGlzLCBzdGF0ZV84OTEpO1xuICB9XG4gIGV4dGVuZChhdHRyc184OTIpIHtcbiAgICByZXR1cm4gbmV3IFZhcmlhYmxlRGVjbGFyYXRpb25TdGF0ZW1lbnQoT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzg5MikpO1xuICB9XG59XG5TdGF0ZW1lbnQuQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VWYXJpYWJsZURlY2xhcmF0aW9uU3RhdGVtZW50ID0gZnVuY3Rpb24gKHRlcm1fODkzLCBzdGF0ZV84OTQpIHtcbiAgcmV0dXJuIG5ldyBWYXJpYWJsZURlY2xhcmF0aW9uU3RhdGVtZW50KHN0YXRlXzg5NCk7XG59O1xuZXhwb3J0IHtWYXJpYWJsZURlY2xhcmF0aW9uU3RhdGVtZW50IGFzIFZhcmlhYmxlRGVjbGFyYXRpb25TdGF0ZW1lbnR9O1xuY2xhc3MgV2l0aFN0YXRlbWVudCBleHRlbmRzIFN0YXRlbWVudCB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzg5NSwgdHlwZV84OTYpIHtcbiAgICBzdXBlcihhdHRyc184OTUsIHR5cGVfODk2IHx8IFwiV2l0aFN0YXRlbWVudFwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfODk1LCBcIm9iamVjdFwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJvYmplY3RcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc184OTUsIFwiYm9keVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJib2R5XCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl84OTcsIHN0YXRlXzg5OCA9IHt9KSB7XG4gICAgc3RhdGVfODk4Lm9iamVjdCA9IHRoaXMub2JqZWN0IGluc3RhbmNlb2YgRXhwcmVzc2lvbiA/IHRoaXMub2JqZWN0LnJlZHVjZShyZWR1Y2VyXzg5NykgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLm9iamVjdCkpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICBzdGF0ZV84OTguYm9keSA9IHRoaXMuYm9keSBpbnN0YW5jZW9mIFN0YXRlbWVudCA/IHRoaXMuYm9keS5yZWR1Y2UocmVkdWNlcl84OTcpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5ib2R5KSk7XG4gICAgfS5jYWxsKHRoaXMpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfODk3LCBzdGF0ZV84OTgpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtvYmplY3Q6IHRoaXMub2JqZWN0LCBib2R5OiB0aGlzLmJvZHl9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl84OTkpIHtcbiAgICBsZXQgc3RhdGVfOTAwID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl84OTkpO1xuICAgIHJldHVybiByZWR1Y2VyXzg5OS5yZWR1Y2VXaXRoU3RhdGVtZW50KHRoaXMsIHN0YXRlXzkwMCk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzkwMSkge1xuICAgIHJldHVybiBuZXcgV2l0aFN0YXRlbWVudChPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfOTAxKSk7XG4gIH1cbn1cblN0YXRlbWVudC5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZVdpdGhTdGF0ZW1lbnQgPSBmdW5jdGlvbiAodGVybV85MDIsIHN0YXRlXzkwMykge1xuICByZXR1cm4gbmV3IFdpdGhTdGF0ZW1lbnQoc3RhdGVfOTAzKTtcbn07XG5leHBvcnQge1dpdGhTdGF0ZW1lbnQgYXMgV2l0aFN0YXRlbWVudH07XG5jbGFzcyBXaGlsZVN0YXRlbWVudCBleHRlbmRzIEl0ZXJhdGlvblN0YXRlbWVudCB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzkwNCwgdHlwZV85MDUpIHtcbiAgICBzdXBlcihhdHRyc185MDQsIHR5cGVfOTA1IHx8IFwiV2hpbGVTdGF0ZW1lbnRcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzkwNCwgXCJ0ZXN0XCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcInRlc3RcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzkwNiwgc3RhdGVfOTA3ID0ge30pIHtcbiAgICBzdGF0ZV85MDcudGVzdCA9IHRoaXMudGVzdCBpbnN0YW5jZW9mIEV4cHJlc3Npb24gPyB0aGlzLnRlc3QucmVkdWNlKHJlZHVjZXJfOTA2KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMudGVzdCkpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzkwNiwgc3RhdGVfOTA3KTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7dGVzdDogdGhpcy50ZXN0fSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfOTA4KSB7XG4gICAgbGV0IHN0YXRlXzkwOSA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfOTA4KTtcbiAgICByZXR1cm4gcmVkdWNlcl85MDgucmVkdWNlV2hpbGVTdGF0ZW1lbnQodGhpcywgc3RhdGVfOTA5KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfOTEwKSB7XG4gICAgcmV0dXJuIG5ldyBXaGlsZVN0YXRlbWVudChPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfOTEwKSk7XG4gIH1cbn1cbkl0ZXJhdGlvblN0YXRlbWVudC5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZVdoaWxlU3RhdGVtZW50ID0gZnVuY3Rpb24gKHRlcm1fOTExLCBzdGF0ZV85MTIpIHtcbiAgcmV0dXJuIG5ldyBXaGlsZVN0YXRlbWVudChzdGF0ZV85MTIpO1xufTtcbmV4cG9ydCB7V2hpbGVTdGF0ZW1lbnQgYXMgV2hpbGVTdGF0ZW1lbnR9O1xuY2xhc3MgUHJhZ21hIGV4dGVuZHMgVGVybSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzkxMywgdHlwZV85MTQpIHtcbiAgICBzdXBlcihhdHRyc185MTMsIHR5cGVfOTE0IHx8IFwiUHJhZ21hXCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc185MTMsIFwia2luZFwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJraW5kXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfOTEzLCBcIml0ZW1zXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcIml0ZW1zXCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl85MTUsIHN0YXRlXzkxNiA9IHt9KSB7XG4gICAgc3RhdGVfOTE2LmtpbmQgPSB0aGlzLmtpbmQ7XG4gICAgc3RhdGVfOTE2Lml0ZW1zID0gdGhpcy5pdGVtcztcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzkxNSwgc3RhdGVfOTE2KTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7a2luZDogdGhpcy5raW5kLCBpdGVtczogdGhpcy5pdGVtc30sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzkxNykge1xuICAgIGxldCBzdGF0ZV85MTggPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzkxNyk7XG4gICAgcmV0dXJuIHJlZHVjZXJfOTE3LnJlZHVjZVByYWdtYSh0aGlzLCBzdGF0ZV85MTgpO1xuICB9XG4gIGV4dGVuZChhdHRyc185MTkpIHtcbiAgICByZXR1cm4gbmV3IFByYWdtYShPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfOTE5KSk7XG4gIH1cbn1cblRlcm0uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VQcmFnbWEgPSBmdW5jdGlvbiAodGVybV85MjAsIHN0YXRlXzkyMSkge1xuICByZXR1cm4gbmV3IFByYWdtYShzdGF0ZV85MjEpO1xufTtcbmV4cG9ydCB7UHJhZ21hIGFzIFByYWdtYX07XG5jbGFzcyBCbG9jayBleHRlbmRzIFRlcm0ge1xuICBjb25zdHJ1Y3RvcihhdHRyc185MjIsIHR5cGVfOTIzKSB7XG4gICAgc3VwZXIoYXR0cnNfOTIyLCB0eXBlXzkyMyB8fCBcIkJsb2NrXCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc185MjIsIFwic3RhdGVtZW50c1wiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJzdGF0ZW1lbnRzXCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl85MjQsIHN0YXRlXzkyNSA9IHt9KSB7XG4gICAgc3RhdGVfOTI1LnN0YXRlbWVudHMgPSB0aGlzLnN0YXRlbWVudHMubWFwKGFfOTI2ID0+IGFfOTI2IGluc3RhbmNlb2YgU3RhdGVtZW50ID8gYV85MjYucmVkdWNlKHJlZHVjZXJfOTI0KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KGFfOTI2KSk7XG4gICAgfS5jYWxsKHRoaXMpKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzkyNCwgc3RhdGVfOTI1KTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7c3RhdGVtZW50czogdGhpcy5zdGF0ZW1lbnRzfSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfOTI3KSB7XG4gICAgbGV0IHN0YXRlXzkyOCA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfOTI3KTtcbiAgICByZXR1cm4gcmVkdWNlcl85MjcucmVkdWNlQmxvY2sodGhpcywgc3RhdGVfOTI4KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfOTI5KSB7XG4gICAgcmV0dXJuIG5ldyBCbG9jayhPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfOTI5KSk7XG4gIH1cbn1cblRlcm0uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VCbG9jayA9IGZ1bmN0aW9uICh0ZXJtXzkzMCwgc3RhdGVfOTMxKSB7XG4gIHJldHVybiBuZXcgQmxvY2soc3RhdGVfOTMxKTtcbn07XG5leHBvcnQge0Jsb2NrIGFzIEJsb2NrfTtcbmNsYXNzIENhdGNoQ2xhdXNlIGV4dGVuZHMgVGVybSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzkzMiwgdHlwZV85MzMpIHtcbiAgICBzdXBlcihhdHRyc185MzIsIHR5cGVfOTMzIHx8IFwiQ2F0Y2hDbGF1c2VcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzkzMiwgXCJiaW5kaW5nXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImJpbmRpbmdcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc185MzIsIFwiYm9keVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJib2R5XCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl85MzQsIHN0YXRlXzkzNSA9IHt9KSB7XG4gICAgc3RhdGVfOTM1LmJpbmRpbmcgPSB0aGlzLmJpbmRpbmcgaW5zdGFuY2VvZiBPYmplY3RCaW5kaW5nID8gdGhpcy5iaW5kaW5nLnJlZHVjZShyZWR1Y2VyXzkzNCkgOiB0aGlzLmJpbmRpbmcgaW5zdGFuY2VvZiBBcnJheUJpbmRpbmcgPyB0aGlzLmJpbmRpbmcucmVkdWNlKHJlZHVjZXJfOTM0KSA6IHRoaXMuYmluZGluZyBpbnN0YW5jZW9mIEJpbmRpbmdJZGVudGlmaWVyID8gdGhpcy5iaW5kaW5nLnJlZHVjZShyZWR1Y2VyXzkzNCkgOiB0aGlzLmJpbmRpbmcgaW5zdGFuY2VvZiBNZW1iZXJFeHByZXNzaW9uID8gdGhpcy5iaW5kaW5nLnJlZHVjZShyZWR1Y2VyXzkzNCkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmJpbmRpbmcpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfOTM1LmJvZHkgPSB0aGlzLmJvZHkgaW5zdGFuY2VvZiBCbG9jayA/IHRoaXMuYm9keS5yZWR1Y2UocmVkdWNlcl85MzQpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5ib2R5KSk7XG4gICAgfS5jYWxsKHRoaXMpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfOTM0LCBzdGF0ZV85MzUpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtiaW5kaW5nOiB0aGlzLmJpbmRpbmcsIGJvZHk6IHRoaXMuYm9keX0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzkzNikge1xuICAgIGxldCBzdGF0ZV85MzcgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzkzNik7XG4gICAgcmV0dXJuIHJlZHVjZXJfOTM2LnJlZHVjZUNhdGNoQ2xhdXNlKHRoaXMsIHN0YXRlXzkzNyk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzkzOCkge1xuICAgIHJldHVybiBuZXcgQ2F0Y2hDbGF1c2UoT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzkzOCkpO1xuICB9XG59XG5UZXJtLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlQ2F0Y2hDbGF1c2UgPSBmdW5jdGlvbiAodGVybV85MzksIHN0YXRlXzk0MCkge1xuICByZXR1cm4gbmV3IENhdGNoQ2xhdXNlKHN0YXRlXzk0MCk7XG59O1xuZXhwb3J0IHtDYXRjaENsYXVzZSBhcyBDYXRjaENsYXVzZX07XG5jbGFzcyBEaXJlY3RpdmUgZXh0ZW5kcyBUZXJtIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfOTQxLCB0eXBlXzk0Mikge1xuICAgIHN1cGVyKGF0dHJzXzk0MSwgdHlwZV85NDIgfHwgXCJEaXJlY3RpdmVcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzk0MSwgXCJyYXdWYWx1ZVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJyYXdWYWx1ZVwiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfOTQzLCBzdGF0ZV85NDQgPSB7fSkge1xuICAgIHN0YXRlXzk0NC5yYXdWYWx1ZSA9IHRoaXMucmF3VmFsdWU7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl85NDMsIHN0YXRlXzk0NCk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe3Jhd1ZhbHVlOiB0aGlzLnJhd1ZhbHVlfSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfOTQ1KSB7XG4gICAgbGV0IHN0YXRlXzk0NiA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfOTQ1KTtcbiAgICByZXR1cm4gcmVkdWNlcl85NDUucmVkdWNlRGlyZWN0aXZlKHRoaXMsIHN0YXRlXzk0Nik7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzk0Nykge1xuICAgIHJldHVybiBuZXcgRGlyZWN0aXZlKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc185NDcpKTtcbiAgfVxufVxuVGVybS5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZURpcmVjdGl2ZSA9IGZ1bmN0aW9uICh0ZXJtXzk0OCwgc3RhdGVfOTQ5KSB7XG4gIHJldHVybiBuZXcgRGlyZWN0aXZlKHN0YXRlXzk0OSk7XG59O1xuZXhwb3J0IHtEaXJlY3RpdmUgYXMgRGlyZWN0aXZlfTtcbmNsYXNzIEZvcm1hbFBhcmFtZXRlcnMgZXh0ZW5kcyBUZXJtIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfOTUwLCB0eXBlXzk1MSkge1xuICAgIHN1cGVyKGF0dHJzXzk1MCwgdHlwZV85NTEgfHwgXCJGb3JtYWxQYXJhbWV0ZXJzXCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc185NTAsIFwiaXRlbXNcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiaXRlbXNcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc185NTAsIFwicmVzdFwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJyZXN0XCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl85NTIsIHN0YXRlXzk1MyA9IHt9KSB7XG4gICAgc3RhdGVfOTUzLml0ZW1zID0gdGhpcy5pdGVtcy5tYXAoYV85NTQgPT4gYV85NTQgaW5zdGFuY2VvZiBPYmplY3RCaW5kaW5nID8gYV85NTQucmVkdWNlKHJlZHVjZXJfOTUyKSA6IGFfOTU0IGluc3RhbmNlb2YgQXJyYXlCaW5kaW5nID8gYV85NTQucmVkdWNlKHJlZHVjZXJfOTUyKSA6IGFfOTU0IGluc3RhbmNlb2YgQmluZGluZ0lkZW50aWZpZXIgPyBhXzk1NC5yZWR1Y2UocmVkdWNlcl85NTIpIDogYV85NTQgaW5zdGFuY2VvZiBNZW1iZXJFeHByZXNzaW9uID8gYV85NTQucmVkdWNlKHJlZHVjZXJfOTUyKSA6IGFfOTU0IGluc3RhbmNlb2YgQmluZGluZ1dpdGhEZWZhdWx0ID8gYV85NTQucmVkdWNlKHJlZHVjZXJfOTUyKSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KGFfOTU0KSk7XG4gICAgfS5jYWxsKHRoaXMpKTtcbiAgICBzdGF0ZV85NTMucmVzdCA9IHRoaXMucmVzdCA9PSBudWxsID8gbnVsbCA6IHRoaXMucmVzdCBpbnN0YW5jZW9mIEJpbmRpbmdJZGVudGlmaWVyID8gdGhpcy5yZXN0LnJlZHVjZShyZWR1Y2VyXzk1MikgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLnJlc3QpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl85NTIsIHN0YXRlXzk1Myk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe2l0ZW1zOiB0aGlzLml0ZW1zLCByZXN0OiB0aGlzLnJlc3R9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl85NTUpIHtcbiAgICBsZXQgc3RhdGVfOTU2ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl85NTUpO1xuICAgIHJldHVybiByZWR1Y2VyXzk1NS5yZWR1Y2VGb3JtYWxQYXJhbWV0ZXJzKHRoaXMsIHN0YXRlXzk1Nik7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzk1Nykge1xuICAgIHJldHVybiBuZXcgRm9ybWFsUGFyYW1ldGVycyhPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfOTU3KSk7XG4gIH1cbn1cblRlcm0uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VGb3JtYWxQYXJhbWV0ZXJzID0gZnVuY3Rpb24gKHRlcm1fOTU4LCBzdGF0ZV85NTkpIHtcbiAgcmV0dXJuIG5ldyBGb3JtYWxQYXJhbWV0ZXJzKHN0YXRlXzk1OSk7XG59O1xuZXhwb3J0IHtGb3JtYWxQYXJhbWV0ZXJzIGFzIEZvcm1hbFBhcmFtZXRlcnN9O1xuY2xhc3MgRnVuY3Rpb25Cb2R5IGV4dGVuZHMgVGVybSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzk2MCwgdHlwZV85NjEpIHtcbiAgICBzdXBlcihhdHRyc185NjAsIHR5cGVfOTYxIHx8IFwiRnVuY3Rpb25Cb2R5XCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc185NjAsIFwiZGlyZWN0aXZlc1wiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJkaXJlY3RpdmVzXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfOTYwLCBcInN0YXRlbWVudHNcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwic3RhdGVtZW50c1wiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfOTYyLCBzdGF0ZV85NjMgPSB7fSkge1xuICAgIHN0YXRlXzk2My5kaXJlY3RpdmVzID0gdGhpcy5kaXJlY3RpdmVzLm1hcChhXzk2NCA9PiBhXzk2NCk7XG4gICAgc3RhdGVfOTYzLnN0YXRlbWVudHMgPSB0aGlzLnN0YXRlbWVudHMubWFwKGFfOTY1ID0+IGFfOTY1IGluc3RhbmNlb2YgU3RhdGVtZW50ID8gYV85NjUucmVkdWNlKHJlZHVjZXJfOTYyKSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KGFfOTY1KSk7XG4gICAgfS5jYWxsKHRoaXMpKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzk2Miwgc3RhdGVfOTYzKTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7ZGlyZWN0aXZlczogdGhpcy5kaXJlY3RpdmVzLCBzdGF0ZW1lbnRzOiB0aGlzLnN0YXRlbWVudHN9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl85NjYpIHtcbiAgICBsZXQgc3RhdGVfOTY3ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl85NjYpO1xuICAgIHJldHVybiByZWR1Y2VyXzk2Ni5yZWR1Y2VGdW5jdGlvbkJvZHkodGhpcywgc3RhdGVfOTY3KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfOTY4KSB7XG4gICAgcmV0dXJuIG5ldyBGdW5jdGlvbkJvZHkoT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzk2OCkpO1xuICB9XG59XG5UZXJtLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlRnVuY3Rpb25Cb2R5ID0gZnVuY3Rpb24gKHRlcm1fOTY5LCBzdGF0ZV85NzApIHtcbiAgcmV0dXJuIG5ldyBGdW5jdGlvbkJvZHkoc3RhdGVfOTcwKTtcbn07XG5leHBvcnQge0Z1bmN0aW9uQm9keSBhcyBGdW5jdGlvbkJvZHl9O1xuY2xhc3MgRnVuY3Rpb25EZWNsYXJhdGlvbiBleHRlbmRzIFN0YXRlbWVudCB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzk3MSwgdHlwZV85NzIpIHtcbiAgICBzdXBlcihhdHRyc185NzEsIHR5cGVfOTcyIHx8IFwiRnVuY3Rpb25EZWNsYXJhdGlvblwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfOTcxLCBcIm5hbWVcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwibmFtZVwiKTtcbiAgICB9XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzk3MSwgXCJpc0dlbmVyYXRvclwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJpc0dlbmVyYXRvclwiKTtcbiAgICB9XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzk3MSwgXCJwYXJhbXNcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwicGFyYW1zXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfOTcxLCBcImJvZHlcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiYm9keVwiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfOTczLCBzdGF0ZV85NzQgPSB7fSkge1xuICAgIHN0YXRlXzk3NC5uYW1lID0gdGhpcy5uYW1lIGluc3RhbmNlb2YgQmluZGluZ0lkZW50aWZpZXIgPyB0aGlzLm5hbWUucmVkdWNlKHJlZHVjZXJfOTczKSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMubmFtZSkpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICBzdGF0ZV85NzQuaXNHZW5lcmF0b3IgPSB0aGlzLmlzR2VuZXJhdG9yO1xuICAgIHN0YXRlXzk3NC5wYXJhbXMgPSB0aGlzLnBhcmFtcyBpbnN0YW5jZW9mIEZvcm1hbFBhcmFtZXRlcnMgPyB0aGlzLnBhcmFtcy5yZWR1Y2UocmVkdWNlcl85NzMpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5wYXJhbXMpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfOTc0LmJvZHkgPSB0aGlzLmJvZHkgaW5zdGFuY2VvZiBGdW5jdGlvbkJvZHkgPyB0aGlzLmJvZHkucmVkdWNlKHJlZHVjZXJfOTczKSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMuYm9keSkpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzk3Mywgc3RhdGVfOTc0KTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7bmFtZTogdGhpcy5uYW1lLCBpc0dlbmVyYXRvcjogdGhpcy5pc0dlbmVyYXRvciwgcGFyYW1zOiB0aGlzLnBhcmFtcywgYm9keTogdGhpcy5ib2R5fSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfOTc1KSB7XG4gICAgbGV0IHN0YXRlXzk3NiA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfOTc1KTtcbiAgICByZXR1cm4gcmVkdWNlcl85NzUucmVkdWNlRnVuY3Rpb25EZWNsYXJhdGlvbih0aGlzLCBzdGF0ZV85NzYpO1xuICB9XG4gIGV4dGVuZChhdHRyc185NzcpIHtcbiAgICByZXR1cm4gbmV3IEZ1bmN0aW9uRGVjbGFyYXRpb24oT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzk3NykpO1xuICB9XG59XG5TdGF0ZW1lbnQuQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VGdW5jdGlvbkRlY2xhcmF0aW9uID0gZnVuY3Rpb24gKHRlcm1fOTc4LCBzdGF0ZV85NzkpIHtcbiAgcmV0dXJuIG5ldyBGdW5jdGlvbkRlY2xhcmF0aW9uKHN0YXRlXzk3OSk7XG59O1xuZXhwb3J0IHtGdW5jdGlvbkRlY2xhcmF0aW9uIGFzIEZ1bmN0aW9uRGVjbGFyYXRpb259O1xuY2xhc3MgRnVuY3Rpb25EZWNsYXJhdGlvbkUgZXh0ZW5kcyBTdGF0ZW1lbnQge1xuICBjb25zdHJ1Y3RvcihhdHRyc185ODAsIHR5cGVfOTgxKSB7XG4gICAgc3VwZXIoYXR0cnNfOTgwLCB0eXBlXzk4MSB8fCBcIkZ1bmN0aW9uRGVjbGFyYXRpb25FXCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc185ODAsIFwibmFtZVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJuYW1lXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfOTgwLCBcImlzR2VuZXJhdG9yXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImlzR2VuZXJhdG9yXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfOTgwLCBcInBhcmFtc1wiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJwYXJhbXNcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc185ODAsIFwiYm9keVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJib2R5XCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl85ODIsIHN0YXRlXzk4MyA9IHt9KSB7XG4gICAgc3RhdGVfOTgzLm5hbWUgPSB0aGlzLm5hbWUgaW5zdGFuY2VvZiBCaW5kaW5nSWRlbnRpZmllciA/IHRoaXMubmFtZS5yZWR1Y2UocmVkdWNlcl85ODIpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5uYW1lKSk7XG4gICAgfS5jYWxsKHRoaXMpO1xuICAgIHN0YXRlXzk4My5pc0dlbmVyYXRvciA9IHRoaXMuaXNHZW5lcmF0b3I7XG4gICAgc3RhdGVfOTgzLnBhcmFtcyA9IHRoaXMucGFyYW1zIGluc3RhbmNlb2YgRm9ybWFsUGFyYW1ldGVycyA/IHRoaXMucGFyYW1zLnJlZHVjZShyZWR1Y2VyXzk4MikgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLnBhcmFtcykpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICBzdGF0ZV85ODMuYm9keSA9IHRoaXMuYm9keS5tYXAoYV85ODQgPT4gYV85ODQgaW5zdGFuY2VvZiBUZXJtID8gYV85ODQucmVkdWNlKHJlZHVjZXJfOTgyKSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KGFfOTg0KSk7XG4gICAgfS5jYWxsKHRoaXMpKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzk4Miwgc3RhdGVfOTgzKTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7bmFtZTogdGhpcy5uYW1lLCBpc0dlbmVyYXRvcjogdGhpcy5pc0dlbmVyYXRvciwgcGFyYW1zOiB0aGlzLnBhcmFtcywgYm9keTogdGhpcy5ib2R5fSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfOTg1KSB7XG4gICAgbGV0IHN0YXRlXzk4NiA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfOTg1KTtcbiAgICByZXR1cm4gcmVkdWNlcl85ODUucmVkdWNlRnVuY3Rpb25EZWNsYXJhdGlvbkUodGhpcywgc3RhdGVfOTg2KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfOTg3KSB7XG4gICAgcmV0dXJuIG5ldyBGdW5jdGlvbkRlY2xhcmF0aW9uRShPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfOTg3KSk7XG4gIH1cbn1cblN0YXRlbWVudC5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZUZ1bmN0aW9uRGVjbGFyYXRpb25FID0gZnVuY3Rpb24gKHRlcm1fOTg4LCBzdGF0ZV85ODkpIHtcbiAgcmV0dXJuIG5ldyBGdW5jdGlvbkRlY2xhcmF0aW9uRShzdGF0ZV85ODkpO1xufTtcbmV4cG9ydCB7RnVuY3Rpb25EZWNsYXJhdGlvbkUgYXMgRnVuY3Rpb25EZWNsYXJhdGlvbkV9O1xuY2xhc3MgU2NyaXB0IGV4dGVuZHMgVGVybSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzk5MCwgdHlwZV85OTEpIHtcbiAgICBzdXBlcihhdHRyc185OTAsIHR5cGVfOTkxIHx8IFwiU2NyaXB0XCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc185OTAsIFwiZGlyZWN0aXZlc1wiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJkaXJlY3RpdmVzXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfOTkwLCBcInN0YXRlbWVudHNcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwic3RhdGVtZW50c1wiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfOTkyLCBzdGF0ZV85OTMgPSB7fSkge1xuICAgIHN0YXRlXzk5My5kaXJlY3RpdmVzID0gdGhpcy5kaXJlY3RpdmVzLm1hcChhXzk5NCA9PiBhXzk5NCk7XG4gICAgc3RhdGVfOTkzLnN0YXRlbWVudHMgPSB0aGlzLnN0YXRlbWVudHMubWFwKGFfOTk1ID0+IGFfOTk1IGluc3RhbmNlb2YgU3RhdGVtZW50ID8gYV85OTUucmVkdWNlKHJlZHVjZXJfOTkyKSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KGFfOTk1KSk7XG4gICAgfS5jYWxsKHRoaXMpKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzk5Miwgc3RhdGVfOTkzKTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7ZGlyZWN0aXZlczogdGhpcy5kaXJlY3RpdmVzLCBzdGF0ZW1lbnRzOiB0aGlzLnN0YXRlbWVudHN9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl85OTYpIHtcbiAgICBsZXQgc3RhdGVfOTk3ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl85OTYpO1xuICAgIHJldHVybiByZWR1Y2VyXzk5Ni5yZWR1Y2VTY3JpcHQodGhpcywgc3RhdGVfOTk3KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfOTk4KSB7XG4gICAgcmV0dXJuIG5ldyBTY3JpcHQoT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzk5OCkpO1xuICB9XG59XG5UZXJtLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlU2NyaXB0ID0gZnVuY3Rpb24gKHRlcm1fOTk5LCBzdGF0ZV8xMDAwKSB7XG4gIHJldHVybiBuZXcgU2NyaXB0KHN0YXRlXzEwMDApO1xufTtcbmV4cG9ydCB7U2NyaXB0IGFzIFNjcmlwdH07XG5jbGFzcyBTcHJlYWRFbGVtZW50IGV4dGVuZHMgVGVybSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzEwMDEsIHR5cGVfMTAwMikge1xuICAgIHN1cGVyKGF0dHJzXzEwMDEsIHR5cGVfMTAwMiB8fCBcIlNwcmVhZEVsZW1lbnRcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzEwMDEsIFwiZXhwcmVzc2lvblwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJleHByZXNzaW9uXCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl8xMDAzLCBzdGF0ZV8xMDA0ID0ge30pIHtcbiAgICBzdGF0ZV8xMDA0LmV4cHJlc3Npb24gPSB0aGlzLmV4cHJlc3Npb24gaW5zdGFuY2VvZiBFeHByZXNzaW9uID8gdGhpcy5leHByZXNzaW9uLnJlZHVjZShyZWR1Y2VyXzEwMDMpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy5leHByZXNzaW9uKSk7XG4gICAgfS5jYWxsKHRoaXMpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTAwMywgc3RhdGVfMTAwNCk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe2V4cHJlc3Npb246IHRoaXMuZXhwcmVzc2lvbn0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzEwMDUpIHtcbiAgICBsZXQgc3RhdGVfMTAwNiA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTAwNSk7XG4gICAgcmV0dXJuIHJlZHVjZXJfMTAwNS5yZWR1Y2VTcHJlYWRFbGVtZW50KHRoaXMsIHN0YXRlXzEwMDYpO1xuICB9XG4gIGV4dGVuZChhdHRyc18xMDA3KSB7XG4gICAgcmV0dXJuIG5ldyBTcHJlYWRFbGVtZW50KE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc18xMDA3KSk7XG4gIH1cbn1cblRlcm0uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VTcHJlYWRFbGVtZW50ID0gZnVuY3Rpb24gKHRlcm1fMTAwOCwgc3RhdGVfMTAwOSkge1xuICByZXR1cm4gbmV3IFNwcmVhZEVsZW1lbnQoc3RhdGVfMTAwOSk7XG59O1xuZXhwb3J0IHtTcHJlYWRFbGVtZW50IGFzIFNwcmVhZEVsZW1lbnR9O1xuY2xhc3MgU3VwZXIgZXh0ZW5kcyBUZXJtIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfMTAxMCwgdHlwZV8xMDExKSB7XG4gICAgc3VwZXIoYXR0cnNfMTAxMCwgdHlwZV8xMDExIHx8IFwiU3VwZXJcIik7XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTAxMiwgc3RhdGVfMTAxMyA9IHt9KSB7XG4gICAgO1xuICAgIHJldHVybiBzdXBlci5fcmVkdWNlU3RhdGUocmVkdWNlcl8xMDEyLCBzdGF0ZV8xMDEzKTtcbiAgfVxuICBfY2xvbmVBdHRycygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfMTAxNCkge1xuICAgIGxldCBzdGF0ZV8xMDE1ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl8xMDE0KTtcbiAgICByZXR1cm4gcmVkdWNlcl8xMDE0LnJlZHVjZVN1cGVyKHRoaXMsIHN0YXRlXzEwMTUpO1xuICB9XG4gIGV4dGVuZChhdHRyc18xMDE2KSB7XG4gICAgcmV0dXJuIG5ldyBTdXBlcihPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfMTAxNikpO1xuICB9XG59XG5UZXJtLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlU3VwZXIgPSBmdW5jdGlvbiAodGVybV8xMDE3LCBzdGF0ZV8xMDE4KSB7XG4gIHJldHVybiBuZXcgU3VwZXIoc3RhdGVfMTAxOCk7XG59O1xuZXhwb3J0IHtTdXBlciBhcyBTdXBlcn07XG5jbGFzcyBTd2l0Y2hDYXNlIGV4dGVuZHMgVGVybSB7XG4gIGNvbnN0cnVjdG9yKGF0dHJzXzEwMTksIHR5cGVfMTAyMCkge1xuICAgIHN1cGVyKGF0dHJzXzEwMTksIHR5cGVfMTAyMCB8fCBcIlN3aXRjaENhc2VcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzEwMTksIFwidGVzdFwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJ0ZXN0XCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfMTAxOSwgXCJjb25zZXF1ZW50XCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImNvbnNlcXVlbnRcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzEwMjEsIHN0YXRlXzEwMjIgPSB7fSkge1xuICAgIHN0YXRlXzEwMjIudGVzdCA9IHRoaXMudGVzdCBpbnN0YW5jZW9mIEV4cHJlc3Npb24gPyB0aGlzLnRlc3QucmVkdWNlKHJlZHVjZXJfMTAyMSkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLnRlc3QpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfMTAyMi5jb25zZXF1ZW50ID0gdGhpcy5jb25zZXF1ZW50Lm1hcChhXzEwMjMgPT4gYV8xMDIzIGluc3RhbmNlb2YgU3RhdGVtZW50ID8gYV8xMDIzLnJlZHVjZShyZWR1Y2VyXzEwMjEpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkoYV8xMDIzKSk7XG4gICAgfS5jYWxsKHRoaXMpKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzEwMjEsIHN0YXRlXzEwMjIpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt0ZXN0OiB0aGlzLnRlc3QsIGNvbnNlcXVlbnQ6IHRoaXMuY29uc2VxdWVudH0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzEwMjQpIHtcbiAgICBsZXQgc3RhdGVfMTAyNSA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTAyNCk7XG4gICAgcmV0dXJuIHJlZHVjZXJfMTAyNC5yZWR1Y2VTd2l0Y2hDYXNlKHRoaXMsIHN0YXRlXzEwMjUpO1xuICB9XG4gIGV4dGVuZChhdHRyc18xMDI2KSB7XG4gICAgcmV0dXJuIG5ldyBTd2l0Y2hDYXNlKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc18xMDI2KSk7XG4gIH1cbn1cblRlcm0uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VTd2l0Y2hDYXNlID0gZnVuY3Rpb24gKHRlcm1fMTAyNywgc3RhdGVfMTAyOCkge1xuICByZXR1cm4gbmV3IFN3aXRjaENhc2Uoc3RhdGVfMTAyOCk7XG59O1xuZXhwb3J0IHtTd2l0Y2hDYXNlIGFzIFN3aXRjaENhc2V9O1xuY2xhc3MgU3dpdGNoRGVmYXVsdCBleHRlbmRzIFRlcm0ge1xuICBjb25zdHJ1Y3RvcihhdHRyc18xMDI5LCB0eXBlXzEwMzApIHtcbiAgICBzdXBlcihhdHRyc18xMDI5LCB0eXBlXzEwMzAgfHwgXCJTd2l0Y2hEZWZhdWx0XCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc18xMDI5LCBcImNvbnNlcXVlbnRcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiY29uc2VxdWVudFwiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTAzMSwgc3RhdGVfMTAzMiA9IHt9KSB7XG4gICAgc3RhdGVfMTAzMi5jb25zZXF1ZW50ID0gdGhpcy5jb25zZXF1ZW50Lm1hcChhXzEwMzMgPT4gYV8xMDMzIGluc3RhbmNlb2YgU3RhdGVtZW50ID8gYV8xMDMzLnJlZHVjZShyZWR1Y2VyXzEwMzEpIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkoYV8xMDMzKSk7XG4gICAgfS5jYWxsKHRoaXMpKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzEwMzEsIHN0YXRlXzEwMzIpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtjb25zZXF1ZW50OiB0aGlzLmNvbnNlcXVlbnR9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl8xMDM0KSB7XG4gICAgbGV0IHN0YXRlXzEwMzUgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzEwMzQpO1xuICAgIHJldHVybiByZWR1Y2VyXzEwMzQucmVkdWNlU3dpdGNoRGVmYXVsdCh0aGlzLCBzdGF0ZV8xMDM1KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfMTAzNikge1xuICAgIHJldHVybiBuZXcgU3dpdGNoRGVmYXVsdChPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfMTAzNikpO1xuICB9XG59XG5UZXJtLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlU3dpdGNoRGVmYXVsdCA9IGZ1bmN0aW9uICh0ZXJtXzEwMzcsIHN0YXRlXzEwMzgpIHtcbiAgcmV0dXJuIG5ldyBTd2l0Y2hEZWZhdWx0KHN0YXRlXzEwMzgpO1xufTtcbmV4cG9ydCB7U3dpdGNoRGVmYXVsdCBhcyBTd2l0Y2hEZWZhdWx0fTtcbmNsYXNzIFRlbXBsYXRlRWxlbWVudCBleHRlbmRzIFRlcm0ge1xuICBjb25zdHJ1Y3RvcihhdHRyc18xMDM5LCB0eXBlXzEwNDApIHtcbiAgICBzdXBlcihhdHRyc18xMDM5LCB0eXBlXzEwNDAgfHwgXCJUZW1wbGF0ZUVsZW1lbnRcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzEwMzksIFwicmF3VmFsdWVcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwicmF3VmFsdWVcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzEwNDEsIHN0YXRlXzEwNDIgPSB7fSkge1xuICAgIHN0YXRlXzEwNDIucmF3VmFsdWUgPSB0aGlzLnJhd1ZhbHVlO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTA0MSwgc3RhdGVfMTA0Mik7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe3Jhd1ZhbHVlOiB0aGlzLnJhd1ZhbHVlfSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfMTA0Mykge1xuICAgIGxldCBzdGF0ZV8xMDQ0ID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl8xMDQzKTtcbiAgICByZXR1cm4gcmVkdWNlcl8xMDQzLnJlZHVjZVRlbXBsYXRlRWxlbWVudCh0aGlzLCBzdGF0ZV8xMDQ0KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfMTA0NSkge1xuICAgIHJldHVybiBuZXcgVGVtcGxhdGVFbGVtZW50KE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc18xMDQ1KSk7XG4gIH1cbn1cblRlcm0uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VUZW1wbGF0ZUVsZW1lbnQgPSBmdW5jdGlvbiAodGVybV8xMDQ2LCBzdGF0ZV8xMDQ3KSB7XG4gIHJldHVybiBuZXcgVGVtcGxhdGVFbGVtZW50KHN0YXRlXzEwNDcpO1xufTtcbmV4cG9ydCB7VGVtcGxhdGVFbGVtZW50IGFzIFRlbXBsYXRlRWxlbWVudH07XG5jbGFzcyBTeW50YXhUZW1wbGF0ZSBleHRlbmRzIEV4cHJlc3Npb24ge1xuICBjb25zdHJ1Y3RvcihhdHRyc18xMDQ4LCB0eXBlXzEwNDkpIHtcbiAgICBzdXBlcihhdHRyc18xMDQ4LCB0eXBlXzEwNDkgfHwgXCJTeW50YXhUZW1wbGF0ZVwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfMTA0OCwgXCJ0ZW1wbGF0ZVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJ0ZW1wbGF0ZVwiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTA1MCwgc3RhdGVfMTA1MSA9IHt9KSB7XG4gICAgc3RhdGVfMTA1MS50ZW1wbGF0ZSA9IHRoaXMudGVtcGxhdGUubWFwKGFfMTA1MiA9PiBhXzEwNTIgaW5zdGFuY2VvZiBTeW50YXhUZXJtID8gYV8xMDUyLnJlZHVjZShyZWR1Y2VyXzEwNTApIDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvYmplY3Q6IFwiICsgSlNPTi5zdHJpbmdpZnkoYV8xMDUyKSk7XG4gICAgfS5jYWxsKHRoaXMpKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzEwNTAsIHN0YXRlXzEwNTEpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt0ZW1wbGF0ZTogdGhpcy50ZW1wbGF0ZX0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzEwNTMpIHtcbiAgICBsZXQgc3RhdGVfMTA1NCA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTA1Myk7XG4gICAgcmV0dXJuIHJlZHVjZXJfMTA1My5yZWR1Y2VTeW50YXhUZW1wbGF0ZSh0aGlzLCBzdGF0ZV8xMDU0KTtcbiAgfVxuICBleHRlbmQoYXR0cnNfMTA1NSkge1xuICAgIHJldHVybiBuZXcgU3ludGF4VGVtcGxhdGUoT2JqZWN0LmFzc2lnbih0aGlzLl9jbG9uZUF0dHJzKCksIGF0dHJzXzEwNTUpKTtcbiAgfVxufVxuRXhwcmVzc2lvbi5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZVN5bnRheFRlbXBsYXRlID0gZnVuY3Rpb24gKHRlcm1fMTA1Niwgc3RhdGVfMTA1Nykge1xuICByZXR1cm4gbmV3IFN5bnRheFRlbXBsYXRlKHN0YXRlXzEwNTcpO1xufTtcbmV4cG9ydCB7U3ludGF4VGVtcGxhdGUgYXMgU3ludGF4VGVtcGxhdGV9O1xuY2xhc3MgU3ludGF4UXVvdGUgZXh0ZW5kcyBUZXJtIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfMTA1OCwgdHlwZV8xMDU5KSB7XG4gICAgc3VwZXIoYXR0cnNfMTA1OCwgdHlwZV8xMDU5IHx8IFwiU3ludGF4UXVvdGVcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzEwNTgsIFwibmFtZVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJuYW1lXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfMTA1OCwgXCJ0ZW1wbGF0ZVwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJ0ZW1wbGF0ZVwiKTtcbiAgICB9XG4gIH1cbiAgX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTA2MCwgc3RhdGVfMTA2MSA9IHt9KSB7XG4gICAgc3RhdGVfMTA2MS5uYW1lID0gdGhpcy5uYW1lO1xuICAgIHN0YXRlXzEwNjEudGVtcGxhdGUgPSB0aGlzLnRlbXBsYXRlO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTA2MCwgc3RhdGVfMTA2MSk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe25hbWU6IHRoaXMubmFtZSwgdGVtcGxhdGU6IHRoaXMudGVtcGxhdGV9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl8xMDYyKSB7XG4gICAgbGV0IHN0YXRlXzEwNjMgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzEwNjIpO1xuICAgIHJldHVybiByZWR1Y2VyXzEwNjIucmVkdWNlU3ludGF4UXVvdGUodGhpcywgc3RhdGVfMTA2Myk7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzEwNjQpIHtcbiAgICByZXR1cm4gbmV3IFN5bnRheFF1b3RlKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc18xMDY0KSk7XG4gIH1cbn1cblRlcm0uQ2xvbmVSZWR1Y2VyLnByb3RvdHlwZS5yZWR1Y2VTeW50YXhRdW90ZSA9IGZ1bmN0aW9uICh0ZXJtXzEwNjUsIHN0YXRlXzEwNjYpIHtcbiAgcmV0dXJuIG5ldyBTeW50YXhRdW90ZShzdGF0ZV8xMDY2KTtcbn07XG5leHBvcnQge1N5bnRheFF1b3RlIGFzIFN5bnRheFF1b3RlfTtcbmNsYXNzIFZhcmlhYmxlRGVjbGFyYXRpb24gZXh0ZW5kcyBUZXJtIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfMTA2NywgdHlwZV8xMDY4KSB7XG4gICAgc3VwZXIoYXR0cnNfMTA2NywgdHlwZV8xMDY4IHx8IFwiVmFyaWFibGVEZWNsYXJhdGlvblwiKTtcbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfMTA2NywgXCJraW5kXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImtpbmRcIik7XG4gICAgfVxuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc18xMDY3LCBcImRlY2xhcmF0b3JzXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImRlY2xhcmF0b3JzXCIpO1xuICAgIH1cbiAgfVxuICBfcmVkdWNlU3RhdGUocmVkdWNlcl8xMDY5LCBzdGF0ZV8xMDcwID0ge30pIHtcbiAgICBzdGF0ZV8xMDcwLmtpbmQgPSB0aGlzLmtpbmQ7XG4gICAgc3RhdGVfMTA3MC5kZWNsYXJhdG9ycyA9IHRoaXMuZGVjbGFyYXRvcnMubWFwKGFfMTA3MSA9PiBhXzEwNzEgaW5zdGFuY2VvZiBWYXJpYWJsZURlY2xhcmF0b3IgPyBhXzEwNzEucmVkdWNlKHJlZHVjZXJfMTA2OSkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeShhXzEwNzEpKTtcbiAgICB9LmNhbGwodGhpcykpO1xuICAgIDtcbiAgICByZXR1cm4gc3VwZXIuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTA2OSwgc3RhdGVfMTA3MCk7XG4gIH1cbiAgX2Nsb25lQXR0cnMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe2tpbmQ6IHRoaXMua2luZCwgZGVjbGFyYXRvcnM6IHRoaXMuZGVjbGFyYXRvcnN9LCBzdXBlci5fY2xvbmVBdHRycygpKTtcbiAgfVxuICByZWR1Y2UocmVkdWNlcl8xMDcyKSB7XG4gICAgbGV0IHN0YXRlXzEwNzMgPSB0aGlzLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzEwNzIpO1xuICAgIHJldHVybiByZWR1Y2VyXzEwNzIucmVkdWNlVmFyaWFibGVEZWNsYXJhdGlvbih0aGlzLCBzdGF0ZV8xMDczKTtcbiAgfVxuICBleHRlbmQoYXR0cnNfMTA3NCkge1xuICAgIHJldHVybiBuZXcgVmFyaWFibGVEZWNsYXJhdGlvbihPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfMTA3NCkpO1xuICB9XG59XG5UZXJtLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlVmFyaWFibGVEZWNsYXJhdGlvbiA9IGZ1bmN0aW9uICh0ZXJtXzEwNzUsIHN0YXRlXzEwNzYpIHtcbiAgcmV0dXJuIG5ldyBWYXJpYWJsZURlY2xhcmF0aW9uKHN0YXRlXzEwNzYpO1xufTtcbmV4cG9ydCB7VmFyaWFibGVEZWNsYXJhdGlvbiBhcyBWYXJpYWJsZURlY2xhcmF0aW9ufTtcbmNsYXNzIFZhcmlhYmxlRGVjbGFyYXRvciBleHRlbmRzIFRlcm0ge1xuICBjb25zdHJ1Y3RvcihhdHRyc18xMDc3LCB0eXBlXzEwNzgpIHtcbiAgICBzdXBlcihhdHRyc18xMDc3LCB0eXBlXzEwNzggfHwgXCJWYXJpYWJsZURlY2xhcmF0b3JcIik7XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzEwNzcsIFwiYmluZGluZ1wiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBhdHRyaWJ1dGU6IFwiICsgXCJiaW5kaW5nXCIpO1xuICAgIH1cbiAgICBpZiAoIXt9Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cnNfMTA3NywgXCJpbml0XCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGF0dHJpYnV0ZTogXCIgKyBcImluaXRcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzEwNzksIHN0YXRlXzEwODAgPSB7fSkge1xuICAgIHN0YXRlXzEwODAuYmluZGluZyA9IHRoaXMuYmluZGluZyBpbnN0YW5jZW9mIE9iamVjdEJpbmRpbmcgPyB0aGlzLmJpbmRpbmcucmVkdWNlKHJlZHVjZXJfMTA3OSkgOiB0aGlzLmJpbmRpbmcgaW5zdGFuY2VvZiBBcnJheUJpbmRpbmcgPyB0aGlzLmJpbmRpbmcucmVkdWNlKHJlZHVjZXJfMTA3OSkgOiB0aGlzLmJpbmRpbmcgaW5zdGFuY2VvZiBCaW5kaW5nSWRlbnRpZmllciA/IHRoaXMuYmluZGluZy5yZWR1Y2UocmVkdWNlcl8xMDc5KSA6IHRoaXMuYmluZGluZyBpbnN0YW5jZW9mIE1lbWJlckV4cHJlc3Npb24gPyB0aGlzLmJpbmRpbmcucmVkdWNlKHJlZHVjZXJfMTA3OSkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdDogXCIgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmJpbmRpbmcpKTtcbiAgICB9LmNhbGwodGhpcyk7XG4gICAgc3RhdGVfMTA4MC5pbml0ID0gdGhpcy5pbml0ID09IG51bGwgPyBudWxsIDogdGhpcy5pbml0IGluc3RhbmNlb2YgRXhwcmVzc2lvbiA/IHRoaXMuaW5pdC5yZWR1Y2UocmVkdWNlcl8xMDc5KSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gb2JqZWN0OiBcIiArIEpTT04uc3RyaW5naWZ5KHRoaXMuaW5pdCkpO1xuICAgIH0uY2FsbCh0aGlzKTtcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzEwNzksIHN0YXRlXzEwODApO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtiaW5kaW5nOiB0aGlzLmJpbmRpbmcsIGluaXQ6IHRoaXMuaW5pdH0sIHN1cGVyLl9jbG9uZUF0dHJzKCkpO1xuICB9XG4gIHJlZHVjZShyZWR1Y2VyXzEwODEpIHtcbiAgICBsZXQgc3RhdGVfMTA4MiA9IHRoaXMuX3JlZHVjZVN0YXRlKHJlZHVjZXJfMTA4MSk7XG4gICAgcmV0dXJuIHJlZHVjZXJfMTA4MS5yZWR1Y2VWYXJpYWJsZURlY2xhcmF0b3IodGhpcywgc3RhdGVfMTA4Mik7XG4gIH1cbiAgZXh0ZW5kKGF0dHJzXzEwODMpIHtcbiAgICByZXR1cm4gbmV3IFZhcmlhYmxlRGVjbGFyYXRvcihPYmplY3QuYXNzaWduKHRoaXMuX2Nsb25lQXR0cnMoKSwgYXR0cnNfMTA4MykpO1xuICB9XG59XG5UZXJtLkNsb25lUmVkdWNlci5wcm90b3R5cGUucmVkdWNlVmFyaWFibGVEZWNsYXJhdG9yID0gZnVuY3Rpb24gKHRlcm1fMTA4NCwgc3RhdGVfMTA4NSkge1xuICByZXR1cm4gbmV3IFZhcmlhYmxlRGVjbGFyYXRvcihzdGF0ZV8xMDg1KTtcbn07XG5leHBvcnQge1ZhcmlhYmxlRGVjbGFyYXRvciBhcyBWYXJpYWJsZURlY2xhcmF0b3J9O1xuY2xhc3MgT3BlcmF0b3JEZWNsYXJhdG9yIGV4dGVuZHMgVmFyaWFibGVEZWNsYXJhdG9yIHtcbiAgY29uc3RydWN0b3IoYXR0cnNfMTA4NiwgdHlwZV8xMDg3KSB7XG4gICAgc3VwZXIoYXR0cnNfMTA4NiwgdHlwZV8xMDg3IHx8IFwiT3BlcmF0b3JEZWNsYXJhdG9yXCIpO1xuICAgIGlmICghe30uaGFzT3duUHJvcGVydHkuY2FsbChhdHRyc18xMDg2LCBcInByZWNcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwicHJlY1wiKTtcbiAgICB9XG4gICAgaWYgKCF7fS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGF0dHJzXzEwODYsIFwiYXNzb2NcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXR0cmlidXRlOiBcIiArIFwiYXNzb2NcIik7XG4gICAgfVxuICB9XG4gIF9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzEwODgsIHN0YXRlXzEwODkgPSB7fSkge1xuICAgIHN0YXRlXzEwODkucHJlYyA9IHRoaXMucHJlYztcbiAgICBzdGF0ZV8xMDg5LmFzc29jID0gdGhpcy5hc3NvYztcbiAgICA7XG4gICAgcmV0dXJuIHN1cGVyLl9yZWR1Y2VTdGF0ZShyZWR1Y2VyXzEwODgsIHN0YXRlXzEwODkpO1xuICB9XG4gIF9jbG9uZUF0dHJzKCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtwcmVjOiB0aGlzLnByZWMsIGFzc29jOiB0aGlzLmFzc29jfSwgc3VwZXIuX2Nsb25lQXR0cnMoKSk7XG4gIH1cbiAgcmVkdWNlKHJlZHVjZXJfMTA5MCkge1xuICAgIGxldCBzdGF0ZV8xMDkxID0gdGhpcy5fcmVkdWNlU3RhdGUocmVkdWNlcl8xMDkwKTtcbiAgICByZXR1cm4gcmVkdWNlcl8xMDkwLnJlZHVjZU9wZXJhdG9yRGVjbGFyYXRvcih0aGlzLCBzdGF0ZV8xMDkxKTtcbiAgfVxuICBleHRlbmQoYXR0cnNfMTA5Mikge1xuICAgIHJldHVybiBuZXcgT3BlcmF0b3JEZWNsYXJhdG9yKE9iamVjdC5hc3NpZ24odGhpcy5fY2xvbmVBdHRycygpLCBhdHRyc18xMDkyKSk7XG4gIH1cbn1cblZhcmlhYmxlRGVjbGFyYXRvci5DbG9uZVJlZHVjZXIucHJvdG90eXBlLnJlZHVjZU9wZXJhdG9yRGVjbGFyYXRvciA9IGZ1bmN0aW9uICh0ZXJtXzEwOTMsIHN0YXRlXzEwOTQpIHtcbiAgcmV0dXJuIG5ldyBPcGVyYXRvckRlY2xhcmF0b3Ioc3RhdGVfMTA5NCk7XG59O1xuZXhwb3J0IHtPcGVyYXRvckRlY2xhcmF0b3IgYXMgT3BlcmF0b3JEZWNsYXJhdG9yfTtcbiJdfQ==\n\n/***/ },\n/* 44 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.isClassDeclaration = exports.isFunctionDeclaration = exports.isCompiletimeStatement = exports.isSyntaxDeclarationStatement = exports.isVariableDeclarationStatement = exports.isSyntaxVariableDeclartion = exports.isVariableDeclarator = exports.isVariableDeclaration = exports.isExportFrom = exports.isExportDefault = exports.isExport = exports.isExportDeclaration = exports.isImportDeclaration = undefined;\n\n\tvar _sweetSpec = __webpack_require__(43);\n\n\tvar T = _interopRequireWildcard(_sweetSpec);\n\n\tvar _ramda = __webpack_require__(20);\n\n\tvar _ = _interopRequireWildcard(_ramda);\n\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\n\tconst isImportDeclaration = exports.isImportDeclaration = _.is(T.ImportDeclaration);\n\n\tconst isExportDeclaration = exports.isExportDeclaration = _.is(T.ExportDeclaration);\n\tconst isExport = exports.isExport = _.is(T.Export);\n\tconst isExportDefault = exports.isExportDefault = _.is(T.ExportDefault);\n\tconst isExportFrom = exports.isExportFrom = _.is(T.ExportFrom);\n\n\tconst isVariableDeclaration = exports.isVariableDeclaration = _.is(T.VariableDeclaration);\n\tconst isVariableDeclarator = exports.isVariableDeclarator = _.is(T.VariableDeclarator);\n\tconst isSyntaxVariableDeclartion = exports.isSyntaxVariableDeclartion = _.both(isVariableDeclaration, _.either(_.propEq('kind', 'syntax'), _.propEq('kind', 'syntaxrec')));\n\n\tconst isVariableDeclarationStatement = exports.isVariableDeclarationStatement = _.is(T.VariableDeclarationStatement);\n\tconst isSyntaxDeclarationStatement = exports.isSyntaxDeclarationStatement = term => {\n\t  // syntax m = ...\n\t  // syntaxrec m = ...\n\t  return isVariableDeclarationStatement(term) && isSyntaxVariableDeclartion(term.declaration);\n\t};\n\n\tconst isCompiletimeStatement = exports.isCompiletimeStatement = isSyntaxDeclarationStatement;\n\n\tconst isFunctionDeclaration = exports.isFunctionDeclaration = _.is(T.FunctionDeclaration);\n\tconst isClassDeclaration = exports.isClassDeclaration = _.is(T.ClassDeclaration);\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zd2VldC1zcGVjLXV0aWxzLmpzIl0sIm5hbWVzIjpbIlQiLCJfIiwiaXNJbXBvcnREZWNsYXJhdGlvbiIsImlzIiwiSW1wb3J0RGVjbGFyYXRpb24iLCJpc0V4cG9ydERlY2xhcmF0aW9uIiwiRXhwb3J0RGVjbGFyYXRpb24iLCJpc0V4cG9ydCIsIkV4cG9ydCIsImlzRXhwb3J0RGVmYXVsdCIsIkV4cG9ydERlZmF1bHQiLCJpc0V4cG9ydEZyb20iLCJFeHBvcnRGcm9tIiwiaXNWYXJpYWJsZURlY2xhcmF0aW9uIiwiVmFyaWFibGVEZWNsYXJhdGlvbiIsImlzVmFyaWFibGVEZWNsYXJhdG9yIiwiVmFyaWFibGVEZWNsYXJhdG9yIiwiaXNTeW50YXhWYXJpYWJsZURlY2xhcnRpb24iLCJib3RoIiwiZWl0aGVyIiwicHJvcEVxIiwiaXNWYXJpYWJsZURlY2xhcmF0aW9uU3RhdGVtZW50IiwiVmFyaWFibGVEZWNsYXJhdGlvblN0YXRlbWVudCIsImlzU3ludGF4RGVjbGFyYXRpb25TdGF0ZW1lbnQiLCJ0ZXJtIiwiZGVjbGFyYXRpb24iLCJpc0NvbXBpbGV0aW1lU3RhdGVtZW50IiwiaXNGdW5jdGlvbkRlY2xhcmF0aW9uIiwiRnVuY3Rpb25EZWNsYXJhdGlvbiIsImlzQ2xhc3NEZWNsYXJhdGlvbiIsIkNsYXNzRGVjbGFyYXRpb24iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFFQTs7SUFBWUEsQzs7QUFDWjs7SUFBWUMsQzs7OztBQUVMLE1BQU1DLG9EQUFzQkQsRUFBRUUsRUFBRixDQUFLSCxFQUFFSSxpQkFBUCxDQUE1Qjs7QUFFQSxNQUFNQyxvREFBc0JKLEVBQUVFLEVBQUYsQ0FBS0gsRUFBRU0saUJBQVAsQ0FBNUI7QUFDQSxNQUFNQyw4QkFBV04sRUFBRUUsRUFBRixDQUFLSCxFQUFFUSxNQUFQLENBQWpCO0FBQ0EsTUFBTUMsNENBQWtCUixFQUFFRSxFQUFGLENBQUtILEVBQUVVLGFBQVAsQ0FBeEI7QUFDQSxNQUFNQyxzQ0FBZVYsRUFBRUUsRUFBRixDQUFLSCxFQUFFWSxVQUFQLENBQXJCOztBQUVBLE1BQU1DLHdEQUF3QlosRUFBRUUsRUFBRixDQUFLSCxFQUFFYyxtQkFBUCxDQUE5QjtBQUNBLE1BQU1DLHNEQUF1QmQsRUFBRUUsRUFBRixDQUFLSCxFQUFFZ0Isa0JBQVAsQ0FBN0I7QUFDQSxNQUFNQyxrRUFBNkJoQixFQUFFaUIsSUFBRixDQUN4Q0wscUJBRHdDLEVBRXhDWixFQUFFa0IsTUFBRixDQUFTbEIsRUFBRW1CLE1BQUYsQ0FBUyxNQUFULEVBQWlCLFFBQWpCLENBQVQsRUFBcUNuQixFQUFFbUIsTUFBRixDQUFTLE1BQVQsRUFBaUIsV0FBakIsQ0FBckMsQ0FGd0MsQ0FBbkM7O0FBS0EsTUFBTUMsMEVBQWlDcEIsRUFBRUUsRUFBRixDQUM1Q0gsRUFBRXNCLDRCQUQwQyxDQUF2QztBQUdBLE1BQU1DLHNFQUFnQ0MsSUFBRCxJQUFlO0FBQ3pEO0FBQ0E7QUFDQSxTQUFPSCwrQkFBK0JHLElBQS9CLEtBQ0xQLDJCQUEyQk8sS0FBS0MsV0FBaEMsQ0FERjtBQUVELENBTE07O0FBT0EsTUFBTUMsMERBQXlCSCw0QkFBL0I7O0FBRUEsTUFBTUksd0RBQXdCMUIsRUFBRUUsRUFBRixDQUFLSCxFQUFFNEIsbUJBQVAsQ0FBOUI7QUFDQSxNQUFNQyxrREFBcUI1QixFQUFFRSxFQUFGLENBQUtILEVBQUU4QixnQkFBUCxDQUEzQiIsImZpbGUiOiJzd2VldC1zcGVjLXV0aWxzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcblxuaW1wb3J0ICogYXMgVCBmcm9tICdzd2VldC1zcGVjJztcbmltcG9ydCAqIGFzIF8gZnJvbSAncmFtZGEnO1xuXG5leHBvcnQgY29uc3QgaXNJbXBvcnREZWNsYXJhdGlvbiA9IF8uaXMoVC5JbXBvcnREZWNsYXJhdGlvbik7XG5cbmV4cG9ydCBjb25zdCBpc0V4cG9ydERlY2xhcmF0aW9uID0gXy5pcyhULkV4cG9ydERlY2xhcmF0aW9uKTtcbmV4cG9ydCBjb25zdCBpc0V4cG9ydCA9IF8uaXMoVC5FeHBvcnQpO1xuZXhwb3J0IGNvbnN0IGlzRXhwb3J0RGVmYXVsdCA9IF8uaXMoVC5FeHBvcnREZWZhdWx0KTtcbmV4cG9ydCBjb25zdCBpc0V4cG9ydEZyb20gPSBfLmlzKFQuRXhwb3J0RnJvbSk7XG5cbmV4cG9ydCBjb25zdCBpc1ZhcmlhYmxlRGVjbGFyYXRpb24gPSBfLmlzKFQuVmFyaWFibGVEZWNsYXJhdGlvbik7XG5leHBvcnQgY29uc3QgaXNWYXJpYWJsZURlY2xhcmF0b3IgPSBfLmlzKFQuVmFyaWFibGVEZWNsYXJhdG9yKTtcbmV4cG9ydCBjb25zdCBpc1N5bnRheFZhcmlhYmxlRGVjbGFydGlvbiA9IF8uYm90aChcbiAgaXNWYXJpYWJsZURlY2xhcmF0aW9uLFxuICBfLmVpdGhlcihfLnByb3BFcSgna2luZCcsICdzeW50YXgnKSwgXy5wcm9wRXEoJ2tpbmQnLCAnc3ludGF4cmVjJykpLFxuKTtcblxuZXhwb3J0IGNvbnN0IGlzVmFyaWFibGVEZWNsYXJhdGlvblN0YXRlbWVudCA9IF8uaXMoXG4gIFQuVmFyaWFibGVEZWNsYXJhdGlvblN0YXRlbWVudCxcbik7XG5leHBvcnQgY29uc3QgaXNTeW50YXhEZWNsYXJhdGlvblN0YXRlbWVudCA9ICh0ZXJtOiBhbnkpID0+IHtcbiAgLy8gc3ludGF4IG0gPSAuLi5cbiAgLy8gc3ludGF4cmVjIG0gPSAuLi5cbiAgcmV0dXJuIGlzVmFyaWFibGVEZWNsYXJhdGlvblN0YXRlbWVudCh0ZXJtKSAmJlxuICAgIGlzU3ludGF4VmFyaWFibGVEZWNsYXJ0aW9uKHRlcm0uZGVjbGFyYXRpb24pO1xufTtcblxuZXhwb3J0IGNvbnN0IGlzQ29tcGlsZXRpbWVTdGF0ZW1lbnQgPSBpc1N5bnRheERlY2xhcmF0aW9uU3RhdGVtZW50O1xuXG5leHBvcnQgY29uc3QgaXNGdW5jdGlvbkRlY2xhcmF0aW9uID0gXy5pcyhULkZ1bmN0aW9uRGVjbGFyYXRpb24pO1xuZXhwb3J0IGNvbnN0IGlzQ2xhc3NEZWNsYXJhdGlvbiA9IF8uaXMoVC5DbGFzc0RlY2xhcmF0aW9uKTtcbiJdfQ==\n\n/***/ },\n/* 45 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.default = codegen;\n\n\tvar _shiftCodegen = __webpack_require__(46);\n\n\tvar _shiftCodegen2 = _interopRequireDefault(_shiftCodegen);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tfunction codegen(modTerm) {\n\t  return {\n\t    code: (0, _shiftCodegen2.default)(modTerm, new _shiftCodegen.FormattedCodeGen())\n\t  };\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb2RlZ2VuLmpzIl0sIm5hbWVzIjpbImNvZGVnZW4iLCJtb2RUZXJtIiwiY29kZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7a0JBRXdCQSxPOztBQUZ4Qjs7Ozs7O0FBRWUsU0FBU0EsT0FBVCxDQUFpQkMsT0FBakIsRUFBMEI7QUFDdkMsU0FBTztBQUNMQyxVQUFNLDRCQUFhRCxPQUFiLEVBQXNCLG9DQUF0QjtBQURELEdBQVA7QUFHRCIsImZpbGUiOiJjb2RlZ2VuLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHNoaWZ0Q29kZWdlbiwgeyBGb3JtYXR0ZWRDb2RlR2VuIH0gZnJvbSAnc2hpZnQtY29kZWdlbic7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGNvZGVnZW4obW9kVGVybSkge1xuICByZXR1cm4ge1xuICAgIGNvZGU6IHNoaWZ0Q29kZWdlbihtb2RUZXJtLCBuZXcgRm9ybWF0dGVkQ29kZUdlbigpKSxcbiAgfTtcbn1cbiJdfQ==\n\n/***/ },\n/* 46 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.SemiOp = exports.CommaSep = exports.Semi = exports.Seq = exports.ContainsIn = exports.NoIn = exports.Brace = exports.Bracket = exports.Paren = exports.NumberCodeRep = exports.Token = exports.Empty = exports.CodeRep = exports.escapeStringLiteral = exports.getPrecedence = exports.Precedence = exports.Sep = exports.FormattedCodeGen = exports.ExtensibleCodeGen = exports.MinimalCodeGen = undefined;\n\texports.default = codeGen;\n\n\tvar _minimalCodegen = __webpack_require__(47);\n\n\tObject.defineProperty(exports, \"MinimalCodeGen\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _minimalCodegen.default;\n\t  }\n\t});\n\n\tvar _formattedCodegen = __webpack_require__(50);\n\n\tObject.defineProperty(exports, \"ExtensibleCodeGen\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _formattedCodegen.ExtensibleCodeGen;\n\t  }\n\t});\n\tObject.defineProperty(exports, \"FormattedCodeGen\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _formattedCodegen.FormattedCodeGen;\n\t  }\n\t});\n\tObject.defineProperty(exports, \"Sep\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _formattedCodegen.Sep;\n\t  }\n\t});\n\n\tvar _coderep = __webpack_require__(49);\n\n\tObject.defineProperty(exports, \"Precedence\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _coderep.Precedence;\n\t  }\n\t});\n\tObject.defineProperty(exports, \"getPrecedence\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _coderep.getPrecedence;\n\t  }\n\t});\n\tObject.defineProperty(exports, \"escapeStringLiteral\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _coderep.escapeStringLiteral;\n\t  }\n\t});\n\tObject.defineProperty(exports, \"CodeRep\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _coderep.CodeRep;\n\t  }\n\t});\n\tObject.defineProperty(exports, \"Empty\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _coderep.Empty;\n\t  }\n\t});\n\tObject.defineProperty(exports, \"Token\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _coderep.Token;\n\t  }\n\t});\n\tObject.defineProperty(exports, \"NumberCodeRep\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _coderep.NumberCodeRep;\n\t  }\n\t});\n\tObject.defineProperty(exports, \"Paren\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _coderep.Paren;\n\t  }\n\t});\n\tObject.defineProperty(exports, \"Bracket\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _coderep.Bracket;\n\t  }\n\t});\n\tObject.defineProperty(exports, \"Brace\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _coderep.Brace;\n\t  }\n\t});\n\tObject.defineProperty(exports, \"NoIn\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _coderep.NoIn;\n\t  }\n\t});\n\tObject.defineProperty(exports, \"ContainsIn\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _coderep.ContainsIn;\n\t  }\n\t});\n\tObject.defineProperty(exports, \"Seq\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _coderep.Seq;\n\t  }\n\t});\n\tObject.defineProperty(exports, \"Semi\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _coderep.Semi;\n\t  }\n\t});\n\tObject.defineProperty(exports, \"CommaSep\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _coderep.CommaSep;\n\t  }\n\t});\n\tObject.defineProperty(exports, \"SemiOp\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _coderep.SemiOp;\n\t  }\n\t});\n\n\tvar _shiftReducer = __webpack_require__(51);\n\n\tvar _shiftReducer2 = _interopRequireDefault(_shiftReducer);\n\n\tvar _token_stream = __webpack_require__(55);\n\n\tvar _minimalCodegen2 = _interopRequireDefault(_minimalCodegen);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tfunction codeGen(script) {\n\t  var generator = arguments.length <= 1 || arguments[1] === undefined ? new _minimalCodegen2.default() : arguments[1];\n\n\t  var ts = new _token_stream.TokenStream();\n\t  var rep = (0, _shiftReducer2.default)(generator, script);\n\t  rep.emit(ts);\n\t  return ts.result;\n\t}\n\n/***/ },\n/* 47 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\n\tvar _objectAssign = __webpack_require__(48);\n\n\tvar _objectAssign2 = _interopRequireDefault(_objectAssign);\n\n\tvar _esutils = __webpack_require__(15);\n\n\tvar _coderep = __webpack_require__(49);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n\tfunction p(node, precedence, a) {\n\t  return (0, _coderep.getPrecedence)(node) < precedence ? paren(a) : a;\n\t}\n\n\tfunction t(token) {\n\t  return new _coderep.Token(token);\n\t}\n\n\tfunction paren(rep) {\n\t  return new _coderep.Paren(rep);\n\t}\n\n\tfunction brace(rep) {\n\t  return new _coderep.Brace(rep);\n\t}\n\n\tfunction bracket(rep) {\n\t  return new _coderep.Bracket(rep);\n\t}\n\n\tfunction noIn(rep) {\n\t  return new _coderep.NoIn(rep);\n\t}\n\n\tfunction markContainsIn(state) {\n\t  return state.containsIn ? new _coderep.ContainsIn(state) : state;\n\t}\n\n\tfunction seq() {\n\t  for (var _len = arguments.length, reps = Array(_len), _key = 0; _key < _len; _key++) {\n\t    reps[_key] = arguments[_key];\n\t  }\n\n\t  return new _coderep.Seq(reps);\n\t}\n\n\tfunction semi() {\n\t  return new _coderep.Semi();\n\t}\n\n\tfunction semiOp() {\n\t  return new _coderep.SemiOp();\n\t}\n\n\tfunction empty() {\n\t  return new _coderep.Empty();\n\t}\n\n\tfunction commaSep(pieces) {\n\t  return new _coderep.CommaSep(pieces);\n\t}\n\n\tfunction getAssignmentExpr(state) {\n\t  return state ? state.containsGroup ? paren(state) : state : empty();\n\t}\n\n\tvar MinimalCodeGen = function () {\n\t  function MinimalCodeGen() {\n\t    _classCallCheck(this, MinimalCodeGen);\n\t  }\n\n\t  _createClass(MinimalCodeGen, [{\n\t    key: \"parenToAvoidBeingDirective\",\n\t    value: function parenToAvoidBeingDirective(element, original) {\n\t      if (element && element.type === \"ExpressionStatement\" && element.expression.type === \"LiteralStringExpression\") {\n\t        return seq(paren(original.children[0]), semiOp());\n\t      }\n\t      return original;\n\t    }\n\t  }, {\n\t    key: \"reduceArrayExpression\",\n\t    value: function reduceArrayExpression(node, _ref) {\n\t      var elements = _ref.elements;\n\n\t      if (elements.length === 0) {\n\t        return bracket(empty());\n\t      }\n\n\t      var content = commaSep(elements.map(getAssignmentExpr));\n\t      if (elements.length > 0 && elements[elements.length - 1] == null) {\n\t        content = seq(content, t(\",\"));\n\t      }\n\t      return bracket(content);\n\t    }\n\t  }, {\n\t    key: \"reduceSpreadElement\",\n\t    value: function reduceSpreadElement(node, _ref2) {\n\t      var expression = _ref2.expression;\n\n\t      return seq(t(\"...\"), p(node.expression, _coderep.Precedence.Assignment, expression));\n\t    }\n\t  }, {\n\t    key: \"reduceAssignmentExpression\",\n\t    value: function reduceAssignmentExpression(node, _ref3) {\n\t      var binding = _ref3.binding;\n\t      var expression = _ref3.expression;\n\n\t      var leftCode = binding;\n\t      var rightCode = expression;\n\t      var containsIn = expression.containsIn;\n\t      var startsWithCurly = binding.startsWithCurly;\n\t      var startsWithLetSquareBracket = binding.startsWithLetSquareBracket;\n\t      var startsWithFunctionOrClass = binding.startsWithFunctionOrClass;\n\t      if ((0, _coderep.getPrecedence)(node.expression) < (0, _coderep.getPrecedence)(node)) {\n\t        rightCode = paren(rightCode);\n\t        containsIn = false;\n\t      }\n\t      return (0, _objectAssign2.default)(seq(leftCode, t(\"=\"), rightCode), { containsIn: containsIn, startsWithCurly: startsWithCurly, startsWithLetSquareBracket: startsWithLetSquareBracket, startsWithFunctionOrClass: startsWithFunctionOrClass });\n\t    }\n\t  }, {\n\t    key: \"reduceCompoundAssignmentExpression\",\n\t    value: function reduceCompoundAssignmentExpression(node, _ref4) {\n\t      var binding = _ref4.binding;\n\t      var expression = _ref4.expression;\n\n\t      var leftCode = binding;\n\t      var rightCode = expression;\n\t      var containsIn = expression.containsIn;\n\t      var startsWithCurly = binding.startsWithCurly;\n\t      var startsWithLetSquareBracket = binding.startsWithLetSquareBracket;\n\t      var startsWithFunctionOrClass = binding.startsWithFunctionOrClass;\n\t      if ((0, _coderep.getPrecedence)(node.expression) < (0, _coderep.getPrecedence)(node)) {\n\t        rightCode = paren(rightCode);\n\t        containsIn = false;\n\t      }\n\t      return (0, _objectAssign2.default)(seq(leftCode, t(node.operator), rightCode), { containsIn: containsIn, startsWithCurly: startsWithCurly, startsWithLetSquareBracket: startsWithLetSquareBracket, startsWithFunctionOrClass: startsWithFunctionOrClass });\n\t    }\n\t  }, {\n\t    key: \"reduceBinaryExpression\",\n\t    value: function reduceBinaryExpression(node, _ref5) {\n\t      var left = _ref5.left;\n\t      var right = _ref5.right;\n\n\t      var leftCode = left;\n\t      var startsWithCurly = left.startsWithCurly;\n\t      var startsWithLetSquareBracket = left.startsWithLetSquareBracket;\n\t      var startsWithFunctionOrClass = left.startsWithFunctionOrClass;\n\t      var leftContainsIn = left.containsIn;\n\t      if ((0, _coderep.getPrecedence)(node.left) < (0, _coderep.getPrecedence)(node)) {\n\t        leftCode = paren(leftCode);\n\t        startsWithCurly = false;\n\t        startsWithLetSquareBracket = false;\n\t        startsWithFunctionOrClass = false;\n\t        leftContainsIn = false;\n\t      }\n\t      var rightCode = right;\n\t      var rightContainsIn = right.containsIn;\n\t      if ((0, _coderep.getPrecedence)(node.right) <= (0, _coderep.getPrecedence)(node)) {\n\t        rightCode = paren(rightCode);\n\t        rightContainsIn = false;\n\t      }\n\t      return (0, _objectAssign2.default)(seq(leftCode, t(node.operator), rightCode), {\n\t        containsIn: leftContainsIn || rightContainsIn || node.operator === \"in\",\n\t        containsGroup: node.operator == \",\",\n\t        startsWithCurly: startsWithCurly,\n\t        startsWithLetSquareBracket: startsWithLetSquareBracket,\n\t        startsWithFunctionOrClass: startsWithFunctionOrClass\n\t      });\n\t    }\n\t  }, {\n\t    key: \"reduceBindingWithDefault\",\n\t    value: function reduceBindingWithDefault(node, _ref6) {\n\t      var binding = _ref6.binding;\n\t      var init = _ref6.init;\n\n\t      return seq(binding, t(\"=\"), init);\n\t    }\n\t  }, {\n\t    key: \"reduceBindingIdentifier\",\n\t    value: function reduceBindingIdentifier(node) {\n\t      var a = t(node.name);\n\t      if (node.name === \"let\") {\n\t        a.startsWithLet = true;\n\t      }\n\t      return a;\n\t    }\n\t  }, {\n\t    key: \"reduceArrayBinding\",\n\t    value: function reduceArrayBinding(node, _ref7) {\n\t      var elements = _ref7.elements;\n\t      var restElement = _ref7.restElement;\n\n\t      var content = undefined;\n\t      if (elements.length === 0) {\n\t        content = restElement == null ? empty() : seq(t(\"...\"), restElement);\n\t      } else {\n\t        elements = elements.concat(restElement == null ? [] : [seq(t(\"...\"), restElement)]);\n\t        content = commaSep(elements.map(getAssignmentExpr));\n\t        if (elements.length > 0 && elements[elements.length - 1] == null) {\n\t          content = seq(content, t(\",\"));\n\t        }\n\t      }\n\t      return bracket(content);\n\t    }\n\t  }, {\n\t    key: \"reduceObjectBinding\",\n\t    value: function reduceObjectBinding(node, _ref8) {\n\t      var properties = _ref8.properties;\n\n\t      var state = brace(commaSep(properties));\n\t      state.startsWithCurly = true;\n\t      return state;\n\t    }\n\t  }, {\n\t    key: \"reduceBindingPropertyIdentifier\",\n\t    value: function reduceBindingPropertyIdentifier(node, _ref9) {\n\t      var binding = _ref9.binding;\n\t      var init = _ref9.init;\n\n\t      if (node.init == null) return binding;\n\t      return seq(binding, t(\"=\"), init);\n\t    }\n\t  }, {\n\t    key: \"reduceBindingPropertyProperty\",\n\t    value: function reduceBindingPropertyProperty(node, _ref10) {\n\t      var name = _ref10.name;\n\t      var binding = _ref10.binding;\n\n\t      return seq(name, t(\":\"), binding);\n\t    }\n\t  }, {\n\t    key: \"reduceBlock\",\n\t    value: function reduceBlock(node, _ref11) {\n\t      var statements = _ref11.statements;\n\n\t      return brace(seq.apply(undefined, _toConsumableArray(statements)));\n\t    }\n\t  }, {\n\t    key: \"reduceBlockStatement\",\n\t    value: function reduceBlockStatement(node, _ref12) {\n\t      var block = _ref12.block;\n\n\t      return block;\n\t    }\n\t  }, {\n\t    key: \"reduceBreakStatement\",\n\t    value: function reduceBreakStatement(node, _ref13) {\n\t      var label = _ref13.label;\n\n\t      return seq(t(\"break\"), label ? t(label) : empty(), semiOp());\n\t    }\n\t  }, {\n\t    key: \"reduceCallExpression\",\n\t    value: function reduceCallExpression(node, _ref14) {\n\t      var callee = _ref14.callee;\n\t      var args = _ref14.arguments;\n\n\t      return (0, _objectAssign2.default)(seq(p(node.callee, (0, _coderep.getPrecedence)(node), callee), paren(commaSep(args))), {\n\t        startsWithCurly: callee.startsWithCurly,\n\t        startsWithLetSquareBracket: callee.startsWithLetSquareBracket,\n\t        startsWithFunctionOrClass: callee.startsWithFunctionOrClass\n\t      });\n\t    }\n\t  }, {\n\t    key: \"reduceCatchClause\",\n\t    value: function reduceCatchClause(node, _ref15) {\n\t      var binding = _ref15.binding;\n\t      var body = _ref15.body;\n\n\t      return seq(t(\"catch\"), paren(binding), body);\n\t    }\n\t  }, {\n\t    key: \"reduceClassDeclaration\",\n\t    value: function reduceClassDeclaration(node, _ref16) {\n\t      var name = _ref16.name;\n\t      var _super = _ref16.super;\n\t      var elements = _ref16.elements;\n\n\t      var state = seq(t(\"class\"), name);\n\t      if (_super != null) {\n\t        state = seq(state, t(\"extends\"), _super);\n\t      }\n\t      state = seq.apply(undefined, [state, t(\"{\")].concat(_toConsumableArray(elements), [t(\"}\")]));\n\t      return state;\n\t    }\n\t  }, {\n\t    key: \"reduceClassExpression\",\n\t    value: function reduceClassExpression(node, _ref17) {\n\t      var name = _ref17.name;\n\t      var _super = _ref17.super;\n\t      var elements = _ref17.elements;\n\n\t      var state = t(\"class\");\n\t      if (name != null) {\n\t        state = seq(state, name);\n\t      }\n\t      if (_super != null) {\n\t        state = seq(state, t(\"extends\"), _super);\n\t      }\n\t      state = seq.apply(undefined, [state, t(\"{\")].concat(_toConsumableArray(elements), [t(\"}\")]));\n\t      state.startsWithFunctionOrClass = true;\n\t      return state;\n\t    }\n\t  }, {\n\t    key: \"reduceClassElement\",\n\t    value: function reduceClassElement(node, _ref18) {\n\t      var method = _ref18.method;\n\n\t      if (!node.isStatic) return method;\n\t      return seq(t(\"static\"), method);\n\t    }\n\t  }, {\n\t    key: \"reduceComputedMemberExpression\",\n\t    value: function reduceComputedMemberExpression(node, _ref19) {\n\t      var object = _ref19.object;\n\t      var expression = _ref19.expression;\n\n\t      var startsWithLetSquareBracket = object.startsWithLetSquareBracket || node.object.type === \"IdentifierExpression\" && node.object.name === \"let\";\n\t      return (0, _objectAssign2.default)(seq(p(node.object, (0, _coderep.getPrecedence)(node), object), bracket(expression)), {\n\t        startsWithLet: object.startsWithLet,\n\t        startsWithLetSquareBracket: startsWithLetSquareBracket,\n\t        startsWithCurly: object.startsWithCurly,\n\t        startsWithFunctionOrClass: object.startsWithFunctionOrClass\n\t      });\n\t    }\n\t  }, {\n\t    key: \"reduceComputedPropertyName\",\n\t    value: function reduceComputedPropertyName(node, _ref20) {\n\t      var expression = _ref20.expression;\n\n\t      return bracket(expression);\n\t    }\n\t  }, {\n\t    key: \"reduceConditionalExpression\",\n\t    value: function reduceConditionalExpression(node, _ref21) {\n\t      var test = _ref21.test;\n\t      var consequent = _ref21.consequent;\n\t      var alternate = _ref21.alternate;\n\n\t      var containsIn = test.containsIn || alternate.containsIn;\n\t      var startsWithCurly = test.startsWithCurly;\n\t      var startsWithLetSquareBracket = test.startsWithLetSquareBracket;\n\t      var startsWithFunctionOrClass = test.startsWithFunctionOrClass;\n\t      return (0, _objectAssign2.default)(seq(p(node.test, _coderep.Precedence.LogicalOR, test), t(\"?\"), p(node.consequent, _coderep.Precedence.Assignment, consequent), t(\":\"), p(node.alternate, _coderep.Precedence.Assignment, alternate)), {\n\t        containsIn: containsIn,\n\t        startsWithCurly: startsWithCurly,\n\t        startsWithLetSquareBracket: startsWithLetSquareBracket,\n\t        startsWithFunctionOrClass: startsWithFunctionOrClass\n\t      });\n\t    }\n\t  }, {\n\t    key: \"reduceContinueStatement\",\n\t    value: function reduceContinueStatement(node, _ref22) {\n\t      var label = _ref22.label;\n\n\t      return seq(t(\"continue\"), label ? t(label) : empty(), semiOp());\n\t    }\n\t  }, {\n\t    key: \"reduceDataProperty\",\n\t    value: function reduceDataProperty(node, _ref23) {\n\t      var name = _ref23.name;\n\t      var expression = _ref23.expression;\n\n\t      return seq(name, t(\":\"), getAssignmentExpr(expression));\n\t    }\n\t  }, {\n\t    key: \"reduceDebuggerStatement\",\n\t    value: function reduceDebuggerStatement(node) {\n\t      return seq(t(\"debugger\"), semiOp());\n\t    }\n\t  }, {\n\t    key: \"reduceDoWhileStatement\",\n\t    value: function reduceDoWhileStatement(node, _ref24) {\n\t      var body = _ref24.body;\n\t      var test = _ref24.test;\n\n\t      return seq(t(\"do\"), body, t(\"while\"), paren(test), semiOp());\n\t    }\n\t  }, {\n\t    key: \"reduceEmptyStatement\",\n\t    value: function reduceEmptyStatement(node) {\n\t      return semi();\n\t    }\n\t  }, {\n\t    key: \"reduceExpressionStatement\",\n\t    value: function reduceExpressionStatement(node, _ref25) {\n\t      var expression = _ref25.expression;\n\n\t      var needsParens = expression.startsWithCurly || expression.startsWithLetSquareBracket || expression.startsWithFunctionOrClass;\n\t      return seq(needsParens ? paren(expression) : expression, semiOp());\n\t    }\n\t  }, {\n\t    key: \"reduceForInStatement\",\n\t    value: function reduceForInStatement(node, _ref26) {\n\t      var left = _ref26.left;\n\t      var right = _ref26.right;\n\t      var body = _ref26.body;\n\n\t      var leftP = left;\n\t      switch (node.left.type) {\n\t        case \"VariableDeclaration\":\n\t          leftP = noIn(markContainsIn(left));\n\t          break;\n\t        case \"BindingIdentifier\":\n\t          if (node.left.name === \"let\") {\n\t            leftP = paren(left);\n\t          }\n\t          break;\n\t      }\n\t      return (0, _objectAssign2.default)(seq(t(\"for\"), paren(seq(leftP, t(\"in\"), right)), body), { endsWithMissingElse: body.endsWithMissingElse });\n\t    }\n\t  }, {\n\t    key: \"reduceForOfStatement\",\n\t    value: function reduceForOfStatement(node, _ref27) {\n\t      var left = _ref27.left;\n\t      var right = _ref27.right;\n\t      var body = _ref27.body;\n\n\t      left = node.left.type === \"VariableDeclaration\" ? noIn(markContainsIn(left)) : left;\n\t      return (0, _objectAssign2.default)(seq(t(\"for\"), paren(seq(left.startsWithLet ? paren(left) : left, t(\"of\"), right)), body), { endsWithMissingElse: body.endsWithMissingElse });\n\t    }\n\t  }, {\n\t    key: \"reduceForStatement\",\n\t    value: function reduceForStatement(node, _ref28) {\n\t      var init = _ref28.init;\n\t      var test = _ref28.test;\n\t      var update = _ref28.update;\n\t      var body = _ref28.body;\n\n\t      return (0, _objectAssign2.default)(seq(t(\"for\"), paren(seq(init ? noIn(markContainsIn(init)) : empty(), semi(), test || empty(), semi(), update || empty())), body), {\n\t        endsWithMissingElse: body.endsWithMissingElse\n\t      });\n\t    }\n\t  }, {\n\t    key: \"reduceFunctionBody\",\n\t    value: function reduceFunctionBody(node, _ref29) {\n\t      var directives = _ref29.directives;\n\t      var statements = _ref29.statements;\n\n\t      if (statements.length) {\n\t        statements[0] = this.parenToAvoidBeingDirective(node.statements[0], statements[0]);\n\t      }\n\t      return seq.apply(undefined, _toConsumableArray(directives).concat(_toConsumableArray(statements)));\n\t    }\n\t  }, {\n\t    key: \"reduceFunctionDeclaration\",\n\t    value: function reduceFunctionDeclaration(node, _ref30) {\n\t      var name = _ref30.name;\n\t      var params = _ref30.params;\n\t      var body = _ref30.body;\n\n\t      return seq(t(\"function\"), node.isGenerator ? t(\"*\") : empty(), node.name.name === \"*default*\" ? empty() : name, paren(params), brace(body));\n\t    }\n\t  }, {\n\t    key: \"reduceFunctionExpression\",\n\t    value: function reduceFunctionExpression(node, _ref31) {\n\t      var name = _ref31.name;\n\t      var params = _ref31.params;\n\t      var body = _ref31.body;\n\n\t      var state = seq(t(\"function\"), node.isGenerator ? t(\"*\") : empty(), name ? name : empty(), paren(params), brace(body));\n\t      state.startsWithFunctionOrClass = true;\n\t      return state;\n\t    }\n\t  }, {\n\t    key: \"reduceFormalParameters\",\n\t    value: function reduceFormalParameters(node, _ref32) {\n\t      var items = _ref32.items;\n\t      var rest = _ref32.rest;\n\n\t      return commaSep(items.concat(rest == null ? [] : [seq(t(\"...\"), rest)]));\n\t    }\n\t  }, {\n\t    key: \"reduceArrowExpression\",\n\t    value: function reduceArrowExpression(node, _ref33) {\n\t      var params = _ref33.params;\n\t      var body = _ref33.body;\n\n\t      if (node.params.rest != null || node.params.items.length !== 1 || node.params.items[0].type !== \"BindingIdentifier\") {\n\t        params = paren(params);\n\t      }\n\t      if (node.body.type === \"FunctionBody\") {\n\t        body = brace(body);\n\t      } else if (body.startsWithCurly) {\n\t        body = paren(body);\n\t      }\n\t      return seq(params, t(\"=>\"), p(node.body, _coderep.Precedence.Assignment, body));\n\t    }\n\t  }, {\n\t    key: \"reduceGetter\",\n\t    value: function reduceGetter(node, _ref34) {\n\t      var name = _ref34.name;\n\t      var body = _ref34.body;\n\n\t      return seq(t(\"get\"), name, paren(empty()), brace(body));\n\t    }\n\t  }, {\n\t    key: \"reduceIdentifierExpression\",\n\t    value: function reduceIdentifierExpression(node) {\n\t      var a = t(node.name);\n\t      if (node.name === \"let\") {\n\t        a.startsWithLet = true;\n\t      }\n\t      return a;\n\t    }\n\t  }, {\n\t    key: \"reduceIfStatement\",\n\t    value: function reduceIfStatement(node, _ref35) {\n\t      var test = _ref35.test;\n\t      var consequent = _ref35.consequent;\n\t      var alternate = _ref35.alternate;\n\n\t      if (alternate && consequent.endsWithMissingElse) {\n\t        consequent = brace(consequent);\n\t      }\n\t      return (0, _objectAssign2.default)(seq(t(\"if\"), paren(test), consequent, alternate ? seq(t(\"else\"), alternate) : empty()), { endsWithMissingElse: alternate ? alternate.endsWithMissingElse : true });\n\t    }\n\t  }, {\n\t    key: \"reduceImport\",\n\t    value: function reduceImport(node, _ref36) {\n\t      var defaultBinding = _ref36.defaultBinding;\n\t      var namedImports = _ref36.namedImports;\n\n\t      var bindings = [];\n\t      if (defaultBinding != null) {\n\t        bindings.push(defaultBinding);\n\t      }\n\t      if (namedImports.length > 0) {\n\t        bindings.push(brace(commaSep(namedImports)));\n\t      }\n\t      if (bindings.length === 0) {\n\t        return seq(t(\"import\"), t((0, _coderep.escapeStringLiteral)(node.moduleSpecifier)), semiOp());\n\t      }\n\t      return seq(t(\"import\"), commaSep(bindings), t(\"from\"), t((0, _coderep.escapeStringLiteral)(node.moduleSpecifier)), semiOp());\n\t    }\n\t  }, {\n\t    key: \"reduceImportNamespace\",\n\t    value: function reduceImportNamespace(node, _ref37) {\n\t      var defaultBinding = _ref37.defaultBinding;\n\t      var namespaceBinding = _ref37.namespaceBinding;\n\n\t      return seq(t(\"import\"), defaultBinding == null ? empty() : seq(defaultBinding, t(\",\")), t(\"*\"), t(\"as\"), namespaceBinding, t(\"from\"), t((0, _coderep.escapeStringLiteral)(node.moduleSpecifier)), semiOp());\n\t    }\n\t  }, {\n\t    key: \"reduceImportSpecifier\",\n\t    value: function reduceImportSpecifier(node, _ref38) {\n\t      var binding = _ref38.binding;\n\n\t      if (node.name == null) return binding;\n\t      return seq(t(node.name), t(\"as\"), binding);\n\t    }\n\t  }, {\n\t    key: \"reduceExportAllFrom\",\n\t    value: function reduceExportAllFrom(node) {\n\t      return seq(t(\"export\"), t(\"*\"), t(\"from\"), t((0, _coderep.escapeStringLiteral)(node.moduleSpecifier)), semiOp());\n\t    }\n\t  }, {\n\t    key: \"reduceExportFrom\",\n\t    value: function reduceExportFrom(node, _ref39) {\n\t      var namedExports = _ref39.namedExports;\n\n\t      return seq(t(\"export\"), brace(commaSep(namedExports)), node.moduleSpecifier == null ? empty() : seq(t(\"from\"), t((0, _coderep.escapeStringLiteral)(node.moduleSpecifier)), semiOp()));\n\t    }\n\t  }, {\n\t    key: \"reduceExport\",\n\t    value: function reduceExport(node, _ref40) {\n\t      var declaration = _ref40.declaration;\n\n\t      switch (node.declaration.type) {\n\t        case \"FunctionDeclaration\":\n\t        case \"ClassDeclaration\":\n\t          break;\n\t        default:\n\t          declaration = seq(declaration, semiOp());\n\t      }\n\t      return seq(t(\"export\"), declaration);\n\t    }\n\t  }, {\n\t    key: \"reduceExportDefault\",\n\t    value: function reduceExportDefault(node, _ref41) {\n\t      var body = _ref41.body;\n\n\t      body = body.startsWithFunctionOrClass ? paren(body) : body;\n\t      switch (node.body.type) {\n\t        case \"FunctionDeclaration\":\n\t        case \"ClassDeclaration\":\n\t          break;\n\t        default:\n\t          body = seq(body, semiOp());\n\t      }\n\t      return seq(t(\"export default\"), body);\n\t    }\n\t  }, {\n\t    key: \"reduceExportSpecifier\",\n\t    value: function reduceExportSpecifier(node) {\n\t      if (node.name == null) return t(node.exportedName);\n\t      return seq(t(node.name), t(\"as\"), t(node.exportedName));\n\t    }\n\t  }, {\n\t    key: \"reduceLabeledStatement\",\n\t    value: function reduceLabeledStatement(node, _ref42) {\n\t      var label = _ref42.label;\n\t      var body = _ref42.body;\n\n\t      return (0, _objectAssign2.default)(seq(t(label + \":\"), body), { endsWithMissingElse: body.endsWithMissingElse });\n\t    }\n\t  }, {\n\t    key: \"reduceLiteralBooleanExpression\",\n\t    value: function reduceLiteralBooleanExpression(node) {\n\t      return t(node.value.toString());\n\t    }\n\t  }, {\n\t    key: \"reduceLiteralNullExpression\",\n\t    value: function reduceLiteralNullExpression(node) {\n\t      return t(\"null\");\n\t    }\n\t  }, {\n\t    key: \"reduceLiteralInfinityExpression\",\n\t    value: function reduceLiteralInfinityExpression(node) {\n\t      return t(\"2e308\");\n\t    }\n\t  }, {\n\t    key: \"reduceLiteralNumericExpression\",\n\t    value: function reduceLiteralNumericExpression(node) {\n\t      return new _coderep.NumberCodeRep(node.value);\n\t    }\n\t  }, {\n\t    key: \"reduceLiteralRegExpExpression\",\n\t    value: function reduceLiteralRegExpExpression(node) {\n\t      return t(\"/\" + node.pattern + \"/\" + node.flags);\n\t    }\n\t  }, {\n\t    key: \"reduceLiteralStringExpression\",\n\t    value: function reduceLiteralStringExpression(node) {\n\t      return t((0, _coderep.escapeStringLiteral)(node.value));\n\t    }\n\t  }, {\n\t    key: \"reduceMethod\",\n\t    value: function reduceMethod(node, _ref43) {\n\t      var name = _ref43.name;\n\t      var params = _ref43.params;\n\t      var body = _ref43.body;\n\n\t      return seq(node.isGenerator ? t(\"*\") : empty(), name, paren(params), brace(body));\n\t    }\n\t  }, {\n\t    key: \"reduceModule\",\n\t    value: function reduceModule(node, _ref44) {\n\t      var directives = _ref44.directives;\n\t      var items = _ref44.items;\n\n\t      if (items.length) {\n\t        items[0] = this.parenToAvoidBeingDirective(node.items[0], items[0]);\n\t      }\n\t      return seq.apply(undefined, _toConsumableArray(directives).concat(_toConsumableArray(items)));\n\t    }\n\t  }, {\n\t    key: \"reduceNewExpression\",\n\t    value: function reduceNewExpression(node, _ref45) {\n\t      var callee = _ref45.callee;\n\t      var args = _ref45.arguments;\n\n\t      var calleeRep = (0, _coderep.getPrecedence)(node.callee) == _coderep.Precedence.Call ? paren(callee) : p(node.callee, (0, _coderep.getPrecedence)(node), callee);\n\t      return seq(t(\"new\"), calleeRep, args.length === 0 ? empty() : paren(commaSep(args)));\n\t    }\n\t  }, {\n\t    key: \"reduceNewTargetExpression\",\n\t    value: function reduceNewTargetExpression() {\n\t      return t(\"new.target\");\n\t    }\n\t  }, {\n\t    key: \"reduceObjectExpression\",\n\t    value: function reduceObjectExpression(node, _ref46) {\n\t      var properties = _ref46.properties;\n\n\t      var state = brace(commaSep(properties));\n\t      state.startsWithCurly = true;\n\t      return state;\n\t    }\n\t  }, {\n\t    key: \"reduceUpdateExpression\",\n\t    value: function reduceUpdateExpression(node, _ref47) {\n\t      var operand = _ref47.operand;\n\n\t      if (node.isPrefix) {\n\t        return this.reduceUnaryExpression.apply(this, arguments);\n\t      } else {\n\t        return (0, _objectAssign2.default)(seq(p(node.operand, _coderep.Precedence.New, operand), t(node.operator)), {\n\t          startsWithCurly: operand.startsWithCurly,\n\t          startsWithLetSquareBracket: operand.startsWithLetSquareBracket,\n\t          startsWithFunctionOrClass: operand.startsWithFunctionOrClass\n\t        });\n\t      }\n\t    }\n\t  }, {\n\t    key: \"reduceUnaryExpression\",\n\t    value: function reduceUnaryExpression(node, _ref48) {\n\t      var operand = _ref48.operand;\n\n\t      return seq(t(node.operator), p(node.operand, (0, _coderep.getPrecedence)(node), operand));\n\t    }\n\t  }, {\n\t    key: \"reduceReturnStatement\",\n\t    value: function reduceReturnStatement(node, _ref49) {\n\t      var expression = _ref49.expression;\n\n\t      return seq(t(\"return\"), expression || empty(), semiOp());\n\t    }\n\t  }, {\n\t    key: \"reduceScript\",\n\t    value: function reduceScript(node, _ref50) {\n\t      var directives = _ref50.directives;\n\t      var statements = _ref50.statements;\n\n\t      if (statements.length) {\n\t        statements[0] = this.parenToAvoidBeingDirective(node.statements[0], statements[0]);\n\t      }\n\t      return seq.apply(undefined, _toConsumableArray(directives).concat(_toConsumableArray(statements)));\n\t    }\n\t  }, {\n\t    key: \"reduceSetter\",\n\t    value: function reduceSetter(node, _ref51) {\n\t      var name = _ref51.name;\n\t      var param = _ref51.param;\n\t      var body = _ref51.body;\n\n\t      return seq(t(\"set\"), name, paren(param), brace(body));\n\t    }\n\t  }, {\n\t    key: \"reduceShorthandProperty\",\n\t    value: function reduceShorthandProperty(node) {\n\t      return t(node.name);\n\t    }\n\t  }, {\n\t    key: \"reduceStaticMemberExpression\",\n\t    value: function reduceStaticMemberExpression(node, _ref52) {\n\t      var object = _ref52.object;\n\t      var property = _ref52.property;\n\n\t      var state = seq(p(node.object, (0, _coderep.getPrecedence)(node), object), t(\".\"), t(property));\n\t      state.startsWithLet = object.startsWithLet;\n\t      state.startsWithCurly = object.startsWithCurly;\n\t      state.startsWithLetSquareBracket = object.startsWithLetSquareBracket;\n\t      state.startsWithFunctionOrClass = object.startsWithFunctionOrClass;\n\t      return state;\n\t    }\n\t  }, {\n\t    key: \"reduceStaticPropertyName\",\n\t    value: function reduceStaticPropertyName(node) {\n\t      var n;\n\t      if (_esutils.keyword.isIdentifierNameES6(node.value)) {\n\t        return t(node.value);\n\t      } else if (n = parseFloat(node.value), n === n) {\n\t        return new _coderep.NumberCodeRep(n);\n\t      }\n\t      return t((0, _coderep.escapeStringLiteral)(node.value));\n\t    }\n\t  }, {\n\t    key: \"reduceSuper\",\n\t    value: function reduceSuper() {\n\t      return t(\"super\");\n\t    }\n\t  }, {\n\t    key: \"reduceSwitchCase\",\n\t    value: function reduceSwitchCase(node, _ref53) {\n\t      var test = _ref53.test;\n\t      var consequent = _ref53.consequent;\n\n\t      return seq(t(\"case\"), test, t(\":\"), seq.apply(undefined, _toConsumableArray(consequent)));\n\t    }\n\t  }, {\n\t    key: \"reduceSwitchDefault\",\n\t    value: function reduceSwitchDefault(node, _ref54) {\n\t      var consequent = _ref54.consequent;\n\n\t      return seq(t(\"default:\"), seq.apply(undefined, _toConsumableArray(consequent)));\n\t    }\n\t  }, {\n\t    key: \"reduceSwitchStatement\",\n\t    value: function reduceSwitchStatement(node, _ref55) {\n\t      var discriminant = _ref55.discriminant;\n\t      var cases = _ref55.cases;\n\n\t      return seq(t(\"switch\"), paren(discriminant), brace(seq.apply(undefined, _toConsumableArray(cases))));\n\t    }\n\t  }, {\n\t    key: \"reduceSwitchStatementWithDefault\",\n\t    value: function reduceSwitchStatementWithDefault(node, _ref56) {\n\t      var discriminant = _ref56.discriminant;\n\t      var preDefaultCases = _ref56.preDefaultCases;\n\t      var defaultCase = _ref56.defaultCase;\n\t      var postDefaultCases = _ref56.postDefaultCases;\n\n\t      return seq(t(\"switch\"), paren(discriminant), brace(seq.apply(undefined, _toConsumableArray(preDefaultCases).concat([defaultCase], _toConsumableArray(postDefaultCases)))));\n\t    }\n\t  }, {\n\t    key: \"reduceTemplateExpression\",\n\t    value: function reduceTemplateExpression(node, _ref57) {\n\t      var tag = _ref57.tag;\n\t      var elements = _ref57.elements;\n\n\t      var state = node.tag == null ? empty() : p(node.tag, (0, _coderep.getPrecedence)(node), tag);\n\t      var templateData = \"\";\n\t      state = seq(state, t(\"`\"));\n\t      for (var i = 0, l = node.elements.length; i < l; ++i) {\n\t        if (node.elements[i].type === \"TemplateElement\") {\n\t          var d = \"\";\n\t          if (i > 0) d += \"}\";\n\t          d += node.elements[i].rawValue;\n\t          if (i < l - 1) d += \"${\";\n\t          state = seq(state, t(d));\n\t        } else {\n\t          state = seq(state, elements[i]);\n\t        }\n\t      }\n\t      state = seq(state, t(\"`\"));\n\t      if (node.tag != null) {\n\t        state.startsWithCurly = tag.startsWithCurly;\n\t        state.startsWithLetSquareBracket = tag.startsWithLetSquareBracket;\n\t        state.startsWithFunctionOrClass = tag.startsWithFunctionOrClass;\n\t      }\n\t      return state;\n\t    }\n\t  }, {\n\t    key: \"reduceTemplateElement\",\n\t    value: function reduceTemplateElement(node) {\n\t      return t(node.rawValue);\n\t    }\n\t  }, {\n\t    key: \"reduceThisExpression\",\n\t    value: function reduceThisExpression(node) {\n\t      return t(\"this\");\n\t    }\n\t  }, {\n\t    key: \"reduceThrowStatement\",\n\t    value: function reduceThrowStatement(node, _ref58) {\n\t      var expression = _ref58.expression;\n\n\t      return seq(t(\"throw\"), expression, semiOp());\n\t    }\n\t  }, {\n\t    key: \"reduceTryCatchStatement\",\n\t    value: function reduceTryCatchStatement(node, _ref59) {\n\t      var body = _ref59.body;\n\t      var catchClause = _ref59.catchClause;\n\n\t      return seq(t(\"try\"), body, catchClause);\n\t    }\n\t  }, {\n\t    key: \"reduceTryFinallyStatement\",\n\t    value: function reduceTryFinallyStatement(node, _ref60) {\n\t      var body = _ref60.body;\n\t      var catchClause = _ref60.catchClause;\n\t      var finalizer = _ref60.finalizer;\n\n\t      return seq(t(\"try\"), body, catchClause || empty(), t(\"finally\"), finalizer);\n\t    }\n\t  }, {\n\t    key: \"reduceYieldExpression\",\n\t    value: function reduceYieldExpression(node, _ref61) {\n\t      var expression = _ref61.expression;\n\n\t      if (node.expression == null) return t(\"yield\");\n\t      return seq(t(\"yield\"), p(node.expression, (0, _coderep.getPrecedence)(node), expression));\n\t    }\n\t  }, {\n\t    key: \"reduceYieldGeneratorExpression\",\n\t    value: function reduceYieldGeneratorExpression(node, _ref62) {\n\t      var expression = _ref62.expression;\n\n\t      return seq(t(\"yield\"), t(\"*\"), p(node.expression, (0, _coderep.getPrecedence)(node), expression));\n\t    }\n\t  }, {\n\t    key: \"reduceDirective\",\n\t    value: function reduceDirective(node) {\n\t      var delim = /^(?:[^\"\\\\]|\\\\.)*$/.test(node.rawValue) ? \"\\\"\" : \"'\";\n\t      return seq(t(delim + node.rawValue + delim), semiOp());\n\t    }\n\t  }, {\n\t    key: \"reduceVariableDeclaration\",\n\t    value: function reduceVariableDeclaration(node, _ref63) {\n\t      var declarators = _ref63.declarators;\n\n\t      return seq(t(node.kind), commaSep(declarators));\n\t    }\n\t  }, {\n\t    key: \"reduceVariableDeclarationStatement\",\n\t    value: function reduceVariableDeclarationStatement(node, _ref64) {\n\t      var declaration = _ref64.declaration;\n\n\t      return seq(declaration, semiOp());\n\t    }\n\t  }, {\n\t    key: \"reduceVariableDeclarator\",\n\t    value: function reduceVariableDeclarator(node, _ref65) {\n\t      var binding = _ref65.binding;\n\t      var init = _ref65.init;\n\n\t      var containsIn = init && init.containsIn && !init.containsGroup;\n\t      if (init) {\n\t        if (init.containsGroup) {\n\t          init = paren(init);\n\t        } else {\n\t          init = markContainsIn(init);\n\t        }\n\t      }\n\t      return (0, _objectAssign2.default)(init == null ? binding : seq(binding, t(\"=\"), init), { containsIn: containsIn });\n\t    }\n\t  }, {\n\t    key: \"reduceWhileStatement\",\n\t    value: function reduceWhileStatement(node, _ref66) {\n\t      var test = _ref66.test;\n\t      var body = _ref66.body;\n\n\t      return (0, _objectAssign2.default)(seq(t(\"while\"), paren(test), body), { endsWithMissingElse: body.endsWithMissingElse });\n\t    }\n\t  }, {\n\t    key: \"reduceWithStatement\",\n\t    value: function reduceWithStatement(node, _ref67) {\n\t      var object = _ref67.object;\n\t      var body = _ref67.body;\n\n\t      return (0, _objectAssign2.default)(seq(t(\"with\"), paren(object), body), { endsWithMissingElse: body.endsWithMissingElse });\n\t    }\n\t  }]);\n\n\t  return MinimalCodeGen;\n\t}();\n\n\texports.default = MinimalCodeGen;\n\n/***/ },\n/* 48 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\tvar propIsEnumerable = Object.prototype.propertyIsEnumerable;\n\n\tfunction ToObject(val) {\n\t\tif (val == null) {\n\t\t\tthrow new TypeError('Object.assign cannot be called with null or undefined');\n\t\t}\n\n\t\treturn Object(val);\n\t}\n\n\tfunction ownEnumerableKeys(obj) {\n\t\tvar keys = Object.getOwnPropertyNames(obj);\n\n\t\tif (Object.getOwnPropertySymbols) {\n\t\t\tkeys = keys.concat(Object.getOwnPropertySymbols(obj));\n\t\t}\n\n\t\treturn keys.filter(function (key) {\n\t\t\treturn propIsEnumerable.call(obj, key);\n\t\t});\n\t}\n\n\tmodule.exports = Object.assign || function (target, source) {\n\t\tvar from;\n\t\tvar keys;\n\t\tvar to = ToObject(target);\n\n\t\tfor (var s = 1; s < arguments.length; s++) {\n\t\t\tfrom = arguments[s];\n\t\t\tkeys = ownEnumerableKeys(Object(from));\n\n\t\t\tfor (var i = 0; i < keys.length; i++) {\n\t\t\t\tto[keys[i]] = from[keys[i]];\n\t\t\t}\n\t\t}\n\n\t\treturn to;\n\t};\n\n\n/***/ },\n/* 49 */\n/***/ function(module, exports) {\n\n\t\"use strict\";\n\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.getPrecedence = getPrecedence;\n\texports.escapeStringLiteral = escapeStringLiteral;\n\n\tfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n\tvar Precedence = {\n\t  Sequence: 0,\n\t  Yield: 1,\n\t  Assignment: 1,\n\t  Conditional: 2,\n\t  ArrowFunction: 2,\n\t  LogicalOR: 3,\n\t  LogicalAND: 4,\n\t  BitwiseOR: 5,\n\t  BitwiseXOR: 6,\n\t  BitwiseAND: 7,\n\t  Equality: 8,\n\t  Relational: 9,\n\t  BitwiseSHIFT: 10,\n\t  Additive: 11,\n\t  Multiplicative: 12,\n\t  Prefix: 13,\n\t  Postfix: 14,\n\t  New: 15,\n\t  Call: 16,\n\t  TaggedTemplate: 17,\n\t  Member: 18,\n\t  Primary: 19\n\t};\n\n\texports.Precedence = Precedence;\n\n\tvar BinaryPrecedence = {\n\t  \",\": Precedence.Sequence,\n\t  \"||\": Precedence.LogicalOR,\n\t  \"&&\": Precedence.LogicalAND,\n\t  \"|\": Precedence.BitwiseOR,\n\t  \"^\": Precedence.BitwiseXOR,\n\t  \"&\": Precedence.BitwiseAND,\n\t  \"==\": Precedence.Equality,\n\t  \"!=\": Precedence.Equality,\n\t  \"===\": Precedence.Equality,\n\t  \"!==\": Precedence.Equality,\n\t  \"<\": Precedence.Relational,\n\t  \">\": Precedence.Relational,\n\t  \"<=\": Precedence.Relational,\n\t  \">=\": Precedence.Relational,\n\t  \"in\": Precedence.Relational,\n\t  \"instanceof\": Precedence.Relational,\n\t  \"<<\": Precedence.BitwiseSHIFT,\n\t  \">>\": Precedence.BitwiseSHIFT,\n\t  \">>>\": Precedence.BitwiseSHIFT,\n\t  \"+\": Precedence.Additive,\n\t  \"-\": Precedence.Additive,\n\t  \"*\": Precedence.Multiplicative,\n\t  \"%\": Precedence.Multiplicative,\n\t  \"/\": Precedence.Multiplicative\n\t};\n\n\tfunction getPrecedence(node) {\n\t  switch (node.type) {\n\t    case \"ArrayExpression\":\n\t    case \"FunctionExpression\":\n\t    case \"IdentifierExpression\":\n\t    case \"LiteralBooleanExpression\":\n\t    case \"LiteralNullExpression\":\n\t    case \"LiteralNumericExpression\":\n\t    case \"LiteralInfinityExpression\":\n\t    case \"LiteralRegExpExpression\":\n\t    case \"LiteralStringExpression\":\n\t    case \"ObjectExpression\":\n\t    case \"ThisExpression\":\n\t      return Precedence.Primary;\n\n\t    case \"ArrowExpression\":\n\t    case \"AssignmentExpression\":\n\t    case \"CompoundAssignmentExpression\":\n\t    case \"YieldExpression\":\n\t    case \"YieldGeneratorExpression\":\n\t      return Precedence.Assignment;\n\n\t    case \"ConditionalExpression\":\n\t      return Precedence.Conditional;\n\n\t    case \"ComputedMemberExpression\":\n\t    case \"StaticMemberExpression\":\n\t      switch (node.object.type) {\n\t        case \"CallExpression\":\n\t        case \"ComputedMemberExpression\":\n\t        case \"StaticMemberExpression\":\n\t        case \"TemplateExpression\":\n\t          return getPrecedence(node.object);\n\t        default:\n\t          return Precedence.Member;\n\t      }\n\n\t    case \"TemplateExpression\":\n\t      if (node.tag == null) return Precedence.Member;\n\t      switch (node.tag.type) {\n\t        case \"CallExpression\":\n\t        case \"ComputedMemberExpression\":\n\t        case \"StaticMemberExpression\":\n\t        case \"TemplateExpression\":\n\t          return getPrecedence(node.tag);\n\t        default:\n\t          return Precedence.Member;\n\t      }\n\n\t    case \"BinaryExpression\":\n\t      return BinaryPrecedence[node.operator];\n\n\t    case \"CallExpression\":\n\t      return Precedence.Call;\n\t    case \"NewExpression\":\n\t      return node.arguments.length === 0 ? Precedence.New : Precedence.Member;\n\t    case \"UpdateExpression\":\n\t      return node.isPrefix ? Precedence.Prefix : Precedence.Postfix;\n\t    case \"UnaryExpression\":\n\t      return Precedence.Prefix;\n\t  }\n\t}\n\n\tfunction escapeStringLiteral(stringValue) {\n\t  var result = \"\";\n\t  var nSingle = 0,\n\t      nDouble = 0;\n\t  for (var i = 0, l = stringValue.length; i < l; ++i) {\n\t    var ch = stringValue[i];\n\t    if (ch === \"\\\"\") {\n\t      ++nDouble;\n\t    } else if (ch === \"'\") {\n\t      ++nSingle;\n\t    }\n\t  }\n\t  var delim = nDouble > nSingle ? \"'\" : \"\\\"\";\n\t  result += delim;\n\t  for (var i = 0; i < stringValue.length; i++) {\n\t    var ch = stringValue.charAt(i);\n\t    switch (ch) {\n\t      case delim:\n\t        result += \"\\\\\" + delim;\n\t        break;\n\t      case \"\\b\":\n\t        result += \"\\\\b\";\n\t        break;\n\t      case \"\\t\":\n\t        result += \"\\\\t\";\n\t        break;\n\t      case \"\\n\":\n\t        result += \"\\\\n\";\n\t        break;\n\t      case \"\\u000b\":\n\t        result += \"\\\\v\";\n\t        break;\n\t      case \"\\f\":\n\t        result += \"\\\\f\";\n\t        break;\n\t      case \"\\r\":\n\t        result += \"\\\\r\";\n\t        break;\n\t      case \"\\\\\":\n\t        result += \"\\\\\\\\\";\n\t        break;\n\t      case \"\\u2028\":\n\t        result += \"\\\\u2028\";\n\t        break;\n\t      case \"\\u2029\":\n\t        result += \"\\\\u2029\";\n\t        break;\n\t      default:\n\t        result += ch;\n\t        break;\n\t    }\n\t  }\n\t  result += delim;\n\t  return result;\n\t}\n\n\tvar CodeRep = exports.CodeRep = function () {\n\t  function CodeRep() {\n\t    _classCallCheck(this, CodeRep);\n\n\t    this.containsIn = false;\n\t    this.containsGroup = false;\n\t    // restricted lookaheads: {, function, class, let, let [\n\t    this.startsWithCurly = false;\n\t    this.startsWithFunctionOrClass = false;\n\t    this.startsWithLet = false;\n\t    this.startsWithLetSquareBracket = false;\n\t    this.endsWithMissingElse = false;\n\t  }\n\n\t  _createClass(CodeRep, [{\n\t    key: \"forEach\",\n\t    value: function forEach(f) {\n\t      // Call a function on every CodeRep represented by this node. Always calls f on a node and then its children, so if you're careful you can modify a node's children online.\n\t      f(this);\n\t    }\n\t  }]);\n\n\t  return CodeRep;\n\t}();\n\n\tvar Empty = exports.Empty = function (_CodeRep) {\n\t  _inherits(Empty, _CodeRep);\n\n\t  function Empty() {\n\t    _classCallCheck(this, Empty);\n\n\t    return _possibleConstructorReturn(this, Object.getPrototypeOf(Empty).call(this));\n\t  }\n\n\t  _createClass(Empty, [{\n\t    key: \"emit\",\n\t    value: function emit() {}\n\t  }]);\n\n\t  return Empty;\n\t}(CodeRep);\n\n\tvar Token = exports.Token = function (_CodeRep2) {\n\t  _inherits(Token, _CodeRep2);\n\n\t  function Token(token) {\n\t    _classCallCheck(this, Token);\n\n\t    var _this2 = _possibleConstructorReturn(this, Object.getPrototypeOf(Token).call(this));\n\n\t    _this2.token = token;\n\t    return _this2;\n\t  }\n\n\t  _createClass(Token, [{\n\t    key: \"emit\",\n\t    value: function emit(ts) {\n\t      ts.put(this.token);\n\t    }\n\t  }]);\n\n\t  return Token;\n\t}(CodeRep);\n\n\tvar NumberCodeRep = exports.NumberCodeRep = function (_CodeRep3) {\n\t  _inherits(NumberCodeRep, _CodeRep3);\n\n\t  function NumberCodeRep(number) {\n\t    _classCallCheck(this, NumberCodeRep);\n\n\t    var _this3 = _possibleConstructorReturn(this, Object.getPrototypeOf(NumberCodeRep).call(this));\n\n\t    _this3.number = number;\n\t    return _this3;\n\t  }\n\n\t  _createClass(NumberCodeRep, [{\n\t    key: \"emit\",\n\t    value: function emit(ts) {\n\t      ts.putNumber(this.number);\n\t    }\n\t  }]);\n\n\t  return NumberCodeRep;\n\t}(CodeRep);\n\n\tvar Paren = exports.Paren = function (_CodeRep4) {\n\t  _inherits(Paren, _CodeRep4);\n\n\t  function Paren(expr) {\n\t    _classCallCheck(this, Paren);\n\n\t    var _this4 = _possibleConstructorReturn(this, Object.getPrototypeOf(Paren).call(this));\n\n\t    _this4.expr = expr;\n\t    return _this4;\n\t  }\n\n\t  _createClass(Paren, [{\n\t    key: \"emit\",\n\t    value: function emit(ts) {\n\t      ts.put(\"(\");\n\t      this.expr.emit(ts, false);\n\t      ts.put(\")\");\n\t    }\n\t  }, {\n\t    key: \"forEach\",\n\t    value: function forEach(f) {\n\t      f(this);\n\t      this.expr.forEach(f);\n\t    }\n\t  }]);\n\n\t  return Paren;\n\t}(CodeRep);\n\n\tvar Bracket = exports.Bracket = function (_CodeRep5) {\n\t  _inherits(Bracket, _CodeRep5);\n\n\t  function Bracket(expr) {\n\t    _classCallCheck(this, Bracket);\n\n\t    var _this5 = _possibleConstructorReturn(this, Object.getPrototypeOf(Bracket).call(this));\n\n\t    _this5.expr = expr;\n\t    return _this5;\n\t  }\n\n\t  _createClass(Bracket, [{\n\t    key: \"emit\",\n\t    value: function emit(ts) {\n\t      ts.put(\"[\");\n\t      this.expr.emit(ts, false);\n\t      ts.put(\"]\");\n\t    }\n\t  }, {\n\t    key: \"forEach\",\n\t    value: function forEach(f) {\n\t      f(this);\n\t      this.expr.forEach(f);\n\t    }\n\t  }]);\n\n\t  return Bracket;\n\t}(CodeRep);\n\n\tvar Brace = exports.Brace = function (_CodeRep6) {\n\t  _inherits(Brace, _CodeRep6);\n\n\t  function Brace(expr) {\n\t    _classCallCheck(this, Brace);\n\n\t    var _this6 = _possibleConstructorReturn(this, Object.getPrototypeOf(Brace).call(this));\n\n\t    _this6.expr = expr;\n\t    return _this6;\n\t  }\n\n\t  _createClass(Brace, [{\n\t    key: \"emit\",\n\t    value: function emit(ts) {\n\t      ts.put(\"{\");\n\t      this.expr.emit(ts, false);\n\t      ts.put(\"}\");\n\t    }\n\t  }, {\n\t    key: \"forEach\",\n\t    value: function forEach(f) {\n\t      f(this);\n\t      this.expr.forEach(f);\n\t    }\n\t  }]);\n\n\t  return Brace;\n\t}(CodeRep);\n\n\tvar NoIn = exports.NoIn = function (_CodeRep7) {\n\t  _inherits(NoIn, _CodeRep7);\n\n\t  function NoIn(expr) {\n\t    _classCallCheck(this, NoIn);\n\n\t    var _this7 = _possibleConstructorReturn(this, Object.getPrototypeOf(NoIn).call(this));\n\n\t    _this7.expr = expr;\n\t    return _this7;\n\t  }\n\n\t  _createClass(NoIn, [{\n\t    key: \"emit\",\n\t    value: function emit(ts) {\n\t      this.expr.emit(ts, true);\n\t    }\n\t  }, {\n\t    key: \"forEach\",\n\t    value: function forEach(f) {\n\t      f(this);\n\t      this.expr.forEach(f);\n\t    }\n\t  }]);\n\n\t  return NoIn;\n\t}(CodeRep);\n\n\tvar ContainsIn = exports.ContainsIn = function (_CodeRep8) {\n\t  _inherits(ContainsIn, _CodeRep8);\n\n\t  function ContainsIn(expr) {\n\t    _classCallCheck(this, ContainsIn);\n\n\t    var _this8 = _possibleConstructorReturn(this, Object.getPrototypeOf(ContainsIn).call(this));\n\n\t    _this8.expr = expr;\n\t    return _this8;\n\t  }\n\n\t  _createClass(ContainsIn, [{\n\t    key: \"emit\",\n\t    value: function emit(ts, noIn) {\n\t      if (noIn) {\n\t        ts.put(\"(\");\n\t        this.expr.emit(ts, false);\n\t        ts.put(\")\");\n\t      } else {\n\t        this.expr.emit(ts, false);\n\t      }\n\t    }\n\t  }, {\n\t    key: \"forEach\",\n\t    value: function forEach(f) {\n\t      f(this);\n\t      this.expr.forEach(f);\n\t    }\n\t  }]);\n\n\t  return ContainsIn;\n\t}(CodeRep);\n\n\tvar Seq = exports.Seq = function (_CodeRep9) {\n\t  _inherits(Seq, _CodeRep9);\n\n\t  function Seq(children) {\n\t    _classCallCheck(this, Seq);\n\n\t    var _this9 = _possibleConstructorReturn(this, Object.getPrototypeOf(Seq).call(this));\n\n\t    _this9.children = children;\n\t    return _this9;\n\t  }\n\n\t  _createClass(Seq, [{\n\t    key: \"emit\",\n\t    value: function emit(ts, noIn) {\n\t      this.children.forEach(function (cr) {\n\t        return cr.emit(ts, noIn);\n\t      });\n\t    }\n\t  }, {\n\t    key: \"forEach\",\n\t    value: function forEach(f) {\n\t      f(this);\n\t      this.children.forEach(function (x) {\n\t        return x.forEach(f);\n\t      });\n\t    }\n\t  }]);\n\n\t  return Seq;\n\t}(CodeRep);\n\n\tvar Semi = exports.Semi = function (_Token) {\n\t  _inherits(Semi, _Token);\n\n\t  function Semi() {\n\t    _classCallCheck(this, Semi);\n\n\t    return _possibleConstructorReturn(this, Object.getPrototypeOf(Semi).call(this, \";\"));\n\t  }\n\n\t  return Semi;\n\t}(Token);\n\n\tvar CommaSep = exports.CommaSep = function (_CodeRep10) {\n\t  _inherits(CommaSep, _CodeRep10);\n\n\t  function CommaSep(children) {\n\t    _classCallCheck(this, CommaSep);\n\n\t    var _this11 = _possibleConstructorReturn(this, Object.getPrototypeOf(CommaSep).call(this));\n\n\t    _this11.children = children;\n\t    return _this11;\n\t  }\n\n\t  _createClass(CommaSep, [{\n\t    key: \"emit\",\n\t    value: function emit(ts, noIn) {\n\t      var first = true;\n\t      this.children.forEach(function (cr) {\n\t        if (first) {\n\t          first = false;\n\t        } else {\n\t          ts.put(\",\");\n\t        }\n\t        cr.emit(ts, noIn);\n\t      });\n\t    }\n\t  }, {\n\t    key: \"forEach\",\n\t    value: function forEach(f) {\n\t      f(this);\n\t      this.children.forEach(function (x) {\n\t        return x.forEach(f);\n\t      });\n\t    }\n\t  }]);\n\n\t  return CommaSep;\n\t}(CodeRep);\n\n\tvar SemiOp = exports.SemiOp = function (_CodeRep11) {\n\t  _inherits(SemiOp, _CodeRep11);\n\n\t  function SemiOp() {\n\t    _classCallCheck(this, SemiOp);\n\n\t    return _possibleConstructorReturn(this, Object.getPrototypeOf(SemiOp).call(this));\n\t  }\n\n\t  _createClass(SemiOp, [{\n\t    key: \"emit\",\n\t    value: function emit(ts) {\n\t      ts.putOptionalSemi();\n\t    }\n\t  }]);\n\n\t  return SemiOp;\n\t}(CodeRep);\n\n/***/ },\n/* 50 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.FormattedCodeGen = exports.ExtensibleCodeGen = exports.Sep = undefined;\n\n\tvar _objectAssign = __webpack_require__(48);\n\n\tvar _objectAssign2 = _interopRequireDefault(_objectAssign);\n\n\tvar _esutils = __webpack_require__(15);\n\n\tvar _coderep = __webpack_require__(49);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n\tfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n\tfunction empty() {\n\t  return new _coderep.Empty();\n\t}\n\n\tfunction noIn(rep) {\n\t  return new _coderep.NoIn(rep);\n\t}\n\n\tfunction markContainsIn(state) {\n\t  return state.containsIn ? new _coderep.ContainsIn(state) : state;\n\t}\n\n\tfunction seq() {\n\t  for (var _len = arguments.length, reps = Array(_len), _key = 0; _key < _len; _key++) {\n\t    reps[_key] = arguments[_key];\n\t  }\n\n\t  return new _coderep.Seq(reps);\n\t}\n\n\tfunction isEmpty(codeRep) {\n\t  return codeRep instanceof _coderep.Empty || codeRep instanceof Linebreak || codeRep instanceof _coderep.Seq && codeRep.children.every(isEmpty);\n\t}\n\n\tvar Sep = {};\n\tvar separatorNames = [\"ARRAY_EMPTY\", \"ARRAY_BEFORE_COMMA\", \"ARRAY_AFTER_COMMA\", \"SPREAD\", \"BEFORE_DEFAULT_EQUALS\", \"AFTER_DEFAULT_EQUALS\", \"REST\", \"OBJECT_BEFORE_COMMA\", \"OBJECT_AFTER_COMMA\", \"BEFORE_PROP\", \"AFTER_PROP\", \"BEFORE_JUMP_LABEL\", \"ARGS_BEFORE_COMMA\", \"ARGS_AFTER_COMMA\", \"CALL\", \"BEFORE_CATCH_BINDING\", \"AFTER_CATCH_BINDING\", \"BEFORE_CLASS_NAME\", \"BEFORE_EXTENDS\", \"AFTER_EXTENDS\", \"BEFORE_CLASS_DECLARATION_ELEMENTS\", \"BEFORE_CLASS_EXPRESSION_ELEMENTS\", \"AFTER_STATIC\", \"BEFORE_CLASS_ELEMENT\", \"AFTER_CLASS_ELEMENT\", \"BEFORE_TERNARY_QUESTION\", \"AFTER_TERNARY_QUESTION\", \"BEFORE_TERNARY_COLON\", \"AFTER_TERNARY_COLON\", \"COMPUTED_MEMBER_EXPRESSION\", \"AFTER_DO\", \"BEFORE_DOWHILE_WHILE\", \"AFTER_DOWHILE_WHILE\", \"AFTER_FORIN_FOR\", \"BEFORE_FORIN_IN\", \"AFTER_FORIN_FOR\", \"BEFORE_FORIN_BODY\", \"AFTER_FOROF_FOR\", \"BEFORE_FOROF_OF\", \"AFTER_FOROF_FOR\", \"BEFORE_FOROF_BODY\", \"AFTER_FOR_FOR\", \"BEFORE_FOR_INIT\", \"AFTER_FOR_INIT\", \"EMPTY_FOR_INIT\", \"BEFORE_FOR_TEST\", \"AFTER_FOR_TEST\", \"EMPTY_FOR_TEST\", \"BEFORE_FOR_UPDATE\", \"AFTER_FOR_UPDATE\", \"EMPTY_FOR_UPDATE\", \"BEFORE_FOR_BODY\", \"BEFORE_GENERATOR_STAR\", \"AFTER_GENERATOR_STAR\", \"BEFORE_FUNCTION_PARAMS\", \"BEFORE_FUNCTION_DECLARATION_BODY\", \"BEFORE_FUNCTION_EXPRESSION_BODY\", \"AFTER_FUNCTION_DIRECTIVES\", \"BEFORE_ARROW\", \"AFTER_ARROW\", \"AFTER_GET\", \"BEFORE_GET_PARAMS\", \"BEFORE_GET_BODY\", \"AFTER_IF\", \"AFTER_IF_TEST\", \"BEFORE_ELSE\", \"AFTER_ELSE\", \"PARAMETER_BEFORE_COMMA\", \"PARAMETER_AFTER_COMMA\", \"NAMED_IMPORT_BEFORE_COMMA\", \"NAMED_IMPORT_AFTER_COMMA\", \"IMPORT_BEFORE_COMMA\", \"IMPORT_AFTER_COMMA\", \"BEFORE_IMPORT_BINDINGS\", \"BEFORE_IMPORT_MODULE\", \"AFTER_IMPORT_BINDINGS\", \"AFTER_FROM\", \"BEFORE_IMPORT_NAMESPACE\", \"BEFORE_IMPORT_STAR\", \"AFTER_IMPORT_STAR\", \"AFTER_IMPORT_AS\", \"AFTER_NAMESPACE_BINDING\", \"BEFORE_IMPORT_AS\", \"AFTER_IMPORT_AS\", \"EXPORTS_BEFORE_COMMA\", \"EXPORTS_AFTER_COMMA\", \"BEFORE_EXPORT_STAR\", \"AFTER_EXPORT_STAR\", \"BEFORE_EXPORT_BINDINGS\", \"AFTER_EXPORT_BINDINGS\", \"AFTER_EXPORT\", \"EXPORT_DEFAULT\", \"AFTER_EXPORT_DEFAULT\", \"BEFORE_EXPORT_AS\", \"AFTER_EXPORT_AS\", \"BEFORE_LABEL_COLON\", \"AFTER_LABEL_COLON\", \"AFTER_METHOD_GENERATOR_STAR\", \"AFTER_METHOD_NAME\", \"BEFORE_METHOD_BODY\", \"AFTER_MODULE_DIRECTIVES\", \"AFTER_NEW\", \"BEFORE_NEW_ARGS\", \"EMPTY_NEW_CALL\", \"NEW_TARGET_BEFORE_DOT\", \"NEW_TARGET_AFTER_DOT\", \"RETURN\", \"AFTER_SET\", \"BEFORE_SET_PARAMS\", \"BEFORE_SET_BODY\", \"AFTER_SCRIPT_DIRECTIVES\", \"BEFORE_STATIC_MEMBER_DOT\", \"AFTER_STATIC_MEMBER_DOT\", \"BEFORE_CASE_TEST\", \"AFTER_CASE_TEST\", \"BEFORE_CASE_BODY\", \"AFTER_CASE_BODY\", \"DEFAULT\", \"AFTER_DEFAULT_BODY\", \"BEFORE_SWITCH_DISCRIM\", \"BEFORE_SWITCH_BODY\", \"TEMPLATE_TAG\", \"BEFORE_TEMPLATE_EXPRESSION\", \"AFTER_TEMPLATE_EXPRESSION\", \"THROW\", \"AFTER_TRY\", \"BEFORE_CATCH\", \"BEFORE_FINALLY\", \"AFTER_FINALLY\", \"VARIABLE_DECLARATION\", \"YIELD\", \"BEFORE_YIELD_STAR\", \"AFTER_YIELD_STAR\", \"DECLARATORS_BEFORE_COMMA\", \"DECLARATORS_AFTER_COMMA\", \"BEFORE_INIT_EQUALS\", \"AFTER_INIT_EQUALS\", \"AFTER_WHILE\", \"BEFORE_WHILE_BODY\", \"AFTER_WITH\", \"BEFORE_WITH_BODY\", \"PAREN_AVOIDING_DIRECTIVE_BEFORE\", \"PAREN_AVOIDING_DIRECTIVE_AFTER\", \"PRECEDENCE_BEFORE\", \"PRECEDENCE_AFTER\", \"EXPRESSION_PAREN_BEFORE\", \"EXPRESSION_PAREN_AFTER\", \"CALL_PAREN_BEFORE\", \"CALL_PAREN_AFTER\", \"CALL_PAREN_EMPTY\", \"CATCH_PAREN_BEFORE\", \"CATCH_PAREN_AFTER\", \"DO_WHILE_TEST_PAREN_BEFORE\", \"DO_WHILE_TEST_PAREN_AFTER\", \"EXPRESSION_STATEMENT_PAREN_BEFORE\", \"EXPRESSION_STATEMENT_PAREN_AFTER\", \"FOR_IN_LET_PAREN_BEFORE\", \"FOR_IN_LET_PAREN_AFTER\", \"FOR_IN_PAREN_BEFORE\", \"FOR_IN_PAREN_AFTER\", \"FOR_OF_LET_PAREN_BEFORE\", \"FOR_OF_LET_PAREN_AFTER\", \"FOR_OF_PAREN_BEFORE\", \"FOR_OF_PAREN_AFTER\", \"PARAMETERS_PAREN_BEFORE\", \"PARAMETERS_PAREN_AFTER\", \"PARAMETERS_PAREN_EMPTY\", \"ARROW_PARAMETERS_PAREN_BEFORE\", \"ARROW_PARAMETERS_PAREN_AFTER\", \"ARROW_PARAMETERS_PAREN_EMPTY\", \"ARROW_BODY_PAREN_BEFORE\", \"ARROW_BODY_PAREN_AFTER\", \"GETTER_PARAMS\", \"IF_PAREN_BEFORE\", \"IF_PAREN_AFTER\", \"EXPORT_PAREN_BEFORE\", \"EXPORT_PAREN_AFTER\", \"NEW_CALLEE_PAREN_BEFORE\", \"NEW_CALLEE_PAREN_AFTER\", \"NEW_PAREN_BEFORE\", \"NEW_PAREN_AFTER\", \"NEW_PAREN_EMPTY\", \"SETTER_PARAM_BEFORE\", \"SETTER_PARAM_AFTER\", \"SWITCH_DISCRIM_PAREN_BEFORE\", \"SWITCH_DISCRIM_PAREN_AFTER\", \"WHILE_TEST_PAREN_BEFORE\", \"WHILE_TEST_PAREN_AFTER\", \"WITH_PAREN_BEFORE\", \"WITH_PAREN_AFTER\", \"OBJECT_BRACE_INITIAL\", \"OBJECT_BRACE_FINAL\", \"OBJECT_EMPTY\", \"BLOCK_BRACE_INITIAL\", \"BLOCK_BRACE_FINAL\", \"BLOCK_EMPTY\", \"CLASS_BRACE_INITIAL\", \"CLASS_BRACE_FINAL\", \"CLASS_EMPTY\", \"CLASS_EXPRESSION_BRACE_INITIAL\", \"CLASS_EXPRESSION_BRACE_FINAL\", \"CLASS_EXPRESSION_BRACE_EMPTY\", \"FUNCTION_BRACE_INITIAL\", \"FUNCTION_BRACE_FINAL\", \"FUNCTION_EMPTY\", \"FUNCTION_EXPRESSION_BRACE_INITIAL\", \"FUNCTION_EXPRESSION_BRACE_FINAL\", \"FUNCTION_EXPRESSION_EMPTY\", \"ARROW_BRACE_INITIAL\", \"ARROW_BRACE_FINAL\", \"ARROW_BRACE_EMPTY\", \"GET_BRACE_INTIAL\", \"GET_BRACE_FINAL\", \"GET_BRACE_EMPTY\", \"MISSING_ELSE_INTIIAL\", \"MISSING_ELSE_FINAL\", \"MISSING_ELSE_EMPTY\", \"IMPORT_BRACE_INTIAL\", \"IMPORT_BRACE_FINAL\", \"IMPORT_BRACE_EMPTY\", \"EXPORT_BRACE_INITIAL\", \"EXPORT_BRACE_FINAL\", \"EXPORT_BRACE_EMPTY\", \"METHOD_BRACE_INTIAL\", \"METHOD_BRACE_FINAL\", \"METHOD_BRACE_EMPTY\", \"SET_BRACE_INTIIAL\", \"SET_BRACE_FINAL\", \"SET_BRACE_EMPTY\", \"SWITCH_BRACE_INTIAL\", \"SWITCH_BRACE_FINAL\", \"SWITCH_BRACE_EMPTY\", \"ARRAY_INITIAL\", \"ARRAY_FINAL\", \"COMPUTED_MEMBER_BRACKET_INTIAL\", \"COMPUTED_MEMBER_BRACKET_FINAL\", \"COMPUTED_PROPERTY_BRACKET_INTIAL\", \"COMPUTED_PROPERTY_BRACKET_FINAL\"];\n\tfor (var i = 0; i < separatorNames.length; ++i) {\n\t  Sep[separatorNames[i]] = { type: separatorNames[i] };\n\t}\n\n\tSep.BEFORE_ASSIGN_OP = function (op) {\n\t  return {\n\t    type: \"BEFORE_ASSIGN_OP\",\n\t    op: op\n\t  };\n\t};\n\n\tSep.AFTER_ASSIGN_OP = function (op) {\n\t  return {\n\t    type: \"AFTER_ASSIGN_OP\",\n\t    op: op\n\t  };\n\t};\n\n\tSep.BEFORE_BINOP = function (op) {\n\t  return {\n\t    type: \"BEFORE_BINOP\",\n\t    op: op\n\t  };\n\t};\n\n\tSep.AFTER_BINOP = function (op) {\n\t  return {\n\t    type: \"AFTER_BINOP\",\n\t    op: op\n\t  };\n\t};\n\n\tSep.BEFORE_POSTFIX = function (op) {\n\t  return {\n\t    type: \"BEFORE_POSTFIX\",\n\t    op: op\n\t  };\n\t};\n\n\tSep.UNARY = function (op) {\n\t  return {\n\t    type: \"UNARY\",\n\t    op: op\n\t  };\n\t};\n\n\tSep.AFTER_STATEMENT = function (node) {\n\t  return {\n\t    type: \"AFTER_STATEMENT\",\n\t    node: node\n\t  };\n\t};\n\n\tSep.BEFORE_FUNCTION_NAME = function (node) {\n\t  return {\n\t    type: \"BEFORE_FUNCTION_NAME\",\n\t    node: node\n\t  };\n\t};\n\texports.Sep = Sep;\n\n\tvar ExtensibleCodeGen = exports.ExtensibleCodeGen = function () {\n\t  function ExtensibleCodeGen() {\n\t    _classCallCheck(this, ExtensibleCodeGen);\n\t  }\n\n\t  _createClass(ExtensibleCodeGen, [{\n\t    key: \"parenToAvoidBeingDirective\",\n\t    value: function parenToAvoidBeingDirective(element, original) {\n\t      if (element && element.type === \"ExpressionStatement\" && element.expression.type === \"LiteralStringExpression\") {\n\t        return seq(this.paren(original.children[0], Sep.PAREN_AVOIDING_DIRECTIVE_BEFORE, Sep.PAREN_AVOIDING_DIRECTIVE_AFTER), this.semiOp());\n\t      }\n\t      return original;\n\t    }\n\t  }, {\n\t    key: \"t\",\n\t    value: function t(token) {\n\t      return new _coderep.Token(token);\n\t    }\n\t  }, {\n\t    key: \"p\",\n\t    value: function p(node, precedence, a) {\n\t      return (0, _coderep.getPrecedence)(node) < precedence ? this.paren(a, Sep.PRECEDENCE_BEFORE, Sep.PRECEDENCE_AFTER) : a;\n\t    }\n\t  }, {\n\t    key: \"getAssignmentExpr\",\n\t    value: function getAssignmentExpr(state) {\n\t      return state ? state.containsGroup ? this.paren(state, Sep.EXPRESSION_PAREN_BEFORE, Sep.EXPRESSION_PAREN_AFTER) : state : empty();\n\t    }\n\t  }, {\n\t    key: \"paren\",\n\t    value: function paren(rep, first, last, empty) {\n\t      if (isEmpty(rep)) {\n\t        return new _coderep.Paren(this.sep(empty));\n\t      }\n\t      return new _coderep.Paren(seq(first ? this.sep(first) : new _coderep.Empty(), rep, last ? this.sep(last) : new _coderep.Empty()));\n\t    }\n\t  }, {\n\t    key: \"brace\",\n\t    value: function brace(rep, node, first, last, empty) {\n\t      if (isEmpty(rep)) {\n\t        return new _coderep.Brace(this.sep(empty));\n\t      }\n\t      return new _coderep.Brace(seq(this.sep(first), rep, this.sep(last)));\n\t    }\n\t  }, {\n\t    key: \"bracket\",\n\t    value: function bracket(rep, first, last, empty) {\n\t      if (isEmpty(rep)) {\n\t        return new _coderep.Bracket(this.sep(empty));\n\t      }\n\t      return new _coderep.Bracket(seq(this.sep(first), rep, this.sep(last)));\n\t    }\n\t  }, {\n\t    key: \"commaSep\",\n\t    value: function commaSep(pieces, before, after) {\n\t      var _this = this;\n\n\t      var first = true;\n\t      pieces = pieces.map(function (p) {\n\t        if (first) {\n\t          first = false;\n\t          return p;\n\t        } else {\n\t          return seq(_this.sep(before), _this.t(\",\"), _this.sep(after), p);\n\t        }\n\t      });\n\t      return seq.apply(undefined, _toConsumableArray(pieces));\n\t    }\n\t  }, {\n\t    key: \"semiOp\",\n\t    value: function semiOp() {\n\t      return new _coderep.SemiOp();\n\t    }\n\t  }, {\n\t    key: \"sep\",\n\t    value: function sep(kind) {\n\t      return new _coderep.Empty();\n\t    }\n\t  }, {\n\t    key: \"reduceArrayExpression\",\n\t    value: function reduceArrayExpression(node, _ref) {\n\t      var _this2 = this;\n\n\t      var elements = _ref.elements;\n\n\t      if (elements.length === 0) {\n\t        return this.bracket(empty(), null, null, Sep.ARRAY_EMPTY);\n\t      }\n\n\t      var content = this.commaSep(elements.map(function (e) {\n\t        return _this2.getAssignmentExpr(e);\n\t      }), Sep.ARRAY_BEFORE_COMMA, Sep.ARRAY_AFTER_COMMA);\n\t      if (elements.length > 0 && elements[elements.length - 1] == null) {\n\t        content = seq(content, this.sep(Sep.ARRAY_BEFORE_COMMA), this.t(\",\"), this.sep(Sep.ARRAY_AFTER_COMMA));\n\t      }\n\t      return this.bracket(content, Sep.ARRAY_INITIAL, Sep.ARRAY_FINAL);\n\t    }\n\t  }, {\n\t    key: \"reduceSpreadElement\",\n\t    value: function reduceSpreadElement(node, _ref2) {\n\t      var expression = _ref2.expression;\n\n\t      return seq(this.t(\"...\"), this.sep(Sep.SPREAD), this.p(node.expression, _coderep.Precedence.Assignment, expression));\n\t    }\n\t  }, {\n\t    key: \"reduceAssignmentExpression\",\n\t    value: function reduceAssignmentExpression(node, _ref3) {\n\t      var binding = _ref3.binding;\n\t      var expression = _ref3.expression;\n\n\t      var leftCode = binding;\n\t      var rightCode = expression;\n\t      var containsIn = expression.containsIn;\n\t      var startsWithCurly = binding.startsWithCurly;\n\t      var startsWithLetSquareBracket = binding.startsWithLetSquareBracket;\n\t      var startsWithFunctionOrClass = binding.startsWithFunctionOrClass;\n\t      if ((0, _coderep.getPrecedence)(node.expression) < (0, _coderep.getPrecedence)(node)) {\n\t        rightCode = this.paren(rightCode, Sep.EXPRESSION_PAREN_BEFORE, Sep.EXPRESSION_PAREN_AFTER);\n\t        containsIn = false;\n\t      }\n\t      return (0, _objectAssign2.default)(seq(leftCode, this.sep(Sep.BEFORE_ASSIGN_OP(\"=\")), this.t(\"=\"), this.sep(Sep.AFTER_ASSIGN_OP(\"=\")), rightCode), { containsIn: containsIn, startsWithCurly: startsWithCurly, startsWithLetSquareBracket: startsWithLetSquareBracket, startsWithFunctionOrClass: startsWithFunctionOrClass });\n\t    }\n\t  }, {\n\t    key: \"reduceCompoundAssignmentExpression\",\n\t    value: function reduceCompoundAssignmentExpression(node, _ref4) {\n\t      var binding = _ref4.binding;\n\t      var expression = _ref4.expression;\n\n\t      var leftCode = binding;\n\t      var rightCode = expression;\n\t      var containsIn = expression.containsIn;\n\t      var startsWithCurly = binding.startsWithCurly;\n\t      var startsWithLetSquareBracket = binding.startsWithLetSquareBracket;\n\t      var startsWithFunctionOrClass = binding.startsWithFunctionOrClass;\n\t      if ((0, _coderep.getPrecedence)(node.expression) < (0, _coderep.getPrecedence)(node)) {\n\t        rightCode = this.paren(rightCode, Sep.EXPRESSION_PAREN_BEFORE, Sep.EXPRESSION_PAREN_AFTER);\n\t        containsIn = false;\n\t      }\n\t      return (0, _objectAssign2.default)(seq(leftCode, this.sep(Sep.BEFORE_ASSIGN_OP(node.operator)), this.t(node.operator), this.sep(Sep.AFTER_ASSIGN_OP(node.operator)), rightCode), { containsIn: containsIn, startsWithCurly: startsWithCurly, startsWithLetSquareBracket: startsWithLetSquareBracket, startsWithFunctionOrClass: startsWithFunctionOrClass });\n\t    }\n\t  }, {\n\t    key: \"reduceBinaryExpression\",\n\t    value: function reduceBinaryExpression(node, _ref5) {\n\t      var left = _ref5.left;\n\t      var right = _ref5.right;\n\n\t      var leftCode = left;\n\t      var startsWithCurly = left.startsWithCurly;\n\t      var startsWithLetSquareBracket = left.startsWithLetSquareBracket;\n\t      var startsWithFunctionOrClass = left.startsWithFunctionOrClass;\n\t      var leftContainsIn = left.containsIn;\n\t      if ((0, _coderep.getPrecedence)(node.left) < (0, _coderep.getPrecedence)(node)) {\n\t        leftCode = this.paren(leftCode, Sep.EXPRESSION_PAREN_BEFORE, Sep.EXPRESSION_PAREN_AFTER);\n\t        startsWithCurly = false;\n\t        startsWithLetSquareBracket = false;\n\t        startsWithFunctionOrClass = false;\n\t        leftContainsIn = false;\n\t      }\n\t      var rightCode = right;\n\t      var rightContainsIn = right.containsIn;\n\t      if ((0, _coderep.getPrecedence)(node.right) <= (0, _coderep.getPrecedence)(node)) {\n\t        rightCode = this.paren(rightCode, Sep.EXPRESSION_PAREN_BEFORE, Sep.EXPRESSION_PAREN_AFTER);\n\t        rightContainsIn = false;\n\t      }\n\t      return (0, _objectAssign2.default)(seq(leftCode, this.sep(Sep.BEFORE_BINOP(node.operator)), this.t(node.operator), this.sep(Sep.AFTER_BINOP(node.operator)), rightCode), {\n\t        containsIn: leftContainsIn || rightContainsIn || node.operator === \"in\",\n\t        containsGroup: node.operator == \",\",\n\t        startsWithCurly: startsWithCurly,\n\t        startsWithLetSquareBracket: startsWithLetSquareBracket,\n\t        startsWithFunctionOrClass: startsWithFunctionOrClass\n\t      });\n\t    }\n\t  }, {\n\t    key: \"reduceBindingWithDefault\",\n\t    value: function reduceBindingWithDefault(node, _ref6) {\n\t      var binding = _ref6.binding;\n\t      var init = _ref6.init;\n\n\t      return seq(binding, this.sep(Sep.BEFORE_DEFAULT_EQUALS), this.t(\"=\"), this.sep(Sep.AFTER_DEFAULT_EQUALS), init);\n\t    }\n\t  }, {\n\t    key: \"reduceBindingIdentifier\",\n\t    value: function reduceBindingIdentifier(node) {\n\t      var a = this.t(node.name);\n\t      if (node.name === \"let\") {\n\t        a.startsWithLet = true;\n\t      }\n\t      return a;\n\t    }\n\t  }, {\n\t    key: \"reduceArrayBinding\",\n\t    value: function reduceArrayBinding(node, _ref7) {\n\t      var _this3 = this;\n\n\t      var elements = _ref7.elements;\n\t      var restElement = _ref7.restElement;\n\n\t      var content = undefined;\n\t      if (elements.length === 0) {\n\t        content = restElement == null ? empty() : seq(this.t(\"...\"), this.sep(Sep.REST), restElement);\n\t      } else {\n\t        elements = elements.concat(restElement == null ? [] : [seq(this.t(\"...\"), this.sep(Sep.REST), restElement)]);\n\t        content = this.commaSep(elements.map(function (e) {\n\t          return _this3.getAssignmentExpr(e);\n\t        }), Sep.ARRAY_BEFORE_COMMA, Sep.ARRAY_AFTER_COMMA);\n\t        if (elements.length > 0 && elements[elements.length - 1] == null) {\n\t          content = seq(content, this.sep(Sep.ARRAY_BEFORE_COMMA), this.t(\",\"), this.sep(Sep.ARRAY_AFTER_COMMA));\n\t        }\n\t      }\n\t      return this.bracket(content, Sep.ARRAY_INITIAL, Sep.ARRAY_FINAL, Sep.ARRAY_EMPTY);\n\t    }\n\t  }, {\n\t    key: \"reduceObjectBinding\",\n\t    value: function reduceObjectBinding(node, _ref8) {\n\t      var properties = _ref8.properties;\n\n\t      var state = this.brace(this.commaSep(properties, Sep.OBJECT_BEFORE_COMMA, Sep.OBJECT_AFTER_COMMA), node, Sep.OBJECT_BRACE_INITIAL, Sep.OBJECT_BRACE_FINAL, Sep.OBJECT_EMPTY);\n\t      state.startsWithCurly = true;\n\t      return state;\n\t    }\n\t  }, {\n\t    key: \"reduceBindingPropertyIdentifier\",\n\t    value: function reduceBindingPropertyIdentifier(node, _ref9) {\n\t      var binding = _ref9.binding;\n\t      var init = _ref9.init;\n\n\t      if (node.init == null) return binding;\n\t      return seq(binding, this.sep(Sep.BEFORE_DEFAULT_EQUALS), this.t(\"=\"), this.sep(Sep.AFTER_DEFAULT_EQUALS), init);\n\t    }\n\t  }, {\n\t    key: \"reduceBindingPropertyProperty\",\n\t    value: function reduceBindingPropertyProperty(node, _ref10) {\n\t      var name = _ref10.name;\n\t      var binding = _ref10.binding;\n\n\t      return seq(name, this.sep(Sep.BEFORE_PROP), this.t(\":\"), this.sep(Sep.AFTER_PROP), binding);\n\t    }\n\t  }, {\n\t    key: \"reduceBlock\",\n\t    value: function reduceBlock(node, _ref11) {\n\t      var statements = _ref11.statements;\n\n\t      return this.brace(seq.apply(undefined, _toConsumableArray(statements)), node, Sep.BLOCK_BRACE_INITIAL, Sep.BLOCK_BRACE_FINAL, Sep.BLOCK_EMPTY);\n\t    }\n\t  }, {\n\t    key: \"reduceBlockStatement\",\n\t    value: function reduceBlockStatement(node, _ref12) {\n\t      var block = _ref12.block;\n\n\t      return seq(block, this.sep(Sep.AFTER_STATEMENT(node)));\n\t    }\n\t  }, {\n\t    key: \"reduceBreakStatement\",\n\t    value: function reduceBreakStatement(node, _ref13) {\n\t      var label = _ref13.label;\n\n\t      return seq(this.t(\"break\"), label ? seq(this.sep(Sep.BEFORE_JUMP_LABEL), this.t(label)) : empty(), this.semiOp(), this.sep(Sep.AFTER_STATEMENT(node)));\n\t    }\n\t  }, {\n\t    key: \"reduceCallExpression\",\n\t    value: function reduceCallExpression(node, _ref14) {\n\t      var callee = _ref14.callee;\n\t      var args = _ref14.arguments;\n\n\t      return (0, _objectAssign2.default)(seq(this.p(node.callee, (0, _coderep.getPrecedence)(node), callee), this.sep(Sep.CALL), this.paren(this.commaSep(args, Sep.ARGS_BEFORE_COMMA, Sep.ARGS_AFTER_COMMA), Sep.CALL_PAREN_BEFORE, Sep.CALL_PAREN_AFTER, Sep.CALL_PAREN_EMPTY)), {\n\t        startsWithCurly: callee.startsWithCurly,\n\t        startsWithLetSquareBracket: callee.startsWithLetSquareBracket,\n\t        startsWithFunctionOrClass: callee.startsWithFunctionOrClass\n\t      });\n\t    }\n\t  }, {\n\t    key: \"reduceCatchClause\",\n\t    value: function reduceCatchClause(node, _ref15) {\n\t      var binding = _ref15.binding;\n\t      var body = _ref15.body;\n\n\t      return seq(this.t(\"catch\"), this.sep(Sep.BEFORE_CATCH_BINDING), this.paren(binding, Sep.CATCH_PAREN_BEFORE, Sep.CATCH_PAREN_AFTER), this.sep(Sep.AFTER_CATCH_BINDING), body);\n\t    }\n\t  }, {\n\t    key: \"reduceClassDeclaration\",\n\t    value: function reduceClassDeclaration(node, _ref16) {\n\t      var name = _ref16.name;\n\t      var _super = _ref16.super;\n\t      var elements = _ref16.elements;\n\n\t      var state = seq(this.t(\"class\"), this.sep(Sep.BEFORE_CLASS_NAME), name);\n\t      if (_super != null) {\n\t        state = seq(state, this.sep(Sep.BEFORE_EXTENDS), this.t(\"extends\"), this.sep(Sep.AFTER_EXTENDS), _super);\n\t      }\n\t      state = seq(state, this.sep(Sep.BEFORE_CLASS_DECLARATION_ELEMENTS), this.brace(seq.apply(undefined, _toConsumableArray(elements)), node, Sep.CLASS_BRACE_INITIAL, Sep.CLASS_BRACE_FINAL, Sep.CLASS_EMPTY), this.sep(Sep.AFTER_STATEMENT(node)));\n\t      return state;\n\t    }\n\t  }, {\n\t    key: \"reduceClassExpression\",\n\t    value: function reduceClassExpression(node, _ref17) {\n\t      var name = _ref17.name;\n\t      var _super = _ref17.super;\n\t      var elements = _ref17.elements;\n\n\t      var state = this.t(\"class\");\n\t      if (name != null) {\n\t        state = seq(state, this.sep(Sep.BEFORE_CLASS_NAME), name);\n\t      }\n\t      if (_super != null) {\n\t        state = seq(state, this.sep(Sep.BEFORE_EXTENDS), this.t(\"extends\"), this.sep(Sep.AFTER_EXTENDS), _super);\n\t      }\n\t      state = seq(state, this.sep(Sep.BEFORE_CLASS_EXPRESSION_ELEMENTS), this.brace(seq.apply(undefined, _toConsumableArray(elements)), node, Sep.CLASS_EXPRESSION_BRACE_INITIAL, Sep.CLASS_EXPRESSION_BRACE_FINAL, Sep.CLASS_EXPRESSION_BRACE_EMPTY));\n\t      state.startsWithFunctionOrClass = true;\n\t      return state;\n\t    }\n\t  }, {\n\t    key: \"reduceClassElement\",\n\t    value: function reduceClassElement(node, _ref18) {\n\t      var method = _ref18.method;\n\n\t      method = seq(this.sep(Sep.BEFORE_CLASS_ELEMENT), method, this.sep(Sep.AFTER_CLASS_ELEMENT));\n\t      if (!node.isStatic) return method;\n\t      return seq(this.t(\"static\"), this.sep(Sep.AFTER_STATIC), method);\n\t    }\n\t  }, {\n\t    key: \"reduceComputedMemberExpression\",\n\t    value: function reduceComputedMemberExpression(node, _ref19) {\n\t      var object = _ref19.object;\n\t      var expression = _ref19.expression;\n\n\t      var startsWithLetSquareBracket = object.startsWithLetSquareBracket || node.object.type === \"IdentifierExpression\" && node.object.name === \"let\";\n\t      return (0, _objectAssign2.default)(seq(this.p(node.object, (0, _coderep.getPrecedence)(node), object), this.sep(Sep.COMPUTED_MEMBER_EXPRESSION), this.bracket(expression, Sep.COMPUTED_MEMBER_BRACKET_INTIAL, Sep.COMPUTED_MEMBER_BRACKET_FINAL)), {\n\t        startsWithLet: object.startsWithLet,\n\t        startsWithLetSquareBracket: startsWithLetSquareBracket,\n\t        startsWithCurly: object.startsWithCurly,\n\t        startsWithFunctionOrClass: object.startsWithFunctionOrClass\n\t      });\n\t    }\n\t  }, {\n\t    key: \"reduceComputedPropertyName\",\n\t    value: function reduceComputedPropertyName(node, _ref20) {\n\t      var expression = _ref20.expression;\n\n\t      return this.bracket(expression, Sep.COMPUTED_PROPERTY_BRACKET_INTIAL, Sep.COMPUTED_PROPERTY_BRACKET_FINAL);\n\t    }\n\t  }, {\n\t    key: \"reduceConditionalExpression\",\n\t    value: function reduceConditionalExpression(node, _ref21) {\n\t      var test = _ref21.test;\n\t      var consequent = _ref21.consequent;\n\t      var alternate = _ref21.alternate;\n\n\t      var containsIn = test.containsIn || alternate.containsIn;\n\t      var startsWithCurly = test.startsWithCurly;\n\t      var startsWithLetSquareBracket = test.startsWithLetSquareBracket;\n\t      var startsWithFunctionOrClass = test.startsWithFunctionOrClass;\n\t      return (0, _objectAssign2.default)(seq(this.p(node.test, _coderep.Precedence.LogicalOR, test), this.sep(Sep.BEFORE_TERNARY_QUESTION), this.t(\"?\"), this.sep(Sep.AFTER_TERNARY_QUESTION), this.p(node.consequent, _coderep.Precedence.Assignment, consequent), this.sep(Sep.BEFORE_TERNARY_COLON), this.t(\":\"), this.sep(Sep.AFTER_TERNARY_COLON), this.p(node.alternate, _coderep.Precedence.Assignment, alternate)), {\n\t        containsIn: containsIn,\n\t        startsWithCurly: startsWithCurly,\n\t        startsWithLetSquareBracket: startsWithLetSquareBracket,\n\t        startsWithFunctionOrClass: startsWithFunctionOrClass\n\t      });\n\t    }\n\t  }, {\n\t    key: \"reduceContinueStatement\",\n\t    value: function reduceContinueStatement(node, _ref22) {\n\t      var label = _ref22.label;\n\n\t      return seq(this.t(\"continue\"), label ? seq(this.sep(Sep.BEFORE_JUMP_LABEL), this.t(label)) : empty(), this.semiOp(), this.sep(Sep.AFTER_STATEMENT(node)));\n\t    }\n\t  }, {\n\t    key: \"reduceDataProperty\",\n\t    value: function reduceDataProperty(node, _ref23) {\n\t      var name = _ref23.name;\n\t      var expression = _ref23.expression;\n\n\t      return seq(name, this.sep(Sep.BEFORE_PROP), this.t(\":\"), this.sep(Sep.AFTER_PROP), this.getAssignmentExpr(expression));\n\t    }\n\t  }, {\n\t    key: \"reduceDebuggerStatement\",\n\t    value: function reduceDebuggerStatement(node) {\n\t      return seq(this.t(\"debugger\"), this.semiOp(), this.sep(Sep.AFTER_STATEMENT(node)));\n\t    }\n\t  }, {\n\t    key: \"reduceDoWhileStatement\",\n\t    value: function reduceDoWhileStatement(node, _ref24) {\n\t      var body = _ref24.body;\n\t      var test = _ref24.test;\n\n\t      return seq(this.t(\"do\"), this.sep(Sep.AFTER_DO), body, this.sep(Sep.BEFORE_DOWHILE_WHILE), this.t(\"while\"), this.sep(Sep.AFTER_DOWHILE_WHILE), this.paren(test, Sep.DO_WHILE_TEST_PAREN_BEFORE, Sep.DO_WHILE_TEST_PAREN_AFTER), this.semiOp(), this.sep(Sep.AFTER_STATEMENT(node)));\n\t    }\n\t  }, {\n\t    key: \"reduceEmptyStatement\",\n\t    value: function reduceEmptyStatement(node) {\n\t      return seq(this.t(\";\"), this.sep(Sep.AFTER_STATEMENT(node)));\n\t    }\n\t  }, {\n\t    key: \"reduceExpressionStatement\",\n\t    value: function reduceExpressionStatement(node, _ref25) {\n\t      var expression = _ref25.expression;\n\n\t      var needsParens = expression.startsWithCurly || expression.startsWithLetSquareBracket || expression.startsWithFunctionOrClass;\n\t      return seq(needsParens ? this.paren(expression, Sep.EXPRESSION_STATEMENT_PAREN_BEFORE, Sep.EXPRESSION_STATEMENT_PAREN_AFTER) : expression, this.semiOp(), this.sep(Sep.AFTER_STATEMENT(node)));\n\t    }\n\t  }, {\n\t    key: \"reduceForInStatement\",\n\t    value: function reduceForInStatement(node, _ref26) {\n\t      var left = _ref26.left;\n\t      var right = _ref26.right;\n\t      var body = _ref26.body;\n\n\t      var leftP = left;\n\t      switch (node.left.type) {\n\t        case \"VariableDeclaration\":\n\t          leftP = noIn(markContainsIn(left));\n\t          break;\n\t        case \"BindingIdentifier\":\n\t          if (node.left.name === \"let\") {\n\t            leftP = this.paren(left, Sep.FOR_IN_LET_PAREN_BEFORE, Sep.FOR_IN_LET_PAREN_BEFORE);\n\t          }\n\t          break;\n\t      }\n\t      return (0, _objectAssign2.default)(seq(this.t(\"for\"), this.sep(Sep.AFTER_FORIN_FOR), this.paren(seq(leftP, this.sep(Sep.BEFORE_FORIN_IN), this.t(\"in\"), this.sep(Sep.AFTER_FORIN_FOR), right), Sep.FOR_IN_PAREN_BEFORE, Sep.FOR_IN_PAREN_AFTER), this.sep(Sep.BEFORE_FORIN_BODY), body, this.sep(Sep.AFTER_STATEMENT(node))), { endsWithMissingElse: body.endsWithMissingElse });\n\t    }\n\t  }, {\n\t    key: \"reduceForOfStatement\",\n\t    value: function reduceForOfStatement(node, _ref27) {\n\t      var left = _ref27.left;\n\t      var right = _ref27.right;\n\t      var body = _ref27.body;\n\n\t      left = node.left.type === \"VariableDeclaration\" ? noIn(markContainsIn(left)) : left;\n\t      return (0, _objectAssign2.default)(seq(this.t(\"for\"), this.sep(Sep.AFTER_FOROF_FOR), this.paren(seq(left.startsWithLet ? this.paren(left, Sep.FOR_OF_LET_PAREN_BEFORE, Sep.FOR_OF_LET_PAREN_AFTER) : left, this.sep(Sep.BEFORE_FOROF_OF), this.t(\"of\"), this.sep(Sep.AFTER_FOROF_FOR), right), Sep.FOR_OF_PAREN_BEFORE, Sep.FOR_OF_PAREN_AFTER), this.sep(Sep.BEFORE_FOROF_BODY), body, this.sep(Sep.AFTER_STATEMENT(node))), { endsWithMissingElse: body.endsWithMissingElse });\n\t    }\n\t  }, {\n\t    key: \"reduceForStatement\",\n\t    value: function reduceForStatement(node, _ref28) {\n\t      var init = _ref28.init;\n\t      var test = _ref28.test;\n\t      var update = _ref28.update;\n\t      var body = _ref28.body;\n\n\t      return (0, _objectAssign2.default)(seq(this.t(\"for\"), this.sep(Sep.AFTER_FOR_FOR), this.paren(seq(init ? seq(this.sep(Sep.BEFORE_FOR_INIT), noIn(markContainsIn(init)), this.sep(Sep.AFTER_FOR_INIT)) : this.sep(Sep.EMPTY_FOR_INIT), this.t(\";\"), test ? seq(this.sep(Sep.BEFORE_FOR_TEST), test, this.sep(Sep.AFTER_FOR_TEST)) : this.sep(Sep.EMPTY_FOR_TEST), this.t(\";\"), update ? seq(this.sep(Sep.BEFORE_FOR_UPDATE), update, this.sep(Sep.AFTER_FOR_UPDATE)) : this.sep(Sep.EMPTY_FOR_UPDATE))), this.sep(Sep.BEFORE_FOR_BODY), body, this.sep(Sep.AFTER_STATEMENT(node))), {\n\t        endsWithMissingElse: body.endsWithMissingElse\n\t      });\n\t    }\n\t  }, {\n\t    key: \"reduceFunctionBody\",\n\t    value: function reduceFunctionBody(node, _ref29) {\n\t      var directives = _ref29.directives;\n\t      var statements = _ref29.statements;\n\n\t      if (statements.length) {\n\t        statements[0] = this.parenToAvoidBeingDirective(node.statements[0], statements[0]);\n\t      }\n\t      return seq.apply(undefined, _toConsumableArray(directives).concat([directives.length ? this.sep(Sep.AFTER_FUNCTION_DIRECTIVES) : empty()], _toConsumableArray(statements)));\n\t    }\n\t  }, {\n\t    key: \"reduceFunctionDeclaration\",\n\t    value: function reduceFunctionDeclaration(node, _ref30) {\n\t      var name = _ref30.name;\n\t      var params = _ref30.params;\n\t      var body = _ref30.body;\n\n\t      return seq(this.t(\"function\"), node.isGenerator ? seq(this.sep(Sep.BEFORE_GENERATOR_STAR), this.t(\"*\"), this.sep(Sep.AFTER_GENERATOR_STAR)) : empty(), this.sep(Sep.BEFORE_FUNCTION_NAME(node)), node.name.name === \"*default*\" ? empty() : name, this.sep(Sep.BEFORE_FUNCTION_PARAMS), this.paren(params, Sep.PARAMETERS_PAREN_BEFORE, Sep.PARAMETERS_PAREN_AFTER, Sep.PARAMETERS_PAREN_EMPTY), this.sep(Sep.BEFORE_FUNCTION_DECLARATION_BODY), this.brace(body, node, Sep.FUNCTION_BRACE_INITIAL, Sep.FUNCTION_BRACE_FINAL, Sep.FUNCTION_EMPTY), this.sep(Sep.AFTER_STATEMENT(node)));\n\t    }\n\t  }, {\n\t    key: \"reduceFunctionExpression\",\n\t    value: function reduceFunctionExpression(node, _ref31) {\n\t      var name = _ref31.name;\n\t      var params = _ref31.params;\n\t      var body = _ref31.body;\n\n\t      var state = seq(this.t(\"function\"), node.isGenerator ? seq(this.sep(Sep.BEFORE_GENERATOR_STAR), this.t(\"*\"), this.sep(Sep.AFTER_GENERATOR_STAR)) : empty(), this.sep(Sep.BEFORE_FUNCTION_NAME(node)), name ? name : empty(), this.sep(Sep.BEFORE_FUNCTION_PARAMS), this.paren(params, Sep.PARAMETERS_PAREN_BEFORE, Sep.PARAMETERS_PAREN_AFTER, Sep.PARAMETERS_PAREN_EMPTY), this.sep(Sep.BEFORE_FUNCTION_EXPRESSION_BODY), this.brace(body, node, Sep.FUNCTION_EXPRESSION_BRACE_INITIAL, Sep.FUNCTION_EXPRESSION_BRACE_FINAL, Sep.FUNCTION_EXPRESSION_EMPTY));\n\t      state.startsWithFunctionOrClass = true;\n\t      return state;\n\t    }\n\t  }, {\n\t    key: \"reduceFormalParameters\",\n\t    value: function reduceFormalParameters(node, _ref32) {\n\t      var items = _ref32.items;\n\t      var rest = _ref32.rest;\n\n\t      return this.commaSep(items.concat(rest == null ? [] : [seq(this.t(\"...\"), this.sep(Sep.REST), rest)]), Sep.PARAMETER_BEFORE_COMMA, Sep.PARAMETER_AFTER_COMMA);\n\t    }\n\t  }, {\n\t    key: \"reduceArrowExpression\",\n\t    value: function reduceArrowExpression(node, _ref33) {\n\t      var params = _ref33.params;\n\t      var body = _ref33.body;\n\n\t      if (node.params.rest != null || node.params.items.length !== 1 || node.params.items[0].type !== \"BindingIdentifier\") {\n\t        params = this.paren(params, Sep.ARROW_PARAMETERS_PAREN_BEFORE, Sep.ARROW_PARAMETERS_PAREN_AFTER, Sep.ARROW_PARAMETERS_PAREN_EMPTY);\n\t      }\n\t      if (node.body.type === \"FunctionBody\") {\n\t        body = this.brace(body, node, Sep.ARROW_BRACE_INITIAL, Sep.ARROW_BRACE_FINAL, Sep.ARROW_BRACE_EMPTY);\n\t      } else if (body.startsWithCurly) {\n\t        body = this.paren(body, Sep.ARROW_BODY_PAREN_BEFORE, Sep.ARROW_BODY_PAREN_AFTER);\n\t      }\n\t      return seq(params, this.sep(Sep.BEFORE_ARROW), this.t(\"=>\"), this.sep(Sep.AFTER_ARROW), this.p(node.body, _coderep.Precedence.Assignment, body));\n\t    }\n\t  }, {\n\t    key: \"reduceGetter\",\n\t    value: function reduceGetter(node, _ref34) {\n\t      var name = _ref34.name;\n\t      var body = _ref34.body;\n\n\t      return seq(this.t(\"get\"), this.sep(Sep.AFTER_GET), name, this.sep(Sep.BEFORE_GET_PARAMS), this.paren(empty(), null, null, Sep.GETTER_PARAMS), this.sep(Sep.BEFORE_GET_BODY), this.brace(body, node, Sep.GET_BRACE_INTIAL, Sep.GET_BRACE_FINAL, Sep.GET_BRACE_EMPTY));\n\t    }\n\t  }, {\n\t    key: \"reduceIdentifierExpression\",\n\t    value: function reduceIdentifierExpression(node) {\n\t      var a = this.t(node.name);\n\t      if (node.name === \"let\") {\n\t        a.startsWithLet = true;\n\t      }\n\t      return a;\n\t    }\n\t  }, {\n\t    key: \"reduceIfStatement\",\n\t    value: function reduceIfStatement(node, _ref35) {\n\t      var test = _ref35.test;\n\t      var consequent = _ref35.consequent;\n\t      var alternate = _ref35.alternate;\n\n\t      if (alternate && consequent.endsWithMissingElse) {\n\t        consequent = this.brace(consequent, node, Sep.MISSING_ELSE_INTIIAL, Sep.MISSING_ELSE_FINAL, Sep.MISSING_ELSE_EMPTY);\n\t      }\n\t      return (0, _objectAssign2.default)(seq(this.t(\"if\"), this.sep(Sep.AFTER_IF), this.paren(test, Sep.IF_PAREN_BEFORE, Sep.IF_PAREN_AFTER), this.sep(Sep.AFTER_IF_TEST), consequent, alternate ? seq(this.sep(Sep.BEFORE_ELSE), this.t(\"else\"), this.sep(Sep.AFTER_ELSE), alternate) : empty(), this.sep(Sep.AFTER_STATEMENT(node))), { endsWithMissingElse: alternate ? alternate.endsWithMissingElse : true });\n\t    }\n\t  }, {\n\t    key: \"reduceImport\",\n\t    value: function reduceImport(node, _ref36) {\n\t      var defaultBinding = _ref36.defaultBinding;\n\t      var namedImports = _ref36.namedImports;\n\n\t      var bindings = [];\n\t      if (defaultBinding != null) {\n\t        bindings.push(defaultBinding);\n\t      }\n\t      if (namedImports.length > 0) {\n\t        bindings.push(this.brace(this.commaSep(namedImports, Sep.NAMED_IMPORT_BEFORE_COMMA, Sep.NAMED_IMPORT_AFTER_COMMA), node, Sep.IMPORT_BRACE_INTIAL, Sep.IMPORT_BRACE_FINAL, Sep.IMPORT_BRACE_EMPTY));\n\t      }\n\t      if (bindings.length === 0) {\n\t        return seq(this.t(\"import\"), this.sep(Sep.BEFORE_IMPORT_MODULE), this.t((0, _coderep.escapeStringLiteral)(node.moduleSpecifier)), this.semiOp(), this.sep(Sep.AFTER_STATEMENT(node)));\n\t      }\n\t      return seq(this.t(\"import\"), this.sep(Sep.BEFORE_IMPORT_BINDINGS), this.commaSep(bindings, Sep.IMPORT_BEFORE_COMMA, Sep.IMPORT_AFTER_COMMA), this.sep(Sep.AFTER_IMPORT_BINDINGS), this.t(\"from\"), this.sep(Sep.AFTER_FROM), this.t((0, _coderep.escapeStringLiteral)(node.moduleSpecifier)), this.semiOp(), this.sep(Sep.AFTER_STATEMENT(node)));\n\t    }\n\t  }, {\n\t    key: \"reduceImportNamespace\",\n\t    value: function reduceImportNamespace(node, _ref37) {\n\t      var defaultBinding = _ref37.defaultBinding;\n\t      var namespaceBinding = _ref37.namespaceBinding;\n\n\t      return seq(this.t(\"import\"), this.sep(Sep.BEFORE_IMPORT_NAMESPACE), defaultBinding == null ? empty() : seq(defaultBinding, this.sep(Sep.IMPORT_BEFORE_COMMA), this.t(\",\"), this.sep(Sep.IMPORT_AFTER_COMMA)), this.sep(Sep.BEFORE_IMPORT_STAR), this.t(\"*\"), this.sep(Sep.AFTER_IMPORT_STAR), this.t(\"as\"), this.sep(Sep.AFTER_IMPORT_AS), namespaceBinding, this.sep(Sep.AFTER_NAMESPACE_BINDING), this.t(\"from\"), this.sep(Sep.AFTER_FROM), this.t((0, _coderep.escapeStringLiteral)(node.moduleSpecifier)), this.semiOp(), this.sep(Sep.AFTER_STATEMENT(node)));\n\t    }\n\t  }, {\n\t    key: \"reduceImportSpecifier\",\n\t    value: function reduceImportSpecifier(node, _ref38) {\n\t      var binding = _ref38.binding;\n\n\t      if (node.name == null) return binding;\n\t      return seq(this.t(node.name), this.sep(Sep.BEFORE_IMPORT_AS), this.t(\"as\"), this.sep(Sep.AFTER_IMPORT_AS), binding);\n\t    }\n\t  }, {\n\t    key: \"reduceExportAllFrom\",\n\t    value: function reduceExportAllFrom(node) {\n\t      return seq(this.t(\"export\"), this.sep(Sep.BEFORE_EXPORT_STAR), this.t(\"*\"), this.sep(Sep.AFTER_EXPORT_STAR), this.t(\"from\"), this.sep(Sep.AFTER_FROM), this.t((0, _coderep.escapeStringLiteral)(node.moduleSpecifier)), this.semiOp(), this.sep(Sep.AFTER_STATEMENT(node)));\n\t    }\n\t  }, {\n\t    key: \"reduceExportFrom\",\n\t    value: function reduceExportFrom(node, _ref39) {\n\t      var namedExports = _ref39.namedExports;\n\n\t      return seq(this.t(\"export\"), this.sep(Sep.BEFORE_EXPORT_BINDINGS), this.brace(this.commaSep(namedExports, Sep.EXPORTS_BEFORE_COMMA, Sep.EXPORTS_AFTER_COMMA), node, Sep.EXPORT_BRACE_INITIAL, Sep.EXPORT_BRACE_FINAL, Sep.EXPORT_BRACE_EMPTY), node.moduleSpecifier == null ? empty() : seq(this.sep(Sep.AFTER_EXPORT_BINDINGS), this.t(\"from\"), this.sep(Sep.AFTER_FROM), this.t((0, _coderep.escapeStringLiteral)(node.moduleSpecifier)), this.semiOp(), this.sep(Sep.AFTER_STATEMENT(node))));\n\t    }\n\t  }, {\n\t    key: \"reduceExport\",\n\t    value: function reduceExport(node, _ref40) {\n\t      var declaration = _ref40.declaration;\n\n\t      switch (node.declaration.type) {\n\t        case \"FunctionDeclaration\":\n\t        case \"ClassDeclaration\":\n\t          break;\n\t        default:\n\t          declaration = seq(declaration, this.semiOp(), this.sep(Sep.AFTER_STATEMENT(node)));\n\t      }\n\t      return seq(this.t(\"export\"), this.sep(Sep.AFTER_EXPORT), declaration);\n\t    }\n\t  }, {\n\t    key: \"reduceExportDefault\",\n\t    value: function reduceExportDefault(node, _ref41) {\n\t      var body = _ref41.body;\n\n\t      body = body.startsWithFunctionOrClass ? this.paren(body, Sep.EXPORT_PAREN_BEFORE, Sep.EXPORT_PAREN_AFTER) : body;\n\t      switch (node.body.type) {\n\t        case \"FunctionDeclaration\":\n\t        case \"ClassDeclaration\":\n\t          break;\n\t        default:\n\t          body = seq(body, this.semiOp(), this.sep(Sep.AFTER_STATEMENT(node)));\n\t      }\n\t      return seq(this.t(\"export\"), this.sep(Sep.EXPORT_DEFAULT), this.t(\"default\"), this.sep(Sep.AFTER_EXPORT_DEFAULT), body);\n\t    }\n\t  }, {\n\t    key: \"reduceExportSpecifier\",\n\t    value: function reduceExportSpecifier(node) {\n\t      if (node.name == null) return this.t(node.exportedName);\n\t      return seq(this.t(node.name), this.sep(Sep.BEFORE_EXPORT_AS), this.t(\"as\"), this.sep(Sep.AFTER_EXPORT_AS), this.t(node.exportedName));\n\t    }\n\t  }, {\n\t    key: \"reduceLabeledStatement\",\n\t    value: function reduceLabeledStatement(node, _ref42) {\n\t      var label = _ref42.label;\n\t      var body = _ref42.body;\n\n\t      return (0, _objectAssign2.default)(seq(this.t(label), this.sep(Sep.BEFORE_LABEL_COLON), this.t(\":\"), this.sep(Sep.AFTER_LABEL_COLON), body), { endsWithMissingElse: body.endsWithMissingElse });\n\t    }\n\t  }, {\n\t    key: \"reduceLiteralBooleanExpression\",\n\t    value: function reduceLiteralBooleanExpression(node) {\n\t      return this.t(node.value.toString());\n\t    }\n\t  }, {\n\t    key: \"reduceLiteralNullExpression\",\n\t    value: function reduceLiteralNullExpression(node) {\n\t      return this.t(\"null\");\n\t    }\n\t  }, {\n\t    key: \"reduceLiteralInfinityExpression\",\n\t    value: function reduceLiteralInfinityExpression(node) {\n\t      return this.t(\"2e308\");\n\t    }\n\t  }, {\n\t    key: \"reduceLiteralNumericExpression\",\n\t    value: function reduceLiteralNumericExpression(node) {\n\t      return new _coderep.NumberCodeRep(node.value);\n\t    }\n\t  }, {\n\t    key: \"reduceLiteralRegExpExpression\",\n\t    value: function reduceLiteralRegExpExpression(node) {\n\t      return this.t(\"/\" + node.pattern + \"/\" + node.flags);\n\t    }\n\t  }, {\n\t    key: \"reduceLiteralStringExpression\",\n\t    value: function reduceLiteralStringExpression(node) {\n\t      return this.t((0, _coderep.escapeStringLiteral)(node.value));\n\t    }\n\t  }, {\n\t    key: \"reduceMethod\",\n\t    value: function reduceMethod(node, _ref43) {\n\t      var name = _ref43.name;\n\t      var params = _ref43.params;\n\t      var body = _ref43.body;\n\n\t      return seq(node.isGenerator ? seq(this.t(\"*\"), this.sep(Sep.AFTER_METHOD_GENERATOR_STAR)) : empty(), name, this.sep(Sep.AFTER_METHOD_NAME), this.paren(params, Sep.PARAMETERS_PAREN_BEFORE, Sep.PARAMETERS_PAREN_AFTER, Sep.PARAMETERS_PAREN_EMPTY), this.sep(Sep.BEFORE_METHOD_BODY), this.brace(body, node, Sep.METHOD_BRACE_INTIAL, Sep.METHOD_BRACE_FINAL, Sep.METHOD_BRACE_EMPTY));\n\t    }\n\t  }, {\n\t    key: \"reduceModule\",\n\t    value: function reduceModule(node, _ref44) {\n\t      var directives = _ref44.directives;\n\t      var items = _ref44.items;\n\n\t      if (items.length) {\n\t        items[0] = this.parenToAvoidBeingDirective(node.items[0], items[0]);\n\t      }\n\t      return seq.apply(undefined, _toConsumableArray(directives).concat([directives.length ? this.sep(Sep.AFTER_MODULE_DIRECTIVES) : empty()], _toConsumableArray(items)));\n\t    }\n\t  }, {\n\t    key: \"reduceNewExpression\",\n\t    value: function reduceNewExpression(node, _ref45) {\n\t      var callee = _ref45.callee;\n\t      var args = _ref45.arguments;\n\n\t      var calleeRep = (0, _coderep.getPrecedence)(node.callee) == _coderep.Precedence.Call ? this.paren(callee, Sep.NEW_CALLEE_PAREN_BEFORE, Sep.NEW_CALLEE_PAREN_AFTER) : this.p(node.callee, (0, _coderep.getPrecedence)(node), callee);\n\t      return seq(this.t(\"new\"), this.sep(Sep.AFTER_NEW), calleeRep, args.length === 0 ? this.sep(Sep.EMPTY_NEW_CALL) : seq(this.sep(Sep.BEFORE_NEW_ARGS), this.paren(this.commaSep(args, Sep.ARGS_BEFORE_COMMA, Sep.ARGS_AFTER_COMMA), Sep.NEW_PAREN_BEFORE, Sep.NEW_PAREN_AFTER, Sep.NEW_PAREN_EMPTY)));\n\t    }\n\t  }, {\n\t    key: \"reduceNewTargetExpression\",\n\t    value: function reduceNewTargetExpression() {\n\t      return seq(this.t(\"new\"), this.sep(Sep.NEW_TARGET_BEFORE_DOT), this.t(\".\"), this.sep(Sep.NEW_TARGET_AFTER_DOT), this.t(\"target\"));\n\t    }\n\t  }, {\n\t    key: \"reduceObjectExpression\",\n\t    value: function reduceObjectExpression(node, _ref46) {\n\t      var properties = _ref46.properties;\n\n\t      var state = this.brace(this.commaSep(properties, Sep.OBJECT_BEFORE_COMMA, Sep.OBJECT_AFTER_COMMA), node, Sep.OBJECT_BRACE_INITIAL, Sep.OBJECT_BRACE_FINAL, Sep.OBJECT_EMPTY);\n\t      state.startsWithCurly = true;\n\t      return state;\n\t    }\n\t  }, {\n\t    key: \"reduceUpdateExpression\",\n\t    value: function reduceUpdateExpression(node, _ref47) {\n\t      var operand = _ref47.operand;\n\n\t      if (node.isPrefix) {\n\t        return this.reduceUnaryExpression.apply(this, arguments);\n\t      } else {\n\t        return (0, _objectAssign2.default)(seq(this.p(node.operand, _coderep.Precedence.New, operand), this.sep(Sep.BEFORE_POSTFIX(node.operator)), this.t(node.operator)), {\n\t          startsWithCurly: operand.startsWithCurly,\n\t          startsWithLetSquareBracket: operand.startsWithLetSquareBracket,\n\t          startsWithFunctionOrClass: operand.startsWithFunctionOrClass\n\t        });\n\t      }\n\t    }\n\t  }, {\n\t    key: \"reduceUnaryExpression\",\n\t    value: function reduceUnaryExpression(node, _ref48) {\n\t      var operand = _ref48.operand;\n\n\t      return seq(this.t(node.operator), this.sep(Sep.UNARY(node.operator)), this.p(node.operand, (0, _coderep.getPrecedence)(node), operand));\n\t    }\n\t  }, {\n\t    key: \"reduceReturnStatement\",\n\t    value: function reduceReturnStatement(node, _ref49) {\n\t      var expression = _ref49.expression;\n\n\t      return seq(this.t(\"return\"), expression ? seq(this.sep(Sep.RETURN), expression) : empty(), this.semiOp(), this.sep(Sep.AFTER_STATEMENT(node)));\n\t    }\n\t  }, {\n\t    key: \"reduceScript\",\n\t    value: function reduceScript(node, _ref50) {\n\t      var directives = _ref50.directives;\n\t      var statements = _ref50.statements;\n\n\t      if (statements.length) {\n\t        statements[0] = this.parenToAvoidBeingDirective(node.statements[0], statements[0]);\n\t      }\n\t      return seq.apply(undefined, _toConsumableArray(directives).concat([directives.length ? this.sep(Sep.AFTER_SCRIPT_DIRECTIVES) : empty()], _toConsumableArray(statements)));\n\t    }\n\t  }, {\n\t    key: \"reduceSetter\",\n\t    value: function reduceSetter(node, _ref51) {\n\t      var name = _ref51.name;\n\t      var param = _ref51.param;\n\t      var body = _ref51.body;\n\n\t      return seq(this.t(\"set\"), this.sep(Sep.AFTER_SET), name, this.sep(Sep.BEFORE_SET_PARAMS), this.paren(param, Sep.SETTER_PARAM_BEFORE, Sep.SETTER_PARAM_AFTER), this.sep(Sep.BEFORE_SET_BODY), this.brace(body, node, Sep.SET_BRACE_INTIIAL, Sep.SET_BRACE_FINAL, Sep.SET_BRACE_EMPTY));\n\t    }\n\t  }, {\n\t    key: \"reduceShorthandProperty\",\n\t    value: function reduceShorthandProperty(node) {\n\t      return this.t(node.name);\n\t    }\n\t  }, {\n\t    key: \"reduceStaticMemberExpression\",\n\t    value: function reduceStaticMemberExpression(node, _ref52) {\n\t      var object = _ref52.object;\n\t      var property = _ref52.property;\n\n\t      var state = seq(this.p(node.object, (0, _coderep.getPrecedence)(node), object), this.sep(Sep.BEFORE_STATIC_MEMBER_DOT), this.t(\".\"), this.sep(Sep.AFTER_STATIC_MEMBER_DOT), this.t(property));\n\t      state.startsWithLet = object.startsWithLet;\n\t      state.startsWithCurly = object.startsWithCurly;\n\t      state.startsWithLetSquareBracket = object.startsWithLetSquareBracket;\n\t      state.startsWithFunctionOrClass = object.startsWithFunctionOrClass;\n\t      return state;\n\t    }\n\t  }, {\n\t    key: \"reduceStaticPropertyName\",\n\t    value: function reduceStaticPropertyName(node) {\n\t      var n;\n\t      if (_esutils.keyword.isIdentifierNameES6(node.value)) {\n\t        return this.t(node.value);\n\t      } else if (n = parseFloat(node.value), n === n) {\n\t        return new _coderep.NumberCodeRep(n);\n\t      }\n\t      return this.t((0, _coderep.escapeStringLiteral)(node.value));\n\t    }\n\t  }, {\n\t    key: \"reduceSuper\",\n\t    value: function reduceSuper() {\n\t      return this.t(\"super\");\n\t    }\n\t  }, {\n\t    key: \"reduceSwitchCase\",\n\t    value: function reduceSwitchCase(node, _ref53) {\n\t      var test = _ref53.test;\n\t      var consequent = _ref53.consequent;\n\n\t      return seq(this.t(\"case\"), this.sep(Sep.BEFORE_CASE_TEST), test, this.sep(Sep.AFTER_CASE_TEST), this.t(\":\"), this.sep(Sep.BEFORE_CASE_BODY), seq.apply(undefined, _toConsumableArray(consequent)), this.sep(Sep.AFTER_CASE_BODY));\n\t    }\n\t  }, {\n\t    key: \"reduceSwitchDefault\",\n\t    value: function reduceSwitchDefault(node, _ref54) {\n\t      var consequent = _ref54.consequent;\n\n\t      return seq(this.t(\"default\"), this.sep(Sep.DEFAULT), this.t(\":\"), this.sep(Sep.BEFORE_CASE_BODY), seq.apply(undefined, _toConsumableArray(consequent)), this.sep(Sep.AFTER_DEFAULT_BODY));\n\t    }\n\t  }, {\n\t    key: \"reduceSwitchStatement\",\n\t    value: function reduceSwitchStatement(node, _ref55) {\n\t      var discriminant = _ref55.discriminant;\n\t      var cases = _ref55.cases;\n\n\t      return seq(this.t(\"switch\"), this.sep(Sep.BEFORE_SWITCH_DISCRIM), this.paren(discriminant, Sep.SWITCH_DISCRIM_PAREN_BEFORE, Sep.SWITCH_DISCRIM_PAREN_AFTER), this.sep(Sep.BEFORE_SWITCH_BODY), this.brace(seq.apply(undefined, _toConsumableArray(cases)), node, Sep.SWITCH_BRACE_INTIAL, Sep.SWITCH_BRACE_FINAL, Sep.SWITCH_BRACE_EMPTY), this.sep(Sep.AFTER_STATEMENT(node)));\n\t    }\n\t  }, {\n\t    key: \"reduceSwitchStatementWithDefault\",\n\t    value: function reduceSwitchStatementWithDefault(node, _ref56) {\n\t      var discriminant = _ref56.discriminant;\n\t      var preDefaultCases = _ref56.preDefaultCases;\n\t      var defaultCase = _ref56.defaultCase;\n\t      var postDefaultCases = _ref56.postDefaultCases;\n\n\t      return seq(this.t(\"switch\"), this.sep(Sep.BEFORE_SWITCH_DISCRIM), this.paren(discriminant, Sep.SWITCH_DISCRIM_PAREN_BEFORE, Sep.SWITCH_DISCRIM_PAREN_AFTER), this.sep(Sep.BEFORE_SWITCH_BODY), this.brace(seq.apply(undefined, _toConsumableArray(preDefaultCases).concat([defaultCase], _toConsumableArray(postDefaultCases))), node, Sep.SWITCH_BRACE_INTIAL, Sep.SWITCH_BRACE_FINAL, Sep.SWITCH_BRACE_EMPTY), this.sep(Sep.AFTER_STATEMENT(node)));\n\t    }\n\t  }, {\n\t    key: \"reduceTemplateExpression\",\n\t    value: function reduceTemplateExpression(node, _ref57) {\n\t      var tag = _ref57.tag;\n\t      var elements = _ref57.elements;\n\n\t      var state = node.tag == null ? empty() : seq(this.p(node.tag, (0, _coderep.getPrecedence)(node), tag), this.sep(Sep.TEMPLATE_TAG));\n\t      var templateData = \"\";\n\t      state = seq(state, this.t(\"`\"));\n\t      for (var i = 0, l = node.elements.length; i < l; ++i) {\n\t        if (node.elements[i].type === \"TemplateElement\") {\n\t          var d = \"\";\n\t          if (i > 0) d += \"}\";\n\t          d += node.elements[i].rawValue;\n\t          if (i < l - 1) d += \"${\";\n\t          state = seq(state, this.t(d));\n\t        } else {\n\t          state = seq(state, this.sep(Sep.BEFORE_TEMPLATE_EXPRESSION), elements[i], this.sep(Sep.AFTER_TEMPLATE_EXPRESSION));\n\t        }\n\t      }\n\t      state = seq(state, this.t(\"`\"));\n\t      if (node.tag != null) {\n\t        state.startsWithCurly = tag.startsWithCurly;\n\t        state.startsWithLetSquareBracket = tag.startsWithLetSquareBracket;\n\t        state.startsWithFunctionOrClass = tag.startsWithFunctionOrClass;\n\t      }\n\t      return state;\n\t    }\n\t  }, {\n\t    key: \"reduceTemplateElement\",\n\t    value: function reduceTemplateElement(node) {\n\t      return this.t(node.rawValue);\n\t    }\n\t  }, {\n\t    key: \"reduceThisExpression\",\n\t    value: function reduceThisExpression(node) {\n\t      return this.t(\"this\");\n\t    }\n\t  }, {\n\t    key: \"reduceThrowStatement\",\n\t    value: function reduceThrowStatement(node, _ref58) {\n\t      var expression = _ref58.expression;\n\n\t      return seq(this.t(\"throw\"), this.sep(Sep.THROW), expression, this.semiOp(), this.sep(Sep.AFTER_STATEMENT(node)));\n\t    }\n\t  }, {\n\t    key: \"reduceTryCatchStatement\",\n\t    value: function reduceTryCatchStatement(node, _ref59) {\n\t      var body = _ref59.body;\n\t      var catchClause = _ref59.catchClause;\n\n\t      return seq(this.t(\"try\"), this.sep(Sep.AFTER_TRY), body, this.sep(Sep.BEFORE_CATCH), catchClause, this.sep(Sep.AFTER_STATEMENT(node)));\n\t    }\n\t  }, {\n\t    key: \"reduceTryFinallyStatement\",\n\t    value: function reduceTryFinallyStatement(node, _ref60) {\n\t      var body = _ref60.body;\n\t      var catchClause = _ref60.catchClause;\n\t      var finalizer = _ref60.finalizer;\n\n\t      return seq(this.t(\"try\"), this.sep(Sep.AFTER_TRY), body, catchClause ? seq(this.sep(Sep.BEFORE_CATCH), catchClause) : empty(), this.sep(Sep.BEFORE_FINALLY), this.t(\"finally\"), this.sep(Sep.AFTER_FINALLY), finalizer, this.sep(Sep.AFTER_STATEMENT(node)));\n\t    }\n\t  }, {\n\t    key: \"reduceYieldExpression\",\n\t    value: function reduceYieldExpression(node, _ref61) {\n\t      var expression = _ref61.expression;\n\n\t      if (node.expression == null) return this.t(\"yield\");\n\t      return seq(this.t(\"yield\"), this.sep(Sep.YIELD), this.p(node.expression, (0, _coderep.getPrecedence)(node), expression));\n\t    }\n\t  }, {\n\t    key: \"reduceYieldGeneratorExpression\",\n\t    value: function reduceYieldGeneratorExpression(node, _ref62) {\n\t      var expression = _ref62.expression;\n\n\t      return seq(this.t(\"yield\"), this.sep(Sep.BEFORE_YIELD_STAR), this.t(\"*\"), this.sep(Sep.AFTER_YIELD_STAR), this.p(node.expression, (0, _coderep.getPrecedence)(node), expression));\n\t    }\n\t  }, {\n\t    key: \"reduceDirective\",\n\t    value: function reduceDirective(node) {\n\t      var delim = /^(?:[^\"\\\\]|\\\\.)*$/.test(node.rawValue) ? \"\\\"\" : \"'\";\n\t      return seq(this.t(delim + node.rawValue + delim), this.semiOp(), this.sep(Sep.AFTER_STATEMENT(node)));\n\t    }\n\t  }, {\n\t    key: \"reduceVariableDeclaration\",\n\t    value: function reduceVariableDeclaration(node, _ref63) {\n\t      var declarators = _ref63.declarators;\n\n\t      return seq(this.t(node.kind), this.sep(Sep.VARIABLE_DECLARATION), this.commaSep(declarators, Sep.DECLARATORS_BEFORE_COMMA, Sep.DECLARATORS_AFTER_COMMA));\n\t    }\n\t  }, {\n\t    key: \"reduceVariableDeclarationStatement\",\n\t    value: function reduceVariableDeclarationStatement(node, _ref64) {\n\t      var declaration = _ref64.declaration;\n\n\t      return seq(declaration, this.semiOp(), this.sep(Sep.AFTER_STATEMENT(node)));\n\t    }\n\t  }, {\n\t    key: \"reduceVariableDeclarator\",\n\t    value: function reduceVariableDeclarator(node, _ref65) {\n\t      var binding = _ref65.binding;\n\t      var init = _ref65.init;\n\n\t      var containsIn = init && init.containsIn && !init.containsGroup;\n\t      if (init) {\n\t        if (init.containsGroup) {\n\t          init = this.paren(init, Sep.EXPRESSION_PAREN_BEFORE, Sep.EXPRESSION_PAREN_AFTER);\n\t        } else {\n\t          init = markContainsIn(init);\n\t        }\n\t      }\n\t      return (0, _objectAssign2.default)(init == null ? binding : seq(binding, this.sep(Sep.BEFORE_INIT_EQUALS), this.t(\"=\"), this.sep(Sep.AFTER_INIT_EQUALS), init), { containsIn: containsIn });\n\t    }\n\t  }, {\n\t    key: \"reduceWhileStatement\",\n\t    value: function reduceWhileStatement(node, _ref66) {\n\t      var test = _ref66.test;\n\t      var body = _ref66.body;\n\n\t      return (0, _objectAssign2.default)(seq(this.t(\"while\"), this.sep(Sep.AFTER_WHILE), this.paren(test, Sep.WHILE_TEST_PAREN_BEFORE, Sep.WHILE_TEST_PAREN_AFTER), this.sep(Sep.BEFORE_WHILE_BODY), body, this.sep(Sep.AFTER_STATEMENT(node))), { endsWithMissingElse: body.endsWithMissingElse });\n\t    }\n\t  }, {\n\t    key: \"reduceWithStatement\",\n\t    value: function reduceWithStatement(node, _ref67) {\n\t      var object = _ref67.object;\n\t      var body = _ref67.body;\n\n\t      return (0, _objectAssign2.default)(seq(this.t(\"with\"), this.sep(Sep.AFTER_WITH), this.paren(object, Sep.WITH_PAREN_BEFORE, Sep.WITH_PAREN_AFTER), this.sep(Sep.BEFORE_WITH_BODY), body, this.sep(Sep.AFTER_STATEMENT(node))), { endsWithMissingElse: body.endsWithMissingElse });\n\t    }\n\t  }]);\n\n\t  return ExtensibleCodeGen;\n\t}();\n\n\tvar INDENT = \"  \";\n\n\tvar Linebreak = function (_CodeRep) {\n\t  _inherits(Linebreak, _CodeRep);\n\n\t  function Linebreak() {\n\t    _classCallCheck(this, Linebreak);\n\n\t    var _this4 = _possibleConstructorReturn(this, Object.getPrototypeOf(Linebreak).call(this));\n\n\t    _this4.indentation = 0;\n\t    return _this4;\n\t  }\n\n\t  _createClass(Linebreak, [{\n\t    key: \"emit\",\n\t    value: function emit(ts) {\n\t      ts.put(\"\\n\");\n\t      for (var i = 0; i < this.indentation; ++i) {\n\t        ts.put(INDENT);\n\t      }\n\t    }\n\t  }]);\n\n\t  return Linebreak;\n\t}(_coderep.CodeRep);\n\n\tfunction withoutTrailingLinebreak(state) {\n\t  if (state && state instanceof _coderep.Seq) {\n\t    var lastChild = state.children[state.children.length - 1];\n\t    /* istanbul ignore next */\n\t    while (lastChild instanceof _coderep.Empty) {\n\t      state.children.pop();\n\t      lastChild = state.children[state.children.length - 1];\n\t    }\n\t    /* istanbul ignore else */\n\t    if (lastChild instanceof _coderep.Seq) {\n\t      withoutTrailingLinebreak(lastChild);\n\t    } else if (lastChild instanceof Linebreak) {\n\t      state.children.pop();\n\t    }\n\t  }\n\t  return state;\n\t}\n\n\tfunction indent(rep, includingFinal) {\n\t  var finalLinebreak = undefined;\n\t  function indentNode(node) {\n\t    if (node instanceof Linebreak) {\n\t      finalLinebreak = node;\n\t      ++node.indentation;\n\t    }\n\t  }\n\t  rep.forEach(indentNode);\n\t  if (!includingFinal) {\n\t    --finalLinebreak.indentation;\n\t  }\n\t  return rep;\n\t}\n\n\tvar FormattedCodeGen = exports.FormattedCodeGen = function (_ExtensibleCodeGen) {\n\t  _inherits(FormattedCodeGen, _ExtensibleCodeGen);\n\n\t  function FormattedCodeGen() {\n\t    _classCallCheck(this, FormattedCodeGen);\n\n\t    return _possibleConstructorReturn(this, Object.getPrototypeOf(FormattedCodeGen).apply(this, arguments));\n\t  }\n\n\t  _createClass(FormattedCodeGen, [{\n\t    key: \"parenToAvoidBeingDirective\",\n\t    value: function parenToAvoidBeingDirective(element, original) {\n\t      if (element && element.type === \"ExpressionStatement\" && element.expression.type === \"LiteralStringExpression\") {\n\t        return seq(this.paren(original.children[0], Sep.PAREN_AVOIDING_DIRECTIVE_BEFORE, Sep.PAREN_AVOIDING_DIRECTIVE_AFTER), this.semiOp(), this.sep(Sep.AFTER_STATEMENT(element)));\n\t      }\n\t      return original;\n\t    }\n\t  }, {\n\t    key: \"brace\",\n\t    value: function brace(rep, node) {\n\t      if (isEmpty(rep)) {\n\t        return this.t(\"{}\");\n\t      }\n\n\t      switch (node.type) {\n\t        case \"ObjectBinding\":\n\t        case \"Import\":\n\t        case \"ExportFrom\":\n\t        case \"ObjectExpression\":\n\t          return new _coderep.Brace(rep);\n\t      }\n\n\t      rep = seq(new Linebreak(), rep);\n\t      indent(rep, false);\n\t      return new _coderep.Brace(rep);\n\t    }\n\t  }, {\n\t    key: \"reduceDoWhileStatement\",\n\t    value: function reduceDoWhileStatement(node, _ref68) {\n\t      var body = _ref68.body;\n\t      var test = _ref68.test;\n\n\t      return seq(this.t(\"do\"), this.sep(Sep.AFTER_DO), withoutTrailingLinebreak(body), this.sep(Sep.BEFORE_DOWHILE_WHILE), this.t(\"while\"), this.sep(Sep.AFTER_DOWHILE_WHILE), this.paren(test, Sep.DO_WHILE_TEST_PAREN_BEFORE, Sep.DO_WHILE_TEST_PAREN_AFTER), this.semiOp(), this.sep(Sep.AFTER_STATEMENT(node)));\n\t    }\n\t  }, {\n\t    key: \"reduceIfStatement\",\n\t    value: function reduceIfStatement(node, _ref69) {\n\t      var test = _ref69.test;\n\t      var consequent = _ref69.consequent;\n\t      var alternate = _ref69.alternate;\n\n\t      if (alternate && consequent.endsWithMissingElse) {\n\t        consequent = this.brace(consequent, node);\n\t      }\n\t      return (0, _objectAssign2.default)(seq(this.t(\"if\"), this.sep(Sep.AFTER_IF), this.paren(test, Sep.IF_PAREN_BEFORE, Sep.IF_PAREN_AFTER), this.sep(Sep.AFTER_IF_TEST), withoutTrailingLinebreak(consequent), alternate ? seq(this.sep(Sep.BEFORE_ELSE), this.t(\"else\"), this.sep(Sep.AFTER_ELSE), withoutTrailingLinebreak(alternate)) : empty(), this.sep(Sep.AFTER_STATEMENT(node))), { endsWithMissingElse: alternate ? alternate.endsWithMissingElse : true });\n\t    }\n\t  }, {\n\t    key: \"reduceSwitchCase\",\n\t    value: function reduceSwitchCase(node, _ref70) {\n\t      var test = _ref70.test;\n\t      var consequent = _ref70.consequent;\n\n\t      consequent = indent(withoutTrailingLinebreak(seq.apply(undefined, [this.sep(Sep.BEFORE_CASE_BODY)].concat(_toConsumableArray(consequent)))), true);\n\t      return seq(this.t(\"case\"), this.sep(Sep.BEFORE_CASE_TEST), test, this.sep(Sep.AFTER_CASE_TEST), this.t(\":\"), consequent, this.sep(Sep.AFTER_CASE_BODY));\n\t    }\n\t  }, {\n\t    key: \"reduceSwitchDefault\",\n\t    value: function reduceSwitchDefault(node, _ref71) {\n\t      var consequent = _ref71.consequent;\n\n\t      consequent = indent(withoutTrailingLinebreak(seq.apply(undefined, [this.sep(Sep.BEFORE_CASE_BODY)].concat(_toConsumableArray(consequent)))), true);\n\t      return seq(this.t(\"default\"), this.sep(Sep.DEFAULT), this.t(\":\"), consequent, this.sep(Sep.AFTER_DEFAULT_BODY));\n\t    }\n\t  }, {\n\t    key: \"sep\",\n\t    value: function sep(separator) {\n\t      switch (separator.type) {\n\t        case \"ARRAY_AFTER_COMMA\":\n\t        case \"OBJECT_AFTER_COMMA\":\n\t        case \"ARGS_AFTER_COMMA\":\n\t        case \"PARAMETER_AFTER_COMMA\":\n\t        case \"DECLARATORS_AFTER_COMMA\":\n\t        case \"NAMED_IMPORT_AFTER_COMMA\":\n\t        case \"IMPORT_AFTER_COMMA\":\n\t        case \"BEFORE_DEFAULT_EQUALS\":\n\t        case \"AFTER_DEFAULT_EQUALS\":\n\t        case \"AFTER_PROP\":\n\t        case \"BEFORE_JUMP_LABEL\":\n\t        case \"BEFORE_CATCH\":\n\t        case \"BEFORE_CATCH_BINDING\":\n\t        case \"AFTER_CATCH_BINDING\":\n\t        case \"BEFORE_CLASS_NAME\":\n\t        case \"BEFORE_EXTENDS\":\n\t        case \"AFTER_EXTENDS\":\n\t        case \"BEFORE_CLASS_DECLARATION_ELEMENTS\":\n\t        case \"BEFORE_CLASS_EXPRESSION_ELEMENTS\":\n\t        case \"AFTER_STATIC\":\n\t        case \"BEFORE_TERNARY_QUESTION\":\n\t        case \"AFTER_TERNARY_QUESTION\":\n\t        case \"BEFORE_TERNARY_COLON\":\n\t        case \"AFTER_TERNARY_COLON\":\n\t        case \"AFTER_DO\":\n\t        case \"BEFORE_DOWHILE_WHILE\":\n\t        case \"AFTER_DOWHILE_WHILE\":\n\t        case \"AFTER_FORIN_FOR\":\n\t        case \"BEFORE_FORIN_IN\":\n\t        case \"AFTER_FORIN_FOR\":\n\t        case \"BEFORE_FORIN_BODY\":\n\t        case \"AFTER_FOROF_FOR\":\n\t        case \"BEFORE_FOROF_OF\":\n\t        case \"AFTER_FOROF_FOR\":\n\t        case \"BEFORE_FOROF_BODY\":\n\t        case \"AFTER_FOR_FOR\":\n\t        case \"BEFORE_FOR_TEST\":\n\t        case \"BEFORE_FOR_UPDATE\":\n\t        case \"BEFORE_FOR_BODY\":\n\t        case \"BEFORE_FUNCTION_DECLARATION_BODY\":\n\t        case \"BEFORE_FUNCTION_EXPRESSION_BODY\":\n\t        case \"BEFORE_ARROW\":\n\t        case \"AFTER_ARROW\":\n\t        case \"AFTER_GET\":\n\t        case \"BEFORE_GET_BODY\":\n\t        case \"AFTER_IF\":\n\t        case \"AFTER_IF_TEST\":\n\t        case \"BEFORE_ELSE\":\n\t        case \"AFTER_ELSE\":\n\t        case \"BEFORE_IMPORT_BINDINGS\":\n\t        case \"BEFORE_IMPORT_MODULE\":\n\t        case \"AFTER_IMPORT_BINDINGS\":\n\t        case \"AFTER_FROM\":\n\t        case \"BEFORE_IMPORT_NAMESPACE\":\n\t        case \"BEFORE_IMPORT_STAR\":\n\t        case \"AFTER_IMPORT_STAR\":\n\t        case \"AFTER_IMPORT_AS\":\n\t        case \"AFTER_NAMESPACE_BINDING\":\n\t        case \"BEFORE_IMPORT_AS\":\n\t        case \"AFTER_IMPORT_AS\":\n\t        case \"EXPORTS_AFTER_COMMA\":\n\t        case \"BEFORE_EXPORT_STAR\":\n\t        case \"AFTER_EXPORT_STAR\":\n\t        case \"BEFORE_EXPORT_BINDINGS\":\n\t        case \"AFTER_EXPORT_BINDINGS\":\n\t        case \"AFTER_EXPORT\":\n\t        case \"AFTER_EXPORT_DEFAULT\":\n\t        case \"BEFORE_EXPORT_AS\":\n\t        case \"AFTER_EXPORT_AS\":\n\t        case \"AFTER_LABEL_COLON\":\n\t        case \"BEFORE_METHOD_BODY\":\n\t        case \"AFTER_NEW\":\n\t        case \"RETURN\":\n\t        case \"AFTER_SET\":\n\t        case \"BEFORE_SET_BODY\":\n\t        case \"BEFORE_SET_PARAMS\":\n\t        case \"BEFORE_CASE_TEST\":\n\t        case \"BEFORE_SWITCH_DISCRIM\":\n\t        case \"BEFORE_SWITCH_BODY\":\n\t        case \"THROW\":\n\t        case \"AFTER_TRY\":\n\t        case \"BEFORE_CATCH\":\n\t        case \"BEFORE_FINALLY\":\n\t        case \"AFTER_FINALLY\":\n\t        case \"VARIABLE_DECLARATION\":\n\t        case \"YIELD\":\n\t        case \"AFTER_YIELD_STAR\":\n\t        case \"DECLARATORS_AFTER_COMMA\":\n\t        case \"BEFORE_INIT_EQUALS\":\n\t        case \"AFTER_INIT_EQUALS\":\n\t        case \"AFTER_WHILE\":\n\t        case \"BEFORE_WHILE_BODY\":\n\t        case \"AFTER_WITH\":\n\t        case \"BEFORE_WITH_BODY\":\n\t        case \"BEFORE_FUNCTION_NAME\":\n\t        case \"AFTER_BINOP\":\n\t        case \"BEFORE_ASSIGN_OP\":\n\t        case \"AFTER_ASSIGN_OP\":\n\t          return this.t(\" \");\n\t        case \"AFTER_STATEMENT\":\n\t          switch (separator.node.type) {\n\t            case \"ForInStatement\":\n\t            case \"ForOfStatement\":\n\t            case \"ForStatement\":\n\t            case \"WhileStatement\":\n\t            case \"WithStatement\":\n\t              return empty(); // because those already end with an AFTER_STATEMENT\n\t            default:\n\t              return new Linebreak();\n\t          }\n\t        case \"AFTER_CLASS_ELEMENT\":\n\t        case \"BEFORE_CASE_BODY\":\n\t        case \"AFTER_CASE_BODY\":\n\t        case \"AFTER_DEFAULT_BODY\":\n\t          return new Linebreak();\n\t        case \"BEFORE_BINOP\":\n\t          return separator.op === \",\" ? empty() : this.t(\" \");\n\t        case \"UNARY\":\n\t          return separator.op === \"delete\" || separator.op === \"void\" || separator.op === \"typeof\" ? this.t(\" \") : empty();\n\t        default:\n\t          return empty();\n\t      }\n\t    }\n\t  }]);\n\n\t  return FormattedCodeGen;\n\t}(ExtensibleCodeGen);\n\n/***/ },\n/* 51 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.MonoidalReducer = exports.CloneReducer = undefined;\n\texports.default = reduce;\n\n\tvar _cloneReducer = __webpack_require__(52);\n\n\tObject.defineProperty(exports, \"CloneReducer\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _cloneReducer.default;\n\t  }\n\t});\n\n\tvar _monoidalReducer = __webpack_require__(54);\n\n\tObject.defineProperty(exports, \"MonoidalReducer\", {\n\t  enumerable: true,\n\t  get: function get() {\n\t    return _monoidalReducer.default;\n\t  }\n\t});\n\n\tvar _shiftSpec = __webpack_require__(53);\n\n\tvar _shiftSpec2 = _interopRequireDefault(_shiftSpec);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tfunction transformWithSpec(transformer, node, spec) {\n\t  switch (spec.typeName) {\n\t    case \"Enum\":\n\t    case \"String\":\n\t    case \"Number\":\n\t    case \"Boolean\":\n\t    case \"SourceSpan\":\n\t      return node;\n\t    case \"Const\":\n\t      // TODO: checked version\n\t      return transformWithSpec(transformer, node, spec.argument);\n\t    case \"Maybe\":\n\t      return node && transformWithSpec(transformer, node, spec.argument);\n\t    case \"List\":\n\t      return node.map(function (e) {\n\t        return transformWithSpec(transformer, e, spec.argument);\n\t      });\n\t    case \"Union\":\n\t      // TODO: checked version\n\t      return transformWithSpec(transformer, node, _shiftSpec2.default[node.type]);\n\t    default:\n\t      var state = {};\n\t      spec.fields.forEach(function (field) {\n\t        var v = transformWithSpec(transformer, node[field.name], field.type);\n\t        state[field.name] = v == null ? null : v;\n\t      });\n\t      if (typeof transformer[\"reduce\" + node.type] !== \"function\") {\n\t        throw new Error(\"Encountered \" + node.type + \", which the provided reducer does not handle.\");\n\t      }\n\t      return transformer[\"reduce\" + node.type](node, state);\n\t  }\n\t} /**\n\t   * Copyright 2014 Shape Security, Inc.\n\t   *\n\t   * Licensed under the Apache License, Version 2.0 (the \"License\")\n\t   * you may not use this file except in compliance with the License.\n\t   * You may obtain a copy of the License at\n\t   *\n\t   *     http://www.apache.org/licenses/LICENSE-2.0\n\t   *\n\t   * Unless required by applicable law or agreed to in writing, software\n\t   * distributed under the License is distributed on an \"AS IS\" BASIS,\n\t   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\t   * See the License for the specific language governing permissions and\n\t   * limitations under the License.\n\t   */\n\n\tfunction reduce(reducer, reducible) {\n\t  return transformWithSpec(reducer, reducible, _shiftSpec2.default[reducible.type]);\n\t}\n\n/***/ },\n/* 52 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\n\tvar _shiftSpec = __webpack_require__(53);\n\n\tvar _shiftSpec2 = _interopRequireDefault(_shiftSpec);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } /**\n\t                                                                                                                                                           * Copyright 2014 Shape Security, Inc.\n\t                                                                                                                                                           *\n\t                                                                                                                                                           * Licensed under the Apache License, Version 2.0 (the \"License\")\n\t                                                                                                                                                           * you may not use this file except in compliance with the License.\n\t                                                                                                                                                           * You may obtain a copy of the License at\n\t                                                                                                                                                           *\n\t                                                                                                                                                           *     http://www.apache.org/licenses/LICENSE-2.0\n\t                                                                                                                                                           *\n\t                                                                                                                                                           * Unless required by applicable law or agreed to in writing, software\n\t                                                                                                                                                           * distributed under the License is distributed on an \"AS IS\" BASIS,\n\t                                                                                                                                                           * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\t                                                                                                                                                           * See the License for the specific language governing permissions and\n\t                                                                                                                                                           * limitations under the License.\n\t                                                                                                                                                           */\n\n\tvar CloneReducer = function CloneReducer() {\n\t  _classCallCheck(this, CloneReducer);\n\t};\n\n\texports.default = CloneReducer;\n\n\tfor (var typeName in _shiftSpec2.default) {\n\t  var type = _shiftSpec2.default[typeName];\n\t  Object.defineProperty(CloneReducer.prototype, \"reduce\" + typeName, {\n\t    value: function value(node, state) {\n\t      return state;\n\t    }\n\t  });\n\t}\n\n/***/ },\n/* 53 */\n/***/ function(module, exports) {\n\n\t// Generated by src/generate-spec.js. \n\n\t/**\n\t * Copyright 2015 Shape Security, Inc.\n\t *\n\t * Licensed under the Apache License, Version 2.0 (the \"License\");\n\t * you may not use this file except in compliance with the License.\n\t * You may obtain a copy of the License at\n\t *\n\t *     http://www.apache.org/licenses/LICENSE-2.0\n\t *\n\t * Unless required by applicable law or agreed to in writing, software\n\t * distributed under the License is distributed on an \"AS IS\" BASIS,\n\t * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\t * See the License for the specific language governing permissions and\n\t * limitations under the License.\n\t */\n\n\t// Hack to make Babel6 import this as a module.\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\n\t// Meta data generated from spec.idl.\n\texports.default = (function() {\n\t  var SPEC = {};\n\n\t  var BOOLEAN = { typeName: \"Boolean\" };\n\t  var DOUBLE = { typeName: \"Number\" };\n\t  var STRING = { typeName: \"String\" };\n\t  function Maybe(arg) { return { typeName: \"Maybe\", argument: arg }; }\n\t  function List(arg) { return { typeName: \"List\", argument: arg }; }\n\t  function Const(arg) { return { typeName: \"Const\", argument: arg }; }\n\t  function Union() { return { typeName: \"Union\", arguments: [].slice.call(arguments, 0) }; }\n\n\t  var TYPE_INDICATOR = {\n\t    typeName: \"Enum\",\n\t    values: [\"ArrayBinding\", \"ArrayExpression\", \"ArrowExpression\", \"AssignmentExpression\", \"BinaryExpression\", \"BindingIdentifier\", \"BindingProperty\", \"BindingPropertyIdentifier\", \"BindingPropertyProperty\", \"BindingWithDefault\", \"Block\", \"BlockStatement\", \"BreakStatement\", \"CallExpression\", \"CatchClause\", \"Class\", \"ClassDeclaration\", \"ClassElement\", \"ClassExpression\", \"CompoundAssignmentExpression\", \"ComputedMemberExpression\", \"ComputedPropertyName\", \"ConditionalExpression\", \"ContinueStatement\", \"DataProperty\", \"DebuggerStatement\", \"Directive\", \"DoWhileStatement\", \"EmptyStatement\", \"Export\", \"ExportAllFrom\", \"ExportDeclaration\", \"ExportDefault\", \"ExportFrom\", \"ExportSpecifier\", \"Expression\", \"ExpressionStatement\", \"ForInStatement\", \"ForOfStatement\", \"ForStatement\", \"FormalParameters\", \"Function\", \"FunctionBody\", \"FunctionDeclaration\", \"FunctionExpression\", \"Getter\", \"IdentifierExpression\", \"IfStatement\", \"Import\", \"ImportDeclaration\", \"ImportNamespace\", \"ImportSpecifier\", \"IterationStatement\", \"LabeledStatement\", \"LiteralBooleanExpression\", \"LiteralInfinityExpression\", \"LiteralNullExpression\", \"LiteralNumericExpression\", \"LiteralRegExpExpression\", \"LiteralStringExpression\", \"MemberExpression\", \"Method\", \"MethodDefinition\", \"Module\", \"NamedObjectProperty\", \"NewExpression\", \"NewTargetExpression\", \"Node\", \"ObjectBinding\", \"ObjectExpression\", \"ObjectProperty\", \"PropertyName\", \"ReturnStatement\", \"Script\", \"Setter\", \"ShorthandProperty\", \"SourceLocation\", \"SourceSpan\", \"SpreadElement\", \"Statement\", \"StaticMemberExpression\", \"StaticPropertyName\", \"Super\", \"SwitchCase\", \"SwitchDefault\", \"SwitchStatement\", \"SwitchStatementWithDefault\", \"TemplateElement\", \"TemplateExpression\", \"ThisExpression\", \"ThrowStatement\", \"TryCatchStatement\", \"TryFinallyStatement\", \"UnaryExpression\", \"UpdateExpression\", \"VariableDeclaration\", \"VariableDeclarationStatement\", \"VariableDeclarator\", \"WhileStatement\", \"WithStatement\", \"YieldExpression\", \"YieldGeneratorExpression\"]\n\t  };\n\n\t  var VariableDeclarationKind = {\n\t    typeName: \"Enum\",\n\t    values: [\"var\", \"let\", \"const\"]\n\t  };\n\n\t  var CompoundAssignmentOperator = {\n\t    typeName: \"Enum\",\n\t    values: [\"+=\", \"-=\", \"*=\", \"/=\", \"%=\", \"<<=\", \">>=\", \">>>=\", \"|=\", \"^=\", \"&=\"]\n\t  };\n\n\t  var BinaryOperator = {\n\t    typeName: \"Enum\",\n\t    values: [\"==\", \"!=\", \"===\", \"!==\", \"<\", \"<=\", \">\", \">=\", \"in\", \"instanceof\", \"<<\", \">>\", \">>>\", \"+\", \"-\", \"*\", \"/\", \"%\", \",\", \"||\", \"&&\", \"|\", \"^\", \"&\"]\n\t  };\n\n\t  var UnaryOperator = {\n\t    typeName: \"Enum\",\n\t    values: [\"+\", \"-\", \"!\", \"~\", \"typeof\", \"void\", \"delete\"]\n\t  };\n\n\t  var UpdateOperator = {\n\t    typeName: \"Enum\",\n\t    values: [\"++\", \"--\"]\n\t  };\n\n\t  var SourceLocation = SPEC.SourceLocation = {};\n\t  var SourceSpan = SPEC.SourceSpan = {};\n\t  var BindingWithDefault = SPEC.BindingWithDefault = {};\n\t  var BindingIdentifier = SPEC.BindingIdentifier = {};\n\t  var ArrayBinding = SPEC.ArrayBinding = {};\n\t  var ObjectBinding = SPEC.ObjectBinding = {};\n\t  var BindingPropertyIdentifier = SPEC.BindingPropertyIdentifier = {};\n\t  var BindingPropertyProperty = SPEC.BindingPropertyProperty = {};\n\t  var ClassExpression = SPEC.ClassExpression = {};\n\t  var ClassDeclaration = SPEC.ClassDeclaration = {};\n\t  var ClassElement = SPEC.ClassElement = {};\n\t  var Module = SPEC.Module = {};\n\t  var Import = SPEC.Import = {};\n\t  var ImportNamespace = SPEC.ImportNamespace = {};\n\t  var ImportSpecifier = SPEC.ImportSpecifier = {};\n\t  var ExportAllFrom = SPEC.ExportAllFrom = {};\n\t  var ExportFrom = SPEC.ExportFrom = {};\n\t  var Export = SPEC.Export = {};\n\t  var ExportDefault = SPEC.ExportDefault = {};\n\t  var ExportSpecifier = SPEC.ExportSpecifier = {};\n\t  var Method = SPEC.Method = {};\n\t  var Getter = SPEC.Getter = {};\n\t  var Setter = SPEC.Setter = {};\n\t  var DataProperty = SPEC.DataProperty = {};\n\t  var ShorthandProperty = SPEC.ShorthandProperty = {};\n\t  var ComputedPropertyName = SPEC.ComputedPropertyName = {};\n\t  var StaticPropertyName = SPEC.StaticPropertyName = {};\n\t  var LiteralBooleanExpression = SPEC.LiteralBooleanExpression = {};\n\t  var LiteralInfinityExpression = SPEC.LiteralInfinityExpression = {};\n\t  var LiteralNullExpression = SPEC.LiteralNullExpression = {};\n\t  var LiteralNumericExpression = SPEC.LiteralNumericExpression = {};\n\t  var LiteralRegExpExpression = SPEC.LiteralRegExpExpression = {};\n\t  var LiteralStringExpression = SPEC.LiteralStringExpression = {};\n\t  var ArrayExpression = SPEC.ArrayExpression = {};\n\t  var ArrowExpression = SPEC.ArrowExpression = {};\n\t  var AssignmentExpression = SPEC.AssignmentExpression = {};\n\t  var BinaryExpression = SPEC.BinaryExpression = {};\n\t  var CallExpression = SPEC.CallExpression = {};\n\t  var CompoundAssignmentExpression = SPEC.CompoundAssignmentExpression = {};\n\t  var ComputedMemberExpression = SPEC.ComputedMemberExpression = {};\n\t  var ConditionalExpression = SPEC.ConditionalExpression = {};\n\t  var FunctionExpression = SPEC.FunctionExpression = {};\n\t  var IdentifierExpression = SPEC.IdentifierExpression = {};\n\t  var NewExpression = SPEC.NewExpression = {};\n\t  var NewTargetExpression = SPEC.NewTargetExpression = {};\n\t  var ObjectExpression = SPEC.ObjectExpression = {};\n\t  var UnaryExpression = SPEC.UnaryExpression = {};\n\t  var StaticMemberExpression = SPEC.StaticMemberExpression = {};\n\t  var TemplateExpression = SPEC.TemplateExpression = {};\n\t  var ThisExpression = SPEC.ThisExpression = {};\n\t  var UpdateExpression = SPEC.UpdateExpression = {};\n\t  var YieldExpression = SPEC.YieldExpression = {};\n\t  var YieldGeneratorExpression = SPEC.YieldGeneratorExpression = {};\n\t  var BlockStatement = SPEC.BlockStatement = {};\n\t  var BreakStatement = SPEC.BreakStatement = {};\n\t  var ContinueStatement = SPEC.ContinueStatement = {};\n\t  var DebuggerStatement = SPEC.DebuggerStatement = {};\n\t  var DoWhileStatement = SPEC.DoWhileStatement = {};\n\t  var EmptyStatement = SPEC.EmptyStatement = {};\n\t  var ExpressionStatement = SPEC.ExpressionStatement = {};\n\t  var ForInStatement = SPEC.ForInStatement = {};\n\t  var ForOfStatement = SPEC.ForOfStatement = {};\n\t  var ForStatement = SPEC.ForStatement = {};\n\t  var IfStatement = SPEC.IfStatement = {};\n\t  var LabeledStatement = SPEC.LabeledStatement = {};\n\t  var ReturnStatement = SPEC.ReturnStatement = {};\n\t  var SwitchStatement = SPEC.SwitchStatement = {};\n\t  var SwitchStatementWithDefault = SPEC.SwitchStatementWithDefault = {};\n\t  var ThrowStatement = SPEC.ThrowStatement = {};\n\t  var TryCatchStatement = SPEC.TryCatchStatement = {};\n\t  var TryFinallyStatement = SPEC.TryFinallyStatement = {};\n\t  var VariableDeclarationStatement = SPEC.VariableDeclarationStatement = {};\n\t  var WhileStatement = SPEC.WhileStatement = {};\n\t  var WithStatement = SPEC.WithStatement = {};\n\t  var Block = SPEC.Block = {};\n\t  var CatchClause = SPEC.CatchClause = {};\n\t  var Directive = SPEC.Directive = {};\n\t  var FormalParameters = SPEC.FormalParameters = {};\n\t  var FunctionBody = SPEC.FunctionBody = {};\n\t  var FunctionDeclaration = SPEC.FunctionDeclaration = {};\n\t  var Script = SPEC.Script = {};\n\t  var SpreadElement = SPEC.SpreadElement = {};\n\t  var Super = SPEC.Super = {};\n\t  var SwitchCase = SPEC.SwitchCase = {};\n\t  var SwitchDefault = SPEC.SwitchDefault = {};\n\t  var TemplateElement = SPEC.TemplateElement = {};\n\t  var VariableDeclaration = SPEC.VariableDeclaration = {};\n\t  var VariableDeclarator = SPEC.VariableDeclarator = {};\n\n\t  var Class = Union(ClassExpression, ClassDeclaration);\n\t  var BindingProperty = Union(BindingPropertyIdentifier, BindingPropertyProperty);\n\t  var ExportDeclaration = Union(ExportAllFrom, ExportFrom, Export, ExportDefault);\n\t  var ImportDeclaration = Union(Import, ImportNamespace);\n\t  var MethodDefinition = Union(Method, Getter, Setter);\n\t  var NamedObjectProperty = Union(MethodDefinition, DataProperty);\n\t  var ObjectProperty = Union(NamedObjectProperty, ShorthandProperty);\n\t  var PropertyName = Union(ComputedPropertyName, StaticPropertyName);\n\t  var MemberExpression = Union(ComputedMemberExpression, StaticMemberExpression);\n\t  var Expression = Union(MemberExpression, ClassExpression, LiteralBooleanExpression, LiteralInfinityExpression, LiteralNullExpression, LiteralNumericExpression, LiteralRegExpExpression, LiteralStringExpression, ArrayExpression, ArrowExpression, AssignmentExpression, BinaryExpression, CallExpression, CompoundAssignmentExpression, ConditionalExpression, FunctionExpression, IdentifierExpression, NewExpression, NewTargetExpression, ObjectExpression, UnaryExpression, TemplateExpression, ThisExpression, UpdateExpression, YieldExpression, YieldGeneratorExpression);\n\t  var IterationStatement = Union(DoWhileStatement, ForInStatement, ForOfStatement, ForStatement, WhileStatement);\n\t  var Statement = Union(IterationStatement, ClassDeclaration, BlockStatement, BreakStatement, ContinueStatement, DebuggerStatement, EmptyStatement, ExpressionStatement, IfStatement, LabeledStatement, ReturnStatement, SwitchStatement, SwitchStatementWithDefault, ThrowStatement, TryCatchStatement, TryFinallyStatement, VariableDeclarationStatement, WithStatement, FunctionDeclaration);\n\t  var Node = Union(Statement, Expression, PropertyName, ObjectProperty, ImportDeclaration, ExportDeclaration, BindingWithDefault, BindingIdentifier, ArrayBinding, ObjectBinding, BindingProperty, ClassElement, Module, ImportSpecifier, ExportSpecifier, Block, CatchClause, Directive, FormalParameters, FunctionBody, Script, SpreadElement, Super, SwitchCase, SwitchDefault, TemplateElement, VariableDeclaration, VariableDeclarator);\n\t  var Function = Union(FunctionExpression, FunctionDeclaration);\n\n\t  SourceLocation.typeName = \"SourceLocation\";\n\t  SourceLocation.fields = [\n\t    { name: \"line\", type: DOUBLE },\n\t    { name: \"column\", type: DOUBLE },\n\t    { name: \"offset\", type: DOUBLE },\n\t  ];\n\n\t  SourceSpan.typeName = \"SourceSpan\";\n\t  SourceSpan.fields = [\n\t    { name: \"source\", type: Maybe(STRING) },\n\t    { name: \"start\", type: SourceLocation },\n\t    { name: \"end\", type: SourceLocation },\n\t  ];\n\n\t  BindingWithDefault.typeName = \"BindingWithDefault\";\n\t  BindingWithDefault.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"BindingWithDefault\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"binding\", type: Union(ObjectBinding, ArrayBinding, BindingIdentifier, MemberExpression) },\n\t    { name: \"init\", type: Expression },\n\t  ];\n\n\t  BindingIdentifier.typeName = \"BindingIdentifier\";\n\t  BindingIdentifier.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"BindingIdentifier\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"name\", type: STRING },\n\t  ];\n\n\t  ArrayBinding.typeName = \"ArrayBinding\";\n\t  ArrayBinding.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ArrayBinding\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"elements\", type: List(Maybe(Union(ObjectBinding, ArrayBinding, BindingIdentifier, MemberExpression, BindingWithDefault))) },\n\t    { name: \"restElement\", type: Maybe(Union(ObjectBinding, ArrayBinding, BindingIdentifier, MemberExpression)) },\n\t  ];\n\n\t  ObjectBinding.typeName = \"ObjectBinding\";\n\t  ObjectBinding.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ObjectBinding\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"properties\", type: List(BindingProperty) },\n\t  ];\n\n\t  BindingPropertyIdentifier.typeName = \"BindingPropertyIdentifier\";\n\t  BindingPropertyIdentifier.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"BindingPropertyIdentifier\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"binding\", type: BindingIdentifier },\n\t    { name: \"init\", type: Maybe(Expression) },\n\t  ];\n\n\t  BindingPropertyProperty.typeName = \"BindingPropertyProperty\";\n\t  BindingPropertyProperty.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"BindingPropertyProperty\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"name\", type: PropertyName },\n\t    { name: \"binding\", type: Union(ObjectBinding, ArrayBinding, BindingIdentifier, MemberExpression, BindingWithDefault) },\n\t  ];\n\n\t  ClassExpression.typeName = \"ClassExpression\";\n\t  ClassExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ClassExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"name\", type: Maybe(BindingIdentifier) },\n\t    { name: \"super\", type: Maybe(Expression) },\n\t    { name: \"elements\", type: List(ClassElement) },\n\t  ];\n\n\t  ClassDeclaration.typeName = \"ClassDeclaration\";\n\t  ClassDeclaration.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ClassDeclaration\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"name\", type: BindingIdentifier },\n\t    { name: \"super\", type: Maybe(Expression) },\n\t    { name: \"elements\", type: List(ClassElement) },\n\t  ];\n\n\t  ClassElement.typeName = \"ClassElement\";\n\t  ClassElement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ClassElement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"isStatic\", type: BOOLEAN },\n\t    { name: \"method\", type: MethodDefinition },\n\t  ];\n\n\t  Module.typeName = \"Module\";\n\t  Module.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"Module\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"directives\", type: List(Directive) },\n\t    { name: \"items\", type: List(Union(ImportDeclaration, ExportDeclaration, Statement)) },\n\t  ];\n\n\t  Import.typeName = \"Import\";\n\t  Import.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"Import\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"moduleSpecifier\", type: STRING },\n\t    { name: \"defaultBinding\", type: Maybe(BindingIdentifier) },\n\t    { name: \"namedImports\", type: List(ImportSpecifier) },\n\t  ];\n\n\t  ImportNamespace.typeName = \"ImportNamespace\";\n\t  ImportNamespace.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ImportNamespace\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"moduleSpecifier\", type: STRING },\n\t    { name: \"defaultBinding\", type: Maybe(BindingIdentifier) },\n\t    { name: \"namespaceBinding\", type: BindingIdentifier },\n\t  ];\n\n\t  ImportSpecifier.typeName = \"ImportSpecifier\";\n\t  ImportSpecifier.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ImportSpecifier\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"name\", type: Maybe(STRING) },\n\t    { name: \"binding\", type: BindingIdentifier },\n\t  ];\n\n\t  ExportAllFrom.typeName = \"ExportAllFrom\";\n\t  ExportAllFrom.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ExportAllFrom\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"moduleSpecifier\", type: STRING },\n\t  ];\n\n\t  ExportFrom.typeName = \"ExportFrom\";\n\t  ExportFrom.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ExportFrom\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"namedExports\", type: List(ExportSpecifier) },\n\t    { name: \"moduleSpecifier\", type: Maybe(STRING) },\n\t  ];\n\n\t  Export.typeName = \"Export\";\n\t  Export.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"Export\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"declaration\", type: Union(FunctionDeclaration, ClassDeclaration, VariableDeclaration) },\n\t  ];\n\n\t  ExportDefault.typeName = \"ExportDefault\";\n\t  ExportDefault.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ExportDefault\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"body\", type: Union(FunctionDeclaration, ClassDeclaration, Expression) },\n\t  ];\n\n\t  ExportSpecifier.typeName = \"ExportSpecifier\";\n\t  ExportSpecifier.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ExportSpecifier\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"name\", type: Maybe(STRING) },\n\t    { name: \"exportedName\", type: STRING },\n\t  ];\n\n\t  Method.typeName = \"Method\";\n\t  Method.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"Method\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"name\", type: PropertyName },\n\t    { name: \"isGenerator\", type: BOOLEAN },\n\t    { name: \"params\", type: FormalParameters },\n\t    { name: \"body\", type: FunctionBody },\n\t  ];\n\n\t  Getter.typeName = \"Getter\";\n\t  Getter.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"Getter\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"name\", type: PropertyName },\n\t    { name: \"body\", type: FunctionBody },\n\t  ];\n\n\t  Setter.typeName = \"Setter\";\n\t  Setter.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"Setter\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"name\", type: PropertyName },\n\t    { name: \"param\", type: Union(ObjectBinding, ArrayBinding, BindingIdentifier, MemberExpression, BindingWithDefault) },\n\t    { name: \"body\", type: FunctionBody },\n\t  ];\n\n\t  DataProperty.typeName = \"DataProperty\";\n\t  DataProperty.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"DataProperty\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"name\", type: PropertyName },\n\t    { name: \"expression\", type: Expression },\n\t  ];\n\n\t  ShorthandProperty.typeName = \"ShorthandProperty\";\n\t  ShorthandProperty.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ShorthandProperty\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"name\", type: STRING },\n\t  ];\n\n\t  ComputedPropertyName.typeName = \"ComputedPropertyName\";\n\t  ComputedPropertyName.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ComputedPropertyName\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"expression\", type: Expression },\n\t  ];\n\n\t  StaticPropertyName.typeName = \"StaticPropertyName\";\n\t  StaticPropertyName.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"StaticPropertyName\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"value\", type: STRING },\n\t  ];\n\n\t  LiteralBooleanExpression.typeName = \"LiteralBooleanExpression\";\n\t  LiteralBooleanExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"LiteralBooleanExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"value\", type: BOOLEAN },\n\t  ];\n\n\t  LiteralInfinityExpression.typeName = \"LiteralInfinityExpression\";\n\t  LiteralInfinityExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"LiteralInfinityExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t  ];\n\n\t  LiteralNullExpression.typeName = \"LiteralNullExpression\";\n\t  LiteralNullExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"LiteralNullExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t  ];\n\n\t  LiteralNumericExpression.typeName = \"LiteralNumericExpression\";\n\t  LiteralNumericExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"LiteralNumericExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"value\", type: DOUBLE },\n\t  ];\n\n\t  LiteralRegExpExpression.typeName = \"LiteralRegExpExpression\";\n\t  LiteralRegExpExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"LiteralRegExpExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"pattern\", type: STRING },\n\t    { name: \"flags\", type: STRING },\n\t  ];\n\n\t  LiteralStringExpression.typeName = \"LiteralStringExpression\";\n\t  LiteralStringExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"LiteralStringExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"value\", type: STRING },\n\t  ];\n\n\t  ArrayExpression.typeName = \"ArrayExpression\";\n\t  ArrayExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ArrayExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"elements\", type: List(Maybe(Union(SpreadElement, Expression))) },\n\t  ];\n\n\t  ArrowExpression.typeName = \"ArrowExpression\";\n\t  ArrowExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ArrowExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"params\", type: FormalParameters },\n\t    { name: \"body\", type: Union(FunctionBody, Expression) },\n\t  ];\n\n\t  AssignmentExpression.typeName = \"AssignmentExpression\";\n\t  AssignmentExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"AssignmentExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"binding\", type: Union(ObjectBinding, ArrayBinding, BindingIdentifier, MemberExpression) },\n\t    { name: \"expression\", type: Expression },\n\t  ];\n\n\t  BinaryExpression.typeName = \"BinaryExpression\";\n\t  BinaryExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"BinaryExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"operator\", type: BinaryOperator },\n\t    { name: \"left\", type: Expression },\n\t    { name: \"right\", type: Expression },\n\t  ];\n\n\t  CallExpression.typeName = \"CallExpression\";\n\t  CallExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"CallExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"callee\", type: Union(Expression, Super) },\n\t    { name: \"arguments\", type: List(Union(SpreadElement, Expression)) },\n\t  ];\n\n\t  CompoundAssignmentExpression.typeName = \"CompoundAssignmentExpression\";\n\t  CompoundAssignmentExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"CompoundAssignmentExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"operator\", type: CompoundAssignmentOperator },\n\t    { name: \"binding\", type: Union(BindingIdentifier, MemberExpression) },\n\t    { name: \"expression\", type: Expression },\n\t  ];\n\n\t  ComputedMemberExpression.typeName = \"ComputedMemberExpression\";\n\t  ComputedMemberExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ComputedMemberExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"object\", type: Union(Expression, Super) },\n\t    { name: \"expression\", type: Expression },\n\t  ];\n\n\t  ConditionalExpression.typeName = \"ConditionalExpression\";\n\t  ConditionalExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ConditionalExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"test\", type: Expression },\n\t    { name: \"consequent\", type: Expression },\n\t    { name: \"alternate\", type: Expression },\n\t  ];\n\n\t  FunctionExpression.typeName = \"FunctionExpression\";\n\t  FunctionExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"FunctionExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"isGenerator\", type: BOOLEAN },\n\t    { name: \"name\", type: Maybe(BindingIdentifier) },\n\t    { name: \"params\", type: FormalParameters },\n\t    { name: \"body\", type: FunctionBody },\n\t  ];\n\n\t  IdentifierExpression.typeName = \"IdentifierExpression\";\n\t  IdentifierExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"IdentifierExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"name\", type: STRING },\n\t  ];\n\n\t  NewExpression.typeName = \"NewExpression\";\n\t  NewExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"NewExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"callee\", type: Expression },\n\t    { name: \"arguments\", type: List(Union(SpreadElement, Expression)) },\n\t  ];\n\n\t  NewTargetExpression.typeName = \"NewTargetExpression\";\n\t  NewTargetExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"NewTargetExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t  ];\n\n\t  ObjectExpression.typeName = \"ObjectExpression\";\n\t  ObjectExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ObjectExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"properties\", type: List(ObjectProperty) },\n\t  ];\n\n\t  UnaryExpression.typeName = \"UnaryExpression\";\n\t  UnaryExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"UnaryExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"operator\", type: UnaryOperator },\n\t    { name: \"operand\", type: Expression },\n\t  ];\n\n\t  StaticMemberExpression.typeName = \"StaticMemberExpression\";\n\t  StaticMemberExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"StaticMemberExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"object\", type: Union(Expression, Super) },\n\t    { name: \"property\", type: STRING },\n\t  ];\n\n\t  TemplateExpression.typeName = \"TemplateExpression\";\n\t  TemplateExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"TemplateExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"tag\", type: Maybe(Expression) },\n\t    { name: \"elements\", type: List(Union(Expression, TemplateElement)) },\n\t  ];\n\n\t  ThisExpression.typeName = \"ThisExpression\";\n\t  ThisExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ThisExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t  ];\n\n\t  UpdateExpression.typeName = \"UpdateExpression\";\n\t  UpdateExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"UpdateExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"isPrefix\", type: BOOLEAN },\n\t    { name: \"operator\", type: UpdateOperator },\n\t    { name: \"operand\", type: Union(BindingIdentifier, MemberExpression) },\n\t  ];\n\n\t  YieldExpression.typeName = \"YieldExpression\";\n\t  YieldExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"YieldExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"expression\", type: Maybe(Expression) },\n\t  ];\n\n\t  YieldGeneratorExpression.typeName = \"YieldGeneratorExpression\";\n\t  YieldGeneratorExpression.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"YieldGeneratorExpression\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"expression\", type: Expression },\n\t  ];\n\n\t  BlockStatement.typeName = \"BlockStatement\";\n\t  BlockStatement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"BlockStatement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"block\", type: Block },\n\t  ];\n\n\t  BreakStatement.typeName = \"BreakStatement\";\n\t  BreakStatement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"BreakStatement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"label\", type: Maybe(STRING) },\n\t  ];\n\n\t  ContinueStatement.typeName = \"ContinueStatement\";\n\t  ContinueStatement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ContinueStatement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"label\", type: Maybe(STRING) },\n\t  ];\n\n\t  DebuggerStatement.typeName = \"DebuggerStatement\";\n\t  DebuggerStatement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"DebuggerStatement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t  ];\n\n\t  DoWhileStatement.typeName = \"DoWhileStatement\";\n\t  DoWhileStatement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"DoWhileStatement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"body\", type: Statement },\n\t    { name: \"test\", type: Expression },\n\t  ];\n\n\t  EmptyStatement.typeName = \"EmptyStatement\";\n\t  EmptyStatement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"EmptyStatement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t  ];\n\n\t  ExpressionStatement.typeName = \"ExpressionStatement\";\n\t  ExpressionStatement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ExpressionStatement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"expression\", type: Expression },\n\t  ];\n\n\t  ForInStatement.typeName = \"ForInStatement\";\n\t  ForInStatement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ForInStatement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"left\", type: Union(VariableDeclaration, ObjectBinding, ArrayBinding, BindingIdentifier, MemberExpression) },\n\t    { name: \"right\", type: Expression },\n\t    { name: \"body\", type: Statement },\n\t  ];\n\n\t  ForOfStatement.typeName = \"ForOfStatement\";\n\t  ForOfStatement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ForOfStatement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"left\", type: Union(VariableDeclaration, ObjectBinding, ArrayBinding, BindingIdentifier, MemberExpression) },\n\t    { name: \"right\", type: Expression },\n\t    { name: \"body\", type: Statement },\n\t  ];\n\n\t  ForStatement.typeName = \"ForStatement\";\n\t  ForStatement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ForStatement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"init\", type: Maybe(Union(VariableDeclaration, Expression)) },\n\t    { name: \"test\", type: Maybe(Expression) },\n\t    { name: \"update\", type: Maybe(Expression) },\n\t    { name: \"body\", type: Statement },\n\t  ];\n\n\t  IfStatement.typeName = \"IfStatement\";\n\t  IfStatement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"IfStatement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"test\", type: Expression },\n\t    { name: \"consequent\", type: Statement },\n\t    { name: \"alternate\", type: Maybe(Statement) },\n\t  ];\n\n\t  LabeledStatement.typeName = \"LabeledStatement\";\n\t  LabeledStatement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"LabeledStatement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"label\", type: STRING },\n\t    { name: \"body\", type: Statement },\n\t  ];\n\n\t  ReturnStatement.typeName = \"ReturnStatement\";\n\t  ReturnStatement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ReturnStatement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"expression\", type: Maybe(Expression) },\n\t  ];\n\n\t  SwitchStatement.typeName = \"SwitchStatement\";\n\t  SwitchStatement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"SwitchStatement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"discriminant\", type: Expression },\n\t    { name: \"cases\", type: List(SwitchCase) },\n\t  ];\n\n\t  SwitchStatementWithDefault.typeName = \"SwitchStatementWithDefault\";\n\t  SwitchStatementWithDefault.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"SwitchStatementWithDefault\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"discriminant\", type: Expression },\n\t    { name: \"preDefaultCases\", type: List(SwitchCase) },\n\t    { name: \"defaultCase\", type: SwitchDefault },\n\t    { name: \"postDefaultCases\", type: List(SwitchCase) },\n\t  ];\n\n\t  ThrowStatement.typeName = \"ThrowStatement\";\n\t  ThrowStatement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"ThrowStatement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"expression\", type: Expression },\n\t  ];\n\n\t  TryCatchStatement.typeName = \"TryCatchStatement\";\n\t  TryCatchStatement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"TryCatchStatement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"body\", type: Block },\n\t    { name: \"catchClause\", type: CatchClause },\n\t  ];\n\n\t  TryFinallyStatement.typeName = \"TryFinallyStatement\";\n\t  TryFinallyStatement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"TryFinallyStatement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"body\", type: Block },\n\t    { name: \"catchClause\", type: Maybe(CatchClause) },\n\t    { name: \"finalizer\", type: Block },\n\t  ];\n\n\t  VariableDeclarationStatement.typeName = \"VariableDeclarationStatement\";\n\t  VariableDeclarationStatement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"VariableDeclarationStatement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"declaration\", type: VariableDeclaration },\n\t  ];\n\n\t  WhileStatement.typeName = \"WhileStatement\";\n\t  WhileStatement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"WhileStatement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"test\", type: Expression },\n\t    { name: \"body\", type: Statement },\n\t  ];\n\n\t  WithStatement.typeName = \"WithStatement\";\n\t  WithStatement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"WithStatement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"object\", type: Expression },\n\t    { name: \"body\", type: Statement },\n\t  ];\n\n\t  Block.typeName = \"Block\";\n\t  Block.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"Block\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"statements\", type: List(Statement) },\n\t  ];\n\n\t  CatchClause.typeName = \"CatchClause\";\n\t  CatchClause.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"CatchClause\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"binding\", type: Union(ObjectBinding, ArrayBinding, BindingIdentifier, MemberExpression) },\n\t    { name: \"body\", type: Block },\n\t  ];\n\n\t  Directive.typeName = \"Directive\";\n\t  Directive.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"Directive\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"rawValue\", type: STRING },\n\t  ];\n\n\t  FormalParameters.typeName = \"FormalParameters\";\n\t  FormalParameters.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"FormalParameters\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"items\", type: List(Union(ObjectBinding, ArrayBinding, BindingIdentifier, MemberExpression, BindingWithDefault)) },\n\t    { name: \"rest\", type: Maybe(BindingIdentifier) },\n\t  ];\n\n\t  FunctionBody.typeName = \"FunctionBody\";\n\t  FunctionBody.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"FunctionBody\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"directives\", type: List(Directive) },\n\t    { name: \"statements\", type: List(Statement) },\n\t  ];\n\n\t  FunctionDeclaration.typeName = \"FunctionDeclaration\";\n\t  FunctionDeclaration.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"FunctionDeclaration\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"isGenerator\", type: BOOLEAN },\n\t    { name: \"name\", type: BindingIdentifier },\n\t    { name: \"params\", type: FormalParameters },\n\t    { name: \"body\", type: FunctionBody },\n\t  ];\n\n\t  Script.typeName = \"Script\";\n\t  Script.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"Script\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"directives\", type: List(Directive) },\n\t    { name: \"statements\", type: List(Statement) },\n\t  ];\n\n\t  SpreadElement.typeName = \"SpreadElement\";\n\t  SpreadElement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"SpreadElement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"expression\", type: Expression },\n\t  ];\n\n\t  Super.typeName = \"Super\";\n\t  Super.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"Super\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t  ];\n\n\t  SwitchCase.typeName = \"SwitchCase\";\n\t  SwitchCase.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"SwitchCase\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"test\", type: Expression },\n\t    { name: \"consequent\", type: List(Statement) },\n\t  ];\n\n\t  SwitchDefault.typeName = \"SwitchDefault\";\n\t  SwitchDefault.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"SwitchDefault\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"consequent\", type: List(Statement) },\n\t  ];\n\n\t  TemplateElement.typeName = \"TemplateElement\";\n\t  TemplateElement.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"TemplateElement\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"rawValue\", type: STRING },\n\t  ];\n\n\t  VariableDeclaration.typeName = \"VariableDeclaration\";\n\t  VariableDeclaration.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"VariableDeclaration\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"kind\", type: VariableDeclarationKind },\n\t    { name: \"declarators\", type: List(VariableDeclarator) },\n\t  ];\n\n\t  VariableDeclarator.typeName = \"VariableDeclarator\";\n\t  VariableDeclarator.fields = [\n\t    { name: \"type\", type: Const(TYPE_INDICATOR), value: \"VariableDeclarator\" },\n\t    { name: \"loc\", type: Maybe(SourceSpan) },\n\t    { name: \"binding\", type: Union(ObjectBinding, ArrayBinding, BindingIdentifier, MemberExpression) },\n\t    { name: \"init\", type: Maybe(Expression) },\n\t  ];\n\n\t  return SPEC;\n\t}());\n\n\n/***/ },\n/* 54 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\n\tvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol ? \"symbol\" : typeof obj; }; /**\n\t                                                                                                                                                                                                                                                   * Copyright 2014 Shape Security, Inc.\n\t                                                                                                                                                                                                                                                   *\n\t                                                                                                                                                                                                                                                   * Licensed under the Apache License, Version 2.0 (the \"License\")\n\t                                                                                                                                                                                                                                                   * you may not use this file except in compliance with the License.\n\t                                                                                                                                                                                                                                                   * You may obtain a copy of the License at\n\t                                                                                                                                                                                                                                                   *\n\t                                                                                                                                                                                                                                                   *     http://www.apache.org/licenses/LICENSE-2.0\n\t                                                                                                                                                                                                                                                   *\n\t                                                                                                                                                                                                                                                   * Unless required by applicable law or agreed to in writing, software\n\t                                                                                                                                                                                                                                                   * distributed under the License is distributed on an \"AS IS\" BASIS,\n\t                                                                                                                                                                                                                                                   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\t                                                                                                                                                                                                                                                   * See the License for the specific language governing permissions and\n\t                                                                                                                                                                                                                                                   * limitations under the License.\n\t                                                                                                                                                                                                                                                   */\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\n\tvar _shiftSpec = __webpack_require__(53);\n\n\tvar _shiftSpec2 = _interopRequireDefault(_shiftSpec);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n\tvar methods = {};\n\n\tfunction id(x) {\n\t  return x;\n\t}\n\n\tfunction handlerForFieldOfType(type) {\n\t  switch (type.typeName) {\n\t    case \"Enum\":\n\t    case \"String\":\n\t    case \"Boolean\":\n\t    case \"Number\":\n\t    case \"SourceSpan\":\n\t      return null;\n\t    case \"Const\":\n\t      return handlerForFieldOfType(type.argument);\n\t    case \"Maybe\":\n\t      {\n\t        var _ret = function () {\n\t          var subHandler = handlerForFieldOfType(type.argument);\n\t          if (subHandler == null) return {\n\t              v: null\n\t            };\n\t          return {\n\t            v: function v(t) {\n\t              return t == null ? this.identity : subHandler.call(this, t);\n\t            }\n\t          };\n\t        }();\n\n\t        if ((typeof _ret === \"undefined\" ? \"undefined\" : _typeof(_ret)) === \"object\") return _ret.v;\n\t      }\n\t    case \"List\":\n\t      {\n\t        var _ret2 = function () {\n\t          var subHandler = handlerForFieldOfType(type.argument);\n\t          if (subHandler == null) return {\n\t              v: null\n\t            };\n\t          return {\n\t            v: function v(t) {\n\t              var _this = this;\n\n\t              return this.fold(t.map(function (x) {\n\t                return subHandler.call(_this, x);\n\t              }));\n\t            }\n\t          };\n\t        }();\n\n\t        if ((typeof _ret2 === \"undefined\" ? \"undefined\" : _typeof(_ret2)) === \"object\") return _ret2.v;\n\t      }\n\t    default:\n\t      return id;\n\t  }\n\t}\n\n\tvar _loop = function _loop(typeName) {\n\t  var type = _shiftSpec2.default[typeName];\n\n\t  var handlers = {};\n\t  type.fields.forEach(function (field) {\n\t    var handler = handlerForFieldOfType(field.type);\n\t    if (handler != null) handlers[field.name] = handler;\n\t  });\n\t  var fieldNames = Object.keys(handlers);\n\n\t  methods[\"reduce\" + typeName] = {\n\t    value: function value(node, state) {\n\t      var _this3 = this;\n\n\t      return this.fold(fieldNames.map(function (fieldName) {\n\t        return handlers[fieldName].call(_this3, state[fieldName]);\n\t      }));\n\t    }\n\t  };\n\t};\n\n\tfor (var typeName in _shiftSpec2.default) {\n\t  _loop(typeName);\n\t}\n\n\tvar MonoidalReducer = function () {\n\t  function MonoidalReducer(monoid) {\n\t    _classCallCheck(this, MonoidalReducer);\n\n\t    this.identity = monoid.empty();\n\t    var concat = monoid.prototype && monoid.prototype.concat || monoid.concat;\n\t    this.append = function (a, b) {\n\t      return concat.call(a, b);\n\t    };\n\t  }\n\n\t  _createClass(MonoidalReducer, [{\n\t    key: \"fold\",\n\t    value: function fold(list, a) {\n\t      var _this2 = this;\n\n\t      return list.reduce(function (memo, x) {\n\t        return _this2.append(memo, x);\n\t      }, a == null ? this.identity : a);\n\t    }\n\t  }]);\n\n\t  return MonoidalReducer;\n\t}();\n\n\texports.default = MonoidalReducer;\n\n\tObject.defineProperties(MonoidalReducer.prototype, methods);\n\n/***/ },\n/* 55 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\n\tvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**\n\t                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Copyright 2014 Shape Security, Inc.\n\t                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *\n\t                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Licensed under the Apache License, Version 2.0 (the \"License\")\n\t                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * you may not use this file except in compliance with the License.\n\t                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * You may obtain a copy of the License at\n\t                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *\n\t                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *     http://www.apache.org/licenses/LICENSE-2.0\n\t                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      *\n\t                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * Unless required by applicable law or agreed to in writing, software\n\t                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * distributed under the License is distributed on an \"AS IS\" BASIS,\n\t                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\t                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * See the License for the specific language governing permissions and\n\t                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      * limitations under the License.\n\t                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      */\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.TokenStream = undefined;\n\n\tvar _esutils = __webpack_require__(15);\n\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n\tfunction numberDot(fragment) {\n\t  if (fragment.indexOf(\".\") < 0 && fragment.indexOf(\"e\") < 0) {\n\t    return \"..\";\n\t  }\n\t  return \".\";\n\t}\n\n\tfunction renderNumber(n) {\n\t  var s;\n\t  if (n >= 1e3 && n % 10 === 0) {\n\t    s = n.toString(10);\n\t    if (/[eE]/.test(s)) {\n\t      return s.replace(/[eE]\\+/, \"e\");\n\t    }\n\t    return n.toString(10).replace(/0+$/, function (match) {\n\t      return \"e\" + match.length;\n\t    });\n\t  } else if (n % 1 === 0) {\n\t    if (n > 1e15 && n < 1e20) {\n\t      return \"0x\" + n.toString(16).toUpperCase();\n\t    }\n\t    return n.toString(10).replace(/[eE]\\+/, \"e\");\n\t  } else {\n\t    return n.toString(10).replace(/^0\\./, \".\").replace(/[eE]\\+/, \"e\");\n\t  }\n\t}\n\n\tvar TokenStream = exports.TokenStream = function () {\n\t  function TokenStream() {\n\t    _classCallCheck(this, TokenStream);\n\n\t    this.result = \"\";\n\t    this.lastNumber = null;\n\t    this.lastChar = null;\n\t    this.optionalSemi = false;\n\t  }\n\n\t  _createClass(TokenStream, [{\n\t    key: \"putNumber\",\n\t    value: function putNumber(number) {\n\t      var tokenStr = renderNumber(number);\n\t      this.put(tokenStr);\n\t      this.lastNumber = tokenStr;\n\t    }\n\t  }, {\n\t    key: \"putOptionalSemi\",\n\t    value: function putOptionalSemi() {\n\t      this.optionalSemi = true;\n\t    }\n\t  }, {\n\t    key: \"put\",\n\t    value: function put(tokenStr) {\n\t      if (this.optionalSemi) {\n\t        this.optionalSemi = false;\n\t        if (tokenStr !== \"}\") {\n\t          this.put(\";\");\n\t        }\n\t      }\n\t      if (this.lastNumber !== null && tokenStr.length == 1) {\n\t        if (tokenStr === \".\") {\n\t          this.result += numberDot(this.lastNumber);\n\t          this.lastNumber = null;\n\t          this.lastChar = \".\";\n\t          return;\n\t        }\n\t      }\n\t      this.lastNumber = null;\n\t      var rightChar = tokenStr.charAt(0);\n\t      var lastChar = this.lastChar;\n\t      this.lastChar = tokenStr.charAt(tokenStr.length - 1);\n\t      if (lastChar && ((lastChar == \"+\" || lastChar == \"-\") && lastChar == rightChar || _esutils.code.isIdentifierPartES6(lastChar.charCodeAt(0)) && _esutils.code.isIdentifierPartES6(rightChar.charCodeAt(0)) || lastChar == \"/\" && rightChar == \"i\")) {\n\t        this.result += \" \";\n\t      }\n\n\t      this.result += tokenStr;\n\t    }\n\t  }]);\n\n\t  return TokenStream;\n\t}();\n\n/***/ },\n/* 56 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\n\tvar _sweetSpec = __webpack_require__(43);\n\n\tvar S = _interopRequireWildcard(_sweetSpec);\n\n\tvar _ramda = __webpack_require__(20);\n\n\tvar _immutable = __webpack_require__(12);\n\n\tvar _terms = __webpack_require__(57);\n\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\n\tconst notEmptyStatement = (0, _ramda.complement)(_terms.isEmptyStatement);\n\n\texports.default = class extends S.default.CloneReducer {\n\n\t  constructor(phase) {\n\t    super();\n\t    this.phase = phase;\n\t  }\n\n\t  reduceModule(t, s) {\n\t    return new S.Module({\n\t      directives: s.directives.toArray(),\n\t      items: s.items.toArray().filter(notEmptyStatement)\n\t    });\n\t  }\n\n\t  reduceIdentifierExpression(t, s) {\n\t    return new S.IdentifierExpression({\n\t      name: s.name.resolve(this.phase)\n\t    });\n\t  }\n\n\t  reduceStaticPropertyName(t, s) {\n\t    return new S.StaticPropertyName({\n\t      value: s.value.val().toString()\n\t    });\n\t  }\n\n\t  reduceBindingIdentifier(t, s) {\n\t    return new S.BindingIdentifier({\n\t      name: s.name.resolve(this.phase)\n\t    });\n\t  }\n\n\t  reduceStaticMemberExpression(t, s) {\n\t    return new S.StaticMemberExpression({\n\t      object: s.object,\n\t      property: s.property.val()\n\t    });\n\t  }\n\n\t  reduceFunctionBody(t, s) {\n\t    return new S.FunctionBody({\n\t      directives: s.directives.toArray(),\n\t      statements: s.statements.toArray().filter(notEmptyStatement)\n\t    });\n\t  }\n\n\t  reduceVariableDeclarationStatement(t, s) {\n\t    if (t.declaration.kind === 'syntax' || t.declaration.kind === 'syntaxrec' || t.declaration.kind === 'operator') {\n\t      return new S.EmptyStatement();\n\t    }\n\t    return new S.VariableDeclarationStatement({\n\t      declaration: s.declaration\n\t    });\n\t  }\n\n\t  reduceVariableDeclaration(t, s) {\n\t    return new S.VariableDeclaration({\n\t      kind: s.kind,\n\t      declarators: s.declarators.toArray()\n\t    });\n\t  }\n\n\t  reduceCallExpression(t, s) {\n\t    return new S.CallExpression({\n\t      callee: s.callee,\n\t      arguments: s.arguments.toArray()\n\t    });\n\t  }\n\n\t  reduceArrayExpression(t, s) {\n\t    return new S.ArrayExpression({\n\t      elements: s.elements.toArray()\n\t    });\n\t  }\n\n\t  reduceImport() {\n\t    return new S.EmptyStatement({});\n\t  }\n\n\t  reduceBlock(t, s) {\n\t    return new S.Block({\n\t      statements: s.statements.toArray().filter(notEmptyStatement)\n\t    });\n\t  }\n\t};\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zd2VldC10by1zaGlmdC1yZWR1Y2VyLmpzIl0sIm5hbWVzIjpbIlMiLCJub3RFbXB0eVN0YXRlbWVudCIsIkNsb25lUmVkdWNlciIsImNvbnN0cnVjdG9yIiwicGhhc2UiLCJyZWR1Y2VNb2R1bGUiLCJ0IiwicyIsIk1vZHVsZSIsImRpcmVjdGl2ZXMiLCJ0b0FycmF5IiwiaXRlbXMiLCJmaWx0ZXIiLCJyZWR1Y2VJZGVudGlmaWVyRXhwcmVzc2lvbiIsIklkZW50aWZpZXJFeHByZXNzaW9uIiwibmFtZSIsInJlc29sdmUiLCJyZWR1Y2VTdGF0aWNQcm9wZXJ0eU5hbWUiLCJTdGF0aWNQcm9wZXJ0eU5hbWUiLCJ2YWx1ZSIsInZhbCIsInRvU3RyaW5nIiwicmVkdWNlQmluZGluZ0lkZW50aWZpZXIiLCJCaW5kaW5nSWRlbnRpZmllciIsInJlZHVjZVN0YXRpY01lbWJlckV4cHJlc3Npb24iLCJTdGF0aWNNZW1iZXJFeHByZXNzaW9uIiwib2JqZWN0IiwicHJvcGVydHkiLCJyZWR1Y2VGdW5jdGlvbkJvZHkiLCJGdW5jdGlvbkJvZHkiLCJzdGF0ZW1lbnRzIiwicmVkdWNlVmFyaWFibGVEZWNsYXJhdGlvblN0YXRlbWVudCIsImRlY2xhcmF0aW9uIiwia2luZCIsIkVtcHR5U3RhdGVtZW50IiwiVmFyaWFibGVEZWNsYXJhdGlvblN0YXRlbWVudCIsInJlZHVjZVZhcmlhYmxlRGVjbGFyYXRpb24iLCJWYXJpYWJsZURlY2xhcmF0aW9uIiwiZGVjbGFyYXRvcnMiLCJyZWR1Y2VDYWxsRXhwcmVzc2lvbiIsIkNhbGxFeHByZXNzaW9uIiwiY2FsbGVlIiwiYXJndW1lbnRzIiwicmVkdWNlQXJyYXlFeHByZXNzaW9uIiwiQXJyYXlFeHByZXNzaW9uIiwiZWxlbWVudHMiLCJyZWR1Y2VJbXBvcnQiLCJyZWR1Y2VCbG9jayIsIkJsb2NrIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFDQTs7SUFBa0JBLEM7O0FBQ2xCOztBQUNBOztBQUVBOzs7O0FBSUEs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SUFBSVAsRUFBRTRDLGVBQU4sQ0FBc0I7QUFDM0JDLGdCQUFVdEMsRUFBRXNDLFFBQUYsQ0FBV25DLE9BQVg7QUFEaUIsS0FBdEIsQ0FBUDtBQUdEOztBQUVEb0MsaUJBQWU7QUFDYixXQUFPLElBQUk5QyxFQUFFa0MsY0FBTixDQUFxQixFQUFyQixDQUFQO0FBQ0Q7O0FBRURhLGNBQVl6QyxDQUFaLEVBQXFCQyxDQUFyQixFQUFtRDtBQUNqRCxXQUFPLElBQUlQLEVBQUVnRCxLQUFOLENBQVk7QUFDakJsQixrQkFBWXZCLEVBQUV1QixVQUFGLENBQWFwQixPQUFiLEdBQXVCRSxNQUF2QixDQUE4QlgsaUJBQTlCO0FBREssS0FBWixDQUFQO0FBR0Q7QUEzRjRDLEMiLCJmaWxlIjoic3dlZXQtdG8tc2hpZnQtcmVkdWNlci5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG5pbXBvcnQgVGVybSwgKiBhcyBTIGZyb20gJ3N3ZWV0LXNwZWMnO1xuaW1wb3J0IHsgY29tcGxlbWVudCB9IGZyb20gJ3JhbWRhJztcbmltcG9ydCB7IExpc3QgfSBmcm9tICdpbW11dGFibGUnO1xuXG5pbXBvcnQgeyBpc0VtcHR5U3RhdGVtZW50IH0gZnJvbSAnLi90ZXJtcyc7XG5cbmltcG9ydCB0eXBlIFN5bnRheCBmcm9tICcuL3N5bnRheC5qcyc7XG5cbmNvbnN0IG5vdEVtcHR5U3RhdGVtZW50ID0gY29tcGxlbWVudChpc0VtcHR5U3RhdGVtZW50KTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgZXh0ZW5kcyBUZXJtLkNsb25lUmVkdWNlciB7XG4gIHBoYXNlOiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IocGhhc2U6IG51bWJlcikge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5waGFzZSA9IHBoYXNlO1xuICB9XG5cbiAgcmVkdWNlTW9kdWxlKHQ6IFRlcm0sIHM6IHsgZGlyZWN0aXZlczogTGlzdDxhbnk+LCBpdGVtczogTGlzdDxhbnk+IH0pIHtcbiAgICByZXR1cm4gbmV3IFMuTW9kdWxlKHtcbiAgICAgIGRpcmVjdGl2ZXM6IHMuZGlyZWN0aXZlcy50b0FycmF5KCksXG4gICAgICBpdGVtczogcy5pdGVtcy50b0FycmF5KCkuZmlsdGVyKG5vdEVtcHR5U3RhdGVtZW50KSxcbiAgICB9KTtcbiAgfVxuXG4gIHJlZHVjZUlkZW50aWZpZXJFeHByZXNzaW9uKHQ6IFRlcm0sIHM6IHsgbmFtZTogU3ludGF4IH0pIHtcbiAgICByZXR1cm4gbmV3IFMuSWRlbnRpZmllckV4cHJlc3Npb24oe1xuICAgICAgbmFtZTogcy5uYW1lLnJlc29sdmUodGhpcy5waGFzZSksXG4gICAgfSk7XG4gIH1cblxuICByZWR1Y2VTdGF0aWNQcm9wZXJ0eU5hbWUodDogVGVybSwgczogeyB2YWx1ZTogU3ludGF4IH0pIHtcbiAgICByZXR1cm4gbmV3IFMuU3RhdGljUHJvcGVydHlOYW1lKHtcbiAgICAgIHZhbHVlOiBzLnZhbHVlLnZhbCgpLnRvU3RyaW5nKCksXG4gICAgfSk7XG4gIH1cblxuICByZWR1Y2VCaW5kaW5nSWRlbnRpZmllcih0OiBUZXJtLCBzOiB7IG5hbWU6IFN5bnRheCB9KSB7XG4gICAgcmV0dXJuIG5ldyBTLkJpbmRpbmdJZGVudGlmaWVyKHtcbiAgICAgIG5hbWU6IHMubmFtZS5yZXNvbHZlKHRoaXMucGhhc2UpLFxuICAgIH0pO1xuICB9XG5cbiAgcmVkdWNlU3RhdGljTWVtYmVyRXhwcmVzc2lvbih0OiBUZXJtLCBzOiB7IG9iamVjdDogYW55LCBwcm9wZXJ0eTogU3ludGF4IH0pIHtcbiAgICByZXR1cm4gbmV3IFMuU3RhdGljTWVtYmVyRXhwcmVzc2lvbih7XG4gICAgICBvYmplY3Q6IHMub2JqZWN0LFxuICAgICAgcHJvcGVydHk6IHMucHJvcGVydHkudmFsKCksXG4gICAgfSk7XG4gIH1cblxuICByZWR1Y2VGdW5jdGlvbkJvZHkoXG4gICAgdDogVGVybSxcbiAgICBzOiB7IHN0YXRlbWVudHM6IExpc3Q8YW55PiwgZGlyZWN0aXZlczogTGlzdDxhbnk+IH0sXG4gICkge1xuICAgIHJldHVybiBuZXcgUy5GdW5jdGlvbkJvZHkoe1xuICAgICAgZGlyZWN0aXZlczogcy5kaXJlY3RpdmVzLnRvQXJyYXkoKSxcbiAgICAgIHN0YXRlbWVudHM6IHMuc3RhdGVtZW50cy50b0FycmF5KCkuZmlsdGVyKG5vdEVtcHR5U3RhdGVtZW50KSxcbiAgICB9KTtcbiAgfVxuXG4gIHJlZHVjZVZhcmlhYmxlRGVjbGFyYXRpb25TdGF0ZW1lbnQodDogVGVybSwgczogeyBkZWNsYXJhdGlvbjogYW55IH0pIHtcbiAgICBpZiAoXG4gICAgICB0LmRlY2xhcmF0aW9uLmtpbmQgPT09ICdzeW50YXgnIHx8XG4gICAgICB0LmRlY2xhcmF0aW9uLmtpbmQgPT09ICdzeW50YXhyZWMnIHx8XG4gICAgICB0LmRlY2xhcmF0aW9uLmtpbmQgPT09ICdvcGVyYXRvcidcbiAgICApIHtcbiAgICAgIHJldHVybiBuZXcgUy5FbXB0eVN0YXRlbWVudCgpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFMuVmFyaWFibGVEZWNsYXJhdGlvblN0YXRlbWVudCh7XG4gICAgICBkZWNsYXJhdGlvbjogcy5kZWNsYXJhdGlvbixcbiAgICB9KTtcbiAgfVxuXG4gIHJlZHVjZVZhcmlhYmxlRGVjbGFyYXRpb24odDogVGVybSwgczogeyBraW5kOiBhbnksIGRlY2xhcmF0b3JzOiBMaXN0PGFueT4gfSkge1xuICAgIHJldHVybiBuZXcgUy5WYXJpYWJsZURlY2xhcmF0aW9uKHtcbiAgICAgIGtpbmQ6IHMua2luZCxcbiAgICAgIGRlY2xhcmF0b3JzOiBzLmRlY2xhcmF0b3JzLnRvQXJyYXkoKSxcbiAgICB9KTtcbiAgfVxuXG4gIHJlZHVjZUNhbGxFeHByZXNzaW9uKHQ6IFRlcm0sIHM6IHsgY2FsbGVlOiBhbnksIGFyZ3VtZW50czogTGlzdDxhbnk+IH0pIHtcbiAgICByZXR1cm4gbmV3IFMuQ2FsbEV4cHJlc3Npb24oe1xuICAgICAgY2FsbGVlOiBzLmNhbGxlZSxcbiAgICAgIGFyZ3VtZW50czogcy5hcmd1bWVudHMudG9BcnJheSgpLFxuICAgIH0pO1xuICB9XG5cbiAgcmVkdWNlQXJyYXlFeHByZXNzaW9uKHQ6IFRlcm0sIHM6IHsgZWxlbWVudHM6IExpc3Q8YW55PiB9KSB7XG4gICAgcmV0dXJuIG5ldyBTLkFycmF5RXhwcmVzc2lvbih7XG4gICAgICBlbGVtZW50czogcy5lbGVtZW50cy50b0FycmF5KCksXG4gICAgfSk7XG4gIH1cblxuICByZWR1Y2VJbXBvcnQoKSB7XG4gICAgcmV0dXJuIG5ldyBTLkVtcHR5U3RhdGVtZW50KHt9KTtcbiAgfVxuXG4gIHJlZHVjZUJsb2NrKHQ6IFRlcm0sIHM6IHsgc3RhdGVtZW50czogTGlzdDxhbnk+IH0pIHtcbiAgICByZXR1cm4gbmV3IFMuQmxvY2soe1xuICAgICAgc3RhdGVtZW50czogcy5zdGF0ZW1lbnRzLnRvQXJyYXkoKS5maWx0ZXIobm90RW1wdHlTdGF0ZW1lbnQpLFxuICAgIH0pO1xuICB9XG59XG4iXX0=\n\n/***/ },\n/* 57 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.isExportDeclaration = exports.isImportDeclaration = exports.isCompiletimeStatement = exports.isCompiletimeDeclaration = exports.isSyntaxDeclarationStatement = exports.isExportSyntax = exports.isParenthesizedExpression = exports.isFunctionWithName = exports.isFunctionTerm = exports.isSyntaxrecDeclaration = exports.isSyntaxDeclaration = exports.isEOF = exports.isVariableDeclarator = exports.isVariableDeclaration = exports.isSyntaxTemplate = exports.isTemplateElement = exports.isSwitchDefault = exports.isSwitchCase = exports.isSuper = exports.isSpreadElement = exports.isScript = exports.isFunctionDeclaration = exports.isFunctionBody = exports.isFormalParameters = exports.isDirective = exports.isCatchClause = exports.isBlock = exports.isWithStatement = exports.isWhileStatement = exports.isVariableDeclarationStatement = exports.isTryFinallyStatement = exports.isTryCatchStatement = exports.isThrowStatement = exports.isSwitchStatementWithDefault = exports.isSwitchStatement = exports.isReturnStatement = exports.isLabeledStatement = exports.isIfStatement = exports.isForStatement = exports.isForOfStatement = exports.isForInStatement = exports.isExpressionStatement = exports.isEmptyStatement = exports.isDoWhileStatement = exports.isDebuggerStatement = exports.isCompoundAssignmentExpression = exports.isContinueStatement = exports.isBreakStatement = exports.isBlockStatement = exports.isYieldGeneratorExpression = exports.isYieldExpression = exports.isUpdateExpression = exports.isThisExpression = exports.isTemplateExpression = exports.isStaticMemberExpression = exports.isUnaryExpression = exports.isObjectExpression = exports.isNewTargetExpression = exports.isNewExpression = exports.isIdentifierExpression = exports.isFunctionExpression = exports.isConditionalExpression = exports.isComputedMemberExpression = exports.isComputedAssignmentExpression = exports.isCallExpression = exports.isBinaryExpression = exports.isAssignmentExpression = exports.isArrowExpression = exports.isArrayExpression = exports.isLiteralStringExpression = exports.isLiteralRegExpExpression = exports.isLiteralNumericExpression = exports.isLiteralNullExpression = exports.isLiteralInfinityExpression = exports.isLiteralBooleanExpression = exports.isStaticPropertyName = exports.isComputedPropertyName = exports.isShorthandProperty = exports.isDataProperty = exports.isSetter = exports.isGetter = exports.isMethod = exports.isExportSpecifier = exports.isExportDefault = exports.isExport = exports.isExportFrom = exports.isExportAllFrom = exports.isImportSpecifier = exports.isImportNamespace = exports.isImport = exports.isModule = exports.isClassElement = exports.isClassDeclaration = exports.isClassExpression = exports.isBindingPropertyProperty = exports.isBindingPropertyIdentifier = exports.isObjectBinding = exports.isArrayBinding = exports.isBindingIdentifier = exports.isBindingWithDefault = undefined;\n\n\tvar _ramda = __webpack_require__(20);\n\n\tvar R = _interopRequireWildcard(_ramda);\n\n\tvar _sweetSpec = __webpack_require__(43);\n\n\tvar _sweetSpec2 = _interopRequireDefault(_sweetSpec);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\n\t// bindings\n\tconst isBindingWithDefault = exports.isBindingWithDefault = R.whereEq({ type: 'BindingWithDefault' });\n\tconst isBindingIdentifier = exports.isBindingIdentifier = R.whereEq({ type: 'BindingIdentifier' });\n\tconst isArrayBinding = exports.isArrayBinding = R.whereEq({ type: 'ArrayBinding' });\n\tconst isObjectBinding = exports.isObjectBinding = R.whereEq({ type: 'ObjectBinding' });\n\tconst isBindingPropertyIdentifier = exports.isBindingPropertyIdentifier = R.whereEq({\n\t  type: 'BindingPropertyIdentifier'\n\t});\n\tconst isBindingPropertyProperty = exports.isBindingPropertyProperty = R.whereEq({\n\t  type: 'BindingPropertyIdentifier'\n\t});\n\n\t// class\n\tconst isClassExpression = exports.isClassExpression = R.whereEq({ type: 'ClassExpression' });\n\tconst isClassDeclaration = exports.isClassDeclaration = R.whereEq({ type: 'ClassDeclaration' });\n\tconst isClassElement = exports.isClassElement = R.whereEq({ type: 'ClassElement' });\n\n\t// modules\n\tconst isModule = exports.isModule = R.whereEq({ type: 'Module' });\n\tconst isImport = exports.isImport = R.whereEq({ type: 'Import' });\n\tconst isImportNamespace = exports.isImportNamespace = R.whereEq({ type: 'ImportNamespace' });\n\tconst isImportSpecifier = exports.isImportSpecifier = R.whereEq({ type: 'ImportSpecifier' });\n\tconst isExportAllFrom = exports.isExportAllFrom = R.whereEq({ type: 'ExportAllFrom' });\n\tconst isExportFrom = exports.isExportFrom = R.whereEq({ type: 'ExportFrom' });\n\tconst isExport = exports.isExport = R.whereEq({ type: 'Export' });\n\tconst isExportDefault = exports.isExportDefault = R.whereEq({ type: 'ExportDefault' });\n\tconst isExportSpecifier = exports.isExportSpecifier = R.whereEq({ type: 'ExportSpecifier' });\n\n\t// property definition\n\tconst isMethod = exports.isMethod = R.whereEq({ type: 'Method' });\n\tconst isGetter = exports.isGetter = R.whereEq({ type: 'Getter' });\n\tconst isSetter = exports.isSetter = R.whereEq({ type: 'Setter' });\n\tconst isDataProperty = exports.isDataProperty = R.whereEq({ type: 'DataProperty' });\n\tconst isShorthandProperty = exports.isShorthandProperty = R.whereEq({ type: 'ShorthandProperty' });\n\tconst isComputedPropertyName = exports.isComputedPropertyName = R.whereEq({\n\t  type: 'ComputedPropertyName'\n\t});\n\tconst isStaticPropertyName = exports.isStaticPropertyName = R.whereEq({ type: 'StaticPropertyName' });\n\n\t// literals\n\tconst isLiteralBooleanExpression = exports.isLiteralBooleanExpression = R.whereEq({\n\t  type: 'LiteralBooleanExpression'\n\t});\n\tconst isLiteralInfinityExpression = exports.isLiteralInfinityExpression = R.whereEq({\n\t  type: 'LiteralInfinityExpression'\n\t});\n\tconst isLiteralNullExpression = exports.isLiteralNullExpression = R.whereEq({\n\t  type: 'LiteralNullExpression'\n\t});\n\tconst isLiteralNumericExpression = exports.isLiteralNumericExpression = R.whereEq({\n\t  type: 'LiteralNumericExpression'\n\t});\n\tconst isLiteralRegExpExpression = exports.isLiteralRegExpExpression = R.whereEq({\n\t  type: 'LiteralRegExpExpression'\n\t});\n\tconst isLiteralStringExpression = exports.isLiteralStringExpression = R.whereEq({\n\t  type: 'LiteralStringExpression'\n\t});\n\n\t// expressions\n\tconst isArrayExpression = exports.isArrayExpression = R.whereEq({ type: 'ArrayExpression' });\n\tconst isArrowExpression = exports.isArrowExpression = R.whereEq({ type: 'ArrowExpression' });\n\tconst isAssignmentExpression = exports.isAssignmentExpression = R.whereEq({\n\t  type: 'AssignmentExpression'\n\t});\n\tconst isBinaryExpression = exports.isBinaryExpression = R.whereEq({ type: 'BinaryExpression' });\n\tconst isCallExpression = exports.isCallExpression = R.whereEq({ type: 'CallExpression' });\n\tconst isComputedAssignmentExpression = exports.isComputedAssignmentExpression = R.whereEq({\n\t  type: 'ComputedAssignmentExpression'\n\t});\n\tconst isComputedMemberExpression = exports.isComputedMemberExpression = R.whereEq({\n\t  type: 'ComputedMemberExpression'\n\t});\n\tconst isConditionalExpression = exports.isConditionalExpression = R.whereEq({\n\t  type: 'ConditionalExpression'\n\t});\n\tconst isFunctionExpression = exports.isFunctionExpression = R.whereEq({ type: 'FunctionExpression' });\n\tconst isIdentifierExpression = exports.isIdentifierExpression = R.whereEq({\n\t  type: 'IdentifierExpression'\n\t});\n\tconst isNewExpression = exports.isNewExpression = R.whereEq({ type: 'NewExpression' });\n\tconst isNewTargetExpression = exports.isNewTargetExpression = R.whereEq({ type: 'NewTargetExpression' });\n\tconst isObjectExpression = exports.isObjectExpression = R.whereEq({ type: 'ObjectExpression' });\n\tconst isUnaryExpression = exports.isUnaryExpression = R.whereEq({ type: 'UnaryExpression' });\n\tconst isStaticMemberExpression = exports.isStaticMemberExpression = R.whereEq({\n\t  type: 'StaticMemberExpression'\n\t});\n\tconst isTemplateExpression = exports.isTemplateExpression = R.whereEq({ type: 'TemplateExpression' });\n\tconst isThisExpression = exports.isThisExpression = R.whereEq({ type: 'ThisExpression' });\n\tconst isUpdateExpression = exports.isUpdateExpression = R.whereEq({ type: 'UpdateExpression' });\n\tconst isYieldExpression = exports.isYieldExpression = R.whereEq({ type: 'YieldExpression' });\n\tconst isYieldGeneratorExpression = exports.isYieldGeneratorExpression = R.whereEq({\n\t  type: 'YieldGeneratorExpression'\n\t});\n\n\t// statements\n\tconst isBlockStatement = exports.isBlockStatement = R.whereEq({ type: 'BlockStatement' });\n\tconst isBreakStatement = exports.isBreakStatement = R.whereEq({ type: 'BreakStatement' });\n\tconst isContinueStatement = exports.isContinueStatement = R.whereEq({ type: 'ContinueStatement' });\n\tconst isCompoundAssignmentExpression = exports.isCompoundAssignmentExpression = R.whereEq({\n\t  type: 'CompoundAssignmentExpression'\n\t});\n\tconst isDebuggerStatement = exports.isDebuggerStatement = R.whereEq({ type: 'DebuggerStatement' });\n\tconst isDoWhileStatement = exports.isDoWhileStatement = R.whereEq({ type: 'DoWhileStatement' });\n\tconst isEmptyStatement = exports.isEmptyStatement = R.whereEq({ type: 'EmptyStatement' });\n\tconst isExpressionStatement = exports.isExpressionStatement = R.whereEq({ type: 'ExpressionStatement' });\n\tconst isForInStatement = exports.isForInStatement = R.whereEq({ type: 'ForInStatement' });\n\tconst isForOfStatement = exports.isForOfStatement = R.whereEq({ type: 'ForOfStatement' });\n\tconst isForStatement = exports.isForStatement = R.whereEq({ type: 'ForStatement' });\n\tconst isIfStatement = exports.isIfStatement = R.whereEq({ type: 'IfStatement' });\n\tconst isLabeledStatement = exports.isLabeledStatement = R.whereEq({ type: 'LabeledStatement' });\n\tconst isReturnStatement = exports.isReturnStatement = R.whereEq({ type: 'ReturnStatement' });\n\tconst isSwitchStatement = exports.isSwitchStatement = R.whereEq({ type: 'SwitchStatement' });\n\tconst isSwitchStatementWithDefault = exports.isSwitchStatementWithDefault = R.whereEq({\n\t  type: 'SwitchStatementWithDefault'\n\t});\n\tconst isThrowStatement = exports.isThrowStatement = R.whereEq({ type: 'ThrowStatement' });\n\tconst isTryCatchStatement = exports.isTryCatchStatement = R.whereEq({ type: 'TryCatchStatement' });\n\tconst isTryFinallyStatement = exports.isTryFinallyStatement = R.whereEq({ type: 'TryFinallyStatement' });\n\tconst isVariableDeclarationStatement = exports.isVariableDeclarationStatement = R.whereEq({\n\t  type: 'VariableDeclarationStatement'\n\t});\n\tconst isWhileStatement = exports.isWhileStatement = R.whereEq({ type: 'WhileStatement' });\n\tconst isWithStatement = exports.isWithStatement = R.whereEq({ type: 'WithStatement' });\n\n\t// other\n\tconst isBlock = exports.isBlock = R.whereEq({ type: 'Block' });\n\tconst isCatchClause = exports.isCatchClause = R.whereEq({ type: 'CatchClause' });\n\tconst isDirective = exports.isDirective = R.whereEq({ type: 'Directive' });\n\tconst isFormalParameters = exports.isFormalParameters = R.whereEq({ type: 'FormalParameters' });\n\tconst isFunctionBody = exports.isFunctionBody = R.whereEq({ type: 'FunctionBody' });\n\tconst isFunctionDeclaration = exports.isFunctionDeclaration = R.whereEq({ type: 'FunctionDeclaration' });\n\tconst isScript = exports.isScript = R.whereEq({ type: 'Script' });\n\tconst isSpreadElement = exports.isSpreadElement = R.whereEq({ type: 'SpreadElement' });\n\tconst isSuper = exports.isSuper = R.whereEq({ type: 'Super' });\n\tconst isSwitchCase = exports.isSwitchCase = R.whereEq({ type: 'SwitchCase' });\n\tconst isSwitchDefault = exports.isSwitchDefault = R.whereEq({ type: 'SwitchDefault' });\n\tconst isTemplateElement = exports.isTemplateElement = R.whereEq({ type: 'TemplateElement' });\n\tconst isSyntaxTemplate = exports.isSyntaxTemplate = R.whereEq({ type: 'SyntaxTemplate' });\n\tconst isVariableDeclaration = exports.isVariableDeclaration = R.whereEq({ type: 'VariableDeclaration' });\n\tconst isVariableDeclarator = exports.isVariableDeclarator = R.whereEq({ type: 'VariableDeclarator' });\n\tconst isEOF = exports.isEOF = R.whereEq({ type: 'EOF' });\n\tconst isSyntaxDeclaration = exports.isSyntaxDeclaration = R.both(isVariableDeclaration, R.whereEq({ kind: 'syntax' }));\n\tconst isSyntaxrecDeclaration = exports.isSyntaxrecDeclaration = R.both(isVariableDeclaration, R.whereEq({ kind: 'syntaxrec' }));\n\tconst isFunctionTerm = exports.isFunctionTerm = R.either(isFunctionDeclaration, isFunctionExpression);\n\tconst isFunctionWithName = exports.isFunctionWithName = R.and(isFunctionTerm, R.complement(R.where({ name: R.isNil })));\n\tconst isParenthesizedExpression = exports.isParenthesizedExpression = R.whereEq({\n\t  type: 'ParenthesizedExpression'\n\t});\n\tconst isExportSyntax = exports.isExportSyntax = R.both(isExport, exp => R.or(isSyntaxDeclaration(exp.declaration), isSyntaxrecDeclaration(exp.declaration)));\n\tconst isSyntaxDeclarationStatement = exports.isSyntaxDeclarationStatement = R.both(isVariableDeclarationStatement, decl => isCompiletimeDeclaration(decl.declaration));\n\n\tconst isCompiletimeDeclaration = exports.isCompiletimeDeclaration = R.either(isSyntaxDeclaration, isSyntaxrecDeclaration);\n\tconst isCompiletimeStatement = exports.isCompiletimeStatement = term => {\n\t  return term instanceof _sweetSpec2.default && isVariableDeclarationStatement(term) && isCompiletimeDeclaration(term.declaration);\n\t};\n\tconst isImportDeclaration = exports.isImportDeclaration = R.either(isImport, isImportNamespace);\n\tconst isExportDeclaration = exports.isExportDeclaration = R.either(isExport, isExportDefault, isExportFrom, isExportAllFrom);\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXJtcy5qcyJdLCJuYW1lcyI6WyJSIiwiaXNCaW5kaW5nV2l0aERlZmF1bHQiLCJ3aGVyZUVxIiwidHlwZSIsImlzQmluZGluZ0lkZW50aWZpZXIiLCJpc0FycmF5QmluZGluZyIsImlzT2JqZWN0QmluZGluZyIsImlzQmluZGluZ1Byb3BlcnR5SWRlbnRpZmllciIsImlzQmluZGluZ1Byb3BlcnR5UHJvcGVydHkiLCJpc0NsYXNzRXhwcmVzc2lvbiIsImlzQ2xhc3NEZWNsYXJhdGlvbiIsImlzQ2xhc3NFbGVtZW50IiwiaXNNb2R1bGUiLCJpc0ltcG9ydCIsImlzSW1wb3J0TmFtZXNwYWNlIiwiaXNJbXBvcnRTcGVjaWZpZXIiLCJpc0V4cG9ydEFsbEZyb20iLCJpc0V4cG9ydEZyb20iLCJpc0V4cG9ydCIsImlzRXhwb3J0RGVmYXVsdCIsImlzRXhwb3J0U3BlY2lmaWVyIiwiaXNNZXRob2QiLCJpc0dldHRlciIsImlzU2V0dGVyIiwiaXNEYXRhUHJvcGVydHkiLCJpc1Nob3J0aGFuZFByb3BlcnR5IiwiaXNDb21wdXRlZFByb3BlcnR5TmFtZSIsImlzU3RhdGljUHJvcGVydHlOYW1lIiwiaXNMaXRlcmFsQm9vbGVhbkV4cHJlc3Npb24iLCJpc0xpdGVyYWxJbmZpbml0eUV4cHJlc3Npb24iLCJpc0xpdGVyYWxOdWxsRXhwcmVzc2lvbiIsImlzTGl0ZXJhbE51bWVyaWNFeHByZXNzaW9uIiwiaXNMaXRlcmFsUmVnRXhwRXhwcmVzc2lvbiIsImlzTGl0ZXJhbFN0cmluZ0V4cHJlc3Npb24iLCJpc0FycmF5RXhwcmVzc2lvbiIsImlzQXJyb3dFeHByZXNzaW9uIiwiaXNBc3NpZ25tZW50RXhwcmVzc2lvbiIsImlzQmluYXJ5RXhwcmVzc2lvbiIsImlzQ2FsbEV4cHJlc3Npb24iLCJpc0NvbXB1dGVkQXNzaWdubWVudEV4cHJlc3Npb24iLCJpc0NvbXB1dGVkTWVtYmVyRXhwcmVzc2lvbiIsImlzQ29uZGl0aW9uYWxFeHByZXNzaW9uIiwiaXNGdW5jdGlvbkV4cHJlc3Npb24iLCJpc0lkZW50aWZpZXJFeHByZXNzaW9uIiwiaXNOZXdFeHByZXNzaW9uIiwiaXNOZXdUYXJnZXRFeHByZXNzaW9uIiwiaXNPYmplY3RFeHByZXNzaW9uIiwiaXNVbmFyeUV4cHJlc3Npb24iLCJpc1N0YXRpY01lbWJlckV4cHJlc3Npb24iLCJpc1RlbXBsYXRlRXhwcmVzc2lvbiIsImlzVGhpc0V4cHJlc3Npb24iLCJpc1VwZGF0ZUV4cHJlc3Npb24iLCJpc1lpZWxkRXhwcmVzc2lvbiIsImlzWWllbGRHZW5lcmF0b3JFeHByZXNzaW9uIiwiaXNCbG9ja1N0YXRlbWVudCIsImlzQnJlYWtTdGF0ZW1lbnQiLCJpc0NvbnRpbnVlU3RhdGVtZW50IiwiaXNDb21wb3VuZEFzc2lnbm1lbnRFeHByZXNzaW9uIiwiaXNEZWJ1Z2dlclN0YXRlbWVudCIsImlzRG9XaGlsZVN0YXRlbWVudCIsImlzRW1wdHlTdGF0ZW1lbnQiLCJpc0V4cHJlc3Npb25TdGF0ZW1lbnQiLCJpc0ZvckluU3RhdGVtZW50IiwiaXNGb3JPZlN0YXRlbWVudCIsImlzRm9yU3RhdGVtZW50IiwiaXNJZlN0YXRlbWVudCIsImlzTGFiZWxlZFN0YXRlbWVudCIsImlzUmV0dXJuU3RhdGVtZW50IiwiaXNTd2l0Y2hTdGF0ZW1lbnQiLCJpc1N3aXRjaFN0YXRlbWVudFdpdGhEZWZhdWx0IiwiaXNUaHJvd1N0YXRlbWVudCIsImlzVHJ5Q2F0Y2hTdGF0ZW1lbnQiLCJpc1RyeUZpbmFsbHlTdGF0ZW1lbnQiLCJpc1ZhcmlhYmxlRGVjbGFyYXRpb25TdGF0ZW1lbnQiLCJpc1doaWxlU3RhdGVtZW50IiwiaXNXaXRoU3RhdGVtZW50IiwiaXNCbG9jayIsImlzQ2F0Y2hDbGF1c2UiLCJpc0RpcmVjdGl2ZSIsImlzRm9ybWFsUGFyYW1ldGVycyIsImlzRnVuY3Rpb25Cb2R5IiwiaXNGdW5jdGlvbkRlY2xhcmF0aW9uIiwiaXNTY3JpcHQiLCJpc1NwcmVhZEVsZW1lbnQiLCJpc1N1cGVyIiwiaXNTd2l0Y2hDYXNlIiwiaXNTd2l0Y2hEZWZhdWx0IiwiaXNUZW1wbGF0ZUVsZW1lbnQiLCJpc1N5bnRheFRlbXBsYXRlIiwiaXNWYXJpYWJsZURlY2xhcmF0aW9uIiwiaXNWYXJpYWJsZURlY2xhcmF0b3IiLCJpc0VPRiIsImlzU3ludGF4RGVjbGFyYXRpb24iLCJib3RoIiwia2luZCIsImlzU3ludGF4cmVjRGVjbGFyYXRpb24iLCJpc0Z1bmN0aW9uVGVybSIsImVpdGhlciIsImlzRnVuY3Rpb25XaXRoTmFtZSIsImFuZCIsImNvbXBsZW1lbnQiLCJ3aGVyZSIsIm5hbWUiLCJpc05pbCIsImlzUGFyZW50aGVzaXplZEV4cHJlc3Npb24iLCJpc0V4cG9ydFN5bnRheCIsImV4cCIsIm9yIiwiZGVjbGFyYXRpb24iLCJpc1N5bnRheERlY2xhcmF0aW9uU3RhdGVtZW50IiwiZGVjbCIsImlzQ29tcGlsZXRpbWVEZWNsYXJhdGlvbiIsImlzQ29tcGlsZXRpbWVTdGF0ZW1lbnQiLCJ0ZXJtIiwiaXNJbXBvcnREZWNsYXJhdGlvbiIsImlzRXhwb3J0RGVjbGFyYXRpb24iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7SUFBWUEsQzs7QUFDWjs7Ozs7Ozs7QUFFQTtBQUNPLE1BQU1DLHNEQUF1QkQsRUFBRUUsT0FBRixDQUFVLEVBQUVDLE1BQU0sb0JBQVIsRUFBVixDQUE3QjtBQUNBLE1BQU1DLG9EQUFzQkosRUFBRUUsT0FBRixDQUFVLEVBQUVDLE1BQU0sbUJBQVIsRUFBVixDQUE1QjtBQUNBLE1BQU1FLDBDQUFpQkwsRUFBRUUsT0FBRixDQUFVLEVBQUVDLE1BQU0sY0FBUixFQUFWLENBQXZCO0FBQ0EsTUFBTUcsNENBQWtCTixFQUFFRSxPQUFGLENBQVUsRUFBRUMsTUFBTSxlQUFSLEVBQVYsQ0FBeEI7QUFDQSxNQUFNSSxvRUFBOEJQLEVBQUVFLE9BQUYsQ0FBVTtBQUNuREMsUUFBTTtBQUQ2QyxDQUFWLENBQXBDO0FBR0EsTUFBTUssZ0VBQTRCUixFQUFFRSxPQUFGLENBQVU7QUFDakRDLFFBQU07QUFEMkMsQ0FBVixD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TUFBTU0sb0RBQXNCbEgsRUFBRWlHLE1BQUYsQ0FBU3BGLFFBQVQsRUFBbUJDLGlCQUFuQixDQUE1QjtBQUNBLE1BQU1xRyxvREFBc0JuSCxFQUFFaUcsTUFBRixDQUNqQy9FLFFBRGlDLEVBRWpDQyxlQUZpQyxFQUdqQ0YsWUFIaUMsRUFJakNELGVBSmlDLENBQTVCIiwiZmlsZSI6InRlcm1zLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgUiBmcm9tICdyYW1kYSc7XG5pbXBvcnQgVGVybSBmcm9tICdzd2VldC1zcGVjJztcblxuLy8gYmluZGluZ3NcbmV4cG9ydCBjb25zdCBpc0JpbmRpbmdXaXRoRGVmYXVsdCA9IFIud2hlcmVFcSh7IHR5cGU6ICdCaW5kaW5nV2l0aERlZmF1bHQnIH0pO1xuZXhwb3J0IGNvbnN0IGlzQmluZGluZ0lkZW50aWZpZXIgPSBSLndoZXJlRXEoeyB0eXBlOiAnQmluZGluZ0lkZW50aWZpZXInIH0pO1xuZXhwb3J0IGNvbnN0IGlzQXJyYXlCaW5kaW5nID0gUi53aGVyZUVxKHsgdHlwZTogJ0FycmF5QmluZGluZycgfSk7XG5leHBvcnQgY29uc3QgaXNPYmplY3RCaW5kaW5nID0gUi53aGVyZUVxKHsgdHlwZTogJ09iamVjdEJpbmRpbmcnIH0pO1xuZXhwb3J0IGNvbnN0IGlzQmluZGluZ1Byb3BlcnR5SWRlbnRpZmllciA9IFIud2hlcmVFcSh7XG4gIHR5cGU6ICdCaW5kaW5nUHJvcGVydHlJZGVudGlmaWVyJyxcbn0pO1xuZXhwb3J0IGNvbnN0IGlzQmluZGluZ1Byb3BlcnR5UHJvcGVydHkgPSBSLndoZXJlRXEoe1xuICB0eXBlOiAnQmluZGluZ1Byb3BlcnR5SWRlbnRpZmllcicsXG59KTtcblxuLy8gY2xhc3NcbmV4cG9ydCBjb25zdCBpc0NsYXNzRXhwcmVzc2lvbiA9IFIud2hlcmVFcSh7IHR5cGU6ICdDbGFzc0V4cHJlc3Npb24nIH0pO1xuZXhwb3J0IGNvbnN0IGlzQ2xhc3NEZWNsYXJhdGlvbiA9IFIud2hlcmVFcSh7IHR5cGU6ICdDbGFzc0RlY2xhcmF0aW9uJyB9KTtcbmV4cG9ydCBjb25zdCBpc0NsYXNzRWxlbWVudCA9IFIud2hlcmVFcSh7IHR5cGU6ICdDbGFzc0VsZW1lbnQnIH0pO1xuXG4vLyBtb2R1bGVzXG5leHBvcnQgY29uc3QgaXNNb2R1bGUgPSBSLndoZXJlRXEoeyB0eXBlOiAnTW9kdWxlJyB9KTtcbmV4cG9ydCBjb25zdCBpc0ltcG9ydCA9IFIud2hlcmVFcSh7IHR5cGU6ICdJbXBvcnQnIH0pO1xuZXhwb3J0IGNvbnN0IGlzSW1wb3J0TmFtZXNwYWNlID0gUi53aGVyZUVxKHsgdHlwZTogJ0ltcG9ydE5hbWVzcGFjZScgfSk7XG5leHBvcnQgY29uc3QgaXNJbXBvcnRTcGVjaWZpZXIgPSBSLndoZXJlRXEoeyB0eXBlOiAnSW1wb3J0U3BlY2lmaWVyJyB9KTtcbmV4cG9ydCBjb25zdCBpc0V4cG9ydEFsbEZyb20gPSBSLndoZXJlRXEoeyB0eXBlOiAnRXhwb3J0QWxsRnJvbScgfSk7XG5leHBvcnQgY29uc3QgaXNFeHBvcnRGcm9tID0gUi53aGVyZUVxKHsgdHlwZTogJ0V4cG9ydEZyb20nIH0pO1xuZXhwb3J0IGNvbnN0IGlzRXhwb3J0ID0gUi53aGVyZUVxKHsgdHlwZTogJ0V4cG9ydCcgfSk7XG5leHBvcnQgY29uc3QgaXNFeHBvcnREZWZhdWx0ID0gUi53aGVyZUVxKHsgdHlwZTogJ0V4cG9ydERlZmF1bHQnIH0pO1xuZXhwb3J0IGNvbnN0IGlzRXhwb3J0U3BlY2lmaWVyID0gUi53aGVyZUVxKHsgdHlwZTogJ0V4cG9ydFNwZWNpZmllcicgfSk7XG5cbi8vIHByb3BlcnR5IGRlZmluaXRpb25cbmV4cG9ydCBjb25zdCBpc01ldGhvZCA9IFIud2hlcmVFcSh7IHR5cGU6ICdNZXRob2QnIH0pO1xuZXhwb3J0IGNvbnN0IGlzR2V0dGVyID0gUi53aGVyZUVxKHsgdHlwZTogJ0dldHRlcicgfSk7XG5leHBvcnQgY29uc3QgaXNTZXR0ZXIgPSBSLndoZXJlRXEoeyB0eXBlOiAnU2V0dGVyJyB9KTtcbmV4cG9ydCBjb25zdCBpc0RhdGFQcm9wZXJ0eSA9IFIud2hlcmVFcSh7IHR5cGU6ICdEYXRhUHJvcGVydHknIH0pO1xuZXhwb3J0IGNvbnN0IGlzU2hvcnRoYW5kUHJvcGVydHkgPSBSLndoZXJlRXEoeyB0eXBlOiAnU2hvcnRoYW5kUHJvcGVydHknIH0pO1xuZXhwb3J0IGNvbnN0IGlzQ29tcHV0ZWRQcm9wZXJ0eU5hbWUgPSBSLndoZXJlRXEoe1xuICB0eXBlOiAnQ29tcHV0ZWRQcm9wZXJ0eU5hbWUnLFxufSk7XG5leHBvcnQgY29uc3QgaXNTdGF0aWNQcm9wZXJ0eU5hbWUgPSBSLndoZXJlRXEoeyB0eXBlOiAnU3RhdGljUHJvcGVydHlOYW1lJyB9KTtcblxuLy8gbGl0ZXJhbHNcbmV4cG9ydCBjb25zdCBpc0xpdGVyYWxCb29sZWFuRXhwcmVzc2lvbiA9IFIud2hlcmVFcSh7XG4gIHR5cGU6ICdMaXRlcmFsQm9vbGVhbkV4cHJlc3Npb24nLFxufSk7XG5leHBvcnQgY29uc3QgaXNMaXRlcmFsSW5maW5pdHlFeHByZXNzaW9uID0gUi53aGVyZUVxKHtcbiAgdHlwZTogJ0xpdGVyYWxJbmZpbml0eUV4cHJlc3Npb24nLFxufSk7XG5leHBvcnQgY29uc3QgaXNMaXRlcmFsTnVsbEV4cHJlc3Npb24gPSBSLndoZXJlRXEoe1xuICB0eXBlOiAnTGl0ZXJhbE51bGxFeHByZXNzaW9uJyxcbn0pO1xuZXhwb3J0IGNvbnN0IGlzTGl0ZXJhbE51bWVyaWNFeHByZXNzaW9uID0gUi53aGVyZUVxKHtcbiAgdHlwZTogJ0xpdGVyYWxOdW1lcmljRXhwcmVzc2lvbicsXG59KTtcbmV4cG9ydCBjb25zdCBpc0xpdGVyYWxSZWdFeHBFeHByZXNzaW9uID0gUi53aGVyZUVxKHtcbiAgdHlwZTogJ0xpdGVyYWxSZWdFeHBFeHByZXNzaW9uJyxcbn0pO1xuZXhwb3J0IGNvbnN0IGlzTGl0ZXJhbFN0cmluZ0V4cHJlc3Npb24gPSBSLndoZXJlRXEoe1xuICB0eXBlOiAnTGl0ZXJhbFN0cmluZ0V4cHJlc3Npb24nLFxufSk7XG5cbi8vIGV4cHJlc3Npb25zXG5leHBvcnQgY29uc3QgaXNBcnJheUV4cHJlc3Npb24gPSBSLndoZXJlRXEoeyB0eXBlOiAnQXJyYXlFeHByZXNzaW9uJyB9KTtcbmV4cG9ydCBjb25zdCBpc0Fycm93RXhwcmVzc2lvbiA9IFIud2hlcmVFcSh7IHR5cGU6ICdBcnJvd0V4cHJlc3Npb24nIH0pO1xuZXhwb3J0IGNvbnN0IGlzQXNzaWdubWVudEV4cHJlc3Npb24gPSBSLndoZXJlRXEoe1xuICB0eXBlOiAnQXNzaWdubWVudEV4cHJlc3Npb24nLFxufSk7XG5leHBvcnQgY29uc3QgaXNCaW5hcnlFeHByZXNzaW9uID0gUi53aGVyZUVxKHsgdHlwZTogJ0JpbmFyeUV4cHJlc3Npb24nIH0pO1xuZXhwb3J0IGNvbnN0IGlzQ2FsbEV4cHJlc3Npb24gPSBSLndoZXJlRXEoeyB0eXBlOiAnQ2FsbEV4cHJlc3Npb24nIH0pO1xuZXhwb3J0IGNvbnN0IGlzQ29tcHV0ZWRBc3NpZ25tZW50RXhwcmVzc2lvbiA9IFIud2hlcmVFcSh7XG4gIHR5cGU6ICdDb21wdXRlZEFzc2lnbm1lbnRFeHByZXNzaW9uJyxcbn0pO1xuZXhwb3J0IGNvbnN0IGlzQ29tcHV0ZWRNZW1iZXJFeHByZXNzaW9uID0gUi53aGVyZUVxKHtcbiAgdHlwZTogJ0NvbXB1dGVkTWVtYmVyRXhwcmVzc2lvbicsXG59KTtcbmV4cG9ydCBjb25zdCBpc0NvbmRpdGlvbmFsRXhwcmVzc2lvbiA9IFIud2hlcmVFcSh7XG4gIHR5cGU6ICdDb25kaXRpb25hbEV4cHJlc3Npb24nLFxufSk7XG5leHBvcnQgY29uc3QgaXNGdW5jdGlvbkV4cHJlc3Npb24gPSBSLndoZXJlRXEoeyB0eXBlOiAnRnVuY3Rpb25FeHByZXNzaW9uJyB9KTtcbmV4cG9ydCBjb25zdCBpc0lkZW50aWZpZXJFeHByZXNzaW9uID0gUi53aGVyZUVxKHtcbiAgdHlwZTogJ0lkZW50aWZpZXJFeHByZXNzaW9uJyxcbn0pO1xuZXhwb3J0IGNvbnN0IGlzTmV3RXhwcmVzc2lvbiA9IFIud2hlcmVFcSh7IHR5cGU6ICdOZXdFeHByZXNzaW9uJyB9KTtcbmV4cG9ydCBjb25zdCBpc05ld1RhcmdldEV4cHJlc3Npb24gPSBSLndoZXJlRXEoeyB0eXBlOiAnTmV3VGFyZ2V0RXhwcmVzc2lvbicgfSk7XG5leHBvcnQgY29uc3QgaXNPYmplY3RFeHByZXNzaW9uID0gUi53aGVyZUVxKHsgdHlwZTogJ09iamVjdEV4cHJlc3Npb24nIH0pO1xuZXhwb3J0IGNvbnN0IGlzVW5hcnlFeHByZXNzaW9uID0gUi53aGVyZUVxKHsgdHlwZTogJ1VuYXJ5RXhwcmVzc2lvbicgfSk7XG5leHBvcnQgY29uc3QgaXNTdGF0aWNNZW1iZXJFeHByZXNzaW9uID0gUi53aGVyZUVxKHtcbiAgdHlwZTogJ1N0YXRpY01lbWJlckV4cHJlc3Npb24nLFxufSk7XG5leHBvcnQgY29uc3QgaXNUZW1wbGF0ZUV4cHJlc3Npb24gPSBSLndoZXJlRXEoeyB0eXBlOiAnVGVtcGxhdGVFeHByZXNzaW9uJyB9KTtcbmV4cG9ydCBjb25zdCBpc1RoaXNFeHByZXNzaW9uID0gUi53aGVyZUVxKHsgdHlwZTogJ1RoaXNFeHByZXNzaW9uJyB9KTtcbmV4cG9ydCBjb25zdCBpc1VwZGF0ZUV4cHJlc3Npb24gPSBSLndoZXJlRXEoeyB0eXBlOiAnVXBkYXRlRXhwcmVzc2lvbicgfSk7XG5leHBvcnQgY29uc3QgaXNZaWVsZEV4cHJlc3Npb24gPSBSLndoZXJlRXEoeyB0eXBlOiAnWWllbGRFeHByZXNzaW9uJyB9KTtcbmV4cG9ydCBjb25zdCBpc1lpZWxkR2VuZXJhdG9yRXhwcmVzc2lvbiA9IFIud2hlcmVFcSh7XG4gIHR5cGU6ICdZaWVsZEdlbmVyYXRvckV4cHJlc3Npb24nLFxufSk7XG5cbi8vIHN0YXRlbWVudHNcbmV4cG9ydCBjb25zdCBpc0Jsb2NrU3RhdGVtZW50ID0gUi53aGVyZUVxKHsgdHlwZTogJ0Jsb2NrU3RhdGVtZW50JyB9KTtcbmV4cG9ydCBjb25zdCBpc0JyZWFrU3RhdGVtZW50ID0gUi53aGVyZUVxKHsgdHlwZTogJ0JyZWFrU3RhdGVtZW50JyB9KTtcbmV4cG9ydCBjb25zdCBpc0NvbnRpbnVlU3RhdGVtZW50ID0gUi53aGVyZUVxKHsgdHlwZTogJ0NvbnRpbnVlU3RhdGVtZW50JyB9KTtcbmV4cG9ydCBjb25zdCBpc0NvbXBvdW5kQXNzaWdubWVudEV4cHJlc3Npb24gPSBSLndoZXJlRXEoe1xuICB0eXBlOiAnQ29tcG91bmRBc3NpZ25tZW50RXhwcmVzc2lvbicsXG59KTtcbmV4cG9ydCBjb25zdCBpc0RlYnVnZ2VyU3RhdGVtZW50ID0gUi53aGVyZUVxKHsgdHlwZTogJ0RlYnVnZ2VyU3RhdGVtZW50JyB9KTtcbmV4cG9ydCBjb25zdCBpc0RvV2hpbGVTdGF0ZW1lbnQgPSBSLndoZXJlRXEoeyB0eXBlOiAnRG9XaGlsZVN0YXRlbWVudCcgfSk7XG5leHBvcnQgY29uc3QgaXNFbXB0eVN0YXRlbWVudCA9IFIud2hlcmVFcSh7IHR5cGU6ICdFbXB0eVN0YXRlbWVudCcgfSk7XG5leHBvcnQgY29uc3QgaXNFeHByZXNzaW9uU3RhdGVtZW50ID0gUi53aGVyZUVxKHsgdHlwZTogJ0V4cHJlc3Npb25TdGF0ZW1lbnQnIH0pO1xuZXhwb3J0IGNvbnN0IGlzRm9ySW5TdGF0ZW1lbnQgPSBSLndoZXJlRXEoeyB0eXBlOiAnRm9ySW5TdGF0ZW1lbnQnIH0pO1xuZXhwb3J0IGNvbnN0IGlzRm9yT2ZTdGF0ZW1lbnQgPSBSLndoZXJlRXEoeyB0eXBlOiAnRm9yT2ZTdGF0ZW1lbnQnIH0pO1xuZXhwb3J0IGNvbnN0IGlzRm9yU3RhdGVtZW50ID0gUi53aGVyZUVxKHsgdHlwZTogJ0ZvclN0YXRlbWVudCcgfSk7XG5leHBvcnQgY29uc3QgaXNJZlN0YXRlbWVudCA9IFIud2hlcmVFcSh7IHR5cGU6ICdJZlN0YXRlbWVudCcgfSk7XG5leHBvcnQgY29uc3QgaXNMYWJlbGVkU3RhdGVtZW50ID0gUi53aGVyZUVxKHsgdHlwZTogJ0xhYmVsZWRTdGF0ZW1lbnQnIH0pO1xuZXhwb3J0IGNvbnN0IGlzUmV0dXJuU3RhdGVtZW50ID0gUi53aGVyZUVxKHsgdHlwZTogJ1JldHVyblN0YXRlbWVudCcgfSk7XG5leHBvcnQgY29uc3QgaXNTd2l0Y2hTdGF0ZW1lbnQgPSBSLndoZXJlRXEoeyB0eXBlOiAnU3dpdGNoU3RhdGVtZW50JyB9KTtcbmV4cG9ydCBjb25zdCBpc1N3aXRjaFN0YXRlbWVudFdpdGhEZWZhdWx0ID0gUi53aGVyZUVxKHtcbiAgdHlwZTogJ1N3aXRjaFN0YXRlbWVudFdpdGhEZWZhdWx0Jyxcbn0pO1xuZXhwb3J0IGNvbnN0IGlzVGhyb3dTdGF0ZW1lbnQgPSBSLndoZXJlRXEoeyB0eXBlOiAnVGhyb3dTdGF0ZW1lbnQnIH0pO1xuZXhwb3J0IGNvbnN0IGlzVHJ5Q2F0Y2hTdGF0ZW1lbnQgPSBSLndoZXJlRXEoeyB0eXBlOiAnVHJ5Q2F0Y2hTdGF0ZW1lbnQnIH0pO1xuZXhwb3J0IGNvbnN0IGlzVHJ5RmluYWxseVN0YXRlbWVudCA9IFIud2hlcmVFcSh7IHR5cGU6ICdUcnlGaW5hbGx5U3RhdGVtZW50JyB9KTtcbmV4cG9ydCBjb25zdCBpc1ZhcmlhYmxlRGVjbGFyYXRpb25TdGF0ZW1lbnQgPSBSLndoZXJlRXEoe1xuICB0eXBlOiAnVmFyaWFibGVEZWNsYXJhdGlvblN0YXRlbWVudCcsXG59KTtcbmV4cG9ydCBjb25zdCBpc1doaWxlU3RhdGVtZW50ID0gUi53aGVyZUVxKHsgdHlwZTogJ1doaWxlU3RhdGVtZW50JyB9KTtcbmV4cG9ydCBjb25zdCBpc1dpdGhTdGF0ZW1lbnQgPSBSLndoZXJlRXEoeyB0eXBlOiAnV2l0aFN0YXRlbWVudCcgfSk7XG5cbi8vIG90aGVyXG5leHBvcnQgY29uc3QgaXNCbG9jayA9IFIud2hlcmVFcSh7IHR5cGU6ICdCbG9jaycgfSk7XG5leHBvcnQgY29uc3QgaXNDYXRjaENsYXVzZSA9IFIud2hlcmVFcSh7IHR5cGU6ICdDYXRjaENsYXVzZScgfSk7XG5leHBvcnQgY29uc3QgaXNEaXJlY3RpdmUgPSBSLndoZXJlRXEoeyB0eXBlOiAnRGlyZWN0aXZlJyB9KTtcbmV4cG9ydCBjb25zdCBpc0Zvcm1hbFBhcmFtZXRlcnMgPSBSLndoZXJlRXEoeyB0eXBlOiAnRm9ybWFsUGFyYW1ldGVycycgfSk7XG5leHBvcnQgY29uc3QgaXNGdW5jdGlvbkJvZHkgPSBSLndoZXJlRXEoeyB0eXBlOiAnRnVuY3Rpb25Cb2R5JyB9KTtcbmV4cG9ydCBjb25zdCBpc0Z1bmN0aW9uRGVjbGFyYXRpb24gPSBSLndoZXJlRXEoeyB0eXBlOiAnRnVuY3Rpb25EZWNsYXJhdGlvbicgfSk7XG5leHBvcnQgY29uc3QgaXNTY3JpcHQgPSBSLndoZXJlRXEoeyB0eXBlOiAnU2NyaXB0JyB9KTtcbmV4cG9ydCBjb25zdCBpc1NwcmVhZEVsZW1lbnQgPSBSLndoZXJlRXEoeyB0eXBlOiAnU3ByZWFkRWxlbWVudCcgfSk7XG5leHBvcnQgY29uc3QgaXNTdXBlciA9IFIud2hlcmVFcSh7IHR5cGU6ICdTdXBlcicgfSk7XG5leHBvcnQgY29uc3QgaXNTd2l0Y2hDYXNlID0gUi53aGVyZUVxKHsgdHlwZTogJ1N3aXRjaENhc2UnIH0pO1xuZXhwb3J0IGNvbnN0IGlzU3dpdGNoRGVmYXVsdCA9IFIud2hlcmVFcSh7IHR5cGU6ICdTd2l0Y2hEZWZhdWx0JyB9KTtcbmV4cG9ydCBjb25zdCBpc1RlbXBsYXRlRWxlbWVudCA9IFIud2hlcmVFcSh7IHR5cGU6ICdUZW1wbGF0ZUVsZW1lbnQnIH0pO1xuZXhwb3J0IGNvbnN0IGlzU3ludGF4VGVtcGxhdGUgPSBSLndoZXJlRXEoeyB0eXBlOiAnU3ludGF4VGVtcGxhdGUnIH0pO1xuZXhwb3J0IGNvbnN0IGlzVmFyaWFibGVEZWNsYXJhdGlvbiA9IFIud2hlcmVFcSh7IHR5cGU6ICdWYXJpYWJsZURlY2xhcmF0aW9uJyB9KTtcbmV4cG9ydCBjb25zdCBpc1ZhcmlhYmxlRGVjbGFyYXRvciA9IFIud2hlcmVFcSh7IHR5cGU6ICdWYXJpYWJsZURlY2xhcmF0b3InIH0pO1xuZXhwb3J0IGNvbnN0IGlzRU9GID0gUi53aGVyZUVxKHsgdHlwZTogJ0VPRicgfSk7XG5leHBvcnQgY29uc3QgaXNTeW50YXhEZWNsYXJhdGlvbiA9IFIuYm90aChcbiAgaXNWYXJpYWJsZURlY2xhcmF0aW9uLFxuICBSLndoZXJlRXEoeyBraW5kOiAnc3ludGF4JyB9KSxcbik7XG5leHBvcnQgY29uc3QgaXNTeW50YXhyZWNEZWNsYXJhdGlvbiA9IFIuYm90aChcbiAgaXNWYXJpYWJsZURlY2xhcmF0aW9uLFxuICBSLndoZXJlRXEoeyBraW5kOiAnc3ludGF4cmVjJyB9KSxcbik7XG5leHBvcnQgY29uc3QgaXNGdW5jdGlvblRlcm0gPSBSLmVpdGhlcihcbiAgaXNGdW5jdGlvbkRlY2xhcmF0aW9uLFxuICBpc0Z1bmN0aW9uRXhwcmVzc2lvbixcbik7XG5leHBvcnQgY29uc3QgaXNGdW5jdGlvbldpdGhOYW1lID0gUi5hbmQoXG4gIGlzRnVuY3Rpb25UZXJtLFxuICBSLmNvbXBsZW1lbnQoUi53aGVyZSh7IG5hbWU6IFIuaXNOaWwgfSkpLFxuKTtcbmV4cG9ydCBjb25zdCBpc1BhcmVudGhlc2l6ZWRFeHByZXNzaW9uID0gUi53aGVyZUVxKHtcbiAgdHlwZTogJ1BhcmVudGhlc2l6ZWRFeHByZXNzaW9uJyxcbn0pO1xuZXhwb3J0IGNvbnN0IGlzRXhwb3J0U3ludGF4ID0gUi5ib3RoKGlzRXhwb3J0LCBleHAgPT5cbiAgUi5vcihcbiAgICBpc1N5bnRheERlY2xhcmF0aW9uKGV4cC5kZWNsYXJhdGlvbiksXG4gICAgaXNTeW50YXhyZWNEZWNsYXJhdGlvbihleHAuZGVjbGFyYXRpb24pLFxuICApKTtcbmV4cG9ydCBjb25zdCBpc1N5bnRheERlY2xhcmF0aW9uU3RhdGVtZW50ID0gUi5ib3RoKFxuICBpc1ZhcmlhYmxlRGVjbGFyYXRpb25TdGF0ZW1lbnQsXG4gIGRlY2wgPT4gaXNDb21waWxldGltZURlY2xhcmF0aW9uKGRlY2wuZGVjbGFyYXRpb24pLFxuKTtcblxuZXhwb3J0IGNvbnN0IGlzQ29tcGlsZXRpbWVEZWNsYXJhdGlvbiA9IFIuZWl0aGVyKFxuICBpc1N5bnRheERlY2xhcmF0aW9uLFxuICBpc1N5bnRheHJlY0RlY2xhcmF0aW9uLFxuKTtcbmV4cG9ydCBjb25zdCBpc0NvbXBpbGV0aW1lU3RhdGVtZW50ID0gdGVybSA9PiB7XG4gIHJldHVybiB0ZXJtIGluc3RhbmNlb2YgVGVybSAmJlxuICAgIGlzVmFyaWFibGVEZWNsYXJhdGlvblN0YXRlbWVudCh0ZXJtKSAmJlxuICAgIGlzQ29tcGlsZXRpbWVEZWNsYXJhdGlvbih0ZXJtLmRlY2xhcmF0aW9uKTtcbn07XG5leHBvcnQgY29uc3QgaXNJbXBvcnREZWNsYXJhdGlvbiA9IFIuZWl0aGVyKGlzSW1wb3J0LCBpc0ltcG9ydE5hbWVzcGFjZSk7XG5leHBvcnQgY29uc3QgaXNFeHBvcnREZWNsYXJhdGlvbiA9IFIuZWl0aGVyKFxuICBpc0V4cG9ydCxcbiAgaXNFeHBvcnREZWZhdWx0LFxuICBpc0V4cG9ydEZyb20sXG4gIGlzRXhwb3J0QWxsRnJvbSxcbik7XG4iXX0=\n\n/***/ },\n/* 58 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.ALL_PHASES = exports.Types = undefined;\n\n\tvar _immutable = __webpack_require__(12);\n\n\tvar _errors = __webpack_require__(59);\n\n\tvar _bindingMap = __webpack_require__(60);\n\n\tvar _bindingMap2 = _interopRequireDefault(_bindingMap);\n\n\tvar _ramdaFantasy = __webpack_require__(21);\n\n\tvar _ramda = __webpack_require__(20);\n\n\tvar _ = _interopRequireWildcard(_ramda);\n\n\tvar _sweetSpec = __webpack_require__(43);\n\n\tvar T = _interopRequireWildcard(_sweetSpec);\n\n\tvar _tokens = __webpack_require__(19);\n\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tfunction getFirstSlice(stx) {\n\t  if (!stx || typeof stx.isDelimiter !== 'function') return null; // TODO: should not have to do this\n\t  if (!stx.isDelimiter()) {\n\t    return stx.token.slice;\n\t  }\n\t  return stx.token.get(0).token.slice;\n\t}\n\n\n\tfunction sizeDecending(a, b) {\n\t  if (a.scopes.size > b.scopes.size) {\n\t    return -1;\n\t  } else if (b.scopes.size > a.scopes.size) {\n\t    return 1;\n\t  } else {\n\t    return 0;\n\t  }\n\t}\n\n\tlet Types = exports.Types = {\n\t  null: {\n\t    match: token => !Types.delimiter.match(token) && token.type === _tokens.TokenType.NULL,\n\t    create: (value, stx) => new Syntax({\n\t      type: _tokens.TokenType.NULL,\n\t      value: null,\n\t      typeCode: _tokens.TypeCodes.Keyword\n\t    }, stx)\n\t  },\n\t  number: {\n\t    match: token => !Types.delimiter.match(token) && token.type.klass === _tokens.TokenClass.NumericLiteral,\n\t    create: (value, stx) => new Syntax({\n\t      type: _tokens.TokenType.NUMBER,\n\t      value,\n\t      typeCode: _tokens.TypeCodes.NumericLiteral\n\t    }, stx)\n\t  },\n\t  string: {\n\t    match: token => !Types.delimiter.match(token) && token.type.klass === _tokens.TokenClass.StringLiteral,\n\t    create: (value, stx) => new Syntax({\n\t      type: _tokens.TokenType.STRING,\n\t      str: value,\n\t      typeCode: _tokens.TypeCodes.StringLiteral\n\t    }, stx)\n\t  },\n\t  punctuator: {\n\t    match: token => !Types.delimiter.match(token) && token.type.klass === _tokens.TokenClass.Punctuator,\n\t    create: (value, stx) => new Syntax({\n\t      type: {\n\t        klass: _tokens.TokenClass.Punctuator,\n\t        name: value\n\t      },\n\t      typeCode: _tokens.TypeCodes.Punctuator,\n\t      value\n\t    }, stx)\n\t  },\n\t  keyword: {\n\t    match: token => !Types.delimiter.match(token) && token.type.klass === _tokens.TokenClass.Keyword,\n\t    create: (value, stx) => new Syntax({\n\t      type: {\n\t        klass: _tokens.TokenClass.Keyword,\n\t        name: value\n\t      },\n\t      typeCode: _tokens.TypeCodes.Keyword,\n\t      value\n\t    }, stx)\n\t  },\n\t  identifier: {\n\t    match: token => !Types.delimiter.match(token) && token.type.klass === _tokens.TokenClass.Ident,\n\t    create: (value, stx) => new Syntax({\n\t      type: _tokens.TokenType.IDENTIFIER,\n\t      value,\n\t      typeCode: _tokens.TypeCodes.Identifier\n\t    }, stx)\n\t  },\n\t  regularExpression: {\n\t    match: token => !Types.delimiter.match(token) && token.type.klass === _tokens.TokenClass.RegularExpression,\n\t    create: (value, stx) => new Syntax({\n\t      type: _tokens.TokenType.REGEXP,\n\t      value,\n\t      typeCode: _tokens.TypeCodes.RegExp\n\t    }, stx)\n\t  },\n\t  braces: {\n\t    match: token => Types.delimiter.match(token) && token.get(0).token.type === _tokens.TokenType.LBRACE,\n\t    create: (inner, stx) => {\n\t      let left = new T.RawSyntax({\n\t        value: new Syntax({\n\t          type: _tokens.TokenType.LBRACE,\n\t          typeCode: _tokens.TypeCodes.Punctuator,\n\t          value: '{',\n\t          slice: getFirstSlice(stx)\n\t        })\n\t      });\n\t      let right = new T.RawSyntax({\n\t        value: new Syntax({\n\t          type: _tokens.TokenType.RBRACE,\n\t          typeCode: _tokens.TypeCodes.Punctuator,\n\t          value: '}',\n\t          slice: getFirstSlice(stx)\n\t        })\n\t      });\n\t      return new T.RawDelimiter({\n\t        kind: 'braces',\n\t        inner: _immutable.List.of(left).concat(inner).push(right)\n\t      });\n\t    }\n\t  },\n\t  brackets: {\n\t    match: token => Types.delimiter.match(token) && token.get(0).token.type === _tokens.TokenType.LBRACK,\n\t    create: (inner, stx) => {\n\t      let left = new T.RawSyntax({\n\t        value: new Syntax({\n\t          type: _tokens.TokenType.LBRACK,\n\t          typeCode: _tokens.TypeCodes.Punctuator,\n\t          value: '[',\n\t          slice: getFirstSlice(stx)\n\t        })\n\t      });\n\t      let right = new T.RawSyntax({\n\t        value: new Syntax({\n\t          type: _tokens.TokenType.RBRACK,\n\t          typeCode: _tokens.TypeCodes.Punctuator,\n\t          value: ']',\n\t          slice: getFirstSlice(stx)\n\t        })\n\t      });\n\t      return new T.RawDelimiter({\n\t        kind: 'brackets',\n\t        inner: _immutable.List.of(left).concat(inner).push(right)\n\t      });\n\t    }\n\t  },\n\t  parens: {\n\t    match: token => Types.delimiter.match(token) && token.get(0).token.type === _tokens.TokenType.LPAREN,\n\t    create: (inner, stx) => {\n\t      let left = new T.RawSyntax({\n\t        value: new Syntax({\n\t          type: _tokens.TokenType.LPAREN,\n\t          typeCode: _tokens.TypeCodes.Punctuator,\n\t          value: '(',\n\t          slice: getFirstSlice(stx)\n\t        })\n\t      });\n\t      let right = new T.RawSyntax({\n\t        value: new Syntax({\n\t          type: _tokens.TokenType.RPAREN,\n\t          typeCode: _tokens.TypeCodes.Punctuator,\n\t          value: ')',\n\t          slice: getFirstSlice(stx)\n\t        })\n\t      });\n\t      return new T.RawDelimiter({\n\t        kind: 'parens',\n\t        inner: _immutable.List.of(left).concat(inner).push(right)\n\t      });\n\t    }\n\t  },\n\n\t  assign: {\n\t    match: token => {\n\t      if (Types.punctuator.match(token)) {\n\t        switch (token.value) {\n\t          case '=':\n\t          case '|=':\n\t          case '^=':\n\t          case '&=':\n\t          case '<<=':\n\t          case '>>=':\n\t          case '>>>=':\n\t          case '+=':\n\t          case '-=':\n\t          case '*=':\n\t          case '/=':\n\t          case '%=':\n\t            return true;\n\t          default:\n\t            return false;\n\t        }\n\t      }\n\t      return false;\n\t    }\n\t  },\n\n\t  boolean: {\n\t    match: token => !Types.delimiter.match(token) && token.type === _tokens.TokenType.TRUE || token.type === _tokens.TokenType.FALSE\n\t  },\n\n\t  template: {\n\t    match: token => !Types.delimiter.match(token) && token.type === _tokens.TokenType.TEMPLATE\n\t  },\n\n\t  delimiter: {\n\t    match: token => _immutable.List.isList(token)\n\t  },\n\n\t  syntaxTemplate: {\n\t    match: token => Types.delimiter.match(token) && token.get(0).val() === '#`'\n\t  },\n\n\t  eof: {\n\t    match: token => !Types.delimiter.match(token) && token.type === _tokens.TokenType.EOS\n\t  }\n\t};\n\tconst ALL_PHASES = exports.ALL_PHASES = {};\n\n\tclass Syntax {\n\n\t  constructor(token, oldstx) {\n\t    this.token = token;\n\t    this.bindings = oldstx && oldstx.bindings != null ? oldstx.bindings : new _bindingMap2.default();\n\t    this.scopesets = oldstx && oldstx.scopesets != null ? oldstx.scopesets : {\n\t      all: (0, _immutable.List)(),\n\t      phase: (0, _immutable.Map)()\n\t    };\n\t    Object.freeze(this);\n\t  }\n\t  // token: Token | List<Token>;\n\n\n\t  static of(token, stx) {\n\t    return new Syntax(token, stx);\n\t  }\n\n\t  static from(type, value, stx) {\n\t    if (!Types[type]) {\n\t      throw new Error(type + ' is not a valid type');\n\t    } else if (!Types[type].create) {\n\t      throw new Error('Cannot create a syntax from type ' + type);\n\t    }\n\t    let newstx = Types[type].create(value, stx);\n\t    let slice = getFirstSlice(stx);\n\t    if (slice != null && newstx.token != null) {\n\t      newstx.token.slice = slice;\n\t    }\n\t    return newstx;\n\t  }\n\n\t  from(type, value) {\n\t    // TODO: this is gross, fix\n\t    let s = Syntax.from(type, value, this);\n\t    if (s instanceof Syntax) {\n\t      return new T.RawSyntax({ value: s });\n\t    }\n\t    return s;\n\t  }\n\n\t  fromNull() {\n\t    return this.from('null', null);\n\t  }\n\n\t  fromNumber(value) {\n\t    return this.from('number', value);\n\t  }\n\n\t  fromString(value) {\n\t    return this.from('string', value);\n\t  }\n\n\t  fromPunctuator(value) {\n\t    return this.from('punctuator', value);\n\t  }\n\n\t  fromKeyword(value) {\n\t    return this.from('keyword', value);\n\t  }\n\n\t  fromIdentifier(value) {\n\t    return this.from('identifier', value);\n\t  }\n\n\t  fromRegularExpression(value) {\n\t    return this.from('regularExpression', value);\n\t  }\n\n\t  static fromNull(stx) {\n\t    return Syntax.from('null', null, stx);\n\t  }\n\n\t  static fromNumber(value, stx) {\n\t    return Syntax.from('number', value, stx);\n\t  }\n\n\t  static fromString(value, stx) {\n\t    return Syntax.from('string', value, stx);\n\t  }\n\n\t  static fromPunctuator(value, stx) {\n\t    return Syntax.from('punctuator', value, stx);\n\t  }\n\n\t  static fromKeyword(value, stx) {\n\t    return Syntax.from('keyword', value, stx);\n\t  }\n\n\t  static fromIdentifier(value, stx) {\n\t    return Syntax.from('identifier', value, stx);\n\t  }\n\n\t  static fromRegularExpression(value, stx) {\n\t    return Syntax.from('regularExpression', value, stx);\n\t  }\n\n\t  // () -> string\n\t  resolve(phase) {\n\t    (0, _errors.assert)(phase != null, 'must provide a phase to resolve');\n\t    let allScopes = this.scopesets.all;\n\t    let stxScopes = this.scopesets.phase.has(phase) ? this.scopesets.phase.get(phase) : (0, _immutable.List)();\n\t    stxScopes = allScopes.concat(stxScopes);\n\t    if (stxScopes.size === 0 || !(this.match('identifier') || this.match('keyword') || this.match('punctuator'))) {\n\t      return this.token.value;\n\t    }\n\t    let scope = stxScopes.last();\n\t    let bindings = this.bindings;\n\t    if (scope) {\n\t      // List<{ scopes: List<Scope>, binding: Symbol }>\n\t      let scopesetBindingList = bindings.get(this);\n\n\t      if (scopesetBindingList) {\n\t        // { scopes: List<Scope>, binding: Symbol }\n\t        let biggestBindingPair = scopesetBindingList.filter(({ scopes }) => {\n\t          return scopes.isSubset(stxScopes);\n\t        }).sort(sizeDecending);\n\n\t        if (biggestBindingPair.size >= 2 && biggestBindingPair.get(0).scopes.size === biggestBindingPair.get(1).scopes.size) {\n\t          let debugBase = '{' + stxScopes.map(s => s.toString()).join(', ') + '}';\n\t          let debugAmbigousScopesets = biggestBindingPair.map(({ scopes }) => {\n\t            return '{' + scopes.map(s => s.toString()).join(', ') + '}';\n\t          }).join(', ');\n\t          throw new Error('Scopeset ' + debugBase + ' has ambiguous subsets ' + debugAmbigousScopesets);\n\t        } else if (biggestBindingPair.size !== 0) {\n\t          let bindingStr = biggestBindingPair.get(0).binding.toString();\n\t          if (_ramdaFantasy.Maybe.isJust(biggestBindingPair.get(0).alias)) {\n\t            // null never happens because we just checked if it is a Just\n\t            return biggestBindingPair.get(0).alias.getOrElse(null).resolve(phase);\n\t          }\n\t          return bindingStr;\n\t        }\n\t      }\n\t    }\n\t    return this.token.value;\n\t  }\n\n\t  val() {\n\t    (0, _errors.assert)(!this.match('delimiter'), 'cannot get the val of a delimiter');\n\t    if (this.match('string')) {\n\t      return this.token.str;\n\t    }\n\t    if (this.match('template')) {\n\t      if (!this.token.items) return this.token.value;\n\t      return this.token.items.map(el => {\n\t        if (typeof el.match === 'function' && el.match('delimiter')) {\n\t          return '${...}';\n\t        }\n\t        return el.slice.text;\n\t      }).join('');\n\t    }\n\t    return this.token.value;\n\t  }\n\n\t  lineNumber() {\n\t    if (!this.match('delimiter')) {\n\t      return this.token.slice.startLocation.line;\n\t    } else {\n\t      return this.token.get(0).lineNumber();\n\t    }\n\t  }\n\n\t  setLineNumber(line) {\n\t    let newTok = {};\n\t    if (this.isDelimiter()) {\n\t      newTok = this.token.map(s => s.setLineNumber(line));\n\t    } else {\n\t      for (let key of Object.keys(this.token)) {\n\t        newTok[key] = this.token[key];\n\t      }\n\t      (0, _errors.assert)(newTok.slice && newTok.slice.startLocation, 'all tokens must have line info');\n\t      newTok.slice.startLocation.line = line;\n\t    }\n\t    return new Syntax(newTok, this);\n\t  }\n\n\t  // () -> List<Syntax>\n\t  // inner() {\n\t  //   assert(this.match(\"delimiter\"), \"can only get the inner of a delimiter\");\n\t  //   return this.token.slice(1, this.token.size - 1);\n\t  // }\n\n\t  addScope(scope, bindings, phase, options = { flip: false }) {\n\t    let token = this.match('delimiter') ? this.token.map(s => s.addScope(scope, bindings, phase, options)) : this.token;\n\t    if (this.match('template')) {\n\t      token = _.merge(token, {\n\t        items: token.items.map(it => {\n\t          if (it instanceof Syntax && it.match('delimiter')) {\n\t            return it.addScope(scope, bindings, phase, options);\n\t          }\n\t          return it;\n\t        })\n\t      });\n\t    }\n\t    let oldScopeset;\n\t    if (phase === ALL_PHASES) {\n\t      oldScopeset = this.scopesets.all;\n\t    } else {\n\t      oldScopeset = this.scopesets.phase.has(phase) ? this.scopesets.phase.get(phase) : (0, _immutable.List)();\n\t    }\n\t    let newScopeset;\n\t    if (options.flip) {\n\t      let index = oldScopeset.indexOf(scope);\n\t      if (index !== -1) {\n\t        newScopeset = oldScopeset.remove(index);\n\t      } else {\n\t        newScopeset = oldScopeset.push(scope);\n\t      }\n\t    } else {\n\t      newScopeset = oldScopeset.push(scope);\n\t    }\n\t    let newstx = {\n\t      bindings,\n\t      scopesets: {\n\t        all: this.scopesets.all,\n\t        phase: this.scopesets.phase\n\t      }\n\t    };\n\n\t    if (phase === ALL_PHASES) {\n\t      newstx.scopesets.all = newScopeset;\n\t    } else {\n\t      newstx.scopesets.phase = newstx.scopesets.phase.set(phase, newScopeset);\n\t    }\n\t    return new Syntax(token, newstx);\n\t  }\n\n\t  removeScope(scope, phase) {\n\t    let token = this.match('delimiter') ? this.token.map(s => s.removeScope(scope, phase)) : this.token;\n\t    let phaseScopeset = this.scopesets.phase.has(phase) ? this.scopesets.phase.get(phase) : (0, _immutable.List)();\n\t    let allScopeset = this.scopesets.all;\n\t    let newstx = {\n\t      bindings: this.bindings,\n\t      scopesets: {\n\t        all: this.scopesets.all,\n\t        phase: this.scopesets.phase\n\t      }\n\t    };\n\n\t    let phaseIndex = phaseScopeset.indexOf(scope);\n\t    let allIndex = allScopeset.indexOf(scope);\n\t    if (phaseIndex !== -1) {\n\t      newstx.scopesets.phase = this.scopesets.phase.set(phase, phaseScopeset.remove(phaseIndex));\n\t    } else if (allIndex !== -1) {\n\t      newstx.scopesets.all = allScopeset.remove(allIndex);\n\t    }\n\t    return new Syntax(token, newstx);\n\t  }\n\n\t  match(type, value) {\n\t    if (!Types[type]) {\n\t      throw new Error(type + ' is an invalid type');\n\t    }\n\t    return Types[type].match(this.token) && (value == null || (value instanceof RegExp ? value.test(this.val()) : this.val() == value));\n\t  }\n\n\t  isIdentifier(value) {\n\t    return this.match('identifier', value);\n\t  }\n\n\t  isAssign(value) {\n\t    return this.match('assign', value);\n\t  }\n\n\t  isBooleanLiteral(value) {\n\t    return this.match('boolean', value);\n\t  }\n\n\t  isKeyword(value) {\n\t    return this.match('keyword', value);\n\t  }\n\n\t  isNullLiteral(value) {\n\t    return this.match('null', value);\n\t  }\n\n\t  isNumericLiteral(value) {\n\t    return this.match('number', value);\n\t  }\n\n\t  isPunctuator(value) {\n\t    return this.match('punctuator', value);\n\t  }\n\n\t  isStringLiteral(value) {\n\t    return this.match('string', value);\n\t  }\n\n\t  isRegularExpression(value) {\n\t    return this.match('regularExpression', value);\n\t  }\n\n\t  isTemplate(value) {\n\t    return this.match('template', value);\n\t  }\n\n\t  isDelimiter(value) {\n\t    return this.match('delimiter', value);\n\t  }\n\n\t  isParens(value) {\n\t    return this.match('parens', value);\n\t  }\n\n\t  isBraces(value) {\n\t    return this.match('braces', value);\n\t  }\n\n\t  isBrackets(value) {\n\t    return this.match('brackets', value);\n\t  }\n\n\t  isSyntaxTemplate(value) {\n\t    return this.match('syntaxTemplate', value);\n\t  }\n\n\t  isEOF(value) {\n\t    return this.match('eof', value);\n\t  }\n\n\t  toString() {\n\t    if (this.match('delimiter')) {\n\t      return this.token.map(s => s.toString()).join(' ');\n\t    }\n\t    if (this.match('string')) {\n\t      return `'${ this.token.str }'`;\n\t    }\n\t    if (this.match('template')) {\n\t      return this.val();\n\t    }\n\t    return this.token.value;\n\t  }\n\t}\n\texports.default = Syntax;\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zeW50YXguanMiXSwibmFtZXMiOlsiXyIsIlQiLCJnZXRGaXJzdFNsaWNlIiwic3R4IiwiaXNEZWxpbWl0ZXIiLCJ0b2tlbiIsInNsaWNlIiwiZ2V0Iiwic2l6ZURlY2VuZGluZyIsImEiLCJiIiwic2NvcGVzIiwic2l6ZSIsIlR5cGVzIiwibnVsbCIsIm1hdGNoIiwiZGVsaW1pdGVyIiwidHlwZSIsIk5VTEwiLCJjcmVhdGUiLCJ2YWx1ZSIsIlN5bnRheCIsInR5cGVDb2RlIiwiS2V5d29yZCIsIm51bWJlciIsImtsYXNzIiwiTnVtZXJpY0xpdGVyYWwiLCJOVU1CRVIiLCJzdHJpbmciLCJTdHJpbmdMaXRlcmFsIiwiU1RSSU5HIiwic3RyIiwicHVuY3R1YXRvciIsIlB1bmN0dWF0b3IiLCJuYW1lIiwia2V5d29yZCIsImlkZW50aWZpZXIiLCJJZGVudCIsIklERU5USUZJRVIiLCJJZGVudGlmaWVyIiwicmVndWxhckV4cHJlc3Npb24iLCJSZWd1bGFyRXhwcmVzc2lvbiIsIlJFR0VYUCIsIlJlZ0V4cCIsImJyYWNlcyIsIkxCUkFDRSIsImlubmVyIiwibGVmdCIsIlJhd1N5bnRheCIsInJpZ2h0IiwiUkJSQUNFIiwiUmF3RGVsaW1pdGVyIiwia2luZCIsIm9mIiwiY29uY2F0IiwicHVzaCIsImJyYWNrZXRzIiwiTEJSQUNLIiwiUkJSQUNLIiwicGFyZW5zIiwiTFBBUkVOIiwiUlBBUkVOIiwiYXNzaWduIiwiYm9vbGVhbiIsIlRSVUUiLCJGQUxTRSIsInRlbXBsYXRlIiwiVEVNUExBVEUiLCJpc0xpc3QiLCJzeW50YXhUZW1wbGF0ZSIsInZhbCIsImVvZiIsIkVPUyIsIkFMTF9QSEFTRVMiLCJjb25zdHJ1Y3RvciIsIm9sZHN0eCIsImJpbmRpbmdzIiwic2NvcGVzZXRzIiwiYWxsIiwicGhhc2UiLCJPYmplY3QiLCJmcmVlemUiLCJmcm9tIiwiRXJyb3IiLCJuZXdzdHgiLCJzIiwiZnJvbU51bGwiLCJmcm9tTnVtYmVyIiwiZnJvbVN0cmluZyIsImZyb21QdW5jdHVhdG9yIiwiZnJvbUtleXdvcmQiLCJmcm9tSWRlbnRpZmllciIsImZyb21SZWd1bGFyRXhwcmVzc2lvbiIsInJlc29sdmUiLCJhbGxTY29wZXMiLCJzdHhTY29wZXMiLCJoYXMiLCJzY29wZSIsImxhc3QiLCJzY29wZXNldEJpbmRpbmdMaXN0IiwiYmlnZ2VzdEJpbmRpbmdQYWlyIiwiZmlsdGVyIiwiaXNTdWJzZXQiLCJzb3J0IiwiZGVidWdCYXNlIiwibWFwIiwidG9TdHJpbmciLCJqb2luIiwiZGVidWdBbWJpZ291c1Njb3Blc2V0cyIsImJpbmRpbmdTdHIiLCJiaW5kaW5nIiwiaXNKdXN0IiwiYWxpYXMiLCJnZXRPckVsc2UiLCJpdGVtcyIsImVsIiwidGV4dCIsImxpbmVOdW1iZXIiLCJzdGFydExvY2F0aW9uIiwibGluZSIsInNldExpbmVOdW1iZXIiLCJuZXdUb2siLCJrZXkiLCJrZXlzIiwiYWRkU2NvcGUiLCJvcHRpb25zIiwiZmxpcCIsIm1lcmdlIiwiaXQiLCJvbGRTY29wZXNldCIsIm5ld1Njb3Blc2V0IiwiaW5kZXgiLCJpbmRleE9mIiwicmVtb3ZlIiwic2V0IiwicmVtb3ZlU2NvcGUiLCJwaGFzZVNjb3Blc2V0IiwiYWxsU2NvcGVzZXQiLCJwaGFzZUluZGV4IiwiYWxsSW5kZXgiLCJ0ZXN0IiwiaXNJZGVudGlmaWVyIiwiaXNBc3NpZ24iLCJpc0Jvb2xlYW5MaXRlcmFsIiwiaXNLZXl3b3JkIiwiaXNOdWxsTGl0ZXJhbCIsImlzTnVtZXJpY0xpdGVyYWwiLCJpc1B1bmN0dWF0b3IiLCJpc1N0cmluZ0xpdGVyYWwiLCJpc1JlZ3VsYXJFeHByZXNzaW9uIiwiaXNUZW1wbGF0ZSIsImlzUGFyZW5zIiwiaXNCcmFjZXMiLCJpc0JyYWNrZXRzIiwiaXNTeW50YXhUZW1wbGF0ZSIsImlzRU9GIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFDQTs7QUFDQTs7SUFBWUEsQzs7QUFDWjs7SUFBWUMsQzs7QUFFWjs7Ozs7O0FBMEJB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LEVBQTZCO0FBQzNCLFdBQU8sS0FBS0wsS0FBTCxDQUFXLGdCQUFYLEVBQTZCSyxLQUE3QixDQUFQO0FBQ0Q7O0FBRUR1SSxRQUFNdkksS0FBTixFQUFrQjtBQUNoQixXQUFPLEtBQUtMLEtBQUwsQ0FBVyxLQUFYLEVBQWtCSyxLQUFsQixDQUFQO0FBQ0Q7O0FBRURzRixhQUFXO0FBQ1QsUUFBSSxLQUFLM0YsS0FBTCxDQUFXLFdBQVgsQ0FBSixFQUE2QjtBQUMzQixhQUFPLEtBQUtWLEtBQUwsQ0FBV29HLEdBQVgsQ0FBZXBCLEtBQUtBLEVBQUVxQixRQUFGLEVBQXBCLEVBQWtDQyxJQUFsQyxDQUF1QyxHQUF2QyxDQUFQO0FBQ0Q7QUFDRCxRQUFJLEtBQUs1RixLQUFMLENBQVcsUUFBWCxDQUFKLEVBQTBCO0FBQ3hCLGFBQVEsS0FBRyxLQUFLVixLQUFMLENBQVcwQixHQUFJLElBQTFCO0FBQ0Q7QUFDRCxRQUFJLEtBQUtoQixLQUFMLENBQVcsVUFBWCxDQUFKLEVBQTRCO0FBQzFCLGFBQU8sS0FBS3VELEdBQUwsRUFBUDtBQUNEO0FBQ0QsV0FBTyxLQUFLakUsS0FBTCxDQUFXZSxLQUFsQjtBQUNEO0FBbll5QjtrQkFBUEMsTSIsImZpbGUiOiJzeW50YXguanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAZmxvd1xuaW1wb3J0IHsgTGlzdCwgTWFwIH0gZnJvbSAnaW1tdXRhYmxlJztcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJy4vZXJyb3JzJztcbmltcG9ydCBCaW5kaW5nTWFwIGZyb20gJy4vYmluZGluZy1tYXAnO1xuaW1wb3J0IHsgTWF5YmUgfSBmcm9tICdyYW1kYS1mYW50YXN5JztcbmltcG9ydCAqIGFzIF8gZnJvbSAncmFtZGEnO1xuaW1wb3J0ICogYXMgVCBmcm9tICdzd2VldC1zcGVjJztcblxuaW1wb3J0IHsgVG9rZW5UeXBlLCBUb2tlbkNsYXNzLCBUeXBlQ29kZXMgfSBmcm9tICcuL3Rva2Vucyc7XG5cbnR5cGUgVG9rZW4gPSB7XG4gIHR5cGU6IGFueSxcbiAgdmFsdWU6IGFueSxcbiAgc2xpY2U6IGFueSxcbn07XG5cbnR5cGUgVG9rZW5UYWcgPVxuICB8ICdudWxsJ1xuICB8ICdudW1iZXInXG4gIHwgJ3N0cmluZydcbiAgfCAncHVuY3R1YXRvcidcbiAgfCAna2V5d29yZCdcbiAgfCAnaWRlbnRpZmllcidcbiAgfCAncmVndWxhckV4cHJlc3Npb24nXG4gIHwgJ2Jvb2xlYW4nXG4gIHwgJ2JyYWNlcydcbiAgfCAncGFyZW5zJ1xuICB8ICdkZWxpbWl0ZXInXG4gIHwgJ2VvZidcbiAgfCAndGVtcGxhdGUnXG4gIHwgJ2Fzc2lnbidcbiAgfCAnc3ludGF4VGVtcGxhdGUnXG4gIHwgJ2JyYWNrZXRzJztcblxuZnVuY3Rpb24gZ2V0Rmlyc3RTbGljZShzdHg6ID9TeW50YXgpIHtcbiAgaWYgKCFzdHggfHwgdHlwZW9mIHN0eC5pc0RlbGltaXRlciAhPT0gJ2Z1bmN0aW9uJykgcmV0dXJuIG51bGw7IC8vIFRPRE86IHNob3VsZCBub3QgaGF2ZSB0byBkbyB0aGlzXG4gIGlmICghc3R4LmlzRGVsaW1pdGVyKCkpIHtcbiAgICByZXR1cm4gc3R4LnRva2VuLnNsaWNlO1xuICB9XG4gIHJldHVybiBzdHgudG9rZW4uZ2V0KDApLnRva2VuLnNsaWNlO1xufVxuXG5mdW5jdGlvbiBzaXplRGVjZW5kaW5nKGEsIGIpIHtcbiAgaWYgKGEuc2NvcGVzLnNpemUgPiBiLnNjb3Blcy5zaXplKSB7XG4gICAgcmV0dXJuIC0xO1xuICB9IGVsc2UgaWYgKGIuc2NvcGVzLnNpemUgPiBhLnNjb3Blcy5zaXplKSB7XG4gICAgcmV0dXJuIDE7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cbn1cblxudHlwZSBUeXBlc0hlbHBlciA9IHtcbiAgW2tleTogVG9rZW5UYWddOiB7XG4gICAgbWF0Y2godG9rZW46IGFueSk6IGJvb2xlYW4sXG4gICAgY3JlYXRlPzogKHZhbHVlOiBhbnksIHN0eDogP1N5bnRheCkgPT4gU3ludGF4LFxuICB9LFxufTtcblxuZXhwb3J0IGxldCBUeXBlczogVHlwZXNIZWxwZXIgPSB7XG4gIG51bGw6IHtcbiAgICBtYXRjaDogdG9rZW4gPT5cbiAgICAgICFUeXBlcy5kZWxpbWl0ZXIubWF0Y2godG9rZW4pICYmIHRva2VuLnR5cGUgPT09IFRva2VuVHlwZS5OVUxMLFxuICAgIGNyZWF0ZTogKHZhbHVlLCBzdHgpID0+XG4gICAgICBuZXcgU3ludGF4KFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogVG9rZW5UeXBlLk5VTEwsXG4gICAgICAgICAgdmFsdWU6IG51bGwsXG4gICAgICAgICAgdHlwZUNvZGU6IFR5cGVDb2Rlcy5LZXl3b3JkLFxuICAgICAgICB9LFxuICAgICAgICBzdHgsXG4gICAgICApLFxuICB9LFxuICBudW1iZXI6IHtcbiAgICBtYXRjaDogdG9rZW4gPT5cbiAgICAgICFUeXBlcy5kZWxpbWl0ZXIubWF0Y2godG9rZW4pICYmXG4gICAgICB0b2tlbi50eXBlLmtsYXNzID09PSBUb2tlbkNsYXNzLk51bWVyaWNMaXRlcmFsLFxuICAgIGNyZWF0ZTogKHZhbHVlLCBzdHgpID0+XG4gICAgICBuZXcgU3ludGF4KFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogVG9rZW5UeXBlLk5VTUJFUixcbiAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICB0eXBlQ29kZTogVHlwZUNvZGVzLk51bWVyaWNMaXRlcmFsLFxuICAgICAgICB9LFxuICAgICAgICBzdHgsXG4gICAgICApLFxuICB9LFxuICBzdHJpbmc6IHtcbiAgICBtYXRjaDogdG9rZW4gPT5cbiAgICAgICFUeXBlcy5kZWxpbWl0ZXIubWF0Y2godG9rZW4pICYmXG4gICAgICB0b2tlbi50eXBlLmtsYXNzID09PSBUb2tlbkNsYXNzLlN0cmluZ0xpdGVyYWwsXG4gICAgY3JlYXRlOiAodmFsdWUsIHN0eCkgPT5cbiAgICAgIG5ldyBTeW50YXgoXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiBUb2tlblR5cGUuU1RSSU5HLFxuICAgICAgICAgIHN0cjogdmFsdWUsXG4gICAgICAgICAgdHlwZUNvZGU6IFR5cGVDb2Rlcy5TdHJpbmdMaXRlcmFsLFxuICAgICAgICB9LFxuICAgICAgICBzdHgsXG4gICAgICApLFxuICB9LFxuICBwdW5jdHVhdG9yOiB7XG4gICAgbWF0Y2g6IHRva2VuID0+XG4gICAgICAhVHlwZXMuZGVsaW1pdGVyLm1hdGNoKHRva2VuKSAmJlxuICAgICAgdG9rZW4udHlwZS5rbGFzcyA9PT0gVG9rZW5DbGFzcy5QdW5jdHVhdG9yLFxuICAgIGNyZWF0ZTogKHZhbHVlLCBzdHgpID0+XG4gICAgICBuZXcgU3ludGF4KFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZToge1xuICAgICAgICAgICAga2xhc3M6IFRva2VuQ2xhc3MuUHVuY3R1YXRvcixcbiAgICAgICAgICAgIG5hbWU6IHZhbHVlLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdHlwZUNvZGU6IFR5cGVDb2Rlcy5QdW5jdHVhdG9yLFxuICAgICAgICAgIHZhbHVlLFxuICAgICAgICB9LFxuICAgICAgICBzdHgsXG4gICAgICApLFxuICB9LFxuICBrZXl3b3JkOiB7XG4gICAgbWF0Y2g6IHRva2VuID0+XG4gICAgICAhVHlwZXMuZGVsaW1pdGVyLm1hdGNoKHRva2VuKSAmJiB0b2tlbi50eXBlLmtsYXNzID09PSBUb2tlbkNsYXNzLktleXdvcmQsXG4gICAgY3JlYXRlOiAodmFsdWUsIHN0eCkgPT5cbiAgICAgIG5ldyBTeW50YXgoXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiB7XG4gICAgICAgICAgICBrbGFzczogVG9rZW5DbGFzcy5LZXl3b3JkLFxuICAgICAgICAgICAgbmFtZTogdmFsdWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0eXBlQ29kZTogVHlwZUNvZGVzLktleXdvcmQsXG4gICAgICAgICAgdmFsdWUsXG4gICAgICAgIH0sXG4gICAgICAgIHN0eCxcbiAgICAgICksXG4gIH0sXG4gIGlkZW50aWZpZXI6IHtcbiAgICBtYXRjaDogdG9rZW4gPT5cbiAgICAgICFUeXBlcy5kZWxpbWl0ZXIubWF0Y2godG9rZW4pICYmIHRva2VuLnR5cGUua2xhc3MgPT09IFRva2VuQ2xhc3MuSWRlbnQsXG4gICAgY3JlYXRlOiAodmFsdWUsIHN0eCkgPT5cbiAgICAgIG5ldyBTeW50YXgoXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiBUb2tlblR5cGUuSURFTlRJRklFUixcbiAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICB0eXBlQ29kZTogVHlwZUNvZGVzLklkZW50aWZpZXIsXG4gICAgICAgIH0sXG4gICAgICAgIHN0eCxcbiAgICAgICksXG4gIH0sXG4gIHJlZ3VsYXJFeHByZXNzaW9uOiB7XG4gICAgbWF0Y2g6IHRva2VuID0+XG4gICAgICAhVHlwZXMuZGVsaW1pdGVyLm1hdGNoKHRva2VuKSAmJlxuICAgICAgdG9rZW4udHlwZS5rbGFzcyA9PT0gVG9rZW5DbGFzcy5SZWd1bGFyRXhwcmVzc2lvbixcbiAgICBjcmVhdGU6ICh2YWx1ZSwgc3R4KSA9PlxuICAgICAgbmV3IFN5bnRheChcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6IFRva2VuVHlwZS5SRUdFWFAsXG4gICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgdHlwZUNvZGU6IFR5cGVDb2Rlcy5SZWdFeHAsXG4gICAgICAgIH0sXG4gICAgICAgIHN0eCxcbiAgICAgICksXG4gIH0sXG4gIGJyYWNlczoge1xuICAgIG1hdGNoOiB0b2tlbiA9PlxuICAgICAgVHlwZXMuZGVsaW1pdGVyLm1hdGNoKHRva2VuKSAmJlxuICAgICAgdG9rZW4uZ2V0KDApLnRva2VuLnR5cGUgPT09IFRva2VuVHlwZS5MQlJBQ0UsXG4gICAgY3JlYXRlOiAoaW5uZXIsIHN0eCkgPT4ge1xuICAgICAgbGV0IGxlZnQgPSBuZXcgVC5SYXdTeW50YXgoe1xuICAgICAgICB2YWx1ZTogbmV3IFN5bnRheCh7XG4gICAgICAgICAgdHlwZTogVG9rZW5UeXBlLkxCUkFDRSxcbiAgICAgICAgICB0eXBlQ29kZTogVHlwZUNvZGVzLlB1bmN0dWF0b3IsXG4gICAgICAgICAgdmFsdWU6ICd7JyxcbiAgICAgICAgICBzbGljZTogZ2V0Rmlyc3RTbGljZShzdHgpLFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuICAgICAgbGV0IHJpZ2h0ID0gbmV3IFQuUmF3U3ludGF4KHtcbiAgICAgICAgdmFsdWU6IG5ldyBTeW50YXgoe1xuICAgICAgICAgIHR5cGU6IFRva2VuVHlwZS5SQlJBQ0UsXG4gICAgICAgICAgdHlwZUNvZGU6IFR5cGVDb2Rlcy5QdW5jdHVhdG9yLFxuICAgICAgICAgIHZhbHVlOiAnfScsXG4gICAgICAgICAgc2xpY2U6IGdldEZpcnN0U2xpY2Uoc3R4KSxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBuZXcgVC5SYXdEZWxpbWl0ZXIoe1xuICAgICAgICBraW5kOiAnYnJhY2VzJyxcbiAgICAgICAgaW5uZXI6IExpc3Qub2YobGVmdCkuY29uY2F0KGlubmVyKS5wdXNoKHJpZ2h0KSxcbiAgICAgIH0pO1xuICAgIH0sXG4gIH0sXG4gIGJyYWNrZXRzOiB7XG4gICAgbWF0Y2g6IHRva2VuID0+XG4gICAgICBUeXBlcy5kZWxpbWl0ZXIubWF0Y2godG9rZW4pICYmXG4gICAgICB0b2tlbi5nZXQoMCkudG9rZW4udHlwZSA9PT0gVG9rZW5UeXBlLkxCUkFDSyxcbiAgICBjcmVhdGU6IChpbm5lciwgc3R4KSA9PiB7XG4gICAgICBsZXQgbGVmdCA9IG5ldyBULlJhd1N5bnRheCh7XG4gICAgICAgIHZhbHVlOiBuZXcgU3ludGF4KHtcbiAgICAgICAgICB0eXBlOiBUb2tlblR5cGUuTEJSQUNLLFxuICAgICAgICAgIHR5cGVDb2RlOiBUeXBlQ29kZXMuUHVuY3R1YXRvcixcbiAgICAgICAgICB2YWx1ZTogJ1snLFxuICAgICAgICAgIHNsaWNlOiBnZXRGaXJzdFNsaWNlKHN0eCksXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgICBsZXQgcmlnaHQgPSBuZXcgVC5SYXdTeW50YXgoe1xuICAgICAgICB2YWx1ZTogbmV3IFN5bnRheCh7XG4gICAgICAgICAgdHlwZTogVG9rZW5UeXBlLlJCUkFDSyxcbiAgICAgICAgICB0eXBlQ29kZTogVHlwZUNvZGVzLlB1bmN0dWF0b3IsXG4gICAgICAgICAgdmFsdWU6ICddJyxcbiAgICAgICAgICBzbGljZTogZ2V0Rmlyc3RTbGljZShzdHgpLFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIG5ldyBULlJhd0RlbGltaXRlcih7XG4gICAgICAgIGtpbmQ6ICdicmFja2V0cycsXG4gICAgICAgIGlubmVyOiBMaXN0Lm9mKGxlZnQpLmNvbmNhdChpbm5lcikucHVzaChyaWdodCksXG4gICAgICB9KTtcbiAgICB9LFxuICB9LFxuICBwYXJlbnM6IHtcbiAgICBtYXRjaDogdG9rZW4gPT5cbiAgICAgIFR5cGVzLmRlbGltaXRlci5tYXRjaCh0b2tlbikgJiZcbiAgICAgIHRva2VuLmdldCgwKS50b2tlbi50eXBlID09PSBUb2tlblR5cGUuTFBBUkVOLFxuICAgIGNyZWF0ZTogKGlubmVyLCBzdHgpID0+IHtcbiAgICAgIGxldCBsZWZ0ID0gbmV3IFQuUmF3U3ludGF4KHtcbiAgICAgICAgdmFsdWU6IG5ldyBTeW50YXgoe1xuICAgICAgICAgIHR5cGU6IFRva2VuVHlwZS5MUEFSRU4sXG4gICAgICAgICAgdHlwZUNvZGU6IFR5cGVDb2Rlcy5QdW5jdHVhdG9yLFxuICAgICAgICAgIHZhbHVlOiAnKCcsXG4gICAgICAgICAgc2xpY2U6IGdldEZpcnN0U2xpY2Uoc3R4KSxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICAgIGxldCByaWdodCA9IG5ldyBULlJhd1N5bnRheCh7XG4gICAgICAgIHZhbHVlOiBuZXcgU3ludGF4KHtcbiAgICAgICAgICB0eXBlOiBUb2tlblR5cGUuUlBBUkVOLFxuICAgICAgICAgIHR5cGVDb2RlOiBUeXBlQ29kZXMuUHVuY3R1YXRvcixcbiAgICAgICAgICB2YWx1ZTogJyknLFxuICAgICAgICAgIHNsaWNlOiBnZXRGaXJzdFNsaWNlKHN0eCksXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gbmV3IFQuUmF3RGVsaW1pdGVyKHtcbiAgICAgICAga2luZDogJ3BhcmVucycsXG4gICAgICAgIGlubmVyOiBMaXN0Lm9mKGxlZnQpLmNvbmNhdChpbm5lcikucHVzaChyaWdodCksXG4gICAgICB9KTtcbiAgICB9LFxuICB9LFxuXG4gIGFzc2lnbjoge1xuICAgIG1hdGNoOiB0b2tlbiA9PiB7XG4gICAgICBpZiAoVHlwZXMucHVuY3R1YXRvci5tYXRjaCh0b2tlbikpIHtcbiAgICAgICAgc3dpdGNoICh0b2tlbi52YWx1ZSkge1xuICAgICAgICAgIGNhc2UgJz0nOlxuICAgICAgICAgIGNhc2UgJ3w9JzpcbiAgICAgICAgICBjYXNlICdePSc6XG4gICAgICAgICAgY2FzZSAnJj0nOlxuICAgICAgICAgIGNhc2UgJzw8PSc6XG4gICAgICAgICAgY2FzZSAnPj49JzpcbiAgICAgICAgICBjYXNlICc+Pj49JzpcbiAgICAgICAgICBjYXNlICcrPSc6XG4gICAgICAgICAgY2FzZSAnLT0nOlxuICAgICAgICAgIGNhc2UgJyo9JzpcbiAgICAgICAgICBjYXNlICcvPSc6XG4gICAgICAgICAgY2FzZSAnJT0nOlxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG4gIH0sXG5cbiAgYm9vbGVhbjoge1xuICAgIG1hdGNoOiB0b2tlbiA9PlxuICAgICAgKCFUeXBlcy5kZWxpbWl0ZXIubWF0Y2godG9rZW4pICYmIHRva2VuLnR5cGUgPT09IFRva2VuVHlwZS5UUlVFKSB8fFxuICAgICAgdG9rZW4udHlwZSA9PT0gVG9rZW5UeXBlLkZBTFNFLFxuICB9LFxuXG4gIHRlbXBsYXRlOiB7XG4gICAgbWF0Y2g6IHRva2VuID0+XG4gICAgICAhVHlwZXMuZGVsaW1pdGVyLm1hdGNoKHRva2VuKSAmJiB0b2tlbi50eXBlID09PSBUb2tlblR5cGUuVEVNUExBVEUsXG4gIH0sXG5cbiAgZGVsaW1pdGVyOiB7XG4gICAgbWF0Y2g6IHRva2VuID0+IExpc3QuaXNMaXN0KHRva2VuKSxcbiAgfSxcblxuICBzeW50YXhUZW1wbGF0ZToge1xuICAgIG1hdGNoOiB0b2tlbiA9PiBUeXBlcy5kZWxpbWl0ZXIubWF0Y2godG9rZW4pICYmIHRva2VuLmdldCgwKS52YWwoKSA9PT0gJyNgJyxcbiAgfSxcblxuICBlb2Y6IHtcbiAgICBtYXRjaDogdG9rZW4gPT5cbiAgICAgICFUeXBlcy5kZWxpbWl0ZXIubWF0Y2godG9rZW4pICYmIHRva2VuLnR5cGUgPT09IFRva2VuVHlwZS5FT1MsXG4gIH0sXG59O1xuZXhwb3J0IGNvbnN0IEFMTF9QSEFTRVMgPSB7fTtcblxudHlwZSBTY29wZXNldCA9IHtcbiAgYWxsOiBMaXN0PGFueT4sXG4gIHBoYXNlOiBNYXA8bnVtYmVyIHwge30sIGFueT4sXG59O1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTeW50YXgge1xuICAvLyB0b2tlbjogVG9rZW4gfCBMaXN0PFRva2VuPjtcbiAgdG9rZW46IGFueTtcbiAgYmluZGluZ3M6IEJpbmRpbmdNYXA7XG4gIHNjb3Blc2V0czogU2NvcGVzZXQ7XG5cbiAgY29uc3RydWN0b3IodG9rZW46IGFueSwgb2xkc3R4OiA/eyBiaW5kaW5nczogYW55LCBzY29wZXNldHM6IGFueSB9KSB7XG4gICAgdGhpcy50b2tlbiA9IHRva2VuO1xuICAgIHRoaXMuYmluZGluZ3MgPSBvbGRzdHggJiYgb2xkc3R4LmJpbmRpbmdzICE9IG51bGxcbiAgICAgID8gb2xkc3R4LmJpbmRpbmdzXG4gICAgICA6IG5ldyBCaW5kaW5nTWFwKCk7XG4gICAgdGhpcy5zY29wZXNldHMgPSBvbGRzdHggJiYgb2xkc3R4LnNjb3Blc2V0cyAhPSBudWxsXG4gICAgICA/IG9sZHN0eC5zY29wZXNldHNcbiAgICAgIDoge1xuICAgICAgICAgIGFsbDogTGlzdCgpLFxuICAgICAgICAgIHBoYXNlOiBNYXAoKSxcbiAgICAgICAgfTtcbiAgICBPYmplY3QuZnJlZXplKHRoaXMpO1xuICB9XG5cbiAgc3RhdGljIG9mKHRva2VuOiBUb2tlbiwgc3R4OiA/U3ludGF4KSB7XG4gICAgcmV0dXJuIG5ldyBTeW50YXgodG9rZW4sIHN0eCk7XG4gIH1cblxuICBzdGF0aWMgZnJvbSh0eXBlLCB2YWx1ZSwgc3R4OiA/U3ludGF4KSB7XG4gICAgaWYgKCFUeXBlc1t0eXBlXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHR5cGUgKyAnIGlzIG5vdCBhIHZhbGlkIHR5cGUnKTtcbiAgICB9IGVsc2UgaWYgKCFUeXBlc1t0eXBlXS5jcmVhdGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGNyZWF0ZSBhIHN5bnRheCBmcm9tIHR5cGUgJyArIHR5cGUpO1xuICAgIH1cbiAgICBsZXQgbmV3c3R4ID0gVHlwZXNbdHlwZV0uY3JlYXRlKHZhbHVlLCBzdHgpO1xuICAgIGxldCBzbGljZSA9IGdldEZpcnN0U2xpY2Uoc3R4KTtcbiAgICBpZiAoc2xpY2UgIT0gbnVsbCAmJiBuZXdzdHgudG9rZW4gIT0gbnVsbCkge1xuICAgICAgbmV3c3R4LnRva2VuLnNsaWNlID0gc2xpY2U7XG4gICAgfVxuICAgIHJldHVybiBuZXdzdHg7XG4gIH1cblxuICBmcm9tKHR5cGU6IFRva2VuVGFnLCB2YWx1ZTogYW55KSB7XG4gICAgLy8gVE9ETzogdGhpcyBpcyBncm9zcywgZml4XG4gICAgbGV0IHMgPSBTeW50YXguZnJvbSh0eXBlLCB2YWx1ZSwgdGhpcyk7XG4gICAgaWYgKHMgaW5zdGFuY2VvZiBTeW50YXgpIHtcbiAgICAgIHJldHVybiBuZXcgVC5SYXdTeW50YXgoeyB2YWx1ZTogcyB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHM7XG4gIH1cblxuICBmcm9tTnVsbCgpIHtcbiAgICByZXR1cm4gdGhpcy5mcm9tKCdudWxsJywgbnVsbCk7XG4gIH1cblxuICBmcm9tTnVtYmVyKHZhbHVlOiBudW1iZXIpIHtcbiAgICByZXR1cm4gdGhpcy5mcm9tKCdudW1iZXInLCB2YWx1ZSk7XG4gIH1cblxuICBmcm9tU3RyaW5nKHZhbHVlOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5mcm9tKCdzdHJpbmcnLCB2YWx1ZSk7XG4gIH1cblxuICBmcm9tUHVuY3R1YXRvcih2YWx1ZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuZnJvbSgncHVuY3R1YXRvcicsIHZhbHVlKTtcbiAgfVxuXG4gIGZyb21LZXl3b3JkKHZhbHVlOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5mcm9tKCdrZXl3b3JkJywgdmFsdWUpO1xuICB9XG5cbiAgZnJvbUlkZW50aWZpZXIodmFsdWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmZyb20oJ2lkZW50aWZpZXInLCB2YWx1ZSk7XG4gIH1cblxuICBmcm9tUmVndWxhckV4cHJlc3Npb24odmFsdWU6IGFueSkge1xuICAgIHJldHVybiB0aGlzLmZyb20oJ3JlZ3VsYXJFeHByZXNzaW9uJywgdmFsdWUpO1xuICB9XG5cbiAgc3RhdGljIGZyb21OdWxsKHN0eDogU3ludGF4KSB7XG4gICAgcmV0dXJuIFN5bnRheC5mcm9tKCdudWxsJywgbnVsbCwgc3R4KTtcbiAgfVxuXG4gIHN0YXRpYyBmcm9tTnVtYmVyKHZhbHVlLCBzdHgpIHtcbiAgICByZXR1cm4gU3ludGF4LmZyb20oJ251bWJlcicsIHZhbHVlLCBzdHgpO1xuICB9XG5cbiAgc3RhdGljIGZyb21TdHJpbmcodmFsdWUsIHN0eCkge1xuICAgIHJldHVybiBTeW50YXguZnJvbSgnc3RyaW5nJywgdmFsdWUsIHN0eCk7XG4gIH1cblxuICBzdGF0aWMgZnJvbVB1bmN0dWF0b3IodmFsdWUsIHN0eCkge1xuICAgIHJldHVybiBTeW50YXguZnJvbSgncHVuY3R1YXRvcicsIHZhbHVlLCBzdHgpO1xuICB9XG5cbiAgc3RhdGljIGZyb21LZXl3b3JkKHZhbHVlLCBzdHgpIHtcbiAgICByZXR1cm4gU3ludGF4LmZyb20oJ2tleXdvcmQnLCB2YWx1ZSwgc3R4KTtcbiAgfVxuXG4gIHN0YXRpYyBmcm9tSWRlbnRpZmllcih2YWx1ZSwgc3R4KSB7XG4gICAgcmV0dXJuIFN5bnRheC5mcm9tKCdpZGVudGlmaWVyJywgdmFsdWUsIHN0eCk7XG4gIH1cblxuICBzdGF0aWMgZnJvbVJlZ3VsYXJFeHByZXNzaW9uKHZhbHVlLCBzdHgpIHtcbiAgICByZXR1cm4gU3ludGF4LmZyb20oJ3JlZ3VsYXJFeHByZXNzaW9uJywgdmFsdWUsIHN0eCk7XG4gIH1cblxuICAvLyAoKSAtPiBzdHJpbmdcbiAgcmVzb2x2ZShwaGFzZTogYW55KSB7XG4gICAgYXNzZXJ0KHBoYXNlICE9IG51bGwsICdtdXN0IHByb3ZpZGUgYSBwaGFzZSB0byByZXNvbHZlJyk7XG4gICAgbGV0IGFsbFNjb3BlcyA9IHRoaXMuc2NvcGVzZXRzLmFsbDtcbiAgICBsZXQgc3R4U2NvcGVzID0gdGhpcy5zY29wZXNldHMucGhhc2UuaGFzKHBoYXNlKVxuICAgICAgPyB0aGlzLnNjb3Blc2V0cy5waGFzZS5nZXQocGhhc2UpXG4gICAgICA6IExpc3QoKTtcbiAgICBzdHhTY29wZXMgPSBhbGxTY29wZXMuY29uY2F0KHN0eFNjb3Blcyk7XG4gICAgaWYgKFxuICAgICAgc3R4U2NvcGVzLnNpemUgPT09IDAgfHxcbiAgICAgICEodGhpcy5tYXRjaCgnaWRlbnRpZmllcicpIHx8XG4gICAgICAgIHRoaXMubWF0Y2goJ2tleXdvcmQnKSB8fFxuICAgICAgICB0aGlzLm1hdGNoKCdwdW5jdHVhdG9yJykpXG4gICAgKSB7XG4gICAgICByZXR1cm4gdGhpcy50b2tlbi52YWx1ZTtcbiAgICB9XG4gICAgbGV0IHNjb3BlID0gc3R4U2NvcGVzLmxhc3QoKTtcbiAgICBsZXQgYmluZGluZ3MgPSB0aGlzLmJpbmRpbmdzO1xuICAgIGlmIChzY29wZSkge1xuICAgICAgLy8gTGlzdDx7IHNjb3BlczogTGlzdDxTY29wZT4sIGJpbmRpbmc6IFN5bWJvbCB9PlxuICAgICAgbGV0IHNjb3Blc2V0QmluZGluZ0xpc3QgPSBiaW5kaW5ncy5nZXQodGhpcyk7XG5cbiAgICAgIGlmIChzY29wZXNldEJpbmRpbmdMaXN0KSB7XG4gICAgICAgIC8vIHsgc2NvcGVzOiBMaXN0PFNjb3BlPiwgYmluZGluZzogU3ltYm9sIH1cbiAgICAgICAgbGV0IGJpZ2dlc3RCaW5kaW5nUGFpciA9IHNjb3Blc2V0QmluZGluZ0xpc3RcbiAgICAgICAgICAuZmlsdGVyKCh7IHNjb3BlcyB9KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gc2NvcGVzLmlzU3Vic2V0KHN0eFNjb3Blcyk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc29ydChzaXplRGVjZW5kaW5nKTtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgYmlnZ2VzdEJpbmRpbmdQYWlyLnNpemUgPj0gMiAmJlxuICAgICAgICAgIGJpZ2dlc3RCaW5kaW5nUGFpci5nZXQoMCkuc2NvcGVzLnNpemUgPT09XG4gICAgICAgICAgICBiaWdnZXN0QmluZGluZ1BhaXIuZ2V0KDEpLnNjb3Blcy5zaXplXG4gICAgICAgICkge1xuICAgICAgICAgIGxldCBkZWJ1Z0Jhc2UgPSAneycgK1xuICAgICAgICAgICAgc3R4U2NvcGVzLm1hcChzID0+IHMudG9TdHJpbmcoKSkuam9pbignLCAnKSArXG4gICAgICAgICAgICAnfSc7XG4gICAgICAgICAgbGV0IGRlYnVnQW1iaWdvdXNTY29wZXNldHMgPSBiaWdnZXN0QmluZGluZ1BhaXJcbiAgICAgICAgICAgIC5tYXAoKHsgc2NvcGVzIH0pID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuICd7JyArIHNjb3Blcy5tYXAocyA9PiBzLnRvU3RyaW5nKCkpLmpvaW4oJywgJykgKyAnfSc7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmpvaW4oJywgJyk7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgJ1Njb3Blc2V0ICcgK1xuICAgICAgICAgICAgICBkZWJ1Z0Jhc2UgK1xuICAgICAgICAgICAgICAnIGhhcyBhbWJpZ3VvdXMgc3Vic2V0cyAnICtcbiAgICAgICAgICAgICAgZGVidWdBbWJpZ291c1Njb3Blc2V0cyxcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYgKGJpZ2dlc3RCaW5kaW5nUGFpci5zaXplICE9PSAwKSB7XG4gICAgICAgICAgbGV0IGJpbmRpbmdTdHIgPSBiaWdnZXN0QmluZGluZ1BhaXIuZ2V0KDApLmJpbmRpbmcudG9TdHJpbmcoKTtcbiAgICAgICAgICBpZiAoTWF5YmUuaXNKdXN0KGJpZ2dlc3RCaW5kaW5nUGFpci5nZXQoMCkuYWxpYXMpKSB7XG4gICAgICAgICAgICAvLyBudWxsIG5ldmVyIGhhcHBlbnMgYmVjYXVzZSB3ZSBqdXN0IGNoZWNrZWQgaWYgaXQgaXMgYSBKdXN0XG4gICAgICAgICAgICByZXR1cm4gYmlnZ2VzdEJpbmRpbmdQYWlyXG4gICAgICAgICAgICAgIC5nZXQoMClcbiAgICAgICAgICAgICAgLmFsaWFzLmdldE9yRWxzZShudWxsKVxuICAgICAgICAgICAgICAucmVzb2x2ZShwaGFzZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBiaW5kaW5nU3RyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnRva2VuLnZhbHVlO1xuICB9XG5cbiAgdmFsKCk6IGFueSB7XG4gICAgYXNzZXJ0KCF0aGlzLm1hdGNoKCdkZWxpbWl0ZXInKSwgJ2Nhbm5vdCBnZXQgdGhlIHZhbCBvZiBhIGRlbGltaXRlcicpO1xuICAgIGlmICh0aGlzLm1hdGNoKCdzdHJpbmcnKSkge1xuICAgICAgcmV0dXJuIHRoaXMudG9rZW4uc3RyO1xuICAgIH1cbiAgICBpZiAodGhpcy5tYXRjaCgndGVtcGxhdGUnKSkge1xuICAgICAgaWYgKCF0aGlzLnRva2VuLml0ZW1zKSByZXR1cm4gdGhpcy50b2tlbi52YWx1ZTtcbiAgICAgIHJldHVybiB0aGlzLnRva2VuLml0ZW1zXG4gICAgICAgIC5tYXAoZWwgPT4ge1xuICAgICAgICAgIGlmICh0eXBlb2YgZWwubWF0Y2ggPT09ICdmdW5jdGlvbicgJiYgZWwubWF0Y2goJ2RlbGltaXRlcicpKSB7XG4gICAgICAgICAgICByZXR1cm4gJyR7Li4ufSc7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBlbC5zbGljZS50ZXh0O1xuICAgICAgICB9KVxuICAgICAgICAuam9pbignJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnRva2VuLnZhbHVlO1xuICB9XG5cbiAgbGluZU51bWJlcigpIHtcbiAgICBpZiAoIXRoaXMubWF0Y2goJ2RlbGltaXRlcicpKSB7XG4gICAgICByZXR1cm4gdGhpcy50b2tlbi5zbGljZS5zdGFydExvY2F0aW9uLmxpbmU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLnRva2VuLmdldCgwKS5saW5lTnVtYmVyKCk7XG4gICAgfVxuICB9XG5cbiAgc2V0TGluZU51bWJlcihsaW5lOiBudW1iZXIpIHtcbiAgICBsZXQgbmV3VG9rID0ge307XG4gICAgaWYgKHRoaXMuaXNEZWxpbWl0ZXIoKSkge1xuICAgICAgbmV3VG9rID0gdGhpcy50b2tlbi5tYXAocyA9PiBzLnNldExpbmVOdW1iZXIobGluZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGxldCBrZXkgb2YgT2JqZWN0LmtleXModGhpcy50b2tlbikpIHtcbiAgICAgICAgbmV3VG9rW2tleV0gPSB0aGlzLnRva2VuW2tleV07XG4gICAgICB9XG4gICAgICBhc3NlcnQoXG4gICAgICAgIG5ld1Rvay5zbGljZSAmJiBuZXdUb2suc2xpY2Uuc3RhcnRMb2NhdGlvbixcbiAgICAgICAgJ2FsbCB0b2tlbnMgbXVzdCBoYXZlIGxpbmUgaW5mbycsXG4gICAgICApO1xuICAgICAgbmV3VG9rLnNsaWNlLnN0YXJ0TG9jYXRpb24ubGluZSA9IGxpbmU7XG4gICAgfVxuICAgIHJldHVybiBuZXcgU3ludGF4KG5ld1RvaywgdGhpcyk7XG4gIH1cblxuICAvLyAoKSAtPiBMaXN0PFN5bnRheD5cbiAgLy8gaW5uZXIoKSB7XG4gIC8vICAgYXNzZXJ0KHRoaXMubWF0Y2goXCJkZWxpbWl0ZXJcIiksIFwiY2FuIG9ubHkgZ2V0IHRoZSBpbm5lciBvZiBhIGRlbGltaXRlclwiKTtcbiAgLy8gICByZXR1cm4gdGhpcy50b2tlbi5zbGljZSgxLCB0aGlzLnRva2VuLnNpemUgLSAxKTtcbiAgLy8gfVxuXG4gIGFkZFNjb3BlKFxuICAgIHNjb3BlOiBhbnksXG4gICAgYmluZGluZ3M6IGFueSxcbiAgICBwaGFzZTogbnVtYmVyIHwge30sXG4gICAgb3B0aW9uczogYW55ID0geyBmbGlwOiBmYWxzZSB9LFxuICApIHtcbiAgICBsZXQgdG9rZW4gPSB0aGlzLm1hdGNoKCdkZWxpbWl0ZXInKVxuICAgICAgPyB0aGlzLnRva2VuLm1hcChzID0+IHMuYWRkU2NvcGUoc2NvcGUsIGJpbmRpbmdzLCBwaGFzZSwgb3B0aW9ucykpXG4gICAgICA6IHRoaXMudG9rZW47XG4gICAgaWYgKHRoaXMubWF0Y2goJ3RlbXBsYXRlJykpIHtcbiAgICAgIHRva2VuID0gXy5tZXJnZSh0b2tlbiwge1xuICAgICAgICBpdGVtczogdG9rZW4uaXRlbXMubWFwKGl0ID0+IHtcbiAgICAgICAgICBpZiAoaXQgaW5zdGFuY2VvZiBTeW50YXggJiYgaXQubWF0Y2goJ2RlbGltaXRlcicpKSB7XG4gICAgICAgICAgICByZXR1cm4gaXQuYWRkU2NvcGUoc2NvcGUsIGJpbmRpbmdzLCBwaGFzZSwgb3B0aW9ucyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBpdDtcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICB9XG4gICAgbGV0IG9sZFNjb3Blc2V0O1xuICAgIGlmIChwaGFzZSA9PT0gQUxMX1BIQVNFUykge1xuICAgICAgb2xkU2NvcGVzZXQgPSB0aGlzLnNjb3Blc2V0cy5hbGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9sZFNjb3Blc2V0ID0gdGhpcy5zY29wZXNldHMucGhhc2UuaGFzKHBoYXNlKVxuICAgICAgICA/IHRoaXMuc2NvcGVzZXRzLnBoYXNlLmdldChwaGFzZSlcbiAgICAgICAgOiBMaXN0KCk7XG4gICAgfVxuICAgIGxldCBuZXdTY29wZXNldDtcbiAgICBpZiAob3B0aW9ucy5mbGlwKSB7XG4gICAgICBsZXQgaW5kZXggPSBvbGRTY29wZXNldC5pbmRleE9mKHNjb3BlKTtcbiAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgbmV3U2NvcGVzZXQgPSBvbGRTY29wZXNldC5yZW1vdmUoaW5kZXgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV3U2NvcGVzZXQgPSBvbGRTY29wZXNldC5wdXNoKHNjb3BlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbmV3U2NvcGVzZXQgPSBvbGRTY29wZXNldC5wdXNoKHNjb3BlKTtcbiAgICB9XG4gICAgbGV0IG5ld3N0eCA9IHtcbiAgICAgIGJpbmRpbmdzLFxuICAgICAgc2NvcGVzZXRzOiB7XG4gICAgICAgIGFsbDogdGhpcy5zY29wZXNldHMuYWxsLFxuICAgICAgICBwaGFzZTogdGhpcy5zY29wZXNldHMucGhhc2UsXG4gICAgICB9LFxuICAgIH07XG5cbiAgICBpZiAocGhhc2UgPT09IEFMTF9QSEFTRVMpIHtcbiAgICAgIG5ld3N0eC5zY29wZXNldHMuYWxsID0gbmV3U2NvcGVzZXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5ld3N0eC5zY29wZXNldHMucGhhc2UgPSBuZXdzdHguc2NvcGVzZXRzLnBoYXNlLnNldChwaGFzZSwgbmV3U2NvcGVzZXQpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFN5bnRheCh0b2tlbiwgbmV3c3R4KTtcbiAgfVxuXG4gIHJlbW92ZVNjb3BlKHNjb3BlOiBhbnksIHBoYXNlOiBudW1iZXIpIHtcbiAgICBsZXQgdG9rZW4gPSB0aGlzLm1hdGNoKCdkZWxpbWl0ZXInKVxuICAgICAgPyB0aGlzLnRva2VuLm1hcChzID0+IHMucmVtb3ZlU2NvcGUoc2NvcGUsIHBoYXNlKSlcbiAgICAgIDogdGhpcy50b2tlbjtcbiAgICBsZXQgcGhhc2VTY29wZXNldCA9IHRoaXMuc2NvcGVzZXRzLnBoYXNlLmhhcyhwaGFzZSlcbiAgICAgID8gdGhpcy5zY29wZXNldHMucGhhc2UuZ2V0KHBoYXNlKVxuICAgICAgOiBMaXN0KCk7XG4gICAgbGV0IGFsbFNjb3Blc2V0ID0gdGhpcy5zY29wZXNldHMuYWxsO1xuICAgIGxldCBuZXdzdHggPSB7XG4gICAgICBiaW5kaW5nczogdGhpcy5iaW5kaW5ncyxcbiAgICAgIHNjb3Blc2V0czoge1xuICAgICAgICBhbGw6IHRoaXMuc2NvcGVzZXRzLmFsbCxcbiAgICAgICAgcGhhc2U6IHRoaXMuc2NvcGVzZXRzLnBoYXNlLFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgbGV0IHBoYXNlSW5kZXggPSBwaGFzZVNjb3Blc2V0LmluZGV4T2Yoc2NvcGUpO1xuICAgIGxldCBhbGxJbmRleCA9IGFsbFNjb3Blc2V0LmluZGV4T2Yoc2NvcGUpO1xuICAgIGlmIChwaGFzZUluZGV4ICE9PSAtMSkge1xuICAgICAgbmV3c3R4LnNjb3Blc2V0cy5waGFzZSA9IHRoaXMuc2NvcGVzZXRzLnBoYXNlLnNldChcbiAgICAgICAgcGhhc2UsXG4gICAgICAgIHBoYXNlU2NvcGVzZXQucmVtb3ZlKHBoYXNlSW5kZXgpLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKGFsbEluZGV4ICE9PSAtMSkge1xuICAgICAgbmV3c3R4LnNjb3Blc2V0cy5hbGwgPSBhbGxTY29wZXNldC5yZW1vdmUoYWxsSW5kZXgpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFN5bnRheCh0b2tlbiwgbmV3c3R4KTtcbiAgfVxuXG4gIG1hdGNoKHR5cGU6IFRva2VuVGFnLCB2YWx1ZTogYW55KSB7XG4gICAgaWYgKCFUeXBlc1t0eXBlXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHR5cGUgKyAnIGlzIGFuIGludmFsaWQgdHlwZScpO1xuICAgIH1cbiAgICByZXR1cm4gVHlwZXNbdHlwZV0ubWF0Y2godGhpcy50b2tlbikgJiZcbiAgICAgICh2YWx1ZSA9PSBudWxsIHx8XG4gICAgICAgICh2YWx1ZSBpbnN0YW5jZW9mIFJlZ0V4cFxuICAgICAgICAgID8gdmFsdWUudGVzdCh0aGlzLnZhbCgpKVxuICAgICAgICAgIDogdGhpcy52YWwoKSA9PSB2YWx1ZSkpO1xuICB9XG5cbiAgaXNJZGVudGlmaWVyKHZhbHVlOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5tYXRjaCgnaWRlbnRpZmllcicsIHZhbHVlKTtcbiAgfVxuXG4gIGlzQXNzaWduKHZhbHVlOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5tYXRjaCgnYXNzaWduJywgdmFsdWUpO1xuICB9XG5cbiAgaXNCb29sZWFuTGl0ZXJhbCh2YWx1ZTogYm9vbGVhbikge1xuICAgIHJldHVybiB0aGlzLm1hdGNoKCdib29sZWFuJywgdmFsdWUpO1xuICB9XG5cbiAgaXNLZXl3b3JkKHZhbHVlOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5tYXRjaCgna2V5d29yZCcsIHZhbHVlKTtcbiAgfVxuXG4gIGlzTnVsbExpdGVyYWwodmFsdWU6IGFueSkge1xuICAgIHJldHVybiB0aGlzLm1hdGNoKCdudWxsJywgdmFsdWUpO1xuICB9XG5cbiAgaXNOdW1lcmljTGl0ZXJhbCh2YWx1ZTogbnVtYmVyKSB7XG4gICAgcmV0dXJuIHRoaXMubWF0Y2goJ251bWJlcicsIHZhbHVlKTtcbiAgfVxuXG4gIGlzUHVuY3R1YXRvcih2YWx1ZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMubWF0Y2goJ3B1bmN0dWF0b3InLCB2YWx1ZSk7XG4gIH1cblxuICBpc1N0cmluZ0xpdGVyYWwodmFsdWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLm1hdGNoKCdzdHJpbmcnLCB2YWx1ZSk7XG4gIH1cblxuICBpc1JlZ3VsYXJFeHByZXNzaW9uKHZhbHVlOiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5tYXRjaCgncmVndWxhckV4cHJlc3Npb24nLCB2YWx1ZSk7XG4gIH1cblxuICBpc1RlbXBsYXRlKHZhbHVlOiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5tYXRjaCgndGVtcGxhdGUnLCB2YWx1ZSk7XG4gIH1cblxuICBpc0RlbGltaXRlcih2YWx1ZTogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMubWF0Y2goJ2RlbGltaXRlcicsIHZhbHVlKTtcbiAgfVxuXG4gIGlzUGFyZW5zKHZhbHVlOiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5tYXRjaCgncGFyZW5zJywgdmFsdWUpO1xuICB9XG5cbiAgaXNCcmFjZXModmFsdWU6IGFueSkge1xuICAgIHJldHVybiB0aGlzLm1hdGNoKCdicmFjZXMnLCB2YWx1ZSk7XG4gIH1cblxuICBpc0JyYWNrZXRzKHZhbHVlOiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5tYXRjaCgnYnJhY2tldHMnLCB2YWx1ZSk7XG4gIH1cblxuICBpc1N5bnRheFRlbXBsYXRlKHZhbHVlOiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5tYXRjaCgnc3ludGF4VGVtcGxhdGUnLCB2YWx1ZSk7XG4gIH1cblxuICBpc0VPRih2YWx1ZTogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMubWF0Y2goJ2VvZicsIHZhbHVlKTtcbiAgfVxuXG4gIHRvU3RyaW5nKCkge1xuICAgIGlmICh0aGlzLm1hdGNoKCdkZWxpbWl0ZXInKSkge1xuICAgICAgcmV0dXJuIHRoaXMudG9rZW4ubWFwKHMgPT4gcy50b1N0cmluZygpKS5qb2luKCcgJyk7XG4gICAgfVxuICAgIGlmICh0aGlzLm1hdGNoKCdzdHJpbmcnKSkge1xuICAgICAgcmV0dXJuIGAnJHt0aGlzLnRva2VuLnN0cn0nYDtcbiAgICB9XG4gICAgaWYgKHRoaXMubWF0Y2goJ3RlbXBsYXRlJykpIHtcbiAgICAgIHJldHVybiB0aGlzLnZhbCgpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy50b2tlbi52YWx1ZTtcbiAgfVxufVxuIl19\n\n/***/ },\n/* 59 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.expect = expect;\n\texports.assert = assert;\n\tfunction expect(cond, message, offendingSyntax, rest) {\n\t  if (!cond) {\n\t    let ctx = '';\n\t    if (rest) {\n\t      ctx = rest.slice(0, 20).map(s => {\n\t        let val = s.isDelimiter() ? '( ... )' : s.val();\n\t        if (s === offendingSyntax) {\n\t          return '__' + val + '__';\n\t        }\n\t        return val;\n\t      }).join(' ');\n\t    }\n\t    throw new Error('[error]: ' + message + '\\n' + ctx);\n\t  }\n\t}\n\n\tfunction assert(cond, message) {\n\t  if (!cond) {\n\t    throw new Error('[assertion error]: ' + message);\n\t  }\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lcnJvcnMuanMiXSwibmFtZXMiOlsiZXhwZWN0IiwiYXNzZXJ0IiwiY29uZCIsIm1lc3NhZ2UiLCJvZmZlbmRpbmdTeW50YXgiLCJyZXN0IiwiY3R4Iiwic2xpY2UiLCJtYXAiLCJzIiwidmFsIiwiaXNEZWxpbWl0ZXIiLCJqb2luIiwiRXJyb3IiXSwibWFwcGluZ3MiOiI7Ozs7O1FBQWdCQSxNLEdBQUFBLE07UUFtQkFDLE0sR0FBQUEsTTtBQW5CVCxTQUFTRCxNQUFULENBQWdCRSxJQUFoQixFQUFzQkMsT0FBdEIsRUFBK0JDLGVBQS9CLEVBQWdEQyxJQUFoRCxFQUFzRDtBQUMzRCxNQUFJLENBQUNILElBQUwsRUFBVztBQUNULFFBQUlJLE1BQU0sRUFBVjtBQUNBLFFBQUlELElBQUosRUFBVTtBQUNSQyxZQUFNRCxLQUNIRSxLQURHLENBQ0csQ0FESCxFQUNNLEVBRE4sRUFFSEMsR0FGRyxDQUVDQyxLQUFLO0FBQ1IsWUFBSUMsTUFBTUQsRUFBRUUsV0FBRixLQUFrQixTQUFsQixHQUE4QkYsRUFBRUMsR0FBRixFQUF4QztBQUNBLFlBQUlELE1BQU1MLGVBQVYsRUFBMkI7QUFDekIsaUJBQU8sT0FBT00sR0FBUCxHQUFhLElBQXBCO0FBQ0Q7QUFDRCxlQUFPQSxHQUFQO0FBQ0QsT0FSRyxFQVNIRSxJQVRHLENBU0UsR0FURixDQUFOO0FBVUQ7QUFDRCxVQUFNLElBQUlDLEtBQUosQ0FBVSxjQUFjVixPQUFkLEdBQXdCLElBQXhCLEdBQStCRyxHQUF6QyxDQUFOO0FBQ0Q7QUFDRjs7QUFFTSxTQUFTTCxNQUFULENBQWdCQyxJQUFoQixFQUFzQkMsT0FBdEIsRUFBK0I7QUFDcEMsTUFBSSxDQUFDRCxJQUFMLEVBQVc7QUFDVCxVQUFNLElBQUlXLEtBQUosQ0FBVSx3QkFBd0JWLE9BQWxDLENBQU47QUFDRDtBQUNGIiwiZmlsZSI6ImVycm9ycy5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBmdW5jdGlvbiBleHBlY3QoY29uZCwgbWVzc2FnZSwgb2ZmZW5kaW5nU3ludGF4LCByZXN0KSB7XG4gIGlmICghY29uZCkge1xuICAgIGxldCBjdHggPSAnJztcbiAgICBpZiAocmVzdCkge1xuICAgICAgY3R4ID0gcmVzdFxuICAgICAgICAuc2xpY2UoMCwgMjApXG4gICAgICAgIC5tYXAocyA9PiB7XG4gICAgICAgICAgbGV0IHZhbCA9IHMuaXNEZWxpbWl0ZXIoKSA/ICcoIC4uLiApJyA6IHMudmFsKCk7XG4gICAgICAgICAgaWYgKHMgPT09IG9mZmVuZGluZ1N5bnRheCkge1xuICAgICAgICAgICAgcmV0dXJuICdfXycgKyB2YWwgKyAnX18nO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgICB9KVxuICAgICAgICAuam9pbignICcpO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1tlcnJvcl06ICcgKyBtZXNzYWdlICsgJ1xcbicgKyBjdHgpO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnQoY29uZCwgbWVzc2FnZSkge1xuICBpZiAoIWNvbmQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1thc3NlcnRpb24gZXJyb3JdOiAnICsgbWVzc2FnZSk7XG4gIH1cbn1cbiJdfQ==\n\n/***/ },\n/* 60 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\n\tvar _immutable = __webpack_require__(12);\n\n\tvar _errors = __webpack_require__(59);\n\n\tvar _ramdaFantasy = __webpack_require__(21);\n\n\tvar _syntax = __webpack_require__(58);\n\n\tvar _syntax2 = _interopRequireDefault(_syntax);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tclass BindingMap {\n\n\t  constructor() {\n\t    this._map = new Map();\n\t  }\n\n\t  // given a syntax object and a binding,\n\t  // add the binding to the map associating the binding with the syntax object's\n\t  // scope set\n\t  add(stx, {\n\t    binding,\n\t    phase,\n\t    skipDup = false\n\t  }) {\n\t    let stxName = stx.val();\n\t    let allScopeset = stx.scopesets.all;\n\t    let scopeset = stx.scopesets.phase.has(phase) ? stx.scopesets.phase.get(phase) : (0, _immutable.List)();\n\t    scopeset = allScopeset.concat(scopeset);\n\t    (0, _errors.assert)(phase != null, 'must provide a phase for binding add');\n\n\t    let scopesetBindingList = this._map.get(stxName);\n\t    if (scopesetBindingList) {\n\t      if (skipDup && scopesetBindingList.some(s => s.scopes.equals(scopeset))) {\n\t        return;\n\t      }\n\t      this._map.set(stxName, scopesetBindingList.push({\n\t        scopes: scopeset,\n\t        binding: binding,\n\t        alias: _ramdaFantasy.Maybe.Nothing()\n\t      }));\n\t    } else {\n\t      this._map.set(stxName, _immutable.List.of({\n\t        scopes: scopeset,\n\t        binding: binding,\n\t        alias: _ramdaFantasy.Maybe.Nothing()\n\t      }));\n\t    }\n\t  }\n\n\t  addForward(stx, forwardStx, binding, phase) {\n\t    let stxName = stx.token.value;\n\t    let allScopeset = stx.scopesets.all;\n\t    let scopeset = stx.scopesets.phase.has(phase) ? stx.scopesets.phase.get(phase) : (0, _immutable.List)();\n\t    scopeset = allScopeset.concat(scopeset);\n\t    (0, _errors.assert)(phase != null, 'must provide a phase for binding add');\n\n\t    let scopesetBindingList = this._map.get(stxName);\n\t    if (scopesetBindingList) {\n\t      this._map.set(stxName, scopesetBindingList.push({\n\t        scopes: scopeset,\n\t        binding: binding,\n\t        alias: _ramdaFantasy.Maybe.of(forwardStx)\n\t      }));\n\t    } else {\n\t      this._map.set(stxName, _immutable.List.of({\n\t        scopes: scopeset,\n\t        binding: binding,\n\t        alias: _ramdaFantasy.Maybe.of(forwardStx)\n\t      }));\n\t    }\n\t  }\n\n\t  get(stx) {\n\t    return this._map.get(stx.token.value);\n\t  }\n\t}\n\texports.default = BindingMap;\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9iaW5kaW5nLW1hcC5qcyJdLCJuYW1lcyI6WyJCaW5kaW5nTWFwIiwiY29uc3RydWN0b3IiLCJfbWFwIiwiTWFwIiwiYWRkIiwic3R4IiwiYmluZGluZyIsInBoYXNlIiwic2tpcER1cCIsInN0eE5hbWUiLCJ2YWwiLCJhbGxTY29wZXNldCIsInNjb3Blc2V0cyIsImFsbCIsInNjb3Blc2V0IiwiaGFzIiwiZ2V0IiwiY29uY2F0Iiwic2NvcGVzZXRCaW5kaW5nTGlzdCIsInNvbWUiLCJzIiwic2NvcGVzIiwiZXF1YWxzIiwic2V0IiwicHVzaCIsImFsaWFzIiwiTm90aGluZyIsIm9mIiwiYWRkRm9yd2FyZCIsImZvcndhcmRTdHgiLCJ0b2tlbiIsInZhbHVlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFQTs7Ozs7O0FBVWUsTUFBTUEsVUFBTixDQUFpQjs7QUFHOUJDLGdCQUFjO0FBQ1osU0FBS0MsSUFBTCxHQUFZLElBQUlDLEdBQUosRUFBWjtBQUNEOztBQUVEO0FBQ0E7QUFDQTtBQUNBQyxNQUNFQyxHQURGLEVBRUU7QUFDRUMsV0FERjtBQUVFQyxTQUZGO0FBR0VDLGNBQVU7QUFIWixHQUZGLEVBT0U7QUFDQSxRQUFJQyxVQUFVSixJQUFJSyxHQUFKLEVBQWQ7QUFDQSxRQUFJQyxjQUFjTixJQUFJTyxTQUFKLENBQWNDLEdBQWhDO0FBQ0EsUUFBSUMsV0FBV1QsSUFBSU8sU0FBSixDQUFjTCxLQUFkLENBQW9CUSxHQUFwQixDQUF3QlIsS0FBeEIsSUFDWEYsSUFBSU8sU0FBSixDQUFjTCxLQUFkLENBQW9CUyxHQUFwQixDQUF3QlQsS0FBeEIsQ0FEVyxHQUVYLHNCQUZKO0FBR0FPLGVBQVdILFlBQVlNLE1BQVosQ0FBbUJILFFBQW5CLENBQVg7QUFDQSx3QkFBT1AsU0FBUyxJQUFoQixFQUFzQixzQ0FBdEI7O0FBRUEsUUFBSVcsc0JBQXNCLEtBQUtoQixJQUFMLENBQVVjLEdBQVYsQ0FBY1AsT0FBZCxDQUExQjtBQUNBLFFBQUlTLG1CQUFKLEVBQXlCO0FBQ3ZCLFVBQUlWLFdBQVdVLG9CQUFvQkMsSUFBcEIsQ0FBeUJDLEtBQUtBLEVBQUVDLE1BQUYsQ0FBU0MsTUFBVCxDQUFnQlIsUUFBaEIsQ0FBOUIsQ0FBZixFQUF5RTtBQUN2RTtBQUNEO0FBQ0QsV0FBS1osSUFBTCxDQUFVcUIsR0FBVixDQUNFZCxPQURGLEVBRUVTLG9CQUFvQk0sSUFBcEIsQ0FBeUI7QUFDdkJILGdCQUFRUCxRQURlO0FBRXZCUixpQkFBU0EsT0FGYztBQUd2Qm1CLGVBQU8sb0JBQU1DLE9BQU47QUFIZ0IsT0FBekIsQ0FGRjtBQVFELEtBWkQsTUFZTztBQUNMLFdBQUt4QixJQUFMLENBQVVxQixHQUFWLENBQ0VkLE9BREYsRUFFRSxnQkFBS2tCLEVBQUwsQ0FBUTtBQUNOTixnQkFBUVAsUUFERjtBQUVOUixpQkFBU0EsT0FGSDtBQUdObUIsZUFBTyxvQkFBTUMsT0FBTjtBQUhELE9BQVIsQ0FGRjtBQVFEO0FBQ0Y7O0FBRURFLGFBQ0V2QixHQURGLEVBRUV3QixVQUZGLEVBR0V2QixPQUhGLEVBSUVDLEtBSkYsRUFLRTtBQUNBLFFBQUlFLFVBQVVKLElBQUl5QixLQUFKLENBQVVDLEtBQXhCO0FBQ0EsUUFBSXBCLGNBQWNOLElBQUlPLFNBQUosQ0FBY0MsR0FBaEM7QUFDQSxRQUFJQyxXQUFXVCxJQUFJTyxTQUFKLENBQWNMLEtBQWQsQ0FBb0JRLEdBQXBCLENBQXdCUixLQUF4QixJQUNYRixJQUFJTyxTQUFKLENBQWNMLEtBQWQsQ0FBb0JTLEdBQXBCLENBQXdCVCxLQUF4QixDQURXLEdBRVgsc0JBRko7QUFHQU8sZUFBV0gsWUFBWU0sTUFBWixDQUFtQkgsUUFBbkIsQ0FBWDtBQUNBLHdCQUFPUCxTQUFTLElBQWhCLEVBQXNCLHNDQUF0Qjs7QUFFQSxRQUFJVyxzQkFBc0IsS0FBS2hCLElBQUwsQ0FBVWMsR0FBVixDQUFjUCxPQUFkLENBQTFCO0FBQ0EsUUFBSVMsbUJBQUosRUFBeUI7QUFDdkIsV0FBS2hCLElBQUwsQ0FBVXFCLEdBQVYsQ0FDRWQsT0FERixFQUVFUyxvQkFBb0JNLElBQXBCLENBQXlCO0FBQ3ZCSCxnQkFBUVAsUUFEZTtBQUV2QlIsaUJBQVNBLE9BRmM7QUFHdkJtQixlQUFPLG9CQUFNRSxFQUFOLENBQVNFLFVBQVQ7QUFIZ0IsT0FBekIsQ0FGRjtBQVFELEtBVEQsTUFTTztBQUNMLFdBQUszQixJQUFMLENBQVVxQixHQUFWLENBQ0VkLE9BREYsRUFFRSxnQkFBS2tCLEVBQUwsQ0FBUTtBQUNOTixnQkFBUVAsUUFERjtBQUVOUixpQkFBU0EsT0FGSDtBQUdObUIsZUFBTyxvQkFBTUUsRUFBTixDQUFTRSxVQUFUO0FBSEQsT0FBUixDQUZGO0FBUUQ7QUFDRjs7QUFFRGIsTUFBSVgsR0FBSixFQUFpQjtBQUNmLFdBQU8sS0FBS0gsSUFBTCxDQUFVYyxHQUFWLENBQWNYLElBQUl5QixLQUFKLENBQVVDLEtBQXhCLENBQVA7QUFDRDtBQXpGNkI7a0JBQVgvQixVIiwiZmlsZSI6ImJpbmRpbmctbWFwLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbmltcG9ydCB7IExpc3QgfSBmcm9tICdpbW11dGFibGUnO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSAnLi9lcnJvcnMnO1xuaW1wb3J0IHsgTWF5YmUgfSBmcm9tICdyYW1kYS1mYW50YXN5JztcbmltcG9ydCB0eXBlIHsgU3ltYm9sQ2xhc3MgfSBmcm9tICcuL3N5bWJvbCc7XG5pbXBvcnQgU3ludGF4IGZyb20gJy4vc3ludGF4JztcblxudHlwZSBTY29wZXNldCA9IGFueTtcblxudHlwZSBTY29wZXNldEJpbmRpbmcgPSB7XG4gIHNjb3BlczogU2NvcGVzZXQsXG4gIGJpbmRpbmc6IFN5bWJvbENsYXNzLFxuICBhbGlhczogTWF5YmU8U3ludGF4Pixcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJpbmRpbmdNYXAge1xuICBfbWFwOiBNYXA8c3RyaW5nLCBMaXN0PFNjb3Blc2V0QmluZGluZz4+O1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuX21hcCA9IG5ldyBNYXAoKTtcbiAgfVxuXG4gIC8vIGdpdmVuIGEgc3ludGF4IG9iamVjdCBhbmQgYSBiaW5kaW5nLFxuICAvLyBhZGQgdGhlIGJpbmRpbmcgdG8gdGhlIG1hcCBhc3NvY2lhdGluZyB0aGUgYmluZGluZyB3aXRoIHRoZSBzeW50YXggb2JqZWN0J3NcbiAgLy8gc2NvcGUgc2V0XG4gIGFkZChcbiAgICBzdHg6IFN5bnRheCxcbiAgICB7XG4gICAgICBiaW5kaW5nLFxuICAgICAgcGhhc2UsXG4gICAgICBza2lwRHVwID0gZmFsc2UsXG4gICAgfTogeyBiaW5kaW5nOiBTeW1ib2xDbGFzcywgcGhhc2U6IG51bWJlciB8IHt9LCBza2lwRHVwOiBib29sZWFuIH0sXG4gICkge1xuICAgIGxldCBzdHhOYW1lID0gc3R4LnZhbCgpO1xuICAgIGxldCBhbGxTY29wZXNldCA9IHN0eC5zY29wZXNldHMuYWxsO1xuICAgIGxldCBzY29wZXNldCA9IHN0eC5zY29wZXNldHMucGhhc2UuaGFzKHBoYXNlKVxuICAgICAgPyBzdHguc2NvcGVzZXRzLnBoYXNlLmdldChwaGFzZSlcbiAgICAgIDogTGlzdCgpO1xuICAgIHNjb3Blc2V0ID0gYWxsU2NvcGVzZXQuY29uY2F0KHNjb3Blc2V0KTtcbiAgICBhc3NlcnQocGhhc2UgIT0gbnVsbCwgJ211c3QgcHJvdmlkZSBhIHBoYXNlIGZvciBiaW5kaW5nIGFkZCcpO1xuXG4gICAgbGV0IHNjb3Blc2V0QmluZGluZ0xpc3QgPSB0aGlzLl9tYXAuZ2V0KHN0eE5hbWUpO1xuICAgIGlmIChzY29wZXNldEJpbmRpbmdMaXN0KSB7XG4gICAgICBpZiAoc2tpcER1cCAmJiBzY29wZXNldEJpbmRpbmdMaXN0LnNvbWUocyA9PiBzLnNjb3Blcy5lcXVhbHMoc2NvcGVzZXQpKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLl9tYXAuc2V0KFxuICAgICAgICBzdHhOYW1lLFxuICAgICAgICBzY29wZXNldEJpbmRpbmdMaXN0LnB1c2goe1xuICAgICAgICAgIHNjb3Blczogc2NvcGVzZXQsXG4gICAgICAgICAgYmluZGluZzogYmluZGluZyxcbiAgICAgICAgICBhbGlhczogTWF5YmUuTm90aGluZygpLFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX21hcC5zZXQoXG4gICAgICAgIHN0eE5hbWUsXG4gICAgICAgIExpc3Qub2Yoe1xuICAgICAgICAgIHNjb3Blczogc2NvcGVzZXQsXG4gICAgICAgICAgYmluZGluZzogYmluZGluZyxcbiAgICAgICAgICBhbGlhczogTWF5YmUuTm90aGluZygpLFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgYWRkRm9yd2FyZChcbiAgICBzdHg6IFN5bnRheCxcbiAgICBmb3J3YXJkU3R4OiBTeW50YXgsXG4gICAgYmluZGluZzogU3ltYm9sQ2xhc3MsXG4gICAgcGhhc2U6IG51bWJlciB8IHt9LFxuICApIHtcbiAgICBsZXQgc3R4TmFtZSA9IHN0eC50b2tlbi52YWx1ZTtcbiAgICBsZXQgYWxsU2NvcGVzZXQgPSBzdHguc2NvcGVzZXRzLmFsbDtcbiAgICBsZXQgc2NvcGVzZXQgPSBzdHguc2NvcGVzZXRzLnBoYXNlLmhhcyhwaGFzZSlcbiAgICAgID8gc3R4LnNjb3Blc2V0cy5waGFzZS5nZXQocGhhc2UpXG4gICAgICA6IExpc3QoKTtcbiAgICBzY29wZXNldCA9IGFsbFNjb3Blc2V0LmNvbmNhdChzY29wZXNldCk7XG4gICAgYXNzZXJ0KHBoYXNlICE9IG51bGwsICdtdXN0IHByb3ZpZGUgYSBwaGFzZSBmb3IgYmluZGluZyBhZGQnKTtcblxuICAgIGxldCBzY29wZXNldEJpbmRpbmdMaXN0ID0gdGhpcy5fbWFwLmdldChzdHhOYW1lKTtcbiAgICBpZiAoc2NvcGVzZXRCaW5kaW5nTGlzdCkge1xuICAgICAgdGhpcy5fbWFwLnNldChcbiAgICAgICAgc3R4TmFtZSxcbiAgICAgICAgc2NvcGVzZXRCaW5kaW5nTGlzdC5wdXNoKHtcbiAgICAgICAgICBzY29wZXM6IHNjb3Blc2V0LFxuICAgICAgICAgIGJpbmRpbmc6IGJpbmRpbmcsXG4gICAgICAgICAgYWxpYXM6IE1heWJlLm9mKGZvcndhcmRTdHgpLFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX21hcC5zZXQoXG4gICAgICAgIHN0eE5hbWUsXG4gICAgICAgIExpc3Qub2Yoe1xuICAgICAgICAgIHNjb3Blczogc2NvcGVzZXQsXG4gICAgICAgICAgYmluZGluZzogYmluZGluZyxcbiAgICAgICAgICBhbGlhczogTWF5YmUub2YoZm9yd2FyZFN0eCksXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBnZXQoc3R4OiBTeW50YXgpIHtcbiAgICByZXR1cm4gdGhpcy5fbWFwLmdldChzdHgudG9rZW4udmFsdWUpO1xuICB9XG59XG4iXX0=\n\n/***/ },\n/* 61 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\n\tvar _termExpander = __webpack_require__(62);\n\n\tvar _termExpander2 = _interopRequireDefault(_termExpander);\n\n\tvar _tokenExpander = __webpack_require__(70);\n\n\tvar _tokenExpander2 = _interopRequireDefault(_tokenExpander);\n\n\tvar _ramda = __webpack_require__(20);\n\n\tvar _ = _interopRequireWildcard(_ramda);\n\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tclass Compiler {\n\t  constructor(phase, env, store, context) {\n\t    this.phase = phase;\n\t    this.env = env;\n\t    this.store = store;\n\t    this.context = context;\n\t  }\n\n\t  compile(stxl) {\n\t    let tokenExpander = new _tokenExpander2.default(_.merge(this.context, {\n\t      phase: this.phase,\n\t      env: this.env,\n\t      store: this.store\n\t    }));\n\t    let termExpander = new _termExpander2.default(_.merge(this.context, {\n\t      phase: this.phase,\n\t      env: this.env,\n\t      store: this.store\n\t    }));\n\n\t    return tokenExpander.expand(stxl).map(t => termExpander.expand(t));\n\t  }\n\t}\n\texports.default = Compiler;\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21waWxlci5qcyJdLCJuYW1lcyI6WyJfIiwiQ29tcGlsZXIiLCJjb25zdHJ1Y3RvciIsInBoYXNlIiwiZW52Iiwic3RvcmUiLCJjb250ZXh0IiwiY29tcGlsZSIsInN0eGwiLCJ0b2tlbkV4cGFuZGVyIiwibWVyZ2UiLCJ0ZXJtRXhwYW5kZXIiLCJleHBhbmQiLCJtYXAiLCJ0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTs7OztBQUNBOzs7O0FBQ0E7O0lBQVlBLEM7Ozs7OztBQUVHLE1BQU1DLFFBQU4sQ0FBZTtBQUM1QkMsY0FBWUMsS0FBWixFQUFtQkMsR0FBbkIsRUFBd0JDLEtBQXhCLEVBQStCQyxPQUEvQixFQUF3QztBQUN0QyxTQUFLSCxLQUFMLEdBQWFBLEtBQWI7QUFDQSxTQUFLQyxHQUFMLEdBQVdBLEdBQVg7QUFDQSxTQUFLQyxLQUFMLEdBQWFBLEtBQWI7QUFDQSxTQUFLQyxPQUFMLEdBQWVBLE9BQWY7QUFDRDs7QUFFREMsVUFBUUMsSUFBUixFQUFjO0FBQ1osUUFBSUMsZ0JBQWdCLDRCQUNsQlQsRUFBRVUsS0FBRixDQUFRLEtBQUtKLE9BQWIsRUFBc0I7QUFDcEJILGFBQU8sS0FBS0EsS0FEUTtBQUVwQkMsV0FBSyxLQUFLQSxHQUZVO0FBR3BCQyxhQUFPLEtBQUtBO0FBSFEsS0FBdEIsQ0FEa0IsQ0FBcEI7QUFPQSxRQUFJTSxlQUFlLDJCQUNqQlgsRUFBRVUsS0FBRixDQUFRLEtBQUtKLE9BQWIsRUFBc0I7QUFDcEJILGFBQU8sS0FBS0EsS0FEUTtBQUVwQkMsV0FBSyxLQUFLQSxHQUZVO0FBR3BCQyxhQUFPLEtBQUtBO0FBSFEsS0FBdEIsQ0FEaUIsQ0FBbkI7O0FBUUEsV0FBT0ksY0FBY0csTUFBZCxDQUFxQkosSUFBckIsRUFBMkJLLEdBQTNCLENBQStCQyxLQUFLSCxhQUFhQyxNQUFiLENBQW9CRSxDQUFwQixDQUFwQyxDQUFQO0FBQ0Q7QUF6QjJCO2tCQUFUYixRIiwiZmlsZSI6ImNvbXBpbGVyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFRlcm1FeHBhbmRlciBmcm9tICcuL3Rlcm0tZXhwYW5kZXIuanMnO1xuaW1wb3J0IFRva2VuRXhwYW5kZXIgZnJvbSAnLi90b2tlbi1leHBhbmRlcic7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ3JhbWRhJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ29tcGlsZXIge1xuICBjb25zdHJ1Y3RvcihwaGFzZSwgZW52LCBzdG9yZSwgY29udGV4dCkge1xuICAgIHRoaXMucGhhc2UgPSBwaGFzZTtcbiAgICB0aGlzLmVudiA9IGVudjtcbiAgICB0aGlzLnN0b3JlID0gc3RvcmU7XG4gICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDtcbiAgfVxuXG4gIGNvbXBpbGUoc3R4bCkge1xuICAgIGxldCB0b2tlbkV4cGFuZGVyID0gbmV3IFRva2VuRXhwYW5kZXIoXG4gICAgICBfLm1lcmdlKHRoaXMuY29udGV4dCwge1xuICAgICAgICBwaGFzZTogdGhpcy5waGFzZSxcbiAgICAgICAgZW52OiB0aGlzLmVudixcbiAgICAgICAgc3RvcmU6IHRoaXMuc3RvcmUsXG4gICAgICB9KSxcbiAgICApO1xuICAgIGxldCB0ZXJtRXhwYW5kZXIgPSBuZXcgVGVybUV4cGFuZGVyKFxuICAgICAgXy5tZXJnZSh0aGlzLmNvbnRleHQsIHtcbiAgICAgICAgcGhhc2U6IHRoaXMucGhhc2UsXG4gICAgICAgIGVudjogdGhpcy5lbnYsXG4gICAgICAgIHN0b3JlOiB0aGlzLnN0b3JlLFxuICAgICAgfSksXG4gICAgKTtcblxuICAgIHJldHVybiB0b2tlbkV4cGFuZGVyLmV4cGFuZChzdHhsKS5tYXAodCA9PiB0ZXJtRXhwYW5kZXIuZXhwYW5kKHQpKTtcbiAgfVxufVxuIl19\n\n/***/ },\n/* 62 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\n\tvar _immutable = __webpack_require__(12);\n\n\tvar _terms = __webpack_require__(57);\n\n\tvar _sweetSpec = __webpack_require__(43);\n\n\tvar T = _interopRequireWildcard(_sweetSpec);\n\n\tvar _scope = __webpack_require__(38);\n\n\tvar _compiler = __webpack_require__(61);\n\n\tvar _compiler2 = _interopRequireDefault(_compiler);\n\n\tvar _syntax = __webpack_require__(58);\n\n\tvar _syntax2 = _interopRequireDefault(_syntax);\n\n\tvar _enforester = __webpack_require__(63);\n\n\tvar _templateProcessor = __webpack_require__(67);\n\n\tvar _astDispatcher = __webpack_require__(69);\n\n\tvar _astDispatcher2 = _interopRequireDefault(_astDispatcher);\n\n\tvar _scopeReducer = __webpack_require__(64);\n\n\tvar _scopeReducer2 = _interopRequireDefault(_scopeReducer);\n\n\tvar _symbol = __webpack_require__(39);\n\n\tvar _transforms = __webpack_require__(41);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\n\tclass TermExpander extends _astDispatcher2.default {\n\t  constructor(context) {\n\t    super('expand', true);\n\t    this.context = context;\n\t  }\n\n\t  expand(term) {\n\t    return this.dispatch(term);\n\t  }\n\n\t  expandRawSyntax(term) {\n\t    return term;\n\t  }\n\n\t  expandRawDelimiter(term) {\n\t    return term;\n\t  }\n\n\t  expandTemplateExpression(term) {\n\t    return new T.TemplateExpression({\n\t      tag: term.tag == null ? null : this.expand(term.tag),\n\t      elements: term.elements.toArray()\n\t    });\n\t  }\n\n\t  expandBreakStatement(term) {\n\t    return new T.BreakStatement({\n\t      label: term.label ? term.label.val() : null\n\t    });\n\t  }\n\n\t  expandDoWhileStatement(term) {\n\t    return new T.DoWhileStatement({\n\t      body: this.expand(term.body),\n\t      test: this.expand(term.test)\n\t    });\n\t  }\n\n\t  expandWithStatement(term) {\n\t    return new T.WithStatement({\n\t      body: this.expand(term.body),\n\t      object: this.expand(term.object)\n\t    });\n\t  }\n\n\t  expandDebuggerStatement(term) {\n\t    return term;\n\t  }\n\n\t  expandContinueStatement(term) {\n\t    return new T.ContinueStatement({\n\t      label: term.label ? term.label.val() : null\n\t    });\n\t  }\n\n\t  expandSwitchStatementWithDefault(term) {\n\t    return new T.SwitchStatementWithDefault({\n\t      discriminant: this.expand(term.discriminant),\n\t      preDefaultCases: term.preDefaultCases.map(c => this.expand(c)).toArray(),\n\t      defaultCase: this.expand(term.defaultCase),\n\t      postDefaultCases: term.postDefaultCases.map(c => this.expand(c)).toArray()\n\t    });\n\t  }\n\n\t  expandComputedMemberExpression(term) {\n\t    return new T.ComputedMemberExpression({\n\t      object: this.expand(term.object),\n\t      expression: this.expand(term.expression)\n\t    });\n\t  }\n\n\t  expandSwitchStatement(term) {\n\t    return new T.SwitchStatement({\n\t      discriminant: this.expand(term.discriminant),\n\t      cases: term.cases.map(c => this.expand(c)).toArray()\n\t    });\n\t  }\n\n\t  expandFormalParameters(term) {\n\t    let rest = term.rest == null ? null : this.expand(term.rest);\n\t    return new T.FormalParameters({\n\t      items: term.items.map(i => this.expand(i)),\n\t      rest\n\t    });\n\t  }\n\n\t  expandArrowExpressionE(term) {\n\t    return this.doFunctionExpansion(term, 'ArrowExpression');\n\t  }\n\n\t  expandArrowExpression(term) {\n\t    return this.doFunctionExpansion(term, 'ArrowExpression');\n\t  }\n\n\t  expandSwitchDefault(term) {\n\t    return new T.SwitchDefault({\n\t      consequent: term.consequent.map(c => this.expand(c)).toArray()\n\t    });\n\t  }\n\n\t  expandSwitchCase(term) {\n\t    return new T.SwitchCase({\n\t      test: this.expand(term.test),\n\t      consequent: term.consequent.map(c => this.expand(c)).toArray()\n\t    });\n\t  }\n\n\t  expandForInStatement(term) {\n\t    return new T.ForInStatement({\n\t      left: this.expand(term.left),\n\t      right: this.expand(term.right),\n\t      body: this.expand(term.body)\n\t    });\n\t  }\n\n\t  expandTryCatchStatement(term) {\n\t    return new T.TryCatchStatement({\n\t      body: this.expand(term.body),\n\t      catchClause: this.expand(term.catchClause)\n\t    });\n\t  }\n\n\t  expandTryFinallyStatement(term) {\n\t    let catchClause = term.catchClause == null ? null : this.expand(term.catchClause);\n\t    return new T.TryFinallyStatement({\n\t      body: this.expand(term.body),\n\t      catchClause,\n\t      finalizer: this.expand(term.finalizer)\n\t    });\n\t  }\n\n\t  expandCatchClause(term) {\n\t    return new T.CatchClause({\n\t      binding: this.expand(term.binding),\n\t      body: this.expand(term.body)\n\t    });\n\t  }\n\n\t  expandThrowStatement(term) {\n\t    return new T.ThrowStatement({\n\t      expression: this.expand(term.expression)\n\t    });\n\t  }\n\n\t  expandForOfStatement(term) {\n\t    return new T.ForOfStatement({\n\t      left: this.expand(term.left),\n\t      right: this.expand(term.right),\n\t      body: this.expand(term.body)\n\t    });\n\t  }\n\n\t  expandBindingIdentifier(term) {\n\t    return term;\n\t  }\n\n\t  expandBindingPropertyIdentifier(term) {\n\t    return term;\n\t  }\n\t  expandBindingPropertyProperty(term) {\n\t    return new T.BindingPropertyProperty({\n\t      name: this.expand(term.name),\n\t      binding: this.expand(term.binding)\n\t    });\n\t  }\n\n\t  expandComputedPropertyName(term) {\n\t    return new T.ComputedPropertyName({\n\t      expression: this.expand(term.expression)\n\t    });\n\t  }\n\n\t  expandObjectBinding(term) {\n\t    return new T.ObjectBinding({\n\t      properties: term.properties.map(t => this.expand(t)).toArray()\n\t    });\n\t  }\n\n\t  expandArrayBinding(term) {\n\t    let restElement = term.restElement == null ? null : this.expand(term.restElement);\n\t    return new T.ArrayBinding({\n\t      elements: term.elements.map(t => t == null ? null : this.expand(t)).toArray(),\n\t      restElement\n\t    });\n\t  }\n\n\t  expandBindingWithDefault(term) {\n\t    return new T.BindingWithDefault({\n\t      binding: this.expand(term.binding),\n\t      init: this.expand(term.init)\n\t    });\n\t  }\n\n\t  expandShorthandProperty(term) {\n\t    // because hygiene, shorthand properties must turn into DataProperties\n\t    return new T.DataProperty({\n\t      name: new T.StaticPropertyName({\n\t        value: term.name\n\t      }),\n\t      expression: new T.IdentifierExpression({\n\t        name: term.name\n\t      })\n\t    });\n\t  }\n\n\t  expandForStatement(term) {\n\t    let init = term.init == null ? null : this.expand(term.init);\n\t    let test = term.test == null ? null : this.expand(term.test);\n\t    let update = term.update == null ? null : this.expand(term.update);\n\t    let body = this.expand(term.body);\n\t    return new T.ForStatement({ init, test, update, body });\n\t  }\n\n\t  expandYieldExpression(term) {\n\t    let expr = term.expression == null ? null : this.expand(term.expression);\n\t    return new T.YieldExpression({\n\t      expression: expr\n\t    });\n\t  }\n\n\t  expandYieldGeneratorExpression(term) {\n\t    let expr = term.expression == null ? null : this.expand(term.expression);\n\t    return new T.YieldGeneratorExpression({\n\t      expression: expr\n\t    });\n\t  }\n\n\t  expandWhileStatement(term) {\n\t    return new T.WhileStatement({\n\t      test: this.expand(term.test),\n\t      body: this.expand(term.body)\n\t    });\n\t  }\n\n\t  expandIfStatement(term) {\n\t    let consequent = term.consequent == null ? null : this.expand(term.consequent);\n\t    let alternate = term.alternate == null ? null : this.expand(term.alternate);\n\t    return new T.IfStatement({\n\t      test: this.expand(term.test),\n\t      consequent: consequent,\n\t      alternate: alternate\n\t    });\n\t  }\n\n\t  expandBlockStatement(term) {\n\t    return new T.BlockStatement({\n\t      block: this.expand(term.block)\n\t    });\n\t  }\n\n\t  expandBlock(term) {\n\t    let scope = (0, _scope.freshScope)('block');\n\t    this.context.currentScope.push(scope);\n\t    let compiler = new _compiler2.default(this.context.phase, this.context.env, this.context.store, this.context);\n\n\t    let markedBody, bodyTerm;\n\t    markedBody = term.statements.map(b => b.reduce(new _scopeReducer2.default([{ scope, phase: _syntax.ALL_PHASES, flip: false }], this.context.bindings)));\n\t    bodyTerm = new T.Block({\n\t      statements: compiler.compile(markedBody)\n\t    });\n\t    this.context.currentScope.pop();\n\t    return bodyTerm;\n\t  }\n\n\t  expandVariableDeclarationStatement(term) {\n\t    return new T.VariableDeclarationStatement({\n\t      declaration: this.expand(term.declaration)\n\t    });\n\t  }\n\t  expandReturnStatement(term) {\n\t    if (term.expression == null) {\n\t      return term;\n\t    }\n\t    return new T.ReturnStatement({\n\t      expression: this.expand(term.expression)\n\t    });\n\t  }\n\n\t  expandClassDeclaration(term) {\n\t    return new T.ClassDeclaration({\n\t      name: term.name == null ? null : this.expand(term.name),\n\t      super: term.super == null ? null : this.expand(term.super),\n\t      elements: term.elements.map(el => this.expand(el)).toArray()\n\t    });\n\t  }\n\n\t  expandClassExpression(term) {\n\t    return new T.ClassExpression({\n\t      name: term.name == null ? null : this.expand(term.name),\n\t      super: term.super == null ? null : this.expand(term.super),\n\t      elements: term.elements.map(el => this.expand(el)).toArray()\n\t    });\n\t  }\n\n\t  expandClassElement(term) {\n\t    return new T.ClassElement({\n\t      isStatic: term.isStatic,\n\t      method: this.expand(term.method)\n\t    });\n\t  }\n\n\t  expandThisExpression(term) {\n\t    return term;\n\t  }\n\n\t  expandSyntaxTemplate(term) {\n\t    let r = (0, _templateProcessor.processTemplate)(term.template.slice(1, term.template.size - 1));\n\t    let ident = this.context.getTemplateIdentifier();\n\t    this.context.templateMap.set(ident, r.template);\n\t    let name = _syntax2.default.fromIdentifier('syntaxTemplate', term.template.first().value);\n\t    let callee = new T.IdentifierExpression({\n\t      name: name\n\t    });\n\n\t    let expandedInterps = r.interp.map(i => {\n\t      let enf = new _enforester.Enforester(i, (0, _immutable.List)(), this.context);\n\t      return this.expand(enf.enforest('expression'));\n\t    });\n\n\t    let args = _immutable.List.of(new T.LiteralNumericExpression({ value: ident })).concat(expandedInterps);\n\n\t    return new T.CallExpression({\n\t      callee,\n\t      arguments: args\n\t    });\n\t  }\n\n\t  expandStaticMemberExpression(term) {\n\t    return new T.StaticMemberExpression({\n\t      object: this.expand(term.object),\n\t      property: term.property\n\t    });\n\t  }\n\n\t  expandArrayExpression(term) {\n\t    return new T.ArrayExpression({\n\t      elements: term.elements.map(t => t == null ? t : this.expand(t))\n\t    });\n\t  }\n\n\t  expandImport(term) {\n\t    return term;\n\t  }\n\n\t  expandImportNamespace(term) {\n\t    return term;\n\t  }\n\n\t  expandExport(term) {\n\t    return new T.Export({\n\t      declaration: this.expand(term.declaration)\n\t    });\n\t  }\n\n\t  expandExportDefault(term) {\n\t    return new T.ExportDefault({\n\t      body: this.expand(term.body)\n\t    });\n\t  }\n\n\t  expandExportFrom(term) {\n\t    return term;\n\t  }\n\n\t  expandExportAllFrom(term) {\n\t    return term;\n\t  }\n\n\t  expandExportSpecifier(term) {\n\t    return term;\n\t  }\n\n\t  expandStaticPropertyName(term) {\n\t    return term;\n\t  }\n\n\t  expandDataProperty(term) {\n\t    return new T.DataProperty({\n\t      name: this.expand(term.name),\n\t      expression: this.expand(term.expression)\n\t    });\n\t  }\n\n\t  expandObjectExpression(term) {\n\t    return new T.ObjectExpression({\n\t      properties: term.properties.map(t => this.expand(t))\n\t    });\n\t  }\n\n\t  expandVariableDeclarator(term) {\n\t    let init = term.init == null ? null : this.expand(term.init);\n\t    return new T.VariableDeclarator({\n\t      binding: this.expand(term.binding),\n\t      init: init\n\t    });\n\t  }\n\n\t  expandVariableDeclaration(term) {\n\t    if (term.kind === 'syntax' || term.kind === 'syntaxrec' || term.kind === 'operator') {\n\t      return term;\n\t    }\n\t    return new T.VariableDeclaration({\n\t      kind: term.kind,\n\t      declarators: term.declarators.map(d => this.expand(d))\n\t    });\n\t  }\n\n\t  expandParenthesizedExpression(term) {\n\t    if (term.inner.size === 0) {\n\t      throw new Error('unexpected end of input');\n\t    }\n\t    let enf = new _enforester.Enforester(term.inner, (0, _immutable.List)(), this.context);\n\t    let lookahead = enf.peek();\n\t    let t = enf.enforestExpression();\n\t    if (t == null || enf.rest.size > 0) {\n\t      if (enf.rest.size === 0) {\n\t        throw enf.createError(')', 'unexpected token');\n\t      }\n\t      throw enf.createError(lookahead, 'unexpected syntax');\n\t    }\n\t    return this.expand(t);\n\t  }\n\n\t  expandUnaryExpression(term) {\n\t    return new T.UnaryExpression({\n\t      operator: term.operator,\n\t      operand: this.expand(term.operand)\n\t    });\n\t  }\n\n\t  expandUpdateExpression(term) {\n\t    return new T.UpdateExpression({\n\t      isPrefix: term.isPrefix,\n\t      operator: term.operator,\n\t      operand: this.expand(term.operand)\n\t    });\n\t  }\n\n\t  expandBinaryExpression(term) {\n\t    let left = this.expand(term.left);\n\t    let right = this.expand(term.right);\n\t    return new T.BinaryExpression({\n\t      left: left,\n\t      operator: term.operator,\n\t      right: right\n\t    });\n\t  }\n\n\t  expandConditionalExpression(term) {\n\t    return new T.ConditionalExpression({\n\t      test: this.expand(term.test),\n\t      consequent: this.expand(term.consequent),\n\t      alternate: this.expand(term.alternate)\n\t    });\n\t  }\n\n\t  expandNewTargetExpression(term) {\n\t    return term;\n\t  }\n\n\t  expandNewExpression(term) {\n\t    let callee = this.expand(term.callee);\n\t    let enf = new _enforester.Enforester(term.arguments, (0, _immutable.List)(), this.context);\n\t    let args = enf.enforestArgumentList().map(arg => this.expand(arg));\n\t    return new T.NewExpression({\n\t      callee,\n\t      arguments: args.toArray()\n\t    });\n\t  }\n\n\t  expandSuper(term) {\n\t    return term;\n\t  }\n\n\t  expandCallExpressionE(term) {\n\t    let callee = this.expand(term.callee);\n\t    let enf = new _enforester.Enforester(term.arguments, (0, _immutable.List)(), this.context);\n\t    let args = enf.enforestArgumentList().map(arg => this.expand(arg));\n\t    return new T.CallExpression({\n\t      callee: callee,\n\t      arguments: args\n\t    });\n\t  }\n\n\t  expandSpreadElement(term) {\n\t    return new T.SpreadElement({\n\t      expression: this.expand(term.expression)\n\t    });\n\t  }\n\n\t  expandExpressionStatement(term) {\n\t    let child = this.expand(term.expression);\n\t    return new T.ExpressionStatement({\n\t      expression: child\n\t    });\n\t  }\n\n\t  expandLabeledStatement(term) {\n\t    return new T.LabeledStatement({\n\t      label: term.label.val(),\n\t      body: this.expand(term.body)\n\t    });\n\t  }\n\n\t  doFunctionExpansion(term, type) {\n\t    let scope = (0, _scope.freshScope)('fun');\n\t    let params;\n\t    let self = this;\n\t    if (type !== 'Getter' && type !== 'Setter') {\n\t      // TODO: need to register the parameter bindings again\n\t      params = term.params.reduce(new class extends T.default.CloneReducer {\n\t        reduceBindingIdentifier(term) {\n\t          let name = term.name.addScope(scope, self.context.bindings, _syntax.ALL_PHASES);\n\t          let newBinding = (0, _symbol.gensym)(name.val());\n\n\t          self.context.env.set(newBinding.toString(), new _transforms.VarBindingTransform(name));\n\t          self.context.bindings.add(name, {\n\t            binding: newBinding,\n\t            phase: self.context.phase,\n\t            skipDup: true\n\t          });\n\t          return new T.BindingIdentifier({ name });\n\t        }\n\t      }());\n\t      params = this.expand(params);\n\t    }\n\t    this.context.currentScope.push(scope);\n\t    let compiler = new _compiler2.default(this.context.phase, this.context.env, this.context.store, this.context);\n\n\t    let bodyTerm;\n\t    let scopeReducer = new _scopeReducer2.default([{ scope, phase: _syntax.ALL_PHASES, flip: false }], this.context.bindings);\n\t    if (term.body instanceof T.default) {\n\t      // Arrow functions have a single term as their body\n\t      bodyTerm = this.expand(term.body.reduce(scopeReducer));\n\t    } else {\n\t      let compiledBody = compiler.compile(term.body.map(b => b.reduce(scopeReducer)));\n\t      const directives = compiledBody.takeWhile(s => (0, _terms.isExpressionStatement)(s) && (0, _terms.isLiteralStringExpression)(s.expression)).map(s => new T.Directive({ rawValue: s.expression.value }));\n\t      bodyTerm = new T.FunctionBody({\n\t        directives: directives,\n\t        statements: compiledBody.slice(directives.size)\n\t      });\n\t    }\n\t    this.context.currentScope.pop();\n\n\t    switch (type) {\n\t      case 'Getter':\n\t        return new T.Getter({\n\t          name: this.expand(term.name),\n\t          body: bodyTerm\n\t        });\n\t      case 'Setter':\n\t        return new T.Setter({\n\t          name: this.expand(term.name),\n\t          param: term.param,\n\t          body: bodyTerm\n\t        });\n\t      case 'Method':\n\t        return new T.Method({\n\t          name: term.name,\n\t          isGenerator: term.isGenerator,\n\t          params: params,\n\t          body: bodyTerm\n\t        });\n\t      case 'ArrowExpression':\n\t        return new T.ArrowExpression({\n\t          params: params,\n\t          body: bodyTerm\n\t        });\n\t      case 'FunctionExpression':\n\t        return new T.FunctionExpression({\n\t          name: term.name,\n\t          isGenerator: term.isGenerator,\n\t          params: params,\n\t          body: bodyTerm\n\t        });\n\t      case 'FunctionDeclaration':\n\t        return new T.FunctionDeclaration({\n\t          name: term.name,\n\t          isGenerator: term.isGenerator,\n\t          params: params,\n\t          body: bodyTerm\n\t        });\n\t      default:\n\t        throw new Error(`Unknown function type: ${ type }`);\n\t    }\n\t  }\n\n\t  expandMethod(term) {\n\t    return this.doFunctionExpansion(term, 'Method');\n\t  }\n\n\t  expandSetter(term) {\n\t    return this.doFunctionExpansion(term, 'Setter');\n\t  }\n\n\t  expandGetter(term) {\n\t    return this.doFunctionExpansion(term, 'Getter');\n\t  }\n\n\t  expandFunctionDeclarationE(term) {\n\t    return this.doFunctionExpansion(term, 'FunctionDeclaration');\n\t  }\n\n\t  expandFunctionExpressionE(term) {\n\t    return this.doFunctionExpansion(term, 'FunctionExpression');\n\t  }\n\n\t  expandCompoundAssignmentExpression(term) {\n\t    return new T.CompoundAssignmentExpression({\n\t      binding: this.expand(term.binding),\n\t      operator: term.operator,\n\t      expression: this.expand(term.expression)\n\t    });\n\t  }\n\n\t  expandAssignmentExpression(term) {\n\t    return new T.AssignmentExpression({\n\t      binding: this.expand(term.binding),\n\t      expression: this.expand(term.expression)\n\t    });\n\t  }\n\n\t  expandEmptyStatement(term) {\n\t    return term;\n\t  }\n\n\t  expandLiteralBooleanExpression(term) {\n\t    return term;\n\t  }\n\n\t  expandLiteralNumericExpression(term) {\n\t    return term;\n\t  }\n\t  expandLiteralInfinityExpression(term) {\n\t    return term;\n\t  }\n\n\t  expandIdentifierExpression(term) {\n\t    let trans = this.context.env.get(term.name.resolve(this.context.phase));\n\t    if (trans) {\n\t      return new T.IdentifierExpression({\n\t        name: trans.id\n\t      });\n\t    }\n\t    return term;\n\t  }\n\n\t  expandLiteralNullExpression(term) {\n\t    return term;\n\t  }\n\n\t  expandLiteralStringExpression(term) {\n\t    return term;\n\t  }\n\n\t  expandLiteralRegExpExpression(term) {\n\t    return term;\n\t  }\n\t}\n\texports.default = TermExpander;\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXJtLWV4cGFuZGVyLmpzIl0sIm5hbWVzIjpbIlQiLCJUZXJtRXhwYW5kZXIiLCJjb25zdHJ1Y3RvciIsImNvbnRleHQiLCJleHBhbmQiLCJ0ZXJtIiwiZGlzcGF0Y2giLCJleHBhbmRSYXdTeW50YXgiLCJleHBhbmRSYXdEZWxpbWl0ZXIiLCJleHBhbmRUZW1wbGF0ZUV4cHJlc3Npb24iLCJUZW1wbGF0ZUV4cHJlc3Npb24iLCJ0YWciLCJlbGVtZW50cyIsInRvQXJyYXkiLCJleHBhbmRCcmVha1N0YXRlbWVudCIsIkJyZWFrU3RhdGVtZW50IiwibGFiZWwiLCJ2YWwiLCJleHBhbmREb1doaWxlU3RhdGVtZW50IiwiRG9XaGlsZVN0YXRlbWVudCIsImJvZHkiLCJ0ZXN0IiwiZXhwYW5kV2l0aFN0YXRlbWVudCIsIldpdGhTdGF0ZW1lbnQiLCJvYmplY3QiLCJleHBhbmREZWJ1Z2dlclN0YXRlbWVudCIsImV4cGFuZENvbnRpbnVlU3RhdGVtZW50IiwiQ29udGludWVTdGF0ZW1lbnQiLCJleHBhbmRTd2l0Y2hTdGF0ZW1lbnRXaXRoRGVmYXVsdCIsIlN3aXRjaFN0YXRlbWVudFdpdGhEZWZhdWx0IiwiZGlzY3JpbWluYW50IiwicHJlRGVmYXVsdENhc2VzIiwibWFwIiwiYyIsImRlZmF1bHRDYXNlIiwicG9zdERlZmF1bHRDYXNlcyIsImV4cGFuZENvbXB1dGVkTWVtYmVyRXhwcmVzc2lvbiIsIkNvbXB1dGVkTWVtYmVyRXhwcmVzc2lvbiIsImV4cHJlc3Npb24iLCJleHBhbmRTd2l0Y2hTdGF0ZW1lbnQiLCJTd2l0Y2hTdGF0ZW1lbnQiLCJjYXNlcyIsImV4cGFuZEZvcm1hbFBhcmFtZXRlcnMiLCJyZXN0IiwiRm9ybWFsUGFyYW1ldGVycyIsIml0ZW1zIiwiaSIsImV4cGFuZEFycm93RXhwcmVzc2lvbkUiLCJkb0Z1bmN0aW9uRXhwYW5zaW9uIiwiZXhwYW5kQXJyb3dFeHByZXNzaW9uIiwiZXhwYW5kU3dpdGNoRGVmYXVsdCIsIlN3aXRjaERlZmF1bHQiLCJjb25zZXF1ZW50IiwiZXhwYW5kU3dpdGNoQ2FzZSIsIlN3aXRjaENhc2UiLCJleHBhbmRGb3JJblN0YXRlbWVudCIsIkZvckluU3RhdGVtZW50IiwibGVmdCIsInJpZ2h0IiwiZXhwYW5kVHJ5Q2F0Y2hTdGF0ZW1lbnQiLCJUcnlDYXRjaFN0YXRlbWVudCIsImNhdGNoQ2xhdXNlIiwiZXhwYW5kVHJ5RmluYWxseVN0YXRlbWVudCIsIlRyeUZpbmFsbHlTdGF0ZW1lbnQiLCJmaW5hbGl6ZXIiLCJleHBhbmRDYXRjaENsYXVzZSIsIkNhdGNoQ2xhdXNlIiwiYmluZGluZyIsImV4cGFuZFRocm93U3RhdGVtZW50IiwiVGhyb3dTdGF0ZW1lbnQiLCJleHBhbmRGb3JPZlN0YXRlbWVudCIsIkZvck9mU3RhdGVtZW50IiwiZXhwYW5kQmluZGluZ0lkZW50aWZpZXIiLCJleHBhbmRCaW5kaW5nUHJvcGVydHlJZGVudGlmaWVyIiwiZXhwYW5kQmluZGluZ1Byb3BlcnR5UHJvcGVydHkiLCJCaW5kaW5nUHJvcGVydHlQcm9wZXJ0eSIsIm5hbWUiLCJleHBhbmRDb21wdXRlZFByb3BlcnR5TmFtZSIsIkNvbXB1dGVkUHJvcGVydHlOYW1lIiwiZXhwYW5kT2JqZWN0QmluZGluZyIsIk9iamVjdEJpbmRpbmciLCJwcm9wZXJ0aWVzIiwidCIsImV4cGFuZEFycmF5QmluZGluZyIsInJlc3RFbGVtZW50IiwiQXJyYXlCaW5kaW5nIiwiZXhwYW5kQmluZGluZ1dpdGhEZWZhdWx0IiwiQmluZGluZ1dpdGhEZWZhdWx0IiwiaW5pdCIsImV4cGFuZFNob3J0aGFuZFByb3BlcnR5IiwiRGF0YVByb3BlcnR5IiwiU3RhdGljUHJvcGVydHlOYW1lIiwidmFsdWUiLCJJZGVudGlmaWVyRXhwcmVzc2lvbiIsImV4cGFuZEZvclN0YXRlbWVudCIsInVwZGF0ZSIsIkZvclN0YXRlbWVudCIsImV4cGFuZFlpZWxkRXhwcmVzc2lvbiIsImV4cHIiLCJZaWVsZEV4cHJlc3Npb24iLCJleHBhbmRZaWVsZEdlbmVyYXRvckV4cHJlc3Npb24iLCJZaWVsZEdlbmVyYXRvckV4cHJlc3Npb24iLCJleHBhbmRXaGlsZVN0YXRlbWVudCIsIldoaWxlU3RhdGVtZW50IiwiZXhwYW5kSWZTdGF0ZW1lbnQiLCJhbHRlcm5hdGUiLCJJZlN0YXRlbWVudCIsImV4cGFuZEJsb2NrU3RhdGVtZW50IiwiQmxvY2tTdGF0ZW1lbnQiLCJibG9jayIsImV4cGFuZEJsb2NrIiwic2NvcGUiLCJjdXJyZW50U2NvcGUiLCJwdXNoIiwiY29tcGlsZXIiLCJwaGFzZSIsImVudiIsInN0b3JlIiwibWFya2VkQm9keSIsImJvZHlUZXJtIiwic3RhdGVtZW50cyIsImIiLCJyZWR1Y2UiLCJmbGlwIiwiYmluZGluZ3MiLCJCbG9jayIsImNvbXBpbGUiLCJwb3AiLCJleHBhbmRWYXJpYWJsZURlY2xhcmF0aW9uU3RhdGVtZW50IiwiVmFyaWFibGVEZWNsYXJhdGlvblN0YXRlbWVudCIsImRlY2xhcmF0aW9uIiwiZXhwYW5kUmV0dXJuU3RhdGVtZW50IiwiUmV0dXJuU3RhdGVtZW50IiwiZXhwYW5kQ2xhc3NEZWNsYXJhdGlvbiIsIkNsYXNzRGVjbGFyYXRpb24iLCJzdXBlciIsImVsIiwiZXhwYW5kQ2xhc3NFeHByZXNzaW9uIiwiQ2xhc3NFeHByZXNzaW9uIiwiZXhwYW5kQ2xhc3NFbGVtZW50IiwiQ2xhc3NFbGVtZW50IiwiaXNTdGF0aWMiLCJtZXRob2QiLCJleHBhbmRUaGlzRXhwcmVzc2lvbiIsImV4cGFuZFN5bnRheFRlbXBsYXRlIiwiciIsInRlbXBsYXRlIiwic2xpY2UiLCJzaXplIiwiaWRlbnQiLCJnZXRUZW1wbGF0ZUlkZW50aWZpZXIiLCJ0ZW1wbGF0ZU1hcCIsInNldCIsImZyb21JZGVudGlmaWVyIiwiZmlyc3QiLCJjYWxsZWUiLCJleHBhbmRlZEludGVycHMiLCJpbnRlcnAiLCJlbmYiLCJlbmZvcmVzdCIsImFyZ3MiLCJvZiIsIkxpdGVyYWxOdW1lcmljRXhwcmVzc2lvbiIsImNvbmNhdCIsIkNhbGxFeHByZXNzaW9uIiwiYXJndW1lbnRzIiwiZXhwYW5kU3RhdGljTWVtYmVyRXhwcmVzc2lvbiIsIlN0YXRpY01lbWJlckV4cHJlc3Npb24iLCJwcm9wZXJ0eSIsImV4cGFuZEFycmF5RXhwcmVzc2lvbiIsIkFycmF5RXhwcmVzc2lvbiIsImV4cGFuZEltcG9ydCIsImV4cGFuZEltcG9ydE5hbWVzcGFjZSIsImV4cGFuZEV4cG9ydCIsIkV4cG9ydCIsImV4cGFuZEV4cG9ydERlZmF1bHQiLCJFeHBvcnREZWZhdWx0IiwiZXhwYW5kRXhwb3J0RnJvbSIsImV4cGFuZEV4cG9ydEFsbEZyb20iLCJleHBhbmRFeHBvcnRTcGVjaWZpZXIiLCJleHBhbmRTdGF0aWNQcm9wZXJ0eU5hbWUiLCJleHBhbmREYXRhUHJvcGVydHkiLCJleHBhbmRPYmplY3RFeHByZXNzaW9uIiwiT2JqZWN0RXhwcmVzc2lvbiIsImV4cGFuZFZhcmlhYmxlRGVjbGFyYXRvciIsIlZhcmlhYmxlRGVjbGFyYXRvciIsImV4cGFuZFZhcmlhYmxlRGVjbGFyYXRpb24iLCJraW5kIiwiVmFyaWFibGVEZWNsYXJhdGlvbiIsImRlY2xhcmF0b3JzIiwiZCIsImV4cGFuZFBhcmVudGhlc2l6ZWRFeHByZXNzaW9uIiwiaW5uZXIiLCJFcnJvciIsImxvb2thaGVhZCIsInBlZWsiLCJlbmZvcmVzdEV4cHJlc3Npb24iLCJjcmVhdGVFcnJvciIsImV4cGFuZFVuYXJ5RXhwcmVzc2lvbiIsIlVuYXJ5RXhwcmVzc2lvbiIsIm9wZXJhdG9yIiwib3BlcmFuZCIsImV4cGFuZFVwZGF0ZUV4cHJlc3Npb24iLCJVcGRhdGVFeHByZXNzaW9uIiwiaXNQcmVmaXgiLCJleHBhbmRCaW5hcnlFeHByZXNzaW9uIiwiQmluYXJ5RXhwcmVzc2lvbiIsImV4cGFuZENvbmRpdGlvbmFsRXhwcmVzc2lvbiIsIkNvbmRpdGlvbmFsRXhwcmVzc2lvbiIsImV4cGFuZE5ld1RhcmdldEV4cHJlc3Npb24iLCJleHBhbmROZXdFeHByZXNzaW9uIiwiZW5mb3Jlc3RBcmd1bWVudExpc3QiLCJhcmciLCJOZXdFeHByZXNzaW9uIiwiZXhwYW5kU3VwZXIiLCJleHBhbmRDYWxsRXhwcmVzc2lvbkUiLCJleHBhbmRTcHJlYWRFbGVtZW50IiwiU3ByZWFkRWxlbWVudCIsImV4cGFuZEV4cHJlc3Npb25TdGF0ZW1lbnQiLCJjaGlsZCIsIkV4cHJlc3Npb25TdGF0ZW1lbnQiLCJleHBhbmRMYWJlbGVkU3RhdGVtZW50IiwiTGFiZWxlZFN0YXRlbWVudCIsInR5cGUiLCJwYXJhbXMiLCJzZWxmIiwiQ2xvbmVSZWR1Y2VyIiwicmVkdWNlQmluZGluZ0lkZW50aWZpZXIiLCJhZGRTY29wZSIsIm5ld0JpbmRpbmciLCJ0b1N0cmluZyIsImFkZCIsInNraXBEdXAiLCJCaW5kaW5nSWRlbnRpZmllciIsInNjb3BlUmVkdWNlciIsImNvbXBpbGVkQm9keSIsImRpcmVjdGl2ZXMiLCJ0YWtlV2hpbGUiLCJzIiwiRGlyZWN0aXZlIiwicmF3VmFsdWUiLCJGdW5jdGlvbkJvZHkiLCJHZXR0ZXIiLCJTZXR0ZXIiLCJwYXJhbSIsIk1ldGhvZCIsImlzR2VuZXJhdG9yIiwiQXJyb3dFeHByZXNzaW9uIiwiRnVuY3Rpb25FeHByZXNzaW9uIiwiRnVuY3Rpb25EZWNsYXJhdGlvbiIsImV4cGFuZE1ldGhvZCIsImV4cGFuZFNldHRlciIsImV4cGFuZEdldHRlciIsImV4cGFuZEZ1bmN0aW9uRGVjbGFyYXRpb25FIiwiZXhwYW5kRnVuY3Rpb25FeHByZXNzaW9uRSIsImV4cGFuZENvbXBvdW5kQXNzaWdubWVudEV4cHJlc3Npb24iLCJDb21wb3VuZEFzc2lnbm1lbnRFeHByZXNzaW9uIiwiZXhwYW5kQXNzaWdubWVudEV4cHJlc3Npb24iLCJBc3NpZ25tZW50RXhwcmVzc2lvbiIsImV4cGFuZEVtcHR5U3RhdGVtZW50IiwiZXhwYW5kTGl0ZXJhbEJvb2xlYW5FeHByZXNzaW9uIiwiZXhwYW5kTGl0ZXJhbE51bWVyaWNFeHByZXNzaW9uIiwiZXhwYW5kTGl0ZXJhbEluZmluaXR5RXhwcmVzc2lvbiIsImV4cGFuZElkZW50aWZpZXJFeHByZXNzaW9uIiwidHJhbnMiLCJnZXQiLCJyZXNvbHZlIiwiaWQiLCJleHBhbmRMaXRlcmFsTnVsbEV4cHJlc3Npb24iLCJleHBhbmRMaXRlcmFsU3RyaW5nRXhwcmVzc2lvbiIsImV4cGFuZExpdGVyYWxSZWdFeHBFeHByZXNzaW9uIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7SUFBa0JBLEM7O0FBQ2xCOztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7O0FBQ0E7Ozs7OztBQUdlLE1BQU1DLFlBQU4saUNBQXlDO0FBQ3REQyxjQUFZQyxPQUFaLEVBQXFCO0FBQ25CLFVBQU0sUUFBTixFQUFnQixJQUFoQjtBQUNBLFNBQUtBLE9BQUwsR0FBZUEsT0FBZjtBQUNEOztBQUVEQyxTQUFPQyxJQUFQLEVBQWE7QUFDWCxXQUFPLEtBQUtDLFFBQUwsQ0FBY0QsSUFBZCxDQUFQO0FBQ0Q7O0FBRURFLGtCQUFnQkYsSUFBaEIsRUFBc0I7QUFDcEIsV0FBT0EsSUFBUDtBQUNEOztBQUVERyxxQkFBbUJILElBQW5CLEVBQXlCO0FBQ3ZCLFdBQU9BLElBQVA7QUFDRDs7QUFFREksMkJBQXlCSixJQUF6QixFQUErQjtBQUM3QixXQUFPLElBQUlMLEVBQUVVLGtCQUFOLENBQXlCO0FBQzlCQyxXQUFLTixLQUFLTSxHQUFMLElBQVksSUFBWixHQUFtQixJQUFuQixHQUEwQixLQUFLUCxNQUFMLENBQVlDLEtBQUtNLEdBQWpCLENBREQ7QUFFOUJDLGdCQUFVUCxLQUFLTyxRQUFMLENBQWNDLE9BQWQ7QUFGb0IsS0FBekIsQ0FBUDtBQUlEOztBQUVEQyx1QkFBcUJULElBQXJCLEVBQTJCO0FBQ3pCLFdBQU8sSUFBSUwsRUFBRWUsY0FBTixDQUFxQjtBQUMxQkMsYUFBT1gsS0FBS1csS0FBTCxHQUFhWCxLQUFLVyxLQUFMLENBQVdDLEdBQVgsRUFBYixHQUFnQztBQURiLEtBQXJCLENBQVA7QUFHRDs7QUFFREMseUJBQXVCYixJQUF2QixFQUE2QjtBQUMzQixXQUFP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Q0FBZ0NqUSxJQUFoQyxFQUFzQztBQUNwQyxXQUFPQSxJQUFQO0FBQ0Q7O0FBRURrUSw2QkFBMkJsUSxJQUEzQixFQUFpQztBQUMvQixRQUFJbVEsUUFBUSxLQUFLclEsT0FBTCxDQUFhaUgsR0FBYixDQUFpQnFKLEdBQWpCLENBQXFCcFEsS0FBS3VFLElBQUwsQ0FBVThMLE9BQVYsQ0FBa0IsS0FBS3ZRLE9BQUwsQ0FBYWdILEtBQS9CLENBQXJCLENBQVo7QUFDQSxRQUFJcUosS0FBSixFQUFXO0FBQ1QsYUFBTyxJQUFJeFEsRUFBRTZGLG9CQUFOLENBQTJCO0FBQ2hDakIsY0FBTTRMLE1BQU1HO0FBRG9CLE9BQTNCLENBQVA7QUFHRDtBQUNELFdBQU90USxJQUFQO0FBQ0Q7O0FBRUR1USw4QkFBNEJ2USxJQUE1QixFQUFrQztBQUNoQyxXQUFPQSxJQUFQO0FBQ0Q7O0FBRUR3USxnQ0FBOEJ4USxJQUE5QixFQUFvQztBQUNsQyxXQUFPQSxJQUFQO0FBQ0Q7O0FBRUR5USxnQ0FBOEJ6USxJQUE5QixFQUFvQztBQUNsQyxXQUFPQSxJQUFQO0FBQ0Q7QUF2c0JxRDtrQkFBbkNKLFkiLCJmaWxlIjoidGVybS1leHBhbmRlci5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IExpc3QgfSBmcm9tICdpbW11dGFibGUnO1xuaW1wb3J0IHsgaXNFeHByZXNzaW9uU3RhdGVtZW50LCBpc0xpdGVyYWxTdHJpbmdFeHByZXNzaW9uIH0gZnJvbSAnLi90ZXJtcyc7XG5pbXBvcnQgVGVybSwgKiBhcyBUIGZyb20gJ3N3ZWV0LXNwZWMnO1xuaW1wb3J0IHsgZnJlc2hTY29wZSB9IGZyb20gJy4vc2NvcGUnO1xuaW1wb3J0IENvbXBpbGVyIGZyb20gJy4vY29tcGlsZXInO1xuaW1wb3J0IHsgQUxMX1BIQVNFUyB9IGZyb20gJy4vc3ludGF4JztcbmltcG9ydCB7IEVuZm9yZXN0ZXIgfSBmcm9tICcuL2VuZm9yZXN0ZXInO1xuaW1wb3J0IHsgcHJvY2Vzc1RlbXBsYXRlIH0gZnJvbSAnLi90ZW1wbGF0ZS1wcm9jZXNzb3InO1xuaW1wb3J0IEFTVERpc3BhdGNoZXIgZnJvbSAnLi9hc3QtZGlzcGF0Y2hlcic7XG5pbXBvcnQgU2NvcGVSZWR1Y2VyIGZyb20gJy4vc2NvcGUtcmVkdWNlcic7XG5pbXBvcnQgeyBnZW5zeW0gfSBmcm9tICcuL3N5bWJvbCc7XG5pbXBvcnQgeyBWYXJCaW5kaW5nVHJhbnNmb3JtIH0gZnJvbSAnLi90cmFuc2Zvcm1zJztcbmltcG9ydCBTeW50YXggZnJvbSAnLi9zeW50YXgnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUZXJtRXhwYW5kZXIgZXh0ZW5kcyBBU1REaXNwYXRjaGVyIHtcbiAgY29uc3RydWN0b3IoY29udGV4dCkge1xuICAgIHN1cGVyKCdleHBhbmQnLCB0cnVlKTtcbiAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICB9XG5cbiAgZXhwYW5kKHRlcm0pIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaCh0ZXJtKTtcbiAgfVxuXG4gIGV4cGFuZFJhd1N5bnRheCh0ZXJtKSB7XG4gICAgcmV0dXJuIHRlcm07XG4gIH1cblxuICBleHBhbmRSYXdEZWxpbWl0ZXIodGVybSkge1xuICAgIHJldHVybiB0ZXJtO1xuICB9XG5cbiAgZXhwYW5kVGVtcGxhdGVFeHByZXNzaW9uKHRlcm0pIHtcbiAgICByZXR1cm4gbmV3IFQuVGVtcGxhdGVFeHByZXNzaW9uKHtcbiAgICAgIHRhZzogdGVybS50YWcgPT0gbnVsbCA/IG51bGwgOiB0aGlzLmV4cGFuZCh0ZXJtLnRhZyksXG4gICAgICBlbGVtZW50czogdGVybS5lbGVtZW50cy50b0FycmF5KCksXG4gICAgfSk7XG4gIH1cblxuICBleHBhbmRCcmVha1N0YXRlbWVudCh0ZXJtKSB7XG4gICAgcmV0dXJuIG5ldyBULkJyZWFrU3RhdGVtZW50KHtcbiAgICAgIGxhYmVsOiB0ZXJtLmxhYmVsID8gdGVybS5sYWJlbC52YWwoKSA6IG51bGwsXG4gICAgfSk7XG4gIH1cblxuICBleHBhbmREb1doaWxlU3RhdGVtZW50KHRlcm0pIHtcbiAgICByZXR1cm4gbmV3IFQuRG9XaGlsZVN0YXRlbWVudCh7XG4gICAgICBib2R5OiB0aGlzLmV4cGFuZCh0ZXJtLmJvZHkpLFxuICAgICAgdGVzdDogdGhpcy5leHBhbmQodGVybS50ZXN0KSxcbiAgICB9KTtcbiAgfVxuXG4gIGV4cGFuZFdpdGhTdGF0ZW1lbnQodGVybSkge1xuICAgIHJldHVybiBuZXcgVC5XaXRoU3RhdGVtZW50KHtcbiAgICAgIGJvZHk6IHRoaXMuZXhwYW5kKHRlcm0uYm9keSksXG4gICAgICBvYmplY3Q6IHRoaXMuZXhwYW5kKHRlcm0ub2JqZWN0KSxcbiAgICB9KTtcbiAgfVxuXG4gIGV4cGFuZERlYnVnZ2VyU3RhdGVtZW50KHRlcm0pIHtcbiAgICByZXR1cm4gdGVybTtcbiAgfVxuXG4gIGV4cGFuZENvbnRpbnVlU3RhdGVtZW50KHRlcm0pIHtcbiAgICByZXR1cm4gbmV3IFQuQ29udGludWVTdGF0ZW1lbnQoe1xuICAgICAgbGFiZWw6IHRlcm0ubGFiZWwgPyB0ZXJtLmxhYmVsLnZhbCgpIDogbnVsbCxcbiAgICB9KTtcbiAgfVxuXG4gIGV4cGFuZFN3aXRjaFN0YXRlbWVudFdpdGhEZWZhdWx0KHRlcm0pIHtcbiAgICByZXR1cm4gbmV3IFQuU3dpdGNoU3RhdGVtZW50V2l0aERlZmF1bHQoe1xuICAgICAgZGlzY3JpbWluYW50OiB0aGlzLmV4cGFuZCh0ZXJtLmRpc2NyaW1pbmFudCksXG4gICAgICBwcmVEZWZhdWx0Q2FzZXM6IHRlcm0ucHJlRGVmYXVsdENhc2VzLm1hcChjID0+IHRoaXMuZXhwYW5kKGMpKS50b0FycmF5KCksXG4gICAgICBkZWZhdWx0Q2FzZTogdGhpcy5leHBhbmQodGVybS5kZWZhdWx0Q2FzZSksXG4gICAgICBwb3N0RGVmYXVsdENhc2VzOiB0ZXJtLnBvc3REZWZhdWx0Q2FzZXNcbiAgICAgICAgLm1hcChjID0+IHRoaXMuZXhwYW5kKGMpKVxuICAgICAgICAudG9BcnJheSgpLFxuICAgIH0pO1xuICB9XG5cbiAgZXhwYW5kQ29tcHV0ZWRNZW1iZXJFeHByZXNzaW9uKHRlcm0pIHtcbiAgICByZXR1cm4gbmV3IFQuQ29tcHV0ZWRNZW1iZXJFeHByZXNzaW9uKHtcbiAgICAgIG9iamVjdDogdGhpcy5leHBhbmQodGVybS5vYmplY3QpLFxuICAgICAgZXhwcmVzc2lvbjogdGhpcy5leHBhbmQodGVybS5leHByZXNzaW9uKSxcbiAgICB9KTtcbiAgfVxuXG4gIGV4cGFuZFN3aXRjaFN0YXRlbWVudCh0ZXJtKSB7XG4gICAgcmV0dXJuIG5ldyBULlN3aXRjaFN0YXRlbWVudCh7XG4gICAgICBkaXNjcmltaW5hbnQ6IHRoaXMuZXhwYW5kKHRlcm0uZGlzY3JpbWluYW50KSxcbiAgICAgIGNhc2VzOiB0ZXJtLmNhc2VzLm1hcChjID0+IHRoaXMuZXhwYW5kKGMpKS50b0FycmF5KCksXG4gICAgfSk7XG4gIH1cblxuICBleHBhbmRGb3JtYWxQYXJhbWV0ZXJzKHRlcm0pIHtcbiAgICBsZXQgcmVzdCA9IHRlcm0ucmVzdCA9PSBudWxsID8gbnVsbCA6IHRoaXMuZXhwYW5kKHRlcm0ucmVzdCk7XG4gICAgcmV0dXJuIG5ldyBULkZvcm1hbFBhcmFtZXRlcnMoe1xuICAgICAgaXRlbXM6IHRlcm0uaXRlbXMubWFwKGkgPT4gdGhpcy5leHBhbmQoaSkpLFxuICAgICAgcmVzdCxcbiAgICB9KTtcbiAgfVxuXG4gIGV4cGFuZEFycm93RXhwcmVzc2lvbkUodGVybSkge1xuICAgIHJldHVybiB0aGlzLmRvRnVuY3Rpb25FeHBhbnNpb24odGVybSwgJ0Fycm93RXhwcmVzc2lvbicpO1xuICB9XG5cbiAgZXhwYW5kQXJyb3dFeHByZXNzaW9uKHRlcm0pIHtcbiAgICByZXR1cm4gdGhpcy5kb0Z1bmN0aW9uRXhwYW5zaW9uKHRlcm0sICdBcnJvd0V4cHJlc3Npb24nKTtcbiAgfVxuXG4gIGV4cGFuZFN3aXRjaERlZmF1bHQodGVybSkge1xuICAgIHJldHVybiBuZXcgVC5Td2l0Y2hEZWZhdWx0KHtcbiAgICAgIGNvbnNlcXVlbnQ6IHRlcm0uY29uc2VxdWVudC5tYXAoYyA9PiB0aGlzLmV4cGFuZChjKSkudG9BcnJheSgpLFxuICAgIH0pO1xuICB9XG5cbiAgZXhwYW5kU3dpdGNoQ2FzZSh0ZXJtKSB7XG4gICAgcmV0dXJuIG5ldyBULlN3aXRjaENhc2Uoe1xuICAgICAgdGVzdDogdGhpcy5leHBhbmQodGVybS50ZXN0KSxcbiAgICAgIGNvbnNlcXVlbnQ6IHRlcm0uY29uc2VxdWVudC5tYXAoYyA9PiB0aGlzLmV4cGFuZChjKSkudG9BcnJheSgpLFxuICAgIH0pO1xuICB9XG5cbiAgZXhwYW5kRm9ySW5TdGF0ZW1lbnQodGVybSkge1xuICAgIHJldHVybiBuZXcgVC5Gb3JJblN0YXRlbWVudCh7XG4gICAgICBsZWZ0OiB0aGlzLmV4cGFuZCh0ZXJtLmxlZnQpLFxuICAgICAgcmlnaHQ6IHRoaXMuZXhwYW5kKHRlcm0ucmlnaHQpLFxuICAgICAgYm9keTogdGhpcy5leHBhbmQodGVybS5ib2R5KSxcbiAgICB9KTtcbiAgfVxuXG4gIGV4cGFuZFRyeUNhdGNoU3RhdGVtZW50KHRlcm0pIHtcbiAgICByZXR1cm4gbmV3IFQuVHJ5Q2F0Y2hTdGF0ZW1lbnQoe1xuICAgICAgYm9keTogdGhpcy5leHBhbmQodGVybS5ib2R5KSxcbiAgICAgIGNhdGNoQ2xhdXNlOiB0aGlzLmV4cGFuZCh0ZXJtLmNhdGNoQ2xhdXNlKSxcbiAgICB9KTtcbiAgfVxuXG4gIGV4cGFuZFRyeUZpbmFsbHlTdGF0ZW1lbnQodGVybSkge1xuICAgIGxldCBjYXRjaENsYXVzZSA9IHRlcm0uY2F0Y2hDbGF1c2UgPT0gbnVsbFxuICAgICAgPyBudWxsXG4gICAgICA6IHRoaXMuZXhwYW5kKHRlcm0uY2F0Y2hDbGF1c2UpO1xuICAgIHJldHVybiBuZXcgVC5UcnlGaW5hbGx5U3RhdGVtZW50KHtcbiAgICAgIGJvZHk6IHRoaXMuZXhwYW5kKHRlcm0uYm9keSksXG4gICAgICBjYXRjaENsYXVzZSxcbiAgICAgIGZpbmFsaXplcjogdGhpcy5leHBhbmQodGVybS5maW5hbGl6ZXIpLFxuICAgIH0pO1xuICB9XG5cbiAgZXhwYW5kQ2F0Y2hDbGF1c2UodGVybSkge1xuICAgIHJldHVybiBuZXcgVC5DYXRjaENsYXVzZSh7XG4gICAgICBiaW5kaW5nOiB0aGlzLmV4cGFuZCh0ZXJtLmJpbmRpbmcpLFxuICAgICAgYm9keTogdGhpcy5leHBhbmQodGVybS5ib2R5KSxcbiAgICB9KTtcbiAgfVxuXG4gIGV4cGFuZFRocm93U3RhdGVtZW50KHRlcm0pIHtcbiAgICByZXR1cm4gbmV3IFQuVGhyb3dTdGF0ZW1lbnQoe1xuICAgICAgZXhwcmVzc2lvbjogdGhpcy5leHBhbmQodGVybS5leHByZXNzaW9uKSxcbiAgICB9KTtcbiAgfVxuXG4gIGV4cGFuZEZvck9mU3RhdGVtZW50KHRlcm0pIHtcbiAgICByZXR1cm4gbmV3IFQuRm9yT2ZTdGF0ZW1lbnQoe1xuICAgICAgbGVmdDogdGhpcy5leHBhbmQodGVybS5sZWZ0KSxcbiAgICAgIHJpZ2h0OiB0aGlzLmV4cGFuZCh0ZXJtLnJpZ2h0KSxcbiAgICAgIGJvZHk6IHRoaXMuZXhwYW5kKHRlcm0uYm9keSksXG4gICAgfSk7XG4gIH1cblxuICBleHBhbmRCaW5kaW5nSWRlbnRpZmllcih0ZXJtKSB7XG4gICAgcmV0dXJuIHRlcm07XG4gIH1cblxuICBleHBhbmRCaW5kaW5nUHJvcGVydHlJZGVudGlmaWVyKHRlcm0pIHtcbiAgICByZXR1cm4gdGVybTtcbiAgfVxuICBleHBhbmRCaW5kaW5nUHJvcGVydHlQcm9wZXJ0eSh0ZXJtKSB7XG4gICAgcmV0dXJuIG5ldyBULkJpbmRpbmdQcm9wZXJ0eVByb3BlcnR5KHtcbiAgICAgIG5hbWU6IHRoaXMuZXhwYW5kKHRlcm0ubmFtZSksXG4gICAgICBiaW5kaW5nOiB0aGlzLmV4cGFuZCh0ZXJtLmJpbmRpbmcpLFxuICAgIH0pO1xuICB9XG5cbiAgZXhwYW5kQ29tcHV0ZWRQcm9wZXJ0eU5hbWUodGVybSkge1xuICAgIHJldHVybiBuZXcgVC5Db21wdXRlZFByb3BlcnR5TmFtZSh7XG4gICAgICBleHByZXNzaW9uOiB0aGlzLmV4cGFuZCh0ZXJtLmV4cHJlc3Npb24pLFxuICAgIH0pO1xuICB9XG5cbiAgZXhwYW5kT2JqZWN0QmluZGluZyh0ZXJtKSB7XG4gICAgcmV0dXJuIG5ldyBULk9iamVjdEJpbmRpbmcoe1xuICAgICAgcHJvcGVydGllczogdGVybS5wcm9wZXJ0aWVzLm1hcCh0ID0+IHRoaXMuZXhwYW5kKHQpKS50b0FycmF5KCksXG4gICAgfSk7XG4gIH1cblxuICBleHBhbmRBcnJheUJpbmRpbmcodGVybSkge1xuICAgIGxldCByZXN0RWxlbWVudCA9IHRlcm0ucmVzdEVsZW1lbnQgPT0gbnVsbFxuICAgICAgPyBudWxsXG4gICAgICA6IHRoaXMuZXhwYW5kKHRlcm0ucmVzdEVsZW1lbnQpO1xuICAgIHJldHVybiBuZXcgVC5BcnJheUJpbmRpbmcoe1xuICAgICAgZWxlbWVudHM6IHRlcm0uZWxlbWVudHNcbiAgICAgICAgLm1hcCh0ID0+IHQgPT0gbnVsbCA/IG51bGwgOiB0aGlzLmV4cGFuZCh0KSlcbiAgICAgICAgLnRvQXJyYXkoKSxcbiAgICAgIHJlc3RFbGVtZW50LFxuICAgIH0pO1xuICB9XG5cbiAgZXhwYW5kQmluZGluZ1dpdGhEZWZhdWx0KHRlcm0pIHtcbiAgICByZXR1cm4gbmV3IFQuQmluZGluZ1dpdGhEZWZhdWx0KHtcbiAgICAgIGJpbmRpbmc6IHRoaXMuZXhwYW5kKHRlcm0uYmluZGluZyksXG4gICAgICBpbml0OiB0aGlzLmV4cGFuZCh0ZXJtLmluaXQpLFxuICAgIH0pO1xuICB9XG5cbiAgZXhwYW5kU2hvcnRoYW5kUHJvcGVydHkodGVybSkge1xuICAgIC8vIGJlY2F1c2UgaHlnaWVuZSwgc2hvcnRoYW5kIHByb3BlcnRpZXMgbXVzdCB0dXJuIGludG8gRGF0YVByb3BlcnRpZXNcbiAgICByZXR1cm4gbmV3IFQuRGF0YVByb3BlcnR5KHtcbiAgICAgIG5hbWU6IG5ldyBULlN0YXRpY1Byb3BlcnR5TmFtZSh7XG4gICAgICAgIHZhbHVlOiB0ZXJtLm5hbWUsXG4gICAgICB9KSxcbiAgICAgIGV4cHJlc3Npb246IG5ldyBULklkZW50aWZpZXJFeHByZXNzaW9uKHtcbiAgICAgICAgbmFtZTogdGVybS5uYW1lLFxuICAgICAgfSksXG4gICAgfSk7XG4gIH1cblxuICBleHBhbmRGb3JTdGF0ZW1lbnQodGVybSkge1xuICAgIGxldCBpbml0ID0gdGVybS5pbml0ID09IG51bGwgPyBudWxsIDogdGhpcy5leHBhbmQodGVybS5pbml0KTtcbiAgICBsZXQgdGVzdCA9IHRlcm0udGVzdCA9PSBudWxsID8gbnVsbCA6IHRoaXMuZXhwYW5kKHRlcm0udGVzdCk7XG4gICAgbGV0IHVwZGF0ZSA9IHRlcm0udXBkYXRlID09IG51bGwgPyBudWxsIDogdGhpcy5leHBhbmQodGVybS51cGRhdGUpO1xuICAgIGxldCBib2R5ID0gdGhpcy5leHBhbmQodGVybS5ib2R5KTtcbiAgICByZXR1cm4gbmV3IFQuRm9yU3RhdGVtZW50KHsgaW5pdCwgdGVzdCwgdXBkYXRlLCBib2R5IH0pO1xuICB9XG5cbiAgZXhwYW5kWWllbGRFeHByZXNzaW9uKHRlcm0pIHtcbiAgICBsZXQgZXhwciA9IHRlcm0uZXhwcmVzc2lvbiA9PSBudWxsID8gbnVsbCA6IHRoaXMuZXhwYW5kKHRlcm0uZXhwcmVzc2lvbik7XG4gICAgcmV0dXJuIG5ldyBULllpZWxkRXhwcmVzc2lvbih7XG4gICAgICBleHByZXNzaW9uOiBleHByLFxuICAgIH0pO1xuICB9XG5cbiAgZXhwYW5kWWllbGRHZW5lcmF0b3JFeHByZXNzaW9uKHRlcm0pIHtcbiAgICBsZXQgZXhwciA9IHRlcm0uZXhwcmVzc2lvbiA9PSBudWxsID8gbnVsbCA6IHRoaXMuZXhwYW5kKHRlcm0uZXhwcmVzc2lvbik7XG4gICAgcmV0dXJuIG5ldyBULllpZWxkR2VuZXJhdG9yRXhwcmVzc2lvbih7XG4gICAgICBleHByZXNzaW9uOiBleHByLFxuICAgIH0pO1xuICB9XG5cbiAgZXhwYW5kV2hpbGVTdGF0ZW1lbnQodGVybSkge1xuICAgIHJldHVybiBuZXcgVC5XaGlsZVN0YXRlbWVudCh7XG4gICAgICB0ZXN0OiB0aGlzLmV4cGFuZCh0ZXJtLnRlc3QpLFxuICAgICAgYm9keTogdGhpcy5leHBhbmQodGVybS5ib2R5KSxcbiAgICB9KTtcbiAgfVxuXG4gIGV4cGFuZElmU3RhdGVtZW50KHRlcm0pIHtcbiAgICBsZXQgY29uc2VxdWVudCA9IHRlcm0uY29uc2VxdWVudCA9PSBudWxsXG4gICAgICA/IG51bGxcbiAgICAgIDogdGhpcy5leHBhbmQodGVybS5jb25zZXF1ZW50KTtcbiAgICBsZXQgYWx0ZXJuYXRlID0gdGVybS5hbHRlcm5hdGUgPT0gbnVsbCA/IG51bGwgOiB0aGlzLmV4cGFuZCh0ZXJtLmFsdGVybmF0ZSk7XG4gICAgcmV0dXJuIG5ldyBULklmU3RhdGVtZW50KHtcbiAgICAgIHRlc3Q6IHRoaXMuZXhwYW5kKHRlcm0udGVzdCksXG4gICAgICBjb25zZXF1ZW50OiBjb25zZXF1ZW50LFxuICAgICAgYWx0ZXJuYXRlOiBhbHRlcm5hdGUsXG4gICAgfSk7XG4gIH1cblxuICBleHBhbmRCbG9ja1N0YXRlbWVudCh0ZXJtKSB7XG4gICAgcmV0dXJuIG5ldyBULkJsb2NrU3RhdGVtZW50KHtcbiAgICAgIGJsb2NrOiB0aGlzLmV4cGFuZCh0ZXJtLmJsb2NrKSxcbiAgICB9KTtcbiAgfVxuXG4gIGV4cGFuZEJsb2NrKHRlcm0pIHtcbiAgICBsZXQgc2NvcGUgPSBmcmVzaFNjb3BlKCdibG9jaycpO1xuICAgIHRoaXMuY29udGV4dC5jdXJyZW50U2NvcGUucHVzaChzY29wZSk7XG4gICAgbGV0IGNvbXBpbGVyID0gbmV3IENvbXBpbGVyKFxuICAgICAgdGhpcy5jb250ZXh0LnBoYXNlLFxuICAgICAgdGhpcy5jb250ZXh0LmVudixcbiAgICAgIHRoaXMuY29udGV4dC5zdG9yZSxcbiAgICAgIHRoaXMuY29udGV4dCxcbiAgICApO1xuXG4gICAgbGV0IG1hcmtlZEJvZHksIGJvZHlUZXJtO1xuICAgIG1hcmtlZEJvZHkgPSB0ZXJtLnN0YXRlbWVudHMubWFwKGIgPT5cbiAgICAgIGIucmVkdWNlKFxuICAgICAgICBuZXcgU2NvcGVSZWR1Y2VyKFxuICAgICAgICAgIFt7IHNjb3BlLCBwaGFzZTogQUxMX1BIQVNFUywgZmxpcDogZmFsc2UgfV0sXG4gICAgICAgICAgdGhpcy5jb250ZXh0LmJpbmRpbmdzLFxuICAgICAgICApLFxuICAgICAgKSk7XG4gICAgYm9keVRlcm0gPSBuZXcgVC5CbG9jayh7XG4gICAgICBzdGF0ZW1lbnRzOiBjb21waWxlci5jb21waWxlKG1hcmtlZEJvZHkpLFxuICAgIH0pO1xuICAgIHRoaXMuY29udGV4dC5jdXJyZW50U2NvcGUucG9wKCk7XG4gICAgcmV0dXJuIGJvZHlUZXJtO1xuICB9XG5cbiAgZXhwYW5kVmFyaWFibGVEZWNsYXJhdGlvblN0YXRlbWVudCh0ZXJtKSB7XG4gICAgcmV0dXJuIG5ldyBULlZhcmlhYmxlRGVjbGFyYXRpb25TdGF0ZW1lbnQoe1xuICAgICAgZGVjbGFyYXRpb246IHRoaXMuZXhwYW5kKHRlcm0uZGVjbGFyYXRpb24pLFxuICAgIH0pO1xuICB9XG4gIGV4cGFuZFJldHVyblN0YXRlbWVudCh0ZXJtKSB7XG4gICAgaWYgKHRlcm0uZXhwcmVzc2lvbiA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gdGVybTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBULlJldHVyblN0YXRlbWVudCh7XG4gICAgICBleHByZXNzaW9uOiB0aGlzLmV4cGFuZCh0ZXJtLmV4cHJlc3Npb24pLFxuICAgIH0pO1xuICB9XG5cbiAgZXhwYW5kQ2xhc3NEZWNsYXJhdGlvbih0ZXJtKSB7XG4gICAgcmV0dXJuIG5ldyBULkNsYXNzRGVjbGFyYXRpb24oe1xuICAgICAgbmFtZTogdGVybS5uYW1lID09IG51bGwgPyBudWxsIDogdGhpcy5leHBhbmQodGVybS5uYW1lKSxcbiAgICAgIHN1cGVyOiB0ZXJtLnN1cGVyID09IG51bGwgPyBudWxsIDogdGhpcy5leHBhbmQodGVybS5zdXBlciksXG4gICAgICBlbGVtZW50czogdGVybS5lbGVtZW50cy5tYXAoZWwgPT4gdGhpcy5leHBhbmQoZWwpKS50b0FycmF5KCksXG4gICAgfSk7XG4gIH1cblxuICBleHBhbmRDbGFzc0V4cHJlc3Npb24odGVybSkge1xuICAgIHJldHVybiBuZXcgVC5DbGFzc0V4cHJlc3Npb24oe1xuICAgICAgbmFtZTogdGVybS5uYW1lID09IG51bGwgPyBudWxsIDogdGhpcy5leHBhbmQodGVybS5uYW1lKSxcbiAgICAgIHN1cGVyOiB0ZXJtLnN1cGVyID09IG51bGwgPyBudWxsIDogdGhpcy5leHBhbmQodGVybS5zdXBlciksXG4gICAgICBlbGVtZW50czogdGVybS5lbGVtZW50cy5tYXAoZWwgPT4gdGhpcy5leHBhbmQoZWwpKS50b0FycmF5KCksXG4gICAgfSk7XG4gIH1cblxuICBleHBhbmRDbGFzc0VsZW1lbnQodGVybSkge1xuICAgIHJldHVybiBuZXcgVC5DbGFzc0VsZW1lbnQoe1xuICAgICAgaXNTdGF0aWM6IHRlcm0uaXNTdGF0aWMsXG4gICAgICBtZXRob2Q6IHRoaXMuZXhwYW5kKHRlcm0ubWV0aG9kKSxcbiAgICB9KTtcbiAgfVxuXG4gIGV4cGFuZFRoaXNFeHByZXNzaW9uKHRlcm0pIHtcbiAgICByZXR1cm4gdGVybTtcbiAgfVxuXG4gIGV4cGFuZFN5bnRheFRlbXBsYXRlKHRlcm0pIHtcbiAgICBsZXQgciA9IHByb2Nlc3NUZW1wbGF0ZSh0ZXJtLnRlbXBsYXRlLnNsaWNlKDEsIHRlcm0udGVtcGxhdGUuc2l6ZSAtIDEpKTtcbiAgICBsZXQgaWRlbnQgPSB0aGlzLmNvbnRleHQuZ2V0VGVtcGxhdGVJZGVudGlmaWVyKCk7XG4gICAgdGhpcy5jb250ZXh0LnRlbXBsYXRlTWFwLnNldChpZGVudCwgci50ZW1wbGF0ZSk7XG4gICAgbGV0IG5hbWUgPSBTeW50YXguZnJvbUlkZW50aWZpZXIoXG4gICAgICAnc3ludGF4VGVtcGxhdGUnLFxuICAgICAgdGVybS50ZW1wbGF0ZS5maXJzdCgpLnZhbHVlLFxuICAgICk7XG4gICAgbGV0IGNhbGxlZSA9IG5ldyBULklkZW50aWZpZXJFeHByZXNzaW9uKHtcbiAgICAgIG5hbWU6IG5hbWUsXG4gICAgfSk7XG5cbiAgICBsZXQgZXhwYW5kZWRJbnRlcnBzID0gci5pbnRlcnAubWFwKGkgPT4ge1xuICAgICAgbGV0IGVuZiA9IG5ldyBFbmZvcmVzdGVyKGksIExpc3QoKSwgdGhpcy5jb250ZXh0KTtcbiAgICAgIHJldHVybiB0aGlzLmV4cGFuZChlbmYuZW5mb3Jlc3QoJ2V4cHJlc3Npb24nKSk7XG4gICAgfSk7XG5cbiAgICBsZXQgYXJncyA9IExpc3Qub2YobmV3IFQuTGl0ZXJhbE51bWVyaWNFeHByZXNzaW9uKHsgdmFsdWU6IGlkZW50IH0pKS5jb25jYXQoXG4gICAgICBleHBhbmRlZEludGVycHMsXG4gICAgKTtcblxuICAgIHJldHVybiBuZXcgVC5DYWxsRXhwcmVzc2lvbih7XG4gICAgICBjYWxsZWUsXG4gICAgICBhcmd1bWVudHM6IGFyZ3MsXG4gICAgfSk7XG4gIH1cblxuICBleHBhbmRTdGF0aWNNZW1iZXJFeHByZXNzaW9uKHRlcm0pIHtcbiAgICByZXR1cm4gbmV3IFQuU3RhdGljTWVtYmVyRXhwcmVzc2lvbih7XG4gICAgICBvYmplY3Q6IHRoaXMuZXhwYW5kKHRlcm0ub2JqZWN0KSxcbiAgICAgIHByb3BlcnR5OiB0ZXJtLnByb3BlcnR5LFxuICAgIH0pO1xuICB9XG5cbiAgZXhwYW5kQXJyYXlFeHByZXNzaW9uKHRlcm0pIHtcbiAgICByZXR1cm4gbmV3IFQuQXJyYXlFeHByZXNzaW9uKHtcbiAgICAgIGVsZW1lbnRzOiB0ZXJtLmVsZW1lbnRzLm1hcCh0ID0+IHQgPT0gbnVsbCA/IHQgOiB0aGlzLmV4cGFuZCh0KSksXG4gICAgfSk7XG4gIH1cblxuICBleHBhbmRJbXBvcnQodGVybSkge1xuICAgIHJldHVybiB0ZXJtO1xuICB9XG5cbiAgZXhwYW5kSW1wb3J0TmFtZXNwYWNlKHRlcm0pIHtcbiAgICByZXR1cm4gdGVybTtcbiAgfVxuXG4gIGV4cGFuZEV4cG9ydCh0ZXJtKSB7XG4gICAgcmV0dXJuIG5ldyBULkV4cG9ydCh7XG4gICAgICBkZWNsYXJhdGlvbjogdGhpcy5leHBhbmQodGVybS5kZWNsYXJhdGlvbiksXG4gICAgfSk7XG4gIH1cblxuICBleHBhbmRFeHBvcnREZWZhdWx0KHRlcm0pIHtcbiAgICByZXR1cm4gbmV3IFQuRXhwb3J0RGVmYXVsdCh7XG4gICAgICBib2R5OiB0aGlzLmV4cGFuZCh0ZXJtLmJvZHkpLFxuICAgIH0pO1xuICB9XG5cbiAgZXhwYW5kRXhwb3J0RnJvbSh0ZXJtKSB7XG4gICAgcmV0dXJuIHRlcm07XG4gIH1cblxuICBleHBhbmRFeHBvcnRBbGxGcm9tKHRlcm0pIHtcbiAgICByZXR1cm4gdGVybTtcbiAgfVxuXG4gIGV4cGFuZEV4cG9ydFNwZWNpZmllcih0ZXJtKSB7XG4gICAgcmV0dXJuIHRlcm07XG4gIH1cblxuICBleHBhbmRTdGF0aWNQcm9wZXJ0eU5hbWUodGVybSkge1xuICAgIHJldHVybiB0ZXJtO1xuICB9XG5cbiAgZXhwYW5kRGF0YVByb3BlcnR5KHRlcm0pIHtcbiAgICByZXR1cm4gbmV3IFQuRGF0YVByb3BlcnR5KHtcbiAgICAgIG5hbWU6IHRoaXMuZXhwYW5kKHRlcm0ubmFtZSksXG4gICAgICBleHByZXNzaW9uOiB0aGlzLmV4cGFuZCh0ZXJtLmV4cHJlc3Npb24pLFxuICAgIH0pO1xuICB9XG5cbiAgZXhwYW5kT2JqZWN0RXhwcmVzc2lvbih0ZXJtKSB7XG4gICAgcmV0dXJuIG5ldyBULk9iamVjdEV4cHJlc3Npb24oe1xuICAgICAgcHJvcGVydGllczogdGVybS5wcm9wZXJ0aWVzLm1hcCh0ID0+IHRoaXMuZXhwYW5kKHQpKSxcbiAgICB9KTtcbiAgfVxuXG4gIGV4cGFuZFZhcmlhYmxlRGVjbGFyYXRvcih0ZXJtKSB7XG4gICAgbGV0IGluaXQgPSB0ZXJtLmluaXQgPT0gbnVsbCA/IG51bGwgOiB0aGlzLmV4cGFuZCh0ZXJtLmluaXQpO1xuICAgIHJldHVybiBuZXcgVC5WYXJpYWJsZURlY2xhcmF0b3Ioe1xuICAgICAgYmluZGluZzogdGhpcy5leHBhbmQodGVybS5iaW5kaW5nKSxcbiAgICAgIGluaXQ6IGluaXQsXG4gICAgfSk7XG4gIH1cblxuICBleHBhbmRWYXJpYWJsZURlY2xhcmF0aW9uKHRlcm0pIHtcbiAgICBpZiAoXG4gICAgICB0ZXJtLmtpbmQgPT09ICdzeW50YXgnIHx8XG4gICAgICB0ZXJtLmtpbmQgPT09ICdzeW50YXhyZWMnIHx8XG4gICAgICB0ZXJtLmtpbmQgPT09ICdvcGVyYXRvcidcbiAgICApIHtcbiAgICAgIHJldHVybiB0ZXJtO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFQuVmFyaWFibGVEZWNsYXJhdGlvbih7XG4gICAgICBraW5kOiB0ZXJtLmtpbmQsXG4gICAgICBkZWNsYXJhdG9yczogdGVybS5kZWNsYXJhdG9ycy5tYXAoZCA9PiB0aGlzLmV4cGFuZChkKSksXG4gICAgfSk7XG4gIH1cblxuICBleHBhbmRQYXJlbnRoZXNpemVkRXhwcmVzc2lvbih0ZXJtKSB7XG4gICAgaWYgKHRlcm0uaW5uZXIuc2l6ZSA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bmV4cGVjdGVkIGVuZCBvZiBpbnB1dCcpO1xuICAgIH1cbiAgICBsZXQgZW5mID0gbmV3IEVuZm9yZXN0ZXIodGVybS5pbm5lciwgTGlzdCgpLCB0aGlzLmNvbnRleHQpO1xuICAgIGxldCBsb29rYWhlYWQgPSBlbmYucGVlaygpO1xuICAgIGxldCB0ID0gZW5mLmVuZm9yZXN0RXhwcmVzc2lvbigpO1xuICAgIGlmICh0ID09IG51bGwgfHwgZW5mLnJlc3Quc2l6ZSA+IDApIHtcbiAgICAgIGlmIChlbmYucmVzdC5zaXplID09PSAwKSB7XG4gICAgICAgIHRocm93IGVuZi5jcmVhdGVFcnJvcignKScsICd1bmV4cGVjdGVkIHRva2VuJyk7XG4gICAgICB9XG4gICAgICB0aHJvdyBlbmYuY3JlYXRlRXJyb3IobG9va2FoZWFkLCAndW5leHBlY3RlZCBzeW50YXgnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZXhwYW5kKHQpO1xuICB9XG5cbiAgZXhwYW5kVW5hcnlFeHByZXNzaW9uKHRlcm0pIHtcbiAgICByZXR1cm4gbmV3IFQuVW5hcnlFeHByZXNzaW9uKHtcbiAgICAgIG9wZXJhdG9yOiB0ZXJtLm9wZXJhdG9yLFxuICAgICAgb3BlcmFuZDogdGhpcy5leHBhbmQodGVybS5vcGVyYW5kKSxcbiAgICB9KTtcbiAgfVxuXG4gIGV4cGFuZFVwZGF0ZUV4cHJlc3Npb24odGVybSkge1xuICAgIHJldHVybiBuZXcgVC5VcGRhdGVFeHByZXNzaW9uKHtcbiAgICAgIGlzUHJlZml4OiB0ZXJtLmlzUHJlZml4LFxuICAgICAgb3BlcmF0b3I6IHRlcm0ub3BlcmF0b3IsXG4gICAgICBvcGVyYW5kOiB0aGlzLmV4cGFuZCh0ZXJtLm9wZXJhbmQpLFxuICAgIH0pO1xuICB9XG5cbiAgZXhwYW5kQmluYXJ5RXhwcmVzc2lvbih0ZXJtKSB7XG4gICAgbGV0IGxlZnQgPSB0aGlzLmV4cGFuZCh0ZXJtLmxlZnQpO1xuICAgIGxldCByaWdodCA9IHRoaXMuZXhwYW5kKHRlcm0ucmlnaHQpO1xuICAgIHJldHVybiBuZXcgVC5CaW5hcnlFeHByZXNzaW9uKHtcbiAgICAgIGxlZnQ6IGxlZnQsXG4gICAgICBvcGVyYXRvcjogdGVybS5vcGVyYXRvcixcbiAgICAgIHJpZ2h0OiByaWdodCxcbiAgICB9KTtcbiAgfVxuXG4gIGV4cGFuZENvbmRpdGlvbmFsRXhwcmVzc2lvbih0ZXJtKSB7XG4gICAgcmV0dXJuIG5ldyBULkNvbmRpdGlvbmFsRXhwcmVzc2lvbih7XG4gICAgICB0ZXN0OiB0aGlzLmV4cGFuZCh0ZXJtLnRlc3QpLFxuICAgICAgY29uc2VxdWVudDogdGhpcy5leHBhbmQodGVybS5jb25zZXF1ZW50KSxcbiAgICAgIGFsdGVybmF0ZTogdGhpcy5leHBhbmQodGVybS5hbHRlcm5hdGUpLFxuICAgIH0pO1xuICB9XG5cbiAgZXhwYW5kTmV3VGFyZ2V0RXhwcmVzc2lvbih0ZXJtKSB7XG4gICAgcmV0dXJuIHRlcm07XG4gIH1cblxuICBleHBhbmROZXdFeHByZXNzaW9uKHRlcm0pIHtcbiAgICBsZXQgY2FsbGVlID0gdGhpcy5leHBhbmQodGVybS5jYWxsZWUpO1xuICAgIGxldCBlbmYgPSBuZXcgRW5mb3Jlc3Rlcih0ZXJtLmFyZ3VtZW50cywgTGlzdCgpLCB0aGlzLmNvbnRleHQpO1xuICAgIGxldCBhcmdzID0gZW5mLmVuZm9yZXN0QXJndW1lbnRMaXN0KCkubWFwKGFyZyA9PiB0aGlzLmV4cGFuZChhcmcpKTtcbiAgICByZXR1cm4gbmV3IFQuTmV3RXhwcmVzc2lvbih7XG4gICAgICBjYWxsZWUsXG4gICAgICBhcmd1bWVudHM6IGFyZ3MudG9BcnJheSgpLFxuICAgIH0pO1xuICB9XG5cbiAgZXhwYW5kU3VwZXIodGVybSkge1xuICAgIHJldHVybiB0ZXJtO1xuICB9XG5cbiAgZXhwYW5kQ2FsbEV4cHJlc3Npb25FKHRlcm0pIHtcbiAgICBsZXQgY2FsbGVlID0gdGhpcy5leHBhbmQodGVybS5jYWxsZWUpO1xuICAgIGxldCBlbmYgPSBuZXcgRW5mb3Jlc3Rlcih0ZXJtLmFyZ3VtZW50cywgTGlzdCgpLCB0aGlzLmNvbnRleHQpO1xuICAgIGxldCBhcmdzID0gZW5mLmVuZm9yZXN0QXJndW1lbnRMaXN0KCkubWFwKGFyZyA9PiB0aGlzLmV4cGFuZChhcmcpKTtcbiAgICByZXR1cm4gbmV3IFQuQ2FsbEV4cHJlc3Npb24oe1xuICAgICAgY2FsbGVlOiBjYWxsZWUsXG4gICAgICBhcmd1bWVudHM6IGFyZ3MsXG4gICAgfSk7XG4gIH1cblxuICBleHBhbmRTcHJlYWRFbGVtZW50KHRlcm0pIHtcbiAgICByZXR1cm4gbmV3IFQuU3ByZWFkRWxlbWVudCh7XG4gICAgICBleHByZXNzaW9uOiB0aGlzLmV4cGFuZCh0ZXJtLmV4cHJlc3Npb24pLFxuICAgIH0pO1xuICB9XG5cbiAgZXhwYW5kRXhwcmVzc2lvblN0YXRlbWVudCh0ZXJtKSB7XG4gICAgbGV0IGNoaWxkID0gdGhpcy5leHBhbmQodGVybS5leHByZXNzaW9uKTtcbiAgICByZXR1cm4gbmV3IFQuRXhwcmVzc2lvblN0YXRlbWVudCh7XG4gICAgICBleHByZXNzaW9uOiBjaGlsZCxcbiAgICB9KTtcbiAgfVxuXG4gIGV4cGFuZExhYmVsZWRTdGF0ZW1lbnQodGVybSkge1xuICAgIHJldHVybiBuZXcgVC5MYWJlbGVkU3RhdGVtZW50KHtcbiAgICAgIGxhYmVsOiB0ZXJtLmxhYmVsLnZhbCgpLFxuICAgICAgYm9keTogdGhpcy5leHBhbmQodGVybS5ib2R5KSxcbiAgICB9KTtcbiAgfVxuXG4gIGRvRnVuY3Rpb25FeHBhbnNpb24odGVybSwgdHlwZSkge1xuICAgIGxldCBzY29wZSA9IGZyZXNoU2NvcGUoJ2Z1bicpO1xuICAgIGxldCBwYXJhbXM7XG4gICAgbGV0IHNlbGYgPSB0aGlzO1xuICAgIGlmICh0eXBlICE9PSAnR2V0dGVyJyAmJiB0eXBlICE9PSAnU2V0dGVyJykge1xuICAgICAgLy8gVE9ETzogbmVlZCB0byByZWdpc3RlciB0aGUgcGFyYW1ldGVyIGJpbmRpbmdzIGFnYWluXG4gICAgICBwYXJhbXMgPSB0ZXJtLnBhcmFtcy5yZWR1Y2UoXG4gICAgICAgIG5ldyBjbGFzcyBleHRlbmRzIFRlcm0uQ2xvbmVSZWR1Y2VyIHtcbiAgICAgICAgICByZWR1Y2VCaW5kaW5nSWRlbnRpZmllcih0ZXJtKSB7XG4gICAgICAgICAgICBsZXQgbmFtZSA9IHRlcm0ubmFtZS5hZGRTY29wZShcbiAgICAgICAgICAgICAgc2NvcGUsXG4gICAgICAgICAgICAgIHNlbGYuY29udGV4dC5iaW5kaW5ncyxcbiAgICAgICAgICAgICAgQUxMX1BIQVNFUyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBsZXQgbmV3QmluZGluZyA9IGdlbnN5bShuYW1lLnZhbCgpKTtcblxuICAgICAgICAgICAgc2VsZi5jb250ZXh0LmVudi5zZXQoXG4gICAgICAgICAgICAgIG5ld0JpbmRpbmcudG9TdHJpbmcoKSxcbiAgICAgICAgICAgICAgbmV3IFZhckJpbmRpbmdUcmFuc2Zvcm0obmFtZSksXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgc2VsZi5jb250ZXh0LmJpbmRpbmdzLmFkZChuYW1lLCB7XG4gICAgICAgICAgICAgIGJpbmRpbmc6IG5ld0JpbmRpbmcsXG4gICAgICAgICAgICAgIHBoYXNlOiBzZWxmLmNvbnRleHQucGhhc2UsXG4gICAgICAgICAgICAgIHNraXBEdXA6IHRydWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgVC5CaW5kaW5nSWRlbnRpZmllcih7IG5hbWUgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KCksXG4gICAgICApO1xuICAgICAgcGFyYW1zID0gdGhpcy5leHBhbmQocGFyYW1zKTtcbiAgICB9XG4gICAgdGhpcy5jb250ZXh0LmN1cnJlbnRTY29wZS5wdXNoKHNjb3BlKTtcbiAgICBsZXQgY29tcGlsZXIgPSBuZXcgQ29tcGlsZXIoXG4gICAgICB0aGlzLmNvbnRleHQucGhhc2UsXG4gICAgICB0aGlzLmNvbnRleHQuZW52LFxuICAgICAgdGhpcy5jb250ZXh0LnN0b3JlLFxuICAgICAgdGhpcy5jb250ZXh0LFxuICAgICk7XG5cbiAgICBsZXQgYm9keVRlcm07XG4gICAgbGV0IHNjb3BlUmVkdWNlciA9IG5ldyBTY29wZVJlZHVjZXIoXG4gICAgICBbeyBzY29wZSwgcGhhc2U6IEFMTF9QSEFTRVMsIGZsaXA6IGZhbHNlIH1dLFxuICAgICAgdGhpcy5jb250ZXh0LmJpbmRpbmdzLFxuICAgICk7XG4gICAgaWYgKHRlcm0uYm9keSBpbnN0YW5jZW9mIFRlcm0pIHtcbiAgICAgIC8vIEFycm93IGZ1bmN0aW9ucyBoYXZlIGEgc2luZ2xlIHRlcm0gYXMgdGhlaXIgYm9keVxuICAgICAgYm9keVRlcm0gPSB0aGlzLmV4cGFuZCh0ZXJtLmJvZHkucmVkdWNlKHNjb3BlUmVkdWNlcikpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgY29tcGlsZWRCb2R5ID0gY29tcGlsZXIuY29tcGlsZShcbiAgICAgICAgdGVybS5ib2R5Lm1hcChiID0+IGIucmVkdWNlKHNjb3BlUmVkdWNlcikpLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGRpcmVjdGl2ZXMgPSBjb21waWxlZEJvZHlcbiAgICAgICAgLnRha2VXaGlsZShcbiAgICAgICAgICBzID0+XG4gICAgICAgICAgICBpc0V4cHJlc3Npb25TdGF0ZW1lbnQocykgJiYgaXNMaXRlcmFsU3RyaW5nRXhwcmVzc2lvbihzLmV4cHJlc3Npb24pLFxuICAgICAgICApXG4gICAgICAgIC5tYXAocyA9PiBuZXcgVC5EaXJlY3RpdmUoeyByYXdWYWx1ZTogcy5leHByZXNzaW9uLnZhbHVlIH0pKTtcbiAgICAgIGJvZHlUZXJtID0gbmV3IFQuRnVuY3Rpb25Cb2R5KHtcbiAgICAgICAgZGlyZWN0aXZlczogZGlyZWN0aXZlcyxcbiAgICAgICAgc3RhdGVtZW50czogY29tcGlsZWRCb2R5LnNsaWNlKGRpcmVjdGl2ZXMuc2l6ZSksXG4gICAgICB9KTtcbiAgICB9XG4gICAgdGhpcy5jb250ZXh0LmN1cnJlbnRTY29wZS5wb3AoKTtcblxuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSAnR2V0dGVyJzpcbiAgICAgICAgcmV0dXJuIG5ldyBULkdldHRlcih7XG4gICAgICAgICAgbmFtZTogdGhpcy5leHBhbmQodGVybS5uYW1lKSxcbiAgICAgICAgICBib2R5OiBib2R5VGVybSxcbiAgICAgICAgfSk7XG4gICAgICBjYXNlICdTZXR0ZXInOlxuICAgICAgICByZXR1cm4gbmV3IFQuU2V0dGVyKHtcbiAgICAgICAgICBuYW1lOiB0aGlzLmV4cGFuZCh0ZXJtLm5hbWUpLFxuICAgICAgICAgIHBhcmFtOiB0ZXJtLnBhcmFtLFxuICAgICAgICAgIGJvZHk6IGJvZHlUZXJtLFxuICAgICAgICB9KTtcbiAgICAgIGNhc2UgJ01ldGhvZCc6XG4gICAgICAgIHJldHVybiBuZXcgVC5NZXRob2Qoe1xuICAgICAgICAgIG5hbWU6IHRlcm0ubmFtZSxcbiAgICAgICAgICBpc0dlbmVyYXRvcjogdGVybS5pc0dlbmVyYXRvcixcbiAgICAgICAgICBwYXJhbXM6IHBhcmFtcyxcbiAgICAgICAgICBib2R5OiBib2R5VGVybSxcbiAgICAgICAgfSk7XG4gICAgICBjYXNlICdBcnJvd0V4cHJlc3Npb24nOlxuICAgICAgICByZXR1cm4gbmV3IFQuQXJyb3dFeHByZXNzaW9uKHtcbiAgICAgICAgICBwYXJhbXM6IHBhcmFtcyxcbiAgICAgICAgICBib2R5OiBib2R5VGVybSxcbiAgICAgICAgfSk7XG4gICAgICBjYXNlICdGdW5jdGlvbkV4cHJlc3Npb24nOlxuICAgICAgICByZXR1cm4gbmV3IFQuRnVuY3Rpb25FeHByZXNzaW9uKHtcbiAgICAgICAgICBuYW1lOiB0ZXJtLm5hbWUsXG4gICAgICAgICAgaXNHZW5lcmF0b3I6IHRlcm0uaXNHZW5lcmF0b3IsXG4gICAgICAgICAgcGFyYW1zOiBwYXJhbXMsXG4gICAgICAgICAgYm9keTogYm9keVRlcm0sXG4gICAgICAgIH0pO1xuICAgICAgY2FzZSAnRnVuY3Rpb25EZWNsYXJhdGlvbic6XG4gICAgICAgIHJldHVybiBuZXcgVC5GdW5jdGlvbkRlY2xhcmF0aW9uKHtcbiAgICAgICAgICBuYW1lOiB0ZXJtLm5hbWUsXG4gICAgICAgICAgaXNHZW5lcmF0b3I6IHRlcm0uaXNHZW5lcmF0b3IsXG4gICAgICAgICAgcGFyYW1zOiBwYXJhbXMsXG4gICAgICAgICAgYm9keTogYm9keVRlcm0sXG4gICAgICAgIH0pO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGZ1bmN0aW9uIHR5cGU6ICR7dHlwZX1gKTtcbiAgICB9XG4gIH1cblxuICBleHBhbmRNZXRob2QodGVybSkge1xuICAgIHJldHVybiB0aGlzLmRvRnVuY3Rpb25FeHBhbnNpb24odGVybSwgJ01ldGhvZCcpO1xuICB9XG5cbiAgZXhwYW5kU2V0dGVyKHRlcm0pIHtcbiAgICByZXR1cm4gdGhpcy5kb0Z1bmN0aW9uRXhwYW5zaW9uKHRlcm0sICdTZXR0ZXInKTtcbiAgfVxuXG4gIGV4cGFuZEdldHRlcih0ZXJtKSB7XG4gICAgcmV0dXJuIHRoaXMuZG9GdW5jdGlvbkV4cGFuc2lvbih0ZXJtLCAnR2V0dGVyJyk7XG4gIH1cblxuICBleHBhbmRGdW5jdGlvbkRlY2xhcmF0aW9uRSh0ZXJtKSB7XG4gICAgcmV0dXJuIHRoaXMuZG9GdW5jdGlvbkV4cGFuc2lvbih0ZXJtLCAnRnVuY3Rpb25EZWNsYXJhdGlvbicpO1xuICB9XG5cbiAgZXhwYW5kRnVuY3Rpb25FeHByZXNzaW9uRSh0ZXJtKSB7XG4gICAgcmV0dXJuIHRoaXMuZG9GdW5jdGlvbkV4cGFuc2lvbih0ZXJtLCAnRnVuY3Rpb25FeHByZXNzaW9uJyk7XG4gIH1cblxuICBleHBhbmRDb21wb3VuZEFzc2lnbm1lbnRFeHByZXNzaW9uKHRlcm0pIHtcbiAgICByZXR1cm4gbmV3IFQuQ29tcG91bmRBc3NpZ25tZW50RXhwcmVzc2lvbih7XG4gICAgICBiaW5kaW5nOiB0aGlzLmV4cGFuZCh0ZXJtLmJpbmRpbmcpLFxuICAgICAgb3BlcmF0b3I6IHRlcm0ub3BlcmF0b3IsXG4gICAgICBleHByZXNzaW9uOiB0aGlzLmV4cGFuZCh0ZXJtLmV4cHJlc3Npb24pLFxuICAgIH0pO1xuICB9XG5cbiAgZXhwYW5kQXNzaWdubWVudEV4cHJlc3Npb24odGVybSkge1xuICAgIHJldHVybiBuZXcgVC5Bc3NpZ25tZW50RXhwcmVzc2lvbih7XG4gICAgICBiaW5kaW5nOiB0aGlzLmV4cGFuZCh0ZXJtLmJpbmRpbmcpLFxuICAgICAgZXhwcmVzc2lvbjogdGhpcy5leHBhbmQodGVybS5leHByZXNzaW9uKSxcbiAgICB9KTtcbiAgfVxuXG4gIGV4cGFuZEVtcHR5U3RhdGVtZW50KHRlcm0pIHtcbiAgICByZXR1cm4gdGVybTtcbiAgfVxuXG4gIGV4cGFuZExpdGVyYWxCb29sZWFuRXhwcmVzc2lvbih0ZXJtKSB7XG4gICAgcmV0dXJuIHRlcm07XG4gIH1cblxuICBleHBhbmRMaXRlcmFsTnVtZXJpY0V4cHJlc3Npb24odGVybSkge1xuICAgIHJldHVybiB0ZXJtO1xuICB9XG4gIGV4cGFuZExpdGVyYWxJbmZpbml0eUV4cHJlc3Npb24odGVybSkge1xuICAgIHJldHVybiB0ZXJtO1xuICB9XG5cbiAgZXhwYW5kSWRlbnRpZmllckV4cHJlc3Npb24odGVybSkge1xuICAgIGxldCB0cmFucyA9IHRoaXMuY29udGV4dC5lbnYuZ2V0KHRlcm0ubmFtZS5yZXNvbHZlKHRoaXMuY29udGV4dC5waGFzZSkpO1xuICAgIGlmICh0cmFucykge1xuICAgICAgcmV0dXJuIG5ldyBULklkZW50aWZpZXJFeHByZXNzaW9uKHtcbiAgICAgICAgbmFtZTogdHJhbnMuaWQsXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHRlcm07XG4gIH1cblxuICBleHBhbmRMaXRlcmFsTnVsbEV4cHJlc3Npb24odGVybSkge1xuICAgIHJldHVybiB0ZXJtO1xuICB9XG5cbiAgZXhwYW5kTGl0ZXJhbFN0cmluZ0V4cHJlc3Npb24odGVybSkge1xuICAgIHJldHVybiB0ZXJtO1xuICB9XG5cbiAgZXhwYW5kTGl0ZXJhbFJlZ0V4cEV4cHJlc3Npb24odGVybSkge1xuICAgIHJldHVybiB0ZXJtO1xuICB9XG59XG4iXX0=\n\n/***/ },\n/* 63 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.Enforester = undefined;\n\n\tvar _terms = __webpack_require__(57);\n\n\tvar _sweetSpec = __webpack_require__(43);\n\n\tvar T = _interopRequireWildcard(_sweetSpec);\n\n\tvar _ramdaFantasy = __webpack_require__(21);\n\n\tvar _scopeReducer = __webpack_require__(64);\n\n\tvar _scopeReducer2 = _interopRequireDefault(_scopeReducer);\n\n\tvar _transforms = __webpack_require__(41);\n\n\tvar _immutable = __webpack_require__(12);\n\n\tvar _errors = __webpack_require__(59);\n\n\tvar _operators = __webpack_require__(65);\n\n\tvar _syntax = __webpack_require__(58);\n\n\tvar _syntax2 = _interopRequireDefault(_syntax);\n\n\tvar _scope = __webpack_require__(38);\n\n\tvar _loadSyntax = __webpack_require__(66);\n\n\tvar _macroContext = __webpack_require__(68);\n\n\tvar _macroContext2 = _interopRequireDefault(_macroContext);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\n\tconst Just = _ramdaFantasy.Maybe.Just;\n\tconst Nothing = _ramdaFantasy.Maybe.Nothing;\n\n\tconst EXPR_LOOP_OPERATOR = {};\n\tconst EXPR_LOOP_NO_CHANGE = {};\n\tconst EXPR_LOOP_EXPANSION = {};\n\n\tfunction getLineNumber(x) {\n\t  let stx;\n\t  if (x instanceof _syntax2.default) {\n\t    stx = x;\n\t  } else if (x instanceof T.RawSyntax) {\n\t    stx = x.value;\n\t  } else if (x instanceof T.RawDelimiter) {\n\t    return getLineNumber(x.inner.first());\n\t  } else {\n\t    throw new Error(`Not implemented yet ${ x }`);\n\t  }\n\t  return stx.lineNumber();\n\t}\n\n\tclass Enforester {\n\n\t  constructor(stxl, prev, context) {\n\t    this.done = false;\n\t    (0, _errors.assert)(_immutable.List.isList(stxl), 'expecting a list of terms to enforest');\n\t    (0, _errors.assert)(_immutable.List.isList(prev), 'expecting a list of terms to enforest');\n\t    (0, _errors.assert)(context, 'expecting a context to enforest');\n\t    this.term = null;\n\n\t    this.rest = stxl;\n\t    this.prev = prev;\n\n\t    this.context = context;\n\t  }\n\n\t  peek(n = 0) {\n\t    return this.rest.get(n);\n\t  }\n\n\t  advance() {\n\t    let ret = this.rest.first();\n\t    this.rest = this.rest.rest();\n\t    return ret;\n\t  }\n\n\t  /*\n\t   enforest works over:\n\t   prev - a list of the previously enforest Terms\n\t   term - the current term being enforested (initially null)\n\t   rest - remaining Terms to enforest\n\t   */\n\t  enforest(type = 'Module') {\n\t    // initialize the term\n\t    this.term = null;\n\n\t    if (this.rest.size === 0) {\n\t      this.done = true;\n\t      return this.term;\n\t    }\n\n\t    if (this.isEOF(this.peek())) {\n\t      this.term = new T.EOF({});\n\t      this.advance();\n\t      return this.term;\n\t    }\n\n\t    let result;\n\t    if (type === 'expression') {\n\t      result = this.enforestExpressionLoop();\n\t    } else {\n\t      result = this.enforestModule();\n\t    }\n\n\t    if (this.rest.size === 0) {\n\t      this.done = true;\n\t    }\n\t    return result;\n\t  }\n\n\t  enforestModule() {\n\t    return this.enforestBody();\n\t  }\n\n\t  enforestBody() {\n\t    return this.enforestModuleItem();\n\t  }\n\n\t  enforestModuleItem() {\n\t    let lookahead = this.peek();\n\n\t    if (this.isImportTransform(lookahead)) {\n\t      this.advance();\n\t      return this.enforestImportDeclaration();\n\t    } else if (this.isExportTransform(lookahead)) {\n\t      this.advance();\n\t      return this.enforestExportDeclaration();\n\t    }\n\t    return this.enforestStatement();\n\t  }\n\n\t  enforestExportDeclaration() {\n\t    let lookahead = this.peek();\n\t    if (this.isCompiletimeTransform(lookahead)) {\n\t      this.expandMacro();\n\t      lookahead = this.peek();\n\t    }\n\n\t    if (this.isPunctuator(lookahead, '*')) {\n\t      this.advance();\n\t      let moduleSpecifier = this.enforestFromClause();\n\t      return new T.ExportAllFrom({ moduleSpecifier });\n\t    } else if (this.isBraces(lookahead)) {\n\t      let namedExports = this.enforestExportClause();\n\t      let moduleSpecifier = null;\n\t      if (this.isIdentifier(this.peek(), 'from')) {\n\t        moduleSpecifier = this.enforestFromClause();\n\t      }\n\t      return new T.ExportFrom({ namedExports, moduleSpecifier });\n\t    } else if (this.isClassTransform(lookahead)) {\n\t      return new T.Export({\n\t        declaration: this.enforestClass({ isExpr: false })\n\t      });\n\t    } else if (this.isFnDeclTransform(lookahead)) {\n\t      return new T.Export({\n\t        declaration: this.enforestFunction({ isExpr: false })\n\t      });\n\t    } else if (this.isDefaultTransform(lookahead)) {\n\t      this.advance();\n\t      if (this.isCompiletimeTransform(lookahead)) {\n\t        this.expandMacro();\n\t        lookahead = this.peek();\n\t      }\n\n\t      if (this.isFnDeclTransform(this.peek())) {\n\t        return new T.ExportDefault({\n\t          body: this.enforestFunction({ isExpr: false, inDefault: true })\n\t        });\n\t      } else if (this.isClassTransform(this.peek())) {\n\t        return new T.ExportDefault({\n\t          body: this.enforestClass({ isExpr: false, inDefault: true })\n\t        });\n\t      } else {\n\t        let body = this.enforestExpressionLoop();\n\t        this.consumeSemicolon();\n\t        return new T.ExportDefault({ body });\n\t      }\n\t    } else if (this.isVarDeclTransform(lookahead) || this.isLetDeclTransform(lookahead) || this.isConstDeclTransform(lookahead) || this.isSyntaxrecDeclTransform(lookahead) || this.isSyntaxDeclTransform(lookahead) || this.isOperatorDeclTransform(lookahead)) {\n\t      return new T.Export({\n\t        declaration: this.enforestVariableDeclaration()\n\t      });\n\t    }\n\t    throw this.createError(lookahead, 'unexpected syntax');\n\t  }\n\n\t  enforestExportClause() {\n\t    let enf = new Enforester(this.matchCurlies(), (0, _immutable.List)(), this.context);\n\t    let result = [];\n\t    while (enf.rest.size !== 0) {\n\t      result.push(enf.enforestExportSpecifier());\n\t      enf.consumeComma();\n\t    }\n\t    return (0, _immutable.List)(result);\n\t  }\n\n\t  enforestExportSpecifier() {\n\t    let name = this.enforestIdentifier();\n\t    if (this.isIdentifier(this.peek(), 'as')) {\n\t      this.advance();\n\t      let exportedName = this.enforestIdentifier();\n\t      return new T.ExportSpecifier({ name, exportedName });\n\t    }\n\t    return new T.ExportSpecifier({\n\t      name: null,\n\t      exportedName: name\n\t    });\n\t  }\n\n\t  enforestImportDeclaration() {\n\t    let lookahead = this.peek();\n\t    let defaultBinding = null;\n\t    let namedImports = (0, _immutable.List)();\n\t    let forSyntax = false;\n\n\t    if (this.isStringLiteral(lookahead)) {\n\t      let moduleSpecifier = this.advance();\n\t      this.consumeSemicolon();\n\t      return new T.Import({\n\t        defaultBinding,\n\t        namedImports,\n\t        moduleSpecifier,\n\t        forSyntax\n\t      });\n\t    }\n\n\t    if (this.isIdentifier(lookahead) || this.isKeyword(lookahead)) {\n\t      defaultBinding = this.enforestBindingIdentifier();\n\t      if (!this.isPunctuator(this.peek(), ',')) {\n\t        let moduleSpecifier = this.enforestFromClause();\n\t        if (this.isKeyword(this.peek(), 'for') && this.isIdentifier(this.peek(1), 'syntax')) {\n\t          this.advance();\n\t          this.advance();\n\t          forSyntax = true;\n\t        }\n\n\t        return new T.Import({\n\t          defaultBinding,\n\t          moduleSpecifier,\n\t          namedImports: (0, _immutable.List)(),\n\t          forSyntax\n\t        });\n\t      }\n\t    }\n\t    this.consumeComma();\n\t    lookahead = this.peek();\n\t    if (this.isBraces(lookahead)) {\n\t      let imports = this.enforestNamedImports();\n\t      let fromClause = this.enforestFromClause();\n\t      if (this.isKeyword(this.peek(), 'for') && this.isIdentifier(this.peek(1), 'syntax')) {\n\t        this.advance();\n\t        this.advance();\n\t        forSyntax = true;\n\t      }\n\n\t      return new T.Import({\n\t        defaultBinding,\n\t        forSyntax,\n\t        namedImports: imports,\n\t        moduleSpecifier: fromClause\n\t      });\n\t    } else if (this.isPunctuator(lookahead, '*')) {\n\t      let namespaceBinding = this.enforestNamespaceBinding();\n\t      let moduleSpecifier = this.enforestFromClause();\n\t      if (this.isKeyword(this.peek(), 'for') && this.isIdentifier(this.peek(1), 'syntax')) {\n\t        this.advance();\n\t        this.advance();\n\t        forSyntax = true;\n\t      }\n\t      return new T.ImportNamespace({\n\t        defaultBinding,\n\t        forSyntax,\n\t        namespaceBinding,\n\t        moduleSpecifier\n\t      });\n\t    }\n\t    throw this.createError(lookahead, 'unexpected syntax');\n\t  }\n\n\t  enforestNamespaceBinding() {\n\t    this.matchPunctuator('*');\n\t    this.matchIdentifier('as');\n\t    return this.enforestBindingIdentifier();\n\t  }\n\n\t  enforestNamedImports() {\n\t    let enf = new Enforester(this.matchCurlies(), (0, _immutable.List)(), this.context);\n\t    let result = [];\n\t    while (enf.rest.size !== 0) {\n\t      result.push(enf.enforestImportSpecifiers());\n\t      enf.consumeComma();\n\t    }\n\t    return (0, _immutable.List)(result);\n\t  }\n\n\t  enforestImportSpecifiers() {\n\t    let lookahead = this.peek();\n\t    let name;\n\t    if (this.isIdentifier(lookahead) || this.isKeyword(lookahead)) {\n\t      name = this.matchRawSyntax();\n\t      if (!this.isIdentifier(this.peek(), 'as')) {\n\t        return new T.ImportSpecifier({\n\t          name: null,\n\t          binding: new T.BindingIdentifier({\n\t            name: name\n\t          })\n\t        });\n\t      } else {\n\t        this.matchIdentifier('as');\n\t      }\n\t    } else {\n\t      throw this.createError(lookahead, 'unexpected token in import specifier');\n\t    }\n\t    return new T.ImportSpecifier({\n\t      name,\n\t      binding: this.enforestBindingIdentifier()\n\t    });\n\t  }\n\n\t  enforestFromClause() {\n\t    this.matchIdentifier('from');\n\t    let lookahead = this.matchStringLiteral();\n\t    this.consumeSemicolon();\n\t    return lookahead;\n\t  }\n\n\t  enforestStatementListItem() {\n\t    let lookahead = this.peek();\n\n\t    if (this.isFnDeclTransform(lookahead)) {\n\t      return this.enforestFunction({ isExpr: false });\n\t    } else if (this.isClassTransform(lookahead)) {\n\t      return this.enforestClass({ isExpr: false });\n\t    } else {\n\t      return this.enforestStatement();\n\t    }\n\t  }\n\n\t  enforestStatement() {\n\t    let lookahead = this.peek();\n\n\t    if (this.term === null && this.isCompiletimeTransform(lookahead)) {\n\t      this.expandMacro();\n\t      lookahead = this.peek();\n\t    }\n\n\t    if (this.term === null && this.isTerm(lookahead) && lookahead instanceof T.Statement) {\n\t      // TODO: check that this is actually an statement\n\t      return this.advance();\n\t    }\n\n\t    if (this.term === null && this.isBraces(lookahead)) {\n\t      return this.enforestBlockStatement();\n\t    }\n\n\t    if (this.term === null && this.isWhileTransform(lookahead)) {\n\t      return this.enforestWhileStatement();\n\t    }\n\n\t    if (this.term === null && this.isIfTransform(lookahead)) {\n\t      return this.enforestIfStatement();\n\t    }\n\t    if (this.term === null && this.isForTransform(lookahead)) {\n\t      return this.enforestForStatement();\n\t    }\n\t    if (this.term === null && this.isSwitchTransform(lookahead)) {\n\t      return this.enforestSwitchStatement();\n\t    }\n\t    if (this.term === null && this.isBreakTransform(lookahead)) {\n\t      return this.enforestBreakStatement();\n\t    }\n\t    if (this.term === null && this.isContinueTransform(lookahead)) {\n\t      return this.enforestContinueStatement();\n\t    }\n\t    if (this.term === null && this.isDoTransform(lookahead)) {\n\t      return this.enforestDoStatement();\n\t    }\n\t    if (this.term === null && this.isDebuggerTransform(lookahead)) {\n\t      return this.enforestDebuggerStatement();\n\t    }\n\t    if (this.term === null && this.isWithTransform(lookahead)) {\n\t      return this.enforestWithStatement();\n\t    }\n\t    if (this.term === null && this.isTryTransform(lookahead)) {\n\t      return this.enforestTryStatement();\n\t    }\n\t    if (this.term === null && this.isThrowTransform(lookahead)) {\n\t      return this.enforestThrowStatement();\n\t    }\n\n\t    // TODO: put somewhere else\n\t    if (this.term === null && this.isKeyword(lookahead, 'class')) {\n\t      return this.enforestClass({ isExpr: false });\n\t    }\n\n\t    if (this.term === null && this.isFnDeclTransform(lookahead)) {\n\t      return this.enforestFunction({ isExpr: false });\n\t    }\n\n\t    if (this.term === null && this.isIdentifier(lookahead) && this.isPunctuator(this.peek(1), ':')) {\n\t      return this.enforestLabeledStatement();\n\t    }\n\n\t    if (this.term === null && (this.isVarDeclTransform(lookahead) || this.isLetDeclTransform(lookahead) || this.isConstDeclTransform(lookahead) || this.isSyntaxrecDeclTransform(lookahead) || this.isSyntaxDeclTransform(lookahead) || this.isOperatorDeclTransform(lookahead))) {\n\t      let stmt = new T.VariableDeclarationStatement({\n\t        declaration: this.enforestVariableDeclaration()\n\t      });\n\t      this.consumeSemicolon();\n\t      return stmt;\n\t    }\n\n\t    if (this.term === null && this.isReturnStmtTransform(lookahead)) {\n\t      return this.enforestReturnStatement();\n\t    }\n\n\t    if (this.term === null && this.isPunctuator(lookahead, ';')) {\n\t      this.advance();\n\t      return new T.EmptyStatement({});\n\t    }\n\n\t    return this.enforestExpressionStatement();\n\t  }\n\n\t  enforestLabeledStatement() {\n\t    let label = this.matchIdentifier();\n\t    this.matchPunctuator(':');\n\t    let stmt = this.enforestStatement();\n\n\t    return new T.LabeledStatement({\n\t      label: label,\n\t      body: stmt\n\t    });\n\t  }\n\n\t  enforestBreakStatement() {\n\t    this.matchKeyword('break');\n\t    let lookahead = this.peek();\n\t    let label = null;\n\t    if (this.rest.size === 0 || this.isPunctuator(lookahead, ';')) {\n\t      this.consumeSemicolon();\n\t      return new T.BreakStatement({ label });\n\t    }\n\t    if (this.isIdentifier(lookahead) || this.isKeyword(lookahead, 'yield') || this.isKeyword(lookahead, 'let')) {\n\t      label = this.enforestIdentifier();\n\t    }\n\t    this.consumeSemicolon();\n\n\t    return new T.BreakStatement({ label });\n\t  }\n\n\t  enforestTryStatement() {\n\t    this.matchKeyword('try');\n\t    let body = this.enforestBlock();\n\t    if (this.isKeyword(this.peek(), 'catch')) {\n\t      let catchClause = this.enforestCatchClause();\n\t      if (this.isKeyword(this.peek(), 'finally')) {\n\t        this.advance();\n\t        let finalizer = this.enforestBlock();\n\t        return new T.TryFinallyStatement({\n\t          body,\n\t          catchClause,\n\t          finalizer\n\t        });\n\t      }\n\t      return new T.TryCatchStatement({ body, catchClause });\n\t    }\n\t    if (this.isKeyword(this.peek(), 'finally')) {\n\t      this.advance();\n\t      let finalizer = this.enforestBlock();\n\t      return new T.TryFinallyStatement({ body, catchClause: null, finalizer });\n\t    }\n\t    throw this.createError(this.peek(), 'try with no catch or finally');\n\t  }\n\n\t  enforestCatchClause() {\n\t    this.matchKeyword('catch');\n\t    let bindingParens = this.matchParens();\n\t    let enf = new Enforester(bindingParens, (0, _immutable.List)(), this.context);\n\t    let binding = enf.enforestBindingTarget();\n\t    let body = this.enforestBlock();\n\t    return new T.CatchClause({ binding, body });\n\t  }\n\n\t  enforestThrowStatement() {\n\t    this.matchKeyword('throw');\n\t    let expression = this.enforestExpression();\n\t    this.consumeSemicolon();\n\t    return new T.ThrowStatement({ expression });\n\t  }\n\n\t  enforestWithStatement() {\n\t    this.matchKeyword('with');\n\t    let objParens = this.matchParens();\n\t    let enf = new Enforester(objParens, (0, _immutable.List)(), this.context);\n\t    let object = enf.enforestExpression();\n\t    let body = this.enforestStatement();\n\t    return new T.WithStatement({ object, body });\n\t  }\n\n\t  enforestDebuggerStatement() {\n\t    this.matchKeyword('debugger');\n\n\t    return new T.DebuggerStatement({});\n\t  }\n\n\t  enforestDoStatement() {\n\t    this.matchKeyword('do');\n\t    let body = this.enforestStatement();\n\t    this.matchKeyword('while');\n\t    let testBody = this.matchParens();\n\t    let enf = new Enforester(testBody, (0, _immutable.List)(), this.context);\n\t    let test = enf.enforestExpression();\n\t    this.consumeSemicolon();\n\t    return new T.DoWhileStatement({ body, test });\n\t  }\n\n\t  enforestContinueStatement() {\n\t    let kwd = this.matchKeyword('continue');\n\t    let lookahead = this.peek();\n\t    let label = null;\n\t    if (this.rest.size === 0 || this.isPunctuator(lookahead, ';')) {\n\t      this.consumeSemicolon();\n\t      return new T.ContinueStatement({ label });\n\t    }\n\t    if (lookahead instanceof T.RawSyntax && this.lineNumberEq(kwd, lookahead) && (this.isIdentifier(lookahead) || this.isKeyword(lookahead, 'yield') || this.isKeyword(lookahead, 'let'))) {\n\t      label = this.enforestIdentifier();\n\t    }\n\t    this.consumeSemicolon();\n\n\t    return new T.ContinueStatement({ label });\n\t  }\n\n\t  enforestSwitchStatement() {\n\t    this.matchKeyword('switch');\n\t    let cond = this.matchParens();\n\t    let enf = new Enforester(cond, (0, _immutable.List)(), this.context);\n\t    let discriminant = enf.enforestExpression();\n\t    let body = this.matchCurlies();\n\n\t    if (body.size === 0) {\n\t      return new T.SwitchStatement({\n\t        discriminant: discriminant,\n\t        cases: (0, _immutable.List)()\n\t      });\n\t    }\n\t    enf = new Enforester(body, (0, _immutable.List)(), this.context);\n\t    let cases = enf.enforestSwitchCases();\n\t    let lookahead = enf.peek();\n\t    if (enf.isKeyword(lookahead, 'default')) {\n\t      let defaultCase = enf.enforestSwitchDefault();\n\t      let postDefaultCases = enf.enforestSwitchCases();\n\t      return new T.SwitchStatementWithDefault({\n\t        discriminant,\n\t        preDefaultCases: cases,\n\t        defaultCase,\n\t        postDefaultCases\n\t      });\n\t    }\n\t    return new T.SwitchStatement({ discriminant, cases });\n\t  }\n\n\t  enforestSwitchCases() {\n\t    let cases = [];\n\t    while (!(this.rest.size === 0 || this.isKeyword(this.peek(), 'default'))) {\n\t      cases.push(this.enforestSwitchCase());\n\t    }\n\t    return (0, _immutable.List)(cases);\n\t  }\n\n\t  enforestSwitchCase() {\n\t    this.matchKeyword('case');\n\t    return new T.SwitchCase({\n\t      test: this.enforestExpression(),\n\t      consequent: this.enforestSwitchCaseBody()\n\t    });\n\t  }\n\n\t  enforestSwitchCaseBody() {\n\t    this.matchPunctuator(':');\n\t    return this.enforestStatementListInSwitchCaseBody();\n\t  }\n\n\t  enforestStatementListInSwitchCaseBody() {\n\t    let result = [];\n\t    while (!(this.rest.size === 0 || this.isKeyword(this.peek(), 'default') || this.isKeyword(this.peek(), 'case'))) {\n\t      result.push(this.enforestStatementListItem());\n\t    }\n\t    return (0, _immutable.List)(result);\n\t  }\n\n\t  enforestSwitchDefault() {\n\t    this.matchKeyword('default');\n\t    return new T.SwitchDefault({\n\t      consequent: this.enforestSwitchCaseBody()\n\t    });\n\t  }\n\n\t  enforestForStatement() {\n\t    this.matchKeyword('for');\n\t    let cond = this.matchParens();\n\t    let enf = new Enforester(cond, (0, _immutable.List)(), this.context);\n\t    let lookahead, test, init, right, left, update, cnst;\n\n\t    // case where init is null\n\t    if (enf.isPunctuator(enf.peek(), ';')) {\n\t      enf.advance();\n\t      if (!enf.isPunctuator(enf.peek(), ';')) {\n\t        test = enf.enforestExpression();\n\t      }\n\t      enf.matchPunctuator(';');\n\t      if (enf.rest.size !== 0) {\n\t        right = enf.enforestExpression();\n\t      }\n\t      return new T.ForStatement({\n\t        init: null,\n\t        test: test,\n\t        update: right,\n\t        body: this.enforestStatement()\n\t      });\n\t      // case where init is not null\n\t    } else {\n\t      // testing\n\t      lookahead = enf.peek();\n\t      if (enf.isVarDeclTransform(lookahead) || enf.isLetDeclTransform(lookahead) || enf.isConstDeclTransform(lookahead)) {\n\t        init = enf.enforestVariableDeclaration();\n\t        lookahead = enf.peek();\n\t        if (this.isKeyword(lookahead, 'in') || this.isIdentifier(lookahead, 'of')) {\n\t          if (this.isKeyword(lookahead, 'in')) {\n\t            enf.advance();\n\t            right = enf.enforestExpression();\n\t            cnst = T.ForInStatement;\n\t          } else {\n\t            (0, _errors.assert)(this.isIdentifier(lookahead, 'of'), 'expecting `of` keyword');\n\t            enf.advance();\n\t            right = enf.enforestExpression();\n\t            cnst = T.ForOfStatement;\n\t          }\n\t          return new cnst({\n\t            left: init,\n\t            right,\n\t            body: this.enforestStatement()\n\t          });\n\t        }\n\t        enf.matchPunctuator(';');\n\t        if (enf.isPunctuator(enf.peek(), ';')) {\n\t          enf.advance();\n\t          test = null;\n\t        } else {\n\t          test = enf.enforestExpression();\n\t          enf.matchPunctuator(';');\n\t        }\n\t        update = enf.enforestExpression();\n\t      } else {\n\t        if (this.isKeyword(enf.peek(1), 'in') || this.isIdentifier(enf.peek(1), 'of')) {\n\t          left = enf.enforestBindingIdentifier();\n\t          let kind = enf.advance();\n\t          if (this.isKeyword(kind, 'in')) {\n\t            cnst = T.ForInStatement;\n\t          } else {\n\t            cnst = T.ForOfStatement;\n\t          }\n\t          right = enf.enforestExpression();\n\t          return new cnst({\n\t            left: left,\n\t            right,\n\t            body: this.enforestStatement()\n\t          });\n\t        }\n\t        init = enf.enforestExpression();\n\t        enf.matchPunctuator(';');\n\t        if (enf.isPunctuator(enf.peek(), ';')) {\n\t          enf.advance();\n\t          test = null;\n\t        } else {\n\t          test = enf.enforestExpression();\n\t          enf.matchPunctuator(';');\n\t        }\n\t        update = enf.enforestExpression();\n\t      }\n\t      return new T.ForStatement({\n\t        init,\n\t        test,\n\t        update,\n\t        body: this.enforestStatement()\n\t      });\n\t    }\n\t  }\n\n\t  enforestIfStatement() {\n\t    this.matchKeyword('if');\n\t    let cond = this.matchParens();\n\t    let enf = new Enforester(cond, (0, _immutable.List)(), this.context);\n\t    let lookahead = enf.peek();\n\t    let test = enf.enforestExpression();\n\t    if (test === null) {\n\t      throw enf.createError(lookahead, 'expecting an expression');\n\t    }\n\t    let consequent = this.enforestStatement();\n\t    let alternate = null;\n\t    if (this.isKeyword(this.peek(), 'else')) {\n\t      this.advance();\n\t      alternate = this.enforestStatement();\n\t    }\n\t    return new T.IfStatement({ test, consequent, alternate });\n\t  }\n\n\t  enforestWhileStatement() {\n\t    this.matchKeyword('while');\n\t    let cond = this.matchParens();\n\t    let enf = new Enforester(cond, (0, _immutable.List)(), this.context);\n\t    let lookahead = enf.peek();\n\t    let test = enf.enforestExpression();\n\t    if (test === null) {\n\t      throw enf.createError(lookahead, 'expecting an expression');\n\t    }\n\t    let body = this.enforestStatement();\n\n\t    return new T.WhileStatement({ test, body });\n\t  }\n\n\t  enforestBlockStatement() {\n\t    return new T.BlockStatement({\n\t      block: this.enforestBlock()\n\t    });\n\t  }\n\n\t  enforestBlock() {\n\t    return new T.Block({\n\t      statements: this.matchCurlies()\n\t    });\n\t  }\n\n\t  enforestClass({\n\t    isExpr = false,\n\t    inDefault = false\n\t  }) {\n\t    let kw = this.matchRawSyntax();\n\t    let name = null,\n\t        supr = null;\n\n\t    if (this.isIdentifier(this.peek())) {\n\t      name = this.enforestBindingIdentifier();\n\t    } else if (!isExpr) {\n\t      if (inDefault) {\n\t        name = new T.BindingIdentifier({\n\t          name: _syntax2.default.fromIdentifier('_default', kw)\n\t        });\n\t      } else {\n\t        throw this.createError(this.peek(), 'unexpected syntax');\n\t      }\n\t    }\n\n\t    if (this.isKeyword(this.peek(), 'extends')) {\n\t      this.advance();\n\t      supr = this.enforestExpressionLoop();\n\t    }\n\n\t    let elements = [];\n\t    let enf = new Enforester(this.matchCurlies(), (0, _immutable.List)(), this.context);\n\t    while (enf.rest.size !== 0) {\n\t      if (enf.isPunctuator(enf.peek(), ';')) {\n\t        enf.advance();\n\t        continue;\n\t      }\n\n\t      let isStatic = false;\n\t      let { methodOrKey, kind } = enf.enforestMethodDefinition();\n\t      if (kind === 'identifier' && methodOrKey.value.val() === 'static') {\n\t        isStatic = true;\n\t        ({ methodOrKey, kind } = enf.enforestMethodDefinition());\n\t      }\n\t      if (kind === 'method') {\n\t        elements.push(new T.ClassElement({ isStatic, method: methodOrKey }));\n\t      } else {\n\t        throw this.createError(enf.peek(), 'Only methods are allowed in classes');\n\t      }\n\t    }\n\t    return new (isExpr ? T.ClassExpression : T.ClassDeclaration)({\n\t      name,\n\t      super: supr,\n\t      elements: (0, _immutable.List)(elements)\n\t    });\n\t  }\n\n\t  enforestBindingTarget({ allowPunctuator = false } = {}) {\n\t    let lookahead = this.peek();\n\t    if (this.isIdentifier(lookahead) || this.isKeyword(lookahead) || allowPunctuator && this.isPunctuator(lookahead)) {\n\t      return this.enforestBindingIdentifier({ allowPunctuator });\n\t    } else if (this.isBrackets(lookahead)) {\n\t      return this.enforestArrayBinding();\n\t    } else if (this.isBraces(lookahead)) {\n\t      return this.enforestObjectBinding();\n\t    }\n\t    (0, _errors.assert)(false, 'not implemented yet');\n\t  }\n\n\t  enforestObjectBinding() {\n\t    let enf = new Enforester(this.matchCurlies(), (0, _immutable.List)(), this.context);\n\t    let properties = [];\n\n\t    //TODO: implement object rest operator when it lands\n\t    while (enf.rest.size !== 0) {\n\t      properties.push(enf.enforestBindingProperty());\n\n\t      if (enf.rest.size > 0 && !enf.isPunctuator(enf.peek(), ',')) {\n\t        throw enf.createError(enf.peek(), 'unexpected token');\n\t      }\n\n\t      enf.consumeComma();\n\t    }\n\n\t    return new T.ObjectBinding({\n\t      properties: (0, _immutable.List)(properties)\n\t    });\n\t  }\n\n\t  enforestBindingProperty() {\n\t    let lookahead = this.peek();\n\t    let { name, binding } = this.enforestPropertyName();\n\t    if (this.isIdentifier(lookahead) || this.isKeyword(lookahead, 'let') || this.isKeyword(lookahead, 'yield')) {\n\t      if (!this.isPunctuator(this.peek(), ':')) {\n\t        let defaultValue = null;\n\t        if (this.isAssign(this.peek())) {\n\t          this.advance();\n\t          let expr = this.enforestExpressionLoop();\n\t          defaultValue = expr;\n\t        }\n\t        return new T.BindingPropertyIdentifier({\n\t          binding,\n\t          init: defaultValue\n\t        });\n\t      }\n\t    }\n\t    this.matchPunctuator(':');\n\t    binding = this.enforestBindingElement();\n\t    return new T.BindingPropertyProperty({\n\t      name,\n\t      binding\n\t    });\n\t  }\n\n\t  enforestArrayBinding() {\n\t    let bracket = this.matchSquares();\n\t    let enf = new Enforester(bracket, (0, _immutable.List)(), this.context);\n\t    let elements = [],\n\t        restElement = null;\n\t    while (enf.rest.size !== 0) {\n\t      let el = null;\n\t      if (!enf.isPunctuator(enf.peek(), ',')) {\n\t        if (enf.isPunctuator(enf.peek(), '...')) {\n\t          enf.advance();\n\t          restElement = enf.enforestBindingTarget();\n\t          if (enf.rest.size > 0) {\n\t            throw enf.createError('', 'Rest element must be last element in array');\n\t          }\n\t        } else {\n\t          el = enf.enforestBindingElement();\n\n\t          if (el == null) {\n\t            throw enf.createError(enf.peek(), 'expected expression');\n\t          }\n\t          if (enf.rest.size > 0 && !enf.isPunctuator(enf.peek(), ',')) {\n\t            throw enf.createError(enf.peek(), 'unexpected token');\n\t          }\n\t        }\n\t      }\n\t      if (restElement == null) {\n\t        elements.push(el);\n\t        enf.consumeComma();\n\t      }\n\t    }\n\t    return new T.ArrayBinding({\n\t      elements: (0, _immutable.List)(elements),\n\t      restElement\n\t    });\n\t  }\n\n\t  enforestBindingElement() {\n\t    let binding = this.enforestBindingTarget();\n\n\t    if (this.isAssign(this.peek())) {\n\t      this.advance();\n\t      let init = this.enforestExpressionLoop();\n\t      binding = new T.BindingWithDefault({ binding, init });\n\t    }\n\t    return binding;\n\t  }\n\n\t  enforestBindingIdentifier({ allowPunctuator } = {}) {\n\t    let name;\n\t    if (allowPunctuator && this.isPunctuator(this.peek())) {\n\t      name = this.enforestPunctuator();\n\t    } else {\n\t      name = this.enforestIdentifier();\n\t    }\n\t    return new T.BindingIdentifier({ name });\n\t  }\n\n\t  enforestPunctuator() {\n\t    let lookahead = this.peek();\n\t    if (this.isPunctuator(lookahead)) {\n\t      return this.matchRawSyntax();\n\t    }\n\t    throw this.createError(lookahead, 'expecting a punctuator');\n\t  }\n\n\t  enforestIdentifier() {\n\t    let lookahead = this.peek();\n\t    if (this.isIdentifier(lookahead) || this.isKeyword(lookahead)) {\n\t      return this.matchRawSyntax();\n\t    }\n\t    throw this.createError(lookahead, 'expecting an identifier');\n\t  }\n\n\t  enforestReturnStatement() {\n\t    let kw = this.matchRawSyntax();\n\t    let lookahead = this.peek();\n\n\t    // short circuit for the empty expression case\n\t    if (this.rest.size === 0 || lookahead && !this.lineNumberEq(kw, lookahead)) {\n\t      return new T.ReturnStatement({\n\t        expression: null\n\t      });\n\t    }\n\n\t    let term = null;\n\t    if (!this.isPunctuator(lookahead, ';')) {\n\t      term = this.enforestExpression();\n\t      (0, _errors.expect)(term != null, 'Expecting an expression to follow return keyword', lookahead, this.rest);\n\t    }\n\n\t    this.consumeSemicolon();\n\t    return new T.ReturnStatement({\n\t      expression: term\n\t    });\n\t  }\n\n\t  enforestVariableDeclaration() {\n\t    let kind;\n\t    let lookahead = this.advance();\n\n\t    if (this.isVarDeclTransform(lookahead)) {\n\t      kind = 'var';\n\t    } else if (this.isLetDeclTransform(lookahead)) {\n\t      kind = 'let';\n\t    } else if (this.isConstDeclTransform(lookahead)) {\n\t      kind = 'const';\n\t    } else if (this.isSyntaxDeclTransform(lookahead)) {\n\t      kind = 'syntax';\n\t    } else if (this.isSyntaxrecDeclTransform(lookahead)) {\n\t      kind = 'syntaxrec';\n\t    } else if (this.isOperatorDeclTransform(lookahead)) {\n\t      kind = 'operator';\n\t    }\n\n\t    let decls = (0, _immutable.List)();\n\n\t    while (true) {\n\t      let term = this.enforestVariableDeclarator({\n\t        isSyntax: kind === 'syntax' || kind === 'syntaxrec' || kind === 'operator',\n\t        isOperator: kind === 'operator'\n\t      });\n\t      let lookahead = this.peek();\n\t      decls = decls.concat(term);\n\n\t      if (this.isPunctuator(lookahead, ',')) {\n\t        this.advance();\n\t      } else {\n\t        break;\n\t      }\n\t    }\n\n\t    return new T.VariableDeclaration({\n\t      kind: kind,\n\t      declarators: decls\n\t    });\n\t  }\n\n\t  enforestVariableDeclarator({ isSyntax, isOperator }) {\n\t    let id = this.enforestBindingTarget({ allowPunctuator: isSyntax });\n\t    const AssocValues = ['left', 'right', 'prefix', 'postfix'];\n\n\t    let assoc, prec;\n\t    if (isOperator) {\n\t      assoc = this.matchIdentifier();\n\t      if (AssocValues.indexOf(assoc.val()) === -1) {\n\t        throw this.createError(this.peek(), `Associativity must be one of ${ AssocValues.join(',') }`);\n\t      }\n\t      prec = this.matchLiteral();\n\t    }\n\n\t    let init;\n\t    if (this.isPunctuator(this.peek(), '=')) {\n\t      this.advance();\n\t      let enf = new Enforester(this.rest, (0, _immutable.List)(), this.context);\n\t      init = enf.enforest('expression');\n\t      this.rest = enf.rest;\n\t    } else {\n\t      init = null;\n\t    }\n\n\t    if (isOperator) {\n\t      return new T.OperatorDeclarator({\n\t        binding: id,\n\t        init,\n\t        prec,\n\t        assoc\n\t      });\n\t    }\n\t    return new T.VariableDeclarator({\n\t      binding: id,\n\t      init: init\n\t    });\n\t  }\n\n\t  enforestExpressionStatement() {\n\t    let start = this.rest.get(0);\n\t    let expr = this.enforestExpression();\n\t    if (expr === null) {\n\t      throw this.createError(start, 'not a valid expression');\n\t    }\n\t    this.consumeSemicolon();\n\n\t    return new T.ExpressionStatement({\n\t      expression: expr\n\t    });\n\t  }\n\n\t  enforestExpression() {\n\t    let left = this.enforestExpressionLoop();\n\t    let lookahead = this.peek();\n\t    if (this.isPunctuator(lookahead, ',')) {\n\t      while (this.rest.size !== 0) {\n\t        if (!this.isPunctuator(this.peek(), ',')) {\n\t          break;\n\t        }\n\t        let operator = this.matchRawSyntax();\n\t        let right = this.enforestExpressionLoop();\n\t        left = new T.BinaryExpression({\n\t          left,\n\t          operator: operator.val(),\n\t          right\n\t        });\n\t      }\n\t    }\n\t    this.term = null;\n\t    return left;\n\t  }\n\n\t  enforestExpressionLoop() {\n\t    this.term = null;\n\t    this.opCtx = {\n\t      prec: 0,\n\t      combine: x => x,\n\t      stack: (0, _immutable.List)()\n\t    };\n\n\t    do {\n\t      let term = this.enforestAssignmentExpression();\n\t      // no change means we've done as much enforesting as possible\n\t      // if nothing changed, maybe we just need to pop the expr stack\n\t      if (term === EXPR_LOOP_NO_CHANGE && this.opCtx.stack.size > 0) {\n\t        this.term = this.opCtx.combine(this.term);\n\t        let { prec, combine } = this.opCtx.stack.last();\n\t        this.opCtx.prec = prec;\n\t        this.opCtx.combine = combine;\n\t        this.opCtx.stack = this.opCtx.stack.pop();\n\t      } else if (term === EXPR_LOOP_NO_CHANGE) {\n\t        break;\n\t      } else if (term === EXPR_LOOP_OPERATOR || term === EXPR_LOOP_EXPANSION) {\n\t        // operator means an opCtx was pushed on the stack\n\t        this.term = null;\n\t      } else {\n\t        this.term = term;\n\t      }\n\t    } while (true); // get a fixpoint\n\t    return this.term;\n\t  }\n\n\t  enforestAssignmentExpression() {\n\t    let lookahead = this.peek();\n\n\t    if (this.term === null && this.isModuleNamespaceTransform(lookahead)) {\n\t      // $FlowFixMe: we need to refactor the enforester to make flow work better\n\t      let namespace = this.getFromCompiletimeEnvironment(this.advance().value);\n\t      this.matchPunctuator('.');\n\t      let name = this.matchIdentifier();\n\t      // $FlowFixMe: we need to refactor the enforester to make flow work better\n\t      let exportedName = namespace.mod.exportedNames.find(exName => exName.exportedName.val() === name.val());\n\t      this.rest = this.rest.unshift(new T.RawSyntax({\n\t        value: _syntax2.default.fromIdentifier(name.val(), exportedName.exportedName)\n\t      }));\n\t      lookahead = this.peek();\n\t    }\n\n\t    if (this.term === null && this.isCompiletimeTransform(lookahead)) {\n\t      this.expandMacro();\n\t      lookahead = this.peek();\n\t    }\n\n\t    if (this.term === null && this.isTerm(lookahead) && lookahead instanceof T.Expression) {\n\t      // TODO: check that this is actually an expression\n\t      return this.advance();\n\t    }\n\n\t    if (this.term === null && this.isYieldTransform(lookahead)) {\n\t      return this.enforestYieldExpression();\n\t    }\n\n\t    if (this.term === null && this.isClassTransform(lookahead)) {\n\t      return this.enforestClass({ isExpr: true });\n\t    }\n\n\t    if (this.term === null && lookahead && (this.isIdentifier(lookahead) || this.isParens(lookahead)) && this.isPunctuator(this.peek(1), '=>') && this.lineNumberEq(lookahead, this.peek(1))) {\n\t      return this.enforestArrowExpression();\n\t    }\n\n\t    if (this.term === null && this.isSyntaxTemplate(lookahead)) {\n\t      return this.enforestSyntaxTemplate();\n\t    }\n\n\t    // ($x:expr)\n\t    if (this.term === null && this.isParens(lookahead)) {\n\t      return new T.ParenthesizedExpression({\n\t        inner: this.matchParens()\n\t      });\n\t    }\n\n\t    if (this.term === null && (this.isKeyword(lookahead, 'this') || this.isIdentifier(lookahead) || this.isKeyword(lookahead, 'let') || this.isKeyword(lookahead, 'yield') || this.isNumericLiteral(lookahead) || this.isStringLiteral(lookahead) || this.isTemplate(lookahead) || this.isBooleanLiteral(lookahead) || this.isNullLiteral(lookahead) || this.isRegularExpression(lookahead) || this.isFnDeclTransform(lookahead) || this.isBraces(lookahead) || this.isBrackets(lookahead))) {\n\t      return this.enforestPrimaryExpression();\n\t    }\n\n\t    // prefix unary\n\t    if (this.term === null && (this.isOperator(lookahead) || this.isCustomPrefixOperator(lookahead))) {\n\t      return this.enforestUnaryExpression();\n\t    }\n\n\t    if (this.term === null && this.isVarBindingTransform(lookahead) && lookahead instanceof T.RawSyntax) {\n\t      let lookstx = lookahead.value;\n\t      // $FlowFixMe\n\t      let id = this.getFromCompiletimeEnvironment(lookstx).id;\n\t      if (id !== lookstx) {\n\t        this.advance();\n\t        this.rest = _immutable.List.of(id).concat(this.rest);\n\t        return EXPR_LOOP_EXPANSION;\n\t      }\n\t    }\n\n\t    if (this.term === null && (this.isNewTransform(lookahead) || this.isSuperTransform(lookahead)) ||\n\t    // and then check the cases where the term part of p is something...\n\t    this.term && (\n\t    // $x:expr . $prop:ident\n\t    this.isPunctuator(lookahead, '.') && (this.isIdentifier(this.peek(1)) || this.isKeyword(this.peek(1))) ||\n\t    // $x:expr [ $b:expr ]\n\t    this.isBrackets(lookahead) ||\n\t    // $x:expr (...)\n\t    this.isParens(lookahead))) {\n\t      return this.enforestLeftHandSideExpression({ allowCall: true });\n\t    }\n\n\t    // postfix unary\n\t    if (this.term && (this.isUpdateOperator(lookahead) || this.isCustomPostfixOperator(lookahead))) {\n\t      return this.enforestUpdateExpression();\n\t    }\n\n\t    // $x:id `...`\n\t    if (this.term && this.isTemplate(lookahead)) {\n\t      return this.enforestTemplateLiteral();\n\t    }\n\n\t    // $l:expr $op:binaryOperator $r:expr\n\t    if (this.term && (this.isOperator(lookahead) || this.isCustomBinaryOperator(lookahead))) {\n\t      return this.enforestBinaryExpression();\n\t    }\n\n\t    // $x:expr = $init:expr\n\t    if (this.term && this.isAssign(lookahead)) {\n\t      let binding = this.transformDestructuring(this.term);\n\t      let op = this.matchRawSyntax();\n\n\t      let enf = new Enforester(this.rest, (0, _immutable.List)(), this.context);\n\t      let init = enf.enforest('expression');\n\t      this.rest = enf.rest;\n\n\t      if (op.val() === '=') {\n\t        return new T.AssignmentExpression({\n\t          binding,\n\t          expression: init\n\t        });\n\t      } else {\n\t        return new T.CompoundAssignmentExpression({\n\t          binding,\n\t          operator: op.val(),\n\t          expression: init\n\t        });\n\t      }\n\t    }\n\n\t    if (this.term && this.isPunctuator(lookahead, '?')) {\n\t      return this.enforestConditionalExpression();\n\t    }\n\n\t    return EXPR_LOOP_NO_CHANGE;\n\t  }\n\n\t  enforestPrimaryExpression() {\n\t    let lookahead = this.peek();\n\t    // $x:ThisExpression\n\t    if (this.term === null && this.isKeyword(lookahead, 'this')) {\n\t      return this.enforestThisExpression();\n\t    }\n\t    // $x:ident\n\t    if (this.term === null && (this.isIdentifier(lookahead) || this.isKeyword(lookahead, 'let') || this.isKeyword(lookahead, 'yield'))) {\n\t      return this.enforestIdentifierExpression();\n\t    }\n\t    if (this.term === null && this.isNumericLiteral(lookahead)) {\n\t      return this.enforestNumericLiteral();\n\t    }\n\t    if (this.term === null && this.isStringLiteral(lookahead)) {\n\t      return this.enforestStringLiteral();\n\t    }\n\t    if (this.term === null && this.isTemplate(lookahead)) {\n\t      return this.enforestTemplateLiteral();\n\t    }\n\t    if (this.term === null && this.isBooleanLiteral(lookahead)) {\n\t      return this.enforestBooleanLiteral();\n\t    }\n\t    if (this.term === null && this.isNullLiteral(lookahead)) {\n\t      return this.enforestNullLiteral();\n\t    }\n\t    if (this.term === null && this.isRegularExpression(lookahead)) {\n\t      return this.enforestRegularExpressionLiteral();\n\t    }\n\t    // $x:FunctionExpression\n\t    if (this.term === null && this.isFnDeclTransform(lookahead)) {\n\t      return this.enforestFunction({ isExpr: true });\n\t    }\n\t    // { $p:prop (,) ... }\n\t    if (this.term === null && this.isBraces(lookahead)) {\n\t      return this.enforestObjectExpression();\n\t    }\n\t    // [$x:expr (,) ...]\n\t    if (this.term === null && this.isBrackets(lookahead)) {\n\t      return this.enforestArrayExpression();\n\t    }\n\t    (0, _errors.assert)(false, 'Not a primary expression');\n\t  }\n\n\t  enforestLeftHandSideExpression({ allowCall }) {\n\t    let lookahead = this.peek();\n\n\t    if (this.isCompiletimeTransform(lookahead)) {\n\t      this.expandMacro();\n\t      lookahead = this.peek();\n\t    }\n\n\t    if (this.isSuperTransform(lookahead)) {\n\t      this.advance();\n\t      this.term = new T.Super({});\n\t    } else if (this.isNewTransform(lookahead)) {\n\t      this.term = this.enforestNewExpression();\n\t    } else if (this.isThisTransform(lookahead)) {\n\t      this.term = this.enforestThisExpression();\n\t    }\n\n\t    while (true) {\n\t      lookahead = this.peek();\n\t      if (this.isParens(lookahead)) {\n\t        if (!allowCall) {\n\t          // we're dealing with a new expression\n\t          if (this.term && ((0, _terms.isIdentifierExpression)(this.term) || (0, _terms.isStaticMemberExpression)(this.term) || (0, _terms.isComputedMemberExpression)(this.term))) {\n\t            return this.term;\n\t          }\n\t          this.term = this.enforestExpressionLoop();\n\t        } else {\n\t          this.term = this.enforestCallExpression();\n\t        }\n\t      } else if (this.isBrackets(lookahead)) {\n\t        this.term = this.term ? this.enforestComputedMemberExpression() : this.enforestPrimaryExpression();\n\t      } else if (this.isPunctuator(lookahead, '.') && (this.isIdentifier(this.peek(1)) || this.isKeyword(this.peek(1)))) {\n\t        this.term = this.enforestStaticMemberExpression();\n\t      } else if (this.isTemplate(lookahead)) {\n\t        this.term = this.enforestTemplateLiteral();\n\t      } else if (this.isBraces(lookahead)) {\n\t        this.term = this.enforestPrimaryExpression();\n\t      } else if (this.isIdentifier(lookahead)) {\n\t        if (this.term) break;\n\t        this.term = new T.IdentifierExpression({\n\t          name: this.enforestIdentifier()\n\t        });\n\t      } else {\n\t        break;\n\t      }\n\t    }\n\t    return this.term;\n\t  }\n\n\t  enforestBooleanLiteral() {\n\t    return new T.LiteralBooleanExpression({\n\t      value: this.matchRawSyntax().val() === 'true'\n\t    });\n\t  }\n\n\t  enforestTemplateLiteral() {\n\t    return new T.TemplateExpression({\n\t      tag: this.term,\n\t      elements: this.enforestTemplateElements()\n\t    });\n\t  }\n\n\t  enforestStringLiteral() {\n\t    return new T.LiteralStringExpression({\n\t      value: this.matchRawSyntax().val()\n\t    });\n\t  }\n\n\t  enforestNumericLiteral() {\n\t    let num = this.matchRawSyntax();\n\t    if (num.val() === 1 / 0) {\n\t      return new T.LiteralInfinityExpression({});\n\t    }\n\t    return new T.LiteralNumericExpression({\n\t      value: num.val()\n\t    });\n\t  }\n\n\t  enforestIdentifierExpression() {\n\t    return new T.IdentifierExpression({\n\t      name: this.matchRawSyntax()\n\t    });\n\t  }\n\n\t  enforestRegularExpressionLiteral() {\n\t    let reStx = this.matchRawSyntax();\n\n\t    let lastSlash = reStx.token.value.lastIndexOf('/');\n\t    let pattern = reStx.token.value.slice(1, lastSlash);\n\t    let flags = reStx.token.value.slice(lastSlash + 1);\n\t    return new T.LiteralRegExpExpression({\n\t      pattern,\n\t      flags\n\t    });\n\t  }\n\n\t  enforestNullLiteral() {\n\t    this.advance();\n\t    return new T.LiteralNullExpression({});\n\t  }\n\n\t  enforestThisExpression() {\n\t    return new T.ThisExpression({\n\t      stx: this.matchRawSyntax()\n\t    });\n\t  }\n\n\t  enforestArgumentList() {\n\t    let result = [];\n\t    while (this.rest.size > 0) {\n\t      let arg;\n\t      if (this.isPunctuator(this.peek(), '...')) {\n\t        this.advance();\n\t        arg = new T.SpreadElement({\n\t          expression: this.enforestExpressionLoop()\n\t        });\n\t      } else {\n\t        arg = this.enforestExpressionLoop();\n\t      }\n\t      if (this.rest.size > 0) {\n\t        this.matchPunctuator(',');\n\t      }\n\t      result.push(arg);\n\t    }\n\t    return (0, _immutable.List)(result);\n\t  }\n\n\t  enforestNewExpression() {\n\t    this.matchKeyword('new');\n\t    if (this.isPunctuator(this.peek(), '.') && this.isIdentifier(this.peek(1), 'target')) {\n\t      this.advance();\n\t      this.advance();\n\t      return new T.NewTargetExpression({});\n\t    }\n\n\t    let callee = this.enforestLeftHandSideExpression({ allowCall: false });\n\t    let args;\n\t    if (this.isParens(this.peek())) {\n\t      args = this.matchParens();\n\t    } else {\n\t      args = (0, _immutable.List)();\n\t    }\n\t    return new T.NewExpression({\n\t      callee,\n\t      arguments: args\n\t    });\n\t  }\n\n\t  enforestComputedMemberExpression() {\n\t    let enf = new Enforester(this.matchSquares(), (0, _immutable.List)(), this.context);\n\t    return new T.ComputedMemberExpression({\n\t      object: this.term,\n\t      expression: enf.enforestExpression()\n\t    });\n\t  }\n\n\t  transformDestructuring(term) {\n\t    switch (term.type) {\n\t      case 'IdentifierExpression':\n\t        return new T.BindingIdentifier({ name: term.name });\n\n\t      case 'ParenthesizedExpression':\n\t        if (term.inner.size === 1 && this.isIdentifier(term.inner.get(0))) {\n\t          return new T.BindingIdentifier({ name: term.inner.get(0).value });\n\t        }\n\t        return term;\n\t      case 'DataProperty':\n\t        return new T.BindingPropertyProperty({\n\t          name: term.name,\n\t          binding: this.transformDestructuringWithDefault(term.expression)\n\t        });\n\t      case 'ShorthandProperty':\n\t        return new T.BindingPropertyIdentifier({\n\t          binding: new T.BindingIdentifier({ name: term.name }),\n\t          init: null\n\t        });\n\t      case 'ObjectExpression':\n\t        return new T.ObjectBinding({\n\t          properties: term.properties.map(t => this.transformDestructuring(t))\n\t        });\n\t      case 'ArrayExpression':\n\t        {\n\t          let last = term.elements.last();\n\t          if (last != null && last.type === 'SpreadElement') {\n\t            return new T.ArrayBinding({\n\t              elements: term.elements.slice(0, -1).map(t => t && this.transformDestructuringWithDefault(t)),\n\t              restElement: this.transformDestructuringWithDefault(last.expression)\n\t            });\n\t          } else {\n\t            return new T.ArrayBinding({\n\t              elements: term.elements.map(t => t && this.transformDestructuringWithDefault(t)),\n\t              restElement: null\n\t            });\n\t          }\n\t        }\n\t      case 'StaticPropertyName':\n\t        return new T.BindingIdentifier({\n\t          name: term.value\n\t        });\n\t      case 'ComputedMemberExpression':\n\t      case 'StaticMemberExpression':\n\t      case 'ArrayBinding':\n\t      case 'BindingIdentifier':\n\t      case 'BindingPropertyIdentifier':\n\t      case 'BindingPropertyProperty':\n\t      case 'BindingWithDefault':\n\t      case 'ObjectBinding':\n\t        return term;\n\t    }\n\t    (0, _errors.assert)(false, 'not implemented yet for ' + term.type);\n\t  }\n\n\t  transformDestructuringWithDefault(term) {\n\t    switch (term.type) {\n\t      case 'AssignmentExpression':\n\t        return new T.BindingWithDefault({\n\t          binding: this.transformDestructuring(term.binding),\n\t          init: term.expression\n\t        });\n\t    }\n\t    return this.transformDestructuring(term);\n\t  }\n\n\t  enforestCallExpression() {\n\t    let paren = this.matchParens();\n\t    return new T.CallExpressionE({\n\t      callee: this.term,\n\t      arguments: paren\n\t    });\n\t  }\n\n\t  enforestArrowExpression() {\n\t    let enf;\n\t    if (this.isIdentifier(this.peek())) {\n\t      enf = new Enforester(_immutable.List.of(this.advance()), (0, _immutable.List)(), this.context);\n\t    } else {\n\t      let p = this.matchParens();\n\t      enf = new Enforester(p, (0, _immutable.List)(), this.context);\n\t    }\n\t    let params = enf.enforestFormalParameters();\n\t    this.matchPunctuator('=>');\n\n\t    let body;\n\t    if (this.isBraces(this.peek())) {\n\t      body = this.matchCurlies();\n\t      return new T.ArrowExpressionE({ params, body });\n\t    } else {\n\t      enf = new Enforester(this.rest, (0, _immutable.List)(), this.context);\n\t      body = enf.enforestExpressionLoop();\n\t      this.rest = enf.rest;\n\t      return new T.ArrowExpression({ params, body });\n\t    }\n\t  }\n\n\t  enforestYieldExpression() {\n\t    let kwd = this.matchKeyword('yield');\n\t    let lookahead = this.peek();\n\n\t    if (this.rest.size === 0 || lookahead && !this.lineNumberEq(kwd, lookahead)) {\n\t      return new T.YieldExpression({\n\t        expression: null\n\t      });\n\t    } else {\n\t      let isGenerator = false;\n\t      if (this.isPunctuator(this.peek(), '*')) {\n\t        isGenerator = true;\n\t        this.advance();\n\t      }\n\t      let expr = this.enforestExpression();\n\t      return new (isGenerator ? T.YieldGeneratorExpression : T.YieldExpression)({\n\t        expression: expr\n\t      });\n\t    }\n\t  }\n\n\t  enforestSyntaxTemplate() {\n\t    return new T.SyntaxTemplate({\n\t      template: this.matchRawDelimiter()\n\t    });\n\t  }\n\n\t  enforestStaticMemberExpression() {\n\t    let object = this.term;\n\t    this.advance();\n\t    let property = this.matchRawSyntax();\n\n\t    return new T.StaticMemberExpression({\n\t      object: object,\n\t      property: property\n\t    });\n\t  }\n\n\t  enforestArrayExpression() {\n\t    let arr = this.matchSquares();\n\n\t    let elements = [];\n\n\t    let enf = new Enforester(arr, (0, _immutable.List)(), this.context);\n\n\t    while (enf.rest.size > 0) {\n\t      let lookahead = enf.peek();\n\t      let expression = null;\n\t      if (!enf.isPunctuator(lookahead, ',')) {\n\t        let isSpread = false;\n\t        if (enf.isPunctuator(lookahead, '...')) {\n\t          enf.advance();\n\t          isSpread = true;\n\t        }\n\t        expression = enf.enforestExpressionLoop();\n\t        if (expression == null) {\n\t          // this was a macro that expanded to nothing\n\t          continue;\n\t        }\n\t        if (enf.rest.size > 0 && !enf.isPunctuator(enf.peek(), ',')) {\n\t          throw enf.createError(enf.peek(), 'unexpected token');\n\t        }\n\t        if (isSpread) {\n\t          expression = new T.SpreadElement({ expression });\n\t        }\n\t      }\n\t      enf.consumeComma();\n\t      elements.push(expression);\n\t    }\n\n\t    return new T.ArrayExpression({\n\t      elements: (0, _immutable.List)(elements)\n\t    });\n\t  }\n\n\t  enforestObjectExpression() {\n\t    let obj = this.matchCurlies();\n\n\t    let properties = (0, _immutable.List)();\n\n\t    let enf = new Enforester(obj, (0, _immutable.List)(), this.context);\n\n\t    let lastProp = null;\n\t    //TODO: implement object spread operator when it lands\n\t    while (enf.rest.size > 0) {\n\t      let prop = enf.enforestPropertyDefinition();\n\n\t      if (enf.rest.size > 0 && !enf.isPunctuator(enf.peek(), ',')) {\n\t        throw enf.createError(enf.peek(), 'unexpected token');\n\t      }\n\n\t      enf.consumeComma();\n\t      properties = properties.concat(prop);\n\n\t      if (lastProp === prop) {\n\t        throw enf.createError(prop, 'invalid syntax in object');\n\t      }\n\t      lastProp = prop;\n\t    }\n\n\t    return new T.ObjectExpression({\n\t      properties: properties\n\t    });\n\t  }\n\n\t  enforestPropertyDefinition() {\n\t    let { methodOrKey, kind } = this.enforestMethodDefinition();\n\n\t    switch (kind) {\n\t      case 'method':\n\t        return methodOrKey;\n\t      case 'identifier':\n\t        if (this.isAssign(this.peek())) {\n\t          this.advance();\n\t          let init = this.enforestExpressionLoop();\n\t          return new T.BindingPropertyIdentifier({\n\t            init,\n\t            binding: this.transformDestructuring(methodOrKey)\n\t          });\n\t        } else if (!this.isPunctuator(this.peek(), ':')) {\n\t          return new T.ShorthandProperty({\n\t            name: methodOrKey.value\n\t          });\n\t        }\n\t    }\n\n\t    this.matchPunctuator(':');\n\t    let expr = this.enforestExpressionLoop();\n\n\t    return new T.DataProperty({\n\t      name: methodOrKey,\n\t      expression: expr\n\t    });\n\t  }\n\n\t  enforestMethodDefinition() {\n\t    let lookahead = this.peek();\n\t    let isGenerator = false;\n\t    if (this.isPunctuator(lookahead, '*')) {\n\t      isGenerator = true;\n\t      this.advance();\n\t    }\n\n\t    if (this.isIdentifier(lookahead, 'get') && this.isPropertyName(this.peek(1))) {\n\t      this.advance();\n\t      let { name } = this.enforestPropertyName();\n\t      this.matchParens();\n\t      let body = this.matchCurlies();\n\t      return {\n\t        methodOrKey: new T.Getter({ name, body }),\n\t        kind: 'method'\n\t      };\n\t    } else if (this.isIdentifier(lookahead, 'set') && this.isPropertyName(this.peek(1))) {\n\t      this.advance();\n\t      let { name } = this.enforestPropertyName();\n\t      let enf = new Enforester(this.matchParens(), (0, _immutable.List)(), this.context);\n\t      let param = enf.enforestBindingElement();\n\t      let body = this.matchCurlies();\n\t      return {\n\t        methodOrKey: new T.Setter({ name, param, body }),\n\t        kind: 'method'\n\t      };\n\t    }\n\t    let { name } = this.enforestPropertyName();\n\t    if (this.isParens(this.peek())) {\n\t      let params = this.matchParens();\n\t      let enf = new Enforester(params, (0, _immutable.List)(), this.context);\n\t      let formalParams = enf.enforestFormalParameters();\n\n\t      let body = this.matchCurlies();\n\t      return {\n\t        methodOrKey: new T.Method({\n\t          isGenerator,\n\t          name,\n\t          params: formalParams,\n\t          body\n\t        }),\n\t        kind: 'method'\n\t      };\n\t    }\n\t    return {\n\t      methodOrKey: name,\n\t      kind: this.isIdentifier(lookahead) || this.isKeyword(lookahead) ? 'identifier' : 'property'\n\t    };\n\t  }\n\n\t  enforestPropertyName() {\n\t    let lookahead = this.peek();\n\n\t    if (this.isStringLiteral(lookahead) || this.isNumericLiteral(lookahead)) {\n\t      return {\n\t        name: new T.StaticPropertyName({\n\t          value: this.matchRawSyntax()\n\t        }),\n\t        binding: null\n\t      };\n\t    } else if (this.isBrackets(lookahead)) {\n\t      let enf = new Enforester(this.matchSquares(), (0, _immutable.List)(), this.context);\n\t      let expr = enf.enforestExpressionLoop();\n\t      return {\n\t        name: new T.ComputedPropertyName({\n\t          expression: expr\n\t        }),\n\t        binding: null\n\t      };\n\t    }\n\t    let name = this.matchRawSyntax();\n\t    return {\n\t      name: new T.StaticPropertyName({ value: name }),\n\t      binding: new T.BindingIdentifier({ name })\n\t    };\n\t  }\n\n\t  enforestFunction({ isExpr, inDefault }) {\n\t    let name = null,\n\t        params,\n\t        body;\n\t    let isGenerator = false;\n\t    // eat the function keyword\n\t    let fnKeyword = this.matchRawSyntax();\n\t    let lookahead = this.peek();\n\n\t    if (this.isPunctuator(lookahead, '*')) {\n\t      isGenerator = true;\n\t      this.advance();\n\t      lookahead = this.peek();\n\t    }\n\n\t    if (!this.isParens(lookahead)) {\n\t      name = this.enforestBindingIdentifier();\n\t    } else if (inDefault) {\n\t      name = new T.BindingIdentifier({\n\t        name: _syntax2.default.fromIdentifier('*default*', fnKeyword)\n\t      });\n\t    }\n\n\t    params = this.matchParens();\n\n\t    body = this.matchCurlies();\n\n\t    let enf = new Enforester(params, (0, _immutable.List)(), this.context);\n\t    let formalParams = enf.enforestFormalParameters();\n\n\t    return new (isExpr ? T.FunctionExpressionE : T.FunctionDeclarationE)({\n\t      name: name,\n\t      isGenerator: isGenerator,\n\t      params: formalParams,\n\t      body: body\n\t    });\n\t  }\n\n\t  enforestFormalParameters() {\n\t    let items = [];\n\t    let rest = null;\n\t    while (this.rest.size !== 0) {\n\t      let lookahead = this.peek();\n\t      if (this.isPunctuator(lookahead, '...')) {\n\t        this.matchPunctuator('...');\n\t        rest = this.enforestBindingIdentifier();\n\t        break;\n\t      }\n\t      items.push(this.enforestParam());\n\t      this.consumeComma();\n\t    }\n\t    return new T.FormalParameters({\n\t      items: (0, _immutable.List)(items),\n\t      rest\n\t    });\n\t  }\n\n\t  enforestParam() {\n\t    return this.enforestBindingElement();\n\t  }\n\n\t  enforestUpdateExpression() {\n\t    const lookahead = this.peek();\n\t    const leftTerm = this.term;\n\t    if (!lookahead) {\n\t      throw this.createError(lookahead, 'assertion failure: operator is null');\n\t    }\n\t    let operator = this.matchRawSyntax();\n\t    if (this.isCompiletimeTransform(lookahead)) {\n\t      const operatorTransform = this.getFromCompiletimeEnvironment(operator);\n\t      if (!operatorTransform || operatorTransform.value.type !== 'operator') {\n\t        throw this.createError(lookahead, 'unexpected transform');\n\t      }\n\t      let result = operatorTransform.value.f.call(null, leftTerm);\n\t      let enf = new Enforester(result, (0, _immutable.List)(), this.context);\n\t      return enf.enforestExpressionLoop();\n\t    }\n\t    return new T.UpdateExpression({\n\t      isPrefix: false,\n\t      operator: operator.val(),\n\t      operand: this.transformDestructuring(leftTerm)\n\t    });\n\t  }\n\n\t  enforestUnaryExpression() {\n\t    const lookahead = this.peek();\n\t    if (!lookahead) {\n\t      throw this.createError(lookahead, 'assertion failure: operator is null');\n\t    }\n\t    let operator = this.matchRawSyntax();\n\t    let prec, combine;\n\t    if (this.isCompiletimeTransform(lookahead)) {\n\t      const operatorTransform = this.getFromCompiletimeEnvironment(lookahead);\n\t      if (!operatorTransform || operatorTransform.value.type !== 'operator') {\n\t        throw this.createError(lookahead, 'unexpected transform');\n\t      }\n\t      prec = operatorTransform.value.prec;\n\t      combine = rightTerm => {\n\t        return this.expandOperator(lookahead, operatorTransform, [rightTerm]);\n\t      };\n\t    } else {\n\t      // all builtins are 16\n\t      prec = 16;\n\t      combine = rightTerm => {\n\t        if (operator.val() === '++' || operator.val() === '--') {\n\t          return new T.UpdateExpression({\n\t            operator: operator.val(),\n\t            operand: this.transformDestructuring(rightTerm),\n\t            isPrefix: true\n\t          });\n\t        } else {\n\t          return new T.UnaryExpression({\n\t            operator: operator.val(),\n\t            operand: rightTerm\n\t          });\n\t        }\n\t      };\n\t    }\n\n\t    this.opCtx.stack = this.opCtx.stack.push({\n\t      prec: this.opCtx.prec,\n\t      combine: this.opCtx.combine\n\t    });\n\t    this.opCtx.prec = prec;\n\t    this.opCtx.combine = rightTerm => {\n\t      return combine(rightTerm);\n\t    };\n\t    return EXPR_LOOP_OPERATOR;\n\t  }\n\n\t  enforestConditionalExpression() {\n\t    // first, pop the operator stack\n\t    let test = this.opCtx.combine(this.term);\n\t    if (this.opCtx.stack.size > 0) {\n\t      let { prec, combine } = this.opCtx.stack.last();\n\t      this.opCtx.stack = this.opCtx.stack.pop();\n\t      this.opCtx.prec = prec;\n\t      this.opCtx.combine = combine;\n\t    }\n\n\t    this.matchPunctuator('?');\n\t    let enf = new Enforester(this.rest, (0, _immutable.List)(), this.context);\n\t    let consequent = enf.enforestExpressionLoop();\n\t    enf.matchPunctuator(':');\n\t    enf = new Enforester(enf.rest, (0, _immutable.List)(), this.context);\n\t    let alternate = enf.enforestExpressionLoop();\n\t    this.rest = enf.rest;\n\t    return new T.ConditionalExpression({\n\t      test,\n\t      consequent,\n\t      alternate\n\t    });\n\t  }\n\n\t  enforestBinaryExpression() {\n\t    let leftTerm = this.term;\n\t    const opStx = this.peek();\n\t    if (!opStx) {\n\t      throw this.createError(opStx, 'assertion failure: opStx is null');\n\t    }\n\n\t    let prec, assoc, combine;\n\t    if (this.isCompiletimeTransform(this.peek())) {\n\t      const operatorTransform = this.getFromCompiletimeEnvironment(opStx.value);\n\t      if (!operatorTransform || operatorTransform.value.type !== 'operator') {\n\t        throw this.createError(opStx.value, 'unexpected transform');\n\t      }\n\t      prec = operatorTransform.value.prec;\n\t      assoc = operatorTransform.value.assoc;\n\t      combine = (left, right) => {\n\t        return this.expandOperator(opStx, operatorTransform, [left, right]);\n\t      };\n\t    } else {\n\t      prec = (0, _operators.getOperatorPrec)(opStx.value.val());\n\t      assoc = (0, _operators.getOperatorAssoc)(opStx.value.val());\n\t      combine = (left, right) => new T.BinaryExpression({\n\t        left,\n\t        right,\n\t        operator: opStx.value.val()\n\t      });\n\t    }\n\n\t    if ((0, _operators.operatorLt)(this.opCtx.prec, prec, assoc)) {\n\t      this.opCtx.stack = this.opCtx.stack.push({\n\t        prec: this.opCtx.prec,\n\t        combine: this.opCtx.combine\n\t      });\n\t      this.opCtx.prec = prec;\n\t      this.opCtx.combine = rightTerm => {\n\t        return combine(leftTerm, rightTerm);\n\t      };\n\t      this.advance();\n\t      return EXPR_LOOP_OPERATOR;\n\t    } else {\n\t      let term = this.opCtx.combine(leftTerm);\n\t      // this.rest does not change\n\t      let { prec, combine } = this.opCtx.stack.last();\n\t      this.opCtx.stack = this.opCtx.stack.pop();\n\t      this.opCtx.prec = prec;\n\t      this.opCtx.combine = combine;\n\t      return term;\n\t    }\n\t  }\n\n\t  enforestTemplateElements() {\n\t    let lookahead = this.matchTemplate();\n\t    let elements = lookahead.token.items.map(it => {\n\t      if (this.isDelimiter(it)) {\n\t        let enf = new Enforester(it.inner.slice(1, it.inner.size - 1), (0, _immutable.List)(), this.context);\n\t        return enf.enforest('expression');\n\t      }\n\t      return new T.TemplateElement({\n\t        rawValue: it.value.token.slice.text\n\t      });\n\t    });\n\t    return elements;\n\t  }\n\n\t  expandMacro() {\n\t    let lookahead = this.peek();\n\t    while (this.isCompiletimeTransform(lookahead)) {\n\t      let name = this.matchRawSyntax();\n\n\t      let syntaxTransform = this.getFromCompiletimeEnvironment(name);\n\t      if (syntaxTransform == null) {\n\t        throw this.createError(name, `The macro ${ name.resolve(this.context.phase) } does not have a bound value`);\n\t      } else if (typeof syntaxTransform.value.f !== 'function') {\n\t        throw this.createError(name, `The macro ${ name.resolve(this.context.phase) } was not bound to a callable value: ${ syntaxTransform.value.f }`);\n\t      }\n\t      let useSiteScope = (0, _scope.freshScope)('u');\n\t      let introducedScope = (0, _scope.freshScope)('i');\n\t      // TODO: needs to be a list of scopes I think\n\t      this.context.useScope = useSiteScope;\n\n\t      let ctx = new _macroContext2.default(this, name, this.context, useSiteScope, introducedScope);\n\n\t      let result = (0, _loadSyntax.sanitizeReplacementValues)(syntaxTransform.value.f.call(null, ctx));\n\t      if (!_immutable.List.isList(result)) {\n\t        throw this.createError(name, 'macro must return a list but got: ' + result);\n\t      }\n\t      let scopeReducer = new _scopeReducer2.default([{ scope: introducedScope, phase: _syntax.ALL_PHASES, flip: true }], this.context.bindings, true);\n\t      result = result.map(terms => {\n\t        if (terms instanceof _syntax2.default) {\n\t          return new T.RawSyntax({\n\t            value: terms\n\t          }).reduce(scopeReducer);\n\t        } else if (!(terms instanceof T.default)) {\n\t          throw this.createError(name, 'macro must return syntax objects or terms but got: ' + terms);\n\t        }\n\t        return terms.reduce(scopeReducer);\n\t      });\n\n\t      this.rest = result.concat(ctx._rest(this));\n\t      lookahead = this.peek();\n\t    }\n\t  }\n\n\t  expandOperator(name, operatorTransform, args) {\n\t    let useSiteScope = (0, _scope.freshScope)('u');\n\t    let introducedScope = (0, _scope.freshScope)('i');\n\t    // TODO: needs to be a list of scopes I think\n\t    this.context.useScope = useSiteScope;\n\t    args = args.map(arg => {\n\t      return arg.reduce(new _scopeReducer2.default([{ scope: useSiteScope, phase: _syntax.ALL_PHASES, flip: false }, { scope: introducedScope, phase: _syntax.ALL_PHASES, flip: true }], this.context.bindings));\n\t    });\n\t    let result = (0, _loadSyntax.sanitizeReplacementValues)(operatorTransform.value.f.apply(null, args));\n\t    let scopeReducer = new _scopeReducer2.default([{ scope: introducedScope, phase: _syntax.ALL_PHASES, flip: true }], this.context.bindings, true);\n\t    result = result.map(terms => {\n\t      if (terms instanceof _syntax2.default) {\n\t        return new T.RawSyntax({\n\t          value: terms\n\t        }).reduce(scopeReducer);\n\t      } else if (!(terms instanceof T.default)) {\n\t        throw this.createError(name, 'macro must return syntax objects or terms but got: ' + terms);\n\t      }\n\t      return terms.reduce(scopeReducer);\n\t    });\n\t    let enf = new Enforester(result, (0, _immutable.List)(), this.context);\n\t    return enf.enforestExpressionLoop();\n\t  }\n\n\t  consumeSemicolon() {\n\t    let lookahead = this.peek();\n\n\t    if (lookahead && this.isPunctuator(lookahead, ';')) {\n\t      this.advance();\n\t    }\n\t  }\n\n\t  consumeComma() {\n\t    let lookahead = this.peek();\n\n\t    if (lookahead && this.isPunctuator(lookahead, ',')) {\n\t      this.advance();\n\t    }\n\t  }\n\n\t  safeCheck(obj, type, val = null) {\n\t    if (obj instanceof T.default) {\n\t      if (obj instanceof T.RawSyntax) {\n\t        return obj.value && (typeof obj.value.match === 'function' ? obj.value.match(type, val) : false);\n\t      } else if (obj instanceof T.RawDelimiter) {\n\t        return type === 'delimiter' || obj.kind === type;\n\t      }\n\t    }\n\t    return obj && (typeof obj.match === 'function' ? obj.match(type, val) : false);\n\t  }\n\n\t  isTerm(term) {\n\t    return term && term instanceof T.default;\n\t  }\n\n\t  isEOF(obj) {\n\t    return this.safeCheck(obj, 'eof');\n\t  }\n\n\t  isIdentifier(obj, val = null) {\n\t    return this.safeCheck(obj, 'identifier', val);\n\t  }\n\n\t  isPropertyName(obj) {\n\t    return this.isIdentifier(obj) || this.isKeyword(obj) || this.isNumericLiteral(obj) || this.isStringLiteral(obj) || this.isBrackets(obj);\n\t  }\n\n\t  isNumericLiteral(obj, val = null) {\n\t    return this.safeCheck(obj, 'number', val);\n\t  }\n\n\t  isStringLiteral(obj, val = null) {\n\t    return this.safeCheck(obj, 'string', val);\n\t  }\n\n\t  isTemplate(obj, val = null) {\n\t    return this.safeCheck(obj, 'template', val);\n\t  }\n\n\t  isSyntaxTemplate(obj) {\n\t    return this.safeCheck(obj, 'syntaxTemplate');\n\t  }\n\n\t  isBooleanLiteral(obj, val = null) {\n\t    return this.safeCheck(obj, 'boolean', val);\n\t  }\n\n\t  isNullLiteral(obj, val = null) {\n\t    return this.safeCheck(obj, 'null', val);\n\t  }\n\n\t  isRegularExpression(obj, val = null) {\n\t    return this.safeCheck(obj, 'regularExpression', val);\n\t  }\n\n\t  isDelimiter(obj) {\n\t    return this.safeCheck(obj, 'delimiter');\n\t  }\n\n\t  isParens(obj) {\n\t    return this.safeCheck(obj, 'parens');\n\t  }\n\n\t  isBraces(obj) {\n\t    return this.safeCheck(obj, 'braces');\n\t  }\n\n\t  isBrackets(obj) {\n\t    return this.safeCheck(obj, 'brackets');\n\t  }\n\n\t  isAssign(obj, val = null) {\n\t    return this.safeCheck(obj, 'assign', val);\n\t  }\n\n\t  isKeyword(obj, val = null) {\n\t    return this.safeCheck(obj, 'keyword', val);\n\t  }\n\n\t  isPunctuator(obj, val = null) {\n\t    return this.safeCheck(obj, 'punctuator', val);\n\t  }\n\n\t  isOperator(obj) {\n\t    return (this.safeCheck(obj, 'punctuator') || this.safeCheck(obj, 'identifier') || this.safeCheck(obj, 'keyword')) && (obj instanceof T.RawSyntax && (0, _operators.isOperator)(obj.value) || obj instanceof _syntax2.default && (0, _operators.isOperator)(obj));\n\t  }\n\n\t  isCustomPrefixOperator(obj) {\n\t    if (this.isCompiletimeTransform(obj)) {\n\t      let t = this.getFromCompiletimeEnvironment(obj.value);\n\t      return t && t.value.assoc === 'prefix';\n\t    }\n\t    return false;\n\t  }\n\n\t  isCustomPostfixOperator(obj) {\n\t    if (this.isCompiletimeTransform(obj)) {\n\t      let t = this.getFromCompiletimeEnvironment(obj.value);\n\t      return t && t.value.assoc === 'postfix';\n\t    }\n\t    return false;\n\t  }\n\n\t  isCustomBinaryOperator(obj) {\n\t    if (this.isCompiletimeTransform(obj)) {\n\t      let t = this.getFromCompiletimeEnvironment(obj.value);\n\t      return t && (t.value.assoc === 'left' || t.value.assoc === 'right');\n\t    }\n\t    return false;\n\t  }\n\n\t  isUpdateOperator(obj) {\n\t    return this.safeCheck(obj, 'punctuator', '++') || this.safeCheck(obj, 'punctuator', '--');\n\t  }\n\n\t  safeResolve(obj, phase) {\n\t    if (obj instanceof T.RawSyntax) {\n\t      return typeof obj.value.resolve === 'function' ? Just(obj.value.resolve(phase)) : Nothing();\n\t    } else if (obj instanceof _syntax2.default) {\n\t      return typeof obj.resolve === 'function' ? Just(obj.resolve(phase)) : Nothing();\n\t    }\n\t    return Nothing();\n\t  }\n\n\t  isTransform(obj, trans) {\n\t    return this.safeResolve(obj, this.context.phase).map(name => this.context.env.get(name) === trans || this.context.store.get(name) === trans).getOrElse(false);\n\t  }\n\n\t  isTransformInstance(obj, trans) {\n\t    return this.safeResolve(obj, this.context.phase).map(name => this.context.env.get(name) instanceof trans || this.context.store.get(name) instanceof trans).getOrElse(false);\n\t  }\n\n\t  isFnDeclTransform(obj) {\n\t    return this.isTransform(obj, _transforms.FunctionDeclTransform);\n\t  }\n\n\t  isVarDeclTransform(obj) {\n\t    return this.isTransform(obj, _transforms.VariableDeclTransform);\n\t  }\n\n\t  isLetDeclTransform(obj) {\n\t    return this.isTransform(obj, _transforms.LetDeclTransform);\n\t  }\n\n\t  isConstDeclTransform(obj) {\n\t    return this.isTransform(obj, _transforms.ConstDeclTransform);\n\t  }\n\n\t  isSyntaxDeclTransform(obj) {\n\t    return this.isTransform(obj, _transforms.SyntaxDeclTransform);\n\t  }\n\n\t  isSyntaxrecDeclTransform(obj) {\n\t    return this.isTransform(obj, _transforms.SyntaxrecDeclTransform);\n\t  }\n\n\t  isReturnStmtTransform(obj) {\n\t    return this.isTransform(obj, _transforms.ReturnStatementTransform);\n\t  }\n\n\t  isWhileTransform(obj) {\n\t    return this.isTransform(obj, _transforms.WhileTransform);\n\t  }\n\n\t  isForTransform(obj) {\n\t    return this.isTransform(obj, _transforms.ForTransform);\n\t  }\n\n\t  isSwitchTransform(obj) {\n\t    return this.isTransform(obj, _transforms.SwitchTransform);\n\t  }\n\n\t  isBreakTransform(obj) {\n\t    return this.isTransform(obj, _transforms.BreakTransform);\n\t  }\n\n\t  isContinueTransform(obj) {\n\t    return this.isTransform(obj, _transforms.ContinueTransform);\n\t  }\n\n\t  isDoTransform(obj) {\n\t    return this.isTransform(obj, _transforms.DoTransform);\n\t  }\n\n\t  isDebuggerTransform(obj) {\n\t    return this.isTransform(obj, _transforms.DebuggerTransform);\n\t  }\n\n\t  isWithTransform(obj) {\n\t    return this.isTransform(obj, _transforms.WithTransform);\n\t  }\n\n\t  isImportTransform(obj) {\n\t    return this.isTransform(obj, _transforms.ImportTransform);\n\t  }\n\n\t  isExportTransform(obj) {\n\t    return this.isTransform(obj, _transforms.ExportTransform);\n\t  }\n\n\t  isTryTransform(obj) {\n\t    return this.isTransform(obj, _transforms.TryTransform);\n\t  }\n\n\t  isThrowTransform(obj) {\n\t    return this.isTransform(obj, _transforms.ThrowTransform);\n\t  }\n\n\t  isOperatorDeclTransform(obj) {\n\t    return this.isTransform(obj, _transforms.OperatorDeclTransform);\n\t  }\n\n\t  isIfTransform(obj) {\n\t    return this.isTransform(obj, _transforms.IfTransform);\n\t  }\n\n\t  isNewTransform(obj) {\n\t    return this.isTransform(obj, _transforms.NewTransform);\n\t  }\n\n\t  isSuperTransform(obj) {\n\t    return this.isTransform(obj, _transforms.SuperTransform);\n\t  }\n\n\t  isThisTransform(obj) {\n\t    return this.isTransform(obj, _transforms.ThisTransform);\n\t  }\n\n\t  isClassTransform(obj) {\n\t    return this.isTransform(obj, _transforms.ClassTransform);\n\t  }\n\n\t  isYieldTransform(obj) {\n\t    return this.isTransform(obj, _transforms.YieldTransform);\n\t  }\n\n\t  isDefaultTransform(obj) {\n\t    return this.isTransform(obj, _transforms.DefaultTransform);\n\t  }\n\n\t  isCompiletimeTransform(obj) {\n\t    return this.isTransformInstance(obj, _transforms.CompiletimeTransform);\n\t  }\n\n\t  isModuleNamespaceTransform(obj) {\n\t    return this.isTransformInstance(obj, _transforms.ModuleNamespaceTransform);\n\t  }\n\n\t  isVarBindingTransform(obj) {\n\t    return this.isTransformInstance(obj, _transforms.VarBindingTransform);\n\t  }\n\n\t  getFromCompiletimeEnvironment(term) {\n\t    if (this.context.env.has(term.resolve(this.context.phase))) {\n\t      return this.context.env.get(term.resolve(this.context.phase));\n\t    }\n\t    return this.context.store.get(term.resolve(this.context.phase));\n\t  }\n\n\t  lineNumberEq(a, b) {\n\t    if (!(a && b)) {\n\t      return false;\n\t    }\n\t    return getLineNumber(a) === getLineNumber(b);\n\t  }\n\n\t  matchRawDelimiter() {\n\t    let lookahead = this.advance();\n\t    if (lookahead instanceof T.RawDelimiter) {\n\t      return lookahead.inner;\n\t    }\n\t    throw this.createError(lookahead, 'expecting a RawDelimiter');\n\t  }\n\n\t  matchRawSyntax() {\n\t    let lookahead = this.advance();\n\t    if (lookahead instanceof T.RawSyntax) {\n\t      return lookahead.value;\n\t    }\n\t    throw this.createError(lookahead, 'expecting a RawSyntax');\n\t  }\n\n\t  matchIdentifier(val) {\n\t    let lookahead = this.peek();\n\t    if (this.isIdentifier(lookahead, val)) {\n\t      return this.matchRawSyntax();\n\t    }\n\t    throw this.createError(lookahead, 'expecting an identifier');\n\t  }\n\n\t  matchKeyword(val) {\n\t    let lookahead = this.peek();\n\t    if (this.isKeyword(lookahead, val)) {\n\t      return this.matchRawSyntax();\n\t    }\n\t    throw this.createError(lookahead, 'expecting ' + val);\n\t  }\n\n\t  matchLiteral() {\n\t    let lookahead = this.peek();\n\t    if (this.isNumericLiteral(lookahead) || this.isStringLiteral(lookahead) || this.isBooleanLiteral(lookahead) || this.isNullLiteral(lookahead) || this.isTemplate(lookahead) || this.isRegularExpression(lookahead)) {\n\t      return this.matchRawSyntax();\n\t    }\n\t    throw this.createError(lookahead, 'expecting a literal');\n\t  }\n\n\t  matchStringLiteral() {\n\t    let lookahead = this.peek();\n\t    if (this.isStringLiteral(lookahead)) {\n\t      return this.matchRawSyntax();\n\t    }\n\t    throw this.createError(lookahead, 'expecting a string literal');\n\t  }\n\n\t  matchTemplate() {\n\t    let lookahead = this.peek();\n\t    if (this.isTemplate(lookahead)) {\n\t      return this.matchRawSyntax();\n\t    }\n\t    throw this.createError(lookahead, 'expecting a template literal');\n\t  }\n\n\t  matchParens() {\n\t    let lookahead = this.peek();\n\t    if (this.isParens(lookahead)) {\n\t      let inner = this.matchRawDelimiter();\n\t      return inner.slice(1, inner.size - 1);\n\t    }\n\t    throw this.createError(lookahead, 'expecting parens');\n\t  }\n\n\t  matchCurlies() {\n\t    let lookahead = this.peek();\n\t    if (this.isBraces(lookahead)) {\n\t      let inner = this.matchRawDelimiter();\n\t      return inner.slice(1, inner.size - 1);\n\t    }\n\t    throw this.createError(lookahead, 'expecting curly braces');\n\t  }\n\n\t  matchSquares() {\n\t    let lookahead = this.peek();\n\t    if (this.isBrackets(lookahead)) {\n\t      let inner = this.matchRawDelimiter();\n\t      return inner.slice(1, inner.size - 1);\n\t    }\n\t    throw this.createError(lookahead, 'expecting square braces');\n\t  }\n\n\t  matchUnaryOperator() {\n\t    let lookahead = this.matchRawSyntax();\n\t    if ((0, _operators.isUnaryOperator)(lookahead)) {\n\t      return lookahead;\n\t    }\n\t    throw this.createError(lookahead, 'expecting a unary operator');\n\t  }\n\n\t  matchPunctuator(val) {\n\t    let lookahead = this.matchRawSyntax();\n\t    if (this.isPunctuator(lookahead)) {\n\t      if (typeof val !== 'undefined') {\n\t        if (lookahead.val() === val) {\n\t          return lookahead;\n\t        } else {\n\t          throw this.createError(lookahead, 'expecting a ' + val + ' punctuator');\n\t        }\n\t      }\n\t      return lookahead;\n\t    }\n\t    throw this.createError(lookahead, 'expecting a punctuator');\n\t  }\n\n\t  createError(stx, message) {\n\t    let ctx = '';\n\t    let offending = stx;\n\t    if (this.rest.size > 0) {\n\t      ctx = this.rest.slice(0, 20).map(term => {\n\t        if (term instanceof T.RawDelimiter) {\n\t          return term.inner;\n\t        }\n\t        return _immutable.List.of(term);\n\t      }).flatten().map(s => {\n\t        let sval = s instanceof T.RawSyntax ? s.value.val() : s.toString();\n\t        if (s === offending) {\n\t          return '__' + sval + '__';\n\t        }\n\t        return sval;\n\t      }).join(' ');\n\t    } else {\n\t      ctx = offending.toString();\n\t    }\n\t    return new Error(message + '\\n' + ctx);\n\t  }\n\t}\n\texports.Enforester = Enforester;\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lbmZvcmVzdGVyLmpzIl0sIm5hbWVzIjpbIlQiLCJKdXN0IiwiTm90aGluZyIsIkVYUFJfTE9PUF9PUEVSQVRPUiIsIkVYUFJfTE9PUF9OT19DSEFOR0UiLCJFWFBSX0xPT1BfRVhQQU5TSU9OIiwiZ2V0TGluZU51bWJlciIsIngiLCJzdHgiLCJSYXdTeW50YXgiLCJ2YWx1ZSIsIlJhd0RlbGltaXRlciIsImlubmVyIiwiZmlyc3QiLCJFcnJvciIsImxpbmVOdW1iZXIiLCJFbmZvcmVzdGVyIiwiY29uc3RydWN0b3IiLCJzdHhsIiwicHJldiIsImNvbnRleHQiLCJkb25lIiwiaXNMaXN0IiwidGVybSIsInJlc3QiLCJwZWVrIiwibiIsImdldCIsImFkdmFuY2UiLCJyZXQiLCJlbmZvcmVzdCIsInR5cGUiLCJzaXplIiwiaXNFT0YiLCJFT0YiLCJyZXN1bHQiLCJlbmZvcmVzdEV4cHJlc3Npb25Mb29wIiwiZW5mb3Jlc3RNb2R1bGUiLCJlbmZvcmVzdEJvZHkiLCJlbmZvcmVzdE1vZHVsZUl0ZW0iLCJsb29rYWhlYWQiLCJpc0ltcG9ydFRyYW5zZm9ybSIsImVuZm9yZXN0SW1wb3J0RGVjbGFyYXRpb24iLCJpc0V4cG9ydFRyYW5zZm9ybSIsImVuZm9yZXN0RXhwb3J0RGVjbGFyYXRpb24iLCJlbmZvcmVzdFN0YXRlbWVudCIsImlzQ29tcGlsZXRpbWVUcmFuc2Zvcm0iLCJleHBhbmRNYWNybyIsImlzUHVuY3R1YXRvciIsIm1vZHVsZVNwZWNpZmllciIsImVuZm9yZXN0RnJvbUNsYXVzZSIsIkV4cG9ydEFsbEZyb20iLCJpc0JyYWNlcyIsIm5hbWVkRXhwb3J0cyIsImVuZm9yZXN0RXhwb3J0Q2xhdXNlIiwiaXNJZGVudGlmaWVyIiwiRXhwb3J0RnJvbSIsImlzQ2xhc3NUcmFuc2Zvcm0iLCJFeHBvcnQiLCJkZWNsYXJhdGlvbiIsImVuZm9yZXN0Q2xhc3MiLCJpc0V4cHIiLCJpc0ZuRGVjbFRyYW5zZm9ybSIsImVuZm9yZXN0RnVuY3Rpb24iLCJpc0RlZmF1bHRUcmFuc2Zvcm0iLCJFeHBvcnREZWZhdWx0IiwiYm9keSIsImluRGVmYXVsdCIsImNvbnN1bWVTZW1pY29sb24iLCJpc1ZhckRlY2xUcmFuc2Zvcm0iLCJpc0xldERlY2xUcmFuc2Zvcm0iLCJpc0NvbnN0RGVjbFRyYW5zZm9ybSIsImlzU3ludGF4cmVjRGVjbFRyYW5zZm9ybSIsImlzU3ludGF4RGVjbFRyYW5zZm9ybSIsImlzT3BlcmF0b3JEZWNsVHJhbnNmb3JtIiwiZW5mb3Jlc3RWYXJpYWJsZURlY2xhcmF0aW9uIiwiY3JlYXRlRXJyb3IiLCJlbmYiLCJtYXRjaEN1cmxpZXMiLCJwdXNoIiwiZW5mb3Jlc3RFeHBvcnRTcGVjaWZpZXIiLCJjb25zdW1lQ29tbWEiLCJuYW1lIiwiZW5mb3Jlc3RJZGVudGlmaWVyIiwiZXhwb3J0ZWROYW1lIiwiRXhwb3J0U3BlY2lmaWVyIiwiZGVmYXVsdEJpbmRpbmciLCJuYW1lZEltcG9ydHMiLCJmb3JTeW50YXgiLCJpc1N0cmluZ0xpdGVyYWwiLCJJbXBvcnQiLCJpc0tleXdvcmQiLCJlbmZvcmVzdEJpbmRpbmdJZGVudGlmaWVyIiwiaW1wb3J0cyIsImVuZm9yZXN0TmFtZWRJbXBvcnRzIiwiZnJvbUNsYXVzZSIsIm5hbWVzcGFjZUJpbmRpbmciLCJlbmZvcmVzdE5hbWVzcGFjZUJpbmRpbmciLCJJbXBvcnROYW1lc3BhY2UiLCJtYXRjaFB1bmN0dWF0b3IiLCJtYXRjaElkZW50aWZpZXIiLCJlbmZvcmVzdEltcG9ydFNwZWNpZmllcnMiLCJtYXRjaFJhd1N5bnRheCIsIkltcG9ydFNwZWNpZmllciIsImJpbmRpbmciLCJCaW5kaW5nSWRlbnRpZmllciIsIm1hdGNoU3RyaW5nTGl0ZXJhbCIsImVuZm9yZXN0U3RhdGVtZW50TGlzdEl0ZW0iLCJpc1Rlcm0iLCJTdGF0ZW1lbnQiLCJlbmZvcmVzdEJsb2NrU3RhdGVtZW50IiwiaXNXaGlsZVRyYW5zZm9ybSIsImVuZm9yZXN0V2hpbGVTdGF0ZW1lbnQiLCJpc0lmVHJhbnNmb3JtIiwiZW5mb3Jlc3RJZlN0YXRlbWVudCIsImlzRm9yVHJhbnNmb3JtIiwiZW5mb3Jlc3RGb3JTdGF0ZW1lbnQiLCJpc1N3aXRjaFRyYW5zZm9ybSIsImVuZm9yZXN0U3dpdGNoU3RhdGVtZW50IiwiaXNCcmVha1RyYW5zZm9ybSIsImVuZm9yZXN0QnJlYWtTdGF0ZW1lbnQiLCJpc0NvbnRpbnVlVHJhbnNmb3JtIiwiZW5mb3Jlc3RDb250aW51ZVN0YXRlbWVudCIsImlzRG9UcmFuc2Zvcm0iLCJlbmZvcmVzdERvU3RhdGVtZW50IiwiaXNEZWJ1Z2dlclRyYW5zZm9ybSIsImVuZm9yZXN0RGVidWdnZXJTdGF0ZW1lbnQiLCJpc1dpdGhUcmFuc2Zvcm0iLCJlbmZvcmVzdFdpdGhTdGF0ZW1lbnQiLCJpc1RyeVRyYW5zZm9ybSIsImVuZm9yZXN0VHJ5U3RhdGVtZW50IiwiaXNUaHJvd1RyYW5zZm9ybSIsImVuZm9yZXN0VGhyb3dTdGF0ZW1lbnQiLCJlbmZvcmVzdExhYmVsZWRTdGF0ZW1lbnQiLCJzdG10IiwiVmFyaWFibGVEZWNsYXJhdGlvblN0YXRlbWVudCIsImlzUmV0dXJuU3RtdFRyYW5zZm9ybSIsImVuZm9yZXN0UmV0dXJuU3RhdGVtZW50IiwiRW1wdHlTdGF0ZW1lbnQiLCJlbmZvcmVzdEV4cHJlc3Npb25TdGF0ZW1lbnQiLCJsYWJlbCIsIkxhYmVsZWRTdGF0ZW1lbnQiLCJtYXRjaEtleXdvcmQiLCJCcmVha1N0YXRlbWVudCIsImVuZm9yZXN0QmxvY2siLCJjYXRjaENsYXVzZSIsImVuZm9yZXN0Q2F0Y2hDbGF1c2UiLCJmaW5hbGl6ZXIiLCJUcnlGaW5hbGx5U3RhdGVtZW50IiwiVHJ5Q2F0Y2hTdGF0ZW1lbnQiLCJiaW5kaW5nUGFyZW5zIiwibWF0Y2hQYXJlbnMiLCJlbmZvcmVzdEJpbmRpbmdUYXJnZXQiLCJDYXRjaENsYXVzZSIsImV4cHJlc3Npb24iLCJlbmZvcmVzdEV4cHJlc3Npb24iLCJUaHJvd1N0YXRlbWVudCIsIm9ialBhcmVucyIsIm9iamVjdCIsIldpdGhTdGF0ZW1lbnQiLCJEZWJ1Z2dlclN0YXRlbWVudCIsInRlc3RCb2R5IiwidGVzdCIsIkRvV2hpbGVTdGF0ZW1lbnQiLCJrd2QiLCJDb250aW51ZVN0YXRlbWVudCIsImxpbmVOdW1iZXJFcSIsImNvbmQiLCJkaXNjcmltaW5hbnQiLCJTd2l0Y2hTdGF0ZW1lbnQiLCJjYXNlcyIsImVuZm9yZXN0U3dpdGNoQ2FzZXMiLCJkZWZhdWx0Q2FzZSIsImVuZm9yZXN0U3dpdGNoRGVmYXVsdCIsInBvc3REZWZhdWx0Q2FzZXMiLCJTd2l0Y2hTdGF0ZW1lbnRXaXRoRGVmYXVsdCIsInByZURlZmF1bHRDYXNlcyIsImVuZm9yZXN0U3dpdGNoQ2FzZSIsIlN3aXRjaENhc2UiLCJjb25zZXF1ZW50IiwiZW5mb3Jlc3RTd2l0Y2hDYXNlQm9keSIsImVuZm9yZXN0U3RhdGVtZW50TGlzdEluU3dpdGNoQ2FzZUJvZHkiLCJTd2l0Y2hEZWZhdWx0IiwiaW5pdCIsInJpZ2h0IiwibGVmdCIsInVwZGF0ZSIsImNuc3QiLCJGb3JTdGF0ZW1lbnQiLCJGb3JJblN0YXRlbWVudCIsIkZvck9mU3RhdGVtZW50Iiwia2luZCIsImFsdGVybmF0ZSIsIklmU3RhdGVtZW50IiwiV2hpbGVTdGF0ZW1lbnQiLCJCbG9ja1N0YXRlbWVudCIsImJsb2NrIiwiQmxvY2siLCJzdGF0ZW1lbnRzIiwia3ciLCJzdXByIiwiZnJvbUlkZW50aWZpZXIiLCJlbGVtZW50cyIsImlzU3RhdGljIiwibWV0aG9kT3JLZXkiLCJlbmZvcmVzdE1ldGhvZERlZmluaXRpb24iLCJ2YWwiLCJDbGFzc0VsZW1lbnQiLCJtZXRob2QiLCJDbGFzc0V4cHJlc3Npb24iLCJDbGFzc0RlY2xhcmF0aW9uIiwic3VwZXIiLCJhbGxvd1B1bmN0dWF0b3IiLCJpc0JyYWNrZXRzIiwiZW5mb3Jlc3RBcnJheUJpbmRpbmciLCJlbmZvcmVzdE9iamVjdEJpbmRpbmciLCJwcm9wZXJ0aWVzIiwiZW5mb3Jlc3RCaW5kaW5nUHJvcGVydHkiLCJPYmplY3RCaW5kaW5nIiwiZW5mb3Jlc3RQcm9wZXJ0eU5hbWUiLCJkZWZhdWx0VmFsdWUiLCJpc0Fzc2lnbiIsImV4cHIiLCJCaW5kaW5nUHJvcGVydHlJZGVudGlmaWVyIiwiZW5mb3Jlc3RCaW5kaW5nRWxlbWVudCIsIkJpbmRpbmdQcm9wZXJ0eVByb3BlcnR5IiwiYnJhY2tldCIsIm1hdGNoU3F1YXJlcyIsInJlc3RFbGVtZW50IiwiZWwiLCJBcnJheUJpbmRpbmciLCJCaW5kaW5nV2l0aERlZmF1bHQiLCJlbmZvcmVzdFB1bmN0dWF0b3IiLCJSZXR1cm5TdGF0ZW1lbnQiLCJkZWNscyIsImVuZm9yZXN0VmFyaWFibGVEZWNsYXJhdG9yIiwiaXNTeW50YXgiLCJpc09wZXJhdG9yIiwiY29uY2F0IiwiVmFyaWFibGVEZWNsYXJhdGlvbiIsImRlY2xhcmF0b3JzIiwiaWQiLCJBc3NvY1ZhbHVlcyIsImFzc29jIiwicHJlYyIsImluZGV4T2YiLCJqb2luIiwibWF0Y2hMaXRlcmFsIiwiT3BlcmF0b3JEZWNsYXJhdG9yIiwiVmFyaWFibGVEZWNsYXJhdG9yIiwic3RhcnQiLCJFeHByZXNzaW9uU3RhdGVtZW50Iiwib3BlcmF0b3IiLCJCaW5hcnlFeHByZXNzaW9uIiwib3BDdHgiLCJjb21iaW5lIiwic3RhY2siLCJlbmZvcmVzdEFzc2lnbm1lbnRFeHByZXNzaW9uIiwibGFzdCIsInBvcCIsImlzTW9kdWxlTmFtZXNwYWNlVHJhbnNmb3JtIiwibmFtZXNwYWNlIiwiZ2V0RnJvbUNvbXBpbGV0aW1lRW52aXJvbm1lbnQiLCJtb2QiLCJleHBvcnRlZE5hbWVzIiwiZmluZCIsImV4TmFtZSIsInVuc2hpZnQiLCJFeHByZXNzaW9uIiwiaXNZaWVsZFRyYW5zZm9ybSIsImVuZm9yZXN0WWllbGRFeHByZXNzaW9uIiwiaXNQYXJlbnMiLCJlbmZvcmVzdEFycm93RXhwcmVzc2lvbiIsImlzU3ludGF4VGVtcGxhdGUiLCJlbmZvcmVzdFN5bnRheFRlbXBsYXRlIiwiUGFyZW50aGVzaXplZEV4cHJlc3Npb24iLCJpc051bWVyaWNMaXRlcmFsIiwiaXNUZW1wbGF0ZSIsImlzQm9vbGVhbkxpdGVyYWwiLCJpc051bGxMaXRlcmFsIiwiaXNSZWd1bGFyRXhwcmVzc2lvbiIsImVuZm9yZXN0UHJpbWFyeUV4cHJlc3Npb24iLCJpc0N1c3RvbVByZWZpeE9wZXJhdG9yIiwiZW5mb3Jlc3RVbmFyeUV4cHJlc3Npb24iLCJpc1ZhckJpbmRpbmdUcmFuc2Zvcm0iLCJsb29rc3R4Iiwib2YiLCJpc05ld1RyYW5zZm9ybSIsImlzU3VwZXJUcmFuc2Zvcm0iLCJlbmZvcmVzdExlZnRIYW5kU2lkZUV4cHJlc3Npb24iLCJhbGxvd0NhbGwiLCJpc1VwZGF0ZU9wZXJhdG9yIiwiaXNDdXN0b21Qb3N0Zml4T3BlcmF0b3IiLCJlbmZvcmVzdFVwZGF0ZUV4cHJlc3Npb24iLCJlbmZvcmVzdFRlbXBsYXRlTGl0ZXJhbCIsImlzQ3VzdG9tQmluYXJ5T3BlcmF0b3IiLCJlbmZvcmVzdEJpbmFyeUV4cHJlc3Npb24iLCJ0cmFuc2Zvcm1EZXN0cnVjdHVyaW5nIiwib3AiLCJBc3NpZ25tZW50RXhwcmVzc2lvbiIsIkNvbXBvdW5kQXNzaWdubWVudEV4cHJlc3Npb24iLCJlbmZvcmVzdENvbmRpdGlvbmFsRXhwcmVzc2lvbiIsImVuZm9yZXN0VGhpc0V4cHJlc3Npb24iLCJlbmZvcmVzdElkZW50aWZpZXJFeHByZXNzaW9uIiwiZW5mb3Jlc3ROdW1lcmljTGl0ZXJhbCIsImVuZm9yZXN0U3RyaW5nTGl0ZXJhbCIsImVuZm9yZXN0Qm9vbGVhbkxpdGVyYWwiLCJlbmZvcmVzdE51bGxMaXRlcmFsIiwiZW5mb3Jlc3RSZWd1bGFyRXhwcmVzc2lvbkxpdGVyYWwiLCJlbmZvcmVzdE9iamVjdEV4cHJlc3Npb24iLCJlbmZvcmVzdEFycmF5RXhwcmVzc2lvbiIsIlN1cGVyIiwiZW5mb3Jlc3ROZXdFeHByZXNzaW9uIiwiaXNUaGlzVHJhbnNmb3JtIiwiZW5mb3Jlc3RDYWxsRXhwcmVzc2lvbiIsImVuZm9yZXN0Q29tcHV0ZWRNZW1iZXJFeHByZXNzaW9uIiwiZW5mb3Jlc3RTdGF0aWNNZW1iZXJFeHByZXNzaW9uIiwiSWRlbnRpZmllckV4cHJlc3Npb24iLCJMaXRlcmFsQm9vbGVhbkV4cHJlc3Npb24iLCJUZW1wbGF0ZUV4cHJlc3Npb24iLCJ0YWciLCJlbmZvcmVzdFRlbXBsYXRlRWxlbWVudHMiLCJMaXRlcmFsU3RyaW5nRXhwcmVzc2lvbiIsIm51bSIsIkxpdGVyYWxJbmZpbml0eUV4cHJlc3Npb24iLCJMaXRlcmFsTnVtZXJpY0V4cHJlc3Npb24iLCJyZVN0eCIsImxhc3RTbGFzaCIsInRva2VuIiwibGFzdEluZGV4T2YiLCJwYXR0ZXJuIiwic2xpY2UiLCJmbGFncyIsIkxpdGVyYWxSZWdFeHBFeHByZXNzaW9uIiwiTGl0ZXJhbE51bGxFeHByZXNzaW9uIiwiVGhpc0V4cHJlc3Npb24iLCJlbmZvcmVzdEFyZ3VtZW50TGlzdCIsImFyZyIsIlNwcmVhZEVsZW1lbnQiLCJOZXdUYXJnZXRFeHByZXNzaW9uIiwiY2FsbGVlIiwiYXJncyIsIk5ld0V4cHJlc3Npb24iLCJhcmd1bWVudHMiLCJDb21wdXRlZE1lbWJlckV4cHJlc3Npb24iLCJ0cmFuc2Zvcm1EZXN0cnVjdHVyaW5nV2l0aERlZmF1bHQiLCJtYXAiLCJ0IiwicGFyZW4iLCJDYWxsRXhwcmVzc2lvbkUiLCJwIiwicGFyYW1zIiwiZW5mb3Jlc3RGb3JtYWxQYXJhbWV0ZXJzIiwiQXJyb3dFeHByZXNzaW9uRSIsIkFycm93RXhwcmVzc2lvbiIsIllpZWxkRXhwcmVzc2lvbiIsImlzR2VuZXJhdG9yIiwiWWllbGRHZW5lcmF0b3JFeHByZXNzaW9uIiwiU3ludGF4VGVtcGxhdGUiLCJ0ZW1wbGF0ZSIsIm1hdGNoUmF3RGVsaW1pdGVyIiwicHJvcGVydHkiLCJTdGF0aWNNZW1iZXJFeHByZXNzaW9uIiwiYXJyIiwiaXNTcHJlYWQiLCJBcnJheUV4cHJlc3Npb24iLCJvYmoiLCJsYXN0UHJvcCIsInByb3AiLCJlbmZvcmVzdFByb3BlcnR5RGVmaW5pdGlvbiIsIk9iamVjdEV4cHJlc3Npb24iLCJTaG9ydGhhbmRQcm9wZXJ0eSIsIkRhdGFQcm9wZXJ0eSIsImlzUHJvcGVydHlOYW1lIiwiR2V0dGVyIiwicGFyYW0iLCJTZXR0ZXIiLCJmb3JtYWxQYXJhbXMiLCJNZXRob2QiLCJTdGF0aWNQcm9wZXJ0eU5hbWUiLCJDb21wdXRlZFByb3BlcnR5TmFtZSIsImZuS2V5d29yZCIsIkZ1bmN0aW9uRXhwcmVzc2lvbkUiLCJGdW5jdGlvbkRlY2xhcmF0aW9uRSIsIml0ZW1zIiwiZW5mb3Jlc3RQYXJhbSIsIkZvcm1hbFBhcmFtZXRlcnMiLCJsZWZ0VGVybSIsIm9wZXJhdG9yVHJhbnNmb3JtIiwiZiIsImNhbGwiLCJVcGRhdGVFeHByZXNzaW9uIiwiaXNQcmVmaXgiLCJvcGVyYW5kIiwicmlnaHRUZXJtIiwiZXhwYW5kT3BlcmF0b3IiLCJVbmFyeUV4cHJlc3Npb24iLCJDb25kaXRpb25hbEV4cHJlc3Npb24iLCJvcFN0eCIsIm1hdGNoVGVtcGxhdGUiLCJpdCIsImlzRGVsaW1pdGVyIiwiVGVtcGxhdGVFbGVtZW50IiwicmF3VmFsdWUiLCJ0ZXh0Iiwic3ludGF4VHJhbnNmb3JtIiwicmVzb2x2ZSIsInBoYXNlIiwidXNlU2l0ZVNjb3BlIiwiaW50cm9kdWNlZFNjb3BlIiwidXNlU2NvcGUiLCJjdHgiLCJzY29wZVJlZHVjZXIiLCJzY29wZSIsImZsaXAiLCJiaW5kaW5ncyIsInRlcm1zIiwicmVkdWNlIiwiX3Jlc3QiLCJhcHBseSIsInNhZmVDaGVjayIsIm1hdGNoIiwic2FmZVJlc29sdmUiLCJpc1RyYW5zZm9ybSIsInRyYW5zIiwiZW52Iiwic3RvcmUiLCJnZXRPckVsc2UiLCJpc1RyYW5zZm9ybUluc3RhbmNlIiwiaGFzIiwiYSIsImIiLCJtYXRjaFVuYXJ5T3BlcmF0b3IiLCJtZXNzYWdlIiwib2ZmZW5kaW5nIiwiZmxhdHRlbiIsInMiLCJzdmFsIiwidG9TdHJpbmciXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFDQTs7QUFLQTs7SUFBa0JBLEM7O0FBQ2xCOztBQUNBOzs7O0FBSUE7O0FBZ0NBOztBQUNBOztBQUNBOztBQU9BOzs7O0FBR0E7O0FBQ0E7O0FB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O0FBQ0Q7QUFDRCxVQUFNLEtBQUtvQyxXQUFMLENBQWlCcEMsU0FBakIsRUFBNEIsd0JBQTVCLENBQU47QUFDRDs7QUFFRG9DLGNBQVlwRSxHQUFaLEVBQWdDeWEsT0FBaEMsRUFBaUQ7QUFDL0MsUUFBSXRCLE1BQU0sRUFBVjtBQUNBLFFBQUl1QixZQUFZMWEsR0FBaEI7QUFDQSxRQUFJLEtBQUtnQixJQUFMLENBQVVRLElBQVYsR0FBaUIsQ0FBckIsRUFBd0I7QUFDdEIyWCxZQUFNLEtBQUtuWSxJQUFMLENBQ0htVCxLQURHLENBQ0csQ0FESCxFQUNNLEVBRE4sRUFFSGUsR0FGRyxDQUVDblUsUUFBUTtBQUNYLFlBQUlBLGdCQUFnQnZCLEVBQUVXLFlBQXRCLEVBQW9DO0FBQ2xDLGlCQUFPWSxLQUFLWCxLQUFaO0FBQ0Q7QUFDRCxlQUFPLGdCQUFLa1IsRUFBTCxDQUFRdlEsSUFBUixDQUFQO0FBQ0QsT0FQRyxFQVFINFosT0FSRyxHQVNIekYsR0FURyxDQVNDMEYsS0FBSztBQUNSLFlBQUlDLE9BQU9ELGFBQWFwYixFQUFFUyxTQUFmLEdBQTJCMmEsRUFBRTFhLEtBQUYsQ0FBUW9NLEdBQVIsRUFBM0IsR0FBMkNzTyxFQUFFRSxRQUFGLEVBQXREO0FBQ0EsWUFBSUYsTUFBTUYsU0FBVixFQUFxQjtBQUNuQixpQkFBTyxPQUFPRyxJQUFQLEdBQWMsSUFBckI7QUFDRDtBQUNELGVBQU9BLElBQVA7QUFDRCxPQWZHLEVBZ0JIL0wsSUFoQkcsQ0FnQkUsR0FoQkYsQ0FBTjtBQWlCRCxLQWxCRCxNQWtCTztBQUNMcUssWUFBTXVCLFVBQVVJLFFBQVYsRUFBTjtBQUNEO0FBQ0QsV0FBTyxJQUFJeGEsS0FBSixDQUFVbWEsVUFBVSxJQUFWLEdBQWlCdEIsR0FBM0IsQ0FBUDtBQUNEO0FBcGtGcUI7UUFBWDNZLFUsR0FBQUEsVSIsImZpbGUiOiJlbmZvcmVzdGVyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbmltcG9ydCB7XG4gIGlzSWRlbnRpZmllckV4cHJlc3Npb24sXG4gIGlzU3RhdGljTWVtYmVyRXhwcmVzc2lvbixcbiAgaXNDb21wdXRlZE1lbWJlckV4cHJlc3Npb24sXG59IGZyb20gJy4vdGVybXMnO1xuaW1wb3J0IFRlcm0sICogYXMgVCBmcm9tICdzd2VldC1zcGVjJztcbmltcG9ydCB7IE1heWJlIH0gZnJvbSAncmFtZGEtZmFudGFzeSc7XG5pbXBvcnQgU2NvcGVSZWR1Y2VyIGZyb20gJy4vc2NvcGUtcmVkdWNlcic7XG5jb25zdCBKdXN0ID0gTWF5YmUuSnVzdDtcbmNvbnN0IE5vdGhpbmcgPSBNYXliZS5Ob3RoaW5nO1xuXG5pbXBvcnQge1xuICBGdW5jdGlvbkRlY2xUcmFuc2Zvcm0sXG4gIFZhcmlhYmxlRGVjbFRyYW5zZm9ybSxcbiAgTmV3VHJhbnNmb3JtLFxuICBMZXREZWNsVHJhbnNmb3JtLFxuICBDb25zdERlY2xUcmFuc2Zvcm0sXG4gIFN5bnRheERlY2xUcmFuc2Zvcm0sXG4gIFN5bnRheHJlY0RlY2xUcmFuc2Zvcm0sXG4gIE9wZXJhdG9yRGVjbFRyYW5zZm9ybSxcbiAgUmV0dXJuU3RhdGVtZW50VHJhbnNmb3JtLFxuICBXaGlsZVRyYW5zZm9ybSxcbiAgSWZUcmFuc2Zvcm0sXG4gIEZvclRyYW5zZm9ybSxcbiAgU3dpdGNoVHJhbnNmb3JtLFxuICBCcmVha1RyYW5zZm9ybSxcbiAgQ29udGludWVUcmFuc2Zvcm0sXG4gIERvVHJhbnNmb3JtLFxuICBEZWJ1Z2dlclRyYW5zZm9ybSxcbiAgWWllbGRUcmFuc2Zvcm0sXG4gIFdpdGhUcmFuc2Zvcm0sXG4gIEltcG9ydFRyYW5zZm9ybSxcbiAgRXhwb3J0VHJhbnNmb3JtLFxuICBTdXBlclRyYW5zZm9ybSxcbiAgVGhpc1RyYW5zZm9ybSxcbiAgQ2xhc3NUcmFuc2Zvcm0sXG4gIERlZmF1bHRUcmFuc2Zvcm0sXG4gIFRyeVRyYW5zZm9ybSxcbiAgVGhyb3dUcmFuc2Zvcm0sXG4gIENvbXBpbGV0aW1lVHJhbnNmb3JtLFxuICBWYXJCaW5kaW5nVHJhbnNmb3JtLFxuICBNb2R1bGVOYW1lc3BhY2VUcmFuc2Zvcm0sXG59IGZyb20gJy4vdHJhbnNmb3Jtcyc7XG5pbXBvcnQgeyBMaXN0IH0gZnJvbSAnaW1tdXRhYmxlJztcbmltcG9ydCB7IGV4cGVjdCwgYXNzZXJ0IH0gZnJvbSAnLi9lcnJvcnMnO1xuaW1wb3J0IHtcbiAgaXNPcGVyYXRvcixcbiAgaXNVbmFyeU9wZXJhdG9yLFxuICBnZXRPcGVyYXRvckFzc29jLFxuICBnZXRPcGVyYXRvclByZWMsXG4gIG9wZXJhdG9yTHQsXG59IGZyb20gJy4vb3BlcmF0b3JzJztcbmltcG9ydCBTeW50YXgsIHsgQUxMX1BIQVNFUyB9IGZyb20gJy4vc3ludGF4JztcbmltcG9ydCB0eXBlIHsgU3ltYm9sQ2xhc3MgfSBmcm9tICcuL3N5bWJvbCc7XG5cbmltcG9ydCB7IGZyZXNoU2NvcGUgfSBmcm9tICcuL3Njb3BlJztcbmltcG9ydCB7IHNhbml0aXplUmVwbGFjZW1lbnRWYWx1ZXMgfSBmcm9tICcuL2xvYWQtc3ludGF4JztcblxuaW1wb3J0IE1hY3JvQ29udGV4dCBmcm9tICcuL21hY3JvLWNvbnRleHQnO1xuXG5jb25zdCBFWFBSX0xPT1BfT1BFUkFUT1IgPSB7fTtcbmNvbnN0IEVYUFJfTE9PUF9OT19DSEFOR0UgPSB7fTtcbmNvbnN0IEVYUFJfTE9PUF9FWFBBTlNJT04gPSB7fTtcblxuZnVuY3Rpb24gZ2V0TGluZU51bWJlcih4OiBTeW50YXggfCBULlRlcm0pIHtcbiAgbGV0IHN0eDtcbiAgaWYgKHggaW5zdGFuY2VvZiBTeW50YXgpIHtcbiAgICBzdHggPSB4O1xuICB9IGVsc2UgaWYgKHggaW5zdGFuY2VvZiBULlJhd1N5bnRheCkge1xuICAgIHN0eCA9IHgudmFsdWU7XG4gIH0gZWxzZSBpZiAoeCBpbnN0YW5jZW9mIFQuUmF3RGVsaW1pdGVyKSB7XG4gICAgcmV0dXJuIGdldExpbmVOdW1iZXIoeC5pbm5lci5maXJzdCgpKTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYE5vdCBpbXBsZW1lbnRlZCB5ZXQgJHt4fWApO1xuICB9XG4gIHJldHVybiBzdHgubGluZU51bWJlcigpO1xufVxuXG5leHBvcnQgY2xhc3MgRW5mb3Jlc3RlciB7XG4gIGRvbmU6IGJvb2xlYW47XG4gIHRlcm06ID9UZXJtO1xuICByZXN0OiBMaXN0PFRlcm0+O1xuICBwcmV2OiBMaXN0PFRlcm0+O1xuICBjb250ZXh0OiB7XG4gICAgZW52OiBNYXA8c3RyaW5nLCBhbnk+LFxuICAgIHN0b3JlOiBNYXA8c3RyaW5nLCBhbnk+LFxuICAgIHBoYXNlOiBudW1iZXIgfCB7fSxcbiAgICB1c2VTY29wZTogU3ltYm9sQ2xhc3MsXG4gICAgYmluZGluZ3M6IGFueSxcbiAgfTtcbiAgb3BDdHg6IHtcbiAgICBwcmVjOiBudW1iZXIsXG4gICAgY29tYmluZTogKHg6IGFueSkgPT4gYW55LFxuICAgIHN0YWNrOiBMaXN0PCo+LFxuICB9O1xuXG4gIGNvbnN0cnVjdG9yKHN0eGw6IExpc3Q8VGVybT4sIHByZXY6IExpc3Q8VGVybT4sIGNvbnRleHQ6IGFueSkge1xuICAgIHRoaXMuZG9uZSA9IGZhbHNlO1xuICAgIGFzc2VydChMaXN0LmlzTGlzdChzdHhsKSwgJ2V4cGVjdGluZyBhIGxpc3Qgb2YgdGVybXMgdG8gZW5mb3Jlc3QnKTtcbiAgICBhc3NlcnQoTGlzdC5pc0xpc3QocHJldiksICdleHBlY3RpbmcgYSBsaXN0IG9mIHRlcm1zIHRvIGVuZm9yZXN0Jyk7XG4gICAgYXNzZXJ0KGNvbnRleHQsICdleHBlY3RpbmcgYSBjb250ZXh0IHRvIGVuZm9yZXN0Jyk7XG4gICAgdGhpcy50ZXJtID0gbnVsbDtcblxuICAgIHRoaXMucmVzdCA9IHN0eGw7XG4gICAgdGhpcy5wcmV2ID0gcHJldjtcblxuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gIH1cblxuICBwZWVrKG46IG51bWJlciA9IDApOiA/VGVybSB7XG4gICAgcmV0dXJuIHRoaXMucmVzdC5nZXQobik7XG4gIH1cblxuICBhZHZhbmNlKCkge1xuICAgIGxldCByZXQ6ID9UZXJtID0gdGhpcy5yZXN0LmZpcnN0KCk7XG4gICAgdGhpcy5yZXN0ID0gdGhpcy5yZXN0LnJlc3QoKTtcbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgLypcbiAgIGVuZm9yZXN0IHdvcmtzIG92ZXI6XG4gICBwcmV2IC0gYSBsaXN0IG9mIHRoZSBwcmV2aW91c2x5IGVuZm9yZXN0IFRlcm1zXG4gICB0ZXJtIC0gdGhlIGN1cnJlbnQgdGVybSBiZWluZyBlbmZvcmVzdGVkIChpbml0aWFsbHkgbnVsbClcbiAgIHJlc3QgLSByZW1haW5pbmcgVGVybXMgdG8gZW5mb3Jlc3RcbiAgICovXG4gIGVuZm9yZXN0KHR5cGU/OiAnZXhwcmVzc2lvbicgfCAnTW9kdWxlJyA9ICdNb2R1bGUnKSB7XG4gICAgLy8gaW5pdGlhbGl6ZSB0aGUgdGVybVxuICAgIHRoaXMudGVybSA9IG51bGw7XG5cbiAgICBpZiAodGhpcy5yZXN0LnNpemUgPT09IDApIHtcbiAgICAgIHRoaXMuZG9uZSA9IHRydWU7XG4gICAgICByZXR1cm4gdGhpcy50ZXJtO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzRU9GKHRoaXMucGVlaygpKSkge1xuICAgICAgdGhpcy50ZXJtID0gbmV3IFQuRU9GKHt9KTtcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgcmV0dXJuIHRoaXMudGVybTtcbiAgICB9XG5cbiAgICBsZXQgcmVzdWx0O1xuICAgIGlmICh0eXBlID09PSAnZXhwcmVzc2lvbicpIHtcbiAgICAgIHJlc3VsdCA9IHRoaXMuZW5mb3Jlc3RFeHByZXNzaW9uTG9vcCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQgPSB0aGlzLmVuZm9yZXN0TW9kdWxlKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucmVzdC5zaXplID09PSAwKSB7XG4gICAgICB0aGlzLmRvbmUgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgZW5mb3Jlc3RNb2R1bGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuZW5mb3Jlc3RCb2R5KCk7XG4gIH1cblxuICBlbmZvcmVzdEJvZHkoKSB7XG4gICAgcmV0dXJuIHRoaXMuZW5mb3Jlc3RNb2R1bGVJdGVtKCk7XG4gIH1cblxuICBlbmZvcmVzdE1vZHVsZUl0ZW0oKSB7XG4gICAgbGV0IGxvb2thaGVhZCA9IHRoaXMucGVlaygpO1xuXG4gICAgaWYgKHRoaXMuaXNJbXBvcnRUcmFuc2Zvcm0obG9va2FoZWFkKSkge1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICByZXR1cm4gdGhpcy5lbmZvcmVzdEltcG9ydERlY2xhcmF0aW9uKCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmlzRXhwb3J0VHJhbnNmb3JtKGxvb2thaGVhZCkpIHtcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgcmV0dXJuIHRoaXMuZW5mb3Jlc3RFeHBvcnREZWNsYXJhdGlvbigpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5lbmZvcmVzdFN0YXRlbWVudCgpO1xuICB9XG5cbiAgZW5mb3Jlc3RFeHBvcnREZWNsYXJhdGlvbigpIHtcbiAgICBsZXQgbG9va2FoZWFkID0gdGhpcy5wZWVrKCk7XG4gICAgaWYgKHRoaXMuaXNDb21waWxldGltZVRyYW5zZm9ybShsb29rYWhlYWQpKSB7XG4gICAgICB0aGlzLmV4cGFuZE1hY3JvKCk7XG4gICAgICBsb29rYWhlYWQgPSB0aGlzLnBlZWsoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc1B1bmN0dWF0b3IobG9va2FoZWFkLCAnKicpKSB7XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIGxldCBtb2R1bGVTcGVjaWZpZXIgPSB0aGlzLmVuZm9yZXN0RnJvbUNsYXVzZSgpO1xuICAgICAgcmV0dXJuIG5ldyBULkV4cG9ydEFsbEZyb20oeyBtb2R1bGVTcGVjaWZpZXIgfSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmlzQnJhY2VzKGxvb2thaGVhZCkpIHtcbiAgICAgIGxldCBuYW1lZEV4cG9ydHMgPSB0aGlzLmVuZm9yZXN0RXhwb3J0Q2xhdXNlKCk7XG4gICAgICBsZXQgbW9kdWxlU3BlY2lmaWVyID0gbnVsbDtcbiAgICAgIGlmICh0aGlzLmlzSWRlbnRpZmllcih0aGlzLnBlZWsoKSwgJ2Zyb20nKSkge1xuICAgICAgICBtb2R1bGVTcGVjaWZpZXIgPSB0aGlzLmVuZm9yZXN0RnJvbUNsYXVzZSgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBULkV4cG9ydEZyb20oeyBuYW1lZEV4cG9ydHMsIG1vZHVsZVNwZWNpZmllciB9KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuaXNDbGFzc1RyYW5zZm9ybShsb29rYWhlYWQpKSB7XG4gICAgICByZXR1cm4gbmV3IFQuRXhwb3J0KHtcbiAgICAgICAgZGVjbGFyYXRpb246IHRoaXMuZW5mb3Jlc3RDbGFzcyh7IGlzRXhwcjogZmFsc2UgfSksXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuaXNGbkRlY2xUcmFuc2Zvcm0obG9va2FoZWFkKSkge1xuICAgICAgcmV0dXJuIG5ldyBULkV4cG9ydCh7XG4gICAgICAgIGRlY2xhcmF0aW9uOiB0aGlzLmVuZm9yZXN0RnVuY3Rpb24oeyBpc0V4cHI6IGZhbHNlIH0pLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmlzRGVmYXVsdFRyYW5zZm9ybShsb29rYWhlYWQpKSB7XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIGlmICh0aGlzLmlzQ29tcGlsZXRpbWVUcmFuc2Zvcm0obG9va2FoZWFkKSkge1xuICAgICAgICB0aGlzLmV4cGFuZE1hY3JvKCk7XG4gICAgICAgIGxvb2thaGVhZCA9IHRoaXMucGVlaygpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5pc0ZuRGVjbFRyYW5zZm9ybSh0aGlzLnBlZWsoKSkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBULkV4cG9ydERlZmF1bHQoe1xuICAgICAgICAgIGJvZHk6IHRoaXMuZW5mb3Jlc3RGdW5jdGlvbih7IGlzRXhwcjogZmFsc2UsIGluRGVmYXVsdDogdHJ1ZSB9KSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuaXNDbGFzc1RyYW5zZm9ybSh0aGlzLnBlZWsoKSkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBULkV4cG9ydERlZmF1bHQoe1xuICAgICAgICAgIGJvZHk6IHRoaXMuZW5mb3Jlc3RDbGFzcyh7IGlzRXhwcjogZmFsc2UsIGluRGVmYXVsdDogdHJ1ZSB9KSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZXQgYm9keSA9IHRoaXMuZW5mb3Jlc3RFeHByZXNzaW9uTG9vcCgpO1xuICAgICAgICB0aGlzLmNvbnN1bWVTZW1pY29sb24oKTtcbiAgICAgICAgcmV0dXJuIG5ldyBULkV4cG9ydERlZmF1bHQoeyBib2R5IH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoXG4gICAgICB0aGlzLmlzVmFyRGVjbFRyYW5zZm9ybShsb29rYWhlYWQpIHx8XG4gICAgICB0aGlzLmlzTGV0RGVjbFRyYW5zZm9ybShsb29rYWhlYWQpIHx8XG4gICAgICB0aGlzLmlzQ29uc3REZWNsVHJhbnNmb3JtKGxvb2thaGVhZCkgfHxcbiAgICAgIHRoaXMuaXNTeW50YXhyZWNEZWNsVHJhbnNmb3JtKGxvb2thaGVhZCkgfHxcbiAgICAgIHRoaXMuaXNTeW50YXhEZWNsVHJhbnNmb3JtKGxvb2thaGVhZCkgfHxcbiAgICAgIHRoaXMuaXNPcGVyYXRvckRlY2xUcmFuc2Zvcm0obG9va2FoZWFkKVxuICAgICkge1xuICAgICAgcmV0dXJuIG5ldyBULkV4cG9ydCh7XG4gICAgICAgIGRlY2xhcmF0aW9uOiB0aGlzLmVuZm9yZXN0VmFyaWFibGVEZWNsYXJhdGlvbigpLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHRocm93IHRoaXMuY3JlYXRlRXJyb3IobG9va2FoZWFkLCAndW5leHBlY3RlZCBzeW50YXgnKTtcbiAgfVxuXG4gIGVuZm9yZXN0RXhwb3J0Q2xhdXNlKCkge1xuICAgIGxldCBlbmYgPSBuZXcgRW5mb3Jlc3Rlcih0aGlzLm1hdGNoQ3VybGllcygpLCBMaXN0KCksIHRoaXMuY29udGV4dCk7XG4gICAgbGV0IHJlc3VsdCA9IFtdO1xuICAgIHdoaWxlIChlbmYucmVzdC5zaXplICE9PSAwKSB7XG4gICAgICByZXN1bHQucHVzaChlbmYuZW5mb3Jlc3RFeHBvcnRTcGVjaWZpZXIoKSk7XG4gICAgICBlbmYuY29uc3VtZUNvbW1hKCk7XG4gICAgfVxuICAgIHJldHVybiBMaXN0KHJlc3VsdCk7XG4gIH1cblxuICBlbmZvcmVzdEV4cG9ydFNwZWNpZmllcigpIHtcbiAgICBsZXQgbmFtZSA9IHRoaXMuZW5mb3Jlc3RJZGVudGlmaWVyKCk7XG4gICAgaWYgKHRoaXMuaXNJZGVudGlmaWVyKHRoaXMucGVlaygpLCAnYXMnKSkge1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICBsZXQgZXhwb3J0ZWROYW1lID0gdGhpcy5lbmZvcmVzdElkZW50aWZpZXIoKTtcbiAgICAgIHJldHVybiBuZXcgVC5FeHBvcnRTcGVjaWZpZXIoeyBuYW1lLCBleHBvcnRlZE5hbWUgfSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgVC5FeHBvcnRTcGVjaWZpZXIoe1xuICAgICAgbmFtZTogbnVsbCxcbiAgICAgIGV4cG9ydGVkTmFtZTogbmFtZSxcbiAgICB9KTtcbiAgfVxuXG4gIGVuZm9yZXN0SW1wb3J0RGVjbGFyYXRpb24oKSB7XG4gICAgbGV0IGxvb2thaGVhZCA9IHRoaXMucGVlaygpO1xuICAgIGxldCBkZWZhdWx0QmluZGluZyA9IG51bGw7XG4gICAgbGV0IG5hbWVkSW1wb3J0cyA9IExpc3QoKTtcbiAgICBsZXQgZm9yU3ludGF4ID0gZmFsc2U7XG5cbiAgICBpZiAodGhpcy5pc1N0cmluZ0xpdGVyYWwobG9va2FoZWFkKSkge1xuICAgICAgbGV0IG1vZHVsZVNwZWNpZmllciA9IHRoaXMuYWR2YW5jZSgpO1xuICAgICAgdGhpcy5jb25zdW1lU2VtaWNvbG9uKCk7XG4gICAgICByZXR1cm4gbmV3IFQuSW1wb3J0KHtcbiAgICAgICAgZGVmYXVsdEJpbmRpbmcsXG4gICAgICAgIG5hbWVkSW1wb3J0cyxcbiAgICAgICAgbW9kdWxlU3BlY2lmaWVyLFxuICAgICAgICBmb3JTeW50YXgsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc0lkZW50aWZpZXIobG9va2FoZWFkKSB8fCB0aGlzLmlzS2V5d29yZChsb29rYWhlYWQpKSB7XG4gICAgICBkZWZhdWx0QmluZGluZyA9IHRoaXMuZW5mb3Jlc3RCaW5kaW5nSWRlbnRpZmllcigpO1xuICAgICAgaWYgKCF0aGlzLmlzUHVuY3R1YXRvcih0aGlzLnBlZWsoKSwgJywnKSkge1xuICAgICAgICBsZXQgbW9kdWxlU3BlY2lmaWVyID0gdGhpcy5lbmZvcmVzdEZyb21DbGF1c2UoKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRoaXMuaXNLZXl3b3JkKHRoaXMucGVlaygpLCAnZm9yJykgJiZcbiAgICAgICAgICB0aGlzLmlzSWRlbnRpZmllcih0aGlzLnBlZWsoMSksICdzeW50YXgnKVxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgICAgICBmb3JTeW50YXggPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBULkltcG9ydCh7XG4gICAgICAgICAgZGVmYXVsdEJpbmRpbmcsXG4gICAgICAgICAgbW9kdWxlU3BlY2lmaWVyLFxuICAgICAgICAgIG5hbWVkSW1wb3J0czogTGlzdCgpLFxuICAgICAgICAgIGZvclN5bnRheCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuY29uc3VtZUNvbW1hKCk7XG4gICAgbG9va2FoZWFkID0gdGhpcy5wZWVrKCk7XG4gICAgaWYgKHRoaXMuaXNCcmFjZXMobG9va2FoZWFkKSkge1xuICAgICAgbGV0IGltcG9ydHMgPSB0aGlzLmVuZm9yZXN0TmFtZWRJbXBvcnRzKCk7XG4gICAgICBsZXQgZnJvbUNsYXVzZSA9IHRoaXMuZW5mb3Jlc3RGcm9tQ2xhdXNlKCk7XG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMuaXNLZXl3b3JkKHRoaXMucGVlaygpLCAnZm9yJykgJiZcbiAgICAgICAgdGhpcy5pc0lkZW50aWZpZXIodGhpcy5wZWVrKDEpLCAnc3ludGF4JylcbiAgICAgICkge1xuICAgICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICAgIGZvclN5bnRheCA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuZXcgVC5JbXBvcnQoe1xuICAgICAgICBkZWZhdWx0QmluZGluZyxcbiAgICAgICAgZm9yU3ludGF4LFxuICAgICAgICBuYW1lZEltcG9ydHM6IGltcG9ydHMsXG4gICAgICAgIG1vZHVsZVNwZWNpZmllcjogZnJvbUNsYXVzZSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAodGhpcy5pc1B1bmN0dWF0b3IobG9va2FoZWFkLCAnKicpKSB7XG4gICAgICBsZXQgbmFtZXNwYWNlQmluZGluZyA9IHRoaXMuZW5mb3Jlc3ROYW1lc3BhY2VCaW5kaW5nKCk7XG4gICAgICBsZXQgbW9kdWxlU3BlY2lmaWVyID0gdGhpcy5lbmZvcmVzdEZyb21DbGF1c2UoKTtcbiAgICAgIGlmIChcbiAgICAgICAgdGhpcy5pc0tleXdvcmQodGhpcy5wZWVrKCksICdmb3InKSAmJlxuICAgICAgICB0aGlzLmlzSWRlbnRpZmllcih0aGlzLnBlZWsoMSksICdzeW50YXgnKVxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgICAgZm9yU3ludGF4ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXcgVC5JbXBvcnROYW1lc3BhY2Uoe1xuICAgICAgICBkZWZhdWx0QmluZGluZyxcbiAgICAgICAgZm9yU3ludGF4LFxuICAgICAgICBuYW1lc3BhY2VCaW5kaW5nLFxuICAgICAgICBtb2R1bGVTcGVjaWZpZXIsXG4gICAgICB9KTtcbiAgICB9XG4gICAgdGhyb3cgdGhpcy5jcmVhdGVFcnJvcihsb29rYWhlYWQsICd1bmV4cGVjdGVkIHN5bnRheCcpO1xuICB9XG5cbiAgZW5mb3Jlc3ROYW1lc3BhY2VCaW5kaW5nKCkge1xuICAgIHRoaXMubWF0Y2hQdW5jdHVhdG9yKCcqJyk7XG4gICAgdGhpcy5tYXRjaElkZW50aWZpZXIoJ2FzJyk7XG4gICAgcmV0dXJuIHRoaXMuZW5mb3Jlc3RCaW5kaW5nSWRlbnRpZmllcigpO1xuICB9XG5cbiAgZW5mb3Jlc3ROYW1lZEltcG9ydHMoKSB7XG4gICAgbGV0IGVuZiA9IG5ldyBFbmZvcmVzdGVyKHRoaXMubWF0Y2hDdXJsaWVzKCksIExpc3QoKSwgdGhpcy5jb250ZXh0KTtcbiAgICBsZXQgcmVzdWx0ID0gW107XG4gICAgd2hpbGUgKGVuZi5yZXN0LnNpemUgIT09IDApIHtcbiAgICAgIHJlc3VsdC5wdXNoKGVuZi5lbmZvcmVzdEltcG9ydFNwZWNpZmllcnMoKSk7XG4gICAgICBlbmYuY29uc3VtZUNvbW1hKCk7XG4gICAgfVxuICAgIHJldHVybiBMaXN0KHJlc3VsdCk7XG4gIH1cblxuICBlbmZvcmVzdEltcG9ydFNwZWNpZmllcnMoKSB7XG4gICAgbGV0IGxvb2thaGVhZCA9IHRoaXMucGVlaygpO1xuICAgIGxldCBuYW1lO1xuICAgIGlmICh0aGlzLmlzSWRlbnRpZmllcihsb29rYWhlYWQpIHx8IHRoaXMuaXNLZXl3b3JkKGxvb2thaGVhZCkpIHtcbiAgICAgIG5hbWUgPSB0aGlzLm1hdGNoUmF3U3ludGF4KCk7XG4gICAgICBpZiAoIXRoaXMuaXNJZGVudGlmaWVyKHRoaXMucGVlaygpLCAnYXMnKSkge1xuICAgICAgICByZXR1cm4gbmV3IFQuSW1wb3J0U3BlY2lmaWVyKHtcbiAgICAgICAgICBuYW1lOiBudWxsLFxuICAgICAgICAgIGJpbmRpbmc6IG5ldyBULkJpbmRpbmdJZGVudGlmaWVyKHtcbiAgICAgICAgICAgIG5hbWU6IG5hbWUsXG4gICAgICAgICAgfSksXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5tYXRjaElkZW50aWZpZXIoJ2FzJyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IHRoaXMuY3JlYXRlRXJyb3IobG9va2FoZWFkLCAndW5leHBlY3RlZCB0b2tlbiBpbiBpbXBvcnQgc3BlY2lmaWVyJyk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgVC5JbXBvcnRTcGVjaWZpZXIoe1xuICAgICAgbmFtZSxcbiAgICAgIGJpbmRpbmc6IHRoaXMuZW5mb3Jlc3RCaW5kaW5nSWRlbnRpZmllcigpLFxuICAgIH0pO1xuICB9XG5cbiAgZW5mb3Jlc3RGcm9tQ2xhdXNlKCkge1xuICAgIHRoaXMubWF0Y2hJZGVudGlmaWVyKCdmcm9tJyk7XG4gICAgbGV0IGxvb2thaGVhZCA9IHRoaXMubWF0Y2hTdHJpbmdMaXRlcmFsKCk7XG4gICAgdGhpcy5jb25zdW1lU2VtaWNvbG9uKCk7XG4gICAgcmV0dXJuIGxvb2thaGVhZDtcbiAgfVxuXG4gIGVuZm9yZXN0U3RhdGVtZW50TGlzdEl0ZW0oKSB7XG4gICAgbGV0IGxvb2thaGVhZCA9IHRoaXMucGVlaygpO1xuXG4gICAgaWYgKHRoaXMuaXNGbkRlY2xUcmFuc2Zvcm0obG9va2FoZWFkKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZW5mb3Jlc3RGdW5jdGlvbih7IGlzRXhwcjogZmFsc2UgfSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmlzQ2xhc3NUcmFuc2Zvcm0obG9va2FoZWFkKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZW5mb3Jlc3RDbGFzcyh7IGlzRXhwcjogZmFsc2UgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmVuZm9yZXN0U3RhdGVtZW50KCk7XG4gICAgfVxuICB9XG5cbiAgZW5mb3Jlc3RTdGF0ZW1lbnQoKSB7XG4gICAgbGV0IGxvb2thaGVhZCA9IHRoaXMucGVlaygpO1xuXG4gICAgaWYgKHRoaXMudGVybSA9PT0gbnVsbCAmJiB0aGlzLmlzQ29tcGlsZXRpbWVUcmFuc2Zvcm0obG9va2FoZWFkKSkge1xuICAgICAgdGhpcy5leHBhbmRNYWNybygpO1xuICAgICAgbG9va2FoZWFkID0gdGhpcy5wZWVrKCk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdGhpcy50ZXJtID09PSBudWxsICYmXG4gICAgICB0aGlzLmlzVGVybShsb29rYWhlYWQpICYmXG4gICAgICBsb29rYWhlYWQgaW5zdGFuY2VvZiBULlN0YXRlbWVudFxuICAgICkge1xuICAgICAgLy8gVE9ETzogY2hlY2sgdGhhdCB0aGlzIGlzIGFjdHVhbGx5IGFuIHN0YXRlbWVudFxuICAgICAgcmV0dXJuIHRoaXMuYWR2YW5jZSgpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnRlcm0gPT09IG51bGwgJiYgdGhpcy5pc0JyYWNlcyhsb29rYWhlYWQpKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmZvcmVzdEJsb2NrU3RhdGVtZW50KCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudGVybSA9PT0gbnVsbCAmJiB0aGlzLmlzV2hpbGVUcmFuc2Zvcm0obG9va2FoZWFkKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZW5mb3Jlc3RXaGlsZVN0YXRlbWVudCgpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnRlcm0gPT09IG51bGwgJiYgdGhpcy5pc0lmVHJhbnNmb3JtKGxvb2thaGVhZCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuZm9yZXN0SWZTdGF0ZW1lbnQoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMudGVybSA9PT0gbnVsbCAmJiB0aGlzLmlzRm9yVHJhbnNmb3JtKGxvb2thaGVhZCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuZm9yZXN0Rm9yU3RhdGVtZW50KCk7XG4gICAgfVxuICAgIGlmICh0aGlzLnRlcm0gPT09IG51bGwgJiYgdGhpcy5pc1N3aXRjaFRyYW5zZm9ybShsb29rYWhlYWQpKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmZvcmVzdFN3aXRjaFN0YXRlbWVudCgpO1xuICAgIH1cbiAgICBpZiAodGhpcy50ZXJtID09PSBudWxsICYmIHRoaXMuaXNCcmVha1RyYW5zZm9ybShsb29rYWhlYWQpKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmZvcmVzdEJyZWFrU3RhdGVtZW50KCk7XG4gICAgfVxuICAgIGlmICh0aGlzLnRlcm0gPT09IG51bGwgJiYgdGhpcy5pc0NvbnRpbnVlVHJhbnNmb3JtKGxvb2thaGVhZCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuZm9yZXN0Q29udGludWVTdGF0ZW1lbnQoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMudGVybSA9PT0gbnVsbCAmJiB0aGlzLmlzRG9UcmFuc2Zvcm0obG9va2FoZWFkKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZW5mb3Jlc3REb1N0YXRlbWVudCgpO1xuICAgIH1cbiAgICBpZiAodGhpcy50ZXJtID09PSBudWxsICYmIHRoaXMuaXNEZWJ1Z2dlclRyYW5zZm9ybShsb29rYWhlYWQpKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmZvcmVzdERlYnVnZ2VyU3RhdGVtZW50KCk7XG4gICAgfVxuICAgIGlmICh0aGlzLnRlcm0gPT09IG51bGwgJiYgdGhpcy5pc1dpdGhUcmFuc2Zvcm0obG9va2FoZWFkKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZW5mb3Jlc3RXaXRoU3RhdGVtZW50KCk7XG4gICAgfVxuICAgIGlmICh0aGlzLnRlcm0gPT09IG51bGwgJiYgdGhpcy5pc1RyeVRyYW5zZm9ybShsb29rYWhlYWQpKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmZvcmVzdFRyeVN0YXRlbWVudCgpO1xuICAgIH1cbiAgICBpZiAodGhpcy50ZXJtID09PSBudWxsICYmIHRoaXMuaXNUaHJvd1RyYW5zZm9ybShsb29rYWhlYWQpKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmZvcmVzdFRocm93U3RhdGVtZW50KCk7XG4gICAgfVxuXG4gICAgLy8gVE9ETzogcHV0IHNvbWV3aGVyZSBlbHNlXG4gICAgaWYgKHRoaXMudGVybSA9PT0gbnVsbCAmJiB0aGlzLmlzS2V5d29yZChsb29rYWhlYWQsICdjbGFzcycpKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmZvcmVzdENsYXNzKHsgaXNFeHByOiBmYWxzZSB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy50ZXJtID09PSBudWxsICYmIHRoaXMuaXNGbkRlY2xUcmFuc2Zvcm0obG9va2FoZWFkKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZW5mb3Jlc3RGdW5jdGlvbih7IGlzRXhwcjogZmFsc2UgfSk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdGhpcy50ZXJtID09PSBudWxsICYmXG4gICAgICB0aGlzLmlzSWRlbnRpZmllcihsb29rYWhlYWQpICYmXG4gICAgICB0aGlzLmlzUHVuY3R1YXRvcih0aGlzLnBlZWsoMSksICc6JylcbiAgICApIHtcbiAgICAgIHJldHVybiB0aGlzLmVuZm9yZXN0TGFiZWxlZFN0YXRlbWVudCgpO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHRoaXMudGVybSA9PT0gbnVsbCAmJlxuICAgICAgKHRoaXMuaXNWYXJEZWNsVHJhbnNmb3JtKGxvb2thaGVhZCkgfHxcbiAgICAgICAgdGhpcy5pc0xldERlY2xUcmFuc2Zvcm0obG9va2FoZWFkKSB8fFxuICAgICAgICB0aGlzLmlzQ29uc3REZWNsVHJhbnNmb3JtKGxvb2thaGVhZCkgfHxcbiAgICAgICAgdGhpcy5pc1N5bnRheHJlY0RlY2xUcmFuc2Zvcm0obG9va2FoZWFkKSB8fFxuICAgICAgICB0aGlzLmlzU3ludGF4RGVjbFRyYW5zZm9ybShsb29rYWhlYWQpIHx8XG4gICAgICAgIHRoaXMuaXNPcGVyYXRvckRlY2xUcmFuc2Zvcm0obG9va2FoZWFkKSlcbiAgICApIHtcbiAgICAgIGxldCBzdG10ID0gbmV3IFQuVmFyaWFibGVEZWNsYXJhdGlvblN0YXRlbWVudCh7XG4gICAgICAgIGRlY2xhcmF0aW9uOiB0aGlzLmVuZm9yZXN0VmFyaWFibGVEZWNsYXJhdGlvbigpLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmNvbnN1bWVTZW1pY29sb24oKTtcbiAgICAgIHJldHVybiBzdG10O1xuICAgIH1cblxuICAgIGlmICh0aGlzLnRlcm0gPT09IG51bGwgJiYgdGhpcy5pc1JldHVyblN0bXRUcmFuc2Zvcm0obG9va2FoZWFkKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZW5mb3Jlc3RSZXR1cm5TdGF0ZW1lbnQoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy50ZXJtID09PSBudWxsICYmIHRoaXMuaXNQdW5jdHVhdG9yKGxvb2thaGVhZCwgJzsnKSkge1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICByZXR1cm4gbmV3IFQuRW1wdHlTdGF0ZW1lbnQoe30pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmVuZm9yZXN0RXhwcmVzc2lvblN0YXRlbWVudCgpO1xuICB9XG5cbiAgZW5mb3Jlc3RMYWJlbGVkU3RhdGVtZW50KCkge1xuICAgIGxldCBsYWJlbCA9IHRoaXMubWF0Y2hJZGVudGlmaWVyKCk7XG4gICAgdGhpcy5tYXRjaFB1bmN0dWF0b3IoJzonKTtcbiAgICBsZXQgc3RtdCA9IHRoaXMuZW5mb3Jlc3RTdGF0ZW1lbnQoKTtcblxuICAgIHJldHVybiBuZXcgVC5MYWJlbGVkU3RhdGVtZW50KHtcbiAgICAgIGxhYmVsOiBsYWJlbCxcbiAgICAgIGJvZHk6IHN0bXQsXG4gICAgfSk7XG4gIH1cblxuICBlbmZvcmVzdEJyZWFrU3RhdGVtZW50KCkge1xuICAgIHRoaXMubWF0Y2hLZXl3b3JkKCdicmVhaycpO1xuICAgIGxldCBsb29rYWhlYWQgPSB0aGlzLnBlZWsoKTtcbiAgICBsZXQgbGFiZWwgPSBudWxsO1xuICAgIGlmICh0aGlzLnJlc3Quc2l6ZSA9PT0gMCB8fCB0aGlzLmlzUHVuY3R1YXRvcihsb29rYWhlYWQsICc7JykpIHtcbiAgICAgIHRoaXMuY29uc3VtZVNlbWljb2xvbigpO1xuICAgICAgcmV0dXJuIG5ldyBULkJyZWFrU3RhdGVtZW50KHsgbGFiZWwgfSk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIHRoaXMuaXNJZGVudGlmaWVyKGxvb2thaGVhZCkgfHxcbiAgICAgIHRoaXMuaXNLZXl3b3JkKGxvb2thaGVhZCwgJ3lpZWxkJykgfHxcbiAgICAgIHRoaXMuaXNLZXl3b3JkKGxvb2thaGVhZCwgJ2xldCcpXG4gICAgKSB7XG4gICAgICBsYWJlbCA9IHRoaXMuZW5mb3Jlc3RJZGVudGlmaWVyKCk7XG4gICAgfVxuICAgIHRoaXMuY29uc3VtZVNlbWljb2xvbigpO1xuXG4gICAgcmV0dXJuIG5ldyBULkJyZWFrU3RhdGVtZW50KHsgbGFiZWwgfSk7XG4gIH1cblxuICBlbmZvcmVzdFRyeVN0YXRlbWVudCgpIHtcbiAgICB0aGlzLm1hdGNoS2V5d29yZCgndHJ5Jyk7XG4gICAgbGV0IGJvZHkgPSB0aGlzLmVuZm9yZXN0QmxvY2soKTtcbiAgICBpZiAodGhpcy5pc0tleXdvcmQodGhpcy5wZWVrKCksICdjYXRjaCcpKSB7XG4gICAgICBsZXQgY2F0Y2hDbGF1c2UgPSB0aGlzLmVuZm9yZXN0Q2F0Y2hDbGF1c2UoKTtcbiAgICAgIGlmICh0aGlzLmlzS2V5d29yZCh0aGlzLnBlZWsoKSwgJ2ZpbmFsbHknKSkge1xuICAgICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgICAgbGV0IGZpbmFsaXplciA9IHRoaXMuZW5mb3Jlc3RCbG9jaygpO1xuICAgICAgICByZXR1cm4gbmV3IFQuVHJ5RmluYWxseVN0YXRlbWVudCh7XG4gICAgICAgICAgYm9keSxcbiAgICAgICAgICBjYXRjaENsYXVzZSxcbiAgICAgICAgICBmaW5hbGl6ZXIsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBULlRyeUNhdGNoU3RhdGVtZW50KHsgYm9keSwgY2F0Y2hDbGF1c2UgfSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmlzS2V5d29yZCh0aGlzLnBlZWsoKSwgJ2ZpbmFsbHknKSkge1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICBsZXQgZmluYWxpemVyID0gdGhpcy5lbmZvcmVzdEJsb2NrKCk7XG4gICAgICByZXR1cm4gbmV3IFQuVHJ5RmluYWxseVN0YXRlbWVudCh7IGJvZHksIGNhdGNoQ2xhdXNlOiBudWxsLCBmaW5hbGl6ZXIgfSk7XG4gICAgfVxuICAgIHRocm93IHRoaXMuY3JlYXRlRXJyb3IodGhpcy5wZWVrKCksICd0cnkgd2l0aCBubyBjYXRjaCBvciBmaW5hbGx5Jyk7XG4gIH1cblxuICBlbmZvcmVzdENhdGNoQ2xhdXNlKCkge1xuICAgIHRoaXMubWF0Y2hLZXl3b3JkKCdjYXRjaCcpO1xuICAgIGxldCBiaW5kaW5nUGFyZW5zID0gdGhpcy5tYXRjaFBhcmVucygpO1xuICAgIGxldCBlbmYgPSBuZXcgRW5mb3Jlc3RlcihiaW5kaW5nUGFyZW5zLCBMaXN0KCksIHRoaXMuY29udGV4dCk7XG4gICAgbGV0IGJpbmRpbmcgPSBlbmYuZW5mb3Jlc3RCaW5kaW5nVGFyZ2V0KCk7XG4gICAgbGV0IGJvZHkgPSB0aGlzLmVuZm9yZXN0QmxvY2soKTtcbiAgICByZXR1cm4gbmV3IFQuQ2F0Y2hDbGF1c2UoeyBiaW5kaW5nLCBib2R5IH0pO1xuICB9XG5cbiAgZW5mb3Jlc3RUaHJvd1N0YXRlbWVudCgpIHtcbiAgICB0aGlzLm1hdGNoS2V5d29yZCgndGhyb3cnKTtcbiAgICBsZXQgZXhwcmVzc2lvbiA9IHRoaXMuZW5mb3Jlc3RFeHByZXNzaW9uKCk7XG4gICAgdGhpcy5jb25zdW1lU2VtaWNvbG9uKCk7XG4gICAgcmV0dXJuIG5ldyBULlRocm93U3RhdGVtZW50KHsgZXhwcmVzc2lvbiB9KTtcbiAgfVxuXG4gIGVuZm9yZXN0V2l0aFN0YXRlbWVudCgpIHtcbiAgICB0aGlzLm1hdGNoS2V5d29yZCgnd2l0aCcpO1xuICAgIGxldCBvYmpQYXJlbnMgPSB0aGlzLm1hdGNoUGFyZW5zKCk7XG4gICAgbGV0IGVuZiA9IG5ldyBFbmZvcmVzdGVyKG9ialBhcmVucywgTGlzdCgpLCB0aGlzLmNvbnRleHQpO1xuICAgIGxldCBvYmplY3QgPSBlbmYuZW5mb3Jlc3RFeHByZXNzaW9uKCk7XG4gICAgbGV0IGJvZHkgPSB0aGlzLmVuZm9yZXN0U3RhdGVtZW50KCk7XG4gICAgcmV0dXJuIG5ldyBULldpdGhTdGF0ZW1lbnQoeyBvYmplY3QsIGJvZHkgfSk7XG4gIH1cblxuICBlbmZvcmVzdERlYnVnZ2VyU3RhdGVtZW50KCkge1xuICAgIHRoaXMubWF0Y2hLZXl3b3JkKCdkZWJ1Z2dlcicpO1xuXG4gICAgcmV0dXJuIG5ldyBULkRlYnVnZ2VyU3RhdGVtZW50KHt9KTtcbiAgfVxuXG4gIGVuZm9yZXN0RG9TdGF0ZW1lbnQoKSB7XG4gICAgdGhpcy5tYXRjaEtleXdvcmQoJ2RvJyk7XG4gICAgbGV0IGJvZHkgPSB0aGlzLmVuZm9yZXN0U3RhdGVtZW50KCk7XG4gICAgdGhpcy5tYXRjaEtleXdvcmQoJ3doaWxlJyk7XG4gICAgbGV0IHRlc3RCb2R5ID0gdGhpcy5tYXRjaFBhcmVucygpO1xuICAgIGxldCBlbmYgPSBuZXcgRW5mb3Jlc3Rlcih0ZXN0Qm9keSwgTGlzdCgpLCB0aGlzLmNvbnRleHQpO1xuICAgIGxldCB0ZXN0ID0gZW5mLmVuZm9yZXN0RXhwcmVzc2lvbigpO1xuICAgIHRoaXMuY29uc3VtZVNlbWljb2xvbigpO1xuICAgIHJldHVybiBuZXcgVC5Eb1doaWxlU3RhdGVtZW50KHsgYm9keSwgdGVzdCB9KTtcbiAgfVxuXG4gIGVuZm9yZXN0Q29udGludWVTdGF0ZW1lbnQoKSB7XG4gICAgbGV0IGt3ZCA9IHRoaXMubWF0Y2hLZXl3b3JkKCdjb250aW51ZScpO1xuICAgIGxldCBsb29rYWhlYWQgPSB0aGlzLnBlZWsoKTtcbiAgICBsZXQgbGFiZWwgPSBudWxsO1xuICAgIGlmICh0aGlzLnJlc3Quc2l6ZSA9PT0gMCB8fCB0aGlzLmlzUHVuY3R1YXRvcihsb29rYWhlYWQsICc7JykpIHtcbiAgICAgIHRoaXMuY29uc3VtZVNlbWljb2xvbigpO1xuICAgICAgcmV0dXJuIG5ldyBULkNvbnRpbnVlU3RhdGVtZW50KHsgbGFiZWwgfSk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIGxvb2thaGVhZCBpbnN0YW5jZW9mIFQuUmF3U3ludGF4ICYmXG4gICAgICB0aGlzLmxpbmVOdW1iZXJFcShrd2QsIGxvb2thaGVhZCkgJiZcbiAgICAgICh0aGlzLmlzSWRlbnRpZmllcihsb29rYWhlYWQpIHx8XG4gICAgICAgIHRoaXMuaXNLZXl3b3JkKGxvb2thaGVhZCwgJ3lpZWxkJykgfHxcbiAgICAgICAgdGhpcy5pc0tleXdvcmQobG9va2FoZWFkLCAnbGV0JykpXG4gICAgKSB7XG4gICAgICBsYWJlbCA9IHRoaXMuZW5mb3Jlc3RJZGVudGlmaWVyKCk7XG4gICAgfVxuICAgIHRoaXMuY29uc3VtZVNlbWljb2xvbigpO1xuXG4gICAgcmV0dXJuIG5ldyBULkNvbnRpbnVlU3RhdGVtZW50KHsgbGFiZWwgfSk7XG4gIH1cblxuICBlbmZvcmVzdFN3aXRjaFN0YXRlbWVudCgpIHtcbiAgICB0aGlzLm1hdGNoS2V5d29yZCgnc3dpdGNoJyk7XG4gICAgbGV0IGNvbmQgPSB0aGlzLm1hdGNoUGFyZW5zKCk7XG4gICAgbGV0IGVuZiA9IG5ldyBFbmZvcmVzdGVyKGNvbmQsIExpc3QoKSwgdGhpcy5jb250ZXh0KTtcbiAgICBsZXQgZGlzY3JpbWluYW50ID0gZW5mLmVuZm9yZXN0RXhwcmVzc2lvbigpO1xuICAgIGxldCBib2R5ID0gdGhpcy5tYXRjaEN1cmxpZXMoKTtcblxuICAgIGlmIChib2R5LnNpemUgPT09IDApIHtcbiAgICAgIHJldHVybiBuZXcgVC5Td2l0Y2hTdGF0ZW1lbnQoe1xuICAgICAgICBkaXNjcmltaW5hbnQ6IGRpc2NyaW1pbmFudCxcbiAgICAgICAgY2FzZXM6IExpc3QoKSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBlbmYgPSBuZXcgRW5mb3Jlc3Rlcihib2R5LCBMaXN0KCksIHRoaXMuY29udGV4dCk7XG4gICAgbGV0IGNhc2VzID0gZW5mLmVuZm9yZXN0U3dpdGNoQ2FzZXMoKTtcbiAgICBsZXQgbG9va2FoZWFkID0gZW5mLnBlZWsoKTtcbiAgICBpZiAoZW5mLmlzS2V5d29yZChsb29rYWhlYWQsICdkZWZhdWx0JykpIHtcbiAgICAgIGxldCBkZWZhdWx0Q2FzZSA9IGVuZi5lbmZvcmVzdFN3aXRjaERlZmF1bHQoKTtcbiAgICAgIGxldCBwb3N0RGVmYXVsdENhc2VzID0gZW5mLmVuZm9yZXN0U3dpdGNoQ2FzZXMoKTtcbiAgICAgIHJldHVybiBuZXcgVC5Td2l0Y2hTdGF0ZW1lbnRXaXRoRGVmYXVsdCh7XG4gICAgICAgIGRpc2NyaW1pbmFudCxcbiAgICAgICAgcHJlRGVmYXVsdENhc2VzOiBjYXNlcyxcbiAgICAgICAgZGVmYXVsdENhc2UsXG4gICAgICAgIHBvc3REZWZhdWx0Q2FzZXMsXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBULlN3aXRjaFN0YXRlbWVudCh7IGRpc2NyaW1pbmFudCwgY2FzZXMgfSk7XG4gIH1cblxuICBlbmZvcmVzdFN3aXRjaENhc2VzKCkge1xuICAgIGxldCBjYXNlcyA9IFtdO1xuICAgIHdoaWxlICghKHRoaXMucmVzdC5zaXplID09PSAwIHx8IHRoaXMuaXNLZXl3b3JkKHRoaXMucGVlaygpLCAnZGVmYXVsdCcpKSkge1xuICAgICAgY2FzZXMucHVzaCh0aGlzLmVuZm9yZXN0U3dpdGNoQ2FzZSgpKTtcbiAgICB9XG4gICAgcmV0dXJuIExpc3QoY2FzZXMpO1xuICB9XG5cbiAgZW5mb3Jlc3RTd2l0Y2hDYXNlKCkge1xuICAgIHRoaXMubWF0Y2hLZXl3b3JkKCdjYXNlJyk7XG4gICAgcmV0dXJuIG5ldyBULlN3aXRjaENhc2Uoe1xuICAgICAgdGVzdDogdGhpcy5lbmZvcmVzdEV4cHJlc3Npb24oKSxcbiAgICAgIGNvbnNlcXVlbnQ6IHRoaXMuZW5mb3Jlc3RTd2l0Y2hDYXNlQm9keSgpLFxuICAgIH0pO1xuICB9XG5cbiAgZW5mb3Jlc3RTd2l0Y2hDYXNlQm9keSgpIHtcbiAgICB0aGlzLm1hdGNoUHVuY3R1YXRvcignOicpO1xuICAgIHJldHVybiB0aGlzLmVuZm9yZXN0U3RhdGVtZW50TGlzdEluU3dpdGNoQ2FzZUJvZHkoKTtcbiAgfVxuXG4gIGVuZm9yZXN0U3RhdGVtZW50TGlzdEluU3dpdGNoQ2FzZUJvZHkoKSB7XG4gICAgbGV0IHJlc3VsdCA9IFtdO1xuICAgIHdoaWxlIChcbiAgICAgICEodGhpcy5yZXN0LnNpemUgPT09IDAgfHxcbiAgICAgICAgdGhpcy5pc0tleXdvcmQodGhpcy5wZWVrKCksICdkZWZhdWx0JykgfHxcbiAgICAgICAgdGhpcy5pc0tleXdvcmQodGhpcy5wZWVrKCksICdjYXNlJykpXG4gICAgKSB7XG4gICAgICByZXN1bHQucHVzaCh0aGlzLmVuZm9yZXN0U3RhdGVtZW50TGlzdEl0ZW0oKSk7XG4gICAgfVxuICAgIHJldHVybiBMaXN0KHJlc3VsdCk7XG4gIH1cblxuICBlbmZvcmVzdFN3aXRjaERlZmF1bHQoKSB7XG4gICAgdGhpcy5tYXRjaEtleXdvcmQoJ2RlZmF1bHQnKTtcbiAgICByZXR1cm4gbmV3IFQuU3dpdGNoRGVmYXVsdCh7XG4gICAgICBjb25zZXF1ZW50OiB0aGlzLmVuZm9yZXN0U3dpdGNoQ2FzZUJvZHkoKSxcbiAgICB9KTtcbiAgfVxuXG4gIGVuZm9yZXN0Rm9yU3RhdGVtZW50KCkge1xuICAgIHRoaXMubWF0Y2hLZXl3b3JkKCdmb3InKTtcbiAgICBsZXQgY29uZCA9IHRoaXMubWF0Y2hQYXJlbnMoKTtcbiAgICBsZXQgZW5mID0gbmV3IEVuZm9yZXN0ZXIoY29uZCwgTGlzdCgpLCB0aGlzLmNvbnRleHQpO1xuICAgIGxldCBsb29rYWhlYWQsIHRlc3QsIGluaXQsIHJpZ2h0LCBsZWZ0LCB1cGRhdGUsIGNuc3Q7XG5cbiAgICAvLyBjYXNlIHdoZXJlIGluaXQgaXMgbnVsbFxuICAgIGlmIChlbmYuaXNQdW5jdHVhdG9yKGVuZi5wZWVrKCksICc7JykpIHtcbiAgICAgIGVuZi5hZHZhbmNlKCk7XG4gICAgICBpZiAoIWVuZi5pc1B1bmN0dWF0b3IoZW5mLnBlZWsoKSwgJzsnKSkge1xuICAgICAgICB0ZXN0ID0gZW5mLmVuZm9yZXN0RXhwcmVzc2lvbigpO1xuICAgICAgfVxuICAgICAgZW5mLm1hdGNoUHVuY3R1YXRvcignOycpO1xuICAgICAgaWYgKGVuZi5yZXN0LnNpemUgIT09IDApIHtcbiAgICAgICAgcmlnaHQgPSBlbmYuZW5mb3Jlc3RFeHByZXNzaW9uKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV3IFQuRm9yU3RhdGVtZW50KHtcbiAgICAgICAgaW5pdDogbnVsbCxcbiAgICAgICAgdGVzdDogdGVzdCxcbiAgICAgICAgdXBkYXRlOiByaWdodCxcbiAgICAgICAgYm9keTogdGhpcy5lbmZvcmVzdFN0YXRlbWVudCgpLFxuICAgICAgfSk7XG4gICAgICAvLyBjYXNlIHdoZXJlIGluaXQgaXMgbm90IG51bGxcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gdGVzdGluZ1xuICAgICAgbG9va2FoZWFkID0gZW5mLnBlZWsoKTtcbiAgICAgIGlmIChcbiAgICAgICAgZW5mLmlzVmFyRGVjbFRyYW5zZm9ybShsb29rYWhlYWQpIHx8XG4gICAgICAgIGVuZi5pc0xldERlY2xUcmFuc2Zvcm0obG9va2FoZWFkKSB8fFxuICAgICAgICBlbmYuaXNDb25zdERlY2xUcmFuc2Zvcm0obG9va2FoZWFkKVxuICAgICAgKSB7XG4gICAgICAgIGluaXQgPSBlbmYuZW5mb3Jlc3RWYXJpYWJsZURlY2xhcmF0aW9uKCk7XG4gICAgICAgIGxvb2thaGVhZCA9IGVuZi5wZWVrKCk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0aGlzLmlzS2V5d29yZChsb29rYWhlYWQsICdpbicpIHx8IHRoaXMuaXNJZGVudGlmaWVyKGxvb2thaGVhZCwgJ29mJylcbiAgICAgICAgKSB7XG4gICAgICAgICAgaWYgKHRoaXMuaXNLZXl3b3JkKGxvb2thaGVhZCwgJ2luJykpIHtcbiAgICAgICAgICAgIGVuZi5hZHZhbmNlKCk7XG4gICAgICAgICAgICByaWdodCA9IGVuZi5lbmZvcmVzdEV4cHJlc3Npb24oKTtcbiAgICAgICAgICAgIGNuc3QgPSBULkZvckluU3RhdGVtZW50O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhc3NlcnQoXG4gICAgICAgICAgICAgIHRoaXMuaXNJZGVudGlmaWVyKGxvb2thaGVhZCwgJ29mJyksXG4gICAgICAgICAgICAgICdleHBlY3RpbmcgYG9mYCBrZXl3b3JkJyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBlbmYuYWR2YW5jZSgpO1xuICAgICAgICAgICAgcmlnaHQgPSBlbmYuZW5mb3Jlc3RFeHByZXNzaW9uKCk7XG4gICAgICAgICAgICBjbnN0ID0gVC5Gb3JPZlN0YXRlbWVudDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG5ldyBjbnN0KHtcbiAgICAgICAgICAgIGxlZnQ6IGluaXQsXG4gICAgICAgICAgICByaWdodCxcbiAgICAgICAgICAgIGJvZHk6IHRoaXMuZW5mb3Jlc3RTdGF0ZW1lbnQoKSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbmYubWF0Y2hQdW5jdHVhdG9yKCc7Jyk7XG4gICAgICAgIGlmIChlbmYuaXNQdW5jdHVhdG9yKGVuZi5wZWVrKCksICc7JykpIHtcbiAgICAgICAgICBlbmYuYWR2YW5jZSgpO1xuICAgICAgICAgIHRlc3QgPSBudWxsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRlc3QgPSBlbmYuZW5mb3Jlc3RFeHByZXNzaW9uKCk7XG4gICAgICAgICAgZW5mLm1hdGNoUHVuY3R1YXRvcignOycpO1xuICAgICAgICB9XG4gICAgICAgIHVwZGF0ZSA9IGVuZi5lbmZvcmVzdEV4cHJlc3Npb24oKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0aGlzLmlzS2V5d29yZChlbmYucGVlaygxKSwgJ2luJykgfHxcbiAgICAgICAgICB0aGlzLmlzSWRlbnRpZmllcihlbmYucGVlaygxKSwgJ29mJylcbiAgICAgICAgKSB7XG4gICAgICAgICAgbGVmdCA9IGVuZi5lbmZvcmVzdEJpbmRpbmdJZGVudGlmaWVyKCk7XG4gICAgICAgICAgbGV0IGtpbmQgPSBlbmYuYWR2YW5jZSgpO1xuICAgICAgICAgIGlmICh0aGlzLmlzS2V5d29yZChraW5kLCAnaW4nKSkge1xuICAgICAgICAgICAgY25zdCA9IFQuRm9ySW5TdGF0ZW1lbnQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNuc3QgPSBULkZvck9mU3RhdGVtZW50O1xuICAgICAgICAgIH1cbiAgICAgICAgICByaWdodCA9IGVuZi5lbmZvcmVzdEV4cHJlc3Npb24oKTtcbiAgICAgICAgICByZXR1cm4gbmV3IGNuc3Qoe1xuICAgICAgICAgICAgbGVmdDogbGVmdCxcbiAgICAgICAgICAgIHJpZ2h0LFxuICAgICAgICAgICAgYm9keTogdGhpcy5lbmZvcmVzdFN0YXRlbWVudCgpLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGluaXQgPSBlbmYuZW5mb3Jlc3RFeHByZXNzaW9uKCk7XG4gICAgICAgIGVuZi5tYXRjaFB1bmN0dWF0b3IoJzsnKTtcbiAgICAgICAgaWYgKGVuZi5pc1B1bmN0dWF0b3IoZW5mLnBlZWsoKSwgJzsnKSkge1xuICAgICAgICAgIGVuZi5hZHZhbmNlKCk7XG4gICAgICAgICAgdGVzdCA9IG51bGw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGVzdCA9IGVuZi5lbmZvcmVzdEV4cHJlc3Npb24oKTtcbiAgICAgICAgICBlbmYubWF0Y2hQdW5jdHVhdG9yKCc7Jyk7XG4gICAgICAgIH1cbiAgICAgICAgdXBkYXRlID0gZW5mLmVuZm9yZXN0RXhwcmVzc2lvbigpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBULkZvclN0YXRlbWVudCh7XG4gICAgICAgIGluaXQsXG4gICAgICAgIHRlc3QsXG4gICAgICAgIHVwZGF0ZSxcbiAgICAgICAgYm9keTogdGhpcy5lbmZvcmVzdFN0YXRlbWVudCgpLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZW5mb3Jlc3RJZlN0YXRlbWVudCgpIHtcbiAgICB0aGlzLm1hdGNoS2V5d29yZCgnaWYnKTtcbiAgICBsZXQgY29uZCA9IHRoaXMubWF0Y2hQYXJlbnMoKTtcbiAgICBsZXQgZW5mID0gbmV3IEVuZm9yZXN0ZXIoY29uZCwgTGlzdCgpLCB0aGlzLmNvbnRleHQpO1xuICAgIGxldCBsb29rYWhlYWQgPSBlbmYucGVlaygpO1xuICAgIGxldCB0ZXN0ID0gZW5mLmVuZm9yZXN0RXhwcmVzc2lvbigpO1xuICAgIGlmICh0ZXN0ID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBlbmYuY3JlYXRlRXJyb3IobG9va2FoZWFkLCAnZXhwZWN0aW5nIGFuIGV4cHJlc3Npb24nKTtcbiAgICB9XG4gICAgbGV0IGNvbnNlcXVlbnQgPSB0aGlzLmVuZm9yZXN0U3RhdGVtZW50KCk7XG4gICAgbGV0IGFsdGVybmF0ZSA9IG51bGw7XG4gICAgaWYgKHRoaXMuaXNLZXl3b3JkKHRoaXMucGVlaygpLCAnZWxzZScpKSB7XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIGFsdGVybmF0ZSA9IHRoaXMuZW5mb3Jlc3RTdGF0ZW1lbnQoKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBULklmU3RhdGVtZW50KHsgdGVzdCwgY29uc2VxdWVudCwgYWx0ZXJuYXRlIH0pO1xuICB9XG5cbiAgZW5mb3Jlc3RXaGlsZVN0YXRlbWVudCgpIHtcbiAgICB0aGlzLm1hdGNoS2V5d29yZCgnd2hpbGUnKTtcbiAgICBsZXQgY29uZCA9IHRoaXMubWF0Y2hQYXJlbnMoKTtcbiAgICBsZXQgZW5mID0gbmV3IEVuZm9yZXN0ZXIoY29uZCwgTGlzdCgpLCB0aGlzLmNvbnRleHQpO1xuICAgIGxldCBsb29rYWhlYWQgPSBlbmYucGVlaygpO1xuICAgIGxldCB0ZXN0ID0gZW5mLmVuZm9yZXN0RXhwcmVzc2lvbigpO1xuICAgIGlmICh0ZXN0ID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBlbmYuY3JlYXRlRXJyb3IobG9va2FoZWFkLCAnZXhwZWN0aW5nIGFuIGV4cHJlc3Npb24nKTtcbiAgICB9XG4gICAgbGV0IGJvZHkgPSB0aGlzLmVuZm9yZXN0U3RhdGVtZW50KCk7XG5cbiAgICByZXR1cm4gbmV3IFQuV2hpbGVTdGF0ZW1lbnQoeyB0ZXN0LCBib2R5IH0pO1xuICB9XG5cbiAgZW5mb3Jlc3RCbG9ja1N0YXRlbWVudCgpIHtcbiAgICByZXR1cm4gbmV3IFQuQmxvY2tTdGF0ZW1lbnQoe1xuICAgICAgYmxvY2s6IHRoaXMuZW5mb3Jlc3RCbG9jaygpLFxuICAgIH0pO1xuICB9XG5cbiAgZW5mb3Jlc3RCbG9jaygpIHtcbiAgICByZXR1cm4gbmV3IFQuQmxvY2soe1xuICAgICAgc3RhdGVtZW50czogdGhpcy5tYXRjaEN1cmxpZXMoKSxcbiAgICB9KTtcbiAgfVxuXG4gIGVuZm9yZXN0Q2xhc3MoXG4gICAge1xuICAgICAgaXNFeHByID0gZmFsc2UsXG4gICAgICBpbkRlZmF1bHQgPSBmYWxzZSxcbiAgICB9OiB7IGlzRXhwcj86IGJvb2xlYW4sIGluRGVmYXVsdD86IGJvb2xlYW4gfSxcbiAgKSB7XG4gICAgbGV0IGt3ID0gdGhpcy5tYXRjaFJhd1N5bnRheCgpO1xuICAgIGxldCBuYW1lID0gbnVsbCwgc3VwciA9IG51bGw7XG5cbiAgICBpZiAodGhpcy5pc0lkZW50aWZpZXIodGhpcy5wZWVrKCkpKSB7XG4gICAgICBuYW1lID0gdGhpcy5lbmZvcmVzdEJpbmRpbmdJZGVudGlmaWVyKCk7XG4gICAgfSBlbHNlIGlmICghaXNFeHByKSB7XG4gICAgICBpZiAoaW5EZWZhdWx0KSB7XG4gICAgICAgIG5hbWUgPSBuZXcgVC5CaW5kaW5nSWRlbnRpZmllcih7XG4gICAgICAgICAgbmFtZTogU3ludGF4LmZyb21JZGVudGlmaWVyKCdfZGVmYXVsdCcsIGt3KSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyB0aGlzLmNyZWF0ZUVycm9yKHRoaXMucGVlaygpLCAndW5leHBlY3RlZCBzeW50YXgnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc0tleXdvcmQodGhpcy5wZWVrKCksICdleHRlbmRzJykpIHtcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgc3VwciA9IHRoaXMuZW5mb3Jlc3RFeHByZXNzaW9uTG9vcCgpO1xuICAgIH1cblxuICAgIGxldCBlbGVtZW50cyA9IFtdO1xuICAgIGxldCBlbmYgPSBuZXcgRW5mb3Jlc3Rlcih0aGlzLm1hdGNoQ3VybGllcygpLCBMaXN0KCksIHRoaXMuY29udGV4dCk7XG4gICAgd2hpbGUgKGVuZi5yZXN0LnNpemUgIT09IDApIHtcbiAgICAgIGlmIChlbmYuaXNQdW5jdHVhdG9yKGVuZi5wZWVrKCksICc7JykpIHtcbiAgICAgICAgZW5mLmFkdmFuY2UoKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGxldCBpc1N0YXRpYyA9IGZhbHNlO1xuICAgICAgbGV0IHsgbWV0aG9kT3JLZXksIGtpbmQgfSA9IGVuZi5lbmZvcmVzdE1ldGhvZERlZmluaXRpb24oKTtcbiAgICAgIGlmIChraW5kID09PSAnaWRlbnRpZmllcicgJiYgbWV0aG9kT3JLZXkudmFsdWUudmFsKCkgPT09ICdzdGF0aWMnKSB7XG4gICAgICAgIGlzU3RhdGljID0gdHJ1ZTtcbiAgICAgICAgKHsgbWV0aG9kT3JLZXksIGtpbmQgfSA9IGVuZi5lbmZvcmVzdE1ldGhvZERlZmluaXRpb24oKSk7XG4gICAgICB9XG4gICAgICBpZiAoa2luZCA9PT0gJ21ldGhvZCcpIHtcbiAgICAgICAgZWxlbWVudHMucHVzaChuZXcgVC5DbGFzc0VsZW1lbnQoeyBpc1N0YXRpYywgbWV0aG9kOiBtZXRob2RPcktleSB9KSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyB0aGlzLmNyZWF0ZUVycm9yKFxuICAgICAgICAgIGVuZi5wZWVrKCksXG4gICAgICAgICAgJ09ubHkgbWV0aG9kcyBhcmUgYWxsb3dlZCBpbiBjbGFzc2VzJyxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5ldyAoaXNFeHByID8gVC5DbGFzc0V4cHJlc3Npb24gOiBULkNsYXNzRGVjbGFyYXRpb24pKHtcbiAgICAgIG5hbWUsXG4gICAgICBzdXBlcjogc3VwcixcbiAgICAgIGVsZW1lbnRzOiBMaXN0KGVsZW1lbnRzKSxcbiAgICB9KTtcbiAgfVxuXG4gIGVuZm9yZXN0QmluZGluZ1RhcmdldChcbiAgICB7IGFsbG93UHVuY3R1YXRvciA9IGZhbHNlIH06IHsgYWxsb3dQdW5jdHVhdG9yPzogYm9vbGVhbiB9ID0ge30sXG4gICkge1xuICAgIGxldCBsb29rYWhlYWQgPSB0aGlzLnBlZWsoKTtcbiAgICBpZiAoXG4gICAgICB0aGlzLmlzSWRlbnRpZmllcihsb29rYWhlYWQpIHx8XG4gICAgICB0aGlzLmlzS2V5d29yZChsb29rYWhlYWQpIHx8XG4gICAgICAoYWxsb3dQdW5jdHVhdG9yICYmIHRoaXMuaXNQdW5jdHVhdG9yKGxvb2thaGVhZCkpXG4gICAgKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmZvcmVzdEJpbmRpbmdJZGVudGlmaWVyKHsgYWxsb3dQdW5jdHVhdG9yIH0pO1xuICAgIH0gZWxzZSBpZiAodGhpcy5pc0JyYWNrZXRzKGxvb2thaGVhZCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuZm9yZXN0QXJyYXlCaW5kaW5nKCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmlzQnJhY2VzKGxvb2thaGVhZCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuZm9yZXN0T2JqZWN0QmluZGluZygpO1xuICAgIH1cbiAgICBhc3NlcnQoZmFsc2UsICdub3QgaW1wbGVtZW50ZWQgeWV0Jyk7XG4gIH1cblxuICBlbmZvcmVzdE9iamVjdEJpbmRpbmcoKSB7XG4gICAgbGV0IGVuZiA9IG5ldyBFbmZvcmVzdGVyKHRoaXMubWF0Y2hDdXJsaWVzKCksIExpc3QoKSwgdGhpcy5jb250ZXh0KTtcbiAgICBsZXQgcHJvcGVydGllcyA9IFtdO1xuXG4gICAgLy9UT0RPOiBpbXBsZW1lbnQgb2JqZWN0IHJlc3Qgb3BlcmF0b3Igd2hlbiBpdCBsYW5kc1xuICAgIHdoaWxlIChlbmYucmVzdC5zaXplICE9PSAwKSB7XG4gICAgICBwcm9wZXJ0aWVzLnB1c2goZW5mLmVuZm9yZXN0QmluZGluZ1Byb3BlcnR5KCkpO1xuXG4gICAgICBpZiAoZW5mLnJlc3Quc2l6ZSA+IDAgJiYgIWVuZi5pc1B1bmN0dWF0b3IoZW5mLnBlZWsoKSwgJywnKSkge1xuICAgICAgICB0aHJvdyBlbmYuY3JlYXRlRXJyb3IoZW5mLnBlZWsoKSwgJ3VuZXhwZWN0ZWQgdG9rZW4nKTtcbiAgICAgIH1cblxuICAgICAgZW5mLmNvbnN1bWVDb21tYSgpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgVC5PYmplY3RCaW5kaW5nKHtcbiAgICAgIHByb3BlcnRpZXM6IExpc3QocHJvcGVydGllcyksXG4gICAgfSk7XG4gIH1cblxuICBlbmZvcmVzdEJpbmRpbmdQcm9wZXJ0eSgpIHtcbiAgICBsZXQgbG9va2FoZWFkID0gdGhpcy5wZWVrKCk7XG4gICAgbGV0IHsgbmFtZSwgYmluZGluZyB9ID0gdGhpcy5lbmZvcmVzdFByb3BlcnR5TmFtZSgpO1xuICAgIGlmIChcbiAgICAgIHRoaXMuaXNJZGVudGlmaWVyKGxvb2thaGVhZCkgfHxcbiAgICAgIHRoaXMuaXNLZXl3b3JkKGxvb2thaGVhZCwgJ2xldCcpIHx8XG4gICAgICB0aGlzLmlzS2V5d29yZChsb29rYWhlYWQsICd5aWVsZCcpXG4gICAgKSB7XG4gICAgICBpZiAoIXRoaXMuaXNQdW5jdHVhdG9yKHRoaXMucGVlaygpLCAnOicpKSB7XG4gICAgICAgIGxldCBkZWZhdWx0VmFsdWUgPSBudWxsO1xuICAgICAgICBpZiAodGhpcy5pc0Fzc2lnbih0aGlzLnBlZWsoKSkpIHtcbiAgICAgICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgICAgICBsZXQgZXhwciA9IHRoaXMuZW5mb3Jlc3RFeHByZXNzaW9uTG9vcCgpO1xuICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9IGV4cHI7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBULkJpbmRpbmdQcm9wZXJ0eUlkZW50aWZpZXIoe1xuICAgICAgICAgIGJpbmRpbmcsXG4gICAgICAgICAgaW5pdDogZGVmYXVsdFZhbHVlLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5tYXRjaFB1bmN0dWF0b3IoJzonKTtcbiAgICBiaW5kaW5nID0gdGhpcy5lbmZvcmVzdEJpbmRpbmdFbGVtZW50KCk7XG4gICAgcmV0dXJuIG5ldyBULkJpbmRpbmdQcm9wZXJ0eVByb3BlcnR5KHtcbiAgICAgIG5hbWUsXG4gICAgICBiaW5kaW5nLFxuICAgIH0pO1xuICB9XG5cbiAgZW5mb3Jlc3RBcnJheUJpbmRpbmcoKSB7XG4gICAgbGV0IGJyYWNrZXQgPSB0aGlzLm1hdGNoU3F1YXJlcygpO1xuICAgIGxldCBlbmYgPSBuZXcgRW5mb3Jlc3RlcihicmFja2V0LCBMaXN0KCksIHRoaXMuY29udGV4dCk7XG4gICAgbGV0IGVsZW1lbnRzID0gW10sIHJlc3RFbGVtZW50ID0gbnVsbDtcbiAgICB3aGlsZSAoZW5mLnJlc3Quc2l6ZSAhPT0gMCkge1xuICAgICAgbGV0IGVsID0gbnVsbDtcbiAgICAgIGlmICghZW5mLmlzUHVuY3R1YXRvcihlbmYucGVlaygpLCAnLCcpKSB7XG4gICAgICAgIGlmIChlbmYuaXNQdW5jdHVhdG9yKGVuZi5wZWVrKCksICcuLi4nKSkge1xuICAgICAgICAgIGVuZi5hZHZhbmNlKCk7XG4gICAgICAgICAgcmVzdEVsZW1lbnQgPSBlbmYuZW5mb3Jlc3RCaW5kaW5nVGFyZ2V0KCk7XG4gICAgICAgICAgaWYgKGVuZi5yZXN0LnNpemUgPiAwKSB7XG4gICAgICAgICAgICB0aHJvdyBlbmYuY3JlYXRlRXJyb3IoXG4gICAgICAgICAgICAgICcnLFxuICAgICAgICAgICAgICAnUmVzdCBlbGVtZW50IG11c3QgYmUgbGFzdCBlbGVtZW50IGluIGFycmF5JyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVsID0gZW5mLmVuZm9yZXN0QmluZGluZ0VsZW1lbnQoKTtcblxuICAgICAgICAgIGlmIChlbCA9PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBlbmYuY3JlYXRlRXJyb3IoZW5mLnBlZWsoKSwgJ2V4cGVjdGVkIGV4cHJlc3Npb24nKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGVuZi5yZXN0LnNpemUgPiAwICYmICFlbmYuaXNQdW5jdHVhdG9yKGVuZi5wZWVrKCksICcsJykpIHtcbiAgICAgICAgICAgIHRocm93IGVuZi5jcmVhdGVFcnJvcihlbmYucGVlaygpLCAndW5leHBlY3RlZCB0b2tlbicpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHJlc3RFbGVtZW50ID09IG51bGwpIHtcbiAgICAgICAgZWxlbWVudHMucHVzaChlbCk7XG4gICAgICAgIGVuZi5jb25zdW1lQ29tbWEoKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5ldyBULkFycmF5QmluZGluZyh7XG4gICAgICBlbGVtZW50czogTGlzdChlbGVtZW50cyksXG4gICAgICByZXN0RWxlbWVudCxcbiAgICB9KTtcbiAgfVxuXG4gIGVuZm9yZXN0QmluZGluZ0VsZW1lbnQoKSB7XG4gICAgbGV0IGJpbmRpbmcgPSB0aGlzLmVuZm9yZXN0QmluZGluZ1RhcmdldCgpO1xuXG4gICAgaWYgKHRoaXMuaXNBc3NpZ24odGhpcy5wZWVrKCkpKSB7XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIGxldCBpbml0ID0gdGhpcy5lbmZvcmVzdEV4cHJlc3Npb25Mb29wKCk7XG4gICAgICBiaW5kaW5nID0gbmV3IFQuQmluZGluZ1dpdGhEZWZhdWx0KHsgYmluZGluZywgaW5pdCB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGJpbmRpbmc7XG4gIH1cblxuICBlbmZvcmVzdEJpbmRpbmdJZGVudGlmaWVyKFxuICAgIHsgYWxsb3dQdW5jdHVhdG9yIH06IHsgYWxsb3dQdW5jdHVhdG9yPzogYm9vbGVhbiB9ID0ge30sXG4gICkge1xuICAgIGxldCBuYW1lO1xuICAgIGlmIChhbGxvd1B1bmN0dWF0b3IgJiYgdGhpcy5pc1B1bmN0dWF0b3IodGhpcy5wZWVrKCkpKSB7XG4gICAgICBuYW1lID0gdGhpcy5lbmZvcmVzdFB1bmN0dWF0b3IoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmFtZSA9IHRoaXMuZW5mb3Jlc3RJZGVudGlmaWVyKCk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgVC5CaW5kaW5nSWRlbnRpZmllcih7IG5hbWUgfSk7XG4gIH1cblxuICBlbmZvcmVzdFB1bmN0dWF0b3IoKSB7XG4gICAgbGV0IGxvb2thaGVhZCA9IHRoaXMucGVlaygpO1xuICAgIGlmICh0aGlzLmlzUHVuY3R1YXRvcihsb29rYWhlYWQpKSB7XG4gICAgICByZXR1cm4gdGhpcy5tYXRjaFJhd1N5bnRheCgpO1xuICAgIH1cbiAgICB0aHJvdyB0aGlzLmNyZWF0ZUVycm9yKGxvb2thaGVhZCwgJ2V4cGVjdGluZyBhIHB1bmN0dWF0b3InKTtcbiAgfVxuXG4gIGVuZm9yZXN0SWRlbnRpZmllcigpIHtcbiAgICBsZXQgbG9va2FoZWFkID0gdGhpcy5wZWVrKCk7XG4gICAgaWYgKHRoaXMuaXNJZGVudGlmaWVyKGxvb2thaGVhZCkgfHwgdGhpcy5pc0tleXdvcmQobG9va2FoZWFkKSkge1xuICAgICAgcmV0dXJuIHRoaXMubWF0Y2hSYXdTeW50YXgoKTtcbiAgICB9XG4gICAgdGhyb3cgdGhpcy5jcmVhdGVFcnJvcihsb29rYWhlYWQsICdleHBlY3RpbmcgYW4gaWRlbnRpZmllcicpO1xuICB9XG5cbiAgZW5mb3Jlc3RSZXR1cm5TdGF0ZW1lbnQoKSB7XG4gICAgbGV0IGt3ID0gdGhpcy5tYXRjaFJhd1N5bnRheCgpO1xuICAgIGxldCBsb29rYWhlYWQgPSB0aGlzLnBlZWsoKTtcblxuICAgIC8vIHNob3J0IGNpcmN1aXQgZm9yIHRoZSBlbXB0eSBleHByZXNzaW9uIGNhc2VcbiAgICBpZiAoXG4gICAgICB0aGlzLnJlc3Quc2l6ZSA9PT0gMCB8fCAobG9va2FoZWFkICYmICF0aGlzLmxpbmVOdW1iZXJFcShrdywgbG9va2FoZWFkKSlcbiAgICApIHtcbiAgICAgIHJldHVybiBuZXcgVC5SZXR1cm5TdGF0ZW1lbnQoe1xuICAgICAgICBleHByZXNzaW9uOiBudWxsLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgbGV0IHRlcm0gPSBudWxsO1xuICAgIGlmICghdGhpcy5pc1B1bmN0dWF0b3IobG9va2FoZWFkLCAnOycpKSB7XG4gICAgICB0ZXJtID0gdGhpcy5lbmZvcmVzdEV4cHJlc3Npb24oKTtcbiAgICAgIGV4cGVjdChcbiAgICAgICAgdGVybSAhPSBudWxsLFxuICAgICAgICAnRXhwZWN0aW5nIGFuIGV4cHJlc3Npb24gdG8gZm9sbG93IHJldHVybiBrZXl3b3JkJyxcbiAgICAgICAgbG9va2FoZWFkLFxuICAgICAgICB0aGlzLnJlc3QsXG4gICAgICApO1xuICAgIH1cblxuICAgIHRoaXMuY29uc3VtZVNlbWljb2xvbigpO1xuICAgIHJldHVybiBuZXcgVC5SZXR1cm5TdGF0ZW1lbnQoe1xuICAgICAgZXhwcmVzc2lvbjogdGVybSxcbiAgICB9KTtcbiAgfVxuXG4gIGVuZm9yZXN0VmFyaWFibGVEZWNsYXJhdGlvbigpIHtcbiAgICBsZXQga2luZDtcbiAgICBsZXQgbG9va2FoZWFkID0gdGhpcy5hZHZhbmNlKCk7XG5cbiAgICBpZiAodGhpcy5pc1ZhckRlY2xUcmFuc2Zvcm0obG9va2FoZWFkKSkge1xuICAgICAga2luZCA9ICd2YXInO1xuICAgIH0gZWxzZSBpZiAodGhpcy5pc0xldERlY2xUcmFuc2Zvcm0obG9va2FoZWFkKSkge1xuICAgICAga2luZCA9ICdsZXQnO1xuICAgIH0gZWxzZSBpZiAodGhpcy5pc0NvbnN0RGVjbFRyYW5zZm9ybShsb29rYWhlYWQpKSB7XG4gICAgICBraW5kID0gJ2NvbnN0JztcbiAgICB9IGVsc2UgaWYgKHRoaXMuaXNTeW50YXhEZWNsVHJhbnNmb3JtKGxvb2thaGVhZCkpIHtcbiAgICAgIGtpbmQgPSAnc3ludGF4JztcbiAgICB9IGVsc2UgaWYgKHRoaXMuaXNTeW50YXhyZWNEZWNsVHJhbnNmb3JtKGxvb2thaGVhZCkpIHtcbiAgICAgIGtpbmQgPSAnc3ludGF4cmVjJztcbiAgICB9IGVsc2UgaWYgKHRoaXMuaXNPcGVyYXRvckRlY2xUcmFuc2Zvcm0obG9va2FoZWFkKSkge1xuICAgICAga2luZCA9ICdvcGVyYXRvcic7XG4gICAgfVxuXG4gICAgbGV0IGRlY2xzID0gTGlzdCgpO1xuXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGxldCB0ZXJtID0gdGhpcy5lbmZvcmVzdFZhcmlhYmxlRGVjbGFyYXRvcih7XG4gICAgICAgIGlzU3ludGF4OiBraW5kID09PSAnc3ludGF4JyB8fFxuICAgICAgICAgIGtpbmQgPT09ICdzeW50YXhyZWMnIHx8XG4gICAgICAgICAga2luZCA9PT0gJ29wZXJhdG9yJyxcbiAgICAgICAgaXNPcGVyYXRvcjoga2luZCA9PT0gJ29wZXJhdG9yJyxcbiAgICAgIH0pO1xuICAgICAgbGV0IGxvb2thaGVhZCA9IHRoaXMucGVlaygpO1xuICAgICAgZGVjbHMgPSBkZWNscy5jb25jYXQodGVybSk7XG5cbiAgICAgIGlmICh0aGlzLmlzUHVuY3R1YXRvcihsb29rYWhlYWQsICcsJykpIHtcbiAgICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFQuVmFyaWFibGVEZWNsYXJhdGlvbih7XG4gICAgICBraW5kOiBraW5kLFxuICAgICAgZGVjbGFyYXRvcnM6IGRlY2xzLFxuICAgIH0pO1xuICB9XG5cbiAgZW5mb3Jlc3RWYXJpYWJsZURlY2xhcmF0b3IoXG4gICAgeyBpc1N5bnRheCwgaXNPcGVyYXRvciB9OiB7IGlzU3ludGF4OiBib29sZWFuLCBpc09wZXJhdG9yOiBib29sZWFuIH0sXG4gICkge1xuICAgIGxldCBpZCA9IHRoaXMuZW5mb3Jlc3RCaW5kaW5nVGFyZ2V0KHsgYWxsb3dQdW5jdHVhdG9yOiBpc1N5bnRheCB9KTtcbiAgICBjb25zdCBBc3NvY1ZhbHVlcyA9IFsnbGVmdCcsICdyaWdodCcsICdwcmVmaXgnLCAncG9zdGZpeCddO1xuXG4gICAgbGV0IGFzc29jLCBwcmVjO1xuICAgIGlmIChpc09wZXJhdG9yKSB7XG4gICAgICBhc3NvYyA9IHRoaXMubWF0Y2hJZGVudGlmaWVyKCk7XG4gICAgICBpZiAoQXNzb2NWYWx1ZXMuaW5kZXhPZihhc3NvYy52YWwoKSkgPT09IC0xKSB7XG4gICAgICAgIHRocm93IHRoaXMuY3JlYXRlRXJyb3IoXG4gICAgICAgICAgdGhpcy5wZWVrKCksXG4gICAgICAgICAgYEFzc29jaWF0aXZpdHkgbXVzdCBiZSBvbmUgb2YgJHtBc3NvY1ZhbHVlcy5qb2luKCcsJyl9YCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHByZWMgPSB0aGlzLm1hdGNoTGl0ZXJhbCgpO1xuICAgIH1cblxuICAgIGxldCBpbml0O1xuICAgIGlmICh0aGlzLmlzUHVuY3R1YXRvcih0aGlzLnBlZWsoKSwgJz0nKSkge1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICBsZXQgZW5mID0gbmV3IEVuZm9yZXN0ZXIodGhpcy5yZXN0LCBMaXN0KCksIHRoaXMuY29udGV4dCk7XG4gICAgICBpbml0ID0gZW5mLmVuZm9yZXN0KCdleHByZXNzaW9uJyk7XG4gICAgICB0aGlzLnJlc3QgPSBlbmYucmVzdDtcbiAgICB9IGVsc2Uge1xuICAgICAgaW5pdCA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKGlzT3BlcmF0b3IpIHtcbiAgICAgIHJldHVybiBuZXcgVC5PcGVyYXRvckRlY2xhcmF0b3Ioe1xuICAgICAgICBiaW5kaW5nOiBpZCxcbiAgICAgICAgaW5pdCxcbiAgICAgICAgcHJlYyxcbiAgICAgICAgYXNzb2MsXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBULlZhcmlhYmxlRGVjbGFyYXRvcih7XG4gICAgICBiaW5kaW5nOiBpZCxcbiAgICAgIGluaXQ6IGluaXQsXG4gICAgfSk7XG4gIH1cblxuICBlbmZvcmVzdEV4cHJlc3Npb25TdGF0ZW1lbnQoKSB7XG4gICAgbGV0IHN0YXJ0ID0gdGhpcy5yZXN0LmdldCgwKTtcbiAgICBsZXQgZXhwciA9IHRoaXMuZW5mb3Jlc3RFeHByZXNzaW9uKCk7XG4gICAgaWYgKGV4cHIgPT09IG51bGwpIHtcbiAgICAgIHRocm93IHRoaXMuY3JlYXRlRXJyb3Ioc3RhcnQsICdub3QgYSB2YWxpZCBleHByZXNzaW9uJyk7XG4gICAgfVxuICAgIHRoaXMuY29uc3VtZVNlbWljb2xvbigpO1xuXG4gICAgcmV0dXJuIG5ldyBULkV4cHJlc3Npb25TdGF0ZW1lbnQoe1xuICAgICAgZXhwcmVzc2lvbjogZXhwcixcbiAgICB9KTtcbiAgfVxuXG4gIGVuZm9yZXN0RXhwcmVzc2lvbigpIHtcbiAgICBsZXQgbGVmdCA9IHRoaXMuZW5mb3Jlc3RFeHByZXNzaW9uTG9vcCgpO1xuICAgIGxldCBsb29rYWhlYWQgPSB0aGlzLnBlZWsoKTtcbiAgICBpZiAodGhpcy5pc1B1bmN0dWF0b3IobG9va2FoZWFkLCAnLCcpKSB7XG4gICAgICB3aGlsZSAodGhpcy5yZXN0LnNpemUgIT09IDApIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzUHVuY3R1YXRvcih0aGlzLnBlZWsoKSwgJywnKSkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGxldCBvcGVyYXRvciA9IHRoaXMubWF0Y2hSYXdTeW50YXgoKTtcbiAgICAgICAgbGV0IHJpZ2h0ID0gdGhpcy5lbmZvcmVzdEV4cHJlc3Npb25Mb29wKCk7XG4gICAgICAgIGxlZnQgPSBuZXcgVC5CaW5hcnlFeHByZXNzaW9uKHtcbiAgICAgICAgICBsZWZ0LFxuICAgICAgICAgIG9wZXJhdG9yOiBvcGVyYXRvci52YWwoKSxcbiAgICAgICAgICByaWdodCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMudGVybSA9IG51bGw7XG4gICAgcmV0dXJuIGxlZnQ7XG4gIH1cblxuICBlbmZvcmVzdEV4cHJlc3Npb25Mb29wKCkge1xuICAgIHRoaXMudGVybSA9IG51bGw7XG4gICAgdGhpcy5vcEN0eCA9IHtcbiAgICAgIHByZWM6IDAsXG4gICAgICBjb21iaW5lOiB4ID0+IHgsXG4gICAgICBzdGFjazogTGlzdCgpLFxuICAgIH07XG5cbiAgICBkbyB7XG4gICAgICBsZXQgdGVybSA9IHRoaXMuZW5mb3Jlc3RBc3NpZ25tZW50RXhwcmVzc2lvbigpO1xuICAgICAgLy8gbm8gY2hhbmdlIG1lYW5zIHdlJ3ZlIGRvbmUgYXMgbXVjaCBlbmZvcmVzdGluZyBhcyBwb3NzaWJsZVxuICAgICAgLy8gaWYgbm90aGluZyBjaGFuZ2VkLCBtYXliZSB3ZSBqdXN0IG5lZWQgdG8gcG9wIHRoZSBleHByIHN0YWNrXG4gICAgICBpZiAodGVybSA9PT0gRVhQUl9MT09QX05PX0NIQU5HRSAmJiB0aGlzLm9wQ3R4LnN0YWNrLnNpemUgPiAwKSB7XG4gICAgICAgIHRoaXMudGVybSA9IHRoaXMub3BDdHguY29tYmluZSh0aGlzLnRlcm0pO1xuICAgICAgICBsZXQgeyBwcmVjLCBjb21iaW5lIH0gPSB0aGlzLm9wQ3R4LnN0YWNrLmxhc3QoKTtcbiAgICAgICAgdGhpcy5vcEN0eC5wcmVjID0gcHJlYztcbiAgICAgICAgdGhpcy5vcEN0eC5jb21iaW5lID0gY29tYmluZTtcbiAgICAgICAgdGhpcy5vcEN0eC5zdGFjayA9IHRoaXMub3BDdHguc3RhY2sucG9wKCk7XG4gICAgICB9IGVsc2UgaWYgKHRlcm0gPT09IEVYUFJfTE9PUF9OT19DSEFOR0UpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9IGVsc2UgaWYgKHRlcm0gPT09IEVYUFJfTE9PUF9PUEVSQVRPUiB8fCB0ZXJtID09PSBFWFBSX0xPT1BfRVhQQU5TSU9OKSB7XG4gICAgICAgIC8vIG9wZXJhdG9yIG1lYW5zIGFuIG9wQ3R4IHdhcyBwdXNoZWQgb24gdGhlIHN0YWNrXG4gICAgICAgIHRoaXMudGVybSA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnRlcm0gPSB0ZXJtO1xuICAgICAgfVxuICAgIH0gd2hpbGUgKHRydWUpOyAvLyBnZXQgYSBmaXhwb2ludFxuICAgIHJldHVybiB0aGlzLnRlcm07XG4gIH1cblxuICBlbmZvcmVzdEFzc2lnbm1lbnRFeHByZXNzaW9uKCkge1xuICAgIGxldCBsb29rYWhlYWQgPSB0aGlzLnBlZWsoKTtcblxuICAgIGlmICh0aGlzLnRlcm0gPT09IG51bGwgJiYgdGhpcy5pc01vZHVsZU5hbWVzcGFjZVRyYW5zZm9ybShsb29rYWhlYWQpKSB7XG4gICAgICAvLyAkRmxvd0ZpeE1lOiB3ZSBuZWVkIHRvIHJlZmFjdG9yIHRoZSBlbmZvcmVzdGVyIHRvIG1ha2UgZmxvdyB3b3JrIGJldHRlclxuICAgICAgbGV0IG5hbWVzcGFjZSA9IHRoaXMuZ2V0RnJvbUNvbXBpbGV0aW1lRW52aXJvbm1lbnQodGhpcy5hZHZhbmNlKCkudmFsdWUpO1xuICAgICAgdGhpcy5tYXRjaFB1bmN0dWF0b3IoJy4nKTtcbiAgICAgIGxldCBuYW1lID0gdGhpcy5tYXRjaElkZW50aWZpZXIoKTtcbiAgICAgIC8vICRGbG93Rml4TWU6IHdlIG5lZWQgdG8gcmVmYWN0b3IgdGhlIGVuZm9yZXN0ZXIgdG8gbWFrZSBmbG93IHdvcmsgYmV0dGVyXG4gICAgICBsZXQgZXhwb3J0ZWROYW1lID0gbmFtZXNwYWNlLm1vZC5leHBvcnRlZE5hbWVzLmZpbmQoXG4gICAgICAgIGV4TmFtZSA9PiBleE5hbWUuZXhwb3J0ZWROYW1lLnZhbCgpID09PSBuYW1lLnZhbCgpLFxuICAgICAgKTtcbiAgICAgIHRoaXMucmVzdCA9IHRoaXMucmVzdC51bnNoaWZ0KFxuICAgICAgICBuZXcgVC5SYXdTeW50YXgoe1xuICAgICAgICAgIHZhbHVlOiBTeW50YXguZnJvbUlkZW50aWZpZXIobmFtZS52YWwoKSwgZXhwb3J0ZWROYW1lLmV4cG9ydGVkTmFtZSksXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICAgIGxvb2thaGVhZCA9IHRoaXMucGVlaygpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnRlcm0gPT09IG51bGwgJiYgdGhpcy5pc0NvbXBpbGV0aW1lVHJhbnNmb3JtKGxvb2thaGVhZCkpIHtcbiAgICAgIHRoaXMuZXhwYW5kTWFjcm8oKTtcbiAgICAgIGxvb2thaGVhZCA9IHRoaXMucGVlaygpO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHRoaXMudGVybSA9PT0gbnVsbCAmJlxuICAgICAgdGhpcy5pc1Rlcm0obG9va2FoZWFkKSAmJlxuICAgICAgbG9va2FoZWFkIGluc3RhbmNlb2YgVC5FeHByZXNzaW9uXG4gICAgKSB7XG4gICAgICAvLyBUT0RPOiBjaGVjayB0aGF0IHRoaXMgaXMgYWN0dWFsbHkgYW4gZXhwcmVzc2lvblxuICAgICAgcmV0dXJuIHRoaXMuYWR2YW5jZSgpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnRlcm0gPT09IG51bGwgJiYgdGhpcy5pc1lpZWxkVHJhbnNmb3JtKGxvb2thaGVhZCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuZm9yZXN0WWllbGRFeHByZXNzaW9uKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudGVybSA9PT0gbnVsbCAmJiB0aGlzLmlzQ2xhc3NUcmFuc2Zvcm0obG9va2FoZWFkKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZW5mb3Jlc3RDbGFzcyh7IGlzRXhwcjogdHJ1ZSB9KTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLnRlcm0gPT09IG51bGwgJiZcbiAgICAgIGxvb2thaGVhZCAmJlxuICAgICAgKHRoaXMuaXNJZGVudGlmaWVyKGxvb2thaGVhZCkgfHwgdGhpcy5pc1BhcmVucyhsb29rYWhlYWQpKSAmJlxuICAgICAgdGhpcy5pc1B1bmN0dWF0b3IodGhpcy5wZWVrKDEpLCAnPT4nKSAmJlxuICAgICAgdGhpcy5saW5lTnVtYmVyRXEobG9va2FoZWFkLCB0aGlzLnBlZWsoMSkpXG4gICAgKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmZvcmVzdEFycm93RXhwcmVzc2lvbigpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnRlcm0gPT09IG51bGwgJiYgdGhpcy5pc1N5bnRheFRlbXBsYXRlKGxvb2thaGVhZCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuZm9yZXN0U3ludGF4VGVtcGxhdGUoKTtcbiAgICB9XG5cbiAgICAvLyAoJHg6ZXhwcilcbiAgICBpZiAodGhpcy50ZXJtID09PSBudWxsICYmIHRoaXMuaXNQYXJlbnMobG9va2FoZWFkKSkge1xuICAgICAgcmV0dXJuIG5ldyBULlBhcmVudGhlc2l6ZWRFeHByZXNzaW9uKHtcbiAgICAgICAgaW5uZXI6IHRoaXMubWF0Y2hQYXJlbnMoKSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHRoaXMudGVybSA9PT0gbnVsbCAmJlxuICAgICAgKHRoaXMuaXNLZXl3b3JkKGxvb2thaGVhZCwgJ3RoaXMnKSB8fFxuICAgICAgICB0aGlzLmlzSWRlbnRpZmllcihsb29rYWhlYWQpIHx8XG4gICAgICAgIHRoaXMuaXNLZXl3b3JkKGxvb2thaGVhZCwgJ2xldCcpIHx8XG4gICAgICAgIHRoaXMuaXNLZXl3b3JkKGxvb2thaGVhZCwgJ3lpZWxkJykgfHxcbiAgICAgICAgdGhpcy5pc051bWVyaWNMaXRlcmFsKGxvb2thaGVhZCkgfHxcbiAgICAgICAgdGhpcy5pc1N0cmluZ0xpdGVyYWwobG9va2FoZWFkKSB8fFxuICAgICAgICB0aGlzLmlzVGVtcGxhdGUobG9va2FoZWFkKSB8fFxuICAgICAgICB0aGlzLmlzQm9vbGVhbkxpdGVyYWwobG9va2FoZWFkKSB8fFxuICAgICAgICB0aGlzLmlzTnVsbExpdGVyYWwobG9va2FoZWFkKSB8fFxuICAgICAgICB0aGlzLmlzUmVndWxhckV4cHJlc3Npb24obG9va2FoZWFkKSB8fFxuICAgICAgICB0aGlzLmlzRm5EZWNsVHJhbnNmb3JtKGxvb2thaGVhZCkgfHxcbiAgICAgICAgdGhpcy5pc0JyYWNlcyhsb29rYWhlYWQpIHx8XG4gICAgICAgIHRoaXMuaXNCcmFja2V0cyhsb29rYWhlYWQpKVxuICAgICkge1xuICAgICAgcmV0dXJuIHRoaXMuZW5mb3Jlc3RQcmltYXJ5RXhwcmVzc2lvbigpO1xuICAgIH1cblxuICAgIC8vIHByZWZpeCB1bmFyeVxuICAgIGlmIChcbiAgICAgIHRoaXMudGVybSA9PT0gbnVsbCAmJlxuICAgICAgKHRoaXMuaXNPcGVyYXRvcihsb29rYWhlYWQpIHx8IHRoaXMuaXNDdXN0b21QcmVmaXhPcGVyYXRvcihsb29rYWhlYWQpKVxuICAgICkge1xuICAgICAgcmV0dXJuIHRoaXMuZW5mb3Jlc3RVbmFyeUV4cHJlc3Npb24oKTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICB0aGlzLnRlcm0gPT09IG51bGwgJiZcbiAgICAgIHRoaXMuaXNWYXJCaW5kaW5nVHJhbnNmb3JtKGxvb2thaGVhZCkgJiZcbiAgICAgIGxvb2thaGVhZCBpbnN0YW5jZW9mIFQuUmF3U3ludGF4XG4gICAgKSB7XG4gICAgICBsZXQgbG9va3N0eCA9IGxvb2thaGVhZC52YWx1ZTtcbiAgICAgIC8vICRGbG93Rml4TWVcbiAgICAgIGxldCBpZCA9IHRoaXMuZ2V0RnJvbUNvbXBpbGV0aW1lRW52aXJvbm1lbnQobG9va3N0eCkuaWQ7XG4gICAgICBpZiAoaWQgIT09IGxvb2tzdHgpIHtcbiAgICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICAgIHRoaXMucmVzdCA9IExpc3Qub2YoaWQpLmNvbmNhdCh0aGlzLnJlc3QpO1xuICAgICAgICByZXR1cm4gRVhQUl9MT09QX0VYUEFOU0lPTjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICAodGhpcy50ZXJtID09PSBudWxsICYmXG4gICAgICAgICh0aGlzLmlzTmV3VHJhbnNmb3JtKGxvb2thaGVhZCkgfHwgdGhpcy5pc1N1cGVyVHJhbnNmb3JtKGxvb2thaGVhZCkpKSB8fFxuICAgICAgLy8gYW5kIHRoZW4gY2hlY2sgdGhlIGNhc2VzIHdoZXJlIHRoZSB0ZXJtIHBhcnQgb2YgcCBpcyBzb21ldGhpbmcuLi5cbiAgICAgICh0aGlzLnRlcm0gJiZcbiAgICAgICAgLy8gJHg6ZXhwciAuICRwcm9wOmlkZW50XG4gICAgICAgICgodGhpcy5pc1B1bmN0dWF0b3IobG9va2FoZWFkLCAnLicpICYmXG4gICAgICAgICAgKHRoaXMuaXNJZGVudGlmaWVyKHRoaXMucGVlaygxKSkgfHwgdGhpcy5pc0tleXdvcmQodGhpcy5wZWVrKDEpKSkpIHx8XG4gICAgICAgICAgLy8gJHg6ZXhwciBbICRiOmV4cHIgXVxuICAgICAgICAgIHRoaXMuaXNCcmFja2V0cyhsb29rYWhlYWQpIHx8XG4gICAgICAgICAgLy8gJHg6ZXhwciAoLi4uKVxuICAgICAgICAgIHRoaXMuaXNQYXJlbnMobG9va2FoZWFkKSkpXG4gICAgKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmZvcmVzdExlZnRIYW5kU2lkZUV4cHJlc3Npb24oeyBhbGxvd0NhbGw6IHRydWUgfSk7XG4gICAgfVxuXG4gICAgLy8gcG9zdGZpeCB1bmFyeVxuICAgIGlmIChcbiAgICAgIHRoaXMudGVybSAmJlxuICAgICAgKHRoaXMuaXNVcGRhdGVPcGVyYXRvcihsb29rYWhlYWQpIHx8XG4gICAgICAgIHRoaXMuaXNDdXN0b21Qb3N0Zml4T3BlcmF0b3IobG9va2FoZWFkKSlcbiAgICApIHtcbiAgICAgIHJldHVybiB0aGlzLmVuZm9yZXN0VXBkYXRlRXhwcmVzc2lvbigpO1xuICAgIH1cblxuICAgIC8vICR4OmlkIGAuLi5gXG4gICAgaWYgKHRoaXMudGVybSAmJiB0aGlzLmlzVGVtcGxhdGUobG9va2FoZWFkKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZW5mb3Jlc3RUZW1wbGF0ZUxpdGVyYWwoKTtcbiAgICB9XG5cbiAgICAvLyAkbDpleHByICRvcDpiaW5hcnlPcGVyYXRvciAkcjpleHByXG4gICAgaWYgKFxuICAgICAgdGhpcy50ZXJtICYmXG4gICAgICAodGhpcy5pc09wZXJhdG9yKGxvb2thaGVhZCkgfHwgdGhpcy5pc0N1c3RvbUJpbmFyeU9wZXJhdG9yKGxvb2thaGVhZCkpXG4gICAgKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmZvcmVzdEJpbmFyeUV4cHJlc3Npb24oKTtcbiAgICB9XG5cbiAgICAvLyAkeDpleHByID0gJGluaXQ6ZXhwclxuICAgIGlmICh0aGlzLnRlcm0gJiYgdGhpcy5pc0Fzc2lnbihsb29rYWhlYWQpKSB7XG4gICAgICBsZXQgYmluZGluZyA9IHRoaXMudHJhbnNmb3JtRGVzdHJ1Y3R1cmluZyh0aGlzLnRlcm0pO1xuICAgICAgbGV0IG9wID0gdGhpcy5tYXRjaFJhd1N5bnRheCgpO1xuXG4gICAgICBsZXQgZW5mID0gbmV3IEVuZm9yZXN0ZXIodGhpcy5yZXN0LCBMaXN0KCksIHRoaXMuY29udGV4dCk7XG4gICAgICBsZXQgaW5pdCA9IGVuZi5lbmZvcmVzdCgnZXhwcmVzc2lvbicpO1xuICAgICAgdGhpcy5yZXN0ID0gZW5mLnJlc3Q7XG5cbiAgICAgIGlmIChvcC52YWwoKSA9PT0gJz0nKSB7XG4gICAgICAgIHJldHVybiBuZXcgVC5Bc3NpZ25tZW50RXhwcmVzc2lvbih7XG4gICAgICAgICAgYmluZGluZyxcbiAgICAgICAgICBleHByZXNzaW9uOiBpbml0LFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBuZXcgVC5Db21wb3VuZEFzc2lnbm1lbnRFeHByZXNzaW9uKHtcbiAgICAgICAgICBiaW5kaW5nLFxuICAgICAgICAgIG9wZXJhdG9yOiBvcC52YWwoKSxcbiAgICAgICAgICBleHByZXNzaW9uOiBpbml0LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy50ZXJtICYmIHRoaXMuaXNQdW5jdHVhdG9yKGxvb2thaGVhZCwgJz8nKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZW5mb3Jlc3RDb25kaXRpb25hbEV4cHJlc3Npb24oKTtcbiAgICB9XG5cbiAgICByZXR1cm4gRVhQUl9MT09QX05PX0NIQU5HRTtcbiAgfVxuXG4gIGVuZm9yZXN0UHJpbWFyeUV4cHJlc3Npb24oKSB7XG4gICAgbGV0IGxvb2thaGVhZCA9IHRoaXMucGVlaygpO1xuICAgIC8vICR4OlRoaXNFeHByZXNzaW9uXG4gICAgaWYgKHRoaXMudGVybSA9PT0gbnVsbCAmJiB0aGlzLmlzS2V5d29yZChsb29rYWhlYWQsICd0aGlzJykpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuZm9yZXN0VGhpc0V4cHJlc3Npb24oKTtcbiAgICB9XG4gICAgLy8gJHg6aWRlbnRcbiAgICBpZiAoXG4gICAgICB0aGlzLnRlcm0gPT09IG51bGwgJiZcbiAgICAgICh0aGlzLmlzSWRlbnRpZmllcihsb29rYWhlYWQpIHx8XG4gICAgICAgIHRoaXMuaXNLZXl3b3JkKGxvb2thaGVhZCwgJ2xldCcpIHx8XG4gICAgICAgIHRoaXMuaXNLZXl3b3JkKGxvb2thaGVhZCwgJ3lpZWxkJykpXG4gICAgKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmZvcmVzdElkZW50aWZpZXJFeHByZXNzaW9uKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLnRlcm0gPT09IG51bGwgJiYgdGhpcy5pc051bWVyaWNMaXRlcmFsKGxvb2thaGVhZCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuZm9yZXN0TnVtZXJpY0xpdGVyYWwoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMudGVybSA9PT0gbnVsbCAmJiB0aGlzLmlzU3RyaW5nTGl0ZXJhbChsb29rYWhlYWQpKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmZvcmVzdFN0cmluZ0xpdGVyYWwoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMudGVybSA9PT0gbnVsbCAmJiB0aGlzLmlzVGVtcGxhdGUobG9va2FoZWFkKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZW5mb3Jlc3RUZW1wbGF0ZUxpdGVyYWwoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMudGVybSA9PT0gbnVsbCAmJiB0aGlzLmlzQm9vbGVhbkxpdGVyYWwobG9va2FoZWFkKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZW5mb3Jlc3RCb29sZWFuTGl0ZXJhbCgpO1xuICAgIH1cbiAgICBpZiAodGhpcy50ZXJtID09PSBudWxsICYmIHRoaXMuaXNOdWxsTGl0ZXJhbChsb29rYWhlYWQpKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmZvcmVzdE51bGxMaXRlcmFsKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLnRlcm0gPT09IG51bGwgJiYgdGhpcy5pc1JlZ3VsYXJFeHByZXNzaW9uKGxvb2thaGVhZCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuZm9yZXN0UmVndWxhckV4cHJlc3Npb25MaXRlcmFsKCk7XG4gICAgfVxuICAgIC8vICR4OkZ1bmN0aW9uRXhwcmVzc2lvblxuICAgIGlmICh0aGlzLnRlcm0gPT09IG51bGwgJiYgdGhpcy5pc0ZuRGVjbFRyYW5zZm9ybShsb29rYWhlYWQpKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbmZvcmVzdEZ1bmN0aW9uKHsgaXNFeHByOiB0cnVlIH0pO1xuICAgIH1cbiAgICAvLyB7ICRwOnByb3AgKCwpIC4uLiB9XG4gICAgaWYgKHRoaXMudGVybSA9PT0gbnVsbCAmJiB0aGlzLmlzQnJhY2VzKGxvb2thaGVhZCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuZm9yZXN0T2JqZWN0RXhwcmVzc2lvbigpO1xuICAgIH1cbiAgICAvLyBbJHg6ZXhwciAoLCkgLi4uXVxuICAgIGlmICh0aGlzLnRlcm0gPT09IG51bGwgJiYgdGhpcy5pc0JyYWNrZXRzKGxvb2thaGVhZCkpIHtcbiAgICAgIHJldHVybiB0aGlzLmVuZm9yZXN0QXJyYXlFeHByZXNzaW9uKCk7XG4gICAgfVxuICAgIGFzc2VydChmYWxzZSwgJ05vdCBhIHByaW1hcnkgZXhwcmVzc2lvbicpO1xuICB9XG5cbiAgZW5mb3Jlc3RMZWZ0SGFuZFNpZGVFeHByZXNzaW9uKHsgYWxsb3dDYWxsIH06IHsgYWxsb3dDYWxsOiBib29sZWFuIH0pIHtcbiAgICBsZXQgbG9va2FoZWFkID0gdGhpcy5wZWVrKCk7XG5cbiAgICBpZiAodGhpcy5pc0NvbXBpbGV0aW1lVHJhbnNmb3JtKGxvb2thaGVhZCkpIHtcbiAgICAgIHRoaXMuZXhwYW5kTWFjcm8oKTtcbiAgICAgIGxvb2thaGVhZCA9IHRoaXMucGVlaygpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzU3VwZXJUcmFuc2Zvcm0obG9va2FoZWFkKSkge1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICB0aGlzLnRlcm0gPSBuZXcgVC5TdXBlcih7fSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmlzTmV3VHJhbnNmb3JtKGxvb2thaGVhZCkpIHtcbiAgICAgIHRoaXMudGVybSA9IHRoaXMuZW5mb3Jlc3ROZXdFeHByZXNzaW9uKCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmlzVGhpc1RyYW5zZm9ybShsb29rYWhlYWQpKSB7XG4gICAgICB0aGlzLnRlcm0gPSB0aGlzLmVuZm9yZXN0VGhpc0V4cHJlc3Npb24oKTtcbiAgICB9XG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgbG9va2FoZWFkID0gdGhpcy5wZWVrKCk7XG4gICAgICBpZiAodGhpcy5pc1BhcmVucyhsb29rYWhlYWQpKSB7XG4gICAgICAgIGlmICghYWxsb3dDYWxsKSB7XG4gICAgICAgICAgLy8gd2UncmUgZGVhbGluZyB3aXRoIGEgbmV3IGV4cHJlc3Npb25cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGlzLnRlcm0gJiZcbiAgICAgICAgICAgIChpc0lkZW50aWZpZXJFeHByZXNzaW9uKHRoaXMudGVybSkgfHxcbiAgICAgICAgICAgICAgaXNTdGF0aWNNZW1iZXJFeHByZXNzaW9uKHRoaXMudGVybSkgfHxcbiAgICAgICAgICAgICAgaXNDb21wdXRlZE1lbWJlckV4cHJlc3Npb24odGhpcy50ZXJtKSlcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnRlcm07XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMudGVybSA9IHRoaXMuZW5mb3Jlc3RFeHByZXNzaW9uTG9vcCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMudGVybSA9IHRoaXMuZW5mb3Jlc3RDYWxsRXhwcmVzc2lvbigpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuaXNCcmFja2V0cyhsb29rYWhlYWQpKSB7XG4gICAgICAgIHRoaXMudGVybSA9IHRoaXMudGVybVxuICAgICAgICAgID8gdGhpcy5lbmZvcmVzdENvbXB1dGVkTWVtYmVyRXhwcmVzc2lvbigpXG4gICAgICAgICAgOiB0aGlzLmVuZm9yZXN0UHJpbWFyeUV4cHJlc3Npb24oKTtcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIHRoaXMuaXNQdW5jdHVhdG9yKGxvb2thaGVhZCwgJy4nKSAmJlxuICAgICAgICAodGhpcy5pc0lkZW50aWZpZXIodGhpcy5wZWVrKDEpKSB8fCB0aGlzLmlzS2V5d29yZCh0aGlzLnBlZWsoMSkpKVxuICAgICAgKSB7XG4gICAgICAgIHRoaXMudGVybSA9IHRoaXMuZW5mb3Jlc3RTdGF0aWNNZW1iZXJFeHByZXNzaW9uKCk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuaXNUZW1wbGF0ZShsb29rYWhlYWQpKSB7XG4gICAgICAgIHRoaXMudGVybSA9IHRoaXMuZW5mb3Jlc3RUZW1wbGF0ZUxpdGVyYWwoKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5pc0JyYWNlcyhsb29rYWhlYWQpKSB7XG4gICAgICAgIHRoaXMudGVybSA9IHRoaXMuZW5mb3Jlc3RQcmltYXJ5RXhwcmVzc2lvbigpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmlzSWRlbnRpZmllcihsb29rYWhlYWQpKSB7XG4gICAgICAgIGlmICh0aGlzLnRlcm0pIGJyZWFrO1xuICAgICAgICB0aGlzLnRlcm0gPSBuZXcgVC5JZGVudGlmaWVyRXhwcmVzc2lvbih7XG4gICAgICAgICAgbmFtZTogdGhpcy5lbmZvcmVzdElkZW50aWZpZXIoKSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudGVybTtcbiAgfVxuXG4gIGVuZm9yZXN0Qm9vbGVhbkxpdGVyYWwoKSB7XG4gICAgcmV0dXJuIG5ldyBULkxpdGVyYWxCb29sZWFuRXhwcmVzc2lvbih7XG4gICAgICB2YWx1ZTogdGhpcy5tYXRjaFJhd1N5bnRheCgpLnZhbCgpID09PSAndHJ1ZScsXG4gICAgfSk7XG4gIH1cblxuICBlbmZvcmVzdFRlbXBsYXRlTGl0ZXJhbCgpIHtcbiAgICByZXR1cm4gbmV3IFQuVGVtcGxhdGVFeHByZXNzaW9uKHtcbiAgICAgIHRhZzogdGhpcy50ZXJtLFxuICAgICAgZWxlbWVudHM6IHRoaXMuZW5mb3Jlc3RUZW1wbGF0ZUVsZW1lbnRzKCksXG4gICAgfSk7XG4gIH1cblxuICBlbmZvcmVzdFN0cmluZ0xpdGVyYWwoKSB7XG4gICAgcmV0dXJuIG5ldyBULkxpdGVyYWxTdHJpbmdFeHByZXNzaW9uKHtcbiAgICAgIHZhbHVlOiB0aGlzLm1hdGNoUmF3U3ludGF4KCkudmFsKCksXG4gICAgfSk7XG4gIH1cblxuICBlbmZvcmVzdE51bWVyaWNMaXRlcmFsKCkge1xuICAgIGxldCBudW0gPSB0aGlzLm1hdGNoUmF3U3ludGF4KCk7XG4gICAgaWYgKG51bS52YWwoKSA9PT0gMSAvIDApIHtcbiAgICAgIHJldHVybiBuZXcgVC5MaXRlcmFsSW5maW5pdHlFeHByZXNzaW9uKHt9KTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBULkxpdGVyYWxOdW1lcmljRXhwcmVzc2lvbih7XG4gICAgICB2YWx1ZTogbnVtLnZhbCgpLFxuICAgIH0pO1xuICB9XG5cbiAgZW5mb3Jlc3RJZGVudGlmaWVyRXhwcmVzc2lvbigpIHtcbiAgICByZXR1cm4gbmV3IFQuSWRlbnRpZmllckV4cHJlc3Npb24oe1xuICAgICAgbmFtZTogdGhpcy5tYXRjaFJhd1N5bnRheCgpLFxuICAgIH0pO1xuICB9XG5cbiAgZW5mb3Jlc3RSZWd1bGFyRXhwcmVzc2lvbkxpdGVyYWwoKSB7XG4gICAgbGV0IHJlU3R4ID0gdGhpcy5tYXRjaFJhd1N5bnRheCgpO1xuXG4gICAgbGV0IGxhc3RTbGFzaCA9IHJlU3R4LnRva2VuLnZhbHVlLmxhc3RJbmRleE9mKCcvJyk7XG4gICAgbGV0IHBhdHRlcm4gPSByZVN0eC50b2tlbi52YWx1ZS5zbGljZSgxLCBsYXN0U2xhc2gpO1xuICAgIGxldCBmbGFncyA9IHJlU3R4LnRva2VuLnZhbHVlLnNsaWNlKGxhc3RTbGFzaCArIDEpO1xuICAgIHJldHVybiBuZXcgVC5MaXRlcmFsUmVnRXhwRXhwcmVzc2lvbih7XG4gICAgICBwYXR0ZXJuLFxuICAgICAgZmxhZ3MsXG4gICAgfSk7XG4gIH1cblxuICBlbmZvcmVzdE51bGxMaXRlcmFsKCkge1xuICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgIHJldHVybiBuZXcgVC5MaXRlcmFsTnVsbEV4cHJlc3Npb24oe30pO1xuICB9XG5cbiAgZW5mb3Jlc3RUaGlzRXhwcmVzc2lvbigpIHtcbiAgICByZXR1cm4gbmV3IFQuVGhpc0V4cHJlc3Npb24oe1xuICAgICAgc3R4OiB0aGlzLm1hdGNoUmF3U3ludGF4KCksXG4gICAgfSk7XG4gIH1cblxuICBlbmZvcmVzdEFyZ3VtZW50TGlzdCgpIHtcbiAgICBsZXQgcmVzdWx0ID0gW107XG4gICAgd2hpbGUgKHRoaXMucmVzdC5zaXplID4gMCkge1xuICAgICAgbGV0IGFyZztcbiAgICAgIGlmICh0aGlzLmlzUHVuY3R1YXRvcih0aGlzLnBlZWsoKSwgJy4uLicpKSB7XG4gICAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgICBhcmcgPSBuZXcgVC5TcHJlYWRFbGVtZW50KHtcbiAgICAgICAgICBleHByZXNzaW9uOiB0aGlzLmVuZm9yZXN0RXhwcmVzc2lvbkxvb3AoKSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhcmcgPSB0aGlzLmVuZm9yZXN0RXhwcmVzc2lvbkxvb3AoKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLnJlc3Quc2l6ZSA+IDApIHtcbiAgICAgICAgdGhpcy5tYXRjaFB1bmN0dWF0b3IoJywnKTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdC5wdXNoKGFyZyk7XG4gICAgfVxuICAgIHJldHVybiBMaXN0KHJlc3VsdCk7XG4gIH1cblxuICBlbmZvcmVzdE5ld0V4cHJlc3Npb24oKSB7XG4gICAgdGhpcy5tYXRjaEtleXdvcmQoJ25ldycpO1xuICAgIGlmIChcbiAgICAgIHRoaXMuaXNQdW5jdHVhdG9yKHRoaXMucGVlaygpLCAnLicpICYmXG4gICAgICB0aGlzLmlzSWRlbnRpZmllcih0aGlzLnBlZWsoMSksICd0YXJnZXQnKVxuICAgICkge1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIHJldHVybiBuZXcgVC5OZXdUYXJnZXRFeHByZXNzaW9uKHt9KTtcbiAgICB9XG5cbiAgICBsZXQgY2FsbGVlID0gdGhpcy5lbmZvcmVzdExlZnRIYW5kU2lkZUV4cHJlc3Npb24oeyBhbGxvd0NhbGw6IGZhbHNlIH0pO1xuICAgIGxldCBhcmdzO1xuICAgIGlmICh0aGlzLmlzUGFyZW5zKHRoaXMucGVlaygpKSkge1xuICAgICAgYXJncyA9IHRoaXMubWF0Y2hQYXJlbnMoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXJncyA9IExpc3QoKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBULk5ld0V4cHJlc3Npb24oe1xuICAgICAgY2FsbGVlLFxuICAgICAgYXJndW1lbnRzOiBhcmdzLFxuICAgIH0pO1xuICB9XG5cbiAgZW5mb3Jlc3RDb21wdXRlZE1lbWJlckV4cHJlc3Npb24oKSB7XG4gICAgbGV0IGVuZiA9IG5ldyBFbmZvcmVzdGVyKHRoaXMubWF0Y2hTcXVhcmVzKCksIExpc3QoKSwgdGhpcy5jb250ZXh0KTtcbiAgICByZXR1cm4gbmV3IFQuQ29tcHV0ZWRNZW1iZXJFeHByZXNzaW9uKHtcbiAgICAgIG9iamVjdDogdGhpcy50ZXJtLFxuICAgICAgZXhwcmVzc2lvbjogZW5mLmVuZm9yZXN0RXhwcmVzc2lvbigpLFxuICAgIH0pO1xuICB9XG5cbiAgdHJhbnNmb3JtRGVzdHJ1Y3R1cmluZyh0ZXJtOiBUZXJtKSB7XG4gICAgc3dpdGNoICh0ZXJtLnR5cGUpIHtcbiAgICAgIGNhc2UgJ0lkZW50aWZpZXJFeHByZXNzaW9uJzpcbiAgICAgICAgcmV0dXJuIG5ldyBULkJpbmRpbmdJZGVudGlmaWVyKHsgbmFtZTogdGVybS5uYW1lIH0pO1xuXG4gICAgICBjYXNlICdQYXJlbnRoZXNpemVkRXhwcmVzc2lvbic6XG4gICAgICAgIGlmICh0ZXJtLmlubmVyLnNpemUgPT09IDEgJiYgdGhpcy5pc0lkZW50aWZpZXIodGVybS5pbm5lci5nZXQoMCkpKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBULkJpbmRpbmdJZGVudGlmaWVyKHsgbmFtZTogdGVybS5pbm5lci5nZXQoMCkudmFsdWUgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRlcm07XG4gICAgICBjYXNlICdEYXRhUHJvcGVydHknOlxuICAgICAgICByZXR1cm4gbmV3IFQuQmluZGluZ1Byb3BlcnR5UHJvcGVydHkoe1xuICAgICAgICAgIG5hbWU6IHRlcm0ubmFtZSxcbiAgICAgICAgICBiaW5kaW5nOiB0aGlzLnRyYW5zZm9ybURlc3RydWN0dXJpbmdXaXRoRGVmYXVsdCh0ZXJtLmV4cHJlc3Npb24pLFxuICAgICAgICB9KTtcbiAgICAgIGNhc2UgJ1Nob3J0aGFuZFByb3BlcnR5JzpcbiAgICAgICAgcmV0dXJuIG5ldyBULkJpbmRpbmdQcm9wZXJ0eUlkZW50aWZpZXIoe1xuICAgICAgICAgIGJpbmRpbmc6IG5ldyBULkJpbmRpbmdJZGVudGlmaWVyKHsgbmFtZTogdGVybS5uYW1lIH0pLFxuICAgICAgICAgIGluaXQ6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgY2FzZSAnT2JqZWN0RXhwcmVzc2lvbic6XG4gICAgICAgIHJldHVybiBuZXcgVC5PYmplY3RCaW5kaW5nKHtcbiAgICAgICAgICBwcm9wZXJ0aWVzOiB0ZXJtLnByb3BlcnRpZXMubWFwKHQgPT4gdGhpcy50cmFuc2Zvcm1EZXN0cnVjdHVyaW5nKHQpKSxcbiAgICAgICAgfSk7XG4gICAgICBjYXNlICdBcnJheUV4cHJlc3Npb24nOiB7XG4gICAgICAgIGxldCBsYXN0ID0gdGVybS5lbGVtZW50cy5sYXN0KCk7XG4gICAgICAgIGlmIChsYXN0ICE9IG51bGwgJiYgbGFzdC50eXBlID09PSAnU3ByZWFkRWxlbWVudCcpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFQuQXJyYXlCaW5kaW5nKHtcbiAgICAgICAgICAgIGVsZW1lbnRzOiB0ZXJtLmVsZW1lbnRzXG4gICAgICAgICAgICAgIC5zbGljZSgwLCAtMSlcbiAgICAgICAgICAgICAgLm1hcCh0ID0+IHQgJiYgdGhpcy50cmFuc2Zvcm1EZXN0cnVjdHVyaW5nV2l0aERlZmF1bHQodCkpLFxuICAgICAgICAgICAgcmVzdEVsZW1lbnQ6IHRoaXMudHJhbnNmb3JtRGVzdHJ1Y3R1cmluZ1dpdGhEZWZhdWx0KFxuICAgICAgICAgICAgICBsYXN0LmV4cHJlc3Npb24sXG4gICAgICAgICAgICApLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBuZXcgVC5BcnJheUJpbmRpbmcoe1xuICAgICAgICAgICAgZWxlbWVudHM6IHRlcm0uZWxlbWVudHMubWFwKFxuICAgICAgICAgICAgICB0ID0+IHQgJiYgdGhpcy50cmFuc2Zvcm1EZXN0cnVjdHVyaW5nV2l0aERlZmF1bHQodCksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgcmVzdEVsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNhc2UgJ1N0YXRpY1Byb3BlcnR5TmFtZSc6XG4gICAgICAgIHJldHVybiBuZXcgVC5CaW5kaW5nSWRlbnRpZmllcih7XG4gICAgICAgICAgbmFtZTogdGVybS52YWx1ZSxcbiAgICAgICAgfSk7XG4gICAgICBjYXNlICdDb21wdXRlZE1lbWJlckV4cHJlc3Npb24nOlxuICAgICAgY2FzZSAnU3RhdGljTWVtYmVyRXhwcmVzc2lvbic6XG4gICAgICBjYXNlICdBcnJheUJpbmRpbmcnOlxuICAgICAgY2FzZSAnQmluZGluZ0lkZW50aWZpZXInOlxuICAgICAgY2FzZSAnQmluZGluZ1Byb3BlcnR5SWRlbnRpZmllcic6XG4gICAgICBjYXNlICdCaW5kaW5nUHJvcGVydHlQcm9wZXJ0eSc6XG4gICAgICBjYXNlICdCaW5kaW5nV2l0aERlZmF1bHQnOlxuICAgICAgY2FzZSAnT2JqZWN0QmluZGluZyc6XG4gICAgICAgIHJldHVybiB0ZXJtO1xuICAgIH1cbiAgICBhc3NlcnQoZmFsc2UsICdub3QgaW1wbGVtZW50ZWQgeWV0IGZvciAnICsgdGVybS50eXBlKTtcbiAgfVxuXG4gIHRyYW5zZm9ybURlc3RydWN0dXJpbmdXaXRoRGVmYXVsdCh0ZXJtOiBUZXJtKSB7XG4gICAgc3dpdGNoICh0ZXJtLnR5cGUpIHtcbiAgICAgIGNhc2UgJ0Fzc2lnbm1lbnRFeHByZXNzaW9uJzpcbiAgICAgICAgcmV0dXJuIG5ldyBULkJpbmRpbmdXaXRoRGVmYXVsdCh7XG4gICAgICAgICAgYmluZGluZzogdGhpcy50cmFuc2Zvcm1EZXN0cnVjdHVyaW5nKHRlcm0uYmluZGluZyksXG4gICAgICAgICAgaW5pdDogdGVybS5leHByZXNzaW9uLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtRGVzdHJ1Y3R1cmluZyh0ZXJtKTtcbiAgfVxuXG4gIGVuZm9yZXN0Q2FsbEV4cHJlc3Npb24oKSB7XG4gICAgbGV0IHBhcmVuID0gdGhpcy5tYXRjaFBhcmVucygpO1xuICAgIHJldHVybiBuZXcgVC5DYWxsRXhwcmVzc2lvbkUoe1xuICAgICAgY2FsbGVlOiB0aGlzLnRlcm0sXG4gICAgICBhcmd1bWVudHM6IHBhcmVuLFxuICAgIH0pO1xuICB9XG5cbiAgZW5mb3Jlc3RBcnJvd0V4cHJlc3Npb24oKSB7XG4gICAgbGV0IGVuZjtcbiAgICBpZiAodGhpcy5pc0lkZW50aWZpZXIodGhpcy5wZWVrKCkpKSB7XG4gICAgICBlbmYgPSBuZXcgRW5mb3Jlc3RlcihMaXN0Lm9mKHRoaXMuYWR2YW5jZSgpKSwgTGlzdCgpLCB0aGlzLmNvbnRleHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgcCA9IHRoaXMubWF0Y2hQYXJlbnMoKTtcbiAgICAgIGVuZiA9IG5ldyBFbmZvcmVzdGVyKHAsIExpc3QoKSwgdGhpcy5jb250ZXh0KTtcbiAgICB9XG4gICAgbGV0IHBhcmFtcyA9IGVuZi5lbmZvcmVzdEZvcm1hbFBhcmFtZXRlcnMoKTtcbiAgICB0aGlzLm1hdGNoUHVuY3R1YXRvcignPT4nKTtcblxuICAgIGxldCBib2R5O1xuICAgIGlmICh0aGlzLmlzQnJhY2VzKHRoaXMucGVlaygpKSkge1xuICAgICAgYm9keSA9IHRoaXMubWF0Y2hDdXJsaWVzKCk7XG4gICAgICByZXR1cm4gbmV3IFQuQXJyb3dFeHByZXNzaW9uRSh7IHBhcmFtcywgYm9keSB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW5mID0gbmV3IEVuZm9yZXN0ZXIodGhpcy5yZXN0LCBMaXN0KCksIHRoaXMuY29udGV4dCk7XG4gICAgICBib2R5ID0gZW5mLmVuZm9yZXN0RXhwcmVzc2lvbkxvb3AoKTtcbiAgICAgIHRoaXMucmVzdCA9IGVuZi5yZXN0O1xuICAgICAgcmV0dXJuIG5ldyBULkFycm93RXhwcmVzc2lvbih7IHBhcmFtcywgYm9keSB9KTtcbiAgICB9XG4gIH1cblxuICBlbmZvcmVzdFlpZWxkRXhwcmVzc2lvbigpIHtcbiAgICBsZXQga3dkID0gdGhpcy5tYXRjaEtleXdvcmQoJ3lpZWxkJyk7XG4gICAgbGV0IGxvb2thaGVhZCA9IHRoaXMucGVlaygpO1xuXG4gICAgaWYgKFxuICAgICAgdGhpcy5yZXN0LnNpemUgPT09IDAgfHwgKGxvb2thaGVhZCAmJiAhdGhpcy5saW5lTnVtYmVyRXEoa3dkLCBsb29rYWhlYWQpKVxuICAgICkge1xuICAgICAgcmV0dXJuIG5ldyBULllpZWxkRXhwcmVzc2lvbih7XG4gICAgICAgIGV4cHJlc3Npb246IG51bGwsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IGlzR2VuZXJhdG9yID0gZmFsc2U7XG4gICAgICBpZiAodGhpcy5pc1B1bmN0dWF0b3IodGhpcy5wZWVrKCksICcqJykpIHtcbiAgICAgICAgaXNHZW5lcmF0b3IgPSB0cnVlO1xuICAgICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIH1cbiAgICAgIGxldCBleHByID0gdGhpcy5lbmZvcmVzdEV4cHJlc3Npb24oKTtcbiAgICAgIHJldHVybiBuZXcgKGlzR2VuZXJhdG9yXG4gICAgICAgID8gVC5ZaWVsZEdlbmVyYXRvckV4cHJlc3Npb25cbiAgICAgICAgOiBULllpZWxkRXhwcmVzc2lvbikoe1xuICAgICAgICBleHByZXNzaW9uOiBleHByLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZW5mb3Jlc3RTeW50YXhUZW1wbGF0ZSgpIHtcbiAgICByZXR1cm4gbmV3IFQuU3ludGF4VGVtcGxhdGUoe1xuICAgICAgdGVtcGxhdGU6IHRoaXMubWF0Y2hSYXdEZWxpbWl0ZXIoKSxcbiAgICB9KTtcbiAgfVxuXG4gIGVuZm9yZXN0U3RhdGljTWVtYmVyRXhwcmVzc2lvbigpIHtcbiAgICBsZXQgb2JqZWN0ID0gdGhpcy50ZXJtO1xuICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgIGxldCBwcm9wZXJ0eSA9IHRoaXMubWF0Y2hSYXdTeW50YXgoKTtcblxuICAgIHJldHVybiBuZXcgVC5TdGF0aWNNZW1iZXJFeHByZXNzaW9uKHtcbiAgICAgIG9iamVjdDogb2JqZWN0LFxuICAgICAgcHJvcGVydHk6IHByb3BlcnR5LFxuICAgIH0pO1xuICB9XG5cbiAgZW5mb3Jlc3RBcnJheUV4cHJlc3Npb24oKSB7XG4gICAgbGV0IGFyciA9IHRoaXMubWF0Y2hTcXVhcmVzKCk7XG5cbiAgICBsZXQgZWxlbWVudHMgPSBbXTtcblxuICAgIGxldCBlbmYgPSBuZXcgRW5mb3Jlc3RlcihhcnIsIExpc3QoKSwgdGhpcy5jb250ZXh0KTtcblxuICAgIHdoaWxlIChlbmYucmVzdC5zaXplID4gMCkge1xuICAgICAgbGV0IGxvb2thaGVhZCA9IGVuZi5wZWVrKCk7XG4gICAgICBsZXQgZXhwcmVzc2lvbiA9IG51bGw7XG4gICAgICBpZiAoIWVuZi5pc1B1bmN0dWF0b3IobG9va2FoZWFkLCAnLCcpKSB7XG4gICAgICAgIGxldCBpc1NwcmVhZCA9IGZhbHNlO1xuICAgICAgICBpZiAoZW5mLmlzUHVuY3R1YXRvcihsb29rYWhlYWQsICcuLi4nKSkge1xuICAgICAgICAgIGVuZi5hZHZhbmNlKCk7XG4gICAgICAgICAgaXNTcHJlYWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGV4cHJlc3Npb24gPSBlbmYuZW5mb3Jlc3RFeHByZXNzaW9uTG9vcCgpO1xuICAgICAgICBpZiAoZXhwcmVzc2lvbiA9PSBudWxsKSB7XG4gICAgICAgICAgLy8gdGhpcyB3YXMgYSBtYWNybyB0aGF0IGV4cGFuZGVkIHRvIG5vdGhpbmdcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZW5mLnJlc3Quc2l6ZSA+IDAgJiYgIWVuZi5pc1B1bmN0dWF0b3IoZW5mLnBlZWsoKSwgJywnKSkge1xuICAgICAgICAgIHRocm93IGVuZi5jcmVhdGVFcnJvcihlbmYucGVlaygpLCAndW5leHBlY3RlZCB0b2tlbicpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc1NwcmVhZCkge1xuICAgICAgICAgIGV4cHJlc3Npb24gPSBuZXcgVC5TcHJlYWRFbGVtZW50KHsgZXhwcmVzc2lvbiB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZW5mLmNvbnN1bWVDb21tYSgpO1xuICAgICAgZWxlbWVudHMucHVzaChleHByZXNzaW9uKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFQuQXJyYXlFeHByZXNzaW9uKHtcbiAgICAgIGVsZW1lbnRzOiBMaXN0KGVsZW1lbnRzKSxcbiAgICB9KTtcbiAgfVxuXG4gIGVuZm9yZXN0T2JqZWN0RXhwcmVzc2lvbigpIHtcbiAgICBsZXQgb2JqID0gdGhpcy5tYXRjaEN1cmxpZXMoKTtcblxuICAgIGxldCBwcm9wZXJ0aWVzID0gTGlzdCgpO1xuXG4gICAgbGV0IGVuZiA9IG5ldyBFbmZvcmVzdGVyKG9iaiwgTGlzdCgpLCB0aGlzLmNvbnRleHQpO1xuXG4gICAgbGV0IGxhc3RQcm9wID0gbnVsbDtcbiAgICAvL1RPRE86IGltcGxlbWVudCBvYmplY3Qgc3ByZWFkIG9wZXJhdG9yIHdoZW4gaXQgbGFuZHNcbiAgICB3aGlsZSAoZW5mLnJlc3Quc2l6ZSA+IDApIHtcbiAgICAgIGxldCBwcm9wID0gZW5mLmVuZm9yZXN0UHJvcGVydHlEZWZpbml0aW9uKCk7XG5cbiAgICAgIGlmIChlbmYucmVzdC5zaXplID4gMCAmJiAhZW5mLmlzUHVuY3R1YXRvcihlbmYucGVlaygpLCAnLCcpKSB7XG4gICAgICAgIHRocm93IGVuZi5jcmVhdGVFcnJvcihlbmYucGVlaygpLCAndW5leHBlY3RlZCB0b2tlbicpO1xuICAgICAgfVxuXG4gICAgICBlbmYuY29uc3VtZUNvbW1hKCk7XG4gICAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcy5jb25jYXQocHJvcCk7XG5cbiAgICAgIGlmIChsYXN0UHJvcCA9PT0gcHJvcCkge1xuICAgICAgICB0aHJvdyBlbmYuY3JlYXRlRXJyb3IocHJvcCwgJ2ludmFsaWQgc3ludGF4IGluIG9iamVjdCcpO1xuICAgICAgfVxuICAgICAgbGFzdFByb3AgPSBwcm9wO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgVC5PYmplY3RFeHByZXNzaW9uKHtcbiAgICAgIHByb3BlcnRpZXM6IHByb3BlcnRpZXMsXG4gICAgfSk7XG4gIH1cblxuICBlbmZvcmVzdFByb3BlcnR5RGVmaW5pdGlvbigpIHtcbiAgICBsZXQgeyBtZXRob2RPcktleSwga2luZCB9ID0gdGhpcy5lbmZvcmVzdE1ldGhvZERlZmluaXRpb24oKTtcblxuICAgIHN3aXRjaCAoa2luZCkge1xuICAgICAgY2FzZSAnbWV0aG9kJzpcbiAgICAgICAgcmV0dXJuIG1ldGhvZE9yS2V5O1xuICAgICAgY2FzZSAnaWRlbnRpZmllcic6XG4gICAgICAgIGlmICh0aGlzLmlzQXNzaWduKHRoaXMucGVlaygpKSkge1xuICAgICAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgICAgIGxldCBpbml0ID0gdGhpcy5lbmZvcmVzdEV4cHJlc3Npb25Mb29wKCk7XG4gICAgICAgICAgcmV0dXJuIG5ldyBULkJpbmRpbmdQcm9wZXJ0eUlkZW50aWZpZXIoe1xuICAgICAgICAgICAgaW5pdCxcbiAgICAgICAgICAgIGJpbmRpbmc6IHRoaXMudHJhbnNmb3JtRGVzdHJ1Y3R1cmluZyhtZXRob2RPcktleSksXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoIXRoaXMuaXNQdW5jdHVhdG9yKHRoaXMucGVlaygpLCAnOicpKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBULlNob3J0aGFuZFByb3BlcnR5KHtcbiAgICAgICAgICAgIG5hbWU6IG1ldGhvZE9yS2V5LnZhbHVlLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5tYXRjaFB1bmN0dWF0b3IoJzonKTtcbiAgICBsZXQgZXhwciA9IHRoaXMuZW5mb3Jlc3RFeHByZXNzaW9uTG9vcCgpO1xuXG4gICAgcmV0dXJuIG5ldyBULkRhdGFQcm9wZXJ0eSh7XG4gICAgICBuYW1lOiBtZXRob2RPcktleSxcbiAgICAgIGV4cHJlc3Npb246IGV4cHIsXG4gICAgfSk7XG4gIH1cblxuICBlbmZvcmVzdE1ldGhvZERlZmluaXRpb24oKSB7XG4gICAgbGV0IGxvb2thaGVhZCA9IHRoaXMucGVlaygpO1xuICAgIGxldCBpc0dlbmVyYXRvciA9IGZhbHNlO1xuICAgIGlmICh0aGlzLmlzUHVuY3R1YXRvcihsb29rYWhlYWQsICcqJykpIHtcbiAgICAgIGlzR2VuZXJhdG9yID0gdHJ1ZTtcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHRoaXMuaXNJZGVudGlmaWVyKGxvb2thaGVhZCwgJ2dldCcpICYmIHRoaXMuaXNQcm9wZXJ0eU5hbWUodGhpcy5wZWVrKDEpKVxuICAgICkge1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICBsZXQgeyBuYW1lIH0gPSB0aGlzLmVuZm9yZXN0UHJvcGVydHlOYW1lKCk7XG4gICAgICB0aGlzLm1hdGNoUGFyZW5zKCk7XG4gICAgICBsZXQgYm9keSA9IHRoaXMubWF0Y2hDdXJsaWVzKCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBtZXRob2RPcktleTogbmV3IFQuR2V0dGVyKHsgbmFtZSwgYm9keSB9KSxcbiAgICAgICAga2luZDogJ21ldGhvZCcsXG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICB0aGlzLmlzSWRlbnRpZmllcihsb29rYWhlYWQsICdzZXQnKSAmJiB0aGlzLmlzUHJvcGVydHlOYW1lKHRoaXMucGVlaygxKSlcbiAgICApIHtcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgbGV0IHsgbmFtZSB9ID0gdGhpcy5lbmZvcmVzdFByb3BlcnR5TmFtZSgpO1xuICAgICAgbGV0IGVuZiA9IG5ldyBFbmZvcmVzdGVyKHRoaXMubWF0Y2hQYXJlbnMoKSwgTGlzdCgpLCB0aGlzLmNvbnRleHQpO1xuICAgICAgbGV0IHBhcmFtID0gZW5mLmVuZm9yZXN0QmluZGluZ0VsZW1lbnQoKTtcbiAgICAgIGxldCBib2R5ID0gdGhpcy5tYXRjaEN1cmxpZXMoKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG1ldGhvZE9yS2V5OiBuZXcgVC5TZXR0ZXIoeyBuYW1lLCBwYXJhbSwgYm9keSB9KSxcbiAgICAgICAga2luZDogJ21ldGhvZCcsXG4gICAgICB9O1xuICAgIH1cbiAgICBsZXQgeyBuYW1lIH0gPSB0aGlzLmVuZm9yZXN0UHJvcGVydHlOYW1lKCk7XG4gICAgaWYgKHRoaXMuaXNQYXJlbnModGhpcy5wZWVrKCkpKSB7XG4gICAgICBsZXQgcGFyYW1zID0gdGhpcy5tYXRjaFBhcmVucygpO1xuICAgICAgbGV0IGVuZiA9IG5ldyBFbmZvcmVzdGVyKHBhcmFtcywgTGlzdCgpLCB0aGlzLmNvbnRleHQpO1xuICAgICAgbGV0IGZvcm1hbFBhcmFtcyA9IGVuZi5lbmZvcmVzdEZvcm1hbFBhcmFtZXRlcnMoKTtcblxuICAgICAgbGV0IGJvZHkgPSB0aGlzLm1hdGNoQ3VybGllcygpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbWV0aG9kT3JLZXk6IG5ldyBULk1ldGhvZCh7XG4gICAgICAgICAgaXNHZW5lcmF0b3IsXG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgICBwYXJhbXM6IGZvcm1hbFBhcmFtcyxcbiAgICAgICAgICBib2R5LFxuICAgICAgICB9KSxcbiAgICAgICAga2luZDogJ21ldGhvZCcsXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgbWV0aG9kT3JLZXk6IG5hbWUsXG4gICAgICBraW5kOiB0aGlzLmlzSWRlbnRpZmllcihsb29rYWhlYWQpIHx8IHRoaXMuaXNLZXl3b3JkKGxvb2thaGVhZClcbiAgICAgICAgPyAnaWRlbnRpZmllcidcbiAgICAgICAgOiAncHJvcGVydHknLFxuICAgIH07XG4gIH1cblxuICBlbmZvcmVzdFByb3BlcnR5TmFtZSgpIHtcbiAgICBsZXQgbG9va2FoZWFkID0gdGhpcy5wZWVrKCk7XG5cbiAgICBpZiAodGhpcy5pc1N0cmluZ0xpdGVyYWwobG9va2FoZWFkKSB8fCB0aGlzLmlzTnVtZXJpY0xpdGVyYWwobG9va2FoZWFkKSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbmFtZTogbmV3IFQuU3RhdGljUHJvcGVydHlOYW1lKHtcbiAgICAgICAgICB2YWx1ZTogdGhpcy5tYXRjaFJhd1N5bnRheCgpLFxuICAgICAgICB9KSxcbiAgICAgICAgYmluZGluZzogbnVsbCxcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmICh0aGlzLmlzQnJhY2tldHMobG9va2FoZWFkKSkge1xuICAgICAgbGV0IGVuZiA9IG5ldyBFbmZvcmVzdGVyKHRoaXMubWF0Y2hTcXVhcmVzKCksIExpc3QoKSwgdGhpcy5jb250ZXh0KTtcbiAgICAgIGxldCBleHByID0gZW5mLmVuZm9yZXN0RXhwcmVzc2lvbkxvb3AoKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG5hbWU6IG5ldyBULkNvbXB1dGVkUHJvcGVydHlOYW1lKHtcbiAgICAgICAgICBleHByZXNzaW9uOiBleHByLFxuICAgICAgICB9KSxcbiAgICAgICAgYmluZGluZzogbnVsbCxcbiAgICAgIH07XG4gICAgfVxuICAgIGxldCBuYW1lID0gdGhpcy5tYXRjaFJhd1N5bnRheCgpO1xuICAgIHJldHVybiB7XG4gICAgICBuYW1lOiBuZXcgVC5TdGF0aWNQcm9wZXJ0eU5hbWUoeyB2YWx1ZTogbmFtZSB9KSxcbiAgICAgIGJpbmRpbmc6IG5ldyBULkJpbmRpbmdJZGVudGlmaWVyKHsgbmFtZSB9KSxcbiAgICB9O1xuICB9XG5cbiAgZW5mb3Jlc3RGdW5jdGlvbihcbiAgICB7IGlzRXhwciwgaW5EZWZhdWx0IH06IHsgaXNFeHByPzogYm9vbGVhbiwgaW5EZWZhdWx0PzogYm9vbGVhbiB9LFxuICApIHtcbiAgICBsZXQgbmFtZSA9IG51bGwsIHBhcmFtcywgYm9keTtcbiAgICBsZXQgaXNHZW5lcmF0b3IgPSBmYWxzZTtcbiAgICAvLyBlYXQgdGhlIGZ1bmN0aW9uIGtleXdvcmRcbiAgICBsZXQgZm5LZXl3b3JkID0gdGhpcy5tYXRjaFJhd1N5bnRheCgpO1xuICAgIGxldCBsb29rYWhlYWQgPSB0aGlzLnBlZWsoKTtcblxuICAgIGlmICh0aGlzLmlzUHVuY3R1YXRvcihsb29rYWhlYWQsICcqJykpIHtcbiAgICAgIGlzR2VuZXJhdG9yID0gdHJ1ZTtcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgbG9va2FoZWFkID0gdGhpcy5wZWVrKCk7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmlzUGFyZW5zKGxvb2thaGVhZCkpIHtcbiAgICAgIG5hbWUgPSB0aGlzLmVuZm9yZXN0QmluZGluZ0lkZW50aWZpZXIoKTtcbiAgICB9IGVsc2UgaWYgKGluRGVmYXVsdCkge1xuICAgICAgbmFtZSA9IG5ldyBULkJpbmRpbmdJZGVudGlmaWVyKHtcbiAgICAgICAgbmFtZTogU3ludGF4LmZyb21JZGVudGlmaWVyKCcqZGVmYXVsdConLCBmbktleXdvcmQpLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcGFyYW1zID0gdGhpcy5tYXRjaFBhcmVucygpO1xuXG4gICAgYm9keSA9IHRoaXMubWF0Y2hDdXJsaWVzKCk7XG5cbiAgICBsZXQgZW5mID0gbmV3IEVuZm9yZXN0ZXIocGFyYW1zLCBMaXN0KCksIHRoaXMuY29udGV4dCk7XG4gICAgbGV0IGZvcm1hbFBhcmFtcyA9IGVuZi5lbmZvcmVzdEZvcm1hbFBhcmFtZXRlcnMoKTtcblxuICAgIHJldHVybiBuZXcgKGlzRXhwciA/IFQuRnVuY3Rpb25FeHByZXNzaW9uRSA6IFQuRnVuY3Rpb25EZWNsYXJhdGlvbkUpKHtcbiAgICAgIG5hbWU6IG5hbWUsXG4gICAgICBpc0dlbmVyYXRvcjogaXNHZW5lcmF0b3IsXG4gICAgICBwYXJhbXM6IGZvcm1hbFBhcmFtcyxcbiAgICAgIGJvZHk6IGJvZHksXG4gICAgfSk7XG4gIH1cblxuICBlbmZvcmVzdEZvcm1hbFBhcmFtZXRlcnMoKSB7XG4gICAgbGV0IGl0ZW1zID0gW107XG4gICAgbGV0IHJlc3QgPSBudWxsO1xuICAgIHdoaWxlICh0aGlzLnJlc3Quc2l6ZSAhPT0gMCkge1xuICAgICAgbGV0IGxvb2thaGVhZCA9IHRoaXMucGVlaygpO1xuICAgICAgaWYgKHRoaXMuaXNQdW5jdHVhdG9yKGxvb2thaGVhZCwgJy4uLicpKSB7XG4gICAgICAgIHRoaXMubWF0Y2hQdW5jdHVhdG9yKCcuLi4nKTtcbiAgICAgICAgcmVzdCA9IHRoaXMuZW5mb3Jlc3RCaW5kaW5nSWRlbnRpZmllcigpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGl0ZW1zLnB1c2godGhpcy5lbmZvcmVzdFBhcmFtKCkpO1xuICAgICAgdGhpcy5jb25zdW1lQ29tbWEoKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBULkZvcm1hbFBhcmFtZXRlcnMoe1xuICAgICAgaXRlbXM6IExpc3QoaXRlbXMpLFxuICAgICAgcmVzdCxcbiAgICB9KTtcbiAgfVxuXG4gIGVuZm9yZXN0UGFyYW0oKSB7XG4gICAgcmV0dXJuIHRoaXMuZW5mb3Jlc3RCaW5kaW5nRWxlbWVudCgpO1xuICB9XG5cbiAgZW5mb3Jlc3RVcGRhdGVFeHByZXNzaW9uKCkge1xuICAgIGNvbnN0IGxvb2thaGVhZCA9IHRoaXMucGVlaygpO1xuICAgIGNvbnN0IGxlZnRUZXJtID0gdGhpcy50ZXJtO1xuICAgIGlmICghbG9va2FoZWFkKSB7XG4gICAgICB0aHJvdyB0aGlzLmNyZWF0ZUVycm9yKGxvb2thaGVhZCwgJ2Fzc2VydGlvbiBmYWlsdXJlOiBvcGVyYXRvciBpcyBudWxsJyk7XG4gICAgfVxuICAgIGxldCBvcGVyYXRvciA9IHRoaXMubWF0Y2hSYXdTeW50YXgoKTtcbiAgICBpZiAodGhpcy5pc0NvbXBpbGV0aW1lVHJhbnNmb3JtKGxvb2thaGVhZCkpIHtcbiAgICAgIGNvbnN0IG9wZXJhdG9yVHJhbnNmb3JtID0gdGhpcy5nZXRGcm9tQ29tcGlsZXRpbWVFbnZpcm9ubWVudChvcGVyYXRvcik7XG4gICAgICBpZiAoIW9wZXJhdG9yVHJhbnNmb3JtIHx8IG9wZXJhdG9yVHJhbnNmb3JtLnZhbHVlLnR5cGUgIT09ICdvcGVyYXRvcicpIHtcbiAgICAgICAgdGhyb3cgdGhpcy5jcmVhdGVFcnJvcihsb29rYWhlYWQsICd1bmV4cGVjdGVkIHRyYW5zZm9ybScpO1xuICAgICAgfVxuICAgICAgbGV0IHJlc3VsdCA9IG9wZXJhdG9yVHJhbnNmb3JtLnZhbHVlLmYuY2FsbChudWxsLCBsZWZ0VGVybSk7XG4gICAgICBsZXQgZW5mID0gbmV3IEVuZm9yZXN0ZXIocmVzdWx0LCBMaXN0KCksIHRoaXMuY29udGV4dCk7XG4gICAgICByZXR1cm4gZW5mLmVuZm9yZXN0RXhwcmVzc2lvbkxvb3AoKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBULlVwZGF0ZUV4cHJlc3Npb24oe1xuICAgICAgaXNQcmVmaXg6IGZhbHNlLFxuICAgICAgb3BlcmF0b3I6IG9wZXJhdG9yLnZhbCgpLFxuICAgICAgb3BlcmFuZDogdGhpcy50cmFuc2Zvcm1EZXN0cnVjdHVyaW5nKGxlZnRUZXJtKSxcbiAgICB9KTtcbiAgfVxuXG4gIGVuZm9yZXN0VW5hcnlFeHByZXNzaW9uKCkge1xuICAgIGNvbnN0IGxvb2thaGVhZCA9IHRoaXMucGVlaygpO1xuICAgIGlmICghbG9va2FoZWFkKSB7XG4gICAgICB0aHJvdyB0aGlzLmNyZWF0ZUVycm9yKGxvb2thaGVhZCwgJ2Fzc2VydGlvbiBmYWlsdXJlOiBvcGVyYXRvciBpcyBudWxsJyk7XG4gICAgfVxuICAgIGxldCBvcGVyYXRvciA9IHRoaXMubWF0Y2hSYXdTeW50YXgoKTtcbiAgICBsZXQgcHJlYywgY29tYmluZTtcbiAgICBpZiAodGhpcy5pc0NvbXBpbGV0aW1lVHJhbnNmb3JtKGxvb2thaGVhZCkpIHtcbiAgICAgIGNvbnN0IG9wZXJhdG9yVHJhbnNmb3JtID0gdGhpcy5nZXRGcm9tQ29tcGlsZXRpbWVFbnZpcm9ubWVudChsb29rYWhlYWQpO1xuICAgICAgaWYgKCFvcGVyYXRvclRyYW5zZm9ybSB8fCBvcGVyYXRvclRyYW5zZm9ybS52YWx1ZS50eXBlICE9PSAnb3BlcmF0b3InKSB7XG4gICAgICAgIHRocm93IHRoaXMuY3JlYXRlRXJyb3IobG9va2FoZWFkLCAndW5leHBlY3RlZCB0cmFuc2Zvcm0nKTtcbiAgICAgIH1cbiAgICAgIHByZWMgPSBvcGVyYXRvclRyYW5zZm9ybS52YWx1ZS5wcmVjO1xuICAgICAgY29tYmluZSA9IHJpZ2h0VGVybSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmV4cGFuZE9wZXJhdG9yKGxvb2thaGVhZCwgb3BlcmF0b3JUcmFuc2Zvcm0sIFtyaWdodFRlcm1dKTtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGFsbCBidWlsdGlucyBhcmUgMTZcbiAgICAgIHByZWMgPSAxNjtcbiAgICAgIGNvbWJpbmUgPSByaWdodFRlcm0gPT4ge1xuICAgICAgICBpZiAob3BlcmF0b3IudmFsKCkgPT09ICcrKycgfHwgb3BlcmF0b3IudmFsKCkgPT09ICctLScpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFQuVXBkYXRlRXhwcmVzc2lvbih7XG4gICAgICAgICAgICBvcGVyYXRvcjogb3BlcmF0b3IudmFsKCksXG4gICAgICAgICAgICBvcGVyYW5kOiB0aGlzLnRyYW5zZm9ybURlc3RydWN0dXJpbmcocmlnaHRUZXJtKSxcbiAgICAgICAgICAgIGlzUHJlZml4OiB0cnVlLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBuZXcgVC5VbmFyeUV4cHJlc3Npb24oe1xuICAgICAgICAgICAgb3BlcmF0b3I6IG9wZXJhdG9yLnZhbCgpLFxuICAgICAgICAgICAgb3BlcmFuZDogcmlnaHRUZXJtLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cblxuICAgIHRoaXMub3BDdHguc3RhY2sgPSB0aGlzLm9wQ3R4LnN0YWNrLnB1c2goe1xuICAgICAgcHJlYzogdGhpcy5vcEN0eC5wcmVjLFxuICAgICAgY29tYmluZTogdGhpcy5vcEN0eC5jb21iaW5lLFxuICAgIH0pO1xuICAgIHRoaXMub3BDdHgucHJlYyA9IHByZWM7XG4gICAgdGhpcy5vcEN0eC5jb21iaW5lID0gcmlnaHRUZXJtID0+IHtcbiAgICAgIHJldHVybiBjb21iaW5lKHJpZ2h0VGVybSk7XG4gICAgfTtcbiAgICByZXR1cm4gRVhQUl9MT09QX09QRVJBVE9SO1xuICB9XG5cbiAgZW5mb3Jlc3RDb25kaXRpb25hbEV4cHJlc3Npb24oKSB7XG4gICAgLy8gZmlyc3QsIHBvcCB0aGUgb3BlcmF0b3Igc3RhY2tcbiAgICBsZXQgdGVzdCA9IHRoaXMub3BDdHguY29tYmluZSh0aGlzLnRlcm0pO1xuICAgIGlmICh0aGlzLm9wQ3R4LnN0YWNrLnNpemUgPiAwKSB7XG4gICAgICBsZXQgeyBwcmVjLCBjb21iaW5lIH0gPSB0aGlzLm9wQ3R4LnN0YWNrLmxhc3QoKTtcbiAgICAgIHRoaXMub3BDdHguc3RhY2sgPSB0aGlzLm9wQ3R4LnN0YWNrLnBvcCgpO1xuICAgICAgdGhpcy5vcEN0eC5wcmVjID0gcHJlYztcbiAgICAgIHRoaXMub3BDdHguY29tYmluZSA9IGNvbWJpbmU7XG4gICAgfVxuXG4gICAgdGhpcy5tYXRjaFB1bmN0dWF0b3IoJz8nKTtcbiAgICBsZXQgZW5mID0gbmV3IEVuZm9yZXN0ZXIodGhpcy5yZXN0LCBMaXN0KCksIHRoaXMuY29udGV4dCk7XG4gICAgbGV0IGNvbnNlcXVlbnQgPSBlbmYuZW5mb3Jlc3RFeHByZXNzaW9uTG9vcCgpO1xuICAgIGVuZi5tYXRjaFB1bmN0dWF0b3IoJzonKTtcbiAgICBlbmYgPSBuZXcgRW5mb3Jlc3RlcihlbmYucmVzdCwgTGlzdCgpLCB0aGlzLmNvbnRleHQpO1xuICAgIGxldCBhbHRlcm5hdGUgPSBlbmYuZW5mb3Jlc3RFeHByZXNzaW9uTG9vcCgpO1xuICAgIHRoaXMucmVzdCA9IGVuZi5yZXN0O1xuICAgIHJldHVybiBuZXcgVC5Db25kaXRpb25hbEV4cHJlc3Npb24oe1xuICAgICAgdGVzdCxcbiAgICAgIGNvbnNlcXVlbnQsXG4gICAgICBhbHRlcm5hdGUsXG4gICAgfSk7XG4gIH1cblxuICBlbmZvcmVzdEJpbmFyeUV4cHJlc3Npb24oKSB7XG4gICAgbGV0IGxlZnRUZXJtID0gdGhpcy50ZXJtO1xuICAgIGNvbnN0IG9wU3R4ID0gdGhpcy5wZWVrKCk7XG4gICAgaWYgKCFvcFN0eCkge1xuICAgICAgdGhyb3cgdGhpcy5jcmVhdGVFcnJvcihvcFN0eCwgJ2Fzc2VydGlvbiBmYWlsdXJlOiBvcFN0eCBpcyBudWxsJyk7XG4gICAgfVxuXG4gICAgbGV0IHByZWMsIGFzc29jLCBjb21iaW5lO1xuICAgIGlmICh0aGlzLmlzQ29tcGlsZXRpbWVUcmFuc2Zvcm0odGhpcy5wZWVrKCkpKSB7XG4gICAgICBjb25zdCBvcGVyYXRvclRyYW5zZm9ybSA9IHRoaXMuZ2V0RnJvbUNvbXBpbGV0aW1lRW52aXJvbm1lbnQob3BTdHgudmFsdWUpO1xuICAgICAgaWYgKCFvcGVyYXRvclRyYW5zZm9ybSB8fCBvcGVyYXRvclRyYW5zZm9ybS52YWx1ZS50eXBlICE9PSAnb3BlcmF0b3InKSB7XG4gICAgICAgIHRocm93IHRoaXMuY3JlYXRlRXJyb3Iob3BTdHgudmFsdWUsICd1bmV4cGVjdGVkIHRyYW5zZm9ybScpO1xuICAgICAgfVxuICAgICAgcHJlYyA9IG9wZXJhdG9yVHJhbnNmb3JtLnZhbHVlLnByZWM7XG4gICAgICBhc3NvYyA9IG9wZXJhdG9yVHJhbnNmb3JtLnZhbHVlLmFzc29jO1xuICAgICAgY29tYmluZSA9IChsZWZ0LCByaWdodCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5leHBhbmRPcGVyYXRvcihvcFN0eCwgb3BlcmF0b3JUcmFuc2Zvcm0sIFtsZWZ0LCByaWdodF0pO1xuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJlYyA9IGdldE9wZXJhdG9yUHJlYyhvcFN0eC52YWx1ZS52YWwoKSk7XG4gICAgICBhc3NvYyA9IGdldE9wZXJhdG9yQXNzb2Mob3BTdHgudmFsdWUudmFsKCkpO1xuICAgICAgY29tYmluZSA9IChsZWZ0LCByaWdodCkgPT5cbiAgICAgICAgbmV3IFQuQmluYXJ5RXhwcmVzc2lvbih7XG4gICAgICAgICAgbGVmdCxcbiAgICAgICAgICByaWdodCxcbiAgICAgICAgICBvcGVyYXRvcjogb3BTdHgudmFsdWUudmFsKCksXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChvcGVyYXRvckx0KHRoaXMub3BDdHgucHJlYywgcHJlYywgYXNzb2MpKSB7XG4gICAgICB0aGlzLm9wQ3R4LnN0YWNrID0gdGhpcy5vcEN0eC5zdGFjay5wdXNoKHtcbiAgICAgICAgcHJlYzogdGhpcy5vcEN0eC5wcmVjLFxuICAgICAgICBjb21iaW5lOiB0aGlzLm9wQ3R4LmNvbWJpbmUsXG4gICAgICB9KTtcbiAgICAgIHRoaXMub3BDdHgucHJlYyA9IHByZWM7XG4gICAgICB0aGlzLm9wQ3R4LmNvbWJpbmUgPSByaWdodFRlcm0gPT4ge1xuICAgICAgICByZXR1cm4gY29tYmluZShsZWZ0VGVybSwgcmlnaHRUZXJtKTtcbiAgICAgIH07XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIHJldHVybiBFWFBSX0xPT1BfT1BFUkFUT1I7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCB0ZXJtID0gdGhpcy5vcEN0eC5jb21iaW5lKGxlZnRUZXJtKTtcbiAgICAgIC8vIHRoaXMucmVzdCBkb2VzIG5vdCBjaGFuZ2VcbiAgICAgIGxldCB7IHByZWMsIGNvbWJpbmUgfSA9IHRoaXMub3BDdHguc3RhY2subGFzdCgpO1xuICAgICAgdGhpcy5vcEN0eC5zdGFjayA9IHRoaXMub3BDdHguc3RhY2sucG9wKCk7XG4gICAgICB0aGlzLm9wQ3R4LnByZWMgPSBwcmVjO1xuICAgICAgdGhpcy5vcEN0eC5jb21iaW5lID0gY29tYmluZTtcbiAgICAgIHJldHVybiB0ZXJtO1xuICAgIH1cbiAgfVxuXG4gIGVuZm9yZXN0VGVtcGxhdGVFbGVtZW50cygpIHtcbiAgICBsZXQgbG9va2FoZWFkID0gdGhpcy5tYXRjaFRlbXBsYXRlKCk7XG4gICAgbGV0IGVsZW1lbnRzID0gbG9va2FoZWFkLnRva2VuLml0ZW1zLm1hcChpdCA9PiB7XG4gICAgICBpZiAodGhpcy5pc0RlbGltaXRlcihpdCkpIHtcbiAgICAgICAgbGV0IGVuZiA9IG5ldyBFbmZvcmVzdGVyKFxuICAgICAgICAgIGl0LmlubmVyLnNsaWNlKDEsIGl0LmlubmVyLnNpemUgLSAxKSxcbiAgICAgICAgICBMaXN0KCksXG4gICAgICAgICAgdGhpcy5jb250ZXh0LFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gZW5mLmVuZm9yZXN0KCdleHByZXNzaW9uJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV3IFQuVGVtcGxhdGVFbGVtZW50KHtcbiAgICAgICAgcmF3VmFsdWU6IGl0LnZhbHVlLnRva2VuLnNsaWNlLnRleHQsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgICByZXR1cm4gZWxlbWVudHM7XG4gIH1cblxuICBleHBhbmRNYWNybygpIHtcbiAgICBsZXQgbG9va2FoZWFkID0gdGhpcy5wZWVrKCk7XG4gICAgd2hpbGUgKHRoaXMuaXNDb21waWxldGltZVRyYW5zZm9ybShsb29rYWhlYWQpKSB7XG4gICAgICBsZXQgbmFtZSA9IHRoaXMubWF0Y2hSYXdTeW50YXgoKTtcblxuICAgICAgbGV0IHN5bnRheFRyYW5zZm9ybSA9IHRoaXMuZ2V0RnJvbUNvbXBpbGV0aW1lRW52aXJvbm1lbnQobmFtZSk7XG4gICAgICBpZiAoc3ludGF4VHJhbnNmb3JtID09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgdGhpcy5jcmVhdGVFcnJvcihcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgIGBUaGUgbWFjcm8gJHtuYW1lLnJlc29sdmUodGhpcy5jb250ZXh0LnBoYXNlKX0gZG9lcyBub3QgaGF2ZSBhIGJvdW5kIHZhbHVlYCxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHN5bnRheFRyYW5zZm9ybS52YWx1ZS5mICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IHRoaXMuY3JlYXRlRXJyb3IoXG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgICBgVGhlIG1hY3JvICR7bmFtZS5yZXNvbHZlKHRoaXMuY29udGV4dC5waGFzZSl9IHdhcyBub3QgYm91bmQgdG8gYSBjYWxsYWJsZSB2YWx1ZTogJHtzeW50YXhUcmFuc2Zvcm0udmFsdWUuZn1gLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgbGV0IHVzZVNpdGVTY29wZSA9IGZyZXNoU2NvcGUoJ3UnKTtcbiAgICAgIGxldCBpbnRyb2R1Y2VkU2NvcGUgPSBmcmVzaFNjb3BlKCdpJyk7XG4gICAgICAvLyBUT0RPOiBuZWVkcyB0byBiZSBhIGxpc3Qgb2Ygc2NvcGVzIEkgdGhpbmtcbiAgICAgIHRoaXMuY29udGV4dC51c2VTY29wZSA9IHVzZVNpdGVTY29wZTtcblxuICAgICAgbGV0IGN0eCA9IG5ldyBNYWNyb0NvbnRleHQoXG4gICAgICAgIHRoaXMsXG4gICAgICAgIG5hbWUsXG4gICAgICAgIHRoaXMuY29udGV4dCxcbiAgICAgICAgdXNlU2l0ZVNjb3BlLFxuICAgICAgICBpbnRyb2R1Y2VkU2NvcGUsXG4gICAgICApO1xuXG4gICAgICBsZXQgcmVzdWx0ID0gc2FuaXRpemVSZXBsYWNlbWVudFZhbHVlcyhcbiAgICAgICAgc3ludGF4VHJhbnNmb3JtLnZhbHVlLmYuY2FsbChudWxsLCBjdHgpLFxuICAgICAgKTtcbiAgICAgIGlmICghTGlzdC5pc0xpc3QocmVzdWx0KSkge1xuICAgICAgICB0aHJvdyB0aGlzLmNyZWF0ZUVycm9yKFxuICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgJ21hY3JvIG11c3QgcmV0dXJuIGEgbGlzdCBidXQgZ290OiAnICsgcmVzdWx0LFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgbGV0IHNjb3BlUmVkdWNlciA9IG5ldyBTY29wZVJlZHVjZXIoXG4gICAgICAgIFt7IHNjb3BlOiBpbnRyb2R1Y2VkU2NvcGUsIHBoYXNlOiBBTExfUEhBU0VTLCBmbGlwOiB0cnVlIH1dLFxuICAgICAgICB0aGlzLmNvbnRleHQuYmluZGluZ3MsXG4gICAgICAgIHRydWUsXG4gICAgICApO1xuICAgICAgcmVzdWx0ID0gcmVzdWx0Lm1hcCh0ZXJtcyA9PiB7XG4gICAgICAgIGlmICh0ZXJtcyBpbnN0YW5jZW9mIFN5bnRheCkge1xuICAgICAgICAgIHJldHVybiBuZXcgVC5SYXdTeW50YXgoe1xuICAgICAgICAgICAgdmFsdWU6IHRlcm1zLFxuICAgICAgICAgIH0pLnJlZHVjZShzY29wZVJlZHVjZXIpO1xuICAgICAgICB9IGVsc2UgaWYgKCEodGVybXMgaW5zdGFuY2VvZiBUZXJtKSkge1xuICAgICAgICAgIHRocm93IHRoaXMuY3JlYXRlRXJyb3IoXG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgJ21hY3JvIG11c3QgcmV0dXJuIHN5bnRheCBvYmplY3RzIG9yIHRlcm1zIGJ1dCBnb3Q6ICcgKyB0ZXJtcyxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0ZXJtcy5yZWR1Y2Uoc2NvcGVSZWR1Y2VyKTtcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLnJlc3QgPSByZXN1bHQuY29uY2F0KGN0eC5fcmVzdCh0aGlzKSk7XG4gICAgICBsb29rYWhlYWQgPSB0aGlzLnBlZWsoKTtcbiAgICB9XG4gIH1cblxuICBleHBhbmRPcGVyYXRvcihuYW1lOiBUZXJtLCBvcGVyYXRvclRyYW5zZm9ybTogYW55LCBhcmdzOiBBcnJheTxUZXJtPikge1xuICAgIGxldCB1c2VTaXRlU2NvcGUgPSBmcmVzaFNjb3BlKCd1Jyk7XG4gICAgbGV0IGludHJvZHVjZWRTY29wZSA9IGZyZXNoU2NvcGUoJ2knKTtcbiAgICAvLyBUT0RPOiBuZWVkcyB0byBiZSBhIGxpc3Qgb2Ygc2NvcGVzIEkgdGhpbmtcbiAgICB0aGlzLmNvbnRleHQudXNlU2NvcGUgPSB1c2VTaXRlU2NvcGU7XG4gICAgYXJncyA9IGFyZ3MubWFwKGFyZyA9PiB7XG4gICAgICByZXR1cm4gYXJnLnJlZHVjZShcbiAgICAgICAgbmV3IFNjb3BlUmVkdWNlcihcbiAgICAgICAgICBbXG4gICAgICAgICAgICB7IHNjb3BlOiB1c2VTaXRlU2NvcGUsIHBoYXNlOiBBTExfUEhBU0VTLCBmbGlwOiBmYWxzZSB9LFxuICAgICAgICAgICAgeyBzY29wZTogaW50cm9kdWNlZFNjb3BlLCBwaGFzZTogQUxMX1BIQVNFUywgZmxpcDogdHJ1ZSB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgdGhpcy5jb250ZXh0LmJpbmRpbmdzLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9KTtcbiAgICBsZXQgcmVzdWx0ID0gc2FuaXRpemVSZXBsYWNlbWVudFZhbHVlcyhcbiAgICAgIG9wZXJhdG9yVHJhbnNmb3JtLnZhbHVlLmYuYXBwbHkobnVsbCwgYXJncyksXG4gICAgKTtcbiAgICBsZXQgc2NvcGVSZWR1Y2VyID0gbmV3IFNjb3BlUmVkdWNlcihcbiAgICAgIFt7IHNjb3BlOiBpbnRyb2R1Y2VkU2NvcGUsIHBoYXNlOiBBTExfUEhBU0VTLCBmbGlwOiB0cnVlIH1dLFxuICAgICAgdGhpcy5jb250ZXh0LmJpbmRpbmdzLFxuICAgICAgdHJ1ZSxcbiAgICApO1xuICAgIHJlc3VsdCA9IHJlc3VsdC5tYXAodGVybXMgPT4ge1xuICAgICAgaWYgKHRlcm1zIGluc3RhbmNlb2YgU3ludGF4KSB7XG4gICAgICAgIHJldHVybiBuZXcgVC5SYXdTeW50YXgoe1xuICAgICAgICAgIHZhbHVlOiB0ZXJtcyxcbiAgICAgICAgfSkucmVkdWNlKHNjb3BlUmVkdWNlcik7XG4gICAgICB9IGVsc2UgaWYgKCEodGVybXMgaW5zdGFuY2VvZiBUZXJtKSkge1xuICAgICAgICB0aHJvdyB0aGlzLmNyZWF0ZUVycm9yKFxuICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgJ21hY3JvIG11c3QgcmV0dXJuIHN5bnRheCBvYmplY3RzIG9yIHRlcm1zIGJ1dCBnb3Q6ICcgKyB0ZXJtcyxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0ZXJtcy5yZWR1Y2Uoc2NvcGVSZWR1Y2VyKTtcbiAgICB9KTtcbiAgICBsZXQgZW5mID0gbmV3IEVuZm9yZXN0ZXIocmVzdWx0LCBMaXN0KCksIHRoaXMuY29udGV4dCk7XG4gICAgcmV0dXJuIGVuZi5lbmZvcmVzdEV4cHJlc3Npb25Mb29wKCk7XG4gIH1cblxuICBjb25zdW1lU2VtaWNvbG9uKCkge1xuICAgIGxldCBsb29rYWhlYWQgPSB0aGlzLnBlZWsoKTtcblxuICAgIGlmIChsb29rYWhlYWQgJiYgdGhpcy5pc1B1bmN0dWF0b3IobG9va2FoZWFkLCAnOycpKSB7XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICB9XG4gIH1cblxuICBjb25zdW1lQ29tbWEoKSB7XG4gICAgbGV0IGxvb2thaGVhZCA9IHRoaXMucGVlaygpO1xuXG4gICAgaWYgKGxvb2thaGVhZCAmJiB0aGlzLmlzUHVuY3R1YXRvcihsb29rYWhlYWQsICcsJykpIHtcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgIH1cbiAgfVxuXG4gIHNhZmVDaGVjayhvYmo6IFN5bnRheCB8IFRlcm0sIHR5cGU6IGFueSwgdmFsOiA/c3RyaW5nID0gbnVsbCkge1xuICAgIGlmIChvYmogaW5zdGFuY2VvZiBUZXJtKSB7XG4gICAgICBpZiAob2JqIGluc3RhbmNlb2YgVC5SYXdTeW50YXgpIHtcbiAgICAgICAgcmV0dXJuIG9iai52YWx1ZSAmJlxuICAgICAgICAgICh0eXBlb2Ygb2JqLnZhbHVlLm1hdGNoID09PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICA/IG9iai52YWx1ZS5tYXRjaCh0eXBlLCB2YWwpXG4gICAgICAgICAgICA6IGZhbHNlKTtcbiAgICAgIH0gZWxzZSBpZiAob2JqIGluc3RhbmNlb2YgVC5SYXdEZWxpbWl0ZXIpIHtcbiAgICAgICAgcmV0dXJuIHR5cGUgPT09ICdkZWxpbWl0ZXInIHx8IG9iai5raW5kID09PSB0eXBlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gb2JqICYmXG4gICAgICAodHlwZW9mIG9iai5tYXRjaCA9PT0gJ2Z1bmN0aW9uJyA/IG9iai5tYXRjaCh0eXBlLCB2YWwpIDogZmFsc2UpO1xuICB9XG5cbiAgaXNUZXJtKHRlcm06IGFueSkge1xuICAgIHJldHVybiB0ZXJtICYmIHRlcm0gaW5zdGFuY2VvZiBUZXJtO1xuICB9XG5cbiAgaXNFT0Yob2JqOiBTeW50YXggfCBUZXJtKSB7XG4gICAgcmV0dXJuIHRoaXMuc2FmZUNoZWNrKG9iaiwgJ2VvZicpO1xuICB9XG5cbiAgaXNJZGVudGlmaWVyKG9iajogU3ludGF4IHwgVGVybSwgdmFsOiA/c3RyaW5nID0gbnVsbCkge1xuICAgIHJldHVybiB0aGlzLnNhZmVDaGVjayhvYmosICdpZGVudGlmaWVyJywgdmFsKTtcbiAgfVxuXG4gIGlzUHJvcGVydHlOYW1lKG9iajogU3ludGF4IHwgVGVybSkge1xuICAgIHJldHVybiB0aGlzLmlzSWRlbnRpZmllcihvYmopIHx8XG4gICAgICB0aGlzLmlzS2V5d29yZChvYmopIHx8XG4gICAgICB0aGlzLmlzTnVtZXJpY0xpdGVyYWwob2JqKSB8fFxuICAgICAgdGhpcy5pc1N0cmluZ0xpdGVyYWwob2JqKSB8fFxuICAgICAgdGhpcy5pc0JyYWNrZXRzKG9iaik7XG4gIH1cblxuICBpc051bWVyaWNMaXRlcmFsKG9iajogU3ludGF4IHwgVGVybSwgdmFsOiA/c3RyaW5nID0gbnVsbCkge1xuICAgIHJldHVybiB0aGlzLnNhZmVDaGVjayhvYmosICdudW1iZXInLCB2YWwpO1xuICB9XG5cbiAgaXNTdHJpbmdMaXRlcmFsKG9iajogU3ludGF4IHwgVGVybSwgdmFsOiA/c3RyaW5nID0gbnVsbCkge1xuICAgIHJldHVybiB0aGlzLnNhZmVDaGVjayhvYmosICdzdHJpbmcnLCB2YWwpO1xuICB9XG5cbiAgaXNUZW1wbGF0ZShvYmo6IFN5bnRheCB8IFRlcm0sIHZhbDogP3N0cmluZyA9IG51bGwpIHtcbiAgICByZXR1cm4gdGhpcy5zYWZlQ2hlY2sob2JqLCAndGVtcGxhdGUnLCB2YWwpO1xuICB9XG5cbiAgaXNTeW50YXhUZW1wbGF0ZShvYmo6IFN5bnRheCB8IFRlcm0pIHtcbiAgICByZXR1cm4gdGhpcy5zYWZlQ2hlY2sob2JqLCAnc3ludGF4VGVtcGxhdGUnKTtcbiAgfVxuXG4gIGlzQm9vbGVhbkxpdGVyYWwob2JqOiBTeW50YXggfCBUZXJtLCB2YWw6ID9zdHJpbmcgPSBudWxsKSB7XG4gICAgcmV0dXJuIHRoaXMuc2FmZUNoZWNrKG9iaiwgJ2Jvb2xlYW4nLCB2YWwpO1xuICB9XG5cbiAgaXNOdWxsTGl0ZXJhbChvYmo6IFN5bnRheCB8IFRlcm0sIHZhbDogP3N0cmluZyA9IG51bGwpIHtcbiAgICByZXR1cm4gdGhpcy5zYWZlQ2hlY2sob2JqLCAnbnVsbCcsIHZhbCk7XG4gIH1cblxuICBpc1JlZ3VsYXJFeHByZXNzaW9uKG9iajogU3ludGF4IHwgVGVybSwgdmFsOiA/c3RyaW5nID0gbnVsbCkge1xuICAgIHJldHVybiB0aGlzLnNhZmVDaGVjayhvYmosICdyZWd1bGFyRXhwcmVzc2lvbicsIHZhbCk7XG4gIH1cblxuICBpc0RlbGltaXRlcihvYmo6IFN5bnRheCB8IFRlcm0pIHtcbiAgICByZXR1cm4gdGhpcy5zYWZlQ2hlY2sob2JqLCAnZGVsaW1pdGVyJyk7XG4gIH1cblxuICBpc1BhcmVucyhvYmo6IFN5bnRheCB8IFRlcm0pIHtcbiAgICByZXR1cm4gdGhpcy5zYWZlQ2hlY2sob2JqLCAncGFyZW5zJyk7XG4gIH1cblxuICBpc0JyYWNlcyhvYmo6IFN5bnRheCB8IFRlcm0pIHtcbiAgICByZXR1cm4gdGhpcy5zYWZlQ2hlY2sob2JqLCAnYnJhY2VzJyk7XG4gIH1cblxuICBpc0JyYWNrZXRzKG9iajogU3ludGF4IHwgVGVybSkge1xuICAgIHJldHVybiB0aGlzLnNhZmVDaGVjayhvYmosICdicmFja2V0cycpO1xuICB9XG5cbiAgaXNBc3NpZ24ob2JqOiBTeW50YXggfCBUZXJtLCB2YWw6ID9zdHJpbmcgPSBudWxsKSB7XG4gICAgcmV0dXJuIHRoaXMuc2FmZUNoZWNrKG9iaiwgJ2Fzc2lnbicsIHZhbCk7XG4gIH1cblxuICBpc0tleXdvcmQob2JqOiBTeW50YXggfCBUZXJtLCB2YWw6ID9zdHJpbmcgPSBudWxsKSB7XG4gICAgcmV0dXJuIHRoaXMuc2FmZUNoZWNrKG9iaiwgJ2tleXdvcmQnLCB2YWwpO1xuICB9XG5cbiAgaXNQdW5jdHVhdG9yKG9iajogU3ludGF4IHwgVGVybSwgdmFsOiA/c3RyaW5nID0gbnVsbCkge1xuICAgIHJldHVybiB0aGlzLnNhZmVDaGVjayhvYmosICdwdW5jdHVhdG9yJywgdmFsKTtcbiAgfVxuXG4gIGlzT3BlcmF0b3Iob2JqOiBTeW50YXggfCBUZXJtKSB7XG4gICAgcmV0dXJuICh0aGlzLnNhZmVDaGVjayhvYmosICdwdW5jdHVhdG9yJykgfHxcbiAgICAgIHRoaXMuc2FmZUNoZWNrKG9iaiwgJ2lkZW50aWZpZXInKSB8fFxuICAgICAgdGhpcy5zYWZlQ2hlY2sob2JqLCAna2V5d29yZCcpKSAmJlxuICAgICAgKChvYmogaW5zdGFuY2VvZiBULlJhd1N5bnRheCAmJiBpc09wZXJhdG9yKG9iai52YWx1ZSkpIHx8XG4gICAgICAgIChvYmogaW5zdGFuY2VvZiBTeW50YXggJiYgaXNPcGVyYXRvcihvYmopKSk7XG4gIH1cblxuICBpc0N1c3RvbVByZWZpeE9wZXJhdG9yKG9iajogVGVybSkge1xuICAgIGlmICh0aGlzLmlzQ29tcGlsZXRpbWVUcmFuc2Zvcm0ob2JqKSkge1xuICAgICAgbGV0IHQgPSB0aGlzLmdldEZyb21Db21waWxldGltZUVudmlyb25tZW50KG9iai52YWx1ZSk7XG4gICAgICByZXR1cm4gdCAmJiB0LnZhbHVlLmFzc29jID09PSAncHJlZml4JztcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaXNDdXN0b21Qb3N0Zml4T3BlcmF0b3Iob2JqOiBUZXJtKSB7XG4gICAgaWYgKHRoaXMuaXNDb21waWxldGltZVRyYW5zZm9ybShvYmopKSB7XG4gICAgICBsZXQgdCA9IHRoaXMuZ2V0RnJvbUNvbXBpbGV0aW1lRW52aXJvbm1lbnQob2JqLnZhbHVlKTtcbiAgICAgIHJldHVybiB0ICYmIHQudmFsdWUuYXNzb2MgPT09ICdwb3N0Zml4JztcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaXNDdXN0b21CaW5hcnlPcGVyYXRvcihvYmo6IFRlcm0pIHtcbiAgICBpZiAodGhpcy5pc0NvbXBpbGV0aW1lVHJhbnNmb3JtKG9iaikpIHtcbiAgICAgIGxldCB0ID0gdGhpcy5nZXRGcm9tQ29tcGlsZXRpbWVFbnZpcm9ubWVudChvYmoudmFsdWUpO1xuICAgICAgcmV0dXJuIHQgJiYgKHQudmFsdWUuYXNzb2MgPT09ICdsZWZ0JyB8fCB0LnZhbHVlLmFzc29jID09PSAncmlnaHQnKTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaXNVcGRhdGVPcGVyYXRvcihvYmo6IFN5bnRheCB8IFRlcm0pIHtcbiAgICByZXR1cm4gdGhpcy5zYWZlQ2hlY2sob2JqLCAncHVuY3R1YXRvcicsICcrKycpIHx8XG4gICAgICB0aGlzLnNhZmVDaGVjayhvYmosICdwdW5jdHVhdG9yJywgJy0tJyk7XG4gIH1cblxuICBzYWZlUmVzb2x2ZShvYmo6IFN5bnRheCB8IFRlcm0sIHBoYXNlOiBudW1iZXIgfCB7fSkge1xuICAgIGlmIChvYmogaW5zdGFuY2VvZiBULlJhd1N5bnRheCkge1xuICAgICAgcmV0dXJuIHR5cGVvZiBvYmoudmFsdWUucmVzb2x2ZSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICA/IEp1c3Qob2JqLnZhbHVlLnJlc29sdmUocGhhc2UpKVxuICAgICAgICA6IE5vdGhpbmcoKTtcbiAgICB9IGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIFN5bnRheCkge1xuICAgICAgcmV0dXJuIHR5cGVvZiBvYmoucmVzb2x2ZSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICA/IEp1c3Qob2JqLnJlc29sdmUocGhhc2UpKVxuICAgICAgICA6IE5vdGhpbmcoKTtcbiAgICB9XG4gICAgcmV0dXJuIE5vdGhpbmcoKTtcbiAgfVxuXG4gIGlzVHJhbnNmb3JtKG9iajogU3ludGF4IHwgVGVybSwgdHJhbnM6IGFueSkge1xuICAgIHJldHVybiB0aGlzLnNhZmVSZXNvbHZlKG9iaiwgdGhpcy5jb250ZXh0LnBoYXNlKVxuICAgICAgLm1hcChcbiAgICAgICAgbmFtZSA9PlxuICAgICAgICAgIHRoaXMuY29udGV4dC5lbnYuZ2V0KG5hbWUpID09PSB0cmFucyB8fFxuICAgICAgICAgIHRoaXMuY29udGV4dC5zdG9yZS5nZXQobmFtZSkgPT09IHRyYW5zLFxuICAgICAgKVxuICAgICAgLmdldE9yRWxzZShmYWxzZSk7XG4gIH1cblxuICBpc1RyYW5zZm9ybUluc3RhbmNlKG9iajogU3ludGF4IHwgVGVybSwgdHJhbnM6IGFueSkge1xuICAgIHJldHVybiB0aGlzLnNhZmVSZXNvbHZlKG9iaiwgdGhpcy5jb250ZXh0LnBoYXNlKVxuICAgICAgLm1hcChcbiAgICAgICAgbmFtZSA9PlxuICAgICAgICAgIHRoaXMuY29udGV4dC5lbnYuZ2V0KG5hbWUpIGluc3RhbmNlb2YgdHJhbnMgfHxcbiAgICAgICAgICB0aGlzLmNvbnRleHQuc3RvcmUuZ2V0KG5hbWUpIGluc3RhbmNlb2YgdHJhbnMsXG4gICAgICApXG4gICAgICAuZ2V0T3JFbHNlKGZhbHNlKTtcbiAgfVxuXG4gIGlzRm5EZWNsVHJhbnNmb3JtKG9iajogU3ludGF4IHwgVGVybSkge1xuICAgIHJldHVybiB0aGlzLmlzVHJhbnNmb3JtKG9iaiwgRnVuY3Rpb25EZWNsVHJhbnNmb3JtKTtcbiAgfVxuXG4gIGlzVmFyRGVjbFRyYW5zZm9ybShvYmo6IFN5bnRheCB8IFRlcm0pIHtcbiAgICByZXR1cm4gdGhpcy5pc1RyYW5zZm9ybShvYmosIFZhcmlhYmxlRGVjbFRyYW5zZm9ybSk7XG4gIH1cblxuICBpc0xldERlY2xUcmFuc2Zvcm0ob2JqOiBTeW50YXggfCBUZXJtKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNUcmFuc2Zvcm0ob2JqLCBMZXREZWNsVHJhbnNmb3JtKTtcbiAgfVxuXG4gIGlzQ29uc3REZWNsVHJhbnNmb3JtKG9iajogU3ludGF4IHwgVGVybSkge1xuICAgIHJldHVybiB0aGlzLmlzVHJhbnNmb3JtKG9iaiwgQ29uc3REZWNsVHJhbnNmb3JtKTtcbiAgfVxuXG4gIGlzU3ludGF4RGVjbFRyYW5zZm9ybShvYmo6IFN5bnRheCB8IFRlcm0pIHtcbiAgICByZXR1cm4gdGhpcy5pc1RyYW5zZm9ybShvYmosIFN5bnRheERlY2xUcmFuc2Zvcm0pO1xuICB9XG5cbiAgaXNTeW50YXhyZWNEZWNsVHJhbnNmb3JtKG9iajogU3ludGF4IHwgVGVybSkge1xuICAgIHJldHVybiB0aGlzLmlzVHJhbnNmb3JtKG9iaiwgU3ludGF4cmVjRGVjbFRyYW5zZm9ybSk7XG4gIH1cblxuICBpc1JldHVyblN0bXRUcmFuc2Zvcm0ob2JqOiBTeW50YXggfCBUZXJtKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNUcmFuc2Zvcm0ob2JqLCBSZXR1cm5TdGF0ZW1lbnRUcmFuc2Zvcm0pO1xuICB9XG5cbiAgaXNXaGlsZVRyYW5zZm9ybShvYmo6IFN5bnRheCB8IFRlcm0pIHtcbiAgICByZXR1cm4gdGhpcy5pc1RyYW5zZm9ybShvYmosIFdoaWxlVHJhbnNmb3JtKTtcbiAgfVxuXG4gIGlzRm9yVHJhbnNmb3JtKG9iajogU3ludGF4IHwgVGVybSkge1xuICAgIHJldHVybiB0aGlzLmlzVHJhbnNmb3JtKG9iaiwgRm9yVHJhbnNmb3JtKTtcbiAgfVxuXG4gIGlzU3dpdGNoVHJhbnNmb3JtKG9iajogU3ludGF4IHwgVGVybSkge1xuICAgIHJldHVybiB0aGlzLmlzVHJhbnNmb3JtKG9iaiwgU3dpdGNoVHJhbnNmb3JtKTtcbiAgfVxuXG4gIGlzQnJlYWtUcmFuc2Zvcm0ob2JqOiBTeW50YXggfCBUZXJtKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNUcmFuc2Zvcm0ob2JqLCBCcmVha1RyYW5zZm9ybSk7XG4gIH1cblxuICBpc0NvbnRpbnVlVHJhbnNmb3JtKG9iajogU3ludGF4IHwgVGVybSkge1xuICAgIHJldHVybiB0aGlzLmlzVHJhbnNmb3JtKG9iaiwgQ29udGludWVUcmFuc2Zvcm0pO1xuICB9XG5cbiAgaXNEb1RyYW5zZm9ybShvYmo6IFN5bnRheCB8IFRlcm0pIHtcbiAgICByZXR1cm4gdGhpcy5pc1RyYW5zZm9ybShvYmosIERvVHJhbnNmb3JtKTtcbiAgfVxuXG4gIGlzRGVidWdnZXJUcmFuc2Zvcm0ob2JqOiBTeW50YXggfCBUZXJtKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNUcmFuc2Zvcm0ob2JqLCBEZWJ1Z2dlclRyYW5zZm9ybSk7XG4gIH1cblxuICBpc1dpdGhUcmFuc2Zvcm0ob2JqOiBTeW50YXggfCBUZXJtKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNUcmFuc2Zvcm0ob2JqLCBXaXRoVHJhbnNmb3JtKTtcbiAgfVxuXG4gIGlzSW1wb3J0VHJhbnNmb3JtKG9iajogU3ludGF4IHwgVGVybSkge1xuICAgIHJldHVybiB0aGlzLmlzVHJhbnNmb3JtKG9iaiwgSW1wb3J0VHJhbnNmb3JtKTtcbiAgfVxuXG4gIGlzRXhwb3J0VHJhbnNmb3JtKG9iajogU3ludGF4IHwgVGVybSkge1xuICAgIHJldHVybiB0aGlzLmlzVHJhbnNmb3JtKG9iaiwgRXhwb3J0VHJhbnNmb3JtKTtcbiAgfVxuXG4gIGlzVHJ5VHJhbnNmb3JtKG9iajogU3ludGF4IHwgVGVybSkge1xuICAgIHJldHVybiB0aGlzLmlzVHJhbnNmb3JtKG9iaiwgVHJ5VHJhbnNmb3JtKTtcbiAgfVxuXG4gIGlzVGhyb3dUcmFuc2Zvcm0ob2JqOiBTeW50YXggfCBUZXJtKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNUcmFuc2Zvcm0ob2JqLCBUaHJvd1RyYW5zZm9ybSk7XG4gIH1cblxuICBpc09wZXJhdG9yRGVjbFRyYW5zZm9ybShvYmo6IFN5bnRheCB8IFRlcm0pIHtcbiAgICByZXR1cm4gdGhpcy5pc1RyYW5zZm9ybShvYmosIE9wZXJhdG9yRGVjbFRyYW5zZm9ybSk7XG4gIH1cblxuICBpc0lmVHJhbnNmb3JtKG9iajogU3ludGF4IHwgVGVybSkge1xuICAgIHJldHVybiB0aGlzLmlzVHJhbnNmb3JtKG9iaiwgSWZUcmFuc2Zvcm0pO1xuICB9XG5cbiAgaXNOZXdUcmFuc2Zvcm0ob2JqOiBTeW50YXggfCBUZXJtKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNUcmFuc2Zvcm0ob2JqLCBOZXdUcmFuc2Zvcm0pO1xuICB9XG5cbiAgaXNTdXBlclRyYW5zZm9ybShvYmo6IFN5bnRheCB8IFRlcm0pIHtcbiAgICByZXR1cm4gdGhpcy5pc1RyYW5zZm9ybShvYmosIFN1cGVyVHJhbnNmb3JtKTtcbiAgfVxuXG4gIGlzVGhpc1RyYW5zZm9ybShvYmo6IFN5bnRheCB8IFRlcm0pIHtcbiAgICByZXR1cm4gdGhpcy5pc1RyYW5zZm9ybShvYmosIFRoaXNUcmFuc2Zvcm0pO1xuICB9XG5cbiAgaXNDbGFzc1RyYW5zZm9ybShvYmo6IFN5bnRheCB8IFRlcm0pIHtcbiAgICByZXR1cm4gdGhpcy5pc1RyYW5zZm9ybShvYmosIENsYXNzVHJhbnNmb3JtKTtcbiAgfVxuXG4gIGlzWWllbGRUcmFuc2Zvcm0ob2JqOiBTeW50YXggfCBUZXJtKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNUcmFuc2Zvcm0ob2JqLCBZaWVsZFRyYW5zZm9ybSk7XG4gIH1cblxuICBpc0RlZmF1bHRUcmFuc2Zvcm0ob2JqOiBTeW50YXggfCBUZXJtKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNUcmFuc2Zvcm0ob2JqLCBEZWZhdWx0VHJhbnNmb3JtKTtcbiAgfVxuXG4gIGlzQ29tcGlsZXRpbWVUcmFuc2Zvcm0ob2JqOiBTeW50YXggfCBUZXJtKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNUcmFuc2Zvcm1JbnN0YW5jZShvYmosIENvbXBpbGV0aW1lVHJhbnNmb3JtKTtcbiAgfVxuXG4gIGlzTW9kdWxlTmFtZXNwYWNlVHJhbnNmb3JtKG9iajogVGVybSkge1xuICAgIHJldHVybiB0aGlzLmlzVHJhbnNmb3JtSW5zdGFuY2Uob2JqLCBNb2R1bGVOYW1lc3BhY2VUcmFuc2Zvcm0pO1xuICB9XG5cbiAgaXNWYXJCaW5kaW5nVHJhbnNmb3JtKG9iajogU3ludGF4IHwgVGVybSkge1xuICAgIHJldHVybiB0aGlzLmlzVHJhbnNmb3JtSW5zdGFuY2Uob2JqLCBWYXJCaW5kaW5nVHJhbnNmb3JtKTtcbiAgfVxuXG4gIGdldEZyb21Db21waWxldGltZUVudmlyb25tZW50KHRlcm06IFN5bnRheCkge1xuICAgIGlmICh0aGlzLmNvbnRleHQuZW52Lmhhcyh0ZXJtLnJlc29sdmUodGhpcy5jb250ZXh0LnBoYXNlKSkpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnRleHQuZW52LmdldCh0ZXJtLnJlc29sdmUodGhpcy5jb250ZXh0LnBoYXNlKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNvbnRleHQuc3RvcmUuZ2V0KHRlcm0ucmVzb2x2ZSh0aGlzLmNvbnRleHQucGhhc2UpKTtcbiAgfVxuXG4gIGxpbmVOdW1iZXJFcShhOiA/KFQuVGVybSB8IFN5bnRheCksIGI6ID8oU3ludGF4IHwgVC5UZXJtKSkge1xuICAgIGlmICghKGEgJiYgYikpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIGdldExpbmVOdW1iZXIoYSkgPT09IGdldExpbmVOdW1iZXIoYik7XG4gIH1cblxuICBtYXRjaFJhd0RlbGltaXRlcigpOiBMaXN0PFQuU3ludGF4VGVybT4ge1xuICAgIGxldCBsb29rYWhlYWQgPSB0aGlzLmFkdmFuY2UoKTtcbiAgICBpZiAobG9va2FoZWFkIGluc3RhbmNlb2YgVC5SYXdEZWxpbWl0ZXIpIHtcbiAgICAgIHJldHVybiBsb29rYWhlYWQuaW5uZXI7XG4gICAgfVxuICAgIHRocm93IHRoaXMuY3JlYXRlRXJyb3IobG9va2FoZWFkLCAnZXhwZWN0aW5nIGEgUmF3RGVsaW1pdGVyJyk7XG4gIH1cblxuICBtYXRjaFJhd1N5bnRheCgpOiBTeW50YXgge1xuICAgIGxldCBsb29rYWhlYWQgPSB0aGlzLmFkdmFuY2UoKTtcbiAgICBpZiAobG9va2FoZWFkIGluc3RhbmNlb2YgVC5SYXdTeW50YXgpIHtcbiAgICAgIHJldHVybiBsb29rYWhlYWQudmFsdWU7XG4gICAgfVxuICAgIHRocm93IHRoaXMuY3JlYXRlRXJyb3IobG9va2FoZWFkLCAnZXhwZWN0aW5nIGEgUmF3U3ludGF4Jyk7XG4gIH1cblxuICBtYXRjaElkZW50aWZpZXIodmFsPzogc3RyaW5nKSB7XG4gICAgbGV0IGxvb2thaGVhZCA9IHRoaXMucGVlaygpO1xuICAgIGlmICh0aGlzLmlzSWRlbnRpZmllcihsb29rYWhlYWQsIHZhbCkpIHtcbiAgICAgIHJldHVybiB0aGlzLm1hdGNoUmF3U3ludGF4KCk7XG4gICAgfVxuICAgIHRocm93IHRoaXMuY3JlYXRlRXJyb3IobG9va2FoZWFkLCAnZXhwZWN0aW5nIGFuIGlkZW50aWZpZXInKTtcbiAgfVxuXG4gIG1hdGNoS2V5d29yZCh2YWw6IHN0cmluZykge1xuICAgIGxldCBsb29rYWhlYWQgPSB0aGlzLnBlZWsoKTtcbiAgICBpZiAodGhpcy5pc0tleXdvcmQobG9va2FoZWFkLCB2YWwpKSB7XG4gICAgICByZXR1cm4gdGhpcy5tYXRjaFJhd1N5bnRheCgpO1xuICAgIH1cbiAgICB0aHJvdyB0aGlzLmNyZWF0ZUVycm9yKGxvb2thaGVhZCwgJ2V4cGVjdGluZyAnICsgdmFsKTtcbiAgfVxuXG4gIG1hdGNoTGl0ZXJhbCgpIHtcbiAgICBsZXQgbG9va2FoZWFkID0gdGhpcy5wZWVrKCk7XG4gICAgaWYgKFxuICAgICAgdGhpcy5pc051bWVyaWNMaXRlcmFsKGxvb2thaGVhZCkgfHxcbiAgICAgIHRoaXMuaXNTdHJpbmdMaXRlcmFsKGxvb2thaGVhZCkgfHxcbiAgICAgIHRoaXMuaXNCb29sZWFuTGl0ZXJhbChsb29rYWhlYWQpIHx8XG4gICAgICB0aGlzLmlzTnVsbExpdGVyYWwobG9va2FoZWFkKSB8fFxuICAgICAgdGhpcy5pc1RlbXBsYXRlKGxvb2thaGVhZCkgfHxcbiAgICAgIHRoaXMuaXNSZWd1bGFyRXhwcmVzc2lvbihsb29rYWhlYWQpXG4gICAgKSB7XG4gICAgICByZXR1cm4gdGhpcy5tYXRjaFJhd1N5bnRheCgpO1xuICAgIH1cbiAgICB0aHJvdyB0aGlzLmNyZWF0ZUVycm9yKGxvb2thaGVhZCwgJ2V4cGVjdGluZyBhIGxpdGVyYWwnKTtcbiAgfVxuXG4gIG1hdGNoU3RyaW5nTGl0ZXJhbCgpIHtcbiAgICBsZXQgbG9va2FoZWFkID0gdGhpcy5wZWVrKCk7XG4gICAgaWYgKHRoaXMuaXNTdHJpbmdMaXRlcmFsKGxvb2thaGVhZCkpIHtcbiAgICAgIHJldHVybiB0aGlzLm1hdGNoUmF3U3ludGF4KCk7XG4gICAgfVxuICAgIHRocm93IHRoaXMuY3JlYXRlRXJyb3IobG9va2FoZWFkLCAnZXhwZWN0aW5nIGEgc3RyaW5nIGxpdGVyYWwnKTtcbiAgfVxuXG4gIG1hdGNoVGVtcGxhdGUoKSB7XG4gICAgbGV0IGxvb2thaGVhZCA9IHRoaXMucGVlaygpO1xuICAgIGlmICh0aGlzLmlzVGVtcGxhdGUobG9va2FoZWFkKSkge1xuICAgICAgcmV0dXJuIHRoaXMubWF0Y2hSYXdTeW50YXgoKTtcbiAgICB9XG4gICAgdGhyb3cgdGhpcy5jcmVhdGVFcnJvcihsb29rYWhlYWQsICdleHBlY3RpbmcgYSB0ZW1wbGF0ZSBsaXRlcmFsJyk7XG4gIH1cblxuICBtYXRjaFBhcmVucygpOiBMaXN0PFQuU3ludGF4VGVybT4ge1xuICAgIGxldCBsb29rYWhlYWQgPSB0aGlzLnBlZWsoKTtcbiAgICBpZiAodGhpcy5pc1BhcmVucyhsb29rYWhlYWQpKSB7XG4gICAgICBsZXQgaW5uZXIgPSB0aGlzLm1hdGNoUmF3RGVsaW1pdGVyKCk7XG4gICAgICByZXR1cm4gaW5uZXIuc2xpY2UoMSwgaW5uZXIuc2l6ZSAtIDEpO1xuICAgIH1cbiAgICB0aHJvdyB0aGlzLmNyZWF0ZUVycm9yKGxvb2thaGVhZCwgJ2V4cGVjdGluZyBwYXJlbnMnKTtcbiAgfVxuXG4gIG1hdGNoQ3VybGllcygpIHtcbiAgICBsZXQgbG9va2FoZWFkID0gdGhpcy5wZWVrKCk7XG4gICAgaWYgKHRoaXMuaXNCcmFjZXMobG9va2FoZWFkKSkge1xuICAgICAgbGV0IGlubmVyID0gdGhpcy5tYXRjaFJhd0RlbGltaXRlcigpO1xuICAgICAgcmV0dXJuIGlubmVyLnNsaWNlKDEsIGlubmVyLnNpemUgLSAxKTtcbiAgICB9XG4gICAgdGhyb3cgdGhpcy5jcmVhdGVFcnJvcihsb29rYWhlYWQsICdleHBlY3RpbmcgY3VybHkgYnJhY2VzJyk7XG4gIH1cblxuICBtYXRjaFNxdWFyZXMoKTogTGlzdDxULlN5bnRheFRlcm0+IHtcbiAgICBsZXQgbG9va2FoZWFkID0gdGhpcy5wZWVrKCk7XG4gICAgaWYgKHRoaXMuaXNCcmFja2V0cyhsb29rYWhlYWQpKSB7XG4gICAgICBsZXQgaW5uZXIgPSB0aGlzLm1hdGNoUmF3RGVsaW1pdGVyKCk7XG4gICAgICByZXR1cm4gaW5uZXIuc2xpY2UoMSwgaW5uZXIuc2l6ZSAtIDEpO1xuICAgIH1cbiAgICB0aHJvdyB0aGlzLmNyZWF0ZUVycm9yKGxvb2thaGVhZCwgJ2V4cGVjdGluZyBzcXVhcmUgYnJhY2VzJyk7XG4gIH1cblxuICBtYXRjaFVuYXJ5T3BlcmF0b3IoKSB7XG4gICAgbGV0IGxvb2thaGVhZCA9IHRoaXMubWF0Y2hSYXdTeW50YXgoKTtcbiAgICBpZiAoaXNVbmFyeU9wZXJhdG9yKGxvb2thaGVhZCkpIHtcbiAgICAgIHJldHVybiBsb29rYWhlYWQ7XG4gICAgfVxuICAgIHRocm93IHRoaXMuY3JlYXRlRXJyb3IobG9va2FoZWFkLCAnZXhwZWN0aW5nIGEgdW5hcnkgb3BlcmF0b3InKTtcbiAgfVxuXG4gIG1hdGNoUHVuY3R1YXRvcih2YWw6IHN0cmluZykge1xuICAgIGxldCBsb29rYWhlYWQgPSB0aGlzLm1hdGNoUmF3U3ludGF4KCk7XG4gICAgaWYgKHRoaXMuaXNQdW5jdHVhdG9yKGxvb2thaGVhZCkpIHtcbiAgICAgIGlmICh0eXBlb2YgdmFsICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBpZiAobG9va2FoZWFkLnZhbCgpID09PSB2YWwpIHtcbiAgICAgICAgICByZXR1cm4gbG9va2FoZWFkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IHRoaXMuY3JlYXRlRXJyb3IoXG4gICAgICAgICAgICBsb29rYWhlYWQsXG4gICAgICAgICAgICAnZXhwZWN0aW5nIGEgJyArIHZhbCArICcgcHVuY3R1YXRvcicsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGxvb2thaGVhZDtcbiAgICB9XG4gICAgdGhyb3cgdGhpcy5jcmVhdGVFcnJvcihsb29rYWhlYWQsICdleHBlY3RpbmcgYSBwdW5jdHVhdG9yJyk7XG4gIH1cblxuICBjcmVhdGVFcnJvcihzdHg6IFN5bnRheCB8IFRlcm0sIG1lc3NhZ2U6IHN0cmluZykge1xuICAgIGxldCBjdHggPSAnJztcbiAgICBsZXQgb2ZmZW5kaW5nID0gc3R4O1xuICAgIGlmICh0aGlzLnJlc3Quc2l6ZSA+IDApIHtcbiAgICAgIGN0eCA9IHRoaXMucmVzdFxuICAgICAgICAuc2xpY2UoMCwgMjApXG4gICAgICAgIC5tYXAodGVybSA9PiB7XG4gICAgICAgICAgaWYgKHRlcm0gaW5zdGFuY2VvZiBULlJhd0RlbGltaXRlcikge1xuICAgICAgICAgICAgcmV0dXJuIHRlcm0uaW5uZXI7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBMaXN0Lm9mKHRlcm0pO1xuICAgICAgICB9KVxuICAgICAgICAuZmxhdHRlbigpXG4gICAgICAgIC5tYXAocyA9PiB7XG4gICAgICAgICAgbGV0IHN2YWwgPSBzIGluc3RhbmNlb2YgVC5SYXdTeW50YXggPyBzLnZhbHVlLnZhbCgpIDogcy50b1N0cmluZygpO1xuICAgICAgICAgIGlmIChzID09PSBvZmZlbmRpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiAnX18nICsgc3ZhbCArICdfXyc7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBzdmFsO1xuICAgICAgICB9KVxuICAgICAgICAuam9pbignICcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjdHggPSBvZmZlbmRpbmcudG9TdHJpbmcoKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBFcnJvcihtZXNzYWdlICsgJ1xcbicgKyBjdHgpO1xuICB9XG59XG4iXX0=\n\n/***/ },\n/* 64 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\n\tvar _sweetSpec = __webpack_require__(43);\n\n\tvar S = _interopRequireWildcard(_sweetSpec);\n\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\n\texports.default = class extends S.default.CloneReducer {\n\n\t  constructor(scopes, bindings) {\n\t    super();\n\t    this.scopes = scopes;\n\t    this.bindings = bindings;\n\t  }\n\n\t  applyScopes(s) {\n\t    return this.scopes.reduce((acc, sc) => {\n\t      return acc.addScope(sc.scope, this.bindings, sc.phase, {\n\t        flip: sc.flip\n\t      });\n\t    }, s);\n\t  }\n\n\t  reduceBindingIdentifier(t, s) {\n\t    return new S.BindingIdentifier({\n\t      name: this.applyScopes(s.name)\n\t    });\n\t  }\n\n\t  reduceIdentifierExpression(t, s) {\n\t    return new S.IdentifierExpression({\n\t      name: this.applyScopes(s.name)\n\t    });\n\t  }\n\n\t  reduceRawSyntax(t, s) {\n\t    // TODO: fix this once reading tokens is reasonable\n\t    if (s.value.isTemplate() && s.value.items) {\n\t      s.value.token.items = s.value.token.items.map(t => {\n\t        if (t instanceof S.default) {\n\t          return t.reduce(this);\n\t        }\n\t        return t;\n\t      });\n\t    }\n\t    return new S.RawSyntax({\n\t      value: this.applyScopes(s.value)\n\t    });\n\t  }\n\t};\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY29wZS1yZWR1Y2VyLmpzIl0sIm5hbWVzIjpbIlMiLCJDbG9uZVJlZHVjZXIiLCJjb25zdHJ1Y3RvciIsInNjb3BlcyIsImJpbmRpbmdzIiwiYXBwbHlTY29wZXMiLCJzIiwicmVkdWNlIiwiYWNjIiwic2MiLCJhZGRTY29wZSIsInNjb3BlIiwicGhhc2UiLCJmbGlwIiwicmVkdWNlQmluZGluZ0lkZW50aWZpZXIiLCJ0IiwiQmluZGluZ0lkZW50aWZpZXIiLCJuYW1lIiwicmVkdWNlSWRlbnRpZmllckV4cHJlc3Npb24iLCJJZGVudGlmaWVyRXhwcmVzc2lvbiIsInJlZHVjZVJhd1N5bnRheCIsInZhbHVlIiwiaXNUZW1wbGF0ZSIsIml0ZW1zIiwidG9rZW4iLCJtYXAiLCJSYXdTeW50YXgiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBOztJQUFrQkEsQzs7OztrQkFLSCxjQUxHQSxDQUtXLFNBQUtDLFlBQW5CLENBQWdDOztBQUk3Q0MsY0FDRUMsTUFERixFQUVFQyxRQUZGLEVBR0U7QUFDQTtBQUNBLFNBQUtELE1BQUwsR0FBY0EsTUFBZDtBQUNBLFNBQUtDLFFBQUwsR0FBZ0JBLFFBQWhCO0FBQ0Q7O0FBRURDLGNBQVlDLENBQVosRUFBdUI7QUFDckIsV0FBTyxLQUFLSCxNQUFMLENBQVlJLE1BQVosQ0FDTCxDQUFDQyxHQUFELEVBQU1DLEVBQU4sS0FBYTtBQUNYLGFBQU9ELElBQUlFLFFBQUosQ0FBYUQsR0FBR0UsS0FBaEIsRUFBdUIsS0FBS1AsUUFBNUIsRUFBc0NLLEdBQUdHLEtBQXpDLEVBQWdEO0FBQ3JEQyxjQUFNSixHQUFHSTtBQUQ0QyxPQUFoRCxDQUFQO0FBR0QsS0FMSSxFQU1MUCxDQU5LLENBQVA7QUFRRDs7QUFFRFEsMEJBQXdCQyxDQUF4QixFQUFpQ1QsQ0FBakMsRUFBc0Q7QUFDcEQsV0FBTyxJQUFJTixFQUFFZ0IsaUJBQU4sQ0FBd0I7QUFDN0JDLFlBQU0sS0FBS1osV0FBTCxDQUFpQkMsRUFBRVcsSUFBbkI7QUFEdUIsS0FBeEIsQ0FBUDtBQUdEOztBQUVEQyw2QkFBMkJILENBQTNCLEVBQW9DVCxDQUFwQyxFQUF5RDtBQUN2RCxXQUFPLElBQUlOLEVBQUVtQixvQkFBTixDQUEyQjtBQUNoQ0YsWUFBTSxLQUFLWixXQUFMLENBQWlCQyxFQUFFVyxJQUFuQjtBQUQwQixLQUEzQixDQUFQO0FBR0Q7O0FBRURHLGtCQUFnQkwsQ0FBaEIsRUFBeUJULENBQXpCLEVBQStDO0FBQzdDO0FBQ0EsUUFBSUEsRUFBRWUsS0FBRixDQUFRQyxVQUFSLE1BQXdCaEIsRUFBRWUsS0FBRixDQUFRRSxLQUFwQyxFQUEyQztBQUN6Q2pCLFFBQUVlLEtBQUYsQ0FBUUcsS0FBUixDQUFjRCxLQUFkLEdBQXNCakIsRUFBRWUsS0FBRixDQUFRRyxLQUFSLENBQWNELEtBQWQsQ0FBb0JFLEdBQXBCLENBQXdCVixLQUFLO0FBQ2pELFlBQUlBLGFBN0NNZixDQTZDTixRQUFKLEVBQXVCO0FBQ3JCLGlCQUFPZSxFQUFFUixNQUFGLENBQVMsSUFBVCxDQUFQO0FBQ0Q7QUFDRCxlQUFPUSxDQUFQO0FBQ0QsT0FMcUIsQ0FBdEI7QUFNRDtBQUNELFdBQU8sSUFBSWYsRUFBRTBCLFNBQU4sQ0FBZ0I7QUFDckJMLGFBQU8sS0FBS2hCLFdBQUwsQ0FBaUJDLEVBQUVlLEtBQW5CO0FBRGMsS0FBaEIsQ0FBUDtBQUdEO0FBakQ0QyxDIiwiZmlsZSI6InNjb3BlLXJlZHVjZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAZmxvd1xuaW1wb3J0IFRlcm0sICogYXMgUyBmcm9tICdzd2VldC1zcGVjJztcbmltcG9ydCB0eXBlIFN5bnRheCBmcm9tICcuL3N5bnRheCc7XG5pbXBvcnQgdHlwZSB7IFN5bWJvbENsYXNzIH0gZnJvbSAnLi9zeW1ib2wnO1xuaW1wb3J0IHR5cGUgQmluZGluZ01hcCBmcm9tICcuL2JpbmRpbmctbWFwJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgZXh0ZW5kcyBUZXJtLkNsb25lUmVkdWNlciB7XG4gIHNjb3BlczogQXJyYXk8eyBzY29wZTogU3ltYm9sQ2xhc3MsIHBoYXNlOiBudW1iZXIgfCB7fSwgZmxpcDogYm9vbGVhbiB9PjtcbiAgYmluZGluZ3M6IEJpbmRpbmdNYXA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGVzOiBBcnJheTx7IHNjb3BlOiBTeW1ib2xDbGFzcywgcGhhc2U6IG51bWJlciB8IHt9LCBmbGlwOiBib29sZWFuIH0+LFxuICAgIGJpbmRpbmdzOiBCaW5kaW5nTWFwLFxuICApIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuc2NvcGVzID0gc2NvcGVzO1xuICAgIHRoaXMuYmluZGluZ3MgPSBiaW5kaW5ncztcbiAgfVxuXG4gIGFwcGx5U2NvcGVzKHM6IFN5bnRheCkge1xuICAgIHJldHVybiB0aGlzLnNjb3Blcy5yZWR1Y2UoXG4gICAgICAoYWNjLCBzYykgPT4ge1xuICAgICAgICByZXR1cm4gYWNjLmFkZFNjb3BlKHNjLnNjb3BlLCB0aGlzLmJpbmRpbmdzLCBzYy5waGFzZSwge1xuICAgICAgICAgIGZsaXA6IHNjLmZsaXAsXG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICAgIHMsXG4gICAgKTtcbiAgfVxuXG4gIHJlZHVjZUJpbmRpbmdJZGVudGlmaWVyKHQ6IFRlcm0sIHM6IHsgbmFtZTogU3ludGF4IH0pIHtcbiAgICByZXR1cm4gbmV3IFMuQmluZGluZ0lkZW50aWZpZXIoe1xuICAgICAgbmFtZTogdGhpcy5hcHBseVNjb3BlcyhzLm5hbWUpLFxuICAgIH0pO1xuICB9XG5cbiAgcmVkdWNlSWRlbnRpZmllckV4cHJlc3Npb24odDogVGVybSwgczogeyBuYW1lOiBTeW50YXggfSkge1xuICAgIHJldHVybiBuZXcgUy5JZGVudGlmaWVyRXhwcmVzc2lvbih7XG4gICAgICBuYW1lOiB0aGlzLmFwcGx5U2NvcGVzKHMubmFtZSksXG4gICAgfSk7XG4gIH1cblxuICByZWR1Y2VSYXdTeW50YXgodDogVGVybSwgczogeyB2YWx1ZTogU3ludGF4IH0pIHtcbiAgICAvLyBUT0RPOiBmaXggdGhpcyBvbmNlIHJlYWRpbmcgdG9rZW5zIGlzIHJlYXNvbmFibGVcbiAgICBpZiAocy52YWx1ZS5pc1RlbXBsYXRlKCkgJiYgcy52YWx1ZS5pdGVtcykge1xuICAgICAgcy52YWx1ZS50b2tlbi5pdGVtcyA9IHMudmFsdWUudG9rZW4uaXRlbXMubWFwKHQgPT4ge1xuICAgICAgICBpZiAodCBpbnN0YW5jZW9mIFRlcm0pIHtcbiAgICAgICAgICByZXR1cm4gdC5yZWR1Y2UodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHQ7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBTLlJhd1N5bnRheCh7XG4gICAgICB2YWx1ZTogdGhpcy5hcHBseVNjb3BlcyhzLnZhbHVlKSxcbiAgICB9KTtcbiAgfVxufVxuIl19\n\n/***/ },\n/* 65 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.operatorLt = operatorLt;\n\texports.getOperatorPrec = getOperatorPrec;\n\texports.getOperatorAssoc = getOperatorAssoc;\n\texports.isUnaryOperator = isUnaryOperator;\n\texports.isOperator = isOperator;\n\tconst unaryOperators = {\n\t  '+': true,\n\t  '-': true,\n\t  '!': true,\n\t  '~': true,\n\t  '++': true,\n\t  '--': true,\n\t  typeof: true,\n\t  void: true,\n\t  delete: true\n\t};\n\tconst binaryOperatorPrecedence = {\n\t  '*': 14,\n\t  '/': 14,\n\t  '%': 14,\n\t  '+': 13,\n\t  '-': 13,\n\t  '>>': 12,\n\t  '<<': 12,\n\t  '>>>': 12,\n\t  '<': 11,\n\t  '<=': 11,\n\t  '>': 11,\n\t  '>=': 11,\n\t  in: 11,\n\t  instanceof: 11,\n\t  '==': 10,\n\t  '!=': 10,\n\t  '===': 10,\n\t  '!==': 10,\n\t  '&': 9,\n\t  '^': 8,\n\t  '|': 7,\n\t  '&&': 6,\n\t  '||': 5\n\t};\n\n\tvar operatorAssoc = {\n\t  '*': 'left',\n\t  '/': 'left',\n\t  '%': 'left',\n\t  '+': 'left',\n\t  '-': 'left',\n\t  '>>': 'left',\n\t  '<<': 'left',\n\t  '>>>': 'left',\n\t  '<': 'left',\n\t  '<=': 'left',\n\t  '>': 'left',\n\t  '>=': 'left',\n\t  in: 'left',\n\t  instanceof: 'left',\n\t  '==': 'left',\n\t  '!=': 'left',\n\t  '===': 'left',\n\t  '!==': 'left',\n\t  '&': 'left',\n\t  '^': 'left',\n\t  '|': 'left',\n\t  '&&': 'left',\n\t  '||': 'left'\n\t};\n\n\tfunction operatorLt(left, right, assoc) {\n\t  if (assoc === 'left') {\n\t    return left < right;\n\t  } else {\n\t    return left <= right;\n\t  }\n\t}\n\n\tfunction getOperatorPrec(op) {\n\t  return binaryOperatorPrecedence[op];\n\t}\n\tfunction getOperatorAssoc(op) {\n\t  return operatorAssoc[op];\n\t}\n\n\tfunction isUnaryOperator(op) {\n\t  return (op.match('punctuator') || op.match('identifier') || op.match('keyword')) && unaryOperators.hasOwnProperty(op.val());\n\t}\n\n\tfunction isOperator(op) {\n\t  if (op.match('punctuator') || op.match('identifier') || op.match('keyword')) {\n\t    return binaryOperatorPrecedence.hasOwnProperty(op) || unaryOperators.hasOwnProperty(op.val());\n\t  }\n\t  return false;\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9vcGVyYXRvcnMuanMiXSwibmFtZXMiOlsib3BlcmF0b3JMdCIsImdldE9wZXJhdG9yUHJlYyIsImdldE9wZXJhdG9yQXNzb2MiLCJpc1VuYXJ5T3BlcmF0b3IiLCJpc09wZXJhdG9yIiwidW5hcnlPcGVyYXRvcnMiLCJ0eXBlb2YiLCJ2b2lkIiwiZGVsZXRlIiwiYmluYXJ5T3BlcmF0b3JQcmVjZWRlbmNlIiwiaW4iLCJpbnN0YW5jZW9mIiwib3BlcmF0b3JBc3NvYyIsImxlZnQiLCJyaWdodCIsImFzc29jIiwib3AiLCJtYXRjaCIsImhhc093blByb3BlcnR5IiwidmFsIl0sIm1hcHBpbmdzIjoiOzs7OztRQStEZ0JBLFUsR0FBQUEsVTtRQVFBQyxlLEdBQUFBLGU7UUFHQUMsZ0IsR0FBQUEsZ0I7UUFJQUMsZSxHQUFBQSxlO1FBT0FDLFUsR0FBQUEsVTtBQXJGaEIsTUFBTUMsaUJBQWlCO0FBQ3JCLE9BQUssSUFEZ0I7QUFFckIsT0FBSyxJQUZnQjtBQUdyQixPQUFLLElBSGdCO0FBSXJCLE9BQUssSUFKZ0I7QUFLckIsUUFBTSxJQUxlO0FBTXJCLFFBQU0sSUFOZTtBQU9yQkMsVUFBUSxJQVBhO0FBUXJCQyxRQUFNLElBUmU7QUFTckJDLFVBQVE7QUFUYSxDQUF2QjtBQVdBLE1BQU1DLDJCQUEyQjtBQUMvQixPQUFLLEVBRDBCO0FBRS9CLE9BQUssRUFGMEI7QUFHL0IsT0FBSyxFQUgwQjtBQUkvQixPQUFLLEVBSjBCO0FBSy9CLE9BQUssRUFMMEI7QUFNL0IsUUFBTSxFQU55QjtBQU8vQixRQUFNLEVBUHlCO0FBUS9CLFNBQU8sRUFSd0I7QUFTL0IsT0FBSyxFQVQwQjtBQVUvQixRQUFNLEVBVnlCO0FBVy9CLE9BQUssRUFYMEI7QUFZL0IsUUFBTSxFQVp5QjtBQWEvQkMsTUFBSSxFQWIyQjtBQWMvQkMsY0FBWSxFQWRtQjtBQWUvQixRQUFNLEVBZnlCO0FBZ0IvQixRQUFNLEVBaEJ5QjtBQWlCL0IsU0FBTyxFQWpCd0I7QUFrQi9CLFNBQU8sRUFsQndCO0FBbUIvQixPQUFLLENBbkIwQjtBQW9CL0IsT0FBSyxDQXBCMEI7QUFxQi9CLE9BQUssQ0FyQjBCO0FBc0IvQixRQUFNLENBdEJ5QjtBQXVCL0IsUUFBTTtBQXZCeUIsQ0FBakM7O0FBMEJBLElBQUlDLGdCQUFnQjtBQUNsQixPQUFLLE1BRGE7QUFFbEIsT0FBSyxNQUZhO0FBR2xCLE9BQUssTUFIYTtBQUlsQixPQUFLLE1BSmE7QUFLbEIsT0FBSyxNQUxhO0FBTWxCLFFBQU0sTUFOWTtBQU9sQixRQUFNLE1BUFk7QUFRbEIsU0FBTyxNQVJXO0FBU2xCLE9BQUssTUFUYTtBQVVsQixRQUFNLE1BVlk7QUFXbEIsT0FBSyxNQVhhO0FBWWxCLFFBQU0sTUFaWTtBQWFsQkYsTUFBSSxNQWJjO0FBY2xCQyxjQUFZLE1BZE07QUFlbEIsUUFBTSxNQWZZO0FBZ0JsQixRQUFNLE1BaEJZO0FBaUJsQixTQUFPLE1BakJXO0FBa0JsQixTQUFPLE1BbEJXO0FBbUJsQixPQUFLLE1BbkJhO0FBb0JsQixPQUFLLE1BcEJhO0FBcUJsQixPQUFLLE1BckJhO0FBc0JsQixRQUFNLE1BdEJZO0FBdUJsQixRQUFNO0FBdkJZLENBQXBCOztBQTBCTyxTQUFTWCxVQUFULENBQW9CYSxJQUFwQixFQUEwQkMsS0FBMUIsRUFBaUNDLEtBQWpDLEVBQXdDO0FBQzdDLE1BQUlBLFVBQVUsTUFBZCxFQUFzQjtBQUNwQixXQUFPRixPQUFPQyxLQUFkO0FBQ0QsR0FGRCxNQUVPO0FBQ0wsV0FBT0QsUUFBUUMsS0FBZjtBQUNEO0FBQ0Y7O0FBRU0sU0FBU2IsZUFBVCxDQUF5QmUsRUFBekIsRUFBNkI7QUFDbEMsU0FBT1AseUJBQXlCTyxFQUF6QixDQUFQO0FBQ0Q7QUFDTSxTQUFTZCxnQkFBVCxDQUEwQmMsRUFBMUIsRUFBOEI7QUFDbkMsU0FBT0osY0FBY0ksRUFBZCxDQUFQO0FBQ0Q7O0FBRU0sU0FBU2IsZUFBVCxDQUF5QmEsRUFBekIsRUFBNkI7QUFDbEMsU0FBTyxDQUFDQSxHQUFHQyxLQUFILENBQVMsWUFBVCxLQUNORCxHQUFHQyxLQUFILENBQVMsWUFBVCxDQURNLElBRU5ELEdBQUdDLEtBQUgsQ0FBUyxTQUFULENBRkssS0FHTFosZUFBZWEsY0FBZixDQUE4QkYsR0FBR0csR0FBSCxFQUE5QixDQUhGO0FBSUQ7O0FBRU0sU0FBU2YsVUFBVCxDQUFvQlksRUFBcEIsRUFBd0I7QUFDN0IsTUFBSUEsR0FBR0MsS0FBSCxDQUFTLFlBQVQsS0FBMEJELEdBQUdDLEtBQUgsQ0FBUyxZQUFULENBQTFCLElBQW9ERCxHQUFHQyxLQUFILENBQVMsU0FBVCxDQUF4RCxFQUE2RTtBQUMzRSxXQUFPUix5QkFBeUJTLGNBQXpCLENBQXdDRixFQUF4QyxLQUNMWCxlQUFlYSxjQUFmLENBQThCRixHQUFHRyxHQUFILEVBQTlCLENBREY7QUFFRDtBQUNELFNBQU8sS0FBUDtBQUNEIiwiZmlsZSI6Im9wZXJhdG9ycy5qcyIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IHVuYXJ5T3BlcmF0b3JzID0ge1xuICAnKyc6IHRydWUsXG4gICctJzogdHJ1ZSxcbiAgJyEnOiB0cnVlLFxuICAnfic6IHRydWUsXG4gICcrKyc6IHRydWUsXG4gICctLSc6IHRydWUsXG4gIHR5cGVvZjogdHJ1ZSxcbiAgdm9pZDogdHJ1ZSxcbiAgZGVsZXRlOiB0cnVlLFxufTtcbmNvbnN0IGJpbmFyeU9wZXJhdG9yUHJlY2VkZW5jZSA9IHtcbiAgJyonOiAxNCxcbiAgJy8nOiAxNCxcbiAgJyUnOiAxNCxcbiAgJysnOiAxMyxcbiAgJy0nOiAxMyxcbiAgJz4+JzogMTIsXG4gICc8PCc6IDEyLFxuICAnPj4+JzogMTIsXG4gICc8JzogMTEsXG4gICc8PSc6IDExLFxuICAnPic6IDExLFxuICAnPj0nOiAxMSxcbiAgaW46IDExLFxuICBpbnN0YW5jZW9mOiAxMSxcbiAgJz09JzogMTAsXG4gICchPSc6IDEwLFxuICAnPT09JzogMTAsXG4gICchPT0nOiAxMCxcbiAgJyYnOiA5LFxuICAnXic6IDgsXG4gICd8JzogNyxcbiAgJyYmJzogNixcbiAgJ3x8JzogNSxcbn07XG5cbnZhciBvcGVyYXRvckFzc29jID0ge1xuICAnKic6ICdsZWZ0JyxcbiAgJy8nOiAnbGVmdCcsXG4gICclJzogJ2xlZnQnLFxuICAnKyc6ICdsZWZ0JyxcbiAgJy0nOiAnbGVmdCcsXG4gICc+Pic6ICdsZWZ0JyxcbiAgJzw8JzogJ2xlZnQnLFxuICAnPj4+JzogJ2xlZnQnLFxuICAnPCc6ICdsZWZ0JyxcbiAgJzw9JzogJ2xlZnQnLFxuICAnPic6ICdsZWZ0JyxcbiAgJz49JzogJ2xlZnQnLFxuICBpbjogJ2xlZnQnLFxuICBpbnN0YW5jZW9mOiAnbGVmdCcsXG4gICc9PSc6ICdsZWZ0JyxcbiAgJyE9JzogJ2xlZnQnLFxuICAnPT09JzogJ2xlZnQnLFxuICAnIT09JzogJ2xlZnQnLFxuICAnJic6ICdsZWZ0JyxcbiAgJ14nOiAnbGVmdCcsXG4gICd8JzogJ2xlZnQnLFxuICAnJiYnOiAnbGVmdCcsXG4gICd8fCc6ICdsZWZ0Jyxcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBvcGVyYXRvckx0KGxlZnQsIHJpZ2h0LCBhc3NvYykge1xuICBpZiAoYXNzb2MgPT09ICdsZWZ0Jykge1xuICAgIHJldHVybiBsZWZ0IDwgcmlnaHQ7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGxlZnQgPD0gcmlnaHQ7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE9wZXJhdG9yUHJlYyhvcCkge1xuICByZXR1cm4gYmluYXJ5T3BlcmF0b3JQcmVjZWRlbmNlW29wXTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnZXRPcGVyYXRvckFzc29jKG9wKSB7XG4gIHJldHVybiBvcGVyYXRvckFzc29jW29wXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzVW5hcnlPcGVyYXRvcihvcCkge1xuICByZXR1cm4gKG9wLm1hdGNoKCdwdW5jdHVhdG9yJykgfHxcbiAgICBvcC5tYXRjaCgnaWRlbnRpZmllcicpIHx8XG4gICAgb3AubWF0Y2goJ2tleXdvcmQnKSkgJiZcbiAgICB1bmFyeU9wZXJhdG9ycy5oYXNPd25Qcm9wZXJ0eShvcC52YWwoKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc09wZXJhdG9yKG9wKSB7XG4gIGlmIChvcC5tYXRjaCgncHVuY3R1YXRvcicpIHx8IG9wLm1hdGNoKCdpZGVudGlmaWVyJykgfHwgb3AubWF0Y2goJ2tleXdvcmQnKSkge1xuICAgIHJldHVybiBiaW5hcnlPcGVyYXRvclByZWNlZGVuY2UuaGFzT3duUHJvcGVydHkob3ApIHx8XG4gICAgICB1bmFyeU9wZXJhdG9ycy5oYXNPd25Qcm9wZXJ0eShvcC52YWwoKSk7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuIl19\n\n/***/ },\n/* 66 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.expandCompiletime = expandCompiletime;\n\texports.sanitizeReplacementValues = sanitizeReplacementValues;\n\texports.evalCompiletimeValue = evalCompiletimeValue;\n\n\tvar _sweetSpec = __webpack_require__(43);\n\n\tvar S = _interopRequireWildcard(_sweetSpec);\n\n\tvar _ramda = __webpack_require__(20);\n\n\tvar _ = _interopRequireWildcard(_ramda);\n\n\tvar _immutable = __webpack_require__(12);\n\n\tvar _syntax = __webpack_require__(58);\n\n\tvar _syntax2 = _interopRequireDefault(_syntax);\n\n\tvar _shiftCodegen = __webpack_require__(46);\n\n\tvar _shiftCodegen2 = _interopRequireDefault(_shiftCodegen);\n\n\tvar _sweetToShiftReducer = __webpack_require__(56);\n\n\tvar _sweetToShiftReducer2 = _interopRequireDefault(_sweetToShiftReducer);\n\n\tvar _termExpander = __webpack_require__(62);\n\n\tvar _termExpander2 = _interopRequireDefault(_termExpander);\n\n\tvar _env = __webpack_require__(40);\n\n\tvar _env2 = _interopRequireDefault(_env);\n\n\tvar _templateProcessor = __webpack_require__(67);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\n\tfunction expandCompiletime(term, context) {\n\t  // each compiletime value needs to be expanded with a fresh\n\t  // environment and in the next higher phase\n\t  let syntaxExpander = new _termExpander2.default(_.merge(context, {\n\t    phase: context.phase + 1,\n\t    env: new _env2.default(),\n\t    store: context.store\n\t  }));\n\n\t  return syntaxExpander.expand(term);\n\t}\n\n\tfunction sanitizeReplacementValues(values) {\n\t  if (Array.isArray(values)) {\n\t    return sanitizeReplacementValues((0, _immutable.List)(values));\n\t  } else if (_immutable.List.isList(values)) {\n\t    return values.map(sanitizeReplacementValues);\n\t  } else if (values == null) {\n\t    throw new Error('replacement values for syntax template must not be null or undefined');\n\t  } else if (typeof values.next === 'function') {\n\t    return sanitizeReplacementValues((0, _immutable.List)(values));\n\t  }\n\t  return values;\n\t}\n\n\t// (Expression, Context) -> [function]\n\tfunction evalCompiletimeValue(expr, context) {\n\t  let sandbox = {\n\t    syntaxTemplate: function (ident, ...values) {\n\t      return (0, _templateProcessor.replaceTemplate)(context.templateMap.get(ident), sanitizeReplacementValues(values));\n\t    }\n\t  };\n\n\t  let sandboxKeys = (0, _immutable.List)(Object.keys(sandbox));\n\t  let sandboxVals = sandboxKeys.map(k => sandbox[k]).toArray();\n\n\t  let parsed = new S.Module({\n\t    directives: (0, _immutable.List)(),\n\t    items: _immutable.List.of(new S.ExpressionStatement({\n\t      expression: new S.FunctionExpression({\n\t        isGenerator: false,\n\t        name: null,\n\t        params: new S.FormalParameters({\n\t          items: sandboxKeys.map(param => {\n\t            return new S.BindingIdentifier({\n\t              name: _syntax2.default.from('identifier', param)\n\t            });\n\t          }),\n\t          rest: null\n\t        }),\n\t        body: new S.FunctionBody({\n\t          directives: _immutable.List.of(new S.Directive({\n\t            rawValue: 'use strict'\n\t          })),\n\t          statements: _immutable.List.of(new S.ReturnStatement({\n\t            expression: expr\n\t          }))\n\t        })\n\t      })\n\t    }))\n\t  }).reduce(new _sweetToShiftReducer2.default(context.phase));\n\n\t  let gen = (0, _shiftCodegen2.default)(parsed, new _shiftCodegen.FormattedCodeGen());\n\t  let result = context.transform(gen);\n\n\t  let val = context.loader.eval(result.code, context.store);\n\t  return val.apply(undefined, sandboxVals);\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9sb2FkLXN5bnRheC5qcyJdLCJuYW1lcyI6WyJleHBhbmRDb21waWxldGltZSIsInNhbml0aXplUmVwbGFjZW1lbnRWYWx1ZXMiLCJldmFsQ29tcGlsZXRpbWVWYWx1ZSIsIlMiLCJfIiwidGVybSIsImNvbnRleHQiLCJzeW50YXhFeHBhbmRlciIsIm1lcmdlIiwicGhhc2UiLCJlbnYiLCJzdG9yZSIsImV4cGFuZCIsInZhbHVlcyIsIkFycmF5IiwiaXNBcnJheSIsImlzTGlzdCIsIm1hcCIsIkVycm9yIiwibmV4dCIsImV4cHIiLCJzYW5kYm94Iiwic3ludGF4VGVtcGxhdGUiLCJpZGVudCIsInRlbXBsYXRlTWFwIiwiZ2V0Iiwic2FuZGJveEtleXMiLCJPYmplY3QiLCJrZXlzIiwic2FuZGJveFZhbHMiLCJrIiwidG9BcnJheSIsInBhcnNlZCIsIk1vZHVsZSIsImRpcmVjdGl2ZXMiLCJpdGVtcyIsIm9mIiwiRXhwcmVzc2lvblN0YXRlbWVudCIsImV4cHJlc3Npb24iLCJGdW5jdGlvbkV4cHJlc3Npb24iLCJpc0dlbmVyYXRvciIsIm5hbWUiLCJwYXJhbXMiLCJGb3JtYWxQYXJhbWV0ZXJzIiwicGFyYW0iLCJCaW5kaW5nSWRlbnRpZmllciIsImZyb20iLCJyZXN0IiwiYm9keSIsIkZ1bmN0aW9uQm9keSIsIkRpcmVjdGl2ZSIsInJhd1ZhbHVlIiwic3RhdGVtZW50cyIsIlJldHVyblN0YXRlbWVudCIsInJlZHVjZSIsImdlbiIsInJlc3VsdCIsInRyYW5zZm9ybSIsInZhbCIsImxvYWRlciIsImV2YWwiLCJjb2RlIiwiYXBwbHkiLCJ1bmRlZmluZWQiXSwibWFwcGluZ3MiOiI7Ozs7O1FBV2dCQSxpQixHQUFBQSxpQjtRQWNBQyx5QixHQUFBQSx5QjtRQWdCQUMsb0IsR0FBQUEsb0I7O0FBekNoQjs7SUFBWUMsQzs7QUFDWjs7SUFBWUMsQzs7QUFDWjs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBRUE7Ozs7OztBQUVPLFNBQVNKLGlCQUFULENBQTJCSyxJQUEzQixFQUFpQ0MsT0FBakMsRUFBMEM7QUFDL0M7QUFDQTtBQUNBLE1BQUlDLGlCQUFpQiwyQkFDbkJILEVBQUVJLEtBQUYsQ0FBUUYsT0FBUixFQUFpQjtBQUNmRyxXQUFPSCxRQUFRRyxLQUFSLEdBQWdCLENBRFI7QUFFZkMsU0FBSyxtQkFGVTtBQUdmQyxXQUFPTCxRQUFRSztBQUhBLEdBQWpCLENBRG1CLENBQXJCOztBQVFBLFNBQU9KLGVBQWVLLE1BQWYsQ0FBc0JQLElBQXRCLENBQVA7QUFDRDs7QUFFTSxTQUFTSix5QkFBVCxDQUFtQ1ksTUFBbkMsRUFBMkM7QUFDaEQsTUFBSUMsTUFBTUMsT0FBTixDQUFjRixNQUFkLENBQUosRUFBMkI7QUFDekIsV0FBT1osMEJBQTBCLHFCQUFLWSxNQUFMLENBQTFCLENBQVA7QUFDRCxHQUZELE1BRU8sSUFBSSxnQkFBS0csTUFBTCxDQUFZSCxNQUFaLENBQUosRUFBeUI7QUFDOUIsV0FBT0EsT0FBT0ksR0FBUCxDQUFXaEIseUJBQVgsQ0FBUDtBQUNELEdBRk0sTUFFQSxJQUFJWSxVQUFVLElBQWQsRUFBb0I7QUFDekIsVUFBTSxJQUFJSyxLQUFKLENBQ0osc0VBREksQ0FBTjtBQUdELEdBSk0sTUFJQSxJQUFJLE9BQU9MLE9BQU9NLElBQWQsS0FBdUIsVUFBM0IsRUFBdUM7QUFDNUMsV0FBT2xCLDBCQUEwQixxQkFBS1ksTUFBTCxDQUExQixDQUFQO0FBQ0Q7QUFDRCxTQUFPQSxNQUFQO0FBQ0Q7O0FBRUQ7QUFDTyxTQUFTWCxvQkFBVCxDQUE4QmtCLElBQTlCLEVBQWtEZCxPQUFsRCxFQUFnRTtBQUNyRSxNQUFJZSxVQUFVO0FBQ1pDLG9CQUFnQixVQUFTQyxLQUFULEVBQWdCLEdBQUdWLE1BQW5CLEVBQTJCO0FBQ3pDLGFBQU8sd0NBQ0xQLFFBQVFrQixXQUFSLENBQW9CQyxHQUFwQixDQUF3QkYsS0FBeEIsQ0FESyxFQUVMdEIsMEJBQTBCWSxNQUExQixDQUZLLENBQVA7QUFJRDtBQU5XLEdBQWQ7O0FBU0EsTUFBSWEsY0FBYyxxQkFBS0MsT0FBT0MsSUFBUCxDQUFZUCxPQUFaLENBQUwsQ0FBbEI7QUFDQSxNQUFJUSxjQUFjSCxZQUFZVCxHQUFaLENBQWdCYSxLQUFLVCxRQUFRUyxDQUFSLENBQXJCLEVBQWlDQyxPQUFqQyxFQUFsQjs7QUFFQSxNQUFJQyxTQUFTLElBQUk3QixFQUFFOEIsTUFBTixDQUFhO0FBQ3hCQyxnQkFBWSxzQkFEWTtBQUV4QkMsV0FBTyxnQkFBS0MsRUFBTCxDQUNMLElBQUlqQyxFQUFFa0MsbUJBQU4sQ0FBMEI7QUFDeEJDLGtCQUFZLElBQUluQyxFQUFFb0Msa0JBQU4sQ0FBeUI7QUFDbkNDLHFCQUFhLEtBRHNCO0FBRW5DQyxjQUFNLElBRjZCO0FBR25DQyxnQkFBUSxJQUFJdkMsRUFBRXdDLGdCQUFOLENBQXVCO0FBQzdCUixpQkFBT1QsWUFBWVQsR0FBWixDQUFnQjJCLFNBQVM7QUFDOUIsbUJBQU8sSUFBSXpDLEVBQUUwQyxpQkFBTixDQUF3QjtBQUM3Qkosb0JBQU0saUJBQU9LLElBQVAsQ0FBWSxZQUFaLEVBQTBCRixLQUExQjtBQUR1QixhQUF4QixDQUFQO0FBR0QsV0FKTSxDQURzQjtBQU03QkcsZ0JBQU07QUFOdUIsU0FBdkIsQ0FIMkI7QUFXbkNDLGNBQU0sSUFBSTdDLEVBQUU4QyxZQUFOLENBQW1CO0FBQ3ZCZixzQkFBWSxnQkFBS0UsRUFBTCxDQUNWLElBQUlqQyxFQUFFK0MsU0FBTixDQUFnQjtBQUNkQyxzQkFBVTtBQURJLFdBQWhCLENBRFUsQ0FEVztBQU12QkMsc0JBQVksZ0JBQUtoQixFQUFMLENBQ1YsSUFBSWpDLEVBQUVrRCxlQUFOLENBQXNCO0FBQ3BCZix3QkFBWWxCO0FBRFEsV0FBdEIsQ0FEVTtBQU5XLFNBQW5CO0FBWDZCLE9BQXpCO0FBRFksS0FBMUIsQ0FESztBQUZpQixHQUFiLEVBOEJWa0MsTUE5QlUsQ0E4Qkgsa0NBQXdCaEQsUUFBUUcsS0FBaEMsQ0E5QkcsQ0FBYjs7QUFnQ0EsTUFBSThDLE1BQU0sNEJBQVF2QixNQUFSLEVBQWdCLG9DQUFoQixDQUFWO0FBQ0EsTUFBSXdCLFNBQVNsRCxRQUFRbUQsU0FBUixDQUFrQkYsR0FBbEIsQ0FBYjs7QUFFQSxNQUFJRyxNQUFNcEQsUUFBUXFELE1BQVIsQ0FBZUMsSUFBZixDQUFvQkosT0FBT0ssSUFBM0IsRUFBaUN2RCxRQUFRSyxLQUF6QyxDQUFWO0FBQ0EsU0FBTytDLElBQUlJLEtBQUosQ0FBVUMsU0FBVixFQUFxQmxDLFdBQXJCLENBQVA7QUFDRCIsImZpbGUiOiJsb2FkLXN5bnRheC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIFMgZnJvbSAnc3dlZXQtc3BlYyc7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ3JhbWRhJztcbmltcG9ydCB7IExpc3QgfSBmcm9tICdpbW11dGFibGUnO1xuaW1wb3J0IFN5bnRheCBmcm9tICcuL3N5bnRheCc7XG5pbXBvcnQgY29kZWdlbiwgeyBGb3JtYXR0ZWRDb2RlR2VuIH0gZnJvbSAnc2hpZnQtY29kZWdlbic7XG5pbXBvcnQgU3dlZXRUb1NoaWZ0UmVkdWNlciBmcm9tICcuL3N3ZWV0LXRvLXNoaWZ0LXJlZHVjZXInO1xuaW1wb3J0IFRlcm1FeHBhbmRlciBmcm9tICcuL3Rlcm0tZXhwYW5kZXInO1xuaW1wb3J0IEVudiBmcm9tICcuL2Vudic7XG5cbmltcG9ydCB7IHJlcGxhY2VUZW1wbGF0ZSB9IGZyb20gJy4vdGVtcGxhdGUtcHJvY2Vzc29yJztcblxuZXhwb3J0IGZ1bmN0aW9uIGV4cGFuZENvbXBpbGV0aW1lKHRlcm0sIGNvbnRleHQpIHtcbiAgLy8gZWFjaCBjb21waWxldGltZSB2YWx1ZSBuZWVkcyB0byBiZSBleHBhbmRlZCB3aXRoIGEgZnJlc2hcbiAgLy8gZW52aXJvbm1lbnQgYW5kIGluIHRoZSBuZXh0IGhpZ2hlciBwaGFzZVxuICBsZXQgc3ludGF4RXhwYW5kZXIgPSBuZXcgVGVybUV4cGFuZGVyKFxuICAgIF8ubWVyZ2UoY29udGV4dCwge1xuICAgICAgcGhhc2U6IGNvbnRleHQucGhhc2UgKyAxLFxuICAgICAgZW52OiBuZXcgRW52KCksXG4gICAgICBzdG9yZTogY29udGV4dC5zdG9yZSxcbiAgICB9KSxcbiAgKTtcblxuICByZXR1cm4gc3ludGF4RXhwYW5kZXIuZXhwYW5kKHRlcm0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2FuaXRpemVSZXBsYWNlbWVudFZhbHVlcyh2YWx1ZXMpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWVzKSkge1xuICAgIHJldHVybiBzYW5pdGl6ZVJlcGxhY2VtZW50VmFsdWVzKExpc3QodmFsdWVzKSk7XG4gIH0gZWxzZSBpZiAoTGlzdC5pc0xpc3QodmFsdWVzKSkge1xuICAgIHJldHVybiB2YWx1ZXMubWFwKHNhbml0aXplUmVwbGFjZW1lbnRWYWx1ZXMpO1xuICB9IGVsc2UgaWYgKHZhbHVlcyA9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ3JlcGxhY2VtZW50IHZhbHVlcyBmb3Igc3ludGF4IHRlbXBsYXRlIG11c3Qgbm90IGJlIG51bGwgb3IgdW5kZWZpbmVkJyxcbiAgICApO1xuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZXMubmV4dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBzYW5pdGl6ZVJlcGxhY2VtZW50VmFsdWVzKExpc3QodmFsdWVzKSk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlcztcbn1cblxuLy8gKEV4cHJlc3Npb24sIENvbnRleHQpIC0+IFtmdW5jdGlvbl1cbmV4cG9ydCBmdW5jdGlvbiBldmFsQ29tcGlsZXRpbWVWYWx1ZShleHByOiBTLkV4cHJlc3Npb24sIGNvbnRleHQ6IGFueSkge1xuICBsZXQgc2FuZGJveCA9IHtcbiAgICBzeW50YXhUZW1wbGF0ZTogZnVuY3Rpb24oaWRlbnQsIC4uLnZhbHVlcykge1xuICAgICAgcmV0dXJuIHJlcGxhY2VUZW1wbGF0ZShcbiAgICAgICAgY29udGV4dC50ZW1wbGF0ZU1hcC5nZXQoaWRlbnQpLFxuICAgICAgICBzYW5pdGl6ZVJlcGxhY2VtZW50VmFsdWVzKHZhbHVlcyksXG4gICAgICApO1xuICAgIH0sXG4gIH07XG5cbiAgbGV0IHNhbmRib3hLZXlzID0gTGlzdChPYmplY3Qua2V5cyhzYW5kYm94KSk7XG4gIGxldCBzYW5kYm94VmFscyA9IHNhbmRib3hLZXlzLm1hcChrID0+IHNhbmRib3hba10pLnRvQXJyYXkoKTtcblxuICBsZXQgcGFyc2VkID0gbmV3IFMuTW9kdWxlKHtcbiAgICBkaXJlY3RpdmVzOiBMaXN0KCksXG4gICAgaXRlbXM6IExpc3Qub2YoXG4gICAgICBuZXcgUy5FeHByZXNzaW9uU3RhdGVtZW50KHtcbiAgICAgICAgZXhwcmVzc2lvbjogbmV3IFMuRnVuY3Rpb25FeHByZXNzaW9uKHtcbiAgICAgICAgICBpc0dlbmVyYXRvcjogZmFsc2UsXG4gICAgICAgICAgbmFtZTogbnVsbCxcbiAgICAgICAgICBwYXJhbXM6IG5ldyBTLkZvcm1hbFBhcmFtZXRlcnMoe1xuICAgICAgICAgICAgaXRlbXM6IHNhbmRib3hLZXlzLm1hcChwYXJhbSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBuZXcgUy5CaW5kaW5nSWRlbnRpZmllcih7XG4gICAgICAgICAgICAgICAgbmFtZTogU3ludGF4LmZyb20oJ2lkZW50aWZpZXInLCBwYXJhbSksXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICByZXN0OiBudWxsLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIGJvZHk6IG5ldyBTLkZ1bmN0aW9uQm9keSh7XG4gICAgICAgICAgICBkaXJlY3RpdmVzOiBMaXN0Lm9mKFxuICAgICAgICAgICAgICBuZXcgUy5EaXJlY3RpdmUoe1xuICAgICAgICAgICAgICAgIHJhd1ZhbHVlOiAndXNlIHN0cmljdCcsXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIHN0YXRlbWVudHM6IExpc3Qub2YoXG4gICAgICAgICAgICAgIG5ldyBTLlJldHVyblN0YXRlbWVudCh7XG4gICAgICAgICAgICAgICAgZXhwcmVzc2lvbjogZXhwcixcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICApLFxuICAgICAgICAgIH0pLFxuICAgICAgICB9KSxcbiAgICAgIH0pLFxuICAgICksXG4gIH0pLnJlZHVjZShuZXcgU3dlZXRUb1NoaWZ0UmVkdWNlcihjb250ZXh0LnBoYXNlKSk7XG5cbiAgbGV0IGdlbiA9IGNvZGVnZW4ocGFyc2VkLCBuZXcgRm9ybWF0dGVkQ29kZUdlbigpKTtcbiAgbGV0IHJlc3VsdCA9IGNvbnRleHQudHJhbnNmb3JtKGdlbik7XG5cbiAgbGV0IHZhbCA9IGNvbnRleHQubG9hZGVyLmV2YWwocmVzdWx0LmNvZGUsIGNvbnRleHQuc3RvcmUpO1xuICByZXR1cm4gdmFsLmFwcGx5KHVuZGVmaW5lZCwgc2FuZGJveFZhbHMpO1xufVxuIl19\n\n/***/ },\n/* 67 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.processTemplate = processTemplate;\n\texports.replaceTemplate = replaceTemplate;\n\n\tvar _immutable = __webpack_require__(12);\n\n\tvar _ramda = __webpack_require__(20);\n\n\tvar _ramda2 = _interopRequireDefault(_ramda);\n\n\tvar _errors = __webpack_require__(59);\n\n\tvar _sweetSpec = __webpack_require__(43);\n\n\tvar T = _interopRequireWildcard(_sweetSpec);\n\n\tvar _syntax = __webpack_require__(58);\n\n\tvar _syntax2 = _interopRequireDefault(_syntax);\n\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\t/*\n\tGiven a syntax list like:\n\n\t  [foo, bar, $, { 42, +, 24 }, baz]\n\n\tconvert it to:\n\n\t  [foo, bar, $, { 0 }, baz]\n\n\tand return another list with the interpolated values at the corresponding\n\tpositions.\n\n\tRequires either lookahead/lookbehind of one (to see the $).\n\t*/\n\n\tconst isDolar = s => s instanceof T.RawSyntax && typeof s.value.match === 'function' && s.value.match('identifier') && s.value.val() === '$';\n\n\tconst isDelimiter = s => s instanceof T.RawDelimiter;\n\tconst isBraces = s => s instanceof T.RawDelimiter && s.kind === 'braces';\n\tconst isParens = s => s instanceof T.RawDelimiter && s.kind === 'parens';\n\tconst isBrackets = s => s instanceof T.RawDelimiter && s.kind === 'brackets';\n\n\tconst mkDelimiter = (kind, inner, from) => {\n\t  return new T.RawDelimiter({\n\t    kind,\n\t    inner: _immutable.List.of(from.inner.first()).concat(inner).concat(from.inner.last())\n\t  });\n\t};\n\n\tconst insertIntoDelimiter = _ramda2.default.cond([[isBraces, (s, r) => mkDelimiter('braces', r, s)], [isParens, (s, r) => mkDelimiter('parens', r, s)], [isBrackets, (s, r) => mkDelimiter('brackets', r, s)]]);\n\n\tconst process = (acc, s) => {\n\t  if (isBraces(s) && isDolar(acc.template.last())) {\n\t    let idx = _syntax2.default.fromNumber(acc.interp.size, s.inner.first().value);\n\t    return {\n\t      template: acc.template.push(mkDelimiter('braces', _immutable.List.of(new T.RawSyntax({\n\t        value: idx\n\t      })), s)),\n\t      interp: acc.interp.push(s.inner.slice(1, s.inner.size - 1))\n\t    };\n\t  } else if (isDelimiter(s)) {\n\t    let innerResult = processTemplate(s.inner.slice(1, s.inner.size - 1), acc.interp);\n\t    return {\n\t      template: acc.template.push(insertIntoDelimiter(s, innerResult.template)),\n\t      interp: innerResult.interp\n\t    };\n\t  } else {\n\t    return {\n\t      template: acc.template.push(s),\n\t      interp: acc.interp\n\t    };\n\t  }\n\t};\n\n\tfunction getLineNumber(t) {\n\t  if (t instanceof T.RawSyntax) {\n\t    return t.value.lineNumber();\n\t  }\n\t  return t.inner.first().value.lineNumber();\n\t}\n\n\tfunction setLineNumber(t, lineNumber) {\n\t  if (t instanceof T.RawSyntax) {\n\t    return t.extend({\n\t      value: t.value.setLineNumber(lineNumber)\n\t    });\n\t  } else if (t instanceof T.RawDelimiter) {\n\t    return t.extend({\n\t      inner: t.inner.map(tt => setLineNumber(tt, lineNumber))\n\t    });\n\t  } else if (_immutable.List.isList(t)) {\n\t    return t.map(tt => setLineNumber(tt, lineNumber));\n\t  }\n\t  // TODO: need to handle line numbers for all AST nodes\n\t  return t;\n\t}\n\n\tfunction cloneLineNumber(to, from) {\n\t  if (from && to) {\n\t    return setLineNumber(to, getLineNumber(from));\n\t  }\n\t  return to;\n\t}\n\n\tconst replace = (acc, s) => {\n\t  let last = acc.template.get(-1);\n\t  let beforeLast = acc.template.get(-2);\n\t  if (isBraces(s) && isDolar(last)) {\n\t    let index = s.inner.get(1).value.val();\n\t    (0, _errors.assert)(acc.rep.size > index, 'unknown replacement value');\n\t    // TODO: figure out holistic solution to line nubmers and ASI\n\t    let replacement = cloneLineNumber(acc.rep.get(index), beforeLast);\n\t    // let replacement = acc.rep.get(index);\n\t    return {\n\t      template: acc.template.pop().concat(replacement),\n\t      rep: acc.rep\n\t    };\n\t  } else if (isDelimiter(s)) {\n\t    let innerResult = replaceTemplate(s.inner.slice(1, s.inner.size - 1), acc.rep);\n\t    return {\n\t      template: acc.template.push(insertIntoDelimiter(s, innerResult)),\n\t      rep: acc.rep\n\t    };\n\t  } else {\n\t    return {\n\t      template: acc.template.push(s),\n\t      rep: acc.rep\n\t    };\n\t  }\n\t};\n\n\tfunction processTemplate(temp, interp = (0, _immutable.List)()) {\n\t  return temp.reduce(process, { template: (0, _immutable.List)(), interp });\n\t}\n\n\tfunction replaceTemplate(temp, rep) {\n\t  return temp.reduce(replace, { template: (0, _immutable.List)(), rep }).template;\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZW1wbGF0ZS1wcm9jZXNzb3IuanMiXSwibmFtZXMiOlsicHJvY2Vzc1RlbXBsYXRlIiwicmVwbGFjZVRlbXBsYXRlIiwiVCIsImlzRG9sYXIiLCJzIiwiUmF3U3ludGF4IiwidmFsdWUiLCJtYXRjaCIsInZhbCIsImlzRGVsaW1pdGVyIiwiUmF3RGVsaW1pdGVyIiwiaXNCcmFjZXMiLCJraW5kIiwiaXNQYXJlbnMiLCJpc0JyYWNrZXRzIiwibWtEZWxpbWl0ZXIiLCJpbm5lciIsImZyb20iLCJvZiIsImZpcnN0IiwiY29uY2F0IiwibGFzdCIsImluc2VydEludG9EZWxpbWl0ZXIiLCJjb25kIiwiciIsInByb2Nlc3MiLCJhY2MiLCJ0ZW1wbGF0ZSIsImlkeCIsImZyb21OdW1iZXIiLCJpbnRlcnAiLCJzaXplIiwicHVzaCIsInNsaWNlIiwiaW5uZXJSZXN1bHQiLCJnZXRMaW5lTnVtYmVyIiwidCIsImxpbmVOdW1iZXIiLCJzZXRMaW5lTnVtYmVyIiwiZXh0ZW5kIiwibWFwIiwidHQiLCJpc0xpc3QiLCJjbG9uZUxpbmVOdW1iZXIiLCJ0byIsInJlcGxhY2UiLCJnZXQiLCJiZWZvcmVMYXN0IiwiaW5kZXgiLCJyZXAiLCJyZXBsYWNlbWVudCIsInBvcCIsInRlbXAiLCJyZWR1Y2UiXSwibWFwcGluZ3MiOiI7Ozs7O1FBMEpnQkEsZSxHQUFBQSxlO1FBT0FDLGUsR0FBQUEsZTs7QUFoS2hCOztBQUNBOzs7O0FBQ0E7O0FBQ0E7O0lBQVlDLEM7O0FBQ1o7Ozs7Ozs7O0FBRUE7Ozs7Ozs7Ozs7Ozs7OztBQWVBLE1BQU1DLFVBQVdDLENBQUQsSUFDZEEsYUFBYUYsRUFBRUcsU0FBZixJQUNBLE9BQU9ELEVBQUVFLEtBQUYsQ0FBUUMsS0FBZixLQUF5QixVQUR6QixJQUVBSCxFQUFFRSxLQUFGLENBQVFDLEtBQVIsQ0FBYyxZQUFkLENBRkEsSUFHQUgsRUFBRUUsS0FBRixDQUFRRSxHQUFSLE9BQWtCLEdBSnBCOztBQUtBLE1BQU1DLGNBQWVM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SixDQUFhSyxJQUFiLENBQWtCNUIsQ0FBbEIsQ0FETDtBQUVMNkMsV0FBS3ZCLElBQUl1QjtBQUZKLEtBQVA7QUFJRDtBQUNGLENBL0JEOztBQWlDTyxTQUFTakQsZUFBVCxDQUNMb0QsSUFESyxFQUVMdEIsU0FBNkIsc0JBRnhCLEVBR0w7QUFDQSxTQUFPc0IsS0FBS0MsTUFBTCxDQUFZNUIsT0FBWixFQUFxQixFQUFFRSxVQUFVLHNCQUFaLEVBQW9CRyxNQUFwQixFQUFyQixDQUFQO0FBQ0Q7O0FBRU0sU0FBUzdCLGVBQVQsQ0FBeUJtRCxJQUF6QixFQUFtREgsR0FBbkQsRUFBNkQ7QUFDbEUsU0FBT0csS0FBS0MsTUFBTCxDQUFZUixPQUFaLEVBQXFCLEVBQUVsQixVQUFVLHNCQUFaLEVBQW9Cc0IsR0FBcEIsRUFBckIsRUFBZ0R0QixRQUF2RDtBQUNEIiwiZmlsZSI6InRlbXBsYXRlLXByb2Nlc3Nvci5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG5pbXBvcnQgeyBMaXN0IH0gZnJvbSAnaW1tdXRhYmxlJztcbmltcG9ydCBfIGZyb20gJ3JhbWRhJztcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJy4vZXJyb3JzJztcbmltcG9ydCAqIGFzIFQgZnJvbSAnc3dlZXQtc3BlYyc7XG5pbXBvcnQgU3ludGF4IGZyb20gJy4vc3ludGF4JztcblxuLypcbkdpdmVuIGEgc3ludGF4IGxpc3QgbGlrZTpcblxuICBbZm9vLCBiYXIsICQsIHsgNDIsICssIDI0IH0sIGJhel1cblxuY29udmVydCBpdCB0bzpcblxuICBbZm9vLCBiYXIsICQsIHsgMCB9LCBiYXpdXG5cbmFuZCByZXR1cm4gYW5vdGhlciBsaXN0IHdpdGggdGhlIGludGVycG9sYXRlZCB2YWx1ZXMgYXQgdGhlIGNvcnJlc3BvbmRpbmdcbnBvc2l0aW9ucy5cblxuUmVxdWlyZXMgZWl0aGVyIGxvb2thaGVhZC9sb29rYmVoaW5kIG9mIG9uZSAodG8gc2VlIHRoZSAkKS5cbiovXG5cbmNvbnN0IGlzRG9sYXIgPSAoczogVC5TeW50YXhUZXJtKSA9PlxuICBzIGluc3RhbmNlb2YgVC5SYXdTeW50YXggJiZcbiAgdHlwZW9mIHMudmFsdWUubWF0Y2ggPT09ICdmdW5jdGlvbicgJiZcbiAgcy52YWx1ZS5tYXRjaCgnaWRlbnRpZmllcicpICYmXG4gIHMudmFsdWUudmFsKCkgPT09ICckJztcbmNvbnN0IGlzRGVsaW1pdGVyID0gKHM6IFQuU3ludGF4VGVybSkgPT4gcyBpbnN0YW5jZW9mIFQuUmF3RGVsaW1pdGVyO1xuY29uc3QgaXNCcmFjZXMgPSAoczogVC5TeW50YXhUZXJtKSA9PlxuICBzIGluc3RhbmNlb2YgVC5SYXdEZWxpbWl0ZXIgJiYgcy5raW5kID09PSAnYnJhY2VzJztcbmNvbnN0IGlzUGFyZW5zID0gKHM6IFQuU3ludGF4VGVybSkgPT5cbiAgcyBpbnN0YW5jZW9mIFQuUmF3RGVsaW1pdGVyICYmIHMua2luZCA9PT0gJ3BhcmVucyc7XG5jb25zdCBpc0JyYWNrZXRzID0gKHM6IFQuU3ludGF4VGVybSkgPT5cbiAgcyBpbnN0YW5jZW9mIFQuUmF3RGVsaW1pdGVyICYmIHMua2luZCA9PT0gJ2JyYWNrZXRzJztcblxudHlwZSBEZWxpbUtpbmQgPSAnYnJhY2VzJyB8ICdwYXJlbnMnIHwgJ2JyYWNrZXRzJztcblxuY29uc3QgbWtEZWxpbWl0ZXIgPSAoXG4gIGtpbmQ6IERlbGltS2luZCxcbiAgaW5uZXI6IExpc3Q8VC5TeW50YXhUZXJtPixcbiAgZnJvbTogVC5SYXdEZWxpbWl0ZXIsXG4pID0+IHtcbiAgcmV0dXJuIG5ldyBULlJhd0RlbGltaXRlcih7XG4gICAga2luZCxcbiAgICBpbm5lcjogTGlzdC5vZihmcm9tLmlubmVyLmZpcnN0KCkpLmNvbmNhdChpbm5lcikuY29uY2F0KGZyb20uaW5uZXIubGFzdCgpKSxcbiAgfSk7XG59O1xuXG5jb25zdCBpbnNlcnRJbnRvRGVsaW1pdGVyID0gXy5jb25kKFtcbiAgW2lzQnJhY2VzLCAocywgcikgPT4gbWtEZWxpbWl0ZXIoJ2JyYWNlcycsIHIsIHMpXSxcbiAgW2lzUGFyZW5zLCAocywgcikgPT4gbWtEZWxpbWl0ZXIoJ3BhcmVucycsIHIsIHMpXSxcbiAgW2lzQnJhY2tldHMsIChzLCByKSA9PiBta0RlbGltaXRlcignYnJhY2tldHMnLCByLCBzKV0sXG5dKTtcblxuY29uc3QgcHJvY2VzcyA9IChcbiAgYWNjOiB7IHRlbXBsYXRlOiBMaXN0PFQuU3ludGF4VGVybT4sIGludGVycDogTGlzdDxMaXN0PFQuU3ludGF4VGVybT4+IH0sXG4gIHM6IFQuU3ludGF4VGVybSxcbikgPT4ge1xuICBpZiAoaXNCcmFjZXMocykgJiYgaXNEb2xhcihhY2MudGVtcGxhdGUubGFzdCgpKSkge1xuICAgIGxldCBpZHggPSBTeW50YXguZnJvbU51bWJlcihhY2MuaW50ZXJwLnNpemUsIHMuaW5uZXIuZmlyc3QoKS52YWx1ZSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRlbXBsYXRlOiBhY2MudGVtcGxhdGUucHVzaChcbiAgICAgICAgbWtEZWxpbWl0ZXIoXG4gICAgICAgICAgJ2JyYWNlcycsXG4gICAgICAgICAgTGlzdC5vZihcbiAgICAgICAgICAgIG5ldyBULlJhd1N5bnRheCh7XG4gICAgICAgICAgICAgIHZhbHVlOiBpZHgsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApLFxuICAgICAgICAgIHMsXG4gICAgICAgICksXG4gICAgICApLFxuICAgICAgaW50ZXJwOiBhY2MuaW50ZXJwLnB1c2gocy5pbm5lci5zbGljZSgxLCBzLmlubmVyLnNpemUgLSAxKSksXG4gICAgfTtcbiAgfSBlbHNlIGlmIChpc0RlbGltaXRlcihzKSkge1xuICAgIGxldCBpbm5lclJlc3VsdCA9IHByb2Nlc3NUZW1wbGF0ZShcbiAgICAgIHMuaW5uZXIuc2xpY2UoMSwgcy5pbm5lci5zaXplIC0gMSksXG4gICAgICBhY2MuaW50ZXJwLFxuICAgICk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRlbXBsYXRlOiBhY2MudGVtcGxhdGUucHVzaChpbnNlcnRJbnRvRGVsaW1pdGVyKHMsIGlubmVyUmVzdWx0LnRlbXBsYXRlKSksXG4gICAgICBpbnRlcnA6IGlubmVyUmVzdWx0LmludGVycCxcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB7XG4gICAgICB0ZW1wbGF0ZTogYWNjLnRlbXBsYXRlLnB1c2gocyksXG4gICAgICBpbnRlcnA6IGFjYy5pbnRlcnAsXG4gICAgfTtcbiAgfVxufTtcblxuZnVuY3Rpb24gZ2V0TGluZU51bWJlcih0OiBULlN5bnRheFRlcm0pIHtcbiAgaWYgKHQgaW5zdGFuY2VvZiBULlJhd1N5bnRheCkge1xuICAgIHJldHVybiB0LnZhbHVlLmxpbmVOdW1iZXIoKTtcbiAgfVxuICByZXR1cm4gdC5pbm5lci5maXJzdCgpLnZhbHVlLmxpbmVOdW1iZXIoKTtcbn1cblxuZnVuY3Rpb24gc2V0TGluZU51bWJlcih0OiBULlRlcm0gfCBMaXN0PFQuVGVybT4sIGxpbmVOdW1iZXI6IG51bWJlcikge1xuICBpZiAodCBpbnN0YW5jZW9mIFQuUmF3U3ludGF4KSB7XG4gICAgcmV0dXJuIHQuZXh0ZW5kKHtcbiAgICAgIHZhbHVlOiB0LnZhbHVlLnNldExpbmVOdW1iZXIobGluZU51bWJlciksXG4gICAgfSk7XG4gIH0gZWxzZSBpZiAodCBpbnN0YW5jZW9mIFQuUmF3RGVsaW1pdGVyKSB7XG4gICAgcmV0dXJuIHQuZXh0ZW5kKHtcbiAgICAgIGlubmVyOiB0LmlubmVyLm1hcCh0dCA9PiBzZXRMaW5lTnVtYmVyKHR0LCBsaW5lTnVtYmVyKSksXG4gICAgfSk7XG4gIH0gZWxzZSBpZiAoTGlzdC5pc0xpc3QodCkpIHtcbiAgICByZXR1cm4gdC5tYXAodHQgPT4gc2V0TGluZU51bWJlcih0dCwgbGluZU51bWJlcikpO1xuICB9XG4gIC8vIFRPRE86IG5lZWQgdG8gaGFuZGxlIGxpbmUgbnVtYmVycyBmb3IgYWxsIEFTVCBub2Rlc1xuICByZXR1cm4gdDtcbn1cblxuZnVuY3Rpb24gY2xvbmVMaW5lTnVtYmVyKHRvOiBULlRlcm0sIGZyb206IFQuU3ludGF4VGVybSkge1xuICBpZiAoZnJvbSAmJiB0bykge1xuICAgIHJldHVybiBzZXRMaW5lTnVtYmVyKHRvLCBnZXRMaW5lTnVtYmVyKGZyb20pKTtcbiAgfVxuICByZXR1cm4gdG87XG59XG5cbmNvbnN0IHJlcGxhY2UgPSAoXG4gIGFjYzogeyB0ZW1wbGF0ZTogTGlzdDxULlN5bnRheFRlcm0+LCByZXA6IExpc3Q8VC5UZXJtIHwgTGlzdDxULlRlcm0+PiB9LFxuICBzOiBULlN5bnRheFRlcm0sXG4pID0+IHtcbiAgbGV0IGxhc3QgPSBhY2MudGVtcGxhdGUuZ2V0KC0xKTtcbiAgbGV0IGJlZm9yZUxhc3QgPSBhY2MudGVtcGxhdGUuZ2V0KC0yKTtcbiAgaWYgKGlzQnJhY2VzKHMpICYmIGlzRG9sYXIobGFzdCkpIHtcbiAgICBsZXQgaW5kZXggPSBzLmlubmVyLmdldCgxKS52YWx1ZS52YWwoKTtcbiAgICBhc3NlcnQoYWNjLnJlcC5zaXplID4gaW5kZXgsICd1bmtub3duIHJlcGxhY2VtZW50IHZhbHVlJyk7XG4gICAgLy8gVE9ETzogZmlndXJlIG91dCBob2xpc3RpYyBzb2x1dGlvbiB0byBsaW5lIG51Ym1lcnMgYW5kIEFTSVxuICAgIGxldCByZXBsYWNlbWVudCA9IGNsb25lTGluZU51bWJlcihhY2MucmVwLmdldChpbmRleCksIGJlZm9yZUxhc3QpO1xuICAgIC8vIGxldCByZXBsYWNlbWVudCA9IGFjYy5yZXAuZ2V0KGluZGV4KTtcbiAgICByZXR1cm4ge1xuICAgICAgdGVtcGxhdGU6IGFjYy50ZW1wbGF0ZS5wb3AoKS5jb25jYXQocmVwbGFjZW1lbnQpLFxuICAgICAgcmVwOiBhY2MucmVwLFxuICAgIH07XG4gIH0gZWxzZSBpZiAoaXNEZWxpbWl0ZXIocykpIHtcbiAgICBsZXQgaW5uZXJSZXN1bHQgPSByZXBsYWNlVGVtcGxhdGUoXG4gICAgICBzLmlubmVyLnNsaWNlKDEsIHMuaW5uZXIuc2l6ZSAtIDEpLFxuICAgICAgYWNjLnJlcCxcbiAgICApO1xuICAgIHJldHVybiB7XG4gICAgICB0ZW1wbGF0ZTogYWNjLnRlbXBsYXRlLnB1c2goaW5zZXJ0SW50b0RlbGltaXRlcihzLCBpbm5lclJlc3VsdCkpLFxuICAgICAgcmVwOiBhY2MucmVwLFxuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRlbXBsYXRlOiBhY2MudGVtcGxhdGUucHVzaChzKSxcbiAgICAgIHJlcDogYWNjLnJlcCxcbiAgICB9O1xuICB9XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gcHJvY2Vzc1RlbXBsYXRlKFxuICB0ZW1wOiBMaXN0PFQuU3ludGF4VGVybT4sXG4gIGludGVycDogTGlzdDxULlN5bnRheFRlcm0+ID0gTGlzdCgpLFxuKSB7XG4gIHJldHVybiB0ZW1wLnJlZHVjZShwcm9jZXNzLCB7IHRlbXBsYXRlOiBMaXN0KCksIGludGVycCB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlcGxhY2VUZW1wbGF0ZSh0ZW1wOiBMaXN0PFQuU3ludGF4VGVybT4sIHJlcDogYW55KSB7XG4gIHJldHVybiB0ZW1wLnJlZHVjZShyZXBsYWNlLCB7IHRlbXBsYXRlOiBMaXN0KCksIHJlcCB9KS50ZW1wbGF0ZTtcbn1cbiJdfQ==\n\n/***/ },\n/* 68 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.wrapInTerms = wrapInTerms;\n\n\tvar _errors = __webpack_require__(59);\n\n\tvar _immutable = __webpack_require__(12);\n\n\tvar _enforester = __webpack_require__(63);\n\n\tvar _syntax = __webpack_require__(58);\n\n\tvar _syntax2 = _interopRequireDefault(_syntax);\n\n\tvar _ramda = __webpack_require__(20);\n\n\tvar _ = _interopRequireWildcard(_ramda);\n\n\tvar _scopeReducer = __webpack_require__(64);\n\n\tvar _scopeReducer2 = _interopRequireDefault(_scopeReducer);\n\n\tvar _sweetSpec = __webpack_require__(43);\n\n\tvar T = _interopRequireWildcard(_sweetSpec);\n\n\tvar S = _interopRequireWildcard(_sweetSpec);\n\n\tvar _tokens = __webpack_require__(19);\n\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tfunction wrapInTerms(stx) {\n\t  return stx.map(s => {\n\t    if ((0, _tokens.isTemplate)(s)) {\n\t      if (s.items) {\n\t        s.items = wrapInTerms(s.items);\n\t        return new T.RawSyntax({\n\t          value: new _syntax2.default(s)\n\t        });\n\t      }\n\t      return new T.RawSyntax({\n\t        value: new _syntax2.default(s)\n\t      });\n\t    } else if ((0, _tokens.isDelimiter)(s)) {\n\t      return new S.RawDelimiter({\n\t        kind: (0, _tokens.getKind)(s),\n\t        inner: wrapInTerms(s)\n\t      });\n\t    }\n\t    return new S.RawSyntax({\n\t      value: new _syntax2.default(s)\n\t    });\n\t  });\n\t}\n\n\tconst privateData = new WeakMap();\n\n\tfunction cloneEnforester(enf) {\n\t  const { rest, prev, context } = enf;\n\t  return new _enforester.Enforester(rest, prev, context);\n\t}\n\n\tfunction Marker() {}\n\n\t/*\n\tctx :: {\n\t  of: (Syntax) -> ctx\n\t  next: (String) -> Syntax or Term\n\t}\n\t*/\n\tclass MacroContext {\n\t  constructor(enf, name, context, useScope, introducedScope) {\n\t    const startMarker = new Marker();\n\t    const startEnf = cloneEnforester(enf);\n\t    const priv = {\n\t      name,\n\t      context,\n\t      enf: startEnf,\n\t      startMarker,\n\t      markers: new Map([[startMarker, enf]])\n\t    };\n\n\t    if (useScope && introducedScope) {\n\t      priv.noScopes = false;\n\t      priv.useScope = useScope;\n\t      priv.introducedScope = introducedScope;\n\t    } else {\n\t      priv.noScopes = true;\n\t    }\n\t    privateData.set(this, priv);\n\t    this.reset(); // set current enforester\n\n\t    this[Symbol.iterator] = () => this;\n\t  }\n\n\t  name() {\n\t    const { name } = privateData.get(this);\n\t    return new T.RawSyntax({ value: name });\n\t  }\n\n\t  contextify(delim) {\n\t    if (!(delim instanceof T.RawDelimiter)) {\n\t      throw new Error(`Can only contextify a delimiter but got ${ delim }`);\n\t    }\n\t    const { context } = privateData.get(this);\n\n\t    let enf = new _enforester.Enforester(delim.inner.slice(1, delim.inner.size - 1), (0, _immutable.List)(), context);\n\t    return new MacroContext(enf, 'inner', context);\n\t  }\n\n\t  expand(type) {\n\t    const { enf } = privateData.get(this);\n\t    if (enf.rest.size === 0) {\n\t      return {\n\t        done: true,\n\t        value: null\n\t      };\n\t    }\n\t    enf.expandMacro();\n\t    let originalRest = enf.rest;\n\t    let value;\n\t    switch (type) {\n\t      case 'AssignmentExpression':\n\t      case 'expr':\n\t        value = enf.enforestExpressionLoop();\n\t        break;\n\t      case 'Expression':\n\t        value = enf.enforestExpression();\n\t        break;\n\t      case 'Statement':\n\t      case 'stmt':\n\t        value = enf.enforestStatement();\n\t        break;\n\t      case 'BlockStatement':\n\t      case 'WhileStatement':\n\t      case 'IfStatement':\n\t      case 'ForStatement':\n\t      case 'SwitchStatement':\n\t      case 'BreakStatement':\n\t      case 'ContinueStatement':\n\t      case 'DebuggerStatement':\n\t      case 'WithStatement':\n\t      case 'TryStatement':\n\t      case 'ThrowStatement':\n\t      case 'ClassDeclaration':\n\t      case 'FunctionDeclaration':\n\t      case 'LabeledStatement':\n\t      case 'VariableDeclarationStatement':\n\t      case 'ReturnStatement':\n\t      case 'ExpressionStatement':\n\t        value = enf.enforestStatement();\n\t        (0, _errors.expect)(_.whereEq({ type }, value), `Expecting a ${ type }`, value, originalRest);\n\t        break;\n\t      case 'YieldExpression':\n\t        value = enf.enforestYieldExpression();\n\t        break;\n\t      case 'ClassExpression':\n\t        value = enf.enforestClass({ isExpr: true });\n\t        break;\n\t      case 'ArrowExpression':\n\t        value = enf.enforestArrowExpression();\n\t        break;\n\t      case 'NewExpression':\n\t        value = enf.enforestNewExpression();\n\t        break;\n\t      case 'ThisExpression':\n\t      case 'FunctionExpression':\n\t      case 'IdentifierExpression':\n\t      case 'LiteralNumericExpression':\n\t      case 'LiteralInfinityExpression':\n\t      case 'LiteralStringExpression':\n\t      case 'TemplateExpression':\n\t      case 'LiteralBooleanExpression':\n\t      case 'LiteralNullExpression':\n\t      case 'LiteralRegExpExpression':\n\t      case 'ObjectExpression':\n\t      case 'ArrayExpression':\n\t        value = enf.enforestPrimaryExpression();\n\t        break;\n\t      case 'UnaryExpression':\n\t      case 'UpdateExpression':\n\t      case 'BinaryExpression':\n\t      case 'StaticMemberExpression':\n\t      case 'ComputedMemberExpression':\n\t      case 'CompoundAssignmentExpression':\n\t      case 'ConditionalExpression':\n\t        value = enf.enforestExpressionLoop();\n\t        (0, _errors.expect)(_.whereEq({ type }, value), `Expecting a ${ type }`, value, originalRest);\n\t        break;\n\t      default:\n\t        throw new Error('Unknown term type: ' + type);\n\t    }\n\t    return {\n\t      done: false,\n\t      value: value\n\t    };\n\t  }\n\n\t  _rest(enf) {\n\t    const priv = privateData.get(this);\n\t    if (priv.markers.get(priv.startMarker) === enf) {\n\t      return priv.enf.rest;\n\t    }\n\t    throw Error('Unauthorized access!');\n\t  }\n\n\t  reset(marker) {\n\t    const priv = privateData.get(this);\n\t    let enf;\n\t    if (marker == null) {\n\t      // go to the beginning\n\t      enf = priv.markers.get(priv.startMarker);\n\t    } else if (marker && marker instanceof Marker) {\n\t      // marker could be from another context\n\t      if (priv.markers.has(marker)) {\n\t        enf = priv.markers.get(marker);\n\t      } else {\n\t        throw new Error('marker must originate from this context');\n\t      }\n\t    } else {\n\t      throw new Error('marker must be an instance of Marker');\n\t    }\n\t    priv.enf = cloneEnforester(enf);\n\t  }\n\n\t  mark() {\n\t    const priv = privateData.get(this);\n\t    let marker;\n\n\t    // the idea here is that marking at the beginning shouldn't happen more than once.\n\t    // We can reuse startMarker.\n\t    if (priv.enf.rest === priv.markers.get(priv.startMarker).rest) {\n\t      marker = priv.startMarker;\n\t    } else if (priv.enf.rest.isEmpty()) {\n\t      // same reason as above\n\t      if (!priv.endMarker) priv.endMarker = new Marker();\n\t      marker = priv.endMarker;\n\t    } else {\n\t      //TODO(optimization/dubious): check that there isn't already a marker for this index?\n\t      marker = new Marker();\n\t    }\n\t    if (!priv.markers.has(marker)) {\n\t      priv.markers.set(marker, cloneEnforester(priv.enf));\n\t    }\n\t    return marker;\n\t  }\n\n\t  next() {\n\t    const {\n\t      enf,\n\t      noScopes,\n\t      useScope,\n\t      introducedScope,\n\t      context\n\t    } = privateData.get(this);\n\t    if (enf.rest.size === 0) {\n\t      return {\n\t        done: true,\n\t        value: null\n\t      };\n\t    }\n\t    let value = enf.advance();\n\t    if (!noScopes) {\n\t      value = value.reduce(new _scopeReducer2.default([{ scope: useScope, phase: _syntax.ALL_PHASES, flip: false }, { scope: introducedScope, phase: _syntax.ALL_PHASES, flip: true }], context.bindings));\n\t    }\n\t    return {\n\t      done: false,\n\t      value: value\n\t    };\n\t  }\n\t}\n\texports.default = MacroContext;\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tYWNyby1jb250ZXh0LmpzIl0sIm5hbWVzIjpbIndyYXBJblRlcm1zIiwiXyIsIlQiLCJTIiwic3R4IiwibWFwIiwicyIsIml0ZW1zIiwiUmF3U3ludGF4IiwidmFsdWUiLCJSYXdEZWxpbWl0ZXIiLCJraW5kIiwiaW5uZXIiLCJwcml2YXRlRGF0YSIsIldlYWtNYXAiLCJjbG9uZUVuZm9yZXN0ZXIiLCJlbmYiLCJyZXN0IiwicHJldiIsImNvbnRleHQiLCJNYXJrZXIiLCJNYWNyb0NvbnRleHQiLCJjb25zdHJ1Y3RvciIsIm5hbWUiLCJ1c2VTY29wZSIsImludHJvZHVjZWRTY29wZSIsInN0YXJ0TWFya2VyIiwic3RhcnRFbmYiLCJwcml2IiwibWFya2VycyIsIk1hcCIsIm5vU2NvcGVzIiwic2V0IiwicmVzZXQiLCJTeW1ib2wiLCJpdGVyYXRvciIsImdldCIsImNvbnRleHRpZnkiLCJkZWxpbSIsIkVycm9yIiwic2xpY2UiLCJzaXplIiwiZXhwYW5kIiwidHlwZSIsImRvbmUiLCJleHBhbmRNYWNybyIsIm9yaWdpbmFsUmVzdCIsImVuZm9yZXN0RXhwcmVzc2lvbkxvb3AiLCJlbmZvcmVzdEV4cHJlc3Npb24iLCJlbmZvcmVzdFN0YXRlbWVudCIsIndoZXJlRXEiLCJlbmZvcmVzdFlpZWxkRXhwcmVzc2lvbiIsImVuZm9yZXN0Q2xhc3MiLCJpc0V4cHIiLCJlbmZvcmVzdEFycm93RXhwcmVzc2lvbiIsImVuZm9yZXN0TmV3RXhwcmVzc2lvbiIsImVuZm9yZXN0UHJpbWFyeUV4cHJlc3Npb24iLCJfcmVzdCIsIm1hcmtlciIsImhhcyIsIm1hcmsiLCJpc0VtcHR5IiwiZW5kTWFya2VyIiwibmV4dCIsImFkdmFuY2UiLCJyZWR1Y2UiLCJzY29wZSIsInBoYXNlIiwiZmxpcCIsImJpbmRpbmdzIl0sIm1hcHBpbmdzIjoiOzs7OztRQVlnQkEsVyxHQUFBQSxXOztBQVpoQjs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUNBOztJQUFZQyxDOztB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LEVBRUUsRUFBRUYsT0FBT3pDLGVBQVQsRUFBMEIwQyx5QkFBMUIsRUFBNkNDLE1BQU0sSUFBbkQsRUFGRixDQURGLEVBS0VqRCxRQUFRa0QsUUFMVixDQURNLENBQVI7QUFTRDtBQUNELFdBQU87QUFDTHpCLFlBQU0sS0FERDtBQUVMbkMsYUFBT0E7QUFGRixLQUFQO0FBSUQ7QUE3TitCO2tCQUFiWSxZIiwiZmlsZSI6Im1hY3JvLWNvbnRleHQuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBleHBlY3QgfSBmcm9tICcuL2Vycm9ycyc7XG5pbXBvcnQgeyBMaXN0IH0gZnJvbSAnaW1tdXRhYmxlJztcbmltcG9ydCB7IEVuZm9yZXN0ZXIgfSBmcm9tICcuL2VuZm9yZXN0ZXInO1xuaW1wb3J0IHsgQUxMX1BIQVNFUyB9IGZyb20gJy4vc3ludGF4JztcbmltcG9ydCAqIGFzIF8gZnJvbSAncmFtZGEnO1xuaW1wb3J0IFNjb3BlUmVkdWNlciBmcm9tICcuL3Njb3BlLXJlZHVjZXInO1xuaW1wb3J0ICogYXMgVCBmcm9tICdzd2VldC1zcGVjJztcbmltcG9ydCBUZXJtLCAqIGFzIFMgZnJvbSAnc3dlZXQtc3BlYyc7XG5pbXBvcnQgU3ludGF4IGZyb20gJy4vc3ludGF4JztcbmltcG9ydCB7IGlzVGVtcGxhdGUsIGlzRGVsaW1pdGVyLCBnZXRLaW5kIH0gZnJvbSAnLi90b2tlbnMnO1xuaW1wb3J0IHR5cGUgeyBUb2tlblRyZWUgfSBmcm9tICcuL3Rva2Vucyc7XG5cbmV4cG9ydCBmdW5jdGlvbiB3cmFwSW5UZXJtcyhzdHg6IExpc3Q8VG9rZW5UcmVlPik6IExpc3Q8VGVybT4ge1xuICByZXR1cm4gc3R4Lm1hcChzID0+IHtcbiAgICBpZiAoaXNUZW1wbGF0ZShzKSkge1xuICAgICAgaWYgKHMuaXRlbXMpIHtcbiAgICAgICAgcy5pdGVtcyA9IHdyYXBJblRlcm1zKHMuaXRlbXMpO1xuICAgICAgICByZXR1cm4gbmV3IFQuUmF3U3ludGF4KHtcbiAgICAgICAgICB2YWx1ZTogbmV3IFN5bnRheChzKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV3IFQuUmF3U3ludGF4KHtcbiAgICAgICAgdmFsdWU6IG5ldyBTeW50YXgocyksXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKGlzRGVsaW1pdGVyKHMpKSB7XG4gICAgICByZXR1cm4gbmV3IFMuUmF3RGVsaW1pdGVyKHtcbiAgICAgICAga2luZDogZ2V0S2luZChzKSxcbiAgICAgICAgaW5uZXI6IHdyYXBJblRlcm1zKHMpLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgUy5SYXdTeW50YXgoe1xuICAgICAgdmFsdWU6IG5ldyBTeW50YXgocyksXG4gICAgfSk7XG4gIH0pO1xufVxuXG5jb25zdCBwcml2YXRlRGF0YSA9IG5ldyBXZWFrTWFwKCk7XG5cbmZ1bmN0aW9uIGNsb25lRW5mb3Jlc3RlcihlbmYpIHtcbiAgY29uc3QgeyByZXN0LCBwcmV2LCBjb250ZXh0IH0gPSBlbmY7XG4gIHJldHVybiBuZXcgRW5mb3Jlc3RlcihyZXN0LCBwcmV2LCBjb250ZXh0KTtcbn1cblxuZnVuY3Rpb24gTWFya2VyKCkge31cblxuLypcbmN0eCA6OiB7XG4gIG9mOiAoU3ludGF4KSAtPiBjdHhcbiAgbmV4dDogKFN0cmluZykgLT4gU3ludGF4IG9yIFRlcm1cbn1cbiovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNYWNyb0NvbnRleHQge1xuICBjb25zdHJ1Y3RvcihlbmYsIG5hbWUsIGNvbnRleHQsIHVzZVNjb3BlLCBpbnRyb2R1Y2VkU2NvcGUpIHtcbiAgICBjb25zdCBzdGFydE1hcmtlciA9IG5ldyBNYXJrZXIoKTtcbiAgICBjb25zdCBzdGFydEVuZiA9IGNsb25lRW5mb3Jlc3RlcihlbmYpO1xuICAgIGNvbnN0IHByaXYgPSB7XG4gICAgICBuYW1lLFxuICAgICAgY29udGV4dCxcbiAgICAgIGVuZjogc3RhcnRFbmYsXG4gICAgICBzdGFydE1hcmtlcixcbiAgICAgIG1hcmtlcnM6IG5ldyBNYXAoW1tzdGFydE1hcmtlciwgZW5mXV0pLFxuICAgIH07XG5cbiAgICBpZiAodXNlU2NvcGUgJiYgaW50cm9kdWNlZFNjb3BlKSB7XG4gICAgICBwcml2Lm5vU2NvcGVzID0gZmFsc2U7XG4gICAgICBwcml2LnVzZVNjb3BlID0gdXNlU2NvcGU7XG4gICAgICBwcml2LmludHJvZHVjZWRTY29wZSA9IGludHJvZHVjZWRTY29wZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJpdi5ub1Njb3BlcyA9IHRydWU7XG4gICAgfVxuICAgIHByaXZhdGVEYXRhLnNldCh0aGlzLCBwcml2KTtcbiAgICB0aGlzLnJlc2V0KCk7IC8vIHNldCBjdXJyZW50IGVuZm9yZXN0ZXJcblxuICAgIHRoaXNbU3ltYm9sLml0ZXJhdG9yXSA9ICgpID0+IHRoaXM7XG4gIH1cblxuICBuYW1lKCkge1xuICAgIGNvbnN0IHsgbmFtZSB9ID0gcHJpdmF0ZURhdGEuZ2V0KHRoaXMpO1xuICAgIHJldHVybiBuZXcgVC5SYXdTeW50YXgoeyB2YWx1ZTogbmFtZSB9KTtcbiAgfVxuXG4gIGNvbnRleHRpZnkoZGVsaW06IGFueSkge1xuICAgIGlmICghKGRlbGltIGluc3RhbmNlb2YgVC5SYXdEZWxpbWl0ZXIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbiBvbmx5IGNvbnRleHRpZnkgYSBkZWxpbWl0ZXIgYnV0IGdvdCAke2RlbGltfWApO1xuICAgIH1cbiAgICBjb25zdCB7IGNvbnRleHQgfSA9IHByaXZhdGVEYXRhLmdldCh0aGlzKTtcblxuICAgIGxldCBlbmYgPSBuZXcgRW5mb3Jlc3RlcihcbiAgICAgIGRlbGltLmlubmVyLnNsaWNlKDEsIGRlbGltLmlubmVyLnNpemUgLSAxKSxcbiAgICAgIExpc3QoKSxcbiAgICAgIGNvbnRleHQsXG4gICAgKTtcbiAgICByZXR1cm4gbmV3IE1hY3JvQ29udGV4dChlbmYsICdpbm5lcicsIGNvbnRleHQpO1xuICB9XG5cbiAgZXhwYW5kKHR5cGUpIHtcbiAgICBjb25zdCB7IGVuZiB9ID0gcHJpdmF0ZURhdGEuZ2V0KHRoaXMpO1xuICAgIGlmIChlbmYucmVzdC5zaXplID09PSAwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBkb25lOiB0cnVlLFxuICAgICAgICB2YWx1ZTogbnVsbCxcbiAgICAgIH07XG4gICAgfVxuICAgIGVuZi5leHBhbmRNYWNybygpO1xuICAgIGxldCBvcmlnaW5hbFJlc3QgPSBlbmYucmVzdDtcbiAgICBsZXQgdmFsdWU7XG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlICdBc3NpZ25tZW50RXhwcmVzc2lvbic6XG4gICAgICBjYXNlICdleHByJzpcbiAgICAgICAgdmFsdWUgPSBlbmYuZW5mb3Jlc3RFeHByZXNzaW9uTG9vcCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0V4cHJlc3Npb24nOlxuICAgICAgICB2YWx1ZSA9IGVuZi5lbmZvcmVzdEV4cHJlc3Npb24oKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdTdGF0ZW1lbnQnOlxuICAgICAgY2FzZSAnc3RtdCc6XG4gICAgICAgIHZhbHVlID0gZW5mLmVuZm9yZXN0U3RhdGVtZW50KCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnQmxvY2tTdGF0ZW1lbnQnOlxuICAgICAgY2FzZSAnV2hpbGVTdGF0ZW1lbnQnOlxuICAgICAgY2FzZSAnSWZTdGF0ZW1lbnQnOlxuICAgICAgY2FzZSAnRm9yU3RhdGVtZW50JzpcbiAgICAgIGNhc2UgJ1N3aXRjaFN0YXRlbWVudCc6XG4gICAgICBjYXNlICdCcmVha1N0YXRlbWVudCc6XG4gICAgICBjYXNlICdDb250aW51ZVN0YXRlbWVudCc6XG4gICAgICBjYXNlICdEZWJ1Z2dlclN0YXRlbWVudCc6XG4gICAgICBjYXNlICdXaXRoU3RhdGVtZW50JzpcbiAgICAgIGNhc2UgJ1RyeVN0YXRlbWVudCc6XG4gICAgICBjYXNlICdUaHJvd1N0YXRlbWVudCc6XG4gICAgICBjYXNlICdDbGFzc0RlY2xhcmF0aW9uJzpcbiAgICAgIGNhc2UgJ0Z1bmN0aW9uRGVjbGFyYXRpb24nOlxuICAgICAgY2FzZSAnTGFiZWxlZFN0YXRlbWVudCc6XG4gICAgICBjYXNlICdWYXJpYWJsZURlY2xhcmF0aW9uU3RhdGVtZW50JzpcbiAgICAgIGNhc2UgJ1JldHVyblN0YXRlbWVudCc6XG4gICAgICBjYXNlICdFeHByZXNzaW9uU3RhdGVtZW50JzpcbiAgICAgICAgdmFsdWUgPSBlbmYuZW5mb3Jlc3RTdGF0ZW1lbnQoKTtcbiAgICAgICAgZXhwZWN0KFxuICAgICAgICAgIF8ud2hlcmVFcSh7IHR5cGUgfSwgdmFsdWUpLFxuICAgICAgICAgIGBFeHBlY3RpbmcgYSAke3R5cGV9YCxcbiAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICBvcmlnaW5hbFJlc3QsXG4gICAgICAgICk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnWWllbGRFeHByZXNzaW9uJzpcbiAgICAgICAgdmFsdWUgPSBlbmYuZW5mb3Jlc3RZaWVsZEV4cHJlc3Npb24oKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdDbGFzc0V4cHJlc3Npb24nOlxuICAgICAgICB2YWx1ZSA9IGVuZi5lbmZvcmVzdENsYXNzKHsgaXNFeHByOiB0cnVlIH0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0Fycm93RXhwcmVzc2lvbic6XG4gICAgICAgIHZhbHVlID0gZW5mLmVuZm9yZXN0QXJyb3dFeHByZXNzaW9uKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnTmV3RXhwcmVzc2lvbic6XG4gICAgICAgIHZhbHVlID0gZW5mLmVuZm9yZXN0TmV3RXhwcmVzc2lvbigpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ1RoaXNFeHByZXNzaW9uJzpcbiAgICAgIGNhc2UgJ0Z1bmN0aW9uRXhwcmVzc2lvbic6XG4gICAgICBjYXNlICdJZGVudGlmaWVyRXhwcmVzc2lvbic6XG4gICAgICBjYXNlICdMaXRlcmFsTnVtZXJpY0V4cHJlc3Npb24nOlxuICAgICAgY2FzZSAnTGl0ZXJhbEluZmluaXR5RXhwcmVzc2lvbic6XG4gICAgICBjYXNlICdMaXRlcmFsU3RyaW5nRXhwcmVzc2lvbic6XG4gICAgICBjYXNlICdUZW1wbGF0ZUV4cHJlc3Npb24nOlxuICAgICAgY2FzZSAnTGl0ZXJhbEJvb2xlYW5FeHByZXNzaW9uJzpcbiAgICAgIGNhc2UgJ0xpdGVyYWxOdWxsRXhwcmVzc2lvbic6XG4gICAgICBjYXNlICdMaXRlcmFsUmVnRXhwRXhwcmVzc2lvbic6XG4gICAgICBjYXNlICdPYmplY3RFeHByZXNzaW9uJzpcbiAgICAgIGNhc2UgJ0FycmF5RXhwcmVzc2lvbic6XG4gICAgICAgIHZhbHVlID0gZW5mLmVuZm9yZXN0UHJpbWFyeUV4cHJlc3Npb24oKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdVbmFyeUV4cHJlc3Npb24nOlxuICAgICAgY2FzZSAnVXBkYXRlRXhwcmVzc2lvbic6XG4gICAgICBjYXNlICdCaW5hcnlFeHByZXNzaW9uJzpcbiAgICAgIGNhc2UgJ1N0YXRpY01lbWJlckV4cHJlc3Npb24nOlxuICAgICAgY2FzZSAnQ29tcHV0ZWRNZW1iZXJFeHByZXNzaW9uJzpcbiAgICAgIGNhc2UgJ0NvbXBvdW5kQXNzaWdubWVudEV4cHJlc3Npb24nOlxuICAgICAgY2FzZSAnQ29uZGl0aW9uYWxFeHByZXNzaW9uJzpcbiAgICAgICAgdmFsdWUgPSBlbmYuZW5mb3Jlc3RFeHByZXNzaW9uTG9vcCgpO1xuICAgICAgICBleHBlY3QoXG4gICAgICAgICAgXy53aGVyZUVxKHsgdHlwZSB9LCB2YWx1ZSksXG4gICAgICAgICAgYEV4cGVjdGluZyBhICR7dHlwZX1gLFxuICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgIG9yaWdpbmFsUmVzdCxcbiAgICAgICAgKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gdGVybSB0eXBlOiAnICsgdHlwZSk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBkb25lOiBmYWxzZSxcbiAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICB9O1xuICB9XG5cbiAgX3Jlc3QoZW5mKSB7XG4gICAgY29uc3QgcHJpdiA9IHByaXZhdGVEYXRhLmdldCh0aGlzKTtcbiAgICBpZiAocHJpdi5tYXJrZXJzLmdldChwcml2LnN0YXJ0TWFya2VyKSA9PT0gZW5mKSB7XG4gICAgICByZXR1cm4gcHJpdi5lbmYucmVzdDtcbiAgICB9XG4gICAgdGhyb3cgRXJyb3IoJ1VuYXV0aG9yaXplZCBhY2Nlc3MhJyk7XG4gIH1cblxuICByZXNldChtYXJrZXIpIHtcbiAgICBjb25zdCBwcml2ID0gcHJpdmF0ZURhdGEuZ2V0KHRoaXMpO1xuICAgIGxldCBlbmY7XG4gICAgaWYgKG1hcmtlciA9PSBudWxsKSB7XG4gICAgICAvLyBnbyB0byB0aGUgYmVnaW5uaW5nXG4gICAgICBlbmYgPSBwcml2Lm1hcmtlcnMuZ2V0KHByaXYuc3RhcnRNYXJrZXIpO1xuICAgIH0gZWxzZSBpZiAobWFya2VyICYmIG1hcmtlciBpbnN0YW5jZW9mIE1hcmtlcikge1xuICAgICAgLy8gbWFya2VyIGNvdWxkIGJlIGZyb20gYW5vdGhlciBjb250ZXh0XG4gICAgICBpZiAocHJpdi5tYXJrZXJzLmhhcyhtYXJrZXIpKSB7XG4gICAgICAgIGVuZiA9IHByaXYubWFya2Vycy5nZXQobWFya2VyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbWFya2VyIG11c3Qgb3JpZ2luYXRlIGZyb20gdGhpcyBjb250ZXh0Jyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWFya2VyIG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgTWFya2VyJyk7XG4gICAgfVxuICAgIHByaXYuZW5mID0gY2xvbmVFbmZvcmVzdGVyKGVuZik7XG4gIH1cblxuICBtYXJrKCkge1xuICAgIGNvbnN0IHByaXYgPSBwcml2YXRlRGF0YS5nZXQodGhpcyk7XG4gICAgbGV0IG1hcmtlcjtcblxuICAgIC8vIHRoZSBpZGVhIGhlcmUgaXMgdGhhdCBtYXJraW5nIGF0IHRoZSBiZWdpbm5pbmcgc2hvdWxkbid0IGhhcHBlbiBtb3JlIHRoYW4gb25jZS5cbiAgICAvLyBXZSBjYW4gcmV1c2Ugc3RhcnRNYXJrZXIuXG4gICAgaWYgKHByaXYuZW5mLnJlc3QgPT09IHByaXYubWFya2Vycy5nZXQocHJpdi5zdGFydE1hcmtlcikucmVzdCkge1xuICAgICAgbWFya2VyID0gcHJpdi5zdGFydE1hcmtlcjtcbiAgICB9IGVsc2UgaWYgKHByaXYuZW5mLnJlc3QuaXNFbXB0eSgpKSB7XG4gICAgICAvLyBzYW1lIHJlYXNvbiBhcyBhYm92ZVxuICAgICAgaWYgKCFwcml2LmVuZE1hcmtlcikgcHJpdi5lbmRNYXJrZXIgPSBuZXcgTWFya2VyKCk7XG4gICAgICBtYXJrZXIgPSBwcml2LmVuZE1hcmtlcjtcbiAgICB9IGVsc2Uge1xuICAgICAgLy9UT0RPKG9wdGltaXphdGlvbi9kdWJpb3VzKTogY2hlY2sgdGhhdCB0aGVyZSBpc24ndCBhbHJlYWR5IGEgbWFya2VyIGZvciB0aGlzIGluZGV4P1xuICAgICAgbWFya2VyID0gbmV3IE1hcmtlcigpO1xuICAgIH1cbiAgICBpZiAoIXByaXYubWFya2Vycy5oYXMobWFya2VyKSkge1xuICAgICAgcHJpdi5tYXJrZXJzLnNldChtYXJrZXIsIGNsb25lRW5mb3Jlc3Rlcihwcml2LmVuZikpO1xuICAgIH1cbiAgICByZXR1cm4gbWFya2VyO1xuICB9XG5cbiAgbmV4dCgpIHtcbiAgICBjb25zdCB7XG4gICAgICBlbmYsXG4gICAgICBub1Njb3BlcyxcbiAgICAgIHVzZVNjb3BlLFxuICAgICAgaW50cm9kdWNlZFNjb3BlLFxuICAgICAgY29udGV4dCxcbiAgICB9ID0gcHJpdmF0ZURhdGEuZ2V0KHRoaXMpO1xuICAgIGlmIChlbmYucmVzdC5zaXplID09PSAwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBkb25lOiB0cnVlLFxuICAgICAgICB2YWx1ZTogbnVsbCxcbiAgICAgIH07XG4gICAgfVxuICAgIGxldCB2YWx1ZSA9IGVuZi5hZHZhbmNlKCk7XG4gICAgaWYgKCFub1Njb3Blcykge1xuICAgICAgdmFsdWUgPSB2YWx1ZS5yZWR1Y2UoXG4gICAgICAgIG5ldyBTY29wZVJlZHVjZXIoXG4gICAgICAgICAgW1xuICAgICAgICAgICAgeyBzY29wZTogdXNlU2NvcGUsIHBoYXNlOiBBTExfUEhBU0VTLCBmbGlwOiBmYWxzZSB9LFxuICAgICAgICAgICAgeyBzY29wZTogaW50cm9kdWNlZFNjb3BlLCBwaGFzZTogQUxMX1BIQVNFUywgZmxpcDogdHJ1ZSB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgY29udGV4dC5iaW5kaW5ncyxcbiAgICAgICAgKSxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBkb25lOiBmYWxzZSxcbiAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICB9O1xuICB9XG59XG4iXX0=\n\n/***/ },\n/* 69 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\tclass ASTDispatcher {\n\t  constructor(prefix, errorIfMissing) {\n\t    this.errorIfMissing = errorIfMissing;\n\t    this.prefix = prefix;\n\t  }\n\n\t  dispatch(term) {\n\t    let field = this.prefix + term.type;\n\t    if (typeof this[field] === 'function') {\n\t      return this[field](term);\n\t    } else if (!this.errorIfMissing) {\n\t      return term;\n\t    }\n\t    throw new Error(`Missing implementation for: ${ field }`);\n\t  }\n\t}\n\texports.default = ASTDispatcher;\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hc3QtZGlzcGF0Y2hlci5qcyJdLCJuYW1lcyI6WyJBU1REaXNwYXRjaGVyIiwiY29uc3RydWN0b3IiLCJwcmVmaXgiLCJlcnJvcklmTWlzc2luZyIsImRpc3BhdGNoIiwidGVybSIsImZpZWxkIiwidHlwZSIsIkVycm9yIl0sIm1hcHBpbmdzIjoiOzs7OztBQUFlLE1BQU1BLGFBQU4sQ0FBb0I7QUFDakNDLGNBQVlDLE1BQVosRUFBb0JDLGNBQXBCLEVBQW9DO0FBQ2xDLFNBQUtBLGNBQUwsR0FBc0JBLGNBQXRCO0FBQ0EsU0FBS0QsTUFBTCxHQUFjQSxNQUFkO0FBQ0Q7O0FBRURFLFdBQVNDLElBQVQsRUFBZTtBQUNiLFFBQUlDLFFBQVEsS0FBS0osTUFBTCxHQUFjRyxLQUFLRSxJQUEvQjtBQUNBLFFBQUksT0FBTyxLQUFLRCxLQUFMLENBQVAsS0FBdUIsVUFBM0IsRUFBdUM7QUFDckMsYUFBTyxLQUFLQSxLQUFMLEVBQVlELElBQVosQ0FBUDtBQUNELEtBRkQsTUFFTyxJQUFJLENBQUMsS0FBS0YsY0FBVixFQUEwQjtBQUMvQixhQUFPRSxJQUFQO0FBQ0Q7QUFDRCxVQUFNLElBQUlHLEtBQUosQ0FBVyxnQ0FBOEJGLEtBQU0sR0FBL0MsQ0FBTjtBQUNEO0FBZGdDO2tCQUFkTixhIiwiZmlsZSI6ImFzdC1kaXNwYXRjaGVyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGRlZmF1bHQgY2xhc3MgQVNURGlzcGF0Y2hlciB7XG4gIGNvbnN0cnVjdG9yKHByZWZpeCwgZXJyb3JJZk1pc3NpbmcpIHtcbiAgICB0aGlzLmVycm9ySWZNaXNzaW5nID0gZXJyb3JJZk1pc3Npbmc7XG4gICAgdGhpcy5wcmVmaXggPSBwcmVmaXg7XG4gIH1cblxuICBkaXNwYXRjaCh0ZXJtKSB7XG4gICAgbGV0IGZpZWxkID0gdGhpcy5wcmVmaXggKyB0ZXJtLnR5cGU7XG4gICAgaWYgKHR5cGVvZiB0aGlzW2ZpZWxkXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIHRoaXNbZmllbGRdKHRlcm0pO1xuICAgIH0gZWxzZSBpZiAoIXRoaXMuZXJyb3JJZk1pc3NpbmcpIHtcbiAgICAgIHJldHVybiB0ZXJtO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoYE1pc3NpbmcgaW1wbGVtZW50YXRpb24gZm9yOiAke2ZpZWxkfWApO1xuICB9XG59XG4iXX0=\n\n/***/ },\n/* 70 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\n\tvar _sweetSpec = __webpack_require__(43);\n\n\tvar S = _interopRequireWildcard(_sweetSpec);\n\n\tvar _immutable = __webpack_require__(12);\n\n\tvar _enforester = __webpack_require__(63);\n\n\tvar _termExpander = __webpack_require__(62);\n\n\tvar _termExpander2 = _interopRequireDefault(_termExpander);\n\n\tvar _env = __webpack_require__(40);\n\n\tvar _env2 = _interopRequireDefault(_env);\n\n\tvar _ramda = __webpack_require__(20);\n\n\tvar _ = _interopRequireWildcard(_ramda);\n\n\tvar _terms = __webpack_require__(57);\n\n\tvar T = _interopRequireWildcard(_terms);\n\n\tvar _symbol = __webpack_require__(39);\n\n\tvar _transforms = __webpack_require__(41);\n\n\tvar _loadSyntax = __webpack_require__(66);\n\n\tvar _scope = __webpack_require__(38);\n\n\tvar _syntax = __webpack_require__(58);\n\n\tvar _astDispatcher = __webpack_require__(69);\n\n\tvar _astDispatcher2 = _interopRequireDefault(_astDispatcher);\n\n\tvar _syntax2 = __webpack_require__(58);\n\n\tvar _syntax3 = _interopRequireDefault(_syntax2);\n\n\tvar _scopeReducer = __webpack_require__(64);\n\n\tvar _scopeReducer2 = _interopRequireDefault(_scopeReducer);\n\n\tvar _moduleVisitor = __webpack_require__(71);\n\n\tvar _moduleVisitor2 = _interopRequireDefault(_moduleVisitor);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\n\tclass RegisterBindingsReducer extends S.default.CloneReducer {\n\n\t  constructor(useScope, phase, skipDup, bindings, env) {\n\t    super();\n\t    this.useScope = useScope;\n\t    this.phase = phase;\n\t    this.bindings = bindings;\n\t    this.skipDup = skipDup;\n\t    this.env = env;\n\t  }\n\n\t  reduceBindingIdentifier(t, s) {\n\t    let newName = s.name.removeScope(this.useScope, this.phase);\n\t    let newBinding = (0, _symbol.gensym)(newName.val());\n\t    this.bindings.add(newName, {\n\t      binding: newBinding,\n\t      phase: this.phase,\n\t      skipDup: this.skipDup\n\t    });\n\t    this.env.set(newBinding.toString(), new _transforms.VarBindingTransform(newName));\n\t    return t.extend({\n\t      name: newName\n\t    });\n\t  }\n\t}\n\n\tclass RegisterSyntaxBindingsReducer extends S.default.CloneReducer {\n\n\t  constructor(useScope, phase, bindings, env, val) {\n\t    super();\n\t    this.useScope = useScope;\n\t    this.phase = phase;\n\t    this.bindings = bindings;\n\t    this.env = env;\n\t    this.val = val;\n\t  }\n\n\t  reduceBindingIdentifier(t, s) {\n\t    let newName = s.name.removeScope(this.useScope, this.phase);\n\t    let newBinding = (0, _symbol.gensym)(newName.val());\n\t    this.bindings.add(newName, {\n\t      binding: newBinding,\n\t      phase: this.phase,\n\t      skipDup: false\n\t    });\n\t    let resolvedName = newName.resolve(this.phase);\n\t    this.env.set(resolvedName, new _transforms.CompiletimeTransform(this.val));\n\t    return t.extend({\n\t      name: newName\n\t    });\n\t  }\n\t}\n\n\tclass TokenExpander extends _astDispatcher2.default {\n\t  constructor(context) {\n\t    super('expand', false);\n\t    this.context = context;\n\t  }\n\n\t  expand(stxl) {\n\t    let result = [];\n\t    if (stxl.size === 0) {\n\t      return (0, _immutable.List)(result);\n\t    }\n\t    let prev = (0, _immutable.List)();\n\t    let enf = new _enforester.Enforester(stxl, prev, this.context);\n\n\t    while (!enf.done) {\n\t      result.push(this.dispatch(enf.enforest()));\n\t    }\n\n\t    return (0, _immutable.List)(result);\n\t  }\n\n\t  expandVariableDeclarationStatement(term) {\n\t    return term.extend({\n\t      declaration: this.registerVariableDeclaration(term.declaration)\n\t    });\n\t  }\n\n\t  expandFunctionDeclaration(term) {\n\t    return this.registerFunctionOrClass(term);\n\t  }\n\n\t  // TODO: think about function expressions\n\n\t  registerImport(term) {\n\t    let path = term.moduleSpecifier.val();\n\t    let mod;\n\t    let visitor = new _moduleVisitor2.default(this.context);\n\t    if (term.forSyntax) {\n\t      mod = this.context.loader.get(path, this.context.phase + 1, this.context.cwd);\n\t      this.context.store = visitor.visit(mod, this.context.phase + 1, this.context.store);\n\t      this.context.store = visitor.invoke(mod, this.context.phase + 1, this.context.store);\n\t    } else {\n\t      mod = this.context.loader.get(path, this.context.phase, this.context.cwd);\n\t      this.context.store = visitor.visit(mod, this.context.phase, this.context.store);\n\t    }\n\t    (0, _moduleVisitor.bindImports)(term, mod, this.context.phase, this.context);\n\t    return term;\n\t  }\n\n\t  expandImport(term) {\n\t    return this.registerImport(term);\n\t  }\n\n\t  expandImportNamespace(term) {\n\t    return this.registerImport(term);\n\t  }\n\n\t  expandExport(term) {\n\t    if (T.isFunctionDeclaration(term.declaration) || T.isClassDeclaration(term.declaration)) {\n\t      return term.extend({\n\t        declaration: this.registerFunctionOrClass(term.declaration)\n\t      });\n\t    } else if (T.isVariableDeclaration(term.declaration)) {\n\t      return term.extend({\n\t        declaration: this.registerVariableDeclaration(term.declaration)\n\t      });\n\t    }\n\t    return term;\n\t  }\n\n\t  registerFunctionOrClass(term) {\n\t    let red = new RegisterBindingsReducer(this.context.useScope, this.context.phase, false, this.context.bindings, this.context.env);\n\t    return term.extend({\n\t      name: term.name.reduce(red)\n\t    });\n\t  }\n\n\t  registerVariableDeclaration(term) {\n\t    if (term.kind === 'syntax' || term.kind === 'syntaxrec' || term.kind === 'operator') {\n\t      return this.registerSyntaxDeclaration(term);\n\t    }\n\t    let red = new RegisterBindingsReducer(this.context.useScope, this.context.phase, term.kind === 'var', this.context.bindings, this.context.env);\n\t    return term.extend({\n\t      declarators: term.declarators.map(decl => {\n\t        return decl.extend({\n\t          binding: decl.binding.reduce(red)\n\t        });\n\t      })\n\t    });\n\t  }\n\n\t  registerSyntaxDeclaration(term) {\n\t    if (term.kind === 'syntax' || term.kind === 'operator') {\n\t      // syntax id^{a, b} = <init>^{a, b}\n\t      // ->\n\t      // syntaxrec id^{a,b,c} = function() { return <<id^{a}>> }\n\t      // syntaxrec id^{a,b} = <init>^{a,b,c}\n\t      let scope = (0, _scope.freshScope)('nonrec');\n\t      let scopeReducer = new _scopeReducer2.default([{ scope: scope, phase: _syntax.ALL_PHASES, flip: false }], this.context.bindings);\n\t      term = term.extend({\n\t        declarators: term.declarators.map(decl => {\n\t          let name = decl.binding.name;\n\t          let nameAdded = name.addScope(scope, this.context.bindings, _syntax.ALL_PHASES);\n\t          let nameRemoved = name.removeScope(this.context.currentScope[this.context.currentScope.length - 1], this.context.phase);\n\t          let newBinding = (0, _symbol.gensym)(name.val());\n\t          this.context.bindings.addForward(nameAdded, nameRemoved, newBinding, this.context.phase);\n\t          return decl.extend({\n\t            init: decl.init.reduce(scopeReducer)\n\t          });\n\t        })\n\t      });\n\t    }\n\t    // for syntax declarations we need to load the compiletime value\n\t    // into the environment\n\t    let compiletimeType = term.kind === 'operator' ? 'operator' : 'syntax';\n\t    return term.extend({\n\t      declarators: term.declarators.map(decl => {\n\t        // each compiletime value needs to be expanded with a fresh\n\t        // environment and in the next higher phase\n\t        let syntaxExpander = new _termExpander2.default(_.merge(this.context, {\n\t          phase: this.context.phase + 1,\n\t          env: new _env2.default(),\n\t          store: this.context.store\n\t        }));\n\n\t        let init = syntaxExpander.expand(decl.init);\n\t        let val = (0, _loadSyntax.evalCompiletimeValue)(init, _.merge(this.context, {\n\t          phase: this.context.phase + 1\n\t        }));\n\t        let red = new RegisterSyntaxBindingsReducer(this.context.useScope, this.context.phase, this.context.bindings, this.context.env, {\n\t          type: compiletimeType,\n\t          prec: decl.prec == null ? void 0 : decl.prec.val(),\n\t          assoc: decl.assoc == null ? void 0 : decl.assoc.val(),\n\t          f: val\n\t        });\n\t        return decl.extend({ binding: decl.binding.reduce(red), init });\n\t      })\n\t    });\n\t  }\n\n\t  // registerSyntaxDeclarator(term) {\n\t  //\n\t  // }\n\t}\n\texports.default = TokenExpander;\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90b2tlbi1leHBhbmRlci5qcyJdLCJuYW1lcyI6WyJTIiwiXyIsIlQiLCJSZWdpc3RlckJpbmRpbmdzUmVkdWNlciIsIkNsb25lUmVkdWNlciIsImNvbnN0cnVjdG9yIiwidXNlU2NvcGUiLCJwaGFzZSIsInNraXBEdXAiLCJiaW5kaW5ncyIsImVudiIsInJlZHVjZUJpbmRpbmdJZGVudGlmaWVyIiwidCIsInMiLCJuZXdOYW1lIiwibmFtZSIsInJlbW92ZVNjb3BlIiwibmV3QmluZGluZyIsInZhbCIsImFkZCIsImJpbmRpbmciLCJzZXQiLCJ0b1N0cmluZyIsImV4dGVuZCIsIlJlZ2lzdGVyU3ludGF4QmluZGluZ3NSZWR1Y2VyIiwicmVzb2x2ZWROYW1lIiwicmVzb2x2ZSIsIlRva2VuRXhwYW5kZXIiLCJjb250ZXh0IiwiZXhwYW5kIiwic3R4bCIsInJlc3VsdCIsInNpemUiLCJwcmV2IiwiZW5mIiwiZG9uZSIsInB1c2giLCJkaXNwYXRjaCIsImVuZm9yZXN0IiwiZXhwYW5kVmFyaWFibGVEZWNsYXJhdGlvblN0YXRlbWVudCIsInRlcm0iLCJkZWNsYXJhdGlvbiIsInJlZ2lzdGVyVmFyaWFibGVEZWNsYXJhdGlvbiIsImV4cGFuZEZ1bmN0aW9uRGVjbGFyYXRpb24iLCJyZWdpc3RlckZ1bmN0aW9uT3JDbGFzcyIsInJlZ2lzdGVySW1wb3J0IiwicGF0aCIsIm1vZHVsZVNwZWNpZmllciIsIm1vZCIsInZpc2l0b3IiLCJmb3JTeW50YXgiLCJsb2FkZXIiLCJnZXQiLCJjd2QiLCJzdG9yZSIsInZpc2l0IiwiaW52b2tlIiwiZXhwYW5kSW1wb3J0IiwiZXhwYW5kSW1wb3J0TmFtZXNwYWNlIiwiZXhwYW5kRXhwb3J0IiwiaXNGdW5jdGlvbkRlY2xhcmF0aW9uIiwiaXNDbGFzc0RlY2xhcmF0aW9uIiwiaXNWYXJpYWJsZURlY2xhcmF0aW9uIiwicmVkIiwicmVkdWNlIiwia2luZCIsInJlZ2lzdGVyU3ludGF4RGVjbGFyYXRpb24iLCJkZWNsYXJhdG9ycyIsIm1hcCIsImRlY2wiLCJzY29wZSIsInNjb3BlUmVkdWNlciIsImZsaXAiLCJuYW1lQWRkZWQiLCJhZGRTY29wZSIsIm5hbWVSZW1vdmVkIiwiY3VycmVudFNjb3BlIiwibGVuZ3RoIiwiYWRkRm9yd2FyZCIsImluaXQiLCJjb21waWxldGltZVR5cGUiLCJzeW50YXhFeHBhbmRlciIsIm1lcmdlIiwidHlwZSIsInByZWMiLCJhc3NvYyIsImYiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBOztJQUFrQkEsQzs7QUFDbEI7O0FBQ0E7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOztJQUFZQyxDOztBQUNaOztJQUFZQyxDOztBQUNaOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7Ozs7OztBQUVBLE1BQU1DLHVCQUFOLFNBakJrQkgsQ0FpQm9CLFNBQUtJLFlBQTNDLENBQXdEOztBQU90REMsY0FDRUMsUUFERixFQUVFQyxLQUZGLEVBR0VDLE9BSEYsRUFJRUMsUUFKRixFQUtFQyxHQUxGLEVBTUU7QUFDQTtBQUNBLFNBQUtKLFFBQUwsR0FBZ0JBLFFBQWhCO0FBQ0EsU0FBS0MsS0FBTCxHQUFhQSxLQUFiO0FBQ0EsU0FBS0UsUUFBTCxHQUFnQkEsUUFBaEI7QUFDQSxTQUFLRCxPQUFMLEdBQWVBLE9BQWY7QUFDQSxTQUFLRSxHQUFMLEdBQVdBLEdBQVg7QUFDRDs7QUFFREMsMEJBQXdCQyxDQUF4QixFQUFpQ0MsQ0FBakMsRUFBc0Q7QUFDcEQsUUFBSUMsVUFBVUQsRUFBRUUsSUFBRixDQUFPQyxXQUFQLENBQW1CLEtBQUtWLFFBQXhCLEVBQWtDLEtBQUtDLEtBQXZDLENBQWQ7QUFDQSxRQUFJVSxhQUFhLG9CQUFPSCxRQUFRSSxHQUFSLEVBQVAsQ0FBakI7QUFDQSxTQUFLVCxRQUFMLENBQWNVLEdBQWQsQ0FBa0JMLE9BQWxCLEVBQTJCO0FBQ3pCTSxlQUFTSCxVQURnQjtBQUV6QlYsYUFBTyxLQUFLQSxLQUZhO0FBR3pCQyxlQUFTLEtB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REwsRUFFUixLQUFLc0IsT0FBTCxDQUFhckIsS0FGTCxFQUdSLEtBQUtxQixPQUFMLENBQWFuQixRQUhMLEVBSVIsS0FBS21CLE9BQUwsQ0FBYWxCLEdBSkwsRUFLUjtBQUNFeUUsZ0JBQU1ILGVBRFI7QUFFRUksZ0JBQU1mLEtBQUtlLElBQUwsSUFBYSxJQUFiLEdBQW9CLEtBQUssQ0FBekIsR0FBNkJmLEtBQUtlLElBQUwsQ0FBVWxFLEdBQVYsRUFGckM7QUFHRW1FLGlCQUFPaEIsS0FBS2dCLEtBQUwsSUFBYyxJQUFkLEdBQXFCLEtBQUssQ0FBMUIsR0FBOEJoQixLQUFLZ0IsS0FBTCxDQUFXbkUsR0FBWCxFQUh2QztBQUlFb0UsYUFBR3BFO0FBSkwsU0FMUSxDQUFWO0FBWUEsZUFBT21ELEtBQUs5QyxNQUFMLENBQVksRUFBRUgsU0FBU2lELEtBQUtqRCxPQUFMLENBQWE0QyxNQUFiLENBQW9CRCxHQUFwQixDQUFYLEVBQXFDZ0IsSUFBckMsRUFBWixDQUFQO0FBQ0QsT0EvQlk7QUFESSxLQUFaLENBQVA7QUFrQ0Q7O0FBRUQ7QUFDQTtBQUNBO0FBM011RDtrQkFBcENwRCxhIiwiZmlsZSI6InRva2VuLWV4cGFuZGVyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbmltcG9ydCBUZXJtLCAqIGFzIFMgZnJvbSAnc3dlZXQtc3BlYyc7XG5pbXBvcnQgeyBMaXN0IH0gZnJvbSAnaW1tdXRhYmxlJztcbmltcG9ydCB7IEVuZm9yZXN0ZXIgfSBmcm9tICcuL2VuZm9yZXN0ZXInO1xuaW1wb3J0IFRlcm1FeHBhbmRlciBmcm9tICcuL3Rlcm0tZXhwYW5kZXIuanMnO1xuaW1wb3J0IEVudiBmcm9tICcuL2Vudic7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ3JhbWRhJztcbmltcG9ydCAqIGFzIFQgZnJvbSAnLi90ZXJtcyc7XG5pbXBvcnQgeyBnZW5zeW0gfSBmcm9tICcuL3N5bWJvbCc7XG5pbXBvcnQgeyBWYXJCaW5kaW5nVHJhbnNmb3JtLCBDb21waWxldGltZVRyYW5zZm9ybSB9IGZyb20gJy4vdHJhbnNmb3Jtcyc7XG5pbXBvcnQgeyBldmFsQ29tcGlsZXRpbWVWYWx1ZSB9IGZyb20gJy4vbG9hZC1zeW50YXgnO1xuaW1wb3J0IHsgZnJlc2hTY29wZSB9IGZyb20gJy4vc2NvcGUnO1xuaW1wb3J0IHsgQUxMX1BIQVNFUyB9IGZyb20gJy4vc3ludGF4JztcbmltcG9ydCBBU1REaXNwYXRjaGVyIGZyb20gJy4vYXN0LWRpc3BhdGNoZXInO1xuaW1wb3J0IFN5bnRheCBmcm9tICcuL3N5bnRheC5qcyc7XG5pbXBvcnQgU2NvcGVSZWR1Y2VyIGZyb20gJy4vc2NvcGUtcmVkdWNlcic7XG5pbXBvcnQgTW9kdWxlVmlzaXRvciwgeyBiaW5kSW1wb3J0cyB9IGZyb20gJy4vbW9kdWxlLXZpc2l0b3InO1xuXG5jbGFzcyBSZWdpc3RlckJpbmRpbmdzUmVkdWNlciBleHRlbmRzIFRlcm0uQ2xvbmVSZWR1Y2VyIHtcbiAgdXNlU2NvcGU6IGFueTtcbiAgcGhhc2U6IG51bWJlcjtcbiAgYmluZGluZ3M6IGFueTtcbiAgc2tpcER1cDogYm9vbGVhbjtcbiAgZW52OiBFbnY7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgdXNlU2NvcGU6IGFueSxcbiAgICBwaGFzZTogbnVtYmVyLFxuICAgIHNraXBEdXA6IGJvb2xlYW4sXG4gICAgYmluZGluZ3M6IGFueSxcbiAgICBlbnY6IEVudixcbiAgKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLnVzZVNjb3BlID0gdXNlU2NvcGU7XG4gICAgdGhpcy5waGFzZSA9IHBoYXNlO1xuICAgIHRoaXMuYmluZGluZ3MgPSBiaW5kaW5ncztcbiAgICB0aGlzLnNraXBEdXAgPSBza2lwRHVwO1xuICAgIHRoaXMuZW52ID0gZW52O1xuICB9XG5cbiAgcmVkdWNlQmluZGluZ0lkZW50aWZpZXIodDogVGVybSwgczogeyBuYW1lOiBTeW50YXggfSkge1xuICAgIGxldCBuZXdOYW1lID0gcy5uYW1lLnJlbW92ZVNjb3BlKHRoaXMudXNlU2NvcGUsIHRoaXMucGhhc2UpO1xuICAgIGxldCBuZXdCaW5kaW5nID0gZ2Vuc3ltKG5ld05hbWUudmFsKCkpO1xuICAgIHRoaXMuYmluZGluZ3MuYWRkKG5ld05hbWUsIHtcbiAgICAgIGJpbmRpbmc6IG5ld0JpbmRpbmcsXG4gICAgICBwaGFzZTogdGhpcy5waGFzZSxcbiAgICAgIHNraXBEdXA6IHRoaXMuc2tpcER1cCxcbiAgICB9KTtcbiAgICB0aGlzLmVudi5zZXQobmV3QmluZGluZy50b1N0cmluZygpLCBuZXcgVmFyQmluZGluZ1RyYW5zZm9ybShuZXdOYW1lKSk7XG4gICAgcmV0dXJuIHQuZXh0ZW5kKHtcbiAgICAgIG5hbWU6IG5ld05hbWUsXG4gICAgfSk7XG4gIH1cbn1cblxuY2xhc3MgUmVnaXN0ZXJTeW50YXhCaW5kaW5nc1JlZHVjZXIgZXh0ZW5kcyBUZXJtLkNsb25lUmVkdWNlciB7XG4gIHVzZVNjb3BlOiBhbnk7XG4gIHBoYXNlOiBudW1iZXI7XG4gIGJpbmRpbmdzOiBhbnk7XG4gIGVudjogRW52O1xuICB2YWw6IGFueTtcblxuICBjb25zdHJ1Y3Rvcih1c2VTY29wZTogYW55LCBwaGFzZTogbnVtYmVyLCBiaW5kaW5nczogYW55LCBlbnY6IEVudiwgdmFsOiBhbnkpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMudXNlU2NvcGUgPSB1c2VTY29wZTtcbiAgICB0aGlzLnBoYXNlID0gcGhhc2U7XG4gICAgdGhpcy5iaW5kaW5ncyA9IGJpbmRpbmdzO1xuICAgIHRoaXMuZW52ID0gZW52O1xuICAgIHRoaXMudmFsID0gdmFsO1xuICB9XG5cbiAgcmVkdWNlQmluZGluZ0lkZW50aWZpZXIodDogVGVybSwgczogeyBuYW1lOiBTeW50YXggfSkge1xuICAgIGxldCBuZXdOYW1lID0gcy5uYW1lLnJlbW92ZVNjb3BlKHRoaXMudXNlU2NvcGUsIHRoaXMucGhhc2UpO1xuICAgIGxldCBuZXdCaW5kaW5nID0gZ2Vuc3ltKG5ld05hbWUudmFsKCkpO1xuICAgIHRoaXMuYmluZGluZ3MuYWRkKG5ld05hbWUsIHtcbiAgICAgIGJpbmRpbmc6IG5ld0JpbmRpbmcsXG4gICAgICBwaGFzZTogdGhpcy5waGFzZSxcbiAgICAgIHNraXBEdXA6IGZhbHNlLFxuICAgIH0pO1xuICAgIGxldCByZXNvbHZlZE5hbWUgPSBuZXdOYW1lLnJlc29sdmUodGhpcy5waGFzZSk7XG4gICAgdGhpcy5lbnYuc2V0KHJlc29sdmVkTmFtZSwgbmV3IENvbXBpbGV0aW1lVHJhbnNmb3JtKHRoaXMudmFsKSk7XG4gICAgcmV0dXJuIHQuZXh0ZW5kKHtcbiAgICAgIG5hbWU6IG5ld05hbWUsXG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVG9rZW5FeHBhbmRlciBleHRlbmRzIEFTVERpc3BhdGNoZXIge1xuICBjb25zdHJ1Y3Rvcihjb250ZXh0OiBhbnkpIHtcbiAgICBzdXBlcignZXhwYW5kJywgZmFsc2UpO1xuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gIH1cblxuICBleHBhbmQoc3R4bDogTGlzdDxTeW50YXg+KSB7XG4gICAgbGV0IHJlc3VsdCA9IFtdO1xuICAgIGlmIChzdHhsLnNpemUgPT09IDApIHtcbiAgICAgIHJldHVybiBMaXN0KHJlc3VsdCk7XG4gICAgfVxuICAgIGxldCBwcmV2ID0gTGlzdCgpO1xuICAgIGxldCBlbmYgPSBuZXcgRW5mb3Jlc3RlcihzdHhsLCBwcmV2LCB0aGlzLmNvbnRleHQpO1xuXG4gICAgd2hpbGUgKCFlbmYuZG9uZSkge1xuICAgICAgcmVzdWx0LnB1c2godGhpcy5kaXNwYXRjaChlbmYuZW5mb3Jlc3QoKSkpO1xuICAgIH1cblxuICAgIHJldHVybiBMaXN0KHJlc3VsdCk7XG4gIH1cblxuICBleHBhbmRWYXJpYWJsZURlY2xhcmF0aW9uU3RhdGVtZW50KHRlcm06IFMuVmFyaWFibGVEZWNsYXJhdGlvblN0YXRlbWVudCkge1xuICAgIHJldHVybiB0ZXJtLmV4dGVuZCh7XG4gICAgICBkZWNsYXJhdGlvbjogdGhpcy5yZWdpc3RlclZhcmlhYmxlRGVjbGFyYXRpb24odGVybS5kZWNsYXJhdGlvbiksXG4gICAgfSk7XG4gIH1cblxuICBleHBhbmRGdW5jdGlvbkRlY2xhcmF0aW9uKHRlcm06IFRlcm0pIHtcbiAgICByZXR1cm4gdGhpcy5yZWdpc3RlckZ1bmN0aW9uT3JDbGFzcyh0ZXJtKTtcbiAgfVxuXG4gIC8vIFRPRE86IHRoaW5rIGFib3V0IGZ1bmN0aW9uIGV4cHJlc3Npb25zXG5cbiAgcmVnaXN0ZXJJbXBvcnQodGVybTogUy5JbXBvcnQgfCBTLkltcG9ydE5hbWVzcGFjZSkge1xuICAgIGxldCBwYXRoID0gdGVybS5tb2R1bGVTcGVjaWZpZXIudmFsKCk7XG4gICAgbGV0IG1vZDtcbiAgICBsZXQgdmlzaXRvciA9IG5ldyBNb2R1bGVWaXNpdG9yKHRoaXMuY29udGV4dCk7XG4gICAgaWYgKHRlcm0uZm9yU3ludGF4KSB7XG4gICAgICBtb2QgPSB0aGlzLmNvbnRleHQubG9hZGVyLmdldChcbiAgICAgICAgcGF0aCxcbiAgICAgICAgdGhpcy5jb250ZXh0LnBoYXNlICsgMSxcbiAgICAgICAgdGhpcy5jb250ZXh0LmN3ZCxcbiAgICAgICk7XG4gICAgICB0aGlzLmNvbnRleHQuc3RvcmUgPSB2aXNpdG9yLnZpc2l0KFxuICAgICAgICBtb2QsXG4gICAgICAgIHRoaXMuY29udGV4dC5waGFzZSArIDEsXG4gICAgICAgIHRoaXMuY29udGV4dC5zdG9yZSxcbiAgICAgICk7XG4gICAgICB0aGlzLmNvbnRleHQuc3RvcmUgPSB2aXNpdG9yLmludm9rZShcbiAgICAgICAgbW9kLFxuICAgICAgICB0aGlzLmNvbnRleHQucGhhc2UgKyAxLFxuICAgICAgICB0aGlzLmNvbnRleHQuc3RvcmUsXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBtb2QgPSB0aGlzLmNvbnRleHQubG9hZGVyLmdldChwYXRoLCB0aGlzLmNvbnRleHQucGhhc2UsIHRoaXMuY29udGV4dC5jd2QpO1xuICAgICAgdGhpcy5jb250ZXh0LnN0b3JlID0gdmlzaXRvci52aXNpdChcbiAgICAgICAgbW9kLFxuICAgICAgICB0aGlzLmNvbnRleHQucGhhc2UsXG4gICAgICAgIHRoaXMuY29udGV4dC5zdG9yZSxcbiAgICAgICk7XG4gICAgfVxuICAgIGJpbmRJbXBvcnRzKHRlcm0sIG1vZCwgdGhpcy5jb250ZXh0LnBoYXNlLCB0aGlzLmNvbnRleHQpO1xuICAgIHJldHVybiB0ZXJtO1xuICB9XG5cbiAgZXhwYW5kSW1wb3J0KHRlcm06IFMuSW1wb3J0KSB7XG4gICAgcmV0dXJuIHRoaXMucmVnaXN0ZXJJbXBvcnQodGVybSk7XG4gIH1cblxuICBleHBhbmRJbXBvcnROYW1lc3BhY2UodGVybTogUy5JbXBvcnROYW1lc3BhY2UpIHtcbiAgICByZXR1cm4gdGhpcy5yZWdpc3RlckltcG9ydCh0ZXJtKTtcbiAgfVxuXG4gIGV4cGFuZEV4cG9ydCh0ZXJtOiBUZXJtKSB7XG4gICAgaWYgKFxuICAgICAgVC5pc0Z1bmN0aW9uRGVjbGFyYXRpb24odGVybS5kZWNsYXJhdGlvbikgfHxcbiAgICAgIFQuaXNDbGFzc0RlY2xhcmF0aW9uKHRlcm0uZGVjbGFyYXRpb24pXG4gICAgKSB7XG4gICAgICByZXR1cm4gdGVybS5leHRlbmQoe1xuICAgICAgICBkZWNsYXJhdGlvbjogdGhpcy5yZWdpc3RlckZ1bmN0aW9uT3JDbGFzcyh0ZXJtLmRlY2xhcmF0aW9uKSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoVC5pc1ZhcmlhYmxlRGVjbGFyYXRpb24odGVybS5kZWNsYXJhdGlvbikpIHtcbiAgICAgIHJldHVybiB0ZXJtLmV4dGVuZCh7XG4gICAgICAgIGRlY2xhcmF0aW9uOiB0aGlzLnJlZ2lzdGVyVmFyaWFibGVEZWNsYXJhdGlvbih0ZXJtLmRlY2xhcmF0aW9uKSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdGVybTtcbiAgfVxuXG4gIHJlZ2lzdGVyRnVuY3Rpb25PckNsYXNzKHRlcm06IFRlcm0pIHtcbiAgICBsZXQgcmVkID0gbmV3IFJlZ2lzdGVyQmluZGluZ3NSZWR1Y2VyKFxuICAgICAgdGhpcy5jb250ZXh0LnVzZVNjb3BlLFxuICAgICAgdGhpcy5jb250ZXh0LnBoYXNlLFxuICAgICAgZmFsc2UsXG4gICAgICB0aGlzLmNvbnRleHQuYmluZGluZ3MsXG4gICAgICB0aGlzLmNvbnRleHQuZW52LFxuICAgICk7XG4gICAgcmV0dXJuIHRlcm0uZXh0ZW5kKHtcbiAgICAgIG5hbWU6IHRlcm0ubmFtZS5yZWR1Y2UocmVkKSxcbiAgICB9KTtcbiAgfVxuXG4gIHJlZ2lzdGVyVmFyaWFibGVEZWNsYXJhdGlvbih0ZXJtOiBUZXJtKSB7XG4gICAgaWYgKFxuICAgICAgdGVybS5raW5kID09PSAnc3ludGF4JyB8fFxuICAgICAgdGVybS5raW5kID09PSAnc3ludGF4cmVjJyB8fFxuICAgICAgdGVybS5raW5kID09PSAnb3BlcmF0b3InXG4gICAgKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZWdpc3RlclN5bnRheERlY2xhcmF0aW9uKHRlcm0pO1xuICAgIH1cbiAgICBsZXQgcmVkID0gbmV3IFJlZ2lzdGVyQmluZGluZ3NSZWR1Y2VyKFxuICAgICAgdGhpcy5jb250ZXh0LnVzZVNjb3BlLFxuICAgICAgdGhpcy5jb250ZXh0LnBoYXNlLFxuICAgICAgdGVybS5raW5kID09PSAndmFyJyxcbiAgICAgIHRoaXMuY29udGV4dC5iaW5kaW5ncyxcbiAgICAgIHRoaXMuY29udGV4dC5lbnYsXG4gICAgKTtcbiAgICByZXR1cm4gdGVybS5leHRlbmQoe1xuICAgICAgZGVjbGFyYXRvcnM6IHRlcm0uZGVjbGFyYXRvcnMubWFwKGRlY2wgPT4ge1xuICAgICAgICByZXR1cm4gZGVjbC5leHRlbmQoe1xuICAgICAgICAgIGJpbmRpbmc6IGRlY2wuYmluZGluZy5yZWR1Y2UocmVkKSxcbiAgICAgICAgfSk7XG4gICAgICB9KSxcbiAgICB9KTtcbiAgfVxuXG4gIHJlZ2lzdGVyU3ludGF4RGVjbGFyYXRpb24odGVybTogVGVybSkge1xuICAgIGlmICh0ZXJtLmtpbmQgPT09ICdzeW50YXgnIHx8IHRlcm0ua2luZCA9PT0gJ29wZXJhdG9yJykge1xuICAgICAgLy8gc3ludGF4IGlkXnthLCBifSA9IDxpbml0Pl57YSwgYn1cbiAgICAgIC8vIC0+XG4gICAgICAvLyBzeW50YXhyZWMgaWRee2EsYixjfSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gPDxpZF57YX0+PiB9XG4gICAgICAvLyBzeW50YXhyZWMgaWRee2EsYn0gPSA8aW5pdD5ee2EsYixjfVxuICAgICAgbGV0IHNjb3BlID0gZnJlc2hTY29wZSgnbm9ucmVjJyk7XG4gICAgICBsZXQgc2NvcGVSZWR1Y2VyID0gbmV3IFNjb3BlUmVkdWNlcihcbiAgICAgICAgW3sgc2NvcGU6IHNjb3BlLCBwaGFzZTogQUxMX1BIQVNFUywgZmxpcDogZmFsc2UgfV0sXG4gICAgICAgIHRoaXMuY29udGV4dC5iaW5kaW5ncyxcbiAgICAgICk7XG4gICAgICB0ZXJtID0gdGVybS5leHRlbmQoe1xuICAgICAgICBkZWNsYXJhdG9yczogdGVybS5kZWNsYXJhdG9ycy5tYXAoZGVjbCA9PiB7XG4gICAgICAgICAgbGV0IG5hbWUgPSBkZWNsLmJpbmRpbmcubmFtZTtcbiAgICAgICAgICBsZXQgbmFtZUFkZGVkID0gbmFtZS5hZGRTY29wZShcbiAgICAgICAgICAgIHNjb3BlLFxuICAgICAgICAgICAgdGhpcy5jb250ZXh0LmJpbmRpbmdzLFxuICAgICAgICAgICAgQUxMX1BIQVNFUyxcbiAgICAgICAgICApO1xuICAgICAgICAgIGxldCBuYW1lUmVtb3ZlZCA9IG5hbWUucmVtb3ZlU2NvcGUoXG4gICAgICAgICAgICB0aGlzLmNvbnRleHQuY3VycmVudFNjb3BlW3RoaXMuY29udGV4dC5jdXJyZW50U2NvcGUubGVuZ3RoIC0gMV0sXG4gICAgICAgICAgICB0aGlzLmNvbnRleHQucGhhc2UsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBsZXQgbmV3QmluZGluZyA9IGdlbnN5bShuYW1lLnZhbCgpKTtcbiAgICAgICAgICB0aGlzLmNvbnRleHQuYmluZGluZ3MuYWRkRm9yd2FyZChcbiAgICAgICAgICAgIG5hbWVBZGRlZCxcbiAgICAgICAgICAgIG5hbWVSZW1vdmVkLFxuICAgICAgICAgICAgbmV3QmluZGluZyxcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5waGFzZSxcbiAgICAgICAgICApO1xuICAgICAgICAgIHJldHVybiBkZWNsLmV4dGVuZCh7XG4gICAgICAgICAgICBpbml0OiBkZWNsLmluaXQucmVkdWNlKHNjb3BlUmVkdWNlciksXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgfVxuICAgIC8vIGZvciBzeW50YXggZGVjbGFyYXRpb25zIHdlIG5lZWQgdG8gbG9hZCB0aGUgY29tcGlsZXRpbWUgdmFsdWVcbiAgICAvLyBpbnRvIHRoZSBlbnZpcm9ubWVudFxuICAgIGxldCBjb21waWxldGltZVR5cGUgPSB0ZXJtLmtpbmQgPT09ICdvcGVyYXRvcicgPyAnb3BlcmF0b3InIDogJ3N5bnRheCc7XG4gICAgcmV0dXJuIHRlcm0uZXh0ZW5kKHtcbiAgICAgIGRlY2xhcmF0b3JzOiB0ZXJtLmRlY2xhcmF0b3JzLm1hcChkZWNsID0+IHtcbiAgICAgICAgLy8gZWFjaCBjb21waWxldGltZSB2YWx1ZSBuZWVkcyB0byBiZSBleHBhbmRlZCB3aXRoIGEgZnJlc2hcbiAgICAgICAgLy8gZW52aXJvbm1lbnQgYW5kIGluIHRoZSBuZXh0IGhpZ2hlciBwaGFzZVxuICAgICAgICBsZXQgc3ludGF4RXhwYW5kZXIgPSBuZXcgVGVybUV4cGFuZGVyKFxuICAgICAgICAgIF8ubWVyZ2UodGhpcy5jb250ZXh0LCB7XG4gICAgICAgICAgICBwaGFzZTogdGhpcy5jb250ZXh0LnBoYXNlICsgMSxcbiAgICAgICAgICAgIGVudjogbmV3IEVudigpLFxuICAgICAgICAgICAgc3RvcmU6IHRoaXMuY29udGV4dC5zdG9yZSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcblxuICAgICAgICBsZXQgaW5pdCA9IHN5bnRheEV4cGFuZGVyLmV4cGFuZChkZWNsLmluaXQpO1xuICAgICAgICBsZXQgdmFsID0gZXZhbENvbXBpbGV0aW1lVmFsdWUoXG4gICAgICAgICAgaW5pdCxcbiAgICAgICAgICBfLm1lcmdlKHRoaXMuY29udGV4dCwge1xuICAgICAgICAgICAgcGhhc2U6IHRoaXMuY29udGV4dC5waGFzZSArIDEsXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICAgIGxldCByZWQgPSBuZXcgUmVnaXN0ZXJTeW50YXhCaW5kaW5nc1JlZHVjZXIoXG4gICAgICAgICAgdGhpcy5jb250ZXh0LnVzZVNjb3BlLFxuICAgICAgICAgIHRoaXMuY29udGV4dC5waGFzZSxcbiAgICAgICAgICB0aGlzLmNvbnRleHQuYmluZGluZ3MsXG4gICAgICAgICAgdGhpcy5jb250ZXh0LmVudixcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBjb21waWxldGltZVR5cGUsXG4gICAgICAgICAgICBwcmVjOiBkZWNsLnByZWMgPT0gbnVsbCA/IHZvaWQgMCA6IGRlY2wucHJlYy52YWwoKSxcbiAgICAgICAgICAgIGFzc29jOiBkZWNsLmFzc29jID09IG51bGwgPyB2b2lkIDAgOiBkZWNsLmFzc29jLnZhbCgpLFxuICAgICAgICAgICAgZjogdmFsLFxuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBkZWNsLmV4dGVuZCh7IGJpbmRpbmc6IGRlY2wuYmluZGluZy5yZWR1Y2UocmVkKSwgaW5pdCB9KTtcbiAgICAgIH0pLFxuICAgIH0pO1xuICB9XG5cbiAgLy8gcmVnaXN0ZXJTeW50YXhEZWNsYXJhdG9yKHRlcm0pIHtcbiAgLy9cbiAgLy8gfVxufVxuIl19\n\n/***/ },\n/* 71 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.bindImports = bindImports;\n\n\tvar _loadSyntax = __webpack_require__(66);\n\n\tvar _ramda = __webpack_require__(20);\n\n\tvar _ = _interopRequireWildcard(_ramda);\n\n\tvar _sweetSpec = __webpack_require__(43);\n\n\tvar T = _interopRequireWildcard(_sweetSpec);\n\n\tvar _sweetSpecUtils = __webpack_require__(44);\n\n\tvar S = _interopRequireWildcard(_sweetSpecUtils);\n\n\tvar _symbol = __webpack_require__(39);\n\n\tvar _transforms = __webpack_require__(41);\n\n\tvar _hygieneUtils = __webpack_require__(72);\n\n\tvar _sweetModule = __webpack_require__(42);\n\n\tvar _sweetModule2 = _interopRequireDefault(_sweetModule);\n\n\tvar _immutable = __webpack_require__(12);\n\n\tvar _sweetToShiftReducer = __webpack_require__(56);\n\n\tvar _sweetToShiftReducer2 = _interopRequireDefault(_sweetToShiftReducer);\n\n\tvar _shiftCodegen = __webpack_require__(46);\n\n\tvar _shiftCodegen2 = _interopRequireDefault(_shiftCodegen);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\n\tfunction bindImports(impTerm, exModule, phase, context) {\n\t  let names = [];\n\t  let phaseToBind = impTerm.forSyntax ? phase + 1 : phase;\n\t  if (impTerm.defaultBinding != null) {\n\t    let exportName = exModule.exportedNames.find(exName => exName.exportedName.val() === '_default');\n\t    let name = impTerm.defaultBinding.name;\n\t    if (exportName != null) {\n\t      let newBinding = (0, _symbol.gensym)('_default');\n\t      let toForward = exportName.exportedName;\n\t      context.bindings.addForward(name, toForward, newBinding, phaseToBind);\n\t      names.push(name);\n\t    }\n\t  }\n\t  if (impTerm.namedImports) {\n\t    impTerm.namedImports.forEach(specifier => {\n\t      let name = specifier.binding.name;\n\t      let exportName = exModule.exportedNames.find(exName => exName.exportedName.val() === name.val());\n\t      if (exportName != null) {\n\t        let newBinding = (0, _symbol.gensym)(name.val());\n\t        let toForward = exportName.name ? exportName.name : exportName.exportedName;\n\t        context.bindings.addForward(name, toForward, newBinding, phaseToBind);\n\t        names.push(name);\n\t      }\n\t    });\n\t  }\n\t  if (impTerm.namespaceBinding) {\n\t    let name = impTerm.namespaceBinding.name;\n\t    let newBinding = (0, _symbol.gensym)(name.val());\n\t    context.store.set(newBinding.toString(), new _transforms.ModuleNamespaceTransform(name, exModule));\n\t    context.bindings.add(name, {\n\t      binding: newBinding,\n\t      phase: phaseToBind,\n\t      skipDup: false\n\t    });\n\n\t    names.push(name);\n\t  }\n\t  return (0, _immutable.List)(names);\n\t}\n\texports.default = class {\n\n\t  constructor(context) {\n\t    this.context = context;\n\t  }\n\n\t  visit(mod, phase, store) {\n\t    mod.imports.forEach(imp => {\n\t      if (imp.forSyntax) {\n\t        let mod = this.context.loader.get(imp.moduleSpecifier.val(), phase + 1, '');\n\t        this.visit(mod, phase + 1, store);\n\t        this.invoke(mod, phase + 1, store);\n\t      } else {\n\t        let mod = this.context.loader.get(imp.moduleSpecifier.val(), phase, '');\n\t        this.visit(mod, phase, store);\n\t      }\n\t      bindImports(imp, mod, phase, this.context);\n\t    });\n\t    for (let term of mod.compiletimeItems()) {\n\t      if (S.isSyntaxDeclarationStatement(term)) {\n\t        this.registerSyntaxDeclaration(term.declaration, phase, store);\n\t      }\n\t    }\n\t    return store;\n\t  }\n\n\t  invoke(mod, phase, store) {\n\t    mod.imports.forEach(imp => {\n\t      if (!imp.forSyntax) {\n\t        let mod = this.context.loader.get(imp.moduleSpecifier.val(), phase, '');\n\t        this.invoke(mod, phase, store);\n\t        bindImports(imp, mod, phase, this.context);\n\t      }\n\t    });\n\t    let items = mod.runtimeItems();\n\t    for (let term of items) {\n\t      if (S.isVariableDeclarationStatement(term)) {\n\t        this.registerVariableDeclaration(term.declaration, phase, store);\n\t      } else if (S.isFunctionDeclaration(term)) {\n\t        this.registerFunctionOrClass(term, phase, store);\n\t      }\n\t    }\n\t    let parsed = new T.Module({\n\t      directives: (0, _immutable.List)(),\n\t      items\n\t    }).reduce(new _sweetToShiftReducer2.default(phase));\n\n\t    let gen = (0, _shiftCodegen2.default)(parsed, new _shiftCodegen.FormattedCodeGen());\n\t    let result = this.context.transform(gen);\n\n\t    this.context.loader.eval(result.code, store);\n\t    return store;\n\t  }\n\n\t  registerSyntaxDeclaration(term, phase, store) {\n\t    term.declarators.forEach(decl => {\n\t      let val = (0, _loadSyntax.evalCompiletimeValue)(decl.init, _.merge(this.context, {\n\t        phase: phase + 1,\n\t        store\n\t      }));\n\n\t      (0, _hygieneUtils.collectBindings)(decl.binding).forEach(stx => {\n\t        if (phase !== 0) {\n\t          // phase 0 bindings extend the binding map during compilation\n\t          let newBinding = (0, _symbol.gensym)(stx.val());\n\t          this.context.bindings.add(stx, {\n\t            binding: newBinding,\n\t            phase: phase,\n\t            skipDup: false\n\t          });\n\t        }\n\t        let resolvedName = stx.resolve(phase);\n\t        store.set(resolvedName, new _transforms.CompiletimeTransform({ type: 'syntax', f: val }));\n\t      });\n\t    });\n\t  }\n\n\t  registerVariableDeclaration(term, phase, store) {\n\t    term.declarators.forEach(decl => {\n\t      (0, _hygieneUtils.collectBindings)(decl.binding).forEach(stx => {\n\t        if (phase !== 0) {\n\t          // phase 0 bindings extend the binding map during compilation\n\t          let newBinding = (0, _symbol.gensym)(stx.val());\n\t          this.context.bindings.add(stx, {\n\t            binding: newBinding,\n\t            phase: phase,\n\t            skipDup: term.kind === 'var'\n\t          });\n\t        }\n\t      });\n\t    });\n\t  }\n\n\t  registerFunctionOrClass(term, phase, store) {\n\t    (0, _hygieneUtils.collectBindings)(term.name).forEach(stx => {\n\t      if (phase !== 0) {\n\t        let newBinding = (0, _symbol.gensym)(stx.val());\n\t        this.context.bindings.add(stx, {\n\t          binding: newBinding,\n\t          phase: phase,\n\t          skipDup: false\n\t        });\n\t      }\n\t    });\n\t  }\n\t};\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tb2R1bGUtdmlzaXRvci5qcyJdLCJuYW1lcyI6WyJiaW5kSW1wb3J0cyIsIl8iLCJUIiwiUyIsImltcFRlcm0iLCJleE1vZHVsZSIsInBoYXNlIiwiY29udGV4dCIsIm5hbWVzIiwicGhhc2VUb0JpbmQiLCJmb3JTeW50YXgiLCJkZWZhdWx0QmluZGluZyIsImV4cG9ydE5hbWUiLCJleHBvcnRlZE5hbWVzIiwiZmluZCIsImV4TmFtZSIsImV4cG9ydGVkTmFtZSIsInZhbCIsIm5hbWUiLCJuZXdCaW5kaW5nIiwidG9Gb3J3YXJkIiwiYmluZGluZ3MiLCJhZGRGb3J3YXJkIiwicHVzaCIsIm5hbWVkSW1wb3J0cyIsImZvckVhY2giLCJzcGVjaWZpZXIiLCJiaW5kaW5nIiwibmFtZXNwYWNlQmluZGluZyIsInN0b3JlIiwic2V0IiwidG9TdHJpbmciLCJhZGQiLCJza2lwRHVwIiwiY29uc3RydWN0b3IiLCJ2aXNpdCIsIm1vZCIsImltcG9ydHMiLCJpbXAiLCJsb2FkZXIiLCJnZXQiLCJtb2R1bGVTcGVjaWZpZXIiLCJpbnZva2UiLCJ0ZXJtIiwiY29tcGlsZXRpbWVJdGVtcyIsImlzU3ludGF4RGVjbGFyYXRpb25TdGF0ZW1lbnQiLCJyZWdpc3RlclN5bnRheERlY2xhcmF0aW9uIiwiZGVjbGFyYXRpb24iLCJpdGVtcyIsInJ1bnRpbWVJdGVtcyIsImlzVmFyaWFibGVEZWNsYXJhdGlvblN0YXRlbWVudCIsInJlZ2lzdGVyVmFyaWFibGVEZWNsYXJhdGlvbiIsImlzRnVuY3Rpb25EZWNsYXJhdGlvbiIsInJlZ2lzdGVyRnVuY3Rpb25PckNsYXNzIiwicGFyc2VkIiwiTW9kdWxlIiwiZGlyZWN0aXZlcyIsInJlZHVjZSIsImdlbiIsInJlc3VsdCIsInRyYW5zZm9ybSIsImV2YWwiLCJjb2RlIiwiZGVjbGFyYXRvcnMiLCJkZWNsIiwiaW5pdCIsIm1lcmdlIiwic3R4IiwicmVzb2x2ZWROYW1lIiwicmVzb2x2ZSIsInR5cGUiLCJmIiwia2lu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SzZCLElBQUwsS0FBYztBQUhNLFdBQS9CO0FBS0Q7QUFDRixPQVZEO0FBV0QsS0FaRDtBQWFEOztBQUVEbkIsMEJBQXdCVixJQUF4QixFQUFtQ3JDLEtBQW5DLEVBQStDdUIsS0FBL0MsRUFBMkQ7QUFDekQsdUNBQWdCYyxLQUFLekIsSUFBckIsRUFBMkJPLE9BQTNCLENBQW1DMEMsT0FBTztBQUN4QyxVQUFJN0QsVUFBVSxDQUFkLEVBQWlCO0FBQ2YsWUFBSWEsYUFBYSxvQkFBT2dELElBQUlsRCxHQUFKLEVBQVAsQ0FBakI7QUFDQSxhQUFLVixPQUFMLENBQWFjLFFBQWIsQ0FBc0JXLEdBQXRCLENBQTBCbUMsR0FBMUIsRUFBK0I7QUFDN0J4QyxtQkFBU1IsVUFEb0I7QUFFN0JiLGlCQUFPQSxLQUZzQjtBQUc3QjJCLG1CQUFTO0FBSG9CLFNBQS9CO0FBS0Q7QUFDRixLQVREO0FBVUQ7QUF2SGtCLEMiLCJmaWxlIjoibW9kdWxlLXZpc2l0b3IuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAZmxvd1xuaW1wb3J0IHsgZXZhbENvbXBpbGV0aW1lVmFsdWUgfSBmcm9tICcuL2xvYWQtc3ludGF4JztcbmltcG9ydCAqIGFzIF8gZnJvbSAncmFtZGEnO1xuaW1wb3J0ICogYXMgVCBmcm9tICdzd2VldC1zcGVjJztcbmltcG9ydCAqIGFzIFMgZnJvbSAnLi9zd2VldC1zcGVjLXV0aWxzJztcbmltcG9ydCB7IGdlbnN5bSB9IGZyb20gJy4vc3ltYm9sJztcbmltcG9ydCB7IE1vZHVsZU5hbWVzcGFjZVRyYW5zZm9ybSwgQ29tcGlsZXRpbWVUcmFuc2Zvcm0gfSBmcm9tICcuL3RyYW5zZm9ybXMnO1xuaW1wb3J0IHsgY29sbGVjdEJpbmRpbmdzIH0gZnJvbSAnLi9oeWdpZW5lLXV0aWxzJztcbmltcG9ydCBTd2VldE1vZHVsZSBmcm9tICcuL3N3ZWV0LW1vZHVsZSc7XG5pbXBvcnQgeyBMaXN0IH0gZnJvbSAnaW1tdXRhYmxlJztcbmltcG9ydCBTd2VldFRvU2hpZnRSZWR1Y2VyIGZyb20gJy4vc3dlZXQtdG8tc2hpZnQtcmVkdWNlcic7XG5pbXBvcnQgY29kZWdlbiwgeyBGb3JtYXR0ZWRDb2RlR2VuIH0gZnJvbSAnc2hpZnQtY29kZWdlbic7XG5cbmltcG9ydCB0eXBlIHsgQ29udGV4dCB9IGZyb20gJy4vc3dlZXQtbG9hZGVyJztcblxuZXhwb3J0IGZ1bmN0aW9uIGJpbmRJbXBvcnRzKFxuICBpbXBUZXJtOiBULkltcG9ydERlY2xhcmF0aW9uLFxuICBleE1vZHVsZTogU3dlZXRNb2R1bGUsXG4gIHBoYXNlOiBhbnksXG4gIGNvbnRleHQ6IENvbnRleHQsXG4pIHtcbiAgbGV0IG5hbWVzID0gW107XG4gIGxldCBwaGFzZVRvQmluZCA9IGltcFRlcm0uZm9yU3ludGF4ID8gcGhhc2UgKyAxIDogcGhhc2U7XG4gIGlmIChpbXBUZXJtLmRlZmF1bHRCaW5kaW5nICE9IG51bGwpIHtcbiAgICBsZXQgZXhwb3J0TmFtZSA9IGV4TW9kdWxlLmV4cG9ydGVkTmFtZXMuZmluZChcbiAgICAgIGV4TmFtZSA9PiBleE5hbWUuZXhwb3J0ZWROYW1lLnZhbCgpID09PSAnX2RlZmF1bHQnLFxuICAgICk7XG4gICAgbGV0IG5hbWUgPSBpbXBUZXJtLmRlZmF1bHRCaW5kaW5nLm5hbWU7XG4gICAgaWYgKGV4cG9ydE5hbWUgIT0gbnVsbCkge1xuICAgICAgbGV0IG5ld0JpbmRpbmcgPSBnZW5zeW0oJ19kZWZhdWx0Jyk7XG4gICAgICBsZXQgdG9Gb3J3YXJkID0gZXhwb3J0TmFtZS5leHBvcnRlZE5hbWU7XG4gICAgICBjb250ZXh0LmJpbmRpbmdzLmFkZEZvcndhcmQobmFtZSwgdG9Gb3J3YXJkLCBuZXdCaW5kaW5nLCBwaGFzZVRvQmluZCk7XG4gICAgICBuYW1lcy5wdXNoKG5hbWUpO1xuICAgIH1cbiAgfVxuICBpZiAoaW1wVGVybS5uYW1lZEltcG9ydHMpIHtcbiAgICBpbXBUZXJtLm5hbWVkSW1wb3J0cy5mb3JFYWNoKHNwZWNpZmllciA9PiB7XG4gICAgICBsZXQgbmFtZSA9IHNwZWNpZmllci5iaW5kaW5nLm5hbWU7XG4gICAgICBsZXQgZXhwb3J0TmFtZSA9IGV4TW9kdWxlLmV4cG9ydGVkTmFtZXMuZmluZChcbiAgICAgICAgZXhOYW1lID0+IGV4TmFtZS5leHBvcnRlZE5hbWUudmFsKCkgPT09IG5hbWUudmFsKCksXG4gICAgICApO1xuICAgICAgaWYgKGV4cG9ydE5hbWUgIT0gbnVsbCkge1xuICAgICAgICBsZXQgbmV3QmluZGluZyA9IGdlbnN5bShuYW1lLnZhbCgpKTtcbiAgICAgICAgbGV0IHRvRm9yd2FyZCA9IGV4cG9ydE5hbWUubmFtZVxuICAgICAgICAgID8gZXhwb3J0TmFtZS5uYW1lXG4gICAgICAgICAgOiBleHBvcnROYW1lLmV4cG9ydGVkTmFtZTtcbiAgICAgICAgY29udGV4dC5iaW5kaW5ncy5hZGRGb3J3YXJkKG5hbWUsIHRvRm9yd2FyZCwgbmV3QmluZGluZywgcGhhc2VUb0JpbmQpO1xuICAgICAgICBuYW1lcy5wdXNoKG5hbWUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIGlmIChpbXBUZXJtLm5hbWVzcGFjZUJpbmRpbmcpIHtcbiAgICBsZXQgbmFtZSA9IGltcFRlcm0ubmFtZXNwYWNlQmluZGluZy5uYW1lO1xuICAgIGxldCBuZXdCaW5kaW5nID0gZ2Vuc3ltKG5hbWUudmFsKCkpO1xuICAgIGNvbnRleHQuc3RvcmUuc2V0KFxuICAgICAgbmV3QmluZGluZy50b1N0cmluZygpLFxuICAgICAgbmV3IE1vZHVsZU5hbWVzcGFjZVRyYW5zZm9ybShuYW1lLCBleE1vZHVsZSksXG4gICAgKTtcbiAgICBjb250ZXh0LmJpbmRpbmdzLmFkZChuYW1lLCB7XG4gICAgICBiaW5kaW5nOiBuZXdCaW5kaW5nLFxuICAgICAgcGhhc2U6IHBoYXNlVG9CaW5kLFxuICAgICAgc2tpcER1cDogZmFsc2UsXG4gICAgfSk7XG5cbiAgICBuYW1lcy5wdXNoKG5hbWUpO1xuICB9XG4gIHJldHVybiBMaXN0KG5hbWVzKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3Mge1xuICBjb250ZXh0OiBDb250ZXh0O1xuXG4gIGNvbnN0cnVjdG9yKGNvbnRleHQ6IENvbnRleHQpIHtcbiAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICB9XG5cbiAgdmlzaXQobW9kOiBTd2VldE1vZHVsZSwgcGhhc2U6IGFueSwgc3RvcmU6IGFueSkge1xuICAgIG1vZC5pbXBvcnRzLmZvckVhY2goaW1wID0+IHtcbiAgICAgIGlmIChpbXAuZm9yU3ludGF4KSB7XG4gICAgICAgIGxldCBtb2QgPSB0aGlzLmNvbnRleHQubG9hZGVyLmdldChcbiAgICAgICAgICBpbXAubW9kdWxlU3BlY2lmaWVyLnZhbCgpLFxuICAgICAgICAgIHBoYXNlICsgMSxcbiAgICAgICAgICAnJyxcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy52aXNpdChtb2QsIHBoYXNlICsgMSwgc3RvcmUpO1xuICAgICAgICB0aGlzLmludm9rZShtb2QsIHBoYXNlICsgMSwgc3RvcmUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGV0IG1vZCA9IHRoaXMuY29udGV4dC5sb2FkZXIuZ2V0KGltcC5tb2R1bGVTcGVjaWZpZXIudmFsKCksIHBoYXNlLCAnJyk7XG4gICAgICAgIHRoaXMudmlzaXQobW9kLCBwaGFzZSwgc3RvcmUpO1xuICAgICAgfVxuICAgICAgYmluZEltcG9ydHMoaW1wLCBtb2QsIHBoYXNlLCB0aGlzLmNvbnRleHQpO1xuICAgIH0pO1xuICAgIGZvciAobGV0IHRlcm0gb2YgbW9kLmNvbXBpbGV0aW1lSXRlbXMoKSkge1xuICAgICAgaWYgKFMuaXNTeW50YXhEZWNsYXJhdGlvblN0YXRlbWVudCh0ZXJtKSkge1xuICAgICAgICB0aGlzLnJlZ2lzdGVyU3ludGF4RGVjbGFyYXRpb24odGVybS5kZWNsYXJhdGlvbiwgcGhhc2UsIHN0b3JlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHN0b3JlO1xuICB9XG5cbiAgaW52b2tlKG1vZDogYW55LCBwaGFzZTogYW55LCBzdG9yZTogYW55KSB7XG4gICAgbW9kLmltcG9ydHMuZm9yRWFjaChpbXAgPT4ge1xuICAgICAgaWYgKCFpbXAuZm9yU3ludGF4KSB7XG4gICAgICAgIGxldCBtb2QgPSB0aGlzLmNvbnRleHQubG9hZGVyLmdldChpbXAubW9kdWxlU3BlY2lmaWVyLnZhbCgpLCBwaGFzZSwgJycpO1xuICAgICAgICB0aGlzLmludm9rZShtb2QsIHBoYXNlLCBzdG9yZSk7XG4gICAgICAgIGJpbmRJbXBvcnRzKGltcCwgbW9kLCBwaGFzZSwgdGhpcy5jb250ZXh0KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBsZXQgaXRlbXMgPSBtb2QucnVudGltZUl0ZW1zKCk7XG4gICAgZm9yIChsZXQgdGVybSBvZiBpdGVtcykge1xuICAgICAgaWYgKFMuaXNWYXJpYWJsZURlY2xhcmF0aW9uU3RhdGVtZW50KHRlcm0pKSB7XG4gICAgICAgIHRoaXMucmVnaXN0ZXJWYXJpYWJsZURlY2xhcmF0aW9uKHRlcm0uZGVjbGFyYXRpb24sIHBoYXNlLCBzdG9yZSk7XG4gICAgICB9IGVsc2UgaWYgKFMuaXNGdW5jdGlvbkRlY2xhcmF0aW9uKHRlcm0pKSB7XG4gICAgICAgIHRoaXMucmVnaXN0ZXJGdW5jdGlvbk9yQ2xhc3ModGVybSwgcGhhc2UsIHN0b3JlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgbGV0IHBhcnNlZCA9IG5ldyBULk1vZHVsZSh7XG4gICAgICBkaXJlY3RpdmVzOiBMaXN0KCksXG4gICAgICBpdGVtcyxcbiAgICB9KS5yZWR1Y2UobmV3IFN3ZWV0VG9TaGlmdFJlZHVjZXIocGhhc2UpKTtcblxuICAgIGxldCBnZW4gPSBjb2RlZ2VuKHBhcnNlZCwgbmV3IEZvcm1hdHRlZENvZGVHZW4oKSk7XG4gICAgbGV0IHJlc3VsdCA9IHRoaXMuY29udGV4dC50cmFuc2Zvcm0oZ2VuKTtcblxuICAgIHRoaXMuY29udGV4dC5sb2FkZXIuZXZhbChyZXN1bHQuY29kZSwgc3RvcmUpO1xuICAgIHJldHVybiBzdG9yZTtcbiAgfVxuXG4gIHJlZ2lzdGVyU3ludGF4RGVjbGFyYXRpb24oXG4gICAgdGVybTogVC5WYXJpYWJsZURlY2xhcmF0aW9uU3RhdGVtZW50LFxuICAgIHBoYXNlOiBhbnksXG4gICAgc3RvcmU6IGFueSxcbiAgKSB7XG4gICAgdGVybS5kZWNsYXJhdG9ycy5mb3JFYWNoKGRlY2wgPT4ge1xuICAgICAgbGV0IHZhbCA9IGV2YWxDb21waWxldGltZVZhbHVlKFxuICAgICAgICBkZWNsLmluaXQsXG4gICAgICAgIF8ubWVyZ2UodGhpcy5jb250ZXh0LCB7XG4gICAgICAgICAgcGhhc2U6IHBoYXNlICsgMSxcbiAgICAgICAgICBzdG9yZSxcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBjb2xsZWN0QmluZGluZ3MoZGVjbC5iaW5kaW5nKS5mb3JFYWNoKHN0eCA9PiB7XG4gICAgICAgIGlmIChwaGFzZSAhPT0gMCkge1xuICAgICAgICAgIC8vIHBoYXNlIDAgYmluZGluZ3MgZXh0ZW5kIHRoZSBiaW5kaW5nIG1hcCBkdXJpbmcgY29tcGlsYXRpb25cbiAgICAgICAgICBsZXQgbmV3QmluZGluZyA9IGdlbnN5bShzdHgudmFsKCkpO1xuICAgICAgICAgIHRoaXMuY29udGV4dC5iaW5kaW5ncy5hZGQoc3R4LCB7XG4gICAgICAgICAgICBiaW5kaW5nOiBuZXdCaW5kaW5nLFxuICAgICAgICAgICAgcGhhc2U6IHBoYXNlLFxuICAgICAgICAgICAgc2tpcER1cDogZmFsc2UsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHJlc29sdmVkTmFtZSA9IHN0eC5yZXNvbHZlKHBoYXNlKTtcbiAgICAgICAgc3RvcmUuc2V0KFxuICAgICAgICAgIHJlc29sdmVkTmFtZSxcbiAgICAgICAgICBuZXcgQ29tcGlsZXRpbWVUcmFuc2Zvcm0oeyB0eXBlOiAnc3ludGF4JywgZjogdmFsIH0pLFxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICByZWdpc3RlclZhcmlhYmxlRGVjbGFyYXRpb24odGVybTogYW55LCBwaGFzZTogYW55LCBzdG9yZTogYW55KSB7XG4gICAgdGVybS5kZWNsYXJhdG9ycy5mb3JFYWNoKGRlY2wgPT4ge1xuICAgICAgY29sbGVjdEJpbmRpbmdzKGRlY2wuYmluZGluZykuZm9yRWFjaChzdHggPT4ge1xuICAgICAgICBpZiAocGhhc2UgIT09IDApIHtcbiAgICAgICAgICAvLyBwaGFzZSAwIGJpbmRpbmdzIGV4dGVuZCB0aGUgYmluZGluZyBtYXAgZHVyaW5nIGNvbXBpbGF0aW9uXG4gICAgICAgICAgbGV0IG5ld0JpbmRpbmcgPSBnZW5zeW0oc3R4LnZhbCgpKTtcbiAgICAgICAgICB0aGlzLmNvbnRleHQuYmluZGluZ3MuYWRkKHN0eCwge1xuICAgICAgICAgICAgYmluZGluZzogbmV3QmluZGluZyxcbiAgICAgICAgICAgIHBoYXNlOiBwaGFzZSxcbiAgICAgICAgICAgIHNraXBEdXA6IHRlcm0ua2luZCA9PT0gJ3ZhcicsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcmVnaXN0ZXJGdW5jdGlvbk9yQ2xhc3ModGVybTogYW55LCBwaGFzZTogYW55LCBzdG9yZTogYW55KSB7XG4gICAgY29sbGVjdEJpbmRpbmdzKHRlcm0ubmFtZSkuZm9yRWFjaChzdHggPT4ge1xuICAgICAgaWYgKHBoYXNlICE9PSAwKSB7XG4gICAgICAgIGxldCBuZXdCaW5kaW5nID0gZ2Vuc3ltKHN0eC52YWwoKSk7XG4gICAgICAgIHRoaXMuY29udGV4dC5iaW5kaW5ncy5hZGQoc3R4LCB7XG4gICAgICAgICAgYmluZGluZzogbmV3QmluZGluZyxcbiAgICAgICAgICBwaGFzZTogcGhhc2UsXG4gICAgICAgICAgc2tpcER1cDogZmFsc2UsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59XG4iXX0=\n\n/***/ },\n/* 72 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\texports.CollectBindingSyntax = undefined;\n\texports.collectBindings = collectBindings;\n\n\tvar _immutable = __webpack_require__(12);\n\n\tvar _astDispatcher = __webpack_require__(69);\n\n\tvar _astDispatcher2 = _interopRequireDefault(_astDispatcher);\n\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n\tclass CollectBindingSyntax extends _astDispatcher2.default {\n\t  constructor() {\n\t    super('collect', true);\n\t    this.names = (0, _immutable.List)();\n\t  }\n\n\t  // registerSyntax(stx) {\n\t  //   let newBinding = gensym(stx.val());\n\t  //   this.context.bindings.add(stx, {\n\t  //     binding: newBinding,\n\t  //     phase: this.context.phase,\n\t  //     // skip dup because js allows variable redeclarations\n\t  //     // (technically only for `var` but we can let later stages of the pipeline\n\t  //     // handle incorrect redeclarations of `const` and `let`)\n\t  //     skipDup: true\n\t  //   });\n\t  //   return stx;\n\t  // }\n\n\t  collect(term) {\n\t    return this.dispatch(term);\n\t  }\n\n\t  collectBindingIdentifier(term) {\n\t    return this.names.concat(term.name);\n\t  }\n\n\t  collectBindingPropertyIdentifier(term) {\n\t    return this.collect(term.binding);\n\t  }\n\n\t  collectBindingPropertyProperty(term) {\n\t    return this.collect(term.binding);\n\t  }\n\n\t  collectArrayBinding(term) {\n\t    let restElement = null;\n\t    if (term.restElement != null) {\n\t      restElement = this.collect(term.restElement);\n\t    }\n\t    return this.names.concat(restElement).concat(term.elements.filter(el => el != null).flatMap(el => this.collect(el)));\n\t  }\n\n\t  collectObjectBinding() {\n\t    // return term.properties.flatMap(prop => this.collect(prop));\n\t    return (0, _immutable.List)();\n\t  }\n\n\t  // registerVariableDeclaration(term) {\n\t  //   let declarators = term.declarators.map(decl => {\n\t  //     return decl.extend({\n\t  //       binding: this.register(decl.binding)\n\t  //     });\n\t  //   });\n\t  //   return term.extend({ declarators });\n\t  // }\n\t  //\n\t  // registerFunctionDeclaration(term) {\n\t  //   return term.extend({\n\t  //     name: this.register(term.name)\n\t  //   });\n\t  // }\n\t  //\n\t  // registerExport(term) {\n\t  //   return term.extend({\n\t  //     declaration: this.register(term.declaration)\n\t  //   });\n\t  // }\n\t}\n\n\texports.CollectBindingSyntax = CollectBindingSyntax;\n\tfunction collectBindings(term) {\n\t  return new CollectBindingSyntax().collect(term);\n\t}\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9oeWdpZW5lLXV0aWxzLmpzIl0sIm5hbWVzIjpbImNvbGxlY3RCaW5kaW5ncyIsIkNvbGxlY3RCaW5kaW5nU3ludGF4IiwiY29uc3RydWN0b3IiLCJuYW1lcyIsImNvbGxlY3QiLCJ0ZXJtIiwiZGlzcGF0Y2giLCJjb2xsZWN0QmluZGluZ0lkZW50aWZpZXIiLCJjb25jYXQiLCJuYW1lIiwiY29sbGVjdEJpbmRpbmdQcm9wZXJ0eUlkZW50aWZpZXIiLCJiaW5kaW5nIiwiY29sbGVjdEJpbmRpbmdQcm9wZXJ0eVByb3BlcnR5IiwiY29sbGVjdEFycmF5QmluZGluZyIsInJlc3RFbGVtZW50IiwiZWxlbWVudHMiLCJmaWx0ZXIiLCJlbCIsImZsYXRNYXAiLCJjb2xsZWN0T2JqZWN0QmluZGluZyJdLCJtYXBwaW5ncyI6Ijs7Ozs7O1FBOEVnQkEsZSxHQUFBQSxlOztBQTlFaEI7O0FBRUE7Ozs7OztBQUVPLE1BQU1DLG9CQUFOLGlDQUFpRDtBQUN0REMsZ0JBQWM7QUFDWixVQUFNLFNBQU4sRUFBaUIsSUFBakI7QUFDQSxTQUFLQyxLQUFMLEdBQWEsc0JBQWI7QUFDRDs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUFDLFVBQVFDLElBQVIsRUFBYztBQUNaLFdBQU8sS0FBS0MsUUFBTCxDQUFjRCxJQUFkLENBQVA7QUFDRDs7QUFFREUsMkJBQXlCRixJQUF6QixFQUErQjtBQUM3QixXQUFPLEtBQUtGLEtBQUwsQ0FBV0ssTUFBWCxDQUFrQkgsS0FBS0ksSUFBdkIsQ0FBUDtBQUNEOztBQUVEQyxtQ0FBaUNMLElBQWpDLEVBQXVDO0FBQ3JDLFdBQU8sS0FBS0QsT0FBTCxDQUFhQyxLQUFLTSxPQUFsQixDQUFQO0FBQ0Q7O0FBRURDLGlDQUErQlAsSUFBL0IsRUFBcUM7QUFDbkMsV0FBTyxLQUFLRCxPQUFMLENBQWFDLEtBQUtNLE9BQWxCLENBQVA7QUFDRDs7QUFFREUsc0JBQW9CUixJQUFwQixFQUEwQjtBQUN4QixRQUFJUyxjQUFjLElBQWxCO0FBQ0EsUUFBSVQsS0FBS1MsV0FBTCxJQUFvQixJQUF4QixFQUE4QjtBQUM1QkEsb0JBQWMsS0FBS1YsT0FBTCxDQUFhQyxLQUFLUyxXQUFsQixDQUFkO0FBQ0Q7QUFDRCxXQUFPLEtBQUtYLEtBQUwsQ0FDSkssTUFESSxDQUNHTSxXQURILEVBRUpOLE1BRkksQ0FHSEgsS0FBS1UsUUFBTCxDQUFjQyxNQUFkLENBQXFCQyxNQUFNQSxNQUFNLElBQWpDLEVBQXVDQyxPQUF2QyxDQUErQ0QsTUFBTSxLQUFLYixPQUFMLENBQWFhLEVBQWIsQ0FBckQsQ0FIRyxDQUFQO0FBS0Q7O0FBRURFLHlCQUF1QjtBQUNyQjtBQUNBLFdBQU8sc0JBQVA7QUFDRDs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBdkVzRDs7UUFBM0NsQixvQixHQUFBQSxvQjtBQTBFTixTQUFTRCxlQUFULENBQXlCSyxJQUF6QixFQUErQjtBQUNwQyxTQUFPLElBQUlKLG9CQUFKLEdBQTJCRyxPQUEzQixDQUFtQ0MsSUFBbkMsQ0FBUDtBQUNEIiwiZmlsZSI6Imh5Z2llbmUtdXRpbHMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBMaXN0IH0gZnJvbSAnaW1tdXRhYmxlJztcblxuaW1wb3J0IEFTVERpc3BhdGNoZXIgZnJvbSAnLi9hc3QtZGlzcGF0Y2hlcic7XG5cbmV4cG9ydCBjbGFzcyBDb2xsZWN0QmluZGluZ1N5bnRheCBleHRlbmRzIEFTVERpc3BhdGNoZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcignY29sbGVjdCcsIHRydWUpO1xuICAgIHRoaXMubmFtZXMgPSBMaXN0KCk7XG4gIH1cblxuICAvLyByZWdpc3RlclN5bnRheChzdHgpIHtcbiAgLy8gICBsZXQgbmV3QmluZGluZyA9IGdlbnN5bShzdHgudmFsKCkpO1xuICAvLyAgIHRoaXMuY29udGV4dC5iaW5kaW5ncy5hZGQoc3R4LCB7XG4gIC8vICAgICBiaW5kaW5nOiBuZXdCaW5kaW5nLFxuICAvLyAgICAgcGhhc2U6IHRoaXMuY29udGV4dC5waGFzZSxcbiAgLy8gICAgIC8vIHNraXAgZHVwIGJlY2F1c2UganMgYWxsb3dzIHZhcmlhYmxlIHJlZGVjbGFyYXRpb25zXG4gIC8vICAgICAvLyAodGVjaG5pY2FsbHkgb25seSBmb3IgYHZhcmAgYnV0IHdlIGNhbiBsZXQgbGF0ZXIgc3RhZ2VzIG9mIHRoZSBwaXBlbGluZVxuICAvLyAgICAgLy8gaGFuZGxlIGluY29ycmVjdCByZWRlY2xhcmF0aW9ucyBvZiBgY29uc3RgIGFuZCBgbGV0YClcbiAgLy8gICAgIHNraXBEdXA6IHRydWVcbiAgLy8gICB9KTtcbiAgLy8gICByZXR1cm4gc3R4O1xuICAvLyB9XG5cbiAgY29sbGVjdCh0ZXJtKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2godGVybSk7XG4gIH1cblxuICBjb2xsZWN0QmluZGluZ0lkZW50aWZpZXIodGVybSkge1xuICAgIHJldHVybiB0aGlzLm5hbWVzLmNvbmNhdCh0ZXJtLm5hbWUpO1xuICB9XG5cbiAgY29sbGVjdEJpbmRpbmdQcm9wZXJ0eUlkZW50aWZpZXIodGVybSkge1xuICAgIHJldHVybiB0aGlzLmNvbGxlY3QodGVybS5iaW5kaW5nKTtcbiAgfVxuXG4gIGNvbGxlY3RCaW5kaW5nUHJvcGVydHlQcm9wZXJ0eSh0ZXJtKSB7XG4gICAgcmV0dXJuIHRoaXMuY29sbGVjdCh0ZXJtLmJpbmRpbmcpO1xuICB9XG5cbiAgY29sbGVjdEFycmF5QmluZGluZyh0ZXJtKSB7XG4gICAgbGV0IHJlc3RFbGVtZW50ID0gbnVsbDtcbiAgICBpZiAodGVybS5yZXN0RWxlbWVudCAhPSBudWxsKSB7XG4gICAgICByZXN0RWxlbWVudCA9IHRoaXMuY29sbGVjdCh0ZXJtLnJlc3RFbGVtZW50KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMubmFtZXNcbiAgICAgIC5jb25jYXQocmVzdEVsZW1lbnQpXG4gICAgICAuY29uY2F0KFxuICAgICAgICB0ZXJtLmVsZW1lbnRzLmZpbHRlcihlbCA9PiBlbCAhPSBudWxsKS5mbGF0TWFwKGVsID0+IHRoaXMuY29sbGVjdChlbCkpLFxuICAgICAgKTtcbiAgfVxuXG4gIGNvbGxlY3RPYmplY3RCaW5kaW5nKCkge1xuICAgIC8vIHJldHVybiB0ZXJtLnByb3BlcnRpZXMuZmxhdE1hcChwcm9wID0+IHRoaXMuY29sbGVjdChwcm9wKSk7XG4gICAgcmV0dXJuIExpc3QoKTtcbiAgfVxuXG4gIC8vIHJlZ2lzdGVyVmFyaWFibGVEZWNsYXJhdGlvbih0ZXJtKSB7XG4gIC8vICAgbGV0IGRlY2xhcmF0b3JzID0gdGVybS5kZWNsYXJhdG9ycy5tYXAoZGVjbCA9PiB7XG4gIC8vICAgICByZXR1cm4gZGVjbC5leHRlbmQoe1xuICAvLyAgICAgICBiaW5kaW5nOiB0aGlzLnJlZ2lzdGVyKGRlY2wuYmluZGluZylcbiAgLy8gICAgIH0pO1xuICAvLyAgIH0pO1xuICAvLyAgIHJldHVybiB0ZXJtLmV4dGVuZCh7IGRlY2xhcmF0b3JzIH0pO1xuICAvLyB9XG4gIC8vXG4gIC8vIHJlZ2lzdGVyRnVuY3Rpb25EZWNsYXJhdGlvbih0ZXJtKSB7XG4gIC8vICAgcmV0dXJuIHRlcm0uZXh0ZW5kKHtcbiAgLy8gICAgIG5hbWU6IHRoaXMucmVnaXN0ZXIodGVybS5uYW1lKVxuICAvLyAgIH0pO1xuICAvLyB9XG4gIC8vXG4gIC8vIHJlZ2lzdGVyRXhwb3J0KHRlcm0pIHtcbiAgLy8gICByZXR1cm4gdGVybS5leHRlbmQoe1xuICAvLyAgICAgZGVjbGFyYXRpb246IHRoaXMucmVnaXN0ZXIodGVybS5kZWNsYXJhdGlvbilcbiAgLy8gICB9KTtcbiAgLy8gfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY29sbGVjdEJpbmRpbmdzKHRlcm0pIHtcbiAgcmV0dXJuIG5ldyBDb2xsZWN0QmluZGluZ1N5bnRheCgpLmNvbGxlY3QodGVybSk7XG59XG4iXX0=\n\n/***/ },\n/* 73 */\n/***/ function(module, exports) {\n\n\t\"use strict\";\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t  value: true\n\t});\n\tclass Store extends Map {\n\t  constructor(backingObject) {\n\t    super();\n\t    this.backingObject = backingObject;\n\t  }\n\n\t  set(key, val) {\n\t    super.set(key, val);\n\t    this.backingObject[key] = val;\n\t  }\n\n\t  getBackingObject() {\n\t    return this.backingObject;\n\t  }\n\t}\n\texports.default = Store;\n\t//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yZS5qcyJdLCJuYW1lcyI6WyJTdG9yZSIsIk1hcCIsImNvbnN0cnVjdG9yIiwiYmFja2luZ09iamVjdCIsInNldCIsImtleSIsInZhbCIsImdldEJhY2tpbmdPYmplY3QiXSwibWFwcGluZ3MiOiI7Ozs7O0FBQWUsTUFBTUEsS0FBTixTQUFvQkMsR0FBcEIsQ0FBd0I7QUFDckNDLGNBQVlDLGFBQVosRUFBMkI7QUFDekI7QUFDQSxTQUFLQSxhQUFMLEdBQXFCQSxhQUFyQjtBQUNEOztBQUVEQyxNQUFJQyxHQUFKLEVBQVNDLEdBQVQsRUFBYztBQUNaLFVBQU1GLEdBQU4sQ0FBVUMsR0FBVixFQUFlQyxHQUFmO0FBQ0EsU0FBS0gsYUFBTCxDQUFtQkUsR0FBbkIsSUFBMEJDLEdBQTFCO0FBQ0Q7O0FBRURDLHFCQUFtQjtBQUNqQixXQUFPLEtBQUtKLGFBQVo7QUFDRDtBQWJvQztrQkFBbEJILEsiLCJmaWxlIjoic3RvcmUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZGVmYXVsdCBjbGFzcyBTdG9yZSBleHRlbmRzIE1hcCB7XG4gIGNvbnN0cnVjdG9yKGJhY2tpbmdPYmplY3QpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuYmFja2luZ09iamVjdCA9IGJhY2tpbmdPYmplY3Q7XG4gIH1cblxuICBzZXQoa2V5LCB2YWwpIHtcbiAgICBzdXBlci5zZXQoa2V5LCB2YWwpO1xuICAgIHRoaXMuYmFja2luZ09iamVjdFtrZXldID0gdmFsO1xuICB9XG5cbiAgZ2V0QmFja2luZ09iamVjdCgpIHtcbiAgICByZXR1cm4gdGhpcy5iYWNraW5nT2JqZWN0O1xuICB9XG59XG4iXX0=\n\n/***/ },\n/* 74 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar indexOf = __webpack_require__(75);\n\n\tvar Object_keys = function (obj) {\n\t    if (Object.keys) return Object.keys(obj)\n\t    else {\n\t        var res = [];\n\t        for (var key in obj) res.push(key)\n\t        return res;\n\t    }\n\t};\n\n\tvar forEach = function (xs, fn) {\n\t    if (xs.forEach) return xs.forEach(fn)\n\t    else for (var i = 0; i < xs.length; i++) {\n\t        fn(xs[i], i, xs);\n\t    }\n\t};\n\n\tvar defineProp = (function() {\n\t    try {\n\t        Object.defineProperty({}, '_', {});\n\t        return function(obj, name, value) {\n\t            Object.defineProperty(obj, name, {\n\t                writable: true,\n\t                enumerable: false,\n\t                configurable: true,\n\t                value: value\n\t            })\n\t        };\n\t    } catch(e) {\n\t        return function(obj, name, value) {\n\t            obj[name] = value;\n\t        };\n\t    }\n\t}());\n\n\tvar globals = ['Array', 'Boolean', 'Date', 'Error', 'EvalError', 'Function',\n\t'Infinity', 'JSON', 'Math', 'NaN', 'Number', 'Object', 'RangeError',\n\t'ReferenceError', 'RegExp', 'String', 'SyntaxError', 'TypeError', 'URIError',\n\t'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape',\n\t'eval', 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'undefined', 'unescape'];\n\n\tfunction Context() {}\n\tContext.prototype = {};\n\n\tvar Script = exports.Script = function NodeScript (code) {\n\t    if (!(this instanceof Script)) return new Script(code);\n\t    this.code = code;\n\t};\n\n\tScript.prototype.runInContext = function (context) {\n\t    if (!(context instanceof Context)) {\n\t        throw new TypeError(\"needs a 'context' argument.\");\n\t    }\n\t    \n\t    var iframe = document.createElement('iframe');\n\t    if (!iframe.style) iframe.style = {};\n\t    iframe.style.display = 'none';\n\t    \n\t    document.body.appendChild(iframe);\n\t    \n\t    var win = iframe.contentWindow;\n\t    var wEval = win.eval, wExecScript = win.execScript;\n\n\t    if (!wEval && wExecScript) {\n\t        // win.eval() magically appears when this is called in IE:\n\t        wExecScript.call(win, 'null');\n\t        wEval = win.eval;\n\t    }\n\t    \n\t    forEach(Object_keys(context), function (key) {\n\t        win[key] = context[key];\n\t    });\n\t    forEach(globals, function (key) {\n\t        if (context[key]) {\n\t            win[key] = context[key];\n\t        }\n\t    });\n\t    \n\t    var winKeys = Object_keys(win);\n\n\t    var res = wEval.call(win, this.code);\n\t    \n\t    forEach(Object_keys(win), function (key) {\n\t        // Avoid copying circular objects like `top` and `window` by only\n\t        // updating existing context properties or new properties in the `win`\n\t        // that was only introduced after the eval.\n\t        if (key in context || indexOf(winKeys, key) === -1) {\n\t            context[key] = win[key];\n\t        }\n\t    });\n\n\t    forEach(globals, function (key) {\n\t        if (!(key in context)) {\n\t            defineProp(context, key, win[key]);\n\t        }\n\t    });\n\t    \n\t    document.body.removeChild(iframe);\n\t    \n\t    return res;\n\t};\n\n\tScript.prototype.runInThisContext = function () {\n\t    return eval(this.code); // maybe...\n\t};\n\n\tScript.prototype.runInNewContext = function (context) {\n\t    var ctx = Script.createContext(context);\n\t    var res = this.runInContext(ctx);\n\n\t    forEach(Object_keys(ctx), function (key) {\n\t        context[key] = ctx[key];\n\t    });\n\n\t    return res;\n\t};\n\n\tforEach(Object_keys(Script.prototype), function (name) {\n\t    exports[name] = Script[name] = function (code) {\n\t        var s = Script(code);\n\t        return s[name].apply(s, [].slice.call(arguments, 1));\n\t    };\n\t});\n\n\texports.createScript = function (code) {\n\t    return exports.Script(code);\n\t};\n\n\texports.createContext = Script.createContext = function (context) {\n\t    var copy = new Context();\n\t    if(typeof context === 'object') {\n\t        forEach(Object_keys(context), function (key) {\n\t            copy[key] = context[key];\n\t        });\n\t    }\n\t    return copy;\n\t};\n\n\n/***/ },\n/* 75 */\n/***/ function(module, exports) {\n\n\t\n\tvar indexOf = [].indexOf;\n\n\tmodule.exports = function(arr, obj){\n\t  if (indexOf) return arr.indexOf(obj);\n\t  for (var i = 0; i < arr.length; ++i) {\n\t    if (arr[i] === obj) return i;\n\t  }\n\t  return -1;\n\t};\n\n/***/ }\n/******/ ])\n});\n;"
  },
  {
    "path": "docs/editor/scripts/syntax.js",
    "content": "(function (root, factory) {\n    if (typeof exports === 'object') {\n        // CommonJS\n        factory(exports, require('underscore'), require('./parser'), require('./expander'));\n    } else if (typeof define === 'function' && define.amd) {\n        // AMD. Register as an anonymous module.\n        define([\n            'exports',\n            'underscore',\n            'parser',\n            'expander'\n        ], factory);\n    }\n}(this, function (exports$2, _, parser, expander) {\n    function assert(condition, message) {\n        if (!condition) {\n            throw new Error('ASSERT: ' + message);\n        }\n    }\n    // Keep an incrementing global counter so that a particular\n    // each new context object is assigned a unique \"instance number\"\n    // that it can be identified by. This helps with the memoization\n    // of the recursive resolveCtx implementation in expander.js.\n    // The memoization addresses issue #232.\n    var globalContextInstanceNumber = 1;\n    // (CSyntax, Str) -> CContext\n    function Rename(id, name, ctx, defctx) {\n        defctx = defctx || null;\n        this.id = id;\n        this.name = name;\n        this.context = ctx;\n        this.def = defctx;\n        this.instNum = globalContextInstanceNumber++;\n    }\n    // (Num) -> CContext\n    function Mark(mark, ctx) {\n        this.mark = mark;\n        this.context = ctx;\n        this.instNum = globalContextInstanceNumber++;\n    }\n    function Def(defctx, ctx) {\n        this.defctx = defctx;\n        this.context = ctx;\n        this.instNum = globalContextInstanceNumber++;\n    }\n    function Syntax(token, oldstx) {\n        this.token = token;\n        this.context = oldstx && oldstx.context ? oldstx.context : null;\n        this.deferredContext = oldstx && oldstx.deferredContext ? oldstx.deferredContext : null;\n    }\n    Syntax.prototype = {\n        mark: function (newMark) {\n            if (this.token.inner) {\n                return syntaxFromToken(this.token, {\n                    deferredContext: new Mark(newMark, this.deferredContext),\n                    context: new Mark(newMark, this.context)\n                });\n            }\n            return syntaxFromToken(this.token, { context: new Mark(newMark, this.context) });\n        },\n        rename: function (id, name, defctx) {\n            // defer renaming of delimiters\n            if (this.token.inner) {\n                return syntaxFromToken(this.token, {\n                    deferredContext: new Rename(id, name, this.deferredContext, defctx),\n                    context: new Rename(id, name, this.context, defctx)\n                });\n            }\n            return syntaxFromToken(this.token, { context: new Rename(id, name, this.context, defctx) });\n        },\n        addDefCtx: function (defctx) {\n            if (this.token.inner) {\n                return syntaxFromToken(this.token, {\n                    deferredContext: new Def(defctx, this.deferredContext),\n                    context: new Def(defctx, this.context)\n                });\n            }\n            return syntaxFromToken(this.token, { context: new Def(defctx, this.context) });\n        },\n        getDefCtx: function () {\n            var ctx = this.context;\n            while (ctx !== null) {\n                if (ctx instanceof Def) {\n                    return ctx.defctx;\n                }\n                ctx = ctx.context;\n            }\n            return null;\n        },\n        expose: function () {\n            assert(this.token.type === parser.Token.Delimiter, 'Only delimiters can be exposed');\n            function applyContext(stxCtx, ctx) {\n                if (ctx == null) {\n                    return stxCtx;\n                } else if (ctx instanceof Rename) {\n                    return new Rename(ctx.id, ctx.name, applyContext(stxCtx, ctx.context), ctx.def);\n                } else if (ctx instanceof Mark) {\n                    return new Mark(ctx.mark, applyContext(stxCtx, ctx.context));\n                } else if (ctx instanceof Def) {\n                    return new Def(ctx.defctx, applyContext(stxCtx, ctx.context));\n                } else {\n                    assert(false, 'unknown context type');\n                }\n            }\n            var self = this;\n            this.token.inner = _.map(this.token.inner, function (stx) {\n                // when not a syntax object (aka a TermTree) then no need to push down the expose\n                if (!stx.token) {\n                    return stx;\n                }\n                if (stx.token.inner) {\n                    return syntaxFromToken(stx.token, {\n                        deferredContext: applyContext(stx.deferredContext, self.deferredContext),\n                        context: applyContext(stx.context, self.deferredContext)\n                    });\n                } else {\n                    return syntaxFromToken(stx.token, { context: applyContext(stx.context, self.deferredContext) });\n                }\n            });\n            this.deferredContext = null;\n            return this;\n        },\n        toString: function () {\n            var val = this.token.type === parser.Token.EOF ? 'EOF' : this.token.value;\n            return '[Syntax: ' + val + ']';\n        }\n    };\n    // (CToken, CSyntax?) -> CSyntax\n    function syntaxFromToken(token, oldstx) {\n        return new Syntax(token, oldstx);\n    }\n    function mkSyntax(stx, value, type, inner) {\n        if (stx && Array.isArray(stx) && stx.length === 1) {\n            stx = stx[0];\n        } else if (stx && Array.isArray(stx)) {\n            throwSyntaxError('mkSyntax', 'Expecting a syntax object or an array with a single syntax object');\n        } else if (stx === undefined) {\n            throwSyntaxError('mkSyntax', 'You must provide an old syntax object context (or null) when creating a new syntax object.');\n        }\n        if (type === parser.Token.Delimiter) {\n            var startLineNumber, startLineStart, endLineNumber, endLineStart, startRange, endRange;\n            if (!Array.isArray(inner)) {\n                throwSyntaxError('mkSyntax', 'Must provide inner array of syntax objects when creating a delimiter');\n            }\n            if (stx && stx.token.type === parser.Token.Delimiter) {\n                startLineNumber = stx.token.startLineNumber;\n                startLineStart = stx.token.startLineStart;\n                endLineNumber = stx.token.endLineNumber;\n                endLineStart = stx.token.endLineStart;\n                startRange = stx.token.startRange;\n                endRange = stx.token.endRange;\n            } else if (stx && stx.token) {\n                startLineNumber = stx.token.lineNumber;\n                startLineStart = stx.token.lineStart;\n                endLineNumber = stx.token.lineNumber;\n                endLineStart = stx.token.lineStart;\n                startRange = stx.token.range;\n                endRange = stx.token.range;\n            }\n            return syntaxFromToken({\n                type: parser.Token.Delimiter,\n                value: value,\n                inner: inner,\n                startLineStart: startLineStart,\n                startLineNumber: startLineNumber,\n                endLineStart: endLineStart,\n                endLineNumber: endLineNumber,\n                startRange: startRange,\n                endRange: endRange\n            }, stx);\n        } else {\n            var lineStart, lineNumber, range;\n            if (stx && stx.token.type === parser.Token.Delimiter) {\n                lineStart = stx.token.startLineStart;\n                lineNumber = stx.token.startLineNumber;\n                range = stx.token.startRange;\n            } else if (stx && stx.token) {\n                lineStart = stx.token.lineStart;\n                lineNumber = stx.token.lineNumber;\n                range = stx.token.range;\n            }\n            return syntaxFromToken({\n                type: type,\n                value: value,\n                lineStart: lineStart,\n                lineNumber: lineNumber,\n                range: range\n            }, stx);\n        }\n    }\n    function makeValue(val, stx) {\n        if (typeof val === 'boolean') {\n            return mkSyntax(stx, val ? 'true' : 'false', parser.Token.BooleanLiteral);\n        } else if (typeof val === 'number') {\n            if (val !== val) {\n                return makeDelim('()', [\n                    makeValue(0, stx),\n                    makePunc('/', stx),\n                    makeValue(0, stx)\n                ], stx);\n            }\n            if (val < 0) {\n                return makeDelim('()', [\n                    makePunc('-', stx),\n                    makeValue(Math.abs(val), stx)\n                ], stx);\n            } else {\n                return mkSyntax(stx, val, parser.Token.NumericLiteral);\n            }\n        } else if (typeof val === 'string') {\n            return mkSyntax(stx, val, parser.Token.StringLiteral);\n        } else if (val === null) {\n            return mkSyntax(stx, 'null', parser.Token.NullLiteral);\n        } else {\n            throwSyntaxError('makeValue', 'Cannot make value syntax object from: ' + val);\n        }\n    }\n    function makeRegex(val, flags, stx) {\n        var newstx = mkSyntax(stx, new RegExp(val, flags), parser.Token.RegexLiteral);\n        // regex tokens need the extra field literal on token\n        newstx.token.literal = val;\n        return newstx;\n    }\n    function makeIdent(val, stx) {\n        return mkSyntax(stx, val, parser.Token.Identifier);\n    }\n    function makeKeyword(val, stx) {\n        return mkSyntax(stx, val, parser.Token.Keyword);\n    }\n    function makePunc(val, stx) {\n        return mkSyntax(stx, val, parser.Token.Punctuator);\n    }\n    function makeDelim(val, inner, stx) {\n        return mkSyntax(stx, val, parser.Token.Delimiter, inner);\n    }\n    function unwrapSyntax(stx) {\n        if (Array.isArray(stx) && stx.length === 1) {\n            // pull stx out of single element arrays for convenience\n            stx = stx[0];\n        }\n        if (stx.token) {\n            if (stx.token.type === parser.Token.Delimiter) {\n                return stx.token;\n            } else {\n                return stx.token.value;\n            }\n        } else {\n            throw new Error('Not a syntax object: ' + stx);\n        }\n    }\n    // ([...CSyntax]) -> [...CToken]\n    function syntaxToTokens(stx) {\n        return _.map(stx, function (stx$2) {\n            if (stx$2.token.inner) {\n                stx$2.token.inner = syntaxToTokens(stx$2.token.inner);\n            }\n            return stx$2.token;\n        });\n    }\n    // (CToken or [...CToken]) -> [...CSyntax]\n    function tokensToSyntax(tokens) {\n        if (!_.isArray(tokens)) {\n            tokens = [tokens];\n        }\n        return _.map(tokens, function (token) {\n            if (token.inner) {\n                token.inner = tokensToSyntax(token.inner);\n            }\n            return syntaxFromToken(token);\n        });\n    }\n    // ([...CSyntax], Str) -> [...CSyntax])\n    function joinSyntax(tojoin, punc) {\n        if (tojoin.length === 0) {\n            return [];\n        }\n        if (punc === ' ') {\n            return tojoin;\n        }\n        return _.reduce(_.rest(tojoin, 1), function (acc, join) {\n            acc.push(makePunc(punc, join), join);\n            return acc;\n        }, [_.first(tojoin)]);\n    }\n    // ([...[...CSyntax]], Str) -> [...CSyntax]\n    function joinSyntaxArray(tojoin, punc) {\n        if (tojoin.length === 0) {\n            return [];\n        }\n        if (punc === ' ') {\n            return _.flatten(tojoin, true);\n        }\n        return _.reduce(_.rest(tojoin, 1), function (acc, join) {\n            acc.push(makePunc(punc, _.first(join)));\n            Array.prototype.push.apply(acc, join);\n            return acc;\n        }, _.first(tojoin));\n    }\n    function cloneSyntaxArray(arr) {\n        return arr.map(function (stx) {\n            var o = syntaxFromToken(_.clone(stx.token), stx);\n            if (o.token.type === parser.Token.Delimiter) {\n                o.token.inner = cloneSyntaxArray(o.token.inner);\n            }\n            return o;\n        });\n    }\n    function MacroSyntaxError(name, message, stx) {\n        this.name = name;\n        this.message = message;\n        this.stx = stx;\n    }\n    function throwSyntaxError(name, message, stx) {\n        if (stx && Array.isArray(stx)) {\n            stx = stx[0];\n        }\n        throw new MacroSyntaxError(name, message, stx);\n    }\n    function SyntaxCaseError(message) {\n        this.message = message;\n    }\n    function throwSyntaxCaseError(message) {\n        throw new SyntaxCaseError(message);\n    }\n    function printSyntaxError(code, err) {\n        if (!err.stx) {\n            return '[' + err.name + '] ' + err.message;\n        }\n        var token = err.stx.token;\n        var lineNumber = token.sm_startLineNumber || token.sm_lineNumber || token.startLineNumber || token.lineNumber;\n        var lineStart = token.sm_startLineStart || token.sm_lineStart || token.startLineStart || token.lineStart;\n        var start = (token.sm_startRange || token.sm_range || token.startRange || token.range)[0];\n        var offset = start - lineStart;\n        var line = '';\n        var pre = lineNumber + ': ';\n        var ch;\n        while (ch = code.charAt(lineStart++)) {\n            if (ch == '\\r' || ch == '\\n') {\n                break;\n            }\n            line += ch;\n        }\n        return '[' + err.name + '] ' + err.message + '\\n' + pre + line + '\\n' + Array(offset + pre.length).join(' ') + ' ^';\n    }\n    // fun ([...CSyntax]) -> String\n    function prettyPrint(stxarr, shouldResolve) {\n        var indent = 0;\n        var unparsedLines = stxarr.reduce(function (acc, stx) {\n                var s = shouldResolve ? expander.resolve(stx) : stx.token.value;\n                // skip the end of file token\n                if (stx.token.type === parser.Token.EOF) {\n                    return acc;\n                }\n                if (stx.token.type === parser.Token.StringLiteral) {\n                    s = '\"' + s + '\"';\n                }\n                if (s == '{') {\n                    acc[0].str += ' ' + s;\n                    indent++;\n                    acc.unshift({\n                        indent: indent,\n                        str: ''\n                    });\n                } else if (s == '}') {\n                    indent--;\n                    acc.unshift({\n                        indent: indent,\n                        str: s\n                    });\n                    acc.unshift({\n                        indent: indent,\n                        str: ''\n                    });\n                } else if (s == ';') {\n                    acc[0].str += s;\n                    acc.unshift({\n                        indent: indent,\n                        str: ''\n                    });\n                } else {\n                    acc[0].str += (acc[0].str ? ' ' : '') + s;\n                }\n                return acc;\n            }, [{\n                    indent: 0,\n                    str: ''\n                }]);\n        return unparsedLines.reduce(function (acc, line) {\n            var ind = '';\n            while (ind.length < line.indent * 2) {\n                ind += ' ';\n            }\n            return ind + line.str + '\\n' + acc;\n        }, '');\n    }\n    exports$2.assert = assert;\n    exports$2.unwrapSyntax = unwrapSyntax;\n    exports$2.makeDelim = makeDelim;\n    exports$2.makePunc = makePunc;\n    exports$2.makeKeyword = makeKeyword;\n    exports$2.makeIdent = makeIdent;\n    exports$2.makeRegex = makeRegex;\n    exports$2.makeValue = makeValue;\n    exports$2.Rename = Rename;\n    exports$2.Mark = Mark;\n    exports$2.Def = Def;\n    exports$2.syntaxFromToken = syntaxFromToken;\n    exports$2.tokensToSyntax = tokensToSyntax;\n    exports$2.syntaxToTokens = syntaxToTokens;\n    exports$2.joinSyntax = joinSyntax;\n    exports$2.joinSyntaxArray = joinSyntaxArray;\n    exports$2.cloneSyntaxArray = cloneSyntaxArray;\n    exports$2.prettyPrint = prettyPrint;\n    exports$2.MacroSyntaxError = MacroSyntaxError;\n    exports$2.throwSyntaxError = throwSyntaxError;\n    exports$2.SyntaxCaseError = SyntaxCaseError;\n    exports$2.throwSyntaxCaseError = throwSyntaxCaseError;\n    exports$2.printSyntaxError = printSyntaxError;\n}));\n//# sourceMappingURL=syntax.js.map"
  },
  {
    "path": "docs/editor/scripts/text.js",
    "content": "/**\n * @license RequireJS text 2.0.10 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.\n * Available via the MIT or new BSD license.\n * see: http://github.com/requirejs/text for details\n */\n/*jslint regexp: true */\n/*global require, XMLHttpRequest, ActiveXObject,\n  define, window, process, Packages,\n  java, location, Components, FileUtils */\n\ndefine(['module'], function (module) {\n    'use strict';\n\n    var text, fs, Cc, Ci, xpcIsWindows,\n        progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'],\n        xmlRegExp = /^\\s*<\\?xml(\\s)+version=[\\'\\\"](\\d)*.(\\d)*[\\'\\\"](\\s)*\\?>/im,\n        bodyRegExp = /<body[^>]*>\\s*([\\s\\S]+)\\s*<\\/body>/im,\n        hasLocation = typeof location !== 'undefined' && location.href,\n        defaultProtocol = hasLocation && location.protocol && location.protocol.replace(/\\:/, ''),\n        defaultHostName = hasLocation && location.hostname,\n        defaultPort = hasLocation && (location.port || undefined),\n        buildMap = {},\n        masterConfig = (module.config && module.config()) || {};\n\n    text = {\n        version: '2.0.10',\n\n        strip: function (content) {\n            //Strips <?xml ...?> declarations so that external SVG and XML\n            //documents can be added to a document without worry. Also, if the string\n            //is an HTML document, only the part inside the body tag is returned.\n            if (content) {\n                content = content.replace(xmlRegExp, \"\");\n                var matches = content.match(bodyRegExp);\n                if (matches) {\n                    content = matches[1];\n                }\n            } else {\n                content = \"\";\n            }\n            return content;\n        },\n\n        jsEscape: function (content) {\n            return content.replace(/(['\\\\])/g, '\\\\$1')\n                .replace(/[\\f]/g, \"\\\\f\")\n                .replace(/[\\b]/g, \"\\\\b\")\n                .replace(/[\\n]/g, \"\\\\n\")\n                .replace(/[\\t]/g, \"\\\\t\")\n                .replace(/[\\r]/g, \"\\\\r\")\n                .replace(/[\\u2028]/g, \"\\\\u2028\")\n                .replace(/[\\u2029]/g, \"\\\\u2029\");\n        },\n\n        createXhr: masterConfig.createXhr || function () {\n            //Would love to dump the ActiveX crap in here. Need IE 6 to die first.\n            var xhr, i, progId;\n            if (typeof XMLHttpRequest !== \"undefined\") {\n                return new XMLHttpRequest();\n            } else if (typeof ActiveXObject !== \"undefined\") {\n                for (i = 0; i < 3; i += 1) {\n                    progId = progIds[i];\n                    try {\n                        xhr = new ActiveXObject(progId);\n                    } catch (e) {}\n\n                    if (xhr) {\n                        progIds = [progId];  // so faster next time\n                        break;\n                    }\n                }\n            }\n\n            return xhr;\n        },\n\n        /**\n         * Parses a resource name into its component parts. Resource names\n         * look like: module/name.ext!strip, where the !strip part is\n         * optional.\n         * @param {String} name the resource name\n         * @returns {Object} with properties \"moduleName\", \"ext\" and \"strip\"\n         * where strip is a boolean.\n         */\n        parseName: function (name) {\n            var modName, ext, temp,\n                strip = false,\n                index = name.indexOf(\".\"),\n                isRelative = name.indexOf('./') === 0 ||\n                             name.indexOf('../') === 0;\n\n            if (index !== -1 && (!isRelative || index > 1)) {\n                modName = name.substring(0, index);\n                ext = name.substring(index + 1, name.length);\n            } else {\n                modName = name;\n            }\n\n            temp = ext || modName;\n            index = temp.indexOf(\"!\");\n            if (index !== -1) {\n                //Pull off the strip arg.\n                strip = temp.substring(index + 1) === \"strip\";\n                temp = temp.substring(0, index);\n                if (ext) {\n                    ext = temp;\n                } else {\n                    modName = temp;\n                }\n            }\n\n            return {\n                moduleName: modName,\n                ext: ext,\n                strip: strip\n            };\n        },\n\n        xdRegExp: /^((\\w+)\\:)?\\/\\/([^\\/\\\\]+)/,\n\n        /**\n         * Is an URL on another domain. Only works for browser use, returns\n         * false in non-browser environments. Only used to know if an\n         * optimized .js version of a text resource should be loaded\n         * instead.\n         * @param {String} url\n         * @returns Boolean\n         */\n        useXhr: function (url, protocol, hostname, port) {\n            var uProtocol, uHostName, uPort,\n                match = text.xdRegExp.exec(url);\n            if (!match) {\n                return true;\n            }\n            uProtocol = match[2];\n            uHostName = match[3];\n\n            uHostName = uHostName.split(':');\n            uPort = uHostName[1];\n            uHostName = uHostName[0];\n\n            return (!uProtocol || uProtocol === protocol) &&\n                   (!uHostName || uHostName.toLowerCase() === hostname.toLowerCase()) &&\n                   ((!uPort && !uHostName) || uPort === port);\n        },\n\n        finishLoad: function (name, strip, content, onLoad) {\n            content = strip ? text.strip(content) : content;\n            if (masterConfig.isBuild) {\n                buildMap[name] = content;\n            }\n            onLoad(content);\n        },\n\n        load: function (name, req, onLoad, config) {\n            //Name has format: some.module.filext!strip\n            //The strip part is optional.\n            //if strip is present, then that means only get the string contents\n            //inside a body tag in an HTML string. For XML/SVG content it means\n            //removing the <?xml ...?> declarations so the content can be inserted\n            //into the current doc without problems.\n\n            // Do not bother with the work if a build and text will\n            // not be inlined.\n            if (config.isBuild && !config.inlineText) {\n                onLoad();\n                return;\n            }\n\n            masterConfig.isBuild = config.isBuild;\n\n            var parsed = text.parseName(name),\n                nonStripName = parsed.moduleName +\n                    (parsed.ext ? '.' + parsed.ext : ''),\n                url = req.toUrl(nonStripName),\n                useXhr = (masterConfig.useXhr) ||\n                         text.useXhr;\n\n            // Do not load if it is an empty: url\n            if (url.indexOf('empty:') === 0) {\n                onLoad();\n                return;\n            }\n\n            //Load the text. Use XHR if possible and in a browser.\n            if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) {\n                text.get(url, function (content) {\n                    text.finishLoad(name, parsed.strip, content, onLoad);\n                }, function (err) {\n                    if (onLoad.error) {\n                        onLoad.error(err);\n                    }\n                });\n            } else {\n                //Need to fetch the resource across domains. Assume\n                //the resource has been optimized into a JS module. Fetch\n                //by the module name + extension, but do not include the\n                //!strip part to avoid file system issues.\n                req([nonStripName], function (content) {\n                    text.finishLoad(parsed.moduleName + '.' + parsed.ext,\n                                    parsed.strip, content, onLoad);\n                });\n            }\n        },\n\n        write: function (pluginName, moduleName, write, config) {\n            if (buildMap.hasOwnProperty(moduleName)) {\n                var content = text.jsEscape(buildMap[moduleName]);\n                write.asModule(pluginName + \"!\" + moduleName,\n                               \"define(function () { return '\" +\n                                   content +\n                               \"';});\\n\");\n            }\n        },\n\n        writeFile: function (pluginName, moduleName, req, write, config) {\n            var parsed = text.parseName(moduleName),\n                extPart = parsed.ext ? '.' + parsed.ext : '',\n                nonStripName = parsed.moduleName + extPart,\n                //Use a '.js' file name so that it indicates it is a\n                //script that can be loaded across domains.\n                fileName = req.toUrl(parsed.moduleName + extPart) + '.js';\n\n            //Leverage own load() method to load plugin value, but only\n            //write out values that do not have the strip argument,\n            //to avoid any potential issues with ! in file names.\n            text.load(nonStripName, req, function (value) {\n                //Use own write() method to construct full module value.\n                //But need to create shell that translates writeFile's\n                //write() to the right interface.\n                var textWrite = function (contents) {\n                    return write(fileName, contents);\n                };\n                textWrite.asModule = function (moduleName, contents) {\n                    return write.asModule(moduleName, fileName, contents);\n                };\n\n                text.write(pluginName, nonStripName, textWrite, config);\n            }, config);\n        }\n    };\n\n    if (masterConfig.env === 'node' || (!masterConfig.env &&\n            typeof process !== \"undefined\" &&\n            process.versions &&\n            !!process.versions.node &&\n            !process.versions['node-webkit'])) {\n        //Using special require.nodeRequire, something added by r.js.\n        fs = require.nodeRequire('fs');\n\n        text.get = function (url, callback, errback) {\n            try {\n                var file = fs.readFileSync(url, 'utf8');\n                //Remove BOM (Byte Mark Order) from utf8 files if it is there.\n                if (file.indexOf('\\uFEFF') === 0) {\n                    file = file.substring(1);\n                }\n                callback(file);\n            } catch (e) {\n                errback(e);\n            }\n        };\n    } else if (masterConfig.env === 'xhr' || (!masterConfig.env &&\n            text.createXhr())) {\n        text.get = function (url, callback, errback, headers) {\n            var xhr = text.createXhr(), header;\n            xhr.open('GET', url, true);\n\n            //Allow plugins direct access to xhr headers\n            if (headers) {\n                for (header in headers) {\n                    if (headers.hasOwnProperty(header)) {\n                        xhr.setRequestHeader(header.toLowerCase(), headers[header]);\n                    }\n                }\n            }\n\n            //Allow overrides specified in config\n            if (masterConfig.onXhr) {\n                masterConfig.onXhr(xhr, url);\n            }\n\n            xhr.onreadystatechange = function (evt) {\n                var status, err;\n                //Do not explicitly handle errors, those should be\n                //visible via console output in the browser.\n                if (xhr.readyState === 4) {\n                    status = xhr.status;\n                    if (status > 399 && status < 600) {\n                        //An http 4xx or 5xx error. Signal an error.\n                        err = new Error(url + ' HTTP status: ' + status);\n                        err.xhr = xhr;\n                        errback(err);\n                    } else {\n                        callback(xhr.responseText);\n                    }\n\n                    if (masterConfig.onXhrComplete) {\n                        masterConfig.onXhrComplete(xhr, url);\n                    }\n                }\n            };\n            xhr.send(null);\n        };\n    } else if (masterConfig.env === 'rhino' || (!masterConfig.env &&\n            typeof Packages !== 'undefined' && typeof java !== 'undefined')) {\n        //Why Java, why is this so awkward?\n        text.get = function (url, callback) {\n            var stringBuffer, line,\n                encoding = \"utf-8\",\n                file = new java.io.File(url),\n                lineSeparator = java.lang.System.getProperty(\"line.separator\"),\n                input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)),\n                content = '';\n            try {\n                stringBuffer = new java.lang.StringBuffer();\n                line = input.readLine();\n\n                // Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324\n                // http://www.unicode.org/faq/utf_bom.html\n\n                // Note that when we use utf-8, the BOM should appear as \"EF BB BF\", but it doesn't due to this bug in the JDK:\n                // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058\n                if (line && line.length() && line.charAt(0) === 0xfeff) {\n                    // Eat the BOM, since we've already found the encoding on this file,\n                    // and we plan to concatenating this buffer with others; the BOM should\n                    // only appear at the top of a file.\n                    line = line.substring(1);\n                }\n\n                if (line !== null) {\n                    stringBuffer.append(line);\n                }\n\n                while ((line = input.readLine()) !== null) {\n                    stringBuffer.append(lineSeparator);\n                    stringBuffer.append(line);\n                }\n                //Make sure we return a JavaScript string and not a Java string.\n                content = String(stringBuffer.toString()); //String\n            } finally {\n                input.close();\n            }\n            callback(content);\n        };\n    } else if (masterConfig.env === 'xpconnect' || (!masterConfig.env &&\n            typeof Components !== 'undefined' && Components.classes &&\n            Components.interfaces)) {\n        //Avert your gaze!\n        Cc = Components.classes,\n        Ci = Components.interfaces;\n        Components.utils['import']('resource://gre/modules/FileUtils.jsm');\n        xpcIsWindows = ('@mozilla.org/windows-registry-key;1' in Cc);\n\n        text.get = function (url, callback) {\n            var inStream, convertStream, fileObj,\n                readData = {};\n\n            if (xpcIsWindows) {\n                url = url.replace(/\\//g, '\\\\');\n            }\n\n            fileObj = new FileUtils.File(url);\n\n            //XPCOM, you so crazy\n            try {\n                inStream = Cc['@mozilla.org/network/file-input-stream;1']\n                           .createInstance(Ci.nsIFileInputStream);\n                inStream.init(fileObj, 1, 0, false);\n\n                convertStream = Cc['@mozilla.org/intl/converter-input-stream;1']\n                                .createInstance(Ci.nsIConverterInputStream);\n                convertStream.init(inStream, \"utf-8\", inStream.available(),\n                Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);\n\n                convertStream.readString(inStream.available(), readData);\n                convertStream.close();\n                inStream.close();\n                callback(readData.value);\n            } catch (e) {\n                throw new Error((fileObj && fileObj.path || '') + ': ' + e);\n            }\n        };\n    }\n    return text;\n});\n"
  },
  {
    "path": "docs/editor/scripts/underscore.js",
    "content": "//     Underscore.js 1.4.2\n//     http://underscorejs.org\n//     (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.\n//     Underscore may be freely distributed under the MIT license.\n\n(function() {\n\n  // Baseline setup\n  // --------------\n\n  // Establish the root object, `window` in the browser, or `global` on the server.\n  var root = this;\n\n  // Save the previous value of the `_` variable.\n  var previousUnderscore = root._;\n\n  // Establish the object that gets returned to break out of a loop iteration.\n  var breaker = {};\n\n  // Save bytes in the minified (but not gzipped) version:\n  var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;\n\n  // Create quick reference variables for speed access to core prototypes.\n  var push             = ArrayProto.push,\n      slice            = ArrayProto.slice,\n      concat           = ArrayProto.concat,\n      unshift          = ArrayProto.unshift,\n      toString         = ObjProto.toString,\n      hasOwnProperty   = ObjProto.hasOwnProperty;\n\n  // All **ECMAScript 5** native function implementations that we hope to use\n  // are declared here.\n  var\n    nativeForEach      = ArrayProto.forEach,\n    nativeMap          = ArrayProto.map,\n    nativeReduce       = ArrayProto.reduce,\n    nativeReduceRight  = ArrayProto.reduceRight,\n    nativeFilter       = ArrayProto.filter,\n    nativeEvery        = ArrayProto.every,\n    nativeSome         = ArrayProto.some,\n    nativeIndexOf      = ArrayProto.indexOf,\n    nativeLastIndexOf  = ArrayProto.lastIndexOf,\n    nativeIsArray      = Array.isArray,\n    nativeKeys         = Object.keys,\n    nativeBind         = FuncProto.bind;\n\n  // Create a safe reference to the Underscore object for use below.\n  var _ = function(obj) {\n    if (obj instanceof _) return obj;\n    if (!(this instanceof _)) return new _(obj);\n    this._wrapped = obj;\n  };\n\n  // Export the Underscore object for **Node.js**, with\n  // backwards-compatibility for the old `require()` API. If we're in\n  // the browser, add `_` as a global object via a string identifier,\n  // for Closure Compiler \"advanced\" mode.\n  if (typeof exports !== 'undefined') {\n    if (typeof module !== 'undefined' && module.exports) {\n      exports = module.exports = _;\n    }\n    exports._ = _;\n  } else {\n    root['_'] = _;\n  }\n\n  // Current version.\n  _.VERSION = '1.4.2';\n\n  // Collection Functions\n  // --------------------\n\n  // The cornerstone, an `each` implementation, aka `forEach`.\n  // Handles objects with the built-in `forEach`, arrays, and raw objects.\n  // Delegates to **ECMAScript 5**'s native `forEach` if available.\n  var each = _.each = _.forEach = function(obj, iterator, context) {\n    if (obj == null) return;\n    if (nativeForEach && obj.forEach === nativeForEach) {\n      obj.forEach(iterator, context);\n    } else if (obj.length === +obj.length) {\n      for (var i = 0, l = obj.length; i < l; i++) {\n        if (iterator.call(context, obj[i], i, obj) === breaker) return;\n      }\n    } else {\n      for (var key in obj) {\n        if (_.has(obj, key)) {\n          if (iterator.call(context, obj[key], key, obj) === breaker) return;\n        }\n      }\n    }\n  };\n\n  // Return the results of applying the iterator to each element.\n  // Delegates to **ECMAScript 5**'s native `map` if available.\n  _.map = _.collect = function(obj, iterator, context) {\n    var results = [];\n    if (obj == null) return results;\n    if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);\n    each(obj, function(value, index, list) {\n      results[results.length] = iterator.call(context, value, index, list);\n    });\n    return results;\n  };\n\n  // **Reduce** builds up a single result from a list of values, aka `inject`,\n  // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.\n  _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {\n    var initial = arguments.length > 2;\n    if (obj == null) obj = [];\n    if (nativeReduce && obj.reduce === nativeReduce) {\n      if (context) iterator = _.bind(iterator, context);\n      return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);\n    }\n    each(obj, function(value, index, list) {\n      if (!initial) {\n        memo = value;\n        initial = true;\n      } else {\n        memo = iterator.call(context, memo, value, index, list);\n      }\n    });\n    if (!initial) throw new TypeError('Reduce of empty array with no initial value');\n    return memo;\n  };\n\n  // The right-associative version of reduce, also known as `foldr`.\n  // Delegates to **ECMAScript 5**'s native `reduceRight` if available.\n  _.reduceRight = _.foldr = function(obj, iterator, memo, context) {\n    var initial = arguments.length > 2;\n    if (obj == null) obj = [];\n    if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {\n      if (context) iterator = _.bind(iterator, context);\n      return arguments.length > 2 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);\n    }\n    var length = obj.length;\n    if (length !== +length) {\n      var keys = _.keys(obj);\n      length = keys.length;\n    }\n    each(obj, function(value, index, list) {\n      index = keys ? keys[--length] : --length;\n      if (!initial) {\n        memo = obj[index];\n        initial = true;\n      } else {\n        memo = iterator.call(context, memo, obj[index], index, list);\n      }\n    });\n    if (!initial) throw new TypeError('Reduce of empty array with no initial value');\n    return memo;\n  };\n\n  // Return the first value which passes a truth test. Aliased as `detect`.\n  _.find = _.detect = function(obj, iterator, context) {\n    var result;\n    any(obj, function(value, index, list) {\n      if (iterator.call(context, value, index, list)) {\n        result = value;\n        return true;\n      }\n    });\n    return result;\n  };\n\n  // Return all the elements that pass a truth test.\n  // Delegates to **ECMAScript 5**'s native `filter` if available.\n  // Aliased as `select`.\n  _.filter = _.select = function(obj, iterator, context) {\n    var results = [];\n    if (obj == null) return results;\n    if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);\n    each(obj, function(value, index, list) {\n      if (iterator.call(context, value, index, list)) results[results.length] = value;\n    });\n    return results;\n  };\n\n  // Return all the elements for which a truth test fails.\n  _.reject = function(obj, iterator, context) {\n    return _.filter(obj, function(value, index, list) {\n      return !iterator.call(context, value, index, list);\n    }, context);\n  };\n\n  // Determine whether all of the elements match a truth test.\n  // Delegates to **ECMAScript 5**'s native `every` if available.\n  // Aliased as `all`.\n  _.every = _.all = function(obj, iterator, context) {\n    iterator || (iterator = _.identity);\n    var result = true;\n    if (obj == null) return result;\n    if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);\n    each(obj, function(value, index, list) {\n      if (!(result = result && iterator.call(context, value, index, list))) return breaker;\n    });\n    return !!result;\n  };\n\n  // Determine if at least one element in the object matches a truth test.\n  // Delegates to **ECMAScript 5**'s native `some` if available.\n  // Aliased as `any`.\n  var any = _.some = _.any = function(obj, iterator, context) {\n    iterator || (iterator = _.identity);\n    var result = false;\n    if (obj == null) return result;\n    if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);\n    each(obj, function(value, index, list) {\n      if (result || (result = iterator.call(context, value, index, list))) return breaker;\n    });\n    return !!result;\n  };\n\n  // Determine if the array or object contains a given value (using `===`).\n  // Aliased as `include`.\n  _.contains = _.include = function(obj, target) {\n    var found = false;\n    if (obj == null) return found;\n    if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;\n    found = any(obj, function(value) {\n      return value === target;\n    });\n    return found;\n  };\n\n  // Invoke a method (with arguments) on every item in a collection.\n  _.invoke = function(obj, method) {\n    var args = slice.call(arguments, 2);\n    return _.map(obj, function(value) {\n      return (_.isFunction(method) ? method : value[method]).apply(value, args);\n    });\n  };\n\n  // Convenience version of a common use case of `map`: fetching a property.\n  _.pluck = function(obj, key) {\n    return _.map(obj, function(value){ return value[key]; });\n  };\n\n  // Convenience version of a common use case of `filter`: selecting only objects\n  // with specific `key:value` pairs.\n  _.where = function(obj, attrs) {\n    if (_.isEmpty(attrs)) return [];\n    return _.filter(obj, function(value) {\n      for (var key in attrs) {\n        if (attrs[key] !== value[key]) return false;\n      }\n      return true;\n    });\n  };\n\n  // Return the maximum element or (element-based computation).\n  // Can't optimize arrays of integers longer than 65,535 elements.\n  // See: https://bugs.webkit.org/show_bug.cgi?id=80797\n  _.max = function(obj, iterator, context) {\n    if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {\n      return Math.max.apply(Math, obj);\n    }\n    if (!iterator && _.isEmpty(obj)) return -Infinity;\n    var result = {computed : -Infinity};\n    each(obj, function(value, index, list) {\n      var computed = iterator ? iterator.call(context, value, index, list) : value;\n      computed >= result.computed && (result = {value : value, computed : computed});\n    });\n    return result.value;\n  };\n\n  // Return the minimum element (or element-based computation).\n  _.min = function(obj, iterator, context) {\n    if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {\n      return Math.min.apply(Math, obj);\n    }\n    if (!iterator && _.isEmpty(obj)) return Infinity;\n    var result = {computed : Infinity};\n    each(obj, function(value, index, list) {\n      var computed = iterator ? iterator.call(context, value, index, list) : value;\n      computed < result.computed && (result = {value : value, computed : computed});\n    });\n    return result.value;\n  };\n\n  // Shuffle an array.\n  _.shuffle = function(obj) {\n    var rand;\n    var index = 0;\n    var shuffled = [];\n    each(obj, function(value) {\n      rand = _.random(index++);\n      shuffled[index - 1] = shuffled[rand];\n      shuffled[rand] = value;\n    });\n    return shuffled;\n  };\n\n  // An internal function to generate lookup iterators.\n  var lookupIterator = function(value) {\n    return _.isFunction(value) ? value : function(obj){ return obj[value]; };\n  };\n\n  // Sort the object's values by a criterion produced by an iterator.\n  _.sortBy = function(obj, value, context) {\n    var iterator = lookupIterator(value);\n    return _.pluck(_.map(obj, function(value, index, list) {\n      return {\n        value : value,\n        index : index,\n        criteria : iterator.call(context, value, index, list)\n      };\n    }).sort(function(left, right) {\n      var a = left.criteria;\n      var b = right.criteria;\n      if (a !== b) {\n        if (a > b || a === void 0) return 1;\n        if (a < b || b === void 0) return -1;\n      }\n      return left.index < right.index ? -1 : 1;\n    }), 'value');\n  };\n\n  // An internal function used for aggregate \"group by\" operations.\n  var group = function(obj, value, context, behavior) {\n    var result = {};\n    var iterator = lookupIterator(value);\n    each(obj, function(value, index) {\n      var key = iterator.call(context, value, index, obj);\n      behavior(result, key, value);\n    });\n    return result;\n  };\n\n  // Groups the object's values by a criterion. Pass either a string attribute\n  // to group by, or a function that returns the criterion.\n  _.groupBy = function(obj, value, context) {\n    return group(obj, value, context, function(result, key, value) {\n      (_.has(result, key) ? result[key] : (result[key] = [])).push(value);\n    });\n  };\n\n  // Counts instances of an object that group by a certain criterion. Pass\n  // either a string attribute to count by, or a function that returns the\n  // criterion.\n  _.countBy = function(obj, value, context) {\n    return group(obj, value, context, function(result, key, value) {\n      if (!_.has(result, key)) result[key] = 0;\n      result[key]++;\n    });\n  };\n\n  // Use a comparator function to figure out the smallest index at which\n  // an object should be inserted so as to maintain order. Uses binary search.\n  _.sortedIndex = function(array, obj, iterator, context) {\n    iterator = iterator == null ? _.identity : lookupIterator(iterator);\n    var value = iterator.call(context, obj);\n    var low = 0, high = array.length;\n    while (low < high) {\n      var mid = (low + high) >>> 1;\n      iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;\n    }\n    return low;\n  };\n\n  // Safely convert anything iterable into a real, live array.\n  _.toArray = function(obj) {\n    if (!obj) return [];\n    if (obj.length === +obj.length) return slice.call(obj);\n    return _.values(obj);\n  };\n\n  // Return the number of elements in an object.\n  _.size = function(obj) {\n    if (obj == null) return 0;\n    return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;\n  };\n\n  // Array Functions\n  // ---------------\n\n  // Get the first element of an array. Passing **n** will return the first N\n  // values in the array. Aliased as `head` and `take`. The **guard** check\n  // allows it to work with `_.map`.\n  _.first = _.head = _.take = function(array, n, guard) {\n    if (array == null) return void 0;\n    return (n != null) && !guard ? slice.call(array, 0, n) : array[0];\n  };\n\n  // Returns everything but the last entry of the array. Especially useful on\n  // the arguments object. Passing **n** will return all the values in\n  // the array, excluding the last N. The **guard** check allows it to work with\n  // `_.map`.\n  _.initial = function(array, n, guard) {\n    return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));\n  };\n\n  // Get the last element of an array. Passing **n** will return the last N\n  // values in the array. The **guard** check allows it to work with `_.map`.\n  _.last = function(array, n, guard) {\n    if (array == null) return void 0;\n    if ((n != null) && !guard) {\n      return slice.call(array, Math.max(array.length - n, 0));\n    } else {\n      return array[array.length - 1];\n    }\n  };\n\n  // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.\n  // Especially useful on the arguments object. Passing an **n** will return\n  // the rest N values in the array. The **guard**\n  // check allows it to work with `_.map`.\n  _.rest = _.tail = _.drop = function(array, n, guard) {\n    return slice.call(array, (n == null) || guard ? 1 : n);\n  };\n\n  // Trim out all falsy values from an array.\n  _.compact = function(array) {\n    return _.filter(array, function(value){ return !!value; });\n  };\n\n  // Internal implementation of a recursive `flatten` function.\n  var flatten = function(input, shallow, output) {\n    each(input, function(value) {\n      if (_.isArray(value)) {\n        shallow ? push.apply(output, value) : flatten(value, shallow, output);\n      } else {\n        output.push(value);\n      }\n    });\n    return output;\n  };\n\n  // Return a completely flattened version of an array.\n  _.flatten = function(array, shallow) {\n    return flatten(array, shallow, []);\n  };\n\n  // Return a version of the array that does not contain the specified value(s).\n  _.without = function(array) {\n    return _.difference(array, slice.call(arguments, 1));\n  };\n\n  // Produce a duplicate-free version of the array. If the array has already\n  // been sorted, you have the option of using a faster algorithm.\n  // Aliased as `unique`.\n  _.uniq = _.unique = function(array, isSorted, iterator, context) {\n    var initial = iterator ? _.map(array, iterator, context) : array;\n    var results = [];\n    var seen = [];\n    each(initial, function(value, index) {\n      if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {\n        seen.push(value);\n        results.push(array[index]);\n      }\n    });\n    return results;\n  };\n\n  // Produce an array that contains the union: each distinct element from all of\n  // the passed-in arrays.\n  _.union = function() {\n    return _.uniq(concat.apply(ArrayProto, arguments));\n  };\n\n  // Produce an array that contains every item shared between all the\n  // passed-in arrays.\n  _.intersection = function(array) {\n    var rest = slice.call(arguments, 1);\n    return _.filter(_.uniq(array), function(item) {\n      return _.every(rest, function(other) {\n        return _.indexOf(other, item) >= 0;\n      });\n    });\n  };\n\n  // Take the difference between one array and a number of other arrays.\n  // Only the elements present in just the first array will remain.\n  _.difference = function(array) {\n    var rest = concat.apply(ArrayProto, slice.call(arguments, 1));\n    return _.filter(array, function(value){ return !_.contains(rest, value); });\n  };\n\n  // Zip together multiple lists into a single array -- elements that share\n  // an index go together.\n  _.zip = function() {\n    var args = slice.call(arguments);\n    var length = _.max(_.pluck(args, 'length'));\n    var results = new Array(length);\n    for (var i = 0; i < length; i++) {\n      results[i] = _.pluck(args, \"\" + i);\n    }\n    return results;\n  };\n\n  // Converts lists into objects. Pass either a single array of `[key, value]`\n  // pairs, or two parallel arrays of the same length -- one of keys, and one of\n  // the corresponding values.\n  _.object = function(list, values) {\n    if (list == null) return {};\n    var result = {};\n    for (var i = 0, l = list.length; i < l; i++) {\n      if (values) {\n        result[list[i]] = values[i];\n      } else {\n        result[list[i][0]] = list[i][1];\n      }\n    }\n    return result;\n  };\n\n  // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),\n  // we need this function. Return the position of the first occurrence of an\n  // item in an array, or -1 if the item is not included in the array.\n  // Delegates to **ECMAScript 5**'s native `indexOf` if available.\n  // If the array is large and already in sort order, pass `true`\n  // for **isSorted** to use binary search.\n  _.indexOf = function(array, item, isSorted) {\n    if (array == null) return -1;\n    var i = 0, l = array.length;\n    if (isSorted) {\n      if (typeof isSorted == 'number') {\n        i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);\n      } else {\n        i = _.sortedIndex(array, item);\n        return array[i] === item ? i : -1;\n      }\n    }\n    if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);\n    for (; i < l; i++) if (array[i] === item) return i;\n    return -1;\n  };\n\n  // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.\n  _.lastIndexOf = function(array, item, from) {\n    if (array == null) return -1;\n    var hasIndex = from != null;\n    if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {\n      return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);\n    }\n    var i = (hasIndex ? from : array.length);\n    while (i--) if (array[i] === item) return i;\n    return -1;\n  };\n\n  // Generate an integer Array containing an arithmetic progression. A port of\n  // the native Python `range()` function. See\n  // [the Python documentation](http://docs.python.org/library/functions.html#range).\n  _.range = function(start, stop, step) {\n    if (arguments.length <= 1) {\n      stop = start || 0;\n      start = 0;\n    }\n    step = arguments[2] || 1;\n\n    var len = Math.max(Math.ceil((stop - start) / step), 0);\n    var idx = 0;\n    var range = new Array(len);\n\n    while(idx < len) {\n      range[idx++] = start;\n      start += step;\n    }\n\n    return range;\n  };\n\n  // Function (ahem) Functions\n  // ------------------\n\n  // Reusable constructor function for prototype setting.\n  var ctor = function(){};\n\n  // Create a function bound to a given object (assigning `this`, and arguments,\n  // optionally). Binding with arguments is also known as `curry`.\n  // Delegates to **ECMAScript 5**'s native `Function.bind` if available.\n  // We check for `func.bind` first, to fail fast when `func` is undefined.\n  _.bind = function bind(func, context) {\n    var bound, args;\n    if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));\n    if (!_.isFunction(func)) throw new TypeError;\n    args = slice.call(arguments, 2);\n    return bound = function() {\n      if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));\n      ctor.prototype = func.prototype;\n      var self = new ctor;\n      var result = func.apply(self, args.concat(slice.call(arguments)));\n      if (Object(result) === result) return result;\n      return self;\n    };\n  };\n\n  // Bind all of an object's methods to that object. Useful for ensuring that\n  // all callbacks defined on an object belong to it.\n  _.bindAll = function(obj) {\n    var funcs = slice.call(arguments, 1);\n    if (funcs.length == 0) funcs = _.functions(obj);\n    each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });\n    return obj;\n  };\n\n  // Memoize an expensive function by storing its results.\n  _.memoize = function(func, hasher) {\n    var memo = {};\n    hasher || (hasher = _.identity);\n    return function() {\n      var key = hasher.apply(this, arguments);\n      return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));\n    };\n  };\n\n  // Delays a function for the given number of milliseconds, and then calls\n  // it with the arguments supplied.\n  _.delay = function(func, wait) {\n    var args = slice.call(arguments, 2);\n    return setTimeout(function(){ return func.apply(null, args); }, wait);\n  };\n\n  // Defers a function, scheduling it to run after the current call stack has\n  // cleared.\n  _.defer = function(func) {\n    return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));\n  };\n\n  // Returns a function, that, when invoked, will only be triggered at most once\n  // during a given window of time.\n  _.throttle = function(func, wait) {\n    var context, args, timeout, result;\n    var previous = 0;\n    var later = function() {\n      previous = new Date;\n      timeout = null;\n      result = func.apply(context, args);\n    };\n    return function() {\n      var now = new Date;\n      var remaining = wait - (now - previous);\n      context = this;\n      args = arguments;\n      if (remaining <= 0) {\n        clearTimeout(timeout);\n        previous = now;\n        result = func.apply(context, args);\n      } else if (!timeout) {\n        timeout = setTimeout(later, remaining);\n      }\n      return result;\n    };\n  };\n\n  // Returns a function, that, as long as it continues to be invoked, will not\n  // be triggered. The function will be called after it stops being called for\n  // N milliseconds. If `immediate` is passed, trigger the function on the\n  // leading edge, instead of the trailing.\n  _.debounce = function(func, wait, immediate) {\n    var timeout, result;\n    return function() {\n      var context = this, args = arguments;\n      var later = function() {\n        timeout = null;\n        if (!immediate) result = func.apply(context, args);\n      };\n      var callNow = immediate && !timeout;\n      clearTimeout(timeout);\n      timeout = setTimeout(later, wait);\n      if (callNow) result = func.apply(context, args);\n      return result;\n    };\n  };\n\n  // Returns a function that will be executed at most one time, no matter how\n  // often you call it. Useful for lazy initialization.\n  _.once = function(func) {\n    var ran = false, memo;\n    return function() {\n      if (ran) return memo;\n      ran = true;\n      memo = func.apply(this, arguments);\n      func = null;\n      return memo;\n    };\n  };\n\n  // Returns the first function passed as an argument to the second,\n  // allowing you to adjust arguments, run code before and after, and\n  // conditionally execute the original function.\n  _.wrap = function(func, wrapper) {\n    return function() {\n      var args = [func];\n      push.apply(args, arguments);\n      return wrapper.apply(this, args);\n    };\n  };\n\n  // Returns a function that is the composition of a list of functions, each\n  // consuming the return value of the function that follows.\n  _.compose = function() {\n    var funcs = arguments;\n    return function() {\n      var args = arguments;\n      for (var i = funcs.length - 1; i >= 0; i--) {\n        args = [funcs[i].apply(this, args)];\n      }\n      return args[0];\n    };\n  };\n\n  // Returns a function that will only be executed after being called N times.\n  _.after = function(times, func) {\n    if (times <= 0) return func();\n    return function() {\n      if (--times < 1) {\n        return func.apply(this, arguments);\n      }\n    };\n  };\n\n  // Object Functions\n  // ----------------\n\n  // Retrieve the names of an object's properties.\n  // Delegates to **ECMAScript 5**'s native `Object.keys`\n  _.keys = nativeKeys || function(obj) {\n    if (obj !== Object(obj)) throw new TypeError('Invalid object');\n    var keys = [];\n    for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;\n    return keys;\n  };\n\n  // Retrieve the values of an object's properties.\n  _.values = function(obj) {\n    var values = [];\n    for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);\n    return values;\n  };\n\n  // Convert an object into a list of `[key, value]` pairs.\n  _.pairs = function(obj) {\n    var pairs = [];\n    for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);\n    return pairs;\n  };\n\n  // Invert the keys and values of an object. The values must be serializable.\n  _.invert = function(obj) {\n    var result = {};\n    for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;\n    return result;\n  };\n\n  // Return a sorted list of the function names available on the object.\n  // Aliased as `methods`\n  _.functions = _.methods = function(obj) {\n    var names = [];\n    for (var key in obj) {\n      if (_.isFunction(obj[key])) names.push(key);\n    }\n    return names.sort();\n  };\n\n  // Extend a given object with all the properties in passed-in object(s).\n  _.extend = function(obj) {\n    each(slice.call(arguments, 1), function(source) {\n      for (var prop in source) {\n        obj[prop] = source[prop];\n      }\n    });\n    return obj;\n  };\n\n  // Return a copy of the object only containing the whitelisted properties.\n  _.pick = function(obj) {\n    var copy = {};\n    var keys = concat.apply(ArrayProto, slice.call(arguments, 1));\n    each(keys, function(key) {\n      if (key in obj) copy[key] = obj[key];\n    });\n    return copy;\n  };\n\n   // Return a copy of the object without the blacklisted properties.\n  _.omit = function(obj) {\n    var copy = {};\n    var keys = concat.apply(ArrayProto, slice.call(arguments, 1));\n    for (var key in obj) {\n      if (!_.contains(keys, key)) copy[key] = obj[key];\n    }\n    return copy;\n  };\n\n  // Fill in a given object with default properties.\n  _.defaults = function(obj) {\n    each(slice.call(arguments, 1), function(source) {\n      for (var prop in source) {\n        if (obj[prop] == null) obj[prop] = source[prop];\n      }\n    });\n    return obj;\n  };\n\n  // Create a (shallow-cloned) duplicate of an object.\n  _.clone = function(obj) {\n    if (!_.isObject(obj)) return obj;\n    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);\n  };\n\n  // Invokes interceptor with the obj, and then returns obj.\n  // The primary purpose of this method is to \"tap into\" a method chain, in\n  // order to perform operations on intermediate results within the chain.\n  _.tap = function(obj, interceptor) {\n    interceptor(obj);\n    return obj;\n  };\n\n  // Internal recursive comparison function for `isEqual`.\n  var eq = function(a, b, aStack, bStack) {\n    // Identical objects are equal. `0 === -0`, but they aren't identical.\n    // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.\n    if (a === b) return a !== 0 || 1 / a == 1 / b;\n    // A strict comparison is necessary because `null == undefined`.\n    if (a == null || b == null) return a === b;\n    // Unwrap any wrapped objects.\n    if (a instanceof _) a = a._wrapped;\n    if (b instanceof _) b = b._wrapped;\n    // Compare `[[Class]]` names.\n    var className = toString.call(a);\n    if (className != toString.call(b)) return false;\n    switch (className) {\n      // Strings, numbers, dates, and booleans are compared by value.\n      case '[object String]':\n        // Primitives and their corresponding object wrappers are equivalent; thus, `\"5\"` is\n        // equivalent to `new String(\"5\")`.\n        return a == String(b);\n      case '[object Number]':\n        // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for\n        // other numeric values.\n        return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);\n      case '[object Date]':\n      case '[object Boolean]':\n        // Coerce dates and booleans to numeric primitive values. Dates are compared by their\n        // millisecond representations. Note that invalid dates with millisecond representations\n        // of `NaN` are not equivalent.\n        return +a == +b;\n      // RegExps are compared by their source patterns and flags.\n      case '[object RegExp]':\n        return a.source == b.source &&\n               a.global == b.global &&\n               a.multiline == b.multiline &&\n               a.ignoreCase == b.ignoreCase;\n    }\n    if (typeof a != 'object' || typeof b != 'object') return false;\n    // Assume equality for cyclic structures. The algorithm for detecting cyclic\n    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.\n    var length = aStack.length;\n    while (length--) {\n      // Linear search. Performance is inversely proportional to the number of\n      // unique nested structures.\n      if (aStack[length] == a) return bStack[length] == b;\n    }\n    // Add the first object to the stack of traversed objects.\n    aStack.push(a);\n    bStack.push(b);\n    var size = 0, result = true;\n    // Recursively compare objects and arrays.\n    if (className == '[object Array]') {\n      // Compare array lengths to determine if a deep comparison is necessary.\n      size = a.length;\n      result = size == b.length;\n      if (result) {\n        // Deep compare the contents, ignoring non-numeric properties.\n        while (size--) {\n          if (!(result = eq(a[size], b[size], aStack, bStack))) break;\n        }\n      }\n    } else {\n      // Objects with different constructors are not equivalent, but `Object`s\n      // from different frames are.\n      var aCtor = a.constructor, bCtor = b.constructor;\n      if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&\n                               _.isFunction(bCtor) && (bCtor instanceof bCtor))) {\n        return false;\n      }\n      // Deep compare objects.\n      for (var key in a) {\n        if (_.has(a, key)) {\n          // Count the expected number of properties.\n          size++;\n          // Deep compare each member.\n          if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;\n        }\n      }\n      // Ensure that both objects contain the same number of properties.\n      if (result) {\n        for (key in b) {\n          if (_.has(b, key) && !(size--)) break;\n        }\n        result = !size;\n      }\n    }\n    // Remove the first object from the stack of traversed objects.\n    aStack.pop();\n    bStack.pop();\n    return result;\n  };\n\n  // Perform a deep comparison to check if two objects are equal.\n  _.isEqual = function(a, b) {\n    return eq(a, b, [], []);\n  };\n\n  // Is a given array, string, or object empty?\n  // An \"empty\" object has no enumerable own-properties.\n  _.isEmpty = function(obj) {\n    if (obj == null) return true;\n    if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;\n    for (var key in obj) if (_.has(obj, key)) return false;\n    return true;\n  };\n\n  // Is a given value a DOM element?\n  _.isElement = function(obj) {\n    return !!(obj && obj.nodeType === 1);\n  };\n\n  // Is a given value an array?\n  // Delegates to ECMA5's native Array.isArray\n  _.isArray = nativeIsArray || function(obj) {\n    return toString.call(obj) == '[object Array]';\n  };\n\n  // Is a given variable an object?\n  _.isObject = function(obj) {\n    return obj === Object(obj);\n  };\n\n  // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.\n  each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {\n    _['is' + name] = function(obj) {\n      return toString.call(obj) == '[object ' + name + ']';\n    };\n  });\n\n  // Define a fallback version of the method in browsers (ahem, IE), where\n  // there isn't any inspectable \"Arguments\" type.\n  if (!_.isArguments(arguments)) {\n    _.isArguments = function(obj) {\n      return !!(obj && _.has(obj, 'callee'));\n    };\n  }\n\n  // Optimize `isFunction` if appropriate.\n  if (typeof (/./) !== 'function') {\n    _.isFunction = function(obj) {\n      return typeof obj === 'function';\n    };\n  }\n\n  // Is a given object a finite number?\n  _.isFinite = function(obj) {\n    return _.isNumber(obj) && isFinite(obj);\n  };\n\n  // Is the given value `NaN`? (NaN is the only number which does not equal itself).\n  _.isNaN = function(obj) {\n    return _.isNumber(obj) && obj != +obj;\n  };\n\n  // Is a given value a boolean?\n  _.isBoolean = function(obj) {\n    return obj === true || obj === false || toString.call(obj) == '[object Boolean]';\n  };\n\n  // Is a given value equal to null?\n  _.isNull = function(obj) {\n    return obj === null;\n  };\n\n  // Is a given variable undefined?\n  _.isUndefined = function(obj) {\n    return obj === void 0;\n  };\n\n  // Shortcut function for checking if an object has a given property directly\n  // on itself (in other words, not on a prototype).\n  _.has = function(obj, key) {\n    return hasOwnProperty.call(obj, key);\n  };\n\n  // Utility Functions\n  // -----------------\n\n  // Run Underscore.js in *noConflict* mode, returning the `_` variable to its\n  // previous owner. Returns a reference to the Underscore object.\n  _.noConflict = function() {\n    root._ = previousUnderscore;\n    return this;\n  };\n\n  // Keep the identity function around for default iterators.\n  _.identity = function(value) {\n    return value;\n  };\n\n  // Run a function **n** times.\n  _.times = function(n, iterator, context) {\n    for (var i = 0; i < n; i++) iterator.call(context, i);\n  };\n\n  // Return a random integer between min and max (inclusive).\n  _.random = function(min, max) {\n    if (max == null) {\n      max = min;\n      min = 0;\n    }\n    return min + (0 | Math.random() * (max - min + 1));\n  };\n\n  // List of HTML entities for escaping.\n  var entityMap = {\n    escape: {\n      '&': '&amp;',\n      '<': '&lt;',\n      '>': '&gt;',\n      '\"': '&quot;',\n      \"'\": '&#x27;',\n      '/': '&#x2F;'\n    }\n  };\n  entityMap.unescape = _.invert(entityMap.escape);\n\n  // Regexes containing the keys and values listed immediately above.\n  var entityRegexes = {\n    escape:   new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),\n    unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')\n  };\n\n  // Functions for escaping and unescaping strings to/from HTML interpolation.\n  _.each(['escape', 'unescape'], function(method) {\n    _[method] = function(string) {\n      if (string == null) return '';\n      return ('' + string).replace(entityRegexes[method], function(match) {\n        return entityMap[method][match];\n      });\n    };\n  });\n\n  // If the value of the named property is a function then invoke it;\n  // otherwise, return it.\n  _.result = function(object, property) {\n    if (object == null) return null;\n    var value = object[property];\n    return _.isFunction(value) ? value.call(object) : value;\n  };\n\n  // Add your own custom functions to the Underscore object.\n  _.mixin = function(obj) {\n    each(_.functions(obj), function(name){\n      var func = _[name] = obj[name];\n      _.prototype[name] = function() {\n        var args = [this._wrapped];\n        push.apply(args, arguments);\n        return result.call(this, func.apply(_, args));\n      };\n    });\n  };\n\n  // Generate a unique integer id (unique within the entire client session).\n  // Useful for temporary DOM ids.\n  var idCounter = 0;\n  _.uniqueId = function(prefix) {\n    var id = idCounter++;\n    return prefix ? prefix + id : id;\n  };\n\n  // By default, Underscore uses ERB-style template delimiters, change the\n  // following template settings to use alternative delimiters.\n  _.templateSettings = {\n    evaluate    : /<%([\\s\\S]+?)%>/g,\n    interpolate : /<%=([\\s\\S]+?)%>/g,\n    escape      : /<%-([\\s\\S]+?)%>/g\n  };\n\n  // When customizing `templateSettings`, if you don't want to define an\n  // interpolation, evaluation or escaping regex, we need one that is\n  // guaranteed not to match.\n  var noMatch = /(.)^/;\n\n  // Certain characters need to be escaped so that they can be put into a\n  // string literal.\n  var escapes = {\n    \"'\":      \"'\",\n    '\\\\':     '\\\\',\n    '\\r':     'r',\n    '\\n':     'n',\n    '\\t':     't',\n    '\\u2028': 'u2028',\n    '\\u2029': 'u2029'\n  };\n\n  var escaper = /\\\\|'|\\r|\\n|\\t|\\u2028|\\u2029/g;\n\n  // JavaScript micro-templating, similar to John Resig's implementation.\n  // Underscore templating handles arbitrary delimiters, preserves whitespace,\n  // and correctly escapes quotes within interpolated code.\n  _.template = function(text, data, settings) {\n    settings = _.defaults({}, settings, _.templateSettings);\n\n    // Combine delimiters into one regular expression via alternation.\n    var matcher = new RegExp([\n      (settings.escape || noMatch).source,\n      (settings.interpolate || noMatch).source,\n      (settings.evaluate || noMatch).source\n    ].join('|') + '|$', 'g');\n\n    // Compile the template source, escaping string literals appropriately.\n    var index = 0;\n    var source = \"__p+='\";\n    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {\n      source += text.slice(index, offset)\n        .replace(escaper, function(match) { return '\\\\' + escapes[match]; });\n      source +=\n        escape ? \"'+\\n((__t=(\" + escape + \"))==null?'':_.escape(__t))+\\n'\" :\n        interpolate ? \"'+\\n((__t=(\" + interpolate + \"))==null?'':__t)+\\n'\" :\n        evaluate ? \"';\\n\" + evaluate + \"\\n__p+='\" : '';\n      index = offset + match.length;\n    });\n    source += \"';\\n\";\n\n    // If a variable is not specified, place data values in local scope.\n    if (!settings.variable) source = 'with(obj||{}){\\n' + source + '}\\n';\n\n    source = \"var __t,__p='',__j=Array.prototype.join,\" +\n      \"print=function(){__p+=__j.call(arguments,'');};\\n\" +\n      source + \"return __p;\\n\";\n\n    try {\n      var render = new Function(settings.variable || 'obj', '_', source);\n    } catch (e) {\n      e.source = source;\n      throw e;\n    }\n\n    if (data) return render(data, _);\n    var template = function(data) {\n      return render.call(this, data, _);\n    };\n\n    // Provide the compiled function source as a convenience for precompilation.\n    template.source = 'function(' + (settings.variable || 'obj') + '){\\n' + source + '}';\n\n    return template;\n  };\n\n  // Add a \"chain\" function, which will delegate to the wrapper.\n  _.chain = function(obj) {\n    return _(obj).chain();\n  };\n\n  // OOP\n  // ---------------\n  // If Underscore is called as a function, it returns a wrapped object that\n  // can be used OO-style. This wrapper holds altered versions of all the\n  // underscore functions. Wrapped objects may be chained.\n\n  // Helper function to continue chaining intermediate results.\n  var result = function(obj) {\n    return this._chain ? _(obj).chain() : obj;\n  };\n\n  // Add all of the Underscore functions to the wrapper object.\n  _.mixin(_);\n\n  // Add all mutator Array functions to the wrapper.\n  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {\n    var method = ArrayProto[name];\n    _.prototype[name] = function() {\n      var obj = this._wrapped;\n      method.apply(obj, arguments);\n      if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];\n      return result.call(this, obj);\n    };\n  });\n\n  // Add all accessor Array functions to the wrapper.\n  each(['concat', 'join', 'slice'], function(name) {\n    var method = ArrayProto[name];\n    _.prototype[name] = function() {\n      return result.call(this, method.apply(this._wrapped, arguments));\n    };\n  });\n\n  _.extend(_.prototype, {\n\n    // Start chaining a wrapped Underscore object.\n    chain: function() {\n      this._chain = true;\n      return this;\n    },\n\n    // Extracts the result from a wrapped and chained object.\n    value: function() {\n      return this._wrapped;\n    }\n\n  });\n\n}).call(this);\n"
  },
  {
    "path": "docs/editor/scripts/urdujs/keywords.js",
    "content": "'lang sweet.js';\n\n// true\nexport syntax sach = function (ctx) {\n    return #`true`;\n}\n\n// false\nexport syntax galat = function (ctx) {\n    return #`false`;\n}\n\n// if\nexport syntax agar = function (ctx) {\n    let ifparam = ctx.next().value\n    let ifblock = ctx.next().value;\n    let warnas = ctx.next();\n    let result = #`if ${ifparam} ${ifblock}`;\n    while(!warnas.done){\n\t\t\tif (warnas.value.value.token.value === \"warna\"){\n\t\t\t\tlet elseblock = ctx.next().value;\n\t\t\t\tresult = result.concat(#`else ${elseblock}`)\n\t\t\t}\n\n\t\t\tif (warnas.value.value.token.value === \"warnaagar\"){\n\t\t\t\tlet elseifparam = ctx.next().value;\n\t\t\t\tlet elseifblock = ctx.next().value;\n\n\t\t\t\tresult = result.concat(#`else if ${elseifparam} ${elseifblock}`)\n\t\t\t\t\n\t\t\t\t\n\t\t\t}\n\n\t\t\twarnas = ctx.next();\n    }\n    //console.log(\"warnas\",warnas.value.token.value)\n    \n    return result\n    //return #`if ${ifparam} ${ifblock}`;\n}\n\n\n// var\nexport syntax samjho = function (ctx) {\n    return #`var`;\n}\n\n// while\nexport syntax jabtak = function (ctx) {\n    let wparam = ctx.next().value\n    let wblock = ctx.next().value;\n    return #`while ${wparam} ${wblock}`;\n}\n\n// console.log\nexport syntax likho = function (ctx) {\n    let params = ctx.next().value\n    //let wblock = ctx.next().value;\n    return #`console.log ${params}`;\n}\n\n// function\nexport syntax tareeka = function (ctx) {\n\tlet fname = ctx.next().value\n\tlet fparam = ctx.next().value\n\tlet fblock = ctx.next().value;\n\n  return #`function ${fname} ${fparam} ${fblock}`;\n}\n\n// for and foreach loop\nexport syntax har = function (ctx) {\n\tlet fparam = ctx.next().value\n\t\n\tif (fparam.type===\"RawSyntax\"){\n\t\t//foreach\n\t\tlet fparamk = ctx.next().value;\n\t\tlet fparamvar = ctx.next().value;\n\t\tlet fblock = ctx.next().value;\n\t\t//ignore 'per' or 'pe' if present\n\t\tif (fblock.type===\"RawSyntax\" \n\t\t\t\t&& fblock.value.token.value===\"per\"\n\t\t\t\t&& fblock.value.token.value===\"pe\"\n\t\t\t){\n\t\t\tfblock = ctx.next().value;\n\t\t}\n\t\treturn #`for (var ${fparamvar} of ${fparam}) ${fblock}`;\n\t}\n\telse{\n\t\tlet fblock = ctx.next().value;\n\t\treturn #`for ${fparam} ${fblock}`;\n\t}\n}"
  },
  {
    "path": "docs/editor/scripts/urdujs/keywords.js.txt",
    "content": "'lang sweet.js';\n\n// null\nexport syntax khali = ctx => #`null`\nexport syntax khaali = ctx => #`null`\n\n// true\nexport syntax sahi = ctx => #`true`\n\n// false\nexport syntax galat = ctx => #`false`\nexport syntax ghalat = ctx => #`false`\n\n// if\nexport syntax agar = function (ctx) {\n\t\n    let ifparam = ctx.next().value\n    let ifblock = ctx.next().value;\n    let warnas = ctx.next();\n    let ctxCounter = 3;\n    let result = #`if ${ifparam} ${ifblock}`;\n    while(!warnas.done){\n\t\tvar isWarna = false;\n\t\t\t\n\n\t\t\tif (warnas.value.value.token.value === \"warna\"){\n\t\t\t\tlet elseblock = ctx.next().value;\n\t\t\t\tresult = result.concat(#`else ${elseblock}`)\n\t\t\t\t//isWarna = true;\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tif (warnas.value.value.token.value === \"warnaagar\"){\n\t\t\t\tlet elseifparam = ctx.next().value;\n\t\t\t\tlet elseifblock = ctx.next().value;\n\t\t\t\tctxCounter += 2\n\t\t\t\tresult = result.concat(#`else if ${elseifparam} ${elseifblock}`)\n\t\t\t\tisWarna = true;\n\t\t\t\t\n\t\t\t}\n\n\t\t\tif (!isWarna) {\n\t\t\t\t// we fetched something beyond this code block. reset context and fwd correctly.\n\t\t\t\tctx.reset()\n\t\t\t\twhile (--ctxCounter){\n\t\t\t\t\tctx.next()\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\twarnas = ctx.next();\n\t\t\tctxCounter++;\n    }\n    //console.log(\"warnas\",warnas.value.token.value)\n    \n    return result\n    //return #`if ${ifparam} ${ifblock}`;\n}\n\n// var\nexport syntax rakho = ctx => #`var`\n\n// while\nexport syntax jabtak = function (ctx) {\n    let wparam = ctx.next().value\n    let wblock = ctx.next().value;\n    return #`while ${wparam} ${wblock}`;\n}\n\n// console.log\nexport syntax likho = ctx => #`console.log ${ctx.next().value}`\n\n// alert\nexport syntax _testAlert = ctx => #`alert ${ctx.next().value}`\n\n// prompt (only works on browser right now)\nexport syntax pucho = ctx => #`prompt ${ctx.next().value}`\n\n// function\nexport syntax kaam = function (ctx) {\n\tlet fname = ctx.next().value\n\tlet fparam = ctx.next().value\n\tlet fblock = ctx.next().value;\n  return #`function ${fname} ${fparam} ${fblock}`;\n}\n\n// for and foreach loop\nexport syntax har = function (ctx) {\n\tlet fparam = ctx.next().value\n\t\n\tif (fparam.type===\"RawSyntax\"){\n\t\t//foreach\n\t\tlet fparamk = ctx.next().value;\n\t\tlet fparamvar = ctx.next().value;\n\t\tlet fblock = ctx.next().value;\n\n\t\t//ignore 'per' or 'pe' if present\n\t\tif (fblock.type===\"RawSyntax\" \n\t\t\t\t&& (fblock.value.token.value===\"per\" || fblock.value.token.value===\"pe\")\n\t\t\t){\n\t\t\t\tfblock = ctx.next().value;\n\t\t}\n\t\treturn #`for (var ${fparamvar} of ${fparam}) ${fblock}`;\n\t}\n\telse{\n\t\tlet fblock = ctx.next().value;\n\t\treturn #`for ${fparam} ${fblock}`;\n\t}\n}\n\n// return\nexport syntax bhejo = ctx => #`return ${ctx.next().value}`;\n\n//do while\nexport syntax karo = function(ctx) {\n\tlet dblock = ctx.next().value;\n\tlet jabtak = ctx.next();\n\tif(jabtak.value != null){\n\t\tif(jabtak.value.value.token.value === \"jabtak\"){\n\t\t//console.log(jabtak.value.value.token.value);\n\t\tlet jabtakparams = ctx.next().value;\n\t\treturn #`do ${dblock} while ${jabtakparams}`;\n\t\t} else {\n\t\t\treturn #`console.log(\"galti: karo ke liye jabtak hona lazmi hai!\")`;\n\t\t}\n\t} else {\n\t\treturn #`console.log(\"galti: karo ke liye jabtak hona lazmi hai!\")`;\n\t}\n\t\n\t\n}\n\n// break\nexport syntax rukjao = (ctx) => #`break`;\n"
  },
  {
    "path": "hello.js",
    "content": "// URDU.js headers\nimport {\n  sach,\n  galat, \n  rakho, \n  agar,\n  jabtak,\n\tlikho,\n\tkaam,\n\thar,\n\tbhejo,\n\tkhali,\n\tpucho,\n\tkaro\n} from './src/keywords'\n\n/////////////////////////////////\n/*\nsamjho naam = \"asad\"\nhar (a=0; a<3; a++){\n\tsalaam(naam)\n}\n\n*/\n/*\nsamjho sabNaam = [\"asad\",\"ahmed\"]\nhar sabNaam k naam per{\n\tlikho(naam)\n}\n*/\nlikho(salaam(\"asad\"))\nhello()\n\nkaam salaam(naam){\n\tagar (naam === \"ahmed\"){\n\t\twapas \"oye ahmed\"\n\t}\n\twarnaagar (naam === \"asad\"){\n\t\twapas \"oye asad\"\n\t}\n\twarna {\n\t\twapas \"mein kisi \" + naam + \" ko nai janta!\"\n\t}\n}\n\nkamm hello(){\n\tlikho(\"hello\")\n}\n\n/*\nsamjho naam = \"asad\"\n\nagar (naam){\n\tlikho(\"salaam \" + naam)\n}\nwarnaagar(naam===0) {\n\tlikho(\"Naam khali hai\")\n}\nwarna{\n\tlikho(\"kch\")\n}\n\nlikho (\"end\")\nlikho (\"asad2\")\n\n/*\nsamjho a = 10\njabtak( a>0 ){\n\tagar ( a%2 ){\n\t\tlikho(\"even\", a)\n\t}\n\twarna{\n\t\tlikho(\"odd\", a)\n\t}\n\ta--\n}\n*/"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"urdu.js\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"bin\": {\n    \"urdujs\": \"bin/urdujs.js\"\n  },\n  \"scripts\": {\n    \"example\": \"bin/urdujs.js hello.js\",\n    \"start\": \"cp src/keywords.js docs/editor/scripts/urdujs/keywords.js.txt && node_modules/nws/bin/nws -d docs/editor\",\n    \"windows\": \"copy src\\\\keywords.js docs\\\\editor\\\\scripts\\\\urdujs\\\\keywords.js.txt && nws -d docs/editor\",\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"author\": \"Asad Memon\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"@sweet-js/core\": \"^3.0.13\",\n    \"nws\": \"^1.1.1\",\n    \"yargs\": \"^8.0.2\"\n  }\n}\n"
  },
  {
    "path": "src/keywords.js",
    "content": "'lang sweet.js';\n\n// null\nexport syntax khali = ctx => #`null`\nexport syntax khaali = ctx => #`null`\n\n// true\nexport syntax sahi = ctx => #`true`\n\n// false\nexport syntax galat = ctx => #`false`\nexport syntax ghalat = ctx => #`false`\n\n// if\nexport syntax agar = function (ctx) {\n\t\n    let ifparam = ctx.next().value\n    let ifblock = ctx.next().value;\n    let warnas = ctx.next();\n    let ctxCounter = 3;\n    let result = #`if ${ifparam} ${ifblock}`;\n    while(!warnas.done){\n\t\tvar isWarna = false;\n\t\t\t\n\n\t\t\tif (warnas.value.value.token.value === \"warna\"){\n\t\t\t\tlet elseblock = ctx.next().value;\n\t\t\t\tresult = result.concat(#`else ${elseblock}`)\n\t\t\t\t//isWarna = true;\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tif (warnas.value.value.token.value === \"warnaagar\"){\n\t\t\t\tlet elseifparam = ctx.next().value;\n\t\t\t\tlet elseifblock = ctx.next().value;\n\t\t\t\tctxCounter += 2\n\t\t\t\tresult = result.concat(#`else if ${elseifparam} ${elseifblock}`)\n\t\t\t\tisWarna = true;\n\t\t\t\t\n\t\t\t}\n\n\t\t\tif (!isWarna) {\n\t\t\t\t// we fetched something beyond this code block. reset context and fwd correctly.\n\t\t\t\tctx.reset()\n\t\t\t\twhile (--ctxCounter){\n\t\t\t\t\tctx.next()\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\twarnas = ctx.next();\n\t\t\tctxCounter++;\n    }\n    //console.log(\"warnas\",warnas.value.token.value)\n    \n    return result\n    //return #`if ${ifparam} ${ifblock}`;\n}\n\n// var\nexport syntax rakho = ctx => #`var`\n\n// while\nexport syntax jabtak = function (ctx) {\n    let wparam = ctx.next().value\n    let wblock = ctx.next().value;\n    return #`while ${wparam} ${wblock}`;\n}\n\n// console.log\nexport syntax likho = ctx => #`console.log ${ctx.next().value}`\n\n// alert\nexport syntax _testAlert = ctx => #`alert ${ctx.next().value}`\n\n// prompt (only works on browser right now)\nexport syntax pucho = ctx => #`prompt ${ctx.next().value}`\n\n// function\nexport syntax kaam = function (ctx) {\n\tlet fname = ctx.next().value\n\tlet fparam = ctx.next().value\n\tlet fblock = ctx.next().value;\n  return #`function ${fname} ${fparam} ${fblock}`;\n}\n\n// for and foreach loop\nexport syntax har = function (ctx) {\n\tlet fparam = ctx.next().value\n\t\n\tif (fparam.type===\"RawSyntax\"){\n\t\t//foreach\n\t\tlet fparamk = ctx.next().value;\n\t\tlet fparamvar = ctx.next().value;\n\t\tlet fblock = ctx.next().value;\n\n\t\t//ignore 'per' or 'pe' if present\n\t\tif (fblock.type===\"RawSyntax\" \n\t\t\t\t&& (fblock.value.token.value===\"per\" || fblock.value.token.value===\"pe\")\n\t\t\t){\n\t\t\t\tfblock = ctx.next().value;\n\t\t}\n\t\treturn #`for (var ${fparamvar} of ${fparam}) ${fblock}`;\n\t}\n\telse{\n\t\tlet fblock = ctx.next().value;\n\t\treturn #`for ${fparam} ${fblock}`;\n\t}\n}\n\n// return\nexport syntax bhejo = ctx => #`return ${ctx.next().value}`;\n\n//do while\nexport syntax karo = function(ctx) {\n\tlet dblock = ctx.next().value;\n\tlet jabtak = ctx.next();\n\tif(jabtak.value != null){\n\t\tif(jabtak.value.value.token.value === \"jabtak\"){\n\t\t//console.log(jabtak.value.value.token.value);\n\t\tlet jabtakparams = ctx.next().value;\n\t\treturn #`do ${dblock} while ${jabtakparams}`;\n\t\t} else {\n\t\t\treturn #`console.log(\"galti: karo ke liye jabtak hona lazmi hai!\")`;\n\t\t}\n\t} else {\n\t\treturn #`console.log(\"galti: karo ke liye jabtak hona lazmi hai!\")`;\n\t}\n\n}\n\n// break\nexport syntax rukjao = (ctx) => #`break`;\n"
  }
]