'+a.addText+" "),l=d.find("tr:last a")):(c.filter(":last").after('"),l=c.filter(":last").next().find("a")));l.on("click",function(d){d.preventDefault();d=b("#"+a.prefix+"-empty");
+var c=d.clone(!0);c.removeClass(a.emptyCssClass).addClass(a.formCssClass).attr("id",a.prefix+"-"+h);c.is("tr")?c.children(":last").append('"):c.is("ul")||c.is("ol")?c.append(''+a.deleteText+" "):c.children(":first").append(''+a.deleteText+" ");c.find("*").each(function(){f(this,a.prefix,g.val())});c.insertBefore(b(d));
+b(g).val(parseInt(g.val(),10)+1);h+=1;""!==e.val()&&0>=e.val()-g.val()&&l.parent().hide();c.find("a."+a.deleteCssClass).on("click",function(d){d.preventDefault();c.remove();--h;a.removed&&a.removed(c);b(document).trigger("formset:removed",[c,a.prefix]);d=b("."+a.formCssClass);b("#id_"+a.prefix+"-TOTAL_FORMS").val(d.length);(""===e.val()||0 tr",b(d).tabularFormset(d,a.options)}})})})(django.jQuery);
diff --git a/static/admin/js/jquery.init.js b/static/admin/js/jquery.init.js
new file mode 100644
index 0000000..f3ac162
--- /dev/null
+++ b/static/admin/js/jquery.init.js
@@ -0,0 +1,8 @@
+/*global django:true, jQuery:false*/
+/* Puts the included jQuery into our own namespace using noConflict and passing
+ * it 'true'. This ensures that the included jQuery doesn't pollute the global
+ * namespace (i.e. this preserves pre-existing values for both window.$ and
+ * window.jQuery).
+ */
+var django = django || {};
+django.jQuery = jQuery.noConflict(true);
diff --git a/static/admin/js/popup_response.js b/static/admin/js/popup_response.js
new file mode 100644
index 0000000..b4a07e7
--- /dev/null
+++ b/static/admin/js/popup_response.js
@@ -0,0 +1,16 @@
+/*global opener */
+(function() {
+ 'use strict';
+ var initData = JSON.parse(document.getElementById('django-admin-popup-response-constants').dataset.popupResponse);
+ switch(initData.action) {
+ case 'change':
+ opener.dismissChangeRelatedObjectPopup(window, initData.value, initData.obj, initData.new_value);
+ break;
+ case 'delete':
+ opener.dismissDeleteRelatedObjectPopup(window, initData.value);
+ break;
+ default:
+ opener.dismissAddRelatedObjectPopup(window, initData.value, initData.obj);
+ break;
+ }
+})();
diff --git a/static/admin/js/prepopulate.js b/static/admin/js/prepopulate.js
new file mode 100644
index 0000000..bef45a3
--- /dev/null
+++ b/static/admin/js/prepopulate.js
@@ -0,0 +1,42 @@
+/*global URLify*/
+(function($) {
+ 'use strict';
+ $.fn.prepopulate = function(dependencies, maxLength, allowUnicode) {
+ /*
+ Depends on urlify.js
+ Populates a selected field with the values of the dependent fields,
+ URLifies and shortens the string.
+ dependencies - array of dependent fields ids
+ maxLength - maximum length of the URLify'd string
+ allowUnicode - Unicode support of the URLify'd string
+ */
+ return this.each(function() {
+ var prepopulatedField = $(this);
+
+ var populate = function() {
+ // Bail if the field's value has been changed by the user
+ if (prepopulatedField.data('_changed')) {
+ return;
+ }
+
+ var values = [];
+ $.each(dependencies, function(i, field) {
+ field = $(field);
+ if (field.val().length > 0) {
+ values.push(field.val());
+ }
+ });
+ prepopulatedField.val(URLify(values.join(' '), maxLength, allowUnicode));
+ };
+
+ prepopulatedField.data('_changed', false);
+ prepopulatedField.on('change', function() {
+ prepopulatedField.data('_changed', true);
+ });
+
+ if (!prepopulatedField.val()) {
+ $(dependencies.join(',')).on('keyup change focus', populate);
+ }
+ });
+ };
+})(django.jQuery);
diff --git a/static/admin/js/prepopulate.min.js b/static/admin/js/prepopulate.min.js
new file mode 100644
index 0000000..43c1b79
--- /dev/null
+++ b/static/admin/js/prepopulate.min.js
@@ -0,0 +1 @@
+(function(b){b.fn.prepopulate=function(d,f,g){return this.each(function(){var a=b(this),h=function(){if(!a.data("_changed")){var e=[];b.each(d,function(a,c){c=b(c);0 elements
+ // (i.e., `typeof document.createElement( "object" ) === "function"`).
+ // We don't want to classify *any* DOM node as a function.
+ return typeof obj === "function" && typeof obj.nodeType !== "number";
+ };
+
+
+var isWindow = function isWindow( obj ) {
+ return obj != null && obj === obj.window;
+ };
+
+
+
+
+ var preservedScriptAttributes = {
+ type: true,
+ src: true,
+ noModule: true
+ };
+
+ function DOMEval( code, doc, node ) {
+ doc = doc || document;
+
+ var i,
+ script = doc.createElement( "script" );
+
+ script.text = code;
+ if ( node ) {
+ for ( i in preservedScriptAttributes ) {
+ if ( node[ i ] ) {
+ script[ i ] = node[ i ];
+ }
+ }
+ }
+ doc.head.appendChild( script ).parentNode.removeChild( script );
+ }
+
+
+function toType( obj ) {
+ if ( obj == null ) {
+ return obj + "";
+ }
+
+ // Support: Android <=2.3 only (functionish RegExp)
+ return typeof obj === "object" || typeof obj === "function" ?
+ class2type[ toString.call( obj ) ] || "object" :
+ typeof obj;
+}
+/* global Symbol */
+// Defining this global in .eslintrc.json would create a danger of using the global
+// unguarded in another place, it seems safer to define global only for this module
+
+
+
+var
+ version = "3.3.1",
+
+ // Define a local copy of jQuery
+ jQuery = function( selector, context ) {
+
+ // The jQuery object is actually just the init constructor 'enhanced'
+ // Need init if jQuery is called (just allow error to be thrown if not included)
+ return new jQuery.fn.init( selector, context );
+ },
+
+ // Support: Android <=4.0 only
+ // Make sure we trim BOM and NBSP
+ rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
+
+jQuery.fn = jQuery.prototype = {
+
+ // The current version of jQuery being used
+ jquery: version,
+
+ constructor: jQuery,
+
+ // The default length of a jQuery object is 0
+ length: 0,
+
+ toArray: function() {
+ return slice.call( this );
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+
+ // Return all the elements in a clean array
+ if ( num == null ) {
+ return slice.call( this );
+ }
+
+ // Return just the one element from the set
+ return num < 0 ? this[ num + this.length ] : this[ num ];
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems ) {
+
+ // Build a new jQuery matched element set
+ var ret = jQuery.merge( this.constructor(), elems );
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Execute a callback for every element in the matched set.
+ each: function( callback ) {
+ return jQuery.each( this, callback );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map( this, function( elem, i ) {
+ return callback.call( elem, i, elem );
+ } ) );
+ },
+
+ slice: function() {
+ return this.pushStack( slice.apply( this, arguments ) );
+ },
+
+ first: function() {
+ return this.eq( 0 );
+ },
+
+ last: function() {
+ return this.eq( -1 );
+ },
+
+ eq: function( i ) {
+ var len = this.length,
+ j = +i + ( i < 0 ? len : 0 );
+ return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
+ },
+
+ end: function() {
+ return this.prevObject || this.constructor();
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: push,
+ sort: arr.sort,
+ splice: arr.splice
+};
+
+jQuery.extend = jQuery.fn.extend = function() {
+ var options, name, src, copy, copyIsArray, clone,
+ target = arguments[ 0 ] || {},
+ i = 1,
+ length = arguments.length,
+ deep = false;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+
+ // Skip the boolean and the target
+ target = arguments[ i ] || {};
+ i++;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !isFunction( target ) ) {
+ target = {};
+ }
+
+ // Extend jQuery itself if only one argument is passed
+ if ( i === length ) {
+ target = this;
+ i--;
+ }
+
+ for ( ; i < length; i++ ) {
+
+ // Only deal with non-null/undefined values
+ if ( ( options = arguments[ i ] ) != null ) {
+
+ // Extend the base object
+ for ( name in options ) {
+ src = target[ name ];
+ copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy ) {
+ continue;
+ }
+
+ // Recurse if we're merging plain objects or arrays
+ if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
+ ( copyIsArray = Array.isArray( copy ) ) ) ) {
+
+ if ( copyIsArray ) {
+ copyIsArray = false;
+ clone = src && Array.isArray( src ) ? src : [];
+
+ } else {
+ clone = src && jQuery.isPlainObject( src ) ? src : {};
+ }
+
+ // Never move original objects, clone them
+ target[ name ] = jQuery.extend( deep, clone, copy );
+
+ // Don't bring in undefined values
+ } else if ( copy !== undefined ) {
+ target[ name ] = copy;
+ }
+ }
+ }
+ }
+
+ // Return the modified object
+ return target;
+};
+
+jQuery.extend( {
+
+ // Unique for each copy of jQuery on the page
+ expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
+
+ // Assume jQuery is ready without the ready module
+ isReady: true,
+
+ error: function( msg ) {
+ throw new Error( msg );
+ },
+
+ noop: function() {},
+
+ isPlainObject: function( obj ) {
+ var proto, Ctor;
+
+ // Detect obvious negatives
+ // Use toString instead of jQuery.type to catch host objects
+ if ( !obj || toString.call( obj ) !== "[object Object]" ) {
+ return false;
+ }
+
+ proto = getProto( obj );
+
+ // Objects with no prototype (e.g., `Object.create( null )`) are plain
+ if ( !proto ) {
+ return true;
+ }
+
+ // Objects with prototype are plain iff they were constructed by a global Object function
+ Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
+ return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
+ },
+
+ isEmptyObject: function( obj ) {
+
+ /* eslint-disable no-unused-vars */
+ // See https://github.com/eslint/eslint/issues/6125
+ var name;
+
+ for ( name in obj ) {
+ return false;
+ }
+ return true;
+ },
+
+ // Evaluates a script in a global context
+ globalEval: function( code ) {
+ DOMEval( code );
+ },
+
+ each: function( obj, callback ) {
+ var length, i = 0;
+
+ if ( isArrayLike( obj ) ) {
+ length = obj.length;
+ for ( ; i < length; i++ ) {
+ if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( i in obj ) {
+ if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
+ break;
+ }
+ }
+ }
+
+ return obj;
+ },
+
+ // Support: Android <=4.0 only
+ trim: function( text ) {
+ return text == null ?
+ "" :
+ ( text + "" ).replace( rtrim, "" );
+ },
+
+ // results is for internal usage only
+ makeArray: function( arr, results ) {
+ var ret = results || [];
+
+ if ( arr != null ) {
+ if ( isArrayLike( Object( arr ) ) ) {
+ jQuery.merge( ret,
+ typeof arr === "string" ?
+ [ arr ] : arr
+ );
+ } else {
+ push.call( ret, arr );
+ }
+ }
+
+ return ret;
+ },
+
+ inArray: function( elem, arr, i ) {
+ return arr == null ? -1 : indexOf.call( arr, elem, i );
+ },
+
+ // Support: Android <=4.0 only, PhantomJS 1 only
+ // push.apply(_, arraylike) throws on ancient WebKit
+ merge: function( first, second ) {
+ var len = +second.length,
+ j = 0,
+ i = first.length;
+
+ for ( ; j < len; j++ ) {
+ first[ i++ ] = second[ j ];
+ }
+
+ first.length = i;
+
+ return first;
+ },
+
+ grep: function( elems, callback, invert ) {
+ var callbackInverse,
+ matches = [],
+ i = 0,
+ length = elems.length,
+ callbackExpect = !invert;
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( ; i < length; i++ ) {
+ callbackInverse = !callback( elems[ i ], i );
+ if ( callbackInverse !== callbackExpect ) {
+ matches.push( elems[ i ] );
+ }
+ }
+
+ return matches;
+ },
+
+ // arg is for internal usage only
+ map: function( elems, callback, arg ) {
+ var length, value,
+ i = 0,
+ ret = [];
+
+ // Go through the array, translating each of the items to their new values
+ if ( isArrayLike( elems ) ) {
+ length = elems.length;
+ for ( ; i < length; i++ ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret.push( value );
+ }
+ }
+
+ // Go through every key on the object,
+ } else {
+ for ( i in elems ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret.push( value );
+ }
+ }
+ }
+
+ // Flatten any nested arrays
+ return concat.apply( [], ret );
+ },
+
+ // A global GUID counter for objects
+ guid: 1,
+
+ // jQuery.support is not used in Core but other projects attach their
+ // properties to it so it needs to exist.
+ support: support
+} );
+
+if ( typeof Symbol === "function" ) {
+ jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
+}
+
+// Populate the class2type map
+jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
+function( i, name ) {
+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
+} );
+
+function isArrayLike( obj ) {
+
+ // Support: real iOS 8.2 only (not reproducible in simulator)
+ // `in` check used to prevent JIT error (gh-2145)
+ // hasOwn isn't used here due to false negatives
+ // regarding Nodelist length in IE
+ var length = !!obj && "length" in obj && obj.length,
+ type = toType( obj );
+
+ if ( isFunction( obj ) || isWindow( obj ) ) {
+ return false;
+ }
+
+ return type === "array" || length === 0 ||
+ typeof length === "number" && length > 0 && ( length - 1 ) in obj;
+}
+var Sizzle =
+/*!
+ * Sizzle CSS Selector Engine v2.3.3
+ * https://sizzlejs.com/
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2016-08-08
+ */
+(function( window ) {
+
+var i,
+ support,
+ Expr,
+ getText,
+ isXML,
+ tokenize,
+ compile,
+ select,
+ outermostContext,
+ sortInput,
+ hasDuplicate,
+
+ // Local document vars
+ setDocument,
+ document,
+ docElem,
+ documentIsHTML,
+ rbuggyQSA,
+ rbuggyMatches,
+ matches,
+ contains,
+
+ // Instance-specific data
+ expando = "sizzle" + 1 * new Date(),
+ preferredDoc = window.document,
+ dirruns = 0,
+ done = 0,
+ classCache = createCache(),
+ tokenCache = createCache(),
+ compilerCache = createCache(),
+ sortOrder = function( a, b ) {
+ if ( a === b ) {
+ hasDuplicate = true;
+ }
+ return 0;
+ },
+
+ // Instance methods
+ hasOwn = ({}).hasOwnProperty,
+ arr = [],
+ pop = arr.pop,
+ push_native = arr.push,
+ push = arr.push,
+ slice = arr.slice,
+ // Use a stripped-down indexOf as it's faster than native
+ // https://jsperf.com/thor-indexof-vs-for/5
+ indexOf = function( list, elem ) {
+ var i = 0,
+ len = list.length;
+ for ( ; i < len; i++ ) {
+ if ( list[i] === elem ) {
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
+
+ // Regular expressions
+
+ // http://www.w3.org/TR/css3-selectors/#whitespace
+ whitespace = "[\\x20\\t\\r\\n\\f]",
+
+ // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+ identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
+
+ // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
+ attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
+ // Operator (capture 2)
+ "*([*^$|!~]?=)" + whitespace +
+ // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
+ "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
+ "*\\]",
+
+ pseudos = ":(" + identifier + ")(?:\\((" +
+ // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
+ // 1. quoted (capture 3; capture 4 or capture 5)
+ "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
+ // 2. simple (capture 6)
+ "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
+ // 3. anything else (capture 2)
+ ".*" +
+ ")\\)|)",
+
+ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+ rwhitespace = new RegExp( whitespace + "+", "g" ),
+ rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+
+ rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+ rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
+
+ rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
+
+ rpseudo = new RegExp( pseudos ),
+ ridentifier = new RegExp( "^" + identifier + "$" ),
+
+ matchExpr = {
+ "ID": new RegExp( "^#(" + identifier + ")" ),
+ "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
+ "TAG": new RegExp( "^(" + identifier + "|[*])" ),
+ "ATTR": new RegExp( "^" + attributes ),
+ "PSEUDO": new RegExp( "^" + pseudos ),
+ "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
+ "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+ "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+ "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
+ // For use in libraries implementing .is()
+ // We use this for POS matching in `select`
+ "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
+ whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
+ },
+
+ rinputs = /^(?:input|select|textarea|button)$/i,
+ rheader = /^h\d$/i,
+
+ rnative = /^[^{]+\{\s*\[native \w/,
+
+ // Easily-parseable/retrievable ID or TAG or CLASS selectors
+ rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+
+ rsibling = /[+~]/,
+
+ // CSS escapes
+ // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+ runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
+ funescape = function( _, escaped, escapedWhitespace ) {
+ var high = "0x" + escaped - 0x10000;
+ // NaN means non-codepoint
+ // Support: Firefox<24
+ // Workaround erroneous numeric interpretation of +"0x"
+ return high !== high || escapedWhitespace ?
+ escaped :
+ high < 0 ?
+ // BMP codepoint
+ String.fromCharCode( high + 0x10000 ) :
+ // Supplemental Plane codepoint (surrogate pair)
+ String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
+ },
+
+ // CSS string/identifier serialization
+ // https://drafts.csswg.org/cssom/#common-serializing-idioms
+ rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
+ fcssescape = function( ch, asCodePoint ) {
+ if ( asCodePoint ) {
+
+ // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
+ if ( ch === "\0" ) {
+ return "\uFFFD";
+ }
+
+ // Control characters and (dependent upon position) numbers get escaped as code points
+ return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
+ }
+
+ // Other potentially-special ASCII characters get backslash-escaped
+ return "\\" + ch;
+ },
+
+ // Used for iframes
+ // See setDocument()
+ // Removing the function wrapper causes a "Permission Denied"
+ // error in IE
+ unloadHandler = function() {
+ setDocument();
+ },
+
+ disabledAncestor = addCombinator(
+ function( elem ) {
+ return elem.disabled === true && ("form" in elem || "label" in elem);
+ },
+ { dir: "parentNode", next: "legend" }
+ );
+
+// Optimize for push.apply( _, NodeList )
+try {
+ push.apply(
+ (arr = slice.call( preferredDoc.childNodes )),
+ preferredDoc.childNodes
+ );
+ // Support: Android<4.0
+ // Detect silently failing push.apply
+ arr[ preferredDoc.childNodes.length ].nodeType;
+} catch ( e ) {
+ push = { apply: arr.length ?
+
+ // Leverage slice if possible
+ function( target, els ) {
+ push_native.apply( target, slice.call(els) );
+ } :
+
+ // Support: IE<9
+ // Otherwise append directly
+ function( target, els ) {
+ var j = target.length,
+ i = 0;
+ // Can't trust NodeList.length
+ while ( (target[j++] = els[i++]) ) {}
+ target.length = j - 1;
+ }
+ };
+}
+
+function Sizzle( selector, context, results, seed ) {
+ var m, i, elem, nid, match, groups, newSelector,
+ newContext = context && context.ownerDocument,
+
+ // nodeType defaults to 9, since context defaults to document
+ nodeType = context ? context.nodeType : 9;
+
+ results = results || [];
+
+ // Return early from calls with invalid selector or context
+ if ( typeof selector !== "string" || !selector ||
+ nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
+
+ return results;
+ }
+
+ // Try to shortcut find operations (as opposed to filters) in HTML documents
+ if ( !seed ) {
+
+ if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
+ setDocument( context );
+ }
+ context = context || document;
+
+ if ( documentIsHTML ) {
+
+ // If the selector is sufficiently simple, try using a "get*By*" DOM method
+ // (excepting DocumentFragment context, where the methods don't exist)
+ if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
+
+ // ID selector
+ if ( (m = match[1]) ) {
+
+ // Document context
+ if ( nodeType === 9 ) {
+ if ( (elem = context.getElementById( m )) ) {
+
+ // Support: IE, Opera, Webkit
+ // TODO: identify versions
+ // getElementById can match elements by name instead of ID
+ if ( elem.id === m ) {
+ results.push( elem );
+ return results;
+ }
+ } else {
+ return results;
+ }
+
+ // Element context
+ } else {
+
+ // Support: IE, Opera, Webkit
+ // TODO: identify versions
+ // getElementById can match elements by name instead of ID
+ if ( newContext && (elem = newContext.getElementById( m )) &&
+ contains( context, elem ) &&
+ elem.id === m ) {
+
+ results.push( elem );
+ return results;
+ }
+ }
+
+ // Type selector
+ } else if ( match[2] ) {
+ push.apply( results, context.getElementsByTagName( selector ) );
+ return results;
+
+ // Class selector
+ } else if ( (m = match[3]) && support.getElementsByClassName &&
+ context.getElementsByClassName ) {
+
+ push.apply( results, context.getElementsByClassName( m ) );
+ return results;
+ }
+ }
+
+ // Take advantage of querySelectorAll
+ if ( support.qsa &&
+ !compilerCache[ selector + " " ] &&
+ (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+
+ if ( nodeType !== 1 ) {
+ newContext = context;
+ newSelector = selector;
+
+ // qSA looks outside Element context, which is not what we want
+ // Thanks to Andrew Dupont for this workaround technique
+ // Support: IE <=8
+ // Exclude object elements
+ } else if ( context.nodeName.toLowerCase() !== "object" ) {
+
+ // Capture the context ID, setting it first if necessary
+ if ( (nid = context.getAttribute( "id" )) ) {
+ nid = nid.replace( rcssescape, fcssescape );
+ } else {
+ context.setAttribute( "id", (nid = expando) );
+ }
+
+ // Prefix every selector in the list
+ groups = tokenize( selector );
+ i = groups.length;
+ while ( i-- ) {
+ groups[i] = "#" + nid + " " + toSelector( groups[i] );
+ }
+ newSelector = groups.join( "," );
+
+ // Expand context for sibling selectors
+ newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
+ context;
+ }
+
+ if ( newSelector ) {
+ try {
+ push.apply( results,
+ newContext.querySelectorAll( newSelector )
+ );
+ return results;
+ } catch ( qsaError ) {
+ } finally {
+ if ( nid === expando ) {
+ context.removeAttribute( "id" );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // All others
+ return select( selector.replace( rtrim, "$1" ), context, results, seed );
+}
+
+/**
+ * Create key-value caches of limited size
+ * @returns {function(string, object)} Returns the Object data after storing it on itself with
+ * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
+ * deleting the oldest entry
+ */
+function createCache() {
+ var keys = [];
+
+ function cache( key, value ) {
+ // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
+ if ( keys.push( key + " " ) > Expr.cacheLength ) {
+ // Only keep the most recent entries
+ delete cache[ keys.shift() ];
+ }
+ return (cache[ key + " " ] = value);
+ }
+ return cache;
+}
+
+/**
+ * Mark a function for special use by Sizzle
+ * @param {Function} fn The function to mark
+ */
+function markFunction( fn ) {
+ fn[ expando ] = true;
+ return fn;
+}
+
+/**
+ * Support testing using an element
+ * @param {Function} fn Passed the created element and returns a boolean result
+ */
+function assert( fn ) {
+ var el = document.createElement("fieldset");
+
+ try {
+ return !!fn( el );
+ } catch (e) {
+ return false;
+ } finally {
+ // Remove from its parent by default
+ if ( el.parentNode ) {
+ el.parentNode.removeChild( el );
+ }
+ // release memory in IE
+ el = null;
+ }
+}
+
+/**
+ * Adds the same handler for all of the specified attrs
+ * @param {String} attrs Pipe-separated list of attributes
+ * @param {Function} handler The method that will be applied
+ */
+function addHandle( attrs, handler ) {
+ var arr = attrs.split("|"),
+ i = arr.length;
+
+ while ( i-- ) {
+ Expr.attrHandle[ arr[i] ] = handler;
+ }
+}
+
+/**
+ * Checks document order of two siblings
+ * @param {Element} a
+ * @param {Element} b
+ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
+ */
+function siblingCheck( a, b ) {
+ var cur = b && a,
+ diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
+ a.sourceIndex - b.sourceIndex;
+
+ // Use IE sourceIndex if available on both nodes
+ if ( diff ) {
+ return diff;
+ }
+
+ // Check if b follows a
+ if ( cur ) {
+ while ( (cur = cur.nextSibling) ) {
+ if ( cur === b ) {
+ return -1;
+ }
+ }
+ }
+
+ return a ? 1 : -1;
+}
+
+/**
+ * Returns a function to use in pseudos for input types
+ * @param {String} type
+ */
+function createInputPseudo( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === type;
+ };
+}
+
+/**
+ * Returns a function to use in pseudos for buttons
+ * @param {String} type
+ */
+function createButtonPseudo( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button") && elem.type === type;
+ };
+}
+
+/**
+ * Returns a function to use in pseudos for :enabled/:disabled
+ * @param {Boolean} disabled true for :disabled; false for :enabled
+ */
+function createDisabledPseudo( disabled ) {
+
+ // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
+ return function( elem ) {
+
+ // Only certain elements can match :enabled or :disabled
+ // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
+ // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
+ if ( "form" in elem ) {
+
+ // Check for inherited disabledness on relevant non-disabled elements:
+ // * listed form-associated elements in a disabled fieldset
+ // https://html.spec.whatwg.org/multipage/forms.html#category-listed
+ // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
+ // * option elements in a disabled optgroup
+ // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
+ // All such elements have a "form" property.
+ if ( elem.parentNode && elem.disabled === false ) {
+
+ // Option elements defer to a parent optgroup if present
+ if ( "label" in elem ) {
+ if ( "label" in elem.parentNode ) {
+ return elem.parentNode.disabled === disabled;
+ } else {
+ return elem.disabled === disabled;
+ }
+ }
+
+ // Support: IE 6 - 11
+ // Use the isDisabled shortcut property to check for disabled fieldset ancestors
+ return elem.isDisabled === disabled ||
+
+ // Where there is no isDisabled, check manually
+ /* jshint -W018 */
+ elem.isDisabled !== !disabled &&
+ disabledAncestor( elem ) === disabled;
+ }
+
+ return elem.disabled === disabled;
+
+ // Try to winnow out elements that can't be disabled before trusting the disabled property.
+ // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
+ // even exist on them, let alone have a boolean value.
+ } else if ( "label" in elem ) {
+ return elem.disabled === disabled;
+ }
+
+ // Remaining elements are neither :enabled nor :disabled
+ return false;
+ };
+}
+
+/**
+ * Returns a function to use in pseudos for positionals
+ * @param {Function} fn
+ */
+function createPositionalPseudo( fn ) {
+ return markFunction(function( argument ) {
+ argument = +argument;
+ return markFunction(function( seed, matches ) {
+ var j,
+ matchIndexes = fn( [], seed.length, argument ),
+ i = matchIndexes.length;
+
+ // Match elements found at the specified indexes
+ while ( i-- ) {
+ if ( seed[ (j = matchIndexes[i]) ] ) {
+ seed[j] = !(matches[j] = seed[j]);
+ }
+ }
+ });
+ });
+}
+
+/**
+ * Checks a node for validity as a Sizzle context
+ * @param {Element|Object=} context
+ * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
+ */
+function testContext( context ) {
+ return context && typeof context.getElementsByTagName !== "undefined" && context;
+}
+
+// Expose support vars for convenience
+support = Sizzle.support = {};
+
+/**
+ * Detects XML nodes
+ * @param {Element|Object} elem An element or a document
+ * @returns {Boolean} True iff elem is a non-HTML XML node
+ */
+isXML = Sizzle.isXML = function( elem ) {
+ // documentElement is verified for cases where it doesn't yet exist
+ // (such as loading iframes in IE - #4833)
+ var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+/**
+ * Sets document-related variables once based on the current document
+ * @param {Element|Object} [doc] An element or document object to use to set the document
+ * @returns {Object} Returns the current document
+ */
+setDocument = Sizzle.setDocument = function( node ) {
+ var hasCompare, subWindow,
+ doc = node ? node.ownerDocument || node : preferredDoc;
+
+ // Return early if doc is invalid or already selected
+ if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
+ return document;
+ }
+
+ // Update global variables
+ document = doc;
+ docElem = document.documentElement;
+ documentIsHTML = !isXML( document );
+
+ // Support: IE 9-11, Edge
+ // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
+ if ( preferredDoc !== document &&
+ (subWindow = document.defaultView) && subWindow.top !== subWindow ) {
+
+ // Support: IE 11, Edge
+ if ( subWindow.addEventListener ) {
+ subWindow.addEventListener( "unload", unloadHandler, false );
+
+ // Support: IE 9 - 10 only
+ } else if ( subWindow.attachEvent ) {
+ subWindow.attachEvent( "onunload", unloadHandler );
+ }
+ }
+
+ /* Attributes
+ ---------------------------------------------------------------------- */
+
+ // Support: IE<8
+ // Verify that getAttribute really returns attributes and not properties
+ // (excepting IE8 booleans)
+ support.attributes = assert(function( el ) {
+ el.className = "i";
+ return !el.getAttribute("className");
+ });
+
+ /* getElement(s)By*
+ ---------------------------------------------------------------------- */
+
+ // Check if getElementsByTagName("*") returns only elements
+ support.getElementsByTagName = assert(function( el ) {
+ el.appendChild( document.createComment("") );
+ return !el.getElementsByTagName("*").length;
+ });
+
+ // Support: IE<9
+ support.getElementsByClassName = rnative.test( document.getElementsByClassName );
+
+ // Support: IE<10
+ // Check if getElementById returns elements by name
+ // The broken getElementById methods don't pick up programmatically-set names,
+ // so use a roundabout getElementsByName test
+ support.getById = assert(function( el ) {
+ docElem.appendChild( el ).id = expando;
+ return !document.getElementsByName || !document.getElementsByName( expando ).length;
+ });
+
+ // ID filter and find
+ if ( support.getById ) {
+ Expr.filter["ID"] = function( id ) {
+ var attrId = id.replace( runescape, funescape );
+ return function( elem ) {
+ return elem.getAttribute("id") === attrId;
+ };
+ };
+ Expr.find["ID"] = function( id, context ) {
+ if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+ var elem = context.getElementById( id );
+ return elem ? [ elem ] : [];
+ }
+ };
+ } else {
+ Expr.filter["ID"] = function( id ) {
+ var attrId = id.replace( runescape, funescape );
+ return function( elem ) {
+ var node = typeof elem.getAttributeNode !== "undefined" &&
+ elem.getAttributeNode("id");
+ return node && node.value === attrId;
+ };
+ };
+
+ // Support: IE 6 - 7 only
+ // getElementById is not reliable as a find shortcut
+ Expr.find["ID"] = function( id, context ) {
+ if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+ var node, i, elems,
+ elem = context.getElementById( id );
+
+ if ( elem ) {
+
+ // Verify the id attribute
+ node = elem.getAttributeNode("id");
+ if ( node && node.value === id ) {
+ return [ elem ];
+ }
+
+ // Fall back on getElementsByName
+ elems = context.getElementsByName( id );
+ i = 0;
+ while ( (elem = elems[i++]) ) {
+ node = elem.getAttributeNode("id");
+ if ( node && node.value === id ) {
+ return [ elem ];
+ }
+ }
+ }
+
+ return [];
+ }
+ };
+ }
+
+ // Tag
+ Expr.find["TAG"] = support.getElementsByTagName ?
+ function( tag, context ) {
+ if ( typeof context.getElementsByTagName !== "undefined" ) {
+ return context.getElementsByTagName( tag );
+
+ // DocumentFragment nodes don't have gEBTN
+ } else if ( support.qsa ) {
+ return context.querySelectorAll( tag );
+ }
+ } :
+
+ function( tag, context ) {
+ var elem,
+ tmp = [],
+ i = 0,
+ // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
+ results = context.getElementsByTagName( tag );
+
+ // Filter out possible comments
+ if ( tag === "*" ) {
+ while ( (elem = results[i++]) ) {
+ if ( elem.nodeType === 1 ) {
+ tmp.push( elem );
+ }
+ }
+
+ return tmp;
+ }
+ return results;
+ };
+
+ // Class
+ Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
+ if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
+ return context.getElementsByClassName( className );
+ }
+ };
+
+ /* QSA/matchesSelector
+ ---------------------------------------------------------------------- */
+
+ // QSA and matchesSelector support
+
+ // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+ rbuggyMatches = [];
+
+ // qSa(:focus) reports false when true (Chrome 21)
+ // We allow this because of a bug in IE8/9 that throws an error
+ // whenever `document.activeElement` is accessed on an iframe
+ // So, we allow :focus to pass through QSA all the time to avoid the IE error
+ // See https://bugs.jquery.com/ticket/13378
+ rbuggyQSA = [];
+
+ if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
+ // Build QSA regex
+ // Regex strategy adopted from Diego Perini
+ assert(function( el ) {
+ // Select is set to empty string on purpose
+ // This is to test IE's treatment of not explicitly
+ // setting a boolean content attribute,
+ // since its presence should be enough
+ // https://bugs.jquery.com/ticket/12359
+ docElem.appendChild( el ).innerHTML = " " +
+ "" +
+ " ";
+
+ // Support: IE8, Opera 11-12.16
+ // Nothing should be selected when empty strings follow ^= or $= or *=
+ // The test attribute must be unknown in Opera but "safe" for WinRT
+ // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
+ if ( el.querySelectorAll("[msallowcapture^='']").length ) {
+ rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
+ }
+
+ // Support: IE8
+ // Boolean attributes and "value" are not treated correctly
+ if ( !el.querySelectorAll("[selected]").length ) {
+ rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
+ }
+
+ // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
+ if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
+ rbuggyQSA.push("~=");
+ }
+
+ // Webkit/Opera - :checked should return selected option elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ // IE8 throws error here and will not see later tests
+ if ( !el.querySelectorAll(":checked").length ) {
+ rbuggyQSA.push(":checked");
+ }
+
+ // Support: Safari 8+, iOS 8+
+ // https://bugs.webkit.org/show_bug.cgi?id=136851
+ // In-page `selector#id sibling-combinator selector` fails
+ if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
+ rbuggyQSA.push(".#.+[+~]");
+ }
+ });
+
+ assert(function( el ) {
+ el.innerHTML = " " +
+ " ";
+
+ // Support: Windows 8 Native Apps
+ // The type and name attributes are restricted during .innerHTML assignment
+ var input = document.createElement("input");
+ input.setAttribute( "type", "hidden" );
+ el.appendChild( input ).setAttribute( "name", "D" );
+
+ // Support: IE8
+ // Enforce case-sensitivity of name attribute
+ if ( el.querySelectorAll("[name=d]").length ) {
+ rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
+ }
+
+ // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+ // IE8 throws error here and will not see later tests
+ if ( el.querySelectorAll(":enabled").length !== 2 ) {
+ rbuggyQSA.push( ":enabled", ":disabled" );
+ }
+
+ // Support: IE9-11+
+ // IE's :disabled selector does not pick up the children of disabled fieldsets
+ docElem.appendChild( el ).disabled = true;
+ if ( el.querySelectorAll(":disabled").length !== 2 ) {
+ rbuggyQSA.push( ":enabled", ":disabled" );
+ }
+
+ // Opera 10-11 does not throw on post-comma invalid pseudos
+ el.querySelectorAll("*,:x");
+ rbuggyQSA.push(",.*:");
+ });
+ }
+
+ if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
+ docElem.webkitMatchesSelector ||
+ docElem.mozMatchesSelector ||
+ docElem.oMatchesSelector ||
+ docElem.msMatchesSelector) )) ) {
+
+ assert(function( el ) {
+ // Check to see if it's possible to do matchesSelector
+ // on a disconnected node (IE 9)
+ support.disconnectedMatch = matches.call( el, "*" );
+
+ // This should fail with an exception
+ // Gecko does not error, returns false instead
+ matches.call( el, "[s!='']:x" );
+ rbuggyMatches.push( "!=", pseudos );
+ });
+ }
+
+ rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
+ rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
+
+ /* Contains
+ ---------------------------------------------------------------------- */
+ hasCompare = rnative.test( docElem.compareDocumentPosition );
+
+ // Element contains another
+ // Purposefully self-exclusive
+ // As in, an element does not contain itself
+ contains = hasCompare || rnative.test( docElem.contains ) ?
+ function( a, b ) {
+ var adown = a.nodeType === 9 ? a.documentElement : a,
+ bup = b && b.parentNode;
+ return a === bup || !!( bup && bup.nodeType === 1 && (
+ adown.contains ?
+ adown.contains( bup ) :
+ a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
+ ));
+ } :
+ function( a, b ) {
+ if ( b ) {
+ while ( (b = b.parentNode) ) {
+ if ( b === a ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+
+ /* Sorting
+ ---------------------------------------------------------------------- */
+
+ // Document order sorting
+ sortOrder = hasCompare ?
+ function( a, b ) {
+
+ // Flag for duplicate removal
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ // Sort on method existence if only one input has compareDocumentPosition
+ var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
+ if ( compare ) {
+ return compare;
+ }
+
+ // Calculate position if both inputs belong to the same document
+ compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
+ a.compareDocumentPosition( b ) :
+
+ // Otherwise we know they are disconnected
+ 1;
+
+ // Disconnected nodes
+ if ( compare & 1 ||
+ (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
+
+ // Choose the first element that is related to our preferred document
+ if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
+ return -1;
+ }
+ if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
+ return 1;
+ }
+
+ // Maintain original order
+ return sortInput ?
+ ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
+ 0;
+ }
+
+ return compare & 4 ? -1 : 1;
+ } :
+ function( a, b ) {
+ // Exit early if the nodes are identical
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ var cur,
+ i = 0,
+ aup = a.parentNode,
+ bup = b.parentNode,
+ ap = [ a ],
+ bp = [ b ];
+
+ // Parentless nodes are either documents or disconnected
+ if ( !aup || !bup ) {
+ return a === document ? -1 :
+ b === document ? 1 :
+ aup ? -1 :
+ bup ? 1 :
+ sortInput ?
+ ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
+ 0;
+
+ // If the nodes are siblings, we can do a quick check
+ } else if ( aup === bup ) {
+ return siblingCheck( a, b );
+ }
+
+ // Otherwise we need full lists of their ancestors for comparison
+ cur = a;
+ while ( (cur = cur.parentNode) ) {
+ ap.unshift( cur );
+ }
+ cur = b;
+ while ( (cur = cur.parentNode) ) {
+ bp.unshift( cur );
+ }
+
+ // Walk down the tree looking for a discrepancy
+ while ( ap[i] === bp[i] ) {
+ i++;
+ }
+
+ return i ?
+ // Do a sibling check if the nodes have a common ancestor
+ siblingCheck( ap[i], bp[i] ) :
+
+ // Otherwise nodes in our document sort first
+ ap[i] === preferredDoc ? -1 :
+ bp[i] === preferredDoc ? 1 :
+ 0;
+ };
+
+ return document;
+};
+
+Sizzle.matches = function( expr, elements ) {
+ return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+ // Set document vars if needed
+ if ( ( elem.ownerDocument || elem ) !== document ) {
+ setDocument( elem );
+ }
+
+ // Make sure that attribute selectors are quoted
+ expr = expr.replace( rattributeQuotes, "='$1']" );
+
+ if ( support.matchesSelector && documentIsHTML &&
+ !compilerCache[ expr + " " ] &&
+ ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
+ ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
+
+ try {
+ var ret = matches.call( elem, expr );
+
+ // IE 9's matchesSelector returns false on disconnected nodes
+ if ( ret || support.disconnectedMatch ||
+ // As well, disconnected nodes are said to be in a document
+ // fragment in IE 9
+ elem.document && elem.document.nodeType !== 11 ) {
+ return ret;
+ }
+ } catch (e) {}
+ }
+
+ return Sizzle( expr, document, null, [ elem ] ).length > 0;
+};
+
+Sizzle.contains = function( context, elem ) {
+ // Set document vars if needed
+ if ( ( context.ownerDocument || context ) !== document ) {
+ setDocument( context );
+ }
+ return contains( context, elem );
+};
+
+Sizzle.attr = function( elem, name ) {
+ // Set document vars if needed
+ if ( ( elem.ownerDocument || elem ) !== document ) {
+ setDocument( elem );
+ }
+
+ var fn = Expr.attrHandle[ name.toLowerCase() ],
+ // Don't get fooled by Object.prototype properties (jQuery #13807)
+ val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
+ fn( elem, name, !documentIsHTML ) :
+ undefined;
+
+ return val !== undefined ?
+ val :
+ support.attributes || !documentIsHTML ?
+ elem.getAttribute( name ) :
+ (val = elem.getAttributeNode(name)) && val.specified ?
+ val.value :
+ null;
+};
+
+Sizzle.escape = function( sel ) {
+ return (sel + "").replace( rcssescape, fcssescape );
+};
+
+Sizzle.error = function( msg ) {
+ throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+/**
+ * Document sorting and removing duplicates
+ * @param {ArrayLike} results
+ */
+Sizzle.uniqueSort = function( results ) {
+ var elem,
+ duplicates = [],
+ j = 0,
+ i = 0;
+
+ // Unless we *know* we can detect duplicates, assume their presence
+ hasDuplicate = !support.detectDuplicates;
+ sortInput = !support.sortStable && results.slice( 0 );
+ results.sort( sortOrder );
+
+ if ( hasDuplicate ) {
+ while ( (elem = results[i++]) ) {
+ if ( elem === results[ i ] ) {
+ j = duplicates.push( i );
+ }
+ }
+ while ( j-- ) {
+ results.splice( duplicates[ j ], 1 );
+ }
+ }
+
+ // Clear input after sorting to release objects
+ // See https://github.com/jquery/sizzle/pull/225
+ sortInput = null;
+
+ return results;
+};
+
+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+getText = Sizzle.getText = function( elem ) {
+ var node,
+ ret = "",
+ i = 0,
+ nodeType = elem.nodeType;
+
+ if ( !nodeType ) {
+ // If no nodeType, this is expected to be an array
+ while ( (node = elem[i++]) ) {
+ // Do not traverse comment nodes
+ ret += getText( node );
+ }
+ } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+ // Use textContent for elements
+ // innerText usage removed for consistency of new lines (jQuery #11153)
+ if ( typeof elem.textContent === "string" ) {
+ return elem.textContent;
+ } else {
+ // Traverse its children
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+ ret += getText( elem );
+ }
+ }
+ } else if ( nodeType === 3 || nodeType === 4 ) {
+ return elem.nodeValue;
+ }
+ // Do not include comment or processing instruction nodes
+
+ return ret;
+};
+
+Expr = Sizzle.selectors = {
+
+ // Can be adjusted by the user
+ cacheLength: 50,
+
+ createPseudo: markFunction,
+
+ match: matchExpr,
+
+ attrHandle: {},
+
+ find: {},
+
+ relative: {
+ ">": { dir: "parentNode", first: true },
+ " ": { dir: "parentNode" },
+ "+": { dir: "previousSibling", first: true },
+ "~": { dir: "previousSibling" }
+ },
+
+ preFilter: {
+ "ATTR": function( match ) {
+ match[1] = match[1].replace( runescape, funescape );
+
+ // Move the given value to match[3] whether quoted or unquoted
+ match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
+
+ if ( match[2] === "~=" ) {
+ match[3] = " " + match[3] + " ";
+ }
+
+ return match.slice( 0, 4 );
+ },
+
+ "CHILD": function( match ) {
+ /* matches from matchExpr["CHILD"]
+ 1 type (only|nth|...)
+ 2 what (child|of-type)
+ 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+ 4 xn-component of xn+y argument ([+-]?\d*n|)
+ 5 sign of xn-component
+ 6 x of xn-component
+ 7 sign of y-component
+ 8 y of y-component
+ */
+ match[1] = match[1].toLowerCase();
+
+ if ( match[1].slice( 0, 3 ) === "nth" ) {
+ // nth-* requires argument
+ if ( !match[3] ) {
+ Sizzle.error( match[0] );
+ }
+
+ // numeric x and y parameters for Expr.filter.CHILD
+ // remember that false/true cast respectively to 0/1
+ match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
+ match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
+
+ // other types prohibit arguments
+ } else if ( match[3] ) {
+ Sizzle.error( match[0] );
+ }
+
+ return match;
+ },
+
+ "PSEUDO": function( match ) {
+ var excess,
+ unquoted = !match[6] && match[2];
+
+ if ( matchExpr["CHILD"].test( match[0] ) ) {
+ return null;
+ }
+
+ // Accept quoted arguments as-is
+ if ( match[3] ) {
+ match[2] = match[4] || match[5] || "";
+
+ // Strip excess characters from unquoted arguments
+ } else if ( unquoted && rpseudo.test( unquoted ) &&
+ // Get excess from tokenize (recursively)
+ (excess = tokenize( unquoted, true )) &&
+ // advance to the next closing parenthesis
+ (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
+
+ // excess is a negative index
+ match[0] = match[0].slice( 0, excess );
+ match[2] = unquoted.slice( 0, excess );
+ }
+
+ // Return only captures needed by the pseudo filter method (type and argument)
+ return match.slice( 0, 3 );
+ }
+ },
+
+ filter: {
+
+ "TAG": function( nodeNameSelector ) {
+ var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
+ return nodeNameSelector === "*" ?
+ function() { return true; } :
+ function( elem ) {
+ return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+ };
+ },
+
+ "CLASS": function( className ) {
+ var pattern = classCache[ className + " " ];
+
+ return pattern ||
+ (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
+ classCache( className, function( elem ) {
+ return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
+ });
+ },
+
+ "ATTR": function( name, operator, check ) {
+ return function( elem ) {
+ var result = Sizzle.attr( elem, name );
+
+ if ( result == null ) {
+ return operator === "!=";
+ }
+ if ( !operator ) {
+ return true;
+ }
+
+ result += "";
+
+ return operator === "=" ? result === check :
+ operator === "!=" ? result !== check :
+ operator === "^=" ? check && result.indexOf( check ) === 0 :
+ operator === "*=" ? check && result.indexOf( check ) > -1 :
+ operator === "$=" ? check && result.slice( -check.length ) === check :
+ operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
+ operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
+ false;
+ };
+ },
+
+ "CHILD": function( type, what, argument, first, last ) {
+ var simple = type.slice( 0, 3 ) !== "nth",
+ forward = type.slice( -4 ) !== "last",
+ ofType = what === "of-type";
+
+ return first === 1 && last === 0 ?
+
+ // Shortcut for :nth-*(n)
+ function( elem ) {
+ return !!elem.parentNode;
+ } :
+
+ function( elem, context, xml ) {
+ var cache, uniqueCache, outerCache, node, nodeIndex, start,
+ dir = simple !== forward ? "nextSibling" : "previousSibling",
+ parent = elem.parentNode,
+ name = ofType && elem.nodeName.toLowerCase(),
+ useCache = !xml && !ofType,
+ diff = false;
+
+ if ( parent ) {
+
+ // :(first|last|only)-(child|of-type)
+ if ( simple ) {
+ while ( dir ) {
+ node = elem;
+ while ( (node = node[ dir ]) ) {
+ if ( ofType ?
+ node.nodeName.toLowerCase() === name :
+ node.nodeType === 1 ) {
+
+ return false;
+ }
+ }
+ // Reverse direction for :only-* (if we haven't yet done so)
+ start = dir = type === "only" && !start && "nextSibling";
+ }
+ return true;
+ }
+
+ start = [ forward ? parent.firstChild : parent.lastChild ];
+
+ // non-xml :nth-child(...) stores cache data on `parent`
+ if ( forward && useCache ) {
+
+ // Seek `elem` from a previously-cached index
+
+ // ...in a gzip-friendly way
+ node = parent;
+ outerCache = node[ expando ] || (node[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ (outerCache[ node.uniqueID ] = {});
+
+ cache = uniqueCache[ type ] || [];
+ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+ diff = nodeIndex && cache[ 2 ];
+ node = nodeIndex && parent.childNodes[ nodeIndex ];
+
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
+
+ // Fallback to seeking `elem` from the start
+ (diff = nodeIndex = 0) || start.pop()) ) {
+
+ // When found, cache indexes on `parent` and break
+ if ( node.nodeType === 1 && ++diff && node === elem ) {
+ uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
+ break;
+ }
+ }
+
+ } else {
+ // Use previously-cached element index if available
+ if ( useCache ) {
+ // ...in a gzip-friendly way
+ node = elem;
+ outerCache = node[ expando ] || (node[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ (outerCache[ node.uniqueID ] = {});
+
+ cache = uniqueCache[ type ] || [];
+ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+ diff = nodeIndex;
+ }
+
+ // xml :nth-child(...)
+ // or :nth-last-child(...) or :nth(-last)?-of-type(...)
+ if ( diff === false ) {
+ // Use the same loop as above to seek `elem` from the start
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
+ (diff = nodeIndex = 0) || start.pop()) ) {
+
+ if ( ( ofType ?
+ node.nodeName.toLowerCase() === name :
+ node.nodeType === 1 ) &&
+ ++diff ) {
+
+ // Cache the index of each encountered element
+ if ( useCache ) {
+ outerCache = node[ expando ] || (node[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ (outerCache[ node.uniqueID ] = {});
+
+ uniqueCache[ type ] = [ dirruns, diff ];
+ }
+
+ if ( node === elem ) {
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Incorporate the offset, then check against cycle size
+ diff -= last;
+ return diff === first || ( diff % first === 0 && diff / first >= 0 );
+ }
+ };
+ },
+
+ "PSEUDO": function( pseudo, argument ) {
+ // pseudo-class names are case-insensitive
+ // http://www.w3.org/TR/selectors/#pseudo-classes
+ // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+ // Remember that setFilters inherits from pseudos
+ var args,
+ fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
+ Sizzle.error( "unsupported pseudo: " + pseudo );
+
+ // The user may use createPseudo to indicate that
+ // arguments are needed to create the filter function
+ // just as Sizzle does
+ if ( fn[ expando ] ) {
+ return fn( argument );
+ }
+
+ // But maintain support for old signatures
+ if ( fn.length > 1 ) {
+ args = [ pseudo, pseudo, "", argument ];
+ return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+ markFunction(function( seed, matches ) {
+ var idx,
+ matched = fn( seed, argument ),
+ i = matched.length;
+ while ( i-- ) {
+ idx = indexOf( seed, matched[i] );
+ seed[ idx ] = !( matches[ idx ] = matched[i] );
+ }
+ }) :
+ function( elem ) {
+ return fn( elem, 0, args );
+ };
+ }
+
+ return fn;
+ }
+ },
+
+ pseudos: {
+ // Potentially complex pseudos
+ "not": markFunction(function( selector ) {
+ // Trim the selector passed to compile
+ // to avoid treating leading and trailing
+ // spaces as combinators
+ var input = [],
+ results = [],
+ matcher = compile( selector.replace( rtrim, "$1" ) );
+
+ return matcher[ expando ] ?
+ markFunction(function( seed, matches, context, xml ) {
+ var elem,
+ unmatched = matcher( seed, null, xml, [] ),
+ i = seed.length;
+
+ // Match elements unmatched by `matcher`
+ while ( i-- ) {
+ if ( (elem = unmatched[i]) ) {
+ seed[i] = !(matches[i] = elem);
+ }
+ }
+ }) :
+ function( elem, context, xml ) {
+ input[0] = elem;
+ matcher( input, null, xml, results );
+ // Don't keep the element (issue #299)
+ input[0] = null;
+ return !results.pop();
+ };
+ }),
+
+ "has": markFunction(function( selector ) {
+ return function( elem ) {
+ return Sizzle( selector, elem ).length > 0;
+ };
+ }),
+
+ "contains": markFunction(function( text ) {
+ text = text.replace( runescape, funescape );
+ return function( elem ) {
+ return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
+ };
+ }),
+
+ // "Whether an element is represented by a :lang() selector
+ // is based solely on the element's language value
+ // being equal to the identifier C,
+ // or beginning with the identifier C immediately followed by "-".
+ // The matching of C against the element's language value is performed case-insensitively.
+ // The identifier C does not have to be a valid language name."
+ // http://www.w3.org/TR/selectors/#lang-pseudo
+ "lang": markFunction( function( lang ) {
+ // lang value must be a valid identifier
+ if ( !ridentifier.test(lang || "") ) {
+ Sizzle.error( "unsupported lang: " + lang );
+ }
+ lang = lang.replace( runescape, funescape ).toLowerCase();
+ return function( elem ) {
+ var elemLang;
+ do {
+ if ( (elemLang = documentIsHTML ?
+ elem.lang :
+ elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
+
+ elemLang = elemLang.toLowerCase();
+ return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
+ }
+ } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
+ return false;
+ };
+ }),
+
+ // Miscellaneous
+ "target": function( elem ) {
+ var hash = window.location && window.location.hash;
+ return hash && hash.slice( 1 ) === elem.id;
+ },
+
+ "root": function( elem ) {
+ return elem === docElem;
+ },
+
+ "focus": function( elem ) {
+ return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
+ },
+
+ // Boolean properties
+ "enabled": createDisabledPseudo( false ),
+ "disabled": createDisabledPseudo( true ),
+
+ "checked": function( elem ) {
+ // In CSS3, :checked should return both checked and selected elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ var nodeName = elem.nodeName.toLowerCase();
+ return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+ },
+
+ "selected": function( elem ) {
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ if ( elem.parentNode ) {
+ elem.parentNode.selectedIndex;
+ }
+
+ return elem.selected === true;
+ },
+
+ // Contents
+ "empty": function( elem ) {
+ // http://www.w3.org/TR/selectors/#empty-pseudo
+ // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
+ // but not by others (comment: 8; processing instruction: 7; etc.)
+ // nodeType < 6 works because attributes (2) do not appear as children
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+ if ( elem.nodeType < 6 ) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ "parent": function( elem ) {
+ return !Expr.pseudos["empty"]( elem );
+ },
+
+ // Element/input types
+ "header": function( elem ) {
+ return rheader.test( elem.nodeName );
+ },
+
+ "input": function( elem ) {
+ return rinputs.test( elem.nodeName );
+ },
+
+ "button": function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === "button" || name === "button";
+ },
+
+ "text": function( elem ) {
+ var attr;
+ return elem.nodeName.toLowerCase() === "input" &&
+ elem.type === "text" &&
+
+ // Support: IE<8
+ // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
+ ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
+ },
+
+ // Position-in-collection
+ "first": createPositionalPseudo(function() {
+ return [ 0 ];
+ }),
+
+ "last": createPositionalPseudo(function( matchIndexes, length ) {
+ return [ length - 1 ];
+ }),
+
+ "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ return [ argument < 0 ? argument + length : argument ];
+ }),
+
+ "even": createPositionalPseudo(function( matchIndexes, length ) {
+ var i = 0;
+ for ( ; i < length; i += 2 ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "odd": createPositionalPseudo(function( matchIndexes, length ) {
+ var i = 1;
+ for ( ; i < length; i += 2 ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ var i = argument < 0 ? argument + length : argument;
+ for ( ; --i >= 0; ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ var i = argument < 0 ? argument + length : argument;
+ for ( ; ++i < length; ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ })
+ }
+};
+
+Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+// Add button/input type pseudos
+for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
+ Expr.pseudos[ i ] = createInputPseudo( i );
+}
+for ( i in { submit: true, reset: true } ) {
+ Expr.pseudos[ i ] = createButtonPseudo( i );
+}
+
+// Easy API for creating new setFilters
+function setFilters() {}
+setFilters.prototype = Expr.filters = Expr.pseudos;
+Expr.setFilters = new setFilters();
+
+tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
+ var matched, match, tokens, type,
+ soFar, groups, preFilters,
+ cached = tokenCache[ selector + " " ];
+
+ if ( cached ) {
+ return parseOnly ? 0 : cached.slice( 0 );
+ }
+
+ soFar = selector;
+ groups = [];
+ preFilters = Expr.preFilter;
+
+ while ( soFar ) {
+
+ // Comma and first run
+ if ( !matched || (match = rcomma.exec( soFar )) ) {
+ if ( match ) {
+ // Don't consume trailing commas as valid
+ soFar = soFar.slice( match[0].length ) || soFar;
+ }
+ groups.push( (tokens = []) );
+ }
+
+ matched = false;
+
+ // Combinators
+ if ( (match = rcombinators.exec( soFar )) ) {
+ matched = match.shift();
+ tokens.push({
+ value: matched,
+ // Cast descendant combinators to space
+ type: match[0].replace( rtrim, " " )
+ });
+ soFar = soFar.slice( matched.length );
+ }
+
+ // Filters
+ for ( type in Expr.filter ) {
+ if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+ (match = preFilters[ type ]( match ))) ) {
+ matched = match.shift();
+ tokens.push({
+ value: matched,
+ type: type,
+ matches: match
+ });
+ soFar = soFar.slice( matched.length );
+ }
+ }
+
+ if ( !matched ) {
+ break;
+ }
+ }
+
+ // Return the length of the invalid excess
+ // if we're just parsing
+ // Otherwise, throw an error or return tokens
+ return parseOnly ?
+ soFar.length :
+ soFar ?
+ Sizzle.error( selector ) :
+ // Cache the tokens
+ tokenCache( selector, groups ).slice( 0 );
+};
+
+function toSelector( tokens ) {
+ var i = 0,
+ len = tokens.length,
+ selector = "";
+ for ( ; i < len; i++ ) {
+ selector += tokens[i].value;
+ }
+ return selector;
+}
+
+function addCombinator( matcher, combinator, base ) {
+ var dir = combinator.dir,
+ skip = combinator.next,
+ key = skip || dir,
+ checkNonElements = base && key === "parentNode",
+ doneName = done++;
+
+ return combinator.first ?
+ // Check against closest ancestor/preceding element
+ function( elem, context, xml ) {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ return matcher( elem, context, xml );
+ }
+ }
+ return false;
+ } :
+
+ // Check against all ancestor/preceding elements
+ function( elem, context, xml ) {
+ var oldCache, uniqueCache, outerCache,
+ newCache = [ dirruns, doneName ];
+
+ // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
+ if ( xml ) {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ if ( matcher( elem, context, xml ) ) {
+ return true;
+ }
+ }
+ }
+ } else {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ outerCache = elem[ expando ] || (elem[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
+
+ if ( skip && skip === elem.nodeName.toLowerCase() ) {
+ elem = elem[ dir ] || elem;
+ } else if ( (oldCache = uniqueCache[ key ]) &&
+ oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
+
+ // Assign to newCache so results back-propagate to previous elements
+ return (newCache[ 2 ] = oldCache[ 2 ]);
+ } else {
+ // Reuse newcache so results back-propagate to previous elements
+ uniqueCache[ key ] = newCache;
+
+ // A match means we're done; a fail means we have to keep checking
+ if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ };
+}
+
+function elementMatcher( matchers ) {
+ return matchers.length > 1 ?
+ function( elem, context, xml ) {
+ var i = matchers.length;
+ while ( i-- ) {
+ if ( !matchers[i]( elem, context, xml ) ) {
+ return false;
+ }
+ }
+ return true;
+ } :
+ matchers[0];
+}
+
+function multipleContexts( selector, contexts, results ) {
+ var i = 0,
+ len = contexts.length;
+ for ( ; i < len; i++ ) {
+ Sizzle( selector, contexts[i], results );
+ }
+ return results;
+}
+
+function condense( unmatched, map, filter, context, xml ) {
+ var elem,
+ newUnmatched = [],
+ i = 0,
+ len = unmatched.length,
+ mapped = map != null;
+
+ for ( ; i < len; i++ ) {
+ if ( (elem = unmatched[i]) ) {
+ if ( !filter || filter( elem, context, xml ) ) {
+ newUnmatched.push( elem );
+ if ( mapped ) {
+ map.push( i );
+ }
+ }
+ }
+ }
+
+ return newUnmatched;
+}
+
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+ if ( postFilter && !postFilter[ expando ] ) {
+ postFilter = setMatcher( postFilter );
+ }
+ if ( postFinder && !postFinder[ expando ] ) {
+ postFinder = setMatcher( postFinder, postSelector );
+ }
+ return markFunction(function( seed, results, context, xml ) {
+ var temp, i, elem,
+ preMap = [],
+ postMap = [],
+ preexisting = results.length,
+
+ // Get initial elements from seed or context
+ elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
+
+ // Prefilter to get matcher input, preserving a map for seed-results synchronization
+ matcherIn = preFilter && ( seed || !selector ) ?
+ condense( elems, preMap, preFilter, context, xml ) :
+ elems,
+
+ matcherOut = matcher ?
+ // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
+ postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
+
+ // ...intermediate processing is necessary
+ [] :
+
+ // ...otherwise use results directly
+ results :
+ matcherIn;
+
+ // Find primary matches
+ if ( matcher ) {
+ matcher( matcherIn, matcherOut, context, xml );
+ }
+
+ // Apply postFilter
+ if ( postFilter ) {
+ temp = condense( matcherOut, postMap );
+ postFilter( temp, [], context, xml );
+
+ // Un-match failing elements by moving them back to matcherIn
+ i = temp.length;
+ while ( i-- ) {
+ if ( (elem = temp[i]) ) {
+ matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
+ }
+ }
+ }
+
+ if ( seed ) {
+ if ( postFinder || preFilter ) {
+ if ( postFinder ) {
+ // Get the final matcherOut by condensing this intermediate into postFinder contexts
+ temp = [];
+ i = matcherOut.length;
+ while ( i-- ) {
+ if ( (elem = matcherOut[i]) ) {
+ // Restore matcherIn since elem is not yet a final match
+ temp.push( (matcherIn[i] = elem) );
+ }
+ }
+ postFinder( null, (matcherOut = []), temp, xml );
+ }
+
+ // Move matched elements from seed to results to keep them synchronized
+ i = matcherOut.length;
+ while ( i-- ) {
+ if ( (elem = matcherOut[i]) &&
+ (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
+
+ seed[temp] = !(results[temp] = elem);
+ }
+ }
+ }
+
+ // Add elements to results, through postFinder if defined
+ } else {
+ matcherOut = condense(
+ matcherOut === results ?
+ matcherOut.splice( preexisting, matcherOut.length ) :
+ matcherOut
+ );
+ if ( postFinder ) {
+ postFinder( null, results, matcherOut, xml );
+ } else {
+ push.apply( results, matcherOut );
+ }
+ }
+ });
+}
+
+function matcherFromTokens( tokens ) {
+ var checkContext, matcher, j,
+ len = tokens.length,
+ leadingRelative = Expr.relative[ tokens[0].type ],
+ implicitRelative = leadingRelative || Expr.relative[" "],
+ i = leadingRelative ? 1 : 0,
+
+ // The foundational matcher ensures that elements are reachable from top-level context(s)
+ matchContext = addCombinator( function( elem ) {
+ return elem === checkContext;
+ }, implicitRelative, true ),
+ matchAnyContext = addCombinator( function( elem ) {
+ return indexOf( checkContext, elem ) > -1;
+ }, implicitRelative, true ),
+ matchers = [ function( elem, context, xml ) {
+ var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+ (checkContext = context).nodeType ?
+ matchContext( elem, context, xml ) :
+ matchAnyContext( elem, context, xml ) );
+ // Avoid hanging onto element (issue #299)
+ checkContext = null;
+ return ret;
+ } ];
+
+ for ( ; i < len; i++ ) {
+ if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
+ matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
+ } else {
+ matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
+
+ // Return special upon seeing a positional matcher
+ if ( matcher[ expando ] ) {
+ // Find the next relative operator (if any) for proper handling
+ j = ++i;
+ for ( ; j < len; j++ ) {
+ if ( Expr.relative[ tokens[j].type ] ) {
+ break;
+ }
+ }
+ return setMatcher(
+ i > 1 && elementMatcher( matchers ),
+ i > 1 && toSelector(
+ // If the preceding token was a descendant combinator, insert an implicit any-element `*`
+ tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
+ ).replace( rtrim, "$1" ),
+ matcher,
+ i < j && matcherFromTokens( tokens.slice( i, j ) ),
+ j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
+ j < len && toSelector( tokens )
+ );
+ }
+ matchers.push( matcher );
+ }
+ }
+
+ return elementMatcher( matchers );
+}
+
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+ var bySet = setMatchers.length > 0,
+ byElement = elementMatchers.length > 0,
+ superMatcher = function( seed, context, xml, results, outermost ) {
+ var elem, j, matcher,
+ matchedCount = 0,
+ i = "0",
+ unmatched = seed && [],
+ setMatched = [],
+ contextBackup = outermostContext,
+ // We must always have either seed elements or outermost context
+ elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
+ // Use integer dirruns iff this is the outermost matcher
+ dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
+ len = elems.length;
+
+ if ( outermost ) {
+ outermostContext = context === document || context || outermost;
+ }
+
+ // Add elements passing elementMatchers directly to results
+ // Support: IE<9, Safari
+ // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id
+ for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
+ if ( byElement && elem ) {
+ j = 0;
+ if ( !context && elem.ownerDocument !== document ) {
+ setDocument( elem );
+ xml = !documentIsHTML;
+ }
+ while ( (matcher = elementMatchers[j++]) ) {
+ if ( matcher( elem, context || document, xml) ) {
+ results.push( elem );
+ break;
+ }
+ }
+ if ( outermost ) {
+ dirruns = dirrunsUnique;
+ }
+ }
+
+ // Track unmatched elements for set filters
+ if ( bySet ) {
+ // They will have gone through all possible matchers
+ if ( (elem = !matcher && elem) ) {
+ matchedCount--;
+ }
+
+ // Lengthen the array for every element, matched or not
+ if ( seed ) {
+ unmatched.push( elem );
+ }
+ }
+ }
+
+ // `i` is now the count of elements visited above, and adding it to `matchedCount`
+ // makes the latter nonnegative.
+ matchedCount += i;
+
+ // Apply set filters to unmatched elements
+ // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
+ // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
+ // no element matchers and no seed.
+ // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
+ // case, which will result in a "00" `matchedCount` that differs from `i` but is also
+ // numerically zero.
+ if ( bySet && i !== matchedCount ) {
+ j = 0;
+ while ( (matcher = setMatchers[j++]) ) {
+ matcher( unmatched, setMatched, context, xml );
+ }
+
+ if ( seed ) {
+ // Reintegrate element matches to eliminate the need for sorting
+ if ( matchedCount > 0 ) {
+ while ( i-- ) {
+ if ( !(unmatched[i] || setMatched[i]) ) {
+ setMatched[i] = pop.call( results );
+ }
+ }
+ }
+
+ // Discard index placeholder values to get only actual matches
+ setMatched = condense( setMatched );
+ }
+
+ // Add matches to results
+ push.apply( results, setMatched );
+
+ // Seedless set matches succeeding multiple successful matchers stipulate sorting
+ if ( outermost && !seed && setMatched.length > 0 &&
+ ( matchedCount + setMatchers.length ) > 1 ) {
+
+ Sizzle.uniqueSort( results );
+ }
+ }
+
+ // Override manipulation of globals by nested matchers
+ if ( outermost ) {
+ dirruns = dirrunsUnique;
+ outermostContext = contextBackup;
+ }
+
+ return unmatched;
+ };
+
+ return bySet ?
+ markFunction( superMatcher ) :
+ superMatcher;
+}
+
+compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
+ var i,
+ setMatchers = [],
+ elementMatchers = [],
+ cached = compilerCache[ selector + " " ];
+
+ if ( !cached ) {
+ // Generate a function of recursive functions that can be used to check each element
+ if ( !match ) {
+ match = tokenize( selector );
+ }
+ i = match.length;
+ while ( i-- ) {
+ cached = matcherFromTokens( match[i] );
+ if ( cached[ expando ] ) {
+ setMatchers.push( cached );
+ } else {
+ elementMatchers.push( cached );
+ }
+ }
+
+ // Cache the compiled function
+ cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
+
+ // Save selector and tokenization
+ cached.selector = selector;
+ }
+ return cached;
+};
+
+/**
+ * A low-level selection function that works with Sizzle's compiled
+ * selector functions
+ * @param {String|Function} selector A selector or a pre-compiled
+ * selector function built with Sizzle.compile
+ * @param {Element} context
+ * @param {Array} [results]
+ * @param {Array} [seed] A set of elements to match against
+ */
+select = Sizzle.select = function( selector, context, results, seed ) {
+ var i, tokens, token, type, find,
+ compiled = typeof selector === "function" && selector,
+ match = !seed && tokenize( (selector = compiled.selector || selector) );
+
+ results = results || [];
+
+ // Try to minimize operations if there is only one selector in the list and no seed
+ // (the latter of which guarantees us context)
+ if ( match.length === 1 ) {
+
+ // Reduce context if the leading compound selector is an ID
+ tokens = match[0] = match[0].slice( 0 );
+ if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
+ context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {
+
+ context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
+ if ( !context ) {
+ return results;
+
+ // Precompiled matchers will still verify ancestry, so step up a level
+ } else if ( compiled ) {
+ context = context.parentNode;
+ }
+
+ selector = selector.slice( tokens.shift().value.length );
+ }
+
+ // Fetch a seed set for right-to-left matching
+ i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
+ while ( i-- ) {
+ token = tokens[i];
+
+ // Abort if we hit a combinator
+ if ( Expr.relative[ (type = token.type) ] ) {
+ break;
+ }
+ if ( (find = Expr.find[ type ]) ) {
+ // Search, expanding context for leading sibling combinators
+ if ( (seed = find(
+ token.matches[0].replace( runescape, funescape ),
+ rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
+ )) ) {
+
+ // If seed is empty or no tokens remain, we can return early
+ tokens.splice( i, 1 );
+ selector = seed.length && toSelector( tokens );
+ if ( !selector ) {
+ push.apply( results, seed );
+ return results;
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+ // Compile and execute a filtering function if one is not provided
+ // Provide `match` to avoid retokenization if we modified the selector above
+ ( compiled || compile( selector, match ) )(
+ seed,
+ context,
+ !documentIsHTML,
+ results,
+ !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
+ );
+ return results;
+};
+
+// One-time assignments
+
+// Sort stability
+support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
+
+// Support: Chrome 14-35+
+// Always assume duplicates if they aren't passed to the comparison function
+support.detectDuplicates = !!hasDuplicate;
+
+// Initialize against the default document
+setDocument();
+
+// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
+// Detached nodes confoundingly follow *each other*
+support.sortDetached = assert(function( el ) {
+ // Should return 1, but returns 4 (following)
+ return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
+});
+
+// Support: IE<8
+// Prevent attribute/property "interpolation"
+// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !assert(function( el ) {
+ el.innerHTML = " ";
+ return el.firstChild.getAttribute("href") === "#" ;
+}) ) {
+ addHandle( "type|href|height|width", function( elem, name, isXML ) {
+ if ( !isXML ) {
+ return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
+ }
+ });
+}
+
+// Support: IE<9
+// Use defaultValue in place of getAttribute("value")
+if ( !support.attributes || !assert(function( el ) {
+ el.innerHTML = " ";
+ el.firstChild.setAttribute( "value", "" );
+ return el.firstChild.getAttribute( "value" ) === "";
+}) ) {
+ addHandle( "value", function( elem, name, isXML ) {
+ if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
+ return elem.defaultValue;
+ }
+ });
+}
+
+// Support: IE<9
+// Use getAttributeNode to fetch booleans when getAttribute lies
+if ( !assert(function( el ) {
+ return el.getAttribute("disabled") == null;
+}) ) {
+ addHandle( booleans, function( elem, name, isXML ) {
+ var val;
+ if ( !isXML ) {
+ return elem[ name ] === true ? name.toLowerCase() :
+ (val = elem.getAttributeNode( name )) && val.specified ?
+ val.value :
+ null;
+ }
+ });
+}
+
+return Sizzle;
+
+})( window );
+
+
+
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+
+// Deprecated
+jQuery.expr[ ":" ] = jQuery.expr.pseudos;
+jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+jQuery.escapeSelector = Sizzle.escape;
+
+
+
+
+var dir = function( elem, dir, until ) {
+ var matched = [],
+ truncate = until !== undefined;
+
+ while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
+ if ( elem.nodeType === 1 ) {
+ if ( truncate && jQuery( elem ).is( until ) ) {
+ break;
+ }
+ matched.push( elem );
+ }
+ }
+ return matched;
+};
+
+
+var siblings = function( n, elem ) {
+ var matched = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType === 1 && n !== elem ) {
+ matched.push( n );
+ }
+ }
+
+ return matched;
+};
+
+
+var rneedsContext = jQuery.expr.match.needsContext;
+
+
+
+function nodeName( elem, name ) {
+
+ return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+
+};
+var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
+
+
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, not ) {
+ if ( isFunction( qualifier ) ) {
+ return jQuery.grep( elements, function( elem, i ) {
+ return !!qualifier.call( elem, i, elem ) !== not;
+ } );
+ }
+
+ // Single element
+ if ( qualifier.nodeType ) {
+ return jQuery.grep( elements, function( elem ) {
+ return ( elem === qualifier ) !== not;
+ } );
+ }
+
+ // Arraylike of elements (jQuery, arguments, Array)
+ if ( typeof qualifier !== "string" ) {
+ return jQuery.grep( elements, function( elem ) {
+ return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
+ } );
+ }
+
+ // Filtered directly for both simple and complex selectors
+ return jQuery.filter( qualifier, elements, not );
+}
+
+jQuery.filter = function( expr, elems, not ) {
+ var elem = elems[ 0 ];
+
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ if ( elems.length === 1 && elem.nodeType === 1 ) {
+ return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
+ }
+
+ return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
+ return elem.nodeType === 1;
+ } ) );
+};
+
+jQuery.fn.extend( {
+ find: function( selector ) {
+ var i, ret,
+ len = this.length,
+ self = this;
+
+ if ( typeof selector !== "string" ) {
+ return this.pushStack( jQuery( selector ).filter( function() {
+ for ( i = 0; i < len; i++ ) {
+ if ( jQuery.contains( self[ i ], this ) ) {
+ return true;
+ }
+ }
+ } ) );
+ }
+
+ ret = this.pushStack( [] );
+
+ for ( i = 0; i < len; i++ ) {
+ jQuery.find( selector, self[ i ], ret );
+ }
+
+ return len > 1 ? jQuery.uniqueSort( ret ) : ret;
+ },
+ filter: function( selector ) {
+ return this.pushStack( winnow( this, selector || [], false ) );
+ },
+ not: function( selector ) {
+ return this.pushStack( winnow( this, selector || [], true ) );
+ },
+ is: function( selector ) {
+ return !!winnow(
+ this,
+
+ // If this is a positional/relative selector, check membership in the returned set
+ // so $("p:first").is("p:last") won't return true for a doc with two "p".
+ typeof selector === "string" && rneedsContext.test( selector ) ?
+ jQuery( selector ) :
+ selector || [],
+ false
+ ).length;
+ }
+} );
+
+
+// Initialize a jQuery object
+
+
+// A central reference to the root jQuery(document)
+var rootjQuery,
+
+ // A simple way to check for HTML strings
+ // Prioritize #id over to avoid XSS via location.hash (#9521)
+ // Strict HTML recognition (#11290: must start with <)
+ // Shortcut simple #id case for speed
+ rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
+
+ init = jQuery.fn.init = function( selector, context, root ) {
+ var match, elem;
+
+ // HANDLE: $(""), $(null), $(undefined), $(false)
+ if ( !selector ) {
+ return this;
+ }
+
+ // Method init() accepts an alternate rootjQuery
+ // so migrate can support jQuery.sub (gh-2101)
+ root = root || rootjQuery;
+
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ if ( selector[ 0 ] === "<" &&
+ selector[ selector.length - 1 ] === ">" &&
+ selector.length >= 3 ) {
+
+ // Assume that strings that start and end with <> are HTML and skip the regex check
+ match = [ null, selector, null ];
+
+ } else {
+ match = rquickExpr.exec( selector );
+ }
+
+ // Match html or make sure no context is specified for #id
+ if ( match && ( match[ 1 ] || !context ) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[ 1 ] ) {
+ context = context instanceof jQuery ? context[ 0 ] : context;
+
+ // Option to run scripts is true for back-compat
+ // Intentionally let the error be thrown if parseHTML is not present
+ jQuery.merge( this, jQuery.parseHTML(
+ match[ 1 ],
+ context && context.nodeType ? context.ownerDocument || context : document,
+ true
+ ) );
+
+ // HANDLE: $(html, props)
+ if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
+ for ( match in context ) {
+
+ // Properties of context are called as methods if possible
+ if ( isFunction( this[ match ] ) ) {
+ this[ match ]( context[ match ] );
+
+ // ...and otherwise set as attributes
+ } else {
+ this.attr( match, context[ match ] );
+ }
+ }
+ }
+
+ return this;
+
+ // HANDLE: $(#id)
+ } else {
+ elem = document.getElementById( match[ 2 ] );
+
+ if ( elem ) {
+
+ // Inject the element directly into the jQuery object
+ this[ 0 ] = elem;
+ this.length = 1;
+ }
+ return this;
+ }
+
+ // HANDLE: $(expr, $(...))
+ } else if ( !context || context.jquery ) {
+ return ( context || root ).find( selector );
+
+ // HANDLE: $(expr, context)
+ // (which is just equivalent to: $(context).find(expr)
+ } else {
+ return this.constructor( context ).find( selector );
+ }
+
+ // HANDLE: $(DOMElement)
+ } else if ( selector.nodeType ) {
+ this[ 0 ] = selector;
+ this.length = 1;
+ return this;
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( isFunction( selector ) ) {
+ return root.ready !== undefined ?
+ root.ready( selector ) :
+
+ // Execute immediately if ready is not present
+ selector( jQuery );
+ }
+
+ return jQuery.makeArray( selector, this );
+ };
+
+// Give the init function the jQuery prototype for later instantiation
+init.prototype = jQuery.fn;
+
+// Initialize central reference
+rootjQuery = jQuery( document );
+
+
+var rparentsprev = /^(?:parents|prev(?:Until|All))/,
+
+ // Methods guaranteed to produce a unique set when starting from a unique set
+ guaranteedUnique = {
+ children: true,
+ contents: true,
+ next: true,
+ prev: true
+ };
+
+jQuery.fn.extend( {
+ has: function( target ) {
+ var targets = jQuery( target, this ),
+ l = targets.length;
+
+ return this.filter( function() {
+ var i = 0;
+ for ( ; i < l; i++ ) {
+ if ( jQuery.contains( this, targets[ i ] ) ) {
+ return true;
+ }
+ }
+ } );
+ },
+
+ closest: function( selectors, context ) {
+ var cur,
+ i = 0,
+ l = this.length,
+ matched = [],
+ targets = typeof selectors !== "string" && jQuery( selectors );
+
+ // Positional selectors never match, since there's no _selection_ context
+ if ( !rneedsContext.test( selectors ) ) {
+ for ( ; i < l; i++ ) {
+ for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
+
+ // Always skip document fragments
+ if ( cur.nodeType < 11 && ( targets ?
+ targets.index( cur ) > -1 :
+
+ // Don't pass non-elements to Sizzle
+ cur.nodeType === 1 &&
+ jQuery.find.matchesSelector( cur, selectors ) ) ) {
+
+ matched.push( cur );
+ break;
+ }
+ }
+ }
+ }
+
+ return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
+ },
+
+ // Determine the position of an element within the set
+ index: function( elem ) {
+
+ // No argument, return index in parent
+ if ( !elem ) {
+ return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
+ }
+
+ // Index in selector
+ if ( typeof elem === "string" ) {
+ return indexOf.call( jQuery( elem ), this[ 0 ] );
+ }
+
+ // Locate the position of the desired element
+ return indexOf.call( this,
+
+ // If it receives a jQuery object, the first element is used
+ elem.jquery ? elem[ 0 ] : elem
+ );
+ },
+
+ add: function( selector, context ) {
+ return this.pushStack(
+ jQuery.uniqueSort(
+ jQuery.merge( this.get(), jQuery( selector, context ) )
+ )
+ );
+ },
+
+ addBack: function( selector ) {
+ return this.add( selector == null ?
+ this.prevObject : this.prevObject.filter( selector )
+ );
+ }
+} );
+
+function sibling( cur, dir ) {
+ while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
+ return cur;
+}
+
+jQuery.each( {
+ parent: function( elem ) {
+ var parent = elem.parentNode;
+ return parent && parent.nodeType !== 11 ? parent : null;
+ },
+ parents: function( elem ) {
+ return dir( elem, "parentNode" );
+ },
+ parentsUntil: function( elem, i, until ) {
+ return dir( elem, "parentNode", until );
+ },
+ next: function( elem ) {
+ return sibling( elem, "nextSibling" );
+ },
+ prev: function( elem ) {
+ return sibling( elem, "previousSibling" );
+ },
+ nextAll: function( elem ) {
+ return dir( elem, "nextSibling" );
+ },
+ prevAll: function( elem ) {
+ return dir( elem, "previousSibling" );
+ },
+ nextUntil: function( elem, i, until ) {
+ return dir( elem, "nextSibling", until );
+ },
+ prevUntil: function( elem, i, until ) {
+ return dir( elem, "previousSibling", until );
+ },
+ siblings: function( elem ) {
+ return siblings( ( elem.parentNode || {} ).firstChild, elem );
+ },
+ children: function( elem ) {
+ return siblings( elem.firstChild );
+ },
+ contents: function( elem ) {
+ if ( nodeName( elem, "iframe" ) ) {
+ return elem.contentDocument;
+ }
+
+ // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
+ // Treat the template element as a regular one in browsers that
+ // don't support it.
+ if ( nodeName( elem, "template" ) ) {
+ elem = elem.content || elem;
+ }
+
+ return jQuery.merge( [], elem.childNodes );
+ }
+}, function( name, fn ) {
+ jQuery.fn[ name ] = function( until, selector ) {
+ var matched = jQuery.map( this, fn, until );
+
+ if ( name.slice( -5 ) !== "Until" ) {
+ selector = until;
+ }
+
+ if ( selector && typeof selector === "string" ) {
+ matched = jQuery.filter( selector, matched );
+ }
+
+ if ( this.length > 1 ) {
+
+ // Remove duplicates
+ if ( !guaranteedUnique[ name ] ) {
+ jQuery.uniqueSort( matched );
+ }
+
+ // Reverse order for parents* and prev-derivatives
+ if ( rparentsprev.test( name ) ) {
+ matched.reverse();
+ }
+ }
+
+ return this.pushStack( matched );
+ };
+} );
+var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
+
+
+
+// Convert String-formatted options into Object-formatted ones
+function createOptions( options ) {
+ var object = {};
+ jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
+ object[ flag ] = true;
+ } );
+ return object;
+}
+
+/*
+ * Create a callback list using the following parameters:
+ *
+ * options: an optional list of space-separated options that will change how
+ * the callback list behaves or a more traditional option object
+ *
+ * By default a callback list will act like an event callback list and can be
+ * "fired" multiple times.
+ *
+ * Possible options:
+ *
+ * once: will ensure the callback list can only be fired once (like a Deferred)
+ *
+ * memory: will keep track of previous values and will call any callback added
+ * after the list has been fired right away with the latest "memorized"
+ * values (like a Deferred)
+ *
+ * unique: will ensure a callback can only be added once (no duplicate in the list)
+ *
+ * stopOnFalse: interrupt callings when a callback returns false
+ *
+ */
+jQuery.Callbacks = function( options ) {
+
+ // Convert options from String-formatted to Object-formatted if needed
+ // (we check in cache first)
+ options = typeof options === "string" ?
+ createOptions( options ) :
+ jQuery.extend( {}, options );
+
+ var // Flag to know if list is currently firing
+ firing,
+
+ // Last fire value for non-forgettable lists
+ memory,
+
+ // Flag to know if list was already fired
+ fired,
+
+ // Flag to prevent firing
+ locked,
+
+ // Actual callback list
+ list = [],
+
+ // Queue of execution data for repeatable lists
+ queue = [],
+
+ // Index of currently firing callback (modified by add/remove as needed)
+ firingIndex = -1,
+
+ // Fire callbacks
+ fire = function() {
+
+ // Enforce single-firing
+ locked = locked || options.once;
+
+ // Execute callbacks for all pending executions,
+ // respecting firingIndex overrides and runtime changes
+ fired = firing = true;
+ for ( ; queue.length; firingIndex = -1 ) {
+ memory = queue.shift();
+ while ( ++firingIndex < list.length ) {
+
+ // Run callback and check for early termination
+ if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
+ options.stopOnFalse ) {
+
+ // Jump to end and forget the data so .add doesn't re-fire
+ firingIndex = list.length;
+ memory = false;
+ }
+ }
+ }
+
+ // Forget the data if we're done with it
+ if ( !options.memory ) {
+ memory = false;
+ }
+
+ firing = false;
+
+ // Clean up if we're done firing for good
+ if ( locked ) {
+
+ // Keep an empty list if we have data for future add calls
+ if ( memory ) {
+ list = [];
+
+ // Otherwise, this object is spent
+ } else {
+ list = "";
+ }
+ }
+ },
+
+ // Actual Callbacks object
+ self = {
+
+ // Add a callback or a collection of callbacks to the list
+ add: function() {
+ if ( list ) {
+
+ // If we have memory from a past run, we should fire after adding
+ if ( memory && !firing ) {
+ firingIndex = list.length - 1;
+ queue.push( memory );
+ }
+
+ ( function add( args ) {
+ jQuery.each( args, function( _, arg ) {
+ if ( isFunction( arg ) ) {
+ if ( !options.unique || !self.has( arg ) ) {
+ list.push( arg );
+ }
+ } else if ( arg && arg.length && toType( arg ) !== "string" ) {
+
+ // Inspect recursively
+ add( arg );
+ }
+ } );
+ } )( arguments );
+
+ if ( memory && !firing ) {
+ fire();
+ }
+ }
+ return this;
+ },
+
+ // Remove a callback from the list
+ remove: function() {
+ jQuery.each( arguments, function( _, arg ) {
+ var index;
+ while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
+ list.splice( index, 1 );
+
+ // Handle firing indexes
+ if ( index <= firingIndex ) {
+ firingIndex--;
+ }
+ }
+ } );
+ return this;
+ },
+
+ // Check if a given callback is in the list.
+ // If no argument is given, return whether or not list has callbacks attached.
+ has: function( fn ) {
+ return fn ?
+ jQuery.inArray( fn, list ) > -1 :
+ list.length > 0;
+ },
+
+ // Remove all callbacks from the list
+ empty: function() {
+ if ( list ) {
+ list = [];
+ }
+ return this;
+ },
+
+ // Disable .fire and .add
+ // Abort any current/pending executions
+ // Clear all callbacks and values
+ disable: function() {
+ locked = queue = [];
+ list = memory = "";
+ return this;
+ },
+ disabled: function() {
+ return !list;
+ },
+
+ // Disable .fire
+ // Also disable .add unless we have memory (since it would have no effect)
+ // Abort any pending executions
+ lock: function() {
+ locked = queue = [];
+ if ( !memory && !firing ) {
+ list = memory = "";
+ }
+ return this;
+ },
+ locked: function() {
+ return !!locked;
+ },
+
+ // Call all callbacks with the given context and arguments
+ fireWith: function( context, args ) {
+ if ( !locked ) {
+ args = args || [];
+ args = [ context, args.slice ? args.slice() : args ];
+ queue.push( args );
+ if ( !firing ) {
+ fire();
+ }
+ }
+ return this;
+ },
+
+ // Call all the callbacks with the given arguments
+ fire: function() {
+ self.fireWith( this, arguments );
+ return this;
+ },
+
+ // To know if the callbacks have already been called at least once
+ fired: function() {
+ return !!fired;
+ }
+ };
+
+ return self;
+};
+
+
+function Identity( v ) {
+ return v;
+}
+function Thrower( ex ) {
+ throw ex;
+}
+
+function adoptValue( value, resolve, reject, noValue ) {
+ var method;
+
+ try {
+
+ // Check for promise aspect first to privilege synchronous behavior
+ if ( value && isFunction( ( method = value.promise ) ) ) {
+ method.call( value ).done( resolve ).fail( reject );
+
+ // Other thenables
+ } else if ( value && isFunction( ( method = value.then ) ) ) {
+ method.call( value, resolve, reject );
+
+ // Other non-thenables
+ } else {
+
+ // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
+ // * false: [ value ].slice( 0 ) => resolve( value )
+ // * true: [ value ].slice( 1 ) => resolve()
+ resolve.apply( undefined, [ value ].slice( noValue ) );
+ }
+
+ // For Promises/A+, convert exceptions into rejections
+ // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
+ // Deferred#then to conditionally suppress rejection.
+ } catch ( value ) {
+
+ // Support: Android 4.0 only
+ // Strict mode functions invoked without .call/.apply get global-object context
+ reject.apply( undefined, [ value ] );
+ }
+}
+
+jQuery.extend( {
+
+ Deferred: function( func ) {
+ var tuples = [
+
+ // action, add listener, callbacks,
+ // ... .then handlers, argument index, [final state]
+ [ "notify", "progress", jQuery.Callbacks( "memory" ),
+ jQuery.Callbacks( "memory" ), 2 ],
+ [ "resolve", "done", jQuery.Callbacks( "once memory" ),
+ jQuery.Callbacks( "once memory" ), 0, "resolved" ],
+ [ "reject", "fail", jQuery.Callbacks( "once memory" ),
+ jQuery.Callbacks( "once memory" ), 1, "rejected" ]
+ ],
+ state = "pending",
+ promise = {
+ state: function() {
+ return state;
+ },
+ always: function() {
+ deferred.done( arguments ).fail( arguments );
+ return this;
+ },
+ "catch": function( fn ) {
+ return promise.then( null, fn );
+ },
+
+ // Keep pipe for back-compat
+ pipe: function( /* fnDone, fnFail, fnProgress */ ) {
+ var fns = arguments;
+
+ return jQuery.Deferred( function( newDefer ) {
+ jQuery.each( tuples, function( i, tuple ) {
+
+ // Map tuples (progress, done, fail) to arguments (done, fail, progress)
+ var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
+
+ // deferred.progress(function() { bind to newDefer or newDefer.notify })
+ // deferred.done(function() { bind to newDefer or newDefer.resolve })
+ // deferred.fail(function() { bind to newDefer or newDefer.reject })
+ deferred[ tuple[ 1 ] ]( function() {
+ var returned = fn && fn.apply( this, arguments );
+ if ( returned && isFunction( returned.promise ) ) {
+ returned.promise()
+ .progress( newDefer.notify )
+ .done( newDefer.resolve )
+ .fail( newDefer.reject );
+ } else {
+ newDefer[ tuple[ 0 ] + "With" ](
+ this,
+ fn ? [ returned ] : arguments
+ );
+ }
+ } );
+ } );
+ fns = null;
+ } ).promise();
+ },
+ then: function( onFulfilled, onRejected, onProgress ) {
+ var maxDepth = 0;
+ function resolve( depth, deferred, handler, special ) {
+ return function() {
+ var that = this,
+ args = arguments,
+ mightThrow = function() {
+ var returned, then;
+
+ // Support: Promises/A+ section 2.3.3.3.3
+ // https://promisesaplus.com/#point-59
+ // Ignore double-resolution attempts
+ if ( depth < maxDepth ) {
+ return;
+ }
+
+ returned = handler.apply( that, args );
+
+ // Support: Promises/A+ section 2.3.1
+ // https://promisesaplus.com/#point-48
+ if ( returned === deferred.promise() ) {
+ throw new TypeError( "Thenable self-resolution" );
+ }
+
+ // Support: Promises/A+ sections 2.3.3.1, 3.5
+ // https://promisesaplus.com/#point-54
+ // https://promisesaplus.com/#point-75
+ // Retrieve `then` only once
+ then = returned &&
+
+ // Support: Promises/A+ section 2.3.4
+ // https://promisesaplus.com/#point-64
+ // Only check objects and functions for thenability
+ ( typeof returned === "object" ||
+ typeof returned === "function" ) &&
+ returned.then;
+
+ // Handle a returned thenable
+ if ( isFunction( then ) ) {
+
+ // Special processors (notify) just wait for resolution
+ if ( special ) {
+ then.call(
+ returned,
+ resolve( maxDepth, deferred, Identity, special ),
+ resolve( maxDepth, deferred, Thrower, special )
+ );
+
+ // Normal processors (resolve) also hook into progress
+ } else {
+
+ // ...and disregard older resolution values
+ maxDepth++;
+
+ then.call(
+ returned,
+ resolve( maxDepth, deferred, Identity, special ),
+ resolve( maxDepth, deferred, Thrower, special ),
+ resolve( maxDepth, deferred, Identity,
+ deferred.notifyWith )
+ );
+ }
+
+ // Handle all other returned values
+ } else {
+
+ // Only substitute handlers pass on context
+ // and multiple values (non-spec behavior)
+ if ( handler !== Identity ) {
+ that = undefined;
+ args = [ returned ];
+ }
+
+ // Process the value(s)
+ // Default process is resolve
+ ( special || deferred.resolveWith )( that, args );
+ }
+ },
+
+ // Only normal processors (resolve) catch and reject exceptions
+ process = special ?
+ mightThrow :
+ function() {
+ try {
+ mightThrow();
+ } catch ( e ) {
+
+ if ( jQuery.Deferred.exceptionHook ) {
+ jQuery.Deferred.exceptionHook( e,
+ process.stackTrace );
+ }
+
+ // Support: Promises/A+ section 2.3.3.3.4.1
+ // https://promisesaplus.com/#point-61
+ // Ignore post-resolution exceptions
+ if ( depth + 1 >= maxDepth ) {
+
+ // Only substitute handlers pass on context
+ // and multiple values (non-spec behavior)
+ if ( handler !== Thrower ) {
+ that = undefined;
+ args = [ e ];
+ }
+
+ deferred.rejectWith( that, args );
+ }
+ }
+ };
+
+ // Support: Promises/A+ section 2.3.3.3.1
+ // https://promisesaplus.com/#point-57
+ // Re-resolve promises immediately to dodge false rejection from
+ // subsequent errors
+ if ( depth ) {
+ process();
+ } else {
+
+ // Call an optional hook to record the stack, in case of exception
+ // since it's otherwise lost when execution goes async
+ if ( jQuery.Deferred.getStackHook ) {
+ process.stackTrace = jQuery.Deferred.getStackHook();
+ }
+ window.setTimeout( process );
+ }
+ };
+ }
+
+ return jQuery.Deferred( function( newDefer ) {
+
+ // progress_handlers.add( ... )
+ tuples[ 0 ][ 3 ].add(
+ resolve(
+ 0,
+ newDefer,
+ isFunction( onProgress ) ?
+ onProgress :
+ Identity,
+ newDefer.notifyWith
+ )
+ );
+
+ // fulfilled_handlers.add( ... )
+ tuples[ 1 ][ 3 ].add(
+ resolve(
+ 0,
+ newDefer,
+ isFunction( onFulfilled ) ?
+ onFulfilled :
+ Identity
+ )
+ );
+
+ // rejected_handlers.add( ... )
+ tuples[ 2 ][ 3 ].add(
+ resolve(
+ 0,
+ newDefer,
+ isFunction( onRejected ) ?
+ onRejected :
+ Thrower
+ )
+ );
+ } ).promise();
+ },
+
+ // Get a promise for this deferred
+ // If obj is provided, the promise aspect is added to the object
+ promise: function( obj ) {
+ return obj != null ? jQuery.extend( obj, promise ) : promise;
+ }
+ },
+ deferred = {};
+
+ // Add list-specific methods
+ jQuery.each( tuples, function( i, tuple ) {
+ var list = tuple[ 2 ],
+ stateString = tuple[ 5 ];
+
+ // promise.progress = list.add
+ // promise.done = list.add
+ // promise.fail = list.add
+ promise[ tuple[ 1 ] ] = list.add;
+
+ // Handle state
+ if ( stateString ) {
+ list.add(
+ function() {
+
+ // state = "resolved" (i.e., fulfilled)
+ // state = "rejected"
+ state = stateString;
+ },
+
+ // rejected_callbacks.disable
+ // fulfilled_callbacks.disable
+ tuples[ 3 - i ][ 2 ].disable,
+
+ // rejected_handlers.disable
+ // fulfilled_handlers.disable
+ tuples[ 3 - i ][ 3 ].disable,
+
+ // progress_callbacks.lock
+ tuples[ 0 ][ 2 ].lock,
+
+ // progress_handlers.lock
+ tuples[ 0 ][ 3 ].lock
+ );
+ }
+
+ // progress_handlers.fire
+ // fulfilled_handlers.fire
+ // rejected_handlers.fire
+ list.add( tuple[ 3 ].fire );
+
+ // deferred.notify = function() { deferred.notifyWith(...) }
+ // deferred.resolve = function() { deferred.resolveWith(...) }
+ // deferred.reject = function() { deferred.rejectWith(...) }
+ deferred[ tuple[ 0 ] ] = function() {
+ deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
+ return this;
+ };
+
+ // deferred.notifyWith = list.fireWith
+ // deferred.resolveWith = list.fireWith
+ // deferred.rejectWith = list.fireWith
+ deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
+ } );
+
+ // Make the deferred a promise
+ promise.promise( deferred );
+
+ // Call given func if any
+ if ( func ) {
+ func.call( deferred, deferred );
+ }
+
+ // All done!
+ return deferred;
+ },
+
+ // Deferred helper
+ when: function( singleValue ) {
+ var
+
+ // count of uncompleted subordinates
+ remaining = arguments.length,
+
+ // count of unprocessed arguments
+ i = remaining,
+
+ // subordinate fulfillment data
+ resolveContexts = Array( i ),
+ resolveValues = slice.call( arguments ),
+
+ // the master Deferred
+ master = jQuery.Deferred(),
+
+ // subordinate callback factory
+ updateFunc = function( i ) {
+ return function( value ) {
+ resolveContexts[ i ] = this;
+ resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
+ if ( !( --remaining ) ) {
+ master.resolveWith( resolveContexts, resolveValues );
+ }
+ };
+ };
+
+ // Single- and empty arguments are adopted like Promise.resolve
+ if ( remaining <= 1 ) {
+ adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
+ !remaining );
+
+ // Use .then() to unwrap secondary thenables (cf. gh-3000)
+ if ( master.state() === "pending" ||
+ isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
+
+ return master.then();
+ }
+ }
+
+ // Multiple arguments are aggregated like Promise.all array elements
+ while ( i-- ) {
+ adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
+ }
+
+ return master.promise();
+ }
+} );
+
+
+// These usually indicate a programmer mistake during development,
+// warn about them ASAP rather than swallowing them by default.
+var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
+
+jQuery.Deferred.exceptionHook = function( error, stack ) {
+
+ // Support: IE 8 - 9 only
+ // Console exists when dev tools are open, which can happen at any time
+ if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
+ window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
+ }
+};
+
+
+
+
+jQuery.readyException = function( error ) {
+ window.setTimeout( function() {
+ throw error;
+ } );
+};
+
+
+
+
+// The deferred used on DOM ready
+var readyList = jQuery.Deferred();
+
+jQuery.fn.ready = function( fn ) {
+
+ readyList
+ .then( fn )
+
+ // Wrap jQuery.readyException in a function so that the lookup
+ // happens at the time of error handling instead of callback
+ // registration.
+ .catch( function( error ) {
+ jQuery.readyException( error );
+ } );
+
+ return this;
+};
+
+jQuery.extend( {
+
+ // Is the DOM ready to be used? Set to true once it occurs.
+ isReady: false,
+
+ // A counter to track how many items to wait for before
+ // the ready event fires. See #6781
+ readyWait: 1,
+
+ // Handle when the DOM is ready
+ ready: function( wait ) {
+
+ // Abort if there are pending holds or we're already ready
+ if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
+ return;
+ }
+
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If a normal DOM Ready event fired, decrement, and wait if need be
+ if ( wait !== true && --jQuery.readyWait > 0 ) {
+ return;
+ }
+
+ // If there are functions bound, to execute
+ readyList.resolveWith( document, [ jQuery ] );
+ }
+} );
+
+jQuery.ready.then = readyList.then;
+
+// The ready event handler and self cleanup method
+function completed() {
+ document.removeEventListener( "DOMContentLoaded", completed );
+ window.removeEventListener( "load", completed );
+ jQuery.ready();
+}
+
+// Catch cases where $(document).ready() is called
+// after the browser event has already occurred.
+// Support: IE <=9 - 10 only
+// Older IE sometimes signals "interactive" too soon
+if ( document.readyState === "complete" ||
+ ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
+
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
+ window.setTimeout( jQuery.ready );
+
+} else {
+
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", completed );
+
+ // A fallback to window.onload, that will always work
+ window.addEventListener( "load", completed );
+}
+
+
+
+
+// Multifunctional method to get and set values of a collection
+// The value/s can optionally be executed if it's a function
+var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
+ var i = 0,
+ len = elems.length,
+ bulk = key == null;
+
+ // Sets many values
+ if ( toType( key ) === "object" ) {
+ chainable = true;
+ for ( i in key ) {
+ access( elems, fn, i, key[ i ], true, emptyGet, raw );
+ }
+
+ // Sets one value
+ } else if ( value !== undefined ) {
+ chainable = true;
+
+ if ( !isFunction( value ) ) {
+ raw = true;
+ }
+
+ if ( bulk ) {
+
+ // Bulk operations run against the entire set
+ if ( raw ) {
+ fn.call( elems, value );
+ fn = null;
+
+ // ...except when executing function values
+ } else {
+ bulk = fn;
+ fn = function( elem, key, value ) {
+ return bulk.call( jQuery( elem ), value );
+ };
+ }
+ }
+
+ if ( fn ) {
+ for ( ; i < len; i++ ) {
+ fn(
+ elems[ i ], key, raw ?
+ value :
+ value.call( elems[ i ], i, fn( elems[ i ], key ) )
+ );
+ }
+ }
+ }
+
+ if ( chainable ) {
+ return elems;
+ }
+
+ // Gets
+ if ( bulk ) {
+ return fn.call( elems );
+ }
+
+ return len ? fn( elems[ 0 ], key ) : emptyGet;
+};
+
+
+// Matches dashed string for camelizing
+var rmsPrefix = /^-ms-/,
+ rdashAlpha = /-([a-z])/g;
+
+// Used by camelCase as callback to replace()
+function fcamelCase( all, letter ) {
+ return letter.toUpperCase();
+}
+
+// Convert dashed to camelCase; used by the css and data modules
+// Support: IE <=9 - 11, Edge 12 - 15
+// Microsoft forgot to hump their vendor prefix (#9572)
+function camelCase( string ) {
+ return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+}
+var acceptData = function( owner ) {
+
+ // Accepts only:
+ // - Node
+ // - Node.ELEMENT_NODE
+ // - Node.DOCUMENT_NODE
+ // - Object
+ // - Any
+ return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
+};
+
+
+
+
+function Data() {
+ this.expando = jQuery.expando + Data.uid++;
+}
+
+Data.uid = 1;
+
+Data.prototype = {
+
+ cache: function( owner ) {
+
+ // Check if the owner object already has a cache
+ var value = owner[ this.expando ];
+
+ // If not, create one
+ if ( !value ) {
+ value = {};
+
+ // We can accept data for non-element nodes in modern browsers,
+ // but we should not, see #8335.
+ // Always return an empty object.
+ if ( acceptData( owner ) ) {
+
+ // If it is a node unlikely to be stringify-ed or looped over
+ // use plain assignment
+ if ( owner.nodeType ) {
+ owner[ this.expando ] = value;
+
+ // Otherwise secure it in a non-enumerable property
+ // configurable must be true to allow the property to be
+ // deleted when data is removed
+ } else {
+ Object.defineProperty( owner, this.expando, {
+ value: value,
+ configurable: true
+ } );
+ }
+ }
+ }
+
+ return value;
+ },
+ set: function( owner, data, value ) {
+ var prop,
+ cache = this.cache( owner );
+
+ // Handle: [ owner, key, value ] args
+ // Always use camelCase key (gh-2257)
+ if ( typeof data === "string" ) {
+ cache[ camelCase( data ) ] = value;
+
+ // Handle: [ owner, { properties } ] args
+ } else {
+
+ // Copy the properties one-by-one to the cache object
+ for ( prop in data ) {
+ cache[ camelCase( prop ) ] = data[ prop ];
+ }
+ }
+ return cache;
+ },
+ get: function( owner, key ) {
+ return key === undefined ?
+ this.cache( owner ) :
+
+ // Always use camelCase key (gh-2257)
+ owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
+ },
+ access: function( owner, key, value ) {
+
+ // In cases where either:
+ //
+ // 1. No key was specified
+ // 2. A string key was specified, but no value provided
+ //
+ // Take the "read" path and allow the get method to determine
+ // which value to return, respectively either:
+ //
+ // 1. The entire cache object
+ // 2. The data stored at the key
+ //
+ if ( key === undefined ||
+ ( ( key && typeof key === "string" ) && value === undefined ) ) {
+
+ return this.get( owner, key );
+ }
+
+ // When the key is not a string, or both a key and value
+ // are specified, set or extend (existing objects) with either:
+ //
+ // 1. An object of properties
+ // 2. A key and value
+ //
+ this.set( owner, key, value );
+
+ // Since the "set" path can have two possible entry points
+ // return the expected data based on which path was taken[*]
+ return value !== undefined ? value : key;
+ },
+ remove: function( owner, key ) {
+ var i,
+ cache = owner[ this.expando ];
+
+ if ( cache === undefined ) {
+ return;
+ }
+
+ if ( key !== undefined ) {
+
+ // Support array or space separated string of keys
+ if ( Array.isArray( key ) ) {
+
+ // If key is an array of keys...
+ // We always set camelCase keys, so remove that.
+ key = key.map( camelCase );
+ } else {
+ key = camelCase( key );
+
+ // If a key with the spaces exists, use it.
+ // Otherwise, create an array by matching non-whitespace
+ key = key in cache ?
+ [ key ] :
+ ( key.match( rnothtmlwhite ) || [] );
+ }
+
+ i = key.length;
+
+ while ( i-- ) {
+ delete cache[ key[ i ] ];
+ }
+ }
+
+ // Remove the expando if there's no more data
+ if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
+
+ // Support: Chrome <=35 - 45
+ // Webkit & Blink performance suffers when deleting properties
+ // from DOM nodes, so set to undefined instead
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
+ if ( owner.nodeType ) {
+ owner[ this.expando ] = undefined;
+ } else {
+ delete owner[ this.expando ];
+ }
+ }
+ },
+ hasData: function( owner ) {
+ var cache = owner[ this.expando ];
+ return cache !== undefined && !jQuery.isEmptyObject( cache );
+ }
+};
+var dataPriv = new Data();
+
+var dataUser = new Data();
+
+
+
+// Implementation Summary
+//
+// 1. Enforce API surface and semantic compatibility with 1.9.x branch
+// 2. Improve the module's maintainability by reducing the storage
+// paths to a single mechanism.
+// 3. Use the same single mechanism to support "private" and "user" data.
+// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
+// 5. Avoid exposing implementation details on user objects (eg. expando properties)
+// 6. Provide a clear path for implementation upgrade to WeakMap in 2014
+
+var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
+ rmultiDash = /[A-Z]/g;
+
+function getData( data ) {
+ if ( data === "true" ) {
+ return true;
+ }
+
+ if ( data === "false" ) {
+ return false;
+ }
+
+ if ( data === "null" ) {
+ return null;
+ }
+
+ // Only convert to a number if it doesn't change the string
+ if ( data === +data + "" ) {
+ return +data;
+ }
+
+ if ( rbrace.test( data ) ) {
+ return JSON.parse( data );
+ }
+
+ return data;
+}
+
+function dataAttr( elem, key, data ) {
+ var name;
+
+ // If nothing was found internally, try to fetch any
+ // data from the HTML5 data-* attribute
+ if ( data === undefined && elem.nodeType === 1 ) {
+ name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
+ data = elem.getAttribute( name );
+
+ if ( typeof data === "string" ) {
+ try {
+ data = getData( data );
+ } catch ( e ) {}
+
+ // Make sure we set the data so it isn't changed later
+ dataUser.set( elem, key, data );
+ } else {
+ data = undefined;
+ }
+ }
+ return data;
+}
+
+jQuery.extend( {
+ hasData: function( elem ) {
+ return dataUser.hasData( elem ) || dataPriv.hasData( elem );
+ },
+
+ data: function( elem, name, data ) {
+ return dataUser.access( elem, name, data );
+ },
+
+ removeData: function( elem, name ) {
+ dataUser.remove( elem, name );
+ },
+
+ // TODO: Now that all calls to _data and _removeData have been replaced
+ // with direct calls to dataPriv methods, these can be deprecated.
+ _data: function( elem, name, data ) {
+ return dataPriv.access( elem, name, data );
+ },
+
+ _removeData: function( elem, name ) {
+ dataPriv.remove( elem, name );
+ }
+} );
+
+jQuery.fn.extend( {
+ data: function( key, value ) {
+ var i, name, data,
+ elem = this[ 0 ],
+ attrs = elem && elem.attributes;
+
+ // Gets all values
+ if ( key === undefined ) {
+ if ( this.length ) {
+ data = dataUser.get( elem );
+
+ if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
+ i = attrs.length;
+ while ( i-- ) {
+
+ // Support: IE 11 only
+ // The attrs elements can be null (#14894)
+ if ( attrs[ i ] ) {
+ name = attrs[ i ].name;
+ if ( name.indexOf( "data-" ) === 0 ) {
+ name = camelCase( name.slice( 5 ) );
+ dataAttr( elem, name, data[ name ] );
+ }
+ }
+ }
+ dataPriv.set( elem, "hasDataAttrs", true );
+ }
+ }
+
+ return data;
+ }
+
+ // Sets multiple values
+ if ( typeof key === "object" ) {
+ return this.each( function() {
+ dataUser.set( this, key );
+ } );
+ }
+
+ return access( this, function( value ) {
+ var data;
+
+ // The calling jQuery object (element matches) is not empty
+ // (and therefore has an element appears at this[ 0 ]) and the
+ // `value` parameter was not undefined. An empty jQuery object
+ // will result in `undefined` for elem = this[ 0 ] which will
+ // throw an exception if an attempt to read a data cache is made.
+ if ( elem && value === undefined ) {
+
+ // Attempt to get data from the cache
+ // The key will always be camelCased in Data
+ data = dataUser.get( elem, key );
+ if ( data !== undefined ) {
+ return data;
+ }
+
+ // Attempt to "discover" the data in
+ // HTML5 custom data-* attrs
+ data = dataAttr( elem, key );
+ if ( data !== undefined ) {
+ return data;
+ }
+
+ // We tried really hard, but the data doesn't exist.
+ return;
+ }
+
+ // Set the data...
+ this.each( function() {
+
+ // We always store the camelCased key
+ dataUser.set( this, key, value );
+ } );
+ }, null, value, arguments.length > 1, null, true );
+ },
+
+ removeData: function( key ) {
+ return this.each( function() {
+ dataUser.remove( this, key );
+ } );
+ }
+} );
+
+
+jQuery.extend( {
+ queue: function( elem, type, data ) {
+ var queue;
+
+ if ( elem ) {
+ type = ( type || "fx" ) + "queue";
+ queue = dataPriv.get( elem, type );
+
+ // Speed up dequeue by getting out quickly if this is just a lookup
+ if ( data ) {
+ if ( !queue || Array.isArray( data ) ) {
+ queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
+ } else {
+ queue.push( data );
+ }
+ }
+ return queue || [];
+ }
+ },
+
+ dequeue: function( elem, type ) {
+ type = type || "fx";
+
+ var queue = jQuery.queue( elem, type ),
+ startLength = queue.length,
+ fn = queue.shift(),
+ hooks = jQuery._queueHooks( elem, type ),
+ next = function() {
+ jQuery.dequeue( elem, type );
+ };
+
+ // If the fx queue is dequeued, always remove the progress sentinel
+ if ( fn === "inprogress" ) {
+ fn = queue.shift();
+ startLength--;
+ }
+
+ if ( fn ) {
+
+ // Add a progress sentinel to prevent the fx queue from being
+ // automatically dequeued
+ if ( type === "fx" ) {
+ queue.unshift( "inprogress" );
+ }
+
+ // Clear up the last queue stop function
+ delete hooks.stop;
+ fn.call( elem, next, hooks );
+ }
+
+ if ( !startLength && hooks ) {
+ hooks.empty.fire();
+ }
+ },
+
+ // Not public - generate a queueHooks object, or return the current one
+ _queueHooks: function( elem, type ) {
+ var key = type + "queueHooks";
+ return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
+ empty: jQuery.Callbacks( "once memory" ).add( function() {
+ dataPriv.remove( elem, [ type + "queue", key ] );
+ } )
+ } );
+ }
+} );
+
+jQuery.fn.extend( {
+ queue: function( type, data ) {
+ var setter = 2;
+
+ if ( typeof type !== "string" ) {
+ data = type;
+ type = "fx";
+ setter--;
+ }
+
+ if ( arguments.length < setter ) {
+ return jQuery.queue( this[ 0 ], type );
+ }
+
+ return data === undefined ?
+ this :
+ this.each( function() {
+ var queue = jQuery.queue( this, type, data );
+
+ // Ensure a hooks for this queue
+ jQuery._queueHooks( this, type );
+
+ if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
+ jQuery.dequeue( this, type );
+ }
+ } );
+ },
+ dequeue: function( type ) {
+ return this.each( function() {
+ jQuery.dequeue( this, type );
+ } );
+ },
+ clearQueue: function( type ) {
+ return this.queue( type || "fx", [] );
+ },
+
+ // Get a promise resolved when queues of a certain type
+ // are emptied (fx is the type by default)
+ promise: function( type, obj ) {
+ var tmp,
+ count = 1,
+ defer = jQuery.Deferred(),
+ elements = this,
+ i = this.length,
+ resolve = function() {
+ if ( !( --count ) ) {
+ defer.resolveWith( elements, [ elements ] );
+ }
+ };
+
+ if ( typeof type !== "string" ) {
+ obj = type;
+ type = undefined;
+ }
+ type = type || "fx";
+
+ while ( i-- ) {
+ tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
+ if ( tmp && tmp.empty ) {
+ count++;
+ tmp.empty.add( resolve );
+ }
+ }
+ resolve();
+ return defer.promise( obj );
+ }
+} );
+var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
+
+var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
+
+
+var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
+
+var isHiddenWithinTree = function( elem, el ) {
+
+ // isHiddenWithinTree might be called from jQuery#filter function;
+ // in that case, element will be second argument
+ elem = el || elem;
+
+ // Inline style trumps all
+ return elem.style.display === "none" ||
+ elem.style.display === "" &&
+
+ // Otherwise, check computed style
+ // Support: Firefox <=43 - 45
+ // Disconnected elements can have computed display: none, so first confirm that elem is
+ // in the document.
+ jQuery.contains( elem.ownerDocument, elem ) &&
+
+ jQuery.css( elem, "display" ) === "none";
+ };
+
+var swap = function( elem, options, callback, args ) {
+ var ret, name,
+ old = {};
+
+ // Remember the old values, and insert the new ones
+ for ( name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
+ }
+
+ ret = callback.apply( elem, args || [] );
+
+ // Revert the old values
+ for ( name in options ) {
+ elem.style[ name ] = old[ name ];
+ }
+
+ return ret;
+};
+
+
+
+
+function adjustCSS( elem, prop, valueParts, tween ) {
+ var adjusted, scale,
+ maxIterations = 20,
+ currentValue = tween ?
+ function() {
+ return tween.cur();
+ } :
+ function() {
+ return jQuery.css( elem, prop, "" );
+ },
+ initial = currentValue(),
+ unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
+
+ // Starting value computation is required for potential unit mismatches
+ initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
+ rcssNum.exec( jQuery.css( elem, prop ) );
+
+ if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
+
+ // Support: Firefox <=54
+ // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
+ initial = initial / 2;
+
+ // Trust units reported by jQuery.css
+ unit = unit || initialInUnit[ 3 ];
+
+ // Iteratively approximate from a nonzero starting point
+ initialInUnit = +initial || 1;
+
+ while ( maxIterations-- ) {
+
+ // Evaluate and update our best guess (doubling guesses that zero out).
+ // Finish if the scale equals or crosses 1 (making the old*new product non-positive).
+ jQuery.style( elem, prop, initialInUnit + unit );
+ if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
+ maxIterations = 0;
+ }
+ initialInUnit = initialInUnit / scale;
+
+ }
+
+ initialInUnit = initialInUnit * 2;
+ jQuery.style( elem, prop, initialInUnit + unit );
+
+ // Make sure we update the tween properties later on
+ valueParts = valueParts || [];
+ }
+
+ if ( valueParts ) {
+ initialInUnit = +initialInUnit || +initial || 0;
+
+ // Apply relative offset (+=/-=) if specified
+ adjusted = valueParts[ 1 ] ?
+ initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
+ +valueParts[ 2 ];
+ if ( tween ) {
+ tween.unit = unit;
+ tween.start = initialInUnit;
+ tween.end = adjusted;
+ }
+ }
+ return adjusted;
+}
+
+
+var defaultDisplayMap = {};
+
+function getDefaultDisplay( elem ) {
+ var temp,
+ doc = elem.ownerDocument,
+ nodeName = elem.nodeName,
+ display = defaultDisplayMap[ nodeName ];
+
+ if ( display ) {
+ return display;
+ }
+
+ temp = doc.body.appendChild( doc.createElement( nodeName ) );
+ display = jQuery.css( temp, "display" );
+
+ temp.parentNode.removeChild( temp );
+
+ if ( display === "none" ) {
+ display = "block";
+ }
+ defaultDisplayMap[ nodeName ] = display;
+
+ return display;
+}
+
+function showHide( elements, show ) {
+ var display, elem,
+ values = [],
+ index = 0,
+ length = elements.length;
+
+ // Determine new display value for elements that need to change
+ for ( ; index < length; index++ ) {
+ elem = elements[ index ];
+ if ( !elem.style ) {
+ continue;
+ }
+
+ display = elem.style.display;
+ if ( show ) {
+
+ // Since we force visibility upon cascade-hidden elements, an immediate (and slow)
+ // check is required in this first loop unless we have a nonempty display value (either
+ // inline or about-to-be-restored)
+ if ( display === "none" ) {
+ values[ index ] = dataPriv.get( elem, "display" ) || null;
+ if ( !values[ index ] ) {
+ elem.style.display = "";
+ }
+ }
+ if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
+ values[ index ] = getDefaultDisplay( elem );
+ }
+ } else {
+ if ( display !== "none" ) {
+ values[ index ] = "none";
+
+ // Remember what we're overwriting
+ dataPriv.set( elem, "display", display );
+ }
+ }
+ }
+
+ // Set the display of the elements in a second loop to avoid constant reflow
+ for ( index = 0; index < length; index++ ) {
+ if ( values[ index ] != null ) {
+ elements[ index ].style.display = values[ index ];
+ }
+ }
+
+ return elements;
+}
+
+jQuery.fn.extend( {
+ show: function() {
+ return showHide( this, true );
+ },
+ hide: function() {
+ return showHide( this );
+ },
+ toggle: function( state ) {
+ if ( typeof state === "boolean" ) {
+ return state ? this.show() : this.hide();
+ }
+
+ return this.each( function() {
+ if ( isHiddenWithinTree( this ) ) {
+ jQuery( this ).show();
+ } else {
+ jQuery( this ).hide();
+ }
+ } );
+ }
+} );
+var rcheckableType = ( /^(?:checkbox|radio)$/i );
+
+var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
+
+var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
+
+
+
+// We have to close these tags to support XHTML (#13200)
+var wrapMap = {
+
+ // Support: IE <=9 only
+ option: [ 1, "", " " ],
+
+ // XHTML parsers do not magically insert elements in the
+ // same way that tag soup parsers do. So we cannot shorten
+ // this by omitting or other required elements.
+ thead: [ 1, "" ],
+ col: [ 2, "" ],
+ tr: [ 2, "" ],
+ td: [ 3, "" ],
+
+ _default: [ 0, "", "" ]
+};
+
+// Support: IE <=9 only
+wrapMap.optgroup = wrapMap.option;
+
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+
+function getAll( context, tag ) {
+
+ // Support: IE <=9 - 11 only
+ // Use typeof to avoid zero-argument method invocation on host objects (#15151)
+ var ret;
+
+ if ( typeof context.getElementsByTagName !== "undefined" ) {
+ ret = context.getElementsByTagName( tag || "*" );
+
+ } else if ( typeof context.querySelectorAll !== "undefined" ) {
+ ret = context.querySelectorAll( tag || "*" );
+
+ } else {
+ ret = [];
+ }
+
+ if ( tag === undefined || tag && nodeName( context, tag ) ) {
+ return jQuery.merge( [ context ], ret );
+ }
+
+ return ret;
+}
+
+
+// Mark scripts as having already been evaluated
+function setGlobalEval( elems, refElements ) {
+ var i = 0,
+ l = elems.length;
+
+ for ( ; i < l; i++ ) {
+ dataPriv.set(
+ elems[ i ],
+ "globalEval",
+ !refElements || dataPriv.get( refElements[ i ], "globalEval" )
+ );
+ }
+}
+
+
+var rhtml = /<|?\w+;/;
+
+function buildFragment( elems, context, scripts, selection, ignored ) {
+ var elem, tmp, tag, wrap, contains, j,
+ fragment = context.createDocumentFragment(),
+ nodes = [],
+ i = 0,
+ l = elems.length;
+
+ for ( ; i < l; i++ ) {
+ elem = elems[ i ];
+
+ if ( elem || elem === 0 ) {
+
+ // Add nodes directly
+ if ( toType( elem ) === "object" ) {
+
+ // Support: Android <=4.0 only, PhantomJS 1 only
+ // push.apply(_, arraylike) throws on ancient WebKit
+ jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
+
+ // Convert non-html into a text node
+ } else if ( !rhtml.test( elem ) ) {
+ nodes.push( context.createTextNode( elem ) );
+
+ // Convert html into DOM nodes
+ } else {
+ tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
+
+ // Deserialize a standard representation
+ tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
+ wrap = wrapMap[ tag ] || wrapMap._default;
+ tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
+
+ // Descend through wrappers to the right content
+ j = wrap[ 0 ];
+ while ( j-- ) {
+ tmp = tmp.lastChild;
+ }
+
+ // Support: Android <=4.0 only, PhantomJS 1 only
+ // push.apply(_, arraylike) throws on ancient WebKit
+ jQuery.merge( nodes, tmp.childNodes );
+
+ // Remember the top-level container
+ tmp = fragment.firstChild;
+
+ // Ensure the created nodes are orphaned (#12392)
+ tmp.textContent = "";
+ }
+ }
+ }
+
+ // Remove wrapper from fragment
+ fragment.textContent = "";
+
+ i = 0;
+ while ( ( elem = nodes[ i++ ] ) ) {
+
+ // Skip elements already in the context collection (trac-4087)
+ if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
+ if ( ignored ) {
+ ignored.push( elem );
+ }
+ continue;
+ }
+
+ contains = jQuery.contains( elem.ownerDocument, elem );
+
+ // Append to fragment
+ tmp = getAll( fragment.appendChild( elem ), "script" );
+
+ // Preserve script evaluation history
+ if ( contains ) {
+ setGlobalEval( tmp );
+ }
+
+ // Capture executables
+ if ( scripts ) {
+ j = 0;
+ while ( ( elem = tmp[ j++ ] ) ) {
+ if ( rscriptType.test( elem.type || "" ) ) {
+ scripts.push( elem );
+ }
+ }
+ }
+ }
+
+ return fragment;
+}
+
+
+( function() {
+ var fragment = document.createDocumentFragment(),
+ div = fragment.appendChild( document.createElement( "div" ) ),
+ input = document.createElement( "input" );
+
+ // Support: Android 4.0 - 4.3 only
+ // Check state lost if the name is set (#11217)
+ // Support: Windows Web Apps (WWA)
+ // `name` and `type` must use .setAttribute for WWA (#14901)
+ input.setAttribute( "type", "radio" );
+ input.setAttribute( "checked", "checked" );
+ input.setAttribute( "name", "t" );
+
+ div.appendChild( input );
+
+ // Support: Android <=4.1 only
+ // Older WebKit doesn't clone checked state correctly in fragments
+ support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+ // Support: IE <=11 only
+ // Make sure textarea (and checkbox) defaultValue is properly cloned
+ div.innerHTML = "";
+ support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
+} )();
+var documentElement = document.documentElement;
+
+
+
+var
+ rkeyEvent = /^key/,
+ rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
+ rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
+
+function returnTrue() {
+ return true;
+}
+
+function returnFalse() {
+ return false;
+}
+
+// Support: IE <=9 only
+// See #13393 for more info
+function safeActiveElement() {
+ try {
+ return document.activeElement;
+ } catch ( err ) { }
+}
+
+function on( elem, types, selector, data, fn, one ) {
+ var origFn, type;
+
+ // Types can be a map of types/handlers
+ if ( typeof types === "object" ) {
+
+ // ( types-Object, selector, data )
+ if ( typeof selector !== "string" ) {
+
+ // ( types-Object, data )
+ data = data || selector;
+ selector = undefined;
+ }
+ for ( type in types ) {
+ on( elem, type, selector, data, types[ type ], one );
+ }
+ return elem;
+ }
+
+ if ( data == null && fn == null ) {
+
+ // ( types, fn )
+ fn = selector;
+ data = selector = undefined;
+ } else if ( fn == null ) {
+ if ( typeof selector === "string" ) {
+
+ // ( types, selector, fn )
+ fn = data;
+ data = undefined;
+ } else {
+
+ // ( types, data, fn )
+ fn = data;
+ data = selector;
+ selector = undefined;
+ }
+ }
+ if ( fn === false ) {
+ fn = returnFalse;
+ } else if ( !fn ) {
+ return elem;
+ }
+
+ if ( one === 1 ) {
+ origFn = fn;
+ fn = function( event ) {
+
+ // Can use an empty set, since event contains the info
+ jQuery().off( event );
+ return origFn.apply( this, arguments );
+ };
+
+ // Use same guid so caller can remove using origFn
+ fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
+ }
+ return elem.each( function() {
+ jQuery.event.add( this, types, fn, data, selector );
+ } );
+}
+
+/*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+jQuery.event = {
+
+ global: {},
+
+ add: function( elem, types, handler, data, selector ) {
+
+ var handleObjIn, eventHandle, tmp,
+ events, t, handleObj,
+ special, handlers, type, namespaces, origType,
+ elemData = dataPriv.get( elem );
+
+ // Don't attach events to noData or text/comment nodes (but allow plain objects)
+ if ( !elemData ) {
+ return;
+ }
+
+ // Caller can pass in an object of custom data in lieu of the handler
+ if ( handler.handler ) {
+ handleObjIn = handler;
+ handler = handleObjIn.handler;
+ selector = handleObjIn.selector;
+ }
+
+ // Ensure that invalid selectors throw exceptions at attach time
+ // Evaluate against documentElement in case elem is a non-element node (e.g., document)
+ if ( selector ) {
+ jQuery.find.matchesSelector( documentElement, selector );
+ }
+
+ // Make sure that the handler has a unique ID, used to find/remove it later
+ if ( !handler.guid ) {
+ handler.guid = jQuery.guid++;
+ }
+
+ // Init the element's event structure and main handler, if this is the first
+ if ( !( events = elemData.events ) ) {
+ events = elemData.events = {};
+ }
+ if ( !( eventHandle = elemData.handle ) ) {
+ eventHandle = elemData.handle = function( e ) {
+
+ // Discard the second event of a jQuery.event.trigger() and
+ // when an event is called after a page has unloaded
+ return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
+ jQuery.event.dispatch.apply( elem, arguments ) : undefined;
+ };
+ }
+
+ // Handle multiple events separated by a space
+ types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
+ t = types.length;
+ while ( t-- ) {
+ tmp = rtypenamespace.exec( types[ t ] ) || [];
+ type = origType = tmp[ 1 ];
+ namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
+
+ // There *must* be a type, no attaching namespace-only handlers
+ if ( !type ) {
+ continue;
+ }
+
+ // If event changes its type, use the special event handlers for the changed type
+ special = jQuery.event.special[ type ] || {};
+
+ // If selector defined, determine special event api type, otherwise given type
+ type = ( selector ? special.delegateType : special.bindType ) || type;
+
+ // Update special based on newly reset type
+ special = jQuery.event.special[ type ] || {};
+
+ // handleObj is passed to all event handlers
+ handleObj = jQuery.extend( {
+ type: type,
+ origType: origType,
+ data: data,
+ handler: handler,
+ guid: handler.guid,
+ selector: selector,
+ needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
+ namespace: namespaces.join( "." )
+ }, handleObjIn );
+
+ // Init the event handler queue if we're the first
+ if ( !( handlers = events[ type ] ) ) {
+ handlers = events[ type ] = [];
+ handlers.delegateCount = 0;
+
+ // Only use addEventListener if the special events handler returns false
+ if ( !special.setup ||
+ special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+
+ if ( elem.addEventListener ) {
+ elem.addEventListener( type, eventHandle );
+ }
+ }
+ }
+
+ if ( special.add ) {
+ special.add.call( elem, handleObj );
+
+ if ( !handleObj.handler.guid ) {
+ handleObj.handler.guid = handler.guid;
+ }
+ }
+
+ // Add to the element's handler list, delegates in front
+ if ( selector ) {
+ handlers.splice( handlers.delegateCount++, 0, handleObj );
+ } else {
+ handlers.push( handleObj );
+ }
+
+ // Keep track of which events have ever been used, for event optimization
+ jQuery.event.global[ type ] = true;
+ }
+
+ },
+
+ // Detach an event or set of events from an element
+ remove: function( elem, types, handler, selector, mappedTypes ) {
+
+ var j, origCount, tmp,
+ events, t, handleObj,
+ special, handlers, type, namespaces, origType,
+ elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
+
+ if ( !elemData || !( events = elemData.events ) ) {
+ return;
+ }
+
+ // Once for each type.namespace in types; type may be omitted
+ types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
+ t = types.length;
+ while ( t-- ) {
+ tmp = rtypenamespace.exec( types[ t ] ) || [];
+ type = origType = tmp[ 1 ];
+ namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
+
+ // Unbind all events (on this namespace, if provided) for the element
+ if ( !type ) {
+ for ( type in events ) {
+ jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
+ }
+ continue;
+ }
+
+ special = jQuery.event.special[ type ] || {};
+ type = ( selector ? special.delegateType : special.bindType ) || type;
+ handlers = events[ type ] || [];
+ tmp = tmp[ 2 ] &&
+ new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
+
+ // Remove matching events
+ origCount = j = handlers.length;
+ while ( j-- ) {
+ handleObj = handlers[ j ];
+
+ if ( ( mappedTypes || origType === handleObj.origType ) &&
+ ( !handler || handler.guid === handleObj.guid ) &&
+ ( !tmp || tmp.test( handleObj.namespace ) ) &&
+ ( !selector || selector === handleObj.selector ||
+ selector === "**" && handleObj.selector ) ) {
+ handlers.splice( j, 1 );
+
+ if ( handleObj.selector ) {
+ handlers.delegateCount--;
+ }
+ if ( special.remove ) {
+ special.remove.call( elem, handleObj );
+ }
+ }
+ }
+
+ // Remove generic event handler if we removed something and no more handlers exist
+ // (avoids potential for endless recursion during removal of special event handlers)
+ if ( origCount && !handlers.length ) {
+ if ( !special.teardown ||
+ special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+
+ jQuery.removeEvent( elem, type, elemData.handle );
+ }
+
+ delete events[ type ];
+ }
+ }
+
+ // Remove data and the expando if it's no longer used
+ if ( jQuery.isEmptyObject( events ) ) {
+ dataPriv.remove( elem, "handle events" );
+ }
+ },
+
+ dispatch: function( nativeEvent ) {
+
+ // Make a writable jQuery.Event from the native event object
+ var event = jQuery.event.fix( nativeEvent );
+
+ var i, j, ret, matched, handleObj, handlerQueue,
+ args = new Array( arguments.length ),
+ handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
+ special = jQuery.event.special[ event.type ] || {};
+
+ // Use the fix-ed jQuery.Event rather than the (read-only) native event
+ args[ 0 ] = event;
+
+ for ( i = 1; i < arguments.length; i++ ) {
+ args[ i ] = arguments[ i ];
+ }
+
+ event.delegateTarget = this;
+
+ // Call the preDispatch hook for the mapped type, and let it bail if desired
+ if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
+ return;
+ }
+
+ // Determine handlers
+ handlerQueue = jQuery.event.handlers.call( this, event, handlers );
+
+ // Run delegates first; they may want to stop propagation beneath us
+ i = 0;
+ while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
+ event.currentTarget = matched.elem;
+
+ j = 0;
+ while ( ( handleObj = matched.handlers[ j++ ] ) &&
+ !event.isImmediatePropagationStopped() ) {
+
+ // Triggered event must either 1) have no namespace, or 2) have namespace(s)
+ // a subset or equal to those in the bound event (both can have no namespace).
+ if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
+
+ event.handleObj = handleObj;
+ event.data = handleObj.data;
+
+ ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
+ handleObj.handler ).apply( matched.elem, args );
+
+ if ( ret !== undefined ) {
+ if ( ( event.result = ret ) === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+ }
+ }
+ }
+
+ // Call the postDispatch hook for the mapped type
+ if ( special.postDispatch ) {
+ special.postDispatch.call( this, event );
+ }
+
+ return event.result;
+ },
+
+ handlers: function( event, handlers ) {
+ var i, handleObj, sel, matchedHandlers, matchedSelectors,
+ handlerQueue = [],
+ delegateCount = handlers.delegateCount,
+ cur = event.target;
+
+ // Find delegate handlers
+ if ( delegateCount &&
+
+ // Support: IE <=9
+ // Black-hole SVG instance trees (trac-13180)
+ cur.nodeType &&
+
+ // Support: Firefox <=42
+ // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
+ // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
+ // Support: IE 11 only
+ // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
+ !( event.type === "click" && event.button >= 1 ) ) {
+
+ for ( ; cur !== this; cur = cur.parentNode || this ) {
+
+ // Don't check non-elements (#13208)
+ // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
+ if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
+ matchedHandlers = [];
+ matchedSelectors = {};
+ for ( i = 0; i < delegateCount; i++ ) {
+ handleObj = handlers[ i ];
+
+ // Don't conflict with Object.prototype properties (#13203)
+ sel = handleObj.selector + " ";
+
+ if ( matchedSelectors[ sel ] === undefined ) {
+ matchedSelectors[ sel ] = handleObj.needsContext ?
+ jQuery( sel, this ).index( cur ) > -1 :
+ jQuery.find( sel, this, null, [ cur ] ).length;
+ }
+ if ( matchedSelectors[ sel ] ) {
+ matchedHandlers.push( handleObj );
+ }
+ }
+ if ( matchedHandlers.length ) {
+ handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
+ }
+ }
+ }
+ }
+
+ // Add the remaining (directly-bound) handlers
+ cur = this;
+ if ( delegateCount < handlers.length ) {
+ handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
+ }
+
+ return handlerQueue;
+ },
+
+ addProp: function( name, hook ) {
+ Object.defineProperty( jQuery.Event.prototype, name, {
+ enumerable: true,
+ configurable: true,
+
+ get: isFunction( hook ) ?
+ function() {
+ if ( this.originalEvent ) {
+ return hook( this.originalEvent );
+ }
+ } :
+ function() {
+ if ( this.originalEvent ) {
+ return this.originalEvent[ name ];
+ }
+ },
+
+ set: function( value ) {
+ Object.defineProperty( this, name, {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: value
+ } );
+ }
+ } );
+ },
+
+ fix: function( originalEvent ) {
+ return originalEvent[ jQuery.expando ] ?
+ originalEvent :
+ new jQuery.Event( originalEvent );
+ },
+
+ special: {
+ load: {
+
+ // Prevent triggered image.load events from bubbling to window.load
+ noBubble: true
+ },
+ focus: {
+
+ // Fire native event if possible so blur/focus sequence is correct
+ trigger: function() {
+ if ( this !== safeActiveElement() && this.focus ) {
+ this.focus();
+ return false;
+ }
+ },
+ delegateType: "focusin"
+ },
+ blur: {
+ trigger: function() {
+ if ( this === safeActiveElement() && this.blur ) {
+ this.blur();
+ return false;
+ }
+ },
+ delegateType: "focusout"
+ },
+ click: {
+
+ // For checkbox, fire native event so checked state will be right
+ trigger: function() {
+ if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {
+ this.click();
+ return false;
+ }
+ },
+
+ // For cross-browser consistency, don't fire native .click() on links
+ _default: function( event ) {
+ return nodeName( event.target, "a" );
+ }
+ },
+
+ beforeunload: {
+ postDispatch: function( event ) {
+
+ // Support: Firefox 20+
+ // Firefox doesn't alert if the returnValue field is not set.
+ if ( event.result !== undefined && event.originalEvent ) {
+ event.originalEvent.returnValue = event.result;
+ }
+ }
+ }
+ }
+};
+
+jQuery.removeEvent = function( elem, type, handle ) {
+
+ // This "if" is needed for plain objects
+ if ( elem.removeEventListener ) {
+ elem.removeEventListener( type, handle );
+ }
+};
+
+jQuery.Event = function( src, props ) {
+
+ // Allow instantiation without the 'new' keyword
+ if ( !( this instanceof jQuery.Event ) ) {
+ return new jQuery.Event( src, props );
+ }
+
+ // Event object
+ if ( src && src.type ) {
+ this.originalEvent = src;
+ this.type = src.type;
+
+ // Events bubbling up the document may have been marked as prevented
+ // by a handler lower down the tree; reflect the correct value.
+ this.isDefaultPrevented = src.defaultPrevented ||
+ src.defaultPrevented === undefined &&
+
+ // Support: Android <=2.3 only
+ src.returnValue === false ?
+ returnTrue :
+ returnFalse;
+
+ // Create target properties
+ // Support: Safari <=6 - 7 only
+ // Target should not be a text node (#504, #13143)
+ this.target = ( src.target && src.target.nodeType === 3 ) ?
+ src.target.parentNode :
+ src.target;
+
+ this.currentTarget = src.currentTarget;
+ this.relatedTarget = src.relatedTarget;
+
+ // Event type
+ } else {
+ this.type = src;
+ }
+
+ // Put explicitly provided properties onto the event object
+ if ( props ) {
+ jQuery.extend( this, props );
+ }
+
+ // Create a timestamp if incoming event doesn't have one
+ this.timeStamp = src && src.timeStamp || Date.now();
+
+ // Mark it as fixed
+ this[ jQuery.expando ] = true;
+};
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+ constructor: jQuery.Event,
+ isDefaultPrevented: returnFalse,
+ isPropagationStopped: returnFalse,
+ isImmediatePropagationStopped: returnFalse,
+ isSimulated: false,
+
+ preventDefault: function() {
+ var e = this.originalEvent;
+
+ this.isDefaultPrevented = returnTrue;
+
+ if ( e && !this.isSimulated ) {
+ e.preventDefault();
+ }
+ },
+ stopPropagation: function() {
+ var e = this.originalEvent;
+
+ this.isPropagationStopped = returnTrue;
+
+ if ( e && !this.isSimulated ) {
+ e.stopPropagation();
+ }
+ },
+ stopImmediatePropagation: function() {
+ var e = this.originalEvent;
+
+ this.isImmediatePropagationStopped = returnTrue;
+
+ if ( e && !this.isSimulated ) {
+ e.stopImmediatePropagation();
+ }
+
+ this.stopPropagation();
+ }
+};
+
+// Includes all common event props including KeyEvent and MouseEvent specific props
+jQuery.each( {
+ altKey: true,
+ bubbles: true,
+ cancelable: true,
+ changedTouches: true,
+ ctrlKey: true,
+ detail: true,
+ eventPhase: true,
+ metaKey: true,
+ pageX: true,
+ pageY: true,
+ shiftKey: true,
+ view: true,
+ "char": true,
+ charCode: true,
+ key: true,
+ keyCode: true,
+ button: true,
+ buttons: true,
+ clientX: true,
+ clientY: true,
+ offsetX: true,
+ offsetY: true,
+ pointerId: true,
+ pointerType: true,
+ screenX: true,
+ screenY: true,
+ targetTouches: true,
+ toElement: true,
+ touches: true,
+
+ which: function( event ) {
+ var button = event.button;
+
+ // Add which for key events
+ if ( event.which == null && rkeyEvent.test( event.type ) ) {
+ return event.charCode != null ? event.charCode : event.keyCode;
+ }
+
+ // Add which for click: 1 === left; 2 === middle; 3 === right
+ if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
+ if ( button & 1 ) {
+ return 1;
+ }
+
+ if ( button & 2 ) {
+ return 3;
+ }
+
+ if ( button & 4 ) {
+ return 2;
+ }
+
+ return 0;
+ }
+
+ return event.which;
+ }
+}, jQuery.event.addProp );
+
+// Create mouseenter/leave events using mouseover/out and event-time checks
+// so that event delegation works in jQuery.
+// Do the same for pointerenter/pointerleave and pointerover/pointerout
+//
+// Support: Safari 7 only
+// Safari sends mouseenter too often; see:
+// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
+// for the description of the bug (it existed in older Chrome versions as well).
+jQuery.each( {
+ mouseenter: "mouseover",
+ mouseleave: "mouseout",
+ pointerenter: "pointerover",
+ pointerleave: "pointerout"
+}, function( orig, fix ) {
+ jQuery.event.special[ orig ] = {
+ delegateType: fix,
+ bindType: fix,
+
+ handle: function( event ) {
+ var ret,
+ target = this,
+ related = event.relatedTarget,
+ handleObj = event.handleObj;
+
+ // For mouseenter/leave call the handler if related is outside the target.
+ // NB: No relatedTarget if the mouse left/entered the browser window
+ if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
+ event.type = handleObj.origType;
+ ret = handleObj.handler.apply( this, arguments );
+ event.type = fix;
+ }
+ return ret;
+ }
+ };
+} );
+
+jQuery.fn.extend( {
+
+ on: function( types, selector, data, fn ) {
+ return on( this, types, selector, data, fn );
+ },
+ one: function( types, selector, data, fn ) {
+ return on( this, types, selector, data, fn, 1 );
+ },
+ off: function( types, selector, fn ) {
+ var handleObj, type;
+ if ( types && types.preventDefault && types.handleObj ) {
+
+ // ( event ) dispatched jQuery.Event
+ handleObj = types.handleObj;
+ jQuery( types.delegateTarget ).off(
+ handleObj.namespace ?
+ handleObj.origType + "." + handleObj.namespace :
+ handleObj.origType,
+ handleObj.selector,
+ handleObj.handler
+ );
+ return this;
+ }
+ if ( typeof types === "object" ) {
+
+ // ( types-object [, selector] )
+ for ( type in types ) {
+ this.off( type, selector, types[ type ] );
+ }
+ return this;
+ }
+ if ( selector === false || typeof selector === "function" ) {
+
+ // ( types [, fn] )
+ fn = selector;
+ selector = undefined;
+ }
+ if ( fn === false ) {
+ fn = returnFalse;
+ }
+ return this.each( function() {
+ jQuery.event.remove( this, types, fn, selector );
+ } );
+ }
+} );
+
+
+var
+
+ /* eslint-disable max-len */
+
+ // See https://github.com/eslint/eslint/issues/3229
+ rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
+
+ /* eslint-enable */
+
+ // Support: IE <=10 - 11, Edge 12 - 13 only
+ // In IE/Edge using regex groups here causes severe slowdowns.
+ // See https://connect.microsoft.com/IE/feedback/details/1736512/
+ rnoInnerhtml = /
+
+
+
+
+
+
+APL mode
+
+
+
+
+ Simple mode that tries to handle APL as well as it can.
+ It attempts to label functions/operators based upon
+ monadic/dyadic usage (but this is far from fully fleshed out).
+ This means there are meaningful classnames so hover states can
+ have popups etc.
+
+ MIME types defined: text/apl
(APL code)
+
diff --git a/static/mdeditor/js/lib/codemirror/mode/asterisk/asterisk.js b/static/mdeditor/js/lib/codemirror/mode/asterisk/asterisk.js
new file mode 100644
index 0000000..a1ead11
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/asterisk/asterisk.js
@@ -0,0 +1,198 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+/*
+ * =====================================================================================
+ *
+ * Filename: mode/asterisk/asterisk.js
+ *
+ * Description: CodeMirror mode for Asterisk dialplan
+ *
+ * Created: 05/17/2012 09:20:25 PM
+ * Revision: none
+ *
+ * Author: Stas Kobzar (stas@modulis.ca),
+ * Company: Modulis.ca Inc.
+ *
+ * =====================================================================================
+ */
+
+(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) {
+"use strict";
+
+CodeMirror.defineMode("asterisk", function() {
+ var atoms = ["exten", "same", "include","ignorepat","switch"],
+ dpcmd = ["#include","#exec"],
+ apps = [
+ "addqueuemember","adsiprog","aelsub","agentlogin","agentmonitoroutgoing","agi",
+ "alarmreceiver","amd","answer","authenticate","background","backgrounddetect",
+ "bridge","busy","callcompletioncancel","callcompletionrequest","celgenuserevent",
+ "changemonitor","chanisavail","channelredirect","chanspy","clearhash","confbridge",
+ "congestion","continuewhile","controlplayback","dahdiacceptr2call","dahdibarge",
+ "dahdiras","dahdiscan","dahdisendcallreroutingfacility","dahdisendkeypadfacility",
+ "datetime","dbdel","dbdeltree","deadagi","dial","dictate","directory","disa",
+ "dumpchan","eagi","echo","endwhile","exec","execif","execiftime","exitwhile","extenspy",
+ "externalivr","festival","flash","followme","forkcdr","getcpeid","gosub","gosubif",
+ "goto","gotoif","gotoiftime","hangup","iax2provision","ices","importvar","incomplete",
+ "ivrdemo","jabberjoin","jabberleave","jabbersend","jabbersendgroup","jabberstatus",
+ "jack","log","macro","macroexclusive","macroexit","macroif","mailboxexists","meetme",
+ "meetmeadmin","meetmechanneladmin","meetmecount","milliwatt","minivmaccmess","minivmdelete",
+ "minivmgreet","minivmmwi","minivmnotify","minivmrecord","mixmonitor","monitor","morsecode",
+ "mp3player","mset","musiconhold","nbscat","nocdr","noop","odbc","odbc","odbcfinish",
+ "originate","ospauth","ospfinish","osplookup","ospnext","page","park","parkandannounce",
+ "parkedcall","pausemonitor","pausequeuemember","pickup","pickupchan","playback","playtones",
+ "privacymanager","proceeding","progress","queue","queuelog","raiseexception","read","readexten",
+ "readfile","receivefax","receivefax","receivefax","record","removequeuemember",
+ "resetcdr","retrydial","return","ringing","sayalpha","saycountedadj","saycountednoun",
+ "saycountpl","saydigits","saynumber","sayphonetic","sayunixtime","senddtmf","sendfax",
+ "sendfax","sendfax","sendimage","sendtext","sendurl","set","setamaflags",
+ "setcallerpres","setmusiconhold","sipaddheader","sipdtmfmode","sipremoveheader","skel",
+ "slastation","slatrunk","sms","softhangup","speechactivategrammar","speechbackground",
+ "speechcreate","speechdeactivategrammar","speechdestroy","speechloadgrammar","speechprocessingsound",
+ "speechstart","speechunloadgrammar","stackpop","startmusiconhold","stopmixmonitor","stopmonitor",
+ "stopmusiconhold","stopplaytones","system","testclient","testserver","transfer","tryexec",
+ "trysystem","unpausemonitor","unpausequeuemember","userevent","verbose","vmauthenticate",
+ "vmsayname","voicemail","voicemailmain","wait","waitexten","waitfornoise","waitforring",
+ "waitforsilence","waitmusiconhold","waituntil","while","zapateller"
+ ];
+
+ function basicToken(stream,state){
+ var cur = '';
+ var ch = '';
+ ch = stream.next();
+ // comment
+ if(ch == ";") {
+ stream.skipToEnd();
+ return "comment";
+ }
+ // context
+ if(ch == '[') {
+ stream.skipTo(']');
+ stream.eat(']');
+ return "header";
+ }
+ // string
+ if(ch == '"') {
+ stream.skipTo('"');
+ return "string";
+ }
+ if(ch == "'") {
+ stream.skipTo("'");
+ return "string-2";
+ }
+ // dialplan commands
+ if(ch == '#') {
+ stream.eatWhile(/\w/);
+ cur = stream.current();
+ if(dpcmd.indexOf(cur) !== -1) {
+ stream.skipToEnd();
+ return "strong";
+ }
+ }
+ // application args
+ if(ch == '$'){
+ var ch1 = stream.peek();
+ if(ch1 == '{'){
+ stream.skipTo('}');
+ stream.eat('}');
+ return "variable-3";
+ }
+ }
+ // extension
+ stream.eatWhile(/\w/);
+ cur = stream.current();
+ if(atoms.indexOf(cur) !== -1) {
+ state.extenStart = true;
+ switch(cur) {
+ case 'same': state.extenSame = true; break;
+ case 'include':
+ case 'switch':
+ case 'ignorepat':
+ state.extenInclude = true;break;
+ default:break;
+ }
+ return "atom";
+ }
+ }
+
+ return {
+ startState: function() {
+ return {
+ extenStart: false,
+ extenSame: false,
+ extenInclude: false,
+ extenExten: false,
+ extenPriority: false,
+ extenApplication: false
+ };
+ },
+ token: function(stream, state) {
+
+ var cur = '';
+ var ch = '';
+ if(stream.eatSpace()) return null;
+ // extension started
+ if(state.extenStart){
+ stream.eatWhile(/[^\s]/);
+ cur = stream.current();
+ if(/^=>?$/.test(cur)){
+ state.extenExten = true;
+ state.extenStart = false;
+ return "strong";
+ } else {
+ state.extenStart = false;
+ stream.skipToEnd();
+ return "error";
+ }
+ } else if(state.extenExten) {
+ // set exten and priority
+ state.extenExten = false;
+ state.extenPriority = true;
+ stream.eatWhile(/[^,]/);
+ if(state.extenInclude) {
+ stream.skipToEnd();
+ state.extenPriority = false;
+ state.extenInclude = false;
+ }
+ if(state.extenSame) {
+ state.extenPriority = false;
+ state.extenSame = false;
+ state.extenApplication = true;
+ }
+ return "tag";
+ } else if(state.extenPriority) {
+ state.extenPriority = false;
+ state.extenApplication = true;
+ ch = stream.next(); // get comma
+ if(state.extenSame) return null;
+ stream.eatWhile(/[^,]/);
+ return "number";
+ } else if(state.extenApplication) {
+ stream.eatWhile(/,/);
+ cur = stream.current();
+ if(cur === ',') return null;
+ stream.eatWhile(/\w/);
+ cur = stream.current().toLowerCase();
+ state.extenApplication = false;
+ if(apps.indexOf(cur) !== -1){
+ return "def strong";
+ }
+ } else{
+ return basicToken(stream,state);
+ }
+
+ return null;
+ }
+ };
+});
+
+CodeMirror.defineMIME("text/x-asterisk", "asterisk");
+
+});
diff --git a/static/mdeditor/js/lib/codemirror/mode/asterisk/index.html b/static/mdeditor/js/lib/codemirror/mode/asterisk/index.html
new file mode 100644
index 0000000..257bd39
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/asterisk/index.html
@@ -0,0 +1,154 @@
+
+
+CodeMirror: Asterisk dialplan mode
+
+
+
+
+
+
+
+
+
+
+Asterisk dialplan mode
+
+; extensions.conf - the Asterisk dial plan
+;
+
+[general]
+;
+; If static is set to no, or omitted, then the pbx_config will rewrite
+; this file when extensions are modified. Remember that all comments
+; made in the file will be lost when that happens.
+static=yes
+
+#include "/etc/asterisk/additional_general.conf
+
+[iaxprovider]
+switch => IAX2/user:[key]@myserver/mycontext
+
+[dynamic]
+#exec /usr/bin/dynamic-peers.pl
+
+[trunkint]
+;
+; International long distance through trunk
+;
+exten => _9011.,1,Macro(dundi-e164,${EXTEN:4})
+exten => _9011.,n,Dial(${GLOBAL(TRUNK)}/${FILTER(0-9,${EXTEN:${GLOBAL(TRUNKMSD)}})})
+
+[local]
+;
+; Master context for local, toll-free, and iaxtel calls only
+;
+ignorepat => 9
+include => default
+
+[demo]
+include => stdexten
+;
+; We start with what to do when a call first comes in.
+;
+exten => s,1,Wait(1) ; Wait a second, just for fun
+same => n,Answer ; Answer the line
+same => n,Set(TIMEOUT(digit)=5) ; Set Digit Timeout to 5 seconds
+same => n,Set(TIMEOUT(response)=10) ; Set Response Timeout to 10 seconds
+same => n(restart),BackGround(demo-congrats) ; Play a congratulatory message
+same => n(instruct),BackGround(demo-instruct) ; Play some instructions
+same => n,WaitExten ; Wait for an extension to be dialed.
+
+exten => 2,1,BackGround(demo-moreinfo) ; Give some more information.
+exten => 2,n,Goto(s,instruct)
+
+exten => 3,1,Set(LANGUAGE()=fr) ; Set language to french
+exten => 3,n,Goto(s,restart) ; Start with the congratulations
+
+exten => 1000,1,Goto(default,s,1)
+;
+; We also create an example user, 1234, who is on the console and has
+; voicemail, etc.
+;
+exten => 1234,1,Playback(transfer,skip) ; "Please hold while..."
+ ; (but skip if channel is not up)
+exten => 1234,n,Gosub(${EXTEN},stdexten(${GLOBAL(CONSOLE)}))
+exten => 1234,n,Goto(default,s,1) ; exited Voicemail
+
+exten => 1235,1,Voicemail(1234,u) ; Right to voicemail
+
+exten => 1236,1,Dial(Console/dsp) ; Ring forever
+exten => 1236,n,Voicemail(1234,b) ; Unless busy
+
+;
+; # for when they're done with the demo
+;
+exten => #,1,Playback(demo-thanks) ; "Thanks for trying the demo"
+exten => #,n,Hangup ; Hang them up.
+
+;
+; A timeout and "invalid extension rule"
+;
+exten => t,1,Goto(#,1) ; If they take too long, give up
+exten => i,1,Playback(invalid) ; "That's not valid, try again"
+
+;
+; Create an extension, 500, for dialing the
+; Asterisk demo.
+;
+exten => 500,1,Playback(demo-abouttotry); Let them know what's going on
+exten => 500,n,Dial(IAX2/guest@pbx.digium.com/s@default) ; Call the Asterisk demo
+exten => 500,n,Playback(demo-nogo) ; Couldn't connect to the demo site
+exten => 500,n,Goto(s,6) ; Return to the start over message.
+
+;
+; Create an extension, 600, for evaluating echo latency.
+;
+exten => 600,1,Playback(demo-echotest) ; Let them know what's going on
+exten => 600,n,Echo ; Do the echo test
+exten => 600,n,Playback(demo-echodone) ; Let them know it's over
+exten => 600,n,Goto(s,6) ; Start over
+
+;
+; You can use the Macro Page to intercom a individual user
+exten => 76245,1,Macro(page,SIP/Grandstream1)
+; or if your peernames are the same as extensions
+exten => _7XXX,1,Macro(page,SIP/${EXTEN})
+;
+;
+; System Wide Page at extension 7999
+;
+exten => 7999,1,Set(TIMEOUT(absolute)=60)
+exten => 7999,2,Page(Local/Grandstream1@page&Local/Xlite1@page&Local/1234@page/n,d)
+
+; Give voicemail at extension 8500
+;
+exten => 8500,1,VoicemailMain
+exten => 8500,n,Goto(s,6)
+
+
+
+
+ MIME types defined: text/x-asterisk
.
+
+
diff --git a/static/mdeditor/js/lib/codemirror/mode/clike/clike.js b/static/mdeditor/js/lib/codemirror/mode/clike/clike.js
new file mode 100644
index 0000000..e2223cc
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/clike/clike.js
@@ -0,0 +1,493 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(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) {
+"use strict";
+
+CodeMirror.defineMode("clike", function(config, parserConfig) {
+ var indentUnit = config.indentUnit,
+ statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
+ dontAlignCalls = parserConfig.dontAlignCalls,
+ keywords = parserConfig.keywords || {},
+ builtin = parserConfig.builtin || {},
+ blockKeywords = parserConfig.blockKeywords || {},
+ atoms = parserConfig.atoms || {},
+ hooks = parserConfig.hooks || {},
+ multiLineStrings = parserConfig.multiLineStrings,
+ indentStatements = parserConfig.indentStatements !== false;
+ var isOperatorChar = /[+\-*&%=<>!?|\/]/;
+
+ var curPunc;
+
+ function tokenBase(stream, state) {
+ var ch = stream.next();
+ if (hooks[ch]) {
+ var result = hooks[ch](stream, state);
+ if (result !== false) return result;
+ }
+ if (ch == '"' || ch == "'") {
+ state.tokenize = tokenString(ch);
+ return state.tokenize(stream, state);
+ }
+ if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
+ curPunc = ch;
+ return null;
+ }
+ if (/\d/.test(ch)) {
+ stream.eatWhile(/[\w\.]/);
+ return "number";
+ }
+ 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";
+ }
+ stream.eatWhile(/[\w\$_\xa1-\uffff]/);
+ var cur = stream.current();
+ if (keywords.propertyIsEnumerable(cur)) {
+ if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
+ return "keyword";
+ }
+ if (builtin.propertyIsEnumerable(cur)) {
+ if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
+ return "builtin";
+ }
+ if (atoms.propertyIsEnumerable(cur)) return "atom";
+ return "variable";
+ }
+
+ function tokenString(quote) {
+ return function(stream, state) {
+ var escaped = false, next, end = false;
+ while ((next = stream.next()) != null) {
+ if (next == quote && !escaped) {end = true; break;}
+ escaped = !escaped && next == "\\";
+ }
+ if (end || !(escaped || multiLineStrings))
+ state.tokenize = null;
+ return "string";
+ };
+ }
+
+ function tokenComment(stream, state) {
+ var maybeEnd = false, ch;
+ while (ch = stream.next()) {
+ if (ch == "/" && maybeEnd) {
+ state.tokenize = null;
+ break;
+ }
+ maybeEnd = (ch == "*");
+ }
+ return "comment";
+ }
+
+ function Context(indented, column, type, align, prev) {
+ this.indented = indented;
+ this.column = column;
+ this.type = type;
+ this.align = align;
+ this.prev = prev;
+ }
+ function pushContext(state, col, type) {
+ var indent = state.indented;
+ if (state.context && state.context.type == "statement")
+ indent = state.context.indented;
+ return state.context = new Context(indent, col, type, null, state.context);
+ }
+ function popContext(state) {
+ var t = state.context.type;
+ if (t == ")" || t == "]" || t == "}")
+ state.indented = state.context.indented;
+ return state.context = state.context.prev;
+ }
+
+ // Interface
+
+ return {
+ startState: function(basecolumn) {
+ return {
+ tokenize: null,
+ context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
+ indented: 0,
+ startOfLine: true
+ };
+ },
+
+ token: function(stream, state) {
+ var ctx = state.context;
+ if (stream.sol()) {
+ if (ctx.align == null) ctx.align = false;
+ state.indented = stream.indentation();
+ state.startOfLine = true;
+ }
+ if (stream.eatSpace()) return null;
+ curPunc = null;
+ var style = (state.tokenize || tokenBase)(stream, state);
+ if (style == "comment" || style == "meta") return style;
+ if (ctx.align == null) ctx.align = true;
+
+ if ((curPunc == ";" || curPunc == ":" || curPunc == ",") && ctx.type == "statement") popContext(state);
+ else if (curPunc == "{") pushContext(state, stream.column(), "}");
+ else if (curPunc == "[") pushContext(state, stream.column(), "]");
+ else if (curPunc == "(") pushContext(state, stream.column(), ")");
+ else if (curPunc == "}") {
+ while (ctx.type == "statement") ctx = popContext(state);
+ if (ctx.type == "}") ctx = popContext(state);
+ while (ctx.type == "statement") ctx = popContext(state);
+ }
+ else if (curPunc == ctx.type) popContext(state);
+ else if (indentStatements &&
+ (((ctx.type == "}" || ctx.type == "top") && curPunc != ';') ||
+ (ctx.type == "statement" && curPunc == "newstatement")))
+ pushContext(state, stream.column(), "statement");
+ state.startOfLine = false;
+ return style;
+ },
+
+ indent: function(state, textAfter) {
+ if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
+ var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
+ if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
+ var closing = firstChar == ctx.type;
+ if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
+ else if (ctx.align && (!dontAlignCalls || ctx.type != ")")) return ctx.column + (closing ? 0 : 1);
+ else if (ctx.type == ")" && !closing) return ctx.indented + statementIndentUnit;
+ else return ctx.indented + (closing ? 0 : indentUnit);
+ },
+
+ electricChars: "{}",
+ blockCommentStart: "/*",
+ blockCommentEnd: "*/",
+ lineComment: "//",
+ fold: "brace"
+ };
+});
+
+ function words(str) {
+ var obj = {}, words = str.split(" ");
+ for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+ return obj;
+ }
+ var cKeywords = "auto if break int case long char register continue return default short do sizeof " +
+ "double static else struct entry switch extern typedef float union for unsigned " +
+ "goto while enum void const signed volatile";
+
+ function cppHook(stream, state) {
+ if (!state.startOfLine) return false;
+ for (;;) {
+ if (stream.skipTo("\\")) {
+ stream.next();
+ if (stream.eol()) {
+ state.tokenize = cppHook;
+ break;
+ }
+ } else {
+ stream.skipToEnd();
+ state.tokenize = null;
+ break;
+ }
+ }
+ return "meta";
+ }
+
+ function cpp11StringHook(stream, state) {
+ stream.backUp(1);
+ // Raw strings.
+ if (stream.match(/(R|u8R|uR|UR|LR)/)) {
+ var match = stream.match(/"([^\s\\()]{0,16})\(/);
+ if (!match) {
+ return false;
+ }
+ state.cpp11RawStringDelim = match[1];
+ state.tokenize = tokenRawString;
+ return tokenRawString(stream, state);
+ }
+ // Unicode strings/chars.
+ if (stream.match(/(u8|u|U|L)/)) {
+ if (stream.match(/["']/, /* eat */ false)) {
+ return "string";
+ }
+ return false;
+ }
+ // Ignore this hook.
+ stream.next();
+ return false;
+ }
+
+ // C#-style strings where "" escapes a quote.
+ function tokenAtString(stream, state) {
+ var next;
+ while ((next = stream.next()) != null) {
+ if (next == '"' && !stream.eat('"')) {
+ state.tokenize = null;
+ break;
+ }
+ }
+ return "string";
+ }
+
+ // C++11 raw string literal is "( anything )", where
+ // can be a string up to 16 characters long.
+ function tokenRawString(stream, state) {
+ // Escape characters that have special regex meanings.
+ var delim = state.cpp11RawStringDelim.replace(/[^\w\s]/g, '\\$&');
+ var match = stream.match(new RegExp(".*?\\)" + delim + '"'));
+ if (match)
+ state.tokenize = null;
+ else
+ stream.skipToEnd();
+ return "string";
+ }
+
+ function def(mimes, mode) {
+ if (typeof mimes == "string") mimes = [mimes];
+ var words = [];
+ function add(obj) {
+ if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop))
+ words.push(prop);
+ }
+ add(mode.keywords);
+ add(mode.builtin);
+ add(mode.atoms);
+ if (words.length) {
+ mode.helperType = mimes[0];
+ CodeMirror.registerHelper("hintWords", mimes[0], words);
+ }
+
+ for (var i = 0; i < mimes.length; ++i)
+ CodeMirror.defineMIME(mimes[i], mode);
+ }
+
+ def(["text/x-csrc", "text/x-c", "text/x-chdr"], {
+ name: "clike",
+ keywords: words(cKeywords),
+ blockKeywords: words("case do else for if switch while struct"),
+ atoms: words("null"),
+ hooks: {"#": cppHook},
+ modeProps: {fold: ["brace", "include"]}
+ });
+
+ def(["text/x-c++src", "text/x-c++hdr"], {
+ name: "clike",
+ keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try bool explicit new " +
+ "static_cast typeid catch operator template typename class friend private " +
+ "this using const_cast inline public throw virtual delete mutable protected " +
+ "wchar_t alignas alignof constexpr decltype nullptr noexcept thread_local final " +
+ "static_assert override"),
+ blockKeywords: words("catch class do else finally for if struct switch try while"),
+ atoms: words("true false null"),
+ hooks: {
+ "#": cppHook,
+ "u": cpp11StringHook,
+ "U": cpp11StringHook,
+ "L": cpp11StringHook,
+ "R": cpp11StringHook
+ },
+ modeProps: {fold: ["brace", "include"]}
+ });
+
+ def("text/x-java", {
+ name: "clike",
+ keywords: words("abstract assert boolean break byte case catch char class const continue default " +
+ "do double else enum extends final finally float for goto if implements import " +
+ "instanceof int interface long native new package private protected public " +
+ "return short static strictfp super switch synchronized this throw throws transient " +
+ "try void volatile while"),
+ blockKeywords: words("catch class do else finally for if switch try while"),
+ atoms: words("true false null"),
+ hooks: {
+ "@": function(stream) {
+ stream.eatWhile(/[\w\$_]/);
+ return "meta";
+ }
+ },
+ modeProps: {fold: ["brace", "import"]}
+ });
+
+ def("text/x-csharp", {
+ name: "clike",
+ keywords: words("abstract as base break case catch checked class const continue" +
+ " default delegate do else enum event explicit extern finally fixed for" +
+ " foreach goto if implicit in interface internal is lock namespace new" +
+ " operator out override params private protected public readonly ref return sealed" +
+ " sizeof stackalloc static struct switch this throw try typeof unchecked" +
+ " unsafe using virtual void volatile while add alias ascending descending dynamic from get" +
+ " global group into join let orderby partial remove select set value var yield"),
+ blockKeywords: words("catch class do else finally for foreach if struct switch try while"),
+ builtin: words("Boolean Byte Char DateTime DateTimeOffset Decimal Double" +
+ " Guid Int16 Int32 Int64 Object SByte Single String TimeSpan UInt16 UInt32" +
+ " UInt64 bool byte char decimal double short int long object" +
+ " sbyte float string ushort uint ulong"),
+ atoms: words("true false null"),
+ hooks: {
+ "@": function(stream, state) {
+ if (stream.eat('"')) {
+ state.tokenize = tokenAtString;
+ return tokenAtString(stream, state);
+ }
+ stream.eatWhile(/[\w\$_]/);
+ return "meta";
+ }
+ }
+ });
+
+ function tokenTripleString(stream, state) {
+ var escaped = false;
+ while (!stream.eol()) {
+ if (!escaped && stream.match('"""')) {
+ state.tokenize = null;
+ break;
+ }
+ escaped = stream.next() == "\\" && !escaped;
+ }
+ return "string";
+ }
+
+ def("text/x-scala", {
+ name: "clike",
+ keywords: words(
+
+ /* scala */
+ "abstract case catch class def do else extends false final finally for forSome if " +
+ "implicit import lazy match new null object override package private protected return " +
+ "sealed super this throw trait try trye type val var while with yield _ : = => <- <: " +
+ "<% >: # @ " +
+
+ /* package scala */
+ "assert assume require print println printf readLine readBoolean readByte readShort " +
+ "readChar readInt readLong readFloat readDouble " +
+
+ "AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " +
+ "Enumeration Equiv Error Exception Fractional Function IndexedSeq Integral Iterable " +
+ "Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering " +
+ "Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder " +
+ "StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector :: #:: " +
+
+ /* package java.lang */
+ "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
+ "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
+ "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
+ "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
+ ),
+ multiLineStrings: true,
+ blockKeywords: words("catch class do else finally for forSome if match switch try while"),
+ atoms: words("true false null"),
+ indentStatements: false,
+ hooks: {
+ "@": function(stream) {
+ stream.eatWhile(/[\w\$_]/);
+ return "meta";
+ },
+ '"': function(stream, state) {
+ if (!stream.match('""')) return false;
+ state.tokenize = tokenTripleString;
+ return state.tokenize(stream, state);
+ },
+ "'": function(stream) {
+ stream.eatWhile(/[\w\$_\xa1-\uffff]/);
+ return "atom";
+ }
+ }
+ });
+
+ def(["x-shader/x-vertex", "x-shader/x-fragment"], {
+ name: "clike",
+ keywords: words("float int bool void " +
+ "vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " +
+ "mat2 mat3 mat4 " +
+ "sampler1D sampler2D sampler3D samplerCube " +
+ "sampler1DShadow sampler2DShadow " +
+ "const attribute uniform varying " +
+ "break continue discard return " +
+ "for while do if else struct " +
+ "in out inout"),
+ blockKeywords: words("for while do if else struct"),
+ builtin: words("radians degrees sin cos tan asin acos atan " +
+ "pow exp log exp2 sqrt inversesqrt " +
+ "abs sign floor ceil fract mod min max clamp mix step smoothstep " +
+ "length distance dot cross normalize ftransform faceforward " +
+ "reflect refract matrixCompMult " +
+ "lessThan lessThanEqual greaterThan greaterThanEqual " +
+ "equal notEqual any all not " +
+ "texture1D texture1DProj texture1DLod texture1DProjLod " +
+ "texture2D texture2DProj texture2DLod texture2DProjLod " +
+ "texture3D texture3DProj texture3DLod texture3DProjLod " +
+ "textureCube textureCubeLod " +
+ "shadow1D shadow2D shadow1DProj shadow2DProj " +
+ "shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod " +
+ "dFdx dFdy fwidth " +
+ "noise1 noise2 noise3 noise4"),
+ atoms: words("true false " +
+ "gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " +
+ "gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " +
+ "gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " +
+ "gl_FogCoord gl_PointCoord " +
+ "gl_Position gl_PointSize gl_ClipVertex " +
+ "gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " +
+ "gl_TexCoord gl_FogFragCoord " +
+ "gl_FragCoord gl_FrontFacing " +
+ "gl_FragData gl_FragDepth " +
+ "gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " +
+ "gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " +
+ "gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " +
+ "gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose " +
+ "gl_ProjectionMatrixInverseTranspose " +
+ "gl_ModelViewProjectionMatrixInverseTranspose " +
+ "gl_TextureMatrixInverseTranspose " +
+ "gl_NormalScale gl_DepthRange gl_ClipPlane " +
+ "gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel " +
+ "gl_FrontLightModelProduct gl_BackLightModelProduct " +
+ "gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ " +
+ "gl_FogParameters " +
+ "gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords " +
+ "gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats " +
+ "gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits " +
+ "gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits " +
+ "gl_MaxDrawBuffers"),
+ hooks: {"#": cppHook},
+ modeProps: {fold: ["brace", "include"]}
+ });
+
+ def("text/x-nesc", {
+ name: "clike",
+ keywords: words(cKeywords + "as atomic async call command component components configuration event generic " +
+ "implementation includes interface module new norace nx_struct nx_union post provides " +
+ "signal task uses abstract extends"),
+ blockKeywords: words("case do else for if switch while struct"),
+ atoms: words("null"),
+ hooks: {"#": cppHook},
+ modeProps: {fold: ["brace", "include"]}
+ });
+
+ def("text/x-objectivec", {
+ name: "clike",
+ keywords: words(cKeywords + "inline restrict _Bool _Complex _Imaginery BOOL Class bycopy byref id IMP in " +
+ "inout nil oneway out Protocol SEL self super atomic nonatomic retain copy readwrite readonly"),
+ atoms: words("YES NO NULL NILL ON OFF"),
+ hooks: {
+ "@": function(stream) {
+ stream.eatWhile(/[\w\$]/);
+ return "keyword";
+ },
+ "#": cppHook
+ },
+ modeProps: {fold: "brace"}
+ });
+
+});
diff --git a/static/mdeditor/js/lib/codemirror/mode/clike/index.html b/static/mdeditor/js/lib/codemirror/mode/clike/index.html
new file mode 100644
index 0000000..8b386d2
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/clike/index.html
@@ -0,0 +1,251 @@
+
+
+CodeMirror: C-like mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+C-like mode
+
+
+/* C demo code */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+typedef struct {
+ void* arg_socket;
+ zmq_msg_t* arg_msg;
+ char* arg_string;
+ unsigned long arg_len;
+ int arg_int, arg_command;
+
+ int signal_fd;
+ int pad;
+ void* context;
+ sem_t sem;
+} acl_zmq_context;
+
+#define p(X) (context->arg_##X)
+
+void* zmq_thread(void* context_pointer) {
+ acl_zmq_context* context = (acl_zmq_context*)context_pointer;
+ char ok = 'K', err = 'X';
+ int res;
+
+ while (1) {
+ while ((res = sem_wait(&context->sem)) == EINTR);
+ if (res) {write(context->signal_fd, &err, 1); goto cleanup;}
+ switch(p(command)) {
+ case 0: goto cleanup;
+ case 1: p(socket) = zmq_socket(context->context, p(int)); break;
+ case 2: p(int) = zmq_close(p(socket)); break;
+ case 3: p(int) = zmq_bind(p(socket), p(string)); break;
+ case 4: p(int) = zmq_connect(p(socket), p(string)); break;
+ case 5: p(int) = zmq_getsockopt(p(socket), p(int), (void*)p(string), &p(len)); break;
+ case 6: p(int) = zmq_setsockopt(p(socket), p(int), (void*)p(string), p(len)); break;
+ case 7: p(int) = zmq_send(p(socket), p(msg), p(int)); break;
+ case 8: p(int) = zmq_recv(p(socket), p(msg), p(int)); break;
+ case 9: p(int) = zmq_poll(p(socket), p(int), p(len)); break;
+ }
+ p(command) = errno;
+ write(context->signal_fd, &ok, 1);
+ }
+ cleanup:
+ close(context->signal_fd);
+ free(context_pointer);
+ return 0;
+}
+
+void* zmq_thread_init(void* zmq_context, int signal_fd) {
+ acl_zmq_context* context = malloc(sizeof(acl_zmq_context));
+ pthread_t thread;
+
+ context->context = zmq_context;
+ context->signal_fd = signal_fd;
+ sem_init(&context->sem, 1, 0);
+ pthread_create(&thread, 0, &zmq_thread, context);
+ pthread_detach(thread);
+ return context;
+}
+
+
+C++ example
+
+
+#include
+#include "mystuff/util.h"
+
+namespace {
+enum Enum {
+ VAL1, VAL2, VAL3
+};
+
+char32_t unicode_string = U"\U0010FFFF";
+string raw_string = R"delim(anything
+you
+want)delim";
+
+int Helper(const MyType& param) {
+ return 0;
+}
+} // namespace
+
+class ForwardDec;
+
+template
+class Class : public BaseClass {
+ const MyType member_;
+
+ public:
+ const MyType& Method() const {
+ return member_;
+ }
+
+ void Method2(MyType* value);
+}
+
+template
+void Class::Method2(MyType* value) {
+ std::out << 1 >> method();
+ value->Method3(member_);
+ member_ = value;
+}
+
+
+Objective-C example
+
+
+/*
+This is a longer comment
+That spans two lines
+*/
+
+#import
+@implementation YourAppDelegate
+
+// This is a one-line comment
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
+ char myString[] = "This is a C character array";
+ int test = 5;
+ return YES;
+}
+
+
+Java example
+
+
+import com.demo.util.MyType;
+import com.demo.util.MyInterface;
+
+public enum Enum {
+ VAL1, VAL2, VAL3
+}
+
+public class Class implements MyInterface {
+ public static final MyType member;
+
+ private class InnerClass {
+ public int zero() {
+ return 0;
+ }
+ }
+
+ @Override
+ public MyType method() {
+ return member;
+ }
+
+ public void method2(MyType value) {
+ method();
+ value.method3();
+ member = value;
+ }
+}
+
+
+Scala example
+
+
+object FilterTest extends App {
+ def filter(xs: List[Int], threshold: Int) = {
+ def process(ys: List[Int]): List[Int] =
+ if (ys.isEmpty) ys
+ else if (ys.head < threshold) ys.head :: process(ys.tail)
+ else process(ys.tail)
+ process(xs)
+ }
+ println(filter(List(1, 9, 2, 8, 3, 7, 4), 5))
+}
+
+
+
+
+ Simple mode that tries to handle C-like languages as well as it
+ can. Takes two configuration parameters: keywords
, an
+ object whose property names are the keywords in the language,
+ and useCPP
, which determines whether C preprocessor
+ directives are recognized.
+
+ MIME types defined: text/x-csrc
+ (C), text/x-c++src
(C++), text/x-java
+ (Java), text/x-csharp
(C#),
+ text/x-objectivec
(Objective-C),
+ text/x-scala
(Scala), text/x-vertex
+ and x-shader/x-fragment
(shader programs).
+
diff --git a/static/mdeditor/js/lib/codemirror/mode/clike/scala.html b/static/mdeditor/js/lib/codemirror/mode/clike/scala.html
new file mode 100644
index 0000000..aa04cf0
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/clike/scala.html
@@ -0,0 +1,767 @@
+
+
+CodeMirror: Scala mode
+
+
+
+
+
+
+
+
+
+
+
+Scala mode
+
+
+
+ /* __ *\
+ ** ________ ___ / / ___ Scala API **
+ ** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
+ ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+ ** /____/\___/_/ |_/____/_/ | | **
+ ** |/ **
+ \* */
+
+ package scala.collection
+
+ import generic._
+ import mutable.{ Builder, ListBuffer }
+ import annotation.{tailrec, migration, bridge}
+ import annotation.unchecked.{ uncheckedVariance => uV }
+ import parallel.ParIterable
+
+ /** A template trait for traversable collections of type `Traversable[A]`.
+ *
+ * $traversableInfo
+ * @define mutability
+ * @define traversableInfo
+ * This is a base trait of all kinds of $mutability Scala collections. It
+ * implements the behavior common to all collections, in terms of a method
+ * `foreach` with signature:
+ * {{{
+ * def foreach[U](f: Elem => U): Unit
+ * }}}
+ * Collection classes mixing in this trait provide a concrete
+ * `foreach` method which traverses all the
+ * elements contained in the collection, applying a given function to each.
+ * They also need to provide a method `newBuilder`
+ * which creates a builder for collections of the same kind.
+ *
+ * A traversable class might or might not have two properties: strictness
+ * and orderedness. Neither is represented as a type.
+ *
+ * The instances of a strict collection class have all their elements
+ * computed before they can be used as values. By contrast, instances of
+ * a non-strict collection class may defer computation of some of their
+ * elements until after the instance is available as a value.
+ * A typical example of a non-strict collection class is a
+ *
+ * `scala.collection.immutable.Stream` .
+ * A more general class of examples are `TraversableViews`.
+ *
+ * If a collection is an instance of an ordered collection class, traversing
+ * its elements with `foreach` will always visit elements in the
+ * same order, even for different runs of the program. If the class is not
+ * ordered, `foreach` can visit elements in different orders for
+ * different runs (but it will keep the same order in the same run).'
+ *
+ * A typical example of a collection class which is not ordered is a
+ * `HashMap` of objects. The traversal order for hash maps will
+ * depend on the hash codes of its elements, and these hash codes might
+ * differ from one run to the next. By contrast, a `LinkedHashMap`
+ * is ordered because it's `foreach` method visits elements in the
+ * order they were inserted into the `HashMap`.
+ *
+ * @author Martin Odersky
+ * @version 2.8
+ * @since 2.8
+ * @tparam A the element type of the collection
+ * @tparam Repr the type of the actual collection containing the elements.
+ *
+ * @define Coll Traversable
+ * @define coll traversable collection
+ */
+ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
+ with FilterMonadic[A, Repr]
+ with TraversableOnce[A]
+ with GenTraversableLike[A, Repr]
+ with Parallelizable[A, ParIterable[A]]
+ {
+ self =>
+
+ import Traversable.breaks._
+
+ /** The type implementing this traversable */
+ protected type Self = Repr
+
+ /** The collection of type $coll underlying this `TraversableLike` object.
+ * By default this is implemented as the `TraversableLike` object itself,
+ * but this can be overridden.
+ */
+ def repr: Repr = this.asInstanceOf[Repr]
+
+ /** The underlying collection seen as an instance of `$Coll`.
+ * By default this is implemented as the current collection object itself,
+ * but this can be overridden.
+ */
+ protected[this] def thisCollection: Traversable[A] = this.asInstanceOf[Traversable[A]]
+
+ /** A conversion from collections of type `Repr` to `$Coll` objects.
+ * By default this is implemented as just a cast, but this can be overridden.
+ */
+ protected[this] def toCollection(repr: Repr): Traversable[A] = repr.asInstanceOf[Traversable[A]]
+
+ /** Creates a new builder for this collection type.
+ */
+ protected[this] def newBuilder: Builder[A, Repr]
+
+ protected[this] def parCombiner = ParIterable.newCombiner[A]
+
+ /** Applies a function `f` to all elements of this $coll.
+ *
+ * Note: this method underlies the implementation of most other bulk operations.
+ * It's important to implement this method in an efficient way.
+ *
+ *
+ * @param f the function that is applied for its side-effect to every element.
+ * The result of function `f` is discarded.
+ *
+ * @tparam U the type parameter describing the result of function `f`.
+ * This result will always be ignored. Typically `U` is `Unit`,
+ * but this is not necessary.
+ *
+ * @usecase def foreach(f: A => Unit): Unit
+ */
+ def foreach[U](f: A => U): Unit
+
+ /** Tests whether this $coll is empty.
+ *
+ * @return `true` if the $coll contain no elements, `false` otherwise.
+ */
+ def isEmpty: Boolean = {
+ var result = true
+ breakable {
+ for (x <- this) {
+ result = false
+ break
+ }
+ }
+ result
+ }
+
+ /** Tests whether this $coll is known to have a finite size.
+ * All strict collections are known to have finite size. For a non-strict collection
+ * such as `Stream`, the predicate returns `true` if all elements have been computed.
+ * It returns `false` if the stream is not yet evaluated to the end.
+ *
+ * Note: many collection methods will not work on collections of infinite sizes.
+ *
+ * @return `true` if this collection is known to have finite size, `false` otherwise.
+ */
+ def hasDefiniteSize = true
+
+ def ++[B >: A, That](that: GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+ val b = bf(repr)
+ if (that.isInstanceOf[IndexedSeqLike[_, _]]) b.sizeHint(this, that.seq.size)
+ b ++= thisCollection
+ b ++= that.seq
+ b.result
+ }
+
+ @bridge
+ def ++[B >: A, That](that: TraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That =
+ ++(that: GenTraversableOnce[B])(bf)
+
+ /** Concatenates this $coll with the elements of a traversable collection.
+ * It differs from ++ in that the right operand determines the type of the
+ * resulting collection rather than the left one.
+ *
+ * @param that the traversable to append.
+ * @tparam B the element type of the returned collection.
+ * @tparam That $thatinfo
+ * @param bf $bfinfo
+ * @return a new collection of type `That` which contains all elements
+ * of this $coll followed by all elements of `that`.
+ *
+ * @usecase def ++:[B](that: TraversableOnce[B]): $Coll[B]
+ *
+ * @return a new $coll which contains all elements of this $coll
+ * followed by all elements of `that`.
+ */
+ def ++:[B >: A, That](that: TraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+ val b = bf(repr)
+ if (that.isInstanceOf[IndexedSeqLike[_, _]]) b.sizeHint(this, that.size)
+ b ++= that
+ b ++= thisCollection
+ b.result
+ }
+
+ /** This overload exists because: for the implementation of ++: we should reuse
+ * that of ++ because many collections override it with more efficient versions.
+ * Since TraversableOnce has no '++' method, we have to implement that directly,
+ * but Traversable and down can use the overload.
+ */
+ def ++:[B >: A, That](that: Traversable[B])(implicit bf: CanBuildFrom[Repr, B, That]): That =
+ (that ++ seq)(breakOut)
+
+ def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+ val b = bf(repr)
+ b.sizeHint(this)
+ for (x <- this) b += f(x)
+ b.result
+ }
+
+ def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+ val b = bf(repr)
+ for (x <- this) b ++= f(x).seq
+ b.result
+ }
+
+ /** Selects all elements of this $coll which satisfy a predicate.
+ *
+ * @param p the predicate used to test elements.
+ * @return a new $coll consisting of all elements of this $coll that satisfy the given
+ * predicate `p`. The order of the elements is preserved.
+ */
+ def filter(p: A => Boolean): Repr = {
+ val b = newBuilder
+ for (x <- this)
+ if (p(x)) b += x
+ b.result
+ }
+
+ /** Selects all elements of this $coll which do not satisfy a predicate.
+ *
+ * @param p the predicate used to test elements.
+ * @return a new $coll consisting of all elements of this $coll that do not satisfy the given
+ * predicate `p`. The order of the elements is preserved.
+ */
+ def filterNot(p: A => Boolean): Repr = filter(!p(_))
+
+ def collect[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+ val b = bf(repr)
+ for (x <- this) if (pf.isDefinedAt(x)) b += pf(x)
+ b.result
+ }
+
+ /** Builds a new collection by applying an option-valued function to all
+ * elements of this $coll on which the function is defined.
+ *
+ * @param f the option-valued function which filters and maps the $coll.
+ * @tparam B the element type of the returned collection.
+ * @tparam That $thatinfo
+ * @param bf $bfinfo
+ * @return a new collection of type `That` resulting from applying the option-valued function
+ * `f` to each element and collecting all defined results.
+ * The order of the elements is preserved.
+ *
+ * @usecase def filterMap[B](f: A => Option[B]): $Coll[B]
+ *
+ * @param pf the partial function which filters and maps the $coll.
+ * @return a new $coll resulting from applying the given option-valued function
+ * `f` to each element and collecting all defined results.
+ * The order of the elements is preserved.
+ def filterMap[B, That](f: A => Option[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+ val b = bf(repr)
+ for (x <- this)
+ f(x) match {
+ case Some(y) => b += y
+ case _ =>
+ }
+ b.result
+ }
+ */
+
+ /** Partitions this $coll in two ${coll}s according to a predicate.
+ *
+ * @param p the predicate on which to partition.
+ * @return a pair of ${coll}s: the first $coll consists of all elements that
+ * satisfy the predicate `p` and the second $coll consists of all elements
+ * that don't. The relative order of the elements in the resulting ${coll}s
+ * is the same as in the original $coll.
+ */
+ def partition(p: A => Boolean): (Repr, Repr) = {
+ val l, r = newBuilder
+ for (x <- this) (if (p(x)) l else r) += x
+ (l.result, r.result)
+ }
+
+ def groupBy[K](f: A => K): immutable.Map[K, Repr] = {
+ val m = mutable.Map.empty[K, Builder[A, Repr]]
+ for (elem <- this) {
+ val key = f(elem)
+ val bldr = m.getOrElseUpdate(key, newBuilder)
+ bldr += elem
+ }
+ val b = immutable.Map.newBuilder[K, Repr]
+ for ((k, v) <- m)
+ b += ((k, v.result))
+
+ b.result
+ }
+
+ /** Tests whether a predicate holds for all elements of this $coll.
+ *
+ * $mayNotTerminateInf
+ *
+ * @param p the predicate used to test elements.
+ * @return `true` if the given predicate `p` holds for all elements
+ * of this $coll, otherwise `false`.
+ */
+ def forall(p: A => Boolean): Boolean = {
+ var result = true
+ breakable {
+ for (x <- this)
+ if (!p(x)) { result = false; break }
+ }
+ result
+ }
+
+ /** Tests whether a predicate holds for some of the elements of this $coll.
+ *
+ * $mayNotTerminateInf
+ *
+ * @param p the predicate used to test elements.
+ * @return `true` if the given predicate `p` holds for some of the
+ * elements of this $coll, otherwise `false`.
+ */
+ def exists(p: A => Boolean): Boolean = {
+ var result = false
+ breakable {
+ for (x <- this)
+ if (p(x)) { result = true; break }
+ }
+ result
+ }
+
+ /** Finds the first element of the $coll satisfying a predicate, if any.
+ *
+ * $mayNotTerminateInf
+ * $orderDependent
+ *
+ * @param p the predicate used to test elements.
+ * @return an option value containing the first element in the $coll
+ * that satisfies `p`, or `None` if none exists.
+ */
+ def find(p: A => Boolean): Option[A] = {
+ var result: Option[A] = None
+ breakable {
+ for (x <- this)
+ if (p(x)) { result = Some(x); break }
+ }
+ result
+ }
+
+ def scan[B >: A, That](z: B)(op: (B, B) => B)(implicit cbf: CanBuildFrom[Repr, B, That]): That = scanLeft(z)(op)
+
+ def scanLeft[B, That](z: B)(op: (B, A) => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+ val b = bf(repr)
+ b.sizeHint(this, 1)
+ var acc = z
+ b += acc
+ for (x <- this) { acc = op(acc, x); b += acc }
+ b.result
+ }
+
+ @migration(2, 9,
+ "This scanRight definition has changed in 2.9.\n" +
+ "The previous behavior can be reproduced with scanRight.reverse."
+ )
+ def scanRight[B, That](z: B)(op: (A, B) => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+ var scanned = List(z)
+ var acc = z
+ for (x <- reversed) {
+ acc = op(x, acc)
+ scanned ::= acc
+ }
+ val b = bf(repr)
+ for (elem <- scanned) b += elem
+ b.result
+ }
+
+ /** Selects the first element of this $coll.
+ * $orderDependent
+ * @return the first element of this $coll.
+ * @throws `NoSuchElementException` if the $coll is empty.
+ */
+ def head: A = {
+ var result: () => A = () => throw new NoSuchElementException
+ breakable {
+ for (x <- this) {
+ result = () => x
+ break
+ }
+ }
+ result()
+ }
+
+ /** Optionally selects the first element.
+ * $orderDependent
+ * @return the first element of this $coll if it is nonempty, `None` if it is empty.
+ */
+ def headOption: Option[A] = if (isEmpty) None else Some(head)
+
+ /** Selects all elements except the first.
+ * $orderDependent
+ * @return a $coll consisting of all elements of this $coll
+ * except the first one.
+ * @throws `UnsupportedOperationException` if the $coll is empty.
+ */
+ override def tail: Repr = {
+ if (isEmpty) throw new UnsupportedOperationException("empty.tail")
+ drop(1)
+ }
+
+ /** Selects the last element.
+ * $orderDependent
+ * @return The last element of this $coll.
+ * @throws NoSuchElementException If the $coll is empty.
+ */
+ def last: A = {
+ var lst = head
+ for (x <- this)
+ lst = x
+ lst
+ }
+
+ /** Optionally selects the last element.
+ * $orderDependent
+ * @return the last element of this $coll$ if it is nonempty, `None` if it is empty.
+ */
+ def lastOption: Option[A] = if (isEmpty) None else Some(last)
+
+ /** Selects all elements except the last.
+ * $orderDependent
+ * @return a $coll consisting of all elements of this $coll
+ * except the last one.
+ * @throws `UnsupportedOperationException` if the $coll is empty.
+ */
+ def init: Repr = {
+ if (isEmpty) throw new UnsupportedOperationException("empty.init")
+ var lst = head
+ var follow = false
+ val b = newBuilder
+ b.sizeHint(this, -1)
+ for (x <- this.seq) {
+ if (follow) b += lst
+ else follow = true
+ lst = x
+ }
+ b.result
+ }
+
+ def take(n: Int): Repr = slice(0, n)
+
+ def drop(n: Int): Repr =
+ if (n <= 0) {
+ val b = newBuilder
+ b.sizeHint(this)
+ b ++= thisCollection result
+ }
+ else sliceWithKnownDelta(n, Int.MaxValue, -n)
+
+ def slice(from: Int, until: Int): Repr = sliceWithKnownBound(math.max(from, 0), until)
+
+ // Precondition: from >= 0, until > 0, builder already configured for building.
+ private[this] def sliceInternal(from: Int, until: Int, b: Builder[A, Repr]): Repr = {
+ var i = 0
+ breakable {
+ for (x <- this.seq) {
+ if (i >= from) b += x
+ i += 1
+ if (i >= until) break
+ }
+ }
+ b.result
+ }
+ // Precondition: from >= 0
+ private[scala] def sliceWithKnownDelta(from: Int, until: Int, delta: Int): Repr = {
+ val b = newBuilder
+ if (until <= from) b.result
+ else {
+ b.sizeHint(this, delta)
+ sliceInternal(from, until, b)
+ }
+ }
+ // Precondition: from >= 0
+ private[scala] def sliceWithKnownBound(from: Int, until: Int): Repr = {
+ val b = newBuilder
+ if (until <= from) b.result
+ else {
+ b.sizeHintBounded(until - from, this)
+ sliceInternal(from, until, b)
+ }
+ }
+
+ def takeWhile(p: A => Boolean): Repr = {
+ val b = newBuilder
+ breakable {
+ for (x <- this) {
+ if (!p(x)) break
+ b += x
+ }
+ }
+ b.result
+ }
+
+ def dropWhile(p: A => Boolean): Repr = {
+ val b = newBuilder
+ var go = false
+ for (x <- this) {
+ if (!p(x)) go = true
+ if (go) b += x
+ }
+ b.result
+ }
+
+ def span(p: A => Boolean): (Repr, Repr) = {
+ val l, r = newBuilder
+ var toLeft = true
+ for (x <- this) {
+ toLeft = toLeft && p(x)
+ (if (toLeft) l else r) += x
+ }
+ (l.result, r.result)
+ }
+
+ def splitAt(n: Int): (Repr, Repr) = {
+ val l, r = newBuilder
+ l.sizeHintBounded(n, this)
+ if (n >= 0) r.sizeHint(this, -n)
+ var i = 0
+ for (x <- this) {
+ (if (i < n) l else r) += x
+ i += 1
+ }
+ (l.result, r.result)
+ }
+
+ /** Iterates over the tails of this $coll. The first value will be this
+ * $coll and the final one will be an empty $coll, with the intervening
+ * values the results of successive applications of `tail`.
+ *
+ * @return an iterator over all the tails of this $coll
+ * @example `List(1,2,3).tails = Iterator(List(1,2,3), List(2,3), List(3), Nil)`
+ */
+ def tails: Iterator[Repr] = iterateUntilEmpty(_.tail)
+
+ /** Iterates over the inits of this $coll. The first value will be this
+ * $coll and the final one will be an empty $coll, with the intervening
+ * values the results of successive applications of `init`.
+ *
+ * @return an iterator over all the inits of this $coll
+ * @example `List(1,2,3).inits = Iterator(List(1,2,3), List(1,2), List(1), Nil)`
+ */
+ def inits: Iterator[Repr] = iterateUntilEmpty(_.init)
+
+ /** Copies elements of this $coll to an array.
+ * Fills the given array `xs` with at most `len` elements of
+ * this $coll, starting at position `start`.
+ * Copying will stop once either the end of the current $coll is reached,
+ * or the end of the array is reached, or `len` elements have been copied.
+ *
+ * $willNotTerminateInf
+ *
+ * @param xs the array to fill.
+ * @param start the starting index.
+ * @param len the maximal number of elements to copy.
+ * @tparam B the type of the elements of the array.
+ *
+ *
+ * @usecase def copyToArray(xs: Array[A], start: Int, len: Int): Unit
+ */
+ def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) {
+ var i = start
+ val end = (start + len) min xs.length
+ breakable {
+ for (x <- this) {
+ if (i >= end) break
+ xs(i) = x
+ i += 1
+ }
+ }
+ }
+
+ def toTraversable: Traversable[A] = thisCollection
+ def toIterator: Iterator[A] = toStream.iterator
+ def toStream: Stream[A] = toBuffer.toStream
+
+ /** Converts this $coll to a string.
+ *
+ * @return a string representation of this collection. By default this
+ * string consists of the `stringPrefix` of this $coll,
+ * followed by all elements separated by commas and enclosed in parentheses.
+ */
+ override def toString = mkString(stringPrefix + "(", ", ", ")")
+
+ /** Defines the prefix of this object's `toString` representation.
+ *
+ * @return a string representation which starts the result of `toString`
+ * applied to this $coll. By default the string prefix is the
+ * simple name of the collection class $coll.
+ */
+ def stringPrefix : String = {
+ var string = repr.asInstanceOf[AnyRef].getClass.getName
+ val idx1 = string.lastIndexOf('.' : Int)
+ if (idx1 != -1) string = string.substring(idx1 + 1)
+ val idx2 = string.indexOf('$')
+ if (idx2 != -1) string = string.substring(0, idx2)
+ string
+ }
+
+ /** Creates a non-strict view of this $coll.
+ *
+ * @return a non-strict view of this $coll.
+ */
+ def view = new TraversableView[A, Repr] {
+ protected lazy val underlying = self.repr
+ override def foreach[U](f: A => U) = self foreach f
+ }
+
+ /** Creates a non-strict view of a slice of this $coll.
+ *
+ * Note: the difference between `view` and `slice` is that `view` produces
+ * a view of the current $coll, whereas `slice` produces a new $coll.
+ *
+ * Note: `view(from, to)` is equivalent to `view.slice(from, to)`
+ * $orderDependent
+ *
+ * @param from the index of the first element of the view
+ * @param until the index of the element following the view
+ * @return a non-strict view of a slice of this $coll, starting at index `from`
+ * and extending up to (but not including) index `until`.
+ */
+ def view(from: Int, until: Int): TraversableView[A, Repr] = view.slice(from, until)
+
+ /** Creates a non-strict filter of this $coll.
+ *
+ * Note: the difference between `c filter p` and `c withFilter p` is that
+ * the former creates a new collection, whereas the latter only
+ * restricts the domain of subsequent `map`, `flatMap`, `foreach`,
+ * and `withFilter` operations.
+ * $orderDependent
+ *
+ * @param p the predicate used to test elements.
+ * @return an object of class `WithFilter`, which supports
+ * `map`, `flatMap`, `foreach`, and `withFilter` operations.
+ * All these operations apply to those elements of this $coll which
+ * satisfy the predicate `p`.
+ */
+ def withFilter(p: A => Boolean): FilterMonadic[A, Repr] = new WithFilter(p)
+
+ /** A class supporting filtered operations. Instances of this class are
+ * returned by method `withFilter`.
+ */
+ class WithFilter(p: A => Boolean) extends FilterMonadic[A, Repr] {
+
+ /** Builds a new collection by applying a function to all elements of the
+ * outer $coll containing this `WithFilter` instance that satisfy predicate `p`.
+ *
+ * @param f the function to apply to each element.
+ * @tparam B the element type of the returned collection.
+ * @tparam That $thatinfo
+ * @param bf $bfinfo
+ * @return a new collection of type `That` resulting from applying
+ * the given function `f` to each element of the outer $coll
+ * that satisfies predicate `p` and collecting the results.
+ *
+ * @usecase def map[B](f: A => B): $Coll[B]
+ *
+ * @return a new $coll resulting from applying the given function
+ * `f` to each element of the outer $coll that satisfies
+ * predicate `p` and collecting the results.
+ */
+ def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+ val b = bf(repr)
+ for (x <- self)
+ if (p(x)) b += f(x)
+ b.result
+ }
+
+ /** Builds a new collection by applying a function to all elements of the
+ * outer $coll containing this `WithFilter` instance that satisfy
+ * predicate `p` and concatenating the results.
+ *
+ * @param f the function to apply to each element.
+ * @tparam B the element type of the returned collection.
+ * @tparam That $thatinfo
+ * @param bf $bfinfo
+ * @return a new collection of type `That` resulting from applying
+ * the given collection-valued function `f` to each element
+ * of the outer $coll that satisfies predicate `p` and
+ * concatenating the results.
+ *
+ * @usecase def flatMap[B](f: A => TraversableOnce[B]): $Coll[B]
+ *
+ * @return a new $coll resulting from applying the given collection-valued function
+ * `f` to each element of the outer $coll that satisfies predicate `p` and concatenating the results.
+ */
+ def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
+ val b = bf(repr)
+ for (x <- self)
+ if (p(x)) b ++= f(x).seq
+ b.result
+ }
+
+ /** Applies a function `f` to all elements of the outer $coll containing
+ * this `WithFilter` instance that satisfy predicate `p`.
+ *
+ * @param f the function that is applied for its side-effect to every element.
+ * The result of function `f` is discarded.
+ *
+ * @tparam U the type parameter describing the result of function `f`.
+ * This result will always be ignored. Typically `U` is `Unit`,
+ * but this is not necessary.
+ *
+ * @usecase def foreach(f: A => Unit): Unit
+ */
+ def foreach[U](f: A => U): Unit =
+ for (x <- self)
+ if (p(x)) f(x)
+
+ /** Further refines the filter for this $coll.
+ *
+ * @param q the predicate used to test elements.
+ * @return an object of class `WithFilter`, which supports
+ * `map`, `flatMap`, `foreach`, and `withFilter` operations.
+ * All these operations apply to those elements of this $coll which
+ * satisfy the predicate `q` in addition to the predicate `p`.
+ */
+ def withFilter(q: A => Boolean): WithFilter =
+ new WithFilter(x => p(x) && q(x))
+ }
+
+ // A helper for tails and inits.
+ private def iterateUntilEmpty(f: Traversable[A @uV] => Traversable[A @uV]): Iterator[Repr] = {
+ val it = Iterator.iterate(thisCollection)(f) takeWhile (x => !x.isEmpty)
+ it ++ Iterator(Nil) map (newBuilder ++= _ result)
+ }
+ }
+
+
+
+
+
+
+
diff --git a/static/mdeditor/js/lib/codemirror/mode/clojure/clojure.js b/static/mdeditor/js/lib/codemirror/mode/clojure/clojure.js
new file mode 100644
index 0000000..c334de7
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/clojure/clojure.js
@@ -0,0 +1,243 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+/**
+ * Author: Hans Engel
+ * Branched from CodeMirror's Scheme mode (by Koh Zi Han, based on implementation by Koh Zi Chun)
+ */
+
+(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) {
+"use strict";
+
+CodeMirror.defineMode("clojure", function (options) {
+ var BUILTIN = "builtin", COMMENT = "comment", STRING = "string", CHARACTER = "string-2",
+ ATOM = "atom", NUMBER = "number", BRACKET = "bracket", KEYWORD = "keyword", VAR = "variable";
+ var INDENT_WORD_SKIP = options.indentUnit || 2;
+ var NORMAL_INDENT_UNIT = options.indentUnit || 2;
+
+ function makeKeywords(str) {
+ var obj = {}, words = str.split(" ");
+ for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+ return obj;
+ }
+
+ var atoms = makeKeywords("true false nil");
+
+ var keywords = makeKeywords(
+ "defn defn- def def- defonce defmulti defmethod defmacro defstruct deftype defprotocol defrecord defproject deftest slice defalias defhinted defmacro- defn-memo defnk defnk defonce- defunbound defunbound- defvar defvar- let letfn do case cond condp for loop recur when when-not when-let when-first if if-let if-not . .. -> ->> doto and or dosync doseq dotimes dorun doall load import unimport ns in-ns refer try catch finally throw with-open with-local-vars binding gen-class gen-and-load-class gen-and-save-class handler-case handle");
+
+ var builtins = makeKeywords(
+ "* *' *1 *2 *3 *agent* *allow-unresolved-vars* *assert* *clojure-version* *command-line-args* *compile-files* *compile-path* *compiler-options* *data-readers* *e *err* *file* *flush-on-newline* *fn-loader* *in* *math-context* *ns* *out* *print-dup* *print-length* *print-level* *print-meta* *print-readably* *read-eval* *source-path* *unchecked-math* *use-context-classloader* *verbose-defrecords* *warn-on-reflection* + +' - -' -> ->> ->ArrayChunk ->Vec ->VecNode ->VecSeq -cache-protocol-fn -reset-methods .. / < <= = == > >= EMPTY-NODE accessor aclone add-classpath add-watch agent agent-error agent-errors aget alength alias all-ns alter alter-meta! alter-var-root amap ancestors and apply areduce array-map aset aset-boolean aset-byte aset-char aset-double aset-float aset-int aset-long aset-short assert assoc assoc! assoc-in associative? atom await await-for await1 bases bean bigdec bigint biginteger binding bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set bit-shift-left bit-shift-right bit-test bit-xor boolean boolean-array booleans bound-fn bound-fn* bound? butlast byte byte-array bytes case cast char char-array char-escape-string char-name-string char? chars chunk chunk-append chunk-buffer chunk-cons chunk-first chunk-next chunk-rest chunked-seq? class class? clear-agent-errors clojure-version coll? comment commute comp comparator compare compare-and-set! compile complement concat cond condp conj conj! cons constantly construct-proxy contains? count counted? create-ns create-struct cycle dec dec' decimal? declare default-data-readers definline definterface defmacro defmethod defmulti defn defn- defonce defprotocol defrecord defstruct deftype delay delay? deliver denominator deref derive descendants destructure disj disj! dissoc dissoc! distinct distinct? doall dorun doseq dosync dotimes doto double double-array doubles drop drop-last drop-while empty empty? ensure enumeration-seq error-handler error-mode eval even? every-pred every? ex-data ex-info extend extend-protocol extend-type extenders extends? false? ffirst file-seq filter filterv find find-keyword find-ns find-protocol-impl find-protocol-method find-var first flatten float float-array float? floats flush fn fn? fnext fnil for force format frequencies future future-call future-cancel future-cancelled? future-done? future? gen-class gen-interface gensym get get-in get-method get-proxy-class get-thread-bindings get-validator group-by hash hash-combine hash-map hash-set identical? identity if-let if-not ifn? import in-ns inc inc' init-proxy instance? int int-array integer? interleave intern interpose into into-array ints io! isa? iterate iterator-seq juxt keep keep-indexed key keys keyword keyword? last lazy-cat lazy-seq let letfn line-seq list list* list? load load-file load-reader load-string loaded-libs locking long long-array longs loop macroexpand macroexpand-1 make-array make-hierarchy map map-indexed map? mapcat mapv max max-key memfn memoize merge merge-with meta method-sig methods min min-key mod munge name namespace namespace-munge neg? newline next nfirst nil? nnext not not-any? not-empty not-every? not= ns ns-aliases ns-imports ns-interns ns-map ns-name ns-publics ns-refers ns-resolve ns-unalias ns-unmap nth nthnext nthrest num number? numerator object-array odd? or parents partial partition partition-all partition-by pcalls peek persistent! pmap pop pop! pop-thread-bindings pos? pr pr-str prefer-method prefers primitives-classnames print print-ctor print-dup print-method print-simple print-str printf println println-str prn prn-str promise proxy proxy-call-with-super proxy-mappings proxy-name proxy-super push-thread-bindings pvalues quot rand rand-int rand-nth range ratio? rational? rationalize re-find re-groups re-matcher re-matches re-pattern re-seq read read-line read-string realized? reduce reduce-kv reductions ref ref-history-count ref-max-history ref-min-history ref-set refer refer-clojure reify release-pending-sends rem remove remove-all-methods remove-method remove-ns remove-watch repeat repeatedly replace replicate require reset! reset-meta! resolve rest restart-agent resultset-seq reverse reversible? rseq rsubseq satisfies? second select-keys send send-off seq seq? seque sequence sequential? set set-error-handler! set-error-mode! set-validator! set? short short-array shorts shuffle shutdown-agents slurp some some-fn sort sort-by sorted-map sorted-map-by sorted-set sorted-set-by sorted? special-symbol? spit split-at split-with str string? struct struct-map subs subseq subvec supers swap! symbol symbol? sync take take-last take-nth take-while test the-ns thread-bound? time to-array to-array-2d trampoline transient tree-seq true? type unchecked-add unchecked-add-int unchecked-byte unchecked-char unchecked-dec unchecked-dec-int unchecked-divide-int unchecked-double unchecked-float unchecked-inc unchecked-inc-int unchecked-int unchecked-long unchecked-multiply unchecked-multiply-int unchecked-negate unchecked-negate-int unchecked-remainder-int unchecked-short unchecked-subtract unchecked-subtract-int underive unquote unquote-splicing update-in update-proxy use val vals var-get var-set var? vary-meta vec vector vector-of vector? when when-first when-let when-not while with-bindings with-bindings* with-in-str with-loading-context with-local-vars with-meta with-open with-out-str with-precision with-redefs with-redefs-fn xml-seq zero? zipmap *default-data-reader-fn* as-> cond-> cond->> reduced reduced? send-via set-agent-send-executor! set-agent-send-off-executor! some-> some->>");
+
+ var indentKeys = makeKeywords(
+ // Built-ins
+ "ns fn def defn defmethod bound-fn if if-not case condp when while when-not when-first do future comment doto locking proxy with-open with-precision reify deftype defrecord defprotocol extend extend-protocol extend-type try catch " +
+
+ // Binding forms
+ "let letfn binding loop for doseq dotimes when-let if-let " +
+
+ // Data structures
+ "defstruct struct-map assoc " +
+
+ // clojure.test
+ "testing deftest " +
+
+ // contrib
+ "handler-case handle dotrace deftrace");
+
+ var tests = {
+ digit: /\d/,
+ digit_or_colon: /[\d:]/,
+ hex: /[0-9a-f]/i,
+ sign: /[+-]/,
+ exponent: /e/i,
+ keyword_char: /[^\s\(\[\;\)\]]/,
+ symbol: /[\w*+!\-\._?:<>\/\xa1-\uffff]/
+ };
+
+ function stateStack(indent, type, prev) { // represents a state stack object
+ this.indent = indent;
+ this.type = type;
+ this.prev = prev;
+ }
+
+ function pushStack(state, indent, type) {
+ state.indentStack = new stateStack(indent, type, state.indentStack);
+ }
+
+ function popStack(state) {
+ state.indentStack = state.indentStack.prev;
+ }
+
+ function isNumber(ch, stream){
+ // hex
+ if ( ch === '0' && stream.eat(/x/i) ) {
+ stream.eatWhile(tests.hex);
+ return true;
+ }
+
+ // leading sign
+ if ( ( ch == '+' || ch == '-' ) && ( tests.digit.test(stream.peek()) ) ) {
+ stream.eat(tests.sign);
+ ch = stream.next();
+ }
+
+ if ( tests.digit.test(ch) ) {
+ stream.eat(ch);
+ stream.eatWhile(tests.digit);
+
+ if ( '.' == stream.peek() ) {
+ stream.eat('.');
+ stream.eatWhile(tests.digit);
+ }
+
+ if ( stream.eat(tests.exponent) ) {
+ stream.eat(tests.sign);
+ stream.eatWhile(tests.digit);
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ // Eat character that starts after backslash \
+ function eatCharacter(stream) {
+ var first = stream.next();
+ // Read special literals: backspace, newline, space, return.
+ // Just read all lowercase letters.
+ if (first && first.match(/[a-z]/) && stream.match(/[a-z]+/, true)) {
+ return;
+ }
+ // Read unicode character: \u1000 \uA0a1
+ if (first === "u") {
+ stream.match(/[0-9a-z]{4}/i, true);
+ }
+ }
+
+ return {
+ startState: function () {
+ return {
+ indentStack: null,
+ indentation: 0,
+ mode: false
+ };
+ },
+
+ token: function (stream, state) {
+ if (state.indentStack == null && stream.sol()) {
+ // update indentation, but only if indentStack is empty
+ state.indentation = stream.indentation();
+ }
+
+ // skip spaces
+ if (stream.eatSpace()) {
+ return null;
+ }
+ var returnType = null;
+
+ switch(state.mode){
+ case "string": // multi-line string parsing mode
+ var next, escaped = false;
+ while ((next = stream.next()) != null) {
+ if (next == "\"" && !escaped) {
+
+ state.mode = false;
+ break;
+ }
+ escaped = !escaped && next == "\\";
+ }
+ returnType = STRING; // continue on in string mode
+ break;
+ default: // default parsing mode
+ var ch = stream.next();
+
+ if (ch == "\"") {
+ state.mode = "string";
+ returnType = STRING;
+ } else if (ch == "\\") {
+ eatCharacter(stream);
+ returnType = CHARACTER;
+ } else if (ch == "'" && !( tests.digit_or_colon.test(stream.peek()) )) {
+ returnType = ATOM;
+ } else if (ch == ";") { // comment
+ stream.skipToEnd(); // rest of the line is a comment
+ returnType = COMMENT;
+ } else if (isNumber(ch,stream)){
+ returnType = NUMBER;
+ } else if (ch == "(" || ch == "[" || ch == "{" ) {
+ var keyWord = '', indentTemp = stream.column(), letter;
+ /**
+ Either
+ (indent-word ..
+ (non-indent-word ..
+ (;something else, bracket, etc.
+ */
+
+ if (ch == "(") while ((letter = stream.eat(tests.keyword_char)) != null) {
+ keyWord += letter;
+ }
+
+ if (keyWord.length > 0 && (indentKeys.propertyIsEnumerable(keyWord) ||
+ /^(?:def|with)/.test(keyWord))) { // indent-word
+ pushStack(state, indentTemp + INDENT_WORD_SKIP, ch);
+ } else { // non-indent word
+ // we continue eating the spaces
+ stream.eatSpace();
+ if (stream.eol() || stream.peek() == ";") {
+ // nothing significant after
+ // we restart indentation the user defined spaces after
+ pushStack(state, indentTemp + NORMAL_INDENT_UNIT, ch);
+ } else {
+ pushStack(state, indentTemp + stream.current().length, ch); // else we match
+ }
+ }
+ stream.backUp(stream.current().length - 1); // undo all the eating
+
+ returnType = BRACKET;
+ } else if (ch == ")" || ch == "]" || ch == "}") {
+ returnType = BRACKET;
+ if (state.indentStack != null && state.indentStack.type == (ch == ")" ? "(" : (ch == "]" ? "[" :"{"))) {
+ popStack(state);
+ }
+ } else if ( ch == ":" ) {
+ stream.eatWhile(tests.symbol);
+ return ATOM;
+ } else {
+ stream.eatWhile(tests.symbol);
+
+ if (keywords && keywords.propertyIsEnumerable(stream.current())) {
+ returnType = KEYWORD;
+ } else if (builtins && builtins.propertyIsEnumerable(stream.current())) {
+ returnType = BUILTIN;
+ } else if (atoms && atoms.propertyIsEnumerable(stream.current())) {
+ returnType = ATOM;
+ } else {
+ returnType = VAR;
+ }
+ }
+ }
+
+ return returnType;
+ },
+
+ indent: function (state) {
+ if (state.indentStack == null) return state.indentation;
+ return state.indentStack.indent;
+ },
+
+ lineComment: ";;"
+ };
+});
+
+CodeMirror.defineMIME("text/x-clojure", "clojure");
+
+});
diff --git a/static/mdeditor/js/lib/codemirror/mode/clojure/index.html b/static/mdeditor/js/lib/codemirror/mode/clojure/index.html
new file mode 100644
index 0000000..3ecf4c4
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/clojure/index.html
@@ -0,0 +1,88 @@
+
+
+CodeMirror: Clojure mode
+
+
+
+
+
+
+
+
+
+
+Clojure mode
+
+; Conway's Game of Life, based on the work of:
+;; Laurent Petit https://gist.github.com/1200343
+;; Christophe Grand http://clj-me.cgrand.net/2011/08/19/conways-game-of-life
+
+(ns ^{:doc "Conway's Game of Life."}
+ game-of-life)
+
+;; Core game of life's algorithm functions
+
+(defn neighbours
+ "Given a cell's coordinates, returns the coordinates of its neighbours."
+ [[x y]]
+ (for [dx [-1 0 1] dy (if (zero? dx) [-1 1] [-1 0 1])]
+ [(+ dx x) (+ dy y)]))
+
+(defn step
+ "Given a set of living cells, computes the new set of living cells."
+ [cells]
+ (set (for [[cell n] (frequencies (mapcat neighbours cells))
+ :when (or (= n 3) (and (= n 2) (cells cell)))]
+ cell)))
+
+;; Utility methods for displaying game on a text terminal
+
+(defn print-board
+ "Prints a board on *out*, representing a step in the game."
+ [board w h]
+ (doseq [x (range (inc w)) y (range (inc h))]
+ (if (= y 0) (print "\n"))
+ (print (if (board [x y]) "[X]" " . "))))
+
+(defn display-grids
+ "Prints a squence of boards on *out*, representing several steps."
+ [grids w h]
+ (doseq [board grids]
+ (print-board board w h)
+ (print "\n")))
+
+;; Launches an example board
+
+(def
+ ^{:doc "board represents the initial set of living cells"}
+ board #{[2 1] [2 2] [2 3]})
+
+(display-grids (take 3 (iterate step board)) 5 5)
+
+;; Let's play with characters
+(println \1 \a \# \\
+ \" \( \newline
+ \} \" \space
+ \tab \return \backspace
+ \u1000 \uAaAa \u9F9F)
+
+
+
+
+ MIME types defined: text/x-clojure
.
+
+
diff --git a/static/mdeditor/js/lib/codemirror/mode/cobol/cobol.js b/static/mdeditor/js/lib/codemirror/mode/cobol/cobol.js
new file mode 100644
index 0000000..897022b
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/cobol/cobol.js
@@ -0,0 +1,255 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+/**
+ * Author: Gautam Mehta
+ * Branched from CodeMirror's Scheme mode
+ */
+(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) {
+"use strict";
+
+CodeMirror.defineMode("cobol", function () {
+ var BUILTIN = "builtin", COMMENT = "comment", STRING = "string",
+ ATOM = "atom", NUMBER = "number", KEYWORD = "keyword", MODTAG = "header",
+ COBOLLINENUM = "def", PERIOD = "link";
+ function makeKeywords(str) {
+ var obj = {}, words = str.split(" ");
+ for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+ return obj;
+ }
+ var atoms = makeKeywords("TRUE FALSE ZEROES ZEROS ZERO SPACES SPACE LOW-VALUE LOW-VALUES ");
+ var keywords = makeKeywords(
+ "ACCEPT ACCESS ACQUIRE ADD ADDRESS " +
+ "ADVANCING AFTER ALIAS ALL ALPHABET " +
+ "ALPHABETIC ALPHABETIC-LOWER ALPHABETIC-UPPER ALPHANUMERIC ALPHANUMERIC-EDITED " +
+ "ALSO ALTER ALTERNATE AND ANY " +
+ "ARE AREA AREAS ARITHMETIC ASCENDING " +
+ "ASSIGN AT ATTRIBUTE AUTHOR AUTO " +
+ "AUTO-SKIP AUTOMATIC B-AND B-EXOR B-LESS " +
+ "B-NOT B-OR BACKGROUND-COLOR BACKGROUND-COLOUR BEEP " +
+ "BEFORE BELL BINARY BIT BITS " +
+ "BLANK BLINK BLOCK BOOLEAN BOTTOM " +
+ "BY CALL CANCEL CD CF " +
+ "CH CHARACTER CHARACTERS CLASS CLOCK-UNITS " +
+ "CLOSE COBOL CODE CODE-SET COL " +
+ "COLLATING COLUMN COMMA COMMIT COMMITMENT " +
+ "COMMON COMMUNICATION COMP COMP-0 COMP-1 " +
+ "COMP-2 COMP-3 COMP-4 COMP-5 COMP-6 " +
+ "COMP-7 COMP-8 COMP-9 COMPUTATIONAL COMPUTATIONAL-0 " +
+ "COMPUTATIONAL-1 COMPUTATIONAL-2 COMPUTATIONAL-3 COMPUTATIONAL-4 COMPUTATIONAL-5 " +
+ "COMPUTATIONAL-6 COMPUTATIONAL-7 COMPUTATIONAL-8 COMPUTATIONAL-9 COMPUTE " +
+ "CONFIGURATION CONNECT CONSOLE CONTAINED CONTAINS " +
+ "CONTENT CONTINUE CONTROL CONTROL-AREA CONTROLS " +
+ "CONVERTING COPY CORR CORRESPONDING COUNT " +
+ "CRT CRT-UNDER CURRENCY CURRENT CURSOR " +
+ "DATA DATE DATE-COMPILED DATE-WRITTEN DAY " +
+ "DAY-OF-WEEK DB DB-ACCESS-CONTROL-KEY DB-DATA-NAME DB-EXCEPTION " +
+ "DB-FORMAT-NAME DB-RECORD-NAME DB-SET-NAME DB-STATUS DBCS " +
+ "DBCS-EDITED DE DEBUG-CONTENTS DEBUG-ITEM DEBUG-LINE " +
+ "DEBUG-NAME DEBUG-SUB-1 DEBUG-SUB-2 DEBUG-SUB-3 DEBUGGING " +
+ "DECIMAL-POINT DECLARATIVES DEFAULT DELETE DELIMITED " +
+ "DELIMITER DEPENDING DESCENDING DESCRIBED DESTINATION " +
+ "DETAIL DISABLE DISCONNECT DISPLAY DISPLAY-1 " +
+ "DISPLAY-2 DISPLAY-3 DISPLAY-4 DISPLAY-5 DISPLAY-6 " +
+ "DISPLAY-7 DISPLAY-8 DISPLAY-9 DIVIDE DIVISION " +
+ "DOWN DROP DUPLICATE DUPLICATES DYNAMIC " +
+ "EBCDIC EGI EJECT ELSE EMI " +
+ "EMPTY EMPTY-CHECK ENABLE END END. END-ACCEPT END-ACCEPT. " +
+ "END-ADD END-CALL END-COMPUTE END-DELETE END-DISPLAY " +
+ "END-DIVIDE END-EVALUATE END-IF END-INVOKE END-MULTIPLY " +
+ "END-OF-PAGE END-PERFORM END-READ END-RECEIVE END-RETURN " +
+ "END-REWRITE END-SEARCH END-START END-STRING END-SUBTRACT " +
+ "END-UNSTRING END-WRITE END-XML ENTER ENTRY " +
+ "ENVIRONMENT EOP EQUAL EQUALS ERASE " +
+ "ERROR ESI EVALUATE EVERY EXCEEDS " +
+ "EXCEPTION EXCLUSIVE EXIT EXTEND EXTERNAL " +
+ "EXTERNALLY-DESCRIBED-KEY FD FETCH FILE FILE-CONTROL " +
+ "FILE-STREAM FILES FILLER FINAL FIND " +
+ "FINISH FIRST FOOTING FOR FOREGROUND-COLOR " +
+ "FOREGROUND-COLOUR FORMAT FREE FROM FULL " +
+ "FUNCTION GENERATE GET GIVING GLOBAL " +
+ "GO GOBACK GREATER GROUP HEADING " +
+ "HIGH-VALUE HIGH-VALUES HIGHLIGHT I-O I-O-CONTROL " +
+ "ID IDENTIFICATION IF IN INDEX " +
+ "INDEX-1 INDEX-2 INDEX-3 INDEX-4 INDEX-5 " +
+ "INDEX-6 INDEX-7 INDEX-8 INDEX-9 INDEXED " +
+ "INDIC INDICATE INDICATOR INDICATORS INITIAL " +
+ "INITIALIZE INITIATE INPUT INPUT-OUTPUT INSPECT " +
+ "INSTALLATION INTO INVALID INVOKE IS " +
+ "JUST JUSTIFIED KANJI KEEP KEY " +
+ "LABEL LAST LD LEADING LEFT " +
+ "LEFT-JUSTIFY LENGTH LENGTH-CHECK LESS LIBRARY " +
+ "LIKE LIMIT LIMITS LINAGE LINAGE-COUNTER " +
+ "LINE LINE-COUNTER LINES LINKAGE LOCAL-STORAGE " +
+ "LOCALE LOCALLY LOCK " +
+ "MEMBER MEMORY MERGE MESSAGE METACLASS " +
+ "MODE MODIFIED MODIFY MODULES MOVE " +
+ "MULTIPLE MULTIPLY NATIONAL NATIVE NEGATIVE " +
+ "NEXT NO NO-ECHO NONE NOT " +
+ "NULL NULL-KEY-MAP NULL-MAP NULLS NUMBER " +
+ "NUMERIC NUMERIC-EDITED OBJECT OBJECT-COMPUTER OCCURS " +
+ "OF OFF OMITTED ON ONLY " +
+ "OPEN OPTIONAL OR ORDER ORGANIZATION " +
+ "OTHER OUTPUT OVERFLOW OWNER PACKED-DECIMAL " +
+ "PADDING PAGE PAGE-COUNTER PARSE PERFORM " +
+ "PF PH PIC PICTURE PLUS " +
+ "POINTER POSITION POSITIVE PREFIX PRESENT " +
+ "PRINTING PRIOR PROCEDURE PROCEDURE-POINTER PROCEDURES " +
+ "PROCEED PROCESS PROCESSING PROGRAM PROGRAM-ID " +
+ "PROMPT PROTECTED PURGE QUEUE QUOTE " +
+ "QUOTES RANDOM RD READ READY " +
+ "REALM RECEIVE RECONNECT RECORD RECORD-NAME " +
+ "RECORDS RECURSIVE REDEFINES REEL REFERENCE " +
+ "REFERENCE-MONITOR REFERENCES RELATION RELATIVE RELEASE " +
+ "REMAINDER REMOVAL RENAMES REPEATED REPLACE " +
+ "REPLACING REPORT REPORTING REPORTS REPOSITORY " +
+ "REQUIRED RERUN RESERVE RESET RETAINING " +
+ "RETRIEVAL RETURN RETURN-CODE RETURNING REVERSE-VIDEO " +
+ "REVERSED REWIND REWRITE RF RH " +
+ "RIGHT RIGHT-JUSTIFY ROLLBACK ROLLING ROUNDED " +
+ "RUN SAME SCREEN SD SEARCH " +
+ "SECTION SECURE SECURITY SEGMENT SEGMENT-LIMIT " +
+ "SELECT SEND SENTENCE SEPARATE SEQUENCE " +
+ "SEQUENTIAL SET SHARED SIGN SIZE " +
+ "SKIP1 SKIP2 SKIP3 SORT SORT-MERGE " +
+ "SORT-RETURN SOURCE SOURCE-COMPUTER SPACE-FILL " +
+ "SPECIAL-NAMES STANDARD STANDARD-1 STANDARD-2 " +
+ "START STARTING STATUS STOP STORE " +
+ "STRING SUB-QUEUE-1 SUB-QUEUE-2 SUB-QUEUE-3 SUB-SCHEMA " +
+ "SUBFILE SUBSTITUTE SUBTRACT SUM SUPPRESS " +
+ "SYMBOLIC SYNC SYNCHRONIZED SYSIN SYSOUT " +
+ "TABLE TALLYING TAPE TENANT TERMINAL " +
+ "TERMINATE TEST TEXT THAN THEN " +
+ "THROUGH THRU TIME TIMES TITLE " +
+ "TO TOP TRAILING TRAILING-SIGN TRANSACTION " +
+ "TYPE TYPEDEF UNDERLINE UNEQUAL UNIT " +
+ "UNSTRING UNTIL UP UPDATE UPON " +
+ "USAGE USAGE-MODE USE USING VALID " +
+ "VALIDATE VALUE VALUES VARYING VLR " +
+ "WAIT WHEN WHEN-COMPILED WITH WITHIN " +
+ "WORDS WORKING-STORAGE WRITE XML XML-CODE " +
+ "XML-EVENT XML-NTEXT XML-TEXT ZERO ZERO-FILL " );
+
+ var builtins = makeKeywords("- * ** / + < <= = > >= ");
+ var tests = {
+ digit: /\d/,
+ digit_or_colon: /[\d:]/,
+ hex: /[0-9a-f]/i,
+ sign: /[+-]/,
+ exponent: /e/i,
+ keyword_char: /[^\s\(\[\;\)\]]/,
+ symbol: /[\w*+\-]/
+ };
+ function isNumber(ch, stream){
+ // hex
+ if ( ch === '0' && stream.eat(/x/i) ) {
+ stream.eatWhile(tests.hex);
+ return true;
+ }
+ // leading sign
+ if ( ( ch == '+' || ch == '-' ) && ( tests.digit.test(stream.peek()) ) ) {
+ stream.eat(tests.sign);
+ ch = stream.next();
+ }
+ if ( tests.digit.test(ch) ) {
+ stream.eat(ch);
+ stream.eatWhile(tests.digit);
+ if ( '.' == stream.peek()) {
+ stream.eat('.');
+ stream.eatWhile(tests.digit);
+ }
+ if ( stream.eat(tests.exponent) ) {
+ stream.eat(tests.sign);
+ stream.eatWhile(tests.digit);
+ }
+ return true;
+ }
+ return false;
+ }
+ return {
+ startState: function () {
+ return {
+ indentStack: null,
+ indentation: 0,
+ mode: false
+ };
+ },
+ token: function (stream, state) {
+ if (state.indentStack == null && stream.sol()) {
+ // update indentation, but only if indentStack is empty
+ state.indentation = 6 ; //stream.indentation();
+ }
+ // skip spaces
+ if (stream.eatSpace()) {
+ return null;
+ }
+ var returnType = null;
+ switch(state.mode){
+ case "string": // multi-line string parsing mode
+ var next = false;
+ while ((next = stream.next()) != null) {
+ if (next == "\"" || next == "\'") {
+ state.mode = false;
+ break;
+ }
+ }
+ returnType = STRING; // continue on in string mode
+ break;
+ default: // default parsing mode
+ var ch = stream.next();
+ var col = stream.column();
+ if (col >= 0 && col <= 5) {
+ returnType = COBOLLINENUM;
+ } else if (col >= 72 && col <= 79) {
+ stream.skipToEnd();
+ returnType = MODTAG;
+ } else if (ch == "*" && col == 6) { // comment
+ stream.skipToEnd(); // rest of the line is a comment
+ returnType = COMMENT;
+ } else if (ch == "\"" || ch == "\'") {
+ state.mode = "string";
+ returnType = STRING;
+ } else if (ch == "'" && !( tests.digit_or_colon.test(stream.peek()) )) {
+ returnType = ATOM;
+ } else if (ch == ".") {
+ returnType = PERIOD;
+ } else if (isNumber(ch,stream)){
+ returnType = NUMBER;
+ } else {
+ if (stream.current().match(tests.symbol)) {
+ while (col < 71) {
+ if (stream.eat(tests.symbol) === undefined) {
+ break;
+ } else {
+ col++;
+ }
+ }
+ }
+ if (keywords && keywords.propertyIsEnumerable(stream.current().toUpperCase())) {
+ returnType = KEYWORD;
+ } else if (builtins && builtins.propertyIsEnumerable(stream.current().toUpperCase())) {
+ returnType = BUILTIN;
+ } else if (atoms && atoms.propertyIsEnumerable(stream.current().toUpperCase())) {
+ returnType = ATOM;
+ } else returnType = null;
+ }
+ }
+ return returnType;
+ },
+ indent: function (state) {
+ if (state.indentStack == null) return state.indentation;
+ return state.indentStack.indent;
+ }
+ };
+});
+
+CodeMirror.defineMIME("text/x-cobol", "cobol");
+
+});
diff --git a/static/mdeditor/js/lib/codemirror/mode/cobol/index.html b/static/mdeditor/js/lib/codemirror/mode/cobol/index.html
new file mode 100644
index 0000000..4352419
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/cobol/index.html
@@ -0,0 +1,210 @@
+
+
+CodeMirror: COBOL mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+COBOL mode
+
+ Select Theme
+ default
+ ambiance
+ blackboard
+ cobalt
+ eclipse
+ elegant
+ erlang-dark
+ lesser-dark
+ midnight
+ monokai
+ neat
+ night
+ rubyblue
+ solarized dark
+ solarized light
+ twilight
+ vibrant-ink
+ xq-dark
+ xq-light
+ Select Font Size
+ 13px
+ 14px
+ 16px
+ 18px
+ 20px
+ 24px
+ 26px
+ 28px
+ 30px
+ 32px
+ 34px
+ 36px
+
+Read-only
+
+Insert Spaces on Tab
+
+
+
+---------1---------2---------3---------4---------5---------6---------7---------8
+12345678911234567892123456789312345678941234567895123456789612345678971234567898
+000010 IDENTIFICATION DIVISION. MODTGHERE
+000020 PROGRAM-ID. SAMPLE.
+000030 AUTHOR. TEST SAM.
+000040 DATE-WRITTEN. 5 February 2013
+000041
+000042* A sample program just to show the form.
+000043* The program copies its input to the output,
+000044* and counts the number of records.
+000045* At the end this number is printed.
+000046
+000050 ENVIRONMENT DIVISION.
+000060 INPUT-OUTPUT SECTION.
+000070 FILE-CONTROL.
+000080 SELECT STUDENT-FILE ASSIGN TO SYSIN
+000090 ORGANIZATION IS LINE SEQUENTIAL.
+000100 SELECT PRINT-FILE ASSIGN TO SYSOUT
+000110 ORGANIZATION IS LINE SEQUENTIAL.
+000120
+000130 DATA DIVISION.
+000140 FILE SECTION.
+000150 FD STUDENT-FILE
+000160 RECORD CONTAINS 43 CHARACTERS
+000170 DATA RECORD IS STUDENT-IN.
+000180 01 STUDENT-IN PIC X(43).
+000190
+000200 FD PRINT-FILE
+000210 RECORD CONTAINS 80 CHARACTERS
+000220 DATA RECORD IS PRINT-LINE.
+000230 01 PRINT-LINE PIC X(80).
+000240
+000250 WORKING-STORAGE SECTION.
+000260 01 DATA-REMAINS-SWITCH PIC X(2) VALUE SPACES.
+000261 01 RECORDS-WRITTEN PIC 99.
+000270
+000280 01 DETAIL-LINE.
+000290 05 FILLER PIC X(7) VALUE SPACES.
+000300 05 RECORD-IMAGE PIC X(43).
+000310 05 FILLER PIC X(30) VALUE SPACES.
+000311
+000312 01 SUMMARY-LINE.
+000313 05 FILLER PIC X(7) VALUE SPACES.
+000314 05 TOTAL-READ PIC 99.
+000315 05 FILLER PIC X VALUE SPACE.
+000316 05 FILLER PIC X(17)
+000317 VALUE 'Records were read'.
+000318 05 FILLER PIC X(53) VALUE SPACES.
+000319
+000320 PROCEDURE DIVISION.
+000321
+000330 PREPARE-SENIOR-REPORT.
+000340 OPEN INPUT STUDENT-FILE
+000350 OUTPUT PRINT-FILE.
+000351 MOVE ZERO TO RECORDS-WRITTEN.
+000360 READ STUDENT-FILE
+000370 AT END MOVE 'NO' TO DATA-REMAINS-SWITCH
+000380 END-READ.
+000390 PERFORM PROCESS-RECORDS
+000410 UNTIL DATA-REMAINS-SWITCH = 'NO'.
+000411 PERFORM PRINT-SUMMARY.
+000420 CLOSE STUDENT-FILE
+000430 PRINT-FILE.
+000440 STOP RUN.
+000450
+000460 PROCESS-RECORDS.
+000470 MOVE STUDENT-IN TO RECORD-IMAGE.
+000480 MOVE DETAIL-LINE TO PRINT-LINE.
+000490 WRITE PRINT-LINE.
+000500 ADD 1 TO RECORDS-WRITTEN.
+000510 READ STUDENT-FILE
+000520 AT END MOVE 'NO' TO DATA-REMAINS-SWITCH
+000530 END-READ.
+000540
+000550 PRINT-SUMMARY.
+000560 MOVE RECORDS-WRITTEN TO TOTAL-READ.
+000570 MOVE SUMMARY-LINE TO PRINT-LINE.
+000571 WRITE PRINT-LINE.
+000572
+000580
+
+
+
diff --git a/static/mdeditor/js/lib/codemirror/mode/coffeescript/coffeescript.js b/static/mdeditor/js/lib/codemirror/mode/coffeescript/coffeescript.js
new file mode 100644
index 0000000..da0eb2d
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/coffeescript/coffeescript.js
@@ -0,0 +1,369 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+/**
+ * Link to the project's GitHub page:
+ * https://github.com/pickhardt/coffeescript-codemirror-mode
+ */
+(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) {
+"use strict";
+
+CodeMirror.defineMode("coffeescript", function(conf, parserConf) {
+ var ERRORCLASS = "error";
+
+ function wordRegexp(words) {
+ return new RegExp("^((" + words.join(")|(") + "))\\b");
+ }
+
+ var operators = /^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?|(or|and|\|\||&&|\?)=)/;
+ var delimiters = /^(?:[()\[\]{},:`=;]|\.\.?\.?)/;
+ var identifiers = /^[_A-Za-z$][_A-Za-z$0-9]*/;
+ var properties = /^(@|this\.)[_A-Za-z$][_A-Za-z$0-9]*/;
+
+ var wordOperators = wordRegexp(["and", "or", "not",
+ "is", "isnt", "in",
+ "instanceof", "typeof"]);
+ var indentKeywords = ["for", "while", "loop", "if", "unless", "else",
+ "switch", "try", "catch", "finally", "class"];
+ var commonKeywords = ["break", "by", "continue", "debugger", "delete",
+ "do", "in", "of", "new", "return", "then",
+ "this", "@", "throw", "when", "until", "extends"];
+
+ var keywords = wordRegexp(indentKeywords.concat(commonKeywords));
+
+ indentKeywords = wordRegexp(indentKeywords);
+
+
+ var stringPrefixes = /^('{3}|\"{3}|['\"])/;
+ var regexPrefixes = /^(\/{3}|\/)/;
+ var commonConstants = ["Infinity", "NaN", "undefined", "null", "true", "false", "on", "off", "yes", "no"];
+ var constants = wordRegexp(commonConstants);
+
+ // Tokenizers
+ function tokenBase(stream, state) {
+ // Handle scope changes
+ if (stream.sol()) {
+ if (state.scope.align === null) state.scope.align = false;
+ var scopeOffset = state.scope.offset;
+ if (stream.eatSpace()) {
+ var lineOffset = stream.indentation();
+ if (lineOffset > scopeOffset && state.scope.type == "coffee") {
+ return "indent";
+ } else if (lineOffset < scopeOffset) {
+ return "dedent";
+ }
+ return null;
+ } else {
+ if (scopeOffset > 0) {
+ dedent(stream, state);
+ }
+ }
+ }
+ if (stream.eatSpace()) {
+ return null;
+ }
+
+ var ch = stream.peek();
+
+ // Handle docco title comment (single line)
+ if (stream.match("####")) {
+ stream.skipToEnd();
+ return "comment";
+ }
+
+ // Handle multi line comments
+ if (stream.match("###")) {
+ state.tokenize = longComment;
+ return state.tokenize(stream, state);
+ }
+
+ // Single line comment
+ if (ch === "#") {
+ stream.skipToEnd();
+ return "comment";
+ }
+
+ // Handle number literals
+ if (stream.match(/^-?[0-9\.]/, false)) {
+ var floatLiteral = false;
+ // Floats
+ if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) {
+ floatLiteral = true;
+ }
+ if (stream.match(/^-?\d+\.\d*/)) {
+ floatLiteral = true;
+ }
+ if (stream.match(/^-?\.\d+/)) {
+ floatLiteral = true;
+ }
+
+ if (floatLiteral) {
+ // prevent from getting extra . on 1..
+ if (stream.peek() == "."){
+ stream.backUp(1);
+ }
+ return "number";
+ }
+ // Integers
+ var intLiteral = false;
+ // Hex
+ if (stream.match(/^-?0x[0-9a-f]+/i)) {
+ intLiteral = true;
+ }
+ // Decimal
+ if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) {
+ intLiteral = true;
+ }
+ // Zero by itself with no other piece of number.
+ if (stream.match(/^-?0(?![\dx])/i)) {
+ intLiteral = true;
+ }
+ if (intLiteral) {
+ return "number";
+ }
+ }
+
+ // Handle strings
+ if (stream.match(stringPrefixes)) {
+ state.tokenize = tokenFactory(stream.current(), false, "string");
+ return state.tokenize(stream, state);
+ }
+ // Handle regex literals
+ if (stream.match(regexPrefixes)) {
+ if (stream.current() != "/" || stream.match(/^.*\//, false)) { // prevent highlight of division
+ state.tokenize = tokenFactory(stream.current(), true, "string-2");
+ return state.tokenize(stream, state);
+ } else {
+ stream.backUp(1);
+ }
+ }
+
+ // Handle operators and delimiters
+ if (stream.match(operators) || stream.match(wordOperators)) {
+ return "operator";
+ }
+ if (stream.match(delimiters)) {
+ return "punctuation";
+ }
+
+ if (stream.match(constants)) {
+ return "atom";
+ }
+
+ if (stream.match(keywords)) {
+ return "keyword";
+ }
+
+ if (stream.match(identifiers)) {
+ return "variable";
+ }
+
+ if (stream.match(properties)) {
+ return "property";
+ }
+
+ // Handle non-detected items
+ stream.next();
+ return ERRORCLASS;
+ }
+
+ function tokenFactory(delimiter, singleline, outclass) {
+ return function(stream, state) {
+ while (!stream.eol()) {
+ stream.eatWhile(/[^'"\/\\]/);
+ if (stream.eat("\\")) {
+ stream.next();
+ if (singleline && stream.eol()) {
+ return outclass;
+ }
+ } else if (stream.match(delimiter)) {
+ state.tokenize = tokenBase;
+ return outclass;
+ } else {
+ stream.eat(/['"\/]/);
+ }
+ }
+ if (singleline) {
+ if (parserConf.singleLineStringErrors) {
+ outclass = ERRORCLASS;
+ } else {
+ state.tokenize = tokenBase;
+ }
+ }
+ return outclass;
+ };
+ }
+
+ function longComment(stream, state) {
+ while (!stream.eol()) {
+ stream.eatWhile(/[^#]/);
+ if (stream.match("###")) {
+ state.tokenize = tokenBase;
+ break;
+ }
+ stream.eatWhile("#");
+ }
+ return "comment";
+ }
+
+ function indent(stream, state, type) {
+ type = type || "coffee";
+ var offset = 0, align = false, alignOffset = null;
+ for (var scope = state.scope; scope; scope = scope.prev) {
+ if (scope.type === "coffee" || scope.type == "}") {
+ offset = scope.offset + conf.indentUnit;
+ break;
+ }
+ }
+ if (type !== "coffee") {
+ align = null;
+ alignOffset = stream.column() + stream.current().length;
+ } else if (state.scope.align) {
+ state.scope.align = false;
+ }
+ state.scope = {
+ offset: offset,
+ type: type,
+ prev: state.scope,
+ align: align,
+ alignOffset: alignOffset
+ };
+ }
+
+ function dedent(stream, state) {
+ if (!state.scope.prev) return;
+ if (state.scope.type === "coffee") {
+ var _indent = stream.indentation();
+ var matched = false;
+ for (var scope = state.scope; scope; scope = scope.prev) {
+ if (_indent === scope.offset) {
+ matched = true;
+ break;
+ }
+ }
+ if (!matched) {
+ return true;
+ }
+ while (state.scope.prev && state.scope.offset !== _indent) {
+ state.scope = state.scope.prev;
+ }
+ return false;
+ } else {
+ state.scope = state.scope.prev;
+ return false;
+ }
+ }
+
+ function tokenLexer(stream, state) {
+ var style = state.tokenize(stream, state);
+ var current = stream.current();
+
+ // Handle "." connected identifiers
+ if (current === ".") {
+ style = state.tokenize(stream, state);
+ current = stream.current();
+ if (/^\.[\w$]+$/.test(current)) {
+ return "variable";
+ } else {
+ return ERRORCLASS;
+ }
+ }
+
+ // Handle scope changes.
+ if (current === "return") {
+ state.dedent = true;
+ }
+ if (((current === "->" || current === "=>") &&
+ !state.lambda &&
+ !stream.peek())
+ || style === "indent") {
+ indent(stream, state);
+ }
+ var delimiter_index = "[({".indexOf(current);
+ if (delimiter_index !== -1) {
+ indent(stream, state, "])}".slice(delimiter_index, delimiter_index+1));
+ }
+ if (indentKeywords.exec(current)){
+ indent(stream, state);
+ }
+ if (current == "then"){
+ dedent(stream, state);
+ }
+
+
+ if (style === "dedent") {
+ if (dedent(stream, state)) {
+ return ERRORCLASS;
+ }
+ }
+ delimiter_index = "])}".indexOf(current);
+ if (delimiter_index !== -1) {
+ while (state.scope.type == "coffee" && state.scope.prev)
+ state.scope = state.scope.prev;
+ if (state.scope.type == current)
+ state.scope = state.scope.prev;
+ }
+ if (state.dedent && stream.eol()) {
+ if (state.scope.type == "coffee" && state.scope.prev)
+ state.scope = state.scope.prev;
+ state.dedent = false;
+ }
+
+ return style;
+ }
+
+ var external = {
+ startState: function(basecolumn) {
+ return {
+ tokenize: tokenBase,
+ scope: {offset:basecolumn || 0, type:"coffee", prev: null, align: false},
+ lastToken: null,
+ lambda: false,
+ dedent: 0
+ };
+ },
+
+ token: function(stream, state) {
+ var fillAlign = state.scope.align === null && state.scope;
+ if (fillAlign && stream.sol()) fillAlign.align = false;
+
+ var style = tokenLexer(stream, state);
+ if (fillAlign && style && style != "comment") fillAlign.align = true;
+
+ state.lastToken = {style:style, content: stream.current()};
+
+ if (stream.eol() && stream.lambda) {
+ state.lambda = false;
+ }
+
+ return style;
+ },
+
+ indent: function(state, text) {
+ if (state.tokenize != tokenBase) return 0;
+ var scope = state.scope;
+ var closer = text && "])}".indexOf(text.charAt(0)) > -1;
+ if (closer) while (scope.type == "coffee" && scope.prev) scope = scope.prev;
+ var closes = closer && scope.type === text.charAt(0);
+ if (scope.align)
+ return scope.alignOffset - (closes ? 1 : 0);
+ else
+ return (closes ? scope.prev : scope).offset;
+ },
+
+ lineComment: "#",
+ fold: "indent"
+ };
+ return external;
+});
+
+CodeMirror.defineMIME("text/x-coffeescript", "coffeescript");
+
+});
diff --git a/static/mdeditor/js/lib/codemirror/mode/coffeescript/index.html b/static/mdeditor/js/lib/codemirror/mode/coffeescript/index.html
new file mode 100644
index 0000000..93a5f4f
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/coffeescript/index.html
@@ -0,0 +1,740 @@
+
+
+CodeMirror: CoffeeScript mode
+
+
+
+
+
+
+
+
+
+
+CoffeeScript mode
+
+# CoffeeScript mode for CodeMirror
+# Copyright (c) 2011 Jeff Pickhardt, released under
+# the MIT License.
+#
+# Modified from the Python CodeMirror mode, which also is
+# under the MIT License Copyright (c) 2010 Timothy Farrell.
+#
+# The following script, Underscore.coffee, is used to
+# demonstrate CoffeeScript mode for CodeMirror.
+#
+# To download CoffeeScript mode for CodeMirror, go to:
+# https://github.com/pickhardt/coffeescript-codemirror-mode
+
+# **Underscore.coffee
+# (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.**
+# Underscore is freely distributable under the terms of the
+# [MIT license](http://en.wikipedia.org/wiki/MIT_License).
+# Portions of Underscore are inspired by or borrowed from
+# [Prototype.js](http://prototypejs.org/api), Oliver Steele's
+# [Functional](http://osteele.com), and John Resig's
+# [Micro-Templating](http://ejohn.org).
+# For all details and documentation:
+# http://documentcloud.github.com/underscore/
+
+
+# Baseline setup
+# --------------
+
+# Establish the root object, `window` in the browser, or `global` on the server.
+root = this
+
+
+# Save the previous value of the `_` variable.
+previousUnderscore = root._
+
+### Multiline
+ comment
+###
+
+# Establish the object that gets thrown to break out of a loop iteration.
+# `StopIteration` is SOP on Mozilla.
+breaker = if typeof(StopIteration) is 'undefined' then '__break__' else StopIteration
+
+
+#### Docco style single line comment (title)
+
+
+# Helper function to escape **RegExp** contents, because JS doesn't have one.
+escapeRegExp = (string) -> string.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1')
+
+
+# Save bytes in the minified (but not gzipped) version:
+ArrayProto = Array.prototype
+ObjProto = Object.prototype
+
+
+# Create quick reference variables for speed access to core prototypes.
+slice = ArrayProto.slice
+unshift = ArrayProto.unshift
+toString = ObjProto.toString
+hasOwnProperty = ObjProto.hasOwnProperty
+propertyIsEnumerable = ObjProto.propertyIsEnumerable
+
+
+# All **ECMA5** native implementations we hope to use are declared here.
+nativeForEach = ArrayProto.forEach
+nativeMap = ArrayProto.map
+nativeReduce = ArrayProto.reduce
+nativeReduceRight = ArrayProto.reduceRight
+nativeFilter = ArrayProto.filter
+nativeEvery = ArrayProto.every
+nativeSome = ArrayProto.some
+nativeIndexOf = ArrayProto.indexOf
+nativeLastIndexOf = ArrayProto.lastIndexOf
+nativeIsArray = Array.isArray
+nativeKeys = Object.keys
+
+
+# Create a safe reference to the Underscore object for use below.
+_ = (obj) -> new wrapper(obj)
+
+
+# Export the Underscore object for **CommonJS**.
+if typeof(exports) != 'undefined' then exports._ = _
+
+
+# Export Underscore to global scope.
+root._ = _
+
+
+# Current version.
+_.VERSION = '1.1.0'
+
+
+# Collection Functions
+# --------------------
+
+# The cornerstone, an **each** implementation.
+# Handles objects implementing **forEach**, arrays, and raw objects.
+_.each = (obj, iterator, context) ->
+ try
+ if nativeForEach and obj.forEach is nativeForEach
+ obj.forEach iterator, context
+ else if _.isNumber obj.length
+ iterator.call context, obj[i], i, obj for i in [0...obj.length]
+ else
+ iterator.call context, val, key, obj for own key, val of obj
+ catch e
+ throw e if e isnt breaker
+ obj
+
+
+# Return the results of applying the iterator to each element. Use JavaScript
+# 1.6's version of **map**, if possible.
+_.map = (obj, iterator, context) ->
+ return obj.map(iterator, context) if nativeMap and obj.map is nativeMap
+ results = []
+ _.each obj, (value, index, list) ->
+ results.push iterator.call context, value, index, list
+ results
+
+
+# **Reduce** builds up a single result from a list of values. Also known as
+# **inject**, or **foldl**. Uses JavaScript 1.8's version of **reduce**, if possible.
+_.reduce = (obj, iterator, memo, context) ->
+ if nativeReduce and obj.reduce is nativeReduce
+ iterator = _.bind iterator, context if context
+ return obj.reduce iterator, memo
+ _.each obj, (value, index, list) ->
+ memo = iterator.call context, memo, value, index, list
+ memo
+
+
+# The right-associative version of **reduce**, also known as **foldr**. Uses
+# JavaScript 1.8's version of **reduceRight**, if available.
+_.reduceRight = (obj, iterator, memo, context) ->
+ if nativeReduceRight and obj.reduceRight is nativeReduceRight
+ iterator = _.bind iterator, context if context
+ return obj.reduceRight iterator, memo
+ reversed = _.clone(_.toArray(obj)).reverse()
+ _.reduce reversed, iterator, memo, context
+
+
+# Return the first value which passes a truth test.
+_.detect = (obj, iterator, context) ->
+ result = null
+ _.each obj, (value, index, list) ->
+ if iterator.call context, value, index, list
+ result = value
+ _.breakLoop()
+ result
+
+
+# Return all the elements that pass a truth test. Use JavaScript 1.6's
+# **filter**, if it exists.
+_.filter = (obj, iterator, context) ->
+ return obj.filter iterator, context if nativeFilter and obj.filter is nativeFilter
+ results = []
+ _.each obj, (value, index, list) ->
+ results.push value if iterator.call context, value, index, list
+ results
+
+
+# Return all the elements for which a truth test fails.
+_.reject = (obj, iterator, context) ->
+ results = []
+ _.each obj, (value, index, list) ->
+ results.push value if not iterator.call context, value, index, list
+ results
+
+
+# Determine whether all of the elements match a truth test. Delegate to
+# JavaScript 1.6's **every**, if it is present.
+_.every = (obj, iterator, context) ->
+ iterator ||= _.identity
+ return obj.every iterator, context if nativeEvery and obj.every is nativeEvery
+ result = true
+ _.each obj, (value, index, list) ->
+ _.breakLoop() unless (result = result and iterator.call(context, value, index, list))
+ result
+
+
+# Determine if at least one element in the object matches a truth test. Use
+# JavaScript 1.6's **some**, if it exists.
+_.some = (obj, iterator, context) ->
+ iterator ||= _.identity
+ return obj.some iterator, context if nativeSome and obj.some is nativeSome
+ result = false
+ _.each obj, (value, index, list) ->
+ _.breakLoop() if (result = iterator.call(context, value, index, list))
+ result
+
+
+# Determine if a given value is included in the array or object,
+# based on `===`.
+_.include = (obj, target) ->
+ return _.indexOf(obj, target) isnt -1 if nativeIndexOf and obj.indexOf is nativeIndexOf
+ return true for own key, val of obj when val is target
+ false
+
+
+# Invoke a method with arguments on every item in a collection.
+_.invoke = (obj, method) ->
+ args = _.rest arguments, 2
+ (if method then val[method] else val).apply(val, args) for val in obj
+
+
+# Convenience version of a common use case of **map**: fetching a property.
+_.pluck = (obj, key) ->
+ _.map(obj, (val) -> val[key])
+
+
+# Return the maximum item or (item-based computation).
+_.max = (obj, iterator, context) ->
+ return Math.max.apply(Math, obj) if not iterator and _.isArray(obj)
+ result = computed: -Infinity
+ _.each obj, (value, index, list) ->
+ computed = if iterator then iterator.call(context, value, index, list) else value
+ computed >= result.computed and (result = {value: value, computed: computed})
+ result.value
+
+
+# Return the minimum element (or element-based computation).
+_.min = (obj, iterator, context) ->
+ return Math.min.apply(Math, obj) if not iterator and _.isArray(obj)
+ result = computed: Infinity
+ _.each obj, (value, index, list) ->
+ computed = if iterator then iterator.call(context, value, index, list) else value
+ computed < result.computed and (result = {value: value, computed: computed})
+ result.value
+
+
+# Sort the object's values by a criterion produced by an iterator.
+_.sortBy = (obj, iterator, context) ->
+ _.pluck(((_.map obj, (value, index, list) ->
+ {value: value, criteria: iterator.call(context, value, index, list)}
+ ).sort((left, right) ->
+ a = left.criteria; b = right.criteria
+ if a < b then -1 else if a > b then 1 else 0
+ )), 'value')
+
+
+# Use a comparator function to figure out at what index an object should
+# be inserted so as to maintain order. Uses binary search.
+_.sortedIndex = (array, obj, iterator) ->
+ iterator ||= _.identity
+ low = 0
+ high = array.length
+ while low < high
+ mid = (low + high) >> 1
+ if iterator(array[mid]) < iterator(obj) then low = mid + 1 else high = mid
+ low
+
+
+# Convert anything iterable into a real, live array.
+_.toArray = (iterable) ->
+ return [] if (!iterable)
+ return iterable.toArray() if (iterable.toArray)
+ return iterable if (_.isArray(iterable))
+ return slice.call(iterable) if (_.isArguments(iterable))
+ _.values(iterable)
+
+
+# Return the number of elements in an object.
+_.size = (obj) -> _.toArray(obj).length
+
+
+# Array Functions
+# ---------------
+
+# Get the first element of an array. Passing `n` will return the first N
+# values in the array. Aliased as **head**. The `guard` check allows it to work
+# with **map**.
+_.first = (array, n, guard) ->
+ if n and not guard then slice.call(array, 0, n) else array[0]
+
+
+# Returns everything but the first entry of the array. Aliased as **tail**.
+# Especially useful on the arguments object. Passing an `index` will return
+# the rest of the values in the array from that index onward. The `guard`
+# check allows it to work with **map**.
+_.rest = (array, index, guard) ->
+ slice.call(array, if _.isUndefined(index) or guard then 1 else index)
+
+
+# Get the last element of an array.
+_.last = (array) -> array[array.length - 1]
+
+
+# Trim out all falsy values from an array.
+_.compact = (array) -> item for item in array when item
+
+
+# Return a completely flattened version of an array.
+_.flatten = (array) ->
+ _.reduce array, (memo, value) ->
+ return memo.concat(_.flatten(value)) if _.isArray value
+ memo.push value
+ memo
+ , []
+
+
+# Return a version of the array that does not contain the specified value(s).
+_.without = (array) ->
+ values = _.rest arguments
+ val for val in _.toArray(array) when not _.include values, val
+
+
+# Produce a duplicate-free version of the array. If the array has already
+# been sorted, you have the option of using a faster algorithm.
+_.uniq = (array, isSorted) ->
+ memo = []
+ for el, i in _.toArray array
+ memo.push el if i is 0 || (if isSorted is true then _.last(memo) isnt el else not _.include(memo, el))
+ memo
+
+
+# Produce an array that contains every item shared between all the
+# passed-in arrays.
+_.intersect = (array) ->
+ rest = _.rest arguments
+ _.select _.uniq(array), (item) ->
+ _.all rest, (other) ->
+ _.indexOf(other, item) >= 0
+
+
+# Zip together multiple lists into a single array -- elements that share
+# an index go together.
+_.zip = ->
+ length = _.max _.pluck arguments, 'length'
+ results = new Array length
+ for i in [0...length]
+ results[i] = _.pluck arguments, String i
+ results
+
+
+# If the browser doesn't supply us with **indexOf** (I'm looking at you, MSIE),
+# we need this function. Return the position of the first occurrence of an
+# item in an array, or -1 if the item is not included in the array.
+_.indexOf = (array, item) ->
+ return array.indexOf item if nativeIndexOf and array.indexOf is nativeIndexOf
+ i = 0; l = array.length
+ while l - i
+ if array[i] is item then return i else i++
+ -1
+
+
+# Provide JavaScript 1.6's **lastIndexOf**, delegating to the native function,
+# if possible.
+_.lastIndexOf = (array, item) ->
+ return array.lastIndexOf(item) if nativeLastIndexOf and array.lastIndexOf is nativeLastIndexOf
+ i = array.length
+ while i
+ if array[i] is item then return i else i--
+ -1
+
+
+# Generate an integer Array containing an arithmetic progression. A port of
+# [the native Python **range** function](http://docs.python.org/library/functions.html#range).
+_.range = (start, stop, step) ->
+ a = arguments
+ solo = a.length <= 1
+ i = start = if solo then 0 else a[0]
+ stop = if solo then a[0] else a[1]
+ step = a[2] or 1
+ len = Math.ceil((stop - start) / step)
+ return [] if len <= 0
+ range = new Array len
+ idx = 0
+ loop
+ return range if (if step > 0 then i - stop else stop - i) >= 0
+ range[idx] = i
+ idx++
+ i+= step
+
+
+# Function Functions
+# ------------------
+
+# Create a function bound to a given object (assigning `this`, and arguments,
+# optionally). Binding with arguments is also known as **curry**.
+_.bind = (func, obj) ->
+ args = _.rest arguments, 2
+ -> func.apply obj or root, args.concat arguments
+
+
+# Bind all of an object's methods to that object. Useful for ensuring that
+# all callbacks defined on an object belong to it.
+_.bindAll = (obj) ->
+ funcs = if arguments.length > 1 then _.rest(arguments) else _.functions(obj)
+ _.each funcs, (f) -> obj[f] = _.bind obj[f], obj
+ obj
+
+
+# Delays a function for the given number of milliseconds, and then calls
+# it with the arguments supplied.
+_.delay = (func, wait) ->
+ args = _.rest arguments, 2
+ setTimeout((-> func.apply(func, args)), wait)
+
+
+# Memoize an expensive function by storing its results.
+_.memoize = (func, hasher) ->
+ memo = {}
+ hasher or= _.identity
+ ->
+ key = hasher.apply this, arguments
+ return memo[key] if key of memo
+ memo[key] = func.apply this, arguments
+
+
+# Defers a function, scheduling it to run after the current call stack has
+# cleared.
+_.defer = (func) ->
+ _.delay.apply _, [func, 1].concat _.rest arguments
+
+
+# Returns the first function passed as an argument to the second,
+# allowing you to adjust arguments, run code before and after, and
+# conditionally execute the original function.
+_.wrap = (func, wrapper) ->
+ -> wrapper.apply wrapper, [func].concat arguments
+
+
+# Returns a function that is the composition of a list of functions, each
+# consuming the return value of the function that follows.
+_.compose = ->
+ funcs = arguments
+ ->
+ args = arguments
+ for i in [funcs.length - 1..0] by -1
+ args = [funcs[i].apply(this, args)]
+ args[0]
+
+
+# Object Functions
+# ----------------
+
+# Retrieve the names of an object's properties.
+_.keys = nativeKeys or (obj) ->
+ return _.range 0, obj.length if _.isArray(obj)
+ key for key, val of obj
+
+
+# Retrieve the values of an object's properties.
+_.values = (obj) ->
+ _.map obj, _.identity
+
+
+# Return a sorted list of the function names available in Underscore.
+_.functions = (obj) ->
+ _.filter(_.keys(obj), (key) -> _.isFunction(obj[key])).sort()
+
+
+# Extend a given object with all of the properties in a source object.
+_.extend = (obj) ->
+ for source in _.rest(arguments)
+ obj[key] = val for key, val of source
+ obj
+
+
+# Create a (shallow-cloned) duplicate of an object.
+_.clone = (obj) ->
+ return obj.slice 0 if _.isArray obj
+ _.extend {}, obj
+
+
+# Invokes interceptor with the obj, and then returns obj.
+# The primary purpose of this method is to "tap into" a method chain,
+# in order to perform operations on intermediate results within
+ the chain.
+_.tap = (obj, interceptor) ->
+ interceptor obj
+ obj
+
+
+# Perform a deep comparison to check if two objects are equal.
+_.isEqual = (a, b) ->
+ # Check object identity.
+ return true if a is b
+ # Different types?
+ atype = typeof(a); btype = typeof(b)
+ return false if atype isnt btype
+ # Basic equality test (watch out for coercions).
+ return true if `a == b`
+ # One is falsy and the other truthy.
+ return false if (!a and b) or (a and !b)
+ # One of them implements an `isEqual()`?
+ return a.isEqual(b) if a.isEqual
+ # Check dates' integer values.
+ return a.getTime() is b.getTime() if _.isDate(a) and _.isDate(b)
+ # Both are NaN?
+ return false if _.isNaN(a) and _.isNaN(b)
+ # Compare regular expressions.
+ if _.isRegExp(a) and _.isRegExp(b)
+ return a.source is b.source and
+ a.global is b.global and
+ a.ignoreCase is b.ignoreCase and
+ a.multiline is b.multiline
+ # If a is not an object by this point, we can't handle it.
+ return false if atype isnt 'object'
+ # Check for different array lengths before comparing contents.
+ return false if a.length and (a.length isnt b.length)
+ # Nothing else worked, deep compare the contents.
+ aKeys = _.keys(a); bKeys = _.keys(b)
+ # Different object sizes?
+ return false if aKeys.length isnt bKeys.length
+ # Recursive comparison of contents.
+ return false for key, val of a when !(key of b) or !_.isEqual(val, b[key])
+ true
+
+
+# Is a given array or object empty?
+_.isEmpty = (obj) ->
+ return obj.length is 0 if _.isArray(obj) or _.isString(obj)
+ return false for own key of obj
+ true
+
+
+# Is a given value a DOM element?
+_.isElement = (obj) -> obj and obj.nodeType is 1
+
+
+# Is a given value an array?
+_.isArray = nativeIsArray or (obj) -> !!(obj and obj.concat and obj.unshift and not obj.callee)
+
+
+# Is a given variable an arguments object?
+_.isArguments = (obj) -> obj and obj.callee
+
+
+# Is the given value a function?
+_.isFunction = (obj) -> !!(obj and obj.constructor and obj.call and obj.apply)
+
+
+# Is the given value a string?
+_.isString = (obj) -> !!(obj is '' or (obj and obj.charCodeAt and obj.substr))
+
+
+# Is a given value a number?
+_.isNumber = (obj) -> (obj is +obj) or toString.call(obj) is '[object Number]'
+
+
+# Is a given value a boolean?
+_.isBoolean = (obj) -> obj is true or obj is false
+
+
+# Is a given value a Date?
+_.isDate = (obj) -> !!(obj and obj.getTimezoneOffset and obj.setUTCFullYear)
+
+
+# Is the given value a regular expression?
+_.isRegExp = (obj) -> !!(obj and obj.exec and (obj.ignoreCase or obj.ignoreCase is false))
+
+
+# Is the given value NaN -- this one is interesting. `NaN != NaN`, and
+# `isNaN(undefined) == true`, so we make sure it's a number first.
+_.isNaN = (obj) -> _.isNumber(obj) and window.isNaN(obj)
+
+
+# Is a given value equal to null?
+_.isNull = (obj) -> obj is null
+
+
+# Is a given variable undefined?
+_.isUndefined = (obj) -> typeof obj is 'undefined'
+
+
+# Utility Functions
+# -----------------
+
+# Run Underscore.js in noConflict mode, returning the `_` variable to its
+# previous owner. Returns a reference to the Underscore object.
+_.noConflict = ->
+ root._ = previousUnderscore
+ this
+
+
+# Keep the identity function around for default iterators.
+_.identity = (value) -> value
+
+
+# Run a function `n` times.
+_.times = (n, iterator, context) ->
+ iterator.call context, i for i in [0...n]
+
+
+# Break out of the middle of an iteration.
+_.breakLoop = -> throw breaker
+
+
+# Add your own custom functions to the Underscore object, ensuring that
+# they're correctly added to the OOP wrapper as well.
+_.mixin = (obj) ->
+ for name in _.functions(obj)
+ addToWrapper name, _[name] = obj[name]
+
+
+# Generate a unique integer id (unique within the entire client session).
+# Useful for temporary DOM ids.
+idCounter = 0
+_.uniqueId = (prefix) ->
+ (prefix or '') + idCounter++
+
+
+# By default, Underscore uses **ERB**-style template delimiters, change the
+# following template settings to use alternative delimiters.
+_.templateSettings = {
+ start: '<%'
+ end: '%>'
+ interpolate: /<%=(.+?)%>/g
+}
+
+
+# JavaScript templating a-la **ERB**, pilfered from John Resig's
+# *Secrets of the JavaScript Ninja*, page 83.
+# Single-quote fix from Rick Strahl.
+# With alterations for arbitrary delimiters, and to preserve whitespace.
+_.template = (str, data) ->
+ c = _.templateSettings
+ endMatch = new RegExp("'(?=[^"+c.end.substr(0, 1)+"]*"+escapeRegExp(c.end)+")","g")
+ fn = new Function 'obj',
+ 'var p=[],print=function(){p.push.apply(p,arguments);};' +
+ 'with(obj||{}){p.push(\'' +
+ str.replace(/\r/g, '\\r')
+ .replace(/\n/g, '\\n')
+ .replace(/\t/g, '\\t')
+ .replace(endMatch,"���")
+ .split("'").join("\\'")
+ .split("���").join("'")
+ .replace(c.interpolate, "',$1,'")
+ .split(c.start).join("');")
+ .split(c.end).join("p.push('") +
+ "');}return p.join('');"
+ if data then fn(data) else fn
+
+
+# Aliases
+# -------
+
+_.forEach = _.each
+_.foldl = _.inject = _.reduce
+_.foldr = _.reduceRight
+_.select = _.filter
+_.all = _.every
+_.any = _.some
+_.contains = _.include
+_.head = _.first
+_.tail = _.rest
+_.methods = _.functions
+
+
+# Setup the OOP Wrapper
+# ---------------------
+
+# If Underscore is called as a function, it returns a wrapped object that
+# can be used OO-style. This wrapper holds altered versions of all the
+# underscore functions. Wrapped objects may be chained.
+wrapper = (obj) ->
+ this._wrapped = obj
+ this
+
+
+# Helper function to continue chaining intermediate results.
+result = (obj, chain) ->
+ if chain then _(obj).chain() else obj
+
+
+# A method to easily add functions to the OOP wrapper.
+addToWrapper = (name, func) ->
+ wrapper.prototype[name] = ->
+ args = _.toArray arguments
+ unshift.call args, this._wrapped
+ result func.apply(_, args), this._chain
+
+
+# Add all ofthe Underscore functions to the wrapper object.
+_.mixin _
+
+
+# Add all mutator Array functions to the wrapper.
+_.each ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], (name) ->
+ method = Array.prototype[name]
+ wrapper.prototype[name] = ->
+ method.apply(this._wrapped, arguments)
+ result(this._wrapped, this._chain)
+
+
+# Add all accessor Array functions to the wrapper.
+_.each ['concat', 'join', 'slice'], (name) ->
+ method = Array.prototype[name]
+ wrapper.prototype[name] = ->
+ result(method.apply(this._wrapped, arguments), this._chain)
+
+
+# Start chaining a wrapped Underscore object.
+wrapper::chain = ->
+ this._chain = true
+ this
+
+
+# Extracts the result from a wrapped and chained object.
+wrapper::value = -> this._wrapped
+
+
+
+ MIME types defined: text/x-coffeescript
.
+
+ The CoffeeScript mode was written by Jeff Pickhardt.
+
+
diff --git a/static/mdeditor/js/lib/codemirror/mode/commonlisp/commonlisp.js b/static/mdeditor/js/lib/codemirror/mode/commonlisp/commonlisp.js
new file mode 100644
index 0000000..5f50b35
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/commonlisp/commonlisp.js
@@ -0,0 +1,122 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(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) {
+"use strict";
+
+CodeMirror.defineMode("commonlisp", function (config) {
+ var specialForm = /^(block|let*|return-from|catch|load-time-value|setq|eval-when|locally|symbol-macrolet|flet|macrolet|tagbody|function|multiple-value-call|the|go|multiple-value-prog1|throw|if|progn|unwind-protect|labels|progv|let|quote)$/;
+ var assumeBody = /^with|^def|^do|^prog|case$|^cond$|bind$|when$|unless$/;
+ var numLiteral = /^(?:[+\-]?(?:\d+|\d*\.\d+)(?:[efd][+\-]?\d+)?|[+\-]?\d+(?:\/[+\-]?\d+)?|#b[+\-]?[01]+|#o[+\-]?[0-7]+|#x[+\-]?[\da-f]+)/;
+ var symbol = /[^\s'`,@()\[\]";]/;
+ var type;
+
+ function readSym(stream) {
+ var ch;
+ while (ch = stream.next()) {
+ if (ch == "\\") stream.next();
+ else if (!symbol.test(ch)) { stream.backUp(1); break; }
+ }
+ return stream.current();
+ }
+
+ function base(stream, state) {
+ if (stream.eatSpace()) {type = "ws"; return null;}
+ if (stream.match(numLiteral)) return "number";
+ var ch = stream.next();
+ if (ch == "\\") ch = stream.next();
+
+ if (ch == '"') return (state.tokenize = inString)(stream, state);
+ else if (ch == "(") { type = "open"; return "bracket"; }
+ else if (ch == ")" || ch == "]") { type = "close"; return "bracket"; }
+ else if (ch == ";") { stream.skipToEnd(); type = "ws"; return "comment"; }
+ else if (/['`,@]/.test(ch)) return null;
+ else if (ch == "|") {
+ if (stream.skipTo("|")) { stream.next(); return "symbol"; }
+ else { stream.skipToEnd(); return "error"; }
+ } else if (ch == "#") {
+ var ch = stream.next();
+ if (ch == "[") { type = "open"; return "bracket"; }
+ else if (/[+\-=\.']/.test(ch)) return null;
+ else if (/\d/.test(ch) && stream.match(/^\d*#/)) return null;
+ else if (ch == "|") return (state.tokenize = inComment)(stream, state);
+ else if (ch == ":") { readSym(stream); return "meta"; }
+ else return "error";
+ } else {
+ var name = readSym(stream);
+ if (name == ".") return null;
+ type = "symbol";
+ if (name == "nil" || name == "t" || name.charAt(0) == ":") return "atom";
+ if (state.lastType == "open" && (specialForm.test(name) || assumeBody.test(name))) return "keyword";
+ if (name.charAt(0) == "&") return "variable-2";
+ return "variable";
+ }
+ }
+
+ function inString(stream, state) {
+ var escaped = false, next;
+ while (next = stream.next()) {
+ if (next == '"' && !escaped) { state.tokenize = base; break; }
+ escaped = !escaped && next == "\\";
+ }
+ return "string";
+ }
+
+ function inComment(stream, state) {
+ var next, last;
+ while (next = stream.next()) {
+ if (next == "#" && last == "|") { state.tokenize = base; break; }
+ last = next;
+ }
+ type = "ws";
+ return "comment";
+ }
+
+ return {
+ startState: function () {
+ return {ctx: {prev: null, start: 0, indentTo: 0}, lastType: null, tokenize: base};
+ },
+
+ token: function (stream, state) {
+ if (stream.sol() && typeof state.ctx.indentTo != "number")
+ state.ctx.indentTo = state.ctx.start + 1;
+
+ type = null;
+ var style = state.tokenize(stream, state);
+ if (type != "ws") {
+ if (state.ctx.indentTo == null) {
+ if (type == "symbol" && assumeBody.test(stream.current()))
+ state.ctx.indentTo = state.ctx.start + config.indentUnit;
+ else
+ state.ctx.indentTo = "next";
+ } else if (state.ctx.indentTo == "next") {
+ state.ctx.indentTo = stream.column();
+ }
+ state.lastType = type;
+ }
+ if (type == "open") state.ctx = {prev: state.ctx, start: stream.column(), indentTo: null};
+ else if (type == "close") state.ctx = state.ctx.prev || state.ctx;
+ return style;
+ },
+
+ indent: function (state, _textAfter) {
+ var i = state.ctx.indentTo;
+ return typeof i == "number" ? i : state.ctx.start + 1;
+ },
+
+ lineComment: ";;",
+ blockCommentStart: "#|",
+ blockCommentEnd: "|#"
+ };
+});
+
+CodeMirror.defineMIME("text/x-common-lisp", "commonlisp");
+
+});
diff --git a/static/mdeditor/js/lib/codemirror/mode/commonlisp/index.html b/static/mdeditor/js/lib/codemirror/mode/commonlisp/index.html
new file mode 100644
index 0000000..f2bf452
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/commonlisp/index.html
@@ -0,0 +1,177 @@
+
+
+CodeMirror: Common Lisp mode
+
+
+
+
+
+
+
+
+
+
+Common Lisp mode
+(in-package :cl-postgres)
+
+;; These are used to synthesize reader and writer names for integer
+;; reading/writing functions when the amount of bytes and the
+;; signedness is known. Both the macro that creates the functions and
+;; some macros that use them create names this way.
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (defun integer-reader-name (bytes signed)
+ (intern (with-standard-io-syntax
+ (format nil "~a~a~a~a" '#:read- (if signed "" '#:u) '#:int bytes))))
+ (defun integer-writer-name (bytes signed)
+ (intern (with-standard-io-syntax
+ (format nil "~a~a~a~a" '#:write- (if signed "" '#:u) '#:int bytes)))))
+
+(defmacro integer-reader (bytes)
+ "Create a function to read integers from a binary stream."
+ (let ((bits (* bytes 8)))
+ (labels ((return-form (signed)
+ (if signed
+ `(if (logbitp ,(1- bits) result)
+ (dpb result (byte ,(1- bits) 0) -1)
+ result)
+ `result))
+ (generate-reader (signed)
+ `(defun ,(integer-reader-name bytes signed) (socket)
+ (declare (type stream socket)
+ #.*optimize*)
+ ,(if (= bytes 1)
+ `(let ((result (the (unsigned-byte 8) (read-byte socket))))
+ (declare (type (unsigned-byte 8) result))
+ ,(return-form signed))
+ `(let ((result 0))
+ (declare (type (unsigned-byte ,bits) result))
+ ,@(loop :for byte :from (1- bytes) :downto 0
+ :collect `(setf (ldb (byte 8 ,(* 8 byte)) result)
+ (the (unsigned-byte 8) (read-byte socket))))
+ ,(return-form signed))))))
+ `(progn
+;; This causes weird errors on SBCL in some circumstances. Disabled for now.
+;; (declaim (inline ,(integer-reader-name bytes t)
+;; ,(integer-reader-name bytes nil)))
+ (declaim (ftype (function (t) (signed-byte ,bits))
+ ,(integer-reader-name bytes t)))
+ ,(generate-reader t)
+ (declaim (ftype (function (t) (unsigned-byte ,bits))
+ ,(integer-reader-name bytes nil)))
+ ,(generate-reader nil)))))
+
+(defmacro integer-writer (bytes)
+ "Create a function to write integers to a binary stream."
+ (let ((bits (* 8 bytes)))
+ `(progn
+ (declaim (inline ,(integer-writer-name bytes t)
+ ,(integer-writer-name bytes nil)))
+ (defun ,(integer-writer-name bytes nil) (socket value)
+ (declare (type stream socket)
+ (type (unsigned-byte ,bits) value)
+ #.*optimize*)
+ ,@(if (= bytes 1)
+ `((write-byte value socket))
+ (loop :for byte :from (1- bytes) :downto 0
+ :collect `(write-byte (ldb (byte 8 ,(* byte 8)) value)
+ socket)))
+ (values))
+ (defun ,(integer-writer-name bytes t) (socket value)
+ (declare (type stream socket)
+ (type (signed-byte ,bits) value)
+ #.*optimize*)
+ ,@(if (= bytes 1)
+ `((write-byte (ldb (byte 8 0) value) socket))
+ (loop :for byte :from (1- bytes) :downto 0
+ :collect `(write-byte (ldb (byte 8 ,(* byte 8)) value)
+ socket)))
+ (values)))))
+
+;; All the instances of the above that we need.
+
+(integer-reader 1)
+(integer-reader 2)
+(integer-reader 4)
+(integer-reader 8)
+
+(integer-writer 1)
+(integer-writer 2)
+(integer-writer 4)
+
+(defun write-bytes (socket bytes)
+ "Write a byte-array to a stream."
+ (declare (type stream socket)
+ (type (simple-array (unsigned-byte 8)) bytes)
+ #.*optimize*)
+ (write-sequence bytes socket))
+
+(defun write-str (socket string)
+ "Write a null-terminated string to a stream \(encoding it when UTF-8
+support is enabled.)."
+ (declare (type stream socket)
+ (type string string)
+ #.*optimize*)
+ (enc-write-string string socket)
+ (write-uint1 socket 0))
+
+(declaim (ftype (function (t unsigned-byte)
+ (simple-array (unsigned-byte 8) (*)))
+ read-bytes))
+(defun read-bytes (socket length)
+ "Read a byte array of the given length from a stream."
+ (declare (type stream socket)
+ (type fixnum length)
+ #.*optimize*)
+ (let ((result (make-array length :element-type '(unsigned-byte 8))))
+ (read-sequence result socket)
+ result))
+
+(declaim (ftype (function (t) string) read-str))
+(defun read-str (socket)
+ "Read a null-terminated string from a stream. Takes care of encoding
+when UTF-8 support is enabled."
+ (declare (type stream socket)
+ #.*optimize*)
+ (enc-read-string socket :null-terminated t))
+
+(defun skip-bytes (socket length)
+ "Skip a given number of bytes in a binary stream."
+ (declare (type stream socket)
+ (type (unsigned-byte 32) length)
+ #.*optimize*)
+ (dotimes (i length)
+ (read-byte socket)))
+
+(defun skip-str (socket)
+ "Skip a null-terminated string."
+ (declare (type stream socket)
+ #.*optimize*)
+ (loop :for char :of-type fixnum = (read-byte socket)
+ :until (zerop char)))
+
+(defun ensure-socket-is-closed (socket &key abort)
+ (when (open-stream-p socket)
+ (handler-case
+ (close socket :abort abort)
+ (error (error)
+ (warn "Ignoring the error which happened while trying to close PostgreSQL socket: ~A" error)))))
+
+
+
+ MIME types defined: text/x-common-lisp
.
+
+
diff --git a/static/mdeditor/js/lib/codemirror/mode/css/css.js b/static/mdeditor/js/lib/codemirror/mode/css/css.js
new file mode 100644
index 0000000..34355aa
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/css/css.js
@@ -0,0 +1,766 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(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) {
+"use strict";
+
+CodeMirror.defineMode("css", function(config, parserConfig) {
+ if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
+
+ var indentUnit = config.indentUnit,
+ tokenHooks = parserConfig.tokenHooks,
+ documentTypes = parserConfig.documentTypes || {},
+ mediaTypes = parserConfig.mediaTypes || {},
+ mediaFeatures = parserConfig.mediaFeatures || {},
+ propertyKeywords = parserConfig.propertyKeywords || {},
+ nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
+ fontProperties = parserConfig.fontProperties || {},
+ counterDescriptors = parserConfig.counterDescriptors || {},
+ colorKeywords = parserConfig.colorKeywords || {},
+ valueKeywords = parserConfig.valueKeywords || {},
+ allowNested = parserConfig.allowNested;
+
+ var type, override;
+ function ret(style, tp) { type = tp; return style; }
+
+ // Tokenizers
+
+ function tokenBase(stream, state) {
+ var ch = stream.next();
+ if (tokenHooks[ch]) {
+ var result = tokenHooks[ch](stream, state);
+ if (result !== false) return result;
+ }
+ if (ch == "@") {
+ stream.eatWhile(/[\w\\\-]/);
+ return ret("def", stream.current());
+ } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
+ return ret(null, "compare");
+ } else if (ch == "\"" || ch == "'") {
+ state.tokenize = tokenString(ch);
+ return state.tokenize(stream, state);
+ } else if (ch == "#") {
+ stream.eatWhile(/[\w\\\-]/);
+ return ret("atom", "hash");
+ } else if (ch == "!") {
+ stream.match(/^\s*\w*/);
+ return ret("keyword", "important");
+ } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
+ stream.eatWhile(/[\w.%]/);
+ return ret("number", "unit");
+ } else if (ch === "-") {
+ if (/[\d.]/.test(stream.peek())) {
+ stream.eatWhile(/[\w.%]/);
+ return ret("number", "unit");
+ } else if (stream.match(/^-[\w\\\-]+/)) {
+ stream.eatWhile(/[\w\\\-]/);
+ if (stream.match(/^\s*:/, false))
+ return ret("variable-2", "variable-definition");
+ return ret("variable-2", "variable");
+ } else if (stream.match(/^\w+-/)) {
+ return ret("meta", "meta");
+ }
+ } else if (/[,+>*\/]/.test(ch)) {
+ return ret(null, "select-op");
+ } else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
+ return ret("qualifier", "qualifier");
+ } else if (/[:;{}\[\]\(\)]/.test(ch)) {
+ return ret(null, ch);
+ } else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) ||
+ (ch == "d" && stream.match("omain(")) ||
+ (ch == "r" && stream.match("egexp("))) {
+ stream.backUp(1);
+ state.tokenize = tokenParenthesized;
+ return ret("property", "word");
+ } else if (/[\w\\\-]/.test(ch)) {
+ stream.eatWhile(/[\w\\\-]/);
+ return ret("property", "word");
+ } else {
+ return ret(null, null);
+ }
+ }
+
+ function tokenString(quote) {
+ return function(stream, state) {
+ var escaped = false, ch;
+ while ((ch = stream.next()) != null) {
+ if (ch == quote && !escaped) {
+ if (quote == ")") stream.backUp(1);
+ break;
+ }
+ escaped = !escaped && ch == "\\";
+ }
+ if (ch == quote || !escaped && quote != ")") state.tokenize = null;
+ return ret("string", "string");
+ };
+ }
+
+ function tokenParenthesized(stream, state) {
+ stream.next(); // Must be '('
+ if (!stream.match(/\s*[\"\')]/, false))
+ state.tokenize = tokenString(")");
+ else
+ state.tokenize = null;
+ return ret(null, "(");
+ }
+
+ // Context management
+
+ function Context(type, indent, prev) {
+ this.type = type;
+ this.indent = indent;
+ this.prev = prev;
+ }
+
+ function pushContext(state, stream, type) {
+ state.context = new Context(type, stream.indentation() + indentUnit, state.context);
+ return type;
+ }
+
+ function popContext(state) {
+ state.context = state.context.prev;
+ return state.context.type;
+ }
+
+ function pass(type, stream, state) {
+ return states[state.context.type](type, stream, state);
+ }
+ function popAndPass(type, stream, state, n) {
+ for (var i = n || 1; i > 0; i--)
+ state.context = state.context.prev;
+ return pass(type, stream, state);
+ }
+
+ // Parser
+
+ function wordAsValue(stream) {
+ var word = stream.current().toLowerCase();
+ if (valueKeywords.hasOwnProperty(word))
+ override = "atom";
+ else if (colorKeywords.hasOwnProperty(word))
+ override = "keyword";
+ else
+ override = "variable";
+ }
+
+ var states = {};
+
+ states.top = function(type, stream, state) {
+ if (type == "{") {
+ return pushContext(state, stream, "block");
+ } else if (type == "}" && state.context.prev) {
+ return popContext(state);
+ } else if (/@(media|supports|(-moz-)?document)/.test(type)) {
+ return pushContext(state, stream, "atBlock");
+ } else if (/@(font-face|counter-style)/.test(type)) {
+ state.stateArg = type;
+ return "restricted_atBlock_before";
+ } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
+ return "keyframes";
+ } else if (type && type.charAt(0) == "@") {
+ return pushContext(state, stream, "at");
+ } else if (type == "hash") {
+ override = "builtin";
+ } else if (type == "word") {
+ override = "tag";
+ } else if (type == "variable-definition") {
+ return "maybeprop";
+ } else if (type == "interpolation") {
+ return pushContext(state, stream, "interpolation");
+ } else if (type == ":") {
+ return "pseudo";
+ } else if (allowNested && type == "(") {
+ return pushContext(state, stream, "parens");
+ }
+ return state.context.type;
+ };
+
+ states.block = function(type, stream, state) {
+ if (type == "word") {
+ var word = stream.current().toLowerCase();
+ if (propertyKeywords.hasOwnProperty(word)) {
+ override = "property";
+ return "maybeprop";
+ } else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
+ override = "string-2";
+ return "maybeprop";
+ } else if (allowNested) {
+ override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag";
+ return "block";
+ } else {
+ override += " error";
+ return "maybeprop";
+ }
+ } else if (type == "meta") {
+ return "block";
+ } else if (!allowNested && (type == "hash" || type == "qualifier")) {
+ override = "error";
+ return "block";
+ } else {
+ return states.top(type, stream, state);
+ }
+ };
+
+ states.maybeprop = function(type, stream, state) {
+ if (type == ":") return pushContext(state, stream, "prop");
+ return pass(type, stream, state);
+ };
+
+ states.prop = function(type, stream, state) {
+ if (type == ";") return popContext(state);
+ if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
+ if (type == "}" || type == "{") return popAndPass(type, stream, state);
+ if (type == "(") return pushContext(state, stream, "parens");
+
+ if (type == "hash" && !/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
+ override += " error";
+ } else if (type == "word") {
+ wordAsValue(stream);
+ } else if (type == "interpolation") {
+ return pushContext(state, stream, "interpolation");
+ }
+ return "prop";
+ };
+
+ states.propBlock = function(type, _stream, state) {
+ if (type == "}") return popContext(state);
+ if (type == "word") { override = "property"; return "maybeprop"; }
+ return state.context.type;
+ };
+
+ states.parens = function(type, stream, state) {
+ if (type == "{" || type == "}") return popAndPass(type, stream, state);
+ if (type == ")") return popContext(state);
+ if (type == "(") return pushContext(state, stream, "parens");
+ if (type == "word") wordAsValue(stream);
+ return "parens";
+ };
+
+ states.pseudo = function(type, stream, state) {
+ if (type == "word") {
+ override = "variable-3";
+ return state.context.type;
+ }
+ return pass(type, stream, state);
+ };
+
+ states.atBlock = function(type, stream, state) {
+ if (type == "(") return pushContext(state, stream, "atBlock_parens");
+ if (type == "}") return popAndPass(type, stream, state);
+ if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
+
+ if (type == "word") {
+ var word = stream.current().toLowerCase();
+ if (word == "only" || word == "not" || word == "and" || word == "or")
+ override = "keyword";
+ else if (documentTypes.hasOwnProperty(word))
+ override = "tag";
+ else if (mediaTypes.hasOwnProperty(word))
+ override = "attribute";
+ else if (mediaFeatures.hasOwnProperty(word))
+ override = "property";
+ else if (propertyKeywords.hasOwnProperty(word))
+ override = "property";
+ else if (nonStandardPropertyKeywords.hasOwnProperty(word))
+ override = "string-2";
+ else if (valueKeywords.hasOwnProperty(word))
+ override = "atom";
+ else
+ override = "error";
+ }
+ return state.context.type;
+ };
+
+ states.atBlock_parens = function(type, stream, state) {
+ if (type == ")") return popContext(state);
+ if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
+ return states.atBlock(type, stream, state);
+ };
+
+ states.restricted_atBlock_before = function(type, stream, state) {
+ if (type == "{")
+ return pushContext(state, stream, "restricted_atBlock");
+ if (type == "word" && state.stateArg == "@counter-style") {
+ override = "variable";
+ return "restricted_atBlock_before";
+ }
+ return pass(type, stream, state);
+ };
+
+ states.restricted_atBlock = function(type, stream, state) {
+ if (type == "}") {
+ state.stateArg = null;
+ return popContext(state);
+ }
+ if (type == "word") {
+ if ((state.stateArg == "@font-face" && !fontProperties.hasOwnProperty(stream.current().toLowerCase())) ||
+ (state.stateArg == "@counter-style" && !counterDescriptors.hasOwnProperty(stream.current().toLowerCase())))
+ override = "error";
+ else
+ override = "property";
+ return "maybeprop";
+ }
+ return "restricted_atBlock";
+ };
+
+ states.keyframes = function(type, stream, state) {
+ if (type == "word") { override = "variable"; return "keyframes"; }
+ if (type == "{") return pushContext(state, stream, "top");
+ return pass(type, stream, state);
+ };
+
+ states.at = function(type, stream, state) {
+ if (type == ";") return popContext(state);
+ if (type == "{" || type == "}") return popAndPass(type, stream, state);
+ if (type == "word") override = "tag";
+ else if (type == "hash") override = "builtin";
+ return "at";
+ };
+
+ states.interpolation = function(type, stream, state) {
+ if (type == "}") return popContext(state);
+ if (type == "{" || type == ";") return popAndPass(type, stream, state);
+ if (type != "variable") override = "error";
+ return "interpolation";
+ };
+
+ return {
+ startState: function(base) {
+ return {tokenize: null,
+ state: "top",
+ stateArg: null,
+ context: new Context("top", base || 0, null)};
+ },
+
+ token: function(stream, state) {
+ if (!state.tokenize && stream.eatSpace()) return null;
+ var style = (state.tokenize || tokenBase)(stream, state);
+ if (style && typeof style == "object") {
+ type = style[1];
+ style = style[0];
+ }
+ override = style;
+ state.state = states[state.state](type, stream, state);
+ return override;
+ },
+
+ indent: function(state, textAfter) {
+ var cx = state.context, ch = textAfter && textAfter.charAt(0);
+ var indent = cx.indent;
+ if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
+ if (cx.prev &&
+ (ch == "}" && (cx.type == "block" || cx.type == "top" || cx.type == "interpolation" || cx.type == "restricted_atBlock") ||
+ ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
+ ch == "{" && (cx.type == "at" || cx.type == "atBlock"))) {
+ indent = cx.indent - indentUnit;
+ cx = cx.prev;
+ }
+ return indent;
+ },
+
+ electricChars: "}",
+ blockCommentStart: "/*",
+ blockCommentEnd: "*/",
+ fold: "brace"
+ };
+});
+
+ function keySet(array) {
+ var keys = {};
+ for (var i = 0; i < array.length; ++i) {
+ keys[array[i]] = true;
+ }
+ return keys;
+ }
+
+ var documentTypes_ = [
+ "domain", "regexp", "url", "url-prefix"
+ ], documentTypes = keySet(documentTypes_);
+
+ var mediaTypes_ = [
+ "all", "aural", "braille", "handheld", "print", "projection", "screen",
+ "tty", "tv", "embossed"
+ ], mediaTypes = keySet(mediaTypes_);
+
+ var mediaFeatures_ = [
+ "width", "min-width", "max-width", "height", "min-height", "max-height",
+ "device-width", "min-device-width", "max-device-width", "device-height",
+ "min-device-height", "max-device-height", "aspect-ratio",
+ "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
+ "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
+ "max-color", "color-index", "min-color-index", "max-color-index",
+ "monochrome", "min-monochrome", "max-monochrome", "resolution",
+ "min-resolution", "max-resolution", "scan", "grid"
+ ], mediaFeatures = keySet(mediaFeatures_);
+
+ var propertyKeywords_ = [
+ "align-content", "align-items", "align-self", "alignment-adjust",
+ "alignment-baseline", "anchor-point", "animation", "animation-delay",
+ "animation-direction", "animation-duration", "animation-fill-mode",
+ "animation-iteration-count", "animation-name", "animation-play-state",
+ "animation-timing-function", "appearance", "azimuth", "backface-visibility",
+ "background", "background-attachment", "background-clip", "background-color",
+ "background-image", "background-origin", "background-position",
+ "background-repeat", "background-size", "baseline-shift", "binding",
+ "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
+ "bookmark-target", "border", "border-bottom", "border-bottom-color",
+ "border-bottom-left-radius", "border-bottom-right-radius",
+ "border-bottom-style", "border-bottom-width", "border-collapse",
+ "border-color", "border-image", "border-image-outset",
+ "border-image-repeat", "border-image-slice", "border-image-source",
+ "border-image-width", "border-left", "border-left-color",
+ "border-left-style", "border-left-width", "border-radius", "border-right",
+ "border-right-color", "border-right-style", "border-right-width",
+ "border-spacing", "border-style", "border-top", "border-top-color",
+ "border-top-left-radius", "border-top-right-radius", "border-top-style",
+ "border-top-width", "border-width", "bottom", "box-decoration-break",
+ "box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
+ "caption-side", "clear", "clip", "color", "color-profile", "column-count",
+ "column-fill", "column-gap", "column-rule", "column-rule-color",
+ "column-rule-style", "column-rule-width", "column-span", "column-width",
+ "columns", "content", "counter-increment", "counter-reset", "crop", "cue",
+ "cue-after", "cue-before", "cursor", "direction", "display",
+ "dominant-baseline", "drop-initial-after-adjust",
+ "drop-initial-after-align", "drop-initial-before-adjust",
+ "drop-initial-before-align", "drop-initial-size", "drop-initial-value",
+ "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
+ "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
+ "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
+ "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
+ "font-stretch", "font-style", "font-synthesis", "font-variant",
+ "font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
+ "font-variant-ligatures", "font-variant-numeric", "font-variant-position",
+ "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
+ "grid-auto-position", "grid-auto-rows", "grid-column", "grid-column-end",
+ "grid-column-start", "grid-row", "grid-row-end", "grid-row-start",
+ "grid-template", "grid-template-areas", "grid-template-columns",
+ "grid-template-rows", "hanging-punctuation", "height", "hyphens",
+ "icon", "image-orientation", "image-rendering", "image-resolution",
+ "inline-box-align", "justify-content", "left", "letter-spacing",
+ "line-break", "line-height", "line-stacking", "line-stacking-ruby",
+ "line-stacking-shift", "line-stacking-strategy", "list-style",
+ "list-style-image", "list-style-position", "list-style-type", "margin",
+ "margin-bottom", "margin-left", "margin-right", "margin-top",
+ "marker-offset", "marks", "marquee-direction", "marquee-loop",
+ "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
+ "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
+ "nav-left", "nav-right", "nav-up", "object-fit", "object-position",
+ "opacity", "order", "orphans", "outline",
+ "outline-color", "outline-offset", "outline-style", "outline-width",
+ "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
+ "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
+ "page", "page-break-after", "page-break-before", "page-break-inside",
+ "page-policy", "pause", "pause-after", "pause-before", "perspective",
+ "perspective-origin", "pitch", "pitch-range", "play-during", "position",
+ "presentation-level", "punctuation-trim", "quotes", "region-break-after",
+ "region-break-before", "region-break-inside", "region-fragment",
+ "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
+ "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
+ "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
+ "shape-outside", "size", "speak", "speak-as", "speak-header",
+ "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
+ "tab-size", "table-layout", "target", "target-name", "target-new",
+ "target-position", "text-align", "text-align-last", "text-decoration",
+ "text-decoration-color", "text-decoration-line", "text-decoration-skip",
+ "text-decoration-style", "text-emphasis", "text-emphasis-color",
+ "text-emphasis-position", "text-emphasis-style", "text-height",
+ "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
+ "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
+ "text-wrap", "top", "transform", "transform-origin", "transform-style",
+ "transition", "transition-delay", "transition-duration",
+ "transition-property", "transition-timing-function", "unicode-bidi",
+ "vertical-align", "visibility", "voice-balance", "voice-duration",
+ "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
+ "voice-volume", "volume", "white-space", "widows", "width", "word-break",
+ "word-spacing", "word-wrap", "z-index",
+ // SVG-specific
+ "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
+ "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
+ "color-interpolation", "color-interpolation-filters",
+ "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
+ "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
+ "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
+ "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
+ "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
+ "glyph-orientation-vertical", "text-anchor", "writing-mode"
+ ], propertyKeywords = keySet(propertyKeywords_);
+
+ var nonStandardPropertyKeywords_ = [
+ "scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
+ "scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
+ "scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
+ "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
+ "searchfield-results-decoration", "zoom"
+ ], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
+
+ var fontProperties_ = [
+ "font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
+ "font-stretch", "font-weight", "font-style"
+ ], fontProperties = keySet(fontProperties_);
+
+ var counterDescriptors_ = [
+ "additive-symbols", "fallback", "negative", "pad", "prefix", "range",
+ "speak-as", "suffix", "symbols", "system"
+ ], counterDescriptors = keySet(counterDescriptors_);
+
+ var colorKeywords_ = [
+ "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
+ "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
+ "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
+ "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
+ "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
+ "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
+ "darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
+ "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
+ "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
+ "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
+ "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
+ "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
+ "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
+ "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
+ "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
+ "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
+ "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
+ "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
+ "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
+ "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
+ "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
+ "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
+ "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
+ "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
+ "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
+ "whitesmoke", "yellow", "yellowgreen"
+ ], colorKeywords = keySet(colorKeywords_);
+
+ var valueKeywords_ = [
+ "above", "absolute", "activeborder", "additive", "activecaption", "afar",
+ "after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
+ "always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
+ "arabic-indic", "armenian", "asterisks", "attr", "auto", "avoid", "avoid-column", "avoid-page",
+ "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
+ "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
+ "both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel",
+ "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
+ "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
+ "cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
+ "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
+ "col-resize", "collapse", "column", "compact", "condensed", "contain", "content",
+ "content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop",
+ "cross", "crosshair", "currentcolor", "cursive", "cyclic", "dashed", "decimal",
+ "decimal-leading-zero", "default", "default-button", "destination-atop",
+ "destination-in", "destination-out", "destination-over", "devanagari",
+ "disc", "discard", "disclosure-closed", "disclosure-open", "document",
+ "dot-dash", "dot-dot-dash",
+ "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
+ "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
+ "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
+ "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
+ "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
+ "ethiopic-halehame-gez", "ethiopic-halehame-om-et",
+ "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
+ "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
+ "ethiopic-numeric", "ew-resize", "expanded", "extends", "extra-condensed",
+ "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "footnotes",
+ "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
+ "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
+ "help", "hidden", "hide", "higher", "highlight", "highlighttext",
+ "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
+ "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
+ "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
+ "inline-block", "inline-flex", "inline-table", "inset", "inside", "intrinsic", "invert",
+ "italic", "japanese-formal", "japanese-informal", "justify", "kannada",
+ "katakana", "katakana-iroha", "keep-all", "khmer",
+ "korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal",
+ "landscape", "lao", "large", "larger", "left", "level", "lighter",
+ "line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
+ "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
+ "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
+ "lower-roman", "lowercase", "ltr", "malayalam", "match", "matrix", "matrix3d",
+ "media-controls-background", "media-current-time-display",
+ "media-fullscreen-button", "media-mute-button", "media-play-button",
+ "media-return-to-realtime-button", "media-rewind-button",
+ "media-seek-back-button", "media-seek-forward-button", "media-slider",
+ "media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
+ "media-volume-slider-container", "media-volume-sliderthumb", "medium",
+ "menu", "menulist", "menulist-button", "menulist-text",
+ "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
+ "mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize",
+ "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
+ "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
+ "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
+ "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
+ "outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
+ "painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter",
+ "pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
+ "progress", "push-button", "radial-gradient", "radio", "read-only",
+ "read-write", "read-write-plaintext-only", "rectangle", "region",
+ "relative", "repeat", "repeating-linear-gradient",
+ "repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
+ "rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
+ "rotateZ", "round", "row-resize", "rtl", "run-in", "running",
+ "s-resize", "sans-serif", "scale", "scale3d", "scaleX", "scaleY", "scaleZ",
+ "scroll", "scrollbar", "se-resize", "searchfield",
+ "searchfield-cancel-button", "searchfield-decoration",
+ "searchfield-results-button", "searchfield-results-decoration",
+ "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
+ "simp-chinese-formal", "simp-chinese-informal", "single",
+ "skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
+ "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
+ "small", "small-caps", "small-caption", "smaller", "solid", "somali",
+ "source-atop", "source-in", "source-out", "source-over", "space", "spell-out", "square",
+ "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
+ "subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "table",
+ "table-caption", "table-cell", "table-column", "table-column-group",
+ "table-footer-group", "table-header-group", "table-row", "table-row-group",
+ "tamil",
+ "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
+ "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
+ "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
+ "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
+ "trad-chinese-formal", "trad-chinese-informal",
+ "translate", "translate3d", "translateX", "translateY", "translateZ",
+ "transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
+ "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
+ "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
+ "var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
+ "visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
+ "window", "windowframe", "windowtext", "words", "x-large", "x-small", "xor",
+ "xx-large", "xx-small"
+ ], valueKeywords = keySet(valueKeywords_);
+
+ var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(propertyKeywords_)
+ .concat(nonStandardPropertyKeywords_).concat(colorKeywords_).concat(valueKeywords_);
+ CodeMirror.registerHelper("hintWords", "css", allWords);
+
+ function tokenCComment(stream, state) {
+ var maybeEnd = false, ch;
+ while ((ch = stream.next()) != null) {
+ if (maybeEnd && ch == "/") {
+ state.tokenize = null;
+ break;
+ }
+ maybeEnd = (ch == "*");
+ }
+ return ["comment", "comment"];
+ }
+
+ function tokenSGMLComment(stream, state) {
+ if (stream.skipTo("-->")) {
+ stream.match("-->");
+ state.tokenize = null;
+ } else {
+ stream.skipToEnd();
+ }
+ return ["comment", "comment"];
+ }
+
+ CodeMirror.defineMIME("text/css", {
+ documentTypes: documentTypes,
+ mediaTypes: mediaTypes,
+ mediaFeatures: mediaFeatures,
+ propertyKeywords: propertyKeywords,
+ nonStandardPropertyKeywords: nonStandardPropertyKeywords,
+ fontProperties: fontProperties,
+ counterDescriptors: counterDescriptors,
+ colorKeywords: colorKeywords,
+ valueKeywords: valueKeywords,
+ tokenHooks: {
+ "<": function(stream, state) {
+ if (!stream.match("!--")) return false;
+ state.tokenize = tokenSGMLComment;
+ return tokenSGMLComment(stream, state);
+ },
+ "/": function(stream, state) {
+ if (!stream.eat("*")) return false;
+ state.tokenize = tokenCComment;
+ return tokenCComment(stream, state);
+ }
+ },
+ name: "css"
+ });
+
+ CodeMirror.defineMIME("text/x-scss", {
+ mediaTypes: mediaTypes,
+ mediaFeatures: mediaFeatures,
+ propertyKeywords: propertyKeywords,
+ nonStandardPropertyKeywords: nonStandardPropertyKeywords,
+ colorKeywords: colorKeywords,
+ valueKeywords: valueKeywords,
+ fontProperties: fontProperties,
+ allowNested: true,
+ tokenHooks: {
+ "/": function(stream, state) {
+ if (stream.eat("/")) {
+ stream.skipToEnd();
+ return ["comment", "comment"];
+ } else if (stream.eat("*")) {
+ state.tokenize = tokenCComment;
+ return tokenCComment(stream, state);
+ } else {
+ return ["operator", "operator"];
+ }
+ },
+ ":": function(stream) {
+ if (stream.match(/\s*\{/))
+ return [null, "{"];
+ return false;
+ },
+ "$": function(stream) {
+ stream.match(/^[\w-]+/);
+ if (stream.match(/^\s*:/, false))
+ return ["variable-2", "variable-definition"];
+ return ["variable-2", "variable"];
+ },
+ "#": function(stream) {
+ if (!stream.eat("{")) return false;
+ return [null, "interpolation"];
+ }
+ },
+ name: "css",
+ helperType: "scss"
+ });
+
+ CodeMirror.defineMIME("text/x-less", {
+ mediaTypes: mediaTypes,
+ mediaFeatures: mediaFeatures,
+ propertyKeywords: propertyKeywords,
+ nonStandardPropertyKeywords: nonStandardPropertyKeywords,
+ colorKeywords: colorKeywords,
+ valueKeywords: valueKeywords,
+ fontProperties: fontProperties,
+ allowNested: true,
+ tokenHooks: {
+ "/": function(stream, state) {
+ if (stream.eat("/")) {
+ stream.skipToEnd();
+ return ["comment", "comment"];
+ } else if (stream.eat("*")) {
+ state.tokenize = tokenCComment;
+ return tokenCComment(stream, state);
+ } else {
+ return ["operator", "operator"];
+ }
+ },
+ "@": function(stream) {
+ if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
+ stream.eatWhile(/[\w\\\-]/);
+ if (stream.match(/^\s*:/, false))
+ return ["variable-2", "variable-definition"];
+ return ["variable-2", "variable"];
+ },
+ "&": function() {
+ return ["atom", "atom"];
+ }
+ },
+ name: "css",
+ helperType: "less"
+ });
+
+});
diff --git a/static/mdeditor/js/lib/codemirror/mode/css/index.html b/static/mdeditor/js/lib/codemirror/mode/css/index.html
new file mode 100644
index 0000000..2d2b9b0
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/css/index.html
@@ -0,0 +1,75 @@
+
+
+CodeMirror: CSS mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+CSS mode
+
+/* Some example CSS */
+
+@import url("something.css");
+
+body {
+ margin: 0;
+ padding: 3em 6em;
+ font-family: tahoma, arial, sans-serif;
+ color: #000;
+}
+
+#navigation a {
+ font-weight: bold;
+ text-decoration: none !important;
+}
+
+h1 {
+ font-size: 2.5em;
+}
+
+h2 {
+ font-size: 1.7em;
+}
+
+h1:before, h2:before {
+ content: "::";
+}
+
+code {
+ font-family: courier, monospace;
+ font-size: 80%;
+ color: #418A8A;
+}
+
+
+
+ MIME types defined: text/css
, text/x-scss
(demo ), text/x-less
(demo ).
+
+ Parsing/Highlighting Tests: normal , verbose .
+
+
diff --git a/static/mdeditor/js/lib/codemirror/mode/css/less.html b/static/mdeditor/js/lib/codemirror/mode/css/less.html
new file mode 100644
index 0000000..6ccb721
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/css/less.html
@@ -0,0 +1,152 @@
+
+
+CodeMirror: LESS mode
+
+
+
+
+
+
+
+
+
+
+
+LESS mode
+@media screen and (device-aspect-ratio: 16/9) { … }
+@media screen and (device-aspect-ratio: 1280/720) { … }
+@media screen and (device-aspect-ratio: 2560/1440) { … }
+
+html:lang(fr-be)
+
+tr:nth-child(2n+1) /* represents every odd row of an HTML table */
+
+img:nth-of-type(2n+1) { float: right; }
+img:nth-of-type(2n) { float: left; }
+
+body > h2:not(:first-of-type):not(:last-of-type)
+
+html|*:not(:link):not(:visited)
+*|*:not(:hover)
+p::first-line { text-transform: uppercase }
+
+@namespace foo url(http://www.example.com);
+foo|h1 { color: blue } /* first rule */
+
+span[hello="Ocean"][goodbye="Land"]
+
+E[foo]{
+ padding:65px;
+}
+
+input[type="search"]::-webkit-search-decoration,
+input[type="search"]::-webkit-search-cancel-button {
+ -webkit-appearance: none; // Inner-padding issues in Chrome OSX, Safari 5
+}
+button::-moz-focus-inner,
+input::-moz-focus-inner { // Inner padding and border oddities in FF3/4
+ padding: 0;
+ border: 0;
+}
+.btn {
+ // reset here as of 2.0.3 due to Recess property order
+ border-color: #ccc;
+ border-color: rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);
+}
+fieldset span button, fieldset span input[type="file"] {
+ font-size:12px;
+ font-family:Arial, Helvetica, sans-serif;
+}
+
+.rounded-corners (@radius: 5px) {
+ border-radius: @radius;
+ -webkit-border-radius: @radius;
+ -moz-border-radius: @radius;
+}
+
+@import url("something.css");
+
+@light-blue: hsl(190, 50%, 65%);
+
+#menu {
+ position: absolute;
+ width: 100%;
+ z-index: 3;
+ clear: both;
+ display: block;
+ background-color: @blue;
+ height: 42px;
+ border-top: 2px solid lighten(@alpha-blue, 20%);
+ border-bottom: 2px solid darken(@alpha-blue, 25%);
+ .box-shadow(0, 1px, 8px, 0.6);
+ -moz-box-shadow: 0 0 0 #000; // Because firefox sucks.
+
+ &.docked {
+ background-color: hsla(210, 60%, 40%, 0.4);
+ }
+ &:hover {
+ background-color: @blue;
+ }
+
+ #dropdown {
+ margin: 0 0 0 117px;
+ padding: 0;
+ padding-top: 5px;
+ display: none;
+ width: 190px;
+ border-top: 2px solid @medium;
+ color: @highlight;
+ border: 2px solid darken(@medium, 25%);
+ border-left-color: darken(@medium, 15%);
+ border-right-color: darken(@medium, 15%);
+ border-top-width: 0;
+ background-color: darken(@medium, 10%);
+ ul {
+ padding: 0px;
+ }
+ li {
+ font-size: 14px;
+ display: block;
+ text-align: left;
+ padding: 0;
+ border: 0;
+ a {
+ display: block;
+ padding: 0px 15px;
+ text-decoration: none;
+ color: white;
+ &:hover {
+ background-color: darken(@medium, 15%);
+ text-decoration: none;
+ }
+ }
+ }
+ .border-radius(5px, bottom);
+ .box-shadow(0, 6px, 8px, 0.5);
+ }
+}
+
+
+
+ The LESS mode is a sub-mode of the CSS mode (defined in css.js
.
+
+ Parsing/Highlighting Tests: normal , verbose .
+
diff --git a/static/mdeditor/js/lib/codemirror/mode/css/less_test.js b/static/mdeditor/js/lib/codemirror/mode/css/less_test.js
new file mode 100644
index 0000000..2ba6998
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/css/less_test.js
@@ -0,0 +1,51 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(function() {
+ "use strict";
+
+ var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-less");
+ function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "less"); }
+
+ MT("variable",
+ "[variable-2 @base]: [atom #f04615];",
+ "[qualifier .class] {",
+ " [property width]: [variable percentage]([number 0.5]); [comment // returns `50%`]",
+ " [property color]: [variable saturate]([variable-2 @base], [number 5%]);",
+ "}");
+
+ MT("amp",
+ "[qualifier .child], [qualifier .sibling] {",
+ " [qualifier .parent] [atom &] {",
+ " [property color]: [keyword black];",
+ " }",
+ " [atom &] + [atom &] {",
+ " [property color]: [keyword red];",
+ " }",
+ "}");
+
+ MT("mixin",
+ "[qualifier .mixin] ([variable dark]; [variable-2 @color]) {",
+ " [property color]: [variable darken]([variable-2 @color], [number 10%]);",
+ "}",
+ "[qualifier .mixin] ([variable light]; [variable-2 @color]) {",
+ " [property color]: [variable lighten]([variable-2 @color], [number 10%]);",
+ "}",
+ "[qualifier .mixin] ([variable-2 @_]; [variable-2 @color]) {",
+ " [property display]: [atom block];",
+ "}",
+ "[variable-2 @switch]: [variable light];",
+ "[qualifier .class] {",
+ " [qualifier .mixin]([variable-2 @switch]; [atom #888]);",
+ "}");
+
+ MT("nest",
+ "[qualifier .one] {",
+ " [def @media] ([property width]: [number 400px]) {",
+ " [property font-size]: [number 1.2em];",
+ " [def @media] [attribute print] [keyword and] [property color] {",
+ " [property color]: [keyword blue];",
+ " }",
+ " }",
+ "}");
+})();
diff --git a/static/mdeditor/js/lib/codemirror/mode/css/scss.html b/static/mdeditor/js/lib/codemirror/mode/css/scss.html
new file mode 100644
index 0000000..21f20e0
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/css/scss.html
@@ -0,0 +1,157 @@
+
+
+CodeMirror: SCSS mode
+
+
+
+
+
+
+
+
+
+
+SCSS mode
+
+/* Some example SCSS */
+
+@import "compass/css3";
+$variable: #333;
+
+$blue: #3bbfce;
+$margin: 16px;
+
+.content-navigation {
+ #nested {
+ background-color: black;
+ }
+ border-color: $blue;
+ color:
+ darken($blue, 9%);
+}
+
+.border {
+ padding: $margin / 2;
+ margin: $margin / 2;
+ border-color: $blue;
+}
+
+@mixin table-base {
+ th {
+ text-align: center;
+ font-weight: bold;
+ }
+ td, th {padding: 2px}
+}
+
+table.hl {
+ margin: 2em 0;
+ td.ln {
+ text-align: right;
+ }
+}
+
+li {
+ font: {
+ family: serif;
+ weight: bold;
+ size: 1.2em;
+ }
+}
+
+@mixin left($dist) {
+ float: left;
+ margin-left: $dist;
+}
+
+#data {
+ @include left(10px);
+ @include table-base;
+}
+
+.source {
+ @include flow-into(target);
+ border: 10px solid green;
+ margin: 20px;
+ width: 200px; }
+
+.new-container {
+ @include flow-from(target);
+ border: 10px solid red;
+ margin: 20px;
+ width: 200px; }
+
+body {
+ margin: 0;
+ padding: 3em 6em;
+ font-family: tahoma, arial, sans-serif;
+ color: #000;
+}
+
+@mixin yellow() {
+ background: yellow;
+}
+
+.big {
+ font-size: 14px;
+}
+
+.nested {
+ @include border-radius(3px);
+ @extend .big;
+ p {
+ background: whitesmoke;
+ a {
+ color: red;
+ }
+ }
+}
+
+#navigation a {
+ font-weight: bold;
+ text-decoration: none !important;
+}
+
+h1 {
+ font-size: 2.5em;
+}
+
+h2 {
+ font-size: 1.7em;
+}
+
+h1:before, h2:before {
+ content: "::";
+}
+
+code {
+ font-family: courier, monospace;
+ font-size: 80%;
+ color: #418A8A;
+}
+
+
+
+ The SCSS mode is a sub-mode of the CSS mode (defined in css.js
.
+
+ Parsing/Highlighting Tests: normal , verbose .
+
+
diff --git a/static/mdeditor/js/lib/codemirror/mode/css/scss_test.js b/static/mdeditor/js/lib/codemirror/mode/css/scss_test.js
new file mode 100644
index 0000000..8dcea9e
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/css/scss_test.js
@@ -0,0 +1,110 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(function() {
+ var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-scss");
+ function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "scss"); }
+
+ MT('url_with_quotation',
+ "[tag foo] { [property background]:[atom url]([string test.jpg]) }");
+
+ MT('url_with_double_quotes',
+ "[tag foo] { [property background]:[atom url]([string \"test.jpg\"]) }");
+
+ MT('url_with_single_quotes',
+ "[tag foo] { [property background]:[atom url]([string \'test.jpg\']) }");
+
+ MT('string',
+ "[def @import] [string \"compass/css3\"]");
+
+ MT('important_keyword',
+ "[tag foo] { [property background]:[atom url]([string \'test.jpg\']) [keyword !important] }");
+
+ MT('variable',
+ "[variable-2 $blue]:[atom #333]");
+
+ MT('variable_as_attribute',
+ "[tag foo] { [property color]:[variable-2 $blue] }");
+
+ MT('numbers',
+ "[tag foo] { [property padding]:[number 10px] [number 10] [number 10em] [number 8in] }");
+
+ MT('number_percentage',
+ "[tag foo] { [property width]:[number 80%] }");
+
+ MT('selector',
+ "[builtin #hello][qualifier .world]{}");
+
+ MT('singleline_comment',
+ "[comment // this is a comment]");
+
+ MT('multiline_comment',
+ "[comment /*foobar*/]");
+
+ MT('attribute_with_hyphen',
+ "[tag foo] { [property font-size]:[number 10px] }");
+
+ MT('string_after_attribute',
+ "[tag foo] { [property content]:[string \"::\"] }");
+
+ MT('directives',
+ "[def @include] [qualifier .mixin]");
+
+ MT('basic_structure',
+ "[tag p] { [property background]:[keyword red]; }");
+
+ MT('nested_structure',
+ "[tag p] { [tag a] { [property color]:[keyword red]; } }");
+
+ MT('mixin',
+ "[def @mixin] [tag table-base] {}");
+
+ MT('number_without_semicolon',
+ "[tag p] {[property width]:[number 12]}",
+ "[tag a] {[property color]:[keyword red];}");
+
+ MT('atom_in_nested_block',
+ "[tag p] { [tag a] { [property color]:[atom #000]; } }");
+
+ MT('interpolation_in_property',
+ "[tag foo] { #{[variable-2 $hello]}:[number 2]; }");
+
+ MT('interpolation_in_selector',
+ "[tag foo]#{[variable-2 $hello]} { [property color]:[atom #000]; }");
+
+ MT('interpolation_error',
+ "[tag foo]#{[error foo]} { [property color]:[atom #000]; }");
+
+ MT("divide_operator",
+ "[tag foo] { [property width]:[number 4] [operator /] [number 2] }");
+
+ MT('nested_structure_with_id_selector',
+ "[tag p] { [builtin #hello] { [property color]:[keyword red]; } }");
+
+ MT('indent_mixin',
+ "[def @mixin] [tag container] (",
+ " [variable-2 $a]: [number 10],",
+ " [variable-2 $b]: [number 10])",
+ "{}");
+
+ MT('indent_nested',
+ "[tag foo] {",
+ " [tag bar] {",
+ " }",
+ "}");
+
+ MT('indent_parentheses',
+ "[tag foo] {",
+ " [property color]: [variable darken]([variable-2 $blue],",
+ " [number 9%]);",
+ "}");
+
+ MT('indent_vardef',
+ "[variable-2 $name]:",
+ " [string 'val'];",
+ "[tag tag] {",
+ " [tag inner] {",
+ " [property margin]: [number 3px];",
+ " }",
+ "}");
+})();
diff --git a/static/mdeditor/js/lib/codemirror/mode/css/test.js b/static/mdeditor/js/lib/codemirror/mode/css/test.js
new file mode 100644
index 0000000..bef7156
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/css/test.js
@@ -0,0 +1,195 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(function() {
+ var mode = CodeMirror.getMode({indentUnit: 2}, "css");
+ function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
+
+ // Error, because "foobarhello" is neither a known type or property, but
+ // property was expected (after "and"), and it should be in parenthese.
+ MT("atMediaUnknownType",
+ "[def @media] [attribute screen] [keyword and] [error foobarhello] { }");
+
+ // Soft error, because "foobarhello" is not a known property or type.
+ MT("atMediaUnknownProperty",
+ "[def @media] [attribute screen] [keyword and] ([error foobarhello]) { }");
+
+ // Make sure nesting works with media queries
+ MT("atMediaMaxWidthNested",
+ "[def @media] [attribute screen] [keyword and] ([property max-width]: [number 25px]) { [tag foo] { } }");
+
+ MT("tagSelector",
+ "[tag foo] { }");
+
+ MT("classSelector",
+ "[qualifier .foo-bar_hello] { }");
+
+ MT("idSelector",
+ "[builtin #foo] { [error #foo] }");
+
+ MT("tagSelectorUnclosed",
+ "[tag foo] { [property margin]: [number 0] } [tag bar] { }");
+
+ MT("tagStringNoQuotes",
+ "[tag foo] { [property font-family]: [variable hello] [variable world]; }");
+
+ MT("tagStringDouble",
+ "[tag foo] { [property font-family]: [string \"hello world\"]; }");
+
+ MT("tagStringSingle",
+ "[tag foo] { [property font-family]: [string 'hello world']; }");
+
+ MT("tagColorKeyword",
+ "[tag foo] {",
+ " [property color]: [keyword black];",
+ " [property color]: [keyword navy];",
+ " [property color]: [keyword yellow];",
+ "}");
+
+ MT("tagColorHex3",
+ "[tag foo] { [property background]: [atom #fff]; }");
+
+ MT("tagColorHex6",
+ "[tag foo] { [property background]: [atom #ffffff]; }");
+
+ MT("tagColorHex4",
+ "[tag foo] { [property background]: [atom&error #ffff]; }");
+
+ MT("tagColorHexInvalid",
+ "[tag foo] { [property background]: [atom&error #ffg]; }");
+
+ MT("tagNegativeNumber",
+ "[tag foo] { [property margin]: [number -5px]; }");
+
+ MT("tagPositiveNumber",
+ "[tag foo] { [property padding]: [number 5px]; }");
+
+ MT("tagVendor",
+ "[tag foo] { [meta -foo-][property box-sizing]: [meta -foo-][atom border-box]; }");
+
+ MT("tagBogusProperty",
+ "[tag foo] { [property&error barhelloworld]: [number 0]; }");
+
+ MT("tagTwoProperties",
+ "[tag foo] { [property margin]: [number 0]; [property padding]: [number 0]; }");
+
+ MT("tagTwoPropertiesURL",
+ "[tag foo] { [property background]: [atom url]([string //example.com/foo.png]); [property padding]: [number 0]; }");
+
+ MT("commentSGML",
+ "[comment ]");
+
+ MT("commentSGML2",
+ "[comment ] [tag div] {}");
+
+ MT("indent_tagSelector",
+ "[tag strong], [tag em] {",
+ " [property background]: [atom rgba](",
+ " [number 255], [number 255], [number 0], [number .2]",
+ " );",
+ "}");
+
+ MT("indent_atMedia",
+ "[def @media] {",
+ " [tag foo] {",
+ " [property color]:",
+ " [keyword yellow];",
+ " }",
+ "}");
+
+ MT("indent_comma",
+ "[tag foo] {",
+ " [property font-family]: [variable verdana],",
+ " [atom sans-serif];",
+ "}");
+
+ MT("indent_parentheses",
+ "[tag foo]:[variable-3 before] {",
+ " [property background]: [atom url](",
+ "[string blahblah]",
+ "[string etc]",
+ "[string ]) [keyword !important];",
+ "}");
+
+ MT("font_face",
+ "[def @font-face] {",
+ " [property font-family]: [string 'myfont'];",
+ " [error nonsense]: [string 'abc'];",
+ " [property src]: [atom url]([string http://blah]),",
+ " [atom url]([string http://foo]);",
+ "}");
+
+ MT("empty_url",
+ "[def @import] [tag url]() [tag screen];");
+
+ MT("parens",
+ "[qualifier .foo] {",
+ " [property background-image]: [variable fade]([atom #000], [number 20%]);",
+ " [property border-image]: [atom linear-gradient](",
+ " [atom to] [atom bottom],",
+ " [variable fade]([atom #000], [number 20%]) [number 0%],",
+ " [variable fade]([atom #000], [number 20%]) [number 100%]",
+ " );",
+ "}");
+
+ MT("css_variable",
+ ":[variable-3 root] {",
+ " [variable-2 --main-color]: [atom #06c];",
+ "}",
+ "[tag h1][builtin #foo] {",
+ " [property color]: [atom var]([variable-2 --main-color]);",
+ "}");
+
+ MT("supports",
+ "[def @supports] ([keyword not] (([property text-align-last]: [atom justify]) [keyword or] ([meta -moz-][property text-align-last]: [atom justify])) {",
+ " [property text-align-last]: [atom justify];",
+ "}");
+
+ MT("document",
+ "[def @document] [tag url]([string http://blah]),",
+ " [tag url-prefix]([string https://]),",
+ " [tag domain]([string blah.com]),",
+ " [tag regexp]([string \".*blah.+\"]) {",
+ " [builtin #id] {",
+ " [property background-color]: [keyword white];",
+ " }",
+ " [tag foo] {",
+ " [property font-family]: [variable Verdana], [atom sans-serif];",
+ " }",
+ " }");
+
+ MT("document_url",
+ "[def @document] [tag url]([string http://blah]) { [qualifier .class] { } }");
+
+ MT("document_urlPrefix",
+ "[def @document] [tag url-prefix]([string https://]) { [builtin #id] { } }");
+
+ MT("document_domain",
+ "[def @document] [tag domain]([string blah.com]) { [tag foo] { } }");
+
+ MT("document_regexp",
+ "[def @document] [tag regexp]([string \".*blah.+\"]) { [builtin #id] { } }");
+
+ MT("counter-style",
+ "[def @counter-style] [variable binary] {",
+ " [property system]: [atom numeric];",
+ " [property symbols]: [number 0] [number 1];",
+ " [property suffix]: [string \".\"];",
+ " [property range]: [atom infinite];",
+ " [property speak-as]: [atom numeric];",
+ "}");
+
+ MT("counter-style-additive-symbols",
+ "[def @counter-style] [variable simple-roman] {",
+ " [property system]: [atom additive];",
+ " [property additive-symbols]: [number 10] [variable X], [number 5] [variable V], [number 1] [variable I];",
+ " [property range]: [number 1] [number 49];",
+ "}");
+
+ MT("counter-style-use",
+ "[tag ol][qualifier .roman] { [property list-style]: [variable simple-roman]; }");
+
+ MT("counter-style-symbols",
+ "[tag ol] { [property list-style]: [atom symbols]([atom cyclic] [string \"*\"] [string \"\\2020\"] [string \"\\2021\"] [string \"\\A7\"]); }");
+})();
diff --git a/static/mdeditor/js/lib/codemirror/mode/cypher/cypher.js b/static/mdeditor/js/lib/codemirror/mode/cypher/cypher.js
new file mode 100644
index 0000000..9decf30
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/cypher/cypher.js
@@ -0,0 +1,146 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+// By the Neo4j Team and contributors.
+// https://github.com/neo4j-contrib/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) {
+ "use strict";
+ var wordRegexp = function(words) {
+ return new RegExp("^(?:" + words.join("|") + ")$", "i");
+ };
+
+ CodeMirror.defineMode("cypher", function(config) {
+ var tokenBase = function(stream/*, state*/) {
+ var ch = stream.next(), curPunc = null;
+ if (ch === "\"" || ch === "'") {
+ stream.match(/.+?["']/);
+ return "string";
+ }
+ if (/[{}\(\),\.;\[\]]/.test(ch)) {
+ curPunc = ch;
+ return "node";
+ } else if (ch === "/" && stream.eat("/")) {
+ stream.skipToEnd();
+ return "comment";
+ } else if (operatorChars.test(ch)) {
+ stream.eatWhile(operatorChars);
+ return null;
+ } else {
+ stream.eatWhile(/[_\w\d]/);
+ if (stream.eat(":")) {
+ stream.eatWhile(/[\w\d_\-]/);
+ return "atom";
+ }
+ var word = stream.current();
+ if (funcs.test(word)) return "builtin";
+ if (preds.test(word)) return "def";
+ if (keywords.test(word)) return "keyword";
+ return "variable";
+ }
+ };
+ var pushContext = function(state, type, col) {
+ return state.context = {
+ prev: state.context,
+ indent: state.indent,
+ col: col,
+ type: type
+ };
+ };
+ var popContext = function(state) {
+ state.indent = state.context.indent;
+ return state.context = state.context.prev;
+ };
+ var indentUnit = config.indentUnit;
+ var curPunc;
+ var funcs = wordRegexp(["abs", "acos", "allShortestPaths", "asin", "atan", "atan2", "avg", "ceil", "coalesce", "collect", "cos", "cot", "count", "degrees", "e", "endnode", "exp", "extract", "filter", "floor", "haversin", "head", "id", "keys", "labels", "last", "left", "length", "log", "log10", "lower", "ltrim", "max", "min", "node", "nodes", "percentileCont", "percentileDisc", "pi", "radians", "rand", "range", "reduce", "rel", "relationship", "relationships", "replace", "right", "round", "rtrim", "shortestPath", "sign", "sin", "split", "sqrt", "startnode", "stdev", "stdevp", "str", "substring", "sum", "tail", "tan", "timestamp", "toFloat", "toInt", "trim", "type", "upper"]);
+ var preds = wordRegexp(["all", "and", "any", "has", "in", "none", "not", "or", "single", "xor"]);
+ var keywords = wordRegexp(["as", "asc", "ascending", "assert", "by", "case", "commit", "constraint", "create", "csv", "cypher", "delete", "desc", "descending", "distinct", "drop", "else", "end", "explain", "false", "fieldterminator", "foreach", "from", "headers", "in", "index", "is", "limit", "load", "match", "merge", "null", "on", "optional", "order", "periodic", "profile", "remove", "return", "scan", "set", "skip", "start", "then", "true", "union", "unique", "unwind", "using", "when", "where", "with"]);
+ var operatorChars = /[*+\-<>=&|~%^]/;
+
+ return {
+ startState: function(/*base*/) {
+ return {
+ tokenize: tokenBase,
+ context: null,
+ indent: 0,
+ col: 0
+ };
+ },
+ token: function(stream, state) {
+ if (stream.sol()) {
+ if (state.context && (state.context.align == null)) {
+ state.context.align = false;
+ }
+ state.indent = stream.indentation();
+ }
+ if (stream.eatSpace()) {
+ return null;
+ }
+ var style = state.tokenize(stream, state);
+ if (style !== "comment" && state.context && (state.context.align == null) && state.context.type !== "pattern") {
+ state.context.align = true;
+ }
+ if (curPunc === "(") {
+ pushContext(state, ")", stream.column());
+ } else if (curPunc === "[") {
+ pushContext(state, "]", stream.column());
+ } else if (curPunc === "{") {
+ pushContext(state, "}", stream.column());
+ } else if (/[\]\}\)]/.test(curPunc)) {
+ while (state.context && state.context.type === "pattern") {
+ popContext(state);
+ }
+ if (state.context && curPunc === state.context.type) {
+ popContext(state);
+ }
+ } else if (curPunc === "." && state.context && state.context.type === "pattern") {
+ popContext(state);
+ } else if (/atom|string|variable/.test(style) && state.context) {
+ if (/[\}\]]/.test(state.context.type)) {
+ pushContext(state, "pattern", stream.column());
+ } else if (state.context.type === "pattern" && !state.context.align) {
+ state.context.align = true;
+ state.context.col = stream.column();
+ }
+ }
+ return style;
+ },
+ indent: function(state, textAfter) {
+ var firstChar = textAfter && textAfter.charAt(0);
+ var context = state.context;
+ if (/[\]\}]/.test(firstChar)) {
+ while (context && context.type === "pattern") {
+ context = context.prev;
+ }
+ }
+ var closing = context && firstChar === context.type;
+ if (!context) return 0;
+ if (context.type === "keywords") return CodeMirror.commands.newlineAndIndent;
+ if (context.align) return context.col + (closing ? 0 : 1);
+ return context.indent + (closing ? 0 : indentUnit);
+ }
+ };
+ });
+
+ CodeMirror.modeExtensions["cypher"] = {
+ autoFormatLineBreaks: function(text) {
+ var i, lines, reProcessedPortion;
+ var lines = text.split("\n");
+ var reProcessedPortion = /\s+\b(return|where|order by|match|with|skip|limit|create|delete|set)\b\s/g;
+ for (var i = 0; i < lines.length; i++)
+ lines[i] = lines[i].replace(reProcessedPortion, " \n$1 ").trim();
+ return lines.join("\n");
+ }
+ };
+
+ CodeMirror.defineMIME("application/x-cypher-query", "cypher");
+
+});
diff --git a/static/mdeditor/js/lib/codemirror/mode/cypher/index.html b/static/mdeditor/js/lib/codemirror/mode/cypher/index.html
new file mode 100644
index 0000000..b8bd75c
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/cypher/index.html
@@ -0,0 +1,63 @@
+
+
+CodeMirror: Cypher Mode for CodeMirror
+
+
+
+
+
+
+
+
+
+
+
+Cypher Mode for CodeMirror
+
+ // Cypher Mode for CodeMirror, using the neo theme
+MATCH (joe { name: 'Joe' })-[:knows*2..2]-(friend_of_friend)
+WHERE NOT (joe)-[:knows]-(friend_of_friend)
+RETURN friend_of_friend.name, COUNT(*)
+ORDER BY COUNT(*) DESC , friend_of_friend.name
+
+
+ MIME types defined:
+ application/x-cypher-query
+
+
+
+
diff --git a/static/mdeditor/js/lib/codemirror/mode/d/d.js b/static/mdeditor/js/lib/codemirror/mode/d/d.js
new file mode 100644
index 0000000..c927a7e
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/d/d.js
@@ -0,0 +1,218 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(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) {
+"use strict";
+
+CodeMirror.defineMode("d", function(config, parserConfig) {
+ var indentUnit = config.indentUnit,
+ statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
+ keywords = parserConfig.keywords || {},
+ builtin = parserConfig.builtin || {},
+ blockKeywords = parserConfig.blockKeywords || {},
+ atoms = parserConfig.atoms || {},
+ hooks = parserConfig.hooks || {},
+ multiLineStrings = parserConfig.multiLineStrings;
+ var isOperatorChar = /[+\-*&%=<>!?|\/]/;
+
+ var curPunc;
+
+ function tokenBase(stream, state) {
+ var ch = stream.next();
+ if (hooks[ch]) {
+ var result = hooks[ch](stream, state);
+ if (result !== false) return result;
+ }
+ if (ch == '"' || ch == "'" || ch == "`") {
+ state.tokenize = tokenString(ch);
+ return state.tokenize(stream, state);
+ }
+ if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
+ curPunc = ch;
+ return null;
+ }
+ if (/\d/.test(ch)) {
+ stream.eatWhile(/[\w\.]/);
+ return "number";
+ }
+ if (ch == "/") {
+ if (stream.eat("+")) {
+ state.tokenize = tokenComment;
+ return tokenNestedComment(stream, state);
+ }
+ 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";
+ }
+ stream.eatWhile(/[\w\$_\xa1-\uffff]/);
+ var cur = stream.current();
+ if (keywords.propertyIsEnumerable(cur)) {
+ if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
+ return "keyword";
+ }
+ if (builtin.propertyIsEnumerable(cur)) {
+ if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
+ return "builtin";
+ }
+ if (atoms.propertyIsEnumerable(cur)) return "atom";
+ return "variable";
+ }
+
+ function tokenString(quote) {
+ return function(stream, state) {
+ var escaped = false, next, end = false;
+ while ((next = stream.next()) != null) {
+ if (next == quote && !escaped) {end = true; break;}
+ escaped = !escaped && next == "\\";
+ }
+ if (end || !(escaped || multiLineStrings))
+ state.tokenize = null;
+ return "string";
+ };
+ }
+
+ function tokenComment(stream, state) {
+ var maybeEnd = false, ch;
+ while (ch = stream.next()) {
+ if (ch == "/" && maybeEnd) {
+ state.tokenize = null;
+ break;
+ }
+ maybeEnd = (ch == "*");
+ }
+ return "comment";
+ }
+
+ function tokenNestedComment(stream, state) {
+ var maybeEnd = false, ch;
+ while (ch = stream.next()) {
+ if (ch == "/" && maybeEnd) {
+ state.tokenize = null;
+ break;
+ }
+ maybeEnd = (ch == "+");
+ }
+ return "comment";
+ }
+
+ function Context(indented, column, type, align, prev) {
+ this.indented = indented;
+ this.column = column;
+ this.type = type;
+ this.align = align;
+ this.prev = prev;
+ }
+ function pushContext(state, col, type) {
+ var indent = state.indented;
+ if (state.context && state.context.type == "statement")
+ indent = state.context.indented;
+ return state.context = new Context(indent, col, type, null, state.context);
+ }
+ function popContext(state) {
+ var t = state.context.type;
+ if (t == ")" || t == "]" || t == "}")
+ state.indented = state.context.indented;
+ return state.context = state.context.prev;
+ }
+
+ // Interface
+
+ return {
+ startState: function(basecolumn) {
+ return {
+ tokenize: null,
+ context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
+ indented: 0,
+ startOfLine: true
+ };
+ },
+
+ token: function(stream, state) {
+ var ctx = state.context;
+ if (stream.sol()) {
+ if (ctx.align == null) ctx.align = false;
+ state.indented = stream.indentation();
+ state.startOfLine = true;
+ }
+ if (stream.eatSpace()) return null;
+ curPunc = null;
+ var style = (state.tokenize || tokenBase)(stream, state);
+ if (style == "comment" || style == "meta") return style;
+ if (ctx.align == null) ctx.align = true;
+
+ if ((curPunc == ";" || curPunc == ":" || curPunc == ",") && ctx.type == "statement") popContext(state);
+ else if (curPunc == "{") pushContext(state, stream.column(), "}");
+ else if (curPunc == "[") pushContext(state, stream.column(), "]");
+ else if (curPunc == "(") pushContext(state, stream.column(), ")");
+ else if (curPunc == "}") {
+ while (ctx.type == "statement") ctx = popContext(state);
+ if (ctx.type == "}") ctx = popContext(state);
+ while (ctx.type == "statement") ctx = popContext(state);
+ }
+ else if (curPunc == ctx.type) popContext(state);
+ else if (((ctx.type == "}" || ctx.type == "top") && curPunc != ';') || (ctx.type == "statement" && curPunc == "newstatement"))
+ pushContext(state, stream.column(), "statement");
+ state.startOfLine = false;
+ return style;
+ },
+
+ indent: function(state, textAfter) {
+ if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
+ var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
+ if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
+ var closing = firstChar == ctx.type;
+ if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
+ else if (ctx.align) return ctx.column + (closing ? 0 : 1);
+ else return ctx.indented + (closing ? 0 : indentUnit);
+ },
+
+ electricChars: "{}"
+ };
+});
+
+ function words(str) {
+ var obj = {}, words = str.split(" ");
+ for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+ return obj;
+ }
+
+ var blockKeywords = "body catch class do else enum for foreach foreach_reverse if in interface mixin " +
+ "out scope struct switch try union unittest version while with";
+
+ CodeMirror.defineMIME("text/x-d", {
+ name: "d",
+ keywords: words("abstract alias align asm assert auto break case cast cdouble cent cfloat const continue " +
+ "debug default delegate delete deprecated export extern final finally function goto immutable " +
+ "import inout invariant is lazy macro module new nothrow override package pragma private " +
+ "protected public pure ref return shared short static super synchronized template this " +
+ "throw typedef typeid typeof volatile __FILE__ __LINE__ __gshared __traits __vector __parameters " +
+ blockKeywords),
+ blockKeywords: words(blockKeywords),
+ builtin: words("bool byte char creal dchar double float idouble ifloat int ireal long real short ubyte " +
+ "ucent uint ulong ushort wchar wstring void size_t sizediff_t"),
+ atoms: words("exit failure success true false null"),
+ hooks: {
+ "@": function(stream, _state) {
+ stream.eatWhile(/[\w\$_]/);
+ return "meta";
+ }
+ }
+ });
+
+});
diff --git a/static/mdeditor/js/lib/codemirror/mode/d/index.html b/static/mdeditor/js/lib/codemirror/mode/d/index.html
new file mode 100644
index 0000000..08cabd8
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/d/index.html
@@ -0,0 +1,273 @@
+
+
+CodeMirror: D mode
+
+
+
+
+
+
+
+
+
+
+
+D mode
+
+/* D demo code // copied from phobos/sd/metastrings.d */
+// Written in the D programming language.
+
+/**
+Templates with which to do compile-time manipulation of strings.
+
+Macros:
+ WIKI = Phobos/StdMetastrings
+
+Copyright: Copyright Digital Mars 2007 - 2009.
+License: Boost License 1.0 .
+Authors: $(WEB digitalmars.com, Walter Bright),
+ Don Clugston
+Source: $(PHOBOSSRC std/_metastrings.d)
+*/
+/*
+ Copyright Digital Mars 2007 - 2009.
+Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+ */
+module std.metastrings;
+
+/**
+Formats constants into a string at compile time. Analogous to $(XREF
+string,format).
+
+Parameters:
+
+A = tuple of constants, which can be strings, characters, or integral
+ values.
+
+Formats:
+ * The formats supported are %s for strings, and %%
+ * for the % character.
+Example:
+---
+import std.metastrings;
+import std.stdio;
+
+void main()
+{
+ string s = Format!("Arg %s = %s", "foo", 27);
+ writefln(s); // "Arg foo = 27"
+}
+ * ---
+ */
+
+template Format(A...)
+{
+ static if (A.length == 0)
+ enum Format = "";
+ else static if (is(typeof(A[0]) : const(char)[]))
+ enum Format = FormatString!(A[0], A[1..$]);
+ else
+ enum Format = toStringNow!(A[0]) ~ Format!(A[1..$]);
+}
+
+template FormatString(const(char)[] F, A...)
+{
+ static if (F.length == 0)
+ enum FormatString = Format!(A);
+ else static if (F.length == 1)
+ enum FormatString = F[0] ~ Format!(A);
+ else static if (F[0..2] == "%s")
+ enum FormatString
+ = toStringNow!(A[0]) ~ FormatString!(F[2..$],A[1..$]);
+ else static if (F[0..2] == "%%")
+ enum FormatString = "%" ~ FormatString!(F[2..$],A);
+ else
+ {
+ static assert(F[0] != '%', "unrecognized format %" ~ F[1]);
+ enum FormatString = F[0] ~ FormatString!(F[1..$],A);
+ }
+}
+
+unittest
+{
+ auto s = Format!("hel%slo", "world", -138, 'c', true);
+ assert(s == "helworldlo-138ctrue", "[" ~ s ~ "]");
+}
+
+/**
+ * Convert constant argument to a string.
+ */
+
+template toStringNow(ulong v)
+{
+ static if (v < 10)
+ enum toStringNow = "" ~ cast(char)(v + '0');
+ else
+ enum toStringNow = toStringNow!(v / 10) ~ toStringNow!(v % 10);
+}
+
+unittest
+{
+ static assert(toStringNow!(1uL << 62) == "4611686018427387904");
+}
+
+/// ditto
+template toStringNow(long v)
+{
+ static if (v < 0)
+ enum toStringNow = "-" ~ toStringNow!(cast(ulong) -v);
+ else
+ enum toStringNow = toStringNow!(cast(ulong) v);
+}
+
+unittest
+{
+ static assert(toStringNow!(0x100000000) == "4294967296");
+ static assert(toStringNow!(-138L) == "-138");
+}
+
+/// ditto
+template toStringNow(uint U)
+{
+ enum toStringNow = toStringNow!(cast(ulong)U);
+}
+
+/// ditto
+template toStringNow(int I)
+{
+ enum toStringNow = toStringNow!(cast(long)I);
+}
+
+/// ditto
+template toStringNow(bool B)
+{
+ enum toStringNow = B ? "true" : "false";
+}
+
+/// ditto
+template toStringNow(string S)
+{
+ enum toStringNow = S;
+}
+
+/// ditto
+template toStringNow(char C)
+{
+ enum toStringNow = "" ~ C;
+}
+
+
+/********
+ * Parse unsigned integer literal from the start of string s.
+ * returns:
+ * .value = the integer literal as a string,
+ * .rest = the string following the integer literal
+ * Otherwise:
+ * .value = null,
+ * .rest = s
+ */
+
+template parseUinteger(const(char)[] s)
+{
+ static if (s.length == 0)
+ {
+ enum value = "";
+ enum rest = "";
+ }
+ else static if (s[0] >= '0' && s[0] <= '9')
+ {
+ enum value = s[0] ~ parseUinteger!(s[1..$]).value;
+ enum rest = parseUinteger!(s[1..$]).rest;
+ }
+ else
+ {
+ enum value = "";
+ enum rest = s;
+ }
+}
+
+/********
+Parse integer literal optionally preceded by $(D '-') from the start
+of string $(D s).
+
+Returns:
+ .value = the integer literal as a string,
+ .rest = the string following the integer literal
+
+Otherwise:
+ .value = null,
+ .rest = s
+*/
+
+template parseInteger(const(char)[] s)
+{
+ static if (s.length == 0)
+ {
+ enum value = "";
+ enum rest = "";
+ }
+ else static if (s[0] >= '0' && s[0] <= '9')
+ {
+ enum value = s[0] ~ parseUinteger!(s[1..$]).value;
+ enum rest = parseUinteger!(s[1..$]).rest;
+ }
+ else static if (s.length >= 2 &&
+ s[0] == '-' && s[1] >= '0' && s[1] <= '9')
+ {
+ enum value = s[0..2] ~ parseUinteger!(s[2..$]).value;
+ enum rest = parseUinteger!(s[2..$]).rest;
+ }
+ else
+ {
+ enum value = "";
+ enum rest = s;
+ }
+}
+
+unittest
+{
+ assert(parseUinteger!("1234abc").value == "1234");
+ assert(parseUinteger!("1234abc").rest == "abc");
+ assert(parseInteger!("-1234abc").value == "-1234");
+ assert(parseInteger!("-1234abc").rest == "abc");
+}
+
+/**
+Deprecated aliases held for backward compatibility.
+*/
+deprecated alias toStringNow ToString;
+/// Ditto
+deprecated alias parseUinteger ParseUinteger;
+/// Ditto
+deprecated alias parseUinteger ParseInteger;
+
+
+
+
+
+ Simple mode that handle D-Syntax (DLang Homepage ).
+
+ MIME types defined: text/x-d
+ .
+
diff --git a/static/mdeditor/js/lib/codemirror/mode/dart/dart.js b/static/mdeditor/js/lib/codemirror/mode/dart/dart.js
new file mode 100644
index 0000000..a49e218
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/dart/dart.js
@@ -0,0 +1,50 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"), require("../clike/clike"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror", "../clike/clike"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+ "use strict";
+
+ var keywords = ("this super static final const abstract class extends external factory " +
+ "implements get native operator set typedef with enum throw rethrow " +
+ "assert break case continue default in return new deferred async await " +
+ "try catch finally do else for if switch while import library export " +
+ "part of show hide is").split(" ");
+ var blockKeywords = "try catch finally do else for if switch while".split(" ");
+ var atoms = "true false null".split(" ");
+ var builtins = "void bool num int double dynamic var String".split(" ");
+
+ function set(words) {
+ var obj = {};
+ for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+ return obj;
+ }
+
+ CodeMirror.defineMIME("application/dart", {
+ name: "clike",
+ keywords: set(keywords),
+ multiLineStrings: true,
+ blockKeywords: set(blockKeywords),
+ builtin: set(builtins),
+ atoms: set(atoms),
+ hooks: {
+ "@": function(stream) {
+ stream.eatWhile(/[\w\$_]/);
+ return "meta";
+ }
+ }
+ });
+
+ CodeMirror.registerHelper("hintWords", "application/dart", keywords.concat(atoms).concat(builtins));
+
+ // This is needed to make loading through meta.js work.
+ CodeMirror.defineMode("dart", function(conf) {
+ return CodeMirror.getMode(conf, "application/dart");
+ }, "clike");
+});
diff --git a/static/mdeditor/js/lib/codemirror/mode/dart/index.html b/static/mdeditor/js/lib/codemirror/mode/dart/index.html
new file mode 100644
index 0000000..e79da5a
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/dart/index.html
@@ -0,0 +1,71 @@
+
+
+CodeMirror: Dart mode
+
+
+
+
+
+
+
+
+
+
+Dart mode
+
+
+import 'dart:math' show Random;
+
+void main() {
+ print(new Die(n: 12).roll());
+}
+
+// Define a class.
+class Die {
+ // Define a class variable.
+ static Random shaker = new Random();
+
+ // Define instance variables.
+ int sides, value;
+
+ // Define a method using shorthand syntax.
+ String toString() => '$value';
+
+ // Define a constructor.
+ Die({int n: 6}) {
+ if (4 <= n && n <= 20) {
+ sides = n;
+ } else {
+ // Support for errors and exceptions.
+ throw new ArgumentError(/* */);
+ }
+ }
+
+ // Define an instance method.
+ int roll() {
+ return value = shaker.nextInt(sides) + 1;
+ }
+}
+
+
+
+
+
+
diff --git a/static/mdeditor/js/lib/codemirror/mode/diff/diff.js b/static/mdeditor/js/lib/codemirror/mode/diff/diff.js
new file mode 100644
index 0000000..fe0305e
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/diff/diff.js
@@ -0,0 +1,47 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(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) {
+"use strict";
+
+CodeMirror.defineMode("diff", function() {
+
+ var TOKEN_NAMES = {
+ '+': 'positive',
+ '-': 'negative',
+ '@': 'meta'
+ };
+
+ return {
+ token: function(stream) {
+ var tw_pos = stream.string.search(/[\t ]+?$/);
+
+ if (!stream.sol() || tw_pos === 0) {
+ stream.skipToEnd();
+ return ("error " + (
+ TOKEN_NAMES[stream.string.charAt(0)] || '')).replace(/ $/, '');
+ }
+
+ var token_name = TOKEN_NAMES[stream.peek()] || stream.skipToEnd();
+
+ if (tw_pos === -1) {
+ stream.skipToEnd();
+ } else {
+ stream.pos = tw_pos;
+ }
+
+ return token_name;
+ }
+ };
+});
+
+CodeMirror.defineMIME("text/x-diff", "diff");
+
+});
diff --git a/static/mdeditor/js/lib/codemirror/mode/diff/index.html b/static/mdeditor/js/lib/codemirror/mode/diff/index.html
new file mode 100644
index 0000000..0af611f
--- /dev/null
+++ b/static/mdeditor/js/lib/codemirror/mode/diff/index.html
@@ -0,0 +1,117 @@
+
+
+CodeMirror: Diff mode
+
+
+
+
+
+
+
+
+
+
+Diff mode
+
+diff --git a/index.html b/index.html
+index c1d9156..7764744 100644
+--- a/index.html
++++ b/index.html
+@@ -95,7 +95,8 @@ StringStream.prototype = {
+
+