1{"version":3,"sources":["../../node_modules/codemirror/mode/ruby/ruby.js"],"names":["mod","exports","module","require","define","amd","CodeMirror","defineMode","config","wordObj","words","o","i","e","length","keywords","indentWords","dedentWords","opening","[","{","(","closing","]","}",")","curPunc","chain","newtok","stream","state","tokenize","push","tokenBase","sol","match","eol","readBlockComment","eatSpace","ch","next","m","readQuoted","regexpAhead","style","embed","eat","delim","propertyIsEnumerable","skipToEnd","readHereDoc","eatWhile","test","varList","lastTok","more","start","pos","depth","found","escaped","indexOf","backUp","tokenBaseUntilBrace","peek","pop","tokenBaseOnce","alreadyCalled","quote","unescaped","context","type","prev","phrase","mayIndent","startState","indented","indentUnit","continuedLine","token","indentation","kwtype","thisTok","word","current","column","indent","textAfter","Pass","firstChar","charAt","ct","closed","electricInput","lineComment","fold","defineMIME"],"mappings":"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","file":"ruby.min.js","sourcesContent":["// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: https://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\nCodeMirror.defineMode(\"ruby\", function(config) {\n  function wordObj(words) {\n    var o = {};\n    for (var i = 0, e = words.length; i < e; ++i) o[words[i]] = true;\n    return o;\n  }\n  var keywords = wordObj([\n    \"alias\", \"and\", \"BEGIN\", \"begin\", \"break\", \"case\", \"class\", \"def\", \"defined?\", \"do\", \"else\",\n    \"elsif\", \"END\", \"end\", \"ensure\", \"false\", \"for\", \"if\", \"in\", \"module\", \"next\", \"not\", \"or\",\n    \"redo\", \"rescue\", \"retry\", \"return\", \"self\", \"super\", \"then\", \"true\", \"undef\", \"unless\",\n    \"until\", \"when\", \"while\", \"yield\", \"nil\", \"raise\", \"throw\", \"catch\", \"fail\", \"loop\", \"callcc\",\n    \"caller\", \"lambda\", \"proc\", \"public\", \"protected\", \"private\", \"require\", \"load\",\n    \"require_relative\", \"extend\", \"autoload\", \"__END__\", \"__FILE__\", \"__LINE__\", \"__dir__\"\n  ]);\n  var indentWords = wordObj([\"def\", \"class\", \"case\", \"for\", \"while\", \"until\", \"module\", \"then\",\n                             \"catch\", \"loop\", \"proc\", \"begin\"]);\n  var dedentWords = wordObj([\"end\", \"until\"]);\n  var opening = {\"[\": \"]\", \"{\": \"}\", \"(\": \")\"};\n  var closing = {\"]\": \"[\", \"}\": \"{\", \")\": \"(\"};\n  var curPunc;\n\n  function chain(newtok, stream, state) {\n    state.tokenize.push(newtok);\n    return newtok(stream, state);\n  }\n\n  function tokenBase(stream, state) {\n    if (stream.sol() && stream.match(\"=begin\") && stream.eol()) {\n      state.tokenize.push(readBlockComment);\n      return \"comment\";\n    }\n    if (stream.eatSpace()) return null;\n    var ch = stream.next(), m;\n    if (ch == \"`\" || ch == \"'\" || ch == '\"') {\n      return chain(readQuoted(ch, \"string\", ch == '\"' || ch == \"`\"), stream, state);\n    } else if (ch == \"/\") {\n      if (regexpAhead(stream))\n        return chain(readQuoted(ch, \"string-2\", true), stream, state);\n      else\n        return \"operator\";\n    } else if (ch == \"%\") {\n      var style = \"string\", embed = true;\n      if (stream.eat(\"s\")) style = \"atom\";\n      else if (stream.eat(/[WQ]/)) style = \"string\";\n      else if (stream.eat(/[r]/)) style = \"string-2\";\n      else if (stream.eat(/[wxq]/)) { style = \"string\"; embed = false; }\n      var delim = stream.eat(/[^\\w\\s=]/);\n      if (!delim) return \"operator\";\n      if (opening.propertyIsEnumerable(delim)) delim = opening[delim];\n      return chain(readQuoted(delim, style, embed, true), stream, state);\n    } else if (ch == \"#\") {\n      stream.skipToEnd();\n      return \"comment\";\n    } else if (ch == \"<\" && (m = stream.match(/^<([-~])[\\`\\\"\\']?([a-zA-Z_?]\\w*)[\\`\\\"\\']?(?:;|$)/))) {\n      return chain(readHereDoc(m[2], m[1]), stream, state);\n    } else if (ch == \"0\") {\n      if (stream.eat(\"x\")) stream.eatWhile(/[\\da-fA-F]/);\n      else if (stream.eat(\"b\")) stream.eatWhile(/[01]/);\n      else stream.eatWhile(/[0-7]/);\n      return \"number\";\n    } else if (/\\d/.test(ch)) {\n      stream.match(/^[\\d_]*(?:\\.[\\d_]+)?(?:[eE][+\\-]?[\\d_]+)?/);\n      return \"number\";\n    } else if (ch == \"?\") {\n      while (stream.match(/^\\\\[CM]-/)) {}\n      if (stream.eat(\"\\\\\")) stream.eatWhile(/\\w/);\n      else stream.next();\n      return \"string\";\n    } else if (ch == \":\") {\n      if (stream.eat(\"'\")) return chain(readQuoted(\"'\", \"atom\", false), stream, state);\n      if (stream.eat('\"')) return chain(readQuoted('\"', \"atom\", true), stream, state);\n\n      // :> :>> :< :<< are valid symbols\n      if (stream.eat(/[\\<\\>]/)) {\n        stream.eat(/[\\<\\>]/);\n        return \"atom\";\n      }\n\n      // :+ :- :/ :* :| :& :! are valid symbols\n      if (stream.eat(/[\\+\\-\\*\\/\\&\\|\\:\\!]/)) {\n        return \"atom\";\n      }\n\n      // Symbols can't start by a digit\n      if (stream.eat(/[a-zA-Z$@_\\xa1-\\uffff]/)) {\n        stream.eatWhile(/[\\w$\\xa1-\\uffff]/);\n        // Only one ? ! = is allowed and only as the last character\n        stream.eat(/[\\?\\!\\=]/);\n        return \"atom\";\n      }\n      return \"operator\";\n    } else if (ch == \"@\" && stream.match(/^@?[a-zA-Z_\\xa1-\\uffff]/)) {\n      stream.eat(\"@\");\n      stream.eatWhile(/[\\w\\xa1-\\uffff]/);\n      return \"variable-2\";\n    } else if (ch == \"$\") {\n      if (stream.eat(/[a-zA-Z_]/)) {\n        stream.eatWhile(/[\\w]/);\n      } else if (stream.eat(/\\d/)) {\n        stream.eat(/\\d/);\n      } else {\n        stream.next(); // Must be a special global like $: or $!\n      }\n      return \"variable-3\";\n    } else if (/[a-zA-Z_\\xa1-\\uffff]/.test(ch)) {\n      stream.eatWhile(/[\\w\\xa1-\\uffff]/);\n      stream.eat(/[\\?\\!]/);\n      if (stream.eat(\":\")) return \"atom\";\n      return \"ident\";\n    } else if (ch == \"|\" && (state.varList || state.lastTok == \"{\" || state.lastTok == \"do\")) {\n      curPunc = \"|\";\n      return null;\n    } else if (/[\\(\\)\\[\\]{}\\\\;]/.test(ch)) {\n      curPunc = ch;\n      return null;\n    } else if (ch == \"-\" && stream.eat(\">\")) {\n      return \"arrow\";\n    } else if (/[=+\\-\\/*:\\.^%<>~|]/.test(ch)) {\n      var more = stream.eatWhile(/[=+\\-\\/*:\\.^%<>~|]/);\n      if (ch == \".\" && !more) curPunc = \".\";\n      return \"operator\";\n    } else {\n      return null;\n    }\n  }\n\n  function regexpAhead(stream) {\n    var start = stream.pos, depth = 0, next, found = false, escaped = false\n    while ((next = stream.next()) != null) {\n      if (!escaped) {\n        if (\"[{(\".indexOf(next) > -1) {\n          depth++\n        } else if (\"]})\".indexOf(next) > -1) {\n          depth--\n          if (depth < 0) break\n        } else if (next == \"/\" && depth == 0) {\n          found = true\n          break\n        }\n        escaped = next == \"\\\\\"\n      } else {\n        escaped = false\n      }\n    }\n    stream.backUp(stream.pos - start)\n    return found\n  }\n\n  function tokenBaseUntilBrace(depth) {\n    if (!depth) depth = 1;\n    return function(stream, state) {\n      if (stream.peek() == \"}\") {\n        if (depth == 1) {\n          state.tokenize.pop();\n          return state.tokenize[state.tokenize.length-1](stream, state);\n        } else {\n          state.tokenize[state.tokenize.length - 1] = tokenBaseUntilBrace(depth - 1);\n        }\n      } else if (stream.peek() == \"{\") {\n        state.tokenize[state.tokenize.length - 1] = tokenBaseUntilBrace(depth + 1);\n      }\n      return tokenBase(stream, state);\n    };\n  }\n  function tokenBaseOnce() {\n    var alreadyCalled = false;\n    return function(stream, state) {\n      if (alreadyCalled) {\n        state.tokenize.pop();\n        return state.tokenize[state.tokenize.length-1](stream, state);\n      }\n      alreadyCalled = true;\n      return tokenBase(stream, state);\n    };\n  }\n  function readQuoted(quote, style, embed, unescaped) {\n    return function(stream, state) {\n      var escaped = false, ch;\n\n      if (state.context.type === 'read-quoted-paused') {\n        state.context = state.context.prev;\n        stream.eat(\"}\");\n      }\n\n      while ((ch = stream.next()) != null) {\n        if (ch == quote && (unescaped || !escaped)) {\n          state.tokenize.pop();\n          break;\n        }\n        if (embed && ch == \"#\" && !escaped) {\n          if (stream.eat(\"{\")) {\n            if (quote == \"}\") {\n              state.context = {prev: state.context, type: 'read-quoted-paused'};\n            }\n            state.tokenize.push(tokenBaseUntilBrace());\n            break;\n          } else if (/[@\\$]/.test(stream.peek())) {\n            state.tokenize.push(tokenBaseOnce());\n            break;\n          }\n        }\n        escaped = !escaped && ch == \"\\\\\";\n      }\n      return style;\n    };\n  }\n  function readHereDoc(phrase, mayIndent) {\n    return function(stream, state) {\n      if (mayIndent) stream.eatSpace()\n      if (stream.match(phrase)) state.tokenize.pop();\n      else stream.skipToEnd();\n      return \"string\";\n    };\n  }\n  function readBlockComment(stream, state) {\n    if (stream.sol() && stream.match(\"=end\") && stream.eol())\n      state.tokenize.pop();\n    stream.skipToEnd();\n    return \"comment\";\n  }\n\n  return {\n    startState: function() {\n      return {tokenize: [tokenBase],\n              indented: 0,\n              context: {type: \"top\", indented: -config.indentUnit},\n              continuedLine: false,\n              lastTok: null,\n              varList: false};\n    },\n\n    token: function(stream, state) {\n      curPunc = null;\n      if (stream.sol()) state.indented = stream.indentation();\n      var style = state.tokenize[state.tokenize.length-1](stream, state), kwtype;\n      var thisTok = curPunc;\n      if (style == \"ident\") {\n        var word = stream.current();\n        style = state.lastTok == \".\" ? \"property\"\n          : keywords.propertyIsEnumerable(stream.current()) ? \"keyword\"\n          : /^[A-Z]/.test(word) ? \"tag\"\n          : (state.lastTok == \"def\" || state.lastTok == \"class\" || state.varList) ? \"def\"\n          : \"variable\";\n        if (style == \"keyword\") {\n          thisTok = word;\n          if (indentWords.propertyIsEnumerable(word)) kwtype = \"indent\";\n          else if (dedentWords.propertyIsEnumerable(word)) kwtype = \"dedent\";\n          else if ((word == \"if\" || word == \"unless\") && stream.column() == stream.indentation())\n            kwtype = \"indent\";\n          else if (word == \"do\" && state.context.indented < state.indented)\n            kwtype = \"indent\";\n        }\n      }\n      if (curPunc || (style && style != \"comment\")) state.lastTok = thisTok;\n      if (curPunc == \"|\") state.varList = !state.varList;\n\n      if (kwtype == \"indent\" || /[\\(\\[\\{]/.test(curPunc))\n        state.context = {prev: state.context, type: curPunc || style, indented: state.indented};\n      else if ((kwtype == \"dedent\" || /[\\)\\]\\}]/.test(curPunc)) && state.context.prev)\n        state.context = state.context.prev;\n\n      if (stream.eol())\n        state.continuedLine = (curPunc == \"\\\\\" || style == \"operator\");\n      return style;\n    },\n\n    indent: function(state, textAfter) {\n      if (state.tokenize[state.tokenize.length-1] != tokenBase) return CodeMirror.Pass;\n      var firstChar = textAfter && textAfter.charAt(0);\n      var ct = state.context;\n      var closed = ct.type == closing[firstChar] ||\n        ct.type == \"keyword\" && /^(?:end|until|else|elsif|when|rescue)\\b/.test(textAfter);\n      return ct.indented + (closed ? 0 : config.indentUnit) +\n        (state.continuedLine ? config.indentUnit : 0);\n    },\n\n    electricInput: /^\\s*(?:end|rescue|elsif|else|\\})$/,\n    lineComment: \"#\",\n    fold: \"indent\"\n  };\n});\n\nCodeMirror.defineMIME(\"text/x-ruby\", \"ruby\");\n\n});\n"]}