diff --git a/.gitignore b/.gitignore index 534b0b840..aac1325cf 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ bin/ .DS_Store .idea/ .vscode/ +.nova/ *.iml # ENV diff --git a/README.md b/README.md index 5a193807b..1b52133fa 100644 --- a/README.md +++ b/README.md @@ -7,13 +7,10 @@ original V [docs.md](https://github.com/vlang/v/blob/master/doc/docs.md) ## External dependencies -You'll need V, of course. Best to +This project only requires V. Best to [install it from source](https://github.com/vlang/v?tab=readme-ov-file#installing-v-from-source) if you don't already have it. -Make sure you have [sass](https://sass-lang.com/install/) installed -locally to build the css files. - ## Contributing To setup the generator and contribute changes to it, do this once: @@ -31,14 +28,20 @@ To build the documentation, after the setup, run the following commands: ```shell v run . ``` -This will download the latest version +This will download the latest version of [docs.md](https://github.com/vlang/v/edit/master/doc/docs.md), then it will regenerate the documentation from it, and save it in the `output` directory. ## Testing the output + +Use V to serve your local copy of the documentation. + ```shell v -e 'import net.http.file; file.serve(folder: "output/")' ``` -Now load http://localhost:4001/ in your browser. + +The line of code executed will start a basic web server with the documentation created in the "outputs" folder. + +Access the documentation on your browser using this url http://localhost:4001/. diff --git a/main.v b/main.v index 2642ad8d5..84251796f 100644 --- a/main.v +++ b/main.v @@ -20,7 +20,8 @@ fn main() { commit_res := os.execute_or_exit('git ls-remote -h https://github.com/vlang/v.git refs/heads/master') latest_v_commit_hash := commit_res.output.all_before('\t') - update_sass() + //Removed need for sass, using css variables + //update_sass() mut ctx := Context{ full_text: response.body @@ -39,11 +40,18 @@ mut: } fn (mut ctx Context) write_mapping() ! { - content := ' -const titles_to_fnames = ${json.encode_pretty(ctx.titles_to_fnames)}; -const fnames = ${json.encode_pretty(ctx.pages)}; -' - write_output_file('assets/scripts/titles_to_fnames.js', content)! + js_file_index := ' + // Lookups of sections to files + vdocs.titles_to_fnames = ${json.encode_pretty(ctx.titles_to_fnames)}; + vdocs.fnames = ${json.encode_pretty(ctx.pages)};' + + js_src := os.read_file('templates/assets/scripts/v-docs.js') or { + eprintln('Failed to read file: $err') + return + } + + write_output_file('assets/scripts/v-docs.js', js_src + js_file_index)! + eprintln('> Total titles: ${ctx.titles_to_fnames.len}') eprintln('> HTML pages: ${ctx.pages.len}') } diff --git a/sass.v b/sass.v deleted file mode 100644 index 0d979938e..000000000 --- a/sass.v +++ /dev/null @@ -1,22 +0,0 @@ -module main - -import os - -fn update_sass() { - // Note: sass is https://sass-lang.com/dart-sass/, while sassc is https://github.com/sass/sassc . - // On the FreeBSD vps, where the documentation is generated, *only `sassc` is available* natively, - // and the `sass` tool, does not have an easily installable prebuilt native version for FreeBSD, - // only a slower transpiled to JS version, installed through `npm install -g sass`. - // - // In comparison, they both produce nearly equal output with --style=expanded , except for: - // a) `transition: fill 0.25s;` vs `transition: fill .25s;` - // b) some newlines at the end of each CSS rule - // c) style.css.map is different. - sass_cmd := 'sassc --sourcemap=auto --style=expanded templates/assets/styles/style.scss templates/assets/styles/style.css' - // sass_cmd := 'sass --style=expanded templates/assets/styles/style.scss templates/assets/styles/style.css' - res := os.system(sass_cmd) - if res != 0 { - eprintln('sass compilation failed, cmd: `${sass_cmd}`') - exit(1) - } -} diff --git a/templates/assets/scripts/cm-lang-v.js b/templates/assets/scripts/cm-lang-v.js new file mode 100644 index 000000000..ee6e402df --- /dev/null +++ b/templates/assets/scripts/cm-lang-v.js @@ -0,0 +1,617 @@ + +/* + V-Lang Language Mode for CodeMirror +*/ +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + +const baseAttributes = [ + "params", "noinit", "required", "skip", "assert_continues", + "unsafe", "manualfree", "heap", "nonnull", "primary", "inline", + "direct_array_access", "live", "flag", "noinline", "noreturn", "typedef", "console", + "sql", "table", "deprecated", "deprecated_after", "export", "callconv" +]; +const baseModules = [ + "arrays", + "benchmark", "bitfield", + "cli", "clipboard", "compress", "context", "crypto", + "darwin", "datatypes", "dl", "dlmalloc", + "encoding", "eventbus", + "flag", "fontstash", + "gg", "gx", + "hash", + "io", + "js", "json", + "log", + "math", "mssql", "mysql", + "net", + "orm", "os", + "pg", "picoev", "picohttpparser", + "rand", "readline", "regex", "runtime", + "semver", "sokol", "sqlite", "stbi", "strconv", "strings", "sync", "szip", + "term", "time", "toml", + "v", "vweb", + "x", +]; +const word = "[\\w_]+"; +//[key: value] +const keyValue = `(${word}: ${word})`; + +// [if expr ?] +const ifAttributesRegexp = new RegExp(`^if ${word} \\??]`); +// [key: value; key: value] +const keyValueAttributesRegexp = new RegExp(`^((${keyValue})(; )?){2,}]$`); +const simpleAttributesRegexp = new RegExp(`^(${baseAttributes.join("|")})]$`); +const singleKeyValueAttributesRegexp = new RegExp(`^${keyValue}]$`); +const severalSingleKeyValueAttributesRegexp = new RegExp(`^(${baseAttributes.join("|")}(; ?)?){2,}]$`); + +class Context { + constructor( + indentation, + column, + type, + align, + prev, + knownImports = new Set() + ) { + this.indentation = indentation + this.column = column + this.type = type + this.align = align + this.prev = prev + this.knownImports = knownImports + } + + /** + * Whenever current position inside a string. + */ + insideString = false + + /** + * Current quotation mark. + * Valid only when insideString is true. + */ + stringQuote = null + + /** + * Whenever next token expected to be an import name. + * Used for highlighting import names in import statements. + */ + expectedImportName = false +} + +const keywords = new Set([ + "as", + "asm", + "assert", + "atomic", + "break", + "const", + "continue", + "defer", + "else", + "enum", + "fn", + "for", + "go", + "goto", + "if", + "implements", + "import", + "in", + "interface", + "is", + "isreftype", + "lock", + "match", + "module", + "mut", + "none", + "or", + "pub", + "return", + "rlock", + "select", + "shared", + "sizeof", + "static", + "struct", + "spawn", + "type", + "typeof", + "union", + "unsafe", + "volatile", + "__global", + "__offsetof" +]) + +const pseudoKeywords = new Set(["sql", "chan", "thread"]) + +const hashDirectives = new Set(["#flag", "#include", "#pkgconfig"]) + +const atoms = new Set([ + "true", + "false", + "nil", + "print", + "println", + "exit", + "panic", + "error", + "dump" +]) + +const builtinTypes = new Set([ + "bool", + "string", + "i8", + "i16", + "int", + "i32", + "i64", + "i128", + "u8", + "u16", + "u32", + "u64", + "u128", + "rune", + "f32", + "f64", + "isize", + "usize", + "voidptr", + "any" +]) + + +CodeMirror.defineMode("v", config => { + const indentUnit = config.indentUnit ?? 0 + + const isOperatorChar = /[+\-*&^%:=<>!?|\/]/ + + let curPunc = null + + function eatIdentifier(stream) { + stream.eatWhile(/[\w$_\xa1-\uffff]/) + return stream.current() + } + + function tokenBase(stream, state) { + const ch = stream.next() + if (ch === null) { + return null + } + + if (state.context.insideString && ch === "}") { + stream.eat("}") + state.tokenize = tokenString(state.context.stringQuote) + return "end-interpolation" + } + + if (ch === '"' || ch === "'" || ch === "`") { + state.tokenize = tokenString(ch) + return state.tokenize(stream, state) + } + + // r'foo' or c'foo' + // r"foo" or c"foo" + if ( + (ch === "r" || ch === "c") && + (stream.peek() == '"' || stream.peek() == "'") + ) { + const next = stream.next() + if (next === null) { + return "string" + } + state.tokenize = tokenRawString(next) + return "string" + } + + if (ch === ".") { + if (!stream.match(/^[0-9]+([eE][\-+]?[0-9]+)?/)) { + return "operator" + } + } + + // probably attribute + // [attr] + // [attr: value] + // [attr1; attr2] + if (ch === "[") { + // [unsafe] + if (stream.match(simpleAttributesRegexp)) { + return "attribute" + } + + // [sql: foo] + if (stream.match(singleKeyValueAttributesRegexp)) { + return "attribute" + } + + // [sql; foo] + if (stream.match(severalSingleKeyValueAttributesRegexp)) { + return "attribute" + } + + // [attr: value; attr: value] + // [attr: value; attr] + if (stream.match(keyValueAttributesRegexp)) { + return "attribute" + } + + // match `[if some ?]` + if (stream.match(ifAttributesRegexp)) { + return "attribute" + } + } + + if (/[\d.]/.test(ch)) { + if (ch === "0") { + stream.match(/^[xX][0-9a-fA-F_]+/) || + stream.match(/^o[0-7_]+/) || + stream.match(/^b[0-1_]+/) + } else { + stream.match(/^[0-9_]*\.?[0-9_]*([eE][\-+]?[0-9_]+)?/) + } + return "number" + } + if (/[\[\]{}(),;:.]/.test(ch)) { + curPunc = ch + return null + } + if (ch === "/") { + if (stream.eat("*")) { + state.tokenize = tokenComment + return tokenComment(stream, state) + } + if (stream.eat("/")) { + stream.skipToEnd() + return "comment" + } + } + if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar) + return "operator" + } + + if (ch === "@") { + eatIdentifier(stream) + return "at-identifier" + } + + if (ch === "$") { + const ident = eatIdentifier(stream).slice(1) + if (keywords.has(ident)) { + return "keyword" + } + + return "compile-time-identifier" + } + + stream.backUp(2) + const wasDot = stream.next() === "." + stream.next() + + const cur = eatIdentifier(stream) + if (cur === "import") { + state.context.expectedImportName = true + } + + if (keywords.has(cur)) return "keyword" + if (pseudoKeywords.has(cur)) return "keyword" + if (atoms.has(cur)) return "atom" + if (hashDirectives.has(cur)) return "hash-directive" + + if (!wasDot) { + // don't highlight `foo.int()` + // ^^^ as builtin + if (builtinTypes.has(cur)) return "builtin" + } + + if (cur.length > 0 && cur[0].toUpperCase() === cur[0]) { + return "type" + } + + const next = stream.peek() + if (next === "(" || next === "<") { + return "function" + } + + if (next === "[") { + stream.next() + const after = stream.next() + stream.backUp(2) + if (after != null && after.match(/[A-Z]/i)) { + return "function" + } + } + + // highlight only last part + // example: + // import foo.boo + // ^^^ - only this part will be highlighted + if (state.context.expectedImportName && stream.peek() !== ".") { + state.context.expectedImportName = false + if (state.context.knownImports === undefined) { + state.context.knownImports = new Set() + } + state.context.knownImports.add(cur) + return "import-name" + } + + if (wasDot) { + return "property" + } + + // highlight only identifier with dot after it + // example: + // import foo + // import bar + // + // foo.bar + // ^^^ - only this part will be highlighted + if (state.context.knownImports.has(cur) && stream.peek() == ".") { + return "import-name" + } + + return "variable" + } + + function tokenLongInterpolation(stream, state) { + if (stream.match("}")) { + state.tokenize = tokenString(state.context.stringQuote) + return "end-interpolation" + } + state.tokenize = tokenBase + return state.tokenize(stream, state) + } + + function tokenShortInterpolation(stream, state) { + const ch = stream.next() + if (ch === " ") { + state.tokenize = tokenString(state.context.stringQuote) + return state.tokenize(stream, state) + } + if (ch === ".") { + return "operator" + } + + const ident = eatIdentifier(stream) + if (ident[0].toLowerCase() === ident[0].toUpperCase()) { + state.tokenize = tokenString(state.context.stringQuote) + return state.tokenize(stream, state) + } + + const next = stream.next() + stream.backUp(1) + if (next === ".") { + state.tokenize = tokenShortInterpolation + } else { + state.tokenize = tokenString(state.context.stringQuote) + } + + return "variable" + } + + function tokenNextInterpolation(stream, state) { + let next = stream.next() + if (next === "$" && stream.eat("{")) { + state.tokenize = tokenLongInterpolation + return "start-interpolation" + } + if (next === "$") { + state.tokenize = tokenShortInterpolation + return "start-interpolation" + } + + return "string" + } + + function tokenNextEscape(stream, state) { + let next = stream.next() + if (next === "\\") { + stream.next() + state.tokenize = tokenString(state.context.stringQuote) + // we already know that next char is valid escape + return "valid-escape" + } + + return "string" + } + + function isValidEscapeChar(ch) { + return ( + ch === "n" || + ch === "t" || + ch === "r" || + ch === "\\" || + ch === '"' || + ch === "'" || + ch === "0" + ) + } + + function tokenString(quote) { + return function(stream, state) { + state.context.insideString = true + state.context.stringQuote = quote + + let next = "" + let escaped = false + let end = false + + while ((next = stream.next()) != null) { + if (next === quote && !escaped) { + end = true + break + } + if (next === "$" && !escaped && stream.eat("{")) { + state.tokenize = tokenNextInterpolation + stream.backUp(2) + return "string" + } + if (next === "$" && !escaped) { + state.tokenize = tokenNextInterpolation + stream.backUp(1) + return "string" + } + if (escaped && isValidEscapeChar(next)) { + stream.backUp(2) + state.tokenize = tokenNextEscape + return "string" + } + escaped = !escaped && next === "\\" + } + + if (end || escaped) { + state.tokenize = tokenBase + } + + state.context.insideString = false + state.context.stringQuote = null + return "string" + } + } + + function tokenRawString(quote) { + return function(stream, state) { + state.context.insideString = true + state.context.stringQuote = quote + + let next = "" + let escaped = false + let end = false + + while ((next = stream.next()) != null) { + if (next === quote && !escaped) { + end = true + break + } + escaped = !escaped && next === "\\" + } + + if (end || escaped) { + state.tokenize = tokenBase + } + + state.context.insideString = false + state.context.stringQuote = null + return "string" + } + } + + function tokenComment(stream, state) { + let maybeEnd = false + let ch + while ((ch = stream.next())) { + if (ch === "/" && maybeEnd) { + state.tokenize = tokenBase + break + } + maybeEnd = ch === "*" + } + return "comment" + } + + function pushContext(state, column, type) { + return (state.context = new Context( + state.indention, + column, + type, + null, + state.context, + state.context.knownImports + )) + } + + function popContext(state) { + if (!state.context.prev) return + const t = state.context.type + if (t === ")" || t === "]" || t === "}") + state.indention = state.context.indentation + state.context = state.context.prev + return state.context + } + + return { + startState: function() { + return { + tokenize: null, + context: new Context(0, 0, "top", false), + indention: 0, + startOfLine: true + } + }, + + token: function(stream, state) { + const ctx = state.context + if (stream.sol()) { + if (ctx.align == null) { + ctx.align = false + } + state.indention = stream.indentation() + state.startOfLine = true + } + if (stream.eatSpace()) { + return null + } + curPunc = null + const style = state.tokenize || tokenBase(stream, state) + if (style === "comment") { + return style + } + if (ctx.align == null) { + ctx.align = true + } + + if (curPunc === "{") pushContext(state, stream.column(), "}") + else if (curPunc === "[") pushContext(state, stream.column(), "]") + else if (curPunc === "(") pushContext(state, stream.column(), ")") + else if (curPunc === "}" && ctx.type === "}") popContext(state) + else if (curPunc === ctx.type) popContext(state) + state.startOfLine = false + return style + }, + + indent: function(state, textAfter) { + if (state.tokenize !== tokenBase && state.tokenize != null) { + return 0 + } + + if (state.context.type == "top") { + return 0 + } + + const ctx = state.context + const firstChar = textAfter.charAt(0) + + const closing = firstChar === ctx.type + if (ctx.align) { + return ctx.column + (closing ? 0 : 1) + } + + return ctx.indentation + (closing ? 0 : indentUnit) + }, + + // @ts-ignore + electricChars: "{}):", + // @ts-ignore + closeBrackets: "()[]{}''\"\"``", + fold: "brace", + blockCommentStart: "/*", + blockCommentEnd: "*/", + lineComment: "//" + } +}) + +CodeMirror.defineMIME("text/x-v", "v"); + +}); diff --git a/templates/assets/scripts/search.js b/templates/assets/scripts/search.js deleted file mode 100644 index ef0d1ecb9..000000000 --- a/templates/assets/scripts/search.js +++ /dev/null @@ -1,145 +0,0 @@ -const original_docs_md_url = 'https://github.com/vlang/v/blob/master/doc/docs.md'; -const search_source_url = 'https://docs.vlang.io/assets/docs.md'; -let file_content = null; - -// Function to fetch and cache the file content -async function fetchFileContent() { - try { - const response = await fetch(search_source_url); - if (!response.ok) { - throw new Error('Network response was not ok ' + response.statusText); - } - file_content = await response.text(); - } catch (error) { - console.error('Failed to fetch file content:', error); - } -} - -// Function to parse the markdown content and create a map of sections -function parseMarkdown(content) { - const lines = content.split('\n'); - const sections = {}; - let currentSection = ''; - - lines.forEach(line => { - const sectionMatch = line.match(/^##+\s+(.+)/); // Match headers (##, ###, etc.) - if (sectionMatch) { - currentSection = sectionMatch[1]; - sections[currentSection] = []; - } else if (currentSection) { - sections[currentSection].push(line); - } - }); - - return sections; -} - -// Function to search through the cached file content and map results to sections -function searchFileContent(query) { - if (!file_content) { - return 'File content not loaded. Please try again later.'; - } - - const sections = parseMarkdown(file_content); - const results = []; - const regex = new RegExp(query, 'gi'); - - for (const section in sections) { - const sectionContent = sections[section].join('\n'); - const match = sectionContent.match(regex); - if (match) { - results.push({ section, snippet: getSnippet(sectionContent, match[0]) }); - } - } - - // Filter out the "Table of Contents" section - return results.filter(result => result.section.toLowerCase() !== 'table of contents'); -} - -// Function to get a snippet of text around the first match -function getSnippet(content, match) { - const index = content.indexOf(match); - const snippetLength = 100; - const start = Math.max(index - snippetLength / 2, 0); - const end = Math.min(index + snippetLength / 2, content.length); - return content.substring(start, end).replace(/\n/g, ' ') + '...'; -} - -// Function to create links to the relevant sections in the docs -function createResultLinks(results) { - if (typeof results === 'string') { - return results; - } - - return results.map(result => { - const sectionLink = sectionToLink(result.section); - return ` -
- ${result.section} -

