1{"version":3,"sources":["../../node_modules/codemirror/mode/crystal/crystal.js"],"names":["mod","exports","module","require","define","amd","CodeMirror","defineMode","config","wordRegExp","words","end","RegExp","join","chain","tokenize","stream","state","push","operators","conditionalOperators","indexingOperators","anotherOperators","idents","types","keywords","atomWords","indentKeywordsArray","indentKeywords","indentExpressionKeywordsArray","indentExpressionKeywords","dedentKeywordsArray","dedentKeywords","dedentPunctualsArray","dedentPunctuals","nextTokenizer","def","tokenFollowIdent","fun","macro","tokenMacroDef","class","tokenFollowType","struct","lib","enum","union","matching","[","{","(","<","tokenBase","eatSpace","lastToken","match","tokenMacro","peek","skipToEnd","matched","eat","current","test","blocks","indexOf","currentIndent","lastStyle","pop","hasOwnProperty","tokenNest","tokenQuote","style","embed","delim","next","tokenHereDoc","begin","started","length","nextStyle","escaped","ch","phrase","sol","startState","token","indent","textAfter","replace","indentUnit","fold","electricInput","concat","lineComment","defineMIME"],"mappings":"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","file":"crystal.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\n CodeMirror.defineMode(\"crystal\", function(config) {\n function wordRegExp(words, end) {\n return new RegExp((end ? \"\" : \"^\") + \"(?:\" + words.join(\"|\") + \")\" + (end ? \"$\" : \"\\\\b\"));\n }\n\n function chain(tokenize, stream, state) {\n state.tokenize.push(tokenize);\n return tokenize(stream, state);\n }\n\n var operators = /^(?:[-+/%|&^]|\\*\\*?|[<>]{2})/;\n var conditionalOperators = /^(?:[=!]~|===|<=>|[<>=!]=?|[|&]{2}|~)/;\n var indexingOperators = /^(?:\\[\\][?=]?)/;\n var anotherOperators = /^(?:\\.(?:\\.{2})?|->|[?:])/;\n var idents = /^[a-z_\\u009F-\\uFFFF][a-zA-Z0-9_\\u009F-\\uFFFF]*/;\n var types = /^[A-Z_\\u009F-\\uFFFF][a-zA-Z0-9_\\u009F-\\uFFFF]*/;\n var keywords = wordRegExp([\n \"abstract\", \"alias\", \"as\", \"asm\", \"begin\", \"break\", \"case\", \"class\", \"def\", \"do\",\n \"else\", \"elsif\", \"end\", \"ensure\", \"enum\", \"extend\", \"for\", \"fun\", \"if\",\n \"include\", \"instance_sizeof\", \"lib\", \"macro\", \"module\", \"next\", \"of\", \"out\", \"pointerof\",\n \"private\", \"protected\", \"rescue\", \"return\", \"require\", \"select\", \"sizeof\", \"struct\",\n \"super\", \"then\", \"type\", \"typeof\", \"uninitialized\", \"union\", \"unless\", \"until\", \"when\", \"while\", \"with\",\n \"yield\", \"__DIR__\", \"__END_LINE__\", \"__FILE__\", \"__LINE__\"\n ]);\n var atomWords = wordRegExp([\"true\", \"false\", \"nil\", \"self\"]);\n var indentKeywordsArray = [\n \"def\", \"fun\", \"macro\",\n \"class\", \"module\", \"struct\", \"lib\", \"enum\", \"union\",\n \"do\", \"for\"\n ];\n var indentKeywords = wordRegExp(indentKeywordsArray);\n var indentExpressionKeywordsArray = [\"if\", \"unless\", \"case\", \"while\", \"until\", \"begin\", \"then\"];\n var indentExpressionKeywords = wordRegExp(indentExpressionKeywordsArray);\n var dedentKeywordsArray = [\"end\", \"else\", \"elsif\", \"rescue\", \"ensure\"];\n var dedentKeywords = wordRegExp(dedentKeywordsArray);\n var dedentPunctualsArray = [\"\\\\)\", \"\\\\}\", \"\\\\]\"];\n var dedentPunctuals = new RegExp(\"^(?:\" + dedentPunctualsArray.join(\"|\") + \")$\");\n var nextTokenizer = {\n \"def\": tokenFollowIdent, \"fun\": tokenFollowIdent, \"macro\": tokenMacroDef,\n \"class\": tokenFollowType, \"module\": tokenFollowType, \"struct\": tokenFollowType,\n \"lib\": tokenFollowType, \"enum\": tokenFollowType, \"union\": tokenFollowType\n };\n var matching = {\"[\": \"]\", \"{\": \"}\", \"(\": \")\", \"<\": \">\"};\n\n function tokenBase(stream, state) {\n if (stream.eatSpace()) {\n return null;\n }\n\n // Macros\n if (state.lastToken != \"\\\\\" && stream.match(\"{%\", false)) {\n return chain(tokenMacro(\"%\", \"%\"), stream, state);\n }\n\n if (state.lastToken != \"\\\\\" && stream.match(\"{{\", false)) {\n return chain(tokenMacro(\"{\", \"}\"), stream, state);\n }\n\n // Comments\n if (stream.peek() == \"#\") {\n stream.skipToEnd();\n return \"comment\";\n }\n\n // Variables and keywords\n var matched;\n if (stream.match(idents)) {\n stream.eat(/[?!]/);\n\n matched = stream.current();\n if (stream.eat(\":\")) {\n return \"atom\";\n } else if (state.lastToken == \".\") {\n return \"property\";\n } else if (keywords.test(matched)) {\n if (indentKeywords.test(matched)) {\n if (!(matched == \"fun\" && state.blocks.indexOf(\"lib\") >= 0) && !(matched == \"def\" && state.lastToken == \"abstract\")) {\n state.blocks.push(matched);\n state.currentIndent += 1;\n }\n } else if ((state.lastStyle == \"operator\" || !state.lastStyle) && indentExpressionKeywords.test(matched)) {\n state.blocks.push(matched);\n state.currentIndent += 1;\n } else if (matched == \"end\") {\n state.blocks.pop();\n state.currentIndent -= 1;\n }\n\n if (nextTokenizer.hasOwnProperty(matched)) {\n state.tokenize.push(nextTokenizer[matched]);\n }\n\n return \"keyword\";\n } else if (atomWords.test(matched)) {\n return \"atom\";\n }\n\n return \"variable\";\n }\n\n // Class variables and instance variables\n // or attributes\n if (stream.eat(\"@\")) {\n if (stream.peek() == \"[\") {\n return chain(tokenNest(\"[\", \"]\", \"meta\"), stream, state);\n }\n\n stream.eat(\"@\");\n stream.match(idents) || stream.match(types);\n return \"variable-2\";\n }\n\n // Constants and types\n if (stream.match(types)) {\n return \"tag\";\n }\n\n // Symbols or ':' operator\n if (stream.eat(\":\")) {\n if (stream.eat(\"\\\"\")) {\n return chain(tokenQuote(\"\\\"\", \"atom\", false), stream, state);\n } else if (stream.match(idents) || stream.match(types) ||\n stream.match(operators) || stream.match(conditionalOperators) || stream.match(indexingOperators)) {\n return \"atom\";\n }\n stream.eat(\":\");\n return \"operator\";\n }\n\n // Strings\n if (stream.eat(\"\\\"\")) {\n return chain(tokenQuote(\"\\\"\", \"string\", true), stream, state);\n }\n\n // Strings or regexps or macro variables or '%' operator\n if (stream.peek() == \"%\") {\n var style = \"string\";\n var embed = true;\n var delim;\n\n if (stream.match(\"%r\")) {\n // Regexps\n style = \"string-2\";\n delim = stream.next();\n } else if (stream.match(\"%w\")) {\n embed = false;\n delim = stream.next();\n } else if (stream.match(\"%q\")) {\n embed = false;\n delim = stream.next();\n } else {\n if(delim = stream.match(/^%([^\\w\\s=])/)) {\n delim = delim[1];\n } else if (stream.match(/^%[a-zA-Z0-9_\\u009F-\\uFFFF]*/)) {\n // Macro variables\n return \"meta\";\n } else {\n // '%' operator\n return \"operator\";\n }\n }\n\n if (matching.hasOwnProperty(delim)) {\n delim = matching[delim];\n }\n return chain(tokenQuote(delim, style, embed), stream, state);\n }\n\n // Here Docs\n if (matched = stream.match(/^<<-('?)([A-Z]\\w*)\\1/)) {\n return chain(tokenHereDoc(matched[2], !matched[1]), stream, state)\n }\n\n // Characters\n if (stream.eat(\"'\")) {\n stream.match(/^(?:[^']|\\\\(?:[befnrtv0'\"]|[0-7]{3}|u(?:[0-9a-fA-F]{4}|\\{[0-9a-fA-F]{1,6}\\})))/);\n stream.eat(\"'\");\n return \"atom\";\n }\n\n // Numbers\n if (stream.eat(\"0\")) {\n if (stream.eat(\"x\")) {\n stream.match(/^[0-9a-fA-F]+/);\n } else if (stream.eat(\"o\")) {\n stream.match(/^[0-7]+/);\n } else if (stream.eat(\"b\")) {\n stream.match(/^[01]+/);\n }\n return \"number\";\n }\n\n if (stream.eat(/^\\d/)) {\n stream.match(/^\\d*(?:\\.\\d+)?(?:[eE][+-]?\\d+)?/);\n return \"number\";\n }\n\n // Operators\n if (stream.match(operators)) {\n stream.eat(\"=\"); // Operators can follow assign symbol.\n return \"operator\";\n }\n\n if (stream.match(conditionalOperators) || stream.match(anotherOperators)) {\n return \"operator\";\n }\n\n // Parens and braces\n if (matched = stream.match(/[({[]/, false)) {\n matched = matched[0];\n return chain(tokenNest(matched, matching[matched], null), stream, state);\n }\n\n // Escapes\n if (stream.eat(\"\\\\\")) {\n stream.next();\n return \"meta\";\n }\n\n stream.next();\n return null;\n }\n\n function tokenNest(begin, end, style, started) {\n return function (stream, state) {\n if (!started && stream.match(begin)) {\n state.tokenize[state.tokenize.length - 1] = tokenNest(begin, end, style, true);\n state.currentIndent += 1;\n return style;\n }\n\n var nextStyle = tokenBase(stream, state);\n if (stream.current() === end) {\n state.tokenize.pop();\n state.currentIndent -= 1;\n nextStyle = style;\n }\n\n return nextStyle;\n };\n }\n\n function tokenMacro(begin, end, started) {\n return function (stream, state) {\n if (!started && stream.match(\"{\" + begin)) {\n state.currentIndent += 1;\n state.tokenize[state.tokenize.length - 1] = tokenMacro(begin, end, true);\n return \"meta\";\n }\n\n if (stream.match(end + \"}\")) {\n state.currentIndent -= 1;\n state.tokenize.pop();\n return \"meta\";\n }\n\n return tokenBase(stream, state);\n };\n }\n\n function tokenMacroDef(stream, state) {\n if (stream.eatSpace()) {\n return null;\n }\n\n var matched;\n if (matched = stream.match(idents)) {\n if (matched == \"def\") {\n return \"keyword\";\n }\n stream.eat(/[?!]/);\n }\n\n state.tokenize.pop();\n return \"def\";\n }\n\n function tokenFollowIdent(stream, state) {\n if (stream.eatSpace()) {\n return null;\n }\n\n if (stream.match(idents)) {\n stream.eat(/[!?]/);\n } else {\n stream.match(operators) || stream.match(conditionalOperators) || stream.match(indexingOperators);\n }\n state.tokenize.pop();\n return \"def\";\n }\n\n function tokenFollowType(stream, state) {\n if (stream.eatSpace()) {\n return null;\n }\n\n stream.match(types);\n state.tokenize.pop();\n return \"def\";\n }\n\n function tokenQuote(end, style, embed) {\n return function (stream, state) {\n var escaped = false;\n\n while (stream.peek()) {\n if (!escaped) {\n if (stream.match(\"{%\", false)) {\n state.tokenize.push(tokenMacro(\"%\", \"%\"));\n return style;\n }\n\n if (stream.match(\"{{\", false)) {\n state.tokenize.push(tokenMacro(\"{\", \"}\"));\n return style;\n }\n\n if (embed && stream.match(\"#{\", false)) {\n state.tokenize.push(tokenNest(\"#{\", \"}\", \"meta\"));\n return style;\n }\n\n var ch = stream.next();\n\n if (ch == end) {\n state.tokenize.pop();\n return style;\n }\n\n escaped = embed && ch == \"\\\\\";\n } else {\n stream.next();\n escaped = false;\n }\n }\n\n return style;\n };\n }\n\n function tokenHereDoc(phrase, embed) {\n return function (stream, state) {\n if (stream.sol()) {\n stream.eatSpace()\n if (stream.match(phrase)) {\n state.tokenize.pop();\n return \"string\";\n }\n }\n\n var escaped = false;\n while (stream.peek()) {\n if (!escaped) {\n if (stream.match(\"{%\", false)) {\n state.tokenize.push(tokenMacro(\"%\", \"%\"));\n return \"string\";\n }\n\n if (stream.match(\"{{\", false)) {\n state.tokenize.push(tokenMacro(\"{\", \"}\"));\n return \"string\";\n }\n\n if (embed && stream.match(\"#{\", false)) {\n state.tokenize.push(tokenNest(\"#{\", \"}\", \"meta\"));\n return \"string\";\n }\n\n escaped = embed && stream.next() == \"\\\\\";\n } else {\n stream.next();\n escaped = false;\n }\n }\n\n return \"string\";\n }\n }\n\n return {\n startState: function () {\n return {\n tokenize: [tokenBase],\n currentIndent: 0,\n lastToken: null,\n lastStyle: null,\n blocks: []\n };\n },\n\n token: function (stream, state) {\n var style = state.tokenize[state.tokenize.length - 1](stream, state);\n var token = stream.current();\n\n if (style && style != \"comment\") {\n state.lastToken = token;\n state.lastStyle = style;\n }\n\n return style;\n },\n\n indent: function (state, textAfter) {\n textAfter = textAfter.replace(/^\\s*(?:\\{%)?\\s*|\\s*(?:%\\})?\\s*$/g, \"\");\n\n if (dedentKeywords.test(textAfter) || dedentPunctuals.test(textAfter)) {\n return config.indentUnit * (state.currentIndent - 1);\n }\n\n return config.indentUnit * state.currentIndent;\n },\n\n fold: \"indent\",\n electricInput: wordRegExp(dedentPunctualsArray.concat(dedentKeywordsArray), true),\n lineComment: '#'\n };\n });\n\n CodeMirror.defineMIME(\"text/x-crystal\", \"crystal\");\n});\n"]}