diff --git a/static/editor.md/css/editormd.css b/static/editor.md/css/editormd.css index 77353329..bcb4dbfd 100644 --- a/static/editor.md/css/editormd.css +++ b/static/editor.md/css/editormd.css @@ -2,12 +2,12 @@ * Editor.md * * @file editormd.css - * @version v1.5.0 + * @version v1.7.17 * @description Open source online markdown editor. * @license MIT License - * @author Pandao - * {@link https://github.com/pandao/editor.md} - * @updateTime 2015-06-09 + * @author IBM Skills Network + * {@link https://github.com/ibm-skills-network/editor.md} + * @updateTime 2024-03-27 */ @charset "UTF-8"; @@ -47,9 +47,9 @@ .editormd .editormd-markdown-textarea { display: none; } -.editormd input[type="text"], -.editormd input[type="button"], -.editormd input[type="submit"], +.editormd input[type=text], +.editormd input[type=button], +.editormd input[type=submit], .editormd select, .editormd textarea, .editormd button { -webkit-appearance: none; -moz-appearance: none; @@ -73,16 +73,11 @@ border-radius: 6px; } .editormd ::-webkit-scrollbar-thumb:hover { - -webkit-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25); - /* Webkit browsers */ - -moz-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25); - /* Firefox */ - -ms-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25); - /* IE9 */ - -o-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25); - /* Opera(Old) */ - box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25); - /* IE9+, News */ + -webkit-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25); /* Webkit browsers */ + -moz-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25); /* Firefox */ + -ms-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25); /* IE9 */ + -o-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25); /* Opera(Old) */ + box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25); /* IE9+, News */ background-color: rgba(0, 0, 0, 0.4); } @@ -148,12 +143,9 @@ -o-border-radius: 2px; border-radius: 2px; border: 1px solid #fff; - -webkit-transition: all 300ms ease-out; - /* Safari, Chrome */ - -moz-transition: all 300ms ease-out; - /* Firefox 4.0~16.0 */ - transition: all 300ms ease-out; - /* IE >9, FF >15, Opera >12.0 */ + -webkit-transition: all 300ms ease-out; /* Safari, Chrome */ + -moz-transition: all 300ms ease-out; /* Firefox 4.0~16.0 */ + transition: all 300ms ease-out; /* IE >9, FF >15, Opera >12.0 */ } .editormd-menu > li > a:hover, .editormd-menu > li > a.active { border: 1px solid #ddd; @@ -186,16 +178,11 @@ top: 33px; left: 0; z-index: 100; - -webkit-box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.15); - /* Webkit browsers */ - -moz-box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.15); - /* Firefox */ - -ms-box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.15); - /* IE9 */ - -o-box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.15); - /* Opera(Old) */ - box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.15); - /* IE9+, News */ + -webkit-box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.15); /* Webkit browsers */ + -moz-box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.15); /* Firefox */ + -ms-box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.15); /* IE9 */ + -o-box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.15); /* Opera(Old) */ + box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.15); /* IE9+, News */ } .editormd-dropdown-menu:before, .editormd-dropdown-menu:after { width: 0; @@ -222,12 +209,9 @@ } .editormd-dropdown-menu > li > a:hover { background: #f6f6f6; - -webkit-transition: all 300ms ease-out; - /* Safari, Chrome */ - -moz-transition: all 300ms ease-out; - /* Firefox 4.0~16.0 */ - transition: all 300ms ease-out; - /* IE >9, FF >15, Opera >12.0 */ + -webkit-transition: all 300ms ease-out; /* Safari, Chrome */ + -moz-transition: all 300ms ease-out; /* Firefox 4.0~16.0 */ + transition: all 300ms ease-out; /* IE >9, FF >15, Opera >12.0 */ } .editormd-dropdown-menu > li + li { border-top: 1px solid #ddd; @@ -256,16 +240,11 @@ -ms-border-radius: 3px; -o-border-radius: 3px; border-radius: 3px; - -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); - /* Webkit browsers */ - -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); - /* Firefox */ - -ms-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); - /* IE9 */ - -o-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); - /* Opera(Old) */ - box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); - /* IE9+, News */ + -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); /* Webkit browsers */ + -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); /* Firefox */ + -ms-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); /* IE9 */ + -o-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); /* Opera(Old) */ + box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); /* IE9+, News */ background: #fff; font-size: 14px; } @@ -301,12 +280,9 @@ right: 15px; font-size: 18px; color: #ccc; - -webkit-transition: color 300ms ease-out; - /* Safari, Chrome */ - -moz-transition: color 300ms ease-out; - /* Firefox 4.0~16.0 */ - transition: color 300ms ease-out; - /* IE >9, FF >15, Opera >12.0 */ + -webkit-transition: color 300ms ease-out; /* Safari, Chrome */ + -moz-transition: color 300ms ease-out; /* Firefox 4.0~16.0 */ + transition: color 300ms ease-out; /* IE >9, FF >15, Opera >12.0 */ } .editormd-dialog-close:hover { color: #999; @@ -315,12 +291,9 @@ .editormd-dialog-header { padding: 11px 20px; border-bottom: 1px solid #eee; - -webkit-transition: background 300ms ease-out; - /* Safari, Chrome */ - -moz-transition: background 300ms ease-out; - /* Firefox 4.0~16.0 */ - transition: background 300ms ease-out; - /* IE >9, FF >15, Opera >12.0 */ + -webkit-transition: background 300ms ease-out; /* Safari, Chrome */ + -moz-transition: background 300ms ease-out; /* Firefox 4.0~16.0 */ + transition: background 300ms ease-out; /* IE >9, FF >15, Opera >12.0 */ } .editormd-dialog-header:hover { background: #f6f6f6; @@ -385,24 +358,18 @@ .editormd-mask { position: fixed; background: #000; - opacity: 0.2; - /* W3C */ - filter: alpha(opacity=20); - /* IE */ + opacity: 0.2; /* W3C */ + filter: alpha(opacity=20); /* IE */ z-index: 99998; } .editormd-container-mask, .editormd-dialog-mask-con { background: url(../images/loading.gif) no-repeat center center; - -webkit-background-size: 32px 32px; - /* Chrome, iOS, Safari */ - -moz-background-size: 32px 32px; - /* Firefox 3.6~4.0 */ - -o-background-size: 32px 32px; - /* Opera 9.5 */ - background-size: 32px 32px; - /* IE9+, New */ + -webkit-background-size: 32px 32px; /* Chrome, iOS, Safari */ + -moz-background-size: 32px 32px; /* Firefox 3.6~4.0 */ + -o-background-size: 32px 32px; /* Opera 9.5 */ + background-size: 32px 32px; /* IE9+, New */ } .editormd-container-mask { @@ -462,12 +429,9 @@ vertical-align: middle; border: 1px solid #ddd; text-decoration: none; - -webkit-transition: background-color 300ms ease-out, color 100ms ease-in; - /* Safari, Chrome */ - -moz-transition: background-color 300ms ease-out, color 100ms ease-in; - /* Firefox 4.0~16.0 */ - transition: background-color 300ms ease-out, color 100ms ease-in; - /* IE >9, FF >15, Opera >12.0 */ + -webkit-transition: background-color 300ms ease-out, color 100ms ease-in; /* Safari, Chrome */ + -moz-transition: background-color 300ms ease-out, color 100ms ease-in; /* Firefox 4.0~16.0 */ + transition: background-color 300ms ease-out, color 100ms ease-in; /* IE >9, FF >15, Opera >12.0 */ } .editormd-grid-table-row a.selected { color: #666; @@ -504,12 +468,9 @@ -o-border-top-right-radius: 3px; border-top-right-radius: 3px; background: #f6f6f6; - -webkit-transition: all 300ms ease-out; - /* Safari, Chrome */ - -moz-transition: all 300ms ease-out; - /* Firefox 4.0~16.0 */ - transition: all 300ms ease-out; - /* IE >9, FF >15, Opera >12.0 */ + -webkit-transition: all 300ms ease-out; /* Safari, Chrome */ + -moz-transition: all 300ms ease-out; /* Firefox 4.0~16.0 */ + transition: all 300ms ease-out; /* IE >9, FF >15, Opera >12.0 */ } .editormd-tab-head li a:hover { color: #666; @@ -549,17 +510,17 @@ .editormd-form input:focus { outline: 0; } -.editormd-form input[type="text"], .editormd-form input[type="number"] { +.editormd-form input[type=text], .editormd-form input[type=number] { color: #999; padding: 8px; border: 1px solid #ddd; } -.editormd-form input[type="number"] { +.editormd-form input[type=number] { width: 40px; display: inline-block; padding: 6px 8px; } -.editormd-form input[type="text"] { +.editormd-form input[type=text] { display: inline-block; width: 264px; } @@ -585,11 +546,11 @@ cursor: pointer; } -.editormd-form input[type="submit"], .editormd-form .editormd-btn, .editormd-form button, -.editormd-dialog-container input[type="submit"], +.editormd-form input[type=submit], .editormd-form .editormd-btn, .editormd-form button, +.editormd-dialog-container input[type=submit], .editormd-dialog-container .editormd-btn, .editormd-dialog-container button, -.editormd-dialog-footer input[type="submit"], +.editormd-dialog-footer input[type=submit], .editormd-dialog-footer .editormd-btn, .editormd-dialog-footer button { color: #666; @@ -603,18 +564,15 @@ -ms-border-radius: 3px; -o-border-radius: 3px; border-radius: 3px; - -webkit-transition: background 300ms ease-out; - /* Safari, Chrome */ - -moz-transition: background 300ms ease-out; - /* Firefox 4.0~16.0 */ - transition: background 300ms ease-out; - /* IE >9, FF >15, Opera >12.0 */ + -webkit-transition: background 300ms ease-out; /* Safari, Chrome */ + -moz-transition: background 300ms ease-out; /* Firefox 4.0~16.0 */ + transition: background 300ms ease-out; /* IE >9, FF >15, Opera >12.0 */ } -.editormd-form input[type="submit"]:hover, .editormd-form .editormd-btn:hover, .editormd-form button:hover, -.editormd-dialog-container input[type="submit"]:hover, +.editormd-form input[type=submit]:hover, .editormd-form .editormd-btn:hover, .editormd-form button:hover, +.editormd-dialog-container input[type=submit]:hover, .editormd-dialog-container .editormd-btn:hover, .editormd-dialog-container button:hover, -.editormd-dialog-footer input[type="submit"]:hover, +.editormd-dialog-footer input[type=submit]:hover, .editormd-dialog-footer .editormd-btn:hover, .editormd-dialog-footer button:hover { background: #eee; @@ -622,7 +580,7 @@ .editormd-form .editormd-btn, .editormd-dialog-container .editormd-btn, .editormd-dialog-footer .editormd-btn { - padding: 5px 8px 4px\0; + padding: 5px 8px 4px\0 ; } .editormd-form .editormd-btn + .editormd-btn, .editormd-dialog-container .editormd-btn + .editormd-btn, @@ -637,7 +595,7 @@ position: relative; display: inline-block; } -.editormd-file-input input[type="file"] { +.editormd-file-input input[type=file] { width: 75px; height: 32px; opacity: 0; @@ -648,10 +606,10 @@ top: 0; right: 0; } -.editormd-file-input input[type="file"]::-webkit-file-upload-button { +.editormd-file-input input[type=file]::-webkit-file-upload-button { visibility: hidden; } -.editormd-file-input:hover input[type="submit"] { +.editormd-file-input:hover input[type=submit] { background: #eee; } @@ -670,11 +628,12 @@ position: absolute; top: 35px; right: 0; - right: -1px\0; + right: -1px\0 ; overflow: auto; line-height: 1.6; display: none; background: #fff; + z-index: 10; } .editormd .CodeMirror { @@ -735,7 +694,7 @@ /* FONT PATH * -------------------------- */ @font-face { - font-family: 'FontAwesome'; + font-family: "FontAwesome"; src: url("../fonts/fontawesome-webfont.eot?v=4.3.0"); src: url("../fonts/fontawesome-webfont.eot?#iefix&v=4.3.0") format("embedded-opentype"), url("../fonts/fontawesome-webfont.woff2?v=4.3.0") format("woff2"), url("../fonts/fontawesome-webfont.woff?v=4.3.0") format("woff"), url("../fonts/fontawesome-webfont.ttf?v=4.3.0") format("truetype"), url("../fonts/fontawesome-webfont.svg?v=4.3.0#fontawesomeregular") format("svg"); font-weight: normal; @@ -802,9 +761,9 @@ } .fa-border { - padding: .2em .25em .15em; + padding: 0.2em 0.25em 0.15em; border: solid 0.08em #eeeeee; - border-radius: .1em; + border-radius: 0.1em; } .pull-right { @@ -816,11 +775,11 @@ } .fa.pull-left { - margin-right: .3em; + margin-right: 0.3em; } .fa.pull-right { - margin-left: .3em; + margin-left: 0.3em; } .fa-spin { @@ -3079,9 +3038,9 @@ /*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */ @font-face { - font-family: 'editormd-logo'; + font-family: "editormd-logo"; src: url("../fonts/editormd-logo.eot?-5y8q6h"); - src: url(".../fonts/editormd-logo.eot?#iefix-5y8q6h") format("embedded-opentype"), url("../fonts/editormd-logo.woff?-5y8q6h") format("woff"), url("../fonts/editormd-logo.ttf?-5y8q6h") format("truetype"), url("../fonts/editormd-logo.svg?-5y8q6h#icomoon") format("svg"); + src: url("../fonts/editormd-logo.eot?#iefix-5y8q6h") format("embedded-opentype"), url("../fonts/editormd-logo.woff?-5y8q6h") format("woff"), url("../fonts/editormd-logo.ttf?-5y8q6h") format("truetype"), url("../fonts/editormd-logo.svg?-5y8q6h#icomoon") format("svg"); font-weight: normal; font-style: normal; } @@ -3094,7 +3053,7 @@ .editormd-logo-6x, .editormd-logo-7x, .editormd-logo-8x { - font-family: 'editormd-logo'; + font-family: "editormd-logo"; speak: none; font-style: normal; font-weight: normal; @@ -3233,7 +3192,7 @@ line-height: normal; } -.markdown-body input[type="checkbox"] { +.markdown-body input[type=checkbox] { -moz-box-sizing: border-box; box-sizing: border-box; padding: 0; @@ -3259,7 +3218,7 @@ } .markdown-body a { - color: #08c; + color: #4183c4; text-decoration: none; } @@ -3375,7 +3334,7 @@ } .markdown-body .octicon-link:before { - content: '\f05c'; + content: "\f05c"; } .markdown-body > *:first-child { @@ -3613,7 +3572,7 @@ .markdown-body code:before, .markdown-body code:after { letter-spacing: -0.2em; - content: "\00a0"; + content: " "; } .markdown-body pre > code { @@ -3636,6 +3595,7 @@ overflow: auto; font-size: 85%; line-height: 1.45; + background-color: #f7f7f7; border-radius: 3px; } @@ -3656,6 +3616,7 @@ overflow: initial; line-height: inherit; word-wrap: normal; + background-color: transparent; border: 0; } @@ -3834,36 +3795,12 @@ background-color: #fff; } .editormd-preview-container blockquote, .editormd-html-preview blockquote { - color: #2C3E50; - border-left: 5px solid #D6DBDF; + color: #666; + border-left: 4px solid #ddd; + padding-left: 20px; + margin-left: 0; font-size: 14px; - background: none repeat scroll 0 0 rgba(102,128,153,.05); - margin: 8px 0; - padding: 8px 16px; -} -.editormd-preview-container blockquote.default, .editormd-html-preview blockquote.default { - - -} -.editormd-preview-container blockquote.info, .editormd-html-preview blockquote.info { - border-left-color: #5bc0de; - color: #5bc0de; - background-color: #f4f8fa -} -.editormd-preview-container blockquote.warning, .editormd-html-preview blockquote.warning { - background-color: #fcf8f2; - border-color: #f0ad4e; - color: #f0ad4e -} -.editormd-preview-container blockquote.danger, .editormd-html-preview blockquote.danger { - color: #d9534f; - background-color: #fdf7f7; - border-color: #d9534f -} -.editormd-preview-container blockquote.success, .editormd-html-preview blockquote.success { - background-color: #f3f8f3; - border-color: #50af51; - color: #50af51 + font-style: italic; } .editormd-preview-container p code, .editormd-html-preview p code { margin-left: 5px; @@ -3887,6 +3824,7 @@ } .editormd-preview-container pre, .editormd-html-preview pre { border: 1px solid #ddd; + background: #f6f6f6; padding: 10px; -webkit-border-radius: 3px; -moz-border-radius: 3px; @@ -3932,104 +3870,73 @@ /* SPAN elements with the classes below are added by prettyprint. */ .pln { color: #000; -} - -/* plain text */ +} /* plain text */ @media screen { .str { color: #080; - } - - /* string content */ + } /* string content */ .kwd { color: #008; - } - - /* a keyword */ + } /* a keyword */ .com { color: #800; - } - - /* a comment */ + } /* a comment */ .typ { color: #606; - } - - /* a type name */ + } /* a type name */ .lit { color: #066; - } - - /* a literal value */ + } /* a literal value */ /* punctuation, lisp open bracket, lisp close bracket */ .pun, .opn, .clo { color: #660; } - .tag { color: #008; - } - - /* a markup tag name */ + } /* a markup tag name */ .atn { color: #606; - } - - /* a markup attribute name */ + } /* a markup attribute name */ .atv { color: #080; - } - - /* a markup attribute value */ + } /* a markup attribute value */ .dec, .var { color: #606; - } - - /* a declaration; a variable name */ + } /* a declaration; a variable name */ .fun { color: red; - } - - /* a function name */ + } /* a function name */ } /* Use higher contrast and text-weight for printable form. */ @media print, projection { .str { color: #060; } - .kwd { color: #006; font-weight: bold; } - .com { color: #600; font-style: italic; } - .typ { color: #404; font-weight: bold; } - .lit { color: #044; } - .pun, .opn, .clo { color: #440; } - .tag { color: #006; font-weight: bold; } - .atn { color: #404; } - .atv { color: #060; } @@ -4044,9 +3951,7 @@ pre.prettyprint { ol.linenums { margin-top: 0; margin-bottom: 0; -} - -/* IE indents via margin-left */ +} /* IE indents via margin-left */ li.L0, li.L1, li.L2, @@ -4117,16 +4022,11 @@ li.L9 { -ms-border-radius: 4px; -o-border-radius: 4px; border-radius: 4px; - -webkit-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); - /* Webkit browsers */ - -moz-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); - /* Firefox */ - -ms-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); - /* IE9 */ - -o-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); - /* Opera(Old) */ - box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); - /* IE9+, News */ + -webkit-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* Webkit browsers */ + -moz-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* Firefox */ + -ms-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* IE9 */ + -o-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* Opera(Old) */ + box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* IE9+, News */ } .editormd-preview-container .editormd-toc-menu > .markdown-toc > ul > li ul, .editormd-html-preview .editormd-toc-menu > .markdown-toc > ul > li ul { width: 100%; @@ -4144,12 +4044,9 @@ li.L9 { color: #666; padding: 6px 10px; display: block; - -webkit-transition: background-color 500ms ease-out; - /* Safari, Chrome */ - -moz-transition: background-color 500ms ease-out; - /* Firefox 4.0~16.0 */ - transition: background-color 500ms ease-out; - /* IE >9, FF >15, Opera >12.0 */ + -webkit-transition: background-color 500ms ease-out; /* Safari, Chrome */ + -moz-transition: background-color 500ms ease-out; /* Firefox 4.0~16.0 */ + transition: background-color 500ms ease-out; /* IE >9, FF >15, Opera >12.0 */ } .editormd-preview-container .editormd-toc-menu > .markdown-toc > ul > li a:hover, .editormd-html-preview .editormd-toc-menu > .markdown-toc > ul > li a:hover { background-color: #f6f6f6; @@ -4162,16 +4059,11 @@ li.L9 { top: 32px; left: 10%; display: none; - -webkit-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); - /* Webkit browsers */ - -moz-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); - /* Firefox */ - -ms-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); - /* IE9 */ - -o-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); - /* Opera(Old) */ - box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); - /* IE9+, News */ + -webkit-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* Webkit browsers */ + -moz-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* Firefox */ + -ms-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* IE9 */ + -o-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* Opera(Old) */ + box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* IE9+, News */ } .editormd-preview-container .editormd-toc-menu > .markdown-toc li > ul:before, .editormd-preview-container .editormd-toc-menu > .markdown-toc li > ul:after, .editormd-html-preview .editormd-toc-menu > .markdown-toc li > ul:before, .editormd-html-preview .editormd-toc-menu > .markdown-toc li > ul:after { pointer-events: pointer-events; @@ -4214,12 +4106,9 @@ li.L9 { padding: 5px 10px; border-radius: 4px; display: inline-block; - -webkit-transition: background-color 500ms ease-out; - /* Safari, Chrome */ - -moz-transition: background-color 500ms ease-out; - /* Firefox 4.0~16.0 */ - transition: background-color 500ms ease-out; - /* IE >9, FF >15, Opera >12.0 */ + -webkit-transition: background-color 500ms ease-out; /* Safari, Chrome */ + -moz-transition: background-color 500ms ease-out; /* Firefox 4.0~16.0 */ + transition: background-color 500ms ease-out; /* IE >9, FF >15, Opera >12.0 */ } .editormd-preview-container .editormd-toc-menu .toc-menu-btn:hover, .editormd-html-preview .editormd-toc-menu .toc-menu-btn:hover { background-color: #f6f6f6; @@ -4274,12 +4163,9 @@ hr.editormd-page-break { top: 25px; right: 35px; z-index: 19; - -webkit-transition: background-color 300ms ease-out; - /* Safari, Chrome */ - -moz-transition: background-color 300ms ease-out; - /* Firefox 4.0~16.0 */ - transition: background-color 300ms ease-out; - /* IE >9, FF >15, Opera >12.0 */ + -webkit-transition: background-color 300ms ease-out; /* Safari, Chrome */ + -moz-transition: background-color 300ms ease-out; /* Firefox 4.0~16.0 */ + transition: background-color 300ms ease-out; /* IE >9, FF >15, Opera >12.0 */ } .editormd-preview-close-btn:hover { background-color: #999; @@ -4382,8 +4268,7 @@ hr.editormd-page-break { } @media screen { - .editormd-preview-theme-dark { - /* string content */ + .editormd-preview-theme-dark { /* string content */ /* a keyword */ /* a comment */ /* a type name */ @@ -4468,4 +4353,4 @@ hr.editormd-page-break { } .editormd-theme-dark .CodeMirror { border-right: 1px solid rgba(0, 0, 0, 0.1); -} +} \ No newline at end of file diff --git a/static/editor.md/css/editormd.logo.css b/static/editor.md/css/editormd.logo.css index 5f901bfa..99684401 100644 --- a/static/editor.md/css/editormd.logo.css +++ b/static/editor.md/css/editormd.logo.css @@ -2,19 +2,20 @@ * Editor.md * * @file editormd.logo.css - * @version v1.5.0 + * @version v1.7.17 * @description Open source online markdown editor. * @license MIT License - * @author Pandao - * {@link https://github.com/pandao/editor.md} - * @updateTime 2015-06-09 + * @author IBM Skills Network + * {@link https://github.com/ibm-skills-network/editor.md} + * @updateTime 2024-03-27 */ +@charset "UTF-8"; /*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */ @font-face { - font-family: 'editormd-logo'; + font-family: "editormd-logo"; src: url("../fonts/editormd-logo.eot?-5y8q6h"); - src: url(".../fonts/editormd-logo.eot?#iefix-5y8q6h") format("embedded-opentype"), url("../fonts/editormd-logo.woff?-5y8q6h") format("woff"), url("../fonts/editormd-logo.ttf?-5y8q6h") format("truetype"), url("../fonts/editormd-logo.svg?-5y8q6h#icomoon") format("svg"); + src: url("../fonts/editormd-logo.eot?#iefix-5y8q6h") format("embedded-opentype"), url("../fonts/editormd-logo.woff?-5y8q6h") format("woff"), url("../fonts/editormd-logo.ttf?-5y8q6h") format("truetype"), url("../fonts/editormd-logo.svg?-5y8q6h#icomoon") format("svg"); font-weight: normal; font-style: normal; } @@ -27,7 +28,7 @@ .editormd-logo-6x, .editormd-logo-7x, .editormd-logo-8x { - font-family: 'editormd-logo'; + font-family: "editormd-logo"; speak: none; font-style: normal; font-weight: normal; @@ -95,4 +96,4 @@ .editormd-logo-color { color: #2196F3; -} +} \ No newline at end of file diff --git a/static/editor.md/css/editormd.logo.min.css b/static/editor.md/css/editormd.logo.min.css index d1699782..92d37bcc 100644 --- a/static/editor.md/css/editormd.logo.min.css +++ b/static/editor.md/css/editormd.logo.min.css @@ -1,2 +1,2 @@ -/*! Editor.md v1.5.0 | editormd.logo.min.css | Open source online markdown editor. | MIT License | By: Pandao | https://github.com/pandao/editor.md | 2015-06-09 */ -/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */@font-face{font-family:editormd-logo;src:url(../fonts/editormd-logo.eot?-5y8q6h);src:url(.../fonts/editormd-logo.eot?#iefix-5y8q6h)format("embedded-opentype"),url(../fonts/editormd-logo.woff?-5y8q6h)format("woff"),url(../fonts/editormd-logo.ttf?-5y8q6h)format("truetype"),url(../fonts/editormd-logo.svg?-5y8q6h#icomoon)format("svg");font-weight:400;font-style:normal}.editormd-logo,.editormd-logo-1x,.editormd-logo-2x,.editormd-logo-3x,.editormd-logo-4x,.editormd-logo-5x,.editormd-logo-6x,.editormd-logo-7x,.editormd-logo-8x{font-family:editormd-logo;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;font-size:inherit;line-height:1;display:inline-block;text-rendering:auto;vertical-align:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.editormd-logo-1x:before,.editormd-logo-2x:before,.editormd-logo-3x:before,.editormd-logo-4x:before,.editormd-logo-5x:before,.editormd-logo-6x:before,.editormd-logo-7x:before,.editormd-logo-8x:before,.editormd-logo:before{content:"\e1987"}.editormd-logo-1x{font-size:1em}.editormd-logo-lg{font-size:1.2em}.editormd-logo-2x{font-size:2em}.editormd-logo-3x{font-size:3em}.editormd-logo-4x{font-size:4em}.editormd-logo-5x{font-size:5em}.editormd-logo-6x{font-size:6em}.editormd-logo-7x{font-size:7em}.editormd-logo-8x{font-size:8em}.editormd-logo-color{color:#2196F3} \ No newline at end of file +/*! Editor.md v1.7.17 | editormd.logo.min.css | Open source online markdown editor. | MIT License | By: IBM Skills Network | https://github.com/ibm-skills-network/editor.md | 2024-03-27 */ +@charset "UTF-8";/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */@font-face{font-family:editormd-logo;src:url(../fonts/editormd-logo.eot?-5y8q6h);src:url(../fonts/editormd-logo.eot?#iefix-5y8q6h) format("embedded-opentype"),url(../fonts/editormd-logo.woff?-5y8q6h) format("woff"),url(../fonts/editormd-logo.ttf?-5y8q6h) format("truetype"),url(../fonts/editormd-logo.svg?-5y8q6h#icomoon) format("svg");font-weight:400;font-style:normal}.editormd-logo,.editormd-logo-1x,.editormd-logo-2x,.editormd-logo-3x,.editormd-logo-4x,.editormd-logo-5x,.editormd-logo-6x,.editormd-logo-7x,.editormd-logo-8x{font-family:editormd-logo;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;font-size:inherit;line-height:1;display:inline-block;text-rendering:auto;vertical-align:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.editormd-logo-1x:before,.editormd-logo-2x:before,.editormd-logo-3x:before,.editormd-logo-4x:before,.editormd-logo-5x:before,.editormd-logo-6x:before,.editormd-logo-7x:before,.editormd-logo-8x:before,.editormd-logo:before{content:"󡦇"}.editormd-logo-1x{font-size:1em}.editormd-logo-lg{font-size:1.2em}.editormd-logo-2x{font-size:2em}.editormd-logo-3x{font-size:3em}.editormd-logo-4x{font-size:4em}.editormd-logo-5x{font-size:5em}.editormd-logo-6x{font-size:6em}.editormd-logo-7x{font-size:7em}.editormd-logo-8x{font-size:8em}.editormd-logo-color{color:#2196f3} \ No newline at end of file diff --git a/static/editor.md/css/editormd.min.css b/static/editor.md/css/editormd.min.css index 05abb501..53126ddb 100644 --- a/static/editor.md/css/editormd.min.css +++ b/static/editor.md/css/editormd.min.css @@ -1,5 +1,5 @@ -/*! Editor.md v1.5.0 | editormd.min.css | Open source online markdown editor. | MIT License | By: Pandao | https://github.com/pandao/editor.md | 2015-06-09 */ -@charset "UTF-8";/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */.fa-ul,.markdown-body .task-list-item,li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}.editormd-form br,.markdown-body hr:after{clear:both}.editormd{width:90%;height:640px;margin:0 auto 15px;text-align:left;overflow:hidden;position:relative;border:1px solid #ddd;font-family:"Meiryo UI","Microsoft YaHei","Malgun Gothic","Segoe UI","Trebuchet MS",Helvetica,Monaco,monospace,Tahoma,STXihei,"华文细黑",STHeiti,"Helvetica Neue","Droid Sans","wenquanyi micro hei",FreeSans,Arimo,Arial,SimSun,"宋体",Heiti,"黑体",sans-serif}.editormd *,.editormd :after,.editormd :before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.editormd a{text-decoration:none}.editormd img{border:none;vertical-align:middle}.editormd .editormd-html-textarea,.editormd .editormd-markdown-textarea,.editormd>textarea{width:0;height:0;outline:0;resize:none}.editormd .editormd-html-textarea,.editormd .editormd-markdown-textarea{display:none}.editormd button,.editormd input[type=text],.editormd input[type=button],.editormd input[type=submit],.editormd select,.editormd textarea{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none}.editormd ::-webkit-scrollbar{height:10px;width:7px;background:rgba(0,0,0,.1)}.editormd ::-webkit-scrollbar:hover{background:rgba(0,0,0,.2)}.editormd ::-webkit-scrollbar-thumb{background:rgba(0,0,0,.3);-webkit-border-radius:6px;-moz-border-radius:6px;-ms-border-radius:6px;-o-border-radius:6px;border-radius:6px}.editormd ::-webkit-scrollbar-thumb:hover{-webkit-box-shadow:inset 1px 1px 1px rgba(0,0,0,.25);-moz-box-shadow:inset 1px 1px 1px rgba(0,0,0,.25);-ms-box-shadow:inset 1px 1px 1px rgba(0,0,0,.25);-o-box-shadow:inset 1px 1px 1px rgba(0,0,0,.25);box-shadow:inset 1px 1px 1px rgba(0,0,0,.25);background-color:rgba(0,0,0,.4)}.editormd-user-unselect{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.editormd-toolbar{width:100%;min-height:37px;background:#fff;display:none;position:absolute;top:0;left:0;z-index:10;border-bottom:1px solid #ddd}.editormd-toolbar-container{padding:0 8px;min-height:35px;-o-user-select:none;user-select:none}.editormd-toolbar-container,.markdown-body .octicon{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.editormd-menu,.markdown-body ol,.markdown-body td,.markdown-body th,.markdown-body ul{padding:0}.editormd-menu{margin:0;list-style:none}.editormd-menu>li{margin:0;padding:5px 1px;display:inline-block;position:relative}.editormd-menu>li.divider{display:inline-block;text-indent:-9999px;margin:0 5px;height:65%;border-right:1px solid #ddd}.editormd-menu>li>a{outline:0;color:#666;display:inline-block;min-width:24px;font-size:16px;text-decoration:none;text-align:center;-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;border:1px solid #fff;transition:all 300ms ease-out}.editormd-dropdown-menu>li>a:hover,.editormd-menu>li>a{-webkit-transition:all 300ms ease-out;-moz-transition:all 300ms ease-out}.editormd-menu>li>a.active,.editormd-menu>li>a:hover{border:1px solid #ddd;background:#eee}.editormd-menu>li>a>.fa{text-align:center;display:block;padding:5px}.editormd-menu>li>a>.editormd-bold{padding:5px 2px;display:inline-block;font-weight:700}.editormd-menu>li:hover .editormd-dropdown-menu{display:block}.editormd-menu>li+li>a{margin-left:3px}.editormd-dropdown-menu{display:none;background:#fff;border:1px solid #ddd;width:148px;list-style:none;position:absolute;top:33px;left:0;z-index:100;-webkit-box-shadow:1px 2px 6px rgba(0,0,0,.15);-moz-box-shadow:1px 2px 6px rgba(0,0,0,.15);-ms-box-shadow:1px 2px 6px rgba(0,0,0,.15);-o-box-shadow:1px 2px 6px rgba(0,0,0,.15);box-shadow:1px 2px 6px rgba(0,0,0,.15)}.editormd-dropdown-menu:after,.editormd-dropdown-menu:before{width:0;height:0;display:block;content:"";position:absolute;top:-11px;left:8px;border:5px solid transparent}.editormd-dropdown-menu:before{border-bottom-color:#ccc}.editormd-dropdown-menu:after{border-bottom-color:#fff;top:-10px}.editormd-dropdown-menu>li>a{color:#666;display:block;text-decoration:none;padding:8px 10px}.editormd-dropdown-menu>li>a:hover{background:#f6f6f6;transition:all 300ms ease-out}.editormd-dropdown-menu>li+li{border-top:1px solid #ddd}.editormd-container{margin:0;width:100%;height:100%;overflow:hidden;padding:35px 0 0;position:relative;background:#fff;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.editormd-dialog{color:#666;position:fixed;z-index:99999;display:none;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 0 10px rgba(0,0,0,.3);-moz-box-shadow:0 0 10px rgba(0,0,0,.3);-ms-box-shadow:0 0 10px rgba(0,0,0,.3);-o-box-shadow:0 0 10px rgba(0,0,0,.3);box-shadow:0 0 10px rgba(0,0,0,.3);background:#fff;font-size:14px}.editormd-dialog-container{position:relative;padding:20px;line-height:1.4}.editormd-dialog-container h1{font-size:24px;margin-bottom:10px}.editormd-dialog-container h1 .fa{color:#2C7EEA;padding-right:5px}.editormd-dialog-container h1 small{padding-left:5px;font-weight:400;font-size:12px;color:#999}.editormd-dialog-container select{color:#999;padding:3px 8px;border:1px solid #ddd}.editormd-dialog-close{position:absolute;top:12px;right:15px;font-size:18px;color:#ccc;-webkit-transition:color 300ms ease-out;-moz-transition:color 300ms ease-out;transition:color 300ms ease-out}.editormd-dialog-close:hover{color:#999}.editormd-dialog-header{padding:11px 20px;border-bottom:1px solid #eee;-webkit-transition:background 300ms ease-out;-moz-transition:background 300ms ease-out;transition:background 300ms ease-out}.editormd-dialog-header:hover{background:#f6f6f6}.editormd-dialog-title{font-size:14px}.editormd-dialog-footer{padding:10px 0 0;text-align:right}.editormd-dialog-info{width:420px}.editormd-dialog-info h1{font-weight:400}.editormd-dialog-info .editormd-dialog-container{padding:20px 25px 25px}.editormd-dialog-info .editormd-dialog-close{top:10px;right:10px}.editormd-dialog-info .hover-link:hover,.editormd-dialog-info p>a{color:#2196F3}.editormd-dialog-info .hover-link{color:#666}.editormd-dialog-info a .fa-external-link{display:none}.editormd-dialog-info a:hover{color:#2196F3}.editormd-dialog-info a:hover .fa-external-link{display:inline-block}.editormd-container-mask,.editormd-dialog-mask,.editormd-mask{display:none;width:100%;height:100%;position:absolute;top:0;left:0}.editormd-dialog-mask-bg,.editormd-mask{background:#fff;opacity:.5;filter:alpha(opacity=50)}.editormd-mask{position:fixed;background:#000;opacity:.2;filter:alpha(opacity=20);z-index:99998}.editormd-container-mask,.editormd-dialog-mask-con{background:url(../images/loading.gif)center center no-repeat;-webkit-background-size:32px 32px;-moz-background-size:32px 32px;-o-background-size:32px 32px;background-size:32px 32px}.editormd-container-mask{z-index:20;display:block;background-color:#fff}@media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min-device-pixel-ratio:2){.editormd-container-mask,.editormd-dialog-mask-con{background-image:url(../images/loading@2x.gif)}}@media only screen and (-webkit-min-device-pixel-ratio:3),only screen and (min-device-pixel-ratio:3){.editormd-container-mask,.editormd-dialog-mask-con{background-image:url(../images/loading@3x.gif)}}.editormd-code-block-dialog textarea,.editormd-preformatted-text-dialog textarea{width:100%;height:400px;margin-bottom:6px;overflow:auto;border:1px solid #eee;background:#fff;padding:15px;resize:none}.editormd-code-toolbar{color:#999;font-size:14px;margin:-5px 0 10px}.editormd-grid-table{width:99%;display:table;border:1px solid #ddd;border-collapse:collapse}.editormd-grid-table-row{width:100%;display:table-row}.editormd-grid-table-row a{font-size:1.4em;width:5%;height:36px;color:#999;text-align:center;display:table-cell;vertical-align:middle;border:1px solid #ddd;text-decoration:none;-webkit-transition:background-color 300ms ease-out,color 100ms ease-in;-moz-transition:background-color 300ms ease-out,color 100ms ease-in;transition:background-color 300ms ease-out,color 100ms ease-in}.editormd-grid-table-row a.selected{color:#666;background-color:#eee}.editormd-grid-table-row a:hover{color:#777;background-color:#f6f6f6}.editormd-tab-head{list-style:none;border-bottom:1px solid #ddd}.editormd-tab-head li{display:inline-block}.editormd-tab-head li a{color:#999;display:block;padding:6px 12px 5px;text-align:center;text-decoration:none;margin-bottom:-1px;border:1px solid #ddd;-webkit-border-top-left-radius:3px;-moz-border-top-left-radius:3px;-ms-border-top-left-radius:3px;-o-border-top-left-radius:3px;border-top-left-radius:3px;-webkit-border-top-right-radius:3px;-moz-border-top-right-radius:3px;-ms-border-top-right-radius:3px;-o-border-top-right-radius:3px;border-top-right-radius:3px;background:#f6f6f6;-webkit-transition:all 300ms ease-out;-moz-transition:all 300ms ease-out;transition:all 300ms ease-out}.editormd-tab-head li a:hover{color:#666;background:#eee}.editormd-tab-head li.active a{color:#666;background:#fff;border-bottom-color:#fff}.editormd-tab-head li+li{margin-left:3px}.editormd-tab-box{padding:20px 0}.editormd-form{color:#666}.editormd-form label{float:left;display:block;width:75px;text-align:left;padding:7px 0 15px 5px;margin:0 0 2px;font-weight:400}.editormd-form iframe{display:none}.editormd-form input:focus{outline:0}.editormd-form input[type=text],.editormd-form input[type=number]{color:#999;padding:8px;border:1px solid #ddd}.editormd-form input[type=number]{width:40px;display:inline-block;padding:6px 8px}.editormd-form input[type=text]{display:inline-block;width:264px}.editormd-form .fa-btns{display:inline-block}.editormd-form .fa-btns a{color:#999;padding:7px 10px 0 0;display:inline-block;text-decoration:none;text-align:center}.editormd-form .fa-btns .fa{font-size:1.3em}.editormd-form .fa-btns label{float:none;display:inline-block;width:auto;text-align:left;padding:0 0 0 5px;cursor:pointer}.fa-fw,.fa-li{text-align:center}.editormd-dialog-container .editormd-btn,.editormd-dialog-container button,.editormd-dialog-container input[type=submit],.editormd-dialog-footer .editormd-btn,.editormd-dialog-footer button,.editormd-dialog-footer input[type=submit],.editormd-form .editormd-btn,.editormd-form button,.editormd-form input[type=submit]{color:#666;min-width:75px;cursor:pointer;background:#fff;padding:7px 10px;border:1px solid #ddd;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px;-webkit-transition:background 300ms ease-out;-moz-transition:background 300ms ease-out;transition:background 300ms ease-out}.editormd-dialog-container .editormd-btn:hover,.editormd-dialog-container button:hover,.editormd-dialog-container input[type=submit]:hover,.editormd-dialog-footer .editormd-btn:hover,.editormd-dialog-footer button:hover,.editormd-dialog-footer input[type=submit]:hover,.editormd-form .editormd-btn:hover,.editormd-form button:hover,.editormd-form input[type=submit]:hover{background:#eee}.editormd-dialog-container .editormd-btn+.editormd-btn,.editormd-dialog-footer .editormd-btn+.editormd-btn,.editormd-form .editormd-btn+.editormd-btn{margin-left:8px}.editormd-file-input{width:75px;height:32px;margin-left:8px;position:relative;display:inline-block}.editormd-file-input input[type=file]{width:75px;height:32px;opacity:0;cursor:pointer;background:#000;display:inline-block;position:absolute;top:0;right:0}.editormd-file-input input[type=file]::-webkit-file-upload-button{visibility:hidden}.editormd-file-input:hover input[type=submit]{background:#eee}.editormd .CodeMirror,.editormd-preview{display:inline-block;width:50%;height:100%;vertical-align:top;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;margin:0}.editormd-preview{position:absolute;top:35px;right:0;overflow:auto;line-height:1.6;display:none;background:#fff}.fa,.fa-stack{display:inline-block}.editormd .CodeMirror{z-index:10;float:left;border-right:1px solid #ddd;font-size:14px;font-family:"YaHei Consolas Hybrid",Consolas,"微软雅黑","Meiryo UI","Malgun Gothic","Segoe UI","Trebuchet MS",Helvetica,Monaco,courier,monospace;line-height:1.6;margin-top:35px}.editormd .CodeMirror pre{font-size:14px;padding:0 12px}.editormd .CodeMirror-linenumbers{padding:0 5px}.editormd .CodeMirror-focused .CodeMirror-selected,.editormd .CodeMirror-selected{background:#70B7FF}.editormd .CodeMirror,.editormd .CodeMirror-scroll,.editormd .editormd-preview{-webkit-overflow-scrolling:touch}.editormd .styled-background{background-color:#ff7}.editormd .CodeMirror-focused .cm-matchhighlight{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFklEQVQI12NgYGBgkKzc8x9CMDAwAAAmhwSbidEoSQAAAABJRU5ErkJggg==);background-position:bottom;background-repeat:repeat-x}.editormd .CodeMirror-empty.CodeMirror-focused{outline:0}.editormd .CodeMirror pre.CodeMirror-placeholder{color:#999}.editormd .cm-trailingspace{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAACCAYAAAB/qH1jAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QUXCToH00Y1UgAAACFJREFUCNdjPMDBUc/AwNDAAAFMTAwMDA0OP34wQgX/AQBYgwYEx4f9lQAAAABJRU5ErkJggg==);background-position:bottom left;background-repeat:repeat-x}.editormd .cm-tab{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=)right no-repeat}/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 *//*! +/*! Editor.md v1.7.17 | editormd.min.css | Open source online markdown editor. | MIT License | By: IBM Skills Network | https://github.com/ibm-skills-network/editor.md | 2024-03-27 */ +@charset "UTF-8";/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */.editormd{width:90%;height:640px;margin:0 auto;text-align:left;overflow:hidden;position:relative;margin-bottom:15px;border:1px solid #ddd;font-family:"Meiryo UI","Microsoft YaHei","Malgun Gothic","Segoe UI","Trebuchet MS",Helvetica,Monaco,monospace,Tahoma,STXihei,"华文细黑",STHeiti,"Helvetica Neue","Droid Sans","wenquanyi micro hei",FreeSans,Arimo,Arial,SimSun,"宋体",Heiti,"黑体",sans-serif}.editormd *,.editormd :after,.editormd :before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.editormd a{text-decoration:none}.editormd img{border:none;vertical-align:middle}.editormd .editormd-html-textarea,.editormd .editormd-markdown-textarea,.editormd>textarea{width:0;height:0;outline:0;resize:none}.editormd .editormd-html-textarea,.editormd .editormd-markdown-textarea{display:none}.editormd button,.editormd input[type=button],.editormd input[type=submit],.editormd input[type=text],.editormd select,.editormd textarea{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none}.editormd ::-webkit-scrollbar{height:10px;width:7px;background:rgba(0,0,0,.1)}.editormd ::-webkit-scrollbar:hover{background:rgba(0,0,0,.2)}.editormd ::-webkit-scrollbar-thumb{background:rgba(0,0,0,.3);-webkit-border-radius:6px;-moz-border-radius:6px;-ms-border-radius:6px;-o-border-radius:6px;border-radius:6px}.editormd ::-webkit-scrollbar-thumb:hover{-webkit-box-shadow:inset 1px 1px 1px rgba(0,0,0,.25);-moz-box-shadow:inset 1px 1px 1px rgba(0,0,0,.25);-ms-box-shadow:inset 1px 1px 1px rgba(0,0,0,.25);-o-box-shadow:inset 1px 1px 1px rgba(0,0,0,.25);box-shadow:inset 1px 1px 1px rgba(0,0,0,.25);background-color:rgba(0,0,0,.4)}.editormd-user-unselect{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.editormd-toolbar{width:100%;min-height:37px;background:#fff;display:none;position:absolute;top:0;left:0;z-index:10;border-bottom:1px solid #ddd}.editormd-toolbar-container{padding:0 8px;min-height:35px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.editormd-menu{margin:0;padding:0;list-style:none}.editormd-menu>li{margin:0;padding:5px 1px;display:inline-block;position:relative}.editormd-menu>li.divider{display:inline-block;text-indent:-9999px;margin:0 5px;height:65%;border-right:1px solid #ddd}.editormd-menu>li>a{outline:0;color:#666;display:inline-block;min-width:24px;font-size:16px;text-decoration:none;text-align:center;-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;border:1px solid #fff;-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;transition:all .3s ease-out}.editormd-menu>li>a.active,.editormd-menu>li>a:hover{border:1px solid #ddd;background:#eee}.editormd-menu>li>a>.fa{text-align:center;display:block;padding:5px}.editormd-menu>li>a>.editormd-bold{padding:5px 2px;display:inline-block;font-weight:700}.editormd-menu>li:hover .editormd-dropdown-menu{display:block}.editormd-menu>li+li>a{margin-left:3px}.editormd-dropdown-menu{display:none;background:#fff;border:1px solid #ddd;width:148px;list-style:none;position:absolute;top:33px;left:0;z-index:100;-webkit-box-shadow:1px 2px 6px rgba(0,0,0,.15);-moz-box-shadow:1px 2px 6px rgba(0,0,0,.15);-ms-box-shadow:1px 2px 6px rgba(0,0,0,.15);-o-box-shadow:1px 2px 6px rgba(0,0,0,.15);box-shadow:1px 2px 6px rgba(0,0,0,.15)}.editormd-dropdown-menu:after,.editormd-dropdown-menu:before{width:0;height:0;display:block;content:"";position:absolute;top:-11px;left:8px;border:5px solid transparent}.editormd-dropdown-menu:before{border-bottom-color:#ccc}.editormd-dropdown-menu:after{border-bottom-color:#fff;top:-10px}.editormd-dropdown-menu>li>a{color:#666;display:block;text-decoration:none;padding:8px 10px}.editormd-dropdown-menu>li>a:hover{background:#f6f6f6;-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;transition:all .3s ease-out}.editormd-dropdown-menu>li+li{border-top:1px solid #ddd}.editormd-container{margin:0;width:100%;height:100%;overflow:hidden;padding:35px 0 0;position:relative;background:#fff;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.editormd-dialog{color:#666;position:fixed;z-index:99999;display:none;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 0 10px rgba(0,0,0,.3);-moz-box-shadow:0 0 10px rgba(0,0,0,.3);-ms-box-shadow:0 0 10px rgba(0,0,0,.3);-o-box-shadow:0 0 10px rgba(0,0,0,.3);box-shadow:0 0 10px rgba(0,0,0,.3);background:#fff;font-size:14px}.editormd-dialog-container{position:relative;padding:20px;line-height:1.4}.editormd-dialog-container h1{font-size:24px;margin-bottom:10px}.editormd-dialog-container h1 .fa{color:#2c7eea;padding-right:5px}.editormd-dialog-container h1 small{padding-left:5px;font-weight:400;font-size:12px;color:#999}.editormd-dialog-container select{color:#999;padding:3px 8px;border:1px solid #ddd}.editormd-dialog-close{position:absolute;top:12px;right:15px;font-size:18px;color:#ccc;-webkit-transition:color .3s ease-out;-moz-transition:color .3s ease-out;transition:color .3s ease-out}.editormd-dialog-close:hover{color:#999}.editormd-dialog-header{padding:11px 20px;border-bottom:1px solid #eee;-webkit-transition:background .3s ease-out;-moz-transition:background .3s ease-out;transition:background .3s ease-out}.editormd-dialog-header:hover{background:#f6f6f6}.editormd-dialog-title{font-size:14px}.editormd-dialog-footer{padding:10px 0 0 0;text-align:right}.editormd-dialog-info{width:420px}.editormd-dialog-info h1{font-weight:400}.editormd-dialog-info .editormd-dialog-container{padding:20px 25px 25px}.editormd-dialog-info .editormd-dialog-close{top:10px;right:10px}.editormd-dialog-info .hover-link:hover,.editormd-dialog-info p>a{color:#2196f3}.editormd-dialog-info .hover-link{color:#666}.editormd-dialog-info a .fa-external-link{display:none}.editormd-dialog-info a:hover{color:#2196f3}.editormd-dialog-info a:hover .fa-external-link{display:inline-block}.editormd-container-mask,.editormd-dialog-mask,.editormd-mask{display:none;width:100%;height:100%;position:absolute;top:0;left:0}.editormd-dialog-mask-bg,.editormd-mask{background:#fff;opacity:.5;filter:alpha(opacity=50)}.editormd-mask{position:fixed;background:#000;opacity:.2;filter:alpha(opacity=20);z-index:99998}.editormd-container-mask,.editormd-dialog-mask-con{background:url(../images/loading.gif) no-repeat center center;-webkit-background-size:32px 32px;-moz-background-size:32px 32px;-o-background-size:32px 32px;background-size:32px 32px}.editormd-container-mask{z-index:20;display:block;background-color:#fff}@media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min-device-pixel-ratio:2){.editormd-container-mask,.editormd-dialog-mask-con{background-image:url(../images/loading@2x.gif)}}@media only screen and (-webkit-min-device-pixel-ratio:3),only screen and (min-device-pixel-ratio:3){.editormd-container-mask,.editormd-dialog-mask-con{background-image:url(../images/loading@3x.gif)}}.editormd-code-block-dialog textarea,.editormd-preformatted-text-dialog textarea{width:100%;height:400px;margin-bottom:6px;overflow:auto;border:1px solid #eee;background:#fff;padding:15px;resize:none}.editormd-code-toolbar{color:#999;font-size:14px;margin:-5px 0 10px}.editormd-grid-table{width:99%;display:table;border:1px solid #ddd;border-collapse:collapse}.editormd-grid-table-row{width:100%;display:table-row}.editormd-grid-table-row a{font-size:1.4em;width:5%;height:36px;color:#999;text-align:center;display:table-cell;vertical-align:middle;border:1px solid #ddd;text-decoration:none;-webkit-transition:background-color .3s ease-out,color .1s ease-in;-moz-transition:background-color .3s ease-out,color .1s ease-in;transition:background-color .3s ease-out,color .1s ease-in}.editormd-grid-table-row a.selected{color:#666;background-color:#eee}.editormd-grid-table-row a:hover{color:#777;background-color:#f6f6f6}.editormd-tab-head{list-style:none;border-bottom:1px solid #ddd}.editormd-tab-head li{display:inline-block}.editormd-tab-head li a{color:#999;display:block;padding:6px 12px 5px;text-align:center;text-decoration:none;margin-bottom:-1px;border:1px solid #ddd;-webkit-border-top-left-radius:3px;-moz-border-top-left-radius:3px;-ms-border-top-left-radius:3px;-o-border-top-left-radius:3px;border-top-left-radius:3px;-webkit-border-top-right-radius:3px;-moz-border-top-right-radius:3px;-ms-border-top-right-radius:3px;-o-border-top-right-radius:3px;border-top-right-radius:3px;background:#f6f6f6;-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;transition:all .3s ease-out}.editormd-tab-head li a:hover{color:#666;background:#eee}.editormd-tab-head li.active a{color:#666;background:#fff;border-bottom-color:#fff}.editormd-tab-head li+li{margin-left:3px}.editormd-tab-box{padding:20px 0}.editormd-form{color:#666}.editormd-form label{float:left;display:block;width:75px;text-align:left;padding:7px 0 15px 5px;margin:0 0 2px;font-weight:400}.editormd-form br{clear:both}.editormd-form iframe{display:none}.editormd-form input:focus{outline:0}.editormd-form input[type=number],.editormd-form input[type=text]{color:#999;padding:8px;border:1px solid #ddd}.editormd-form input[type=number]{width:40px;display:inline-block;padding:6px 8px}.editormd-form input[type=text]{display:inline-block;width:264px}.editormd-form .fa-btns{display:inline-block}.editormd-form .fa-btns a{color:#999;padding:7px 10px 0 0;display:inline-block;text-decoration:none;text-align:center}.editormd-form .fa-btns .fa{font-size:1.3em}.editormd-form .fa-btns label{float:none;display:inline-block;width:auto;text-align:left;padding:0 0 0 5px;cursor:pointer}.editormd-dialog-container .editormd-btn,.editormd-dialog-container button,.editormd-dialog-container input[type=submit],.editormd-dialog-footer .editormd-btn,.editormd-dialog-footer button,.editormd-dialog-footer input[type=submit],.editormd-form .editormd-btn,.editormd-form button,.editormd-form input[type=submit]{color:#666;min-width:75px;cursor:pointer;background:#fff;padding:7px 10px;border:1px solid #ddd;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px;-webkit-transition:background .3s ease-out;-moz-transition:background .3s ease-out;transition:background .3s ease-out}.editormd-dialog-container .editormd-btn:hover,.editormd-dialog-container button:hover,.editormd-dialog-container input[type=submit]:hover,.editormd-dialog-footer .editormd-btn:hover,.editormd-dialog-footer button:hover,.editormd-dialog-footer input[type=submit]:hover,.editormd-form .editormd-btn:hover,.editormd-form button:hover,.editormd-form input[type=submit]:hover{background:#eee}.editormd-dialog-container .editormd-btn,.editormd-dialog-footer .editormd-btn,.editormd-form .editormd-btn{padding:5px 8px 4px\0}.editormd-dialog-container .editormd-btn+.editormd-btn,.editormd-dialog-footer .editormd-btn+.editormd-btn,.editormd-form .editormd-btn+.editormd-btn{margin-left:8px}.editormd-file-input{width:75px;height:32px;margin-left:8px;position:relative;display:inline-block}.editormd-file-input input[type=file]{width:75px;height:32px;opacity:0;cursor:pointer;background:#000;display:inline-block;position:absolute;top:0;right:0}.editormd-file-input input[type=file]::-webkit-file-upload-button{visibility:hidden}.editormd-file-input:hover input[type=submit]{background:#eee}.editormd .CodeMirror,.editormd-preview{display:inline-block;width:50%;height:100%;vertical-align:top;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;margin:0}.editormd-preview{position:absolute;top:35px;right:0;right:-1px\0;overflow:auto;line-height:1.6;display:none;background:#fff;z-index:10}.editormd .CodeMirror{z-index:10;float:left;border-right:1px solid #ddd;font-size:14px;font-family:"YaHei Consolas Hybrid",Consolas,"微软雅黑","Meiryo UI","Malgun Gothic","Segoe UI","Trebuchet MS",Helvetica,Monaco,courier,monospace;line-height:1.6;margin-top:35px}.editormd .CodeMirror pre{font-size:14px;padding:0 12px}.editormd .CodeMirror-linenumbers{padding:0 5px}.editormd .CodeMirror-selected{background:#70b7ff}.editormd .CodeMirror-focused .CodeMirror-selected{background:#70b7ff}.editormd .CodeMirror,.editormd .CodeMirror-scroll,.editormd .editormd-preview{-webkit-overflow-scrolling:touch}.editormd .styled-background{background-color:#ff7}.editormd .CodeMirror-focused .cm-matchhighlight{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFklEQVQI12NgYGBgkKzc8x9CMDAwAAAmhwSbidEoSQAAAABJRU5ErkJggg==);background-position:bottom;background-repeat:repeat-x}.editormd .CodeMirror-empty.CodeMirror-focused{outline:0}.editormd .CodeMirror pre.CodeMirror-placeholder{color:#999}.editormd .cm-trailingspace{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAACCAYAAAB/qH1jAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QUXCToH00Y1UgAAACFJREFUCNdjPMDBUc/AwNDAAAFMTAwMDA0OP34wQgX/AQBYgwYEx4f9lQAAAABJRU5ErkJggg==);background-position:bottom left;background-repeat:repeat-x}.editormd .cm-tab{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);background-position:right;background-repeat:no-repeat}/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 *//*! * Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:FontAwesome;src:url(../fonts/fontawesome-webfont.eot?v=4.3.0);src:url(../fonts/fontawesome-webfont.eot?#iefix&v=4.3.0)format("embedded-opentype"),url(../fonts/fontawesome-webfont.woff2?v=4.3.0)format("woff2"),url(../fonts/fontawesome-webfont.woff?v=4.3.0)format("woff"),url(../fonts/fontawesome-webfont.ttf?v=4.3.0)format("truetype"),url(../fonts/fontawesome-webfont.svg?v=4.3.0#fontawesomeregular)format("svg");font-weight:400;font-style:normal}.fa{font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transform:translate(0,0)}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em}.fa-ul{padding-left:0;margin-left:2.14285714em}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{filter:none}.fa-stack{position:relative;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-close:before,.fa-remove:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-cog:before,.fa-gear:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-repeat:before,.fa-rotate-right:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-exclamation-triangle:before,.fa-warning:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-cogs:before,.fa-gears:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-floppy-o:before,.fa-save:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-sort:before,.fa-unsorted:before{content:"\f0dc"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-sort-asc:before,.fa-sort-up:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-gavel:before,.fa-legal:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-bolt:before,.fa-flash:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-chain-broken:before,.fa-unlink:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:"\f150"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:"\f151"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:"\f152"}.fa-eur:before,.fa-euro:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-inr:before,.fa-rupee:before{content:"\f156"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:"\f157"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:"\f158"}.fa-krw:before,.fa-won:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-try:before,.fa-turkish-lira:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:"\f19c"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:"\f1c5"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:"\f1c6"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-empire:before,.fa-ge:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-paper-plane:before,.fa-send:before{content:"\f1d8"}.fa-paper-plane-o:before,.fa-send-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before,.fa-genderless:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-bed:before,.fa-hotel:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */@font-face{font-family:editormd-logo;src:url(../fonts/editormd-logo.eot?-5y8q6h);src:url(.../fonts/editormd-logo.eot?#iefix-5y8q6h)format("embedded-opentype"),url(../fonts/editormd-logo.woff?-5y8q6h)format("woff"),url(../fonts/editormd-logo.ttf?-5y8q6h)format("truetype"),url(../fonts/editormd-logo.svg?-5y8q6h#icomoon)format("svg");font-weight:400;font-style:normal}.editormd-logo,.editormd-logo-1x,.editormd-logo-2x,.editormd-logo-3x,.editormd-logo-4x,.editormd-logo-5x,.editormd-logo-6x,.editormd-logo-7x,.editormd-logo-8x{font-family:editormd-logo;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;font-size:inherit;line-height:1;display:inline-block;text-rendering:auto;vertical-align:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.markdown-body hr:after,.markdown-body hr:before{content:"";display:table}.editormd-logo-1x:before,.editormd-logo-2x:before,.editormd-logo-3x:before,.editormd-logo-4x:before,.editormd-logo-5x:before,.editormd-logo-6x:before,.editormd-logo-7x:before,.editormd-logo-8x:before,.editormd-logo:before{content:"\e1987"}.editormd-logo-1x{font-size:1em}.editormd-logo-lg{font-size:1.2em}.editormd-logo-2x{font-size:2em}.editormd-logo-3x{font-size:3em}.editormd-logo-4x{font-size:4em}.editormd-logo-5x{font-size:5em}.editormd-logo-6x{font-size:6em}.editormd-logo-7x{font-size:7em}.editormd-logo-8x{font-size:8em}.editormd-logo-color{color:#2196F3}/*! github-markdown-css | The MIT License (MIT) | Copyright (c) Sindre Sorhus (sindresorhus.com) | https://github.com/sindresorhus/github-markdown-css */@font-face{font-family:octicons-anchor;src:url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAYcAA0AAAAACjQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABMAAAABwAAAAca8vGTk9TLzIAAAFMAAAARAAAAFZG1VHVY21hcAAAAZAAAAA+AAABQgAP9AdjdnQgAAAB0AAAAAQAAAAEACICiGdhc3AAAAHUAAAACAAAAAj//wADZ2x5ZgAAAdwAAADRAAABEKyikaNoZWFkAAACsAAAAC0AAAA2AtXoA2hoZWEAAALgAAAAHAAAACQHngNFaG10eAAAAvwAAAAQAAAAEAwAACJsb2NhAAADDAAAAAoAAAAKALIAVG1heHAAAAMYAAAAHwAAACABEAB2bmFtZQAAAzgAAALBAAAFu3I9x/Nwb3N0AAAF/AAAAB0AAAAvaoFvbwAAAAEAAAAAzBdyYwAAAADP2IQvAAAAAM/bz7t4nGNgZGFgnMDAysDB1Ml0hoGBoR9CM75mMGLkYGBgYmBlZsAKAtJcUxgcPsR8iGF2+O/AEMPsznAYKMwIkgMA5REMOXicY2BgYGaAYBkGRgYQsAHyGMF8FgYFIM0ChED+h5j//yEk/3KoSgZGNgYYk4GRCUgwMaACRoZhDwCs7QgGAAAAIgKIAAAAAf//AAJ4nHWMMQrCQBBF/0zWrCCIKUQsTDCL2EXMohYGSSmorScInsRGL2DOYJe0Ntp7BK+gJ1BxF1stZvjz/v8DRghQzEc4kIgKwiAppcA9LtzKLSkdNhKFY3HF4lK69ExKslx7Xa+vPRVS43G98vG1DnkDMIBUgFN0MDXflU8tbaZOUkXUH0+U27RoRpOIyCKjbMCVejwypzJJG4jIwb43rfl6wbwanocrJm9XFYfskuVC5K/TPyczNU7b84CXcbxks1Un6H6tLH9vf2LRnn8Ax7A5WQAAAHicY2BkYGAA4teL1+yI57f5ysDNwgAC529f0kOmWRiYVgEpDgYmEA8AUzEKsQAAAHicY2BkYGB2+O/AEMPCAAJAkpEBFbAAADgKAe0EAAAiAAAAAAQAAAAEAAAAAAAAKgAqACoAiAAAeJxjYGRgYGBhsGFgYgABEMkFhAwM/xn0QAIAD6YBhwB4nI1Ty07cMBS9QwKlQapQW3VXySvEqDCZGbGaHULiIQ1FKgjWMxknMfLEke2A+IJu+wntrt/QbVf9gG75jK577Lg8K1qQPCfnnnt8fX1NRC/pmjrk/zprC+8D7tBy9DHgBXoWfQ44Av8t4Bj4Z8CLtBL9CniJluPXASf0Lm4CXqFX8Q84dOLnMB17N4c7tBo1AS/Qi+hTwBH4rwHHwN8DXqQ30XXAS7QaLwSc0Gn8NuAVWou/gFmnjLrEaEh9GmDdDGgL3B4JsrRPDU2hTOiMSuJUIdKQQayiAth69r6akSSFqIJuA19TrzCIaY8sIoxyrNIrL//pw7A2iMygkX5vDj+G+kuoLdX4GlGK/8Lnlz6/h9MpmoO9rafrz7ILXEHHaAx95s9lsI7AHNMBWEZHULnfAXwG9/ZqdzLI08iuwRloXE8kfhXYAvE23+23DU3t626rbs8/8adv+9DWknsHp3E17oCf+Z48rvEQNZ78paYM38qfk3v/u3l3u3GXN2Dmvmvpf1Srwk3pB/VSsp512bA/GG5i2WJ7wu430yQ5K3nFGiOqgtmSB5pJVSizwaacmUZzZhXLlZTq8qGGFY2YcSkqbth6aW1tRmlaCFs2016m5qn36SbJrqosG4uMV4aP2PHBmB3tjtmgN2izkGQyLWprekbIntJFing32a5rKWCN/SdSoga45EJykyQ7asZvHQ8PTm6cslIpwyeyjbVltNikc2HTR7YKh9LBl9DADC0U/jLcBZDKrMhUBfQBvXRzLtFtjU9eNHKin0x5InTqb8lNpfKv1s1xHzTXRqgKzek/mb7nB8RZTCDhGEX3kK/8Q75AmUM/eLkfA+0Hi908Kx4eNsMgudg5GLdRD7a84npi+YxNr5i5KIbW5izXas7cHXIMAau1OueZhfj+cOcP3P8MNIWLyYOBuxL6DRylJ4cAAAB4nGNgYoAALjDJyIAOWMCiTIxMLDmZedkABtIBygAAAA==)format("woff")}.markdown-body{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;color:#333;overflow:hidden;font-family:"Microsoft YaHei",Helvetica,"Meiryo UI","Malgun Gothic","Segoe UI","Trebuchet MS",Monaco,monospace,Tahoma,STXihei,"华文细黑",STHeiti,"Helvetica Neue","Droid Sans","wenquanyi micro hei",FreeSans,Arimo,Arial,SimSun,"宋体",Heiti,"黑体",sans-serif;font-size:16px;line-height:1.6;word-wrap:break-word}.markdown-body strong{font-weight:700}.markdown-body h1{margin:.67em 0}.markdown-body img{border:0}.markdown-body hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}.markdown-body input{color:inherit;margin:0;line-height:normal;font:13px/1.4 Helvetica,arial,freesans,clean,sans-serif,"Segoe UI Emoji","Segoe UI Symbol"}.markdown-body html input[disabled]{cursor:default}.markdown-body input[type=checkbox]{-moz-box-sizing:border-box;box-sizing:border-box;padding:0}.markdown-body *{-moz-box-sizing:border-box;box-sizing:border-box}.markdown-body a{background:0 0;color:#4183c4;text-decoration:none}.markdown-body a:active,.markdown-body a:hover{outline:0;text-decoration:underline}.markdown-body hr{margin:15px 0;overflow:hidden;background:0 0;border:0;border-bottom:1px solid #ddd}.markdown-body h1,.markdown-body h2{padding-bottom:.3em;border-bottom:1px solid #eee}.markdown-body blockquote{margin:0}.markdown-body ol ol,.markdown-body ul ol{list-style-type:lower-roman}.markdown-body ol ol ol,.markdown-body ol ul ol,.markdown-body ul ol ol,.markdown-body ul ul ol{list-style-type:lower-alpha}.markdown-body dd{margin-left:0}.markdown-body code{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace}.markdown-body pre{font:12px Consolas,"Liberation Mono",Menlo,Courier,monospace;word-wrap:normal}.markdown-body .octicon{font:normal normal 16px octicons-anchor;line-height:1;display:inline-block;text-decoration:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;user-select:none}.markdown-body .octicon-link:before{content:'\f05c'}.markdown-body>:first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdown-body .anchor{position:absolute;top:0;left:0;display:block;padding-right:6px;padding-left:30px;margin-left:-30px}.markdown-body .anchor:focus{outline:0}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{position:relative;margin-top:1em;margin-bottom:16px;font-weight:700;line-height:1.4}.markdown-body h1 .octicon-link,.markdown-body h2 .octicon-link,.markdown-body h3 .octicon-link,.markdown-body h4 .octicon-link,.markdown-body h5 .octicon-link,.markdown-body h6 .octicon-link{display:none;color:#000;vertical-align:middle}.markdown-body h1:hover .anchor,.markdown-body h2:hover .anchor,.markdown-body h3:hover .anchor,.markdown-body h4:hover .anchor,.markdown-body h5:hover .anchor,.markdown-body h6:hover .anchor{padding-left:8px;margin-left:-30px;text-decoration:none}.markdown-body h1:hover .anchor .octicon-link,.markdown-body h2:hover .anchor .octicon-link,.markdown-body h3:hover .anchor .octicon-link,.markdown-body h4:hover .anchor .octicon-link,.markdown-body h5:hover .anchor .octicon-link,.markdown-body h6:hover .anchor .octicon-link{display:inline-block}.markdown-body h1{font-size:2.25em;line-height:1.2}.markdown-body h1 .anchor{line-height:1}.markdown-body h2{font-size:1.75em;line-height:1.225}.markdown-body h2 .anchor{line-height:1}.markdown-body h3{font-size:1.5em;line-height:1.43}.markdown-body h3 .anchor,.markdown-body h4 .anchor{line-height:1.2}.markdown-body h4{font-size:1.25em}.markdown-body h5 .anchor,.markdown-body h6 .anchor{line-height:1.1}.markdown-body h5{font-size:1em}.markdown-body h6{font-size:1em;color:#777}.markdown-body blockquote,.markdown-body dl,.markdown-body ol,.markdown-body p,.markdown-body pre,.markdown-body table,.markdown-body ul{margin-top:0;margin-bottom:16px}.markdown-body ol,.markdown-body ul{padding-left:2em}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:0;margin-bottom:0}.markdown-body li>p{margin-top:16px}.markdown-body dl{padding:0}.markdown-body dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:700}.markdown-body dl dd{padding:0 16px;margin-bottom:16px}.markdown-body blockquote{padding:0 15px;color:#777;border-left:4px solid #ddd}.markdown-body blockquote>:first-child{margin-top:0}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body table{border-collapse:collapse;border-spacing:0;display:block;width:100%;overflow:auto;word-break:normal;word-break:keep-all}.markdown-body table th{font-weight:700}.markdown-body table td,.markdown-body table th{padding:6px 13px;border:1px solid #ddd}.markdown-body table tr{background-color:#fff;border-top:1px solid #ccc}.markdown-body table tr:nth-child(2n){background-color:#f8f8f8}.markdown-body img{max-width:100%;-moz-box-sizing:border-box;box-sizing:border-box}.markdown-body code{padding:.2em 0;margin:0;font-size:85%;background-color:rgba(0,0,0,.04);border-radius:3px}.markdown-body code:after,.markdown-body code:before{letter-spacing:-.2em;content:"\00a0"}.markdown-body pre>code{padding:0;margin:0;font-size:100%;word-break:normal;white-space:pre;background:0 0;border:0}.markdown-body .highlight{margin-bottom:16px}.markdown-body .highlight pre,.markdown-body pre{padding:16px;overflow:auto;font-size:85%;background-color:#f7f7f7;border-radius:3px}.markdown-body .highlight pre{margin-bottom:0;word-break:normal}.markdown-body pre code{display:inline;max-width:initial;padding:0;margin:0;overflow:initial;line-height:inherit;word-wrap:normal;background-color:transparent;border:0}.markdown-body pre code:after,.markdown-body pre code:before{content:normal}.markdown-body .pl-c{color:#969896}.markdown-body .pl-c1,.markdown-body .pl-mdh,.markdown-body .pl-mm,.markdown-body .pl-mp,.markdown-body .pl-mr,.markdown-body .pl-s1 .pl-v,.markdown-body .pl-s3,.markdown-body .pl-sc,.markdown-body .pl-sv{color:#0086b3}.markdown-body .pl-e,.markdown-body .pl-en{color:#795da3}.markdown-body .pl-s1 .pl-s2,.markdown-body .pl-smi,.markdown-body .pl-smp,.markdown-body .pl-stj,.markdown-body .pl-vo,.markdown-body .pl-vpf{color:#333}.markdown-body .pl-ent{color:#63a35c}.markdown-body .pl-k,.markdown-body .pl-s,.markdown-body .pl-st{color:#a71d5d}.markdown-body .pl-pds,.markdown-body .pl-s1,.markdown-body .pl-s1 .pl-pse .pl-s2,.markdown-body .pl-sr,.markdown-body .pl-sr .pl-cce,.markdown-body .pl-sr .pl-sra,.markdown-body .pl-sr .pl-sre,.markdown-body .pl-src{color:#df5000}.markdown-body .pl-mo,.markdown-body .pl-v{color:#1d3e81}.markdown-body .pl-id{color:#b52a1d}.markdown-body .pl-ii{background-color:#b52a1d;color:#f8f8f8}.markdown-body .pl-sr .pl-cce{color:#63a35c;font-weight:700}.markdown-body .pl-ml{color:#693a17}.markdown-body .pl-mh,.markdown-body .pl-mh .pl-en,.markdown-body .pl-ms{color:#1d3e81;font-weight:700}.markdown-body .pl-mq{color:teal}.markdown-body .pl-mi{color:#333;font-style:italic}.markdown-body .pl-mb{color:#333;font-weight:700}.markdown-body .pl-md,.markdown-body .pl-mdhf{background-color:#ffecec;color:#bd2c00}.markdown-body .pl-mdht,.markdown-body .pl-mi1{background-color:#eaffea;color:#55a532}.markdown-body .pl-mdr{color:#795da3;font-weight:700}.markdown-body kbd{display:inline-block;padding:3px 5px;font:11px Consolas,"Liberation Mono",Menlo,Courier,monospace;line-height:10px;color:#555;vertical-align:middle;background-color:#fcfcfc;border:1px solid #ccc;border-bottom-color:#bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb}.markdown-body .task-list-item+.task-list-item{margin-top:3px}.markdown-body .task-list-item input{float:left;margin:.3em 0 .25em -1.6em;vertical-align:middle}.markdown-body :checked+.radio-label{z-index:1;position:relative;border-color:#4183c4}.editormd-html-preview,.editormd-preview-container{text-align:left;font-size:14px;line-height:1.6;padding:20px;overflow:auto;width:100%;background-color:#fff}.editormd-html-preview blockquote,.editormd-preview-container blockquote{color:#666;border-left:4px solid #ddd;padding-left:20px;margin-left:0;font-size:14px;font-style:italic}.editormd-html-preview p code,.editormd-preview-container p code{margin-left:5px;margin-right:4px}.editormd-html-preview abbr,.editormd-preview-container abbr{background:#ffd}.editormd-html-preview hr,.editormd-preview-container hr{height:1px;border:none;border-top:1px solid #ddd;background:0 0}.editormd-html-preview code,.editormd-preview-container code{border:1px solid #ddd;background:#f6f6f6;padding:3px;border-radius:3px;font-size:14px}.editormd-html-preview pre,.editormd-preview-container pre{border:1px solid #ddd;background:#f6f6f6;padding:10px;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px}.editormd-html-preview pre code,.editormd-preview-container pre code{padding:0}.editormd-html-preview code,.editormd-html-preview kbd,.editormd-html-preview pre,.editormd-preview-container code,.editormd-preview-container kbd,.editormd-preview-container pre{font-family:"YaHei Consolas Hybrid",Consolas,"Meiryo UI","Malgun Gothic","Segoe UI","Trebuchet MS",Helvetica,monospace,monospace}.editormd-html-preview table thead tr,.editormd-preview-container table thead tr{background-color:#F8F8F8}.editormd-html-preview p.editormd-tex,.editormd-preview-container p.editormd-tex{text-align:center}.editormd-html-preview span.editormd-tex,.editormd-preview-container span.editormd-tex{margin:0 5px}.editormd-html-preview .emoji,.editormd-preview-container .emoji{width:24px;height:24px}.editormd-html-preview .katex,.editormd-preview-container .katex{font-size:1.4em}.editormd-html-preview .flowchart,.editormd-html-preview .sequence-diagram,.editormd-preview-container .flowchart,.editormd-preview-container .sequence-diagram{margin:0 auto;text-align:center}.editormd-html-preview .flowchart svg,.editormd-html-preview .sequence-diagram svg,.editormd-preview-container .flowchart svg,.editormd-preview-container .sequence-diagram svg{margin:0 auto}.editormd-html-preview .flowchart text,.editormd-html-preview .sequence-diagram text,.editormd-preview-container .flowchart text,.editormd-preview-container .sequence-diagram text{font-size:15px!important;font-family:"YaHei Consolas Hybrid",Consolas,"Microsoft YaHei","Malgun Gothic","Segoe UI",Helvetica,Arial!important}/*! Pretty printing styles. Used with prettify.js. */.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.clo,.opn,.pun{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.kwd,.tag,.typ{font-weight:700}.str{color:#060}.kwd{color:#006}.com{color:#600;font-style:italic}.typ{color:#404}.lit{color:#044}.clo,.opn,.pun{color:#440}.tag{color:#006}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}.editormd-html-preview pre.prettyprint,.editormd-preview-container pre.prettyprint{padding:10px;border:1px solid #ddd;white-space:pre-wrap;word-wrap:break-word}.editormd-html-preview ol.linenums,.editormd-preview-container ol.linenums{color:#999;padding-left:2.5em}.editormd-html-preview ol.linenums li,.editormd-preview-container ol.linenums li{list-style-type:decimal}.editormd-html-preview ol.linenums li code,.editormd-preview-container ol.linenums li code{border:none;background:0 0;padding:0}.editormd-html-preview .editormd-toc-menu,.editormd-preview-container .editormd-toc-menu{margin:8px 0 12px;display:inline-block}.editormd-html-preview .editormd-toc-menu>.markdown-toc,.editormd-preview-container .editormd-toc-menu>.markdown-toc{position:relative;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;-o-border-radius:4px;border-radius:4px;border:1px solid #ddd;display:inline-block;font-size:1em}.editormd-html-preview .editormd-toc-menu>.markdown-toc>ul,.editormd-preview-container .editormd-toc-menu>.markdown-toc>ul{width:160%;min-width:180px;position:absolute;left:-1px;top:-2px;z-index:100;padding:0 10px 10px;display:none;background:#fff;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;-o-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 3px 5px rgba(0,0,0,.2);-moz-box-shadow:0 3px 5px rgba(0,0,0,.2);-ms-box-shadow:0 3px 5px rgba(0,0,0,.2);-o-box-shadow:0 3px 5px rgba(0,0,0,.2);box-shadow:0 3px 5px rgba(0,0,0,.2)}.editormd-html-preview .editormd-toc-menu>.markdown-toc>ul>li ul,.editormd-preview-container .editormd-toc-menu>.markdown-toc>ul>li ul{width:100%;min-width:180px;border:1px solid #ddd;display:none;background:#fff;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;-o-border-radius:4px;border-radius:4px}.editormd-html-preview .editormd-toc-menu .toc-menu-btn:hover,.editormd-html-preview .editormd-toc-menu>.markdown-toc>ul>li a:hover,.editormd-preview-container .editormd-toc-menu .toc-menu-btn:hover,.editormd-preview-container .editormd-toc-menu>.markdown-toc>ul>li a:hover{background-color:#f6f6f6}.editormd-html-preview .editormd-toc-menu>.markdown-toc>ul>li a,.editormd-preview-container .editormd-toc-menu>.markdown-toc>ul>li a{color:#666;padding:6px 10px;display:block;-webkit-transition:background-color 500ms ease-out;-moz-transition:background-color 500ms ease-out;transition:background-color 500ms ease-out}.editormd-html-preview .editormd-toc-menu>.markdown-toc li,.editormd-preview-container .editormd-toc-menu>.markdown-toc li{position:relative}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul{position:absolute;top:32px;left:10%;display:none;-webkit-box-shadow:0 3px 5px rgba(0,0,0,.2);-moz-box-shadow:0 3px 5px rgba(0,0,0,.2);-ms-box-shadow:0 3px 5px rgba(0,0,0,.2);-o-box-shadow:0 3px 5px rgba(0,0,0,.2);box-shadow:0 3px 5px rgba(0,0,0,.2)}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:after,.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:before,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:after,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:before{pointer-events:pointer-events;position:absolute;left:15px;top:-6px;display:block;content:"";width:0;height:0;border:6px solid transparent;border-width:0 6px 6px;z-index:10}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:before,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:before{border-bottom-color:#ccc}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:after,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:after{border-bottom-color:#fff;top:-5px}.editormd-html-preview .editormd-toc-menu ul,.editormd-preview-container .editormd-toc-menu ul{list-style:none}.editormd-html-preview .editormd-toc-menu a,.editormd-preview-container .editormd-toc-menu a{text-decoration:none}.editormd-html-preview .editormd-toc-menu h1,.editormd-preview-container .editormd-toc-menu h1{font-size:16px;padding:5px 0 10px 10px;line-height:1;border-bottom:1px solid #eee}.editormd-html-preview .editormd-toc-menu h1 .fa,.editormd-preview-container .editormd-toc-menu h1 .fa{padding-left:10px}.editormd-html-preview .editormd-toc-menu .toc-menu-btn,.editormd-preview-container .editormd-toc-menu .toc-menu-btn{color:#666;min-width:180px;padding:5px 10px;border-radius:4px;display:inline-block;-webkit-transition:background-color 500ms ease-out;-moz-transition:background-color 500ms ease-out;transition:background-color 500ms ease-out}.editormd-html-preview textarea,.editormd-onlyread .editormd-toolbar{display:none}.editormd-html-preview .editormd-toc-menu .toc-menu-btn .fa,.editormd-preview-container .editormd-toc-menu .toc-menu-btn .fa{float:right;padding:3px 0 0 10px;font-size:1.3em}.markdown-body .editormd-toc-menu ul{padding-left:0}.markdown-body .highlight pre,.markdown-body pre{line-height:1.6}hr.editormd-page-break{border:1px dotted #ccc;font-size:0;height:2px}@media only print{hr.editormd-page-break{background:0 0;border:none;height:0}}.editormd-html-preview hr.editormd-page-break{background:0 0;border:none;height:0}.editormd-preview-close-btn{color:#fff;padding:4px 6px;font-size:18px;-webkit-border-radius:500px;-moz-border-radius:500px;-ms-border-radius:500px;-o-border-radius:500px;border-radius:500px;display:none;background-color:#ccc;position:absolute;top:25px;right:35px;z-index:19;-webkit-transition:background-color 300ms ease-out;-moz-transition:background-color 300ms ease-out;transition:background-color 300ms ease-out}.editormd-preview-close-btn:hover{background-color:#999}.editormd-preview-active{width:100%;padding:40px}.editormd-preview-theme-dark{color:#777;background:#2C2827}.editormd-preview-theme-dark .editormd-preview-container{color:#888;background-color:#2C2827}.editormd-preview-theme-dark .editormd-preview-container pre.prettyprint{border:none}.editormd-preview-theme-dark .editormd-preview-container blockquote{color:#555;padding:.5em;background:#222;border-color:#333}.editormd-preview-theme-dark .editormd-preview-container abbr{color:#fff;padding:1px 3px;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px;background:#f90}.editormd-preview-theme-dark .editormd-preview-container code{color:#fff;border:none;padding:1px 3px;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px;background:#5A9600}.editormd-preview-theme-dark .editormd-preview-container table{border:none}.editormd-preview-theme-dark .editormd-preview-container .fa-emoji{color:#B4BF42}.editormd-preview-theme-dark .editormd-preview-container .katex{color:#FEC93F}.editormd-preview-theme-dark .editormd-toc-menu>.markdown-toc{background:#fff;border:none}.editormd-preview-theme-dark .editormd-toc-menu>.markdown-toc h1{border-color:#ddd}.editormd-preview-theme-dark .markdown-body h1,.editormd-preview-theme-dark .markdown-body h2,.editormd-preview-theme-dark .markdown-body hr{border-color:#222}.editormd-preview-theme-dark pre{color:#999;background-color:#111;background-color:rgba(0,0,0,.4)}.editormd-preview-theme-dark pre .pln{color:#999}.editormd-preview-theme-dark li.L1,.editormd-preview-theme-dark li.L3,.editormd-preview-theme-dark li.L5,.editormd-preview-theme-dark li.L7,.editormd-preview-theme-dark li.L9{background:0 0}.editormd-preview-theme-dark [class*=editormd-logo]{color:#2196F3}.editormd-preview-theme-dark .sequence-diagram text{fill:#fff}.editormd-preview-theme-dark .sequence-diagram path,.editormd-preview-theme-dark .sequence-diagram rect{color:#fff;fill:#64D1CB;stroke:#64D1CB}.editormd-preview-theme-dark .flowchart path,.editormd-preview-theme-dark .flowchart rect{stroke:#A6C6FF}.editormd-preview-theme-dark .flowchart rect{fill:#A6C6FF}.editormd-preview-theme-dark .flowchart text{fill:#5879B4}@media screen{.editormd-preview-theme-dark .str{color:#080}.editormd-preview-theme-dark .kwd{color:#f90}.editormd-preview-theme-dark .com{color:#444}.editormd-preview-theme-dark .typ{color:#606}.editormd-preview-theme-dark .lit{color:#066}.editormd-preview-theme-dark .clo,.editormd-preview-theme-dark .opn,.editormd-preview-theme-dark .pun{color:#660}.editormd-preview-theme-dark .tag{color:#f90}.editormd-preview-theme-dark .atn{color:#6C95F5}.editormd-preview-theme-dark .atv{color:#080}.editormd-preview-theme-dark .dec,.editormd-preview-theme-dark .var{color:#008BA7}.editormd-preview-theme-dark .fun{color:red}}.editormd-onlyread .CodeMirror{margin-top:0}.editormd-onlyread .editormd-preview{top:0}.editormd-fullscreen{position:fixed;top:0;left:0;border:none;margin:0 auto}.editormd-theme-dark{border-color:#1a1a17}.editormd-theme-dark .editormd-toolbar{background:#1A1A17;border-color:#1a1a17}.editormd-theme-dark .editormd-menu>li>a{color:#777;border-color:#1a1a17}.editormd-theme-dark .editormd-menu>li>a.active,.editormd-theme-dark .editormd-menu>li>a:hover{border-color:#333;background:#333}.editormd-theme-dark .editormd-menu>li.divider{border-right:1px solid #111}.editormd-theme-dark .CodeMirror{border-right:1px solid rgba(0,0,0,.1)} \ No newline at end of file + */@font-face{font-family:FontAwesome;src:url(../fonts/fontawesome-webfont.eot?v=4.3.0);src:url(../fonts/fontawesome-webfont.eot?#iefix&v=4.3.0) format("embedded-opentype"),url(../fonts/fontawesome-webfont.woff2?v=4.3.0) format("woff2"),url(../fonts/fontawesome-webfont.woff?v=4.3.0) format("woff"),url(../fonts/fontawesome-webfont.ttf?v=4.3.0) format("truetype"),url(../fonts/fontawesome-webfont.svg?v=4.3.0#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transform:translate(0,0)}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-close:before,.fa-remove:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-cog:before,.fa-gear:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-repeat:before,.fa-rotate-right:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-exclamation-triangle:before,.fa-warning:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-cogs:before,.fa-gears:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-floppy-o:before,.fa-save:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-sort:before,.fa-unsorted:before{content:"\f0dc"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-sort-asc:before,.fa-sort-up:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-gavel:before,.fa-legal:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-bolt:before,.fa-flash:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-chain-broken:before,.fa-unlink:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:"\f150"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:"\f151"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:"\f152"}.fa-eur:before,.fa-euro:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-inr:before,.fa-rupee:before{content:"\f156"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:"\f157"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:"\f158"}.fa-krw:before,.fa-won:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-try:before,.fa-turkish-lira:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:"\f19c"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:"\f1c5"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:"\f1c6"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-empire:before,.fa-ge:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-paper-plane:before,.fa-send:before{content:"\f1d8"}.fa-paper-plane-o:before,.fa-send-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before,.fa-genderless:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-bed:before,.fa-hotel:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */@font-face{font-family:editormd-logo;src:url(../fonts/editormd-logo.eot?-5y8q6h);src:url(../fonts/editormd-logo.eot?#iefix-5y8q6h) format("embedded-opentype"),url(../fonts/editormd-logo.woff?-5y8q6h) format("woff"),url(../fonts/editormd-logo.ttf?-5y8q6h) format("truetype"),url(../fonts/editormd-logo.svg?-5y8q6h#icomoon) format("svg");font-weight:400;font-style:normal}.editormd-logo,.editormd-logo-1x,.editormd-logo-2x,.editormd-logo-3x,.editormd-logo-4x,.editormd-logo-5x,.editormd-logo-6x,.editormd-logo-7x,.editormd-logo-8x{font-family:editormd-logo;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;font-size:inherit;line-height:1;display:inline-block;text-rendering:auto;vertical-align:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.editormd-logo-1x:before,.editormd-logo-2x:before,.editormd-logo-3x:before,.editormd-logo-4x:before,.editormd-logo-5x:before,.editormd-logo-6x:before,.editormd-logo-7x:before,.editormd-logo-8x:before,.editormd-logo:before{content:"󡦇"}.editormd-logo-1x{font-size:1em}.editormd-logo-lg{font-size:1.2em}.editormd-logo-2x{font-size:2em}.editormd-logo-3x{font-size:3em}.editormd-logo-4x{font-size:4em}.editormd-logo-5x{font-size:5em}.editormd-logo-6x{font-size:6em}.editormd-logo-7x{font-size:7em}.editormd-logo-8x{font-size:8em}.editormd-logo-color{color:#2196f3}/*! github-markdown-css | The MIT License (MIT) | Copyright (c) Sindre Sorhus (sindresorhus.com) | https://github.com/sindresorhus/github-markdown-css */@font-face{font-family:octicons-anchor;src:url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAYcAA0AAAAACjQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABMAAAABwAAAAca8vGTk9TLzIAAAFMAAAARAAAAFZG1VHVY21hcAAAAZAAAAA+AAABQgAP9AdjdnQgAAAB0AAAAAQAAAAEACICiGdhc3AAAAHUAAAACAAAAAj//wADZ2x5ZgAAAdwAAADRAAABEKyikaNoZWFkAAACsAAAAC0AAAA2AtXoA2hoZWEAAALgAAAAHAAAACQHngNFaG10eAAAAvwAAAAQAAAAEAwAACJsb2NhAAADDAAAAAoAAAAKALIAVG1heHAAAAMYAAAAHwAAACABEAB2bmFtZQAAAzgAAALBAAAFu3I9x/Nwb3N0AAAF/AAAAB0AAAAvaoFvbwAAAAEAAAAAzBdyYwAAAADP2IQvAAAAAM/bz7t4nGNgZGFgnMDAysDB1Ml0hoGBoR9CM75mMGLkYGBgYmBlZsAKAtJcUxgcPsR8iGF2+O/AEMPsznAYKMwIkgMA5REMOXicY2BgYGaAYBkGRgYQsAHyGMF8FgYFIM0ChED+h5j//yEk/3KoSgZGNgYYk4GRCUgwMaACRoZhDwCs7QgGAAAAIgKIAAAAAf//AAJ4nHWMMQrCQBBF/0zWrCCIKUQsTDCL2EXMohYGSSmorScInsRGL2DOYJe0Ntp7BK+gJ1BxF1stZvjz/v8DRghQzEc4kIgKwiAppcA9LtzKLSkdNhKFY3HF4lK69ExKslx7Xa+vPRVS43G98vG1DnkDMIBUgFN0MDXflU8tbaZOUkXUH0+U27RoRpOIyCKjbMCVejwypzJJG4jIwb43rfl6wbwanocrJm9XFYfskuVC5K/TPyczNU7b84CXcbxks1Un6H6tLH9vf2LRnn8Ax7A5WQAAAHicY2BkYGAA4teL1+yI57f5ysDNwgAC529f0kOmWRiYVgEpDgYmEA8AUzEKsQAAAHicY2BkYGB2+O/AEMPCAAJAkpEBFbAAADgKAe0EAAAiAAAAAAQAAAAEAAAAAAAAKgAqACoAiAAAeJxjYGRgYGBhsGFgYgABEMkFhAwM/xn0QAIAD6YBhwB4nI1Ty07cMBS9QwKlQapQW3VXySvEqDCZGbGaHULiIQ1FKgjWMxknMfLEke2A+IJu+wntrt/QbVf9gG75jK577Lg8K1qQPCfnnnt8fX1NRC/pmjrk/zprC+8D7tBy9DHgBXoWfQ44Av8t4Bj4Z8CLtBL9CniJluPXASf0Lm4CXqFX8Q84dOLnMB17N4c7tBo1AS/Qi+hTwBH4rwHHwN8DXqQ30XXAS7QaLwSc0Gn8NuAVWou/gFmnjLrEaEh9GmDdDGgL3B4JsrRPDU2hTOiMSuJUIdKQQayiAth69r6akSSFqIJuA19TrzCIaY8sIoxyrNIrL//pw7A2iMygkX5vDj+G+kuoLdX4GlGK/8Lnlz6/h9MpmoO9rafrz7ILXEHHaAx95s9lsI7AHNMBWEZHULnfAXwG9/ZqdzLI08iuwRloXE8kfhXYAvE23+23DU3t626rbs8/8adv+9DWknsHp3E17oCf+Z48rvEQNZ78paYM38qfk3v/u3l3u3GXN2Dmvmvpf1Srwk3pB/VSsp512bA/GG5i2WJ7wu430yQ5K3nFGiOqgtmSB5pJVSizwaacmUZzZhXLlZTq8qGGFY2YcSkqbth6aW1tRmlaCFs2016m5qn36SbJrqosG4uMV4aP2PHBmB3tjtmgN2izkGQyLWprekbIntJFing32a5rKWCN/SdSoga45EJykyQ7asZvHQ8PTm6cslIpwyeyjbVltNikc2HTR7YKh9LBl9DADC0U/jLcBZDKrMhUBfQBvXRzLtFtjU9eNHKin0x5InTqb8lNpfKv1s1xHzTXRqgKzek/mb7nB8RZTCDhGEX3kK/8Q75AmUM/eLkfA+0Hi908Kx4eNsMgudg5GLdRD7a84npi+YxNr5i5KIbW5izXas7cHXIMAau1OueZhfj+cOcP3P8MNIWLyYOBuxL6DRylJ4cAAAB4nGNgYoAALjDJyIAOWMCiTIxMLDmZedkABtIBygAAAA==) format("woff")}.markdown-body{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;color:#333;overflow:hidden;font-family:"Microsoft YaHei",Helvetica,"Meiryo UI","Malgun Gothic","Segoe UI","Trebuchet MS",Monaco,monospace,Tahoma,STXihei,"华文细黑",STHeiti,"Helvetica Neue","Droid Sans","wenquanyi micro hei",FreeSans,Arimo,Arial,SimSun,"宋体",Heiti,"黑体",sans-serif;font-size:16px;line-height:1.6;word-wrap:break-word}.markdown-body a{background:0 0}.markdown-body a:active,.markdown-body a:hover{outline:0}.markdown-body strong{font-weight:700}.markdown-body h1{font-size:2em;margin:.67em 0}.markdown-body img{border:0}.markdown-body hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}.markdown-body pre{overflow:auto}.markdown-body code,.markdown-body kbd,.markdown-body pre{font-family:"Meiryo UI","YaHei Consolas Hybrid",Consolas,"Malgun Gothic","Segoe UI","Trebuchet MS",Helvetica,monospace,monospace;font-size:1em}.markdown-body input{color:inherit;font:inherit;margin:0}.markdown-body html input[disabled]{cursor:default}.markdown-body input{line-height:normal}.markdown-body input[type=checkbox]{-moz-box-sizing:border-box;box-sizing:border-box;padding:0}.markdown-body table{border-collapse:collapse;border-spacing:0}.markdown-body td,.markdown-body th{padding:0}.markdown-body *{-moz-box-sizing:border-box;box-sizing:border-box}.markdown-body input{font:13px/1.4 Helvetica,arial,freesans,clean,sans-serif,"Segoe UI Emoji","Segoe UI Symbol"}.markdown-body a{color:#4183c4;text-decoration:none}.markdown-body a:active,.markdown-body a:hover{text-decoration:underline}.markdown-body hr{height:0;margin:15px 0;overflow:hidden;background:0 0;border:0;border-bottom:1px solid #ddd}.markdown-body hr:before{display:table;content:""}.markdown-body hr:after{display:table;clear:both;content:""}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{margin-top:15px;margin-bottom:15px;line-height:1.1}.markdown-body h1{font-size:30px}.markdown-body h2{font-size:21px}.markdown-body h3{font-size:16px}.markdown-body h4{font-size:14px}.markdown-body h5{font-size:12px}.markdown-body h6{font-size:11px}.markdown-body blockquote{margin:0}.markdown-body ol,.markdown-body ul{padding:0;margin-top:0;margin-bottom:0}.markdown-body ol ol,.markdown-body ul ol{list-style-type:lower-roman}.markdown-body ol ol ol,.markdown-body ol ul ol,.markdown-body ul ol ol,.markdown-body ul ul ol{list-style-type:lower-alpha}.markdown-body dd{margin-left:0}.markdown-body code{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px}.markdown-body pre{margin-top:0;margin-bottom:0;font:12px Consolas,"Liberation Mono",Menlo,Courier,monospace}.markdown-body .octicon{font:normal normal 16px octicons-anchor;line-height:1;display:inline-block;text-decoration:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.markdown-body .octicon-link:before{content:"\f05c"}.markdown-body>:first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdown-body .anchor{position:absolute;top:0;left:0;display:block;padding-right:6px;padding-left:30px;margin-left:-30px}.markdown-body .anchor:focus{outline:0}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{position:relative;margin-top:1em;margin-bottom:16px;font-weight:700;line-height:1.4}.markdown-body h1 .octicon-link,.markdown-body h2 .octicon-link,.markdown-body h3 .octicon-link,.markdown-body h4 .octicon-link,.markdown-body h5 .octicon-link,.markdown-body h6 .octicon-link{display:none;color:#000;vertical-align:middle}.markdown-body h1:hover .anchor,.markdown-body h2:hover .anchor,.markdown-body h3:hover .anchor,.markdown-body h4:hover .anchor,.markdown-body h5:hover .anchor,.markdown-body h6:hover .anchor{padding-left:8px;margin-left:-30px;text-decoration:none}.markdown-body h1:hover .anchor .octicon-link,.markdown-body h2:hover .anchor .octicon-link,.markdown-body h3:hover .anchor .octicon-link,.markdown-body h4:hover .anchor .octicon-link,.markdown-body h5:hover .anchor .octicon-link,.markdown-body h6:hover .anchor .octicon-link{display:inline-block}.markdown-body h1{padding-bottom:.3em;font-size:2.25em;line-height:1.2;border-bottom:1px solid #eee}.markdown-body h1 .anchor{line-height:1}.markdown-body h2{padding-bottom:.3em;font-size:1.75em;line-height:1.225;border-bottom:1px solid #eee}.markdown-body h2 .anchor{line-height:1}.markdown-body h3{font-size:1.5em;line-height:1.43}.markdown-body h3 .anchor{line-height:1.2}.markdown-body h4{font-size:1.25em}.markdown-body h4 .anchor{line-height:1.2}.markdown-body h5{font-size:1em}.markdown-body h5 .anchor{line-height:1.1}.markdown-body h6{font-size:1em;color:#777}.markdown-body h6 .anchor{line-height:1.1}.markdown-body blockquote,.markdown-body dl,.markdown-body ol,.markdown-body p,.markdown-body pre,.markdown-body table,.markdown-body ul{margin-top:0;margin-bottom:16px}.markdown-body ol,.markdown-body ul{padding-left:2em}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:0;margin-bottom:0}.markdown-body li>p{margin-top:16px}.markdown-body dl{padding:0}.markdown-body dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:700}.markdown-body dl dd{padding:0 16px;margin-bottom:16px}.markdown-body blockquote{padding:0 15px;color:#777;border-left:4px solid #ddd}.markdown-body blockquote>:first-child{margin-top:0}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body table{display:block;width:100%;overflow:auto;word-break:normal;word-break:keep-all}.markdown-body table th{font-weight:700}.markdown-body table td,.markdown-body table th{padding:6px 13px;border:1px solid #ddd}.markdown-body table tr{background-color:#fff;border-top:1px solid #ccc}.markdown-body table tr:nth-child(2n){background-color:#f8f8f8}.markdown-body img{max-width:100%;-moz-box-sizing:border-box;box-sizing:border-box}.markdown-body code{padding:0;padding-top:.2em;padding-bottom:.2em;margin:0;font-size:85%;background-color:rgba(0,0,0,.04);border-radius:3px}.markdown-body code:after,.markdown-body code:before{letter-spacing:-.2em;content:" "}.markdown-body pre>code{padding:0;margin:0;font-size:100%;word-break:normal;white-space:pre;background:0 0;border:0}.markdown-body .highlight{margin-bottom:16px}.markdown-body .highlight pre,.markdown-body pre{padding:16px;overflow:auto;font-size:85%;line-height:1.45;background-color:#f7f7f7;border-radius:3px}.markdown-body .highlight pre{margin-bottom:0;word-break:normal}.markdown-body pre{word-wrap:normal}.markdown-body pre code{display:inline;max-width:initial;padding:0;margin:0;overflow:initial;line-height:inherit;word-wrap:normal;background-color:transparent;border:0}.markdown-body pre code:after,.markdown-body pre code:before{content:normal}.markdown-body kbd{display:inline-block;padding:3px 5px;font-size:11px;line-height:10px;color:#555;vertical-align:middle;background-color:#fcfcfc;border:solid 1px #ccc;border-bottom-color:#bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb}.markdown-body .pl-c{color:#969896}.markdown-body .pl-c1,.markdown-body .pl-mdh,.markdown-body .pl-mm,.markdown-body .pl-mp,.markdown-body .pl-mr,.markdown-body .pl-s1 .pl-v,.markdown-body .pl-s3,.markdown-body .pl-sc,.markdown-body .pl-sv{color:#0086b3}.markdown-body .pl-e,.markdown-body .pl-en{color:#795da3}.markdown-body .pl-s1 .pl-s2,.markdown-body .pl-smi,.markdown-body .pl-smp,.markdown-body .pl-stj,.markdown-body .pl-vo,.markdown-body .pl-vpf{color:#333}.markdown-body .pl-ent{color:#63a35c}.markdown-body .pl-k,.markdown-body .pl-s,.markdown-body .pl-st{color:#a71d5d}.markdown-body .pl-pds,.markdown-body .pl-s1,.markdown-body .pl-s1 .pl-pse .pl-s2,.markdown-body .pl-sr,.markdown-body .pl-sr .pl-cce,.markdown-body .pl-sr .pl-sra,.markdown-body .pl-sr .pl-sre,.markdown-body .pl-src{color:#df5000}.markdown-body .pl-mo,.markdown-body .pl-v{color:#1d3e81}.markdown-body .pl-id{color:#b52a1d}.markdown-body .pl-ii{background-color:#b52a1d;color:#f8f8f8}.markdown-body .pl-sr .pl-cce{color:#63a35c;font-weight:700}.markdown-body .pl-ml{color:#693a17}.markdown-body .pl-mh,.markdown-body .pl-mh .pl-en,.markdown-body .pl-ms{color:#1d3e81;font-weight:700}.markdown-body .pl-mq{color:teal}.markdown-body .pl-mi{color:#333;font-style:italic}.markdown-body .pl-mb{color:#333;font-weight:700}.markdown-body .pl-md,.markdown-body .pl-mdhf{background-color:#ffecec;color:#bd2c00}.markdown-body .pl-mdht,.markdown-body .pl-mi1{background-color:#eaffea;color:#55a532}.markdown-body .pl-mdr{color:#795da3;font-weight:700}.markdown-body kbd{display:inline-block;padding:3px 5px;font:11px Consolas,"Liberation Mono",Menlo,Courier,monospace;line-height:10px;color:#555;vertical-align:middle;background-color:#fcfcfc;border:solid 1px #ccc;border-bottom-color:#bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb}.markdown-body .task-list-item{list-style-type:none}.markdown-body .task-list-item+.task-list-item{margin-top:3px}.markdown-body .task-list-item input{float:left;margin:.3em 0 .25em -1.6em;vertical-align:middle}.markdown-body :checked+.radio-label{z-index:1;position:relative;border-color:#4183c4}.editormd-html-preview,.editormd-preview-container{text-align:left;font-size:14px;line-height:1.6;padding:20px;overflow:auto;width:100%;background-color:#fff}.editormd-html-preview blockquote,.editormd-preview-container blockquote{color:#666;border-left:4px solid #ddd;padding-left:20px;margin-left:0;font-size:14px;font-style:italic}.editormd-html-preview p code,.editormd-preview-container p code{margin-left:5px;margin-right:4px}.editormd-html-preview abbr,.editormd-preview-container abbr{background:#ffd}.editormd-html-preview hr,.editormd-preview-container hr{height:1px;border:none;border-top:1px solid #ddd;background:0 0}.editormd-html-preview code,.editormd-preview-container code{border:1px solid #ddd;background:#f6f6f6;padding:3px;border-radius:3px;font-size:14px}.editormd-html-preview pre,.editormd-preview-container pre{border:1px solid #ddd;background:#f6f6f6;padding:10px;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px}.editormd-html-preview pre code,.editormd-preview-container pre code{padding:0}.editormd-html-preview code,.editormd-html-preview kbd,.editormd-html-preview pre,.editormd-preview-container code,.editormd-preview-container kbd,.editormd-preview-container pre{font-family:"YaHei Consolas Hybrid",Consolas,"Meiryo UI","Malgun Gothic","Segoe UI","Trebuchet MS",Helvetica,monospace,monospace}.editormd-html-preview table thead tr,.editormd-preview-container table thead tr{background-color:#f8f8f8}.editormd-html-preview p.editormd-tex,.editormd-preview-container p.editormd-tex{text-align:center}.editormd-html-preview span.editormd-tex,.editormd-preview-container span.editormd-tex{margin:0 5px}.editormd-html-preview .emoji,.editormd-preview-container .emoji{width:24px;height:24px}.editormd-html-preview .katex,.editormd-preview-container .katex{font-size:1.4em}.editormd-html-preview .flowchart,.editormd-html-preview .sequence-diagram,.editormd-preview-container .flowchart,.editormd-preview-container .sequence-diagram{margin:0 auto;text-align:center}.editormd-html-preview .flowchart svg,.editormd-html-preview .sequence-diagram svg,.editormd-preview-container .flowchart svg,.editormd-preview-container .sequence-diagram svg{margin:0 auto}.editormd-html-preview .flowchart text,.editormd-html-preview .sequence-diagram text,.editormd-preview-container .flowchart text,.editormd-preview-container .sequence-diagram text{font-size:15px!important;font-family:"YaHei Consolas Hybrid",Consolas,"Microsoft YaHei","Malgun Gothic","Segoe UI",Helvetica,Arial!important}/*! Pretty printing styles. Used with prettify.js. */.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.clo,.opn,.pun{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:700}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:700}.lit{color:#044}.clo,.opn,.pun{color:#440}.tag{color:#006;font-weight:700}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}.editormd-html-preview pre.prettyprint,.editormd-preview-container pre.prettyprint{padding:10px;border:1px solid #ddd;white-space:pre-wrap;word-wrap:break-word}.editormd-html-preview ol.linenums,.editormd-preview-container ol.linenums{color:#999;padding-left:2.5em}.editormd-html-preview ol.linenums li,.editormd-preview-container ol.linenums li{list-style-type:decimal}.editormd-html-preview ol.linenums li code,.editormd-preview-container ol.linenums li code{border:none;background:0 0;padding:0}.editormd-html-preview .editormd-toc-menu,.editormd-preview-container .editormd-toc-menu{margin:8px 0 12px 0;display:inline-block}.editormd-html-preview .editormd-toc-menu>.markdown-toc,.editormd-preview-container .editormd-toc-menu>.markdown-toc{position:relative;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;-o-border-radius:4px;border-radius:4px;border:1px solid #ddd;display:inline-block;font-size:1em}.editormd-html-preview .editormd-toc-menu>.markdown-toc>ul,.editormd-preview-container .editormd-toc-menu>.markdown-toc>ul{width:160%;min-width:180px;position:absolute;left:-1px;top:-2px;z-index:100;padding:0 10px 10px;display:none;background:#fff;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;-o-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 3px 5px rgba(0,0,0,.2);-moz-box-shadow:0 3px 5px rgba(0,0,0,.2);-ms-box-shadow:0 3px 5px rgba(0,0,0,.2);-o-box-shadow:0 3px 5px rgba(0,0,0,.2);box-shadow:0 3px 5px rgba(0,0,0,.2)}.editormd-html-preview .editormd-toc-menu>.markdown-toc>ul>li ul,.editormd-preview-container .editormd-toc-menu>.markdown-toc>ul>li ul{width:100%;min-width:180px;border:1px solid #ddd;display:none;background:#fff;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;-o-border-radius:4px;border-radius:4px}.editormd-html-preview .editormd-toc-menu>.markdown-toc>ul>li a,.editormd-preview-container .editormd-toc-menu>.markdown-toc>ul>li a{color:#666;padding:6px 10px;display:block;-webkit-transition:background-color .5s ease-out;-moz-transition:background-color .5s ease-out;transition:background-color .5s ease-out}.editormd-html-preview .editormd-toc-menu>.markdown-toc>ul>li a:hover,.editormd-preview-container .editormd-toc-menu>.markdown-toc>ul>li a:hover{background-color:#f6f6f6}.editormd-html-preview .editormd-toc-menu>.markdown-toc li,.editormd-preview-container .editormd-toc-menu>.markdown-toc li{position:relative}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul{position:absolute;top:32px;left:10%;display:none;-webkit-box-shadow:0 3px 5px rgba(0,0,0,.2);-moz-box-shadow:0 3px 5px rgba(0,0,0,.2);-ms-box-shadow:0 3px 5px rgba(0,0,0,.2);-o-box-shadow:0 3px 5px rgba(0,0,0,.2);box-shadow:0 3px 5px rgba(0,0,0,.2)}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:after,.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:before,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:after,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:before{pointer-events:pointer-events;position:absolute;left:15px;top:-6px;display:block;content:"";width:0;height:0;border:6px solid transparent;border-width:0 6px 6px;z-index:10}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:before,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:before{border-bottom-color:#ccc}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:after,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:after{border-bottom-color:#fff;top:-5px}.editormd-html-preview .editormd-toc-menu ul,.editormd-preview-container .editormd-toc-menu ul{list-style:none}.editormd-html-preview .editormd-toc-menu a,.editormd-preview-container .editormd-toc-menu a{text-decoration:none}.editormd-html-preview .editormd-toc-menu h1,.editormd-preview-container .editormd-toc-menu h1{font-size:16px;padding:5px 0 10px 10px;line-height:1;border-bottom:1px solid #eee}.editormd-html-preview .editormd-toc-menu h1 .fa,.editormd-preview-container .editormd-toc-menu h1 .fa{padding-left:10px}.editormd-html-preview .editormd-toc-menu .toc-menu-btn,.editormd-preview-container .editormd-toc-menu .toc-menu-btn{color:#666;min-width:180px;padding:5px 10px;border-radius:4px;display:inline-block;-webkit-transition:background-color .5s ease-out;-moz-transition:background-color .5s ease-out;transition:background-color .5s ease-out}.editormd-html-preview .editormd-toc-menu .toc-menu-btn:hover,.editormd-preview-container .editormd-toc-menu .toc-menu-btn:hover{background-color:#f6f6f6}.editormd-html-preview .editormd-toc-menu .toc-menu-btn .fa,.editormd-preview-container .editormd-toc-menu .toc-menu-btn .fa{float:right;padding:3px 0 0 10px;font-size:1.3em}.markdown-body .editormd-toc-menu ul{padding-left:0}.markdown-body .highlight pre,.markdown-body pre{line-height:1.6}hr.editormd-page-break{border:1px dotted #ccc;font-size:0;height:2px}@media only print{hr.editormd-page-break{background:0 0;border:none;height:0}}.editormd-html-preview textarea{display:none}.editormd-html-preview hr.editormd-page-break{background:0 0;border:none;height:0}.editormd-preview-close-btn{color:#fff;padding:4px 6px;font-size:18px;-webkit-border-radius:500px;-moz-border-radius:500px;-ms-border-radius:500px;-o-border-radius:500px;border-radius:500px;display:none;background-color:#ccc;position:absolute;top:25px;right:35px;z-index:19;-webkit-transition:background-color .3s ease-out;-moz-transition:background-color .3s ease-out;transition:background-color .3s ease-out}.editormd-preview-close-btn:hover{background-color:#999}.editormd-preview-active{width:100%;padding:40px}.editormd-preview-theme-dark{color:#777;background:#2c2827}.editormd-preview-theme-dark .editormd-preview-container{color:#888;background-color:#2c2827}.editormd-preview-theme-dark .editormd-preview-container pre.prettyprint{border:none}.editormd-preview-theme-dark .editormd-preview-container blockquote{color:#555;padding:.5em;background:#222;border-color:#333}.editormd-preview-theme-dark .editormd-preview-container abbr{color:#fff;padding:1px 3px;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px;background:#f90}.editormd-preview-theme-dark .editormd-preview-container code{color:#fff;border:none;padding:1px 3px;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px;background:#5a9600}.editormd-preview-theme-dark .editormd-preview-container table{border:none}.editormd-preview-theme-dark .editormd-preview-container .fa-emoji{color:#b4bf42}.editormd-preview-theme-dark .editormd-preview-container .katex{color:#fec93f}.editormd-preview-theme-dark .editormd-toc-menu>.markdown-toc{background:#fff;border:none}.editormd-preview-theme-dark .editormd-toc-menu>.markdown-toc h1{border-color:#ddd}.editormd-preview-theme-dark .markdown-body h1,.editormd-preview-theme-dark .markdown-body h2,.editormd-preview-theme-dark .markdown-body hr{border-color:#222}.editormd-preview-theme-dark pre{color:#999;background-color:#111;background-color:rgba(0,0,0,.4)}.editormd-preview-theme-dark pre .pln{color:#999}.editormd-preview-theme-dark li.L1,.editormd-preview-theme-dark li.L3,.editormd-preview-theme-dark li.L5,.editormd-preview-theme-dark li.L7,.editormd-preview-theme-dark li.L9{background:0 0}.editormd-preview-theme-dark [class*=editormd-logo]{color:#2196f3}.editormd-preview-theme-dark .sequence-diagram text{fill:#fff}.editormd-preview-theme-dark .sequence-diagram path,.editormd-preview-theme-dark .sequence-diagram rect{color:#fff;fill:#64d1cb;stroke:#64d1cb}.editormd-preview-theme-dark .flowchart path,.editormd-preview-theme-dark .flowchart rect{stroke:#a6c6ff}.editormd-preview-theme-dark .flowchart rect{fill:#a6c6ff}.editormd-preview-theme-dark .flowchart text{fill:#5879b4}@media screen{.editormd-preview-theme-dark .str{color:#080}.editormd-preview-theme-dark .kwd{color:#f90}.editormd-preview-theme-dark .com{color:#444}.editormd-preview-theme-dark .typ{color:#606}.editormd-preview-theme-dark .lit{color:#066}.editormd-preview-theme-dark .clo,.editormd-preview-theme-dark .opn,.editormd-preview-theme-dark .pun{color:#660}.editormd-preview-theme-dark .tag{color:#f90}.editormd-preview-theme-dark .atn{color:#6c95f5}.editormd-preview-theme-dark .atv{color:#080}.editormd-preview-theme-dark .dec,.editormd-preview-theme-dark .var{color:#008ba7}.editormd-preview-theme-dark .fun{color:red}}.editormd-onlyread .editormd-toolbar{display:none}.editormd-onlyread .CodeMirror{margin-top:0}.editormd-onlyread .editormd-preview{top:0}.editormd-fullscreen{position:fixed;top:0;left:0;border:none;margin:0 auto}.editormd-theme-dark{border-color:#1a1a17}.editormd-theme-dark .editormd-toolbar{background:#1a1a17;border-color:#1a1a17}.editormd-theme-dark .editormd-menu>li>a{color:#777;border-color:#1a1a17}.editormd-theme-dark .editormd-menu>li>a.active,.editormd-theme-dark .editormd-menu>li>a:hover{border-color:#333;background:#333}.editormd-theme-dark .editormd-menu>li.divider{border-right:1px solid #111}.editormd-theme-dark .CodeMirror{border-right:1px solid rgba(0,0,0,.1)} \ No newline at end of file diff --git a/static/editor.md/css/editormd.preview.css b/static/editor.md/css/editormd.preview.css index 438b6c6f..abcafbdb 100644 --- a/static/editor.md/css/editormd.preview.css +++ b/static/editor.md/css/editormd.preview.css @@ -2,12 +2,12 @@ * Editor.md * * @file editormd.preview.css - * @version v1.5.0 + * @version v1.7.17 * @description Open source online markdown editor. * @license MIT License - * @author Pandao - * {@link https://github.com/pandao/editor.md} - * @updateTime 2015-06-09 + * @author IBM Skills Network + * {@link https://github.com/ibm-skills-network/editor.md} + * @updateTime 2024-03-27 */ @charset "UTF-8"; @@ -19,7 +19,7 @@ /* FONT PATH * -------------------------- */ @font-face { - font-family: 'FontAwesome'; + font-family: "FontAwesome"; src: url("../fonts/fontawesome-webfont.eot?v=4.3.0"); src: url("../fonts/fontawesome-webfont.eot?#iefix&v=4.3.0") format("embedded-opentype"), url("../fonts/fontawesome-webfont.woff2?v=4.3.0") format("woff2"), url("../fonts/fontawesome-webfont.woff?v=4.3.0") format("woff"), url("../fonts/fontawesome-webfont.ttf?v=4.3.0") format("truetype"), url("../fonts/fontawesome-webfont.svg?v=4.3.0#fontawesomeregular") format("svg"); font-weight: normal; @@ -86,9 +86,9 @@ } .fa-border { - padding: .2em .25em .15em; + padding: 0.2em 0.25em 0.15em; border: solid 0.08em #eeeeee; - border-radius: .1em; + border-radius: 0.1em; } .pull-right { @@ -100,11 +100,11 @@ } .fa.pull-left { - margin-right: .3em; + margin-right: 0.3em; } .fa.pull-right { - margin-left: .3em; + margin-left: 0.3em; } .fa-spin { @@ -2363,9 +2363,9 @@ /*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */ @font-face { - font-family: 'editormd-logo'; + font-family: "editormd-logo"; src: url("../fonts/editormd-logo.eot?-5y8q6h"); - src: url(".../fonts/editormd-logo.eot?#iefix-5y8q6h") format("embedded-opentype"), url("../fonts/editormd-logo.woff?-5y8q6h") format("woff"), url("../fonts/editormd-logo.ttf?-5y8q6h") format("truetype"), url("../fonts/editormd-logo.svg?-5y8q6h#icomoon") format("svg"); + src: url("../fonts/editormd-logo.eot?#iefix-5y8q6h") format("embedded-opentype"), url("../fonts/editormd-logo.woff?-5y8q6h") format("woff"), url("../fonts/editormd-logo.ttf?-5y8q6h") format("truetype"), url("../fonts/editormd-logo.svg?-5y8q6h#icomoon") format("svg"); font-weight: normal; font-style: normal; } @@ -2378,7 +2378,7 @@ .editormd-logo-6x, .editormd-logo-7x, .editormd-logo-8x { - font-family: 'editormd-logo'; + font-family: "editormd-logo"; speak: none; font-style: normal; font-weight: normal; @@ -2517,7 +2517,7 @@ line-height: normal; } -.markdown-body input[type="checkbox"] { +.markdown-body input[type=checkbox] { -moz-box-sizing: border-box; box-sizing: border-box; padding: 0; @@ -2659,7 +2659,7 @@ } .markdown-body .octicon-link:before { - content: '\f05c'; + content: "\f05c"; } .markdown-body > *:first-child { @@ -2897,7 +2897,7 @@ .markdown-body code:before, .markdown-body code:after { letter-spacing: -0.2em; - content: "\00a0"; + content: " "; } .markdown-body pre > code { @@ -2920,6 +2920,7 @@ overflow: auto; font-size: 85%; line-height: 1.45; + background-color: #f7f7f7; border-radius: 3px; } @@ -2940,6 +2941,7 @@ overflow: initial; line-height: inherit; word-wrap: normal; + background-color: transparent; border: 0; } @@ -3111,17 +3113,19 @@ .editormd-preview-container, .editormd-html-preview { text-align: left; font-size: 14px; + line-height: 1.6; padding: 20px; + overflow: auto; width: 100%; - line-height: 1.6em; + background-color: #fff; } .editormd-preview-container blockquote, .editormd-html-preview blockquote { - color: #2C3E50; - border-left: 4px solid #D6DBDF; + color: #666; + border-left: 4px solid #ddd; + padding-left: 20px; + margin-left: 0; font-size: 14px; - background: none repeat scroll 0 0 rgba(102,128,153,.05); - margin: 8px 0; - padding: 8px 16px; + font-style: italic; } .editormd-preview-container p code, .editormd-html-preview p code { margin-left: 5px; @@ -3145,6 +3149,7 @@ } .editormd-preview-container pre, .editormd-html-preview pre { border: 1px solid #ddd; + background: #f6f6f6; padding: 10px; -webkit-border-radius: 3px; -moz-border-radius: 3px; @@ -3186,129 +3191,77 @@ font-family: "YaHei Consolas Hybrid", Consolas, "Microsoft YaHei", "Malgun Gothic", "Segoe UI", Helvetica, Arial !important; } -.editormd-preview-container blockquote.info, .editormd-html-preview blockquote.info { - border-left-color: #5bc0de; - color: #5bc0de; - background-color: #f4f8fa -} -.editormd-preview-container blockquote.warning, .editormd-html-preview blockquote.warning { - background-color: #fcf8f2; - border-color: #f0ad4e; - color: #f0ad4e -} -.editormd-preview-container blockquote.danger, .editormd-html-preview blockquote.danger { - color: #d9534f; - background-color: #fdf7f7; - border-color: #d9534f -} -.editormd-preview-container blockquote.success, .editormd-html-preview blockquote.success { - background-color: #f3f8f3; - border-color: #50af51; - color: #50af51 -} - /*! Pretty printing styles. Used with prettify.js. */ /* SPAN elements with the classes below are added by prettyprint. */ .pln { color: #000; -} - -/* plain text */ +} /* plain text */ @media screen { .str { color: #080; - } - - /* string content */ + } /* string content */ .kwd { color: #008; - } - - /* a keyword */ + } /* a keyword */ .com { color: #800; - } - - /* a comment */ + } /* a comment */ .typ { color: #606; - } - - /* a type name */ + } /* a type name */ .lit { color: #066; - } - - /* a literal value */ + } /* a literal value */ /* punctuation, lisp open bracket, lisp close bracket */ .pun, .opn, .clo { color: #660; } - .tag { color: #008; - } - - /* a markup tag name */ + } /* a markup tag name */ .atn { color: #606; - } - - /* a markup attribute name */ + } /* a markup attribute name */ .atv { color: #080; - } - - /* a markup attribute value */ + } /* a markup attribute value */ .dec, .var { color: #606; - } - - /* a declaration; a variable name */ + } /* a declaration; a variable name */ .fun { color: red; - } - - /* a function name */ + } /* a function name */ } /* Use higher contrast and text-weight for printable form. */ @media print, projection { .str { color: #060; } - .kwd { color: #006; font-weight: bold; } - .com { color: #600; font-style: italic; } - .typ { color: #404; font-weight: bold; } - .lit { color: #044; } - .pun, .opn, .clo { color: #440; } - .tag { color: #006; font-weight: bold; } - .atn { color: #404; } - .atv { color: #060; } @@ -3323,9 +3276,7 @@ pre.prettyprint { ol.linenums { margin-top: 0; margin-bottom: 0; -} - -/* IE indents via margin-left */ +} /* IE indents via margin-left */ li.L0, li.L1, li.L2, @@ -3396,16 +3347,11 @@ li.L9 { -ms-border-radius: 4px; -o-border-radius: 4px; border-radius: 4px; - -webkit-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); - /* Webkit browsers */ - -moz-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); - /* Firefox */ - -ms-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); - /* IE9 */ - -o-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); - /* Opera(Old) */ - box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); - /* IE9+, News */ + -webkit-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* Webkit browsers */ + -moz-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* Firefox */ + -ms-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* IE9 */ + -o-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* Opera(Old) */ + box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* IE9+, News */ } .editormd-preview-container .editormd-toc-menu > .markdown-toc > ul > li ul, .editormd-html-preview .editormd-toc-menu > .markdown-toc > ul > li ul { width: 100%; @@ -3423,12 +3369,9 @@ li.L9 { color: #666; padding: 6px 10px; display: block; - -webkit-transition: background-color 500ms ease-out; - /* Safari, Chrome */ - -moz-transition: background-color 500ms ease-out; - /* Firefox 4.0~16.0 */ - transition: background-color 500ms ease-out; - /* IE >9, FF >15, Opera >12.0 */ + -webkit-transition: background-color 500ms ease-out; /* Safari, Chrome */ + -moz-transition: background-color 500ms ease-out; /* Firefox 4.0~16.0 */ + transition: background-color 500ms ease-out; /* IE >9, FF >15, Opera >12.0 */ } .editormd-preview-container .editormd-toc-menu > .markdown-toc > ul > li a:hover, .editormd-html-preview .editormd-toc-menu > .markdown-toc > ul > li a:hover { background-color: #f6f6f6; @@ -3441,16 +3384,11 @@ li.L9 { top: 32px; left: 10%; display: none; - -webkit-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); - /* Webkit browsers */ - -moz-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); - /* Firefox */ - -ms-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); - /* IE9 */ - -o-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); - /* Opera(Old) */ - box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); - /* IE9+, News */ + -webkit-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* Webkit browsers */ + -moz-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* Firefox */ + -ms-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* IE9 */ + -o-box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* Opera(Old) */ + box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2); /* IE9+, News */ } .editormd-preview-container .editormd-toc-menu > .markdown-toc li > ul:before, .editormd-preview-container .editormd-toc-menu > .markdown-toc li > ul:after, .editormd-html-preview .editormd-toc-menu > .markdown-toc li > ul:before, .editormd-html-preview .editormd-toc-menu > .markdown-toc li > ul:after { pointer-events: pointer-events; @@ -3493,12 +3431,9 @@ li.L9 { padding: 5px 10px; border-radius: 4px; display: inline-block; - -webkit-transition: background-color 500ms ease-out; - /* Safari, Chrome */ - -moz-transition: background-color 500ms ease-out; - /* Firefox 4.0~16.0 */ - transition: background-color 500ms ease-out; - /* IE >9, FF >15, Opera >12.0 */ + -webkit-transition: background-color 500ms ease-out; /* Safari, Chrome */ + -moz-transition: background-color 500ms ease-out; /* Firefox 4.0~16.0 */ + transition: background-color 500ms ease-out; /* IE >9, FF >15, Opera >12.0 */ } .editormd-preview-container .editormd-toc-menu .toc-menu-btn:hover, .editormd-html-preview .editormd-toc-menu .toc-menu-btn:hover { background-color: #f6f6f6; @@ -3553,12 +3488,9 @@ hr.editormd-page-break { top: 25px; right: 35px; z-index: 19; - -webkit-transition: background-color 300ms ease-out; - /* Safari, Chrome */ - -moz-transition: background-color 300ms ease-out; - /* Firefox 4.0~16.0 */ - transition: background-color 300ms ease-out; - /* IE >9, FF >15, Opera >12.0 */ + -webkit-transition: background-color 300ms ease-out; /* Safari, Chrome */ + -moz-transition: background-color 300ms ease-out; /* Firefox 4.0~16.0 */ + transition: background-color 300ms ease-out; /* IE >9, FF >15, Opera >12.0 */ } .editormd-preview-close-btn:hover { background-color: #999; @@ -3567,4 +3499,4 @@ hr.editormd-page-break { .editormd-preview-active { width: 100%; padding: 40px; -} +} \ No newline at end of file diff --git a/static/editor.md/css/editormd.preview.min.css b/static/editor.md/css/editormd.preview.min.css index a0f22ada..5cc11d92 100644 --- a/static/editor.md/css/editormd.preview.min.css +++ b/static/editor.md/css/editormd.preview.min.css @@ -1,5 +1,5 @@ -/*! Editor.md v1.5.0 | editormd.preview.min.css | Open source online markdown editor. | MIT License | By: Pandao | https://github.com/pandao/editor.md | 2015-06-09 */ +/*! Editor.md v1.7.17 | editormd.preview.min.css | Open source online markdown editor. | MIT License | By: IBM Skills Network | https://github.com/ibm-skills-network/editor.md | 2024-03-27 */ @charset "UTF-8";/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 *//*! * Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */.fa-ul,.markdown-body .task-list-item,li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}.fa-fw,.fa-li{text-align:center}.fa,.fa-stack{display:inline-block}.fa,.markdown-body .octicon{-moz-osx-font-smoothing:grayscale}@font-face{font-family:FontAwesome;src:url(../fonts/fontawesome-webfont.eot?v=4.3.0);src:url(../fonts/fontawesome-webfont.eot?#iefix&v=4.3.0)format("embedded-opentype"),url(../fonts/fontawesome-webfont.woff2?v=4.3.0)format("woff2"),url(../fonts/fontawesome-webfont.woff?v=4.3.0)format("woff"),url(../fonts/fontawesome-webfont.ttf?v=4.3.0)format("truetype"),url(../fonts/fontawesome-webfont.svg?v=4.3.0#fontawesomeregular)format("svg");font-weight:400;font-style:normal}.fa{font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;transform:translate(0,0)}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em}.fa-ul{padding-left:0;margin-left:2.14285714em}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{filter:none}.fa-stack{position:relative;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-close:before,.fa-remove:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-cog:before,.fa-gear:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-repeat:before,.fa-rotate-right:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-exclamation-triangle:before,.fa-warning:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-cogs:before,.fa-gears:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-floppy-o:before,.fa-save:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-sort:before,.fa-unsorted:before{content:"\f0dc"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-sort-asc:before,.fa-sort-up:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-gavel:before,.fa-legal:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-bolt:before,.fa-flash:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-chain-broken:before,.fa-unlink:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:"\f150"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:"\f151"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:"\f152"}.fa-eur:before,.fa-euro:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-inr:before,.fa-rupee:before{content:"\f156"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:"\f157"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:"\f158"}.fa-krw:before,.fa-won:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-try:before,.fa-turkish-lira:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:"\f19c"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:"\f1c5"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:"\f1c6"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-empire:before,.fa-ge:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-paper-plane:before,.fa-send:before{content:"\f1d8"}.fa-paper-plane-o:before,.fa-send-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before,.fa-genderless:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-bed:before,.fa-hotel:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */@font-face{font-family:editormd-logo;src:url(../fonts/editormd-logo.eot?-5y8q6h);src:url(.../fonts/editormd-logo.eot?#iefix-5y8q6h)format("embedded-opentype"),url(../fonts/editormd-logo.woff?-5y8q6h)format("woff"),url(../fonts/editormd-logo.ttf?-5y8q6h)format("truetype"),url(../fonts/editormd-logo.svg?-5y8q6h#icomoon)format("svg");font-weight:400;font-style:normal}.editormd-logo,.editormd-logo-1x,.editormd-logo-2x,.editormd-logo-3x,.editormd-logo-4x,.editormd-logo-5x,.editormd-logo-6x,.editormd-logo-7x,.editormd-logo-8x{font-family:editormd-logo;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;font-size:inherit;line-height:1;display:inline-block;text-rendering:auto;vertical-align:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.markdown-body hr:after,.markdown-body hr:before{content:"";display:table}.editormd-logo-1x:before,.editormd-logo-2x:before,.editormd-logo-3x:before,.editormd-logo-4x:before,.editormd-logo-5x:before,.editormd-logo-6x:before,.editormd-logo-7x:before,.editormd-logo-8x:before,.editormd-logo:before{content:"\e1987"}.editormd-logo-1x{font-size:1em}.editormd-logo-lg{font-size:1.2em}.editormd-logo-2x{font-size:2em}.editormd-logo-3x{font-size:3em}.editormd-logo-4x{font-size:4em}.editormd-logo-5x{font-size:5em}.editormd-logo-6x{font-size:6em}.editormd-logo-7x{font-size:7em}.editormd-logo-8x{font-size:8em}.editormd-logo-color{color:#2196F3}/*! github-markdown-css | The MIT License (MIT) | Copyright (c) Sindre Sorhus (sindresorhus.com) | https://github.com/sindresorhus/github-markdown-css */@font-face{font-family:octicons-anchor;src:url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAYcAA0AAAAACjQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABMAAAABwAAAAca8vGTk9TLzIAAAFMAAAARAAAAFZG1VHVY21hcAAAAZAAAAA+AAABQgAP9AdjdnQgAAAB0AAAAAQAAAAEACICiGdhc3AAAAHUAAAACAAAAAj//wADZ2x5ZgAAAdwAAADRAAABEKyikaNoZWFkAAACsAAAAC0AAAA2AtXoA2hoZWEAAALgAAAAHAAAACQHngNFaG10eAAAAvwAAAAQAAAAEAwAACJsb2NhAAADDAAAAAoAAAAKALIAVG1heHAAAAMYAAAAHwAAACABEAB2bmFtZQAAAzgAAALBAAAFu3I9x/Nwb3N0AAAF/AAAAB0AAAAvaoFvbwAAAAEAAAAAzBdyYwAAAADP2IQvAAAAAM/bz7t4nGNgZGFgnMDAysDB1Ml0hoGBoR9CM75mMGLkYGBgYmBlZsAKAtJcUxgcPsR8iGF2+O/AEMPsznAYKMwIkgMA5REMOXicY2BgYGaAYBkGRgYQsAHyGMF8FgYFIM0ChED+h5j//yEk/3KoSgZGNgYYk4GRCUgwMaACRoZhDwCs7QgGAAAAIgKIAAAAAf//AAJ4nHWMMQrCQBBF/0zWrCCIKUQsTDCL2EXMohYGSSmorScInsRGL2DOYJe0Ntp7BK+gJ1BxF1stZvjz/v8DRghQzEc4kIgKwiAppcA9LtzKLSkdNhKFY3HF4lK69ExKslx7Xa+vPRVS43G98vG1DnkDMIBUgFN0MDXflU8tbaZOUkXUH0+U27RoRpOIyCKjbMCVejwypzJJG4jIwb43rfl6wbwanocrJm9XFYfskuVC5K/TPyczNU7b84CXcbxks1Un6H6tLH9vf2LRnn8Ax7A5WQAAAHicY2BkYGAA4teL1+yI57f5ysDNwgAC529f0kOmWRiYVgEpDgYmEA8AUzEKsQAAAHicY2BkYGB2+O/AEMPCAAJAkpEBFbAAADgKAe0EAAAiAAAAAAQAAAAEAAAAAAAAKgAqACoAiAAAeJxjYGRgYGBhsGFgYgABEMkFhAwM/xn0QAIAD6YBhwB4nI1Ty07cMBS9QwKlQapQW3VXySvEqDCZGbGaHULiIQ1FKgjWMxknMfLEke2A+IJu+wntrt/QbVf9gG75jK577Lg8K1qQPCfnnnt8fX1NRC/pmjrk/zprC+8D7tBy9DHgBXoWfQ44Av8t4Bj4Z8CLtBL9CniJluPXASf0Lm4CXqFX8Q84dOLnMB17N4c7tBo1AS/Qi+hTwBH4rwHHwN8DXqQ30XXAS7QaLwSc0Gn8NuAVWou/gFmnjLrEaEh9GmDdDGgL3B4JsrRPDU2hTOiMSuJUIdKQQayiAth69r6akSSFqIJuA19TrzCIaY8sIoxyrNIrL//pw7A2iMygkX5vDj+G+kuoLdX4GlGK/8Lnlz6/h9MpmoO9rafrz7ILXEHHaAx95s9lsI7AHNMBWEZHULnfAXwG9/ZqdzLI08iuwRloXE8kfhXYAvE23+23DU3t626rbs8/8adv+9DWknsHp3E17oCf+Z48rvEQNZ78paYM38qfk3v/u3l3u3GXN2Dmvmvpf1Srwk3pB/VSsp512bA/GG5i2WJ7wu430yQ5K3nFGiOqgtmSB5pJVSizwaacmUZzZhXLlZTq8qGGFY2YcSkqbth6aW1tRmlaCFs2016m5qn36SbJrqosG4uMV4aP2PHBmB3tjtmgN2izkGQyLWprekbIntJFing32a5rKWCN/SdSoga45EJykyQ7asZvHQ8PTm6cslIpwyeyjbVltNikc2HTR7YKh9LBl9DADC0U/jLcBZDKrMhUBfQBvXRzLtFtjU9eNHKin0x5InTqb8lNpfKv1s1xHzTXRqgKzek/mb7nB8RZTCDhGEX3kK/8Q75AmUM/eLkfA+0Hi908Kx4eNsMgudg5GLdRD7a84npi+YxNr5i5KIbW5izXas7cHXIMAau1OueZhfj+cOcP3P8MNIWLyYOBuxL6DRylJ4cAAAB4nGNgYoAALjDJyIAOWMCiTIxMLDmZedkABtIBygAAAA==)format("woff")}.markdown-body{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;color:#333;overflow:hidden;font-family:"Microsoft YaHei",Helvetica,"Meiryo UI","Malgun Gothic","Segoe UI","Trebuchet MS",Monaco,monospace,Tahoma,STXihei,"华文细黑",STHeiti,"Helvetica Neue","Droid Sans","wenquanyi micro hei",FreeSans,Arimo,Arial,SimSun,"宋体",Heiti,"黑体",sans-serif;font-size:16px;line-height:1.6;word-wrap:break-word}.markdown-body strong{font-weight:700}.markdown-body h1{margin:.67em 0}.markdown-body img{border:0}.markdown-body hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}.markdown-body input{color:inherit;margin:0;line-height:normal;font:13px/1.4 Helvetica,arial,freesans,clean,sans-serif,"Segoe UI Emoji","Segoe UI Symbol"}.markdown-body html input[disabled]{cursor:default}.markdown-body input[type=checkbox]{-moz-box-sizing:border-box;box-sizing:border-box;padding:0}.markdown-body td,.markdown-body th{padding:0}.markdown-body *{-moz-box-sizing:border-box;box-sizing:border-box}.markdown-body a{background:0 0;color:#4183c4;text-decoration:none}.markdown-body a:active,.markdown-body a:hover{outline:0;text-decoration:underline}.markdown-body hr{margin:15px 0;overflow:hidden;background:0 0;border:0;border-bottom:1px solid #ddd}.markdown-body h1,.markdown-body h2{padding-bottom:.3em;border-bottom:1px solid #eee}.markdown-body hr:after{clear:both}.markdown-body blockquote{margin:0}.markdown-body ol,.markdown-body ul{padding:0}.markdown-body ol ol,.markdown-body ul ol{list-style-type:lower-roman}.markdown-body ol ol ol,.markdown-body ol ul ol,.markdown-body ul ol ol,.markdown-body ul ul ol{list-style-type:lower-alpha}.markdown-body dd{margin-left:0}.markdown-body code{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace}.markdown-body pre{font:12px Consolas,"Liberation Mono",Menlo,Courier,monospace;word-wrap:normal}.markdown-body .octicon{font:normal normal 16px octicons-anchor;line-height:1;display:inline-block;text-decoration:none;-webkit-font-smoothing:antialiased;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.markdown-body .octicon-link:before{content:'\f05c'}.markdown-body>:first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdown-body .anchor{position:absolute;top:0;left:0;display:block;padding-right:6px;padding-left:30px;margin-left:-30px}.markdown-body .anchor:focus{outline:0}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{position:relative;margin-top:1em;margin-bottom:16px;font-weight:700;line-height:1.4}.markdown-body h1 .octicon-link,.markdown-body h2 .octicon-link,.markdown-body h3 .octicon-link,.markdown-body h4 .octicon-link,.markdown-body h5 .octicon-link,.markdown-body h6 .octicon-link{display:none;color:#000;vertical-align:middle}.markdown-body h1:hover .anchor,.markdown-body h2:hover .anchor,.markdown-body h3:hover .anchor,.markdown-body h4:hover .anchor,.markdown-body h5:hover .anchor,.markdown-body h6:hover .anchor{padding-left:8px;margin-left:-30px;text-decoration:none}.markdown-body h1:hover .anchor .octicon-link,.markdown-body h2:hover .anchor .octicon-link,.markdown-body h3:hover .anchor .octicon-link,.markdown-body h4:hover .anchor .octicon-link,.markdown-body h5:hover .anchor .octicon-link,.markdown-body h6:hover .anchor .octicon-link{display:inline-block}.markdown-body h1{font-size:2.25em;line-height:1.2}.markdown-body h1 .anchor{line-height:1}.markdown-body h2{font-size:1.75em;line-height:1.225}.markdown-body h2 .anchor{line-height:1}.markdown-body h3{font-size:1.5em;line-height:1.43}.markdown-body h3 .anchor,.markdown-body h4 .anchor{line-height:1.2}.markdown-body h4{font-size:1.25em}.markdown-body h5 .anchor,.markdown-body h6 .anchor{line-height:1.1}.markdown-body h5{font-size:1em}.markdown-body h6{font-size:1em;color:#777}.markdown-body blockquote,.markdown-body dl,.markdown-body ol,.markdown-body p,.markdown-body pre,.markdown-body table,.markdown-body ul{margin-top:0;margin-bottom:16px}.markdown-body ol,.markdown-body ul{padding-left:2em}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:0;margin-bottom:0}.markdown-body li>p{margin-top:16px}.markdown-body dl{padding:0}.markdown-body dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:700}.markdown-body dl dd{padding:0 16px;margin-bottom:16px}.markdown-body blockquote{padding:0 15px;color:#777;border-left:4px solid #ddd}.markdown-body blockquote>:first-child{margin-top:0}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body table{border-collapse:collapse;border-spacing:0;display:block;width:100%;overflow:auto;word-break:normal;word-break:keep-all}.markdown-body table th{font-weight:700}.markdown-body table td,.markdown-body table th{padding:6px 13px;border:1px solid #ddd}.markdown-body table tr{background-color:#fff;border-top:1px solid #ccc}.markdown-body table tr:nth-child(2n){background-color:#f8f8f8}.markdown-body img{max-width:100%;-moz-box-sizing:border-box;box-sizing:border-box}.markdown-body code{padding:.2em 0;margin:0;font-size:85%;background-color:rgba(0,0,0,.04);border-radius:3px}.markdown-body code:after,.markdown-body code:before{letter-spacing:-.2em;content:"\00a0"}.markdown-body pre>code{padding:0;margin:0;font-size:100%;word-break:normal;white-space:pre;background:0 0;border:0}.markdown-body .highlight{margin-bottom:16px}.markdown-body .highlight pre,.markdown-body pre{padding:16px;overflow:auto;font-size:85%;background-color:#f7f7f7;border-radius:3px}.markdown-body .highlight pre{margin-bottom:0;word-break:normal}.markdown-body pre code{display:inline;max-width:initial;padding:0;margin:0;overflow:initial;line-height:inherit;word-wrap:normal;background-color:transparent;border:0}.markdown-body pre code:after,.markdown-body pre code:before{content:normal}.markdown-body .pl-c{color:#969896}.markdown-body .pl-c1,.markdown-body .pl-mdh,.markdown-body .pl-mm,.markdown-body .pl-mp,.markdown-body .pl-mr,.markdown-body .pl-s1 .pl-v,.markdown-body .pl-s3,.markdown-body .pl-sc,.markdown-body .pl-sv{color:#0086b3}.markdown-body .pl-e,.markdown-body .pl-en{color:#795da3}.markdown-body .pl-s1 .pl-s2,.markdown-body .pl-smi,.markdown-body .pl-smp,.markdown-body .pl-stj,.markdown-body .pl-vo,.markdown-body .pl-vpf{color:#333}.markdown-body .pl-ent{color:#63a35c}.markdown-body .pl-k,.markdown-body .pl-s,.markdown-body .pl-st{color:#a71d5d}.markdown-body .pl-pds,.markdown-body .pl-s1,.markdown-body .pl-s1 .pl-pse .pl-s2,.markdown-body .pl-sr,.markdown-body .pl-sr .pl-cce,.markdown-body .pl-sr .pl-sra,.markdown-body .pl-sr .pl-sre,.markdown-body .pl-src{color:#df5000}.markdown-body .pl-mo,.markdown-body .pl-v{color:#1d3e81}.markdown-body .pl-id{color:#b52a1d}.markdown-body .pl-ii{background-color:#b52a1d;color:#f8f8f8}.markdown-body .pl-sr .pl-cce{color:#63a35c;font-weight:700}.markdown-body .pl-ml{color:#693a17}.markdown-body .pl-mh,.markdown-body .pl-mh .pl-en,.markdown-body .pl-ms{color:#1d3e81;font-weight:700}.markdown-body .pl-mq{color:teal}.markdown-body .pl-mi{color:#333;font-style:italic}.markdown-body .pl-mb{color:#333;font-weight:700}.markdown-body .pl-md,.markdown-body .pl-mdhf{background-color:#ffecec;color:#bd2c00}.markdown-body .pl-mdht,.markdown-body .pl-mi1{background-color:#eaffea;color:#55a532}.markdown-body .pl-mdr{color:#795da3;font-weight:700}.markdown-body kbd{display:inline-block;padding:3px 5px;font:11px Consolas,"Liberation Mono",Menlo,Courier,monospace;line-height:10px;color:#555;vertical-align:middle;background-color:#fcfcfc;border:1px solid #ccc;border-bottom-color:#bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb}.markdown-body .task-list-item+.task-list-item{margin-top:3px}.markdown-body .task-list-item input{float:left;margin:.3em 0 .25em -1.6em;vertical-align:middle}.markdown-body :checked+.radio-label{z-index:1;position:relative;border-color:#4183c4}.editormd-html-preview,.editormd-preview-container{text-align:left;font-size:14px;line-height:1.6;padding:20px;overflow:auto;width:100%;background-color:#fff}.editormd-html-preview blockquote,.editormd-preview-container blockquote{color:#666;border-left:4px solid #ddd;padding-left:20px;margin-left:0;font-size:14px;font-style:italic}.editormd-html-preview p code,.editormd-preview-container p code{margin-left:5px;margin-right:4px}.editormd-html-preview abbr,.editormd-preview-container abbr{background:#ffd}.editormd-html-preview hr,.editormd-preview-container hr{height:1px;border:none;border-top:1px solid #ddd;background:0 0}.editormd-html-preview code,.editormd-preview-container code{border:1px solid #ddd;background:#f6f6f6;padding:3px;border-radius:3px;font-size:14px}.editormd-html-preview pre,.editormd-preview-container pre{border:1px solid #ddd;background:#f6f6f6;padding:10px;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px}.editormd-html-preview pre code,.editormd-preview-container pre code{padding:0}.editormd-html-preview code,.editormd-html-preview kbd,.editormd-html-preview pre,.editormd-preview-container code,.editormd-preview-container kbd,.editormd-preview-container pre{font-family:"YaHei Consolas Hybrid",Consolas,"Meiryo UI","Malgun Gothic","Segoe UI","Trebuchet MS",Helvetica,monospace,monospace}.editormd-html-preview table thead tr,.editormd-preview-container table thead tr{background-color:#F8F8F8}.editormd-html-preview p.editormd-tex,.editormd-preview-container p.editormd-tex{text-align:center}.editormd-html-preview span.editormd-tex,.editormd-preview-container span.editormd-tex{margin:0 5px}.editormd-html-preview .emoji,.editormd-preview-container .emoji{width:24px;height:24px}.editormd-html-preview .katex,.editormd-preview-container .katex{font-size:1.4em}.editormd-html-preview .flowchart,.editormd-html-preview .sequence-diagram,.editormd-preview-container .flowchart,.editormd-preview-container .sequence-diagram{margin:0 auto;text-align:center}.editormd-html-preview .flowchart svg,.editormd-html-preview .sequence-diagram svg,.editormd-preview-container .flowchart svg,.editormd-preview-container .sequence-diagram svg{margin:0 auto}.editormd-html-preview .flowchart text,.editormd-html-preview .sequence-diagram text,.editormd-preview-container .flowchart text,.editormd-preview-container .sequence-diagram text{font-size:15px!important;font-family:"YaHei Consolas Hybrid",Consolas,"Microsoft YaHei","Malgun Gothic","Segoe UI",Helvetica,Arial!important}/*! Pretty printing styles. Used with prettify.js. */.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.clo,.opn,.pun{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.kwd,.tag,.typ{font-weight:700}.str{color:#060}.kwd{color:#006}.com{color:#600;font-style:italic}.typ{color:#404}.lit{color:#044}.clo,.opn,.pun{color:#440}.tag{color:#006}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}.editormd-html-preview pre.prettyprint,.editormd-preview-container pre.prettyprint{padding:10px;border:1px solid #ddd;white-space:pre-wrap;word-wrap:break-word}.editormd-html-preview ol.linenums,.editormd-preview-container ol.linenums{color:#999;padding-left:2.5em}.editormd-html-preview ol.linenums li,.editormd-preview-container ol.linenums li{list-style-type:decimal}.editormd-html-preview ol.linenums li code,.editormd-preview-container ol.linenums li code{border:none;background:0 0;padding:0}.editormd-html-preview .editormd-toc-menu,.editormd-preview-container .editormd-toc-menu{margin:8px 0 12px;display:inline-block}.editormd-html-preview .editormd-toc-menu>.markdown-toc,.editormd-preview-container .editormd-toc-menu>.markdown-toc{position:relative;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;-o-border-radius:4px;border-radius:4px;border:1px solid #ddd;display:inline-block;font-size:1em}.editormd-html-preview .editormd-toc-menu>.markdown-toc>ul,.editormd-preview-container .editormd-toc-menu>.markdown-toc>ul{width:160%;min-width:180px;position:absolute;left:-1px;top:-2px;z-index:100;padding:0 10px 10px;display:none;background:#fff;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;-o-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 3px 5px rgba(0,0,0,.2);-moz-box-shadow:0 3px 5px rgba(0,0,0,.2);-ms-box-shadow:0 3px 5px rgba(0,0,0,.2);-o-box-shadow:0 3px 5px rgba(0,0,0,.2);box-shadow:0 3px 5px rgba(0,0,0,.2)}.editormd-html-preview .editormd-toc-menu>.markdown-toc>ul>li ul,.editormd-preview-container .editormd-toc-menu>.markdown-toc>ul>li ul{width:100%;min-width:180px;border:1px solid #ddd;display:none;background:#fff;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;-o-border-radius:4px;border-radius:4px}.editormd-html-preview .editormd-toc-menu .toc-menu-btn:hover,.editormd-html-preview .editormd-toc-menu>.markdown-toc>ul>li a:hover,.editormd-preview-container .editormd-toc-menu .toc-menu-btn:hover,.editormd-preview-container .editormd-toc-menu>.markdown-toc>ul>li a:hover{background-color:#f6f6f6}.editormd-html-preview .editormd-toc-menu>.markdown-toc>ul>li a,.editormd-preview-container .editormd-toc-menu>.markdown-toc>ul>li a{color:#666;padding:6px 10px;display:block;-webkit-transition:background-color 500ms ease-out;-moz-transition:background-color 500ms ease-out;transition:background-color 500ms ease-out}.editormd-html-preview .editormd-toc-menu>.markdown-toc li,.editormd-preview-container .editormd-toc-menu>.markdown-toc li{position:relative}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul{position:absolute;top:32px;left:10%;display:none;-webkit-box-shadow:0 3px 5px rgba(0,0,0,.2);-moz-box-shadow:0 3px 5px rgba(0,0,0,.2);-ms-box-shadow:0 3px 5px rgba(0,0,0,.2);-o-box-shadow:0 3px 5px rgba(0,0,0,.2);box-shadow:0 3px 5px rgba(0,0,0,.2)}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:after,.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:before,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:after,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:before{pointer-events:pointer-events;position:absolute;left:15px;top:-6px;display:block;content:"";width:0;height:0;border:6px solid transparent;border-width:0 6px 6px;z-index:10}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:before,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:before{border-bottom-color:#ccc}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:after,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:after{border-bottom-color:#fff;top:-5px}.editormd-html-preview .editormd-toc-menu ul,.editormd-preview-container .editormd-toc-menu ul{list-style:none}.editormd-html-preview .editormd-toc-menu a,.editormd-preview-container .editormd-toc-menu a{text-decoration:none}.editormd-html-preview .editormd-toc-menu h1,.editormd-preview-container .editormd-toc-menu h1{font-size:16px;padding:5px 0 10px 10px;line-height:1;border-bottom:1px solid #eee}.editormd-html-preview .editormd-toc-menu h1 .fa,.editormd-preview-container .editormd-toc-menu h1 .fa{padding-left:10px}.editormd-html-preview .editormd-toc-menu .toc-menu-btn,.editormd-preview-container .editormd-toc-menu .toc-menu-btn{color:#666;min-width:180px;padding:5px 10px;border-radius:4px;display:inline-block;-webkit-transition:background-color 500ms ease-out;-moz-transition:background-color 500ms ease-out;transition:background-color 500ms ease-out}.editormd-html-preview .editormd-toc-menu .toc-menu-btn .fa,.editormd-preview-container .editormd-toc-menu .toc-menu-btn .fa{float:right;padding:3px 0 0 10px;font-size:1.3em}.markdown-body .editormd-toc-menu ul{padding-left:0}.markdown-body .highlight pre,.markdown-body pre{line-height:1.6}hr.editormd-page-break{border:1px dotted #ccc;font-size:0;height:2px}@media only print{hr.editormd-page-break{background:0 0;border:none;height:0}}.editormd-html-preview textarea{display:none}.editormd-html-preview hr.editormd-page-break{background:0 0;border:none;height:0}.editormd-preview-close-btn{color:#fff;padding:4px 6px;font-size:18px;-webkit-border-radius:500px;-moz-border-radius:500px;-ms-border-radius:500px;-o-border-radius:500px;border-radius:500px;display:none;background-color:#ccc;position:absolute;top:25px;right:35px;z-index:19;-webkit-transition:background-color 300ms ease-out;-moz-transition:background-color 300ms ease-out;transition:background-color 300ms ease-out}.editormd-preview-close-btn:hover{background-color:#999}.editormd-preview-active{width:100%;padding:40px} \ No newline at end of file + */@font-face{font-family:FontAwesome;src:url(../fonts/fontawesome-webfont.eot?v=4.3.0);src:url(../fonts/fontawesome-webfont.eot?#iefix&v=4.3.0) format("embedded-opentype"),url(../fonts/fontawesome-webfont.woff2?v=4.3.0) format("woff2"),url(../fonts/fontawesome-webfont.woff?v=4.3.0) format("woff"),url(../fonts/fontawesome-webfont.ttf?v=4.3.0) format("truetype"),url(../fonts/fontawesome-webfont.svg?v=4.3.0#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transform:translate(0,0)}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-close:before,.fa-remove:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-cog:before,.fa-gear:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-repeat:before,.fa-rotate-right:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-exclamation-triangle:before,.fa-warning:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-cogs:before,.fa-gears:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-floppy-o:before,.fa-save:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-sort:before,.fa-unsorted:before{content:"\f0dc"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-sort-asc:before,.fa-sort-up:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-gavel:before,.fa-legal:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-bolt:before,.fa-flash:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-chain-broken:before,.fa-unlink:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:"\f150"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:"\f151"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:"\f152"}.fa-eur:before,.fa-euro:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-inr:before,.fa-rupee:before{content:"\f156"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:"\f157"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:"\f158"}.fa-krw:before,.fa-won:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-try:before,.fa-turkish-lira:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:"\f19c"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:"\f1c5"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:"\f1c6"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-empire:before,.fa-ge:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-paper-plane:before,.fa-send:before{content:"\f1d8"}.fa-paper-plane-o:before,.fa-send-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before,.fa-genderless:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-bed:before,.fa-hotel:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */@font-face{font-family:editormd-logo;src:url(../fonts/editormd-logo.eot?-5y8q6h);src:url(../fonts/editormd-logo.eot?#iefix-5y8q6h) format("embedded-opentype"),url(../fonts/editormd-logo.woff?-5y8q6h) format("woff"),url(../fonts/editormd-logo.ttf?-5y8q6h) format("truetype"),url(../fonts/editormd-logo.svg?-5y8q6h#icomoon) format("svg");font-weight:400;font-style:normal}.editormd-logo,.editormd-logo-1x,.editormd-logo-2x,.editormd-logo-3x,.editormd-logo-4x,.editormd-logo-5x,.editormd-logo-6x,.editormd-logo-7x,.editormd-logo-8x{font-family:editormd-logo;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;font-size:inherit;line-height:1;display:inline-block;text-rendering:auto;vertical-align:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.editormd-logo-1x:before,.editormd-logo-2x:before,.editormd-logo-3x:before,.editormd-logo-4x:before,.editormd-logo-5x:before,.editormd-logo-6x:before,.editormd-logo-7x:before,.editormd-logo-8x:before,.editormd-logo:before{content:"󡦇"}.editormd-logo-1x{font-size:1em}.editormd-logo-lg{font-size:1.2em}.editormd-logo-2x{font-size:2em}.editormd-logo-3x{font-size:3em}.editormd-logo-4x{font-size:4em}.editormd-logo-5x{font-size:5em}.editormd-logo-6x{font-size:6em}.editormd-logo-7x{font-size:7em}.editormd-logo-8x{font-size:8em}.editormd-logo-color{color:#2196f3}/*! github-markdown-css | The MIT License (MIT) | Copyright (c) Sindre Sorhus (sindresorhus.com) | https://github.com/sindresorhus/github-markdown-css */@font-face{font-family:octicons-anchor;src:url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAYcAA0AAAAACjQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABMAAAABwAAAAca8vGTk9TLzIAAAFMAAAARAAAAFZG1VHVY21hcAAAAZAAAAA+AAABQgAP9AdjdnQgAAAB0AAAAAQAAAAEACICiGdhc3AAAAHUAAAACAAAAAj//wADZ2x5ZgAAAdwAAADRAAABEKyikaNoZWFkAAACsAAAAC0AAAA2AtXoA2hoZWEAAALgAAAAHAAAACQHngNFaG10eAAAAvwAAAAQAAAAEAwAACJsb2NhAAADDAAAAAoAAAAKALIAVG1heHAAAAMYAAAAHwAAACABEAB2bmFtZQAAAzgAAALBAAAFu3I9x/Nwb3N0AAAF/AAAAB0AAAAvaoFvbwAAAAEAAAAAzBdyYwAAAADP2IQvAAAAAM/bz7t4nGNgZGFgnMDAysDB1Ml0hoGBoR9CM75mMGLkYGBgYmBlZsAKAtJcUxgcPsR8iGF2+O/AEMPsznAYKMwIkgMA5REMOXicY2BgYGaAYBkGRgYQsAHyGMF8FgYFIM0ChED+h5j//yEk/3KoSgZGNgYYk4GRCUgwMaACRoZhDwCs7QgGAAAAIgKIAAAAAf//AAJ4nHWMMQrCQBBF/0zWrCCIKUQsTDCL2EXMohYGSSmorScInsRGL2DOYJe0Ntp7BK+gJ1BxF1stZvjz/v8DRghQzEc4kIgKwiAppcA9LtzKLSkdNhKFY3HF4lK69ExKslx7Xa+vPRVS43G98vG1DnkDMIBUgFN0MDXflU8tbaZOUkXUH0+U27RoRpOIyCKjbMCVejwypzJJG4jIwb43rfl6wbwanocrJm9XFYfskuVC5K/TPyczNU7b84CXcbxks1Un6H6tLH9vf2LRnn8Ax7A5WQAAAHicY2BkYGAA4teL1+yI57f5ysDNwgAC529f0kOmWRiYVgEpDgYmEA8AUzEKsQAAAHicY2BkYGB2+O/AEMPCAAJAkpEBFbAAADgKAe0EAAAiAAAAAAQAAAAEAAAAAAAAKgAqACoAiAAAeJxjYGRgYGBhsGFgYgABEMkFhAwM/xn0QAIAD6YBhwB4nI1Ty07cMBS9QwKlQapQW3VXySvEqDCZGbGaHULiIQ1FKgjWMxknMfLEke2A+IJu+wntrt/QbVf9gG75jK577Lg8K1qQPCfnnnt8fX1NRC/pmjrk/zprC+8D7tBy9DHgBXoWfQ44Av8t4Bj4Z8CLtBL9CniJluPXASf0Lm4CXqFX8Q84dOLnMB17N4c7tBo1AS/Qi+hTwBH4rwHHwN8DXqQ30XXAS7QaLwSc0Gn8NuAVWou/gFmnjLrEaEh9GmDdDGgL3B4JsrRPDU2hTOiMSuJUIdKQQayiAth69r6akSSFqIJuA19TrzCIaY8sIoxyrNIrL//pw7A2iMygkX5vDj+G+kuoLdX4GlGK/8Lnlz6/h9MpmoO9rafrz7ILXEHHaAx95s9lsI7AHNMBWEZHULnfAXwG9/ZqdzLI08iuwRloXE8kfhXYAvE23+23DU3t626rbs8/8adv+9DWknsHp3E17oCf+Z48rvEQNZ78paYM38qfk3v/u3l3u3GXN2Dmvmvpf1Srwk3pB/VSsp512bA/GG5i2WJ7wu430yQ5K3nFGiOqgtmSB5pJVSizwaacmUZzZhXLlZTq8qGGFY2YcSkqbth6aW1tRmlaCFs2016m5qn36SbJrqosG4uMV4aP2PHBmB3tjtmgN2izkGQyLWprekbIntJFing32a5rKWCN/SdSoga45EJykyQ7asZvHQ8PTm6cslIpwyeyjbVltNikc2HTR7YKh9LBl9DADC0U/jLcBZDKrMhUBfQBvXRzLtFtjU9eNHKin0x5InTqb8lNpfKv1s1xHzTXRqgKzek/mb7nB8RZTCDhGEX3kK/8Q75AmUM/eLkfA+0Hi908Kx4eNsMgudg5GLdRD7a84npi+YxNr5i5KIbW5izXas7cHXIMAau1OueZhfj+cOcP3P8MNIWLyYOBuxL6DRylJ4cAAAB4nGNgYoAALjDJyIAOWMCiTIxMLDmZedkABtIBygAAAA==) format("woff")}.markdown-body{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;color:#333;overflow:hidden;font-family:"Microsoft YaHei",Helvetica,"Meiryo UI","Malgun Gothic","Segoe UI","Trebuchet MS",Monaco,monospace,Tahoma,STXihei,"华文细黑",STHeiti,"Helvetica Neue","Droid Sans","wenquanyi micro hei",FreeSans,Arimo,Arial,SimSun,"宋体",Heiti,"黑体",sans-serif;font-size:16px;line-height:1.6;word-wrap:break-word}.markdown-body a{background:0 0}.markdown-body a:active,.markdown-body a:hover{outline:0}.markdown-body strong{font-weight:700}.markdown-body h1{font-size:2em;margin:.67em 0}.markdown-body img{border:0}.markdown-body hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}.markdown-body pre{overflow:auto}.markdown-body code,.markdown-body kbd,.markdown-body pre{font-family:"Meiryo UI","YaHei Consolas Hybrid",Consolas,"Malgun Gothic","Segoe UI","Trebuchet MS",Helvetica,monospace,monospace;font-size:1em}.markdown-body input{color:inherit;font:inherit;margin:0}.markdown-body html input[disabled]{cursor:default}.markdown-body input{line-height:normal}.markdown-body input[type=checkbox]{-moz-box-sizing:border-box;box-sizing:border-box;padding:0}.markdown-body table{border-collapse:collapse;border-spacing:0}.markdown-body td,.markdown-body th{padding:0}.markdown-body *{-moz-box-sizing:border-box;box-sizing:border-box}.markdown-body input{font:13px/1.4 Helvetica,arial,freesans,clean,sans-serif,"Segoe UI Emoji","Segoe UI Symbol"}.markdown-body a{color:#4183c4;text-decoration:none}.markdown-body a:active,.markdown-body a:hover{text-decoration:underline}.markdown-body hr{height:0;margin:15px 0;overflow:hidden;background:0 0;border:0;border-bottom:1px solid #ddd}.markdown-body hr:before{display:table;content:""}.markdown-body hr:after{display:table;clear:both;content:""}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{margin-top:15px;margin-bottom:15px;line-height:1.1}.markdown-body h1{font-size:30px}.markdown-body h2{font-size:21px}.markdown-body h3{font-size:16px}.markdown-body h4{font-size:14px}.markdown-body h5{font-size:12px}.markdown-body h6{font-size:11px}.markdown-body blockquote{margin:0}.markdown-body ol,.markdown-body ul{padding:0;margin-top:0;margin-bottom:0}.markdown-body ol ol,.markdown-body ul ol{list-style-type:lower-roman}.markdown-body ol ol ol,.markdown-body ol ul ol,.markdown-body ul ol ol,.markdown-body ul ul ol{list-style-type:lower-alpha}.markdown-body dd{margin-left:0}.markdown-body code{font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:12px}.markdown-body pre{margin-top:0;margin-bottom:0;font:12px Consolas,"Liberation Mono",Menlo,Courier,monospace}.markdown-body .octicon{font:normal normal 16px octicons-anchor;line-height:1;display:inline-block;text-decoration:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.markdown-body .octicon-link:before{content:"\f05c"}.markdown-body>:first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdown-body .anchor{position:absolute;top:0;left:0;display:block;padding-right:6px;padding-left:30px;margin-left:-30px}.markdown-body .anchor:focus{outline:0}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{position:relative;margin-top:1em;margin-bottom:16px;font-weight:700;line-height:1.4}.markdown-body h1 .octicon-link,.markdown-body h2 .octicon-link,.markdown-body h3 .octicon-link,.markdown-body h4 .octicon-link,.markdown-body h5 .octicon-link,.markdown-body h6 .octicon-link{display:none;color:#000;vertical-align:middle}.markdown-body h1:hover .anchor,.markdown-body h2:hover .anchor,.markdown-body h3:hover .anchor,.markdown-body h4:hover .anchor,.markdown-body h5:hover .anchor,.markdown-body h6:hover .anchor{padding-left:8px;margin-left:-30px;text-decoration:none}.markdown-body h1:hover .anchor .octicon-link,.markdown-body h2:hover .anchor .octicon-link,.markdown-body h3:hover .anchor .octicon-link,.markdown-body h4:hover .anchor .octicon-link,.markdown-body h5:hover .anchor .octicon-link,.markdown-body h6:hover .anchor .octicon-link{display:inline-block}.markdown-body h1{padding-bottom:.3em;font-size:2.25em;line-height:1.2;border-bottom:1px solid #eee}.markdown-body h1 .anchor{line-height:1}.markdown-body h2{padding-bottom:.3em;font-size:1.75em;line-height:1.225;border-bottom:1px solid #eee}.markdown-body h2 .anchor{line-height:1}.markdown-body h3{font-size:1.5em;line-height:1.43}.markdown-body h3 .anchor{line-height:1.2}.markdown-body h4{font-size:1.25em}.markdown-body h4 .anchor{line-height:1.2}.markdown-body h5{font-size:1em}.markdown-body h5 .anchor{line-height:1.1}.markdown-body h6{font-size:1em;color:#777}.markdown-body h6 .anchor{line-height:1.1}.markdown-body blockquote,.markdown-body dl,.markdown-body ol,.markdown-body p,.markdown-body pre,.markdown-body table,.markdown-body ul{margin-top:0;margin-bottom:16px}.markdown-body ol,.markdown-body ul{padding-left:2em}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:0;margin-bottom:0}.markdown-body li>p{margin-top:16px}.markdown-body dl{padding:0}.markdown-body dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:700}.markdown-body dl dd{padding:0 16px;margin-bottom:16px}.markdown-body blockquote{padding:0 15px;color:#777;border-left:4px solid #ddd}.markdown-body blockquote>:first-child{margin-top:0}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body table{display:block;width:100%;overflow:auto;word-break:normal;word-break:keep-all}.markdown-body table th{font-weight:700}.markdown-body table td,.markdown-body table th{padding:6px 13px;border:1px solid #ddd}.markdown-body table tr{background-color:#fff;border-top:1px solid #ccc}.markdown-body table tr:nth-child(2n){background-color:#f8f8f8}.markdown-body img{max-width:100%;-moz-box-sizing:border-box;box-sizing:border-box}.markdown-body code{padding:0;padding-top:.2em;padding-bottom:.2em;margin:0;font-size:85%;background-color:rgba(0,0,0,.04);border-radius:3px}.markdown-body code:after,.markdown-body code:before{letter-spacing:-.2em;content:" "}.markdown-body pre>code{padding:0;margin:0;font-size:100%;word-break:normal;white-space:pre;background:0 0;border:0}.markdown-body .highlight{margin-bottom:16px}.markdown-body .highlight pre,.markdown-body pre{padding:16px;overflow:auto;font-size:85%;line-height:1.45;background-color:#f7f7f7;border-radius:3px}.markdown-body .highlight pre{margin-bottom:0;word-break:normal}.markdown-body pre{word-wrap:normal}.markdown-body pre code{display:inline;max-width:initial;padding:0;margin:0;overflow:initial;line-height:inherit;word-wrap:normal;background-color:transparent;border:0}.markdown-body pre code:after,.markdown-body pre code:before{content:normal}.markdown-body kbd{display:inline-block;padding:3px 5px;font-size:11px;line-height:10px;color:#555;vertical-align:middle;background-color:#fcfcfc;border:solid 1px #ccc;border-bottom-color:#bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb}.markdown-body .pl-c{color:#969896}.markdown-body .pl-c1,.markdown-body .pl-mdh,.markdown-body .pl-mm,.markdown-body .pl-mp,.markdown-body .pl-mr,.markdown-body .pl-s1 .pl-v,.markdown-body .pl-s3,.markdown-body .pl-sc,.markdown-body .pl-sv{color:#0086b3}.markdown-body .pl-e,.markdown-body .pl-en{color:#795da3}.markdown-body .pl-s1 .pl-s2,.markdown-body .pl-smi,.markdown-body .pl-smp,.markdown-body .pl-stj,.markdown-body .pl-vo,.markdown-body .pl-vpf{color:#333}.markdown-body .pl-ent{color:#63a35c}.markdown-body .pl-k,.markdown-body .pl-s,.markdown-body .pl-st{color:#a71d5d}.markdown-body .pl-pds,.markdown-body .pl-s1,.markdown-body .pl-s1 .pl-pse .pl-s2,.markdown-body .pl-sr,.markdown-body .pl-sr .pl-cce,.markdown-body .pl-sr .pl-sra,.markdown-body .pl-sr .pl-sre,.markdown-body .pl-src{color:#df5000}.markdown-body .pl-mo,.markdown-body .pl-v{color:#1d3e81}.markdown-body .pl-id{color:#b52a1d}.markdown-body .pl-ii{background-color:#b52a1d;color:#f8f8f8}.markdown-body .pl-sr .pl-cce{color:#63a35c;font-weight:700}.markdown-body .pl-ml{color:#693a17}.markdown-body .pl-mh,.markdown-body .pl-mh .pl-en,.markdown-body .pl-ms{color:#1d3e81;font-weight:700}.markdown-body .pl-mq{color:teal}.markdown-body .pl-mi{color:#333;font-style:italic}.markdown-body .pl-mb{color:#333;font-weight:700}.markdown-body .pl-md,.markdown-body .pl-mdhf{background-color:#ffecec;color:#bd2c00}.markdown-body .pl-mdht,.markdown-body .pl-mi1{background-color:#eaffea;color:#55a532}.markdown-body .pl-mdr{color:#795da3;font-weight:700}.markdown-body kbd{display:inline-block;padding:3px 5px;font:11px Consolas,"Liberation Mono",Menlo,Courier,monospace;line-height:10px;color:#555;vertical-align:middle;background-color:#fcfcfc;border:solid 1px #ccc;border-bottom-color:#bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb}.markdown-body .task-list-item{list-style-type:none}.markdown-body .task-list-item+.task-list-item{margin-top:3px}.markdown-body .task-list-item input{float:left;margin:.3em 0 .25em -1.6em;vertical-align:middle}.markdown-body :checked+.radio-label{z-index:1;position:relative;border-color:#4183c4}.editormd-html-preview,.editormd-preview-container{text-align:left;font-size:14px;line-height:1.6;padding:20px;overflow:auto;width:100%;background-color:#fff}.editormd-html-preview blockquote,.editormd-preview-container blockquote{color:#666;border-left:4px solid #ddd;padding-left:20px;margin-left:0;font-size:14px;font-style:italic}.editormd-html-preview p code,.editormd-preview-container p code{margin-left:5px;margin-right:4px}.editormd-html-preview abbr,.editormd-preview-container abbr{background:#ffd}.editormd-html-preview hr,.editormd-preview-container hr{height:1px;border:none;border-top:1px solid #ddd;background:0 0}.editormd-html-preview code,.editormd-preview-container code{border:1px solid #ddd;background:#f6f6f6;padding:3px;border-radius:3px;font-size:14px}.editormd-html-preview pre,.editormd-preview-container pre{border:1px solid #ddd;background:#f6f6f6;padding:10px;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;border-radius:3px}.editormd-html-preview pre code,.editormd-preview-container pre code{padding:0}.editormd-html-preview code,.editormd-html-preview kbd,.editormd-html-preview pre,.editormd-preview-container code,.editormd-preview-container kbd,.editormd-preview-container pre{font-family:"YaHei Consolas Hybrid",Consolas,"Meiryo UI","Malgun Gothic","Segoe UI","Trebuchet MS",Helvetica,monospace,monospace}.editormd-html-preview table thead tr,.editormd-preview-container table thead tr{background-color:#f8f8f8}.editormd-html-preview p.editormd-tex,.editormd-preview-container p.editormd-tex{text-align:center}.editormd-html-preview span.editormd-tex,.editormd-preview-container span.editormd-tex{margin:0 5px}.editormd-html-preview .emoji,.editormd-preview-container .emoji{width:24px;height:24px}.editormd-html-preview .katex,.editormd-preview-container .katex{font-size:1.4em}.editormd-html-preview .flowchart,.editormd-html-preview .sequence-diagram,.editormd-preview-container .flowchart,.editormd-preview-container .sequence-diagram{margin:0 auto;text-align:center}.editormd-html-preview .flowchart svg,.editormd-html-preview .sequence-diagram svg,.editormd-preview-container .flowchart svg,.editormd-preview-container .sequence-diagram svg{margin:0 auto}.editormd-html-preview .flowchart text,.editormd-html-preview .sequence-diagram text,.editormd-preview-container .flowchart text,.editormd-preview-container .sequence-diagram text{font-size:15px!important;font-family:"YaHei Consolas Hybrid",Consolas,"Microsoft YaHei","Malgun Gothic","Segoe UI",Helvetica,Arial!important}/*! Pretty printing styles. Used with prettify.js. */.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.clo,.opn,.pun{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:700}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:700}.lit{color:#044}.clo,.opn,.pun{color:#440}.tag{color:#006;font-weight:700}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}.editormd-html-preview pre.prettyprint,.editormd-preview-container pre.prettyprint{padding:10px;border:1px solid #ddd;white-space:pre-wrap;word-wrap:break-word}.editormd-html-preview ol.linenums,.editormd-preview-container ol.linenums{color:#999;padding-left:2.5em}.editormd-html-preview ol.linenums li,.editormd-preview-container ol.linenums li{list-style-type:decimal}.editormd-html-preview ol.linenums li code,.editormd-preview-container ol.linenums li code{border:none;background:0 0;padding:0}.editormd-html-preview .editormd-toc-menu,.editormd-preview-container .editormd-toc-menu{margin:8px 0 12px 0;display:inline-block}.editormd-html-preview .editormd-toc-menu>.markdown-toc,.editormd-preview-container .editormd-toc-menu>.markdown-toc{position:relative;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;-o-border-radius:4px;border-radius:4px;border:1px solid #ddd;display:inline-block;font-size:1em}.editormd-html-preview .editormd-toc-menu>.markdown-toc>ul,.editormd-preview-container .editormd-toc-menu>.markdown-toc>ul{width:160%;min-width:180px;position:absolute;left:-1px;top:-2px;z-index:100;padding:0 10px 10px;display:none;background:#fff;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;-o-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 3px 5px rgba(0,0,0,.2);-moz-box-shadow:0 3px 5px rgba(0,0,0,.2);-ms-box-shadow:0 3px 5px rgba(0,0,0,.2);-o-box-shadow:0 3px 5px rgba(0,0,0,.2);box-shadow:0 3px 5px rgba(0,0,0,.2)}.editormd-html-preview .editormd-toc-menu>.markdown-toc>ul>li ul,.editormd-preview-container .editormd-toc-menu>.markdown-toc>ul>li ul{width:100%;min-width:180px;border:1px solid #ddd;display:none;background:#fff;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;-o-border-radius:4px;border-radius:4px}.editormd-html-preview .editormd-toc-menu>.markdown-toc>ul>li a,.editormd-preview-container .editormd-toc-menu>.markdown-toc>ul>li a{color:#666;padding:6px 10px;display:block;-webkit-transition:background-color .5s ease-out;-moz-transition:background-color .5s ease-out;transition:background-color .5s ease-out}.editormd-html-preview .editormd-toc-menu>.markdown-toc>ul>li a:hover,.editormd-preview-container .editormd-toc-menu>.markdown-toc>ul>li a:hover{background-color:#f6f6f6}.editormd-html-preview .editormd-toc-menu>.markdown-toc li,.editormd-preview-container .editormd-toc-menu>.markdown-toc li{position:relative}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul{position:absolute;top:32px;left:10%;display:none;-webkit-box-shadow:0 3px 5px rgba(0,0,0,.2);-moz-box-shadow:0 3px 5px rgba(0,0,0,.2);-ms-box-shadow:0 3px 5px rgba(0,0,0,.2);-o-box-shadow:0 3px 5px rgba(0,0,0,.2);box-shadow:0 3px 5px rgba(0,0,0,.2)}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:after,.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:before,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:after,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:before{pointer-events:pointer-events;position:absolute;left:15px;top:-6px;display:block;content:"";width:0;height:0;border:6px solid transparent;border-width:0 6px 6px;z-index:10}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:before,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:before{border-bottom-color:#ccc}.editormd-html-preview .editormd-toc-menu>.markdown-toc li>ul:after,.editormd-preview-container .editormd-toc-menu>.markdown-toc li>ul:after{border-bottom-color:#fff;top:-5px}.editormd-html-preview .editormd-toc-menu ul,.editormd-preview-container .editormd-toc-menu ul{list-style:none}.editormd-html-preview .editormd-toc-menu a,.editormd-preview-container .editormd-toc-menu a{text-decoration:none}.editormd-html-preview .editormd-toc-menu h1,.editormd-preview-container .editormd-toc-menu h1{font-size:16px;padding:5px 0 10px 10px;line-height:1;border-bottom:1px solid #eee}.editormd-html-preview .editormd-toc-menu h1 .fa,.editormd-preview-container .editormd-toc-menu h1 .fa{padding-left:10px}.editormd-html-preview .editormd-toc-menu .toc-menu-btn,.editormd-preview-container .editormd-toc-menu .toc-menu-btn{color:#666;min-width:180px;padding:5px 10px;border-radius:4px;display:inline-block;-webkit-transition:background-color .5s ease-out;-moz-transition:background-color .5s ease-out;transition:background-color .5s ease-out}.editormd-html-preview .editormd-toc-menu .toc-menu-btn:hover,.editormd-preview-container .editormd-toc-menu .toc-menu-btn:hover{background-color:#f6f6f6}.editormd-html-preview .editormd-toc-menu .toc-menu-btn .fa,.editormd-preview-container .editormd-toc-menu .toc-menu-btn .fa{float:right;padding:3px 0 0 10px;font-size:1.3em}.markdown-body .editormd-toc-menu ul{padding-left:0}.markdown-body .highlight pre,.markdown-body pre{line-height:1.6}hr.editormd-page-break{border:1px dotted #ccc;font-size:0;height:2px}@media only print{hr.editormd-page-break{background:0 0;border:none;height:0}}.editormd-html-preview textarea{display:none}.editormd-html-preview hr.editormd-page-break{background:0 0;border:none;height:0}.editormd-preview-close-btn{color:#fff;padding:4px 6px;font-size:18px;-webkit-border-radius:500px;-moz-border-radius:500px;-ms-border-radius:500px;-o-border-radius:500px;border-radius:500px;display:none;background-color:#ccc;position:absolute;top:25px;right:35px;z-index:19;-webkit-transition:background-color .3s ease-out;-moz-transition:background-color .3s ease-out;transition:background-color .3s ease-out}.editormd-preview-close-btn:hover{background-color:#999}.editormd-preview-active{width:100%;padding:40px} \ No newline at end of file diff --git a/static/editor.md/editormd.amd.js b/static/editor.md/editormd.amd.js index 0eb6b603..d11e6924 100644 --- a/static/editor.md/editormd.amd.js +++ b/static/editor.md/editormd.amd.js @@ -2,20 +2,32 @@ * Editor.md * * @file editormd.amd.js - * @version v1.5.0 + * @version v1.7.17 * @description Open source online markdown editor. * @license MIT License - * @author Pandao - * {@link https://github.com/pandao/editor.md} - * @updateTime 2015-06-09 + * @author IBM Skills Network + * {@link https://github.com/ibm-skills-network/editor.md} + * @updateTime 2024-03-27 + */ + +/* + * Editor.md + * + * @file editormd.js + * @version v1.7.17 + * @description Open source online markdown editor. + * @license MIT License + * @author IBM Skills Network + * {@link https://github.com/ibm-skills-network/editor.md} + * @updateTime 2024-03-27 */ ;(function(factory) { "use strict"; - + // CommonJS/Node.js if (typeof require === "function" && typeof exports === "object" && typeof module === "object") - { + { module.exports = factory; } else if (typeof define === "function") // AMD/CMD/Sea.js @@ -26,10 +38,7 @@ var cmAddonPath = "codemirror/addon/"; var codeMirrorModules = [ - "jquery", "marked", - //"prettify", - "highlight/highlight", - "mermaid/mermaid", + "jquery", "marked", "prettify", "katex", "raphael", "underscore", "flowchart", "jqueryflowchart", "sequenceDiagram", "codemirror/lib/codemirror", @@ -87,18 +96,18 @@ ]; define(codeMirrorModules, factory); - } - else + } + else { define(["jquery"], factory); // for Sea.js } - } + } else - { + { window.editormd = factory(); } - -}(function() { + +}(function() { if (typeof define == "function" && define.amd) { $ = arguments[0]; @@ -110,70 +119,72 @@ flowchart = arguments[6]; CodeMirror = arguments[9]; } - + "use strict"; - + var $ = (typeof (jQuery) !== "undefined") ? jQuery : Zepto; if (typeof ($) === "undefined") { return ; } - + /** * editormd - * + * * @param {String} id 编辑器的ID * @param {Object} options 配置选项 Key/Value * @returns {Object} editormd 返回editormd对象 */ - - var editormd = function (id, options) { - return new editormd.fn.init(id, options); + + var editormd = function (id,author_ide_version, options) { + return new editormd.fn.init(id,author_ide_version, options); }; - + editormd.title = editormd.$name = "Editor.md"; - editormd.version = "1.5.0"; + editormd.version = "1.7.17"; editormd.homePage = "https://pandao.github.io/editor.md/"; editormd.classPrefix = "editormd-"; - + editormd.toolbarModes = { full : [ - "undo", "redo", "|", - "bold", "del", "italic", "quote", "ucwords", "uppercase", "lowercase", "|", - "h1", "h2", "h3", "h4", "h5", "h6", "|", + "undo", "redo", "|", + "bold", "del", "italic", "quote", "ucwords", "uppercase", "lowercase", "|", + "h1", "h2", "h3", "h4", "h5", "h6", "|", "list-ul", "list-ol", "hr", "|", "link", "reference-link", "image", "code", "preformatted-text", "code-block", "table", "datetime", "emoji", "html-entities", "pagebreak", "|", "goto-line", "watch", "preview", "fullscreen", "clear", "search", "|", - "help", "info" + "help", "changetheme", "info" ], simple : [ - "undo", "redo", "|", - "bold", "del", "italic", "quote", "uppercase", "lowercase", "|", - "h1", "h2", "h3", "h4", "h5", "h6", "|", + "undo", "redo", "|", + "bold", "del", "italic", "quote", "uppercase", "lowercase", "|", + "h1", "h2", "h3", "h4", "h5", "h6", "|", "list-ul", "list-ol", "hr", "|", "watch", "preview", "fullscreen", "|", - "help", "info" + "help", "changetheme", "info" ], mini : [ "undo", "redo", "|", "watch", "preview", "|", - "help", "info" + "help", "changetheme", "info" ] }; - + editormd.defaults = { + debug : false, mode : "gfm", //gfm or markdown name : "", // Form element name value : "", // value for CodeMirror, if mode not gfm/markdown theme : "", // Editor.md self themes, before v1.5.0 is CodeMirror theme, default empty editorTheme : "default", // Editor area, this is CodeMirror theme at v1.5.0 previewTheme : "", // Preview area theme, default empty - markdown : "", // Markdown source code + markdown : undefined, // Markdown source code appendMarkdown : "", // if in init textarea value not empty, append markdown to textarea width : "100%", height : "100%", path : "./lib/", // Dependents module file directory pluginPath : "", // If this empty, default use settings.path + "../plugins/" + customPluginPath : "", delay : 300, // Delay parse markdown to html, Uint : ms autoLoadModules : true, // Automatic load dependent module files watch : true, @@ -205,50 +216,55 @@ fontSize : "13px", saveHTMLToTextarea : false, disabledKeyMaps : [], - + onload : function() {}, onresize : function() {}, onchange : function() {}, onwatch : null, onunwatch : null, onpreviewing : function() {}, + onCmChange : null, + fixCodeBlocks : function() {}, // run after prettyprint(function to prettify code blocks) finished onpreviewed : function() {}, onfullscreen : function() {}, onfullscreenExit : function() {}, onscroll : function() {}, onpreviewscroll : function() {}, - + imageUpload : false, imageFormats : ["jpg", "jpeg", "gif", "png", "bmp", "webp"], imageUploadURL : "", crossDomainUpload : false, uploadCallbackURL : "", - + toc : true, // Table of contents tocm : false, // Using [TOCM], auto create ToC dropdown menu tocTitle : "", // for ToC dropdown menu btn tocDropdown : false, tocContainer : "", tocStartLevel : 1, // Said from H1 to create ToC - htmlDecode : false, // Open the HTML tag identification + htmlDecode : false, // Open the HTML tag identification pageBreak : true, // Enable parse page break [========] atLink : true, // for @link emailLink : true, // for email address auto link taskList : false, // Enable Github Flavored Markdown task lists - emoji : false, // :emoji: , Support Github emoji, Twitter Emoji (Twemoji); + emoji : true, // :emoji: , Support Github emoji, Twitter Emoji (Twemoji); // Support FontAwesome icon emoji :fa-xxx: > Using fontAwesome icon web fonts; // Support Editor.md logo icon emoji :editormd-logo: :editormd-logo-1x: > 1~8x; tex : false, // TeX(LaTeX), based on KaTeX flowChart : false, // flowChart.js only support IE9+ sequenceDiagram : false, // sequenceDiagram.js only support IE9+ - mermaidGantt : false, //mermaid/mermaid.js - mermaidSequence : false, - mermaidFlowChat : false, + mermaid : true, + mindMap : true, // 脑图 previewCodeHighlight : true, - highlightStyle : "github", - + toolbar : true, // show/hide toolbar toolbarAutoFixed : true, // on window scroll auto fixed position + titlebar : { + left: {}, + center: {}, + right: {} + }, toolbarIcons : "full", toolbarTitles : {}, toolbarHandlers : { @@ -260,9 +276,10 @@ } }, toolbarCustomIcons : { // using html tag create toolbar icon, unused default tag. - lowercase : "a", - "ucwords" : "Aa" - }, + lowercase : "a", + "ucwords" : "Aa", + "fontcase" : "Aa" + }, toolbarIconsClass : { undo : "fa-undo", redo : "fa-repeat", @@ -271,6 +288,7 @@ italic : "fa-italic", quote : "fa-quote-left", uppercase : "fa-font", + heading : "fa-header", h1 : editormd.classPrefix + "bold", h2 : editormd.classPrefix + "bold", h3 : editormd.classPrefix + "bold", @@ -299,10 +317,22 @@ fullscreen : "fa-arrows-alt", clear : "fa-eraser", help : "fa-question-circle", + changetheme : "fa-info-circle", info : "fa-info-circle" - }, - toolbarIconTexts : {}, - + }, + toolbarIconTexts : { + "ucwords" : "Capitalize", + uppercase : "Uppercase", + lowercase : "Lowercase", + h1 : "Heading 1", + h2 : "Heading 2", + h3 : "Heading 3", + h4 : "Heading 4", + h5 : "Heading 5", + h6 : "Heading 6" + }, + + // Support for other languaages (see README) lang : { name : "zh-cn", description : "开源在线Markdown编辑器
Open source online Markdown editor.", @@ -345,6 +375,7 @@ clear : "清空", search : "搜索", help : "使用帮助", + changetheme : "切换编辑主题", info : "关于" + editormd.title }, buttons : { @@ -380,11 +411,11 @@ formatNotAllowed : "错误:只允许上传图片文件,允许上传的图片文件格式有:" }, preformattedText : { - title : "添加预格式文本或代码块", + title : "添加预格式文本或代码块", emptyAlert : "错误:请填写预格式文本或代码的内容。" }, codeBlock : { - title : "添加代码块", + title : "添加代码块", selectLabel : "代码语言:", selectDefaultText : "请选择代码语言", otherLanguage : "其他语言", @@ -396,22 +427,27 @@ }, help : { title : "使用帮助" - } + }, + changetheme : { + title : "切换编辑主题" + }, } } }; - + editormd.classNames = { - tex : editormd.classPrefix + "tex" + tex : editormd.classPrefix + "tex", + texDisplay : editormd.classPrefix + "texDisaply" }; editormd.dialogZindex = 99999; - + editormd.$katex = null; editormd.$marked = null; + editormd.$filterXSS = null; editormd.$CodeMirror = null; editormd.$prettyPrint = null; - + var timer, flowchartTimer; editormd.prototype = editormd.fn = { @@ -421,76 +457,76 @@ preview : false, fullscreen : false }, - + /** * 构造函数/实例初始化 * Constructor / instance initialization - * + * * @param {String} id 编辑器的ID * @param {Object} [options={}] 配置选项 Key/Value * @returns {editormd} 返回editormd的实例对象 */ - - init : function (id, options) { - + + init : function (id, author_ide_version, options) { + options = options || {}; - + if (typeof id === "object") { options = id; } - - var _this = this; - var classPrefix = this.classPrefix = editormd.classPrefix; - var settings = this.settings = $.extend(true, editormd.defaults, options); - + + var classPrefix = this.classPrefix = editormd.classPrefix; + var settings = this.settings = $.extend(true, {}, editormd.defaults, options); + id = (typeof id === "object") ? settings.id : id; - + var editor = this.editor = $("#" + id); - + this.id = id; + this.author_ide_version = author_ide_version || editor.version; this.lang = settings.lang; - + var classNames = this.classNames = { textarea : { html : classPrefix + "html-textarea", markdown : classPrefix + "markdown-textarea" } }; - - settings.pluginPath = (settings.pluginPath === "") ? settings.path + "../plugins/" : settings.pluginPath; - + + settings.pluginPath = (settings.pluginPath === "") ? settings.path + "../plugins/" : settings.pluginPath; + this.state.watching = (settings.watch) ? true : false; - + if ( !editor.hasClass("editormd") ) { editor.addClass("editormd"); } - + editor.css({ width : (typeof settings.width === "number") ? settings.width + "px" : settings.width, height : (typeof settings.height === "number") ? settings.height + "px" : settings.height }); - + if (settings.autoHeight) { editor.css("height", "auto"); } - + var markdownTextarea = this.markdownTextarea = editor.children("textarea"); - + if (markdownTextarea.length < 1) { editor.append(""); markdownTextarea = this.markdownTextarea = editor.children("textarea"); } - + markdownTextarea.addClass(classNames.textarea.markdown).attr("placeholder", settings.placeholder); - + if (typeof markdownTextarea.attr("name") === "undefined" || markdownTextarea.attr("name") === "") { markdownTextarea.attr("name", (settings.name !== "") ? settings.name : id + "-markdown-doc"); } - + var appendElements = [ (!settings.readOnly) ? "" : "", ( (settings.saveHTMLToTextarea) ? "" : "" ), @@ -498,119 +534,115 @@ "
", "
" ].join("\n"); - + editor.append(appendElements).addClass(classPrefix + "vertical"); - - if (settings.theme !== "") + + if (settings.theme !== "") { editor.addClass(classPrefix + "theme-" + settings.theme); } - - this.mask = editor.children("." + classPrefix + "mask"); + + this.mask = editor.children("." + classPrefix + "mask"); this.containerMask = editor.children("." + classPrefix + "container-mask"); - - if (settings.markdown !== "") + + if (settings.markdown !== undefined) { markdownTextarea.val(settings.markdown); } - + if (settings.appendMarkdown !== "") { markdownTextarea.val(markdownTextarea.val() + settings.appendMarkdown); } - - this.htmlTextarea = editor.children("." + classNames.textarea.html); + + this.htmlTextarea = editor.children("." + classNames.textarea.html); this.preview = editor.children("." + classPrefix + "preview"); this.previewContainer = this.preview.children("." + classPrefix + "preview-container"); - - if (settings.previewTheme !== "") + + if (settings.previewTheme !== "") { this.preview.addClass(classPrefix + "preview-theme-" + settings.previewTheme); } - + if (typeof define === "function" && define.amd) { - if (typeof katex !== "undefined") + if (typeof katex !== "undefined") { editormd.$katex = katex; } - - if (settings.searchReplace && !settings.readOnly) + + if (settings.searchReplace && !settings.readOnly) { editormd.loadCSS(settings.path + "codemirror/addon/dialog/dialog"); editormd.loadCSS(settings.path + "codemirror/addon/search/matchesonscrollbar"); } } - + if ((typeof define === "function" && define.amd) || !settings.autoLoadModules) { if (typeof CodeMirror !== "undefined") { editormd.$CodeMirror = CodeMirror; } - + if (typeof marked !== "undefined") { editormd.$marked = marked; } - + this.setCodeMirror().setToolbar().loadedDisplay(); - } - else + } + else { this.loadQueues(); } return this; }, - + /** * 所需组件加载队列 * Required components loading queue - * + * * @returns {editormd} 返回editormd的实例对象 */ - + loadQueues : function() { - var _this = this; - var settings = this.settings; - var loadPath = settings.path; - + var _this = this; + var settings = this.settings; + var loadPath = settings.path; + var isLoadedDisplay = false; + var loadFlowChartOrSequenceDiagram = function() { - - if (editormd.isIE8) + + if (editormd.isIE8) { _this.loadedDisplay(); - + return ; } - if (settings.mermaidGantt || settings.mermaidFlowChat || settings.mermaidSequence) { - console.log("aa") - editormd.loadScript(loadPath + "mermaid/mermaid.min", function () { - _this.loadedDisplay(); - }); - } - if (settings.flowChart || settings.sequenceDiagram) + + if (settings.flowChart || settings.sequenceDiagram) { editormd.loadScript(loadPath + "raphael.min", function() { - editormd.loadScript(loadPath + "underscore.min", function() { + editormd.loadScript(loadPath + "underscore.min", function() { - if (!settings.flowChart && settings.sequenceDiagram) + if (!settings.flowChart && settings.sequenceDiagram) { editormd.loadScript(loadPath + "sequence-diagram.min", function() { _this.loadedDisplay(); }); } - else if (settings.flowChart && !settings.sequenceDiagram) - { - editormd.loadScript(loadPath + "flowchart.min", function() { + else if (settings.flowChart && !settings.sequenceDiagram) + { + editormd.loadScript(loadPath + "flowchart.min", function() { editormd.loadScript(loadPath + "jquery.flowchart.min", function() { _this.loadedDisplay(); }); }); } - else if (settings.flowChart && settings.sequenceDiagram) - { - editormd.loadScript(loadPath + "flowchart.min", function() { + else if (settings.flowChart && settings.sequenceDiagram) + { + editormd.loadScript(loadPath + "flowchart.min", function() { editormd.loadScript(loadPath + "jquery.flowchart.min", function() { editormd.loadScript(loadPath + "sequence-diagram.min", function() { _this.loadedDisplay(); @@ -621,160 +653,168 @@ }); }); - } + } else { _this.loadedDisplay(); } - }; + }; + + editormd.loadScript(loadPath + "xss", function () { + editormd.$filterXSS = filterXSS + }); editormd.loadCSS(loadPath + "codemirror/codemirror.min"); - + if (settings.searchReplace && !settings.readOnly) { editormd.loadCSS(loadPath + "codemirror/addon/dialog/dialog"); editormd.loadCSS(loadPath + "codemirror/addon/search/matchesonscrollbar"); } - + if (settings.codeFold) { - editormd.loadCSS(loadPath + "codemirror/addon/fold/foldgutter"); + editormd.loadCSS(loadPath + "codemirror/addon/fold/foldgutter"); } - + editormd.loadScript(loadPath + "codemirror/codemirror.min", function() { editormd.$CodeMirror = CodeMirror; - + editormd.loadScript(loadPath + "codemirror/modes.min", function() { - + editormd.loadScript(loadPath + "codemirror/addons.min", function() { - + _this.setCodeMirror(); - - if (settings.mode !== "gfm" && settings.mode !== "markdown") + + if (settings.mode !== "gfm" && settings.mode !== "markdown") { _this.loadedDisplay(); - + return false; } - + _this.setToolbar(); editormd.loadScript(loadPath + "marked.min", function() { editormd.$marked = marked; - - if (settings.previewCodeHighlight) + + if(!settings.highlightStyle){ + settings.highlightStyle = "github"; + } + if (settings.previewCodeHighlight) { // editormd.loadScript(loadPath + "prettify.min", function() { // loadFlowChartOrSequenceDiagram(); // }); + editormd.loadCSS(loadPath + "highlight/styles/" + settings.highlightStyle); editormd.loadScript(loadPath + "highlight/highlight", function() { loadFlowChartOrSequenceDiagram(); }); - } + } else - { + { loadFlowChartOrSequenceDiagram(); } }); - + }); - + }); - + }); return this; }, - + /** * 设置 Editor.md 的整体主题,主要是工具栏 * Setting Editor.md theme - * + * * @returns {editormd} 返回editormd的实例对象 */ - + setTheme : function(theme) { var editor = this.editor; var oldTheme = this.settings.theme; var themePrefix = this.classPrefix + "theme-"; - + editor.removeClass(themePrefix + oldTheme).addClass(themePrefix + theme); - + this.settings.theme = theme; - + return this; }, - + /** * 设置 CodeMirror(编辑区)的主题 * Setting CodeMirror (Editor area) theme - * + * * @returns {editormd} 返回editormd的实例对象 */ - - setEditorTheme : function(theme) { - var settings = this.settings; - settings.editorTheme = theme; - + + setEditorTheme : function(theme) { + var settings = this.settings; + settings.editorTheme = theme; + if (theme !== "default") { editormd.loadCSS(settings.path + "codemirror/theme/" + settings.editorTheme); } - + this.cm.setOption("theme", theme); - + return this; }, - + /** * setEditorTheme() 的别名 * setEditorTheme() alias - * + * * @returns {editormd} 返回editormd的实例对象 */ - - setCodeMirrorTheme : function (theme) { + + setCodeMirrorTheme : function (theme) { this.setEditorTheme(theme); - + return this; }, - + /** * 设置 Editor.md 的主题 * Setting Editor.md theme - * + * * @returns {editormd} 返回editormd的实例对象 */ - - setPreviewTheme : function(theme) { + + setPreviewTheme : function(theme) { var preview = this.preview; var oldTheme = this.settings.previewTheme; var themePrefix = this.classPrefix + "preview-theme-"; - + preview.removeClass(themePrefix + oldTheme).addClass(themePrefix + theme); - + this.settings.previewTheme = theme; - + return this; }, - + /** * 配置和初始化CodeMirror组件 * CodeMirror initialization - * + * * @returns {editormd} 返回editormd的实例对象 */ - - setCodeMirror : function() { + + setCodeMirror : function() { var settings = this.settings; var editor = this.editor; - + if (settings.editorTheme !== "default") { editormd.loadCSS(settings.path + "codemirror/theme/" + settings.editorTheme); } - + var codeMirrorConfig = { mode : settings.mode, theme : settings.editorTheme, @@ -787,8 +827,8 @@ lineNumbers : settings.lineNumbers, lineWrapping : settings.lineWrapping, extraKeys : { - "Ctrl-Q": function(cm) { - cm.foldCode(cm.getCursor()); + "Ctrl-Q": function(cm) { + cm.foldCode(cm.getCursor()); } }, foldGutter : settings.codeFold, @@ -801,10 +841,10 @@ showTrailingSpace : settings.showTrailingSpace, highlightSelectionMatches : ( (!settings.matchWordHighlight) ? false : { showToken: (settings.matchWordHighlight === "onselected") ? false : /\w/ } ) }; - + this.codeEditor = this.cm = editormd.$CodeMirror.fromTextArea(this.markdownTextarea[0], codeMirrorConfig); this.codeMirror = this.cmElement = editor.children(".CodeMirror"); - + if (settings.value !== "") { this.cm.setValue(settings.value); @@ -814,13 +854,13 @@ fontSize : settings.fontSize, width : (!settings.watch) ? "100%" : "50%" }); - + if (settings.autoHeight) { this.codeMirror.css("height", "auto"); this.cm.setOption("viewportMargin", Infinity); } - + if (!settings.lineNumbers) { this.codeMirror.find(".CodeMirror-gutters").css("border-right", "none"); @@ -828,149 +868,149 @@ return this; }, - + /** * 获取CodeMirror的配置选项 * Get CodeMirror setting options - * + * * @returns {Mixed} return CodeMirror setting option value */ - - getCodeMirrorOption : function(key) { + + getCodeMirrorOption : function(key) { return this.cm.getOption(key); }, - + /** * 配置和重配置CodeMirror的选项 * CodeMirror setting options / resettings - * + * * @returns {editormd} 返回editormd的实例对象 */ - + setCodeMirrorOption : function(key, value) { - + this.cm.setOption(key, value); - + return this; }, - + /** * 添加 CodeMirror 键盘快捷键 * Add CodeMirror keyboard shortcuts key map - * + * * @returns {editormd} 返回editormd的实例对象 */ - + addKeyMap : function(map, bottom) { this.cm.addKeyMap(map, bottom); - + return this; }, - + /** * 移除 CodeMirror 键盘快捷键 * Remove CodeMirror keyboard shortcuts key map - * + * * @returns {editormd} 返回editormd的实例对象 */ - + removeKeyMap : function(map) { this.cm.removeKeyMap(map); - + return this; }, - + /** * 跳转到指定的行 * Goto CodeMirror line - * + * * @param {String|Intiger} line line number or "first"|"last" * @returns {editormd} 返回editormd的实例对象 */ - + gotoLine : function (line) { - + var settings = this.settings; - + if (!settings.gotoLine) { return this; } - + var cm = this.cm; var editor = this.editor; var count = cm.lineCount(); var preview = this.preview; - + if (typeof line === "string") { if(line === "last") { line = count; } - + if (line === "first") { line = 1; } } - - if (typeof line !== "number") - { + + if (typeof line !== "number") + { alert("Error: The line number must be an integer."); return this; } - + line = parseInt(line) - 1; - + if (line > count) { alert("Error: The line number range 1-" + count); - + return this; } - + cm.setCursor( {line : line, ch : 0} ); - + var scrollInfo = cm.getScrollInfo(); - var clientHeight = scrollInfo.clientHeight; + var clientHeight = scrollInfo.clientHeight; var coords = cm.charCoords({line : line, ch : 0}, "local"); - + cm.scrollTo(null, (coords.top + coords.bottom - clientHeight) / 2); - + if (settings.watch) - { + { var cmScroll = this.codeMirror.find(".CodeMirror-scroll")[0]; - var height = $(cmScroll).height(); - var scrollTop = cmScroll.scrollTop; + var height = $(cmScroll).height(); + var scrollTop = cmScroll.scrollTop; var percent = (scrollTop / cmScroll.scrollHeight); if (scrollTop === 0) { preview.scrollTop(0); - } + } else if (scrollTop + height >= cmScroll.scrollHeight - 16) - { - preview.scrollTop(preview[0].scrollHeight); - } + { + preview.scrollTop(preview[0].scrollHeight); + } else - { + { preview.scrollTop(preview[0].scrollHeight * percent); } } cm.focus(); - + return this; }, - + /** * 扩展当前实例对象,可同时设置多个或者只设置一个 * Extend editormd instance object, can mutil setting. - * + * * @returns {editormd} this(editormd instance object.) */ - + extend : function() { if (typeof arguments[1] !== "undefined") { @@ -981,7 +1021,7 @@ this[arguments[0]] = arguments[1]; } - + if (typeof arguments[0] === "object" && typeof arguments[0].length === "undefined") { $.extend(true, this, arguments[0]); @@ -989,168 +1029,168 @@ return this; }, - + /** * 设置或扩展当前实例对象,单个设置 * Extend editormd instance object, one by one - * + * * @param {String|Object} key option key * @param {String|Object} value option value * @returns {editormd} this(editormd instance object.) */ - + set : function (key, value) { - + if (typeof value !== "undefined" && typeof value === "function") { value = $.proxy(value, this); } - + this[key] = value; return this; }, - + /** * 重新配置 * Resetting editor options - * + * * @param {String|Object} key option key * @param {String|Object} value option value * @returns {editormd} this(editormd instance object.) */ - + config : function(key, value) { var settings = this.settings; - + if (typeof key === "object") { settings = $.extend(true, settings, key); } - + if (typeof key === "string") { settings[key] = value; } - + this.settings = settings; this.recreate(); - + return this; }, - + /** * 注册事件处理方法 * Bind editor event handle - * + * * @param {String} eventType event type * @param {Function} callback 回调函数 * @returns {editormd} this(editormd instance object.) */ - + on : function(eventType, callback) { var settings = this.settings; - - if (typeof settings["on" + eventType] !== "undefined") - { - settings["on" + eventType] = $.proxy(callback, this); + + if (typeof settings["on" + eventType] !== "undefined") + { + settings["on" + eventType] = $.proxy(callback, this); } return this; }, - + /** * 解除事件处理方法 * Unbind editor event handle - * + * * @param {String} eventType event type * @returns {editormd} this(editormd instance object.) */ - + off : function(eventType) { var settings = this.settings; - - if (typeof settings["on" + eventType] !== "undefined") + + if (typeof settings["on" + eventType] !== "undefined") { settings["on" + eventType] = function(){}; } - + return this; }, - + /** * 显示工具栏 * Display toolbar - * + * * @param {Function} [callback=function(){}] 回调函数 * @returns {editormd} 返回editormd的实例对象 */ - + showToolbar : function(callback) { var settings = this.settings; - + if(settings.readOnly) { return this; } - + if (settings.toolbar && (this.toolbar.length < 1 || this.toolbar.find("." + this.classPrefix + "menu").html() === "") ) { this.setToolbar(); } - - settings.toolbar = true; - + + settings.toolbar = true; + this.toolbar.show(); this.resize(); - + $.proxy(callback || function(){}, this)(); return this; }, - + /** * 隐藏工具栏 * Hide toolbar - * + * * @param {Function} [callback=function(){}] 回调函数 * @returns {editormd} this(editormd instance object.) */ - - hideToolbar : function(callback) { + + hideToolbar : function(callback) { var settings = this.settings; - - settings.toolbar = false; + + settings.toolbar = false; this.toolbar.hide(); this.resize(); - + $.proxy(callback || function(){}, this)(); return this; }, - + /** * 页面滚动时工具栏的固定定位 * Set toolbar in window scroll auto fixed position - * + * * @returns {editormd} 返回editormd的实例对象 */ - + setToolbarAutoFixed : function(fixed) { - + var state = this.state; var editor = this.editor; var toolbar = this.toolbar; var settings = this.settings; - + if (typeof fixed !== "undefined") { settings.toolbarAutoFixed = fixed; } - + var autoFixedHandle = function(){ var $window = $(window); var top = $window.scrollTop(); - + if (!settings.toolbarAutoFixed) { return false; @@ -1173,7 +1213,7 @@ }); } }; - + if (!state.fullscreen && !state.preview && settings.toolbar && settings.toolbarAutoFixed) { $(window).bind("scroll", autoFixedHandle); @@ -1181,158 +1221,279 @@ return this; }, - + /** * 配置和初始化工具栏 * Set toolbar and Initialization - * + * * @returns {editormd} 返回editormd的实例对象 */ - + setToolbar : function() { - var settings = this.settings; - + var settings = this.settings; + if(settings.readOnly) { return this; } - - var editor = this.editor; - var preview = this.preview; - var classPrefix = this.classPrefix; - + + var editor = this.editor; + var preview = this.preview; + var classPrefix = this.classPrefix; // this.classPrefix = "editormd-" + var titlebarModes = (typeof settings.titlebar === "function") ? settings.titlebar() : settings.titlebar; + var toolbar = this.toolbar = editor.children("." + classPrefix + "toolbar"); - + if (settings.toolbar && toolbar.length < 1) - { - var toolbarHTML = "
    "; - + { + var toolbarHTML = "
    \ +
    \ +
    \ +
    \ +
      \ +
      \ +
      "; + editor.append(toolbarHTML); toolbar = this.toolbar = editor.children("." + classPrefix + "toolbar"); } - - if (!settings.toolbar) + + if (!settings.toolbar) { toolbar.hide(); - + return this; } - + + // Store html for titlebar + var titlebarContent = ""; + + // for each titlebar section + Object.entries(titlebarModes).forEach(([titlebarSection, sectionButtons]) => { + + var sectionHtml = ""; + + if (titlebarSection === "left") { + // set logo and Author IDE title + sectionHtml = "Skills Network Author IDE"; + } else { + // for each item in the section, add HTML to sectionHTML + for (var name in sectionButtons) { + var htmlSafeName = name.replace(/\s+/g, '-').toLowerCase(); + var hoverTitle = (typeof settings.lang.titlebar[name] === "string") ? settings.lang.titlebar[name] : ""; + + switch (sectionButtons[name]) { + case "dropdown": + sectionHtml += "
      \ + \ +
      \ +
      "; + break; + case "button": + sectionHtml += ""; + break; + default: + sectionHtml += "" + + name + ""; + }; + } + } + + // add generated html for the section to the titlebar + titlebarContent += "
      " + sectionHtml + "
      "; + + }); + + // Set html for titlebar + toolbar.find("div." + classPrefix + "titlebar-container").html(titlebarContent); + + + // Set toolbar icons toolbar.show(); - - var icons = (typeof settings.toolbarIcons === "function") ? settings.toolbarIcons() + + var icons = (typeof settings.toolbarIcons === "function") ? settings.toolbarIcons() : ((typeof settings.toolbarIcons === "string") ? editormd.toolbarModes[settings.toolbarIcons] : settings.toolbarIcons); - + var toolbarMenu = toolbar.find("." + this.classPrefix + "menu"), menu = ""; var pullRight = false; - + for (var i = 0, len = icons.length; i < len; i++) { var name = icons[i]; - if (name === "||") - { + if (name === "||") + { pullRight = true; - } + } else if (name === "|") { - menu += "
    • |
    • "; + menu += "
    • "; } else { - var isHeader = (/h(\d)/.test(name)); - var index = name; - - if (name === "watch" && !settings.watch) { - index = "unwatch"; - } - - var title = settings.lang.toolbar[index]; - var iconTexts = settings.toolbarIconTexts[index]; - var iconClass = settings.toolbarIconsClass[index]; - - title = (typeof title === "undefined") ? "" : title; - iconTexts = (typeof iconTexts === "undefined") ? "" : iconTexts; - iconClass = (typeof iconClass === "undefined") ? "" : iconClass; + var isDropdown = name.includes("dropdown"); - var menuItem = pullRight ? "
    • " : "
    • "; - - if (typeof settings.toolbarCustomIcons[name] !== "undefined" && typeof settings.toolbarCustomIcons[name] !== "function") - { - menuItem += settings.toolbarCustomIcons[name]; + // add classes for menu item + var menuClasses = [] + if (pullRight) { + menuClasses.push("pull-right"); } - else - { - menuItem += ""; - menuItem += ""+((isHeader) ? name.toUpperCase() : ( (iconClass === "") ? iconTexts : "") ) + ""; + if (isDropdown) { + menuClasses.push("dropdown"); + } + + // stores HTML for current menu item; add opening tag + var menuItem = (menuClasses.length > 0) ? "
    • " : "
    • "; + + // list of icons in menu item (usually just one unless dropdown) + var selections = [] + + if (isDropdown) { + var info = name.split(":"); + var dropdownType = info[0]; // "dropdown", "dropdownIcon" + name = info[1]; // set name to actual parsed name from info + var dropdownContent = info[2].split(","); + selections = [name].concat(dropdownContent); + // set isDropdown to false if no dropdown content + if (!dropdownContent.length) { + isDropdown = false; + } + } else { + selections.push(name) + } + + for (var j = 0, len = selections.length; j < len; j++) { + name = selections[j].trim(); + + // insert dropdown opening tag + if (isDropdown && j === 1) { + menuItem += "
      "; + } + + // default "dropdown" has no icons in content, use "dropdownIcon" for icon+text options + var hasIcon = !(isDropdown && dropdownType !== "dropdownIcon" && menuItem.includes("toolbar-dropdown-content")); + var isHeader = (/h(\d)/.test(name)); + var index = name; + + if (name === "watch" && !settings.watch) { + index = "unwatch"; + } + + var title = settings.lang.toolbar[index]; // hover text + var iconTexts = settings.toolbarIconTexts[index]; // placeholder text if icon is empty + var iconClass = settings.toolbarIconsClass[index]; // font awesome icon class + + title = (typeof title === "undefined" || isDropdown) ? "" : title; + iconTexts = (typeof iconTexts === "undefined") ? "" : iconTexts; + iconClass = (typeof iconClass === "undefined" || !hasIcon) ? "" : iconClass; + + + menuItem += ""; + + // add custom icon + if (hasIcon && typeof settings.toolbarCustomIcons[name] !== "undefined" && typeof settings.toolbarCustomIcons[name] !== "function") + { + menuItem += settings.toolbarCustomIcons[name]; + } + // add icon content + else + { + menuItem += ""; + + if (typeof settings.toolbarIcons !== "function" && isHeader) { + menuItem += "" + name.toUpperCase() + ""; + } else if (dropdownType && dropdownType === "dropdownIcon" && menuItem.includes("toolbar-dropdown-content")) { + menuItem += "" + (iconTexts ? iconTexts : name) + ""; + } else if (iconClass === "" || !hasIcon) { + menuItem += "" + (iconTexts ? iconTexts : name) + ""; + } + + menuItem += ""; + } + menuItem += ""; + + // insert dropdown closing tag + if (isDropdown && j === len - 1 && menuItem.includes("toolbar-dropdown-content")) { + menuItem += "
      "; + dropdownType = ""; + } } + // add closing tag and append to toolbar menuItem += "
    • "; - menu = pullRight ? menuItem + menu : menu + menuItem; } } toolbarMenu.html(menu); - + toolbarMenu.find("[title=\"Lowercase\"]").attr("title", settings.lang.toolbar.lowercase); toolbarMenu.find("[title=\"ucwords\"]").attr("title", settings.lang.toolbar.ucwords); - + this.setToolbarHandler(); this.setToolbarAutoFixed(); return this; }, - + /** * 工具栏图标事件处理对象序列 * Get toolbar icons event handlers - * + * * @param {Object} cm CodeMirror的实例对象 * @param {String} name 要获取的事件处理器名称 * @returns {Object} 返回处理对象序列 */ - + dialogLockScreen : function() { $.proxy(editormd.dialogLockScreen, this)(); - + return this; }, dialogShowMask : function(dialog) { $.proxy(editormd.dialogShowMask, this)(dialog); - + return this; }, - - getToolbarHandles : function(name) { + positionDialog : function(dialog, position) { + $.proxy(editormd.positionDialog, this)(dialog, position); + + return this; + }, + + getToolbarHandles : function(name) { var toolbarHandlers = this.toolbarHandlers = editormd.toolbarHandlers; - + return (name && typeof toolbarIconHandlers[name] !== "undefined") ? toolbarHandlers[name] : toolbarHandlers; }, - + /** * 工具栏图标事件处理器 - * Bind toolbar icons event handle - * + * Bind toolbar icons to their event handlers + * * @returns {editormd} 返回editormd的实例对象 */ - + setToolbarHandler : function() { var _this = this; var settings = this.settings; - + if (!settings.toolbar || settings.readOnly) { return this; } - + var toolbar = this.toolbar; var cm = this.cm; - var classPrefix = this.classPrefix; - var toolbarIcons = this.toolbarIcons = toolbar.find("." + classPrefix + "menu > li > a"); - var toolbarIconHandlers = this.getToolbarHandles(); - - toolbarIcons.bind(editormd.mouseOrTouch("click", "touchend"), function(event) { + var classPrefix = this.classPrefix; + var toolbarIcons = this.toolbarIcons = toolbar.find("." + classPrefix + "menu > li a"); + var toolbarIconHandlers = this.getToolbarHandles(); + + toolbarIcons.bind(editormd.mouseOrTouch("click", "touchend"), function() { var icon = $(this).children(".fa"); var name = icon.attr("name"); @@ -1342,23 +1503,23 @@ if (name === "") { return ; } - + _this.activeIcon = icon; - if (typeof toolbarIconHandlers[name] !== "undefined") + if (typeof toolbarIconHandlers[name] !== "undefined") { $.proxy(toolbarIconHandlers[name], _this)(cm); } - else + else { - if (typeof settings.toolbarHandlers[name] !== "undefined") + if (typeof settings.toolbarHandlers[name] !== "undefined") { $.proxy(settings.toolbarHandlers[name], _this)(cm, icon, cursor, selection); } } - - if (name !== "link" && name !== "reference-link" && name !== "image" && name !== "code-block" && - name !== "preformatted-text" && name !== "watch" && name !== "preview" && name !== "search" && name !== "fullscreen" && name !== "info") + + if (name !== "link" && name !== "reference-link" && name !== "image" && name !== "code-block" && + name !== "preformatted-text" && name !== "watch" && name !== "preview" && name !== "search" && name !== "fullscreen" && name !== "info") { cm.focus(); } @@ -1369,31 +1530,31 @@ return this; }, - + /** * 动态创建对话框 * Creating custom dialogs - * + * * @param {Object} options 配置项键值对 Key/Value * @returns {dialog} 返回创建的dialog的jQuery实例对象 */ - - createDialog : function(options) { + + createDialog : function(options) { return $.proxy(editormd.createDialog, this)(options); }, - + /** * 创建关于Editor.md的对话框 * Create about Editor.md dialog - * + * * @returns {editormd} 返回editormd的实例对象 */ - + createInfoDialog : function() { var _this = this; - var editor = this.editor; - var classPrefix = this.classPrefix; - + var editor = this.editor; + var classPrefix = this.classPrefix; + var infoDialogHTML = [ "
      ", "
      ", @@ -1407,30 +1568,30 @@ ].join("\n"); editor.append(infoDialogHTML); - + var infoDialog = this.infoDialog = editor.children("." + classPrefix + "dialog-info"); infoDialog.find("." + classPrefix + "dialog-close").bind(editormd.mouseOrTouch("click", "touchend"), function() { _this.hideInfoDialog(); }); - + infoDialog.css("border", (editormd.isIE8) ? "1px solid #ddd" : "").css("z-index", editormd.dialogZindex).show(); - + this.infoDialogPosition(); return this; }, - + /** * 关于Editor.md对话居中定位 * Editor.md dialog position handle - * + * * @returns {editormd} 返回editormd的实例对象 */ - + infoDialogPosition : function() { var infoDialog = this.infoDialog; - + var _infoDialogPosition = function() { infoDialog.css({ top : ($(window).height() - infoDialog.height()) / 2 + "px", @@ -1441,33 +1602,33 @@ _infoDialogPosition(); $(window).resize(_infoDialogPosition); - + return this; }, - + /** * 显示关于Editor.md * Display about Editor.md dialog - * + * * @returns {editormd} 返回editormd的实例对象 */ - + showInfoDialog : function() { $("html,body").css("overflow-x", "hidden"); - + var _this = this; - var editor = this.editor; - var settings = this.settings; + var editor = this.editor; + var settings = this.settings; var infoDialog = this.infoDialog = editor.children("." + this.classPrefix + "dialog-info"); - + if (infoDialog.length < 1) { this.createInfoDialog(); } - + this.lockScreen(true); - + this.mask.css({ opacity : settings.dialogMaskOpacity, backgroundColor : settings.dialogMaskBgColor @@ -1479,15 +1640,15 @@ return this; }, - + /** * 隐藏关于Editor.md * Hide about Editor.md dialog - * + * * @returns {editormd} 返回editormd的实例对象 */ - - hideInfoDialog : function() { + + hideInfoDialog : function() { $("html,body").css("overflow-x", ""); this.infoDialog.hide(); this.mask.hide(); @@ -1495,143 +1656,186 @@ return this; }, - + /** * 锁屏 * lock screen - * + * * @param {Boolean} lock Boolean 布尔值,是否锁屏 * @returns {editormd} 返回editormd的实例对象 */ - + lockScreen : function(lock) { editormd.lockScreen(lock); this.resize(); return this; }, - + /** * 编辑器界面重建,用于动态语言包或模块加载等 * Recreate editor - * + * * @returns {editormd} 返回editormd的实例对象 */ - + recreate : function() { var _this = this; var editor = this.editor; var settings = this.settings; - + this.codeMirror.remove(); - + this.setCodeMirror(); - if (!settings.readOnly) + if (!settings.readOnly) { if (editor.find(".editormd-dialog").length > 0) { editor.find(".editormd-dialog").remove(); } - - if (settings.toolbar) - { - this.getToolbarHandles(); + + if (settings.toolbar) + { + this.getToolbarHandles(); this.setToolbar(); } } - + this.loadedDisplay(true); return this; }, - + /** * 高亮预览HTML的pre代码部分 * highlight of preview codes - * + * * @returns {editormd} 返回editormd的实例对象 */ - - previewCodeHighlight : function() { + + previewCodeHighlight : function() { var settings = this.settings; var previewContainer = this.previewContainer; - - if (settings.previewCodeHighlight) + + if (settings.previewCodeHighlight) { - // previewContainer.find("pre").addClass("prettyprint"); - // - // if (typeof prettyPrint !== "undefined") - // { - // prettyPrint(); - // } - if (typeof hljs !== "undefined") { - previewContainer.find('pre').each(function (i, block) { - hljs.highlightBlock(block); - }); + previewContainer.find("pre").addClass("prettyprint linenums"); + + if (typeof prettyPrint !== "undefined") + { + prettyPrint($.proxy(settings.fixCodeBlocks,this)); } + previewContainer.find("pre").each(function (i, block) { + hljs.highlightBlock(block); + }); } return this; }, - + /** * 解析TeX(KaTeX)科学公式 * TeX(KaTeX) Renderer - * + * * @returns {editormd} 返回editormd的实例对象 */ - + katexRender : function() { - + if (timer === null) { return this; } - + this.previewContainer.find("." + editormd.classNames.tex).each(function(){ var tex = $(this); - editormd.$katex.render(tex.text(), tex[0]); - + editormd.$katex.render(tex.text(), tex[0],{ + throwOnError: false, + }); + tex.find(".katex").css("font-size", "1.6em"); - }); + }); + + this.previewContainer.find("." + editormd.classNames.texDisplay).each(function(){ + var tex = $(this); + editormd.$katex.render(tex.text(), tex[0],{ + throwOnError: false, + displayMode: true, + }); + + tex.find(".katex").css("font-size", "1.6em"); + }); return this; }, - + + + /** + * 解析思维导图 - 2020-04-12 + * + * @returns {editormd} 返回editormd的实例对象 + */ + mindmapRender:function(){ + this.previewContainer.find(".mindmap").each(function(){ + var mmap = $(this); + var md_data = window.markmap.transform(mmap.text().trim()); + window.markmap.markmap("svg#"+this.id,md_data) + }); + + return this; + }, + /** * 解析和渲染流程图及时序图 * FlowChart and SequenceDiagram Renderer - * + * * @returns {editormd} 返回editormd的实例对象 */ - + flowChartAndSequenceDiagramRender : function() { var $this = this; var settings = this.settings; var previewContainer = this.previewContainer; - + if (editormd.isIE8) { return this; } + if (settings.mermaid) { + var mermaid = previewContainer.find(".lang-mermaid"); + if (mermaid) { + try { + window.mermaid.init(void 0, mermaid.removeClass("hide")); + }catch (e) { + console.log(e); + } + } + } if (settings.flowChart) { if (flowchartTimer === null) { return this; } - - previewContainer.find(".flowchart").flowChart(); + try { + previewContainer.find(".flowchart").flowChart(); + }catch (e) { + console.log(e); + } } if (settings.sequenceDiagram) { - previewContainer.find(".sequence-diagram").sequenceDiagram({theme: "simple"}); + try { + previewContainer.find(".sequence-diagram").sequenceDiagram({theme: "simple"}); + }catch (e) { + console.log(e); + } } - + var preview = $this.preview; var codeMirror = $this.codeMirror; var codeView = codeMirror.find(".CodeMirror-scroll"); var height = codeView.height(); - var scrollTop = codeView.scrollTop(); + var scrollTop = codeView.scrollTop(); var percent = (scrollTop / codeView[0].scrollHeight); var tocHeight = 0; @@ -1639,43 +1843,43 @@ tocHeight += $(this).height(); }); - var tocMenuHeight = preview.find(".editormd-toc-menu").height(); + var tocMenuHeight = preview.find(".editormd-toc-menu").height(); tocMenuHeight = (!tocMenuHeight) ? 0 : tocMenuHeight; - if (scrollTop === 0) + if (scrollTop === 0) { preview.scrollTop(0); - } + } else if (scrollTop + height >= codeView[0].scrollHeight - 16) - { - preview.scrollTop(preview[0].scrollHeight); - } + { + preview.scrollTop(preview[0].scrollHeight); + } else - { + { preview.scrollTop((preview[0].scrollHeight + tocHeight + tocMenuHeight) * percent); } return this; }, - + /** * 注册键盘快捷键处理 * Register CodeMirror keyMaps (keyboard shortcuts). - * + * * @param {Object} keyMap KeyMap key/value {"(Ctrl/Shift/Alt)-Key" : function(){}} * @returns {editormd} return this */ - + registerKeyMaps : function(keyMap) { - + var _this = this; var cm = this.cm; var settings = this.settings; var toolbarHandlers = editormd.toolbarHandlers; var disabledKeyMaps = settings.disabledKeyMaps; - + keyMap = keyMap || null; - + if (keyMap) { for (var i in keyMap) @@ -1695,7 +1899,7 @@ { var _keyMap = editormd.keyMaps[k]; var handle = (typeof _keyMap === "string") ? $.proxy(toolbarHandlers[_keyMap], _this) : $.proxy(_keyMap, _this); - + if ($.inArray(k, ["F9", "F10", "F11"]) < 0 && $.inArray(k, disabledKeyMaps) < 0) { var _map = {}; @@ -1704,15 +1908,15 @@ cm.addKeyMap(_map); } } - + $(window).keydown(function(event) { - + var keymaps = { "120" : "F9", "121" : "F10", "122" : "F11" }; - + if ( $.inArray(keymaps[event.keyCode], disabledKeyMaps) < 0 ) { switch (event.keyCode) @@ -1721,17 +1925,17 @@ $.proxy(toolbarHandlers["watch"], _this)(); return false; break; - + case 121: $.proxy(toolbarHandlers["preview"], _this)(); return false; - break; - + break; + case 122: - $.proxy(toolbarHandlers["fullscreen"], _this)(); + $.proxy(toolbarHandlers["fullscreen"], _this)(); return false; - break; - + break; + default: break; } @@ -1741,54 +1945,57 @@ return this; }, - + /** * 绑定同步滚动 - * + * * @returns {editormd} return this */ - + bindScrollEvent : function() { - + var _this = this; - var preview = this.preview; + // var preview = this.preview; + var preview = this.previewContainer; var settings = this.settings; var codeMirror = this.codeMirror; var mouseOrTouch = editormd.mouseOrTouch; - + if (!settings.syncScrolling) { return this; } - - var cmBindScroll = function() { - codeMirror.find(".CodeMirror-scroll").bind(mouseOrTouch("scroll", "touchmove"), function(event) { - var height = $(this).height(); - var scrollTop = $(this).scrollTop(); - var percent = (scrollTop / $(this)[0].scrollHeight); - - var tocHeight = 0; - - preview.find(".markdown-toc-list").each(function(){ - tocHeight += $(this).height(); - }); - - var tocMenuHeight = preview.find(".editormd-toc-menu").height(); - tocMenuHeight = (!tocMenuHeight) ? 0 : tocMenuHeight; - if (scrollTop === 0) - { - preview.scrollTop(0); - } - else if (scrollTop + height >= $(this)[0].scrollHeight - 16) - { - preview.scrollTop(preview[0].scrollHeight); - } - else - { - preview.scrollTop((preview[0].scrollHeight + tocHeight + tocMenuHeight) * percent); + var cmBindScroll = function() { + codeMirror.find(".CodeMirror-scroll").bind(mouseOrTouch("scroll", "touchmove"), function(event) { + if (timer == null){ + var height = $(this).height(); + var scrollTop = $(this).scrollTop(); + var percent = (scrollTop / $(this)[0].scrollHeight); + + var tocHeight = 0; + + preview.find(".markdown-toc-list").each(function(){ + tocHeight += $(this).height(); + }); + + var tocMenuHeight = preview.find(".editormd-toc-menu").height(); + tocMenuHeight = (!tocMenuHeight) ? 0 : tocMenuHeight; + + if (scrollTop === 0) + { + preview.scrollTop(0); + } + else if (scrollTop + height >= $(this)[0].scrollHeight - 16) + { + preview.scrollTop(preview[0].scrollHeight); + } + else + { + preview.scrollTop((preview[0].scrollHeight + tocHeight + tocMenuHeight) * percent); + } + + $.proxy(settings.onscroll, _this)(event); } - - $.proxy(settings.onscroll, _this)(event); }); }; @@ -1797,34 +2004,34 @@ }; var previewBindScroll = function() { - - preview.bind(mouseOrTouch("scroll", "touchmove"), function(event) { - var height = $(this).height(); - var scrollTop = $(this).scrollTop(); - var percent = (scrollTop / $(this)[0].scrollHeight); - var codeView = codeMirror.find(".CodeMirror-scroll"); - if(scrollTop === 0) - { - codeView.scrollTop(0); + preview.bind(mouseOrTouch("scroll", "touchmove"), function(event) { + if (timer == null){ + var height = $(this).height(); + var scrollTop = $(this).scrollTop(); + var percent = (scrollTop / $(this)[0].scrollHeight); + var codeView = codeMirror.find(".CodeMirror-scroll"); + + if(scrollTop === 0) + { + codeView.scrollTop(0); + } + else if (scrollTop + height >= $(this)[0].scrollHeight) + { + codeView.scrollTop(codeView[0].scrollHeight); + } + else + { + codeView.scrollTop(codeView[0].scrollHeight * percent); + } + $.proxy(settings.onpreviewscroll, _this)(event); } - else if (scrollTop + height >= $(this)[0].scrollHeight) - { - codeView.scrollTop(codeView[0].scrollHeight); - } - else - { - codeView.scrollTop(codeView[0].scrollHeight * percent); - } - - $.proxy(settings.onpreviewscroll, _this)(event); }); }; - var previewUnbindScroll = function() { preview.unbind(mouseOrTouch("scroll", "touchmove")); - }; + }; codeMirror.bind({ mouseover : cmBindScroll, @@ -1832,12 +2039,14 @@ touchstart : cmBindScroll, touchend : cmUnbindScroll }); - + if (settings.syncScrolling === "single") { + // cmBindScroll(); return this; } - - preview.bind({ + + // previewBindScroll(); + preview.bind({ mouseover : previewBindScroll, mouseout : previewUnbindScroll, touchstart : previewBindScroll, @@ -1846,26 +2055,27 @@ return this; }, - + bindChangeEvent : function() { - + var _this = this; var cm = this.cm; var settings = this.settings; - - if (!settings.syncScrolling) { - return this; - } - + + // if (!settings.syncScrolling) { + // return this; + // } + cm.on("change", function(_cm, changeObj) { - + // console.log("cmChange") if (settings.watch) { _this.previewContainer.css("padding", settings.autoHeight ? "20px 20px 50px 40px" : "20px"); } - + if (timer) clearTimeout(timer); + if (settings.onCmChange) $.proxy(settings.onCmChange, _this)(); timer = setTimeout(function() { - clearTimeout(timer); + // console.log("cmChangeinsideTimeout") _this.save(); timer = null; }, settings.delay); @@ -1873,528 +2083,549 @@ return this; }, - + /** * 加载队列完成之后的显示处理 * Display handle of the module queues loaded after. - * + * * @param {Boolean} recreate 是否为重建编辑器 * @returns {editormd} 返回editormd的实例对象 */ - + loadedDisplay : function(recreate) { - + // console.log("loadedDisplay") recreate = recreate || false; - + var _this = this; var editor = this.editor; var preview = this.preview; var settings = this.settings; - + this.containerMask.hide(); - + this.save(); - + if (settings.watch) { preview.show(); } - + editor.data("oldWidth", editor.width()).data("oldHeight", editor.height()); // 为了兼容Zepto - + this.resize(); this.registerKeyMaps(); - + $(window).resize(function(){ _this.resize(); }); - + this.bindScrollEvent().bindChangeEvent(); - + if (!recreate) { $.proxy(settings.onload, this)(); } - + this.state.loaded = true; + if (settings.watch) { + this.save(); + preview.show(); + } + return this; }, - + /** * 设置编辑器的宽度 * Set editor width - * + * * @param {Number|String} width 编辑器宽度值 * @returns {editormd} 返回editormd的实例对象 */ - + width : function(width) { - - this.editor.css("width", (typeof width === "number") ? width + "px" : width); + + this.editor.css("width", (typeof width === "number") ? width + "px" : width); this.resize(); - + return this; }, - + /** * 设置编辑器的高度 * Set editor height - * + * * @param {Number|String} height 编辑器高度值 * @returns {editormd} 返回editormd的实例对象 */ - + height : function(height) { - - this.editor.css("height", (typeof height === "number") ? height + "px" : height); + + this.editor.css("height", (typeof height === "number") ? height + "px" : height); this.resize(); - + return this; }, - + /** * 调整编辑器的尺寸和布局 * Resize editor layout - * + * * @param {Number|String} [width=null] 编辑器宽度值 * @param {Number|String} [height=null] 编辑器高度值 * @returns {editormd} 返回editormd的实例对象 */ - + resize : function(width, height) { - + // console.log("resize") width = width || null; height = height || null; - + var state = this.state; var editor = this.editor; var preview = this.preview; var toolbar = this.toolbar; var settings = this.settings; var codeMirror = this.codeMirror; - + if (width) { editor.css("width", (typeof width === "number") ? width + "px" : width); } - + if (settings.autoHeight && !state.fullscreen && !state.preview) { editor.css("height", "auto"); codeMirror.css("height", "auto"); - } - else + } + else { - if (height) + if (height) { editor.css("height", (typeof height === "number") ? height + "px" : height); } - + if (state.fullscreen) { editor.height($(window).height()); } - if (settings.toolbar && !settings.readOnly) + if (settings.toolbar && !settings.readOnly) { codeMirror.css("margin-top", toolbar.height() + 1).height(editor.height() - toolbar.height()); - } + } else { codeMirror.css("margin-top", 0).height(editor.height()); } } - - if(settings.watch) + + if(settings.watch) { codeMirror.width(editor.width() / 2); preview.width((!state.preview) ? editor.width() / 2 : editor.width()); - + this.previewContainer.css("padding", settings.autoHeight ? "20px 20px 50px 40px" : "20px"); - - if (settings.toolbar && !settings.readOnly) + + if (settings.toolbar && !settings.readOnly) { preview.css("top", toolbar.height() + 1); - } - else + } + else { preview.css("top", 0); } - + if (settings.autoHeight && !state.fullscreen && !state.preview) { preview.height(""); } else - { + { var previewHeight = (settings.toolbar && !settings.readOnly) ? editor.height() - toolbar.height() : editor.height(); - + preview.height(previewHeight); } - } - else + } + else { codeMirror.width(editor.width()); preview.hide(); } - - if (state.loaded) + + if (state.loaded) { $.proxy(settings.onresize, this)(); } return this; }, - + /** * 解析和保存Markdown代码 * Parse & Saving Markdown source code - * + * * @returns {editormd} 返回editormd的实例对象 */ - + save : function() { - - if (timer === null) - { - return this; - } - + // console.log("saving") var _this = this; var state = this.state; var settings = this.settings; - var cm = this.cm; + var cm = this.cm; var cmValue = cm.getValue(); var previewContainer = this.previewContainer; - if (settings.mode !== "gfm" && settings.mode !== "markdown") + if (timer === null && !(!settings.watch && state.preview)) { - this.markdownTextarea.val(cmValue); - return this; } - - var marked = editormd.$marked; - var markdownToC = this.markdownToC = []; - var rendererOptions = this.markedRendererOptions = { - toc : settings.toc, - tocm : settings.tocm, - tocStartLevel : settings.tocStartLevel, - pageBreak : settings.pageBreak, - taskList : settings.taskList, - emoji : settings.emoji, - tex : settings.tex, - atLink : settings.atLink, // for @link - emailLink : settings.emailLink, // for mail address auto link - flowChart : settings.flowChart, - sequenceDiagram : settings.sequenceDiagram, - previewCodeHighlight : settings.previewCodeHighlight, - }; - - var markedOptions = this.markedOptions = { - renderer : editormd.markedRenderer(markdownToC, rendererOptions), - gfm : true, - tables : true, - breaks : true, - pedantic : false, - sanitize : (settings.htmlDecode) ? false : true, // 关闭忽略HTML标签,即开启识别HTML标签,默认为false - smartLists : true, - smartypants : true - }; - - marked.setOptions(markedOptions); - - var newMarkdownDoc = editormd.$marked(cmValue, markedOptions); - - //console.info("cmValue", cmValue, newMarkdownDoc); - - newMarkdownDoc = editormd.filterHTMLTags(newMarkdownDoc, settings.htmlDecode); - - //console.error("cmValue", cmValue, newMarkdownDoc); - - this.markdownTextarea.text(cmValue); - + + if (settings.mode !== "gfm" && settings.mode !== "markdown") + { + this.markdownTextarea.val(cmValue); + + return this; + } + cm.save(); - - if (settings.saveHTMLToTextarea) - { - this.htmlTextarea.text(newMarkdownDoc); - } - - if(settings.watch || (!settings.watch && state.preview)) - { - previewContainer.html(newMarkdownDoc); - this.previewCodeHighlight(); - - if (settings.toc) - { - var tocContainer = (settings.tocContainer === "") ? previewContainer : $(settings.tocContainer); - var tocMenu = tocContainer.find("." + this.classPrefix + "toc-menu"); - - tocContainer.attr("previewContainer", (settings.tocContainer === "") ? "true" : "false"); - - if (settings.tocContainer !== "" && tocMenu.length > 0) - { - tocMenu.remove(); - } - - editormd.markdownToCRenderer(markdownToC, tocContainer, settings.tocDropdown, settings.tocStartLevel); - - if (settings.tocDropdown || tocContainer.find("." + this.classPrefix + "toc-menu").length > 0) - { - editormd.tocDropdownMenu(tocContainer, (settings.tocTitle !== "") ? settings.tocTitle : this.lang.tocTitle); - } - - if (settings.tocContainer !== "") - { - previewContainer.find(".markdown-toc").css("border", "none"); - } + if (settings.saveHTMLToTextarea || settings.watch || (!settings.watch && state.preview)){ + // console.log("rendering") + var marked = editormd.$marked; + var markdownToC = this.markdownToC = []; + var rendererOptions = this.markedRendererOptions = { + toc : settings.toc, + tocm : settings.tocm, + tocStartLevel : settings.tocStartLevel, + pageBreak : settings.pageBreak, + taskList : settings.taskList, + emoji : settings.emoji, + tex : settings.tex, + atLink : settings.atLink, // for @link + emailLink : settings.emailLink, // for mail address auto link + flowChart : settings.flowChart, + sequenceDiagram : settings.sequenceDiagram, + previewCodeHighlight : settings.previewCodeHighlight, + mermaid : settings.mermaid, + mindMap : settings.mindMap, // 思维导图 + }; + + var markedOptions = this.markedOptions = { + renderer : editormd.markedRenderer(markdownToC, rendererOptions), + gfm : true, + tables : true, + breaks : true, + pedantic : false, + sanitize : (settings.htmlDecode) ? false : true, // 关闭忽略HTML标签,即开启识别HTML标签,默认为false + smartLists : true, + smartypants : true + }; + + marked.setOptions(markedOptions); + + var newMarkdownDoc = editormd.$marked.parse(cmValue, markedOptions); + + if(settings.debug) { + console.info("cmValue", cmValue, newMarkdownDoc); } - - if (settings.tex) + newMarkdownDoc = editormd.$filterXSS(newMarkdownDoc); + + //console.error("cmValue", cmValue, newMarkdownDoc); + + this.markdownTextarea.text(cmValue); + + cm.save(); + + if (settings.saveHTMLToTextarea) { - if (!editormd.kaTeXLoaded && settings.autoLoadModules) + this.htmlTextarea.text(newMarkdownDoc); + } + + if(settings.watch || (!settings.watch && state.preview)) + { + previewContainer.html(newMarkdownDoc); + + this.previewCodeHighlight(); + + if (settings.toc) { - editormd.loadKaTeX(function() { + var tocContainer = (settings.tocContainer === "") ? previewContainer : $(settings.tocContainer); + var tocMenu = tocContainer.find("." + this.classPrefix + "toc-menu"); + + tocContainer.attr("previewContainer", (settings.tocContainer === "") ? "true" : "false"); + + if (settings.tocContainer !== "" && tocMenu.length > 0) + { + tocMenu.remove(); + } + + editormd.markdownToCRenderer(markdownToC, tocContainer, settings.tocDropdown, settings.tocStartLevel); + + if (settings.tocDropdown || tocContainer.find("." + this.classPrefix + "toc-menu").length > 0) + { + editormd.tocDropdownMenu(tocContainer, (settings.tocTitle !== "") ? settings.tocTitle : this.lang.tocTitle); + } + + if (settings.tocContainer !== "") + { + previewContainer.find(".markdown-toc").css("border", "none"); + } + } + + if (settings.tex) + { + if (!editormd.kaTeXLoaded && settings.autoLoadModules) + { + editormd.loadKaTeX(function() { + editormd.$katex = katex; + editormd.kaTeXLoaded = true; + _this.katexRender(); + }); + } + else + { editormd.$katex = katex; - editormd.kaTeXLoaded = true; - _this.katexRender(); - }); - } - else - { - editormd.$katex = katex; - this.katexRender(); + this.katexRender(); + } + } + + // 渲染脑图 + if(settings.mindMap){ + setTimeout(function(){ + _this.mindmapRender(); + },10) + + } + + if (settings.flowChart || settings.sequenceDiagram || settings.mermaid) + { + flowchartTimer = setTimeout(function(){ + clearTimeout(flowchartTimer); + _this.flowChartAndSequenceDiagramRender(); + flowchartTimer = null; + }, 10); + } + + if (state.loaded) + { + $.proxy(settings.onchange, this)(); } - } - - if (settings.flowChart || settings.sequenceDiagram) - { - flowchartTimer = setTimeout(function(){ - clearTimeout(flowchartTimer); - _this.flowChartAndSequenceDiagramRender(); - flowchartTimer = null; - }, 10); } - if (state.loaded) - { - $.proxy(settings.onchange, this)(); - } } - return this; }, - + /** * 聚焦光标位置 * Focusing the cursor position - * + * * @returns {editormd} 返回editormd的实例对象 */ - + focus : function() { this.cm.focus(); return this; }, - + /** * 设置光标的位置 * Set cursor position - * + * * @param {Object} cursor 要设置的光标位置键值对象,例:{line:1, ch:0} * @returns {editormd} 返回editormd的实例对象 */ - + setCursor : function(cursor) { this.cm.setCursor(cursor); return this; }, - + /** * 获取当前光标的位置 * Get the current position of the cursor - * + * * @returns {Cursor} 返回一个光标Cursor对象 */ - + getCursor : function() { return this.cm.getCursor(); }, - + /** * 设置光标选中的范围 * Set cursor selected ranges - * + * * @param {Object} from 开始位置的光标键值对象,例:{line:1, ch:0} * @param {Object} to 结束位置的光标键值对象,例:{line:1, ch:0} * @returns {editormd} 返回editormd的实例对象 */ - + setSelection : function(from, to) { - + this.cm.setSelection(from, to); - + return this; }, - + /** * 获取光标选中的文本 * Get the texts from cursor selected - * + * * @returns {String} 返回选中文本的字符串形式 */ - + getSelection : function() { return this.cm.getSelection(); }, - + /** * 设置光标选中的文本范围 * Set the cursor selection ranges - * + * * @param {Array} ranges cursor selection ranges array * @returns {Array} return this */ - + setSelections : function(ranges) { this.cm.setSelections(ranges); - + return this; }, - + /** * 获取光标选中的文本范围 * Get the cursor selection ranges - * + * * @returns {Array} return selection ranges array */ - + getSelections : function() { return this.cm.getSelections(); }, - + /** * 替换当前光标选中的文本或在当前光标处插入新字符 * Replace the text at the current cursor selected or insert a new character at the current cursor position - * + * * @param {String} value 要插入的字符值 * @returns {editormd} 返回editormd的实例对象 */ - + replaceSelection : function(value) { this.cm.replaceSelection(value); return this; }, - + /** * 在当前光标处插入新字符 * Insert a new character at the current cursor position * * 同replaceSelection()方法 * With the replaceSelection() method - * + * * @param {String} value 要插入的字符值 * @returns {editormd} 返回editormd的实例对象 */ - + insertValue : function(value) { this.replaceSelection(value); return this; }, - + /** * 追加markdown * append Markdown to editor - * + * * @param {String} md 要追加的markdown源文档 * @returns {editormd} 返回editormd的实例对象 */ - + appendMarkdown : function(md) { var settings = this.settings; var cm = this.cm; - + cm.setValue(cm.getValue() + md); - + return this; }, - + /** * 设置和传入编辑器的markdown源文档 * Set Markdown source document - * + * * @param {String} md 要传入的markdown源文档 * @returns {editormd} 返回editormd的实例对象 */ - + setMarkdown : function(md) { this.cm.setValue(md || this.settings.markdown); - + return this; }, - + /** * 获取编辑器的markdown源文档 * Set Editor.md markdown/CodeMirror value - * + * * @returns {editormd} 返回editormd的实例对象 */ - + getMarkdown : function() { return this.cm.getValue(); }, - + /** * 获取编辑器的源文档 * Get CodeMirror value - * + * * @returns {editormd} 返回editormd的实例对象 */ - + getValue : function() { return this.cm.getValue(); }, - + /** * 设置编辑器的源文档 * Set CodeMirror value - * + * * @param {String} value set code/value/string/text * @returns {editormd} 返回editormd的实例对象 */ - + setValue : function(value) { this.cm.setValue(value); - + return this; }, - + /** * 清空编辑器 * Empty CodeMirror editor container - * + * * @returns {editormd} 返回editormd的实例对象 */ - + clear : function() { this.cm.setValue(""); - + return this; }, - + /** * 获取解析后存放在Textarea的HTML源码 * Get parsed html code from Textarea - * + * * @returns {String} 返回HTML源码 */ - + getHTML : function() { if (!this.settings.saveHTMLToTextarea) { @@ -2402,28 +2633,28 @@ return false; } - + return this.htmlTextarea.val(); }, - + /** * getHTML()的别名 * getHTML (alias) - * + * * @returns {String} Return html code 返回HTML源码 */ - + getTextareaSavedHTML : function() { return this.getHTML(); }, - + /** * 获取预览窗口的HTML源码 * Get html from preview container - * + * * @returns {editormd} 返回editormd的实例对象 */ - + getPreviewedHTML : function() { if (!this.settings.watch) { @@ -2431,137 +2662,137 @@ return false; } - + return this.previewContainer.html(); }, - + /** * 开启实时预览 * Enable real-time watching - * + * * @returns {editormd} 返回editormd的实例对象 */ - - watch : function(callback) { + + watch : function(callback) { var settings = this.settings; - + if ($.inArray(settings.mode, ["gfm", "markdown"]) < 0) { return this; } - + this.state.watching = settings.watch = true; this.preview.show(); - + if (this.toolbar) { var watchIcon = settings.toolbarIconsClass.watch; var unWatchIcon = settings.toolbarIconsClass.unwatch; - + var icon = this.toolbar.find(".fa[name=watch]"); icon.parent().attr("title", settings.lang.toolbar.watch); icon.removeClass(unWatchIcon).addClass(watchIcon); } - - this.codeMirror.css("border-right", "1px solid #ddd").width(this.editor.width() / 2); - + + this.codeMirror.css("border-right", "1px solid #ddd").width(this.editor.width() / 2); + timer = 0; - + this.save().resize(); - + if (!settings.onwatch) { settings.onwatch = callback || function() {}; } - + $.proxy(settings.onwatch, this)(); - + return this; }, - + /** * 关闭实时预览 * Disable real-time watching - * + * * @returns {editormd} 返回editormd的实例对象 */ - + unwatch : function(callback) { var settings = this.settings; this.state.watching = settings.watch = false; this.preview.hide(); - - if (this.toolbar) + + if (this.toolbar) { var watchIcon = settings.toolbarIconsClass.watch; var unWatchIcon = settings.toolbarIconsClass.unwatch; - + var icon = this.toolbar.find(".fa[name=watch]"); icon.parent().attr("title", settings.lang.toolbar.unwatch); icon.removeClass(watchIcon).addClass(unWatchIcon); } - + this.codeMirror.css("border-right", "none").width(this.editor.width()); - + this.resize(); - + if (!settings.onunwatch) { settings.onunwatch = callback || function() {}; } - + $.proxy(settings.onunwatch, this)(); - + return this; }, - + /** * 显示编辑器 * Show editor - * + * * @param {Function} [callback=function()] 回调函数 * @returns {editormd} 返回editormd的实例对象 */ - + show : function(callback) { callback = callback || function() {}; - + var _this = this; this.editor.show(0, function() { $.proxy(callback, _this)(); }); - + return this; }, - + /** * 隐藏编辑器 * Hide editor - * + * * @param {Function} [callback=function()] 回调函数 * @returns {editormd} 返回editormd的实例对象 */ - + hide : function(callback) { callback = callback || function() {}; - + var _this = this; this.editor.hide(0, function() { $.proxy(callback, _this)(); }); - + return this; }, - + /** * 隐藏编辑器部分,只预览HTML * Enter preview html state - * + * * @returns {editormd} 返回editormd的实例对象 */ - + previewing : function() { - + var _this = this; var editor = this.editor; var preview = this.preview; @@ -2569,18 +2800,19 @@ var settings = this.settings; var codeMirror = this.codeMirror; var previewContainer = this.previewContainer; - + if ($.inArray(settings.mode, ["gfm", "markdown"]) < 0) { return this; } - + if (settings.toolbar && toolbar) { toolbar.toggle(); toolbar.find(".fa[name=preview]").toggleClass("active"); } - + + // codeMirror.hide(); codeMirror.toggle(); - + var escHandle = function(event) { if (event.shiftKey && event.keyCode === 27) { _this.previewed(); @@ -2594,20 +2826,20 @@ if (this.state.fullscreen) { preview.css("background", "#fff"); } - + editor.find("." + this.classPrefix + "preview-close-btn").show().bind(editormd.mouseOrTouch("click", "touchend"), function(){ _this.previewed(); }); - + if (!settings.watch) { this.save(); - } - else + } + else { previewContainer.css("padding", ""); } - + previewContainer.addClass(this.classPrefix + "preview-active"); preview.show().css({ @@ -2616,30 +2848,30 @@ width : editor.width(), height : (settings.autoHeight && !this.state.fullscreen) ? "auto" : editor.height() }); - + if (this.state.loaded) { $.proxy(settings.onpreviewing, this)(); } $(window).bind("keyup", escHandle); - } - else + } + else { $(window).unbind("keyup", escHandle); this.previewed(); } }, - + /** * 显示编辑器部分,退出只预览HTML * Exit preview html state - * + * * @returns {editormd} 返回editormd的实例对象 */ - + previewed : function() { - + var editor = this.editor; var preview = this.preview; var toolbar = this.toolbar; @@ -2648,49 +2880,51 @@ var previewCloseBtn = editor.find("." + this.classPrefix + "preview-close-btn"); this.state.preview = false; - + this.codeMirror.show(); - + if (settings.toolbar) { toolbar.show(); } - + preview[(settings.watch) ? "show" : "hide"](); - + previewCloseBtn.hide().unbind(editormd.mouseOrTouch("click", "touchend")); - + previewContainer.removeClass(this.classPrefix + "preview-active"); - + if (settings.watch) { previewContainer.css("padding", "20px"); } - - preview.css({ + + const toolbarHeight = (settings.toolbar) ? toolbar.height() : 0; + + preview.css({ background : null, position : "absolute", width : editor.width() / 2, - height : (settings.autoHeight && !this.state.fullscreen) ? "auto" : editor.height() - toolbar.height(), - top : (settings.toolbar) ? toolbar.height() : 0 + height : (settings.autoHeight && !this.state.fullscreen) ? "auto" : editor.height() - toolbarHeight, + top : (settings.toolbar) ? toolbarHeight : 0 }); if (this.state.loaded) { $.proxy(settings.onpreviewed, this)(); } - + return this; }, - + /** * 编辑器全屏显示 * Fullscreen show - * + * * @returns {editormd} 返回editormd的实例对象 */ - + fullscreen : function() { - + var _this = this; var state = this.state; var editor = this.editor; @@ -2698,13 +2932,13 @@ var toolbar = this.toolbar; var settings = this.settings; var fullscreenClass = this.classPrefix + "fullscreen"; - + if (toolbar) { - toolbar.find(".fa[name=fullscreen]").parent().toggleClass("active"); + toolbar.find(".fa[name=fullscreen]").parent().toggleClass("active"); } - + var escHandle = function(event) { - if (!event.shiftKey && event.keyCode === 27) + if (!event.shiftKey && event.keyCode === 27) { if (state.fullscreen) { @@ -2713,50 +2947,50 @@ } }; - if (!editor.hasClass(fullscreenClass)) + if (!editor.hasClass(fullscreenClass)) { state.fullscreen = true; $("html,body").css("overflow", "hidden"); - + editor.css({ width : $(window).width(), height : $(window).height() }).addClass(fullscreenClass); this.resize(); - + $.proxy(settings.onfullscreen, this)(); $(window).bind("keyup", escHandle); } else - { - $(window).unbind("keyup", escHandle); + { + $(window).unbind("keyup", escHandle); this.fullscreenExit(); } return this; }, - + /** * 编辑器退出全屏显示 * Exit fullscreen state - * + * * @returns {editormd} 返回editormd的实例对象 */ - + fullscreenExit : function() { - + var editor = this.editor; var settings = this.settings; var toolbar = this.toolbar; - var fullscreenClass = this.classPrefix + "fullscreen"; - + var fullscreenClass = this.classPrefix + "fullscreen"; + this.state.fullscreen = false; - + if (toolbar) { - toolbar.find(".fa[name=fullscreen]").parent().removeClass("active"); + toolbar.find(".fa[name=fullscreen]").parent().removeClass("active"); } $("html,body").css("overflow", ""); @@ -2767,127 +3001,166 @@ }).removeClass(fullscreenClass); this.resize(); - + $.proxy(settings.onfullscreenExit, this)(); return this; }, - + /** * 加载并执行插件 * Load and execute the plugin - * + * * @param {String} name plugin name / function name * @param {String} path plugin load path * @returns {editormd} 返回editormd的实例对象 */ - - executePlugin : function(name, path) { - + + executePlugin : function(name, path, customPlugin = false, optionalParams= {"proxy": false}) { var _this = this; var cm = this.cm; var settings = this.settings; - - path = settings.pluginPath + path; - - if (typeof define === "function") - { + + path = (customPlugin ? settings.customPluginPath : settings.pluginPath) + path; + + if (typeof define === "function") + { if (typeof this[name] === "undefined") { alert("Error: " + name + " plugin is not found, you are not load this plugin."); - + + return this; + } + + if (optionalParams["proxy"]) { + return this[name](cm); + } else { + this[name](cm); return this; } - - this[name](cm); - - return this; } - + if ($.inArray(path, editormd.loadFiles.plugin) < 0) { - editormd.loadPlugin(path, function() { - editormd.loadPlugins[name] = _this[name]; - _this[name](cm); - }); + if (optionalParams["proxy"]){ + return new Promise((res)=>{ + editormd.loadPlugin(path, function() { + editormd.loadPlugins[name] = _this[name]; + res(_this[name](cm, optionalParams)) + }, "head", (customPlugin ? _this.author_ide_version : editormd.version) ); + }); + } + else{ + editormd.loadPlugin(path, function() { + editormd.loadPlugins[name] = _this[name]; + _this[name](cm, optionalParams); + }, "head", (customPlugin ? _this.author_ide_version : editormd.version) ); + } } else { - $.proxy(editormd.loadPlugins[name], this)(cm); + if (optionalParams["proxy"]) return $.proxy(editormd.loadPlugins[name], this)(cm, optionalParams); + $.proxy(editormd.loadPlugins[name], this)(cm, optionalParams); } - + return this; }, - + /** * 搜索替换 * Search & replace - * + * * @param {String} command CodeMirror serach commands, "find, fintNext, fintPrev, clearSearch, replace, replaceAll" * @returns {editormd} return this */ - + search : function(command) { var settings = this.settings; - + if (!settings.searchReplace) { alert("Error: settings.searchReplace == false"); return this; } - + if (!settings.readOnly) { this.cm.execCommand(command || "find"); } - + return this; }, - - searchReplace : function() { + + searchReplace : function() { this.search("replace"); - + return this; }, - - searchReplaceAll : function() { + + searchReplaceAll : function() { this.search("replaceAll"); - + return this; } }; - - editormd.fn.init.prototype = editormd.fn; - + + editormd.fn.init.prototype = editormd.fn; + /** * 锁屏 * lock screen when dialog opening - * + * * @returns {void} */ editormd.dialogLockScreen = function() { var settings = this.settings || {dialogLockScreen : true}; - - if (settings.dialogLockScreen) - { + + if (settings.dialogLockScreen) + { $("html,body").css("overflow", "hidden"); this.resize(); } }; - + + + editormd.positionDialog = function(dialog, position="center") { + var left, top; + + switch (position) { + case "center": + left = ($(window).width() - dialog.width()) / 2 + "px"; + top = ($(window).height() - dialog.height()) / 2 + "px"; + break; + case "center-left": + left = ($(window).width() / 4 - dialog.width() / 2) + "px"; + top = ($(window).height() - dialog.height()) / 2 + "px"; + break; + case "center-right": + left = ($(window).width() * 3 / 4 - dialog.width() / 2) + "px"; + top = ($(window).height() - dialog.height()) / 2 + "px"; + break; + default: + console.warn(`Unsupported dialog position: ${position}`); + left = ($(window).width() - dialog.width()) / 2 + "px"; + top = ($(window).height() - dialog.height()) / 2 + "px"; + } + + dialog.css({ top, left }); + }; + /** * 显示透明背景层 * Display mask layer when dialog opening - * + * * @param {Object} dialog dialog jQuery object * @returns {void} */ - + editormd.dialogShowMask = function(dialog) { var editor = this.editor; var settings = this.settings || {dialogShowMask : true}; - + dialog.css({ top : ($(window).height() - dialog.height()) / 2 + "px", left : ($(window).width() - dialog.width()) / 2 + "px" @@ -2902,11 +3175,11 @@ undo : function() { this.cm.undo(); }, - + redo : function() { this.cm.redo(); }, - + bold : function() { var cm = this.cm; var cursor = cm.getCursor(); @@ -2918,7 +3191,7 @@ cm.setCursor(cursor.line, cursor.ch + 2); } }, - + del : function() { var cm = this.cm; var cursor = cm.getCursor(); @@ -2962,7 +3235,7 @@ //cm.replaceSelection("> " + selection); //cm.setCursor(cursor.line, (selection === "") ? cursor.ch + 2 : cursor.ch + selection.length + 2); }, - + ucfirst : function() { var cm = this.cm; var selection = cm.getSelection(); @@ -2971,7 +3244,7 @@ cm.replaceSelection(editormd.firstUpperCase(selection)); cm.setSelections(selections); }, - + ucwords : function() { var cm = this.cm; var selection = cm.getSelection(); @@ -2980,7 +3253,7 @@ cm.replaceSelection(editormd.wordsFirstUpperCase(selection)); cm.setSelections(selections); }, - + uppercase : function() { var cm = this.cm; var selection = cm.getSelection(); @@ -2989,13 +3262,13 @@ cm.replaceSelection(selection.toUpperCase()); cm.setSelections(selections); }, - + lowercase : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); var selections = cm.listSelections(); - + cm.replaceSelection(selection.toLowerCase()); cm.setSelections(selections); }, @@ -3003,102 +3276,176 @@ h1 : function() { var cm = this.cm; var cursor = cm.getCursor(); + // var selection = cm.getLine(cursor.line); var selection = cm.getSelection(); - - if (cursor.ch !== 0) - { - cm.setCursor(cursor.line, 0); - cm.replaceSelection("# " + selection); - cm.setCursor(cursor.line, cursor.ch + 2); + var patt1=new RegExp("^#{1}[ ]");//如果存在H1 + var patt2=new RegExp("^#{1,6}[ ]");//如果存在H2-H6 + //如果存在H1,取消H1的设置 + if (patt1.test(selection)===true){ + selection=selection.replace(/^#{1}[ ]/,""); + cm.setSelection({line:cursor.line, ch:0}, {line:cursor.line+1, ch:0 }); + cm.replaceSelection(selection+"\n"); + cm.setCursor(cursor.line, cursor.ch -2); } - else + //如果存在H1-H6,取消H2-H6,并替换为H1 + else if(patt2.test(selection)===true){ + selection=selection.replace(/^#{1,6}[ ]/,""); + cm.setSelection({line:cursor.line, ch:0}, {line:cursor.line+1, ch:0 }); + cm.replaceSelection("# "+selection+"\n"); + cm.setCursor(cursor.line, cursor.ch +2); + + }else + //设置为H1 { - cm.replaceSelection("# " + selection); + cm.setSelection({line:cursor.line, ch:0}, {line:cursor.line+1, ch:0 }); + cm.replaceSelection("# "+selection+"\n"); + cm.setCursor(cursor.line, cursor.ch +2); } }, h2 : function() { var cm = this.cm; var cursor = cm.getCursor(); + // var selection = cm.getLine(cursor.line); var selection = cm.getSelection(); - - if (cursor.ch !== 0) - { - cm.setCursor(cursor.line, 0); - cm.replaceSelection("## " + selection); - cm.setCursor(cursor.line, cursor.ch + 3); - } - else - { - cm.replaceSelection("## " + selection); + var patt1=new RegExp("^#{2}[ ]");//如果存在H1 + var patt2=new RegExp("^#{1,6}[ ]");//如果存在H1-H6 + //如果存在H2,取消H2的设置 + if (patt1.test(selection)===true){ + selection=selection.replace(/^#{2}[ ]/,""); + cm.setSelection({line:cursor.line, ch:0}, {line:cursor.line+1, ch:0 }); + cm.replaceSelection(selection+"\n"); + cm.setCursor(cursor.line, cursor.ch -3); + }else if(patt2.test(selection)===true){ + selection=selection.replace(/^#{1,6}[ ]/,""); + cm.setSelection({line:cursor.line, ch:0}, {line:cursor.line+1, ch:0 }); + cm.replaceSelection("## "+selection+"\n"); + cm.setCursor(cursor.line, cursor.ch +3); + + }else{ + cm.setSelection({line:cursor.line, ch:0}, {line:cursor.line+1, ch:0 }); + cm.replaceSelection("## "+selection+"\n"); + cm.setCursor(cursor.line, cursor.ch +3); } }, h3 : function() { var cm = this.cm; var cursor = cm.getCursor(); + // var selection = cm.getLine(cursor.line); var selection = cm.getSelection(); - - if (cursor.ch !== 0) - { - cm.setCursor(cursor.line, 0); - cm.replaceSelection("### " + selection); - cm.setCursor(cursor.line, cursor.ch + 4); + var patt1=new RegExp("^#{3}[ ]");//如果存在H3 + var patt2=new RegExp("^#{1,6}[ ]");//如果存在H1-H6 + //如果存在H3,取消H3的设置 + if (patt1.test(selection)===true){ + selection=selection.replace(/^#{3}[ ]/,""); + cm.setSelection({line:cursor.line, ch:0}, {line:cursor.line+1, ch:0 }); + cm.replaceSelection(selection+"\n"); + cm.setCursor(cursor.line, cursor.ch -4); } - else + //如果存在H1-H6,取消H1-H6,并替换为H3 + else if(patt2.test(selection)===true){ + selection=selection.replace(/^#{1,6}[ ]/,""); + cm.setSelection({line:cursor.line, ch:0}, {line:cursor.line+1, ch:0 }); + cm.replaceSelection("### "+selection+"\n"); + cm.setCursor(cursor.line, cursor.ch +4); + + }else + //设置为H3 { - cm.replaceSelection("### " + selection); + cm.setSelection({line:cursor.line, ch:0}, {line:cursor.line+1, ch:0 }); + cm.replaceSelection("### "+selection+"\n"); + cm.setCursor(cursor.line, cursor.ch +4); } }, h4 : function() { var cm = this.cm; var cursor = cm.getCursor(); + // var selection = cm.getLine(cursor.line); var selection = cm.getSelection(); - - if (cursor.ch !== 0) - { - cm.setCursor(cursor.line, 0); - cm.replaceSelection("#### " + selection); - cm.setCursor(cursor.line, cursor.ch + 5); + var patt1=new RegExp("^#{4}[ ]");//如果存在H4 + var patt2=new RegExp("^#{1,6}[ ]");//如果存在H1-H6 + //如果存在H4,取消H4的设置 + if (patt1.test(selection)===true){ + selection=selection.replace(/^#{4}[ ]/,""); + cm.setSelection({line:cursor.line, ch:0}, {line:cursor.line+1, ch:0 }); + cm.replaceSelection(selection+"\n"); + cm.setCursor(cursor.line, cursor.ch -5); } - else + //如果存在H1-H6,取消H1-H6,并替换为H4 + else if(patt2.test(selection)===true){ + selection=selection.replace(/^#{1,6}[ ]/,""); + cm.setSelection({line:cursor.line, ch:0}, {line:cursor.line+1, ch:0 }); + cm.replaceSelection("#### "+selection+"\n"); + cm.setCursor(cursor.line, cursor.ch +5); + + }else + //设置为H4 { - cm.replaceSelection("#### " + selection); + cm.setSelection({line:cursor.line, ch:0}, {line:cursor.line+1, ch:0 }); + cm.replaceSelection("#### "+selection+"\n"); + cm.setCursor(cursor.line, cursor.ch +5); } }, h5 : function() { var cm = this.cm; var cursor = cm.getCursor(); + // var selection = cm.getLine(cursor.line); var selection = cm.getSelection(); - - if (cursor.ch !== 0) - { - cm.setCursor(cursor.line, 0); - cm.replaceSelection("##### " + selection); - cm.setCursor(cursor.line, cursor.ch + 6); + var patt1=new RegExp("^#{5}[ ]");//如果存在H5 + var patt2=new RegExp("^#{1,6}[ ]");//如果存在H1-H6 + //如果存在H5,取消H5的设置 + if (patt1.test(selection)===true){ + selection=selection.replace(/^#{5}[ ]/,""); + cm.setSelection({line:cursor.line, ch:0}, {line:cursor.line+1, ch:0 }); + cm.replaceSelection(selection+"\n"); + cm.setCursor(cursor.line, cursor.ch -6); } - else + //如果存在H1-H6,取消H1-H6,并替换为H5 + else if(patt2.test(selection)===true){ + selection=selection.replace(/^#{1,6}[ ]/,""); + cm.setSelection({line:cursor.line, ch:0}, {line:cursor.line+1, ch:0 }); + cm.replaceSelection("##### "+selection+"\n"); + cm.setCursor(cursor.line, cursor.ch +6); + + }else + //设置为H5 { - cm.replaceSelection("##### " + selection); + cm.setSelection({line:cursor.line, ch:0}, {line:cursor.line+1, ch:0 }); + cm.replaceSelection("##### "+selection+"\n"); + cm.setCursor(cursor.line, cursor.ch +6); } }, h6 : function() { var cm = this.cm; var cursor = cm.getCursor(); + // var selection = cm.getLine(cursor.line); var selection = cm.getSelection(); - - if (cursor.ch !== 0) - { - cm.setCursor(cursor.line, 0); - cm.replaceSelection("###### " + selection); - cm.setCursor(cursor.line, cursor.ch + 7); + var patt1=new RegExp("^#{6}[ ]");//如果存在H6 + var patt2=new RegExp("^#{1,6}[ ]");//如果存在H1-H6 + //如果存在H6,取消H6的设置 + if (patt1.test(selection)===true){ + selection=selection.replace(/^#{6}[ ]/,""); + cm.setSelection({line:cursor.line, ch:0}, {line:cursor.line+1, ch:0 }); + cm.replaceSelection(selection+"\n"); + cm.setCursor(cursor.line, cursor.ch -7); } - else + //如果存在H1-H6,取消H1-H6,并替换为H6 + else if(patt2.test(selection)===true){ + selection=selection.replace(/^#{1,6}[ ]/,""); + cm.setSelection({line:cursor.line, ch:0}, {line:cursor.line+1, ch:0 }); + cm.replaceSelection("###### "+selection+"\n"); + cm.setCursor(cursor.line, cursor.ch +7); + + }else + //设置为H6 { - cm.replaceSelection("###### " + selection); + cm.setSelection({line:cursor.line, ch:0}, {line:cursor.line+1, ch:0 }); + cm.replaceSelection("###### "+selection+"\n"); + cm.setCursor(cursor.line, cursor.ch +7); } }, @@ -3106,20 +3453,35 @@ var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); - - if (selection === "") + var patt1=new RegExp("^-{1}[ ]"); + var cnt =0; + //如果未选择,将该行设置为无序列表 + if (selection === "") { + cm.setCursor(cursor.line, 0); cm.replaceSelection("- " + selection); - } - else + cm.setCursor(cursor.line, cursor.ch + 2); + } + else { var selectionText = selection.split("\n"); - - for (var i = 0, len = selectionText.length; i < len; i++) + //判断取中内容是否已作无序列表标记 + for (var i = 0, len = selectionText.length; i < len; i++) { - selectionText[i] = (selectionText[i] === "") ? "" : "- " + selectionText[i]; + if (patt1.test(selectionText[i])===true ){cnt++;} + } + //如果全作了无序列表标记,取消标记 + if(cnt===selectionText.length){ + for (var i = 0, len = selectionText.length; i < len; i++){ + selectionText[i] = (selectionText[i] === "") ? "" : selectionText[i].replace(patt1,""); + } + }else + //对未打上无序列表标记,打上标记 + { + for (var i = 0, len = selectionText.length; i < len; i++){ + selectionText[i] = (selectionText[i] === "") ? "" : "- " + selectionText[i].replace(patt1,""); + } } - cm.replaceSelection(selectionText.join("\n")); } }, @@ -3128,20 +3490,34 @@ var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); - - if(selection === "") + var patt1=new RegExp("^[0-9]+[\.][ ]"); + var cnt =0; + //如果未选择,将该行设置为有序列表 + if (selection === "") { + cm.setCursor(cursor.line, 0); cm.replaceSelection("1. " + selection); + cm.setCursor(cursor.line, cursor.ch + 3); } else { var selectionText = selection.split("\n"); - - for (var i = 0, len = selectionText.length; i < len; i++) + //判断取中内容是否已作有序列表标记 + for (var i = 0, len = selectionText.length; i < len; i++) { - selectionText[i] = (selectionText[i] === "") ? "" : (i+1) + ". " + selectionText[i]; + if (patt1.test(selectionText[i])===true ){cnt++;} + } + //如果全作了有序列表标记,取消标记 + if(cnt===selectionText.length){ + for (var i = 0, len = selectionText.length; i < len; i++){ + selectionText[i] = (selectionText[i] === "") ? "" : selectionText[i].replace(/^[0-9]+[\.][ ]/,""); + } + } else { + //对未打上有序列表标记,打上标记 + for (var i = 0, len = selectionText.length; i < len; i++){ + selectionText[i] = (selectionText[i] === "") ? "" : (i+1) + ". " + selectionText[i].replace(patt1,""); + } } - cm.replaceSelection(selectionText.join("\n")); } }, @@ -3160,7 +3536,7 @@ alert("settings.tex === false"); return this; } - + var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); @@ -3186,7 +3562,7 @@ alert("settings.pageBreak === false"); return this; } - + var cm = this.cm; var selection = cm.getSelection(); @@ -3196,7 +3572,7 @@ image : function() { this.executePlugin("imageDialog", "image-dialog/image-dialog"); }, - + code : function() { var cm = this.cm; var cursor = cm.getCursor(); @@ -3210,17 +3586,17 @@ }, "code-block" : function() { - this.executePlugin("codeBlockDialog", "code-block-dialog/code-block-dialog"); + this.executePlugin("codeBlockDialog", "code-block-dialog/code-block-dialog"); }, "preformatted-text" : function() { this.executePlugin("preformattedTextDialog", "preformatted-text-dialog/preformatted-text-dialog"); }, - + table : function() { - this.executePlugin("tableDialog", "table-dialog/table-dialog"); + this.executePlugin("tableDialog", "table-dialog/table-dialog"); }, - + datetime : function() { var cm = this.cm; var selection = cm.getSelection(); @@ -3230,20 +3606,20 @@ cm.replaceSelection(datefmt); }, - + emoji : function() { this.executePlugin("emojiDialog", "emoji-dialog/emoji-dialog"); }, - + "html-entities" : function() { this.executePlugin("htmlEntitiesDialog", "html-entities-dialog/html-entities-dialog"); }, - + "goto-line" : function() { this.executePlugin("gotoLineDialog", "goto-line-dialog/goto-line-dialog"); }, - watch : function() { + watch : function() { this[this.settings.watch ? "unwatch" : "watch"](); }, @@ -3258,7 +3634,7 @@ clear : function() { this.clear(); }, - + search : function() { this.search(); }, @@ -3267,26 +3643,34 @@ this.executePlugin("helpDialog", "help-dialog/help-dialog"); }, + changetheme : function() { + this.setEditorTheme((this.settings.editorTheme=="default")?"pastel-on-dark":"default"); + this.setPreviewTheme((this.settings.previewTheme=="")?"dark":""); + }, + info : function() { this.showInfoDialog(); } }; - + + var isMac = navigator.platform.toUpperCase().indexOf('MAC')>=0; + var key = isMac ? "Cmd" : "Ctrl"; + editormd.keyMaps = { - "Ctrl-1" : "h1", - "Ctrl-2" : "h2", - "Ctrl-3" : "h3", - "Ctrl-4" : "h4", - "Ctrl-5" : "h5", - "Ctrl-6" : "h6", - "Ctrl-B" : "bold", // if this is string == editormd.toolbarHandlers.xxxx - "Ctrl-D" : "datetime", - - "Ctrl-E" : function() { // emoji + [key + "-1"] : "h1", + [key + "-2"] : "h2", + [key + "-3"] : "h3", + [key + "-4"] : "h4", + [key + "-5"] : "h5", + [key + "-6"] : "h6", + [key + "-B"] : "bold", // if this is string == editormd.toolbarHandlers.xxxx + [key + "-D"] : "datetime", + + [key + "-E"] : function() { // emoji var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); - + if (!this.settings.emoji) { alert("Error: settings.emoji == false"); @@ -3299,16 +3683,16 @@ cm.setCursor(cursor.line, cursor.ch + 1); } }, - "Ctrl-Alt-G" : "goto-line", - "Ctrl-H" : "hr", - "Ctrl-I" : "italic", - "Ctrl-K" : "code", - - "Ctrl-L" : function() { + [key + "-Alt-G"] : "goto-line", + [key + "-H"] : "hr", + [key + "-I"] : "italic", + [key + "-K"] : "code", + + [key + "-L"] : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); - + var title = (selection === "") ? "" : " \""+selection+"\""; cm.replaceSelection("[" + selection + "]("+title+")"); @@ -3317,13 +3701,13 @@ cm.setCursor(cursor.line, cursor.ch + 1); } }, - "Ctrl-U" : "list-ul", - - "Shift-Ctrl-A" : function() { + [key + "-U"] : "list-ul", + + ["Shift-" + key + "-A"] : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); - + if (!this.settings.atLink) { alert("Error: settings.atLink == false"); @@ -3336,38 +3720,38 @@ cm.setCursor(cursor.line, cursor.ch + 1); } }, - - "Shift-Ctrl-C" : "code", - "Shift-Ctrl-Q" : "quote", - "Shift-Ctrl-S" : "del", - "Shift-Ctrl-K" : "tex", // KaTeX - + + ["Shift" + key + "-C"] : "code", + ["Shift" + key + "Q"] : "quote", + ["Shift" + key + "S"] : "del", + ["Shift" + key + "K"] : "tex", // KaTeX + "Shift-Alt-C" : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); - + cm.replaceSelection(["```", selection, "```"].join("\n")); if (selection === "") { cm.setCursor(cursor.line, cursor.ch + 3); - } + } }, - - "Shift-Ctrl-Alt-C" : "code-block", - "Shift-Ctrl-H" : "html-entities", - "Shift-Alt-H" : "help", - "Shift-Ctrl-E" : "emoji", - "Shift-Ctrl-U" : "uppercase", - "Shift-Alt-U" : "ucwords", - "Shift-Ctrl-Alt-U" : "ucfirst", - "Shift-Alt-L" : "lowercase", - - "Shift-Ctrl-I" : function() { + + ["Shift-" + key + "-Alt-C"] : "code-block", + ["Shift-" + key + "-H"] : "html-entities", + "Shift-Alt-H" : "help", + ["Shift-" + key + "-E"] : "emoji", + ["Shift-" + key + "-U"] : "uppercase", + "Shift-Alt-U" : "ucwords", + ["Shift-" + key + "-Alt-U"] : "ucfirst", + "Shift-Alt-L" : "lowercase", + + ["Shift-" + key + "-I"] : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); - + var title = (selection === "") ? "" : " \""+selection+"\""; cm.replaceSelection("![" + selection + "]("+title+")"); @@ -3376,76 +3760,76 @@ cm.setCursor(cursor.line, cursor.ch + 4); } }, - - "Shift-Ctrl-Alt-I" : "image", - "Shift-Ctrl-L" : "link", - "Shift-Ctrl-O" : "list-ol", - "Shift-Ctrl-P" : "preformatted-text", - "Shift-Ctrl-T" : "table", - "Shift-Alt-P" : "pagebreak", - "F9" : "watch", - "F10" : "preview", - "F11" : "fullscreen", + + ["Shift-" + key + "-Alt-I"] : "image", + ["Shift-" + key + "-L"] : "link", + ["Shift-" + key + "-O"] : "list-ol", + ["Shift-" + key + "-P"] : "preformatted-text", + ["Shift-" + key + "-T"] : "table", + "Shift-Alt-P" : "pagebreak", + "F9" : "watch", + "F10" : "preview", + "F11" : "fullscreen", }; - + /** * 清除字符串两边的空格 * Clear the space of strings both sides. - * + * * @param {String} str string - * @returns {String} trimed string + * @returns {String} trimed string */ - + var trim = function(str) { return (!String.prototype.trim) ? str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "") : str.trim(); }; - + editormd.trim = trim; - + /** * 所有单词首字母大写 * Words first to uppercase - * + * * @param {String} str string * @returns {String} string */ - + var ucwords = function (str) { - return str.toLowerCase().replace(/\b(\w)|\s(\w)/g, function($1) { + return str.toLowerCase().replace(/\b(\w)|\s(\w)/g, function($1) { return $1.toUpperCase(); }); }; - + editormd.ucwords = editormd.wordsFirstUpperCase = ucwords; - + /** * 字符串首字母大写 * Only string first char to uppercase - * + * * @param {String} str string * @returns {String} string */ - - var firstUpperCase = function(str) { + + var firstUpperCase = function(str) { return str.toLowerCase().replace(/\b(\w)/, function($1){ return $1.toUpperCase(); }); }; - + var ucfirst = firstUpperCase; - + editormd.firstUpperCase = editormd.ucfirst = firstUpperCase; - + editormd.urls = { atLinkBase : "https://github.com/" }; - + editormd.regexs = { atLink : /@(\w+)/g, email : /(\w+)@(\w+)\.(\w+)\.?(\w+)?/g, emailLink : /(mailto:)?([\w\.\_]+)@(\w+)\.(\w+)\.?(\w+)?/g, emoji : /:([\w\+-]+):/g, - emojiDatetime : /(\d{2}:\d{2}:\d{2})/g, + emojiDatetime : /(\d{1,2}:\d{1,2}:\d{1,2})/g, twemoji : /:(tw-([\w]+)-?(\w+)?):/g, fontAwesome : /:(fa-([\w]+)(-(\w+)){0,}):/g, editormdLogo : /:(editormd-logo-?(\w+)?):/g, @@ -3454,11 +3838,12 @@ // Emoji graphics files url path editormd.emoji = { - path : "http://www.emoji-cheat-sheet.com/graphics/emojis/", + // path : "http://www.emoji-cheat-sheet.com/graphics/emojis/", + path: "https://www.webpagefx.com/tools/emoji-cheat-sheet/graphics/emojis/", ext : ".png" }; - // Twitter Emoji (Twemoji) graphics files url path + // Twitter Emoji (Twemoji) graphics files url path editormd.twemoji = { path : "http://twemoji.maxcdn.com/36x36/", ext : ".png" @@ -3467,7 +3852,7 @@ /** * 自定义marked的解析器 * Custom Marked renderer rules - * + * * @param {Array} markdownToC 传入用于接收TOC的数组 * @returns {Renderer} markedRenderer 返回marked的Renderer自定义对象 */ @@ -3476,7 +3861,7 @@ var defaults = { toc : true, // Table of contents tocm : false, - tocStartLevel : 1, // Said from H1 to create ToC + tocStartLevel : 1, // Said from H1 to create ToC pageBreak : true, atLink : true, // for @link emailLink : true, // for mail address auto link @@ -3485,13 +3870,14 @@ tex : false, // TeX(LaTeX), based on KaTeX flowChart : false, // flowChart.js only support IE9+ sequenceDiagram : false, // sequenceDiagram.js only support IE9+ + mermaid : true, }; - - var settings = $.extend(defaults, options || {}); + + var settings = $.extend(defaults, options || {}); var marked = editormd.$marked; var markedRenderer = new marked.Renderer(); - markdownToC = markdownToC || []; - + markdownToC = markdownToC || []; + var regexs = editormd.regexs; var atLinkReg = regexs.atLink; var emojiReg = regexs.emoji; @@ -3502,12 +3888,83 @@ var editormdLogoReg = regexs.editormdLogo; var pageBreakReg = regexs.pageBreak; + markedRenderer.blockquote = function($quote) { + + var quoteBegin = ""; + + var ps = $quote.match(//i); + if(ps !== null) { + quoteBegin = ps[0]; + $quote = $quote.substr(quoteBegin.length); + } + var $class = "default"; + + if($quote.indexOf("[info]") === 0){ + $class = "info"; + $quote = $quote.substr(6); + }else if($quote.indexOf("[warning]") === 0){ + $class = "warning"; + $quote = $quote.substr(9); + }else if($quote.indexOf("[success]") === 0){ + $class = "success"; + $quote = $quote.substr(9); + }else if($quote.indexOf("[danger]") === 0){ + $class = "danger"; + $quote = $quote.substr(8); + } + + return '
      \n' + quoteBegin + $quote + '
      \n'; + }; + + markedRenderer.image = function(href,title,text) { + var attr = ""; + var begin = ""; + var end = ""; + + if(href && href !== ""){ + var a = document.createElement('a'); + a.href = href; + var attrs = a.hash.match(/size=\d+x\d+/i); + if(attrs !== null) { + a.hash = a.hash.replace(attrs[0],""); + href = a.href; + attrs = attrs[0].replace("size=","").split("x"); + if(attrs[0] > 0) { + attr += " width=\"" + attrs[0] + "\"" + } + if(attrs[1] > 0) { + attr += " height=\"" + attrs[1] + "\"" + } + } + attrs = a.hash.match(/align=(center|left|right)/i) + if (attrs !== null) { + var hash = a.hash.replace(attrs[0],""); + if (hash.indexOf("#&") === 0) { + hash = "#" + hash.substr(2); + } + a.hash = hash; + + href = a.href; + attrs = attrs[0].replace("align=",""); + end = "

      "; + if(attrs === "center"){ + begin = '

      '; + }else if (attrs === "left") { + begin = '

      '; + }else if (attrs === "right") { + begin = '

      '; + } + } + } + return begin + "\""+text+"\"" + end; + }; + markedRenderer.emoji = function(text) { - - text = text.replace(editormd.regexs.emojiDatetime, function($1) { + + text = text.replace(editormd.regexs.emojiDatetime, function($1) { return $1.replace(/:/g, ":"); }); - + var matchs = text.match(emojiReg); if (!matchs || !settings.emoji) { @@ -3515,7 +3972,7 @@ } for (var i = 0, len = matchs.length; i < len; i++) - { + { if (matchs[i] === ":+1:") { matchs[i] = ":\\+1:"; } @@ -3525,11 +3982,11 @@ var name = $1.replace(/:/g, ""); if (faMatchs) - { + { for (var fa = 0, len1 = faMatchs.length; fa < len1; fa++) { var faName = faMatchs[fa].replace(/:/g, ""); - + return ""; } } @@ -3538,15 +3995,15 @@ var emdlogoMathcs = $1.match(editormdLogoReg); var twemojiMatchs = $1.match(twemojiReg); - if (emdlogoMathcs) - { + if (emdlogoMathcs) + { for (var x = 0, len2 = emdlogoMathcs.length; x < len2; x++) { var logoName = emdlogoMathcs[x].replace(/:/g, ""); return ""; } } - else if (twemojiMatchs) + else if (twemojiMatchs) { for (var t = 0, len3 = twemojiMatchs.length; t < len3; t++) { @@ -3572,18 +4029,18 @@ markedRenderer.atLink = function(text) { if (atLinkReg.test(text)) - { - if (settings.atLink) + { + if (settings.atLink) { text = text.replace(emailReg, function($1, $2, $3, $4) { return $1.replace(/@/g, "_#_@_#_"); }); text = text.replace(atLinkReg, function($1, $2) { - return "" + $1 + ""; + return "" + $1 + ""; }).replace(/_#_@_#_/g, "@"); } - + if (settings.emailLink) { text = text.replace(emailLinkReg, function($1, $2, $3, $4, $5) { @@ -3596,7 +4053,7 @@ return text; }; - + markedRenderer.link = function (href, title, text) { if (this.options.sanitize) { @@ -3610,16 +4067,22 @@ return ""; } } + if(href.indexOf("@") === 0){ + return ''; + } + + var out = "" + text.replace(/@/g, "@") + ""; } @@ -3631,14 +4094,14 @@ return out; }; - + markedRenderer.heading = function(text, level, raw) { - + var linkText = text; var hasLinkReg = /\s*\]*)\>(.*)\<\/a\>\s*/; var getLinkTextReg = /\s*\]+)\>([^\>]*)\<\/a\>\s*/g; - if (hasLinkReg.test(text)) + if (hasLinkReg.test(text)) { var tempText = []; text = text.split(/\]+)\>([^\>]*)\<\/a\>/); @@ -3650,83 +4113,113 @@ text = tempText.join(" "); } - + text = trim(text); - + var escapedText = text.toLowerCase().replace(/[^\w]+/g, "-"); var toc = { text : text, level : level, - slug : escapedText + slug : escapedText, + id : id }; - + var isChinese = /^[\u4e00-\u9fa5]+$/.test(text); - var id = (isChinese) ? escape(text).replace(/\%/g, "") : text.toLowerCase().replace(/[^\w]+/g, "-"); + var id = (isChinese) ? encodeURIComponent(text).replace(/\%/g, "") : text.toLowerCase().replace(/[^\w]+/g, "-"); + // var id = Math.floor(Math.random() * 1000000000 ).toString(36); markdownToC.push(toc); - + var headingHTML = ""; - - headingHTML += ""; + headingHTML += ""; headingHTML += (hasLinkReg) ? this.atLink(this.emoji(linkText)) : this.atLink(this.emoji(text)); headingHTML += ""; return headingHTML; }; - + markedRenderer.pageBreak = function(text) { if (pageBreakReg.test(text) && settings.pageBreak) { text = "


      "; } - + return text; }; markedRenderer.paragraph = function(text) { - var isTeXInline = /\$\$(.*)\$\$/g.test(text); - var isTeXLine = /^\$\$(.*)\$\$$/.test(text); + var isTeXInline = /\$\$(.+?)\$\$/g.test(text); + var isTeXLine = /^(?!\$\$.+?(?:\$\$).+?\$\$)(\$\$(.+?)\$\$)$/.test(text); var isTeXAddClass = (isTeXLine) ? " class=\"" + editormd.classNames.tex + "\"" : ""; var isToC = (settings.tocm) ? /^(\[TOC\]|\[TOCM\])$/.test(text) : /^\[TOC\]$/.test(text); var isToCMenu = /^\[TOCM\]$/.test(text); - - if (!isTeXLine && isTeXInline) + + if (!isTeXLine && isTeXInline) { - text = text.replace(/(\$\$([^\$]*)\$\$)+/g, function($1, $2) { - return "" + $2.replace(/\$/g, "") + ""; + text = text.replaceAll(/(\$\$(.+?)\$\$)/g, function(match, $1, $2) { + return "" + $2.replaceAll(/\/g,"") + ""; }); - } - else - { - text = (isTeXLine) ? text.replace(/\$/g, "") : text; } - + else + { + text = (isTeXLine) ? text.replace(/^(?!\$\$.+?(?:\$\$).+?\$\$)(\$\$(.+?)\$\$)$/, (match, $1, $2) => $2) : text; + } + var tocHTML = "
      " + text + "
      "; - + return (isToC) ? ( (isToCMenu) ? "
      " + tocHTML + "

      " : tocHTML ) : ( (pageBreakReg.test(text)) ? this.pageBreak(text) : "" + this.atLink(this.emoji(text)) + "

      \n" ); }; - markedRenderer.code = function (code, lang, escaped) { + markedRenderer.code = function (code, lang, escaped) { if (lang === "seq" || lang === "sequence") { return "
      " + code + "
      "; - } else if (lang === "gantt"){ - return "
      + code + "
      " + } + else if (lang === "mermaid"){ + var $chars = 'ABCDEFGHJKLMNOPQRSTUVWXYZabcdefhijlkmnopqrstuvwxyz012345678'; + + var maxPos = $chars.length; + var id = ''; + for (var i = 0; i < 4; i++) { + id += $chars.charAt(Math.floor(Math.random() * maxPos)); + } + + return "
      " + code + "
      "; } else if ( lang === "flow") { return "
      " + code + "
      "; - } + } else if ( lang === "math" || lang === "latex" || lang === "katex") { - return "

      " + code + "

      "; - } - else + return "

      " + code + "

      "; + } + else if (/^mindmap/i.test(lang)){ + var len = 9 || 32; + var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; + var maxPos = $chars.length; + var map_id = ''; + var custom_height; + var h = lang.split('>')[1]; + if (h != undefined) { + custom_height = h; + } else { + custom_height = 150; + } + for (var i = 0; i < len; i++) { + map_id += $chars.charAt(Math.floor(Math.random() * maxPos)); + } + return ""+code+""; + } + if (lang === "drawio") { + var svgCode = decodeURIComponent(escape(window.atob(code))) + return "
      " + svgCode + "
      " + } + else { - return marked.Renderer.prototype.code.apply(this, arguments); } }; @@ -3734,109 +4227,113 @@ markedRenderer.tablecell = function(content, flags) { var type = (flags.header) ? "th" : "td"; var tag = (flags.align) ? "<" + type +" style=\"text-align:" + flags.align + "\">" : "<" + type + ">"; - + return tag + this.atLink(this.emoji(content)) + "\n"; }; markedRenderer.listitem = function(text) { - if (settings.taskList && /^\s*\[[x\s]\]\s*/.test(text)) + if (settings.taskList && /^\s*\[[x\s]\]\s*/.test(text)) { text = text.replace(/^\s*\[\s\]\s*/, " ") .replace(/^\s*\[x\]\s*/, " "); return "
    • " + this.atLink(this.emoji(text)) + "
    • "; } - else + else { return "
    • " + this.atLink(this.emoji(text)) + "
    • "; } }; - + markedRenderer.checkbox = function(checked){ + return checked ? ' ' : ' '; + }; + return markedRenderer; }; - + /** * * 生成TOC(Table of Contents) * Creating ToC (Table of Contents) - * + * * @param {Array} toc 从marked获取的TOC数组列表 * @param {Element} container 插入TOC的容器元素 * @param {Integer} startLevel Hx 起始层级 * @returns {Object} tocContainer 返回ToC列表容器层的jQuery对象元素 */ - + editormd.markdownToCRenderer = function(toc, container, tocDropdown, startLevel) { - - var html = ""; + + var html = ""; var lastLevel = 0; var classPrefix = this.classPrefix; - + startLevel = startLevel || 1; - - for (var i = 0, len = toc.length; i < len; i++) + + for (var i = 0, len = toc.length; i < len; i++) { var text = toc[i].text; var level = toc[i].level; - + var id = toc[i].id; + if (level < startLevel) { continue; } - - if (level > lastLevel) + + if (level > lastLevel) { html += ""; } - else if (level < lastLevel) + else if (level < lastLevel) { html += (new Array(lastLevel - level + 2)).join(""); - } - else + } + else { html += ""; } - html += "
    • " + text + "
        "; + html += "
      • " + text + "
          "; lastLevel = level; } - + var tocContainer = container.find(".markdown-toc"); - + if ((tocContainer.length < 1 && container.attr("previewContainer") === "false")) { var tocHTML = "
          "; - + tocHTML = (tocDropdown) ? "
          " + tocHTML + "
          " : tocHTML; - + container.html(tocHTML); - + tocContainer = container.find(".markdown-toc"); } - + if (tocDropdown) { tocContainer.wrap("

          "); } - + tocContainer.html("
            ").children(".markdown-toc-list").html(html.replace(/\r?\n?\\<\/ul\>/g, "")); - + return tocContainer; }; - + /** * * 生成TOC下拉菜单 * Creating ToC dropdown menu - * + * * @param {Object} container 插入TOC的容器jQuery对象元素 * @param {String} tocTitle ToC title * @returns {Object} return toc-menu object */ - + editormd.tocDropdownMenu = function(container, tocTitle) { - + tocTitle = tocTitle || "Table of Contents"; - + var zindex = 400; var tocMenus = container.find("." + this.classPrefix + "toc-menu"); @@ -3845,13 +4342,13 @@ var toc = $this.children(".markdown-toc"); var icon = ""; var btn = "" + icon + tocTitle + ""; - var menu = toc.children("ul"); + var menu = toc.children("ul"); var list = menu.find("li"); - + toc.append(btn); - + list.first().before("
          • " + tocTitle + " " + icon + "

          • "); - + $this.mouseover(function(){ menu.show(); @@ -3883,27 +4380,27 @@ }); }).mouseleave(function(){ menu.hide(); - }); - }); - + }); + }); + return tocMenus; }; - + /** * 简单地过滤指定的HTML标签 * Filter custom html tags - * + * * @param {String} html 要过滤HTML * @param {String} filters 要过滤的标签 * @returns {String} html 返回过滤的HTML */ - + editormd.filterHTMLTags = function(html, filters) { - + if (typeof html !== "string") { html = new String(html); } - + if (typeof filters !== "string") { return html; } @@ -3918,7 +4415,7 @@ html = html.replace(new RegExp("\<\s*" + tag + "\s*([^\>]*)\>([^\>]*)\<\s*\/" + tag + "\s*\>", "igm"), ""); } - + //return html; if (typeof attrs !== "undefined") @@ -3929,7 +4426,7 @@ { html = html.replace(htmlTagRegex, function($1, $2, $3, $4, $5) { return "<" + $2 + ">" + $4 + ""; - }); + }); } else if (attrs === "on*") { @@ -3937,19 +4434,19 @@ var el = $("<" + $2 + ">" + $4 + ""); var _attrs = $($1)[0].attributes; var $attrs = {}; - + $.each(_attrs, function(i, e) { if (e.nodeName !== '"') $attrs[e.nodeName] = e.nodeValue; }); - - $.each($attrs, function(i) { + + $.each($attrs, function(i) { if (i.indexOf("on") === 0) { delete $attrs[i]; } }); - + el.attr($attrs); - + var text = (typeof el[1] !== "undefined") ? $(el[1]).text() : ""; return el[0].outerHTML + text; @@ -3970,19 +4467,20 @@ }); } } - + return html; }; - + editormd.$filterXSS = editormd.filterHTMLTags; + /** * 将Markdown文档解析为HTML用于前台显示 * Parse Markdown to HTML for Font-end preview. - * + * * @param {String} id 用于显示HTML的对象ID * @param {Object} [options={}] 配置选项,可选 * @returns {Object} div 返回jQuery对象元素 */ - + editormd.markdownToHTML = function(id, options) { var defaults = { gfm : true, @@ -4004,25 +4502,27 @@ emoji : false, flowChart : false, sequenceDiagram : false, - previewCodeHighlight : true + previewCodeHighlight : true, + mermaid : true, + mindMap : true, //思维导图 }; - + editormd.$marked = marked; var div = $("#" + id); var settings = div.settings = $.extend(true, defaults, options || {}); var saveTo = div.find("textarea"); - + if (saveTo.length < 1) { div.append(""); saveTo = div.find("textarea"); - } - - var markdownDoc = (settings.markdown === "") ? saveTo.val() : settings.markdown; + } + + var markdownDoc = (settings.markdown === undefined) ? saveTo.val() : settings.markdown; var markdownToC = []; - var rendererOptions = { + var rendererOptions = { toc : settings.toc, tocm : settings.tocm, tocStartLevel : settings.tocStartLevel, @@ -4034,6 +4534,8 @@ emailLink : settings.emailLink, // for mail address auto link flowChart : settings.flowChart, sequenceDiagram : settings.sequenceDiagram, + mermaid : settings.mermaid, + mindMap : settings.mindMap, // 思维导图 previewCodeHighlight : settings.previewCodeHighlight, }; @@ -4047,73 +4549,75 @@ smartLists : true, smartypants : true }; - + markdownDoc = new String(markdownDoc); - - var markdownParsed = marked(markdownDoc, markedOptions); - - markdownParsed = editormd.filterHTMLTags(markdownParsed, settings.htmlDecode); - + + var markdownParsed = marked.parse(markdownDoc, markedOptions); + + markdownParsed = editormd.$filterXSS(markdownParsed); + if (settings.markdownSourceCode) { saveTo.text(markdownDoc); } else { saveTo.remove(); } - + div.addClass("markdown-body " + this.classPrefix + "html-preview").append(markdownParsed); - + var tocContainer = (settings.tocContainer !== "") ? $(settings.tocContainer) : div; - + if (settings.tocContainer !== "") { tocContainer.attr("previewContainer", false); } - - if (settings.toc) + + if (settings.toc) { div.tocContainer = this.markdownToCRenderer(markdownToC, tocContainer, settings.tocDropdown, settings.tocStartLevel); - + if (settings.tocDropdown || div.find("." + this.classPrefix + "toc-menu").length > 0) { this.tocDropdownMenu(div, settings.tocTitle); } - + if (settings.tocContainer !== "") { div.find(".editormd-toc-menu, .editormd-markdown-toc").remove(); } } - - if (settings.previewCodeHighlight) + + if (settings.previewCodeHighlight) { - //div.find("pre").addClass("prettyprint"); - //prettyPrint(); - div.find("pre").each(function (i, block) { - hljs.highlightBlock(block); - }); + div.find("pre").addClass("prettyprint linenums"); + //TODO: fix later if we decide to generate html + prettyPrint(); + // prettyPrint($.proxy(editormd.settings.fixCodeBlocks, editormd)); } - - if (!editormd.isIE8) + + if (!editormd.isIE8) { if (settings.flowChart) { - div.find(".flowchart").flowChart(); + div.find(".flowchart").flowChart(); } if (settings.sequenceDiagram) { div.find(".sequence-diagram").sequenceDiagram({theme: "simple"}); } + if (settings.mermaid) { + window.mermaid.init(void 0, div.find(".lang-mermaid")); + } } if (settings.tex) { var katexHandle = function() { div.find("." + editormd.classNames.tex).each(function(){ - var tex = $(this); - katex.render(tex.html().replace(/</g, "<").replace(/>/g, ">"), tex[0]); + var tex = $(this); + katex.render(tex.html().replace(/</g, "<").replace(/>/g, ">"), tex[0]); tex.find(".katex").css("font-size", "1.6em"); }); }; - + if (settings.autoLoadKaTeX && !editormd.$katex && !editormd.kaTeXLoaded) { this.loadKaTeX(function() { @@ -4127,22 +4631,34 @@ katexHandle(); } } - - div.getMarkdown = function() { + + // 前台渲染脑图 + if(settings.mindMap){ + var mindmapHandle = function(){ + div.find(".mindmap").each(function(){ + var mmap = $(this); + var md_data = window.markmap.transform(mmap.text().trim()); + window.markmap.markmap("svg#"+this.id,md_data) + }); + } + mindmapHandle(); + } + + div.getMarkdown = function() { return saveTo.val(); }; - + return div; }; - + // Editor.md themes, change toolbar themes etc. // added @1.5.0 editormd.themes = ["default", "dark"]; - + // Preview area themes // added @1.5.0 editormd.previewThemes = ["default", "dark"]; - + // CodeMirror / editor area themes // @1.5.0 rename -> editorThemes, old version -> themes editormd.editorThemes = [ @@ -4163,44 +4679,47 @@ ]; editormd.loadPlugins = {}; - + editormd.loadFiles = { js : [], css : [], plugin : [] }; - + /** * 动态加载Editor.md插件,但不立即执行 * Load editor.md plugins - * + * * @param {String} fileName 插件文件路径 * @param {Function} [callback=function()] 加载成功后执行的回调函数 * @param {String} [into="head"] 嵌入页面的位置 + * @param {String} [version=editormd.version] */ - - editormd.loadPlugin = function(fileName, callback, into) { + + editormd.loadPlugin = function(fileName, callback, into, version) { callback = callback || function() {}; - + this.loadScript(fileName, function() { editormd.loadFiles.plugin.push(fileName); callback(); - }, into); + }, into, version); }; - + /** * 动态加载CSS文件的方法 * Load css file method - * + * * @param {String} fileName CSS文件名 * @param {Function} [callback=function()] 加载成功后执行的回调函数 * @param {String} [into="head"] 嵌入页面的位置 + * @param {String} [version=editormd.version] */ - - editormd.loadCSS = function(fileName, callback, into) { - into = into || "head"; + + editormd.loadCSS = function(fileName, callback, into, version=editormd.version) { + into = into || "head"; callback = callback || function() {}; - + version = version || editormd.version + var css = document.createElement("link"); css.type = "text/css"; css.rel = "stylesheet"; @@ -4209,7 +4728,7 @@ callback(); }; - css.href = fileName + ".css"; + css.href = fileName + `.css?editormd_version=${version}`; if(into === "head") { document.getElementsByTagName("head")[0].appendChild(css); @@ -4217,42 +4736,43 @@ document.body.appendChild(css); } }; - + editormd.isIE = (navigator.appName == "Microsoft Internet Explorer"); editormd.isIE8 = (editormd.isIE && navigator.appVersion.match(/8./i) == "8."); /** * 动态加载JS文件的方法 * Load javascript file method - * + * * @param {String} fileName JS文件名 * @param {Function} [callback=function()] 加载成功后执行的回调函数 * @param {String} [into="head"] 嵌入页面的位置 */ - editormd.loadScript = function(fileName, callback, into) { - + editormd.loadScript = function(fileName, callback, into, version) { + into = into || "head"; + version = version || editormd.version callback = callback || function() {}; - - var script = null; + + var script = null; script = document.createElement("script"); script.id = fileName.replace(/[\./]+/g, "-"); - script.type = "text/javascript"; - script.src = fileName + ".js"; - - if (editormd.isIE8) - { + script.type = "text/javascript"; + script.src = fileName + `.js?editormd_version=${version}`; + + if (editormd.isIE8) + { script.onreadystatechange = function() { - if(script.readyState) + if(script.readyState) { - if (script.readyState === "loaded" || script.readyState === "complete") + if (script.readyState === "loaded" || script.readyState === "complete") { - script.onreadystatechange = null; + script.onreadystatechange = null; editormd.loadFiles.js.push(fileName); callback(); } - } + } }; } else @@ -4269,45 +4789,48 @@ document.body.appendChild(script); } }; - - // 使用国外的CDN,加载速度有时会很慢,或者自定义URL + + // 使用国内的CDN,或者自定义URL // You can custom KaTeX load url. editormd.katexURL = { - css : "//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.3.0/katex.min", - js : "//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.3.0/katex.min" + css: "https://cdn.bootcdn.net/ajax/libs/KaTeX/0.16.8/katex.min", + jsmain: "https://cdn.bootcdn.net/ajax/libs/KaTeX/0.16.8/katex.min", + jsauto: "https://cdn.bootcdn.net/ajax/libs/KaTeX/0.16.8/contrib/auto-render.min" }; - + editormd.kaTeXLoaded = false; - + /** * 加载KaTeX文件 * load KaTeX files - * + * * @param {Function} [callback=function()] 加载成功后执行的回调函数 */ - + editormd.loadKaTeX = function (callback) { editormd.loadCSS(editormd.katexURL.css, function(){ - editormd.loadScript(editormd.katexURL.js, callback || function(){}); + editormd.loadScript(editormd.katexURL.jsmain, function() { + editormd.loadScript(editormd.katexURL.jsauto, callback || function() {}) + }) }); }; - + /** * 锁屏 * lock screen - * + * * @param {Boolean} lock Boolean 布尔值,是否锁屏 * @returns {void} */ - + editormd.lockScreen = function(lock) { $("html,body").css("overflow", (lock) ? "hidden" : ""); }; - + /** * 动态创建对话框 * Creating custom dialogs - * + * * @param {Object} options 配置项键值对 Key/Value * @returns {dialog} 返回创建的dialog的jQuery实例对象 */ @@ -4316,7 +4839,7 @@ var defaults = { name : "", width : 420, - height: 240, + height: "auto", title : "", drag : true, closed : true, @@ -4326,13 +4849,20 @@ backgroundColor : "#fff", opacity : 0.1 }, + removeDialogOnClose: false, + resizeableX: false, + resizeableY: false, + minWidth: 0, + minHeight: 0, + maxWidth: "none", + maxHeight: "none", lockScreen : true, footer : true, buttons : false }; options = $.extend(true, defaults, options); - + var $this = this; var editor = this.editor; var classPrefix = editormd.classPrefix; @@ -4345,18 +4875,17 @@ if (options.title !== "") { html += "
            "; - html += "" + options.title + ""; + html += "" + options.title + ""; + if (options.closed) + { + html += ""; + } html += "
            "; } - if (options.closed) - { - html += ""; - } + html += "
            " + options.content; - html += "
            " + options.content; - - if (options.footer || typeof options.footer === "string") + if (options.footer || typeof options.footer === "string") { html += "
            " + ( (typeof options.footer === "boolean") ? "" : options.footer) + "
            "; } @@ -4373,7 +4902,7 @@ dialog.lockScreen = function(lock) { if (options.lockScreen) - { + { $("html,body").css("overflow", (lock) ? "hidden" : ""); $this.resize(); } @@ -4398,7 +4927,7 @@ return dialog; }; - dialog.loading = function(show) { + dialog.loading = function(show) { var loading = dialog.find("." + classPrefix + "dialog-mask"); loading[(show) ? "show" : "hide"](); @@ -4411,7 +4940,14 @@ zIndex : editormd.dialogZindex, border : (editormd.isIE8) ? "1px solid #ddd" : "", width : (typeof options.width === "number") ? options.width + "px" : options.width, - height : (typeof options.height === "number") ? options.height + "px" : options.height + height : (typeof options.height === "number") ? options.height + "px" : options.height, + "min-width": (typeof options.minWidth === "number") ? options.minWidth + "px" : options.minWidth, + "min-height": (typeof options.minHeight === "number") ? options.minHeight + "px" : options.minHeight, + "max-width": (typeof options.maxWidth === "number") ? options.maxWidth + "px" : options.maxWidth, + "max-height": (typeof options.maxHeight === "number") ? options.maxHeight + "px" : options.maxHeight, + ...((options.resizeableX || options.resizeableY) ? { overflow: 'hidden', + resize: (options.resizeableX && options.resizeableY) ? "both" : ((options.resizeableX) ? "horizontal" : "vertical") + } : {}) }); var dialogPosition = function(){ @@ -4425,8 +4961,9 @@ $(window).resize(dialogPosition); - dialog.children("." + classPrefix + "dialog-close").bind(mouseOrTouch("click", "touchend"), function() { + dialog.find("." + classPrefix + "dialog-close").bind(mouseOrTouch("click", "touchend"), function() { dialog.hide().lockScreen(false).hideMask(); + if (options.removeDialogOnClose) dialog.remove() }); if (typeof options.buttons === "object") @@ -4445,7 +4982,7 @@ } if (options.title !== "" && options.drag) - { + { var posX, posY; var dialogHeader = dialog.children("." + classPrefix + "dialog-header"); @@ -4461,7 +4998,7 @@ posX = e.clientX - parseInt(dialog[0].style.left); posY = e.clientY - parseInt(dialog[0].style.top); - document.onmousemove = moveAction; + document.onmousemove = moveAction; }); var userCanSelect = function (obj) { @@ -4469,7 +5006,7 @@ }; var userUnselect = function (obj) { - obj.addClass(classPrefix + "user-unselect").on("selectstart", function(event) { // selectstart for IE + obj.addClass(classPrefix + "user-unselect").on("selectstart", function(event) { // selectstart for IE return false; }); }; @@ -4482,7 +5019,7 @@ if( nowLeft >= 0 ) { if( nowLeft + dialog.width() <= $(window).width()) { left = e.clientX - posX; - } else { + } else { left = $(window).width() - dialog.width(); document.onmousemove = null; } @@ -4509,18 +5046,18 @@ dialog[0].style.top = top + "px"; }; - document.onmouseup = function() { + document.onmouseup = function() { userCanSelect($("body")); userCanSelect(dialog); - document.onselectstart = null; + document.onselectstart = null; document.onmousemove = null; }; dialogHeader.touchDraggable = function() { var offset = null; var start = function(e) { - var orig = e.originalEvent; + var orig = e.originalEvent; var pos = $(this).parent().position(); offset = { @@ -4549,20 +5086,20 @@ return dialog; }; - + /** * 鼠标和触摸事件的判断/选择方法 * MouseEvent or TouchEvent type switch - * + * * @param {String} [mouseEventType="click"] 供选择的鼠标事件 * @param {String} [touchEventType="touchend"] 供选择的触摸事件 * @returns {String} EventType 返回事件类型名称 */ - + editormd.mouseOrTouch = function(mouseEventType, touchEventType) { mouseEventType = mouseEventType || "click"; touchEventType = touchEventType || "touchend"; - + var eventType = mouseEventType; try { @@ -4572,23 +5109,23 @@ return eventType; }; - + /** * 日期时间的格式化方法 * Datetime format method - * + * * @param {String} [format=""] 日期时间的格式,类似PHP的格式 * @returns {String} datefmt 返回格式化后的日期时间字符串 */ - - editormd.dateFormat = function(format) { + + editormd.dateFormat = function(format) { format = format || ""; var addZero = function(d) { return (d < 10) ? "0" + d : d; }; - var date = new Date(); + var date = new Date(); var year = date.getFullYear(); var year2 = year.toString().slice(2, 4); var month = addZero(date.getMonth() + 1); @@ -4597,14 +5134,14 @@ var hour = addZero(date.getHours()); var min = addZero(date.getMinutes()); var second = addZero(date.getSeconds()); - var ms = addZero(date.getMilliseconds()); + var ms = addZero(date.getMilliseconds()); var datefmt = ""; var ymd = year2 + "-" + month + "-" + day; var fymd = year + "-" + month + "-" + day; var hms = hour + ":" + min + ":" + second; - switch (format) + switch (format) { case "UNIX Time" : datefmt = date.getTime(); @@ -4612,11 +5149,11 @@ case "UTC" : datefmt = date.toUTCString(); - break; + break; case "yy" : datefmt = year2; - break; + break; case "year" : case "yyyy" : @@ -4626,7 +5163,7 @@ case "month" : case "mm" : datefmt = month; - break; + break; case "cn-week-day" : case "cn-wd" : @@ -4673,7 +5210,7 @@ break; case "yyyy-mm-dd h:i:s ms" : - case "full + ms" : + case "full + ms" : datefmt = fymd + " " + hms + " " + ms; break; @@ -4686,7 +5223,14 @@ return datefmt; }; - + /** + * 获取指定行的内容 + * @param n + * @returns {*} + */ + editormd.getLine = function(n) { + return this.cm.getLine(n); + }; return editormd; })); diff --git a/static/editor.md/editormd.amd.min.js b/static/editor.md/editormd.amd.min.js index 23013692..3abc86f9 100644 --- a/static/editor.md/editormd.amd.min.js +++ b/static/editor.md/editormd.amd.min.js @@ -1,4 +1,2 @@ -/*! Editor.md v1.5.0 | editormd.amd.min.js | Open source online markdown editor. | MIT License | By: Pandao | https://github.com/pandao/editor.md | 2015-06-09 */ -!function(e){"use strict";if("function"==typeof require&&"object"==typeof exports&&"object"==typeof module)module.exports=e;else if("function"==typeof define)if(define.amd){var t="codemirror/mode/",i="codemirror/addon/",o=["jquery","marked","prettify","katex","raphael","underscore","flowchart","jqueryflowchart","sequenceDiagram","codemirror/lib/codemirror",t+"css/css",t+"sass/sass",t+"shell/shell",t+"sql/sql",t+"clike/clike",t+"php/php",t+"xml/xml",t+"markdown/markdown",t+"javascript/javascript",t+"htmlmixed/htmlmixed",t+"gfm/gfm",t+"http/http",t+"go/go",t+"dart/dart",t+"coffeescript/coffeescript",t+"nginx/nginx",t+"python/python",t+"perl/perl",t+"lua/lua",t+"r/r",t+"ruby/ruby",t+"rst/rst",t+"smartymixed/smartymixed",t+"vb/vb",t+"vbscript/vbscript",t+"velocity/velocity",t+"xquery/xquery",t+"yaml/yaml",t+"erlang/erlang",t+"jade/jade",i+"edit/trailingspace",i+"dialog/dialog",i+"search/searchcursor",i+"search/search",i+"scroll/annotatescrollbar",i+"search/matchesonscrollbar",i+"display/placeholder",i+"edit/closetag",i+"fold/foldcode",i+"fold/foldgutter",i+"fold/indent-fold",i+"fold/brace-fold",i+"fold/xml-fold",i+"fold/markdown-fold",i+"fold/comment-fold",i+"mode/overlay",i+"selection/active-line",i+"edit/closebrackets",i+"display/fullscreen",i+"search/match-highlighter"];define(o,e)}else define(["jquery"],e);else window.editormd=e()}(function(){"function"==typeof define&&define.amd&&(e=arguments[0],marked=arguments[1],prettify=arguments[2],katex=arguments[3],Raphael=arguments[4],_=arguments[5],flowchart=arguments[6],CodeMirror=arguments[9]);var e="undefined"!=typeof jQuery?jQuery:Zepto;if("undefined"!=typeof e){var t=function(e,i){return new t.fn.init(e,i)};t.title=t.$name="Editor.md",t.version="1.5.0",t.homePage="https://pandao.github.io/editor.md/",t.classPrefix="editormd-",t.toolbarModes={full:["undo","redo","|","bold","del","italic","quote","ucwords","uppercase","lowercase","|","h1","h2","h3","h4","h5","h6","|","list-ul","list-ol","hr","|","link","reference-link","image","code","preformatted-text","code-block","table","datetime","emoji","html-entities","pagebreak","|","goto-line","watch","preview","fullscreen","clear","search","|","help","info"],simple:["undo","redo","|","bold","del","italic","quote","uppercase","lowercase","|","h1","h2","h3","h4","h5","h6","|","list-ul","list-ol","hr","|","watch","preview","fullscreen","|","help","info"],mini:["undo","redo","|","watch","preview","|","help","info"]},t.defaults={mode:"gfm",name:"",value:"",theme:"",editorTheme:"default",previewTheme:"",markdown:"",appendMarkdown:"",width:"100%",height:"100%",path:"./lib/",pluginPath:"",delay:300,autoLoadModules:!0,watch:!0,placeholder:"Enjoy Markdown! coding now...",gotoLine:!0,codeFold:!1,autoHeight:!1,autoFocus:!0,autoCloseTags:!0,searchReplace:!0,syncScrolling:!0,readOnly:!1,tabSize:4,indentUnit:4,lineNumbers:!0,lineWrapping:!0,autoCloseBrackets:!0,showTrailingSpace:!0,matchBrackets:!0,indentWithTabs:!0,styleSelectedText:!0,matchWordHighlight:!0,styleActiveLine:!0,dialogLockScreen:!0,dialogShowMask:!0,dialogDraggable:!0,dialogMaskBgColor:"#fff",dialogMaskOpacity:.1,fontSize:"13px",saveHTMLToTextarea:!1,disabledKeyMaps:[],onload:function(){},onresize:function(){},onchange:function(){},onwatch:null,onunwatch:null,onpreviewing:function(){},onpreviewed:function(){},onfullscreen:function(){},onfullscreenExit:function(){},onscroll:function(){},onpreviewscroll:function(){},imageUpload:!1,imageFormats:["jpg","jpeg","gif","png","bmp","webp"],imageUploadURL:"",crossDomainUpload:!1,uploadCallbackURL:"",toc:!0,tocm:!1,tocTitle:"",tocDropdown:!1,tocContainer:"",tocStartLevel:1,htmlDecode:!1,pageBreak:!0,atLink:!0,emailLink:!0,taskList:!1,emoji:!1,tex:!1,flowChart:!1,sequenceDiagram:!1,previewCodeHighlight:!0,toolbar:!0,toolbarAutoFixed:!0,toolbarIcons:"full",toolbarTitles:{},toolbarHandlers:{ucwords:function(){return t.toolbarHandlers.ucwords},lowercase:function(){return t.toolbarHandlers.lowercase}},toolbarCustomIcons:{lowercase:'a',ucwords:'Aa'},toolbarIconsClass:{undo:"fa-undo",redo:"fa-repeat",bold:"fa-bold",del:"fa-strikethrough",italic:"fa-italic",quote:"fa-quote-left",uppercase:"fa-font",h1:t.classPrefix+"bold",h2:t.classPrefix+"bold",h3:t.classPrefix+"bold",h4:t.classPrefix+"bold",h5:t.classPrefix+"bold",h6:t.classPrefix+"bold","list-ul":"fa-list-ul","list-ol":"fa-list-ol",hr:"fa-minus",link:"fa-link","reference-link":"fa-anchor",image:"fa-picture-o",code:"fa-code","preformatted-text":"fa-file-code-o","code-block":"fa-file-code-o",table:"fa-table",datetime:"fa-clock-o",emoji:"fa-smile-o","html-entities":"fa-copyright",pagebreak:"fa-newspaper-o","goto-line":"fa-terminal",watch:"fa-eye-slash",unwatch:"fa-eye",preview:"fa-desktop",search:"fa-search",fullscreen:"fa-arrows-alt",clear:"fa-eraser",help:"fa-question-circle",info:"fa-info-circle"},toolbarIconTexts:{},lang:{name:"zh-cn",description:"开源在线Markdown编辑器
            Open source online Markdown editor.",tocTitle:"目录",toolbar:{undo:"撤销(Ctrl+Z)",redo:"重做(Ctrl+Y)",bold:"粗体",del:"删除线",italic:"斜体",quote:"引用",ucwords:"将每个单词首字母转成大写",uppercase:"将所选转换成大写",lowercase:"将所选转换成小写",h1:"标题1",h2:"标题2",h3:"标题3",h4:"标题4",h5:"标题5",h6:"标题6","list-ul":"无序列表","list-ol":"有序列表",hr:"横线",link:"链接","reference-link":"引用链接",image:"添加图片",code:"行内代码","preformatted-text":"预格式文本 / 代码块(缩进风格)","code-block":"代码块(多语言风格)",table:"添加表格",datetime:"日期时间",emoji:"Emoji表情","html-entities":"HTML实体字符",pagebreak:"插入分页符","goto-line":"跳转到行",watch:"关闭实时预览",unwatch:"开启实时预览",preview:"全窗口预览HTML(按 Shift + ESC还原)",fullscreen:"全屏(按ESC还原)",clear:"清空",search:"搜索",help:"使用帮助",info:"关于"+t.title},buttons:{enter:"确定",cancel:"取消",close:"关闭"},dialog:{link:{title:"添加链接",url:"链接地址",urlTitle:"链接标题",urlEmpty:"错误:请填写链接地址。"},referenceLink:{title:"添加引用链接",name:"引用名称",url:"链接地址",urlId:"链接ID",urlTitle:"链接标题",nameEmpty:"错误:引用链接的名称不能为空。",idEmpty:"错误:请填写引用链接的ID。",urlEmpty:"错误:请填写引用链接的URL地址。"},image:{title:"添加图片",url:"图片地址",link:"图片链接",alt:"图片描述",uploadButton:"本地上传",imageURLEmpty:"错误:图片地址不能为空。",uploadFileEmpty:"错误:上传的图片不能为空。",formatNotAllowed:"错误:只允许上传图片文件,允许上传的图片文件格式有:"},preformattedText:{title:"添加预格式文本或代码块",emptyAlert:"错误:请填写预格式文本或代码的内容。"},codeBlock:{title:"添加代码块",selectLabel:"代码语言:",selectDefaultText:"请选择代码语言",otherLanguage:"其他语言",unselectedLanguageAlert:"错误:请选择代码所属的语言类型。",codeEmptyAlert:"错误:请填写代码内容。"},htmlEntities:{title:"HTML 实体字符"},help:{title:"使用帮助"}}}},t.classNames={tex:t.classPrefix+"tex"},t.dialogZindex=99999,t.$katex=null,t.$marked=null,t.$CodeMirror=null,t.$prettyPrint=null;var i,o;t.prototype=t.fn={state:{watching:!1,loaded:!1,preview:!1,fullscreen:!1},init:function(i,o){o=o||{},"object"==typeof i&&(o=i);var r=this.classPrefix=t.classPrefix,n=this.settings=e.extend(!0,t.defaults,o);i="object"==typeof i?n.id:i;var a=this.editor=e("#"+i);this.id=i,this.lang=n.lang;var s=this.classNames={textarea:{html:r+"html-textarea",markdown:r+"markdown-textarea"}};n.pluginPath=""===n.pluginPath?n.path+"../plugins/":n.pluginPath,this.state.watching=n.watch?!0:!1,a.hasClass("editormd")||a.addClass("editormd"),a.css({width:"number"==typeof n.width?n.width+"px":n.width,height:"number"==typeof n.height?n.height+"px":n.height}),n.autoHeight&&a.css("height","auto");var l=this.markdownTextarea=a.children("textarea");l.length<1&&(a.append(""),l=this.markdownTextarea=a.children("textarea")),l.addClass(s.textarea.markdown).attr("placeholder",n.placeholder),("undefined"==typeof l.attr("name")||""===l.attr("name"))&&l.attr("name",""!==n.name?n.name:i+"-markdown-doc");var c=[n.readOnly?"":'',n.saveHTMLToTextarea?'':"",'
            ','
            ','
            '].join("\n");return a.append(c).addClass(r+"vertical"),""!==n.theme&&a.addClass(r+"theme-"+n.theme),this.mask=a.children("."+r+"mask"),this.containerMask=a.children("."+r+"container-mask"),""!==n.markdown&&l.val(n.markdown),""!==n.appendMarkdown&&l.val(l.val()+n.appendMarkdown),this.htmlTextarea=a.children("."+s.textarea.html),this.preview=a.children("."+r+"preview"),this.previewContainer=this.preview.children("."+r+"preview-container"),""!==n.previewTheme&&this.preview.addClass(r+"preview-theme-"+n.previewTheme),"function"==typeof define&&define.amd&&("undefined"!=typeof katex&&(t.$katex=katex),n.searchReplace&&!n.readOnly&&(t.loadCSS(n.path+"codemirror/addon/dialog/dialog"),t.loadCSS(n.path+"codemirror/addon/search/matchesonscrollbar"))),"function"==typeof define&&define.amd||!n.autoLoadModules?("undefined"!=typeof CodeMirror&&(t.$CodeMirror=CodeMirror),"undefined"!=typeof marked&&(t.$marked=marked),this.setCodeMirror().setToolbar().loadedDisplay()):this.loadQueues(),this},loadQueues:function(){var e=this,i=this.settings,o=i.path,r=function(){return t.isIE8?void e.loadedDisplay():void(i.flowChart||i.sequenceDiagram?t.loadScript(o+"raphael.min",function(){t.loadScript(o+"underscore.min",function(){!i.flowChart&&i.sequenceDiagram?t.loadScript(o+"sequence-diagram.min",function(){e.loadedDisplay()}):i.flowChart&&!i.sequenceDiagram?t.loadScript(o+"flowchart.min",function(){t.loadScript(o+"jquery.flowchart.min",function(){e.loadedDisplay()})}):i.flowChart&&i.sequenceDiagram&&t.loadScript(o+"flowchart.min",function(){t.loadScript(o+"jquery.flowchart.min",function(){t.loadScript(o+"sequence-diagram.min",function(){e.loadedDisplay()})})})})}):e.loadedDisplay())};return t.loadCSS(o+"codemirror/codemirror.min"),i.searchReplace&&!i.readOnly&&(t.loadCSS(o+"codemirror/addon/dialog/dialog"),t.loadCSS(o+"codemirror/addon/search/matchesonscrollbar")),i.codeFold&&t.loadCSS(o+"codemirror/addon/fold/foldgutter"),t.loadScript(o+"codemirror/codemirror.min",function(){t.$CodeMirror=CodeMirror,t.loadScript(o+"codemirror/modes.min",function(){t.loadScript(o+"codemirror/addons.min",function(){return e.setCodeMirror(),"gfm"!==i.mode&&"markdown"!==i.mode?(e.loadedDisplay(),!1):(e.setToolbar(),void t.loadScript(o+"marked.min",function(){t.$marked=marked,i.previewCodeHighlight?t.loadScript(o+"prettify.min",function(){r()}):r()}))})})}),this},setTheme:function(e){var t=this.editor,i=this.settings.theme,o=this.classPrefix+"theme-";return t.removeClass(o+i).addClass(o+e),this.settings.theme=e,this},setEditorTheme:function(e){var i=this.settings;return i.editorTheme=e,"default"!==e&&t.loadCSS(i.path+"codemirror/theme/"+i.editorTheme),this.cm.setOption("theme",e),this},setCodeMirrorTheme:function(e){return this.setEditorTheme(e),this},setPreviewTheme:function(e){var t=this.preview,i=this.settings.previewTheme,o=this.classPrefix+"preview-theme-";return t.removeClass(o+i).addClass(o+e),this.settings.previewTheme=e,this},setCodeMirror:function(){var e=this.settings,i=this.editor;"default"!==e.editorTheme&&t.loadCSS(e.path+"codemirror/theme/"+e.editorTheme);var o={mode:e.mode,theme:e.editorTheme,tabSize:e.tabSize,dragDrop:!1,autofocus:e.autoFocus,autoCloseTags:e.autoCloseTags,readOnly:e.readOnly?"nocursor":!1,indentUnit:e.indentUnit,lineNumbers:e.lineNumbers,lineWrapping:e.lineWrapping,extraKeys:{"Ctrl-Q":function(e){e.foldCode(e.getCursor())}},foldGutter:e.codeFold,gutters:["CodeMirror-linenumbers","CodeMirror-foldgutter"],matchBrackets:e.matchBrackets,indentWithTabs:e.indentWithTabs,styleActiveLine:e.styleActiveLine,styleSelectedText:e.styleSelectedText,autoCloseBrackets:e.autoCloseBrackets,showTrailingSpace:e.showTrailingSpace,highlightSelectionMatches:e.matchWordHighlight?{showToken:"onselected"===e.matchWordHighlight?!1:/\w/}:!1};return this.codeEditor=this.cm=t.$CodeMirror.fromTextArea(this.markdownTextarea[0],o),this.codeMirror=this.cmElement=i.children(".CodeMirror"),""!==e.value&&this.cm.setValue(e.value),this.codeMirror.css({fontSize:e.fontSize,width:e.watch?"50%":"100%"}),e.autoHeight&&(this.codeMirror.css("height","auto"),this.cm.setOption("viewportMargin",1/0)),e.lineNumbers||this.codeMirror.find(".CodeMirror-gutters").css("border-right","none"),this},getCodeMirrorOption:function(e){return this.cm.getOption(e)},setCodeMirrorOption:function(e,t){return this.cm.setOption(e,t),this},addKeyMap:function(e,t){return this.cm.addKeyMap(e,t),this},removeKeyMap:function(e){return this.cm.removeKeyMap(e),this},gotoLine:function(t){var i=this.settings;if(!i.gotoLine)return this;var o=this.cm,r=(this.editor,o.lineCount()),n=this.preview;if("string"==typeof t&&("last"===t&&(t=r),"first"===t&&(t=1)),"number"!=typeof t)return alert("Error: The line number must be an integer."),this;if(t=parseInt(t)-1,t>r)return alert("Error: The line number range 1-"+r),this;o.setCursor({line:t,ch:0});var a=o.getScrollInfo(),s=a.clientHeight,l=o.charCoords({line:t,ch:0},"local");if(o.scrollTo(null,(l.top+l.bottom-s)/2),i.watch){var c=this.codeMirror.find(".CodeMirror-scroll")[0],h=e(c).height(),d=c.scrollTop,u=d/c.scrollHeight;n.scrollTop(0===d?0:d+h>=c.scrollHeight-16?n[0].scrollHeight:n[0].scrollHeight*u)}return o.focus(),this},extend:function(){return"undefined"!=typeof arguments[1]&&("function"==typeof arguments[1]&&(arguments[1]=e.proxy(arguments[1],this)),this[arguments[0]]=arguments[1]),"object"==typeof arguments[0]&&"undefined"==typeof arguments[0].length&&e.extend(!0,this,arguments[0]),this},set:function(t,i){return"undefined"!=typeof i&&"function"==typeof i&&(i=e.proxy(i,this)),this[t]=i,this},config:function(t,i){var o=this.settings;return"object"==typeof t&&(o=e.extend(!0,o,t)),"string"==typeof t&&(o[t]=i),this.settings=o,this.recreate(),this},on:function(t,i){var o=this.settings;return"undefined"!=typeof o["on"+t]&&(o["on"+t]=e.proxy(i,this)),this},off:function(e){var t=this.settings;return"undefined"!=typeof t["on"+e]&&(t["on"+e]=function(){}),this},showToolbar:function(t){var i=this.settings;return i.readOnly?this:(i.toolbar&&(this.toolbar.length<1||""===this.toolbar.find("."+this.classPrefix+"menu").html())&&this.setToolbar(),i.toolbar=!0,this.toolbar.show(),this.resize(),e.proxy(t||function(){},this)(),this)},hideToolbar:function(t){var i=this.settings;return i.toolbar=!1,this.toolbar.hide(),this.resize(),e.proxy(t||function(){},this)(),this},setToolbarAutoFixed:function(t){var i=this.state,o=this.editor,r=this.toolbar,n=this.settings;"undefined"!=typeof t&&(n.toolbarAutoFixed=t);var a=function(){var t=e(window),i=t.scrollTop();return n.toolbarAutoFixed?void r.css(i-o.offset().top>10&&i
              ';i.append(n),r=this.toolbar=i.children("."+o+"toolbar")}if(!e.toolbar)return r.hide(),this;r.show();for(var a="function"==typeof e.toolbarIcons?e.toolbarIcons():"string"==typeof e.toolbarIcons?t.toolbarModes[e.toolbarIcons]:e.toolbarIcons,s=r.find("."+this.classPrefix+"menu"),l="",c=!1,h=0,d=a.length;d>h;h++){var u=a[h];if("||"===u)c=!0;else if("|"===u)l+='
            • |
            • ';else{var f=/h(\d)/.test(u),g=u;"watch"!==u||e.watch||(g="unwatch");var p=e.lang.toolbar[g],m=e.toolbarIconTexts[g],w=e.toolbarIconsClass[g];p="undefined"==typeof p?"":p,m="undefined"==typeof m?"":m,w="undefined"==typeof w?"":w;var v=c?'
            • ':"
            • ";"undefined"!=typeof e.toolbarCustomIcons[u]&&"function"!=typeof e.toolbarCustomIcons[u]?v+=e.toolbarCustomIcons[u]:(v+='',v+=''+(f?u.toUpperCase():""===w?m:"")+"",v+=""),v+="
            • ",l=c?v+l:l+v}}return s.html(l),s.find('[title="Lowercase"]').attr("title",e.lang.toolbar.lowercase),s.find('[title="ucwords"]').attr("title",e.lang.toolbar.ucwords),this.setToolbarHandler(),this.setToolbarAutoFixed(),this},dialogLockScreen:function(){return e.proxy(t.dialogLockScreen,this)(),this},dialogShowMask:function(i){return e.proxy(t.dialogShowMask,this)(i),this},getToolbarHandles:function(e){var i=this.toolbarHandlers=t.toolbarHandlers;return e&&"undefined"!=typeof toolbarIconHandlers[e]?i[e]:i},setToolbarHandler:function(){var i=this,o=this.settings;if(!o.toolbar||o.readOnly)return this;var r=this.toolbar,n=this.cm,a=this.classPrefix,s=this.toolbarIcons=r.find("."+a+"menu > li > a"),l=this.getToolbarHandles();return s.bind(t.mouseOrTouch("click","touchend"),function(t){var r=e(this).children(".fa"),a=r.attr("name"),s=n.getCursor(),c=n.getSelection();return""!==a?(i.activeIcon=r,"undefined"!=typeof l[a]?e.proxy(l[a],i)(n):"undefined"!=typeof o.toolbarHandlers[a]&&e.proxy(o.toolbarHandlers[a],i)(n,r,s,c),"link"!==a&&"reference-link"!==a&&"image"!==a&&"code-block"!==a&&"preformatted-text"!==a&&"watch"!==a&&"preview"!==a&&"search"!==a&&"fullscreen"!==a&&"info"!==a&&n.focus(),!1):void 0}),this},createDialog:function(i){return e.proxy(t.createDialog,this)(i)},createInfoDialog:function(){var e=this,i=this.editor,o=this.classPrefix,r=['
              ','
              ','

              '+t.title+"v"+t.version+"

              ","

              "+this.lang.description+"

              ",'

              '+t.homePage+'

              ','

              Copyright © 2015 Pandao, The MIT License.

              ',"
              ",'',"
              "].join("\n");i.append(r);var n=this.infoDialog=i.children("."+o+"dialog-info");return n.find("."+o+"dialog-close").bind(t.mouseOrTouch("click","touchend"),function(){e.hideInfoDialog()}),n.css("border",t.isIE8?"1px solid #ddd":"").css("z-index",t.dialogZindex).show(),this.infoDialogPosition(),this},infoDialogPosition:function(){var t=this.infoDialog,i=function(){t.css({top:(e(window).height()-t.height())/2+"px",left:(e(window).width()-t.width())/2+"px"})};return i(),e(window).resize(i),this},showInfoDialog:function(){e("html,body").css("overflow-x","hidden");var i=this.editor,o=this.settings,r=this.infoDialog=i.children("."+this.classPrefix+"dialog-info");return r.length<1&&this.createInfoDialog(),this.lockScreen(!0),this.mask.css({opacity:o.dialogMaskOpacity,backgroundColor:o.dialogMaskBgColor}).show(),r.css("z-index",t.dialogZindex).show(),this.infoDialogPosition(),this},hideInfoDialog:function(){return e("html,body").css("overflow-x",""),this.infoDialog.hide(),this.mask.hide(),this.lockScreen(!1),this},lockScreen:function(e){return t.lockScreen(e),this.resize(),this},recreate:function(){var e=this.editor,t=this.settings;return this.codeMirror.remove(),this.setCodeMirror(),t.readOnly||(e.find(".editormd-dialog").length>0&&e.find(".editormd-dialog").remove(),t.toolbar&&(this.getToolbarHandles(),this.setToolbar())),this.loadedDisplay(!0),this},previewCodeHighlight:function(){var e=this.settings,t=this.previewContainer;return e.previewCodeHighlight&&(t.find("pre").addClass("prettyprint linenums"),"undefined"!=typeof prettyPrint&&prettyPrint()),this},katexRender:function(){return null===i?this:(this.previewContainer.find("."+t.classNames.tex).each(function(){var i=e(this);t.$katex.render(i.text(),i[0]),i.find(".katex").css("font-size","1.6em")}),this)},flowChartAndSequenceDiagramRender:function(){var i=this,r=this.settings,n=this.previewContainer;if(t.isIE8)return this;if(r.flowChart){if(null===o)return this;n.find(".flowchart").flowChart()}r.sequenceDiagram&&n.find(".sequence-diagram").sequenceDiagram({theme:"simple"});var a=i.preview,s=i.codeMirror,l=s.find(".CodeMirror-scroll"),c=l.height(),h=l.scrollTop(),d=h/l[0].scrollHeight,u=0;a.find(".markdown-toc-list").each(function(){u+=e(this).height()});var f=a.find(".editormd-toc-menu").height();return f=f?f:0,a.scrollTop(0===h?0:h+c>=l[0].scrollHeight-16?a[0].scrollHeight:(a[0].scrollHeight+u+f)*d),this},registerKeyMaps:function(i){var o=this,r=this.cm,n=this.settings,a=t.toolbarHandlers,s=n.disabledKeyMaps;if(i=i||null){for(var l in i)if(e.inArray(l,s)<0){var c={};c[l]=i[l],r.addKeyMap(i)}}else{for(var h in t.keyMaps){var d=t.keyMaps[h],u="string"==typeof d?e.proxy(a[d],o):e.proxy(d,o);if(e.inArray(h,["F9","F10","F11"])<0&&e.inArray(h,s)<0){var f={};f[h]=u,r.addKeyMap(f)}}e(window).keydown(function(t){var i={120:"F9",121:"F10",122:"F11"};if(e.inArray(i[t.keyCode],s)<0)switch(t.keyCode){case 120:return e.proxy(a.watch,o)(),!1;case 121:return e.proxy(a.preview,o)(),!1;case 122:return e.proxy(a.fullscreen,o)(),!1}})}return this},bindScrollEvent:function(){var i=this,o=this.preview,r=this.settings,n=this.codeMirror,a=t.mouseOrTouch;if(!r.syncScrolling)return this;var s=function(){n.find(".CodeMirror-scroll").bind(a("scroll","touchmove"),function(t){var n=e(this).height(),a=e(this).scrollTop(),s=a/e(this)[0].scrollHeight,l=0;o.find(".markdown-toc-list").each(function(){l+=e(this).height()});var c=o.find(".editormd-toc-menu").height();c=c?c:0,o.scrollTop(0===a?0:a+n>=e(this)[0].scrollHeight-16?o[0].scrollHeight:(o[0].scrollHeight+l+c)*s),e.proxy(r.onscroll,i)(t)})},l=function(){n.find(".CodeMirror-scroll").unbind(a("scroll","touchmove"))},c=function(){o.bind(a("scroll","touchmove"),function(t){var o=e(this).height(),a=e(this).scrollTop(),s=a/e(this)[0].scrollHeight,l=n.find(".CodeMirror-scroll");l.scrollTop(0===a?0:a+o>=e(this)[0].scrollHeight?l[0].scrollHeight:l[0].scrollHeight*s),e.proxy(r.onpreviewscroll,i)(t)})},h=function(){o.unbind(a("scroll","touchmove"))};return n.bind({mouseover:s,mouseout:l,touchstart:s,touchend:l}),"single"===r.syncScrolling?this:(o.bind({mouseover:c,mouseout:h,touchstart:c,touchend:h}),this)},bindChangeEvent:function(){var e=this,t=this.cm,o=this.settings;return o.syncScrolling?(t.on("change",function(t,r){o.watch&&e.previewContainer.css("padding",o.autoHeight?"20px 20px 50px 40px":"20px"),i=setTimeout(function(){clearTimeout(i),e.save(),i=null},o.delay)}),this):this},loadedDisplay:function(t){t=t||!1;var i=this,o=this.editor,r=this.preview,n=this.settings;return this.containerMask.hide(),this.save(),n.watch&&r.show(),o.data("oldWidth",o.width()).data("oldHeight",o.height()),this.resize(),this.registerKeyMaps(),e(window).resize(function(){i.resize()}),this.bindScrollEvent().bindChangeEvent(),t||e.proxy(n.onload,this)(),this.state.loaded=!0,this},width:function(e){return this.editor.css("width","number"==typeof e?e+"px":e),this.resize(),this},height:function(e){return this.editor.css("height","number"==typeof e?e+"px":e),this.resize(),this},resize:function(t,i){t=t||null,i=i||null;var o=this.state,r=this.editor,n=this.preview,a=this.toolbar,s=this.settings,l=this.codeMirror;if(t&&r.css("width","number"==typeof t?t+"px":t),!s.autoHeight||o.fullscreen||o.preview?(i&&r.css("height","number"==typeof i?i+"px":i),o.fullscreen&&r.height(e(window).height()),s.toolbar&&!s.readOnly?l.css("margin-top",a.height()+1).height(r.height()-a.height()):l.css("margin-top",0).height(r.height())):(r.css("height","auto"),l.css("height","auto")),s.watch)if(l.width(r.width()/2),n.width(o.preview?r.width():r.width()/2),this.previewContainer.css("padding",s.autoHeight?"20px 20px 50px 40px":"20px"),s.toolbar&&!s.readOnly?n.css("top",a.height()+1):n.css("top",0),!s.autoHeight||o.fullscreen||o.preview){var c=s.toolbar&&!s.readOnly?r.height()-a.height():r.height();n.height(c)}else n.height("");else l.width(r.width()),n.hide();return o.loaded&&e.proxy(s.onresize,this)(),this},save:function(){if(null===i)return this;var r=this,n=this.state,a=this.settings,s=this.cm,l=s.getValue(),c=this.previewContainer;if("gfm"!==a.mode&&"markdown"!==a.mode)return this.markdownTextarea.val(l),this;var h=t.$marked,d=this.markdownToC=[],u=this.markedRendererOptions={toc:a.toc,tocm:a.tocm,tocStartLevel:a.tocStartLevel,pageBreak:a.pageBreak,taskList:a.taskList,emoji:a.emoji,tex:a.tex,atLink:a.atLink,emailLink:a.emailLink,flowChart:a.flowChart,sequenceDiagram:a.sequenceDiagram,previewCodeHighlight:a.previewCodeHighlight},f=this.markedOptions={renderer:t.markedRenderer(d,u),gfm:!0,tables:!0,breaks:!0,pedantic:!1,sanitize:a.htmlDecode?!1:!0,smartLists:!0,smartypants:!0};h.setOptions(f);var g=t.$marked(l,f);if(g=t.filterHTMLTags(g,a.htmlDecode),this.markdownTextarea.text(l),s.save(),a.saveHTMLToTextarea&&this.htmlTextarea.text(g),a.watch||!a.watch&&n.preview){if(c.html(g),this.previewCodeHighlight(),a.toc){var p=""===a.tocContainer?c:e(a.tocContainer),m=p.find("."+this.classPrefix+"toc-menu");p.attr("previewContainer",""===a.tocContainer?"true":"false"),""!==a.tocContainer&&m.length>0&&m.remove(),t.markdownToCRenderer(d,p,a.tocDropdown,a.tocStartLevel),(a.tocDropdown||p.find("."+this.classPrefix+"toc-menu").length>0)&&t.tocDropdownMenu(p,""!==a.tocTitle?a.tocTitle:this.lang.tocTitle),""!==a.tocContainer&&c.find(".markdown-toc").css("border","none")}a.tex&&(!t.kaTeXLoaded&&a.autoLoadModules?t.loadKaTeX(function(){t.$katex=katex,t.kaTeXLoaded=!0,r.katexRender()}):(t.$katex=katex,this.katexRender())),(a.flowChart||a.sequenceDiagram)&&(o=setTimeout(function(){clearTimeout(o),r.flowChartAndSequenceDiagramRender(),o=null},10)),n.loaded&&e.proxy(a.onchange,this)()}return this},focus:function(){return this.cm.focus(),this},setCursor:function(e){return this.cm.setCursor(e),this},getCursor:function(){return this.cm.getCursor()},setSelection:function(e,t){return this.cm.setSelection(e,t),this},getSelection:function(){return this.cm.getSelection()},setSelections:function(e){return this.cm.setSelections(e),this},getSelections:function(){return this.cm.getSelections()},replaceSelection:function(e){return this.cm.replaceSelection(e),this},insertValue:function(e){return this.replaceSelection(e),this},appendMarkdown:function(e){var t=(this.settings,this.cm);return t.setValue(t.getValue()+e),this},setMarkdown:function(e){return this.cm.setValue(e||this.settings.markdown),this},getMarkdown:function(){return this.cm.getValue()},getValue:function(){return this.cm.getValue()},setValue:function(e){return this.cm.setValue(e),this},clear:function(){return this.cm.setValue(""),this},getHTML:function(){return this.settings.saveHTMLToTextarea?this.htmlTextarea.val():(alert("Error: settings.saveHTMLToTextarea == false"),!1)},getTextareaSavedHTML:function(){return this.getHTML()},getPreviewedHTML:function(){return this.settings.watch?this.previewContainer.html():(alert("Error: settings.watch == false"),!1)},watch:function(t){var o=this.settings;if(e.inArray(o.mode,["gfm","markdown"])<0)return this;if(this.state.watching=o.watch=!0,this.preview.show(),this.toolbar){var r=o.toolbarIconsClass.watch,n=o.toolbarIconsClass.unwatch,a=this.toolbar.find(".fa[name=watch]");a.parent().attr("title",o.lang.toolbar.watch),a.removeClass(n).addClass(r)}return this.codeMirror.css("border-right","1px solid #ddd").width(this.editor.width()/2),i=0,this.save().resize(),o.onwatch||(o.onwatch=t||function(){}),e.proxy(o.onwatch,this)(),this},unwatch:function(t){var i=this.settings;if(this.state.watching=i.watch=!1,this.preview.hide(),this.toolbar){var o=i.toolbarIconsClass.watch,r=i.toolbarIconsClass.unwatch,n=this.toolbar.find(".fa[name=watch]");n.parent().attr("title",i.lang.toolbar.unwatch),n.removeClass(o).addClass(r)}return this.codeMirror.css("border-right","none").width(this.editor.width()),this.resize(),i.onunwatch||(i.onunwatch=t||function(){}),e.proxy(i.onunwatch,this)(),this},show:function(t){t=t||function(){};var i=this;return this.editor.show(0,function(){e.proxy(t,i)()}),this},hide:function(t){t=t||function(){};var i=this;return this.editor.hide(0,function(){e.proxy(t,i)()}),this},previewing:function(){var i=this,o=this.editor,r=this.preview,n=this.toolbar,a=this.settings,s=this.codeMirror,l=this.previewContainer;if(e.inArray(a.mode,["gfm","markdown"])<0)return this;a.toolbar&&n&&(n.toggle(),n.find(".fa[name=preview]").toggleClass("active")),s.toggle();var c=function(e){e.shiftKey&&27===e.keyCode&&i.previewed()};"none"===s.css("display")?(this.state.preview=!0,this.state.fullscreen&&r.css("background","#fff"),o.find("."+this.classPrefix+"preview-close-btn").show().bind(t.mouseOrTouch("click","touchend"),function(){i.previewed()}),a.watch?l.css("padding",""):this.save(),l.addClass(this.classPrefix+"preview-active"),r.show().css({position:"",top:0,width:o.width(),height:a.autoHeight&&!this.state.fullscreen?"auto":o.height()}),this.state.loaded&&e.proxy(a.onpreviewing,this)(),e(window).bind("keyup",c)):(e(window).unbind("keyup",c),this.previewed())},previewed:function(){var i=this.editor,o=this.preview,r=this.toolbar,n=this.settings,a=this.previewContainer,s=i.find("."+this.classPrefix+"preview-close-btn");return this.state.preview=!1,this.codeMirror.show(),n.toolbar&&r.show(),o[n.watch?"show":"hide"](),s.hide().unbind(t.mouseOrTouch("click","touchend")),a.removeClass(this.classPrefix+"preview-active"),n.watch&&a.css("padding","20px"),o.css({background:null,position:"absolute",width:i.width()/2,height:n.autoHeight&&!this.state.fullscreen?"auto":i.height()-r.height(),top:n.toolbar?r.height():0}),this.state.loaded&&e.proxy(n.onpreviewed,this)(),this},fullscreen:function(){var t=this,i=this.state,o=this.editor,r=(this.preview,this.toolbar),n=this.settings,a=this.classPrefix+"fullscreen";r&&r.find(".fa[name=fullscreen]").parent().toggleClass("active");var s=function(e){e.shiftKey||27!==e.keyCode||i.fullscreen&&t.fullscreenExit()};return o.hasClass(a)?(e(window).unbind("keyup",s),this.fullscreenExit()):(i.fullscreen=!0,e("html,body").css("overflow","hidden"),o.css({width:e(window).width(),height:e(window).height()}).addClass(a),this.resize(),e.proxy(n.onfullscreen,this)(),e(window).bind("keyup",s)),this},fullscreenExit:function(){var t=this.editor,i=this.settings,o=this.toolbar,r=this.classPrefix+"fullscreen";return this.state.fullscreen=!1,o&&o.find(".fa[name=fullscreen]").parent().removeClass("active"),e("html,body").css("overflow",""),t.css({width:t.data("oldWidth"),height:t.data("oldHeight")}).removeClass(r),this.resize(),e.proxy(i.onfullscreenExit,this)(),this},executePlugin:function(i,o){var r=this,n=this.cm,a=this.settings;return o=a.pluginPath+o,"function"==typeof define?"undefined"==typeof this[i]?(alert("Error: "+i+" plugin is not found, you are not load this plugin."),this):(this[i](n),this):(e.inArray(o,t.loadFiles.plugin)<0?t.loadPlugin(o,function(){t.loadPlugins[i]=r[i],r[i](n)}):e.proxy(t.loadPlugins[i],this)(n),this)},search:function(e){var t=this.settings;return t.searchReplace?(t.readOnly||this.cm.execCommand(e||"find"),this):(alert("Error: settings.searchReplace == false"),this)},searchReplace:function(){return this.search("replace"),this},searchReplaceAll:function(){return this.search("replaceAll"),this}},t.fn.init.prototype=t.fn,t.dialogLockScreen=function(){var t=this.settings||{dialogLockScreen:!0};t.dialogLockScreen&&(e("html,body").css("overflow","hidden"),this.resize())},t.dialogShowMask=function(t){var i=this.editor,o=this.settings||{dialogShowMask:!0};t.css({top:(e(window).height()-t.height())/2+"px",left:(e(window).width()-t.width())/2+"px"}),o.dialogShowMask&&i.children("."+this.classPrefix+"mask").css("z-index",parseInt(t.css("z-index"))-1).show()},t.toolbarHandlers={undo:function(){this.cm.undo()},redo:function(){this.cm.redo()},bold:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection(); - -e.replaceSelection("**"+i+"**"),""===i&&e.setCursor(t.line,t.ch+2)},del:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection("~~"+i+"~~"),""===i&&e.setCursor(t.line,t.ch+2)},italic:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection("*"+i+"*"),""===i&&e.setCursor(t.line,t.ch+1)},quote:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("> "+i),e.setCursor(t.line,t.ch+2)):e.replaceSelection("> "+i)},ucfirst:function(){var e=this.cm,i=e.getSelection(),o=e.listSelections();e.replaceSelection(t.firstUpperCase(i)),e.setSelections(o)},ucwords:function(){var e=this.cm,i=e.getSelection(),o=e.listSelections();e.replaceSelection(t.wordsFirstUpperCase(i)),e.setSelections(o)},uppercase:function(){var e=this.cm,t=e.getSelection(),i=e.listSelections();e.replaceSelection(t.toUpperCase()),e.setSelections(i)},lowercase:function(){var e=this.cm,t=(e.getCursor(),e.getSelection()),i=e.listSelections();e.replaceSelection(t.toLowerCase()),e.setSelections(i)},h1:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("# "+i),e.setCursor(t.line,t.ch+2)):e.replaceSelection("# "+i)},h2:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("## "+i),e.setCursor(t.line,t.ch+3)):e.replaceSelection("## "+i)},h3:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("### "+i),e.setCursor(t.line,t.ch+4)):e.replaceSelection("### "+i)},h4:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("#### "+i),e.setCursor(t.line,t.ch+5)):e.replaceSelection("#### "+i)},h5:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("##### "+i),e.setCursor(t.line,t.ch+6)):e.replaceSelection("##### "+i)},h6:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("###### "+i),e.setCursor(t.line,t.ch+7)):e.replaceSelection("###### "+i)},"list-ul":function(){var e=this.cm,t=(e.getCursor(),e.getSelection());if(""===t)e.replaceSelection("- "+t);else{for(var i=t.split("\n"),o=0,r=i.length;r>o;o++)i[o]=""===i[o]?"":"- "+i[o];e.replaceSelection(i.join("\n"))}},"list-ol":function(){var e=this.cm,t=(e.getCursor(),e.getSelection());if(""===t)e.replaceSelection("1. "+t);else{for(var i=t.split("\n"),o=0,r=i.length;r>o;o++)i[o]=""===i[o]?"":o+1+". "+i[o];e.replaceSelection(i.join("\n"))}},hr:function(){{var e=this.cm,t=e.getCursor();e.getSelection()}e.replaceSelection((0!==t.ch?"\n\n":"\n")+"------------\n\n")},tex:function(){if(!this.settings.tex)return alert("settings.tex === false"),this;var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection("$$"+i+"$$"),""===i&&e.setCursor(t.line,t.ch+2)},link:function(){this.executePlugin("linkDialog","link-dialog/link-dialog")},"reference-link":function(){this.executePlugin("referenceLinkDialog","reference-link-dialog/reference-link-dialog")},pagebreak:function(){if(!this.settings.pageBreak)return alert("settings.pageBreak === false"),this;{var e=this.cm;e.getSelection()}e.replaceSelection("\r\n[========]\r\n")},image:function(){this.executePlugin("imageDialog","image-dialog/image-dialog")},code:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection("`"+i+"`"),""===i&&e.setCursor(t.line,t.ch+1)},"code-block":function(){this.executePlugin("codeBlockDialog","code-block-dialog/code-block-dialog")},"preformatted-text":function(){this.executePlugin("preformattedTextDialog","preformatted-text-dialog/preformatted-text-dialog")},table:function(){this.executePlugin("tableDialog","table-dialog/table-dialog")},datetime:function(){var e=this.cm,i=(e.getSelection(),new Date,this.settings.lang.name),o=t.dateFormat()+" "+t.dateFormat("zh-cn"===i||"zh-tw"===i?"cn-week-day":"week-day");e.replaceSelection(o)},emoji:function(){this.executePlugin("emojiDialog","emoji-dialog/emoji-dialog")},"html-entities":function(){this.executePlugin("htmlEntitiesDialog","html-entities-dialog/html-entities-dialog")},"goto-line":function(){this.executePlugin("gotoLineDialog","goto-line-dialog/goto-line-dialog")},watch:function(){this[this.settings.watch?"unwatch":"watch"]()},preview:function(){this.previewing()},fullscreen:function(){this.fullscreen()},clear:function(){this.clear()},search:function(){this.search()},help:function(){this.executePlugin("helpDialog","help-dialog/help-dialog")},info:function(){this.showInfoDialog()}},t.keyMaps={"Ctrl-1":"h1","Ctrl-2":"h2","Ctrl-3":"h3","Ctrl-4":"h4","Ctrl-5":"h5","Ctrl-6":"h6","Ctrl-B":"bold","Ctrl-D":"datetime","Ctrl-E":function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();return this.settings.emoji?(e.replaceSelection(":"+i+":"),void(""===i&&e.setCursor(t.line,t.ch+1))):void alert("Error: settings.emoji == false")},"Ctrl-Alt-G":"goto-line","Ctrl-H":"hr","Ctrl-I":"italic","Ctrl-K":"code","Ctrl-L":function(){var e=this.cm,t=e.getCursor(),i=e.getSelection(),o=""===i?"":' "'+i+'"';e.replaceSelection("["+i+"]("+o+")"),""===i&&e.setCursor(t.line,t.ch+1)},"Ctrl-U":"list-ul","Shift-Ctrl-A":function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();return this.settings.atLink?(e.replaceSelection("@"+i),void(""===i&&e.setCursor(t.line,t.ch+1))):void alert("Error: settings.atLink == false")},"Shift-Ctrl-C":"code","Shift-Ctrl-Q":"quote","Shift-Ctrl-S":"del","Shift-Ctrl-K":"tex","Shift-Alt-C":function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection(["```",i,"```"].join("\n")),""===i&&e.setCursor(t.line,t.ch+3)},"Shift-Ctrl-Alt-C":"code-block","Shift-Ctrl-H":"html-entities","Shift-Alt-H":"help","Shift-Ctrl-E":"emoji","Shift-Ctrl-U":"uppercase","Shift-Alt-U":"ucwords","Shift-Ctrl-Alt-U":"ucfirst","Shift-Alt-L":"lowercase","Shift-Ctrl-I":function(){var e=this.cm,t=e.getCursor(),i=e.getSelection(),o=""===i?"":' "'+i+'"';e.replaceSelection("!["+i+"]("+o+")"),""===i&&e.setCursor(t.line,t.ch+4)},"Shift-Ctrl-Alt-I":"image","Shift-Ctrl-L":"link","Shift-Ctrl-O":"list-ol","Shift-Ctrl-P":"preformatted-text","Shift-Ctrl-T":"table","Shift-Alt-P":"pagebreak",F9:"watch",F10:"preview",F11:"fullscreen"};var r=function(e){return String.prototype.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")};t.trim=r;var n=function(e){return e.toLowerCase().replace(/\b(\w)|\s(\w)/g,function(e){return e.toUpperCase()})};t.ucwords=t.wordsFirstUpperCase=n;var a=function(e){return e.toLowerCase().replace(/\b(\w)/,function(e){return e.toUpperCase()})};return t.firstUpperCase=t.ucfirst=a,t.urls={atLinkBase:"https://github.com/"},t.regexs={atLink:/@(\w+)/g,email:/(\w+)@(\w+)\.(\w+)\.?(\w+)?/g,emailLink:/(mailto:)?([\w\.\_]+)@(\w+)\.(\w+)\.?(\w+)?/g,emoji:/:([\w\+-]+):/g,emojiDatetime:/(\d{2}:\d{2}:\d{2})/g,twemoji:/:(tw-([\w]+)-?(\w+)?):/g,fontAwesome:/:(fa-([\w]+)(-(\w+)){0,}):/g,editormdLogo:/:(editormd-logo-?(\w+)?):/g,pageBreak:/^\[[=]{8,}\]$/},t.emoji={path:"http://www.emoji-cheat-sheet.com/graphics/emojis/",ext:".png"},t.twemoji={path:"http://twemoji.maxcdn.com/36x36/",ext:".png"},t.markedRenderer=function(i,o){var n={toc:!0,tocm:!1,tocStartLevel:1,pageBreak:!0,atLink:!0,emailLink:!0,taskList:!1,emoji:!1,tex:!1,flowChart:!1,sequenceDiagram:!1},a=e.extend(n,o||{}),s=t.$marked,l=new s.Renderer;i=i||[];var c=t.regexs,h=c.atLink,d=c.emoji,u=c.email,f=c.emailLink,g=c.twemoji,p=c.fontAwesome,m=c.editormdLogo,w=c.pageBreak;return l.emoji=function(e){e=e.replace(t.regexs.emojiDatetime,function(e){return e.replace(/:/g,":")});var i=e.match(d);if(!i||!a.emoji)return e;for(var o=0,r=i.length;r>o;o++)":+1:"===i[o]&&(i[o]=":\\+1:"),e=e.replace(new RegExp(i[o]),function(e,i){var o=e.match(p),r=e.replace(/:/g,"");if(o)for(var n=0,a=o.length;a>n;n++){var s=o[n].replace(/:/g,"");return''}else{var l=e.match(m),c=e.match(g);if(l)for(var h=0,d=l.length;d>h;h++){var u=l[h].replace(/:/g,"");return''}else{if(!c){var f="+1"===r?"plus1":r;return f="black_large_square"===f?"black_square":f,f="moon"===f?"waxing_gibbous_moon":f,':'+r+':'}for(var w=0,v=c.length;v>w;w++){var k=c[w].replace(/:/g,"").replace("tw-","");return'twemoji-'+k+''}}}});return e},l.atLink=function(i){return h.test(i)?(a.atLink&&(i=i.replace(u,function(e,t,i,o){return e.replace(/@/g,"_#_@_#_")}),i=i.replace(h,function(e,i){return''+e+""}).replace(/_#_@_#_/g,"@")),a.emailLink&&(i=i.replace(f,function(t,i,o,r,n){return!i&&e.inArray(n,"jpg|jpeg|png|gif|webp|ico|icon|pdf".split("|"))<0?''+t+"":t})),i):i},l.link=function(e,t,i){if(this.options.sanitize){try{var o=decodeURIComponent(unescape(e)).replace(/[^\w:]/g,"").toLowerCase()}catch(r){return""}if(0===o.indexOf("javascript:"))return""}var n=''+i.replace(/@/g,"@")+""):(t&&(n+=' title="'+t+'"'),n+=">"+i+"")},l.heading=function(e,t,o){var n=e,a=/\s*\]*)\>(.*)\<\/a\>\s*/;if(a.test(e)){var s=[];e=e.split(/\]+)\>([^\>]*)\<\/a\>/);for(var l=0,c=e.length;c>l;l++)s.push(e[l].replace(/\s*href\=\"(.*)\"\s*/g,""));e=s.join(" ")}e=r(e);var h=e.toLowerCase().replace(/[^\w]+/g,"-"),d={text:e,level:t,slug:h},u=/^[\u4e00-\u9fa5]+$/.test(e),f=u?escape(e).replace(/\%/g,""):e.toLowerCase().replace(/[^\w]+/g,"-");i.push(d);var g="';return g+='',g+='',g+=this.atLink(a?this.emoji(n):this.emoji(e)),g+=""},l.pageBreak=function(e){return w.test(e)&&a.pageBreak&&(e='
              '),e},l.paragraph=function(e){var i=/\$\$(.*)\$\$/g.test(e),o=/^\$\$(.*)\$\$$/.test(e),r=o?' class="'+t.classNames.tex+'"':"",n=a.tocm?/^(\[TOC\]|\[TOCM\])$/.test(e):/^\[TOC\]$/.test(e),s=/^\[TOCM\]$/.test(e);e=!o&&i?e.replace(/(\$\$([^\$]*)\$\$)+/g,function(e,i){return''+i.replace(/\$/g,"")+""}):o?e.replace(/\$/g,""):e;var l='
              '+e+"
              ";return n?s?'
              '+l+"

              ":l:w.test(e)?this.pageBreak(e):""+this.atLink(this.emoji(e))+"

              \n"},l.code=function(e,i,o){return"seq"===i||"sequence"===i?'
              '+e+"
              ":"flow"===i?'
              '+e+"
              ":"math"===i||"latex"===i||"katex"===i?'

              '+e+"

              ":s.Renderer.prototype.code.apply(this,arguments)},l.tablecell=function(e,t){var i=t.header?"th":"td",o=t.align?"<"+i+' style="text-align:'+t.align+'">':"<"+i+">";return o+this.atLink(this.emoji(e))+"\n"},l.listitem=function(e){return a.taskList&&/^\s*\[[x\s]\]\s*/.test(e)?(e=e.replace(/^\s*\[\s\]\s*/,' ').replace(/^\s*\[x\]\s*/,' '),'
            • '+this.atLink(this.emoji(e))+"
            • "):"
            • "+this.atLink(this.emoji(e))+"
            • "},l},t.markdownToCRenderer=function(e,t,i,o){var r="",n=0,a=this.classPrefix;o=o||1;for(var s=0,l=e.length;l>s;s++){var c=e[s].text,h=e[s].level;o>h||(r+=h>n?"":n>h?new Array(n-h+2).join("
          • "):"
        • ",r+='
        • '+c+"
            ",n=h)}var d=t.find(".markdown-toc");if(d.length<1&&"false"===t.attr("previewContainer")){var u='
            ';u=i?'
            '+u+"
            ":u,t.html(u),d=t.find(".markdown-toc")}return i&&d.wrap('

            '),d.html('
              ').children(".markdown-toc-list").html(r.replace(/\r?\n?\\<\/ul\>/g,"")),d},t.tocDropdownMenu=function(t,i){i=i||"Table of Contents";var o=400,r=t.find("."+this.classPrefix+"toc-menu");return r.each(function(){var t=e(this),r=t.children(".markdown-toc"),n='',a=''+n+i+"",s=r.children("ul"),l=s.find("li");r.append(a),l.first().before("
            • "+i+" "+n+"

            • "),t.mouseover(function(){s.show(),l.each(function(){var t=e(this),i=t.children("ul");if(""===i.html()&&i.remove(),i.length>0&&""!==i.html()){var r=t.children("a").first();r.children(".fa").length<1&&r.append(e(n).css({"float":"right",paddingTop:"4px"}))}t.mouseover(function(){i.css("z-index",o).show(),o+=1}).mouseleave(function(){i.hide()})})}).mouseleave(function(){s.hide()})}),r},t.filterHTMLTags=function(t,i){if("string"!=typeof t&&(t=new String(t)),"string"!=typeof i)return t;for(var o=i.split("|"),r=o[0].split(","),n=o[1],a=0,s=r.length;s>a;a++){var l=r[a];t=t.replace(new RegExp("]*)>([^>]*)","igm"),"")}if("undefined"!=typeof n){var c=/\<(\w+)\s*([^\>]*)\>([^\>]*)\<\/(\w+)\>/gi;t="*"===n?t.replace(c,function(e,t,i,o,r){return"<"+t+">"+o+""}):"on*"===n?t.replace(c,function(t,i,o,r,n){var a=e("<"+i+">"+r+""),s=e(t)[0].attributes,l={};e.each(s,function(e,t){'"'!==t.nodeName&&(l[t.nodeName]=t.nodeValue)}),e.each(l,function(e){0===e.indexOf("on")&&delete l[e]}),a.attr(l);var c="undefined"!=typeof a[1]?e(a[1]).text():"";return a[0].outerHTML+c}):t.replace(c,function(t,i,o,r){var a=n.split(","),s=e(t);return s.html(r),e.each(a,function(e){s.attr(a[e],null)}),s[0].outerHTML})}return t},t.markdownToHTML=function(i,o){var r={gfm:!0,toc:!0,tocm:!1,tocStartLevel:1,tocTitle:"目录",tocDropdown:!1,tocContainer:"",markdown:"",markdownSourceCode:!1,htmlDecode:!1,autoLoadKaTeX:!0,pageBreak:!0,atLink:!0,emailLink:!0,tex:!1,taskList:!1,emoji:!1,flowChart:!1,sequenceDiagram:!1,previewCodeHighlight:!0};t.$marked=marked;var n=e("#"+i),a=n.settings=e.extend(!0,r,o||{}),s=n.find("textarea");s.length<1&&(n.append(""),s=n.find("textarea"));var l=""===a.markdown?s.val():a.markdown,c=[],h={toc:a.toc,tocm:a.tocm,tocStartLevel:a.tocStartLevel,taskList:a.taskList,emoji:a.emoji,tex:a.tex,pageBreak:a.pageBreak,atLink:a.atLink,emailLink:a.emailLink,flowChart:a.flowChart,sequenceDiagram:a.sequenceDiagram,previewCodeHighlight:a.previewCodeHighlight},d={renderer:t.markedRenderer(c,h),gfm:a.gfm,tables:!0,breaks:!0,pedantic:!1,sanitize:a.htmlDecode?!1:!0,smartLists:!0,smartypants:!0};l=new String(l);var u=marked(l,d);u=t.filterHTMLTags(u,a.htmlDecode),a.markdownSourceCode?s.text(l):s.remove(),n.addClass("markdown-body "+this.classPrefix+"html-preview").append(u);var f=""!==a.tocContainer?e(a.tocContainer):n;if(""!==a.tocContainer&&f.attr("previewContainer",!1),a.toc&&(n.tocContainer=this.markdownToCRenderer(c,f,a.tocDropdown,a.tocStartLevel),(a.tocDropdown||n.find("."+this.classPrefix+"toc-menu").length>0)&&this.tocDropdownMenu(n,a.tocTitle),""!==a.tocContainer&&n.find(".editormd-toc-menu, .editormd-markdown-toc").remove()),a.previewCodeHighlight&&(n.find("pre").addClass("prettyprint linenums"),prettyPrint()),t.isIE8||(a.flowChart&&n.find(".flowchart").flowChart(),a.sequenceDiagram&&n.find(".sequence-diagram").sequenceDiagram({theme:"simple"})),a.tex){var g=function(){n.find("."+t.classNames.tex).each(function(){var t=e(this);katex.render(t.html().replace(/</g,"<").replace(/>/g,">"),t[0]),t.find(".katex").css("font-size","1.6em")})};!a.autoLoadKaTeX||t.$katex||t.kaTeXLoaded?g():this.loadKaTeX(function(){t.$katex=katex,t.kaTeXLoaded=!0,g()})}return n.getMarkdown=function(){return s.val()},n},t.themes=["default","dark"],t.previewThemes=["default","dark"],t.editorThemes=["default","3024-day","3024-night","ambiance","ambiance-mobile","base16-dark","base16-light","blackboard","cobalt","eclipse","elegant","erlang-dark","lesser-dark","mbo","mdn-like","midnight","monokai","neat","neo","night","paraiso-dark","paraiso-light","pastel-on-dark","rubyblue","solarized","the-matrix","tomorrow-night-eighties","twilight","vibrant-ink","xq-dark","xq-light"],t.loadPlugins={},t.loadFiles={js:[],css:[],plugin:[]},t.loadPlugin=function(e,i,o){i=i||function(){},this.loadScript(e,function(){t.loadFiles.plugin.push(e),i()},o)},t.loadCSS=function(e,i,o){o=o||"head",i=i||function(){};var r=document.createElement("link");r.type="text/css",r.rel="stylesheet",r.onload=r.onreadystatechange=function(){t.loadFiles.css.push(e),i()},r.href=e+".css","head"===o?document.getElementsByTagName("head")[0].appendChild(r):document.body.appendChild(r)},t.isIE="Microsoft Internet Explorer"==navigator.appName,t.isIE8=t.isIE&&"8."==navigator.appVersion.match(/8./i),t.loadScript=function(e,i,o){o=o||"head",i=i||function(){};var r=null;r=document.createElement("script"),r.id=e.replace(/[\./]+/g,"-"),r.type="text/javascript",r.src=e+".js",t.isIE8?r.onreadystatechange=function(){r.readyState&&("loaded"===r.readyState||"complete"===r.readyState)&&(r.onreadystatechange=null,t.loadFiles.js.push(e),i())}:r.onload=function(){t.loadFiles.js.push(e),i()},"head"===o?document.getElementsByTagName("head")[0].appendChild(r):document.body.appendChild(r)},t.katexURL={css:"//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.3.0/katex.min",js:"//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.3.0/katex.min"},t.kaTeXLoaded=!1,t.loadKaTeX=function(e){t.loadCSS(t.katexURL.css,function(){t.loadScript(t.katexURL.js,e||function(){})})},t.lockScreen=function(t){e("html,body").css("overflow",t?"hidden":"")},t.createDialog=function(i){var o={name:"",width:420,height:240,title:"",drag:!0,closed:!0,content:"",mask:!0,maskStyle:{backgroundColor:"#fff",opacity:.1},lockScreen:!0,footer:!0,buttons:!1};i=e.extend(!0,o,i);var r=this,n=this.editor,a=t.classPrefix,s=(new Date).getTime(),l=""===i.name?a+"dialog-"+s:i.name,c=t.mouseOrTouch,h='
              ';""!==i.title&&(h+='
              ",h+=''+i.title+"",h+="
              "),i.closed&&(h+=''),h+='
              '+i.content,(i.footer||"string"==typeof i.footer)&&(h+='"),h+="
              ",h+='
              ',h+='
              ',h+="
              ",n.append(h);var d=n.find("."+l);d.lockScreen=function(t){return i.lockScreen&&(e("html,body").css("overflow",t?"hidden":""),r.resize()),d},d.showMask=function(){return i.mask&&n.find("."+a+"mask").css(i.maskStyle).css("z-index",t.dialogZindex-1).show(),d},d.hideMask=function(){return i.mask&&n.find("."+a+"mask").hide(),d},d.loading=function(e){var t=d.find("."+a+"dialog-mask");return t[e?"show":"hide"](),d},d.lockScreen(!0).showMask(),d.show().css({zIndex:t.dialogZindex,border:t.isIE8?"1px solid #ddd":"",width:"number"==typeof i.width?i.width+"px":i.width,height:"number"==typeof i.height?i.height+"px":i.height});var u=function(){d.css({top:(e(window).height()-d.height())/2+"px",left:(e(window).width()-d.width())/2+"px"})};if(u(),e(window).resize(u),d.children("."+a+"dialog-close").bind(c("click","touchend"),function(){d.hide().lockScreen(!1).hideMask()}),"object"==typeof i.buttons){var f=d.footer=d.find("."+a+"dialog-footer");for(var g in i.buttons){var p=i.buttons[g],m=a+g+"-btn";f.append('"),p[1]=e.proxy(p[1],d),f.children("."+m).bind(c("click","touchend"),p[1])}}if(""!==i.title&&i.drag){var w,v,k=d.children("."+a+"dialog-header");i.mask||k.bind(c("click","touchend"),function(){t.dialogZindex+=2,d.css("z-index",t.dialogZindex)}),k.mousedown(function(e){e=e||window.event,w=e.clientX-parseInt(d[0].style.left),v=e.clientY-parseInt(d[0].style.top),document.onmousemove=y});var b=function(e){e.removeClass(a+"user-unselect").off("selectstart")},x=function(e){e.addClass(a+"user-unselect").on("selectstart",function(e){return!1})},y=function(t){t=t||window.event;var i,o,r=parseInt(d[0].style.left),n=parseInt(d[0].style.top);r>=0?r+d.width()<=e(window).width()?i=t.clientX-w:(i=e(window).width()-d.width(),document.onmousemove=null):(i=0,document.onmousemove=null),n>=0?o=t.clientY-v:(o=0,document.onmousemove=null),document.onselectstart=function(){return!1},x(e("body")),x(d),d[0].style.left=i+"px",d[0].style.top=o+"px"};document.onmouseup=function(){b(e("body")),b(d),document.onselectstart=null,document.onmousemove=null},k.touchDraggable=function(){var t=null,i=function(i){var o=i.originalEvent,r=e(this).parent().position();t={x:o.changedTouches[0].pageX-r.left,y:o.changedTouches[0].pageY-r.top}},o=function(i){i.preventDefault();var o=i.originalEvent;e(this).parent().css({top:o.changedTouches[0].pageY-t.y,left:o.changedTouches[0].pageX-t.x})};this.bind("touchstart",i).bind("touchmove",o)},k.touchDraggable()}return t.dialogZindex+=2,d},t.mouseOrTouch=function(e,t){e=e||"click",t=t||"touchend";var i=e;try{document.createEvent("TouchEvent"),i=t}catch(o){}return i},t.dateFormat=function(e){e=e||"";var t=function(e){return 10>e?"0"+e:e},i=new Date,o=i.getFullYear(),r=o.toString().slice(2,4),n=t(i.getMonth()+1),a=t(i.getDate()),s=i.getDay(),l=t(i.getHours()),c=t(i.getMinutes()),h=t(i.getSeconds()),d=t(i.getMilliseconds()),u="",f=r+"-"+n+"-"+a,g=o+"-"+n+"-"+a,p=l+":"+c+":"+h;switch(e){case"UNIX Time":u=i.getTime();break;case"UTC":u=i.toUTCString();break;case"yy":u=r;break;case"year":case"yyyy":u=o;break;case"month":case"mm":u=n;break;case"cn-week-day":case"cn-wd":var m=["日","一","二","三","四","五","六"];u="星期"+m[s];break;case"week-day":case"wd":var w=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];u=w[s];break;case"day":case"dd":u=a;break;case"hour":case"hh":u=l;break;case"min":case"ii":u=c;break;case"second":case"ss":u=h;break;case"ms":u=d;break;case"yy-mm-dd":u=f;break;case"yyyy-mm-dd":u=g;break;case"yyyy-mm-dd h:i:s ms":case"full + ms":u=g+" "+p+" "+d;break;case"full":case"yyyy-mm-dd h:i:s":default:u=g+" "+p}return u},t}}); \ No newline at end of file +/*! Editor.md v1.7.17 | editormd.amd.min.js | Open source online markdown editor. | MIT License | By: IBM Skills Network | https://github.com/ibm-skills-network/editor.md | 2024-03-27 */ +!function(e){"use strict";var t;"function"==typeof require&&"object"==typeof exports&&"object"==typeof module?module.exports=e:"function"==typeof define?define.amd?define(["jquery","marked","prettify","katex","raphael","underscore","flowchart","jqueryflowchart","sequenceDiagram","codemirror/lib/codemirror",(t="codemirror/mode/")+"css/css",t+"sass/sass",t+"shell/shell",t+"sql/sql",t+"clike/clike",t+"php/php",t+"xml/xml",t+"markdown/markdown",t+"javascript/javascript",t+"htmlmixed/htmlmixed",t+"gfm/gfm",t+"http/http",t+"go/go",t+"dart/dart",t+"coffeescript/coffeescript",t+"nginx/nginx",t+"python/python",t+"perl/perl",t+"lua/lua",t+"r/r",t+"ruby/ruby",t+"rst/rst",t+"smartymixed/smartymixed",t+"vb/vb",t+"vbscript/vbscript",t+"velocity/velocity",t+"xquery/xquery",t+"yaml/yaml",t+"erlang/erlang",t+"jade/jade",(t="codemirror/addon/")+"edit/trailingspace",t+"dialog/dialog",t+"search/searchcursor",t+"search/search",t+"scroll/annotatescrollbar",t+"search/matchesonscrollbar",t+"display/placeholder",t+"edit/closetag",t+"fold/foldcode",t+"fold/foldgutter",t+"fold/indent-fold",t+"fold/brace-fold",t+"fold/xml-fold",t+"fold/markdown-fold",t+"fold/comment-fold",t+"mode/overlay",t+"selection/active-line",t+"edit/closebrackets",t+"display/fullscreen",t+"search/match-highlighter"],e):define(["jquery"],e):window.editormd=e()}(function(){"function"==typeof define&&define.amd&&(v=arguments[0],marked=arguments[1],prettify=arguments[2],katex=arguments[3],Raphael=arguments[4],_=arguments[5],flowchart=arguments[6],CodeMirror=arguments[9]);var C,c,h,e,d,v="undefined"!=typeof jQuery?jQuery:Zepto;if(void 0!==v)return(C=function(e,t,i){return new C.fn.init(e,t,i)}).title=C.$name="Editor.md",C.version="1.7.17",C.homePage="https://pandao.github.io/editor.md/",C.classPrefix="editormd-",C.toolbarModes={full:["undo","redo","|","bold","del","italic","quote","ucwords","uppercase","lowercase","|","h1","h2","h3","h4","h5","h6","|","list-ul","list-ol","hr","|","link","reference-link","image","code","preformatted-text","code-block","table","datetime","emoji","html-entities","pagebreak","|","goto-line","watch","preview","fullscreen","clear","search","|","help","changetheme","info"],simple:["undo","redo","|","bold","del","italic","quote","uppercase","lowercase","|","h1","h2","h3","h4","h5","h6","|","list-ul","list-ol","hr","|","watch","preview","fullscreen","|","help","changetheme","info"],mini:["undo","redo","|","watch","preview","|","help","changetheme","info"]},C.defaults={debug:!1,mode:"gfm",name:"",value:"",theme:"",editorTheme:"default",previewTheme:"",markdown:void 0,appendMarkdown:"",width:"100%",height:"100%",path:"./lib/",pluginPath:"",customPluginPath:"",delay:300,autoLoadModules:!0,watch:!0,placeholder:"Enjoy Markdown! coding now...",gotoLine:!0,codeFold:!1,autoHeight:!1,autoFocus:!0,autoCloseTags:!0,searchReplace:!0,syncScrolling:!0,readOnly:!1,tabSize:4,indentUnit:4,lineNumbers:!0,lineWrapping:!0,autoCloseBrackets:!0,showTrailingSpace:!0,matchBrackets:!0,indentWithTabs:!0,styleSelectedText:!0,matchWordHighlight:!0,styleActiveLine:!0,dialogLockScreen:!0,dialogShowMask:!0,dialogDraggable:!0,dialogMaskBgColor:"#fff",dialogMaskOpacity:.1,fontSize:"13px",saveHTMLToTextarea:!1,disabledKeyMaps:[],onload:function(){},onresize:function(){},onchange:function(){},onwatch:null,onunwatch:null,onpreviewing:function(){},onCmChange:null,fixCodeBlocks:function(){},onpreviewed:function(){},onfullscreen:function(){},onfullscreenExit:function(){},onscroll:function(){},onpreviewscroll:function(){},imageUpload:!1,imageFormats:["jpg","jpeg","gif","png","bmp","webp"],imageUploadURL:"",crossDomainUpload:!1,uploadCallbackURL:"",toc:!0,tocm:!1,tocTitle:"",tocDropdown:!1,tocContainer:"",tocStartLevel:1,htmlDecode:!1,pageBreak:!0,atLink:!0,emailLink:!0,taskList:!1,emoji:!0,tex:!1,flowChart:!1,sequenceDiagram:!1,mermaid:!0,mindMap:!0,previewCodeHighlight:!0,toolbar:!0,toolbarAutoFixed:!0,titlebar:{left:{},center:{},right:{}},toolbarIcons:"full",toolbarTitles:{},toolbarHandlers:{ucwords:function(){return C.toolbarHandlers.ucwords},lowercase:function(){return C.toolbarHandlers.lowercase}},toolbarCustomIcons:{lowercase:'a',ucwords:'Aa',fontcase:'Aa'},toolbarIconsClass:{undo:"fa-undo",redo:"fa-repeat",bold:"fa-bold",del:"fa-strikethrough",italic:"fa-italic",quote:"fa-quote-left",uppercase:"fa-font",heading:"fa-header",h1:C.classPrefix+"bold",h2:C.classPrefix+"bold",h3:C.classPrefix+"bold",h4:C.classPrefix+"bold",h5:C.classPrefix+"bold",h6:C.classPrefix+"bold","list-ul":"fa-list-ul","list-ol":"fa-list-ol",hr:"fa-minus",link:"fa-link","reference-link":"fa-anchor",image:"fa-picture-o",code:"fa-code","preformatted-text":"fa-file-code-o","code-block":"fa-file-code-o",table:"fa-table",datetime:"fa-clock-o",emoji:"fa-smile-o","html-entities":"fa-copyright",pagebreak:"fa-newspaper-o","goto-line":"fa-terminal",watch:"fa-eye-slash",unwatch:"fa-eye",preview:"fa-desktop",search:"fa-search",fullscreen:"fa-arrows-alt",clear:"fa-eraser",help:"fa-question-circle",changetheme:"fa-info-circle",info:"fa-info-circle"},toolbarIconTexts:{ucwords:"Capitalize",uppercase:"Uppercase",lowercase:"Lowercase",h1:"Heading 1",h2:"Heading 2",h3:"Heading 3",h4:"Heading 4",h5:"Heading 5",h6:"Heading 6"},lang:{name:"zh-cn",description:"开源在线Markdown编辑器
              Open source online Markdown editor.",tocTitle:"目录",toolbar:{undo:"撤销(Ctrl+Z)",redo:"重做(Ctrl+Y)",bold:"粗体",del:"删除线",italic:"斜体",quote:"引用",ucwords:"将每个单词首字母转成大写",uppercase:"将所选转换成大写",lowercase:"将所选转换成小写",h1:"标题1",h2:"标题2",h3:"标题3",h4:"标题4",h5:"标题5",h6:"标题6","list-ul":"无序列表","list-ol":"有序列表",hr:"横线",link:"链接","reference-link":"引用链接",image:"添加图片",code:"行内代码","preformatted-text":"预格式文本 / 代码块(缩进风格)","code-block":"代码块(多语言风格)",table:"添加表格",datetime:"日期时间",emoji:"Emoji表情","html-entities":"HTML实体字符",pagebreak:"插入分页符","goto-line":"跳转到行",watch:"关闭实时预览",unwatch:"开启实时预览",preview:"全窗口预览HTML(按 Shift + ESC还原)",fullscreen:"全屏(按ESC还原)",clear:"清空",search:"搜索",help:"使用帮助",changetheme:"切换编辑主题",info:"关于"+C.title},buttons:{enter:"确定",cancel:"取消",close:"关闭"},dialog:{link:{title:"添加链接",url:"链接地址",urlTitle:"链接标题",urlEmpty:"错误:请填写链接地址。"},referenceLink:{title:"添加引用链接",name:"引用名称",url:"链接地址",urlId:"链接ID",urlTitle:"链接标题",nameEmpty:"错误:引用链接的名称不能为空。",idEmpty:"错误:请填写引用链接的ID。",urlEmpty:"错误:请填写引用链接的URL地址。"},image:{title:"添加图片",url:"图片地址",link:"图片链接",alt:"图片描述",uploadButton:"本地上传",imageURLEmpty:"错误:图片地址不能为空。",uploadFileEmpty:"错误:上传的图片不能为空。",formatNotAllowed:"错误:只允许上传图片文件,允许上传的图片文件格式有:"},preformattedText:{title:"添加预格式文本或代码块",emptyAlert:"错误:请填写预格式文本或代码的内容。"},codeBlock:{title:"添加代码块",selectLabel:"代码语言:",selectDefaultText:"请选择代码语言",otherLanguage:"其他语言",unselectedLanguageAlert:"错误:请选择代码所属的语言类型。",codeEmptyAlert:"错误:请填写代码内容。"},htmlEntities:{title:"HTML 实体字符"},help:{title:"使用帮助"},changetheme:{title:"切换编辑主题"}}}},C.classNames={tex:C.classPrefix+"tex",texDisplay:C.classPrefix+"texDisaply"},C.dialogZindex=99999,C.$katex=null,C.$marked=null,C.$filterXSS=null,C.$CodeMirror=null,C.$prettyPrint=null,C.prototype=C.fn={state:{watching:!1,loaded:!1,preview:!1,fullscreen:!1},init:function(e,t,i){i="object"==typeof e?e:i||{};var o=this.classPrefix=C.classPrefix,i=this.settings=v.extend(!0,{},C.defaults,i),n=(e="object"==typeof e?i.id:e,this.editor=v("#"+e)),t=(this.id=e,this.author_ide_version=t||n.version,this.lang=i.lang,this.classNames={textarea:{html:o+"html-textarea",markdown:o+"markdown-textarea"}}),r=(i.pluginPath=""===i.pluginPath?i.path+"../plugins/":i.pluginPath,this.state.watching=!!i.watch,n.hasClass("editormd")||n.addClass("editormd"),n.css({width:"number"==typeof i.width?i.width+"px":i.width,height:"number"==typeof i.height?i.height+"px":i.height}),i.autoHeight&&n.css("height","auto"),this.markdownTextarea=n.children("textarea")),e=(r.length<1&&(n.append(""),r=this.markdownTextarea=n.children("textarea")),r.addClass(t.textarea.markdown).attr("placeholder",i.placeholder),void 0!==r.attr("name")&&""!==r.attr("name")||r.attr("name",""!==i.name?i.name:e+"-markdown-doc"),[i.readOnly?"":'',i.saveHTMLToTextarea?'':"",'
              ','
              ','
              '].join("\n"));return n.append(e).addClass(o+"vertical"),""!==i.theme&&n.addClass(o+"theme-"+i.theme),this.mask=n.children("."+o+"mask"),this.containerMask=n.children("."+o+"container-mask"),void 0!==i.markdown&&r.val(i.markdown),""!==i.appendMarkdown&&r.val(r.val()+i.appendMarkdown),this.htmlTextarea=n.children("."+t.textarea.html),this.preview=n.children("."+o+"preview"),this.previewContainer=this.preview.children("."+o+"preview-container"),""!==i.previewTheme&&this.preview.addClass(o+"preview-theme-"+i.previewTheme),"function"==typeof define&&define.amd&&("undefined"!=typeof katex&&(C.$katex=katex),i.searchReplace)&&!i.readOnly&&(C.loadCSS(i.path+"codemirror/addon/dialog/dialog"),C.loadCSS(i.path+"codemirror/addon/search/matchesonscrollbar")),"function"==typeof define&&define.amd||!i.autoLoadModules?("undefined"!=typeof CodeMirror&&(C.$CodeMirror=CodeMirror),"undefined"!=typeof marked&&(C.$marked=marked),this.setCodeMirror().setToolbar().loadedDisplay()):this.loadQueues(),this},loadQueues:function(){function e(){!C.isIE8&&(i.flowChart||i.sequenceDiagram)?C.loadScript(o+"raphael.min",function(){C.loadScript(o+"underscore.min",function(){!i.flowChart&&i.sequenceDiagram?C.loadScript(o+"sequence-diagram.min",function(){t.loadedDisplay()}):i.flowChart&&!i.sequenceDiagram?C.loadScript(o+"flowchart.min",function(){C.loadScript(o+"jquery.flowchart.min",function(){t.loadedDisplay()})}):i.flowChart&&i.sequenceDiagram&&C.loadScript(o+"flowchart.min",function(){C.loadScript(o+"jquery.flowchart.min",function(){C.loadScript(o+"sequence-diagram.min",function(){t.loadedDisplay()})})})})}):t.loadedDisplay()}var t=this,i=this.settings,o=i.path;return C.loadScript(o+"xss",function(){C.$filterXSS=filterXSS}),C.loadCSS(o+"codemirror/codemirror.min"),i.searchReplace&&!i.readOnly&&(C.loadCSS(o+"codemirror/addon/dialog/dialog"),C.loadCSS(o+"codemirror/addon/search/matchesonscrollbar")),i.codeFold&&C.loadCSS(o+"codemirror/addon/fold/foldgutter"),C.loadScript(o+"codemirror/codemirror.min",function(){C.$CodeMirror=CodeMirror,C.loadScript(o+"codemirror/modes.min",function(){C.loadScript(o+"codemirror/addons.min",function(){if(t.setCodeMirror(),"gfm"!==i.mode&&"markdown"!==i.mode)return t.loadedDisplay(),!1;t.setToolbar(),C.loadScript(o+"marked.min",function(){C.$marked=marked,i.highlightStyle||(i.highlightStyle="github"),i.previewCodeHighlight?(C.loadCSS(o+"highlight/styles/"+i.highlightStyle),C.loadScript(o+"highlight/highlight",function(){e()})):e()})})})}),this},setTheme:function(e){var t=this.editor,i=this.settings.theme,o=this.classPrefix+"theme-";return t.removeClass(o+i).addClass(o+e),this.settings.theme=e,this},setEditorTheme:function(e){var t=this.settings;return"default"!==(t.editorTheme=e)&&C.loadCSS(t.path+"codemirror/theme/"+t.editorTheme),this.cm.setOption("theme",e),this},setCodeMirrorTheme:function(e){return this.setEditorTheme(e),this},setPreviewTheme:function(e){var t=this.preview,i=this.settings.previewTheme,o=this.classPrefix+"preview-theme-";return t.removeClass(o+i).addClass(o+e),this.settings.previewTheme=e,this},setCodeMirror:function(){var e=this.settings,t=this.editor,i=("default"!==e.editorTheme&&C.loadCSS(e.path+"codemirror/theme/"+e.editorTheme),{mode:e.mode,theme:e.editorTheme,tabSize:e.tabSize,dragDrop:!1,autofocus:e.autoFocus,autoCloseTags:e.autoCloseTags,readOnly:!!e.readOnly&&"nocursor",indentUnit:e.indentUnit,lineNumbers:e.lineNumbers,lineWrapping:e.lineWrapping,extraKeys:{"Ctrl-Q":function(e){e.foldCode(e.getCursor())}},foldGutter:e.codeFold,gutters:["CodeMirror-linenumbers","CodeMirror-foldgutter"],matchBrackets:e.matchBrackets,indentWithTabs:e.indentWithTabs,styleActiveLine:e.styleActiveLine,styleSelectedText:e.styleSelectedText,autoCloseBrackets:e.autoCloseBrackets,showTrailingSpace:e.showTrailingSpace,highlightSelectionMatches:!!e.matchWordHighlight&&{showToken:"onselected"!==e.matchWordHighlight&&/\w/}});return this.codeEditor=this.cm=C.$CodeMirror.fromTextArea(this.markdownTextarea[0],i),this.codeMirror=this.cmElement=t.children(".CodeMirror"),""!==e.value&&this.cm.setValue(e.value),this.codeMirror.css({fontSize:e.fontSize,width:e.watch?"50%":"100%"}),e.autoHeight&&(this.codeMirror.css("height","auto"),this.cm.setOption("viewportMargin",1/0)),e.lineNumbers||this.codeMirror.find(".CodeMirror-gutters").css("border-right","none"),this},getCodeMirrorOption:function(e){return this.cm.getOption(e)},setCodeMirrorOption:function(e,t){return this.cm.setOption(e,t),this},addKeyMap:function(e,t){return this.cm.addKeyMap(e,t),this},removeKeyMap:function(e){return this.cm.removeKeyMap(e),this},gotoLine:function(e){var t,i,o,n,r=this.settings;return r.gotoLine&&(t=this.cm,this.editor,o=t.lineCount(),i=this.preview,"number"!=typeof(e="string"==typeof e&&"first"===(e="last"===e?o:e)?1:e)?alert("Error: The line number must be an integer."):o<(e=parseInt(e)-1)?alert("Error: The line number range 1-"+o):(t.setCursor({line:e,ch:0}),o=t.getScrollInfo().clientHeight,e=t.charCoords({line:e,ch:0},"local"),t.scrollTo(null,(e.top+e.bottom-o)/2),r.watch&&(e=this.codeMirror.find(".CodeMirror-scroll")[0],o=v(e).height(),n=(r=e.scrollTop)/e.scrollHeight,0===r?i.scrollTop(0):r+o>=e.scrollHeight-16?i.scrollTop(i[0].scrollHeight):i.scrollTop(i[0].scrollHeight*n)),t.focus())),this},extend:function(){return void 0!==arguments[1]&&("function"==typeof arguments[1]&&(arguments[1]=v.proxy(arguments[1],this)),this[arguments[0]]=arguments[1]),"object"==typeof arguments[0]&&void 0===arguments[0].length&&v.extend(!0,this,arguments[0]),this},set:function(e,t){return void 0!==t&&"function"==typeof t&&(t=v.proxy(t,this)),this[e]=t,this},config:function(e,t){var i=this.settings;return"object"==typeof e&&(i=v.extend(!0,i,e)),"string"==typeof e&&(i[e]=t),this.settings=i,this.recreate(),this},on:function(e,t){var i=this.settings;return void 0!==i["on"+e]&&(i["on"+e]=v.proxy(t,this)),this},off:function(e){var t=this.settings;return void 0!==t["on"+e]&&(t["on"+e]=function(){}),this},showToolbar:function(e){var t=this.settings;return t.readOnly||(t.toolbar&&(this.toolbar.length<1||""===this.toolbar.find("."+this.classPrefix+"menu").html())&&this.setToolbar(),t.toolbar=!0,this.toolbar.show(),this.resize(),v.proxy(e||function(){},this)()),this},hideToolbar:function(e){return this.settings.toolbar=!1,this.toolbar.hide(),this.resize(),v.proxy(e||function(){},this)(),this},setToolbarAutoFixed:function(e){var t=this.state,i=this.editor,o=this.toolbar,n=this.settings;void 0!==e&&(n.toolbarAutoFixed=e);return!t.fullscreen&&!t.preview&&n.toolbar&&n.toolbarAutoFixed&&v(window).bind("scroll",function(){var e=v(window),t=e.scrollTop();if(!n.toolbarAutoFixed)return!1;10
            • '),i=this.toolbar=e.children("."+s+"toolbar")),a.toolbar){for(var l="",o=(Object.entries(t).forEach(([e,t])=>{var i="";if("left"===e)i='Skills Network Author IDE';else for(var o in t){var n=o.replace(/\s+/g,"-").toLowerCase(),r="string"==typeof a.lang.titlebar[o]?a.lang.titlebar[o]:"";switch(t[o]){case"dropdown":i+='
              ';break;case"button":i+='";break;default:i+=''+o+""}}l+='
              '+i+"
              "}),i.find("div."+s+"titlebar-container").html(l),i.show(),"function"==typeof a.toolbarIcons?a.toolbarIcons():"string"==typeof a.toolbarIcons?C.toolbarModes[a.toolbarIcons]:a.toolbarIcons),e=i.find("."+this.classPrefix+"menu"),n="",r=!1,c=0,h=o.length;c';else{var d,u,f=u.includes("dropdown"),p=[],g=(r&&p.push("pull-right"),f&&p.push("dropdown"),0':"
            • "),m=[];f?(d=(p=u.split(":"))[0],u=p[1],p=p[2].split(","),m=[u].concat(p),p.length||(f=!1)):m.push(u);for(var w=0,h=m.length;w');var v=!(f&&"dropdownIcon"!==d&&g.includes("toolbar-dropdown-content")),b=/h(\d)/.test(u),x=u,k=("watch"!==u||a.watch||(x="unwatch"),a.lang.toolbar[x]),y=void 0===(y=a.toolbarIconTexts[x])?"":y,x=void 0!==(x=a.toolbarIconsClass[x])&&v?x:"";g+='',v&&void 0!==a.toolbarCustomIcons[u]&&"function"!=typeof a.toolbarCustomIcons[u]?g+=a.toolbarCustomIcons[u]:(g+='',"function"!=typeof a.toolbarIcons&&b?g+=''+u.toUpperCase()+"":d&&"dropdownIcon"===d&&g.includes("toolbar-dropdown-content")?g+=''+(y||u)+"":""!==x&&v||(g+=''+(y||u)+""),g+=""),g+="",f&&w===h-1&&g.includes("toolbar-dropdown-content")&&(g+="
            • ",d="")}g+="",n=r?g+n:n+g}e.html(n),e.find('[title="Lowercase"]').attr("title",a.lang.toolbar.lowercase),e.find('[title="ucwords"]').attr("title",a.lang.toolbar.ucwords),this.setToolbarHandler(),this.setToolbarAutoFixed()}else i.hide()}return this},dialogLockScreen:function(){return v.proxy(C.dialogLockScreen,this)(),this},dialogShowMask:function(e){return v.proxy(C.dialogShowMask,this)(e),this},positionDialog:function(e,t){return v.proxy(C.positionDialog,this)(e,t),this},getToolbarHandles:function(e){var t=this.toolbarHandlers=C.toolbarHandlers;return e&&void 0!==toolbarIconHandlers[e]?t[e]:t},setToolbarHandler:function(){var n,e,t,r,a=this,s=this.settings;return s.toolbar&&!s.readOnly&&(t=this.toolbar,n=this.cm,e=this.classPrefix,t=this.toolbarIcons=t.find("."+e+"menu > li a"),r=this.getToolbarHandles(),t.bind(C.mouseOrTouch("click","touchend"),function(){var e=v(this).children(".fa"),t=e.attr("name"),i=n.getCursor(),o=n.getSelection();if(""!==t)return a.activeIcon=e,void 0!==r[t]?v.proxy(r[t],a)(n):void 0!==s.toolbarHandlers[t]&&v.proxy(s.toolbarHandlers[t],a)(n,e,i,o),"link"!==t&&"reference-link"!==t&&"image"!==t&&"code-block"!==t&&"preformatted-text"!==t&&"watch"!==t&&"preview"!==t&&"search"!==t&&"fullscreen"!==t&&"info"!==t&&n.focus(),!1})),this},createDialog:function(e){return v.proxy(C.createDialog,this)(e)},createInfoDialog:function(){var e=this,t=this.editor,i=this.classPrefix,o=['
              ','
              ','

              '+C.title+"v"+C.version+"

              ","

              "+this.lang.description+"

              ",'

              '+C.homePage+'

              ','

              Copyright © 2015 Pandao, The MIT License.

              ',"
              ",'',"
              "].join("\n"),o=(t.append(o),this.infoDialog=t.children("."+i+"dialog-info"));return o.find("."+i+"dialog-close").bind(C.mouseOrTouch("click","touchend"),function(){e.hideInfoDialog()}),o.css("border",C.isIE8?"1px solid #ddd":"").css("z-index",C.dialogZindex).show(),this.infoDialogPosition(),this},infoDialogPosition:function(){function e(){t.css({top:(v(window).height()-t.height())/2+"px",left:(v(window).width()-t.width())/2+"px"})}var t=this.infoDialog;return e(),v(window).resize(e),this},showInfoDialog:function(){v("html,body").css("overflow-x","hidden");var e=this.editor,t=this.settings,e=this.infoDialog=e.children("."+this.classPrefix+"dialog-info");return e.length<1&&this.createInfoDialog(),this.lockScreen(!0),this.mask.css({opacity:t.dialogMaskOpacity,backgroundColor:t.dialogMaskBgColor}).show(),e.css("z-index",C.dialogZindex).show(),this.infoDialogPosition(),this},hideInfoDialog:function(){return v("html,body").css("overflow-x",""),this.infoDialog.hide(),this.mask.hide(),this.lockScreen(!1),this},lockScreen:function(e){return C.lockScreen(e),this.resize(),this},recreate:function(){var e=this.editor,t=this.settings;return this.codeMirror.remove(),this.setCodeMirror(),t.readOnly||(0=e[0].scrollHeight-16?i.scrollTop(i[0].scrollHeight):i.scrollTop((i[0].scrollHeight+r+a)*n)}return this},registerKeyMaps:function(e){var t=this,i=this.cm,o=this.settings,n=C.toolbarHandlers,r=o.disabledKeyMaps;if(e=e||null)for(var a in e)v.inArray(a,r)<0&&(e[a],i.addKeyMap(e));else{for(var s in C.keyMaps){var l,c=C.keyMaps[s],c="string"==typeof c?v.proxy(n[c],t):v.proxy(c,t);v.inArray(s,["F9","F10","F11"])<0&&v.inArray(s,r)<0&&((l={})[s]=c,i.addKeyMap(l))}v(window).keydown(function(e){if(v.inArray({120:"F9",121:"F10",122:"F11"}[e.keyCode],r)<0)switch(e.keyCode){case 120:return v.proxy(n.watch,t)(),!1;case 121:return v.proxy(n.preview,t)(),!1;case 122:return v.proxy(n.fullscreen,t)(),!1}})}return this},bindScrollEvent:function(){var e,t,i,o,a=this,s=this.previewContainer,l=this.settings,r=this.codeMirror,n=C.mouseOrTouch;return l.syncScrolling&&(i=function(){s.bind(n("scroll","touchmove"),function(e){var t,i,o,n;null==c&&(t=v(this).height(),o=(i=v(this).scrollTop())/v(this)[0].scrollHeight,n=r.find(".CodeMirror-scroll"),0===i?n.scrollTop(0):i+t>=v(this)[0].scrollHeight?n.scrollTop(n[0].scrollHeight):n.scrollTop(n[0].scrollHeight*o),v.proxy(l.onpreviewscroll,a)(e))})},o=function(){s.unbind(n("scroll","touchmove"))},r.bind({mouseover:e=function(){r.find(".CodeMirror-scroll").bind(n("scroll","touchmove"),function(e){var t,i,o,n,r;null==c&&(t=v(this).height(),o=(i=v(this).scrollTop())/v(this)[0].scrollHeight,n=0,s.find(".markdown-toc-list").each(function(){n+=v(this).height()}),r=(r=s.find(".editormd-toc-menu").height())||0,0===i?s.scrollTop(0):i+t>=v(this)[0].scrollHeight-16?s.scrollTop(s[0].scrollHeight):s.scrollTop((s[0].scrollHeight+n+r)*o),v.proxy(l.onscroll,a)(e))})},mouseout:t=function(){r.find(".CodeMirror-scroll").unbind(n("scroll","touchmove"))},touchstart:e,touchend:t}),"single"!==l.syncScrolling)&&s.bind({mouseover:i,mouseout:o,touchstart:i,touchend:o}),this},bindChangeEvent:function(){var i=this,e=this.cm,o=this.settings;return e.on("change",function(e,t){o.watch&&i.previewContainer.css("padding",o.autoHeight?"20px 20px 50px 40px":"20px"),c&&clearTimeout(c),o.onCmChange&&v.proxy(o.onCmChange,i)(),c=setTimeout(function(){i.save(),c=null},o.delay)}),this},loadedDisplay:function(e){e=e||!1;var t=this,i=this.editor,o=this.preview,n=this.settings;return this.containerMask.hide(),this.save(),n.watch&&o.show(),i.data("oldWidth",i.width()).data("oldHeight",i.height()),this.resize(),this.registerKeyMaps(),v(window).resize(function(){t.resize()}),this.bindScrollEvent().bindChangeEvent(),e||v.proxy(n.onload,this)(),this.state.loaded=!0,n.watch&&(this.save(),o.show()),this},width:function(e){return this.editor.css("width","number"==typeof e?e+"px":e),this.resize(),this},height:function(e){return this.editor.css("height","number"==typeof e?e+"px":e),this.resize(),this},resize:function(e,t){t=t||null;var i=this.state,o=this.editor,n=this.preview,r=this.toolbar,a=this.settings,s=this.codeMirror;return(e=e||null)&&o.css("width","number"==typeof e?e+"px":e),!a.autoHeight||i.fullscreen||i.preview?(t&&o.css("height","number"==typeof t?t+"px":t),i.fullscreen&&o.height(v(window).height()),a.toolbar&&!a.readOnly?s.css("margin-top",r.height()+1).height(o.height()-r.height()):s.css("margin-top",0).height(o.height())):(o.css("height","auto"),s.css("height","auto")),a.watch?(s.width(o.width()/2),n.width(i.preview?o.width():o.width()/2),this.previewContainer.css("padding",a.autoHeight?"20px 20px 50px 40px":"20px"),a.toolbar&&!a.readOnly?n.css("top",r.height()+1):n.css("top",0),!a.autoHeight||i.fullscreen||i.preview?(e=a.toolbar&&!a.readOnly?o.height()-r.height():o.height(),n.height(e)):n.height("")):(s.width(o.width()),n.hide()),i.loaded&&v.proxy(a.onresize,this)(),this},save:function(){var e,t,i,o=this,n=this.state,r=this.settings,a=this.cm,s=a.getValue(),l=this.previewContainer;return(null!==c||!r.watch&&n.preview)&&("gfm"!==r.mode&&"markdown"!==r.mode?this.markdownTextarea.val(s):(a.save(),(r.saveHTMLToTextarea||r.watch||!r.watch&&n.preview)&&(t=C.$marked,e=this.markdownToC=[],i=this.markedRendererOptions={toc:r.toc,tocm:r.tocm,tocStartLevel:r.tocStartLevel,pageBreak:r.pageBreak,taskList:r.taskList,emoji:r.emoji,tex:r.tex,atLink:r.atLink,emailLink:r.emailLink,flowChart:r.flowChart,sequenceDiagram:r.sequenceDiagram,previewCodeHighlight:r.previewCodeHighlight,mermaid:r.mermaid,mindMap:r.mindMap},i=this.markedOptions={renderer:C.markedRenderer(e,i),gfm:!0,tables:!0,breaks:!0,pedantic:!1,sanitize:!r.htmlDecode,smartLists:!0,smartypants:!0},t.setOptions(i),t=C.$marked.parse(s,i),r.debug&&console.info("cmValue",s,t),t=C.$filterXSS(t),this.markdownTextarea.text(s),a.save(),r.saveHTMLToTextarea&&this.htmlTextarea.text(t),r.watch||!r.watch&&n.preview)&&(l.html(t),this.previewCodeHighlight(),r.toc&&(s=(i=""===r.tocContainer?l:v(r.tocContainer)).find("."+this.classPrefix+"toc-menu"),i.attr("previewContainer",""===r.tocContainer?"true":"false"),""!==r.tocContainer&&0{C.loadPlugin(i,function(){C.loadPlugins[t]=r[t],e(r[t](a,n))},"head",o?r.author_ide_version:C.version)});C.loadPlugin(i,function(){C.loadPlugins[t]=r[t],r[t](a,n)},"head",o?r.author_ide_version:C.version)}else{if(n.proxy)return v.proxy(C.loadPlugins[t],this)(a,n);v.proxy(C.loadPlugins[t],this)(a,n)}return this},search:function(e){var t=this.settings;return t.searchReplace?t.readOnly||this.cm.execCommand(e||"find"):alert("Error: settings.searchReplace == false"),this},searchReplace:function(){return this.search("replace"),this},searchReplaceAll:function(){return this.search("replaceAll"),this}},C.fn.init.prototype=C.fn,C.dialogLockScreen=function(){(this.settings||{dialogLockScreen:!0}).dialogLockScreen&&(v("html,body").css("overflow","hidden"),this.resize())},C.positionDialog=function(e,t="center"){var i,o;switch(t){case"center":i=(v(window).width()-e.width())/2+"px",o=(v(window).height()-e.height())/2+"px";break;case"center-left":i=v(window).width()/4-e.width()/2+"px",o=(v(window).height()-e.height())/2+"px";break;case"center-right":i=3*v(window).width()/4-e.width()/2+"px",o=(v(window).height()-e.height())/2+"px";break;default:console.warn("Unsupported dialog position: "+t),i=(v(window).width()-e.width())/2+"px",o=(v(window).height()-e.height())/2+"px"}e.css({top:o,left:i})},C.dialogShowMask=function(e){var t=this.editor,i=this.settings||{dialogShowMask:!0};e.css({top:(v(window).height()-e.height())/2+"px",left:(v(window).width()-e.width())/2+"px"}),i.dialogShowMask&&t.children("."+this.classPrefix+"mask").css("z-index",parseInt(e.css("z-index"))-1).show()},C.toolbarHandlers={undo:function(){this.cm.undo()},redo:function(){this.cm.redo()},bold:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection("**"+i+"**"),""===i&&e.setCursor(t.line,t.ch+2)},del:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection("~~"+i+"~~"),""===i&&e.setCursor(t.line,t.ch+2)},italic:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection("*"+i+"*"),""===i&&e.setCursor(t.line,t.ch+1)},quote:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("> "+i),e.setCursor(t.line,t.ch+2)):e.replaceSelection("> "+i)},ucfirst:function(){var e=this.cm,t=e.getSelection(),i=e.listSelections();e.replaceSelection(C.firstUpperCase(t)),e.setSelections(i)},ucwords:function(){var e=this.cm,t=e.getSelection(),i=e.listSelections();e.replaceSelection(C.wordsFirstUpperCase(t)),e.setSelections(i)},uppercase:function(){var e=this.cm,t=e.getSelection(),i=e.listSelections();e.replaceSelection(t.toUpperCase()),e.setSelections(i)},lowercase:function(){var e=this.cm,t=(e.getCursor(),e.getSelection()),i=e.listSelections();e.replaceSelection(t.toLowerCase()),e.setSelections(i)},h1:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection(),o=new RegExp("^#{1}[ ]"),n=new RegExp("^#{1,6}[ ]");!0===o.test(i)?(i=i.replace(/^#{1}[ ]/,""),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection(i+"\n"),e.setCursor(t.line,t.ch-2)):(!0===n.test(i)&&(i=i.replace(/^#{1,6}[ ]/,"")),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection("# "+i+"\n"),e.setCursor(t.line,t.ch+2))},h2:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection(),o=new RegExp("^#{2}[ ]"),n=new RegExp("^#{1,6}[ ]");!0===o.test(i)?(i=i.replace(/^#{2}[ ]/,""),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection(i+"\n"),e.setCursor(t.line,t.ch-3)):(!0===n.test(i)&&(i=i.replace(/^#{1,6}[ ]/,"")),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection("## "+i+"\n"),e.setCursor(t.line,t.ch+3))},h3:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection(),o=new RegExp("^#{3}[ ]"),n=new RegExp("^#{1,6}[ ]");!0===o.test(i)?(i=i.replace(/^#{3}[ ]/,""),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection(i+"\n"),e.setCursor(t.line,t.ch-4)):(!0===n.test(i)&&(i=i.replace(/^#{1,6}[ ]/,"")),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection("### "+i+"\n"),e.setCursor(t.line,t.ch+4))},h4:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection(),o=new RegExp("^#{4}[ ]"),n=new RegExp("^#{1,6}[ ]");!0===o.test(i)?(i=i.replace(/^#{4}[ ]/,""),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection(i+"\n"),e.setCursor(t.line,t.ch-5)):(!0===n.test(i)&&(i=i.replace(/^#{1,6}[ ]/,"")),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection("#### "+i+"\n"),e.setCursor(t.line,t.ch+5))},h5:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection(),o=new RegExp("^#{5}[ ]"),n=new RegExp("^#{1,6}[ ]");!0===o.test(i)?(i=i.replace(/^#{5}[ ]/,""),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection(i+"\n"),e.setCursor(t.line,t.ch-6)):(!0===n.test(i)&&(i=i.replace(/^#{1,6}[ ]/,"")),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection("##### "+i+"\n"),e.setCursor(t.line,t.ch+6))},h6:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection(),o=new RegExp("^#{6}[ ]"),n=new RegExp("^#{1,6}[ ]");!0===o.test(i)?(i=i.replace(/^#{6}[ ]/,""),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection(i+"\n"),e.setCursor(t.line,t.ch-7)):(!0===n.test(i)&&(i=i.replace(/^#{1,6}[ ]/,"")),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection("###### "+i+"\n"),e.setCursor(t.line,t.ch+7))},"list-ul":function(){var e=this.cm,t=e.getCursor(),i=e.getSelection(),o=new RegExp("^-{1}[ ]"),n=0;if(""===i)e.setCursor(t.line,0),e.replaceSelection("- "+i),e.setCursor(t.line,t.ch+2);else{for(var r=i.split("\n"),a=0,s=r.length;a/i),i=(null!==i&&(t=i[0],e=e.substr(t.length)),"default");return 0===e.indexOf("[info]")?(i="info",e=e.substr(6)):0===e.indexOf("[warning]")?(i="warning",e=e.substr(9)):0===e.indexOf("[success]")?(i="success",e=e.substr(9)):0===e.indexOf("[danger]")&&(i="danger",e=e.substr(8)),'
              \n'+t+e+"
              \n"},e.image=function(e,t,i){var o,n,r,a="",s="",l="";return e&&""!==e&&((o=document.createElement("a")).href=e,null!==(n=o.hash.match(/size=\d+x\d+/i))&&(o.hash=o.hash.replace(n[0],""),e=o.href,0<(n=n[0].replace("size=","").split("x"))[0]&&(a+=' width="'+n[0]+'"'),0","center"===(n=n[0].replace("align=",""))?s='

              ':"left"===n?s='

              ':"right"===n&&(s='

              ')),s+''+i+'"+l},e.emoji=function(e){var t=(e=e.replace(C.regexs.emojiDatetime,function(e){return e.replace(/:/g,":")})).match(r);if(t&&a.emoji)for(var i=0,o=t.length;i'}else{var s=e.match(w),l=e.match(g);if(s)for(var c=0,h=s.length;c'}else{if(!l)return':'+o+':';for(var u=0,f=l.length;u'}}}});return e},e.atLink=function(e){return n.test(e)&&(a.atLink&&(e=(e=e.replace(i,function(e,t,i,o){return e.replace(/@/g,"_#_@_#_")})).replace(n,function(e,t){return''+e+""}).replace(/_#_@_#_/g,"@")),a.emailLink)?e.replace(o,function(e,t,i,o,n){return!t&&v.inArray(n,"jpg|jpeg|png|gif|webp|ico|icon|pdf".split("|"))<0?''+e+"":e}):e},e.link=function(e,t,i){if(this.options.sanitize){try{var o=decodeURIComponent(unescape(e)).replace(/[^\w:]/g,"").toLowerCase()}catch(e){return""}if(0===o.indexOf("javascript:"))return""}return 0===e.indexOf("@")?'':(o=''+i.replace(/@/g,"@")+""):(t&&(o+=' title="'+t+'"'),o+">"+i+""))},e.heading=function(e,t,i){var o=e,n=/\s*\]*)\>(.*)\<\/a\>\s*/;if(n.test(e)){for(var r=[],a=0,s=(e=e.split(/\]+)\>([^\>]*)\<\/a\>/)).length;a');return(l+='')+(n?this.atLink(this.emoji(o)):this.atLink(this.emoji(e)))+("")},e.pageBreak=function(e){return e=s.test(e)&&a.pageBreak?'


              ':e},e.paragraph=function(e){var t=/\$\$(.+?)\$\$/g.test(e),i=/^(?!\$\$.+?(?:\$\$).+?\$\$)(\$\$(.+?)\$\$)$/.test(e),o=i?' class="'+C.classNames.tex+'"':"",n=(a.tocm?/^(\[TOC\]|\[TOCM\])$/:/^\[TOC\]$/).test(e),r=/^\[TOCM\]$/.test(e),t='
              '+(e=!i&&t?e.replaceAll(/(\$\$(.+?)\$\$)/g,function(e,t,i){return''+i.replaceAll(/\/g,"")+""}):i?e.replace(/^(?!\$\$.+?(?:\$\$).+?\$\$)(\$\$(.+?)\$\$)$/,(e,t,i)=>i):e)+"
              ";return n?r?'
              '+t+"

              ":t:s.test(e)?this.pageBreak(e):""+this.atLink(this.emoji(e))+"

              \n"},e.code=function(e,t,i){if("seq"===t||"sequence"===t)return'
              '+e+"
              ";if("mermaid"===t){for(var o=(a="ABCDEFGHJKLMNOPQRSTUVWXYZabcdefhijlkmnopqrstuvwxyz012345678").length,n="",r=0;r<4;r++)n+=a.charAt(Math.floor(Math.random()*o));return'
              '+e+"
              "}if("flow"===t)return'
              '+e+"
              ";if("math"===t||"latex"===t||"katex"===t)return'

              '+e+"

              ";if(/^mindmap/i.test(t)){for(var a,o=(a="ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678").length,s="",l=t.split(">")[1],l=null!=l?l:150,r=0;r<9;r++)s+=a.charAt(Math.floor(Math.random()*o));return""+e+""}return"drawio"===t?'
              '+decodeURIComponent(escape(window.atob(e)))+"
              ":c.Renderer.prototype.code.apply(this,arguments)},e.tablecell=function(e,t){var i=t.header?"th":"td";return(t.align?"<"+i+' style="text-align:'+t.align+'">':"<"+i+">")+this.atLink(this.emoji(e))+"\n"},e.listitem=function(e){return a.taskList&&/^\s*\[[x\s]\]\s*/.test(e)?(e=e.replace(/^\s*\[\s\]\s*/,' ').replace(/^\s*\[x\]\s*/,' '),'
            • '+this.atLink(this.emoji(e))+"
            • "):"
            • "+this.atLink(this.emoji(e))+"
            • "},e.checkbox=function(e){return e?' ':' '},e},C.markdownToCRenderer=function(e,t,i,o){var n="",r=0,a=this.classPrefix;o=o||1;for(var s=0,l=e.length;s"):"")+'
            • '+c+"
                ",r=h)}var u,f=t.find(".markdown-toc");return f.length<1&&"false"===t.attr("previewContainer")&&(u='
                ',t.html(u=i?'
                '+u+"
                ":u),f=t.find(".markdown-toc")),i&&f.wrap('

                '),f.html('
                  ').children(".markdown-toc-list").html(n.replace(/\r?\n?\\<\/ul\>/g,"")),f},C.tocDropdownMenu=function(e,a){a=a||"Table of Contents";var s=400,e=e.find("."+this.classPrefix+"toc-menu");return e.each(function(){var e=v(this),t=e.children(".markdown-toc"),o='',i=''+o+a+"",n=t.children("ul"),r=n.find("li");t.append(i),r.first().before("
                • "+a+" "+o+"

                • "),e.mouseover(function(){n.show(),r.each(function(){var e,t=v(this),i=t.children("ul");""===i.html()&&i.remove(),0]*)>([^>]*)","igm"),"")}void 0!==a&&(t=/\<(\w+)\s*([^\>]*)\>([^\>]*)\<\/(\w+)\>/gi,e="*"===a?e.replace(t,function(e,t,i,o,n){return"<"+t+">"+o+""}):"on*"===a?e.replace(t,function(e,t,i,o,n){var t=v("<"+t+">"+o+""),o=v(e)[0].attributes,r={},n=(v.each(o,function(e,t){'"'!==t.nodeName&&(r[t.nodeName]=t.nodeValue)}),v.each(r,function(e){0===e.indexOf("on")&&delete r[e]}),t.attr(r),void 0!==t[1]?v(t[1]).text():"");return t[0].outerHTML+n}):e.replace(t,function(e,t,i,o){var n=a.split(","),r=v(e);return r.html(o),v.each(n,function(e){r.attr(n[e],null)}),r[0].outerHTML}))}return e},C.markdownToHTML=function(e,t){C.$marked=marked;var i,o=v("#"+e),e=o.settings=v.extend(!0,{gfm:!0,toc:!0,tocm:!1,tocStartLevel:1,tocTitle:"目录",tocDropdown:!1,tocContainer:"",markdown:"",markdownSourceCode:!1,htmlDecode:!1,autoLoadKaTeX:!0,pageBreak:!0,atLink:!0,emailLink:!0,tex:!1,taskList:!1,emoji:!1,flowChart:!1,sequenceDiagram:!1,previewCodeHighlight:!0,mermaid:!0,mindMap:!0},t||{}),n=o.find("textarea"),t=(n.length<1&&(o.append(""),n=o.find("textarea")),void 0===e.markdown?n.val():e.markdown),r=[],a={toc:e.toc,tocm:e.tocm,tocStartLevel:e.tocStartLevel,taskList:e.taskList,emoji:e.emoji,tex:e.tex,pageBreak:e.pageBreak,atLink:e.atLink,emailLink:e.emailLink,flowChart:e.flowChart,sequenceDiagram:e.sequenceDiagram,mermaid:e.mermaid,mindMap:e.mindMap,previewCodeHighlight:e.previewCodeHighlight},a={renderer:C.markedRenderer(r,a),gfm:e.gfm,tables:!0,breaks:!0,pedantic:!1,sanitize:!e.htmlDecode,smartLists:!0,smartypants:!0},t=new String(t),a=marked.parse(t,a),a=C.$filterXSS(a),t=(e.markdownSourceCode?n.text(t):n.remove(),o.addClass("markdown-body "+this.classPrefix+"html-preview").append(a),""!==e.tocContainer?v(e.tocContainer):o);return""!==e.tocContainer&&t.attr("previewContainer",!1),e.toc&&(o.tocContainer=this.markdownToCRenderer(r,t,e.tocDropdown,e.tocStartLevel),(e.tocDropdown||0"),e[0]),e.find(".katex").css("font-size","1.6em")})},!e.autoLoadKaTeX||C.$katex||C.kaTeXLoaded?i():this.loadKaTeX(function(){C.$katex=katex,C.kaTeXLoaded=!0,i()})),e.mindMap&&o.find(".mindmap").each(function(){var e=v(this),e=window.markmap.transform(e.text().trim());window.markmap.markmap("svg#"+this.id,e)}),o.getMarkdown=function(){return n.val()},o},C.themes=["default","dark"],C.previewThemes=["default","dark"],C.editorThemes=["default","3024-day","3024-night","ambiance","ambiance-mobile","base16-dark","base16-light","blackboard","cobalt","eclipse","elegant","erlang-dark","lesser-dark","mbo","mdn-like","midnight","monokai","neat","neo","night","paraiso-dark","paraiso-light","pastel-on-dark","rubyblue","solarized","the-matrix","tomorrow-night-eighties","twilight","vibrant-ink","xq-dark","xq-light"],C.loadPlugins={},C.loadFiles={js:[],css:[],plugin:[]},C.loadPlugin=function(e,t,i,o){t=t||function(){},this.loadScript(e,function(){C.loadFiles.plugin.push(e),t()},i,o)},C.loadCSS=function(e,t,i,o=C.version){i=i||"head",t=t||function(){},o=o||C.version;var n=document.createElement("link");n.type="text/css",n.rel="stylesheet",n.onload=n.onreadystatechange=function(){C.loadFiles.css.push(e),t()},n.href=e+".css?editormd_version="+o,("head"===i?document.getElementsByTagName("head")[0]:document.body).appendChild(n)},C.isIE="Microsoft Internet Explorer"==navigator.appName,C.isIE8=C.isIE&&"8."==navigator.appVersion.match(/8./i),C.loadScript=function(e,t,i,o){i=i||"head",o=o||C.version,t=t||function(){};var n=null;(n=document.createElement("script")).id=e.replace(/[\./]+/g,"-"),n.type="text/javascript",n.src=e+".js?editormd_version="+o,C.isIE8?n.onreadystatechange=function(){!n.readyState||"loaded"!==n.readyState&&"complete"!==n.readyState||(n.onreadystatechange=null,C.loadFiles.js.push(e),t())}:n.onload=function(){C.loadFiles.js.push(e),t()},("head"===i?document.getElementsByTagName("head")[0]:document.body).appendChild(n)},C.katexURL={css:"https://cdn.bootcdn.net/ajax/libs/KaTeX/0.16.8/katex.min",jsmain:"https://cdn.bootcdn.net/ajax/libs/KaTeX/0.16.8/katex.min",jsauto:"https://cdn.bootcdn.net/ajax/libs/KaTeX/0.16.8/contrib/auto-render.min"},C.kaTeXLoaded=!1,C.loadKaTeX=function(e){C.loadCSS(C.katexURL.css,function(){C.loadScript(C.katexURL.jsmain,function(){C.loadScript(C.katexURL.jsauto,e||function(){})})})},C.lockScreen=function(e){v("html,body").css("overflow",e?"hidden":"")},C.createDialog=function(t){function e(){f.css({top:(v(window).height()-f.height())/2+"px",left:(v(window).width()-f.width())/2+"px"})}t=v.extend(!0,{name:"",width:420,height:"auto",title:"",drag:!0,closed:!0,content:"",mask:!0,maskStyle:{backgroundColor:"#fff",opacity:.1},removeDialogOnClose:!1,resizeableX:!1,resizeableY:!1,minWidth:0,minHeight:0,maxWidth:"none",maxHeight:"none",lockScreen:!0,footer:!0,buttons:!1},t);var r,a,i,s,o,n=this,l=this.editor,c=C.classPrefix,h=(new Date).getTime(),h=""===t.name?c+"dialog-"+h:t.name,d=C.mouseOrTouch,u='
                  ',f=(""!==t.title&&(u=(u+='
                  ")+''+t.title+"",t.closed&&(u+=''),u+="
                  "),u+='
                  '+t.content,!t.footer&&"string"!=typeof t.footer||(u+='"),l.append(u=(u=u+"
                  "+('
                  '))+('
                  ')+"
                  "),l.find("."+h));f.lockScreen=function(e){return t.lockScreen&&(v("html,body").css("overflow",e?"hidden":""),n.resize()),f},f.showMask=function(){return t.mask&&l.find("."+c+"mask").css(t.maskStyle).css("z-index",C.dialogZindex-1).show(),f},f.hideMask=function(){return t.mask&&l.find("."+c+"mask").hide(),f},f.loading=function(e){return f.find("."+c+"dialog-mask")[e?"show":"hide"](),f},f.lockScreen(!0).showMask(),f.show().css({zIndex:C.dialogZindex,border:C.isIE8?"1px solid #ddd":"",width:"number"==typeof t.width?t.width+"px":t.width,height:"number"==typeof t.height?t.height+"px":t.height,"min-width":"number"==typeof t.minWidth?t.minWidth+"px":t.minWidth,"min-height":"number"==typeof t.minHeight?t.minHeight+"px":t.minHeight,"max-width":"number"==typeof t.maxWidth?t.maxWidth+"px":t.maxWidth,"max-height":"number"==typeof t.maxHeight?t.maxHeight+"px":t.maxHeight,...t.resizeableX||t.resizeableY?{overflow:"hidden",resize:t.resizeableX&&t.resizeableY?"both":t.resizeableX?"horizontal":"vertical"}:{}});if(e(),v(window).resize(e),f.find("."+c+"dialog-close").bind(d("click","touchend"),function(){f.hide().lockScreen(!1).hideMask(),t.removeDialogOnClose&&f.remove()}),"object"==typeof t.buttons){var p,g=f.footer=f.find("."+c+"dialog-footer");for(p in t.buttons){var m=t.buttons[p],w=c+p+"-btn";g.append('"),m[1]=v.proxy(m[1],f),g.children("."+w).bind(d("click","touchend"),m[1])}}return""!==t.title&&t.drag&&(u=f.children("."+c+"dialog-header"),t.mask||u.bind(d("click","touchend"),function(){C.dialogZindex+=2,f.css("z-index",C.dialogZindex)}),u.mousedown(function(e){e=e||window.event,r=e.clientX-parseInt(f[0].style.left),a=e.clientY-parseInt(f[0].style.top),document.onmousemove=o}),i=function(e){e.removeClass(c+"user-unselect").off("selectstart")},s=function(e){e.addClass(c+"user-unselect").on("selectstart",function(e){return!1})},o=function(e){e=e||window.event;var t,i,o=parseInt(f[0].style.left),n=parseInt(f[0].style.top);0<=o?o+f.width()<=v(window).width()?t=e.clientX-r:(t=v(window).width()-f.width(),document.onmousemove=null):(t=0,document.onmousemove=null),0<=n?i=e.clientY-a:(i=0,document.onmousemove=null),document.onselectstart=function(){return!1},s(v("body")),s(f),f[0].style.left=t+"px",f[0].style.top=i+"px"},document.onmouseup=function(){i(v("body")),i(f),document.onselectstart=null,document.onmousemove=null},u.touchDraggable=function(){var i=null;this.bind("touchstart",function(e){var e=e.originalEvent,t=v(this).parent().position();i={x:e.changedTouches[0].pageX-t.left,y:e.changedTouches[0].pageY-t.top}}).bind("touchmove",function(e){e.preventDefault();e=e.originalEvent;v(this).parent().css({top:e.changedTouches[0].pageY-i.y,left:e.changedTouches[0].pageX-i.x})})},u.touchDraggable()),C.dialogZindex+=2,f},C.mouseOrTouch=function(e,t){t=t||"touchend";e=e||"click";try{document.createEvent("TouchEvent"),e=t}catch(e){}return e},C.dateFormat=function(e){e=e||"";function t(e){return e<10?"0"+e:e}var i=new Date,o=i.getFullYear(),n=o.toString().slice(2,4),r=t(i.getMonth()+1),a=t(i.getDate()),s=i.getDay(),l=t(i.getHours()),c=t(i.getMinutes()),h=t(i.getSeconds()),d=t(i.getMilliseconds()),u="",f=n+"-"+r+"-"+a,p=o+"-"+r+"-"+a,g=l+":"+c+":"+h;switch(e){case"UNIX Time":u=i.getTime();break;case"UTC":u=i.toUTCString();break;case"yy":u=n;break;case"year":case"yyyy":u=o;break;case"month":case"mm":u=r;break;case"cn-week-day":case"cn-wd":u="星期"+["日","一","二","三","四","五","六"][s];break;case"week-day":case"wd":u=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"][s];break;case"day":case"dd":u=a;break;case"hour":case"hh":u=l;break;case"min":case"ii":u=c;break;case"second":case"ss":u=h;break;case"ms":u=d;break;case"yy-mm-dd":u=f;break;case"yyyy-mm-dd":u=p;break;case"yyyy-mm-dd h:i:s ms":case"full + ms":u=p+" "+g+" "+d;break;default:u=p+" "+g}return u},C.getLine=function(e){return this.cm.getLine(e)},C}); \ No newline at end of file diff --git a/static/editor.md/editormd.js b/static/editor.md/editormd.js index 980f7cac..c6ee6dc2 100755 --- a/static/editor.md/editormd.js +++ b/static/editor.md/editormd.js @@ -1,13 +1,25 @@ /* * Editor.md * - * @file editormd.js - * @version v1.5.0 + * @file editormd.js + * @version v1.7.17 * @description Open source online markdown editor. * @license MIT License - * @author Pandao - * {@link https://github.com/pandao/editor.md} - * @updateTime 2015-06-09 + * @author IBM Skills Network + * {@link https://github.com/ibm-skills-network/editor.md} + * @updateTime 2024-03-27 + */ + +/* + * Editor.md + * + * @file editormd.js + * @version v1.7.17 + * @description Open source online markdown editor. + * @license MIT License + * @author IBM Skills Network + * {@link https://github.com/ibm-skills-network/editor.md} + * @updateTime 2024-03-27 */ ;(function(factory) { @@ -54,12 +66,13 @@ * @returns {Object} editormd 返回editormd对象 */ - var editormd = function (id, options) { - return new editormd.fn.init(id, options); + var editormd = function (id,author_ide_version, options) { + return new editormd.fn.init(id,author_ide_version, options); }; + editormd.URL_ROOT = document.currentScript.src.replace(/\/[^\/]+$/ig, '') + "/" editormd.title = editormd.$name = "Editor.md"; - editormd.version = "1.5.0"; + editormd.version = "1.7.17"; editormd.homePage = "https://pandao.github.io/editor.md/"; editormd.classPrefix = "editormd-"; @@ -94,15 +107,16 @@ name : "", // Form element name value : "", // value for CodeMirror, if mode not gfm/markdown theme : "", // Editor.md self themes, before v1.5.0 is CodeMirror theme, default empty - editorTheme : "pastel-on-dark", //"default", // Editor area, this is CodeMirror theme at v1.5.0 - previewTheme : "dark", //"", // Preview area theme, default empty - markdown : "", // Markdown source code + editorTheme : "default", // Editor area, this is CodeMirror theme at v1.5.0 + previewTheme : "", // Preview area theme, default empty + markdown : undefined, // Markdown source code appendMarkdown : "", // if in init textarea value not empty, append markdown to textarea width : "100%", height : "100%", path : "./lib/", // Dependents module file directory pluginPath : "", // If this empty, default use settings.path + "../plugins/" - delay : 500, // Delay parse markdown to html, Uint : ms + customPluginPath : "", + delay : 300, // Delay parse markdown to html, Uint : ms autoLoadModules : true, // Automatic load dependent module files watch : true, placeholder : "Enjoy Markdown! coding now...", @@ -140,6 +154,8 @@ onwatch : null, onunwatch : null, onpreviewing : function() {}, + onCmChange : null, + fixCodeBlocks : function() {}, // run after prettyprint(function to prettify code blocks) finished onpreviewed : function() {}, onfullscreen : function() {}, onfullscreenExit : function() {}, @@ -163,7 +179,7 @@ atLink : true, // for @link emailLink : true, // for email address auto link taskList : false, // Enable Github Flavored Markdown task lists - emoji : false, // :emoji: , Support Github emoji, Twitter Emoji (Twemoji); + emoji : true, // :emoji: , Support Github emoji, Twitter Emoji (Twemoji); // Support FontAwesome icon emoji :fa-xxx: > Using fontAwesome icon web fonts; // Support Editor.md logo icon emoji :editormd-logo: :editormd-logo-1x: > 1~8x; tex : false, // TeX(LaTeX), based on KaTeX @@ -173,8 +189,13 @@ mindMap : true, // 脑图 previewCodeHighlight : true, - toolbar : true, // show/hide toolbar + toolbar : false, // show/hide toolbar toolbarAutoFixed : true, // on window scroll auto fixed position + titlebar : { + left: {}, + center: {}, + right: {} + }, toolbarIcons : "full", toolbarTitles : {}, toolbarHandlers : { @@ -186,8 +207,9 @@ } }, toolbarCustomIcons : { // using html tag create toolbar icon, unused default tag. - lowercase : "a", - "ucwords" : "Aa" + lowercase : "a", + "ucwords" : "Aa", + "fontcase" : "Aa" }, toolbarIconsClass : { undo : "fa-undo", @@ -197,6 +219,7 @@ italic : "fa-italic", quote : "fa-quote-left", uppercase : "fa-font", + heading : "fa-header", h1 : editormd.classPrefix + "bold", h2 : editormd.classPrefix + "bold", h3 : editormd.classPrefix + "bold", @@ -228,8 +251,19 @@ changetheme : "fa-info-circle", info : "fa-info-circle" }, - toolbarIconTexts : {}, + toolbarIconTexts : { + "ucwords" : "Capitalize", + uppercase : "Uppercase", + lowercase : "Lowercase", + h1 : "Heading 1", + h2 : "Heading 2", + h3 : "Heading 3", + h4 : "Heading 4", + h5 : "Heading 5", + h6 : "Heading 6" + }, + // Support for other languaages (see README) lang : { name : "zh-cn", description : "开源在线Markdown编辑器
                  Open source online Markdown editor.", @@ -333,13 +367,15 @@ }; editormd.classNames = { - tex : editormd.classPrefix + "tex" + tex : editormd.classPrefix + "tex", + texDisplay : editormd.classPrefix + "texDisaply" }; editormd.dialogZindex = 99999; editormd.$katex = null; editormd.$marked = null; + editormd.$filterXSS = null; editormd.$CodeMirror = null; editormd.$prettyPrint = null; @@ -362,7 +398,7 @@ * @returns {editormd} 返回editormd的实例对象 */ - init : function (id, options) { + init : function (id, author_ide_version, options) { options = options || {}; @@ -371,15 +407,19 @@ options = id; } - var _this = this; var classPrefix = this.classPrefix = editormd.classPrefix; - var settings = this.settings = $.extend(true, editormd.defaults, options); + var settings = this.settings = $.extend(true, {}, editormd.defaults, options); + if (settings.path.startsWith('.')) { + settings.path = editormd.URL_ROOT + settings.path + } + console.log(settings.path) id = (typeof id === "object") ? settings.id : id; var editor = this.editor = $("#" + id); this.id = id; + this.author_ide_version = author_ide_version || editor.version; this.lang = settings.lang; var classNames = this.classNames = { @@ -440,7 +480,7 @@ this.mask = editor.children("." + classPrefix + "mask"); this.containerMask = editor.children("." + classPrefix + "container-mask"); - if (settings.markdown !== "") + if (settings.markdown !== undefined) { markdownTextarea.val(settings.markdown); } @@ -515,91 +555,38 @@ return ; } - - if (settings.mermaid) { - editormd.loadScript(loadPath + "mermaid/mermaid.min", function () { - window.mermaid.initialize({ - theme: 'default', - logLevel: 3, - securityLevel: 'loose', - flowchart: { curve: 'basis' }, - gantt: { axisFormat: '%m/%d/%Y' }, - sequence: { actorMargin: 50 }, - }); - mermaid.ganttConfig = { - axisFormatter: [ - // Within a day - ['%I:%M', function (d) { - return d.getHours(); - }], - // Monday a week - ['%m/%d', function (d) { // redefine date here as '%m/%d'instead of 'w. %U', search mermaid.js - return d.getDay() == 1; - }], - // Day within a week (not monday) - ['%a %d', function (d) { - return d.getDay() && d.getDate() != 1; - }], - // within a month - ['%b %d', function (d) { - return d.getDate() != 1; - }], - // Month - ['%m-%y', function (d) { - return d.getMonth(); - }],[ "%m-%Y", function () { - return d.getFullYear(); - }]] - }; - - if (!isLoadedDisplay){ - isLoadedDisplay = true; - _this.loadedDisplay(); - } - }); - } - if (settings.flowChart) + if (settings.flowChart || settings.sequenceDiagram) { editormd.loadScript(loadPath + "raphael.min", function() { - editormd.loadScript(loadPath + "flowchart.min", function() { - editormd.loadScript(loadPath + "jquery.flowchart.min", function() { - if (!isLoadedDisplay){ - isLoadedDisplay = true; - _this.loadedDisplay(); - } - }); - }); - }); - } - if (settings.mindMap) - { - editormd.loadScript(loadPath + "mindmap/transform.min", function() { - editormd.loadScript(loadPath + "mindmap/d3@5", function() { - editormd.loadScript(loadPath + "mindmap/view.min", function() { - if (!isLoadedDisplay){ - isLoadedDisplay = true; - _this.loadedDisplay(); - } - }); - }); - }); - } + editormd.loadScript(loadPath + "underscore.min", function() { - if(settings.sequenceDiagram) { - editormd.loadCSS(loadPath + "sequence/sequence-diagram-min", function () { - editormd.loadScript(loadPath + "sequence/webfont", function() { - editormd.loadScript(loadPath + "sequence/snap.svg-min", function() { - editormd.loadScript(loadPath + "sequence/underscore-min", function() { - editormd.loadScript(loadPath + "sequence/sequence-diagram-min", function() { - if (!isLoadedDisplay){ - isLoadedDisplay = true; - _this.loadedDisplay(); - } + if (!settings.flowChart && settings.sequenceDiagram) + { + editormd.loadScript(loadPath + "sequence-diagram.min", function() { + _this.loadedDisplay(); + }); + } + else if (settings.flowChart && !settings.sequenceDiagram) + { + editormd.loadScript(loadPath + "flowchart.min", function() { + editormd.loadScript(loadPath + "jquery.flowchart.min", function() { + _this.loadedDisplay(); }); }); - }); + } + else if (settings.flowChart && settings.sequenceDiagram) + { + editormd.loadScript(loadPath + "flowchart.min", function() { + editormd.loadScript(loadPath + "jquery.flowchart.min", function() { + editormd.loadScript(loadPath + "sequence-diagram.min", function() { + _this.loadedDisplay(); + }); + }); + }); + } }); + }); } else @@ -608,6 +595,10 @@ } }; + // editormd.loadScript(loadPath + "xss", function () { + // editormd.$filterXSS = filterXSS + // }); + editormd.loadCSS(loadPath + "codemirror/codemirror.min"); if (settings.searchReplace && !settings.readOnly) @@ -639,7 +630,7 @@ _this.setToolbar(); - editormd.loadScript(loadPath + "marked", function() { + editormd.loadScript(loadPath + "marked.umd", function() { editormd.$marked = marked; @@ -648,6 +639,9 @@ } if (settings.previewCodeHighlight) { + // editormd.loadScript(loadPath + "prettify.min", function() { + // loadFlowChartOrSequenceDiagram(); + // }); editormd.loadCSS(loadPath + "highlight/styles/" + settings.highlightStyle); editormd.loadScript(loadPath + "highlight/highlight", function() { loadFlowChartOrSequenceDiagram(); @@ -1177,15 +1171,22 @@ return this; } - var editor = this.editor; - var preview = this.preview; - var classPrefix = this.classPrefix; + var editor = this.editor; + var preview = this.preview; + var classPrefix = this.classPrefix; // this.classPrefix = "editormd-" + var titlebarModes = (typeof settings.titlebar === "function") ? settings.titlebar() : settings.titlebar; var toolbar = this.toolbar = editor.children("." + classPrefix + "toolbar"); if (settings.toolbar && toolbar.length < 1) { - var toolbarHTML = "
                    "; + var toolbarHTML = "
                    \ +
                    \ +
                    \ +
                    \ +
                      \ +
                      \ +
                      "; editor.append(toolbarHTML); toolbar = this.toolbar = editor.children("." + classPrefix + "toolbar"); @@ -1198,6 +1199,7 @@ return this; } + // Set toolbar icons toolbar.show(); var icons = (typeof settings.toolbarIcons === "function") ? settings.toolbarIcons() @@ -1216,40 +1218,101 @@ } else if (name === "|") { - menu += "
                    • |
                    • "; + menu += "
                    • "; } else { - var isHeader = (/h(\d)/.test(name)); - var index = name; + var isDropdown = name.includes("dropdown"); - if (name === "watch" && !settings.watch) { - index = "unwatch"; + // add classes for menu item + var menuClasses = [] + if (pullRight) { + menuClasses.push("pull-right"); + } + if (isDropdown) { + menuClasses.push("dropdown"); } - var title = settings.lang.toolbar[index]; - var iconTexts = settings.toolbarIconTexts[index]; - var iconClass = settings.toolbarIconsClass[index]; + // stores HTML for current menu item; add opening tag + var menuItem = (menuClasses.length > 0) ? "
                    • " : "
                    • "; - title = (typeof title === "undefined") ? "" : title; - iconTexts = (typeof iconTexts === "undefined") ? "" : iconTexts; - iconClass = (typeof iconClass === "undefined") ? "" : iconClass; + // list of icons in menu item (usually just one unless dropdown) + var selections = [] - var menuItem = pullRight ? "
                    • " : "
                    • "; - - if (typeof settings.toolbarCustomIcons[name] !== "undefined" && typeof settings.toolbarCustomIcons[name] !== "function") - { - menuItem += settings.toolbarCustomIcons[name]; + if (isDropdown) { + var info = name.split(":"); + var dropdownType = info[0]; // "dropdown", "dropdownIcon" + name = info[1]; // set name to actual parsed name from info + var dropdownContent = info[2].split(","); + selections = [name].concat(dropdownContent); + // set isDropdown to false if no dropdown content + if (!dropdownContent.length) { + isDropdown = false; + } + } else { + selections.push(name) } - else - { - menuItem += ""; - menuItem += ""+((isHeader) ? name.toUpperCase() : ( (iconClass === "") ? iconTexts : "") ) + ""; + + for (var j = 0, len = selections.length; j < len; j++) { + name = selections[j].trim(); + + // insert dropdown opening tag + if (isDropdown && j === 1) { + menuItem += "
                      "; + } + + // default "dropdown" has no icons in content, use "dropdownIcon" for icon+text options + var hasIcon = !(isDropdown && dropdownType !== "dropdownIcon" && menuItem.includes("toolbar-dropdown-content")); + var isHeader = (/h(\d)/.test(name)); + var index = name; + + if (name === "watch" && !settings.watch) { + index = "unwatch"; + } + + var title = settings.lang.toolbar[index]; // hover text + var iconTexts = settings.toolbarIconTexts[index]; // placeholder text if icon is empty + var iconClass = settings.toolbarIconsClass[index]; // font awesome icon class + + title = (typeof title === "undefined" || isDropdown) ? "" : title; + iconTexts = (typeof iconTexts === "undefined") ? "" : iconTexts; + iconClass = (typeof iconClass === "undefined" || !hasIcon) ? "" : iconClass; + + + menuItem += ""; + + // add custom icon + if (hasIcon && typeof settings.toolbarCustomIcons[name] !== "undefined" && typeof settings.toolbarCustomIcons[name] !== "function") + { + menuItem += settings.toolbarCustomIcons[name]; + } + // add icon content + else + { + menuItem += ""; + + if (typeof settings.toolbarIcons !== "function" && isHeader) { + menuItem += "" + name.toUpperCase() + ""; + } else if (dropdownType && dropdownType === "dropdownIcon" && menuItem.includes("toolbar-dropdown-content")) { + menuItem += "" + (iconTexts ? iconTexts : name) + ""; + } else if (iconClass === "" || !hasIcon) { + menuItem += "" + (iconTexts ? iconTexts : name) + ""; + } + + menuItem += ""; + } + menuItem += ""; + + // insert dropdown closing tag + if (isDropdown && j === len - 1 && menuItem.includes("toolbar-dropdown-content")) { + menuItem += "
                      "; + dropdownType = ""; + } } + // add closing tag and append to toolbar menuItem += "
                    • "; - menu = pullRight ? menuItem + menu : menu + menuItem; } } @@ -1285,6 +1348,11 @@ return this; }, + positionDialog : function(dialog, position) { + $.proxy(editormd.positionDialog, this)(dialog, position); + + return this; + }, getToolbarHandles : function(name) { var toolbarHandlers = this.toolbarHandlers = editormd.toolbarHandlers; @@ -1294,7 +1362,7 @@ /** * 工具栏图标事件处理器 - * Bind toolbar icons event handle + * Bind toolbar icons to their event handlers * * @returns {editormd} 返回editormd的实例对象 */ @@ -1310,10 +1378,10 @@ var toolbar = this.toolbar; var cm = this.cm; var classPrefix = this.classPrefix; - var toolbarIcons = this.toolbarIcons = toolbar.find("." + classPrefix + "menu > li > a"); + var toolbarIcons = this.toolbarIcons = toolbar.find("." + classPrefix + "menu > li a"); var toolbarIconHandlers = this.getToolbarHandles(); - toolbarIcons.bind(editormd.mouseOrTouch("click", "touchend"), function(event) { + toolbarIcons.bind(editormd.mouseOrTouch("click", "touchend"), function() { var icon = $(this).children(".fa"); var name = icon.attr("name"); @@ -1372,7 +1440,7 @@ createInfoDialog : function() { var _this = this; - var editor = this.editor; + var editor = this.editor; var classPrefix = this.classPrefix; var infoDialogHTML = [ @@ -1438,7 +1506,7 @@ $("html,body").css("overflow-x", "hidden"); var _this = this; - var editor = this.editor; + var editor = this.editor; var settings = this.settings; var infoDialog = this.infoDialog = editor.children("." + this.classPrefix + "dialog-info"); @@ -1539,12 +1607,12 @@ if (settings.previewCodeHighlight) { - // previewContainer.find("pre").addClass("prettyprint"); - // - // if (typeof prettyPrint !== "undefined") - // { - // prettyPrint(); - // } + previewContainer.find("pre").addClass("prettyprint linenums"); + + if (typeof prettyPrint !== "undefined") + { + prettyPrint($.proxy(settings.fixCodeBlocks,this)); + } previewContainer.find("pre").each(function (i, block) { hljs.highlightBlock(block); }); @@ -1569,7 +1637,19 @@ this.previewContainer.find("." + editormd.classNames.tex).each(function(){ var tex = $(this); - editormd.$katex.render(tex.text(), tex[0]); + editormd.$katex.render(tex.text(), tex[0],{ + throwOnError: false, + }); + + tex.find(".katex").css("font-size", "1.6em"); + }); + + this.previewContainer.find("." + editormd.classNames.texDisplay).each(function(){ + var tex = $(this); + editormd.$katex.render(tex.text(), tex[0],{ + throwOnError: false, + displayMode: true, + }); tex.find(".katex").css("font-size", "1.6em"); }); @@ -1612,7 +1692,7 @@ var mermaid = previewContainer.find(".lang-mermaid"); if (mermaid) { try { - window.mermaid.init(void 0, mermaid.removeClass("hide")); + mermaid.init(void 0, mermaid.removeClass("hide")); }catch (e) { console.log(e); } @@ -1737,12 +1817,12 @@ case 121: $.proxy(toolbarHandlers["preview"], _this)(); return false; - break; + break; case 122: $.proxy(toolbarHandlers["fullscreen"], _this)(); return false; - break; + break; default: break; @@ -1763,7 +1843,8 @@ bindScrollEvent : function() { var _this = this; - var preview = this.preview; + // var preview = this.preview; + var preview = this.previewContainer; var settings = this.settings; var codeMirror = this.codeMirror; var mouseOrTouch = editormd.mouseOrTouch; @@ -1774,33 +1855,35 @@ var cmBindScroll = function() { codeMirror.find(".CodeMirror-scroll").bind(mouseOrTouch("scroll", "touchmove"), function(event) { - var height = $(this).height(); - var scrollTop = $(this).scrollTop(); - var percent = (scrollTop / $(this)[0].scrollHeight); + if (timer == null){ + var height = $(this).height(); + var scrollTop = $(this).scrollTop(); + var percent = (scrollTop / $(this)[0].scrollHeight); - var tocHeight = 0; + var tocHeight = 0; - preview.find(".markdown-toc-list").each(function(){ - tocHeight += $(this).height(); - }); + preview.find(".markdown-toc-list").each(function(){ + tocHeight += $(this).height(); + }); - var tocMenuHeight = preview.find(".editormd-toc-menu").height(); - tocMenuHeight = (!tocMenuHeight) ? 0 : tocMenuHeight; + var tocMenuHeight = preview.find(".editormd-toc-menu").height(); + tocMenuHeight = (!tocMenuHeight) ? 0 : tocMenuHeight; - if (scrollTop === 0) - { - preview.scrollTop(0); + if (scrollTop === 0) + { + preview.scrollTop(0); + } + else if (scrollTop + height >= $(this)[0].scrollHeight - 16) + { + preview.scrollTop(preview[0].scrollHeight); + } + else + { + preview.scrollTop((preview[0].scrollHeight + tocHeight + tocMenuHeight) * percent); + } + + $.proxy(settings.onscroll, _this)(event); } - else if (scrollTop + height >= $(this)[0].scrollHeight - 16) - { - preview.scrollTop(preview[0].scrollHeight); - } - else - { - preview.scrollTop((preview[0].scrollHeight + tocHeight + tocMenuHeight) * percent); - } - - $.proxy(settings.onscroll, _this)(event); }); }; @@ -1811,29 +1894,29 @@ var previewBindScroll = function() { preview.bind(mouseOrTouch("scroll", "touchmove"), function(event) { - var height = $(this).height(); - var scrollTop = $(this).scrollTop(); - var percent = (scrollTop / $(this)[0].scrollHeight); - var codeView = codeMirror.find(".CodeMirror-scroll"); + if (timer == null){ + var height = $(this).height(); + var scrollTop = $(this).scrollTop(); + var percent = (scrollTop / $(this)[0].scrollHeight); + var codeView = codeMirror.find(".CodeMirror-scroll"); - if(scrollTop === 0) - { - codeView.scrollTop(0); + if(scrollTop === 0) + { + codeView.scrollTop(0); + } + else if (scrollTop + height >= $(this)[0].scrollHeight) + { + codeView.scrollTop(codeView[0].scrollHeight); + } + else + { + codeView.scrollTop(codeView[0].scrollHeight * percent); + } + $.proxy(settings.onpreviewscroll, _this)(event); } - else if (scrollTop + height >= $(this)[0].scrollHeight) - { - codeView.scrollTop(codeView[0].scrollHeight); - } - else - { - codeView.scrollTop(codeView[0].scrollHeight * percent); - } - - $.proxy(settings.onpreviewscroll, _this)(event); }); }; - var previewUnbindScroll = function() { preview.unbind(mouseOrTouch("scroll", "touchmove")); }; @@ -1846,10 +1929,12 @@ }); if (settings.syncScrolling === "single") { + // cmBindScroll(); return this; } - preview.bind({ + // previewBindScroll(); + preview.bind({ mouseover : previewBindScroll, mouseout : previewUnbindScroll, touchstart : previewBindScroll, @@ -1865,19 +1950,20 @@ var cm = this.cm; var settings = this.settings; - if (!settings.syncScrolling) { - return this; - } + // if (!settings.syncScrolling) { + // return this; + // } cm.on("change", function(_cm, changeObj) { - + // console.log("cmChange") if (settings.watch) { _this.previewContainer.css("padding", settings.autoHeight ? "20px 20px 50px 40px" : "20px"); } - + if (timer) clearTimeout(timer); + if (settings.onCmChange) $.proxy(settings.onCmChange, _this)(); timer = setTimeout(function() { - clearTimeout(timer); + // console.log("cmChangeinsideTimeout") _this.save(); timer = null; }, settings.delay); @@ -1895,7 +1981,7 @@ */ loadedDisplay : function(recreate) { - + // console.log("loadedDisplay") recreate = recreate || false; var _this = this; @@ -1929,6 +2015,11 @@ this.state.loaded = true; + if (settings.watch) { + this.save(); + preview.show(); + } + return this; }, @@ -1974,7 +2065,7 @@ */ resize : function(width, height) { - + // console.log("resize") width = width || null; height = height || null; @@ -2066,12 +2157,7 @@ */ save : function() { - - if (timer === null) - { - return this; - } - + // console.log("saving") var _this = this; var state = this.state; var settings = this.settings; @@ -2079,6 +2165,11 @@ var cmValue = cm.getValue(); var previewContainer = this.previewContainer; + if (timer === null && !(!settings.watch && state.preview)) + { + return this; + } + if (settings.mode !== "gfm" && settings.mode !== "markdown") { this.markdownTextarea.val(cmValue); @@ -2086,127 +2177,131 @@ return this; } - var marked = editormd.$marked; - var markdownToC = this.markdownToC = []; - var rendererOptions = this.markedRendererOptions = { - toc : settings.toc, - tocm : settings.tocm, - tocStartLevel : settings.tocStartLevel, - pageBreak : settings.pageBreak, - taskList : settings.taskList, - emoji : settings.emoji, - tex : settings.tex, - atLink : settings.atLink, // for @link - emailLink : settings.emailLink, // for mail address auto link - flowChart : settings.flowChart, - sequenceDiagram : settings.sequenceDiagram, - previewCodeHighlight : settings.previewCodeHighlight, - mermaid : settings.mermaid, - mindMap : settings.mindMap, // 思维导图 - }; - - var markedOptions = this.markedOptions = { - renderer : editormd.markedRenderer(markdownToC, rendererOptions), - gfm : true, - tables : true, - breaks : true, - pedantic : false, - sanitize : (settings.htmlDecode) ? false : true, // 关闭忽略HTML标签,即开启识别HTML标签,默认为false - smartLists : true, - smartypants : true - }; - - marked.setOptions(markedOptions); - - var newMarkdownDoc = editormd.$marked(cmValue, markedOptions); - - if(settings.debug) { - console.info("cmValue", cmValue, newMarkdownDoc); - } - newMarkdownDoc = editormd.filterHTMLTags(newMarkdownDoc, settings.htmlDecode); - - //console.error("cmValue", cmValue, newMarkdownDoc); - - this.markdownTextarea.text(cmValue); - cm.save(); - if (settings.saveHTMLToTextarea) - { - this.htmlTextarea.text(newMarkdownDoc); - } + if (settings.saveHTMLToTextarea || settings.watch || (!settings.watch && state.preview)){ + // console.log("rendering") + var marked = editormd.$marked; + var markdownToC = this.markdownToC = []; + var rendererOptions = this.markedRendererOptions = { + toc : settings.toc, + tocm : settings.tocm, + tocStartLevel : settings.tocStartLevel, + pageBreak : settings.pageBreak, + taskList : settings.taskList, + emoji : settings.emoji, + tex : settings.tex, + atLink : settings.atLink, // for @link + emailLink : settings.emailLink, // for mail address auto link + flowChart : settings.flowChart, + sequenceDiagram : settings.sequenceDiagram, + previewCodeHighlight : settings.previewCodeHighlight, + mermaid : settings.mermaid, + mindMap : settings.mindMap, // 思维导图 + }; - if(settings.watch || (!settings.watch && state.preview)) - { - previewContainer.html(newMarkdownDoc); + var markedOptions = this.markedOptions = { + renderer : editormd.markedRenderer(markdownToC, rendererOptions), + gfm : true, + tables : true, + breaks : true, + pedantic : false, + smartLists : true, + smartypants : true + }; - this.previewCodeHighlight(); + marked.setOptions(markedOptions); - if (settings.toc) + var newMarkdownDoc = editormd.$marked.parse(cmValue, markedOptions); + + if(settings.debug) { + console.info("cmValue", cmValue, newMarkdownDoc); + } + newMarkdownDoc = editormd.$filterXSS(newMarkdownDoc); + + //console.error("cmValue", cmValue, newMarkdownDoc); + + this.markdownTextarea.text(cmValue); + + cm.save(); + + if (settings.saveHTMLToTextarea) { - var tocContainer = (settings.tocContainer === "") ? previewContainer : $(settings.tocContainer); - var tocMenu = tocContainer.find("." + this.classPrefix + "toc-menu"); - - tocContainer.attr("previewContainer", (settings.tocContainer === "") ? "true" : "false"); - - if (settings.tocContainer !== "" && tocMenu.length > 0) - { - tocMenu.remove(); - } - - editormd.markdownToCRenderer(markdownToC, tocContainer, settings.tocDropdown, settings.tocStartLevel); - - if (settings.tocDropdown || tocContainer.find("." + this.classPrefix + "toc-menu").length > 0) - { - editormd.tocDropdownMenu(tocContainer, (settings.tocTitle !== "") ? settings.tocTitle : this.lang.tocTitle); - } - - if (settings.tocContainer !== "") - { - previewContainer.find(".markdown-toc").css("border", "none"); - } + this.htmlTextarea.text(newMarkdownDoc); } - if (settings.tex) + if(settings.watch || (!settings.watch && state.preview)) { - if (!editormd.kaTeXLoaded && settings.autoLoadModules) + previewContainer.html(newMarkdownDoc); + + this.previewCodeHighlight(); + + if (settings.toc) { - editormd.loadKaTeX(function() { + var tocContainer = (settings.tocContainer === "") ? previewContainer : $(settings.tocContainer); + var tocMenu = tocContainer.find("." + this.classPrefix + "toc-menu"); + + tocContainer.attr("previewContainer", (settings.tocContainer === "") ? "true" : "false"); + + if (settings.tocContainer !== "" && tocMenu.length > 0) + { + tocMenu.remove(); + } + + editormd.markdownToCRenderer(markdownToC, tocContainer, settings.tocDropdown, settings.tocStartLevel); + + if (settings.tocDropdown || tocContainer.find("." + this.classPrefix + "toc-menu").length > 0) + { + editormd.tocDropdownMenu(tocContainer, (settings.tocTitle !== "") ? settings.tocTitle : this.lang.tocTitle); + } + + if (settings.tocContainer !== "") + { + previewContainer.find(".markdown-toc").css("border", "none"); + } + } + + if (settings.tex) + { + if (!editormd.kaTeXLoaded && settings.autoLoadModules) + { + editormd.loadKaTeX(function() { + editormd.$katex = katex; + editormd.kaTeXLoaded = true; + _this.katexRender(); + }); + } + else + { editormd.$katex = katex; - editormd.kaTeXLoaded = true; - _this.katexRender(); - }); + this.katexRender(); + } } - else + + // 渲染脑图 + if(settings.mindMap){ + setTimeout(function(){ + _this.mindmapRender(); + },10) + + } + + if (settings.flowChart || settings.sequenceDiagram || settings.mermaid) { - editormd.$katex = katex; - this.katexRender(); + flowchartTimer = setTimeout(function(){ + clearTimeout(flowchartTimer); + _this.flowChartAndSequenceDiagramRender(); + flowchartTimer = null; + }, 10); + } + + if (state.loaded) + { + $.proxy(settings.onchange, this)(); } } - // 渲染脑图 - if(settings.mindMap){ - setTimeout(function(){ - _this.mindmapRender(); - },10) - - } - - if (settings.flowChart || settings.sequenceDiagram || settings.mermaid) - { - flowchartTimer = setTimeout(function(){ - clearTimeout(flowchartTimer); - _this.flowChartAndSequenceDiagramRender(); - flowchartTimer = null; - }, 10); - } - - if (state.loaded) - { - $.proxy(settings.onchange, this)(); - } } - return this; }, @@ -2602,6 +2697,7 @@ toolbar.find(".fa[name=preview]").toggleClass("active"); } + // codeMirror.hide(); codeMirror.toggle(); var escHandle = function(event) { @@ -2689,12 +2785,14 @@ previewContainer.css("padding", "20px"); } + const toolbarHeight = (settings.toolbar) ? toolbar.height() : 0; + preview.css({ background : null, position : "absolute", width : editor.width() / 2, - height : (settings.autoHeight && !this.state.fullscreen) ? "auto" : editor.height() - toolbar.height(), - top : (settings.toolbar) ? toolbar.height() : 0 + height : (settings.autoHeight && !this.state.fullscreen) ? "auto" : editor.height() - toolbarHeight, + top : (settings.toolbar) ? toolbarHeight : 0 }); if (this.state.loaded) @@ -2805,13 +2903,12 @@ * @returns {editormd} 返回editormd的实例对象 */ - executePlugin : function(name, path) { - + executePlugin : function(name, path, customPlugin = false, optionalParams= {"proxy": false}) { var _this = this; var cm = this.cm; var settings = this.settings; - path = settings.pluginPath + path; + path = (customPlugin ? settings.customPluginPath : settings.pluginPath) + path; if (typeof define === "function") { @@ -2822,21 +2919,35 @@ return this; } - this[name](cm); - - return this; + if (optionalParams["proxy"]) { + return this[name](cm); + } else { + this[name](cm); + return this; + } } if ($.inArray(path, editormd.loadFiles.plugin) < 0) { - editormd.loadPlugin(path, function() { - editormd.loadPlugins[name] = _this[name]; - _this[name](cm); - }); + if (optionalParams["proxy"]){ + return new Promise((res)=>{ + editormd.loadPlugin(path, function() { + editormd.loadPlugins[name] = _this[name]; + res(_this[name](cm, optionalParams)) + }, "head", (customPlugin ? _this.author_ide_version : editormd.version) ); + }); + } + else{ + editormd.loadPlugin(path, function() { + editormd.loadPlugins[name] = _this[name]; + _this[name](cm, optionalParams); + }, "head", (customPlugin ? _this.author_ide_version : editormd.version) ); + } } else { - $.proxy(editormd.loadPlugins[name], this)(cm); + if (optionalParams["proxy"]) return $.proxy(editormd.loadPlugins[name], this)(cm, optionalParams); + $.proxy(editormd.loadPlugins[name], this)(cm, optionalParams); } return this; @@ -2899,6 +3010,32 @@ } }; + + editormd.positionDialog = function(dialog, position="center") { + var left, top; + + switch (position) { + case "center": + left = ($(window).width() - dialog.width()) / 2 + "px"; + top = ($(window).height() - dialog.height()) / 2 + "px"; + break; + case "center-left": + left = ($(window).width() / 4 - dialog.width() / 2) + "px"; + top = ($(window).height() - dialog.height()) / 2 + "px"; + break; + case "center-right": + left = ($(window).width() * 3 / 4 - dialog.width() / 2) + "px"; + top = ($(window).height() - dialog.height()) / 2 + "px"; + break; + default: + console.warn(`Unsupported dialog position: ${position}`); + left = ($(window).width() - dialog.width()) / 2 + "px"; + top = ($(window).height() - dialog.height()) / 2 + "px"; + } + + dialog.css({ top, left }); + }; + /** * 显示透明背景层 * Display mask layer when dialog opening @@ -3026,7 +3163,8 @@ h1 : function() { var cm = this.cm; var cursor = cm.getCursor(); - var selection = cm.getLine(cursor.line); + // var selection = cm.getLine(cursor.line); + var selection = cm.getSelection(); var patt1=new RegExp("^#{1}[ ]");//如果存在H1 var patt2=new RegExp("^#{1,6}[ ]");//如果存在H2-H6 //如果存在H1,取消H1的设置 @@ -3055,7 +3193,8 @@ h2 : function() { var cm = this.cm; var cursor = cm.getCursor(); - var selection = cm.getLine(cursor.line); + // var selection = cm.getLine(cursor.line); + var selection = cm.getSelection(); var patt1=new RegExp("^#{2}[ ]");//如果存在H1 var patt2=new RegExp("^#{1,6}[ ]");//如果存在H1-H6 //如果存在H2,取消H2的设置 @@ -3069,7 +3208,7 @@ cm.setSelection({line:cursor.line, ch:0}, {line:cursor.line+1, ch:0 }); cm.replaceSelection("## "+selection+"\n"); cm.setCursor(cursor.line, cursor.ch +3); - + }else{ cm.setSelection({line:cursor.line, ch:0}, {line:cursor.line+1, ch:0 }); cm.replaceSelection("## "+selection+"\n"); @@ -3080,7 +3219,8 @@ h3 : function() { var cm = this.cm; var cursor = cm.getCursor(); - var selection = cm.getLine(cursor.line); + // var selection = cm.getLine(cursor.line); + var selection = cm.getSelection(); var patt1=new RegExp("^#{3}[ ]");//如果存在H3 var patt2=new RegExp("^#{1,6}[ ]");//如果存在H1-H6 //如果存在H3,取消H3的设置 @@ -3109,7 +3249,8 @@ h4 : function() { var cm = this.cm; var cursor = cm.getCursor(); - var selection = cm.getLine(cursor.line); + // var selection = cm.getLine(cursor.line); + var selection = cm.getSelection(); var patt1=new RegExp("^#{4}[ ]");//如果存在H4 var patt2=new RegExp("^#{1,6}[ ]");//如果存在H1-H6 //如果存在H4,取消H4的设置 @@ -3138,7 +3279,8 @@ h5 : function() { var cm = this.cm; var cursor = cm.getCursor(); - var selection = cm.getLine(cursor.line); + // var selection = cm.getLine(cursor.line); + var selection = cm.getSelection(); var patt1=new RegExp("^#{5}[ ]");//如果存在H5 var patt2=new RegExp("^#{1,6}[ ]");//如果存在H1-H6 //如果存在H5,取消H5的设置 @@ -3167,7 +3309,8 @@ h6 : function() { var cm = this.cm; var cursor = cm.getCursor(); - var selection = cm.getLine(cursor.line); + // var selection = cm.getLine(cursor.line); + var selection = cm.getSelection(); var patt1=new RegExp("^#{6}[ ]");//如果存在H6 var patt2=new RegExp("^#{1,6}[ ]");//如果存在H1-H6 //如果存在H6,取消H6的设置 @@ -3217,15 +3360,14 @@ //如果全作了无序列表标记,取消标记 if(cnt===selectionText.length){ for (var i = 0, len = selectionText.length; i < len; i++){ - selectionText[i] = (selectionText[i] === "") ? "" : selectionText[i].replace(/^-{1}[ ]/,""); + selectionText[i] = (selectionText[i] === "") ? "" : selectionText[i].replace(patt1,""); } }else //对未打上无序列表标记,打上标记 { for (var i = 0, len = selectionText.length; i < len; i++){ - selectionText[i] = (selectionText[i] === "") ? "" : "- "+selectionText[i].replace(/^-{1}[ ]/,""); + selectionText[i] = (selectionText[i] === "") ? "" : "- " + selectionText[i].replace(patt1,""); } - } cm.replaceSelection(selectionText.join("\n")); } @@ -3257,13 +3399,11 @@ for (var i = 0, len = selectionText.length; i < len; i++){ selectionText[i] = (selectionText[i] === "") ? "" : selectionText[i].replace(/^[0-9]+[\.][ ]/,""); } - }else - //对未打上有序列表标记,打上标记 - { + } else { + //对未打上有序列表标记,打上标记 for (var i = 0, len = selectionText.length; i < len; i++){ - selectionText[i] = (selectionText[i] === "") ? "" : (i+1)+". "+selectionText[i].replace(/^[0-9]+[\.][ ]/,""); + selectionText[i] = (selectionText[i] === "") ? "" : (i+1) + ". " + selectionText[i].replace(patt1,""); } - } cm.replaceSelection(selectionText.join("\n")); } @@ -3400,17 +3540,20 @@ } }; - editormd.keyMaps = { - "Ctrl-1" : "h1", - "Ctrl-2" : "h2", - "Ctrl-3" : "h3", - "Ctrl-4" : "h4", - "Ctrl-5" : "h5", - "Ctrl-6" : "h6", - "Ctrl-B" : "bold", // if this is string == editormd.toolbarHandlers.xxxx - "Ctrl-D" : "datetime", + var isMac = navigator.platform.toUpperCase().indexOf('MAC')>=0; + var key = isMac ? "Cmd" : "Ctrl"; - "Ctrl-E" : function() { // emoji + editormd.keyMaps = { + [key + "-1"] : "h1", + [key + "-2"] : "h2", + [key + "-3"] : "h3", + [key + "-4"] : "h4", + [key + "-5"] : "h5", + [key + "-6"] : "h6", + [key + "-B"] : "bold", // if this is string == editormd.toolbarHandlers.xxxx + [key + "-D"] : "datetime", + + [key + "-E"] : function() { // emoji var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); @@ -3427,12 +3570,12 @@ cm.setCursor(cursor.line, cursor.ch + 1); } }, - "Ctrl-Alt-G" : "goto-line", - "Ctrl-H" : "hr", - "Ctrl-I" : "italic", - "Ctrl-K" : "code", + [key + "-Alt-G"] : "goto-line", + [key + "-H"] : "hr", + [key + "-I"] : "italic", + [key + "-K"] : "code", - "Ctrl-L" : function() { + [key + "-L"] : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); @@ -3445,9 +3588,9 @@ cm.setCursor(cursor.line, cursor.ch + 1); } }, - "Ctrl-U" : "list-ul", + [key + "-U"] : "list-ul", - "Shift-Ctrl-A" : function() { + ["Shift-" + key + "-A"] : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); @@ -3465,10 +3608,10 @@ } }, - "Shift-Ctrl-C" : "code", - "Shift-Ctrl-Q" : "quote", - "Shift-Ctrl-S" : "del", - "Shift-Ctrl-K" : "tex", // KaTeX + ["Shift" + key + "-C"] : "code", + ["Shift" + key + "Q"] : "quote", + ["Shift" + key + "S"] : "del", + ["Shift" + key + "K"] : "tex", // KaTeX "Shift-Alt-C" : function() { var cm = this.cm; @@ -3482,16 +3625,16 @@ } }, - "Shift-Ctrl-Alt-C" : "code-block", - "Shift-Ctrl-H" : "html-entities", - "Shift-Alt-H" : "help", - "Shift-Ctrl-E" : "emoji", - "Shift-Ctrl-U" : "uppercase", - "Shift-Alt-U" : "ucwords", - "Shift-Ctrl-Alt-U" : "ucfirst", - "Shift-Alt-L" : "lowercase", + ["Shift-" + key + "-Alt-C"] : "code-block", + ["Shift-" + key + "-H"] : "html-entities", + "Shift-Alt-H" : "help", + ["Shift-" + key + "-E"] : "emoji", + ["Shift-" + key + "-U"] : "uppercase", + "Shift-Alt-U" : "ucwords", + ["Shift-" + key + "-Alt-U"] : "ucfirst", + "Shift-Alt-L" : "lowercase", - "Shift-Ctrl-I" : function() { + ["Shift-" + key + "-I"] : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); @@ -3505,15 +3648,15 @@ } }, - "Shift-Ctrl-Alt-I" : "image", - "Shift-Ctrl-L" : "link", - "Shift-Ctrl-O" : "list-ol", - "Shift-Ctrl-P" : "preformatted-text", - "Shift-Ctrl-T" : "table", - "Shift-Alt-P" : "pagebreak", - "F9" : "watch", - "F10" : "preview", - "F11" : "fullscreen", + ["Shift-" + key + "-Alt-I"] : "image", + ["Shift-" + key + "-L"] : "link", + ["Shift-" + key + "-O"] : "list-ol", + ["Shift-" + key + "-P"] : "preformatted-text", + ["Shift-" + key + "-T"] : "table", + "Shift-Alt-P" : "pagebreak", + "F9" : "watch", + "F10" : "preview", + "F11" : "fullscreen", }; /** @@ -3573,7 +3716,7 @@ email : /(\w+)@(\w+)\.(\w+)\.?(\w+)?/g, emailLink : /(mailto:)?([\w\.\_]+)@(\w+)\.(\w+)\.?(\w+)?/g, emoji : /:([\w\+-]+):/g, - emojiDatetime : /(\d{2}:\d{2}:\d{2})/g, + emojiDatetime : /(\d{1,2}:\d{1,2}:\d{1,2})/g, twemoji : /:(tw-([\w]+)-?(\w+)?):/g, fontAwesome : /:(fa-([\w]+)(-(\w+)){0,}):/g, editormdLogo : /:(editormd-logo-?(\w+)?):/g, @@ -3582,7 +3725,8 @@ // Emoji graphics files url path editormd.emoji = { - path : "http://www.emoji-cheat-sheet.com/graphics/emojis/", + // path : "http://www.emoji-cheat-sheet.com/graphics/emojis/", + path: "https://www.webpagefx.com/tools/emoji-cheat-sheet/graphics/emojis/", ext : ".png" }; @@ -3814,7 +3958,7 @@ return ''; } - var out = ""; + var headingHTML = ""; - headingHTML += ""; headingHTML += ""; headingHTML += (hasLinkReg) ? this.atLink(this.emoji(linkText)) : this.atLink(this.emoji(text)); headingHTML += ""; @@ -3895,21 +4036,21 @@ }; markedRenderer.paragraph = function(text) { - var isTeXInline = /\$\$(.*)\$\$/g.test(text); - var isTeXLine = /^\$\$(.*)\$\$$/.test(text); - var isTeXAddClass = (isTeXLine) ? " class=\"" + editormd.classNames.tex + "\"" : " class=\"line\""; + var isTeXInline = /\$\$(.+?)\$\$/g.test(text); + var isTeXLine = /^(?!\$\$.+?(?:\$\$).+?\$\$)(\$\$(.+?)\$\$)$/.test(text); + var isTeXAddClass = (isTeXLine) ? " class=\"" + editormd.classNames.tex + "\"" : ""; var isToC = (settings.tocm) ? /^(\[TOC\]|\[TOCM\])$/.test(text) : /^\[TOC\]$/.test(text); var isToCMenu = /^\[TOCM\]$/.test(text); if (!isTeXLine && isTeXInline) { - text = text.replace(/(\$\$([^\$]*)\$\$)+/g, function($1, $2) { - return "" + $2.replace(/\$/g, "") + ""; + text = text.replaceAll(/(\$\$(.+?)\$\$)/g, function(match, $1, $2) { + return "" + $2.replaceAll(/\/g,"") + ""; }); } else { - text = (isTeXLine) ? text.replace(/\$/g, "") : text; + text = (isTeXLine) ? text.replace(/^(?!\$\$.+?(?:\$\$).+?\$\$)(\$\$(.+?)\$\$)$/, (match, $1, $2) => $2) : text; } var tocHTML = "
                      " + text + "
                      "; @@ -3941,7 +4082,7 @@ } else if ( lang === "math" || lang === "latex" || lang === "katex") { - return "

                      " + code + "

                      "; + return "

                      " + code + "

                      "; } else if (/^mindmap/i.test(lang)){ var len = 9 || 32; @@ -3963,7 +4104,7 @@ if (lang === "drawio") { var svgCode = decodeURIComponent(escape(window.atob(code))) return "
                      " + svgCode + "
                      " - } + } else { return marked.Renderer.prototype.code.apply(this, arguments); @@ -4032,14 +4173,14 @@ } else if (level < lastLevel) { - // html += (new Array(lastLevel - level + 2)).join("
                  • "); + html += (new Array(lastLevel - level + 2)).join(""); } else { - // html += ""; + html += ""; } - html += "
                  • " + text + "
                  • "; + html += "
                  • " + text + "
                      "; lastLevel = level; } @@ -4216,6 +4357,7 @@ return html; }; + editormd.$filterXSS = editormd.filterHTMLTags; /** * 将Markdown文档解析为HTML用于前台显示 @@ -4237,7 +4379,6 @@ tocContainer : "", markdown : "", markdownSourceCode : false, - htmlDecode : false, autoLoadKaTeX : true, pageBreak : true, atLink : true, // for @link @@ -4264,7 +4405,7 @@ saveTo = div.find("textarea"); } - var markdownDoc = (settings.markdown === "") ? saveTo.val() : settings.markdown; + var markdownDoc = (settings.markdown === undefined) ? saveTo.val() : settings.markdown; var markdownToC = []; var rendererOptions = { @@ -4290,16 +4431,15 @@ tables : true, breaks : true, pedantic : false, - sanitize : (settings.htmlDecode) ? false : true, // 是否忽略HTML标签,即是否开启HTML标签解析,为了安全性,默认不开启 smartLists : true, smartypants : true }; markdownDoc = new String(markdownDoc); - var markdownParsed = marked(markdownDoc, markedOptions); + var markdownParsed = marked.parse(markdownDoc, markedOptions); - markdownParsed = editormd.filterHTMLTags(markdownParsed, settings.htmlDecode); + markdownParsed = editormd.$filterXSS(markdownParsed); if (settings.markdownSourceCode) { saveTo.text(markdownDoc); @@ -4333,8 +4473,10 @@ if (settings.previewCodeHighlight) { - div.find("pre").addClass("prettyprint"); + div.find("pre").addClass("prettyprint linenums"); + //TODO: fix later if we decide to generate html prettyPrint(); + // prettyPrint($.proxy(editormd.settings.fixCodeBlocks, editormd)); } if (!editormd.isIE8) @@ -4436,15 +4578,16 @@ * @param {String} fileName 插件文件路径 * @param {Function} [callback=function()] 加载成功后执行的回调函数 * @param {String} [into="head"] 嵌入页面的位置 + * @param {String} [version=editormd.version] */ - editormd.loadPlugin = function(fileName, callback, into) { + editormd.loadPlugin = function(fileName, callback, into, version) { callback = callback || function() {}; this.loadScript(fileName, function() { editormd.loadFiles.plugin.push(fileName); callback(); - }, into); + }, into, version); }; /** @@ -4454,11 +4597,13 @@ * @param {String} fileName CSS文件名 * @param {Function} [callback=function()] 加载成功后执行的回调函数 * @param {String} [into="head"] 嵌入页面的位置 + * @param {String} [version=editormd.version] */ - editormd.loadCSS = function(fileName, callback, into) { + editormd.loadCSS = function(fileName, callback, into, version=editormd.version) { into = into || "head"; callback = callback || function() {}; + version = version || editormd.version var css = document.createElement("link"); css.type = "text/css"; @@ -4468,7 +4613,7 @@ callback(); }; - css.href = fileName + ".css"; + css.href = fileName + `.css?editormd_version=${version}`; if(into === "head") { document.getElementsByTagName("head")[0].appendChild(css); @@ -4489,16 +4634,17 @@ * @param {String} [into="head"] 嵌入页面的位置 */ - editormd.loadScript = function(fileName, callback, into) { + editormd.loadScript = function(fileName, callback, into, version) { into = into || "head"; + version = version || editormd.version callback = callback || function() {}; var script = null; script = document.createElement("script"); script.id = fileName.replace(/[\./]+/g, "-"); script.type = "text/javascript"; - script.src = fileName + ".js"; + script.src = fileName + `.js?editormd_version=${version}`; if (editormd.isIE8) { @@ -4529,11 +4675,12 @@ } }; - // 使用国外的CDN,加载速度有时会很慢,或者自定义URL + // 使用国内的CDN,或者自定义URL // You can custom KaTeX load url. editormd.katexURL = { - css : "//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.3.0/katex.min", - js : "//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.3.0/katex.min" + css: "https://cdn.bootcdn.net/ajax/libs/KaTeX/0.16.8/katex.min", + jsmain: "https://cdn.bootcdn.net/ajax/libs/KaTeX/0.16.8/katex.min", + jsauto: "https://cdn.bootcdn.net/ajax/libs/KaTeX/0.16.8/contrib/auto-render.min" }; editormd.kaTeXLoaded = false; @@ -4547,7 +4694,9 @@ editormd.loadKaTeX = function (callback) { editormd.loadCSS(editormd.katexURL.css, function(){ - editormd.loadScript(editormd.katexURL.js, callback || function(){}); + editormd.loadScript(editormd.katexURL.jsmain, function() { + editormd.loadScript(editormd.katexURL.jsauto, callback || function() {}) + }) }); }; @@ -4575,7 +4724,7 @@ var defaults = { name : "", width : 420, - height: 240, + height: "auto", title : "", drag : true, closed : true, @@ -4585,6 +4734,13 @@ backgroundColor : "#fff", opacity : 0.1 }, + removeDialogOnClose: false, + resizeableX: false, + resizeableY: false, + minWidth: 0, + minHeight: 0, + maxWidth: "none", + maxHeight: "none", lockScreen : true, footer : true, buttons : false @@ -4604,15 +4760,14 @@ if (options.title !== "") { html += "
                      "; - html += "" + options.title + ""; + html += "" + options.title + ""; + if (options.closed) + { + html += ""; + } html += "
                      "; } - if (options.closed) - { - html += ""; - } - html += "
                      " + options.content; if (options.footer || typeof options.footer === "string") @@ -4670,7 +4825,14 @@ zIndex : editormd.dialogZindex, border : (editormd.isIE8) ? "1px solid #ddd" : "", width : (typeof options.width === "number") ? options.width + "px" : options.width, - height : (typeof options.height === "number") ? options.height + "px" : options.height + height : (typeof options.height === "number") ? options.height + "px" : options.height, + "min-width": (typeof options.minWidth === "number") ? options.minWidth + "px" : options.minWidth, + "min-height": (typeof options.minHeight === "number") ? options.minHeight + "px" : options.minHeight, + "max-width": (typeof options.maxWidth === "number") ? options.maxWidth + "px" : options.maxWidth, + "max-height": (typeof options.maxHeight === "number") ? options.maxHeight + "px" : options.maxHeight, + ...((options.resizeableX || options.resizeableY) ? { overflow: 'hidden', + resize: (options.resizeableX && options.resizeableY) ? "both" : ((options.resizeableX) ? "horizontal" : "vertical") + } : {}) }); var dialogPosition = function(){ @@ -4684,8 +4846,9 @@ $(window).resize(dialogPosition); - dialog.children("." + classPrefix + "dialog-close").bind(mouseOrTouch("click", "touchend"), function() { + dialog.find("." + classPrefix + "dialog-close").bind(mouseOrTouch("click", "touchend"), function() { dialog.hide().lockScreen(false).hideMask(); + if (options.removeDialogOnClose) dialog.remove() }); if (typeof options.buttons === "object") diff --git a/static/editor.md/editormd.min.js b/static/editor.md/editormd.min.js index f264e9a1..e6225362 100644 --- a/static/editor.md/editormd.min.js +++ b/static/editor.md/editormd.min.js @@ -1 +1,2 @@ -(function(factory){"use strict";if(typeof require==="function"&&typeof exports==="object"&&typeof module==="object"){module.exports=factory}else if(typeof define==="function"){if(define.amd){}else{define(["jquery"],factory)}}else{window.editormd=factory()}})(function(){"use strict";var $=typeof jQuery!=="undefined"?jQuery:Zepto;if(typeof $==="undefined"){return}var editormd=function(id,options){return new editormd.fn.init(id,options)};editormd.title=editormd.$name="Editor.md";editormd.version="1.5.0";editormd.homePage="https://pandao.github.io/editor.md/";editormd.classPrefix="editormd-";editormd.toolbarModes={full:["undo","redo","|","bold","del","italic","quote","ucwords","uppercase","lowercase","|","h1","h2","h3","h4","h5","h6","|","list-ul","list-ol","hr","|","link","reference-link","image","code","preformatted-text","code-block","table","datetime","emoji","html-entities","pagebreak","|","goto-line","watch","preview","fullscreen","clear","search","|","help","info"],simple:["undo","redo","|","bold","del","italic","quote","uppercase","lowercase","|","h1","h2","h3","h4","h5","h6","|","list-ul","list-ol","hr","|","watch","preview","fullscreen","|","help","info"],mini:["undo","redo","|","watch","preview","|","help","info"]};editormd.defaults={debug:false,mode:"gfm",name:"",value:"",theme:"",editorTheme:"default",previewTheme:"",markdown:"",appendMarkdown:"",width:"100%",height:"100%",path:"./lib/",pluginPath:"",delay:500,autoLoadModules:true,watch:true,placeholder:"Enjoy Markdown! coding now...",gotoLine:true,codeFold:false,autoHeight:false,autoFocus:true,autoCloseTags:true,searchReplace:true,syncScrolling:true,readOnly:false,tabSize:4,indentUnit:4,lineNumbers:true,lineWrapping:true,autoCloseBrackets:true,showTrailingSpace:true,matchBrackets:true,indentWithTabs:true,styleSelectedText:true,matchWordHighlight:true,styleActiveLine:true,dialogLockScreen:true,dialogShowMask:true,dialogDraggable:true,dialogMaskBgColor:"#fff",dialogMaskOpacity:.1,fontSize:"13px",saveHTMLToTextarea:false,disabledKeyMaps:[],onload:function(){},onresize:function(){},onchange:function(){},onwatch:null,onunwatch:null,onpreviewing:function(){},onpreviewed:function(){},onfullscreen:function(){},onfullscreenExit:function(){},onscroll:function(){},onpreviewscroll:function(){},imageUpload:false,imageFormats:["jpg","jpeg","gif","png","bmp","webp"],imageUploadURL:"",crossDomainUpload:false,uploadCallbackURL:"",toc:true,tocm:false,tocTitle:"",tocDropdown:false,tocContainer:"",tocStartLevel:1,htmlDecode:false,pageBreak:true,atLink:true,emailLink:true,taskList:false,emoji:false,tex:false,flowChart:false,sequenceDiagram:false,mermaid:true,mindMap:true,previewCodeHighlight:true,toolbar:true,toolbarAutoFixed:true,toolbarIcons:"full",toolbarTitles:{},toolbarHandlers:{ucwords:function(){return editormd.toolbarHandlers.ucwords},lowercase:function(){return editormd.toolbarHandlers.lowercase}},toolbarCustomIcons:{lowercase:'a',ucwords:'Aa'},toolbarIconsClass:{undo:"fa-undo",redo:"fa-repeat",bold:"fa-bold",del:"fa-strikethrough",italic:"fa-italic",quote:"fa-quote-left",uppercase:"fa-font",h1:editormd.classPrefix+"bold",h2:editormd.classPrefix+"bold",h3:editormd.classPrefix+"bold",h4:editormd.classPrefix+"bold",h5:editormd.classPrefix+"bold",h6:editormd.classPrefix+"bold","list-ul":"fa-list-ul","list-ol":"fa-list-ol",hr:"fa-minus",link:"fa-link","reference-link":"fa-anchor",image:"fa-picture-o",code:"fa-code","preformatted-text":"fa-file-code-o","code-block":"fa-file-code-o",table:"fa-table",datetime:"fa-clock-o",emoji:"fa-smile-o","html-entities":"fa-copyright",pagebreak:"fa-newspaper-o","goto-line":"fa-terminal",watch:"fa-eye-slash",unwatch:"fa-eye",preview:"fa-desktop",search:"fa-search",fullscreen:"fa-arrows-alt",clear:"fa-eraser",help:"fa-question-circle",info:"fa-info-circle"},toolbarIconTexts:{},lang:{name:"zh-cn",description:"开源在线Markdown编辑器
                      Open source online Markdown editor.",tocTitle:"目录",toolbar:{undo:"撤销(Ctrl+Z)",redo:"重做(Ctrl+Y)",bold:"粗体",del:"删除线",italic:"斜体",quote:"引用",ucwords:"将每个单词首字母转成大写",uppercase:"将所选转换成大写",lowercase:"将所选转换成小写",h1:"标题1",h2:"标题2",h3:"标题3",h4:"标题4",h5:"标题5",h6:"标题6","list-ul":"无序列表","list-ol":"有序列表",hr:"横线",link:"链接","reference-link":"引用链接",image:"添加图片",code:"行内代码","preformatted-text":"预格式文本 / 代码块(缩进风格)","code-block":"代码块(多语言风格)",table:"添加表格",datetime:"日期时间",emoji:"Emoji表情","html-entities":"HTML实体字符",pagebreak:"插入分页符","goto-line":"跳转到行",watch:"关闭实时预览",unwatch:"开启实时预览",preview:"全窗口预览HTML(按 Shift + ESC还原)",fullscreen:"全屏(按ESC还原)",clear:"清空",search:"搜索",help:"使用帮助",info:"关于"+editormd.title},buttons:{enter:"确定",cancel:"取消",close:"关闭"},dialog:{link:{title:"添加链接",url:"链接地址",urlTitle:"链接标题",urlEmpty:"错误:请填写链接地址。"},referenceLink:{title:"添加引用链接",name:"引用名称",url:"链接地址",urlId:"链接ID",urlTitle:"链接标题",nameEmpty:"错误:引用链接的名称不能为空。",idEmpty:"错误:请填写引用链接的ID。",urlEmpty:"错误:请填写引用链接的URL地址。"},image:{title:"添加图片",url:"图片地址",link:"图片链接",alt:"图片描述",uploadButton:"本地上传",imageURLEmpty:"错误:图片地址不能为空。",uploadFileEmpty:"错误:上传的图片不能为空。",formatNotAllowed:"错误:只允许上传图片文件,允许上传的图片文件格式有:"},preformattedText:{title:"添加预格式文本或代码块",emptyAlert:"错误:请填写预格式文本或代码的内容。"},codeBlock:{title:"添加代码块",selectLabel:"代码语言:",selectDefaultText:"请选择代码语言",otherLanguage:"其他语言",unselectedLanguageAlert:"错误:请选择代码所属的语言类型。",codeEmptyAlert:"错误:请填写代码内容。"},htmlEntities:{title:"HTML 实体字符"},help:{title:"使用帮助"}}}};editormd.classNames={tex:editormd.classPrefix+"tex"};editormd.dialogZindex=99999;editormd.$katex=null;editormd.$marked=null;editormd.$CodeMirror=null;editormd.$prettyPrint=null;var timer,flowchartTimer;editormd.prototype=editormd.fn={state:{watching:false,loaded:false,preview:false,fullscreen:false},init:function(id,options){options=options||{};if(typeof id==="object"){options=id}var _this=this;var classPrefix=this.classPrefix=editormd.classPrefix;var settings=this.settings=$.extend(true,editormd.defaults,options);id=typeof id==="object"?settings.id:id;var editor=this.editor=$("#"+id);this.id=id;this.lang=settings.lang;var classNames=this.classNames={textarea:{html:classPrefix+"html-textarea",markdown:classPrefix+"markdown-textarea"}};settings.pluginPath=settings.pluginPath===""?settings.path+"../plugins/":settings.pluginPath;this.state.watching=settings.watch?true:false;if(!editor.hasClass("editormd")){editor.addClass("editormd")}editor.css({width:typeof settings.width==="number"?settings.width+"px":settings.width,height:typeof settings.height==="number"?settings.height+"px":settings.height});if(settings.autoHeight){editor.css("height","auto")}var markdownTextarea=this.markdownTextarea=editor.children("textarea");if(markdownTextarea.length<1){editor.append("");markdownTextarea=this.markdownTextarea=editor.children("textarea")}markdownTextarea.addClass(classNames.textarea.markdown).attr("placeholder",settings.placeholder);if(typeof markdownTextarea.attr("name")==="undefined"||markdownTextarea.attr("name")===""){markdownTextarea.attr("name",settings.name!==""?settings.name:id+"-markdown-doc")}var appendElements=[!settings.readOnly?'':"",settings.saveHTMLToTextarea?'':"",'
                      ','
                      ','
                      '].join("\n");editor.append(appendElements).addClass(classPrefix+"vertical");if(settings.theme!==""){editor.addClass(classPrefix+"theme-"+settings.theme)}this.mask=editor.children("."+classPrefix+"mask");this.containerMask=editor.children("."+classPrefix+"container-mask");if(settings.markdown!==""){markdownTextarea.val(settings.markdown)}if(settings.appendMarkdown!==""){markdownTextarea.val(markdownTextarea.val()+settings.appendMarkdown)}this.htmlTextarea=editor.children("."+classNames.textarea.html);this.preview=editor.children("."+classPrefix+"preview");this.previewContainer=this.preview.children("."+classPrefix+"preview-container");if(settings.previewTheme!==""){this.preview.addClass(classPrefix+"preview-theme-"+settings.previewTheme)}if(typeof define==="function"&&define.amd){if(typeof katex!=="undefined"){editormd.$katex=katex}if(settings.searchReplace&&!settings.readOnly){editormd.loadCSS(settings.path+"codemirror/addon/dialog/dialog");editormd.loadCSS(settings.path+"codemirror/addon/search/matchesonscrollbar")}}if(typeof define==="function"&&define.amd||!settings.autoLoadModules){if(typeof CodeMirror!=="undefined"){editormd.$CodeMirror=CodeMirror}if(typeof marked!=="undefined"){editormd.$marked=marked}this.setCodeMirror().setToolbar().loadedDisplay()}else{this.loadQueues()}return this},loadQueues:function(){var _this=this;var settings=this.settings;var loadPath=settings.path;var isLoadedDisplay=false;var loadFlowChartOrSequenceDiagram=function(){if(editormd.isIE8){_this.loadedDisplay();return}if(settings.mermaid){editormd.loadScript(loadPath+"mermaid/mermaid.min",function(){window.mermaid.initialize({theme:"default",logLevel:3,securityLevel:"loose",flowchart:{curve:"basis"},gantt:{axisFormat:"%m/%d/%Y"},sequence:{actorMargin:50}});mermaid.ganttConfig={axisFormatter:[["%I:%M",function(d){return d.getHours()}],["%m/%d",function(d){return d.getDay()==1}],["%a %d",function(d){return d.getDay()&&d.getDate()!=1}],["%b %d",function(d){return d.getDate()!=1}],["%m-%y",function(d){return d.getMonth()}],["%m-%Y",function(){return d.getFullYear()}]]};if(!isLoadedDisplay){isLoadedDisplay=true;_this.loadedDisplay()}})}if(settings.flowChart){editormd.loadScript(loadPath+"raphael.min",function(){editormd.loadScript(loadPath+"flowchart.min",function(){editormd.loadScript(loadPath+"jquery.flowchart.min",function(){if(!isLoadedDisplay){isLoadedDisplay=true;_this.loadedDisplay()}})})})}if(settings.mindMap){editormd.loadScript(loadPath+"mindmap/transform.min",function(){editormd.loadScript(loadPath+"mindmap/d3@5",function(){editormd.loadScript(loadPath+"mindmap/view.min",function(){if(!isLoadedDisplay){isLoadedDisplay=true;_this.loadedDisplay()}})})})}if(settings.sequenceDiagram){editormd.loadCSS(loadPath+"sequence/sequence-diagram-min",function(){editormd.loadScript(loadPath+"sequence/webfont",function(){editormd.loadScript(loadPath+"sequence/snap.svg-min",function(){editormd.loadScript(loadPath+"sequence/underscore-min",function(){editormd.loadScript(loadPath+"sequence/sequence-diagram-min",function(){if(!isLoadedDisplay){isLoadedDisplay=true;_this.loadedDisplay()}})})})})})}else{_this.loadedDisplay()}};editormd.loadCSS(loadPath+"codemirror/codemirror.min");if(settings.searchReplace&&!settings.readOnly){editormd.loadCSS(loadPath+"codemirror/addon/dialog/dialog");editormd.loadCSS(loadPath+"codemirror/addon/search/matchesonscrollbar")}if(settings.codeFold){editormd.loadCSS(loadPath+"codemirror/addon/fold/foldgutter")}editormd.loadScript(loadPath+"codemirror/codemirror.min",function(){editormd.$CodeMirror=CodeMirror;editormd.loadScript(loadPath+"codemirror/modes.min",function(){editormd.loadScript(loadPath+"codemirror/addons.min",function(){_this.setCodeMirror();if(settings.mode!=="gfm"&&settings.mode!=="markdown"){_this.loadedDisplay();return false}_this.setToolbar();editormd.loadScript(loadPath+"marked",function(){editormd.$marked=marked;if(!settings.highlightStyle){settings.highlightStyle="github"}if(settings.previewCodeHighlight){editormd.loadCSS(loadPath+"highlight/styles/"+settings.highlightStyle);editormd.loadScript(loadPath+"highlight/highlight",function(){loadFlowChartOrSequenceDiagram()})}else{loadFlowChartOrSequenceDiagram()}})})})});return this},setTheme:function(theme){var editor=this.editor;var oldTheme=this.settings.theme;var themePrefix=this.classPrefix+"theme-";editor.removeClass(themePrefix+oldTheme).addClass(themePrefix+theme);this.settings.theme=theme;return this},setEditorTheme:function(theme){var settings=this.settings;settings.editorTheme=theme;if(theme!=="default"){editormd.loadCSS(settings.path+"codemirror/theme/"+settings.editorTheme)}this.cm.setOption("theme",theme);return this},setCodeMirrorTheme:function(theme){this.setEditorTheme(theme);return this},setPreviewTheme:function(theme){var preview=this.preview;var oldTheme=this.settings.previewTheme;var themePrefix=this.classPrefix+"preview-theme-";preview.removeClass(themePrefix+oldTheme).addClass(themePrefix+theme);this.settings.previewTheme=theme;return this},setCodeMirror:function(){var settings=this.settings;var editor=this.editor;if(settings.editorTheme!=="default"){editormd.loadCSS(settings.path+"codemirror/theme/"+settings.editorTheme)}var codeMirrorConfig={mode:settings.mode,theme:settings.editorTheme,tabSize:settings.tabSize,dragDrop:false,autofocus:settings.autoFocus,autoCloseTags:settings.autoCloseTags,readOnly:settings.readOnly?"nocursor":false,indentUnit:settings.indentUnit,lineNumbers:settings.lineNumbers,lineWrapping:settings.lineWrapping,extraKeys:{"Ctrl-Q":function(cm){cm.foldCode(cm.getCursor())}},foldGutter:settings.codeFold,gutters:["CodeMirror-linenumbers","CodeMirror-foldgutter"],matchBrackets:settings.matchBrackets,indentWithTabs:settings.indentWithTabs,styleActiveLine:settings.styleActiveLine,styleSelectedText:settings.styleSelectedText,autoCloseBrackets:settings.autoCloseBrackets,showTrailingSpace:settings.showTrailingSpace,highlightSelectionMatches:!settings.matchWordHighlight?false:{showToken:settings.matchWordHighlight==="onselected"?false:/\w/}};this.codeEditor=this.cm=editormd.$CodeMirror.fromTextArea(this.markdownTextarea[0],codeMirrorConfig);this.codeMirror=this.cmElement=editor.children(".CodeMirror");if(settings.value!==""){this.cm.setValue(settings.value)}this.codeMirror.css({fontSize:settings.fontSize,width:!settings.watch?"100%":"50%"});if(settings.autoHeight){this.codeMirror.css("height","auto");this.cm.setOption("viewportMargin",Infinity)}if(!settings.lineNumbers){this.codeMirror.find(".CodeMirror-gutters").css("border-right","none")}return this},getCodeMirrorOption:function(key){return this.cm.getOption(key)},setCodeMirrorOption:function(key,value){this.cm.setOption(key,value);return this},addKeyMap:function(map,bottom){this.cm.addKeyMap(map,bottom);return this},removeKeyMap:function(map){this.cm.removeKeyMap(map);return this},gotoLine:function(line){var settings=this.settings;if(!settings.gotoLine){return this}var cm=this.cm;var editor=this.editor;var count=cm.lineCount();var preview=this.preview;if(typeof line==="string"){if(line==="last"){line=count}if(line==="first"){line=1}}if(typeof line!=="number"){alert("Error: The line number must be an integer.");return this}line=parseInt(line)-1;if(line>count){alert("Error: The line number range 1-"+count);return this}cm.setCursor({line:line,ch:0});var scrollInfo=cm.getScrollInfo();var clientHeight=scrollInfo.clientHeight;var coords=cm.charCoords({line:line,ch:0},"local");cm.scrollTo(null,(coords.top+coords.bottom-clientHeight)/2);if(settings.watch){var cmScroll=this.codeMirror.find(".CodeMirror-scroll")[0];var height=$(cmScroll).height();var scrollTop=cmScroll.scrollTop;var percent=scrollTop/cmScroll.scrollHeight;if(scrollTop===0){preview.scrollTop(0)}else if(scrollTop+height>=cmScroll.scrollHeight-16){preview.scrollTop(preview[0].scrollHeight)}else{preview.scrollTop(preview[0].scrollHeight*percent)}}cm.focus();return this},extend:function(){if(typeof arguments[1]!=="undefined"){if(typeof arguments[1]==="function"){arguments[1]=$.proxy(arguments[1],this)}this[arguments[0]]=arguments[1]}if(typeof arguments[0]==="object"&&typeof arguments[0].length==="undefined"){$.extend(true,this,arguments[0])}return this},set:function(key,value){if(typeof value!=="undefined"&&typeof value==="function"){value=$.proxy(value,this)}this[key]=value;return this},config:function(key,value){var settings=this.settings;if(typeof key==="object"){settings=$.extend(true,settings,key)}if(typeof key==="string"){settings[key]=value}this.settings=settings;this.recreate();return this},on:function(eventType,callback){var settings=this.settings;if(typeof settings["on"+eventType]!=="undefined"){settings["on"+eventType]=$.proxy(callback,this)}return this},off:function(eventType){var settings=this.settings;if(typeof settings["on"+eventType]!=="undefined"){settings["on"+eventType]=function(){}}return this},showToolbar:function(callback){var settings=this.settings;if(settings.readOnly){return this}if(settings.toolbar&&(this.toolbar.length<1||this.toolbar.find("."+this.classPrefix+"menu").html()==="")){this.setToolbar()}settings.toolbar=true;this.toolbar.show();this.resize();$.proxy(callback||function(){},this)();return this},hideToolbar:function(callback){var settings=this.settings;settings.toolbar=false;this.toolbar.hide();this.resize();$.proxy(callback||function(){},this)();return this},setToolbarAutoFixed:function(fixed){var state=this.state;var editor=this.editor;var toolbar=this.toolbar;var settings=this.settings;if(typeof fixed!=="undefined"){settings.toolbarAutoFixed=fixed}var autoFixedHandle=function(){var $window=$(window);var top=$window.scrollTop();if(!settings.toolbarAutoFixed){return false}if(top-editor.offset().top>10&&top
                        ';editor.append(toolbarHTML);toolbar=this.toolbar=editor.children("."+classPrefix+"toolbar")}if(!settings.toolbar){toolbar.hide();return this}toolbar.show();var icons=typeof settings.toolbarIcons==="function"?settings.toolbarIcons():typeof settings.toolbarIcons==="string"?editormd.toolbarModes[settings.toolbarIcons]:settings.toolbarIcons;var toolbarMenu=toolbar.find("."+this.classPrefix+"menu"),menu="";var pullRight=false;for(var i=0,len=icons.length;i|'}else{var isHeader=/h(\d)/.test(name);var index=name;if(name==="watch"&&!settings.watch){index="unwatch"}var title=settings.lang.toolbar[index];var iconTexts=settings.toolbarIconTexts[index];var iconClass=settings.toolbarIconsClass[index];title=typeof title==="undefined"?"":title;iconTexts=typeof iconTexts==="undefined"?"":iconTexts;iconClass=typeof iconClass==="undefined"?"":iconClass;var menuItem=pullRight?'
                      • ':"
                      • ";if(typeof settings.toolbarCustomIcons[name]!=="undefined"&&typeof settings.toolbarCustomIcons[name]!=="function"){menuItem+=settings.toolbarCustomIcons[name]}else{menuItem+='';menuItem+=''+(isHeader?name.toUpperCase():iconClass===""?iconTexts:"")+"";menuItem+=""}menuItem+="
                      • ";menu=pullRight?menuItem+menu:menu+menuItem}}toolbarMenu.html(menu);toolbarMenu.find('[title="Lowercase"]').attr("title",settings.lang.toolbar.lowercase);toolbarMenu.find('[title="ucwords"]').attr("title",settings.lang.toolbar.ucwords);this.setToolbarHandler();this.setToolbarAutoFixed();return this},dialogLockScreen:function(){$.proxy(editormd.dialogLockScreen,this)();return this},dialogShowMask:function(dialog){$.proxy(editormd.dialogShowMask,this)(dialog);return this},getToolbarHandles:function(name){var toolbarHandlers=this.toolbarHandlers=editormd.toolbarHandlers;return name&&typeof toolbarIconHandlers[name]!=="undefined"?toolbarHandlers[name]:toolbarHandlers},setToolbarHandler:function(){var _this=this;var settings=this.settings;if(!settings.toolbar||settings.readOnly){return this}var toolbar=this.toolbar;var cm=this.cm;var classPrefix=this.classPrefix;var toolbarIcons=this.toolbarIcons=toolbar.find("."+classPrefix+"menu > li > a");var toolbarIconHandlers=this.getToolbarHandles();toolbarIcons.bind(editormd.mouseOrTouch("click","touchend"),function(event){var icon=$(this).children(".fa");var name=icon.attr("name");var cursor=cm.getCursor();var selection=cm.getSelection();if(name===""){return}_this.activeIcon=icon;if(typeof toolbarIconHandlers[name]!=="undefined"){$.proxy(toolbarIconHandlers[name],_this)(cm)}else{if(typeof settings.toolbarHandlers[name]!=="undefined"){$.proxy(settings.toolbarHandlers[name],_this)(cm,icon,cursor,selection)}}if(name!=="link"&&name!=="reference-link"&&name!=="image"&&name!=="code-block"&&name!=="preformatted-text"&&name!=="watch"&&name!=="preview"&&name!=="search"&&name!=="fullscreen"&&name!=="info"){cm.focus()}return false});return this},createDialog:function(options){return $.proxy(editormd.createDialog,this)(options)},createInfoDialog:function(){var _this=this;var editor=this.editor;var classPrefix=this.classPrefix;var infoDialogHTML=['
                        ','
                        ','

                        '+editormd.title+"v"+editormd.version+"

                        ","

                        "+this.lang.description+"

                        ",'

                        '+editormd.homePage+'

                        ','

                        Copyright © 2015 Pandao, The MIT License.

                        ',"
                        ",'',"
                        "].join("\n");editor.append(infoDialogHTML);var infoDialog=this.infoDialog=editor.children("."+classPrefix+"dialog-info");infoDialog.find("."+classPrefix+"dialog-close").bind(editormd.mouseOrTouch("click","touchend"),function(){_this.hideInfoDialog()});infoDialog.css("border",editormd.isIE8?"1px solid #ddd":"").css("z-index",editormd.dialogZindex).show();this.infoDialogPosition();return this},infoDialogPosition:function(){var infoDialog=this.infoDialog;var _infoDialogPosition=function(){infoDialog.css({top:($(window).height()-infoDialog.height())/2+"px",left:($(window).width()-infoDialog.width())/2+"px"})};_infoDialogPosition();$(window).resize(_infoDialogPosition);return this},showInfoDialog:function(){$("html,body").css("overflow-x","hidden");var _this=this;var editor=this.editor;var settings=this.settings;var infoDialog=this.infoDialog=editor.children("."+this.classPrefix+"dialog-info");if(infoDialog.length<1){this.createInfoDialog()}this.lockScreen(true);this.mask.css({opacity:settings.dialogMaskOpacity,backgroundColor:settings.dialogMaskBgColor}).show();infoDialog.css("z-index",editormd.dialogZindex).show();this.infoDialogPosition();return this},hideInfoDialog:function(){$("html,body").css("overflow-x","");this.infoDialog.hide();this.mask.hide();this.lockScreen(false);return this},lockScreen:function(lock){editormd.lockScreen(lock);this.resize();return this},recreate:function(){var _this=this;var editor=this.editor;var settings=this.settings;this.codeMirror.remove();this.setCodeMirror();if(!settings.readOnly){if(editor.find(".editormd-dialog").length>0){editor.find(".editormd-dialog").remove()}if(settings.toolbar){this.getToolbarHandles();this.setToolbar()}}this.loadedDisplay(true);return this},previewCodeHighlight:function(){var settings=this.settings;var previewContainer=this.previewContainer;if(settings.previewCodeHighlight){previewContainer.find("pre").each(function(i,block){hljs.highlightBlock(block)})}return this},katexRender:function(){if(timer===null){return this}this.previewContainer.find("."+editormd.classNames.tex).each(function(){var tex=$(this);editormd.$katex.render(tex.text(),tex[0]);tex.find(".katex").css("font-size","1.6em")});return this},mindmapRender:function(){this.previewContainer.find(".mindmap").each(function(){var mmap=$(this);var md_data=window.markmap.transform(mmap.text().trim());window.markmap.markmap("svg#"+this.id,md_data)});return this},flowChartAndSequenceDiagramRender:function(){var $this=this;var settings=this.settings;var previewContainer=this.previewContainer;if(editormd.isIE8){return this}if(settings.mermaid){var mermaid=previewContainer.find(".lang-mermaid");if(mermaid){try{window.mermaid.init(void 0,mermaid.removeClass("hide"))}catch(e){console.log(e)}}}if(settings.flowChart){if(flowchartTimer===null){return this}try{previewContainer.find(".flowchart").flowChart()}catch(e){console.log(e)}}if(settings.sequenceDiagram){try{previewContainer.find(".sequence-diagram").sequenceDiagram({theme:"simple"})}catch(e){console.log(e)}}var preview=$this.preview;var codeMirror=$this.codeMirror;var codeView=codeMirror.find(".CodeMirror-scroll");var height=codeView.height();var scrollTop=codeView.scrollTop();var percent=scrollTop/codeView[0].scrollHeight;var tocHeight=0;preview.find(".markdown-toc-list").each(function(){tocHeight+=$(this).height()});var tocMenuHeight=preview.find(".editormd-toc-menu").height();tocMenuHeight=!tocMenuHeight?0:tocMenuHeight;if(scrollTop===0){preview.scrollTop(0)}else if(scrollTop+height>=codeView[0].scrollHeight-16){preview.scrollTop(preview[0].scrollHeight)}else{preview.scrollTop((preview[0].scrollHeight+tocHeight+tocMenuHeight)*percent)}return this},registerKeyMaps:function(keyMap){var _this=this;var cm=this.cm;var settings=this.settings;var toolbarHandlers=editormd.toolbarHandlers;var disabledKeyMaps=settings.disabledKeyMaps;keyMap=keyMap||null;if(keyMap){for(var i in keyMap){if($.inArray(i,disabledKeyMaps)<0){var map={};map[i]=keyMap[i];cm.addKeyMap(keyMap)}}}else{for(var k in editormd.keyMaps){var _keyMap=editormd.keyMaps[k];var handle=typeof _keyMap==="string"?$.proxy(toolbarHandlers[_keyMap],_this):$.proxy(_keyMap,_this);if($.inArray(k,["F9","F10","F11"])<0&&$.inArray(k,disabledKeyMaps)<0){var _map={};_map[k]=handle;cm.addKeyMap(_map)}}$(window).keydown(function(event){var keymaps={120:"F9",121:"F10",122:"F11"};if($.inArray(keymaps[event.keyCode],disabledKeyMaps)<0){switch(event.keyCode){case 120:$.proxy(toolbarHandlers["watch"],_this)();return false;break;case 121:$.proxy(toolbarHandlers["preview"],_this)();return false;break;case 122:$.proxy(toolbarHandlers["fullscreen"],_this)();return false;break;default:break}}})}return this},bindScrollEvent:function(){var _this=this;var preview=this.preview;var settings=this.settings;var codeMirror=this.codeMirror;var mouseOrTouch=editormd.mouseOrTouch;if(!settings.syncScrolling){return this}var cmBindScroll=function(){codeMirror.find(".CodeMirror-scroll").bind(mouseOrTouch("scroll","touchmove"),function(event){var height=$(this).height();var scrollTop=$(this).scrollTop();var percent=scrollTop/$(this)[0].scrollHeight;var tocHeight=0;preview.find(".markdown-toc-list").each(function(){tocHeight+=$(this).height()});var tocMenuHeight=preview.find(".editormd-toc-menu").height();tocMenuHeight=!tocMenuHeight?0:tocMenuHeight;if(scrollTop===0){preview.scrollTop(0)}else if(scrollTop+height>=$(this)[0].scrollHeight-16){preview.scrollTop(preview[0].scrollHeight)}else{preview.scrollTop((preview[0].scrollHeight+tocHeight+tocMenuHeight)*percent)}$.proxy(settings.onscroll,_this)(event)})};var cmUnbindScroll=function(){codeMirror.find(".CodeMirror-scroll").unbind(mouseOrTouch("scroll","touchmove"))};var previewBindScroll=function(){preview.bind(mouseOrTouch("scroll","touchmove"),function(event){var height=$(this).height();var scrollTop=$(this).scrollTop();var percent=scrollTop/$(this)[0].scrollHeight;var codeView=codeMirror.find(".CodeMirror-scroll");if(scrollTop===0){codeView.scrollTop(0)}else if(scrollTop+height>=$(this)[0].scrollHeight){codeView.scrollTop(codeView[0].scrollHeight)}else{codeView.scrollTop(codeView[0].scrollHeight*percent)}$.proxy(settings.onpreviewscroll,_this)(event)})};var previewUnbindScroll=function(){preview.unbind(mouseOrTouch("scroll","touchmove"))};codeMirror.bind({mouseover:cmBindScroll,mouseout:cmUnbindScroll,touchstart:cmBindScroll,touchend:cmUnbindScroll});if(settings.syncScrolling==="single"){return this}preview.bind({mouseover:previewBindScroll,mouseout:previewUnbindScroll,touchstart:previewBindScroll,touchend:previewUnbindScroll});return this},bindChangeEvent:function(){var _this=this;var cm=this.cm;var settings=this.settings;if(!settings.syncScrolling){return this}cm.on("change",function(_cm,changeObj){if(settings.watch){_this.previewContainer.css("padding",settings.autoHeight?"20px 20px 50px 40px":"20px")}timer=setTimeout(function(){clearTimeout(timer);_this.save();timer=null},settings.delay)});return this},loadedDisplay:function(recreate){recreate=recreate||false;var _this=this;var editor=this.editor;var preview=this.preview;var settings=this.settings;this.containerMask.hide();this.save();if(settings.watch){preview.show()}editor.data("oldWidth",editor.width()).data("oldHeight",editor.height());this.resize();this.registerKeyMaps();$(window).resize(function(){_this.resize()});this.bindScrollEvent().bindChangeEvent();if(!recreate){$.proxy(settings.onload,this)()}this.state.loaded=true;return this},width:function(width){this.editor.css("width",typeof width==="number"?width+"px":width);this.resize();return this},height:function(height){this.editor.css("height",typeof height==="number"?height+"px":height);this.resize();return this},resize:function(width,height){width=width||null;height=height||null;var state=this.state;var editor=this.editor;var preview=this.preview;var toolbar=this.toolbar;var settings=this.settings;var codeMirror=this.codeMirror;if(width){editor.css("width",typeof width==="number"?width+"px":width)}if(settings.autoHeight&&!state.fullscreen&&!state.preview){editor.css("height","auto");codeMirror.css("height","auto")}else{if(height){editor.css("height",typeof height==="number"?height+"px":height)}if(state.fullscreen){editor.height($(window).height())}if(settings.toolbar&&!settings.readOnly){codeMirror.css("margin-top",toolbar.height()+1).height(editor.height()-toolbar.height())}else{codeMirror.css("margin-top",0).height(editor.height())}}if(settings.watch){codeMirror.width(editor.width()/2);preview.width(!state.preview?editor.width()/2:editor.width());this.previewContainer.css("padding",settings.autoHeight?"20px 20px 50px 40px":"20px");if(settings.toolbar&&!settings.readOnly){preview.css("top",toolbar.height()+1)}else{preview.css("top",0)}if(settings.autoHeight&&!state.fullscreen&&!state.preview){preview.height("")}else{var previewHeight=settings.toolbar&&!settings.readOnly?editor.height()-toolbar.height():editor.height();preview.height(previewHeight)}}else{codeMirror.width(editor.width());preview.hide()}if(state.loaded){$.proxy(settings.onresize,this)()}return this},save:function(){if(timer===null){return this}var _this=this;var state=this.state;var settings=this.settings;var cm=this.cm;var cmValue=cm.getValue();var previewContainer=this.previewContainer;if(settings.mode!=="gfm"&&settings.mode!=="markdown"){this.markdownTextarea.val(cmValue);return this}var marked=editormd.$marked;var markdownToC=this.markdownToC=[];var rendererOptions=this.markedRendererOptions={toc:settings.toc,tocm:settings.tocm,tocStartLevel:settings.tocStartLevel,pageBreak:settings.pageBreak,taskList:settings.taskList,emoji:settings.emoji,tex:settings.tex,atLink:settings.atLink,emailLink:settings.emailLink,flowChart:settings.flowChart,sequenceDiagram:settings.sequenceDiagram,previewCodeHighlight:settings.previewCodeHighlight,mermaid:settings.mermaid,mindMap:settings.mindMap};var markedOptions=this.markedOptions={renderer:editormd.markedRenderer(markdownToC,rendererOptions),gfm:true,tables:true,breaks:true,pedantic:false,sanitize:settings.htmlDecode?false:true,smartLists:true,smartypants:true};marked.setOptions(markedOptions);var newMarkdownDoc=editormd.$marked(cmValue,markedOptions);if(settings.debug){console.info("cmValue",cmValue,newMarkdownDoc)}newMarkdownDoc=editormd.filterHTMLTags(newMarkdownDoc,settings.htmlDecode);this.markdownTextarea.text(cmValue);cm.save();if(settings.saveHTMLToTextarea){this.htmlTextarea.text(newMarkdownDoc)}if(settings.watch||!settings.watch&&state.preview){previewContainer.html(newMarkdownDoc);this.previewCodeHighlight();if(settings.toc){var tocContainer=settings.tocContainer===""?previewContainer:$(settings.tocContainer);var tocMenu=tocContainer.find("."+this.classPrefix+"toc-menu");tocContainer.attr("previewContainer",settings.tocContainer===""?"true":"false");if(settings.tocContainer!==""&&tocMenu.length>0){tocMenu.remove()}editormd.markdownToCRenderer(markdownToC,tocContainer,settings.tocDropdown,settings.tocStartLevel);if(settings.tocDropdown||tocContainer.find("."+this.classPrefix+"toc-menu").length>0){editormd.tocDropdownMenu(tocContainer,settings.tocTitle!==""?settings.tocTitle:this.lang.tocTitle)}if(settings.tocContainer!==""){previewContainer.find(".markdown-toc").css("border","none")}}if(settings.tex){if(!editormd.kaTeXLoaded&&settings.autoLoadModules){editormd.loadKaTeX(function(){editormd.$katex=katex;editormd.kaTeXLoaded=true;_this.katexRender()})}else{editormd.$katex=katex;this.katexRender()}}if(settings.mindMap){setTimeout(function(){_this.mindmapRender()},10)}if(settings.flowChart||settings.sequenceDiagram||settings.mermaid){flowchartTimer=setTimeout(function(){clearTimeout(flowchartTimer);_this.flowChartAndSequenceDiagramRender();flowchartTimer=null},10)}if(state.loaded){$.proxy(settings.onchange,this)()}}return this},focus:function(){this.cm.focus();return this},setCursor:function(cursor){this.cm.setCursor(cursor);return this},getCursor:function(){return this.cm.getCursor()},setSelection:function(from,to){this.cm.setSelection(from,to);return this},getSelection:function(){return this.cm.getSelection()},setSelections:function(ranges){this.cm.setSelections(ranges);return this},getSelections:function(){return this.cm.getSelections()},replaceSelection:function(value){this.cm.replaceSelection(value);return this},insertValue:function(value){this.replaceSelection(value);return this},appendMarkdown:function(md){var settings=this.settings;var cm=this.cm;cm.setValue(cm.getValue()+md);return this},setMarkdown:function(md){this.cm.setValue(md||this.settings.markdown);return this},getMarkdown:function(){return this.cm.getValue()},getValue:function(){return this.cm.getValue()},setValue:function(value){this.cm.setValue(value);return this},clear:function(){this.cm.setValue("");return this},getHTML:function(){if(!this.settings.saveHTMLToTextarea){alert("Error: settings.saveHTMLToTextarea == false");return false}return this.htmlTextarea.val()},getTextareaSavedHTML:function(){return this.getHTML()},getPreviewedHTML:function(){if(!this.settings.watch){alert("Error: settings.watch == false");return false}return this.previewContainer.html()},watch:function(callback){var settings=this.settings;if($.inArray(settings.mode,["gfm","markdown"])<0){return this}this.state.watching=settings.watch=true;this.preview.show();if(this.toolbar){var watchIcon=settings.toolbarIconsClass.watch;var unWatchIcon=settings.toolbarIconsClass.unwatch;var icon=this.toolbar.find(".fa[name=watch]");icon.parent().attr("title",settings.lang.toolbar.watch);icon.removeClass(unWatchIcon).addClass(watchIcon)}this.codeMirror.css("border-right","1px solid #ddd").width(this.editor.width()/2);timer=0;this.save().resize();if(!settings.onwatch){settings.onwatch=callback||function(){}}$.proxy(settings.onwatch,this)();return this},unwatch:function(callback){var settings=this.settings;this.state.watching=settings.watch=false;this.preview.hide();if(this.toolbar){var watchIcon=settings.toolbarIconsClass.watch;var unWatchIcon=settings.toolbarIconsClass.unwatch;var icon=this.toolbar.find(".fa[name=watch]");icon.parent().attr("title",settings.lang.toolbar.unwatch);icon.removeClass(watchIcon).addClass(unWatchIcon)}this.codeMirror.css("border-right","none").width(this.editor.width());this.resize();if(!settings.onunwatch){settings.onunwatch=callback||function(){}}$.proxy(settings.onunwatch,this)();return this},show:function(callback){callback=callback||function(){};var _this=this;this.editor.show(0,function(){$.proxy(callback,_this)()});return this},hide:function(callback){callback=callback||function(){};var _this=this;this.editor.hide(0,function(){$.proxy(callback,_this)()});return this},previewing:function(){var _this=this;var editor=this.editor;var preview=this.preview;var toolbar=this.toolbar;var settings=this.settings;var codeMirror=this.codeMirror;var previewContainer=this.previewContainer;if($.inArray(settings.mode,["gfm","markdown"])<0){return this}if(settings.toolbar&&toolbar){toolbar.toggle();toolbar.find(".fa[name=preview]").toggleClass("active")}codeMirror.toggle();var escHandle=function(event){if(event.shiftKey&&event.keyCode===27){_this.previewed()}};if(codeMirror.css("display")==="none"){this.state.preview=true;if(this.state.fullscreen){preview.css("background","#fff")}editor.find("."+this.classPrefix+"preview-close-btn").show().bind(editormd.mouseOrTouch("click","touchend"),function(){_this.previewed()});if(!settings.watch){this.save()}else{previewContainer.css("padding","")}previewContainer.addClass(this.classPrefix+"preview-active");preview.show().css({position:"",top:0,width:editor.width(),height:settings.autoHeight&&!this.state.fullscreen?"auto":editor.height()});if(this.state.loaded){$.proxy(settings.onpreviewing,this)()}$(window).bind("keyup",escHandle)}else{$(window).unbind("keyup",escHandle);this.previewed()}},previewed:function(){var editor=this.editor;var preview=this.preview;var toolbar=this.toolbar;var settings=this.settings;var previewContainer=this.previewContainer;var previewCloseBtn=editor.find("."+this.classPrefix+"preview-close-btn");this.state.preview=false;this.codeMirror.show();if(settings.toolbar){toolbar.show()}preview[settings.watch?"show":"hide"]();previewCloseBtn.hide().unbind(editormd.mouseOrTouch("click","touchend"));previewContainer.removeClass(this.classPrefix+"preview-active");if(settings.watch){previewContainer.css("padding","20px")}preview.css({background:null,position:"absolute",width:editor.width()/2,height:settings.autoHeight&&!this.state.fullscreen?"auto":editor.height()-toolbar.height(),top:settings.toolbar?toolbar.height():0});if(this.state.loaded){$.proxy(settings.onpreviewed,this)()}return this},fullscreen:function(){var _this=this;var state=this.state;var editor=this.editor;var preview=this.preview;var toolbar=this.toolbar;var settings=this.settings;var fullscreenClass=this.classPrefix+"fullscreen";if(toolbar){toolbar.find(".fa[name=fullscreen]").parent().toggleClass("active")}var escHandle=function(event){if(!event.shiftKey&&event.keyCode===27){if(state.fullscreen){_this.fullscreenExit()}}};if(!editor.hasClass(fullscreenClass)){state.fullscreen=true;$("html,body").css("overflow","hidden");editor.css({width:$(window).width(),height:$(window).height()}).addClass(fullscreenClass);this.resize();$.proxy(settings.onfullscreen,this)();$(window).bind("keyup",escHandle)}else{$(window).unbind("keyup",escHandle);this.fullscreenExit()}return this},fullscreenExit:function(){var editor=this.editor;var settings=this.settings;var toolbar=this.toolbar;var fullscreenClass=this.classPrefix+"fullscreen";this.state.fullscreen=false;if(toolbar){toolbar.find(".fa[name=fullscreen]").parent().removeClass("active")}$("html,body").css("overflow","");editor.css({width:editor.data("oldWidth"),height:editor.data("oldHeight")}).removeClass(fullscreenClass);this.resize();$.proxy(settings.onfullscreenExit,this)();return this},executePlugin:function(name,path){var _this=this;var cm=this.cm;var settings=this.settings;path=settings.pluginPath+path;if(typeof define==="function"){if(typeof this[name]==="undefined"){alert("Error: "+name+" plugin is not found, you are not load this plugin.");return this}this[name](cm);return this}if($.inArray(path,editormd.loadFiles.plugin)<0){editormd.loadPlugin(path,function(){editormd.loadPlugins[name]=_this[name];_this[name](cm)})}else{$.proxy(editormd.loadPlugins[name],this)(cm)}return this},search:function(command){var settings=this.settings;if(!settings.searchReplace){alert("Error: settings.searchReplace == false");return this}if(!settings.readOnly){this.cm.execCommand(command||"find")}return this},searchReplace:function(){this.search("replace");return this},searchReplaceAll:function(){this.search("replaceAll");return this}};editormd.fn.init.prototype=editormd.fn;editormd.dialogLockScreen=function(){var settings=this.settings||{dialogLockScreen:true};if(settings.dialogLockScreen){$("html,body").css("overflow","hidden");this.resize()}};editormd.dialogShowMask=function(dialog){var editor=this.editor;var settings=this.settings||{dialogShowMask:true};dialog.css({top:($(window).height()-dialog.height())/2+"px",left:($(window).width()-dialog.width())/2+"px"});if(settings.dialogShowMask){editor.children("."+this.classPrefix+"mask").css("z-index",parseInt(dialog.css("z-index"))-1).show()}};editormd.toolbarHandlers={undo:function(){this.cm.undo()},redo:function(){this.cm.redo()},bold:function(){var cm=this.cm;var cursor=cm.getCursor();var selection=cm.getSelection();cm.replaceSelection("**"+selection+"**");if(selection===""){cm.setCursor(cursor.line,cursor.ch+2)}},del:function(){var cm=this.cm;var cursor=cm.getCursor();var selection=cm.getSelection();cm.replaceSelection("~~"+selection+"~~");if(selection===""){cm.setCursor(cursor.line,cursor.ch+2)}},italic:function(){var cm=this.cm;var cursor=cm.getCursor();var selection=cm.getSelection();cm.replaceSelection("*"+selection+"*");if(selection===""){cm.setCursor(cursor.line,cursor.ch+1)}},quote:function(){var cm=this.cm;var cursor=cm.getCursor();var selection=cm.getSelection();if(cursor.ch!==0){cm.setCursor(cursor.line,0);cm.replaceSelection("> "+selection);cm.setCursor(cursor.line,cursor.ch+2)}else{cm.replaceSelection("> "+selection)}},ucfirst:function(){var cm=this.cm;var selection=cm.getSelection();var selections=cm.listSelections();cm.replaceSelection(editormd.firstUpperCase(selection));cm.setSelections(selections)},ucwords:function(){var cm=this.cm;var selection=cm.getSelection();var selections=cm.listSelections();cm.replaceSelection(editormd.wordsFirstUpperCase(selection));cm.setSelections(selections)},uppercase:function(){var cm=this.cm;var selection=cm.getSelection();var selections=cm.listSelections();cm.replaceSelection(selection.toUpperCase());cm.setSelections(selections)},lowercase:function(){var cm=this.cm;var cursor=cm.getCursor();var selection=cm.getSelection();var selections=cm.listSelections();cm.replaceSelection(selection.toLowerCase());cm.setSelections(selections)},h1:function(){var cm=this.cm;var cursor=cm.getCursor();var selection=cm.getLine(cursor.line);var patt1=new RegExp("^#{1}[ ]");var patt2=new RegExp("^#{1,6}[ ]");if(patt1.test(selection)===true){selection=selection.replace(/^#{1}[ ]/,"");cm.setSelection({line:cursor.line,ch:0},{line:cursor.line+1,ch:0});cm.replaceSelection(selection+"\n");cm.setCursor(cursor.line,cursor.ch-2)}else if(patt2.test(selection)===true){selection=selection.replace(/^#{1,6}[ ]/,"");cm.setSelection({line:cursor.line,ch:0},{line:cursor.line+1,ch:0});cm.replaceSelection("# "+selection+"\n");cm.setCursor(cursor.line,cursor.ch+2)}else{cm.setSelection({line:cursor.line,ch:0},{line:cursor.line+1,ch:0});cm.replaceSelection("# "+selection+"\n");cm.setCursor(cursor.line,cursor.ch+2)}},h2:function(){var cm=this.cm;var cursor=cm.getCursor();var selection=cm.getLine(cursor.line);var patt1=new RegExp("^#{2}[ ]");var patt2=new RegExp("^#{1,6}[ ]");if(patt1.test(selection)===true){selection=selection.replace(/^#{2}[ ]/,"");cm.setSelection({line:cursor.line,ch:0},{line:cursor.line+1,ch:0});cm.replaceSelection(selection+"\n");cm.setCursor(cursor.line,cursor.ch-3)}else if(patt2.test(selection)===true){selection=selection.replace(/^#{1,6}[ ]/,"");cm.setSelection({line:cursor.line,ch:0},{line:cursor.line+1,ch:0});cm.replaceSelection("## "+selection+"\n");cm.setCursor(cursor.line,cursor.ch+3)}else{cm.setSelection({line:cursor.line,ch:0},{line:cursor.line+1,ch:0});cm.replaceSelection("## "+selection+"\n");cm.setCursor(cursor.line,cursor.ch+3)}},h3:function(){var cm=this.cm;var cursor=cm.getCursor();var selection=cm.getLine(cursor.line);var patt1=new RegExp("^#{3}[ ]");var patt2=new RegExp("^#{1,6}[ ]");if(patt1.test(selection)===true){selection=selection.replace(/^#{3}[ ]/,"");cm.setSelection({line:cursor.line,ch:0},{line:cursor.line+1,ch:0});cm.replaceSelection(selection+"\n");cm.setCursor(cursor.line,cursor.ch-4)}else if(patt2.test(selection)===true){selection=selection.replace(/^#{1,6}[ ]/,"");cm.setSelection({line:cursor.line,ch:0},{line:cursor.line+1,ch:0});cm.replaceSelection("### "+selection+"\n");cm.setCursor(cursor.line,cursor.ch+4)}else{cm.setSelection({line:cursor.line,ch:0},{line:cursor.line+1,ch:0});cm.replaceSelection("### "+selection+"\n");cm.setCursor(cursor.line,cursor.ch+4)}},h4:function(){var cm=this.cm;var cursor=cm.getCursor();var selection=cm.getLine(cursor.line);var patt1=new RegExp("^#{4}[ ]");var patt2=new RegExp("^#{1,6}[ ]");if(patt1.test(selection)===true){selection=selection.replace(/^#{4}[ ]/,"");cm.setSelection({line:cursor.line,ch:0},{line:cursor.line+1,ch:0});cm.replaceSelection(selection+"\n");cm.setCursor(cursor.line,cursor.ch-5)}else if(patt2.test(selection)===true){selection=selection.replace(/^#{1,6}[ ]/,"");cm.setSelection({line:cursor.line,ch:0},{line:cursor.line+1,ch:0});cm.replaceSelection("#### "+selection+"\n");cm.setCursor(cursor.line,cursor.ch+5)}else{cm.setSelection({line:cursor.line,ch:0},{line:cursor.line+1,ch:0});cm.replaceSelection("#### "+selection+"\n");cm.setCursor(cursor.line,cursor.ch+5)}},h5:function(){var cm=this.cm;var cursor=cm.getCursor();var selection=cm.getLine(cursor.line);var patt1=new RegExp("^#{5}[ ]");var patt2=new RegExp("^#{1,6}[ ]");if(patt1.test(selection)===true){selection=selection.replace(/^#{5}[ ]/,"");cm.setSelection({line:cursor.line,ch:0},{line:cursor.line+1,ch:0});cm.replaceSelection(selection+"\n");cm.setCursor(cursor.line,cursor.ch-6)}else if(patt2.test(selection)===true){selection=selection.replace(/^#{1,6}[ ]/,"");cm.setSelection({line:cursor.line,ch:0},{line:cursor.line+1,ch:0});cm.replaceSelection("##### "+selection+"\n");cm.setCursor(cursor.line,cursor.ch+6)}else{cm.setSelection({line:cursor.line,ch:0},{line:cursor.line+1,ch:0});cm.replaceSelection("##### "+selection+"\n");cm.setCursor(cursor.line,cursor.ch+6)}},h6:function(){var cm=this.cm;var cursor=cm.getCursor();var selection=cm.getLine(cursor.line);var patt1=new RegExp("^#{6}[ ]");var patt2=new RegExp("^#{1,6}[ ]");if(patt1.test(selection)===true){selection=selection.replace(/^#{6}[ ]/,"");cm.setSelection({line:cursor.line,ch:0},{line:cursor.line+1,ch:0});cm.replaceSelection(selection+"\n");cm.setCursor(cursor.line,cursor.ch-7)}else if(patt2.test(selection)===true){selection=selection.replace(/^#{1,6}[ ]/,"");cm.setSelection({line:cursor.line,ch:0},{line:cursor.line+1,ch:0});cm.replaceSelection("###### "+selection+"\n");cm.setCursor(cursor.line,cursor.ch+7)}else{cm.setSelection({line:cursor.line,ch:0},{line:cursor.line+1,ch:0});cm.replaceSelection("###### "+selection+"\n");cm.setCursor(cursor.line,cursor.ch+7)}},"list-ul":function(){var cm=this.cm;var cursor=cm.getCursor();var selection=cm.getSelection();var patt1=new RegExp("^-{1}[ ]");var cnt=0;if(selection===""){cm.setCursor(cursor.line,0);cm.replaceSelection("- "+selection);cm.setCursor(cursor.line,cursor.ch+2)}else{var selectionText=selection.split("\n");for(var i=0,len=selectionText.length;i/i);if(ps!==null){quoteBegin=ps[0];$quote=$quote.substr(quoteBegin.length)}var $class="default";if($quote.indexOf("[info]")===0){$class="info";$quote=$quote.substr(6)}else if($quote.indexOf("[warning]")===0){$class="warning";$quote=$quote.substr(9)}else if($quote.indexOf("[success]")===0){$class="success";$quote=$quote.substr(9)}else if($quote.indexOf("[danger]")===0){$class="danger";$quote=$quote.substr(8)}return'
                        \n'+quoteBegin+$quote+"
                        \n"};markedRenderer.image=function(href,title,text){var attr="";var begin="";var end="";if(href&&href!==""){var a=document.createElement("a");a.href=href;var attrs=a.hash.match(/size=\d+x\d+/i);if(attrs!==null){a.hash=a.hash.replace(attrs[0],"");href=a.href;attrs=attrs[0].replace("size=","").split("x");if(attrs[0]>0){attr+=' width="'+attrs[0]+'"'}if(attrs[1]>0){attr+=' height="'+attrs[1]+'"'}}attrs=a.hash.match(/align=(center|left|right)/i);if(attrs!==null){var hash=a.hash.replace(attrs[0],"");if(hash.indexOf("#&")===0){hash="#"+hash.substr(2)}a.hash=hash;href=a.href;attrs=attrs[0].replace("align=","");end="

                        ";if(attrs==="center"){begin='

                        '}else if(attrs==="left"){begin='

                        '}else if(attrs==="right"){begin='

                        '}}}return begin+''+text+'"+end};markedRenderer.emoji=function(text){text=text.replace(editormd.regexs.emojiDatetime,function($1){return $1.replace(/:/g,":")});var matchs=text.match(emojiReg);if(!matchs||!settings.emoji){return text}for(var i=0,len=matchs.length;i'}}else{var emdlogoMathcs=$1.match(editormdLogoReg);var twemojiMatchs=$1.match(twemojiReg);if(emdlogoMathcs){for(var x=0,len2=emdlogoMathcs.length;x'}}else if(twemojiMatchs){for(var t=0,len3=twemojiMatchs.length;t'}}else{var src=name==="+1"?"plus1":name;src=src==="black_large_square"?"black_square":src;src=src==="moon"?"waxing_gibbous_moon":src;return':'+name+':'}}})}return text};markedRenderer.atLink=function(text){if(atLinkReg.test(text)){if(settings.atLink){text=text.replace(emailReg,function($1,$2,$3,$4){return $1.replace(/@/g,"_#_@_#_")});text=text.replace(atLinkReg,function($1,$2){return''+$1+""}).replace(/_#_@_#_/g,"@")}if(settings.emailLink){text=text.replace(emailLinkReg,function($1,$2,$3,$4,$5){return!$2&&$.inArray($5,"jpg|jpeg|png|gif|webp|ico|icon|pdf".split("|"))<0?''+$1+"":$1})}return text}return text};markedRenderer.link=function(href,title,text){if(this.options.sanitize){try{var prot=decodeURIComponent(unescape(href)).replace(/[^\w:]/g,"").toLowerCase()}catch(e){return""}if(prot.indexOf("javascript:")===0){return""}}if(href.indexOf("@")===0){return''}var out=''+text.replace(/@/g,"@")+""}if(title){out+=' title="'+title+'"'}out+=">"+text+"";return out};markedRenderer.heading=function(text,level,raw){var linkText=text;var hasLinkReg=/\s*\]*)\>(.*)\<\/a\>\s*/;var getLinkTextReg=/\s*\]+)\>([^\>]*)\<\/a\>\s*/g;if(hasLinkReg.test(text)){var tempText=[];text=text.split(/\]+)\>([^\>]*)\<\/a\>/);for(var i=0,len=text.length;i';headingHTML+='';headingHTML+='';headingHTML+=hasLinkReg?this.atLink(this.emoji(linkText)):this.atLink(this.emoji(text));headingHTML+="";return headingHTML};markedRenderer.pageBreak=function(text){if(pageBreakReg.test(text)&&settings.pageBreak){text='


                        '}return text};markedRenderer.paragraph=function(text){var isTeXInline=/\$\$(.*)\$\$/g.test(text);var isTeXLine=/^\$\$(.*)\$\$$/.test(text);var isTeXAddClass=isTeXLine?' class="'+editormd.classNames.tex+'"':' class="line"';var isToC=settings.tocm?/^(\[TOC\]|\[TOCM\])$/.test(text):/^\[TOC\]$/.test(text);var isToCMenu=/^\[TOCM\]$/.test(text);if(!isTeXLine&&isTeXInline){text=text.replace(/(\$\$([^\$]*)\$\$)+/g,function($1,$2){return''+$2.replace(/\$/g,"")+""})}else{text=isTeXLine?text.replace(/\$/g,""):text}var tocHTML='
                        '+text+"
                        ";return isToC?isToCMenu?'
                        '+tocHTML+"

                        ":tocHTML:pageBreakReg.test(text)?this.pageBreak(text):""+this.atLink(this.emoji(text))+"

                        \n"};markedRenderer.code=function(code,lang,escaped){if(lang==="seq"||lang==="sequence"){return'
                        '+code+"
                        "}else if(lang==="mermaid"){var $chars="ABCDEFGHJKLMNOPQRSTUVWXYZabcdefhijlkmnopqrstuvwxyz012345678";var maxPos=$chars.length;var id="";for(var i=0;i<4;i++){id+=$chars.charAt(Math.floor(Math.random()*maxPos))}return'
                        '+code+"
                        "}else if(lang==="flow"){return'
                        '+code+"
                        "}else if(lang==="math"||lang==="latex"||lang==="katex"){return'

                        '+code+"

                        "}else if(/^mindmap/i.test(lang)){var len=9||32;var $chars="ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";var maxPos=$chars.length;var map_id="";var custom_height;var h=lang.split(">")[1];if(h!=undefined){custom_height=h}else{custom_height=150}for(var i=0;i"+code+""}else{return marked.Renderer.prototype.code.apply(this,arguments)}};markedRenderer.tablecell=function(content,flags){var type=flags.header?"th":"td";var tag=flags.align?"<"+type+' style="text-align:'+flags.align+'">':"<"+type+">";return tag+this.atLink(this.emoji(content))+"\n"};markedRenderer.listitem=function(text){if(settings.taskList&&/^\s*\[[x\s]\]\s*/.test(text)){text=text.replace(/^\s*\[\s\]\s*/,' ').replace(/^\s*\[x\]\s*/,' ');return'
                      • '+this.atLink(this.emoji(text))+"
                      • "}else{return"
                      • "+this.atLink(this.emoji(text))+"
                      • "}};markedRenderer.checkbox=function(checked){return checked?' ':' '};return markedRenderer};editormd.markdownToCRenderer=function(toc,container,tocDropdown,startLevel){var html="";var lastLevel=0;var classPrefix=this.classPrefix;startLevel=startLevel||1;for(var i=0,len=toc.length;ilastLevel){html+=""}else if(level'+text+"";lastLevel=level}console.log(html);var tocContainer=container.find(".markdown-toc");if(tocContainer.length<1&&container.attr("previewContainer")==="false"){var tocHTML='
                        ';tocHTML=tocDropdown?'
                        '+tocHTML+"
                        ":tocHTML;container.html(tocHTML);tocContainer=container.find(".markdown-toc")}if(tocDropdown){tocContainer.wrap('

                        ')}tocContainer.html('
                          ').children(".markdown-toc-list").html(html.replace(/\r?\n?\\<\/ul\>/g,""));return tocContainer};editormd.tocDropdownMenu=function(container,tocTitle){tocTitle=tocTitle||"Table of Contents";var zindex=400;var tocMenus=container.find("."+this.classPrefix+"toc-menu");tocMenus.each(function(){var $this=$(this);var toc=$this.children(".markdown-toc");var icon='';var btn=''+icon+tocTitle+"";var menu=toc.children("ul");var list=menu.find("li");toc.append(btn);list.first().before("
                        • "+tocTitle+" "+icon+"

                        • ");$this.mouseover(function(){menu.show();list.each(function(){var li=$(this);var ul=li.children("ul");if(ul.html()===""){ul.remove()}if(ul.length>0&&ul.html()!==""){var firstA=li.children("a").first();if(firstA.children(".fa").length<1){firstA.append($(icon).css({float:"right",paddingTop:"4px"}))}}li.mouseover(function(){ul.css("z-index",zindex).show();zindex+=1}).mouseleave(function(){ul.hide()})})}).mouseleave(function(){menu.hide()})});return tocMenus};editormd.filterHTMLTags=function(html,filters){if(typeof html!=="string"){html=new String(html)}if(typeof filters!=="string"){return html}var expression=filters.split("|");var filterTags=expression[0].split(",");var attrs=expression[1];for(var i=0,len=filterTags.length;i]*)>([^>]*)","igm"),"")}if(typeof attrs!=="undefined"){var htmlTagRegex=/\<(\w+)\s*([^\>]*)\>([^\>]*)\<\/(\w+)\>/gi;if(attrs==="*"){html=html.replace(htmlTagRegex,function($1,$2,$3,$4,$5){return"<"+$2+">"+$4+""})}else if(attrs==="on*"){html=html.replace(htmlTagRegex,function($1,$2,$3,$4,$5){var el=$("<"+$2+">"+$4+"");var _attrs=$($1)[0].attributes;var $attrs={};$.each(_attrs,function(i,e){if(e.nodeName!=='"')$attrs[e.nodeName]=e.nodeValue});$.each($attrs,function(i){if(i.indexOf("on")===0){delete $attrs[i]}});el.attr($attrs);var text=typeof el[1]!=="undefined"?$(el[1]).text():"";return el[0].outerHTML+text})}else{html=html.replace(htmlTagRegex,function($1,$2,$3,$4){var filterAttrs=attrs.split(",");var el=$($1);el.html($4);$.each(filterAttrs,function(i){el.attr(filterAttrs[i],null)});return el[0].outerHTML})}}return html};editormd.markdownToHTML=function(id,options){var defaults={gfm:true,toc:true,tocm:false,tocStartLevel:1,tocTitle:"目录",tocDropdown:false,tocContainer:"",markdown:"",markdownSourceCode:false,htmlDecode:false,autoLoadKaTeX:true,pageBreak:true,atLink:true,emailLink:true,tex:false,taskList:false,emoji:false,flowChart:false,sequenceDiagram:false,previewCodeHighlight:true,mermaid:true,mindMap:true};editormd.$marked=marked;var div=$("#"+id);var settings=div.settings=$.extend(true,defaults,options||{});var saveTo=div.find("textarea");if(saveTo.length<1){div.append("");saveTo=div.find("textarea")}var markdownDoc=settings.markdown===""?saveTo.val():settings.markdown;var markdownToC=[];var rendererOptions={toc:settings.toc,tocm:settings.tocm,tocStartLevel:settings.tocStartLevel,taskList:settings.taskList,emoji:settings.emoji,tex:settings.tex,pageBreak:settings.pageBreak,atLink:settings.atLink,emailLink:settings.emailLink,flowChart:settings.flowChart,sequenceDiagram:settings.sequenceDiagram,mermaid:settings.mermaid,mindMap:settings.mindMap,previewCodeHighlight:settings.previewCodeHighlight};var markedOptions={renderer:editormd.markedRenderer(markdownToC,rendererOptions),gfm:settings.gfm,tables:true,breaks:true,pedantic:false,sanitize:settings.htmlDecode?false:true,smartLists:true,smartypants:true};markdownDoc=new String(markdownDoc);var markdownParsed=marked(markdownDoc,markedOptions);markdownParsed=editormd.filterHTMLTags(markdownParsed,settings.htmlDecode);if(settings.markdownSourceCode){saveTo.text(markdownDoc)}else{saveTo.remove()}div.addClass("markdown-body "+this.classPrefix+"html-preview").append(markdownParsed);var tocContainer=settings.tocContainer!==""?$(settings.tocContainer):div;if(settings.tocContainer!==""){tocContainer.attr("previewContainer",false)}if(settings.toc){div.tocContainer=this.markdownToCRenderer(markdownToC,tocContainer,settings.tocDropdown,settings.tocStartLevel);if(settings.tocDropdown||div.find("."+this.classPrefix+"toc-menu").length>0){this.tocDropdownMenu(div,settings.tocTitle)}if(settings.tocContainer!==""){div.find(".editormd-toc-menu, .editormd-markdown-toc").remove()}}if(settings.previewCodeHighlight){div.find("pre").addClass("prettyprint");prettyPrint()}if(!editormd.isIE8){if(settings.flowChart){div.find(".flowchart").flowChart()}if(settings.sequenceDiagram){div.find(".sequence-diagram").sequenceDiagram({theme:"simple"})}if(settings.mermaid){window.mermaid.init(void 0,div.find(".lang-mermaid"))}}if(settings.tex){var katexHandle=function(){div.find("."+editormd.classNames.tex).each(function(){var tex=$(this);katex.render(tex.html().replace(/</g,"<").replace(/>/g,">"),tex[0]);tex.find(".katex").css("font-size","1.6em")})};if(settings.autoLoadKaTeX&&!editormd.$katex&&!editormd.kaTeXLoaded){this.loadKaTeX(function(){editormd.$katex=katex;editormd.kaTeXLoaded=true;katexHandle()})}else{katexHandle()}}if(settings.mindMap){var mindmapHandle=function(){div.find(".mindmap").each(function(){var mmap=$(this);var md_data=window.markmap.transform(mmap.text().trim());window.markmap.markmap("svg#"+this.id,md_data)})};mindmapHandle()}div.getMarkdown=function(){return saveTo.val()};return div};editormd.themes=["default","dark"];editormd.previewThemes=["default","dark"];editormd.editorThemes=["default","3024-day","3024-night","ambiance","ambiance-mobile","base16-dark","base16-light","blackboard","cobalt","eclipse","elegant","erlang-dark","lesser-dark","mbo","mdn-like","midnight","monokai","neat","neo","night","paraiso-dark","paraiso-light","pastel-on-dark","rubyblue","solarized","the-matrix","tomorrow-night-eighties","twilight","vibrant-ink","xq-dark","xq-light"];editormd.loadPlugins={};editormd.loadFiles={js:[],css:[],plugin:[]};editormd.loadPlugin=function(fileName,callback,into){callback=callback||function(){};this.loadScript(fileName,function(){editormd.loadFiles.plugin.push(fileName);callback()},into)};editormd.loadCSS=function(fileName,callback,into){into=into||"head";callback=callback||function(){};var css=document.createElement("link");css.type="text/css";css.rel="stylesheet";css.onload=css.onreadystatechange=function(){editormd.loadFiles.css.push(fileName);callback()};css.href=fileName+".css";if(into==="head"){document.getElementsByTagName("head")[0].appendChild(css)}else{document.body.appendChild(css)}};editormd.isIE=navigator.appName=="Microsoft Internet Explorer";editormd.isIE8=editormd.isIE&&navigator.appVersion.match(/8./i)=="8.";editormd.loadScript=function(fileName,callback,into){into=into||"head";callback=callback||function(){};var script=null;script=document.createElement("script");script.id=fileName.replace(/[\./]+/g,"-");script.type="text/javascript";script.src=fileName+".js";if(editormd.isIE8){script.onreadystatechange=function(){if(script.readyState){if(script.readyState==="loaded"||script.readyState==="complete"){script.onreadystatechange=null;editormd.loadFiles.js.push(fileName);callback()}}}}else{script.onload=function(){editormd.loadFiles.js.push(fileName);callback()}}if(into==="head"){document.getElementsByTagName("head")[0].appendChild(script)}else{document.body.appendChild(script)}};editormd.katexURL={css:"//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.3.0/katex.min",js:"//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.3.0/katex.min"};editormd.kaTeXLoaded=false;editormd.loadKaTeX=function(callback){editormd.loadCSS(editormd.katexURL.css,function(){editormd.loadScript(editormd.katexURL.js,callback||function(){})})};editormd.lockScreen=function(lock){$("html,body").css("overflow",lock?"hidden":"")};editormd.createDialog=function(options){var defaults={name:"",width:420,height:240,title:"",drag:true,closed:true,content:"",mask:true,maskStyle:{backgroundColor:"#fff",opacity:.1},lockScreen:true,footer:true,buttons:false};options=$.extend(true,defaults,options);var $this=this;var editor=this.editor;var classPrefix=editormd.classPrefix;var guid=(new Date).getTime();var dialogName=options.name===""?classPrefix+"dialog-"+guid:options.name;var mouseOrTouch=editormd.mouseOrTouch;var html='
                          ';if(options.title!==""){html+='
                          ";html+=''+options.title+"";html+="
                          "}if(options.closed){html+=''}html+='
                          '+options.content;if(options.footer||typeof options.footer==="string"){html+='"}html+="
                          ";html+='
                          ';html+='
                          ';html+="
                          ";editor.append(html);var dialog=editor.find("."+dialogName);dialog.lockScreen=function(lock){if(options.lockScreen){$("html,body").css("overflow",lock?"hidden":"");$this.resize()}return dialog};dialog.showMask=function(){if(options.mask){editor.find("."+classPrefix+"mask").css(options.maskStyle).css("z-index",editormd.dialogZindex-1).show()}return dialog};dialog.hideMask=function(){if(options.mask){editor.find("."+classPrefix+"mask").hide()}return dialog};dialog.loading=function(show){var loading=dialog.find("."+classPrefix+"dialog-mask");loading[show?"show":"hide"]();return dialog};dialog.lockScreen(true).showMask();dialog.show().css({zIndex:editormd.dialogZindex,border:editormd.isIE8?"1px solid #ddd":"",width:typeof options.width==="number"?options.width+"px":options.width,height:typeof options.height==="number"?options.height+"px":options.height});var dialogPosition=function(){dialog.css({top:($(window).height()-dialog.height())/2+"px",left:($(window).width()-dialog.width())/2+"px"})};dialogPosition();$(window).resize(dialogPosition);dialog.children("."+classPrefix+"dialog-close").bind(mouseOrTouch("click","touchend"),function(){dialog.hide().lockScreen(false).hideMask()});if(typeof options.buttons==="object"){var footer=dialog.footer=dialog.find("."+classPrefix+"dialog-footer");for(var key in options.buttons){var btn=options.buttons[key];var btnClassName=classPrefix+key+"-btn";footer.append('");btn[1]=$.proxy(btn[1],dialog);footer.children("."+btnClassName).bind(mouseOrTouch("click","touchend"),btn[1])}}if(options.title!==""&&options.drag){var posX,posY;var dialogHeader=dialog.children("."+classPrefix+"dialog-header");if(!options.mask){dialogHeader.bind(mouseOrTouch("click","touchend"),function(){editormd.dialogZindex+=2;dialog.css("z-index",editormd.dialogZindex)})}dialogHeader.mousedown(function(e){e=e||window.event;posX=e.clientX-parseInt(dialog[0].style.left);posY=e.clientY-parseInt(dialog[0].style.top);document.onmousemove=moveAction});var userCanSelect=function(obj){obj.removeClass(classPrefix+"user-unselect").off("selectstart")};var userUnselect=function(obj){obj.addClass(classPrefix+"user-unselect").on("selectstart",function(event){return false})};var moveAction=function(e){e=e||window.event;var left,top,nowLeft=parseInt(dialog[0].style.left),nowTop=parseInt(dialog[0].style.top);if(nowLeft>=0){if(nowLeft+dialog.width()<=$(window).width()){left=e.clientX-posX}else{left=$(window).width()-dialog.width();document.onmousemove=null}}else{left=0;document.onmousemove=null}if(nowTop>=0){top=e.clientY-posY}else{top=0;document.onmousemove=null}document.onselectstart=function(){return false};userUnselect($("body"));userUnselect(dialog);dialog[0].style.left=left+"px";dialog[0].style.top=top+"px"};document.onmouseup=function(){userCanSelect($("body"));userCanSelect(dialog);document.onselectstart=null;document.onmousemove=null};dialogHeader.touchDraggable=function(){var offset=null;var start=function(e){var orig=e.originalEvent;var pos=$(this).parent().position();offset={x:orig.changedTouches[0].pageX-pos.left,y:orig.changedTouches[0].pageY-pos.top}};var move=function(e){e.preventDefault();var orig=e.originalEvent;$(this).parent().css({top:orig.changedTouches[0].pageY-offset.y,left:orig.changedTouches[0].pageX-offset.x})};this.bind("touchstart",start).bind("touchmove",move)};dialogHeader.touchDraggable()}editormd.dialogZindex+=2;return dialog};editormd.mouseOrTouch=function(mouseEventType,touchEventType){mouseEventType=mouseEventType||"click";touchEventType=touchEventType||"touchend";var eventType=mouseEventType;try{document.createEvent("TouchEvent");eventType=touchEventType}catch(e){}return eventType};editormd.dateFormat=function(format){format=format||"";var addZero=function(d){return d<10?"0"+d:d};var date=new Date;var year=date.getFullYear();var year2=year.toString().slice(2,4);var month=addZero(date.getMonth()+1);var day=addZero(date.getDate());var weekDay=date.getDay();var hour=addZero(date.getHours());var min=addZero(date.getMinutes());var second=addZero(date.getSeconds());var ms=addZero(date.getMilliseconds());var datefmt="";var ymd=year2+"-"+month+"-"+day;var fymd=year+"-"+month+"-"+day;var hms=hour+":"+min+":"+second;switch(format){case"UNIX Time":datefmt=date.getTime();break;case"UTC":datefmt=date.toUTCString();break;case"yy":datefmt=year2;break;case"year":case"yyyy":datefmt=year;break;case"month":case"mm":datefmt=month;break;case"cn-week-day":case"cn-wd":var cnWeekDays=["日","一","二","三","四","五","六"];datefmt="星期"+cnWeekDays[weekDay];break;case"week-day":case"wd":var weekDays=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];datefmt=weekDays[weekDay];break;case"day":case"dd":datefmt=day;break;case"hour":case"hh":datefmt=hour;break;case"min":case"ii":datefmt=min;break;case"second":case"ss":datefmt=second;break;case"ms":datefmt=ms;break;case"yy-mm-dd":datefmt=ymd;break;case"yyyy-mm-dd":datefmt=fymd;break;case"yyyy-mm-dd h:i:s ms":case"full + ms":datefmt=fymd+" "+hms+" "+ms;break;case"full":case"yyyy-mm-dd h:i:s":default:datefmt=fymd+" "+hms;break}return datefmt};editormd.getLine=function(n){return this.cm.getLine(n)};return editormd}); \ No newline at end of file +/*! Editor.md v1.7.17 | editormd.min.js | Open source online markdown editor. | MIT License | By: IBM Skills Network | https://github.com/ibm-skills-network/editor.md | 2024-03-27 */ +!function(e){"use strict";"function"==typeof require&&"object"==typeof exports&&"object"==typeof module?module.exports=e:"function"==typeof define?define.amd||define(["jquery"],e):window.editormd=e()}(function(){"use strict";var C,c,h,e,d,v="undefined"!=typeof jQuery?jQuery:Zepto;if(void 0!==v)return(C=function(e,t,i){return new C.fn.init(e,t,i)}).title=C.$name="Editor.md",C.version="1.7.17",C.homePage="https://pandao.github.io/editor.md/",C.classPrefix="editormd-",C.toolbarModes={full:["undo","redo","|","bold","del","italic","quote","ucwords","uppercase","lowercase","|","h1","h2","h3","h4","h5","h6","|","list-ul","list-ol","hr","|","link","reference-link","image","code","preformatted-text","code-block","table","datetime","emoji","html-entities","pagebreak","|","goto-line","watch","preview","fullscreen","clear","search","|","help","changetheme","info"],simple:["undo","redo","|","bold","del","italic","quote","uppercase","lowercase","|","h1","h2","h3","h4","h5","h6","|","list-ul","list-ol","hr","|","watch","preview","fullscreen","|","help","changetheme","info"],mini:["undo","redo","|","watch","preview","|","help","changetheme","info"]},C.defaults={debug:!1,mode:"gfm",name:"",value:"",theme:"",editorTheme:"default",previewTheme:"",markdown:void 0,appendMarkdown:"",width:"100%",height:"100%",path:"./lib/",pluginPath:"",customPluginPath:"",delay:300,autoLoadModules:!0,watch:!0,placeholder:"Enjoy Markdown! coding now...",gotoLine:!0,codeFold:!1,autoHeight:!1,autoFocus:!0,autoCloseTags:!0,searchReplace:!0,syncScrolling:!0,readOnly:!1,tabSize:4,indentUnit:4,lineNumbers:!0,lineWrapping:!0,autoCloseBrackets:!0,showTrailingSpace:!0,matchBrackets:!0,indentWithTabs:!0,styleSelectedText:!0,matchWordHighlight:!0,styleActiveLine:!0,dialogLockScreen:!0,dialogShowMask:!0,dialogDraggable:!0,dialogMaskBgColor:"#fff",dialogMaskOpacity:.1,fontSize:"13px",saveHTMLToTextarea:!1,disabledKeyMaps:[],onload:function(){},onresize:function(){},onchange:function(){},onwatch:null,onunwatch:null,onpreviewing:function(){},onCmChange:null,fixCodeBlocks:function(){},onpreviewed:function(){},onfullscreen:function(){},onfullscreenExit:function(){},onscroll:function(){},onpreviewscroll:function(){},imageUpload:!1,imageFormats:["jpg","jpeg","gif","png","bmp","webp"],imageUploadURL:"",crossDomainUpload:!1,uploadCallbackURL:"",toc:!0,tocm:!1,tocTitle:"",tocDropdown:!1,tocContainer:"",tocStartLevel:1,htmlDecode:!1,pageBreak:!0,atLink:!0,emailLink:!0,taskList:!1,emoji:!0,tex:!1,flowChart:!1,sequenceDiagram:!1,mermaid:!0,mindMap:!0,previewCodeHighlight:!0,toolbar:!0,toolbarAutoFixed:!0,titlebar:{left:{},center:{},right:{}},toolbarIcons:"full",toolbarTitles:{},toolbarHandlers:{ucwords:function(){return C.toolbarHandlers.ucwords},lowercase:function(){return C.toolbarHandlers.lowercase}},toolbarCustomIcons:{lowercase:'a',ucwords:'Aa',fontcase:'Aa'},toolbarIconsClass:{undo:"fa-undo",redo:"fa-repeat",bold:"fa-bold",del:"fa-strikethrough",italic:"fa-italic",quote:"fa-quote-left",uppercase:"fa-font",heading:"fa-header",h1:C.classPrefix+"bold",h2:C.classPrefix+"bold",h3:C.classPrefix+"bold",h4:C.classPrefix+"bold",h5:C.classPrefix+"bold",h6:C.classPrefix+"bold","list-ul":"fa-list-ul","list-ol":"fa-list-ol",hr:"fa-minus",link:"fa-link","reference-link":"fa-anchor",image:"fa-picture-o",code:"fa-code","preformatted-text":"fa-file-code-o","code-block":"fa-file-code-o",table:"fa-table",datetime:"fa-clock-o",emoji:"fa-smile-o","html-entities":"fa-copyright",pagebreak:"fa-newspaper-o","goto-line":"fa-terminal",watch:"fa-eye-slash",unwatch:"fa-eye",preview:"fa-desktop",search:"fa-search",fullscreen:"fa-arrows-alt",clear:"fa-eraser",help:"fa-question-circle",changetheme:"fa-info-circle",info:"fa-info-circle"},toolbarIconTexts:{ucwords:"Capitalize",uppercase:"Uppercase",lowercase:"Lowercase",h1:"Heading 1",h2:"Heading 2",h3:"Heading 3",h4:"Heading 4",h5:"Heading 5",h6:"Heading 6"},lang:{name:"zh-cn",description:"开源在线Markdown编辑器
                          Open source online Markdown editor.",tocTitle:"目录",toolbar:{undo:"撤销(Ctrl+Z)",redo:"重做(Ctrl+Y)",bold:"粗体",del:"删除线",italic:"斜体",quote:"引用",ucwords:"将每个单词首字母转成大写",uppercase:"将所选转换成大写",lowercase:"将所选转换成小写",h1:"标题1",h2:"标题2",h3:"标题3",h4:"标题4",h5:"标题5",h6:"标题6","list-ul":"无序列表","list-ol":"有序列表",hr:"横线",link:"链接","reference-link":"引用链接",image:"添加图片",code:"行内代码","preformatted-text":"预格式文本 / 代码块(缩进风格)","code-block":"代码块(多语言风格)",table:"添加表格",datetime:"日期时间",emoji:"Emoji表情","html-entities":"HTML实体字符",pagebreak:"插入分页符","goto-line":"跳转到行",watch:"关闭实时预览",unwatch:"开启实时预览",preview:"全窗口预览HTML(按 Shift + ESC还原)",fullscreen:"全屏(按ESC还原)",clear:"清空",search:"搜索",help:"使用帮助",changetheme:"切换编辑主题",info:"关于"+C.title},buttons:{enter:"确定",cancel:"取消",close:"关闭"},dialog:{link:{title:"添加链接",url:"链接地址",urlTitle:"链接标题",urlEmpty:"错误:请填写链接地址。"},referenceLink:{title:"添加引用链接",name:"引用名称",url:"链接地址",urlId:"链接ID",urlTitle:"链接标题",nameEmpty:"错误:引用链接的名称不能为空。",idEmpty:"错误:请填写引用链接的ID。",urlEmpty:"错误:请填写引用链接的URL地址。"},image:{title:"添加图片",url:"图片地址",link:"图片链接",alt:"图片描述",uploadButton:"本地上传",imageURLEmpty:"错误:图片地址不能为空。",uploadFileEmpty:"错误:上传的图片不能为空。",formatNotAllowed:"错误:只允许上传图片文件,允许上传的图片文件格式有:"},preformattedText:{title:"添加预格式文本或代码块",emptyAlert:"错误:请填写预格式文本或代码的内容。"},codeBlock:{title:"添加代码块",selectLabel:"代码语言:",selectDefaultText:"请选择代码语言",otherLanguage:"其他语言",unselectedLanguageAlert:"错误:请选择代码所属的语言类型。",codeEmptyAlert:"错误:请填写代码内容。"},htmlEntities:{title:"HTML 实体字符"},help:{title:"使用帮助"},changetheme:{title:"切换编辑主题"}}}},C.classNames={tex:C.classPrefix+"tex",texDisplay:C.classPrefix+"texDisaply"},C.dialogZindex=99999,C.$katex=null,C.$marked=null,C.$filterXSS=null,C.$CodeMirror=null,C.$prettyPrint=null,C.prototype=C.fn={state:{watching:!1,loaded:!1,preview:!1,fullscreen:!1},init:function(e,t,i){i="object"==typeof e?e:i||{};var o=this.classPrefix=C.classPrefix,i=this.settings=v.extend(!0,{},C.defaults,i),n=(e="object"==typeof e?i.id:e,this.editor=v("#"+e)),t=(this.id=e,this.author_ide_version=t||n.version,this.lang=i.lang,this.classNames={textarea:{html:o+"html-textarea",markdown:o+"markdown-textarea"}}),r=(i.pluginPath=""===i.pluginPath?i.path+"../plugins/":i.pluginPath,this.state.watching=!!i.watch,n.hasClass("editormd")||n.addClass("editormd"),n.css({width:"number"==typeof i.width?i.width+"px":i.width,height:"number"==typeof i.height?i.height+"px":i.height}),i.autoHeight&&n.css("height","auto"),this.markdownTextarea=n.children("textarea")),e=(r.length<1&&(n.append(""),r=this.markdownTextarea=n.children("textarea")),r.addClass(t.textarea.markdown).attr("placeholder",i.placeholder),void 0!==r.attr("name")&&""!==r.attr("name")||r.attr("name",""!==i.name?i.name:e+"-markdown-doc"),[i.readOnly?"":'',i.saveHTMLToTextarea?'':"",'
                          ','
                          ','
                          '].join("\n"));return n.append(e).addClass(o+"vertical"),""!==i.theme&&n.addClass(o+"theme-"+i.theme),this.mask=n.children("."+o+"mask"),this.containerMask=n.children("."+o+"container-mask"),void 0!==i.markdown&&r.val(i.markdown),""!==i.appendMarkdown&&r.val(r.val()+i.appendMarkdown),this.htmlTextarea=n.children("."+t.textarea.html),this.preview=n.children("."+o+"preview"),this.previewContainer=this.preview.children("."+o+"preview-container"),""!==i.previewTheme&&this.preview.addClass(o+"preview-theme-"+i.previewTheme),"function"==typeof define&&define.amd&&("undefined"!=typeof katex&&(C.$katex=katex),i.searchReplace)&&!i.readOnly&&(C.loadCSS(i.path+"codemirror/addon/dialog/dialog"),C.loadCSS(i.path+"codemirror/addon/search/matchesonscrollbar")),"function"==typeof define&&define.amd||!i.autoLoadModules?("undefined"!=typeof CodeMirror&&(C.$CodeMirror=CodeMirror),"undefined"!=typeof marked&&(C.$marked=marked),this.setCodeMirror().setToolbar().loadedDisplay()):this.loadQueues(),this},loadQueues:function(){function e(){!C.isIE8&&(i.flowChart||i.sequenceDiagram)?C.loadScript(o+"raphael.min",function(){C.loadScript(o+"underscore.min",function(){!i.flowChart&&i.sequenceDiagram?C.loadScript(o+"sequence-diagram.min",function(){t.loadedDisplay()}):i.flowChart&&!i.sequenceDiagram?C.loadScript(o+"flowchart.min",function(){C.loadScript(o+"jquery.flowchart.min",function(){t.loadedDisplay()})}):i.flowChart&&i.sequenceDiagram&&C.loadScript(o+"flowchart.min",function(){C.loadScript(o+"jquery.flowchart.min",function(){C.loadScript(o+"sequence-diagram.min",function(){t.loadedDisplay()})})})})}):t.loadedDisplay()}var t=this,i=this.settings,o=i.path;return C.loadScript(o+"xss",function(){C.$filterXSS=filterXSS}),C.loadCSS(o+"codemirror/codemirror.min"),i.searchReplace&&!i.readOnly&&(C.loadCSS(o+"codemirror/addon/dialog/dialog"),C.loadCSS(o+"codemirror/addon/search/matchesonscrollbar")),i.codeFold&&C.loadCSS(o+"codemirror/addon/fold/foldgutter"),C.loadScript(o+"codemirror/codemirror.min",function(){C.$CodeMirror=CodeMirror,C.loadScript(o+"codemirror/modes.min",function(){C.loadScript(o+"codemirror/addons.min",function(){if(t.setCodeMirror(),"gfm"!==i.mode&&"markdown"!==i.mode)return t.loadedDisplay(),!1;t.setToolbar(),C.loadScript(o+"marked.min",function(){C.$marked=marked,i.highlightStyle||(i.highlightStyle="github"),i.previewCodeHighlight?(C.loadCSS(o+"highlight/styles/"+i.highlightStyle),C.loadScript(o+"highlight/highlight",function(){e()})):e()})})})}),this},setTheme:function(e){var t=this.editor,i=this.settings.theme,o=this.classPrefix+"theme-";return t.removeClass(o+i).addClass(o+e),this.settings.theme=e,this},setEditorTheme:function(e){var t=this.settings;return"default"!==(t.editorTheme=e)&&C.loadCSS(t.path+"codemirror/theme/"+t.editorTheme),this.cm.setOption("theme",e),this},setCodeMirrorTheme:function(e){return this.setEditorTheme(e),this},setPreviewTheme:function(e){var t=this.preview,i=this.settings.previewTheme,o=this.classPrefix+"preview-theme-";return t.removeClass(o+i).addClass(o+e),this.settings.previewTheme=e,this},setCodeMirror:function(){var e=this.settings,t=this.editor,i=("default"!==e.editorTheme&&C.loadCSS(e.path+"codemirror/theme/"+e.editorTheme),{mode:e.mode,theme:e.editorTheme,tabSize:e.tabSize,dragDrop:!1,autofocus:e.autoFocus,autoCloseTags:e.autoCloseTags,readOnly:!!e.readOnly&&"nocursor",indentUnit:e.indentUnit,lineNumbers:e.lineNumbers,lineWrapping:e.lineWrapping,extraKeys:{"Ctrl-Q":function(e){e.foldCode(e.getCursor())}},foldGutter:e.codeFold,gutters:["CodeMirror-linenumbers","CodeMirror-foldgutter"],matchBrackets:e.matchBrackets,indentWithTabs:e.indentWithTabs,styleActiveLine:e.styleActiveLine,styleSelectedText:e.styleSelectedText,autoCloseBrackets:e.autoCloseBrackets,showTrailingSpace:e.showTrailingSpace,highlightSelectionMatches:!!e.matchWordHighlight&&{showToken:"onselected"!==e.matchWordHighlight&&/\w/}});return this.codeEditor=this.cm=C.$CodeMirror.fromTextArea(this.markdownTextarea[0],i),this.codeMirror=this.cmElement=t.children(".CodeMirror"),""!==e.value&&this.cm.setValue(e.value),this.codeMirror.css({fontSize:e.fontSize,width:e.watch?"50%":"100%"}),e.autoHeight&&(this.codeMirror.css("height","auto"),this.cm.setOption("viewportMargin",1/0)),e.lineNumbers||this.codeMirror.find(".CodeMirror-gutters").css("border-right","none"),this},getCodeMirrorOption:function(e){return this.cm.getOption(e)},setCodeMirrorOption:function(e,t){return this.cm.setOption(e,t),this},addKeyMap:function(e,t){return this.cm.addKeyMap(e,t),this},removeKeyMap:function(e){return this.cm.removeKeyMap(e),this},gotoLine:function(e){var t,i,o,n,r=this.settings;return r.gotoLine&&(t=this.cm,this.editor,o=t.lineCount(),i=this.preview,"number"!=typeof(e="string"==typeof e&&"first"===(e="last"===e?o:e)?1:e)?alert("Error: The line number must be an integer."):o<(e=parseInt(e)-1)?alert("Error: The line number range 1-"+o):(t.setCursor({line:e,ch:0}),o=t.getScrollInfo().clientHeight,e=t.charCoords({line:e,ch:0},"local"),t.scrollTo(null,(e.top+e.bottom-o)/2),r.watch&&(e=this.codeMirror.find(".CodeMirror-scroll")[0],o=v(e).height(),n=(r=e.scrollTop)/e.scrollHeight,0===r?i.scrollTop(0):r+o>=e.scrollHeight-16?i.scrollTop(i[0].scrollHeight):i.scrollTop(i[0].scrollHeight*n)),t.focus())),this},extend:function(){return void 0!==arguments[1]&&("function"==typeof arguments[1]&&(arguments[1]=v.proxy(arguments[1],this)),this[arguments[0]]=arguments[1]),"object"==typeof arguments[0]&&void 0===arguments[0].length&&v.extend(!0,this,arguments[0]),this},set:function(e,t){return void 0!==t&&"function"==typeof t&&(t=v.proxy(t,this)),this[e]=t,this},config:function(e,t){var i=this.settings;return"object"==typeof e&&(i=v.extend(!0,i,e)),"string"==typeof e&&(i[e]=t),this.settings=i,this.recreate(),this},on:function(e,t){var i=this.settings;return void 0!==i["on"+e]&&(i["on"+e]=v.proxy(t,this)),this},off:function(e){var t=this.settings;return void 0!==t["on"+e]&&(t["on"+e]=function(){}),this},showToolbar:function(e){var t=this.settings;return t.readOnly||(t.toolbar&&(this.toolbar.length<1||""===this.toolbar.find("."+this.classPrefix+"menu").html())&&this.setToolbar(),t.toolbar=!0,this.toolbar.show(),this.resize(),v.proxy(e||function(){},this)()),this},hideToolbar:function(e){return this.settings.toolbar=!1,this.toolbar.hide(),this.resize(),v.proxy(e||function(){},this)(),this},setToolbarAutoFixed:function(e){var t=this.state,i=this.editor,o=this.toolbar,n=this.settings;void 0!==e&&(n.toolbarAutoFixed=e);return!t.fullscreen&&!t.preview&&n.toolbar&&n.toolbarAutoFixed&&v(window).bind("scroll",function(){var e=v(window),t=e.scrollTop();if(!n.toolbarAutoFixed)return!1;10
                            '),i=this.toolbar=e.children("."+s+"toolbar")),a.toolbar){for(var l="",o=(Object.entries(t).forEach(([e,t])=>{var i="";if("left"===e)i='Skills Network Author IDE';else for(var o in t){var n=o.replace(/\s+/g,"-").toLowerCase(),r="string"==typeof a.lang.titlebar[o]?a.lang.titlebar[o]:"";switch(t[o]){case"dropdown":i+='
                            ';break;case"button":i+='";break;default:i+=''+o+""}}l+='
                            '+i+"
                            "}),i.find("div."+s+"titlebar-container").html(l),i.show(),"function"==typeof a.toolbarIcons?a.toolbarIcons():"string"==typeof a.toolbarIcons?C.toolbarModes[a.toolbarIcons]:a.toolbarIcons),e=i.find("."+this.classPrefix+"menu"),n="",r=!1,c=0,h=o.length;c';else{var d,u,f=u.includes("dropdown"),p=[],g=(r&&p.push("pull-right"),f&&p.push("dropdown"),0':"
                          • "),m=[];f?(d=(p=u.split(":"))[0],u=p[1],p=p[2].split(","),m=[u].concat(p),p.length||(f=!1)):m.push(u);for(var w=0,h=m.length;w');var v=!(f&&"dropdownIcon"!==d&&g.includes("toolbar-dropdown-content")),b=/h(\d)/.test(u),x=u,k=("watch"!==u||a.watch||(x="unwatch"),a.lang.toolbar[x]),y=void 0===(y=a.toolbarIconTexts[x])?"":y,x=void 0!==(x=a.toolbarIconsClass[x])&&v?x:"";g+='',v&&void 0!==a.toolbarCustomIcons[u]&&"function"!=typeof a.toolbarCustomIcons[u]?g+=a.toolbarCustomIcons[u]:(g+='',"function"!=typeof a.toolbarIcons&&b?g+=''+u.toUpperCase()+"":d&&"dropdownIcon"===d&&g.includes("toolbar-dropdown-content")?g+=''+(y||u)+"":""!==x&&v||(g+=''+(y||u)+""),g+=""),g+="",f&&w===h-1&&g.includes("toolbar-dropdown-content")&&(g+="",d="")}g+="
                          • ",n=r?g+n:n+g}e.html(n),e.find('[title="Lowercase"]').attr("title",a.lang.toolbar.lowercase),e.find('[title="ucwords"]').attr("title",a.lang.toolbar.ucwords),this.setToolbarHandler(),this.setToolbarAutoFixed()}else i.hide()}return this},dialogLockScreen:function(){return v.proxy(C.dialogLockScreen,this)(),this},dialogShowMask:function(e){return v.proxy(C.dialogShowMask,this)(e),this},positionDialog:function(e,t){return v.proxy(C.positionDialog,this)(e,t),this},getToolbarHandles:function(e){var t=this.toolbarHandlers=C.toolbarHandlers;return e&&void 0!==toolbarIconHandlers[e]?t[e]:t},setToolbarHandler:function(){var n,e,t,r,a=this,s=this.settings;return s.toolbar&&!s.readOnly&&(t=this.toolbar,n=this.cm,e=this.classPrefix,t=this.toolbarIcons=t.find("."+e+"menu > li a"),r=this.getToolbarHandles(),t.bind(C.mouseOrTouch("click","touchend"),function(){var e=v(this).children(".fa"),t=e.attr("name"),i=n.getCursor(),o=n.getSelection();if(""!==t)return a.activeIcon=e,void 0!==r[t]?v.proxy(r[t],a)(n):void 0!==s.toolbarHandlers[t]&&v.proxy(s.toolbarHandlers[t],a)(n,e,i,o),"link"!==t&&"reference-link"!==t&&"image"!==t&&"code-block"!==t&&"preformatted-text"!==t&&"watch"!==t&&"preview"!==t&&"search"!==t&&"fullscreen"!==t&&"info"!==t&&n.focus(),!1})),this},createDialog:function(e){return v.proxy(C.createDialog,this)(e)},createInfoDialog:function(){var e=this,t=this.editor,i=this.classPrefix,o=['
                            ','
                            ','

                            '+C.title+"v"+C.version+"

                            ","

                            "+this.lang.description+"

                            ",'

                            '+C.homePage+'

                            ','

                            Copyright © 2015 Pandao, The MIT License.

                            ',"
                            ",'',"
                            "].join("\n"),o=(t.append(o),this.infoDialog=t.children("."+i+"dialog-info"));return o.find("."+i+"dialog-close").bind(C.mouseOrTouch("click","touchend"),function(){e.hideInfoDialog()}),o.css("border",C.isIE8?"1px solid #ddd":"").css("z-index",C.dialogZindex).show(),this.infoDialogPosition(),this},infoDialogPosition:function(){function e(){t.css({top:(v(window).height()-t.height())/2+"px",left:(v(window).width()-t.width())/2+"px"})}var t=this.infoDialog;return e(),v(window).resize(e),this},showInfoDialog:function(){v("html,body").css("overflow-x","hidden");var e=this.editor,t=this.settings,e=this.infoDialog=e.children("."+this.classPrefix+"dialog-info");return e.length<1&&this.createInfoDialog(),this.lockScreen(!0),this.mask.css({opacity:t.dialogMaskOpacity,backgroundColor:t.dialogMaskBgColor}).show(),e.css("z-index",C.dialogZindex).show(),this.infoDialogPosition(),this},hideInfoDialog:function(){return v("html,body").css("overflow-x",""),this.infoDialog.hide(),this.mask.hide(),this.lockScreen(!1),this},lockScreen:function(e){return C.lockScreen(e),this.resize(),this},recreate:function(){var e=this.editor,t=this.settings;return this.codeMirror.remove(),this.setCodeMirror(),t.readOnly||(0=e[0].scrollHeight-16?i.scrollTop(i[0].scrollHeight):i.scrollTop((i[0].scrollHeight+r+a)*n)}return this},registerKeyMaps:function(e){var t=this,i=this.cm,o=this.settings,n=C.toolbarHandlers,r=o.disabledKeyMaps;if(e=e||null)for(var a in e)v.inArray(a,r)<0&&(e[a],i.addKeyMap(e));else{for(var s in C.keyMaps){var l,c=C.keyMaps[s],c="string"==typeof c?v.proxy(n[c],t):v.proxy(c,t);v.inArray(s,["F9","F10","F11"])<0&&v.inArray(s,r)<0&&((l={})[s]=c,i.addKeyMap(l))}v(window).keydown(function(e){if(v.inArray({120:"F9",121:"F10",122:"F11"}[e.keyCode],r)<0)switch(e.keyCode){case 120:return v.proxy(n.watch,t)(),!1;case 121:return v.proxy(n.preview,t)(),!1;case 122:return v.proxy(n.fullscreen,t)(),!1}})}return this},bindScrollEvent:function(){var e,t,i,o,a=this,s=this.previewContainer,l=this.settings,r=this.codeMirror,n=C.mouseOrTouch;return l.syncScrolling&&(i=function(){s.bind(n("scroll","touchmove"),function(e){var t,i,o,n;null==c&&(t=v(this).height(),o=(i=v(this).scrollTop())/v(this)[0].scrollHeight,n=r.find(".CodeMirror-scroll"),0===i?n.scrollTop(0):i+t>=v(this)[0].scrollHeight?n.scrollTop(n[0].scrollHeight):n.scrollTop(n[0].scrollHeight*o),v.proxy(l.onpreviewscroll,a)(e))})},o=function(){s.unbind(n("scroll","touchmove"))},r.bind({mouseover:e=function(){r.find(".CodeMirror-scroll").bind(n("scroll","touchmove"),function(e){var t,i,o,n,r;null==c&&(t=v(this).height(),o=(i=v(this).scrollTop())/v(this)[0].scrollHeight,n=0,s.find(".markdown-toc-list").each(function(){n+=v(this).height()}),r=(r=s.find(".editormd-toc-menu").height())||0,0===i?s.scrollTop(0):i+t>=v(this)[0].scrollHeight-16?s.scrollTop(s[0].scrollHeight):s.scrollTop((s[0].scrollHeight+n+r)*o),v.proxy(l.onscroll,a)(e))})},mouseout:t=function(){r.find(".CodeMirror-scroll").unbind(n("scroll","touchmove"))},touchstart:e,touchend:t}),"single"!==l.syncScrolling)&&s.bind({mouseover:i,mouseout:o,touchstart:i,touchend:o}),this},bindChangeEvent:function(){var i=this,e=this.cm,o=this.settings;return e.on("change",function(e,t){o.watch&&i.previewContainer.css("padding",o.autoHeight?"20px 20px 50px 40px":"20px"),c&&clearTimeout(c),o.onCmChange&&v.proxy(o.onCmChange,i)(),c=setTimeout(function(){i.save(),c=null},o.delay)}),this},loadedDisplay:function(e){e=e||!1;var t=this,i=this.editor,o=this.preview,n=this.settings;return this.containerMask.hide(),this.save(),n.watch&&o.show(),i.data("oldWidth",i.width()).data("oldHeight",i.height()),this.resize(),this.registerKeyMaps(),v(window).resize(function(){t.resize()}),this.bindScrollEvent().bindChangeEvent(),e||v.proxy(n.onload,this)(),this.state.loaded=!0,n.watch&&(this.save(),o.show()),this},width:function(e){return this.editor.css("width","number"==typeof e?e+"px":e),this.resize(),this},height:function(e){return this.editor.css("height","number"==typeof e?e+"px":e),this.resize(),this},resize:function(e,t){t=t||null;var i=this.state,o=this.editor,n=this.preview,r=this.toolbar,a=this.settings,s=this.codeMirror;return(e=e||null)&&o.css("width","number"==typeof e?e+"px":e),!a.autoHeight||i.fullscreen||i.preview?(t&&o.css("height","number"==typeof t?t+"px":t),i.fullscreen&&o.height(v(window).height()),a.toolbar&&!a.readOnly?s.css("margin-top",r.height()+1).height(o.height()-r.height()):s.css("margin-top",0).height(o.height())):(o.css("height","auto"),s.css("height","auto")),a.watch?(s.width(o.width()/2),n.width(i.preview?o.width():o.width()/2),this.previewContainer.css("padding",a.autoHeight?"20px 20px 50px 40px":"20px"),a.toolbar&&!a.readOnly?n.css("top",r.height()+1):n.css("top",0),!a.autoHeight||i.fullscreen||i.preview?(e=a.toolbar&&!a.readOnly?o.height()-r.height():o.height(),n.height(e)):n.height("")):(s.width(o.width()),n.hide()),i.loaded&&v.proxy(a.onresize,this)(),this},save:function(){var e,t,i,o=this,n=this.state,r=this.settings,a=this.cm,s=a.getValue(),l=this.previewContainer;return(null!==c||!r.watch&&n.preview)&&("gfm"!==r.mode&&"markdown"!==r.mode?this.markdownTextarea.val(s):(a.save(),(r.saveHTMLToTextarea||r.watch||!r.watch&&n.preview)&&(t=C.$marked,e=this.markdownToC=[],i=this.markedRendererOptions={toc:r.toc,tocm:r.tocm,tocStartLevel:r.tocStartLevel,pageBreak:r.pageBreak,taskList:r.taskList,emoji:r.emoji,tex:r.tex,atLink:r.atLink,emailLink:r.emailLink,flowChart:r.flowChart,sequenceDiagram:r.sequenceDiagram,previewCodeHighlight:r.previewCodeHighlight,mermaid:r.mermaid,mindMap:r.mindMap},i=this.markedOptions={renderer:C.markedRenderer(e,i),gfm:!0,tables:!0,breaks:!0,pedantic:!1,sanitize:!r.htmlDecode,smartLists:!0,smartypants:!0},t.setOptions(i),t=C.$marked.parse(s,i),r.debug&&console.info("cmValue",s,t),t=C.$filterXSS(t),this.markdownTextarea.text(s),a.save(),r.saveHTMLToTextarea&&this.htmlTextarea.text(t),r.watch||!r.watch&&n.preview)&&(l.html(t),this.previewCodeHighlight(),r.toc&&(s=(i=""===r.tocContainer?l:v(r.tocContainer)).find("."+this.classPrefix+"toc-menu"),i.attr("previewContainer",""===r.tocContainer?"true":"false"),""!==r.tocContainer&&0{C.loadPlugin(i,function(){C.loadPlugins[t]=r[t],e(r[t](a,n))},"head",o?r.author_ide_version:C.version)});C.loadPlugin(i,function(){C.loadPlugins[t]=r[t],r[t](a,n)},"head",o?r.author_ide_version:C.version)}else{if(n.proxy)return v.proxy(C.loadPlugins[t],this)(a,n);v.proxy(C.loadPlugins[t],this)(a,n)}return this},search:function(e){var t=this.settings;return t.searchReplace?t.readOnly||this.cm.execCommand(e||"find"):alert("Error: settings.searchReplace == false"),this},searchReplace:function(){return this.search("replace"),this},searchReplaceAll:function(){return this.search("replaceAll"),this}},C.fn.init.prototype=C.fn,C.dialogLockScreen=function(){(this.settings||{dialogLockScreen:!0}).dialogLockScreen&&(v("html,body").css("overflow","hidden"),this.resize())},C.positionDialog=function(e,t="center"){var i,o;switch(t){case"center":i=(v(window).width()-e.width())/2+"px",o=(v(window).height()-e.height())/2+"px";break;case"center-left":i=v(window).width()/4-e.width()/2+"px",o=(v(window).height()-e.height())/2+"px";break;case"center-right":i=3*v(window).width()/4-e.width()/2+"px",o=(v(window).height()-e.height())/2+"px";break;default:console.warn("Unsupported dialog position: "+t),i=(v(window).width()-e.width())/2+"px",o=(v(window).height()-e.height())/2+"px"}e.css({top:o,left:i})},C.dialogShowMask=function(e){var t=this.editor,i=this.settings||{dialogShowMask:!0};e.css({top:(v(window).height()-e.height())/2+"px",left:(v(window).width()-e.width())/2+"px"}),i.dialogShowMask&&t.children("."+this.classPrefix+"mask").css("z-index",parseInt(e.css("z-index"))-1).show()},C.toolbarHandlers={undo:function(){this.cm.undo()},redo:function(){this.cm.redo()},bold:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection("**"+i+"**"),""===i&&e.setCursor(t.line,t.ch+2)},del:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection("~~"+i+"~~"),""===i&&e.setCursor(t.line,t.ch+2)},italic:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection("*"+i+"*"),""===i&&e.setCursor(t.line,t.ch+1)},quote:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("> "+i),e.setCursor(t.line,t.ch+2)):e.replaceSelection("> "+i)},ucfirst:function(){var e=this.cm,t=e.getSelection(),i=e.listSelections();e.replaceSelection(C.firstUpperCase(t)),e.setSelections(i)},ucwords:function(){var e=this.cm,t=e.getSelection(),i=e.listSelections();e.replaceSelection(C.wordsFirstUpperCase(t)),e.setSelections(i)},uppercase:function(){var e=this.cm,t=e.getSelection(),i=e.listSelections();e.replaceSelection(t.toUpperCase()),e.setSelections(i)},lowercase:function(){var e=this.cm,t=(e.getCursor(),e.getSelection()),i=e.listSelections();e.replaceSelection(t.toLowerCase()),e.setSelections(i)},h1:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection(),o=new RegExp("^#{1}[ ]"),n=new RegExp("^#{1,6}[ ]");!0===o.test(i)?(i=i.replace(/^#{1}[ ]/,""),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection(i+"\n"),e.setCursor(t.line,t.ch-2)):(!0===n.test(i)&&(i=i.replace(/^#{1,6}[ ]/,"")),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection("# "+i+"\n"),e.setCursor(t.line,t.ch+2))},h2:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection(),o=new RegExp("^#{2}[ ]"),n=new RegExp("^#{1,6}[ ]");!0===o.test(i)?(i=i.replace(/^#{2}[ ]/,""),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection(i+"\n"),e.setCursor(t.line,t.ch-3)):(!0===n.test(i)&&(i=i.replace(/^#{1,6}[ ]/,"")),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection("## "+i+"\n"),e.setCursor(t.line,t.ch+3))},h3:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection(),o=new RegExp("^#{3}[ ]"),n=new RegExp("^#{1,6}[ ]");!0===o.test(i)?(i=i.replace(/^#{3}[ ]/,""),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection(i+"\n"),e.setCursor(t.line,t.ch-4)):(!0===n.test(i)&&(i=i.replace(/^#{1,6}[ ]/,"")),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection("### "+i+"\n"),e.setCursor(t.line,t.ch+4))},h4:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection(),o=new RegExp("^#{4}[ ]"),n=new RegExp("^#{1,6}[ ]");!0===o.test(i)?(i=i.replace(/^#{4}[ ]/,""),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection(i+"\n"),e.setCursor(t.line,t.ch-5)):(!0===n.test(i)&&(i=i.replace(/^#{1,6}[ ]/,"")),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection("#### "+i+"\n"),e.setCursor(t.line,t.ch+5))},h5:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection(),o=new RegExp("^#{5}[ ]"),n=new RegExp("^#{1,6}[ ]");!0===o.test(i)?(i=i.replace(/^#{5}[ ]/,""),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection(i+"\n"),e.setCursor(t.line,t.ch-6)):(!0===n.test(i)&&(i=i.replace(/^#{1,6}[ ]/,"")),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection("##### "+i+"\n"),e.setCursor(t.line,t.ch+6))},h6:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection(),o=new RegExp("^#{6}[ ]"),n=new RegExp("^#{1,6}[ ]");!0===o.test(i)?(i=i.replace(/^#{6}[ ]/,""),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection(i+"\n"),e.setCursor(t.line,t.ch-7)):(!0===n.test(i)&&(i=i.replace(/^#{1,6}[ ]/,"")),e.setSelection({line:t.line,ch:0},{line:t.line+1,ch:0}),e.replaceSelection("###### "+i+"\n"),e.setCursor(t.line,t.ch+7))},"list-ul":function(){var e=this.cm,t=e.getCursor(),i=e.getSelection(),o=new RegExp("^-{1}[ ]"),n=0;if(""===i)e.setCursor(t.line,0),e.replaceSelection("- "+i),e.setCursor(t.line,t.ch+2);else{for(var r=i.split("\n"),a=0,s=r.length;a/i),i=(null!==i&&(t=i[0],e=e.substr(t.length)),"default");return 0===e.indexOf("[info]")?(i="info",e=e.substr(6)):0===e.indexOf("[warning]")?(i="warning",e=e.substr(9)):0===e.indexOf("[success]")?(i="success",e=e.substr(9)):0===e.indexOf("[danger]")&&(i="danger",e=e.substr(8)),'
                            \n'+t+e+"
                            \n"},e.image=function(e,t,i){var o,n,r,a="",s="",l="";return e&&""!==e&&((o=document.createElement("a")).href=e,null!==(n=o.hash.match(/size=\d+x\d+/i))&&(o.hash=o.hash.replace(n[0],""),e=o.href,0<(n=n[0].replace("size=","").split("x"))[0]&&(a+=' width="'+n[0]+'"'),0","center"===(n=n[0].replace("align=",""))?s='

                            ':"left"===n?s='

                            ':"right"===n&&(s='

                            ')),s+''+i+'"+l},e.emoji=function(e){var t=(e=e.replace(C.regexs.emojiDatetime,function(e){return e.replace(/:/g,":")})).match(r);if(t&&a.emoji)for(var i=0,o=t.length;i'}else{var s=e.match(w),l=e.match(g);if(s)for(var c=0,h=s.length;c'}else{if(!l)return':'+o+':';for(var u=0,f=l.length;u'}}}});return e},e.atLink=function(e){return n.test(e)&&(a.atLink&&(e=(e=e.replace(i,function(e,t,i,o){return e.replace(/@/g,"_#_@_#_")})).replace(n,function(e,t){return''+e+""}).replace(/_#_@_#_/g,"@")),a.emailLink)?e.replace(o,function(e,t,i,o,n){return!t&&v.inArray(n,"jpg|jpeg|png|gif|webp|ico|icon|pdf".split("|"))<0?''+e+"":e}):e},e.link=function(e,t,i){if(this.options.sanitize){try{var o=decodeURIComponent(unescape(e)).replace(/[^\w:]/g,"").toLowerCase()}catch(e){return""}if(0===o.indexOf("javascript:"))return""}return 0===e.indexOf("@")?'':(o=''+i.replace(/@/g,"@")+""):(t&&(o+=' title="'+t+'"'),o+">"+i+""))},e.heading=function(e,t,i){var o=e,n=/\s*\]*)\>(.*)\<\/a\>\s*/;if(n.test(e)){for(var r=[],a=0,s=(e=e.split(/\]+)\>([^\>]*)\<\/a\>/)).length;a');return(l+='')+(n?this.atLink(this.emoji(o)):this.atLink(this.emoji(e)))+("")},e.pageBreak=function(e){return e=s.test(e)&&a.pageBreak?'


                            ':e},e.paragraph=function(e){var t=/\$\$(.+?)\$\$/g.test(e),i=/^(?!\$\$.+?(?:\$\$).+?\$\$)(\$\$(.+?)\$\$)$/.test(e),o=i?' class="'+C.classNames.tex+'"':"",n=(a.tocm?/^(\[TOC\]|\[TOCM\])$/:/^\[TOC\]$/).test(e),r=/^\[TOCM\]$/.test(e),t='
                            '+(e=!i&&t?e.replaceAll(/(\$\$(.+?)\$\$)/g,function(e,t,i){return''+i.replaceAll(/\/g,"")+""}):i?e.replace(/^(?!\$\$.+?(?:\$\$).+?\$\$)(\$\$(.+?)\$\$)$/,(e,t,i)=>i):e)+"
                            ";return n?r?'
                            '+t+"

                            ":t:s.test(e)?this.pageBreak(e):""+this.atLink(this.emoji(e))+"

                            \n"},e.code=function(e,t,i){if("seq"===t||"sequence"===t)return'
                            '+e+"
                            ";if("mermaid"===t){for(var o=(a="ABCDEFGHJKLMNOPQRSTUVWXYZabcdefhijlkmnopqrstuvwxyz012345678").length,n="",r=0;r<4;r++)n+=a.charAt(Math.floor(Math.random()*o));return'
                            '+e+"
                            "}if("flow"===t)return'
                            '+e+"
                            ";if("math"===t||"latex"===t||"katex"===t)return'

                            '+e+"

                            ";if(/^mindmap/i.test(t)){for(var a,o=(a="ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678").length,s="",l=t.split(">")[1],l=null!=l?l:150,r=0;r<9;r++)s+=a.charAt(Math.floor(Math.random()*o));return""+e+""}return"drawio"===t?'
                            '+decodeURIComponent(escape(window.atob(e)))+"
                            ":c.Renderer.prototype.code.apply(this,arguments)},e.tablecell=function(e,t){var i=t.header?"th":"td";return(t.align?"<"+i+' style="text-align:'+t.align+'">':"<"+i+">")+this.atLink(this.emoji(e))+"\n"},e.listitem=function(e){return a.taskList&&/^\s*\[[x\s]\]\s*/.test(e)?(e=e.replace(/^\s*\[\s\]\s*/,' ').replace(/^\s*\[x\]\s*/,' '),'
                          • '+this.atLink(this.emoji(e))+"
                          • "):"
                          • "+this.atLink(this.emoji(e))+"
                          • "},e.checkbox=function(e){return e?' ':' '},e},C.markdownToCRenderer=function(e,t,i,o){var n="",r=0,a=this.classPrefix;o=o||1;for(var s=0,l=e.length;s"):"
                        • ")+'
                        • '+c+"
                            ",r=h)}var u,f=t.find(".markdown-toc");return f.length<1&&"false"===t.attr("previewContainer")&&(u='
                            ',t.html(u=i?'
                            '+u+"
                            ":u),f=t.find(".markdown-toc")),i&&f.wrap('

                            '),f.html('
                              ').children(".markdown-toc-list").html(n.replace(/\r?\n?\\<\/ul\>/g,"")),f},C.tocDropdownMenu=function(e,a){a=a||"Table of Contents";var s=400,e=e.find("."+this.classPrefix+"toc-menu");return e.each(function(){var e=v(this),t=e.children(".markdown-toc"),o='',i=''+o+a+"",n=t.children("ul"),r=n.find("li");t.append(i),r.first().before("
                            • "+a+" "+o+"

                            • "),e.mouseover(function(){n.show(),r.each(function(){var e,t=v(this),i=t.children("ul");""===i.html()&&i.remove(),0]*)>([^>]*)","igm"),"")}void 0!==a&&(t=/\<(\w+)\s*([^\>]*)\>([^\>]*)\<\/(\w+)\>/gi,e="*"===a?e.replace(t,function(e,t,i,o,n){return"<"+t+">"+o+""}):"on*"===a?e.replace(t,function(e,t,i,o,n){var t=v("<"+t+">"+o+""),o=v(e)[0].attributes,r={},n=(v.each(o,function(e,t){'"'!==t.nodeName&&(r[t.nodeName]=t.nodeValue)}),v.each(r,function(e){0===e.indexOf("on")&&delete r[e]}),t.attr(r),void 0!==t[1]?v(t[1]).text():"");return t[0].outerHTML+n}):e.replace(t,function(e,t,i,o){var n=a.split(","),r=v(e);return r.html(o),v.each(n,function(e){r.attr(n[e],null)}),r[0].outerHTML}))}return e},C.markdownToHTML=function(e,t){C.$marked=marked;var i,o=v("#"+e),e=o.settings=v.extend(!0,{gfm:!0,toc:!0,tocm:!1,tocStartLevel:1,tocTitle:"目录",tocDropdown:!1,tocContainer:"",markdown:"",markdownSourceCode:!1,htmlDecode:!1,autoLoadKaTeX:!0,pageBreak:!0,atLink:!0,emailLink:!0,tex:!1,taskList:!1,emoji:!1,flowChart:!1,sequenceDiagram:!1,previewCodeHighlight:!0,mermaid:!0,mindMap:!0},t||{}),n=o.find("textarea"),t=(n.length<1&&(o.append(""),n=o.find("textarea")),void 0===e.markdown?n.val():e.markdown),r=[],a={toc:e.toc,tocm:e.tocm,tocStartLevel:e.tocStartLevel,taskList:e.taskList,emoji:e.emoji,tex:e.tex,pageBreak:e.pageBreak,atLink:e.atLink,emailLink:e.emailLink,flowChart:e.flowChart,sequenceDiagram:e.sequenceDiagram,mermaid:e.mermaid,mindMap:e.mindMap,previewCodeHighlight:e.previewCodeHighlight},a={renderer:C.markedRenderer(r,a),gfm:e.gfm,tables:!0,breaks:!0,pedantic:!1,sanitize:!e.htmlDecode,smartLists:!0,smartypants:!0},t=new String(t),a=marked.parse(t,a),a=C.$filterXSS(a),t=(e.markdownSourceCode?n.text(t):n.remove(),o.addClass("markdown-body "+this.classPrefix+"html-preview").append(a),""!==e.tocContainer?v(e.tocContainer):o);return""!==e.tocContainer&&t.attr("previewContainer",!1),e.toc&&(o.tocContainer=this.markdownToCRenderer(r,t,e.tocDropdown,e.tocStartLevel),(e.tocDropdown||0"),e[0]),e.find(".katex").css("font-size","1.6em")})},!e.autoLoadKaTeX||C.$katex||C.kaTeXLoaded?i():this.loadKaTeX(function(){C.$katex=katex,C.kaTeXLoaded=!0,i()})),e.mindMap&&o.find(".mindmap").each(function(){var e=v(this),e=window.markmap.transform(e.text().trim());window.markmap.markmap("svg#"+this.id,e)}),o.getMarkdown=function(){return n.val()},o},C.themes=["default","dark"],C.previewThemes=["default","dark"],C.editorThemes=["default","3024-day","3024-night","ambiance","ambiance-mobile","base16-dark","base16-light","blackboard","cobalt","eclipse","elegant","erlang-dark","lesser-dark","mbo","mdn-like","midnight","monokai","neat","neo","night","paraiso-dark","paraiso-light","pastel-on-dark","rubyblue","solarized","the-matrix","tomorrow-night-eighties","twilight","vibrant-ink","xq-dark","xq-light"],C.loadPlugins={},C.loadFiles={js:[],css:[],plugin:[]},C.loadPlugin=function(e,t,i,o){t=t||function(){},this.loadScript(e,function(){C.loadFiles.plugin.push(e),t()},i,o)},C.loadCSS=function(e,t,i,o=C.version){i=i||"head",t=t||function(){},o=o||C.version;var n=document.createElement("link");n.type="text/css",n.rel="stylesheet",n.onload=n.onreadystatechange=function(){C.loadFiles.css.push(e),t()},n.href=e+".css?editormd_version="+o,("head"===i?document.getElementsByTagName("head")[0]:document.body).appendChild(n)},C.isIE="Microsoft Internet Explorer"==navigator.appName,C.isIE8=C.isIE&&"8."==navigator.appVersion.match(/8./i),C.loadScript=function(e,t,i,o){i=i||"head",o=o||C.version,t=t||function(){};var n=null;(n=document.createElement("script")).id=e.replace(/[\./]+/g,"-"),n.type="text/javascript",n.src=e+".js?editormd_version="+o,C.isIE8?n.onreadystatechange=function(){!n.readyState||"loaded"!==n.readyState&&"complete"!==n.readyState||(n.onreadystatechange=null,C.loadFiles.js.push(e),t())}:n.onload=function(){C.loadFiles.js.push(e),t()},("head"===i?document.getElementsByTagName("head")[0]:document.body).appendChild(n)},C.katexURL={css:"https://cdn.bootcdn.net/ajax/libs/KaTeX/0.16.8/katex.min",jsmain:"https://cdn.bootcdn.net/ajax/libs/KaTeX/0.16.8/katex.min",jsauto:"https://cdn.bootcdn.net/ajax/libs/KaTeX/0.16.8/contrib/auto-render.min"},C.kaTeXLoaded=!1,C.loadKaTeX=function(e){C.loadCSS(C.katexURL.css,function(){C.loadScript(C.katexURL.jsmain,function(){C.loadScript(C.katexURL.jsauto,e||function(){})})})},C.lockScreen=function(e){v("html,body").css("overflow",e?"hidden":"")},C.createDialog=function(t){function e(){f.css({top:(v(window).height()-f.height())/2+"px",left:(v(window).width()-f.width())/2+"px"})}t=v.extend(!0,{name:"",width:420,height:"auto",title:"",drag:!0,closed:!0,content:"",mask:!0,maskStyle:{backgroundColor:"#fff",opacity:.1},removeDialogOnClose:!1,resizeableX:!1,resizeableY:!1,minWidth:0,minHeight:0,maxWidth:"none",maxHeight:"none",lockScreen:!0,footer:!0,buttons:!1},t);var r,a,i,s,o,n=this,l=this.editor,c=C.classPrefix,h=(new Date).getTime(),h=""===t.name?c+"dialog-"+h:t.name,d=C.mouseOrTouch,u='
                              ',f=(""!==t.title&&(u=(u+='
                              ")+''+t.title+"",t.closed&&(u+=''),u+="
                              "),u+='
                              '+t.content,!t.footer&&"string"!=typeof t.footer||(u+='"),l.append(u=(u=u+"
                              "+('
                              '))+('
                              ')+"
                              "),l.find("."+h));f.lockScreen=function(e){return t.lockScreen&&(v("html,body").css("overflow",e?"hidden":""),n.resize()),f},f.showMask=function(){return t.mask&&l.find("."+c+"mask").css(t.maskStyle).css("z-index",C.dialogZindex-1).show(),f},f.hideMask=function(){return t.mask&&l.find("."+c+"mask").hide(),f},f.loading=function(e){return f.find("."+c+"dialog-mask")[e?"show":"hide"](),f},f.lockScreen(!0).showMask(),f.show().css({zIndex:C.dialogZindex,border:C.isIE8?"1px solid #ddd":"",width:"number"==typeof t.width?t.width+"px":t.width,height:"number"==typeof t.height?t.height+"px":t.height,"min-width":"number"==typeof t.minWidth?t.minWidth+"px":t.minWidth,"min-height":"number"==typeof t.minHeight?t.minHeight+"px":t.minHeight,"max-width":"number"==typeof t.maxWidth?t.maxWidth+"px":t.maxWidth,"max-height":"number"==typeof t.maxHeight?t.maxHeight+"px":t.maxHeight,...t.resizeableX||t.resizeableY?{overflow:"hidden",resize:t.resizeableX&&t.resizeableY?"both":t.resizeableX?"horizontal":"vertical"}:{}});if(e(),v(window).resize(e),f.find("."+c+"dialog-close").bind(d("click","touchend"),function(){f.hide().lockScreen(!1).hideMask(),t.removeDialogOnClose&&f.remove()}),"object"==typeof t.buttons){var p,g=f.footer=f.find("."+c+"dialog-footer");for(p in t.buttons){var m=t.buttons[p],w=c+p+"-btn";g.append('"),m[1]=v.proxy(m[1],f),g.children("."+w).bind(d("click","touchend"),m[1])}}return""!==t.title&&t.drag&&(u=f.children("."+c+"dialog-header"),t.mask||u.bind(d("click","touchend"),function(){C.dialogZindex+=2,f.css("z-index",C.dialogZindex)}),u.mousedown(function(e){e=e||window.event,r=e.clientX-parseInt(f[0].style.left),a=e.clientY-parseInt(f[0].style.top),document.onmousemove=o}),i=function(e){e.removeClass(c+"user-unselect").off("selectstart")},s=function(e){e.addClass(c+"user-unselect").on("selectstart",function(e){return!1})},o=function(e){e=e||window.event;var t,i,o=parseInt(f[0].style.left),n=parseInt(f[0].style.top);0<=o?o+f.width()<=v(window).width()?t=e.clientX-r:(t=v(window).width()-f.width(),document.onmousemove=null):(t=0,document.onmousemove=null),0<=n?i=e.clientY-a:(i=0,document.onmousemove=null),document.onselectstart=function(){return!1},s(v("body")),s(f),f[0].style.left=t+"px",f[0].style.top=i+"px"},document.onmouseup=function(){i(v("body")),i(f),document.onselectstart=null,document.onmousemove=null},u.touchDraggable=function(){var i=null;this.bind("touchstart",function(e){var e=e.originalEvent,t=v(this).parent().position();i={x:e.changedTouches[0].pageX-t.left,y:e.changedTouches[0].pageY-t.top}}).bind("touchmove",function(e){e.preventDefault();e=e.originalEvent;v(this).parent().css({top:e.changedTouches[0].pageY-i.y,left:e.changedTouches[0].pageX-i.x})})},u.touchDraggable()),C.dialogZindex+=2,f},C.mouseOrTouch=function(e,t){t=t||"touchend";e=e||"click";try{document.createEvent("TouchEvent"),e=t}catch(e){}return e},C.dateFormat=function(e){e=e||"";function t(e){return e<10?"0"+e:e}var i=new Date,o=i.getFullYear(),n=o.toString().slice(2,4),r=t(i.getMonth()+1),a=t(i.getDate()),s=i.getDay(),l=t(i.getHours()),c=t(i.getMinutes()),h=t(i.getSeconds()),d=t(i.getMilliseconds()),u="",f=n+"-"+r+"-"+a,p=o+"-"+r+"-"+a,g=l+":"+c+":"+h;switch(e){case"UNIX Time":u=i.getTime();break;case"UTC":u=i.toUTCString();break;case"yy":u=n;break;case"year":case"yyyy":u=o;break;case"month":case"mm":u=r;break;case"cn-week-day":case"cn-wd":u="星期"+["日","一","二","三","四","五","六"][s];break;case"week-day":case"wd":u=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"][s];break;case"day":case"dd":u=a;break;case"hour":case"hh":u=l;break;case"min":case"ii":u=c;break;case"second":case"ss":u=h;break;case"ms":u=d;break;case"yy-mm-dd":u=f;break;case"yyyy-mm-dd":u=p;break;case"yyyy-mm-dd h:i:s ms":case"full + ms":u=p+" "+g+" "+d;break;default:u=p+" "+g}return u},C.getLine=function(e){return this.cm.getLine(e)},C}); \ No newline at end of file diff --git a/static/editor.md/languages/en.js b/static/editor.md/languages/en.js index 91fab27f..f5028183 100644 --- a/static/editor.md/languages/en.js +++ b/static/editor.md/languages/en.js @@ -5,8 +5,8 @@ description : "Open source online Markdown editor.", tocTitle : "Table of Contents", toolbar : { - undo : "Undo(Ctrl+Z)", - redo : "Redo(Ctrl+Y)", + undo : "Undo", + redo : "Redo", bold : "Bold", del : "Strikethrough", italic : "Italic", @@ -22,13 +22,13 @@ h6 : "Heading 6", "list-ul" : "Unordered list", "list-ol" : "Ordered list", - hr : "Horizontal rule", + hr : "Horizontal line", link : "Link", "reference-link" : "Reference link", image : "Image", - code : "Code inline", + code : "Inline code", "preformatted-text" : "Preformatted text / Code block (Tab indent)", - "code-block" : "Code block (Multi-languages)", + "code-block" : "Code block", table : "Tables", datetime : "Datetime", emoji : "Emoji", @@ -76,16 +76,18 @@ formatNotAllowed : "Error: only allows to upload pictures file, upload allowed image file format:" }, preformattedText : { - title : "Preformatted text / Codes", - emptyAlert : "Error: Please fill in the Preformatted text or content of the codes." + title : "Preformatted text / Codes", + emptyAlert : "Error: Please fill in the Preformatted text or content of the codes.", + placeholder : "coding now...." }, codeBlock : { - title : "Code block", + title : "Code block", selectLabel : "Languages: ", selectDefaultText : "select a code language...", otherLanguage : "Other languages", unselectedLanguageAlert : "Error: Please select the code language.", - codeEmptyAlert : "Error: Please fill in the code content." + codeEmptyAlert : "Error: Please fill in the code content.", + placeholder : "coding now...." }, htmlEntities : { title : "HTML Entities" @@ -95,13 +97,13 @@ } } }; - + exports.defaults.lang = lang; }; - + // CommonJS/Node.js if (typeof require === "function" && typeof exports === "object" && typeof module === "object") - { + { module.exports = factory; } else if (typeof define === "function") // AMD/CMD/Sea.js @@ -118,10 +120,10 @@ factory(editormd); }); } - } + } else { factory(window.editormd); } - -})(); \ No newline at end of file + +})(); diff --git a/static/editor.md/languages/zh-tw.js b/static/editor.md/languages/zh-tw.js index a7c0496a..4bb83aed 100644 --- a/static/editor.md/languages/zh-tw.js +++ b/static/editor.md/languages/zh-tw.js @@ -77,7 +77,8 @@ }, preformattedText : { title : "添加預格式文本或代碼塊", - emptyAlert : "錯誤:請填寫預格式文本或代碼的內容。" + emptyAlert : "錯誤:請填寫預格式文本或代碼的內容。", + placeholder : "coding now...." }, codeBlock : { title : "添加代碼塊", @@ -85,7 +86,8 @@ selectDefaultText : "請語言代碼語言", otherLanguage : "其他語言", unselectedLanguageAlert : "錯誤:請選擇代碼所屬的語言類型。", - codeEmptyAlert : "錯誤:請填寫代碼內容。" + codeEmptyAlert : "錯誤:請填寫代碼內容。", + placeholder : "coding now...." }, htmlEntities : { title : "HTML實體字符" @@ -124,4 +126,4 @@ factory(window.editormd); } -})(); \ No newline at end of file +})(); diff --git a/static/editor.md/lib/codemirror/AUTHORS b/static/editor.md/lib/codemirror/AUTHORS index 9d62d48e..bacc2b84 100644 --- a/static/editor.md/lib/codemirror/AUTHORS +++ b/static/editor.md/lib/codemirror/AUTHORS @@ -1,30 +1,51 @@ List of CodeMirror contributors. Updated before every release. +4oo4 4r2r Aaron Brooks Abdelouahab +Abdussalam Abdurrahman Abe Fettig +Abhishek Gahlot Adam Ahmed Adam King +Adam Particka +Adam Wight adanlobato Adán Lobato +Aditya Toshniwal Adrian Aichner +Adrian Heine +Adrian Kunz +Adrien Bertrand aeroson Ahmad Amireh Ahmad M. Zawawi +AHOHNMYC ahoward +Ajin Abraham Akeksandr Motsjonov +Alasdair Smith +AlbertHilb Alberto González Palomo Alberto Pose Albert Xing +Alexander Marks Alexander Pavlov Alexander Schepanovski Alexander Shvets Alexander Solovyov Alexandre Bique +Alex Churchill alexey-k Alex Piggott +Alf Eaton Aliaksei Chapyzhenka +Allen Sarkisyan +Ami Fischman +Amin Shali +Amin Ullah Khan +amshali@google.com Amsul amuntean Amy @@ -33,62 +54,142 @@ anaran AndersMad Anders Nawroth Anderson Mesquita +Anders Wåglund Andrea G Andreas Reischuck +Andres Taylor Andre von Houck +Andrew Cheng +Andrew Dassonville Andrey Fedorov Andrey Klyuchnikov Andrey Lushnikov +Andrey Shchekin Andy Joslin Andy Kimball Andy Li +Angelo angelozerr angelo.zerr@gmail.com Ankit Ankit Ahuja Ansel Santosa +Anthony Dugois +anthonygego +Anthony Gégo Anthony Grimes +Anthony Stewart Anton Kovalyov +antosarho +aoki ken +Apollo Zhu +AQNOUCH Mohammed +Aram Shatakhtsyan areos +Arnab Bose +Arnoud Buzing +Arsène von Wyss +Arthur Müller +Arun Narasani as3boyan +asolove +atelierbram AtomicPages LLC Atul Bhouraskar Aurelian Oancea +Axel Lewenhaupt +Baptiste Augrain +Barret Rennie +Bartosz Dziewoński +Basarat Ali Syed Bastian Müller +belhaj Bem Jones-Bey benbro +Benedikt Meurer +benhormann +Ben Hormann Beni Cherniavsky-Paskin Benjamin DeCoste +Benjamin Young Ben Keen +Ben Miller +Ben Mosher Bernhard Sirlinger Bert Chang +Bharad +BigBlueHat +Billiam Billy Moon +Bin Ni binny +Bjorn Hansen B Krishna Chaitanya Blaine G blukat29 +Bo boomyjee +Bo Peng borawjm +Boris K +Brad Metcalf Brandon Frohs Brandon Wamboldt +Bret Little Brett Zamir Brian Grinstead +BrianHung Brian Sletten +brrd Bruce Mitchener +Bruno Logerfo +Bryan Gin-ge Chen +Bryan Massoth +Caitlin Potter +Calin Barbat +callodacity +Camilo Roca +Casey Klebba +cBiscuit87 +César González Íñiguez +Chad Jolly Chandra Sekhar Pydi Charles Skelton Cheah Chu Yeow +Chhekur +Chris Colborne Chris Coyier +Chris Ford Chris Granger Chris Houseknecht +Chris Lohfink Chris Morgan +Chris Reeves +Chris Smith +Christian Gruen Christian Oyarzun Christian Petrov +Christian Sonne +christopherblaser Christopher Brown +Christopher Kramer +Christopher Mitchell +Christopher Pfohl +Christopher Wallis +Chunliang Lyu ciaranj +clone-it +clso CodeAnimal +CodeBitt +coderaiser +Cole R Lawrence ComFreek +Cornelius Weig +Cristian Prieto +Curran Kelleher Curtis Gagliardi +d8888 dagsta daines Dale Jung @@ -97,38 +198,74 @@ Dan Heberden Daniel, Dao Quang Minh Daniele Di Sarli Daniel Faust +Daniel Hanggi Daniel Huigens +Daniel Kesler Daniel KJ Daniel Neel Daniel Parnell +Daniel Thwaites +Danila Malyutin Danny Yoo darealshinji Darius Roberts +databricks-david-lewis +Dave Brondsema +Dave MacLachlan Dave Myers +David Barnett +David H. Bronke David Mignot David Pathakjee +David R. Myers +David Rodrigues +David Santana David Vázquez +David Whittington deebugger Deep Thought +Denis Ovsienko +Devin Abbott Devon Carew +Dick Choi +Diego Fernandez dignifiedquire Dimage Sapelkin +Dimitri Mitropoulos +Dinindu D. Wanniarachchi +dmaclach Dmitry Kiselyov domagoj412 Dominator008 Domizio Demichelis +Doug Blank Doug Wikle Drew Bratcher Drew Hintz Drew Khoury +Drini Cami Dror BG +Duncan Lilley duralog +dwelle +Ealton eborden +edoroshenko edsharp ekhaled +Elisée +Elmar Peise +elpnt +Emmanuel Schanzer Enam Mijbah Noor Eric Allam +Eric Bogard +Erik Demaine +Erik Welander +erosman eustas +Evan Minsk +Fabien Dubosson Fabien O'Carroll Fabio Zendhi Nagao Faiza Alsaied @@ -136,130 +273,281 @@ Fauntleroy fbuchinger feizhang365 Felipe Lalanne +Felipe S. S. Schneider Felix Raab +ficristo Filip Noetzel +Filip Stollár +Filype Pereira +finalfantasia flack -ForbesLindesay +Florian Felten +Fons van der Plas Forbes Lindesay +ForbesLindesay Ford_Lawnmower Forrest Oliphant +Franco Catena +Frank Seifferth Frank Wiegand +fraxx001 +Fredrik Borg +FUJI Goro (gfx) Gabriel Gheorghian Gabriel Horner Gabriel Nahmias galambalazs +Gary Sheng Gautam Mehta +Gavin Douglas gekkoe +Geordie Hall +George Stephanis +geowarin Gerard Braad Gergely Hegykozi +Germain Chazot Giovanni Calò +Glebov Boris Glenn Jorde Glenn Ruehle +goldsmcb Golevka +Google LLC Gordon Smith Grant Skinner greengiant Gregory Koberger +Grzegorz Mazur +Guang Li +Guan Gui Guillaume Massé Guillaume Massé +guraga Gustavo Rodrigues Hakan Tunc +Hanno Fellmann Hans Engel +Hanzhao Deng +Haoran Yu +Harald Schilly Hardest +Harshvardhan Gupta +Hasan Delibaş Hasan Karahan +Heanes +Hector Oswaldo Caballero +Hein Htat +Hélio +Hendrik Erz +Hendrik Wallbaum +Henrik Haugbølle Herculano Campos +hidaiy Hiroyuki Makino hitsthings Hocdoc +Howard +Howard Jing +Hugues Malphettes Ian Beck +Ian Davies Ian Dickinson +Ian Henderson +ianhi +Ian Rose Ian Wehrman Ian Wetherbee Ice White ICHIKAWA, Yuji +idleberg +Igor Petruk ilvalle +Ilya Kharlamov +Ilya Zverev Ingo Richter +Intervue Irakli Gozalishvili +iteriani Ivan Kurnosov +Ivoah +Jack Douglas Jacob Lee +Jaimin +Jake Peyser +Jake Zimmerman +Jakob Kummerow Jakob Miland +Jakub T. Jankiewicz Jakub Vrana Jakub Vrána James Campos +James Cockshull +James Howard James Thorne Jamie Hill +Jamie Morris +Janice Leung Jan Jongboom jankeromnes Jan Keromnes Jan Odvarko +Jan Schär Jan T. Sott +Jared Dean Jared Forsyth +Jared Jacobs Jason Jason Barnabe Jason Grout +Jason Heeris Jason Johnston Jason San Jose Jason Siefken +Jayaprabhakar +Jay Contonio Jaydeep Solanki Jean Boussier +Jeff Blaisdell +Jeff Hanke +Jeff Jenkins jeffkenton Jeff Pickhardt jem (graphite) Jeremy Parmenter +Jim +Jim Avery +jkaplon +JobJob +jochenberger Jochen Berger +Joel Einbinder +joelpinheiro +Joe Predham +joewalsh Johan Ask +Johannes +John Chen John Connor +John-David Dalton +John Engler John Lees-Miller +John Ryan John Snelson +johnspiegel John Van Der Loo +Jon Ander Peñalba +Jonas Döbertin +Jonas Helfer +Jonathan Dierksen +Jonathan Hart Jonathan Malmaud +Jonathan Rascher +Jon Gacnik jongalloway Jon Malmaud Jon Sangster +Joo Joost-Wim Boekesteijn +José dBruxelles Joseph Pecoraro +Josh Barnes +Josh Cohen +Josh Soref Joshua Newman Josh Watzman jots +Joy Zhong jsoojeon +ju1ius Juan Benavides Romero Jucovschi Constantin Juho Vuori +Julien CROUZET +Julien Rebetez +Justin Andresen Justin Hileman jwallers@gmail.com kaniga +karevn +Karol +Kaushik Kulkarni +Kayur Patel +Kazuhisa Ishizaka +Kazuhito Hokamura +kcwiakala +Kees de Kooter +Keldan Chapman +Kenan Christian Dimas Ken Newman +ken restivo Ken Rockot +Kevin Earls +Kevin Kwok +Kevin Muret Kevin Sawicki Kevin Ushey +Kier Darby +Kim-Anh Tran Klaus Silveira Koh Zi Han, Cliff komakino +Konstantin Chernenko Konstantin Lopuhin koops +Kris Ciccarello ks-ifware kubelsmieci +kvncp KwanEsq +Kyle Kelley +KyleMcNutt +LaKing Lanfei Lanny +laobubu Laszlo Vidacs +leaf leaf corcoran +Lemmon +Leo Baschy Leonid Khachaturov Leon Sorokin Leonya Khachaturov +lexer2086 Liam Newman +Libo Cannici +Lior Goldberg +Lior Shub +lishid +LloydMilligan LM lochel +Lonnie Abelbeck +Lorenzo Simionato Lorenzo Stoakes +Louis Mauchet +Luca Fabbri +Lucas Buchala Luciano Longo +Luciano Santana +Lu Fangjian +Łukasz Wielgus +Luke Browning +Luke Granger-Brown Luke Stagner lynschinzer +M1cha +Madhura Jayaratne Maksim Lin Maksym Taran Malay Majithia +Manideep Manuel Rego Casasnovas Marat Dreizin Marcel Gerber +Marcelo Camargo +Marc Espín Marco Aurélio Marco Munizaga Marcus Bointon @@ -267,18 +555,38 @@ Marek Rudnicki Marijn Haverbeke Mário Gonçalves Mario Pietsch +Mark Anderson +Mark Boyes +Mark Dalgleish +Mark Hamstra Mark Lentczner Marko Bonaci +Mark Peace +Markus Bordihn +Markus Olsson Martin Balek Martín Gaitán Martin Hasoň +Martin Hunt +Martin Laine +Martin Zagora +Masahiro MATAYOSHI Mason Malone Mateusz Paprocki Mathias Bynens mats cronqvist +Matt Diehl +Matt Gaide +Matthew Bauer Matthew Beale +Matthew Casperson +matthewhayes +Matthew Rathbone +Matthew Suozzo Matthias Bussonnier Matthias BUSSONNIER +Mattia Astorino +Matt MacPherson Matt McDonald Matt Pass Matt Sacks @@ -286,151 +594,362 @@ mauricio Maximilian Hils Maxim Kraev Max Kirsch +Max Schaefer +Max Wu Max Xiantu mbarkhau +McBrainy +mce2 +Mélanie Chauvel +melpon +meshuamam Metatheos Micah Dubinko +Michael +Michael Chirico +Michael Goderbauer +Michael Grey +Michael Kaminsky Michael Lehenbauer +Michael Wadman +Michael Walker Michael Zhou +Michal Čihař +Michal Dorner +Michal Kapiczynski Mighty Guava Miguel Castillo mihailik +Mika Andrianarijaona Mike +Mike Bostock Mike Brevoort Mike Diaz Mike Ivanov Mike Kadin +Mike Kobit +Milan Szekely +MinJune Kim MinRK Miraculix87 misfo +mkaminsky11 mloginov +mlsad3 +Moritz Schubotz (physikerwelt) Moritz Schwörer +Moshe Wajnberg mps +ms mtaran-google +Mu-An ✌️ Chiou +Mu-An Chiou +Mykola Martynovets +mzabuawala Narciso Jaramillo +nathanlesage Nathan Williams ndr +Neil Anderson +neon-dev nerbert +NetworkNode nextrevision ngn nguillaumin Ng Zhi An Nicholas Bollweg Nicholas Bollweg (Nick) +NickKolok +Nick Kreeger Nick Small +Nicolas Chevobbe +Nicolas Kick +Nicolò Ribaudo Niels van Groningen nightwing Nikita Beloglazov Nikita Vasilyev +Nikolaj Kappler Nikolay Kostov nilp0inter +Nils Knappmeier +Nina Pypchenko Nisarg Jhaveri nlwillia +noragrossman Norman Rzepka +Nouzbe +Oleksandr Yakovenko +Olivia Ytterbrink +Ondřej Mirtes +Opender Singh +opl- +Oreoluwa Onatemowo +orionlee +oscar.lofwenhamn +Oskar Segersvärd +ossdev +overdodactyl pablo +pabloferz +Pablo Zubieta +paddya Page +paladox Panupong Pasupat paris +Paris +Paris Kasidiaris Patil Arpith +Patrick Kettner Patrick Stoica Patrick Strawderman Paul Garvin Paul Ivanov +Paul Masson +Paul Schmidt +Pavel Pavel Feldman +Pavel Petržela Pavel Strashkin Paweł Bartkiewicz peteguhl +peter Peter Flynn peterkroon Peter Kroon +Peter László +Phil DeJarnett +Philipp A +Philipp Markovics +Philip Stadermann +Pi Delport +Pierre Gerold +Pieter Ouwerkerk +Piyush +Pontus Melke prasanthj Prasanth J +Prayag Verma +prendota +Prendota +ps173 +Qiang Li +quiddity-wp Radek Piórkowski Rahul +Rahul Anand +ramwin1 Randall Mason Randy Burden Randy Edmunds +Randy Luecke +Raphael Amorim Rasmus Erik Voel Jensen +Rasmus Schultz +raymondf +Raymond Hill +ray ratchup Ray Ratchup +Remi Nyborg +Renaud Durlin +Reynold Xin +Richard Denton Richard van der Meer Richard Z.H. Wang +Rishi Goomar +Robert Brignull Robert Crossfield +Robert Martin Roberto Abdelkader Martínez Pérez robertop23 +Roberto Vidal Robert Plummer +Roman Frolov +Roman Janusz +Rongjian Zhang +Rrandom +Rrrandom +Ruslan Bekenev Ruslan Osmanov +rvalavicius +Ryan Pangrle +Ryan Petrello Ryan Prior +ryu-sato sabaca +Sachin Gupta +Sam Lee +Sam Rawlins Samuel Ainsworth +Sam Wilson sandeepshetty Sander AKA Redsandro +Sander Verweij santec +Sarah McAlear and Wenlin Zhang Sascha Peilicke +Sasha Varlamov +satamas satchmorun sathyamoorthi +Saul Costa +S. Chris Colbert SCLINIC\jdecker Scott Aikin +Scott Feeney Scott Goodhew +Seb35 +Sebastian Ślepowroński +Sebastian Wilzbach Sebastian Zaha +Seren D +Sergey Goder +Sergey Tselovalnikov +Se-Won Kim +Shane Liesegang shaund shaun gilchrist Shawn A +Shea Bunge sheopory +Shil S Shiv Deepak Shmuel Englard Shubham Jain +Siamak Mokhtari +Siddhartha Gunti silverwind +Simon Edwards +Simon Huber +sinkuu +Slava Rozhnev snasa soliton4 sonson +Sorab Bisht spastorelli srajanpaliwal Stanislav Oaserele +stan-z Stas Kobzar +stasoid Stefan Borsje Steffen Beyer +Steffen Bruchmann +Steffen Kowalski +Stephane Moore +Stephen Lavelle +Steve Champagne +Steve Hoover +Steven Yung Steve O'Hara +stockiNail stoskov +Stryder Crown +Stu Kennedy +Sungho Kim +sverweij Taha Jahangir +takamori +Tako Schotanus Takuji Shimokawa +Takuya Matsuyama Tarmil +T. Brandon Ashley +TDaglis +Teja tel +Tentone tfjgeorge Thaddee Tyl +thanasis TheHowl +themrmax +Thiemo Kreuz think +Thomas Brouard Thomas Dvornik +Thomas Kluyver +thomasmaclean Thomas Schmid Tim Alby Tim Baumann +Tim Gates +Tim Nguyen Timothy Farrell +Timothy Gu Timothy Hatcher +Tim van der Lippe +Tobias Bertelsen TobiasBg +Todd Berman +Todd Kennedy +tokafew420 Tomas-A Tomas Varaneckas Tom Erik Støwer +Tom Klancer Tom MacWright +Tom McLaughlin Tony Jian +tophf +Torben Bundt +Torgeir Thoresen +totalamd Travis Heppe Triangle717 +Tristan Tarrant +TSUYUSATO Kitsune +Tugrul Elmas twifkak +Tyler Long +Tyler Makaro +Vadim Dyachenko +Vadzim Ramanenka +Vaibhav Sagar +vamshi.revu +VapidWorx Vestimir Markov vf +Victor Bocharsky Vincent Woo Volker Mische +vtripolitakis +wdouglashall +Weiyan Shao wenli +Wes Cossick Wesley Wiser +Weston Ruter Will Binns-Smith +Will Cassella +Will Dean +Will Hernandez +William Desportes William Jamieson William Stein Willy Wojtek Ptak +wonderboyjon +Wu Cheng-Han Xavier Mendez +Yang Guo +Yash Singh +Yash-Singh1 Yassin N. Hassan YNH Webdev +yoongu Yunchi Luo Yuvi Panda +Yvonnick Esnault +Zac Anger Zachary Dremann +ZeeshanNoor +Zeno Rocha Zhang Hao +Ziv +zoobestik zziuni 魏鹏刚 diff --git a/static/editor.md/lib/codemirror/LICENSE b/static/editor.md/lib/codemirror/LICENSE index d21bbea5..ff7db4b9 100644 --- a/static/editor.md/lib/codemirror/LICENSE +++ b/static/editor.md/lib/codemirror/LICENSE @@ -1,4 +1,6 @@ -Copyright (C) 2014 by Marijn Haverbeke and others +MIT License + +Copyright (C) 2017 by Marijn Haverbeke and others Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/static/editor.md/lib/codemirror/README.md b/static/editor.md/lib/codemirror/README.md index bc6e7f5c..39c24686 100644 --- a/static/editor.md/lib/codemirror/README.md +++ b/static/editor.md/lib/codemirror/README.md @@ -1,12 +1,47 @@ # CodeMirror -[![Build Status](https://travis-ci.org/codemirror/CodeMirror.svg)](https://travis-ci.org/codemirror/CodeMirror) -[![NPM version](https://img.shields.io/npm/v/codemirror.svg)](https://www.npmjs.org/package/codemirror) -[Funding status: ![maintainer happiness](https://marijnhaverbeke.nl/fund/status_s.png)](https://marijnhaverbeke.nl/fund/) -CodeMirror is a JavaScript component that provides a code editor in -the browser. When a mode is available for the language you are coding -in, it will color your code, and optionally help with indentation. +[![Build Status](https://github.com/codemirror/codemirror/workflows/main/badge.svg)](https://github.com/codemirror/codemirror/actions) +[![NPM version](https://img.shields.io/npm/v/codemirror.svg)](https://www.npmjs.org/package/codemirror) -The project page is http://codemirror.net -The manual is at http://codemirror.net/doc/manual.html -The contributing guidelines are in [CONTRIBUTING.md](https://github.com/codemirror/CodeMirror/blob/master/CONTRIBUTING.md) +CodeMirror is a versatile text editor implemented in JavaScript for +the browser. It is specialized for editing code, and comes with over +100 language modes and various addons that implement more advanced +editing functionality. Every language comes with fully-featured code +and syntax highlighting to help with reading and editing complex code. + +A rich programming API and a CSS theming system are available for +customizing CodeMirror to fit your application, and extending it with +new functionality. + +You can find more information (and the +[manual](https://codemirror.net/doc/manual.html)) on the [project +page](https://codemirror.net). For questions and discussion, use the +[discussion forum](https://discuss.codemirror.net/). + +See +[CONTRIBUTING.md](https://github.com/codemirror/CodeMirror/blob/master/CONTRIBUTING.md) +for contributing guidelines. + +The CodeMirror community aims to be welcoming to everybody. We use the +[Contributor Covenant +(1.1)](http://contributor-covenant.org/version/1/1/0/) as our code of +conduct. + +### Installation + +Either get the [zip file](https://codemirror.net/codemirror.zip) with +the latest version, or make sure you have [Node](https://nodejs.org/) +installed and run: + + npm install codemirror + +**NOTE**: This is the source repository for the library, and not the +distribution channel. Cloning it is not the recommended way to install +the library, and will in fact not work unless you also run the build +step. + +### Quickstart + +To build the project, make sure you have Node.js installed (at least version 6) +and then `npm install`. To run, just open `index.html` in your +browser (you don't need to run a webserver). Run the tests with `npm test`. diff --git a/static/editor.md/lib/codemirror/addon/comment/comment.js b/static/editor.md/lib/codemirror/addon/comment/comment.js index 2dd114d3..dac48d03 100644 --- a/static/editor.md/lib/codemirror/addon/comment/comment.js +++ b/static/editor.md/lib/codemirror/addon/comment/comment.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -13,7 +13,7 @@ var noOptions = {}; var nonWS = /[^\s\u00a0]/; - var Pos = CodeMirror.Pos; + var Pos = CodeMirror.Pos, cmp = CodeMirror.cmpPos; function firstNonWS(str) { var found = str.search(nonWS); @@ -21,26 +21,45 @@ } CodeMirror.commands.toggleComment = function(cm) { - var minLine = Infinity, ranges = cm.listSelections(), mode = null; + cm.toggleComment(); + }; + + CodeMirror.defineExtension("toggleComment", function(options) { + if (!options) options = noOptions; + var cm = this; + var minLine = Infinity, ranges = this.listSelections(), mode = null; for (var i = ranges.length - 1; i >= 0; i--) { var from = ranges[i].from(), to = ranges[i].to(); if (from.line >= minLine) continue; if (to.line >= minLine) to = Pos(minLine, 0); minLine = from.line; if (mode == null) { - if (cm.uncomment(from, to)) mode = "un"; - else { cm.lineComment(from, to); mode = "line"; } + if (cm.uncomment(from, to, options)) mode = "un"; + else { cm.lineComment(from, to, options); mode = "line"; } } else if (mode == "un") { - cm.uncomment(from, to); + cm.uncomment(from, to, options); } else { - cm.lineComment(from, to); + cm.lineComment(from, to, options); } } - }; + }); + + // Rough heuristic to try and detect lines that are part of multi-line string + function probablyInsideString(cm, pos, line) { + return /\bstring\b/.test(cm.getTokenTypeAt(Pos(pos.line, 0))) && !/^[\'\"\`]/.test(line) + } + + function getMode(cm, pos) { + var mode = cm.getMode() + return mode.useInnerComments === false || !mode.innerMode ? mode : cm.getModeAt(pos) + } CodeMirror.defineExtension("lineComment", function(from, to, options) { if (!options) options = noOptions; - var self = this, mode = self.getModeAt(from); + var self = this, mode = getMode(self, from); + var firstLine = self.getLine(from.line); + if (firstLine == null || probablyInsideString(self, from, firstLine)) return; + var commentString = options.lineComment || mode.lineComment; if (!commentString) { if (options.blockCommentStart || mode.blockCommentStart) { @@ -49,15 +68,21 @@ } return; } - var firstLine = self.getLine(from.line); - if (firstLine == null) return; + var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1); var pad = options.padding == null ? " " : options.padding; var blankLines = options.commentBlankLines || from.line == to.line; self.operation(function() { if (options.indent) { - var baseString = firstLine.slice(0, firstNonWS(firstLine)); + var baseString = null; + for (var i = from.line; i < end; ++i) { + var line = self.getLine(i); + var whitespace = line.slice(0, firstNonWS(line)); + if (baseString == null || baseString.length > whitespace.length) { + baseString = whitespace; + } + } for (var i = from.line; i < end; ++i) { var line = self.getLine(i), cut = baseString.length; if (!blankLines && !nonWS.test(line)) continue; @@ -75,7 +100,7 @@ CodeMirror.defineExtension("blockComment", function(from, to, options) { if (!options) options = noOptions; - var self = this, mode = self.getModeAt(from); + var self = this, mode = getMode(self, from); var startString = options.blockCommentStart || mode.blockCommentStart; var endString = options.blockCommentEnd || mode.blockCommentEnd; if (!startString || !endString) { @@ -83,6 +108,7 @@ self.lineComment(from, to, options); return; } + if (/\bcomment\b/.test(self.getTokenTypeAt(Pos(from.line, 0)))) return var end = Math.min(to.line, self.lastLine()); if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end; @@ -100,7 +126,9 @@ if (i != end || lastLineHasText) self.replaceRange(lead + pad, Pos(i, 0)); } else { + var atCursor = cmp(self.getCursor("to"), to) == 0, empty = !self.somethingSelected() self.replaceRange(endString, to); + if (atCursor) self.setSelection(empty ? to : self.getCursor("from"), to) self.replaceRange(startString, from); } }); @@ -108,7 +136,7 @@ CodeMirror.defineExtension("uncomment", function(from, to, options) { if (!options) options = noOptions; - var self = this, mode = self.getModeAt(from); + var self = this, mode = getMode(self, from); var end = Math.min(to.ch != 0 || to.line == from.line ? to.line : to.line - 1, self.lastLine()), start = Math.min(from.line, end); // Try finding line comments @@ -120,7 +148,7 @@ var line = self.getLine(i); var found = line.indexOf(lineString); if (found > -1 && !/comment/.test(self.getTokenTypeAt(Pos(i, found + 1)))) found = -1; - if (found == -1 && (i != end || i == start) && nonWS.test(line)) break lineComment; + if (found == -1 && nonWS.test(line)) break lineComment; if (found > -1 && nonWS.test(line.slice(0, found))) break lineComment; lines.push(line); } @@ -142,15 +170,15 @@ var endString = options.blockCommentEnd || mode.blockCommentEnd; if (!startString || !endString) return false; var lead = options.blockCommentLead || mode.blockCommentLead; - var startLine = self.getLine(start), endLine = end == start ? startLine : self.getLine(end); - var open = startLine.indexOf(startString), close = endLine.lastIndexOf(endString); - if (close == -1 && start != end) { - endLine = self.getLine(--end); - close = endLine.lastIndexOf(endString); - } - if (open == -1 || close == -1 || - !/comment/.test(self.getTokenTypeAt(Pos(start, open + 1))) || - !/comment/.test(self.getTokenTypeAt(Pos(end, close + 1)))) + var startLine = self.getLine(start), open = startLine.indexOf(startString) + if (open == -1) return false + var endLine = end == start ? startLine : self.getLine(end) + var close = endLine.indexOf(endString, end == start ? open + startString.length : 0); + var insideStart = Pos(start, open + 1), insideEnd = Pos(end, close + 1) + if (close == -1 || + !/comment/.test(self.getTokenTypeAt(insideStart)) || + !/comment/.test(self.getTokenTypeAt(insideEnd)) || + self.getRange(insideStart, insideEnd, "\n").indexOf(endString) > -1) return false; // Avoid killing block comments completely outside the selection. diff --git a/static/editor.md/lib/codemirror/addon/comment/continuecomment.js b/static/editor.md/lib/codemirror/addon/comment/continuecomment.js index b11d51e6..7ca1b4a9 100644 --- a/static/editor.md/lib/codemirror/addon/comment/continuecomment.js +++ b/static/editor.md/lib/codemirror/addon/comment/continuecomment.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -9,46 +9,69 @@ else // Plain browser env mod(CodeMirror); })(function(CodeMirror) { - var modes = ["clike", "css", "javascript"]; - - for (var i = 0; i < modes.length; ++i) - CodeMirror.extendMode(modes[i], {blockCommentContinue: " * "}); - + var nonspace = /\S/g; + var repeat = String.prototype.repeat || function (n) { return Array(n + 1).join(this); }; function continueComment(cm) { if (cm.getOption("disableInput")) return CodeMirror.Pass; var ranges = cm.listSelections(), mode, inserts = []; for (var i = 0; i < ranges.length; i++) { - var pos = ranges[i].head, token = cm.getTokenAt(pos); - if (token.type != "comment") return CodeMirror.Pass; - var modeHere = CodeMirror.innerMode(cm.getMode(), token.state).mode; + var pos = ranges[i].head + if (!/\bcomment\b/.test(cm.getTokenTypeAt(pos))) return CodeMirror.Pass; + var modeHere = cm.getModeAt(pos) if (!mode) mode = modeHere; else if (mode != modeHere) return CodeMirror.Pass; - var insert = null; - if (mode.blockCommentStart && mode.blockCommentContinue) { - var end = token.string.indexOf(mode.blockCommentEnd); - var full = cm.getRange(CodeMirror.Pos(pos.line, 0), CodeMirror.Pos(pos.line, token.end)), found; - if (end != -1 && end == token.string.length - mode.blockCommentEnd.length && pos.ch >= end) { - // Comment ended, don't continue it - } else if (token.string.indexOf(mode.blockCommentStart) == 0) { - insert = full.slice(0, token.start); - if (!/^\s*$/.test(insert)) { - insert = ""; - for (var j = 0; j < token.start; ++j) insert += " "; + var insert = null, line, found; + var blockStart = mode.blockCommentStart, lineCmt = mode.lineComment; + if (blockStart && mode.blockCommentContinue) { + line = cm.getLine(pos.line); + var end = line.lastIndexOf(mode.blockCommentEnd, pos.ch - mode.blockCommentEnd.length); + // 1. if this block comment ended + // 2. if this is actually inside a line comment + if (end != -1 && end == pos.ch - mode.blockCommentEnd.length || + lineCmt && (found = line.lastIndexOf(lineCmt, pos.ch - 1)) > -1 && + /\bcomment\b/.test(cm.getTokenTypeAt({line: pos.line, ch: found + 1}))) { + // ...then don't continue it + } else if (pos.ch >= blockStart.length && + (found = line.lastIndexOf(blockStart, pos.ch - blockStart.length)) > -1 && + found > end) { + // reuse the existing leading spaces/tabs/mixed + // or build the correct indent using CM's tab/indent options + if (nonspaceAfter(0, line) >= found) { + insert = line.slice(0, found); + } else { + var tabSize = cm.options.tabSize, numTabs; + found = CodeMirror.countColumn(line, found, tabSize); + insert = !cm.options.indentWithTabs ? repeat.call(" ", found) : + repeat.call("\t", (numTabs = Math.floor(found / tabSize))) + + repeat.call(" ", found - tabSize * numTabs); } - } else if ((found = full.indexOf(mode.blockCommentContinue)) != -1 && - found + mode.blockCommentContinue.length > token.start && - /^\s*$/.test(full.slice(0, found))) { - insert = full.slice(0, found); - } - if (insert != null) insert += mode.blockCommentContinue; - } - if (insert == null && mode.lineComment && continueLineCommentEnabled(cm)) { - var line = cm.getLine(pos.line), found = line.indexOf(mode.lineComment); - if (found > -1) { + } else if ((found = line.indexOf(mode.blockCommentContinue)) > -1 && + found <= pos.ch && + found <= nonspaceAfter(0, line)) { insert = line.slice(0, found); - if (/\S/.test(insert)) insert = null; - else insert += mode.lineComment + line.slice(found + mode.lineComment.length).match(/^\s*/)[0]; + } + if (insert != null) insert += mode.blockCommentContinue + } + if (insert == null && lineCmt && continueLineCommentEnabled(cm)) { + if (line == null) line = cm.getLine(pos.line); + found = line.indexOf(lineCmt); + // cursor at pos 0, line comment also at pos 0 => shift it down, don't continue + if (!pos.ch && !found) insert = ""; + // continue only if the line starts with an optional space + line comment + else if (found > -1 && nonspaceAfter(0, line) >= found) { + // don't continue if there's only space(s) after cursor or the end of the line + insert = nonspaceAfter(pos.ch, line) > -1; + // but always continue if the next line starts with a line comment too + if (!insert) { + var next = cm.getLine(pos.line + 1) || '', + nextFound = next.indexOf(lineCmt); + insert = nextFound > -1 && nonspaceAfter(0, next) >= nextFound || null; + } + if (insert) { + insert = line.slice(0, found) + lineCmt + + line.slice(found + lineCmt.length).match(/^\s*/)[0]; + } } } if (insert == null) return CodeMirror.Pass; @@ -61,6 +84,12 @@ }); } + function nonspaceAfter(ch, str) { + nonspace.lastIndex = ch; + var m = nonspace.exec(str); + return m ? m.index : -1; + } + function continueLineCommentEnabled(cm) { var opt = cm.getOption("continueComments"); if (opt && typeof opt == "object") diff --git a/static/editor.md/lib/codemirror/addon/dialog/dialog.css b/static/editor.md/lib/codemirror/addon/dialog/dialog.css index 2e7c0fc9..677c0783 100644 --- a/static/editor.md/lib/codemirror/addon/dialog/dialog.css +++ b/static/editor.md/lib/codemirror/addon/dialog/dialog.css @@ -1,11 +1,11 @@ .CodeMirror-dialog { position: absolute; left: 0; right: 0; - background: white; + background: inherit; z-index: 15; padding: .1em .8em; overflow: hidden; - color: #333; + color: inherit; } .CodeMirror-dialog-top { diff --git a/static/editor.md/lib/codemirror/addon/dialog/dialog.js b/static/editor.md/lib/codemirror/addon/dialog/dialog.js index e0e8ad4e..5f1f4aa4 100644 --- a/static/editor.md/lib/codemirror/addon/dialog/dialog.js +++ b/static/editor.md/lib/codemirror/addon/dialog/dialog.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE // Open simple dialogs on top of an editor. Relies on dialog.css. @@ -25,6 +25,7 @@ } else { // Assuming it's a detached DOM element. dialog.appendChild(template); } + CodeMirror.addClass(wrap, 'dialog-opened'); return dialog; } @@ -47,6 +48,7 @@ } else { if (closed) return; closed = true; + CodeMirror.rmClass(dialog.parentNode, 'dialog-opened'); dialog.parentNode.removeChild(dialog); me.focus(); @@ -56,9 +58,13 @@ var inp = dialog.getElementsByTagName("input")[0], button; if (inp) { + inp.focus(); + if (options.value) { inp.value = options.value; - inp.select(); + if (options.selectValueOnOpen !== false) { + inp.select(); + } } if (options.onInput) @@ -76,9 +82,9 @@ if (e.keyCode == 13) callback(inp.value, e); }); - if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close); - - inp.focus(); + if (options.closeOnBlur !== false) CodeMirror.on(dialog, "focusout", function (evt) { + if (evt.relatedTarget !== null) close(); + }); } else if (button = dialog.getElementsByTagName("button")[0]) { CodeMirror.on(button, "click", function() { close(); @@ -100,6 +106,7 @@ function close() { if (closed) return; closed = true; + CodeMirror.rmClass(dialog.parentNode, 'dialog-opened'); dialog.parentNode.removeChild(dialog); me.focus(); } @@ -139,6 +146,7 @@ if (closed) return; closed = true; clearTimeout(doneTimer); + CodeMirror.rmClass(dialog.parentNode, 'dialog-opened'); dialog.parentNode.removeChild(dialog); } diff --git a/static/editor.md/lib/codemirror/addon/display/autorefresh.js b/static/editor.md/lib/codemirror/addon/display/autorefresh.js new file mode 100644 index 00000000..37014dc3 --- /dev/null +++ b/static/editor.md/lib/codemirror/addon/display/autorefresh.js @@ -0,0 +1,47 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: https://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.defineOption("autoRefresh", false, function(cm, val) { + if (cm.state.autoRefresh) { + stopListening(cm, cm.state.autoRefresh) + cm.state.autoRefresh = null + } + if (val && cm.display.wrapper.offsetHeight == 0) + startListening(cm, cm.state.autoRefresh = {delay: val.delay || 250}) + }) + + function startListening(cm, state) { + function check() { + if (cm.display.wrapper.offsetHeight) { + stopListening(cm, state) + if (cm.display.lastWrapHeight != cm.display.wrapper.clientHeight) + cm.refresh() + } else { + state.timeout = setTimeout(check, state.delay) + } + } + state.timeout = setTimeout(check, state.delay) + state.hurry = function() { + clearTimeout(state.timeout) + state.timeout = setTimeout(check, 50) + } + CodeMirror.on(window, "mouseup", state.hurry) + CodeMirror.on(window, "keyup", state.hurry) + } + + function stopListening(_cm, state) { + clearTimeout(state.timeout) + CodeMirror.off(window, "mouseup", state.hurry) + CodeMirror.off(window, "keyup", state.hurry) + } +}); diff --git a/static/editor.md/lib/codemirror/addon/display/fullscreen.js b/static/editor.md/lib/codemirror/addon/display/fullscreen.js index cd3673b9..eda7300f 100644 --- a/static/editor.md/lib/codemirror/addon/display/fullscreen.js +++ b/static/editor.md/lib/codemirror/addon/display/fullscreen.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS diff --git a/static/editor.md/lib/codemirror/addon/display/panel.js b/static/editor.md/lib/codemirror/addon/display/panel.js index 22c0453e..29f7e0be 100644 --- a/static/editor.md/lib/codemirror/addon/display/panel.js +++ b/static/editor.md/lib/codemirror/addon/display/panel.js @@ -1,26 +1,51 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE -(function(mod) { +(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) { - CodeMirror.defineExtension("addPanel", function(node, options) { +})(function (CodeMirror) { + CodeMirror.defineExtension("addPanel", function (node, options) { + options = options || {}; + if (!this.state.panels) initPanels(this); var info = this.state.panels; - if (options && options.position == "bottom") - info.wrapper.appendChild(node); - else - info.wrapper.insertBefore(node, info.wrapper.firstChild); + var wrapper = info.wrapper; + var cmWrapper = this.getWrapperElement(); + var replace = options.replace instanceof Panel && !options.replace.cleared; + + if (options.after instanceof Panel && !options.after.cleared) { + wrapper.insertBefore(node, options.before.node.nextSibling); + } else if (options.before instanceof Panel && !options.before.cleared) { + wrapper.insertBefore(node, options.before.node); + } else if (replace) { + wrapper.insertBefore(node, options.replace.node); + options.replace.clear(true); + } else if (options.position == "bottom") { + wrapper.appendChild(node); + } else if (options.position == "before-bottom") { + wrapper.insertBefore(node, cmWrapper.nextSibling); + } else if (options.position == "after-top") { + wrapper.insertBefore(node, cmWrapper); + } else { + wrapper.insertBefore(node, wrapper.firstChild); + } + var height = (options && options.height) || node.offsetHeight; - this._setSize(null, info.heightLeft -= height); - info.panels++; - return new Panel(this, node, options, height); + + var panel = new Panel(this, node, options, height); + info.panels.push(panel); + + this.setSize(); + if (options.stable && isAtTop(this, node)) + this.scrollTo(null, this.getScrollInfo().top + height); + + return panel; }); function Panel(cm, node, options, height) { @@ -31,40 +56,43 @@ this.cleared = false; } - Panel.prototype.clear = function() { + /* when skipRemove is true, clear() was called from addPanel(). + * Thus removePanels() should not be called (issue 5518) */ + Panel.prototype.clear = function (skipRemove) { if (this.cleared) return; this.cleared = true; var info = this.cm.state.panels; - this.cm._setSize(null, info.heightLeft += this.height); + info.panels.splice(info.panels.indexOf(this), 1); + this.cm.setSize(); + if (this.options.stable && isAtTop(this.cm, this.node)) + this.cm.scrollTo(null, this.cm.getScrollInfo().top - this.height) info.wrapper.removeChild(this.node); - if (--info.panels == 0) removePanels(this.cm); + if (info.panels.length == 0 && !skipRemove) removePanels(this.cm); }; - Panel.prototype.changed = function(height) { - var newHeight = height == null ? this.node.offsetHeight : height; - var info = this.cm.state.panels; - this.cm._setSize(null, info.height += (newHeight - this.height)); - this.height = newHeight; + Panel.prototype.changed = function () { + this.height = this.node.getBoundingClientRect().height; + this.cm.setSize(); }; function initPanels(cm) { - var wrap = cm.getWrapperElement(); + var wrap = cm.getWrapperElement() var style = window.getComputedStyle ? window.getComputedStyle(wrap) : wrap.currentStyle; var height = parseInt(style.height); var info = cm.state.panels = { setHeight: wrap.style.height, - heightLeft: height, - panels: 0, + panels: [], wrapper: document.createElement("div") }; + var hasFocus = cm.hasFocus(), scrollPos = cm.getScrollInfo() wrap.parentNode.insertBefore(info.wrapper, wrap); - var hasFocus = cm.hasFocus(); info.wrapper.appendChild(wrap); + cm.scrollTo(scrollPos.left, scrollPos.top) if (hasFocus) cm.focus(); cm._setSize = cm.setSize; - if (height != null) cm.setSize = function(width, newHeight) { - if (newHeight == null) return this._setSize(width, newHeight); + if (height != null) cm.setSize = function (width, newHeight) { + if (!newHeight) newHeight = info.wrapper.offsetHeight; info.setHeight = newHeight; if (typeof newHeight != "number") { var px = /^(\d+\.?\d*)px$/.exec(newHeight); @@ -73,10 +101,12 @@ } else { info.wrapper.style.height = newHeight; newHeight = info.wrapper.offsetHeight; - info.wrapper.style.height = ""; } } - cm._setSize(width, info.heightLeft += (newHeight - height)); + var editorheight = newHeight - info.panels + .map(function (p) { return p.node.getBoundingClientRect().height; }) + .reduce(function (a, b) { return a + b; }, 0); + cm._setSize(width, editorheight); height = newHeight; }; } @@ -85,10 +115,19 @@ var info = cm.state.panels; cm.state.panels = null; - var wrap = cm.getWrapperElement(); + var wrap = cm.getWrapperElement() + var hasFocus = cm.hasFocus(), scrollPos = cm.getScrollInfo() info.wrapper.parentNode.replaceChild(wrap, info.wrapper); + cm.scrollTo(scrollPos.left, scrollPos.top) + if (hasFocus) cm.focus(); wrap.style.height = info.setHeight; cm.setSize = cm._setSize; cm.setSize(); } + + function isAtTop(cm, dom) { + for (var sibling = dom.nextSibling; sibling; sibling = sibling.nextSibling) + if (sibling == cm.getWrapperElement()) return true + return false + } }); diff --git a/static/editor.md/lib/codemirror/addon/display/placeholder.js b/static/editor.md/lib/codemirror/addon/display/placeholder.js index bb0c3931..cfb8341d 100644 --- a/static/editor.md/lib/codemirror/addon/display/placeholder.js +++ b/static/editor.md/lib/codemirror/addon/display/placeholder.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -14,10 +14,14 @@ if (val && !prev) { cm.on("blur", onBlur); cm.on("change", onChange); + cm.on("swapDoc", onChange); + CodeMirror.on(cm.getInputField(), "compositionupdate", cm.state.placeholderCompose = function() { onComposition(cm) }) onChange(cm); } else if (!val && prev) { cm.off("blur", onBlur); cm.off("change", onChange); + cm.off("swapDoc", onChange); + CodeMirror.off(cm.getInputField(), "compositionupdate", cm.state.placeholderCompose) clearPlaceholder(cm); var wrapper = cm.getWrapperElement(); wrapper.className = wrapper.className.replace(" CodeMirror-empty", ""); @@ -36,11 +40,27 @@ clearPlaceholder(cm); var elt = cm.state.placeholder = document.createElement("pre"); elt.style.cssText = "height: 0; overflow: visible"; - elt.className = "CodeMirror-placeholder"; - elt.appendChild(document.createTextNode(cm.getOption("placeholder"))); + elt.style.direction = cm.getOption("direction"); + elt.className = "CodeMirror-placeholder CodeMirror-line-like"; + var placeHolder = cm.getOption("placeholder") + if (typeof placeHolder == "string") placeHolder = document.createTextNode(placeHolder) + elt.appendChild(placeHolder) cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild); } + function onComposition(cm) { + setTimeout(function() { + var empty = false + if (cm.lineCount() == 1) { + var input = cm.getInputField() + empty = input.nodeName == "TEXTAREA" ? !cm.getLine(0).length + : !/[^\u200b]/.test(input.querySelector(".CodeMirror-line").textContent) + } + if (empty) setPlaceholder(cm) + else clearPlaceholder(cm) + }, 20) + } + function onBlur(cm) { if (isEmpty(cm)) setPlaceholder(cm); } diff --git a/static/editor.md/lib/codemirror/addon/display/rulers.js b/static/editor.md/lib/codemirror/addon/display/rulers.js index 13185d30..0bb83bb0 100644 --- a/static/editor.md/lib/codemirror/addon/display/rulers.js +++ b/static/editor.md/lib/codemirror/addon/display/rulers.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -11,34 +11,30 @@ })(function(CodeMirror) { "use strict"; - CodeMirror.defineOption("rulers", false, function(cm, val, old) { - if (old && old != CodeMirror.Init) { - clearRulers(cm); - cm.off("refresh", refreshRulers); + CodeMirror.defineOption("rulers", false, function(cm, val) { + if (cm.state.rulerDiv) { + cm.state.rulerDiv.parentElement.removeChild(cm.state.rulerDiv) + cm.state.rulerDiv = null + cm.off("refresh", drawRulers) } if (val && val.length) { - setRulers(cm); - cm.on("refresh", refreshRulers); + cm.state.rulerDiv = cm.display.lineSpace.parentElement.insertBefore(document.createElement("div"), cm.display.lineSpace) + cm.state.rulerDiv.className = "CodeMirror-rulers" + drawRulers(cm) + cm.on("refresh", drawRulers) } }); - function clearRulers(cm) { - for (var i = cm.display.lineSpace.childNodes.length - 1; i >= 0; i--) { - var node = cm.display.lineSpace.childNodes[i]; - if (/(^|\s)CodeMirror-ruler($|\s)/.test(node.className)) - node.parentNode.removeChild(node); - } - } - - function setRulers(cm) { + function drawRulers(cm) { + cm.state.rulerDiv.textContent = "" var val = cm.getOption("rulers"); var cw = cm.defaultCharWidth(); var left = cm.charCoords(CodeMirror.Pos(cm.firstLine(), 0), "div").left; - var minH = cm.display.scroller.offsetHeight + 30; + cm.state.rulerDiv.style.minHeight = (cm.display.scroller.offsetHeight + 30) + "px"; for (var i = 0; i < val.length; i++) { var elt = document.createElement("div"); elt.className = "CodeMirror-ruler"; - var col, cls = null, conf = val[i]; + var col, conf = val[i]; if (typeof conf == "number") { col = conf; } else { @@ -47,18 +43,9 @@ if (conf.color) elt.style.borderColor = conf.color; if (conf.lineStyle) elt.style.borderLeftStyle = conf.lineStyle; if (conf.width) elt.style.borderLeftWidth = conf.width; - cls = val[i].className; } elt.style.left = (left + col * cw) + "px"; - elt.style.top = "-50px"; - elt.style.bottom = "-20px"; - elt.style.minHeight = minH + "px"; - cm.display.lineSpace.insertBefore(elt, cm.display.cursorDiv); + cm.state.rulerDiv.appendChild(elt) } } - - function refreshRulers(cm) { - clearRulers(cm); - setRulers(cm); - } }); diff --git a/static/editor.md/lib/codemirror/addon/edit/closebrackets.js b/static/editor.md/lib/codemirror/addon/edit/closebrackets.js index ff4bb3f7..593d4439 100644 --- a/static/editor.md/lib/codemirror/addon/edit/closebrackets.js +++ b/static/editor.md/lib/codemirror/addon/edit/closebrackets.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -9,153 +9,193 @@ else // Plain browser env mod(CodeMirror); })(function(CodeMirror) { - var DEFAULT_BRACKETS = "()[]{}''\"\""; - var DEFAULT_TRIPLES = "'\""; - var DEFAULT_EXPLODE_ON_ENTER = "[]{}"; - var SPACE_CHAR_REGEX = /\s/; + var defaults = { + pairs: "()[]{}''\"\"", + closeBefore: ")]}'\":;>", + triples: "", + explode: "[]{}" + }; var Pos = CodeMirror.Pos; CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) { - if (old != CodeMirror.Init && old) - cm.removeKeyMap("autoCloseBrackets"); - if (!val) return; - var pairs = DEFAULT_BRACKETS, triples = DEFAULT_TRIPLES, explode = DEFAULT_EXPLODE_ON_ENTER; - if (typeof val == "string") pairs = val; - else if (typeof val == "object") { - if (val.pairs != null) pairs = val.pairs; - if (val.triples != null) triples = val.triples; - if (val.explode != null) explode = val.explode; + if (old && old != CodeMirror.Init) { + cm.removeKeyMap(keyMap); + cm.state.closeBrackets = null; + } + if (val) { + ensureBound(getOption(val, "pairs")) + cm.state.closeBrackets = val; + cm.addKeyMap(keyMap); } - var map = buildKeymap(pairs, triples); - if (explode) map.Enter = buildExplodeHandler(explode); - cm.addKeyMap(map); }); + function getOption(conf, name) { + if (name == "pairs" && typeof conf == "string") return conf; + if (typeof conf == "object" && conf[name] != null) return conf[name]; + return defaults[name]; + } + + var keyMap = {Backspace: handleBackspace, Enter: handleEnter}; + function ensureBound(chars) { + for (var i = 0; i < chars.length; i++) { + var ch = chars.charAt(i), key = "'" + ch + "'" + if (!keyMap[key]) keyMap[key] = handler(ch) + } + } + ensureBound(defaults.pairs + "`") + + function handler(ch) { + return function(cm) { return handleChar(cm, ch); }; + } + + function getConfig(cm) { + var deflt = cm.state.closeBrackets; + if (!deflt || deflt.override) return deflt; + var mode = cm.getModeAt(cm.getCursor()); + return mode.closeBrackets || deflt; + } + + function handleBackspace(cm) { + var conf = getConfig(cm); + if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass; + + var pairs = getOption(conf, "pairs"); + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + if (!ranges[i].empty()) return CodeMirror.Pass; + var around = charsAround(cm, ranges[i].head); + if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass; + } + for (var i = ranges.length - 1; i >= 0; i--) { + var cur = ranges[i].head; + cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1), "+delete"); + } + } + + function handleEnter(cm) { + var conf = getConfig(cm); + var explode = conf && getOption(conf, "explode"); + if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass; + + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + if (!ranges[i].empty()) return CodeMirror.Pass; + var around = charsAround(cm, ranges[i].head); + if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass; + } + cm.operation(function() { + var linesep = cm.lineSeparator() || "\n"; + cm.replaceSelection(linesep + linesep, null); + moveSel(cm, -1) + ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + var line = ranges[i].head.line; + cm.indentLine(line, null, true); + cm.indentLine(line + 1, null, true); + } + }); + } + + function moveSel(cm, dir) { + var newRanges = [], ranges = cm.listSelections(), primary = 0 + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i] + if (range.head == cm.getCursor()) primary = i + var pos = range.head.ch || dir > 0 ? {line: range.head.line, ch: range.head.ch + dir} : {line: range.head.line - 1} + newRanges.push({anchor: pos, head: pos}) + } + cm.setSelections(newRanges, primary) + } + + function contractSelection(sel) { + var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0; + return {anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)), + head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1))}; + } + + function handleChar(cm, ch) { + var conf = getConfig(cm); + if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass; + + var pairs = getOption(conf, "pairs"); + var pos = pairs.indexOf(ch); + if (pos == -1) return CodeMirror.Pass; + + var closeBefore = getOption(conf,"closeBefore"); + + var triples = getOption(conf, "triples"); + + var identical = pairs.charAt(pos + 1) == ch; + var ranges = cm.listSelections(); + var opening = pos % 2 == 0; + + var type; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i], cur = range.head, curType; + var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1)); + if (opening && !range.empty()) { + curType = "surround"; + } else if ((identical || !opening) && next == ch) { + if (identical && stringStartsAfter(cm, cur)) + curType = "both"; + else if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch) + curType = "skipThree"; + else + curType = "skip"; + } else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 && + cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch) { + if (cur.ch > 2 && /\bstring/.test(cm.getTokenTypeAt(Pos(cur.line, cur.ch - 2)))) return CodeMirror.Pass; + curType = "addFour"; + } else if (identical) { + var prev = cur.ch == 0 ? " " : cm.getRange(Pos(cur.line, cur.ch - 1), cur) + if (!CodeMirror.isWordChar(next) && prev != ch && !CodeMirror.isWordChar(prev)) curType = "both"; + else return CodeMirror.Pass; + } else if (opening && (next.length === 0 || /\s/.test(next) || closeBefore.indexOf(next) > -1)) { + curType = "both"; + } else { + return CodeMirror.Pass; + } + if (!type) type = curType; + else if (type != curType) return CodeMirror.Pass; + } + + var left = pos % 2 ? pairs.charAt(pos - 1) : ch; + var right = pos % 2 ? ch : pairs.charAt(pos + 1); + cm.operation(function() { + if (type == "skip") { + moveSel(cm, 1) + } else if (type == "skipThree") { + moveSel(cm, 3) + } else if (type == "surround") { + var sels = cm.getSelections(); + for (var i = 0; i < sels.length; i++) + sels[i] = left + sels[i] + right; + cm.replaceSelections(sels, "around"); + sels = cm.listSelections().slice(); + for (var i = 0; i < sels.length; i++) + sels[i] = contractSelection(sels[i]); + cm.setSelections(sels); + } else if (type == "both") { + cm.replaceSelection(left + right, null); + cm.triggerElectric(left + right); + moveSel(cm, -1) + } else if (type == "addFour") { + cm.replaceSelection(left + left + left + left, "before"); + moveSel(cm, 1) + } + }); + } + function charsAround(cm, pos) { var str = cm.getRange(Pos(pos.line, pos.ch - 1), Pos(pos.line, pos.ch + 1)); return str.length == 2 ? str : null; } - // Project the token type that will exists after the given char is - // typed, and use it to determine whether it would cause the start - // of a string token. - function enteringString(cm, pos, ch) { - var line = cm.getLine(pos.line); - var token = cm.getTokenAt(pos); - if (/\bstring2?\b/.test(token.type)) return false; - var stream = new CodeMirror.StringStream(line.slice(0, pos.ch) + ch + line.slice(pos.ch), 4); - stream.pos = stream.start = token.start; - for (;;) { - var type1 = cm.getMode().token(stream, token.state); - if (stream.pos >= pos.ch + 1) return /\bstring2?\b/.test(type1); - stream.start = stream.pos; - } - } - - function buildKeymap(pairs, triples) { - var map = { - name : "autoCloseBrackets", - Backspace: function(cm) { - if (cm.getOption("disableInput")) return CodeMirror.Pass; - var ranges = cm.listSelections(); - for (var i = 0; i < ranges.length; i++) { - if (!ranges[i].empty()) return CodeMirror.Pass; - var around = charsAround(cm, ranges[i].head); - if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass; - } - for (var i = ranges.length - 1; i >= 0; i--) { - var cur = ranges[i].head; - cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1)); - } - } - }; - var closingBrackets = ""; - for (var i = 0; i < pairs.length; i += 2) (function(left, right) { - closingBrackets += right; - map["'" + left + "'"] = function(cm) { - if (cm.getOption("disableInput")) return CodeMirror.Pass; - var ranges = cm.listSelections(), type, next; - for (var i = 0; i < ranges.length; i++) { - var range = ranges[i], cur = range.head, curType; - var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1)); - if (!range.empty()) { - curType = "surround"; - } else if (left == right && next == right) { - if (cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == left + left + left) - curType = "skipThree"; - else - curType = "skip"; - } else if (left == right && cur.ch > 1 && triples.indexOf(left) >= 0 && - cm.getRange(Pos(cur.line, cur.ch - 2), cur) == left + left && - (cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != left)) { - curType = "addFour"; - } else if (left == '"' || left == "'") { - if (!CodeMirror.isWordChar(next) && enteringString(cm, cur, left)) curType = "both"; - else return CodeMirror.Pass; - } else if (cm.getLine(cur.line).length == cur.ch || closingBrackets.indexOf(next) >= 0 || SPACE_CHAR_REGEX.test(next)) { - curType = "both"; - } else { - return CodeMirror.Pass; - } - if (!type) type = curType; - else if (type != curType) return CodeMirror.Pass; - } - - cm.operation(function() { - if (type == "skip") { - cm.execCommand("goCharRight"); - } else if (type == "skipThree") { - for (var i = 0; i < 3; i++) - cm.execCommand("goCharRight"); - } else if (type == "surround") { - var sels = cm.getSelections(); - for (var i = 0; i < sels.length; i++) - sels[i] = left + sels[i] + right; - cm.replaceSelections(sels, "around"); - } else if (type == "both") { - cm.replaceSelection(left + right, null); - cm.execCommand("goCharLeft"); - } else if (type == "addFour") { - cm.replaceSelection(left + left + left + left, "before"); - cm.execCommand("goCharRight"); - } - }); - }; - if (left != right) map["'" + right + "'"] = function(cm) { - var ranges = cm.listSelections(); - for (var i = 0; i < ranges.length; i++) { - var range = ranges[i]; - if (!range.empty() || - cm.getRange(range.head, Pos(range.head.line, range.head.ch + 1)) != right) - return CodeMirror.Pass; - } - cm.execCommand("goCharRight"); - }; - })(pairs.charAt(i), pairs.charAt(i + 1)); - return map; - } - - function buildExplodeHandler(pairs) { - return function(cm) { - if (cm.getOption("disableInput")) return CodeMirror.Pass; - var ranges = cm.listSelections(); - for (var i = 0; i < ranges.length; i++) { - if (!ranges[i].empty()) return CodeMirror.Pass; - var around = charsAround(cm, ranges[i].head); - if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass; - } - cm.operation(function() { - cm.replaceSelection("\n\n", null); - cm.execCommand("goCharLeft"); - ranges = cm.listSelections(); - for (var i = 0; i < ranges.length; i++) { - var line = ranges[i].head.line; - cm.indentLine(line, null, true); - cm.indentLine(line + 1, null, true); - } - }); - }; + function stringStartsAfter(cm, pos) { + var token = cm.getTokenAt(Pos(pos.line, pos.ch + 1)) + return /\bstring/.test(token.type) && token.start == pos.ch && + (pos.ch == 0 || !/\bstring/.test(cm.getTokenTypeAt(pos))) } }); diff --git a/static/editor.md/lib/codemirror/addon/edit/closetag.js b/static/editor.md/lib/codemirror/addon/edit/closetag.js index e68d52d9..7c22a50e 100644 --- a/static/editor.md/lib/codemirror/addon/edit/closetag.js +++ b/static/editor.md/lib/codemirror/addon/edit/closetag.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE /** * Tag-closer extension for CodeMirror. @@ -21,6 +21,8 @@ * An array of tag names that should, when opened, cause a * blank line to be added inside the tag, and the blank line and * closing line to be indented. + * `emptyTags` (default is none) + * An array of XML tag names that should be autoclosed with '/>'. * * See demos/closetag.html for a usage example. */ @@ -38,9 +40,9 @@ cm.removeKeyMap("autoCloseTags"); if (!val) return; var map = {name: "autoCloseTags"}; - if (typeof val != "object" || val.whenClosing) + if (typeof val != "object" || val.whenClosing !== false) map["'/'"] = function(cm) { return autoCloseSlash(cm); }; - if (typeof val != "object" || val.whenOpening) + if (typeof val != "object" || val.whenOpening !== false) map["'>'"] = function(cm) { return autoCloseGT(cm); }; cm.addKeyMap(map); }); @@ -53,41 +55,50 @@ function autoCloseGT(cm) { if (cm.getOption("disableInput")) return CodeMirror.Pass; var ranges = cm.listSelections(), replacements = []; + var opt = cm.getOption("autoCloseTags"); for (var i = 0; i < ranges.length; i++) { if (!ranges[i].empty()) return CodeMirror.Pass; var pos = ranges[i].head, tok = cm.getTokenAt(pos); var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state; - if (inner.mode.name != "xml" || !state.tagName) return CodeMirror.Pass; + var tagInfo = inner.mode.xmlCurrentTag && inner.mode.xmlCurrentTag(state) + var tagName = tagInfo && tagInfo.name + if (!tagName) return CodeMirror.Pass - var opt = cm.getOption("autoCloseTags"), html = inner.mode.configuration == "html"; + var html = inner.mode.configuration == "html"; var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose); var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent); - var tagName = state.tagName; if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch); var lowerTagName = tagName.toLowerCase(); // Don't process the '>' at the end of an end-tag or self-closing tag if (!tagName || tok.type == "string" && (tok.end != pos.ch || !/[\"\']/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1) || - tok.type == "tag" && state.type == "closeTag" || - tok.string.indexOf("/") == (tok.string.length - 1) || // match something like + tok.type == "tag" && tagInfo.close || + tok.string.indexOf("/") == (pos.ch - tok.start - 1) || // match something like dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1 || - closingTagExists(cm, tagName, pos, state, true)) + closingTagExists(cm, inner.mode.xmlCurrentContext && inner.mode.xmlCurrentContext(state) || [], tagName, pos, true)) return CodeMirror.Pass; + var emptyTags = typeof opt == "object" && opt.emptyTags; + if (emptyTags && indexOf(emptyTags, tagName) > -1) { + replacements[i] = { text: "/>", newPos: CodeMirror.Pos(pos.line, pos.ch + 2) }; + continue; + } + var indent = indentTags && indexOf(indentTags, lowerTagName) > -1; replacements[i] = {indent: indent, text: ">" + (indent ? "\n\n" : "") + "", newPos: indent ? CodeMirror.Pos(pos.line + 1, 0) : CodeMirror.Pos(pos.line, pos.ch + 1)}; } + var dontIndentOnAutoClose = (typeof opt == "object" && opt.dontIndentOnAutoClose); for (var i = ranges.length - 1; i >= 0; i--) { var info = replacements[i]; cm.replaceRange(info.text, ranges[i].head, ranges[i].anchor, "+insert"); var sel = cm.listSelections().slice(0); sel[i] = {head: info.newPos, anchor: info.newPos}; cm.setSelections(sel); - if (info.indent) { + if (!dontIndentOnAutoClose && info.indent) { cm.indentLine(info.newPos.line, null, true); cm.indentLine(info.newPos.line + 1, null, true); } @@ -97,6 +108,8 @@ function autoCloseCurrent(cm, typingSlash) { var ranges = cm.listSelections(), replacements = []; var head = typingSlash ? "/" : ""; - else if (cm.getMode().name == "htmlmixed" && inner.mode.name == "css") - replacements[i] = head + "style>"; - else - return CodeMirror.Pass; + var replacement, mixed = inner.mode.name != "xml" && cm.getMode().name == "htmlmixed" + if (mixed && inner.mode.name == "javascript") { + replacement = head + "script"; + } else if (mixed && inner.mode.name == "css") { + replacement = head + "style"; } else { - if (!state.context || !state.context.tagName || - closingTagExists(cm, state.context.tagName, pos, state)) + var context = inner.mode.xmlCurrentContext && inner.mode.xmlCurrentContext(state) + var top = context.length ? context[context.length - 1] : "" + if (!context || (context.length && closingTagExists(cm, context, top, pos))) return CodeMirror.Pass; - replacements[i] = head + state.context.tagName + ">"; + replacement = head + top } + if (cm.getLine(pos.line).charAt(tok.end) != ">") replacement += ">"; + replacements[i] = replacement; } cm.replaceSelections(replacements); ranges = cm.listSelections(); - for (var i = 0; i < ranges.length; i++) - if (i == ranges.length - 1 || ranges[i].head.line < ranges[i + 1].head.line) - cm.indentLine(ranges[i].head.line); + if (!dontIndentOnAutoClose) { + for (var i = 0; i < ranges.length; i++) + if (i == ranges.length - 1 || ranges[i].head.line < ranges[i + 1].head.line) + cm.indentLine(ranges[i].head.line); + } } function autoCloseSlash(cm) { @@ -145,16 +161,19 @@ // If xml-fold is loaded, we use its functionality to try and verify // whether a given tag is actually unclosed. - function closingTagExists(cm, tagName, pos, state, newTag) { + function closingTagExists(cm, context, tagName, pos, newTag) { if (!CodeMirror.scanForClosingTag) return false; var end = Math.min(cm.lastLine() + 1, pos.line + 500); var nextClose = CodeMirror.scanForClosingTag(cm, pos, null, end); if (!nextClose || nextClose.tag != tagName) return false; - var cx = state.context; // If the immediate wrapping context contains onCx instances of // the same tag, a closing tag only exists if there are at least // that many closing tags of that type following. - for (var onCx = newTag ? 1 : 0; cx && cx.tagName == tagName; cx = cx.prev) ++onCx; + var onCx = newTag ? 1 : 0 + for (var i = context.length - 1; i >= 0; i--) { + if (context[i] == tagName) ++onCx + else break + } pos = nextClose.to; for (var i = 1; i < onCx; i++) { var next = CodeMirror.scanForClosingTag(cm, pos, null, end); diff --git a/static/editor.md/lib/codemirror/addon/edit/continuelist.js b/static/editor.md/lib/codemirror/addon/edit/continuelist.js index ca8d2675..6ec65010 100644 --- a/static/editor.md/lib/codemirror/addon/edit/continuelist.js +++ b/static/editor.md/lib/codemirror/addon/edit/continuelist.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -11,41 +11,91 @@ })(function(CodeMirror) { "use strict"; - var listRE = /^(\s*)(>[> ]*|[*+-]\s|(\d+)\.)(\s*)/, - emptyListRE = /^(\s*)(>[> ]*|[*+-]|(\d+)\.)(\s*)$/, + var listRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]\s|[*+-]\s|(\d+)([.)]))(\s*)/, + emptyListRE = /^(\s*)(>[> ]*|[*+-] \[[x ]\]|[*+-]|(\d+)[.)])(\s*)$/, unorderedListRE = /[*+-]\s/; CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) { if (cm.getOption("disableInput")) return CodeMirror.Pass; var ranges = cm.listSelections(), replacements = []; for (var i = 0; i < ranges.length; i++) { - var pos = ranges[i].head, match; - var eolState = cm.getStateAfter(pos.line); - var inList = eolState.list !== false; - var inQuote = eolState.quote !== false; + var pos = ranges[i].head; - if (!ranges[i].empty() || (!inList && !inQuote) || !(match = cm.getLine(pos.line).match(listRE))) { + // If we're not in Markdown mode, fall back to normal newlineAndIndent + var eolState = cm.getStateAfter(pos.line); + var inner = CodeMirror.innerMode(cm.getMode(), eolState); + if (inner.mode.name !== "markdown") { + cm.execCommand("newlineAndIndent"); + return; + } else { + eolState = inner.state; + } + + var inList = eolState.list !== false; + var inQuote = eolState.quote !== 0; + + var line = cm.getLine(pos.line), match = listRE.exec(line); + var cursorBeforeBullet = /^\s*$/.test(line.slice(0, pos.ch)); + if (!ranges[i].empty() || (!inList && !inQuote) || !match || cursorBeforeBullet) { cm.execCommand("newlineAndIndent"); return; } - if (cm.getLine(pos.line).match(emptyListRE)) { - cm.replaceRange("", { + if (emptyListRE.test(line)) { + var endOfQuote = inQuote && />\s*$/.test(line) + var endOfList = !/>\s*$/.test(line) + if (endOfQuote || endOfList) cm.replaceRange("", { line: pos.line, ch: 0 }, { line: pos.line, ch: pos.ch + 1 }); replacements[i] = "\n"; - } else { - var indent = match[1], after = match[4]; - var bullet = unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0 - ? match[2] - : (parseInt(match[3], 10) + 1) + "."; - + var indent = match[1], after = match[5]; + var numbered = !(unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0); + var bullet = numbered ? (parseInt(match[3], 10) + 1) + match[4] : match[2].replace("x", " "); replacements[i] = "\n" + indent + bullet + after; + + if (numbered) incrementRemainingMarkdownListNumbers(cm, pos); } } cm.replaceSelections(replacements); }; + + // Auto-updating Markdown list numbers when a new item is added to the + // middle of a list + function incrementRemainingMarkdownListNumbers(cm, pos) { + var startLine = pos.line, lookAhead = 0, skipCount = 0; + var startItem = listRE.exec(cm.getLine(startLine)), startIndent = startItem[1]; + + do { + lookAhead += 1; + var nextLineNumber = startLine + lookAhead; + var nextLine = cm.getLine(nextLineNumber), nextItem = listRE.exec(nextLine); + + if (nextItem) { + var nextIndent = nextItem[1]; + var newNumber = (parseInt(startItem[3], 10) + lookAhead - skipCount); + var nextNumber = (parseInt(nextItem[3], 10)), itemNumber = nextNumber; + + if (startIndent === nextIndent && !isNaN(nextNumber)) { + if (newNumber === nextNumber) itemNumber = nextNumber + 1; + if (newNumber > nextNumber) itemNumber = newNumber + 1; + cm.replaceRange( + nextLine.replace(listRE, nextIndent + itemNumber + nextItem[4] + nextItem[5]), + { + line: nextLineNumber, ch: 0 + }, { + line: nextLineNumber, ch: nextLine.length + }); + } else { + if (startIndent.length > nextIndent.length) return; + // This doesn't run if the next line immediately indents, as it is + // not clear of the users intention (new indented item or same level) + if ((startIndent.length < nextIndent.length) && (lookAhead === 1)) return; + skipCount += 1; + } + } + } while (nextItem); + } }); diff --git a/static/editor.md/lib/codemirror/addon/edit/matchbrackets.js b/static/editor.md/lib/codemirror/addon/edit/matchbrackets.js index 70e1ae18..43dc8840 100644 --- a/static/editor.md/lib/codemirror/addon/edit/matchbrackets.js +++ b/static/editor.md/lib/codemirror/addon/edit/matchbrackets.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -14,17 +14,31 @@ var Pos = CodeMirror.Pos; - var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"}; + var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<", "<": ">>", ">": "<<"}; - function findMatchingBracket(cm, where, strict, config) { + function bracketRegex(config) { + return config && config.bracketRegex || /[(){}[\]]/ + } + + function findMatchingBracket(cm, where, config) { var line = cm.getLineHandle(where.line), pos = where.ch - 1; - var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)]; + var afterCursor = config && config.afterCursor + if (afterCursor == null) + afterCursor = /(^| )cm-fat-cursor($| )/.test(cm.getWrapperElement().className) + var re = bracketRegex(config) + + // A cursor is defined as between two characters, but in in vim command mode + // (i.e. not insert mode), the cursor is visually represented as a + // highlighted box on top of the 2nd character. Otherwise, we allow matches + // from before or after the cursor. + var match = (!afterCursor && pos >= 0 && re.test(line.text.charAt(pos)) && matching[line.text.charAt(pos)]) || + re.test(line.text.charAt(pos + 1)) && matching[line.text.charAt(++pos)]; if (!match) return null; var dir = match.charAt(1) == ">" ? 1 : -1; - if (strict && (dir > 0) != (pos == where.ch)) return null; + if (config && config.strict && (dir > 0) != (pos == where.ch)) return null; var style = cm.getTokenTypeAt(Pos(where.line, pos + 1)); - var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config); + var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style, config); if (found == null) return null; return {from: Pos(where.line, pos), to: found && found.pos, match: found && found.ch == match.charAt(0), forward: dir > 0}; @@ -42,7 +56,7 @@ var maxScanLines = (config && config.maxScanLines) || 1000; var stack = []; - var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\]]/; + var re = bracketRegex(config) var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1) : Math.max(cm.firstLine() - 1, where.line - maxScanLines); for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) { @@ -53,9 +67,10 @@ if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0); for (; pos != end; pos += dir) { var ch = line.charAt(pos); - if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) { + if (re.test(ch) && (style === undefined || + (cm.getTokenTypeAt(Pos(lineNo, pos + 1)) || "") == (style || ""))) { var match = matching[ch]; - if ((match.charAt(1) == ">") == (dir > 0)) stack.push(ch); + if (match && (match.charAt(1) == ">") == (dir > 0)) stack.push(ch); else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch}; else stack.pop(); } @@ -66,11 +81,12 @@ function matchBrackets(cm, autoclear, config) { // Disable brace matching in long lines, since it'll cause hugely slow updates - var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000; + var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000, + highlightNonMatching = config && config.highlightNonMatching; var marks = [], ranges = cm.listSelections(); for (var i = 0; i < ranges.length; i++) { - var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, false, config); - if (match && cm.getLine(match.from.line).length <= maxHighlightLen) { + var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, config); + if (match && (match.match || highlightNonMatching !== false) && cm.getLine(match.from.line).length <= maxHighlightLen) { var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket"; marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style})); if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen) @@ -80,7 +96,7 @@ if (marks.length) { // Kludge to work around the IE bug from issue #1193, where text - // input stops going to the textare whever this fires. + // input stops going to the textarea whenever this fires. if (ie_lt8 && cm.state.focused) cm.focus(); var clear = function() { @@ -93,26 +109,50 @@ } } - var currentlyHighlighted = null; function doMatchBrackets(cm) { cm.operation(function() { - if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;} - currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets); + if (cm.state.matchBrackets.currentlyHighlighted) { + cm.state.matchBrackets.currentlyHighlighted(); + cm.state.matchBrackets.currentlyHighlighted = null; + } + cm.state.matchBrackets.currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets); }); } + function clearHighlighted(cm) { + if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) { + cm.state.matchBrackets.currentlyHighlighted(); + cm.state.matchBrackets.currentlyHighlighted = null; + } + } + CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) { - if (old && old != CodeMirror.Init) + if (old && old != CodeMirror.Init) { cm.off("cursorActivity", doMatchBrackets); + cm.off("focus", doMatchBrackets) + cm.off("blur", clearHighlighted) + clearHighlighted(cm); + } if (val) { cm.state.matchBrackets = typeof val == "object" ? val : {}; cm.on("cursorActivity", doMatchBrackets); + cm.on("focus", doMatchBrackets) + cm.on("blur", clearHighlighted) } }); CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);}); - CodeMirror.defineExtension("findMatchingBracket", function(pos, strict, config){ - return findMatchingBracket(this, pos, strict, config); + CodeMirror.defineExtension("findMatchingBracket", function(pos, config, oldConfig){ + // Backwards-compatibility kludge + if (oldConfig || typeof config == "boolean") { + if (!oldConfig) { + config = config ? {strict: true} : null + } else { + oldConfig.strict = config + config = oldConfig + } + } + return findMatchingBracket(this, pos, config) }); CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){ return scanForBracket(this, pos, dir, style, config); diff --git a/static/editor.md/lib/codemirror/addon/edit/matchtags.js b/static/editor.md/lib/codemirror/addon/edit/matchtags.js index fb1911a8..2203d939 100644 --- a/static/editor.md/lib/codemirror/addon/edit/matchtags.js +++ b/static/editor.md/lib/codemirror/addon/edit/matchtags.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS diff --git a/static/editor.md/lib/codemirror/addon/edit/trailingspace.js b/static/editor.md/lib/codemirror/addon/edit/trailingspace.js index fa7b56be..c39c310a 100644 --- a/static/editor.md/lib/codemirror/addon/edit/trailingspace.js +++ b/static/editor.md/lib/codemirror/addon/edit/trailingspace.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS diff --git a/static/editor.md/lib/codemirror/addon/fold/brace-fold.js b/static/editor.md/lib/codemirror/addon/fold/brace-fold.js index 1605f6c2..28cb093f 100644 --- a/static/editor.md/lib/codemirror/addon/fold/brace-fold.js +++ b/static/editor.md/lib/codemirror/addon/fold/brace-fold.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -11,53 +11,67 @@ })(function(CodeMirror) { "use strict"; -CodeMirror.registerHelper("fold", "brace", function(cm, start) { - var line = start.line, lineText = cm.getLine(line); - var startCh, tokenType; +function bracketFolding(pairs) { + return function(cm, start) { + var line = start.line, lineText = cm.getLine(line); - function findOpening(openCh) { - for (var at = start.ch, pass = 0;;) { - var found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1); - if (found == -1) { - if (pass == 1) break; - pass = 1; - at = lineText.length; - continue; + function findOpening(pair) { + var tokenType; + for (var at = start.ch, pass = 0;;) { + var found = at <= 0 ? -1 : lineText.lastIndexOf(pair[0], at - 1); + if (found == -1) { + if (pass == 1) break; + pass = 1; + at = lineText.length; + continue; + } + if (pass == 1 && found < start.ch) break; + tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1)); + if (!/^(comment|string)/.test(tokenType)) return {ch: found + 1, tokenType: tokenType, pair: pair}; + at = found - 1; } - if (pass == 1 && found < start.ch) break; - tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1)); - if (!/^(comment|string)/.test(tokenType)) return found + 1; - at = found - 1; } - } - var startToken = "{", endToken = "}", startCh = findOpening("{"); - if (startCh == null) { - startToken = "[", endToken = "]"; - startCh = findOpening("["); - } - - if (startCh == null) return; - var count = 1, lastLine = cm.lastLine(), end, endCh; - outer: for (var i = line; i <= lastLine; ++i) { - var text = cm.getLine(i), pos = i == line ? startCh : 0; - for (;;) { - var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos); - if (nextOpen < 0) nextOpen = text.length; - if (nextClose < 0) nextClose = text.length; - pos = Math.min(nextOpen, nextClose); - if (pos == text.length) break; - if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == tokenType) { - if (pos == nextOpen) ++count; - else if (!--count) { end = i; endCh = pos; break outer; } + function findRange(found) { + var count = 1, lastLine = cm.lastLine(), end, startCh = found.ch, endCh + outer: for (var i = line; i <= lastLine; ++i) { + var text = cm.getLine(i), pos = i == line ? startCh : 0; + for (;;) { + var nextOpen = text.indexOf(found.pair[0], pos), nextClose = text.indexOf(found.pair[1], pos); + if (nextOpen < 0) nextOpen = text.length; + if (nextClose < 0) nextClose = text.length; + pos = Math.min(nextOpen, nextClose); + if (pos == text.length) break; + if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == found.tokenType) { + if (pos == nextOpen) ++count; + else if (!--count) { end = i; endCh = pos; break outer; } + } + ++pos; + } } - ++pos; + + if (end == null || line == end) return null + return {from: CodeMirror.Pos(line, startCh), + to: CodeMirror.Pos(end, endCh)}; } + + var found = [] + for (var i = 0; i < pairs.length; i++) { + var open = findOpening(pairs[i]) + if (open) found.push(open) + } + found.sort(function(a, b) { return a.ch - b.ch }) + for (var i = 0; i < found.length; i++) { + var range = findRange(found[i]) + if (range) return range + } + return null } - if (end == null || line == end && endCh == startCh) return; - return {from: CodeMirror.Pos(line, startCh), - to: CodeMirror.Pos(end, endCh)}; -}); +} + +CodeMirror.registerHelper("fold", "brace", bracketFolding([["{", "}"], ["[", "]"]])); + +CodeMirror.registerHelper("fold", "brace-paren", bracketFolding([["{", "}"], ["[", "]"], ["(", ")"]])); CodeMirror.registerHelper("fold", "import", function(cm, start) { function hasImport(line) { @@ -72,15 +86,15 @@ CodeMirror.registerHelper("fold", "import", function(cm, start) { } } - var start = start.line, has = hasImport(start), prev; - if (!has || hasImport(start - 1) || ((prev = hasImport(start - 2)) && prev.end.line == start - 1)) + var startLine = start.line, has = hasImport(startLine), prev; + if (!has || hasImport(startLine - 1) || ((prev = hasImport(startLine - 2)) && prev.end.line == startLine - 1)) return null; for (var end = has.end;;) { var next = hasImport(end.line + 1); if (next == null) break; end = next.end; } - return {from: cm.clipPos(CodeMirror.Pos(start, has.startCh + 1)), to: end}; + return {from: cm.clipPos(CodeMirror.Pos(startLine, has.startCh + 1)), to: end}; }); CodeMirror.registerHelper("fold", "include", function(cm, start) { @@ -91,14 +105,14 @@ CodeMirror.registerHelper("fold", "include", function(cm, start) { if (start.type == "meta" && start.string.slice(0, 8) == "#include") return start.start + 8; } - var start = start.line, has = hasInclude(start); - if (has == null || hasInclude(start - 1) != null) return null; - for (var end = start;;) { + var startLine = start.line, has = hasInclude(startLine); + if (has == null || hasInclude(startLine - 1) != null) return null; + for (var end = startLine;;) { var next = hasInclude(end + 1); if (next == null) break; ++end; } - return {from: CodeMirror.Pos(start, has + 1), + return {from: CodeMirror.Pos(startLine, has + 1), to: cm.clipPos(CodeMirror.Pos(end))}; }); diff --git a/static/editor.md/lib/codemirror/addon/fold/comment-fold.js b/static/editor.md/lib/codemirror/addon/fold/comment-fold.js index b75db7ea..836101d8 100644 --- a/static/editor.md/lib/codemirror/addon/fold/comment-fold.js +++ b/static/editor.md/lib/codemirror/addon/fold/comment-fold.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -28,7 +28,9 @@ CodeMirror.registerGlobalHelper("fold", "comment", function(mode) { continue; } if (pass == 1 && found < start.ch) return; - if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1)))) { + if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1))) && + (found == 0 || lineText.slice(found - endToken.length, found) == endToken || + !/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found))))) { startCh = found + startToken.length; break; } diff --git a/static/editor.md/lib/codemirror/addon/fold/foldcode.js b/static/editor.md/lib/codemirror/addon/fold/foldcode.js index 62911f93..721bc087 100644 --- a/static/editor.md/lib/codemirror/addon/fold/foldcode.js +++ b/static/editor.md/lib/codemirror/addon/fold/foldcode.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -24,9 +24,11 @@ function getRange(allowFolded) { var range = finder(cm, pos); if (!range || range.to.line - range.from.line < minSize) return null; + if (force === "fold") return range; + var marks = cm.findMarksAt(range.from); for (var i = 0; i < marks.length; ++i) { - if (marks[i].__isFold && force !== "fold") { + if (marks[i].__isFold) { if (!allowFolded) return null; range.cleared = true; marks[i].clear(); @@ -42,14 +44,14 @@ } if (!range || range.cleared || force === "unfold") return; - var myWidget = makeWidget(cm, options); + var myWidget = makeWidget(cm, options, range); CodeMirror.on(myWidget, "mousedown", function(e) { myRange.clear(); CodeMirror.e_preventDefault(e); }); var myRange = cm.markText(range.from, range.to, { replacedWith: myWidget, - clearOnEnter: true, + clearOnEnter: getOption(cm, options, "clearOnEnter"), __isFold: true }); myRange.on("clear", function(from, to) { @@ -58,13 +60,20 @@ CodeMirror.signal(cm, "fold", cm, range.from, range.to); } - function makeWidget(cm, options) { + function makeWidget(cm, options, range) { var widget = getOption(cm, options, "widget"); + + if (typeof widget == "function") { + widget = widget(range.from, range.to); + } + if (typeof widget == "string") { var text = document.createTextNode(widget); widget = document.createElement("span"); widget.appendChild(text); widget.className = "CodeMirror-foldmarker"; + } else if (widget) { + widget = widget.cloneNode(true) } return widget; } @@ -92,18 +101,18 @@ cm.foldCode(cm.getCursor(), null, "fold"); }; CodeMirror.commands.unfold = function(cm) { - cm.foldCode(cm.getCursor(), null, "unfold"); + cm.foldCode(cm.getCursor(), { scanUp: false }, "unfold"); }; CodeMirror.commands.foldAll = function(cm) { cm.operation(function() { for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++) - cm.foldCode(CodeMirror.Pos(i, 0), null, "fold"); + cm.foldCode(CodeMirror.Pos(i, 0), { scanUp: false }, "fold"); }); }; CodeMirror.commands.unfoldAll = function(cm) { cm.operation(function() { for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++) - cm.foldCode(CodeMirror.Pos(i, 0), null, "unfold"); + cm.foldCode(CodeMirror.Pos(i, 0), { scanUp: false }, "unfold"); }); }; @@ -129,7 +138,8 @@ rangeFinder: CodeMirror.fold.auto, widget: "\u2194", minFoldSize: 0, - scanUp: false + scanUp: false, + clearOnEnter: true }; CodeMirror.defineOption("foldOptions", null); diff --git a/static/editor.md/lib/codemirror/addon/fold/foldgutter.js b/static/editor.md/lib/codemirror/addon/fold/foldgutter.js index 199120c7..7d46a609 100644 --- a/static/editor.md/lib/codemirror/addon/fold/foldgutter.js +++ b/static/editor.md/lib/codemirror/addon/fold/foldgutter.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -16,21 +16,21 @@ cm.clearGutter(cm.state.foldGutter.options.gutter); cm.state.foldGutter = null; cm.off("gutterClick", onGutterClick); - cm.off("change", onChange); + cm.off("changes", onChange); cm.off("viewportChange", onViewportChange); cm.off("fold", onFold); cm.off("unfold", onFold); - cm.off("swapDoc", updateInViewport); + cm.off("swapDoc", onChange); } if (val) { cm.state.foldGutter = new State(parseOptions(val)); updateInViewport(cm); cm.on("gutterClick", onGutterClick); - cm.on("change", onChange); + cm.on("changes", onChange); cm.on("viewportChange", onViewportChange); cm.on("fold", onFold); cm.on("unfold", onFold); - cm.on("swapDoc", updateInViewport); + cm.on("swapDoc", onChange); } }); @@ -50,9 +50,14 @@ } function isFolded(cm, line) { - var marks = cm.findMarksAt(Pos(line)); - for (var i = 0; i < marks.length; ++i) - if (marks[i].__isFold && marks[i].find().from.line == line) return true; + var marks = cm.findMarks(Pos(line, 0), Pos(line + 1, 0)); + for (var i = 0; i < marks.length; ++i) { + if (marks[i].__isFold) { + var fromPos = marks[i].find(-1); + if (fromPos && fromPos.line === line) + return marks[i]; + } + } } function marker(spec) { @@ -66,24 +71,36 @@ } function updateFoldInfo(cm, from, to) { - var opts = cm.state.foldGutter.options, cur = from; + var opts = cm.state.foldGutter.options, cur = from - 1; var minSize = cm.foldOption(opts, "minFoldSize"); var func = cm.foldOption(opts, "rangeFinder"); + // we can reuse the built-in indicator element if its className matches the new state + var clsFolded = typeof opts.indicatorFolded == "string" && classTest(opts.indicatorFolded); + var clsOpen = typeof opts.indicatorOpen == "string" && classTest(opts.indicatorOpen); cm.eachLine(from, to, function(line) { + ++cur; var mark = null; + var old = line.gutterMarkers; + if (old) old = old[opts.gutter]; if (isFolded(cm, cur)) { + if (clsFolded && old && clsFolded.test(old.className)) return; mark = marker(opts.indicatorFolded); } else { var pos = Pos(cur, 0); var range = func && func(cm, pos); - if (range && range.to.line - range.from.line >= minSize) + if (range && range.to.line - range.from.line >= minSize) { + if (clsOpen && old && clsOpen.test(old.className)) return; mark = marker(opts.indicatorOpen); + } } + if (!mark && !old) return; cm.setGutterMarker(line, opts.gutter, mark); - ++cur; }); } + // copied from CodeMirror/src/util/dom.js + function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") } + function updateInViewport(cm) { var vp = cm.getViewport(), state = cm.state.foldGutter; if (!state) return; @@ -98,7 +115,9 @@ if (!state) return; var opts = state.options; if (gutter != opts.gutter) return; - cm.foldCode(Pos(line, 0), opts.rangeFinder); + var folded = isFolded(cm, line); + if (folded) folded.clear(); + else cm.foldCode(Pos(line, 0), opts); } function onChange(cm) { diff --git a/static/editor.md/lib/codemirror/addon/fold/indent-fold.js b/static/editor.md/lib/codemirror/addon/fold/indent-fold.js index e29f15e9..0cc11264 100644 --- a/static/editor.md/lib/codemirror/addon/fold/indent-fold.js +++ b/static/editor.md/lib/codemirror/addon/fold/indent-fold.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -11,32 +11,36 @@ })(function(CodeMirror) { "use strict"; +function lineIndent(cm, lineNo) { + var text = cm.getLine(lineNo) + var spaceTo = text.search(/\S/) + if (spaceTo == -1 || /\bcomment\b/.test(cm.getTokenTypeAt(CodeMirror.Pos(lineNo, spaceTo + 1)))) + return -1 + return CodeMirror.countColumn(text, null, cm.getOption("tabSize")) +} + CodeMirror.registerHelper("fold", "indent", function(cm, start) { - var tabSize = cm.getOption("tabSize"), firstLine = cm.getLine(start.line); - if (!/\S/.test(firstLine)) return; - var getIndent = function(line) { - return CodeMirror.countColumn(line, null, tabSize); - }; - var myIndent = getIndent(firstLine); - var lastLineInFold = null; + var myIndent = lineIndent(cm, start.line) + if (myIndent < 0) return + var lastLineInFold = null + // Go through lines until we find a line that definitely doesn't belong in // the block we're folding, or to the end. for (var i = start.line + 1, end = cm.lastLine(); i <= end; ++i) { - var curLine = cm.getLine(i); - var curIndent = getIndent(curLine); - if (curIndent > myIndent) { + var indent = lineIndent(cm, i) + if (indent == -1) { + } else if (indent > myIndent) { // Lines with a greater indent are considered part of the block. lastLineInFold = i; - } else if (!/\S/.test(curLine)) { - // Empty lines might be breaks within the block we're trying to fold. } else { - // A non-empty line at an indent equal to or less than ours marks the - // start of another block. + // If this line has non-space, non-comment content, and is + // indented less or equal to the start line, it is the start of + // another block. break; } } if (lastLineInFold) return { - from: CodeMirror.Pos(start.line, firstLine.length), + from: CodeMirror.Pos(start.line, cm.getLine(start.line).length), to: CodeMirror.Pos(lastLineInFold, cm.getLine(lastLineInFold).length) }; }); diff --git a/static/editor.md/lib/codemirror/addon/fold/markdown-fold.js b/static/editor.md/lib/codemirror/addon/fold/markdown-fold.js index ce84c946..6a551786 100644 --- a/static/editor.md/lib/codemirror/addon/fold/markdown-fold.js +++ b/static/editor.md/lib/codemirror/addon/fold/markdown-fold.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS diff --git a/static/editor.md/lib/codemirror/addon/fold/xml-fold.js b/static/editor.md/lib/codemirror/addon/fold/xml-fold.js index 504727f3..13bc3838 100644 --- a/static/editor.md/lib/codemirror/addon/fold/xml-fold.js +++ b/static/editor.md/lib/codemirror/addon/fold/xml-fold.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -21,8 +21,8 @@ function Iter(cm, line, ch, range) { this.line = line; this.ch = ch; this.cm = cm; this.text = cm.getLine(line); - this.min = range ? range.from : cm.firstLine(); - this.max = range ? range.to - 1 : cm.lastLine(); + this.min = range ? Math.max(range.from, cm.firstLine()) : cm.firstLine(); + this.max = range ? Math.min(range.to - 1, cm.lastLine()) : cm.lastLine(); } function tagAt(iter, ch) { @@ -137,12 +137,14 @@ CodeMirror.registerHelper("fold", "xml", function(cm, start) { var iter = new Iter(cm, start.line, 0); for (;;) { - var openTag = toNextTag(iter), end; - if (!openTag || iter.line != start.line || !(end = toTagEnd(iter))) return; + var openTag = toNextTag(iter) + if (!openTag || iter.line != start.line) return + var end = toTagEnd(iter) + if (!end) return if (!openTag[1] && end != "selfClose") { - var start = Pos(iter.line, iter.ch); - var close = findMatchingClose(iter, openTag[2]); - return close && {from: start, to: close.from}; + var startPos = Pos(iter.line, iter.ch); + var endPos = findMatchingClose(iter, openTag[2]); + return endPos && cmp(endPos.from, startPos) > 0 ? {from: startPos, to: endPos.from} : null } } }); @@ -163,10 +165,10 @@ } }; - CodeMirror.findEnclosingTag = function(cm, pos, range) { + CodeMirror.findEnclosingTag = function(cm, pos, range, tag) { var iter = new Iter(cm, pos.line, pos.ch, range); for (;;) { - var open = findMatchingOpen(iter); + var open = findMatchingOpen(iter, tag); if (!open) break; var forward = new Iter(cm, pos.line, pos.ch, range); var close = findMatchingClose(forward, open.tag); diff --git a/static/editor.md/lib/codemirror/addon/hint/anyword-hint.js b/static/editor.md/lib/codemirror/addon/hint/anyword-hint.js index 8e74a920..d27a9ec0 100644 --- a/static/editor.md/lib/codemirror/addon/hint/anyword-hint.js +++ b/static/editor.md/lib/codemirror/addon/hint/anyword-hint.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -21,7 +21,7 @@ while (start && word.test(curLine.charAt(start - 1))) --start; var curWord = start != end && curLine.slice(start, end); - var list = [], seen = {}; + var list = options && options.list || [], seen = {}; var re = new RegExp(word.source, "g"); for (var dir = -1; dir <= 1; dir += 2) { var line = cur.line, endLine = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir; diff --git a/static/editor.md/lib/codemirror/addon/hint/css-hint.js b/static/editor.md/lib/codemirror/addon/hint/css-hint.js index 488da344..980d1197 100644 --- a/static/editor.md/lib/codemirror/addon/hint/css-hint.js +++ b/static/editor.md/lib/codemirror/addon/hint/css-hint.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -11,15 +11,25 @@ })(function(CodeMirror) { "use strict"; - var pseudoClasses = {link: 1, visited: 1, active: 1, hover: 1, focus: 1, - "first-letter": 1, "first-line": 1, "first-child": 1, - before: 1, after: 1, lang: 1}; + var pseudoClasses = {"active":1, "after":1, "before":1, "checked":1, "default":1, + "disabled":1, "empty":1, "enabled":1, "first-child":1, "first-letter":1, + "first-line":1, "first-of-type":1, "focus":1, "hover":1, "in-range":1, + "indeterminate":1, "invalid":1, "lang":1, "last-child":1, "last-of-type":1, + "link":1, "not":1, "nth-child":1, "nth-last-child":1, "nth-last-of-type":1, + "nth-of-type":1, "only-of-type":1, "only-child":1, "optional":1, "out-of-range":1, + "placeholder":1, "read-only":1, "read-write":1, "required":1, "root":1, + "selection":1, "target":1, "valid":1, "visited":1 + }; CodeMirror.registerHelper("hint", "css", function(cm) { var cur = cm.getCursor(), token = cm.getTokenAt(cur); var inner = CodeMirror.innerMode(cm.getMode(), token.state); if (inner.mode.name != "css") return; + if (token.type == "keyword" && "!important".indexOf(token.string) == 0) + return {list: ["!important"], from: CodeMirror.Pos(cur.line, token.start), + to: CodeMirror.Pos(cur.line, token.end)}; + var start = token.start, end = cur.ch, word = token.string.slice(0, end - start); if (/[^\w$_-]/.test(word)) { word = ""; start = end = cur.ch; diff --git a/static/editor.md/lib/codemirror/addon/hint/html-hint.js b/static/editor.md/lib/codemirror/addon/hint/html-hint.js index c6769bca..9878eca6 100644 --- a/static/editor.md/lib/codemirror/addon/hint/html-hint.js +++ b/static/editor.md/lib/codemirror/addon/hint/html-hint.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -98,6 +98,7 @@ dfn: s, dir: s, div: s, + dialog: { attrs: { open: null } }, dl: s, dt: s, em: s, @@ -322,6 +323,8 @@ itemtype: null, lang: ["en", "es"], spellcheck: ["true", "false"], + autocorrect: ["true", "false"], + autocapitalize: ["true", "false"], style: null, tabindex: ["1", "2", "3", "4", "5", "6", "7", "8", "9"], title: null, diff --git a/static/editor.md/lib/codemirror/addon/hint/show-hint.css b/static/editor.md/lib/codemirror/addon/hint/show-hint.css index 924e638f..5617ccca 100644 --- a/static/editor.md/lib/codemirror/addon/hint/show-hint.css +++ b/static/editor.md/lib/codemirror/addon/hint/show-hint.css @@ -25,8 +25,6 @@ margin: 0; padding: 0 4px; border-radius: 2px; - max-width: 19em; - overflow: hidden; white-space: pre; color: black; cursor: pointer; diff --git a/static/editor.md/lib/codemirror/addon/hint/show-hint.js b/static/editor.md/lib/codemirror/addon/hint/show-hint.js index f5446194..2be2c716 100644 --- a/static/editor.md/lib/codemirror/addon/hint/show-hint.js +++ b/static/editor.md/lib/codemirror/addon/hint/show-hint.js @@ -1,5 +1,7 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE + +// declare global: DOMRect (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -24,44 +26,63 @@ return cm.showHint(newOpts); }; - var asyncRunID = 0; - function retrieveHints(getter, cm, options, then) { - if (getter.async) { - var id = ++asyncRunID; - getter(cm, function(hints) { - if (asyncRunID == id) then(hints); - }, options); - } else { - then(getter(cm, options)); - } - } - CodeMirror.defineExtension("showHint", function(options) { - // We want a single cursor position. - if (this.listSelections().length > 1 || this.somethingSelected()) return; + options = parseOptions(this, this.getCursor("start"), options); + var selections = this.listSelections() + if (selections.length > 1) return; + // By default, don't allow completion when something is selected. + // A hint function can have a `supportsSelection` property to + // indicate that it can handle selections. + if (this.somethingSelected()) { + if (!options.hint.supportsSelection) return; + // Don't try with cross-line selections + for (var i = 0; i < selections.length; i++) + if (selections[i].head.line != selections[i].anchor.line) return; + } if (this.state.completionActive) this.state.completionActive.close(); var completion = this.state.completionActive = new Completion(this, options); - var getHints = completion.options.hint; - if (!getHints) return; + if (!completion.options.hint) return; CodeMirror.signal(this, "startCompletion", this); - return retrieveHints(getHints, this, completion.options, function(hints) { completion.showHints(hints); }); + completion.update(true); }); + CodeMirror.defineExtension("closeHint", function() { + if (this.state.completionActive) this.state.completionActive.close() + }) + function Completion(cm, options) { this.cm = cm; - this.options = this.buildOptions(options); - this.widget = this.onClose = null; + this.options = options; + this.widget = null; + this.debounce = 0; + this.tick = 0; + this.startPos = this.cm.getCursor("start"); + this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length; + + if (this.options.updateOnCursorActivity) { + var self = this; + cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); }); + } } + var requestAnimationFrame = window.requestAnimationFrame || function(fn) { + return setTimeout(fn, 1000/60); + }; + var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout; + Completion.prototype = { close: function() { if (!this.active()) return; this.cm.state.completionActive = null; + this.tick = null; + if (this.options.updateOnCursorActivity) { + this.cm.off("cursorActivity", this.activityFunc); + } + if (this.widget && this.data) CodeMirror.signal(this.data, "close"); if (this.widget) this.widget.close(); - if (this.onClose) this.onClose(); CodeMirror.signal(this.cm, "endCompletion", this.cm); }, @@ -70,92 +91,83 @@ }, pick: function(data, i) { - var completion = data.list[i]; - if (completion.hint) completion.hint(this.cm, data, completion); - else this.cm.replaceRange(getText(completion), completion.from || data.from, - completion.to || data.to, "complete"); - CodeMirror.signal(data, "pick", completion); - this.close(); + var completion = data.list[i], self = this; + this.cm.operation(function() { + if (completion.hint) + completion.hint(self.cm, data, completion); + else + self.cm.replaceRange(getText(completion), completion.from || data.from, + completion.to || data.to, "complete"); + CodeMirror.signal(data, "pick", completion); + self.cm.scrollIntoView(); + }); + if (this.options.closeOnPick) { + this.close(); + } }, - showHints: function(data) { - if (!data || !data.list.length || !this.active()) return this.close(); + cursorActivity: function() { + if (this.debounce) { + cancelAnimationFrame(this.debounce); + this.debounce = 0; + } - if (this.options.completeSingle && data.list.length == 1) - this.pick(data, 0); - else - this.showWidget(data); + var identStart = this.startPos; + if(this.data) { + identStart = this.data.from; + } + + var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line); + if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch || + pos.ch < identStart.ch || this.cm.somethingSelected() || + (!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) { + this.close(); + } else { + var self = this; + this.debounce = requestAnimationFrame(function() {self.update();}); + if (this.widget) this.widget.disable(); + } }, - showWidget: function(data) { - this.widget = new Widget(this, data); - CodeMirror.signal(data, "shown"); + update: function(first) { + if (this.tick == null) return + var self = this, myTick = ++this.tick + fetchHints(this.options.hint, this.cm, this.options, function(data) { + if (self.tick == myTick) self.finishUpdate(data, first) + }) + }, - var debounce = 0, completion = this, finished; - var closeOn = this.options.closeCharacters; - var startPos = this.cm.getCursor(), startLen = this.cm.getLine(startPos.line).length; + finishUpdate: function(data, first) { + if (this.data) CodeMirror.signal(this.data, "update"); - var requestAnimationFrame = window.requestAnimationFrame || function(fn) { - return setTimeout(fn, 1000/60); - }; - var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout; + var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle); + if (this.widget) this.widget.close(); - function done() { - if (finished) return; - finished = true; - completion.close(); - completion.cm.off("cursorActivity", activity); - if (data) CodeMirror.signal(data, "close"); - } + this.data = data; - function update() { - if (finished) return; - CodeMirror.signal(data, "update"); - retrieveHints(completion.options.hint, completion.cm, completion.options, finishUpdate); - } - function finishUpdate(data_) { - data = data_; - if (finished) return; - if (!data || !data.list.length) return done(); - if (completion.widget) completion.widget.close(); - completion.widget = new Widget(completion, data); - } - - function clearDebounce() { - if (debounce) { - cancelAnimationFrame(debounce); - debounce = 0; - } - } - - function activity() { - clearDebounce(); - var pos = completion.cm.getCursor(), line = completion.cm.getLine(pos.line); - if (pos.line != startPos.line || line.length - pos.ch != startLen - startPos.ch || - pos.ch < startPos.ch || completion.cm.somethingSelected() || - (pos.ch && closeOn.test(line.charAt(pos.ch - 1)))) { - completion.close(); + if (data && data.list.length) { + if (picked && data.list.length == 1) { + this.pick(data, 0); } else { - debounce = requestAnimationFrame(update); - if (completion.widget) completion.widget.close(); + this.widget = new Widget(this, data); + CodeMirror.signal(data, "shown"); } } - this.cm.on("cursorActivity", activity); - this.onClose = done; - }, - - buildOptions: function(options) { - var editor = this.cm.options.hintOptions; - var out = {}; - for (var prop in defaultOptions) out[prop] = defaultOptions[prop]; - if (editor) for (var prop in editor) - if (editor[prop] !== undefined) out[prop] = editor[prop]; - if (options) for (var prop in options) - if (options[prop] !== undefined) out[prop] = options[prop]; - return out; } }; + function parseOptions(cm, pos, options) { + var editor = cm.options.hintOptions; + var out = {}; + for (var prop in defaultOptions) out[prop] = defaultOptions[prop]; + if (editor) for (var prop in editor) + if (editor[prop] !== undefined) out[prop] = editor[prop]; + if (options) for (var prop in options) + if (options[prop] !== undefined) out[prop] = options[prop]; + if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos) + return out; + } + function getText(completion) { if (typeof completion == "string") return completion; else return completion.text; @@ -173,6 +185,14 @@ Tab: handle.pick, Esc: handle.close }; + + var mac = /Mac/.test(navigator.platform); + + if (mac) { + baseMap["Ctrl-P"] = function() {handle.moveFocus(-1);}; + baseMap["Ctrl-N"] = function() {handle.moveFocus(1);}; + } + var custom = completion.options.customKeys; var ourMap = custom ? {} : baseMap; function addBinding(key, val) { @@ -204,58 +224,95 @@ } function Widget(completion, data) { + this.id = "cm-complete-" + Math.floor(Math.random(1e6)) this.completion = completion; this.data = data; + this.picked = false; var widget = this, cm = completion.cm; + var ownerDocument = cm.getInputField().ownerDocument; + var parentWindow = ownerDocument.defaultView || ownerDocument.parentWindow; - var hints = this.hints = document.createElement("ul"); - hints.className = "CodeMirror-hints"; + var hints = this.hints = ownerDocument.createElement("ul"); + hints.setAttribute("role", "listbox") + hints.setAttribute("aria-expanded", "true") + hints.id = this.id + var theme = completion.cm.options.theme; + hints.className = "CodeMirror-hints " + theme; this.selectedHint = data.selectedHint || 0; var completions = data.list; for (var i = 0; i < completions.length; ++i) { - var elt = hints.appendChild(document.createElement("li")), cur = completions[i]; + var elt = hints.appendChild(ownerDocument.createElement("li")), cur = completions[i]; var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS); if (cur.className != null) className = cur.className + " " + className; elt.className = className; + if (i == this.selectedHint) elt.setAttribute("aria-selected", "true") + elt.id = this.id + "-" + i + elt.setAttribute("role", "option") if (cur.render) cur.render(elt, data, cur); - else elt.appendChild(document.createTextNode(cur.displayText || getText(cur))); + else elt.appendChild(ownerDocument.createTextNode(cur.displayText || getText(cur))); elt.hintId = i; } + var container = completion.options.container || ownerDocument.body; var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null); var left = pos.left, top = pos.bottom, below = true; - hints.style.left = left + "px"; - hints.style.top = top + "px"; + var offsetLeft = 0, offsetTop = 0; + if (container !== ownerDocument.body) { + // We offset the cursor position because left and top are relative to the offsetParent's top left corner. + var isContainerPositioned = ['absolute', 'relative', 'fixed'].indexOf(parentWindow.getComputedStyle(container).position) !== -1; + var offsetParent = isContainerPositioned ? container : container.offsetParent; + var offsetParentPosition = offsetParent.getBoundingClientRect(); + var bodyPosition = ownerDocument.body.getBoundingClientRect(); + offsetLeft = (offsetParentPosition.left - bodyPosition.left - offsetParent.scrollLeft); + offsetTop = (offsetParentPosition.top - bodyPosition.top - offsetParent.scrollTop); + } + hints.style.left = (left - offsetLeft) + "px"; + hints.style.top = (top - offsetTop) + "px"; + // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor. - var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth); - var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight); - (completion.options.container || document.body).appendChild(hints); - var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH; + var winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth); + var winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight); + container.appendChild(hints); + cm.getInputField().setAttribute("aria-autocomplete", "list") + cm.getInputField().setAttribute("aria-owns", this.id) + cm.getInputField().setAttribute("aria-activedescendant", this.id + "-" + this.selectedHint) + + var box = completion.options.moveOnOverlap ? hints.getBoundingClientRect() : new DOMRect(); + var scrolls = completion.options.paddingForScrollbar ? hints.scrollHeight > hints.clientHeight + 1 : false; + + // Compute in the timeout to avoid reflow on init + var startScroll; + setTimeout(function() { startScroll = cm.getScrollInfo(); }); + + var overlapY = box.bottom - winH; if (overlapY > 0) { var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top); if (curTop - height > 0) { // Fits above cursor - hints.style.top = (top = pos.top - height) + "px"; + hints.style.top = (top = pos.top - height - offsetTop) + "px"; below = false; } else if (height > winH) { hints.style.height = (winH - 5) + "px"; - hints.style.top = (top = pos.bottom - box.top) + "px"; + hints.style.top = (top = pos.bottom - box.top - offsetTop) + "px"; var cursor = cm.getCursor(); if (data.from.ch != cursor.ch) { pos = cm.cursorCoords(cursor); - hints.style.left = (left = pos.left) + "px"; + hints.style.left = (left = pos.left - offsetLeft) + "px"; box = hints.getBoundingClientRect(); } } } var overlapX = box.right - winW; + if (scrolls) overlapX += cm.display.nativeBarWidth; if (overlapX > 0) { if (box.right - box.left > winW) { hints.style.width = (winW - 5) + "px"; overlapX -= (box.right - box.left) - winW; } - hints.style.left = (left = pos.left - overlapX) + "px"; + hints.style.left = (left = pos.left - overlapX - offsetLeft) + "px"; } + if (scrolls) for (var node = hints.firstChild; node; node = node.nextSibling) + node.style.paddingRight = cm.display.nativeBarWidth + "px" cm.addKeyMap(this.keyMap = buildKeyMap(completion, { moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); }, @@ -273,11 +330,11 @@ cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); }); } - var startScroll = cm.getScrollInfo(); cm.on("scroll", this.onScroll = function() { var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect(); + if (!startScroll) startScroll = cm.getScrollInfo(); var newTop = top + startScroll.top - curScroll.top; - var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop); + var point = newTop - (parentWindow.pageYOffset || (ownerDocument.documentElement || ownerDocument.body).scrollTop); if (!below) point += hints.offsetHeight; if (point <= editor.top || point >= editor.bottom) return completion.close(); hints.style.top = newTop + "px"; @@ -301,7 +358,13 @@ setTimeout(function(){cm.focus();}, 20); }); - CodeMirror.signal(data, "select", completions[0], hints.firstChild); + // The first hint doesn't need to be scrolled to on init + var selectedHintRange = this.getSelectedHintRange(); + if (selectedHintRange.from !== 0 || selectedHintRange.to !== 0) { + this.scrollToActive(); + } + + CodeMirror.signal(data, "select", completions[this.selectedHint], hints.childNodes[this.selectedHint]); return true; } @@ -309,8 +372,11 @@ close: function() { if (this.completion.widget != this) return; this.completion.widget = null; - this.hints.parentNode.removeChild(this.hints); + if (this.hints.parentNode) this.hints.parentNode.removeChild(this.hints); this.completion.cm.removeKeyMap(this.keyMap); + var input = this.completion.cm.getInputField() + input.removeAttribute("aria-activedescendant") + input.removeAttribute("aria-owns") var cm = this.completion.cm; if (this.completion.options.closeOnUnfocus) { @@ -320,6 +386,13 @@ cm.off("scroll", this.onScroll); }, + disable: function() { + this.completion.cm.removeKeyMap(this.keyMap); + var widget = this; + this.keyMap = {Enter: function() { widget.picked = true; }}; + this.completion.cm.addKeyMap(this.keyMap); + }, + pick: function() { this.completion.pick(this.data, this.selectedHint); }, @@ -331,49 +404,107 @@ i = avoidWrap ? 0 : this.data.list.length - 1; if (this.selectedHint == i) return; var node = this.hints.childNodes[this.selectedHint]; - node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, ""); + if (node) { + node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, ""); + node.removeAttribute("aria-selected") + } node = this.hints.childNodes[this.selectedHint = i]; node.className += " " + ACTIVE_HINT_ELEMENT_CLASS; - if (node.offsetTop < this.hints.scrollTop) - this.hints.scrollTop = node.offsetTop - 3; - else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight) - this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3; + node.setAttribute("aria-selected", "true") + this.completion.cm.getInputField().setAttribute("aria-activedescendant", node.id) + this.scrollToActive() CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node); }, + scrollToActive: function() { + var selectedHintRange = this.getSelectedHintRange(); + var node1 = this.hints.childNodes[selectedHintRange.from]; + var node2 = this.hints.childNodes[selectedHintRange.to]; + var firstNode = this.hints.firstChild; + if (node1.offsetTop < this.hints.scrollTop) + this.hints.scrollTop = node1.offsetTop - firstNode.offsetTop; + else if (node2.offsetTop + node2.offsetHeight > this.hints.scrollTop + this.hints.clientHeight) + this.hints.scrollTop = node2.offsetTop + node2.offsetHeight - this.hints.clientHeight + firstNode.offsetTop; + }, + screenAmount: function() { return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1; + }, + + getSelectedHintRange: function() { + var margin = this.completion.options.scrollMargin || 0; + return { + from: Math.max(0, this.selectedHint - margin), + to: Math.min(this.data.list.length - 1, this.selectedHint + margin), + }; } }; - CodeMirror.registerHelper("hint", "auto", function(cm, options) { - var helpers = cm.getHelpers(cm.getCursor(), "hint"), words; - if (helpers.length) { - for (var i = 0; i < helpers.length; i++) { - var cur = helpers[i](cm, options); - if (cur && cur.list.length) return cur; - } - } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) { - if (words) return CodeMirror.hint.fromList(cm, {words: words}); - } else if (CodeMirror.hint.anyword) { - return CodeMirror.hint.anyword(cm, options); + function applicableHelpers(cm, helpers) { + if (!cm.somethingSelected()) return helpers + var result = [] + for (var i = 0; i < helpers.length; i++) + if (helpers[i].supportsSelection) result.push(helpers[i]) + return result + } + + function fetchHints(hint, cm, options, callback) { + if (hint.async) { + hint(cm, callback, options) + } else { + var result = hint(cm, options) + if (result && result.then) result.then(callback) + else callback(result) } + } + + function resolveAutoHints(cm, pos) { + var helpers = cm.getHelpers(pos, "hint"), words + if (helpers.length) { + var resolved = function(cm, callback, options) { + var app = applicableHelpers(cm, helpers); + function run(i) { + if (i == app.length) return callback(null) + fetchHints(app[i], cm, options, function(result) { + if (result && result.list.length > 0) callback(result) + else run(i + 1) + }) + } + run(0) + } + resolved.async = true + resolved.supportsSelection = true + return resolved + } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) { + return function(cm) { return CodeMirror.hint.fromList(cm, {words: words}) } + } else if (CodeMirror.hint.anyword) { + return function(cm, options) { return CodeMirror.hint.anyword(cm, options) } + } else { + return function() {} + } + } + + CodeMirror.registerHelper("hint", "auto", { + resolve: resolveAutoHints }); CodeMirror.registerHelper("hint", "fromList", function(cm, options) { - var cur = cm.getCursor(), token = cm.getTokenAt(cur); + var cur = cm.getCursor(), token = cm.getTokenAt(cur) + var term, from = CodeMirror.Pos(cur.line, token.start), to = cur + if (token.start < cur.ch && /\w/.test(token.string.charAt(cur.ch - token.start - 1))) { + term = token.string.substr(0, cur.ch - token.start) + } else { + term = "" + from = cur + } var found = []; for (var i = 0; i < options.words.length; i++) { var word = options.words[i]; - if (word.slice(0, token.string.length) == token.string) + if (word.slice(0, term.length) == term) found.push(word); } - if (found.length) return { - list: found, - from: CodeMirror.Pos(cur.line, token.start), - to: CodeMirror.Pos(cur.line, token.end) - }; + if (found.length) return {list: found, from: from, to: to}; }); CodeMirror.commands.autocomplete = CodeMirror.showHint; @@ -383,11 +514,15 @@ completeSingle: true, alignWithWord: true, closeCharacters: /[\s()\[\]{};:>,]/, + closeOnPick: true, closeOnUnfocus: true, - completeOnSingleClick: false, + updateOnCursorActivity: true, + completeOnSingleClick: true, container: null, customKeys: null, - extraKeys: null + extraKeys: null, + paddingForScrollbar: true, + moveOnOverlap: true, }; CodeMirror.defineOption("hintOptions", null); diff --git a/static/editor.md/lib/codemirror/addon/hint/sql-hint.js b/static/editor.md/lib/codemirror/addon/hint/sql-hint.js index 5b0cc769..efdce813 100644 --- a/static/editor.md/lib/codemirror/addon/hint/sql-hint.js +++ b/static/editor.md/lib/codemirror/addon/hint/sql-hint.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -14,11 +14,14 @@ var tables; var defaultTable; var keywords; + var identifierQuote; var CONS = { QUERY_DIV: ";", ALIAS_KEYWORD: "AS" }; - var Pos = CodeMirror.Pos; + var Pos = CodeMirror.Pos, cmpPos = CodeMirror.cmpPos; + + function isArray(val) { return Object.prototype.toString.call(val) == "[object Array]" } function getKeywords(editor) { var mode = editor.doc.modeOption; @@ -26,14 +29,38 @@ return CodeMirror.resolveMode(mode).keywords; } + function getIdentifierQuote(editor) { + var mode = editor.doc.modeOption; + if (mode === "sql") mode = "text/x-sql"; + return CodeMirror.resolveMode(mode).identifierQuote || "`"; + } + function getText(item) { return typeof item == "string" ? item : item.text; } - function getItem(list, item) { - if (!list.slice) return list[item]; - for (var i = list.length - 1; i >= 0; i--) if (getText(list[i]) == item) - return list[i]; + function wrapTable(name, value) { + if (isArray(value)) value = {columns: value} + if (!value.text) value.text = name + return value + } + + function parseTables(input) { + var result = {} + if (isArray(input)) { + for (var i = input.length - 1; i >= 0; i--) { + var item = input[i] + result[getText(item).toUpperCase()] = wrapTable(getText(item), item) + } + } else if (input) { + for (var name in input) + result[name.toUpperCase()] = wrapTable(name, input[name]) + } + return result + } + + function getTable(name) { + return tables[name.toUpperCase()] } function shallowClone(object) { @@ -50,29 +77,41 @@ } function addMatches(result, search, wordlist, formatter) { - for (var word in wordlist) { - if (!wordlist.hasOwnProperty(word)) continue; - if (Array.isArray(wordlist)) { - word = wordlist[word]; - } - if (match(search, word)) { - result.push(formatter(word)); + if (isArray(wordlist)) { + for (var i = 0; i < wordlist.length; i++) + if (match(search, wordlist[i])) result.push(formatter(wordlist[i])) + } else { + for (var word in wordlist) if (wordlist.hasOwnProperty(word)) { + var val = wordlist[word] + if (!val || val === true) + val = word + else + val = val.displayText ? {text: val.text, displayText: val.displayText} : val.text + if (match(search, val)) result.push(formatter(val)) } } } function cleanName(name) { - // Get rid name from backticks(`) and preceding dot(.) + // Get rid name from identifierQuote and preceding dot(.) if (name.charAt(0) == ".") { name = name.substr(1); } - return name.replace(/`/g, ""); + // replace duplicated identifierQuotes with single identifierQuotes + // and remove single identifierQuotes + var nameParts = name.split(identifierQuote+identifierQuote); + for (var i = 0; i < nameParts.length; i++) + nameParts[i] = nameParts[i].replace(new RegExp(identifierQuote,"g"), ""); + return nameParts.join(identifierQuote); } - function insertBackticks(name) { + function insertIdentifierQuotes(name) { var nameParts = getText(name).split("."); for (var i = 0; i < nameParts.length; i++) - nameParts[i] = "`" + nameParts[i] + "`"; + nameParts[i] = identifierQuote + + // duplicate identifierQuotes + nameParts[i].replace(new RegExp(identifierQuote,"g"), identifierQuote+identifierQuote) + + identifierQuote; var escaped = nameParts.join("."); if (typeof name == "string") return escaped; name = shallowClone(name); @@ -81,14 +120,14 @@ } function nameCompletion(cur, token, result, editor) { - // Try to complete table, colunm names and return start position of completion - var useBacktick = false; + // Try to complete table, column names and return start position of completion + var useIdentifierQuotes = false; var nameParts = []; var start = token.start; var cont = true; while (cont) { cont = (token.string.charAt(0) == "."); - useBacktick = useBacktick || (token.string.charAt(0) == "`"); + useIdentifierQuotes = useIdentifierQuotes || (token.string.charAt(0) == identifierQuote); start = token.start; nameParts.unshift(cleanName(token.string)); @@ -103,35 +142,42 @@ // Try to complete table names var string = nameParts.join("."); addMatches(result, string, tables, function(w) { - return useBacktick ? insertBackticks(w) : w; + return useIdentifierQuotes ? insertIdentifierQuotes(w) : w; }); // Try to complete columns from defaultTable addMatches(result, string, defaultTable, function(w) { - return useBacktick ? insertBackticks(w) : w; + return useIdentifierQuotes ? insertIdentifierQuotes(w) : w; }); // Try to complete columns string = nameParts.pop(); var table = nameParts.join("."); + var alias = false; + var aliasTable = table; // Check if table is available. If not, find table by Alias - if (!getItem(tables, table)) + if (!getTable(table)) { + var oldTable = table; table = findTableByAlias(table, editor); + if (table !== oldTable) alias = true; + } - var columns = getItem(tables, table); - if (columns && Array.isArray(tables) && columns.columns) + var columns = getTable(table); + if (columns && columns.columns) columns = columns.columns; if (columns) { addMatches(result, string, columns, function(w) { + var tableInsert = table; + if (alias == true) tableInsert = aliasTable; if (typeof w == "string") { - w = table + "." + w; + w = tableInsert + "." + w; } else { w = shallowClone(w); - w.text = table + "." + w.text; + w.text = tableInsert + "." + w.text; } - return useBacktick ? insertBackticks(w) : w; + return useIdentifierQuotes ? insertIdentifierQuotes(w) : w; }); } @@ -139,21 +185,9 @@ } function eachWord(lineText, f) { - if (!lineText) return; - var excepted = /[,;]/g; - var words = lineText.split(" "); - for (var i = 0; i < words.length; i++) { - f(words[i]?words[i].replace(excepted, '') : ''); - } - } - - function convertCurToNumber(cur) { - // max characters of a line is 999,999. - return cur.line + cur.ch / Math.pow(10, 6); - } - - function convertNumberToCur(num) { - return Pos(Math.floor(num), +num.toString().split('.').pop()); + var words = lineText.split(/\s+/) + for (var i = 0; i < words.length; i++) + if (words[i]) f(words[i].replace(/[`,;]/g, '')) } function findTableByAlias(alias, editor) { @@ -178,38 +212,49 @@ separator.push(Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).text.length)); //find valid range - var prevItem = 0; - var current = convertCurToNumber(editor.getCursor()); - for (var i=0; i< separator.length; i++) { - var _v = convertCurToNumber(separator[i]); - if (current > prevItem && current <= _v) { - validRange = { start: convertNumberToCur(prevItem), end: convertNumberToCur(_v) }; + var prevItem = null; + var current = editor.getCursor() + for (var i = 0; i < separator.length; i++) { + if ((prevItem == null || cmpPos(current, prevItem) > 0) && cmpPos(current, separator[i]) <= 0) { + validRange = {start: prevItem, end: separator[i]}; break; } - prevItem = _v; + prevItem = separator[i]; } - var query = doc.getRange(validRange.start, validRange.end, false); + if (validRange.start) { + var query = doc.getRange(validRange.start, validRange.end, false); - for (var i = 0; i < query.length; i++) { - var lineText = query[i]; - eachWord(lineText, function(word) { - var wordUpperCase = word.toUpperCase(); - if (wordUpperCase === aliasUpperCase && getItem(tables, previousWord)) - table = previousWord; - if (wordUpperCase !== CONS.ALIAS_KEYWORD) - previousWord = word; - }); - if (table) break; + for (var i = 0; i < query.length; i++) { + var lineText = query[i]; + eachWord(lineText, function(word) { + var wordUpperCase = word.toUpperCase(); + if (wordUpperCase === aliasUpperCase && getTable(previousWord)) + table = previousWord; + if (wordUpperCase !== CONS.ALIAS_KEYWORD) + previousWord = word; + }); + if (table) break; + } } return table; } CodeMirror.registerHelper("hint", "sql", function(editor, options) { - tables = (options && options.tables) || {}; + tables = parseTables(options && options.tables) var defaultTableName = options && options.defaultTable; - defaultTable = (defaultTableName && getItem(tables, defaultTableName)) || []; - keywords = keywords || getKeywords(editor); + var disableKeywords = options && options.disableKeywords; + defaultTable = defaultTableName && getTable(defaultTableName); + keywords = getKeywords(editor); + identifierQuote = getIdentifierQuote(editor); + + if (defaultTableName && !defaultTable) + defaultTable = findTableByAlias(defaultTableName, editor); + + defaultTable = defaultTable || []; + + if (defaultTable.columns) + defaultTable = defaultTable.columns; var cur = editor.getCursor(); var result = []; @@ -219,7 +264,7 @@ token.string = token.string.slice(0, cur.ch - token.start); } - if (token.string.match(/^[.`\w@]\w*$/)) { + if (token.string.match(/^[.`"'\w@][\w$#]*$/g)) { search = token.string; start = token.start; end = token.end; @@ -227,13 +272,32 @@ start = end = cur.ch; search = ""; } - if (search.charAt(0) == "." || search.charAt(0) == "`") { + if (search.charAt(0) == "." || search.charAt(0) == identifierQuote) { start = nameCompletion(cur, token, result, editor); } else { - addMatches(result, search, tables, function(w) {return w;}); - addMatches(result, search, defaultTable, function(w) {return w;}); - addMatches(result, search, keywords, function(w) {return w.toUpperCase();}); - } + var objectOrClass = function(w, className) { + if (typeof w === "object") { + w.className = className; + } else { + w = { text: w, className: className }; + } + return w; + }; + addMatches(result, search, defaultTable, function(w) { + return objectOrClass(w, "CodeMirror-hint-table CodeMirror-hint-default-table"); + }); + addMatches( + result, + search, + tables, function(w) { + return objectOrClass(w, "CodeMirror-hint-table"); + } + ); + if (!disableKeywords) + addMatches(result, search, keywords, function(w) { + return objectOrClass(w.toUpperCase(), "CodeMirror-hint-keyword"); + }); + } return {list: result, from: Pos(cur.line, start), to: Pos(cur.line, end)}; }); diff --git a/static/editor.md/lib/codemirror/addon/hint/xml-hint.js b/static/editor.md/lib/codemirror/addon/hint/xml-hint.js index 9b9baa0c..2b315312 100644 --- a/static/editor.md/lib/codemirror/addon/hint/xml-hint.js +++ b/static/editor.md/lib/codemirror/addon/hint/xml-hint.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -13,9 +13,15 @@ var Pos = CodeMirror.Pos; + function matches(hint, typed, matchInMiddle) { + if (matchInMiddle) return hint.indexOf(typed) >= 0; + else return hint.lastIndexOf(typed, 0) == 0; + } + function getHints(cm, options) { var tags = options && options.schemaInfo; var quote = (options && options.quoteChar) || '"'; + var matchInMiddle = options && options.matchInMiddle; if (!tags) return; var cur = cm.getCursor(), token = cm.getTokenAt(cur); if (token.end > cur.ch) { @@ -23,7 +29,7 @@ token.string = token.string.slice(0, cur.ch - token.start); } var inner = CodeMirror.innerMode(cm.getMode(), token.state); - if (inner.mode.name != "xml") return; + if (!inner.mode.xmlCurrentTag) return var result = [], replaceToken = false, prefix; var tag = /\btag\b/.test(token.type) && !/>$/.test(token.string); var tagName = tag && /^\w/.test(token.string), tagStart; @@ -38,25 +44,28 @@ tagType = "close"; } - if (!tag && !inner.state.tagName || tagType) { + var tagInfo = inner.mode.xmlCurrentTag(inner.state) + if (!tag && !tagInfo || tagType) { if (tagName) prefix = token.string; replaceToken = tagType; - var cx = inner.state.context, curTag = cx && tags[cx.tagName]; - var childList = cx ? curTag && curTag.children : tags["!top"]; + var context = inner.mode.xmlCurrentContext ? inner.mode.xmlCurrentContext(inner.state) : [] + var inner = context.length && context[context.length - 1] + var curTag = inner && tags[inner] + var childList = inner ? curTag && curTag.children : tags["!top"]; if (childList && tagType != "close") { - for (var i = 0; i < childList.length; ++i) if (!prefix || childList[i].lastIndexOf(prefix, 0) == 0) + for (var i = 0; i < childList.length; ++i) if (!prefix || matches(childList[i], prefix, matchInMiddle)) result.push("<" + childList[i]); } else if (tagType != "close") { for (var name in tags) - if (tags.hasOwnProperty(name) && name != "!top" && name != "!attrs" && (!prefix || name.lastIndexOf(prefix, 0) == 0)) + if (tags.hasOwnProperty(name) && name != "!top" && name != "!attrs" && (!prefix || matches(name, prefix, matchInMiddle))) result.push("<" + name); } - if (cx && (!prefix || tagType == "close" && cx.tagName.lastIndexOf(prefix, 0) == 0)) - result.push(""); + if (inner && (!prefix || tagType == "close" && matches(inner, prefix, matchInMiddle))) + result.push(""); } else { // Attribute completion - var curTag = tags[inner.state.tagName], attrs = curTag && curTag.attrs; + var curTag = tagInfo && tags[tagInfo.name], attrs = curTag && curTag.attrs; var globalAttrs = tags["!attrs"]; if (!attrs && !globalAttrs) return; if (!attrs) { @@ -86,24 +95,37 @@ quote = token.string.charAt(len - 1); prefix = token.string.substr(n, len - 2); } + if (n) { // an opening quote + var line = cm.getLine(cur.line); + if (line.length > token.end && line.charAt(token.end) == quote) token.end++; // include a closing quote + } replaceToken = true; } - for (var i = 0; i < atValues.length; ++i) if (!prefix || atValues[i].lastIndexOf(prefix, 0) == 0) - result.push(quote + atValues[i] + quote); + var returnHintsFromAtValues = function(atValues) { + if (atValues) + for (var i = 0; i < atValues.length; ++i) if (!prefix || matches(atValues[i], prefix, matchInMiddle)) + result.push(quote + atValues[i] + quote); + return returnHints(); + }; + if (atValues && atValues.then) return atValues.then(returnHintsFromAtValues); + return returnHintsFromAtValues(atValues); } else { // An attribute name if (token.type == "attribute") { prefix = token.string; replaceToken = true; } - for (var attr in attrs) if (attrs.hasOwnProperty(attr) && (!prefix || attr.lastIndexOf(prefix, 0) == 0)) + for (var attr in attrs) if (attrs.hasOwnProperty(attr) && (!prefix || matches(attr, prefix, matchInMiddle))) result.push(attr); } } - return { - list: result, - from: replaceToken ? Pos(cur.line, tagStart == null ? token.start : tagStart) : cur, - to: replaceToken ? Pos(cur.line, token.end) : cur - }; + function returnHints() { + return { + list: result, + from: replaceToken ? Pos(cur.line, tagStart == null ? token.start : tagStart) : cur, + to: replaceToken ? Pos(cur.line, token.end) : cur + }; + } + return returnHints(); } CodeMirror.registerHelper("hint", "xml", getHints); diff --git a/static/editor.md/lib/codemirror/addon/lint/coffeescript-lint.js b/static/editor.md/lib/codemirror/addon/lint/coffeescript-lint.js index 7e39428f..a54c7035 100644 --- a/static/editor.md/lib/codemirror/addon/lint/coffeescript-lint.js +++ b/static/editor.md/lib/codemirror/addon/lint/coffeescript-lint.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE // Depends on coffeelint.js from http://www.coffeelint.org/js/coffeelint.js @@ -17,6 +17,12 @@ CodeMirror.registerHelper("lint", "coffeescript", function(text) { var found = []; + if (!window.coffeelint) { + if (window.console) { + window.console.error("Error: window.coffeelint not defined, CodeMirror CoffeeScript linting cannot run."); + } + return found; + } var parseError = function(err) { var loc = err.lineNumber; found.push({from: CodeMirror.Pos(loc-1, 0), diff --git a/static/editor.md/lib/codemirror/addon/lint/css-lint.js b/static/editor.md/lib/codemirror/addon/lint/css-lint.js index 1f61b479..6058a73e 100644 --- a/static/editor.md/lib/codemirror/addon/lint/css-lint.js +++ b/static/editor.md/lib/codemirror/addon/lint/css-lint.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE // Depends on csslint.js from https://github.com/stubbornella/csslint @@ -15,10 +15,15 @@ })(function(CodeMirror) { "use strict"; -CodeMirror.registerHelper("lint", "css", function(text) { +CodeMirror.registerHelper("lint", "css", function(text, options) { var found = []; - if (!window.CSSLint) return found; - var results = CSSLint.verify(text), messages = results.messages, message = null; + if (!window.CSSLint) { + if (window.console) { + window.console.error("Error: window.CSSLint not defined, CodeMirror CSS linting cannot run."); + } + return found; + } + var results = CSSLint.verify(text, options), messages = results.messages, message = null; for ( var i = 0; i < messages.length; i++) { message = messages[i]; var startLine = message.line -1, endLine = message.line -1, startCol = message.col -1, endCol = message.col; diff --git a/static/editor.md/lib/codemirror/addon/lint/html-lint.js b/static/editor.md/lib/codemirror/addon/lint/html-lint.js new file mode 100644 index 00000000..5295c333 --- /dev/null +++ b/static/editor.md/lib/codemirror/addon/lint/html-lint.js @@ -0,0 +1,59 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: https://codemirror.net/LICENSE + +// Depends on htmlhint.js from http://htmlhint.com/js/htmlhint.js + +// declare global: HTMLHint + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("htmlhint")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "htmlhint"], mod); + else // Plain browser env + mod(CodeMirror, window.HTMLHint); +})(function(CodeMirror, HTMLHint) { + "use strict"; + + var defaultRules = { + "tagname-lowercase": true, + "attr-lowercase": true, + "attr-value-double-quotes": true, + "doctype-first": false, + "tag-pair": true, + "spec-char-escape": true, + "id-unique": true, + "src-not-empty": true, + "attr-no-duplication": true + }; + + CodeMirror.registerHelper("lint", "html", function(text, options) { + var found = []; + if (HTMLHint && !HTMLHint.verify) { + if(typeof HTMLHint.default !== 'undefined') { + HTMLHint = HTMLHint.default; + } else { + HTMLHint = HTMLHint.HTMLHint; + } + } + if (!HTMLHint) HTMLHint = window.HTMLHint; + if (!HTMLHint) { + if (window.console) { + window.console.error("Error: HTMLHint not found, not defined on window, or not available through define/require, CodeMirror HTML linting cannot run."); + } + return found; + } + var messages = HTMLHint.verify(text, options && options.rules || defaultRules); + for (var i = 0; i < messages.length; i++) { + var message = messages[i]; + var startLine = message.line - 1, endLine = message.line - 1, startCol = message.col - 1, endCol = message.col; + found.push({ + from: CodeMirror.Pos(startLine, startCol), + to: CodeMirror.Pos(endLine, endCol), + message: message.message, + severity : message.type + }); + } + return found; + }); +}); diff --git a/static/editor.md/lib/codemirror/addon/lint/json-lint.js b/static/editor.md/lib/codemirror/addon/lint/json-lint.js index 9dbb616b..ac1d6ec2 100644 --- a/static/editor.md/lib/codemirror/addon/lint/json-lint.js +++ b/static/editor.md/lib/codemirror/addon/lint/json-lint.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE // Depends on jsonlint.js from https://github.com/zaach/jsonlint @@ -17,6 +17,15 @@ CodeMirror.registerHelper("lint", "json", function(text) { var found = []; + if (!window.jsonlint) { + if (window.console) { + window.console.error("Error: window.jsonlint not defined, CodeMirror JSON linting cannot run."); + } + return found; + } + // for jsonlint's web dist jsonlint is exported as an object with a single property parser, of which parseError + // is a subproperty + var jsonlint = window.jsonlint.parser || window.jsonlint jsonlint.parseError = function(str, hash) { var loc = hash.loc; found.push({from: CodeMirror.Pos(loc.first_line - 1, loc.first_column), diff --git a/static/editor.md/lib/codemirror/addon/lint/lint.css b/static/editor.md/lib/codemirror/addon/lint/lint.css index 414a9a0e..e1560db9 100644 --- a/static/editor.md/lib/codemirror/addon/lint/lint.css +++ b/static/editor.md/lib/codemirror/addon/lint/lint.css @@ -4,10 +4,10 @@ } .CodeMirror-lint-tooltip { - background-color: infobackground; + background-color: #ffd; border: 1px solid black; border-radius: 4px 4px 4px 4px; - color: infotext; + color: black; font-family: monospace; font-size: 10pt; overflow: hidden; @@ -25,22 +25,20 @@ -ms-transition: opacity .4s; } -.CodeMirror-lint-mark-error, .CodeMirror-lint-mark-warning { +.CodeMirror-lint-mark { background-position: left bottom; background-repeat: repeat-x; } -.CodeMirror-lint-mark-error { - background-image: - url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==") - ; -} - .CodeMirror-lint-mark-warning { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII="); } -.CodeMirror-lint-marker-error, .CodeMirror-lint-marker-warning { +.CodeMirror-lint-mark-error { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg=="); +} + +.CodeMirror-lint-marker { background-position: center center; background-repeat: no-repeat; cursor: pointer; @@ -51,23 +49,31 @@ position: relative; } -.CodeMirror-lint-message-error, .CodeMirror-lint-message-warning { +.CodeMirror-lint-message { padding-left: 18px; background-position: top left; background-repeat: no-repeat; } -.CodeMirror-lint-marker-error, .CodeMirror-lint-message-error { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII="); -} - .CodeMirror-lint-marker-warning, .CodeMirror-lint-message-warning { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII="); } +.CodeMirror-lint-marker-error, .CodeMirror-lint-message-error { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII="); +} + .CodeMirror-lint-marker-multiple { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAMAAADzjKfhAAAACVBMVEUAAAAAAAC/v7914kyHAAAAAXRSTlMAQObYZgAAACNJREFUeNo1ioEJAAAIwmz/H90iFFSGJgFMe3gaLZ0od+9/AQZ0ADosbYraAAAAAElFTkSuQmCC"); background-repeat: no-repeat; background-position: right bottom; width: 100%; height: 100%; } + +.CodeMirror-lint-line-error { + background-color: rgba(183, 76, 81, 0.08); +} + +.CodeMirror-lint-line-warning { + background-color: rgba(255, 211, 0, 0.1); +} diff --git a/static/editor.md/lib/codemirror/addon/lint/lint.js b/static/editor.md/lib/codemirror/addon/lint/lint.js index 18eb7090..1613deb9 100644 --- a/static/editor.md/lib/codemirror/addon/lint/lint.js +++ b/static/editor.md/lib/codemirror/addon/lint/lint.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -11,12 +11,16 @@ })(function(CodeMirror) { "use strict"; var GUTTER_ID = "CodeMirror-lint-markers"; + var LINT_LINE_ID = "CodeMirror-lint-line-"; - function showTooltip(e, content) { + function showTooltip(cm, e, content) { var tt = document.createElement("div"); - tt.className = "CodeMirror-lint-tooltip"; + tt.className = "CodeMirror-lint-tooltip cm-s-" + cm.options.theme; tt.appendChild(content.cloneNode(true)); - document.body.appendChild(tt); + if (cm.state.lint.options.selfContain) + cm.getWrapperElement().appendChild(tt); + else + document.body.appendChild(tt); function position(e) { if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position); @@ -38,8 +42,8 @@ setTimeout(function() { rm(tt); }, 600); } - function showTooltipFor(e, content, node) { - var tooltip = showTooltip(e, content); + function showTooltipFor(cm, e, content, node) { + var tooltip = showTooltip(cm, e, content); function hide() { CodeMirror.off(node, "mouseout", hide); if (tooltip) { hideTooltip(tooltip); tooltip = null; } @@ -55,40 +59,64 @@ CodeMirror.on(node, "mouseout", hide); } - function LintState(cm, options, hasGutter) { + function LintState(cm, conf, hasGutter) { this.marked = []; - this.options = options; + if (conf instanceof Function) conf = {getAnnotations: conf}; + if (!conf || conf === true) conf = {}; + this.options = {}; + this.linterOptions = conf.options || {}; + for (var prop in defaults) this.options[prop] = defaults[prop]; + for (var prop in conf) { + if (defaults.hasOwnProperty(prop)) { + if (conf[prop] != null) this.options[prop] = conf[prop]; + } else if (!conf.options) { + this.linterOptions[prop] = conf[prop]; + } + } this.timeout = null; this.hasGutter = hasGutter; this.onMouseOver = function(e) { onMouseOver(cm, e); }; + this.waitingFor = 0 } - function parseOptions(cm, options) { - if (options instanceof Function) return {getAnnotations: options}; - if (!options || options === true) options = {}; - if (!options.getAnnotations) options.getAnnotations = cm.getHelper(CodeMirror.Pos(0, 0), "lint"); - if (!options.getAnnotations) throw new Error("Required option 'getAnnotations' missing (lint addon)"); - return options; + var defaults = { + highlightLines: false, + tooltips: true, + delay: 500, + lintOnChange: true, + getAnnotations: null, + async: false, + selfContain: null, + formatAnnotation: null, + onUpdateLinting: null } function clearMarks(cm) { var state = cm.state.lint; if (state.hasGutter) cm.clearGutter(GUTTER_ID); + if (state.options.highlightLines) clearErrorLines(cm); for (var i = 0; i < state.marked.length; ++i) state.marked[i].clear(); state.marked.length = 0; } - function makeMarker(labels, severity, multiple, tooltips) { + function clearErrorLines(cm) { + cm.eachLine(function(line) { + var has = line.wrapClass && /\bCodeMirror-lint-line-\w+\b/.exec(line.wrapClass); + if (has) cm.removeLineClass(line, "wrap", has[0]); + }) + } + + function makeMarker(cm, labels, severity, multiple, tooltips) { var marker = document.createElement("div"), inner = marker; - marker.className = "CodeMirror-lint-marker-" + severity; + marker.className = "CodeMirror-lint-marker CodeMirror-lint-marker-" + severity; if (multiple) { inner = marker.appendChild(document.createElement("div")); - inner.className = "CodeMirror-lint-marker-multiple"; + inner.className = "CodeMirror-lint-marker CodeMirror-lint-marker-multiple"; } if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) { - showTooltipFor(e, labels, inner); + showTooltipFor(cm, e, labels, inner); }); return marker; @@ -112,23 +140,58 @@ var severity = ann.severity; if (!severity) severity = "error"; var tip = document.createElement("div"); - tip.className = "CodeMirror-lint-message-" + severity; - tip.appendChild(document.createTextNode(ann.message)); + tip.className = "CodeMirror-lint-message CodeMirror-lint-message-" + severity; + if (typeof ann.messageHTML != 'undefined') { + tip.innerHTML = ann.messageHTML; + } else { + tip.appendChild(document.createTextNode(ann.message)); + } return tip; } + function lintAsync(cm, getAnnotations) { + var state = cm.state.lint + var id = ++state.waitingFor + function abort() { + id = -1 + cm.off("change", abort) + } + cm.on("change", abort) + getAnnotations(cm.getValue(), function(annotations, arg2) { + cm.off("change", abort) + if (state.waitingFor != id) return + if (arg2 && annotations instanceof CodeMirror) annotations = arg2 + cm.operation(function() {updateLinting(cm, annotations)}) + }, state.linterOptions, cm); + } + function startLinting(cm) { - var state = cm.state.lint, options = state.options; - var passOptions = options.options || options; // Support deprecated passing of `options` property in options - if (options.async || options.getAnnotations.async) - options.getAnnotations(cm.getValue(), updateLinting, passOptions, cm); - else - updateLinting(cm, options.getAnnotations(cm.getValue(), passOptions, cm)); + var state = cm.state.lint; + if (!state) return; + var options = state.options; + /* + * Passing rules in `options` property prevents JSHint (and other linters) from complaining + * about unrecognized rules like `onUpdateLinting`, `delay`, `lintOnChange`, etc. + */ + var getAnnotations = options.getAnnotations || cm.getHelper(CodeMirror.Pos(0, 0), "lint"); + if (!getAnnotations) return; + if (options.async || getAnnotations.async) { + lintAsync(cm, getAnnotations) + } else { + var annotations = getAnnotations(cm.getValue(), state.linterOptions, cm); + if (!annotations) return; + if (annotations.then) annotations.then(function(issues) { + cm.operation(function() {updateLinting(cm, issues)}) + }); + else cm.operation(function() {updateLinting(cm, annotations)}) + } } function updateLinting(cm, annotationsNotSorted) { + var state = cm.state.lint; + if (!state) return; + var options = state.options; clearMarks(cm); - var state = cm.state.lint, options = state.options; var annotations = groupByLine(annotationsNotSorted); @@ -136,6 +199,10 @@ var anns = annotations[line]; if (!anns) continue; + // filter out duplicate messages + var message = []; + anns = anns.filter(function(item) { return message.indexOf(item.message) > -1 ? false : message.push(item.message) }); + var maxSeverity = null; var tipLabel = state.hasGutter && document.createDocumentFragment(); @@ -149,27 +216,36 @@ if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann)); if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, { - className: "CodeMirror-lint-mark-" + severity, + className: "CodeMirror-lint-mark CodeMirror-lint-mark-" + severity, __annotation: ann })); } - + // use original annotations[line] to show multiple messages if (state.hasGutter) - cm.setGutterMarker(line, GUTTER_ID, makeMarker(tipLabel, maxSeverity, anns.length > 1, - state.options.tooltips)); + cm.setGutterMarker(line, GUTTER_ID, makeMarker(cm, tipLabel, maxSeverity, annotations[line].length > 1, + options.tooltips)); + + if (options.highlightLines) + cm.addLineClass(line, "wrap", LINT_LINE_ID + maxSeverity); } if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm); } function onChange(cm) { var state = cm.state.lint; + if (!state) return; clearTimeout(state.timeout); - state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500); + state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay); } - function popupSpanTooltip(ann, e) { + function popupTooltips(cm, annotations, e) { var target = e.target || e.srcElement; - showTooltipFor(e, annotationTooltip(ann), target); + var tooltip = document.createDocumentFragment(); + for (var i = 0; i < annotations.length; i++) { + var ann = annotations[i]; + tooltip.appendChild(annotationTooltip(ann)); + } + showTooltipFor(cm, e, tooltip, target); } function onMouseOver(cm, e) { @@ -177,29 +253,39 @@ if (!/\bCodeMirror-lint-mark-/.test(target.className)) return; var box = target.getBoundingClientRect(), x = (box.left + box.right) / 2, y = (box.top + box.bottom) / 2; var spans = cm.findMarksAt(cm.coordsChar({left: x, top: y}, "client")); + + var annotations = []; for (var i = 0; i < spans.length; ++i) { var ann = spans[i].__annotation; - if (ann) return popupSpanTooltip(ann, e); + if (ann) annotations.push(ann); } + if (annotations.length) popupTooltips(cm, annotations, e); } CodeMirror.defineOption("lint", false, function(cm, val, old) { if (old && old != CodeMirror.Init) { clearMarks(cm); - cm.off("change", onChange); + if (cm.state.lint.options.lintOnChange !== false) + cm.off("change", onChange); CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver); + clearTimeout(cm.state.lint.timeout); delete cm.state.lint; } if (val) { var gutters = cm.getOption("gutters"), hasLintGutter = false; for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true; - var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter); - cm.on("change", onChange); - if (state.options.tooltips != false) + var state = cm.state.lint = new LintState(cm, val, hasLintGutter); + if (state.options.lintOnChange) + cm.on("change", onChange); + if (state.options.tooltips != false && state.options.tooltips != "gutter") CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver); startLinting(cm); } }); + + CodeMirror.defineExtension("performLint", function() { + startLinting(this); + }); }); diff --git a/static/editor.md/lib/codemirror/addon/lint/yaml-lint.js b/static/editor.md/lib/codemirror/addon/lint/yaml-lint.js index 3f77e525..b4ac5abc 100644 --- a/static/editor.md/lib/codemirror/addon/lint/yaml-lint.js +++ b/static/editor.md/lib/codemirror/addon/lint/yaml-lint.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -17,10 +17,23 @@ CodeMirror.registerHelper("lint", "yaml", function(text) { var found = []; - try { jsyaml.load(text); } + if (!window.jsyaml) { + if (window.console) { + window.console.error("Error: window.jsyaml not defined, CodeMirror YAML linting cannot run."); + } + return found; + } + try { jsyaml.loadAll(text); } catch(e) { - var loc = e.mark; - found.push({ from: CodeMirror.Pos(loc.line, loc.column), to: CodeMirror.Pos(loc.line, loc.column), message: e.message }); + var loc = e.mark, + // js-yaml YAMLException doesn't always provide an accurate lineno + // e.g., when there are multiple yaml docs + // --- + // --- + // foo:bar + from = loc ? CodeMirror.Pos(loc.line, loc.column) : CodeMirror.Pos(0, 0), + to = from; + found.push({ from: from, to: to, message: e.message }); } return found; }); diff --git a/static/editor.md/lib/codemirror/addon/merge/merge.css b/static/editor.md/lib/codemirror/addon/merge/merge.css index a6a80e43..dadd7f59 100644 --- a/static/editor.md/lib/codemirror/addon/merge/merge.css +++ b/static/editor.md/lib/codemirror/addon/merge/merge.css @@ -48,6 +48,12 @@ color: #555; line-height: 1; } +.CodeMirror-merge-scrolllock:after { + content: "\21db\00a0\00a0\21da"; +} +.CodeMirror-merge-scrolllock.CodeMirror-merge-scrolllock-enabled:after { + content: "\21db\21da"; +} .CodeMirror-merge-copybuttons-left, .CodeMirror-merge-copybuttons-right { position: absolute; @@ -60,6 +66,7 @@ position: absolute; cursor: pointer; color: #44c; + z-index: 3; } .CodeMirror-merge-copy-reverse { diff --git a/static/editor.md/lib/codemirror/addon/merge/merge.js b/static/editor.md/lib/codemirror/addon/merge/merge.js index f1f3aafc..7fd963f7 100644 --- a/static/editor.md/lib/codemirror/addon/merge/merge.js +++ b/static/editor.md/lib/codemirror/addon/merge/merge.js @@ -1,16 +1,16 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE // declare global: diff_match_patch, DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("diff_match_patch")); + mod(require("../../lib/codemirror")); // Note non-packaged dependency diff_match_patch else if (typeof define == "function" && define.amd) // AMD define(["../../lib/codemirror", "diff_match_patch"], mod); else // Plain browser env - mod(CodeMirror, diff_match_patch); -})(function(CodeMirror, diff_match_patch) { + mod(CodeMirror); +})(function(CodeMirror) { "use strict"; var Pos = CodeMirror.Pos; var svgNS = "http://www.w3.org/2000/svg"; @@ -37,16 +37,30 @@ constructor: DiffView, init: function(pane, orig, options) { this.edit = this.mv.edit; + ;(this.edit.state.diffViews || (this.edit.state.diffViews = [])).push(this); this.orig = CodeMirror(pane, copyObj({value: orig, readOnly: !this.mv.options.allowEditingOriginals}, copyObj(options))); + if (this.mv.options.connect == "align") { + if (!this.edit.state.trackAlignable) this.edit.state.trackAlignable = new TrackAlignable(this.edit) + this.orig.state.trackAlignable = new TrackAlignable(this.orig) + } + this.lockButton.title = this.edit.phrase("Toggle locked scrolling"); - this.diff = getDiff(asString(orig), asString(options.value)); + this.orig.state.diffViews = [this]; + var classLocation = options.chunkClassLocation || "background"; + if (Object.prototype.toString.call(classLocation) != "[object Array]") classLocation = [classLocation] + this.classes.classLocation = classLocation + + this.diff = getDiff(asString(orig), asString(options.value), this.mv.options.ignoreWhitespace); this.chunks = getChunks(this.diff); this.diffOutOfDate = this.dealigned = false; + this.needsScrollSync = null this.showDifferences = options.showDifferences !== false; + }, + registerEvents: function(otherDv) { this.forceUpdate = registerUpdate(this); setScrollLock(this, true, false); - registerScroll(this); + registerScroll(this, otherDv); }, setShowDifferences: function(val) { val = val !== false; @@ -59,7 +73,7 @@ function ensureDiff(dv) { if (dv.diffOutOfDate) { - dv.diff = getDiff(dv.orig.getValue(), dv.edit.getValue()); + dv.diff = getDiff(dv.orig.getValue(), dv.edit.getValue(), dv.mv.options.ignoreWhitespace); dv.chunks = getChunks(dv.diff); dv.diffOutOfDate = false; CodeMirror.signal(dv.edit, "updateDiff", dv.diff); @@ -86,10 +100,12 @@ updateMarks(dv.edit, dv.diff, edit, DIFF_INSERT, dv.classes); updateMarks(dv.orig, dv.diff, orig, DIFF_DELETE, dv.classes); } - makeConnections(dv); if (dv.mv.options.connect == "align") alignChunks(dv); + makeConnections(dv); + if (dv.needsScrollSync != null) syncScroll(dv, dv.needsScrollSync) + updating = false; } function setDealign(fast) { @@ -111,37 +127,49 @@ // Update faster when a line was added/removed setDealign(change.text.length - 1 != change.to.line - change.from.line); } + function swapDoc() { + dv.diffOutOfDate = true; + dv.dealigned = true; + update("full"); + } dv.edit.on("change", change); dv.orig.on("change", change); - dv.edit.on("markerAdded", setDealign); - dv.edit.on("markerCleared", setDealign); - dv.orig.on("markerAdded", setDealign); - dv.orig.on("markerCleared", setDealign); + dv.edit.on("swapDoc", swapDoc); + dv.orig.on("swapDoc", swapDoc); + if (dv.mv.options.connect == "align") { + CodeMirror.on(dv.edit.state.trackAlignable, "realign", setDealign) + CodeMirror.on(dv.orig.state.trackAlignable, "realign", setDealign) + } dv.edit.on("viewportChange", function() { set(false); }); dv.orig.on("viewportChange", function() { set(false); }); update(); return update; } - function registerScroll(dv) { + function registerScroll(dv, otherDv) { dv.edit.on("scroll", function() { - syncScroll(dv, DIFF_INSERT) && makeConnections(dv); + syncScroll(dv, true) && makeConnections(dv); }); dv.orig.on("scroll", function() { - syncScroll(dv, DIFF_DELETE) && makeConnections(dv); + syncScroll(dv, false) && makeConnections(dv); + if (otherDv) syncScroll(otherDv, true) && makeConnections(otherDv); }); } - function syncScroll(dv, type) { + function syncScroll(dv, toOrig) { // Change handler will do a refresh after a timeout when diff is out of date - if (dv.diffOutOfDate) return false; + if (dv.diffOutOfDate) { + if (dv.lockScroll && dv.needsScrollSync == null) dv.needsScrollSync = toOrig + return false + } + dv.needsScrollSync = null if (!dv.lockScroll) return true; var editor, other, now = +new Date; - if (type == DIFF_INSERT) { editor = dv.edit; other = dv.orig; } + if (toOrig) { editor = dv.edit; other = dv.orig; } else { editor = dv.orig; other = dv.edit; } // Don't take action if the position of this editor was recently set // (to prevent feedback loops) - if (editor.state.scrollSetBy == dv && (editor.state.scrollSetAt || 0) + 50 > now) return false; + if (editor.state.scrollSetBy == dv && (editor.state.scrollSetAt || 0) + 250 > now) return false; var sInfo = editor.getScrollInfo(); if (dv.mv.options.connect == "align") { @@ -149,9 +177,9 @@ } else { var halfScreen = .5 * sInfo.clientHeight, midY = sInfo.top + halfScreen; var mid = editor.lineAtHeight(midY, "local"); - var around = chunkBoundariesAround(dv.chunks, mid, type == DIFF_INSERT); - var off = getOffsets(editor, type == DIFF_INSERT ? around.edit : around.orig); - var offOther = getOffsets(other, type == DIFF_INSERT ? around.orig : around.edit); + var around = chunkBoundariesAround(dv.chunks, mid, toOrig); + var off = getOffsets(editor, toOrig ? around.edit : around.orig); + var offOther = getOffsets(other, toOrig ? around.orig : around.edit); var ratio = (midY - off.top) / (off.bot - off.top); var targetPos = (offOther.top - halfScreen) + ratio * (offOther.bot - offOther.top); @@ -184,21 +212,27 @@ function setScrollLock(dv, val, action) { dv.lockScroll = val; if (val && action != false) syncScroll(dv, DIFF_INSERT) && makeConnections(dv); - dv.lockButton.innerHTML = val ? "\u21db\u21da" : "\u21db  \u21da"; + (val ? CodeMirror.addClass : CodeMirror.rmClass)(dv.lockButton, "CodeMirror-merge-scrolllock-enabled"); } // Updating the marks for editor content + function removeClass(editor, line, classes) { + var locs = classes.classLocation + for (var i = 0; i < locs.length; i++) { + editor.removeLineClass(line, locs[i], classes.chunk); + editor.removeLineClass(line, locs[i], classes.start); + editor.removeLineClass(line, locs[i], classes.end); + } + } + function clearMarks(editor, arr, classes) { for (var i = 0; i < arr.length; ++i) { var mark = arr[i]; - if (mark instanceof CodeMirror.TextMarker) { + if (mark instanceof CodeMirror.TextMarker) mark.clear(); - } else if (mark.parent) { - editor.removeLineClass(mark, "background", classes.chunk); - editor.removeLineClass(mark, "background", classes.start); - editor.removeLineClass(mark, "background", classes.end); - } + else if (mark.parent) + removeClass(editor, mark, classes); } arr.length = 0; } @@ -224,28 +258,34 @@ }); } + function addClass(editor, lineNr, classes, main, start, end) { + var locs = classes.classLocation, line = editor.getLineHandle(lineNr); + for (var i = 0; i < locs.length; i++) { + if (main) editor.addLineClass(line, locs[i], classes.chunk); + if (start) editor.addLineClass(line, locs[i], classes.start); + if (end) editor.addLineClass(line, locs[i], classes.end); + } + return line; + } + function markChanges(editor, diff, type, marks, from, to, classes) { var pos = Pos(0, 0); var top = Pos(from, 0), bot = editor.clipPos(Pos(to - 1)); var cls = type == DIFF_DELETE ? classes.del : classes.insert; function markChunk(start, end) { var bfrom = Math.max(from, start), bto = Math.min(to, end); - for (var i = bfrom; i < bto; ++i) { - var line = editor.addLineClass(i, "background", classes.chunk); - if (i == start) editor.addLineClass(line, "background", classes.start); - if (i == end - 1) editor.addLineClass(line, "background", classes.end); - marks.push(line); - } + for (var i = bfrom; i < bto; ++i) + marks.push(addClass(editor, i, classes, true, i == start, i == end - 1)); // When the chunk is empty, make sure a horizontal line shows up if (start == end && bfrom == end && bto == end) { if (bfrom) - marks.push(editor.addLineClass(bfrom - 1, "background", classes.end)); + marks.push(addClass(editor, bfrom - 1, classes, false, false, true)); else - marks.push(editor.addLineClass(bfrom, "background", classes.start)); + marks.push(addClass(editor, bfrom, classes, false, true, false)); } } - var chunkStart = 0; + var chunkStart = 0, pending = false; for (var i = 0; i < diff.length; ++i) { var part = diff[i], tp = part[0], str = part[1]; if (tp == DIFF_EQUAL) { @@ -253,10 +293,11 @@ moveOver(pos, str); var cleanTo = pos.line + (endOfLineClean(diff, i) ? 1 : 0); if (cleanTo > cleanFrom) { - if (i) markChunk(chunkStart, cleanFrom); + if (pending) { markChunk(chunkStart, cleanFrom); pending = false } chunkStart = cleanTo; } } else { + pending = true if (tp == type) { var end = moveOver(pos, str, true); var a = posMax(top, pos), b = posMin(bot, end); @@ -266,7 +307,7 @@ } } } - if (chunkStart <= pos.line) markChunk(chunkStart, pos.line + 1); + if (pending) markChunk(chunkStart, pos.line + 1); } // Updating the gap between editor and original @@ -282,7 +323,9 @@ if (dv.copyButtons) clear(dv.copyButtons); var vpEdit = dv.edit.getViewport(), vpOrig = dv.orig.getViewport(); - var sTopEdit = dv.edit.getScrollInfo().top, sTopOrig = dv.orig.getScrollInfo().top; + var outerTop = dv.mv.wrap.getBoundingClientRect().top + var sTopEdit = outerTop - dv.edit.getScrollerElement().getBoundingClientRect().top + dv.edit.getScrollInfo().top + var sTopOrig = outerTop - dv.orig.getScrollerElement().getBoundingClientRect().top + dv.orig.getScrollInfo().top; for (var i = 0; i < dv.chunks.length; i++) { var ch = dv.chunks[i]; if (ch.editFrom <= vpEdit.to && ch.editTo >= vpEdit.from && @@ -303,29 +346,81 @@ return origStart + (editLine - editStart); } - function findAlignedLines(dv, other) { - var linesToAlign = []; - for (var i = 0; i < dv.chunks.length; i++) { - var chunk = dv.chunks[i]; - linesToAlign.push([chunk.origTo, chunk.editTo, other ? getMatchingOrigLine(chunk.editTo, other.chunks) : null]); + // Combines information about chunks and widgets/markers to return + // an array of lines, in a single editor, that probably need to be + // aligned with their counterparts in the editor next to it. + function alignableFor(cm, chunks, isOrig) { + var tracker = cm.state.trackAlignable + var start = cm.firstLine(), trackI = 0 + var result = [] + for (var i = 0;; i++) { + var chunk = chunks[i] + var chunkStart = !chunk ? 1e9 : isOrig ? chunk.origFrom : chunk.editFrom + for (; trackI < tracker.alignable.length; trackI += 2) { + var n = tracker.alignable[trackI] + 1 + if (n <= start) continue + if (n <= chunkStart) result.push(n) + else break + } + if (!chunk) break + result.push(start = isOrig ? chunk.origTo : chunk.editTo) } - if (other) { - for (var i = 0; i < other.chunks.length; i++) { - var chunk = other.chunks[i]; - for (var j = 0; j < linesToAlign.length; j++) { - var align = linesToAlign[j]; - if (align[1] == chunk.editTo) { - j = -1; - break; - } else if (align[1] > chunk.editTo) { - break; - } + return result + } + + // Given information about alignable lines in two editors, fill in + // the result (an array of three-element arrays) to reflect the + // lines that need to be aligned with each other. + function mergeAlignable(result, origAlignable, chunks, setIndex) { + var rI = 0, origI = 0, chunkI = 0, diff = 0 + outer: for (;; rI++) { + var nextR = result[rI], nextO = origAlignable[origI] + if (!nextR && nextO == null) break + + var rLine = nextR ? nextR[0] : 1e9, oLine = nextO == null ? 1e9 : nextO + while (chunkI < chunks.length) { + var chunk = chunks[chunkI] + if (chunk.origFrom <= oLine && chunk.origTo > oLine) { + origI++ + rI-- + continue outer; } - if (j > -1) - linesToAlign.splice(j - 1, 0, [getMatchingOrigLine(chunk.editTo, dv.chunks), chunk.editTo, chunk.origTo]); + if (chunk.editTo > rLine) { + if (chunk.editFrom <= rLine) continue outer; + break + } + diff += (chunk.origTo - chunk.origFrom) - (chunk.editTo - chunk.editFrom) + chunkI++ + } + if (rLine == oLine - diff) { + nextR[setIndex] = oLine + origI++ + } else if (rLine < oLine - diff) { + nextR[setIndex] = rLine + diff + } else { + var record = [oLine - diff, null, null] + record[setIndex] = oLine + result.splice(rI, 0, record) + origI++ } } - return linesToAlign; + } + + function findAlignedLines(dv, other) { + var alignable = alignableFor(dv.edit, dv.chunks, false), result = [] + if (other) for (var i = 0, j = 0; i < other.chunks.length; i++) { + var n = other.chunks[i].editTo + while (j < alignable.length && alignable[j] < n) j++ + if (j == alignable.length || alignable[j] != n) alignable.splice(j++, 0, n) + } + for (var i = 0; i < alignable.length; i++) + result.push([alignable[i], null, null]) + + mergeAlignable(result, alignableFor(dv.orig, dv.chunks, true), dv.chunks, 1) + if (other) + mergeAlignable(result, alignableFor(other.orig, other.chunks, true), other.chunks, 2) + + return result } function alignChunks(dv, force) { @@ -348,22 +443,26 @@ aligners[i].clear(); aligners.length = 0; - var cm = [dv.orig, dv.edit], scroll = []; + var cm = [dv.edit, dv.orig], scroll = [], offset = [] if (other) cm.push(other.orig); - for (var i = 0; i < cm.length; i++) + for (var i = 0; i < cm.length; i++) { scroll.push(cm[i].getScrollInfo().top); + offset.push(-cm[i].getScrollerElement().getBoundingClientRect().top) + } + if (offset[0] != offset[1] || cm.length == 3 && offset[1] != offset[2]) + alignLines(cm, offset, [0, 0, 0], aligners) for (var ln = 0; ln < linesToAlign.length; ln++) - alignLines(cm, linesToAlign[ln], aligners); + alignLines(cm, offset, linesToAlign[ln], aligners); for (var i = 0; i < cm.length; i++) cm[i].scrollTo(null, scroll[i]); } - function alignLines(cm, lines, aligners) { - var maxOffset = 0, offset = []; + function alignLines(cm, cmOffset, lines, aligners) { + var maxOffset = -1e8, offset = []; for (var i = 0; i < cm.length; i++) if (lines[i] != null) { - var off = cm[i].heightAtLine(lines[i], "local"); + var off = cm[i].heightAtLine(lines[i], "local") - cmOffset[i]; offset[i] = off; maxOffset = Math.max(maxOffset, off); } @@ -383,18 +482,18 @@ var elt = document.createElement("div"); elt.className = "CodeMirror-merge-spacer"; elt.style.height = size + "px"; elt.style.minWidth = "1px"; - return cm.addLineWidget(line, elt, {height: size, above: above}); + return cm.addLineWidget(line, elt, {height: size, above: above, mergeSpacer: true, handleMouseEvents: true}); } function drawConnectorsForChunk(dv, chunk, sTopOrig, sTopEdit, w) { var flip = dv.type == "left"; - var top = dv.orig.heightAtLine(chunk.origFrom, "local") - sTopOrig; + var top = dv.orig.heightAtLine(chunk.origFrom, "local", true) - sTopOrig; if (dv.svg) { var topLpx = top; - var topRpx = dv.edit.heightAtLine(chunk.editFrom, "local") - sTopEdit; + var topRpx = dv.edit.heightAtLine(chunk.editFrom, "local", true) - sTopEdit; if (flip) { var tmp = topLpx; topLpx = topRpx; topRpx = tmp; } - var botLpx = dv.orig.heightAtLine(chunk.origTo, "local") - sTopOrig; - var botRpx = dv.edit.heightAtLine(chunk.editTo, "local") - sTopEdit; + var botLpx = dv.orig.heightAtLine(chunk.origTo, "local", true) - sTopOrig; + var botRpx = dv.edit.heightAtLine(chunk.editTo, "local", true) - sTopEdit; if (flip) { var tmp = botLpx; botLpx = botRpx; botRpx = tmp; } var curveTop = " C " + w/2 + " " + topRpx + " " + w/2 + " " + topLpx + " " + (w + 2) + " " + topLpx; var curveBot = " C " + w/2 + " " + botLpx + " " + w/2 + " " + botRpx + " -1 " + botRpx; @@ -406,12 +505,13 @@ var copy = dv.copyButtons.appendChild(elt("div", dv.type == "left" ? "\u21dd" : "\u21dc", "CodeMirror-merge-copy")); var editOriginals = dv.mv.options.allowEditingOriginals; - copy.title = editOriginals ? "Push to left" : "Revert chunk"; + copy.title = dv.edit.phrase(editOriginals ? "Push to left" : "Revert chunk"); copy.chunk = chunk; - copy.style.top = top + "px"; + copy.style.top = (chunk.origTo > chunk.origFrom ? top : dv.edit.heightAtLine(chunk.editFrom, "local") - sTopEdit) + "px"; + copy.setAttribute("role", "button"); if (editOriginals) { - var topReverse = dv.orig.heightAtLine(chunk.editFrom, "local") - sTopEdit; + var topReverse = dv.edit.heightAtLine(chunk.editFrom, "local") - sTopEdit; var copyReverse = dv.copyButtons.appendChild(elt("div", dv.type == "right" ? "\u21dd" : "\u21dc", "CodeMirror-merge-copy-reverse")); copyReverse.title = "Push to right"; @@ -419,14 +519,22 @@ origFrom: chunk.editFrom, origTo: chunk.editTo}; copyReverse.style.top = topReverse + "px"; dv.type == "right" ? copyReverse.style.left = "2px" : copyReverse.style.right = "2px"; + copyReverse.setAttribute("role", "button"); } } } function copyChunk(dv, to, from, chunk) { if (dv.diffOutOfDate) return; - to.replaceRange(from.getRange(Pos(chunk.origFrom, 0), Pos(chunk.origTo, 0)), - Pos(chunk.editFrom, 0), Pos(chunk.editTo, 0)); + var origStart = chunk.origTo > from.lastLine() ? Pos(chunk.origFrom - 1) : Pos(chunk.origFrom, 0) + var origEnd = Pos(chunk.origTo, 0) + var editStart = chunk.editTo > to.lastLine() ? Pos(chunk.editFrom - 1) : Pos(chunk.editFrom, 0) + var editEnd = Pos(chunk.editTo, 0) + var handler = dv.mv.options.revertChunk + if (handler) + handler(dv.mv, from, origStart, origEnd, to, editStart, editEnd) + else + to.replaceRange(from.getRange(origStart, origEnd), editStart, editEnd) } // Merge view, containing 0, 1, or 2 diff views. @@ -444,18 +552,18 @@ if (hasLeft) { left = this.left = new DiffView(this, "left"); - var leftPane = elt("div", null, "CodeMirror-merge-pane"); + var leftPane = elt("div", null, "CodeMirror-merge-pane CodeMirror-merge-left"); wrap.push(leftPane); wrap.push(buildGap(left)); } - var editPane = elt("div", null, "CodeMirror-merge-pane"); + var editPane = elt("div", null, "CodeMirror-merge-pane CodeMirror-merge-editor"); wrap.push(editPane); if (hasRight) { right = this.right = new DiffView(this, "right"); wrap.push(buildGap(right)); - var rightPane = elt("div", null, "CodeMirror-merge-pane"); + var rightPane = elt("div", null, "CodeMirror-merge-pane CodeMirror-merge-right"); wrap.push(rightPane); } @@ -468,18 +576,17 @@ if (left) left.init(leftPane, origLeft, options); if (right) right.init(rightPane, origRight, options); - - if (options.collapseIdentical) { - updating = true; + if (options.collapseIdentical) this.editor().operation(function() { collapseIdenticalStretches(self, options.collapseIdentical); }); - updating = false; - } if (options.connect == "align") { this.aligners = []; alignChunks(this.left || this.right, true); } + if (left) left.registerEvents(right) + if (right) right.registerEvents(left) + var onResize = function() { if (left) makeConnections(left); @@ -494,7 +601,7 @@ function buildGap(dv) { var lock = dv.lockButton = elt("div", null, "CodeMirror-merge-scrolllock"); - lock.title = "Toggle locked scrolling"; + lock.setAttribute("role", "button"); var lockWrap = elt("div", [lock], "CodeMirror-merge-scrolllock-wrap"); CodeMirror.on(lock, "click", function() { setScrollLock(dv, !dv.lockScroll); }); var gapElts = [lockWrap]; @@ -522,7 +629,7 @@ } MergeView.prototype = { - constuctor: MergeView, + constructor: MergeView, editor: function() { return this.edit; }, rightOriginal: function() { return this.right && this.right.orig; }, leftOriginal: function() { return this.left && this.left.orig; }, @@ -544,15 +651,15 @@ } // Operations on diffs + var dmp; + function getDiff(a, b, ignoreWhitespace) { + if (!dmp) dmp = new diff_match_patch(); - var dmp = new diff_match_patch(); - function getDiff(a, b) { var diff = dmp.diff_main(a, b); - dmp.diff_cleanupSemantic(diff); // The library sometimes leaves in empty parts, which confuse the algorithm for (var i = 0; i < diff.length; ++i) { var part = diff[i]; - if (!part[1]) { + if (ignoreWhitespace ? !/[^ \t]/.test(part[1]) : !part[1]) { diff.splice(i--, 1); } else if (i && diff[i - 1][0] == part[0]) { diff.splice(i--, 1); @@ -564,12 +671,13 @@ function getChunks(diff) { var chunks = []; + if (!diff.length) return chunks; var startEdit = 0, startOrig = 0; var edit = Pos(0, 0), orig = Pos(0, 0); for (var i = 0; i < diff.length; ++i) { var part = diff[i], tp = part[0]; if (tp == DIFF_EQUAL) { - var startOff = startOfLineClean(diff, i) ? 0 : 1; + var startOff = !startOfLineClean(diff, i) || edit.line < startEdit || orig.line < startOrig ? 1 : 0; var cleanFromEdit = edit.line + startOff, cleanFromOrig = orig.line + startOff; moveOver(edit, part[1], null, orig); var endOff = endOfLineClean(diff, i) ? 1 : 0; @@ -592,10 +700,10 @@ function endOfLineClean(diff, i) { if (i == diff.length - 1) return true; var next = diff[i + 1][1]; - if (next.length == 1 || next.charCodeAt(0) != 10) return false; + if ((next.length == 1 && i < diff.length - 2) || next.charCodeAt(0) != 10) return false; if (i == diff.length - 2) return true; next = diff[i + 2][1]; - return next.length > 1 && next.charCodeAt(0) == 10; + return (next.length > 1 || i == diff.length - 3) && next.charCodeAt(0) == 10; } function startOfLineClean(diff, i) { @@ -627,7 +735,7 @@ cm.addLineClass(from, "wrap", "CodeMirror-merge-collapsed-line"); var widget = document.createElement("span"); widget.className = "CodeMirror-merge-collapsed-widget"; - widget.title = "Identical text collapsed. Click to expand."; + widget.title = cm.phrase("Identical text collapsed. Click to expand."); var mark = cm.markText(Pos(from, 0), Pos(to - 1), { inclusiveLeft: true, inclusiveRight: true, @@ -638,7 +746,10 @@ mark.clear(); cm.removeLineClass(from, "wrap", "CodeMirror-merge-collapsed-line"); } - widget.addEventListener("click", clear); + if (mark.explicitlyCleared) clear(); + CodeMirror.on(widget, "click", clear); + mark.on("clear", clear); + CodeMirror.on(widget, "click", clear); return {mark: mark, clear: clear}; } @@ -729,7 +840,170 @@ return out; } + // Tracks collapsed markers and line widgets, in order to be able to + // accurately align the content of two editors. + + var F_WIDGET = 1, F_WIDGET_BELOW = 2, F_MARKER = 4 + + function TrackAlignable(cm) { + this.cm = cm + this.alignable = [] + this.height = cm.doc.height + var self = this + cm.on("markerAdded", function(_, marker) { + if (!marker.collapsed) return + var found = marker.find(1) + if (found != null) self.set(found.line, F_MARKER) + }) + cm.on("markerCleared", function(_, marker, _min, max) { + if (max != null && marker.collapsed) + self.check(max, F_MARKER, self.hasMarker) + }) + cm.on("markerChanged", this.signal.bind(this)) + cm.on("lineWidgetAdded", function(_, widget, lineNo) { + if (widget.mergeSpacer) return + if (widget.above) self.set(lineNo - 1, F_WIDGET_BELOW) + else self.set(lineNo, F_WIDGET) + }) + cm.on("lineWidgetCleared", function(_, widget, lineNo) { + if (widget.mergeSpacer) return + if (widget.above) self.check(lineNo - 1, F_WIDGET_BELOW, self.hasWidgetBelow) + else self.check(lineNo, F_WIDGET, self.hasWidget) + }) + cm.on("lineWidgetChanged", this.signal.bind(this)) + cm.on("change", function(_, change) { + var start = change.from.line, nBefore = change.to.line - change.from.line + var nAfter = change.text.length - 1, end = start + nAfter + if (nBefore || nAfter) self.map(start, nBefore, nAfter) + self.check(end, F_MARKER, self.hasMarker) + if (nBefore || nAfter) self.check(change.from.line, F_MARKER, self.hasMarker) + }) + cm.on("viewportChange", function() { + if (self.cm.doc.height != self.height) self.signal() + }) + } + + TrackAlignable.prototype = { + signal: function() { + CodeMirror.signal(this, "realign") + this.height = this.cm.doc.height + }, + + set: function(n, flags) { + var pos = -1 + for (; pos < this.alignable.length; pos += 2) { + var diff = this.alignable[pos] - n + if (diff == 0) { + if ((this.alignable[pos + 1] & flags) == flags) return + this.alignable[pos + 1] |= flags + this.signal() + return + } + if (diff > 0) break + } + this.signal() + this.alignable.splice(pos, 0, n, flags) + }, + + find: function(n) { + for (var i = 0; i < this.alignable.length; i += 2) + if (this.alignable[i] == n) return i + return -1 + }, + + check: function(n, flag, pred) { + var found = this.find(n) + if (found == -1 || !(this.alignable[found + 1] & flag)) return + if (!pred.call(this, n)) { + this.signal() + var flags = this.alignable[found + 1] & ~flag + if (flags) this.alignable[found + 1] = flags + else this.alignable.splice(found, 2) + } + }, + + hasMarker: function(n) { + var handle = this.cm.getLineHandle(n) + if (handle.markedSpans) for (var i = 0; i < handle.markedSpans.length; i++) + if (handle.markedSpans[i].marker.collapsed && handle.markedSpans[i].to != null) + return true + return false + }, + + hasWidget: function(n) { + var handle = this.cm.getLineHandle(n) + if (handle.widgets) for (var i = 0; i < handle.widgets.length; i++) + if (!handle.widgets[i].above && !handle.widgets[i].mergeSpacer) return true + return false + }, + + hasWidgetBelow: function(n) { + if (n == this.cm.lastLine()) return false + var handle = this.cm.getLineHandle(n + 1) + if (handle.widgets) for (var i = 0; i < handle.widgets.length; i++) + if (handle.widgets[i].above && !handle.widgets[i].mergeSpacer) return true + return false + }, + + map: function(from, nBefore, nAfter) { + var diff = nAfter - nBefore, to = from + nBefore, widgetFrom = -1, widgetTo = -1 + for (var i = 0; i < this.alignable.length; i += 2) { + var n = this.alignable[i] + if (n == from && (this.alignable[i + 1] & F_WIDGET_BELOW)) widgetFrom = i + if (n == to && (this.alignable[i + 1] & F_WIDGET_BELOW)) widgetTo = i + if (n <= from) continue + else if (n < to) this.alignable.splice(i--, 2) + else this.alignable[i] += diff + } + if (widgetFrom > -1) { + var flags = this.alignable[widgetFrom + 1] + if (flags == F_WIDGET_BELOW) this.alignable.splice(widgetFrom, 2) + else this.alignable[widgetFrom + 1] = flags & ~F_WIDGET_BELOW + } + if (widgetTo > -1 && nAfter) + this.set(from + nAfter, F_WIDGET_BELOW) + } + } + function posMin(a, b) { return (a.line - b.line || a.ch - b.ch) < 0 ? a : b; } function posMax(a, b) { return (a.line - b.line || a.ch - b.ch) > 0 ? a : b; } function posEq(a, b) { return a.line == b.line && a.ch == b.ch; } + + function findPrevDiff(chunks, start, isOrig) { + for (var i = chunks.length - 1; i >= 0; i--) { + var chunk = chunks[i]; + var to = (isOrig ? chunk.origTo : chunk.editTo) - 1; + if (to < start) return to; + } + } + + function findNextDiff(chunks, start, isOrig) { + for (var i = 0; i < chunks.length; i++) { + var chunk = chunks[i]; + var from = (isOrig ? chunk.origFrom : chunk.editFrom); + if (from > start) return from; + } + } + + function goNearbyDiff(cm, dir) { + var found = null, views = cm.state.diffViews, line = cm.getCursor().line; + if (views) for (var i = 0; i < views.length; i++) { + var dv = views[i], isOrig = cm == dv.orig; + ensureDiff(dv); + var pos = dir < 0 ? findPrevDiff(dv.chunks, line, isOrig) : findNextDiff(dv.chunks, line, isOrig); + if (pos != null && (found == null || (dir < 0 ? pos > found : pos < found))) + found = pos; + } + if (found != null) + cm.setCursor(found, 0); + else + return CodeMirror.Pass; + } + + CodeMirror.commands.goNextDiff = function(cm) { + return goNearbyDiff(cm, 1); + }; + CodeMirror.commands.goPrevDiff = function(cm) { + return goNearbyDiff(cm, -1); + }; }); diff --git a/static/editor.md/lib/codemirror/addon/mode/loadmode.js b/static/editor.md/lib/codemirror/addon/mode/loadmode.js index 10117ec2..fc695d0c 100644 --- a/static/editor.md/lib/codemirror/addon/mode/loadmode.js +++ b/static/editor.md/lib/codemirror/addon/mode/loadmode.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -16,8 +16,8 @@ var countDown = n; return function() { if (--countDown == 0) cont(); }; } - function ensureDeps(mode, cont) { - var deps = CodeMirror.modes[mode].dependencies; + function ensureDeps(mode, cont, options) { + var modeObj = CodeMirror.modes[mode], deps = modeObj && modeObj.dependencies; if (!deps) return cont(); var missing = []; for (var i = 0; i < deps.length; ++i) { @@ -27,16 +27,18 @@ if (!missing.length) return cont(); var split = splitCallback(cont, missing.length); for (var i = 0; i < missing.length; ++i) - CodeMirror.requireMode(missing[i], split); + CodeMirror.requireMode(missing[i], split, options); } - CodeMirror.requireMode = function(mode, cont) { + CodeMirror.requireMode = function(mode, cont, options) { if (typeof mode != "string") mode = mode.name; - if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont); + if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont, options); if (loading.hasOwnProperty(mode)) return loading[mode].push(cont); - var file = CodeMirror.modeURL.replace(/%N/g, mode); - if (env == "plain") { + var file = options && options.path ? options.path(mode) : CodeMirror.modeURL.replace(/%N/g, mode); + if (options && options.loadMode) { + options.loadMode(file, function() { ensureDeps(mode, cont, options) }) + } else if (env == "plain") { var script = document.createElement("script"); script.src = file; var others = document.getElementsByTagName("script")[0]; @@ -44,7 +46,7 @@ CodeMirror.on(script, "load", function() { ensureDeps(mode, function() { for (var i = 0; i < list.length; ++i) list[i](); - }); + }, options); }); others.parentNode.insertBefore(script, others); } else if (env == "cjs") { @@ -55,10 +57,10 @@ } }; - CodeMirror.autoLoadMode = function(instance, mode) { + CodeMirror.autoLoadMode = function(instance, mode, options) { if (!CodeMirror.modes.hasOwnProperty(mode)) CodeMirror.requireMode(mode, function() { instance.setOption("mode", instance.getOption("mode")); - }); + }, options); }; }); diff --git a/static/editor.md/lib/codemirror/addon/mode/multiplex.js b/static/editor.md/lib/codemirror/addon/mode/multiplex.js index 6a95b323..6140bc4f 100644 --- a/static/editor.md/lib/codemirror/addon/mode/multiplex.js +++ b/static/editor.md/lib/codemirror/addon/mode/multiplex.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -12,14 +12,16 @@ "use strict"; CodeMirror.multiplexingMode = function(outer /*, others */) { - // Others should be {open, close, mode [, delimStyle] [, innerStyle]} objects + // Others should be {open, close, mode [, delimStyle] [, innerStyle] [, parseDelimiters]} objects var others = Array.prototype.slice.call(arguments, 1); - var n_others = others.length; - function indexOf(string, pattern, from) { - if (typeof pattern == "string") return string.indexOf(pattern, from); + function indexOf(string, pattern, from, returnEnd) { + if (typeof pattern == "string") { + var found = string.indexOf(pattern, from); + return returnEnd && found > -1 ? found + pattern.length : found; + } var m = pattern.exec(from ? string.slice(from) : string); - return m ? m.index + from : -1; + return m ? m.index + from + (returnEnd ? m[0].length : 0) : -1; } return { @@ -27,7 +29,8 @@ CodeMirror.multiplexingMode = function(outer /*, others */) { return { outer: CodeMirror.startState(outer), innerActive: null, - inner: null + inner: null, + startingInner: false }; }, @@ -35,21 +38,31 @@ CodeMirror.multiplexingMode = function(outer /*, others */) { return { outer: CodeMirror.copyState(outer, state.outer), innerActive: state.innerActive, - inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner) + inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner), + startingInner: state.startingInner }; }, token: function(stream, state) { if (!state.innerActive) { var cutOff = Infinity, oldContent = stream.string; - for (var i = 0; i < n_others; ++i) { + for (var i = 0; i < others.length; ++i) { var other = others[i]; var found = indexOf(oldContent, other.open, stream.pos); if (found == stream.pos) { - stream.match(other.open); + if (!other.parseDelimiters) stream.match(other.open); + state.startingInner = !!other.parseDelimiters state.innerActive = other; - state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0); - return other.delimStyle; + + // Get the outer indent, making sure to handle CodeMirror.Pass + var outerIndent = 0; + if (outer.indent) { + var possibleOuterIndent = outer.indent(state.outer, "", ""); + if (possibleOuterIndent !== CodeMirror.Pass) outerIndent = possibleOuterIndent; + } + + state.inner = CodeMirror.startState(other.mode, outerIndent); + return other.delimStyle && (other.delimStyle + " " + other.delimStyle + "-open"); } else if (found != -1 && found < cutOff) { cutOff = found; } @@ -64,18 +77,23 @@ CodeMirror.multiplexingMode = function(outer /*, others */) { state.innerActive = state.inner = null; return this.token(stream, state); } - var found = curInner.close ? indexOf(oldContent, curInner.close, stream.pos) : -1; - if (found == stream.pos) { + var found = curInner.close && !state.startingInner ? + indexOf(oldContent, curInner.close, stream.pos, curInner.parseDelimiters) : -1; + if (found == stream.pos && !curInner.parseDelimiters) { stream.match(curInner.close); state.innerActive = state.inner = null; - return curInner.delimStyle; + return curInner.delimStyle && (curInner.delimStyle + " " + curInner.delimStyle + "-close"); } if (found > -1) stream.string = oldContent.slice(0, found); var innerToken = curInner.mode.token(stream, state.inner); if (found > -1) stream.string = oldContent; + else if (stream.pos > stream.start) state.startingInner = false + + if (found == stream.pos && curInner.parseDelimiters) + state.innerActive = state.inner = null; if (curInner.innerStyle) { - if (innerToken) innerToken = innerToken + ' ' + curInner.innerStyle; + if (innerToken) innerToken = innerToken + " " + curInner.innerStyle; else innerToken = curInner.innerStyle; } @@ -83,10 +101,10 @@ CodeMirror.multiplexingMode = function(outer /*, others */) { } }, - indent: function(state, textAfter) { + indent: function(state, textAfter, line) { var mode = state.innerActive ? state.innerActive.mode : outer; if (!mode.indent) return CodeMirror.Pass; - return mode.indent(state.innerActive ? state.inner : state.outer, textAfter); + return mode.indent(state.innerActive ? state.inner : state.outer, textAfter, line); }, blankLine: function(state) { @@ -95,11 +113,11 @@ CodeMirror.multiplexingMode = function(outer /*, others */) { mode.blankLine(state.innerActive ? state.inner : state.outer); } if (!state.innerActive) { - for (var i = 0; i < n_others; ++i) { + for (var i = 0; i < others.length; ++i) { var other = others[i]; if (other.open === "\n") { state.innerActive = other; - state.inner = CodeMirror.startState(other.mode, mode.indent ? mode.indent(state.outer, "") : 0); + state.inner = CodeMirror.startState(other.mode, mode.indent ? mode.indent(state.outer, "", "") : 0); } } } else if (state.innerActive.close === "\n") { diff --git a/static/editor.md/lib/codemirror/addon/mode/multiplex_test.js b/static/editor.md/lib/codemirror/addon/mode/multiplex_test.js index d3394342..85039886 100644 --- a/static/editor.md/lib/codemirror/addon/mode/multiplex_test.js +++ b/static/editor.md/lib/codemirror/addon/mode/multiplex_test.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function() { CodeMirror.defineMode("markdown_with_stex", function(){ @@ -29,5 +29,21 @@ MT( "stexInsideMarkdown", - "[strong **Equation:**] [delim $][inner&tag \\pi][delim $]"); + "[strong **Equation:**] [delim&delim-open $][inner&tag \\pi][delim&delim-close $]"); + + CodeMirror.defineMode("identical_delim_multiplex", function() { + return CodeMirror.multiplexingMode(CodeMirror.getMode({indentUnit: 2}, "javascript"), { + open: "#", + close: "#", + mode: CodeMirror.getMode({}, "markdown"), + parseDelimiters: true, + innerStyle: "q" + }); + }); + + var mode2 = CodeMirror.getMode({}, "identical_delim_multiplex"); + + test.mode("identical_delimiters_with_parseDelimiters", mode2, [ + "[keyword let] [def x] [operator =] [q #foo][q&em *bar*][q #];" + ], "multiplexing") })(); diff --git a/static/editor.md/lib/codemirror/addon/mode/overlay.js b/static/editor.md/lib/codemirror/addon/mode/overlay.js index e1b9ed37..016e3c28 100644 --- a/static/editor.md/lib/codemirror/addon/mode/overlay.js +++ b/static/editor.md/lib/codemirror/addon/mode/overlay.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE // Utility function that allows modes to be combined. The mode given // as the base argument takes care of most of the normal mode @@ -68,16 +68,21 @@ CodeMirror.overlayMode = function(base, overlay, combine) { else return state.overlayCur; }, - indent: base.indent && function(state, textAfter) { - return base.indent(state.base, textAfter); + indent: base.indent && function(state, textAfter, line) { + return base.indent(state.base, textAfter, line); }, electricChars: base.electricChars, innerMode: function(state) { return {state: state.base, mode: base}; }, blankLine: function(state) { - if (base.blankLine) base.blankLine(state.base); - if (overlay.blankLine) overlay.blankLine(state.overlay); + var baseToken, overlayToken; + if (base.blankLine) baseToken = base.blankLine(state.base); + if (overlay.blankLine) overlayToken = overlay.blankLine(state.overlay); + + return overlayToken == null ? + baseToken : + (combine && baseToken != null ? baseToken + " " + overlayToken : overlayToken); } }; }; diff --git a/static/editor.md/lib/codemirror/addon/mode/simple.js b/static/editor.md/lib/codemirror/addon/mode/simple.js index 795328b8..0d8cbdeb 100644 --- a/static/editor.md/lib/codemirror/addon/mode/simple.js +++ b/static/editor.md/lib/codemirror/addon/mode/simple.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -60,7 +60,7 @@ function ensureState(states, name) { if (!states.hasOwnProperty(name)) - throw new Error("Undefined state " + name + "in simple mode"); + throw new Error("Undefined state " + name + " in simple mode"); } function toRegex(val, caret) { @@ -68,6 +68,7 @@ var flags = ""; if (val instanceof RegExp) { if (val.ignoreCase) flags = "i"; + if (val.unicode) flags += "u" val = val.source; } else { val = String(val); @@ -77,6 +78,7 @@ function asToken(val) { if (!val) return null; + if (val.apply) return val if (typeof val == "string") return val.replace(/\./g, " "); var result = []; for (var i = 0; i < val.length; i++) @@ -133,17 +135,18 @@ state.indent.push(stream.indentation() + config.indentUnit); if (rule.data.dedent) state.indent.pop(); - if (matches.length > 2) { - state.pending = []; + var token = rule.token + if (token && token.apply) token = token(matches) + if (matches.length > 2 && rule.token && typeof rule.token != "string") { for (var j = 2; j < matches.length; j++) if (matches[j]) - state.pending.push({text: matches[j], token: rule.token[j - 1]}); + (state.pending || (state.pending = [])).push({text: matches[j], token: rule.token[j - 1]}); stream.backUp(matches[0].length - (matches[1] ? matches[1].length : 0)); - return rule.token[0]; - } else if (rule.token && rule.token.join) { - return rule.token[0]; + return token[0]; + } else if (token && token.join) { + return token[0]; } else { - return rule.token; + return token; } } } diff --git a/static/editor.md/lib/codemirror/addon/runmode/colorize.js b/static/editor.md/lib/codemirror/addon/runmode/colorize.js index eb7060d0..3be54115 100644 --- a/static/editor.md/lib/codemirror/addon/runmode/colorize.js +++ b/static/editor.md/lib/codemirror/addon/runmode/colorize.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS diff --git a/static/editor.md/lib/codemirror/addon/runmode/runmode-standalone.js b/static/editor.md/lib/codemirror/addon/runmode/runmode-standalone.js index f4f352c8..76cf3d75 100644 --- a/static/editor.md/lib/codemirror/addon/runmode/runmode-standalone.js +++ b/static/editor.md/lib/codemirror/addon/runmode/runmode-standalone.js @@ -1,157 +1,334 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +(function () { + 'use strict'; -window.CodeMirror = {}; + function copyObj(obj, target, overwrite) { + if (!target) { target = {}; } + for (var prop in obj) + { if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) + { target[prop] = obj[prop]; } } + return target + } -(function() { -"use strict"; + // Counts the column offset in a string, taking tabs into account. + // Used mostly to find indentation. + function countColumn(string, end, tabSize, startIndex, startValue) { + if (end == null) { + end = string.search(/[^\s\u00a0]/); + if (end == -1) { end = string.length; } + } + for (var i = startIndex || 0, n = startValue || 0;;) { + var nextTab = string.indexOf("\t", i); + if (nextTab < 0 || nextTab >= end) + { return n + (end - i) } + n += nextTab - i; + n += tabSize - (n % tabSize); + i = nextTab + 1; + } + } -function splitLines(string){ return string.split(/\r?\n|\r/); }; + function nothing() {} -function StringStream(string) { - this.pos = this.start = 0; - this.string = string; - this.lineStart = 0; -} -StringStream.prototype = { - eol: function() {return this.pos >= this.string.length;}, - sol: function() {return this.pos == 0;}, - peek: function() {return this.string.charAt(this.pos) || null;}, - next: function() { + function createObj(base, props) { + var inst; + if (Object.create) { + inst = Object.create(base); + } else { + nothing.prototype = base; + inst = new nothing(); + } + if (props) { copyObj(props, inst); } + return inst + } + + // STRING STREAM + + // Fed to the mode parsers, provides helper functions to make + // parsers more succinct. + + var StringStream = function(string, tabSize, lineOracle) { + this.pos = this.start = 0; + this.string = string; + this.tabSize = tabSize || 8; + this.lastColumnPos = this.lastColumnValue = 0; + this.lineStart = 0; + this.lineOracle = lineOracle; + }; + + StringStream.prototype.eol = function () {return this.pos >= this.string.length}; + StringStream.prototype.sol = function () {return this.pos == this.lineStart}; + StringStream.prototype.peek = function () {return this.string.charAt(this.pos) || undefined}; + StringStream.prototype.next = function () { if (this.pos < this.string.length) - return this.string.charAt(this.pos++); - }, - eat: function(match) { + { return this.string.charAt(this.pos++) } + }; + StringStream.prototype.eat = function (match) { var ch = this.string.charAt(this.pos); - if (typeof match == "string") var ok = ch == match; - else var ok = ch && (match.test ? match.test(ch) : match(ch)); - if (ok) {++this.pos; return ch;} - }, - eatWhile: function(match) { + var ok; + if (typeof match == "string") { ok = ch == match; } + else { ok = ch && (match.test ? match.test(ch) : match(ch)); } + if (ok) {++this.pos; return ch} + }; + StringStream.prototype.eatWhile = function (match) { var start = this.pos; while (this.eat(match)){} - return this.pos > start; - }, - eatSpace: function() { + return this.pos > start + }; + StringStream.prototype.eatSpace = function () { var start = this.pos; - while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; - return this.pos > start; - }, - skipToEnd: function() {this.pos = this.string.length;}, - skipTo: function(ch) { + while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this.pos; } + return this.pos > start + }; + StringStream.prototype.skipToEnd = function () {this.pos = this.string.length;}; + StringStream.prototype.skipTo = function (ch) { var found = this.string.indexOf(ch, this.pos); - if (found > -1) {this.pos = found; return true;} - }, - backUp: function(n) {this.pos -= n;}, - column: function() {return this.start - this.lineStart;}, - indentation: function() {return 0;}, - match: function(pattern, consume, caseInsensitive) { + if (found > -1) {this.pos = found; return true} + }; + StringStream.prototype.backUp = function (n) {this.pos -= n;}; + StringStream.prototype.column = function () { + if (this.lastColumnPos < this.start) { + this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); + this.lastColumnPos = this.start; + } + return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0) + }; + StringStream.prototype.indentation = function () { + return countColumn(this.string, null, this.tabSize) - + (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0) + }; + StringStream.prototype.match = function (pattern, consume, caseInsensitive) { if (typeof pattern == "string") { - var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; + var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; }; var substr = this.string.substr(this.pos, pattern.length); if (cased(substr) == cased(pattern)) { - if (consume !== false) this.pos += pattern.length; - return true; + if (consume !== false) { this.pos += pattern.length; } + return true } } else { var match = this.string.slice(this.pos).match(pattern); - if (match && match.index > 0) return null; - if (match && consume !== false) this.pos += match[0].length; - return match; + if (match && match.index > 0) { return null } + if (match && consume !== false) { this.pos += match[0].length; } + return match } - }, - current: function(){return this.string.slice(this.start, this.pos);}, - hideFirstChars: function(n, inner) { + }; + StringStream.prototype.current = function (){return this.string.slice(this.start, this.pos)}; + StringStream.prototype.hideFirstChars = function (n, inner) { this.lineStart += n; - try { return inner(); } + try { return inner() } finally { this.lineStart -= n; } - } -}; -CodeMirror.StringStream = StringStream; + }; + StringStream.prototype.lookAhead = function (n) { + var oracle = this.lineOracle; + return oracle && oracle.lookAhead(n) + }; + StringStream.prototype.baseToken = function () { + var oracle = this.lineOracle; + return oracle && oracle.baseToken(this.pos) + }; -CodeMirror.startState = function (mode, a1, a2) { - return mode.startState ? mode.startState(a1, a2) : true; -}; + // Known modes, by name and by MIME + var modes = {}, mimeModes = {}; -var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {}; -CodeMirror.defineMode = function (name, mode) { - if (arguments.length > 2) - mode.dependencies = Array.prototype.slice.call(arguments, 2); - modes[name] = mode; -}; -CodeMirror.defineMIME = function (mime, spec) { mimeModes[mime] = spec; }; -CodeMirror.resolveMode = function(spec) { - if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { - spec = mimeModes[spec]; - } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { - spec = mimeModes[spec.name]; - } - if (typeof spec == "string") return {name: spec}; - else return spec || {name: "null"}; -}; -CodeMirror.getMode = function (options, spec) { - spec = CodeMirror.resolveMode(spec); - var mfactory = modes[spec.name]; - if (!mfactory) throw new Error("Unknown mode: " + spec); - return mfactory(options, spec); -}; -CodeMirror.registerHelper = CodeMirror.registerGlobalHelper = Math.min; -CodeMirror.defineMode("null", function() { - return {token: function(stream) {stream.skipToEnd();}}; -}); -CodeMirror.defineMIME("text/plain", "null"); - -CodeMirror.runMode = function (string, modespec, callback, options) { - var mode = CodeMirror.getMode({ indentUnit: 2 }, modespec); - - if (callback.nodeType == 1) { - var tabSize = (options && options.tabSize) || 4; - var node = callback, col = 0; - node.innerHTML = ""; - callback = function (text, style) { - if (text == "\n") { - node.appendChild(document.createElement("br")); - col = 0; - return; - } - var content = ""; - // replace tabs - for (var pos = 0; ;) { - var idx = text.indexOf("\t", pos); - if (idx == -1) { - content += text.slice(pos); - col += text.length - pos; - break; - } else { - col += idx - pos; - content += text.slice(pos, idx); - var size = tabSize - col % tabSize; - col += size; - for (var i = 0; i < size; ++i) content += " "; - pos = idx + 1; - } - } - - if (style) { - var sp = node.appendChild(document.createElement("span")); - sp.className = "cm-" + style.replace(/ +/g, " cm-"); - sp.appendChild(document.createTextNode(content)); - } else { - node.appendChild(document.createTextNode(content)); - } - }; + // Extra arguments are stored as the mode's dependencies, which is + // used by (legacy) mechanisms like loadmode.js to automatically + // load a mode. (Preferred mechanism is the require/define calls.) + function defineMode(name, mode) { + if (arguments.length > 2) + { mode.dependencies = Array.prototype.slice.call(arguments, 2); } + modes[name] = mode; } - var lines = splitLines(string), state = (options && options.state) || CodeMirror.startState(mode); - for (var i = 0, e = lines.length; i < e; ++i) { - if (i) callback("\n"); - var stream = new CodeMirror.StringStream(lines[i]); - if (!stream.string && mode.blankLine) mode.blankLine(state); - while (!stream.eol()) { - var style = mode.token(stream, state); - callback(stream.current(), style, i, stream.start, state); - stream.start = stream.pos; + function defineMIME(mime, spec) { + mimeModes[mime] = spec; + } + + // Given a MIME type, a {name, ...options} config object, or a name + // string, return a mode config object. + function resolveMode(spec) { + if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { + spec = mimeModes[spec]; + } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { + var found = mimeModes[spec.name]; + if (typeof found == "string") { found = {name: found}; } + spec = createObj(found, spec); + spec.name = found.name; + } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { + return resolveMode("application/xml") + } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+json$/.test(spec)) { + return resolveMode("application/json") } + if (typeof spec == "string") { return {name: spec} } + else { return spec || {name: "null"} } } -}; -})(); + + // Given a mode spec (anything that resolveMode accepts), find and + // initialize an actual mode object. + function getMode(options, spec) { + spec = resolveMode(spec); + var mfactory = modes[spec.name]; + if (!mfactory) { return getMode(options, "text/plain") } + var modeObj = mfactory(options, spec); + if (modeExtensions.hasOwnProperty(spec.name)) { + var exts = modeExtensions[spec.name]; + for (var prop in exts) { + if (!exts.hasOwnProperty(prop)) { continue } + if (modeObj.hasOwnProperty(prop)) { modeObj["_" + prop] = modeObj[prop]; } + modeObj[prop] = exts[prop]; + } + } + modeObj.name = spec.name; + if (spec.helperType) { modeObj.helperType = spec.helperType; } + if (spec.modeProps) { for (var prop$1 in spec.modeProps) + { modeObj[prop$1] = spec.modeProps[prop$1]; } } + + return modeObj + } + + // This can be used to attach properties to mode objects from + // outside the actual mode definition. + var modeExtensions = {}; + function extendMode(mode, properties) { + var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); + copyObj(properties, exts); + } + + function copyState(mode, state) { + if (state === true) { return state } + if (mode.copyState) { return mode.copyState(state) } + var nstate = {}; + for (var n in state) { + var val = state[n]; + if (val instanceof Array) { val = val.concat([]); } + nstate[n] = val; + } + return nstate + } + + // Given a mode and a state (for that mode), find the inner mode and + // state at the position that the state refers to. + function innerMode(mode, state) { + var info; + while (mode.innerMode) { + info = mode.innerMode(state); + if (!info || info.mode == mode) { break } + state = info.state; + mode = info.mode; + } + return info || {mode: mode, state: state} + } + + function startState(mode, a1, a2) { + return mode.startState ? mode.startState(a1, a2) : true + } + + var modeMethods = { + __proto__: null, + modes: modes, + mimeModes: mimeModes, + defineMode: defineMode, + defineMIME: defineMIME, + resolveMode: resolveMode, + getMode: getMode, + modeExtensions: modeExtensions, + extendMode: extendMode, + copyState: copyState, + innerMode: innerMode, + startState: startState + }; + + // declare global: globalThis, CodeMirror + + // Create a minimal CodeMirror needed to use runMode, and assign to root. + var root = typeof globalThis !== 'undefined' ? globalThis : window; + root.CodeMirror = {}; + + // Copy StringStream and mode methods into CodeMirror object. + CodeMirror.StringStream = StringStream; + for (var exported in modeMethods) { CodeMirror[exported] = modeMethods[exported]; } + + // Minimal default mode. + CodeMirror.defineMode("null", function () { return ({token: function (stream) { return stream.skipToEnd(); }}); }); + CodeMirror.defineMIME("text/plain", "null"); + + CodeMirror.registerHelper = CodeMirror.registerGlobalHelper = Math.min; + CodeMirror.splitLines = function(string) { return string.split(/\r?\n|\r/) }; + CodeMirror.countColumn = countColumn; + + CodeMirror.defaults = { indentUnit: 2 }; + + // CodeMirror, copyright (c) by Marijn Haverbeke and others + // Distributed under an MIT license: https://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) { + + CodeMirror.runMode = function(string, modespec, callback, options) { + var mode = CodeMirror.getMode(CodeMirror.defaults, modespec); + var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize; + + // Create a tokenizing callback function if passed-in callback is a DOM element. + if (callback.appendChild) { + var ie = /MSIE \d/.test(navigator.userAgent); + var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9); + var node = callback, col = 0; + node.innerHTML = ""; + callback = function(text, style) { + if (text == "\n") { + // Emitting LF or CRLF on IE8 or earlier results in an incorrect display. + // Emitting a carriage return makes everything ok. + node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text)); + col = 0; + return; + } + var content = ""; + // replace tabs + for (var pos = 0;;) { + var idx = text.indexOf("\t", pos); + if (idx == -1) { + content += text.slice(pos); + col += text.length - pos; + break; + } else { + col += idx - pos; + content += text.slice(pos, idx); + var size = tabSize - col % tabSize; + col += size; + for (var i = 0; i < size; ++i) { content += " "; } + pos = idx + 1; + } + } + // Create a node with token style and append it to the callback DOM element. + if (style) { + var sp = node.appendChild(document.createElement("span")); + sp.className = "cm-" + style.replace(/ +/g, " cm-"); + sp.appendChild(document.createTextNode(content)); + } else { + node.appendChild(document.createTextNode(content)); + } + }; + } + + var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode); + for (var i = 0, e = lines.length; i < e; ++i) { + if (i) { callback("\n"); } + var stream = new CodeMirror.StringStream(lines[i], null, { + lookAhead: function(n) { return lines[i + n] }, + baseToken: function() {} + }); + if (!stream.string && mode.blankLine) { mode.blankLine(state); } + while (!stream.eol()) { + var style = mode.token(stream, state); + callback(stream.current(), style, i, stream.start, state, mode); + stream.start = stream.pos; + } + } + }; + + }); + +}()); diff --git a/static/editor.md/lib/codemirror/addon/runmode/runmode.js b/static/editor.md/lib/codemirror/addon/runmode/runmode.js index 07d2279f..f5d58e24 100644 --- a/static/editor.md/lib/codemirror/addon/runmode/runmode.js +++ b/static/editor.md/lib/codemirror/addon/runmode/runmode.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -13,11 +13,12 @@ CodeMirror.runMode = function(string, modespec, callback, options) { var mode = CodeMirror.getMode(CodeMirror.defaults, modespec); - var ie = /MSIE \d/.test(navigator.userAgent); - var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9); + var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize; - if (callback.nodeType == 1) { - var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize; + // Create a tokenizing callback function if passed-in callback is a DOM element. + if (callback.appendChild) { + var ie = /MSIE \d/.test(navigator.userAgent); + var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9); var node = callback, col = 0; node.innerHTML = ""; callback = function(text, style) { @@ -45,7 +46,7 @@ CodeMirror.runMode = function(string, modespec, callback, options) { pos = idx + 1; } } - + // Create a node with token style and append it to the callback DOM element. if (style) { var sp = node.appendChild(document.createElement("span")); sp.className = "cm-" + style.replace(/ +/g, " cm-"); @@ -59,11 +60,14 @@ CodeMirror.runMode = function(string, modespec, callback, options) { var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode); for (var i = 0, e = lines.length; i < e; ++i) { if (i) callback("\n"); - var stream = new CodeMirror.StringStream(lines[i]); + var stream = new CodeMirror.StringStream(lines[i], null, { + lookAhead: function(n) { return lines[i + n] }, + baseToken: function() {} + }); if (!stream.string && mode.blankLine) mode.blankLine(state); while (!stream.eol()) { var style = mode.token(stream, state); - callback(stream.current(), style, i, stream.start, state); + callback(stream.current(), style, i, stream.start, state, mode); stream.start = stream.pos; } } diff --git a/static/editor.md/lib/codemirror/addon/runmode/runmode.node.js b/static/editor.md/lib/codemirror/addon/runmode/runmode.node.js index 8b8140b4..ddd255ab 100644 --- a/static/editor.md/lib/codemirror/addon/runmode/runmode.node.js +++ b/static/editor.md/lib/codemirror/addon/runmode/runmode.node.js @@ -1,120 +1,329 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +'use strict'; -/* Just enough of CodeMirror to run runMode under node.js */ +function copyObj(obj, target, overwrite) { + if (!target) { target = {}; } + for (var prop in obj) + { if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) + { target[prop] = obj[prop]; } } + return target +} -// declare global: StringStream +// Counts the column offset in a string, taking tabs into account. +// Used mostly to find indentation. +function countColumn(string, end, tabSize, startIndex, startValue) { + if (end == null) { + end = string.search(/[^\s\u00a0]/); + if (end == -1) { end = string.length; } + } + for (var i = startIndex || 0, n = startValue || 0;;) { + var nextTab = string.indexOf("\t", i); + if (nextTab < 0 || nextTab >= end) + { return n + (end - i) } + n += nextTab - i; + n += tabSize - (n % tabSize); + i = nextTab + 1; + } +} -function splitLines(string){ return string.split(/\r?\n|\r/); }; +function nothing() {} -function StringStream(string) { +function createObj(base, props) { + var inst; + if (Object.create) { + inst = Object.create(base); + } else { + nothing.prototype = base; + inst = new nothing(); + } + if (props) { copyObj(props, inst); } + return inst +} + +// STRING STREAM + +// Fed to the mode parsers, provides helper functions to make +// parsers more succinct. + +var StringStream = function(string, tabSize, lineOracle) { this.pos = this.start = 0; this.string = string; + this.tabSize = tabSize || 8; + this.lastColumnPos = this.lastColumnValue = 0; this.lineStart = 0; -} -StringStream.prototype = { - eol: function() {return this.pos >= this.string.length;}, - sol: function() {return this.pos == 0;}, - peek: function() {return this.string.charAt(this.pos) || null;}, - next: function() { - if (this.pos < this.string.length) - return this.string.charAt(this.pos++); - }, - eat: function(match) { - var ch = this.string.charAt(this.pos); - if (typeof match == "string") var ok = ch == match; - else var ok = ch && (match.test ? match.test(ch) : match(ch)); - if (ok) {++this.pos; return ch;} - }, - eatWhile: function(match) { - var start = this.pos; - while (this.eat(match)){} - return this.pos > start; - }, - eatSpace: function() { - var start = this.pos; - while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; - return this.pos > start; - }, - skipToEnd: function() {this.pos = this.string.length;}, - skipTo: function(ch) { - var found = this.string.indexOf(ch, this.pos); - if (found > -1) {this.pos = found; return true;} - }, - backUp: function(n) {this.pos -= n;}, - column: function() {return this.start - this.lineStart;}, - indentation: function() {return 0;}, - match: function(pattern, consume, caseInsensitive) { - if (typeof pattern == "string") { - var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; - var substr = this.string.substr(this.pos, pattern.length); - if (cased(substr) == cased(pattern)) { - if (consume !== false) this.pos += pattern.length; - return true; - } - } else { - var match = this.string.slice(this.pos).match(pattern); - if (match && match.index > 0) return null; - if (match && consume !== false) this.pos += match[0].length; - return match; + this.lineOracle = lineOracle; +}; + +StringStream.prototype.eol = function () {return this.pos >= this.string.length}; +StringStream.prototype.sol = function () {return this.pos == this.lineStart}; +StringStream.prototype.peek = function () {return this.string.charAt(this.pos) || undefined}; +StringStream.prototype.next = function () { + if (this.pos < this.string.length) + { return this.string.charAt(this.pos++) } +}; +StringStream.prototype.eat = function (match) { + var ch = this.string.charAt(this.pos); + var ok; + if (typeof match == "string") { ok = ch == match; } + else { ok = ch && (match.test ? match.test(ch) : match(ch)); } + if (ok) {++this.pos; return ch} +}; +StringStream.prototype.eatWhile = function (match) { + var start = this.pos; + while (this.eat(match)){} + return this.pos > start +}; +StringStream.prototype.eatSpace = function () { + var start = this.pos; + while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this.pos; } + return this.pos > start +}; +StringStream.prototype.skipToEnd = function () {this.pos = this.string.length;}; +StringStream.prototype.skipTo = function (ch) { + var found = this.string.indexOf(ch, this.pos); + if (found > -1) {this.pos = found; return true} +}; +StringStream.prototype.backUp = function (n) {this.pos -= n;}; +StringStream.prototype.column = function () { + if (this.lastColumnPos < this.start) { + this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); + this.lastColumnPos = this.start; + } + return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0) +}; +StringStream.prototype.indentation = function () { + return countColumn(this.string, null, this.tabSize) - + (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0) +}; +StringStream.prototype.match = function (pattern, consume, caseInsensitive) { + if (typeof pattern == "string") { + var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; }; + var substr = this.string.substr(this.pos, pattern.length); + if (cased(substr) == cased(pattern)) { + if (consume !== false) { this.pos += pattern.length; } + return true } - }, - current: function(){return this.string.slice(this.start, this.pos);}, - hideFirstChars: function(n, inner) { - this.lineStart += n; - try { return inner(); } - finally { this.lineStart -= n; } + } else { + var match = this.string.slice(this.pos).match(pattern); + if (match && match.index > 0) { return null } + if (match && consume !== false) { this.pos += match[0].length; } + return match } }; -exports.StringStream = StringStream; - -exports.startState = function(mode, a1, a2) { - return mode.startState ? mode.startState(a1, a2) : true; +StringStream.prototype.current = function (){return this.string.slice(this.start, this.pos)}; +StringStream.prototype.hideFirstChars = function (n, inner) { + this.lineStart += n; + try { return inner() } + finally { this.lineStart -= n; } +}; +StringStream.prototype.lookAhead = function (n) { + var oracle = this.lineOracle; + return oracle && oracle.lookAhead(n) +}; +StringStream.prototype.baseToken = function () { + var oracle = this.lineOracle; + return oracle && oracle.baseToken(this.pos) }; -var modes = exports.modes = {}, mimeModes = exports.mimeModes = {}; -exports.defineMode = function(name, mode) { +// Known modes, by name and by MIME +var modes = {}, mimeModes = {}; + +// Extra arguments are stored as the mode's dependencies, which is +// used by (legacy) mechanisms like loadmode.js to automatically +// load a mode. (Preferred mechanism is the require/define calls.) +function defineMode(name, mode) { if (arguments.length > 2) - mode.dependencies = Array.prototype.slice.call(arguments, 2); + { mode.dependencies = Array.prototype.slice.call(arguments, 2); } modes[name] = mode; -}; -exports.defineMIME = function(mime, spec) { mimeModes[mime] = spec; }; +} -exports.defineMode("null", function() { - return {token: function(stream) {stream.skipToEnd();}}; -}); -exports.defineMIME("text/plain", "null"); +function defineMIME(mime, spec) { + mimeModes[mime] = spec; +} -exports.resolveMode = function(spec) { +// Given a MIME type, a {name, ...options} config object, or a name +// string, return a mode config object. +function resolveMode(spec) { if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { spec = mimeModes[spec]; } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { - spec = mimeModes[spec.name]; + var found = mimeModes[spec.name]; + if (typeof found == "string") { found = {name: found}; } + spec = createObj(found, spec); + spec.name = found.name; + } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { + return resolveMode("application/xml") + } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+json$/.test(spec)) { + return resolveMode("application/json") } - if (typeof spec == "string") return {name: spec}; - else return spec || {name: "null"}; -}; -exports.getMode = function(options, spec) { - spec = exports.resolveMode(spec); - var mfactory = modes[spec.name]; - if (!mfactory) throw new Error("Unknown mode: " + spec); - return mfactory(options, spec); -}; -exports.registerHelper = exports.registerGlobalHelper = Math.min; + if (typeof spec == "string") { return {name: spec} } + else { return spec || {name: "null"} } +} -exports.runMode = function(string, modespec, callback, options) { - var mode = exports.getMode({indentUnit: 2}, modespec); - var lines = splitLines(string), state = (options && options.state) || exports.startState(mode); +// Given a mode spec (anything that resolveMode accepts), find and +// initialize an actual mode object. +function getMode(options, spec) { + spec = resolveMode(spec); + var mfactory = modes[spec.name]; + if (!mfactory) { return getMode(options, "text/plain") } + var modeObj = mfactory(options, spec); + if (modeExtensions.hasOwnProperty(spec.name)) { + var exts = modeExtensions[spec.name]; + for (var prop in exts) { + if (!exts.hasOwnProperty(prop)) { continue } + if (modeObj.hasOwnProperty(prop)) { modeObj["_" + prop] = modeObj[prop]; } + modeObj[prop] = exts[prop]; + } + } + modeObj.name = spec.name; + if (spec.helperType) { modeObj.helperType = spec.helperType; } + if (spec.modeProps) { for (var prop$1 in spec.modeProps) + { modeObj[prop$1] = spec.modeProps[prop$1]; } } + + return modeObj +} + +// This can be used to attach properties to mode objects from +// outside the actual mode definition. +var modeExtensions = {}; +function extendMode(mode, properties) { + var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); + copyObj(properties, exts); +} + +function copyState(mode, state) { + if (state === true) { return state } + if (mode.copyState) { return mode.copyState(state) } + var nstate = {}; + for (var n in state) { + var val = state[n]; + if (val instanceof Array) { val = val.concat([]); } + nstate[n] = val; + } + return nstate +} + +// Given a mode and a state (for that mode), find the inner mode and +// state at the position that the state refers to. +function innerMode(mode, state) { + var info; + while (mode.innerMode) { + info = mode.innerMode(state); + if (!info || info.mode == mode) { break } + state = info.state; + mode = info.mode; + } + return info || {mode: mode, state: state} +} + +function startState(mode, a1, a2) { + return mode.startState ? mode.startState(a1, a2) : true +} + +var modeMethods = { + __proto__: null, + modes: modes, + mimeModes: mimeModes, + defineMode: defineMode, + defineMIME: defineMIME, + resolveMode: resolveMode, + getMode: getMode, + modeExtensions: modeExtensions, + extendMode: extendMode, + copyState: copyState, + innerMode: innerMode, + startState: startState +}; + +// Copy StringStream and mode methods into exports (CodeMirror) object. +exports.StringStream = StringStream; +exports.countColumn = countColumn; +for (var exported in modeMethods) { exports[exported] = modeMethods[exported]; } + +// Shim library CodeMirror with the minimal CodeMirror defined above. +require.cache[require.resolve("../../lib/codemirror")] = require.cache[require.resolve("./runmode.node")]; +require.cache[require.resolve("../../addon/runmode/runmode")] = require.cache[require.resolve("./runmode.node")]; + +// Minimal default mode. +exports.defineMode("null", function () { return ({token: function (stream) { return stream.skipToEnd(); }}); }); +exports.defineMIME("text/plain", "null"); + +exports.registerHelper = exports.registerGlobalHelper = Math.min; +exports.splitLines = function(string) { return string.split(/\r?\n|\r/) }; + +exports.defaults = { indentUnit: 2 }; + +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: https://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) { + +CodeMirror.runMode = function(string, modespec, callback, options) { + var mode = CodeMirror.getMode(CodeMirror.defaults, modespec); + var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize; + + // Create a tokenizing callback function if passed-in callback is a DOM element. + if (callback.appendChild) { + var ie = /MSIE \d/.test(navigator.userAgent); + var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9); + var node = callback, col = 0; + node.innerHTML = ""; + callback = function(text, style) { + if (text == "\n") { + // Emitting LF or CRLF on IE8 or earlier results in an incorrect display. + // Emitting a carriage return makes everything ok. + node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text)); + col = 0; + return; + } + var content = ""; + // replace tabs + for (var pos = 0;;) { + var idx = text.indexOf("\t", pos); + if (idx == -1) { + content += text.slice(pos); + col += text.length - pos; + break; + } else { + col += idx - pos; + content += text.slice(pos, idx); + var size = tabSize - col % tabSize; + col += size; + for (var i = 0; i < size; ++i) { content += " "; } + pos = idx + 1; + } + } + // Create a node with token style and append it to the callback DOM element. + if (style) { + var sp = node.appendChild(document.createElement("span")); + sp.className = "cm-" + style.replace(/ +/g, " cm-"); + sp.appendChild(document.createTextNode(content)); + } else { + node.appendChild(document.createTextNode(content)); + } + }; + } + + var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode); for (var i = 0, e = lines.length; i < e; ++i) { - if (i) callback("\n"); - var stream = new exports.StringStream(lines[i]); - if (!stream.string && mode.blankLine) mode.blankLine(state); + if (i) { callback("\n"); } + var stream = new CodeMirror.StringStream(lines[i], null, { + lookAhead: function(n) { return lines[i + n] }, + baseToken: function() {} + }); + if (!stream.string && mode.blankLine) { mode.blankLine(state); } while (!stream.eol()) { var style = mode.token(stream, state); - callback(stream.current(), style, i, stream.start, state); + callback(stream.current(), style, i, stream.start, state, mode); stream.start = stream.pos; } } }; -require.cache[require.resolve("../../lib/codemirror")] = require.cache[require.resolve("./runmode.node")]; +}); diff --git a/static/editor.md/lib/codemirror/addon/scroll/annotatescrollbar.js b/static/editor.md/lib/codemirror/addon/scroll/annotatescrollbar.js index 54aeacf2..c12e44cd 100644 --- a/static/editor.md/lib/codemirror/addon/scroll/annotatescrollbar.js +++ b/static/editor.md/lib/codemirror/addon/scroll/annotatescrollbar.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -43,7 +43,7 @@ cm.on("markerAdded", this.resizeHandler); cm.on("markerCleared", this.resizeHandler); if (options.listenForChanges !== false) - cm.on("change", this.changeHandler = function() { + cm.on("changes", this.changeHandler = function() { scheduleRedraw(250); }); } @@ -51,7 +51,7 @@ Annotation.prototype.computeScale = function() { var cm = this.cm; var hScale = (cm.getWrapperElement().clientHeight - cm.display.barHeight - this.buttonHeight * 2) / - cm.heightAtLine(cm.lastLine() + 1, "local"); + cm.getScrollerElement().scrollHeight if (hScale != this.hScale) { this.hScale = hScale; return true; @@ -68,15 +68,40 @@ var cm = this.cm, hScale = this.hScale; var frag = document.createDocumentFragment(), anns = this.annotations; + + var wrapping = cm.getOption("lineWrapping"); + var singleLineH = wrapping && cm.defaultTextHeight() * 1.5; + var curLine = null, curLineObj = null; + + function getY(pos, top) { + if (curLine != pos.line) { + curLine = pos.line + curLineObj = cm.getLineHandle(pos.line) + var visual = cm.getLineHandleVisualStart(curLineObj) + if (visual != curLineObj) { + curLine = cm.getLineNumber(visual) + curLineObj = visual + } + } + if ((curLineObj.widgets && curLineObj.widgets.length) || + (wrapping && curLineObj.height > singleLineH)) + return cm.charCoords(pos, "local")[top ? "top" : "bottom"]; + var topY = cm.heightAtLine(curLineObj, "local"); + return topY + (top ? 0 : curLineObj.height); + } + + var lastLine = cm.lastLine() if (cm.display.barWidth) for (var i = 0, nextTop; i < anns.length; i++) { var ann = anns[i]; - var top = nextTop || cm.charCoords(ann.from, "local").top * hScale; - var bottom = cm.charCoords(ann.to, "local").bottom * hScale; + if (ann.to.line > lastLine) continue; + var top = nextTop || getY(ann.from, true) * hScale; + var bottom = getY(ann.to, false) * hScale; while (i < anns.length - 1) { - nextTop = cm.charCoords(anns[i + 1].from, "local").top * hScale; + if (anns[i + 1].to.line > lastLine) break; + nextTop = getY(anns[i + 1].from, true) * hScale; if (nextTop > bottom + .9) break; ann = anns[++i]; - bottom = cm.charCoords(ann.to, "local").bottom * hScale; + bottom = getY(ann.to, false) * hScale; } if (bottom == top) continue; var height = Math.max(bottom - top, 3); @@ -85,6 +110,9 @@ elt.style.cssText = "position: absolute; right: 0px; width: " + Math.max(cm.display.barWidth - 1, 2) + "px; top: " + (top + this.buttonHeight) + "px; height: " + height + "px"; elt.className = this.options.className; + if (ann.id) { + elt.setAttribute("annotation-id", ann.id); + } } this.div.textContent = ""; this.div.appendChild(frag); @@ -94,7 +122,7 @@ this.cm.off("refresh", this.resizeHandler); this.cm.off("markerAdded", this.resizeHandler); this.cm.off("markerCleared", this.resizeHandler); - if (this.changeHandler) this.cm.off("change", this.changeHandler); + if (this.changeHandler) this.cm.off("changes", this.changeHandler); this.div.parentNode.removeChild(this.div); }; }); diff --git a/static/editor.md/lib/codemirror/addon/scroll/scrollpastend.js b/static/editor.md/lib/codemirror/addon/scroll/scrollpastend.js index 008ae4c7..2ed9d95e 100644 --- a/static/editor.md/lib/codemirror/addon/scroll/scrollpastend.js +++ b/static/editor.md/lib/codemirror/addon/scroll/scrollpastend.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -40,7 +40,9 @@ if (cm.state.scrollPastEndPadding != padding) { cm.state.scrollPastEndPadding = padding; cm.display.lineSpace.parentNode.style.paddingBottom = padding; + cm.off("refresh", updateBottomMargin); cm.setSize(); + cm.on("refresh", updateBottomMargin); } } }); diff --git a/static/editor.md/lib/codemirror/addon/scroll/simplescrollbars.js b/static/editor.md/lib/codemirror/addon/scroll/simplescrollbars.js index bb06adb8..750a2bd3 100644 --- a/static/editor.md/lib/codemirror/addon/scroll/simplescrollbars.js +++ b/static/editor.md/lib/codemirror/addon/scroll/simplescrollbars.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -59,26 +59,38 @@ CodeMirror.on(this.node, "DOMMouseScroll", onWheel); } - Bar.prototype.moveTo = function(pos, update) { + Bar.prototype.setPos = function(pos, force) { if (pos < 0) pos = 0; if (pos > this.total - this.screen) pos = this.total - this.screen; - if (pos == this.pos) return; + if (!force && pos == this.pos) return false; this.pos = pos; this.inner.style[this.orientation == "horizontal" ? "left" : "top"] = (pos * (this.size / this.total)) + "px"; - if (update !== false) this.scroll(pos, this.orientation); + return true }; - Bar.prototype.update = function(scrollSize, clientSize, barSize) { - this.screen = clientSize; - this.total = scrollSize; - this.size = barSize; + Bar.prototype.moveTo = function(pos) { + if (this.setPos(pos)) this.scroll(pos, this.orientation); + } - // FIXME clip to min size? + var minButtonSize = 10; + + Bar.prototype.update = function(scrollSize, clientSize, barSize) { + var sizeChanged = this.screen != clientSize || this.total != scrollSize || this.size != barSize + if (sizeChanged) { + this.screen = clientSize; + this.total = scrollSize; + this.size = barSize; + } + + var buttonSize = this.screen * (this.size / this.total); + if (buttonSize < minButtonSize) { + this.size -= minButtonSize - buttonSize; + buttonSize = minButtonSize; + } this.inner.style[this.orientation == "horizontal" ? "width" : "height"] = - this.screen * (this.size / this.total) + "px"; - this.inner.style[this.orientation == "horizontal" ? "left" : "top"] = - this.pos * (this.size / this.total) + "px"; + buttonSize + "px"; + this.setPos(this.pos, sizeChanged); }; function SimpleScrollbars(cls, place, scroll) { @@ -105,7 +117,6 @@ if (needsV) { this.vert.update(measure.scrollHeight, measure.clientHeight, measure.viewHeight - (needsH ? width : 0)); - this.vert.node.style.display = "block"; this.vert.node.style.bottom = needsH ? width + "px" : "0"; } if (needsH) { @@ -119,11 +130,11 @@ }; SimpleScrollbars.prototype.setScrollTop = function(pos) { - this.vert.moveTo(pos, false); + this.vert.setPos(pos); }; SimpleScrollbars.prototype.setScrollLeft = function(pos) { - this.horiz.moveTo(pos, false); + this.horiz.setPos(pos); }; SimpleScrollbars.prototype.clear = function() { diff --git a/static/editor.md/lib/codemirror/addon/search/jump-to-line.js b/static/editor.md/lib/codemirror/addon/search/jump-to-line.js new file mode 100644 index 00000000..990c235e --- /dev/null +++ b/static/editor.md/lib/codemirror/addon/search/jump-to-line.js @@ -0,0 +1,53 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: https://codemirror.net/LICENSE + +// Defines jumpToLine command. Uses dialog.js if present. + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../dialog/dialog")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../dialog/dialog"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + // default search panel location + CodeMirror.defineOption("search", {bottom: false}); + + function dialog(cm, text, shortText, deflt, f) { + if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true, bottom: cm.options.search.bottom}); + else f(prompt(shortText, deflt)); + } + + function getJumpDialog(cm) { + return cm.phrase("Jump to line:") + ' ' + cm.phrase("(Use line:column or scroll% syntax)") + ''; + } + + function interpretLine(cm, string) { + var num = Number(string) + if (/^[-+]/.test(string)) return cm.getCursor().line + num + else return num - 1 + } + + CodeMirror.commands.jumpToLine = function(cm) { + var cur = cm.getCursor(); + dialog(cm, getJumpDialog(cm), cm.phrase("Jump to line:"), (cur.line + 1) + ":" + cur.ch, function(posStr) { + if (!posStr) return; + + var match; + if (match = /^\s*([\+\-]?\d+)\s*\:\s*(\d+)\s*$/.exec(posStr)) { + cm.setCursor(interpretLine(cm, match[1]), Number(match[2])) + } else if (match = /^\s*([\+\-]?\d+(\.\d+)?)\%\s*/.exec(posStr)) { + var line = Math.round(cm.lineCount() * Number(match[1]) / 100); + if (/^[-+]/.test(match[1])) line = cur.line + line + 1; + cm.setCursor(line - 1, cur.ch); + } else if (match = /^\s*\:?\s*([\+\-]?\d+)\s*/.exec(posStr)) { + cm.setCursor(interpretLine(cm, match[1]), cur.ch); + } + }); + }; + + CodeMirror.keyMap["default"]["Alt-G"] = "jumpToLine"; +}); diff --git a/static/editor.md/lib/codemirror/addon/search/match-highlighter.js b/static/editor.md/lib/codemirror/addon/search/match-highlighter.js index e9a22721..9b181ebc 100644 --- a/static/editor.md/lib/codemirror/addon/search/match-highlighter.js +++ b/static/editor.md/lib/codemirror/addon/search/match-highlighter.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE // Highlighting text that matches the selection // @@ -16,81 +16,120 @@ // highlighted only if the selected text is a word. showToken, when enabled, // will cause the current token to be highlighted when nothing is selected. // delay is used to specify how much time to wait, in milliseconds, before -// highlighting the matches. +// highlighting the matches. If annotateScrollbar is enabled, the occurrences +// will be highlighted on the scrollbar via the matchesonscrollbar addon. (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); + mod(require("../../lib/codemirror"), require("./matchesonscrollbar")); else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); + define(["../../lib/codemirror", "./matchesonscrollbar"], mod); else // Plain browser env mod(CodeMirror); })(function(CodeMirror) { "use strict"; - var DEFAULT_MIN_CHARS = 2; - var DEFAULT_TOKEN_STYLE = "matchhighlight"; - var DEFAULT_DELAY = 100; - var DEFAULT_WORDS_ONLY = false; + var defaults = { + style: "matchhighlight", + minChars: 2, + delay: 100, + wordsOnly: false, + annotateScrollbar: false, + showToken: false, + trim: true + } function State(options) { - if (typeof options == "object") { - this.minChars = options.minChars; - this.style = options.style; - this.showToken = options.showToken; - this.delay = options.delay; - this.wordsOnly = options.wordsOnly; - } - if (this.style == null) this.style = DEFAULT_TOKEN_STYLE; - if (this.minChars == null) this.minChars = DEFAULT_MIN_CHARS; - if (this.delay == null) this.delay = DEFAULT_DELAY; - if (this.wordsOnly == null) this.wordsOnly = DEFAULT_WORDS_ONLY; + this.options = {} + for (var name in defaults) + this.options[name] = (options && options.hasOwnProperty(name) ? options : defaults)[name] this.overlay = this.timeout = null; + this.matchesonscroll = null; + this.active = false; } CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) { if (old && old != CodeMirror.Init) { - var over = cm.state.matchHighlighter.overlay; - if (over) cm.removeOverlay(over); + removeOverlay(cm); clearTimeout(cm.state.matchHighlighter.timeout); cm.state.matchHighlighter = null; cm.off("cursorActivity", cursorActivity); + cm.off("focus", onFocus) } if (val) { - cm.state.matchHighlighter = new State(val); - highlightMatches(cm); + var state = cm.state.matchHighlighter = new State(val); + if (cm.hasFocus()) { + state.active = true + highlightMatches(cm) + } else { + cm.on("focus", onFocus) + } cm.on("cursorActivity", cursorActivity); } }); function cursorActivity(cm) { var state = cm.state.matchHighlighter; + if (state.active || cm.hasFocus()) scheduleHighlight(cm, state) + } + + function onFocus(cm) { + var state = cm.state.matchHighlighter + if (!state.active) { + state.active = true + scheduleHighlight(cm, state) + } + } + + function scheduleHighlight(cm, state) { clearTimeout(state.timeout); - state.timeout = setTimeout(function() {highlightMatches(cm);}, state.delay); + state.timeout = setTimeout(function() {highlightMatches(cm);}, state.options.delay); + } + + function addOverlay(cm, query, hasBoundary, style) { + var state = cm.state.matchHighlighter; + cm.addOverlay(state.overlay = makeOverlay(query, hasBoundary, style)); + if (state.options.annotateScrollbar && cm.showMatchesOnScrollbar) { + var searchFor = hasBoundary ? new RegExp((/\w/.test(query.charAt(0)) ? "\\b" : "") + + query.replace(/[\\\[.+*?(){|^$]/g, "\\$&") + + (/\w/.test(query.charAt(query.length - 1)) ? "\\b" : "")) : query; + state.matchesonscroll = cm.showMatchesOnScrollbar(searchFor, false, + {className: "CodeMirror-selection-highlight-scrollbar"}); + } + } + + function removeOverlay(cm) { + var state = cm.state.matchHighlighter; + if (state.overlay) { + cm.removeOverlay(state.overlay); + state.overlay = null; + if (state.matchesonscroll) { + state.matchesonscroll.clear(); + state.matchesonscroll = null; + } + } } function highlightMatches(cm) { cm.operation(function() { var state = cm.state.matchHighlighter; - if (state.overlay) { - cm.removeOverlay(state.overlay); - state.overlay = null; - } - if (!cm.somethingSelected() && state.showToken) { - var re = state.showToken === true ? /[\w$]/ : state.showToken; + removeOverlay(cm); + if (!cm.somethingSelected() && state.options.showToken) { + var re = state.options.showToken === true ? /[\w$]/ : state.options.showToken; var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start; while (start && re.test(line.charAt(start - 1))) --start; while (end < line.length && re.test(line.charAt(end))) ++end; if (start < end) - cm.addOverlay(state.overlay = makeOverlay(line.slice(start, end), re, state.style)); + addOverlay(cm, line.slice(start, end), re, state.options.style); return; } var from = cm.getCursor("from"), to = cm.getCursor("to"); if (from.line != to.line) return; - if (state.wordsOnly && !isWord(cm, from, to)) return; - var selection = cm.getRange(from, to).replace(/^\s+|\s+$/g, ""); - if (selection.length >= state.minChars) - cm.addOverlay(state.overlay = makeOverlay(selection, false, state.style)); + if (state.options.wordsOnly && !isWord(cm, from, to)) return; + var selection = cm.getRange(from, to) + if (state.options.trim) selection = selection.replace(/^\s+|\s+$/g, "") + if (selection.length >= state.options.minChars) + addOverlay(cm, selection, false, state.options.style); }); } diff --git a/static/editor.md/lib/codemirror/addon/search/matchesonscrollbar.js b/static/editor.md/lib/codemirror/addon/search/matchesonscrollbar.js index dbd67a4a..8a4a8275 100644 --- a/static/editor.md/lib/codemirror/addon/search/matchesonscrollbar.js +++ b/static/editor.md/lib/codemirror/addon/search/matchesonscrollbar.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -19,6 +19,7 @@ function SearchAnnotation(cm, query, caseFold, options) { this.cm = cm; + this.options = options; var annotateOptions = {listenForChanges: false}; for (var prop in options) annotateOptions[prop] = options[prop]; if (!annotateOptions.className) annotateOptions.className = "CodeMirror-search-match"; @@ -45,12 +46,13 @@ if (match.from.line >= this.gap.to) break; if (match.to.line >= this.gap.from) this.matches.splice(i--, 1); } - var cursor = this.cm.getSearchCursor(this.query, CodeMirror.Pos(this.gap.from, 0), this.caseFold); + var cursor = this.cm.getSearchCursor(this.query, CodeMirror.Pos(this.gap.from, 0), {caseFold: this.caseFold, multiline: this.options.multiline}); + var maxMatches = this.options && this.options.maxMatches || MAX_MATCHES; while (cursor.findNext()) { var match = {from: cursor.from(), to: cursor.to()}; if (match.from.line >= this.gap.to) break; this.matches.splice(i++, 0, match); - if (this.matches.length > MAX_MATCHES) break; + if (this.matches.length > maxMatches) break; } this.gap = null; }; diff --git a/static/editor.md/lib/codemirror/addon/search/search.js b/static/editor.md/lib/codemirror/addon/search/search.js index 0251067a..24a0855e 100644 --- a/static/editor.md/lib/codemirror/addon/search/search.js +++ b/static/editor.md/lib/codemirror/addon/search/search.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE // Define search commands. Depends on dialog.js or another // implementation of the openDialog method. @@ -18,6 +18,10 @@ mod(CodeMirror); })(function(CodeMirror) { "use strict"; + + // default search panel location + CodeMirror.defineOption("search", {bottom: false}); + function searchOverlay(query, caseInsensitive) { if (typeof query == "string") query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g"); @@ -28,7 +32,7 @@ query.lastIndex = stream.pos; var match = query.exec(stream.string); if (match && match.index == stream.pos) { - stream.pos += match[0].length; + stream.pos += match[0].length || 1; return "searching"; } else if (match) { stream.pos = match.index; @@ -39,59 +43,131 @@ } function SearchState() { - this.posFrom = this.posTo = this.query = null; + this.posFrom = this.posTo = this.lastQuery = this.query = null; this.overlay = null; } + function getSearchState(cm) { return cm.state.search || (cm.state.search = new SearchState()); } + function queryCaseInsensitive(query) { return typeof query == "string" && query == query.toLowerCase(); } + function getSearchCursor(cm, query, pos) { // Heuristic: if the query string is all lowercase, do a case insensitive search. - return cm.getSearchCursor(query, pos, queryCaseInsensitive(query)); + return cm.getSearchCursor(query, pos, {caseFold: queryCaseInsensitive(query), multiline: true}); } + + function persistentDialog(cm, text, deflt, onEnter, onKeyDown) { + cm.openDialog(text, onEnter, { + value: deflt, + selectValueOnOpen: true, + closeOnEnter: false, + onClose: function() { clearSearch(cm); }, + onKeyDown: onKeyDown, + bottom: cm.options.search.bottom + }); + } + function dialog(cm, text, shortText, deflt, f) { - if (cm.openDialog) cm.openDialog(text, f, {value: deflt}); + if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true, bottom: cm.options.search.bottom}); else f(prompt(shortText, deflt)); } + function confirmDialog(cm, text, shortText, fs) { if (cm.openConfirm) cm.openConfirm(text, fs); else if (confirm(shortText)) fs[0](); } + + function parseString(string) { + return string.replace(/\\([nrt\\])/g, function(match, ch) { + if (ch == "n") return "\n" + if (ch == "r") return "\r" + if (ch == "t") return "\t" + if (ch == "\\") return "\\" + return match + }) + } + function parseQuery(query) { var isRE = query.match(/^\/(.*)\/([a-z]*)$/); if (isRE) { try { query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i"); } catch(e) {} // Not a regular expression after all, do a string search + } else { + query = parseString(query) } if (typeof query == "string" ? query == "" : query.test("")) query = /x^/; return query; } - var queryDialog = - 'Search: (Use /re/ syntax for regexp search)'; - function doSearch(cm, rev) { + + function startSearch(cm, state, query) { + state.queryText = query; + state.query = parseQuery(query); + cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query)); + state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query)); + cm.addOverlay(state.overlay); + if (cm.showMatchesOnScrollbar) { + if (state.annotate) { state.annotate.clear(); state.annotate = null; } + state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query)); + } + } + + function doSearch(cm, rev, persistent, immediate) { var state = getSearchState(cm); if (state.query) return findNext(cm, rev); - dialog(cm, queryDialog, "Search for:", cm.getSelection(), function(query) { - cm.operation(function() { - if (!query || state.query) return; - state.query = parseQuery(query); - cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query)); - state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query)); - cm.addOverlay(state.overlay); - if (cm.showMatchesOnScrollbar) { - if (state.annotate) { state.annotate.clear(); state.annotate = null; } - state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query)); + var q = cm.getSelection() || state.lastQuery; + if (q instanceof RegExp && q.source == "x^") q = null + if (persistent && cm.openDialog) { + var hiding = null + var searchNext = function(query, event) { + CodeMirror.e_stop(event); + if (!query) return; + if (query != state.queryText) { + startSearch(cm, state, query); + state.posFrom = state.posTo = cm.getCursor(); + } + if (hiding) hiding.style.opacity = 1 + findNext(cm, event.shiftKey, function(_, to) { + var dialog + if (to.line < 3 && document.querySelector && + (dialog = cm.display.wrapper.querySelector(".CodeMirror-dialog")) && + dialog.getBoundingClientRect().bottom - 4 > cm.cursorCoords(to, "window").top) + (hiding = dialog).style.opacity = .4 + }) + }; + persistentDialog(cm, getQueryDialog(cm), q, searchNext, function(event, query) { + var keyName = CodeMirror.keyName(event) + var extra = cm.getOption('extraKeys'), cmd = (extra && extra[keyName]) || CodeMirror.keyMap[cm.getOption("keyMap")][keyName] + if (cmd == "findNext" || cmd == "findPrev" || + cmd == "findPersistentNext" || cmd == "findPersistentPrev") { + CodeMirror.e_stop(event); + startSearch(cm, getSearchState(cm), query); + cm.execCommand(cmd); + } else if (cmd == "find" || cmd == "findPersistent") { + CodeMirror.e_stop(event); + searchNext(query, event); } - state.posFrom = state.posTo = cm.getCursor(); - findNext(cm, rev); }); - }); + if (immediate && q) { + startSearch(cm, state, q); + findNext(cm, rev); + } + } else { + dialog(cm, getQueryDialog(cm), "Search for:", q, function(query) { + if (query && !state.query) cm.operation(function() { + startSearch(cm, state, query); + state.posFrom = state.posTo = cm.getCursor(); + findNext(cm, rev); + }); + }); + } } - function findNext(cm, rev) {cm.operation(function() { + + function findNext(cm, rev, callback) {cm.operation(function() { var state = getSearchState(cm); var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo); if (!cursor.find(rev)) { @@ -99,39 +175,87 @@ if (!cursor.find(rev)) return; } cm.setSelection(cursor.from(), cursor.to()); - cm.scrollIntoView({from: cursor.from(), to: cursor.to()}); + cm.scrollIntoView({from: cursor.from(), to: cursor.to()}, 20); state.posFrom = cursor.from(); state.posTo = cursor.to(); + if (callback) callback(cursor.from(), cursor.to()) });} + function clearSearch(cm) {cm.operation(function() { var state = getSearchState(cm); + state.lastQuery = state.query; if (!state.query) return; - state.query = null; + state.query = state.queryText = null; cm.removeOverlay(state.overlay); if (state.annotate) { state.annotate.clear(); state.annotate = null; } });} - var replaceQueryDialog = - 'Replace: (Use /re/ syntax for regexp search)'; - var replacementQueryDialog = 'With: '; - var doReplaceConfirm = "Replace? "; + function el(tag, attrs) { + var element = tag ? document.createElement(tag) : document.createDocumentFragment(); + for (var key in attrs) { + element[key] = attrs[key]; + } + for (var i = 2; i < arguments.length; i++) { + var child = arguments[i] + element.appendChild(typeof child == "string" ? document.createTextNode(child) : child); + } + return element; + } + + function getQueryDialog(cm) { + return el("", null, + el("span", {className: "CodeMirror-search-label"}, cm.phrase("Search:")), " ", + el("input", {type: "text", "style": "width: 10em", className: "CodeMirror-search-field"}), " ", + el("span", {style: "color: #888", className: "CodeMirror-search-hint"}, + cm.phrase("(Use /re/ syntax for regexp search)"))); + } + function getReplaceQueryDialog(cm) { + return el("", null, " ", + el("input", {type: "text", "style": "width: 10em", className: "CodeMirror-search-field"}), " ", + el("span", {style: "color: #888", className: "CodeMirror-search-hint"}, + cm.phrase("(Use /re/ syntax for regexp search)"))); + } + function getReplacementQueryDialog(cm) { + return el("", null, + el("span", {className: "CodeMirror-search-label"}, cm.phrase("With:")), " ", + el("input", {type: "text", "style": "width: 10em", className: "CodeMirror-search-field"})); + } + function getDoReplaceConfirm(cm) { + return el("", null, + el("span", {className: "CodeMirror-search-label"}, cm.phrase("Replace?")), " ", + el("button", {}, cm.phrase("Yes")), " ", + el("button", {}, cm.phrase("No")), " ", + el("button", {}, cm.phrase("All")), " ", + el("button", {}, cm.phrase("Stop"))); + } + + function replaceAll(cm, query, text) { + cm.operation(function() { + for (var cursor = getSearchCursor(cm, query); cursor.findNext();) { + if (typeof query != "string") { + var match = cm.getRange(cursor.from(), cursor.to()).match(query); + cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];})); + } else cursor.replace(text); + } + }); + } + function replace(cm, all) { if (cm.getOption("readOnly")) return; - dialog(cm, replaceQueryDialog, "Replace:", cm.getSelection(), function(query) { + var query = cm.getSelection() || getSearchState(cm).lastQuery; + var dialogText = all ? cm.phrase("Replace all:") : cm.phrase("Replace:") + var fragment = el("", null, + el("span", {className: "CodeMirror-search-label"}, dialogText), + getReplaceQueryDialog(cm)) + dialog(cm, fragment, dialogText, query, function(query) { if (!query) return; query = parseQuery(query); - dialog(cm, replacementQueryDialog, "Replace with:", "", function(text) { + dialog(cm, getReplacementQueryDialog(cm), cm.phrase("Replace with:"), "", function(text) { + text = parseString(text) if (all) { - cm.operation(function() { - for (var cursor = getSearchCursor(cm, query); cursor.findNext();) { - if (typeof query != "string") { - var match = cm.getRange(cursor.from(), cursor.to()).match(query); - cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];})); - } else cursor.replace(text); - } - }); + replaceAll(cm, query, text) } else { clearSearch(cm); - var cursor = getSearchCursor(cm, query, cm.getCursor()); + var cursor = getSearchCursor(cm, query, cm.getCursor("from")); var advance = function() { var start = cursor.from(), match; if (!(match = cursor.findNext())) { @@ -141,8 +265,9 @@ } cm.setSelection(cursor.from(), cursor.to()); cm.scrollIntoView({from: cursor.from(), to: cursor.to()}); - confirmDialog(cm, doReplaceConfirm, "Replace?", - [function() {doReplace(match);}, advance]); + confirmDialog(cm, getDoReplaceConfirm(cm), cm.phrase("Replace?"), + [function() {doReplace(match);}, advance, + function() {replaceAll(cm, query, text)}]); }; var doReplace = function(match) { cursor.replace(typeof query == "string" ? text : @@ -156,6 +281,9 @@ } CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);}; + CodeMirror.commands.findPersistent = function(cm) {clearSearch(cm); doSearch(cm, false, true);}; + CodeMirror.commands.findPersistentNext = function(cm) {doSearch(cm, false, true, true);}; + CodeMirror.commands.findPersistentPrev = function(cm) {doSearch(cm, true, true, true);}; CodeMirror.commands.findNext = doSearch; CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);}; CodeMirror.commands.clearSearch = clearSearch; diff --git a/static/editor.md/lib/codemirror/addon/search/searchcursor.js b/static/editor.md/lib/codemirror/addon/search/searchcursor.js index 55c108b5..230017b7 100644 --- a/static/editor.md/lib/codemirror/addon/search/searchcursor.js +++ b/static/editor.md/lib/codemirror/addon/search/searchcursor.js @@ -1,189 +1,305 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); + mod(require("../../lib/codemirror")) else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); + define(["../../lib/codemirror"], mod) else // Plain browser env - mod(CodeMirror); + mod(CodeMirror) })(function(CodeMirror) { - "use strict"; - var Pos = CodeMirror.Pos; + "use strict" + var Pos = CodeMirror.Pos - function SearchCursor(doc, query, pos, caseFold) { - this.atOccurrence = false; this.doc = doc; - if (caseFold == null && typeof query == "string") caseFold = false; + function regexpFlags(regexp) { + var flags = regexp.flags + return flags != null ? flags : (regexp.ignoreCase ? "i" : "") + + (regexp.global ? "g" : "") + + (regexp.multiline ? "m" : "") + } - pos = pos ? doc.clipPos(pos) : Pos(0, 0); - this.pos = {from: pos, to: pos}; + function ensureFlags(regexp, flags) { + var current = regexpFlags(regexp), target = current + for (var i = 0; i < flags.length; i++) if (target.indexOf(flags.charAt(i)) == -1) + target += flags.charAt(i) + return current == target ? regexp : new RegExp(regexp.source, target) + } - // The matches method is filled in based on the type of query. - // It takes a position and a direction, and returns an object - // describing the next occurrence of the query, or null if no - // more matches were found. - if (typeof query != "string") { // Regexp match - if (!query.global) query = new RegExp(query.source, query.ignoreCase ? "ig" : "g"); - this.matches = function(reverse, pos) { - if (reverse) { - query.lastIndex = 0; - var line = doc.getLine(pos.line).slice(0, pos.ch), cutOff = 0, match, start; - for (;;) { - query.lastIndex = cutOff; - var newMatch = query.exec(line); - if (!newMatch) break; - match = newMatch; - start = match.index; - cutOff = match.index + (match[0].length || 1); - if (cutOff == line.length) break; - } - var matchLen = (match && match[0].length) || 0; - if (!matchLen) { - if (start == 0 && line.length == 0) {match = undefined;} - else if (start != doc.getLine(pos.line).length) { - matchLen++; - } - } - } else { - query.lastIndex = pos.ch; - var line = doc.getLine(pos.line), match = query.exec(line); - var matchLen = (match && match[0].length) || 0; - var start = match && match.index; - if (start + matchLen != line.length && !matchLen) matchLen = 1; - } - if (match && matchLen) - return {from: Pos(pos.line, start), - to: Pos(pos.line, start + matchLen), - match: match}; - }; - } else { // String query - var origQuery = query; - if (caseFold) query = query.toLowerCase(); - var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;}; - var target = query.split("\n"); - // Different methods for single-line and multi-line queries - if (target.length == 1) { - if (!query.length) { - // Empty string would match anything and never progress, so - // we define it to match nothing instead. - this.matches = function() {}; - } else { - this.matches = function(reverse, pos) { - if (reverse) { - var orig = doc.getLine(pos.line).slice(0, pos.ch), line = fold(orig); - var match = line.lastIndexOf(query); - if (match > -1) { - match = adjustPos(orig, line, match); - return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)}; - } - } else { - var orig = doc.getLine(pos.line).slice(pos.ch), line = fold(orig); - var match = line.indexOf(query); - if (match > -1) { - match = adjustPos(orig, line, match) + pos.ch; - return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)}; - } - } - }; - } - } else { - var origTarget = origQuery.split("\n"); - this.matches = function(reverse, pos) { - var last = target.length - 1; - if (reverse) { - if (pos.line - (target.length - 1) < doc.firstLine()) return; - if (fold(doc.getLine(pos.line).slice(0, origTarget[last].length)) != target[target.length - 1]) return; - var to = Pos(pos.line, origTarget[last].length); - for (var ln = pos.line - 1, i = last - 1; i >= 1; --i, --ln) - if (target[i] != fold(doc.getLine(ln))) return; - var line = doc.getLine(ln), cut = line.length - origTarget[0].length; - if (fold(line.slice(cut)) != target[0]) return; - return {from: Pos(ln, cut), to: to}; - } else { - if (pos.line + (target.length - 1) > doc.lastLine()) return; - var line = doc.getLine(pos.line), cut = line.length - origTarget[0].length; - if (fold(line.slice(cut)) != target[0]) return; - var from = Pos(pos.line, cut); - for (var ln = pos.line + 1, i = 1; i < last; ++i, ++ln) - if (target[i] != fold(doc.getLine(ln))) return; - if (fold(doc.getLine(ln).slice(0, origTarget[last].length)) != target[last]) return; - return {from: from, to: Pos(ln, origTarget[last].length)}; - } - }; + function maybeMultiline(regexp) { + return /\\s|\\n|\n|\\W|\\D|\[\^/.test(regexp.source) + } + + function searchRegexpForward(doc, regexp, start) { + regexp = ensureFlags(regexp, "g") + for (var line = start.line, ch = start.ch, last = doc.lastLine(); line <= last; line++, ch = 0) { + regexp.lastIndex = ch + var string = doc.getLine(line), match = regexp.exec(string) + if (match) + return {from: Pos(line, match.index), + to: Pos(line, match.index + match[0].length), + match: match} + } + } + + function searchRegexpForwardMultiline(doc, regexp, start) { + if (!maybeMultiline(regexp)) return searchRegexpForward(doc, regexp, start) + + regexp = ensureFlags(regexp, "gm") + var string, chunk = 1 + for (var line = start.line, last = doc.lastLine(); line <= last;) { + // This grows the search buffer in exponentially-sized chunks + // between matches, so that nearby matches are fast and don't + // require concatenating the whole document (in case we're + // searching for something that has tons of matches), but at the + // same time, the amount of retries is limited. + for (var i = 0; i < chunk; i++) { + if (line > last) break + var curLine = doc.getLine(line++) + string = string == null ? curLine : string + "\n" + curLine } + chunk = chunk * 2 + regexp.lastIndex = start.ch + var match = regexp.exec(string) + if (match) { + var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n") + var startLine = start.line + before.length - 1, startCh = before[before.length - 1].length + return {from: Pos(startLine, startCh), + to: Pos(startLine + inside.length - 1, + inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length), + match: match} + } + } + } + + function lastMatchIn(string, regexp, endMargin) { + var match, from = 0 + while (from <= string.length) { + regexp.lastIndex = from + var newMatch = regexp.exec(string) + if (!newMatch) break + var end = newMatch.index + newMatch[0].length + if (end > string.length - endMargin) break + if (!match || end > match.index + match[0].length) + match = newMatch + from = newMatch.index + 1 + } + return match + } + + function searchRegexpBackward(doc, regexp, start) { + regexp = ensureFlags(regexp, "g") + for (var line = start.line, ch = start.ch, first = doc.firstLine(); line >= first; line--, ch = -1) { + var string = doc.getLine(line) + var match = lastMatchIn(string, regexp, ch < 0 ? 0 : string.length - ch) + if (match) + return {from: Pos(line, match.index), + to: Pos(line, match.index + match[0].length), + match: match} + } + } + + function searchRegexpBackwardMultiline(doc, regexp, start) { + if (!maybeMultiline(regexp)) return searchRegexpBackward(doc, regexp, start) + regexp = ensureFlags(regexp, "gm") + var string, chunkSize = 1, endMargin = doc.getLine(start.line).length - start.ch + for (var line = start.line, first = doc.firstLine(); line >= first;) { + for (var i = 0; i < chunkSize && line >= first; i++) { + var curLine = doc.getLine(line--) + string = string == null ? curLine : curLine + "\n" + string + } + chunkSize *= 2 + + var match = lastMatchIn(string, regexp, endMargin) + if (match) { + var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n") + var startLine = line + before.length, startCh = before[before.length - 1].length + return {from: Pos(startLine, startCh), + to: Pos(startLine + inside.length - 1, + inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length), + match: match} + } + } + } + + var doFold, noFold + if (String.prototype.normalize) { + doFold = function(str) { return str.normalize("NFD").toLowerCase() } + noFold = function(str) { return str.normalize("NFD") } + } else { + doFold = function(str) { return str.toLowerCase() } + noFold = function(str) { return str } + } + + // Maps a position in a case-folded line back to a position in the original line + // (compensating for codepoints increasing in number during folding) + function adjustPos(orig, folded, pos, foldFunc) { + if (orig.length == folded.length) return pos + for (var min = 0, max = pos + Math.max(0, orig.length - folded.length);;) { + if (min == max) return min + var mid = (min + max) >> 1 + var len = foldFunc(orig.slice(0, mid)).length + if (len == pos) return mid + else if (len > pos) max = mid + else min = mid + 1 + } + } + + function searchStringForward(doc, query, start, caseFold) { + // Empty string would match anything and never progress, so we + // define it to match nothing instead. + if (!query.length) return null + var fold = caseFold ? doFold : noFold + var lines = fold(query).split(/\r|\n\r?/) + + search: for (var line = start.line, ch = start.ch, last = doc.lastLine() + 1 - lines.length; line <= last; line++, ch = 0) { + var orig = doc.getLine(line).slice(ch), string = fold(orig) + if (lines.length == 1) { + var found = string.indexOf(lines[0]) + if (found == -1) continue search + var start = adjustPos(orig, string, found, fold) + ch + return {from: Pos(line, adjustPos(orig, string, found, fold) + ch), + to: Pos(line, adjustPos(orig, string, found + lines[0].length, fold) + ch)} + } else { + var cutFrom = string.length - lines[0].length + if (string.slice(cutFrom) != lines[0]) continue search + for (var i = 1; i < lines.length - 1; i++) + if (fold(doc.getLine(line + i)) != lines[i]) continue search + var end = doc.getLine(line + lines.length - 1), endString = fold(end), lastLine = lines[lines.length - 1] + if (endString.slice(0, lastLine.length) != lastLine) continue search + return {from: Pos(line, adjustPos(orig, string, cutFrom, fold) + ch), + to: Pos(line + lines.length - 1, adjustPos(end, endString, lastLine.length, fold))} + } + } + } + + function searchStringBackward(doc, query, start, caseFold) { + if (!query.length) return null + var fold = caseFold ? doFold : noFold + var lines = fold(query).split(/\r|\n\r?/) + + search: for (var line = start.line, ch = start.ch, first = doc.firstLine() - 1 + lines.length; line >= first; line--, ch = -1) { + var orig = doc.getLine(line) + if (ch > -1) orig = orig.slice(0, ch) + var string = fold(orig) + if (lines.length == 1) { + var found = string.lastIndexOf(lines[0]) + if (found == -1) continue search + return {from: Pos(line, adjustPos(orig, string, found, fold)), + to: Pos(line, adjustPos(orig, string, found + lines[0].length, fold))} + } else { + var lastLine = lines[lines.length - 1] + if (string.slice(0, lastLine.length) != lastLine) continue search + for (var i = 1, start = line - lines.length + 1; i < lines.length - 1; i++) + if (fold(doc.getLine(start + i)) != lines[i]) continue search + var top = doc.getLine(line + 1 - lines.length), topString = fold(top) + if (topString.slice(topString.length - lines[0].length) != lines[0]) continue search + return {from: Pos(line + 1 - lines.length, adjustPos(top, topString, top.length - lines[0].length, fold)), + to: Pos(line, adjustPos(orig, string, lastLine.length, fold))} + } + } + } + + function SearchCursor(doc, query, pos, options) { + this.atOccurrence = false + this.afterEmptyMatch = false + this.doc = doc + pos = pos ? doc.clipPos(pos) : Pos(0, 0) + this.pos = {from: pos, to: pos} + + var caseFold + if (typeof options == "object") { + caseFold = options.caseFold + } else { // Backwards compat for when caseFold was the 4th argument + caseFold = options + options = null + } + + if (typeof query == "string") { + if (caseFold == null) caseFold = false + this.matches = function(reverse, pos) { + return (reverse ? searchStringBackward : searchStringForward)(doc, query, pos, caseFold) + } + } else { + query = ensureFlags(query, "gm") + if (!options || options.multiline !== false) + this.matches = function(reverse, pos) { + return (reverse ? searchRegexpBackwardMultiline : searchRegexpForwardMultiline)(doc, query, pos) + } + else + this.matches = function(reverse, pos) { + return (reverse ? searchRegexpBackward : searchRegexpForward)(doc, query, pos) + } } } SearchCursor.prototype = { - findNext: function() {return this.find(false);}, - findPrevious: function() {return this.find(true);}, + findNext: function() {return this.find(false)}, + findPrevious: function() {return this.find(true)}, find: function(reverse) { - var self = this, pos = this.doc.clipPos(reverse ? this.pos.from : this.pos.to); - function savePosAndFail(line) { - var pos = Pos(line, 0); - self.pos = {from: pos, to: pos}; - self.atOccurrence = false; - return false; - } - - for (;;) { - if (this.pos = this.matches(reverse, pos)) { - this.atOccurrence = true; - return this.pos.match || true; - } + var head = this.doc.clipPos(reverse ? this.pos.from : this.pos.to); + if (this.afterEmptyMatch && this.atOccurrence) { + // do not return the same 0 width match twice + head = Pos(head.line, head.ch) if (reverse) { - if (!pos.line) return savePosAndFail(0); - pos = Pos(pos.line-1, this.doc.getLine(pos.line-1).length); + head.ch--; + if (head.ch < 0) { + head.line--; + head.ch = (this.doc.getLine(head.line) || "").length; + } + } else { + head.ch++; + if (head.ch > (this.doc.getLine(head.line) || "").length) { + head.ch = 0; + head.line++; + } } - else { - var maxLine = this.doc.lineCount(); - if (pos.line == maxLine - 1) return savePosAndFail(maxLine); - pos = Pos(pos.line + 1, 0); + if (CodeMirror.cmpPos(head, this.doc.clipPos(head)) != 0) { + return this.atOccurrence = false } } + var result = this.matches(reverse, head) + this.afterEmptyMatch = result && CodeMirror.cmpPos(result.from, result.to) == 0 + + if (result) { + this.pos = result + this.atOccurrence = true + return this.pos.match || true + } else { + var end = Pos(reverse ? this.doc.firstLine() : this.doc.lastLine() + 1, 0) + this.pos = {from: end, to: end} + return this.atOccurrence = false + } }, - from: function() {if (this.atOccurrence) return this.pos.from;}, - to: function() {if (this.atOccurrence) return this.pos.to;}, + from: function() {if (this.atOccurrence) return this.pos.from}, + to: function() {if (this.atOccurrence) return this.pos.to}, - replace: function(newText) { - if (!this.atOccurrence) return; - var lines = CodeMirror.splitLines(newText); - this.doc.replaceRange(lines, this.pos.from, this.pos.to); + replace: function(newText, origin) { + if (!this.atOccurrence) return + var lines = CodeMirror.splitLines(newText) + this.doc.replaceRange(lines, this.pos.from, this.pos.to, origin) this.pos.to = Pos(this.pos.from.line + lines.length - 1, - lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0)); - } - }; - - // Maps a position in a case-folded line back to a position in the original line - // (compensating for codepoints increasing in number during folding) - function adjustPos(orig, folded, pos) { - if (orig.length == folded.length) return pos; - for (var pos1 = Math.min(pos, orig.length);;) { - var len1 = orig.slice(0, pos1).toLowerCase().length; - if (len1 < pos) ++pos1; - else if (len1 > pos) --pos1; - else return pos1; + lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0)) } } CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) { - return new SearchCursor(this.doc, query, pos, caseFold); - }); + return new SearchCursor(this.doc, query, pos, caseFold) + }) CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) { - return new SearchCursor(this, query, pos, caseFold); - }); + return new SearchCursor(this, query, pos, caseFold) + }) CodeMirror.defineExtension("selectMatches", function(query, caseFold) { - var ranges = [], next; - var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold); - while (next = cur.findNext()) { - if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break; - ranges.push({anchor: cur.from(), head: cur.to()}); + var ranges = [] + var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold) + while (cur.findNext()) { + if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break + ranges.push({anchor: cur.from(), head: cur.to()}) } if (ranges.length) - this.setSelections(ranges, 0); - }); + this.setSelections(ranges, 0) + }) }); diff --git a/static/editor.md/lib/codemirror/addon/selection/active-line.js b/static/editor.md/lib/codemirror/addon/selection/active-line.js index 22da2e0a..c7b14ce0 100644 --- a/static/editor.md/lib/codemirror/addon/selection/active-line.js +++ b/static/editor.md/lib/codemirror/addon/selection/active-line.js @@ -1,11 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// Because sometimes you need to style the cursor's line. -// -// Adds an option 'styleActiveLine' which, when enabled, gives the -// active line's wrapping
                              the CSS class "CodeMirror-activeline", -// and gives its background
                              the class "CodeMirror-activeline-background". +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -18,24 +12,28 @@ "use strict"; var WRAP_CLASS = "CodeMirror-activeline"; var BACK_CLASS = "CodeMirror-activeline-background"; + var GUTT_CLASS = "CodeMirror-activeline-gutter"; CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) { - var prev = old && old != CodeMirror.Init; - if (val && !prev) { - cm.state.activeLines = []; - updateActiveLines(cm, cm.listSelections()); - cm.on("beforeSelectionChange", selectionChange); - } else if (!val && prev) { + var prev = old == CodeMirror.Init ? false : old; + if (val == prev) return + if (prev) { cm.off("beforeSelectionChange", selectionChange); clearActiveLines(cm); delete cm.state.activeLines; } + if (val) { + cm.state.activeLines = []; + updateActiveLines(cm, cm.listSelections()); + cm.on("beforeSelectionChange", selectionChange); + } }); function clearActiveLines(cm) { for (var i = 0; i < cm.state.activeLines.length; i++) { cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS); cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS); + cm.removeLineClass(cm.state.activeLines[i], "gutter", GUTT_CLASS); } } @@ -50,7 +48,9 @@ var active = []; for (var i = 0; i < ranges.length; i++) { var range = ranges[i]; - if (!range.empty()) continue; + var option = cm.getOption("styleActiveLine"); + if (typeof option == "object" && option.nonEmpty ? range.anchor.line != range.head.line : !range.empty()) + continue var line = cm.getLineHandleVisualStart(range.head.line); if (active[active.length - 1] != line) active.push(line); } @@ -60,6 +60,7 @@ for (var i = 0; i < active.length; i++) { cm.addLineClass(active[i], "wrap", WRAP_CLASS); cm.addLineClass(active[i], "background", BACK_CLASS); + cm.addLineClass(active[i], "gutter", GUTT_CLASS); } cm.state.activeLines = active; }); diff --git a/static/editor.md/lib/codemirror/addon/selection/mark-selection.js b/static/editor.md/lib/codemirror/addon/selection/mark-selection.js index 5c42d21e..adfaa62d 100644 --- a/static/editor.md/lib/codemirror/addon/selection/mark-selection.js +++ b/static/editor.md/lib/codemirror/addon/selection/mark-selection.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE // Because sometimes you need to mark the selected *text*. // @@ -34,11 +34,12 @@ }); function onCursorActivity(cm) { - cm.operation(function() { update(cm); }); + if (cm.state.markedSelection) + cm.operation(function() { update(cm); }); } function onChange(cm) { - if (cm.state.markedSelection.length) + if (cm.state.markedSelection && cm.state.markedSelection.length) cm.operation(function() { clear(cm); }); } @@ -85,7 +86,7 @@ if (!array.length) return coverRange(cm, from, to); var coverStart = array[0].find(), coverEnd = array[array.length - 1].find(); - if (!coverStart || !coverEnd || to.line - from.line < CHUNK_SIZE || + if (!coverStart || !coverEnd || to.line - from.line <= CHUNK_SIZE || cmp(from, coverEnd.to) >= 0 || cmp(to, coverStart.from) <= 0) return reset(cm); diff --git a/static/editor.md/lib/codemirror/addon/selection/selection-pointer.js b/static/editor.md/lib/codemirror/addon/selection/selection-pointer.js index ef5e404a..f0bd61a3 100644 --- a/static/editor.md/lib/codemirror/addon/selection/selection-pointer.js +++ b/static/editor.md/lib/codemirror/addon/selection/selection-pointer.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS diff --git a/static/editor.md/lib/codemirror/addon/tern/tern.css b/static/editor.md/lib/codemirror/addon/tern/tern.css index 76fba33d..c4b8a2f7 100644 --- a/static/editor.md/lib/codemirror/addon/tern/tern.css +++ b/static/editor.md/lib/codemirror/addon/tern/tern.css @@ -1,6 +1,7 @@ .CodeMirror-Tern-completion { padding-left: 22px; position: relative; + line-height: 1.5; } .CodeMirror-Tern-completion:before { position: absolute; diff --git a/static/editor.md/lib/codemirror/addon/tern/tern.js b/static/editor.md/lib/codemirror/addon/tern/tern.js index b049549d..a8837174 100644 --- a/static/editor.md/lib/codemirror/addon/tern/tern.js +++ b/static/editor.md/lib/codemirror/addon/tern/tern.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE // Glue code between CodeMirror and Tern. // @@ -59,6 +59,7 @@ this.options = options || {}; var plugins = this.options.plugins || (this.options.plugins = {}); if (!plugins.doc_comment) plugins.doc_comment = true; + this.docs = Object.create(null); if (this.options.useWorker) { this.server = new WorkerServer(this); } else { @@ -69,7 +70,6 @@ plugins: plugins }); } - this.docs = Object.create(null); this.trackChange = function(doc, change) { trackChange(self, doc, change); }; this.cachedArgHints = null; @@ -124,6 +124,8 @@ var self = this; var doc = findDoc(this, cm.getDoc()); var request = buildRequest(this, doc, query, pos); + var extraOptions = request.query && this.options.queryOptions && this.options.queryOptions[request.query.type] + if (extraOptions) for (var prop in extraOptions) request.query[prop] = extraOptions[prop]; this.server.request(request, function (error, data) { if (!error && self.options.responseFilter) @@ -133,6 +135,7 @@ }, destroy: function () { + closeArgHints(this) if (this.worker) { this.worker.terminate(); this.worker = null; @@ -176,7 +179,7 @@ var data = findDoc(ts, doc); var argHints = ts.cachedArgHints; - if (argHints && argHints.doc == doc && cmpPos(argHints.start, change.to) <= 0) + if (argHints && argHints.doc == doc && cmpPos(argHints.start, change.to) >= 0) ts.cachedArgHints = null; var changed = data.changed; @@ -214,7 +217,7 @@ var completion = data.completions[i], className = typeToIcon(completion.type); if (data.guess) className += " " + cls + "guess"; completions.push({text: completion.name + after, - displayText: completion.name, + displayText: completion.displayName || completion.name, className: className, data: completion}); } @@ -228,8 +231,7 @@ var content = ts.options.completionTip ? ts.options.completionTip(cur.data) : cur.data.doc; if (content) { tooltip = makeTooltip(node.parentNode.getBoundingClientRect().right + window.pageXOffset, - node.getBoundingClientRect().top + window.pageYOffset, content); - tooltip.className += " " + cls + "hint-doc"; + node.getBoundingClientRect().top + window.pageYOffset, content, cm, cls + "hint-doc"); } }); c(obj); @@ -264,7 +266,7 @@ child.target = "_blank"; } } - tempTooltip(cm, tip); + tempTooltip(cm, tip, ts); if (c) c(); }, pos); } @@ -303,7 +305,7 @@ ts.request(cm, {type: "type", preferFunction: true, end: start}, function(error, data) { if (error || !data.type || !(/^fn\(/).test(data.type)) return; ts.cachedArgHints = { - start: pos, + start: start, type: parseFnType(data.type), name: data.exprName || data.name || "fn", guess: data.guess, @@ -331,7 +333,11 @@ tip.appendChild(document.createTextNode(tp.rettype ? ") ->\u00a0" : ")")); if (tp.rettype) tip.appendChild(elt("span", cls + "type", tp.rettype)); var place = cm.cursorCoords(null, "page"); - ts.activeArgHints = makeTooltip(place.right + 1, place.bottom, tip); + var tooltip = ts.activeArgHints = makeTooltip(place.right + 1, place.bottom, tip, cm) + setTimeout(function() { + tooltip.clear = onEditorActivity(cm, function() { + if (ts.activeArgHints == tooltip) closeArgHints(ts) }) + }, 20) } function parseFnType(text) { @@ -442,8 +448,8 @@ function atInterestingExpression(cm) { var pos = cm.getCursor("end"), tok = cm.getTokenAt(pos); - if (tok.start < pos.ch && (tok.type == "comment" || tok.type == "string")) return false; - return /\w/.test(cm.getLine(pos.line).slice(Math.max(pos.ch - 1, 0), pos.ch + 1)); + if (tok.start < pos.ch && tok.type == "comment") return false; + return /[\w)\]]/.test(cm.getLine(pos.line).slice(Math.max(pos.ch - 1, 0), pos.ch + 1)); } // Variable renaming @@ -464,11 +470,12 @@ ts.request(cm, {type: "refs"}, function(error, data) { if (error) return showError(ts, cm, error); var ranges = [], cur = 0; + var curPos = cm.getCursor(); for (var i = 0; i < data.refs.length; i++) { var ref = data.refs[i]; if (ref.file == name) { ranges.push({anchor: ref.start, head: ref.end}); - if (cmpPos(cur, ref.start) >= 0 && cmpPos(cur, ref.end) <= 0) + if (cmpPos(curPos, ref.start) >= 0 && cmpPos(curPos, ref.end) <= 0) cur = ranges.length - 1; } } @@ -563,7 +570,7 @@ return {type: "part", name: data.name, offsetLines: from.line, - text: doc.getRange(from, Pos(endLine, 0))}; + text: doc.getRange(from, Pos(endLine, end.line == endLine ? null : 0))}; } // Generic utilities @@ -590,41 +597,83 @@ // Tooltips - function tempTooltip(cm, content) { + function tempTooltip(cm, content, ts) { if (cm.state.ternTooltip) remove(cm.state.ternTooltip); var where = cm.cursorCoords(); - var tip = cm.state.ternTooltip = makeTooltip(where.right + 1, where.bottom, content); + var tip = cm.state.ternTooltip = makeTooltip(where.right + 1, where.bottom, content, cm); function maybeClear() { old = true; if (!mouseOnTip) clear(); } function clear() { cm.state.ternTooltip = null; - if (!tip.parentNode) return; - cm.off("cursorActivity", clear); - cm.off('blur', clear); - cm.off('scroll', clear); - fadeOut(tip); + if (tip.parentNode) fadeOut(tip) + clearActivity() } var mouseOnTip = false, old = false; CodeMirror.on(tip, "mousemove", function() { mouseOnTip = true; }); CodeMirror.on(tip, "mouseout", function(e) { - if (!CodeMirror.contains(tip, e.relatedTarget || e.toElement)) { + var related = e.relatedTarget || e.toElement + if (!related || !CodeMirror.contains(tip, related)) { if (old) clear(); else mouseOnTip = false; } }); - setTimeout(maybeClear, 1700); - cm.on("cursorActivity", clear); - cm.on('blur', clear); - cm.on('scroll', clear); + setTimeout(maybeClear, ts.options.hintDelay ? ts.options.hintDelay : 1700); + var clearActivity = onEditorActivity(cm, clear) } - function makeTooltip(x, y, content) { - var node = elt("div", cls + "tooltip", content); + function onEditorActivity(cm, f) { + cm.on("cursorActivity", f) + cm.on("blur", f) + cm.on("scroll", f) + cm.on("setDoc", f) + return function() { + cm.off("cursorActivity", f) + cm.off("blur", f) + cm.off("scroll", f) + cm.off("setDoc", f) + } + } + + function makeTooltip(x, y, content, cm, className) { + var node = elt("div", cls + "tooltip" + " " + (className || ""), content); node.style.left = x + "px"; node.style.top = y + "px"; - document.body.appendChild(node); + var container = ((cm.options || {}).hintOptions || {}).container || document.body; + container.appendChild(node); + + var pos = cm.cursorCoords(); + var winW = window.innerWidth; + var winH = window.innerHeight; + var box = node.getBoundingClientRect(); + var hints = document.querySelector(".CodeMirror-hints"); + var overlapY = box.bottom - winH; + var overlapX = box.right - winW; + + if (hints && overlapX > 0) { + node.style.left = 0; + var box = node.getBoundingClientRect(); + node.style.left = (x = x - hints.offsetWidth - box.width) + "px"; + overlapX = box.right - winW; + } + if (overlapY > 0) { + var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top); + if (curTop - height > 0) { // Fits above cursor + node.style.top = (pos.top - height) + "px"; + } else if (height > winH) { + node.style.height = (winH - 5) + "px"; + node.style.top = (pos.bottom - box.top) + "px"; + } + } + if (overlapX > 0) { + if (box.right - box.left > winW) { + node.style.width = (winW - 5) + "px"; + overlapX -= (box.right - box.left) - winW; + } + node.style.left = (x - overlapX) + "px"; + } + return node; } @@ -642,11 +691,15 @@ if (ts.options.showError) ts.options.showError(cm, msg); else - tempTooltip(cm, String(msg)); + tempTooltip(cm, String(msg), ts); } function closeArgHints(ts) { - if (ts.activeArgHints) { remove(ts.activeArgHints); ts.activeArgHints = null; } + if (ts.activeArgHints) { + if (ts.activeArgHints.clear) ts.activeArgHints.clear() + remove(ts.activeArgHints) + ts.activeArgHints = null + } } function docValue(ts, doc) { diff --git a/static/editor.md/lib/codemirror/addon/tern/worker.js b/static/editor.md/lib/codemirror/addon/tern/worker.js index 48277af8..e134ad47 100644 --- a/static/editor.md/lib/codemirror/addon/tern/worker.js +++ b/static/editor.md/lib/codemirror/addon/tern/worker.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE // declare global: tern, server @@ -39,6 +39,6 @@ function startServer(defs, plugins, scripts) { }); } -var console = { +this.console = { log: function(v) { postMessage({type: "debug", message: v}); } }; diff --git a/static/editor.md/lib/codemirror/addon/wrap/hardwrap.js b/static/editor.md/lib/codemirror/addon/wrap/hardwrap.js index fe9b4dd6..516368c8 100644 --- a/static/editor.md/lib/codemirror/addon/wrap/hardwrap.js +++ b/static/editor.md/lib/codemirror/addon/wrap/hardwrap.js @@ -1,5 +1,5 @@ // CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE +// Distributed under an MIT license: https://codemirror.net/LICENSE (function(mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS @@ -29,25 +29,40 @@ return {from: start, to: end}; } - function findBreakPoint(text, column, wrapOn, killTrailingSpace) { - for (var at = column; at > 0; --at) + function findBreakPoint(text, column, wrapOn, killTrailingSpace, forceBreak) { + var at = column + while (at < text.length && text.charAt(at) == " ") at++ + for (; at > 0; --at) if (wrapOn.test(text.slice(at - 1, at + 1))) break; - if (at == 0) at = column; - var endOfText = at; - if (killTrailingSpace) - while (text.charAt(endOfText - 1) == " ") --endOfText; - return {from: endOfText, to: at}; + + if (!forceBreak && at <= text.match(/^[ \t]*/)[0].length) { + // didn't find a break point before column, in non-forceBreak mode try to + // find one after 'column'. + for (at = column + 1; at < text.length - 1; ++at) { + if (wrapOn.test(text.slice(at - 1, at + 1))) break; + } + } + + for (var first = true;; first = false) { + var endOfText = at; + if (killTrailingSpace) + while (text.charAt(endOfText - 1) == " ") --endOfText; + if (endOfText == 0 && first) at = column; + else return {from: endOfText, to: at}; + } } function wrapRange(cm, from, to, options) { from = cm.clipPos(from); to = cm.clipPos(to); var column = options.column || 80; var wrapOn = options.wrapOn || /\s\S|-[^\.\d]/; + var forceBreak = options.forceBreak !== false; var killTrailing = options.killTrailingSpace !== false; var changes = [], curLine = "", curNo = from.line; var lines = cm.getRange(from, to, false); if (!lines.length) return null; var leadingSpace = lines[0].match(/^[ \t]*/)[0]; + if (leadingSpace.length >= column) column = leadingSpace.length + 1 for (var i = 0; i < lines.length; ++i) { var text = lines[i], oldLen = curLine.length, spaceInserted = 0; @@ -63,7 +78,7 @@ curLine += text; if (i) { var firstBreak = curLine.length > column && leadingSpace == spaceTrimmed && - findBreakPoint(curLine, column, wrapOn, killTrailing); + findBreakPoint(curLine, column, wrapOn, killTrailing, forceBreak); // If this isn't broken, or is broken at a different point, remove old break if (!firstBreak || firstBreak.from != oldLen || firstBreak.to != oldLen + spaceInserted) { changes.push({text: [spaceInserted ? " " : ""], @@ -75,18 +90,24 @@ } } while (curLine.length > column) { - var bp = findBreakPoint(curLine, column, wrapOn, killTrailing); - changes.push({text: ["", leadingSpace], - from: Pos(curNo, bp.from), - to: Pos(curNo, bp.to)}); - curLine = leadingSpace + curLine.slice(bp.to); - ++curNo; + var bp = findBreakPoint(curLine, column, wrapOn, killTrailing, forceBreak); + if (bp.from != bp.to || + forceBreak && leadingSpace !== curLine.slice(0, bp.to)) { + changes.push({text: ["", leadingSpace], + from: Pos(curNo, bp.from), + to: Pos(curNo, bp.to)}); + curLine = leadingSpace + curLine.slice(bp.to); + ++curNo; + } else { + break; + } } } if (changes.length) cm.operation(function() { for (var i = 0; i < changes.length; ++i) { var change = changes[i]; - cm.replaceRange(change.text, change.from, change.to); + if (change.text || CodeMirror.cmpPos(change.from, change.to)) + cm.replaceRange(change.text, change.from, change.to); } }); return changes.length ? {from: changes[0].from, to: CodeMirror.changeEnd(changes[changes.length - 1])} : null; diff --git a/static/editor.md/lib/codemirror/addons.min.js b/static/editor.md/lib/codemirror/addons.min.js index a0980800..d4ffe4f5 100644 --- a/static/editor.md/lib/codemirror/addons.min.js +++ b/static/editor.md/lib/codemirror/addons.min.js @@ -1,4 +1,2 @@ -/*! Editor.md v1.5.0 | addons.min.js | Open source online markdown editor. | MIT License | By: Pandao | https://github.com/pandao/editor.md | 2015-06-09 */ -!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){e.defineOption("showTrailingSpace",!1,function(t,i,o){o==e.Init&&(o=!1),o&&!i?t.removeOverlay("trailingspace"):!o&&i&&t.addOverlay({token:function(e){for(var t=e.string.length,i=t;i&&/\s/.test(e.string.charAt(i-1));--i);return i>e.pos?(e.pos=i,null):(e.pos=t,"trailingspace")},name:"trailingspace"})})}),function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){function t(e,t,i){var o,r=e.getWrapperElement();return o=r.appendChild(document.createElement("div")),i?o.className="CodeMirror-dialog CodeMirror-dialog-bottom":o.className="CodeMirror-dialog CodeMirror-dialog-top","string"==typeof t?o.innerHTML=t:o.appendChild(t),o}function i(e,t){e.state.currentNotificationClose&&e.state.currentNotificationClose(),e.state.currentNotificationClose=t}e.defineExtension("openDialog",function(o,r,n){function a(e){if("string"==typeof e)h.value=e;else{if(c)return;c=!0,l.parentNode.removeChild(l),d.focus(),n.onClose&&n.onClose(l)}}n||(n={}),i(this,null);var s,l=t(this,o,n.bottom),c=!1,d=this,h=l.getElementsByTagName("input")[0];return h?(n.value&&(h.value=n.value,h.select()),n.onInput&&e.on(h,"input",function(e){n.onInput(e,h.value,a)}),n.onKeyUp&&e.on(h,"keyup",function(e){n.onKeyUp(e,h.value,a)}),e.on(h,"keydown",function(t){n&&n.onKeyDown&&n.onKeyDown(t,h.value,a)||((27==t.keyCode||n.closeOnEnter!==!1&&13==t.keyCode)&&(h.blur(),e.e_stop(t),a()),13==t.keyCode&&r(h.value,t))}),n.closeOnBlur!==!1&&e.on(h,"blur",a),h.focus()):(s=l.getElementsByTagName("button")[0])&&(e.on(s,"click",function(){a(),d.focus()}),n.closeOnBlur!==!1&&e.on(s,"blur",a),s.focus()),a}),e.defineExtension("openConfirm",function(o,r,n){function a(){c||(c=!0,s.parentNode.removeChild(s),d.focus())}i(this,null);var s=t(this,o,n&&n.bottom),l=s.getElementsByTagName("button"),c=!1,d=this,h=1;l[0].focus();for(var u=0;u=h&&a()},200)}),e.on(f,"focus",function(){++h})}}),e.defineExtension("openNotification",function(o,r){function n(){l||(l=!0,clearTimeout(a),s.parentNode.removeChild(s))}i(this,n);var a,s=t(this,o,r&&r.bottom),l=!1,c=r&&"undefined"!=typeof r.duration?r.duration:5e3;return e.on(s,"click",function(t){e.e_preventDefault(t),n()}),c&&(a=setTimeout(n,c)),n})}),function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict";function t(e,t,r,n){if(this.atOccurrence=!1,this.doc=e,null==n&&"string"==typeof t&&(n=!1),r=r?e.clipPos(r):o(0,0),this.pos={from:r,to:r},"string"!=typeof t)t.global||(t=new RegExp(t.source,t.ignoreCase?"ig":"g")),this.matches=function(i,r){if(i){t.lastIndex=0;for(var n,a,s=e.getLine(r.line).slice(0,r.ch),l=0;;){t.lastIndex=l;var c=t.exec(s);if(!c)break;if(n=c,a=n.index,l=n.index+(n[0].length||1),l==s.length)break}var d=n&&n[0].length||0;d||(0==a&&0==s.length?n=void 0:a!=e.getLine(r.line).length&&d++)}else{t.lastIndex=r.ch;var s=e.getLine(r.line),n=t.exec(s),d=n&&n[0].length||0,a=n&&n.index;a+d==s.length||d||(d=1)}return n&&d?{from:o(r.line,a),to:o(r.line,a+d),match:n}:void 0};else{var a=t;n&&(t=t.toLowerCase());var s=n?function(e){return e.toLowerCase()}:function(e){return e},l=t.split("\n");if(1==l.length)t.length?this.matches=function(r,n){if(r){var l=e.getLine(n.line).slice(0,n.ch),c=s(l),d=c.lastIndexOf(t);if(d>-1)return d=i(l,c,d),{from:o(n.line,d),to:o(n.line,d+a.length)}}else{var l=e.getLine(n.line).slice(n.ch),c=s(l),d=c.indexOf(t);if(d>-1)return d=i(l,c,d)+n.ch,{from:o(n.line,d),to:o(n.line,d+a.length)}}}:this.matches=function(){};else{var c=a.split("\n");this.matches=function(t,i){var r=l.length-1;if(t){if(i.line-(l.length-1)=1;--d,--a)if(l[d]!=s(e.getLine(a)))return;var h=e.getLine(a),u=h.length-c[0].length;if(s(h.slice(u))!=l[0])return;return{from:o(a,u),to:n}}if(!(i.line+(l.length-1)>e.lastLine())){var h=e.getLine(i.line),u=h.length-c[0].length;if(s(h.slice(u))==l[0]){for(var f=o(i.line,u),a=i.line+1,d=1;r>d;++d,++a)if(l[d]!=s(e.getLine(a)))return;if(s(e.getLine(a).slice(0,c[r].length))==l[r])return{from:f,to:o(a,c[r].length)}}}}}}}function i(e,t,i){if(e.length==t.length)return i;for(var o=Math.min(i,e.length);;){var r=e.slice(0,o).toLowerCase().length;if(i>r)++o;else{if(!(r>i))return o;--o}}}var o=e.Pos;t.prototype={findNext:function(){return this.find(!1)},findPrevious:function(){return this.find(!0)},find:function(e){function t(e){var t=o(e,0);return i.pos={from:t,to:t},i.atOccurrence=!1,!1}for(var i=this,r=this.doc.clipPos(e?this.pos.from:this.pos.to);;){if(this.pos=this.matches(e,r))return this.atOccurrence=!0,this.pos.match||!0;if(e){if(!r.line)return t(0);r=o(r.line-1,this.doc.getLine(r.line-1).length)}else{var n=this.doc.lineCount();if(r.line==n-1)return t(n);r=o(r.line+1,0)}}},from:function(){return this.atOccurrence?this.pos.from:void 0},to:function(){return this.atOccurrence?this.pos.to:void 0},replace:function(t){if(this.atOccurrence){var i=e.splitLines(t);this.doc.replaceRange(i,this.pos.from,this.pos.to),this.pos.to=o(this.pos.from.line+i.length-1,i[i.length-1].length+(1==i.length?this.pos.from.ch:0))}}},e.defineExtension("getSearchCursor",function(e,i,o){return new t(this.doc,e,i,o)}),e.defineDocExtension("getSearchCursor",function(e,i,o){return new t(this,e,i,o)}),e.defineExtension("selectMatches",function(t,i){for(var o,r=[],n=this.getSearchCursor(t,this.getCursor("from"),i);(o=n.findNext())&&!(e.cmpPos(n.to(),this.getCursor("to"))>0);)r.push({anchor:n.from(),head:n.to()});r.length&&this.setSelections(r,0)})}),function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror"),require("./searchcursor"),require("../dialog/dialog")):"function"==typeof define&&define.amd?define(["../../lib/codemirror","./searchcursor","../dialog/dialog"],e):e(CodeMirror)}(function(e){"use strict";function t(e,t){return"string"==typeof e?e=new RegExp(e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&"),t?"gi":"g"):e.global||(e=new RegExp(e.source,e.ignoreCase?"gi":"g")),{token:function(t){e.lastIndex=t.pos;var i=e.exec(t.string);return i&&i.index==t.pos?(t.pos+=i[0].length,"searching"):void(i?t.pos=i.index:t.skipToEnd())}}}function i(){this.posFrom=this.posTo=this.query=null,this.overlay=null}function o(e){return e.state.search||(e.state.search=new i)}function r(e){return"string"==typeof e&&e==e.toLowerCase()}function n(e,t,i){return e.getSearchCursor(t,i,r(t))}function a(e,t,i,o,r){e.openDialog?e.openDialog(t,r,{value:o}):r(prompt(i,o))}function s(e,t,i,o){e.openConfirm?e.openConfirm(t,o):confirm(i)&&o[0]()}function l(e){var t=e.match(/^\/(.*)\/([a-z]*)$/);if(t)try{e=new RegExp(t[1],-1==t[2].indexOf("i")?"":"i")}catch(i){}return("string"==typeof e?""==e:e.test(""))&&(e=/x^/),e}function c(e,i){var n=o(e);return n.query?d(e,i):void a(e,f,"Search for:",e.getSelection(),function(o){e.operation(function(){o&&!n.query&&(n.query=l(o),e.removeOverlay(n.overlay,r(n.query)),n.overlay=t(n.query,r(n.query)),e.addOverlay(n.overlay),e.showMatchesOnScrollbar&&(n.annotate&&(n.annotate.clear(),n.annotate=null),n.annotate=e.showMatchesOnScrollbar(n.query,r(n.query))),n.posFrom=n.posTo=e.getCursor(),d(e,i))})})}function d(t,i){t.operation(function(){var r=o(t),a=n(t,r.query,i?r.posFrom:r.posTo);(a.find(i)||(a=n(t,r.query,i?e.Pos(t.lastLine()):e.Pos(t.firstLine(),0)),a.find(i)))&&(t.setSelection(a.from(),a.to()),t.scrollIntoView({from:a.from(),to:a.to()}),r.posFrom=a.from(),r.posTo=a.to())})}function h(e){e.operation(function(){var t=o(e);t.query&&(t.query=null,e.removeOverlay(t.overlay),t.annotate&&(t.annotate.clear(),t.annotate=null))})}function u(e,t){e.getOption("readOnly")||a(e,g,"Replace:",e.getSelection(),function(i){i&&(i=l(i),a(e,p,"Replace with:","",function(o){if(t)e.operation(function(){for(var t=n(e,i);t.findNext();)if("string"!=typeof i){var r=e.getRange(t.from(),t.to()).match(i);t.replace(o.replace(/\$(\d)/g,function(e,t){return r[t]}))}else t.replace(o)});else{h(e);var r=n(e,i,e.getCursor()),a=function(){var t,o=r.from();!(t=r.findNext())&&(r=n(e,i),!(t=r.findNext())||o&&r.from().line==o.line&&r.from().ch==o.ch)||(e.setSelection(r.from(),r.to()),e.scrollIntoView({from:r.from(),to:r.to()}),s(e,m,"Replace?",[function(){l(t)},a]))},l=function(e){r.replace("string"==typeof i?o:o.replace(/\$(\d)/g,function(t,i){return e[i]})),a()};a()}}))})}var f='Search: (Use /re/ syntax for regexp search)',g='Replace: (Use /re/ syntax for regexp search)',p='With: ',m="Replace? ";e.commands.find=function(e){h(e),c(e)},e.commands.findNext=c,e.commands.findPrev=function(e){c(e,!0)},e.commands.clearSearch=h,e.commands.replace=u,e.commands.replaceAll=function(e){u(e,!0)}}),function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict";function t(e,t){function i(e){clearTimeout(o.doRedraw),o.doRedraw=setTimeout(function(){o.redraw()},e)}this.cm=e,this.options=t,this.buttonHeight=t.scrollButtonHeight||e.getOption("scrollButtonHeight"),this.annotations=[],this.doRedraw=this.doUpdate=null,this.div=e.getWrapperElement().appendChild(document.createElement("div")),this.div.style.cssText="position: absolute; right: 0; top: 0; z-index: 7; pointer-events: none",this.computeScale();var o=this;e.on("refresh",this.resizeHandler=function(){clearTimeout(o.doUpdate),o.doUpdate=setTimeout(function(){o.computeScale()&&i(20)},100)}),e.on("markerAdded",this.resizeHandler),e.on("markerCleared",this.resizeHandler),t.listenForChanges!==!1&&e.on("change",this.changeHandler=function(){i(250)})}e.defineExtension("annotateScrollbar",function(e){return"string"==typeof e&&(e={className:e}),new t(this,e)}),e.defineOption("scrollButtonHeight",0),t.prototype.computeScale=function(){var e=this.cm,t=(e.getWrapperElement().clientHeight-e.display.barHeight-2*this.buttonHeight)/e.heightAtLine(e.lastLine()+1,"local");return t!=this.hScale?(this.hScale=t,!0):void 0},t.prototype.update=function(e){this.annotations=e,this.redraw()},t.prototype.redraw=function(e){e!==!1&&this.computeScale();var t=this.cm,i=this.hScale,o=document.createDocumentFragment(),r=this.annotations;if(t.display.barWidth)for(var n,a=0;ac+.9));)s=r[++a],c=t.charCoords(s.to,"local").bottom*i;if(c!=l){var d=Math.max(c-l,3),h=o.appendChild(document.createElement("div"));h.style.cssText="position: absolute; right: 0px; width: "+Math.max(t.display.barWidth-1,2)+"px; top: "+(l+this.buttonHeight)+"px; height: "+d+"px",h.className=this.options.className}}this.div.textContent="",this.div.appendChild(o)},t.prototype.clear=function(){this.cm.off("refresh",this.resizeHandler),this.cm.off("markerAdded",this.resizeHandler),this.cm.off("markerCleared",this.resizeHandler),this.changeHandler&&this.cm.off("change",this.changeHandler),this.div.parentNode.removeChild(this.div)}}),function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror"),require("./searchcursor"),require("../scroll/annotatescrollbar")):"function"==typeof define&&define.amd?define(["../../lib/codemirror","./searchcursor","../scroll/annotatescrollbar"],e):e(CodeMirror)}(function(e){"use strict";function t(e,t,i,o){this.cm=e;var r={listenForChanges:!1};for(var n in o)r[n]=o[n];r.className||(r.className="CodeMirror-search-match"),this.annotation=e.annotateScrollbar(r),this.query=t,this.caseFold=i,this.gap={from:e.firstLine(),to:e.lastLine()+1},this.matches=[],this.update=null,this.findMatches(),this.annotation.update(this.matches);var a=this;e.on("change",this.changeHandler=function(e,t){a.onChange(t)})}function i(e,t,i){return t>=e?e:Math.max(t,e+i)}e.defineExtension("showMatchesOnScrollbar",function(e,i,o){return"string"==typeof o&&(o={className:o}),o||(o={}),new t(this,e,i,o)});var o=1e3;t.prototype.findMatches=function(){if(this.gap){for(var t=0;t=this.gap.to)break;i.to.line>=this.gap.from&&this.matches.splice(t--,1)}for(var r=this.cm.getSearchCursor(this.query,e.Pos(this.gap.from,0),this.caseFold);r.findNext();){var i={from:r.from(),to:r.to()};if(i.from.line>=this.gap.to)break;if(this.matches.splice(t++,0,i),this.matches.length>o)break}this.gap=null}},t.prototype.onChange=function(t){var o=t.from.line,r=e.changeEnd(t).line,n=r-t.to.line;if(this.gap?(this.gap.from=Math.min(i(this.gap.from,o,n),t.from.line),this.gap.to=Math.max(i(this.gap.to,o,n),t.from.line)):this.gap={from:t.from.line,to:r+1},n)for(var a=0;ac.ch&&(v=v.slice(0,v.length-d.end+c.ch));var w=v.toLowerCase();if(!v||"string"==d.type&&(d.end!=c.ch||!/[\"\']/.test(d.string.charAt(d.string.length-1))||1==d.string.length)||"tag"==d.type&&"closeTag"==u.type||d.string.indexOf("/")==d.string.length-1||p&&r(p,w)>-1||n(t,v,c,u,!0))return e.Pass;var b=m&&r(m,w)>-1;o[l]={indent:b,text:">"+(b?"\n\n":"")+"",newPos:b?e.Pos(c.line+1,0):e.Pos(c.line,c.ch+1)}}for(var l=i.length-1;l>=0;l--){var y=o[l];t.replaceRange(y.text,i[l].head,i[l].anchor,"+insert");var k=t.listSelections().slice(0);k[l]={head:y.newPos,anchor:y.newPos},t.setSelections(k),y.indent&&(t.indentLine(y.newPos.line,null,!0),t.indentLine(y.newPos.line+1,null,!0))}}function i(t,i){for(var o=t.listSelections(),r=[],a=i?"/":"";else{if("htmlmixed"!=t.getMode().name||"css"!=d.mode.name)return e.Pass;r[s]=a+"style>"}else{if(!h.context||!h.context.tagName||n(t,h.context.tagName,l,h))return e.Pass;r[s]=a+h.context.tagName+">"}}t.replaceSelections(r),o=t.listSelections();for(var s=0;si;++i)if(e[i]==t)return i;return-1}function n(t,i,o,r,n){if(!e.scanForClosingTag)return!1;var a=Math.min(t.lastLine()+1,o.line+500),s=e.scanForClosingTag(t,o,null,a);if(!s||s.tag!=i)return!1;for(var l=r.context,c=n?1:0;l&&l.tagName==i;l=l.prev)++c;o=s.to;for(var d=1;c>d;d++){var h=e.scanForClosingTag(t,o,null,a);if(!h||h.tag!=i)return!1;o=h.to}return!0}e.defineOption("autoCloseTags",!1,function(i,r,n){if(n!=e.Init&&n&&i.removeKeyMap("autoCloseTags"),r){var a={name:"autoCloseTags"};("object"!=typeof r||r.whenClosing)&&(a["'/'"]=function(e){return o(e)}),("object"!=typeof r||r.whenOpening)&&(a["'>'"]=function(e){return t(e)}),i.addKeyMap(a)}});var a=["area","base","br","col","command","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"],s=["applet","blockquote","body","button","div","dl","fieldset","form","frameset","h1","h2","h3","h4","h5","h6","head","html","iframe","layer","legend","object","ol","p","select","table","ul"];e.commands.closeTag=function(e){return i(e)}}),function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict";function t(t,r,n,a){function s(e){var i=l(t,r);if(!i||i.to.line-i.from.linet.firstLine();)r=e.Pos(r.line-1,0),d=s(!1);if(d&&!d.cleared&&"unfold"!==a){var h=i(t,n);e.on(h,"mousedown",function(t){u.clear(),e.e_preventDefault(t)});var u=t.markText(d.from,d.to,{replacedWith:h,clearOnEnter:!0,__isFold:!0});u.on("clear",function(i,o){e.signal(t,"unfold",t,i,o)}),e.signal(t,"fold",t,d.from,d.to)}}function i(e,t){var i=o(e,t,"widget");if("string"==typeof i){var r=document.createTextNode(i);i=document.createElement("span"),i.appendChild(r),i.className="CodeMirror-foldmarker"}return i}function o(e,t,i){if(t&&void 0!==t[i])return t[i];var o=e.options.foldOptions;return o&&void 0!==o[i]?o[i]:r[i]}e.newFoldFunction=function(e,i){return function(o,r){t(o,r,{rangeFinder:e,widget:i})}},e.defineExtension("foldCode",function(e,i,o){t(this,e,i,o)}),e.defineExtension("isFolded",function(e){for(var t=this.findMarksAt(e),i=0;i=i;i++)t.foldCode(e.Pos(i,0),null,"fold")})},e.commands.unfoldAll=function(t){t.operation(function(){for(var i=t.firstLine(),o=t.lastLine();o>=i;i++)t.foldCode(e.Pos(i,0),null,"unfold")})},e.registerHelper("fold","combine",function(){var e=Array.prototype.slice.call(arguments,0);return function(t,i){for(var o=0;o=s&&(i=r(n.indicatorOpen))}e.setGutterMarker(t,n.gutter,i),++a})}function a(e){var t=e.getViewport(),i=e.state.foldGutter;i&&(e.operation(function(){n(e,t.from,t.to)}),i.from=t.from,i.to=t.to)}function s(e,t,i){var o=e.state.foldGutter;if(o){var r=o.options;i==r.gutter&&e.foldCode(h(t,0),r.rangeFinder)}}function l(e){var t=e.state.foldGutter;if(t){var i=t.options;t.from=t.to=0,clearTimeout(t.changeUpdate),t.changeUpdate=setTimeout(function(){a(e)},i.foldOnChangeTimeSpan||600)}}function c(e){var t=e.state.foldGutter;if(t){var i=t.options;clearTimeout(t.changeUpdate),t.changeUpdate=setTimeout(function(){var i=e.getViewport();t.from==t.to||i.from-t.to>20||t.from-i.to>20?a(e):e.operation(function(){i.fromt.to&&(n(e,t.to,i.to),t.to=i.to)})},i.updateViewportTimeSpan||400)}}function d(e,t){var i=e.state.foldGutter;if(i){var o=t.line;o>=i.from&&o=l;++l){var d=t.getLine(l),h=n(d);if(h>a)s=l;else if(/\S/.test(d))break}return s?{from:e.Pos(i.line,r.length),to:e.Pos(s,t.getLine(s).length)}:void 0}})}),function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict";e.registerHelper("fold","brace",function(t,i){function o(o){for(var r=i.ch,l=0;;){var c=0>=r?-1:s.lastIndexOf(o,r-1);if(-1!=c){if(1==l&&c=g;++g)for(var p=t.getLine(g),m=g==a?r:0;;){var v=p.indexOf(l,m),w=p.indexOf(c,m);if(0>v&&(v=p.length),0>w&&(w=p.length),m=Math.min(v,w),m==p.length)break;if(t.getTokenTypeAt(e.Pos(g,m+1))==n)if(m==v)++u;else if(!--u){d=g,h=m;break e}++m}if(null!=d&&(a!=d||h!=r))return{from:e.Pos(a,r),to:e.Pos(d,h)}}}),e.registerHelper("fold","import",function(t,i){function o(i){if(it.lastLine())return null;var o=t.getTokenAt(e.Pos(i,1));if(/\S/.test(o.string)||(o=t.getTokenAt(e.Pos(i,o.end+1))),"keyword"!=o.type||"import"!=o.string)return null;for(var r=i,n=Math.min(t.lastLine(),i+10);n>=r;++r){var a=t.getLine(r),s=a.indexOf(";");if(-1!=s)return{startCh:o.end,end:e.Pos(r,s)}}}var r,i=i.line,n=o(i);if(!n||o(i-1)||(r=o(i-2))&&r.end.line==i-1)return null;for(var a=n.end;;){var s=o(a.line+1);if(null==s)break;a=s.end}return{from:t.clipPos(e.Pos(i,n.startCh+1)),to:a}}),e.registerHelper("fold","include",function(t,i){function o(i){if(it.lastLine())return null;var o=t.getTokenAt(e.Pos(i,1));return/\S/.test(o.string)||(o=t.getTokenAt(e.Pos(i,o.end+1))),"meta"==o.type&&"#include"==o.string.slice(0,8)?o.start+8:void 0}var i=i.line,r=o(i);if(null==r||null!=o(i-1))return null;for(var n=i;;){var a=o(n+1);if(null==a)break;++n}return{from:e.Pos(i,r+1),to:t.clipPos(e.Pos(n))}})}),function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict";function t(e,t){return e.line-t.line||e.ch-t.ch}function i(e,t,i,o){this.line=t,this.ch=i,this.cm=e,this.text=e.getLine(t),this.min=o?o.from:e.firstLine(),this.max=o?o.to-1:e.lastLine()}function o(e,t){var i=e.cm.getTokenTypeAt(u(e.line,t));return i&&/\btag\b/.test(i)}function r(e){return e.line>=e.max?void 0:(e.ch=0,e.text=e.cm.getLine(++e.line),!0)}function n(e){return e.line<=e.min?void 0:(e.text=e.cm.getLine(--e.line),e.ch=e.text.length,!0)}function a(e){for(;;){var t=e.text.indexOf(">",e.ch);if(-1==t){if(r(e))continue;return}{if(o(e,t+1)){var i=e.text.lastIndexOf("/",t),n=i>-1&&!/\S/.test(e.text.slice(i+1,t));return e.ch=t+1,n?"selfClose":"regular"}e.ch=t+1}}}function s(e){for(;;){var t=e.ch?e.text.lastIndexOf("<",e.ch-1):-1;if(-1==t){if(n(e))continue;return}if(o(e,t+1)){p.lastIndex=t,e.ch=t;var i=p.exec(e.text);if(i&&i.index==t)return i}else e.ch=t}}function l(e){for(;;){p.lastIndex=e.ch;var t=p.exec(e.text);if(!t){if(r(e))continue;return}{if(o(e,t.index+1))return e.ch=t.index+t[0].length,t;e.ch=t.index+1}}}function c(e){for(;;){var t=e.ch?e.text.lastIndexOf(">",e.ch-1):-1;if(-1==t){if(n(e))continue;return}{if(o(e,t+1)){var i=e.text.lastIndexOf("/",t),r=i>-1&&!/\S/.test(e.text.slice(i+1,t));return e.ch=t+1,r?"selfClose":"regular"}e.ch=t}}}function d(e,t){for(var i=[];;){var o,r=l(e),n=e.line,s=e.ch-(r?r[0].length:0);if(!r||!(o=a(e)))return;if("selfClose"!=o)if(r[1]){for(var c=i.length-1;c>=0;--c)if(i[c]==r[2]){i.length=c;break}if(0>c&&(!t||t==r[2]))return{tag:r[2],from:u(n,s),to:u(e.line,e.ch)}}else i.push(r[2])}}function h(e,t){for(var i=[];;){var o=c(e);if(!o)return;if("selfClose"!=o){var r=e.line,n=e.ch,a=s(e);if(!a)return;if(a[1])i.push(a[2]);else{for(var l=i.length-1;l>=0;--l)if(i[l]==a[2]){i.length=l;break}if(0>l&&(!t||t==a[2]))return{tag:a[2],from:u(e.line,e.ch),to:u(r,n)}}}else s(e)}}var u=e.Pos,f="A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD",g=f+"-:.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040",p=new RegExp("<(/?)(["+f+"]["+g+"]*)","g");e.registerHelper("fold","xml",function(e,t){for(var o=new i(e,t.line,0);;){var r,n=l(o);if(!n||o.line!=t.line||!(r=a(o)))return;if(!n[1]&&"selfClose"!=r){var t=u(o.line,o.ch),s=d(o,n[2]);return s&&{from:t,to:s.from}}}}),e.findMatchingTag=function(e,o,r){var n=new i(e,o.line,o.ch,r);if(-1!=n.text.indexOf(">")||-1!=n.text.indexOf("<")){var l=a(n),c=l&&u(n.line,n.ch),f=l&&s(n);if(l&&f&&!(t(n,o)>0)){var g={from:u(n.line,n.ch),to:c,tag:f[2]};return"selfClose"==l?{open:g,close:null,at:"open"}:f[1]?{open:h(n,f[2]),close:g,at:"close"}:(n=new i(e,c.line,c.ch,r),{open:g,close:d(n,f[2]),at:"open"})}}},e.findEnclosingTag=function(e,t,o){for(var r=new i(e,t.line,t.ch,o);;){var n=h(r);if(!n)break;var a=new i(e,t.line,t.ch,o),s=d(a,n.tag);if(s)return{open:n,close:s}}},e.scanForClosingTag=function(e,t,o,r){var n=new i(e,t.line,t.ch,r?{from:0,to:r}:null);return d(n,o)}}),function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict";e.registerHelper("fold","markdown",function(t,i){function o(i){var o=t.getTokenTypeAt(e.Pos(i,0));return o&&/\bheader\b/.test(o)}function r(e,t,i){var r=t&&t.match(/^#+/);return r&&o(e)?r[0].length:(r=i&&i.match(/^[=\-]+\s*$/),r&&o(e+1)?"="==i[0]?1:2:n)}var n=100,a=t.getLine(i.line),s=t.getLine(i.line+1),l=r(i.line,a,s);if(l===n)return void 0;for(var c=t.lastLine(),d=i.line,h=t.getLine(d+2);c>d&&!(r(d+1,s,h)<=l);)++d,s=h,h=t.getLine(d+2);return{from:e.Pos(i.line,a.length),to:e.Pos(d,t.getLine(d).length)}})}),function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict";e.registerGlobalHelper("fold","comment",function(e){return e.blockCommentStart&&e.blockCommentEnd},function(t,i){var o=t.getModeAt(i),r=o.blockCommentStart,n=o.blockCommentEnd;if(r&&n){for(var a,s=i.line,l=t.getLine(s),c=i.ch,d=0;;){var h=0>=c?-1:l.lastIndexOf(r,c-1);if(-1!=h){if(1==d&&h=m;++m)for(var v=t.getLine(m),w=m==s?a:0;;){var b=v.indexOf(r,w),y=v.indexOf(n,w);if(0>b&&(b=v.length),0>y&&(y=v.length),w=Math.min(b,y),w==v.length)break;if(w==b)++g;else if(!--g){u=m,f=w;break e}++w}if(null!=u&&(s!=u||f!=a))return{from:e.Pos(s,a),to:e.Pos(u,f)}}})}),function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict";e.overlayMode=function(t,i,o){return{startState:function(){return{base:e.startState(t),overlay:e.startState(i),basePos:0,baseCur:null,overlayPos:0,overlayCur:null,streamSeen:null}},copyState:function(o){return{base:e.copyState(t,o.base),overlay:e.copyState(i,o.overlay),basePos:o.basePos,baseCur:null,overlayPos:o.overlayPos,overlayCur:null}},token:function(e,r){return(e!=r.streamSeen||Math.min(r.basePos,r.overlayPos)=i.ch+1)return/\bstring2?\b/.test(s);a.start=a.pos}}function o(o,r){for(var n={name:"autoCloseBrackets",Backspace:function(i){if(i.getOption("disableInput"))return e.Pass;for(var r=i.listSelections(),n=0;n=0;n--){var s=r[n].head;i.replaceRange("",c(s.line,s.ch-1),c(s.line,s.ch+1))}}},a="",s=0;s1&&r.indexOf(t)>=0&&n.getRange(c(p.line,p.ch-2),p)==t+t&&(p.ch<=2||n.getRange(c(p.line,p.ch-3),c(p.line,p.ch-2))!=t))f="addFour";else if('"'==t||"'"==t){if(e.isWordChar(d)||!i(n,p,t))return e.Pass;f="both"}else{if(!(n.getLine(p.line).length==p.ch||a.indexOf(d)>=0||l.test(d)))return e.Pass;f="both"}else f="surround";if(s){if(s!=f)return e.Pass}else s=f}n.operation(function(){if("skip"==s)n.execCommand("goCharRight");else if("skipThree"==s)for(var e=0;3>e;e++)n.execCommand("goCharRight");else if("surround"==s){for(var i=n.getSelections(),e=0;es&&e.addOverlay(t.overlay=a(n.slice(s,l),i,t.style)))}var c=e.getCursor("from"),d=e.getCursor("to");if(c.line==d.line&&(!t.wordsOnly||r(e,c,d))){var h=e.getRange(c,d).replace(/^\s+|\s+$/g,"");h.length>=t.minChars&&e.addOverlay(t.overlay=a(h,!1,t.style))}})}function r(e,t,i){var o=e.getRange(t,i);if(null!==o.match(/^\w+$/)){if(t.ch>0){var r={line:t.line,ch:t.ch-1},n=e.getRange(r,t);if(null===n.match(/\W/))return!1}if(i.che.pos?(e.pos=n,null):(e.pos=t,"trailingspace")},name:"trailingspace"})})}),function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(u){function d(e,t,n){var e=e.getWrapperElement(),o=e.appendChild(document.createElement("div"));return o.className=n?"CodeMirror-dialog CodeMirror-dialog-bottom":"CodeMirror-dialog CodeMirror-dialog-top","string"==typeof t?o.innerHTML=t:o.appendChild(t),u.addClass(e,"dialog-opened"),o}function h(e,t){e.state.currentNotificationClose&&e.state.currentNotificationClose(),e.state.currentNotificationClose=t}u.defineExtension("openDialog",function(e,t,n){n=n||{},h(this,null);var o=d(this,e,n.bottom),r=!1,i=this;function a(e){"string"==typeof e?l.value=e:r||(r=!0,u.rmClass(o.parentNode,"dialog-opened"),o.parentNode.removeChild(o),i.focus(),n.onClose&&n.onClose(o))}var l=o.getElementsByTagName("input")[0];return l?(l.focus(),n.value&&(l.value=n.value,!1!==n.selectValueOnOpen)&&l.select(),n.onInput&&u.on(l,"input",function(e){n.onInput(e,l.value,a)}),n.onKeyUp&&u.on(l,"keyup",function(e){n.onKeyUp(e,l.value,a)}),u.on(l,"keydown",function(e){n&&n.onKeyDown&&n.onKeyDown(e,l.value,a)||((27==e.keyCode||!1!==n.closeOnEnter&&13==e.keyCode)&&(l.blur(),u.e_stop(e),a()),13==e.keyCode&&t(l.value,e))}),!1!==n.closeOnBlur&&u.on(o,"focusout",function(e){null!==e.relatedTarget&&a()})):(e=o.getElementsByTagName("button")[0])&&(u.on(e,"click",function(){a(),i.focus()}),!1!==n.closeOnBlur&&u.on(e,"blur",a),e.focus()),a}),u.defineExtension("openConfirm",function(e,t,n){h(this,null);var o=d(this,e,n&&n.bottom),r=o.getElementsByTagName("button"),i=!1,a=this,l=1;function s(){i||(i=!0,u.rmClass(o.parentNode,"dialog-opened"),o.parentNode.removeChild(o),a.focus())}r[0].focus();for(var c=0;ce.length-n)break;(!o||a>o.index+o[0].length)&&(o=i),r=i.index+1}return o}function C(e,t,n){t=p(t,"g");for(var o=n.line,r=n.ch,i=e.firstLine();i<=o;o--,r=-1){var a=e.getLine(o),a=b(a,t,r<0?0:a.length-r);if(a)return{from:y(o,a.index),to:y(o,a.index+a[0].length),match:a}}}function a(e,t,n){if(!g(t))return C(e,t,n);t=p(t,"gm");for(var o=1,r=e.getLine(n.line).length-n.ch,i=n.line,a=e.firstLine();a<=i;){for(var l=0;l>1,l=o(e.slice(0,a)).length;if(l==n)return a;n(this.doc.getLine(t.line)||"").length&&(t.ch=0,t.line++)),0!=r.cmpPos(t,this.doc.clipPos(t)))?this.atOccurrence=!1:(t=this.matches(e,t),this.afterEmptyMatch=t&&0==r.cmpPos(t.from,t.to),t?(this.pos=t,this.atOccurrence=!0,this.pos.match||!0):(t=y(e?this.doc.firstLine():this.doc.lastLine()+1,0),this.pos={from:t,to:t},this.atOccurrence=!1))},from:function(){if(this.atOccurrence)return this.pos.from},to:function(){if(this.atOccurrence)return this.pos.to},replace:function(e,t){this.atOccurrence&&(e=r.splitLines(e),this.doc.replaceRange(e,this.pos.from,this.pos.to,t),this.pos.to=y(this.pos.from.line+e.length-1,e[e.length-1].length+(1==e.length?this.pos.from.ch:0)))}},r.defineExtension("getSearchCursor",function(e,t,n){return new o(this.doc,e,t,n)}),r.defineDocExtension("getSearchCursor",function(e,t,n){return new o(this,e,t,n)}),r.defineExtension("selectMatches",function(e,t){for(var n=[],o=this.getSearchCursor(e,this.getCursor("from"),t);o.findNext()&&!(0r.cursorCoords(t,"window").top&&((i=n).style.opacity=.4)}))},e=C(l=r),s=f,c=function(e,t){var n=u.keyName(e),o=r.getOption("extraKeys"),o=o&&o[n]||u.keyMap[r.getOption("keyMap")][n];"findNext"==o||"findPrev"==o||"findPersistentNext"==o||"findPersistentPrev"==o?(u.e_stop(e),m(r,d(r),t),r.execCommand(o)):"find"!=o&&"findPersistent"!=o||(u.e_stop(e),a(t,e))},l.openDialog(e,a,{value:s,selectValueOnOpen:!0,closeOnEnter:!1,onClose:function(){y(l)},onKeyDown:c,bottom:l.options.search.bottom}),n&&f&&(m(r,o,f),v(r,t))):p(r,C(r),"Search for:",f,function(e){e&&!o.query&&r.operation(function(){m(r,o,e),o.posFrom=o.posTo=r.getCursor(),v(r,t)})})}function v(n,o,r){n.operation(function(){var e=d(n),t=h(n,e.query,o?e.posFrom:e.posTo);(t.find(o)||(t=h(n,e.query,o?u.Pos(n.lastLine()):u.Pos(n.firstLine(),0))).find(o))&&(n.setSelection(t.from(),t.to()),n.scrollIntoView({from:t.from(),to:t.to()},20),e.posFrom=t.from(),e.posTo=t.to(),r)&&r(t.from(),t.to())})}function y(t){t.operation(function(){var e=d(t);e.lastQuery=e.query,e.query&&(e.query=e.queryText=null,t.removeOverlay(e.overlay),e.annotate)&&(e.annotate.clear(),e.annotate=null)})}function b(e,t){var n,o=e?document.createElement(e):document.createDocumentFragment();for(n in t)o[n]=t[n];for(var r=2;ra?o.charCoords(e,"local")[t?"top":"bottom"]:o.heightAtLine(s,"local")+(t?0:s.height)}var f=o.lastLine();if(o.display.barWidth)for(var u,d=0;df)){for(var p,g,m=u||c(h.from,!0)*t,v=c(h.to,!1)*t;df)&&!(v+.9<(u=c(r[d+1].from,!0)*t));)v=c((h=r[++d]).to,!1)*t;v!=m&&(p=Math.max(v-m,3),(g=n.appendChild(document.createElement("div"))).style.cssText="position: absolute; right: 0px; width: "+Math.max(o.display.barWidth-1,2)+"px; top: "+(m+this.buttonHeight)+"px; height: "+p+"px",g.className=this.options.className,h.id)&&g.setAttribute("annotation-id",h.id)}}this.div.textContent="",this.div.appendChild(n)},t.prototype.clear=function(){this.cm.off("refresh",this.resizeHandler),this.cm.off("markerAdded",this.resizeHandler),this.cm.off("markerCleared",this.resizeHandler),this.changeHandler&&this.cm.off("changes",this.changeHandler),this.div.parentNode.removeChild(this.div)}}),function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror"),require("./searchcursor"),require("../scroll/annotatescrollbar")):"function"==typeof define&&define.amd?define(["../../lib/codemirror","./searchcursor","../scroll/annotatescrollbar"],e):e(CodeMirror)}(function(s){"use strict";function o(e,t,n,o){this.cm=e;var r,i={listenForChanges:!1};for(r in this.options=o)i[r]=o[r];i.className||(i.className="CodeMirror-search-match"),this.annotation=e.annotateScrollbar(i),this.query=t,this.caseFold=n,this.gap={from:e.firstLine(),to:e.lastLine()+1},this.matches=[],this.update=null,this.findMatches(),this.annotation.update(this.matches);var a=this;e.on("change",this.changeHandler=function(e,t){a.onChange(t)})}s.defineExtension("showMatchesOnScrollbar",function(e,t,n){return new o(this,e,t,n=(n="string"==typeof n?{className:n}:n)||{})});function c(e,t,n){return e<=t?e:Math.max(t,e+n)}o.prototype.findMatches=function(){if(this.gap){for(var e=0;e=this.gap.to)break;t.to.line>=this.gap.from&&this.matches.splice(e--,1)}for(var t,n=this.cm.getSearchCursor(this.query,s.Pos(this.gap.from,0),{caseFold:this.caseFold,multiline:this.options.multiline}),o=this.options&&this.options.maxMatches||1e3;n.findNext();){if((t={from:n.from(),to:n.to()}).from.line>=this.gap.to)break;if(this.matches.splice(e++,0,t),this.matches.length>o)break}this.gap=null}},o.prototype.onChange=function(e){var t=e.from.line,n=s.changeEnd(e).line,o=n-e.to.line;if(this.gap?(this.gap.from=Math.min(c(this.gap.from,t,o),e.from.line),this.gap.to=Math.max(c(this.gap.to,t,o),e.from.line)):this.gap={from:e.from.line,to:n+1},o)for(var r=0;r'"]=function(e){var t=e;if(t.getOption("disableInput"))return y.Pass;for(var n=t.listSelections(),o=[],r=t.getOption("autoCloseTags"),i=0;ia.ch?u.slice(0,u.length-l.end+a.ch):u).toLowerCase();if(!u||"string"==l.type&&(l.end!=a.ch||!/[\"\']/.test(l.string.charAt(l.string.length-1))||1==l.string.length)||"tag"==l.type&&f.close||l.string.indexOf("/")==a.ch-l.start-1||h&&-1",newPos:y.Pos(a.line,a.ch+2)}:(l=d&&-1"+(l?"\n\n":"")+"",newPos:l?y.Pos(a.line+1,0):y.Pos(a.line,a.ch+1)})}for(var g="object"==typeof r&&r.dontIndentOnAutoClose,i=n.length-1;0<=i;i--){var m=o[i],v=(t.replaceRange(m.text,n[i].head,n[i].anchor,"+insert"),t.listSelections().slice(0));v[i]={head:m.newPos,anchor:m.newPos},t.setSelections(v),!g&&m.indent&&(t.indentLine(m.newPos.line,null,!0),t.indentLine(m.newPos.line+1,null,!0))}}),e.addKeyMap(n))});var b=["area","base","br","col","command","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"],C=["applet","blockquote","body","button","div","dl","fieldset","form","frameset","h1","h2","h3","h4","h5","h6","head","html","iframe","layer","legend","object","ol","p","select","table","ul"];function o(e,t){for(var n=e.listSelections(),o=[],r=t?"/":""!=e.getLine(l.line).charAt(s.end)&&(u+=">"),o[a]=u}if(e.replaceSelections(o),n=e.listSelections(),!i)for(a=0;ar.firstLine();)i=f.Pos(i.line-1,0),c=t(!1);c&&!c.cleared&&"unfold"!==a&&(n=function(e,t,n){e=u(e,t,"widget");"function"==typeof e&&(e=e(n.from,n.to));"string"==typeof e?(t=document.createTextNode(e),(e=document.createElement("span")).appendChild(t),e.className="CodeMirror-foldmarker"):e=e&&e.cloneNode(!0);return e}(r,e,c),f.on(n,"mousedown",function(e){o.clear(),f.e_preventDefault(e)}),(o=r.markText(c.from,c.to,{replacedWith:n,clearOnEnter:u(r,e,"clearOnEnter"),__isFold:!0})).on("clear",function(e,t){f.signal(r,"unfold",r,e,t)}),f.signal(r,"fold",r,c.from,c.to))}f.newFoldFunction=function(n,o){return function(e,t){r(e,t,{rangeFinder:n,widget:o})}},f.defineExtension("foldCode",function(e,t,n){r(this,e,t,n)}),f.defineExtension("isFolded",function(e){for(var t=this.findMarksAt(e),n=0;n=l){if(f&&n&&f.test(n.className))return;t=h(i.indicatorOpen)}}(t||n)&&r.setGutterMarker(e,i.gutter,t)})}function n(e){return new RegExp("(^|\\s)"+e+"(?:$|\\s)\\s*")}function a(e){var t=e.getViewport(),n=e.state.foldGutter;n&&(e.operation(function(){i(e,t.from,t.to)}),n.from=t.from,n.to=t.to)}function l(e,t,n){var o=e.state.foldGutter;o&&n==(n=o.options).gutter&&((o=d(e,t))?o.clear():e.foldCode(u(t,0),n))}function s(e){var t,n=e.state.foldGutter;n&&(t=n.options,n.from=n.to=0,clearTimeout(n.changeUpdate),n.changeUpdate=setTimeout(function(){a(e)},t.foldOnChangeTimeSpan||600))}function c(t){var e,n=t.state.foldGutter;n&&(e=n.options,clearTimeout(n.changeUpdate),n.changeUpdate=setTimeout(function(){var e=t.getViewport();n.from==n.to||20n.to&&(i(t,n.to,e.to),n.to=e.to)})},e.updateViewportTimeSpan||400))}function f(e,t){var n=e.state.foldGutter;n&&(t=t.line)>=n.from&&ti.lastLine())return null;var t=i.getTokenAt(h.Pos(e,1));if("keyword"!=(t=/\S/.test(t.string)?t:i.getTokenAt(h.Pos(e,t.end+1))).type||"import"!=t.string)return null;for(var n=e,o=Math.min(i.lastLine(),e+10);n<=o;++n){var r=i.getLine(n).indexOf(";");if(-1!=r)return{startCh:t.end,end:h.Pos(n,r)}}}var n,e=e.line,o=t(e);if(!o||t(e-1)||(n=t(e-2))&&n.end.line==e-1)return null;for(var r=o.end;;){var a=t(r.line+1);if(null==a)break;r=a.end}return{from:i.clipPos(h.Pos(e,o.startCh+1)),to:r}}),h.registerHelper("fold","include",function(n,e){function t(e){var t;return en.lastLine()?null:(t=n.getTokenAt(h.Pos(e,1)),"meta"==(t=/\S/.test(t.string)?t:n.getTokenAt(h.Pos(e,t.end+1))).type&&"#include"==t.string.slice(0,8)?t.start+8:void 0)}var e=e.line,o=t(e);if(null==o||null!=t(e-1))return null;for(var r=e;;){if(null==t(r+1))break;++r}return{from:h.Pos(e,o+1),to:n.clipPos(h.Pos(r))}})}),function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict";var s=e.Pos;function l(e,t){return e.line-t.line||e.ch-t.ch}var t="A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD",o=new RegExp("<(/?)(["+t+"][A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD-:.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*)","g");function c(e,t,n,o){this.line=t,this.ch=n,this.cm=e,this.text=e.getLine(t),this.min=o?Math.max(o.from,e.firstLine()):e.firstLine(),this.max=o?Math.min(o.to-1,e.lastLine()):e.lastLine()}function f(e,t){e=e.cm.getTokenTypeAt(s(e.line,t));return e&&/\btag\b/.test(e)}function r(e){return!(e.line>=e.max)&&(e.ch=0,e.text=e.cm.getLine(++e.line),1)}function u(e){return!(e.line<=e.min)&&(e.text=e.cm.getLine(--e.line),e.ch=e.text.length,1)}function d(e){for(;;){var t,n=e.text.indexOf(">",e.ch);if(-1==n){if(r(e))continue;return}if(f(e,n+1))return t=-1<(t=e.text.lastIndexOf("/",n))&&!/\S/.test(e.text.slice(t+1,n)),e.ch=n+1,t?"selfClose":"regular";e.ch=n+1}}function h(e){for(;;){var t=e.ch?e.text.lastIndexOf("<",e.ch-1):-1;if(-1==t){if(u(e))continue;return}if(f(e,t+1)){o.lastIndex=t,e.ch=t;var n=o.exec(e.text);if(n&&n.index==t)return n}else e.ch=t}}function p(e){for(;;){o.lastIndex=e.ch;var t=o.exec(e.text);if(!t){if(r(e))continue;return}if(f(e,t.index+1))return e.ch=t.index+t[0].length,t;e.ch=t.index+1}}function g(e,t){for(var n=[];;){var o,r=p(e),i=e.line,a=e.ch-(r?r[0].length:0);if(!r||!(o=d(e)))return;if("selfClose"!=o)if(r[1]){for(var l=n.length-1;0<=l;--l)if(n[l]==r[2]){n.length=l;break}if(l<0&&(!t||t==r[2]))return{tag:r[2],from:s(i,a),to:s(e.line,e.ch)}}else n.push(r[2])}}function m(e,t){for(var n=[];;){var o=function(e){for(;;){var t,n=e.ch?e.text.lastIndexOf(">",e.ch-1):-1;if(-1==n){if(u(e))continue;return}if(f(e,n+1))return t=-1<(t=e.text.lastIndexOf("/",n))&&!/\S/.test(e.text.slice(t+1,n)),e.ch=n+1,t?"selfClose":"regular";e.ch=n}}(e);if(!o)return;if("selfClose"==o)h(e);else{var o=e.line,r=e.ch,i=h(e);if(!i)return;if(i[1])n.push(i[2]);else{for(var a=n.length-1;0<=a;--a)if(n[a]==i[2]){n.length=a;break}if(a<0&&(!t||t==i[2]))return{tag:i[2],from:s(e.line,e.ch),to:s(o,r)}}}}}e.registerHelper("fold","xml",function(e,t){for(var n=new c(e,t.line,0);;){var o=p(n);if(!o||n.line!=t.line)return;var r=d(n);if(!r)return;if(!o[1]&&"selfClose"!=r)return r=s(n.line,n.ch),(o=g(n,o[2]))&&0")||-1!=o.text.indexOf("<")){var r=d(o),i=r&&s(o.line,o.ch),a=r&&h(o);if(r&&a&&!(0",triples:"",explode:"[]{}"},C=b.Pos;function x(e,t){return"pairs"==t&&"string"==typeof e?e:("object"==typeof e&&null!=e[t]?e:n)[t]}b.defineOption("autoCloseBrackets",!1,function(e,t,n){n&&n!=b.Init&&(e.removeKeyMap(r),e.state.closeBrackets=null),t&&(o(x(t,"pairs")),e.state.closeBrackets=t,e.addKeyMap(r))});var r={Backspace:function(e){var t=O(e);if(!t||e.getOption("disableInput"))return b.Pass;for(var n=x(t,"pairs"),o=e.listSelections(),r=0;r=e.options.minChars&&s(l,n,!1,e.options.style))}})}o.defineOption("highlightSelectionMatches",!1,function(e,t,n){n&&n!=o.Init&&(c(e),clearTimeout(e.state.matchHighlighter.timeout),e.state.matchHighlighter=null,e.off("cursorActivity",i),e.off("focus",a)),t&&(n=e.state.matchHighlighter=new r(t),e.hasFocus()?(n.active=!0,f(e)):e.on("focus",a),e.on("cursorActivity",i))})}); \ No newline at end of file diff --git a/static/editor.md/lib/codemirror/codemirror.min.css b/static/editor.md/lib/codemirror/codemirror.min.css index c2d0882c..afd8e994 100644 --- a/static/editor.md/lib/codemirror/codemirror.min.css +++ b/static/editor.md/lib/codemirror/codemirror.min.css @@ -1,3 +1,2 @@ -/* CodeMirror v5.0 | CodeMirror, copyright (c) by Marijn Haverbeke and others | Distributed under an MIT license: http://codemirror.net/LICENSE */ -.CodeMirror{font-family:monospace;height:300px;color:black}.CodeMirror-lines{padding:4px 0}.CodeMirror pre{padding:0 4px}.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{background-color:white}.CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-guttermarker{color:black}.CodeMirror-guttermarker-subtle{color:#999}.CodeMirror div.CodeMirror-cursor{border-left:1px solid black}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.CodeMirror.cm-fat-cursor div.CodeMirror-cursor{width:auto;border:0;background:#7e7}.CodeMirror.cm-fat-cursor div.CodeMirror-cursors{z-index:1}.cm-animate-fat-cursor{width:auto;border:0;-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite}@-moz-keyframes blink{0%{background:#7e7}50%{background:0}100%{background:#7e7}}@-webkit-keyframes blink{0%{background:#7e7}50%{background:0}100%{background:#7e7}}@keyframes blink{0%{background:#7e7}50%{background:0}100%{background:#7e7}}.cm-tab{display:inline-block;text-decoration:inherit}.CodeMirror-ruler{border-left:1px solid #ccc;position:absolute}.cm-s-default .cm-keyword{color:#708}.cm-s-default .cm-atom{color:#219}.cm-s-default .cm-number{color:#164}.cm-s-default .cm-def{color:#00f}.cm-s-default .cm-variable-2{color:#05a}.cm-s-default .cm-variable-3{color:#085}.cm-s-default .cm-comment{color:#a50}.cm-s-default .cm-string{color:#a11}.cm-s-default .cm-string-2{color:#f50}.cm-s-default .cm-meta{color:#555}.cm-s-default .cm-qualifier{color:#555}.cm-s-default .cm-builtin{color:#30a}.cm-s-default .cm-bracket{color:#997}.cm-s-default .cm-tag{color:#170}.cm-s-default .cm-attribute{color:#00c}.cm-s-default .cm-header{color:blue}.cm-s-default .cm-quote{color:#090}.cm-s-default .cm-hr{color:#999}.cm-s-default .cm-link{color:#00c}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:bold}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-strikethrough{text-decoration:line-through}.cm-s-default .cm-error{color:#f00}.cm-invalidchar{color:#f00}div.CodeMirror span.CodeMirror-matchingbracket{color:#0f0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#f22}.CodeMirror-matchingtag{background:rgba(255,150,0,.3)}.CodeMirror-activeline-background{background:#e8f2ff}.CodeMirror{position:relative;overflow:hidden;background:white}.CodeMirror-scroll{overflow:scroll!important;margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:0;position:relative;-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-sizer{position:relative;border-right:30px solid transparent;-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-vscrollbar,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{position:absolute;z-index:6;display:none}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom:0}.CodeMirror-gutters{position:absolute;left:0;top:0;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;-moz-box-sizing:content-box;box-sizing:content-box;display:inline-block;margin-bottom:-30px;*zoom:1;*display:inline}.CodeMirror-gutter-wrapper{position:absolute;z-index:4;height:100%}.CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.CodeMirror-gutter-wrapper{-webkit-user-select:none;-moz-user-select:none;user-select:none}.CodeMirror-lines{cursor:text;min-height:1px}.CodeMirror pre{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;border-width:0;background:transparent;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible;-webkit-tap-highlight-color:transparent}.CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;overflow:auto}.CodeMirror-code{outline:0}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-measure pre{position:static}.CodeMirror div.CodeMirror-cursor{position:absolute;border-right:0;width:0}div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}.CodeMirror-focused div.CodeMirror-cursors{visibility:visible}.CodeMirror-selected{background:#d9d9d9}.CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}.CodeMirror-crosshair{cursor:crosshair}.CodeMirror ::selection{background:#d7d4f0}.CodeMirror ::-moz-selection{background:#d7d4f0}.cm-searching{background:#ffa;background:rgba(255,255,0,.4)}.CodeMirror span{*vertical-align:text-bottom}.cm-force-border{padding-right:.1px} -@media print{.CodeMirror div.CodeMirror-cursors{visibility:hidden}}.cm-tab-wrap-hack:after{content:''}span.CodeMirror-selectedtext{background:0} \ No newline at end of file +/*! Editor.md v1.7.17 | codemirror.min.css | Open source online markdown editor. | MIT License | By: IBM Skills Network | https://github.com/ibm-skills-network/editor.md | 2024-03-27 */ +.CodeMirror{font-family:monospace;height:300px;color:#000;direction:ltr}.CodeMirror-lines{padding:4px 0}.CodeMirror pre.CodeMirror-line,.CodeMirror pre.CodeMirror-line-like{padding:0 4px}.CodeMirror-gutter-filler,.CodeMirror-scrollbar-filler{background-color:#fff}.CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;white-space:nowrap}.CodeMirror-guttermarker{color:#000}.CodeMirror-guttermarker-subtle{color:#999}.CodeMirror-cursor{border-left:1px solid #000;border-right:none;width:0}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.cm-fat-cursor .CodeMirror-cursor{width:auto;border:0!important;background:#7e7}.cm-fat-cursor div.CodeMirror-cursors{z-index:1}.cm-fat-cursor .CodeMirror-line::selection,.cm-fat-cursor .CodeMirror-line>span::selection,.cm-fat-cursor .CodeMirror-line>span>span::selection{background:0 0}.cm-fat-cursor .CodeMirror-line::-moz-selection,.cm-fat-cursor .CodeMirror-line>span::-moz-selection,.cm-fat-cursor .CodeMirror-line>span>span::-moz-selection{background:0 0}.cm-fat-cursor{caret-color:transparent}@-moz-keyframes blink{50%{background-color:transparent}}@-webkit-keyframes blink{50%{background-color:transparent}}@keyframes blink{50%{background-color:transparent}}.cm-tab{display:inline-block;text-decoration:inherit}.CodeMirror-rulers{position:absolute;left:0;right:0;top:-50px;bottom:0;overflow:hidden}.CodeMirror-ruler{border-left:1px solid #ccc;top:0;bottom:0;position:absolute}.cm-s-default .cm-header{color:#00f}.cm-s-default .cm-quote{color:#090}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:700}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-strikethrough{text-decoration:line-through}.cm-s-default .cm-keyword{color:#708}.cm-s-default .cm-atom{color:#219}.cm-s-default .cm-number{color:#164}.cm-s-default .cm-def{color:#00f}.cm-s-default .cm-variable-2{color:#05a}.cm-s-default .cm-type,.cm-s-default .cm-variable-3{color:#085}.cm-s-default .cm-comment{color:#a50}.cm-s-default .cm-string{color:#a11}.cm-s-default .cm-string-2{color:#f50}.cm-s-default .cm-meta{color:#555}.cm-s-default .cm-qualifier{color:#555}.cm-s-default .cm-builtin{color:#30a}.cm-s-default .cm-bracket{color:#997}.cm-s-default .cm-tag{color:#170}.cm-s-default .cm-attribute{color:#00c}.cm-s-default .cm-hr{color:#999}.cm-s-default .cm-link{color:#00c}.cm-s-default .cm-error{color:red}.cm-invalidchar{color:red}.CodeMirror-composing{border-bottom:2px solid}div.CodeMirror span.CodeMirror-matchingbracket{color:#0b0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#a22}.CodeMirror-matchingtag{background:rgba(255,150,0,.3)}.CodeMirror-activeline-background{background:#e8f2ff}.CodeMirror{position:relative;overflow:hidden;background:#fff}.CodeMirror-scroll{overflow:scroll!important;margin-bottom:-50px;margin-right:-50px;padding-bottom:50px;height:100%;outline:0;position:relative;z-index:0}.CodeMirror-sizer{position:relative;border-right:50px solid transparent}.CodeMirror-gutter-filler,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-vscrollbar{position:absolute;z-index:6;display:none;outline:0}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom:0}.CodeMirror-gutters{position:absolute;left:0;top:0;min-height:100%;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;display:inline-block;vertical-align:top;margin-bottom:-50px}.CodeMirror-gutter-wrapper{position:absolute;z-index:4;background:0 0!important;border:none!important}.CodeMirror-gutter-background{position:absolute;top:0;bottom:0;z-index:4}.CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.CodeMirror-gutter-wrapper ::selection{background-color:transparent}.CodeMirror-gutter-wrapper ::-moz-selection{background-color:transparent}.CodeMirror-lines{cursor:text;min-height:1px}.CodeMirror pre.CodeMirror-line,.CodeMirror pre.CodeMirror-line-like{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;border-width:0;background:0 0;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible;-webkit-tap-highlight-color:transparent;-webkit-font-variant-ligatures:contextual;font-variant-ligatures:contextual}.CodeMirror-wrap pre.CodeMirror-line,.CodeMirror-wrap pre.CodeMirror-line-like{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;padding:.1px}.CodeMirror-rtl pre{direction:rtl}.CodeMirror-code{outline:0}.CodeMirror-gutter,.CodeMirror-gutters,.CodeMirror-linenumber,.CodeMirror-scroll,.CodeMirror-sizer{-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-cursor{position:absolute;pointer-events:none}.CodeMirror-measure pre{position:static}div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}div.CodeMirror-dragcursors{visibility:visible}.CodeMirror-focused div.CodeMirror-cursors{visibility:visible}.CodeMirror-selected{background:#d9d9d9}.CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}.CodeMirror-crosshair{cursor:crosshair}.CodeMirror-line::selection,.CodeMirror-line>span::selection,.CodeMirror-line>span>span::selection{background:#d7d4f0}.CodeMirror-line::-moz-selection,.CodeMirror-line>span::-moz-selection,.CodeMirror-line>span>span::-moz-selection{background:#d7d4f0}.cm-searching{background-color:#ffa;background-color:rgba(255,255,0,.4)}.cm-force-border{padding-right:.1px}@media print{.CodeMirror div.CodeMirror-cursors{visibility:hidden}}.cm-tab-wrap-hack:after{content:''}span.CodeMirror-selectedtext{background:0 0} \ No newline at end of file diff --git a/static/editor.md/lib/codemirror/codemirror.min.js b/static/editor.md/lib/codemirror/codemirror.min.js index aa2eb131..b4d2722f 100644 --- a/static/editor.md/lib/codemirror/codemirror.min.js +++ b/static/editor.md/lib/codemirror/codemirror.min.js @@ -1,54 +1,2 @@ -/*! -// CodeMirror v5.0, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// This is CodeMirror (http://codemirror.net), a code editor -// implemented in JavaScript on top of the browser's DOM. -// -// You can find some technical background for some of the code below -// at http://marijnhaverbeke.nl/blog/#cm-internals . -*/ -(function(mod){if(typeof exports=="object"&&typeof module=="object"){module.exports=mod()}else{if(typeof define=="function"&&define.amd){return define([],mod)}else{this.CodeMirror=mod()}}})(function(){var gecko=/gecko\/\d/i.test(navigator.userAgent);var ie_upto10=/MSIE \d/.test(navigator.userAgent);var ie_11up=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);var ie=ie_upto10||ie_11up;var ie_version=ie&&(ie_upto10?document.documentMode||6:ie_11up[1]);var webkit=/WebKit\//.test(navigator.userAgent);var qtwebkit=webkit&&/Qt\/\d+\.\d+/.test(navigator.userAgent);var chrome=/Chrome\//.test(navigator.userAgent);var presto=/Opera\//.test(navigator.userAgent);var safari=/Apple Computer/.test(navigator.vendor);var mac_geMountainLion=/Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent);var phantom=/PhantomJS/.test(navigator.userAgent);var ios=/AppleWebKit/.test(navigator.userAgent)&&/Mobile\/\w+/.test(navigator.userAgent);var mobile=ios||/Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);var mac=ios||/Mac/.test(navigator.platform);var windows=/win/i.test(navigator.platform);var presto_version=presto&&navigator.userAgent.match(/Version\/(\d*\.\d*)/);if(presto_version){presto_version=Number(presto_version[1])}if(presto_version&&presto_version>=15){presto=false;webkit=true}var flipCtrlCmd=mac&&(qtwebkit||presto&&(presto_version==null||presto_version<12.11));var captureRightClick=gecko||(ie&&ie_version>=9);var sawReadOnlySpans=false,sawCollapsedSpans=false;function CodeMirror(place,options){if(!(this instanceof CodeMirror)){return new CodeMirror(place,options)}this.options=options=options?copyObj(options):{};copyObj(defaults,options,false);setGuttersForLineNumbers(options);var doc=options.value;if(typeof doc=="string"){doc=new Doc(doc,options.mode)}this.doc=doc;var input=new CodeMirror.inputStyles[options.inputStyle](this);var display=this.display=new Display(place,doc,input);display.wrapper.CodeMirror=this;updateGutters(this);themeChanged(this);if(options.lineWrapping){this.display.wrapper.className+=" CodeMirror-wrap"}if(options.autofocus&&!mobile){display.input.focus()}initScrollbars(this);this.state={keyMaps:[],overlays:[],modeGen:0,overwrite:false,focused:false,suppressEdits:false,pasteIncoming:false,cutIncoming:false,draggingText:false,highlight:new Delayed(),keySeq:null};var cm=this;if(ie&&ie_version<11){setTimeout(function(){cm.display.input.reset(true)},20)}registerEventHandlers(this);ensureGlobalHandlers();startOperation(this);this.curOp.forceUpdate=true;attachDoc(this,doc);if((options.autofocus&&!mobile)||cm.hasFocus()){setTimeout(bind(onFocus,this),20)}else{onBlur(this)}for(var opt in optionHandlers){if(optionHandlers.hasOwnProperty(opt)){optionHandlers[opt](this,options[opt],Init)}}maybeUpdateLineNumberWidth(this);if(options.finishInit){options.finishInit(this)}for(var i=0;id.maxLineLength){d.maxLineLength=len;d.maxLine=line}})}function setGuttersForLineNumbers(options){var found=indexOf(options.gutters,"CodeMirror-linenumbers");if(found==-1&&options.lineNumbers){options.gutters=options.gutters.concat(["CodeMirror-linenumbers"])}else{if(found>-1&&!options.lineNumbers){options.gutters=options.gutters.slice(0);options.gutters.splice(found,1)}}}function measureForScrollbars(cm){var d=cm.display,gutterW=d.gutters.offsetWidth;var docH=Math.round(cm.doc.height+paddingVert(cm.display));return{clientHeight:d.scroller.clientHeight,viewHeight:d.wrapper.clientHeight,scrollWidth:d.scroller.scrollWidth,clientWidth:d.scroller.clientWidth,viewWidth:d.wrapper.clientWidth,barLeft:cm.options.fixedGutter?gutterW:0,docHeight:docH,scrollHeight:docH+scrollGap(cm)+d.barHeight,nativeBarWidth:d.nativeBarWidth,gutterWidth:gutterW}}function NativeScrollbars(place,scroll,cm){this.cm=cm;var vert=this.vert=elt("div",[elt("div",null,null,"min-width: 1px")],"CodeMirror-vscrollbar");var horiz=this.horiz=elt("div",[elt("div",null,null,"height: 100%; min-height: 1px")],"CodeMirror-hscrollbar");place(vert);place(horiz);on(vert,"scroll",function(){if(vert.clientHeight){scroll(vert.scrollTop,"vertical")}});on(horiz,"scroll",function(){if(horiz.clientWidth){scroll(horiz.scrollLeft,"horizontal")}});this.checkedOverlay=false;if(ie&&ie_version<8){this.horiz.style.minHeight=this.vert.style.minWidth="18px"}}NativeScrollbars.prototype=copyObj({update:function(measure){var needsH=measure.scrollWidth>measure.clientWidth+1;var needsV=measure.scrollHeight>measure.clientHeight+1;var sWidth=measure.nativeBarWidth;if(needsV){this.vert.style.display="block";this.vert.style.bottom=needsH?sWidth+"px":"0";var totalHeight=measure.viewHeight-(needsH?sWidth:0);this.vert.firstChild.style.height=Math.max(0,measure.scrollHeight-measure.clientHeight+totalHeight)+"px" -}else{this.vert.style.display="";this.vert.firstChild.style.height="0"}if(needsH){this.horiz.style.display="block";this.horiz.style.right=needsV?sWidth+"px":"0";this.horiz.style.left=measure.barLeft+"px";var totalWidth=measure.viewWidth-measure.barLeft-(needsV?sWidth:0);this.horiz.firstChild.style.width=(measure.scrollWidth-measure.clientWidth+totalWidth)+"px"}else{this.horiz.style.display="";this.horiz.firstChild.style.width="0"}if(!this.checkedOverlay&&measure.clientHeight>0){if(sWidth==0){this.overlayHack()}this.checkedOverlay=true}return{right:needsV?sWidth:0,bottom:needsH?sWidth:0}},setScrollLeft:function(pos){if(this.horiz.scrollLeft!=pos){this.horiz.scrollLeft=pos}},setScrollTop:function(pos){if(this.vert.scrollTop!=pos){this.vert.scrollTop=pos}},overlayHack:function(){var w=mac&&!mac_geMountainLion?"12px":"18px";this.horiz.style.minHeight=this.vert.style.minWidth=w;var self=this;var barMouseDown=function(e){if(e_target(e)!=self.vert&&e_target(e)!=self.horiz){operation(self.cm,onMouseDown)(e)}};on(this.vert,"mousedown",barMouseDown);on(this.horiz,"mousedown",barMouseDown)},clear:function(){var parent=this.horiz.parentNode;parent.removeChild(this.horiz);parent.removeChild(this.vert)}},NativeScrollbars.prototype);function NullScrollbars(){}NullScrollbars.prototype=copyObj({update:function(){return{bottom:0,right:0}},setScrollLeft:function(){},setScrollTop:function(){},clear:function(){}},NullScrollbars.prototype);CodeMirror.scrollbarModel={"native":NativeScrollbars,"null":NullScrollbars};function initScrollbars(cm){if(cm.display.scrollbars){cm.display.scrollbars.clear();if(cm.display.scrollbars.addClass){rmClass(cm.display.wrapper,cm.display.scrollbars.addClass)}}cm.display.scrollbars=new CodeMirror.scrollbarModel[cm.options.scrollbarStyle](function(node){cm.display.wrapper.insertBefore(node,cm.display.scrollbarFiller);on(node,"mousedown",function(){if(cm.state.focused){setTimeout(function(){cm.display.input.focus()},0)}});node.setAttribute("cm-not-content","true")},function(pos,axis){if(axis=="horizontal"){setScrollLeft(cm,pos)}else{setScrollTop(cm,pos)}},cm);if(cm.display.scrollbars.addClass){addClass(cm.display.wrapper,cm.display.scrollbars.addClass)}}function updateScrollbars(cm,measure){if(!measure){measure=measureForScrollbars(cm)}var startWidth=cm.display.barWidth,startHeight=cm.display.barHeight;updateScrollbarsInner(cm,measure);for(var i=0;i<4&&startWidth!=cm.display.barWidth||startHeight!=cm.display.barHeight;i++){if(startWidth!=cm.display.barWidth&&cm.options.lineWrapping){updateHeightsInViewport(cm)}updateScrollbarsInner(cm,measureForScrollbars(cm));startWidth=cm.display.barWidth;startHeight=cm.display.barHeight}}function updateScrollbarsInner(cm,measure){var d=cm.display;var sizes=d.scrollbars.update(measure);d.sizer.style.paddingRight=(d.barWidth=sizes.right)+"px";d.sizer.style.paddingBottom=(d.barHeight=sizes.bottom)+"px";if(sizes.right&&sizes.bottom){d.scrollbarFiller.style.display="block";d.scrollbarFiller.style.height=sizes.bottom+"px";d.scrollbarFiller.style.width=sizes.right+"px"}else{d.scrollbarFiller.style.display=""}if(sizes.bottom&&cm.options.coverGutterNextToScrollbar&&cm.options.fixedGutter){d.gutterFiller.style.display="block";d.gutterFiller.style.height=sizes.bottom+"px";d.gutterFiller.style.width=measure.gutterWidth+"px"}else{d.gutterFiller.style.display=""}}function visibleLines(display,doc,viewport){var top=viewport&&viewport.top!=null?Math.max(0,viewport.top):display.scroller.scrollTop;top=Math.floor(top-paddingTop(display));var bottom=viewport&&viewport.bottom!=null?viewport.bottom:top+display.wrapper.clientHeight;var from=lineAtHeight(doc,top),to=lineAtHeight(doc,bottom);if(viewport&&viewport.ensure){var ensureFrom=viewport.ensure.from.line,ensureTo=viewport.ensure.to.line;if(ensureFrom=to){from=lineAtHeight(doc,heightAtLine(getLine(doc,ensureTo))-display.wrapper.clientHeight);to=ensureTo}}}return{from:from,to:Math.max(to,from+1)}}function alignHorizontally(cm){var display=cm.display,view=display.view;if(!display.alignWidgets&&(!display.gutters.firstChild||!cm.options.fixedGutter)){return}var comp=compensateForHScroll(display)-display.scroller.scrollLeft+cm.doc.scrollLeft;var gutterW=display.gutters.offsetWidth,left=comp+"px";for(var i=0;i=display.viewFrom&&update.visible.to<=display.viewTo&&(display.updateLineNumbers==null||display.updateLineNumbers>=display.viewTo)&&display.renderedView==display.view&&countDirtyView(cm)==0){return false}if(maybeUpdateLineNumberWidth(cm)){resetView(cm);update.dims=getDimensions(cm)}var end=doc.first+doc.size;var from=Math.max(update.visible.from-cm.options.viewportMargin,doc.first);var to=Math.min(end,update.visible.to+cm.options.viewportMargin);if(display.viewFromto&&display.viewTo-to<20){to=Math.min(end,display.viewTo)}if(sawCollapsedSpans){from=visualLineNo(cm.doc,from);to=visualLineEndNo(cm.doc,to)}var different=from!=display.viewFrom||to!=display.viewTo||display.lastWrapHeight!=update.wrapperHeight||display.lastWrapWidth!=update.wrapperWidth;adjustView(cm,from,to);display.viewOffset=heightAtLine(getLine(cm.doc,display.viewFrom));cm.display.mover.style.top=display.viewOffset+"px";var toUpdate=countDirtyView(cm);if(!different&&toUpdate==0&&!update.force&&display.renderedView==display.view&&(display.updateLineNumbers==null||display.updateLineNumbers>=display.viewTo)){return false}var focused=activeElt();if(toUpdate>4){display.lineDiv.style.display="none"}patchDisplay(cm,display.updateLineNumbers,update.dims);if(toUpdate>4){display.lineDiv.style.display=""}display.renderedView=display.view;if(focused&&activeElt()!=focused&&focused.offsetHeight){focused.focus()}removeChildren(display.cursorDiv);removeChildren(display.selectionDiv);display.gutters.style.height=0;if(different){display.lastWrapHeight=update.wrapperHeight;display.lastWrapWidth=update.wrapperWidth;startWorker(cm,400)}display.updateLineNumbers=null;return true}function postUpdateDisplay(cm,update){var force=update.force,viewport=update.viewport;for(var first=true;;first=false){if(first&&cm.options.lineWrapping&&update.oldDisplayWidth!=displayWidth(cm)){force=true}else{force=false;if(viewport&&viewport.top!=null){viewport={top:Math.min(cm.doc.height+paddingVert(cm.display)-displayHeight(cm),viewport.top)}}update.visible=visibleLines(cm.display,cm.doc,viewport);if(update.visible.from>=cm.display.viewFrom&&update.visible.to<=cm.display.viewTo){break}}if(!updateDisplayIfNeeded(cm,update)){break}updateHeightsInViewport(cm);var barMeasure=measureForScrollbars(cm);updateSelection(cm);setDocumentHeight(cm,barMeasure);updateScrollbars(cm,barMeasure)}update.signal(cm,"update",cm);if(cm.display.viewFrom!=cm.display.reportedViewFrom||cm.display.viewTo!=cm.display.reportedViewTo){update.signal(cm,"viewportChange",cm,cm.display.viewFrom,cm.display.viewTo);cm.display.reportedViewFrom=cm.display.viewFrom;cm.display.reportedViewTo=cm.display.viewTo}}function updateDisplaySimple(cm,viewport){var update=new DisplayUpdate(cm,viewport);if(updateDisplayIfNeeded(cm,update)){updateHeightsInViewport(cm);postUpdateDisplay(cm,update);var barMeasure=measureForScrollbars(cm);updateSelection(cm);setDocumentHeight(cm,barMeasure);updateScrollbars(cm,barMeasure);update.finish()}}function setDocumentHeight(cm,measure){cm.display.sizer.style.minHeight=measure.docHeight+"px";var total=measure.docHeight+cm.display.barHeight; -cm.display.heightForcer.style.top=total+"px";cm.display.gutters.style.height=Math.max(total+scrollGap(cm),measure.clientHeight)+"px"}function updateHeightsInViewport(cm){var display=cm.display;var prevBottom=display.lineDiv.offsetTop;for(var i=0;i0.001||diff<-0.001){updateLineHeight(cur.line,height);updateWidgetHeight(cur.line);if(cur.rest){for(var j=0;j-1){updateNumber=false}updateLineForChanges(cm,lineView,lineN,dims)}if(updateNumber){removeChildren(lineView.lineNumber);lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options,lineN)))}cur=lineView.node.nextSibling}}lineN+=lineView.size}while(cur){cur=rm(cur)}}function updateLineForChanges(cm,lineView,lineN,dims){for(var j=0;j1){if(lastCopied&&lastCopied.join("\n")==inserted){multiPaste=sel.ranges.length%lastCopied.length==0&&map(lastCopied,splitLines)}else{if(textLines.length==sel.ranges.length){multiPaste=map(textLines,function(l){return[l]})}}}for(var i=sel.ranges.length-1;i>=0;i--){var range=sel.ranges[i];var from=range.from(),to=range.to();if(range.empty()){if(deleted&&deleted>0){from=Pos(from.line,from.ch-deleted)}else{if(cm.state.overwrite&&!cm.state.pasteIncoming){to=Pos(to.line,Math.min(getLine(doc,to.line).text.length,to.ch+lst(textLines).length))}}}var updateInput=cm.curOp.updateInput;var changeEvent={from:from,to:to,text:multiPaste?multiPaste[i%multiPaste.length]:textLines,origin:cm.state.pasteIncoming?"paste":cm.state.cutIncoming?"cut":"+input"};makeChange(cm.doc,changeEvent);signalLater(cm,"inputRead",cm,changeEvent);if(inserted&&!cm.state.pasteIncoming&&cm.options.electricChars&&cm.options.smartIndent&&range.head.ch<100&&(!i||sel.ranges[i-1].head.line!=range.head.line)){var mode=cm.getModeAt(range.head);var end=changeEnd(changeEvent);if(mode.electricChars){for(var j=0;j-1){indentLine(cm,end.line,"smart");break}}}else{if(mode.electricInput){if(mode.electricInput.test(getLine(doc,end.line).text.slice(0,end.ch))){indentLine(cm,end.line,"smart")}}}}}ensureCursorVisible(cm);cm.curOp.updateInput=updateInput;cm.curOp.typing=true;cm.state.pasteIncoming=cm.state.cutIncoming=false}function copyableRanges(cm){var text=[],ranges=[];for(var i=0;i=9&&input.hasSelection){input.hasSelection=null}input.poll()});on(te,"paste",function(){if(webkit&&!cm.state.fakedLastChar&&!(new Date-cm.state.lastMiddleDown<200)){var start=te.selectionStart,end=te.selectionEnd;te.value+="$";te.selectionEnd=end;te.selectionStart=start;cm.state.fakedLastChar=true}cm.state.pasteIncoming=true;input.fastPoll()});function prepareCopyCut(e){if(cm.somethingSelected()){lastCopied=cm.getSelections();if(input.inaccurateSelection){input.prevInput="";input.inaccurateSelection=false;te.value=lastCopied.join("\n");selectInput(te)}}else{var ranges=copyableRanges(cm);lastCopied=ranges.text;if(e.type=="cut"){cm.setSelections(ranges.ranges,null,sel_dontScroll)}else{input.prevInput="";te.value=ranges.text.join("\n");selectInput(te)}}if(e.type=="cut"){cm.state.cutIncoming=true}}on(te,"cut",prepareCopyCut);on(te,"copy",prepareCopyCut);on(display.scroller,"paste",function(e){if(eventInWidget(display,e)){return}cm.state.pasteIncoming=true;input.focus()});on(display.lineSpace,"selectstart",function(e){if(!eventInWidget(display,e)){e_preventDefault(e)}})},prepareSelection:function(){var cm=this.cm,display=cm.display,doc=cm.doc;var result=prepareSelection(cm);if(cm.options.moveInputWithCursor){var headPos=cursorCoords(cm,doc.sel.primary().head,"div");var wrapOff=display.wrapper.getBoundingClientRect(),lineOff=display.lineDiv.getBoundingClientRect();result.teTop=Math.max(0,Math.min(display.wrapper.clientHeight-10,headPos.top+lineOff.top-wrapOff.top));result.teLeft=Math.max(0,Math.min(display.wrapper.clientWidth-10,headPos.left+lineOff.left-wrapOff.left))}return result},showSelection:function(drawn){var cm=this.cm,display=cm.display;removeChildrenAndAdd(display.cursorDiv,drawn.cursors);removeChildrenAndAdd(display.selectionDiv,drawn.selection);if(drawn.teTop!=null){this.wrapper.style.top=drawn.teTop+"px";this.wrapper.style.left=drawn.teLeft+"px"}},reset:function(typing){if(this.contextMenuPending){return}var minimal,selected,cm=this.cm,doc=cm.doc;if(cm.somethingSelected()){this.prevInput="";var range=doc.sel.primary();minimal=hasCopyEvent&&(range.to().line-range.from().line>100||(selected=cm.getSelection()).length>1000);var content=minimal?"-":selected||cm.getSelection();this.textarea.value=content;if(cm.state.focused){selectInput(this.textarea)}if(ie&&ie_version>=9){this.hasSelection=content}}else{if(!typing){this.prevInput=this.textarea.value="";if(ie&&ie_version>=9){this.hasSelection=null}}}this.inaccurateSelection=minimal},getField:function(){return this.textarea},supportsTouch:function(){return false},focus:function(){if(this.cm.options.readOnly!="nocursor"&&(!mobile||activeElt()!=this.textarea)){try{this.textarea.focus()}catch(e){}}},blur:function(){this.textarea.blur()},resetPosition:function(){this.wrapper.style.top=this.wrapper.style.left=0},receivedFocus:function(){this.slowPoll()},slowPoll:function(){var input=this;if(input.pollingFast){return}input.polling.set(this.cm.options.pollInterval,function(){input.poll();if(input.cm.state.focused){input.slowPoll()}})},fastPoll:function(){var missed=false,input=this;input.pollingFast=true;function p(){var changed=input.poll();if(!changed&&!missed){missed=true;input.polling.set(60,p)}else{input.pollingFast=false;input.slowPoll()}}input.polling.set(20,p)},poll:function(){var cm=this.cm,input=this.textarea,prevInput=this.prevInput;if(!cm.state.focused||(hasSelection(input)&&!prevInput)||isReadOnly(cm)||cm.options.disableInput||cm.state.keySeq){return false}if(cm.state.pasteIncoming&&cm.state.fakedLastChar){input.value=input.value.substring(0,input.value.length-1);cm.state.fakedLastChar=false}var text=input.value;if(text==prevInput&&!cm.somethingSelected()){return false}if(ie&&ie_version>=9&&this.hasSelection===text||mac&&/[\uf700-\uf7ff]/.test(text)){cm.display.input.reset();return false}if(text.charCodeAt(0)==8203&&cm.doc.sel==cm.display.selForContextMenu&&!prevInput){prevInput="\u200b" -}var same=0,l=Math.min(prevInput.length,text.length);while(same1000||text.indexOf("\n")>-1){input.value=self.prevInput=""}else{self.prevInput=text}});return true},ensurePolled:function(){if(this.pollingFast&&this.poll()){this.pollingFast=false}},onKeyPress:function(){if(ie&&ie_version>=9){this.hasSelection=null}this.fastPoll()},onContextMenu:function(e){var input=this,cm=input.cm,display=cm.display,te=input.textarea;var pos=posFromMouse(cm,e),scrollPos=display.scroller.scrollTop;if(!pos||presto){return}var reset=cm.options.resetSelectionOnContextMenu;if(reset&&cm.doc.sel.contains(pos)==-1){operation(cm,setSelection)(cm.doc,simpleSelection(pos),sel_dontScroll)}var oldCSS=te.style.cssText;input.wrapper.style.position="absolute";te.style.cssText="position: fixed; width: 30px; height: 30px; top: "+(e.clientY-5)+"px; left: "+(e.clientX-5)+"px; z-index: 1000; background: "+(ie?"rgba(255, 255, 255, .05)":"transparent")+"; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";if(webkit){var oldScrollY=window.scrollY}display.input.focus();if(webkit){window.scrollTo(null,oldScrollY)}display.input.reset();if(!cm.somethingSelected()){te.value=input.prevInput=" "}input.contextMenuPending=true;display.selForContextMenu=cm.doc.sel;clearTimeout(display.detectingSelectAll);function prepareSelectAllHack(){if(te.selectionStart!=null){var selected=cm.somethingSelected();var extval=te.value="\u200b"+(selected?te.value:"");input.prevInput=selected?"":"\u200b";te.selectionStart=1;te.selectionEnd=extval.length;display.selForContextMenu=cm.doc.sel}}function rehide(){input.contextMenuPending=false;input.wrapper.style.position="relative";te.style.cssText=oldCSS;if(ie&&ie_version<9){display.scrollbars.setScrollTop(display.scroller.scrollTop=scrollPos)}if(te.selectionStart!=null){if(!ie||(ie&&ie_version<9)){prepareSelectAllHack()}var i=0,poll=function(){if(display.selForContextMenu==cm.doc.sel&&te.selectionStart==0){operation(cm,commands.selectAll)(cm)}else{if(i++<10){display.detectingSelectAll=setTimeout(poll,500)}else{display.input.reset()}}};display.detectingSelectAll=setTimeout(poll,200)}}if(ie&&ie_version>=9){prepareSelectAllHack()}if(captureRightClick){e_stop(e);var mouseup=function(){off(window,"mouseup",mouseup);setTimeout(rehide,20)};on(window,"mouseup",mouseup)}else{setTimeout(rehide,50)}},setUneditable:nothing,needsContentAttribute:false},TextareaInput.prototype);function ContentEditableInput(cm){this.cm=cm;this.lastAnchorNode=this.lastAnchorOffset=this.lastFocusNode=this.lastFocusOffset=null;this.polling=new Delayed()}ContentEditableInput.prototype=copyObj({init:function(display){var input=this,cm=input.cm;var div=input.div=display.lineDiv;div.contentEditable="true";disableBrowserMagic(div);on(div,"paste",function(e){var pasted=e.clipboardData&&e.clipboardData.getData("text/plain");if(pasted){e.preventDefault();cm.replaceSelection(pasted,null,"paste")}});on(div,"compositionstart",function(e){var data=e.data;input.composing={sel:cm.doc.sel,data:data,startData:data};if(!data){return}var prim=cm.doc.sel.primary();var line=cm.getLine(prim.head.line);var found=line.indexOf(data,Math.max(0,prim.head.ch-data.length));if(found>-1&&found<=prim.head.ch){input.composing.sel=simpleSelection(Pos(prim.head.line,found),Pos(prim.head.line,found+data.length))}});on(div,"compositionupdate",function(e){input.composing.data=e.data});on(div,"compositionend",function(e){var ours=input.composing;if(!ours){return}if(e.data!=ours.startData&&!/\u200b/.test(e.data)){ours.data=e.data}setTimeout(function(){if(!ours.handled){input.applyComposition(ours)}if(input.composing==ours){input.composing=null}},50)});on(div,"touchstart",function(){input.forceCompositionEnd()});on(div,"input",function(){if(input.composing){return}if(!input.pollContent()){runInOp(input.cm,function(){regChange(cm)})}});function onCopyCut(e){if(cm.somethingSelected()){lastCopied=cm.getSelections();if(e.type=="cut"){cm.replaceSelection("",null,"cut")}}else{var ranges=copyableRanges(cm);lastCopied=ranges.text;if(e.type=="cut"){cm.operation(function(){cm.setSelections(ranges.ranges,0,sel_dontScroll);cm.replaceSelection("",null,"cut")})}}if(e.clipboardData&&!ios){e.preventDefault();e.clipboardData.clearData();e.clipboardData.setData("text/plain",lastCopied.join("\n"))}else{var kludge=hiddenTextarea(),te=kludge.firstChild;cm.display.lineSpace.insertBefore(kludge,cm.display.lineSpace.firstChild);te.value=lastCopied.join("\n");var hadFocus=document.activeElement;selectInput(te);setTimeout(function(){cm.display.lineSpace.removeChild(kludge);hadFocus.focus()},50)}}on(div,"copy",onCopyCut);on(div,"cut",onCopyCut)},prepareSelection:function(){var result=prepareSelection(this.cm,false);result.focus=this.cm.state.focused;return result},showSelection:function(info){if(!info||!this.cm.display.view.length){return -}if(info.focus){this.showPrimarySelection()}this.showMultipleSelections(info)},showPrimarySelection:function(){var sel=window.getSelection(),prim=this.cm.doc.sel.primary();var curAnchor=domToPos(this.cm,sel.anchorNode,sel.anchorOffset);var curFocus=domToPos(this.cm,sel.focusNode,sel.focusOffset);if(curAnchor&&!curAnchor.bad&&curFocus&&!curFocus.bad&&cmp(minPos(curAnchor,curFocus),prim.from())==0&&cmp(maxPos(curAnchor,curFocus),prim.to())==0){return}var start=posToDOM(this.cm,prim.from());var end=posToDOM(this.cm,prim.to());if(!start&&!end){return}var view=this.cm.display.view;var old=sel.rangeCount&&sel.getRangeAt(0);if(!start){start={node:view[0].measure.map[2],offset:0}}else{if(!end){var measure=view[view.length-1].measure;var map=measure.maps?measure.maps[measure.maps.length-1]:measure.map;end={node:map[map.length-1],offset:map[map.length-2]-map[map.length-3]}}}try{var rng=range(start.node,start.offset,end.offset,end.node)}catch(e){}if(rng){sel.removeAllRanges();sel.addRange(rng);if(old&&sel.anchorNode==null){sel.addRange(old)}}this.rememberSelection()},showMultipleSelections:function(info){removeChildrenAndAdd(this.cm.display.cursorDiv,info.cursors);removeChildrenAndAdd(this.cm.display.selectionDiv,info.selection)},rememberSelection:function(){var sel=window.getSelection();this.lastAnchorNode=sel.anchorNode;this.lastAnchorOffset=sel.anchorOffset;this.lastFocusNode=sel.focusNode;this.lastFocusOffset=sel.focusOffset},selectionInEditor:function(){var sel=window.getSelection();if(!sel.rangeCount){return false}var node=sel.getRangeAt(0).commonAncestorContainer;return contains(this.div,node)},focus:function(){if(this.cm.options.readOnly!="nocursor"){this.div.focus()}},blur:function(){this.div.blur()},getField:function(){return this.div},supportsTouch:function(){return true},receivedFocus:function(){var input=this;if(this.selectionInEditor()){this.pollSelection()}else{runInOp(this.cm,function(){input.cm.curOp.selectionChanged=true})}function poll(){if(input.cm.state.focused){input.pollSelection();input.polling.set(input.cm.options.pollInterval,poll)}}this.polling.set(this.cm.options.pollInterval,poll)},pollSelection:function(){if(this.composing){return}var sel=window.getSelection(),cm=this.cm;if(sel.anchorNode!=this.lastAnchorNode||sel.anchorOffset!=this.lastAnchorOffset||sel.focusNode!=this.lastFocusNode||sel.focusOffset!=this.lastFocusOffset){this.rememberSelection();var anchor=domToPos(cm,sel.anchorNode,sel.anchorOffset);var head=domToPos(cm,sel.focusNode,sel.focusOffset);if(anchor&&head){runInOp(cm,function(){setSelection(cm.doc,simpleSelection(anchor,head),sel_dontScroll);if(anchor.bad||head.bad){cm.curOp.selectionChanged=true}})}}},pollContent:function(){var cm=this.cm,display=cm.display,sel=cm.doc.sel.primary();var from=sel.from(),to=sel.to();if(from.linedisplay.viewTo-1){return false}var fromIndex;if(from.line==display.viewFrom||(fromIndex=findViewIndex(cm,from.line))==0){var fromLine=lineNo(display.view[0].line);var fromNode=display.view[0].node}else{var fromLine=lineNo(display.view[fromIndex].line);var fromNode=display.view[fromIndex-1].node.nextSibling}var toIndex=findViewIndex(cm,to.line);if(toIndex==display.view.length-1){var toLine=display.viewTo-1;var toNode=display.view[toIndex].node}else{var toLine=lineNo(display.view[toIndex+1].line)-1;var toNode=display.view[toIndex+1].node.previousSibling}var newText=splitLines(domTextBetween(cm,fromNode,toNode,fromLine,toLine));var oldText=getBetween(cm.doc,Pos(fromLine,0),Pos(toLine,getLine(cm.doc,toLine).text.length));while(newText.length>1&&oldText.length>1){if(lst(newText)==lst(oldText)){newText.pop();oldText.pop();toLine--}else{if(newText[0]==oldText[0]){newText.shift();oldText.shift();fromLine++}else{break}}}var cutFront=0,cutEnd=0;var newTop=newText[0],oldTop=oldText[0],maxCutFront=Math.min(newTop.length,oldTop.length);while(cutFront1||newText[0]||cmp(chFrom,chTo)){replaceRange(cm.doc,newText,chFrom,chTo,"+input");return true}},ensurePolled:function(){this.forceCompositionEnd()},reset:function(){this.forceCompositionEnd()},forceCompositionEnd:function(){if(!this.composing||this.composing.handled){return}this.applyComposition(this.composing);this.composing.handled=true;this.div.blur();this.div.focus()},applyComposition:function(composing){if(composing.data&&composing.data!=composing.startData){operation(this.cm,applyTextInput)(this.cm,composing.data,0,composing.sel) -}},setUneditable:function(node){node.setAttribute("contenteditable","false")},onKeyPress:function(e){e.preventDefault();operation(this.cm,applyTextInput)(this.cm,String.fromCharCode(e.charCode==null?e.keyCode:e.charCode),0)},onContextMenu:nothing,resetPosition:nothing,needsContentAttribute:true},ContentEditableInput.prototype);function posToDOM(cm,pos){var view=findViewForLine(cm,pos.line);if(!view||view.hidden){return null}var line=getLine(cm.doc,pos.line);var info=mapFromLineView(view,line,pos.line);var order=getOrder(line),side="left";if(order){var partPos=getBidiPartAt(order,pos.ch);side=partPos%2?"right":"left"}var result=nodeAndOffsetInLineMap(info.map,pos.ch,"left");result.offset=result.collapse=="right"?result.end:result.start;return result}function badPos(pos,bad){if(bad){pos.bad=true}return pos}function domToPos(cm,node,offset){var lineNode;if(node==cm.display.lineDiv){lineNode=cm.display.lineDiv.childNodes[offset];if(!lineNode){return badPos(cm.clipPos(Pos(cm.display.viewTo-1)),true)}node=null;offset=0}else{for(lineNode=node;;lineNode=lineNode.parentNode){if(!lineNode||lineNode==cm.display.lineDiv){return null}if(lineNode.parentNode&&lineNode.parentNode==cm.display.lineDiv){break}}}for(var i=0;i=0&&cmp(pos,range.to())<=0){return i}}return -1}};function Range(anchor,head){this.anchor=anchor;this.head=head -}Range.prototype={from:function(){return minPos(this.anchor,this.head)},to:function(){return maxPos(this.anchor,this.head)},empty:function(){return this.head.line==this.anchor.line&&this.head.ch==this.anchor.ch}};function normalizeSelection(ranges,primIndex){var prim=ranges[primIndex];ranges.sort(function(a,b){return cmp(a.from(),b.from())});primIndex=indexOf(ranges,prim);for(var i=1;i=0){var from=minPos(prev.from(),cur.from()),to=maxPos(prev.to(),cur.to());var inv=prev.empty()?cur.from()==cur.head:prev.from()==prev.head;if(i<=primIndex){--primIndex}ranges.splice(--i,2,new Range(inv?to:from,inv?from:to))}}return new Selection(ranges,primIndex)}function simpleSelection(anchor,head){return new Selection([new Range(anchor,head||anchor)],0)}function clipLine(doc,n){return Math.max(doc.first,Math.min(n,doc.first+doc.size-1))}function clipPos(doc,pos){if(pos.linelast){return Pos(last,getLine(doc,last).text.length)}return clipToLen(pos,getLine(doc,pos.line).text.length)}function clipToLen(pos,linelen){var ch=pos.ch;if(ch==null||ch>linelen){return Pos(pos.line,linelen)}else{if(ch<0){return Pos(pos.line,0)}else{return pos}}}function isLine(doc,l){return l>=doc.first&&l=curPos.ch:sp.to>curPos.ch))){if(mayClear){signal(m,"beforeCursorEnter");if(m.explicitlyCleared){if(!line.markedSpans){break}else{--i;continue}}}if(!m.atomic){continue}var newPos=m.find(dir<0?-1:1);if(cmp(newPos,curPos)==0){newPos.ch+=dir; -if(newPos.ch<0){if(newPos.line>doc.first){newPos=clipPos(doc,Pos(newPos.line-1))}else{newPos=null}}else{if(newPos.ch>line.text.length){if(newPos.line3){add(left,leftPos.top,null,leftPos.bottom);left=leftSide;if(leftPos.bottomend.bottom||rightPos.bottom==end.bottom&&rightPos.right>end.right){end=rightPos}if(left0){display.blinker=setInterval(function(){display.cursorDiv.style.visibility=(on=!on)?"":"hidden"},cm.options.cursorBlinkRate)}else{if(cm.options.cursorBlinkRate<0){display.cursorDiv.style.visibility="hidden"}}}function startWorker(cm,time){if(cm.doc.mode.startState&&cm.doc.frontier=cm.display.viewTo){return}var end=+new Date+cm.options.workTime;var state=copyState(doc.mode,getStateBefore(cm,doc.frontier));var changedLines=[];doc.iter(doc.frontier,Math.min(doc.first+doc.size,cm.display.viewTo+500),function(line){if(doc.frontier>=cm.display.viewFrom){var oldStyles=line.styles; -var highlighted=highlightLine(cm,line,state,true);line.styles=highlighted.styles;var oldCls=line.styleClasses,newCls=highlighted.classes;if(newCls){line.styleClasses=newCls}else{if(oldCls){line.styleClasses=null}}var ischange=!oldStyles||oldStyles.length!=line.styles.length||oldCls!=newCls&&(!oldCls||!newCls||oldCls.bgClass!=newCls.bgClass||oldCls.textClass!=newCls.textClass);for(var i=0;!ischange&&iend){startWorker(cm,cm.options.workDelay);return true}});if(changedLines.length){runInOp(cm,function(){for(var i=0;ilim;--search){if(search<=doc.first){return doc.first}var line=getLine(doc,search-1);if(line.stateAfter&&(!precise||search<=doc.frontier)){return search}var indented=countColumn(line.text,null,cm.options.tabSize);if(minline==null||minindent>indented){minline=search-1;minindent=indented}}return minline}function getStateBefore(cm,n,precise){var doc=cm.doc,display=cm.display;if(!doc.mode.startState){return true}var pos=findStartLine(cm,n,precise),state=pos>doc.first&&getLine(doc,pos-1).stateAfter;if(!state){state=startState(doc.mode)}else{state=copyState(doc.mode,state)}doc.iter(pos,n,function(line){processLine(cm,line.text,state);var save=pos==n-1||pos%5==0||pos>=display.viewFrom&&pos2){heights.push((cur.bottom+next.top)/2-rect.top)}}}heights.push(rect.bottom-rect.top)}}function mapFromLineView(lineView,line,lineN){if(lineView.line==line){return{map:lineView.measure.map,cache:lineView.measure.cache}}for(var i=0;ilineN){return{map:lineView.measure.maps[i],cache:lineView.measure.caches[i],before:true}}}}function updateExternalMeasurement(cm,line){line=visualLine(line);var lineN=lineNo(line);var view=cm.display.externalMeasured=new LineView(cm.doc,line,lineN);view.lineN=lineN;var built=view.built=buildLineContent(cm,view);view.text=built.pre;removeChildrenAndAdd(cm.display.lineMeasure,built.pre);return view}function measureChar(cm,line,ch,bias){return measureCharPrepared(cm,prepareMeasureForLine(cm,line),ch,bias)}function findViewForLine(cm,lineN){if(lineN>=cm.display.viewFrom&&lineN=ext.lineN&&lineNch){end=mEnd-mStart;start=end-1;if(ch>=mEnd){collapse="right"}}}}if(start!=null){node=map[i+2];if(mStart==mEnd&&bias==(node.insertLeft?"left":"right")){collapse=bias}if(bias=="left"&&start==0){while(i&&map[i-2]==map[i-3]&&map[i-1].insertLeft){node=map[(i-=3)+2];collapse="left"}}if(bias=="right"&&start==mEnd-mStart){while(i0){collapse=bias="right"}var rects;if(cm.options.lineWrapping&&(rects=node.getClientRects()).length>1){rect=rects[bias=="right"?rects.length-1:0]}else{rect=node.getBoundingClientRect()}}if(ie&&ie_version<9&&!start&&(!rect||!rect.left&&!rect.right)){var rSpan=node.parentNode.getClientRects()[0];if(rSpan){rect={left:rSpan.left,right:rSpan.left+charWidth(cm.display),top:rSpan.top,bottom:rSpan.bottom}}else{rect=nullRect}}var rtop=rect.top-prepared.rect.top,rbot=rect.bottom-prepared.rect.top;var mid=(rtop+rbot)/2;var heights=prepared.view.measure.heights;for(var i=0;ipart.from){return get(ch-1)}return get(ch,right)}var order=getOrder(lineObj),ch=pos.ch;if(!order){return get(ch)}var partPos=getBidiPartAt(order,ch);var val=getBidi(ch,partPos);if(bidiOther!=null){val.other=getBidi(ch,bidiOther)}return val}function estimateCoords(cm,pos){var left=0,pos=clipPos(cm.doc,pos);if(!cm.options.lineWrapping){left=charWidth(cm.display)*pos.ch}var lineObj=getLine(cm.doc,pos.line);var top=heightAtLine(lineObj)+paddingTop(cm.display);return{left:left,right:left,top:top,bottom:top+lineObj.height}}function PosWithInfo(line,ch,outside,xRel){var pos=Pos(line,ch);pos.xRel=xRel;if(outside){pos.outside=true}return pos}function coordsChar(cm,x,y){var doc=cm.doc;y+=cm.display.viewOffset;if(y<0){return PosWithInfo(doc.first,0,true,-1)}var lineN=lineAtHeight(doc,y),last=doc.first+doc.size-1;if(lineN>last){return PosWithInfo(doc.first+doc.size-1,getLine(doc,last).text.length,true,1)}if(x<0){x=0}var lineObj=getLine(doc,lineN);for(;;){var found=coordsCharInner(cm,lineObj,lineN,x,y);var merged=collapsedSpanAtEnd(lineObj);var mergedPos=merged&&merged.find(0,true);if(merged&&(found.ch>mergedPos.from.ch||found.ch==mergedPos.from.ch&&found.xRel>0)){lineN=lineNo(lineObj=mergedPos.to.line)}else{return found}}}function coordsCharInner(cm,lineObj,lineNo,x,y){var innerOff=y-heightAtLine(lineObj);var wrongLine=false,adjust=2*cm.display.wrapper.clientWidth;var preparedMeasure=prepareMeasureForLine(cm,lineObj);function getX(ch){var sp=cursorCoords(cm,Pos(lineNo,ch),"line",lineObj,preparedMeasure);wrongLine=true;if(innerOff>sp.bottom){return sp.left-adjust}else{if(innerOfftoX){return PosWithInfo(lineNo,to,toOutside,1)}for(;;){if(bidi?to==from||to==moveVisually(lineObj,from,1):to-from<=1){var ch=x1?1:0);return pos}var step=Math.ceil(dist/2),middle=from+step;if(bidi){middle=from;for(var i=0;ix){to=middle;toX=middleX;if(toOutside=wrongLine){toX+=1000}dist=step}else{from=middle;fromX=middleX;fromOutside=wrongLine;dist-=step}}}var measureText;function textHeight(display){if(display.cachedTextHeight!=null){return display.cachedTextHeight}if(measureText==null){measureText=elt("pre");for(var i=0;i<49;++i){measureText.appendChild(document.createTextNode("x"));measureText.appendChild(elt("br"))}measureText.appendChild(document.createTextNode("x"))}removeChildrenAndAdd(display.measure,measureText);var height=measureText.offsetHeight/50;if(height>3){display.cachedTextHeight=height}removeChildren(display.measure);return height||1}function charWidth(display){if(display.cachedCharWidth!=null){return display.cachedCharWidth}var anchor=elt("span","xxxxxxxxxx");var pre=elt("pre",[anchor]);removeChildrenAndAdd(display.measure,pre);var rect=anchor.getBoundingClientRect(),width=(rect.right-rect.left)/10;if(width>2){display.cachedCharWidth=width}return width||10}var operationGroup=null;var nextOpId=0;function startOperation(cm){cm.curOp={cm:cm,viewChanged:false,startHeight:cm.doc.height,forceUpdate:false,updateInput:null,typing:false,changeObjs:null,cursorActivityHandlers:null,cursorActivityCalled:0,selectionChanged:false,updateMaxLine:false,scrollLeft:null,scrollTop:null,scrollToPos:null,id:++nextOpId};if(operationGroup){operationGroup.ops.push(cm.curOp)}else{cm.curOp.ownsGroup=operationGroup={ops:[cm.curOp],delayedCallbacks:[]}}}function fireCallbacksForOps(group){var callbacks=group.delayedCallbacks,i=0; -do{for(;i=display.viewTo)||display.maxLineChanged&&cm.options.lineWrapping;op.update=op.mustUpdate&&new DisplayUpdate(cm,op.mustUpdate&&{top:op.scrollTop,ensure:op.scrollToPos},op.forceUpdate)}function endOperation_W1(op){op.updatedDisplay=op.mustUpdate&&updateDisplayIfNeeded(op.cm,op.update)}function endOperation_R2(op){var cm=op.cm,display=cm.display;if(op.updatedDisplay){updateHeightsInViewport(cm)}op.barMeasure=measureForScrollbars(cm);if(display.maxLineChanged&&!cm.options.lineWrapping){op.adjustWidthTo=measureChar(cm,display.maxLine,display.maxLine.text.length).left+3;cm.display.sizerWidth=op.adjustWidthTo;op.barMeasure.scrollWidth=Math.max(display.scroller.clientWidth,display.sizer.offsetLeft+op.adjustWidthTo+scrollGap(cm)+cm.display.barWidth);op.maxScrollLeft=Math.max(0,display.sizer.offsetLeft+op.adjustWidthTo-displayWidth(cm))}if(op.updatedDisplay||op.selectionChanged){op.preparedSelection=display.input.prepareSelection()}}function endOperation_W2(op){var cm=op.cm;if(op.adjustWidthTo!=null){cm.display.sizer.style.minWidth=op.adjustWidthTo+"px";if(op.maxScrollLeft