From 232e758c7a44f6b048df553abf5bfac1a6b285ef Mon Sep 17 00:00:00 2001 From: Isaac Chuang Date: Sun, 13 May 2012 19:36:01 -0400 Subject: [PATCH] Integrating some of Ike's courseware changes --- djangoapps/courseware/capa/capa_problem.py | 115 ++++++-- djangoapps/courseware/capa/responsetypes.py | 253 ++++++++++++++++-- djangoapps/courseware/content_parser.py | 9 + .../courseware/test_files/imageresponse.xml | 15 ++ djangoapps/ssl_auth/__init__.py | 0 static/css/codemirror.css | 112 ++++++++ static/js/codemirror-compressed.js | 1 + static/js/imageinput.js | 24 ++ templates/solutionspan.html | 3 + templates/textbox.html | 34 +++ 10 files changed, 527 insertions(+), 39 deletions(-) create mode 100644 djangoapps/courseware/test_files/imageresponse.xml create mode 100644 djangoapps/ssl_auth/__init__.py create mode 100644 static/css/codemirror.css create mode 100644 static/js/codemirror-compressed.js create mode 100644 static/js/imageinput.js create mode 100644 templates/solutionspan.html create mode 100644 templates/textbox.html diff --git a/djangoapps/courseware/capa/capa_problem.py b/djangoapps/courseware/capa/capa_problem.py index 5ccbdac897..e164429f11 100644 --- a/djangoapps/courseware/capa/capa_problem.py +++ b/djangoapps/courseware/capa/capa_problem.py @@ -1,3 +1,12 @@ +# +# File: courseware/capa/capa_problem.py +# +''' +Main module which shows problems (of "capa" type). + +This is used by capa_module. +''' + import copy import logging import math @@ -10,12 +19,13 @@ import struct from lxml import etree from lxml.etree import Element +from xml.sax.saxutils import escape, unescape from mako.template import Template from util import contextualize_text import inputtypes -from responsetypes import NumericalResponse, FormulaResponse, CustomResponse, SchematicResponse, MultipleChoiceResponse, StudentInputError, TrueFalseResponse +from responsetypes import NumericalResponse, FormulaResponse, CustomResponse, SchematicResponse, MultipleChoiceResponse, StudentInputError, TrueFalseResponse, ExternalResponse,ImageResponse import calc import eia @@ -26,19 +36,27 @@ response_types = {'numericalresponse':NumericalResponse, 'formularesponse':FormulaResponse, 'customresponse':CustomResponse, 'schematicresponse':SchematicResponse, + 'externalresponse':ExternalResponse, 'multiplechoiceresponse':MultipleChoiceResponse, - 'truefalseresponse':TrueFalseResponse} -entry_types = ['textline', 'schematic', 'choicegroup'] -response_properties = ["responseparam", "answer"] + 'truefalseresponse':TrueFalseResponse, + 'imageresponse':ImageResponse, + } +entry_types = ['textline', 'schematic', 'choicegroup','textbox','imageinput'] +solution_types = ['solution'] # extra things displayed after "show answers" is pressed +response_properties = ["responseparam", "answer"] # these get captured as student responses + # How to convert from original XML to HTML # We should do this with xlst later html_transforms = {'problem': {'tag':'div'}, "numericalresponse": {'tag':'span'}, "customresponse": {'tag':'span'}, + "externalresponse": {'tag':'span'}, "schematicresponse": {'tag':'span'}, "formularesponse": {'tag':'span'}, "multiplechoiceresponse": {'tag':'span'}, - "text": {'tag':'span'}} + "text": {'tag':'span'}, + "math": {'tag':'span'}, + } global_context={'random':random, 'numpy':numpy, @@ -50,7 +68,15 @@ global_context={'random':random, # These should be removed from HTML output, including all subelements html_problem_semantics = ["responseparam", "answer", "script"] # These should be removed from HTML output, but keeping subelements -html_skip = ["numericalresponse", "customresponse", "schematicresponse", "formularesponse", "text"] +html_skip = ["numericalresponse", "customresponse", "schematicresponse", "formularesponse", "text","externalresponse"] + +# removed in MC +## These should be transformed +#html_special_response = {"textline":textline.render, +# "schematic":schematic.render, +# "textbox":textbox.render, +# "solution":solution.render, +# } class LoncapaProblem(object): def __init__(self, fileobject, id, state=None, seed=None): @@ -80,6 +106,7 @@ class LoncapaProblem(object): ## Parse XML file file_text = fileobject.read() + self.fileobject = fileobject # save it, so we can use for debugging information later # Convert startouttext and endouttext to proper # TODO: Do with XML operations file_text = re.sub("startouttext\s*/","text",file_text) @@ -102,6 +129,9 @@ class LoncapaProblem(object): 'done':self.done} def get_max_score(self): + ''' + TODO: multiple points for programming problems. + ''' sum = 0 for et in entry_types: sum = sum + self.tree.xpath('count(//'+et+')') @@ -120,27 +150,39 @@ class LoncapaProblem(object): 'total':self.get_max_score()} def grade_answers(self, answers): + ''' + Grade student responses. Called by capa_module.check_problem. + answers is a dict of all the entries from request.POST, but with the first part + of each key removed (the string before the first "_"). + + Thus, for example, input_ID123 -> ID123, and input_fromjs_ID123 -> fromjs_ID123 + ''' self.student_answers = answers context=self.extract_context(self.tree) self.correct_map = dict() problems_simple = self.extract_problems(self.tree) for response in problems_simple: grader = response_types[response.tag](response, self.context) - results = grader.grade(answers) + results = grader.grade(answers) # call the responsetype instance to do the actual grading self.correct_map.update(results) return self.correct_map def get_question_answers(self): + ''' + Make a dict of (id,correct_answer) entries, for all the problems. + Called by "show answers" button JSON request (see capa_module) + ''' context=self.extract_context(self.tree) answer_map = dict() - problems_simple = self.extract_problems(self.tree) + problems_simple = self.extract_problems(self.tree) # purified (flat) XML tree of just response queries for response in problems_simple: - responder = response_types[response.tag](response, self.context) + responder = response_types[response.tag](response, self.context) # instance of numericalresponse, customresponse,... results = responder.get_answers() - answer_map.update(results) + answer_map.update(results) # dict of (id,correct_answer) + # example for the following: for entry in problems_simple.xpath("//"+"|//".join(response_properties+entry_types)): - answer = entry.get('correct_answer') + answer = entry.get('correct_answer') # correct answer, when specified elsewhere, eg in a textline if answer: answer_map[entry.get('id')] = contextualize_text(answer, self.context) @@ -149,11 +191,28 @@ class LoncapaProblem(object): # ======= Private ======== def extract_context(self, tree, seed = struct.unpack('i', os.urandom(4))[0]): # private - ''' Problem XML goes to Python execution context. Runs everything in script tags ''' + ''' + Extract content of from the problem.xml file, and exec it in the + context of this problem. Provides ability to randomize problems, and also set + variables for problem answer checking. + + Problem XML goes to Python execution context. Runs everything in script tags + ''' random.seed(self.seed) - context = dict() - for script in tree.xpath('/problem/script'): - exec script.text in global_context, context + ### IKE: Why do we need these two lines? + context = {'global_context':global_context} # save global context in here also + global_context['context'] = context # and put link to local context in the global one + + #for script in tree.xpath('/problem/script'): + for script in tree.findall('.//script'): + code = script.text + XMLESC = {"'": "'", """: '"'} + code = unescape(code,XMLESC) + try: + exec code in global_context, context + except Exception,err: + print "[courseware.capa.capa_problem.extract_context] error %s" % err + print "in doing exec of this code:",code return context def get_html(self): @@ -165,14 +224,22 @@ class LoncapaProblem(object): if problemtree.tag in html_problem_semantics: return + problemid = problemtree.get('id') # my ID + + # used to be + # if problemtree.tag in html_special_response: + if hasattr(inputtypes, problemtree.tag): + # status is currently the answer for the problem ID for the input element, + # but it will turn into a dict containing both the answer and any associated message + # for the problem ID for the input element. status = "unsubmitted" - if problemtree.get('id') in self.correct_map: + if problemid in self.correct_map: status = self.correct_map[problemtree.get('id')] value = "" - if self.student_answers and problemtree.get('id') in self.student_answers: - value = self.student_answers[problemtree.get('id')] + if self.student_answers and problemid in self.student_answers: + value = self.student_answers[problemid] return getattr(inputtypes, problemtree.tag)(problemtree, value, status) #TODO @@ -203,7 +270,8 @@ class LoncapaProblem(object): return [tree] def preprocess_problem(self, tree, correct_map=dict(), answer_map=dict()): # private - ''' Assign IDs to all the responses + ''' + Assign IDs to all the responses Assign sub-IDs to all entries (textline, schematic, etc.) Annoted correctness and value In-place transformation @@ -217,13 +285,20 @@ class LoncapaProblem(object): response.attrib['state'] = correct response_id = response_id + 1 answer_id = 1 - for entry in tree.xpath("|".join(['//'+response.tag+'[@id=$id]//'+x for x in entry_types]), + for entry in tree.xpath("|".join(['//'+response.tag+'[@id=$id]//'+x for x in (entry_types + solution_types)]), id=response_id_str): entry.attrib['response_id'] = str(response_id) entry.attrib['answer_id'] = str(answer_id) entry.attrib['id'] = "%s_%i_%i"%(self.problem_id, response_id, answer_id) answer_id=answer_id+1 + # ... may not be associated with any specific response; give IDs for those separately + # TODO: We should make the namespaces consistent and unique (e.g. %s_problem_%i). + solution_id = 1 + for solution in tree.findall('.//solution'): + solution.attrib['id'] = "%s_solution_%i"%(self.problem_id, solution_id) + solution_id += 1 + def extract_problems(self, problem_tree): ''' Remove layout from the problem, and give a purified XML tree of just the problems ''' problem_tree=copy.deepcopy(problem_tree) diff --git a/djangoapps/courseware/capa/responsetypes.py b/djangoapps/courseware/capa/responsetypes.py index 2023e0a067..3922dd4661 100644 --- a/djangoapps/courseware/capa/responsetypes.py +++ b/djangoapps/courseware/capa/responsetypes.py @@ -1,30 +1,37 @@ +# +# File: courseware/capa/responsetypes.py +# +''' +Problem response evaluation. Handles checking of student responses, of a variety of types. + +Used by capa_problem.py +''' + +# standard library imports import json import math import numbers import numpy import random +import re +import requests import scipy import traceback import copy import abc +# specific library imports from calc import evaluator, UndefinedVariable from django.conf import settings from util import contextualize_text from lxml import etree from lxml.etree import Element +from lxml.html.soupparser import fromstring as fromstring_bs # uses Beautiful Soup!!! FIXME? +# local imports import calc import eia -# TODO: Should be the same object as in capa_problem -global_context={'random':random, - 'numpy':numpy, - 'math':math, - 'scipy':scipy, - 'calc':calc, - 'eia':eia} - def compare_with_tolerance(v1, v2, tol): ''' Compare v1 to v2 with maximum tolerance tol @@ -56,6 +63,21 @@ class GenericResponse(object): #Every response type needs methods "grade" and "get_answers" class MultipleChoiceResponse(GenericResponse): + ''' + Example: + + + + `a+b`
+ a+b^2
+ a+b+c + a+b+d +
+
+ + TODO: handle direction and randomize + + ''' def __init__(self, xml, context): self.xml = xml self.correct_choices = xml.xpath('//*[@id=$id]//choice[@correct="true"]', @@ -115,11 +137,17 @@ class NumericalResponse(GenericResponse): def __init__(self, xml, context): self.xml = xml self.correct_answer = contextualize_text(xml.get('answer'), context) - self.tolerance_xml = xml.xpath('//*[@id=$id]//responseparam[@type="tolerance"]/@default', - id=xml.get('id'))[0] - self.tolerance = contextualize_text(self.tolerance_xml, context) - self.answer_id = xml.xpath('//*[@id=$id]//textline/@id', - id=xml.get('id'))[0] + try: + self.tolerance_xml = xml.xpath('//*[@id=$id]//responseparam[@type="tolerance"]/@default', + id=xml.get('id'))[0] + self.tolerance = contextualize_text(self.tolerance_xml, context) + except Exception,err: + self.tolerance = 0 + try: + self.answer_id = xml.xpath('//*[@id=$id]//textline/@id', + id=xml.get('id'))[0] + except Exception, err: + self.answer_id = None def grade(self, student_answers): ''' Display HTML for a numeric response ''' @@ -140,7 +168,50 @@ class NumericalResponse(GenericResponse): def get_answers(self): return {self.answer_id:self.correct_answer} +#----------------------------------------------------------------------------- + class CustomResponse(GenericResponse): + ''' + Custom response. The python code to be run should be in .... Example: + + + +
+ Suppose that \(I(t)\) rises from \(0\) to \(I_S\) at a time \(t_0 \neq 0\) + In the space provided below write an algebraic expression for \(I(t)\). +
+ + + + correct=['correct'] + try: + r = str(submission[0]) + except ValueError: + correct[0] ='incorrect' + r = '0' + if not(r=="IS*u(t-t0)"): + correct[0] ='incorrect' + +
+ + Alternatively, the check function can be defined in Example: + + + + + + + + + ''' def __init__(self, xml, context): self.xml = xml ## CRITICAL TODO: Should cover all entrytypes @@ -163,6 +234,10 @@ class CustomResponse(GenericResponse): self.code = answer.text def grade(self, student_answers): + ''' + student_answers is a dict with everything from request.POST, but with the first part + of each key removed (the string before the first "_"). + ''' submission = [student_answers[k] for k in sorted(self.answer_ids)] self.context.update({'submission':submission}) exec self.code in global_context, self.context @@ -173,19 +248,92 @@ class CustomResponse(GenericResponse): # be handled by capa_problem return {} +#----------------------------------------------------------------------------- + +class ExternalResponse(GenericResponse): + ''' + Grade the student's input using an external server. + + Typically used by coding problems. + ''' + def __init__(self, xml, context): + self.xml = xml + self.answer_ids = xml.xpath('//*[@id=$id]//textbox/@id|//*[@id=$id]//textline/@id', + id=xml.get('id')) + self.context = context + answer = xml.xpath('//*[@id=$id]//answer', + id=xml.get('id'))[0] + + answer_src = answer.get('src') + if answer_src != None: + self.code = open(settings.DATA_DIR+'src/'+answer_src).read() + else: + self.code = answer.text + + self.tests = xml.get('answer') + + def grade(self, student_answers): + submission = [student_answers[k] for k in sorted(self.answer_ids)] + self.context.update({'submission':submission}) + + xmlstr = etree.tostring(self.xml, pretty_print=True) + + payload = {'xml': xmlstr, + ### Question: Is this correct/what we want? Shouldn't this be a json.dumps? + 'LONCAPA_student_response': ''.join(submission), + 'LONCAPA_correct_answer': self.tests, + 'processor' : self.code, + } + + # call external server; TODO: get URL from settings.py + r = requests.post("http://eecs1.mit.edu:8889/pyloncapa",data=payload) + + rxml = etree.fromstring(r.text) # response is XML; prase it + ad = rxml.find('awarddetail').text + admap = {'EXACT_ANS':'correct', # TODO: handle other loncapa responses + 'WRONG_FORMAT': 'incorrect', + } + self.context['correct'] = ['correct'] + if ad in admap: + self.context['correct'][0] = admap[ad] + + # self.context['correct'] = ['correct','correct'] + correct_map = dict(zip(sorted(self.answer_ids), self.context['correct'])) + + # TODO: separate message for each answer_id? + correct_map['msg'] = rxml.find('message').text.replace(' ',' ') # store message in correct_map + + return correct_map + + def get_answers(self): + # Since this is explicitly specified in the problem, this will + # be handled by capa_problem + return {} + class StudentInputError(Exception): pass +#----------------------------------------------------------------------------- + class FormulaResponse(GenericResponse): def __init__(self, xml, context): self.xml = xml self.correct_answer = contextualize_text(xml.get('answer'), context) self.samples = contextualize_text(xml.get('samples'), context) - self.tolerance_xml = xml.xpath('//*[@id=$id]//responseparam[@type="tolerance"]/@default', - id=xml.get('id'))[0] - self.tolerance = contextualize_text(self.tolerance_xml, context) - self.answer_id = xml.xpath('//*[@id=$id]//textline/@id', - id=xml.get('id'))[0] + try: + self.tolerance_xml = xml.xpath('//*[@id=$id]//responseparam[@type="tolerance"]/@default', + id=xml.get('id'))[0] + self.tolerance = contextualize_text(self.tolerance_xml, context) + except Exception,err: + self.tolerance = 0 + + try: + self.answer_id = xml.xpath('//*[@id=$id]//textline/@id', + id=xml.get('id'))[0] + except Exception, err: + self.answer_id = None + raise Exception, "[courseware.capa.responsetypes.FormulaResponse] Error: missing answer_id!!" + self.context = context ts = xml.get('type') if ts == None: @@ -211,7 +359,7 @@ class FormulaResponse(GenericResponse): for i in range(numsamples): instructor_variables = self.strip_dict(dict(self.context)) student_variables = dict() - for var in ranges: + for var in ranges: # ranges give numerical ranges for testing value = random.uniform(*ranges[var]) instructor_variables[str(var)] = value student_variables[str(var)] = value @@ -246,6 +394,8 @@ class FormulaResponse(GenericResponse): def get_answers(self): return {self.answer_id:self.correct_answer} +#----------------------------------------------------------------------------- + class SchematicResponse(GenericResponse): def __init__(self, xml, context): self.xml = xml @@ -270,3 +420,68 @@ class SchematicResponse(GenericResponse): # Since this is explicitly specified in the problem, this will # be handled by capa_problem return {} + +#----------------------------------------------------------------------------- + +class ImageResponse(GenericResponse): + """ + Handle student response for image input: the input is a click on an image, + which produces an [x,y] coordinate pair. The click is correct if it falls + within a region specified. This region is nominally a rectangle. + + Lon-CAPA requires that each has a inside it. That + doesn't make sense to me (Ike). Instead, let's have it such that + should contain one or more stanzas. Each should specify + a rectangle, given as an attribute, defining the correct answer. + + Example: + + + + + + + """ + def __init__(self, xml, context): + self.xml = xml + self.context = context + self.ielements = xml.findall('imageinput') + self.answer_ids = [ie.get('id') for ie in self.ielements] + + def grade(self, student_answers): + correct_map = {} + expectedset = self.get_answers() + + for aid in self.answer_ids: # loop through IDs of fields in our stanza + given = student_answers[aid] # this should be a string of the form '[x,y]' + + # parse expected answer + # TODO: Compile regexp on file load + m = re.match('[\(\[]([0-9]+),([0-9]+)[\)\]]-[\(\[]([0-9]+),([0-9]+)[\)\]]',expectedset[aid].strip().replace(' ','')) + if not m: + msg = 'Error in problem specification! cannot parse rectangle in %s' % (etree.tostring(self.ielements[aid], + pretty_print=True)) + raise Exception,'[capamodule.capa.responsetypes.imageinput] '+msg + (llx,lly,urx,ury) = [int(x) for x in m.groups()] + + # parse given answer + m = re.match('\[([0-9]+),([0-9]+)]',given.strip().replace(' ','')) + if not m: + raise Exception,'[capamodule.capa.responsetypes.imageinput] error grading %s (input=%s)' % (err,aid,given) + (gx,gy) = [int(x) for x in m.groups()] + + if settings.DEBUG: + print "[capamodule.capa.responsetypes.imageinput] llx,lly,urx,ury=",(llx,lly,urx,ury) + print "[capamodule.capa.responsetypes.imageinput] gx,gy=",(gx,gy) + + # answer is correct if (x,y) is within the specified rectangle + if (llx <= gx <= urx) and (lly <= gy <= ury): + correct_map[aid] = 'correct' + else: + correct_map[aid] = 'incorrect' + if settings.DEBUG: + print "[capamodule.capa.responsetypes.imageinput] correct_map=",correct_map + return correct_map + + def get_answers(self): + return dict([(ie.get('id'),ie.get('rectangle')) for ie in self.ielements]) diff --git a/djangoapps/courseware/content_parser.py b/djangoapps/courseware/content_parser.py index 8773c1bde1..9ae937e52e 100644 --- a/djangoapps/courseware/content_parser.py +++ b/djangoapps/courseware/content_parser.py @@ -1,3 +1,12 @@ +''' +courseware/content_parser.py + +This file interfaces between all courseware modules and the top-level course.xml file for a course. + +Does some caching (to be explained). + +''' + import hashlib import logging import os diff --git a/djangoapps/courseware/test_files/imageresponse.xml b/djangoapps/courseware/test_files/imageresponse.xml new file mode 100644 index 0000000000..72bf06401a --- /dev/null +++ b/djangoapps/courseware/test_files/imageresponse.xml @@ -0,0 +1,15 @@ + +

+Two skiers are on frictionless black diamond ski slopes. +Hello

+ + + +Click on the image where the top skier will stop momentarily if the top skier starts from rest. + +Click on the image where the lower skier will stop momentarily if the lower skier starts from rest. + +

Use conservation of energy.

+
+
+
\ No newline at end of file diff --git a/djangoapps/ssl_auth/__init__.py b/djangoapps/ssl_auth/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/static/css/codemirror.css b/static/css/codemirror.css new file mode 100644 index 0000000000..2d79f4aa79 --- /dev/null +++ b/static/css/codemirror.css @@ -0,0 +1,112 @@ +.CodeMirror { + line-height: 1em; + font-family: monospace; +} + +.CodeMirror-scroll { + overflow: auto; + height: 300px; + /* This is needed to prevent an IE[67] bug where the scrolled content + is visible outside of the scrolling box. */ + position: relative; + outline: none; +} + +.CodeMirror-gutter { + position: absolute; left: 0; top: 0; + z-index: 10; + background-color: #f7f7f7; + border-right: 1px solid #eee; + min-width: 2em; + height: 100%; +} +.CodeMirror-gutter-text { + color: #aaa; + text-align: right; + padding: .4em .2em .4em .4em; + white-space: pre !important; +} +.CodeMirror-lines { + padding: .4em; + white-space: pre; +} + +.CodeMirror pre { + -moz-border-radius: 0; + -webkit-border-radius: 0; + -o-border-radius: 0; + border-radius: 0; + border-width: 0; margin: 0; padding: 0; background: transparent; + font-family: inherit; + font-size: inherit; + padding: 0; margin: 0; + white-space: pre; + word-wrap: normal; +} + +.CodeMirror-wrap pre { + word-wrap: break-word; + white-space: pre-wrap; +} +.CodeMirror-wrap .CodeMirror-scroll { + overflow-x: hidden; +} + +.CodeMirror textarea { + outline: none !important; +} + +.CodeMirror pre.CodeMirror-cursor { + z-index: 10; + position: absolute; + visibility: hidden; + border-left: 1px solid black; + border-right:none; + width:0; +} +.CodeMirror pre.CodeMirror-cursor.CodeMirror-overwrite {} +.CodeMirror-focused pre.CodeMirror-cursor { + visibility: visible; +} + +div.CodeMirror-selected { background: #d9d9d9; } +.CodeMirror-focused div.CodeMirror-selected { background: #d7d4f0; } + +.CodeMirror-searching { + background: #ffa; + background: rgba(255, 255, 0, .4); +} + +/* Default theme */ + +.cm-s-default span.cm-keyword {color: #708;} +.cm-s-default span.cm-atom {color: #219;} +.cm-s-default span.cm-number {color: #164;} +.cm-s-default span.cm-def {color: #00f;} +.cm-s-default span.cm-variable {color: black;} +.cm-s-default span.cm-variable-2 {color: #05a;} +.cm-s-default span.cm-variable-3 {color: #085;} +.cm-s-default span.cm-property {color: black;} +.cm-s-default span.cm-operator {color: black;} +.cm-s-default span.cm-comment {color: #a50;} +.cm-s-default span.cm-string {color: #a11;} +.cm-s-default span.cm-string-2 {color: #f50;} +.cm-s-default span.cm-meta {color: #555;} +.cm-s-default span.cm-error {color: #f00;} +.cm-s-default span.cm-qualifier {color: #555;} +.cm-s-default span.cm-builtin {color: #30a;} +.cm-s-default span.cm-bracket {color: #cc7;} +.cm-s-default span.cm-tag {color: #170;} +.cm-s-default span.cm-attribute {color: #00c;} +.cm-s-default span.cm-header {color: #a0a;} +.cm-s-default span.cm-quote {color: #090;} +.cm-s-default span.cm-hr {color: #999;} +.cm-s-default span.cm-link {color: #00c;} + +span.cm-header, span.cm-strong {font-weight: bold;} +span.cm-em {font-style: italic;} +span.cm-emstrong {font-style: italic; font-weight: bold;} +span.cm-link {text-decoration: underline;} + +div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;} +div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} diff --git a/static/js/codemirror-compressed.js b/static/js/codemirror-compressed.js new file mode 100644 index 0000000000..855a7bd32f --- /dev/null +++ b/static/js/codemirror-compressed.js @@ -0,0 +1 @@ +var CodeMirror=function(){function a(d,e){function Vb(a){return a>=0&&a=c.to||b.linee-400&&Y(yb.pos,d))return C(a),setTimeout(Dc,20),$c(d.line);if(xb&&xb.time>e-400&&Y(xb.pos,d))return yb={time:e,pos:d},C(a),Zc(d);xb={time:e,pos:d};var g=d,h;if(R&&!f.readOnly&&!Y(vb.from,vb.to)&&!Z(d,vb.from)&&!Z(vb.to,d)){O&&(ib.draggable=!0);var i=I(document,"mouseup",Td(function(b){O&&(ib.draggable=!1),Ab=!1,i(),Math.abs(a.clientX-b.clientX)+Math.abs(a.clientY-b.clientY)<10&&(C(b),Rc(d.line,d.ch,!0),Dc())}),!0);Ab=!0,ib.dragDrop&&ib.dragDrop();return}C(a),Rc(d.line,d.ch,!0);var l=I(document,"mousemove",Td(function(a){clearTimeout(h),C(a),!M&&!G(a)?k(a):j(a)}),!0),i=I(document,"mouseup",Td(k),!0)}function ac(a){for(var b=F(a);b!=s;b=b.parentNode)if(b.parentNode==hb)return C(a);var c=Gd(a);if(!c)return;yb={time:+(new Date),pos:c},C(a),Zc(c)}function bc(a){a.preventDefault();var b=Gd(a,!0),c=a.dataTransfer.files;if(!b||f.readOnly)return;if(c&&c.length&&window.FileReader&&window.File){function d(a,c){var d=new FileReader;d.onload=function(){g[c]=d.result,++h==e&&(b=Tc(b),Td(function(){var a=sc(g.join(""),b,b);Oc(b,a)})())},d.readAsText(a)}var e=c.length,g=Array(e),h=0;for(var i=0;i-1&&setTimeout(Td(function(){ad(vb.to.line,"smart")}),75);if(fc(a,d))return;zc()}function kc(a){if(f.onKeyEvent&&f.onKeyEvent(Wb,B(a)))return;H(a,"keyCode")==16&&(wb=null)}function lc(){if(f.readOnly=="nocursor")return;ub||(f.onFocus&&f.onFocus(Wb),ub=!0,s.className.search(/\bCodeMirror-focused\b/)==-1&&(s.className+=" CodeMirror-focused"),Ib||Cc(!0)),yc(),Id()}function mc(){ub&&(f.onBlur&&f.onBlur(Wb),ub=!1,Pb&&Td(function(){Pb&&(Pb(),Pb=null)})(),s.className=s.className.replace(" CodeMirror-focused","")),clearInterval(qb),setTimeout(function(){ub||(wb=null)},150)}function nc(a,b,c,d,e){if(Cb)return;if(Tb){var g=[];sb.iter(a.line,b.line+1,function(a){g.push(a.text)}),Tb.addChange(a.line,c.length,g);while(Tb.done.length>f.undoDepth)Tb.done.shift()}rc(a,b,c,d,e)}function oc(a,b){if(!a.length)return;var c=a.pop(),d=[];for(var e=c.length-1;e>=0;e-=1){var f=c[e],g=[],h=f.start+f.added;sb.iter(f.start,h,function(a){g.push(a.text)}),d.push({start:f.start,added:f.old.length,old:g});var i=Tc({line:f.start+f.old.length-1,ch:bb(g[g.length-1],f.old[f.old.length-1])});rc({line:f.start,ch:0},{line:h-1,ch:Xb(h-1).text.length},f.old,i,i)}Db=!0,b.push(d)}function pc(){oc(Tb.done,Tb.undone)}function qc(){oc(Tb.undone,Tb.done)}function rc(a,b,c,d,e){function y(a){return a<=Math.min(b.line,b.line+s)?a:a+s}if(Cb)return;var g=!1,h=Qb.length;f.lineWrapping||sb.iter(a.line,b.line,function(a){if(a.text.length==h)return g=!0,!0});if(a.line!=b.line||c.length>1)Jb=!0;var i=b.line-a.line,j=Xb(a.line),k=Xb(b.line);if(a.ch==0&&b.ch==0&&c[c.length-1]==""){var l=[],m=null;a.line?(m=Xb(a.line-1),m.fixMarkEnds(k)):k.fixMarkStarts();for(var n=0,o=c.length-1;n1&&sb.remove(a.line+1,i-1,Kb),sb.insert(a.line+1,l)}if(f.lineWrapping){var p=S.clientWidth/Dd()-3;sb.iter(a.line,a.line+c.length,function(a){if(a.hidden)return;var b=Math.ceil(a.text.length/p)||1;b!=a.height&&Yb(a,b)})}else sb.iter(a.line,n+c.length,function(a){var b=a.text;b.length>h&&(Qb=b,h=b.length,Rb=null,g=!1)}),g&&(h=0,Qb="",Rb=null,sb.iter(0,sb.size,function(a){var b=a.text;b.length>h&&(h=b.length,Qb=b)}));var q=[],s=c.length-i-1;for(var n=0,t=tb.length;nb.line&&q.push(u+s)}var v=a.line+Math.min(c.length,500);Nd(a.line,v),q.push(v),tb=q,Pd(100),Fb.push({from:a.line,to:b.line+1,diff:s});var w={from:a,to:b,text:c};if(Gb){for(var x=Gb;x.next;x=x.next);x.next=w}else Gb=w;Pc(d,e,y(vb.from.line),y(vb.to.line)),S.clientHeight&&(T.style.height=sb.height*Ad()+2*Ed()+"px")}function sc(a,b,c){function d(d){if(Z(d,b))return d;if(!Z(c,d))return e;var f=d.line+a.length-(c.line-b.line)-1,g=d.ch;return d.line==c.line&&(g+=a[a.length-1].length-(c.ch-(c.line==b.line?b.ch:0))),{line:f,ch:g}}b=Tc(b),c?c=Tc(c):c=b,a=eb(a);var e;return uc(a,b,c,function(a){return e=a,{from:d(vb.from),to:d(vb.to)}}),e}function tc(a,b){uc(eb(a),vb.from,vb.to,function(a){return b=="end"?{from:a,to:a}:b=="start"?{from:vb.from,to:vb.from}:{from:vb.from,to:a}})}function uc(a,b,c,d){var e=a.length==1?a[0].length+b.ch:a[a.length-1].length,f=d({line:b.line+a.length-1,ch:e});nc(b,c,a,f.from,f.to)}function vc(a,b){var c=a.line,d=b.line;if(c==d)return Xb(c).text.slice(a.ch,b.ch);var e=[Xb(c).text.slice(a.ch)];return sb.iter(c+1,d,function(a){e.push(a.text)}),e.push(Xb(d).text.slice(0,b.ch)),e.join("\n")}function wc(){return vc(vb.from,vb.to)}function yc(){if(xc)return;ob.set(f.pollInterval,function(){Qd(),Bc(),ub&&yc(),Rd()})}function zc(){function b(){Qd();var c=Bc();!c&&!a?(a=!0,ob.set(60,b)):(xc=!1,yc()),Rd()}var a=!1;xc=!0,ob.set(20,b)}function Bc(){if(Ib||!ub||fb(D)||f.readOnly)return!1;var a=D.value;if(a==Ac)return!1;wb=null;var b=0,c=Math.min(Ac.length,a.length);while(bb)&&kb.scrollIntoView()}function Fc(){var a=ud(vb.inverted?vb.from:vb.to),b=f.lineWrapping?Math.min(a.x,ib.offsetWidth):a.x;return Gc(b,a.y,b,a.yBot)}function Gc(a,b,c,d){var e=Fd(),g=Ed();b+=g,d+=g,a+=e,c+=e;var h=S.clientHeight,i=S.scrollTop,j=!1,k=!0;bi+h&&(S.scrollTop=d-h,j=!0);var l=S.clientWidth,m=S.scrollLeft,n=f.fixedGutter?_.clientWidth:0;return al+m-3&&(S.scrollLeft=c+10-l,j=!0,c>T.clientWidth&&(k=!1)),j&&f.onScroll&&f.onScroll(Wb),k}function Hc(){var a=Ad(),b=S.scrollTop-Ed(),c=Math.max(0,Math.floor(b/a)),d=Math.ceil((b+S.clientHeight)/a);return{from:x(sb,c),to:x(sb,d)}}function Ic(a,b){function n(){Rb=S.clientWidth;var a=mb.firstChild,b=!1;return sb.iter(Mb,Nb,function(c){if(!c.hidden){var d=Math.round(a.offsetHeight/k)||1;c.height!=d&&(Yb(c,d),Jb=b=!0)}a=a.nextSibling}),b&&(T.style.height=sb.height*k+2*Ed()+"px"),b}if(!S.clientWidth){Mb=Nb=Lb=0;return}var c=Hc();if(a!==!0&&a.length==0&&c.from>Mb&&c.toe&&Nb-e<20&&(e=Math.min(sb.size,Nb));var g=a===!0?[]:Jc([{from:Mb,to:Nb,domStart:0}],a),h=0;for(var i=0;ie&&(j.to=e),j.from>=j.to?g.splice(i--,1):h+=j.to-j.from}if(h==e-d)return;g.sort(function(a,b){return a.domStart-b.domStart});var k=Ad(),l=_.style.display;mb.style.display="none",Kc(d,e,g),mb.style.display=_.style.display="";var m=d!=Mb||e!=Nb||Ob!=S.clientHeight+k;m&&(Ob=S.clientHeight+k),Mb=d,Nb=e,Lb=y(sb,d),U.style.top=Lb*k+"px",S.clientHeight&&(T.style.height=sb.height*k+2*Ed()+"px");if(mb.childNodes.length!=Nb-Mb)throw new Error("BAD PATCH! "+JSON.stringify(g)+" size="+(Nb-Mb)+" nodes="+mb.childNodes.length);return f.lineWrapping?n():(Rb==null&&(Rb=qd(Qb)),Rb>S.clientWidth?(ib.style.width=Rb+"px",T.style.width="",T.style.width=S.scrollWidth+"px"):ib.style.width=T.style.width=""),_.style.display=l,(m||Jb)&&Lc()&&f.lineWrapping&&n()&&Lc(),Mc(),!b&&f.onUpdate&&f.onUpdate(Wb),!0}function Jc(a,b){for(var c=0,d=b.length||0;c=j.to?f.push(j):(e.from>j.from&&f.push({from:j.from,to:e.from,domStart:j.domStart}),e.toe)f=d(f),e++;for(var j=0,k=i.to-i.from;jj){if(a.hidden)var b=m.innerHTML="
";else{var b=""+a.getHTML(ed)+"";a.bgClassName&&(b='
 
'+b+"
")}m.innerHTML=b,mb.insertBefore(m.firstChild,f)}else f=f.nextSibling;++j})}function Lc(){if(!f.gutter&&!f.lineNumbers)return;var a=U.offsetHeight,b=S.clientHeight;_.style.height=(a-b<2?b:a)+"px";var c=[],d=Mb,e;sb.iter(Mb,Math.max(Nb,Mb+1),function(a){if(a.hidden)c.push("
");else{var b=a.gutterMarker,g=f.lineNumbers?d+f.firstLineNumber:null;b&&b.text?g=b.text.replace("%N%",g!=null?g:""):g==null&&(g="\u00a0"),c.push(b&&b.style?'
':"
",g);for(var h=1;h ");c.push("
"),b||(e=d)}++d}),_.style.display="none",hb.innerHTML=c.join("");if(e!=null){var g=hb.childNodes[e-Mb],h=String(sb.size).length,i=W(g),j="";while(i.length+j.length2;return ib.style.marginLeft=_.offsetWidth+"px",Jb=!1,k}function Mc(){var a=Y(vb.from,vb.to),b=ud(vb.from,!0),c=a?b:ud(vb.to,!0),d=vb.inverted?b:c,e=Ad(),g=V(s),h=V(mb);A.style.top=Math.max(0,Math.min(S.offsetHeight,d.y+h.top-g.top))+"px",A.style.left=Math.max(0,Math.min(S.offsetWidth,d.x+h.left-g.left))+"px";if(a)kb.style.top=d.y+"px",kb.style.left=(f.lineWrapping?Math.min(d.x,ib.offsetWidth):d.x)+"px",kb.style.display="",lb.style.display="none";else{var i=b.y==c.y,j="";function k(a,b,c,d){j+='
'}var l=ib.clientWidth||ib.offsetWidth,m=ib.clientHeight||ib.offsetHeight;if(vb.from.ch&&b.y>=0){var n=i?l-c.x:0;k(b.x,b.y,n,e)}var o=Math.max(0,b.y+(vb.from.ch?e:0)),p=Math.min(c.y,m)-o;p>.2*e&&k(0,o,0,p),(!i||!vb.from.ch)&&c.yc||g>f.text.length)g=f.text.length;return{line:d,ch:g}}d+=b}}var e=Xb(a.line);return e.hidden?a.line>=b?d(1)||d(-1):d(-1)||d(1):a}function Rc(a,b,c){var d=Tc({line:a,ch:b||0});(c?Oc:Pc)(d,d)}function Sc(a){return Math.max(0,Math.min(a,sb.size-1))}function Tc(a){if(a.line<0)return{line:0,ch:0};if(a.line>=sb.size)return{line:sb.size-1,ch:Xb(sb.size-1).text.length};var b=a.ch,c=Xb(a.line).text.length;return b==null||b>c?{line:a.line,ch:c}:b<0?{line:a.line,ch:0}:a}function Uc(a,b){function g(){for(var b=d+a,c=a<0?-1:sb.size;b!=c;b+=a){var e=Xb(b);if(!e.hidden)return d=b,f=e,!0}}function h(b){if(e==(a<0?0:f.text.length)){if(!!b||!g())return!1;e=a<0?f.text.length:0}else e+=a;return!0}var c=vb.inverted?vb.from:vb.to,d=c.line,e=c.ch,f=Xb(d);if(b=="char")h();else if(b=="column")h(!0);else if(b=="word"){var i=!1;for(;;){if(a<0&&!h())break;if(db(f.text.charAt(e)))i=!0;else if(i){a<0&&(a=1,h());break}if(a>0&&!h())break}}return{line:d,ch:e}}function Vc(a,b){var c=a<0?vb.from:vb.to;if(wb||Y(vb.from,vb.to))c=Uc(a,b);Rc(c.line,c.ch,!0)}function Wc(a,b){Y(vb.from,vb.to)?a<0?sc("",Uc(a,b),vb.to):sc("",vb.from,Uc(a,b)):sc("",vb.from,vb.to),Eb=!0}function Yc(a,b){var c=0,d=ud(vb.inverted?vb.from:vb.to,!0);Xc!=null&&(d.x=Xc),b=="page"?c=Math.min(S.clientHeight,window.innerHeight||document.documentElement.clientHeight):b=="line"&&(c=Ad());var e=vd(d.x,d.y+c*a+2);b=="page"&&(S.scrollTop+=ud(e,!0).y-d.y),Rc(e.line,e.ch,!0),Xc=d.x}function Zc(a){var b=Xb(a.line).text,c=a.ch,d=a.ch;while(c>0&&db(b.charAt(c-1)))--c;while(dQb.length&&(Qb=a.text)});Fb.push({from:0,to:sb.size})}function ed(a){var b=f.tabSize-a%f.tabSize,c=Sb[b];if(c)return c;for(var d='',e=0;e",width:b}}function fd(){S.className=S.className.replace(/\s*cm-s-\w+/g,"")+f.theme.replace(/(^|\s)\s*/g," cm-s-")}function gd(){this.set=[]}function hd(a,b,c){function e(a,b,c,e){Xb(a).addMark(new p(b,c,e,d))}a=Tc(a),b=Tc(b);var d=new gd;if(!Z(a,b))return d;if(a.line==b.line)e(a.line,a.ch,b.ch,c);else{e(a.line,a.ch,null,c);for(var f=a.line+1,g=b.line;f=a.ch)&&b.push(f.marker||f)}return b}function kd(a,b,c){return typeof a=="number"&&(a=Xb(Sc(a))),a.gutterMarker={text:b,style:c},Jb=!0,a}function ld(a){typeof a=="number"&&(a=Xb(Sc(a))),a.gutterMarker=null,Jb=!0}function md(a,b){var c=a,d=a;return typeof a=="number"?d=Xb(Sc(a)):c=w(a),c==null?null:b(d,c)?(Fb.push({from:c,to:c+1}),d):null}function nd(a,b,c){return md(a,function(a){if(a.className!=b||a.bgClassName!=c)return a.className=b,a.bgClassName=c,!0})}function od(a,b){return md(a,function(a,c){if(a.hidden!=b){a.hidden=b,Yb(a,b?0:1);var d=vb.from.line,e=vb.to.line;if(b&&(d==c||e==c)){var f=d==c?Qc({line:d,ch:0},d,0):vb.from,g=e==c?Qc({line:e,ch:0},e,0):vb.to;if(!g)return;Pc(f,g)}return Jb=!0}})}function pd(a){if(typeof a=="number"){if(!Vb(a))return null;var b=a;a=Xb(a);if(!a)return null}else{var b=w(a);if(b==null)return null}var c=a.gutterMarker;return{line:b,handle:a,text:a.text,markerText:c&&c.text,markerClass:c&&c.style,lineClass:a.className,bgClass:a.bgClassName}}function qd(a){return jb.innerHTML="
x
",jb.firstChild.firstChild.firstChild.nodeValue=a,jb.firstChild.firstChild.offsetWidth||10}function rd(a,b){function e(a){return jb.innerHTML="
"+c.getHTML(ed,a)+"
",jb.firstChild.firstChild.offsetWidth}if(b<=0)return 0;var c=Xb(a),d=c.text,f=0,g=0,h=d.length,i,j=Math.min(h,Math.ceil(b/Dd()));for(;;){var k=e(j);if(!(k<=b&&ji)return h;j=Math.floor(h*.8),k=e(j),kb-g?f:h;var l=Math.ceil((f+h)/2),m=e(l);m>b?(h=l,i=m):(f=l,g=m)}}function td(a,b){if(b==0)return{top:0,left:0};var c="";if(f.lineWrapping){var d=a.text.indexOf(" ",b+6);c=ab(a.text.slice(b+1,d<0?a.text.length:d+(M?5:0)))}jb.innerHTML="
"+a.getHTML(ed,b)+''+ab(a.text.charAt(b)||" ")+""+c+"
";var e=document.getElementById("CodeMirror-temp-"+sd),g=e.offsetTop,h=e.offsetLeft;if(M&&g==0&&h==0){var i=document.createElement("span");i.innerHTML="x",e.parentNode.insertBefore(i,e.nextSibling),g=i.offsetTop}return{top:g,left:h}}function ud(a,b){var c,d=Ad(),e=d*(y(sb,a.line)-(b?Lb:0));if(a.ch==0)c=0;else{var g=td(Xb(a.line),a.ch);c=g.left,f.lineWrapping&&(e+=Math.max(0,g.top))}return{x:c,y:e,yBot:e+d}}function vd(a,b){function l(a){var b=td(h,a);if(j){var d=Math.round(b.top/c);return Math.max(0,b.left+(d-k)*S.clientWidth)}return b.left}b<0&&(b=0);var c=Ad(),d=Dd(),e=Lb+Math.floor(b/c),g=x(sb,e);if(g>=sb.size)return{line:sb.size-1,ch:Xb(sb.size-1).text.length};var h=Xb(g),i=h.text,j=f.lineWrapping,k=j?e-y(sb,g):0;if(a<=0&&k==0)return{line:g,ch:0};var m=0,n=0,o=i.length,p,q=Math.min(o,Math.ceil((a+k*S.clientWidth*.9)/d));for(;;){var r=l(q);if(!(r<=a&&qp)return{line:g,ch:o};q=Math.floor(o*.8),r=l(q),ra-n?m:o};var s=Math.ceil((m+o)/2),t=l(s);t>a?(o=s,p=t):(m=s,n=t)}}function wd(a){var b=ud(a,!0),c=V(ib);return{x:c.left+b.x,y:c.top+b.y,yBot:c.top+b.yBot}}function Ad(){if(zd==null){zd="
";for(var a=0;a<49;++a)zd+="x
";zd+="x
"}var b=mb.clientHeight;return b==yd?xd:(yd=b,jb.innerHTML=zd,xd=jb.firstChild.offsetHeight/50||1,jb.innerHTML="",xd)}function Dd(){return S.clientWidth==Cd?Bd:(Cd=S.clientWidth,Bd=qd("x"))}function Ed(){return ib.offsetTop}function Fd(){return ib.offsetLeft}function Gd(a,b){var c=V(S,!0),d,e;try{d=a.clientX,e=a.clientY}catch(a){return null}if(!b&&(d-c.left>S.clientWidth||e-c.top>S.clientHeight))return null;var f=V(ib,!0);return vd(d-f.left,e-f.top)}function Hd(a){function f(){var a=eb(D.value).join("\n");a!=e&&Td(tc)(a,"end"),A.style.position="relative",D.style.cssText=d,N&&(S.scrollTop=c),Ib=!1,Cc(!0),yc()}var b=Gd(a),c=S.scrollTop;if(!b||window.opera)return;(Y(vb.from,vb.to)||Z(b,vb.from)||!Z(b,vb.to))&&Td(Rc)(b.line,b.ch);var d=D.style.cssText;A.style.position="absolute",D.style.cssText="position: fixed; width: 30px; height: 30px; top: "+(a.clientY-5)+"px; left: "+(a.clientX-5)+"px; z-index: 1000; background: white; "+"border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);",Ib=!0;var e=D.value=wc();Dc(),X(D);if(L){E(a);var g=I(window,"mouseup",function(){g(),setTimeout(f,20)},!0)}else setTimeout(f,50)}function Id(){clearInterval(qb);var a=!0;kb.style.visibility="",qb=setInterval(function(){kb.style.visibility=(a=!a)?"":"hidden"},650)}function Kd(a){function p(a,b,c){if(!a.text)return;var d=a.styles,e=g?0:a.text.length-1,f;for(var i=g?0:d.length-2,j=g?d.length:-2;i!=j;i+=2*h){var k=d[i];if(d[i+1]!=null&&d[i+1]!=m){e+=h*k.length;continue}for(var l=g?0:k.length-1,p=g?k.length:-1;l!=p;l+=h,e+=h)if(e>=b&&e"==g)n.push(f);else{if(n.pop()!=q.charAt(0))return{pos:e,match:!1};if(!n.length)return{pos:e,match:!0}}}}}var b=vb.inverted?vb.from:vb.to,c=Xb(b.line),d=b.ch-1,e=d>=0&&Jd[c.text.charAt(d)]||Jd[c.text.charAt(++d)];if(!e)return;var f=e.charAt(0),g=e.charAt(1)==">",h=g?1:-1,i=c.styles;for(var j=d+1,k=0,l=i.length;ke;--d){if(d==0)return 0;var g=Xb(d-1);if(g.stateAfter)return d;var h=g.indentation(f.tabSize);if(c==null||b>h)c=d-1,b=h}return c}function Md(a){var b=Ld(a),c=b&&Xb(b-1).stateAfter;return c?c=m(rb,c):c=n(rb),sb.iter(b,a,function(a){a.highlight(rb,c,f.tabSize),a.stateAfter=m(rb,c)}),b=sb.size)continue;var d=Ld(c),e=d&&Xb(d-1).stateAfter;e?e=m(rb,e):e=n(rb);var g=0,h=rb.compareStates,i=!1,j=d,k=!1;sb.iter(j,sb.size,function(b){var d=b.stateAfter;if(+(new Date)>a)return tb.push(j),Pd(f.workDelay),i&&Fb.push({from:c,to:j+1}),k=!0;var l=b.highlight(rb,e,f.tabSize);l&&(i=!0),b.stateAfter=m(rb,e);if(h){if(d&&h(d,e))return!0}else if(l!==!1||!d)g=0;else if(++g>3&&(!rb.indent||rb.indent(d,"")==rb.indent(e,"")))return!0;++j});if(k)return;i&&Fb.push({from:c,to:j+1})}b&&f.onHighlightComplete&&f.onHighlightComplete(Wb)}function Pd(a){if(!tb.length)return;pb.set(a,Td(Od))}function Qd(){Db=Eb=Gb=null,Fb=[],Hb=!1,Kb=[]}function Rd(){var a=!1,b;Hb&&(a=!Fc()),Fb.length?b=Ic(Fb,!0):(Hb&&Mc(),Jb&&Lc()),a&&Fc(),Hb&&(Ec(),Id()),ub&&!Ib&&(Db===!0||Db!==!1&&Hb)&&Cc(Eb),Hb&&f.matchBrackets&&setTimeout(Td(function(){Pb&&(Pb(),Pb=null),Y(vb.from,vb.to)&&Kd(!1)}),20);var c=Gb,d=Kb;Hb&&f.onCursorActivity&&f.onCursorActivity(Wb),c&&f.onChange&&Wb&&f.onChange(Wb,c);for(var e=0;eh&&a.y>b.offsetHeight&&(f=a.y-b.offsetHeight),g+b.offsetWidth>i&&(g=i-b.offsetWidth)}b.style.top=f+Ed()+"px",b.style.left=b.style.right="",e=="right"?(g=T.clientWidth-b.offsetWidth,b.style.right="0px"):(e=="left"?g=0:e=="middle"&&(g=(T.clientWidth-b.offsetWidth)/2),b.style.left=g+Fd()+"px"),c&&Gc(g,f,g+b.offsetWidth,f+b.offsetHeight)},lineCount:function(){return sb.size},clipPos:Tc,getCursor:function(a){return a==null&&(a=vb.inverted),$(a?vb.from:vb.to)},somethingSelected:function(){return!Y(vb.from,vb.to)},setCursor:Td(function(a,b,c){b==null&&typeof a.line=="number"?Rc(a.line,a.ch,c):Rc(a,b,c)}),setSelection:Td(function(a,b,c){(c?Oc:Pc)(Tc(a),Tc(b||a))}),getLine:function(a){if(Vb(a))return Xb(a).text},getLineHandle:function(a){if(Vb(a))return Xb(a)},setLine:Td(function(a,b){Vb(a)&&sc(b,{line:a,ch:0},{line:a,ch:Xb(a).text.length})}),removeLine:Td(function(a){Vb(a)&&sc("",{line:a,ch:0},Tc({line:a+1,ch:0}))}),replaceRange:Td(sc),getRange:function(a,b){return vc(Tc(a),Tc(b))},triggerOnKeyDown:Td(ic),execCommand:function(a){return h[a](Wb)},moveH:Td(Vc),deleteH:Td(Wc),moveV:Td(Yc),toggleOverwrite:function(){Bb?(Bb=!1,kb.className=kb.className.replace(" CodeMirror-overwrite","")):(Bb=!0,kb.className+=" CodeMirror-overwrite")},posFromIndex:function(a){var b=0,c;return sb.iter(0,sb.size,function(d){var e=d.text.length+1;if(e>a)return c=a,!0;a-=e,++b}),Tc({line:b,ch:c})},indexFromPos:function(a){if(a.line<0||a.ch<0)return 0;var b=a.ch;return sb.iter(0,a.line,function(a){b+=a.text.length+1}),b},scrollTo:function(a,b){a!=null&&(S.scrollLeft=a),b!=null&&(S.scrollTop=b),Ic([])},operation:function(a){return Td(a)()},refresh:function(){Ic(!0),S.scrollHeight>zb&&(S.scrollTop=zb)},getInputField:function(){return D},getWrapperElement:function(){return s},getScrollerElement:function(){return S},getGutterElement:function(){return _}},gc=null,hc,xc=!1,Ac="",Xc=null;gd.prototype.clear=Td(function(){var a=Infinity,b=-Infinity;for(var c=0,d=this.set.length;c",")":"(<","[":"]>","]":"[<","{":"}>","}":"{<"},Sd=0;for(var Ud in g)g.propertyIsEnumerable(Ud)&&!Wb.propertyIsEnumerable(Ud)&&(Wb[Ud]=g[Ud]);return Wb}function j(a){return typeof a=="string"?i[a]:a}function k(a,b,c,d){function e(b){b=j(b);var c=b[a];if(c!=null&&d(c))return!0;if(b.catchall)return d(b.catchall);var f=b.fallthrough;if(f==null)return!1;if(Object.prototype.toString.call(f)!="[object Array]")return e(f);for(var g=0,h=f.length;ga&&d.push(h.slice(a-f,Math.min(h.length,b-f)),c[e+1]),i>=a&&(g=1)):g==1&&(i>b?d.push(h.slice(0,b-f),c[e+1]):d.push(h,c[e+1])),f=i}}function t(a){this.lines=a,this.parent=null;for(var b=0,c=a.length,d=0;b=0&&d>=0;--c,--d)if(a.charAt(c)!=b.charAt(d))break;return d+1}function cb(a,b){if(a.indexOf)return a.indexOf(b);for(var c=0,d=a.length;c0&&b.ch=this.string.length},sol:function(){return this.pos==0},peek:function(){return this.string.charAt(this.pos)},next:function(){if(this.posb},eatSpace:function(){var a=this.pos;while(/[\s\u00a0]/.test(this.string.charAt(this.pos)))++this.pos;return this.pos>a},skipToEnd:function(){this.pos=this.string.length},skipTo:function(a){var b=this.string.indexOf(a,this.pos);if(b>-1)return this.pos=b,!0},backUp:function(a){this.pos-=a},column:function(){return T(this.string,this.start,this.tabSize)},indentation:function(){return T(this.string,null,this.tabSize)},match:function(a,b,c){if(typeof a!="string"){var e=this.string.slice(this.pos).match(a);return e&&b!==!1&&(this.pos+=e[0].length),e}function d(a){return c?a.toLowerCase():a}if(d(this.string).indexOf(d(a),this.pos)==this.pos)return b!==!1&&(this.pos+=a.length),!0},current:function(){return this.string.slice(this.start,this.pos)}},a.StringStream=o,p.prototype={attach:function(a){this.marker.set.push(a)},detach:function(a){var b=cb(this.marker.set,a);b>-1&&this.marker.set.splice(b,1)},split:function(a,b){if(this.to<=a&&this.to!=null)return null;var c=this.fromthis.from&&(d=b&&(this.from=Math.max(d,this.from)+e),c&&(bthis.from||this.from==null)?this.to=null:this.to!=null&&this.to>b&&(this.to=d=this.to},sameSet:function(a){return this.marker==a.marker}},q.prototype={attach:function(a){this.line=a},detach:function(a){this.line==a&&(this.line=null)},split:function(a,b){if(athis.to},clipTo:function(a,b,c,d,e){(a||bthis.to)?(this.from=0,this.to=-1):this.from>b&&(this.from=this.to=Math.max(d,this.from)+e)},sameSet:function(a){return!1},find:function(){return!this.line||!this.line.parent?null:{line:w(this.line),ch:this.from}},clear:function(){if(this.line){var a=cb(this.line.marked,this);a!=-1&&this.line.marked.splice(a,1),this.line=null}}},r.inheritMarks=function(a,b){var c=new r(a),d=b&&b.marked;if(d)for(var e=0;e5e3){e[f++]=this.text.slice(d.pos),e[f++]=null;break}}return e.length!=f&&(e.length=f,g=!0),f&&e[f-2]!=i&&(g=!0),g||(e.length<5&&this.text.length<10?null:!1)},getTokenAt:function(a,b,c){var d=this.text,e=new o(d);while(e.pos',g,"
"):c.push(g)}function k(a){return a?"cm-"+a.replace(/ +/g," cm-"):null}var c=[],d=!0,e=0,g=this.styles,h=this.text,i=this.marked,j=h.length;b!=null&&(j=Math.min(b,j));if(!h&&b==null)f(" ");else if(!i||!i.length)for(var l=0,m=0;mj&&(n=n.slice(0,j-m)),m+=p,f(n,k(o))}else{var q=0,l=0,r="",o,s=0,t=i[0].from||0,u=[],v=0;function w(){var a;while(vy?r.slice(0,y-q):r,A);if(z>=y){r=r.slice(y-q),q=y;break}q=z}r=g[l++],o=k(g[l++])}}}return c.join("")},cleanUp:function(){this.parent=null;if(this.marked)for(var a=0,b=this.marked.length;a50){while(f.lines.length>50){var h=f.lines.splice(f.lines.length-25,25),i=new t(h);f.height-=i.height,this.children.splice(d+1,0,i),i.parent=this}this.maybeSpill()}break}a-=g}},maybeSpill:function(){if(this.children.length<=10)return;var a=this;do{var b=a.children.splice(a.children.length-5,5),c=new u(b);if(!a.parent){var d=new u(a.children);d.parent=a,a.children=[d,c],a=d}else{a.size-=c.size,a.height-=c.height;var e=cb(a.parent.children,a);a.parent.children.splice(e+1,0,c)}c.parent=a.parent}while(a.children.length>10);a.parent.maybeSpill()},iter:function(a,b,c){this.iterN(a,b-a,c)},iterN:function(a,b,c){for(var d=0,e=this.children.length;d400||!f)this.done.push([{start:a,added:b,old:c}]);else if(f.start>a+c.length||f.start+f.added=0;--i)f.old.unshift(c[i]);h=Math.min(0,b-c.length),f.added+=f.start-a+h,f.start=a}else f.start-1&&(S="\r\n")})(),document.documentElement.getBoundingClientRect!=null&&(V=function(a,b){try{var c=a.getBoundingClientRect();c={top:c.top,left:c.left}}catch(d){c={top:0,left:0}}if(!b)if(window.pageYOffset==null){var e=document.documentElement||document.body.parentNode;e.scrollTop==null&&(e=document.body),c.top+=e.scrollTop,c.left+=e.scrollLeft}else c.top+=window.pageYOffset,c.left+=window.pageXOffset;return c});var _=document.createElement("pre");ab("a")=="\na"?ab=function(a){return _.textContent=a,_.innerHTML.slice(1)}:ab(" ")!=" "&&(ab=function(a){return _.innerHTML="",_.appendChild(document.createTextNode(a)),_.innerHTML}),a.htmlEscape=ab;var eb="\n\nb".split(/\n/).length!=3?function(a){var b=0,c,d=[];while((c=a.indexOf("\n",b))>-1)d.push(a.slice(b,a.charAt(c-1)=="\r"?c-1:c)),b=c+1;return d.push(a.slice(b)),d}:function(a){return a.split(/\r?\n/)};a.splitLines=eb;var fb=window.getSelection?function(a){try{return a.selectionStart!=a.selectionEnd}catch(b){return!1}}:function(a){try{var b=a.ownerDocument.selection.createRange()}catch(c){}return!b||b.parentElement()!=a?!1:b.compareEndPoints("StartToEnd",b)!=0};a.defineMode("null",function(){return{token:function(a){a.skipToEnd()}}}),a.defineMIME("text/plain","null");var gb={3:"Enter",8:"Backspace",9:"Tab",13:"Enter",16:"Shift",17:"Ctrl",18:"Alt",19:"Pause",20:"CapsLock",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"PrintScrn",45:"Insert",46:"Delete",59:";",91:"Mod",92:"Mod",93:"Mod",127:"Delete",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",63276:"PageUp",63277:"PageDown",63275:"End",63273:"Home",63234:"Left",63232:"Up",63235:"Right",63233:"Down",63302:"Insert",63272:"Delete"};return a.keyNames=gb,function(){for(var a=0;a<10;a++)gb[a+48]=String(a);for(var a=65;a<=90;a++)gb[a]=String.fromCharCode(a);for(var a=1;a<=12;a++)gb[a+111]=gb[a+63235]="F"+a}(),a}();CodeMirror.defineMode("diff",function(){return{token:function(a){var b=a.next();a.skipToEnd();if(b=="+")return"plus";if(b=="-")return"minus";if(b=="@")return"rangeinfo"}}}),CodeMirror.defineMIME("text/x-diff","diff"),CodeMirror.defineMode("htmlembedded",function(a,b){function g(a,b){return a.match(c,!1)?(b.token=h,e.token(a,b.scriptState)):f.token(a,b.htmlState)}function h(a,b){return a.match(d,!1)?(b.token=g,f.token(a,b.htmlState)):e.token(a,b.scriptState)}var c=b.scriptStartRegex||/^<%/i,d=b.scriptEndRegex||/^%>/i,e,f;return{startState:function(){return e=e||CodeMirror.getMode(a,b.scriptingModeSpec),f=f||CodeMirror.getMode(a,"htmlmixed"),{token:b.startOpen?h:g,htmlState:f.startState(),scriptState:e.startState()}},token:function(a,b){return b.token(a,b)},indent:function(a,b){return a.token==g?f.indent(a.htmlState,b):e.indent(a.scriptState,b)},copyState:function(a){return{token:a.token,htmlState:CodeMirror.copyState(f,a.htmlState),scriptState:CodeMirror.copyState(e,a.scriptState)}},electricChars:"/{}:"}}),CodeMirror.defineMIME("application/x-ejs",{name:"htmlembedded",scriptingModeSpec:"javascript"}),CodeMirror.defineMIME("application/x-aspx",{name:"htmlembedded",scriptingModeSpec:"text/x-csharp"}),CodeMirror.defineMIME("application/x-jsp",{name:"htmlembedded",scriptingModeSpec:"text/x-java"}),CodeMirror.defineMode("htmlmixed",function(a,b){function f(a,b){var f=c.token(a,b.htmlState);return f=="tag"&&a.current()==">"&&b.htmlState.context&&(/^script$/i.test(b.htmlState.context.tagName)?(b.token=h,b.localState=d.startState(c.indent(b.htmlState,"")),b.mode="javascript"):/^style$/i.test(b.htmlState.context.tagName)&&(b.token=i,b.localState=e.startState(c.indent(b.htmlState,"")),b.mode="css")),f}function g(a,b,c){var d=a.current(),e=d.search(b);return e>-1&&a.backUp(d.length-e),c}function h(a,b){return a.match(/^<\/\s*script\s*>/i,!1)?(b.token=f,b.localState=null,b.mode="html",f(a,b)):g(a,/<\/\s*script\s*>/,d.token(a,b.localState))}function i(a,b){return a.match(/^<\/\s*style\s*>/i,!1)?(b.token=f,b.localState=null,b.mode="html",f(a,b)):g(a,/<\/\s*style\s*>/,e.token(a,b.localState))}var c=CodeMirror.getMode(a,{name:"xml",htmlMode:!0}),d=CodeMirror.getMode(a,"javascript"),e=CodeMirror.getMode(a,"css");return{startState:function(){var a=c.startState();return{token:f,localState:null,mode:"html",htmlState:a}},copyState:function(a){if(a.localState)var b=CodeMirror.copyState(a.token==i?e:d,a.localState);return{token:a.token,localState:b,mode:a.mode,htmlState:CodeMirror.copyState(c,a.htmlState)}},token:function(a,b){return b.token(a,b)},indent:function(a,b){return a.token==f||/^\s*<\//.test(b)?c.indent(a.htmlState,b):a.token==h?d.indent(a.localState,b):e.indent(a.localState,b)},compareStates:function(a,b){return c.compareStates(a.htmlState,b.htmlState)},electricChars:"/{}:"}}),CodeMirror.defineMIME("text/html","htmlmixed"),CodeMirror.defineMode("javascript",function(a,b){function g(a,b,c){return b.tokenize=c,c(a,b)}function h(a,b){var c=!1,d;while((d=a.next())!=null){if(d==b&&!c)return!1;c=!c&&d=="\\"}return c}function k(a,b,c){return i=a,j=c,b}function l(a,b){var c=a.next();if(c=='"'||c=="'")return g(a,b,m(c));if(/[\[\]{}\(\),;\:\.]/.test(c))return k(c);if(c=="0"&&a.eat(/x/i))return a.eatWhile(/[\da-f]/i),k("number","number");if(/\d/.test(c))return a.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/),k("number","number");if(c=="/")return a.eat("*")?g(a,b,n):a.eat("/")?(a.skipToEnd(),k("comment","comment")):b.reAllowed?(h(a,"/"),a.eatWhile(/[gimy]/),k("regexp","string-2")):(a.eatWhile(f),k("operator",null,a.current()));if(c=="#")return a.skipToEnd(),k("error","error");if(f.test(c))return a.eatWhile(f),k("operator",null,a.current());a.eatWhile(/[\w\$_]/);var d=a.current(),i=e.propertyIsEnumerable(d)&&e[d];return i&&b.kwAllowed?k(i.type,i.style,d):k("variable","variable",d)}function m(a){return function(b,c){return h(b,a)||(c.tokenize=l),k("string","string")}}function n(a,b){var c=!1,d;while(d=a.next()){if(d=="/"&&c){b.tokenize=l;break}c=d=="*"}return k("comment","comment")}function p(a,b,c,d,e,f){this.indented=a,this.column=b,this.type=c,this.prev=e,this.info=f,d!=null&&(this.align=d)}function q(a,b){for(var c=a.localVars;c;c=c.next)if(c.name==b)return!0}function r(a,b,c,e,f){var g=a.cc;s.state=a,s.stream=f,s.marked=null,s.cc=g,a.lexical.hasOwnProperty("align")||(a.lexical.align=!0);for(;;){var h=g.length?g.pop():d?D:C;if(h(c,e)){while(g.length&&g[g.length-1].lex)g.pop()();return s.marked?s.marked:c=="variable"&&q(a,e)?"variable-2":b}}}function t(){for(var a=arguments.length-1;a>=0;a--)s.cc.push(arguments[a])}function u(){return t.apply(null,arguments),!0}function v(a){var b=s.state;if(b.context){s.marked="def";for(var c=b.localVars;c;c=c.next)if(c.name==a)return;b.localVars={name:a,next:b.localVars}}}function x(){s.state.context||(s.state.localVars=w),s.state.context={prev:s.state.context,vars:s.state.localVars}}function y(){s.state.localVars=s.state.context.vars,s.state.context=s.state.context.prev}function z(a,b){var c=function(){var c=s.state;c.lexical=new p(c.indented,s.stream.column(),a,null,c.lexical,b)};return c.lex=!0,c}function A(){var a=s.state;a.lexical.prev&&(a.lexical.type==")"&&(a.indented=a.lexical.indented),a.lexical=a.lexical.prev)}function B(a){return function(c){return c==a?u():a==";"?t():u(arguments.callee)}}function C(a){return a=="var"?u(z("vardef"),L,B(";"),A):a=="keyword a"?u(z("form"),D,C,A):a=="keyword b"?u(z("form"),C,A):a=="{"?u(z("}"),K,A):a==";"?u():a=="function"?u(R):a=="for"?u(z("form"),B("("),z(")"),N,B(")"),A,C,A):a=="variable"?u(z("stat"),G):a=="switch"?u(z("form"),D,z("}","switch"),B("{"),K,A,A):a=="case"?u(D,B(":")):a=="default"?u(B(":")):a=="catch"?u(z("form"),x,B("("),S,B(")"),C,A,y):t(z("stat"),D,B(";"),A)}function D(a){return o.hasOwnProperty(a)?u(F):a=="function"?u(R):a=="keyword c"?u(E):a=="("?u(z(")"),E,B(")"),A,F):a=="operator"?u(D):a=="["?u(z("]"),J(D,"]"),A,F):a=="{"?u(z("}"),J(I,"}"),A,F):u()}function E(a){return a.match(/[;\}\)\],]/)?t():t(D)}function F(a,b){if(a=="operator"&&/\+\+|--/.test(b))return u(F);if(a=="operator")return u(D);if(a==";")return;if(a=="(")return u(z(")"),J(D,")"),A,F);if(a==".")return u(H,F);if(a=="[")return u(z("]"),D,B("]"),A,F)}function G(a){return a==":"?u(A,C):t(F,B(";"),A)}function H(a){if(a=="variable")return s.marked="property",u()}function I(a){a=="variable"&&(s.marked="property");if(o.hasOwnProperty(a))return u(B(":"),D)}function J(a,b){function c(d){return d==","?u(a,c):d==b?u():u(B(b))}return function(e){return e==b?u():t(a,c)}}function K(a){return a=="}"?u():t(C,K)}function L(a,b){return a=="variable"?(v(b),u(M)):u()}function M(a,b){if(b=="=")return u(D,M);if(a==",")return u(L)}function N(a){return a=="var"?u(L,P):a==";"?t(P):a=="variable"?u(O):t(P)}function O(a,b){return b=="in"?u(D):u(F,P)}function P(a,b){return a==";"?u(Q):b=="in"?u(D):u(D,B(";"),Q)}function Q(a){a!=")"&&u(D)}function R(a,b){if(a=="variable")return v(b),u(R);if(a=="(")return u(z(")"),x,J(S,")"),A,C,y)}function S(a,b){if(a=="variable")return v(b),u()}var c=a.indentUnit,d=b.json,e=function(){function a(a){return{type:a,style:"keyword"}}var b=a("keyword a"),c=a("keyword b"),d=a("keyword c"),e=a("operator"),f={type:"atom",style:"atom"};return{"if":b,"while":b,"with":b,"else":c,"do":c,"try":c,"finally":c,"return":d,"break":d,"continue":d,"new":d,"delete":d,"throw":d,"var":a("var"),"const":a("var"),let:a("var"),"function":a("function"),"catch":a("catch"),"for":a("for"),"switch":a("switch"),"case":a("case"),"default":a("default"),"in":e,"typeof":e,"instanceof":e,"true":f,"false":f,"null":f,"undefined":f,NaN:f,Infinity:f}}(),f=/[+\-*&%=<>!?|]/,i,j,o={atom:!0,number:!0,variable:!0,string:!0,regexp:!0},s={state:null,column:null,marked:null,cc:null},w={name:"this",next:{name:"arguments"}};return A.lex=!0,{startState:function(a){return{tokenize:l,reAllowed:!0,kwAllowed:!0,cc:[],lexical:new p((a||0)-c,0,"block",!1),localVars:b.localVars,context:b.localVars&&{vars:b.localVars},indented:0}},token:function(a,b){a.sol()&&(b.lexical.hasOwnProperty("align")||(b.lexical.align=!1),b.indented=a.indentation());if(a.eatSpace())return null;var c=b.tokenize(a,b);return i=="comment"?c:(b.reAllowed=i=="operator"||i=="keyword c"||!!i.match(/^[\[{}\(,;:]$/),b.kwAllowed=i!=".",r(b,c,i,j,a))},indent:function(a,b){if(a.tokenize!=l)return 0;var d=b&&b.charAt(0),e=a.lexical,f=e.type,g=d==f;return f=="vardef"?e.indented+4:f=="form"&&d=="{"?e.indented:f=="stat"||f=="form"?e.indented+c:e.info=="switch"&&!g?e.indented+(/^(?:case|default)\b/.test(b)?c:2*c):e.align?e.column+(g?0:1):e.indented+(g?0:c)},electricChars:":{}"}}),CodeMirror.defineMIME("text/javascript","javascript"),CodeMirror.defineMIME("application/json",{name:"javascript",json:!0}),CodeMirror.defineMode("markdown",function(a,b){function s(a,b,c){return b.f=b.inline=c,c(a,b)}function t(a,b,c){return b.f=b.block=c,c(a,b)}function u(a){return a.em=!1,a.strong=!1,null}function v(a,b){var c;if(b.indentationDiff>=4)return b.indentation-=b.indentationDiff,a.skipToEnd(),e;if(a.eatSpace())return null;if(a.peek()==="#"||a.match(q))b.header=!0;else if(a.eat(">"))b.indentation++,b.quote=!0;else{if(a.peek()==="[")return s(a,b,C);if(a.match(n,!0))return h;if(c=a.match(o,!0)||a.match(p,!0))return b.indentation+=c[0].length,g}return s(a,b,b.inline)}function w(a,b){var d=c.token(a,b.htmlState);return d==="tag"&&b.htmlState.type!=="openTag"&&!b.htmlState.context&&(b.f=z,b.block=v),d}function x(a){var b=[];return a.strong?b.push(a.em?m:l):a.em&&b.push(k),a.header&&b.push(d),a.quote&&b.push(f),b.length?b.join(" "):null}function y(a,b){return a.match(r,!0)?x(b):undefined}function z(a,b){var c=b.text(a,b);if(typeof c!="undefined")return c;var d=a.next();if(d==="\\")return a.next(),x(b);if(d==="`")return s(a,b,F(e,"`"));if(d==="[")return s(a,b,A);if(d==="<"&&a.match(/^\w/,!1))return a.backUp(1),t(a,b,w);var f=x(b);return d==="*"||d==="_"?a.eat(d)?(b.strong=!b.strong)?x(b):f:(b.em=!b.em)?x(b):f:x(b)}function A(a,b){while(!a.eol()){var c=a.next();c==="\\"&&a.next();if(c==="]")return b.inline=b.f=B,i}return i}function B(a,b){a.eatSpace();var c=a.next();return c==="("||c==="["?s(a,b,F(j,c==="("?")":"]")):"error"}function C(a,b){return a.match(/^[^\]]*\]:/,!0)?(b.f=D,i):s(a,b,z)}function D(a,b){return a.eatSpace(),a.match(/^[^\s]+/,!0),b.f=b.inline=z,j}function E(a){return E[a]||(E[a]=new RegExp("^(?:[^\\\\\\"+a+"]|\\\\.)*(?:\\"+a+"|$)")),E[a]}function F(a,b,c){return c=c||z,function(d,e){return d.match(E(b)),e.inline=e.f=c,a}}var c=CodeMirror.getMode(a,{name:"xml",htmlMode:!0}),d="header",e="comment",f="quote",g="string",h="hr",i="link",j="string",k="em",l="strong",m="emstrong",n=/^([*\-=_])(?:\s*\1){2,}\s*$/,o=/^[*\-+]\s+/,p=/^[0-9]+\.\s+/,q=/^(?:\={3,}|-{3,})$/,r=/^[^\[*_\\<>`]+/;return{startState:function(){return{f:v,block:v,htmlState:c.startState(),indentation:0,inline:z,text:y,em:!1,strong:!1,header:!1,quote:!1}},copyState:function(a){return{f:a.f,block:a.block,htmlState:CodeMirror.copyState(c,a.htmlState),indentation:a.indentation,inline:a.inline,text:a.text,em:a.em,strong:a.strong,header:a.header,quote:a.quote}},token:function(a,b){if(a.sol()){if(a.match(/^\s*$/,!0))return u(b);b.header=!1,b.quote=!1,b.f=b.block;var c=a.match(/^\s*/,!0)[0].replace(/\t/g," ").length;b.indentationDiff=c-b.indentation,b.indentation=c;if(c>0)return null}return b.f(a,b)},blankLine:u,getType:x}}),CodeMirror.defineMIME("text/x-markdown","markdown"),CodeMirror.defineMode("python",function(a,b){function d(a){return new RegExp("^(("+a.join(")|(")+"))\\b")}function t(a,b){if(a.sol()){var d=b.scopes[0].offset;if(a.eatSpace()){var l=a.indentation();return l>d?s="indent":l0&&w(a,b)}if(a.eatSpace())return null;var m=a.peek();if(m==="#")return a.skipToEnd(),"comment";if(a.match(/^[0-9\.]/,!1)){var n=!1;a.match(/^\d*\.\d+(e[\+\-]?\d+)?/i)&&(n=!0),a.match(/^\d+\.\d*/)&&(n=!0),a.match(/^\.\d+/)&&(n=!0);if(n)return a.eat(/J/i),"number";var o=!1;a.match(/^0x[0-9a-f]+/i)&&(o=!0),a.match(/^0b[01]+/i)&&(o=!0),a.match(/^0o[0-7]+/i)&&(o=!0),a.match(/^[1-9]\d*(e[\+\-]?\d+)?/)&&(a.eat(/J/i),o=!0),a.match(/^0(?![\dx])/i)&&(o=!0);if(o)return a.eat(/L/i),"number"}return a.match(p)?(b.tokenize=u(a.current()),b.tokenize(a,b)):a.match(i)||a.match(h)?null:a.match(g)||a.match(e)||a.match(k)?"operator":a.match(f)?null:a.match(q)?"keyword":a.match(r)?"builtin":a.match(j)?"variable":(a.next(),c)}function u(a){while("rub".indexOf(a.charAt(0).toLowerCase())>=0)a=a.substr(1);var d=a.length==1,e="string";return function(g,h){while(!g.eol()){g.eatWhile(/[^'"\\]/);if(g.eat("\\")){g.next();if(d&&g.eol())return e}else{if(g.match(a))return h.tokenize=t,e;g.eat(/['"]/)}}if(d){if(b.singleLineStringErrors)return c;h.tokenize=t}return e}}function v(b,c,d){d=d||"py";var e=0;if(d==="py"){if(c.scopes[0].type!=="py"){c.scopes[0].offset=b.indentation();return}for(var f=0;f0&&a.eol()&&b.scopes[0].type=="py"&&(b.scopes.length>1&&b.scopes.shift(),b.dedent-=1),d))}var c="error",e=new RegExp("^[\\+\\-\\*/%&|\\^~<>!]"),f=new RegExp("^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]"),g=new RegExp("^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))"),h=new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))"),i=new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))"),j=new RegExp("^[_A-Za-z][_A-Za-z0-9]*"),k=d(["and","or","not","is","in"]),l=["as","assert","break","class","continue","def","del","elif","else","except","finally","for","from","global","if","import","lambda","pass","raise","return","try","while","with","yield"],m=["abs","all","any","bin","bool","bytearray","callable","chr","classmethod","compile","complex","delattr","dict","dir","divmod","enumerate","eval","filter","float","format","frozenset","getattr","globals","hasattr","hash","help","hex","id","input","int","isinstance","issubclass","iter","len","list","locals","map","max","memoryview","min","next","object","oct","open","ord","pow","property","range","repr","reversed","round","set","setattr","slice","sorted","staticmethod","str","sum","super","tuple","type","vars","zip","__import__","NotImplemented","Ellipsis","__debug__"],n={builtins:["apply","basestring","buffer","cmp","coerce","execfile","file","intern","long","raw_input","reduce","reload","unichr","unicode","xrange","False","True","None"],keywords:["exec","print"]},o={builtins:["ascii","bytes","exec","print"],keywords:["nonlocal","False","True","None"]};if(!b.version||parseInt(b.version,10)!==3){l=l.concat(n.keywords),m=m.concat(n.builtins);var p=new RegExp("^(([rub]|(ur)|(br))?('{3}|\"{3}|['\"]))","i")}else{l=l.concat(o.keywords),m=m.concat(o.builtins);var p=new RegExp("^(([rb]|(br))?('{3}|\"{3}|['\"]))","i")}var q=d(l),r=d(m),s=null,y={startState:function(a){return{tokenize:t,scopes:[{offset:a||0,type:"py"}],lastToken:null,lambda:!1,dedent:0}},token:function(a,b){var c=x(a,b);return b.lastToken={style:c,content:a.current()},a.eol()&&a.lambda&&(b.lambda=!1),c},indent:function(a,b){return a.tokenize!=t?0:a.scopes[0].offset}};return y}),CodeMirror.defineMIME("text/x-python","python"),CodeMirror.defineMode("xml",function(a,b){function h(a,b){function c(c){return b.tokenize=c,c(a,b)}var d=a.next();if(d=="<"){if(a.eat("!"))return a.eat("[")?a.match("CDATA[")?c(k("atom","]]>")):null:a.match("--")?c(k("comment","-->")):a.match("DOCTYPE",!0,!0)?(a.eatWhile(/[\w\._\-]/),c(l(1))):null;if(a.eat("?"))return a.eatWhile(/[\w\._\-]/),b.tokenize=k("meta","?>"),"meta";g=a.eat("/")?"closeTag":"openTag",a.eatSpace(),f="";var e;while(e=a.eat(/[^\s\u00a0=<>\"\'\/?]/))f+=e;return b.tokenize=i,"tag"}if(d=="&"){var h;return a.eat("#")?a.eat("x")?h=a.eatWhile(/[a-fA-F\d]/)&&a.eat(";"):h=a.eatWhile(/[\d]/)&&a.eat(";"):h=a.eatWhile(/[\w\.\-:]/)&&a.eat(";"),h?"atom":"error"}return a.eatWhile(/[^&<]/),null}function i(a,b){var c=a.next();return c==">"||c=="/"&&a.eat(">")?(b.tokenize=h,g=c==">"?"endTag":"selfcloseTag","tag"):c=="="?(g="equals",null):/[\'\"]/.test(c)?(b.tokenize=j(c),b.tokenize(a,b)):(a.eatWhile(/[^\s\u00a0=<>\"\'\/?]/),"word")}function j(a){return function(b,c){while(!b.eol())if(b.next()==a){c.tokenize=i;break}return"string"}}function k(a,b){return function(c,d){while(!c.eol()){if(c.match(b)){d.tokenize=h;break}c.next()}return a}}function l(a){return function(b,c){var d;while((d=b.next())!=null){if(d=="<")return c.tokenize=l(a+1),c.tokenize(b,c);if(d==">"){if(a==1){c.tokenize=h;break}return c.tokenize=l(a-1),c.tokenize(b,c)}}return"meta"}}function o(){for(var a=arguments.length-1;a>=0;a--)m.cc.push(arguments[a])}function p(){return o.apply(null,arguments),!0}function q(a,b){var c=d.doNotIndent.hasOwnProperty(a)||m.context&&m.context.noIndent;m.context={prev:m.context,tagName:a,indent:m.indented,startOfLine:b,noIndent:c}}function r(){m.context&&(m.context=m.context.prev)}function s(a){if(a=="openTag")return m.tagName=f,p(v,t(m.startOfLine));if(a=="closeTag"){var b=!1;return m.context?b=m.context.tagName!=f:b=!0,b&&(n="error"),p(u(b))}return p()}function t(a){return function(b){return b=="selfcloseTag"||b=="endTag"&&d.autoSelfClosers.hasOwnProperty(m.tagName.toLowerCase())?p():b=="endTag"?(q(m.tagName,a),p()):p()}}function u(a){return function(b){return a&&(n="error"),b=="endTag"?(r(),p()):(n="error",p(arguments.callee))}}function v(a){return a=="word"?(n="attribute",p(w,v)):a=="endTag"||a=="selfcloseTag"?o():(n="error",p(v))}function w(a){return a=="equals"?p(x,v):(d.allowMissing||(n="error"),a=="endTag"||a=="selfcloseTag"?o():p())}function x(a){return a=="string"?p(y):a=="word"&&d.allowUnquoted?(n="string",p()):(n="error",a=="endTag"||a=="selfCloseTag"?o():p())}function y(a){return a=="string"?p(y):o()}var c=a.indentUnit,d=b.htmlMode?{autoSelfClosers:{br:!0,img:!0,hr:!0,link:!0,input:!0,meta:!0,col:!0,frame:!0,base:!0,area:!0},doNotIndent:{pre:!0},allowUnquoted:!0,allowMissing:!1}:{autoSelfClosers:{},doNotIndent:{},allowUnquoted:!1,allowMissing:!1},e=b.alignCDATA,f,g,m,n;return{startState:function(){return{tokenize:h,cc:[],indented:0,startOfLine:!0,tagName:null,context:null}},token:function(a,b){a.sol()&&(b.startOfLine=!0,b.indented=a.indentation());if(a.eatSpace())return null;n=g=f=null;var c=b.tokenize(a,b);b.type=g;if((c||g)&&c!="comment"){m=b;for(;;){var d=b.cc.pop()||s;if(d(g||c))break}}return b.startOfLine=!1,n||c},indent:function(a,b,d){var f=a.context;if(a.tokenize!=i&&a.tokenize!=h||f&&f.noIndent)return d?d.match(/^(\s*)/)[0].length:0;if(e&&/c.keyCol)return a.skipToEnd(),"string";c.literal&&(c.literal=!1);if(a.sol()){c.keyCol=0,c.pair=!1,c.pairStart=!1;if(a.match(/---/))return"def";if(a.match(/\.\.\./))return"def";if(a.match(/\s*-\s+/))return"meta"}if(!c.pair&&a.match(/^\s*([a-z0-9\._-])+(?=\s*:)/i))return c.pair=!0,c.keyCol=a.indentation(),"atom";if(c.pair&&a.match(/^:\s*/))return c.pairStart=!0,"meta";if(a.match(/^(\{|\}|\[|\])/))return d=="{"?c.inlinePairs++:d=="}"?c.inlinePairs--:d=="["?c.inlineList++:c.inlineList--,"meta";if(c.inlineList>0&&!e&&d==",")return a.next(),"meta";if(c.inlinePairs>0&&!e&&d==",")return c.keyCol=0,c.pair=!1,c.pairStart=!1,a.next(),"meta";if(c.pairStart){if(a.match(/^\s*(\||\>)\s*/))return c.literal=!0,"meta";if(a.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i))return"variable-2";if(c.inlinePairs==0&&a.match(/^\s*-?[0-9\.\,]+\s?$/))return"number";if(c.inlinePairs>0&&a.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/))return"number";if(a.match(b))return"keyword"}return c.pairStart=!1,c.escaped=d=="\\",a.next(),null},startState:function(){return{pair:!1,pairStart:!1,keyCol:0,inlinePairs:0,inlineList:0,literal:!1,escaped:!1}}}}),CodeMirror.defineMIME("text/x-yaml","yaml"),CodeMirror.runMode=function(a,b,c,d){var e=CodeMirror.getMode(CodeMirror.defaults,b),f=c.nodeType==1,g=d&&d.tabSize||CodeMirror.defaults.tabSize;if(f){var h=c,i=[],j=0;c=function(a,b){if(a=="\n"){i.push("
"),j=0;return}var c="";for(var d=0;;){var e=a.indexOf(" ",d);if(e==-1){c+=CodeMirror.htmlEscape(a.slice(d)),j+=a.length-d;break}j+=e-d,c+=CodeMirror.htmlEscape(a.slice(d,e));var f=g-j%g;j+=f;for(var h=0;h'+c+""):i.push(c)}}var k=CodeMirror.splitLines(a),l=CodeMirror.startState(e);for(var m=0,n=k.length;m",i+1);if(-1==j){var k=b+1,l=!1,m=a.lineCount();while(k");if(-1!=o){l=!0;var p=n.lastIndexOf("/",o);if(-1!=p&&p/))return k+1}}k++}g=!0}else{var r=f.lastIndexOf("/",j);if(-1==r)g=!0;else{var q=f.substr(r,j-r+1);q.match(/\/\s*\>/)||(g=!0)}}if(g){var s=f.substr(i+1);h=s.match(e),h?(h=h[0],-1!=f.indexOf("",i)&&(g=!1)):g=!1}g||i++}if(g){var t="(\\<\\/"+h+"\\>)|(\\<"+h+"\\>)|(\\<"+h+"\\s)|(\\<"+h+"$)",u=new RegExp(t,"g"),v="",w=1,k=b+1,m=a.lineCount();while(kd)return;var e=a.getTokenAt({line:b,ch:d}).className,f=1,g=a.lineCount(),h;a:for(var i=b+1;i▼%N%'),function(f,g){f.operation(function(){var h=d(f,g);if(h)c.splice(h.pos,1),e(f,h.region);else{var i=a(f,g);if(i==null)return;var j=[];for(var k=g+1;k=g&&(h=f.lastIndexOf(b,d.ch-g))!=-1:(h=f.indexOf(b,d.ch))!=-1)return{from:{line:d.line,ch:h},to:{line:d.line,ch:h+g}}}:this.matches=function(b,c){var d=c.line,g=b?f.length-1:0,h=f[g],i=e(a.getLine(d)),j=b?i.indexOf(h)+h.length:i.lastIndexOf(h);if(b?j>=c.ch||j!=h.length:j<=c.ch||j!=i.length-h.length)return;for(;;){if(b?!d:d==a.lineCount()-1)return;i=e(a.getLine(d+=b?-1:1)),h=f[b?--g:++g];if(g>0&&g-1&&h>-1&&h>g&&(f=f.substr(0,g)+f.substring(g+d.commentStart.length,h)+f.substr(h+d.commentEnd.length)),this.replaceRange(f,b,c)}}),CodeMirror.defineExtension("autoIndentRange",function(a,b){var c=this;this.operation(function(){for(var d=a.line;d<=b.line;d++)c.indentLine(d,"smart")})}),CodeMirror.defineExtension("autoFormatRange",function(a,b){var c=this.indexFromPos(a),d=this.indexFromPos(b),e=this.getModeExt().autoFormatLineBreaks(this.getValue(),c,d),f=this;this.operation(function(){f.replaceRange(e,a,b);var d=f.posFromIndex(c).line,g=f.posFromIndex(c+e.length).line;for(var h=d;h<=g;h++)f.indentLine(h,"smart")})}),CodeMirror.modeExtensions.css={commentStart:"/*",commentEnd:"*/",wordWrapChars:[";","\\{","\\}"],autoFormatLineBreaks:function(a){return a.replace(new RegExp("(;|\\{|\\})([^\r\n])","g"),"$1\n$2")}},CodeMirror.modeExtensions.javascript={commentStart:"/*",commentEnd:"*/",wordWrapChars:[";","\\{","\\}"],getNonBreakableBlocks:function(a){var b=[new RegExp("for\\s*?\\(([\\s\\S]*?)\\)"),new RegExp("'([\\s\\S]*?)('|$)"),new RegExp('"([\\s\\S]*?)("|$)'),new RegExp("//.*([\r\n]|$)")],c=new Array;for(var d=0;db&&(e+=a.substring(b,d[f].start).replace(c,"$1\n$2"),b=d[f].start),d[f].start<=b&&d[f].end>=b&&(e+=a.substring(b,d[f].end),b=d[f].end);return b",wordWrapChars:[">"],autoFormatLineBreaks:function(a){var b=a.split("\n"),c=new RegExp("(^\\s*?<|^[^<]*?)(.+)(>\\s*?$|[^>]*?$)"),d=new RegExp("<","g"),e=new RegExp("(>)([^\r\n])","g");for(var f=0;f3){b[f]=g[1]+g[2].replace(d,"\n$&").replace(e,"$1\n$2")+g[3];continue}}return b.join("\n")}},CodeMirror.modeExtensions.htmlmixed={commentStart:"",wordWrapChars:[">",";","\\{","\\}"],getModeInfos:function(a,b){var c=new Array;c[0]={pos:0,modeExt:CodeMirror.modeExtensions.xml,modeName:"xml"};var d=new Array;d[0]={regex:new RegExp("]*>([\\s\\S]*?)(]*>|$)","i"),modeExt:CodeMirror.modeExtensions.css,modeName:"css"},d[1]={regex:new RegExp("]*>([\\s\\S]*?)(]*>|$)","i"),modeExt:CodeMirror.modeExtensions.javascript,modeName:"javascript"};var e=typeof b!="undefined"?b:a.length-1;for(var f=0;f1&&h[1].length>0){var i=g+h.index+h[0].indexOf(h[1]);c.push({pos:i,modeExt:d[f].modeExt,modeName:d[f].modeName}),c.push({pos:i+h[1].length,modeExt:c[0].modeExt,modeName:c[0].modeName}),g+=h.index+h[0].length;continue}g+=h.index+Math.max(h[0].length,1)}}return c.sort(function(b,c){return b.pos-c.pos}),c},autoFormatLineBreaks:function(a,b,c){var d=this.getModeInfos(a),e=new RegExp("^\\s*?\n"),f=new RegExp("\n\\s*?$"),g="";if(d.length>1)for(var h=1;h<=d.length;h++){var i=d[h-1].pos,j=h=c)break;if(ic&&(j=c);var k=a.substring(i,j);d[h-1].modeName!="xml"&&(!e.test(k)&&i>0&&(k="\n"+k),!f.test(k)&&j=f){var g=c(b),h=b.getSelection();b.operation(function(){if(b.lineCount()<2e3)for(var a=b.getSearchCursor(h);a.findNext();)(a.from().line!==b.getCursor(!0).line||a.from().ch!==b.getCursor(!0).ch)&&g.marked.push(b.markText(a.from(),a.to(),e))})}}var a=2;CodeMirror.defineExtension("matchHighlight",function(a,b){e(this,a,b)})}(),function(){function a(a,c,d,e){b(a,c,e)?(a.replaceSelection("\n\n","end"),a.indentLine(d.line+1),a.indentLine(d.line+2),a.setCursor({line:d.line+1,ch:a.getLine(d.line+1).length})):(a.replaceSelection(""),a.setCursor(d))}function b(a,b,d){if(typeof b=="undefined"||b==null||b==1)b=a.getOption("closeTagIndent");return b||(b=[]),c(b,d.toLowerCase())!=-1}function c(a,b){if(a.indexOf)return a.indexOf(b);for(var c=0,d=a.length;c"),a.setCursor({line:b.line,ch:b.ch+c.length+2})}CodeMirror.defaults.closeTagEnabled=!0,CodeMirror.defaults.closeTagIndent=["applet","blockquote","body","button","div","dl","fieldset","form","frameset","h1","h2","h3","h4","h5","h6","head","html","iframe","layer","legend","object","ol","p","select","table","ul"],CodeMirror.defineExtension("closeTag",function(b,c,e){if(!b.getOption("closeTagEnabled"))throw CodeMirror.Pass;var f=b.getOption("mode");if(f=="text/html"){var g=b.getCursor(),h=b.getTokenAt(g),i=h.state;if(i.mode&&i.mode!="html")throw CodeMirror.Pass;if(c==">"){var j=i.htmlState?i.htmlState.type:i.type;if(h.className=="tag"&&j=="closeTag")throw CodeMirror.Pass;b.replaceSelection(">"),g={line:g.line,ch:g.ch+1},b.setCursor(g),h=b.getTokenAt(b.getCursor()),i=h.state,j=i.htmlState?i.htmlState.type:i.type;if(h.className=="tag"&&j!="selfcloseTag"){var k=i.htmlState?i.htmlState.context.tagName:i.tagName;k.length>0&&a(b,e,g,k);return}b.setSelection({line:g.line,ch:g.ch-1},g),b.replaceSelection("")}else if(c=="/"&&h.className=="tag"&&h.string=="<"){var k=i.htmlState?i.htmlState.context?i.htmlState.context.tagName:"":i.context.tagName;if(k.length>0){d(b,g,k);return}}}else if(f=="xmlpure"){var g=b.getCursor(),h=b.getTokenAt(g),k=h.state.context.tagName;if(c==">"){if(h.string==k){b.replaceSelection(">"),g={line:g.line,ch:g.ch+1},b.setCursor(g),a(b,e,g,k);return}}else if(c=="/"&&h.string=="<"){d(b,g,k);return}}throw CodeMirror.Pass})}(),function(){function b(b){a.push(b),a.length>50&&a.shift()}function c(){return a[a.length-1]||""}function d(){return a.length>1&&a.pop(),c()}var a=[];CodeMirror.keyMap.emacs={"Ctrl-X":function(a){a.setOption("keyMap","emacs-Ctrl-X")},"Ctrl-W":function(a){b(a.getSelection()),a.replaceSelection("")},"Ctrl-Alt-W":function(a){b(a.getSelection()),a.replaceSelection("")},"Alt-W":function(a){b(a.getSelection())},"Ctrl-Y":function(a){a.replaceSelection(c())},"Alt-Y":function(a){a.replaceSelection(d())},"Ctrl-/":"undo","Shift-Ctrl--":"undo","Shift-Alt-,":"goDocStart","Shift-Alt-.":"goDocEnd","Ctrl-S":"findNext","Ctrl-R":"findPrev","Ctrl-G":"clearSearch","Shift-Alt-5":"replace","Ctrl-Z":"undo","Cmd-Z":"undo",fallthrough:["basic","emacsy"]},CodeMirror.keyMap["emacs-Ctrl-X"]={"Ctrl-S":"save","Ctrl-W":"save",S:"saveAll",F:"open",U:"undo",K:"close",auto:"emacs",catchall:function(a){}}}(),function(){function f(){c=""}function g(a){c+=a}function h(b){return function(c){a+=b}}function i(){var b=parseInt(a);return a="",b||1}function j(a){return typeof a=="string"&&(a=CodeMirror.commands[a]),function(b){for(var c=0,d=i();c0&&(e=a.length,f=0);var g=e,h=e;a:for(;b!=e;b+=c)for(var i=0;id?d:c,h=c>d?c:d;a.setCursor(f);for(var i=f;i<=h;i++)g("\n"+a.getLine(f)),a.removeLine(f)}function s(a,b){var c=e[b],d=a.getCursor().line,f=c>d?d:c,h=c>d?c:d;for(var i=f;i<=h;i++)g("\n"+a.getLine(i));a.setCursor(f)}var a="",b="f",c="",d=0,e=[],l=[/\w/,/[^\w\s]/],m=[/\S/],t=CodeMirror.keyMap.vim={0:function(b){a.length>0?h("0")(b):CodeMirror.commands.goLineStart(b)},A:function(a){i(),a.setCursor(a.getCursor().line,a.getCursor().ch+1,!0),a.setOption("keyMap","vim-insert"),q("vim-insert")},"Shift-A":function(a){i(),CodeMirror.commands.goLineEnd(a),a.setOption("keyMap","vim-insert"),q("vim-insert")},I:function(a){i(),a.setOption("keyMap","vim-insert"),q("vim-insert")},"Shift-I":function(a){i(),CodeMirror.commands.goLineStartSmart(a),a.setOption("keyMap","vim-insert"),q("vim-insert")},O:function(a){i(),CodeMirror.commands.goLineEnd(a),a.replaceSelection("\n","end"),a.setOption("keyMap","vim-insert"),q("vim-insert")},"Shift-O":function(a){i(),CodeMirror.commands.goLineStart(a),a.replaceSelection("\n","start"),a.setOption("keyMap","vim-insert"),q("vim-insert")},G:function(a){a.setOption("keyMap","vim-prefix-g")},D:function(a){a.setOption("keyMap","vim-prefix-d"),f()},M:function(a){a.setOption("keyMap","vim-prefix-m"),e=[]},Y:function(a){a.setOption("keyMap","vim-prefix-y"),f(),d=0},"/":function(a){var c=CodeMirror.commands.find;c&&c(a),b="f"},"Shift-/":function(a){var c=CodeMirror.commands.find;c&&(c(a),CodeMirror.commands.findPrev(a),b="r")},N:function(a){var c=CodeMirror.commands.findNext;c&&(b!="r"?c(a):CodeMirror.commands.findPrev(a))},"Shift-N":function(a){var c=CodeMirror.commands.findNext;c&&(b!="r"?CodeMirror.commands.findPrev(a):c.findNext(a))},"Shift-G":function(b){a==""?b.setCursor(b.lineCount()):b.setCursor(parseInt(a)-1),i(),CodeMirror.commands.goLineStart(b)},catchall:function(a){}};for(var u=1;u<10;++u)t[u]=h(u);k({H:"goColumnLeft",L:"goColumnRight",J:"goLineDown",K:"goLineUp",Left:"goColumnLeft",Right:"goColumnRight",Down:"goLineDown",Up:"goLineUp",Backspace:"goCharLeft",Space:"goCharRight",B:function(a){o(a,l,-1,"end")},E:function(a){o(a,l,1,"end")},W:function(a){o(a,l,1,"start")},"Shift-B":function(a){o(a,m,-1,"end")},"Shift-E":function(a){o(a,m,1,"end")},"Shift-W":function(a){o(a,m,1,"start")},X:function(a){CodeMirror.commands.delCharRight(a)},P:function(a){var b=a.getCursor().line;c!=""&&(CodeMirror.commands.goLineEnd(a),a.replaceSelection(c,"end")),a.setCursor(b+1)},"Shift-X":function(a){CodeMirror.commands.delCharLeft(a)},"Shift-J":function(a){p(a)},"Shift-`":function(a){var b=a.getCursor(),c=a.getRange({line:b.line,ch:b.ch},{line:b.line,ch:b.ch+1});c=c!=c.toLowerCase()?c.toLowerCase():c.toUpperCase(),a.replaceRange(c,{line:b.line,ch:b.ch},{line:b.line,ch:b.ch+1}),a.setCursor(b.line,b.ch+1)},"Ctrl-B":function(a){CodeMirror.commands.goPageUp(a)},"Ctrl-F":function(a){CodeMirror.commands.goPageDown(a)},"Ctrl-P":"goLineUp","Ctrl-N":"goLineDown",U:"undo","Ctrl-R":"redo","Shift-4":"goLineEnd"},function(a,b){t[a]=j(b)}),CodeMirror.keyMap["vim-prefix-g"]={E:j(function(a){o(a,l,-1,"start")}),"Shift-E":j(function(a){o(a,m,-1,"start")}),auto:"vim",catchall:function(a){}},CodeMirror.keyMap["vim-prefix-m"]={A:function(a){e.A=a.getCursor().line},"Shift-A":function(a){e["Shift-A"]=a.getCursor().line},B:function(a){e.B=a.getCursor().line},"Shift-B":function(a){e["Shift-B"]=a.getCursor().line},C:function(a){e.C=a.getCursor().line},"Shift-C":function(a){e["Shift-C"]=a.getCursor().line},D:function(a){e.D=a.getCursor().line},"Shift-D":function(a){e["Shift-D"]=a.getCursor().line},E:function(a){e.E=a.getCursor().line},"Shift-E":function(a){e["Shift-E"]=a.getCursor().line},F:function(a){e.F=a.getCursor().line},"Shift-F":function(a){e["Shift-F"]=a.getCursor().line},G:function(a){e.G=a.getCursor().line},"Shift-G":function(a){e["Shift-G"]=a.getCursor().line},H:function(a){e.H=a.getCursor().line},"Shift-H":function(a){e["Shift-H"]=a.getCursor().line},I:function(a){e.I=a.getCursor().line},"Shift-I":function(a){e["Shift-I"]=a.getCursor().line},J:function(a){e.J=a.getCursor().line},"Shift-J":function(a){e["Shift-J"]=a.getCursor().line},K:function(a){e.K=a.getCursor().line},"Shift-K":function(a){e["Shift-K"]=a.getCursor().line},L:function(a){e.L=a.getCursor().line},"Shift-L":function(a){e["Shift-L"]=a.getCursor().line},M:function(a){e.M=a.getCursor().line},"Shift-M":function(a){e["Shift-M"]=a.getCursor().line},N:function(a){e.N=a.getCursor().line},"Shift-N":function(a){e["Shift-N"]=a.getCursor().line},O:function(a){e.O=a.getCursor().line},"Shift-O":function(a){e["Shift-O"]=a.getCursor().line},P:function(a){e.P=a.getCursor().line},"Shift-P":function(a){e["Shift-P"]=a.getCursor().line},Q:function(a){e.Q=a.getCursor().line},"Shift-Q":function(a){e["Shift-Q"]=a.getCursor().line},R:function(a){e.R=a.getCursor().line},"Shift-R":function(a){e["Shift-R"]=a.getCursor().line},S:function(a){e.S=a.getCursor().line},"Shift-S":function(a){e["Shift-S"]=a.getCursor().line},T:function(a){e.T=a.getCursor().line},"Shift-T":function(a){e["Shift-T"]=a.getCursor().line},U:function(a){e.U=a.getCursor().line},"Shift-U":function(a){e["Shift-U"]=a.getCursor().line},V:function(a){e.V=a.getCursor().line},"Shift-V":function(a){e["Shift-V"]=a.getCursor().line},W:function(a){e.W=a.getCursor().line},"Shift-W":function(a){e["Shift-W"]=a.getCursor().line},X:function(a){e.X=a.getCursor().line},"Shift-X":function(a){e["Shift-X"]=a.getCursor().line},Y:function(a){e.Y=a.getCursor().line},"Shift-Y":function(a){e["Shift-Y"]=a.getCursor().line},Z:function(a){e.Z=a.getCursor().line},"Shift-Z":function(a){e["Shift-Z"]=a.getCursor().line},auto:"vim",catchall:function(a){}},CodeMirror.keyMap["vim-prefix-d"]={D:j(function(a){g("\n"+a.getLine(a.getCursor().line)),a.removeLine(a.getCursor().line)}),"'":function(a){a.setOption("keyMap","vim-prefix-d'"),f()},auto:"vim",catchall:function(a){}},CodeMirror.keyMap["vim-prefix-d'"]={A:function(a){r(a,"A")},"Shift-A":function(a){r(a,"Shift-A")},B:function(a){r(a,"B")},"Shift-B":function(a){r(a,"Shift-B")},C:function(a){r(a,"C")},"Shift-C":function(a){r(a,"Shift-C")},D:function(a){r(a,"D")},"Shift-D":function(a){r(a,"Shift-D")},E:function(a){r(a,"E")},"Shift-E":function(a){r(a,"Shift-E")},F:function(a){r(a,"F")},"Shift-F":function(a){r(a,"Shift-F")},G:function(a){r(a,"G")},"Shift-G":function(a){r(a,"Shift-G")},H:function(a){r(a,"H")},"Shift-H":function(a){r(a,"Shift-H")},I:function(a){r(a,"I")},"Shift-I":function(a){r(a,"Shift-I")},J:function(a){r(a,"J")},"Shift-J":function(a){r(a,"Shift-J")},K:function(a){r(a,"K")},"Shift-K":function(a){r(a,"Shift-K")},L:function(a){r(a,"L")},"Shift-L":function(a){r(a,"Shift-L")},M:function(a){r(a,"M")},"Shift-M":function(a){r(a,"Shift-M")},N:function(a){r(a,"N")},"Shift-N":function(a){r(a,"Shift-N")},O:function(a){r(a,"O")},"Shift-O":function(a){r(a,"Shift-O")},P:function(a){r(a,"P")},"Shift-P":function(a){r(a,"Shift-P")},Q:function(a){r(a,"Q")},"Shift-Q":function(a){r(a,"Shift-Q")},R:function(a){r(a,"R")},"Shift-R":function(a){r(a,"Shift-R")},S:function(a){r(a,"S")},"Shift-S":function(a){r(a,"Shift-S")},T:function(a){r(a,"T")},"Shift-T":function(a){r(a,"Shift-T")},U:function(a){r(a,"U")},"Shift-U":function(a){r(a,"Shift-U")},V:function(a){r(a,"V")},"Shift-V":function(a){r(a,"Shift-V")},W:function(a){r(a,"W")},"Shift-W":function(a){r(a,"Shift-W")},X:function(a){r(a,"X")},"Shift-X":function(a){r(a,"Shift-X")},Y:function(a){r(a,"Y")},"Shift-Y":function(a){r(a,"Shift-Y")},Z:function(a){r(a,"Z")},"Shift-Z":function(a){r(a,"Shift-Z")},auto:"vim",catchall:function(a){}},CodeMirror.keyMap["vim-prefix-y'"]={A:function(a){s(a,"A")},"Shift-A":function(a){s(a,"Shift-A")},B:function(a){s(a,"B")},"Shift-B":function(a){s(a,"Shift-B")},C:function(a){s(a,"C")},"Shift-C":function(a){s(a,"Shift-C")},D:function(a){s(a,"D")},"Shift-D":function(a){s(a,"Shift-D")},E:function(a){s(a,"E")},"Shift-E":function(a){s(a,"Shift-E")},F:function(a){s(a,"F")},"Shift-F":function(a){s(a,"Shift-F")},G:function(a){s(a,"G")},"Shift-G":function(a){s(a,"Shift-G")},H:function(a){s(a,"H")},"Shift-H":function(a){s(a,"Shift-H")},I:function(a){s(a,"I")},"Shift-I":function(a){s(a,"Shift-I")},J:function(a){s(a,"J")},"Shift-J":function(a){s(a,"Shift-J")},K:function(a){s(a,"K")},"Shift-K":function(a){s(a,"Shift-K")},L:function(a){s(a,"L")},"Shift-L":function(a){s(a,"Shift-L")},M:function(a){s(a,"M")},"Shift-M":function(a){s(a,"Shift-M")},N:function(a){s(a,"N")},"Shift-N":function(a){s(a,"Shift-N")},O:function(a){s(a,"O")},"Shift-O":function(a){s(a,"Shift-O")},P:function(a){s(a,"P")},"Shift-P":function(a){s(a,"Shift-P")},Q:function(a){s(a,"Q")},"Shift-Q":function(a){s(a,"Shift-Q")},R:function(a){s(a,"R")},"Shift-R":function(a){s(a,"Shift-R")},S:function(a){s(a,"S")},"Shift-S":function(a){s(a,"Shift-S")},T:function(a){s(a,"T")},"Shift-T":function(a){s(a,"Shift-T")},U:function(a){s(a,"U")},"Shift-U":function(a){s(a,"Shift-U")},V:function(a){s(a,"V")},"Shift-V":function(a){s(a,"Shift-V")},W:function(a){s(a,"W")},"Shift-W":function(a){s(a,"Shift-W")},X:function(a){s(a,"X")},"Shift-X":function(a){s(a,"Shift-X")},Y:function(a){s(a,"Y")},"Shift-Y":function(a){s(a,"Shift-Y")},Z:function(a){s(a,"Z")},"Shift-Z":function(a){s(a,"Shift-Z")},auto:"vim",catchall:function(a){}},CodeMirror.keyMap["vim-prefix-y"]={Y:j(function(a){g("\n"+a.getLine(a.getCursor().line+d)),d++}),"'":function(a){a.setOption("keyMap","vim-prefix-y'"),f()},auto:"vim",catchall:function(a){}},CodeMirror.keyMap["vim-insert"]={Esc:function(a){a.setCursor(a.getCursor().line,a.getCursor().ch-1,!0),a.setOption("keyMap","vim"),q("vim")},"Ctrl-N":function(a){},"Ctrl-P":function(a){},fallthrough:["default"]}}() \ No newline at end of file diff --git a/static/js/imageinput.js b/static/js/imageinput.js new file mode 100644 index 0000000000..5b4978ee11 --- /dev/null +++ b/static/js/imageinput.js @@ -0,0 +1,24 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Simple image input +// +//////////////////////////////////////////////////////////////////////////////// + +// click on image, return coordinates +// put a dot at location of click, on imag + +// window.image_input_click = function(id,event){ + +function image_input_click(id,event){ + iidiv = document.getElementById("imageinput_"+id); + pos_x = event.offsetX?(event.offsetX):event.pageX-document.iidiv.offsetLeft; + pos_y = event.offsetY?(event.offsetY):event.pageY-document.iidiv.offsetTop; + result = "[" + pos_x + "," + pos_y + "]"; + cx = (pos_x-15) +"px"; + cy = (pos_y-15) +"px" ; + // alert(result); + document.getElementById("cross_"+id).style.left = cx; + document.getElementById("cross_"+id).style.top = cy; + document.getElementById("cross_"+id).style.visibility = "visible" ; + document.getElementById("input_"+id).value =result; +} diff --git a/templates/solutionspan.html b/templates/solutionspan.html new file mode 100644 index 0000000000..4e85d3aaf4 --- /dev/null +++ b/templates/solutionspan.html @@ -0,0 +1,3 @@ +
+ +
diff --git a/templates/textbox.html b/templates/textbox.html new file mode 100644 index 0000000000..cbbab7babc --- /dev/null +++ b/templates/textbox.html @@ -0,0 +1,34 @@ +
+ + + + + % if state == 'unsubmitted': + + % elif state == 'correct': + + % elif state == 'incorrect': + + % elif state == 'incomplete': + + % endif +
+ (${state}) +
+ ${msg|n} +
+ +
+ + +