${result.snippet}

-
- `; - }).join(''); -} - -// Helper function to convert section titles to links -function sectionToLink(section) { - const fixed_url = titles_to_fnames[ section ]; - if (fixed_url) { return fixed_url; } - const existing_html_page = fnames[ section ]; - if (existing_html_page) { return existing_html_page; } - // try with a simpler normalized version of the section title: - const slug = section.toLowerCase().replace(/\s+/g, '-').replace(/[^\w-]+/g, '') - const sfixed_url = titles_to_fnames[ slug ]; - if (sfixed_url) { return sfixed_url; } - const sexisting_html_page = fnames[ slug ]; - if (sexisting_html_page) { return sexisting_html_page; } - // probably a 3rd level or lower title, that currently has no reverse mapping; redirect to the main docs.md: - return `${original_docs_md_url}#${slug}`; -} - -function display_search_results(how) { - document.getElementById('searchResults').style.display = how; -} - -async function handleSearch() { - const query = document.getElementById('searchInput').value; - const resultsElement = document.getElementById('searchResults'); - if (!file_content) { - await fetchFileContent(); - } - const results = searchFileContent(query); - resultsElement.innerHTML = createResultLinks(results); - display_search_results("block"); -} - -// Initialize the search functionality when the DOM is fully loaded -document.addEventListener('DOMContentLoaded', () => { - const searchInput = document.getElementById('searchInput'); - const searchKeys = document.getElementById('searchKeys'); - searchKeys.innerHTML = (navigator.platform.includes('Mac') ? '⌘' : 'Ctrl') + ' K'; - document.addEventListener('keydown', (event) => { - if ((event.ctrlKey || event.metaKey) && event.key === 'k') { - event.preventDefault(); - searchInput.focus(); - } - }); - searchInput.onfocus = () => searchKeys.style.display = 'none'; - searchInput.onblur = () => searchKeys.style.display = 'block'; - searchInput.onkeydown = (event) => { - if (event.key === 'Enter') { - handleSearch(); - } else if (event.key === 'Escape') { - if (document.getElementById('searchResults').style.display === 'none') { - searchInput.blur(); - return - } - display_search_results("none"); - } - }; - document.getElementById('searchButton').onclick(handleSearch); -}); - -window.onbeforeunload = function () { - display_search_results("none"); -} diff --git a/templates/assets/scripts/theme.js b/templates/assets/scripts/theme.js deleted file mode 100644 index 544fb7336..000000000 --- a/templates/assets/scripts/theme.js +++ /dev/null @@ -1,43 +0,0 @@ -const playgrounds = []; - -document.addEventListener('DOMContentLoaded', () => { - const theme = localStorage.getItem("theme"); - if (theme) { - setTheme(theme); - } else { - const theme = document.querySelector("html").getAttribute("data-theme"); - - localStorage.setItem("theme", theme); - setTheme(theme); - } - - const changeThemeButton = document.querySelector(".js-change-theme__action"); - changeThemeButton.addEventListener("click", () => { - const currentTheme = document.documentElement.getAttribute("data-theme"); - const newTheme = currentTheme === "dark" ? "light" : "dark"; - - setTheme(newTheme); - }); -}); - -function setTheme(newTheme) { - const changeThemeButton = document.querySelector(".js-change-theme__action"); - document.documentElement.setAttribute("data-theme", newTheme); - localStorage.setItem("theme", newTheme); - - const svgSun = changeThemeButton.querySelector(".sun"); - const svgMoon = changeThemeButton.querySelector(".moon"); - if (newTheme === "dark") { - svgSun.style.display = "block"; - svgMoon.style.display = "none"; - } else { - svgSun.style.display = "none"; - svgMoon.style.display = "block"; - } - - if (playgrounds !== undefined) { - playgrounds.forEach(playground => { - playground.setTheme(newTheme); - }); - } -} diff --git a/templates/assets/scripts/v-docs.js b/templates/assets/scripts/v-docs.js new file mode 100644 index 000000000..700b0a9e3 --- /dev/null +++ b/templates/assets/scripts/v-docs.js @@ -0,0 +1,593 @@ +// Function to fetch and cache the file content +async function fetchFileContent(file_url) { + try { + const response = await fetch(file_url); + if (!response.ok) { + throw new Error('Network response was not ok ' + response.statusText); + } + return await response.text(); + } catch (error) { + console.error('Failed to fetch file content:', error); + return ''; + } + +} + + +var vdocs = { + config: { + url_docs_md_original: 'https://github.com/vlang/v/blob/master/doc/docs.md', + url_docs_md_full_source: 'https://docs.vlang.io/assets/docs.md', + url_playground: 'https://play.vlang.io' + }, + hydrate: function(){ + this.ui.hydrateTheme(); + this.ui.hydrateSidebar(); + this.ui.hydrateSearch(); + vdocs.examples.init(); + }, +}; + +vdocs.ui = { + btnChangeTheme: null, + currentTheme: 'dark', + + tocPanel: null, + sidebar: null, + hydrateSidebar: function(){ + this.sidebar = document.getElementById("sidebar-main"); + this.tocPanel = document.getElementById("topics"); + + document.querySelector(".sidebar-open-btn").addEventListener("click", (event) => { + this.sidebar.style.setProperty('display', 'block') + }) + + document.querySelector(".sidebar-close-btn").addEventListener("click", (event) => { + this.sidebar.style.setProperty('display', 'none') + }) + + //scroll to show selected topic + const target = document.querySelector('.nav-entry.is-selected'); + target.scrollIntoView({ behavior: 'smooth', block: 'center' }); + + }, + hydrateTheme: function(){ + this.btnChangeTheme = document.querySelector("header .change-theme"); + this.currentTheme = document.querySelector("html").getAttribute("data-theme"); + + const theme = localStorage.getItem("theme"); + if (theme) { + this.setTheme(theme); + } else { + this.setTheme(this.currentTheme); + } + + + this.btnChangeTheme.addEventListener("click", () => { + const new_theme = this.currentTheme =='dark' ? 'light': 'dark'; + localStorage.setItem("theme", new_theme); + this.setTheme(new_theme); + }); + }, + setTheme: function(newTheme) { + this.currentTheme = newTheme; + document.querySelector("html").setAttribute("data-theme", newTheme); + const svgSun = this.btnChangeTheme.querySelector(".sun"); + const svgMoon = this.btnChangeTheme.querySelector(".moon"); + if (newTheme === "dark") { + svgSun.style.display = "block"; + svgMoon.style.display = "none"; + } else { + svgSun.style.display = "none"; + svgMoon.style.display = "block"; + } + + vdocs.examples.onThemeChanged(newTheme); + + }, + searchInput: null, + searchResults: null, + searchVisible: false, + hydrateSearch: function(){ + // Initialize the search functionality when the DOM is fully loaded + this.searchInput = document.getElementById('search-input'); + + const searchKeys = document.getElementById('search-kb-shortcut'); + searchKeys.innerHTML = (navigator.platform.includes('Mac') ? '⌘' : 'Ctrl') + ' K'; + + var handleDocKey = (e)=>{ + const key = event.key; // const {key} = event; in ES6+ + if (key === "Escape") { + this.hideSearchResults(); + } + }; + + const closeBtn = document.getElementById('search-results-close'); + closeBtn.addEventListener('click', (event) => { + event.preventDefault(); + this.hideSearchResults(); + }); + + document.addEventListener('keydown', (event) => { + + if ((event.ctrlKey || event.metaKey) && event.key === 'k') { + event.preventDefault(); + this.searchInput.value = ''; + this.searchInput.focus(); + }else if (event.key === "Escape" && this.searchVisible) { + event.preventDefault(); + this.hideSearchResults(); + } + }); + + this.searchResults = document.getElementById('search-results'); + this.searchResultsContainer = document.getElementById('search-result-container'); + + this.searchInput.onfocus = () => searchKeys.style.display = 'none'; + this.searchInput.onblur = () => searchKeys.style.display = 'block'; + this.searchInput.onkeydown = (event) => { + + if (event.key === 'Enter') { + this.handleSearch(); + } else if (event.key === 'Escape') { + if (this.searchResults.style.display === 'none') { + this.searchInput.blur(); + return + } + this.hideSearchResults(); + } + }; + + document.getElementById('search-button').addEventListener('click', (evt)=>{ + this.handleSearch(); + }); + + window.onbeforeunload = () => { + this.hideSearchResults("none"); + }; + }, + helperGetLinkToSection: function(section){ + + const fixed_url = vdocs.titles_to_fnames[ section ]; + if (fixed_url) { return fixed_url; } + + const existing_html_page = vdocs.fnames[ section ]; + if (existing_html_page) { return existing_html_page; } + + // try with a simpler normalized version of the section title: + const slug = section.toLowerCase().replace(/\s+/g, '-').replace(/[^\w-]+/g, ''); + + const sfixed_url = vdocs.titles_to_fnames[ slug ]; + if (sfixed_url) { return sfixed_url; } + + const sexisting_html_page = vdocs.fnames[ slug ]; + if (sexisting_html_page) { return sexisting_html_page; } + + // probably a 3rd level or lower title, that currently has no reverse mapping; redirect to the main docs.md: + return vdocs.config.url_docs_md_original + '#' + slug; + }, + hideSearchResults: function(){ + this.searchVisible = false; + + this.sidebar.classList.remove("search-results-open"); + }, + handleSearch: function(){ + vdocs.search.topic( this.searchInput.value, (items) => this.showSearchResults(items) ); + + }, + showSearchResults: function(items){ + + if (typeof items === 'string') { + return items; + } + + let rows = items.map(item => { + const sectionLink = this.helperGetLinkToSection(item.section); + + return ` +
+ ${item.section} +

${item.snippet}

+
`; + }).join(''); + + this.searchVisible = true; + this.searchResultsContainer.innerHTML = rows; + this.sidebar.classList.add("search-results-open"); + }, + +}; + +vdocs.search = { + source_cache: null, + + topic: function(query, onDone){ + + if(!this.source_cache){ + console.log('loading docs cache from "%s"...', vdocs.config.url_docs_md_full_source); + fetch(vdocs.config.url_docs_md_full_source).then((resp)=>{ + return resp.text(); + }).then((data)=>{ + this.source_cache = data; + this.findTopic(query, onDone); + }).catch(function (err) { + // There was an error + console.warn('Failed to fetch search source.', err); + }); + + return; + } + + this.findTopic(query, onDone); + }, + findTopic: function(query, onDone){ + if (!this.source_cache) { + return 'File content not loaded. Please try again later.'; + } + + const sections = this.parseMarkdown(this.source_cache); + const results = []; + const regex = new RegExp(query, 'gi'); + + for (const section in sections) { + const sectionContent = sections[section].join('\n'); + const match = sectionContent.match(regex); + if (match) { + results.push({ section, snippet: this.getSnippet(sectionContent, match[0]) }); + } + } + + // Filter out the "Table of Contents" section + if(onDone){ + let items = results.filter(result => result.section.toLowerCase() !== 'table of contents'); + onDone(items); + } + + }, + // Function to parse the markdown content and create a map of sections + parseMarkdown: function(content) { + const lines = content.split('\n'); + const sections = {}; + let currentSection = ''; + + lines.forEach(line => { + const sectionMatch = line.match(/^##+\s+(.+)/); // Match headers (##, ###, etc.) + if (sectionMatch) { + currentSection = sectionMatch[1]; + sections[currentSection] = []; + } else if (currentSection) { + sections[currentSection].push(line); + } + }); + + return sections; + }, + + // Function to get a snippet of text around the first match + getSnippet: function(content, match) { + const index = content.indexOf(match); + const snippetLength = 100; + const start = Math.max(index - snippetLength / 2, 0); + const end = Math.min(index + snippetLength / 2, content.length); + return content.substring(start, end).replace(/\n/g, ' ') + '...'; + } + + + +}; + +/* + Uses Codemirror 6 with new `V` mode implemented in "cm-lang-v.js". + https://codemirror.net/docs/ +*/ +vdocs.examples = { + items: [], + init: function(){ + CodeMirror.defineMode("v", vdocs_init_mode); + + let items = document.querySelectorAll('.language-v'); + + for(let el of items){ + this.createEditor(el); + } + }, + onThemeChanged: function(theme){ + for(let item of this.items){ + item[1].setOption("theme", theme); + } + }, + createEditor: function(el){ + //Old codemirror docs https://marijnhaverbeke.nl/blog/codemirror-mode-system.html + + const code = el.textContent; + el.classList.add('v-code-example'); + el.innerHTML = `
+ +
+ + + + + + + + + + Try it... +
+
+ + + + +
+
`; + + let editor = CodeMirror(el, { + value: code, + theme: vdocs.ui.currentTheme, + mode: 'v', + lineNumbers: false, + readOnly: false + }); + + + this.items.push([el, editor]); + + el.querySelector('.v-code-btn-run').addEventListener('click', (evt)=>{ + + let code = editor.getValue(); + let url = "https://play.vlang.io/?base64=" + btoa(code); + + window.open(url, "_blank"); + + return; + + }); + el.querySelector('.v-code-btn-copy').addEventListener('click', (evt)=>{ + let code = editor.getValue(); + navigator.clipboard.writeText(code); + }); + }, + run: function(el, editor){ + const data = new FormData(); + + //Old server https://play.vosca.dev/ is defunc + + let code = editor.getValue(); + data.append('code', code); + + //Attempt to use play.vlang.io but cloudflare doesnt play nice here... + fetch('https://play.vlang.io/run_test', { + method: 'POST', + mode: 'no-cors', + headers: { + 'Host': 'play.vlang.io', + 'Accept': '*/*', + 'User-Agent': 'curl/8.4.0' + }, + body: data, + }).then((response) => { + console.log(response); + response.headers.forEach(function(val, key) { console.log(key + ' -> ' + val); }); + + return response.json() + }).then((data) => { + console.log(data); + }) + .catch((error) => { + console.log(error); + }); + + }, + +} + +document.addEventListener('DOMContentLoaded', () => { + vdocs.hydrate(); +}); + +function vdocs_init_mode(config){ + //Creates a CM5 Language Mode + //Deprecated, replaced with CM6 Language Mode in cm-lang-v.js + + //Keywords + var A = new Set([ + "as", "asm", "assert", "atomic", "break", "const", "continue", "defer", "else", "enum", "fn", "for", "go", "goto", "if", "import", "in", "interface", "is", "isreftype", "lock", "match", "module", "mut", "none", "or", "pub", "return", "rlock", "select", "shared", "sizeof", "static", "struct", "spawn", "type", "typeof", "union", "unsafe", "volatile", "__global", "__offsetof", + ]); + //Atoms + var B = new Set(["true", "false", "nil", "print", "println", "exit", "panic", "error", "dump"]); + + //builtin + var W = new Set(["bool", "string", "i8", "i16", "int", "i64", "i128", "u8", "u16", "u32", "u64", "u128", "rune", "f32", "f64", "isize", "usize", "voidptr", "any"]); + + var N = new Set(["sql", "chan", "thread"]); + + const VATTRS = [ + "params", "noinit", "required", "skip", + "assert_continues", "unsafe", "manualfree", "heap", + "nonnull", "primary", "inline", "direct_array_access", "live", "flag", + "noinline", "noreturn", "typedef", "console", "sql", "table", + "deprecated", "deprecated_after", "export", "callconv", + ]; + + let U = "[\\w_]+"; + let Y = `(${U}: ${U})`; + + //RegEx to match attributes + let Q = new RegExp(`^(${VATTRS.join("|")})]$`); + let G = new RegExp(`^(${VATTRS.join("|")}(; ?)?){2,}]$`); + let Z = new RegExp(`^${Y}]$`); + let J = new RegExp(`^((${Y})(; )?){2,}]$`); + let X = new RegExp(`^if ${U} \\??]`); + +var y; + let e = (y = config.indentUnit) != null ? y : 0; + let t = /[+\-*&^%:=<>!?|\/]/; + let n = null; + + function r(i) { + return i.eatWhile(/[\w$_\xa1-\uffff]/), i.current(); + } + function a(i, o) { + return i.match("}") ? ((o.tokenize = g(o.context.stringQuote)), "end-interpolation") : ((o.tokenize = tokenBase), o.tokenize(i, o)); + } + function d(i, o) { + let s = i.next(); + if (s === " ") return (o.tokenize = g(o.context.stringQuote)), o.tokenize(i, o); + if (s === ".") return "operator"; + let h = r(i); + if (h[0].toLowerCase() === h[0].toUpperCase()) return (o.tokenize = g(o.context.stringQuote)), o.tokenize(i, o); + let c = i.next(); + return i.backUp(1), c === "." ? (o.tokenize = d) : (o.tokenize = g(o.context.stringQuote)), "variable"; + } + function p(i, o) { + let s = i.next(); + return s === "$" && i.eat("{") ? ((o.tokenize = a), "start-interpolation") : s === "$" ? ((o.tokenize = d), "start-interpolation") : "string"; + } + function g(i) { + return function (o, s) { + (s.context.insideString = !0), (s.context.stringQuote = i); + let h = "", + c = !1, + x = !1; + for (; (h = o.next()) != null; ) { + if (h === i && !c) { + x = !0; + break; + } + if (h === "$" && !c && o.eat("{")) return (s.tokenize = p), o.backUp(2), "string"; + if (h === "$" && !c) return (s.tokenize = p), o.backUp(1), "string"; + c = !c && h === "\\"; + } + return (x || c) && (s.tokenize = tokenBase), (s.context.insideString = !1), (s.context.stringQuote = null), "string"; + }; + } + function f(i, o) { + let s = !1, + h; + for (; (h = i.next()); ) { + if (h === "/" && s) { + o.tokenize = tokenBase; + break; + } + s = h === "*"; + } + return "comment"; + } + function b(state, column, type) { + return (state.context = new vState(state.indention, column, type, null, state.context)); + } + function m(state) { + if (!state.context.prev) return; + let o = state.context.type; + return (o === ")" || o === "]" || o === "}") && (state.indention = state.context.indentation), (state.context = state.context.prev), state.context; + } + + function tokenBase(stream, state) { + let s = stream.next(); + if (s === null) return null; + + if (state.context.insideString && s === "}") return stream.eat("}"), (state.tokenize = g(state.context.stringQuote)), "end-interpolation"; + + //Is literal string... + if (s === '"' || s === "'" || s === "`") return (state.tokenize = g(s)), state.tokenize(stream, state); + + //Is operator + if (s === "." && !stream.match(/^[0-9]+([eE][\-+]?[0-9]+)?/)) return "operator"; + + //Is attribute? + if (s === "[" && (stream.match(Q) || stream.match(Z) || stream.match(G) || stream.match(J) || stream.match(X))) return "attribute"; + + if (/[\d.]/.test(s)) return s === "0" ? stream.match(/^[xX][0-9a-fA-F_]+/) || stream.match(/^o[0-7_]+/) || stream.match(/^b[0-1_]+/) : stream.match(/^[0-9_]*\.?[0-9_]*([eE][\-+]?[0-9_]+)?/), "number"; + + if (/[\[\]{}(),;:.]/.test(s)) return (n = s), null; + + if (s === "/") { + if (stream.eat("*")) return (state.tokenize = f), f(stream, state); + if (stream.eat("/")) return stream.skipToEnd(), "comment"; + } + + if (t.test(s)) return stream.eatWhile(t), "operator"; + if (s === "@") return r(stream), "at-identifier"; + if (s === "$") { + let M = r(stream).slice(1); + return A.has(M) ? "keyword" : "compile-time-identifier"; + } + stream.backUp(2); + let h = stream.next() === "."; + stream.next(); + + let c = r(stream); + if ((c === "import" && (state.context.expectedImportName = !0), A.has(c) || N.has(c))) return "keyword"; + if (B.has(c)) return "atom"; + if (W.has(c)) return "builtin"; + if (c.length > 0 && c[0].toUpperCase() === c[0]) return "type"; + let x = stream.peek(); + if (x === "(" || x === "<") return "function"; + if (x === "[") { + stream.next(); + let M = stream.next(); + if ((stream.backUp(2), M != null && M.match(/[A-Z]/i))) return "function"; + } + return h + ? "property" + : state.context.expectedImportName && stream.peek() != "." + ? ((state.context.expectedImportName = !1), state.context.knownImports === void 0 && (state.context.knownImports = new Set()), state.context.knownImports.add(c), "import-name") + : state.context.knownImports.has(c) && stream.peek() == "." + ? "import-name" + : "variable"; + } + + class vState { + constructor(e, t, n, r, l) { + this.indentation = e; + this.column = t; + this.type = n; + this.align = r; + this.prev = l; + this.insideString = !1; + this.stringQuote = null; + this.expectedImportName = !1; + this.knownImports = new Set(); + } + }; + + let vMode = { + indent: function (stream, state) { + if ((stream.tokenize !== l && stream.tokenize != null) || stream.context.type == "top") return 0; + let s = stream.context, + c = state.charAt(0) === s.type; + return s.align ? s.column + (c ? 0 : 1) : s.indentation + (c ? 0 : e); + }, + token: function (stream, state) { + let s = state.context; + if ((stream.sol() && (s.align == null && (s.align = !1), (state.indention = stream.indentation()), (state.startOfLine = !0)), stream.eatSpace())) return null; + n = null; + let h = (state.tokenize || tokenBase)(stream, state); + return ( + h === "comment" || + (s.align == null && (s.align = !0), + n === "{" ? b(state, stream.column(), "}") : n === "[" ? b(state, stream.column(), "]") : n === "(" ? b(state, stream.column(), ")") : ((n === "}" && s.type === "}") || n === s.type) && m(state), + (state.startOfLine = !1)), + h + ); + }, + electricChars: "{}):", + closeBrackets: "()[]{}''\"\"``", + fold: "brace", + blockCommentStart: "/*", + blockCommentEnd: "*/", + lineComment: "//", + startState: function () { + return { tokenize: null, context: new vState(0, 0, "top", !1), indention: 0, startOfLine: !0 }; + }, + }; + + return vMode; + + + +} + diff --git a/templates/assets/scripts/vlang-playground.js b/templates/assets/scripts/vlang-playground.js deleted file mode 100644 index 5db43a481..000000000 --- a/templates/assets/scripts/vlang-playground.js +++ /dev/null @@ -1,114 +0,0 @@ -(function(global,factory){typeof exports==="object"&&typeof module!=="undefined"?module.exports=factory():typeof define==="function"&&define.amd?define(factory):(global=global||self,global.CodeMirror=factory())})(this,function(){"use strict";var userAgent=navigator.userAgent;var platform=navigator.platform;var gecko=/gecko\/\d/i.test(userAgent);var ie_upto10=/MSIE \d/.test(userAgent);var ie_11up=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent);var edge=/Edge\/(\d+)/.exec(userAgent);var ie=ie_upto10||ie_11up||edge;var ie_version=ie&&(ie_upto10?document.documentMode||6:+(edge||ie_11up)[1]);var webkit=!edge&&/WebKit\//.test(userAgent);var qtwebkit=webkit&&/Qt\/\d+\.\d+/.test(userAgent);var chrome=!edge&&/Chrome\/(\d+)/.exec(userAgent);var chrome_version=chrome&&+chrome[1];var presto=/Opera\//.test(userAgent);var safari=/Apple Computer/.test(navigator.vendor);var mac_geMountainLion=/Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent);var phantom=/PhantomJS/.test(userAgent);var ios=safari&&(/Mobile\/\w+/.test(userAgent)||navigator.maxTouchPoints>2);var android=/Android/.test(userAgent);var mobile=ios||android||/webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent);var mac=ios||/Mac/.test(platform);var chromeOS=/\bCrOS\b/.test(userAgent);var windows=/win/i.test(platform);var presto_version=presto&&userAgent.match(/Version\/(\d*\.\d*)/);if(presto_version){presto_version=Number(presto_version[1])}if(presto_version&&presto_version>=15){presto=false;webkit=true}var flipCtrlCmd=mac&&(qtwebkit||presto&&(presto_version==null||presto_version<12.11));var captureRightClick=gecko||ie&&ie_version>=9;function classTest(cls){return new RegExp("(^|\\s)"+cls+"(?:$|\\s)\\s*")}var rmClass=function(node,cls){var current=node.className;var match=classTest(cls).exec(current);if(match){var after=current.slice(match.index+match[0].length);node.className=current.slice(0,match.index)+(after?match[1]+after:"")}};function removeChildren(e){for(var count=e.childNodes.length;count>0;--count){e.removeChild(e.firstChild)}return e}function removeChildrenAndAdd(parent,e){return removeChildren(parent).appendChild(e)}function elt(tag,content,className,style){var e=document.createElement(tag);if(className){e.className=className}if(style){e.style.cssText=style}if(typeof content=="string"){e.appendChild(document.createTextNode(content))}else if(content){for(var i=0;i=end){return n+(end-i)}n+=nextTab-i;n+=tabSize-n%tabSize;i=nextTab+1}}var Delayed=function(){this.id=null;this.f=null;this.time=0;this.handler=bind(this.onTimeout,this)};Delayed.prototype.onTimeout=function(self){self.id=0;if(self.time<=+new Date){self.f()}else{setTimeout(self.handler,self.time-+new Date)}};Delayed.prototype.set=function(ms,f){this.f=f;var time=+new Date+ms;if(!this.id||time=goal){return pos+Math.min(skipped,goal-col)}col+=nextTab-pos;col+=tabSize-col%tabSize;pos=nextTab+1;if(col>=goal){return pos}}}var spaceStrs=[""];function spaceStr(n){while(spaceStrs.length<=n){spaceStrs.push(lst(spaceStrs)+" ")}return spaceStrs[n]}function lst(arr){return arr[arr.length-1]}function map(array,f){var out=[];for(var i=0;i"€"&&(ch.toUpperCase()!=ch.toLowerCase()||nonASCIISingleCaseWordChar.test(ch))}function isWordChar(ch,helper){if(!helper){return isWordCharBasic(ch)}if(helper.source.indexOf("\\w")>-1&&isWordCharBasic(ch)){return true}return helper.test(ch)}function isEmpty(obj){for(var n in obj){if(obj.hasOwnProperty(n)&&obj[n]){return false}}return true}var 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]/;function isExtendingChar(ch){return ch.charCodeAt(0)>=768&&extendingChars.test(ch)}function skipExtendingChars(str,pos,dir){while((dir<0?pos>0:posto?-1:1;for(;;){if(from==to){return from}var midF=(from+to)/2,mid=dir<0?Math.ceil(midF):Math.floor(midF);if(mid==from){return pred(mid)?from:to}if(pred(mid)){to=mid}else{from=mid+dir}}}function iterateBidiSections(order,from,to,f){if(!order){return f(from,to,"ltr",0)}var found=false;for(var i=0;ifrom||from==to&&part.to==from){f(Math.max(part.from,from),Math.min(part.to,to),part.level==1?"rtl":"ltr",i);found=true}}if(!found){f(from,to,"ltr")}}var bidiOther=null;function getBidiPartAt(order,ch,sticky){var found;bidiOther=null;for(var i=0;ich){return i}if(cur.to==ch){if(cur.from!=cur.to&&sticky=="before"){found=i}else{bidiOther=i}}if(cur.from==ch){if(cur.from!=cur.to&&sticky!="before"){found=i}else{bidiOther=i}}}return found!=null?found:bidiOther}var bidiOrdering=function(){var lowTypes="bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN";var arabicTypes="nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111";function charType(code){if(code<=247){return lowTypes.charAt(code)}else if(1424<=code&&code<=1524){return"R"}else if(1536<=code&&code<=1785){return arabicTypes.charAt(code-1536)}else if(1774<=code&&code<=2220){return"r"}else if(8192<=code&&code<=8203){return"w"}else if(code==8204){return"b"}else{return"L"}}var bidiRE=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;var isNeutral=/[stwN]/,isStrong=/[LRr]/,countsAsLeft=/[Lb1n]/,countsAsNum=/[1n]/;function BidiSpan(level,from,to){this.level=level;this.from=from;this.to=to}return function(str,direction){var outerType=direction=="ltr"?"L":"R";if(str.length==0||direction=="ltr"&&!bidiRE.test(str)){return false}var len=str.length,types=[];for(var i=0;i-1){map[type]=arr.slice(0,index).concat(arr.slice(index+1))}}}}function signal(emitter,type){var handlers=getHandlers(emitter,type);if(!handlers.length){return}var args=Array.prototype.slice.call(arguments,2);for(var i=0;i0}function eventMixin(ctor){ctor.prototype.on=function(type,f){on(this,type,f)};ctor.prototype.off=function(type,f){off(this,type,f)}}function e_preventDefault(e){if(e.preventDefault){e.preventDefault()}else{e.returnValue=false}}function e_stopPropagation(e){if(e.stopPropagation){e.stopPropagation()}else{e.cancelBubble=true}}function e_defaultPrevented(e){return e.defaultPrevented!=null?e.defaultPrevented:e.returnValue==false}function e_stop(e){e_preventDefault(e);e_stopPropagation(e)}function e_target(e){return e.target||e.srcElement}function e_button(e){var b=e.which;if(b==null){if(e.button&1){b=1}else if(e.button&2){b=3}else if(e.button&4){b=2}}if(mac&&e.ctrlKey&&b==1){b=3}return b}var dragAndDrop=function(){if(ie&&ie_version<9){return false}var div=elt("div");return"draggable"in div||"dragDrop"in div}();var zwspSupported;function zeroWidthElement(measure){if(zwspSupported==null){var test=elt("span","​");removeChildrenAndAdd(measure,elt("span",[test,document.createTextNode("x")]));if(measure.firstChild.offsetHeight!=0){zwspSupported=test.offsetWidth<=1&&test.offsetHeight>2&&!(ie&&ie_version<8)}}var node=zwspSupported?elt("span","​"):elt("span"," ",null,"display: inline-block; width: 1px; margin-right: -1px");node.setAttribute("cm-text","");return node}var badBidiRects;function hasBadBidiRects(measure){if(badBidiRects!=null){return badBidiRects}var txt=removeChildrenAndAdd(measure,document.createTextNode("AخA"));var r0=range(txt,0,1).getBoundingClientRect();var r1=range(txt,1,2).getBoundingClientRect();removeChildren(measure);if(!r0||r0.left==r0.right){return false}return badBidiRects=r1.right-r0.right<3}var splitLinesAuto="\n\nb".split(/\n/).length!=3?function(string){var pos=0,result=[],l=string.length;while(pos<=l){var nl=string.indexOf("\n",pos);if(nl==-1){nl=string.length}var line=string.slice(pos,string.charAt(nl-1)=="\r"?nl-1:nl);var rt=line.indexOf("\r");if(rt!=-1){result.push(line.slice(0,rt));pos+=rt+1}else{result.push(line);pos=nl+1}}return result}:function(string){return string.split(/\r\n?|\n/)};var hasSelection=window.getSelection?function(te){try{return te.selectionStart!=te.selectionEnd}catch(e){return false}}:function(te){var range;try{range=te.ownerDocument.selection.createRange()}catch(e){}if(!range||range.parentElement()!=te){return false}return range.compareEndPoints("StartToEnd",range)!=0};var hasCopyEvent=function(){var e=elt("div");if("oncopy"in e){return true}e.setAttribute("oncopy","return;");return typeof e.oncopy=="function"}();var badZoomedRects=null;function hasBadZoomedRects(measure){if(badZoomedRects!=null){return badZoomedRects}var node=removeChildrenAndAdd(measure,elt("span","x"));var normal=node.getBoundingClientRect();var fromRange=range(node,0,1).getBoundingClientRect();return badZoomedRects=Math.abs(normal.left-fromRange.left)>1}var modes={},mimeModes={};function defineMode(name,mode){if(arguments.length>2){mode.dependencies=Array.prototype.slice.call(arguments,2)}modes[name]=mode}function defineMIME(mime,spec){mimeModes[mime]=spec}function resolveMode(spec){if(typeof spec=="string"&&mimeModes.hasOwnProperty(spec)){spec=mimeModes[spec]}else if(spec&&typeof spec.name=="string"&&mimeModes.hasOwnProperty(spec.name)){var found=mimeModes[spec.name];if(typeof found=="string"){found={name:found}}spec=createObj(found,spec);spec.name=found.name}else if(typeof spec=="string"&&/^[\w\-]+\/[\w\-]+\+xml$/.test(spec)){return resolveMode("application/xml")}else if(typeof spec=="string"&&/^[\w\-]+\/[\w\-]+\+json$/.test(spec)){return resolveMode("application/json")}if(typeof spec=="string"){return{name:spec}}else{return spec||{name:"null"}}}function getMode(options,spec){spec=resolveMode(spec);var mfactory=modes[spec.name];if(!mfactory){return getMode(options,"text/plain")}var modeObj=mfactory(options,spec);if(modeExtensions.hasOwnProperty(spec.name)){var exts=modeExtensions[spec.name];for(var prop in exts){if(!exts.hasOwnProperty(prop)){continue}if(modeObj.hasOwnProperty(prop)){modeObj["_"+prop]=modeObj[prop]}modeObj[prop]=exts[prop]}}modeObj.name=spec.name;if(spec.helperType){modeObj.helperType=spec.helperType}if(spec.modeProps){for(var prop$1 in spec.modeProps){modeObj[prop$1]=spec.modeProps[prop$1]}}return modeObj}var modeExtensions={};function extendMode(mode,properties){var exts=modeExtensions.hasOwnProperty(mode)?modeExtensions[mode]:modeExtensions[mode]={};copyObj(properties,exts)}function copyState(mode,state){if(state===true){return state}if(mode.copyState){return mode.copyState(state)}var nstate={};for(var n in state){var val=state[n];if(val instanceof Array){val=val.concat([])}nstate[n]=val}return nstate}function innerMode(mode,state){var info;while(mode.innerMode){info=mode.innerMode(state);if(!info||info.mode==mode){break}state=info.state;mode=info.mode}return info||{mode:mode,state:state}}function startState(mode,a1,a2){return mode.startState?mode.startState(a1,a2):true}var StringStream=function(string,tabSize,lineOracle){this.pos=this.start=0;this.string=string;this.tabSize=tabSize||8;this.lastColumnPos=this.lastColumnValue=0;this.lineStart=0;this.lineOracle=lineOracle};StringStream.prototype.eol=function(){return this.pos>=this.string.length};StringStream.prototype.sol=function(){return this.pos==this.lineStart};StringStream.prototype.peek=function(){return this.string.charAt(this.pos)||undefined};StringStream.prototype.next=function(){if(this.posstart};StringStream.prototype.eatSpace=function(){var start=this.pos;while(/[\s\u00a0]/.test(this.string.charAt(this.pos))){++this.pos}return this.pos>start};StringStream.prototype.skipToEnd=function(){this.pos=this.string.length};StringStream.prototype.skipTo=function(ch){var found=this.string.indexOf(ch,this.pos);if(found>-1){this.pos=found;return true}};StringStream.prototype.backUp=function(n){this.pos-=n};StringStream.prototype.column=function(){if(this.lastColumnPos0){return null}if(match&&consume!==false){this.pos+=match[0].length}return match}};StringStream.prototype.current=function(){return this.string.slice(this.start,this.pos)};StringStream.prototype.hideFirstChars=function(n,inner){this.lineStart+=n;try{return inner()}finally{this.lineStart-=n}};StringStream.prototype.lookAhead=function(n){var oracle=this.lineOracle;return oracle&&oracle.lookAhead(n)};StringStream.prototype.baseToken=function(){var oracle=this.lineOracle;return oracle&&oracle.baseToken(this.pos)};function getLine(doc,n){n-=doc.first;if(n<0||n>=doc.size){throw new Error("There is no line "+(n+doc.first)+" in the document.")}var chunk=doc;while(!chunk.lines){for(var i=0;;++i){var child=chunk.children[i],sz=child.chunkSize();if(n=doc.first&&llast){return Pos(last,getLine(doc,last).text.length)}return clipToLen(pos,getLine(doc,pos.line).text.length)}function clipToLen(pos,linelen){var ch=pos.ch;if(ch==null||ch>linelen){return Pos(pos.line,linelen)}else if(ch<0){return Pos(pos.line,0)}else{return pos}}function clipPosArray(doc,array){var out=[];for(var i=0;ithis.maxLookAhead){this.maxLookAhead=n}return line};Context.prototype.baseToken=function(n){if(!this.baseTokens){return null}while(this.baseTokens[this.baseTokenPos]<=n){this.baseTokenPos+=2}var type=this.baseTokens[this.baseTokenPos+1];return{type:type&&type.replace(/( |^)overlay .*/,""),size:this.baseTokens[this.baseTokenPos]-n}};Context.prototype.nextLine=function(){this.line++;if(this.maxLookAhead>0){this.maxLookAhead--}};Context.fromSaved=function(doc,saved,line){if(saved instanceof SavedContext){return new Context(doc,copyState(doc.mode,saved.state),line,saved.lookAhead)}else{return new Context(doc,copyState(doc.mode,saved),line)}};Context.prototype.save=function(copy){var state=copy!==false?copyState(this.doc.mode,this.state):this.state;return this.maxLookAhead>0?new SavedContext(state,this.maxLookAhead):state};function highlightLine(cm,line,context,forceToEnd){var st=[cm.state.modeGen],lineClasses={};runMode(cm,line.text,cm.doc.mode,context,function(end,style){return st.push(end,style)},lineClasses,forceToEnd);var state=context.state;var loop=function(o){context.baseTokens=st;var overlay=cm.state.overlays[o],i=1,at=0;context.state=true;runMode(cm,line.text,overlay.mode,context,function(end,style){var start=i;while(atend){st.splice(i,1,end,st[i+1],i_end)}i+=2;at=Math.min(end,i_end)}if(!style){return}if(overlay.opaque){st.splice(start,i-start,end,"overlay "+style);i=start+2}else{for(;startcm.options.maxHighlightLength&©State(cm.doc.mode,context.state);var result=highlightLine(cm,line,context);if(resetState){context.state=resetState}line.stateAfter=context.save(!resetState);line.styles=result.styles;if(result.classes){line.styleClasses=result.classes}else if(line.styleClasses){line.styleClasses=null}if(updateFrontier===cm.doc.highlightFrontier){cm.doc.modeFrontier=Math.max(cm.doc.modeFrontier,++cm.doc.highlightFrontier)}}return line.styles}function getContextBefore(cm,n,precise){var doc=cm.doc,display=cm.display;if(!doc.mode.startState){return new Context(doc,true,n)}var start=findStartLine(cm,n,precise);var saved=start>doc.first&&getLine(doc,start-1).stateAfter;var context=saved?Context.fromSaved(doc,saved,start):new Context(doc,startState(doc.mode),start);doc.iter(start,n,function(line){processLine(cm,line.text,context);var pos=context.line;line.stateAfter=pos==n-1||pos%5==0||pos>=display.viewFrom&&posstream.start){return style}}throw new Error("Mode "+mode.name+" failed to advance stream.")}var Token=function(stream,type,state){this.start=stream.start;this.end=stream.pos;this.string=stream.current();this.type=type||null;this.state=state};function takeToken(cm,pos,precise,asArray){var doc=cm.doc,mode=doc.mode,style;pos=clipPos(doc,pos);var line=getLine(doc,pos.line),context=getContextBefore(cm,pos.line,precise);var stream=new StringStream(line.text,cm.options.tabSize,context),tokens;if(asArray){tokens=[]}while((asArray||stream.poscm.options.maxHighlightLength){flattenSpans=false;if(forceToEnd){processLine(cm,text,context,stream.pos)}stream.pos=text.length;style=null}else{style=extractLineClasses(readToken(mode,stream,context.state,inner),lineClasses)}if(inner){var mName=inner[0].name;if(mName){style="m-"+(style?mName+" "+style:mName)}}if(!flattenSpans||curStyle!=style){while(curStartlim;--search){if(search<=doc.first){return doc.first}var line=getLine(doc,search-1),after=line.stateAfter;if(after&&(!precise||search+(after instanceof SavedContext?after.lookAhead:0)<=doc.modeFrontier)){return search}var indented=countColumn(line.text,null,cm.options.tabSize);if(minline==null||minindent>indented){minline=search-1;minindent=indented}}return minline}function retreatFrontier(doc,n){doc.modeFrontier=Math.min(doc.modeFrontier,n);if(doc.highlightFrontierstart;line--){var saved=getLine(doc,line).stateAfter;if(saved&&(!(saved instanceof SavedContext)||line+saved.lookAhead=startCh:span.to>startCh);(nw||(nw=[])).push(new MarkedSpan(marker,span.from,endsAfter?null:span.to))}}}return nw}function markedSpansAfter(old,endCh,isInsert){var nw;if(old){for(var i=0;i=endCh:span.to>endCh);if(endsAfter||span.from==endCh&&marker.type=="bookmark"&&(!isInsert||span.marker.insertLeft)){var startsBefore=span.from==null||(marker.inclusiveLeft?span.from<=endCh:span.from0&&first){for(var i$2=0;i$20){continue}var newParts=[j,1],dfrom=cmp(p.from,m.from),dto=cmp(p.to,m.to);if(dfrom<0||!mk.inclusiveLeft&&!dfrom){newParts.push({from:p.from,to:m.from})}if(dto>0||!mk.inclusiveRight&&!dto){newParts.push({from:m.to,to:p.to})}parts.splice.apply(parts,newParts);j+=newParts.length-3}}return parts}function detachMarkedSpans(line){var spans=line.markedSpans;if(!spans){return}for(var i=0;ich)&&(!found||compareCollapsedMarkers(found,sp.marker)<0)){found=sp.marker}}}return found}function conflictingCollapsedRange(doc,lineNo,from,to,marker){var line=getLine(doc,lineNo);var sps=sawCollapsedSpans&&line.markedSpans;if(sps){for(var i=0;i=0&&toCmp<=0||fromCmp<=0&&toCmp>=0){continue}if(fromCmp<=0&&(sp.marker.inclusiveRight&&marker.inclusiveLeft?cmp(found.to,from)>=0:cmp(found.to,from)>0)||fromCmp>=0&&(sp.marker.inclusiveRight&&marker.inclusiveLeft?cmp(found.from,to)<=0:cmp(found.from,to)<0)){return true}}}}function visualLine(line){var merged;while(merged=collapsedSpanAtStart(line)){line=merged.find(-1,true).line}return line}function visualLineEnd(line){var merged;while(merged=collapsedSpanAtEnd(line)){line=merged.find(1,true).line}return line}function visualLineContinued(line){var merged,lines;while(merged=collapsedSpanAtEnd(line)){line=merged.find(1,true).line;(lines||(lines=[])).push(line)}return lines}function visualLineNo(doc,lineN){var line=getLine(doc,lineN),vis=visualLine(line);if(line==vis){return lineN}return lineNo(vis)}function visualLineEndNo(doc,lineN){if(lineN>doc.lastLine()){return lineN}var line=getLine(doc,lineN),merged;if(!lineIsHidden(doc,line)){return lineN}while(merged=collapsedSpanAtEnd(line)){line=merged.find(1,true).line}return lineNo(line)+1}function lineIsHidden(doc,line){var sps=sawCollapsedSpans&&line.markedSpans;if(sps){for(var sp=void 0,i=0;id.maxLineLength){d.maxLineLength=len;d.maxLine=line}})}var Line=function(text,markedSpans,estimateHeight){this.text=text;attachMarkedSpans(this,markedSpans);this.height=estimateHeight?estimateHeight(this):1};Line.prototype.lineNo=function(){return lineNo(this)};eventMixin(Line);function updateLine(line,text,markedSpans,estimateHeight){line.text=text;if(line.stateAfter){line.stateAfter=null}if(line.styles){line.styles=null}if(line.order!=null){line.order=null}detachMarkedSpans(line);attachMarkedSpans(line,markedSpans);var estHeight=estimateHeight?estimateHeight(line):1;if(estHeight!=line.height){updateLineHeight(line,estHeight)}}function cleanUpLine(line){line.parent=null;detachMarkedSpans(line)}var styleToClassCache={},styleToClassCacheWithMode={};function interpretTokenStyle(style,options){if(!style||/^\s*$/.test(style)){return null}var cache=options.addModeClass?styleToClassCacheWithMode:styleToClassCache;return cache[style]||(cache[style]=style.replace(/\S+/g,"cm-$&"))}function buildLineContent(cm,lineView){var content=eltP("span",null,null,webkit?"padding-right: .1px":null);var builder={pre:eltP("pre",[content],"CodeMirror-line"),content:content,col:0,pos:0,cm:cm,trailingSpace:false,splitSpaces:cm.getOption("lineWrapping")};lineView.measure={};for(var i=0;i<=(lineView.rest?lineView.rest.length:0);i++){var line=i?lineView.rest[i-1]:lineView.line,order=void 0;builder.pos=0;builder.addToken=buildToken;if(hasBadBidiRects(cm.display.measure)&&(order=getOrder(line,cm.doc.direction))){builder.addToken=buildTokenBadBidi(builder.addToken,order)}builder.map=[];var allowFrontierUpdate=lineView!=cm.display.externalMeasured&&lineNo(line);insertLineContent(line,builder,getLineStyles(cm,line,allowFrontierUpdate));if(line.styleClasses){if(line.styleClasses.bgClass){builder.bgClass=joinClasses(line.styleClasses.bgClass,builder.bgClass||"")}if(line.styleClasses.textClass){builder.textClass=joinClasses(line.styleClasses.textClass,builder.textClass||"")}}if(builder.map.length==0){builder.map.push(0,0,builder.content.appendChild(zeroWidthElement(cm.display.measure)))}if(i==0){lineView.measure.map=builder.map;lineView.measure.cache={}}else{(lineView.measure.maps||(lineView.measure.maps=[])).push(builder.map);(lineView.measure.caches||(lineView.measure.caches=[])).push({})}}if(webkit){var last=builder.content.lastChild;if(/\bcm-tab\b/.test(last.className)||last.querySelector&&last.querySelector(".cm-tab")){builder.content.className="cm-tab-wrap-hack"}}signal(cm,"renderLine",cm,lineView.line,builder.pre);if(builder.pre.className){builder.textClass=joinClasses(builder.pre.className,builder.textClass||"")}return builder}function defaultSpecialCharPlaceholder(ch){var token=elt("span","•","cm-invalidchar");token.title="\\u"+ch.charCodeAt(0).toString(16);token.setAttribute("aria-label",token.title);return token}function buildToken(builder,text,style,startStyle,endStyle,css,attributes){if(!text){return}var displayText=builder.splitSpaces?splitSpaces(text,builder.trailingSpace):text;var special=builder.cm.state.specialChars,mustWrap=false;var content;if(!special.test(text)){builder.col+=text.length;content=document.createTextNode(displayText);builder.map.push(builder.pos,builder.pos+text.length,content);if(ie&&ie_version<9){mustWrap=true}builder.pos+=text.length}else{content=document.createDocumentFragment();var pos=0;while(true){special.lastIndex=pos;var m=special.exec(text);var skipped=m?m.index-pos:text.length-pos;if(skipped){var txt=document.createTextNode(displayText.slice(pos,pos+skipped));if(ie&&ie_version<9){content.appendChild(elt("span",[txt]))}else{content.appendChild(txt)}builder.map.push(builder.pos,builder.pos+skipped,txt);builder.col+=skipped;builder.pos+=skipped}if(!m){break}pos+=skipped+1;var txt$1=void 0;if(m[0]=="\t"){var tabSize=builder.cm.options.tabSize,tabWidth=tabSize-builder.col%tabSize;txt$1=content.appendChild(elt("span",spaceStr(tabWidth),"cm-tab"));txt$1.setAttribute("role","presentation");txt$1.setAttribute("cm-text","\t");builder.col+=tabWidth}else if(m[0]=="\r"||m[0]=="\n"){txt$1=content.appendChild(elt("span",m[0]=="\r"?"␍":"␤","cm-invalidchar"));txt$1.setAttribute("cm-text",m[0]);builder.col+=1}else{txt$1=builder.cm.options.specialCharPlaceholder(m[0]);txt$1.setAttribute("cm-text",m[0]);if(ie&&ie_version<9){content.appendChild(elt("span",[txt$1]))}else{content.appendChild(txt$1)}builder.col+=1}builder.map.push(builder.pos,builder.pos+1,txt$1);builder.pos++}}builder.trailingSpace=displayText.charCodeAt(text.length-1)==32;if(style||startStyle||endStyle||mustWrap||css||attributes){var fullStyle=style||"";if(startStyle){fullStyle+=startStyle}if(endStyle){fullStyle+=endStyle}var token=elt("span",[content],fullStyle,css);if(attributes){for(var attr in attributes){if(attributes.hasOwnProperty(attr)&&attr!="style"&&attr!="class"){token.setAttribute(attr,attributes[attr])}}}return builder.content.appendChild(token)}builder.content.appendChild(content)}function splitSpaces(text,trailingBefore){if(text.length>1&&!/ /.test(text)){return text}var spaceBefore=trailingBefore,result="";for(var i=0;istart&&part.from<=start){break}}if(part.to>=end){return inner(builder,text,style,startStyle,endStyle,css,attributes)}inner(builder,text.slice(0,part.to-start),style,startStyle,null,css,attributes);startStyle=null;text=text.slice(part.to-start);start=part.to}}}function buildCollapsedSpan(builder,size,marker,ignoreWidget){var widget=!ignoreWidget&&marker.widgetNode;if(widget){builder.map.push(builder.pos,builder.pos+size,widget)}if(!ignoreWidget&&builder.cm.display.input.needsContentAttribute){if(!widget){widget=builder.content.appendChild(document.createElement("span"))}widget.setAttribute("cm-marker",marker.id)}if(widget){builder.cm.display.input.setUneditable(widget);builder.content.appendChild(widget)}builder.pos+=size;builder.trailingSpace=false}function insertLineContent(line,builder,styles){var spans=line.markedSpans,allText=line.text,at=0;if(!spans){for(var i$1=1;i$1pos||m.collapsed&&sp.to==pos&&sp.from==pos)){if(sp.to!=null&&sp.to!=pos&&nextChange>sp.to){nextChange=sp.to;spanEndStyle=""}if(m.className){spanStyle+=" "+m.className}if(m.css){css=(css?css+";":"")+m.css}if(m.startStyle&&sp.from==pos){spanStartStyle+=" "+m.startStyle}if(m.endStyle&&sp.to==nextChange){(endStyles||(endStyles=[])).push(m.endStyle,sp.to)}if(m.title){(attributes||(attributes={})).title=m.title}if(m.attributes){for(var attr in m.attributes){(attributes||(attributes={}))[attr]=m.attributes[attr]}}if(m.collapsed&&(!collapsed||compareCollapsedMarkers(collapsed.marker,m)<0)){collapsed=sp}}else if(sp.from>pos&&nextChange>sp.from){nextChange=sp.from}}if(endStyles){for(var j$1=0;j$1=len){break}var upto=Math.min(len,nextChange);while(true){if(text){var end=pos+text.length;if(!collapsed){var tokenText=end>upto?text.slice(0,upto-pos):text;builder.addToken(builder,tokenText,style?style+spanStyle:spanStyle,spanStartStyle,pos+tokenText.length==nextChange?spanEndStyle:"",css,attributes)}if(end>=upto){text=text.slice(upto-pos);pos=upto;break}pos=end;spanStartStyle=""}text=allText.slice(at,at=styles[i++]);style=interpretTokenStyle(styles[i++],builder.cm.options)}}}function LineView(doc,line,lineN){this.line=line;this.rest=visualLineContinued(line);this.size=this.rest?lineNo(lst(this.rest))-lineN+1:1;this.node=this.text=null;this.hidden=lineIsHidden(doc,line)}function buildViewArray(cm,from,to){var array=[],nextPos;for(var pos=from;pos2){heights.push((cur.bottom+next.top)/2-rect.top)}}}heights.push(rect.bottom-rect.top)}}function mapFromLineView(lineView,line,lineN){if(lineView.line==line){return{map:lineView.measure.map,cache:lineView.measure.cache}}if(lineView.rest){for(var i=0;ilineN){return{map:lineView.measure.maps[i$1],cache:lineView.measure.caches[i$1],before:true}}}}}function updateExternalMeasurement(cm,line){line=visualLine(line);var lineN=lineNo(line);var view=cm.display.externalMeasured=new LineView(cm.doc,line,lineN);view.lineN=lineN;var built=view.built=buildLineContent(cm,view);view.text=built.pre;removeChildrenAndAdd(cm.display.lineMeasure,built.pre);return view}function measureChar(cm,line,ch,bias){return measureCharPrepared(cm,prepareMeasureForLine(cm,line),ch,bias)}function findViewForLine(cm,lineN){if(lineN>=cm.display.viewFrom&&lineN=ext.lineN&&lineNch){end=mEnd-mStart;start=end-1;if(ch>=mEnd){collapse="right"}}if(start!=null){node=map[i+2];if(mStart==mEnd&&bias==(node.insertLeft?"left":"right")){collapse=bias}if(bias=="left"&&start==0){while(i&&map[i-2]==map[i-3]&&map[i-1].insertLeft){node=map[(i-=3)+2];collapse="left"}}if(bias=="right"&&start==mEnd-mStart){while(i=0;i$1--){if((rect=rects[i$1]).left!=rect.right){break}}}return rect}function measureCharInner(cm,prepared,ch,bias){var place=nodeAndOffsetInLineMap(prepared.map,ch,bias);var node=place.node,start=place.start,end=place.end,collapse=place.collapse;var rect;if(node.nodeType==3){for(var i$1=0;i$1<4;i$1++){while(start&&isExtendingChar(prepared.line.text.charAt(place.coverStart+start))){--start}while(place.coverStart+end0){collapse=bias="right"}var rects;if(cm.options.lineWrapping&&(rects=node.getClientRects()).length>1){rect=rects[bias=="right"?rects.length-1:0]}else{rect=node.getBoundingClientRect()}}if(ie&&ie_version<9&&!start&&(!rect||!rect.left&&!rect.right)){var rSpan=node.parentNode.getClientRects()[0];if(rSpan){rect={left:rSpan.left,right:rSpan.left+charWidth(cm.display),top:rSpan.top,bottom:rSpan.bottom}}else{rect=nullRect}}var rtop=rect.top-prepared.rect.top,rbot=rect.bottom-prepared.rect.top;var mid=(rtop+rbot)/2;var heights=prepared.view.measure.heights;var i=0;for(;i=lineObj.text.length){ch=lineObj.text.length;sticky="before"}else if(ch<=0){ch=0;sticky="after"}if(!order){return get(sticky=="before"?ch-1:ch,sticky=="before")}function getBidi(ch,partPos,invert){var part=order[partPos],right=part.level==1;return get(invert?ch-1:ch,right!=invert)}var partPos=getBidiPartAt(order,ch,sticky);var other=bidiOther;var val=getBidi(ch,partPos,sticky=="before");if(other!=null){val.other=getBidi(ch,other,sticky!="before")}return val}function estimateCoords(cm,pos){var left=0;pos=clipPos(cm.doc,pos);if(!cm.options.lineWrapping){left=charWidth(cm.display)*pos.ch}var lineObj=getLine(cm.doc,pos.line);var top=heightAtLine(lineObj)+paddingTop(cm.display);return{left:left,right:left,top:top,bottom:top+lineObj.height}}function PosWithInfo(line,ch,sticky,outside,xRel){var pos=Pos(line,ch,sticky);pos.xRel=xRel;if(outside){pos.outside=outside}return pos}function coordsChar(cm,x,y){var doc=cm.doc;y+=cm.display.viewOffset;if(y<0){return PosWithInfo(doc.first,0,null,-1,-1)}var lineN=lineAtHeight(doc,y),last=doc.first+doc.size-1;if(lineN>last){return PosWithInfo(doc.first+doc.size-1,getLine(doc,last).text.length,null,1,1)}if(x<0){x=0}var lineObj=getLine(doc,lineN);for(;;){var found=coordsCharInner(cm,lineObj,lineN,x,y);var collapsed=collapsedSpanAround(lineObj,found.ch+(found.xRel>0||found.outside>0?1:0));if(!collapsed){return found}var rangeEnd=collapsed.find(1);if(rangeEnd.line==lineN){return rangeEnd}lineObj=getLine(doc,lineN=rangeEnd.line)}}function wrappedLineExtent(cm,lineObj,preparedMeasure,y){y-=widgetTopHeight(lineObj);var end=lineObj.text.length;var begin=findFirst(function(ch){return measureCharPrepared(cm,preparedMeasure,ch-1).bottom<=y},end,0);end=findFirst(function(ch){return measureCharPrepared(cm,preparedMeasure,ch).top>y},begin,end);return{begin:begin,end:end}}function wrappedLineExtentChar(cm,lineObj,preparedMeasure,target){if(!preparedMeasure){preparedMeasure=prepareMeasureForLine(cm,lineObj)}var targetTop=intoCoordSystem(cm,lineObj,measureCharPrepared(cm,preparedMeasure,target),"line").top;return wrappedLineExtent(cm,lineObj,preparedMeasure,targetTop)}function boxIsAfter(box,x,y,left){return box.bottom<=y?false:box.top>y?true:(left?box.left:box.right)>x}function coordsCharInner(cm,lineObj,lineNo,x,y){y-=heightAtLine(lineObj);var preparedMeasure=prepareMeasureForLine(cm,lineObj);var widgetHeight=widgetTopHeight(lineObj);var begin=0,end=lineObj.text.length,ltr=true;var order=getOrder(lineObj,cm.doc.direction);if(order){var part=(cm.options.lineWrapping?coordsBidiPartWrapped:coordsBidiPart)(cm,lineObj,lineNo,preparedMeasure,order,x,y);ltr=part.level!=1;begin=ltr?part.from:part.to-1;end=ltr?part.to:part.from-1}var chAround=null,boxAround=null;var ch=findFirst(function(ch){var box=measureCharPrepared(cm,preparedMeasure,ch);box.top+=widgetHeight;box.bottom+=widgetHeight;if(!boxIsAfter(box,x,y,false)){return false}if(box.top<=y&&box.left<=x){chAround=ch;boxAround=box}return true},begin,end);var baseX,sticky,outside=false;if(boxAround){var atLeft=x-boxAround.left=coords.bottom?1:0}ch=skipExtendingChars(lineObj.text,ch,1);return PosWithInfo(lineNo,ch,sticky,outside,x-baseX)}function coordsBidiPart(cm,lineObj,lineNo,preparedMeasure,order,x,y){var index=findFirst(function(i){var part=order[i],ltr=part.level!=1;return boxIsAfter(cursorCoords(cm,Pos(lineNo,ltr?part.to:part.from,ltr?"before":"after"),"line",lineObj,preparedMeasure),x,y,true)},0,order.length-1);var part=order[index];if(index>0){var ltr=part.level!=1;var start=cursorCoords(cm,Pos(lineNo,ltr?part.from:part.to,ltr?"after":"before"),"line",lineObj,preparedMeasure);if(boxIsAfter(start,x,y,true)&&start.top>y){part=order[index-1]}}return part}function coordsBidiPartWrapped(cm,lineObj,_lineNo,preparedMeasure,order,x,y){var ref=wrappedLineExtent(cm,lineObj,preparedMeasure,y);var begin=ref.begin;var end=ref.end;if(/\s/.test(lineObj.text.charAt(end-1))){end--}var part=null,closestDist=null;for(var i=0;i=end||p.to<=begin){continue}var ltr=p.level!=1;var endX=measureCharPrepared(cm,preparedMeasure,ltr?Math.min(end,p.to)-1:Math.max(begin,p.from)).right;var dist=endXdist){part=p;closestDist=dist}}if(!part){part=order[order.length-1]}if(part.fromend){part={from:part.from,to:end,level:part.level}}return part}var measureText;function textHeight(display){if(display.cachedTextHeight!=null){return display.cachedTextHeight}if(measureText==null){measureText=elt("pre",null,"CodeMirror-line-like");for(var i=0;i<49;++i){measureText.appendChild(document.createTextNode("x"));measureText.appendChild(elt("br"))}measureText.appendChild(document.createTextNode("x"))}removeChildrenAndAdd(display.measure,measureText);var height=measureText.offsetHeight/50;if(height>3){display.cachedTextHeight=height}removeChildren(display.measure);return height||1}function charWidth(display){if(display.cachedCharWidth!=null){return display.cachedCharWidth}var anchor=elt("span","xxxxxxxxxx");var pre=elt("pre",[anchor],"CodeMirror-line-like");removeChildrenAndAdd(display.measure,pre);var rect=anchor.getBoundingClientRect(),width=(rect.right-rect.left)/10;if(width>2){display.cachedCharWidth=width}return width||10}function getDimensions(cm){var d=cm.display,left={},width={};var gutterLeft=d.gutters.clientLeft;for(var n=d.gutters.firstChild,i=0;n;n=n.nextSibling,++i){var id=cm.display.gutterSpecs[i].className;left[id]=n.offsetLeft+n.clientLeft+gutterLeft;width[id]=n.clientWidth}return{fixedPos:compensateForHScroll(d),gutterTotalWidth:d.gutters.offsetWidth,gutterLeft:left,gutterWidth:width,wrapperWidth:d.wrapper.clientWidth}}function compensateForHScroll(display){return display.scroller.getBoundingClientRect().left-display.sizer.getBoundingClientRect().left}function estimateHeight(cm){var th=textHeight(cm.display),wrapping=cm.options.lineWrapping;var perLine=wrapping&&Math.max(5,cm.display.scroller.clientWidth/charWidth(cm.display)-3);return function(line){if(lineIsHidden(cm.doc,line)){return 0}var widgetsHeight=0;if(line.widgets){for(var i=0;i0&&(line=getLine(cm.doc,coords.line).text).length==coords.ch){var colDiff=countColumn(line,line.length,cm.options.tabSize)-line.length;coords=Pos(coords.line,Math.max(0,Math.round((x-paddingH(cm.display).left)/charWidth(cm.display))-colDiff))}return coords}function findViewIndex(cm,n){if(n>=cm.display.viewTo){return null}n-=cm.display.viewFrom;if(n<0){return null}var view=cm.display.view;for(var i=0;ifrom)){display.updateLineNumbers=from}cm.curOp.viewChanged=true;if(from>=display.viewTo){if(sawCollapsedSpans&&visualLineNo(cm.doc,from)display.viewFrom){resetView(cm)}else{display.viewFrom+=lendiff;display.viewTo+=lendiff}}else if(from<=display.viewFrom&&to>=display.viewTo){resetView(cm)}else if(from<=display.viewFrom){var cut=viewCuttingPoint(cm,to,to+lendiff,1);if(cut){display.view=display.view.slice(cut.index);display.viewFrom=cut.lineN;display.viewTo+=lendiff}else{resetView(cm)}}else if(to>=display.viewTo){var cut$1=viewCuttingPoint(cm,from,from,-1);if(cut$1){display.view=display.view.slice(0,cut$1.index);display.viewTo=cut$1.lineN}else{resetView(cm)}}else{var cutTop=viewCuttingPoint(cm,from,from,-1);var cutBot=viewCuttingPoint(cm,to,to+lendiff,1);if(cutTop&&cutBot){display.view=display.view.slice(0,cutTop.index).concat(buildViewArray(cm,cutTop.lineN,cutBot.lineN)).concat(display.view.slice(cutBot.index));display.viewTo+=lendiff}else{resetView(cm)}}var ext=display.externalMeasured;if(ext){if(to=ext.lineN&&line=display.viewTo){return}var lineView=display.view[findViewIndex(cm,line)];if(lineView.node==null){return}var arr=lineView.changes||(lineView.changes=[]);if(indexOf(arr,type)==-1){arr.push(type)}}function resetView(cm){cm.display.viewFrom=cm.display.viewTo=cm.doc.first;cm.display.view=[];cm.display.viewOffset=0}function viewCuttingPoint(cm,oldN,newN,dir){var index=findViewIndex(cm,oldN),diff,view=cm.display.view;if(!sawCollapsedSpans||newN==cm.doc.first+cm.doc.size){return{index:index,lineN:newN}}var n=cm.display.viewFrom;for(var i=0;i0){if(index==view.length-1){return null}diff=n+view[index].size-oldN;index++}else{diff=n-oldN}oldN+=diff;newN+=diff}while(visualLineNo(cm.doc,newN)!=newN){if(index==(dir<0?0:view.length-1)){return null}newN+=dir*view[index-(dir<0?1:0)].size;index+=dir}return{index:index,lineN:newN}}function adjustView(cm,from,to){var display=cm.display,view=display.view;if(view.length==0||from>=display.viewTo||to<=display.viewFrom){display.view=buildViewArray(cm,from,to);display.viewFrom=from}else{if(display.viewFrom>from){display.view=buildViewArray(cm,from,display.viewFrom).concat(display.view)}else if(display.viewFromto){display.view=display.view.slice(0,findViewIndex(cm,to))}}display.viewTo=to}function countDirtyView(cm){var view=cm.display.view,dirty=0;for(var i=0;i=cm.display.viewTo||range.to().line0?width:cm.defaultCharWidth())+"px"}if(pos.other){var otherCursor=output.appendChild(elt("div"," ","CodeMirror-cursor CodeMirror-secondarycursor"));otherCursor.style.display="";otherCursor.style.left=pos.other.left+"px";otherCursor.style.top=pos.other.top+"px";otherCursor.style.height=(pos.other.bottom-pos.other.top)*.85+"px"}}function cmpCoords(a,b){return a.top-b.top||a.left-b.left}function drawSelectionRange(cm,range,output){var display=cm.display,doc=cm.doc;var fragment=document.createDocumentFragment();var padding=paddingH(cm.display),leftSide=padding.left;var rightSide=Math.max(display.sizerWidth,displayWidth(cm)-display.sizer.offsetLeft)-padding.right;var docLTR=doc.direction=="ltr";function add(left,top,width,bottom){if(top<0){top=0}top=Math.round(top);bottom=Math.round(bottom);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"))}function drawForLine(line,fromArg,toArg){var lineObj=getLine(doc,line);var lineLen=lineObj.text.length;var start,end;function coords(ch,bias){return charCoords(cm,Pos(line,ch),"div",lineObj,bias)}function wrapX(pos,dir,side){var extent=wrappedLineExtentChar(cm,lineObj,null,pos);var prop=dir=="ltr"==(side=="after")?"left":"right";var ch=side=="after"?extent.begin:extent.end-(/\s/.test(lineObj.text.charAt(extent.end-1))?2:1);return coords(ch,prop)[prop]}var order=getOrder(lineObj,doc.direction);iterateBidiSections(order,fromArg||0,toArg==null?lineLen:toArg,function(from,to,dir,i){var ltr=dir=="ltr";var fromPos=coords(from,ltr?"left":"right");var toPos=coords(to-1,ltr?"right":"left");var openStart=fromArg==null&&from==0,openEnd=toArg==null&&to==lineLen;var first=i==0,last=!order||i==order.length-1;if(toPos.top-fromPos.top<=3){var openLeft=(docLTR?openStart:openEnd)&&first;var openRight=(docLTR?openEnd:openStart)&&last;var left=openLeft?leftSide:(ltr?fromPos:toPos).left;var right=openRight?rightSide:(ltr?toPos:fromPos).right;add(left,fromPos.top,right-left,fromPos.bottom)}else{var topLeft,topRight,botLeft,botRight;if(ltr){topLeft=docLTR&&openStart&&first?leftSide:fromPos.left;topRight=docLTR?rightSide:wrapX(from,dir,"before");botLeft=docLTR?leftSide:wrapX(to,dir,"after");botRight=docLTR&&openEnd&&last?rightSide:toPos.right}else{topLeft=!docLTR?leftSide:wrapX(from,dir,"before");topRight=!docLTR&&openStart&&first?rightSide:fromPos.right;botLeft=!docLTR&&openEnd&&last?leftSide:toPos.left;botRight=!docLTR?rightSide:wrapX(to,dir,"after")}add(topLeft,fromPos.top,topRight-topLeft,fromPos.bottom);if(fromPos.bottom0){display.blinker=setInterval(function(){if(!cm.hasFocus()){onBlur(cm)}display.cursorDiv.style.visibility=(on=!on)?"":"hidden"},cm.options.cursorBlinkRate)}else if(cm.options.cursorBlinkRate<0){display.cursorDiv.style.visibility="hidden"}}function ensureFocus(cm){if(!cm.hasFocus()){cm.display.input.focus();if(!cm.state.focused){onFocus(cm)}}}function delayBlurEvent(cm){cm.state.delayingBlurEvent=true;setTimeout(function(){if(cm.state.delayingBlurEvent){cm.state.delayingBlurEvent=false;if(cm.state.focused){onBlur(cm)}}},100)}function onFocus(cm,e){if(cm.state.delayingBlurEvent&&!cm.state.draggingText){cm.state.delayingBlurEvent=false}if(cm.options.readOnly=="nocursor"){return}if(!cm.state.focused){signal(cm,"focus",cm,e);cm.state.focused=true;addClass(cm.display.wrapper,"CodeMirror-focused");if(!cm.curOp&&cm.display.selForContextMenu!=cm.doc.sel){cm.display.input.reset();if(webkit){setTimeout(function(){return cm.display.input.reset(true)},20)}}cm.display.input.receivedFocus()}restartBlink(cm)}function onBlur(cm,e){if(cm.state.delayingBlurEvent){return}if(cm.state.focused){signal(cm,"blur",cm,e);cm.state.focused=false;rmClass(cm.display.wrapper,"CodeMirror-focused")}clearInterval(cm.display.blinker);setTimeout(function(){if(!cm.state.focused){cm.display.shift=false}},150)}function updateHeightsInViewport(cm){var display=cm.display;var prevBottom=display.lineDiv.offsetTop;var viewTop=Math.max(0,display.scroller.getBoundingClientRect().top);var oldHeight=display.lineDiv.getBoundingClientRect().top;var mustScroll=0;for(var i=0;i.005||diff<-.005){if(oldHeightcm.display.sizerWidth){var chWidth=Math.ceil(width/charWidth(cm.display));if(chWidth>cm.display.maxLineLength){cm.display.maxLineLength=chWidth;cm.display.maxLine=cur.line;cm.display.maxLineChanged=true}}}if(Math.abs(mustScroll)>2){display.scroller.scrollTop+=mustScroll}}function updateWidgetHeight(line){if(line.widgets){for(var i=0;i=to){from=lineAtHeight(doc,heightAtLine(getLine(doc,ensureTo))-display.wrapper.clientHeight);to=ensureTo}}return{from:from,to:Math.max(to,from+1)}}function maybeScrollWindow(cm,rect){if(signalDOMEvent(cm,"scrollCursorIntoView")){return}var display=cm.display,box=display.sizer.getBoundingClientRect(),doScroll=null;var doc=display.wrapper.ownerDocument;if(rect.top+box.top<0){doScroll=true}else if(rect.bottom+box.top>(doc.defaultView.innerHeight||doc.documentElement.clientHeight)){doScroll=false}if(doScroll!=null&&!phantom){var scrollNode=elt("div","​",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;");cm.display.lineSpace.appendChild(scrollNode);scrollNode.scrollIntoView(doScroll);cm.display.lineSpace.removeChild(scrollNode)}}function scrollPosIntoView(cm,pos,end,margin){if(margin==null){margin=0}var rect;if(!cm.options.lineWrapping&&pos==end){end=pos.sticky=="before"?Pos(pos.line,pos.ch+1,"before"):pos;pos=pos.ch?Pos(pos.line,pos.sticky=="before"?pos.ch-1:pos.ch,"after"):pos}for(var limit=0;limit<5;limit++){var changed=false;var coords=cursorCoords(cm,pos);var endCoords=!end||end==pos?coords:cursorCoords(cm,end);rect={left:Math.min(coords.left,endCoords.left),top:Math.min(coords.top,endCoords.top)-margin,right:Math.max(coords.left,endCoords.left),bottom:Math.max(coords.bottom,endCoords.bottom)+margin};var scrollPos=calculateScrollPos(cm,rect);var startTop=cm.doc.scrollTop,startLeft=cm.doc.scrollLeft;if(scrollPos.scrollTop!=null){updateScrollTop(cm,scrollPos.scrollTop);if(Math.abs(cm.doc.scrollTop-startTop)>1){changed=true}}if(scrollPos.scrollLeft!=null){setScrollLeft(cm,scrollPos.scrollLeft);if(Math.abs(cm.doc.scrollLeft-startLeft)>1){changed=true}}if(!changed){break}}return rect}function scrollIntoView(cm,rect){var scrollPos=calculateScrollPos(cm,rect);if(scrollPos.scrollTop!=null){updateScrollTop(cm,scrollPos.scrollTop)}if(scrollPos.scrollLeft!=null){setScrollLeft(cm,scrollPos.scrollLeft)}}function calculateScrollPos(cm,rect){var display=cm.display,snapMargin=textHeight(cm.display);if(rect.top<0){rect.top=0}var screentop=cm.curOp&&cm.curOp.scrollTop!=null?cm.curOp.scrollTop:display.scroller.scrollTop;var screen=displayHeight(cm),result={};if(rect.bottom-rect.top>screen){rect.bottom=rect.top+screen}var docBottom=cm.doc.height+paddingVert(display);var atTop=rect.topdocBottom-snapMargin;if(rect.topscreentop+screen){var newTop=Math.min(rect.top,(atBottom?docBottom:rect.bottom)-screen);if(newTop!=screentop){result.scrollTop=newTop}}var gutterSpace=cm.options.fixedGutter?0:display.gutters.offsetWidth;var screenleft=cm.curOp&&cm.curOp.scrollLeft!=null?cm.curOp.scrollLeft:display.scroller.scrollLeft-gutterSpace;var screenw=displayWidth(cm)-display.gutters.offsetWidth;var tooWide=rect.right-rect.left>screenw;if(tooWide){rect.right=rect.left+screenw}if(rect.left<10){result.scrollLeft=0}else if(rect.leftscreenw+screenleft-3){result.scrollLeft=rect.right+(tooWide?0:10)-screenw}return result}function addToScrollTop(cm,top){if(top==null){return}resolveScrollToPos(cm);cm.curOp.scrollTop=(cm.curOp.scrollTop==null?cm.doc.scrollTop:cm.curOp.scrollTop)+top}function ensureCursorVisible(cm){resolveScrollToPos(cm);var cur=cm.getCursor();cm.curOp.scrollToPos={from:cur,to:cur,margin:cm.options.cursorScrollMargin}}function scrollToCoords(cm,x,y){if(x!=null||y!=null){resolveScrollToPos(cm)}if(x!=null){cm.curOp.scrollLeft=x}if(y!=null){cm.curOp.scrollTop=y}}function scrollToRange(cm,range){resolveScrollToPos(cm);cm.curOp.scrollToPos=range}function resolveScrollToPos(cm){var range=cm.curOp.scrollToPos;if(range){cm.curOp.scrollToPos=null;var from=estimateCoords(cm,range.from),to=estimateCoords(cm,range.to);scrollToCoordsRange(cm,from,to,range.margin)}}function scrollToCoordsRange(cm,from,to,margin){var sPos=calculateScrollPos(cm,{left:Math.min(from.left,to.left),top:Math.min(from.top,to.top)-margin,right:Math.max(from.right,to.right),bottom:Math.max(from.bottom,to.bottom)+margin});scrollToCoords(cm,sPos.scrollLeft,sPos.scrollTop)}function updateScrollTop(cm,val){if(Math.abs(cm.doc.scrollTop-val)<2){return}if(!gecko){updateDisplaySimple(cm,{top:val})}setScrollTop(cm,val,true);if(gecko){updateDisplaySimple(cm)}startWorker(cm,100)}function setScrollTop(cm,val,forceScroll){val=Math.max(0,Math.min(cm.display.scroller.scrollHeight-cm.display.scroller.clientHeight,val));if(cm.display.scroller.scrollTop==val&&!forceScroll){return}cm.doc.scrollTop=val;cm.display.scrollbars.setScrollTop(val);if(cm.display.scroller.scrollTop!=val){cm.display.scroller.scrollTop=val}}function setScrollLeft(cm,val,isScroller,forceScroll){val=Math.max(0,Math.min(val,cm.display.scroller.scrollWidth-cm.display.scroller.clientWidth));if((isScroller?val==cm.doc.scrollLeft:Math.abs(cm.doc.scrollLeft-val)<2)&&!forceScroll){return}cm.doc.scrollLeft=val;alignHorizontally(cm);if(cm.display.scroller.scrollLeft!=val){cm.display.scroller.scrollLeft=val}cm.display.scrollbars.setScrollLeft(val)}function measureForScrollbars(cm){var d=cm.display,gutterW=d.gutters.offsetWidth;var docH=Math.round(cm.doc.height+paddingVert(cm.display));return{clientHeight:d.scroller.clientHeight,viewHeight:d.wrapper.clientHeight,scrollWidth:d.scroller.scrollWidth,clientWidth:d.scroller.clientWidth,viewWidth:d.wrapper.clientWidth,barLeft:cm.options.fixedGutter?gutterW:0,docHeight:docH,scrollHeight:docH+scrollGap(cm)+d.barHeight,nativeBarWidth:d.nativeBarWidth,gutterWidth:gutterW}}var NativeScrollbars=function(place,scroll,cm){this.cm=cm;var vert=this.vert=elt("div",[elt("div",null,null,"min-width: 1px")],"CodeMirror-vscrollbar");var horiz=this.horiz=elt("div",[elt("div",null,null,"height: 100%; min-height: 1px")],"CodeMirror-hscrollbar");vert.tabIndex=horiz.tabIndex=-1;place(vert);place(horiz);on(vert,"scroll",function(){if(vert.clientHeight){scroll(vert.scrollTop,"vertical")}});on(horiz,"scroll",function(){if(horiz.clientWidth){scroll(horiz.scrollLeft,"horizontal")}});this.checkedZeroWidth=false;if(ie&&ie_version<8){this.horiz.style.minHeight=this.vert.style.minWidth="18px"}};NativeScrollbars.prototype.update=function(measure){var needsH=measure.scrollWidth>measure.clientWidth+1;var needsV=measure.scrollHeight>measure.clientHeight+1;var sWidth=measure.nativeBarWidth;if(needsV){this.vert.style.display="block";this.vert.style.bottom=needsH?sWidth+"px":"0";var totalHeight=measure.viewHeight-(needsH?sWidth:0);this.vert.firstChild.style.height=Math.max(0,measure.scrollHeight-measure.clientHeight+totalHeight)+"px"}else{this.vert.scrollTop=0;this.vert.style.display="";this.vert.firstChild.style.height="0"}if(needsH){this.horiz.style.display="block";this.horiz.style.right=needsV?sWidth+"px":"0";this.horiz.style.left=measure.barLeft+"px";var totalWidth=measure.viewWidth-measure.barLeft-(needsV?sWidth:0);this.horiz.firstChild.style.width=Math.max(0,measure.scrollWidth-measure.clientWidth+totalWidth)+"px"}else{this.horiz.style.display="";this.horiz.firstChild.style.width="0"}if(!this.checkedZeroWidth&&measure.clientHeight>0){if(sWidth==0){this.zeroWidthHack()}this.checkedZeroWidth=true}return{right:needsV?sWidth:0,bottom:needsH?sWidth:0}};NativeScrollbars.prototype.setScrollLeft=function(pos){if(this.horiz.scrollLeft!=pos){this.horiz.scrollLeft=pos}if(this.disableHoriz){this.enableZeroWidthBar(this.horiz,this.disableHoriz,"horiz")}};NativeScrollbars.prototype.setScrollTop=function(pos){if(this.vert.scrollTop!=pos){this.vert.scrollTop=pos}if(this.disableVert){this.enableZeroWidthBar(this.vert,this.disableVert,"vert")}};NativeScrollbars.prototype.zeroWidthHack=function(){var w=mac&&!mac_geMountainLion?"12px":"18px";this.horiz.style.height=this.vert.style.width=w;this.horiz.style.visibility=this.vert.style.visibility="hidden";this.disableHoriz=new Delayed;this.disableVert=new Delayed};NativeScrollbars.prototype.enableZeroWidthBar=function(bar,delay,type){bar.style.visibility="";function maybeDisable(){var box=bar.getBoundingClientRect();var elt=type=="vert"?document.elementFromPoint(box.right-1,(box.top+box.bottom)/2):document.elementFromPoint((box.right+box.left)/2,box.bottom-1);if(elt!=bar){bar.style.visibility="hidden"}else{delay.set(1e3,maybeDisable)}}delay.set(1e3,maybeDisable)};NativeScrollbars.prototype.clear=function(){var parent=this.horiz.parentNode;parent.removeChild(this.horiz);parent.removeChild(this.vert)};var NullScrollbars=function(){};NullScrollbars.prototype.update=function(){return{bottom:0,right:0}};NullScrollbars.prototype.setScrollLeft=function(){};NullScrollbars.prototype.setScrollTop=function(){};NullScrollbars.prototype.clear=function(){};function updateScrollbars(cm,measure){if(!measure){measure=measureForScrollbars(cm)}var startWidth=cm.display.barWidth,startHeight=cm.display.barHeight;updateScrollbarsInner(cm,measure);for(var i=0;i<4&&startWidth!=cm.display.barWidth||startHeight!=cm.display.barHeight;i++){if(startWidth!=cm.display.barWidth&&cm.options.lineWrapping){updateHeightsInViewport(cm)}updateScrollbarsInner(cm,measureForScrollbars(cm));startWidth=cm.display.barWidth;startHeight=cm.display.barHeight}}function updateScrollbarsInner(cm,measure){var d=cm.display;var sizes=d.scrollbars.update(measure);d.sizer.style.paddingRight=(d.barWidth=sizes.right)+"px";d.sizer.style.paddingBottom=(d.barHeight=sizes.bottom)+"px";d.heightForcer.style.borderBottom=sizes.bottom+"px solid transparent";if(sizes.right&&sizes.bottom){d.scrollbarFiller.style.display="block";d.scrollbarFiller.style.height=sizes.bottom+"px";d.scrollbarFiller.style.width=sizes.right+"px"}else{d.scrollbarFiller.style.display=""}if(sizes.bottom&&cm.options.coverGutterNextToScrollbar&&cm.options.fixedGutter){d.gutterFiller.style.display="block";d.gutterFiller.style.height=sizes.bottom+"px";d.gutterFiller.style.width=measure.gutterWidth+"px"}else{d.gutterFiller.style.display=""}}var scrollbarModel={native:NativeScrollbars,null:NullScrollbars};function initScrollbars(cm){if(cm.display.scrollbars){cm.display.scrollbars.clear();if(cm.display.scrollbars.addClass){rmClass(cm.display.wrapper,cm.display.scrollbars.addClass)}}cm.display.scrollbars=new scrollbarModel[cm.options.scrollbarStyle](function(node){cm.display.wrapper.insertBefore(node,cm.display.scrollbarFiller);on(node,"mousedown",function(){if(cm.state.focused){setTimeout(function(){return cm.display.input.focus()},0)}});node.setAttribute("cm-not-content","true")},function(pos,axis){if(axis=="horizontal"){setScrollLeft(cm,pos)}else{updateScrollTop(cm,pos)}},cm);if(cm.display.scrollbars.addClass){addClass(cm.display.wrapper,cm.display.scrollbars.addClass)}}var nextOpId=0;function startOperation(cm){cm.curOp={cm:cm,viewChanged:false,startHeight:cm.doc.height,forceUpdate:false,updateInput:0,typing:false,changeObjs:null,cursorActivityHandlers:null,cursorActivityCalled:0,selectionChanged:false,updateMaxLine:false,scrollLeft:null,scrollTop:null,scrollToPos:null,focus:false,id:++nextOpId,markArrays:null};pushOperation(cm.curOp)}function endOperation(cm){var op=cm.curOp;if(op){finishOperation(op,function(group){for(var i=0;i=display.viewTo)||display.maxLineChanged&&cm.options.lineWrapping;op.update=op.mustUpdate&&new DisplayUpdate(cm,op.mustUpdate&&{top:op.scrollTop,ensure:op.scrollToPos},op.forceUpdate)}function endOperation_W1(op){op.updatedDisplay=op.mustUpdate&&updateDisplayIfNeeded(op.cm,op.update)}function endOperation_R2(op){var cm=op.cm,display=cm.display;if(op.updatedDisplay){updateHeightsInViewport(cm)}op.barMeasure=measureForScrollbars(cm);if(display.maxLineChanged&&!cm.options.lineWrapping){op.adjustWidthTo=measureChar(cm,display.maxLine,display.maxLine.text.length).left+3;cm.display.sizerWidth=op.adjustWidthTo;op.barMeasure.scrollWidth=Math.max(display.scroller.clientWidth,display.sizer.offsetLeft+op.adjustWidthTo+scrollGap(cm)+cm.display.barWidth);op.maxScrollLeft=Math.max(0,display.sizer.offsetLeft+op.adjustWidthTo-displayWidth(cm))}if(op.updatedDisplay||op.selectionChanged){op.preparedSelection=display.input.prepareSelection()}}function endOperation_W2(op){var cm=op.cm;if(op.adjustWidthTo!=null){cm.display.sizer.style.minWidth=op.adjustWidthTo+"px";if(op.maxScrollLeft