MailChimp for WordPress - Version 4.3

Version Description

Download this release

Release Info

Developer DvanKooten
Plugin Icon 128x128 MailChimp for WordPress
Version 4.3
Comparing to
See all releases

Code changes from version 4.2.5 to 4.3

assets/css/admin-styles.min.css CHANGED
@@ -1 +1 @@
1
- #mc4wp-admin .cm-em,#mc4wp-admin .help,.mc4wp-admin .cm-em,.mc4wp-admin .help{font-style:italic}#mc4wp-admin .mc4wp-row,#mc4wp-admin .row,.mc4wp-admin .mc4wp-row,.mc4wp-admin .row{margin-left:-20px;margin-right:-20px;float:none}#mc4wp-admin .mc4wp-row .mc4wp-col,#mc4wp-admin .row .col,.mc4wp-admin .mc4wp-row .mc4wp-col,.mc4wp-admin .row .col{padding:0 20px;float:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#mc4wp-admin .mc4wp-row .mc4wp-col-1,#mc4wp-admin .row .col-1,.mc4wp-admin .mc4wp-row .mc4wp-col-1,.mc4wp-admin .row .col-1{width:16.666%}#mc4wp-admin .mc4wp-row .mc4wp-col-2,#mc4wp-admin .row .col-2,.mc4wp-admin .mc4wp-row .mc4wp-col-2,.mc4wp-admin .row .col-2{width:33.333%}#mc4wp-admin .mc4wp-row .mc4wp-col-3,#mc4wp-admin .row .col-3,.mc4wp-admin .mc4wp-row .mc4wp-col-3,.mc4wp-admin .row .col-3{width:50%}#mc4wp-admin .mc4wp-row .mc4wp-col-4,#mc4wp-admin .row .col-4,.mc4wp-admin .mc4wp-row .mc4wp-col-4,.mc4wp-admin .row .col-4{width:66.666%}#mc4wp-admin .mc4wp-row .mc4wp-col-5,#mc4wp-admin .row .col-5,.mc4wp-admin .mc4wp-row .mc4wp-col-5,.mc4wp-admin .row .col-5{width:83.333%}#mc4wp-admin .mc4wp-row .mc4wp-col-6,#mc4wp-admin .row .col-6,.mc4wp-admin .mc4wp-row .mc4wp-col-6,.mc4wp-admin .row .col-6{width:100%}#mc4wp-admin .clearfix:after,#mc4wp-admin .clearfix:before,#mc4wp-admin .mc4wp-row:after,#mc4wp-admin .mc4wp-row:before,#mc4wp-admin .row:after,#mc4wp-admin .row:before,.mc4wp-admin .clearfix:after,.mc4wp-admin .clearfix:before,.mc4wp-admin .mc4wp-row:after,.mc4wp-admin .mc4wp-row:before,.mc4wp-admin .row:after,.mc4wp-admin .row:before{content:" ";display:table}#mc4wp-admin .clearfix:after,#mc4wp-admin .mc4wp-row:after,#mc4wp-admin .row:after,.mc4wp-admin .clearfix:after,.mc4wp-admin .mc4wp-row:after,.mc4wp-admin .row:after{clear:both}@media (max-width:1200px){#mc4wp-admin .mc4wp-row .mc4wp-col,#mc4wp-admin .row .col,.mc4wp-admin .mc4wp-row .mc4wp-col,.mc4wp-admin .row .col{width:100%;float:none;margin:10px 0}}#mc4wp-admin .status,.mc4wp-admin .status{display:inline-block;margin-left:1em;padding:3px 6px;color:#fff;font-size:12px;font-weight:700}#mc4wp-admin .status.positive,.mc4wp-admin .status.positive{background-color:#32cd32}#mc4wp-admin .status.negative,.mc4wp-admin .status.negative{background-color:red}#mc4wp-admin .status.neutral,.mc4wp-admin .status.neutral{background:gray}#mc4wp-admin .valigntop,.mc4wp-admin .valigntop{vertical-align:top!important}#mc4wp-admin .big-margin,.mc4wp-admin .big-margin{margin-top:60px;margin-bottom:60px}#mc4wp-admin .medium-margin,.mc4wp-admin .medium-margin{margin-top:40px;margin-bottom:40px}#mc4wp-admin .small-margin,.mc4wp-admin .small-margin{margin-top:20px;margin-bottom:20px}#mc4wp-admin .tiny-margin,.mc4wp-admin .tiny-margin{margin-top:10px;margin-bottom:10px}#mc4wp-admin .hover-activated,.mc4wp-admin .hover-activated{opacity:.5}#mc4wp-admin .hover-activated:hover,.mc4wp-admin .hover-activated:hover{cursor:pointer;opacity:1}#mc4wp-admin .help-text,.mc4wp-admin .help-text{font-size:14px}#mc4wp-admin .help-text p,.mc4wp-admin .help-text p{margin:10px 0;font-size:14px}#mc4wp-admin .help-text ul,.mc4wp-admin .help-text ul{list-style:square;margin-top:15px;padding-left:40px}#mc4wp-admin .muted,.mc4wp-admin .muted{color:#aaa}#mc4wp-admin .red,.mc4wp-admin .red{color:red}#mc4wp-admin .green,.mc4wp-admin .green{color:#32cd32}#mc4wp-admin .mc4wp-notice,.mc4wp-admin .mc4wp-notice{padding:6px 12px;color:#31708f;background:#d9edf7;border:1px solid #bce8f1;margin:1em 0!important}#mc4wp-admin .mc4wp-is-dismissible,.mc4wp-admin .mc4wp-is-dismissible{padding-right:38px;position:relative}#mc4wp-admin .column-ID,.mc4wp-admin .column-ID{width:10%}#mc4wp-admin .block,.mc4wp-admin .block{display:block}#mc4wp-admin .code-sample,.mc4wp-admin .code-sample{font-family:Consolas,Monaco,Lucida Console,monospace;font-size:12px;background:#fff}#mc4wp-admin .breadcrumbs,.mc4wp-admin .breadcrumbs{border-bottom:1px solid #ccc;padding-bottom:1em}#mc4wp-admin .mc4wp-loader,.mc4wp-admin .mc4wp-loader{position:relative;display:inline-block;text-indent:-9999999px;border:3px solid rgba(0,0,0,.2);border-left-color:#000;-webkit-transform:translateZ(0);-ms-transform:translateZ(0);transform:translateZ(0);-webkit-animation:load8 1.1s infinite linear;animation:load8 1.1s infinite linear;overflow:hidden;border-radius:50%;vertical-align:middle;width:12px;height:12px;margin-bottom:3px;margin-left:3px;margin-right:3px}@-webkit-keyframes load8{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes load8{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}#mc4wp-admin .tab,.mc4wp-admin .tab{display:none;background:inherit;border:none;font-weight:initial}#mc4wp-admin .tab.tab-active,.mc4wp-admin .tab.tab-active{display:block}#mc4wp-admin .tab h2,.mc4wp-admin .tab h2{margin-top:20px}#mc4wp-admin .CodeMirror,.mc4wp-admin .CodeMirror{font-family:monospace;height:300px;color:#000;direction:ltr}#mc4wp-admin .CodeMirror-lines,.mc4wp-admin .CodeMirror-lines{padding:4px 0}#mc4wp-admin .CodeMirror pre,.mc4wp-admin .CodeMirror pre{padding:0 4px}#mc4wp-admin .CodeMirror-gutter-filler,#mc4wp-admin .CodeMirror-scrollbar-filler,.mc4wp-admin .CodeMirror-gutter-filler,.mc4wp-admin .CodeMirror-scrollbar-filler{background-color:#fff}#mc4wp-admin .CodeMirror-gutters,.mc4wp-admin .CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}#mc4wp-admin .CodeMirror-linenumber,.mc4wp-admin .CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;white-space:nowrap}#mc4wp-admin .CodeMirror-guttermarker,.mc4wp-admin .CodeMirror-guttermarker{color:#000}#mc4wp-admin .CodeMirror-guttermarker-subtle,.mc4wp-admin .CodeMirror-guttermarker-subtle{color:#999}#mc4wp-admin .CodeMirror-cursor,.mc4wp-admin .CodeMirror-cursor{border-left:1px solid #000;border-right:none;width:0}#mc4wp-admin .CodeMirror div.CodeMirror-secondarycursor,.mc4wp-admin .CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}#mc4wp-admin .cm-fat-cursor .CodeMirror-cursor,.mc4wp-admin .cm-fat-cursor .CodeMirror-cursor{width:auto;border:0!important;background:#7e7}#mc4wp-admin .cm-fat-cursor div.CodeMirror-cursors,.mc4wp-admin .cm-fat-cursor div.CodeMirror-cursors{z-index:1}#mc4wp-admin .cm-fat-cursor-mark,.mc4wp-admin .cm-fat-cursor-mark{background-color:rgba(20,255,20,.5);-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite}#mc4wp-admin .cm-animate-fat-cursor,.mc4wp-admin .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;background-color:#7e7}@-moz-keyframes blink{50%{background-color:transparent}}@-webkit-keyframes blink{50%{background-color:transparent}}@keyframes blink{50%{background-color:transparent}}#mc4wp-admin .cm-tab,.mc4wp-admin .cm-tab{display:inline-block;text-decoration:inherit}#mc4wp-admin .CodeMirror-rulers,.mc4wp-admin .CodeMirror-rulers{position:absolute;left:0;right:0;top:-50px;bottom:-20px;overflow:hidden}#mc4wp-admin .CodeMirror-ruler,.mc4wp-admin .CodeMirror-ruler{border-left:1px solid #ccc;top:0;bottom:0;position:absolute}#mc4wp-admin .cm-s-default .cm-header,.mc4wp-admin .cm-s-default .cm-header{color:#00f}#mc4wp-admin .cm-s-default .cm-quote,.mc4wp-admin .cm-s-default .cm-quote{color:#090}#mc4wp-admin .cm-negative,.mc4wp-admin .cm-negative{color:#d44}#mc4wp-admin .cm-positive,.mc4wp-admin .cm-positive{color:#292}#mc4wp-admin .cm-header,#mc4wp-admin .cm-strong,.mc4wp-admin .cm-header,.mc4wp-admin .cm-strong{font-weight:700}#mc4wp-admin .cm-link,.mc4wp-admin .cm-link{text-decoration:underline}#mc4wp-admin .cm-strikethrough,.mc4wp-admin .cm-strikethrough{text-decoration:line-through}#mc4wp-admin .cm-s-default .cm-keyword,.mc4wp-admin .cm-s-default .cm-keyword{color:#708}#mc4wp-admin .cm-s-default .cm-atom,.mc4wp-admin .cm-s-default .cm-atom{color:#219}#mc4wp-admin .cm-s-default .cm-number,.mc4wp-admin .cm-s-default .cm-number{color:#164}#mc4wp-admin .cm-s-default .cm-def,.mc4wp-admin .cm-s-default .cm-def{color:#00f}#mc4wp-admin .cm-s-default .cm-variable-2,.mc4wp-admin .cm-s-default .cm-variable-2{color:#05a}#mc4wp-admin .cm-s-default .cm-type,#mc4wp-admin .cm-s-default .cm-variable-3,.mc4wp-admin .cm-s-default .cm-type,.mc4wp-admin .cm-s-default .cm-variable-3{color:#085}#mc4wp-admin .cm-s-default .cm-comment,.mc4wp-admin .cm-s-default .cm-comment{color:#a50}#mc4wp-admin .cm-s-default .cm-string,.mc4wp-admin .cm-s-default .cm-string{color:#a11}#mc4wp-admin .cm-s-default .cm-string-2,.mc4wp-admin .cm-s-default .cm-string-2{color:#f50}#mc4wp-admin .cm-s-default .cm-meta,#mc4wp-admin .cm-s-default .cm-qualifier,.mc4wp-admin .cm-s-default .cm-meta,.mc4wp-admin .cm-s-default .cm-qualifier{color:#555}#mc4wp-admin .cm-s-default .cm-builtin,.mc4wp-admin .cm-s-default .cm-builtin{color:#30a}#mc4wp-admin .cm-s-default .cm-bracket,.mc4wp-admin .cm-s-default .cm-bracket{color:#997}#mc4wp-admin .cm-s-default .cm-tag,.mc4wp-admin .cm-s-default .cm-tag{color:#170}#mc4wp-admin .cm-s-default .cm-attribute,.mc4wp-admin .cm-s-default .cm-attribute{color:#00c}#mc4wp-admin .cm-s-default .cm-hr,.mc4wp-admin .cm-s-default .cm-hr{color:#999}#mc4wp-admin .cm-s-default .cm-link,.mc4wp-admin .cm-s-default .cm-link{color:#00c}#mc4wp-admin .cm-invalidchar,#mc4wp-admin .cm-s-default .cm-error,.mc4wp-admin .cm-invalidchar,.mc4wp-admin .cm-s-default .cm-error{color:red}#mc4wp-admin .CodeMirror-composing,.mc4wp-admin .CodeMirror-composing{border-bottom:2px solid}#mc4wp-admin div.CodeMirror span.CodeMirror-matchingbracket,.mc4wp-admin div.CodeMirror span.CodeMirror-matchingbracket{color:#0b0}#mc4wp-admin div.CodeMirror span.CodeMirror-nonmatchingbracket,.mc4wp-admin div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#a22}#mc4wp-admin .CodeMirror-matchingtag,.mc4wp-admin .CodeMirror-matchingtag{background:rgba(255,150,0,.3)}#mc4wp-admin .CodeMirror-activeline-background,.mc4wp-admin .CodeMirror-activeline-background{background:#e8f2ff}#mc4wp-admin .CodeMirror,.mc4wp-admin .CodeMirror{position:relative;overflow:hidden;background:#fff}#mc4wp-admin .CodeMirror-scroll,.mc4wp-admin .CodeMirror-scroll{overflow:scroll!important;margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:0;position:relative}#mc4wp-admin .CodeMirror-sizer,.mc4wp-admin .CodeMirror-sizer{position:relative;border-right:30px solid transparent}#mc4wp-admin .CodeMirror-gutter-filler,#mc4wp-admin .CodeMirror-hscrollbar,#mc4wp-admin .CodeMirror-scrollbar-filler,#mc4wp-admin .CodeMirror-vscrollbar,.mc4wp-admin .CodeMirror-gutter-filler,.mc4wp-admin .CodeMirror-hscrollbar,.mc4wp-admin .CodeMirror-scrollbar-filler,.mc4wp-admin .CodeMirror-vscrollbar{position:absolute;z-index:6;display:none}#mc4wp-admin .CodeMirror-vscrollbar,.mc4wp-admin .CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}#mc4wp-admin .CodeMirror-hscrollbar,.mc4wp-admin .CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}#mc4wp-admin .CodeMirror-scrollbar-filler,.mc4wp-admin .CodeMirror-scrollbar-filler{right:0;bottom:0}#mc4wp-admin .CodeMirror-gutter-filler,.mc4wp-admin .CodeMirror-gutter-filler{left:0;bottom:0}#mc4wp-admin .CodeMirror-gutters,.mc4wp-admin .CodeMirror-gutters{position:absolute;left:0;top:0;min-height:100%;z-index:3}#mc4wp-admin .CodeMirror-gutter,.mc4wp-admin .CodeMirror-gutter{white-space:normal;height:100%;display:inline-block;vertical-align:top;margin-bottom:-30px}#mc4wp-admin .field-wizard .dashicons,#mc4wp-admin .field-wizard td,#mc4wp-admin .field-wizard tr,.mc4wp-admin .field-wizard .dashicons,.mc4wp-admin .field-wizard td,.mc4wp-admin .field-wizard tr{vertical-align:middle}#mc4wp-admin .CodeMirror-gutter-wrapper,.mc4wp-admin .CodeMirror-gutter-wrapper{position:absolute;z-index:4;background:0 0!important;border:none!important}#mc4wp-admin .CodeMirror-gutter-background,.mc4wp-admin .CodeMirror-gutter-background{position:absolute;top:0;bottom:0;z-index:4}#mc4wp-admin .CodeMirror-gutter-elt,.mc4wp-admin .CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}#mc4wp-admin .CodeMirror-gutter-wrapper ::selection,.mc4wp-admin .CodeMirror-gutter-wrapper ::selection{background-color:transparent}#mc4wp-admin .CodeMirror-gutter-wrapper ::-moz-selection,.mc4wp-admin .CodeMirror-gutter-wrapper ::-moz-selection{background-color:transparent}#mc4wp-admin .CodeMirror-lines,.mc4wp-admin .CodeMirror-lines{cursor:text;min-height:1px}#mc4wp-admin .CodeMirror pre,.mc4wp-admin .CodeMirror pre{-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}#mc4wp-admin .CodeMirror-wrap pre,.mc4wp-admin .CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}#mc4wp-admin .CodeMirror-linebackground,.mc4wp-admin .CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}#mc4wp-admin .CodeMirror-linewidget,.mc4wp-admin .CodeMirror-linewidget{position:relative;z-index:2;padding:.1px}#mc4wp-admin .CodeMirror-rtl pre,.mc4wp-admin .CodeMirror-rtl pre{direction:rtl}#mc4wp-admin .CodeMirror-code,.mc4wp-admin .CodeMirror-code{outline:0}#mc4wp-admin .CodeMirror-gutter,#mc4wp-admin .CodeMirror-gutters,#mc4wp-admin .CodeMirror-linenumber,#mc4wp-admin .CodeMirror-scroll,#mc4wp-admin .CodeMirror-sizer,.mc4wp-admin .CodeMirror-gutter,.mc4wp-admin .CodeMirror-gutters,.mc4wp-admin .CodeMirror-linenumber,.mc4wp-admin .CodeMirror-scroll,.mc4wp-admin .CodeMirror-sizer{-moz-box-sizing:content-box;box-sizing:content-box}#mc4wp-admin .CodeMirror-measure,.mc4wp-admin .CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}#mc4wp-admin .CodeMirror-cursor,.mc4wp-admin .CodeMirror-cursor{position:absolute;pointer-events:none}#mc4wp-admin .CodeMirror-measure pre,.mc4wp-admin .CodeMirror-measure pre{position:static}#mc4wp-admin div.CodeMirror-cursors,.mc4wp-admin div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}#mc4wp-admin .CodeMirror-focused div.CodeMirror-cursors,#mc4wp-admin div.CodeMirror-dragcursors,.mc4wp-admin .CodeMirror-focused div.CodeMirror-cursors,.mc4wp-admin div.CodeMirror-dragcursors{visibility:visible}#mc4wp-admin .CodeMirror-selected,.mc4wp-admin .CodeMirror-selected{background:#d9d9d9}#mc4wp-admin .CodeMirror-focused .CodeMirror-selected,.mc4wp-admin .CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}#mc4wp-admin .CodeMirror-crosshair,.mc4wp-admin .CodeMirror-crosshair{cursor:crosshair}#mc4wp-admin .CodeMirror-line::selection,#mc4wp-admin .CodeMirror-line>span::selection,#mc4wp-admin .CodeMirror-line>span>span::selection,.mc4wp-admin .CodeMirror-line::selection,.mc4wp-admin .CodeMirror-line>span::selection,.mc4wp-admin .CodeMirror-line>span>span::selection{background:#d7d4f0}#mc4wp-admin .CodeMirror-line::-moz-selection,#mc4wp-admin .CodeMirror-line>span::-moz-selection,#mc4wp-admin .CodeMirror-line>span>span::-moz-selection,.mc4wp-admin .CodeMirror-line::-moz-selection,.mc4wp-admin .CodeMirror-line>span::-moz-selection,.mc4wp-admin .CodeMirror-line>span>span::-moz-selection{background:#d7d4f0}#mc4wp-admin .cm-searching,.mc4wp-admin .cm-searching{background-color:#ffa;background-color:rgba(255,255,0,.4)}#mc4wp-admin .cm-force-border,.mc4wp-admin .cm-force-border{padding-right:.1px}@media print{#mc4wp-admin .CodeMirror div.CodeMirror-cursors,.mc4wp-admin .CodeMirror div.CodeMirror-cursors{visibility:hidden}}#mc4wp-admin .cm-tab-wrap-hack:after,.mc4wp-admin .cm-tab-wrap-hack:after{content:''}#mc4wp-admin span.CodeMirror-selectedtext,.mc4wp-admin span.CodeMirror-selectedtext{background:0 0}#mc4wp-admin .CodeMirror,.mc4wp-admin .CodeMirror{border:1px solid #ccc;min-height:500px;font-weight:400;padding:0 4px}#mc4wp-admin .CodeMirror-empty,.mc4wp-admin .CodeMirror-empty{color:#999}#mc4wp-admin #mc4wp-form-preview,.mc4wp-admin #mc4wp-form-preview{border:1px solid #ddd;height:500px;width:100%;border-left-width:0;border-right-width:2px}@media (min-width:1186px){#mc4wp-admin .mc4wp-form-editor-wrap,.mc4wp-admin .mc4wp-form-editor-wrap{padding-right:0!important}#mc4wp-admin .mc4wp-form-preview-wrap,.mc4wp-admin .mc4wp-form-preview-wrap{padding-left:0!important}}@media (max-width:1186px){#mc4wp-admin #mc4wp-form-preview,.mc4wp-admin #mc4wp-form-preview{border-left-width:1px}}#mc4wp-admin .field-wizard h3,.mc4wp-admin .field-wizard h3{margin-top:0;padding-bottom:12px;border-bottom:1px solid #eee;margin-bottom:12px}#mc4wp-admin .field-wizard code,.mc4wp-admin .field-wizard code{margin-left:10px}#mc4wp-admin .field-wizard>div,.mc4wp-admin .field-wizard>div{margin:24px 0}#mc4wp-admin .field-wizard label,.mc4wp-admin .field-wizard label{font-weight:600;display:block;margin-bottom:3px}#mc4wp-admin .field-wizard .cb-wrap,.mc4wp-admin .field-wizard .cb-wrap,.tlite{font-weight:400}#mc4wp-admin .field-wizard table,.mc4wp-admin .field-wizard table{table-layout:fixed;border-collapse:collapse;border-spacing:0}#mc4wp-admin .field-wizard td.stretch,.mc4wp-admin .field-wizard td.stretch{width:100%}#mc4wp-admin .field-wizard .cb-wrap input,.mc4wp-admin .field-wizard .cb-wrap input{margin-right:6px}#mc4wp-admin .field-wizard .limit-height,.mc4wp-admin .field-wizard .limit-height{border:1px solid #eee;padding:6px;max-height:200px;overflow-y:scroll}#mc4wp-admin .field-wizard .help,.mc4wp-admin .field-wizard .help{margin-top:0}#mc4wp-admin .available-fields,.mc4wp-admin .available-fields{border:1px solid #ccc;padding:20px;background:#fff}#mc4wp-admin .available-fields h4,.mc4wp-admin .available-fields h4{font-size:14px;margin-top:0}#mc4wp-admin .available-fields strong,.mc4wp-admin .available-fields strong{display:block;margin-bottom:6px}#mc4wp-admin .available-fields button,.mc4wp-admin .available-fields button{margin:0 6px 6px 0}#mc4wp-admin .available-fields .is-required:after,.mc4wp-admin .available-fields .is-required:after{content:" *";color:red}#mc4wp-admin .available-fields .is-required.not-in-form,.mc4wp-admin .available-fields .is-required.not-in-form{-webkit-box-shadow:0 0 3px 1px red;-moz-box-shadow:0 0 3px 1px red;box-shadow:0 0 3px 1px red}#mc4wp-admin .available-fields .in-form,.mc4wp-admin .available-fields .in-form{opacity:.5}#mc4wp-admin .page-title,.mc4wp-admin .page-title{background:url(../img/icon-large.png) left center no-repeat;padding-left:42px;line-height:32px;margin-bottom:20px}#mc4wp-admin .page-title small,.mc4wp-admin .page-title small{font-size:12px;color:#777;display:inline-block;margin-left:10px}#mc4wp-admin .button .dashicons,#mc4wp-admin .button-secondary .dashicons,#mc4wp-admin .page-title-action .dashicons,.mc4wp-admin .button .dashicons,.mc4wp-admin .button-secondary .dashicons,.mc4wp-admin .page-title-action .dashicons{vertical-align:middle;line-height:16px;margin:0 4px 0 0}#mc4wp-admin .form-table td p,.mc4wp-admin .form-table td p{margin-top:1em}#mc4wp-admin .sidebar,.mc4wp-admin .sidebar{border-left:1px solid #ccc}#mc4wp-admin .sidebar h3,#mc4wp-admin .sidebar h4,.mc4wp-admin .sidebar h3,.mc4wp-admin .sidebar h4{font-size:16px;margin-bottom:0}#mc4wp-admin .sidebar>div,.mc4wp-admin .sidebar>div{border-bottom:1px solid #ccc;margin-bottom:20px;padding-bottom:20px}#mc4wp-admin .sidebar>div:last-of-type,.mc4wp-admin .sidebar>div:last-of-type{border-bottom:0}.mc4wp-log,.overlay{border:1px solid #ccc;overflow-y:scroll}.mc4wp-log{font-family:monaco,monospace,courier,'courier new','Bitstream Vera Sans Mono';font-size:13px;resize:vertical;line-height:140%;height:200px;padding:6px;background:#262626;color:#fff}.mc4wp-log .time{color:#b58900}.mc4wp-log .level{color:#35AECD}.mc4wp-log .debug-log-empty{color:#ccc;font-style:italic}.mc4wp-log .hidden{display:none}.mc4wp-log a{color:#ccc;text-decoration:underline}.overlay{position:fixed;left:0;top:0;z-index:99999;padding:20px;width:100%;max-width:480px;max-height:100%;background:#fefefe;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.overlay .close{position:absolute;padding:10px;right:0;top:0;font-size:24px;cursor:pointer;opacity:.5}.overlay .close:hover{opacity:1}.overlay-background{z-index:99998;background:rgba(0,0,0,.67);position:fixed;left:0;right:0;bottom:0;top:0}.rtl .overlay .close{right:auto;left:0}.rtl #mc4wp-admin .page-title{background-position:right center;padding-left:0;padding-right:42px}.rtl #mc4wp-admin .CodeMirror-scroll{overflow-y:hidden!important}.rtl #mc4wp-admin .CodeMirror-vscrollbar{left:0!important;right:auto!important}.rtl .mc4wp-is-dismissible{padding-left:38px;padding-right:initial;position:relative}.tlite{background:#111;color:#fff;font-family:sans-serif;font-size:.8rem;text-decoration:none;text-align:left;padding:.6em .75rem;border-radius:4px;position:absolute;opacity:0;visibility:hidden;transition:opacity .4s;white-space:nowrap;box-shadow:0 .5rem 1rem -.5rem #000;z-index:1000;-webkit-backface-visibility:hidden}.tlite-table td,.tlite-table th{position:relative}.tlite-visible{visibility:visible;opacity:.9}.tlite::before{content:' ';display:block;background:inherit;width:10px;height:10px;position:absolute;transform:rotate(45deg)}.tlite-n::before{top:-3px;left:50%;margin-left:-5px}.tlite-nw::before{top:-3px;left:10px}.tlite-ne::before{top:-3px;right:10px}.tlite-s::before{bottom:-3px;left:50%;margin-left:-5px}.tlite-se::before{bottom:-3px;right:10px}.tlite-sw::before{bottom:-3px;left:10px}.tlite-w::before{left:-3px;top:50%;margin-top:-5px}.tlite-e::before{right:-3px;top:50%;margin-top:-5px}
1
+ #mc4wp-admin .available-fields .in-form,#mc4wp-admin .hover-activated,.mc4wp-admin .available-fields .in-form,.mc4wp-admin .hover-activated,.overlay .close{opacity:.5}#mc4wp-admin .cm-em,#mc4wp-admin .help,.mc4wp-admin .cm-em,.mc4wp-admin .help,.mc4wp-log .debug-log-empty{font-style:italic}#mc4wp-admin .mc4wp-row,#mc4wp-admin .row,.mc4wp-admin .mc4wp-row,.mc4wp-admin .row{margin-left:-20px;margin-right:-20px;float:none}#mc4wp-admin .mc4wp-row .mc4wp-col,#mc4wp-admin .row .col,.mc4wp-admin .mc4wp-row .mc4wp-col,.mc4wp-admin .row .col{padding:0 20px;float:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#mc4wp-admin .mc4wp-row .mc4wp-col-1,#mc4wp-admin .row .col-1,.mc4wp-admin .mc4wp-row .mc4wp-col-1,.mc4wp-admin .row .col-1{width:16.666%}#mc4wp-admin .mc4wp-row .mc4wp-col-2,#mc4wp-admin .row .col-2,.mc4wp-admin .mc4wp-row .mc4wp-col-2,.mc4wp-admin .row .col-2{width:33.333%}#mc4wp-admin .mc4wp-row .mc4wp-col-3,#mc4wp-admin .row .col-3,.mc4wp-admin .mc4wp-row .mc4wp-col-3,.mc4wp-admin .row .col-3{width:50%}#mc4wp-admin .mc4wp-row .mc4wp-col-4,#mc4wp-admin .row .col-4,.mc4wp-admin .mc4wp-row .mc4wp-col-4,.mc4wp-admin .row .col-4{width:66.666%}#mc4wp-admin .mc4wp-row .mc4wp-col-5,#mc4wp-admin .row .col-5,.mc4wp-admin .mc4wp-row .mc4wp-col-5,.mc4wp-admin .row .col-5{width:83.333%}#mc4wp-admin .mc4wp-row .mc4wp-col-6,#mc4wp-admin .row .col-6,.mc4wp-admin .mc4wp-row .mc4wp-col-6,.mc4wp-admin .row .col-6{width:100%}#mc4wp-admin .clearfix:after,#mc4wp-admin .clearfix:before,#mc4wp-admin .mc4wp-row:after,#mc4wp-admin .mc4wp-row:before,#mc4wp-admin .row:after,#mc4wp-admin .row:before,.mc4wp-admin .clearfix:after,.mc4wp-admin .clearfix:before,.mc4wp-admin .mc4wp-row:after,.mc4wp-admin .mc4wp-row:before,.mc4wp-admin .row:after,.mc4wp-admin .row:before{content:" ";display:table}#mc4wp-admin .clearfix:after,#mc4wp-admin .mc4wp-row:after,#mc4wp-admin .row:after,.mc4wp-admin .clearfix:after,.mc4wp-admin .mc4wp-row:after,.mc4wp-admin .row:after{clear:both}@media (max-width:1200px){#mc4wp-admin .mc4wp-row .mc4wp-col,#mc4wp-admin .row .col,.mc4wp-admin .mc4wp-row .mc4wp-col,.mc4wp-admin .row .col{width:100%;float:none;margin:10px 0}}#mc4wp-admin .status,.mc4wp-admin .status{display:inline-block;margin-left:1em;padding:3px 6px;color:#fff;font-size:12px;font-weight:700}#mc4wp-admin .status.positive,.mc4wp-admin .status.positive{background-color:#32cd32}#mc4wp-admin .status.negative,.mc4wp-admin .status.negative{background-color:red}#mc4wp-admin .status.neutral,.mc4wp-admin .status.neutral{background:gray}#mc4wp-admin .valigntop,.mc4wp-admin .valigntop{vertical-align:top!important}#mc4wp-admin .big-margin,.mc4wp-admin .big-margin{margin-top:60px;margin-bottom:60px}#mc4wp-admin .medium-margin,.mc4wp-admin .medium-margin{margin-top:40px;margin-bottom:40px}#mc4wp-admin .small-margin,.mc4wp-admin .small-margin{margin-top:20px;margin-bottom:20px}#mc4wp-admin .tiny-margin,.mc4wp-admin .tiny-margin{margin-top:10px;margin-bottom:10px}#mc4wp-admin .hover-activated:hover,.mc4wp-admin .hover-activated:hover{cursor:pointer;opacity:1}#mc4wp-admin .help-text,.mc4wp-admin .help-text{font-size:14px}#mc4wp-admin .help-text p,.mc4wp-admin .help-text p{margin:10px 0;font-size:14px}#mc4wp-admin .help-text ul,.mc4wp-admin .help-text ul{list-style:square;margin-top:15px;padding-left:40px}#mc4wp-admin .muted,.mc4wp-admin .muted{color:#aaa}#mc4wp-admin .red,.mc4wp-admin .red{color:red}#mc4wp-admin .green,.mc4wp-admin .green{color:#32cd32}#mc4wp-admin .mc4wp-notice,.mc4wp-admin .mc4wp-notice{padding:6px 12px;color:#31708f;background:#d9edf7;border:1px solid #bce8f1;margin:1em 0!important}#mc4wp-admin .mc4wp-is-dismissible,.mc4wp-admin .mc4wp-is-dismissible{padding-right:38px;position:relative}#mc4wp-admin .column-ID,.mc4wp-admin .column-ID{width:10%}#mc4wp-admin .block,.mc4wp-admin .block{display:block}#mc4wp-admin .code-sample,.mc4wp-admin .code-sample{font-family:Consolas,Monaco,Lucida Console,monospace;font-size:12px;background:#fff}#mc4wp-admin .breadcrumbs,.mc4wp-admin .breadcrumbs{border-bottom:1px solid #ccc;padding-bottom:1em}#mc4wp-admin .mc4wp-loader,.mc4wp-admin .mc4wp-loader{position:relative;display:inline-block;text-indent:-9999999px;border:3px solid rgba(0,0,0,.2);border-left-color:#000;-webkit-transform:translateZ(0);-ms-transform:translateZ(0);transform:translateZ(0);-webkit-animation:load8 1.1s infinite linear;animation:load8 1.1s infinite linear;overflow:hidden;border-radius:50%;vertical-align:middle;width:12px;height:12px;margin-bottom:3px;margin-left:3px;margin-right:3px}@-webkit-keyframes load8{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes load8{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}#mc4wp-admin .tab,.mc4wp-admin .tab{display:none;background:inherit;border:none;font-weight:initial}#mc4wp-admin .tab.tab-active,.mc4wp-admin .tab.tab-active{display:block}#mc4wp-admin .tab h2,.mc4wp-admin .tab h2{margin-top:20px}#mc4wp-admin .CodeMirror,.mc4wp-admin .CodeMirror{font-family:monospace;height:300px;color:#000;direction:ltr}#mc4wp-admin .CodeMirror-lines,.mc4wp-admin .CodeMirror-lines{padding:4px 0}#mc4wp-admin .CodeMirror pre,.mc4wp-admin .CodeMirror pre{padding:0 4px}#mc4wp-admin .CodeMirror-gutter-filler,#mc4wp-admin .CodeMirror-scrollbar-filler,.mc4wp-admin .CodeMirror-gutter-filler,.mc4wp-admin .CodeMirror-scrollbar-filler{background-color:#fff}#mc4wp-admin .CodeMirror-gutters,.mc4wp-admin .CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}#mc4wp-admin .CodeMirror-linenumber,.mc4wp-admin .CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;white-space:nowrap}#mc4wp-admin .CodeMirror-guttermarker,.mc4wp-admin .CodeMirror-guttermarker{color:#000}#mc4wp-admin .CodeMirror-guttermarker-subtle,.mc4wp-admin .CodeMirror-guttermarker-subtle{color:#999}#mc4wp-admin .CodeMirror-cursor,.mc4wp-admin .CodeMirror-cursor{border-left:1px solid #000;border-right:none;width:0}#mc4wp-admin .CodeMirror div.CodeMirror-secondarycursor,.mc4wp-admin .CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}#mc4wp-admin .cm-fat-cursor .CodeMirror-cursor,.mc4wp-admin .cm-fat-cursor .CodeMirror-cursor{width:auto;border:0!important;background:#7e7}#mc4wp-admin .cm-fat-cursor div.CodeMirror-cursors,.mc4wp-admin .cm-fat-cursor div.CodeMirror-cursors{z-index:1}#mc4wp-admin .cm-fat-cursor-mark,.mc4wp-admin .cm-fat-cursor-mark{background-color:rgba(20,255,20,.5);-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite}#mc4wp-admin .cm-animate-fat-cursor,.mc4wp-admin .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;background-color:#7e7}@-moz-keyframes blink{50%{background-color:transparent}}@-webkit-keyframes blink{50%{background-color:transparent}}@keyframes blink{50%{background-color:transparent}}#mc4wp-admin .cm-tab,.mc4wp-admin .cm-tab{display:inline-block;text-decoration:inherit}#mc4wp-admin .cm-link,.mc4wp-admin .cm-link,.mc4wp-log a{text-decoration:underline}#mc4wp-admin .CodeMirror-rulers,.mc4wp-admin .CodeMirror-rulers{position:absolute;left:0;right:0;top:-50px;bottom:-20px;overflow:hidden}#mc4wp-admin .CodeMirror-ruler,.mc4wp-admin .CodeMirror-ruler{border-left:1px solid #ccc;top:0;bottom:0;position:absolute}#mc4wp-admin .cm-s-default .cm-header,.mc4wp-admin .cm-s-default .cm-header{color:#00f}#mc4wp-admin .cm-s-default .cm-quote,.mc4wp-admin .cm-s-default .cm-quote{color:#090}#mc4wp-admin .cm-negative,.mc4wp-admin .cm-negative{color:#d44}#mc4wp-admin .cm-positive,.mc4wp-admin .cm-positive{color:#292}#mc4wp-admin .cm-header,#mc4wp-admin .cm-strong,.mc4wp-admin .cm-header,.mc4wp-admin .cm-strong{font-weight:700}#mc4wp-admin .cm-strikethrough,.mc4wp-admin .cm-strikethrough{text-decoration:line-through}#mc4wp-admin .cm-s-default .cm-keyword,.mc4wp-admin .cm-s-default .cm-keyword{color:#708}#mc4wp-admin .cm-s-default .cm-atom,.mc4wp-admin .cm-s-default .cm-atom{color:#219}#mc4wp-admin .cm-s-default .cm-number,.mc4wp-admin .cm-s-default .cm-number{color:#164}#mc4wp-admin .cm-s-default .cm-def,.mc4wp-admin .cm-s-default .cm-def{color:#00f}#mc4wp-admin .cm-s-default .cm-variable-2,.mc4wp-admin .cm-s-default .cm-variable-2{color:#05a}#mc4wp-admin .cm-s-default .cm-type,#mc4wp-admin .cm-s-default .cm-variable-3,.mc4wp-admin .cm-s-default .cm-type,.mc4wp-admin .cm-s-default .cm-variable-3{color:#085}#mc4wp-admin .cm-s-default .cm-comment,.mc4wp-admin .cm-s-default .cm-comment{color:#a50}#mc4wp-admin .cm-s-default .cm-string,.mc4wp-admin .cm-s-default .cm-string{color:#a11}#mc4wp-admin .cm-s-default .cm-string-2,.mc4wp-admin .cm-s-default .cm-string-2{color:#f50}#mc4wp-admin .cm-s-default .cm-meta,#mc4wp-admin .cm-s-default .cm-qualifier,.mc4wp-admin .cm-s-default .cm-meta,.mc4wp-admin .cm-s-default .cm-qualifier{color:#555}#mc4wp-admin .cm-s-default .cm-builtin,.mc4wp-admin .cm-s-default .cm-builtin{color:#30a}#mc4wp-admin .cm-s-default .cm-bracket,.mc4wp-admin .cm-s-default .cm-bracket{color:#997}#mc4wp-admin .cm-s-default .cm-tag,.mc4wp-admin .cm-s-default .cm-tag{color:#170}#mc4wp-admin .cm-s-default .cm-attribute,.mc4wp-admin .cm-s-default .cm-attribute{color:#00c}#mc4wp-admin .cm-s-default .cm-hr,.mc4wp-admin .cm-s-default .cm-hr{color:#999}#mc4wp-admin .cm-s-default .cm-link,.mc4wp-admin .cm-s-default .cm-link{color:#00c}#mc4wp-admin .cm-invalidchar,#mc4wp-admin .cm-s-default .cm-error,.mc4wp-admin .cm-invalidchar,.mc4wp-admin .cm-s-default .cm-error{color:red}#mc4wp-admin .CodeMirror-composing,.mc4wp-admin .CodeMirror-composing{border-bottom:2px solid}#mc4wp-admin div.CodeMirror span.CodeMirror-matchingbracket,.mc4wp-admin div.CodeMirror span.CodeMirror-matchingbracket{color:#0b0}#mc4wp-admin div.CodeMirror span.CodeMirror-nonmatchingbracket,.mc4wp-admin div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#a22}#mc4wp-admin .CodeMirror-matchingtag,.mc4wp-admin .CodeMirror-matchingtag{background:rgba(255,150,0,.3)}#mc4wp-admin .CodeMirror-activeline-background,.mc4wp-admin .CodeMirror-activeline-background{background:#e8f2ff}#mc4wp-admin .CodeMirror,.mc4wp-admin .CodeMirror{position:relative;overflow:hidden;background:#fff}#mc4wp-admin .CodeMirror-scroll,.mc4wp-admin .CodeMirror-scroll{overflow:scroll!important;margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:0;position:relative}#mc4wp-admin .CodeMirror-sizer,.mc4wp-admin .CodeMirror-sizer{position:relative;border-right:30px solid transparent}#mc4wp-admin .CodeMirror-gutter-filler,#mc4wp-admin .CodeMirror-hscrollbar,#mc4wp-admin .CodeMirror-scrollbar-filler,#mc4wp-admin .CodeMirror-vscrollbar,.mc4wp-admin .CodeMirror-gutter-filler,.mc4wp-admin .CodeMirror-hscrollbar,.mc4wp-admin .CodeMirror-scrollbar-filler,.mc4wp-admin .CodeMirror-vscrollbar{position:absolute;z-index:6;display:none}#mc4wp-admin .CodeMirror-vscrollbar,.mc4wp-admin .CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}#mc4wp-admin .CodeMirror-hscrollbar,.mc4wp-admin .CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}#mc4wp-admin .CodeMirror-scrollbar-filler,.mc4wp-admin .CodeMirror-scrollbar-filler{right:0;bottom:0}#mc4wp-admin .CodeMirror-gutter-filler,.mc4wp-admin .CodeMirror-gutter-filler{left:0;bottom:0}#mc4wp-admin .CodeMirror-gutters,.mc4wp-admin .CodeMirror-gutters{position:absolute;left:0;top:0;min-height:100%;z-index:3}#mc4wp-admin .CodeMirror-gutter,.mc4wp-admin .CodeMirror-gutter{white-space:normal;height:100%;display:inline-block;vertical-align:top;margin-bottom:-30px}#mc4wp-admin .CodeMirror-gutter-wrapper,.mc4wp-admin .CodeMirror-gutter-wrapper{position:absolute;z-index:4;background:0 0!important;border:none!important}#mc4wp-admin .CodeMirror-gutter-background,.mc4wp-admin .CodeMirror-gutter-background{position:absolute;top:0;bottom:0;z-index:4}#mc4wp-admin .CodeMirror-gutter-elt,.mc4wp-admin .CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}#mc4wp-admin .CodeMirror-gutter-wrapper ::selection,.mc4wp-admin .CodeMirror-gutter-wrapper ::selection{background-color:transparent}#mc4wp-admin .CodeMirror-gutter-wrapper ::-moz-selection,.mc4wp-admin .CodeMirror-gutter-wrapper ::-moz-selection{background-color:transparent}#mc4wp-admin .CodeMirror-lines,.mc4wp-admin .CodeMirror-lines{cursor:text;min-height:1px}#mc4wp-admin .CodeMirror pre,.mc4wp-admin .CodeMirror pre{-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}#mc4wp-admin .CodeMirror-wrap pre,.mc4wp-admin .CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}#mc4wp-admin .CodeMirror-linebackground,.mc4wp-admin .CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}#mc4wp-admin .CodeMirror-linewidget,.mc4wp-admin .CodeMirror-linewidget{position:relative;z-index:2;padding:.1px}#mc4wp-admin .CodeMirror-rtl pre,.mc4wp-admin .CodeMirror-rtl pre{direction:rtl}#mc4wp-admin .CodeMirror-code,.mc4wp-admin .CodeMirror-code{outline:0}#mc4wp-admin .CodeMirror-gutter,#mc4wp-admin .CodeMirror-gutters,#mc4wp-admin .CodeMirror-linenumber,#mc4wp-admin .CodeMirror-scroll,#mc4wp-admin .CodeMirror-sizer,.mc4wp-admin .CodeMirror-gutter,.mc4wp-admin .CodeMirror-gutters,.mc4wp-admin .CodeMirror-linenumber,.mc4wp-admin .CodeMirror-scroll,.mc4wp-admin .CodeMirror-sizer{-moz-box-sizing:content-box;box-sizing:content-box}#mc4wp-admin .CodeMirror-measure,.mc4wp-admin .CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}#mc4wp-admin .CodeMirror-cursor,.mc4wp-admin .CodeMirror-cursor{position:absolute;pointer-events:none}#mc4wp-admin .CodeMirror-measure pre,.mc4wp-admin .CodeMirror-measure pre{position:static}#mc4wp-admin div.CodeMirror-cursors,.mc4wp-admin div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}#mc4wp-admin .CodeMirror-focused div.CodeMirror-cursors,#mc4wp-admin div.CodeMirror-dragcursors,.mc4wp-admin .CodeMirror-focused div.CodeMirror-cursors,.mc4wp-admin div.CodeMirror-dragcursors{visibility:visible}#mc4wp-admin .CodeMirror-selected,.mc4wp-admin .CodeMirror-selected{background:#d9d9d9}#mc4wp-admin .CodeMirror-focused .CodeMirror-selected,.mc4wp-admin .CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}#mc4wp-admin .CodeMirror-crosshair,.mc4wp-admin .CodeMirror-crosshair{cursor:crosshair}#mc4wp-admin .CodeMirror-line::selection,#mc4wp-admin .CodeMirror-line>span::selection,#mc4wp-admin .CodeMirror-line>span>span::selection,.mc4wp-admin .CodeMirror-line::selection,.mc4wp-admin .CodeMirror-line>span::selection,.mc4wp-admin .CodeMirror-line>span>span::selection{background:#d7d4f0}#mc4wp-admin .CodeMirror-line::-moz-selection,#mc4wp-admin .CodeMirror-line>span::-moz-selection,#mc4wp-admin .CodeMirror-line>span>span::-moz-selection,.mc4wp-admin .CodeMirror-line::-moz-selection,.mc4wp-admin .CodeMirror-line>span::-moz-selection,.mc4wp-admin .CodeMirror-line>span>span::-moz-selection{background:#d7d4f0}#mc4wp-admin .cm-searching,.mc4wp-admin .cm-searching{background-color:#ffa;background-color:rgba(255,255,0,.4)}#mc4wp-admin .cm-force-border,.mc4wp-admin .cm-force-border{padding-right:.1px}@media print{#mc4wp-admin .CodeMirror div.CodeMirror-cursors,.mc4wp-admin .CodeMirror div.CodeMirror-cursors{visibility:hidden}}#mc4wp-admin .cm-tab-wrap-hack:after,.mc4wp-admin .cm-tab-wrap-hack:after{content:''}#mc4wp-admin span.CodeMirror-selectedtext,.mc4wp-admin span.CodeMirror-selectedtext{background:0 0}#mc4wp-admin .CodeMirror,.mc4wp-admin .CodeMirror{border:1px solid #ccc;min-height:500px;font-weight:400;padding:0 4px}#mc4wp-admin .CodeMirror-empty,.mc4wp-admin .CodeMirror-empty{color:#999}#mc4wp-admin #mc4wp-form-preview,.mc4wp-admin #mc4wp-form-preview{border:1px solid #ddd;height:500px;width:100%;border-left-width:0;border-right-width:2px}@media (min-width:1186px){#mc4wp-admin .mc4wp-form-editor-wrap,.mc4wp-admin .mc4wp-form-editor-wrap{padding-right:0!important}#mc4wp-admin .mc4wp-form-preview-wrap,.mc4wp-admin .mc4wp-form-preview-wrap{padding-left:0!important}}@media (max-width:1186px){#mc4wp-admin #mc4wp-form-preview,.mc4wp-admin #mc4wp-form-preview{border-left-width:1px}}#mc4wp-admin .field-wizard h3,.mc4wp-admin .field-wizard h3{margin-top:0;padding-bottom:12px;border-bottom:1px solid #eee;margin-bottom:12px}#mc4wp-admin .field-wizard code,.mc4wp-admin .field-wizard code{margin-left:10px}#mc4wp-admin .field-wizard>div,.mc4wp-admin .field-wizard>div{margin:24px 0}#mc4wp-admin .field-wizard label,.mc4wp-admin .field-wizard label{font-weight:600;display:block;margin-bottom:3px}#mc4wp-admin .field-wizard .cb-wrap,.mc4wp-admin .field-wizard .cb-wrap,.tlite{font-weight:400}#mc4wp-admin .field-wizard table,.mc4wp-admin .field-wizard table{table-layout:fixed;border-collapse:collapse;border-spacing:0}#mc4wp-admin .field-wizard td,#mc4wp-admin .field-wizard tr,.mc4wp-admin .field-wizard td,.mc4wp-admin .field-wizard tr{vertical-align:middle}#mc4wp-admin .field-wizard td.stretch,.mc4wp-admin .field-wizard td.stretch{width:100%}#mc4wp-admin .field-wizard .cb-wrap input,.mc4wp-admin .field-wizard .cb-wrap input{margin-right:6px}#mc4wp-admin .field-wizard .limit-height,.mc4wp-admin .field-wizard .limit-height{border:1px solid #eee;padding:6px;max-height:200px;overflow-y:scroll}#mc4wp-admin .field-wizard .dashicons,.mc4wp-admin .field-wizard .dashicons{vertical-align:middle}#mc4wp-admin .field-wizard .help,.mc4wp-admin .field-wizard .help{margin-top:0}#mc4wp-admin .available-fields,.mc4wp-admin .available-fields{border:1px solid #ccc;padding:20px;background:#fff}#mc4wp-admin .available-fields h4,.mc4wp-admin .available-fields h4{font-size:14px;margin-top:0}#mc4wp-admin .available-fields strong,.mc4wp-admin .available-fields strong{display:block;margin-bottom:6px}#mc4wp-admin .available-fields button,.mc4wp-admin .available-fields button{margin:0 6px 6px 0}#mc4wp-admin .available-fields .is-required:after,.mc4wp-admin .available-fields .is-required:after{content:" *";color:red}#mc4wp-admin .available-fields .is-required.not-in-form,.mc4wp-admin .available-fields .is-required.not-in-form{-webkit-box-shadow:0 0 3px 1px red;-moz-box-shadow:0 0 3px 1px red;box-shadow:0 0 3px 1px red}#mc4wp-admin .page-title,.mc4wp-admin .page-title{background:url(../img/icon-large.png) left center no-repeat;padding-left:42px;line-height:32px;margin-bottom:20px}#mc4wp-admin .page-title small,.mc4wp-admin .page-title small{font-size:12px;color:#777;display:inline-block;margin-left:10px}#mc4wp-admin .button .dashicons,#mc4wp-admin .button-secondary .dashicons,#mc4wp-admin .page-title-action .dashicons,.mc4wp-admin .button .dashicons,.mc4wp-admin .button-secondary .dashicons,.mc4wp-admin .page-title-action .dashicons{vertical-align:middle;line-height:16px;margin:0 4px 0 0}#mc4wp-admin .form-table td p,.mc4wp-admin .form-table td p{margin-top:1em}#mc4wp-admin .sidebar,.mc4wp-admin .sidebar{border-left:1px solid #ccc}#mc4wp-admin .sidebar h3,#mc4wp-admin .sidebar h4,.mc4wp-admin .sidebar h3,.mc4wp-admin .sidebar h4{font-size:16px;margin-bottom:0}#mc4wp-admin .sidebar>div,.mc4wp-admin .sidebar>div{border-bottom:1px solid #ccc;margin-bottom:20px;padding-bottom:20px}#mc4wp-admin .sidebar>div:last-of-type,.mc4wp-admin .sidebar>div:last-of-type{border-bottom:0}.mc4wp-log{font-family:monaco,monospace,courier,'courier new','Bitstream Vera Sans Mono';font-size:13px;resize:vertical;line-height:140%;height:200px;padding:6px;border:1px solid #ccc;background:#262626;color:#fff;overflow-y:scroll}.mc4wp-log .time{color:#b58900}.mc4wp-log .level{color:#35AECD}.mc4wp-log .debug-log-empty{color:#ccc}.mc4wp-log .hidden{display:none}.mc4wp-log a{color:#ccc}.overlay{position:fixed;left:0;top:0;z-index:99999;padding:20px;width:100%;max-width:480px;max-height:100%;background:#fefefe;border:1px solid #ccc;overflow-y:scroll;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.overlay .close{position:absolute;padding:10px;right:0;top:0;font-size:24px;cursor:pointer}.overlay .close:hover{opacity:1}.overlay-background{z-index:99998;background:rgba(0,0,0,.67);position:fixed;left:0;right:0;bottom:0;top:0}.rtl .overlay .close{right:auto;left:0}.rtl #mc4wp-admin .page-title{background-position:right center;padding-left:0;padding-right:42px}.rtl #mc4wp-admin .CodeMirror-scroll{overflow-y:hidden!important}.rtl #mc4wp-admin .CodeMirror-vscrollbar{left:0!important;right:auto!important}.rtl .mc4wp-is-dismissible{padding-left:38px;padding-right:initial;position:relative}.tlite{background:#111;color:#fff;font-family:sans-serif;font-size:.8rem;text-decoration:none;text-align:left;padding:.6em .75rem;border-radius:4px;position:absolute;opacity:0;visibility:hidden;transition:opacity .4s;white-space:nowrap;box-shadow:0 .5rem 1rem -.5rem #000;z-index:1000;-webkit-backface-visibility:hidden}.tlite-table td,.tlite-table th{position:relative}.tlite-visible{visibility:visible;opacity:.9}.tlite::before{content:' ';display:block;background:inherit;width:10px;height:10px;position:absolute;transform:rotate(45deg)}.tlite-n::before{top:-3px;left:50%;margin-left:-5px}.tlite-nw::before{top:-3px;left:10px}.tlite-ne::before{top:-3px;right:10px}.tlite-s::before{bottom:-3px;left:50%;margin-left:-5px}.tlite-se::before{bottom:-3px;right:10px}.tlite-sw::before{bottom:-3px;left:10px}.tlite-w::before{left:-3px;top:50%;margin-top:-5px}.tlite-e::before{right:-3px;top:50%;margin-top:-5px}
assets/css/form-editor.min.css CHANGED
@@ -1 +1 @@
1
- .CodeMirror{font-family:monospace;height:300px;color:#000;direction:ltr}.CodeMirror-lines{padding:4px 0}.CodeMirror pre{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-mark{background-color:rgba(20,255,20,.5);-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite}.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;background-color:#7e7}@-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:-20px;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,.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-invalidchar,.cm-s-default .cm-error{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:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:0;position:relative}.CodeMirror-sizer{position:relative;border-right:30px solid transparent}.CodeMirror-gutter-filler,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-vscrollbar{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;min-height:100%;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;display:inline-block;vertical-align:top;margin-bottom:-30px}.field-wizard .dashicons,.field-wizard td,.field-wizard tr{vertical-align:middle}.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{-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{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}.CodeMirror-focused div.CodeMirror-cursors,div.CodeMirror-dragcursors{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}.CodeMirror{border:1px solid #ccc;min-height:500px;font-weight:400;padding:0 4px}.CodeMirror-empty{color:#999}#mc4wp-form-preview{border:1px solid #ddd;height:500px;width:100%;border-left-width:0;border-right-width:2px}@media (min-width:1186px){.mc4wp-form-editor-wrap{padding-right:0!important}.mc4wp-form-preview-wrap{padding-left:0!important}}@media (max-width:1186px){#mc4wp-form-preview{border-left-width:1px}}.field-wizard h3{margin-top:0;padding-bottom:12px;border-bottom:1px solid #eee;margin-bottom:12px}.field-wizard code{margin-left:10px}.field-wizard>div{margin:24px 0}.field-wizard label{font-weight:600;display:block;margin-bottom:3px}.field-wizard table{table-layout:fixed;border-collapse:collapse;border-spacing:0}.field-wizard td.stretch{width:100%}.field-wizard .cb-wrap{font-weight:400}.field-wizard .cb-wrap input{margin-right:6px}.field-wizard .limit-height{border:1px solid #eee;padding:6px;max-height:200px;overflow-y:scroll}.field-wizard .help{margin-top:0}.available-fields{border:1px solid #ccc;padding:20px;background:#fff}.available-fields h4{font-size:14px;margin-top:0}.available-fields strong{display:block;margin-bottom:6px}.available-fields button{margin:0 6px 6px 0}.available-fields .is-required:after{content:" *";color:red}.available-fields .is-required.not-in-form{-webkit-box-shadow:0 0 3px 1px red;-moz-box-shadow:0 0 3px 1px red;box-shadow:0 0 3px 1px red}.available-fields .in-form{opacity:.5}
1
+ .CodeMirror{font-family:monospace;height:300px;color:#000;direction:ltr}.CodeMirror-lines{padding:4px 0}.CodeMirror pre{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-mark{background-color:rgba(20,255,20,.5);-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite}.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;background-color:#7e7}@-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:-20px;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,.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-invalidchar,.cm-s-default .cm-error{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:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:0;position:relative}.CodeMirror-sizer{position:relative;border-right:30px solid transparent}.CodeMirror-gutter-filler,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-vscrollbar{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;min-height:100%;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;display:inline-block;vertical-align:top;margin-bottom:-30px}.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{-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{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}.CodeMirror-focused div.CodeMirror-cursors,div.CodeMirror-dragcursors{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}.CodeMirror{border:1px solid #ccc;min-height:500px;font-weight:400;padding:0 4px}.CodeMirror-empty{color:#999}#mc4wp-form-preview{border:1px solid #ddd;height:500px;width:100%;border-left-width:0;border-right-width:2px}@media (min-width:1186px){.mc4wp-form-editor-wrap{padding-right:0!important}.mc4wp-form-preview-wrap{padding-left:0!important}}@media (max-width:1186px){#mc4wp-form-preview{border-left-width:1px}}.field-wizard h3{margin-top:0;padding-bottom:12px;border-bottom:1px solid #eee;margin-bottom:12px}.field-wizard code{margin-left:10px}.field-wizard>div{margin:24px 0}.field-wizard label{font-weight:600;display:block;margin-bottom:3px}.field-wizard table{table-layout:fixed;border-collapse:collapse;border-spacing:0}.field-wizard td,.field-wizard tr{vertical-align:middle}.field-wizard td.stretch{width:100%}.field-wizard .cb-wrap{font-weight:400}.field-wizard .cb-wrap input{margin-right:6px}.field-wizard .limit-height{border:1px solid #eee;padding:6px;max-height:200px;overflow-y:scroll}.field-wizard .dashicons{vertical-align:middle}.field-wizard .help{margin-top:0}.available-fields{border:1px solid #ccc;padding:20px;background:#fff}.available-fields h4{font-size:14px;margin-top:0}.available-fields strong{display:block;margin-bottom:6px}.available-fields button{margin:0 6px 6px 0}.available-fields .is-required:after{content:" *";color:red}.available-fields .is-required.not-in-form{-webkit-box-shadow:0 0 3px 1px red;-moz-box-shadow:0 0 3px 1px red;box-shadow:0 0 3px 1px red}.available-fields .in-form{opacity:.5}
assets/js/admin.js CHANGED
@@ -39,7 +39,7 @@ window.mc4wp.events = events;
39
  window.mc4wp.settings = settings;
40
  window.mc4wp.tabs = tabs;
41
 
42
- },{"./admin/helpers.js":2,"./admin/list-fetcher.js":3,"./admin/settings.js":4,"./admin/tabs.js":5,"mithril":9,"tlite":10,"wolfy87-eventemitter":11}],2:[function(require,module,exports){
43
  'use strict';
44
 
45
  var helpers = {};
@@ -476,379 +476,114 @@ var URL = {
476
  module.exports = URL;
477
 
478
  },{}],7:[function(require,module,exports){
479
- // shim for using process in browser
480
- var process = module.exports = {};
481
-
482
- // cached from whatever global is present so that test runners that stub it
483
- // don't break things. But we need to wrap it in a try catch in case it is
484
- // wrapped in strict mode code which doesn't define any globals. It's inside a
485
- // function because try/catches deoptimize in certain engines.
486
-
487
- var cachedSetTimeout;
488
- var cachedClearTimeout;
489
-
490
- function defaultSetTimout() {
491
- throw new Error('setTimeout has not been defined');
492
  }
493
- function defaultClearTimeout () {
494
- throw new Error('clearTimeout has not been defined');
 
 
495
  }
496
- (function () {
497
- try {
498
- if (typeof setTimeout === 'function') {
499
- cachedSetTimeout = setTimeout;
500
- } else {
501
- cachedSetTimeout = defaultSetTimout;
502
- }
503
- } catch (e) {
504
- cachedSetTimeout = defaultSetTimout;
505
- }
506
- try {
507
- if (typeof clearTimeout === 'function') {
508
- cachedClearTimeout = clearTimeout;
509
- } else {
510
- cachedClearTimeout = defaultClearTimeout;
511
- }
512
- } catch (e) {
513
- cachedClearTimeout = defaultClearTimeout;
514
- }
515
- } ())
516
- function runTimeout(fun) {
517
- if (cachedSetTimeout === setTimeout) {
518
- //normal enviroments in sane situations
519
- return setTimeout(fun, 0);
520
- }
521
- // if setTimeout wasn't available but was latter defined
522
- if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
523
- cachedSetTimeout = setTimeout;
524
- return setTimeout(fun, 0);
525
- }
526
- try {
527
- // when when somebody has screwed with setTimeout but no I.E. maddness
528
- return cachedSetTimeout(fun, 0);
529
- } catch(e){
530
- try {
531
- // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
532
- return cachedSetTimeout.call(null, fun, 0);
533
- } catch(e){
534
- // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
535
- return cachedSetTimeout.call(this, fun, 0);
536
- }
537
- }
538
-
539
-
540
  }
541
- function runClearTimeout(marker) {
542
- if (cachedClearTimeout === clearTimeout) {
543
- //normal enviroments in sane situations
544
- return clearTimeout(marker);
545
- }
546
- // if clearTimeout wasn't available but was latter defined
547
- if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
548
- cachedClearTimeout = clearTimeout;
549
- return clearTimeout(marker);
550
- }
551
- try {
552
- // when when somebody has screwed with setTimeout but no I.E. maddness
553
- return cachedClearTimeout(marker);
554
- } catch (e){
555
- try {
556
- // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
557
- return cachedClearTimeout.call(null, marker);
558
- } catch (e){
559
- // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
560
- // Some versions of I.E. have different rules for clearTimeout vs setTimeout
561
- return cachedClearTimeout.call(this, marker);
562
- }
563
- }
564
-
565
-
566
-
567
  }
568
- var queue = [];
569
- var draining = false;
570
- var currentQueue;
571
- var queueIndex = -1;
572
-
573
- function cleanUpNextTick() {
574
- if (!draining || !currentQueue) {
575
- return;
576
- }
577
- draining = false;
578
- if (currentQueue.length) {
579
- queue = currentQueue.concat(queue);
580
- } else {
581
- queueIndex = -1;
582
- }
583
- if (queue.length) {
584
- drainQueue();
585
- }
586
  }
587
-
588
- function drainQueue() {
589
- if (draining) {
590
- return;
591
- }
592
- var timeout = runTimeout(cleanUpNextTick);
593
- draining = true;
594
-
595
- var len = queue.length;
596
- while(len) {
597
- currentQueue = queue;
598
- queue = [];
599
- while (++queueIndex < len) {
600
- if (currentQueue) {
601
- currentQueue[queueIndex].run();
602
- }
603
- }
604
- queueIndex = -1;
605
- len = queue.length;
606
- }
607
- currentQueue = null;
608
- draining = false;
609
- runClearTimeout(timeout);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
610
  }
611
-
612
- process.nextTick = function (fun) {
613
- var args = new Array(arguments.length - 1);
614
- if (arguments.length > 1) {
615
- for (var i = 1; i < arguments.length; i++) {
616
- args[i - 1] = arguments[i];
617
- }
618
- }
619
- queue.push(new Item(fun, args));
620
- if (queue.length === 1 && !draining) {
621
- runTimeout(drainQueue);
622
- }
623
- };
624
-
625
- // v8 likes predictible objects
626
- function Item(fun, array) {
627
- this.fun = fun;
628
- this.array = array;
629
- }
630
- Item.prototype.run = function () {
631
- this.fun.apply(null, this.array);
632
- };
633
- process.title = 'browser';
634
- process.browser = true;
635
- process.env = {};
636
- process.argv = [];
637
- process.version = ''; // empty string to avoid regexp issues
638
- process.versions = {};
639
-
640
- function noop() {}
641
-
642
- process.on = noop;
643
- process.addListener = noop;
644
- process.once = noop;
645
- process.off = noop;
646
- process.removeListener = noop;
647
- process.removeAllListeners = noop;
648
- process.emit = noop;
649
- process.prependListener = noop;
650
- process.prependOnceListener = noop;
651
-
652
- process.listeners = function (name) { return [] }
653
-
654
- process.binding = function (name) {
655
- throw new Error('process.binding is not supported');
656
- };
657
-
658
- process.cwd = function () { return '/' };
659
- process.chdir = function (dir) {
660
- throw new Error('process.chdir is not supported');
661
- };
662
- process.umask = function() { return 0; };
663
-
664
- },{}],8:[function(require,module,exports){
665
- (function (setImmediate,clearImmediate){
666
- var nextTick = require('process/browser.js').nextTick;
667
- var apply = Function.prototype.apply;
668
- var slice = Array.prototype.slice;
669
- var immediateIds = {};
670
- var nextImmediateId = 0;
671
-
672
- // DOM APIs, for completeness
673
-
674
- exports.setTimeout = function() {
675
- return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);
676
- };
677
- exports.setInterval = function() {
678
- return new Timeout(apply.call(setInterval, window, arguments), clearInterval);
679
- };
680
- exports.clearTimeout =
681
- exports.clearInterval = function(timeout) { timeout.close(); };
682
-
683
- function Timeout(id, clearFn) {
684
- this._id = id;
685
- this._clearFn = clearFn;
686
- }
687
- Timeout.prototype.unref = Timeout.prototype.ref = function() {};
688
- Timeout.prototype.close = function() {
689
- this._clearFn.call(window, this._id);
690
- };
691
-
692
- // Does not start the time, just sets up the members needed.
693
- exports.enroll = function(item, msecs) {
694
- clearTimeout(item._idleTimeoutId);
695
- item._idleTimeout = msecs;
696
- };
697
-
698
- exports.unenroll = function(item) {
699
- clearTimeout(item._idleTimeoutId);
700
- item._idleTimeout = -1;
701
- };
702
-
703
- exports._unrefActive = exports.active = function(item) {
704
- clearTimeout(item._idleTimeoutId);
705
-
706
- var msecs = item._idleTimeout;
707
- if (msecs >= 0) {
708
- item._idleTimeoutId = setTimeout(function onTimeout() {
709
- if (item._onTimeout)
710
- item._onTimeout();
711
- }, msecs);
712
- }
713
- };
714
-
715
- // That's not how node.js implements it but the exposed api is the same.
716
- exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function(fn) {
717
- var id = nextImmediateId++;
718
- var args = arguments.length < 2 ? false : slice.call(arguments, 1);
719
-
720
- immediateIds[id] = true;
721
-
722
- nextTick(function onNextTick() {
723
- if (immediateIds[id]) {
724
- // fn.call() is faster so we optimize for the common use-case
725
- // @see http://jsperf.com/call-apply-segu
726
- if (args) {
727
- fn.apply(null, args);
728
- } else {
729
- fn.call(null);
730
- }
731
- // Prevent ids from leaking
732
- exports.clearImmediate(id);
733
- }
734
- });
735
-
736
- return id;
737
- };
738
-
739
- exports.clearImmediate = typeof clearImmediate === "function" ? clearImmediate : function(id) {
740
- delete immediateIds[id];
741
- };
742
- }).call(this,require("timers").setImmediate,require("timers").clearImmediate)
743
- },{"process/browser.js":7,"timers":8}],9:[function(require,module,exports){
744
- (function (global,setImmediate){
745
- ;(function() {
746
- "use strict"
747
- function Vnode(tag, key, attrs0, children, text, dom) {
748
- return {tag: tag, key: key, attrs: attrs0, children: children, text: text, dom: dom, domSize: undefined, state: undefined, _state: undefined, events: undefined, instance: undefined, skip: false}
749
- }
750
- Vnode.normalize = function(node) {
751
- if (Array.isArray(node)) return Vnode("[", undefined, undefined, Vnode.normalizeChildren(node), undefined, undefined)
752
- if (node != null && typeof node !== "object") return Vnode("#", undefined, undefined, node === false ? "" : node, undefined, undefined)
753
- return node
754
- }
755
- Vnode.normalizeChildren = function normalizeChildren(children) {
756
- for (var i = 0; i < children.length; i++) {
757
- children[i] = Vnode.normalize(children[i])
758
- }
759
- return children
760
- }
761
- var selectorParser = /(?:(^|#|\.)([^#\.\[\]]+))|(\[(.+?)(?:\s*=\s*("|'|)((?:\\["'\]]|.)*?)\5)?\])/g
762
- var selectorCache = {}
763
- var hasOwn = {}.hasOwnProperty
764
- function isEmpty(object) {
765
- for (var key in object) if (hasOwn.call(object, key)) return false
766
- return true
767
- }
768
- function compileSelector(selector) {
769
- var match, tag = "div", classes = [], attrs = {}
770
- while (match = selectorParser.exec(selector)) {
771
- var type = match[1], value = match[2]
772
- if (type === "" && value !== "") tag = value
773
- else if (type === "#") attrs.id = value
774
- else if (type === ".") classes.push(value)
775
- else if (match[3][0] === "[") {
776
- var attrValue = match[6]
777
- if (attrValue) attrValue = attrValue.replace(/\\(["'])/g, "$1").replace(/\\\\/g, "\\")
778
- if (match[4] === "class") classes.push(attrValue)
779
- else attrs[match[4]] = attrValue === "" ? attrValue : attrValue || true
780
- }
781
- }
782
- if (classes.length > 0) attrs.className = classes.join(" ")
783
- return selectorCache[selector] = {tag: tag, attrs: attrs}
784
- }
785
- function execSelector(state, attrs, children) {
786
- var hasAttrs = false, childList, text
787
- var className = attrs.className || attrs.class
788
- if (!isEmpty(state.attrs) && !isEmpty(attrs)) {
789
- var newAttrs = {}
790
- for(var key in attrs) {
791
- if (hasOwn.call(attrs, key)) {
792
- newAttrs[key] = attrs[key]
793
- }
794
- }
795
- attrs = newAttrs
796
- }
797
- for (var key in state.attrs) {
798
- if (hasOwn.call(state.attrs, key)) {
799
- attrs[key] = state.attrs[key]
800
- }
801
- }
802
- if (className !== undefined) {
803
- if (attrs.class !== undefined) {
804
- attrs.class = undefined
805
- attrs.className = className
806
- }
807
- if (state.attrs.className != null) {
808
- attrs.className = state.attrs.className + " " + className
809
- }
810
- }
811
- for (var key in attrs) {
812
- if (hasOwn.call(attrs, key) && key !== "key") {
813
- hasAttrs = true
814
- break
815
- }
816
- }
817
- if (Array.isArray(children) && children.length === 1 && children[0] != null && children[0].tag === "#") {
818
- text = children[0].children
819
- } else {
820
- childList = children
821
- }
822
- return Vnode(state.tag, attrs.key, hasAttrs ? attrs : undefined, childList, text)
823
- }
824
- function hyperscript(selector) {
825
- // Because sloppy mode sucks
826
- var attrs = arguments[1], start = 2, children
827
- if (selector == null || typeof selector !== "string" && typeof selector !== "function" && typeof selector.view !== "function") {
828
- throw Error("The selector must be either a string or a component.");
829
- }
830
- if (typeof selector === "string") {
831
- var cached = selectorCache[selector] || compileSelector(selector)
832
- }
833
- if (attrs == null) {
834
- attrs = {}
835
- } else if (typeof attrs !== "object" || attrs.tag != null || Array.isArray(attrs)) {
836
- attrs = {}
837
- start = 1
838
- }
839
- if (arguments.length === start + 1) {
840
- children = arguments[start]
841
- if (!Array.isArray(children)) children = [children]
842
- } else {
843
- children = []
844
- while (start < arguments.length) children.push(arguments[start++])
845
- }
846
- var normalized = Vnode.normalizeChildren(children)
847
- if (typeof selector === "string") {
848
- return execSelector(cached, attrs, normalized)
849
- } else {
850
- return Vnode(selector, attrs.key, attrs, normalized)
851
- }
852
  }
853
  hyperscript.trust = function(html) {
854
  if (html == null) html = ""
@@ -2000,7 +1735,272 @@ if (typeof module !== "undefined") module["exports"] = m
2000
  else window.m = m
2001
  }());
2002
  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("timers").setImmediate)
2003
- },{"timers":8}],10:[function(require,module,exports){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2004
  function tlite(getTooltipOpts) {
2005
  document.addEventListener('mouseover', function (e) {
2006
  var el = e.target;
39
  window.mc4wp.settings = settings;
40
  window.mc4wp.tabs = tabs;
41
 
42
+ },{"./admin/helpers.js":2,"./admin/list-fetcher.js":3,"./admin/settings.js":4,"./admin/tabs.js":5,"mithril":7,"tlite":10,"wolfy87-eventemitter":11}],2:[function(require,module,exports){
43
  'use strict';
44
 
45
  var helpers = {};
476
  module.exports = URL;
477
 
478
  },{}],7:[function(require,module,exports){
479
+ (function (global,setImmediate){
480
+ ;(function() {
481
+ "use strict"
482
+ function Vnode(tag, key, attrs0, children, text, dom) {
483
+ return {tag: tag, key: key, attrs: attrs0, children: children, text: text, dom: dom, domSize: undefined, state: undefined, _state: undefined, events: undefined, instance: undefined, skip: false}
 
 
 
 
 
 
 
 
484
  }
485
+ Vnode.normalize = function(node) {
486
+ if (Array.isArray(node)) return Vnode("[", undefined, undefined, Vnode.normalizeChildren(node), undefined, undefined)
487
+ if (node != null && typeof node !== "object") return Vnode("#", undefined, undefined, node === false ? "" : node, undefined, undefined)
488
+ return node
489
  }
490
+ Vnode.normalizeChildren = function normalizeChildren(children) {
491
+ for (var i = 0; i < children.length; i++) {
492
+ children[i] = Vnode.normalize(children[i])
493
+ }
494
+ return children
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
495
  }
496
+ var selectorParser = /(?:(^|#|\.)([^#\.\[\]]+))|(\[(.+?)(?:\s*=\s*("|'|)((?:\\["'\]]|.)*?)\5)?\])/g
497
+ var selectorCache = {}
498
+ var hasOwn = {}.hasOwnProperty
499
+ function isEmpty(object) {
500
+ for (var key in object) if (hasOwn.call(object, key)) return false
501
+ return true
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
502
  }
503
+ function compileSelector(selector) {
504
+ var match, tag = "div", classes = [], attrs = {}
505
+ while (match = selectorParser.exec(selector)) {
506
+ var type = match[1], value = match[2]
507
+ if (type === "" && value !== "") tag = value
508
+ else if (type === "#") attrs.id = value
509
+ else if (type === ".") classes.push(value)
510
+ else if (match[3][0] === "[") {
511
+ var attrValue = match[6]
512
+ if (attrValue) attrValue = attrValue.replace(/\\(["'])/g, "$1").replace(/\\\\/g, "\\")
513
+ if (match[4] === "class") classes.push(attrValue)
514
+ else attrs[match[4]] = attrValue === "" ? attrValue : attrValue || true
515
+ }
516
+ }
517
+ if (classes.length > 0) attrs.className = classes.join(" ")
518
+ return selectorCache[selector] = {tag: tag, attrs: attrs}
 
 
519
  }
520
+ function execSelector(state, attrs, children) {
521
+ var hasAttrs = false, childList, text
522
+ var className = attrs.className || attrs.class
523
+ if (!isEmpty(state.attrs) && !isEmpty(attrs)) {
524
+ var newAttrs = {}
525
+ for(var key in attrs) {
526
+ if (hasOwn.call(attrs, key)) {
527
+ newAttrs[key] = attrs[key]
528
+ }
529
+ }
530
+ attrs = newAttrs
531
+ }
532
+ for (var key in state.attrs) {
533
+ if (hasOwn.call(state.attrs, key)) {
534
+ attrs[key] = state.attrs[key]
535
+ }
536
+ }
537
+ if (className !== undefined) {
538
+ if (attrs.class !== undefined) {
539
+ attrs.class = undefined
540
+ attrs.className = className
541
+ }
542
+ if (state.attrs.className != null) {
543
+ attrs.className = state.attrs.className + " " + className
544
+ }
545
+ }
546
+ for (var key in attrs) {
547
+ if (hasOwn.call(attrs, key) && key !== "key") {
548
+ hasAttrs = true
549
+ break
550
+ }
551
+ }
552
+ if (Array.isArray(children) && children.length === 1 && children[0] != null && children[0].tag === "#") {
553
+ text = children[0].children
554
+ } else {
555
+ childList = children
556
+ }
557
+ return Vnode(state.tag, attrs.key, hasAttrs ? attrs : undefined, childList, text)
558
  }
559
+ function hyperscript(selector) {
560
+ // Because sloppy mode sucks
561
+ var attrs = arguments[1], start = 2, children
562
+ if (selector == null || typeof selector !== "string" && typeof selector !== "function" && typeof selector.view !== "function") {
563
+ throw Error("The selector must be either a string or a component.");
564
+ }
565
+ if (typeof selector === "string") {
566
+ var cached = selectorCache[selector] || compileSelector(selector)
567
+ }
568
+ if (attrs == null) {
569
+ attrs = {}
570
+ } else if (typeof attrs !== "object" || attrs.tag != null || Array.isArray(attrs)) {
571
+ attrs = {}
572
+ start = 1
573
+ }
574
+ if (arguments.length === start + 1) {
575
+ children = arguments[start]
576
+ if (!Array.isArray(children)) children = [children]
577
+ } else {
578
+ children = []
579
+ while (start < arguments.length) children.push(arguments[start++])
580
+ }
581
+ var normalized = Vnode.normalizeChildren(children)
582
+ if (typeof selector === "string") {
583
+ return execSelector(cached, attrs, normalized)
584
+ } else {
585
+ return Vnode(selector, attrs.key, attrs, normalized)
586
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
587
  }
588
  hyperscript.trust = function(html) {
589
  if (html == null) html = ""
1735
  else window.m = m
1736
  }());
1737
  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("timers").setImmediate)
1738
+ },{"timers":9}],8:[function(require,module,exports){
1739
+ // shim for using process in browser
1740
+ var process = module.exports = {};
1741
+
1742
+ // cached from whatever global is present so that test runners that stub it
1743
+ // don't break things. But we need to wrap it in a try catch in case it is
1744
+ // wrapped in strict mode code which doesn't define any globals. It's inside a
1745
+ // function because try/catches deoptimize in certain engines.
1746
+
1747
+ var cachedSetTimeout;
1748
+ var cachedClearTimeout;
1749
+
1750
+ function defaultSetTimout() {
1751
+ throw new Error('setTimeout has not been defined');
1752
+ }
1753
+ function defaultClearTimeout () {
1754
+ throw new Error('clearTimeout has not been defined');
1755
+ }
1756
+ (function () {
1757
+ try {
1758
+ if (typeof setTimeout === 'function') {
1759
+ cachedSetTimeout = setTimeout;
1760
+ } else {
1761
+ cachedSetTimeout = defaultSetTimout;
1762
+ }
1763
+ } catch (e) {
1764
+ cachedSetTimeout = defaultSetTimout;
1765
+ }
1766
+ try {
1767
+ if (typeof clearTimeout === 'function') {
1768
+ cachedClearTimeout = clearTimeout;
1769
+ } else {
1770
+ cachedClearTimeout = defaultClearTimeout;
1771
+ }
1772
+ } catch (e) {
1773
+ cachedClearTimeout = defaultClearTimeout;
1774
+ }
1775
+ } ())
1776
+ function runTimeout(fun) {
1777
+ if (cachedSetTimeout === setTimeout) {
1778
+ //normal enviroments in sane situations
1779
+ return setTimeout(fun, 0);
1780
+ }
1781
+ // if setTimeout wasn't available but was latter defined
1782
+ if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
1783
+ cachedSetTimeout = setTimeout;
1784
+ return setTimeout(fun, 0);
1785
+ }
1786
+ try {
1787
+ // when when somebody has screwed with setTimeout but no I.E. maddness
1788
+ return cachedSetTimeout(fun, 0);
1789
+ } catch(e){
1790
+ try {
1791
+ // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
1792
+ return cachedSetTimeout.call(null, fun, 0);
1793
+ } catch(e){
1794
+ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
1795
+ return cachedSetTimeout.call(this, fun, 0);
1796
+ }
1797
+ }
1798
+
1799
+
1800
+ }
1801
+ function runClearTimeout(marker) {
1802
+ if (cachedClearTimeout === clearTimeout) {
1803
+ //normal enviroments in sane situations
1804
+ return clearTimeout(marker);
1805
+ }
1806
+ // if clearTimeout wasn't available but was latter defined
1807
+ if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
1808
+ cachedClearTimeout = clearTimeout;
1809
+ return clearTimeout(marker);
1810
+ }
1811
+ try {
1812
+ // when when somebody has screwed with setTimeout but no I.E. maddness
1813
+ return cachedClearTimeout(marker);
1814
+ } catch (e){
1815
+ try {
1816
+ // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
1817
+ return cachedClearTimeout.call(null, marker);
1818
+ } catch (e){
1819
+ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
1820
+ // Some versions of I.E. have different rules for clearTimeout vs setTimeout
1821
+ return cachedClearTimeout.call(this, marker);
1822
+ }
1823
+ }
1824
+
1825
+
1826
+
1827
+ }
1828
+ var queue = [];
1829
+ var draining = false;
1830
+ var currentQueue;
1831
+ var queueIndex = -1;
1832
+
1833
+ function cleanUpNextTick() {
1834
+ if (!draining || !currentQueue) {
1835
+ return;
1836
+ }
1837
+ draining = false;
1838
+ if (currentQueue.length) {
1839
+ queue = currentQueue.concat(queue);
1840
+ } else {
1841
+ queueIndex = -1;
1842
+ }
1843
+ if (queue.length) {
1844
+ drainQueue();
1845
+ }
1846
+ }
1847
+
1848
+ function drainQueue() {
1849
+ if (draining) {
1850
+ return;
1851
+ }
1852
+ var timeout = runTimeout(cleanUpNextTick);
1853
+ draining = true;
1854
+
1855
+ var len = queue.length;
1856
+ while(len) {
1857
+ currentQueue = queue;
1858
+ queue = [];
1859
+ while (++queueIndex < len) {
1860
+ if (currentQueue) {
1861
+ currentQueue[queueIndex].run();
1862
+ }
1863
+ }
1864
+ queueIndex = -1;
1865
+ len = queue.length;
1866
+ }
1867
+ currentQueue = null;
1868
+ draining = false;
1869
+ runClearTimeout(timeout);
1870
+ }
1871
+
1872
+ process.nextTick = function (fun) {
1873
+ var args = new Array(arguments.length - 1);
1874
+ if (arguments.length > 1) {
1875
+ for (var i = 1; i < arguments.length; i++) {
1876
+ args[i - 1] = arguments[i];
1877
+ }
1878
+ }
1879
+ queue.push(new Item(fun, args));
1880
+ if (queue.length === 1 && !draining) {
1881
+ runTimeout(drainQueue);
1882
+ }
1883
+ };
1884
+
1885
+ // v8 likes predictible objects
1886
+ function Item(fun, array) {
1887
+ this.fun = fun;
1888
+ this.array = array;
1889
+ }
1890
+ Item.prototype.run = function () {
1891
+ this.fun.apply(null, this.array);
1892
+ };
1893
+ process.title = 'browser';
1894
+ process.browser = true;
1895
+ process.env = {};
1896
+ process.argv = [];
1897
+ process.version = ''; // empty string to avoid regexp issues
1898
+ process.versions = {};
1899
+
1900
+ function noop() {}
1901
+
1902
+ process.on = noop;
1903
+ process.addListener = noop;
1904
+ process.once = noop;
1905
+ process.off = noop;
1906
+ process.removeListener = noop;
1907
+ process.removeAllListeners = noop;
1908
+ process.emit = noop;
1909
+ process.prependListener = noop;
1910
+ process.prependOnceListener = noop;
1911
+
1912
+ process.listeners = function (name) { return [] }
1913
+
1914
+ process.binding = function (name) {
1915
+ throw new Error('process.binding is not supported');
1916
+ };
1917
+
1918
+ process.cwd = function () { return '/' };
1919
+ process.chdir = function (dir) {
1920
+ throw new Error('process.chdir is not supported');
1921
+ };
1922
+ process.umask = function() { return 0; };
1923
+
1924
+ },{}],9:[function(require,module,exports){
1925
+ (function (setImmediate,clearImmediate){
1926
+ var nextTick = require('process/browser.js').nextTick;
1927
+ var apply = Function.prototype.apply;
1928
+ var slice = Array.prototype.slice;
1929
+ var immediateIds = {};
1930
+ var nextImmediateId = 0;
1931
+
1932
+ // DOM APIs, for completeness
1933
+
1934
+ exports.setTimeout = function() {
1935
+ return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);
1936
+ };
1937
+ exports.setInterval = function() {
1938
+ return new Timeout(apply.call(setInterval, window, arguments), clearInterval);
1939
+ };
1940
+ exports.clearTimeout =
1941
+ exports.clearInterval = function(timeout) { timeout.close(); };
1942
+
1943
+ function Timeout(id, clearFn) {
1944
+ this._id = id;
1945
+ this._clearFn = clearFn;
1946
+ }
1947
+ Timeout.prototype.unref = Timeout.prototype.ref = function() {};
1948
+ Timeout.prototype.close = function() {
1949
+ this._clearFn.call(window, this._id);
1950
+ };
1951
+
1952
+ // Does not start the time, just sets up the members needed.
1953
+ exports.enroll = function(item, msecs) {
1954
+ clearTimeout(item._idleTimeoutId);
1955
+ item._idleTimeout = msecs;
1956
+ };
1957
+
1958
+ exports.unenroll = function(item) {
1959
+ clearTimeout(item._idleTimeoutId);
1960
+ item._idleTimeout = -1;
1961
+ };
1962
+
1963
+ exports._unrefActive = exports.active = function(item) {
1964
+ clearTimeout(item._idleTimeoutId);
1965
+
1966
+ var msecs = item._idleTimeout;
1967
+ if (msecs >= 0) {
1968
+ item._idleTimeoutId = setTimeout(function onTimeout() {
1969
+ if (item._onTimeout)
1970
+ item._onTimeout();
1971
+ }, msecs);
1972
+ }
1973
+ };
1974
+
1975
+ // That's not how node.js implements it but the exposed api is the same.
1976
+ exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function(fn) {
1977
+ var id = nextImmediateId++;
1978
+ var args = arguments.length < 2 ? false : slice.call(arguments, 1);
1979
+
1980
+ immediateIds[id] = true;
1981
+
1982
+ nextTick(function onNextTick() {
1983
+ if (immediateIds[id]) {
1984
+ // fn.call() is faster so we optimize for the common use-case
1985
+ // @see http://jsperf.com/call-apply-segu
1986
+ if (args) {
1987
+ fn.apply(null, args);
1988
+ } else {
1989
+ fn.call(null);
1990
+ }
1991
+ // Prevent ids from leaking
1992
+ exports.clearImmediate(id);
1993
+ }
1994
+ });
1995
+
1996
+ return id;
1997
+ };
1998
+
1999
+ exports.clearImmediate = typeof clearImmediate === "function" ? clearImmediate : function(id) {
2000
+ delete immediateIds[id];
2001
+ };
2002
+ }).call(this,require("timers").setImmediate,require("timers").clearImmediate)
2003
+ },{"process/browser.js":8,"timers":9}],10:[function(require,module,exports){
2004
  function tlite(getTooltipOpts) {
2005
  document.addEventListener('mouseover', function (e) {
2006
  var el = e.target;
assets/js/admin.min.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(){var l=void 0;!function o(a,l,s){function u(t,e){if(!l[t]){if(!a[t]){var n=!1;if(!e&&n)return n(t,!0);if(c)return c(t,!0);var r=new Error("Cannot find module '"+t+"'");throw r.code="MODULE_NOT_FOUND",r}var i=l[t]={exports:{}};a[t][0].call(i.exports,function(e){return u(a[t][1][e]||e)},i,i.exports,o,a,l,s)}return l[t].exports}for(var c=!1,e=0;e<s.length;e++)u(s[e]);return u}({1:[function(e,t,n){"use strict";var r,i=e("tlite"),o=(r=i)&&r.__esModule?r:{default:r};var a=window.m=e("mithril"),l=e("wolfy87-eventemitter"),s=document.getElementById("mc4wp-admin"),u=new l,c=e("./admin/tabs.js")(s),f=e("./admin/helpers.js"),d=e("./admin/settings.js")(s,f,u);(0,o.default)(function(e){return-1<e.className.indexOf("mc4wp-tooltip")});var h=e("./admin/list-fetcher.js"),v=document.getElementById("mc4wp-list-fetcher");v&&a.mount(v,new h),window.mc4wp=window.mc4wp||{},window.mc4wp.deps=window.mc4wp.deps||{},window.mc4wp.deps.mithril=a,window.mc4wp.helpers=f,window.mc4wp.events=u,window.mc4wp.settings=d,window.mc4wp.tabs=c},{"./admin/helpers.js":2,"./admin/list-fetcher.js":3,"./admin/settings.js":4,"./admin/tabs.js":5,mithril:9,tlite:10,"wolfy87-eventemitter":11}],2:[function(e,t,n){"use strict";var r,a={};a.toggleElement=function(e){for(var t=document.querySelectorAll(e),n=0;n<t.length;n++){var r=t[n].clientHeight<=0;t[n].style.display=r?"":"none"}},a.bindEventToElement=function(e,t,n){e.addEventListener?e.addEventListener(t,n):e.attachEvent&&e.attachEvent("on"+t,n)},a.bindEventToElements=function(e,t,n){Array.prototype.forEach.call(e,function(e){a.bindEventToElement(e,t,n)})},a.debounce=function(r,i,o){var a;return function(){var e=this,t=arguments,n=o&&!a;clearTimeout(a),a=setTimeout(function(){a=null,o||r.apply(e,t)},i),n&&r.apply(e,t)}},r=document.querySelectorAll("[data-showif]"),Array.prototype.forEach.call(r,function(e){var n=JSON.parse(e.getAttribute("data-showif")),t=document.querySelectorAll('[name="'+n.element+'"]'),r=e.querySelectorAll("input,select,textarea:not([readonly])"),i=void 0===n.hide||n.hide;function o(){if("radio"!==this.getAttribute("type")||this.checked){var t=("checkbox"===this.getAttribute("type")?this.checked:this.value)==n.value;i?(e.style.display=t?"":"none",e.style.visibility=t?"":"hidden"):e.style.opacity=t?"":"0.4",Array.prototype.forEach.call(r,function(e){t?e.removeAttribute("readonly"):e.setAttribute("readonly","readonly")})}}Array.prototype.forEach.call(t,function(e){o.call(e)}),a.bindEventToElements(t,"change",o)}),t.exports=a},{}],3:[function(e,t,n){"use strict";var r=window.jQuery,i=mc4wp_vars,o=i.i18n;function a(){this.working=!1,this.done=!1,i.mailchimp.api_connected&&0===i.mailchimp.lists.length&&this.fetch()}a.prototype.fetch=function(e){e&&e.preventDefault(),this.working=!0,this.done=!1,r.post(ajaxurl,{action:"mc4wp_renew_mailchimp_lists",timeout:18e4}).done(function(e){this.success=!0,e&&window.setTimeout(function(){window.location.reload()},3e3)}.bind(this)).fail(function(e){this.success=!1}.bind(this)).always(function(e){this.working=!1,this.done=!0,m.redraw()}.bind(this))},a.prototype.view=function(){return m("form",{method:"POST",onsubmit:this.fetch.bind(this)},[m("p",[m("input",{type:"submit",value:this.working?o.fetching_mailchimp_lists:o.renew_mailchimp_lists,className:"button",disabled:!!this.working}),m.trust(" &nbsp; "),this.working?[m("span.mc4wp-loader","Loading..."),m.trust(" &nbsp; "),m("em.help",o.fetching_mailchimp_lists_can_take_a_while)]:"",this.done?[this.success?m("em.help.green",o.fetching_mailchimp_lists_done):m("em.help.red",o.fetching_mailchimp_lists_error)]:""])])},t.exports=a},{}],4:[function(e,t,n){"use strict";var l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};t.exports=function(e,t,n){e.querySelector("form");var r=e.querySelectorAll(".mc4wp-list-input"),i=mc4wp_vars.mailchimp.lists,o=[];function a(){return o=[],Array.prototype.forEach.call(r,function(e){("boolean"!=typeof e.checked||e.checked)&&"object"===l(i[e.value])&&o.push(i[e.value])}),n.trigger("selectedLists.change",[o]),o}return n.on("selectedLists.change",function(){var e=document.querySelectorAll(".lists--only-selected > *");Array.prototype.forEach.call(e,function(e){var t,n,r=e.getAttribute("data-list-id");0<(t="id",n=r,o.filter(function(e){return e[t]===n})).length?e.setAttribute("class",e.getAttribute("class").replace("hidden","")):e.setAttribute("class",e.getAttribute("class")+" hidden")})}),t.bindEventToElements(r,"change",a),a(),{getSelectedLists:function(){return o}}}},{}],5:[function(e,t,n){"use strict";var d=e("./url.js");t.exports=function(i){var o=window.jQuery,e=o(i),r=e.find(".tab"),a=e.find(".nav-tab"),l=i.querySelector('input[name="_wp_http_referer"]'),s=[];function u(e){for(var t=0;t<s.length;t++)if(s[t].id===e)return s[t]}function c(e,t){if("string"==typeof e&&(e=u(e)),!e)return!1;null==t&&(t=!0),r.removeClass("tab-active").css("display","none"),a.removeClass("nav-tab-active"),Array.prototype.forEach.call(e.nav,function(e){e.className+=" nav-tab-active",e.blur()}),e.element.style.display="block",e.element.className+=" tab-active";var n=d.setParameter(window.location.href,"tab",e.id);return history.pushState&&t&&history.pushState(e.id,"",n),f(e),l.value=n,"function"==typeof tb_remove&&tb_remove(),"fields"===e.id&&window.mc4wp&&window.mc4wp.forms&&window.mc4wp.forms.editor&&mc4wp.forms.editor.refresh(),!0}function f(e){var t=document.title.split("-");document.title=document.title.replace(t[0],e.title+" ")}function t(e){e=e||window.event;var t=this.getAttribute("data-tab");if(!t){var n=this.className.match(/nav-tab-(\w+)?/);n&&(t=n[1])}if(!t){var r=d.parse(this.href);if(!r.tab)return;t=r.tab}return!c(t)||(e.preventDefault(),e.returnValue=!1)}return o.each(r,function(e,t){var n=t.id.substring(4),r=o(t).find("h2").first().text();s.push({id:n,title:r,element:t,nav:i.querySelectorAll(".nav-tab-"+n),open:function(){return c(n)}})}),a.click(t),o(document.body).on("click",".tab-link",t),function(){if(history.pushState){var e=r.filter(":visible").get(0);if(e){var t=u(e.id.substring(4));t&&(history.replaceState&&null===history.state&&history.replaceState(t.id,""),f(t))}}}(),window.addEventListener&&history.pushState&&window.addEventListener("popstate",function(e){return!e.state||c(e.state,!1)}),{open:c,get:u}}},{"./url.js":6}],6:[function(e,t,n){"use strict";var i={parse:function(e){var t={},n=e.split("&");for(var r in n)if(n.hasOwnProperty(r)){var i=n[r].split("=");t[decodeURIComponent(i[0])]=decodeURIComponent(i[1])}return t},build:function(e){var t=[];for(var n in e)t.push(n+"="+encodeURIComponent(e[n]));return t.join("&")},setParameter:function(e,t,n){var r=i.parse(e);return r[t]=n,i.build(r)}};t.exports=i},{}],7:[function(e,t,n){var r,i,o=t.exports={};function a(){throw new Error("setTimeout has not been defined")}function l(){throw new Error("clearTimeout has not been defined")}function s(t){if(r===setTimeout)return setTimeout(t,0);if((r===a||!r)&&setTimeout)return r=setTimeout,setTimeout(t,0);try{return r(t,0)}catch(e){try{return r.call(null,t,0)}catch(e){return r.call(this,t,0)}}}!function(){try{r="function"==typeof setTimeout?setTimeout:a}catch(e){r=a}try{i="function"==typeof clearTimeout?clearTimeout:l}catch(e){i=l}}();var u,c=[],f=!1,d=-1;function h(){f&&u&&(f=!1,u.length?c=u.concat(c):d=-1,c.length&&v())}function v(){if(!f){var e=s(h);f=!0;for(var t=c.length;t;){for(u=c,c=[];++d<t;)u&&u[d].run();d=-1,t=c.length}u=null,f=!1,function(t){if(i===clearTimeout)return clearTimeout(t);if((i===l||!i)&&clearTimeout)return i=clearTimeout,clearTimeout(t);try{i(t)}catch(e){try{return i.call(null,t)}catch(e){return i.call(this,t)}}}(e)}}function p(e,t){this.fun=e,this.array=t}function m(){}o.nextTick=function(e){var t=new Array(arguments.length-1);if(1<arguments.length)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];c.push(new p(e,t)),1!==c.length||f||s(v)},p.prototype.run=function(){this.fun.apply(null,this.array)},o.title="browser",o.browser=!0,o.env={},o.argv=[],o.version="",o.versions={},o.on=m,o.addListener=m,o.once=m,o.off=m,o.removeListener=m,o.removeAllListeners=m,o.emit=m,o.prependListener=m,o.prependOnceListener=m,o.listeners=function(e){return[]},o.binding=function(e){throw new Error("process.binding is not supported")},o.cwd=function(){return"/"},o.chdir=function(e){throw new Error("process.chdir is not supported")},o.umask=function(){return 0}},{}],8:[function(s,e,u){(function(e,t){var r=s("process/browser.js").nextTick,n=Function.prototype.apply,i=Array.prototype.slice,o={},a=0;function l(e,t){this._id=e,this._clearFn=t}u.setTimeout=function(){return new l(n.call(setTimeout,window,arguments),clearTimeout)},u.setInterval=function(){return new l(n.call(setInterval,window,arguments),clearInterval)},u.clearTimeout=u.clearInterval=function(e){e.close()},l.prototype.unref=l.prototype.ref=function(){},l.prototype.close=function(){this._clearFn.call(window,this._id)},u.enroll=function(e,t){clearTimeout(e._idleTimeoutId),e._idleTimeout=t},u.unenroll=function(e){clearTimeout(e._idleTimeoutId),e._idleTimeout=-1},u._unrefActive=u.active=function(e){clearTimeout(e._idleTimeoutId);var t=e._idleTimeout;0<=t&&(e._idleTimeoutId=setTimeout(function(){e._onTimeout&&e._onTimeout()},t))},u.setImmediate="function"==typeof e?e:function(e){var t=a++,n=!(arguments.length<2)&&i.call(arguments,1);return o[t]=!0,r(function(){o[t]&&(n?e.apply(null,n):e.call(null),u.clearImmediate(t))}),t},u.clearImmediate="function"==typeof t?t:function(e){delete o[e]}}).call(this,s("timers").setImmediate,s("timers").clearImmediate)},{"process/browser.js":7,timers:8}],9:[function(e,L,t){(function(k,S){!function(){"use strict";function z(e,t,n,r,i,o){return{tag:e,key:t,attrs:n,children:r,text:i,dom:o,domSize:void 0,state:void 0,_state:void 0,events:void 0,instance:void 0,skip:!1}}z.normalize=function(e){return Array.isArray(e)?z("[",void 0,void 0,z.normalizeChildren(e),void 0,void 0):null!=e&&"object"!=typeof e?z("#",void 0,void 0,!1===e?"":e,void 0,void 0):e},z.normalizeChildren=function(e){for(var t=0;t<e.length;t++)e[t]=z.normalize(e[t]);return e};var s=/(?:(^|#|\.)([^#\.\[\]]+))|(\[(.+?)(?:\s*=\s*("|'|)((?:\\["'\]]|.)*?)\5)?\])/g,u={},c={}.hasOwnProperty;function f(e){for(var t in e)if(c.call(e,t))return!1;return!0}function e(e){var t,n=arguments[1],r=2;if(null==e||"string"!=typeof e&&"function"!=typeof e&&"function"!=typeof e.view)throw Error("The selector must be either a string or a component.");if("string"==typeof e)var i=u[e]||function(e){for(var t,n="div",r=[],i={};t=s.exec(e);){var o=t[1],a=t[2];if(""===o&&""!==a)n=a;else if("#"===o)i.id=a;else if("."===o)r.push(a);else if("["===t[3][0]){var l=t[6];l&&(l=l.replace(/\\(["'])/g,"$1").replace(/\\\\/g,"\\")),"class"===t[4]?r.push(l):i[t[4]]=""===l?l:l||!0}}return 0<r.length&&(i.className=r.join(" ")),u[e]={tag:n,attrs:i}}(e);if(null==n?n={}:("object"!=typeof n||null!=n.tag||Array.isArray(n))&&(n={},r=1),arguments.length===r+1)t=arguments[r],Array.isArray(t)||(t=[t]);else for(t=[];r<arguments.length;)t.push(arguments[r++]);var o=z.normalizeChildren(t);return"string"==typeof e?function(e,t,n){var r,i,o=!1,a=t.className||t.class;if(!f(e.attrs)&&!f(t)){var l={};for(var s in t)c.call(t,s)&&(l[s]=t[s]);t=l}for(var s in e.attrs)c.call(e.attrs,s)&&(t[s]=e.attrs[s]);for(var s in void 0!==a&&(void 0!==t.class&&(t.class=void 0,t.className=a),null!=e.attrs.className&&(t.className=e.attrs.className+" "+a)),t)if(c.call(t,s)&&"key"!==s){o=!0;break}return Array.isArray(n)&&1===n.length&&null!=n[0]&&"#"===n[0].tag?i=n[0].children:r=n,z(e.tag,t.key,o?t:void 0,r,i)}(i,n,o):z(e,n.key,n,o)}e.trust=function(e){return null==e&&(e=""),z("<",void 0,void 0,e,void 0,void 0)},e.fragment=function(e,t){return z("[",e.key,e,z.normalizeChildren(t),void 0,void 0)};var t=e;if((d=function(e){if(!(this instanceof d))throw new Error("Promise must be called with `new`");if("function"!=typeof e)throw new TypeError("executor must be a function");var o=this,a=[],l=[],i=t(a,!0),s=t(l,!1),u=o._instance={resolvers:a,rejectors:l},c="function"==typeof S?S:setTimeout;function t(r,i){return function t(n){var e;try{if(!i||null==n||"object"!=typeof n&&"function"!=typeof n||"function"!=typeof(e=n.then))c(function(){i||0!==r.length||console.error("Possible unhandled promise rejection:",n);for(var e=0;e<r.length;e++)r[e](n);a.length=0,l.length=0,u.state=i,u.retry=function(){t(n)}});else{if(n===o)throw new TypeError("Promise can't be resolved w/ itself");f(e.bind(n))}}catch(e){s(e)}}}function f(e){var n=0;function t(t){return function(e){0<n++||t(e)}}var r=t(s);try{e(t(i),r)}catch(e){r(e)}}f(e)}).prototype.then=function(e,t){var i,o,a=this._instance;function n(t,e,n,r){e.push(function(e){if("function"!=typeof t)n(e);else try{i(t(e))}catch(e){o&&o(e)}}),"function"==typeof a.retry&&r===a.state&&a.retry()}var r=new d(function(e,t){i=e,o=t});return n(e,a.resolvers,i,!0),n(t,a.rejectors,o,!1),r},d.prototype.catch=function(e){return this.then(null,e)},d.resolve=function(t){return t instanceof d?t:new d(function(e){e(t)})},d.reject=function(n){return new d(function(e,t){t(n)})},d.all=function(l){return new d(function(n,r){var i=l.length,o=0,a=[];if(0===l.length)n([]);else for(var e=0;e<l.length;e++)!function(t){function e(e){o++,a[t]=e,o===i&&n(a)}null==l[t]||"object"!=typeof l[t]&&"function"!=typeof l[t]||"function"!=typeof l[t].then?e(l[t]):l[t].then(e,r)}(e)})},d.race=function(r){return new d(function(e,t){for(var n=0;n<r.length;n++)r[n].then(e,t)})},"undefined"!=typeof window){void 0===window.Promise&&(window.Promise=d);var d=window.Promise}else if(void 0!==k){void 0===k.Promise&&(k.Promise=d);d=k.Promise}var p=function(e){if("[object Object]"!==Object.prototype.toString.call(e))return"";var r=[];for(var t in e)i(t,e[t]);return r.join("&");function i(e,t){if(Array.isArray(t))for(var n=0;n<t.length;n++)i(e+"["+n+"]",t[n]);else if("[object Object]"===Object.prototype.toString.call(t))for(var n in t)i(e+"["+n+"]",t[n]);else r.push(encodeURIComponent(e)+(null!=t&&""!==t?"="+encodeURIComponent(t):""))}},m=new RegExp("^file://","i"),n=function(s,r){var t,o=0;function a(){var i=0;function o(){0==--i&&"function"==typeof t&&t()}return function t(n){var r=n.then;return n.then=function(){i++;var e=r.apply(n,arguments);return e.then(o,function(e){if(o(),0===i)throw e}),t(e)},n}}function u(e,t){if("string"==typeof e){var n=e;null==(e=t||{}).url&&(e.url=n)}return e}function c(e,t){if(null==t)return e;for(var n=e.match(/:[^\/]+/gi)||[],r=0;r<n.length;r++){var i=n[r].slice(1);null!=t[i]&&(e=e.replace(n[r],t[i]))}return e}function f(e,t){var n=p(t);if(""!==n){var r=e.indexOf("?")<0?"?":"&";e+=r+n}return e}function d(t){try{return""!==t?JSON.parse(t):null}catch(e){throw new Error(t)}}function h(e){return e.responseText}function v(e,t){if("function"==typeof e){if(!Array.isArray(t))return new e(t);for(var n=0;n<t.length;n++)t[n]=new e(t[n])}return t}return{request:function(l,e){var t=a();l=u(l,e);var n=new r(function(r,i){null==l.method&&(l.method="GET"),l.method=l.method.toUpperCase();var e="GET"!==l.method&&"TRACE"!==l.method&&("boolean"!=typeof l.useBody||l.useBody);"function"!=typeof l.serialize&&(l.serialize="undefined"!=typeof FormData&&l.data instanceof FormData?function(e){return e}:JSON.stringify),"function"!=typeof l.deserialize&&(l.deserialize=d),"function"!=typeof l.extract&&(l.extract=h),l.url=c(l.url,l.data),e?l.data=l.serialize(l.data):l.url=f(l.url,l.data);var o=new s.XMLHttpRequest,a=!1,t=o.abort;for(var n in o.abort=function(){a=!0,t.call(o)},o.open(l.method,l.url,"boolean"!=typeof l.async||l.async,"string"==typeof l.user?l.user:void 0,"string"==typeof l.password?l.password:void 0),l.serialize!==JSON.stringify||!e||l.headers&&l.headers.hasOwnProperty("Content-Type")||o.setRequestHeader("Content-Type","application/json; charset=utf-8"),l.deserialize!==d||l.headers&&l.headers.hasOwnProperty("Accept")||o.setRequestHeader("Accept","application/json, text/*"),l.withCredentials&&(o.withCredentials=l.withCredentials),l.headers)({}).hasOwnProperty.call(l.headers,n)&&o.setRequestHeader(n,l.headers[n]);"function"==typeof l.config&&(o=l.config(o,l)||o),o.onreadystatechange=function(){if(!a&&4===o.readyState)try{var e=l.extract!==h?l.extract(o,l):l.deserialize(l.extract(o,l));if(200<=o.status&&o.status<300||304===o.status||m.test(l.url))r(v(l.type,e));else{var t=new Error(o.responseText);for(var n in e)t[n]=e[n];i(t)}}catch(e){i(e)}},e&&null!=l.data?o.send(l.data):o.send()});return!0===l.background?n:t(n)},jsonp:function(i,e){var t=a();i=u(i,e);var n=new r(function(t,e){var n=i.callbackName||"_mithril_"+Math.round(1e16*Math.random())+"_"+o++,r=s.document.createElement("script");s[n]=function(e){r.parentNode.removeChild(r),t(v(i.type,e)),delete s[n]},r.onerror=function(){r.parentNode.removeChild(r),e(new Error("JSONP request failed")),delete s[n]},null==i.data&&(i.data={}),i.url=c(i.url,i.data),i.data[i.callbackKey||"callback"]=n,r.src=f(i.url,i.data),s.document.documentElement.appendChild(r)});return!0===i.background?n:t(n)},setCompletionCallback:function(e){t=e}}}(window,d),r=function(e){var a,d=e.document,u=d.createDocumentFragment(),t={svg:"http://www.w3.org/2000/svg",math:"http://www.w3.org/1998/Math/MathML"};function h(e){return e.attrs&&e.attrs.xmlns||t[e.tag]}function b(e,t,n,r,i,o,a){for(var l=n;l<r;l++){var s=t[l];null!=s&&x(e,s,i,a,o)}}function x(e,t,n,r,i){var o,a,l,s=t.tag;if("string"!=typeof s)return function(e,t,n,r,i){{if(p(t,n),null!=t.instance){var o=x(e,t.instance,n,r,i);return t.dom=t.instance.dom,t.domSize=null!=t.dom?t.instance.domSize:0,k(e,o,i),o}return t.domSize=0,u}}(e,t,n,r,i);switch(t.state={},null!=t.attrs&&j(t.attrs,t,n),s){case"#":return o=e,l=i,(a=t).dom=d.createTextNode(a.children),k(o,a.dom,l),a.dom;case"<":return v(e,t,i);case"[":return function(e,t,n,r,i){var o=d.createDocumentFragment();if(null!=t.children){var a=t.children;b(o,a,0,a.length,n,null,r)}return t.dom=o.firstChild,t.domSize=o.childNodes.length,k(e,o,i),o}(e,t,n,r,i);default:return function(e,t,n,r,i){var o=t.tag,a=t.attrs,l=a&&a.is,s=(r=h(t)||r)?l?d.createElementNS(r,o,{is:l}):d.createElementNS(r,o):l?d.createElement(o,{is:l}):d.createElement(o);t.dom=s,null!=a&&function(e,t,n){for(var r in t)w(e,r,null,t[r],n)}(t,a,r);if(k(e,s,i),null!=t.attrs&&null!=t.attrs.contenteditable)y(t);else if(null!=t.text&&(""!==t.text?s.textContent=t.text:t.children=[z("#",void 0,void 0,t.text,void 0,void 0)]),null!=t.children){var u=t.children;b(s,u,0,u.length,n,null,r),f=(c=t).attrs,"select"===c.tag&&null!=f&&("value"in f&&w(c,"value",null,f.value,void 0),"selectedIndex"in f&&w(c,"selectedIndex",null,f.selectedIndex,void 0))}var c,f;return s}(e,t,n,r,i)}}function v(e,t,n){var r={caption:"table",thead:"table",tbody:"table",tfoot:"table",tr:"tbody",th:"tr",td:"tr",colgroup:"table",col:"colgroup"}[(t.children.match(/^\s*?<(\w+)/im)||[])[1]]||"div",i=d.createElement(r);i.innerHTML=t.children,t.dom=i.firstChild,t.domSize=i.childNodes.length;for(var o,a=d.createDocumentFragment();o=i.firstChild;)a.appendChild(o);return k(e,a,n),a}function p(e,t){var n;if("function"==typeof e.tag.view){if(e.state=Object.create(e.tag),null!=(n=e.state.view).$$reentrantLock$$)return u;n.$$reentrantLock$$=!0}else{if(e.state=void 0,null!=(n=e.tag).$$reentrantLock$$)return u;n.$$reentrantLock$$=!0,e.state=null!=e.tag.prototype&&"function"==typeof e.tag.prototype.view?new e.tag(e):e.tag(e)}if(e._state=e.state,null!=e.attrs&&j(e.attrs,e,t),j(e._state,e,t),e.instance=z.normalize(e._state.view.call(e.state,e)),e.instance===e)throw Error("A view cannot return the vnode it received as argument");n.$$reentrantLock$$=null}function m(e,t,n,r,i,o,a){if(t!==n&&(null!=t||null!=n))if(null==t)b(e,n,0,n.length,i,o,a);else if(null==n)S(t,0,t.length,n);else{if(t.length===n.length){for(var l=!1,s=0;s<n.length;s++)if(null!=n[s]&&null!=t[s]){l=null==n[s].key&&null==t[s].key;break}if(l){for(s=0;s<t.length;s++)t[s]!==n[s]&&(null==t[s]&&null!=n[s]?x(e,n[s],i,a,T(t,s+1,o)):null==n[s]?S(t,s,s+1,n):E(e,t[s],n[s],i,T(t,s+1,o),r,a));return}}if(r=r||function(e,t){if(null!=e.pool&&Math.abs(e.pool.length-t.length)<=Math.abs(e.length-t.length)){var n=e[0]&&e[0].children&&e[0].children.length||0,r=e.pool[0]&&e.pool[0].children&&e.pool[0].children.length||0,i=t[0]&&t[0].children&&t[0].children.length||0;if(Math.abs(r-i)<=Math.abs(n-i))return!0}return!1}(t,n)){var u=t.pool;t=t.concat(t.pool)}for(var c,f=0,d=0,h=t.length-1,v=n.length-1;f<=h&&d<=v;){if((m=t[f])!==(y=n[d])||r)if(null==m)f++;else if(null==y)d++;else if(m.key===y.key){var p=null!=u&&f>=t.length-u.length||null==u&&r;d++,E(e,m,y,i,T(t,++f,o),p,a),r&&m.tag===y.tag&&k(e,_(m),o)}else{if((m=t[h])!==y||r)if(null==m)h--;else if(null==y)d++;else{if(m.key!==y.key)break;p=null!=u&&h>=t.length-u.length||null==u&&r;E(e,m,y,i,T(t,h+1,o),p,a),(r||d<v)&&k(e,_(m),T(t,f,o)),h--,d++}else h--,d++}else f++,d++}for(;f<=h&&d<=v;){var m,y;if((m=t[h])!==(y=n[v])||r)if(null==m)h--;else if(null==y)v--;else if(m.key===y.key){p=null!=u&&h>=t.length-u.length||null==u&&r;E(e,m,y,i,T(t,h+1,o),p,a),r&&m.tag===y.tag&&k(e,_(m),o),null!=m.dom&&(o=m.dom),h--,v--}else{if(c||(c=A(t,h)),null!=y){var g=c[y.key];if(null!=g){var w=t[g];p=null!=u&&g>=t.length-u.length||null==u&&r;E(e,w,y,i,T(t,h+1,o),r,a),k(e,_(w),o),t[g].skip=!0,null!=w.dom&&(o=w.dom)}else{o=x(e,y,i,a,o)}}v--}else h--,v--;if(v<d)break}b(e,n,d,v+1,i,o,a),S(t,f,h+1,n)}}function E(e,t,n,r,i,o,a){var l,s,u,c,f=t.tag;if(f===n.tag){if(n.state=t.state,n._state=t._state,n.events=t.events,!o&&function(e,t){var n,r;null!=e.attrs&&"function"==typeof e.attrs.onbeforeupdate&&(n=e.attrs.onbeforeupdate.call(e.state,e,t));"string"!=typeof e.tag&&"function"==typeof e._state.onbeforeupdate&&(r=e._state.onbeforeupdate.call(e.state,e,t));if(!(void 0===n&&void 0===r||n||r))return e.dom=t.dom,e.domSize=t.domSize,e.instance=t.instance,!0;return!1}(n,t))return;if("string"==typeof f)switch(null!=n.attrs&&(o?(n.state={},j(n.attrs,n,r)):O(n.attrs,n,r)),f){case"#":!function(e,t){e.children.toString()!==t.children.toString()&&(e.dom.nodeValue=t.children);t.dom=e.dom}(t,n);break;case"<":l=e,u=n,c=i,(s=t).children!==u.children?(_(s),v(l,u,c)):(u.dom=s.dom,u.domSize=s.domSize);break;case"[":!function(e,t,n,r,i,o,a){m(e,t.children,n.children,r,i,o,a);var l=0,s=n.children;if((n.dom=null)!=s){for(var u=0;u<s.length;u++){var c=s[u];null!=c&&null!=c.dom&&(null==n.dom&&(n.dom=c.dom),l+=c.domSize||1)}1!==l&&(n.domSize=l)}}(e,t,n,o,r,i,a);break;default:!function(e,t,n,r,i){var o=t.dom=e.dom;i=h(t)||i,"textarea"===t.tag&&(null==t.attrs&&(t.attrs={}),null!=t.text&&(t.attrs.value=t.text,t.text=void 0));(function(e,t,n,r){if(null!=n)for(var i in n)w(e,i,t&&t[i],n[i],r);if(null!=t)for(var i in t)null!=n&&i in n||("className"===i&&(i="class"),"o"!==i[0]||"n"!==i[1]||L(i)?"key"!==i&&e.dom.removeAttribute(i):C(e,i,void 0))})(t,e.attrs,t.attrs,i),null!=t.attrs&&null!=t.attrs.contenteditable?y(t):null!=e.text&&null!=t.text&&""!==t.text?e.text.toString()!==t.text.toString()&&(e.dom.firstChild.nodeValue=t.text):(null!=e.text&&(e.children=[z("#",void 0,void 0,e.text,void 0,e.dom.firstChild)]),null!=t.text&&(t.children=[z("#",void 0,void 0,t.text,void 0,void 0)]),m(o,e.children,t.children,n,r,null,i))}(t,n,o,r,a)}else!function(e,t,n,r,i,o,a){if(o)p(n,r);else{if(n.instance=z.normalize(n._state.view.call(n.state,n)),n.instance===n)throw Error("A view cannot return the vnode it received as argument");null!=n.attrs&&O(n.attrs,n,r),O(n._state,n,r)}null!=n.instance?(null==t.instance?x(e,n.instance,r,a,i):E(e,t.instance,n.instance,r,i,o,a),n.dom=n.instance.dom,n.domSize=n.instance.domSize):null!=t.instance?(g(t.instance,null),n.dom=void 0,n.domSize=0):(n.dom=t.dom,n.domSize=t.domSize)}(e,t,n,r,i,o,a)}else g(t,null),x(e,n,r,a,i)}function A(e,t){var n={},r=0;for(r=0;r<t;r++){var i=e[r];if(null!=i){var o=i.key;null!=o&&(n[o]=r)}}return n}function _(e){var t=e.domSize;if(null!=t||null==e.dom){var n=d.createDocumentFragment();if(0<t){for(var r=e.dom;--t;)n.appendChild(r.nextSibling);n.insertBefore(r,n.firstChild)}return n}return e.dom}function T(e,t,n){for(;t<e.length;t++)if(null!=e[t]&&null!=e[t].dom)return e[t].dom;return n}function k(e,t,n){n&&n.parentNode?e.insertBefore(t,n):e.appendChild(t)}function y(e){var t=e.children;if(null!=t&&1===t.length&&"<"===t[0].tag){var n=t[0].children;e.dom.innerHTML!==n&&(e.dom.innerHTML=n)}else if(null!=e.text||null!=t&&0!==t.length)throw new Error("Child node of a contenteditable must be trusted")}function S(e,t,n,r){for(var i=t;i<n;i++){var o=e[i];null!=o&&(o.skip?o.skip=!1:g(o,r))}}function g(r,i){var e,o=1,a=0;r.attrs&&"function"==typeof r.attrs.onbeforeremove&&(null!=(e=r.attrs.onbeforeremove.call(r.state,r))&&"function"==typeof e.then&&(o++,e.then(t,t)));"string"!=typeof r.tag&&"function"==typeof r._state.onbeforeremove&&(null!=(e=r._state.onbeforeremove.call(r.state,r))&&"function"==typeof e.then&&(o++,e.then(t,t)));function t(){if(++a===o&&(function e(t){t.attrs&&"function"==typeof t.attrs.onremove&&t.attrs.onremove.call(t.state,t);if("string"!=typeof t.tag)"function"==typeof t._state.onremove&&t._state.onremove.call(t.state,t),null!=t.instance&&e(t.instance);else{var n=t.children;if(Array.isArray(n))for(var r=0;r<n.length;r++){var i=n[r];null!=i&&e(i)}}}(r),r.dom)){var e=r.domSize||1;if(1<e)for(var t=r.dom;--e;)l(t.nextSibling);l(r.dom),null==i||null!=r.domSize||null!=(n=r.attrs)&&(n.oncreate||n.onupdate||n.onbeforeremove||n.onremove)||"string"!=typeof r.tag||(i.pool?i.pool.push(r):i.pool=[r])}var n}t()}function l(e){var t=e.parentNode;null!=t&&t.removeChild(e)}function w(e,t,n,r,i){var o=e.dom;if("key"!==t&&"is"!==t&&(n!==r||(a=e,"value"===(l=t)||"checked"===l||"selectedIndex"===l||"selected"===l&&a.dom===d.activeElement)||"object"==typeof r)&&void 0!==r&&!L(t)){var a,l,s,u,c=t.indexOf(":");if(-1<c&&"xlink"===t.substr(0,c))o.setAttributeNS("http://www.w3.org/1999/xlink",t.slice(c+1),r);else if("o"===t[0]&&"n"===t[1]&&"function"==typeof r)C(e,t,r);else if("style"===t)!function(e,t,n){t===n&&(e.style.cssText="",t=null);if(null==n)e.style.cssText="";else if("string"==typeof n)e.style.cssText=n;else{for(var r in"string"==typeof t&&(e.style.cssText=""),n)e.style[r]=n[r];if(null!=t&&"string"!=typeof t)for(var r in t)r in n||(e.style[r]="")}}(o,n,r);else if(t in o&&("href"!==(u=t)&&"list"!==u&&"form"!==u&&"width"!==u&&"height"!==u)&&void 0===i&&!((s=e).attrs.is||-1<s.tag.indexOf("-"))){if("value"===t){var f=""+r;if(("input"===e.tag||"textarea"===e.tag)&&e.dom.value===f&&e.dom===d.activeElement)return;if("select"===e.tag)if(null===r){if(-1===e.dom.selectedIndex&&e.dom===d.activeElement)return}else if(null!==n&&e.dom.value===f&&e.dom===d.activeElement)return;if("option"===e.tag&&null!=n&&e.dom.value===f)return}if("input"===e.tag&&"type"===t)return void o.setAttribute(t,r);o[t]=r}else"boolean"==typeof r?r?o.setAttribute(t,""):o.removeAttribute(t):o.setAttribute("className"===t?"class":t,r)}}function L(e){return"oninit"===e||"oncreate"===e||"onupdate"===e||"onremove"===e||"onbeforeremove"===e||"onbeforeupdate"===e}function C(e,t,n){var r=e.dom,i="function"!=typeof a?n:function(e){var t=n.call(r,e);return a.call(r,e),t};if(t in r)r[t]="function"==typeof n?i:null;else{var o=t.slice(2);if(void 0===e.events&&(e.events={}),e.events[t]===i)return;null!=e.events[t]&&r.removeEventListener(o,e.events[t],!1),"function"==typeof n&&(e.events[t]=i,r.addEventListener(o,e.events[t],!1))}}function j(e,t,n){"function"==typeof e.oninit&&e.oninit.call(t.state,t),"function"==typeof e.oncreate&&n.push(e.oncreate.bind(t.state,t))}function O(e,t,n){"function"==typeof e.onupdate&&n.push(e.onupdate.bind(t.state,t))}return{render:function(e,t){if(!e)throw new Error("Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined.");var n=[],r=d.activeElement,i=e.namespaceURI;null==e.vnodes&&(e.textContent=""),Array.isArray(t)||(t=[t]),m(e,e.vnodes,z.normalizeChildren(t),!1,n,null,"http://www.w3.org/1999/xhtml"===i?void 0:i),e.vnodes=t,null!=r&&d.activeElement!==r&&r.focus();for(var o=0;o<n.length;o++)n[o]()},setEventCallback:function(e){return a=e}}};var i=function(e){var t=r(e);t.setEventCallback(function(e){!1===e.redraw?e.redraw=void 0:n()});var a=[];function l(e){var t=a.indexOf(e);-1<t&&a.splice(t,2)}function n(){for(var e=1;e<a.length;e+=2)a[e]()}return{subscribe:function(e,t){var n,r,i,o;l(e),a.push(e,(n=t,r=0,i=null,o="function"==typeof requestAnimationFrame?requestAnimationFrame:setTimeout,function(){var e=Date.now();0===r||16<=e-r?(r=e,n()):null===i&&(i=o(function(){i=null,n(),r=Date.now()},16-(e-r)))}))},unsubscribe:l,redraw:n,render:t.render}}(window);n.setCompletionCallback(i.redraw);var o;t.mount=(o=i,function(e,t){if(null===t)return o.render(e,[]),void o.unsubscribe(e);if(null==t.view&&"function"!=typeof t)throw new Error("m.mount(element, component) expects a component, not a vnode");o.subscribe(e,function(){o.render(e,z(t))}),o.redraw()});var a,l,h,v,y,g,w,b,x,E=d,A=function(e){if(""===e||null==e)return{};"?"===e.charAt(0)&&(e=e.slice(1));for(var t=e.split("&"),n={},r={},i=0;i<t.length;i++){var o=t[i].split("="),a=decodeURIComponent(o[0]),l=2===o.length?decodeURIComponent(o[1]):"";"true"===l?l=!0:"false"===l&&(l=!1);var s=a.split(/\]\[?|\[/),u=n;-1<a.indexOf("[")&&s.pop();for(var c=0;c<s.length;c++){var f=s[c],d=s[c+1],h=""==d||!isNaN(parseInt(d,10)),v=c===s.length-1;if(""===f)null==r[a=s.slice(0,c).join()]&&(r[a]=0),f=r[a]++;null==u[f]&&(u[f]=v?l:h?[]:{}),u=u[f]}}return n},_=function(c){var n,f="function"==typeof c.history.pushState,r="function"==typeof S?S:setTimeout;function e(e){var t=c.location[e].replace(/(?:%[a-f89][a-f0-9])+/gim,decodeURIComponent);return"pathname"===e&&"/"!==t[0]&&(t="/"+t),t}function d(e,t,n){var r=e.indexOf("?"),i=e.indexOf("#"),o=-1<r?r:-1<i?i:e.length;if(-1<r){var a=-1<i?i:e.length,l=A(e.slice(r+1,a));for(var s in l)t[s]=l[s]}if(-1<i){var u=A(e.slice(i+1));for(var s in u)n[s]=u[s]}return e.slice(0,o)}var h={prefix:"#!",getPath:function(){switch(h.prefix.charAt(0)){case"#":return e("hash").slice(h.prefix.length);case"?":return e("search").slice(h.prefix.length)+e("hash");default:return e("pathname").slice(h.prefix.length)+e("search")+e("hash")}},setPath:function(e,n,t){var r={},i={};if(e=d(e,r,i),null!=n){for(var o in n)r[o]=n[o];e=e.replace(/:([^\/]+)/g,function(e,t){return delete r[t],n[t]})}var a=p(r);a&&(e+="?"+a);var l=p(i);if(l&&(e+="#"+l),f){var s=t?t.state:null,u=t?t.title:null;c.onpopstate(),t&&t.replace?c.history.replaceState(s,u,h.prefix+e):c.history.pushState(s,u,h.prefix+e)}else c.location.href=h.prefix+e}};return h.defineRoutes=function(l,s,u){function e(){var r=h.getPath(),i={},e=d(r,i,i),t=c.history.state;if(null!=t)for(var n in t)i[n]=t[n];for(var o in l){var a=new RegExp("^"+o.replace(/:[^\/]+?\.{3}/g,"(.*?)").replace(/:[^\/]+/g,"([^\\/]+)")+"/?$");if(a.test(e))return void e.replace(a,function(){for(var e=o.match(/:[^\/]+/g)||[],t=[].slice.call(arguments,1,-2),n=0;n<e.length;n++)i[e[n].replace(/:|\./g,"")]=decodeURIComponent(t[n]);s(l[o],i,r,o)})}u(r,i)}var t;f?c.onpopstate=(t=e,function(){null==n&&(n=r(function(){n=null,t()}))}):"#"===h.prefix.charAt(0)&&(c.onhashchange=e),e()},h};t.route=(a=window,l=i,b=_(a),(x=function(e,t,n){if(null==e)throw new Error("Ensure the DOM element that was passed to `m.route` is not undefined");var o=function(){null!=h&&l.render(e,h(z(v,y.key,y)))},a=function(e){if(e===t)throw new Error("Could not resolve default route "+t);b.setPath(t,null,{replace:!0})};b.defineRoutes(n,function(t,n,r){var i=w=function(e,t){i===w&&(v=null==t||"function"!=typeof t.view&&"function"!=typeof t?"div":t,y=n,g=r,w=null,h=(e.render||function(e){return e}).bind(e),o())};t.view||"function"==typeof t?i({},t):t.onmatch?E.resolve(t.onmatch(n,r)).then(function(e){i(t,e)},a):i(t,"div")},a),l.subscribe(e,o)}).set=function(e,t,n){null!=w&&((n=n||{}).replace=!0),w=null,b.setPath(e,t,n)},x.get=function(){return g},x.prefix=function(e){b.prefix=e},x.link=function(e){e.dom.setAttribute("href",b.prefix+e.attrs.href),e.dom.onclick=function(e){if(!(e.ctrlKey||e.metaKey||e.shiftKey||2===e.which)){e.preventDefault(),e.redraw=!1;var t=this.getAttribute("href");0===t.indexOf(b.prefix)&&(t=t.slice(b.prefix.length)),x.set(t,void 0,void 0)}}},x.param=function(e){return void 0!==y&&void 0!==e?y[e]:y},x),t.withAttr=function(t,n,r){return function(e){n.call(r||this,t in e.currentTarget?e.currentTarget[t]:e.currentTarget.getAttribute(t))}};var T=r(window);t.render=T.render,t.redraw=i.redraw,t.request=n.request,t.jsonp=n.jsonp,t.parseQueryString=A,t.buildQueryString=p,t.version="1.1.6",t.vnode=z,void 0!==L?L.exports=t:window.m=t}()}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},e("timers").setImmediate)},{timers:8}],10:[function(e,t,n){function u(r){document.addEventListener("mouseover",function(e){var t=e.target,n=r(t);n||(n=(t=t.parentElement)&&r(t)),n&&u.show(t,n,!0)})}u.show=function(e,t,l){var s="data-tlite";t=t||{},(e.tooltip||function(e,t){var n,r,i;function o(){u.hide(e,!0)}function a(){n||(n=function(l,e,t){var s=document.createElement("span"),n=t.grav||l.getAttribute("data-tlite")||"n";s.innerHTML=e,l.appendChild(s);var u=n[0]||"",c=n[1]||"";function r(){s.className="tlite tlite-"+u+c;var e=l.offsetTop,t=l.offsetLeft;s.offsetParent===l&&(e=t=0);var n=l.offsetWidth,r=l.offsetHeight,i=s.offsetHeight,o=s.offsetWidth,a=t+n/2;s.style.top=("s"===u?e-i-10:"n"===u?e+r+10:e+r/2-i/2)+"px",s.style.left=("w"===c?t:"e"===c?t+n-o:"w"===u?t+n+10:"e"===u?t-o-10:a-o/2)+"px"}r();var i=s.getBoundingClientRect();"s"===u&&i.top<0?(u="n",r()):"n"===u&&i.bottom>window.innerHeight?(u="s",r()):"e"===u&&i.left<0?(u="w",r()):"w"===u&&i.right>window.innerWidth&&(u="e",r());return s.className+=" tlite-visible",s}(e,i,t))}return e.addEventListener("mousedown",o),e.addEventListener("mouseleave",o),e.tooltip={show:function(){i=e.title||e.getAttribute(s)||i,e.title="",e.setAttribute(s,""),i&&!r&&(r=setTimeout(a,l?150:1))},hide:function(e){if(l===e){r=clearTimeout(r);var t=n&&n.parentNode;t&&t.removeChild(n),n=void 0}}}}(e,t)).show()},u.hide=function(e,t){e.tooltip&&e.tooltip.hide(t)},void 0!==t&&t.exports&&(t.exports=u)},{}],11:[function(e,a,t){!function(e){"use strict";function t(){}var n=t.prototype,r=e.EventEmitter;function o(e,t){for(var n=e.length;n--;)if(e[n].listener===t)return n;return-1}function i(e){return function(){return this[e].apply(this,arguments)}}n.getListeners=function(e){var t,n,r=this._getEvents();if(e instanceof RegExp)for(n in t={},r)r.hasOwnProperty(n)&&e.test(n)&&(t[n]=r[n]);else t=r[e]||(r[e]=[]);return t},n.flattenListeners=function(e){var t,n=[];for(t=0;t<e.length;t+=1)n.push(e[t].listener);return n},n.getListenersAsObject=function(e){var t,n=this.getListeners(e);return n instanceof Array&&((t={})[e]=n),t||n},n.addListener=function(e,t){if(!function e(t){return"function"==typeof t||t instanceof RegExp||!(!t||"object"!=typeof t)&&e(t.listener)}(t))throw new TypeError("listener must be a function");var n,r=this.getListenersAsObject(e),i="object"==typeof t;for(n in r)r.hasOwnProperty(n)&&-1===o(r[n],t)&&r[n].push(i?t:{listener:t,once:!1});return this},n.on=i("addListener"),n.addOnceListener=function(e,t){return this.addListener(e,{listener:t,once:!0})},n.once=i("addOnceListener"),n.defineEvent=function(e){return this.getListeners(e),this},n.defineEvents=function(e){for(var t=0;t<e.length;t+=1)this.defineEvent(e[t]);return this},n.removeListener=function(e,t){var n,r,i=this.getListenersAsObject(e);for(r in i)i.hasOwnProperty(r)&&-1!==(n=o(i[r],t))&&i[r].splice(n,1);return this},n.off=i("removeListener"),n.addListeners=function(e,t){return this.manipulateListeners(!1,e,t)},n.removeListeners=function(e,t){return this.manipulateListeners(!0,e,t)},n.manipulateListeners=function(e,t,n){var r,i,o=e?this.removeListener:this.addListener,a=e?this.removeListeners:this.addListeners;if("object"!=typeof t||t instanceof RegExp)for(r=n.length;r--;)o.call(this,t,n[r]);else for(r in t)t.hasOwnProperty(r)&&(i=t[r])&&("function"==typeof i?o.call(this,r,i):a.call(this,r,i));return this},n.removeEvent=function(e){var t,n=typeof e,r=this._getEvents();if("string"===n)delete r[e];else if(e instanceof RegExp)for(t in r)r.hasOwnProperty(t)&&e.test(t)&&delete r[t];else delete this._events;return this},n.removeAllListeners=i("removeEvent"),n.emitEvent=function(e,t){var n,r,i,o,a=this.getListenersAsObject(e);for(o in a)if(a.hasOwnProperty(o))for(n=a[o].slice(0),i=0;i<n.length;i++)!0===(r=n[i]).once&&this.removeListener(e,r.listener),r.listener.apply(this,t||[])===this._getOnceReturnValue()&&this.removeListener(e,r.listener);return this},n.trigger=i("emitEvent"),n.emit=function(e){var t=Array.prototype.slice.call(arguments,1);return this.emitEvent(e,t)},n.setOnceReturnValue=function(e){return this._onceReturnValue=e,this},n._getOnceReturnValue=function(){return!this.hasOwnProperty("_onceReturnValue")||this._onceReturnValue},n._getEvents=function(){return this._events||(this._events={})},t.noConflict=function(){return e.EventEmitter=r,t},"function"==typeof l&&l.amd?l(function(){return t}):"object"==typeof a&&a.exports?a.exports=t:e.EventEmitter=t}("undefined"!=typeof window?window:this||{})},{}]},{},[1])}();
2
  //# sourceMappingURL=admin.min.js.map
1
+ !function(){var l=void 0;!function o(a,l,s){function u(t,e){if(!l[t]){if(!a[t]){var n=!1;if(!e&&n)return n(t,!0);if(c)return c(t,!0);var r=new Error("Cannot find module '"+t+"'");throw r.code="MODULE_NOT_FOUND",r}var i=l[t]={exports:{}};a[t][0].call(i.exports,function(e){return u(a[t][1][e]||e)},i,i.exports,o,a,l,s)}return l[t].exports}for(var c=!1,e=0;e<s.length;e++)u(s[e]);return u}({1:[function(e,t,n){"use strict";var r,i=e("tlite"),o=(r=i)&&r.__esModule?r:{default:r};var a=window.m=e("mithril"),l=e("wolfy87-eventemitter"),s=document.getElementById("mc4wp-admin"),u=new l,c=e("./admin/tabs.js")(s),f=e("./admin/helpers.js"),d=e("./admin/settings.js")(s,f,u);(0,o.default)(function(e){return-1<e.className.indexOf("mc4wp-tooltip")});var h=e("./admin/list-fetcher.js"),v=document.getElementById("mc4wp-list-fetcher");v&&a.mount(v,new h),window.mc4wp=window.mc4wp||{},window.mc4wp.deps=window.mc4wp.deps||{},window.mc4wp.deps.mithril=a,window.mc4wp.helpers=f,window.mc4wp.events=u,window.mc4wp.settings=d,window.mc4wp.tabs=c},{"./admin/helpers.js":2,"./admin/list-fetcher.js":3,"./admin/settings.js":4,"./admin/tabs.js":5,mithril:7,tlite:10,"wolfy87-eventemitter":11}],2:[function(e,t,n){"use strict";var r,a={};a.toggleElement=function(e){for(var t=document.querySelectorAll(e),n=0;n<t.length;n++){var r=t[n].clientHeight<=0;t[n].style.display=r?"":"none"}},a.bindEventToElement=function(e,t,n){e.addEventListener?e.addEventListener(t,n):e.attachEvent&&e.attachEvent("on"+t,n)},a.bindEventToElements=function(e,t,n){Array.prototype.forEach.call(e,function(e){a.bindEventToElement(e,t,n)})},a.debounce=function(r,i,o){var a;return function(){var e=this,t=arguments,n=o&&!a;clearTimeout(a),a=setTimeout(function(){a=null,o||r.apply(e,t)},i),n&&r.apply(e,t)}},r=document.querySelectorAll("[data-showif]"),Array.prototype.forEach.call(r,function(e){var n=JSON.parse(e.getAttribute("data-showif")),t=document.querySelectorAll('[name="'+n.element+'"]'),r=e.querySelectorAll("input,select,textarea:not([readonly])"),i=void 0===n.hide||n.hide;function o(){if("radio"!==this.getAttribute("type")||this.checked){var t=("checkbox"===this.getAttribute("type")?this.checked:this.value)==n.value;i?(e.style.display=t?"":"none",e.style.visibility=t?"":"hidden"):e.style.opacity=t?"":"0.4",Array.prototype.forEach.call(r,function(e){t?e.removeAttribute("readonly"):e.setAttribute("readonly","readonly")})}}Array.prototype.forEach.call(t,function(e){o.call(e)}),a.bindEventToElements(t,"change",o)}),t.exports=a},{}],3:[function(e,t,n){"use strict";var r=window.jQuery,i=mc4wp_vars,o=i.i18n;function a(){this.working=!1,this.done=!1,i.mailchimp.api_connected&&0===i.mailchimp.lists.length&&this.fetch()}a.prototype.fetch=function(e){e&&e.preventDefault(),this.working=!0,this.done=!1,r.post(ajaxurl,{action:"mc4wp_renew_mailchimp_lists",timeout:18e4}).done(function(e){this.success=!0,e&&window.setTimeout(function(){window.location.reload()},3e3)}.bind(this)).fail(function(e){this.success=!1}.bind(this)).always(function(e){this.working=!1,this.done=!0,m.redraw()}.bind(this))},a.prototype.view=function(){return m("form",{method:"POST",onsubmit:this.fetch.bind(this)},[m("p",[m("input",{type:"submit",value:this.working?o.fetching_mailchimp_lists:o.renew_mailchimp_lists,className:"button",disabled:!!this.working}),m.trust(" &nbsp; "),this.working?[m("span.mc4wp-loader","Loading..."),m.trust(" &nbsp; "),m("em.help",o.fetching_mailchimp_lists_can_take_a_while)]:"",this.done?[this.success?m("em.help.green",o.fetching_mailchimp_lists_done):m("em.help.red",o.fetching_mailchimp_lists_error)]:""])])},t.exports=a},{}],4:[function(e,t,n){"use strict";var l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};t.exports=function(e,t,n){e.querySelector("form");var r=e.querySelectorAll(".mc4wp-list-input"),i=mc4wp_vars.mailchimp.lists,o=[];function a(){return o=[],Array.prototype.forEach.call(r,function(e){("boolean"!=typeof e.checked||e.checked)&&"object"===l(i[e.value])&&o.push(i[e.value])}),n.trigger("selectedLists.change",[o]),o}return n.on("selectedLists.change",function(){var e=document.querySelectorAll(".lists--only-selected > *");Array.prototype.forEach.call(e,function(e){var t,n,r=e.getAttribute("data-list-id");0<(t="id",n=r,o.filter(function(e){return e[t]===n})).length?e.setAttribute("class",e.getAttribute("class").replace("hidden","")):e.setAttribute("class",e.getAttribute("class")+" hidden")})}),t.bindEventToElements(r,"change",a),a(),{getSelectedLists:function(){return o}}}},{}],5:[function(e,t,n){"use strict";var d=e("./url.js");t.exports=function(i){var o=window.jQuery,e=o(i),r=e.find(".tab"),a=e.find(".nav-tab"),l=i.querySelector('input[name="_wp_http_referer"]'),s=[];function u(e){for(var t=0;t<s.length;t++)if(s[t].id===e)return s[t]}function c(e,t){if("string"==typeof e&&(e=u(e)),!e)return!1;null==t&&(t=!0),r.removeClass("tab-active").css("display","none"),a.removeClass("nav-tab-active"),Array.prototype.forEach.call(e.nav,function(e){e.className+=" nav-tab-active",e.blur()}),e.element.style.display="block",e.element.className+=" tab-active";var n=d.setParameter(window.location.href,"tab",e.id);return history.pushState&&t&&history.pushState(e.id,"",n),f(e),l.value=n,"function"==typeof tb_remove&&tb_remove(),"fields"===e.id&&window.mc4wp&&window.mc4wp.forms&&window.mc4wp.forms.editor&&mc4wp.forms.editor.refresh(),!0}function f(e){var t=document.title.split("-");document.title=document.title.replace(t[0],e.title+" ")}function t(e){e=e||window.event;var t=this.getAttribute("data-tab");if(!t){var n=this.className.match(/nav-tab-(\w+)?/);n&&(t=n[1])}if(!t){var r=d.parse(this.href);if(!r.tab)return;t=r.tab}return!c(t)||(e.preventDefault(),e.returnValue=!1)}return o.each(r,function(e,t){var n=t.id.substring(4),r=o(t).find("h2").first().text();s.push({id:n,title:r,element:t,nav:i.querySelectorAll(".nav-tab-"+n),open:function(){return c(n)}})}),a.click(t),o(document.body).on("click",".tab-link",t),function(){if(history.pushState){var e=r.filter(":visible").get(0);if(e){var t=u(e.id.substring(4));t&&(history.replaceState&&null===history.state&&history.replaceState(t.id,""),f(t))}}}(),window.addEventListener&&history.pushState&&window.addEventListener("popstate",function(e){return!e.state||c(e.state,!1)}),{open:c,get:u}}},{"./url.js":6}],6:[function(e,t,n){"use strict";var i={parse:function(e){var t={},n=e.split("&");for(var r in n)if(n.hasOwnProperty(r)){var i=n[r].split("=");t[decodeURIComponent(i[0])]=decodeURIComponent(i[1])}return t},build:function(e){var t=[];for(var n in e)t.push(n+"="+encodeURIComponent(e[n]));return t.join("&")},setParameter:function(e,t,n){var r=i.parse(e);return r[t]=n,i.build(r)}};t.exports=i},{}],7:[function(e,L,t){(function(k,S){!function(){"use strict";function z(e,t,n,r,i,o){return{tag:e,key:t,attrs:n,children:r,text:i,dom:o,domSize:void 0,state:void 0,_state:void 0,events:void 0,instance:void 0,skip:!1}}z.normalize=function(e){return Array.isArray(e)?z("[",void 0,void 0,z.normalizeChildren(e),void 0,void 0):null!=e&&"object"!=typeof e?z("#",void 0,void 0,!1===e?"":e,void 0,void 0):e},z.normalizeChildren=function(e){for(var t=0;t<e.length;t++)e[t]=z.normalize(e[t]);return e};var s=/(?:(^|#|\.)([^#\.\[\]]+))|(\[(.+?)(?:\s*=\s*("|'|)((?:\\["'\]]|.)*?)\5)?\])/g,u={},c={}.hasOwnProperty;function f(e){for(var t in e)if(c.call(e,t))return!1;return!0}function e(e){var t,n=arguments[1],r=2;if(null==e||"string"!=typeof e&&"function"!=typeof e&&"function"!=typeof e.view)throw Error("The selector must be either a string or a component.");if("string"==typeof e)var i=u[e]||function(e){for(var t,n="div",r=[],i={};t=s.exec(e);){var o=t[1],a=t[2];if(""===o&&""!==a)n=a;else if("#"===o)i.id=a;else if("."===o)r.push(a);else if("["===t[3][0]){var l=t[6];l&&(l=l.replace(/\\(["'])/g,"$1").replace(/\\\\/g,"\\")),"class"===t[4]?r.push(l):i[t[4]]=""===l?l:l||!0}}return 0<r.length&&(i.className=r.join(" ")),u[e]={tag:n,attrs:i}}(e);if(null==n?n={}:("object"!=typeof n||null!=n.tag||Array.isArray(n))&&(n={},r=1),arguments.length===r+1)t=arguments[r],Array.isArray(t)||(t=[t]);else for(t=[];r<arguments.length;)t.push(arguments[r++]);var o=z.normalizeChildren(t);return"string"==typeof e?function(e,t,n){var r,i,o=!1,a=t.className||t.class;if(!f(e.attrs)&&!f(t)){var l={};for(var s in t)c.call(t,s)&&(l[s]=t[s]);t=l}for(var s in e.attrs)c.call(e.attrs,s)&&(t[s]=e.attrs[s]);for(var s in void 0!==a&&(void 0!==t.class&&(t.class=void 0,t.className=a),null!=e.attrs.className&&(t.className=e.attrs.className+" "+a)),t)if(c.call(t,s)&&"key"!==s){o=!0;break}return Array.isArray(n)&&1===n.length&&null!=n[0]&&"#"===n[0].tag?i=n[0].children:r=n,z(e.tag,t.key,o?t:void 0,r,i)}(i,n,o):z(e,n.key,n,o)}e.trust=function(e){return null==e&&(e=""),z("<",void 0,void 0,e,void 0,void 0)},e.fragment=function(e,t){return z("[",e.key,e,z.normalizeChildren(t),void 0,void 0)};var t=e;if((d=function(e){if(!(this instanceof d))throw new Error("Promise must be called with `new`");if("function"!=typeof e)throw new TypeError("executor must be a function");var o=this,a=[],l=[],i=t(a,!0),s=t(l,!1),u=o._instance={resolvers:a,rejectors:l},c="function"==typeof S?S:setTimeout;function t(r,i){return function t(n){var e;try{if(!i||null==n||"object"!=typeof n&&"function"!=typeof n||"function"!=typeof(e=n.then))c(function(){i||0!==r.length||console.error("Possible unhandled promise rejection:",n);for(var e=0;e<r.length;e++)r[e](n);a.length=0,l.length=0,u.state=i,u.retry=function(){t(n)}});else{if(n===o)throw new TypeError("Promise can't be resolved w/ itself");f(e.bind(n))}}catch(e){s(e)}}}function f(e){var n=0;function t(t){return function(e){0<n++||t(e)}}var r=t(s);try{e(t(i),r)}catch(e){r(e)}}f(e)}).prototype.then=function(e,t){var i,o,a=this._instance;function n(t,e,n,r){e.push(function(e){if("function"!=typeof t)n(e);else try{i(t(e))}catch(e){o&&o(e)}}),"function"==typeof a.retry&&r===a.state&&a.retry()}var r=new d(function(e,t){i=e,o=t});return n(e,a.resolvers,i,!0),n(t,a.rejectors,o,!1),r},d.prototype.catch=function(e){return this.then(null,e)},d.resolve=function(t){return t instanceof d?t:new d(function(e){e(t)})},d.reject=function(n){return new d(function(e,t){t(n)})},d.all=function(l){return new d(function(n,r){var i=l.length,o=0,a=[];if(0===l.length)n([]);else for(var e=0;e<l.length;e++)!function(t){function e(e){o++,a[t]=e,o===i&&n(a)}null==l[t]||"object"!=typeof l[t]&&"function"!=typeof l[t]||"function"!=typeof l[t].then?e(l[t]):l[t].then(e,r)}(e)})},d.race=function(r){return new d(function(e,t){for(var n=0;n<r.length;n++)r[n].then(e,t)})},"undefined"!=typeof window){void 0===window.Promise&&(window.Promise=d);var d=window.Promise}else if(void 0!==k){void 0===k.Promise&&(k.Promise=d);d=k.Promise}var p=function(e){if("[object Object]"!==Object.prototype.toString.call(e))return"";var r=[];for(var t in e)i(t,e[t]);return r.join("&");function i(e,t){if(Array.isArray(t))for(var n=0;n<t.length;n++)i(e+"["+n+"]",t[n]);else if("[object Object]"===Object.prototype.toString.call(t))for(var n in t)i(e+"["+n+"]",t[n]);else r.push(encodeURIComponent(e)+(null!=t&&""!==t?"="+encodeURIComponent(t):""))}},m=new RegExp("^file://","i"),n=function(s,r){var t,o=0;function a(){var i=0;function o(){0==--i&&"function"==typeof t&&t()}return function t(n){var r=n.then;return n.then=function(){i++;var e=r.apply(n,arguments);return e.then(o,function(e){if(o(),0===i)throw e}),t(e)},n}}function u(e,t){if("string"==typeof e){var n=e;null==(e=t||{}).url&&(e.url=n)}return e}function c(e,t){if(null==t)return e;for(var n=e.match(/:[^\/]+/gi)||[],r=0;r<n.length;r++){var i=n[r].slice(1);null!=t[i]&&(e=e.replace(n[r],t[i]))}return e}function f(e,t){var n=p(t);if(""!==n){var r=e.indexOf("?")<0?"?":"&";e+=r+n}return e}function d(t){try{return""!==t?JSON.parse(t):null}catch(e){throw new Error(t)}}function h(e){return e.responseText}function v(e,t){if("function"==typeof e){if(!Array.isArray(t))return new e(t);for(var n=0;n<t.length;n++)t[n]=new e(t[n])}return t}return{request:function(l,e){var t=a();l=u(l,e);var n=new r(function(r,i){null==l.method&&(l.method="GET"),l.method=l.method.toUpperCase();var e="GET"!==l.method&&"TRACE"!==l.method&&("boolean"!=typeof l.useBody||l.useBody);"function"!=typeof l.serialize&&(l.serialize="undefined"!=typeof FormData&&l.data instanceof FormData?function(e){return e}:JSON.stringify),"function"!=typeof l.deserialize&&(l.deserialize=d),"function"!=typeof l.extract&&(l.extract=h),l.url=c(l.url,l.data),e?l.data=l.serialize(l.data):l.url=f(l.url,l.data);var o=new s.XMLHttpRequest,a=!1,t=o.abort;for(var n in o.abort=function(){a=!0,t.call(o)},o.open(l.method,l.url,"boolean"!=typeof l.async||l.async,"string"==typeof l.user?l.user:void 0,"string"==typeof l.password?l.password:void 0),l.serialize!==JSON.stringify||!e||l.headers&&l.headers.hasOwnProperty("Content-Type")||o.setRequestHeader("Content-Type","application/json; charset=utf-8"),l.deserialize!==d||l.headers&&l.headers.hasOwnProperty("Accept")||o.setRequestHeader("Accept","application/json, text/*"),l.withCredentials&&(o.withCredentials=l.withCredentials),l.headers)({}).hasOwnProperty.call(l.headers,n)&&o.setRequestHeader(n,l.headers[n]);"function"==typeof l.config&&(o=l.config(o,l)||o),o.onreadystatechange=function(){if(!a&&4===o.readyState)try{var e=l.extract!==h?l.extract(o,l):l.deserialize(l.extract(o,l));if(200<=o.status&&o.status<300||304===o.status||m.test(l.url))r(v(l.type,e));else{var t=new Error(o.responseText);for(var n in e)t[n]=e[n];i(t)}}catch(e){i(e)}},e&&null!=l.data?o.send(l.data):o.send()});return!0===l.background?n:t(n)},jsonp:function(i,e){var t=a();i=u(i,e);var n=new r(function(t,e){var n=i.callbackName||"_mithril_"+Math.round(1e16*Math.random())+"_"+o++,r=s.document.createElement("script");s[n]=function(e){r.parentNode.removeChild(r),t(v(i.type,e)),delete s[n]},r.onerror=function(){r.parentNode.removeChild(r),e(new Error("JSONP request failed")),delete s[n]},null==i.data&&(i.data={}),i.url=c(i.url,i.data),i.data[i.callbackKey||"callback"]=n,r.src=f(i.url,i.data),s.document.documentElement.appendChild(r)});return!0===i.background?n:t(n)},setCompletionCallback:function(e){t=e}}}(window,d),r=function(e){var a,d=e.document,u=d.createDocumentFragment(),t={svg:"http://www.w3.org/2000/svg",math:"http://www.w3.org/1998/Math/MathML"};function h(e){return e.attrs&&e.attrs.xmlns||t[e.tag]}function b(e,t,n,r,i,o,a){for(var l=n;l<r;l++){var s=t[l];null!=s&&x(e,s,i,a,o)}}function x(e,t,n,r,i){var o,a,l,s=t.tag;if("string"!=typeof s)return function(e,t,n,r,i){{if(p(t,n),null==t.instance)return t.domSize=0,u;var o=x(e,t.instance,n,r,i);return t.dom=t.instance.dom,t.domSize=null!=t.dom?t.instance.domSize:0,k(e,o,i),o}}(e,t,n,r,i);switch(t.state={},null!=t.attrs&&j(t.attrs,t,n),s){case"#":return o=e,l=i,(a=t).dom=d.createTextNode(a.children),k(o,a.dom,l),a.dom;case"<":return v(e,t,i);case"[":return function(e,t,n,r,i){var o=d.createDocumentFragment();if(null!=t.children){var a=t.children;b(o,a,0,a.length,n,null,r)}return t.dom=o.firstChild,t.domSize=o.childNodes.length,k(e,o,i),o}(e,t,n,r,i);default:return function(e,t,n,r,i){var o=t.tag,a=t.attrs,l=a&&a.is,s=(r=h(t)||r)?l?d.createElementNS(r,o,{is:l}):d.createElementNS(r,o):l?d.createElement(o,{is:l}):d.createElement(o);t.dom=s,null!=a&&function(e,t,n){for(var r in t)w(e,r,null,t[r],n)}(t,a,r);if(k(e,s,i),null!=t.attrs&&null!=t.attrs.contenteditable)y(t);else if(null!=t.text&&(""!==t.text?s.textContent=t.text:t.children=[z("#",void 0,void 0,t.text,void 0,void 0)]),null!=t.children){var u=t.children;b(s,u,0,u.length,n,null,r),f=(c=t).attrs,"select"===c.tag&&null!=f&&("value"in f&&w(c,"value",null,f.value,void 0),"selectedIndex"in f&&w(c,"selectedIndex",null,f.selectedIndex,void 0))}var c,f;return s}(e,t,n,r,i)}}function v(e,t,n){var r={caption:"table",thead:"table",tbody:"table",tfoot:"table",tr:"tbody",th:"tr",td:"tr",colgroup:"table",col:"colgroup"}[(t.children.match(/^\s*?<(\w+)/im)||[])[1]]||"div",i=d.createElement(r);i.innerHTML=t.children,t.dom=i.firstChild,t.domSize=i.childNodes.length;for(var o,a=d.createDocumentFragment();o=i.firstChild;)a.appendChild(o);return k(e,a,n),a}function p(e,t){var n;if("function"==typeof e.tag.view){if(e.state=Object.create(e.tag),null!=(n=e.state.view).$$reentrantLock$$)return u;n.$$reentrantLock$$=!0}else{if(e.state=void 0,null!=(n=e.tag).$$reentrantLock$$)return u;n.$$reentrantLock$$=!0,e.state=null!=e.tag.prototype&&"function"==typeof e.tag.prototype.view?new e.tag(e):e.tag(e)}if(e._state=e.state,null!=e.attrs&&j(e.attrs,e,t),j(e._state,e,t),e.instance=z.normalize(e._state.view.call(e.state,e)),e.instance===e)throw Error("A view cannot return the vnode it received as argument");n.$$reentrantLock$$=null}function m(e,t,n,r,i,o,a){if(t!==n&&(null!=t||null!=n))if(null==t)b(e,n,0,n.length,i,o,a);else if(null==n)S(t,0,t.length,n);else{if(t.length===n.length){for(var l=!1,s=0;s<n.length;s++)if(null!=n[s]&&null!=t[s]){l=null==n[s].key&&null==t[s].key;break}if(l){for(s=0;s<t.length;s++)t[s]!==n[s]&&(null==t[s]&&null!=n[s]?x(e,n[s],i,a,T(t,s+1,o)):null==n[s]?S(t,s,s+1,n):E(e,t[s],n[s],i,T(t,s+1,o),r,a));return}}if(r=r||function(e,t){if(null!=e.pool&&Math.abs(e.pool.length-t.length)<=Math.abs(e.length-t.length)){var n=e[0]&&e[0].children&&e[0].children.length||0,r=e.pool[0]&&e.pool[0].children&&e.pool[0].children.length||0,i=t[0]&&t[0].children&&t[0].children.length||0;if(Math.abs(r-i)<=Math.abs(n-i))return!0}return!1}(t,n)){var u=t.pool;t=t.concat(t.pool)}for(var c,f=0,d=0,h=t.length-1,v=n.length-1;f<=h&&d<=v;){if((m=t[f])!==(y=n[d])||r)if(null==m)f++;else if(null==y)d++;else if(m.key===y.key){var p=null!=u&&f>=t.length-u.length||null==u&&r;d++,E(e,m,y,i,T(t,++f,o),p,a),r&&m.tag===y.tag&&k(e,_(m),o)}else{if((m=t[h])!==y||r)if(null==m)h--;else if(null==y)d++;else{if(m.key!==y.key)break;p=null!=u&&h>=t.length-u.length||null==u&&r;E(e,m,y,i,T(t,h+1,o),p,a),(r||d<v)&&k(e,_(m),T(t,f,o)),h--,d++}else h--,d++}else f++,d++}for(;f<=h&&d<=v;){var m,y;if((m=t[h])!==(y=n[v])||r)if(null==m)h--;else if(null==y)v--;else if(m.key===y.key){p=null!=u&&h>=t.length-u.length||null==u&&r;E(e,m,y,i,T(t,h+1,o),p,a),r&&m.tag===y.tag&&k(e,_(m),o),null!=m.dom&&(o=m.dom),h--,v--}else{if(c||(c=A(t,h)),null!=y){var g=c[y.key];if(null!=g){var w=t[g];p=null!=u&&g>=t.length-u.length||null==u&&r;E(e,w,y,i,T(t,h+1,o),r,a),k(e,_(w),o),t[g].skip=!0,null!=w.dom&&(o=w.dom)}else{o=x(e,y,i,a,o)}}v--}else h--,v--;if(v<d)break}b(e,n,d,v+1,i,o,a),S(t,f,h+1,n)}}function E(e,t,n,r,i,o,a){var l,s,u,c,f=t.tag;if(f===n.tag){if(n.state=t.state,n._state=t._state,n.events=t.events,!o&&function(e,t){var n,r;null!=e.attrs&&"function"==typeof e.attrs.onbeforeupdate&&(n=e.attrs.onbeforeupdate.call(e.state,e,t));"string"!=typeof e.tag&&"function"==typeof e._state.onbeforeupdate&&(r=e._state.onbeforeupdate.call(e.state,e,t));return!(void 0===n&&void 0===r||n||r||(e.dom=t.dom,e.domSize=t.domSize,e.instance=t.instance,0))}(n,t))return;if("string"==typeof f)switch(null!=n.attrs&&(o?(n.state={},j(n.attrs,n,r)):O(n.attrs,n,r)),f){case"#":!function(e,t){e.children.toString()!==t.children.toString()&&(e.dom.nodeValue=t.children);t.dom=e.dom}(t,n);break;case"<":l=e,u=n,c=i,(s=t).children!==u.children?(_(s),v(l,u,c)):(u.dom=s.dom,u.domSize=s.domSize);break;case"[":!function(e,t,n,r,i,o,a){m(e,t.children,n.children,r,i,o,a);var l=0,s=n.children;if((n.dom=null)!=s){for(var u=0;u<s.length;u++){var c=s[u];null!=c&&null!=c.dom&&(null==n.dom&&(n.dom=c.dom),l+=c.domSize||1)}1!==l&&(n.domSize=l)}}(e,t,n,o,r,i,a);break;default:!function(e,t,n,r,i){var o=t.dom=e.dom;i=h(t)||i,"textarea"===t.tag&&(null==t.attrs&&(t.attrs={}),null!=t.text&&(t.attrs.value=t.text,t.text=void 0));(function(e,t,n,r){if(null!=n)for(var i in n)w(e,i,t&&t[i],n[i],r);if(null!=t)for(var i in t)null!=n&&i in n||("className"===i&&(i="class"),"o"!==i[0]||"n"!==i[1]||L(i)?"key"!==i&&e.dom.removeAttribute(i):C(e,i,void 0))})(t,e.attrs,t.attrs,i),null!=t.attrs&&null!=t.attrs.contenteditable?y(t):null!=e.text&&null!=t.text&&""!==t.text?e.text.toString()!==t.text.toString()&&(e.dom.firstChild.nodeValue=t.text):(null!=e.text&&(e.children=[z("#",void 0,void 0,e.text,void 0,e.dom.firstChild)]),null!=t.text&&(t.children=[z("#",void 0,void 0,t.text,void 0,void 0)]),m(o,e.children,t.children,n,r,null,i))}(t,n,o,r,a)}else!function(e,t,n,r,i,o,a){if(o)p(n,r);else{if(n.instance=z.normalize(n._state.view.call(n.state,n)),n.instance===n)throw Error("A view cannot return the vnode it received as argument");null!=n.attrs&&O(n.attrs,n,r),O(n._state,n,r)}null!=n.instance?(null==t.instance?x(e,n.instance,r,a,i):E(e,t.instance,n.instance,r,i,o,a),n.dom=n.instance.dom,n.domSize=n.instance.domSize):null!=t.instance?(g(t.instance,null),n.dom=void 0,n.domSize=0):(n.dom=t.dom,n.domSize=t.domSize)}(e,t,n,r,i,o,a)}else g(t,null),x(e,n,r,a,i)}function A(e,t){var n={},r=0;for(r=0;r<t;r++){var i=e[r];if(null!=i){var o=i.key;null!=o&&(n[o]=r)}}return n}function _(e){var t=e.domSize;if(null==t&&null!=e.dom)return e.dom;var n=d.createDocumentFragment();if(0<t){for(var r=e.dom;--t;)n.appendChild(r.nextSibling);n.insertBefore(r,n.firstChild)}return n}function T(e,t,n){for(;t<e.length;t++)if(null!=e[t]&&null!=e[t].dom)return e[t].dom;return n}function k(e,t,n){n&&n.parentNode?e.insertBefore(t,n):e.appendChild(t)}function y(e){var t=e.children;if(null!=t&&1===t.length&&"<"===t[0].tag){var n=t[0].children;e.dom.innerHTML!==n&&(e.dom.innerHTML=n)}else if(null!=e.text||null!=t&&0!==t.length)throw new Error("Child node of a contenteditable must be trusted")}function S(e,t,n,r){for(var i=t;i<n;i++){var o=e[i];null!=o&&(o.skip?o.skip=!1:g(o,r))}}function g(r,i){var e,o=1,a=0;r.attrs&&"function"==typeof r.attrs.onbeforeremove&&(null!=(e=r.attrs.onbeforeremove.call(r.state,r))&&"function"==typeof e.then&&(o++,e.then(t,t)));"string"!=typeof r.tag&&"function"==typeof r._state.onbeforeremove&&(null!=(e=r._state.onbeforeremove.call(r.state,r))&&"function"==typeof e.then&&(o++,e.then(t,t)));function t(){if(++a===o&&(function e(t){t.attrs&&"function"==typeof t.attrs.onremove&&t.attrs.onremove.call(t.state,t);if("string"!=typeof t.tag)"function"==typeof t._state.onremove&&t._state.onremove.call(t.state,t),null!=t.instance&&e(t.instance);else{var n=t.children;if(Array.isArray(n))for(var r=0;r<n.length;r++){var i=n[r];null!=i&&e(i)}}}(r),r.dom)){var e=r.domSize||1;if(1<e)for(var t=r.dom;--e;)l(t.nextSibling);l(r.dom),null==i||null!=r.domSize||null!=(n=r.attrs)&&(n.oncreate||n.onupdate||n.onbeforeremove||n.onremove)||"string"!=typeof r.tag||(i.pool?i.pool.push(r):i.pool=[r])}var n}t()}function l(e){var t=e.parentNode;null!=t&&t.removeChild(e)}function w(e,t,n,r,i){var o=e.dom;if("key"!==t&&"is"!==t&&(n!==r||(a=e,"value"===(l=t)||"checked"===l||"selectedIndex"===l||"selected"===l&&a.dom===d.activeElement)||"object"==typeof r)&&void 0!==r&&!L(t)){var a,l,s,u,c=t.indexOf(":");if(-1<c&&"xlink"===t.substr(0,c))o.setAttributeNS("http://www.w3.org/1999/xlink",t.slice(c+1),r);else if("o"===t[0]&&"n"===t[1]&&"function"==typeof r)C(e,t,r);else if("style"===t)!function(e,t,n){t===n&&(e.style.cssText="",t=null);if(null==n)e.style.cssText="";else if("string"==typeof n)e.style.cssText=n;else{for(var r in"string"==typeof t&&(e.style.cssText=""),n)e.style[r]=n[r];if(null!=t&&"string"!=typeof t)for(var r in t)r in n||(e.style[r]="")}}(o,n,r);else if(t in o&&("href"!==(u=t)&&"list"!==u&&"form"!==u&&"width"!==u&&"height"!==u)&&void 0===i&&!((s=e).attrs.is||-1<s.tag.indexOf("-"))){if("value"===t){var f=""+r;if(("input"===e.tag||"textarea"===e.tag)&&e.dom.value===f&&e.dom===d.activeElement)return;if("select"===e.tag)if(null===r){if(-1===e.dom.selectedIndex&&e.dom===d.activeElement)return}else if(null!==n&&e.dom.value===f&&e.dom===d.activeElement)return;if("option"===e.tag&&null!=n&&e.dom.value===f)return}if("input"===e.tag&&"type"===t)return void o.setAttribute(t,r);o[t]=r}else"boolean"==typeof r?r?o.setAttribute(t,""):o.removeAttribute(t):o.setAttribute("className"===t?"class":t,r)}}function L(e){return"oninit"===e||"oncreate"===e||"onupdate"===e||"onremove"===e||"onbeforeremove"===e||"onbeforeupdate"===e}function C(e,t,n){var r=e.dom,i="function"!=typeof a?n:function(e){var t=n.call(r,e);return a.call(r,e),t};if(t in r)r[t]="function"==typeof n?i:null;else{var o=t.slice(2);if(void 0===e.events&&(e.events={}),e.events[t]===i)return;null!=e.events[t]&&r.removeEventListener(o,e.events[t],!1),"function"==typeof n&&(e.events[t]=i,r.addEventListener(o,e.events[t],!1))}}function j(e,t,n){"function"==typeof e.oninit&&e.oninit.call(t.state,t),"function"==typeof e.oncreate&&n.push(e.oncreate.bind(t.state,t))}function O(e,t,n){"function"==typeof e.onupdate&&n.push(e.onupdate.bind(t.state,t))}return{render:function(e,t){if(!e)throw new Error("Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined.");var n=[],r=d.activeElement,i=e.namespaceURI;null==e.vnodes&&(e.textContent=""),Array.isArray(t)||(t=[t]),m(e,e.vnodes,z.normalizeChildren(t),!1,n,null,"http://www.w3.org/1999/xhtml"===i?void 0:i),e.vnodes=t,null!=r&&d.activeElement!==r&&r.focus();for(var o=0;o<n.length;o++)n[o]()},setEventCallback:function(e){return a=e}}};var i=function(e){var t=r(e);t.setEventCallback(function(e){!1===e.redraw?e.redraw=void 0:n()});var a=[];function l(e){var t=a.indexOf(e);-1<t&&a.splice(t,2)}function n(){for(var e=1;e<a.length;e+=2)a[e]()}return{subscribe:function(e,t){var n,r,i,o;l(e),a.push(e,(n=t,r=0,i=null,o="function"==typeof requestAnimationFrame?requestAnimationFrame:setTimeout,function(){var e=Date.now();0===r||16<=e-r?(r=e,n()):null===i&&(i=o(function(){i=null,n(),r=Date.now()},16-(e-r)))}))},unsubscribe:l,redraw:n,render:t.render}}(window);n.setCompletionCallback(i.redraw);var o;t.mount=(o=i,function(e,t){if(null===t)return o.render(e,[]),void o.unsubscribe(e);if(null==t.view&&"function"!=typeof t)throw new Error("m.mount(element, component) expects a component, not a vnode");o.subscribe(e,function(){o.render(e,z(t))}),o.redraw()});var a,l,h,v,y,g,w,b,x,E=d,A=function(e){if(""===e||null==e)return{};"?"===e.charAt(0)&&(e=e.slice(1));for(var t=e.split("&"),n={},r={},i=0;i<t.length;i++){var o=t[i].split("="),a=decodeURIComponent(o[0]),l=2===o.length?decodeURIComponent(o[1]):"";"true"===l?l=!0:"false"===l&&(l=!1);var s=a.split(/\]\[?|\[/),u=n;-1<a.indexOf("[")&&s.pop();for(var c=0;c<s.length;c++){var f=s[c],d=s[c+1],h=""==d||!isNaN(parseInt(d,10)),v=c===s.length-1;if(""===f)null==r[a=s.slice(0,c).join()]&&(r[a]=0),f=r[a]++;null==u[f]&&(u[f]=v?l:h?[]:{}),u=u[f]}}return n},_=function(c){var n,f="function"==typeof c.history.pushState,r="function"==typeof S?S:setTimeout;function e(e){var t=c.location[e].replace(/(?:%[a-f89][a-f0-9])+/gim,decodeURIComponent);return"pathname"===e&&"/"!==t[0]&&(t="/"+t),t}function d(e,t,n){var r=e.indexOf("?"),i=e.indexOf("#"),o=-1<r?r:-1<i?i:e.length;if(-1<r){var a=-1<i?i:e.length,l=A(e.slice(r+1,a));for(var s in l)t[s]=l[s]}if(-1<i){var u=A(e.slice(i+1));for(var s in u)n[s]=u[s]}return e.slice(0,o)}var h={prefix:"#!",getPath:function(){switch(h.prefix.charAt(0)){case"#":return e("hash").slice(h.prefix.length);case"?":return e("search").slice(h.prefix.length)+e("hash");default:return e("pathname").slice(h.prefix.length)+e("search")+e("hash")}},setPath:function(e,n,t){var r={},i={};if(e=d(e,r,i),null!=n){for(var o in n)r[o]=n[o];e=e.replace(/:([^\/]+)/g,function(e,t){return delete r[t],n[t]})}var a=p(r);a&&(e+="?"+a);var l=p(i);if(l&&(e+="#"+l),f){var s=t?t.state:null,u=t?t.title:null;c.onpopstate(),t&&t.replace?c.history.replaceState(s,u,h.prefix+e):c.history.pushState(s,u,h.prefix+e)}else c.location.href=h.prefix+e}};return h.defineRoutes=function(l,s,u){function e(){var r=h.getPath(),i={},e=d(r,i,i),t=c.history.state;if(null!=t)for(var n in t)i[n]=t[n];for(var o in l){var a=new RegExp("^"+o.replace(/:[^\/]+?\.{3}/g,"(.*?)").replace(/:[^\/]+/g,"([^\\/]+)")+"/?$");if(a.test(e))return void e.replace(a,function(){for(var e=o.match(/:[^\/]+/g)||[],t=[].slice.call(arguments,1,-2),n=0;n<e.length;n++)i[e[n].replace(/:|\./g,"")]=decodeURIComponent(t[n]);s(l[o],i,r,o)})}u(r,i)}var t;f?c.onpopstate=(t=e,function(){null==n&&(n=r(function(){n=null,t()}))}):"#"===h.prefix.charAt(0)&&(c.onhashchange=e),e()},h};t.route=(a=window,l=i,b=_(a),(x=function(e,t,n){if(null==e)throw new Error("Ensure the DOM element that was passed to `m.route` is not undefined");var o=function(){null!=h&&l.render(e,h(z(v,y.key,y)))},a=function(e){if(e===t)throw new Error("Could not resolve default route "+t);b.setPath(t,null,{replace:!0})};b.defineRoutes(n,function(t,n,r){var i=w=function(e,t){i===w&&(v=null==t||"function"!=typeof t.view&&"function"!=typeof t?"div":t,y=n,g=r,w=null,h=(e.render||function(e){return e}).bind(e),o())};t.view||"function"==typeof t?i({},t):t.onmatch?E.resolve(t.onmatch(n,r)).then(function(e){i(t,e)},a):i(t,"div")},a),l.subscribe(e,o)}).set=function(e,t,n){null!=w&&((n=n||{}).replace=!0),w=null,b.setPath(e,t,n)},x.get=function(){return g},x.prefix=function(e){b.prefix=e},x.link=function(e){e.dom.setAttribute("href",b.prefix+e.attrs.href),e.dom.onclick=function(e){if(!(e.ctrlKey||e.metaKey||e.shiftKey||2===e.which)){e.preventDefault(),e.redraw=!1;var t=this.getAttribute("href");0===t.indexOf(b.prefix)&&(t=t.slice(b.prefix.length)),x.set(t,void 0,void 0)}}},x.param=function(e){return void 0!==y&&void 0!==e?y[e]:y},x),t.withAttr=function(t,n,r){return function(e){n.call(r||this,t in e.currentTarget?e.currentTarget[t]:e.currentTarget.getAttribute(t))}};var T=r(window);t.render=T.render,t.redraw=i.redraw,t.request=n.request,t.jsonp=n.jsonp,t.parseQueryString=A,t.buildQueryString=p,t.version="1.1.6",t.vnode=z,void 0!==L?L.exports=t:window.m=t}()}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},e("timers").setImmediate)},{timers:9}],8:[function(e,t,n){var r,i,o=t.exports={};function a(){throw new Error("setTimeout has not been defined")}function l(){throw new Error("clearTimeout has not been defined")}function s(t){if(r===setTimeout)return setTimeout(t,0);if((r===a||!r)&&setTimeout)return r=setTimeout,setTimeout(t,0);try{return r(t,0)}catch(e){try{return r.call(null,t,0)}catch(e){return r.call(this,t,0)}}}!function(){try{r="function"==typeof setTimeout?setTimeout:a}catch(e){r=a}try{i="function"==typeof clearTimeout?clearTimeout:l}catch(e){i=l}}();var u,c=[],f=!1,d=-1;function h(){f&&u&&(f=!1,u.length?c=u.concat(c):d=-1,c.length&&v())}function v(){if(!f){var e=s(h);f=!0;for(var t=c.length;t;){for(u=c,c=[];++d<t;)u&&u[d].run();d=-1,t=c.length}u=null,f=!1,function(t){if(i===clearTimeout)return clearTimeout(t);if((i===l||!i)&&clearTimeout)return i=clearTimeout,clearTimeout(t);try{i(t)}catch(e){try{return i.call(null,t)}catch(e){return i.call(this,t)}}}(e)}}function p(e,t){this.fun=e,this.array=t}function m(){}o.nextTick=function(e){var t=new Array(arguments.length-1);if(1<arguments.length)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];c.push(new p(e,t)),1!==c.length||f||s(v)},p.prototype.run=function(){this.fun.apply(null,this.array)},o.title="browser",o.browser=!0,o.env={},o.argv=[],o.version="",o.versions={},o.on=m,o.addListener=m,o.once=m,o.off=m,o.removeListener=m,o.removeAllListeners=m,o.emit=m,o.prependListener=m,o.prependOnceListener=m,o.listeners=function(e){return[]},o.binding=function(e){throw new Error("process.binding is not supported")},o.cwd=function(){return"/"},o.chdir=function(e){throw new Error("process.chdir is not supported")},o.umask=function(){return 0}},{}],9:[function(s,e,u){(function(e,t){var r=s("process/browser.js").nextTick,n=Function.prototype.apply,i=Array.prototype.slice,o={},a=0;function l(e,t){this._id=e,this._clearFn=t}u.setTimeout=function(){return new l(n.call(setTimeout,window,arguments),clearTimeout)},u.setInterval=function(){return new l(n.call(setInterval,window,arguments),clearInterval)},u.clearTimeout=u.clearInterval=function(e){e.close()},l.prototype.unref=l.prototype.ref=function(){},l.prototype.close=function(){this._clearFn.call(window,this._id)},u.enroll=function(e,t){clearTimeout(e._idleTimeoutId),e._idleTimeout=t},u.unenroll=function(e){clearTimeout(e._idleTimeoutId),e._idleTimeout=-1},u._unrefActive=u.active=function(e){clearTimeout(e._idleTimeoutId);var t=e._idleTimeout;0<=t&&(e._idleTimeoutId=setTimeout(function(){e._onTimeout&&e._onTimeout()},t))},u.setImmediate="function"==typeof e?e:function(e){var t=a++,n=!(arguments.length<2)&&i.call(arguments,1);return o[t]=!0,r(function(){o[t]&&(n?e.apply(null,n):e.call(null),u.clearImmediate(t))}),t},u.clearImmediate="function"==typeof t?t:function(e){delete o[e]}}).call(this,s("timers").setImmediate,s("timers").clearImmediate)},{"process/browser.js":8,timers:9}],10:[function(e,t,n){function u(r){document.addEventListener("mouseover",function(e){var t=e.target,n=r(t);n||(n=(t=t.parentElement)&&r(t)),n&&u.show(t,n,!0)})}u.show=function(e,t,l){var s="data-tlite";t=t||{},(e.tooltip||function(e,t){var n,r,i;function o(){u.hide(e,!0)}function a(){n||(n=function(l,e,t){var s=document.createElement("span"),n=t.grav||l.getAttribute("data-tlite")||"n";s.innerHTML=e,l.appendChild(s);var u=n[0]||"",c=n[1]||"";function r(){s.className="tlite tlite-"+u+c;var e=l.offsetTop,t=l.offsetLeft;s.offsetParent===l&&(e=t=0);var n=l.offsetWidth,r=l.offsetHeight,i=s.offsetHeight,o=s.offsetWidth,a=t+n/2;s.style.top=("s"===u?e-i-10:"n"===u?e+r+10:e+r/2-i/2)+"px",s.style.left=("w"===c?t:"e"===c?t+n-o:"w"===u?t+n+10:"e"===u?t-o-10:a-o/2)+"px"}r();var i=s.getBoundingClientRect();"s"===u&&i.top<0?(u="n",r()):"n"===u&&i.bottom>window.innerHeight?(u="s",r()):"e"===u&&i.left<0?(u="w",r()):"w"===u&&i.right>window.innerWidth&&(u="e",r());return s.className+=" tlite-visible",s}(e,i,t))}return e.addEventListener("mousedown",o),e.addEventListener("mouseleave",o),e.tooltip={show:function(){i=e.title||e.getAttribute(s)||i,e.title="",e.setAttribute(s,""),i&&!r&&(r=setTimeout(a,l?150:1))},hide:function(e){if(l===e){r=clearTimeout(r);var t=n&&n.parentNode;t&&t.removeChild(n),n=void 0}}}}(e,t)).show()},u.hide=function(e,t){e.tooltip&&e.tooltip.hide(t)},void 0!==t&&t.exports&&(t.exports=u)},{}],11:[function(e,a,t){!function(e){"use strict";function t(){}var n=t.prototype,r=e.EventEmitter;function o(e,t){for(var n=e.length;n--;)if(e[n].listener===t)return n;return-1}function i(e){return function(){return this[e].apply(this,arguments)}}n.getListeners=function(e){var t,n,r=this._getEvents();if(e instanceof RegExp)for(n in t={},r)r.hasOwnProperty(n)&&e.test(n)&&(t[n]=r[n]);else t=r[e]||(r[e]=[]);return t},n.flattenListeners=function(e){var t,n=[];for(t=0;t<e.length;t+=1)n.push(e[t].listener);return n},n.getListenersAsObject=function(e){var t,n=this.getListeners(e);return n instanceof Array&&((t={})[e]=n),t||n},n.addListener=function(e,t){if(!function e(t){return"function"==typeof t||t instanceof RegExp||!(!t||"object"!=typeof t)&&e(t.listener)}(t))throw new TypeError("listener must be a function");var n,r=this.getListenersAsObject(e),i="object"==typeof t;for(n in r)r.hasOwnProperty(n)&&-1===o(r[n],t)&&r[n].push(i?t:{listener:t,once:!1});return this},n.on=i("addListener"),n.addOnceListener=function(e,t){return this.addListener(e,{listener:t,once:!0})},n.once=i("addOnceListener"),n.defineEvent=function(e){return this.getListeners(e),this},n.defineEvents=function(e){for(var t=0;t<e.length;t+=1)this.defineEvent(e[t]);return this},n.removeListener=function(e,t){var n,r,i=this.getListenersAsObject(e);for(r in i)i.hasOwnProperty(r)&&-1!==(n=o(i[r],t))&&i[r].splice(n,1);return this},n.off=i("removeListener"),n.addListeners=function(e,t){return this.manipulateListeners(!1,e,t)},n.removeListeners=function(e,t){return this.manipulateListeners(!0,e,t)},n.manipulateListeners=function(e,t,n){var r,i,o=e?this.removeListener:this.addListener,a=e?this.removeListeners:this.addListeners;if("object"!=typeof t||t instanceof RegExp)for(r=n.length;r--;)o.call(this,t,n[r]);else for(r in t)t.hasOwnProperty(r)&&(i=t[r])&&("function"==typeof i?o.call(this,r,i):a.call(this,r,i));return this},n.removeEvent=function(e){var t,n=typeof e,r=this._getEvents();if("string"===n)delete r[e];else if(e instanceof RegExp)for(t in r)r.hasOwnProperty(t)&&e.test(t)&&delete r[t];else delete this._events;return this},n.removeAllListeners=i("removeEvent"),n.emitEvent=function(e,t){var n,r,i,o,a=this.getListenersAsObject(e);for(o in a)if(a.hasOwnProperty(o))for(n=a[o].slice(0),i=0;i<n.length;i++)!0===(r=n[i]).once&&this.removeListener(e,r.listener),r.listener.apply(this,t||[])===this._getOnceReturnValue()&&this.removeListener(e,r.listener);return this},n.trigger=i("emitEvent"),n.emit=function(e){var t=Array.prototype.slice.call(arguments,1);return this.emitEvent(e,t)},n.setOnceReturnValue=function(e){return this._onceReturnValue=e,this},n._getOnceReturnValue=function(){return!this.hasOwnProperty("_onceReturnValue")||this._onceReturnValue},n._getEvents=function(){return this._events||(this._events={})},t.noConflict=function(){return e.EventEmitter=r,t},"function"==typeof l&&l.amd?l(function(){return t}):"object"==typeof a&&a.exports?a.exports=t:e.EventEmitter=t}("undefined"!=typeof window?window:this||{})},{}]},{},[1])}();
2
  //# sourceMappingURL=admin.min.js.map
assets/js/admin.min.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["admin.js"],"names":["define","undefined","r","e","n","t","o","i","f","c","u","a","Error","code","p","exports","call","length","1","require","module","obj","_tlite","_tlite2","__esModule","default","m","window","EventEmitter","context","document","getElementById","events","tabs","helpers","settings","el","className","indexOf","ListFetcher","mount","mc4wp","deps","mithril","./admin/helpers.js","./admin/list-fetcher.js","./admin/settings.js","./admin/tabs.js","tlite","wolfy87-eventemitter","2","showIfElements","toggleElement","selector","elements","querySelectorAll","show","clientHeight","style","display","bindEventToElement","element","event","handler","addEventListener","attachEvent","bindEventToElements","Array","prototype","forEach","debounce","func","wait","immediate","timeout","this","args","arguments","callNow","clearTimeout","setTimeout","apply","config","JSON","parse","getAttribute","parentElements","inputs","hide","checked","conditionMet","value","visibility","opacity","inputElement","removeAttribute","setAttribute","parentElement","3","$","jQuery","mc4wp_vars","i18n","working","done","mailchimp","api_connected","lists","fetch","preventDefault","post","ajaxurl","action","data","success","location","reload","bind","fail","always","redraw","view","method","onsubmit","type","fetching_mailchimp_lists","renew_mailchimp_lists","disabled","trust","fetching_mailchimp_lists_can_take_a_while","fetching_mailchimp_lists_done","fetching_mailchimp_lists_error","4","_typeof","Symbol","iterator","constructor","querySelector","listInputs","selectedLists","updateSelectedLists","input","push","trigger","on","rows","searchKey","searchValue","listId","filter","replace","getSelectedLists","5","URL","$context","$tabs","find","$tabNavs","refererField","get","id","_open","tab","updateState","removeClass","css","nav","blur","url","setParameter","href","history","pushState","title","tb_remove","forms","editor","refresh","split","switchTab","tabId","match","urlParams","returnValue","each","substring","first","text","open","click","body","activeTab","replaceState","state","init","./url.js","6","query","hasOwnProperty","b","decodeURIComponent","build","ret","d","encodeURIComponent","join","key","7","cachedSetTimeout","cachedClearTimeout","process","defaultSetTimout","defaultClearTimeout","runTimeout","fun","currentQueue","queue","draining","queueIndex","cleanUpNextTick","concat","drainQueue","len","run","marker","runClearTimeout","Item","array","noop","nextTick","browser","env","argv","version","versions","addListener","once","off","removeListener","removeAllListeners","emit","prependListener","prependOnceListener","listeners","name","binding","cwd","chdir","dir","umask","8","setImmediate","clearImmediate","Function","slice","immediateIds","nextImmediateId","Timeout","clearFn","_id","_clearFn","setInterval","clearInterval","close","unref","ref","enroll","item","msecs","_idleTimeoutId","_idleTimeout","unenroll","_unrefActive","active","_onTimeout","fn","process/browser.js","timers","9","global","Vnode","tag","attrs0","children","dom","attrs","domSize","_state","instance","skip","normalize","node","isArray","normalizeChildren","selectorParser","selectorCache","hasOwn","isEmpty","object","hyperscript","start","cached","classes","exec","attrValue","compileSelector","normalized","childList","hasAttrs","class","newAttrs","execSelector","html","fragment","attrs1","PromisePolyfill","executor","TypeError","self","resolvers","rejectors","resolveCurrent","rejectCurrent","_instance","callAsync","list","shouldAbsorb","execute","then","console","error","retry","executeOnce","runs","onerror","onFulfilled","onRejection","resolveNext","rejectNext","handle","callback","next","promise","resolve","reject","catch","all","total","count","values","consume","race","Promise","buildQueryString","Object","toString","key0","destructure","FILE_PROTOCOL_REGEX","RegExp","requestService","$window","oncompletion","callbackCount","finalizer","complete","finalize","promise0","then0","extra","interpolate","tokens","assemble","querystring","prefix","deserialize","extract","xhr","responseText","cast","type0","request","toUpperCase","useBody","serialize","FormData","stringify","XMLHttpRequest","aborted","_abort","abort","async","user","password","headers","setRequestHeader","withCredentials","onreadystatechange","readyState","response","status","test","send","background","jsonp","callbackName","Math","round","random","script","createElement","parentNode","removeChild","callbackKey","src","documentElement","appendChild","setCompletionCallback","_8","coreRenderer","onevent","$doc","$emptyFragment","createDocumentFragment","nameSpace","svg","math","getNameSpace","vnode","xmlns","createNodes","parent","vnodes","end","hooks","nextSibling","ns","createNode","initComponent","insertNode","createComponent","initLifecycle","createTextNode","createHTML","firstChild","childNodes","createFragment","attrs2","is","createElementNS","key2","setAttr","setAttrs","contenteditable","setContentEditable","textContent","selectedIndex","parent1","caption","thead","tbody","tfoot","tr","th","td","colgroup","col","temp","innerHTML","child","sentinel","create","$$reentrantLock$$","updateNodes","old","recycling","removeNodes","isUnkeyed","getNextSibling","updateNode","pool","abs","oldChildrenLength","poolChildrenLength","vnodesChildrenLength","isRecyclable","map","oldStart","oldEnd","v","shouldRecycle","toFragment","getKeyMap","oldIndex","movable","oldTag","forceVnodeUpdate","forceComponentUpdate","onbeforeupdate","shouldNotUpdate","updateLifecycle","nodeValue","updateText","updateFragment","isLifecycleMethod","updateEvent","updateAttrs","updateElement","removeNode","updateComponent","count0","insertBefore","content","result","expected","called","onbeforeremove","continuation","onremove","removeNodeFromDOM","source","oncreate","onupdate","attr","activeElement","nsLastIndex","substr","setAttributeNS","cssText","updateStyle","normalized0","eventName","removeEventListener","oninit","render","namespace","namespaceURI","focus","setEventCallback","redrawService","renderService","callbacks","unsubscribe","key1","index","splice","subscribe","last","pending","requestAnimationFrame","now","Date","_11","redrawService0","root","component","render1","attrs3","currentPath","lastUpdate","routeService","route","parseQueryString","string","charAt","entries","data0","counters","entry","key5","levels","cursor","pop","j","level","nextLevel","isNumber","isNaN","parseInt","isValue","coreRouter","asyncId","supportsPushState","callAsync0","normalize1","fragment0","parsePath","path","queryData","hashData","queryIndex","hashIndex","pathEnd","queryEnd","queryParams","key4","hashParams","router","getPath","setPath","options","match2","token","hash","onpopstate","defineRoutes","routes","resolveRoute","params","pathname","k","route0","matcher","keys","callback0","onhashchange","defaultRoute","run1","bail","payload","update","routeResolver","comp","onmatch","resolved","set","prefix0","link","vnode1","onclick","ctrlKey","metaKey","shiftKey","which","param","key3","withAttr","attrName","callback1","currentTarget","_28","10","getTooltipOpts","target","opts","isAuto","fallbackAttrib","tooltip","tooltipEl","showTimer","autoHide","fadeIn","grav","vertGrav","horzGrav","positionTooltip","top","offsetTop","left","offsetLeft","offsetParent","width","offsetWidth","height","offsetHeight","tooltipHeight","tooltipWidth","centerEl","rect","getBoundingClientRect","bottom","innerHeight","right","innerWidth","createTooltip","isAutoHiding","Tooltip","11","proto","originalGlobalValue","indexOfListener","listener","alias","getListeners","evt","_getEvents","flattenListeners","flatListeners","getListenersAsObject","isValidListener","listenerIsWrapped","addOnceListener","defineEvent","defineEvents","evts","addListeners","manipulateListeners","removeListeners","remove","single","multiple","removeEvent","_events","emitEvent","listenersMap","_getOnceReturnValue","setOnceReturnValue","_onceReturnValue","noConflict","amd"],"mappings":"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","file":"admin.min.js","sourcesContent":["(function () { var require = undefined; var define = undefined; (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){\n'use strict';\n\n// dependencies\n\nvar _tlite = require('tlite');\n\nvar _tlite2 = _interopRequireDefault(_tlite);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar m = window.m = require('mithril');\nvar EventEmitter = require('wolfy87-eventemitter');\n\n// vars\nvar context = document.getElementById('mc4wp-admin');\nvar events = new EventEmitter();\nvar tabs = require('./admin/tabs.js')(context);\nvar helpers = require('./admin/helpers.js');\nvar settings = require('./admin/settings.js')(context, helpers, events);\n\n(0, _tlite2.default)(function (el) {\n return el.className.indexOf('mc4wp-tooltip') > -1;\n});\n\n// list fetcher\nvar ListFetcher = require('./admin/list-fetcher.js');\nvar mount = document.getElementById('mc4wp-list-fetcher');\nif (mount) {\n m.mount(mount, new ListFetcher());\n}\n\n// expose some things\nwindow.mc4wp = window.mc4wp || {};\nwindow.mc4wp.deps = window.mc4wp.deps || {};\nwindow.mc4wp.deps.mithril = m;\nwindow.mc4wp.helpers = helpers;\nwindow.mc4wp.events = events;\nwindow.mc4wp.settings = settings;\nwindow.mc4wp.tabs = tabs;\n\n},{\"./admin/helpers.js\":2,\"./admin/list-fetcher.js\":3,\"./admin/settings.js\":4,\"./admin/tabs.js\":5,\"mithril\":9,\"tlite\":10,\"wolfy87-eventemitter\":11}],2:[function(require,module,exports){\n'use strict';\n\nvar helpers = {};\n\nhelpers.toggleElement = function (selector) {\n\tvar elements = document.querySelectorAll(selector);\n\tfor (var i = 0; i < elements.length; i++) {\n\t\tvar show = elements[i].clientHeight <= 0;\n\t\telements[i].style.display = show ? '' : 'none';\n\t}\n};\n\nhelpers.bindEventToElement = function (element, event, handler) {\n\tif (element.addEventListener) {\n\t\telement.addEventListener(event, handler);\n\t} else if (element.attachEvent) {\n\t\telement.attachEvent('on' + event, handler);\n\t}\n};\n\nhelpers.bindEventToElements = function (elements, event, handler) {\n\tArray.prototype.forEach.call(elements, function (element) {\n\t\thelpers.bindEventToElement(element, event, handler);\n\t});\n};\n\n// polling\nhelpers.debounce = function (func, wait, immediate) {\n\tvar timeout;\n\treturn function () {\n\t\tvar context = this,\n\t\t args = arguments;\n\t\tvar later = function later() {\n\t\t\ttimeout = null;\n\t\t\tif (!immediate) func.apply(context, args);\n\t\t};\n\t\tvar callNow = immediate && !timeout;\n\t\tclearTimeout(timeout);\n\t\ttimeout = setTimeout(later, wait);\n\t\tif (callNow) func.apply(context, args);\n\t};\n};\n\n/**\n * Showif.js\n */\n(function () {\n\tvar showIfElements = document.querySelectorAll('[data-showif]');\n\n\t// dependent elements\n\tArray.prototype.forEach.call(showIfElements, function (element) {\n\t\tvar config = JSON.parse(element.getAttribute('data-showif'));\n\t\tvar parentElements = document.querySelectorAll('[name=\"' + config.element + '\"]');\n\t\tvar inputs = element.querySelectorAll('input,select,textarea:not([readonly])');\n\t\tvar hide = config.hide === undefined || config.hide;\n\n\t\tfunction toggleElement() {\n\n\t\t\t// do nothing with unchecked radio inputs\n\t\t\tif (this.getAttribute('type') === \"radio\" && !this.checked) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar value = this.getAttribute(\"type\") === \"checkbox\" ? this.checked : this.value;\n\t\t\tvar conditionMet = value == config.value;\n\n\t\t\tif (hide) {\n\t\t\t\telement.style.display = conditionMet ? '' : 'none';\n\t\t\t\telement.style.visibility = conditionMet ? '' : 'hidden';\n\t\t\t} else {\n\t\t\t\telement.style.opacity = conditionMet ? '' : '0.4';\n\t\t\t}\n\n\t\t\t// disable input fields to stop sending their values to server\n\t\t\tArray.prototype.forEach.call(inputs, function (inputElement) {\n\t\t\t\tconditionMet ? inputElement.removeAttribute('readonly') : inputElement.setAttribute('readonly', 'readonly');\n\t\t\t});\n\t\t}\n\n\t\t// find checked element and call toggleElement function\n\t\tArray.prototype.forEach.call(parentElements, function (parentElement) {\n\t\t\ttoggleElement.call(parentElement);\n\t\t});\n\n\t\t// bind on all changes\n\t\thelpers.bindEventToElements(parentElements, 'change', toggleElement);\n\t});\n})();\n\nmodule.exports = helpers;\n\n},{}],3:[function(require,module,exports){\n'use strict';\n\nvar $ = window.jQuery;\nvar config = mc4wp_vars;\nvar i18n = config.i18n;\n\nfunction ListFetcher() {\n this.working = false;\n this.done = false;\n\n // start fetching right away when no lists but api key given\n if (config.mailchimp.api_connected && config.mailchimp.lists.length === 0) {\n this.fetch();\n }\n}\n\nListFetcher.prototype.fetch = function (e) {\n e && e.preventDefault();\n\n this.working = true;\n this.done = false;\n\n $.post(ajaxurl, {\n action: \"mc4wp_renew_mailchimp_lists\",\n timeout: 180000\n }).done(function (data) {\n this.success = true;\n\n if (data) {\n window.setTimeout(function () {\n window.location.reload();\n }, 3000);\n }\n }.bind(this)).fail(function (data) {\n this.success = false;\n }.bind(this)).always(function (data) {\n this.working = false;\n this.done = true;\n\n m.redraw();\n }.bind(this));\n};\n\nListFetcher.prototype.view = function () {\n return m('form', {\n method: \"POST\",\n onsubmit: this.fetch.bind(this)\n }, [m('p', [m('input', {\n type: \"submit\",\n value: this.working ? i18n.fetching_mailchimp_lists : i18n.renew_mailchimp_lists,\n className: \"button\",\n disabled: !!this.working\n }), m.trust(' &nbsp; '), this.working ? [m('span.mc4wp-loader', \"Loading...\"), m.trust(' &nbsp; '), m('em.help', i18n.fetching_mailchimp_lists_can_take_a_while)] : '', this.done ? [this.success ? m('em.help.green', i18n.fetching_mailchimp_lists_done) : m('em.help.red', i18n.fetching_mailchimp_lists_error)] : ''])]);\n};\n\nmodule.exports = ListFetcher;\n\n},{}],4:[function(require,module,exports){\n'use strict';\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nvar Settings = function Settings(context, helpers, events) {\n\t'use strict';\n\n\t// vars\n\n\tvar form = context.querySelector('form');\n\tvar listInputs = context.querySelectorAll('.mc4wp-list-input');\n\tvar lists = mc4wp_vars.mailchimp.lists;\n\tvar selectedLists = [];\n\n\t// functions\n\tfunction getSelectedListsWhere(searchKey, searchValue) {\n\t\treturn selectedLists.filter(function (el) {\n\t\t\treturn el[searchKey] === searchValue;\n\t\t});\n\t}\n\n\tfunction getSelectedLists() {\n\t\treturn selectedLists;\n\t}\n\n\tfunction updateSelectedLists() {\n\t\tselectedLists = [];\n\n\t\tArray.prototype.forEach.call(listInputs, function (input) {\n\t\t\t// skip unchecked checkboxes\n\t\t\tif (typeof input.checked === \"boolean\" && !input.checked) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (_typeof(lists[input.value]) === \"object\") {\n\t\t\t\tselectedLists.push(lists[input.value]);\n\t\t\t}\n\t\t});\n\n\t\tevents.trigger('selectedLists.change', [selectedLists]);\n\t\treturn selectedLists;\n\t}\n\n\tfunction toggleVisibleLists() {\n\t\tvar rows = document.querySelectorAll('.lists--only-selected > *');\n\t\tArray.prototype.forEach.call(rows, function (el) {\n\n\t\t\tvar listId = el.getAttribute('data-list-id');\n\t\t\tvar isSelected = getSelectedListsWhere('id', listId).length > 0;\n\n\t\t\tif (isSelected) {\n\t\t\t\tel.setAttribute('class', el.getAttribute('class').replace('hidden', ''));\n\t\t\t} else {\n\t\t\t\tel.setAttribute('class', el.getAttribute('class') + \" hidden\");\n\t\t\t}\n\t\t});\n\t}\n\n\tevents.on('selectedLists.change', toggleVisibleLists);\n\thelpers.bindEventToElements(listInputs, 'change', updateSelectedLists);\n\n\tupdateSelectedLists();\n\n\treturn {\n\t\tgetSelectedLists: getSelectedLists\n\t};\n};\n\nmodule.exports = Settings;\n\n},{}],5:[function(require,module,exports){\n'use strict';\n\nvar URL = require('./url.js');\n\n// Tabs\nvar Tabs = function Tabs(context) {\n\n\t// TODO: last piece of jQuery... can we get rid of it?\n\tvar $ = window.jQuery;\n\n\tvar $context = $(context);\n\tvar $tabs = $context.find('.tab');\n\tvar $tabNavs = $context.find('.nav-tab');\n\tvar refererField = context.querySelector('input[name=\"_wp_http_referer\"]');\n\tvar tabs = [];\n\n\t$.each($tabs, function (i, t) {\n\t\tvar id = t.id.substring(4);\n\t\tvar title = $(t).find('h2').first().text();\n\n\t\ttabs.push({\n\t\t\tid: id,\n\t\t\ttitle: title,\n\t\t\telement: t,\n\t\t\tnav: context.querySelectorAll('.nav-tab-' + id),\n\t\t\topen: function open() {\n\t\t\t\treturn _open(id);\n\t\t\t}\n\t\t});\n\t});\n\n\tfunction get(id) {\n\n\t\tfor (var i = 0; i < tabs.length; i++) {\n\t\t\tif (tabs[i].id === id) {\n\t\t\t\treturn tabs[i];\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tfunction _open(tab, updateState) {\n\n\t\t// make sure we have a tab object\n\t\tif (typeof tab === \"string\") {\n\t\t\ttab = get(tab);\n\t\t}\n\n\t\tif (!tab) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// should we update state?\n\t\tif (updateState == undefined) {\n\t\t\tupdateState = true;\n\t\t}\n\n\t\t// hide all tabs & remove active class\n\t\t$tabs.removeClass('tab-active').css('display', 'none');\n\t\t$tabNavs.removeClass('nav-tab-active');\n\n\t\t// add `nav-tab-active` to this tab\n\t\tArray.prototype.forEach.call(tab.nav, function (nav) {\n\t\t\tnav.className += \" nav-tab-active\";\n\t\t\tnav.blur();\n\t\t});\n\n\t\t// show target tab\n\t\ttab.element.style.display = 'block';\n\t\ttab.element.className += \" tab-active\";\n\n\t\t// create new URL\n\t\tvar url = URL.setParameter(window.location.href, \"tab\", tab.id);\n\n\t\t// update hash\n\t\tif (history.pushState && updateState) {\n\t\t\thistory.pushState(tab.id, '', url);\n\t\t}\n\n\t\t// update document title\n\t\ttitle(tab);\n\n\t\t// update referer field\n\t\trefererField.value = url;\n\n\t\t// if thickbox is open, close it.\n\t\tif (typeof tb_remove === \"function\") {\n\t\t\ttb_remove();\n\t\t}\n\n\t\t// refresh editor after switching tabs\n\t\t// TODO: decouple this! law of demeter etc.\n\t\tif (tab.id === 'fields' && window.mc4wp && window.mc4wp.forms && window.mc4wp.forms.editor) {\n\t\t\tmc4wp.forms.editor.refresh();\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tfunction title(tab) {\n\t\tvar title = document.title.split('-');\n\t\tdocument.title = document.title.replace(title[0], tab.title + \" \");\n\t}\n\n\tfunction switchTab(e) {\n\t\te = e || window.event;\n\n\t\t// get from data attribute\n\t\tvar tabId = this.getAttribute('data-tab');\n\n\t\t// get from classname\n\t\tif (!tabId) {\n\t\t\tvar match = this.className.match(/nav-tab-(\\w+)?/);\n\t\t\tif (match) {\n\t\t\t\ttabId = match[1];\n\t\t\t}\n\t\t}\n\n\t\t// get from href\n\t\tif (!tabId) {\n\t\t\tvar urlParams = URL.parse(this.href);\n\t\t\tif (!urlParams.tab) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttabId = urlParams.tab;\n\t\t}\n\n\t\tvar opened = _open(tabId);\n\n\t\tif (opened) {\n\t\t\te.preventDefault();\n\t\t\te.returnValue = false;\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tfunction init() {\n\n\t\t// check for current tab\n\t\tif (!history.pushState) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar activeTab = $tabs.filter(':visible').get(0);\n\t\tif (!activeTab) {\n\t\t\treturn;\n\t\t}\n\t\tvar tab = get(activeTab.id.substring(4));\n\t\tif (!tab) return;\n\n\t\t// check if tab is in html5 history\n\t\tif (history.replaceState && history.state === null) {\n\t\t\thistory.replaceState(tab.id, '');\n\t\t}\n\n\t\t// update document title\n\t\ttitle(tab);\n\t}\n\n\t$tabNavs.click(switchTab);\n\t$(document.body).on('click', '.tab-link', switchTab);\n\tinit();\n\n\tif (window.addEventListener && history.pushState) {\n\t\twindow.addEventListener('popstate', function (e) {\n\t\t\tif (!e.state) return true;\n\t\t\tvar tabId = e.state;\n\t\t\treturn _open(tabId, false);\n\t\t});\n\t}\n\n\treturn {\n\t\topen: _open,\n\t\tget: get\n\t};\n};\n\nmodule.exports = Tabs;\n\n},{\"./url.js\":6}],6:[function(require,module,exports){\n'use strict';\n\nvar URL = {\n\tparse: function parse(url) {\n\t\tvar query = {};\n\t\tvar a = url.split('&');\n\t\tfor (var i in a) {\n\t\t\tif (!a.hasOwnProperty(i)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvar b = a[i].split('=');\n\t\t\tquery[decodeURIComponent(b[0])] = decodeURIComponent(b[1]);\n\t\t}\n\n\t\treturn query;\n\t},\n\tbuild: function build(data) {\n\t\tvar ret = [];\n\t\tfor (var d in data) {\n\t\t\tret.push(d + \"=\" + encodeURIComponent(data[d]));\n\t\t}return ret.join(\"&\");\n\t},\n\tsetParameter: function setParameter(url, key, value) {\n\t\tvar data = URL.parse(url);\n\t\tdata[key] = value;\n\t\treturn URL.build(data);\n\t}\n};\n\nmodule.exports = URL;\n\n},{}],7:[function(require,module,exports){\n// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n},{}],8:[function(require,module,exports){\n(function (setImmediate,clearImmediate){\nvar nextTick = require('process/browser.js').nextTick;\nvar apply = Function.prototype.apply;\nvar slice = Array.prototype.slice;\nvar immediateIds = {};\nvar nextImmediateId = 0;\n\n// DOM APIs, for completeness\n\nexports.setTimeout = function() {\n return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);\n};\nexports.setInterval = function() {\n return new Timeout(apply.call(setInterval, window, arguments), clearInterval);\n};\nexports.clearTimeout =\nexports.clearInterval = function(timeout) { timeout.close(); };\n\nfunction Timeout(id, clearFn) {\n this._id = id;\n this._clearFn = clearFn;\n}\nTimeout.prototype.unref = Timeout.prototype.ref = function() {};\nTimeout.prototype.close = function() {\n this._clearFn.call(window, this._id);\n};\n\n// Does not start the time, just sets up the members needed.\nexports.enroll = function(item, msecs) {\n clearTimeout(item._idleTimeoutId);\n item._idleTimeout = msecs;\n};\n\nexports.unenroll = function(item) {\n clearTimeout(item._idleTimeoutId);\n item._idleTimeout = -1;\n};\n\nexports._unrefActive = exports.active = function(item) {\n clearTimeout(item._idleTimeoutId);\n\n var msecs = item._idleTimeout;\n if (msecs >= 0) {\n item._idleTimeoutId = setTimeout(function onTimeout() {\n if (item._onTimeout)\n item._onTimeout();\n }, msecs);\n }\n};\n\n// That's not how node.js implements it but the exposed api is the same.\nexports.setImmediate = typeof setImmediate === \"function\" ? setImmediate : function(fn) {\n var id = nextImmediateId++;\n var args = arguments.length < 2 ? false : slice.call(arguments, 1);\n\n immediateIds[id] = true;\n\n nextTick(function onNextTick() {\n if (immediateIds[id]) {\n // fn.call() is faster so we optimize for the common use-case\n // @see http://jsperf.com/call-apply-segu\n if (args) {\n fn.apply(null, args);\n } else {\n fn.call(null);\n }\n // Prevent ids from leaking\n exports.clearImmediate(id);\n }\n });\n\n return id;\n};\n\nexports.clearImmediate = typeof clearImmediate === \"function\" ? clearImmediate : function(id) {\n delete immediateIds[id];\n};\n}).call(this,require(\"timers\").setImmediate,require(\"timers\").clearImmediate)\n},{\"process/browser.js\":7,\"timers\":8}],9:[function(require,module,exports){\n(function (global,setImmediate){\n;(function() {\n\"use strict\"\nfunction Vnode(tag, key, attrs0, children, text, dom) {\n\treturn {tag: tag, key: key, attrs: attrs0, children: children, text: text, dom: dom, domSize: undefined, state: undefined, _state: undefined, events: undefined, instance: undefined, skip: false}\n}\nVnode.normalize = function(node) {\n\tif (Array.isArray(node)) return Vnode(\"[\", undefined, undefined, Vnode.normalizeChildren(node), undefined, undefined)\n\tif (node != null && typeof node !== \"object\") return Vnode(\"#\", undefined, undefined, node === false ? \"\" : node, undefined, undefined)\n\treturn node\n}\nVnode.normalizeChildren = function normalizeChildren(children) {\n\tfor (var i = 0; i < children.length; i++) {\n\t\tchildren[i] = Vnode.normalize(children[i])\n\t}\n\treturn children\n}\nvar selectorParser = /(?:(^|#|\\.)([^#\\.\\[\\]]+))|(\\[(.+?)(?:\\s*=\\s*(\"|'|)((?:\\\\[\"'\\]]|.)*?)\\5)?\\])/g\nvar selectorCache = {}\nvar hasOwn = {}.hasOwnProperty\nfunction isEmpty(object) {\n\tfor (var key in object) if (hasOwn.call(object, key)) return false\n\treturn true\n}\nfunction compileSelector(selector) {\n\tvar match, tag = \"div\", classes = [], attrs = {}\n\twhile (match = selectorParser.exec(selector)) {\n\t\tvar type = match[1], value = match[2]\n\t\tif (type === \"\" && value !== \"\") tag = value\n\t\telse if (type === \"#\") attrs.id = value\n\t\telse if (type === \".\") classes.push(value)\n\t\telse if (match[3][0] === \"[\") {\n\t\t\tvar attrValue = match[6]\n\t\t\tif (attrValue) attrValue = attrValue.replace(/\\\\([\"'])/g, \"$1\").replace(/\\\\\\\\/g, \"\\\\\")\n\t\t\tif (match[4] === \"class\") classes.push(attrValue)\n\t\t\telse attrs[match[4]] = attrValue === \"\" ? attrValue : attrValue || true\n\t\t}\n\t}\n\tif (classes.length > 0) attrs.className = classes.join(\" \")\n\treturn selectorCache[selector] = {tag: tag, attrs: attrs}\n}\nfunction execSelector(state, attrs, children) {\n\tvar hasAttrs = false, childList, text\n\tvar className = attrs.className || attrs.class\n\tif (!isEmpty(state.attrs) && !isEmpty(attrs)) {\n\t\tvar newAttrs = {}\n\t\tfor(var key in attrs) {\n\t\t\tif (hasOwn.call(attrs, key)) {\n\t\t\t\tnewAttrs[key] = attrs[key]\n\t\t\t}\n\t\t}\n\t\tattrs = newAttrs\n\t}\n\tfor (var key in state.attrs) {\n\t\tif (hasOwn.call(state.attrs, key)) {\n\t\t\tattrs[key] = state.attrs[key]\n\t\t}\n\t}\n\tif (className !== undefined) {\n\t\tif (attrs.class !== undefined) {\n\t\t\tattrs.class = undefined\n\t\t\tattrs.className = className\n\t\t}\n\t\tif (state.attrs.className != null) {\n\t\t\tattrs.className = state.attrs.className + \" \" + className\n\t\t}\n\t}\n\tfor (var key in attrs) {\n\t\tif (hasOwn.call(attrs, key) && key !== \"key\") {\n\t\t\thasAttrs = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif (Array.isArray(children) && children.length === 1 && children[0] != null && children[0].tag === \"#\") {\n\t\ttext = children[0].children\n\t} else {\n\t\tchildList = children\n\t}\n\treturn Vnode(state.tag, attrs.key, hasAttrs ? attrs : undefined, childList, text)\n}\nfunction hyperscript(selector) {\n\t// Because sloppy mode sucks\n\tvar attrs = arguments[1], start = 2, children\n\tif (selector == null || typeof selector !== \"string\" && typeof selector !== \"function\" && typeof selector.view !== \"function\") {\n\t\tthrow Error(\"The selector must be either a string or a component.\");\n\t}\n\tif (typeof selector === \"string\") {\n\t\tvar cached = selectorCache[selector] || compileSelector(selector)\n\t}\n\tif (attrs == null) {\n\t\tattrs = {}\n\t} else if (typeof attrs !== \"object\" || attrs.tag != null || Array.isArray(attrs)) {\n\t\tattrs = {}\n\t\tstart = 1\n\t}\n\tif (arguments.length === start + 1) {\n\t\tchildren = arguments[start]\n\t\tif (!Array.isArray(children)) children = [children]\n\t} else {\n\t\tchildren = []\n\t\twhile (start < arguments.length) children.push(arguments[start++])\n\t}\n\tvar normalized = Vnode.normalizeChildren(children)\n\tif (typeof selector === \"string\") {\n\t\treturn execSelector(cached, attrs, normalized)\n\t} else {\n\t\treturn Vnode(selector, attrs.key, attrs, normalized)\n\t}\n}\nhyperscript.trust = function(html) {\n\tif (html == null) html = \"\"\n\treturn Vnode(\"<\", undefined, undefined, html, undefined, undefined)\n}\nhyperscript.fragment = function(attrs1, children) {\n\treturn Vnode(\"[\", attrs1.key, attrs1, Vnode.normalizeChildren(children), undefined, undefined)\n}\nvar m = hyperscript\n/** @constructor */\nvar PromisePolyfill = function(executor) {\n\tif (!(this instanceof PromisePolyfill)) throw new Error(\"Promise must be called with `new`\")\n\tif (typeof executor !== \"function\") throw new TypeError(\"executor must be a function\")\n\tvar self = this, resolvers = [], rejectors = [], resolveCurrent = handler(resolvers, true), rejectCurrent = handler(rejectors, false)\n\tvar instance = self._instance = {resolvers: resolvers, rejectors: rejectors}\n\tvar callAsync = typeof setImmediate === \"function\" ? setImmediate : setTimeout\n\tfunction handler(list, shouldAbsorb) {\n\t\treturn function execute(value) {\n\t\t\tvar then\n\t\t\ttry {\n\t\t\t\tif (shouldAbsorb && value != null && (typeof value === \"object\" || typeof value === \"function\") && typeof (then = value.then) === \"function\") {\n\t\t\t\t\tif (value === self) throw new TypeError(\"Promise can't be resolved w/ itself\")\n\t\t\t\t\texecuteOnce(then.bind(value))\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tcallAsync(function() {\n\t\t\t\t\t\tif (!shouldAbsorb && list.length === 0) console.error(\"Possible unhandled promise rejection:\", value)\n\t\t\t\t\t\tfor (var i = 0; i < list.length; i++) list[i](value)\n\t\t\t\t\t\tresolvers.length = 0, rejectors.length = 0\n\t\t\t\t\t\tinstance.state = shouldAbsorb\n\t\t\t\t\t\tinstance.retry = function() {execute(value)}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\trejectCurrent(e)\n\t\t\t}\n\t\t}\n\t}\n\tfunction executeOnce(then) {\n\t\tvar runs = 0\n\t\tfunction run(fn) {\n\t\t\treturn function(value) {\n\t\t\t\tif (runs++ > 0) return\n\t\t\t\tfn(value)\n\t\t\t}\n\t\t}\n\t\tvar onerror = run(rejectCurrent)\n\t\ttry {then(run(resolveCurrent), onerror)} catch (e) {onerror(e)}\n\t}\n\texecuteOnce(executor)\n}\nPromisePolyfill.prototype.then = function(onFulfilled, onRejection) {\n\tvar self = this, instance = self._instance\n\tfunction handle(callback, list, next, state) {\n\t\tlist.push(function(value) {\n\t\t\tif (typeof callback !== \"function\") next(value)\n\t\t\telse try {resolveNext(callback(value))} catch (e) {if (rejectNext) rejectNext(e)}\n\t\t})\n\t\tif (typeof instance.retry === \"function\" && state === instance.state) instance.retry()\n\t}\n\tvar resolveNext, rejectNext\n\tvar promise = new PromisePolyfill(function(resolve, reject) {resolveNext = resolve, rejectNext = reject})\n\thandle(onFulfilled, instance.resolvers, resolveNext, true), handle(onRejection, instance.rejectors, rejectNext, false)\n\treturn promise\n}\nPromisePolyfill.prototype.catch = function(onRejection) {\n\treturn this.then(null, onRejection)\n}\nPromisePolyfill.resolve = function(value) {\n\tif (value instanceof PromisePolyfill) return value\n\treturn new PromisePolyfill(function(resolve) {resolve(value)})\n}\nPromisePolyfill.reject = function(value) {\n\treturn new PromisePolyfill(function(resolve, reject) {reject(value)})\n}\nPromisePolyfill.all = function(list) {\n\treturn new PromisePolyfill(function(resolve, reject) {\n\t\tvar total = list.length, count = 0, values = []\n\t\tif (list.length === 0) resolve([])\n\t\telse for (var i = 0; i < list.length; i++) {\n\t\t\t(function(i) {\n\t\t\t\tfunction consume(value) {\n\t\t\t\t\tcount++\n\t\t\t\t\tvalues[i] = value\n\t\t\t\t\tif (count === total) resolve(values)\n\t\t\t\t}\n\t\t\t\tif (list[i] != null && (typeof list[i] === \"object\" || typeof list[i] === \"function\") && typeof list[i].then === \"function\") {\n\t\t\t\t\tlist[i].then(consume, reject)\n\t\t\t\t}\n\t\t\t\telse consume(list[i])\n\t\t\t})(i)\n\t\t}\n\t})\n}\nPromisePolyfill.race = function(list) {\n\treturn new PromisePolyfill(function(resolve, reject) {\n\t\tfor (var i = 0; i < list.length; i++) {\n\t\t\tlist[i].then(resolve, reject)\n\t\t}\n\t})\n}\nif (typeof window !== \"undefined\") {\n\tif (typeof window.Promise === \"undefined\") window.Promise = PromisePolyfill\n\tvar PromisePolyfill = window.Promise\n} else if (typeof global !== \"undefined\") {\n\tif (typeof global.Promise === \"undefined\") global.Promise = PromisePolyfill\n\tvar PromisePolyfill = global.Promise\n} else {\n}\nvar buildQueryString = function(object) {\n\tif (Object.prototype.toString.call(object) !== \"[object Object]\") return \"\"\n\tvar args = []\n\tfor (var key0 in object) {\n\t\tdestructure(key0, object[key0])\n\t}\n\treturn args.join(\"&\")\n\tfunction destructure(key0, value) {\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (var i = 0; i < value.length; i++) {\n\t\t\t\tdestructure(key0 + \"[\" + i + \"]\", value[i])\n\t\t\t}\n\t\t}\n\t\telse if (Object.prototype.toString.call(value) === \"[object Object]\") {\n\t\t\tfor (var i in value) {\n\t\t\t\tdestructure(key0 + \"[\" + i + \"]\", value[i])\n\t\t\t}\n\t\t}\n\t\telse args.push(encodeURIComponent(key0) + (value != null && value !== \"\" ? \"=\" + encodeURIComponent(value) : \"\"))\n\t}\n}\nvar FILE_PROTOCOL_REGEX = new RegExp(\"^file://\", \"i\")\nvar _8 = function($window, Promise) {\n\tvar callbackCount = 0\n\tvar oncompletion\n\tfunction setCompletionCallback(callback) {oncompletion = callback}\n\tfunction finalizer() {\n\t\tvar count = 0\n\t\tfunction complete() {if (--count === 0 && typeof oncompletion === \"function\") oncompletion()}\n\t\treturn function finalize(promise0) {\n\t\t\tvar then0 = promise0.then\n\t\t\tpromise0.then = function() {\n\t\t\t\tcount++\n\t\t\t\tvar next = then0.apply(promise0, arguments)\n\t\t\t\tnext.then(complete, function(e) {\n\t\t\t\t\tcomplete()\n\t\t\t\t\tif (count === 0) throw e\n\t\t\t\t})\n\t\t\t\treturn finalize(next)\n\t\t\t}\n\t\t\treturn promise0\n\t\t}\n\t}\n\tfunction normalize(args, extra) {\n\t\tif (typeof args === \"string\") {\n\t\t\tvar url = args\n\t\t\targs = extra || {}\n\t\t\tif (args.url == null) args.url = url\n\t\t}\n\t\treturn args\n\t}\n\tfunction request(args, extra) {\n\t\tvar finalize = finalizer()\n\t\targs = normalize(args, extra)\n\t\tvar promise0 = new Promise(function(resolve, reject) {\n\t\t\tif (args.method == null) args.method = \"GET\"\n\t\t\targs.method = args.method.toUpperCase()\n\t\t\tvar useBody = (args.method === \"GET\" || args.method === \"TRACE\") ? false : (typeof args.useBody === \"boolean\" ? args.useBody : true)\n\t\t\tif (typeof args.serialize !== \"function\") args.serialize = typeof FormData !== \"undefined\" && args.data instanceof FormData ? function(value) {return value} : JSON.stringify\n\t\t\tif (typeof args.deserialize !== \"function\") args.deserialize = deserialize\n\t\t\tif (typeof args.extract !== \"function\") args.extract = extract\n\t\t\targs.url = interpolate(args.url, args.data)\n\t\t\tif (useBody) args.data = args.serialize(args.data)\n\t\t\telse args.url = assemble(args.url, args.data)\n\t\t\tvar xhr = new $window.XMLHttpRequest(),\n\t\t\t\taborted = false,\n\t\t\t\t_abort = xhr.abort\n\t\t\txhr.abort = function abort() {\n\t\t\t\taborted = true\n\t\t\t\t_abort.call(xhr)\n\t\t\t}\n\t\t\txhr.open(args.method, args.url, typeof args.async === \"boolean\" ? args.async : true, typeof args.user === \"string\" ? args.user : undefined, typeof args.password === \"string\" ? args.password : undefined)\n\t\t\tif (args.serialize === JSON.stringify && useBody && !(args.headers && args.headers.hasOwnProperty(\"Content-Type\"))) {\n\t\t\t\txhr.setRequestHeader(\"Content-Type\", \"application/json; charset=utf-8\")\n\t\t\t}\n\t\t\tif (args.deserialize === deserialize && !(args.headers && args.headers.hasOwnProperty(\"Accept\"))) {\n\t\t\t\txhr.setRequestHeader(\"Accept\", \"application/json, text/*\")\n\t\t\t}\n\t\t\tif (args.withCredentials) xhr.withCredentials = args.withCredentials\n\t\t\tfor (var key in args.headers) if ({}.hasOwnProperty.call(args.headers, key)) {\n\t\t\t\txhr.setRequestHeader(key, args.headers[key])\n\t\t\t}\n\t\t\tif (typeof args.config === \"function\") xhr = args.config(xhr, args) || xhr\n\t\t\txhr.onreadystatechange = function() {\n\t\t\t\t// Don't throw errors on xhr.abort().\n\t\t\t\tif(aborted) return\n\t\t\t\tif (xhr.readyState === 4) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tvar response = (args.extract !== extract) ? args.extract(xhr, args) : args.deserialize(args.extract(xhr, args))\n\t\t\t\t\t\tif ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || FILE_PROTOCOL_REGEX.test(args.url)) {\n\t\t\t\t\t\t\tresolve(cast(args.type, response))\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tvar error = new Error(xhr.responseText)\n\t\t\t\t\t\t\tfor (var key in response) error[key] = response[key]\n\t\t\t\t\t\t\treject(error)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcatch (e) {\n\t\t\t\t\t\treject(e)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (useBody && (args.data != null)) xhr.send(args.data)\n\t\t\telse xhr.send()\n\t\t})\n\t\treturn args.background === true ? promise0 : finalize(promise0)\n\t}\n\tfunction jsonp(args, extra) {\n\t\tvar finalize = finalizer()\n\t\targs = normalize(args, extra)\n\t\tvar promise0 = new Promise(function(resolve, reject) {\n\t\t\tvar callbackName = args.callbackName || \"_mithril_\" + Math.round(Math.random() * 1e16) + \"_\" + callbackCount++\n\t\t\tvar script = $window.document.createElement(\"script\")\n\t\t\t$window[callbackName] = function(data) {\n\t\t\t\tscript.parentNode.removeChild(script)\n\t\t\t\tresolve(cast(args.type, data))\n\t\t\t\tdelete $window[callbackName]\n\t\t\t}\n\t\t\tscript.onerror = function() {\n\t\t\t\tscript.parentNode.removeChild(script)\n\t\t\t\treject(new Error(\"JSONP request failed\"))\n\t\t\t\tdelete $window[callbackName]\n\t\t\t}\n\t\t\tif (args.data == null) args.data = {}\n\t\t\targs.url = interpolate(args.url, args.data)\n\t\t\targs.data[args.callbackKey || \"callback\"] = callbackName\n\t\t\tscript.src = assemble(args.url, args.data)\n\t\t\t$window.document.documentElement.appendChild(script)\n\t\t})\n\t\treturn args.background === true? promise0 : finalize(promise0)\n\t}\n\tfunction interpolate(url, data) {\n\t\tif (data == null) return url\n\t\tvar tokens = url.match(/:[^\\/]+/gi) || []\n\t\tfor (var i = 0; i < tokens.length; i++) {\n\t\t\tvar key = tokens[i].slice(1)\n\t\t\tif (data[key] != null) {\n\t\t\t\turl = url.replace(tokens[i], data[key])\n\t\t\t}\n\t\t}\n\t\treturn url\n\t}\n\tfunction assemble(url, data) {\n\t\tvar querystring = buildQueryString(data)\n\t\tif (querystring !== \"\") {\n\t\t\tvar prefix = url.indexOf(\"?\") < 0 ? \"?\" : \"&\"\n\t\t\turl += prefix + querystring\n\t\t}\n\t\treturn url\n\t}\n\tfunction deserialize(data) {\n\t\ttry {return data !== \"\" ? JSON.parse(data) : null}\n\t\tcatch (e) {throw new Error(data)}\n\t}\n\tfunction extract(xhr) {return xhr.responseText}\n\tfunction cast(type0, data) {\n\t\tif (typeof type0 === \"function\") {\n\t\t\tif (Array.isArray(data)) {\n\t\t\t\tfor (var i = 0; i < data.length; i++) {\n\t\t\t\t\tdata[i] = new type0(data[i])\n\t\t\t\t}\n\t\t\t}\n\t\t\telse return new type0(data)\n\t\t}\n\t\treturn data\n\t}\n\treturn {request: request, jsonp: jsonp, setCompletionCallback: setCompletionCallback}\n}\nvar requestService = _8(window, PromisePolyfill)\nvar coreRenderer = function($window) {\n\tvar $doc = $window.document\n\tvar $emptyFragment = $doc.createDocumentFragment()\n\tvar nameSpace = {\n\t\tsvg: \"http://www.w3.org/2000/svg\",\n\t\tmath: \"http://www.w3.org/1998/Math/MathML\"\n\t}\n\tvar onevent\n\tfunction setEventCallback(callback) {return onevent = callback}\n\tfunction getNameSpace(vnode) {\n\t\treturn vnode.attrs && vnode.attrs.xmlns || nameSpace[vnode.tag]\n\t}\n\t//create\n\tfunction createNodes(parent, vnodes, start, end, hooks, nextSibling, ns) {\n\t\tfor (var i = start; i < end; i++) {\n\t\t\tvar vnode = vnodes[i]\n\t\t\tif (vnode != null) {\n\t\t\t\tcreateNode(parent, vnode, hooks, ns, nextSibling)\n\t\t\t}\n\t\t}\n\t}\n\tfunction createNode(parent, vnode, hooks, ns, nextSibling) {\n\t\tvar tag = vnode.tag\n\t\tif (typeof tag === \"string\") {\n\t\t\tvnode.state = {}\n\t\t\tif (vnode.attrs != null) initLifecycle(vnode.attrs, vnode, hooks)\n\t\t\tswitch (tag) {\n\t\t\t\tcase \"#\": return createText(parent, vnode, nextSibling)\n\t\t\t\tcase \"<\": return createHTML(parent, vnode, nextSibling)\n\t\t\t\tcase \"[\": return createFragment(parent, vnode, hooks, ns, nextSibling)\n\t\t\t\tdefault: return createElement(parent, vnode, hooks, ns, nextSibling)\n\t\t\t}\n\t\t}\n\t\telse return createComponent(parent, vnode, hooks, ns, nextSibling)\n\t}\n\tfunction createText(parent, vnode, nextSibling) {\n\t\tvnode.dom = $doc.createTextNode(vnode.children)\n\t\tinsertNode(parent, vnode.dom, nextSibling)\n\t\treturn vnode.dom\n\t}\n\tfunction createHTML(parent, vnode, nextSibling) {\n\t\tvar match1 = vnode.children.match(/^\\s*?<(\\w+)/im) || []\n\t\tvar parent1 = {caption: \"table\", thead: \"table\", tbody: \"table\", tfoot: \"table\", tr: \"tbody\", th: \"tr\", td: \"tr\", colgroup: \"table\", col: \"colgroup\"}[match1[1]] || \"div\"\n\t\tvar temp = $doc.createElement(parent1)\n\t\ttemp.innerHTML = vnode.children\n\t\tvnode.dom = temp.firstChild\n\t\tvnode.domSize = temp.childNodes.length\n\t\tvar fragment = $doc.createDocumentFragment()\n\t\tvar child\n\t\twhile (child = temp.firstChild) {\n\t\t\tfragment.appendChild(child)\n\t\t}\n\t\tinsertNode(parent, fragment, nextSibling)\n\t\treturn fragment\n\t}\n\tfunction createFragment(parent, vnode, hooks, ns, nextSibling) {\n\t\tvar fragment = $doc.createDocumentFragment()\n\t\tif (vnode.children != null) {\n\t\t\tvar children = vnode.children\n\t\t\tcreateNodes(fragment, children, 0, children.length, hooks, null, ns)\n\t\t}\n\t\tvnode.dom = fragment.firstChild\n\t\tvnode.domSize = fragment.childNodes.length\n\t\tinsertNode(parent, fragment, nextSibling)\n\t\treturn fragment\n\t}\n\tfunction createElement(parent, vnode, hooks, ns, nextSibling) {\n\t\tvar tag = vnode.tag\n\t\tvar attrs2 = vnode.attrs\n\t\tvar is = attrs2 && attrs2.is\n\t\tns = getNameSpace(vnode) || ns\n\t\tvar element = ns ?\n\t\t\tis ? $doc.createElementNS(ns, tag, {is: is}) : $doc.createElementNS(ns, tag) :\n\t\t\tis ? $doc.createElement(tag, {is: is}) : $doc.createElement(tag)\n\t\tvnode.dom = element\n\t\tif (attrs2 != null) {\n\t\t\tsetAttrs(vnode, attrs2, ns)\n\t\t}\n\t\tinsertNode(parent, element, nextSibling)\n\t\tif (vnode.attrs != null && vnode.attrs.contenteditable != null) {\n\t\t\tsetContentEditable(vnode)\n\t\t}\n\t\telse {\n\t\t\tif (vnode.text != null) {\n\t\t\t\tif (vnode.text !== \"\") element.textContent = vnode.text\n\t\t\t\telse vnode.children = [Vnode(\"#\", undefined, undefined, vnode.text, undefined, undefined)]\n\t\t\t}\n\t\t\tif (vnode.children != null) {\n\t\t\t\tvar children = vnode.children\n\t\t\t\tcreateNodes(element, children, 0, children.length, hooks, null, ns)\n\t\t\t\tsetLateAttrs(vnode)\n\t\t\t}\n\t\t}\n\t\treturn element\n\t}\n\tfunction initComponent(vnode, hooks) {\n\t\tvar sentinel\n\t\tif (typeof vnode.tag.view === \"function\") {\n\t\t\tvnode.state = Object.create(vnode.tag)\n\t\t\tsentinel = vnode.state.view\n\t\t\tif (sentinel.$$reentrantLock$$ != null) return $emptyFragment\n\t\t\tsentinel.$$reentrantLock$$ = true\n\t\t} else {\n\t\t\tvnode.state = void 0\n\t\t\tsentinel = vnode.tag\n\t\t\tif (sentinel.$$reentrantLock$$ != null) return $emptyFragment\n\t\t\tsentinel.$$reentrantLock$$ = true\n\t\t\tvnode.state = (vnode.tag.prototype != null && typeof vnode.tag.prototype.view === \"function\") ? new vnode.tag(vnode) : vnode.tag(vnode)\n\t\t}\n\t\tvnode._state = vnode.state\n\t\tif (vnode.attrs != null) initLifecycle(vnode.attrs, vnode, hooks)\n\t\tinitLifecycle(vnode._state, vnode, hooks)\n\t\tvnode.instance = Vnode.normalize(vnode._state.view.call(vnode.state, vnode))\n\t\tif (vnode.instance === vnode) throw Error(\"A view cannot return the vnode it received as argument\")\n\t\tsentinel.$$reentrantLock$$ = null\n\t}\n\tfunction createComponent(parent, vnode, hooks, ns, nextSibling) {\n\t\tinitComponent(vnode, hooks)\n\t\tif (vnode.instance != null) {\n\t\t\tvar element = createNode(parent, vnode.instance, hooks, ns, nextSibling)\n\t\t\tvnode.dom = vnode.instance.dom\n\t\t\tvnode.domSize = vnode.dom != null ? vnode.instance.domSize : 0\n\t\t\tinsertNode(parent, element, nextSibling)\n\t\t\treturn element\n\t\t}\n\t\telse {\n\t\t\tvnode.domSize = 0\n\t\t\treturn $emptyFragment\n\t\t}\n\t}\n\t//update\n\tfunction updateNodes(parent, old, vnodes, recycling, hooks, nextSibling, ns) {\n\t\tif (old === vnodes || old == null && vnodes == null) return\n\t\telse if (old == null) createNodes(parent, vnodes, 0, vnodes.length, hooks, nextSibling, ns)\n\t\telse if (vnodes == null) removeNodes(old, 0, old.length, vnodes)\n\t\telse {\n\t\t\tif (old.length === vnodes.length) {\n\t\t\t\tvar isUnkeyed = false\n\t\t\t\tfor (var i = 0; i < vnodes.length; i++) {\n\t\t\t\t\tif (vnodes[i] != null && old[i] != null) {\n\t\t\t\t\t\tisUnkeyed = vnodes[i].key == null && old[i].key == null\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (isUnkeyed) {\n\t\t\t\t\tfor (var i = 0; i < old.length; i++) {\n\t\t\t\t\t\tif (old[i] === vnodes[i]) continue\n\t\t\t\t\t\telse if (old[i] == null && vnodes[i] != null) createNode(parent, vnodes[i], hooks, ns, getNextSibling(old, i + 1, nextSibling))\n\t\t\t\t\t\telse if (vnodes[i] == null) removeNodes(old, i, i + 1, vnodes)\n\t\t\t\t\t\telse updateNode(parent, old[i], vnodes[i], hooks, getNextSibling(old, i + 1, nextSibling), recycling, ns)\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\trecycling = recycling || isRecyclable(old, vnodes)\n\t\t\tif (recycling) {\n\t\t\t\tvar pool = old.pool\n\t\t\t\told = old.concat(old.pool)\n\t\t\t}\n\t\t\tvar oldStart = 0, start = 0, oldEnd = old.length - 1, end = vnodes.length - 1, map\n\t\t\twhile (oldEnd >= oldStart && end >= start) {\n\t\t\t\tvar o = old[oldStart], v = vnodes[start]\n\t\t\t\tif (o === v && !recycling) oldStart++, start++\n\t\t\t\telse if (o == null) oldStart++\n\t\t\t\telse if (v == null) start++\n\t\t\t\telse if (o.key === v.key) {\n\t\t\t\t\tvar shouldRecycle = (pool != null && oldStart >= old.length - pool.length) || ((pool == null) && recycling)\n\t\t\t\t\toldStart++, start++\n\t\t\t\t\tupdateNode(parent, o, v, hooks, getNextSibling(old, oldStart, nextSibling), shouldRecycle, ns)\n\t\t\t\t\tif (recycling && o.tag === v.tag) insertNode(parent, toFragment(o), nextSibling)\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tvar o = old[oldEnd]\n\t\t\t\t\tif (o === v && !recycling) oldEnd--, start++\n\t\t\t\t\telse if (o == null) oldEnd--\n\t\t\t\t\telse if (v == null) start++\n\t\t\t\t\telse if (o.key === v.key) {\n\t\t\t\t\t\tvar shouldRecycle = (pool != null && oldEnd >= old.length - pool.length) || ((pool == null) && recycling)\n\t\t\t\t\t\tupdateNode(parent, o, v, hooks, getNextSibling(old, oldEnd + 1, nextSibling), shouldRecycle, ns)\n\t\t\t\t\t\tif (recycling || start < end) insertNode(parent, toFragment(o), getNextSibling(old, oldStart, nextSibling))\n\t\t\t\t\t\toldEnd--, start++\n\t\t\t\t\t}\n\t\t\t\t\telse break\n\t\t\t\t}\n\t\t\t}\n\t\t\twhile (oldEnd >= oldStart && end >= start) {\n\t\t\t\tvar o = old[oldEnd], v = vnodes[end]\n\t\t\t\tif (o === v && !recycling) oldEnd--, end--\n\t\t\t\telse if (o == null) oldEnd--\n\t\t\t\telse if (v == null) end--\n\t\t\t\telse if (o.key === v.key) {\n\t\t\t\t\tvar shouldRecycle = (pool != null && oldEnd >= old.length - pool.length) || ((pool == null) && recycling)\n\t\t\t\t\tupdateNode(parent, o, v, hooks, getNextSibling(old, oldEnd + 1, nextSibling), shouldRecycle, ns)\n\t\t\t\t\tif (recycling && o.tag === v.tag) insertNode(parent, toFragment(o), nextSibling)\n\t\t\t\t\tif (o.dom != null) nextSibling = o.dom\n\t\t\t\t\toldEnd--, end--\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tif (!map) map = getKeyMap(old, oldEnd)\n\t\t\t\t\tif (v != null) {\n\t\t\t\t\t\tvar oldIndex = map[v.key]\n\t\t\t\t\t\tif (oldIndex != null) {\n\t\t\t\t\t\t\tvar movable = old[oldIndex]\n\t\t\t\t\t\t\tvar shouldRecycle = (pool != null && oldIndex >= old.length - pool.length) || ((pool == null) && recycling)\n\t\t\t\t\t\t\tupdateNode(parent, movable, v, hooks, getNextSibling(old, oldEnd + 1, nextSibling), recycling, ns)\n\t\t\t\t\t\t\tinsertNode(parent, toFragment(movable), nextSibling)\n\t\t\t\t\t\t\told[oldIndex].skip = true\n\t\t\t\t\t\t\tif (movable.dom != null) nextSibling = movable.dom\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tvar dom = createNode(parent, v, hooks, ns, nextSibling)\n\t\t\t\t\t\t\tnextSibling = dom\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tend--\n\t\t\t\t}\n\t\t\t\tif (end < start) break\n\t\t\t}\n\t\t\tcreateNodes(parent, vnodes, start, end + 1, hooks, nextSibling, ns)\n\t\t\tremoveNodes(old, oldStart, oldEnd + 1, vnodes)\n\t\t}\n\t}\n\tfunction updateNode(parent, old, vnode, hooks, nextSibling, recycling, ns) {\n\t\tvar oldTag = old.tag, tag = vnode.tag\n\t\tif (oldTag === tag) {\n\t\t\tvnode.state = old.state\n\t\t\tvnode._state = old._state\n\t\t\tvnode.events = old.events\n\t\t\tif (!recycling && shouldNotUpdate(vnode, old)) return\n\t\t\tif (typeof oldTag === \"string\") {\n\t\t\t\tif (vnode.attrs != null) {\n\t\t\t\t\tif (recycling) {\n\t\t\t\t\t\tvnode.state = {}\n\t\t\t\t\t\tinitLifecycle(vnode.attrs, vnode, hooks)\n\t\t\t\t\t}\n\t\t\t\t\telse updateLifecycle(vnode.attrs, vnode, hooks)\n\t\t\t\t}\n\t\t\t\tswitch (oldTag) {\n\t\t\t\t\tcase \"#\": updateText(old, vnode); break\n\t\t\t\t\tcase \"<\": updateHTML(parent, old, vnode, nextSibling); break\n\t\t\t\t\tcase \"[\": updateFragment(parent, old, vnode, recycling, hooks, nextSibling, ns); break\n\t\t\t\t\tdefault: updateElement(old, vnode, recycling, hooks, ns)\n\t\t\t\t}\n\t\t\t}\n\t\t\telse updateComponent(parent, old, vnode, hooks, nextSibling, recycling, ns)\n\t\t}\n\t\telse {\n\t\t\tremoveNode(old, null)\n\t\t\tcreateNode(parent, vnode, hooks, ns, nextSibling)\n\t\t}\n\t}\n\tfunction updateText(old, vnode) {\n\t\tif (old.children.toString() !== vnode.children.toString()) {\n\t\t\told.dom.nodeValue = vnode.children\n\t\t}\n\t\tvnode.dom = old.dom\n\t}\n\tfunction updateHTML(parent, old, vnode, nextSibling) {\n\t\tif (old.children !== vnode.children) {\n\t\t\ttoFragment(old)\n\t\t\tcreateHTML(parent, vnode, nextSibling)\n\t\t}\n\t\telse vnode.dom = old.dom, vnode.domSize = old.domSize\n\t}\n\tfunction updateFragment(parent, old, vnode, recycling, hooks, nextSibling, ns) {\n\t\tupdateNodes(parent, old.children, vnode.children, recycling, hooks, nextSibling, ns)\n\t\tvar domSize = 0, children = vnode.children\n\t\tvnode.dom = null\n\t\tif (children != null) {\n\t\t\tfor (var i = 0; i < children.length; i++) {\n\t\t\t\tvar child = children[i]\n\t\t\t\tif (child != null && child.dom != null) {\n\t\t\t\t\tif (vnode.dom == null) vnode.dom = child.dom\n\t\t\t\t\tdomSize += child.domSize || 1\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (domSize !== 1) vnode.domSize = domSize\n\t\t}\n\t}\n\tfunction updateElement(old, vnode, recycling, hooks, ns) {\n\t\tvar element = vnode.dom = old.dom\n\t\tns = getNameSpace(vnode) || ns\n\t\tif (vnode.tag === \"textarea\") {\n\t\t\tif (vnode.attrs == null) vnode.attrs = {}\n\t\t\tif (vnode.text != null) {\n\t\t\t\tvnode.attrs.value = vnode.text //FIXME handle0 multiple children\n\t\t\t\tvnode.text = undefined\n\t\t\t}\n\t\t}\n\t\tupdateAttrs(vnode, old.attrs, vnode.attrs, ns)\n\t\tif (vnode.attrs != null && vnode.attrs.contenteditable != null) {\n\t\t\tsetContentEditable(vnode)\n\t\t}\n\t\telse if (old.text != null && vnode.text != null && vnode.text !== \"\") {\n\t\t\tif (old.text.toString() !== vnode.text.toString()) old.dom.firstChild.nodeValue = vnode.text\n\t\t}\n\t\telse {\n\t\t\tif (old.text != null) old.children = [Vnode(\"#\", undefined, undefined, old.text, undefined, old.dom.firstChild)]\n\t\t\tif (vnode.text != null) vnode.children = [Vnode(\"#\", undefined, undefined, vnode.text, undefined, undefined)]\n\t\t\tupdateNodes(element, old.children, vnode.children, recycling, hooks, null, ns)\n\t\t}\n\t}\n\tfunction updateComponent(parent, old, vnode, hooks, nextSibling, recycling, ns) {\n\t\tif (recycling) {\n\t\t\tinitComponent(vnode, hooks)\n\t\t} else {\n\t\t\tvnode.instance = Vnode.normalize(vnode._state.view.call(vnode.state, vnode))\n\t\t\tif (vnode.instance === vnode) throw Error(\"A view cannot return the vnode it received as argument\")\n\t\t\tif (vnode.attrs != null) updateLifecycle(vnode.attrs, vnode, hooks)\n\t\t\tupdateLifecycle(vnode._state, vnode, hooks)\n\t\t}\n\t\tif (vnode.instance != null) {\n\t\t\tif (old.instance == null) createNode(parent, vnode.instance, hooks, ns, nextSibling)\n\t\t\telse updateNode(parent, old.instance, vnode.instance, hooks, nextSibling, recycling, ns)\n\t\t\tvnode.dom = vnode.instance.dom\n\t\t\tvnode.domSize = vnode.instance.domSize\n\t\t}\n\t\telse if (old.instance != null) {\n\t\t\tremoveNode(old.instance, null)\n\t\t\tvnode.dom = undefined\n\t\t\tvnode.domSize = 0\n\t\t}\n\t\telse {\n\t\t\tvnode.dom = old.dom\n\t\t\tvnode.domSize = old.domSize\n\t\t}\n\t}\n\tfunction isRecyclable(old, vnodes) {\n\t\tif (old.pool != null && Math.abs(old.pool.length - vnodes.length) <= Math.abs(old.length - vnodes.length)) {\n\t\t\tvar oldChildrenLength = old[0] && old[0].children && old[0].children.length || 0\n\t\t\tvar poolChildrenLength = old.pool[0] && old.pool[0].children && old.pool[0].children.length || 0\n\t\t\tvar vnodesChildrenLength = vnodes[0] && vnodes[0].children && vnodes[0].children.length || 0\n\t\t\tif (Math.abs(poolChildrenLength - vnodesChildrenLength) <= Math.abs(oldChildrenLength - vnodesChildrenLength)) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n\tfunction getKeyMap(vnodes, end) {\n\t\tvar map = {}, i = 0\n\t\tfor (var i = 0; i < end; i++) {\n\t\t\tvar vnode = vnodes[i]\n\t\t\tif (vnode != null) {\n\t\t\t\tvar key2 = vnode.key\n\t\t\t\tif (key2 != null) map[key2] = i\n\t\t\t}\n\t\t}\n\t\treturn map\n\t}\n\tfunction toFragment(vnode) {\n\t\tvar count0 = vnode.domSize\n\t\tif (count0 != null || vnode.dom == null) {\n\t\t\tvar fragment = $doc.createDocumentFragment()\n\t\t\tif (count0 > 0) {\n\t\t\t\tvar dom = vnode.dom\n\t\t\t\twhile (--count0) fragment.appendChild(dom.nextSibling)\n\t\t\t\tfragment.insertBefore(dom, fragment.firstChild)\n\t\t\t}\n\t\t\treturn fragment\n\t\t}\n\t\telse return vnode.dom\n\t}\n\tfunction getNextSibling(vnodes, i, nextSibling) {\n\t\tfor (; i < vnodes.length; i++) {\n\t\t\tif (vnodes[i] != null && vnodes[i].dom != null) return vnodes[i].dom\n\t\t}\n\t\treturn nextSibling\n\t}\n\tfunction insertNode(parent, dom, nextSibling) {\n\t\tif (nextSibling && nextSibling.parentNode) parent.insertBefore(dom, nextSibling)\n\t\telse parent.appendChild(dom)\n\t}\n\tfunction setContentEditable(vnode) {\n\t\tvar children = vnode.children\n\t\tif (children != null && children.length === 1 && children[0].tag === \"<\") {\n\t\t\tvar content = children[0].children\n\t\t\tif (vnode.dom.innerHTML !== content) vnode.dom.innerHTML = content\n\t\t}\n\t\telse if (vnode.text != null || children != null && children.length !== 0) throw new Error(\"Child node of a contenteditable must be trusted\")\n\t}\n\t//remove\n\tfunction removeNodes(vnodes, start, end, context) {\n\t\tfor (var i = start; i < end; i++) {\n\t\t\tvar vnode = vnodes[i]\n\t\t\tif (vnode != null) {\n\t\t\t\tif (vnode.skip) vnode.skip = false\n\t\t\t\telse removeNode(vnode, context)\n\t\t\t}\n\t\t}\n\t}\n\tfunction removeNode(vnode, context) {\n\t\tvar expected = 1, called = 0\n\t\tif (vnode.attrs && typeof vnode.attrs.onbeforeremove === \"function\") {\n\t\t\tvar result = vnode.attrs.onbeforeremove.call(vnode.state, vnode)\n\t\t\tif (result != null && typeof result.then === \"function\") {\n\t\t\t\texpected++\n\t\t\t\tresult.then(continuation, continuation)\n\t\t\t}\n\t\t}\n\t\tif (typeof vnode.tag !== \"string\" && typeof vnode._state.onbeforeremove === \"function\") {\n\t\t\tvar result = vnode._state.onbeforeremove.call(vnode.state, vnode)\n\t\t\tif (result != null && typeof result.then === \"function\") {\n\t\t\t\texpected++\n\t\t\t\tresult.then(continuation, continuation)\n\t\t\t}\n\t\t}\n\t\tcontinuation()\n\t\tfunction continuation() {\n\t\t\tif (++called === expected) {\n\t\t\t\tonremove(vnode)\n\t\t\t\tif (vnode.dom) {\n\t\t\t\t\tvar count0 = vnode.domSize || 1\n\t\t\t\t\tif (count0 > 1) {\n\t\t\t\t\t\tvar dom = vnode.dom\n\t\t\t\t\t\twhile (--count0) {\n\t\t\t\t\t\t\tremoveNodeFromDOM(dom.nextSibling)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tremoveNodeFromDOM(vnode.dom)\n\t\t\t\t\tif (context != null && vnode.domSize == null && !hasIntegrationMethods(vnode.attrs) && typeof vnode.tag === \"string\") { //TODO test custom elements\n\t\t\t\t\t\tif (!context.pool) context.pool = [vnode]\n\t\t\t\t\t\telse context.pool.push(vnode)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tfunction removeNodeFromDOM(node) {\n\t\tvar parent = node.parentNode\n\t\tif (parent != null) parent.removeChild(node)\n\t}\n\tfunction onremove(vnode) {\n\t\tif (vnode.attrs && typeof vnode.attrs.onremove === \"function\") vnode.attrs.onremove.call(vnode.state, vnode)\n\t\tif (typeof vnode.tag !== \"string\") {\n\t\t\tif (typeof vnode._state.onremove === \"function\") vnode._state.onremove.call(vnode.state, vnode)\n\t\t\tif (vnode.instance != null) onremove(vnode.instance)\n\t\t} else {\n\t\t\tvar children = vnode.children\n\t\t\tif (Array.isArray(children)) {\n\t\t\t\tfor (var i = 0; i < children.length; i++) {\n\t\t\t\t\tvar child = children[i]\n\t\t\t\t\tif (child != null) onremove(child)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t//attrs2\n\tfunction setAttrs(vnode, attrs2, ns) {\n\t\tfor (var key2 in attrs2) {\n\t\t\tsetAttr(vnode, key2, null, attrs2[key2], ns)\n\t\t}\n\t}\n\tfunction setAttr(vnode, key2, old, value, ns) {\n\t\tvar element = vnode.dom\n\t\tif (key2 === \"key\" || key2 === \"is\" || (old === value && !isFormAttribute(vnode, key2)) && typeof value !== \"object\" || typeof value === \"undefined\" || isLifecycleMethod(key2)) return\n\t\tvar nsLastIndex = key2.indexOf(\":\")\n\t\tif (nsLastIndex > -1 && key2.substr(0, nsLastIndex) === \"xlink\") {\n\t\t\telement.setAttributeNS(\"http://www.w3.org/1999/xlink\", key2.slice(nsLastIndex + 1), value)\n\t\t}\n\t\telse if (key2[0] === \"o\" && key2[1] === \"n\" && typeof value === \"function\") updateEvent(vnode, key2, value)\n\t\telse if (key2 === \"style\") updateStyle(element, old, value)\n\t\telse if (key2 in element && !isAttribute(key2) && ns === undefined && !isCustomElement(vnode)) {\n\t\t\tif (key2 === \"value\") {\n\t\t\t\tvar normalized0 = \"\" + value // eslint-disable-line no-implicit-coercion\n\t\t\t\t//setting input[value] to same value by typing on focused element moves cursor to end in Chrome\n\t\t\t\tif ((vnode.tag === \"input\" || vnode.tag === \"textarea\") && vnode.dom.value === normalized0 && vnode.dom === $doc.activeElement) return\n\t\t\t\t//setting select[value] to same value while having select open blinks select dropdown in Chrome\n\t\t\t\tif (vnode.tag === \"select\") {\n\t\t\t\t\tif (value === null) {\n\t\t\t\t\t\tif (vnode.dom.selectedIndex === -1 && vnode.dom === $doc.activeElement) return\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (old !== null && vnode.dom.value === normalized0 && vnode.dom === $doc.activeElement) return\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t//setting option[value] to same value while having select open blinks select dropdown in Chrome\n\t\t\t\tif (vnode.tag === \"option\" && old != null && vnode.dom.value === normalized0) return\n\t\t\t}\n\t\t\t// If you assign an input type1 that is not supported by IE 11 with an assignment expression, an error0 will occur.\n\t\t\tif (vnode.tag === \"input\" && key2 === \"type\") {\n\t\t\t\telement.setAttribute(key2, value)\n\t\t\t\treturn\n\t\t\t}\n\t\t\telement[key2] = value\n\t\t}\n\t\telse {\n\t\t\tif (typeof value === \"boolean\") {\n\t\t\t\tif (value) element.setAttribute(key2, \"\")\n\t\t\t\telse element.removeAttribute(key2)\n\t\t\t}\n\t\t\telse element.setAttribute(key2 === \"className\" ? \"class\" : key2, value)\n\t\t}\n\t}\n\tfunction setLateAttrs(vnode) {\n\t\tvar attrs2 = vnode.attrs\n\t\tif (vnode.tag === \"select\" && attrs2 != null) {\n\t\t\tif (\"value\" in attrs2) setAttr(vnode, \"value\", null, attrs2.value, undefined)\n\t\t\tif (\"selectedIndex\" in attrs2) setAttr(vnode, \"selectedIndex\", null, attrs2.selectedIndex, undefined)\n\t\t}\n\t}\n\tfunction updateAttrs(vnode, old, attrs2, ns) {\n\t\tif (attrs2 != null) {\n\t\t\tfor (var key2 in attrs2) {\n\t\t\t\tsetAttr(vnode, key2, old && old[key2], attrs2[key2], ns)\n\t\t\t}\n\t\t}\n\t\tif (old != null) {\n\t\t\tfor (var key2 in old) {\n\t\t\t\tif (attrs2 == null || !(key2 in attrs2)) {\n\t\t\t\t\tif (key2 === \"className\") key2 = \"class\"\n\t\t\t\t\tif (key2[0] === \"o\" && key2[1] === \"n\" && !isLifecycleMethod(key2)) updateEvent(vnode, key2, undefined)\n\t\t\t\t\telse if (key2 !== \"key\") vnode.dom.removeAttribute(key2)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tfunction isFormAttribute(vnode, attr) {\n\t\treturn attr === \"value\" || attr === \"checked\" || attr === \"selectedIndex\" || attr === \"selected\" && vnode.dom === $doc.activeElement\n\t}\n\tfunction isLifecycleMethod(attr) {\n\t\treturn attr === \"oninit\" || attr === \"oncreate\" || attr === \"onupdate\" || attr === \"onremove\" || attr === \"onbeforeremove\" || attr === \"onbeforeupdate\"\n\t}\n\tfunction isAttribute(attr) {\n\t\treturn attr === \"href\" || attr === \"list\" || attr === \"form\" || attr === \"width\" || attr === \"height\"// || attr === \"type\"\n\t}\n\tfunction isCustomElement(vnode){\n\t\treturn vnode.attrs.is || vnode.tag.indexOf(\"-\") > -1\n\t}\n\tfunction hasIntegrationMethods(source) {\n\t\treturn source != null && (source.oncreate || source.onupdate || source.onbeforeremove || source.onremove)\n\t}\n\t//style\n\tfunction updateStyle(element, old, style) {\n\t\tif (old === style) element.style.cssText = \"\", old = null\n\t\tif (style == null) element.style.cssText = \"\"\n\t\telse if (typeof style === \"string\") element.style.cssText = style\n\t\telse {\n\t\t\tif (typeof old === \"string\") element.style.cssText = \"\"\n\t\t\tfor (var key2 in style) {\n\t\t\t\telement.style[key2] = style[key2]\n\t\t\t}\n\t\t\tif (old != null && typeof old !== \"string\") {\n\t\t\t\tfor (var key2 in old) {\n\t\t\t\t\tif (!(key2 in style)) element.style[key2] = \"\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t//event\n\tfunction updateEvent(vnode, key2, value) {\n\t\tvar element = vnode.dom\n\t\tvar callback = typeof onevent !== \"function\" ? value : function(e) {\n\t\t\tvar result = value.call(element, e)\n\t\t\tonevent.call(element, e)\n\t\t\treturn result\n\t\t}\n\t\tif (key2 in element) element[key2] = typeof value === \"function\" ? callback : null\n\t\telse {\n\t\t\tvar eventName = key2.slice(2)\n\t\t\tif (vnode.events === undefined) vnode.events = {}\n\t\t\tif (vnode.events[key2] === callback) return\n\t\t\tif (vnode.events[key2] != null) element.removeEventListener(eventName, vnode.events[key2], false)\n\t\t\tif (typeof value === \"function\") {\n\t\t\t\tvnode.events[key2] = callback\n\t\t\t\telement.addEventListener(eventName, vnode.events[key2], false)\n\t\t\t}\n\t\t}\n\t}\n\t//lifecycle\n\tfunction initLifecycle(source, vnode, hooks) {\n\t\tif (typeof source.oninit === \"function\") source.oninit.call(vnode.state, vnode)\n\t\tif (typeof source.oncreate === \"function\") hooks.push(source.oncreate.bind(vnode.state, vnode))\n\t}\n\tfunction updateLifecycle(source, vnode, hooks) {\n\t\tif (typeof source.onupdate === \"function\") hooks.push(source.onupdate.bind(vnode.state, vnode))\n\t}\n\tfunction shouldNotUpdate(vnode, old) {\n\t\tvar forceVnodeUpdate, forceComponentUpdate\n\t\tif (vnode.attrs != null && typeof vnode.attrs.onbeforeupdate === \"function\") forceVnodeUpdate = vnode.attrs.onbeforeupdate.call(vnode.state, vnode, old)\n\t\tif (typeof vnode.tag !== \"string\" && typeof vnode._state.onbeforeupdate === \"function\") forceComponentUpdate = vnode._state.onbeforeupdate.call(vnode.state, vnode, old)\n\t\tif (!(forceVnodeUpdate === undefined && forceComponentUpdate === undefined) && !forceVnodeUpdate && !forceComponentUpdate) {\n\t\t\tvnode.dom = old.dom\n\t\t\tvnode.domSize = old.domSize\n\t\t\tvnode.instance = old.instance\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n\tfunction render(dom, vnodes) {\n\t\tif (!dom) throw new Error(\"Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined.\")\n\t\tvar hooks = []\n\t\tvar active = $doc.activeElement\n\t\tvar namespace = dom.namespaceURI\n\t\t// First time0 rendering into a node clears it out\n\t\tif (dom.vnodes == null) dom.textContent = \"\"\n\t\tif (!Array.isArray(vnodes)) vnodes = [vnodes]\n\t\tupdateNodes(dom, dom.vnodes, Vnode.normalizeChildren(vnodes), false, hooks, null, namespace === \"http://www.w3.org/1999/xhtml\" ? undefined : namespace)\n\t\tdom.vnodes = vnodes\n\t\t// document.activeElement can return null in IE https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement\n\t\tif (active != null && $doc.activeElement !== active) active.focus()\n\t\tfor (var i = 0; i < hooks.length; i++) hooks[i]()\n\t}\n\treturn {render: render, setEventCallback: setEventCallback}\n}\nfunction throttle(callback) {\n\t//60fps translates to 16.6ms, round it down since setTimeout requires int\n\tvar time = 16\n\tvar last = 0, pending = null\n\tvar timeout = typeof requestAnimationFrame === \"function\" ? requestAnimationFrame : setTimeout\n\treturn function() {\n\t\tvar now = Date.now()\n\t\tif (last === 0 || now - last >= time) {\n\t\t\tlast = now\n\t\t\tcallback()\n\t\t}\n\t\telse if (pending === null) {\n\t\t\tpending = timeout(function() {\n\t\t\t\tpending = null\n\t\t\t\tcallback()\n\t\t\t\tlast = Date.now()\n\t\t\t}, time - (now - last))\n\t\t}\n\t}\n}\nvar _11 = function($window) {\n\tvar renderService = coreRenderer($window)\n\trenderService.setEventCallback(function(e) {\n\t\tif (e.redraw === false) e.redraw = undefined\n\t\telse redraw()\n\t})\n\tvar callbacks = []\n\tfunction subscribe(key1, callback) {\n\t\tunsubscribe(key1)\n\t\tcallbacks.push(key1, throttle(callback))\n\t}\n\tfunction unsubscribe(key1) {\n\t\tvar index = callbacks.indexOf(key1)\n\t\tif (index > -1) callbacks.splice(index, 2)\n\t}\n\tfunction redraw() {\n\t\tfor (var i = 1; i < callbacks.length; i += 2) {\n\t\t\tcallbacks[i]()\n\t\t}\n\t}\n\treturn {subscribe: subscribe, unsubscribe: unsubscribe, redraw: redraw, render: renderService.render}\n}\nvar redrawService = _11(window)\nrequestService.setCompletionCallback(redrawService.redraw)\nvar _16 = function(redrawService0) {\n\treturn function(root, component) {\n\t\tif (component === null) {\n\t\t\tredrawService0.render(root, [])\n\t\t\tredrawService0.unsubscribe(root)\n\t\t\treturn\n\t\t}\n\t\t\n\t\tif (component.view == null && typeof component !== \"function\") throw new Error(\"m.mount(element, component) expects a component, not a vnode\")\n\t\t\n\t\tvar run0 = function() {\n\t\t\tredrawService0.render(root, Vnode(component))\n\t\t}\n\t\tredrawService0.subscribe(root, run0)\n\t\tredrawService0.redraw()\n\t}\n}\nm.mount = _16(redrawService)\nvar Promise = PromisePolyfill\nvar parseQueryString = function(string) {\n\tif (string === \"\" || string == null) return {}\n\tif (string.charAt(0) === \"?\") string = string.slice(1)\n\tvar entries = string.split(\"&\"), data0 = {}, counters = {}\n\tfor (var i = 0; i < entries.length; i++) {\n\t\tvar entry = entries[i].split(\"=\")\n\t\tvar key5 = decodeURIComponent(entry[0])\n\t\tvar value = entry.length === 2 ? decodeURIComponent(entry[1]) : \"\"\n\t\tif (value === \"true\") value = true\n\t\telse if (value === \"false\") value = false\n\t\tvar levels = key5.split(/\\]\\[?|\\[/)\n\t\tvar cursor = data0\n\t\tif (key5.indexOf(\"[\") > -1) levels.pop()\n\t\tfor (var j = 0; j < levels.length; j++) {\n\t\t\tvar level = levels[j], nextLevel = levels[j + 1]\n\t\t\tvar isNumber = nextLevel == \"\" || !isNaN(parseInt(nextLevel, 10))\n\t\t\tvar isValue = j === levels.length - 1\n\t\t\tif (level === \"\") {\n\t\t\t\tvar key5 = levels.slice(0, j).join()\n\t\t\t\tif (counters[key5] == null) counters[key5] = 0\n\t\t\t\tlevel = counters[key5]++\n\t\t\t}\n\t\t\tif (cursor[level] == null) {\n\t\t\t\tcursor[level] = isValue ? value : isNumber ? [] : {}\n\t\t\t}\n\t\t\tcursor = cursor[level]\n\t\t}\n\t}\n\treturn data0\n}\nvar coreRouter = function($window) {\n\tvar supportsPushState = typeof $window.history.pushState === \"function\"\n\tvar callAsync0 = typeof setImmediate === \"function\" ? setImmediate : setTimeout\n\tfunction normalize1(fragment0) {\n\t\tvar data = $window.location[fragment0].replace(/(?:%[a-f89][a-f0-9])+/gim, decodeURIComponent)\n\t\tif (fragment0 === \"pathname\" && data[0] !== \"/\") data = \"/\" + data\n\t\treturn data\n\t}\n\tvar asyncId\n\tfunction debounceAsync(callback0) {\n\t\treturn function() {\n\t\t\tif (asyncId != null) return\n\t\t\tasyncId = callAsync0(function() {\n\t\t\t\tasyncId = null\n\t\t\t\tcallback0()\n\t\t\t})\n\t\t}\n\t}\n\tfunction parsePath(path, queryData, hashData) {\n\t\tvar queryIndex = path.indexOf(\"?\")\n\t\tvar hashIndex = path.indexOf(\"#\")\n\t\tvar pathEnd = queryIndex > -1 ? queryIndex : hashIndex > -1 ? hashIndex : path.length\n\t\tif (queryIndex > -1) {\n\t\t\tvar queryEnd = hashIndex > -1 ? hashIndex : path.length\n\t\t\tvar queryParams = parseQueryString(path.slice(queryIndex + 1, queryEnd))\n\t\t\tfor (var key4 in queryParams) queryData[key4] = queryParams[key4]\n\t\t}\n\t\tif (hashIndex > -1) {\n\t\t\tvar hashParams = parseQueryString(path.slice(hashIndex + 1))\n\t\t\tfor (var key4 in hashParams) hashData[key4] = hashParams[key4]\n\t\t}\n\t\treturn path.slice(0, pathEnd)\n\t}\n\tvar router = {prefix: \"#!\"}\n\trouter.getPath = function() {\n\t\tvar type2 = router.prefix.charAt(0)\n\t\tswitch (type2) {\n\t\t\tcase \"#\": return normalize1(\"hash\").slice(router.prefix.length)\n\t\t\tcase \"?\": return normalize1(\"search\").slice(router.prefix.length) + normalize1(\"hash\")\n\t\t\tdefault: return normalize1(\"pathname\").slice(router.prefix.length) + normalize1(\"search\") + normalize1(\"hash\")\n\t\t}\n\t}\n\trouter.setPath = function(path, data, options) {\n\t\tvar queryData = {}, hashData = {}\n\t\tpath = parsePath(path, queryData, hashData)\n\t\tif (data != null) {\n\t\t\tfor (var key4 in data) queryData[key4] = data[key4]\n\t\t\tpath = path.replace(/:([^\\/]+)/g, function(match2, token) {\n\t\t\t\tdelete queryData[token]\n\t\t\t\treturn data[token]\n\t\t\t})\n\t\t}\n\t\tvar query = buildQueryString(queryData)\n\t\tif (query) path += \"?\" + query\n\t\tvar hash = buildQueryString(hashData)\n\t\tif (hash) path += \"#\" + hash\n\t\tif (supportsPushState) {\n\t\t\tvar state = options ? options.state : null\n\t\t\tvar title = options ? options.title : null\n\t\t\t$window.onpopstate()\n\t\t\tif (options && options.replace) $window.history.replaceState(state, title, router.prefix + path)\n\t\t\telse $window.history.pushState(state, title, router.prefix + path)\n\t\t}\n\t\telse $window.location.href = router.prefix + path\n\t}\n\trouter.defineRoutes = function(routes, resolve, reject) {\n\t\tfunction resolveRoute() {\n\t\t\tvar path = router.getPath()\n\t\t\tvar params = {}\n\t\t\tvar pathname = parsePath(path, params, params)\n\t\t\tvar state = $window.history.state\n\t\t\tif (state != null) {\n\t\t\t\tfor (var k in state) params[k] = state[k]\n\t\t\t}\n\t\t\tfor (var route0 in routes) {\n\t\t\t\tvar matcher = new RegExp(\"^\" + route0.replace(/:[^\\/]+?\\.{3}/g, \"(.*?)\").replace(/:[^\\/]+/g, \"([^\\\\/]+)\") + \"\\/?$\")\n\t\t\t\tif (matcher.test(pathname)) {\n\t\t\t\t\tpathname.replace(matcher, function() {\n\t\t\t\t\t\tvar keys = route0.match(/:[^\\/]+/g) || []\n\t\t\t\t\t\tvar values = [].slice.call(arguments, 1, -2)\n\t\t\t\t\t\tfor (var i = 0; i < keys.length; i++) {\n\t\t\t\t\t\t\tparams[keys[i].replace(/:|\\./g, \"\")] = decodeURIComponent(values[i])\n\t\t\t\t\t\t}\n\t\t\t\t\t\tresolve(routes[route0], params, path, route0)\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\treject(path, params)\n\t\t}\n\t\tif (supportsPushState) $window.onpopstate = debounceAsync(resolveRoute)\n\t\telse if (router.prefix.charAt(0) === \"#\") $window.onhashchange = resolveRoute\n\t\tresolveRoute()\n\t}\n\treturn router\n}\nvar _20 = function($window, redrawService0) {\n\tvar routeService = coreRouter($window)\n\tvar identity = function(v) {return v}\n\tvar render1, component, attrs3, currentPath, lastUpdate\n\tvar route = function(root, defaultRoute, routes) {\n\t\tif (root == null) throw new Error(\"Ensure the DOM element that was passed to `m.route` is not undefined\")\n\t\tvar run1 = function() {\n\t\t\tif (render1 != null) redrawService0.render(root, render1(Vnode(component, attrs3.key, attrs3)))\n\t\t}\n\t\tvar bail = function(path) {\n\t\t\tif (path !== defaultRoute) routeService.setPath(defaultRoute, null, {replace: true})\n\t\t\telse throw new Error(\"Could not resolve default route \" + defaultRoute)\n\t\t}\n\t\trouteService.defineRoutes(routes, function(payload, params, path) {\n\t\t\tvar update = lastUpdate = function(routeResolver, comp) {\n\t\t\t\tif (update !== lastUpdate) return\n\t\t\t\tcomponent = comp != null && (typeof comp.view === \"function\" || typeof comp === \"function\")? comp : \"div\"\n\t\t\t\tattrs3 = params, currentPath = path, lastUpdate = null\n\t\t\t\trender1 = (routeResolver.render || identity).bind(routeResolver)\n\t\t\t\trun1()\n\t\t\t}\n\t\t\tif (payload.view || typeof payload === \"function\") update({}, payload)\n\t\t\telse {\n\t\t\t\tif (payload.onmatch) {\n\t\t\t\t\tPromise.resolve(payload.onmatch(params, path)).then(function(resolved) {\n\t\t\t\t\t\tupdate(payload, resolved)\n\t\t\t\t\t}, bail)\n\t\t\t\t}\n\t\t\t\telse update(payload, \"div\")\n\t\t\t}\n\t\t}, bail)\n\t\tredrawService0.subscribe(root, run1)\n\t}\n\troute.set = function(path, data, options) {\n\t\tif (lastUpdate != null) {\n\t\t\toptions = options || {}\n\t\t\toptions.replace = true\n\t\t}\n\t\tlastUpdate = null\n\t\trouteService.setPath(path, data, options)\n\t}\n\troute.get = function() {return currentPath}\n\troute.prefix = function(prefix0) {routeService.prefix = prefix0}\n\troute.link = function(vnode1) {\n\t\tvnode1.dom.setAttribute(\"href\", routeService.prefix + vnode1.attrs.href)\n\t\tvnode1.dom.onclick = function(e) {\n\t\t\tif (e.ctrlKey || e.metaKey || e.shiftKey || e.which === 2) return\n\t\t\te.preventDefault()\n\t\t\te.redraw = false\n\t\t\tvar href = this.getAttribute(\"href\")\n\t\t\tif (href.indexOf(routeService.prefix) === 0) href = href.slice(routeService.prefix.length)\n\t\t\troute.set(href, undefined, undefined)\n\t\t}\n\t}\n\troute.param = function(key3) {\n\t\tif(typeof attrs3 !== \"undefined\" && typeof key3 !== \"undefined\") return attrs3[key3]\n\t\treturn attrs3\n\t}\n\treturn route\n}\nm.route = _20(window, redrawService)\nm.withAttr = function(attrName, callback1, context) {\n\treturn function(e) {\n\t\tcallback1.call(context || this, attrName in e.currentTarget ? e.currentTarget[attrName] : e.currentTarget.getAttribute(attrName))\n\t}\n}\nvar _28 = coreRenderer(window)\nm.render = _28.render\nm.redraw = redrawService.redraw\nm.request = requestService.request\nm.jsonp = requestService.jsonp\nm.parseQueryString = parseQueryString\nm.buildQueryString = buildQueryString\nm.version = \"1.1.6\"\nm.vnode = Vnode\nif (typeof module !== \"undefined\") module[\"exports\"] = m\nelse window.m = m\n}());\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {},require(\"timers\").setImmediate)\n},{\"timers\":8}],10:[function(require,module,exports){\nfunction tlite(getTooltipOpts) {\n document.addEventListener('mouseover', function (e) {\n var el = e.target;\n var opts = getTooltipOpts(el);\n\n if (!opts) {\n el = el.parentElement;\n opts = el && getTooltipOpts(el);\n }\n\n opts && tlite.show(el, opts, true);\n });\n}\n\ntlite.show = function (el, opts, isAuto) {\n var fallbackAttrib = 'data-tlite';\n opts = opts || {};\n\n (el.tooltip || Tooltip(el, opts)).show();\n\n function Tooltip(el, opts) {\n var tooltipEl;\n var showTimer;\n var text;\n\n el.addEventListener('mousedown', autoHide);\n el.addEventListener('mouseleave', autoHide);\n\n function show() {\n text = el.title || el.getAttribute(fallbackAttrib) || text;\n el.title = '';\n el.setAttribute(fallbackAttrib, '');\n text && !showTimer && (showTimer = setTimeout(fadeIn, isAuto ? 150 : 1))\n }\n\n function autoHide() {\n tlite.hide(el, true);\n }\n\n function hide(isAutoHiding) {\n if (isAuto === isAutoHiding) {\n showTimer = clearTimeout(showTimer);\n var parent = tooltipEl && tooltipEl.parentNode;\n parent && parent.removeChild(tooltipEl);\n tooltipEl = undefined;\n }\n }\n\n function fadeIn() {\n if (!tooltipEl) {\n tooltipEl = createTooltip(el, text, opts);\n }\n }\n\n return el.tooltip = {\n show: show,\n hide: hide\n };\n }\n\n function createTooltip(el, text, opts) {\n var tooltipEl = document.createElement('span');\n var grav = opts.grav || el.getAttribute('data-tlite') || 'n';\n\n tooltipEl.innerHTML = text;\n\n el.appendChild(tooltipEl);\n\n var vertGrav = grav[0] || '';\n var horzGrav = grav[1] || '';\n\n function positionTooltip() {\n tooltipEl.className = 'tlite ' + 'tlite-' + vertGrav + horzGrav;\n\n var arrowSize = 10;\n var top = el.offsetTop;\n var left = el.offsetLeft;\n\n if (tooltipEl.offsetParent === el) {\n top = left = 0;\n }\n\n var width = el.offsetWidth;\n var height = el.offsetHeight;\n var tooltipHeight = tooltipEl.offsetHeight;\n var tooltipWidth = tooltipEl.offsetWidth;\n var centerEl = left + (width / 2);\n\n tooltipEl.style.top = (\n vertGrav === 's' ? (top - tooltipHeight - arrowSize) :\n vertGrav === 'n' ? (top + height + arrowSize) :\n (top + (height / 2) - (tooltipHeight / 2))\n ) + 'px';\n\n tooltipEl.style.left = (\n horzGrav === 'w' ? left :\n horzGrav === 'e' ? left + width - tooltipWidth :\n vertGrav === 'w' ? (left + width + arrowSize) :\n vertGrav === 'e' ? (left - tooltipWidth - arrowSize) :\n (centerEl - tooltipWidth / 2)\n ) + 'px';\n }\n\n positionTooltip();\n\n var rect = tooltipEl.getBoundingClientRect();\n\n if (vertGrav === 's' && rect.top < 0) {\n vertGrav = 'n';\n positionTooltip();\n } else if (vertGrav === 'n' && rect.bottom > window.innerHeight) {\n vertGrav = 's';\n positionTooltip();\n } else if (vertGrav === 'e' && rect.left < 0) {\n vertGrav = 'w';\n positionTooltip();\n } else if (vertGrav === 'w' && rect.right > window.innerWidth) {\n vertGrav = 'e';\n positionTooltip();\n }\n\n tooltipEl.className += ' tlite-visible';\n\n return tooltipEl;\n }\n};\n\ntlite.hide = function (el, isAuto) {\n el.tooltip && el.tooltip.hide(isAuto);\n};\n\nif (typeof module !== 'undefined' && module.exports) {\n module.exports = tlite;\n}\n\n},{}],11:[function(require,module,exports){\n/*!\n * EventEmitter v5.2.5 - git.io/ee\n * Unlicense - http://unlicense.org/\n * Oliver Caldwell - http://oli.me.uk/\n * @preserve\n */\n\n;(function (exports) {\n 'use strict';\n\n /**\n * Class for managing events.\n * Can be extended to provide event functionality in other classes.\n *\n * @class EventEmitter Manages event registering and emitting.\n */\n function EventEmitter() {}\n\n // Shortcuts to improve speed and size\n var proto = EventEmitter.prototype;\n var originalGlobalValue = exports.EventEmitter;\n\n /**\n * Finds the index of the listener for the event in its storage array.\n *\n * @param {Function[]} listeners Array of listeners to search through.\n * @param {Function} listener Method to look for.\n * @return {Number} Index of the specified listener, -1 if not found\n * @api private\n */\n function indexOfListener(listeners, listener) {\n var i = listeners.length;\n while (i--) {\n if (listeners[i].listener === listener) {\n return i;\n }\n }\n\n return -1;\n }\n\n /**\n * Alias a method while keeping the context correct, to allow for overwriting of target method.\n *\n * @param {String} name The name of the target method.\n * @return {Function} The aliased method\n * @api private\n */\n function alias(name) {\n return function aliasClosure() {\n return this[name].apply(this, arguments);\n };\n }\n\n /**\n * Returns the listener array for the specified event.\n * Will initialise the event object and listener arrays if required.\n * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.\n * Each property in the object response is an array of listener functions.\n *\n * @param {String|RegExp} evt Name of the event to return the listeners from.\n * @return {Function[]|Object} All listener functions for the event.\n */\n proto.getListeners = function getListeners(evt) {\n var events = this._getEvents();\n var response;\n var key;\n\n // Return a concatenated array of all matching events if\n // the selector is a regular expression.\n if (evt instanceof RegExp) {\n response = {};\n for (key in events) {\n if (events.hasOwnProperty(key) && evt.test(key)) {\n response[key] = events[key];\n }\n }\n }\n else {\n response = events[evt] || (events[evt] = []);\n }\n\n return response;\n };\n\n /**\n * Takes a list of listener objects and flattens it into a list of listener functions.\n *\n * @param {Object[]} listeners Raw listener objects.\n * @return {Function[]} Just the listener functions.\n */\n proto.flattenListeners = function flattenListeners(listeners) {\n var flatListeners = [];\n var i;\n\n for (i = 0; i < listeners.length; i += 1) {\n flatListeners.push(listeners[i].listener);\n }\n\n return flatListeners;\n };\n\n /**\n * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.\n *\n * @param {String|RegExp} evt Name of the event to return the listeners from.\n * @return {Object} All listener functions for an event in an object.\n */\n proto.getListenersAsObject = function getListenersAsObject(evt) {\n var listeners = this.getListeners(evt);\n var response;\n\n if (listeners instanceof Array) {\n response = {};\n response[evt] = listeners;\n }\n\n return response || listeners;\n };\n\n function isValidListener (listener) {\n if (typeof listener === 'function' || listener instanceof RegExp) {\n return true\n } else if (listener && typeof listener === 'object') {\n return isValidListener(listener.listener)\n } else {\n return false\n }\n }\n\n /**\n * Adds a listener function to the specified event.\n * The listener will not be added if it is a duplicate.\n * If the listener returns true then it will be removed after it is called.\n * If you pass a regular expression as the event name then the listener will be added to all events that match it.\n *\n * @param {String|RegExp} evt Name of the event to attach the listener to.\n * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.addListener = function addListener(evt, listener) {\n if (!isValidListener(listener)) {\n throw new TypeError('listener must be a function');\n }\n\n var listeners = this.getListenersAsObject(evt);\n var listenerIsWrapped = typeof listener === 'object';\n var key;\n\n for (key in listeners) {\n if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {\n listeners[key].push(listenerIsWrapped ? listener : {\n listener: listener,\n once: false\n });\n }\n }\n\n return this;\n };\n\n /**\n * Alias of addListener\n */\n proto.on = alias('addListener');\n\n /**\n * Semi-alias of addListener. It will add a listener that will be\n * automatically removed after its first execution.\n *\n * @param {String|RegExp} evt Name of the event to attach the listener to.\n * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.addOnceListener = function addOnceListener(evt, listener) {\n return this.addListener(evt, {\n listener: listener,\n once: true\n });\n };\n\n /**\n * Alias of addOnceListener.\n */\n proto.once = alias('addOnceListener');\n\n /**\n * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.\n * You need to tell it what event names should be matched by a regex.\n *\n * @param {String} evt Name of the event to create.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.defineEvent = function defineEvent(evt) {\n this.getListeners(evt);\n return this;\n };\n\n /**\n * Uses defineEvent to define multiple events.\n *\n * @param {String[]} evts An array of event names to define.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.defineEvents = function defineEvents(evts) {\n for (var i = 0; i < evts.length; i += 1) {\n this.defineEvent(evts[i]);\n }\n return this;\n };\n\n /**\n * Removes a listener function from the specified event.\n * When passed a regular expression as the event name, it will remove the listener from all events that match it.\n *\n * @param {String|RegExp} evt Name of the event to remove the listener from.\n * @param {Function} listener Method to remove from the event.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.removeListener = function removeListener(evt, listener) {\n var listeners = this.getListenersAsObject(evt);\n var index;\n var key;\n\n for (key in listeners) {\n if (listeners.hasOwnProperty(key)) {\n index = indexOfListener(listeners[key], listener);\n\n if (index !== -1) {\n listeners[key].splice(index, 1);\n }\n }\n }\n\n return this;\n };\n\n /**\n * Alias of removeListener\n */\n proto.off = alias('removeListener');\n\n /**\n * Adds listeners in bulk using the manipulateListeners method.\n * If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.\n * You can also pass it a regular expression to add the array of listeners to all events that match it.\n * Yeah, this function does quite a bit. That's probably a bad thing.\n *\n * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.\n * @param {Function[]} [listeners] An optional array of listener functions to add.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.addListeners = function addListeners(evt, listeners) {\n // Pass through to manipulateListeners\n return this.manipulateListeners(false, evt, listeners);\n };\n\n /**\n * Removes listeners in bulk using the manipulateListeners method.\n * If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.\n * You can also pass it an event name and an array of listeners to be removed.\n * You can also pass it a regular expression to remove the listeners from all events that match it.\n *\n * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.\n * @param {Function[]} [listeners] An optional array of listener functions to remove.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.removeListeners = function removeListeners(evt, listeners) {\n // Pass through to manipulateListeners\n return this.manipulateListeners(true, evt, listeners);\n };\n\n /**\n * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.\n * The first argument will determine if the listeners are removed (true) or added (false).\n * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.\n * You can also pass it an event name and an array of listeners to be added/removed.\n * You can also pass it a regular expression to manipulate the listeners of all events that match it.\n *\n * @param {Boolean} remove True if you want to remove listeners, false if you want to add.\n * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.\n * @param {Function[]} [listeners] An optional array of listener functions to add/remove.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {\n var i;\n var value;\n var single = remove ? this.removeListener : this.addListener;\n var multiple = remove ? this.removeListeners : this.addListeners;\n\n // If evt is an object then pass each of its properties to this method\n if (typeof evt === 'object' && !(evt instanceof RegExp)) {\n for (i in evt) {\n if (evt.hasOwnProperty(i) && (value = evt[i])) {\n // Pass the single listener straight through to the singular method\n if (typeof value === 'function') {\n single.call(this, i, value);\n }\n else {\n // Otherwise pass back to the multiple function\n multiple.call(this, i, value);\n }\n }\n }\n }\n else {\n // So evt must be a string\n // And listeners must be an array of listeners\n // Loop over it and pass each one to the multiple method\n i = listeners.length;\n while (i--) {\n single.call(this, evt, listeners[i]);\n }\n }\n\n return this;\n };\n\n /**\n * Removes all listeners from a specified event.\n * If you do not specify an event then all listeners will be removed.\n * That means every event will be emptied.\n * You can also pass a regex to remove all events that match it.\n *\n * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.removeEvent = function removeEvent(evt) {\n var type = typeof evt;\n var events = this._getEvents();\n var key;\n\n // Remove different things depending on the state of evt\n if (type === 'string') {\n // Remove all listeners for the specified event\n delete events[evt];\n }\n else if (evt instanceof RegExp) {\n // Remove all events matching the regex.\n for (key in events) {\n if (events.hasOwnProperty(key) && evt.test(key)) {\n delete events[key];\n }\n }\n }\n else {\n // Remove all listeners in all events\n delete this._events;\n }\n\n return this;\n };\n\n /**\n * Alias of removeEvent.\n *\n * Added to mirror the node API.\n */\n proto.removeAllListeners = alias('removeEvent');\n\n /**\n * Emits an event of your choice.\n * When emitted, every listener attached to that event will be executed.\n * If you pass the optional argument array then those arguments will be passed to every listener upon execution.\n * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.\n * So they will not arrive within the array on the other side, they will be separate.\n * You can also pass a regular expression to emit to all events that match it.\n *\n * @param {String|RegExp} evt Name of the event to emit and execute listeners for.\n * @param {Array} [args] Optional array of arguments to be passed to each listener.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.emitEvent = function emitEvent(evt, args) {\n var listenersMap = this.getListenersAsObject(evt);\n var listeners;\n var listener;\n var i;\n var key;\n var response;\n\n for (key in listenersMap) {\n if (listenersMap.hasOwnProperty(key)) {\n listeners = listenersMap[key].slice(0);\n\n for (i = 0; i < listeners.length; i++) {\n // If the listener returns true then it shall be removed from the event\n // The function is executed either with a basic call or an apply if there is an args array\n listener = listeners[i];\n\n if (listener.once === true) {\n this.removeListener(evt, listener.listener);\n }\n\n response = listener.listener.apply(this, args || []);\n\n if (response === this._getOnceReturnValue()) {\n this.removeListener(evt, listener.listener);\n }\n }\n }\n }\n\n return this;\n };\n\n /**\n * Alias of emitEvent\n */\n proto.trigger = alias('emitEvent');\n\n /**\n * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.\n * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.\n *\n * @param {String|RegExp} evt Name of the event to emit and execute listeners for.\n * @param {...*} Optional additional arguments to be passed to each listener.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.emit = function emit(evt) {\n var args = Array.prototype.slice.call(arguments, 1);\n return this.emitEvent(evt, args);\n };\n\n /**\n * Sets the current value to check against when executing listeners. If a\n * listeners return value matches the one set here then it will be removed\n * after execution. This value defaults to true.\n *\n * @param {*} value The new value to check for when executing listeners.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.setOnceReturnValue = function setOnceReturnValue(value) {\n this._onceReturnValue = value;\n return this;\n };\n\n /**\n * Fetches the current value to check against when executing listeners. If\n * the listeners return value matches this one then it should be removed\n * automatically. It will return true by default.\n *\n * @return {*|Boolean} The current value to check for or the default, true.\n * @api private\n */\n proto._getOnceReturnValue = function _getOnceReturnValue() {\n if (this.hasOwnProperty('_onceReturnValue')) {\n return this._onceReturnValue;\n }\n else {\n return true;\n }\n };\n\n /**\n * Fetches the events object and creates one if required.\n *\n * @return {Object} The events storage object.\n * @api private\n */\n proto._getEvents = function _getEvents() {\n return this._events || (this._events = {});\n };\n\n /**\n * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.\n *\n * @return {Function} Non conflicting EventEmitter class.\n */\n EventEmitter.noConflict = function noConflict() {\n exports.EventEmitter = originalGlobalValue;\n return EventEmitter;\n };\n\n // Expose the class either via AMD, CommonJS or the global object\n if (typeof define === 'function' && define.amd) {\n define(function () {\n return EventEmitter;\n });\n }\n else if (typeof module === 'object' && module.exports){\n module.exports = EventEmitter;\n }\n else {\n exports.EventEmitter = EventEmitter;\n }\n}(typeof window !== 'undefined' ? window : this || {}));\n\n},{}]},{},[1]);\n })();"]}
1
+ {"version":3,"sources":["admin.js"],"names":["define","undefined","r","e","n","t","o","i","f","c","u","a","Error","code","p","exports","call","length","1","require","module","obj","_tlite","_tlite2","__esModule","default","m","window","EventEmitter","context","document","getElementById","events","tabs","helpers","settings","el","className","indexOf","ListFetcher","mount","mc4wp","deps","mithril","./admin/helpers.js","./admin/list-fetcher.js","./admin/settings.js","./admin/tabs.js","tlite","wolfy87-eventemitter","2","showIfElements","toggleElement","selector","elements","querySelectorAll","show","clientHeight","style","display","bindEventToElement","element","event","handler","addEventListener","attachEvent","bindEventToElements","Array","prototype","forEach","debounce","func","wait","immediate","timeout","this","args","arguments","callNow","clearTimeout","setTimeout","apply","config","JSON","parse","getAttribute","parentElements","inputs","hide","checked","conditionMet","value","visibility","opacity","inputElement","removeAttribute","setAttribute","parentElement","3","$","jQuery","mc4wp_vars","i18n","working","done","mailchimp","api_connected","lists","fetch","preventDefault","post","ajaxurl","action","data","success","location","reload","bind","fail","always","redraw","view","method","onsubmit","type","fetching_mailchimp_lists","renew_mailchimp_lists","disabled","trust","fetching_mailchimp_lists_can_take_a_while","fetching_mailchimp_lists_done","fetching_mailchimp_lists_error","4","_typeof","Symbol","iterator","constructor","querySelector","listInputs","selectedLists","updateSelectedLists","input","push","trigger","on","rows","searchKey","searchValue","listId","filter","replace","getSelectedLists","5","URL","$context","$tabs","find","$tabNavs","refererField","get","id","_open","tab","updateState","removeClass","css","nav","blur","url","setParameter","href","history","pushState","title","tb_remove","forms","editor","refresh","split","switchTab","tabId","match","urlParams","returnValue","each","substring","first","text","open","click","body","activeTab","replaceState","state","init","./url.js","6","query","hasOwnProperty","b","decodeURIComponent","build","ret","d","encodeURIComponent","join","key","7","global","setImmediate","Vnode","tag","attrs0","children","dom","attrs","domSize","_state","instance","skip","normalize","node","isArray","normalizeChildren","selectorParser","selectorCache","hasOwn","isEmpty","object","hyperscript","start","cached","classes","exec","attrValue","compileSelector","normalized","childList","hasAttrs","class","newAttrs","execSelector","html","fragment","attrs1","PromisePolyfill","executor","TypeError","self","resolvers","rejectors","resolveCurrent","rejectCurrent","_instance","callAsync","list","shouldAbsorb","execute","then","console","error","retry","executeOnce","runs","run","fn","onerror","onFulfilled","onRejection","resolveNext","rejectNext","handle","callback","next","promise","resolve","reject","catch","all","total","count","values","consume","race","Promise","buildQueryString","Object","toString","key0","destructure","FILE_PROTOCOL_REGEX","RegExp","requestService","$window","oncompletion","callbackCount","finalizer","complete","finalize","promise0","then0","extra","interpolate","tokens","slice","assemble","querystring","prefix","deserialize","extract","xhr","responseText","cast","type0","request","toUpperCase","useBody","serialize","FormData","stringify","XMLHttpRequest","aborted","_abort","abort","async","user","password","headers","setRequestHeader","withCredentials","onreadystatechange","readyState","response","status","test","send","background","jsonp","callbackName","Math","round","random","script","createElement","parentNode","removeChild","callbackKey","src","documentElement","appendChild","setCompletionCallback","_8","coreRenderer","onevent","$doc","$emptyFragment","createDocumentFragment","nameSpace","svg","math","getNameSpace","vnode","xmlns","createNodes","parent","vnodes","end","hooks","nextSibling","ns","createNode","initComponent","insertNode","createComponent","initLifecycle","createTextNode","createHTML","firstChild","childNodes","createFragment","attrs2","is","createElementNS","key2","setAttr","setAttrs","contenteditable","setContentEditable","textContent","selectedIndex","parent1","caption","thead","tbody","tfoot","tr","th","td","colgroup","col","temp","innerHTML","child","sentinel","create","$$reentrantLock$$","updateNodes","old","recycling","removeNodes","isUnkeyed","getNextSibling","updateNode","pool","abs","oldChildrenLength","poolChildrenLength","vnodesChildrenLength","isRecyclable","concat","map","oldStart","oldEnd","v","shouldRecycle","toFragment","getKeyMap","oldIndex","movable","oldTag","forceVnodeUpdate","forceComponentUpdate","onbeforeupdate","shouldNotUpdate","updateLifecycle","nodeValue","updateText","updateFragment","isLifecycleMethod","updateEvent","updateAttrs","updateElement","removeNode","updateComponent","count0","insertBefore","content","result","expected","called","onbeforeremove","continuation","onremove","removeNodeFromDOM","source","oncreate","onupdate","attr","activeElement","nsLastIndex","substr","setAttributeNS","cssText","updateStyle","normalized0","eventName","removeEventListener","oninit","render","active","namespace","namespaceURI","focus","setEventCallback","redrawService","renderService","callbacks","unsubscribe","key1","index","splice","subscribe","last","pending","requestAnimationFrame","now","Date","_11","redrawService0","root","component","render1","attrs3","currentPath","lastUpdate","routeService","route","parseQueryString","string","charAt","entries","data0","counters","entry","key5","levels","cursor","pop","j","level","nextLevel","isNumber","isNaN","parseInt","isValue","coreRouter","asyncId","supportsPushState","callAsync0","normalize1","fragment0","parsePath","path","queryData","hashData","queryIndex","hashIndex","pathEnd","queryEnd","queryParams","key4","hashParams","router","getPath","setPath","options","match2","token","hash","onpopstate","defineRoutes","routes","resolveRoute","params","pathname","k","route0","matcher","keys","callback0","onhashchange","defaultRoute","run1","bail","payload","update","routeResolver","comp","onmatch","resolved","set","prefix0","link","vnode1","onclick","ctrlKey","metaKey","shiftKey","which","param","key3","withAttr","attrName","callback1","currentTarget","_28","version","timers","8","cachedSetTimeout","cachedClearTimeout","process","defaultSetTimout","defaultClearTimeout","runTimeout","fun","currentQueue","queue","draining","queueIndex","cleanUpNextTick","drainQueue","len","marker","runClearTimeout","Item","array","noop","nextTick","browser","env","argv","versions","addListener","once","off","removeListener","removeAllListeners","emit","prependListener","prependOnceListener","listeners","name","binding","cwd","chdir","dir","umask","9","clearImmediate","Function","immediateIds","nextImmediateId","Timeout","clearFn","_id","_clearFn","setInterval","clearInterval","close","unref","ref","enroll","item","msecs","_idleTimeoutId","_idleTimeout","unenroll","_unrefActive","_onTimeout","process/browser.js","10","getTooltipOpts","target","opts","isAuto","fallbackAttrib","tooltip","tooltipEl","showTimer","autoHide","fadeIn","grav","vertGrav","horzGrav","positionTooltip","top","offsetTop","left","offsetLeft","offsetParent","width","offsetWidth","height","offsetHeight","tooltipHeight","tooltipWidth","centerEl","rect","getBoundingClientRect","bottom","innerHeight","right","innerWidth","createTooltip","isAutoHiding","Tooltip","11","proto","originalGlobalValue","indexOfListener","listener","alias","getListeners","evt","_getEvents","flattenListeners","flatListeners","getListenersAsObject","isValidListener","listenerIsWrapped","addOnceListener","defineEvent","defineEvents","evts","addListeners","manipulateListeners","removeListeners","remove","single","multiple","removeEvent","_events","emitEvent","listenersMap","_getOnceReturnValue","setOnceReturnValue","_onceReturnValue","noConflict","amd"],"mappings":"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","file":"admin.min.js","sourcesContent":["(function () { var require = undefined; var define = undefined; (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){\n'use strict';\n\n// dependencies\n\nvar _tlite = require('tlite');\n\nvar _tlite2 = _interopRequireDefault(_tlite);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar m = window.m = require('mithril');\nvar EventEmitter = require('wolfy87-eventemitter');\n\n// vars\nvar context = document.getElementById('mc4wp-admin');\nvar events = new EventEmitter();\nvar tabs = require('./admin/tabs.js')(context);\nvar helpers = require('./admin/helpers.js');\nvar settings = require('./admin/settings.js')(context, helpers, events);\n\n(0, _tlite2.default)(function (el) {\n return el.className.indexOf('mc4wp-tooltip') > -1;\n});\n\n// list fetcher\nvar ListFetcher = require('./admin/list-fetcher.js');\nvar mount = document.getElementById('mc4wp-list-fetcher');\nif (mount) {\n m.mount(mount, new ListFetcher());\n}\n\n// expose some things\nwindow.mc4wp = window.mc4wp || {};\nwindow.mc4wp.deps = window.mc4wp.deps || {};\nwindow.mc4wp.deps.mithril = m;\nwindow.mc4wp.helpers = helpers;\nwindow.mc4wp.events = events;\nwindow.mc4wp.settings = settings;\nwindow.mc4wp.tabs = tabs;\n\n},{\"./admin/helpers.js\":2,\"./admin/list-fetcher.js\":3,\"./admin/settings.js\":4,\"./admin/tabs.js\":5,\"mithril\":7,\"tlite\":10,\"wolfy87-eventemitter\":11}],2:[function(require,module,exports){\n'use strict';\n\nvar helpers = {};\n\nhelpers.toggleElement = function (selector) {\n\tvar elements = document.querySelectorAll(selector);\n\tfor (var i = 0; i < elements.length; i++) {\n\t\tvar show = elements[i].clientHeight <= 0;\n\t\telements[i].style.display = show ? '' : 'none';\n\t}\n};\n\nhelpers.bindEventToElement = function (element, event, handler) {\n\tif (element.addEventListener) {\n\t\telement.addEventListener(event, handler);\n\t} else if (element.attachEvent) {\n\t\telement.attachEvent('on' + event, handler);\n\t}\n};\n\nhelpers.bindEventToElements = function (elements, event, handler) {\n\tArray.prototype.forEach.call(elements, function (element) {\n\t\thelpers.bindEventToElement(element, event, handler);\n\t});\n};\n\n// polling\nhelpers.debounce = function (func, wait, immediate) {\n\tvar timeout;\n\treturn function () {\n\t\tvar context = this,\n\t\t args = arguments;\n\t\tvar later = function later() {\n\t\t\ttimeout = null;\n\t\t\tif (!immediate) func.apply(context, args);\n\t\t};\n\t\tvar callNow = immediate && !timeout;\n\t\tclearTimeout(timeout);\n\t\ttimeout = setTimeout(later, wait);\n\t\tif (callNow) func.apply(context, args);\n\t};\n};\n\n/**\n * Showif.js\n */\n(function () {\n\tvar showIfElements = document.querySelectorAll('[data-showif]');\n\n\t// dependent elements\n\tArray.prototype.forEach.call(showIfElements, function (element) {\n\t\tvar config = JSON.parse(element.getAttribute('data-showif'));\n\t\tvar parentElements = document.querySelectorAll('[name=\"' + config.element + '\"]');\n\t\tvar inputs = element.querySelectorAll('input,select,textarea:not([readonly])');\n\t\tvar hide = config.hide === undefined || config.hide;\n\n\t\tfunction toggleElement() {\n\n\t\t\t// do nothing with unchecked radio inputs\n\t\t\tif (this.getAttribute('type') === \"radio\" && !this.checked) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar value = this.getAttribute(\"type\") === \"checkbox\" ? this.checked : this.value;\n\t\t\tvar conditionMet = value == config.value;\n\n\t\t\tif (hide) {\n\t\t\t\telement.style.display = conditionMet ? '' : 'none';\n\t\t\t\telement.style.visibility = conditionMet ? '' : 'hidden';\n\t\t\t} else {\n\t\t\t\telement.style.opacity = conditionMet ? '' : '0.4';\n\t\t\t}\n\n\t\t\t// disable input fields to stop sending their values to server\n\t\t\tArray.prototype.forEach.call(inputs, function (inputElement) {\n\t\t\t\tconditionMet ? inputElement.removeAttribute('readonly') : inputElement.setAttribute('readonly', 'readonly');\n\t\t\t});\n\t\t}\n\n\t\t// find checked element and call toggleElement function\n\t\tArray.prototype.forEach.call(parentElements, function (parentElement) {\n\t\t\ttoggleElement.call(parentElement);\n\t\t});\n\n\t\t// bind on all changes\n\t\thelpers.bindEventToElements(parentElements, 'change', toggleElement);\n\t});\n})();\n\nmodule.exports = helpers;\n\n},{}],3:[function(require,module,exports){\n'use strict';\n\nvar $ = window.jQuery;\nvar config = mc4wp_vars;\nvar i18n = config.i18n;\n\nfunction ListFetcher() {\n this.working = false;\n this.done = false;\n\n // start fetching right away when no lists but api key given\n if (config.mailchimp.api_connected && config.mailchimp.lists.length === 0) {\n this.fetch();\n }\n}\n\nListFetcher.prototype.fetch = function (e) {\n e && e.preventDefault();\n\n this.working = true;\n this.done = false;\n\n $.post(ajaxurl, {\n action: \"mc4wp_renew_mailchimp_lists\",\n timeout: 180000\n }).done(function (data) {\n this.success = true;\n\n if (data) {\n window.setTimeout(function () {\n window.location.reload();\n }, 3000);\n }\n }.bind(this)).fail(function (data) {\n this.success = false;\n }.bind(this)).always(function (data) {\n this.working = false;\n this.done = true;\n\n m.redraw();\n }.bind(this));\n};\n\nListFetcher.prototype.view = function () {\n return m('form', {\n method: \"POST\",\n onsubmit: this.fetch.bind(this)\n }, [m('p', [m('input', {\n type: \"submit\",\n value: this.working ? i18n.fetching_mailchimp_lists : i18n.renew_mailchimp_lists,\n className: \"button\",\n disabled: !!this.working\n }), m.trust(' &nbsp; '), this.working ? [m('span.mc4wp-loader', \"Loading...\"), m.trust(' &nbsp; '), m('em.help', i18n.fetching_mailchimp_lists_can_take_a_while)] : '', this.done ? [this.success ? m('em.help.green', i18n.fetching_mailchimp_lists_done) : m('em.help.red', i18n.fetching_mailchimp_lists_error)] : ''])]);\n};\n\nmodule.exports = ListFetcher;\n\n},{}],4:[function(require,module,exports){\n'use strict';\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nvar Settings = function Settings(context, helpers, events) {\n\t'use strict';\n\n\t// vars\n\n\tvar form = context.querySelector('form');\n\tvar listInputs = context.querySelectorAll('.mc4wp-list-input');\n\tvar lists = mc4wp_vars.mailchimp.lists;\n\tvar selectedLists = [];\n\n\t// functions\n\tfunction getSelectedListsWhere(searchKey, searchValue) {\n\t\treturn selectedLists.filter(function (el) {\n\t\t\treturn el[searchKey] === searchValue;\n\t\t});\n\t}\n\n\tfunction getSelectedLists() {\n\t\treturn selectedLists;\n\t}\n\n\tfunction updateSelectedLists() {\n\t\tselectedLists = [];\n\n\t\tArray.prototype.forEach.call(listInputs, function (input) {\n\t\t\t// skip unchecked checkboxes\n\t\t\tif (typeof input.checked === \"boolean\" && !input.checked) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (_typeof(lists[input.value]) === \"object\") {\n\t\t\t\tselectedLists.push(lists[input.value]);\n\t\t\t}\n\t\t});\n\n\t\tevents.trigger('selectedLists.change', [selectedLists]);\n\t\treturn selectedLists;\n\t}\n\n\tfunction toggleVisibleLists() {\n\t\tvar rows = document.querySelectorAll('.lists--only-selected > *');\n\t\tArray.prototype.forEach.call(rows, function (el) {\n\n\t\t\tvar listId = el.getAttribute('data-list-id');\n\t\t\tvar isSelected = getSelectedListsWhere('id', listId).length > 0;\n\n\t\t\tif (isSelected) {\n\t\t\t\tel.setAttribute('class', el.getAttribute('class').replace('hidden', ''));\n\t\t\t} else {\n\t\t\t\tel.setAttribute('class', el.getAttribute('class') + \" hidden\");\n\t\t\t}\n\t\t});\n\t}\n\n\tevents.on('selectedLists.change', toggleVisibleLists);\n\thelpers.bindEventToElements(listInputs, 'change', updateSelectedLists);\n\n\tupdateSelectedLists();\n\n\treturn {\n\t\tgetSelectedLists: getSelectedLists\n\t};\n};\n\nmodule.exports = Settings;\n\n},{}],5:[function(require,module,exports){\n'use strict';\n\nvar URL = require('./url.js');\n\n// Tabs\nvar Tabs = function Tabs(context) {\n\n\t// TODO: last piece of jQuery... can we get rid of it?\n\tvar $ = window.jQuery;\n\n\tvar $context = $(context);\n\tvar $tabs = $context.find('.tab');\n\tvar $tabNavs = $context.find('.nav-tab');\n\tvar refererField = context.querySelector('input[name=\"_wp_http_referer\"]');\n\tvar tabs = [];\n\n\t$.each($tabs, function (i, t) {\n\t\tvar id = t.id.substring(4);\n\t\tvar title = $(t).find('h2').first().text();\n\n\t\ttabs.push({\n\t\t\tid: id,\n\t\t\ttitle: title,\n\t\t\telement: t,\n\t\t\tnav: context.querySelectorAll('.nav-tab-' + id),\n\t\t\topen: function open() {\n\t\t\t\treturn _open(id);\n\t\t\t}\n\t\t});\n\t});\n\n\tfunction get(id) {\n\n\t\tfor (var i = 0; i < tabs.length; i++) {\n\t\t\tif (tabs[i].id === id) {\n\t\t\t\treturn tabs[i];\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tfunction _open(tab, updateState) {\n\n\t\t// make sure we have a tab object\n\t\tif (typeof tab === \"string\") {\n\t\t\ttab = get(tab);\n\t\t}\n\n\t\tif (!tab) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// should we update state?\n\t\tif (updateState == undefined) {\n\t\t\tupdateState = true;\n\t\t}\n\n\t\t// hide all tabs & remove active class\n\t\t$tabs.removeClass('tab-active').css('display', 'none');\n\t\t$tabNavs.removeClass('nav-tab-active');\n\n\t\t// add `nav-tab-active` to this tab\n\t\tArray.prototype.forEach.call(tab.nav, function (nav) {\n\t\t\tnav.className += \" nav-tab-active\";\n\t\t\tnav.blur();\n\t\t});\n\n\t\t// show target tab\n\t\ttab.element.style.display = 'block';\n\t\ttab.element.className += \" tab-active\";\n\n\t\t// create new URL\n\t\tvar url = URL.setParameter(window.location.href, \"tab\", tab.id);\n\n\t\t// update hash\n\t\tif (history.pushState && updateState) {\n\t\t\thistory.pushState(tab.id, '', url);\n\t\t}\n\n\t\t// update document title\n\t\ttitle(tab);\n\n\t\t// update referer field\n\t\trefererField.value = url;\n\n\t\t// if thickbox is open, close it.\n\t\tif (typeof tb_remove === \"function\") {\n\t\t\ttb_remove();\n\t\t}\n\n\t\t// refresh editor after switching tabs\n\t\t// TODO: decouple this! law of demeter etc.\n\t\tif (tab.id === 'fields' && window.mc4wp && window.mc4wp.forms && window.mc4wp.forms.editor) {\n\t\t\tmc4wp.forms.editor.refresh();\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tfunction title(tab) {\n\t\tvar title = document.title.split('-');\n\t\tdocument.title = document.title.replace(title[0], tab.title + \" \");\n\t}\n\n\tfunction switchTab(e) {\n\t\te = e || window.event;\n\n\t\t// get from data attribute\n\t\tvar tabId = this.getAttribute('data-tab');\n\n\t\t// get from classname\n\t\tif (!tabId) {\n\t\t\tvar match = this.className.match(/nav-tab-(\\w+)?/);\n\t\t\tif (match) {\n\t\t\t\ttabId = match[1];\n\t\t\t}\n\t\t}\n\n\t\t// get from href\n\t\tif (!tabId) {\n\t\t\tvar urlParams = URL.parse(this.href);\n\t\t\tif (!urlParams.tab) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttabId = urlParams.tab;\n\t\t}\n\n\t\tvar opened = _open(tabId);\n\n\t\tif (opened) {\n\t\t\te.preventDefault();\n\t\t\te.returnValue = false;\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tfunction init() {\n\n\t\t// check for current tab\n\t\tif (!history.pushState) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar activeTab = $tabs.filter(':visible').get(0);\n\t\tif (!activeTab) {\n\t\t\treturn;\n\t\t}\n\t\tvar tab = get(activeTab.id.substring(4));\n\t\tif (!tab) return;\n\n\t\t// check if tab is in html5 history\n\t\tif (history.replaceState && history.state === null) {\n\t\t\thistory.replaceState(tab.id, '');\n\t\t}\n\n\t\t// update document title\n\t\ttitle(tab);\n\t}\n\n\t$tabNavs.click(switchTab);\n\t$(document.body).on('click', '.tab-link', switchTab);\n\tinit();\n\n\tif (window.addEventListener && history.pushState) {\n\t\twindow.addEventListener('popstate', function (e) {\n\t\t\tif (!e.state) return true;\n\t\t\tvar tabId = e.state;\n\t\t\treturn _open(tabId, false);\n\t\t});\n\t}\n\n\treturn {\n\t\topen: _open,\n\t\tget: get\n\t};\n};\n\nmodule.exports = Tabs;\n\n},{\"./url.js\":6}],6:[function(require,module,exports){\n'use strict';\n\nvar URL = {\n\tparse: function parse(url) {\n\t\tvar query = {};\n\t\tvar a = url.split('&');\n\t\tfor (var i in a) {\n\t\t\tif (!a.hasOwnProperty(i)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvar b = a[i].split('=');\n\t\t\tquery[decodeURIComponent(b[0])] = decodeURIComponent(b[1]);\n\t\t}\n\n\t\treturn query;\n\t},\n\tbuild: function build(data) {\n\t\tvar ret = [];\n\t\tfor (var d in data) {\n\t\t\tret.push(d + \"=\" + encodeURIComponent(data[d]));\n\t\t}return ret.join(\"&\");\n\t},\n\tsetParameter: function setParameter(url, key, value) {\n\t\tvar data = URL.parse(url);\n\t\tdata[key] = value;\n\t\treturn URL.build(data);\n\t}\n};\n\nmodule.exports = URL;\n\n},{}],7:[function(require,module,exports){\n(function (global,setImmediate){\n;(function() {\n\"use strict\"\nfunction Vnode(tag, key, attrs0, children, text, dom) {\n\treturn {tag: tag, key: key, attrs: attrs0, children: children, text: text, dom: dom, domSize: undefined, state: undefined, _state: undefined, events: undefined, instance: undefined, skip: false}\n}\nVnode.normalize = function(node) {\n\tif (Array.isArray(node)) return Vnode(\"[\", undefined, undefined, Vnode.normalizeChildren(node), undefined, undefined)\n\tif (node != null && typeof node !== \"object\") return Vnode(\"#\", undefined, undefined, node === false ? \"\" : node, undefined, undefined)\n\treturn node\n}\nVnode.normalizeChildren = function normalizeChildren(children) {\n\tfor (var i = 0; i < children.length; i++) {\n\t\tchildren[i] = Vnode.normalize(children[i])\n\t}\n\treturn children\n}\nvar selectorParser = /(?:(^|#|\\.)([^#\\.\\[\\]]+))|(\\[(.+?)(?:\\s*=\\s*(\"|'|)((?:\\\\[\"'\\]]|.)*?)\\5)?\\])/g\nvar selectorCache = {}\nvar hasOwn = {}.hasOwnProperty\nfunction isEmpty(object) {\n\tfor (var key in object) if (hasOwn.call(object, key)) return false\n\treturn true\n}\nfunction compileSelector(selector) {\n\tvar match, tag = \"div\", classes = [], attrs = {}\n\twhile (match = selectorParser.exec(selector)) {\n\t\tvar type = match[1], value = match[2]\n\t\tif (type === \"\" && value !== \"\") tag = value\n\t\telse if (type === \"#\") attrs.id = value\n\t\telse if (type === \".\") classes.push(value)\n\t\telse if (match[3][0] === \"[\") {\n\t\t\tvar attrValue = match[6]\n\t\t\tif (attrValue) attrValue = attrValue.replace(/\\\\([\"'])/g, \"$1\").replace(/\\\\\\\\/g, \"\\\\\")\n\t\t\tif (match[4] === \"class\") classes.push(attrValue)\n\t\t\telse attrs[match[4]] = attrValue === \"\" ? attrValue : attrValue || true\n\t\t}\n\t}\n\tif (classes.length > 0) attrs.className = classes.join(\" \")\n\treturn selectorCache[selector] = {tag: tag, attrs: attrs}\n}\nfunction execSelector(state, attrs, children) {\n\tvar hasAttrs = false, childList, text\n\tvar className = attrs.className || attrs.class\n\tif (!isEmpty(state.attrs) && !isEmpty(attrs)) {\n\t\tvar newAttrs = {}\n\t\tfor(var key in attrs) {\n\t\t\tif (hasOwn.call(attrs, key)) {\n\t\t\t\tnewAttrs[key] = attrs[key]\n\t\t\t}\n\t\t}\n\t\tattrs = newAttrs\n\t}\n\tfor (var key in state.attrs) {\n\t\tif (hasOwn.call(state.attrs, key)) {\n\t\t\tattrs[key] = state.attrs[key]\n\t\t}\n\t}\n\tif (className !== undefined) {\n\t\tif (attrs.class !== undefined) {\n\t\t\tattrs.class = undefined\n\t\t\tattrs.className = className\n\t\t}\n\t\tif (state.attrs.className != null) {\n\t\t\tattrs.className = state.attrs.className + \" \" + className\n\t\t}\n\t}\n\tfor (var key in attrs) {\n\t\tif (hasOwn.call(attrs, key) && key !== \"key\") {\n\t\t\thasAttrs = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif (Array.isArray(children) && children.length === 1 && children[0] != null && children[0].tag === \"#\") {\n\t\ttext = children[0].children\n\t} else {\n\t\tchildList = children\n\t}\n\treturn Vnode(state.tag, attrs.key, hasAttrs ? attrs : undefined, childList, text)\n}\nfunction hyperscript(selector) {\n\t// Because sloppy mode sucks\n\tvar attrs = arguments[1], start = 2, children\n\tif (selector == null || typeof selector !== \"string\" && typeof selector !== \"function\" && typeof selector.view !== \"function\") {\n\t\tthrow Error(\"The selector must be either a string or a component.\");\n\t}\n\tif (typeof selector === \"string\") {\n\t\tvar cached = selectorCache[selector] || compileSelector(selector)\n\t}\n\tif (attrs == null) {\n\t\tattrs = {}\n\t} else if (typeof attrs !== \"object\" || attrs.tag != null || Array.isArray(attrs)) {\n\t\tattrs = {}\n\t\tstart = 1\n\t}\n\tif (arguments.length === start + 1) {\n\t\tchildren = arguments[start]\n\t\tif (!Array.isArray(children)) children = [children]\n\t} else {\n\t\tchildren = []\n\t\twhile (start < arguments.length) children.push(arguments[start++])\n\t}\n\tvar normalized = Vnode.normalizeChildren(children)\n\tif (typeof selector === \"string\") {\n\t\treturn execSelector(cached, attrs, normalized)\n\t} else {\n\t\treturn Vnode(selector, attrs.key, attrs, normalized)\n\t}\n}\nhyperscript.trust = function(html) {\n\tif (html == null) html = \"\"\n\treturn Vnode(\"<\", undefined, undefined, html, undefined, undefined)\n}\nhyperscript.fragment = function(attrs1, children) {\n\treturn Vnode(\"[\", attrs1.key, attrs1, Vnode.normalizeChildren(children), undefined, undefined)\n}\nvar m = hyperscript\n/** @constructor */\nvar PromisePolyfill = function(executor) {\n\tif (!(this instanceof PromisePolyfill)) throw new Error(\"Promise must be called with `new`\")\n\tif (typeof executor !== \"function\") throw new TypeError(\"executor must be a function\")\n\tvar self = this, resolvers = [], rejectors = [], resolveCurrent = handler(resolvers, true), rejectCurrent = handler(rejectors, false)\n\tvar instance = self._instance = {resolvers: resolvers, rejectors: rejectors}\n\tvar callAsync = typeof setImmediate === \"function\" ? setImmediate : setTimeout\n\tfunction handler(list, shouldAbsorb) {\n\t\treturn function execute(value) {\n\t\t\tvar then\n\t\t\ttry {\n\t\t\t\tif (shouldAbsorb && value != null && (typeof value === \"object\" || typeof value === \"function\") && typeof (then = value.then) === \"function\") {\n\t\t\t\t\tif (value === self) throw new TypeError(\"Promise can't be resolved w/ itself\")\n\t\t\t\t\texecuteOnce(then.bind(value))\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tcallAsync(function() {\n\t\t\t\t\t\tif (!shouldAbsorb && list.length === 0) console.error(\"Possible unhandled promise rejection:\", value)\n\t\t\t\t\t\tfor (var i = 0; i < list.length; i++) list[i](value)\n\t\t\t\t\t\tresolvers.length = 0, rejectors.length = 0\n\t\t\t\t\t\tinstance.state = shouldAbsorb\n\t\t\t\t\t\tinstance.retry = function() {execute(value)}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\trejectCurrent(e)\n\t\t\t}\n\t\t}\n\t}\n\tfunction executeOnce(then) {\n\t\tvar runs = 0\n\t\tfunction run(fn) {\n\t\t\treturn function(value) {\n\t\t\t\tif (runs++ > 0) return\n\t\t\t\tfn(value)\n\t\t\t}\n\t\t}\n\t\tvar onerror = run(rejectCurrent)\n\t\ttry {then(run(resolveCurrent), onerror)} catch (e) {onerror(e)}\n\t}\n\texecuteOnce(executor)\n}\nPromisePolyfill.prototype.then = function(onFulfilled, onRejection) {\n\tvar self = this, instance = self._instance\n\tfunction handle(callback, list, next, state) {\n\t\tlist.push(function(value) {\n\t\t\tif (typeof callback !== \"function\") next(value)\n\t\t\telse try {resolveNext(callback(value))} catch (e) {if (rejectNext) rejectNext(e)}\n\t\t})\n\t\tif (typeof instance.retry === \"function\" && state === instance.state) instance.retry()\n\t}\n\tvar resolveNext, rejectNext\n\tvar promise = new PromisePolyfill(function(resolve, reject) {resolveNext = resolve, rejectNext = reject})\n\thandle(onFulfilled, instance.resolvers, resolveNext, true), handle(onRejection, instance.rejectors, rejectNext, false)\n\treturn promise\n}\nPromisePolyfill.prototype.catch = function(onRejection) {\n\treturn this.then(null, onRejection)\n}\nPromisePolyfill.resolve = function(value) {\n\tif (value instanceof PromisePolyfill) return value\n\treturn new PromisePolyfill(function(resolve) {resolve(value)})\n}\nPromisePolyfill.reject = function(value) {\n\treturn new PromisePolyfill(function(resolve, reject) {reject(value)})\n}\nPromisePolyfill.all = function(list) {\n\treturn new PromisePolyfill(function(resolve, reject) {\n\t\tvar total = list.length, count = 0, values = []\n\t\tif (list.length === 0) resolve([])\n\t\telse for (var i = 0; i < list.length; i++) {\n\t\t\t(function(i) {\n\t\t\t\tfunction consume(value) {\n\t\t\t\t\tcount++\n\t\t\t\t\tvalues[i] = value\n\t\t\t\t\tif (count === total) resolve(values)\n\t\t\t\t}\n\t\t\t\tif (list[i] != null && (typeof list[i] === \"object\" || typeof list[i] === \"function\") && typeof list[i].then === \"function\") {\n\t\t\t\t\tlist[i].then(consume, reject)\n\t\t\t\t}\n\t\t\t\telse consume(list[i])\n\t\t\t})(i)\n\t\t}\n\t})\n}\nPromisePolyfill.race = function(list) {\n\treturn new PromisePolyfill(function(resolve, reject) {\n\t\tfor (var i = 0; i < list.length; i++) {\n\t\t\tlist[i].then(resolve, reject)\n\t\t}\n\t})\n}\nif (typeof window !== \"undefined\") {\n\tif (typeof window.Promise === \"undefined\") window.Promise = PromisePolyfill\n\tvar PromisePolyfill = window.Promise\n} else if (typeof global !== \"undefined\") {\n\tif (typeof global.Promise === \"undefined\") global.Promise = PromisePolyfill\n\tvar PromisePolyfill = global.Promise\n} else {\n}\nvar buildQueryString = function(object) {\n\tif (Object.prototype.toString.call(object) !== \"[object Object]\") return \"\"\n\tvar args = []\n\tfor (var key0 in object) {\n\t\tdestructure(key0, object[key0])\n\t}\n\treturn args.join(\"&\")\n\tfunction destructure(key0, value) {\n\t\tif (Array.isArray(value)) {\n\t\t\tfor (var i = 0; i < value.length; i++) {\n\t\t\t\tdestructure(key0 + \"[\" + i + \"]\", value[i])\n\t\t\t}\n\t\t}\n\t\telse if (Object.prototype.toString.call(value) === \"[object Object]\") {\n\t\t\tfor (var i in value) {\n\t\t\t\tdestructure(key0 + \"[\" + i + \"]\", value[i])\n\t\t\t}\n\t\t}\n\t\telse args.push(encodeURIComponent(key0) + (value != null && value !== \"\" ? \"=\" + encodeURIComponent(value) : \"\"))\n\t}\n}\nvar FILE_PROTOCOL_REGEX = new RegExp(\"^file://\", \"i\")\nvar _8 = function($window, Promise) {\n\tvar callbackCount = 0\n\tvar oncompletion\n\tfunction setCompletionCallback(callback) {oncompletion = callback}\n\tfunction finalizer() {\n\t\tvar count = 0\n\t\tfunction complete() {if (--count === 0 && typeof oncompletion === \"function\") oncompletion()}\n\t\treturn function finalize(promise0) {\n\t\t\tvar then0 = promise0.then\n\t\t\tpromise0.then = function() {\n\t\t\t\tcount++\n\t\t\t\tvar next = then0.apply(promise0, arguments)\n\t\t\t\tnext.then(complete, function(e) {\n\t\t\t\t\tcomplete()\n\t\t\t\t\tif (count === 0) throw e\n\t\t\t\t})\n\t\t\t\treturn finalize(next)\n\t\t\t}\n\t\t\treturn promise0\n\t\t}\n\t}\n\tfunction normalize(args, extra) {\n\t\tif (typeof args === \"string\") {\n\t\t\tvar url = args\n\t\t\targs = extra || {}\n\t\t\tif (args.url == null) args.url = url\n\t\t}\n\t\treturn args\n\t}\n\tfunction request(args, extra) {\n\t\tvar finalize = finalizer()\n\t\targs = normalize(args, extra)\n\t\tvar promise0 = new Promise(function(resolve, reject) {\n\t\t\tif (args.method == null) args.method = \"GET\"\n\t\t\targs.method = args.method.toUpperCase()\n\t\t\tvar useBody = (args.method === \"GET\" || args.method === \"TRACE\") ? false : (typeof args.useBody === \"boolean\" ? args.useBody : true)\n\t\t\tif (typeof args.serialize !== \"function\") args.serialize = typeof FormData !== \"undefined\" && args.data instanceof FormData ? function(value) {return value} : JSON.stringify\n\t\t\tif (typeof args.deserialize !== \"function\") args.deserialize = deserialize\n\t\t\tif (typeof args.extract !== \"function\") args.extract = extract\n\t\t\targs.url = interpolate(args.url, args.data)\n\t\t\tif (useBody) args.data = args.serialize(args.data)\n\t\t\telse args.url = assemble(args.url, args.data)\n\t\t\tvar xhr = new $window.XMLHttpRequest(),\n\t\t\t\taborted = false,\n\t\t\t\t_abort = xhr.abort\n\t\t\txhr.abort = function abort() {\n\t\t\t\taborted = true\n\t\t\t\t_abort.call(xhr)\n\t\t\t}\n\t\t\txhr.open(args.method, args.url, typeof args.async === \"boolean\" ? args.async : true, typeof args.user === \"string\" ? args.user : undefined, typeof args.password === \"string\" ? args.password : undefined)\n\t\t\tif (args.serialize === JSON.stringify && useBody && !(args.headers && args.headers.hasOwnProperty(\"Content-Type\"))) {\n\t\t\t\txhr.setRequestHeader(\"Content-Type\", \"application/json; charset=utf-8\")\n\t\t\t}\n\t\t\tif (args.deserialize === deserialize && !(args.headers && args.headers.hasOwnProperty(\"Accept\"))) {\n\t\t\t\txhr.setRequestHeader(\"Accept\", \"application/json, text/*\")\n\t\t\t}\n\t\t\tif (args.withCredentials) xhr.withCredentials = args.withCredentials\n\t\t\tfor (var key in args.headers) if ({}.hasOwnProperty.call(args.headers, key)) {\n\t\t\t\txhr.setRequestHeader(key, args.headers[key])\n\t\t\t}\n\t\t\tif (typeof args.config === \"function\") xhr = args.config(xhr, args) || xhr\n\t\t\txhr.onreadystatechange = function() {\n\t\t\t\t// Don't throw errors on xhr.abort().\n\t\t\t\tif(aborted) return\n\t\t\t\tif (xhr.readyState === 4) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tvar response = (args.extract !== extract) ? args.extract(xhr, args) : args.deserialize(args.extract(xhr, args))\n\t\t\t\t\t\tif ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || FILE_PROTOCOL_REGEX.test(args.url)) {\n\t\t\t\t\t\t\tresolve(cast(args.type, response))\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tvar error = new Error(xhr.responseText)\n\t\t\t\t\t\t\tfor (var key in response) error[key] = response[key]\n\t\t\t\t\t\t\treject(error)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcatch (e) {\n\t\t\t\t\t\treject(e)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (useBody && (args.data != null)) xhr.send(args.data)\n\t\t\telse xhr.send()\n\t\t})\n\t\treturn args.background === true ? promise0 : finalize(promise0)\n\t}\n\tfunction jsonp(args, extra) {\n\t\tvar finalize = finalizer()\n\t\targs = normalize(args, extra)\n\t\tvar promise0 = new Promise(function(resolve, reject) {\n\t\t\tvar callbackName = args.callbackName || \"_mithril_\" + Math.round(Math.random() * 1e16) + \"_\" + callbackCount++\n\t\t\tvar script = $window.document.createElement(\"script\")\n\t\t\t$window[callbackName] = function(data) {\n\t\t\t\tscript.parentNode.removeChild(script)\n\t\t\t\tresolve(cast(args.type, data))\n\t\t\t\tdelete $window[callbackName]\n\t\t\t}\n\t\t\tscript.onerror = function() {\n\t\t\t\tscript.parentNode.removeChild(script)\n\t\t\t\treject(new Error(\"JSONP request failed\"))\n\t\t\t\tdelete $window[callbackName]\n\t\t\t}\n\t\t\tif (args.data == null) args.data = {}\n\t\t\targs.url = interpolate(args.url, args.data)\n\t\t\targs.data[args.callbackKey || \"callback\"] = callbackName\n\t\t\tscript.src = assemble(args.url, args.data)\n\t\t\t$window.document.documentElement.appendChild(script)\n\t\t})\n\t\treturn args.background === true? promise0 : finalize(promise0)\n\t}\n\tfunction interpolate(url, data) {\n\t\tif (data == null) return url\n\t\tvar tokens = url.match(/:[^\\/]+/gi) || []\n\t\tfor (var i = 0; i < tokens.length; i++) {\n\t\t\tvar key = tokens[i].slice(1)\n\t\t\tif (data[key] != null) {\n\t\t\t\turl = url.replace(tokens[i], data[key])\n\t\t\t}\n\t\t}\n\t\treturn url\n\t}\n\tfunction assemble(url, data) {\n\t\tvar querystring = buildQueryString(data)\n\t\tif (querystring !== \"\") {\n\t\t\tvar prefix = url.indexOf(\"?\") < 0 ? \"?\" : \"&\"\n\t\t\turl += prefix + querystring\n\t\t}\n\t\treturn url\n\t}\n\tfunction deserialize(data) {\n\t\ttry {return data !== \"\" ? JSON.parse(data) : null}\n\t\tcatch (e) {throw new Error(data)}\n\t}\n\tfunction extract(xhr) {return xhr.responseText}\n\tfunction cast(type0, data) {\n\t\tif (typeof type0 === \"function\") {\n\t\t\tif (Array.isArray(data)) {\n\t\t\t\tfor (var i = 0; i < data.length; i++) {\n\t\t\t\t\tdata[i] = new type0(data[i])\n\t\t\t\t}\n\t\t\t}\n\t\t\telse return new type0(data)\n\t\t}\n\t\treturn data\n\t}\n\treturn {request: request, jsonp: jsonp, setCompletionCallback: setCompletionCallback}\n}\nvar requestService = _8(window, PromisePolyfill)\nvar coreRenderer = function($window) {\n\tvar $doc = $window.document\n\tvar $emptyFragment = $doc.createDocumentFragment()\n\tvar nameSpace = {\n\t\tsvg: \"http://www.w3.org/2000/svg\",\n\t\tmath: \"http://www.w3.org/1998/Math/MathML\"\n\t}\n\tvar onevent\n\tfunction setEventCallback(callback) {return onevent = callback}\n\tfunction getNameSpace(vnode) {\n\t\treturn vnode.attrs && vnode.attrs.xmlns || nameSpace[vnode.tag]\n\t}\n\t//create\n\tfunction createNodes(parent, vnodes, start, end, hooks, nextSibling, ns) {\n\t\tfor (var i = start; i < end; i++) {\n\t\t\tvar vnode = vnodes[i]\n\t\t\tif (vnode != null) {\n\t\t\t\tcreateNode(parent, vnode, hooks, ns, nextSibling)\n\t\t\t}\n\t\t}\n\t}\n\tfunction createNode(parent, vnode, hooks, ns, nextSibling) {\n\t\tvar tag = vnode.tag\n\t\tif (typeof tag === \"string\") {\n\t\t\tvnode.state = {}\n\t\t\tif (vnode.attrs != null) initLifecycle(vnode.attrs, vnode, hooks)\n\t\t\tswitch (tag) {\n\t\t\t\tcase \"#\": return createText(parent, vnode, nextSibling)\n\t\t\t\tcase \"<\": return createHTML(parent, vnode, nextSibling)\n\t\t\t\tcase \"[\": return createFragment(parent, vnode, hooks, ns, nextSibling)\n\t\t\t\tdefault: return createElement(parent, vnode, hooks, ns, nextSibling)\n\t\t\t}\n\t\t}\n\t\telse return createComponent(parent, vnode, hooks, ns, nextSibling)\n\t}\n\tfunction createText(parent, vnode, nextSibling) {\n\t\tvnode.dom = $doc.createTextNode(vnode.children)\n\t\tinsertNode(parent, vnode.dom, nextSibling)\n\t\treturn vnode.dom\n\t}\n\tfunction createHTML(parent, vnode, nextSibling) {\n\t\tvar match1 = vnode.children.match(/^\\s*?<(\\w+)/im) || []\n\t\tvar parent1 = {caption: \"table\", thead: \"table\", tbody: \"table\", tfoot: \"table\", tr: \"tbody\", th: \"tr\", td: \"tr\", colgroup: \"table\", col: \"colgroup\"}[match1[1]] || \"div\"\n\t\tvar temp = $doc.createElement(parent1)\n\t\ttemp.innerHTML = vnode.children\n\t\tvnode.dom = temp.firstChild\n\t\tvnode.domSize = temp.childNodes.length\n\t\tvar fragment = $doc.createDocumentFragment()\n\t\tvar child\n\t\twhile (child = temp.firstChild) {\n\t\t\tfragment.appendChild(child)\n\t\t}\n\t\tinsertNode(parent, fragment, nextSibling)\n\t\treturn fragment\n\t}\n\tfunction createFragment(parent, vnode, hooks, ns, nextSibling) {\n\t\tvar fragment = $doc.createDocumentFragment()\n\t\tif (vnode.children != null) {\n\t\t\tvar children = vnode.children\n\t\t\tcreateNodes(fragment, children, 0, children.length, hooks, null, ns)\n\t\t}\n\t\tvnode.dom = fragment.firstChild\n\t\tvnode.domSize = fragment.childNodes.length\n\t\tinsertNode(parent, fragment, nextSibling)\n\t\treturn fragment\n\t}\n\tfunction createElement(parent, vnode, hooks, ns, nextSibling) {\n\t\tvar tag = vnode.tag\n\t\tvar attrs2 = vnode.attrs\n\t\tvar is = attrs2 && attrs2.is\n\t\tns = getNameSpace(vnode) || ns\n\t\tvar element = ns ?\n\t\t\tis ? $doc.createElementNS(ns, tag, {is: is}) : $doc.createElementNS(ns, tag) :\n\t\t\tis ? $doc.createElement(tag, {is: is}) : $doc.createElement(tag)\n\t\tvnode.dom = element\n\t\tif (attrs2 != null) {\n\t\t\tsetAttrs(vnode, attrs2, ns)\n\t\t}\n\t\tinsertNode(parent, element, nextSibling)\n\t\tif (vnode.attrs != null && vnode.attrs.contenteditable != null) {\n\t\t\tsetContentEditable(vnode)\n\t\t}\n\t\telse {\n\t\t\tif (vnode.text != null) {\n\t\t\t\tif (vnode.text !== \"\") element.textContent = vnode.text\n\t\t\t\telse vnode.children = [Vnode(\"#\", undefined, undefined, vnode.text, undefined, undefined)]\n\t\t\t}\n\t\t\tif (vnode.children != null) {\n\t\t\t\tvar children = vnode.children\n\t\t\t\tcreateNodes(element, children, 0, children.length, hooks, null, ns)\n\t\t\t\tsetLateAttrs(vnode)\n\t\t\t}\n\t\t}\n\t\treturn element\n\t}\n\tfunction initComponent(vnode, hooks) {\n\t\tvar sentinel\n\t\tif (typeof vnode.tag.view === \"function\") {\n\t\t\tvnode.state = Object.create(vnode.tag)\n\t\t\tsentinel = vnode.state.view\n\t\t\tif (sentinel.$$reentrantLock$$ != null) return $emptyFragment\n\t\t\tsentinel.$$reentrantLock$$ = true\n\t\t} else {\n\t\t\tvnode.state = void 0\n\t\t\tsentinel = vnode.tag\n\t\t\tif (sentinel.$$reentrantLock$$ != null) return $emptyFragment\n\t\t\tsentinel.$$reentrantLock$$ = true\n\t\t\tvnode.state = (vnode.tag.prototype != null && typeof vnode.tag.prototype.view === \"function\") ? new vnode.tag(vnode) : vnode.tag(vnode)\n\t\t}\n\t\tvnode._state = vnode.state\n\t\tif (vnode.attrs != null) initLifecycle(vnode.attrs, vnode, hooks)\n\t\tinitLifecycle(vnode._state, vnode, hooks)\n\t\tvnode.instance = Vnode.normalize(vnode._state.view.call(vnode.state, vnode))\n\t\tif (vnode.instance === vnode) throw Error(\"A view cannot return the vnode it received as argument\")\n\t\tsentinel.$$reentrantLock$$ = null\n\t}\n\tfunction createComponent(parent, vnode, hooks, ns, nextSibling) {\n\t\tinitComponent(vnode, hooks)\n\t\tif (vnode.instance != null) {\n\t\t\tvar element = createNode(parent, vnode.instance, hooks, ns, nextSibling)\n\t\t\tvnode.dom = vnode.instance.dom\n\t\t\tvnode.domSize = vnode.dom != null ? vnode.instance.domSize : 0\n\t\t\tinsertNode(parent, element, nextSibling)\n\t\t\treturn element\n\t\t}\n\t\telse {\n\t\t\tvnode.domSize = 0\n\t\t\treturn $emptyFragment\n\t\t}\n\t}\n\t//update\n\tfunction updateNodes(parent, old, vnodes, recycling, hooks, nextSibling, ns) {\n\t\tif (old === vnodes || old == null && vnodes == null) return\n\t\telse if (old == null) createNodes(parent, vnodes, 0, vnodes.length, hooks, nextSibling, ns)\n\t\telse if (vnodes == null) removeNodes(old, 0, old.length, vnodes)\n\t\telse {\n\t\t\tif (old.length === vnodes.length) {\n\t\t\t\tvar isUnkeyed = false\n\t\t\t\tfor (var i = 0; i < vnodes.length; i++) {\n\t\t\t\t\tif (vnodes[i] != null && old[i] != null) {\n\t\t\t\t\t\tisUnkeyed = vnodes[i].key == null && old[i].key == null\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (isUnkeyed) {\n\t\t\t\t\tfor (var i = 0; i < old.length; i++) {\n\t\t\t\t\t\tif (old[i] === vnodes[i]) continue\n\t\t\t\t\t\telse if (old[i] == null && vnodes[i] != null) createNode(parent, vnodes[i], hooks, ns, getNextSibling(old, i + 1, nextSibling))\n\t\t\t\t\t\telse if (vnodes[i] == null) removeNodes(old, i, i + 1, vnodes)\n\t\t\t\t\t\telse updateNode(parent, old[i], vnodes[i], hooks, getNextSibling(old, i + 1, nextSibling), recycling, ns)\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\trecycling = recycling || isRecyclable(old, vnodes)\n\t\t\tif (recycling) {\n\t\t\t\tvar pool = old.pool\n\t\t\t\told = old.concat(old.pool)\n\t\t\t}\n\t\t\tvar oldStart = 0, start = 0, oldEnd = old.length - 1, end = vnodes.length - 1, map\n\t\t\twhile (oldEnd >= oldStart && end >= start) {\n\t\t\t\tvar o = old[oldStart], v = vnodes[start]\n\t\t\t\tif (o === v && !recycling) oldStart++, start++\n\t\t\t\telse if (o == null) oldStart++\n\t\t\t\telse if (v == null) start++\n\t\t\t\telse if (o.key === v.key) {\n\t\t\t\t\tvar shouldRecycle = (pool != null && oldStart >= old.length - pool.length) || ((pool == null) && recycling)\n\t\t\t\t\toldStart++, start++\n\t\t\t\t\tupdateNode(parent, o, v, hooks, getNextSibling(old, oldStart, nextSibling), shouldRecycle, ns)\n\t\t\t\t\tif (recycling && o.tag === v.tag) insertNode(parent, toFragment(o), nextSibling)\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tvar o = old[oldEnd]\n\t\t\t\t\tif (o === v && !recycling) oldEnd--, start++\n\t\t\t\t\telse if (o == null) oldEnd--\n\t\t\t\t\telse if (v == null) start++\n\t\t\t\t\telse if (o.key === v.key) {\n\t\t\t\t\t\tvar shouldRecycle = (pool != null && oldEnd >= old.length - pool.length) || ((pool == null) && recycling)\n\t\t\t\t\t\tupdateNode(parent, o, v, hooks, getNextSibling(old, oldEnd + 1, nextSibling), shouldRecycle, ns)\n\t\t\t\t\t\tif (recycling || start < end) insertNode(parent, toFragment(o), getNextSibling(old, oldStart, nextSibling))\n\t\t\t\t\t\toldEnd--, start++\n\t\t\t\t\t}\n\t\t\t\t\telse break\n\t\t\t\t}\n\t\t\t}\n\t\t\twhile (oldEnd >= oldStart && end >= start) {\n\t\t\t\tvar o = old[oldEnd], v = vnodes[end]\n\t\t\t\tif (o === v && !recycling) oldEnd--, end--\n\t\t\t\telse if (o == null) oldEnd--\n\t\t\t\telse if (v == null) end--\n\t\t\t\telse if (o.key === v.key) {\n\t\t\t\t\tvar shouldRecycle = (pool != null && oldEnd >= old.length - pool.length) || ((pool == null) && recycling)\n\t\t\t\t\tupdateNode(parent, o, v, hooks, getNextSibling(old, oldEnd + 1, nextSibling), shouldRecycle, ns)\n\t\t\t\t\tif (recycling && o.tag === v.tag) insertNode(parent, toFragment(o), nextSibling)\n\t\t\t\t\tif (o.dom != null) nextSibling = o.dom\n\t\t\t\t\toldEnd--, end--\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tif (!map) map = getKeyMap(old, oldEnd)\n\t\t\t\t\tif (v != null) {\n\t\t\t\t\t\tvar oldIndex = map[v.key]\n\t\t\t\t\t\tif (oldIndex != null) {\n\t\t\t\t\t\t\tvar movable = old[oldIndex]\n\t\t\t\t\t\t\tvar shouldRecycle = (pool != null && oldIndex >= old.length - pool.length) || ((pool == null) && recycling)\n\t\t\t\t\t\t\tupdateNode(parent, movable, v, hooks, getNextSibling(old, oldEnd + 1, nextSibling), recycling, ns)\n\t\t\t\t\t\t\tinsertNode(parent, toFragment(movable), nextSibling)\n\t\t\t\t\t\t\told[oldIndex].skip = true\n\t\t\t\t\t\t\tif (movable.dom != null) nextSibling = movable.dom\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tvar dom = createNode(parent, v, hooks, ns, nextSibling)\n\t\t\t\t\t\t\tnextSibling = dom\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tend--\n\t\t\t\t}\n\t\t\t\tif (end < start) break\n\t\t\t}\n\t\t\tcreateNodes(parent, vnodes, start, end + 1, hooks, nextSibling, ns)\n\t\t\tremoveNodes(old, oldStart, oldEnd + 1, vnodes)\n\t\t}\n\t}\n\tfunction updateNode(parent, old, vnode, hooks, nextSibling, recycling, ns) {\n\t\tvar oldTag = old.tag, tag = vnode.tag\n\t\tif (oldTag === tag) {\n\t\t\tvnode.state = old.state\n\t\t\tvnode._state = old._state\n\t\t\tvnode.events = old.events\n\t\t\tif (!recycling && shouldNotUpdate(vnode, old)) return\n\t\t\tif (typeof oldTag === \"string\") {\n\t\t\t\tif (vnode.attrs != null) {\n\t\t\t\t\tif (recycling) {\n\t\t\t\t\t\tvnode.state = {}\n\t\t\t\t\t\tinitLifecycle(vnode.attrs, vnode, hooks)\n\t\t\t\t\t}\n\t\t\t\t\telse updateLifecycle(vnode.attrs, vnode, hooks)\n\t\t\t\t}\n\t\t\t\tswitch (oldTag) {\n\t\t\t\t\tcase \"#\": updateText(old, vnode); break\n\t\t\t\t\tcase \"<\": updateHTML(parent, old, vnode, nextSibling); break\n\t\t\t\t\tcase \"[\": updateFragment(parent, old, vnode, recycling, hooks, nextSibling, ns); break\n\t\t\t\t\tdefault: updateElement(old, vnode, recycling, hooks, ns)\n\t\t\t\t}\n\t\t\t}\n\t\t\telse updateComponent(parent, old, vnode, hooks, nextSibling, recycling, ns)\n\t\t}\n\t\telse {\n\t\t\tremoveNode(old, null)\n\t\t\tcreateNode(parent, vnode, hooks, ns, nextSibling)\n\t\t}\n\t}\n\tfunction updateText(old, vnode) {\n\t\tif (old.children.toString() !== vnode.children.toString()) {\n\t\t\told.dom.nodeValue = vnode.children\n\t\t}\n\t\tvnode.dom = old.dom\n\t}\n\tfunction updateHTML(parent, old, vnode, nextSibling) {\n\t\tif (old.children !== vnode.children) {\n\t\t\ttoFragment(old)\n\t\t\tcreateHTML(parent, vnode, nextSibling)\n\t\t}\n\t\telse vnode.dom = old.dom, vnode.domSize = old.domSize\n\t}\n\tfunction updateFragment(parent, old, vnode, recycling, hooks, nextSibling, ns) {\n\t\tupdateNodes(parent, old.children, vnode.children, recycling, hooks, nextSibling, ns)\n\t\tvar domSize = 0, children = vnode.children\n\t\tvnode.dom = null\n\t\tif (children != null) {\n\t\t\tfor (var i = 0; i < children.length; i++) {\n\t\t\t\tvar child = children[i]\n\t\t\t\tif (child != null && child.dom != null) {\n\t\t\t\t\tif (vnode.dom == null) vnode.dom = child.dom\n\t\t\t\t\tdomSize += child.domSize || 1\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (domSize !== 1) vnode.domSize = domSize\n\t\t}\n\t}\n\tfunction updateElement(old, vnode, recycling, hooks, ns) {\n\t\tvar element = vnode.dom = old.dom\n\t\tns = getNameSpace(vnode) || ns\n\t\tif (vnode.tag === \"textarea\") {\n\t\t\tif (vnode.attrs == null) vnode.attrs = {}\n\t\t\tif (vnode.text != null) {\n\t\t\t\tvnode.attrs.value = vnode.text //FIXME handle0 multiple children\n\t\t\t\tvnode.text = undefined\n\t\t\t}\n\t\t}\n\t\tupdateAttrs(vnode, old.attrs, vnode.attrs, ns)\n\t\tif (vnode.attrs != null && vnode.attrs.contenteditable != null) {\n\t\t\tsetContentEditable(vnode)\n\t\t}\n\t\telse if (old.text != null && vnode.text != null && vnode.text !== \"\") {\n\t\t\tif (old.text.toString() !== vnode.text.toString()) old.dom.firstChild.nodeValue = vnode.text\n\t\t}\n\t\telse {\n\t\t\tif (old.text != null) old.children = [Vnode(\"#\", undefined, undefined, old.text, undefined, old.dom.firstChild)]\n\t\t\tif (vnode.text != null) vnode.children = [Vnode(\"#\", undefined, undefined, vnode.text, undefined, undefined)]\n\t\t\tupdateNodes(element, old.children, vnode.children, recycling, hooks, null, ns)\n\t\t}\n\t}\n\tfunction updateComponent(parent, old, vnode, hooks, nextSibling, recycling, ns) {\n\t\tif (recycling) {\n\t\t\tinitComponent(vnode, hooks)\n\t\t} else {\n\t\t\tvnode.instance = Vnode.normalize(vnode._state.view.call(vnode.state, vnode))\n\t\t\tif (vnode.instance === vnode) throw Error(\"A view cannot return the vnode it received as argument\")\n\t\t\tif (vnode.attrs != null) updateLifecycle(vnode.attrs, vnode, hooks)\n\t\t\tupdateLifecycle(vnode._state, vnode, hooks)\n\t\t}\n\t\tif (vnode.instance != null) {\n\t\t\tif (old.instance == null) createNode(parent, vnode.instance, hooks, ns, nextSibling)\n\t\t\telse updateNode(parent, old.instance, vnode.instance, hooks, nextSibling, recycling, ns)\n\t\t\tvnode.dom = vnode.instance.dom\n\t\t\tvnode.domSize = vnode.instance.domSize\n\t\t}\n\t\telse if (old.instance != null) {\n\t\t\tremoveNode(old.instance, null)\n\t\t\tvnode.dom = undefined\n\t\t\tvnode.domSize = 0\n\t\t}\n\t\telse {\n\t\t\tvnode.dom = old.dom\n\t\t\tvnode.domSize = old.domSize\n\t\t}\n\t}\n\tfunction isRecyclable(old, vnodes) {\n\t\tif (old.pool != null && Math.abs(old.pool.length - vnodes.length) <= Math.abs(old.length - vnodes.length)) {\n\t\t\tvar oldChildrenLength = old[0] && old[0].children && old[0].children.length || 0\n\t\t\tvar poolChildrenLength = old.pool[0] && old.pool[0].children && old.pool[0].children.length || 0\n\t\t\tvar vnodesChildrenLength = vnodes[0] && vnodes[0].children && vnodes[0].children.length || 0\n\t\t\tif (Math.abs(poolChildrenLength - vnodesChildrenLength) <= Math.abs(oldChildrenLength - vnodesChildrenLength)) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n\tfunction getKeyMap(vnodes, end) {\n\t\tvar map = {}, i = 0\n\t\tfor (var i = 0; i < end; i++) {\n\t\t\tvar vnode = vnodes[i]\n\t\t\tif (vnode != null) {\n\t\t\t\tvar key2 = vnode.key\n\t\t\t\tif (key2 != null) map[key2] = i\n\t\t\t}\n\t\t}\n\t\treturn map\n\t}\n\tfunction toFragment(vnode) {\n\t\tvar count0 = vnode.domSize\n\t\tif (count0 != null || vnode.dom == null) {\n\t\t\tvar fragment = $doc.createDocumentFragment()\n\t\t\tif (count0 > 0) {\n\t\t\t\tvar dom = vnode.dom\n\t\t\t\twhile (--count0) fragment.appendChild(dom.nextSibling)\n\t\t\t\tfragment.insertBefore(dom, fragment.firstChild)\n\t\t\t}\n\t\t\treturn fragment\n\t\t}\n\t\telse return vnode.dom\n\t}\n\tfunction getNextSibling(vnodes, i, nextSibling) {\n\t\tfor (; i < vnodes.length; i++) {\n\t\t\tif (vnodes[i] != null && vnodes[i].dom != null) return vnodes[i].dom\n\t\t}\n\t\treturn nextSibling\n\t}\n\tfunction insertNode(parent, dom, nextSibling) {\n\t\tif (nextSibling && nextSibling.parentNode) parent.insertBefore(dom, nextSibling)\n\t\telse parent.appendChild(dom)\n\t}\n\tfunction setContentEditable(vnode) {\n\t\tvar children = vnode.children\n\t\tif (children != null && children.length === 1 && children[0].tag === \"<\") {\n\t\t\tvar content = children[0].children\n\t\t\tif (vnode.dom.innerHTML !== content) vnode.dom.innerHTML = content\n\t\t}\n\t\telse if (vnode.text != null || children != null && children.length !== 0) throw new Error(\"Child node of a contenteditable must be trusted\")\n\t}\n\t//remove\n\tfunction removeNodes(vnodes, start, end, context) {\n\t\tfor (var i = start; i < end; i++) {\n\t\t\tvar vnode = vnodes[i]\n\t\t\tif (vnode != null) {\n\t\t\t\tif (vnode.skip) vnode.skip = false\n\t\t\t\telse removeNode(vnode, context)\n\t\t\t}\n\t\t}\n\t}\n\tfunction removeNode(vnode, context) {\n\t\tvar expected = 1, called = 0\n\t\tif (vnode.attrs && typeof vnode.attrs.onbeforeremove === \"function\") {\n\t\t\tvar result = vnode.attrs.onbeforeremove.call(vnode.state, vnode)\n\t\t\tif (result != null && typeof result.then === \"function\") {\n\t\t\t\texpected++\n\t\t\t\tresult.then(continuation, continuation)\n\t\t\t}\n\t\t}\n\t\tif (typeof vnode.tag !== \"string\" && typeof vnode._state.onbeforeremove === \"function\") {\n\t\t\tvar result = vnode._state.onbeforeremove.call(vnode.state, vnode)\n\t\t\tif (result != null && typeof result.then === \"function\") {\n\t\t\t\texpected++\n\t\t\t\tresult.then(continuation, continuation)\n\t\t\t}\n\t\t}\n\t\tcontinuation()\n\t\tfunction continuation() {\n\t\t\tif (++called === expected) {\n\t\t\t\tonremove(vnode)\n\t\t\t\tif (vnode.dom) {\n\t\t\t\t\tvar count0 = vnode.domSize || 1\n\t\t\t\t\tif (count0 > 1) {\n\t\t\t\t\t\tvar dom = vnode.dom\n\t\t\t\t\t\twhile (--count0) {\n\t\t\t\t\t\t\tremoveNodeFromDOM(dom.nextSibling)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tremoveNodeFromDOM(vnode.dom)\n\t\t\t\t\tif (context != null && vnode.domSize == null && !hasIntegrationMethods(vnode.attrs) && typeof vnode.tag === \"string\") { //TODO test custom elements\n\t\t\t\t\t\tif (!context.pool) context.pool = [vnode]\n\t\t\t\t\t\telse context.pool.push(vnode)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tfunction removeNodeFromDOM(node) {\n\t\tvar parent = node.parentNode\n\t\tif (parent != null) parent.removeChild(node)\n\t}\n\tfunction onremove(vnode) {\n\t\tif (vnode.attrs && typeof vnode.attrs.onremove === \"function\") vnode.attrs.onremove.call(vnode.state, vnode)\n\t\tif (typeof vnode.tag !== \"string\") {\n\t\t\tif (typeof vnode._state.onremove === \"function\") vnode._state.onremove.call(vnode.state, vnode)\n\t\t\tif (vnode.instance != null) onremove(vnode.instance)\n\t\t} else {\n\t\t\tvar children = vnode.children\n\t\t\tif (Array.isArray(children)) {\n\t\t\t\tfor (var i = 0; i < children.length; i++) {\n\t\t\t\t\tvar child = children[i]\n\t\t\t\t\tif (child != null) onremove(child)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t//attrs2\n\tfunction setAttrs(vnode, attrs2, ns) {\n\t\tfor (var key2 in attrs2) {\n\t\t\tsetAttr(vnode, key2, null, attrs2[key2], ns)\n\t\t}\n\t}\n\tfunction setAttr(vnode, key2, old, value, ns) {\n\t\tvar element = vnode.dom\n\t\tif (key2 === \"key\" || key2 === \"is\" || (old === value && !isFormAttribute(vnode, key2)) && typeof value !== \"object\" || typeof value === \"undefined\" || isLifecycleMethod(key2)) return\n\t\tvar nsLastIndex = key2.indexOf(\":\")\n\t\tif (nsLastIndex > -1 && key2.substr(0, nsLastIndex) === \"xlink\") {\n\t\t\telement.setAttributeNS(\"http://www.w3.org/1999/xlink\", key2.slice(nsLastIndex + 1), value)\n\t\t}\n\t\telse if (key2[0] === \"o\" && key2[1] === \"n\" && typeof value === \"function\") updateEvent(vnode, key2, value)\n\t\telse if (key2 === \"style\") updateStyle(element, old, value)\n\t\telse if (key2 in element && !isAttribute(key2) && ns === undefined && !isCustomElement(vnode)) {\n\t\t\tif (key2 === \"value\") {\n\t\t\t\tvar normalized0 = \"\" + value // eslint-disable-line no-implicit-coercion\n\t\t\t\t//setting input[value] to same value by typing on focused element moves cursor to end in Chrome\n\t\t\t\tif ((vnode.tag === \"input\" || vnode.tag === \"textarea\") && vnode.dom.value === normalized0 && vnode.dom === $doc.activeElement) return\n\t\t\t\t//setting select[value] to same value while having select open blinks select dropdown in Chrome\n\t\t\t\tif (vnode.tag === \"select\") {\n\t\t\t\t\tif (value === null) {\n\t\t\t\t\t\tif (vnode.dom.selectedIndex === -1 && vnode.dom === $doc.activeElement) return\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (old !== null && vnode.dom.value === normalized0 && vnode.dom === $doc.activeElement) return\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t//setting option[value] to same value while having select open blinks select dropdown in Chrome\n\t\t\t\tif (vnode.tag === \"option\" && old != null && vnode.dom.value === normalized0) return\n\t\t\t}\n\t\t\t// If you assign an input type1 that is not supported by IE 11 with an assignment expression, an error0 will occur.\n\t\t\tif (vnode.tag === \"input\" && key2 === \"type\") {\n\t\t\t\telement.setAttribute(key2, value)\n\t\t\t\treturn\n\t\t\t}\n\t\t\telement[key2] = value\n\t\t}\n\t\telse {\n\t\t\tif (typeof value === \"boolean\") {\n\t\t\t\tif (value) element.setAttribute(key2, \"\")\n\t\t\t\telse element.removeAttribute(key2)\n\t\t\t}\n\t\t\telse element.setAttribute(key2 === \"className\" ? \"class\" : key2, value)\n\t\t}\n\t}\n\tfunction setLateAttrs(vnode) {\n\t\tvar attrs2 = vnode.attrs\n\t\tif (vnode.tag === \"select\" && attrs2 != null) {\n\t\t\tif (\"value\" in attrs2) setAttr(vnode, \"value\", null, attrs2.value, undefined)\n\t\t\tif (\"selectedIndex\" in attrs2) setAttr(vnode, \"selectedIndex\", null, attrs2.selectedIndex, undefined)\n\t\t}\n\t}\n\tfunction updateAttrs(vnode, old, attrs2, ns) {\n\t\tif (attrs2 != null) {\n\t\t\tfor (var key2 in attrs2) {\n\t\t\t\tsetAttr(vnode, key2, old && old[key2], attrs2[key2], ns)\n\t\t\t}\n\t\t}\n\t\tif (old != null) {\n\t\t\tfor (var key2 in old) {\n\t\t\t\tif (attrs2 == null || !(key2 in attrs2)) {\n\t\t\t\t\tif (key2 === \"className\") key2 = \"class\"\n\t\t\t\t\tif (key2[0] === \"o\" && key2[1] === \"n\" && !isLifecycleMethod(key2)) updateEvent(vnode, key2, undefined)\n\t\t\t\t\telse if (key2 !== \"key\") vnode.dom.removeAttribute(key2)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tfunction isFormAttribute(vnode, attr) {\n\t\treturn attr === \"value\" || attr === \"checked\" || attr === \"selectedIndex\" || attr === \"selected\" && vnode.dom === $doc.activeElement\n\t}\n\tfunction isLifecycleMethod(attr) {\n\t\treturn attr === \"oninit\" || attr === \"oncreate\" || attr === \"onupdate\" || attr === \"onremove\" || attr === \"onbeforeremove\" || attr === \"onbeforeupdate\"\n\t}\n\tfunction isAttribute(attr) {\n\t\treturn attr === \"href\" || attr === \"list\" || attr === \"form\" || attr === \"width\" || attr === \"height\"// || attr === \"type\"\n\t}\n\tfunction isCustomElement(vnode){\n\t\treturn vnode.attrs.is || vnode.tag.indexOf(\"-\") > -1\n\t}\n\tfunction hasIntegrationMethods(source) {\n\t\treturn source != null && (source.oncreate || source.onupdate || source.onbeforeremove || source.onremove)\n\t}\n\t//style\n\tfunction updateStyle(element, old, style) {\n\t\tif (old === style) element.style.cssText = \"\", old = null\n\t\tif (style == null) element.style.cssText = \"\"\n\t\telse if (typeof style === \"string\") element.style.cssText = style\n\t\telse {\n\t\t\tif (typeof old === \"string\") element.style.cssText = \"\"\n\t\t\tfor (var key2 in style) {\n\t\t\t\telement.style[key2] = style[key2]\n\t\t\t}\n\t\t\tif (old != null && typeof old !== \"string\") {\n\t\t\t\tfor (var key2 in old) {\n\t\t\t\t\tif (!(key2 in style)) element.style[key2] = \"\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t//event\n\tfunction updateEvent(vnode, key2, value) {\n\t\tvar element = vnode.dom\n\t\tvar callback = typeof onevent !== \"function\" ? value : function(e) {\n\t\t\tvar result = value.call(element, e)\n\t\t\tonevent.call(element, e)\n\t\t\treturn result\n\t\t}\n\t\tif (key2 in element) element[key2] = typeof value === \"function\" ? callback : null\n\t\telse {\n\t\t\tvar eventName = key2.slice(2)\n\t\t\tif (vnode.events === undefined) vnode.events = {}\n\t\t\tif (vnode.events[key2] === callback) return\n\t\t\tif (vnode.events[key2] != null) element.removeEventListener(eventName, vnode.events[key2], false)\n\t\t\tif (typeof value === \"function\") {\n\t\t\t\tvnode.events[key2] = callback\n\t\t\t\telement.addEventListener(eventName, vnode.events[key2], false)\n\t\t\t}\n\t\t}\n\t}\n\t//lifecycle\n\tfunction initLifecycle(source, vnode, hooks) {\n\t\tif (typeof source.oninit === \"function\") source.oninit.call(vnode.state, vnode)\n\t\tif (typeof source.oncreate === \"function\") hooks.push(source.oncreate.bind(vnode.state, vnode))\n\t}\n\tfunction updateLifecycle(source, vnode, hooks) {\n\t\tif (typeof source.onupdate === \"function\") hooks.push(source.onupdate.bind(vnode.state, vnode))\n\t}\n\tfunction shouldNotUpdate(vnode, old) {\n\t\tvar forceVnodeUpdate, forceComponentUpdate\n\t\tif (vnode.attrs != null && typeof vnode.attrs.onbeforeupdate === \"function\") forceVnodeUpdate = vnode.attrs.onbeforeupdate.call(vnode.state, vnode, old)\n\t\tif (typeof vnode.tag !== \"string\" && typeof vnode._state.onbeforeupdate === \"function\") forceComponentUpdate = vnode._state.onbeforeupdate.call(vnode.state, vnode, old)\n\t\tif (!(forceVnodeUpdate === undefined && forceComponentUpdate === undefined) && !forceVnodeUpdate && !forceComponentUpdate) {\n\t\t\tvnode.dom = old.dom\n\t\t\tvnode.domSize = old.domSize\n\t\t\tvnode.instance = old.instance\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n\tfunction render(dom, vnodes) {\n\t\tif (!dom) throw new Error(\"Ensure the DOM element being passed to m.route/m.mount/m.render is not undefined.\")\n\t\tvar hooks = []\n\t\tvar active = $doc.activeElement\n\t\tvar namespace = dom.namespaceURI\n\t\t// First time0 rendering into a node clears it out\n\t\tif (dom.vnodes == null) dom.textContent = \"\"\n\t\tif (!Array.isArray(vnodes)) vnodes = [vnodes]\n\t\tupdateNodes(dom, dom.vnodes, Vnode.normalizeChildren(vnodes), false, hooks, null, namespace === \"http://www.w3.org/1999/xhtml\" ? undefined : namespace)\n\t\tdom.vnodes = vnodes\n\t\t// document.activeElement can return null in IE https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement\n\t\tif (active != null && $doc.activeElement !== active) active.focus()\n\t\tfor (var i = 0; i < hooks.length; i++) hooks[i]()\n\t}\n\treturn {render: render, setEventCallback: setEventCallback}\n}\nfunction throttle(callback) {\n\t//60fps translates to 16.6ms, round it down since setTimeout requires int\n\tvar time = 16\n\tvar last = 0, pending = null\n\tvar timeout = typeof requestAnimationFrame === \"function\" ? requestAnimationFrame : setTimeout\n\treturn function() {\n\t\tvar now = Date.now()\n\t\tif (last === 0 || now - last >= time) {\n\t\t\tlast = now\n\t\t\tcallback()\n\t\t}\n\t\telse if (pending === null) {\n\t\t\tpending = timeout(function() {\n\t\t\t\tpending = null\n\t\t\t\tcallback()\n\t\t\t\tlast = Date.now()\n\t\t\t}, time - (now - last))\n\t\t}\n\t}\n}\nvar _11 = function($window) {\n\tvar renderService = coreRenderer($window)\n\trenderService.setEventCallback(function(e) {\n\t\tif (e.redraw === false) e.redraw = undefined\n\t\telse redraw()\n\t})\n\tvar callbacks = []\n\tfunction subscribe(key1, callback) {\n\t\tunsubscribe(key1)\n\t\tcallbacks.push(key1, throttle(callback))\n\t}\n\tfunction unsubscribe(key1) {\n\t\tvar index = callbacks.indexOf(key1)\n\t\tif (index > -1) callbacks.splice(index, 2)\n\t}\n\tfunction redraw() {\n\t\tfor (var i = 1; i < callbacks.length; i += 2) {\n\t\t\tcallbacks[i]()\n\t\t}\n\t}\n\treturn {subscribe: subscribe, unsubscribe: unsubscribe, redraw: redraw, render: renderService.render}\n}\nvar redrawService = _11(window)\nrequestService.setCompletionCallback(redrawService.redraw)\nvar _16 = function(redrawService0) {\n\treturn function(root, component) {\n\t\tif (component === null) {\n\t\t\tredrawService0.render(root, [])\n\t\t\tredrawService0.unsubscribe(root)\n\t\t\treturn\n\t\t}\n\t\t\n\t\tif (component.view == null && typeof component !== \"function\") throw new Error(\"m.mount(element, component) expects a component, not a vnode\")\n\t\t\n\t\tvar run0 = function() {\n\t\t\tredrawService0.render(root, Vnode(component))\n\t\t}\n\t\tredrawService0.subscribe(root, run0)\n\t\tredrawService0.redraw()\n\t}\n}\nm.mount = _16(redrawService)\nvar Promise = PromisePolyfill\nvar parseQueryString = function(string) {\n\tif (string === \"\" || string == null) return {}\n\tif (string.charAt(0) === \"?\") string = string.slice(1)\n\tvar entries = string.split(\"&\"), data0 = {}, counters = {}\n\tfor (var i = 0; i < entries.length; i++) {\n\t\tvar entry = entries[i].split(\"=\")\n\t\tvar key5 = decodeURIComponent(entry[0])\n\t\tvar value = entry.length === 2 ? decodeURIComponent(entry[1]) : \"\"\n\t\tif (value === \"true\") value = true\n\t\telse if (value === \"false\") value = false\n\t\tvar levels = key5.split(/\\]\\[?|\\[/)\n\t\tvar cursor = data0\n\t\tif (key5.indexOf(\"[\") > -1) levels.pop()\n\t\tfor (var j = 0; j < levels.length; j++) {\n\t\t\tvar level = levels[j], nextLevel = levels[j + 1]\n\t\t\tvar isNumber = nextLevel == \"\" || !isNaN(parseInt(nextLevel, 10))\n\t\t\tvar isValue = j === levels.length - 1\n\t\t\tif (level === \"\") {\n\t\t\t\tvar key5 = levels.slice(0, j).join()\n\t\t\t\tif (counters[key5] == null) counters[key5] = 0\n\t\t\t\tlevel = counters[key5]++\n\t\t\t}\n\t\t\tif (cursor[level] == null) {\n\t\t\t\tcursor[level] = isValue ? value : isNumber ? [] : {}\n\t\t\t}\n\t\t\tcursor = cursor[level]\n\t\t}\n\t}\n\treturn data0\n}\nvar coreRouter = function($window) {\n\tvar supportsPushState = typeof $window.history.pushState === \"function\"\n\tvar callAsync0 = typeof setImmediate === \"function\" ? setImmediate : setTimeout\n\tfunction normalize1(fragment0) {\n\t\tvar data = $window.location[fragment0].replace(/(?:%[a-f89][a-f0-9])+/gim, decodeURIComponent)\n\t\tif (fragment0 === \"pathname\" && data[0] !== \"/\") data = \"/\" + data\n\t\treturn data\n\t}\n\tvar asyncId\n\tfunction debounceAsync(callback0) {\n\t\treturn function() {\n\t\t\tif (asyncId != null) return\n\t\t\tasyncId = callAsync0(function() {\n\t\t\t\tasyncId = null\n\t\t\t\tcallback0()\n\t\t\t})\n\t\t}\n\t}\n\tfunction parsePath(path, queryData, hashData) {\n\t\tvar queryIndex = path.indexOf(\"?\")\n\t\tvar hashIndex = path.indexOf(\"#\")\n\t\tvar pathEnd = queryIndex > -1 ? queryIndex : hashIndex > -1 ? hashIndex : path.length\n\t\tif (queryIndex > -1) {\n\t\t\tvar queryEnd = hashIndex > -1 ? hashIndex : path.length\n\t\t\tvar queryParams = parseQueryString(path.slice(queryIndex + 1, queryEnd))\n\t\t\tfor (var key4 in queryParams) queryData[key4] = queryParams[key4]\n\t\t}\n\t\tif (hashIndex > -1) {\n\t\t\tvar hashParams = parseQueryString(path.slice(hashIndex + 1))\n\t\t\tfor (var key4 in hashParams) hashData[key4] = hashParams[key4]\n\t\t}\n\t\treturn path.slice(0, pathEnd)\n\t}\n\tvar router = {prefix: \"#!\"}\n\trouter.getPath = function() {\n\t\tvar type2 = router.prefix.charAt(0)\n\t\tswitch (type2) {\n\t\t\tcase \"#\": return normalize1(\"hash\").slice(router.prefix.length)\n\t\t\tcase \"?\": return normalize1(\"search\").slice(router.prefix.length) + normalize1(\"hash\")\n\t\t\tdefault: return normalize1(\"pathname\").slice(router.prefix.length) + normalize1(\"search\") + normalize1(\"hash\")\n\t\t}\n\t}\n\trouter.setPath = function(path, data, options) {\n\t\tvar queryData = {}, hashData = {}\n\t\tpath = parsePath(path, queryData, hashData)\n\t\tif (data != null) {\n\t\t\tfor (var key4 in data) queryData[key4] = data[key4]\n\t\t\tpath = path.replace(/:([^\\/]+)/g, function(match2, token) {\n\t\t\t\tdelete queryData[token]\n\t\t\t\treturn data[token]\n\t\t\t})\n\t\t}\n\t\tvar query = buildQueryString(queryData)\n\t\tif (query) path += \"?\" + query\n\t\tvar hash = buildQueryString(hashData)\n\t\tif (hash) path += \"#\" + hash\n\t\tif (supportsPushState) {\n\t\t\tvar state = options ? options.state : null\n\t\t\tvar title = options ? options.title : null\n\t\t\t$window.onpopstate()\n\t\t\tif (options && options.replace) $window.history.replaceState(state, title, router.prefix + path)\n\t\t\telse $window.history.pushState(state, title, router.prefix + path)\n\t\t}\n\t\telse $window.location.href = router.prefix + path\n\t}\n\trouter.defineRoutes = function(routes, resolve, reject) {\n\t\tfunction resolveRoute() {\n\t\t\tvar path = router.getPath()\n\t\t\tvar params = {}\n\t\t\tvar pathname = parsePath(path, params, params)\n\t\t\tvar state = $window.history.state\n\t\t\tif (state != null) {\n\t\t\t\tfor (var k in state) params[k] = state[k]\n\t\t\t}\n\t\t\tfor (var route0 in routes) {\n\t\t\t\tvar matcher = new RegExp(\"^\" + route0.replace(/:[^\\/]+?\\.{3}/g, \"(.*?)\").replace(/:[^\\/]+/g, \"([^\\\\/]+)\") + \"\\/?$\")\n\t\t\t\tif (matcher.test(pathname)) {\n\t\t\t\t\tpathname.replace(matcher, function() {\n\t\t\t\t\t\tvar keys = route0.match(/:[^\\/]+/g) || []\n\t\t\t\t\t\tvar values = [].slice.call(arguments, 1, -2)\n\t\t\t\t\t\tfor (var i = 0; i < keys.length; i++) {\n\t\t\t\t\t\t\tparams[keys[i].replace(/:|\\./g, \"\")] = decodeURIComponent(values[i])\n\t\t\t\t\t\t}\n\t\t\t\t\t\tresolve(routes[route0], params, path, route0)\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\treject(path, params)\n\t\t}\n\t\tif (supportsPushState) $window.onpopstate = debounceAsync(resolveRoute)\n\t\telse if (router.prefix.charAt(0) === \"#\") $window.onhashchange = resolveRoute\n\t\tresolveRoute()\n\t}\n\treturn router\n}\nvar _20 = function($window, redrawService0) {\n\tvar routeService = coreRouter($window)\n\tvar identity = function(v) {return v}\n\tvar render1, component, attrs3, currentPath, lastUpdate\n\tvar route = function(root, defaultRoute, routes) {\n\t\tif (root == null) throw new Error(\"Ensure the DOM element that was passed to `m.route` is not undefined\")\n\t\tvar run1 = function() {\n\t\t\tif (render1 != null) redrawService0.render(root, render1(Vnode(component, attrs3.key, attrs3)))\n\t\t}\n\t\tvar bail = function(path) {\n\t\t\tif (path !== defaultRoute) routeService.setPath(defaultRoute, null, {replace: true})\n\t\t\telse throw new Error(\"Could not resolve default route \" + defaultRoute)\n\t\t}\n\t\trouteService.defineRoutes(routes, function(payload, params, path) {\n\t\t\tvar update = lastUpdate = function(routeResolver, comp) {\n\t\t\t\tif (update !== lastUpdate) return\n\t\t\t\tcomponent = comp != null && (typeof comp.view === \"function\" || typeof comp === \"function\")? comp : \"div\"\n\t\t\t\tattrs3 = params, currentPath = path, lastUpdate = null\n\t\t\t\trender1 = (routeResolver.render || identity).bind(routeResolver)\n\t\t\t\trun1()\n\t\t\t}\n\t\t\tif (payload.view || typeof payload === \"function\") update({}, payload)\n\t\t\telse {\n\t\t\t\tif (payload.onmatch) {\n\t\t\t\t\tPromise.resolve(payload.onmatch(params, path)).then(function(resolved) {\n\t\t\t\t\t\tupdate(payload, resolved)\n\t\t\t\t\t}, bail)\n\t\t\t\t}\n\t\t\t\telse update(payload, \"div\")\n\t\t\t}\n\t\t}, bail)\n\t\tredrawService0.subscribe(root, run1)\n\t}\n\troute.set = function(path, data, options) {\n\t\tif (lastUpdate != null) {\n\t\t\toptions = options || {}\n\t\t\toptions.replace = true\n\t\t}\n\t\tlastUpdate = null\n\t\trouteService.setPath(path, data, options)\n\t}\n\troute.get = function() {return currentPath}\n\troute.prefix = function(prefix0) {routeService.prefix = prefix0}\n\troute.link = function(vnode1) {\n\t\tvnode1.dom.setAttribute(\"href\", routeService.prefix + vnode1.attrs.href)\n\t\tvnode1.dom.onclick = function(e) {\n\t\t\tif (e.ctrlKey || e.metaKey || e.shiftKey || e.which === 2) return\n\t\t\te.preventDefault()\n\t\t\te.redraw = false\n\t\t\tvar href = this.getAttribute(\"href\")\n\t\t\tif (href.indexOf(routeService.prefix) === 0) href = href.slice(routeService.prefix.length)\n\t\t\troute.set(href, undefined, undefined)\n\t\t}\n\t}\n\troute.param = function(key3) {\n\t\tif(typeof attrs3 !== \"undefined\" && typeof key3 !== \"undefined\") return attrs3[key3]\n\t\treturn attrs3\n\t}\n\treturn route\n}\nm.route = _20(window, redrawService)\nm.withAttr = function(attrName, callback1, context) {\n\treturn function(e) {\n\t\tcallback1.call(context || this, attrName in e.currentTarget ? e.currentTarget[attrName] : e.currentTarget.getAttribute(attrName))\n\t}\n}\nvar _28 = coreRenderer(window)\nm.render = _28.render\nm.redraw = redrawService.redraw\nm.request = requestService.request\nm.jsonp = requestService.jsonp\nm.parseQueryString = parseQueryString\nm.buildQueryString = buildQueryString\nm.version = \"1.1.6\"\nm.vnode = Vnode\nif (typeof module !== \"undefined\") module[\"exports\"] = m\nelse window.m = m\n}());\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {},require(\"timers\").setImmediate)\n},{\"timers\":9}],8:[function(require,module,exports){\n// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n},{}],9:[function(require,module,exports){\n(function (setImmediate,clearImmediate){\nvar nextTick = require('process/browser.js').nextTick;\nvar apply = Function.prototype.apply;\nvar slice = Array.prototype.slice;\nvar immediateIds = {};\nvar nextImmediateId = 0;\n\n// DOM APIs, for completeness\n\nexports.setTimeout = function() {\n return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);\n};\nexports.setInterval = function() {\n return new Timeout(apply.call(setInterval, window, arguments), clearInterval);\n};\nexports.clearTimeout =\nexports.clearInterval = function(timeout) { timeout.close(); };\n\nfunction Timeout(id, clearFn) {\n this._id = id;\n this._clearFn = clearFn;\n}\nTimeout.prototype.unref = Timeout.prototype.ref = function() {};\nTimeout.prototype.close = function() {\n this._clearFn.call(window, this._id);\n};\n\n// Does not start the time, just sets up the members needed.\nexports.enroll = function(item, msecs) {\n clearTimeout(item._idleTimeoutId);\n item._idleTimeout = msecs;\n};\n\nexports.unenroll = function(item) {\n clearTimeout(item._idleTimeoutId);\n item._idleTimeout = -1;\n};\n\nexports._unrefActive = exports.active = function(item) {\n clearTimeout(item._idleTimeoutId);\n\n var msecs = item._idleTimeout;\n if (msecs >= 0) {\n item._idleTimeoutId = setTimeout(function onTimeout() {\n if (item._onTimeout)\n item._onTimeout();\n }, msecs);\n }\n};\n\n// That's not how node.js implements it but the exposed api is the same.\nexports.setImmediate = typeof setImmediate === \"function\" ? setImmediate : function(fn) {\n var id = nextImmediateId++;\n var args = arguments.length < 2 ? false : slice.call(arguments, 1);\n\n immediateIds[id] = true;\n\n nextTick(function onNextTick() {\n if (immediateIds[id]) {\n // fn.call() is faster so we optimize for the common use-case\n // @see http://jsperf.com/call-apply-segu\n if (args) {\n fn.apply(null, args);\n } else {\n fn.call(null);\n }\n // Prevent ids from leaking\n exports.clearImmediate(id);\n }\n });\n\n return id;\n};\n\nexports.clearImmediate = typeof clearImmediate === \"function\" ? clearImmediate : function(id) {\n delete immediateIds[id];\n};\n}).call(this,require(\"timers\").setImmediate,require(\"timers\").clearImmediate)\n},{\"process/browser.js\":8,\"timers\":9}],10:[function(require,module,exports){\nfunction tlite(getTooltipOpts) {\n document.addEventListener('mouseover', function (e) {\n var el = e.target;\n var opts = getTooltipOpts(el);\n\n if (!opts) {\n el = el.parentElement;\n opts = el && getTooltipOpts(el);\n }\n\n opts && tlite.show(el, opts, true);\n });\n}\n\ntlite.show = function (el, opts, isAuto) {\n var fallbackAttrib = 'data-tlite';\n opts = opts || {};\n\n (el.tooltip || Tooltip(el, opts)).show();\n\n function Tooltip(el, opts) {\n var tooltipEl;\n var showTimer;\n var text;\n\n el.addEventListener('mousedown', autoHide);\n el.addEventListener('mouseleave', autoHide);\n\n function show() {\n text = el.title || el.getAttribute(fallbackAttrib) || text;\n el.title = '';\n el.setAttribute(fallbackAttrib, '');\n text && !showTimer && (showTimer = setTimeout(fadeIn, isAuto ? 150 : 1))\n }\n\n function autoHide() {\n tlite.hide(el, true);\n }\n\n function hide(isAutoHiding) {\n if (isAuto === isAutoHiding) {\n showTimer = clearTimeout(showTimer);\n var parent = tooltipEl && tooltipEl.parentNode;\n parent && parent.removeChild(tooltipEl);\n tooltipEl = undefined;\n }\n }\n\n function fadeIn() {\n if (!tooltipEl) {\n tooltipEl = createTooltip(el, text, opts);\n }\n }\n\n return el.tooltip = {\n show: show,\n hide: hide\n };\n }\n\n function createTooltip(el, text, opts) {\n var tooltipEl = document.createElement('span');\n var grav = opts.grav || el.getAttribute('data-tlite') || 'n';\n\n tooltipEl.innerHTML = text;\n\n el.appendChild(tooltipEl);\n\n var vertGrav = grav[0] || '';\n var horzGrav = grav[1] || '';\n\n function positionTooltip() {\n tooltipEl.className = 'tlite ' + 'tlite-' + vertGrav + horzGrav;\n\n var arrowSize = 10;\n var top = el.offsetTop;\n var left = el.offsetLeft;\n\n if (tooltipEl.offsetParent === el) {\n top = left = 0;\n }\n\n var width = el.offsetWidth;\n var height = el.offsetHeight;\n var tooltipHeight = tooltipEl.offsetHeight;\n var tooltipWidth = tooltipEl.offsetWidth;\n var centerEl = left + (width / 2);\n\n tooltipEl.style.top = (\n vertGrav === 's' ? (top - tooltipHeight - arrowSize) :\n vertGrav === 'n' ? (top + height + arrowSize) :\n (top + (height / 2) - (tooltipHeight / 2))\n ) + 'px';\n\n tooltipEl.style.left = (\n horzGrav === 'w' ? left :\n horzGrav === 'e' ? left + width - tooltipWidth :\n vertGrav === 'w' ? (left + width + arrowSize) :\n vertGrav === 'e' ? (left - tooltipWidth - arrowSize) :\n (centerEl - tooltipWidth / 2)\n ) + 'px';\n }\n\n positionTooltip();\n\n var rect = tooltipEl.getBoundingClientRect();\n\n if (vertGrav === 's' && rect.top < 0) {\n vertGrav = 'n';\n positionTooltip();\n } else if (vertGrav === 'n' && rect.bottom > window.innerHeight) {\n vertGrav = 's';\n positionTooltip();\n } else if (vertGrav === 'e' && rect.left < 0) {\n vertGrav = 'w';\n positionTooltip();\n } else if (vertGrav === 'w' && rect.right > window.innerWidth) {\n vertGrav = 'e';\n positionTooltip();\n }\n\n tooltipEl.className += ' tlite-visible';\n\n return tooltipEl;\n }\n};\n\ntlite.hide = function (el, isAuto) {\n el.tooltip && el.tooltip.hide(isAuto);\n};\n\nif (typeof module !== 'undefined' && module.exports) {\n module.exports = tlite;\n}\n\n},{}],11:[function(require,module,exports){\n/*!\n * EventEmitter v5.2.5 - git.io/ee\n * Unlicense - http://unlicense.org/\n * Oliver Caldwell - http://oli.me.uk/\n * @preserve\n */\n\n;(function (exports) {\n 'use strict';\n\n /**\n * Class for managing events.\n * Can be extended to provide event functionality in other classes.\n *\n * @class EventEmitter Manages event registering and emitting.\n */\n function EventEmitter() {}\n\n // Shortcuts to improve speed and size\n var proto = EventEmitter.prototype;\n var originalGlobalValue = exports.EventEmitter;\n\n /**\n * Finds the index of the listener for the event in its storage array.\n *\n * @param {Function[]} listeners Array of listeners to search through.\n * @param {Function} listener Method to look for.\n * @return {Number} Index of the specified listener, -1 if not found\n * @api private\n */\n function indexOfListener(listeners, listener) {\n var i = listeners.length;\n while (i--) {\n if (listeners[i].listener === listener) {\n return i;\n }\n }\n\n return -1;\n }\n\n /**\n * Alias a method while keeping the context correct, to allow for overwriting of target method.\n *\n * @param {String} name The name of the target method.\n * @return {Function} The aliased method\n * @api private\n */\n function alias(name) {\n return function aliasClosure() {\n return this[name].apply(this, arguments);\n };\n }\n\n /**\n * Returns the listener array for the specified event.\n * Will initialise the event object and listener arrays if required.\n * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.\n * Each property in the object response is an array of listener functions.\n *\n * @param {String|RegExp} evt Name of the event to return the listeners from.\n * @return {Function[]|Object} All listener functions for the event.\n */\n proto.getListeners = function getListeners(evt) {\n var events = this._getEvents();\n var response;\n var key;\n\n // Return a concatenated array of all matching events if\n // the selector is a regular expression.\n if (evt instanceof RegExp) {\n response = {};\n for (key in events) {\n if (events.hasOwnProperty(key) && evt.test(key)) {\n response[key] = events[key];\n }\n }\n }\n else {\n response = events[evt] || (events[evt] = []);\n }\n\n return response;\n };\n\n /**\n * Takes a list of listener objects and flattens it into a list of listener functions.\n *\n * @param {Object[]} listeners Raw listener objects.\n * @return {Function[]} Just the listener functions.\n */\n proto.flattenListeners = function flattenListeners(listeners) {\n var flatListeners = [];\n var i;\n\n for (i = 0; i < listeners.length; i += 1) {\n flatListeners.push(listeners[i].listener);\n }\n\n return flatListeners;\n };\n\n /**\n * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.\n *\n * @param {String|RegExp} evt Name of the event to return the listeners from.\n * @return {Object} All listener functions for an event in an object.\n */\n proto.getListenersAsObject = function getListenersAsObject(evt) {\n var listeners = this.getListeners(evt);\n var response;\n\n if (listeners instanceof Array) {\n response = {};\n response[evt] = listeners;\n }\n\n return response || listeners;\n };\n\n function isValidListener (listener) {\n if (typeof listener === 'function' || listener instanceof RegExp) {\n return true\n } else if (listener && typeof listener === 'object') {\n return isValidListener(listener.listener)\n } else {\n return false\n }\n }\n\n /**\n * Adds a listener function to the specified event.\n * The listener will not be added if it is a duplicate.\n * If the listener returns true then it will be removed after it is called.\n * If you pass a regular expression as the event name then the listener will be added to all events that match it.\n *\n * @param {String|RegExp} evt Name of the event to attach the listener to.\n * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.addListener = function addListener(evt, listener) {\n if (!isValidListener(listener)) {\n throw new TypeError('listener must be a function');\n }\n\n var listeners = this.getListenersAsObject(evt);\n var listenerIsWrapped = typeof listener === 'object';\n var key;\n\n for (key in listeners) {\n if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {\n listeners[key].push(listenerIsWrapped ? listener : {\n listener: listener,\n once: false\n });\n }\n }\n\n return this;\n };\n\n /**\n * Alias of addListener\n */\n proto.on = alias('addListener');\n\n /**\n * Semi-alias of addListener. It will add a listener that will be\n * automatically removed after its first execution.\n *\n * @param {String|RegExp} evt Name of the event to attach the listener to.\n * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.addOnceListener = function addOnceListener(evt, listener) {\n return this.addListener(evt, {\n listener: listener,\n once: true\n });\n };\n\n /**\n * Alias of addOnceListener.\n */\n proto.once = alias('addOnceListener');\n\n /**\n * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.\n * You need to tell it what event names should be matched by a regex.\n *\n * @param {String} evt Name of the event to create.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.defineEvent = function defineEvent(evt) {\n this.getListeners(evt);\n return this;\n };\n\n /**\n * Uses defineEvent to define multiple events.\n *\n * @param {String[]} evts An array of event names to define.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.defineEvents = function defineEvents(evts) {\n for (var i = 0; i < evts.length; i += 1) {\n this.defineEvent(evts[i]);\n }\n return this;\n };\n\n /**\n * Removes a listener function from the specified event.\n * When passed a regular expression as the event name, it will remove the listener from all events that match it.\n *\n * @param {String|RegExp} evt Name of the event to remove the listener from.\n * @param {Function} listener Method to remove from the event.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.removeListener = function removeListener(evt, listener) {\n var listeners = this.getListenersAsObject(evt);\n var index;\n var key;\n\n for (key in listeners) {\n if (listeners.hasOwnProperty(key)) {\n index = indexOfListener(listeners[key], listener);\n\n if (index !== -1) {\n listeners[key].splice(index, 1);\n }\n }\n }\n\n return this;\n };\n\n /**\n * Alias of removeListener\n */\n proto.off = alias('removeListener');\n\n /**\n * Adds listeners in bulk using the manipulateListeners method.\n * If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.\n * You can also pass it a regular expression to add the array of listeners to all events that match it.\n * Yeah, this function does quite a bit. That's probably a bad thing.\n *\n * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.\n * @param {Function[]} [listeners] An optional array of listener functions to add.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.addListeners = function addListeners(evt, listeners) {\n // Pass through to manipulateListeners\n return this.manipulateListeners(false, evt, listeners);\n };\n\n /**\n * Removes listeners in bulk using the manipulateListeners method.\n * If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.\n * You can also pass it an event name and an array of listeners to be removed.\n * You can also pass it a regular expression to remove the listeners from all events that match it.\n *\n * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.\n * @param {Function[]} [listeners] An optional array of listener functions to remove.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.removeListeners = function removeListeners(evt, listeners) {\n // Pass through to manipulateListeners\n return this.manipulateListeners(true, evt, listeners);\n };\n\n /**\n * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.\n * The first argument will determine if the listeners are removed (true) or added (false).\n * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.\n * You can also pass it an event name and an array of listeners to be added/removed.\n * You can also pass it a regular expression to manipulate the listeners of all events that match it.\n *\n * @param {Boolean} remove True if you want to remove listeners, false if you want to add.\n * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.\n * @param {Function[]} [listeners] An optional array of listener functions to add/remove.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {\n var i;\n var value;\n var single = remove ? this.removeListener : this.addListener;\n var multiple = remove ? this.removeListeners : this.addListeners;\n\n // If evt is an object then pass each of its properties to this method\n if (typeof evt === 'object' && !(evt instanceof RegExp)) {\n for (i in evt) {\n if (evt.hasOwnProperty(i) && (value = evt[i])) {\n // Pass the single listener straight through to the singular method\n if (typeof value === 'function') {\n single.call(this, i, value);\n }\n else {\n // Otherwise pass back to the multiple function\n multiple.call(this, i, value);\n }\n }\n }\n }\n else {\n // So evt must be a string\n // And listeners must be an array of listeners\n // Loop over it and pass each one to the multiple method\n i = listeners.length;\n while (i--) {\n single.call(this, evt, listeners[i]);\n }\n }\n\n return this;\n };\n\n /**\n * Removes all listeners from a specified event.\n * If you do not specify an event then all listeners will be removed.\n * That means every event will be emptied.\n * You can also pass a regex to remove all events that match it.\n *\n * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.removeEvent = function removeEvent(evt) {\n var type = typeof evt;\n var events = this._getEvents();\n var key;\n\n // Remove different things depending on the state of evt\n if (type === 'string') {\n // Remove all listeners for the specified event\n delete events[evt];\n }\n else if (evt instanceof RegExp) {\n // Remove all events matching the regex.\n for (key in events) {\n if (events.hasOwnProperty(key) && evt.test(key)) {\n delete events[key];\n }\n }\n }\n else {\n // Remove all listeners in all events\n delete this._events;\n }\n\n return this;\n };\n\n /**\n * Alias of removeEvent.\n *\n * Added to mirror the node API.\n */\n proto.removeAllListeners = alias('removeEvent');\n\n /**\n * Emits an event of your choice.\n * When emitted, every listener attached to that event will be executed.\n * If you pass the optional argument array then those arguments will be passed to every listener upon execution.\n * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.\n * So they will not arrive within the array on the other side, they will be separate.\n * You can also pass a regular expression to emit to all events that match it.\n *\n * @param {String|RegExp} evt Name of the event to emit and execute listeners for.\n * @param {Array} [args] Optional array of arguments to be passed to each listener.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.emitEvent = function emitEvent(evt, args) {\n var listenersMap = this.getListenersAsObject(evt);\n var listeners;\n var listener;\n var i;\n var key;\n var response;\n\n for (key in listenersMap) {\n if (listenersMap.hasOwnProperty(key)) {\n listeners = listenersMap[key].slice(0);\n\n for (i = 0; i < listeners.length; i++) {\n // If the listener returns true then it shall be removed from the event\n // The function is executed either with a basic call or an apply if there is an args array\n listener = listeners[i];\n\n if (listener.once === true) {\n this.removeListener(evt, listener.listener);\n }\n\n response = listener.listener.apply(this, args || []);\n\n if (response === this._getOnceReturnValue()) {\n this.removeListener(evt, listener.listener);\n }\n }\n }\n }\n\n return this;\n };\n\n /**\n * Alias of emitEvent\n */\n proto.trigger = alias('emitEvent');\n\n /**\n * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.\n * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.\n *\n * @param {String|RegExp} evt Name of the event to emit and execute listeners for.\n * @param {...*} Optional additional arguments to be passed to each listener.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.emit = function emit(evt) {\n var args = Array.prototype.slice.call(arguments, 1);\n return this.emitEvent(evt, args);\n };\n\n /**\n * Sets the current value to check against when executing listeners. If a\n * listeners return value matches the one set here then it will be removed\n * after execution. This value defaults to true.\n *\n * @param {*} value The new value to check for when executing listeners.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n proto.setOnceReturnValue = function setOnceReturnValue(value) {\n this._onceReturnValue = value;\n return this;\n };\n\n /**\n * Fetches the current value to check against when executing listeners. If\n * the listeners return value matches this one then it should be removed\n * automatically. It will return true by default.\n *\n * @return {*|Boolean} The current value to check for or the default, true.\n * @api private\n */\n proto._getOnceReturnValue = function _getOnceReturnValue() {\n if (this.hasOwnProperty('_onceReturnValue')) {\n return this._onceReturnValue;\n }\n else {\n return true;\n }\n };\n\n /**\n * Fetches the events object and creates one if required.\n *\n * @return {Object} The events storage object.\n * @api private\n */\n proto._getEvents = function _getEvents() {\n return this._events || (this._events = {});\n };\n\n /**\n * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.\n *\n * @return {Function} Non conflicting EventEmitter class.\n */\n EventEmitter.noConflict = function noConflict() {\n exports.EventEmitter = originalGlobalValue;\n return EventEmitter;\n };\n\n // Expose the class either via AMD, CommonJS or the global object\n if (typeof define === 'function' && define.amd) {\n define(function () {\n return EventEmitter;\n });\n }\n else if (typeof module === 'object' && module.exports){\n module.exports = EventEmitter;\n }\n else {\n exports.EventEmitter = EventEmitter;\n }\n}(typeof window !== 'undefined' ? window : this || {}));\n\n},{}]},{},[1]);\n })();"]}
assets/js/forms-admin.js CHANGED
@@ -1374,7 +1374,7 @@ window.mc4wp.forms.fields = fields;
1374
 
1375
  },{"./admin/field-helper.js":4,"./admin/fields-factory.js":5,"./admin/fields.js":6,"./admin/form-editor.js":7,"./admin/form-watcher.js":8,"./admin/notices":9}],12:[function(require,module,exports){
1376
  // CodeMirror, copyright (c) by Marijn Haverbeke and others
1377
- // Distributed under an MIT license: http://codemirror.net/LICENSE
1378
 
1379
  /**
1380
  * Tag-closer extension for CodeMirror.
@@ -1551,7 +1551,7 @@ window.mc4wp.forms.fields = fields;
1551
 
1552
  },{"../../lib/codemirror":17,"../fold/xml-fold":15}],13:[function(require,module,exports){
1553
  // CodeMirror, copyright (c) by Marijn Haverbeke and others
1554
- // Distributed under an MIT license: http://codemirror.net/LICENSE
1555
 
1556
  (function(mod) {
1557
  if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -1698,7 +1698,7 @@ window.mc4wp.forms.fields = fields;
1698
 
1699
  },{"../../lib/codemirror":17}],14:[function(require,module,exports){
1700
  // CodeMirror, copyright (c) by Marijn Haverbeke and others
1701
- // Distributed under an MIT license: http://codemirror.net/LICENSE
1702
 
1703
  (function(mod) {
1704
  if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -1766,7 +1766,7 @@ window.mc4wp.forms.fields = fields;
1766
 
1767
  },{"../../lib/codemirror":17,"../fold/xml-fold":15}],15:[function(require,module,exports){
1768
  // CodeMirror, copyright (c) by Marijn Haverbeke and others
1769
- // Distributed under an MIT license: http://codemirror.net/LICENSE
1770
 
1771
  (function(mod) {
1772
  if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -1952,7 +1952,7 @@ window.mc4wp.forms.fields = fields;
1952
 
1953
  },{"../../lib/codemirror":17}],16:[function(require,module,exports){
1954
  // CodeMirror, copyright (c) by Marijn Haverbeke and others
1955
- // Distributed under an MIT license: http://codemirror.net/LICENSE
1956
 
1957
  (function(mod) {
1958
  if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -2026,9705 +2026,9707 @@ window.mc4wp.forms.fields = fields;
2026
 
2027
  },{"../../lib/codemirror":17}],17:[function(require,module,exports){
2028
  // CodeMirror, copyright (c) by Marijn Haverbeke and others
2029
- // Distributed under an MIT license: http://codemirror.net/LICENSE
2030
 
2031
- // This is CodeMirror (http://codemirror.net), a code editor
2032
  // implemented in JavaScript on top of the browser's DOM.
2033
  //
2034
  // You can find some technical background for some of the code below
2035
  // at http://marijnhaverbeke.nl/blog/#cm-internals .
2036
 
2037
  (function (global, factory) {
2038
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
2039
- typeof define === 'function' && define.amd ? define(factory) :
2040
- (global.CodeMirror = factory());
2041
  }(this, (function () { 'use strict';
2042
 
2043
- // Kludges for bugs and behavior differences that can't be feature
2044
- // detected are enabled based on userAgent etc sniffing.
2045
- var userAgent = navigator.userAgent;
2046
- var platform = navigator.platform;
2047
-
2048
- var gecko = /gecko\/\d/i.test(userAgent);
2049
- var ie_upto10 = /MSIE \d/.test(userAgent);
2050
- var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent);
2051
- var edge = /Edge\/(\d+)/.exec(userAgent);
2052
- var ie = ie_upto10 || ie_11up || edge;
2053
- var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : +(edge || ie_11up)[1]);
2054
- var webkit = !edge && /WebKit\//.test(userAgent);
2055
- var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent);
2056
- var chrome = !edge && /Chrome\//.test(userAgent);
2057
- var presto = /Opera\//.test(userAgent);
2058
- var safari = /Apple Computer/.test(navigator.vendor);
2059
- var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent);
2060
- var phantom = /PhantomJS/.test(userAgent);
2061
-
2062
- var ios = !edge && /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent);
2063
- var android = /Android/.test(userAgent);
2064
- // This is woefully incomplete. Suggestions for alternative methods welcome.
2065
- var mobile = ios || android || /webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent);
2066
- var mac = ios || /Mac/.test(platform);
2067
- var chromeOS = /\bCrOS\b/.test(userAgent);
2068
- var windows = /win/i.test(platform);
2069
-
2070
- var presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/);
2071
- if (presto_version) { presto_version = Number(presto_version[1]); }
2072
- if (presto_version && presto_version >= 15) { presto = false; webkit = true; }
2073
- // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
2074
- var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11));
2075
- var captureRightClick = gecko || (ie && ie_version >= 9);
2076
-
2077
- function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") }
2078
-
2079
- var rmClass = function(node, cls) {
2080
- var current = node.className;
2081
- var match = classTest(cls).exec(current);
2082
- if (match) {
2083
- var after = current.slice(match.index + match[0].length);
2084
- node.className = current.slice(0, match.index) + (after ? match[1] + after : "");
2085
- }
2086
- };
2087
-
2088
- function removeChildren(e) {
2089
- for (var count = e.childNodes.length; count > 0; --count)
2090
- { e.removeChild(e.firstChild); }
2091
- return e
2092
- }
2093
 
2094
- function removeChildrenAndAdd(parent, e) {
2095
- return removeChildren(parent).appendChild(e)
2096
- }
 
 
2097
 
2098
- function elt(tag, content, className, style) {
2099
- var e = document.createElement(tag);
2100
- if (className) { e.className = className; }
2101
- if (style) { e.style.cssText = style; }
2102
- if (typeof content == "string") { e.appendChild(document.createTextNode(content)); }
2103
- else if (content) { for (var i = 0; i < content.length; ++i) { e.appendChild(content[i]); } }
2104
- return e
2105
- }
2106
- // wrapper for elt, which removes the elt from the accessibility tree
2107
- function eltP(tag, content, className, style) {
2108
- var e = elt(tag, content, className, style);
2109
- e.setAttribute("role", "presentation");
2110
- return e
2111
- }
2112
 
2113
- var range;
2114
- if (document.createRange) { range = function(node, start, end, endNode) {
2115
- var r = document.createRange();
2116
- r.setEnd(endNode || node, end);
2117
- r.setStart(node, start);
2118
- return r
2119
- }; }
2120
- else { range = function(node, start, end) {
2121
- var r = document.body.createTextRange();
2122
- try { r.moveToElementText(node.parentNode); }
2123
- catch(e) { return r }
2124
- r.collapse(true);
2125
- r.moveEnd("character", end);
2126
- r.moveStart("character", start);
2127
- return r
2128
- }; }
2129
-
2130
- function contains(parent, child) {
2131
- if (child.nodeType == 3) // Android browser always returns false when child is a textnode
2132
- { child = child.parentNode; }
2133
- if (parent.contains)
2134
- { return parent.contains(child) }
2135
- do {
2136
- if (child.nodeType == 11) { child = child.host; }
2137
- if (child == parent) { return true }
2138
- } while (child = child.parentNode)
2139
- }
2140
 
2141
- function activeElt() {
2142
- // IE and Edge may throw an "Unspecified Error" when accessing document.activeElement.
2143
- // IE < 10 will throw when accessed while the page is loading or in an iframe.
2144
- // IE > 9 and Edge will throw when accessed in an iframe if document.body is unavailable.
2145
- var activeElement;
2146
- try {
2147
- activeElement = document.activeElement;
2148
- } catch(e) {
2149
- activeElement = document.body || null;
2150
- }
2151
- while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement)
2152
- { activeElement = activeElement.shadowRoot.activeElement; }
2153
- return activeElement
2154
- }
 
 
2155
 
2156
- function addClass(node, cls) {
2157
- var current = node.className;
2158
- if (!classTest(cls).test(current)) { node.className += (current ? " " : "") + cls; }
2159
- }
2160
- function joinClasses(a, b) {
2161
- var as = a.split(" ");
2162
- for (var i = 0; i < as.length; i++)
2163
- { if (as[i] && !classTest(as[i]).test(b)) { b += " " + as[i]; } }
2164
- return b
2165
- }
2166
 
2167
- var selectInput = function(node) { node.select(); };
2168
- if (ios) // Mobile Safari apparently has a bug where select() is broken.
2169
- { selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; }; }
2170
- else if (ie) // Suppress mysterious IE10 errors
2171
- { selectInput = function(node) { try { node.select(); } catch(_e) {} }; }
 
 
 
 
 
 
 
 
 
2172
 
2173
- function bind(f) {
2174
- var args = Array.prototype.slice.call(arguments, 1);
2175
- return function(){return f.apply(null, args)}
2176
- }
 
 
 
 
 
 
2177
 
2178
- function copyObj(obj, target, overwrite) {
2179
- if (!target) { target = {}; }
2180
- for (var prop in obj)
2181
- { if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
2182
- { target[prop] = obj[prop]; } }
2183
- return target
2184
- }
2185
 
2186
- // Counts the column offset in a string, taking tabs into account.
2187
- // Used mostly to find indentation.
2188
- function countColumn(string, end, tabSize, startIndex, startValue) {
2189
- if (end == null) {
2190
- end = string.search(/[^\s\u00a0]/);
2191
- if (end == -1) { end = string.length; }
2192
- }
2193
- for (var i = startIndex || 0, n = startValue || 0;;) {
2194
- var nextTab = string.indexOf("\t", i);
2195
- if (nextTab < 0 || nextTab >= end)
2196
- { return n + (end - i) }
2197
- n += nextTab - i;
2198
- n += tabSize - (n % tabSize);
2199
- i = nextTab + 1;
2200
  }
2201
- }
2202
-
2203
- var Delayed = function() {this.id = null;};
2204
- Delayed.prototype.set = function (ms, f) {
2205
- clearTimeout(this.id);
2206
- this.id = setTimeout(f, ms);
2207
- };
2208
 
2209
- function indexOf(array, elt) {
2210
- for (var i = 0; i < array.length; ++i)
2211
- { if (array[i] == elt) { return i } }
2212
- return -1
2213
- }
 
 
2214
 
2215
- // Number of pixels added to scroller and sizer to hide scrollbar
2216
- var scrollerGap = 30;
2217
-
2218
- // Returned or thrown by various protocols to signal 'I'm not
2219
- // handling this'.
2220
- var Pass = {toString: function(){return "CodeMirror.Pass"}};
2221
-
2222
- // Reused option objects for setSelection & friends
2223
- var sel_dontScroll = {scroll: false};
2224
- var sel_mouse = {origin: "*mouse"};
2225
- var sel_move = {origin: "+move"};
2226
-
2227
- // The inverse of countColumn -- find the offset that corresponds to
2228
- // a particular column.
2229
- function findColumn(string, goal, tabSize) {
2230
- for (var pos = 0, col = 0;;) {
2231
- var nextTab = string.indexOf("\t", pos);
2232
- if (nextTab == -1) { nextTab = string.length; }
2233
- var skipped = nextTab - pos;
2234
- if (nextTab == string.length || col + skipped >= goal)
2235
- { return pos + Math.min(skipped, goal - col) }
2236
- col += nextTab - pos;
2237
- col += tabSize - (col % tabSize);
2238
- pos = nextTab + 1;
2239
- if (col >= goal) { return pos }
2240
  }
2241
- }
2242
 
2243
- var spaceStrs = [""];
2244
- function spaceStr(n) {
2245
- while (spaceStrs.length <= n)
2246
- { spaceStrs.push(lst(spaceStrs) + " "); }
2247
- return spaceStrs[n]
2248
- }
2249
 
2250
- function lst(arr) { return arr[arr.length-1] }
 
 
 
 
2251
 
2252
- function map(array, f) {
2253
- var out = [];
2254
- for (var i = 0; i < array.length; i++) { out[i] = f(array[i], i); }
2255
- return out
2256
- }
2257
 
2258
- function insertSorted(array, value, score) {
2259
- var pos = 0, priority = score(value);
2260
- while (pos < array.length && score(array[pos]) <= priority) { pos++; }
2261
- array.splice(pos, 0, value);
2262
- }
2263
 
2264
- function nothing() {}
 
2265
 
2266
- function createObj(base, props) {
2267
- var inst;
2268
- if (Object.create) {
2269
- inst = Object.create(base);
2270
- } else {
2271
- nothing.prototype = base;
2272
- inst = new nothing();
 
 
 
 
 
 
 
2273
  }
2274
- if (props) { copyObj(props, inst); }
2275
- return inst
2276
- }
2277
 
2278
- var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
2279
- function isWordCharBasic(ch) {
2280
- return /\w/.test(ch) || ch > "\x80" &&
2281
- (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch))
2282
- }
2283
- function isWordChar(ch, helper) {
2284
- if (!helper) { return isWordCharBasic(ch) }
2285
- if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) { return true }
2286
- return helper.test(ch)
2287
- }
2288
 
2289
- function isEmpty(obj) {
2290
- for (var n in obj) { if (obj.hasOwnProperty(n) && obj[n]) { return false } }
2291
- return true
2292
- }
2293
 
2294
- // Extending unicode characters. A series of a non-extending char +
2295
- // any number of extending chars is treated as a single unit as far
2296
- // as editing and measuring is concerned. This is not fully correct,
2297
- // since some scripts/fonts/browsers also treat other configurations
2298
- // of code points as a group.
2299
- var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;
2300
- function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch) }
2301
-
2302
- // Returns a number from the range [`0`; `str.length`] unless `pos` is outside that range.
2303
- function skipExtendingChars(str, pos, dir) {
2304
- while ((dir < 0 ? pos > 0 : pos < str.length) && isExtendingChar(str.charAt(pos))) { pos += dir; }
2305
- return pos
2306
- }
2307
 
2308
- // Returns the value from the range [`from`; `to`] that satisfies
2309
- // `pred` and is closest to `from`. Assumes that at least `to`
2310
- // satisfies `pred`. Supports `from` being greater than `to`.
2311
- function findFirst(pred, from, to) {
2312
- // At any point we are certain `to` satisfies `pred`, don't know
2313
- // whether `from` does.
2314
- var dir = from > to ? -1 : 1;
2315
- for (;;) {
2316
- if (from == to) { return from }
2317
- var midF = (from + to) / 2, mid = dir < 0 ? Math.ceil(midF) : Math.floor(midF);
2318
- if (mid == from) { return pred(mid) ? from : to }
2319
- if (pred(mid)) { to = mid; }
2320
- else { from = mid + dir; }
2321
  }
2322
- }
2323
 
2324
- // The display handles the DOM integration, both for input reading
2325
- // and content drawing. It holds references to DOM nodes and
2326
- // display-related state.
2327
-
2328
- function Display(place, doc, input) {
2329
- var d = this;
2330
- this.input = input;
2331
-
2332
- // Covers bottom-right square when both scrollbars are present.
2333
- d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
2334
- d.scrollbarFiller.setAttribute("cm-not-content", "true");
2335
- // Covers bottom of gutter when coverGutterNextToScrollbar is on
2336
- // and h scrollbar is present.
2337
- d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
2338
- d.gutterFiller.setAttribute("cm-not-content", "true");
2339
- // Will contain the actual code, positioned to cover the viewport.
2340
- d.lineDiv = eltP("div", null, "CodeMirror-code");
2341
- // Elements are added to these to represent selection and cursors.
2342
- d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
2343
- d.cursorDiv = elt("div", null, "CodeMirror-cursors");
2344
- // A visibility: hidden element used to find the size of things.
2345
- d.measure = elt("div", null, "CodeMirror-measure");
2346
- // When lines outside of the viewport are measured, they are drawn in this.
2347
- d.lineMeasure = elt("div", null, "CodeMirror-measure");
2348
- // Wraps everything that needs to exist inside the vertically-padded coordinate system
2349
- d.lineSpace = eltP("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],
2350
- null, "position: relative; outline: none");
2351
- var lines = eltP("div", [d.lineSpace], "CodeMirror-lines");
2352
- // Moved around its parent to cover visible view.
2353
- d.mover = elt("div", [lines], null, "position: relative");
2354
- // Set to the height of the document, allowing scrolling.
2355
- d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
2356
- d.sizerWidth = null;
2357
- // Behavior of elts with overflow: auto and padding is
2358
- // inconsistent across browsers. This is used to ensure the
2359
- // scrollable area is big enough.
2360
- d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;");
2361
- // Will contain the gutters, if any.
2362
- d.gutters = elt("div", null, "CodeMirror-gutters");
2363
- d.lineGutter = null;
2364
- // Actual scrollable element.
2365
- d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
2366
- d.scroller.setAttribute("tabIndex", "-1");
2367
- // The element in which the editor lives.
2368
- d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
2369
-
2370
- // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)
2371
- if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
2372
- if (!webkit && !(gecko && mobile)) { d.scroller.draggable = true; }
2373
-
2374
- if (place) {
2375
- if (place.appendChild) { place.appendChild(d.wrapper); }
2376
- else { place(d.wrapper); }
2377
- }
2378
-
2379
- // Current rendered range (may be bigger than the view window).
2380
- d.viewFrom = d.viewTo = doc.first;
2381
- d.reportedViewFrom = d.reportedViewTo = doc.first;
2382
- // Information about the rendered lines.
2383
- d.view = [];
2384
- d.renderedView = null;
2385
- // Holds info about a single rendered line when it was rendered
2386
- // for measurement, while not in view.
2387
- d.externalMeasured = null;
2388
- // Empty space (in pixels) above the view
2389
- d.viewOffset = 0;
2390
- d.lastWrapHeight = d.lastWrapWidth = 0;
2391
- d.updateLineNumbers = null;
2392
-
2393
- d.nativeBarWidth = d.barHeight = d.barWidth = 0;
2394
- d.scrollbarsClipped = false;
2395
-
2396
- // Used to only resize the line number gutter when necessary (when
2397
- // the amount of lines crosses a boundary that makes its width change)
2398
- d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
2399
- // Set to true when a non-horizontal-scrolling line widget is
2400
- // added. As an optimization, line widget aligning is skipped when
2401
- // this is false.
2402
- d.alignWidgets = false;
2403
-
2404
- d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
2405
-
2406
- // Tracks the maximum line length so that the horizontal scrollbar
2407
- // can be kept static when scrolling.
2408
- d.maxLine = null;
2409
- d.maxLineLength = 0;
2410
- d.maxLineChanged = false;
2411
-
2412
- // Used for measuring wheel scrolling granularity
2413
- d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
2414
-
2415
- // True when shift is held down.
2416
- d.shift = false;
2417
-
2418
- // Used to track whether anything happened since the context menu
2419
- // was opened.
2420
- d.selForContextMenu = null;
2421
-
2422
- d.activeTouch = null;
2423
-
2424
- input.init(d);
2425
- }
2426
 
2427
- // Find the line object corresponding to the given line number.
2428
- function getLine(doc, n) {
2429
- n -= doc.first;
2430
- if (n < 0 || n >= doc.size) { throw new Error("There is no line " + (n + doc.first) + " in the document.") }
2431
- var chunk = doc;
2432
- while (!chunk.lines) {
2433
- for (var i = 0;; ++i) {
2434
- var child = chunk.children[i], sz = child.chunkSize();
2435
- if (n < sz) { chunk = child; break }
2436
- n -= sz;
2437
  }
 
 
2438
  }
2439
- return chunk.lines[n]
2440
- }
2441
 
2442
- // Get the part of a document between two positions, as an array of
2443
- // strings.
2444
- function getBetween(doc, start, end) {
2445
- var out = [], n = start.line;
2446
- doc.iter(start.line, end.line + 1, function (line) {
2447
- var text = line.text;
2448
- if (n == end.line) { text = text.slice(0, end.ch); }
2449
- if (n == start.line) { text = text.slice(start.ch); }
2450
- out.push(text);
2451
- ++n;
2452
- });
2453
- return out
2454
- }
2455
- // Get the lines between from and to, as array of strings.
2456
- function getLines(doc, from, to) {
2457
- var out = [];
2458
- doc.iter(from, to, function (line) { out.push(line.text); }); // iter aborts when callback returns truthy value
2459
- return out
2460
- }
2461
 
2462
- // Update the height of a line, propagating the height change
2463
- // upwards to parent nodes.
2464
- function updateLineHeight(line, height) {
2465
- var diff = height - line.height;
2466
- if (diff) { for (var n = line; n; n = n.parent) { n.height += diff; } }
2467
- }
2468
 
2469
- // Given a line object, find its line number by walking up through
2470
- // its parent links.
2471
- function lineNo(line) {
2472
- if (line.parent == null) { return null }
2473
- var cur = line.parent, no = indexOf(cur.lines, line);
2474
- for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
2475
- for (var i = 0;; ++i) {
2476
- if (chunk.children[i] == cur) { break }
2477
- no += chunk.children[i].chunkSize();
2478
- }
 
 
2479
  }
2480
- return no + cur.first
2481
- }
2482
 
2483
- // Find the line at the given vertical position, using the height
2484
- // information in the document tree.
2485
- function lineAtHeight(chunk, h) {
2486
- var n = chunk.first;
2487
- outer: do {
2488
- for (var i$1 = 0; i$1 < chunk.children.length; ++i$1) {
2489
- var child = chunk.children[i$1], ch = child.height;
2490
- if (h < ch) { chunk = child; continue outer }
2491
- h -= ch;
2492
- n += child.chunkSize();
2493
- }
2494
- return n
2495
- } while (!chunk.lines)
2496
- var i = 0;
2497
- for (; i < chunk.lines.length; ++i) {
2498
- var line = chunk.lines[i], lh = line.height;
2499
- if (h < lh) { break }
2500
- h -= lh;
2501
- }
2502
- return n + i
2503
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2504
 
2505
- function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size}
 
 
 
 
 
2506
 
2507
- function lineNumberFor(options, i) {
2508
- return String(options.lineNumberFormatter(i + options.firstLineNumber))
2509
- }
 
 
 
 
 
 
 
 
 
 
2510
 
2511
- // A Pos instance represents a position within the text.
2512
- function Pos(line, ch, sticky) {
2513
- if ( sticky === void 0 ) sticky = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2514
 
2515
- if (!(this instanceof Pos)) { return new Pos(line, ch, sticky) }
2516
- this.line = line;
2517
- this.ch = ch;
2518
- this.sticky = sticky;
2519
- }
2520
 
2521
- // Compare two positions, return 0 if they are the same, a negative
2522
- // number when a is less, and a positive number otherwise.
2523
- function cmp(a, b) { return a.line - b.line || a.ch - b.ch }
2524
 
2525
- function equalCursorPos(a, b) { return a.sticky == b.sticky && cmp(a, b) == 0 }
 
 
2526
 
2527
- function copyPos(x) {return Pos(x.line, x.ch)}
2528
- function maxPos(a, b) { return cmp(a, b) < 0 ? b : a }
2529
- function minPos(a, b) { return cmp(a, b) < 0 ? a : b }
 
 
2530
 
2531
- // Most of the external API clips given positions to make sure they
2532
- // actually exist within the document.
2533
- function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1))}
2534
- function clipPos(doc, pos) {
2535
- if (pos.line < doc.first) { return Pos(doc.first, 0) }
2536
- var last = doc.first + doc.size - 1;
2537
- if (pos.line > last) { return Pos(last, getLine(doc, last).text.length) }
2538
- return clipToLen(pos, getLine(doc, pos.line).text.length)
2539
- }
2540
- function clipToLen(pos, linelen) {
2541
- var ch = pos.ch;
2542
- if (ch == null || ch > linelen) { return Pos(pos.line, linelen) }
2543
- else if (ch < 0) { return Pos(pos.line, 0) }
2544
- else { return pos }
2545
- }
2546
- function clipPosArray(doc, array) {
2547
- var out = [];
2548
- for (var i = 0; i < array.length; i++) { out[i] = clipPos(doc, array[i]); }
2549
- return out
2550
- }
2551
 
2552
- // Optimize some code when these features are not used.
2553
- var sawReadOnlySpans = false;
2554
- var sawCollapsedSpans = false;
2555
 
2556
- function seeReadOnlySpans() {
2557
- sawReadOnlySpans = true;
2558
- }
2559
 
2560
- function seeCollapsedSpans() {
2561
- sawCollapsedSpans = true;
2562
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2563
 
2564
- // TEXTMARKER SPANS
 
2565
 
2566
- function MarkedSpan(marker, from, to) {
2567
- this.marker = marker;
2568
- this.from = from; this.to = to;
2569
- }
2570
 
2571
- // Search an array of spans for a span matching the given marker.
2572
- function getMarkedSpanFor(spans, marker) {
2573
- if (spans) { for (var i = 0; i < spans.length; ++i) {
2574
- var span = spans[i];
2575
- if (span.marker == marker) { return span }
2576
- } }
2577
- }
2578
- // Remove a span from an array, returning undefined if no spans are
2579
- // left (we don't store arrays for lines without spans).
2580
- function removeMarkedSpan(spans, span) {
2581
- var r;
2582
- for (var i = 0; i < spans.length; ++i)
2583
- { if (spans[i] != span) { (r || (r = [])).push(spans[i]); } }
2584
- return r
2585
- }
2586
- // Add a span to a line.
2587
- function addMarkedSpan(line, span) {
2588
- line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
2589
- span.marker.attachLine(line);
2590
- }
2591
 
2592
- // Used for the algorithm that adjusts markers for a change in the
2593
- // document. These functions cut an array of spans at a given
2594
- // character position, returning an array of remaining chunks (or
2595
- // undefined if nothing remains).
2596
- function markedSpansBefore(old, startCh, isInsert) {
2597
- var nw;
2598
- if (old) { for (var i = 0; i < old.length; ++i) {
2599
- var span = old[i], marker = span.marker;
2600
- var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
2601
- if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) {
2602
- var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);(nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to));
2603
- }
2604
- } }
2605
- return nw
2606
- }
2607
- function markedSpansAfter(old, endCh, isInsert) {
2608
- var nw;
2609
- if (old) { for (var i = 0; i < old.length; ++i) {
2610
- var span = old[i], marker = span.marker;
2611
- var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
2612
- if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) {
2613
- var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);(nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh,
2614
- span.to == null ? null : span.to - endCh));
2615
- }
2616
- } }
2617
- return nw
2618
- }
2619
 
2620
- // Given a change object, compute the new set of marker spans that
2621
- // cover the line in which the change took place. Removes spans
2622
- // entirely within the change, reconnects spans belonging to the
2623
- // same marker that appear on both sides of the change, and cuts off
2624
- // spans partially within the change. Returns an array of span
2625
- // arrays with one element for each line in (after) the change.
2626
- function stretchSpansOverChange(doc, change) {
2627
- if (change.full) { return null }
2628
- var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
2629
- var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
2630
- if (!oldFirst && !oldLast) { return null }
2631
-
2632
- var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0;
2633
- // Get the spans that 'stick out' on both sides
2634
- var first = markedSpansBefore(oldFirst, startCh, isInsert);
2635
- var last = markedSpansAfter(oldLast, endCh, isInsert);
2636
-
2637
- // Next, merge those two ends
2638
- var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
2639
- if (first) {
2640
- // Fix up .to properties of first
2641
- for (var i = 0; i < first.length; ++i) {
2642
- var span = first[i];
2643
- if (span.to == null) {
2644
- var found = getMarkedSpanFor(last, span.marker);
2645
- if (!found) { span.to = startCh; }
2646
- else if (sameLine) { span.to = found.to == null ? null : found.to + offset; }
2647
- }
2648
- }
2649
- }
2650
- if (last) {
2651
- // Fix up .from in last (or move them into first in case of sameLine)
2652
- for (var i$1 = 0; i$1 < last.length; ++i$1) {
2653
- var span$1 = last[i$1];
2654
- if (span$1.to != null) { span$1.to += offset; }
2655
- if (span$1.from == null) {
2656
- var found$1 = getMarkedSpanFor(first, span$1.marker);
2657
- if (!found$1) {
2658
- span$1.from = offset;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2659
  if (sameLine) { (first || (first = [])).push(span$1); }
2660
  }
2661
- } else {
2662
- span$1.from += offset;
2663
- if (sameLine) { (first || (first = [])).push(span$1); }
2664
  }
2665
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2666
  }
2667
- // Make sure we didn't create any zero-length spans
2668
- if (first) { first = clearEmptySpans(first); }
2669
- if (last && last != first) { last = clearEmptySpans(last); }
2670
 
2671
- var newMarkers = [first];
2672
- if (!sameLine) {
2673
- // Fill gap with whole-line-spans
2674
- var gap = change.text.length - 2, gapMarkers;
2675
- if (gap > 0 && first)
2676
- { for (var i$2 = 0; i$2 < first.length; ++i$2)
2677
- { if (first[i$2].to == null)
2678
- { (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i$2].marker, null, null)); } } }
2679
- for (var i$3 = 0; i$3 < gap; ++i$3)
2680
- { newMarkers.push(gapMarkers); }
2681
- newMarkers.push(last);
2682
  }
2683
- return newMarkers
2684
- }
2685
 
2686
- // Remove spans that are empty and don't have a clearWhenEmpty
2687
- // option of false.
2688
- function clearEmptySpans(spans) {
2689
- for (var i = 0; i < spans.length; ++i) {
2690
- var span = spans[i];
2691
- if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false)
2692
- { spans.splice(i--, 1); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2693
  }
2694
- if (!spans.length) { return null }
2695
- return spans
2696
- }
2697
 
2698
- // Used to 'clip' out readOnly ranges when making a change.
2699
- function removeReadOnlyRanges(doc, from, to) {
2700
- var markers = null;
2701
- doc.iter(from.line, to.line + 1, function (line) {
2702
- if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) {
2703
- var mark = line.markedSpans[i].marker;
2704
- if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))
2705
- { (markers || (markers = [])).push(mark); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2706
  } }
2707
- });
2708
- if (!markers) { return null }
2709
- var parts = [{from: from, to: to}];
2710
- for (var i = 0; i < markers.length; ++i) {
2711
- var mk = markers[i], m = mk.find(0);
2712
- for (var j = 0; j < parts.length; ++j) {
2713
- var p = parts[j];
2714
- if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) { continue }
2715
- var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to);
2716
- if (dfrom < 0 || !mk.inclusiveLeft && !dfrom)
2717
- { newParts.push({from: p.from, to: m.from}); }
2718
- if (dto > 0 || !mk.inclusiveRight && !dto)
2719
- { newParts.push({from: m.to, to: p.to}); }
2720
- parts.splice.apply(parts, newParts);
2721
- j += newParts.length - 3;
2722
- }
2723
- }
2724
- return parts
2725
- }
2726
-
2727
- // Connect or disconnect spans from a line.
2728
- function detachMarkedSpans(line) {
2729
- var spans = line.markedSpans;
2730
- if (!spans) { return }
2731
- for (var i = 0; i < spans.length; ++i)
2732
- { spans[i].marker.detachLine(line); }
2733
- line.markedSpans = null;
2734
- }
2735
- function attachMarkedSpans(line, spans) {
2736
- if (!spans) { return }
2737
- for (var i = 0; i < spans.length; ++i)
2738
- { spans[i].marker.attachLine(line); }
2739
- line.markedSpans = spans;
2740
- }
2741
 
2742
- // Helpers used when computing which overlapping collapsed span
2743
- // counts as the larger one.
2744
- function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0 }
2745
- function extraRight(marker) { return marker.inclusiveRight ? 1 : 0 }
2746
-
2747
- // Returns a number indicating which of two overlapping collapsed
2748
- // spans is larger (and thus includes the other). Falls back to
2749
- // comparing ids when the spans cover exactly the same range.
2750
- function compareCollapsedMarkers(a, b) {
2751
- var lenDiff = a.lines.length - b.lines.length;
2752
- if (lenDiff != 0) { return lenDiff }
2753
- var aPos = a.find(), bPos = b.find();
2754
- var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b);
2755
- if (fromCmp) { return -fromCmp }
2756
- var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b);
2757
- if (toCmp) { return toCmp }
2758
- return b.id - a.id
2759
- }
2760
 
2761
- // Find out whether a line ends or starts in a collapsed span. If
2762
- // so, return the marker for that span.
2763
- function collapsedSpanAtSide(line, start) {
2764
- var sps = sawCollapsedSpans && line.markedSpans, found;
2765
- if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) {
2766
- sp = sps[i];
2767
- if (sp.marker.collapsed && (start ? sp.from : sp.to) == null &&
2768
- (!found || compareCollapsedMarkers(found, sp.marker) < 0))
2769
- { found = sp.marker; }
2770
- } }
2771
- return found
2772
- }
2773
- function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true) }
2774
- function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false) }
2775
-
2776
- function collapsedSpanAround(line, ch) {
2777
- var sps = sawCollapsedSpans && line.markedSpans, found;
2778
- if (sps) { for (var i = 0; i < sps.length; ++i) {
2779
- var sp = sps[i];
2780
- if (sp.marker.collapsed && (sp.from == null || sp.from < ch) && (sp.to == null || sp.to > ch) &&
2781
- (!found || compareCollapsedMarkers(found, sp.marker) < 0)) { found = sp.marker; }
2782
- } }
2783
- return found
2784
- }
2785
 
2786
- // Test whether there exists a collapsed span that partially
2787
- // overlaps (covers the start or end, but not both) of a new span.
2788
- // Such overlap is not allowed.
2789
- function conflictingCollapsedRange(doc, lineNo$$1, from, to, marker) {
2790
- var line = getLine(doc, lineNo$$1);
2791
- var sps = sawCollapsedSpans && line.markedSpans;
2792
- if (sps) { for (var i = 0; i < sps.length; ++i) {
2793
- var sp = sps[i];
2794
- if (!sp.marker.collapsed) { continue }
2795
- var found = sp.marker.find(0);
2796
- var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker);
2797
- var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker);
2798
- if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) { continue }
2799
- if (fromCmp <= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.to, from) >= 0 : cmp(found.to, from) > 0) ||
2800
- fromCmp >= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.from, to) <= 0 : cmp(found.from, to) < 0))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2801
  { return true }
2802
- } }
2803
- }
2804
-
2805
- // A visual line is a line as drawn on the screen. Folding, for
2806
- // example, can cause multiple logical lines to appear on the same
2807
- // visual line. This finds the start of the visual line that the
2808
- // given line is part of (usually that is the line itself).
2809
- function visualLine(line) {
2810
- var merged;
2811
- while (merged = collapsedSpanAtStart(line))
2812
- { line = merged.find(-1, true).line; }
2813
- return line
2814
- }
2815
-
2816
- function visualLineEnd(line) {
2817
- var merged;
2818
- while (merged = collapsedSpanAtEnd(line))
2819
- { line = merged.find(1, true).line; }
2820
- return line
2821
- }
2822
-
2823
- // Returns an array of logical lines that continue the visual line
2824
- // started by the argument, or undefined if there are no such lines.
2825
- function visualLineContinued(line) {
2826
- var merged, lines;
2827
- while (merged = collapsedSpanAtEnd(line)) {
2828
- line = merged.find(1, true).line
2829
- ;(lines || (lines = [])).push(line);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2830
  }
2831
- return lines
2832
- }
2833
-
2834
- // Get the line number of the start of the visual line that the
2835
- // given line number is part of.
2836
- function visualLineNo(doc, lineN) {
2837
- var line = getLine(doc, lineN), vis = visualLine(line);
2838
- if (line == vis) { return lineN }
2839
- return lineNo(vis)
2840
- }
2841
 
2842
- // Get the line number of the start of the next visual line after
2843
- // the given line.
2844
- function visualLineEndNo(doc, lineN) {
2845
- if (lineN > doc.lastLine()) { return lineN }
2846
- var line = getLine(doc, lineN), merged;
2847
- if (!lineIsHidden(doc, line)) { return lineN }
2848
- while (merged = collapsedSpanAtEnd(line))
2849
- { line = merged.find(1, true).line; }
2850
- return lineNo(line) + 1
2851
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2852
 
2853
- // Compute whether a line is hidden. Lines count as hidden when they
2854
- // are part of a visual line that starts with another line, or when
2855
- // they are entirely covered by collapsed, non-widget span.
2856
- function lineIsHidden(doc, line) {
2857
- var sps = sawCollapsedSpans && line.markedSpans;
2858
- if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) {
2859
- sp = sps[i];
2860
- if (!sp.marker.collapsed) { continue }
2861
- if (sp.from == null) { return true }
2862
- if (sp.marker.widgetNode) { continue }
2863
- if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))
2864
- { return true }
2865
- } }
2866
- }
2867
- function lineIsHiddenInner(doc, line, span) {
2868
- if (span.to == null) {
2869
- var end = span.marker.find(1, true);
2870
- return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker))
2871
- }
2872
- if (span.marker.inclusiveRight && span.to == line.text.length)
2873
- { return true }
2874
- for (var sp = (void 0), i = 0; i < line.markedSpans.length; ++i) {
2875
- sp = line.markedSpans[i];
2876
- if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to &&
2877
- (sp.to == null || sp.to != span.from) &&
2878
- (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
2879
- lineIsHiddenInner(doc, line, sp)) { return true }
2880
- }
2881
- }
2882
 
2883
- // Find the height above the given line.
2884
- function heightAtLine(lineObj) {
2885
- lineObj = visualLine(lineObj);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2886
 
2887
- var h = 0, chunk = lineObj.parent;
2888
- for (var i = 0; i < chunk.lines.length; ++i) {
2889
- var line = chunk.lines[i];
2890
- if (line == lineObj) { break }
2891
- else { h += line.height; }
2892
- }
2893
- for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {
2894
- for (var i$1 = 0; i$1 < p.children.length; ++i$1) {
2895
- var cur = p.children[i$1];
2896
- if (cur == chunk) { break }
2897
- else { h += cur.height; }
2898
  }
 
 
 
 
 
 
 
 
 
2899
  }
2900
- return h
2901
- }
2902
 
2903
- // Compute the character length of a line, taking into account
2904
- // collapsed ranges (see markText) that might hide parts, and join
2905
- // other lines onto it.
2906
- function lineLength(line) {
2907
- if (line.height == 0) { return 0 }
2908
- var len = line.text.length, merged, cur = line;
2909
- while (merged = collapsedSpanAtStart(cur)) {
2910
- var found = merged.find(0, true);
2911
- cur = found.from.line;
2912
- len += found.from.ch - found.to.ch;
2913
- }
2914
- cur = line;
2915
- while (merged = collapsedSpanAtEnd(cur)) {
2916
- var found$1 = merged.find(0, true);
2917
- len -= cur.text.length - found$1.from.ch;
2918
- cur = found$1.to.line;
2919
- len += cur.text.length - found$1.to.ch;
2920
- }
2921
- return len
2922
- }
2923
 
2924
- // Find the longest line in the document.
2925
- function findMaxLine(cm) {
2926
- var d = cm.display, doc = cm.doc;
2927
- d.maxLine = getLine(doc, doc.first);
2928
- d.maxLineLength = lineLength(d.maxLine);
2929
- d.maxLineChanged = true;
2930
- doc.iter(function (line) {
2931
- var len = lineLength(line);
2932
- if (len > d.maxLineLength) {
2933
- d.maxLineLength = len;
2934
- d.maxLine = line;
2935
- }
2936
- });
2937
- }
2938
 
2939
- // BIDI HELPERS
2940
 
2941
- function iterateBidiSections(order, from, to, f) {
2942
- if (!order) { return f(from, to, "ltr", 0) }
2943
- var found = false;
2944
- for (var i = 0; i < order.length; ++i) {
2945
- var part = order[i];
2946
- if (part.from < to && part.to > from || from == to && part.to == from) {
2947
- f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr", i);
2948
- found = true;
2949
  }
 
 
 
 
2950
  }
2951
- if (!found) { f(from, to, "ltr"); }
2952
- }
2953
 
2954
- var bidiOther = null;
2955
- function getBidiPartAt(order, ch, sticky) {
2956
- var found;
2957
- bidiOther = null;
2958
- for (var i = 0; i < order.length; ++i) {
2959
- var cur = order[i];
2960
- if (cur.from < ch && cur.to > ch) { return i }
2961
- if (cur.to == ch) {
2962
- if (cur.from != cur.to && sticky == "before") { found = i; }
2963
- else { bidiOther = i; }
2964
- }
2965
- if (cur.from == ch) {
2966
- if (cur.from != cur.to && sticky != "before") { found = i; }
2967
- else { bidiOther = i; }
2968
  }
2969
  }
2970
- return found != null ? found : bidiOther
2971
- }
2972
 
2973
- // Bidirectional ordering algorithm
2974
- // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm
2975
- // that this (partially) implements.
2976
-
2977
- // One-char codes used for character types:
2978
- // L (L): Left-to-Right
2979
- // R (R): Right-to-Left
2980
- // r (AL): Right-to-Left Arabic
2981
- // 1 (EN): European Number
2982
- // + (ES): European Number Separator
2983
- // % (ET): European Number Terminator
2984
- // n (AN): Arabic Number
2985
- // , (CS): Common Number Separator
2986
- // m (NSM): Non-Spacing Mark
2987
- // b (BN): Boundary Neutral
2988
- // s (B): Paragraph Separator
2989
- // t (S): Segment Separator
2990
- // w (WS): Whitespace
2991
- // N (ON): Other Neutrals
2992
-
2993
- // Returns null if characters are ordered as they appear
2994
- // (left-to-right), or an array of sections ({from, to, level}
2995
- // objects) in the order in which they occur visually.
2996
- var bidiOrdering = (function() {
2997
- // Character types for codepoints 0 to 0xff
2998
- var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN";
2999
- // Character types for codepoints 0x600 to 0x6f9
3000
- var arabicTypes = "nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111";
3001
- function charType(code) {
3002
- if (code <= 0xf7) { return lowTypes.charAt(code) }
3003
- else if (0x590 <= code && code <= 0x5f4) { return "R" }
3004
- else if (0x600 <= code && code <= 0x6f9) { return arabicTypes.charAt(code - 0x600) }
3005
- else if (0x6ee <= code && code <= 0x8ac) { return "r" }
3006
- else if (0x2000 <= code && code <= 0x200b) { return "w" }
3007
- else if (code == 0x200c) { return "b" }
3008
- else { return "L" }
3009
- }
3010
-
3011
- var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
3012
- var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;
3013
-
3014
- function BidiSpan(level, from, to) {
3015
- this.level = level;
3016
- this.from = from; this.to = to;
3017
  }
3018
 
3019
- return function(str, direction) {
3020
- var outerType = direction == "ltr" ? "L" : "R";
3021
-
3022
- if (str.length == 0 || direction == "ltr" && !bidiRE.test(str)) { return false }
3023
- var len = str.length, types = [];
3024
- for (var i = 0; i < len; ++i)
3025
- { types.push(charType(str.charCodeAt(i))); }
3026
-
3027
- // W1. Examine each non-spacing mark (NSM) in the level run, and
3028
- // change the type of the NSM to the type of the previous
3029
- // character. If the NSM is at the start of the level run, it will
3030
- // get the type of sor.
3031
- for (var i$1 = 0, prev = outerType; i$1 < len; ++i$1) {
3032
- var type = types[i$1];
3033
- if (type == "m") { types[i$1] = prev; }
3034
- else { prev = type; }
3035
- }
3036
-
3037
- // W2. Search backwards from each instance of a European number
3038
- // until the first strong type (R, L, AL, or sor) is found. If an
3039
- // AL is found, change the type of the European number to Arabic
3040
- // number.
3041
- // W3. Change all ALs to R.
3042
- for (var i$2 = 0, cur = outerType; i$2 < len; ++i$2) {
3043
- var type$1 = types[i$2];
3044
- if (type$1 == "1" && cur == "r") { types[i$2] = "n"; }
3045
- else if (isStrong.test(type$1)) { cur = type$1; if (type$1 == "r") { types[i$2] = "R"; } }
3046
- }
3047
-
3048
- // W4. A single European separator between two European numbers
3049
- // changes to a European number. A single common separator between
3050
- // two numbers of the same type changes to that type.
3051
- for (var i$3 = 1, prev$1 = types[0]; i$3 < len - 1; ++i$3) {
3052
- var type$2 = types[i$3];
3053
- if (type$2 == "+" && prev$1 == "1" && types[i$3+1] == "1") { types[i$3] = "1"; }
3054
- else if (type$2 == "," && prev$1 == types[i$3+1] &&
3055
- (prev$1 == "1" || prev$1 == "n")) { types[i$3] = prev$1; }
3056
- prev$1 = type$2;
3057
- }
3058
-
3059
- // W5. A sequence of European terminators adjacent to European
3060
- // numbers changes to all European numbers.
3061
- // W6. Otherwise, separators and terminators change to Other
3062
- // Neutral.
3063
- for (var i$4 = 0; i$4 < len; ++i$4) {
3064
- var type$3 = types[i$4];
3065
- if (type$3 == ",") { types[i$4] = "N"; }
3066
- else if (type$3 == "%") {
3067
- var end = (void 0);
3068
- for (end = i$4 + 1; end < len && types[end] == "%"; ++end) {}
3069
- var replace = (i$4 && types[i$4-1] == "!") || (end < len && types[end] == "1") ? "1" : "N";
3070
- for (var j = i$4; j < end; ++j) { types[j] = replace; }
3071
- i$4 = end - 1;
3072
- }
3073
- }
3074
-
3075
- // W7. Search backwards from each instance of a European number
3076
- // until the first strong type (R, L, or sor) is found. If an L is
3077
- // found, then change the type of the European number to L.
3078
- for (var i$5 = 0, cur$1 = outerType; i$5 < len; ++i$5) {
3079
- var type$4 = types[i$5];
3080
- if (cur$1 == "L" && type$4 == "1") { types[i$5] = "L"; }
3081
- else if (isStrong.test(type$4)) { cur$1 = type$4; }
3082
- }
3083
-
3084
- // N1. A sequence of neutrals takes the direction of the
3085
- // surrounding strong text if the text on both sides has the same
3086
- // direction. European and Arabic numbers act as if they were R in
3087
- // terms of their influence on neutrals. Start-of-level-run (sor)
3088
- // and end-of-level-run (eor) are used at level run boundaries.
3089
- // N2. Any remaining neutrals take the embedding direction.
3090
- for (var i$6 = 0; i$6 < len; ++i$6) {
3091
- if (isNeutral.test(types[i$6])) {
3092
- var end$1 = (void 0);
3093
- for (end$1 = i$6 + 1; end$1 < len && isNeutral.test(types[end$1]); ++end$1) {}
3094
- var before = (i$6 ? types[i$6-1] : outerType) == "L";
3095
- var after = (end$1 < len ? types[end$1] : outerType) == "L";
3096
- var replace$1 = before == after ? (before ? "L" : "R") : outerType;
3097
- for (var j$1 = i$6; j$1 < end$1; ++j$1) { types[j$1] = replace$1; }
3098
- i$6 = end$1 - 1;
3099
- }
3100
- }
3101
-
3102
- // Here we depart from the documented algorithm, in order to avoid
3103
- // building up an actual levels array. Since there are only three
3104
- // levels (0, 1, 2) in an implementation that doesn't take
3105
- // explicit embedding into account, we can build up the order on
3106
- // the fly, without following the level-based algorithm.
3107
- var order = [], m;
3108
- for (var i$7 = 0; i$7 < len;) {
3109
- if (countsAsLeft.test(types[i$7])) {
3110
- var start = i$7;
3111
- for (++i$7; i$7 < len && countsAsLeft.test(types[i$7]); ++i$7) {}
3112
- order.push(new BidiSpan(0, start, i$7));
3113
- } else {
3114
- var pos = i$7, at = order.length;
3115
- for (++i$7; i$7 < len && types[i$7] != "L"; ++i$7) {}
3116
- for (var j$2 = pos; j$2 < i$7;) {
3117
- if (countsAsNum.test(types[j$2])) {
3118
- if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)); }
3119
- var nstart = j$2;
3120
- for (++j$2; j$2 < i$7 && countsAsNum.test(types[j$2]); ++j$2) {}
3121
- order.splice(at, 0, new BidiSpan(2, nstart, j$2));
3122
- pos = j$2;
3123
- } else { ++j$2; }
3124
- }
3125
- if (pos < i$7) { order.splice(at, 0, new BidiSpan(1, pos, i$7)); }
3126
- }
3127
- }
3128
- if (direction == "ltr") {
3129
- if (order[0].level == 1 && (m = str.match(/^\s+/))) {
3130
- order[0].from = m[0].length;
3131
- order.unshift(new BidiSpan(0, 0, m[0].length));
3132
- }
3133
- if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
3134
- lst(order).to -= m[0].length;
3135
- order.push(new BidiSpan(0, len - m[0].length, len));
3136
- }
3137
- }
3138
-
3139
- return direction == "rtl" ? order.reverse() : order
3140
  }
3141
- })();
3142
 
3143
- // Get the bidi ordering for the given line (and cache it). Returns
3144
- // false for lines that are fully left-to-right, and an array of
3145
- // BidiSpan objects otherwise.
3146
- function getOrder(line, direction) {
3147
- var order = line.order;
3148
- if (order == null) { order = line.order = bidiOrdering(line.text, direction); }
3149
- return order
3150
- }
3151
 
3152
- // EVENT HANDLING
 
 
3153
 
3154
- // Lightweight event framework. on/off also work on DOM nodes,
3155
- // registering native DOM handlers.
 
 
 
 
3156
 
3157
- var noHandlers = [];
 
3158
 
3159
- var on = function(emitter, type, f) {
3160
- if (emitter.addEventListener) {
3161
- emitter.addEventListener(type, f, false);
3162
- } else if (emitter.attachEvent) {
3163
- emitter.attachEvent("on" + type, f);
3164
- } else {
3165
- var map$$1 = emitter._handlers || (emitter._handlers = {});
3166
- map$$1[type] = (map$$1[type] || noHandlers).concat(f);
3167
  }
3168
- };
3169
-
3170
- function getHandlers(emitter, type) {
3171
- return emitter._handlers && emitter._handlers[type] || noHandlers
3172
- }
 
 
 
3173
 
3174
- function off(emitter, type, f) {
3175
- if (emitter.removeEventListener) {
3176
- emitter.removeEventListener(type, f, false);
3177
- } else if (emitter.detachEvent) {
3178
- emitter.detachEvent("on" + type, f);
3179
- } else {
3180
- var map$$1 = emitter._handlers, arr = map$$1 && map$$1[type];
3181
- if (arr) {
3182
- var index = indexOf(arr, f);
3183
- if (index > -1)
3184
- { map$$1[type] = arr.slice(0, index).concat(arr.slice(index + 1)); }
3185
  }
 
 
3186
  }
3187
- }
3188
-
3189
- function signal(emitter, type /*, values...*/) {
3190
- var handlers = getHandlers(emitter, type);
3191
- if (!handlers.length) { return }
3192
- var args = Array.prototype.slice.call(arguments, 2);
3193
- for (var i = 0; i < handlers.length; ++i) { handlers[i].apply(null, args); }
3194
- }
3195
-
3196
- // The DOM events that CodeMirror handles can be overridden by
3197
- // registering a (non-DOM) handler on the editor for the event name,
3198
- // and preventDefault-ing the event in that handler.
3199
- function signalDOMEvent(cm, e, override) {
3200
- if (typeof e == "string")
3201
- { e = {type: e, preventDefault: function() { this.defaultPrevented = true; }}; }
3202
- signal(cm, override || e.type, cm, e);
3203
- return e_defaultPrevented(e) || e.codemirrorIgnore
3204
- }
3205
 
3206
- function signalCursorActivity(cm) {
3207
- var arr = cm._handlers && cm._handlers.cursorActivity;
3208
- if (!arr) { return }
3209
- var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []);
3210
- for (var i = 0; i < arr.length; ++i) { if (indexOf(set, arr[i]) == -1)
3211
- { set.push(arr[i]); } }
3212
- }
 
3213
 
3214
- function hasHandler(emitter, type) {
3215
- return getHandlers(emitter, type).length > 0
3216
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3217
 
3218
- // Add on and off methods to a constructor's prototype, to make
3219
- // registering events on such objects more convenient.
3220
- function eventMixin(ctor) {
3221
- ctor.prototype.on = function(type, f) {on(this, type, f);};
3222
- ctor.prototype.off = function(type, f) {off(this, type, f);};
3223
- }
 
 
 
 
3224
 
3225
- // Due to the fact that we still support jurassic IE versions, some
3226
- // compatibility wrappers are needed.
 
 
 
 
 
 
 
 
 
 
 
 
 
3227
 
3228
- function e_preventDefault(e) {
3229
- if (e.preventDefault) { e.preventDefault(); }
3230
- else { e.returnValue = false; }
3231
- }
3232
- function e_stopPropagation(e) {
3233
- if (e.stopPropagation) { e.stopPropagation(); }
3234
- else { e.cancelBubble = true; }
3235
- }
3236
- function e_defaultPrevented(e) {
3237
- return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false
3238
- }
3239
- function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
3240
-
3241
- function e_target(e) {return e.target || e.srcElement}
3242
- function e_button(e) {
3243
- var b = e.which;
3244
- if (b == null) {
3245
- if (e.button & 1) { b = 1; }
3246
- else if (e.button & 2) { b = 3; }
3247
- else if (e.button & 4) { b = 2; }
3248
- }
3249
- if (mac && e.ctrlKey && b == 1) { b = 3; }
3250
- return b
3251
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3252
 
3253
- // Detect drag-and-drop
3254
- var dragAndDrop = function() {
3255
- // There is *some* kind of drag-and-drop support in IE6-8, but I
3256
- // couldn't get it to work yet.
3257
- if (ie && ie_version < 9) { return false }
3258
- var div = elt('div');
3259
- return "draggable" in div || "dragDrop" in div
3260
- }();
3261
-
3262
- var zwspSupported;
3263
- function zeroWidthElement(measure) {
3264
- if (zwspSupported == null) {
3265
- var test = elt("span", "\u200b");
3266
- removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")]));
3267
- if (measure.firstChild.offsetHeight != 0)
3268
- { zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8); }
3269
- }
3270
- var node = zwspSupported ? elt("span", "\u200b") :
3271
- elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
3272
- node.setAttribute("cm-text", "");
3273
- return node
3274
- }
3275
 
3276
- // Feature-detect IE's crummy client rect reporting for bidi text
3277
- var badBidiRects;
3278
- function hasBadBidiRects(measure) {
3279
- if (badBidiRects != null) { return badBidiRects }
3280
- var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA"));
3281
- var r0 = range(txt, 0, 1).getBoundingClientRect();
3282
- var r1 = range(txt, 1, 2).getBoundingClientRect();
3283
- removeChildren(measure);
3284
- if (!r0 || r0.left == r0.right) { return false } // Safari returns null in some cases (#2780)
3285
- return badBidiRects = (r1.right - r0.right < 3)
3286
- }
 
 
 
 
 
 
 
 
 
 
3287
 
3288
- // See if "".split is the broken IE version, if so, provide an
3289
- // alternative way to split lines.
3290
- var splitLinesAuto = "\n\nb".split(/\n/).length != 3 ? function (string) {
3291
- var pos = 0, result = [], l = string.length;
3292
- while (pos <= l) {
3293
- var nl = string.indexOf("\n", pos);
3294
- if (nl == -1) { nl = string.length; }
3295
- var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl);
3296
- var rt = line.indexOf("\r");
3297
- if (rt != -1) {
3298
- result.push(line.slice(0, rt));
3299
- pos += rt + 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3300
  } else {
3301
- result.push(line);
3302
- pos = nl + 1;
3303
- }
3304
- }
3305
- return result
3306
- } : function (string) { return string.split(/\r\n?|\n/); };
3307
-
3308
- var hasSelection = window.getSelection ? function (te) {
3309
- try { return te.selectionStart != te.selectionEnd }
3310
- catch(e) { return false }
3311
- } : function (te) {
3312
- var range$$1;
3313
- try {range$$1 = te.ownerDocument.selection.createRange();}
3314
- catch(e) {}
3315
- if (!range$$1 || range$$1.parentElement() != te) { return false }
3316
- return range$$1.compareEndPoints("StartToEnd", range$$1) != 0
3317
- };
 
 
 
3318
 
3319
- var hasCopyEvent = (function () {
3320
- var e = elt("div");
3321
- if ("oncopy" in e) { return true }
3322
- e.setAttribute("oncopy", "return;");
3323
- return typeof e.oncopy == "function"
3324
- })();
3325
-
3326
- var badZoomedRects = null;
3327
- function hasBadZoomedRects(measure) {
3328
- if (badZoomedRects != null) { return badZoomedRects }
3329
- var node = removeChildrenAndAdd(measure, elt("span", "x"));
3330
- var normal = node.getBoundingClientRect();
3331
- var fromRange = range(node, 0, 1).getBoundingClientRect();
3332
- return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1
3333
- }
3334
 
3335
- // Known modes, by name and by MIME
3336
- var modes = {};
3337
- var mimeModes = {};
3338
-
3339
- // Extra arguments are stored as the mode's dependencies, which is
3340
- // used by (legacy) mechanisms like loadmode.js to automatically
3341
- // load a mode. (Preferred mechanism is the require/define calls.)
3342
- function defineMode(name, mode) {
3343
- if (arguments.length > 2)
3344
- { mode.dependencies = Array.prototype.slice.call(arguments, 2); }
3345
- modes[name] = mode;
3346
- }
3347
 
3348
- function defineMIME(mime, spec) {
3349
- mimeModes[mime] = spec;
3350
- }
 
 
3351
 
3352
- // Given a MIME type, a {name, ...options} config object, or a name
3353
- // string, return a mode config object.
3354
- function resolveMode(spec) {
3355
- if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
3356
- spec = mimeModes[spec];
3357
- } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
3358
- var found = mimeModes[spec.name];
3359
- if (typeof found == "string") { found = {name: found}; }
3360
- spec = createObj(found, spec);
3361
- spec.name = found.name;
3362
- } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
3363
- return resolveMode("application/xml")
3364
- } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+json$/.test(spec)) {
3365
- return resolveMode("application/json")
3366
- }
3367
- if (typeof spec == "string") { return {name: spec} }
3368
- else { return spec || {name: "null"} }
3369
- }
3370
 
3371
- // Given a mode spec (anything that resolveMode accepts), find and
3372
- // initialize an actual mode object.
3373
- function getMode(options, spec) {
3374
- spec = resolveMode(spec);
3375
- var mfactory = modes[spec.name];
3376
- if (!mfactory) { return getMode(options, "text/plain") }
3377
- var modeObj = mfactory(options, spec);
3378
- if (modeExtensions.hasOwnProperty(spec.name)) {
3379
- var exts = modeExtensions[spec.name];
3380
- for (var prop in exts) {
3381
- if (!exts.hasOwnProperty(prop)) { continue }
3382
- if (modeObj.hasOwnProperty(prop)) { modeObj["_" + prop] = modeObj[prop]; }
3383
- modeObj[prop] = exts[prop];
3384
- }
3385
- }
3386
- modeObj.name = spec.name;
3387
- if (spec.helperType) { modeObj.helperType = spec.helperType; }
3388
- if (spec.modeProps) { for (var prop$1 in spec.modeProps)
3389
- { modeObj[prop$1] = spec.modeProps[prop$1]; } }
3390
-
3391
- return modeObj
3392
- }
3393
 
3394
- // This can be used to attach properties to mode objects from
3395
- // outside the actual mode definition.
3396
- var modeExtensions = {};
3397
- function extendMode(mode, properties) {
3398
- var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
3399
- copyObj(properties, exts);
3400
- }
3401
 
3402
- function copyState(mode, state) {
3403
- if (state === true) { return state }
3404
- if (mode.copyState) { return mode.copyState(state) }
3405
- var nstate = {};
3406
- for (var n in state) {
3407
- var val = state[n];
3408
- if (val instanceof Array) { val = val.concat([]); }
3409
- nstate[n] = val;
3410
- }
3411
- return nstate
3412
- }
3413
 
3414
- // Given a mode and a state (for that mode), find the inner mode and
3415
- // state at the position that the state refers to.
3416
- function innerMode(mode, state) {
3417
- var info;
3418
- while (mode.innerMode) {
3419
- info = mode.innerMode(state);
3420
- if (!info || info.mode == mode) { break }
3421
- state = info.state;
3422
- mode = info.mode;
3423
- }
3424
- return info || {mode: mode, state: state}
3425
- }
3426
 
3427
- function startState(mode, a1, a2) {
3428
- return mode.startState ? mode.startState(a1, a2) : true
3429
- }
3430
 
3431
- // STRING STREAM
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3432
 
3433
- // Fed to the mode parsers, provides helper functions to make
3434
- // parsers more succinct.
3435
 
3436
- var StringStream = function(string, tabSize, lineOracle) {
3437
- this.pos = this.start = 0;
3438
- this.string = string;
3439
- this.tabSize = tabSize || 8;
3440
- this.lastColumnPos = this.lastColumnValue = 0;
3441
- this.lineStart = 0;
3442
- this.lineOracle = lineOracle;
3443
- };
3444
 
3445
- StringStream.prototype.eol = function () {return this.pos >= this.string.length};
3446
- StringStream.prototype.sol = function () {return this.pos == this.lineStart};
3447
- StringStream.prototype.peek = function () {return this.string.charAt(this.pos) || undefined};
3448
- StringStream.prototype.next = function () {
3449
- if (this.pos < this.string.length)
3450
- { return this.string.charAt(this.pos++) }
3451
- };
3452
- StringStream.prototype.eat = function (match) {
3453
- var ch = this.string.charAt(this.pos);
3454
- var ok;
3455
- if (typeof match == "string") { ok = ch == match; }
3456
- else { ok = ch && (match.test ? match.test(ch) : match(ch)); }
3457
- if (ok) {++this.pos; return ch}
3458
- };
3459
- StringStream.prototype.eatWhile = function (match) {
3460
- var start = this.pos;
3461
- while (this.eat(match)){}
3462
- return this.pos > start
3463
- };
3464
- StringStream.prototype.eatSpace = function () {
3465
- var this$1 = this;
 
 
 
 
 
 
 
 
 
 
 
3466
 
3467
- var start = this.pos;
3468
- while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this$1.pos; }
3469
- return this.pos > start
3470
- };
3471
- StringStream.prototype.skipToEnd = function () {this.pos = this.string.length;};
3472
- StringStream.prototype.skipTo = function (ch) {
3473
- var found = this.string.indexOf(ch, this.pos);
3474
- if (found > -1) {this.pos = found; return true}
3475
- };
3476
- StringStream.prototype.backUp = function (n) {this.pos -= n;};
3477
- StringStream.prototype.column = function () {
3478
- if (this.lastColumnPos < this.start) {
3479
- this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
3480
- this.lastColumnPos = this.start;
3481
  }
3482
- return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
3483
- };
3484
- StringStream.prototype.indentation = function () {
3485
- return countColumn(this.string, null, this.tabSize) -
3486
- (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
3487
- };
3488
- StringStream.prototype.match = function (pattern, consume, caseInsensitive) {
3489
- if (typeof pattern == "string") {
3490
- var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; };
3491
- var substr = this.string.substr(this.pos, pattern.length);
3492
- if (cased(substr) == cased(pattern)) {
3493
- if (consume !== false) { this.pos += pattern.length; }
3494
- return true
3495
  }
3496
- } else {
3497
- var match = this.string.slice(this.pos).match(pattern);
3498
- if (match && match.index > 0) { return null }
3499
- if (match && consume !== false) { this.pos += match[0].length; }
3500
- return match
3501
  }
3502
- };
3503
- StringStream.prototype.current = function (){return this.string.slice(this.start, this.pos)};
3504
- StringStream.prototype.hideFirstChars = function (n, inner) {
3505
- this.lineStart += n;
3506
- try { return inner() }
3507
- finally { this.lineStart -= n; }
3508
- };
3509
- StringStream.prototype.lookAhead = function (n) {
3510
- var oracle = this.lineOracle;
3511
- return oracle && oracle.lookAhead(n)
3512
- };
3513
- StringStream.prototype.baseToken = function () {
3514
- var oracle = this.lineOracle;
3515
- return oracle && oracle.baseToken(this.pos)
3516
- };
3517
 
3518
- var SavedContext = function(state, lookAhead) {
3519
- this.state = state;
3520
- this.lookAhead = lookAhead;
3521
- };
 
 
3522
 
3523
- var Context = function(doc, state, line, lookAhead) {
3524
- this.state = state;
3525
- this.doc = doc;
3526
- this.line = line;
3527
- this.maxLookAhead = lookAhead || 0;
3528
- this.baseTokens = null;
3529
- this.baseTokenPos = 1;
3530
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3531
 
3532
- Context.prototype.lookAhead = function (n) {
3533
- var line = this.doc.getLine(this.line + n);
3534
- if (line != null && n > this.maxLookAhead) { this.maxLookAhead = n; }
3535
- return line
3536
- };
3537
 
3538
- Context.prototype.baseToken = function (n) {
3539
- var this$1 = this;
 
 
 
 
 
3540
 
3541
- if (!this.baseTokens) { return null }
3542
- while (this.baseTokens[this.baseTokenPos] <= n)
3543
- { this$1.baseTokenPos += 2; }
3544
- var type = this.baseTokens[this.baseTokenPos + 1];
3545
- return {type: type && type.replace(/( |^)overlay .*/, ""),
3546
- size: this.baseTokens[this.baseTokenPos] - n}
3547
- };
3548
 
3549
- Context.prototype.nextLine = function () {
3550
- this.line++;
3551
- if (this.maxLookAhead > 0) { this.maxLookAhead--; }
3552
- };
 
 
 
 
 
 
 
 
 
3553
 
3554
- Context.fromSaved = function (doc, saved, line) {
3555
- if (saved instanceof SavedContext)
3556
- { return new Context(doc, copyState(doc.mode, saved.state), line, saved.lookAhead) }
3557
- else
3558
- { return new Context(doc, copyState(doc.mode, saved), line) }
3559
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3560
 
3561
- Context.prototype.save = function (copy) {
3562
- var state = copy !== false ? copyState(this.doc.mode, this.state) : this.state;
3563
- return this.maxLookAhead > 0 ? new SavedContext(state, this.maxLookAhead) : state
3564
- };
 
 
3565
 
 
 
 
3566
 
3567
- // Compute a style array (an array starting with a mode generation
3568
- // -- for invalidation -- followed by pairs of end positions and
3569
- // style strings), which is used to highlight the tokens on the
3570
- // line.
3571
- function highlightLine(cm, line, context, forceToEnd) {
3572
- // A styles array always starts with a number identifying the
3573
- // mode/overlays that it is based on (for easy invalidation).
3574
- var st = [cm.state.modeGen], lineClasses = {};
3575
- // Compute the base array of styles
3576
- runMode(cm, line.text, cm.doc.mode, context, function (end, style) { return st.push(end, style); },
3577
- lineClasses, forceToEnd);
3578
- var state = context.state;
3579
-
3580
- // Run overlays, adjust style array.
3581
- var loop = function ( o ) {
3582
- context.baseTokens = st;
3583
- var overlay = cm.state.overlays[o], i = 1, at = 0;
3584
- context.state = true;
3585
- runMode(cm, line.text, overlay.mode, context, function (end, style) {
3586
- var start = i;
3587
- // Ensure there's a token end at the current position, and that i points at it
3588
- while (at < end) {
3589
- var i_end = st[i];
3590
- if (i_end > end)
3591
- { st.splice(i, 1, end, st[i+1], i_end); }
3592
- i += 2;
3593
- at = Math.min(end, i_end);
3594
- }
3595
- if (!style) { return }
3596
- if (overlay.opaque) {
3597
- st.splice(start, i - start, end, "overlay " + style);
3598
- i = start + 2;
3599
- } else {
3600
- for (; start < i; start += 2) {
3601
- var cur = st[start+1];
3602
- st[start+1] = (cur ? cur + " " : "") + "overlay " + style;
 
3603
  }
3604
- }
3605
- }, lineClasses);
3606
- context.state = state;
3607
- context.baseTokens = null;
3608
- context.baseTokenPos = 1;
3609
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3610
 
3611
- for (var o = 0; o < cm.state.overlays.length; ++o) loop( o );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3612
 
3613
- return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null}
3614
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
3615
 
3616
- function getLineStyles(cm, line, updateFrontier) {
3617
- if (!line.styles || line.styles[0] != cm.state.modeGen) {
3618
- var context = getContextBefore(cm, lineNo(line));
3619
- var resetState = line.text.length > cm.options.maxHighlightLength && copyState(cm.doc.mode, context.state);
3620
- var result = highlightLine(cm, line, context);
3621
- if (resetState) { context.state = resetState; }
3622
- line.stateAfter = context.save(!resetState);
3623
- line.styles = result.styles;
3624
- if (result.classes) { line.styleClasses = result.classes; }
3625
- else if (line.styleClasses) { line.styleClasses = null; }
3626
- if (updateFrontier === cm.doc.highlightFrontier)
3627
- { cm.doc.modeFrontier = Math.max(cm.doc.modeFrontier, ++cm.doc.highlightFrontier); }
3628
- }
3629
- return line.styles
3630
- }
3631
 
3632
- function getContextBefore(cm, n, precise) {
3633
- var doc = cm.doc, display = cm.display;
3634
- if (!doc.mode.startState) { return new Context(doc, true, n) }
3635
- var start = findStartLine(cm, n, precise);
3636
- var saved = start > doc.first && getLine(doc, start - 1).stateAfter;
3637
- var context = saved ? Context.fromSaved(doc, saved, start) : new Context(doc, startState(doc.mode), start);
3638
-
3639
- doc.iter(start, n, function (line) {
3640
- processLine(cm, line.text, context);
3641
- var pos = context.line;
3642
- line.stateAfter = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo ? context.save() : null;
3643
- context.nextLine();
3644
- });
3645
- if (precise) { doc.modeFrontier = context.line; }
3646
- return context
3647
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3648
 
3649
- // Lightweight form of highlight -- proceed over this line and
3650
- // update state, but don't save a style array. Used for lines that
3651
- // aren't currently visible.
3652
- function processLine(cm, text, context, startAt) {
3653
- var mode = cm.doc.mode;
3654
- var stream = new StringStream(text, cm.options.tabSize, context);
3655
- stream.start = stream.pos = startAt || 0;
3656
- if (text == "") { callBlankLine(mode, context.state); }
3657
- while (!stream.eol()) {
3658
- readToken(mode, stream, context.state);
3659
- stream.start = stream.pos;
 
 
 
 
 
 
3660
  }
3661
- }
3662
 
3663
- function callBlankLine(mode, state) {
3664
- if (mode.blankLine) { return mode.blankLine(state) }
3665
- if (!mode.innerMode) { return }
3666
- var inner = innerMode(mode, state);
3667
- if (inner.mode.blankLine) { return inner.mode.blankLine(inner.state) }
3668
- }
3669
 
3670
- function readToken(mode, stream, state, inner) {
3671
- for (var i = 0; i < 10; i++) {
3672
- if (inner) { inner[0] = innerMode(mode, state).mode; }
3673
- var style = mode.token(stream, state);
3674
- if (stream.pos > stream.start) { return style }
 
 
 
 
 
 
 
3675
  }
3676
- throw new Error("Mode " + mode.name + " failed to advance stream.")
3677
- }
3678
 
3679
- var Token = function(stream, type, state) {
3680
- this.start = stream.start; this.end = stream.pos;
3681
- this.string = stream.current();
3682
- this.type = type || null;
3683
- this.state = state;
3684
- };
 
 
 
 
3685
 
3686
- // Utility for getTokenAt and getLineTokens
3687
- function takeToken(cm, pos, precise, asArray) {
3688
- var doc = cm.doc, mode = doc.mode, style;
3689
- pos = clipPos(doc, pos);
3690
- var line = getLine(doc, pos.line), context = getContextBefore(cm, pos.line, precise);
3691
- var stream = new StringStream(line.text, cm.options.tabSize, context), tokens;
3692
- if (asArray) { tokens = []; }
3693
- while ((asArray || stream.pos < pos.ch) && !stream.eol()) {
3694
- stream.start = stream.pos;
3695
- style = readToken(mode, stream, context.state);
3696
- if (asArray) { tokens.push(new Token(stream, style, copyState(doc.mode, context.state))); }
3697
- }
3698
- return asArray ? tokens : new Token(stream, style, context.state)
3699
- }
3700
 
3701
- function extractLineClasses(type, output) {
3702
- if (type) { for (;;) {
3703
- var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/);
3704
- if (!lineClass) { break }
3705
- type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length);
3706
- var prop = lineClass[1] ? "bgClass" : "textClass";
3707
- if (output[prop] == null)
3708
- { output[prop] = lineClass[2]; }
3709
- else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop]))
3710
- { output[prop] += " " + lineClass[2]; }
3711
- } }
3712
- return type
3713
- }
3714
 
3715
- // Run the given mode's parser over a line, calling f for each token.
3716
- function runMode(cm, text, mode, context, f, lineClasses, forceToEnd) {
3717
- var flattenSpans = mode.flattenSpans;
3718
- if (flattenSpans == null) { flattenSpans = cm.options.flattenSpans; }
3719
- var curStart = 0, curStyle = null;
3720
- var stream = new StringStream(text, cm.options.tabSize, context), style;
3721
- var inner = cm.options.addModeClass && [null];
3722
- if (text == "") { extractLineClasses(callBlankLine(mode, context.state), lineClasses); }
3723
- while (!stream.eol()) {
3724
- if (stream.pos > cm.options.maxHighlightLength) {
3725
- flattenSpans = false;
3726
- if (forceToEnd) { processLine(cm, text, context, stream.pos); }
3727
- stream.pos = text.length;
3728
- style = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3729
  } else {
3730
- style = extractLineClasses(readToken(mode, stream, context.state, inner), lineClasses);
 
3731
  }
3732
- if (inner) {
3733
- var mName = inner[0].name;
3734
- if (mName) { style = "m-" + (style ? mName + " " + style : mName); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3735
  }
3736
- if (!flattenSpans || curStyle != style) {
3737
- while (curStart < stream.start) {
3738
- curStart = Math.min(stream.start, curStart + 5000);
3739
- f(curStart, curStyle);
3740
- }
3741
- curStyle = style;
 
 
3742
  }
3743
- stream.start = stream.pos;
3744
  }
3745
- while (curStart < stream.pos) {
3746
- // Webkit seems to refuse to render text nodes longer than 57444
3747
- // characters, and returns inaccurate measurements in nodes
3748
- // starting around 5000 chars.
3749
- var pos = Math.min(stream.pos, curStart + 5000);
3750
- f(pos, curStyle);
3751
- curStart = pos;
 
 
 
 
 
3752
  }
3753
- }
3754
 
3755
- // Finds the line to start with when starting a parse. Tries to
3756
- // find a line with a stateAfter, so that it can start with a
3757
- // valid state. If that fails, it returns the line with the
3758
- // smallest indentation, which tends to need the least context to
3759
- // parse correctly.
3760
- function findStartLine(cm, n, precise) {
3761
- var minindent, minline, doc = cm.doc;
3762
- var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100);
3763
- for (var search = n; search > lim; --search) {
3764
- if (search <= doc.first) { return doc.first }
3765
- var line = getLine(doc, search - 1), after = line.stateAfter;
3766
- if (after && (!precise || search + (after instanceof SavedContext ? after.lookAhead : 0) <= doc.modeFrontier))
3767
- { return search }
3768
- var indented = countColumn(line.text, null, cm.options.tabSize);
3769
- if (minline == null || minindent > indented) {
3770
- minline = search - 1;
3771
- minindent = indented;
3772
- }
3773
- }
3774
- return minline
3775
- }
3776
 
3777
- function retreatFrontier(doc, n) {
3778
- doc.modeFrontier = Math.min(doc.modeFrontier, n);
3779
- if (doc.highlightFrontier < n - 10) { return }
3780
- var start = doc.first;
3781
- for (var line = n - 1; line > start; line--) {
3782
- var saved = getLine(doc, line).stateAfter;
3783
- // change is on 3
3784
- // state on line 1 looked ahead 2 -- so saw 3
3785
- // test 1 + 2 < 3 should cover this
3786
- if (saved && (!(saved instanceof SavedContext) || line + saved.lookAhead < n)) {
3787
- start = line + 1;
3788
- break
3789
- }
3790
- }
3791
- doc.highlightFrontier = Math.min(doc.highlightFrontier, start);
3792
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3793
 
3794
- // LINE DATA STRUCTURE
 
 
 
 
 
 
3795
 
3796
- // Line objects. These hold state related to a line, including
3797
- // highlighting info (the styles array).
3798
- var Line = function(text, markedSpans, estimateHeight) {
3799
- this.text = text;
3800
- attachMarkedSpans(this, markedSpans);
3801
- this.height = estimateHeight ? estimateHeight(this) : 1;
3802
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3803
 
3804
- Line.prototype.lineNo = function () { return lineNo(this) };
3805
- eventMixin(Line);
3806
-
3807
- // Change the content (text, markers) of a line. Automatically
3808
- // invalidates cached information and tries to re-estimate the
3809
- // line's height.
3810
- function updateLine(line, text, markedSpans, estimateHeight) {
3811
- line.text = text;
3812
- if (line.stateAfter) { line.stateAfter = null; }
3813
- if (line.styles) { line.styles = null; }
3814
- if (line.order != null) { line.order = null; }
3815
- detachMarkedSpans(line);
3816
- attachMarkedSpans(line, markedSpans);
3817
- var estHeight = estimateHeight ? estimateHeight(line) : 1;
3818
- if (estHeight != line.height) { updateLineHeight(line, estHeight); }
3819
- }
3820
 
3821
- // Detach a line from the document tree and its markers.
3822
- function cleanUpLine(line) {
3823
- line.parent = null;
3824
- detachMarkedSpans(line);
3825
- }
3826
 
3827
- // Convert a style as returned by a mode (either null, or a string
3828
- // containing one or more styles) to a CSS style. This is cached,
3829
- // and also looks for line-wide styles.
3830
- var styleToClassCache = {};
3831
- var styleToClassCacheWithMode = {};
3832
- function interpretTokenStyle(style, options) {
3833
- if (!style || /^\s*$/.test(style)) { return null }
3834
- var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache;
3835
- return cache[style] ||
3836
- (cache[style] = style.replace(/\S+/g, "cm-$&"))
3837
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3838
 
3839
- // Render the DOM representation of the text of a line. Also builds
3840
- // up a 'line map', which points at the DOM nodes that represent
3841
- // specific stretches of text, and is used by the measuring code.
3842
- // The returned object contains the DOM node, this map, and
3843
- // information about line-wide styles that were set by the mode.
3844
- function buildLineContent(cm, lineView) {
3845
- // The padding-right forces the element to have a 'border', which
3846
- // is needed on Webkit to be able to get line-level bounding
3847
- // rectangles for it (in measureChar).
3848
- var content = eltP("span", null, null, webkit ? "padding-right: .1px" : null);
3849
- var builder = {pre: eltP("pre", [content], "CodeMirror-line"), content: content,
3850
- col: 0, pos: 0, cm: cm,
3851
- trailingSpace: false,
3852
- splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")};
3853
- lineView.measure = {};
3854
-
3855
- // Iterate over the logical lines that make up this visual line.
3856
- for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) {
3857
- var line = i ? lineView.rest[i - 1] : lineView.line, order = (void 0);
3858
- builder.pos = 0;
3859
- builder.addToken = buildToken;
3860
- // Optionally wire in some hacks into the token-rendering
3861
- // algorithm, to deal with browser quirks.
3862
- if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line, cm.doc.direction)))
3863
- { builder.addToken = buildTokenBadBidi(builder.addToken, order); }
3864
- builder.map = [];
3865
- var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line);
3866
- insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate));
3867
- if (line.styleClasses) {
3868
- if (line.styleClasses.bgClass)
3869
- { builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || ""); }
3870
- if (line.styleClasses.textClass)
3871
- { builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || ""); }
3872
- }
3873
-
3874
- // Ensure at least a single node is present, for measuring.
3875
- if (builder.map.length == 0)
3876
- { builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))); }
3877
-
3878
- // Store the map and a cache object for the current logical line
3879
- if (i == 0) {
3880
- lineView.measure.map = builder.map;
3881
  lineView.measure.cache = {};
3882
- } else {
3883
- (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map)
3884
- ;(lineView.measure.caches || (lineView.measure.caches = [])).push({});
3885
  }
3886
  }
3887
 
3888
- // See issue #2901
3889
- if (webkit) {
3890
- var last = builder.content.lastChild;
3891
- if (/\bcm-tab\b/.test(last.className) || (last.querySelector && last.querySelector(".cm-tab")))
3892
- { builder.content.className = "cm-tab-wrap-hack"; }
3893
  }
3894
 
3895
- signal(cm, "renderLine", cm, lineView.line, builder.pre);
3896
- if (builder.pre.className)
3897
- { builder.textClass = joinClasses(builder.pre.className, builder.textClass || ""); }
3898
-
3899
- return builder
3900
- }
3901
 
3902
- function defaultSpecialCharPlaceholder(ch) {
3903
- var token = elt("span", "\u2022", "cm-invalidchar");
3904
- token.title = "\\u" + ch.charCodeAt(0).toString(16);
3905
- token.setAttribute("aria-label", token.title);
3906
- return token
3907
- }
 
 
 
 
 
3908
 
3909
- // Build up the DOM representation for a single token, and add it to
3910
- // the line map. Takes care to render special characters separately.
3911
- function buildToken(builder, text, style, startStyle, endStyle, title, css) {
3912
- if (!text) { return }
3913
- var displayText = builder.splitSpaces ? splitSpaces(text, builder.trailingSpace) : text;
3914
- var special = builder.cm.state.specialChars, mustWrap = false;
3915
- var content;
3916
- if (!special.test(text)) {
3917
- builder.col += text.length;
3918
- content = document.createTextNode(displayText);
3919
- builder.map.push(builder.pos, builder.pos + text.length, content);
3920
- if (ie && ie_version < 9) { mustWrap = true; }
3921
- builder.pos += text.length;
3922
- } else {
3923
- content = document.createDocumentFragment();
3924
- var pos = 0;
3925
- while (true) {
3926
- special.lastIndex = pos;
3927
- var m = special.exec(text);
3928
- var skipped = m ? m.index - pos : text.length - pos;
3929
- if (skipped) {
3930
- var txt = document.createTextNode(displayText.slice(pos, pos + skipped));
3931
- if (ie && ie_version < 9) { content.appendChild(elt("span", [txt])); }
3932
- else { content.appendChild(txt); }
3933
- builder.map.push(builder.pos, builder.pos + skipped, txt);
3934
- builder.col += skipped;
3935
- builder.pos += skipped;
3936
- }
3937
- if (!m) { break }
3938
- pos += skipped + 1;
3939
- var txt$1 = (void 0);
3940
- if (m[0] == "\t") {
3941
- var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
3942
- txt$1 = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
3943
- txt$1.setAttribute("role", "presentation");
3944
- txt$1.setAttribute("cm-text", "\t");
3945
- builder.col += tabWidth;
3946
- } else if (m[0] == "\r" || m[0] == "\n") {
3947
- txt$1 = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar"));
3948
- txt$1.setAttribute("cm-text", m[0]);
3949
- builder.col += 1;
3950
- } else {
3951
- txt$1 = builder.cm.options.specialCharPlaceholder(m[0]);
3952
- txt$1.setAttribute("cm-text", m[0]);
3953
- if (ie && ie_version < 9) { content.appendChild(elt("span", [txt$1])); }
3954
- else { content.appendChild(txt$1); }
3955
- builder.col += 1;
3956
- }
3957
- builder.map.push(builder.pos, builder.pos + 1, txt$1);
3958
- builder.pos++;
3959
- }
3960
- }
3961
- builder.trailingSpace = displayText.charCodeAt(text.length - 1) == 32;
3962
- if (style || startStyle || endStyle || mustWrap || css) {
3963
- var fullStyle = style || "";
3964
- if (startStyle) { fullStyle += startStyle; }
3965
- if (endStyle) { fullStyle += endStyle; }
3966
- var token = elt("span", [content], fullStyle, css);
3967
- if (title) { token.title = title; }
3968
- return builder.content.appendChild(token)
3969
- }
3970
- builder.content.appendChild(content);
3971
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3972
 
3973
- function splitSpaces(text, trailingBefore) {
3974
- if (text.length > 1 && !/ /.test(text)) { return text }
3975
- var spaceBefore = trailingBefore, result = "";
3976
- for (var i = 0; i < text.length; i++) {
3977
- var ch = text.charAt(i);
3978
- if (ch == " " && spaceBefore && (i == text.length - 1 || text.charCodeAt(i + 1) == 32))
3979
- { ch = "\u00a0"; }
3980
- result += ch;
3981
- spaceBefore = ch == " ";
3982
- }
3983
- return result
3984
- }
3985
 
3986
- // Work around nonsense dimensions being reported for stretches of
3987
- // right-to-left text.
3988
- function buildTokenBadBidi(inner, order) {
3989
- return function (builder, text, style, startStyle, endStyle, title, css) {
3990
- style = style ? style + " cm-force-border" : "cm-force-border";
3991
- var start = builder.pos, end = start + text.length;
3992
  for (;;) {
3993
- // Find the part that overlaps with the start of this text
3994
- var part = (void 0);
3995
- for (var i = 0; i < order.length; i++) {
3996
- part = order[i];
3997
- if (part.to > start && part.from <= start) { break }
3998
- }
3999
- if (part.to >= end) { return inner(builder, text, style, startStyle, endStyle, title, css) }
4000
- inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css);
4001
- startStyle = null;
4002
- text = text.slice(part.to - start);
4003
- start = part.to;
4004
  }
4005
  }
4006
- }
4007
 
4008
- function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
4009
- var widget = !ignoreWidget && marker.widgetNode;
4010
- if (widget) { builder.map.push(builder.pos, builder.pos + size, widget); }
4011
- if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) {
4012
- if (!widget)
4013
- { widget = builder.content.appendChild(document.createElement("span")); }
4014
- widget.setAttribute("cm-marker", marker.id);
4015
  }
4016
- if (widget) {
4017
- builder.cm.display.input.setUneditable(widget);
4018
- builder.content.appendChild(widget);
 
 
4019
  }
4020
- builder.pos += size;
4021
- builder.trailingSpace = false;
4022
- }
4023
 
4024
- // Outputs a number of spans to make up a line, taking highlighting
4025
- // and marked text into account.
4026
- function insertLineContent(line, builder, styles) {
4027
- var spans = line.markedSpans, allText = line.text, at = 0;
4028
- if (!spans) {
4029
- for (var i$1 = 1; i$1 < styles.length; i$1+=2)
4030
- { builder.addToken(builder, allText.slice(at, at = styles[i$1]), interpretTokenStyle(styles[i$1+1], builder.cm.options)); }
4031
- return
4032
- }
4033
-
4034
- var len = allText.length, pos = 0, i = 1, text = "", style, css;
4035
- var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
4036
- for (;;) {
4037
- if (nextChange == pos) { // Update current marker set
4038
- spanStyle = spanEndStyle = spanStartStyle = title = css = "";
4039
- collapsed = null; nextChange = Infinity;
4040
- var foundBookmarks = [], endStyles = (void 0);
4041
- for (var j = 0; j < spans.length; ++j) {
4042
- var sp = spans[j], m = sp.marker;
4043
- if (m.type == "bookmark" && sp.from == pos && m.widgetNode) {
4044
- foundBookmarks.push(m);
4045
- } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) {
4046
- if (sp.to != null && sp.to != pos && nextChange > sp.to) {
4047
- nextChange = sp.to;
4048
- spanEndStyle = "";
4049
- }
4050
- if (m.className) { spanStyle += " " + m.className; }
4051
- if (m.css) { css = (css ? css + ";" : "") + m.css; }
4052
- if (m.startStyle && sp.from == pos) { spanStartStyle += " " + m.startStyle; }
4053
- if (m.endStyle && sp.to == nextChange) { (endStyles || (endStyles = [])).push(m.endStyle, sp.to); }
4054
- if (m.title && !title) { title = m.title; }
4055
- if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))
4056
- { collapsed = sp; }
4057
- } else if (sp.from > pos && nextChange > sp.from) {
4058
- nextChange = sp.from;
4059
- }
4060
- }
4061
- if (endStyles) { for (var j$1 = 0; j$1 < endStyles.length; j$1 += 2)
4062
- { if (endStyles[j$1 + 1] == nextChange) { spanEndStyle += " " + endStyles[j$1]; } } }
4063
 
4064
- if (!collapsed || collapsed.from == pos) { for (var j$2 = 0; j$2 < foundBookmarks.length; ++j$2)
4065
- { buildCollapsedSpan(builder, 0, foundBookmarks[j$2]); } }
4066
- if (collapsed && (collapsed.from || 0) == pos) {
4067
- buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos,
4068
- collapsed.marker, collapsed.from == null);
4069
- if (collapsed.to == null) { return }
4070
- if (collapsed.to == pos) { collapsed = false; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4071
  }
 
4072
  }
4073
- if (pos >= len) { break }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4074
 
4075
- var upto = Math.min(len, nextChange);
4076
- while (true) {
4077
- if (text) {
4078
- var end = pos + text.length;
4079
- if (!collapsed) {
4080
- var tokenText = end > upto ? text.slice(0, upto - pos) : text;
4081
- builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
4082
- spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css);
4083
- }
4084
- if (end >= upto) {text = text.slice(upto - pos); pos = upto; break}
4085
- pos = end;
4086
- spanStartStyle = "";
4087
- }
4088
- text = allText.slice(at, at = styles[i++]);
4089
- style = interpretTokenStyle(styles[i++], builder.cm.options);
4090
  }
4091
  }
4092
- }
4093
 
 
 
 
 
 
 
 
4094
 
4095
- // These objects are used to represent the visible (currently drawn)
4096
- // part of the document. A LineView may correspond to multiple
4097
- // logical lines, if those are connected by collapsed ranges.
4098
- function LineView(doc, line, lineN) {
4099
- // The starting line
4100
- this.line = line;
4101
- // Continuing lines, if any
4102
- this.rest = visualLineContinued(line);
4103
- // Number of logical lines in this visual line
4104
- this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1;
4105
- this.node = this.text = null;
4106
- this.hidden = lineIsHidden(doc, line);
4107
- }
4108
 
4109
- // Create a range of LineView objects for the given lines.
4110
- function buildViewArray(cm, from, to) {
4111
- var array = [], nextPos;
4112
- for (var pos = from; pos < to; pos = nextPos) {
4113
- var view = new LineView(cm.doc, getLine(cm.doc, pos), pos);
4114
- nextPos = pos + view.size;
4115
- array.push(view);
 
 
 
4116
  }
4117
- return array
4118
- }
4119
 
4120
- var operationGroup = null;
 
 
 
 
 
 
 
 
 
 
 
4121
 
4122
- function pushOperation(op) {
4123
- if (operationGroup) {
4124
- operationGroup.ops.push(op);
4125
- } else {
4126
- op.ownsGroup = operationGroup = {
4127
- ops: [op],
4128
- delayedCallbacks: []
4129
- };
4130
  }
4131
- }
4132
 
4133
- function fireCallbacksForOps(group) {
4134
- // Calls delayed callbacks and cursorActivity handlers until no
4135
- // new ones appear
4136
- var callbacks = group.delayedCallbacks, i = 0;
4137
- do {
4138
- for (; i < callbacks.length; i++)
4139
- { callbacks[i].call(null); }
4140
- for (var j = 0; j < group.ops.length; j++) {
4141
- var op = group.ops[j];
4142
- if (op.cursorActivityHandlers)
4143
- { while (op.cursorActivityCalled < op.cursorActivityHandlers.length)
4144
- { op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm); } }
4145
- }
4146
- } while (i < callbacks.length)
4147
- }
4148
 
4149
- function finishOperation(op, endCb) {
4150
- var group = op.ownsGroup;
4151
- if (!group) { return }
4152
 
4153
- try { fireCallbacksForOps(group); }
4154
- finally {
4155
- operationGroup = null;
4156
- endCb(group);
 
 
 
 
 
 
 
4157
  }
4158
- }
4159
 
4160
- var orphanDelayedCallbacks = null;
4161
-
4162
- // Often, we want to signal events at a point where we are in the
4163
- // middle of some work, but don't want the handler to start calling
4164
- // other methods on the editor, which might be in an inconsistent
4165
- // state or simply not expect any other events to happen.
4166
- // signalLater looks whether there are any handlers, and schedules
4167
- // them to be executed when the last operation ends, or, if no
4168
- // operation is active, when a timeout fires.
4169
- function signalLater(emitter, type /*, values...*/) {
4170
- var arr = getHandlers(emitter, type);
4171
- if (!arr.length) { return }
4172
- var args = Array.prototype.slice.call(arguments, 2), list;
4173
- if (operationGroup) {
4174
- list = operationGroup.delayedCallbacks;
4175
- } else if (orphanDelayedCallbacks) {
4176
- list = orphanDelayedCallbacks;
4177
- } else {
4178
- list = orphanDelayedCallbacks = [];
4179
- setTimeout(fireOrphanDelayed, 0);
4180
- }
4181
- var loop = function ( i ) {
4182
- list.push(function () { return arr[i].apply(null, args); });
4183
- };
4184
-
4185
- for (var i = 0; i < arr.length; ++i)
4186
- loop( i );
4187
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4188
 
4189
- function fireOrphanDelayed() {
4190
- var delayed = orphanDelayedCallbacks;
4191
- orphanDelayedCallbacks = null;
4192
- for (var i = 0; i < delayed.length; ++i) { delayed[i](); }
4193
- }
 
 
4194
 
4195
- // When an aspect of a line changes, a string is added to
4196
- // lineView.changes. This updates the relevant part of the line's
4197
- // DOM structure.
4198
- function updateLineForChanges(cm, lineView, lineN, dims) {
4199
- for (var j = 0; j < lineView.changes.length; j++) {
4200
- var type = lineView.changes[j];
4201
- if (type == "text") { updateLineText(cm, lineView); }
4202
- else if (type == "gutter") { updateLineGutter(cm, lineView, lineN, dims); }
4203
- else if (type == "class") { updateLineClasses(cm, lineView); }
4204
- else if (type == "widget") { updateLineWidgets(cm, lineView, dims); }
4205
- }
4206
- lineView.changes = null;
4207
- }
 
 
 
 
 
 
4208
 
4209
- // Lines with gutter elements, widgets or a background class need to
4210
- // be wrapped, and have the extra elements added to the wrapper div
4211
- function ensureLineWrapped(lineView) {
4212
- if (lineView.node == lineView.text) {
4213
- lineView.node = elt("div", null, null, "position: relative");
4214
- if (lineView.text.parentNode)
4215
- { lineView.text.parentNode.replaceChild(lineView.node, lineView.text); }
4216
- lineView.node.appendChild(lineView.text);
4217
- if (ie && ie_version < 8) { lineView.node.style.zIndex = 2; }
4218
- }
4219
- return lineView.node
4220
- }
4221
 
4222
- function updateLineBackground(cm, lineView) {
4223
- var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass;
4224
- if (cls) { cls += " CodeMirror-linebackground"; }
4225
- if (lineView.background) {
4226
- if (cls) { lineView.background.className = cls; }
4227
- else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; }
4228
- } else if (cls) {
4229
- var wrap = ensureLineWrapped(lineView);
4230
- lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild);
4231
- cm.display.input.setUneditable(lineView.background);
 
 
4232
  }
4233
- }
4234
 
4235
- // Wrapper around buildLineContent which will reuse the structure
4236
- // in display.externalMeasured when possible.
4237
- function getLineContent(cm, lineView) {
4238
- var ext = cm.display.externalMeasured;
4239
- if (ext && ext.line == lineView.line) {
4240
- cm.display.externalMeasured = null;
4241
- lineView.measure = ext.measure;
4242
- return ext.built
4243
  }
4244
- return buildLineContent(cm, lineView)
4245
- }
4246
 
4247
- // Redraw the line's text. Interacts with the background and text
4248
- // classes because the mode may output tokens that influence these
4249
- // classes.
4250
- function updateLineText(cm, lineView) {
4251
- var cls = lineView.text.className;
4252
- var built = getLineContent(cm, lineView);
4253
- if (lineView.text == lineView.node) { lineView.node = built.pre; }
4254
- lineView.text.parentNode.replaceChild(built.pre, lineView.text);
4255
- lineView.text = built.pre;
4256
- if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) {
4257
- lineView.bgClass = built.bgClass;
4258
- lineView.textClass = built.textClass;
4259
- updateLineClasses(cm, lineView);
4260
- } else if (cls) {
4261
- lineView.text.className = cls;
4262
  }
4263
- }
4264
 
4265
- function updateLineClasses(cm, lineView) {
4266
- updateLineBackground(cm, lineView);
4267
- if (lineView.line.wrapClass)
4268
- { ensureLineWrapped(lineView).className = lineView.line.wrapClass; }
4269
- else if (lineView.node != lineView.text)
4270
- { lineView.node.className = ""; }
4271
- var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass;
4272
- lineView.text.className = textClass || "";
4273
- }
4274
 
4275
- function updateLineGutter(cm, lineView, lineN, dims) {
4276
- if (lineView.gutter) {
4277
- lineView.node.removeChild(lineView.gutter);
4278
- lineView.gutter = null;
 
 
 
 
 
 
 
 
 
 
 
4279
  }
4280
- if (lineView.gutterBackground) {
4281
- lineView.node.removeChild(lineView.gutterBackground);
4282
- lineView.gutterBackground = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4283
  }
4284
- if (lineView.line.gutterClass) {
4285
- var wrap = ensureLineWrapped(lineView);
4286
- lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass,
4287
- ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px; width: " + (dims.gutterTotalWidth) + "px"));
4288
- cm.display.input.setUneditable(lineView.gutterBackground);
4289
- wrap.insertBefore(lineView.gutterBackground, lineView.text);
4290
- }
4291
- var markers = lineView.line.gutterMarkers;
4292
- if (cm.options.lineNumbers || markers) {
4293
- var wrap$1 = ensureLineWrapped(lineView);
4294
- var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"));
4295
- cm.display.input.setUneditable(gutterWrap);
4296
- wrap$1.insertBefore(gutterWrap, lineView.text);
4297
- if (lineView.line.gutterClass)
4298
- { gutterWrap.className += " " + lineView.line.gutterClass; }
4299
- if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
4300
- { lineView.lineNumber = gutterWrap.appendChild(
4301
- elt("div", lineNumberFor(cm.options, lineN),
4302
- "CodeMirror-linenumber CodeMirror-gutter-elt",
4303
- ("left: " + (dims.gutterLeft["CodeMirror-linenumbers"]) + "px; width: " + (cm.display.lineNumInnerWidth) + "px"))); }
4304
- if (markers) { for (var k = 0; k < cm.options.gutters.length; ++k) {
4305
- var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
4306
- if (found)
4307
- { gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt",
4308
- ("left: " + (dims.gutterLeft[id]) + "px; width: " + (dims.gutterWidth[id]) + "px"))); }
4309
  } }
4310
  }
4311
- }
4312
 
4313
- function updateLineWidgets(cm, lineView, dims) {
4314
- if (lineView.alignable) { lineView.alignable = null; }
4315
- for (var node = lineView.node.firstChild, next = (void 0); node; node = next) {
4316
- next = node.nextSibling;
4317
- if (node.className == "CodeMirror-linewidget")
4318
- { lineView.node.removeChild(node); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4319
  }
4320
- insertLineWidgets(cm, lineView, dims);
4321
- }
4322
 
4323
- // Build a line's DOM representation from scratch
4324
- function buildLineElement(cm, lineView, lineN, dims) {
4325
- var built = getLineContent(cm, lineView);
4326
- lineView.text = lineView.node = built.pre;
4327
- if (built.bgClass) { lineView.bgClass = built.bgClass; }
4328
- if (built.textClass) { lineView.textClass = built.textClass; }
4329
-
4330
- updateLineClasses(cm, lineView);
4331
- updateLineGutter(cm, lineView, lineN, dims);
4332
- insertLineWidgets(cm, lineView, dims);
4333
- return lineView.node
4334
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4335
 
4336
- // A lineView may contain multiple logical lines (when merged by
4337
- // collapsed spans). The widgets for all of them need to be drawn.
4338
- function insertLineWidgets(cm, lineView, dims) {
4339
- insertLineWidgetsFor(cm, lineView.line, lineView, dims, true);
4340
- if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++)
4341
- { insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false); } }
4342
- }
4343
 
4344
- function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) {
4345
- if (!line.widgets) { return }
4346
- var wrap = ensureLineWrapped(lineView);
4347
- for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
4348
- var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
4349
- if (!widget.handleMouseEvents) { node.setAttribute("cm-ignore-events", "true"); }
4350
- positionLineWidget(widget, node, lineView, dims);
4351
- cm.display.input.setUneditable(node);
4352
- if (allowAbove && widget.above)
4353
- { wrap.insertBefore(node, lineView.gutter || lineView.text); }
4354
- else
4355
- { wrap.appendChild(node); }
4356
- signalLater(widget, "redraw");
4357
  }
4358
- }
4359
 
4360
- function positionLineWidget(widget, node, lineView, dims) {
4361
- if (widget.noHScroll) {
4362
- (lineView.alignable || (lineView.alignable = [])).push(node);
4363
- var width = dims.wrapperWidth;
4364
- node.style.left = dims.fixedPos + "px";
4365
- if (!widget.coverGutter) {
4366
- width -= dims.gutterTotalWidth;
4367
- node.style.paddingLeft = dims.gutterTotalWidth + "px";
4368
- }
4369
- node.style.width = width + "px";
4370
  }
4371
- if (widget.coverGutter) {
4372
- node.style.zIndex = 5;
4373
- node.style.position = "relative";
4374
- if (!widget.noHScroll) { node.style.marginLeft = -dims.gutterTotalWidth + "px"; }
4375
  }
4376
- }
4377
 
4378
- function widgetHeight(widget) {
4379
- if (widget.height != null) { return widget.height }
4380
- var cm = widget.doc.cm;
4381
- if (!cm) { return 0 }
4382
- if (!contains(document.body, widget.node)) {
4383
- var parentStyle = "position: relative;";
4384
- if (widget.coverGutter)
4385
- { parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;"; }
4386
- if (widget.noHScroll)
4387
- { parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;"; }
4388
- removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle));
4389
- }
4390
- return widget.height = widget.node.parentNode.offsetHeight
4391
- }
4392
-
4393
- // Return true when the given mouse event happened in a widget
4394
- function eventInWidget(display, e) {
4395
- for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
4396
- if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") ||
4397
- (n.parentNode == display.sizer && n != display.mover))
4398
- { return true }
4399
  }
4400
- }
4401
-
4402
- // POSITION MEASUREMENT
4403
-
4404
- function paddingTop(display) {return display.lineSpace.offsetTop}
4405
- function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight}
4406
- function paddingH(display) {
4407
- if (display.cachedPaddingH) { return display.cachedPaddingH }
4408
- var e = removeChildrenAndAdd(display.measure, elt("pre", "x"));
4409
- var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle;
4410
- var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)};
4411
- if (!isNaN(data.left) && !isNaN(data.right)) { display.cachedPaddingH = data; }
4412
- return data
4413
- }
4414
-
4415
- function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth }
4416
- function displayWidth(cm) {
4417
- return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth
4418
- }
4419
- function displayHeight(cm) {
4420
- return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight
4421
- }
4422
 
4423
- // Ensure the lineView.wrapping.heights array is populated. This is
4424
- // an array of bottom offsets for the lines that make up a drawn
4425
- // line. When lineWrapping is on, there might be more than one
4426
- // height.
4427
- function ensureLineHeights(cm, lineView, rect) {
4428
- var wrapping = cm.options.lineWrapping;
4429
- var curWidth = wrapping && displayWidth(cm);
4430
- if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) {
4431
- var heights = lineView.measure.heights = [];
4432
- if (wrapping) {
4433
- lineView.measure.width = curWidth;
4434
- var rects = lineView.text.firstChild.getClientRects();
4435
- for (var i = 0; i < rects.length - 1; i++) {
4436
- var cur = rects[i], next = rects[i + 1];
4437
- if (Math.abs(cur.bottom - next.bottom) > 2)
4438
- { heights.push((cur.bottom + next.top) / 2 - rect.top); }
4439
- }
4440
- }
4441
- heights.push(rect.bottom - rect.top);
4442
  }
4443
- }
4444
-
4445
- // Find a line map (mapping character offsets to text nodes) and a
4446
- // measurement cache for the given line number. (A line view might
4447
- // contain multiple lines when collapsed ranges are present.)
4448
- function mapFromLineView(lineView, line, lineN) {
4449
- if (lineView.line == line)
4450
- { return {map: lineView.measure.map, cache: lineView.measure.cache} }
4451
- for (var i = 0; i < lineView.rest.length; i++)
4452
- { if (lineView.rest[i] == line)
4453
- { return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]} } }
4454
- for (var i$1 = 0; i$1 < lineView.rest.length; i$1++)
4455
- { if (lineNo(lineView.rest[i$1]) > lineN)
4456
- { return {map: lineView.measure.maps[i$1], cache: lineView.measure.caches[i$1], before: true} } }
4457
- }
4458
-
4459
- // Render a line into the hidden node display.externalMeasured. Used
4460
- // when measurement is needed for a line that's not in the viewport.
4461
- function updateExternalMeasurement(cm, line) {
4462
- line = visualLine(line);
4463
- var lineN = lineNo(line);
4464
- var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN);
4465
- view.lineN = lineN;
4466
- var built = view.built = buildLineContent(cm, view);
4467
- view.text = built.pre;
4468
- removeChildrenAndAdd(cm.display.lineMeasure, built.pre);
4469
- return view
4470
- }
4471
-
4472
- // Get a {top, bottom, left, right} box (in line-local coordinates)
4473
- // for a given character.
4474
- function measureChar(cm, line, ch, bias) {
4475
- return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias)
4476
- }
4477
-
4478
- // Find a line view that corresponds to the given line number.
4479
- function findViewForLine(cm, lineN) {
4480
- if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo)
4481
- { return cm.display.view[findViewIndex(cm, lineN)] }
4482
- var ext = cm.display.externalMeasured;
4483
- if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size)
4484
- { return ext }
4485
- }
4486
 
4487
- // Measurement can be split in two steps, the set-up work that
4488
- // applies to the whole line, and the measurement of the actual
4489
- // character. Functions like coordsChar, that need to do a lot of
4490
- // measurements in a row, can thus ensure that the set-up work is
4491
- // only done once.
4492
- function prepareMeasureForLine(cm, line) {
4493
- var lineN = lineNo(line);
4494
- var view = findViewForLine(cm, lineN);
4495
- if (view && !view.text) {
4496
- view = null;
4497
- } else if (view && view.changes) {
4498
- updateLineForChanges(cm, view, lineN, getDimensions(cm));
4499
- cm.curOp.forceUpdate = true;
4500
- }
4501
- if (!view)
4502
- { view = updateExternalMeasurement(cm, line); }
4503
-
4504
- var info = mapFromLineView(view, line, lineN);
4505
- return {
4506
- line: line, view: view, rect: null,
4507
- map: info.map, cache: info.cache, before: info.before,
4508
- hasHeights: false
4509
  }
4510
- }
4511
-
4512
- // Given a prepared measurement object, measures the position of an
4513
- // actual character (or fetches it from the cache).
4514
- function measureCharPrepared(cm, prepared, ch, bias, varHeight) {
4515
- if (prepared.before) { ch = -1; }
4516
- var key = ch + (bias || ""), found;
4517
- if (prepared.cache.hasOwnProperty(key)) {
4518
- found = prepared.cache[key];
4519
- } else {
4520
- if (!prepared.rect)
4521
- { prepared.rect = prepared.view.text.getBoundingClientRect(); }
4522
- if (!prepared.hasHeights) {
4523
- ensureLineHeights(cm, prepared.view, prepared.rect);
4524
- prepared.hasHeights = true;
4525
- }
4526
- found = measureCharInner(cm, prepared, ch, bias);
4527
- if (!found.bogus) { prepared.cache[key] = found; }
4528
- }
4529
- return {left: found.left, right: found.right,
4530
- top: varHeight ? found.rtop : found.top,
4531
- bottom: varHeight ? found.rbottom : found.bottom}
4532
- }
4533
 
4534
- var nullRect = {left: 0, right: 0, top: 0, bottom: 0};
4535
-
4536
- function nodeAndOffsetInLineMap(map$$1, ch, bias) {
4537
- var node, start, end, collapse, mStart, mEnd;
4538
- // First, search the line map for the text node corresponding to,
4539
- // or closest to, the target character.
4540
- for (var i = 0; i < map$$1.length; i += 3) {
4541
- mStart = map$$1[i];
4542
- mEnd = map$$1[i + 1];
4543
- if (ch < mStart) {
4544
- start = 0; end = 1;
4545
- collapse = "left";
4546
- } else if (ch < mEnd) {
4547
- start = ch - mStart;
4548
- end = start + 1;
4549
- } else if (i == map$$1.length - 3 || ch == mEnd && map$$1[i + 3] > ch) {
4550
- end = mEnd - mStart;
4551
- start = end - 1;
4552
- if (ch >= mEnd) { collapse = "right"; }
4553
- }
4554
- if (start != null) {
4555
- node = map$$1[i + 2];
4556
- if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right"))
4557
- { collapse = bias; }
4558
- if (bias == "left" && start == 0)
4559
- { while (i && map$$1[i - 2] == map$$1[i - 3] && map$$1[i - 1].insertLeft) {
4560
- node = map$$1[(i -= 3) + 2];
4561
- collapse = "left";
4562
- } }
4563
- if (bias == "right" && start == mEnd - mStart)
4564
- { while (i < map$$1.length - 3 && map$$1[i + 3] == map$$1[i + 4] && !map$$1[i + 5].insertLeft) {
4565
- node = map$$1[(i += 3) + 2];
4566
- collapse = "right";
4567
- } }
4568
- break
4569
- }
4570
  }
4571
- return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd}
4572
- }
4573
-
4574
- function getUsefulRect(rects, bias) {
4575
- var rect = nullRect;
4576
- if (bias == "left") { for (var i = 0; i < rects.length; i++) {
4577
- if ((rect = rects[i]).left != rect.right) { break }
4578
- } } else { for (var i$1 = rects.length - 1; i$1 >= 0; i$1--) {
4579
- if ((rect = rects[i$1]).left != rect.right) { break }
4580
- } }
4581
- return rect
4582
- }
4583
 
4584
- function measureCharInner(cm, prepared, ch, bias) {
4585
- var place = nodeAndOffsetInLineMap(prepared.map, ch, bias);
4586
- var node = place.node, start = place.start, end = place.end, collapse = place.collapse;
4587
-
4588
- var rect;
4589
- if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates.
4590
- for (var i$1 = 0; i$1 < 4; i$1++) { // Retry a maximum of 4 times when nonsense rectangles are returned
4591
- while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) { --start; }
4592
- while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) { ++end; }
4593
- if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart)
4594
- { rect = node.parentNode.getBoundingClientRect(); }
4595
- else
4596
- { rect = getUsefulRect(range(node, start, end).getClientRects(), bias); }
4597
- if (rect.left || rect.right || start == 0) { break }
4598
- end = start;
4599
- start = start - 1;
4600
- collapse = "right";
4601
- }
4602
- if (ie && ie_version < 11) { rect = maybeUpdateRectForZooming(cm.display.measure, rect); }
4603
- } else { // If it is a widget, simply get the box for the whole widget.
4604
- if (start > 0) { collapse = bias = "right"; }
4605
- var rects;
4606
- if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1)
4607
- { rect = rects[bias == "right" ? rects.length - 1 : 0]; }
4608
- else
4609
- { rect = node.getBoundingClientRect(); }
4610
  }
4611
- if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) {
4612
- var rSpan = node.parentNode.getClientRects()[0];
4613
- if (rSpan)
4614
- { rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom}; }
4615
- else
4616
- { rect = nullRect; }
4617
- }
4618
-
4619
- var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top;
4620
- var mid = (rtop + rbot) / 2;
4621
- var heights = prepared.view.measure.heights;
4622
- var i = 0;
4623
- for (; i < heights.length - 1; i++)
4624
- { if (mid < heights[i]) { break } }
4625
- var top = i ? heights[i - 1] : 0, bot = heights[i];
4626
- var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left,
4627
- right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left,
4628
- top: top, bottom: bot};
4629
- if (!rect.left && !rect.right) { result.bogus = true; }
4630
- if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; }
4631
-
4632
- return result
4633
- }
4634
 
4635
- // Work around problem with bounding client rects on ranges being
4636
- // returned incorrectly when zoomed on IE10 and below.
4637
- function maybeUpdateRectForZooming(measure, rect) {
4638
- if (!window.screen || screen.logicalXDPI == null ||
4639
- screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure))
4640
- { return rect }
4641
- var scaleX = screen.logicalXDPI / screen.deviceXDPI;
4642
- var scaleY = screen.logicalYDPI / screen.deviceYDPI;
4643
- return {left: rect.left * scaleX, right: rect.right * scaleX,
4644
- top: rect.top * scaleY, bottom: rect.bottom * scaleY}
4645
- }
4646
 
4647
- function clearLineMeasurementCacheFor(lineView) {
4648
- if (lineView.measure) {
4649
- lineView.measure.cache = {};
4650
- lineView.measure.heights = null;
4651
- if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++)
4652
- { lineView.measure.caches[i] = {}; } }
4653
- }
4654
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4655
 
4656
- function clearLineMeasurementCache(cm) {
4657
- cm.display.externalMeasure = null;
4658
- removeChildren(cm.display.lineMeasure);
4659
- for (var i = 0; i < cm.display.view.length; i++)
4660
- { clearLineMeasurementCacheFor(cm.display.view[i]); }
4661
- }
4662
 
4663
- function clearCaches(cm) {
4664
- clearLineMeasurementCache(cm);
4665
- cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null;
4666
- if (!cm.options.lineWrapping) { cm.display.maxLineChanged = true; }
4667
- cm.display.lineNumChars = null;
4668
- }
 
 
 
 
 
 
 
 
 
 
4669
 
4670
- function pageScrollX() {
4671
- // Work around https://bugs.chromium.org/p/chromium/issues/detail?id=489206
4672
- // which causes page_Offset and bounding client rects to use
4673
- // different reference viewports and invalidate our calculations.
4674
- if (chrome && android) { return -(document.body.getBoundingClientRect().left - parseInt(getComputedStyle(document.body).marginLeft)) }
4675
- return window.pageXOffset || (document.documentElement || document.body).scrollLeft
4676
- }
4677
- function pageScrollY() {
4678
- if (chrome && android) { return -(document.body.getBoundingClientRect().top - parseInt(getComputedStyle(document.body).marginTop)) }
4679
- return window.pageYOffset || (document.documentElement || document.body).scrollTop
4680
- }
4681
 
4682
- function widgetTopHeight(lineObj) {
4683
- var height = 0;
4684
- if (lineObj.widgets) { for (var i = 0; i < lineObj.widgets.length; ++i) { if (lineObj.widgets[i].above)
4685
- { height += widgetHeight(lineObj.widgets[i]); } } }
4686
- return height
4687
- }
4688
 
4689
- // Converts a {top, bottom, left, right} box from line-local
4690
- // coordinates into another coordinate system. Context may be one of
4691
- // "line", "div" (display.lineDiv), "local"./null (editor), "window",
4692
- // or "page".
4693
- function intoCoordSystem(cm, lineObj, rect, context, includeWidgets) {
4694
- if (!includeWidgets) {
4695
- var height = widgetTopHeight(lineObj);
4696
- rect.top += height; rect.bottom += height;
4697
- }
4698
- if (context == "line") { return rect }
4699
- if (!context) { context = "local"; }
4700
- var yOff = heightAtLine(lineObj);
4701
- if (context == "local") { yOff += paddingTop(cm.display); }
4702
- else { yOff -= cm.display.viewOffset; }
4703
- if (context == "page" || context == "window") {
4704
- var lOff = cm.display.lineSpace.getBoundingClientRect();
4705
- yOff += lOff.top + (context == "window" ? 0 : pageScrollY());
4706
- var xOff = lOff.left + (context == "window" ? 0 : pageScrollX());
4707
- rect.left += xOff; rect.right += xOff;
4708
- }
4709
- rect.top += yOff; rect.bottom += yOff;
4710
- return rect
4711
- }
4712
 
4713
- // Coverts a box from "div" coords to another coordinate system.
4714
- // Context may be "window", "page", "div", or "local"./null.
4715
- function fromCoordSystem(cm, coords, context) {
4716
- if (context == "div") { return coords }
4717
- var left = coords.left, top = coords.top;
4718
- // First move into "page" coordinate system
4719
- if (context == "page") {
4720
- left -= pageScrollX();
4721
- top -= pageScrollY();
4722
- } else if (context == "local" || !context) {
4723
- var localBox = cm.display.sizer.getBoundingClientRect();
4724
- left += localBox.left;
4725
- top += localBox.top;
4726
- }
4727
-
4728
- var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect();
4729
- return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top}
4730
- }
4731
 
4732
- function charCoords(cm, pos, context, lineObj, bias) {
4733
- if (!lineObj) { lineObj = getLine(cm.doc, pos.line); }
4734
- return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context)
4735
- }
4736
 
4737
- // Returns a box for a given cursor position, which may have an
4738
- // 'other' property containing the position of the secondary cursor
4739
- // on a bidi boundary.
4740
- // A cursor Pos(line, char, "before") is on the same visual line as `char - 1`
4741
- // and after `char - 1` in writing order of `char - 1`
4742
- // A cursor Pos(line, char, "after") is on the same visual line as `char`
4743
- // and before `char` in writing order of `char`
4744
- // Examples (upper-case letters are RTL, lower-case are LTR):
4745
- // Pos(0, 1, ...)
4746
- // before after
4747
- // ab a|b a|b
4748
- // aB a|B aB|
4749
- // Ab |Ab A|b
4750
- // AB B|A B|A
4751
- // Every position after the last character on a line is considered to stick
4752
- // to the last character on the line.
4753
- function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) {
4754
- lineObj = lineObj || getLine(cm.doc, pos.line);
4755
- if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj); }
4756
- function get(ch, right) {
4757
- var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight);
4758
- if (right) { m.left = m.right; } else { m.right = m.left; }
4759
- return intoCoordSystem(cm, lineObj, m, context)
4760
- }
4761
- var order = getOrder(lineObj, cm.doc.direction), ch = pos.ch, sticky = pos.sticky;
4762
- if (ch >= lineObj.text.length) {
4763
- ch = lineObj.text.length;
4764
- sticky = "before";
4765
- } else if (ch <= 0) {
4766
- ch = 0;
4767
- sticky = "after";
4768
- }
4769
- if (!order) { return get(sticky == "before" ? ch - 1 : ch, sticky == "before") }
4770
-
4771
- function getBidi(ch, partPos, invert) {
4772
- var part = order[partPos], right = part.level == 1;
4773
- return get(invert ? ch - 1 : ch, right != invert)
4774
- }
4775
- var partPos = getBidiPartAt(order, ch, sticky);
4776
- var other = bidiOther;
4777
- var val = getBidi(ch, partPos, sticky == "before");
4778
- if (other != null) { val.other = getBidi(ch, other, sticky != "before"); }
4779
- return val
4780
- }
4781
 
4782
- // Used to cheaply estimate the coordinates for a position. Used for
4783
- // intermediate scroll updates.
4784
- function estimateCoords(cm, pos) {
4785
- var left = 0;
4786
- pos = clipPos(cm.doc, pos);
4787
- if (!cm.options.lineWrapping) { left = charWidth(cm.display) * pos.ch; }
4788
- var lineObj = getLine(cm.doc, pos.line);
4789
- var top = heightAtLine(lineObj) + paddingTop(cm.display);
4790
- return {left: left, right: left, top: top, bottom: top + lineObj.height}
4791
- }
 
 
 
 
 
 
 
4792
 
4793
- // Positions returned by coordsChar contain some extra information.
4794
- // xRel is the relative x position of the input coordinates compared
4795
- // to the found position (so xRel > 0 means the coordinates are to
4796
- // the right of the character position, for example). When outside
4797
- // is true, that means the coordinates lie outside the line's
4798
- // vertical range.
4799
- function PosWithInfo(line, ch, sticky, outside, xRel) {
4800
- var pos = Pos(line, ch, sticky);
4801
- pos.xRel = xRel;
4802
- if (outside) { pos.outside = true; }
4803
- return pos
4804
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4805
 
4806
- // Compute the character position closest to the given coordinates.
4807
- // Input must be lineSpace-local ("div" coordinate system).
4808
- function coordsChar(cm, x, y) {
4809
- var doc = cm.doc;
4810
- y += cm.display.viewOffset;
4811
- if (y < 0) { return PosWithInfo(doc.first, 0, null, true, -1) }
4812
- var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
4813
- if (lineN > last)
4814
- { return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, null, true, 1) }
4815
- if (x < 0) { x = 0; }
4816
-
4817
- var lineObj = getLine(doc, lineN);
4818
- for (;;) {
4819
- var found = coordsCharInner(cm, lineObj, lineN, x, y);
4820
- var collapsed = collapsedSpanAround(lineObj, found.ch + (found.xRel > 0 ? 1 : 0));
4821
- if (!collapsed) { return found }
4822
- var rangeEnd = collapsed.find(1);
4823
- if (rangeEnd.line == lineN) { return rangeEnd }
4824
- lineObj = getLine(doc, lineN = rangeEnd.line);
4825
  }
4826
- }
4827
 
4828
- function wrappedLineExtent(cm, lineObj, preparedMeasure, y) {
4829
- y -= widgetTopHeight(lineObj);
4830
- var end = lineObj.text.length;
4831
- var begin = findFirst(function (ch) { return measureCharPrepared(cm, preparedMeasure, ch - 1).bottom <= y; }, end, 0);
4832
- end = findFirst(function (ch) { return measureCharPrepared(cm, preparedMeasure, ch).top > y; }, begin, end);
4833
- return {begin: begin, end: end}
4834
- }
 
 
 
 
 
 
 
 
4835
 
4836
- function wrappedLineExtentChar(cm, lineObj, preparedMeasure, target) {
4837
- if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj); }
4838
- var targetTop = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, target), "line").top;
4839
- return wrappedLineExtent(cm, lineObj, preparedMeasure, targetTop)
4840
- }
4841
 
4842
- // Returns true if the given side of a box is after the given
4843
- // coordinates, in top-to-bottom, left-to-right order.
4844
- function boxIsAfter(box, x, y, left) {
4845
- return box.bottom <= y ? false : box.top > y ? true : (left ? box.left : box.right) > x
4846
- }
 
 
4847
 
4848
- function coordsCharInner(cm, lineObj, lineNo$$1, x, y) {
4849
- // Move y into line-local coordinate space
4850
- y -= heightAtLine(lineObj);
4851
- var preparedMeasure = prepareMeasureForLine(cm, lineObj);
4852
- // When directly calling `measureCharPrepared`, we have to adjust
4853
- // for the widgets at this line.
4854
- var widgetHeight$$1 = widgetTopHeight(lineObj);
4855
- var begin = 0, end = lineObj.text.length, ltr = true;
4856
-
4857
- var order = getOrder(lineObj, cm.doc.direction);
4858
- // If the line isn't plain left-to-right text, first figure out
4859
- // which bidi section the coordinates fall into.
4860
- if (order) {
4861
- var part = (cm.options.lineWrapping ? coordsBidiPartWrapped : coordsBidiPart)
4862
- (cm, lineObj, lineNo$$1, preparedMeasure, order, x, y);
4863
- ltr = part.level != 1;
4864
- // The awkward -1 offsets are needed because findFirst (called
4865
- // on these below) will treat its first bound as inclusive,
4866
- // second as exclusive, but we want to actually address the
4867
- // characters in the part's range
4868
- begin = ltr ? part.from : part.to - 1;
4869
- end = ltr ? part.to : part.from - 1;
4870
- }
4871
-
4872
- // A binary search to find the first character whose bounding box
4873
- // starts after the coordinates. If we run across any whose box wrap
4874
- // the coordinates, store that.
4875
- var chAround = null, boxAround = null;
4876
- var ch = findFirst(function (ch) {
4877
- var box = measureCharPrepared(cm, preparedMeasure, ch);
4878
- box.top += widgetHeight$$1; box.bottom += widgetHeight$$1;
4879
- if (!boxIsAfter(box, x, y, false)) { return false }
4880
- if (box.top <= y && box.left <= x) {
4881
- chAround = ch;
4882
- boxAround = box;
4883
- }
4884
- return true
4885
- }, begin, end);
4886
-
4887
- var baseX, sticky, outside = false;
4888
- // If a box around the coordinates was found, use that
4889
- if (boxAround) {
4890
- // Distinguish coordinates nearer to the left or right side of the box
4891
- var atLeft = x - boxAround.left < boxAround.right - x, atStart = atLeft == ltr;
4892
- ch = chAround + (atStart ? 0 : 1);
4893
- sticky = atStart ? "after" : "before";
4894
- baseX = atLeft ? boxAround.left : boxAround.right;
4895
- } else {
4896
- // (Adjust for extended bound, if necessary.)
4897
- if (!ltr && (ch == end || ch == begin)) { ch++; }
4898
- // To determine which side to associate with, get the box to the
4899
- // left of the character and compare it's vertical position to the
4900
- // coordinates
4901
- sticky = ch == 0 ? "after" : ch == lineObj.text.length ? "before" :
4902
- (measureCharPrepared(cm, preparedMeasure, ch - (ltr ? 1 : 0)).bottom + widgetHeight$$1 <= y) == ltr ?
4903
- "after" : "before";
4904
- // Now get accurate coordinates for this place, in order to get a
4905
- // base X position
4906
- var coords = cursorCoords(cm, Pos(lineNo$$1, ch, sticky), "line", lineObj, preparedMeasure);
4907
- baseX = coords.left;
4908
- outside = y < coords.top || y >= coords.bottom;
4909
- }
4910
-
4911
- ch = skipExtendingChars(lineObj.text, ch, 1);
4912
- return PosWithInfo(lineNo$$1, ch, sticky, outside, x - baseX)
4913
- }
4914
 
4915
- function coordsBidiPart(cm, lineObj, lineNo$$1, preparedMeasure, order, x, y) {
4916
- // Bidi parts are sorted left-to-right, and in a non-line-wrapping
4917
- // situation, we can take this ordering to correspond to the visual
4918
- // ordering. This finds the first part whose end is after the given
4919
- // coordinates.
4920
- var index = findFirst(function (i) {
4921
- var part = order[i], ltr = part.level != 1;
4922
- return boxIsAfter(cursorCoords(cm, Pos(lineNo$$1, ltr ? part.to : part.from, ltr ? "before" : "after"),
4923
- "line", lineObj, preparedMeasure), x, y, true)
4924
- }, 0, order.length - 1);
4925
- var part = order[index];
4926
- // If this isn't the first part, the part's start is also after
4927
- // the coordinates, and the coordinates aren't on the same line as
4928
- // that start, move one part back.
4929
- if (index > 0) {
4930
- var ltr = part.level != 1;
4931
- var start = cursorCoords(cm, Pos(lineNo$$1, ltr ? part.from : part.to, ltr ? "after" : "before"),
4932
- "line", lineObj, preparedMeasure);
4933
- if (boxIsAfter(start, x, y, true) && start.top > y)
4934
- { part = order[index - 1]; }
4935
- }
4936
- return part
4937
- }
4938
 
4939
- function coordsBidiPartWrapped(cm, lineObj, _lineNo, preparedMeasure, order, x, y) {
4940
- // In a wrapped line, rtl text on wrapping boundaries can do things
4941
- // that don't correspond to the ordering in our `order` array at
4942
- // all, so a binary search doesn't work, and we want to return a
4943
- // part that only spans one line so that the binary search in
4944
- // coordsCharInner is safe. As such, we first find the extent of the
4945
- // wrapped line, and then do a flat search in which we discard any
4946
- // spans that aren't on the line.
4947
- var ref = wrappedLineExtent(cm, lineObj, preparedMeasure, y);
4948
- var begin = ref.begin;
4949
- var end = ref.end;
4950
- if (/\s/.test(lineObj.text.charAt(end - 1))) { end--; }
4951
- var part = null, closestDist = null;
4952
- for (var i = 0; i < order.length; i++) {
4953
- var p = order[i];
4954
- if (p.from >= end || p.to <= begin) { continue }
4955
- var ltr = p.level != 1;
4956
- var endX = measureCharPrepared(cm, preparedMeasure, ltr ? Math.min(end, p.to) - 1 : Math.max(begin, p.from)).right;
4957
- // Weigh against spans ending before this, so that they are only
4958
- // picked if nothing ends after
4959
- var dist = endX < x ? x - endX + 1e9 : endX - x;
4960
- if (!part || closestDist > dist) {
4961
- part = p;
4962
- closestDist = dist;
4963
- }
4964
- }
4965
- if (!part) { part = order[order.length - 1]; }
4966
- // Clip the part to the wrapped line.
4967
- if (part.from < begin) { part = {from: begin, to: part.to, level: part.level}; }
4968
- if (part.to > end) { part = {from: part.from, to: end, level: part.level}; }
4969
- return part
4970
- }
4971
 
4972
- var measureText;
4973
- // Compute the default text height.
4974
- function textHeight(display) {
4975
- if (display.cachedTextHeight != null) { return display.cachedTextHeight }
4976
- if (measureText == null) {
4977
- measureText = elt("pre");
4978
- // Measure a bunch of lines, for browsers that compute
4979
- // fractional heights.
4980
- for (var i = 0; i < 49; ++i) {
4981
- measureText.appendChild(document.createTextNode("x"));
4982
- measureText.appendChild(elt("br"));
4983
  }
4984
- measureText.appendChild(document.createTextNode("x"));
 
 
4985
  }
4986
- removeChildrenAndAdd(display.measure, measureText);
4987
- var height = measureText.offsetHeight / 50;
4988
- if (height > 3) { display.cachedTextHeight = height; }
4989
- removeChildren(display.measure);
4990
- return height || 1
4991
- }
4992
 
4993
- // Compute the default character width.
4994
- function charWidth(display) {
4995
- if (display.cachedCharWidth != null) { return display.cachedCharWidth }
4996
- var anchor = elt("span", "xxxxxxxxxx");
4997
- var pre = elt("pre", [anchor]);
4998
- removeChildrenAndAdd(display.measure, pre);
4999
- var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10;
5000
- if (width > 2) { display.cachedCharWidth = width; }
5001
- return width || 10
5002
- }
5003
 
5004
- // Do a bulk-read of the DOM positions and sizes needed to draw the
5005
- // view, so that we don't interleave reading and writing to the DOM.
5006
- function getDimensions(cm) {
5007
- var d = cm.display, left = {}, width = {};
5008
- var gutterLeft = d.gutters.clientLeft;
5009
- for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
5010
- left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft;
5011
- width[cm.options.gutters[i]] = n.clientWidth;
5012
- }
5013
- return {fixedPos: compensateForHScroll(d),
5014
- gutterTotalWidth: d.gutters.offsetWidth,
5015
- gutterLeft: left,
5016
- gutterWidth: width,
5017
- wrapperWidth: d.wrapper.clientWidth}
5018
- }
5019
 
5020
- // Computes display.scroller.scrollLeft + display.gutters.offsetWidth,
5021
- // but using getBoundingClientRect to get a sub-pixel-accurate
5022
- // result.
5023
- function compensateForHScroll(display) {
5024
- return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left
5025
- }
 
5026
 
5027
- // Returns a function that estimates the height of a line, to use as
5028
- // first approximation until the line becomes visible (and is thus
5029
- // properly measurable).
5030
- function estimateHeight(cm) {
5031
- var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
5032
- var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
5033
- return function (line) {
5034
- if (lineIsHidden(cm.doc, line)) { return 0 }
5035
-
5036
- var widgetsHeight = 0;
5037
- if (line.widgets) { for (var i = 0; i < line.widgets.length; i++) {
5038
- if (line.widgets[i].height) { widgetsHeight += line.widgets[i].height; }
5039
- } }
5040
 
5041
- if (wrapping)
5042
- { return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th }
5043
- else
5044
- { return widgetsHeight + th }
5045
  }
5046
- }
5047
 
5048
- function estimateLineHeights(cm) {
5049
- var doc = cm.doc, est = estimateHeight(cm);
5050
- doc.iter(function (line) {
5051
- var estHeight = est(line);
5052
- if (estHeight != line.height) { updateLineHeight(line, estHeight); }
5053
- });
5054
- }
5055
 
5056
- // Given a mouse event, find the corresponding position. If liberal
5057
- // is false, it checks whether a gutter or scrollbar was clicked,
5058
- // and returns null if it was. forRect is used by rectangular
5059
- // selections, and tries to estimate a character position even for
5060
- // coordinates beyond the right of the text.
5061
- function posFromMouse(cm, e, liberal, forRect) {
5062
- var display = cm.display;
5063
- if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") { return null }
5064
-
5065
- var x, y, space = display.lineSpace.getBoundingClientRect();
5066
- // Fails unpredictably on IE[67] when mouse is dragged around quickly.
5067
- try { x = e.clientX - space.left; y = e.clientY - space.top; }
5068
- catch (e) { return null }
5069
- var coords = coordsChar(cm, x, y), line;
5070
- if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
5071
- var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length;
5072
- coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff));
5073
- }
5074
- return coords
5075
- }
5076
 
5077
- // Find the view element corresponding to a given line. Return null
5078
- // when the line isn't visible.
5079
- function findViewIndex(cm, n) {
5080
- if (n >= cm.display.viewTo) { return null }
5081
- n -= cm.display.viewFrom;
5082
- if (n < 0) { return null }
5083
- var view = cm.display.view;
5084
- for (var i = 0; i < view.length; i++) {
5085
- n -= view[i].size;
5086
- if (n < 0) { return i }
5087
- }
5088
- }
5089
 
5090
- function updateSelection(cm) {
5091
- cm.display.input.showSelection(cm.display.input.prepareSelection());
5092
- }
5093
 
5094
- function prepareSelection(cm, primary) {
5095
- if ( primary === void 0 ) primary = true;
 
 
 
 
 
5096
 
5097
- var doc = cm.doc, result = {};
5098
- var curFragment = result.cursors = document.createDocumentFragment();
5099
- var selFragment = result.selection = document.createDocumentFragment();
 
 
 
 
5100
 
5101
- for (var i = 0; i < doc.sel.ranges.length; i++) {
5102
- if (!primary && i == doc.sel.primIndex) { continue }
5103
- var range$$1 = doc.sel.ranges[i];
5104
- if (range$$1.from().line >= cm.display.viewTo || range$$1.to().line < cm.display.viewFrom) { continue }
5105
- var collapsed = range$$1.empty();
5106
- if (collapsed || cm.options.showCursorWhenSelecting)
5107
- { drawSelectionCursor(cm, range$$1.head, curFragment); }
5108
- if (!collapsed)
5109
- { drawSelectionRange(cm, range$$1, selFragment); }
5110
- }
5111
- return result
5112
- }
5113
 
5114
- // Draws a cursor for the given range
5115
- function drawSelectionCursor(cm, head, output) {
5116
- var pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine);
 
 
 
5117
 
5118
- var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor"));
5119
- cursor.style.left = pos.left + "px";
5120
- cursor.style.top = pos.top + "px";
5121
- cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5122
 
5123
- if (pos.other) {
5124
- // Secondary cursor, shown when on a 'jump' in bi-directional text
5125
- var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor"));
5126
- otherCursor.style.display = "";
5127
- otherCursor.style.left = pos.other.left + "px";
5128
- otherCursor.style.top = pos.other.top + "px";
5129
- otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
5130
  }
5131
- }
5132
 
5133
- function cmpCoords(a, b) { return a.top - b.top || a.left - b.left }
5134
-
5135
- // Draws the given range as a highlighted selection
5136
- function drawSelectionRange(cm, range$$1, output) {
5137
- var display = cm.display, doc = cm.doc;
5138
- var fragment = document.createDocumentFragment();
5139
- var padding = paddingH(cm.display), leftSide = padding.left;
5140
- var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right;
5141
- var docLTR = doc.direction == "ltr";
5142
-
5143
- function add(left, top, width, bottom) {
5144
- if (top < 0) { top = 0; }
5145
- top = Math.round(top);
5146
- bottom = Math.round(bottom);
5147
- fragment.appendChild(elt("div", null, "CodeMirror-selected", ("position: absolute; left: " + left + "px;\n top: " + top + "px; width: " + (width == null ? rightSide - left : width) + "px;\n height: " + (bottom - top) + "px")));
5148
- }
5149
-
5150
- function drawForLine(line, fromArg, toArg) {
5151
- var lineObj = getLine(doc, line);
5152
- var lineLen = lineObj.text.length;
5153
- var start, end;
5154
- function coords(ch, bias) {
5155
- return charCoords(cm, Pos(line, ch), "div", lineObj, bias)
5156
- }
5157
-
5158
- function wrapX(pos, dir, side) {
5159
- var extent = wrappedLineExtentChar(cm, lineObj, null, pos);
5160
- var prop = (dir == "ltr") == (side == "after") ? "left" : "right";
5161
- var ch = side == "after" ? extent.begin : extent.end - (/\s/.test(lineObj.text.charAt(extent.end - 1)) ? 2 : 1);
5162
- return coords(ch, prop)[prop]
5163
- }
5164
-
5165
- var order = getOrder(lineObj, doc.direction);
5166
- iterateBidiSections(order, fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir, i) {
5167
- var ltr = dir == "ltr";
5168
- var fromPos = coords(from, ltr ? "left" : "right");
5169
- var toPos = coords(to - 1, ltr ? "right" : "left");
5170
-
5171
- var openStart = fromArg == null && from == 0, openEnd = toArg == null && to == lineLen;
5172
- var first = i == 0, last = !order || i == order.length - 1;
5173
- if (toPos.top - fromPos.top <= 3) { // Single line
5174
- var openLeft = (docLTR ? openStart : openEnd) && first;
5175
- var openRight = (docLTR ? openEnd : openStart) && last;
5176
- var left = openLeft ? leftSide : (ltr ? fromPos : toPos).left;
5177
- var right = openRight ? rightSide : (ltr ? toPos : fromPos).right;
5178
- add(left, fromPos.top, right - left, fromPos.bottom);
5179
- } else { // Multiple lines
5180
- var topLeft, topRight, botLeft, botRight;
5181
- if (ltr) {
5182
- topLeft = docLTR && openStart && first ? leftSide : fromPos.left;
5183
- topRight = docLTR ? rightSide : wrapX(from, dir, "before");
5184
- botLeft = docLTR ? leftSide : wrapX(to, dir, "after");
5185
- botRight = docLTR && openEnd && last ? rightSide : toPos.right;
5186
- } else {
5187
- topLeft = !docLTR ? leftSide : wrapX(from, dir, "before");
5188
- topRight = !docLTR && openStart && first ? rightSide : fromPos.right;
5189
- botLeft = !docLTR && openEnd && last ? leftSide : toPos.left;
5190
- botRight = !docLTR ? rightSide : wrapX(to, dir, "after");
5191
- }
5192
- add(topLeft, fromPos.top, topRight - topLeft, fromPos.bottom);
5193
- if (fromPos.bottom < toPos.top) { add(leftSide, fromPos.bottom, null, toPos.top); }
5194
- add(botLeft, toPos.top, botRight - botLeft, toPos.bottom);
5195
- }
5196
 
5197
- if (!start || cmpCoords(fromPos, start) < 0) { start = fromPos; }
5198
- if (cmpCoords(toPos, start) < 0) { start = toPos; }
5199
- if (!end || cmpCoords(fromPos, end) < 0) { end = fromPos; }
5200
- if (cmpCoords(toPos, end) < 0) { end = toPos; }
5201
- });
5202
- return {start: start, end: end}
5203
- }
5204
-
5205
- var sFrom = range$$1.from(), sTo = range$$1.to();
5206
- if (sFrom.line == sTo.line) {
5207
- drawForLine(sFrom.line, sFrom.ch, sTo.ch);
5208
- } else {
5209
- var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line);
5210
- var singleVLine = visualLine(fromLine) == visualLine(toLine);
5211
- var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end;
5212
- var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start;
5213
- if (singleVLine) {
5214
- if (leftEnd.top < rightStart.top - 2) {
5215
- add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);
5216
- add(leftSide, rightStart.top, rightStart.left, rightStart.bottom);
 
 
 
 
 
 
5217
  } else {
5218
- add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);
5219
  }
 
5220
  }
5221
- if (leftEnd.bottom < rightStart.top)
5222
- { add(leftSide, leftEnd.bottom, null, rightStart.top); }
 
 
 
 
5223
  }
5224
 
5225
- output.appendChild(fragment);
5226
- }
5227
-
5228
- // Cursor-blinking
5229
- function restartBlink(cm) {
5230
- if (!cm.state.focused) { return }
5231
- var display = cm.display;
5232
- clearInterval(display.blinker);
5233
- var on = true;
5234
- display.cursorDiv.style.visibility = "";
5235
- if (cm.options.cursorBlinkRate > 0)
5236
- { display.blinker = setInterval(function () { return display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; },
5237
- cm.options.cursorBlinkRate); }
5238
- else if (cm.options.cursorBlinkRate < 0)
5239
- { display.cursorDiv.style.visibility = "hidden"; }
5240
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5241
 
5242
- function ensureFocus(cm) {
5243
- if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); }
5244
- }
 
 
 
5245
 
5246
- function delayBlurEvent(cm) {
5247
- cm.state.delayingBlurEvent = true;
5248
- setTimeout(function () { if (cm.state.delayingBlurEvent) {
5249
- cm.state.delayingBlurEvent = false;
5250
- onBlur(cm);
5251
- } }, 100);
5252
- }
5253
 
5254
- function onFocus(cm, e) {
5255
- if (cm.state.delayingBlurEvent) { cm.state.delayingBlurEvent = false; }
5256
-
5257
- if (cm.options.readOnly == "nocursor") { return }
5258
- if (!cm.state.focused) {
5259
- signal(cm, "focus", cm, e);
5260
- cm.state.focused = true;
5261
- addClass(cm.display.wrapper, "CodeMirror-focused");
5262
- // This test prevents this from firing when a context
5263
- // menu is closed (since the input reset would kill the
5264
- // select-all detection hack)
5265
- if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) {
5266
- cm.display.input.reset();
5267
- if (webkit) { setTimeout(function () { return cm.display.input.reset(true); }, 20); } // Issue #1730
5268
  }
5269
- cm.display.input.receivedFocus();
5270
  }
5271
- restartBlink(cm);
5272
- }
5273
- function onBlur(cm, e) {
5274
- if (cm.state.delayingBlurEvent) { return }
5275
 
5276
- if (cm.state.focused) {
5277
- signal(cm, "blur", cm, e);
5278
- cm.state.focused = false;
5279
- rmClass(cm.display.wrapper, "CodeMirror-focused");
 
 
 
 
 
 
 
 
 
 
 
5280
  }
5281
- clearInterval(cm.display.blinker);
5282
- setTimeout(function () { if (!cm.state.focused) { cm.display.shift = false; } }, 150);
5283
- }
5284
 
5285
- // Read the actual heights of the rendered lines, and update their
5286
- // stored heights to match.
5287
- function updateHeightsInViewport(cm) {
5288
- var display = cm.display;
5289
- var prevBottom = display.lineDiv.offsetTop;
5290
- for (var i = 0; i < display.view.length; i++) {
5291
- var cur = display.view[i], height = (void 0);
5292
- if (cur.hidden) { continue }
5293
- if (ie && ie_version < 8) {
5294
- var bot = cur.node.offsetTop + cur.node.offsetHeight;
5295
- height = bot - prevBottom;
5296
- prevBottom = bot;
5297
- } else {
5298
- var box = cur.node.getBoundingClientRect();
5299
- height = box.bottom - box.top;
5300
- }
5301
- var diff = cur.line.height - height;
5302
- if (height < 2) { height = textHeight(display); }
5303
- if (diff > .005 || diff < -.005) {
5304
- updateLineHeight(cur.line, height);
5305
- updateWidgetHeight(cur.line);
5306
- if (cur.rest) { for (var j = 0; j < cur.rest.length; j++)
5307
- { updateWidgetHeight(cur.rest[j]); } }
5308
  }
5309
  }
5310
- }
5311
 
5312
- // Read and store the height of line widgets associated with the
5313
- // given line.
5314
- function updateWidgetHeight(line) {
5315
- if (line.widgets) { for (var i = 0; i < line.widgets.length; ++i) {
5316
- var w = line.widgets[i], parent = w.node.parentNode;
5317
- if (parent) { w.height = parent.offsetHeight; }
5318
- } }
5319
- }
5320
 
5321
- // Compute the lines that are visible in a given viewport (defaults
5322
- // the the current scroll position). viewport may contain top,
5323
- // height, and ensure (see op.scrollToPos) properties.
5324
- function visibleLines(display, doc, viewport) {
5325
- var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop;
5326
- top = Math.floor(top - paddingTop(display));
5327
- var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight;
5328
-
5329
- var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom);
5330
- // Ensure is a {from: {line, ch}, to: {line, ch}} object, and
5331
- // forces those lines into the viewport (if possible).
5332
- if (viewport && viewport.ensure) {
5333
- var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line;
5334
- if (ensureFrom < from) {
5335
- from = ensureFrom;
5336
- to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight);
5337
- } else if (Math.min(ensureTo, doc.lastLine()) >= to) {
5338
- from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight);
5339
- to = ensureTo;
5340
- }
5341
- }
5342
- return {from: from, to: Math.max(to, from + 1)}
5343
- }
5344
 
5345
- // Re-align line numbers and gutter marks to compensate for
5346
- // horizontal scrolling.
5347
- function alignHorizontally(cm) {
5348
- var display = cm.display, view = display.view;
5349
- if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) { return }
5350
- var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
5351
- var gutterW = display.gutters.offsetWidth, left = comp + "px";
5352
- for (var i = 0; i < view.length; i++) { if (!view[i].hidden) {
5353
- if (cm.options.fixedGutter) {
5354
- if (view[i].gutter)
5355
- { view[i].gutter.style.left = left; }
5356
- if (view[i].gutterBackground)
5357
- { view[i].gutterBackground.style.left = left; }
5358
- }
5359
- var align = view[i].alignable;
5360
- if (align) { for (var j = 0; j < align.length; j++)
5361
- { align[j].style.left = left; } }
5362
- } }
5363
- if (cm.options.fixedGutter)
5364
- { display.gutters.style.left = (comp + gutterW) + "px"; }
5365
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5366
 
5367
- // Used to ensure that the line number gutter is still the right
5368
- // size for the current document size. Returns true when an update
5369
- // is needed.
5370
- function maybeUpdateLineNumberWidth(cm) {
5371
- if (!cm.options.lineNumbers) { return false }
5372
- var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
5373
- if (last.length != display.lineNumChars) {
5374
- var test = display.measure.appendChild(elt("div", [elt("div", last)],
5375
- "CodeMirror-linenumber CodeMirror-gutter-elt"));
5376
- var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
5377
- display.lineGutter.style.width = "";
5378
- display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1;
5379
- display.lineNumWidth = display.lineNumInnerWidth + padding;
5380
- display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
5381
- display.lineGutter.style.width = display.lineNumWidth + "px";
5382
- updateGutterSpace(cm);
5383
  return true
5384
  }
5385
- return false
5386
- }
5387
-
5388
- // SCROLLING THINGS INTO VIEW
5389
 
5390
- // If an editor sits on the top or bottom of the window, partially
5391
- // scrolled out of view, this ensures that the cursor is visible.
5392
- function maybeScrollWindow(cm, rect) {
5393
- if (signalDOMEvent(cm, "scrollCursorIntoView")) { return }
5394
 
5395
- var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null;
5396
- if (rect.top + box.top < 0) { doScroll = true; }
5397
- else if (rect.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) { doScroll = false; }
5398
- if (doScroll != null && !phantom) {
5399
- var scrollNode = elt("div", "\u200b", null, ("position: absolute;\n top: " + (rect.top - display.viewOffset - paddingTop(cm.display)) + "px;\n height: " + (rect.bottom - rect.top + scrollGap(cm) + display.barHeight) + "px;\n left: " + (rect.left) + "px; width: " + (Math.max(2, rect.right - rect.left)) + "px;"));
5400
- cm.display.lineSpace.appendChild(scrollNode);
5401
- scrollNode.scrollIntoView(doScroll);
5402
- cm.display.lineSpace.removeChild(scrollNode);
5403
- }
5404
- }
5405
-
5406
- // Scroll a given position into view (immediately), verifying that
5407
- // it actually became visible (as line heights are accurately
5408
- // measured, the position of something may 'drift' during drawing).
5409
- function scrollPosIntoView(cm, pos, end, margin) {
5410
- if (margin == null) { margin = 0; }
5411
- var rect;
5412
- if (!cm.options.lineWrapping && pos == end) {
5413
- // Set pos and end to the cursor positions around the character pos sticks to
5414
- // If pos.sticky == "before", that is around pos.ch - 1, otherwise around pos.ch
5415
- // If pos == Pos(_, 0, "before"), pos and end are unchanged
5416
- pos = pos.ch ? Pos(pos.line, pos.sticky == "before" ? pos.ch - 1 : pos.ch, "after") : pos;
5417
- end = pos.sticky == "before" ? Pos(pos.line, pos.ch + 1, "before") : pos;
5418
- }
5419
- for (var limit = 0; limit < 5; limit++) {
5420
- var changed = false;
5421
- var coords = cursorCoords(cm, pos);
5422
- var endCoords = !end || end == pos ? coords : cursorCoords(cm, end);
5423
- rect = {left: Math.min(coords.left, endCoords.left),
5424
- top: Math.min(coords.top, endCoords.top) - margin,
5425
- right: Math.max(coords.left, endCoords.left),
5426
- bottom: Math.max(coords.bottom, endCoords.bottom) + margin};
5427
- var scrollPos = calculateScrollPos(cm, rect);
5428
- var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
5429
- if (scrollPos.scrollTop != null) {
5430
- updateScrollTop(cm, scrollPos.scrollTop);
5431
- if (Math.abs(cm.doc.scrollTop - startTop) > 1) { changed = true; }
5432
- }
5433
- if (scrollPos.scrollLeft != null) {
5434
- setScrollLeft(cm, scrollPos.scrollLeft);
5435
- if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) { changed = true; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5436
  }
5437
- if (!changed) { break }
5438
  }
5439
- return rect
5440
- }
5441
 
5442
- // Scroll a given set of coordinates into view (immediately).
5443
- function scrollIntoView(cm, rect) {
5444
- var scrollPos = calculateScrollPos(cm, rect);
5445
- if (scrollPos.scrollTop != null) { updateScrollTop(cm, scrollPos.scrollTop); }
5446
- if (scrollPos.scrollLeft != null) { setScrollLeft(cm, scrollPos.scrollLeft); }
5447
- }
5448
 
5449
- // Calculate a new scroll position needed to scroll the given
5450
- // rectangle into view. Returns an object with scrollTop and
5451
- // scrollLeft properties. When these are undefined, the
5452
- // vertical/horizontal position does not need to be adjusted.
5453
- function calculateScrollPos(cm, rect) {
5454
- var display = cm.display, snapMargin = textHeight(cm.display);
5455
- if (rect.top < 0) { rect.top = 0; }
5456
- var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop;
5457
- var screen = displayHeight(cm), result = {};
5458
- if (rect.bottom - rect.top > screen) { rect.bottom = rect.top + screen; }
5459
- var docBottom = cm.doc.height + paddingVert(display);
5460
- var atTop = rect.top < snapMargin, atBottom = rect.bottom > docBottom - snapMargin;
5461
- if (rect.top < screentop) {
5462
- result.scrollTop = atTop ? 0 : rect.top;
5463
- } else if (rect.bottom > screentop + screen) {
5464
- var newTop = Math.min(rect.top, (atBottom ? docBottom : rect.bottom) - screen);
5465
- if (newTop != screentop) { result.scrollTop = newTop; }
5466
- }
5467
-
5468
- var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft;
5469
- var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0);
5470
- var tooWide = rect.right - rect.left > screenw;
5471
- if (tooWide) { rect.right = rect.left + screenw; }
5472
- if (rect.left < 10)
5473
- { result.scrollLeft = 0; }
5474
- else if (rect.left < screenleft)
5475
- { result.scrollLeft = Math.max(0, rect.left - (tooWide ? 0 : 10)); }
5476
- else if (rect.right > screenw + screenleft - 3)
5477
- { result.scrollLeft = rect.right + (tooWide ? 0 : 10) - screenw; }
5478
- return result
5479
- }
5480
 
5481
- // Store a relative adjustment to the scroll position in the current
5482
- // operation (to be applied when the operation finishes).
5483
- function addToScrollTop(cm, top) {
5484
- if (top == null) { return }
5485
- resolveScrollToPos(cm);
5486
- cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top;
5487
- }
 
 
 
 
 
 
 
 
 
 
5488
 
5489
- // Make sure that at the end of the operation the current cursor is
5490
- // shown.
5491
- function ensureCursorVisible(cm) {
5492
- resolveScrollToPos(cm);
5493
- var cur = cm.getCursor();
5494
- cm.curOp.scrollToPos = {from: cur, to: cur, margin: cm.options.cursorScrollMargin};
5495
- }
 
 
 
 
5496
 
5497
- function scrollToCoords(cm, x, y) {
5498
- if (x != null || y != null) { resolveScrollToPos(cm); }
5499
- if (x != null) { cm.curOp.scrollLeft = x; }
5500
- if (y != null) { cm.curOp.scrollTop = y; }
5501
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5502
 
5503
- function scrollToRange(cm, range$$1) {
5504
- resolveScrollToPos(cm);
5505
- cm.curOp.scrollToPos = range$$1;
5506
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5507
 
5508
- // When an operation has its scrollToPos property set, and another
5509
- // scroll action is applied before the end of the operation, this
5510
- // 'simulates' scrolling that position into view in a cheap way, so
5511
- // that the effect of intermediate scroll commands is not ignored.
5512
- function resolveScrollToPos(cm) {
5513
- var range$$1 = cm.curOp.scrollToPos;
5514
- if (range$$1) {
5515
- cm.curOp.scrollToPos = null;
5516
- var from = estimateCoords(cm, range$$1.from), to = estimateCoords(cm, range$$1.to);
5517
- scrollToCoordsRange(cm, from, to, range$$1.margin);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5518
  }
5519
- }
5520
 
5521
- function scrollToCoordsRange(cm, from, to, margin) {
5522
- var sPos = calculateScrollPos(cm, {
5523
- left: Math.min(from.left, to.left),
5524
- top: Math.min(from.top, to.top) - margin,
5525
- right: Math.max(from.right, to.right),
5526
- bottom: Math.max(from.bottom, to.bottom) + margin
5527
- });
5528
- scrollToCoords(cm, sPos.scrollLeft, sPos.scrollTop);
5529
- }
5530
 
5531
- // Sync the scrollable area and scrollbars, ensure the viewport
5532
- // covers the visible area.
5533
- function updateScrollTop(cm, val) {
5534
- if (Math.abs(cm.doc.scrollTop - val) < 2) { return }
5535
- if (!gecko) { updateDisplaySimple(cm, {top: val}); }
5536
- setScrollTop(cm, val, true);
5537
- if (gecko) { updateDisplaySimple(cm); }
5538
- startWorker(cm, 100);
5539
- }
5540
 
5541
- function setScrollTop(cm, val, forceScroll) {
5542
- val = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val);
5543
- if (cm.display.scroller.scrollTop == val && !forceScroll) { return }
5544
- cm.doc.scrollTop = val;
5545
- cm.display.scrollbars.setScrollTop(val);
5546
- if (cm.display.scroller.scrollTop != val) { cm.display.scroller.scrollTop = val; }
5547
- }
5548
 
5549
- // Sync scroller and scrollbar, ensure the gutter elements are
5550
- // aligned.
5551
- function setScrollLeft(cm, val, isScroller, forceScroll) {
5552
- val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
5553
- if ((isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) && !forceScroll) { return }
5554
- cm.doc.scrollLeft = val;
5555
- alignHorizontally(cm);
5556
- if (cm.display.scroller.scrollLeft != val) { cm.display.scroller.scrollLeft = val; }
5557
- cm.display.scrollbars.setScrollLeft(val);
5558
- }
5559
 
5560
- // SCROLLBARS
 
5561
 
5562
- // Prepare DOM reads needed to update the scrollbars. Done in one
5563
- // shot to minimize update/measure roundtrips.
5564
- function measureForScrollbars(cm) {
5565
- var d = cm.display, gutterW = d.gutters.offsetWidth;
5566
- var docH = Math.round(cm.doc.height + paddingVert(cm.display));
5567
- return {
5568
- clientHeight: d.scroller.clientHeight,
5569
- viewHeight: d.wrapper.clientHeight,
5570
- scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth,
5571
- viewWidth: d.wrapper.clientWidth,
5572
- barLeft: cm.options.fixedGutter ? gutterW : 0,
5573
- docHeight: docH,
5574
- scrollHeight: docH + scrollGap(cm) + d.barHeight,
5575
- nativeBarWidth: d.nativeBarWidth,
5576
- gutterWidth: gutterW
5577
- }
5578
- }
5579
 
5580
- var NativeScrollbars = function(place, scroll, cm) {
5581
- this.cm = cm;
5582
- var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar");
5583
- var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar");
5584
- vert.tabIndex = horiz.tabIndex = -1;
5585
- place(vert); place(horiz);
5586
 
5587
- on(vert, "scroll", function () {
5588
- if (vert.clientHeight) { scroll(vert.scrollTop, "vertical"); }
5589
- });
5590
- on(horiz, "scroll", function () {
5591
- if (horiz.clientWidth) { scroll(horiz.scrollLeft, "horizontal"); }
5592
- });
5593
 
5594
- this.checkedZeroWidth = false;
5595
- // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
5596
- if (ie && ie_version < 8) { this.horiz.style.minHeight = this.vert.style.minWidth = "18px"; }
5597
- };
5598
 
5599
- NativeScrollbars.prototype.update = function (measure) {
5600
- var needsH = measure.scrollWidth > measure.clientWidth + 1;
5601
- var needsV = measure.scrollHeight > measure.clientHeight + 1;
5602
- var sWidth = measure.nativeBarWidth;
5603
-
5604
- if (needsV) {
5605
- this.vert.style.display = "block";
5606
- this.vert.style.bottom = needsH ? sWidth + "px" : "0";
5607
- var totalHeight = measure.viewHeight - (needsH ? sWidth : 0);
5608
- // A bug in IE8 can cause this value to be negative, so guard it.
5609
- this.vert.firstChild.style.height =
5610
- Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px";
5611
- } else {
5612
- this.vert.style.display = "";
5613
- this.vert.firstChild.style.height = "0";
5614
- }
5615
-
5616
- if (needsH) {
5617
- this.horiz.style.display = "block";
5618
- this.horiz.style.right = needsV ? sWidth + "px" : "0";
5619
- this.horiz.style.left = measure.barLeft + "px";
5620
- var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0);
5621
- this.horiz.firstChild.style.width =
5622
- Math.max(0, measure.scrollWidth - measure.clientWidth + totalWidth) + "px";
5623
- } else {
5624
- this.horiz.style.display = "";
5625
- this.horiz.firstChild.style.width = "0";
5626
- }
5627
-
5628
- if (!this.checkedZeroWidth && measure.clientHeight > 0) {
5629
- if (sWidth == 0) { this.zeroWidthHack(); }
5630
- this.checkedZeroWidth = true;
5631
- }
5632
-
5633
- return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0}
5634
- };
5635
 
5636
- NativeScrollbars.prototype.setScrollLeft = function (pos) {
5637
- if (this.horiz.scrollLeft != pos) { this.horiz.scrollLeft = pos; }
5638
- if (this.disableHoriz) { this.enableZeroWidthBar(this.horiz, this.disableHoriz, "horiz"); }
5639
- };
5640
 
5641
- NativeScrollbars.prototype.setScrollTop = function (pos) {
5642
- if (this.vert.scrollTop != pos) { this.vert.scrollTop = pos; }
5643
- if (this.disableVert) { this.enableZeroWidthBar(this.vert, this.disableVert, "vert"); }
5644
- };
5645
 
5646
- NativeScrollbars.prototype.zeroWidthHack = function () {
5647
- var w = mac && !mac_geMountainLion ? "12px" : "18px";
5648
- this.horiz.style.height = this.vert.style.width = w;
5649
- this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none";
5650
- this.disableHoriz = new Delayed;
5651
- this.disableVert = new Delayed;
5652
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
5653
 
5654
- NativeScrollbars.prototype.enableZeroWidthBar = function (bar, delay, type) {
5655
- bar.style.pointerEvents = "auto";
5656
- function maybeDisable() {
5657
- // To find out whether the scrollbar is still visible, we
5658
- // check whether the element under the pixel in the bottom
5659
- // right corner of the scrollbar box is the scrollbar box
5660
- // itself (when the bar is still visible) or its filler child
5661
- // (when the bar is hidden). If it is still visible, we keep
5662
- // it enabled, if it's hidden, we disable pointer events.
5663
- var box = bar.getBoundingClientRect();
5664
- var elt$$1 = type == "vert" ? document.elementFromPoint(box.right - 1, (box.top + box.bottom) / 2)
5665
- : document.elementFromPoint((box.right + box.left) / 2, box.bottom - 1);
5666
- if (elt$$1 != bar) { bar.style.pointerEvents = "none"; }
5667
- else { delay.set(1000, maybeDisable); }
5668
- }
5669
- delay.set(1000, maybeDisable);
5670
- };
5671
 
5672
- NativeScrollbars.prototype.clear = function () {
5673
- var parent = this.horiz.parentNode;
5674
- parent.removeChild(this.horiz);
5675
- parent.removeChild(this.vert);
5676
- };
 
 
 
 
 
 
 
 
5677
 
5678
- var NullScrollbars = function () {};
 
 
 
5679
 
5680
- NullScrollbars.prototype.update = function () { return {bottom: 0, right: 0} };
5681
- NullScrollbars.prototype.setScrollLeft = function () {};
5682
- NullScrollbars.prototype.setScrollTop = function () {};
5683
- NullScrollbars.prototype.clear = function () {};
 
 
 
 
 
5684
 
5685
- function updateScrollbars(cm, measure) {
5686
- if (!measure) { measure = measureForScrollbars(cm); }
5687
- var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight;
5688
- updateScrollbarsInner(cm, measure);
5689
- for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) {
5690
- if (startWidth != cm.display.barWidth && cm.options.lineWrapping)
5691
- { updateHeightsInViewport(cm); }
5692
- updateScrollbarsInner(cm, measureForScrollbars(cm));
5693
- startWidth = cm.display.barWidth; startHeight = cm.display.barHeight;
5694
  }
5695
- }
5696
 
5697
- // Re-synchronize the fake scrollbars with the actual size of the
5698
- // content.
5699
- function updateScrollbarsInner(cm, measure) {
5700
- var d = cm.display;
5701
- var sizes = d.scrollbars.update(measure);
5702
-
5703
- d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px";
5704
- d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px";
5705
- d.heightForcer.style.borderBottom = sizes.bottom + "px solid transparent";
5706
-
5707
- if (sizes.right && sizes.bottom) {
5708
- d.scrollbarFiller.style.display = "block";
5709
- d.scrollbarFiller.style.height = sizes.bottom + "px";
5710
- d.scrollbarFiller.style.width = sizes.right + "px";
5711
- } else { d.scrollbarFiller.style.display = ""; }
5712
- if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
5713
- d.gutterFiller.style.display = "block";
5714
- d.gutterFiller.style.height = sizes.bottom + "px";
5715
- d.gutterFiller.style.width = measure.gutterWidth + "px";
5716
- } else { d.gutterFiller.style.display = ""; }
5717
- }
5718
 
5719
- var scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars};
5720
 
5721
- function initScrollbars(cm) {
5722
- if (cm.display.scrollbars) {
5723
- cm.display.scrollbars.clear();
5724
- if (cm.display.scrollbars.addClass)
5725
- { rmClass(cm.display.wrapper, cm.display.scrollbars.addClass); }
5726
  }
5727
 
5728
- cm.display.scrollbars = new scrollbarModel[cm.options.scrollbarStyle](function (node) {
5729
- cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller);
5730
- // Prevent clicks in the scrollbars from killing focus
5731
- on(node, "mousedown", function () {
5732
- if (cm.state.focused) { setTimeout(function () { return cm.display.input.focus(); }, 0); }
5733
  });
5734
- node.setAttribute("cm-not-content", "true");
5735
- }, function (pos, axis) {
5736
- if (axis == "horizontal") { setScrollLeft(cm, pos); }
5737
- else { updateScrollTop(cm, pos); }
5738
- }, cm);
5739
- if (cm.display.scrollbars.addClass)
5740
- { addClass(cm.display.wrapper, cm.display.scrollbars.addClass); }
5741
- }
5742
-
5743
- // Operations are used to wrap a series of changes to the editor
5744
- // state in such a way that each change won't have to update the
5745
- // cursor and display (which would be awkward, slow, and
5746
- // error-prone). Instead, display updates are batched and then all
5747
- // combined and executed at once.
5748
-
5749
- var nextOpId = 0;
5750
- // Start a new operation.
5751
- function startOperation(cm) {
5752
- cm.curOp = {
5753
- cm: cm,
5754
- viewChanged: false, // Flag that indicates that lines might need to be redrawn
5755
- startHeight: cm.doc.height, // Used to detect need to update scrollbar
5756
- forceUpdate: false, // Used to force a redraw
5757
- updateInput: null, // Whether to reset the input textarea
5758
- typing: false, // Whether this reset should be careful to leave existing text (for compositing)
5759
- changeObjs: null, // Accumulated changes, for firing change events
5760
- cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on
5761
- cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already
5762
- selectionChanged: false, // Whether the selection needs to be redrawn
5763
- updateMaxLine: false, // Set when the widest line needs to be determined anew
5764
- scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet
5765
- scrollToPos: null, // Used to scroll to a specific position
5766
- focus: false,
5767
- id: ++nextOpId // Unique ID
5768
- };
5769
- pushOperation(cm.curOp);
5770
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5771
 
5772
- // Finish an operation, updating the display and signalling delayed events
5773
- function endOperation(cm) {
5774
- var op = cm.curOp;
5775
- finishOperation(op, function (group) {
5776
- for (var i = 0; i < group.ops.length; i++)
5777
- { group.ops[i].cm.curOp = null; }
5778
- endOperations(group);
5779
- });
5780
- }
5781
 
5782
- // The DOM updates done when an operation finishes are batched so
5783
- // that the minimum number of relayouts are required.
5784
- function endOperations(group) {
5785
- var ops = group.ops;
5786
- for (var i = 0; i < ops.length; i++) // Read DOM
5787
- { endOperation_R1(ops[i]); }
5788
- for (var i$1 = 0; i$1 < ops.length; i$1++) // Write DOM (maybe)
5789
- { endOperation_W1(ops[i$1]); }
5790
- for (var i$2 = 0; i$2 < ops.length; i$2++) // Read DOM
5791
- { endOperation_R2(ops[i$2]); }
5792
- for (var i$3 = 0; i$3 < ops.length; i$3++) // Write DOM (maybe)
5793
- { endOperation_W2(ops[i$3]); }
5794
- for (var i$4 = 0; i$4 < ops.length; i$4++) // Read DOM
5795
- { endOperation_finish(ops[i$4]); }
5796
- }
5797
 
5798
- function endOperation_R1(op) {
5799
- var cm = op.cm, display = cm.display;
5800
- maybeClipScrollbars(cm);
5801
- if (op.updateMaxLine) { findMaxLine(cm); }
5802
-
5803
- op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null ||
5804
- op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom ||
5805
- op.scrollToPos.to.line >= display.viewTo) ||
5806
- display.maxLineChanged && cm.options.lineWrapping;
5807
- op.update = op.mustUpdate &&
5808
- new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate);
5809
- }
5810
 
5811
- function endOperation_W1(op) {
5812
- op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update);
5813
- }
 
 
 
 
 
 
 
5814
 
5815
- function endOperation_R2(op) {
5816
- var cm = op.cm, display = cm.display;
5817
- if (op.updatedDisplay) { updateHeightsInViewport(cm); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5818
 
5819
- op.barMeasure = measureForScrollbars(cm);
 
 
 
 
 
5820
 
5821
- // If the max line changed since it was last measured, measure it,
5822
- // and ensure the document's width matches it.
5823
- // updateDisplay_W2 will use these properties to do the actual resizing
5824
- if (display.maxLineChanged && !cm.options.lineWrapping) {
5825
- op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3;
5826
- cm.display.sizerWidth = op.adjustWidthTo;
5827
- op.barMeasure.scrollWidth =
5828
- Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth);
5829
- op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm));
5830
  }
5831
 
5832
- if (op.updatedDisplay || op.selectionChanged)
5833
- { op.preparedSelection = display.input.prepareSelection(); }
5834
- }
 
 
 
 
 
 
5835
 
5836
- function endOperation_W2(op) {
5837
- var cm = op.cm;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5838
 
5839
- if (op.adjustWidthTo != null) {
5840
- cm.display.sizer.style.minWidth = op.adjustWidthTo + "px";
5841
- if (op.maxScrollLeft < cm.doc.scrollLeft)
5842
- { setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true); }
5843
- cm.display.maxLineChanged = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5844
  }
5845
 
5846
- var takeFocus = op.focus && op.focus == activeElt();
5847
- if (op.preparedSelection)
5848
- { cm.display.input.showSelection(op.preparedSelection, takeFocus); }
5849
- if (op.updatedDisplay || op.startHeight != cm.doc.height)
5850
- { updateScrollbars(cm, op.barMeasure); }
5851
- if (op.updatedDisplay)
5852
- { setDocumentHeight(cm, op.barMeasure); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5853
 
5854
- if (op.selectionChanged) { restartBlink(cm); }
 
 
 
 
5855
 
5856
- if (cm.state.focused && op.updateInput)
5857
- { cm.display.input.reset(op.typing); }
5858
- if (takeFocus) { ensureFocus(op.cm); }
5859
- }
 
 
 
 
 
 
5860
 
5861
- function endOperation_finish(op) {
5862
- var cm = op.cm, display = cm.display, doc = cm.doc;
 
 
 
 
5863
 
5864
- if (op.updatedDisplay) { postUpdateDisplay(cm, op.update); }
 
 
 
5865
 
5866
- // Abort mouse wheel delta measurement, when scrolling explicitly
5867
- if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos))
5868
- { display.wheelStartX = display.wheelStartY = null; }
 
 
 
 
5869
 
5870
- // Propagate the scroll position to the actual DOM scroller
5871
- if (op.scrollTop != null) { setScrollTop(cm, op.scrollTop, op.forceScroll); }
 
 
 
 
 
 
 
 
 
 
5872
 
5873
- if (op.scrollLeft != null) { setScrollLeft(cm, op.scrollLeft, true, true); }
5874
- // If we need to scroll a specific position into view, do so.
5875
- if (op.scrollToPos) {
5876
- var rect = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from),
5877
- clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin);
5878
- maybeScrollWindow(cm, rect);
 
 
5879
  }
5880
 
5881
- // Fire events for markers that are hidden/unidden by editing or
5882
- // undoing
5883
- var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;
5884
- if (hidden) { for (var i = 0; i < hidden.length; ++i)
5885
- { if (!hidden[i].lines.length) { signal(hidden[i], "hide"); } } }
5886
- if (unhidden) { for (var i$1 = 0; i$1 < unhidden.length; ++i$1)
5887
- { if (unhidden[i$1].lines.length) { signal(unhidden[i$1], "unhide"); } } }
5888
 
5889
- if (display.wrapper.offsetHeight)
5890
- { doc.scrollTop = cm.display.scroller.scrollTop; }
 
5891
 
5892
- // Fire change events, and delayed event handlers
5893
- if (op.changeObjs)
5894
- { signal(cm, "changes", cm, op.changeObjs); }
5895
- if (op.update)
5896
- { op.update.finish(); }
5897
- }
5898
 
5899
- // Run the given function in an operation
5900
- function runInOp(cm, f) {
5901
- if (cm.curOp) { return f() }
5902
- startOperation(cm);
5903
- try { return f() }
5904
- finally { endOperation(cm); }
5905
- }
5906
- // Wraps a function in an operation. Returns the wrapped function.
5907
- function operation(cm, f) {
5908
- return function() {
5909
- if (cm.curOp) { return f.apply(cm, arguments) }
5910
- startOperation(cm);
5911
- try { return f.apply(cm, arguments) }
5912
- finally { endOperation(cm); }
5913
  }
5914
- }
5915
- // Used to add methods to editor and doc instances, wrapping them in
5916
- // operations.
5917
- function methodOp(f) {
5918
- return function() {
5919
- if (this.curOp) { return f.apply(this, arguments) }
5920
- startOperation(this);
5921
- try { return f.apply(this, arguments) }
5922
- finally { endOperation(this); }
 
 
5923
  }
5924
- }
5925
- function docMethodOp(f) {
5926
- return function() {
5927
- var cm = this.cm;
5928
- if (!cm || cm.curOp) { return f.apply(this, arguments) }
5929
- startOperation(cm);
5930
- try { return f.apply(this, arguments) }
5931
- finally { endOperation(cm); }
5932
  }
5933
- }
5934
 
5935
- // Updates the display.view data structure for a given change to the
5936
- // document. From and to are in pre-change coordinates. Lendiff is
5937
- // the amount of lines added or subtracted by the change. This is
5938
- // used for changes that span multiple lines, or change the way
5939
- // lines are divided into visual lines. regLineChange (below)
5940
- // registers single-line changes.
5941
- function regChange(cm, from, to, lendiff) {
5942
- if (from == null) { from = cm.doc.first; }
5943
- if (to == null) { to = cm.doc.first + cm.doc.size; }
5944
- if (!lendiff) { lendiff = 0; }
5945
-
5946
- var display = cm.display;
5947
- if (lendiff && to < display.viewTo &&
5948
- (display.updateLineNumbers == null || display.updateLineNumbers > from))
5949
- { display.updateLineNumbers = from; }
5950
-
5951
- cm.curOp.viewChanged = true;
5952
-
5953
- if (from >= display.viewTo) { // Change after
5954
- if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo)
5955
- { resetView(cm); }
5956
- } else if (to <= display.viewFrom) { // Change before
5957
- if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) {
5958
- resetView(cm);
5959
- } else {
5960
- display.viewFrom += lendiff;
5961
- display.viewTo += lendiff;
5962
- }
5963
- } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap
5964
- resetView(cm);
5965
- } else if (from <= display.viewFrom) { // Top overlap
5966
- var cut = viewCuttingPoint(cm, to, to + lendiff, 1);
5967
- if (cut) {
5968
- display.view = display.view.slice(cut.index);
5969
- display.viewFrom = cut.lineN;
5970
- display.viewTo += lendiff;
5971
- } else {
5972
- resetView(cm);
5973
  }
5974
- } else if (to >= display.viewTo) { // Bottom overlap
5975
- var cut$1 = viewCuttingPoint(cm, from, from, -1);
5976
- if (cut$1) {
5977
- display.view = display.view.slice(0, cut$1.index);
5978
- display.viewTo = cut$1.lineN;
5979
- } else {
5980
- resetView(cm);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5981
  }
5982
- } else { // Gap in the middle
5983
- var cutTop = viewCuttingPoint(cm, from, from, -1);
5984
- var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1);
5985
- if (cutTop && cutBot) {
5986
- display.view = display.view.slice(0, cutTop.index)
5987
- .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN))
5988
- .concat(display.view.slice(cutBot.index));
5989
- display.viewTo += lendiff;
 
 
5990
  } else {
5991
- resetView(cm);
5992
  }
5993
  }
5994
 
5995
- var ext = display.externalMeasured;
5996
- if (ext) {
5997
- if (to < ext.lineN)
5998
- { ext.lineN += lendiff; }
5999
- else if (from < ext.lineN + ext.size)
6000
- { display.externalMeasured = null; }
6001
  }
6002
- }
6003
 
6004
- // Register a change to a single line. Type must be one of "text",
6005
- // "gutter", "class", "widget"
6006
- function regLineChange(cm, line, type) {
6007
- cm.curOp.viewChanged = true;
6008
- var display = cm.display, ext = cm.display.externalMeasured;
6009
- if (ext && line >= ext.lineN && line < ext.lineN + ext.size)
6010
- { display.externalMeasured = null; }
6011
-
6012
- if (line < display.viewFrom || line >= display.viewTo) { return }
6013
- var lineView = display.view[findViewIndex(cm, line)];
6014
- if (lineView.node == null) { return }
6015
- var arr = lineView.changes || (lineView.changes = []);
6016
- if (indexOf(arr, type) == -1) { arr.push(type); }
6017
- }
6018
-
6019
- // Clear the view.
6020
- function resetView(cm) {
6021
- cm.display.viewFrom = cm.display.viewTo = cm.doc.first;
6022
- cm.display.view = [];
6023
- cm.display.viewOffset = 0;
6024
- }
6025
 
6026
- function viewCuttingPoint(cm, oldN, newN, dir) {
6027
- var index = findViewIndex(cm, oldN), diff, view = cm.display.view;
6028
- if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size)
6029
- { return {index: index, lineN: newN} }
6030
- var n = cm.display.viewFrom;
6031
- for (var i = 0; i < index; i++)
6032
- { n += view[i].size; }
6033
- if (n != oldN) {
6034
- if (dir > 0) {
6035
- if (index == view.length - 1) { return null }
6036
- diff = (n + view[index].size) - oldN;
6037
- index++;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6038
  } else {
6039
- diff = n - oldN;
6040
  }
6041
- oldN += diff; newN += diff;
6042
  }
6043
- while (visualLineNo(cm.doc, newN) != newN) {
6044
- if (index == (dir < 0 ? 0 : view.length - 1)) { return null }
6045
- newN += dir * view[index - (dir < 0 ? 1 : 0)].size;
6046
- index += dir;
6047
- }
6048
- return {index: index, lineN: newN}
6049
- }
6050
 
6051
- // Force the view to cover a given range, adding empty view element
6052
- // or clipping off existing ones as needed.
6053
- function adjustView(cm, from, to) {
6054
- var display = cm.display, view = display.view;
6055
- if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) {
6056
- display.view = buildViewArray(cm, from, to);
6057
- display.viewFrom = from;
6058
- } else {
6059
- if (display.viewFrom > from)
6060
- { display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view); }
6061
- else if (display.viewFrom < from)
6062
- { display.view = display.view.slice(findViewIndex(cm, from)); }
6063
- display.viewFrom = from;
6064
- if (display.viewTo < to)
6065
- { display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)); }
6066
- else if (display.viewTo > to)
6067
- { display.view = display.view.slice(0, findViewIndex(cm, to)); }
6068
- }
6069
- display.viewTo = to;
6070
- }
6071
 
6072
- // Count the number of lines in the view whose DOM representation is
6073
- // out of date (or nonexistent).
6074
- function countDirtyView(cm) {
6075
- var view = cm.display.view, dirty = 0;
6076
- for (var i = 0; i < view.length; i++) {
6077
- var lineView = view[i];
6078
- if (!lineView.hidden && (!lineView.node || lineView.changes)) { ++dirty; }
6079
  }
6080
- return dirty
6081
- }
6082
 
6083
- // HIGHLIGHT WORKER
 
 
 
6084
 
6085
- function startWorker(cm, time) {
6086
- if (cm.doc.highlightFrontier < cm.display.viewTo)
6087
- { cm.state.highlight.set(time, bind(highlightWorker, cm)); }
6088
- }
6089
 
6090
- function highlightWorker(cm) {
6091
- var doc = cm.doc;
6092
- if (doc.highlightFrontier >= cm.display.viewTo) { return }
6093
- var end = +new Date + cm.options.workTime;
6094
- var context = getContextBefore(cm, doc.highlightFrontier);
6095
- var changedLines = [];
6096
-
6097
- doc.iter(context.line, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function (line) {
6098
- if (context.line >= cm.display.viewFrom) { // Visible
6099
- var oldStyles = line.styles;
6100
- var resetState = line.text.length > cm.options.maxHighlightLength ? copyState(doc.mode, context.state) : null;
6101
- var highlighted = highlightLine(cm, line, context, true);
6102
- if (resetState) { context.state = resetState; }
6103
- line.styles = highlighted.styles;
6104
- var oldCls = line.styleClasses, newCls = highlighted.classes;
6105
- if (newCls) { line.styleClasses = newCls; }
6106
- else if (oldCls) { line.styleClasses = null; }
6107
- var ischange = !oldStyles || oldStyles.length != line.styles.length ||
6108
- oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass);
6109
- for (var i = 0; !ischange && i < oldStyles.length; ++i) { ischange = oldStyles[i] != line.styles[i]; }
6110
- if (ischange) { changedLines.push(context.line); }
6111
- line.stateAfter = context.save();
6112
- context.nextLine();
6113
- } else {
6114
- if (line.text.length <= cm.options.maxHighlightLength)
6115
- { processLine(cm, line.text, context); }
6116
- line.stateAfter = context.line % 5 == 0 ? context.save() : null;
6117
- context.nextLine();
6118
  }
6119
- if (+new Date > end) {
6120
- startWorker(cm, cm.options.workDelay);
6121
- return true
 
 
 
 
 
 
 
 
 
 
 
 
 
6122
  }
6123
- });
6124
- doc.highlightFrontier = context.line;
6125
- doc.modeFrontier = Math.max(doc.modeFrontier, context.line);
6126
- if (changedLines.length) { runInOp(cm, function () {
6127
- for (var i = 0; i < changedLines.length; i++)
6128
- { regLineChange(cm, changedLines[i], "text"); }
6129
- }); }
6130
- }
6131
 
6132
- // DISPLAY DRAWING
6133
-
6134
- var DisplayUpdate = function(cm, viewport, force) {
6135
- var display = cm.display;
6136
-
6137
- this.viewport = viewport;
6138
- // Store some values that we'll need later (but don't want to force a relayout for)
6139
- this.visible = visibleLines(display, cm.doc, viewport);
6140
- this.editorIsHidden = !display.wrapper.offsetWidth;
6141
- this.wrapperHeight = display.wrapper.clientHeight;
6142
- this.wrapperWidth = display.wrapper.clientWidth;
6143
- this.oldDisplayWidth = displayWidth(cm);
6144
- this.force = force;
6145
- this.dims = getDimensions(cm);
6146
- this.events = [];
6147
- };
6148
 
6149
- DisplayUpdate.prototype.signal = function (emitter, type) {
6150
- if (hasHandler(emitter, type))
6151
- { this.events.push(arguments); }
6152
- };
6153
- DisplayUpdate.prototype.finish = function () {
6154
- var this$1 = this;
6155
 
6156
- for (var i = 0; i < this.events.length; i++)
6157
- { signal.apply(null, this$1.events[i]); }
6158
- };
 
 
 
 
6159
 
6160
- function maybeClipScrollbars(cm) {
6161
- var display = cm.display;
6162
- if (!display.scrollbarsClipped && display.scroller.offsetWidth) {
6163
- display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth;
6164
- display.heightForcer.style.height = scrollGap(cm) + "px";
6165
- display.sizer.style.marginBottom = -display.nativeBarWidth + "px";
6166
- display.sizer.style.borderRightWidth = scrollGap(cm) + "px";
6167
- display.scrollbarsClipped = true;
6168
- }
6169
- }
6170
 
6171
- function selectionSnapshot(cm) {
6172
- if (cm.hasFocus()) { return null }
6173
- var active = activeElt();
6174
- if (!active || !contains(cm.display.lineDiv, active)) { return null }
6175
- var result = {activeElt: active};
6176
- if (window.getSelection) {
6177
- var sel = window.getSelection();
6178
- if (sel.anchorNode && sel.extend && contains(cm.display.lineDiv, sel.anchorNode)) {
6179
- result.anchorNode = sel.anchorNode;
6180
- result.anchorOffset = sel.anchorOffset;
6181
- result.focusNode = sel.focusNode;
6182
- result.focusOffset = sel.focusOffset;
6183
- }
6184
- }
6185
- return result
6186
- }
6187
 
6188
- function restoreSelection(snapshot) {
6189
- if (!snapshot || !snapshot.activeElt || snapshot.activeElt == activeElt()) { return }
6190
- snapshot.activeElt.focus();
6191
- if (snapshot.anchorNode && contains(document.body, snapshot.anchorNode) && contains(document.body, snapshot.focusNode)) {
6192
- var sel = window.getSelection(), range$$1 = document.createRange();
6193
- range$$1.setEnd(snapshot.anchorNode, snapshot.anchorOffset);
6194
- range$$1.collapse(false);
6195
- sel.removeAllRanges();
6196
- sel.addRange(range$$1);
6197
- sel.extend(snapshot.focusNode, snapshot.focusOffset);
6198
- }
6199
- }
6200
 
6201
- // Does the actual updating of the line display. Bails out
6202
- // (returning false) when there is nothing to be done and forced is
6203
- // false.
6204
- function updateDisplayIfNeeded(cm, update) {
6205
- var display = cm.display, doc = cm.doc;
6206
 
6207
- if (update.editorIsHidden) {
6208
- resetView(cm);
6209
- return false
6210
  }
6211
 
6212
- // Bail out if the visible area is already rendered and nothing changed.
6213
- if (!update.force &&
6214
- update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo &&
6215
- (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) &&
6216
- display.renderedView == display.view && countDirtyView(cm) == 0)
6217
- { return false }
6218
-
6219
- if (maybeUpdateLineNumberWidth(cm)) {
6220
- resetView(cm);
6221
- update.dims = getDimensions(cm);
6222
- }
6223
-
6224
- // Compute a suitable new viewport (from & to)
6225
- var end = doc.first + doc.size;
6226
- var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first);
6227
- var to = Math.min(end, update.visible.to + cm.options.viewportMargin);
6228
- if (display.viewFrom < from && from - display.viewFrom < 20) { from = Math.max(doc.first, display.viewFrom); }
6229
- if (display.viewTo > to && display.viewTo - to < 20) { to = Math.min(end, display.viewTo); }
6230
- if (sawCollapsedSpans) {
6231
- from = visualLineNo(cm.doc, from);
6232
- to = visualLineEndNo(cm.doc, to);
6233
- }
6234
-
6235
- var different = from != display.viewFrom || to != display.viewTo ||
6236
- display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth;
6237
- adjustView(cm, from, to);
6238
-
6239
- display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom));
6240
- // Position the mover div to align with the current scroll position
6241
- cm.display.mover.style.top = display.viewOffset + "px";
6242
-
6243
- var toUpdate = countDirtyView(cm);
6244
- if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view &&
6245
- (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo))
6246
- { return false }
6247
-
6248
- // For big changes, we hide the enclosing element during the
6249
- // update, since that speeds up the operations on most browsers.
6250
- var selSnapshot = selectionSnapshot(cm);
6251
- if (toUpdate > 4) { display.lineDiv.style.display = "none"; }
6252
- patchDisplay(cm, display.updateLineNumbers, update.dims);
6253
- if (toUpdate > 4) { display.lineDiv.style.display = ""; }
6254
- display.renderedView = display.view;
6255
- // There might have been a widget with a focused element that got
6256
- // hidden or updated, if so re-focus it.
6257
- restoreSelection(selSnapshot);
6258
-
6259
- // Prevent selection and cursors from interfering with the scroll
6260
- // width and height.
6261
- removeChildren(display.cursorDiv);
6262
- removeChildren(display.selectionDiv);
6263
- display.gutters.style.height = display.sizer.style.minHeight = 0;
6264
-
6265
- if (different) {
6266
- display.lastWrapHeight = update.wrapperHeight;
6267
- display.lastWrapWidth = update.wrapperWidth;
6268
- startWorker(cm, 400);
6269
  }
6270
 
6271
- display.updateLineNumbers = null;
 
 
 
 
6272
 
6273
- return true
6274
- }
 
 
 
6275
 
6276
- function postUpdateDisplay(cm, update) {
6277
- var viewport = update.viewport;
6278
-
6279
- for (var first = true;; first = false) {
6280
- if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) {
6281
- // Clip forced viewport to actual scrollable area.
6282
- if (viewport && viewport.top != null)
6283
- { viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)}; }
6284
- // Updated line heights might result in the drawn area not
6285
- // actually covering the viewport. Keep looping until it does.
6286
- update.visible = visibleLines(cm.display, cm.doc, viewport);
6287
- if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)
6288
- { break }
6289
  }
6290
- if (!updateDisplayIfNeeded(cm, update)) { break }
6291
- updateHeightsInViewport(cm);
6292
- var barMeasure = measureForScrollbars(cm);
6293
- updateSelection(cm);
6294
- updateScrollbars(cm, barMeasure);
6295
- setDocumentHeight(cm, barMeasure);
6296
- update.force = false;
6297
- }
6298
 
6299
- update.signal(cm, "update", cm);
6300
- if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) {
6301
- update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo);
6302
- cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo;
6303
- }
6304
- }
6305
 
6306
- function updateDisplaySimple(cm, viewport) {
6307
- var update = new DisplayUpdate(cm, viewport);
6308
- if (updateDisplayIfNeeded(cm, update)) {
6309
- updateHeightsInViewport(cm);
6310
- postUpdateDisplay(cm, update);
6311
- var barMeasure = measureForScrollbars(cm);
6312
- updateSelection(cm);
6313
- updateScrollbars(cm, barMeasure);
6314
- setDocumentHeight(cm, barMeasure);
6315
- update.finish();
6316
  }
6317
- }
6318
 
6319
- // Sync the actual display DOM structure with display.view, removing
6320
- // nodes for lines that are no longer in view, and creating the ones
6321
- // that are not there yet, and updating the ones that are out of
6322
- // date.
6323
- function patchDisplay(cm, updateNumbersFrom, dims) {
6324
- var display = cm.display, lineNumbers = cm.options.lineNumbers;
6325
- var container = display.lineDiv, cur = container.firstChild;
6326
-
6327
- function rm(node) {
6328
- var next = node.nextSibling;
6329
- // Works around a throw-scroll bug in OS X Webkit
6330
- if (webkit && mac && cm.display.currentWheelTarget == node)
6331
- { node.style.display = "none"; }
6332
- else
6333
- { node.parentNode.removeChild(node); }
6334
- return next
6335
- }
6336
-
6337
- var view = display.view, lineN = display.viewFrom;
6338
- // Loop over the elements in the view, syncing cur (the DOM nodes
6339
- // in display.lineDiv) with the view as we go.
6340
- for (var i = 0; i < view.length; i++) {
6341
- var lineView = view[i];
6342
- if (lineView.hidden) {
6343
- } else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet
6344
- var node = buildLineElement(cm, lineView, lineN, dims);
6345
- container.insertBefore(node, cur);
6346
- } else { // Already drawn
6347
- while (cur != lineView.node) { cur = rm(cur); }
6348
- var updateNumber = lineNumbers && updateNumbersFrom != null &&
6349
- updateNumbersFrom <= lineN && lineView.lineNumber;
6350
- if (lineView.changes) {
6351
- if (indexOf(lineView.changes, "gutter") > -1) { updateNumber = false; }
6352
- updateLineForChanges(cm, lineView, lineN, dims);
6353
- }
6354
- if (updateNumber) {
6355
- removeChildren(lineView.lineNumber);
6356
- lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN)));
6357
- }
6358
- cur = lineView.node.nextSibling;
6359
- }
6360
- lineN += lineView.size;
6361
- }
6362
- while (cur) { cur = rm(cur); }
6363
- }
6364
 
6365
- function updateGutterSpace(cm) {
6366
- var width = cm.display.gutters.offsetWidth;
6367
- cm.display.sizer.style.marginLeft = width + "px";
6368
- }
 
 
 
 
 
 
6369
 
6370
- function setDocumentHeight(cm, measure) {
6371
- cm.display.sizer.style.minHeight = measure.docHeight + "px";
6372
- cm.display.heightForcer.style.top = measure.docHeight + "px";
6373
- cm.display.gutters.style.height = (measure.docHeight + cm.display.barHeight + scrollGap(cm)) + "px";
6374
- }
6375
 
6376
- // Rebuild the gutter elements, ensure the margin to the left of the
6377
- // code matches their width.
6378
- function updateGutters(cm) {
6379
- var gutters = cm.display.gutters, specs = cm.options.gutters;
6380
- removeChildren(gutters);
6381
- var i = 0;
6382
- for (; i < specs.length; ++i) {
6383
- var gutterClass = specs[i];
6384
- var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
6385
- if (gutterClass == "CodeMirror-linenumbers") {
6386
- cm.display.lineGutter = gElt;
6387
- gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
6388
- }
6389
- }
6390
- gutters.style.display = i ? "" : "none";
6391
- updateGutterSpace(cm);
6392
- }
6393
 
6394
- // Make sure the gutters options contains the element
6395
- // "CodeMirror-linenumbers" when the lineNumbers option is true.
6396
- function setGuttersForLineNumbers(options) {
6397
- var found = indexOf(options.gutters, "CodeMirror-linenumbers");
6398
- if (found == -1 && options.lineNumbers) {
6399
- options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]);
6400
- } else if (found > -1 && !options.lineNumbers) {
6401
- options.gutters = options.gutters.slice(0);
6402
- options.gutters.splice(found, 1);
6403
- }
6404
- }
 
6405
 
6406
- // Since the delta values reported on mouse wheel events are
6407
- // unstandardized between browsers and even browser versions, and
6408
- // generally horribly unpredictable, this code starts by measuring
6409
- // the scroll effect that the first few mouse wheel events have,
6410
- // and, from that, detects the way it can convert deltas to pixel
6411
- // offsets afterwards.
6412
- //
6413
- // The reason we want to know the amount a wheel event will scroll
6414
- // is that it gives us a chance to update the display before the
6415
- // actual scrolling happens, reducing flickering.
6416
-
6417
- var wheelSamples = 0;
6418
- var wheelPixelsPerUnit = null;
6419
- // Fill in a browser-detected starting value on browsers where we
6420
- // know one. These don't have to be accurate -- the result of them
6421
- // being wrong would just be a slight flicker on the first wheel
6422
- // scroll (if it is large enough).
6423
- if (ie) { wheelPixelsPerUnit = -.53; }
6424
- else if (gecko) { wheelPixelsPerUnit = 15; }
6425
- else if (chrome) { wheelPixelsPerUnit = -.7; }
6426
- else if (safari) { wheelPixelsPerUnit = -1/3; }
6427
-
6428
- function wheelEventDelta(e) {
6429
- var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
6430
- if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) { dx = e.detail; }
6431
- if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) { dy = e.detail; }
6432
- else if (dy == null) { dy = e.wheelDelta; }
6433
- return {x: dx, y: dy}
6434
- }
6435
- function wheelEventPixels(e) {
6436
- var delta = wheelEventDelta(e);
6437
- delta.x *= wheelPixelsPerUnit;
6438
- delta.y *= wheelPixelsPerUnit;
6439
- return delta
6440
- }
6441
 
6442
- function onScrollWheel(cm, e) {
6443
- var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y;
6444
-
6445
- var display = cm.display, scroll = display.scroller;
6446
- // Quit if there's nothing to scroll here
6447
- var canScrollX = scroll.scrollWidth > scroll.clientWidth;
6448
- var canScrollY = scroll.scrollHeight > scroll.clientHeight;
6449
- if (!(dx && canScrollX || dy && canScrollY)) { return }
6450
-
6451
- // Webkit browsers on OS X abort momentum scrolls when the target
6452
- // of the scroll event is removed from the scrollable element.
6453
- // This hack (see related code in patchDisplay) makes sure the
6454
- // element is kept around.
6455
- if (dy && mac && webkit) {
6456
- outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) {
6457
- for (var i = 0; i < view.length; i++) {
6458
- if (view[i].node == cur) {
6459
- cm.display.currentWheelTarget = cur;
6460
- break outer
6461
- }
6462
- }
6463
- }
6464
- }
6465
-
6466
- // On some browsers, horizontal scrolling will cause redraws to
6467
- // happen before the gutter has been realigned, causing it to
6468
- // wriggle around in a most unseemly way. When we have an
6469
- // estimated pixels/delta value, we just handle horizontal
6470
- // scrolling entirely here. It'll be slightly off from native, but
6471
- // better than glitching out.
6472
- if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {
6473
- if (dy && canScrollY)
6474
- { updateScrollTop(cm, Math.max(0, scroll.scrollTop + dy * wheelPixelsPerUnit)); }
6475
- setScrollLeft(cm, Math.max(0, scroll.scrollLeft + dx * wheelPixelsPerUnit));
6476
- // Only prevent default scrolling if vertical scrolling is
6477
- // actually possible. Otherwise, it causes vertical scroll
6478
- // jitter on OSX trackpads when deltaX is small and deltaY
6479
- // is large (issue #3579)
6480
- if (!dy || (dy && canScrollY))
6481
- { e_preventDefault(e); }
6482
- display.wheelStartX = null; // Abort measurement, if in progress
6483
- return
6484
- }
6485
-
6486
- // 'Project' the visible viewport to cover the area that is being
6487
- // scrolled into view (if we know enough to estimate it).
6488
- if (dy && wheelPixelsPerUnit != null) {
6489
- var pixels = dy * wheelPixelsPerUnit;
6490
- var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
6491
- if (pixels < 0) { top = Math.max(0, top + pixels - 50); }
6492
- else { bot = Math.min(cm.doc.height, bot + pixels + 50); }
6493
- updateDisplaySimple(cm, {top: top, bottom: bot});
6494
- }
6495
-
6496
- if (wheelSamples < 20) {
6497
- if (display.wheelStartX == null) {
6498
- display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
6499
- display.wheelDX = dx; display.wheelDY = dy;
6500
- setTimeout(function () {
6501
- if (display.wheelStartX == null) { return }
6502
- var movedX = scroll.scrollLeft - display.wheelStartX;
6503
- var movedY = scroll.scrollTop - display.wheelStartY;
6504
- var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
6505
- (movedX && display.wheelDX && movedX / display.wheelDX);
6506
- display.wheelStartX = display.wheelStartY = null;
6507
- if (!sample) { return }
6508
- wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);
6509
- ++wheelSamples;
6510
- }, 200);
6511
- } else {
6512
- display.wheelDX += dx; display.wheelDY += dy;
6513
  }
 
6514
  }
6515
- }
6516
 
6517
- // Selection objects are immutable. A new one is created every time
6518
- // the selection changes. A selection is one or more non-overlapping
6519
- // (and non-touching) ranges, sorted, and an integer that indicates
6520
- // which one is the primary selection (the one that's scrolled into
6521
- // view, that getCursor returns, etc).
6522
- var Selection = function(ranges, primIndex) {
6523
- this.ranges = ranges;
6524
- this.primIndex = primIndex;
6525
- };
6526
 
6527
- Selection.prototype.primary = function () { return this.ranges[this.primIndex] };
 
 
 
 
6528
 
6529
- Selection.prototype.equals = function (other) {
6530
- var this$1 = this;
6531
 
6532
- if (other == this) { return true }
6533
- if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) { return false }
6534
- for (var i = 0; i < this.ranges.length; i++) {
6535
- var here = this$1.ranges[i], there = other.ranges[i];
6536
- if (!equalCursorPos(here.anchor, there.anchor) || !equalCursorPos(here.head, there.head)) { return false }
 
 
6537
  }
6538
- return true
6539
- };
6540
 
6541
- Selection.prototype.deepCopy = function () {
6542
- var this$1 = this;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6543
 
6544
- var out = [];
6545
- for (var i = 0; i < this.ranges.length; i++)
6546
- { out[i] = new Range(copyPos(this$1.ranges[i].anchor), copyPos(this$1.ranges[i].head)); }
6547
- return new Selection(out, this.primIndex)
6548
- };
6549
 
6550
- Selection.prototype.somethingSelected = function () {
6551
- var this$1 = this;
 
 
 
 
 
 
 
 
 
6552
 
6553
- for (var i = 0; i < this.ranges.length; i++)
6554
- { if (!this$1.ranges[i].empty()) { return true } }
6555
- return false
6556
- };
 
 
 
 
 
 
 
 
6557
 
6558
- Selection.prototype.contains = function (pos, end) {
6559
  var this$1 = this;
6560
 
6561
- if (!end) { end = pos; }
6562
- for (var i = 0; i < this.ranges.length; i++) {
6563
- var range = this$1.ranges[i];
6564
- if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0)
6565
- { return i }
 
 
 
6566
  }
6567
- return -1
6568
- };
6569
 
6570
- var Range = function(anchor, head) {
6571
- this.anchor = anchor; this.head = head;
6572
- };
6573
 
6574
- Range.prototype.from = function () { return minPos(this.anchor, this.head) };
6575
- Range.prototype.to = function () { return maxPos(this.anchor, this.head) };
6576
- Range.prototype.empty = function () { return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch };
6577
-
6578
- // Take an unsorted, potentially overlapping set of ranges, and
6579
- // build a selection out of it. 'Consumes' ranges array (modifying
6580
- // it).
6581
- function normalizeSelection(ranges, primIndex) {
6582
- var prim = ranges[primIndex];
6583
- ranges.sort(function (a, b) { return cmp(a.from(), b.from()); });
6584
- primIndex = indexOf(ranges, prim);
6585
- for (var i = 1; i < ranges.length; i++) {
6586
- var cur = ranges[i], prev = ranges[i - 1];
6587
- if (cmp(prev.to(), cur.from()) >= 0) {
6588
- var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to());
6589
- var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head;
6590
- if (i <= primIndex) { --primIndex; }
6591
- ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to));
6592
- }
6593
- }
6594
- return new Selection(ranges, primIndex)
6595
- }
6596
 
6597
- function simpleSelection(anchor, head) {
6598
- return new Selection([new Range(anchor, head || anchor)], 0)
6599
- }
 
 
 
 
 
6600
 
6601
- // Compute the position of the end of a change (its 'to' property
6602
- // refers to the pre-change end).
6603
- function changeEnd(change) {
6604
- if (!change.text) { return change.to }
6605
- return Pos(change.from.line + change.text.length - 1,
6606
- lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0))
6607
- }
6608
 
6609
- // Adjust a position to refer to the post-change position of the
6610
- // same text, or the end of the change if the change covers it.
6611
- function adjustForChange(pos, change) {
6612
- if (cmp(pos, change.from) < 0) { return pos }
6613
- if (cmp(pos, change.to) <= 0) { return changeEnd(change) }
6614
 
6615
- var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;
6616
- if (pos.line == change.to.line) { ch += changeEnd(change).ch - change.to.ch; }
6617
- return Pos(line, ch)
6618
- }
6619
 
6620
- function computeSelAfterChange(doc, change) {
6621
- var out = [];
6622
- for (var i = 0; i < doc.sel.ranges.length; i++) {
6623
- var range = doc.sel.ranges[i];
6624
- out.push(new Range(adjustForChange(range.anchor, change),
6625
- adjustForChange(range.head, change)));
6626
- }
6627
- return normalizeSelection(out, doc.sel.primIndex)
6628
- }
6629
 
6630
- function offsetPos(pos, old, nw) {
6631
- if (pos.line == old.line)
6632
- { return Pos(nw.line, pos.ch - old.ch + nw.ch) }
6633
- else
6634
- { return Pos(nw.line + (pos.line - old.line), pos.ch) }
6635
- }
6636
 
6637
- // Used by replaceSelections to allow moving the selection to the
6638
- // start or around the replaced test. Hint may be "start" or "around".
6639
- function computeReplacedSel(doc, changes, hint) {
6640
- var out = [];
6641
- var oldPrev = Pos(doc.first, 0), newPrev = oldPrev;
6642
- for (var i = 0; i < changes.length; i++) {
6643
- var change = changes[i];
6644
- var from = offsetPos(change.from, oldPrev, newPrev);
6645
- var to = offsetPos(changeEnd(change), oldPrev, newPrev);
6646
- oldPrev = change.to;
6647
- newPrev = to;
6648
- if (hint == "around") {
6649
- var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0;
6650
- out[i] = new Range(inv ? to : from, inv ? from : to);
6651
- } else {
6652
- out[i] = new Range(from, from);
6653
  }
 
 
 
6654
  }
6655
- return new Selection(out, doc.sel.primIndex)
6656
- }
6657
 
6658
- // Used to get the editor into a consistent state again when options change.
 
6659
 
6660
- function loadMode(cm) {
6661
- cm.doc.mode = getMode(cm.options, cm.doc.modeOption);
6662
- resetModeState(cm);
6663
- }
6664
 
6665
- function resetModeState(cm) {
6666
- cm.doc.iter(function (line) {
6667
- if (line.stateAfter) { line.stateAfter = null; }
6668
- if (line.styles) { line.styles = null; }
6669
- });
6670
- cm.doc.modeFrontier = cm.doc.highlightFrontier = cm.doc.first;
6671
- startWorker(cm, 100);
6672
- cm.state.modeGen++;
6673
- if (cm.curOp) { regChange(cm); }
6674
- }
 
 
 
 
 
 
 
 
 
 
 
 
6675
 
6676
- // DOCUMENT DATA STRUCTURE
 
6677
 
6678
- // By default, updates that start and end at the beginning of a line
6679
- // are treated specially, in order to make the association of line
6680
- // widgets and marker elements with the text behave more intuitive.
6681
- function isWholeLineUpdate(doc, change) {
6682
- return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" &&
6683
- (!doc.cm || doc.cm.options.wholeLineUpdateBefore)
6684
- }
6685
 
6686
- // Perform a change on the document data structure.
6687
- function updateDoc(doc, change, markedSpans, estimateHeight$$1) {
6688
- function spansFor(n) {return markedSpans ? markedSpans[n] : null}
6689
- function update(line, text, spans) {
6690
- updateLine(line, text, spans, estimateHeight$$1);
6691
- signalLater(line, "change", line, change);
6692
- }
6693
- function linesFor(start, end) {
6694
- var result = [];
6695
- for (var i = start; i < end; ++i)
6696
- { result.push(new Line(text[i], spansFor(i), estimateHeight$$1)); }
6697
- return result
6698
- }
6699
 
6700
- var from = change.from, to = change.to, text = change.text;
6701
- var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
6702
- var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
6703
-
6704
- // Adjust the line structure
6705
- if (change.full) {
6706
- doc.insert(0, linesFor(0, text.length));
6707
- doc.remove(text.length, doc.size - text.length);
6708
- } else if (isWholeLineUpdate(doc, change)) {
6709
- // This is a whole-line replace. Treated specially to make
6710
- // sure line objects move the way they are supposed to.
6711
- var added = linesFor(0, text.length - 1);
6712
- update(lastLine, lastLine.text, lastSpans);
6713
- if (nlines) { doc.remove(from.line, nlines); }
6714
- if (added.length) { doc.insert(from.line, added); }
6715
- } else if (firstLine == lastLine) {
6716
- if (text.length == 1) {
6717
- update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
6718
- } else {
6719
- var added$1 = linesFor(1, text.length - 1);
6720
- added$1.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight$$1));
6721
- update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
6722
- doc.insert(from.line + 1, added$1);
6723
- }
6724
- } else if (text.length == 1) {
6725
- update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0));
6726
- doc.remove(from.line + 1, nlines);
6727
- } else {
6728
- update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
6729
- update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
6730
- var added$2 = linesFor(1, text.length - 1);
6731
- if (nlines > 1) { doc.remove(from.line + 1, nlines - 1); }
6732
- doc.insert(from.line + 1, added$2);
6733
- }
6734
 
6735
- signalLater(doc, "change", doc, change);
6736
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6737
 
6738
- // Call f for all linked documents.
6739
- function linkedDocs(doc, f, sharedHistOnly) {
6740
- function propagate(doc, skip, sharedHist) {
6741
- if (doc.linked) { for (var i = 0; i < doc.linked.length; ++i) {
6742
- var rel = doc.linked[i];
6743
- if (rel.doc == skip) { continue }
6744
- var shared = sharedHist && rel.sharedHist;
6745
- if (sharedHistOnly && !shared) { continue }
6746
- f(rel.doc, shared);
6747
- propagate(rel.doc, doc, shared);
6748
- } }
6749
- }
6750
- propagate(doc, null, true);
6751
- }
6752
 
6753
- // Attach a document to an editor.
6754
- function attachDoc(cm, doc) {
6755
- if (doc.cm) { throw new Error("This document is already in use.") }
6756
- cm.doc = doc;
6757
- doc.cm = cm;
6758
- estimateLineHeights(cm);
6759
- loadMode(cm);
6760
- setDirectionClass(cm);
6761
- if (!cm.options.lineWrapping) { findMaxLine(cm); }
6762
- cm.options.mode = doc.modeOption;
6763
- regChange(cm);
6764
- }
6765
-
6766
- function setDirectionClass(cm) {
6767
- (cm.doc.direction == "rtl" ? addClass : rmClass)(cm.display.lineDiv, "CodeMirror-rtl");
6768
- }
6769
-
6770
- function directionChanged(cm) {
6771
- runInOp(cm, function () {
6772
- setDirectionClass(cm);
6773
- regChange(cm);
6774
- });
6775
- }
6776
-
6777
- function History(startGen) {
6778
- // Arrays of change events and selections. Doing something adds an
6779
- // event to done and clears undo. Undoing moves events from done
6780
- // to undone, redoing moves them in the other direction.
6781
- this.done = []; this.undone = [];
6782
- this.undoDepth = Infinity;
6783
- // Used to track when changes can be merged into a single undo
6784
- // event
6785
- this.lastModTime = this.lastSelTime = 0;
6786
- this.lastOp = this.lastSelOp = null;
6787
- this.lastOrigin = this.lastSelOrigin = null;
6788
- // Used by the isClean() method
6789
- this.generation = this.maxGeneration = startGen || 1;
6790
- }
6791
-
6792
- // Create a history change event from an updateDoc-style change
6793
- // object.
6794
- function historyChangeFromChange(doc, change) {
6795
- var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
6796
- attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
6797
- linkedDocs(doc, function (doc) { return attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); }, true);
6798
- return histChange
6799
- }
6800
-
6801
- // Pop all selection events off the end of a history array. Stop at
6802
- // a change event.
6803
- function clearSelectionEvents(array) {
6804
- while (array.length) {
6805
- var last = lst(array);
6806
- if (last.ranges) { array.pop(); }
6807
- else { break }
6808
- }
6809
- }
6810
-
6811
- // Find the top change event in the history. Pop off selection
6812
- // events that are in the way.
6813
- function lastChangeEvent(hist, force) {
6814
- if (force) {
6815
- clearSelectionEvents(hist.done);
6816
- return lst(hist.done)
6817
- } else if (hist.done.length && !lst(hist.done).ranges) {
6818
- return lst(hist.done)
6819
- } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) {
6820
- hist.done.pop();
6821
- return lst(hist.done)
6822
- }
6823
- }
6824
-
6825
- // Register a change in the history. Merges changes that are within
6826
- // a single operation, or are close together with an origin that
6827
- // allows merging (starting with "+") into a single event.
6828
- function addChangeToHistory(doc, change, selAfter, opId) {
6829
- var hist = doc.history;
6830
- hist.undone.length = 0;
6831
- var time = +new Date, cur;
6832
- var last;
6833
-
6834
- if ((hist.lastOp == opId ||
6835
- hist.lastOrigin == change.origin && change.origin &&
6836
- ((change.origin.charAt(0) == "+" && hist.lastModTime > time - (doc.cm ? doc.cm.options.historyEventDelay : 500)) ||
6837
- change.origin.charAt(0) == "*")) &&
6838
- (cur = lastChangeEvent(hist, hist.lastOp == opId))) {
6839
- // Merge this change into the last event
6840
- last = lst(cur.changes);
6841
- if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) {
6842
- // Optimized case for simple insertion -- don't want to add
6843
- // new changesets for every character typed
6844
- last.to = changeEnd(change);
6845
- } else {
6846
- // Add new sub-event
6847
- cur.changes.push(historyChangeFromChange(doc, change));
6848
- }
6849
- } else {
6850
- // Can not be merged, start a new event.
6851
- var before = lst(hist.done);
6852
- if (!before || !before.ranges)
6853
- { pushSelectionToHistory(doc.sel, hist.done); }
6854
- cur = {changes: [historyChangeFromChange(doc, change)],
6855
- generation: hist.generation};
6856
- hist.done.push(cur);
6857
- while (hist.done.length > hist.undoDepth) {
6858
- hist.done.shift();
6859
- if (!hist.done[0].ranges) { hist.done.shift(); }
6860
- }
6861
- }
6862
- hist.done.push(selAfter);
6863
- hist.generation = ++hist.maxGeneration;
6864
- hist.lastModTime = hist.lastSelTime = time;
6865
- hist.lastOp = hist.lastSelOp = opId;
6866
- hist.lastOrigin = hist.lastSelOrigin = change.origin;
6867
-
6868
- if (!last) { signal(doc, "historyAdded"); }
6869
- }
6870
-
6871
- function selectionEventCanBeMerged(doc, origin, prev, sel) {
6872
- var ch = origin.charAt(0);
6873
- return ch == "*" ||
6874
- ch == "+" &&
6875
- prev.ranges.length == sel.ranges.length &&
6876
- prev.somethingSelected() == sel.somethingSelected() &&
6877
- new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500)
6878
- }
6879
-
6880
- // Called whenever the selection changes, sets the new selection as
6881
- // the pending selection in the history, and pushes the old pending
6882
- // selection into the 'done' array when it was significantly
6883
- // different (in number of selected ranges, emptiness, or time).
6884
- function addSelectionToHistory(doc, sel, opId, options) {
6885
- var hist = doc.history, origin = options && options.origin;
6886
-
6887
- // A new event is started when the previous origin does not match
6888
- // the current, or the origins don't allow matching. Origins
6889
- // starting with * are always merged, those starting with + are
6890
- // merged when similar and close together in time.
6891
- if (opId == hist.lastSelOp ||
6892
- (origin && hist.lastSelOrigin == origin &&
6893
- (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin ||
6894
- selectionEventCanBeMerged(doc, origin, lst(hist.done), sel))))
6895
- { hist.done[hist.done.length - 1] = sel; }
6896
- else
6897
- { pushSelectionToHistory(sel, hist.done); }
6898
-
6899
- hist.lastSelTime = +new Date;
6900
- hist.lastSelOrigin = origin;
6901
- hist.lastSelOp = opId;
6902
- if (options && options.clearRedo !== false)
6903
- { clearSelectionEvents(hist.undone); }
6904
- }
6905
-
6906
- function pushSelectionToHistory(sel, dest) {
6907
- var top = lst(dest);
6908
- if (!(top && top.ranges && top.equals(sel)))
6909
- { dest.push(sel); }
6910
- }
6911
-
6912
- // Used to store marked span information in the history.
6913
- function attachLocalSpans(doc, change, from, to) {
6914
- var existing = change["spans_" + doc.id], n = 0;
6915
- doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function (line) {
6916
- if (line.markedSpans)
6917
- { (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans; }
6918
- ++n;
6919
- });
6920
- }
6921
-
6922
- // When un/re-doing restores text containing marked spans, those
6923
- // that have been explicitly cleared should not be restored.
6924
- function removeClearedSpans(spans) {
6925
- if (!spans) { return null }
6926
- var out;
6927
- for (var i = 0; i < spans.length; ++i) {
6928
- if (spans[i].marker.explicitlyCleared) { if (!out) { out = spans.slice(0, i); } }
6929
- else if (out) { out.push(spans[i]); }
6930
- }
6931
- return !out ? spans : out.length ? out : null
6932
- }
6933
-
6934
- // Retrieve and filter the old marked spans stored in a change event.
6935
- function getOldSpans(doc, change) {
6936
- var found = change["spans_" + doc.id];
6937
- if (!found) { return null }
6938
- var nw = [];
6939
- for (var i = 0; i < change.text.length; ++i)
6940
- { nw.push(removeClearedSpans(found[i])); }
6941
- return nw
6942
- }
6943
-
6944
- // Used for un/re-doing changes from the history. Combines the
6945
- // result of computing the existing spans with the set of spans that
6946
- // existed in the history (so that deleting around a span and then
6947
- // undoing brings back the span).
6948
- function mergeOldSpans(doc, change) {
6949
- var old = getOldSpans(doc, change);
6950
- var stretched = stretchSpansOverChange(doc, change);
6951
- if (!old) { return stretched }
6952
- if (!stretched) { return old }
6953
-
6954
- for (var i = 0; i < old.length; ++i) {
6955
- var oldCur = old[i], stretchCur = stretched[i];
6956
- if (oldCur && stretchCur) {
6957
- spans: for (var j = 0; j < stretchCur.length; ++j) {
6958
- var span = stretchCur[j];
6959
- for (var k = 0; k < oldCur.length; ++k)
6960
- { if (oldCur[k].marker == span.marker) { continue spans } }
6961
- oldCur.push(span);
6962
- }
6963
- } else if (stretchCur) {
6964
- old[i] = stretchCur;
6965
- }
6966
- }
6967
- return old
6968
- }
6969
-
6970
- // Used both to provide a JSON-safe object in .getHistory, and, when
6971
- // detaching a document, to split the history in two
6972
- function copyHistoryArray(events, newGroup, instantiateSel) {
6973
- var copy = [];
6974
- for (var i = 0; i < events.length; ++i) {
6975
- var event = events[i];
6976
- if (event.ranges) {
6977
- copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event);
6978
- continue
6979
- }
6980
- var changes = event.changes, newChanges = [];
6981
- copy.push({changes: newChanges});
6982
- for (var j = 0; j < changes.length; ++j) {
6983
- var change = changes[j], m = (void 0);
6984
- newChanges.push({from: change.from, to: change.to, text: change.text});
6985
- if (newGroup) { for (var prop in change) { if (m = prop.match(/^spans_(\d+)$/)) {
6986
- if (indexOf(newGroup, Number(m[1])) > -1) {
6987
- lst(newChanges)[prop] = change[prop];
6988
- delete change[prop];
6989
- }
6990
- } } }
6991
- }
6992
- }
6993
- return copy
6994
- }
6995
-
6996
- // The 'scroll' parameter given to many of these indicated whether
6997
- // the new cursor position should be scrolled into view after
6998
- // modifying the selection.
6999
-
7000
- // If shift is held or the extend flag is set, extends a range to
7001
- // include a given position (and optionally a second position).
7002
- // Otherwise, simply returns the range between the given positions.
7003
- // Used for cursor motion and such.
7004
- function extendRange(range, head, other, extend) {
7005
- if (extend) {
7006
- var anchor = range.anchor;
7007
- if (other) {
7008
- var posBefore = cmp(head, anchor) < 0;
7009
- if (posBefore != (cmp(other, anchor) < 0)) {
7010
- anchor = head;
7011
- head = other;
7012
- } else if (posBefore != (cmp(head, other) < 0)) {
7013
- head = other;
7014
- }
7015
- }
7016
- return new Range(anchor, head)
7017
- } else {
7018
- return new Range(other || head, head)
7019
- }
7020
- }
7021
-
7022
- // Extend the primary selection range, discard the rest.
7023
- function extendSelection(doc, head, other, options, extend) {
7024
- if (extend == null) { extend = doc.cm && (doc.cm.display.shift || doc.extend); }
7025
- setSelection(doc, new Selection([extendRange(doc.sel.primary(), head, other, extend)], 0), options);
7026
- }
7027
-
7028
- // Extend all selections (pos is an array of selections with length
7029
- // equal the number of selections)
7030
- function extendSelections(doc, heads, options) {
7031
- var out = [];
7032
- var extend = doc.cm && (doc.cm.display.shift || doc.extend);
7033
- for (var i = 0; i < doc.sel.ranges.length; i++)
7034
- { out[i] = extendRange(doc.sel.ranges[i], heads[i], null, extend); }
7035
- var newSel = normalizeSelection(out, doc.sel.primIndex);
7036
- setSelection(doc, newSel, options);
7037
- }
7038
-
7039
- // Updates a single range in the selection.
7040
- function replaceOneSelection(doc, i, range, options) {
7041
- var ranges = doc.sel.ranges.slice(0);
7042
- ranges[i] = range;
7043
- setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options);
7044
- }
7045
-
7046
- // Reset the selection to a single range.
7047
- function setSimpleSelection(doc, anchor, head, options) {
7048
- setSelection(doc, simpleSelection(anchor, head), options);
7049
- }
7050
-
7051
- // Give beforeSelectionChange handlers a change to influence a
7052
- // selection update.
7053
- function filterSelectionChange(doc, sel, options) {
7054
- var obj = {
7055
- ranges: sel.ranges,
7056
- update: function(ranges) {
7057
- var this$1 = this;
7058
-
7059
- this.ranges = [];
7060
- for (var i = 0; i < ranges.length; i++)
7061
- { this$1.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),
7062
- clipPos(doc, ranges[i].head)); }
7063
- },
7064
- origin: options && options.origin
7065
- };
7066
- signal(doc, "beforeSelectionChange", doc, obj);
7067
- if (doc.cm) { signal(doc.cm, "beforeSelectionChange", doc.cm, obj); }
7068
- if (obj.ranges != sel.ranges) { return normalizeSelection(obj.ranges, obj.ranges.length - 1) }
7069
- else { return sel }
7070
- }
7071
-
7072
- function setSelectionReplaceHistory(doc, sel, options) {
7073
- var done = doc.history.done, last = lst(done);
7074
- if (last && last.ranges) {
7075
- done[done.length - 1] = sel;
7076
- setSelectionNoUndo(doc, sel, options);
7077
- } else {
7078
- setSelection(doc, sel, options);
7079
- }
7080
- }
7081
-
7082
- // Set a new selection.
7083
- function setSelection(doc, sel, options) {
7084
- setSelectionNoUndo(doc, sel, options);
7085
- addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options);
7086
- }
7087
-
7088
- function setSelectionNoUndo(doc, sel, options) {
7089
- if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
7090
- { sel = filterSelectionChange(doc, sel, options); }
7091
-
7092
- var bias = options && options.bias ||
7093
- (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);
7094
- setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));
7095
-
7096
- if (!(options && options.scroll === false) && doc.cm)
7097
- { ensureCursorVisible(doc.cm); }
7098
- }
7099
-
7100
- function setSelectionInner(doc, sel) {
7101
- if (sel.equals(doc.sel)) { return }
7102
-
7103
- doc.sel = sel;
7104
-
7105
- if (doc.cm) {
7106
- doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true;
7107
- signalCursorActivity(doc.cm);
7108
- }
7109
- signalLater(doc, "cursorActivity", doc);
7110
- }
7111
-
7112
- // Verify that the selection does not partially select any atomic
7113
- // marked ranges.
7114
- function reCheckSelection(doc) {
7115
- setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false));
7116
- }
7117
-
7118
- // Return a selection that does not partially select any atomic
7119
- // ranges.
7120
- function skipAtomicInSelection(doc, sel, bias, mayClear) {
7121
- var out;
7122
- for (var i = 0; i < sel.ranges.length; i++) {
7123
- var range = sel.ranges[i];
7124
- var old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i];
7125
- var newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear);
7126
- var newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear);
7127
- if (out || newAnchor != range.anchor || newHead != range.head) {
7128
- if (!out) { out = sel.ranges.slice(0, i); }
7129
- out[i] = new Range(newAnchor, newHead);
7130
- }
7131
- }
7132
- return out ? normalizeSelection(out, sel.primIndex) : sel
7133
- }
7134
-
7135
- function skipAtomicInner(doc, pos, oldPos, dir, mayClear) {
7136
- var line = getLine(doc, pos.line);
7137
- if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) {
7138
- var sp = line.markedSpans[i], m = sp.marker;
7139
- if ((sp.from == null || (m.inclusiveLeft ? sp.from <= pos.ch : sp.from < pos.ch)) &&
7140
- (sp.to == null || (m.inclusiveRight ? sp.to >= pos.ch : sp.to > pos.ch))) {
7141
- if (mayClear) {
7142
- signal(m, "beforeCursorEnter");
7143
- if (m.explicitlyCleared) {
7144
- if (!line.markedSpans) { break }
7145
- else {--i; continue}
7146
- }
7147
- }
7148
- if (!m.atomic) { continue }
7149
-
7150
- if (oldPos) {
7151
- var near = m.find(dir < 0 ? 1 : -1), diff = (void 0);
7152
- if (dir < 0 ? m.inclusiveRight : m.inclusiveLeft)
7153
- { near = movePos(doc, near, -dir, near && near.line == pos.line ? line : null); }
7154
- if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0))
7155
- { return skipAtomicInner(doc, near, pos, dir, mayClear) }
7156
  }
7157
-
7158
- var far = m.find(dir < 0 ? -1 : 1);
7159
- if (dir < 0 ? m.inclusiveLeft : m.inclusiveRight)
7160
- { far = movePos(doc, far, dir, far.line == pos.line ? line : null); }
7161
- return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null
7162
  }
7163
- } }
7164
- return pos
7165
- }
7166
-
7167
- // Ensure a given position is not inside an atomic range.
7168
- function skipAtomic(doc, pos, oldPos, bias, mayClear) {
7169
- var dir = bias || 1;
7170
- var found = skipAtomicInner(doc, pos, oldPos, dir, mayClear) ||
7171
- (!mayClear && skipAtomicInner(doc, pos, oldPos, dir, true)) ||
7172
- skipAtomicInner(doc, pos, oldPos, -dir, mayClear) ||
7173
- (!mayClear && skipAtomicInner(doc, pos, oldPos, -dir, true));
7174
- if (!found) {
7175
- doc.cantEdit = true;
7176
- return Pos(doc.first, 0)
7177
- }
7178
- return found
7179
- }
7180
-
7181
- function movePos(doc, pos, dir, line) {
7182
- if (dir < 0 && pos.ch == 0) {
7183
- if (pos.line > doc.first) { return clipPos(doc, Pos(pos.line - 1)) }
7184
- else { return null }
7185
- } else if (dir > 0 && pos.ch == (line || getLine(doc, pos.line)).text.length) {
7186
- if (pos.line < doc.first + doc.size - 1) { return Pos(pos.line + 1, 0) }
7187
- else { return null }
7188
- } else {
7189
- return new Pos(pos.line, pos.ch + dir)
7190
- }
7191
- }
7192
-
7193
- function selectAll(cm) {
7194
- cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);
7195
- }
7196
-
7197
- // UPDATING
7198
-
7199
- // Allow "beforeChange" event handlers to influence a change
7200
- function filterChange(doc, change, update) {
7201
- var obj = {
7202
- canceled: false,
7203
- from: change.from,
7204
- to: change.to,
7205
- text: change.text,
7206
- origin: change.origin,
7207
- cancel: function () { return obj.canceled = true; }
7208
- };
7209
- if (update) { obj.update = function (from, to, text, origin) {
7210
- if (from) { obj.from = clipPos(doc, from); }
7211
- if (to) { obj.to = clipPos(doc, to); }
7212
- if (text) { obj.text = text; }
7213
- if (origin !== undefined) { obj.origin = origin; }
7214
- }; }
7215
- signal(doc, "beforeChange", doc, obj);
7216
- if (doc.cm) { signal(doc.cm, "beforeChange", doc.cm, obj); }
7217
-
7218
- if (obj.canceled) { return null }
7219
- return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin}
7220
- }
7221
-
7222
- // Apply a change to a document, and add it to the document's
7223
- // history, and propagating it to all linked documents.
7224
- function makeChange(doc, change, ignoreReadOnly) {
7225
- if (doc.cm) {
7226
- if (!doc.cm.curOp) { return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly) }
7227
- if (doc.cm.state.suppressEdits) { return }
7228
- }
7229
 
7230
- if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) {
7231
- change = filterChange(doc, change, true);
7232
- if (!change) { return }
7233
- }
7234
 
7235
- // Possibly split or suppress the update based on the presence
7236
- // of read-only spans in its range.
7237
- var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);
7238
- if (split) {
7239
- for (var i = split.length - 1; i >= 0; --i)
7240
- { makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text, origin: change.origin}); }
7241
- } else {
7242
- makeChangeInner(doc, change);
7243
- }
7244
- }
7245
 
7246
- function makeChangeInner(doc, change) {
7247
- if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) { return }
7248
- var selAfter = computeSelAfterChange(doc, change);
7249
- addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);
 
7250
 
7251
- makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));
7252
- var rebased = [];
7253
 
7254
- linkedDocs(doc, function (doc, sharedHist) {
7255
- if (!sharedHist && indexOf(rebased, doc.history) == -1) {
7256
- rebaseHist(doc.history, change);
7257
- rebased.push(doc.history);
 
 
 
 
 
 
 
 
7258
  }
7259
- makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change));
7260
- });
7261
- }
7262
-
7263
- // Revert a change stored in a document's history.
7264
- function makeChangeFromHistory(doc, type, allowSelectionOnly) {
7265
- var suppress = doc.cm && doc.cm.state.suppressEdits;
7266
- if (suppress && !allowSelectionOnly) { return }
7267
-
7268
- var hist = doc.history, event, selAfter = doc.sel;
7269
- var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done;
7270
-
7271
- // Verify that there is a useable event (so that ctrl-z won't
7272
- // needlessly clear selection events)
7273
- var i = 0;
7274
- for (; i < source.length; i++) {
7275
- event = source[i];
7276
- if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges)
7277
- { break }
7278
- }
7279
- if (i == source.length) { return }
7280
- hist.lastOrigin = hist.lastSelOrigin = null;
7281
-
7282
- for (;;) {
7283
- event = source.pop();
7284
- if (event.ranges) {
7285
- pushSelectionToHistory(event, dest);
7286
- if (allowSelectionOnly && !event.equals(doc.sel)) {
7287
- setSelection(doc, event, {clearRedo: false});
7288
- return
7289
- }
7290
- selAfter = event;
7291
- } else if (suppress) {
7292
- source.push(event);
7293
- return
7294
- } else { break }
7295
- }
7296
-
7297
- // Build up a reverse change object to add to the opposite history
7298
- // stack (redo when undoing, and vice versa).
7299
- var antiChanges = [];
7300
- pushSelectionToHistory(selAfter, dest);
7301
- dest.push({changes: antiChanges, generation: hist.generation});
7302
- hist.generation = event.generation || ++hist.maxGeneration;
7303
 
7304
- var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange");
 
7305
 
7306
- var loop = function ( i ) {
7307
- var change = event.changes[i];
7308
- change.origin = type;
7309
- if (filter && !filterChange(doc, change, false)) {
7310
- source.length = 0;
7311
- return {}
 
 
 
 
 
7312
  }
7313
-
7314
- antiChanges.push(historyChangeFromChange(doc, change));
7315
-
7316
- var after = i ? computeSelAfterChange(doc, change) : lst(source);
7317
- makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
7318
- if (!i && doc.cm) { doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)}); }
7319
- var rebased = [];
7320
-
7321
- // Propagate to the linked documents
7322
- linkedDocs(doc, function (doc, sharedHist) {
7323
- if (!sharedHist && indexOf(rebased, doc.history) == -1) {
7324
- rebaseHist(doc.history, change);
7325
- rebased.push(doc.history);
7326
- }
7327
- makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change));
7328
- });
7329
  };
7330
-
7331
- for (var i$1 = event.changes.length - 1; i$1 >= 0; --i$1) {
7332
- var returned = loop( i$1 );
7333
-
7334
- if ( returned ) return returned.v;
7335
- }
7336
- }
7337
-
7338
- // Sub-views need their line numbers shifted when text is added
7339
- // above or below them in the parent document.
7340
- function shiftDoc(doc, distance) {
7341
- if (distance == 0) { return }
7342
- doc.first += distance;
7343
- doc.sel = new Selection(map(doc.sel.ranges, function (range) { return new Range(
7344
- Pos(range.anchor.line + distance, range.anchor.ch),
7345
- Pos(range.head.line + distance, range.head.ch)
7346
- ); }), doc.sel.primIndex);
7347
- if (doc.cm) {
7348
- regChange(doc.cm, doc.first, doc.first - distance, distance);
7349
- for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++)
7350
- { regLineChange(doc.cm, l, "gutter"); }
7351
- }
7352
- }
7353
-
7354
- // More lower-level change function, handling only a single document
7355
- // (not linked ones).
7356
- function makeChangeSingleDoc(doc, change, selAfter, spans) {
7357
- if (doc.cm && !doc.cm.curOp)
7358
- { return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans) }
7359
-
7360
- if (change.to.line < doc.first) {
7361
- shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line));
7362
- return
7363
- }
7364
- if (change.from.line > doc.lastLine()) { return }
7365
-
7366
- // Clip the change to the size of this doc
7367
- if (change.from.line < doc.first) {
7368
- var shift = change.text.length - 1 - (doc.first - change.from.line);
7369
- shiftDoc(doc, shift);
7370
- change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),
7371
- text: [lst(change.text)], origin: change.origin};
7372
- }
7373
- var last = doc.lastLine();
7374
- if (change.to.line > last) {
7375
- change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),
7376
- text: [change.text[0]], origin: change.origin};
7377
- }
7378
-
7379
- change.removed = getBetween(doc, change.from, change.to);
7380
-
7381
- if (!selAfter) { selAfter = computeSelAfterChange(doc, change); }
7382
- if (doc.cm) { makeChangeSingleDocInEditor(doc.cm, change, spans); }
7383
- else { updateDoc(doc, change, spans); }
7384
- setSelectionNoUndo(doc, selAfter, sel_dontScroll);
7385
- }
7386
-
7387
- // Handle the interaction of a change to a document with the editor
7388
- // that this document is part of.
7389
- function makeChangeSingleDocInEditor(cm, change, spans) {
7390
- var doc = cm.doc, display = cm.display, from = change.from, to = change.to;
7391
-
7392
- var recomputeMaxLength = false, checkWidthStart = from.line;
7393
- if (!cm.options.lineWrapping) {
7394
- checkWidthStart = lineNo(visualLine(getLine(doc, from.line)));
7395
- doc.iter(checkWidthStart, to.line + 1, function (line) {
7396
- if (line == display.maxLine) {
7397
- recomputeMaxLength = true;
7398
- return true
7399
- }
7400
- });
7401
- }
7402
-
7403
- if (doc.sel.contains(change.from, change.to) > -1)
7404
- { signalCursorActivity(cm); }
7405
-
7406
- updateDoc(doc, change, spans, estimateHeight(cm));
7407
-
7408
- if (!cm.options.lineWrapping) {
7409
- doc.iter(checkWidthStart, from.line + change.text.length, function (line) {
7410
- var len = lineLength(line);
7411
- if (len > display.maxLineLength) {
7412
- display.maxLine = line;
7413
- display.maxLineLength = len;
7414
- display.maxLineChanged = true;
7415
- recomputeMaxLength = false;
7416
  }
 
7417
  });
7418
- if (recomputeMaxLength) { cm.curOp.updateMaxLine = true; }
 
7419
  }
7420
 
7421
- retreatFrontier(doc, from.line);
7422
- startWorker(cm, 400);
7423
 
7424
- var lendiff = change.text.length - (to.line - from.line) - 1;
7425
- // Remember that these lines changed, for updating the display
7426
- if (change.full)
7427
- { regChange(cm); }
7428
- else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))
7429
- { regLineChange(cm, from.line, "text"); }
7430
- else
7431
- { regChange(cm, from.line, to.line + 1, lendiff); }
 
7432
 
7433
- var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change");
7434
- if (changeHandler || changesHandler) {
7435
- var obj = {
7436
- from: from, to: to,
7437
- text: change.text,
7438
- removed: change.removed,
7439
- origin: change.origin
7440
- };
7441
- if (changeHandler) { signalLater(cm, "change", cm, obj); }
7442
- if (changesHandler) { (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj); }
7443
- }
7444
- cm.display.selForContextMenu = null;
7445
- }
7446
-
7447
- function replaceRange(doc, code, from, to, origin) {
7448
- if (!to) { to = from; }
7449
- if (cmp(to, from) < 0) { var assign;
7450
- (assign = [to, from], from = assign[0], to = assign[1]); }
7451
- if (typeof code == "string") { code = doc.splitLines(code); }
7452
- makeChange(doc, {from: from, to: to, text: code, origin: origin});
7453
- }
7454
 
7455
- // Rebasing/resetting history to deal with externally-sourced changes
 
 
 
 
 
7456
 
7457
- function rebaseHistSelSingle(pos, from, to, diff) {
7458
- if (to < pos.line) {
7459
- pos.line += diff;
7460
- } else if (from < pos.line) {
7461
- pos.line = from;
7462
- pos.ch = 0;
7463
- }
7464
- }
7465
 
7466
- // Tries to rebase an array of history events given a change in the
7467
- // document. If the change touches the same lines as the event, the
7468
- // event, and everything 'behind' it, is discarded. If the change is
7469
- // before the event, the event's positions are updated. Uses a
7470
- // copy-on-write scheme for the positions, to avoid having to
7471
- // reallocate them all on every rebase, but also avoid problems with
7472
- // shared position objects being unsafely updated.
7473
- function rebaseHistArray(array, from, to, diff) {
7474
- for (var i = 0; i < array.length; ++i) {
7475
- var sub = array[i], ok = true;
7476
- if (sub.ranges) {
7477
- if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; }
7478
- for (var j = 0; j < sub.ranges.length; j++) {
7479
- rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff);
7480
- rebaseHistSelSingle(sub.ranges[j].head, from, to, diff);
7481
- }
7482
- continue
7483
- }
7484
- for (var j$1 = 0; j$1 < sub.changes.length; ++j$1) {
7485
- var cur = sub.changes[j$1];
7486
- if (to < cur.from.line) {
7487
- cur.from = Pos(cur.from.line + diff, cur.from.ch);
7488
- cur.to = Pos(cur.to.line + diff, cur.to.ch);
7489
- } else if (from <= cur.to.line) {
7490
- ok = false;
7491
- break
7492
- }
7493
- }
7494
- if (!ok) {
7495
- array.splice(0, i + 1);
7496
- i = 0;
7497
  }
7498
- }
7499
- }
7500
-
7501
- function rebaseHist(hist, change) {
7502
- var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1;
7503
- rebaseHistArray(hist.done, from, to, diff);
7504
- rebaseHistArray(hist.undone, from, to, diff);
7505
- }
7506
-
7507
- // Utility for applying a change to a line by handle or number,
7508
- // returning the number and optionally registering the line as
7509
- // changed.
7510
- function changeLine(doc, handle, changeType, op) {
7511
- var no = handle, line = handle;
7512
- if (typeof handle == "number") { line = getLine(doc, clipLine(doc, handle)); }
7513
- else { no = lineNo(handle); }
7514
- if (no == null) { return null }
7515
- if (op(line, no) && doc.cm) { regLineChange(doc.cm, no, changeType); }
7516
- return line
7517
- }
7518
-
7519
- // The document is represented as a BTree consisting of leaves, with
7520
- // chunk of lines in them, and branches, with up to ten leaves or
7521
- // other branch nodes below them. The top node is always a branch
7522
- // node, and is the document object itself (meaning it has
7523
- // additional methods and properties).
7524
- //
7525
- // All nodes have parent links. The tree is used both to go from
7526
- // line numbers to line objects, and to go from objects to numbers.
7527
- // It also indexes by height, and is used to convert between height
7528
- // and line object, and to find the total height of the document.
7529
- //
7530
- // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html
7531
-
7532
- function LeafChunk(lines) {
7533
- var this$1 = this;
7534
-
7535
- this.lines = lines;
7536
- this.parent = null;
7537
- var height = 0;
7538
- for (var i = 0; i < lines.length; ++i) {
7539
- lines[i].parent = this$1;
7540
- height += lines[i].height;
7541
- }
7542
- this.height = height;
7543
- }
7544
-
7545
- LeafChunk.prototype = {
7546
- chunkSize: function() { return this.lines.length },
7547
-
7548
- // Remove the n lines at offset 'at'.
7549
- removeInner: function(at, n) {
7550
- var this$1 = this;
7551
-
7552
- for (var i = at, e = at + n; i < e; ++i) {
7553
  var line = this$1.lines[i];
7554
- this$1.height -= line.height;
7555
- cleanUpLine(line);
7556
- signalLater(line, "delete");
7557
- }
7558
- this.lines.splice(at, n);
7559
- },
7560
-
7561
- // Helper used to collapse a small branch into a single leaf.
7562
- collapse: function(lines) {
7563
- lines.push.apply(lines, this.lines);
7564
- },
7565
-
7566
- // Insert the given array of lines at offset 'at', count them as
7567
- // having the given height.
7568
- insertInner: function(at, lines, height) {
7569
- var this$1 = this;
7570
-
7571
- this.height += height;
7572
- this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
7573
- for (var i = 0; i < lines.length; ++i) { lines[i].parent = this$1; }
7574
- },
7575
-
7576
- // Used to iterate over a part of the tree.
7577
- iterN: function(at, n, op) {
7578
- var this$1 = this;
7579
-
7580
- for (var e = at + n; at < e; ++at)
7581
- { if (op(this$1.lines[at])) { return true } }
7582
- }
7583
- };
7584
-
7585
- function BranchChunk(children) {
7586
- var this$1 = this;
7587
-
7588
- this.children = children;
7589
- var size = 0, height = 0;
7590
- for (var i = 0; i < children.length; ++i) {
7591
- var ch = children[i];
7592
- size += ch.chunkSize(); height += ch.height;
7593
- ch.parent = this$1;
7594
- }
7595
- this.size = size;
7596
- this.height = height;
7597
- this.parent = null;
7598
- }
7599
-
7600
- BranchChunk.prototype = {
7601
- chunkSize: function() { return this.size },
7602
-
7603
- removeInner: function(at, n) {
7604
- var this$1 = this;
7605
 
7606
- this.size -= n;
7607
- for (var i = 0; i < this.children.length; ++i) {
7608
- var child = this$1.children[i], sz = child.chunkSize();
7609
- if (at < sz) {
7610
- var rm = Math.min(n, sz - at), oldHeight = child.height;
7611
- child.removeInner(at, rm);
7612
- this$1.height -= oldHeight - child.height;
7613
- if (sz == rm) { this$1.children.splice(i--, 1); child.parent = null; }
7614
- if ((n -= rm) == 0) { break }
7615
- at = 0;
7616
- } else { at -= sz; }
7617
- }
7618
- // If the result is smaller than 25 lines, ensure that it is a
7619
- // single leaf node.
7620
- if (this.size - n < 25 &&
7621
- (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) {
7622
- var lines = [];
7623
- this.collapse(lines);
7624
- this.children = [new LeafChunk(lines)];
7625
- this.children[0].parent = this;
7626
  }
7627
- },
7628
-
7629
- collapse: function(lines) {
7630
- var this$1 = this;
7631
-
7632
- for (var i = 0; i < this.children.length; ++i) { this$1.children[i].collapse(lines); }
7633
- },
7634
 
7635
- insertInner: function(at, lines, height) {
7636
- var this$1 = this;
 
 
 
 
 
7637
 
7638
- this.size += lines.length;
7639
- this.height += height;
7640
- for (var i = 0; i < this.children.length; ++i) {
7641
- var child = this$1.children[i], sz = child.chunkSize();
7642
- if (at <= sz) {
7643
- child.insertInner(at, lines, height);
7644
- if (child.lines && child.lines.length > 50) {
7645
- // To avoid memory thrashing when child.lines is huge (e.g. first view of a large file), it's never spliced.
7646
- // Instead, small slices are taken. They're taken in order because sequential memory accesses are fastest.
7647
- var remaining = child.lines.length % 25 + 25;
7648
- for (var pos = remaining; pos < child.lines.length;) {
7649
- var leaf = new LeafChunk(child.lines.slice(pos, pos += 25));
7650
- child.height -= leaf.height;
7651
- this$1.children.splice(++i, 0, leaf);
7652
- leaf.parent = this$1;
7653
- }
7654
- child.lines = child.lines.slice(0, remaining);
7655
- this$1.maybeSpill();
7656
- }
7657
- break
7658
  }
7659
- at -= sz;
7660
- }
7661
- },
7662
-
7663
- // When a node has grown, check whether it should be split.
7664
- maybeSpill: function() {
7665
- if (this.children.length <= 10) { return }
7666
- var me = this;
7667
- do {
7668
- var spilled = me.children.splice(me.children.length - 5, 5);
7669
- var sibling = new BranchChunk(spilled);
7670
- if (!me.parent) { // Become the parent node
7671
- var copy = new BranchChunk(me.children);
7672
- copy.parent = me;
7673
- me.children = [copy, sibling];
7674
- me = copy;
7675
- } else {
7676
- me.size -= sibling.size;
7677
- me.height -= sibling.height;
7678
- var myIndex = indexOf(me.parent.children, me);
7679
- me.parent.children.splice(myIndex + 1, 0, sibling);
7680
- }
7681
- sibling.parent = me.parent;
7682
- } while (me.children.length > 10)
7683
- me.parent.maybeSpill();
7684
- },
7685
-
7686
- iterN: function(at, n, op) {
7687
- var this$1 = this;
7688
-
7689
- for (var i = 0; i < this.children.length; ++i) {
7690
- var child = this$1.children[i], sz = child.chunkSize();
7691
- if (at < sz) {
7692
- var used = Math.min(n, sz - at);
7693
- if (child.iterN(at, used, op)) { return true }
7694
- if ((n -= used) == 0) { break }
7695
- at = 0;
7696
- } else { at -= sz; }
7697
  }
7698
- }
7699
- };
7700
-
7701
- // Line widgets are block elements displayed above or below a line.
7702
-
7703
- var LineWidget = function(doc, node, options) {
7704
- var this$1 = this;
7705
-
7706
- if (options) { for (var opt in options) { if (options.hasOwnProperty(opt))
7707
- { this$1[opt] = options[opt]; } } }
7708
- this.doc = doc;
7709
- this.node = node;
7710
- };
7711
 
7712
- LineWidget.prototype.clear = function () {
7713
- var this$1 = this;
 
 
7714
 
7715
- var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line);
7716
- if (no == null || !ws) { return }
7717
- for (var i = 0; i < ws.length; ++i) { if (ws[i] == this$1) { ws.splice(i--, 1); } }
7718
- if (!ws.length) { line.widgets = null; }
7719
- var height = widgetHeight(this);
7720
- updateLineHeight(line, Math.max(0, line.height - height));
7721
- if (cm) {
7722
  runInOp(cm, function () {
7723
- adjustScrollWhenAboveVisible(cm, line, -height);
7724
- regLineChange(cm, no, "widget");
 
 
 
 
 
 
 
 
 
 
 
 
 
7725
  });
7726
- signalLater(cm, "lineWidgetCleared", cm, this, no);
7727
- }
7728
- };
7729
 
7730
- LineWidget.prototype.changed = function () {
7731
- var this$1 = this;
 
 
 
 
 
 
7732
 
7733
- var oldH = this.height, cm = this.doc.cm, line = this.line;
7734
- this.height = null;
7735
- var diff = widgetHeight(this) - oldH;
7736
- if (!diff) { return }
7737
- if (!lineIsHidden(this.doc, line)) { updateLineHeight(line, line.height + diff); }
7738
- if (cm) {
7739
- runInOp(cm, function () {
7740
- cm.curOp.forceUpdate = true;
7741
- adjustScrollWhenAboveVisible(cm, line, diff);
7742
- signalLater(cm, "lineWidgetChanged", cm, this$1, lineNo(line));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7743
  });
7744
- }
7745
- };
7746
- eventMixin(LineWidget);
 
7747
 
7748
- function adjustScrollWhenAboveVisible(cm, line, diff) {
7749
- if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop))
7750
- { addToScrollTop(cm, diff); }
7751
- }
7752
 
7753
- function addLineWidget(doc, handle, node, options) {
7754
- var widget = new LineWidget(doc, node, options);
7755
- var cm = doc.cm;
7756
- if (cm && widget.noHScroll) { cm.display.alignWidgets = true; }
7757
- changeLine(doc, handle, "widget", function (line) {
7758
- var widgets = line.widgets || (line.widgets = []);
7759
- if (widget.insertAt == null) { widgets.push(widget); }
7760
- else { widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget); }
7761
- widget.line = line;
7762
- if (cm && !lineIsHidden(doc, line)) {
7763
- var aboveVisible = heightAtLine(line) < doc.scrollTop;
7764
- updateLineHeight(line, line.height + widgetHeight(widget));
7765
- if (aboveVisible) { addToScrollTop(cm, widget.height); }
7766
- cm.curOp.forceUpdate = true;
7767
  }
7768
- return true
7769
- });
7770
- if (cm) { signalLater(cm, "lineWidgetAdded", cm, widget, typeof handle == "number" ? handle : lineNo(handle)); }
7771
- return widget
7772
- }
7773
-
7774
- // TEXTMARKERS
7775
-
7776
- // Created with markText and setBookmark methods. A TextMarker is a
7777
- // handle that can be used to clear or find a marked position in the
7778
- // document. Line objects hold arrays (markedSpans) containing
7779
- // {from, to, marker} object pointing to such marker objects, and
7780
- // indicating that such a marker is present on that line. Multiple
7781
- // lines may point to the same marker when it spans across lines.
7782
- // The spans will have null for their from/to properties when the
7783
- // marker continues beyond the start/end of the line. Markers have
7784
- // links back to the lines they currently touch.
7785
-
7786
- // Collapsed markers have unique ids, in order to be able to order
7787
- // them, which is needed for uniquely determining an outer marker
7788
- // when they overlap (they may nest, but not partially overlap).
7789
- var nextMarkerId = 0;
7790
-
7791
- var TextMarker = function(doc, type) {
7792
- this.lines = [];
7793
- this.type = type;
7794
- this.doc = doc;
7795
- this.id = ++nextMarkerId;
7796
- };
7797
-
7798
- // Clear the marker.
7799
- TextMarker.prototype.clear = function () {
7800
- var this$1 = this;
7801
-
7802
- if (this.explicitlyCleared) { return }
7803
- var cm = this.doc.cm, withOp = cm && !cm.curOp;
7804
- if (withOp) { startOperation(cm); }
7805
- if (hasHandler(this, "clear")) {
7806
- var found = this.find();
7807
- if (found) { signalLater(this, "clear", found.from, found.to); }
7808
- }
7809
- var min = null, max = null;
7810
- for (var i = 0; i < this.lines.length; ++i) {
7811
- var line = this$1.lines[i];
7812
- var span = getMarkedSpanFor(line.markedSpans, this$1);
7813
- if (cm && !this$1.collapsed) { regLineChange(cm, lineNo(line), "text"); }
7814
- else if (cm) {
7815
- if (span.to != null) { max = lineNo(line); }
7816
- if (span.from != null) { min = lineNo(line); }
7817
- }
7818
- line.markedSpans = removeMarkedSpan(line.markedSpans, span);
7819
- if (span.from == null && this$1.collapsed && !lineIsHidden(this$1.doc, line) && cm)
7820
- { updateLineHeight(line, textHeight(cm.display)); }
7821
- }
7822
- if (cm && this.collapsed && !cm.options.lineWrapping) { for (var i$1 = 0; i$1 < this.lines.length; ++i$1) {
7823
- var visual = visualLine(this$1.lines[i$1]), len = lineLength(visual);
7824
- if (len > cm.display.maxLineLength) {
7825
- cm.display.maxLine = visual;
7826
- cm.display.maxLineLength = len;
7827
- cm.display.maxLineChanged = true;
7828
- }
7829
- } }
7830
-
7831
- if (min != null && cm && this.collapsed) { regChange(cm, min, max + 1); }
7832
- this.lines.length = 0;
7833
- this.explicitlyCleared = true;
7834
- if (this.atomic && this.doc.cantEdit) {
7835
- this.doc.cantEdit = false;
7836
- if (cm) { reCheckSelection(cm.doc); }
7837
- }
7838
- if (cm) { signalLater(cm, "markerCleared", cm, this, min, max); }
7839
- if (withOp) { endOperation(cm); }
7840
- if (this.parent) { this.parent.clear(); }
7841
- };
7842
-
7843
- // Find the position of the marker in the document. Returns a {from,
7844
- // to} object by default. Side can be passed to get a specific side
7845
- // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the
7846
- // Pos objects returned contain a line object, rather than a line
7847
- // number (used to prevent looking up the same line twice).
7848
- TextMarker.prototype.find = function (side, lineObj) {
7849
- var this$1 = this;
7850
-
7851
- if (side == null && this.type == "bookmark") { side = 1; }
7852
- var from, to;
7853
- for (var i = 0; i < this.lines.length; ++i) {
7854
- var line = this$1.lines[i];
7855
- var span = getMarkedSpanFor(line.markedSpans, this$1);
7856
- if (span.from != null) {
7857
- from = Pos(lineObj ? line : lineNo(line), span.from);
7858
- if (side == -1) { return from }
7859
  }
7860
- if (span.to != null) {
7861
- to = Pos(lineObj ? line : lineNo(line), span.to);
7862
- if (side == 1) { return to }
 
 
 
 
 
 
7863
  }
 
7864
  }
7865
- return from && {from: from, to: to}
7866
- };
7867
 
7868
- // Signals that the marker's widget changed, and surrounding layout
7869
- // should be recomputed.
7870
- TextMarker.prototype.changed = function () {
7871
- var this$1 = this;
7872
 
7873
- var pos = this.find(-1, true), widget = this, cm = this.doc.cm;
7874
- if (!pos || !cm) { return }
7875
- runInOp(cm, function () {
7876
- var line = pos.line, lineN = lineNo(pos.line);
7877
- var view = findViewForLine(cm, lineN);
7878
- if (view) {
7879
- clearLineMeasurementCacheFor(view);
7880
- cm.curOp.selectionChanged = cm.curOp.forceUpdate = true;
7881
- }
7882
- cm.curOp.updateMaxLine = true;
7883
- if (!lineIsHidden(widget.doc, line) && widget.height != null) {
7884
- var oldHeight = widget.height;
7885
- widget.height = null;
7886
- var dHeight = widgetHeight(widget) - oldHeight;
7887
- if (dHeight)
7888
- { updateLineHeight(line, line.height + dHeight); }
7889
- }
7890
- signalLater(cm, "markerChanged", cm, this$1);
7891
- });
7892
- };
7893
-
7894
- TextMarker.prototype.attachLine = function (line) {
7895
- if (!this.lines.length && this.doc.cm) {
7896
- var op = this.doc.cm.curOp;
7897
- if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)
7898
- { (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this); }
7899
- }
7900
- this.lines.push(line);
7901
- };
7902
-
7903
- TextMarker.prototype.detachLine = function (line) {
7904
- this.lines.splice(indexOf(this.lines, line), 1);
7905
- if (!this.lines.length && this.doc.cm) {
7906
- var op = this.doc.cm.curOp;(op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
7907
- }
7908
- };
7909
- eventMixin(TextMarker);
7910
-
7911
- // Create a marker, wire it up to the right lines, and
7912
- function markText(doc, from, to, options, type) {
7913
- // Shared markers (across linked documents) are handled separately
7914
- // (markTextShared will call out to this again, once per
7915
- // document).
7916
- if (options && options.shared) { return markTextShared(doc, from, to, options, type) }
7917
- // Ensure we are in an operation.
7918
- if (doc.cm && !doc.cm.curOp) { return operation(doc.cm, markText)(doc, from, to, options, type) }
7919
-
7920
- var marker = new TextMarker(doc, type), diff = cmp(from, to);
7921
- if (options) { copyObj(options, marker, false); }
7922
- // Don't connect empty markers unless clearWhenEmpty is false
7923
- if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false)
7924
- { return marker }
7925
- if (marker.replacedWith) {
7926
- // Showing up as a widget implies collapsed (widget replaces text)
7927
- marker.collapsed = true;
7928
- marker.widgetNode = eltP("span", [marker.replacedWith], "CodeMirror-widget");
7929
- if (!options.handleMouseEvents) { marker.widgetNode.setAttribute("cm-ignore-events", "true"); }
7930
- if (options.insertLeft) { marker.widgetNode.insertLeft = true; }
7931
- }
7932
- if (marker.collapsed) {
7933
- if (conflictingCollapsedRange(doc, from.line, from, to, marker) ||
7934
- from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker))
7935
- { throw new Error("Inserting collapsed marker partially overlapping an existing one") }
7936
- seeCollapsedSpans();
7937
- }
7938
-
7939
- if (marker.addToHistory)
7940
- { addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN); }
7941
-
7942
- var curLine = from.line, cm = doc.cm, updateMaxLine;
7943
- doc.iter(curLine, to.line + 1, function (line) {
7944
- if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine)
7945
- { updateMaxLine = true; }
7946
- if (marker.collapsed && curLine != from.line) { updateLineHeight(line, 0); }
7947
- addMarkedSpan(line, new MarkedSpan(marker,
7948
- curLine == from.line ? from.ch : null,
7949
- curLine == to.line ? to.ch : null));
7950
- ++curLine;
7951
- });
7952
- // lineIsHidden depends on the presence of the spans, so needs a second pass
7953
- if (marker.collapsed) { doc.iter(from.line, to.line + 1, function (line) {
7954
- if (lineIsHidden(doc, line)) { updateLineHeight(line, 0); }
7955
- }); }
7956
-
7957
- if (marker.clearOnEnter) { on(marker, "beforeCursorEnter", function () { return marker.clear(); }); }
7958
-
7959
- if (marker.readOnly) {
7960
- seeReadOnlySpans();
7961
- if (doc.history.done.length || doc.history.undone.length)
7962
- { doc.clearHistory(); }
7963
- }
7964
- if (marker.collapsed) {
7965
- marker.id = ++nextMarkerId;
7966
- marker.atomic = true;
7967
- }
7968
- if (cm) {
7969
- // Sync editor state
7970
- if (updateMaxLine) { cm.curOp.updateMaxLine = true; }
7971
- if (marker.collapsed)
7972
- { regChange(cm, from.line, to.line + 1); }
7973
- else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css)
7974
- { for (var i = from.line; i <= to.line; i++) { regLineChange(cm, i, "text"); } }
7975
- if (marker.atomic) { reCheckSelection(cm.doc); }
7976
- signalLater(cm, "markerAdded", cm, marker);
7977
- }
7978
- return marker
7979
- }
7980
-
7981
- // SHARED TEXTMARKERS
7982
-
7983
- // A shared marker spans multiple linked documents. It is
7984
- // implemented as a meta-marker-object controlling multiple normal
7985
- // markers.
7986
- var SharedTextMarker = function(markers, primary) {
7987
- var this$1 = this;
7988
-
7989
- this.markers = markers;
7990
- this.primary = primary;
7991
- for (var i = 0; i < markers.length; ++i)
7992
- { markers[i].parent = this$1; }
7993
- };
7994
-
7995
- SharedTextMarker.prototype.clear = function () {
7996
  var this$1 = this;
7997
 
7998
- if (this.explicitlyCleared) { return }
7999
- this.explicitlyCleared = true;
8000
- for (var i = 0; i < this.markers.length; ++i)
8001
- { this$1.markers[i].clear(); }
8002
- signalLater(this, "clear");
8003
- };
8004
 
8005
- SharedTextMarker.prototype.find = function (side, lineObj) {
8006
- return this.primary.find(side, lineObj)
8007
- };
8008
- eventMixin(SharedTextMarker);
8009
-
8010
- function markTextShared(doc, from, to, options, type) {
8011
- options = copyObj(options);
8012
- options.shared = false;
8013
- var markers = [markText(doc, from, to, options, type)], primary = markers[0];
8014
- var widget = options.widgetNode;
8015
- linkedDocs(doc, function (doc) {
8016
- if (widget) { options.widgetNode = widget.cloneNode(true); }
8017
- markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
8018
- for (var i = 0; i < doc.linked.length; ++i)
8019
- { if (doc.linked[i].isParent) { return } }
8020
- primary = lst(markers);
8021
- });
8022
- return new SharedTextMarker(markers, primary)
8023
- }
8024
 
8025
- function findSharedMarkers(doc) {
8026
- return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), function (m) { return m.parent; })
8027
- }
 
 
 
8028
 
8029
- function copySharedMarkers(doc, markers) {
8030
- for (var i = 0; i < markers.length; i++) {
8031
- var marker = markers[i], pos = marker.find();
8032
- var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to);
8033
- if (cmp(mFrom, mTo)) {
8034
- var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type);
8035
- marker.markers.push(subMark);
8036
- subMark.parent = marker;
8037
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
8038
  }
8039
- }
8040
 
8041
- function detachSharedMarkers(markers) {
8042
- var loop = function ( i ) {
8043
- var marker = markers[i], linked = [marker.primary.doc];
8044
- linkedDocs(marker.primary.doc, function (d) { return linked.push(d); });
8045
- for (var j = 0; j < marker.markers.length; j++) {
8046
- var subMarker = marker.markers[j];
8047
- if (indexOf(linked, subMarker.doc) == -1) {
8048
- subMarker.parent = null;
8049
- marker.markers.splice(j--, 1);
8050
  }
8051
  }
8052
- };
8053
-
8054
- for (var i = 0; i < markers.length; i++) loop( i );
8055
- }
8056
-
8057
- var nextDocId = 0;
8058
- var Doc = function(text, mode, firstLine, lineSep, direction) {
8059
- if (!(this instanceof Doc)) { return new Doc(text, mode, firstLine, lineSep, direction) }
8060
- if (firstLine == null) { firstLine = 0; }
8061
-
8062
- BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
8063
- this.first = firstLine;
8064
- this.scrollTop = this.scrollLeft = 0;
8065
- this.cantEdit = false;
8066
- this.cleanGeneration = 1;
8067
- this.modeFrontier = this.highlightFrontier = firstLine;
8068
- var start = Pos(firstLine, 0);
8069
- this.sel = simpleSelection(start);
8070
- this.history = new History(null);
8071
- this.id = ++nextDocId;
8072
- this.modeOption = mode;
8073
- this.lineSep = lineSep;
8074
- this.direction = (direction == "rtl") ? "rtl" : "ltr";
8075
- this.extend = false;
8076
-
8077
- if (typeof text == "string") { text = this.splitLines(text); }
8078
- updateDoc(this, {from: start, to: start, text: text});
8079
- setSelection(this, simpleSelection(start), sel_dontScroll);
8080
- };
8081
-
8082
- Doc.prototype = createObj(BranchChunk.prototype, {
8083
- constructor: Doc,
8084
- // Iterate over the document. Supports two forms -- with only one
8085
- // argument, it calls that for each line in the document. With
8086
- // three, it iterates over the range given by the first two (with
8087
- // the second being non-inclusive).
8088
- iter: function(from, to, op) {
8089
- if (op) { this.iterN(from - this.first, to - from, op); }
8090
- else { this.iterN(this.first, this.first + this.size, from); }
8091
- },
8092
-
8093
- // Non-public interface for adding and removing lines.
8094
- insert: function(at, lines) {
8095
- var height = 0;
8096
- for (var i = 0; i < lines.length; ++i) { height += lines[i].height; }
8097
- this.insertInner(at - this.first, lines, height);
8098
- },
8099
- remove: function(at, n) { this.removeInner(at - this.first, n); },
8100
-
8101
- // From here, the methods are part of the public interface. Most
8102
- // are also available from CodeMirror (editor) instances.
8103
 
8104
- getValue: function(lineSep) {
8105
- var lines = getLines(this, this.first, this.first + this.size);
8106
- if (lineSep === false) { return lines }
8107
- return lines.join(lineSep || this.lineSeparator())
8108
- },
8109
- setValue: docMethodOp(function(code) {
8110
- var top = Pos(this.first, 0), last = this.first + this.size - 1;
8111
- makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
8112
- text: this.splitLines(code), origin: "setValue", full: true}, true);
8113
- if (this.cm) { scrollToCoords(this.cm, 0, 0); }
8114
- setSelection(this, simpleSelection(top), sel_dontScroll);
8115
- }),
8116
- replaceRange: function(code, from, to, origin) {
8117
- from = clipPos(this, from);
8118
- to = to ? clipPos(this, to) : from;
8119
- replaceRange(this, code, from, to, origin);
8120
- },
8121
- getRange: function(from, to, lineSep) {
8122
- var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
8123
- if (lineSep === false) { return lines }
8124
- return lines.join(lineSep || this.lineSeparator())
8125
- },
8126
 
8127
- getLine: function(line) {var l = this.getLineHandle(line); return l && l.text},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8128
 
8129
- getLineHandle: function(line) {if (isLine(this, line)) { return getLine(this, line) }},
8130
- getLineNumber: function(line) {return lineNo(line)},
 
 
 
 
 
 
 
 
8131
 
8132
- getLineHandleVisualStart: function(line) {
8133
- if (typeof line == "number") { line = getLine(this, line); }
8134
- return visualLine(line)
8135
- },
 
 
 
8136
 
8137
- lineCount: function() {return this.size},
8138
- firstLine: function() {return this.first},
8139
- lastLine: function() {return this.first + this.size - 1},
8140
 
8141
- clipPos: function(pos) {return clipPos(this, pos)},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8142
 
8143
- getCursor: function(start) {
8144
- var range$$1 = this.sel.primary(), pos;
8145
- if (start == null || start == "head") { pos = range$$1.head; }
8146
- else if (start == "anchor") { pos = range$$1.anchor; }
8147
- else if (start == "end" || start == "to" || start === false) { pos = range$$1.to(); }
8148
- else { pos = range$$1.from(); }
8149
- return pos
8150
- },
8151
- listSelections: function() { return this.sel.ranges },
8152
- somethingSelected: function() {return this.sel.somethingSelected()},
8153
-
8154
- setCursor: docMethodOp(function(line, ch, options) {
8155
- setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options);
8156
- }),
8157
- setSelection: docMethodOp(function(anchor, head, options) {
8158
- setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options);
8159
- }),
8160
- extendSelection: docMethodOp(function(head, other, options) {
8161
- extendSelection(this, clipPos(this, head), other && clipPos(this, other), options);
8162
- }),
8163
- extendSelections: docMethodOp(function(heads, options) {
8164
- extendSelections(this, clipPosArray(this, heads), options);
8165
- }),
8166
- extendSelectionsBy: docMethodOp(function(f, options) {
8167
- var heads = map(this.sel.ranges, f);
8168
- extendSelections(this, clipPosArray(this, heads), options);
8169
- }),
8170
- setSelections: docMethodOp(function(ranges, primary, options) {
8171
- var this$1 = this;
8172
 
8173
- if (!ranges.length) { return }
8174
- var out = [];
8175
- for (var i = 0; i < ranges.length; i++)
8176
- { out[i] = new Range(clipPos(this$1, ranges[i].anchor),
8177
- clipPos(this$1, ranges[i].head)); }
8178
- if (primary == null) { primary = Math.min(ranges.length - 1, this.sel.primIndex); }
8179
- setSelection(this, normalizeSelection(out, primary), options);
8180
- }),
8181
- addSelection: docMethodOp(function(anchor, head, options) {
8182
- var ranges = this.sel.ranges.slice(0);
8183
- ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor)));
8184
- setSelection(this, normalizeSelection(ranges, ranges.length - 1), options);
8185
- }),
8186
-
8187
- getSelection: function(lineSep) {
8188
- var this$1 = this;
8189
 
8190
- var ranges = this.sel.ranges, lines;
8191
- for (var i = 0; i < ranges.length; i++) {
8192
- var sel = getBetween(this$1, ranges[i].from(), ranges[i].to());
8193
- lines = lines ? lines.concat(sel) : sel;
8194
- }
8195
- if (lineSep === false) { return lines }
8196
- else { return lines.join(lineSep || this.lineSeparator()) }
8197
- },
8198
- getSelections: function(lineSep) {
8199
- var this$1 = this;
8200
 
8201
- var parts = [], ranges = this.sel.ranges;
8202
- for (var i = 0; i < ranges.length; i++) {
8203
- var sel = getBetween(this$1, ranges[i].from(), ranges[i].to());
8204
- if (lineSep !== false) { sel = sel.join(lineSep || this$1.lineSeparator()); }
8205
- parts[i] = sel;
8206
- }
8207
- return parts
8208
- },
8209
- replaceSelection: function(code, collapse, origin) {
8210
- var dup = [];
8211
- for (var i = 0; i < this.sel.ranges.length; i++)
8212
- { dup[i] = code; }
8213
- this.replaceSelections(dup, collapse, origin || "+input");
8214
- },
8215
- replaceSelections: docMethodOp(function(code, collapse, origin) {
8216
- var this$1 = this;
8217
 
8218
- var changes = [], sel = this.sel;
8219
- for (var i = 0; i < sel.ranges.length; i++) {
8220
- var range$$1 = sel.ranges[i];
8221
- changes[i] = {from: range$$1.from(), to: range$$1.to(), text: this$1.splitLines(code[i]), origin: origin};
8222
- }
8223
- var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse);
8224
- for (var i$1 = changes.length - 1; i$1 >= 0; i$1--)
8225
- { makeChange(this$1, changes[i$1]); }
8226
- if (newSel) { setSelectionReplaceHistory(this, newSel); }
8227
- else if (this.cm) { ensureCursorVisible(this.cm); }
8228
- }),
8229
- undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}),
8230
- redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}),
8231
- undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}),
8232
- redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}),
8233
-
8234
- setExtending: function(val) {this.extend = val;},
8235
- getExtending: function() {return this.extend},
8236
-
8237
- historySize: function() {
8238
- var hist = this.history, done = 0, undone = 0;
8239
- for (var i = 0; i < hist.done.length; i++) { if (!hist.done[i].ranges) { ++done; } }
8240
- for (var i$1 = 0; i$1 < hist.undone.length; i$1++) { if (!hist.undone[i$1].ranges) { ++undone; } }
8241
- return {undo: done, redo: undone}
8242
- },
8243
- clearHistory: function() {this.history = new History(this.history.maxGeneration);},
8244
 
8245
- markClean: function() {
8246
- this.cleanGeneration = this.changeGeneration(true);
8247
- },
8248
- changeGeneration: function(forceSplit) {
8249
- if (forceSplit)
8250
- { this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null; }
8251
- return this.history.generation
8252
- },
8253
- isClean: function (gen) {
8254
- return this.history.generation == (gen || this.cleanGeneration)
8255
- },
8256
 
8257
- getHistory: function() {
8258
- return {done: copyHistoryArray(this.history.done),
8259
- undone: copyHistoryArray(this.history.undone)}
8260
- },
8261
- setHistory: function(histData) {
8262
- var hist = this.history = new History(this.history.maxGeneration);
8263
- hist.done = copyHistoryArray(histData.done.slice(0), null, true);
8264
- hist.undone = copyHistoryArray(histData.undone.slice(0), null, true);
8265
- },
 
 
 
 
 
 
 
 
 
8266
 
8267
- setGutterMarker: docMethodOp(function(line, gutterID, value) {
8268
- return changeLine(this, line, "gutter", function (line) {
8269
- var markers = line.gutterMarkers || (line.gutterMarkers = {});
8270
- markers[gutterID] = value;
8271
- if (!value && isEmpty(markers)) { line.gutterMarkers = null; }
8272
- return true
8273
- })
8274
- }),
 
 
 
 
 
8275
 
8276
- clearGutter: docMethodOp(function(gutterID) {
8277
- var this$1 = this;
8278
 
8279
- this.iter(function (line) {
8280
- if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
8281
- changeLine(this$1, line, "gutter", function () {
8282
- line.gutterMarkers[gutterID] = null;
8283
- if (isEmpty(line.gutterMarkers)) { line.gutterMarkers = null; }
8284
- return true
8285
- });
8286
  }
8287
- });
8288
- }),
8289
-
8290
- lineInfo: function(line) {
8291
- var n;
8292
- if (typeof line == "number") {
8293
- if (!isLine(this, line)) { return null }
8294
- n = line;
8295
- line = getLine(this, line);
8296
- if (!line) { return null }
8297
- } else {
8298
- n = lineNo(line);
8299
- if (n == null) { return null }
8300
- }
8301
- return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,
8302
- textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,
8303
- widgets: line.widgets}
8304
- },
8305
 
8306
- addLineClass: docMethodOp(function(handle, where, cls) {
8307
- return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) {
8308
- var prop = where == "text" ? "textClass"
8309
- : where == "background" ? "bgClass"
8310
- : where == "gutter" ? "gutterClass" : "wrapClass";
8311
- if (!line[prop]) { line[prop] = cls; }
8312
- else if (classTest(cls).test(line[prop])) { return false }
8313
- else { line[prop] += " " + cls; }
8314
- return true
8315
- })
8316
- }),
8317
- removeLineClass: docMethodOp(function(handle, where, cls) {
8318
- return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) {
8319
- var prop = where == "text" ? "textClass"
8320
- : where == "background" ? "bgClass"
8321
- : where == "gutter" ? "gutterClass" : "wrapClass";
8322
- var cur = line[prop];
8323
- if (!cur) { return false }
8324
- else if (cls == null) { line[prop] = null; }
8325
- else {
8326
- var found = cur.match(classTest(cls));
8327
- if (!found) { return false }
8328
- var end = found.index + found[0].length;
8329
- line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null;
8330
  }
8331
- return true
8332
- })
8333
- }),
8334
-
8335
- addLineWidget: docMethodOp(function(handle, node, options) {
8336
- return addLineWidget(this, handle, node, options)
8337
- }),
8338
- removeLineWidget: function(widget) { widget.clear(); },
8339
-
8340
- markText: function(from, to, options) {
8341
- return markText(this, clipPos(this, from), clipPos(this, to), options, options && options.type || "range")
8342
- },
8343
- setBookmark: function(pos, options) {
8344
- var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
8345
- insertLeft: options && options.insertLeft,
8346
- clearWhenEmpty: false, shared: options && options.shared,
8347
- handleMouseEvents: options && options.handleMouseEvents};
8348
- pos = clipPos(this, pos);
8349
- return markText(this, pos, pos, realOpts, "bookmark")
8350
- },
8351
- findMarksAt: function(pos) {
8352
- pos = clipPos(this, pos);
8353
- var markers = [], spans = getLine(this, pos.line).markedSpans;
8354
- if (spans) { for (var i = 0; i < spans.length; ++i) {
8355
- var span = spans[i];
8356
- if ((span.from == null || span.from <= pos.ch) &&
8357
- (span.to == null || span.to >= pos.ch))
8358
- { markers.push(span.marker.parent || span.marker); }
8359
- } }
8360
- return markers
8361
- },
8362
- findMarks: function(from, to, filter) {
8363
- from = clipPos(this, from); to = clipPos(this, to);
8364
- var found = [], lineNo$$1 = from.line;
8365
- this.iter(from.line, to.line + 1, function (line) {
8366
- var spans = line.markedSpans;
8367
- if (spans) { for (var i = 0; i < spans.length; i++) {
8368
- var span = spans[i];
8369
- if (!(span.to != null && lineNo$$1 == from.line && from.ch >= span.to ||
8370
- span.from == null && lineNo$$1 != from.line ||
8371
- span.from != null && lineNo$$1 == to.line && span.from >= to.ch) &&
8372
- (!filter || filter(span.marker)))
8373
- { found.push(span.marker.parent || span.marker); }
8374
- } }
8375
- ++lineNo$$1;
8376
- });
8377
- return found
8378
- },
8379
- getAllMarks: function() {
8380
- var markers = [];
8381
- this.iter(function (line) {
8382
- var sps = line.markedSpans;
8383
- if (sps) { for (var i = 0; i < sps.length; ++i)
8384
- { if (sps[i].from != null) { markers.push(sps[i].marker); } } }
8385
- });
8386
- return markers
8387
- },
8388
-
8389
- posFromIndex: function(off) {
8390
- var ch, lineNo$$1 = this.first, sepSize = this.lineSeparator().length;
8391
- this.iter(function (line) {
8392
- var sz = line.text.length + sepSize;
8393
- if (sz > off) { ch = off; return true }
8394
- off -= sz;
8395
- ++lineNo$$1;
8396
- });
8397
- return clipPos(this, Pos(lineNo$$1, ch))
8398
- },
8399
- indexFromPos: function (coords) {
8400
- coords = clipPos(this, coords);
8401
- var index = coords.ch;
8402
- if (coords.line < this.first || coords.ch < 0) { return 0 }
8403
- var sepSize = this.lineSeparator().length;
8404
- this.iter(this.first, coords.line, function (line) { // iter aborts when callback returns a truthy value
8405
- index += line.text.length + sepSize;
8406
- });
8407
- return index
8408
- },
8409
 
8410
- copy: function(copyHistory) {
8411
- var doc = new Doc(getLines(this, this.first, this.first + this.size),
8412
- this.modeOption, this.first, this.lineSep, this.direction);
8413
- doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
8414
- doc.sel = this.sel;
8415
- doc.extend = false;
8416
- if (copyHistory) {
8417
- doc.history.undoDepth = this.history.undoDepth;
8418
- doc.setHistory(this.getHistory());
8419
- }
8420
- return doc
8421
- },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8422
 
8423
- linkedDoc: function(options) {
8424
- if (!options) { options = {}; }
8425
- var from = this.first, to = this.first + this.size;
8426
- if (options.from != null && options.from > from) { from = options.from; }
8427
- if (options.to != null && options.to < to) { to = options.to; }
8428
- var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep, this.direction);
8429
- if (options.sharedHist) { copy.history = this.history
8430
- ; }(this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
8431
- copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
8432
- copySharedMarkers(copy, findSharedMarkers(this));
8433
- return copy
8434
- },
8435
- unlinkDoc: function(other) {
8436
- var this$1 = this;
8437
 
8438
- if (other instanceof CodeMirror$1) { other = other.doc; }
8439
- if (this.linked) { for (var i = 0; i < this.linked.length; ++i) {
8440
- var link = this$1.linked[i];
8441
- if (link.doc != other) { continue }
8442
- this$1.linked.splice(i, 1);
8443
- other.unlinkDoc(this$1);
8444
- detachSharedMarkers(findSharedMarkers(this$1));
8445
- break
8446
- } }
8447
- // If the histories were shared, split them again
8448
- if (other.history == this.history) {
8449
- var splitIds = [other.id];
8450
- linkedDocs(other, function (doc) { return splitIds.push(doc.id); }, true);
8451
- other.history = new History(null);
8452
- other.history.done = copyHistoryArray(this.history.done, splitIds);
8453
- other.history.undone = copyHistoryArray(this.history.undone, splitIds);
8454
- }
8455
- },
8456
- iterLinkedDocs: function(f) {linkedDocs(this, f);},
8457
 
8458
- getMode: function() {return this.mode},
8459
- getEditor: function() {return this.cm},
 
 
 
 
 
 
8460
 
8461
- splitLines: function(str) {
8462
- if (this.lineSep) { return str.split(this.lineSep) }
8463
- return splitLinesAuto(str)
8464
- },
8465
- lineSeparator: function() { return this.lineSep || "\n" },
8466
-
8467
- setDirection: docMethodOp(function (dir) {
8468
- if (dir != "rtl") { dir = "ltr"; }
8469
- if (dir == this.direction) { return }
8470
- this.direction = dir;
8471
- this.iter(function (line) { return line.order = null; });
8472
- if (this.cm) { directionChanged(this.cm); }
8473
- })
8474
- });
8475
 
8476
- // Public alias.
8477
- Doc.prototype.eachLine = Doc.prototype.iter;
8478
-
8479
- // Kludge to work around strange IE behavior where it'll sometimes
8480
- // re-fire a series of drag-related events right after the drop (#1551)
8481
- var lastDrop = 0;
8482
-
8483
- function onDrop(e) {
8484
- var cm = this;
8485
- clearDragCursor(cm);
8486
- if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))
8487
- { return }
8488
- e_preventDefault(e);
8489
- if (ie) { lastDrop = +new Date; }
8490
- var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
8491
- if (!pos || cm.isReadOnly()) { return }
8492
- // Might be a file drop, in which case we simply extract the text
8493
- // and insert it.
8494
- if (files && files.length && window.FileReader && window.File) {
8495
- var n = files.length, text = Array(n), read = 0;
8496
- var loadFile = function (file, i) {
8497
- if (cm.options.allowDropFileTypes &&
8498
- indexOf(cm.options.allowDropFileTypes, file.type) == -1)
8499
- { return }
8500
-
8501
- var reader = new FileReader;
8502
- reader.onload = operation(cm, function () {
8503
- var content = reader.result;
8504
- if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) { content = ""; }
8505
- text[i] = content;
8506
- if (++read == n) {
8507
- pos = clipPos(cm.doc, pos);
8508
- var change = {from: pos, to: pos,
8509
- text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())),
8510
- origin: "paste"};
8511
- makeChange(cm.doc, change);
8512
- setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));
8513
  }
8514
  });
8515
- reader.readAsText(file);
8516
- };
8517
- for (var i = 0; i < n; ++i) { loadFile(files[i], i); }
8518
- } else { // Normal drop
8519
- // Don't do a replace if the drop happened inside of the selected text.
8520
- if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) {
8521
- cm.state.draggingText(e);
8522
- // Ensure the editor is re-focused
8523
- setTimeout(function () { return cm.display.input.focus(); }, 20);
8524
- return
8525
- }
8526
- try {
8527
- var text$1 = e.dataTransfer.getData("Text");
8528
- if (text$1) {
8529
- var selected;
8530
- if (cm.state.draggingText && !cm.state.draggingText.copy)
8531
- { selected = cm.listSelections(); }
8532
- setSelectionNoUndo(cm.doc, simpleSelection(pos, pos));
8533
- if (selected) { for (var i$1 = 0; i$1 < selected.length; ++i$1)
8534
- { replaceRange(cm.doc, "", selected[i$1].anchor, selected[i$1].head, "drag"); } }
8535
- cm.replaceSelection(text$1, "around", "paste");
8536
- cm.display.input.focus();
8537
- }
8538
- }
8539
- catch(e){}
8540
- }
8541
- }
8542
-
8543
- function onDragStart(cm, e) {
8544
- if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return }
8545
- if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) { return }
8546
-
8547
- e.dataTransfer.setData("Text", cm.getSelection());
8548
- e.dataTransfer.effectAllowed = "copyMove";
8549
-
8550
- // Use dummy image instead of default browsers image.
8551
- // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
8552
- if (e.dataTransfer.setDragImage && !safari) {
8553
- var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
8554
- img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
8555
- if (presto) {
8556
- img.width = img.height = 1;
8557
- cm.display.wrapper.appendChild(img);
8558
- // Force a relayout, or Opera won't use our image for some obscure reason
8559
- img._top = img.offsetTop;
8560
- }
8561
- e.dataTransfer.setDragImage(img, 0, 0);
8562
- if (presto) { img.parentNode.removeChild(img); }
8563
- }
8564
- }
8565
 
8566
- function onDragOver(cm, e) {
8567
- var pos = posFromMouse(cm, e);
8568
- if (!pos) { return }
8569
- var frag = document.createDocumentFragment();
8570
- drawSelectionCursor(cm, pos, frag);
8571
- if (!cm.display.dragCursor) {
8572
- cm.display.dragCursor = elt("div", null, "CodeMirror-cursors CodeMirror-dragcursors");
8573
- cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv);
8574
- }
8575
- removeChildrenAndAdd(cm.display.dragCursor, frag);
8576
- }
 
 
 
 
8577
 
8578
- function clearDragCursor(cm) {
8579
- if (cm.display.dragCursor) {
8580
- cm.display.lineSpace.removeChild(cm.display.dragCursor);
8581
- cm.display.dragCursor = null;
8582
- }
8583
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8584
 
8585
- // These must be handled carefully, because naively registering a
8586
- // handler for each editor will cause the editors to never be
8587
- // garbage collected.
 
8588
 
8589
- function forEachCodeMirror(f) {
8590
- if (!document.getElementsByClassName) { return }
8591
- var byClass = document.getElementsByClassName("CodeMirror");
8592
- for (var i = 0; i < byClass.length; i++) {
8593
- var cm = byClass[i].CodeMirror;
8594
- if (cm) { f(cm); }
8595
- }
8596
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8597
 
8598
- var globalsRegistered = false;
8599
- function ensureGlobalHandlers() {
8600
- if (globalsRegistered) { return }
8601
- registerGlobalHandlers();
8602
- globalsRegistered = true;
8603
- }
8604
- function registerGlobalHandlers() {
8605
- // When the window resizes, we need to refresh active editors.
8606
- var resizeTimer;
8607
- on(window, "resize", function () {
8608
- if (resizeTimer == null) { resizeTimer = setTimeout(function () {
8609
- resizeTimer = null;
8610
- forEachCodeMirror(onResize);
8611
- }, 100); }
8612
- });
8613
- // When the window loses focus, we want to show the editor as blurred
8614
- on(window, "blur", function () { return forEachCodeMirror(onBlur); });
8615
- }
8616
- // Called when the window resizes
8617
- function onResize(cm) {
8618
- var d = cm.display;
8619
- // Might be a text scaling operation, clear size caches.
8620
- d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
8621
- d.scrollbarsClipped = false;
8622
- cm.setSize();
8623
- }
8624
 
8625
- var keyNames = {
8626
- 3: "Pause", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
8627
- 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
8628
- 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
8629
- 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod",
8630
- 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete", 145: "ScrollLock",
8631
- 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
8632
- 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
8633
- 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"
8634
- };
 
 
8635
 
8636
- // Number keys
8637
- for (var i = 0; i < 10; i++) { keyNames[i + 48] = keyNames[i + 96] = String(i); }
8638
- // Alphabetic keys
8639
- for (var i$1 = 65; i$1 <= 90; i$1++) { keyNames[i$1] = String.fromCharCode(i$1); }
8640
- // Function keys
8641
- for (var i$2 = 1; i$2 <= 12; i$2++) { keyNames[i$2 + 111] = keyNames[i$2 + 63235] = "F" + i$2; }
8642
-
8643
- var keyMap = {};
8644
-
8645
- keyMap.basic = {
8646
- "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
8647
- "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
8648
- "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore",
8649
- "Tab": "defaultTab", "Shift-Tab": "indentAuto",
8650
- "Enter": "newlineAndIndent", "Insert": "toggleOverwrite",
8651
- "Esc": "singleSelection"
8652
- };
8653
- // Note that the save and find-related commands aren't defined by
8654
- // default. User code or addons can define them. Unknown commands
8655
- // are simply ignored.
8656
- keyMap.pcDefault = {
8657
- "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
8658
- "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown",
8659
- "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
8660
- "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
8661
- "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
8662
- "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
8663
- "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection",
8664
- "fallthrough": "basic"
8665
- };
8666
- // Very basic readline/emacs-style bindings, which are standard on Mac.
8667
- keyMap.emacsy = {
8668
- "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
8669
- "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
8670
- "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
8671
- "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars",
8672
- "Ctrl-O": "openLine"
8673
- };
8674
- keyMap.macDefault = {
8675
- "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
8676
- "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
8677
- "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore",
8678
- "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
8679
- "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
8680
- "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight",
8681
- "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd",
8682
- "fallthrough": ["basic", "emacsy"]
8683
- };
8684
- keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
8685
-
8686
- // KEYMAP DISPATCH
8687
-
8688
- function normalizeKeyName(name) {
8689
- var parts = name.split(/-(?!$)/);
8690
- name = parts[parts.length - 1];
8691
- var alt, ctrl, shift, cmd;
8692
- for (var i = 0; i < parts.length - 1; i++) {
8693
- var mod = parts[i];
8694
- if (/^(cmd|meta|m)$/i.test(mod)) { cmd = true; }
8695
- else if (/^a(lt)?$/i.test(mod)) { alt = true; }
8696
- else if (/^(c|ctrl|control)$/i.test(mod)) { ctrl = true; }
8697
- else if (/^s(hift)?$/i.test(mod)) { shift = true; }
8698
- else { throw new Error("Unrecognized modifier name: " + mod) }
8699
- }
8700
- if (alt) { name = "Alt-" + name; }
8701
- if (ctrl) { name = "Ctrl-" + name; }
8702
- if (cmd) { name = "Cmd-" + name; }
8703
- if (shift) { name = "Shift-" + name; }
8704
- return name
8705
- }
8706
 
8707
- // This is a kludge to keep keymaps mostly working as raw objects
8708
- // (backwards compatibility) while at the same time support features
8709
- // like normalization and multi-stroke key bindings. It compiles a
8710
- // new normalized keymap, and then updates the old object to reflect
8711
- // this.
8712
- function normalizeKeyMap(keymap) {
8713
- var copy = {};
8714
- for (var keyname in keymap) { if (keymap.hasOwnProperty(keyname)) {
8715
- var value = keymap[keyname];
8716
- if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) { continue }
8717
- if (value == "...") { delete keymap[keyname]; continue }
8718
-
8719
- var keys = map(keyname.split(" "), normalizeKeyName);
8720
- for (var i = 0; i < keys.length; i++) {
8721
- var val = (void 0), name = (void 0);
8722
- if (i == keys.length - 1) {
8723
- name = keys.join(" ");
8724
- val = value;
8725
- } else {
8726
- name = keys.slice(0, i + 1).join(" ");
8727
- val = "...";
8728
  }
8729
- var prev = copy[name];
8730
- if (!prev) { copy[name] = val; }
8731
- else if (prev != val) { throw new Error("Inconsistent bindings for " + name) }
8732
- }
8733
- delete keymap[keyname];
8734
- } }
8735
- for (var prop in copy) { keymap[prop] = copy[prop]; }
8736
- return keymap
8737
- }
8738
-
8739
- function lookupKey(key, map$$1, handle, context) {
8740
- map$$1 = getKeyMap(map$$1);
8741
- var found = map$$1.call ? map$$1.call(key, context) : map$$1[key];
8742
- if (found === false) { return "nothing" }
8743
- if (found === "...") { return "multi" }
8744
- if (found != null && handle(found)) { return "handled" }
8745
-
8746
- if (map$$1.fallthrough) {
8747
- if (Object.prototype.toString.call(map$$1.fallthrough) != "[object Array]")
8748
- { return lookupKey(key, map$$1.fallthrough, handle, context) }
8749
- for (var i = 0; i < map$$1.fallthrough.length; i++) {
8750
- var result = lookupKey(key, map$$1.fallthrough[i], handle, context);
8751
- if (result) { return result }
8752
- }
8753
- }
8754
- }
8755
 
8756
- // Modifier key presses don't count as 'real' key presses for the
8757
- // purpose of keymap fallthrough.
8758
- function isModifierKey(value) {
8759
- var name = typeof value == "string" ? value : keyNames[value.keyCode];
8760
- return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod"
8761
- }
8762
 
8763
- function addModifierNames(name, event, noShift) {
8764
- var base = name;
8765
- if (event.altKey && base != "Alt") { name = "Alt-" + name; }
8766
- if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") { name = "Ctrl-" + name; }
8767
- if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") { name = "Cmd-" + name; }
8768
- if (!noShift && event.shiftKey && base != "Shift") { name = "Shift-" + name; }
8769
- return name
8770
- }
 
 
 
 
 
 
8771
 
8772
- // Look up the name of a key as indicated by an event object.
8773
- function keyName(event, noShift) {
8774
- if (presto && event.keyCode == 34 && event["char"]) { return false }
8775
- var name = keyNames[event.keyCode];
8776
- if (name == null || event.altGraphKey) { return false }
8777
- // Ctrl-ScrollLock has keyCode 3, same as Ctrl-Pause,
8778
- // so we'll use event.code when available (Chrome 48+, FF 38+, Safari 10.1+)
8779
- if (event.keyCode == 3 && event.code) { name = event.code; }
8780
- return addModifierNames(name, event, noShift)
8781
- }
8782
 
8783
- function getKeyMap(val) {
8784
- return typeof val == "string" ? keyMap[val] : val
8785
- }
8786
 
8787
- // Helper for deleting text near the selection(s), used to implement
8788
- // backspace, delete, and similar functionality.
8789
- function deleteNearSelection(cm, compute) {
8790
- var ranges = cm.doc.sel.ranges, kill = [];
8791
- // Build up a set of ranges to kill first, merging overlapping
8792
- // ranges.
8793
- for (var i = 0; i < ranges.length; i++) {
8794
- var toKill = compute(ranges[i]);
8795
- while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) {
8796
- var replaced = kill.pop();
8797
- if (cmp(replaced.from, toKill.from) < 0) {
8798
- toKill.from = replaced.from;
8799
- break
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8800
  }
 
8801
  }
8802
- kill.push(toKill);
8803
  }
8804
- // Next, remove those actual ranges.
8805
- runInOp(cm, function () {
8806
- for (var i = kill.length - 1; i >= 0; i--)
8807
- { replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete"); }
8808
- ensureCursorVisible(cm);
8809
- });
8810
- }
8811
-
8812
- function moveCharLogically(line, ch, dir) {
8813
- var target = skipExtendingChars(line.text, ch + dir, dir);
8814
- return target < 0 || target > line.text.length ? null : target
8815
- }
8816
 
8817
- function moveLogically(line, start, dir) {
8818
- var ch = moveCharLogically(line, start.ch, dir);
8819
- return ch == null ? null : new Pos(start.line, ch, dir < 0 ? "after" : "before")
8820
- }
8821
 
8822
- function endOfLine(visually, cm, lineObj, lineNo, dir) {
8823
- if (visually) {
8824
- var order = getOrder(lineObj, cm.doc.direction);
8825
- if (order) {
8826
- var part = dir < 0 ? lst(order) : order[0];
8827
- var moveInStorageOrder = (dir < 0) == (part.level == 1);
8828
- var sticky = moveInStorageOrder ? "after" : "before";
8829
- var ch;
8830
- // With a wrapped rtl chunk (possibly spanning multiple bidi parts),
8831
- // it could be that the last bidi part is not on the last visual line,
8832
- // since visual lines contain content order-consecutive chunks.
8833
- // Thus, in rtl, we are looking for the first (content-order) character
8834
- // in the rtl chunk that is on the last line (that is, the same line
8835
- // as the last (content-order) character).
8836
- if (part.level > 0 || cm.doc.direction == "rtl") {
8837
- var prep = prepareMeasureForLine(cm, lineObj);
8838
- ch = dir < 0 ? lineObj.text.length - 1 : 0;
8839
- var targetTop = measureCharPrepared(cm, prep, ch).top;
8840
- ch = findFirst(function (ch) { return measureCharPrepared(cm, prep, ch).top == targetTop; }, (dir < 0) == (part.level == 1) ? part.from : part.to - 1, ch);
8841
- if (sticky == "before") { ch = moveCharLogically(lineObj, ch, 1); }
8842
- } else { ch = dir < 0 ? part.to : part.from; }
8843
- return new Pos(lineNo, ch, sticky)
8844
- }
8845
- }
8846
- return new Pos(lineNo, dir < 0 ? lineObj.text.length : 0, dir < 0 ? "before" : "after")
8847
- }
8848
 
8849
- function moveVisually(cm, line, start, dir) {
8850
- var bidi = getOrder(line, cm.doc.direction);
8851
- if (!bidi) { return moveLogically(line, start, dir) }
8852
- if (start.ch >= line.text.length) {
8853
- start.ch = line.text.length;
8854
- start.sticky = "before";
8855
- } else if (start.ch <= 0) {
8856
- start.ch = 0;
8857
- start.sticky = "after";
8858
- }
8859
- var partPos = getBidiPartAt(bidi, start.ch, start.sticky), part = bidi[partPos];
8860
- if (cm.doc.direction == "ltr" && part.level % 2 == 0 && (dir > 0 ? part.to > start.ch : part.from < start.ch)) {
8861
- // Case 1: We move within an ltr part in an ltr editor. Even with wrapped lines,
8862
- // nothing interesting happens.
8863
- return moveLogically(line, start, dir)
8864
  }
8865
 
8866
- var mv = function (pos, dir) { return moveCharLogically(line, pos instanceof Pos ? pos.ch : pos, dir); };
8867
- var prep;
8868
- var getWrappedLineExtent = function (ch) {
8869
- if (!cm.options.lineWrapping) { return {begin: 0, end: line.text.length} }
8870
- prep = prep || prepareMeasureForLine(cm, line);
8871
- return wrappedLineExtentChar(cm, line, prep, ch)
8872
- };
8873
- var wrappedLineExtent = getWrappedLineExtent(start.sticky == "before" ? mv(start, -1) : start.ch);
8874
-
8875
- if (cm.doc.direction == "rtl" || part.level == 1) {
8876
- var moveInStorageOrder = (part.level == 1) == (dir < 0);
8877
- var ch = mv(start, moveInStorageOrder ? 1 : -1);
8878
- if (ch != null && (!moveInStorageOrder ? ch >= part.from && ch >= wrappedLineExtent.begin : ch <= part.to && ch <= wrappedLineExtent.end)) {
8879
- // Case 2: We move within an rtl part or in an rtl editor on the same visual line
8880
- var sticky = moveInStorageOrder ? "before" : "after";
8881
- return new Pos(start.line, ch, sticky)
8882
  }
 
8883
  }
8884
 
8885
- // Case 3: Could not move within this bidi part in this visual line, so leave
8886
- // the current bidi part
8887
-
8888
- var searchInVisualLine = function (partPos, dir, wrappedLineExtent) {
8889
- var getRes = function (ch, moveInStorageOrder) { return moveInStorageOrder
8890
- ? new Pos(start.line, mv(ch, 1), "before")
8891
- : new Pos(start.line, ch, "after"); };
8892
-
8893
- for (; partPos >= 0 && partPos < bidi.length; partPos += dir) {
8894
- var part = bidi[partPos];
8895
- var moveInStorageOrder = (dir > 0) == (part.level != 1);
8896
- var ch = moveInStorageOrder ? wrappedLineExtent.begin : mv(wrappedLineExtent.end, -1);
8897
- if (part.from <= ch && ch < part.to) { return getRes(ch, moveInStorageOrder) }
8898
- ch = moveInStorageOrder ? part.from : mv(part.to, -1);
8899
- if (wrappedLineExtent.begin <= ch && ch < wrappedLineExtent.end) { return getRes(ch, moveInStorageOrder) }
8900
  }
8901
- };
8902
 
8903
- // Case 3a: Look for other bidi parts on the same visual line
8904
- var res = searchInVisualLine(partPos + dir, dir, wrappedLineExtent);
8905
- if (res) { return res }
8906
 
8907
- // Case 3b: Look for other bidi parts on the next visual line
8908
- var nextCh = dir > 0 ? wrappedLineExtent.end : mv(wrappedLineExtent.begin, -1);
8909
- if (nextCh != null && !(dir > 0 && nextCh == line.text.length)) {
8910
- res = searchInVisualLine(dir > 0 ? 0 : bidi.length - 1, dir, getWrappedLineExtent(nextCh));
8911
- if (res) { return res }
 
 
8912
  }
8913
 
8914
- // Case 4: Nowhere to move
8915
- return null
8916
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8917
 
8918
- // Commands are parameter-less actions that can be performed on an
8919
- // editor, mostly used for keybindings.
8920
- var commands = {
8921
- selectAll: selectAll,
8922
- singleSelection: function (cm) { return cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll); },
8923
- killLine: function (cm) { return deleteNearSelection(cm, function (range) {
8924
- if (range.empty()) {
8925
- var len = getLine(cm.doc, range.head.line).text.length;
8926
- if (range.head.ch == len && range.head.line < cm.lastLine())
8927
- { return {from: range.head, to: Pos(range.head.line + 1, 0)} }
8928
- else
8929
- { return {from: range.head, to: Pos(range.head.line, len)} }
8930
- } else {
8931
- return {from: range.from(), to: range.to()}
8932
- }
8933
- }); },
8934
- deleteLine: function (cm) { return deleteNearSelection(cm, function (range) { return ({
8935
- from: Pos(range.from().line, 0),
8936
- to: clipPos(cm.doc, Pos(range.to().line + 1, 0))
8937
- }); }); },
8938
- delLineLeft: function (cm) { return deleteNearSelection(cm, function (range) { return ({
8939
- from: Pos(range.from().line, 0), to: range.from()
8940
- }); }); },
8941
- delWrappedLineLeft: function (cm) { return deleteNearSelection(cm, function (range) {
8942
- var top = cm.charCoords(range.head, "div").top + 5;
8943
- var leftPos = cm.coordsChar({left: 0, top: top}, "div");
8944
- return {from: leftPos, to: range.from()}
8945
- }); },
8946
- delWrappedLineRight: function (cm) { return deleteNearSelection(cm, function (range) {
8947
- var top = cm.charCoords(range.head, "div").top + 5;
8948
- var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div");
8949
- return {from: range.from(), to: rightPos }
8950
- }); },
8951
- undo: function (cm) { return cm.undo(); },
8952
- redo: function (cm) { return cm.redo(); },
8953
- undoSelection: function (cm) { return cm.undoSelection(); },
8954
- redoSelection: function (cm) { return cm.redoSelection(); },
8955
- goDocStart: function (cm) { return cm.extendSelection(Pos(cm.firstLine(), 0)); },
8956
- goDocEnd: function (cm) { return cm.extendSelection(Pos(cm.lastLine())); },
8957
- goLineStart: function (cm) { return cm.extendSelectionsBy(function (range) { return lineStart(cm, range.head.line); },
8958
- {origin: "+move", bias: 1}
8959
- ); },
8960
- goLineStartSmart: function (cm) { return cm.extendSelectionsBy(function (range) { return lineStartSmart(cm, range.head); },
8961
- {origin: "+move", bias: 1}
8962
- ); },
8963
- goLineEnd: function (cm) { return cm.extendSelectionsBy(function (range) { return lineEnd(cm, range.head.line); },
8964
- {origin: "+move", bias: -1}
8965
- ); },
8966
- goLineRight: function (cm) { return cm.extendSelectionsBy(function (range) {
8967
- var top = cm.cursorCoords(range.head, "div").top + 5;
8968
- return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div")
8969
- }, sel_move); },
8970
- goLineLeft: function (cm) { return cm.extendSelectionsBy(function (range) {
8971
- var top = cm.cursorCoords(range.head, "div").top + 5;
8972
- return cm.coordsChar({left: 0, top: top}, "div")
8973
- }, sel_move); },
8974
- goLineLeftSmart: function (cm) { return cm.extendSelectionsBy(function (range) {
8975
- var top = cm.cursorCoords(range.head, "div").top + 5;
8976
- var pos = cm.coordsChar({left: 0, top: top}, "div");
8977
- if (pos.ch < cm.getLine(pos.line).search(/\S/)) { return lineStartSmart(cm, range.head) }
8978
- return pos
8979
- }, sel_move); },
8980
- goLineUp: function (cm) { return cm.moveV(-1, "line"); },
8981
- goLineDown: function (cm) { return cm.moveV(1, "line"); },
8982
- goPageUp: function (cm) { return cm.moveV(-1, "page"); },
8983
- goPageDown: function (cm) { return cm.moveV(1, "page"); },
8984
- goCharLeft: function (cm) { return cm.moveH(-1, "char"); },
8985
- goCharRight: function (cm) { return cm.moveH(1, "char"); },
8986
- goColumnLeft: function (cm) { return cm.moveH(-1, "column"); },
8987
- goColumnRight: function (cm) { return cm.moveH(1, "column"); },
8988
- goWordLeft: function (cm) { return cm.moveH(-1, "word"); },
8989
- goGroupRight: function (cm) { return cm.moveH(1, "group"); },
8990
- goGroupLeft: function (cm) { return cm.moveH(-1, "group"); },
8991
- goWordRight: function (cm) { return cm.moveH(1, "word"); },
8992
- delCharBefore: function (cm) { return cm.deleteH(-1, "char"); },
8993
- delCharAfter: function (cm) { return cm.deleteH(1, "char"); },
8994
- delWordBefore: function (cm) { return cm.deleteH(-1, "word"); },
8995
- delWordAfter: function (cm) { return cm.deleteH(1, "word"); },
8996
- delGroupBefore: function (cm) { return cm.deleteH(-1, "group"); },
8997
- delGroupAfter: function (cm) { return cm.deleteH(1, "group"); },
8998
- indentAuto: function (cm) { return cm.indentSelection("smart"); },
8999
- indentMore: function (cm) { return cm.indentSelection("add"); },
9000
- indentLess: function (cm) { return cm.indentSelection("subtract"); },
9001
- insertTab: function (cm) { return cm.replaceSelection("\t"); },
9002
- insertSoftTab: function (cm) {
9003
- var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize;
9004
- for (var i = 0; i < ranges.length; i++) {
9005
- var pos = ranges[i].from();
9006
- var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize);
9007
- spaces.push(spaceStr(tabSize - col % tabSize));
9008
- }
9009
- cm.replaceSelections(spaces);
9010
- },
9011
- defaultTab: function (cm) {
9012
- if (cm.somethingSelected()) { cm.indentSelection("add"); }
9013
- else { cm.execCommand("insertTab"); }
9014
- },
9015
- // Swap the two chars left and right of each selection's head.
9016
- // Move cursor behind the two swapped characters afterwards.
9017
- //
9018
- // Doesn't consider line feeds a character.
9019
- // Doesn't scan more than one line above to find a character.
9020
- // Doesn't do anything on an empty line.
9021
- // Doesn't do anything with non-empty selections.
9022
- transposeChars: function (cm) { return runInOp(cm, function () {
9023
- var ranges = cm.listSelections(), newSel = [];
9024
- for (var i = 0; i < ranges.length; i++) {
9025
- if (!ranges[i].empty()) { continue }
9026
- var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text;
9027
- if (line) {
9028
- if (cur.ch == line.length) { cur = new Pos(cur.line, cur.ch - 1); }
9029
- if (cur.ch > 0) {
9030
- cur = new Pos(cur.line, cur.ch + 1);
9031
- cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2),
9032
- Pos(cur.line, cur.ch - 2), cur, "+transpose");
9033
- } else if (cur.line > cm.doc.first) {
9034
- var prev = getLine(cm.doc, cur.line - 1).text;
9035
- if (prev) {
9036
- cur = new Pos(cur.line, 1);
9037
- cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() +
9038
- prev.charAt(prev.length - 1),
9039
- Pos(cur.line - 1, prev.length - 1), cur, "+transpose");
9040
- }
9041
  }
 
 
 
9042
  }
9043
- newSel.push(new Range(cur, cur));
9044
- }
9045
- cm.setSelections(newSel);
9046
- }); },
9047
- newlineAndIndent: function (cm) { return runInOp(cm, function () {
9048
- var sels = cm.listSelections();
9049
- for (var i = sels.length - 1; i >= 0; i--)
9050
- { cm.replaceRange(cm.doc.lineSeparator(), sels[i].anchor, sels[i].head, "+input"); }
9051
- sels = cm.listSelections();
9052
- for (var i$1 = 0; i$1 < sels.length; i$1++)
9053
- { cm.indentLine(sels[i$1].from().line, null, true); }
9054
- ensureCursorVisible(cm);
9055
- }); },
9056
- openLine: function (cm) { return cm.replaceSelection("\n", "start"); },
9057
- toggleOverwrite: function (cm) { return cm.toggleOverwrite(); }
9058
- };
9059
 
 
 
 
 
 
 
9060
 
9061
- function lineStart(cm, lineN) {
9062
- var line = getLine(cm.doc, lineN);
9063
- var visual = visualLine(line);
9064
- if (visual != line) { lineN = lineNo(visual); }
9065
- return endOfLine(true, cm, visual, lineN, 1)
9066
- }
9067
- function lineEnd(cm, lineN) {
9068
- var line = getLine(cm.doc, lineN);
9069
- var visual = visualLineEnd(line);
9070
- if (visual != line) { lineN = lineNo(visual); }
9071
- return endOfLine(true, cm, line, lineN, -1)
9072
- }
9073
- function lineStartSmart(cm, pos) {
9074
- var start = lineStart(cm, pos.line);
9075
- var line = getLine(cm.doc, start.line);
9076
- var order = getOrder(line, cm.doc.direction);
9077
- if (!order || order[0].level == 0) {
9078
- var firstNonWS = Math.max(0, line.text.search(/\S/));
9079
- var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch;
9080
- return Pos(start.line, inWS ? 0 : firstNonWS, start.sticky)
9081
- }
9082
- return start
9083
- }
9084
 
9085
- // Run a handler that was bound to a key.
9086
- function doHandleBinding(cm, bound, dropShift) {
9087
- if (typeof bound == "string") {
9088
- bound = commands[bound];
9089
- if (!bound) { return false }
9090
- }
9091
- // Ensure previous input has been read, so that the handler sees a
9092
- // consistent view of the document
9093
- cm.display.input.ensurePolled();
9094
- var prevShift = cm.display.shift, done = false;
9095
- try {
9096
- if (cm.isReadOnly()) { cm.state.suppressEdits = true; }
9097
- if (dropShift) { cm.display.shift = false; }
9098
- done = bound(cm) != Pass;
9099
- } finally {
9100
- cm.display.shift = prevShift;
9101
- cm.state.suppressEdits = false;
9102
- }
9103
- return done
9104
- }
9105
 
9106
- function lookupKeyForEditor(cm, name, handle) {
9107
- for (var i = 0; i < cm.state.keyMaps.length; i++) {
9108
- var result = lookupKey(name, cm.state.keyMaps[i], handle, cm);
9109
- if (result) { return result }
 
 
 
9110
  }
9111
- return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm))
9112
- || lookupKey(name, cm.options.keyMap, handle, cm)
9113
- }
9114
 
9115
- // Note that, despite the name, this function is also used to check
9116
- // for bound mouse clicks.
 
 
 
 
 
 
 
 
9117
 
9118
- var stopSeq = new Delayed;
 
 
9119
 
9120
- function dispatchKey(cm, name, e, handle) {
9121
- var seq = cm.state.keySeq;
9122
- if (seq) {
9123
- if (isModifierKey(name)) { return "handled" }
9124
- if (/\'$/.test(name))
9125
- { cm.state.keySeq = null; }
9126
- else
9127
- { stopSeq.set(50, function () {
9128
- if (cm.state.keySeq == seq) {
9129
- cm.state.keySeq = null;
9130
- cm.display.input.reset();
 
 
9131
  }
9132
- }); }
9133
- if (dispatchKeyInner(cm, seq + " " + name, e, handle)) { return true }
 
 
 
 
 
 
 
9134
  }
9135
- return dispatchKeyInner(cm, name, e, handle)
9136
- }
9137
-
9138
- function dispatchKeyInner(cm, name, e, handle) {
9139
- var result = lookupKeyForEditor(cm, name, handle);
9140
-
9141
- if (result == "multi")
9142
- { cm.state.keySeq = name; }
9143
- if (result == "handled")
9144
- { signalLater(cm, "keyHandled", cm, name, e); }
9145
 
9146
- if (result == "handled" || result == "multi") {
9147
- e_preventDefault(e);
9148
- restartBlink(cm);
9149
  }
9150
 
9151
- return !!result
9152
- }
9153
-
9154
- // Handle a key from the keydown event.
9155
- function handleKeyBinding(cm, e) {
9156
- var name = keyName(e, true);
9157
- if (!name) { return false }
9158
-
9159
- if (e.shiftKey && !cm.state.keySeq) {
9160
- // First try to resolve full name (including 'Shift-'). Failing
9161
- // that, see if there is a cursor-motion command (starting with
9162
- // 'go') bound to the keyname without 'Shift-'.
9163
- return dispatchKey(cm, "Shift-" + name, e, function (b) { return doHandleBinding(cm, b, true); })
9164
- || dispatchKey(cm, name, e, function (b) {
9165
- if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion)
9166
- { return doHandleBinding(cm, b) }
9167
- })
9168
- } else {
9169
- return dispatchKey(cm, name, e, function (b) { return doHandleBinding(cm, b); })
9170
  }
9171
- }
9172
-
9173
- // Handle a key from the keypress event
9174
- function handleCharBinding(cm, e, ch) {
9175
- return dispatchKey(cm, "'" + ch + "'", e, function (b) { return doHandleBinding(cm, b, true); })
9176
- }
9177
-
9178
- var lastStoppedKey = null;
9179
- function onKeyDown(e) {
9180
- var cm = this;
9181
- cm.curOp.focus = activeElt();
9182
- if (signalDOMEvent(cm, e)) { return }
9183
- // IE does strange things with escape.
9184
- if (ie && ie_version < 11 && e.keyCode == 27) { e.returnValue = false; }
9185
- var code = e.keyCode;
9186
- cm.display.shift = code == 16 || e.shiftKey;
9187
- var handled = handleKeyBinding(cm, e);
9188
- if (presto) {
9189
- lastStoppedKey = handled ? code : null;
9190
- // Opera has no cut event... we try to at least catch the key combo
9191
- if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))
9192
- { cm.replaceSelection("", null, "cut"); }
9193
- }
9194
-
9195
- // Turn mouse into crosshair when Alt is held on Mac.
9196
- if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className))
9197
- { showCrossHair(cm); }
9198
- }
9199
 
9200
- function showCrossHair(cm) {
9201
- var lineDiv = cm.display.lineDiv;
9202
- addClass(lineDiv, "CodeMirror-crosshair");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9203
 
9204
- function up(e) {
9205
- if (e.keyCode == 18 || !e.altKey) {
9206
- rmClass(lineDiv, "CodeMirror-crosshair");
9207
- off(document, "keyup", up);
9208
- off(document, "mouseover", up);
 
 
 
9209
  }
9210
- }
9211
- on(document, "keyup", up);
9212
- on(document, "mouseover", up);
9213
- }
9214
 
9215
- function onKeyUp(e) {
9216
- if (e.keyCode == 16) { this.doc.sel.shift = false; }
9217
- signalDOMEvent(this, e);
9218
- }
9219
 
9220
- function onKeyPress(e) {
9221
- var cm = this;
9222
- if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) { return }
9223
- var keyCode = e.keyCode, charCode = e.charCode;
9224
- if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return}
9225
- if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) { return }
9226
- var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
9227
- // Some browsers fire keypress events for backspace
9228
- if (ch == "\x08") { return }
9229
- if (handleCharBinding(cm, e, ch)) { return }
9230
- cm.display.input.onKeyPress(e);
9231
- }
9232
 
9233
- var DOUBLECLICK_DELAY = 400;
 
 
 
 
 
 
 
 
9234
 
9235
- var PastClick = function(time, pos, button) {
9236
- this.time = time;
9237
- this.pos = pos;
9238
- this.button = button;
9239
- };
9240
 
9241
- PastClick.prototype.compare = function (time, pos, button) {
9242
- return this.time + DOUBLECLICK_DELAY > time &&
9243
- cmp(pos, this.pos) == 0 && button == this.button
9244
- };
 
 
9245
 
9246
- var lastClick;
9247
- var lastDoubleClick;
9248
- function clickRepeat(pos, button) {
9249
- var now = +new Date;
9250
- if (lastDoubleClick && lastDoubleClick.compare(now, pos, button)) {
9251
- lastClick = lastDoubleClick = null;
9252
- return "triple"
9253
- } else if (lastClick && lastClick.compare(now, pos, button)) {
9254
- lastDoubleClick = new PastClick(now, pos, button);
9255
- lastClick = null;
9256
- return "double"
9257
- } else {
9258
- lastClick = new PastClick(now, pos, button);
9259
- lastDoubleClick = null;
9260
- return "single"
9261
  }
9262
- }
9263
 
9264
- // A mouse down can be a single click, double click, triple click,
9265
- // start of selection drag, start of text drag, new cursor
9266
- // (ctrl-click), rectangle drag (alt-drag), or xwin
9267
- // middle-click-paste. Or it might be a click on something we should
9268
- // not interfere with, such as a scrollbar or widget.
9269
- function onMouseDown(e) {
9270
- var cm = this, display = cm.display;
9271
- if (signalDOMEvent(cm, e) || display.activeTouch && display.input.supportsTouch()) { return }
9272
- display.input.ensurePolled();
9273
- display.shift = e.shiftKey;
9274
-
9275
- if (eventInWidget(display, e)) {
9276
- if (!webkit) {
9277
- // Briefly turn off draggability, to allow widgets to do
9278
- // normal dragging things.
9279
- display.scroller.draggable = false;
9280
- setTimeout(function () { return display.scroller.draggable = true; }, 100);
9281
- }
9282
- return
9283
- }
9284
- if (clickInGutter(cm, e)) { return }
9285
- var pos = posFromMouse(cm, e), button = e_button(e), repeat = pos ? clickRepeat(pos, button) : "single";
9286
- window.focus();
9287
-
9288
- // #3261: make sure, that we're not starting a second selection
9289
- if (button == 1 && cm.state.selectingText)
9290
- { cm.state.selectingText(e); }
9291
-
9292
- if (pos && handleMappedButton(cm, button, pos, repeat, e)) { return }
9293
-
9294
- if (button == 1) {
9295
- if (pos) { leftButtonDown(cm, pos, repeat, e); }
9296
- else if (e_target(e) == display.scroller) { e_preventDefault(e); }
9297
- } else if (button == 2) {
9298
- if (pos) { extendSelection(cm.doc, pos); }
9299
- setTimeout(function () { return display.input.focus(); }, 20);
9300
- } else if (button == 3) {
9301
- if (captureRightClick) { onContextMenu(cm, e); }
9302
- else { delayBlurEvent(cm); }
9303
- }
9304
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9305
 
9306
- function handleMappedButton(cm, button, pos, repeat, event) {
9307
- var name = "Click";
9308
- if (repeat == "double") { name = "Double" + name; }
9309
- else if (repeat == "triple") { name = "Triple" + name; }
9310
- name = (button == 1 ? "Left" : button == 2 ? "Middle" : "Right") + name;
9311
 
9312
- return dispatchKey(cm, addModifierNames(name, event), event, function (bound) {
9313
- if (typeof bound == "string") { bound = commands[bound]; }
9314
- if (!bound) { return false }
9315
- var done = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9316
  try {
9317
  if (cm.isReadOnly()) { cm.state.suppressEdits = true; }
9318
- done = bound(cm, pos) != Pass;
 
9319
  } finally {
 
9320
  cm.state.suppressEdits = false;
9321
  }
9322
  return done
9323
- })
9324
- }
9325
-
9326
- function configureMouse(cm, repeat, event) {
9327
- var option = cm.getOption("configureMouse");
9328
- var value = option ? option(cm, repeat, event) : {};
9329
- if (value.unit == null) {
9330
- var rect = chromeOS ? event.shiftKey && event.metaKey : event.altKey;
9331
- value.unit = rect ? "rectangle" : repeat == "single" ? "char" : repeat == "double" ? "word" : "line";
9332
- }
9333
- if (value.extend == null || cm.doc.extend) { value.extend = cm.doc.extend || event.shiftKey; }
9334
- if (value.addNew == null) { value.addNew = mac ? event.metaKey : event.ctrlKey; }
9335
- if (value.moveOnDrag == null) { value.moveOnDrag = !(mac ? event.altKey : event.ctrlKey); }
9336
- return value
9337
- }
9338
 
9339
- function leftButtonDown(cm, pos, repeat, event) {
9340
- if (ie) { setTimeout(bind(ensureFocus, cm), 0); }
9341
- else { cm.curOp.focus = activeElt(); }
 
 
 
 
 
9342
 
9343
- var behavior = configureMouse(cm, repeat, event);
 
9344
 
9345
- var sel = cm.doc.sel, contained;
9346
- if (cm.options.dragDrop && dragAndDrop && !cm.isReadOnly() &&
9347
- repeat == "single" && (contained = sel.contains(pos)) > -1 &&
9348
- (cmp((contained = sel.ranges[contained]).from(), pos) < 0 || pos.xRel > 0) &&
9349
- (cmp(contained.to(), pos) > 0 || pos.xRel < 0))
9350
- { leftButtonStartDrag(cm, event, pos, behavior); }
9351
- else
9352
- { leftButtonSelect(cm, event, pos, behavior); }
9353
- }
9354
 
9355
- // Start a text drag. When it ends, see if any dragging actually
9356
- // happen, and treat as a click if it didn't.
9357
- function leftButtonStartDrag(cm, event, pos, behavior) {
9358
- var display = cm.display, moved = false;
9359
- var dragEnd = operation(cm, function (e) {
9360
- if (webkit) { display.scroller.draggable = false; }
9361
- cm.state.draggingText = false;
9362
- off(display.wrapper.ownerDocument, "mouseup", dragEnd);
9363
- off(display.wrapper.ownerDocument, "mousemove", mouseMove);
9364
- off(display.scroller, "dragstart", dragStart);
9365
- off(display.scroller, "drop", dragEnd);
9366
- if (!moved) {
9367
- e_preventDefault(e);
9368
- if (!behavior.addNew)
9369
- { extendSelection(cm.doc, pos, null, null, behavior.extend); }
9370
- // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081)
9371
- if (webkit || ie && ie_version == 9)
9372
- { setTimeout(function () {display.wrapper.ownerDocument.body.focus(); display.input.focus();}, 20); }
9373
  else
9374
- { display.input.focus(); }
 
 
 
 
 
 
9375
  }
9376
- });
9377
- var mouseMove = function(e2) {
9378
- moved = moved || Math.abs(event.clientX - e2.clientX) + Math.abs(event.clientY - e2.clientY) >= 10;
9379
- };
9380
- var dragStart = function () { return moved = true; };
9381
- // Let the drag handler handle this.
9382
- if (webkit) { display.scroller.draggable = true; }
9383
- cm.state.draggingText = dragEnd;
9384
- dragEnd.copy = !behavior.moveOnDrag;
9385
- // IE's approach to draggable
9386
- if (display.scroller.dragDrop) { display.scroller.dragDrop(); }
9387
- on(display.wrapper.ownerDocument, "mouseup", dragEnd);
9388
- on(display.wrapper.ownerDocument, "mousemove", mouseMove);
9389
- on(display.scroller, "dragstart", dragStart);
9390
- on(display.scroller, "drop", dragEnd);
9391
-
9392
- delayBlurEvent(cm);
9393
- setTimeout(function () { return display.input.focus(); }, 20);
9394
- }
9395
-
9396
- function rangeForUnit(cm, pos, unit) {
9397
- if (unit == "char") { return new Range(pos, pos) }
9398
- if (unit == "word") { return cm.findWordAt(pos) }
9399
- if (unit == "line") { return new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))) }
9400
- var result = unit(cm, pos);
9401
- return new Range(result.from, result.to)
9402
- }
9403
 
9404
- // Normal selection, as opposed to text dragging.
9405
- function leftButtonSelect(cm, event, start, behavior) {
9406
- var display = cm.display, doc = cm.doc;
9407
- e_preventDefault(event);
9408
 
9409
- var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges;
9410
- if (behavior.addNew && !behavior.extend) {
9411
- ourIndex = doc.sel.contains(start);
9412
- if (ourIndex > -1)
9413
- { ourRange = ranges[ourIndex]; }
9414
- else
9415
- { ourRange = new Range(start, start); }
9416
- } else {
9417
- ourRange = doc.sel.primary();
9418
- ourIndex = doc.sel.primIndex;
9419
- }
9420
-
9421
- if (behavior.unit == "rectangle") {
9422
- if (!behavior.addNew) { ourRange = new Range(start, start); }
9423
- start = posFromMouse(cm, event, true, true);
9424
- ourIndex = -1;
9425
- } else {
9426
- var range$$1 = rangeForUnit(cm, start, behavior.unit);
9427
- if (behavior.extend)
9428
- { ourRange = extendRange(ourRange, range$$1.anchor, range$$1.head, behavior.extend); }
9429
- else
9430
- { ourRange = range$$1; }
9431
- }
9432
-
9433
- if (!behavior.addNew) {
9434
- ourIndex = 0;
9435
- setSelection(doc, new Selection([ourRange], 0), sel_mouse);
9436
- startSel = doc.sel;
9437
- } else if (ourIndex == -1) {
9438
- ourIndex = ranges.length;
9439
- setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex),
9440
- {scroll: false, origin: "*mouse"});
9441
- } else if (ranges.length > 1 && ranges[ourIndex].empty() && behavior.unit == "char" && !behavior.extend) {
9442
- setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0),
9443
- {scroll: false, origin: "*mouse"});
9444
- startSel = doc.sel;
9445
- } else {
9446
- replaceOneSelection(doc, ourIndex, ourRange, sel_mouse);
9447
- }
9448
-
9449
- var lastPos = start;
9450
- function extendTo(pos) {
9451
- if (cmp(lastPos, pos) == 0) { return }
9452
- lastPos = pos;
9453
 
9454
- if (behavior.unit == "rectangle") {
9455
- var ranges = [], tabSize = cm.options.tabSize;
9456
- var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize);
9457
- var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize);
9458
- var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol);
9459
- for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line));
9460
- line <= end; line++) {
9461
- var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize);
9462
- if (left == right)
9463
- { ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))); }
9464
- else if (text.length > leftPos)
9465
- { ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))); }
9466
- }
9467
- if (!ranges.length) { ranges.push(new Range(start, start)); }
9468
- setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex),
9469
- {origin: "*mouse", scroll: false});
9470
- cm.scrollIntoView(pos);
9471
- } else {
9472
- var oldRange = ourRange;
9473
- var range$$1 = rangeForUnit(cm, pos, behavior.unit);
9474
- var anchor = oldRange.anchor, head;
9475
- if (cmp(range$$1.anchor, anchor) > 0) {
9476
- head = range$$1.head;
9477
- anchor = minPos(oldRange.from(), range$$1.anchor);
9478
- } else {
9479
- head = range$$1.anchor;
9480
- anchor = maxPos(oldRange.to(), range$$1.head);
9481
- }
9482
- var ranges$1 = startSel.ranges.slice(0);
9483
- ranges$1[ourIndex] = bidiSimplify(cm, new Range(clipPos(doc, anchor), head));
9484
- setSelection(doc, normalizeSelection(ranges$1, ourIndex), sel_mouse);
9485
- }
9486
- }
9487
-
9488
- var editorSize = display.wrapper.getBoundingClientRect();
9489
- // Used to ensure timeout re-tries don't fire when another extend
9490
- // happened in the meantime (clearTimeout isn't reliable -- at
9491
- // least on Chrome, the timeouts still happen even when cleared,
9492
- // if the clear happens after their scheduled firing time).
9493
- var counter = 0;
9494
-
9495
- function extend(e) {
9496
- var curCount = ++counter;
9497
- var cur = posFromMouse(cm, e, true, behavior.unit == "rectangle");
9498
- if (!cur) { return }
9499
- if (cmp(cur, lastPos) != 0) {
9500
- cm.curOp.focus = activeElt();
9501
- extendTo(cur);
9502
- var visible = visibleLines(display, doc);
9503
- if (cur.line >= visible.to || cur.line < visible.from)
9504
- { setTimeout(operation(cm, function () {if (counter == curCount) { extend(e); }}), 150); }
9505
- } else {
9506
- var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0;
9507
- if (outside) { setTimeout(operation(cm, function () {
9508
- if (counter != curCount) { return }
9509
- display.scroller.scrollTop += outside;
9510
- extend(e);
9511
- }), 50); }
9512
  }
9513
- }
9514
 
9515
- function done(e) {
9516
- cm.state.selectingText = false;
9517
- counter = Infinity;
9518
- e_preventDefault(e);
9519
- display.input.focus();
9520
- off(display.wrapper.ownerDocument, "mousemove", move);
9521
- off(display.wrapper.ownerDocument, "mouseup", up);
9522
- doc.history.lastSelOrigin = null;
9523
  }
9524
 
9525
- var move = operation(cm, function (e) {
9526
- if (e.buttons === 0 || !e_button(e)) { done(e); }
9527
- else { extend(e); }
9528
- });
9529
- var up = operation(cm, done);
9530
- cm.state.selectingText = up;
9531
- on(display.wrapper.ownerDocument, "mousemove", move);
9532
- on(display.wrapper.ownerDocument, "mouseup", up);
9533
- }
9534
 
9535
- // Used when mouse-selecting to adjust the anchor to the proper side
9536
- // of a bidi jump depending on the visual position of the head.
9537
- function bidiSimplify(cm, range$$1) {
9538
- var anchor = range$$1.anchor;
9539
- var head = range$$1.head;
9540
- var anchorLine = getLine(cm.doc, anchor.line);
9541
- if (cmp(anchor, head) == 0 && anchor.sticky == head.sticky) { return range$$1 }
9542
- var order = getOrder(anchorLine);
9543
- if (!order) { return range$$1 }
9544
- var index = getBidiPartAt(order, anchor.ch, anchor.sticky), part = order[index];
9545
- if (part.from != anchor.ch && part.to != anchor.ch) { return range$$1 }
9546
- var boundary = index + ((part.from == anchor.ch) == (part.level != 1) ? 0 : 1);
9547
- if (boundary == 0 || boundary == order.length) { return range$$1 }
9548
-
9549
- // Compute the relative visual position of the head compared to the
9550
- // anchor (<0 is to the left, >0 to the right)
9551
- var leftSide;
9552
- if (head.line != anchor.line) {
9553
- leftSide = (head.line - anchor.line) * (cm.doc.direction == "ltr" ? 1 : -1) > 0;
9554
- } else {
9555
- var headIndex = getBidiPartAt(order, head.ch, head.sticky);
9556
- var dir = headIndex - index || (head.ch - anchor.ch) * (part.level == 1 ? -1 : 1);
9557
- if (headIndex == boundary - 1 || headIndex == boundary)
9558
- { leftSide = dir < 0; }
9559
- else
9560
- { leftSide = dir > 0; }
1374
 
1375
  },{"./admin/field-helper.js":4,"./admin/fields-factory.js":5,"./admin/fields.js":6,"./admin/form-editor.js":7,"./admin/form-watcher.js":8,"./admin/notices":9}],12:[function(require,module,exports){
1376
  // CodeMirror, copyright (c) by Marijn Haverbeke and others
1377
+ // Distributed under an MIT license: https://codemirror.net/LICENSE
1378
 
1379
  /**
1380
  * Tag-closer extension for CodeMirror.
1551
 
1552
  },{"../../lib/codemirror":17,"../fold/xml-fold":15}],13:[function(require,module,exports){
1553
  // CodeMirror, copyright (c) by Marijn Haverbeke and others
1554
+ // Distributed under an MIT license: https://codemirror.net/LICENSE
1555
 
1556
  (function(mod) {
1557
  if (typeof exports == "object" && typeof module == "object") // CommonJS
1698
 
1699
  },{"../../lib/codemirror":17}],14:[function(require,module,exports){
1700
  // CodeMirror, copyright (c) by Marijn Haverbeke and others
1701
+ // Distributed under an MIT license: https://codemirror.net/LICENSE
1702
 
1703
  (function(mod) {
1704
  if (typeof exports == "object" && typeof module == "object") // CommonJS
1766
 
1767
  },{"../../lib/codemirror":17,"../fold/xml-fold":15}],15:[function(require,module,exports){
1768
  // CodeMirror, copyright (c) by Marijn Haverbeke and others
1769
+ // Distributed under an MIT license: https://codemirror.net/LICENSE
1770
 
1771
  (function(mod) {
1772
  if (typeof exports == "object" && typeof module == "object") // CommonJS
1952
 
1953
  },{"../../lib/codemirror":17}],16:[function(require,module,exports){
1954
  // CodeMirror, copyright (c) by Marijn Haverbeke and others
1955
+ // Distributed under an MIT license: https://codemirror.net/LICENSE
1956
 
1957
  (function(mod) {
1958
  if (typeof exports == "object" && typeof module == "object") // CommonJS
2026
 
2027
  },{"../../lib/codemirror":17}],17:[function(require,module,exports){
2028
  // CodeMirror, copyright (c) by Marijn Haverbeke and others
2029
+ // Distributed under an MIT license: https://codemirror.net/LICENSE
2030
 
2031
+ // This is CodeMirror (https://codemirror.net), a code editor
2032
  // implemented in JavaScript on top of the browser's DOM.
2033
  //
2034
  // You can find some technical background for some of the code below
2035
  // at http://marijnhaverbeke.nl/blog/#cm-internals .
2036
 
2037
  (function (global, factory) {
2038
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
2039
+ typeof define === 'function' && define.amd ? define(factory) :
2040
+ (global.CodeMirror = factory());
2041
  }(this, (function () { 'use strict';
2042
 
2043
+ // Kludges for bugs and behavior differences that can't be feature
2044
+ // detected are enabled based on userAgent etc sniffing.
2045
+ var userAgent = navigator.userAgent;
2046
+ var platform = navigator.platform;
2047
+
2048
+ var gecko = /gecko\/\d/i.test(userAgent);
2049
+ var ie_upto10 = /MSIE \d/.test(userAgent);
2050
+ var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent);
2051
+ var edge = /Edge\/(\d+)/.exec(userAgent);
2052
+ var ie = ie_upto10 || ie_11up || edge;
2053
+ var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : +(edge || ie_11up)[1]);
2054
+ var webkit = !edge && /WebKit\//.test(userAgent);
2055
+ var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent);
2056
+ var chrome = !edge && /Chrome\//.test(userAgent);
2057
+ var presto = /Opera\//.test(userAgent);
2058
+ var safari = /Apple Computer/.test(navigator.vendor);
2059
+ var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent);
2060
+ var phantom = /PhantomJS/.test(userAgent);
2061
+
2062
+ var ios = !edge && /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent);
2063
+ var android = /Android/.test(userAgent);
2064
+ // This is woefully incomplete. Suggestions for alternative methods welcome.
2065
+ var mobile = ios || android || /webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent);
2066
+ var mac = ios || /Mac/.test(platform);
2067
+ var chromeOS = /\bCrOS\b/.test(userAgent);
2068
+ var windows = /win/i.test(platform);
2069
+
2070
+ var presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/);
2071
+ if (presto_version) { presto_version = Number(presto_version[1]); }
2072
+ if (presto_version && presto_version >= 15) { presto = false; webkit = true; }
2073
+ // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
2074
+ var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11));
2075
+ var captureRightClick = gecko || (ie && ie_version >= 9);
2076
+
2077
+ function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") }
2078
+
2079
+ var rmClass = function(node, cls) {
2080
+ var current = node.className;
2081
+ var match = classTest(cls).exec(current);
2082
+ if (match) {
2083
+ var after = current.slice(match.index + match[0].length);
2084
+ node.className = current.slice(0, match.index) + (after ? match[1] + after : "");
2085
+ }
2086
+ };
 
 
 
 
 
 
2087
 
2088
+ function removeChildren(e) {
2089
+ for (var count = e.childNodes.length; count > 0; --count)
2090
+ { e.removeChild(e.firstChild); }
2091
+ return e
2092
+ }
2093
 
2094
+ function removeChildrenAndAdd(parent, e) {
2095
+ return removeChildren(parent).appendChild(e)
2096
+ }
 
 
 
 
 
 
 
 
 
 
 
2097
 
2098
+ function elt(tag, content, className, style) {
2099
+ var e = document.createElement(tag);
2100
+ if (className) { e.className = className; }
2101
+ if (style) { e.style.cssText = style; }
2102
+ if (typeof content == "string") { e.appendChild(document.createTextNode(content)); }
2103
+ else if (content) { for (var i = 0; i < content.length; ++i) { e.appendChild(content[i]); } }
2104
+ return e
2105
+ }
2106
+ // wrapper for elt, which removes the elt from the accessibility tree
2107
+ function eltP(tag, content, className, style) {
2108
+ var e = elt(tag, content, className, style);
2109
+ e.setAttribute("role", "presentation");
2110
+ return e
2111
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
2112
 
2113
+ var range;
2114
+ if (document.createRange) { range = function(node, start, end, endNode) {
2115
+ var r = document.createRange();
2116
+ r.setEnd(endNode || node, end);
2117
+ r.setStart(node, start);
2118
+ return r
2119
+ }; }
2120
+ else { range = function(node, start, end) {
2121
+ var r = document.body.createTextRange();
2122
+ try { r.moveToElementText(node.parentNode); }
2123
+ catch(e) { return r }
2124
+ r.collapse(true);
2125
+ r.moveEnd("character", end);
2126
+ r.moveStart("character", start);
2127
+ return r
2128
+ }; }
2129
 
2130
+ function contains(parent, child) {
2131
+ if (child.nodeType == 3) // Android browser always returns false when child is a textnode
2132
+ { child = child.parentNode; }
2133
+ if (parent.contains)
2134
+ { return parent.contains(child) }
2135
+ do {
2136
+ if (child.nodeType == 11) { child = child.host; }
2137
+ if (child == parent) { return true }
2138
+ } while (child = child.parentNode)
2139
+ }
2140
 
2141
+ function activeElt() {
2142
+ // IE and Edge may throw an "Unspecified Error" when accessing document.activeElement.
2143
+ // IE < 10 will throw when accessed while the page is loading or in an iframe.
2144
+ // IE > 9 and Edge will throw when accessed in an iframe if document.body is unavailable.
2145
+ var activeElement;
2146
+ try {
2147
+ activeElement = document.activeElement;
2148
+ } catch(e) {
2149
+ activeElement = document.body || null;
2150
+ }
2151
+ while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement)
2152
+ { activeElement = activeElement.shadowRoot.activeElement; }
2153
+ return activeElement
2154
+ }
2155
 
2156
+ function addClass(node, cls) {
2157
+ var current = node.className;
2158
+ if (!classTest(cls).test(current)) { node.className += (current ? " " : "") + cls; }
2159
+ }
2160
+ function joinClasses(a, b) {
2161
+ var as = a.split(" ");
2162
+ for (var i = 0; i < as.length; i++)
2163
+ { if (as[i] && !classTest(as[i]).test(b)) { b += " " + as[i]; } }
2164
+ return b
2165
+ }
2166
 
2167
+ var selectInput = function(node) { node.select(); };
2168
+ if (ios) // Mobile Safari apparently has a bug where select() is broken.
2169
+ { selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; }; }
2170
+ else if (ie) // Suppress mysterious IE10 errors
2171
+ { selectInput = function(node) { try { node.select(); } catch(_e) {} }; }
 
 
2172
 
2173
+ function bind(f) {
2174
+ var args = Array.prototype.slice.call(arguments, 1);
2175
+ return function(){return f.apply(null, args)}
 
 
 
 
 
 
 
 
 
 
 
2176
  }
 
 
 
 
 
 
 
2177
 
2178
+ function copyObj(obj, target, overwrite) {
2179
+ if (!target) { target = {}; }
2180
+ for (var prop in obj)
2181
+ { if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
2182
+ { target[prop] = obj[prop]; } }
2183
+ return target
2184
+ }
2185
 
2186
+ // Counts the column offset in a string, taking tabs into account.
2187
+ // Used mostly to find indentation.
2188
+ function countColumn(string, end, tabSize, startIndex, startValue) {
2189
+ if (end == null) {
2190
+ end = string.search(/[^\s\u00a0]/);
2191
+ if (end == -1) { end = string.length; }
2192
+ }
2193
+ for (var i = startIndex || 0, n = startValue || 0;;) {
2194
+ var nextTab = string.indexOf("\t", i);
2195
+ if (nextTab < 0 || nextTab >= end)
2196
+ { return n + (end - i) }
2197
+ n += nextTab - i;
2198
+ n += tabSize - (n % tabSize);
2199
+ i = nextTab + 1;
2200
+ }
 
 
 
 
 
 
 
 
 
 
2201
  }
 
2202
 
2203
+ var Delayed = function() {this.id = null;};
2204
+ Delayed.prototype.set = function (ms, f) {
2205
+ clearTimeout(this.id);
2206
+ this.id = setTimeout(f, ms);
2207
+ };
 
2208
 
2209
+ function indexOf(array, elt) {
2210
+ for (var i = 0; i < array.length; ++i)
2211
+ { if (array[i] == elt) { return i } }
2212
+ return -1
2213
+ }
2214
 
2215
+ // Number of pixels added to scroller and sizer to hide scrollbar
2216
+ var scrollerGap = 30;
 
 
 
2217
 
2218
+ // Returned or thrown by various protocols to signal 'I'm not
2219
+ // handling this'.
2220
+ var Pass = {toString: function(){return "CodeMirror.Pass"}};
 
 
2221
 
2222
+ // Reused option objects for setSelection & friends
2223
+ var sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"};
2224
 
2225
+ // The inverse of countColumn -- find the offset that corresponds to
2226
+ // a particular column.
2227
+ function findColumn(string, goal, tabSize) {
2228
+ for (var pos = 0, col = 0;;) {
2229
+ var nextTab = string.indexOf("\t", pos);
2230
+ if (nextTab == -1) { nextTab = string.length; }
2231
+ var skipped = nextTab - pos;
2232
+ if (nextTab == string.length || col + skipped >= goal)
2233
+ { return pos + Math.min(skipped, goal - col) }
2234
+ col += nextTab - pos;
2235
+ col += tabSize - (col % tabSize);
2236
+ pos = nextTab + 1;
2237
+ if (col >= goal) { return pos }
2238
+ }
2239
  }
 
 
 
2240
 
2241
+ var spaceStrs = [""];
2242
+ function spaceStr(n) {
2243
+ while (spaceStrs.length <= n)
2244
+ { spaceStrs.push(lst(spaceStrs) + " "); }
2245
+ return spaceStrs[n]
2246
+ }
 
 
 
 
2247
 
2248
+ function lst(arr) { return arr[arr.length-1] }
 
 
 
2249
 
2250
+ function map(array, f) {
2251
+ var out = [];
2252
+ for (var i = 0; i < array.length; i++) { out[i] = f(array[i], i); }
2253
+ return out
2254
+ }
 
 
 
 
 
 
 
 
2255
 
2256
+ function insertSorted(array, value, score) {
2257
+ var pos = 0, priority = score(value);
2258
+ while (pos < array.length && score(array[pos]) <= priority) { pos++; }
2259
+ array.splice(pos, 0, value);
 
 
 
 
 
 
 
 
 
2260
  }
 
2261
 
2262
+ function nothing() {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2263
 
2264
+ function createObj(base, props) {
2265
+ var inst;
2266
+ if (Object.create) {
2267
+ inst = Object.create(base);
2268
+ } else {
2269
+ nothing.prototype = base;
2270
+ inst = new nothing();
 
 
 
2271
  }
2272
+ if (props) { copyObj(props, inst); }
2273
+ return inst
2274
  }
 
 
2275
 
2276
+ var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
2277
+ function isWordCharBasic(ch) {
2278
+ return /\w/.test(ch) || ch > "\x80" &&
2279
+ (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch))
2280
+ }
2281
+ function isWordChar(ch, helper) {
2282
+ if (!helper) { return isWordCharBasic(ch) }
2283
+ if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) { return true }
2284
+ return helper.test(ch)
2285
+ }
 
 
 
 
 
 
 
 
 
2286
 
2287
+ function isEmpty(obj) {
2288
+ for (var n in obj) { if (obj.hasOwnProperty(n) && obj[n]) { return false } }
2289
+ return true
2290
+ }
 
 
2291
 
2292
+ // Extending unicode characters. A series of a non-extending char +
2293
+ // any number of extending chars is treated as a single unit as far
2294
+ // as editing and measuring is concerned. This is not fully correct,
2295
+ // since some scripts/fonts/browsers also treat other configurations
2296
+ // of code points as a group.
2297
+ var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;
2298
+ function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch) }
2299
+
2300
+ // Returns a number from the range [`0`; `str.length`] unless `pos` is outside that range.
2301
+ function skipExtendingChars(str, pos, dir) {
2302
+ while ((dir < 0 ? pos > 0 : pos < str.length) && isExtendingChar(str.charAt(pos))) { pos += dir; }
2303
+ return pos
2304
  }
 
 
2305
 
2306
+ // Returns the value from the range [`from`; `to`] that satisfies
2307
+ // `pred` and is closest to `from`. Assumes that at least `to`
2308
+ // satisfies `pred`. Supports `from` being greater than `to`.
2309
+ function findFirst(pred, from, to) {
2310
+ // At any point we are certain `to` satisfies `pred`, don't know
2311
+ // whether `from` does.
2312
+ var dir = from > to ? -1 : 1;
2313
+ for (;;) {
2314
+ if (from == to) { return from }
2315
+ var midF = (from + to) / 2, mid = dir < 0 ? Math.ceil(midF) : Math.floor(midF);
2316
+ if (mid == from) { return pred(mid) ? from : to }
2317
+ if (pred(mid)) { to = mid; }
2318
+ else { from = mid + dir; }
2319
+ }
2320
+ }
2321
+
2322
+ // The display handles the DOM integration, both for input reading
2323
+ // and content drawing. It holds references to DOM nodes and
2324
+ // display-related state.
2325
+
2326
+ function Display(place, doc, input) {
2327
+ var d = this;
2328
+ this.input = input;
2329
+
2330
+ // Covers bottom-right square when both scrollbars are present.
2331
+ d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
2332
+ d.scrollbarFiller.setAttribute("cm-not-content", "true");
2333
+ // Covers bottom of gutter when coverGutterNextToScrollbar is on
2334
+ // and h scrollbar is present.
2335
+ d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
2336
+ d.gutterFiller.setAttribute("cm-not-content", "true");
2337
+ // Will contain the actual code, positioned to cover the viewport.
2338
+ d.lineDiv = eltP("div", null, "CodeMirror-code");
2339
+ // Elements are added to these to represent selection and cursors.
2340
+ d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
2341
+ d.cursorDiv = elt("div", null, "CodeMirror-cursors");
2342
+ // A visibility: hidden element used to find the size of things.
2343
+ d.measure = elt("div", null, "CodeMirror-measure");
2344
+ // When lines outside of the viewport are measured, they are drawn in this.
2345
+ d.lineMeasure = elt("div", null, "CodeMirror-measure");
2346
+ // Wraps everything that needs to exist inside the vertically-padded coordinate system
2347
+ d.lineSpace = eltP("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],
2348
+ null, "position: relative; outline: none");
2349
+ var lines = eltP("div", [d.lineSpace], "CodeMirror-lines");
2350
+ // Moved around its parent to cover visible view.
2351
+ d.mover = elt("div", [lines], null, "position: relative");
2352
+ // Set to the height of the document, allowing scrolling.
2353
+ d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
2354
+ d.sizerWidth = null;
2355
+ // Behavior of elts with overflow: auto and padding is
2356
+ // inconsistent across browsers. This is used to ensure the
2357
+ // scrollable area is big enough.
2358
+ d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;");
2359
+ // Will contain the gutters, if any.
2360
+ d.gutters = elt("div", null, "CodeMirror-gutters");
2361
+ d.lineGutter = null;
2362
+ // Actual scrollable element.
2363
+ d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
2364
+ d.scroller.setAttribute("tabIndex", "-1");
2365
+ // The element in which the editor lives.
2366
+ d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
2367
+
2368
+ // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)
2369
+ if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
2370
+ if (!webkit && !(gecko && mobile)) { d.scroller.draggable = true; }
2371
+
2372
+ if (place) {
2373
+ if (place.appendChild) { place.appendChild(d.wrapper); }
2374
+ else { place(d.wrapper); }
2375
+ }
2376
+
2377
+ // Current rendered range (may be bigger than the view window).
2378
+ d.viewFrom = d.viewTo = doc.first;
2379
+ d.reportedViewFrom = d.reportedViewTo = doc.first;
2380
+ // Information about the rendered lines.
2381
+ d.view = [];
2382
+ d.renderedView = null;
2383
+ // Holds info about a single rendered line when it was rendered
2384
+ // for measurement, while not in view.
2385
+ d.externalMeasured = null;
2386
+ // Empty space (in pixels) above the view
2387
+ d.viewOffset = 0;
2388
+ d.lastWrapHeight = d.lastWrapWidth = 0;
2389
+ d.updateLineNumbers = null;
2390
+
2391
+ d.nativeBarWidth = d.barHeight = d.barWidth = 0;
2392
+ d.scrollbarsClipped = false;
2393
+
2394
+ // Used to only resize the line number gutter when necessary (when
2395
+ // the amount of lines crosses a boundary that makes its width change)
2396
+ d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
2397
+ // Set to true when a non-horizontal-scrolling line widget is
2398
+ // added. As an optimization, line widget aligning is skipped when
2399
+ // this is false.
2400
+ d.alignWidgets = false;
2401
+
2402
+ d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
2403
+
2404
+ // Tracks the maximum line length so that the horizontal scrollbar
2405
+ // can be kept static when scrolling.
2406
+ d.maxLine = null;
2407
+ d.maxLineLength = 0;
2408
+ d.maxLineChanged = false;
2409
+
2410
+ // Used for measuring wheel scrolling granularity
2411
+ d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
2412
+
2413
+ // True when shift is held down.
2414
+ d.shift = false;
2415
+
2416
+ // Used to track whether anything happened since the context menu
2417
+ // was opened.
2418
+ d.selForContextMenu = null;
2419
+
2420
+ d.activeTouch = null;
2421
+
2422
+ input.init(d);
2423
+ }
2424
+
2425
+ // Find the line object corresponding to the given line number.
2426
+ function getLine(doc, n) {
2427
+ n -= doc.first;
2428
+ if (n < 0 || n >= doc.size) { throw new Error("There is no line " + (n + doc.first) + " in the document.") }
2429
+ var chunk = doc;
2430
+ while (!chunk.lines) {
2431
+ for (var i = 0;; ++i) {
2432
+ var child = chunk.children[i], sz = child.chunkSize();
2433
+ if (n < sz) { chunk = child; break }
2434
+ n -= sz;
2435
+ }
2436
+ }
2437
+ return chunk.lines[n]
2438
+ }
2439
+
2440
+ // Get the part of a document between two positions, as an array of
2441
+ // strings.
2442
+ function getBetween(doc, start, end) {
2443
+ var out = [], n = start.line;
2444
+ doc.iter(start.line, end.line + 1, function (line) {
2445
+ var text = line.text;
2446
+ if (n == end.line) { text = text.slice(0, end.ch); }
2447
+ if (n == start.line) { text = text.slice(start.ch); }
2448
+ out.push(text);
2449
+ ++n;
2450
+ });
2451
+ return out
2452
+ }
2453
+ // Get the lines between from and to, as array of strings.
2454
+ function getLines(doc, from, to) {
2455
+ var out = [];
2456
+ doc.iter(from, to, function (line) { out.push(line.text); }); // iter aborts when callback returns truthy value
2457
+ return out
2458
+ }
2459
 
2460
+ // Update the height of a line, propagating the height change
2461
+ // upwards to parent nodes.
2462
+ function updateLineHeight(line, height) {
2463
+ var diff = height - line.height;
2464
+ if (diff) { for (var n = line; n; n = n.parent) { n.height += diff; } }
2465
+ }
2466
 
2467
+ // Given a line object, find its line number by walking up through
2468
+ // its parent links.
2469
+ function lineNo(line) {
2470
+ if (line.parent == null) { return null }
2471
+ var cur = line.parent, no = indexOf(cur.lines, line);
2472
+ for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
2473
+ for (var i = 0;; ++i) {
2474
+ if (chunk.children[i] == cur) { break }
2475
+ no += chunk.children[i].chunkSize();
2476
+ }
2477
+ }
2478
+ return no + cur.first
2479
+ }
2480
 
2481
+ // Find the line at the given vertical position, using the height
2482
+ // information in the document tree.
2483
+ function lineAtHeight(chunk, h) {
2484
+ var n = chunk.first;
2485
+ outer: do {
2486
+ for (var i$1 = 0; i$1 < chunk.children.length; ++i$1) {
2487
+ var child = chunk.children[i$1], ch = child.height;
2488
+ if (h < ch) { chunk = child; continue outer }
2489
+ h -= ch;
2490
+ n += child.chunkSize();
2491
+ }
2492
+ return n
2493
+ } while (!chunk.lines)
2494
+ var i = 0;
2495
+ for (; i < chunk.lines.length; ++i) {
2496
+ var line = chunk.lines[i], lh = line.height;
2497
+ if (h < lh) { break }
2498
+ h -= lh;
2499
+ }
2500
+ return n + i
2501
+ }
2502
 
2503
+ function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size}
 
 
 
 
2504
 
2505
+ function lineNumberFor(options, i) {
2506
+ return String(options.lineNumberFormatter(i + options.firstLineNumber))
2507
+ }
2508
 
2509
+ // A Pos instance represents a position within the text.
2510
+ function Pos(line, ch, sticky) {
2511
+ if ( sticky === void 0 ) sticky = null;
2512
 
2513
+ if (!(this instanceof Pos)) { return new Pos(line, ch, sticky) }
2514
+ this.line = line;
2515
+ this.ch = ch;
2516
+ this.sticky = sticky;
2517
+ }
2518
 
2519
+ // Compare two positions, return 0 if they are the same, a negative
2520
+ // number when a is less, and a positive number otherwise.
2521
+ function cmp(a, b) { return a.line - b.line || a.ch - b.ch }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2522
 
2523
+ function equalCursorPos(a, b) { return a.sticky == b.sticky && cmp(a, b) == 0 }
 
 
2524
 
2525
+ function copyPos(x) {return Pos(x.line, x.ch)}
2526
+ function maxPos(a, b) { return cmp(a, b) < 0 ? b : a }
2527
+ function minPos(a, b) { return cmp(a, b) < 0 ? a : b }
2528
 
2529
+ // Most of the external API clips given positions to make sure they
2530
+ // actually exist within the document.
2531
+ function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1))}
2532
+ function clipPos(doc, pos) {
2533
+ if (pos.line < doc.first) { return Pos(doc.first, 0) }
2534
+ var last = doc.first + doc.size - 1;
2535
+ if (pos.line > last) { return Pos(last, getLine(doc, last).text.length) }
2536
+ return clipToLen(pos, getLine(doc, pos.line).text.length)
2537
+ }
2538
+ function clipToLen(pos, linelen) {
2539
+ var ch = pos.ch;
2540
+ if (ch == null || ch > linelen) { return Pos(pos.line, linelen) }
2541
+ else if (ch < 0) { return Pos(pos.line, 0) }
2542
+ else { return pos }
2543
+ }
2544
+ function clipPosArray(doc, array) {
2545
+ var out = [];
2546
+ for (var i = 0; i < array.length; i++) { out[i] = clipPos(doc, array[i]); }
2547
+ return out
2548
+ }
2549
 
2550
+ // Optimize some code when these features are not used.
2551
+ var sawReadOnlySpans = false, sawCollapsedSpans = false;
2552
 
2553
+ function seeReadOnlySpans() {
2554
+ sawReadOnlySpans = true;
2555
+ }
 
2556
 
2557
+ function seeCollapsedSpans() {
2558
+ sawCollapsedSpans = true;
2559
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2560
 
2561
+ // TEXTMARKER SPANS
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2562
 
2563
+ function MarkedSpan(marker, from, to) {
2564
+ this.marker = marker;
2565
+ this.from = from; this.to = to;
2566
+ }
2567
+
2568
+ // Search an array of spans for a span matching the given marker.
2569
+ function getMarkedSpanFor(spans, marker) {
2570
+ if (spans) { for (var i = 0; i < spans.length; ++i) {
2571
+ var span = spans[i];
2572
+ if (span.marker == marker) { return span }
2573
+ } }
2574
+ }
2575
+ // Remove a span from an array, returning undefined if no spans are
2576
+ // left (we don't store arrays for lines without spans).
2577
+ function removeMarkedSpan(spans, span) {
2578
+ var r;
2579
+ for (var i = 0; i < spans.length; ++i)
2580
+ { if (spans[i] != span) { (r || (r = [])).push(spans[i]); } }
2581
+ return r
2582
+ }
2583
+ // Add a span to a line.
2584
+ function addMarkedSpan(line, span) {
2585
+ line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
2586
+ span.marker.attachLine(line);
2587
+ }
2588
+
2589
+ // Used for the algorithm that adjusts markers for a change in the
2590
+ // document. These functions cut an array of spans at a given
2591
+ // character position, returning an array of remaining chunks (or
2592
+ // undefined if nothing remains).
2593
+ function markedSpansBefore(old, startCh, isInsert) {
2594
+ var nw;
2595
+ if (old) { for (var i = 0; i < old.length; ++i) {
2596
+ var span = old[i], marker = span.marker;
2597
+ var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
2598
+ if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) {
2599
+ var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh)
2600
+ ;(nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to));
2601
+ }
2602
+ } }
2603
+ return nw
2604
+ }
2605
+ function markedSpansAfter(old, endCh, isInsert) {
2606
+ var nw;
2607
+ if (old) { for (var i = 0; i < old.length; ++i) {
2608
+ var span = old[i], marker = span.marker;
2609
+ var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
2610
+ if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) {
2611
+ var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh)
2612
+ ;(nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh,
2613
+ span.to == null ? null : span.to - endCh));
2614
+ }
2615
+ } }
2616
+ return nw
2617
+ }
2618
+
2619
+ // Given a change object, compute the new set of marker spans that
2620
+ // cover the line in which the change took place. Removes spans
2621
+ // entirely within the change, reconnects spans belonging to the
2622
+ // same marker that appear on both sides of the change, and cuts off
2623
+ // spans partially within the change. Returns an array of span
2624
+ // arrays with one element for each line in (after) the change.
2625
+ function stretchSpansOverChange(doc, change) {
2626
+ if (change.full) { return null }
2627
+ var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
2628
+ var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
2629
+ if (!oldFirst && !oldLast) { return null }
2630
+
2631
+ var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0;
2632
+ // Get the spans that 'stick out' on both sides
2633
+ var first = markedSpansBefore(oldFirst, startCh, isInsert);
2634
+ var last = markedSpansAfter(oldLast, endCh, isInsert);
2635
+
2636
+ // Next, merge those two ends
2637
+ var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
2638
+ if (first) {
2639
+ // Fix up .to properties of first
2640
+ for (var i = 0; i < first.length; ++i) {
2641
+ var span = first[i];
2642
+ if (span.to == null) {
2643
+ var found = getMarkedSpanFor(last, span.marker);
2644
+ if (!found) { span.to = startCh; }
2645
+ else if (sameLine) { span.to = found.to == null ? null : found.to + offset; }
2646
+ }
2647
+ }
2648
+ }
2649
+ if (last) {
2650
+ // Fix up .from in last (or move them into first in case of sameLine)
2651
+ for (var i$1 = 0; i$1 < last.length; ++i$1) {
2652
+ var span$1 = last[i$1];
2653
+ if (span$1.to != null) { span$1.to += offset; }
2654
+ if (span$1.from == null) {
2655
+ var found$1 = getMarkedSpanFor(first, span$1.marker);
2656
+ if (!found$1) {
2657
+ span$1.from = offset;
2658
+ if (sameLine) { (first || (first = [])).push(span$1); }
2659
+ }
2660
+ } else {
2661
+ span$1.from += offset;
2662
  if (sameLine) { (first || (first = [])).push(span$1); }
2663
  }
 
 
 
2664
  }
2665
  }
2666
+ // Make sure we didn't create any zero-length spans
2667
+ if (first) { first = clearEmptySpans(first); }
2668
+ if (last && last != first) { last = clearEmptySpans(last); }
2669
+
2670
+ var newMarkers = [first];
2671
+ if (!sameLine) {
2672
+ // Fill gap with whole-line-spans
2673
+ var gap = change.text.length - 2, gapMarkers;
2674
+ if (gap > 0 && first)
2675
+ { for (var i$2 = 0; i$2 < first.length; ++i$2)
2676
+ { if (first[i$2].to == null)
2677
+ { (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i$2].marker, null, null)); } } }
2678
+ for (var i$3 = 0; i$3 < gap; ++i$3)
2679
+ { newMarkers.push(gapMarkers); }
2680
+ newMarkers.push(last);
2681
+ }
2682
+ return newMarkers
2683
  }
 
 
 
2684
 
2685
+ // Remove spans that are empty and don't have a clearWhenEmpty
2686
+ // option of false.
2687
+ function clearEmptySpans(spans) {
2688
+ for (var i = 0; i < spans.length; ++i) {
2689
+ var span = spans[i];
2690
+ if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false)
2691
+ { spans.splice(i--, 1); }
2692
+ }
2693
+ if (!spans.length) { return null }
2694
+ return spans
 
2695
  }
 
 
2696
 
2697
+ // Used to 'clip' out readOnly ranges when making a change.
2698
+ function removeReadOnlyRanges(doc, from, to) {
2699
+ var markers = null;
2700
+ doc.iter(from.line, to.line + 1, function (line) {
2701
+ if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) {
2702
+ var mark = line.markedSpans[i].marker;
2703
+ if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))
2704
+ { (markers || (markers = [])).push(mark); }
2705
+ } }
2706
+ });
2707
+ if (!markers) { return null }
2708
+ var parts = [{from: from, to: to}];
2709
+ for (var i = 0; i < markers.length; ++i) {
2710
+ var mk = markers[i], m = mk.find(0);
2711
+ for (var j = 0; j < parts.length; ++j) {
2712
+ var p = parts[j];
2713
+ if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) { continue }
2714
+ var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to);
2715
+ if (dfrom < 0 || !mk.inclusiveLeft && !dfrom)
2716
+ { newParts.push({from: p.from, to: m.from}); }
2717
+ if (dto > 0 || !mk.inclusiveRight && !dto)
2718
+ { newParts.push({from: m.to, to: p.to}); }
2719
+ parts.splice.apply(parts, newParts);
2720
+ j += newParts.length - 3;
2721
+ }
2722
+ }
2723
+ return parts
2724
  }
 
 
 
2725
 
2726
+ // Connect or disconnect spans from a line.
2727
+ function detachMarkedSpans(line) {
2728
+ var spans = line.markedSpans;
2729
+ if (!spans) { return }
2730
+ for (var i = 0; i < spans.length; ++i)
2731
+ { spans[i].marker.detachLine(line); }
2732
+ line.markedSpans = null;
2733
+ }
2734
+ function attachMarkedSpans(line, spans) {
2735
+ if (!spans) { return }
2736
+ for (var i = 0; i < spans.length; ++i)
2737
+ { spans[i].marker.attachLine(line); }
2738
+ line.markedSpans = spans;
2739
+ }
2740
+
2741
+ // Helpers used when computing which overlapping collapsed span
2742
+ // counts as the larger one.
2743
+ function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0 }
2744
+ function extraRight(marker) { return marker.inclusiveRight ? 1 : 0 }
2745
+
2746
+ // Returns a number indicating which of two overlapping collapsed
2747
+ // spans is larger (and thus includes the other). Falls back to
2748
+ // comparing ids when the spans cover exactly the same range.
2749
+ function compareCollapsedMarkers(a, b) {
2750
+ var lenDiff = a.lines.length - b.lines.length;
2751
+ if (lenDiff != 0) { return lenDiff }
2752
+ var aPos = a.find(), bPos = b.find();
2753
+ var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b);
2754
+ if (fromCmp) { return -fromCmp }
2755
+ var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b);
2756
+ if (toCmp) { return toCmp }
2757
+ return b.id - a.id
2758
+ }
2759
+
2760
+ // Find out whether a line ends or starts in a collapsed span. If
2761
+ // so, return the marker for that span.
2762
+ function collapsedSpanAtSide(line, start) {
2763
+ var sps = sawCollapsedSpans && line.markedSpans, found;
2764
+ if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) {
2765
+ sp = sps[i];
2766
+ if (sp.marker.collapsed && (start ? sp.from : sp.to) == null &&
2767
+ (!found || compareCollapsedMarkers(found, sp.marker) < 0))
2768
+ { found = sp.marker; }
2769
  } }
2770
+ return found
2771
+ }
2772
+ function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true) }
2773
+ function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false) }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2774
 
2775
+ function collapsedSpanAround(line, ch) {
2776
+ var sps = sawCollapsedSpans && line.markedSpans, found;
2777
+ if (sps) { for (var i = 0; i < sps.length; ++i) {
2778
+ var sp = sps[i];
2779
+ if (sp.marker.collapsed && (sp.from == null || sp.from < ch) && (sp.to == null || sp.to > ch) &&
2780
+ (!found || compareCollapsedMarkers(found, sp.marker) < 0)) { found = sp.marker; }
2781
+ } }
2782
+ return found
2783
+ }
 
 
 
 
 
 
 
 
 
2784
 
2785
+ // Test whether there exists a collapsed span that partially
2786
+ // overlaps (covers the start or end, but not both) of a new span.
2787
+ // Such overlap is not allowed.
2788
+ function conflictingCollapsedRange(doc, lineNo$$1, from, to, marker) {
2789
+ var line = getLine(doc, lineNo$$1);
2790
+ var sps = sawCollapsedSpans && line.markedSpans;
2791
+ if (sps) { for (var i = 0; i < sps.length; ++i) {
2792
+ var sp = sps[i];
2793
+ if (!sp.marker.collapsed) { continue }
2794
+ var found = sp.marker.find(0);
2795
+ var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker);
2796
+ var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker);
2797
+ if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) { continue }
2798
+ if (fromCmp <= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.to, from) >= 0 : cmp(found.to, from) > 0) ||
2799
+ fromCmp >= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.from, to) <= 0 : cmp(found.from, to) < 0))
2800
+ { return true }
2801
+ } }
2802
+ }
 
 
 
 
 
 
2803
 
2804
+ // A visual line is a line as drawn on the screen. Folding, for
2805
+ // example, can cause multiple logical lines to appear on the same
2806
+ // visual line. This finds the start of the visual line that the
2807
+ // given line is part of (usually that is the line itself).
2808
+ function visualLine(line) {
2809
+ var merged;
2810
+ while (merged = collapsedSpanAtStart(line))
2811
+ { line = merged.find(-1, true).line; }
2812
+ return line
2813
+ }
2814
+
2815
+ function visualLineEnd(line) {
2816
+ var merged;
2817
+ while (merged = collapsedSpanAtEnd(line))
2818
+ { line = merged.find(1, true).line; }
2819
+ return line
2820
+ }
2821
+
2822
+ // Returns an array of logical lines that continue the visual line
2823
+ // started by the argument, or undefined if there are no such lines.
2824
+ function visualLineContinued(line) {
2825
+ var merged, lines;
2826
+ while (merged = collapsedSpanAtEnd(line)) {
2827
+ line = merged.find(1, true).line
2828
+ ;(lines || (lines = [])).push(line);
2829
+ }
2830
+ return lines
2831
+ }
2832
+
2833
+ // Get the line number of the start of the visual line that the
2834
+ // given line number is part of.
2835
+ function visualLineNo(doc, lineN) {
2836
+ var line = getLine(doc, lineN), vis = visualLine(line);
2837
+ if (line == vis) { return lineN }
2838
+ return lineNo(vis)
2839
+ }
2840
+
2841
+ // Get the line number of the start of the next visual line after
2842
+ // the given line.
2843
+ function visualLineEndNo(doc, lineN) {
2844
+ if (lineN > doc.lastLine()) { return lineN }
2845
+ var line = getLine(doc, lineN), merged;
2846
+ if (!lineIsHidden(doc, line)) { return lineN }
2847
+ while (merged = collapsedSpanAtEnd(line))
2848
+ { line = merged.find(1, true).line; }
2849
+ return lineNo(line) + 1
2850
+ }
2851
+
2852
+ // Compute whether a line is hidden. Lines count as hidden when they
2853
+ // are part of a visual line that starts with another line, or when
2854
+ // they are entirely covered by collapsed, non-widget span.
2855
+ function lineIsHidden(doc, line) {
2856
+ var sps = sawCollapsedSpans && line.markedSpans;
2857
+ if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) {
2858
+ sp = sps[i];
2859
+ if (!sp.marker.collapsed) { continue }
2860
+ if (sp.from == null) { return true }
2861
+ if (sp.marker.widgetNode) { continue }
2862
+ if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))
2863
+ { return true }
2864
+ } }
2865
+ }
2866
+ function lineIsHiddenInner(doc, line, span) {
2867
+ if (span.to == null) {
2868
+ var end = span.marker.find(1, true);
2869
+ return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker))
2870
+ }
2871
+ if (span.marker.inclusiveRight && span.to == line.text.length)
2872
  { return true }
2873
+ for (var sp = (void 0), i = 0; i < line.markedSpans.length; ++i) {
2874
+ sp = line.markedSpans[i];
2875
+ if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to &&
2876
+ (sp.to == null || sp.to != span.from) &&
2877
+ (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
2878
+ lineIsHiddenInner(doc, line, sp)) { return true }
2879
+ }
2880
+ }
2881
+
2882
+ // Find the height above the given line.
2883
+ function heightAtLine(lineObj) {
2884
+ lineObj = visualLine(lineObj);
2885
+
2886
+ var h = 0, chunk = lineObj.parent;
2887
+ for (var i = 0; i < chunk.lines.length; ++i) {
2888
+ var line = chunk.lines[i];
2889
+ if (line == lineObj) { break }
2890
+ else { h += line.height; }
2891
+ }
2892
+ for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {
2893
+ for (var i$1 = 0; i$1 < p.children.length; ++i$1) {
2894
+ var cur = p.children[i$1];
2895
+ if (cur == chunk) { break }
2896
+ else { h += cur.height; }
2897
+ }
2898
+ }
2899
+ return h
2900
+ }
2901
+
2902
+ // Compute the character length of a line, taking into account
2903
+ // collapsed ranges (see markText) that might hide parts, and join
2904
+ // other lines onto it.
2905
+ function lineLength(line) {
2906
+ if (line.height == 0) { return 0 }
2907
+ var len = line.text.length, merged, cur = line;
2908
+ while (merged = collapsedSpanAtStart(cur)) {
2909
+ var found = merged.find(0, true);
2910
+ cur = found.from.line;
2911
+ len += found.from.ch - found.to.ch;
2912
+ }
2913
+ cur = line;
2914
+ while (merged = collapsedSpanAtEnd(cur)) {
2915
+ var found$1 = merged.find(0, true);
2916
+ len -= cur.text.length - found$1.from.ch;
2917
+ cur = found$1.to.line;
2918
+ len += cur.text.length - found$1.to.ch;
2919
+ }
2920
+ return len
2921
+ }
2922
+
2923
+ // Find the longest line in the document.
2924
+ function findMaxLine(cm) {
2925
+ var d = cm.display, doc = cm.doc;
2926
+ d.maxLine = getLine(doc, doc.first);
2927
+ d.maxLineLength = lineLength(d.maxLine);
2928
+ d.maxLineChanged = true;
2929
+ doc.iter(function (line) {
2930
+ var len = lineLength(line);
2931
+ if (len > d.maxLineLength) {
2932
+ d.maxLineLength = len;
2933
+ d.maxLine = line;
2934
+ }
2935
+ });
2936
  }
 
 
 
 
 
 
 
 
 
 
2937
 
2938
+ // BIDI HELPERS
2939
+
2940
+ function iterateBidiSections(order, from, to, f) {
2941
+ if (!order) { return f(from, to, "ltr", 0) }
2942
+ var found = false;
2943
+ for (var i = 0; i < order.length; ++i) {
2944
+ var part = order[i];
2945
+ if (part.from < to && part.to > from || from == to && part.to == from) {
2946
+ f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr", i);
2947
+ found = true;
2948
+ }
2949
+ }
2950
+ if (!found) { f(from, to, "ltr"); }
2951
+ }
2952
+
2953
+ var bidiOther = null;
2954
+ function getBidiPartAt(order, ch, sticky) {
2955
+ var found;
2956
+ bidiOther = null;
2957
+ for (var i = 0; i < order.length; ++i) {
2958
+ var cur = order[i];
2959
+ if (cur.from < ch && cur.to > ch) { return i }
2960
+ if (cur.to == ch) {
2961
+ if (cur.from != cur.to && sticky == "before") { found = i; }
2962
+ else { bidiOther = i; }
2963
+ }
2964
+ if (cur.from == ch) {
2965
+ if (cur.from != cur.to && sticky != "before") { found = i; }
2966
+ else { bidiOther = i; }
2967
+ }
2968
+ }
2969
+ return found != null ? found : bidiOther
2970
+ }
2971
+
2972
+ // Bidirectional ordering algorithm
2973
+ // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm
2974
+ // that this (partially) implements.
2975
+
2976
+ // One-char codes used for character types:
2977
+ // L (L): Left-to-Right
2978
+ // R (R): Right-to-Left
2979
+ // r (AL): Right-to-Left Arabic
2980
+ // 1 (EN): European Number
2981
+ // + (ES): European Number Separator
2982
+ // % (ET): European Number Terminator
2983
+ // n (AN): Arabic Number
2984
+ // , (CS): Common Number Separator
2985
+ // m (NSM): Non-Spacing Mark
2986
+ // b (BN): Boundary Neutral
2987
+ // s (B): Paragraph Separator
2988
+ // t (S): Segment Separator
2989
+ // w (WS): Whitespace
2990
+ // N (ON): Other Neutrals
2991
+
2992
+ // Returns null if characters are ordered as they appear
2993
+ // (left-to-right), or an array of sections ({from, to, level}
2994
+ // objects) in the order in which they occur visually.
2995
+ var bidiOrdering = (function() {
2996
+ // Character types for codepoints 0 to 0xff
2997
+ var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN";
2998
+ // Character types for codepoints 0x600 to 0x6f9
2999
+ var arabicTypes = "nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111";
3000
+ function charType(code) {
3001
+ if (code <= 0xf7) { return lowTypes.charAt(code) }
3002
+ else if (0x590 <= code && code <= 0x5f4) { return "R" }
3003
+ else if (0x600 <= code && code <= 0x6f9) { return arabicTypes.charAt(code - 0x600) }
3004
+ else if (0x6ee <= code && code <= 0x8ac) { return "r" }
3005
+ else if (0x2000 <= code && code <= 0x200b) { return "w" }
3006
+ else if (code == 0x200c) { return "b" }
3007
+ else { return "L" }
3008
+ }
3009
+
3010
+ var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
3011
+ var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;
3012
+
3013
+ function BidiSpan(level, from, to) {
3014
+ this.level = level;
3015
+ this.from = from; this.to = to;
3016
+ }
3017
+
3018
+ return function(str, direction) {
3019
+ var outerType = direction == "ltr" ? "L" : "R";
3020
+
3021
+ if (str.length == 0 || direction == "ltr" && !bidiRE.test(str)) { return false }
3022
+ var len = str.length, types = [];
3023
+ for (var i = 0; i < len; ++i)
3024
+ { types.push(charType(str.charCodeAt(i))); }
3025
+
3026
+ // W1. Examine each non-spacing mark (NSM) in the level run, and
3027
+ // change the type of the NSM to the type of the previous
3028
+ // character. If the NSM is at the start of the level run, it will
3029
+ // get the type of sor.
3030
+ for (var i$1 = 0, prev = outerType; i$1 < len; ++i$1) {
3031
+ var type = types[i$1];
3032
+ if (type == "m") { types[i$1] = prev; }
3033
+ else { prev = type; }
3034
+ }
3035
+
3036
+ // W2. Search backwards from each instance of a European number
3037
+ // until the first strong type (R, L, AL, or sor) is found. If an
3038
+ // AL is found, change the type of the European number to Arabic
3039
+ // number.
3040
+ // W3. Change all ALs to R.
3041
+ for (var i$2 = 0, cur = outerType; i$2 < len; ++i$2) {
3042
+ var type$1 = types[i$2];
3043
+ if (type$1 == "1" && cur == "r") { types[i$2] = "n"; }
3044
+ else if (isStrong.test(type$1)) { cur = type$1; if (type$1 == "r") { types[i$2] = "R"; } }
3045
+ }
3046
+
3047
+ // W4. A single European separator between two European numbers
3048
+ // changes to a European number. A single common separator between
3049
+ // two numbers of the same type changes to that type.
3050
+ for (var i$3 = 1, prev$1 = types[0]; i$3 < len - 1; ++i$3) {
3051
+ var type$2 = types[i$3];
3052
+ if (type$2 == "+" && prev$1 == "1" && types[i$3+1] == "1") { types[i$3] = "1"; }
3053
+ else if (type$2 == "," && prev$1 == types[i$3+1] &&
3054
+ (prev$1 == "1" || prev$1 == "n")) { types[i$3] = prev$1; }
3055
+ prev$1 = type$2;
3056
+ }
3057
+
3058
+ // W5. A sequence of European terminators adjacent to European
3059
+ // numbers changes to all European numbers.
3060
+ // W6. Otherwise, separators and terminators change to Other
3061
+ // Neutral.
3062
+ for (var i$4 = 0; i$4 < len; ++i$4) {
3063
+ var type$3 = types[i$4];
3064
+ if (type$3 == ",") { types[i$4] = "N"; }
3065
+ else if (type$3 == "%") {
3066
+ var end = (void 0);
3067
+ for (end = i$4 + 1; end < len && types[end] == "%"; ++end) {}
3068
+ var replace = (i$4 && types[i$4-1] == "!") || (end < len && types[end] == "1") ? "1" : "N";
3069
+ for (var j = i$4; j < end; ++j) { types[j] = replace; }
3070
+ i$4 = end - 1;
3071
+ }
3072
+ }
3073
 
3074
+ // W7. Search backwards from each instance of a European number
3075
+ // until the first strong type (R, L, or sor) is found. If an L is
3076
+ // found, then change the type of the European number to L.
3077
+ for (var i$5 = 0, cur$1 = outerType; i$5 < len; ++i$5) {
3078
+ var type$4 = types[i$5];
3079
+ if (cur$1 == "L" && type$4 == "1") { types[i$5] = "L"; }
3080
+ else if (isStrong.test(type$4)) { cur$1 = type$4; }
3081
+ }
3082
+
3083
+ // N1. A sequence of neutrals takes the direction of the
3084
+ // surrounding strong text if the text on both sides has the same
3085
+ // direction. European and Arabic numbers act as if they were R in
3086
+ // terms of their influence on neutrals. Start-of-level-run (sor)
3087
+ // and end-of-level-run (eor) are used at level run boundaries.
3088
+ // N2. Any remaining neutrals take the embedding direction.
3089
+ for (var i$6 = 0; i$6 < len; ++i$6) {
3090
+ if (isNeutral.test(types[i$6])) {
3091
+ var end$1 = (void 0);
3092
+ for (end$1 = i$6 + 1; end$1 < len && isNeutral.test(types[end$1]); ++end$1) {}
3093
+ var before = (i$6 ? types[i$6-1] : outerType) == "L";
3094
+ var after = (end$1 < len ? types[end$1] : outerType) == "L";
3095
+ var replace$1 = before == after ? (before ? "L" : "R") : outerType;
3096
+ for (var j$1 = i$6; j$1 < end$1; ++j$1) { types[j$1] = replace$1; }
3097
+ i$6 = end$1 - 1;
3098
+ }
3099
+ }
 
 
 
3100
 
3101
+ // Here we depart from the documented algorithm, in order to avoid
3102
+ // building up an actual levels array. Since there are only three
3103
+ // levels (0, 1, 2) in an implementation that doesn't take
3104
+ // explicit embedding into account, we can build up the order on
3105
+ // the fly, without following the level-based algorithm.
3106
+ var order = [], m;
3107
+ for (var i$7 = 0; i$7 < len;) {
3108
+ if (countsAsLeft.test(types[i$7])) {
3109
+ var start = i$7;
3110
+ for (++i$7; i$7 < len && countsAsLeft.test(types[i$7]); ++i$7) {}
3111
+ order.push(new BidiSpan(0, start, i$7));
3112
+ } else {
3113
+ var pos = i$7, at = order.length;
3114
+ for (++i$7; i$7 < len && types[i$7] != "L"; ++i$7) {}
3115
+ for (var j$2 = pos; j$2 < i$7;) {
3116
+ if (countsAsNum.test(types[j$2])) {
3117
+ if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)); }
3118
+ var nstart = j$2;
3119
+ for (++j$2; j$2 < i$7 && countsAsNum.test(types[j$2]); ++j$2) {}
3120
+ order.splice(at, 0, new BidiSpan(2, nstart, j$2));
3121
+ pos = j$2;
3122
+ } else { ++j$2; }
3123
+ }
3124
+ if (pos < i$7) { order.splice(at, 0, new BidiSpan(1, pos, i$7)); }
3125
+ }
3126
+ }
3127
+ if (direction == "ltr") {
3128
+ if (order[0].level == 1 && (m = str.match(/^\s+/))) {
3129
+ order[0].from = m[0].length;
3130
+ order.unshift(new BidiSpan(0, 0, m[0].length));
3131
+ }
3132
+ if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
3133
+ lst(order).to -= m[0].length;
3134
+ order.push(new BidiSpan(0, len - m[0].length, len));
3135
+ }
3136
+ }
3137
 
3138
+ return direction == "rtl" ? order.reverse() : order
 
 
 
 
 
 
 
 
 
 
3139
  }
3140
+ })();
3141
+
3142
+ // Get the bidi ordering for the given line (and cache it). Returns
3143
+ // false for lines that are fully left-to-right, and an array of
3144
+ // BidiSpan objects otherwise.
3145
+ function getOrder(line, direction) {
3146
+ var order = line.order;
3147
+ if (order == null) { order = line.order = bidiOrdering(line.text, direction); }
3148
+ return order
3149
  }
 
 
3150
 
3151
+ // EVENT HANDLING
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3152
 
3153
+ // Lightweight event framework. on/off also work on DOM nodes,
3154
+ // registering native DOM handlers.
 
 
 
 
 
 
 
 
 
 
 
 
3155
 
3156
+ var noHandlers = [];
3157
 
3158
+ var on = function(emitter, type, f) {
3159
+ if (emitter.addEventListener) {
3160
+ emitter.addEventListener(type, f, false);
3161
+ } else if (emitter.attachEvent) {
3162
+ emitter.attachEvent("on" + type, f);
3163
+ } else {
3164
+ var map$$1 = emitter._handlers || (emitter._handlers = {});
3165
+ map$$1[type] = (map$$1[type] || noHandlers).concat(f);
3166
  }
3167
+ };
3168
+
3169
+ function getHandlers(emitter, type) {
3170
+ return emitter._handlers && emitter._handlers[type] || noHandlers
3171
  }
 
 
3172
 
3173
+ function off(emitter, type, f) {
3174
+ if (emitter.removeEventListener) {
3175
+ emitter.removeEventListener(type, f, false);
3176
+ } else if (emitter.detachEvent) {
3177
+ emitter.detachEvent("on" + type, f);
3178
+ } else {
3179
+ var map$$1 = emitter._handlers, arr = map$$1 && map$$1[type];
3180
+ if (arr) {
3181
+ var index = indexOf(arr, f);
3182
+ if (index > -1)
3183
+ { map$$1[type] = arr.slice(0, index).concat(arr.slice(index + 1)); }
3184
+ }
 
 
3185
  }
3186
  }
 
 
3187
 
3188
+ function signal(emitter, type /*, values...*/) {
3189
+ var handlers = getHandlers(emitter, type);
3190
+ if (!handlers.length) { return }
3191
+ var args = Array.prototype.slice.call(arguments, 2);
3192
+ for (var i = 0; i < handlers.length; ++i) { handlers[i].apply(null, args); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3193
  }
3194
 
3195
+ // The DOM events that CodeMirror handles can be overridden by
3196
+ // registering a (non-DOM) handler on the editor for the event name,
3197
+ // and preventDefault-ing the event in that handler.
3198
+ function signalDOMEvent(cm, e, override) {
3199
+ if (typeof e == "string")
3200
+ { e = {type: e, preventDefault: function() { this.defaultPrevented = true; }}; }
3201
+ signal(cm, override || e.type, cm, e);
3202
+ return e_defaultPrevented(e) || e.codemirrorIgnore
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3203
  }
 
3204
 
3205
+ function signalCursorActivity(cm) {
3206
+ var arr = cm._handlers && cm._handlers.cursorActivity;
3207
+ if (!arr) { return }
3208
+ var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []);
3209
+ for (var i = 0; i < arr.length; ++i) { if (indexOf(set, arr[i]) == -1)
3210
+ { set.push(arr[i]); } }
3211
+ }
 
3212
 
3213
+ function hasHandler(emitter, type) {
3214
+ return getHandlers(emitter, type).length > 0
3215
+ }
3216
 
3217
+ // Add on and off methods to a constructor's prototype, to make
3218
+ // registering events on such objects more convenient.
3219
+ function eventMixin(ctor) {
3220
+ ctor.prototype.on = function(type, f) {on(this, type, f);};
3221
+ ctor.prototype.off = function(type, f) {off(this, type, f);};
3222
+ }
3223
 
3224
+ // Due to the fact that we still support jurassic IE versions, some
3225
+ // compatibility wrappers are needed.
3226
 
3227
+ function e_preventDefault(e) {
3228
+ if (e.preventDefault) { e.preventDefault(); }
3229
+ else { e.returnValue = false; }
 
 
 
 
 
3230
  }
3231
+ function e_stopPropagation(e) {
3232
+ if (e.stopPropagation) { e.stopPropagation(); }
3233
+ else { e.cancelBubble = true; }
3234
+ }
3235
+ function e_defaultPrevented(e) {
3236
+ return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false
3237
+ }
3238
+ function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
3239
 
3240
+ function e_target(e) {return e.target || e.srcElement}
3241
+ function e_button(e) {
3242
+ var b = e.which;
3243
+ if (b == null) {
3244
+ if (e.button & 1) { b = 1; }
3245
+ else if (e.button & 2) { b = 3; }
3246
+ else if (e.button & 4) { b = 2; }
 
 
 
 
3247
  }
3248
+ if (mac && e.ctrlKey && b == 1) { b = 3; }
3249
+ return b
3250
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3251
 
3252
+ // Detect drag-and-drop
3253
+ var dragAndDrop = function() {
3254
+ // There is *some* kind of drag-and-drop support in IE6-8, but I
3255
+ // couldn't get it to work yet.
3256
+ if (ie && ie_version < 9) { return false }
3257
+ var div = elt('div');
3258
+ return "draggable" in div || "dragDrop" in div
3259
+ }();
3260
 
3261
+ var zwspSupported;
3262
+ function zeroWidthElement(measure) {
3263
+ if (zwspSupported == null) {
3264
+ var test = elt("span", "\u200b");
3265
+ removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")]));
3266
+ if (measure.firstChild.offsetHeight != 0)
3267
+ { zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8); }
3268
+ }
3269
+ var node = zwspSupported ? elt("span", "\u200b") :
3270
+ elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
3271
+ node.setAttribute("cm-text", "");
3272
+ return node
3273
+ }
3274
+
3275
+ // Feature-detect IE's crummy client rect reporting for bidi text
3276
+ var badBidiRects;
3277
+ function hasBadBidiRects(measure) {
3278
+ if (badBidiRects != null) { return badBidiRects }
3279
+ var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA"));
3280
+ var r0 = range(txt, 0, 1).getBoundingClientRect();
3281
+ var r1 = range(txt, 1, 2).getBoundingClientRect();
3282
+ removeChildren(measure);
3283
+ if (!r0 || r0.left == r0.right) { return false } // Safari returns null in some cases (#2780)
3284
+ return badBidiRects = (r1.right - r0.right < 3)
3285
+ }
3286
+
3287
+ // See if "".split is the broken IE version, if so, provide an
3288
+ // alternative way to split lines.
3289
+ var splitLinesAuto = "\n\nb".split(/\n/).length != 3 ? function (string) {
3290
+ var pos = 0, result = [], l = string.length;
3291
+ while (pos <= l) {
3292
+ var nl = string.indexOf("\n", pos);
3293
+ if (nl == -1) { nl = string.length; }
3294
+ var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl);
3295
+ var rt = line.indexOf("\r");
3296
+ if (rt != -1) {
3297
+ result.push(line.slice(0, rt));
3298
+ pos += rt + 1;
3299
+ } else {
3300
+ result.push(line);
3301
+ pos = nl + 1;
3302
+ }
3303
+ }
3304
+ return result
3305
+ } : function (string) { return string.split(/\r\n?|\n/); };
3306
 
3307
+ var hasSelection = window.getSelection ? function (te) {
3308
+ try { return te.selectionStart != te.selectionEnd }
3309
+ catch(e) { return false }
3310
+ } : function (te) {
3311
+ var range$$1;
3312
+ try {range$$1 = te.ownerDocument.selection.createRange();}
3313
+ catch(e) {}
3314
+ if (!range$$1 || range$$1.parentElement() != te) { return false }
3315
+ return range$$1.compareEndPoints("StartToEnd", range$$1) != 0
3316
+ };
3317
 
3318
+ var hasCopyEvent = (function () {
3319
+ var e = elt("div");
3320
+ if ("oncopy" in e) { return true }
3321
+ e.setAttribute("oncopy", "return;");
3322
+ return typeof e.oncopy == "function"
3323
+ })();
3324
+
3325
+ var badZoomedRects = null;
3326
+ function hasBadZoomedRects(measure) {
3327
+ if (badZoomedRects != null) { return badZoomedRects }
3328
+ var node = removeChildrenAndAdd(measure, elt("span", "x"));
3329
+ var normal = node.getBoundingClientRect();
3330
+ var fromRange = range(node, 0, 1).getBoundingClientRect();
3331
+ return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1
3332
+ }
3333
 
3334
+ // Known modes, by name and by MIME
3335
+ var modes = {}, mimeModes = {};
3336
+
3337
+ // Extra arguments are stored as the mode's dependencies, which is
3338
+ // used by (legacy) mechanisms like loadmode.js to automatically
3339
+ // load a mode. (Preferred mechanism is the require/define calls.)
3340
+ function defineMode(name, mode) {
3341
+ if (arguments.length > 2)
3342
+ { mode.dependencies = Array.prototype.slice.call(arguments, 2); }
3343
+ modes[name] = mode;
3344
+ }
3345
+
3346
+ function defineMIME(mime, spec) {
3347
+ mimeModes[mime] = spec;
3348
+ }
3349
+
3350
+ // Given a MIME type, a {name, ...options} config object, or a name
3351
+ // string, return a mode config object.
3352
+ function resolveMode(spec) {
3353
+ if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
3354
+ spec = mimeModes[spec];
3355
+ } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
3356
+ var found = mimeModes[spec.name];
3357
+ if (typeof found == "string") { found = {name: found}; }
3358
+ spec = createObj(found, spec);
3359
+ spec.name = found.name;
3360
+ } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
3361
+ return resolveMode("application/xml")
3362
+ } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+json$/.test(spec)) {
3363
+ return resolveMode("application/json")
3364
+ }
3365
+ if (typeof spec == "string") { return {name: spec} }
3366
+ else { return spec || {name: "null"} }
3367
+ }
3368
+
3369
+ // Given a mode spec (anything that resolveMode accepts), find and
3370
+ // initialize an actual mode object.
3371
+ function getMode(options, spec) {
3372
+ spec = resolveMode(spec);
3373
+ var mfactory = modes[spec.name];
3374
+ if (!mfactory) { return getMode(options, "text/plain") }
3375
+ var modeObj = mfactory(options, spec);
3376
+ if (modeExtensions.hasOwnProperty(spec.name)) {
3377
+ var exts = modeExtensions[spec.name];
3378
+ for (var prop in exts) {
3379
+ if (!exts.hasOwnProperty(prop)) { continue }
3380
+ if (modeObj.hasOwnProperty(prop)) { modeObj["_" + prop] = modeObj[prop]; }
3381
+ modeObj[prop] = exts[prop];
3382
+ }
3383
+ }
3384
+ modeObj.name = spec.name;
3385
+ if (spec.helperType) { modeObj.helperType = spec.helperType; }
3386
+ if (spec.modeProps) { for (var prop$1 in spec.modeProps)
3387
+ { modeObj[prop$1] = spec.modeProps[prop$1]; } }
3388
+
3389
+ return modeObj
3390
+ }
3391
+
3392
+ // This can be used to attach properties to mode objects from
3393
+ // outside the actual mode definition.
3394
+ var modeExtensions = {};
3395
+ function extendMode(mode, properties) {
3396
+ var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
3397
+ copyObj(properties, exts);
3398
+ }
3399
+
3400
+ function copyState(mode, state) {
3401
+ if (state === true) { return state }
3402
+ if (mode.copyState) { return mode.copyState(state) }
3403
+ var nstate = {};
3404
+ for (var n in state) {
3405
+ var val = state[n];
3406
+ if (val instanceof Array) { val = val.concat([]); }
3407
+ nstate[n] = val;
3408
+ }
3409
+ return nstate
3410
+ }
3411
+
3412
+ // Given a mode and a state (for that mode), find the inner mode and
3413
+ // state at the position that the state refers to.
3414
+ function innerMode(mode, state) {
3415
+ var info;
3416
+ while (mode.innerMode) {
3417
+ info = mode.innerMode(state);
3418
+ if (!info || info.mode == mode) { break }
3419
+ state = info.state;
3420
+ mode = info.mode;
3421
+ }
3422
+ return info || {mode: mode, state: state}
3423
+ }
3424
+
3425
+ function startState(mode, a1, a2) {
3426
+ return mode.startState ? mode.startState(a1, a2) : true
3427
+ }
3428
+
3429
+ // STRING STREAM
3430
 
3431
+ // Fed to the mode parsers, provides helper functions to make
3432
+ // parsers more succinct.
3433
+
3434
+ var StringStream = function(string, tabSize, lineOracle) {
3435
+ this.pos = this.start = 0;
3436
+ this.string = string;
3437
+ this.tabSize = tabSize || 8;
3438
+ this.lastColumnPos = this.lastColumnValue = 0;
3439
+ this.lineStart = 0;
3440
+ this.lineOracle = lineOracle;
3441
+ };
 
 
 
 
 
 
 
 
 
 
 
3442
 
3443
+ StringStream.prototype.eol = function () {return this.pos >= this.string.length};
3444
+ StringStream.prototype.sol = function () {return this.pos == this.lineStart};
3445
+ StringStream.prototype.peek = function () {return this.string.charAt(this.pos) || undefined};
3446
+ StringStream.prototype.next = function () {
3447
+ if (this.pos < this.string.length)
3448
+ { return this.string.charAt(this.pos++) }
3449
+ };
3450
+ StringStream.prototype.eat = function (match) {
3451
+ var ch = this.string.charAt(this.pos);
3452
+ var ok;
3453
+ if (typeof match == "string") { ok = ch == match; }
3454
+ else { ok = ch && (match.test ? match.test(ch) : match(ch)); }
3455
+ if (ok) {++this.pos; return ch}
3456
+ };
3457
+ StringStream.prototype.eatWhile = function (match) {
3458
+ var start = this.pos;
3459
+ while (this.eat(match)){}
3460
+ return this.pos > start
3461
+ };
3462
+ StringStream.prototype.eatSpace = function () {
3463
+ var this$1 = this;
3464
 
3465
+ var start = this.pos;
3466
+ while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this$1.pos; }
3467
+ return this.pos > start
3468
+ };
3469
+ StringStream.prototype.skipToEnd = function () {this.pos = this.string.length;};
3470
+ StringStream.prototype.skipTo = function (ch) {
3471
+ var found = this.string.indexOf(ch, this.pos);
3472
+ if (found > -1) {this.pos = found; return true}
3473
+ };
3474
+ StringStream.prototype.backUp = function (n) {this.pos -= n;};
3475
+ StringStream.prototype.column = function () {
3476
+ if (this.lastColumnPos < this.start) {
3477
+ this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
3478
+ this.lastColumnPos = this.start;
3479
+ }
3480
+ return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
3481
+ };
3482
+ StringStream.prototype.indentation = function () {
3483
+ return countColumn(this.string, null, this.tabSize) -
3484
+ (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
3485
+ };
3486
+ StringStream.prototype.match = function (pattern, consume, caseInsensitive) {
3487
+ if (typeof pattern == "string") {
3488
+ var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; };
3489
+ var substr = this.string.substr(this.pos, pattern.length);
3490
+ if (cased(substr) == cased(pattern)) {
3491
+ if (consume !== false) { this.pos += pattern.length; }
3492
+ return true
3493
+ }
3494
  } else {
3495
+ var match = this.string.slice(this.pos).match(pattern);
3496
+ if (match && match.index > 0) { return null }
3497
+ if (match && consume !== false) { this.pos += match[0].length; }
3498
+ return match
3499
+ }
3500
+ };
3501
+ StringStream.prototype.current = function (){return this.string.slice(this.start, this.pos)};
3502
+ StringStream.prototype.hideFirstChars = function (n, inner) {
3503
+ this.lineStart += n;
3504
+ try { return inner() }
3505
+ finally { this.lineStart -= n; }
3506
+ };
3507
+ StringStream.prototype.lookAhead = function (n) {
3508
+ var oracle = this.lineOracle;
3509
+ return oracle && oracle.lookAhead(n)
3510
+ };
3511
+ StringStream.prototype.baseToken = function () {
3512
+ var oracle = this.lineOracle;
3513
+ return oracle && oracle.baseToken(this.pos)
3514
+ };
3515
 
3516
+ var SavedContext = function(state, lookAhead) {
3517
+ this.state = state;
3518
+ this.lookAhead = lookAhead;
3519
+ };
 
 
 
 
 
 
 
 
 
 
 
3520
 
3521
+ var Context = function(doc, state, line, lookAhead) {
3522
+ this.state = state;
3523
+ this.doc = doc;
3524
+ this.line = line;
3525
+ this.maxLookAhead = lookAhead || 0;
3526
+ this.baseTokens = null;
3527
+ this.baseTokenPos = 1;
3528
+ };
 
 
 
 
3529
 
3530
+ Context.prototype.lookAhead = function (n) {
3531
+ var line = this.doc.getLine(this.line + n);
3532
+ if (line != null && n > this.maxLookAhead) { this.maxLookAhead = n; }
3533
+ return line
3534
+ };
3535
 
3536
+ Context.prototype.baseToken = function (n) {
3537
+ var this$1 = this;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3538
 
3539
+ if (!this.baseTokens) { return null }
3540
+ while (this.baseTokens[this.baseTokenPos] <= n)
3541
+ { this$1.baseTokenPos += 2; }
3542
+ var type = this.baseTokens[this.baseTokenPos + 1];
3543
+ return {type: type && type.replace(/( |^)overlay .*/, ""),
3544
+ size: this.baseTokens[this.baseTokenPos] - n}
3545
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3546
 
3547
+ Context.prototype.nextLine = function () {
3548
+ this.line++;
3549
+ if (this.maxLookAhead > 0) { this.maxLookAhead--; }
3550
+ };
 
 
 
3551
 
3552
+ Context.fromSaved = function (doc, saved, line) {
3553
+ if (saved instanceof SavedContext)
3554
+ { return new Context(doc, copyState(doc.mode, saved.state), line, saved.lookAhead) }
3555
+ else
3556
+ { return new Context(doc, copyState(doc.mode, saved), line) }
3557
+ };
 
 
 
 
 
3558
 
3559
+ Context.prototype.save = function (copy) {
3560
+ var state = copy !== false ? copyState(this.doc.mode, this.state) : this.state;
3561
+ return this.maxLookAhead > 0 ? new SavedContext(state, this.maxLookAhead) : state
3562
+ };
 
 
 
 
 
 
 
 
3563
 
 
 
 
3564
 
3565
+ // Compute a style array (an array starting with a mode generation
3566
+ // -- for invalidation -- followed by pairs of end positions and
3567
+ // style strings), which is used to highlight the tokens on the
3568
+ // line.
3569
+ function highlightLine(cm, line, context, forceToEnd) {
3570
+ // A styles array always starts with a number identifying the
3571
+ // mode/overlays that it is based on (for easy invalidation).
3572
+ var st = [cm.state.modeGen], lineClasses = {};
3573
+ // Compute the base array of styles
3574
+ runMode(cm, line.text, cm.doc.mode, context, function (end, style) { return st.push(end, style); },
3575
+ lineClasses, forceToEnd);
3576
+ var state = context.state;
3577
+
3578
+ // Run overlays, adjust style array.
3579
+ var loop = function ( o ) {
3580
+ context.baseTokens = st;
3581
+ var overlay = cm.state.overlays[o], i = 1, at = 0;
3582
+ context.state = true;
3583
+ runMode(cm, line.text, overlay.mode, context, function (end, style) {
3584
+ var start = i;
3585
+ // Ensure there's a token end at the current position, and that i points at it
3586
+ while (at < end) {
3587
+ var i_end = st[i];
3588
+ if (i_end > end)
3589
+ { st.splice(i, 1, end, st[i+1], i_end); }
3590
+ i += 2;
3591
+ at = Math.min(end, i_end);
3592
+ }
3593
+ if (!style) { return }
3594
+ if (overlay.opaque) {
3595
+ st.splice(start, i - start, end, "overlay " + style);
3596
+ i = start + 2;
3597
+ } else {
3598
+ for (; start < i; start += 2) {
3599
+ var cur = st[start+1];
3600
+ st[start+1] = (cur ? cur + " " : "") + "overlay " + style;
3601
+ }
3602
+ }
3603
+ }, lineClasses);
3604
+ context.state = state;
3605
+ context.baseTokens = null;
3606
+ context.baseTokenPos = 1;
3607
+ };
3608
 
3609
+ for (var o = 0; o < cm.state.overlays.length; ++o) loop( o );
 
3610
 
3611
+ return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null}
3612
+ }
 
 
 
 
 
 
3613
 
3614
+ function getLineStyles(cm, line, updateFrontier) {
3615
+ if (!line.styles || line.styles[0] != cm.state.modeGen) {
3616
+ var context = getContextBefore(cm, lineNo(line));
3617
+ var resetState = line.text.length > cm.options.maxHighlightLength && copyState(cm.doc.mode, context.state);
3618
+ var result = highlightLine(cm, line, context);
3619
+ if (resetState) { context.state = resetState; }
3620
+ line.stateAfter = context.save(!resetState);
3621
+ line.styles = result.styles;
3622
+ if (result.classes) { line.styleClasses = result.classes; }
3623
+ else if (line.styleClasses) { line.styleClasses = null; }
3624
+ if (updateFrontier === cm.doc.highlightFrontier)
3625
+ { cm.doc.modeFrontier = Math.max(cm.doc.modeFrontier, ++cm.doc.highlightFrontier); }
3626
+ }
3627
+ return line.styles
3628
+ }
3629
+
3630
+ function getContextBefore(cm, n, precise) {
3631
+ var doc = cm.doc, display = cm.display;
3632
+ if (!doc.mode.startState) { return new Context(doc, true, n) }
3633
+ var start = findStartLine(cm, n, precise);
3634
+ var saved = start > doc.first && getLine(doc, start - 1).stateAfter;
3635
+ var context = saved ? Context.fromSaved(doc, saved, start) : new Context(doc, startState(doc.mode), start);
3636
+
3637
+ doc.iter(start, n, function (line) {
3638
+ processLine(cm, line.text, context);
3639
+ var pos = context.line;
3640
+ line.stateAfter = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo ? context.save() : null;
3641
+ context.nextLine();
3642
+ });
3643
+ if (precise) { doc.modeFrontier = context.line; }
3644
+ return context
3645
+ }
3646
 
3647
+ // Lightweight form of highlight -- proceed over this line and
3648
+ // update state, but don't save a style array. Used for lines that
3649
+ // aren't currently visible.
3650
+ function processLine(cm, text, context, startAt) {
3651
+ var mode = cm.doc.mode;
3652
+ var stream = new StringStream(text, cm.options.tabSize, context);
3653
+ stream.start = stream.pos = startAt || 0;
3654
+ if (text == "") { callBlankLine(mode, context.state); }
3655
+ while (!stream.eol()) {
3656
+ readToken(mode, stream, context.state);
3657
+ stream.start = stream.pos;
3658
+ }
 
 
3659
  }
3660
+
3661
+ function callBlankLine(mode, state) {
3662
+ if (mode.blankLine) { return mode.blankLine(state) }
3663
+ if (!mode.innerMode) { return }
3664
+ var inner = innerMode(mode, state);
3665
+ if (inner.mode.blankLine) { return inner.mode.blankLine(inner.state) }
3666
+ }
3667
+
3668
+ function readToken(mode, stream, state, inner) {
3669
+ for (var i = 0; i < 10; i++) {
3670
+ if (inner) { inner[0] = innerMode(mode, state).mode; }
3671
+ var style = mode.token(stream, state);
3672
+ if (stream.pos > stream.start) { return style }
3673
  }
3674
+ throw new Error("Mode " + mode.name + " failed to advance stream.")
 
 
 
 
3675
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3676
 
3677
+ var Token = function(stream, type, state) {
3678
+ this.start = stream.start; this.end = stream.pos;
3679
+ this.string = stream.current();
3680
+ this.type = type || null;
3681
+ this.state = state;
3682
+ };
3683
 
3684
+ // Utility for getTokenAt and getLineTokens
3685
+ function takeToken(cm, pos, precise, asArray) {
3686
+ var doc = cm.doc, mode = doc.mode, style;
3687
+ pos = clipPos(doc, pos);
3688
+ var line = getLine(doc, pos.line), context = getContextBefore(cm, pos.line, precise);
3689
+ var stream = new StringStream(line.text, cm.options.tabSize, context), tokens;
3690
+ if (asArray) { tokens = []; }
3691
+ while ((asArray || stream.pos < pos.ch) && !stream.eol()) {
3692
+ stream.start = stream.pos;
3693
+ style = readToken(mode, stream, context.state);
3694
+ if (asArray) { tokens.push(new Token(stream, style, copyState(doc.mode, context.state))); }
3695
+ }
3696
+ return asArray ? tokens : new Token(stream, style, context.state)
3697
+ }
3698
+
3699
+ function extractLineClasses(type, output) {
3700
+ if (type) { for (;;) {
3701
+ var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/);
3702
+ if (!lineClass) { break }
3703
+ type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length);
3704
+ var prop = lineClass[1] ? "bgClass" : "textClass";
3705
+ if (output[prop] == null)
3706
+ { output[prop] = lineClass[2]; }
3707
+ else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop]))
3708
+ { output[prop] += " " + lineClass[2]; }
3709
+ } }
3710
+ return type
3711
+ }
3712
+
3713
+ // Run the given mode's parser over a line, calling f for each token.
3714
+ function runMode(cm, text, mode, context, f, lineClasses, forceToEnd) {
3715
+ var flattenSpans = mode.flattenSpans;
3716
+ if (flattenSpans == null) { flattenSpans = cm.options.flattenSpans; }
3717
+ var curStart = 0, curStyle = null;
3718
+ var stream = new StringStream(text, cm.options.tabSize, context), style;
3719
+ var inner = cm.options.addModeClass && [null];
3720
+ if (text == "") { extractLineClasses(callBlankLine(mode, context.state), lineClasses); }
3721
+ while (!stream.eol()) {
3722
+ if (stream.pos > cm.options.maxHighlightLength) {
3723
+ flattenSpans = false;
3724
+ if (forceToEnd) { processLine(cm, text, context, stream.pos); }
3725
+ stream.pos = text.length;
3726
+ style = null;
3727
+ } else {
3728
+ style = extractLineClasses(readToken(mode, stream, context.state, inner), lineClasses);
3729
+ }
3730
+ if (inner) {
3731
+ var mName = inner[0].name;
3732
+ if (mName) { style = "m-" + (style ? mName + " " + style : mName); }
3733
+ }
3734
+ if (!flattenSpans || curStyle != style) {
3735
+ while (curStart < stream.start) {
3736
+ curStart = Math.min(stream.start, curStart + 5000);
3737
+ f(curStart, curStyle);
3738
+ }
3739
+ curStyle = style;
3740
+ }
3741
+ stream.start = stream.pos;
3742
+ }
3743
+ while (curStart < stream.pos) {
3744
+ // Webkit seems to refuse to render text nodes longer than 57444
3745
+ // characters, and returns inaccurate measurements in nodes
3746
+ // starting around 5000 chars.
3747
+ var pos = Math.min(stream.pos, curStart + 5000);
3748
+ f(pos, curStyle);
3749
+ curStart = pos;
3750
+ }
3751
+ }
3752
+
3753
+ // Finds the line to start with when starting a parse. Tries to
3754
+ // find a line with a stateAfter, so that it can start with a
3755
+ // valid state. If that fails, it returns the line with the
3756
+ // smallest indentation, which tends to need the least context to
3757
+ // parse correctly.
3758
+ function findStartLine(cm, n, precise) {
3759
+ var minindent, minline, doc = cm.doc;
3760
+ var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100);
3761
+ for (var search = n; search > lim; --search) {
3762
+ if (search <= doc.first) { return doc.first }
3763
+ var line = getLine(doc, search - 1), after = line.stateAfter;
3764
+ if (after && (!precise || search + (after instanceof SavedContext ? after.lookAhead : 0) <= doc.modeFrontier))
3765
+ { return search }
3766
+ var indented = countColumn(line.text, null, cm.options.tabSize);
3767
+ if (minline == null || minindent > indented) {
3768
+ minline = search - 1;
3769
+ minindent = indented;
3770
+ }
3771
+ }
3772
+ return minline
3773
+ }
3774
+
3775
+ function retreatFrontier(doc, n) {
3776
+ doc.modeFrontier = Math.min(doc.modeFrontier, n);
3777
+ if (doc.highlightFrontier < n - 10) { return }
3778
+ var start = doc.first;
3779
+ for (var line = n - 1; line > start; line--) {
3780
+ var saved = getLine(doc, line).stateAfter;
3781
+ // change is on 3
3782
+ // state on line 1 looked ahead 2 -- so saw 3
3783
+ // test 1 + 2 < 3 should cover this
3784
+ if (saved && (!(saved instanceof SavedContext) || line + saved.lookAhead < n)) {
3785
+ start = line + 1;
3786
+ break
3787
+ }
3788
+ }
3789
+ doc.highlightFrontier = Math.min(doc.highlightFrontier, start);
3790
+ }
3791
 
3792
+ // LINE DATA STRUCTURE
 
 
 
 
3793
 
3794
+ // Line objects. These hold state related to a line, including
3795
+ // highlighting info (the styles array).
3796
+ var Line = function(text, markedSpans, estimateHeight) {
3797
+ this.text = text;
3798
+ attachMarkedSpans(this, markedSpans);
3799
+ this.height = estimateHeight ? estimateHeight(this) : 1;
3800
+ };
3801
 
3802
+ Line.prototype.lineNo = function () { return lineNo(this) };
3803
+ eventMixin(Line);
 
 
 
 
 
3804
 
3805
+ // Change the content (text, markers) of a line. Automatically
3806
+ // invalidates cached information and tries to re-estimate the
3807
+ // line's height.
3808
+ function updateLine(line, text, markedSpans, estimateHeight) {
3809
+ line.text = text;
3810
+ if (line.stateAfter) { line.stateAfter = null; }
3811
+ if (line.styles) { line.styles = null; }
3812
+ if (line.order != null) { line.order = null; }
3813
+ detachMarkedSpans(line);
3814
+ attachMarkedSpans(line, markedSpans);
3815
+ var estHeight = estimateHeight ? estimateHeight(line) : 1;
3816
+ if (estHeight != line.height) { updateLineHeight(line, estHeight); }
3817
+ }
3818
 
3819
+ // Detach a line from the document tree and its markers.
3820
+ function cleanUpLine(line) {
3821
+ line.parent = null;
3822
+ detachMarkedSpans(line);
3823
+ }
3824
+
3825
+ // Convert a style as returned by a mode (either null, or a string
3826
+ // containing one or more styles) to a CSS style. This is cached,
3827
+ // and also looks for line-wide styles.
3828
+ var styleToClassCache = {}, styleToClassCacheWithMode = {};
3829
+ function interpretTokenStyle(style, options) {
3830
+ if (!style || /^\s*$/.test(style)) { return null }
3831
+ var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache;
3832
+ return cache[style] ||
3833
+ (cache[style] = style.replace(/\S+/g, "cm-$&"))
3834
+ }
3835
+
3836
+ // Render the DOM representation of the text of a line. Also builds
3837
+ // up a 'line map', which points at the DOM nodes that represent
3838
+ // specific stretches of text, and is used by the measuring code.
3839
+ // The returned object contains the DOM node, this map, and
3840
+ // information about line-wide styles that were set by the mode.
3841
+ function buildLineContent(cm, lineView) {
3842
+ // The padding-right forces the element to have a 'border', which
3843
+ // is needed on Webkit to be able to get line-level bounding
3844
+ // rectangles for it (in measureChar).
3845
+ var content = eltP("span", null, null, webkit ? "padding-right: .1px" : null);
3846
+ var builder = {pre: eltP("pre", [content], "CodeMirror-line"), content: content,
3847
+ col: 0, pos: 0, cm: cm,
3848
+ trailingSpace: false,
3849
+ splitSpaces: cm.getOption("lineWrapping")};
3850
+ lineView.measure = {};
3851
+
3852
+ // Iterate over the logical lines that make up this visual line.
3853
+ for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) {
3854
+ var line = i ? lineView.rest[i - 1] : lineView.line, order = (void 0);
3855
+ builder.pos = 0;
3856
+ builder.addToken = buildToken;
3857
+ // Optionally wire in some hacks into the token-rendering
3858
+ // algorithm, to deal with browser quirks.
3859
+ if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line, cm.doc.direction)))
3860
+ { builder.addToken = buildTokenBadBidi(builder.addToken, order); }
3861
+ builder.map = [];
3862
+ var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line);
3863
+ insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate));
3864
+ if (line.styleClasses) {
3865
+ if (line.styleClasses.bgClass)
3866
+ { builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || ""); }
3867
+ if (line.styleClasses.textClass)
3868
+ { builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || ""); }
3869
+ }
3870
+
3871
+ // Ensure at least a single node is present, for measuring.
3872
+ if (builder.map.length == 0)
3873
+ { builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))); }
3874
+
3875
+ // Store the map and a cache object for the current logical line
3876
+ if (i == 0) {
3877
+ lineView.measure.map = builder.map;
3878
+ lineView.measure.cache = {};
3879
+ } else {
3880
+ (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map)
3881
+ ;(lineView.measure.caches || (lineView.measure.caches = [])).push({});
3882
+ }
3883
+ }
3884
 
3885
+ // See issue #2901
3886
+ if (webkit) {
3887
+ var last = builder.content.lastChild;
3888
+ if (/\bcm-tab\b/.test(last.className) || (last.querySelector && last.querySelector(".cm-tab")))
3889
+ { builder.content.className = "cm-tab-wrap-hack"; }
3890
+ }
3891
 
3892
+ signal(cm, "renderLine", cm, lineView.line, builder.pre);
3893
+ if (builder.pre.className)
3894
+ { builder.textClass = joinClasses(builder.pre.className, builder.textClass || ""); }
3895
 
3896
+ return builder
3897
+ }
3898
+
3899
+ function defaultSpecialCharPlaceholder(ch) {
3900
+ var token = elt("span", "\u2022", "cm-invalidchar");
3901
+ token.title = "\\u" + ch.charCodeAt(0).toString(16);
3902
+ token.setAttribute("aria-label", token.title);
3903
+ return token
3904
+ }
3905
+
3906
+ // Build up the DOM representation for a single token, and add it to
3907
+ // the line map. Takes care to render special characters separately.
3908
+ function buildToken(builder, text, style, startStyle, endStyle, title, css) {
3909
+ if (!text) { return }
3910
+ var displayText = builder.splitSpaces ? splitSpaces(text, builder.trailingSpace) : text;
3911
+ var special = builder.cm.state.specialChars, mustWrap = false;
3912
+ var content;
3913
+ if (!special.test(text)) {
3914
+ builder.col += text.length;
3915
+ content = document.createTextNode(displayText);
3916
+ builder.map.push(builder.pos, builder.pos + text.length, content);
3917
+ if (ie && ie_version < 9) { mustWrap = true; }
3918
+ builder.pos += text.length;
3919
+ } else {
3920
+ content = document.createDocumentFragment();
3921
+ var pos = 0;
3922
+ while (true) {
3923
+ special.lastIndex = pos;
3924
+ var m = special.exec(text);
3925
+ var skipped = m ? m.index - pos : text.length - pos;
3926
+ if (skipped) {
3927
+ var txt = document.createTextNode(displayText.slice(pos, pos + skipped));
3928
+ if (ie && ie_version < 9) { content.appendChild(elt("span", [txt])); }
3929
+ else { content.appendChild(txt); }
3930
+ builder.map.push(builder.pos, builder.pos + skipped, txt);
3931
+ builder.col += skipped;
3932
+ builder.pos += skipped;
3933
  }
3934
+ if (!m) { break }
3935
+ pos += skipped + 1;
3936
+ var txt$1 = (void 0);
3937
+ if (m[0] == "\t") {
3938
+ var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
3939
+ txt$1 = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
3940
+ txt$1.setAttribute("role", "presentation");
3941
+ txt$1.setAttribute("cm-text", "\t");
3942
+ builder.col += tabWidth;
3943
+ } else if (m[0] == "\r" || m[0] == "\n") {
3944
+ txt$1 = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar"));
3945
+ txt$1.setAttribute("cm-text", m[0]);
3946
+ builder.col += 1;
3947
+ } else {
3948
+ txt$1 = builder.cm.options.specialCharPlaceholder(m[0]);
3949
+ txt$1.setAttribute("cm-text", m[0]);
3950
+ if (ie && ie_version < 9) { content.appendChild(elt("span", [txt$1])); }
3951
+ else { content.appendChild(txt$1); }
3952
+ builder.col += 1;
3953
+ }
3954
+ builder.map.push(builder.pos, builder.pos + 1, txt$1);
3955
+ builder.pos++;
3956
+ }
3957
+ }
3958
+ builder.trailingSpace = displayText.charCodeAt(text.length - 1) == 32;
3959
+ if (style || startStyle || endStyle || mustWrap || css) {
3960
+ var fullStyle = style || "";
3961
+ if (startStyle) { fullStyle += startStyle; }
3962
+ if (endStyle) { fullStyle += endStyle; }
3963
+ var token = elt("span", [content], fullStyle, css);
3964
+ if (title) { token.title = title; }
3965
+ return builder.content.appendChild(token)
3966
+ }
3967
+ builder.content.appendChild(content);
3968
+ }
3969
+
3970
+ // Change some spaces to NBSP to prevent the browser from collapsing
3971
+ // trailing spaces at the end of a line when rendering text (issue #1362).
3972
+ function splitSpaces(text, trailingBefore) {
3973
+ if (text.length > 1 && !/ /.test(text)) { return text }
3974
+ var spaceBefore = trailingBefore, result = "";
3975
+ for (var i = 0; i < text.length; i++) {
3976
+ var ch = text.charAt(i);
3977
+ if (ch == " " && spaceBefore && (i == text.length - 1 || text.charCodeAt(i + 1) == 32))
3978
+ { ch = "\u00a0"; }
3979
+ result += ch;
3980
+ spaceBefore = ch == " ";
3981
+ }
3982
+ return result
3983
+ }
3984
 
3985
+ // Work around nonsense dimensions being reported for stretches of
3986
+ // right-to-left text.
3987
+ function buildTokenBadBidi(inner, order) {
3988
+ return function (builder, text, style, startStyle, endStyle, title, css) {
3989
+ style = style ? style + " cm-force-border" : "cm-force-border";
3990
+ var start = builder.pos, end = start + text.length;
3991
+ for (;;) {
3992
+ // Find the part that overlaps with the start of this text
3993
+ var part = (void 0);
3994
+ for (var i = 0; i < order.length; i++) {
3995
+ part = order[i];
3996
+ if (part.to > start && part.from <= start) { break }
3997
+ }
3998
+ if (part.to >= end) { return inner(builder, text, style, startStyle, endStyle, title, css) }
3999
+ inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css);
4000
+ startStyle = null;
4001
+ text = text.slice(part.to - start);
4002
+ start = part.to;
4003
+ }
4004
+ }
4005
+ }
4006
 
4007
+ function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
4008
+ var widget = !ignoreWidget && marker.widgetNode;
4009
+ if (widget) { builder.map.push(builder.pos, builder.pos + size, widget); }
4010
+ if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) {
4011
+ if (!widget)
4012
+ { widget = builder.content.appendChild(document.createElement("span")); }
4013
+ widget.setAttribute("cm-marker", marker.id);
4014
+ }
4015
+ if (widget) {
4016
+ builder.cm.display.input.setUneditable(widget);
4017
+ builder.content.appendChild(widget);
4018
+ }
4019
+ builder.pos += size;
4020
+ builder.trailingSpace = false;
4021
+ }
4022
 
4023
+ // Outputs a number of spans to make up a line, taking highlighting
4024
+ // and marked text into account.
4025
+ function insertLineContent(line, builder, styles) {
4026
+ var spans = line.markedSpans, allText = line.text, at = 0;
4027
+ if (!spans) {
4028
+ for (var i$1 = 1; i$1 < styles.length; i$1+=2)
4029
+ { builder.addToken(builder, allText.slice(at, at = styles[i$1]), interpretTokenStyle(styles[i$1+1], builder.cm.options)); }
4030
+ return
4031
+ }
 
 
 
 
 
 
4032
 
4033
+ var len = allText.length, pos = 0, i = 1, text = "", style, css;
4034
+ var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
4035
+ for (;;) {
4036
+ if (nextChange == pos) { // Update current marker set
4037
+ spanStyle = spanEndStyle = spanStartStyle = title = css = "";
4038
+ collapsed = null; nextChange = Infinity;
4039
+ var foundBookmarks = [], endStyles = (void 0);
4040
+ for (var j = 0; j < spans.length; ++j) {
4041
+ var sp = spans[j], m = sp.marker;
4042
+ if (m.type == "bookmark" && sp.from == pos && m.widgetNode) {
4043
+ foundBookmarks.push(m);
4044
+ } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) {
4045
+ if (sp.to != null && sp.to != pos && nextChange > sp.to) {
4046
+ nextChange = sp.to;
4047
+ spanEndStyle = "";
4048
+ }
4049
+ if (m.className) { spanStyle += " " + m.className; }
4050
+ if (m.css) { css = (css ? css + ";" : "") + m.css; }
4051
+ if (m.startStyle && sp.from == pos) { spanStartStyle += " " + m.startStyle; }
4052
+ if (m.endStyle && sp.to == nextChange) { (endStyles || (endStyles = [])).push(m.endStyle, sp.to); }
4053
+ if (m.title && !title) { title = m.title; }
4054
+ if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))
4055
+ { collapsed = sp; }
4056
+ } else if (sp.from > pos && nextChange > sp.from) {
4057
+ nextChange = sp.from;
4058
+ }
4059
+ }
4060
+ if (endStyles) { for (var j$1 = 0; j$1 < endStyles.length; j$1 += 2)
4061
+ { if (endStyles[j$1 + 1] == nextChange) { spanEndStyle += " " + endStyles[j$1]; } } }
4062
+
4063
+ if (!collapsed || collapsed.from == pos) { for (var j$2 = 0; j$2 < foundBookmarks.length; ++j$2)
4064
+ { buildCollapsedSpan(builder, 0, foundBookmarks[j$2]); } }
4065
+ if (collapsed && (collapsed.from || 0) == pos) {
4066
+ buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos,
4067
+ collapsed.marker, collapsed.from == null);
4068
+ if (collapsed.to == null) { return }
4069
+ if (collapsed.to == pos) { collapsed = false; }
4070
+ }
4071
+ }
4072
+ if (pos >= len) { break }
4073
 
4074
+ var upto = Math.min(len, nextChange);
4075
+ while (true) {
4076
+ if (text) {
4077
+ var end = pos + text.length;
4078
+ if (!collapsed) {
4079
+ var tokenText = end > upto ? text.slice(0, upto - pos) : text;
4080
+ builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
4081
+ spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css);
4082
+ }
4083
+ if (end >= upto) {text = text.slice(upto - pos); pos = upto; break}
4084
+ pos = end;
4085
+ spanStartStyle = "";
4086
+ }
4087
+ text = allText.slice(at, at = styles[i++]);
4088
+ style = interpretTokenStyle(styles[i++], builder.cm.options);
4089
+ }
4090
+ }
4091
  }
 
4092
 
 
 
 
 
 
 
4093
 
4094
+ // These objects are used to represent the visible (currently drawn)
4095
+ // part of the document. A LineView may correspond to multiple
4096
+ // logical lines, if those are connected by collapsed ranges.
4097
+ function LineView(doc, line, lineN) {
4098
+ // The starting line
4099
+ this.line = line;
4100
+ // Continuing lines, if any
4101
+ this.rest = visualLineContinued(line);
4102
+ // Number of logical lines in this visual line
4103
+ this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1;
4104
+ this.node = this.text = null;
4105
+ this.hidden = lineIsHidden(doc, line);
4106
  }
 
 
4107
 
4108
+ // Create a range of LineView objects for the given lines.
4109
+ function buildViewArray(cm, from, to) {
4110
+ var array = [], nextPos;
4111
+ for (var pos = from; pos < to; pos = nextPos) {
4112
+ var view = new LineView(cm.doc, getLine(cm.doc, pos), pos);
4113
+ nextPos = pos + view.size;
4114
+ array.push(view);
4115
+ }
4116
+ return array
4117
+ }
4118
 
4119
+ var operationGroup = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
4120
 
4121
+ function pushOperation(op) {
4122
+ if (operationGroup) {
4123
+ operationGroup.ops.push(op);
4124
+ } else {
4125
+ op.ownsGroup = operationGroup = {
4126
+ ops: [op],
4127
+ delayedCallbacks: []
4128
+ };
4129
+ }
4130
+ }
 
 
 
4131
 
4132
+ function fireCallbacksForOps(group) {
4133
+ // Calls delayed callbacks and cursorActivity handlers until no
4134
+ // new ones appear
4135
+ var callbacks = group.delayedCallbacks, i = 0;
4136
+ do {
4137
+ for (; i < callbacks.length; i++)
4138
+ { callbacks[i].call(null); }
4139
+ for (var j = 0; j < group.ops.length; j++) {
4140
+ var op = group.ops[j];
4141
+ if (op.cursorActivityHandlers)
4142
+ { while (op.cursorActivityCalled < op.cursorActivityHandlers.length)
4143
+ { op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm); } }
4144
+ }
4145
+ } while (i < callbacks.length)
4146
+ }
4147
+
4148
+ function finishOperation(op, endCb) {
4149
+ var group = op.ownsGroup;
4150
+ if (!group) { return }
4151
+
4152
+ try { fireCallbacksForOps(group); }
4153
+ finally {
4154
+ operationGroup = null;
4155
+ endCb(group);
4156
+ }
4157
+ }
4158
+
4159
+ var orphanDelayedCallbacks = null;
4160
+
4161
+ // Often, we want to signal events at a point where we are in the
4162
+ // middle of some work, but don't want the handler to start calling
4163
+ // other methods on the editor, which might be in an inconsistent
4164
+ // state or simply not expect any other events to happen.
4165
+ // signalLater looks whether there are any handlers, and schedules
4166
+ // them to be executed when the last operation ends, or, if no
4167
+ // operation is active, when a timeout fires.
4168
+ function signalLater(emitter, type /*, values...*/) {
4169
+ var arr = getHandlers(emitter, type);
4170
+ if (!arr.length) { return }
4171
+ var args = Array.prototype.slice.call(arguments, 2), list;
4172
+ if (operationGroup) {
4173
+ list = operationGroup.delayedCallbacks;
4174
+ } else if (orphanDelayedCallbacks) {
4175
+ list = orphanDelayedCallbacks;
4176
  } else {
4177
+ list = orphanDelayedCallbacks = [];
4178
+ setTimeout(fireOrphanDelayed, 0);
4179
  }
4180
+ var loop = function ( i ) {
4181
+ list.push(function () { return arr[i].apply(null, args); });
4182
+ };
4183
+
4184
+ for (var i = 0; i < arr.length; ++i)
4185
+ loop( i );
4186
+ }
4187
+
4188
+ function fireOrphanDelayed() {
4189
+ var delayed = orphanDelayedCallbacks;
4190
+ orphanDelayedCallbacks = null;
4191
+ for (var i = 0; i < delayed.length; ++i) { delayed[i](); }
4192
+ }
4193
+
4194
+ // When an aspect of a line changes, a string is added to
4195
+ // lineView.changes. This updates the relevant part of the line's
4196
+ // DOM structure.
4197
+ function updateLineForChanges(cm, lineView, lineN, dims) {
4198
+ for (var j = 0; j < lineView.changes.length; j++) {
4199
+ var type = lineView.changes[j];
4200
+ if (type == "text") { updateLineText(cm, lineView); }
4201
+ else if (type == "gutter") { updateLineGutter(cm, lineView, lineN, dims); }
4202
+ else if (type == "class") { updateLineClasses(cm, lineView); }
4203
+ else if (type == "widget") { updateLineWidgets(cm, lineView, dims); }
4204
+ }
4205
+ lineView.changes = null;
4206
+ }
4207
+
4208
+ // Lines with gutter elements, widgets or a background class need to
4209
+ // be wrapped, and have the extra elements added to the wrapper div
4210
+ function ensureLineWrapped(lineView) {
4211
+ if (lineView.node == lineView.text) {
4212
+ lineView.node = elt("div", null, null, "position: relative");
4213
+ if (lineView.text.parentNode)
4214
+ { lineView.text.parentNode.replaceChild(lineView.node, lineView.text); }
4215
+ lineView.node.appendChild(lineView.text);
4216
+ if (ie && ie_version < 8) { lineView.node.style.zIndex = 2; }
4217
+ }
4218
+ return lineView.node
4219
+ }
4220
+
4221
+ function updateLineBackground(cm, lineView) {
4222
+ var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass;
4223
+ if (cls) { cls += " CodeMirror-linebackground"; }
4224
+ if (lineView.background) {
4225
+ if (cls) { lineView.background.className = cls; }
4226
+ else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; }
4227
+ } else if (cls) {
4228
+ var wrap = ensureLineWrapped(lineView);
4229
+ lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild);
4230
+ cm.display.input.setUneditable(lineView.background);
4231
+ }
4232
+ }
4233
+
4234
+ // Wrapper around buildLineContent which will reuse the structure
4235
+ // in display.externalMeasured when possible.
4236
+ function getLineContent(cm, lineView) {
4237
+ var ext = cm.display.externalMeasured;
4238
+ if (ext && ext.line == lineView.line) {
4239
+ cm.display.externalMeasured = null;
4240
+ lineView.measure = ext.measure;
4241
+ return ext.built
4242
+ }
4243
+ return buildLineContent(cm, lineView)
4244
+ }
4245
+
4246
+ // Redraw the line's text. Interacts with the background and text
4247
+ // classes because the mode may output tokens that influence these
4248
+ // classes.
4249
+ function updateLineText(cm, lineView) {
4250
+ var cls = lineView.text.className;
4251
+ var built = getLineContent(cm, lineView);
4252
+ if (lineView.text == lineView.node) { lineView.node = built.pre; }
4253
+ lineView.text.parentNode.replaceChild(built.pre, lineView.text);
4254
+ lineView.text = built.pre;
4255
+ if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) {
4256
+ lineView.bgClass = built.bgClass;
4257
+ lineView.textClass = built.textClass;
4258
+ updateLineClasses(cm, lineView);
4259
+ } else if (cls) {
4260
+ lineView.text.className = cls;
4261
+ }
4262
+ }
4263
+
4264
+ function updateLineClasses(cm, lineView) {
4265
+ updateLineBackground(cm, lineView);
4266
+ if (lineView.line.wrapClass)
4267
+ { ensureLineWrapped(lineView).className = lineView.line.wrapClass; }
4268
+ else if (lineView.node != lineView.text)
4269
+ { lineView.node.className = ""; }
4270
+ var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass;
4271
+ lineView.text.className = textClass || "";
4272
+ }
4273
+
4274
+ function updateLineGutter(cm, lineView, lineN, dims) {
4275
+ if (lineView.gutter) {
4276
+ lineView.node.removeChild(lineView.gutter);
4277
+ lineView.gutter = null;
4278
+ }
4279
+ if (lineView.gutterBackground) {
4280
+ lineView.node.removeChild(lineView.gutterBackground);
4281
+ lineView.gutterBackground = null;
4282
+ }
4283
+ if (lineView.line.gutterClass) {
4284
+ var wrap = ensureLineWrapped(lineView);
4285
+ lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass,
4286
+ ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px; width: " + (dims.gutterTotalWidth) + "px"));
4287
+ cm.display.input.setUneditable(lineView.gutterBackground);
4288
+ wrap.insertBefore(lineView.gutterBackground, lineView.text);
4289
+ }
4290
+ var markers = lineView.line.gutterMarkers;
4291
+ if (cm.options.lineNumbers || markers) {
4292
+ var wrap$1 = ensureLineWrapped(lineView);
4293
+ var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"));
4294
+ cm.display.input.setUneditable(gutterWrap);
4295
+ wrap$1.insertBefore(gutterWrap, lineView.text);
4296
+ if (lineView.line.gutterClass)
4297
+ { gutterWrap.className += " " + lineView.line.gutterClass; }
4298
+ if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
4299
+ { lineView.lineNumber = gutterWrap.appendChild(
4300
+ elt("div", lineNumberFor(cm.options, lineN),
4301
+ "CodeMirror-linenumber CodeMirror-gutter-elt",
4302
+ ("left: " + (dims.gutterLeft["CodeMirror-linenumbers"]) + "px; width: " + (cm.display.lineNumInnerWidth) + "px"))); }
4303
+ if (markers) { for (var k = 0; k < cm.options.gutters.length; ++k) {
4304
+ var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
4305
+ if (found)
4306
+ { gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt",
4307
+ ("left: " + (dims.gutterLeft[id]) + "px; width: " + (dims.gutterWidth[id]) + "px"))); }
4308
+ } }
4309
  }
4310
+ }
4311
+
4312
+ function updateLineWidgets(cm, lineView, dims) {
4313
+ if (lineView.alignable) { lineView.alignable = null; }
4314
+ for (var node = lineView.node.firstChild, next = (void 0); node; node = next) {
4315
+ next = node.nextSibling;
4316
+ if (node.className == "CodeMirror-linewidget")
4317
+ { lineView.node.removeChild(node); }
4318
  }
4319
+ insertLineWidgets(cm, lineView, dims);
4320
  }
4321
+
4322
+ // Build a line's DOM representation from scratch
4323
+ function buildLineElement(cm, lineView, lineN, dims) {
4324
+ var built = getLineContent(cm, lineView);
4325
+ lineView.text = lineView.node = built.pre;
4326
+ if (built.bgClass) { lineView.bgClass = built.bgClass; }
4327
+ if (built.textClass) { lineView.textClass = built.textClass; }
4328
+
4329
+ updateLineClasses(cm, lineView);
4330
+ updateLineGutter(cm, lineView, lineN, dims);
4331
+ insertLineWidgets(cm, lineView, dims);
4332
+ return lineView.node
4333
  }
 
4334
 
4335
+ // A lineView may contain multiple logical lines (when merged by
4336
+ // collapsed spans). The widgets for all of them need to be drawn.
4337
+ function insertLineWidgets(cm, lineView, dims) {
4338
+ insertLineWidgetsFor(cm, lineView.line, lineView, dims, true);
4339
+ if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++)
4340
+ { insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false); } }
4341
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4342
 
4343
+ function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) {
4344
+ if (!line.widgets) { return }
4345
+ var wrap = ensureLineWrapped(lineView);
4346
+ for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
4347
+ var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
4348
+ if (!widget.handleMouseEvents) { node.setAttribute("cm-ignore-events", "true"); }
4349
+ positionLineWidget(widget, node, lineView, dims);
4350
+ cm.display.input.setUneditable(node);
4351
+ if (allowAbove && widget.above)
4352
+ { wrap.insertBefore(node, lineView.gutter || lineView.text); }
4353
+ else
4354
+ { wrap.appendChild(node); }
4355
+ signalLater(widget, "redraw");
4356
+ }
4357
+ }
4358
+
4359
+ function positionLineWidget(widget, node, lineView, dims) {
4360
+ if (widget.noHScroll) {
4361
+ (lineView.alignable || (lineView.alignable = [])).push(node);
4362
+ var width = dims.wrapperWidth;
4363
+ node.style.left = dims.fixedPos + "px";
4364
+ if (!widget.coverGutter) {
4365
+ width -= dims.gutterTotalWidth;
4366
+ node.style.paddingLeft = dims.gutterTotalWidth + "px";
4367
+ }
4368
+ node.style.width = width + "px";
4369
+ }
4370
+ if (widget.coverGutter) {
4371
+ node.style.zIndex = 5;
4372
+ node.style.position = "relative";
4373
+ if (!widget.noHScroll) { node.style.marginLeft = -dims.gutterTotalWidth + "px"; }
4374
+ }
4375
+ }
4376
+
4377
+ function widgetHeight(widget) {
4378
+ if (widget.height != null) { return widget.height }
4379
+ var cm = widget.doc.cm;
4380
+ if (!cm) { return 0 }
4381
+ if (!contains(document.body, widget.node)) {
4382
+ var parentStyle = "position: relative;";
4383
+ if (widget.coverGutter)
4384
+ { parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;"; }
4385
+ if (widget.noHScroll)
4386
+ { parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;"; }
4387
+ removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle));
4388
+ }
4389
+ return widget.height = widget.node.parentNode.offsetHeight
4390
+ }
4391
+
4392
+ // Return true when the given mouse event happened in a widget
4393
+ function eventInWidget(display, e) {
4394
+ for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
4395
+ if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") ||
4396
+ (n.parentNode == display.sizer && n != display.mover))
4397
+ { return true }
4398
+ }
4399
+ }
4400
+
4401
+ // POSITION MEASUREMENT
4402
+
4403
+ function paddingTop(display) {return display.lineSpace.offsetTop}
4404
+ function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight}
4405
+ function paddingH(display) {
4406
+ if (display.cachedPaddingH) { return display.cachedPaddingH }
4407
+ var e = removeChildrenAndAdd(display.measure, elt("pre", "x"));
4408
+ var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle;
4409
+ var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)};
4410
+ if (!isNaN(data.left) && !isNaN(data.right)) { display.cachedPaddingH = data; }
4411
+ return data
4412
+ }
4413
+
4414
+ function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth }
4415
+ function displayWidth(cm) {
4416
+ return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth
4417
+ }
4418
+ function displayHeight(cm) {
4419
+ return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight
4420
+ }
4421
+
4422
+ // Ensure the lineView.wrapping.heights array is populated. This is
4423
+ // an array of bottom offsets for the lines that make up a drawn
4424
+ // line. When lineWrapping is on, there might be more than one
4425
+ // height.
4426
+ function ensureLineHeights(cm, lineView, rect) {
4427
+ var wrapping = cm.options.lineWrapping;
4428
+ var curWidth = wrapping && displayWidth(cm);
4429
+ if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) {
4430
+ var heights = lineView.measure.heights = [];
4431
+ if (wrapping) {
4432
+ lineView.measure.width = curWidth;
4433
+ var rects = lineView.text.firstChild.getClientRects();
4434
+ for (var i = 0; i < rects.length - 1; i++) {
4435
+ var cur = rects[i], next = rects[i + 1];
4436
+ if (Math.abs(cur.bottom - next.bottom) > 2)
4437
+ { heights.push((cur.bottom + next.top) / 2 - rect.top); }
4438
+ }
4439
+ }
4440
+ heights.push(rect.bottom - rect.top);
4441
+ }
4442
+ }
4443
+
4444
+ // Find a line map (mapping character offsets to text nodes) and a
4445
+ // measurement cache for the given line number. (A line view might
4446
+ // contain multiple lines when collapsed ranges are present.)
4447
+ function mapFromLineView(lineView, line, lineN) {
4448
+ if (lineView.line == line)
4449
+ { return {map: lineView.measure.map, cache: lineView.measure.cache} }
4450
+ for (var i = 0; i < lineView.rest.length; i++)
4451
+ { if (lineView.rest[i] == line)
4452
+ { return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]} } }
4453
+ for (var i$1 = 0; i$1 < lineView.rest.length; i$1++)
4454
+ { if (lineNo(lineView.rest[i$1]) > lineN)
4455
+ { return {map: lineView.measure.maps[i$1], cache: lineView.measure.caches[i$1], before: true} } }
4456
+ }
4457
+
4458
+ // Render a line into the hidden node display.externalMeasured. Used
4459
+ // when measurement is needed for a line that's not in the viewport.
4460
+ function updateExternalMeasurement(cm, line) {
4461
+ line = visualLine(line);
4462
+ var lineN = lineNo(line);
4463
+ var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN);
4464
+ view.lineN = lineN;
4465
+ var built = view.built = buildLineContent(cm, view);
4466
+ view.text = built.pre;
4467
+ removeChildrenAndAdd(cm.display.lineMeasure, built.pre);
4468
+ return view
4469
+ }
4470
+
4471
+ // Get a {top, bottom, left, right} box (in line-local coordinates)
4472
+ // for a given character.
4473
+ function measureChar(cm, line, ch, bias) {
4474
+ return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias)
4475
+ }
4476
+
4477
+ // Find a line view that corresponds to the given line number.
4478
+ function findViewForLine(cm, lineN) {
4479
+ if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo)
4480
+ { return cm.display.view[findViewIndex(cm, lineN)] }
4481
+ var ext = cm.display.externalMeasured;
4482
+ if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size)
4483
+ { return ext }
4484
+ }
4485
+
4486
+ // Measurement can be split in two steps, the set-up work that
4487
+ // applies to the whole line, and the measurement of the actual
4488
+ // character. Functions like coordsChar, that need to do a lot of
4489
+ // measurements in a row, can thus ensure that the set-up work is
4490
+ // only done once.
4491
+ function prepareMeasureForLine(cm, line) {
4492
+ var lineN = lineNo(line);
4493
+ var view = findViewForLine(cm, lineN);
4494
+ if (view && !view.text) {
4495
+ view = null;
4496
+ } else if (view && view.changes) {
4497
+ updateLineForChanges(cm, view, lineN, getDimensions(cm));
4498
+ cm.curOp.forceUpdate = true;
4499
+ }
4500
+ if (!view)
4501
+ { view = updateExternalMeasurement(cm, line); }
4502
 
4503
+ var info = mapFromLineView(view, line, lineN);
4504
+ return {
4505
+ line: line, view: view, rect: null,
4506
+ map: info.map, cache: info.cache, before: info.before,
4507
+ hasHeights: false
4508
+ }
4509
+ }
4510
 
4511
+ // Given a prepared measurement object, measures the position of an
4512
+ // actual character (or fetches it from the cache).
4513
+ function measureCharPrepared(cm, prepared, ch, bias, varHeight) {
4514
+ if (prepared.before) { ch = -1; }
4515
+ var key = ch + (bias || ""), found;
4516
+ if (prepared.cache.hasOwnProperty(key)) {
4517
+ found = prepared.cache[key];
4518
+ } else {
4519
+ if (!prepared.rect)
4520
+ { prepared.rect = prepared.view.text.getBoundingClientRect(); }
4521
+ if (!prepared.hasHeights) {
4522
+ ensureLineHeights(cm, prepared.view, prepared.rect);
4523
+ prepared.hasHeights = true;
4524
+ }
4525
+ found = measureCharInner(cm, prepared, ch, bias);
4526
+ if (!found.bogus) { prepared.cache[key] = found; }
4527
+ }
4528
+ return {left: found.left, right: found.right,
4529
+ top: varHeight ? found.rtop : found.top,
4530
+ bottom: varHeight ? found.rbottom : found.bottom}
4531
+ }
4532
+
4533
+ var nullRect = {left: 0, right: 0, top: 0, bottom: 0};
4534
+
4535
+ function nodeAndOffsetInLineMap(map$$1, ch, bias) {
4536
+ var node, start, end, collapse, mStart, mEnd;
4537
+ // First, search the line map for the text node corresponding to,
4538
+ // or closest to, the target character.
4539
+ for (var i = 0; i < map$$1.length; i += 3) {
4540
+ mStart = map$$1[i];
4541
+ mEnd = map$$1[i + 1];
4542
+ if (ch < mStart) {
4543
+ start = 0; end = 1;
4544
+ collapse = "left";
4545
+ } else if (ch < mEnd) {
4546
+ start = ch - mStart;
4547
+ end = start + 1;
4548
+ } else if (i == map$$1.length - 3 || ch == mEnd && map$$1[i + 3] > ch) {
4549
+ end = mEnd - mStart;
4550
+ start = end - 1;
4551
+ if (ch >= mEnd) { collapse = "right"; }
4552
+ }
4553
+ if (start != null) {
4554
+ node = map$$1[i + 2];
4555
+ if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right"))
4556
+ { collapse = bias; }
4557
+ if (bias == "left" && start == 0)
4558
+ { while (i && map$$1[i - 2] == map$$1[i - 3] && map$$1[i - 1].insertLeft) {
4559
+ node = map$$1[(i -= 3) + 2];
4560
+ collapse = "left";
4561
+ } }
4562
+ if (bias == "right" && start == mEnd - mStart)
4563
+ { while (i < map$$1.length - 3 && map$$1[i + 3] == map$$1[i + 4] && !map$$1[i + 5].insertLeft) {
4564
+ node = map$$1[(i += 3) + 2];
4565
+ collapse = "right";
4566
+ } }
4567
+ break
4568
+ }
4569
+ }
4570
+ return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd}
4571
+ }
4572
 
4573
+ function getUsefulRect(rects, bias) {
4574
+ var rect = nullRect;
4575
+ if (bias == "left") { for (var i = 0; i < rects.length; i++) {
4576
+ if ((rect = rects[i]).left != rect.right) { break }
4577
+ } } else { for (var i$1 = rects.length - 1; i$1 >= 0; i$1--) {
4578
+ if ((rect = rects[i$1]).left != rect.right) { break }
4579
+ } }
4580
+ return rect
4581
+ }
 
 
 
 
 
 
 
4582
 
4583
+ function measureCharInner(cm, prepared, ch, bias) {
4584
+ var place = nodeAndOffsetInLineMap(prepared.map, ch, bias);
4585
+ var node = place.node, start = place.start, end = place.end, collapse = place.collapse;
 
 
4586
 
4587
+ var rect;
4588
+ if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates.
4589
+ for (var i$1 = 0; i$1 < 4; i$1++) { // Retry a maximum of 4 times when nonsense rectangles are returned
4590
+ while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) { --start; }
4591
+ while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) { ++end; }
4592
+ if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart)
4593
+ { rect = node.parentNode.getBoundingClientRect(); }
4594
+ else
4595
+ { rect = getUsefulRect(range(node, start, end).getClientRects(), bias); }
4596
+ if (rect.left || rect.right || start == 0) { break }
4597
+ end = start;
4598
+ start = start - 1;
4599
+ collapse = "right";
4600
+ }
4601
+ if (ie && ie_version < 11) { rect = maybeUpdateRectForZooming(cm.display.measure, rect); }
4602
+ } else { // If it is a widget, simply get the box for the whole widget.
4603
+ if (start > 0) { collapse = bias = "right"; }
4604
+ var rects;
4605
+ if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1)
4606
+ { rect = rects[bias == "right" ? rects.length - 1 : 0]; }
4607
+ else
4608
+ { rect = node.getBoundingClientRect(); }
4609
+ }
4610
+ if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) {
4611
+ var rSpan = node.parentNode.getClientRects()[0];
4612
+ if (rSpan)
4613
+ { rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom}; }
4614
+ else
4615
+ { rect = nullRect; }
4616
+ }
4617
+
4618
+ var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top;
4619
+ var mid = (rtop + rbot) / 2;
4620
+ var heights = prepared.view.measure.heights;
4621
+ var i = 0;
4622
+ for (; i < heights.length - 1; i++)
4623
+ { if (mid < heights[i]) { break } }
4624
+ var top = i ? heights[i - 1] : 0, bot = heights[i];
4625
+ var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left,
4626
+ right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left,
4627
+ top: top, bottom: bot};
4628
+ if (!rect.left && !rect.right) { result.bogus = true; }
4629
+ if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; }
4630
+
4631
+ return result
4632
+ }
4633
 
4634
+ // Work around problem with bounding client rects on ranges being
4635
+ // returned incorrectly when zoomed on IE10 and below.
4636
+ function maybeUpdateRectForZooming(measure, rect) {
4637
+ if (!window.screen || screen.logicalXDPI == null ||
4638
+ screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure))
4639
+ { return rect }
4640
+ var scaleX = screen.logicalXDPI / screen.deviceXDPI;
4641
+ var scaleY = screen.logicalYDPI / screen.deviceYDPI;
4642
+ return {left: rect.left * scaleX, right: rect.right * scaleX,
4643
+ top: rect.top * scaleY, bottom: rect.bottom * scaleY}
4644
+ }
4645
+
4646
+ function clearLineMeasurementCacheFor(lineView) {
4647
+ if (lineView.measure) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4648
  lineView.measure.cache = {};
4649
+ lineView.measure.heights = null;
4650
+ if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++)
4651
+ { lineView.measure.caches[i] = {}; } }
4652
  }
4653
  }
4654
 
4655
+ function clearLineMeasurementCache(cm) {
4656
+ cm.display.externalMeasure = null;
4657
+ removeChildren(cm.display.lineMeasure);
4658
+ for (var i = 0; i < cm.display.view.length; i++)
4659
+ { clearLineMeasurementCacheFor(cm.display.view[i]); }
4660
  }
4661
 
4662
+ function clearCaches(cm) {
4663
+ clearLineMeasurementCache(cm);
4664
+ cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null;
4665
+ if (!cm.options.lineWrapping) { cm.display.maxLineChanged = true; }
4666
+ cm.display.lineNumChars = null;
4667
+ }
4668
 
4669
+ function pageScrollX() {
4670
+ // Work around https://bugs.chromium.org/p/chromium/issues/detail?id=489206
4671
+ // which causes page_Offset and bounding client rects to use
4672
+ // different reference viewports and invalidate our calculations.
4673
+ if (chrome && android) { return -(document.body.getBoundingClientRect().left - parseInt(getComputedStyle(document.body).marginLeft)) }
4674
+ return window.pageXOffset || (document.documentElement || document.body).scrollLeft
4675
+ }
4676
+ function pageScrollY() {
4677
+ if (chrome && android) { return -(document.body.getBoundingClientRect().top - parseInt(getComputedStyle(document.body).marginTop)) }
4678
+ return window.pageYOffset || (document.documentElement || document.body).scrollTop
4679
+ }
4680
 
4681
+ function widgetTopHeight(lineObj) {
4682
+ var height = 0;
4683
+ if (lineObj.widgets) { for (var i = 0; i < lineObj.widgets.length; ++i) { if (lineObj.widgets[i].above)
4684
+ { height += widgetHeight(lineObj.widgets[i]); } } }
4685
+ return height
4686
+ }
4687
+
4688
+ // Converts a {top, bottom, left, right} box from line-local
4689
+ // coordinates into another coordinate system. Context may be one of
4690
+ // "line", "div" (display.lineDiv), "local"./null (editor), "window",
4691
+ // or "page".
4692
+ function intoCoordSystem(cm, lineObj, rect, context, includeWidgets) {
4693
+ if (!includeWidgets) {
4694
+ var height = widgetTopHeight(lineObj);
4695
+ rect.top += height; rect.bottom += height;
4696
+ }
4697
+ if (context == "line") { return rect }
4698
+ if (!context) { context = "local"; }
4699
+ var yOff = heightAtLine(lineObj);
4700
+ if (context == "local") { yOff += paddingTop(cm.display); }
4701
+ else { yOff -= cm.display.viewOffset; }
4702
+ if (context == "page" || context == "window") {
4703
+ var lOff = cm.display.lineSpace.getBoundingClientRect();
4704
+ yOff += lOff.top + (context == "window" ? 0 : pageScrollY());
4705
+ var xOff = lOff.left + (context == "window" ? 0 : pageScrollX());
4706
+ rect.left += xOff; rect.right += xOff;
4707
+ }
4708
+ rect.top += yOff; rect.bottom += yOff;
4709
+ return rect
4710
+ }
4711
+
4712
+ // Coverts a box from "div" coords to another coordinate system.
4713
+ // Context may be "window", "page", "div", or "local"./null.
4714
+ function fromCoordSystem(cm, coords, context) {
4715
+ if (context == "div") { return coords }
4716
+ var left = coords.left, top = coords.top;
4717
+ // First move into "page" coordinate system
4718
+ if (context == "page") {
4719
+ left -= pageScrollX();
4720
+ top -= pageScrollY();
4721
+ } else if (context == "local" || !context) {
4722
+ var localBox = cm.display.sizer.getBoundingClientRect();
4723
+ left += localBox.left;
4724
+ top += localBox.top;
4725
+ }
4726
+
4727
+ var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect();
4728
+ return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top}
4729
+ }
4730
+
4731
+ function charCoords(cm, pos, context, lineObj, bias) {
4732
+ if (!lineObj) { lineObj = getLine(cm.doc, pos.line); }
4733
+ return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context)
4734
+ }
4735
+
4736
+ // Returns a box for a given cursor position, which may have an
4737
+ // 'other' property containing the position of the secondary cursor
4738
+ // on a bidi boundary.
4739
+ // A cursor Pos(line, char, "before") is on the same visual line as `char - 1`
4740
+ // and after `char - 1` in writing order of `char - 1`
4741
+ // A cursor Pos(line, char, "after") is on the same visual line as `char`
4742
+ // and before `char` in writing order of `char`
4743
+ // Examples (upper-case letters are RTL, lower-case are LTR):
4744
+ // Pos(0, 1, ...)
4745
+ // before after
4746
+ // ab a|b a|b
4747
+ // aB a|B aB|
4748
+ // Ab |Ab A|b
4749
+ // AB B|A B|A
4750
+ // Every position after the last character on a line is considered to stick
4751
+ // to the last character on the line.
4752
+ function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) {
4753
+ lineObj = lineObj || getLine(cm.doc, pos.line);
4754
+ if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj); }
4755
+ function get(ch, right) {
4756
+ var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight);
4757
+ if (right) { m.left = m.right; } else { m.right = m.left; }
4758
+ return intoCoordSystem(cm, lineObj, m, context)
4759
+ }
4760
+ var order = getOrder(lineObj, cm.doc.direction), ch = pos.ch, sticky = pos.sticky;
4761
+ if (ch >= lineObj.text.length) {
4762
+ ch = lineObj.text.length;
4763
+ sticky = "before";
4764
+ } else if (ch <= 0) {
4765
+ ch = 0;
4766
+ sticky = "after";
4767
+ }
4768
+ if (!order) { return get(sticky == "before" ? ch - 1 : ch, sticky == "before") }
4769
+
4770
+ function getBidi(ch, partPos, invert) {
4771
+ var part = order[partPos], right = part.level == 1;
4772
+ return get(invert ? ch - 1 : ch, right != invert)
4773
+ }
4774
+ var partPos = getBidiPartAt(order, ch, sticky);
4775
+ var other = bidiOther;
4776
+ var val = getBidi(ch, partPos, sticky == "before");
4777
+ if (other != null) { val.other = getBidi(ch, other, sticky != "before"); }
4778
+ return val
4779
+ }
4780
+
4781
+ // Used to cheaply estimate the coordinates for a position. Used for
4782
+ // intermediate scroll updates.
4783
+ function estimateCoords(cm, pos) {
4784
+ var left = 0;
4785
+ pos = clipPos(cm.doc, pos);
4786
+ if (!cm.options.lineWrapping) { left = charWidth(cm.display) * pos.ch; }
4787
+ var lineObj = getLine(cm.doc, pos.line);
4788
+ var top = heightAtLine(lineObj) + paddingTop(cm.display);
4789
+ return {left: left, right: left, top: top, bottom: top + lineObj.height}
4790
+ }
4791
+
4792
+ // Positions returned by coordsChar contain some extra information.
4793
+ // xRel is the relative x position of the input coordinates compared
4794
+ // to the found position (so xRel > 0 means the coordinates are to
4795
+ // the right of the character position, for example). When outside
4796
+ // is true, that means the coordinates lie outside the line's
4797
+ // vertical range.
4798
+ function PosWithInfo(line, ch, sticky, outside, xRel) {
4799
+ var pos = Pos(line, ch, sticky);
4800
+ pos.xRel = xRel;
4801
+ if (outside) { pos.outside = true; }
4802
+ return pos
4803
+ }
4804
 
4805
+ // Compute the character position closest to the given coordinates.
4806
+ // Input must be lineSpace-local ("div" coordinate system).
4807
+ function coordsChar(cm, x, y) {
4808
+ var doc = cm.doc;
4809
+ y += cm.display.viewOffset;
4810
+ if (y < 0) { return PosWithInfo(doc.first, 0, null, true, -1) }
4811
+ var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
4812
+ if (lineN > last)
4813
+ { return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, null, true, 1) }
4814
+ if (x < 0) { x = 0; }
 
 
4815
 
4816
+ var lineObj = getLine(doc, lineN);
 
 
 
 
 
4817
  for (;;) {
4818
+ var found = coordsCharInner(cm, lineObj, lineN, x, y);
4819
+ var collapsed = collapsedSpanAround(lineObj, found.ch + (found.xRel > 0 ? 1 : 0));
4820
+ if (!collapsed) { return found }
4821
+ var rangeEnd = collapsed.find(1);
4822
+ if (rangeEnd.line == lineN) { return rangeEnd }
4823
+ lineObj = getLine(doc, lineN = rangeEnd.line);
 
 
 
 
 
4824
  }
4825
  }
 
4826
 
4827
+ function wrappedLineExtent(cm, lineObj, preparedMeasure, y) {
4828
+ y -= widgetTopHeight(lineObj);
4829
+ var end = lineObj.text.length;
4830
+ var begin = findFirst(function (ch) { return measureCharPrepared(cm, preparedMeasure, ch - 1).bottom <= y; }, end, 0);
4831
+ end = findFirst(function (ch) { return measureCharPrepared(cm, preparedMeasure, ch).top > y; }, begin, end);
4832
+ return {begin: begin, end: end}
 
4833
  }
4834
+
4835
+ function wrappedLineExtentChar(cm, lineObj, preparedMeasure, target) {
4836
+ if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj); }
4837
+ var targetTop = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, target), "line").top;
4838
+ return wrappedLineExtent(cm, lineObj, preparedMeasure, targetTop)
4839
  }
 
 
 
4840
 
4841
+ // Returns true if the given side of a box is after the given
4842
+ // coordinates, in top-to-bottom, left-to-right order.
4843
+ function boxIsAfter(box, x, y, left) {
4844
+ return box.bottom <= y ? false : box.top > y ? true : (left ? box.left : box.right) > x
4845
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4846
 
4847
+ function coordsCharInner(cm, lineObj, lineNo$$1, x, y) {
4848
+ // Move y into line-local coordinate space
4849
+ y -= heightAtLine(lineObj);
4850
+ var preparedMeasure = prepareMeasureForLine(cm, lineObj);
4851
+ // When directly calling `measureCharPrepared`, we have to adjust
4852
+ // for the widgets at this line.
4853
+ var widgetHeight$$1 = widgetTopHeight(lineObj);
4854
+ var begin = 0, end = lineObj.text.length, ltr = true;
4855
+
4856
+ var order = getOrder(lineObj, cm.doc.direction);
4857
+ // If the line isn't plain left-to-right text, first figure out
4858
+ // which bidi section the coordinates fall into.
4859
+ if (order) {
4860
+ var part = (cm.options.lineWrapping ? coordsBidiPartWrapped : coordsBidiPart)
4861
+ (cm, lineObj, lineNo$$1, preparedMeasure, order, x, y);
4862
+ ltr = part.level != 1;
4863
+ // The awkward -1 offsets are needed because findFirst (called
4864
+ // on these below) will treat its first bound as inclusive,
4865
+ // second as exclusive, but we want to actually address the
4866
+ // characters in the part's range
4867
+ begin = ltr ? part.from : part.to - 1;
4868
+ end = ltr ? part.to : part.from - 1;
4869
+ }
4870
+
4871
+ // A binary search to find the first character whose bounding box
4872
+ // starts after the coordinates. If we run across any whose box wrap
4873
+ // the coordinates, store that.
4874
+ var chAround = null, boxAround = null;
4875
+ var ch = findFirst(function (ch) {
4876
+ var box = measureCharPrepared(cm, preparedMeasure, ch);
4877
+ box.top += widgetHeight$$1; box.bottom += widgetHeight$$1;
4878
+ if (!boxIsAfter(box, x, y, false)) { return false }
4879
+ if (box.top <= y && box.left <= x) {
4880
+ chAround = ch;
4881
+ boxAround = box;
4882
+ }
4883
+ return true
4884
+ }, begin, end);
4885
+
4886
+ var baseX, sticky, outside = false;
4887
+ // If a box around the coordinates was found, use that
4888
+ if (boxAround) {
4889
+ // Distinguish coordinates nearer to the left or right side of the box
4890
+ var atLeft = x - boxAround.left < boxAround.right - x, atStart = atLeft == ltr;
4891
+ ch = chAround + (atStart ? 0 : 1);
4892
+ sticky = atStart ? "after" : "before";
4893
+ baseX = atLeft ? boxAround.left : boxAround.right;
4894
+ } else {
4895
+ // (Adjust for extended bound, if necessary.)
4896
+ if (!ltr && (ch == end || ch == begin)) { ch++; }
4897
+ // To determine which side to associate with, get the box to the
4898
+ // left of the character and compare it's vertical position to the
4899
+ // coordinates
4900
+ sticky = ch == 0 ? "after" : ch == lineObj.text.length ? "before" :
4901
+ (measureCharPrepared(cm, preparedMeasure, ch - (ltr ? 1 : 0)).bottom + widgetHeight$$1 <= y) == ltr ?
4902
+ "after" : "before";
4903
+ // Now get accurate coordinates for this place, in order to get a
4904
+ // base X position
4905
+ var coords = cursorCoords(cm, Pos(lineNo$$1, ch, sticky), "line", lineObj, preparedMeasure);
4906
+ baseX = coords.left;
4907
+ outside = y < coords.top || y >= coords.bottom;
4908
+ }
4909
+
4910
+ ch = skipExtendingChars(lineObj.text, ch, 1);
4911
+ return PosWithInfo(lineNo$$1, ch, sticky, outside, x - baseX)
4912
+ }
4913
+
4914
+ function coordsBidiPart(cm, lineObj, lineNo$$1, preparedMeasure, order, x, y) {
4915
+ // Bidi parts are sorted left-to-right, and in a non-line-wrapping
4916
+ // situation, we can take this ordering to correspond to the visual
4917
+ // ordering. This finds the first part whose end is after the given
4918
+ // coordinates.
4919
+ var index = findFirst(function (i) {
4920
+ var part = order[i], ltr = part.level != 1;
4921
+ return boxIsAfter(cursorCoords(cm, Pos(lineNo$$1, ltr ? part.to : part.from, ltr ? "before" : "after"),
4922
+ "line", lineObj, preparedMeasure), x, y, true)
4923
+ }, 0, order.length - 1);
4924
+ var part = order[index];
4925
+ // If this isn't the first part, the part's start is also after
4926
+ // the coordinates, and the coordinates aren't on the same line as
4927
+ // that start, move one part back.
4928
+ if (index > 0) {
4929
+ var ltr = part.level != 1;
4930
+ var start = cursorCoords(cm, Pos(lineNo$$1, ltr ? part.from : part.to, ltr ? "after" : "before"),
4931
+ "line", lineObj, preparedMeasure);
4932
+ if (boxIsAfter(start, x, y, true) && start.top > y)
4933
+ { part = order[index - 1]; }
4934
+ }
4935
+ return part
4936
+ }
4937
+
4938
+ function coordsBidiPartWrapped(cm, lineObj, _lineNo, preparedMeasure, order, x, y) {
4939
+ // In a wrapped line, rtl text on wrapping boundaries can do things
4940
+ // that don't correspond to the ordering in our `order` array at
4941
+ // all, so a binary search doesn't work, and we want to return a
4942
+ // part that only spans one line so that the binary search in
4943
+ // coordsCharInner is safe. As such, we first find the extent of the
4944
+ // wrapped line, and then do a flat search in which we discard any
4945
+ // spans that aren't on the line.
4946
+ var ref = wrappedLineExtent(cm, lineObj, preparedMeasure, y);
4947
+ var begin = ref.begin;
4948
+ var end = ref.end;
4949
+ if (/\s/.test(lineObj.text.charAt(end - 1))) { end--; }
4950
+ var part = null, closestDist = null;
4951
+ for (var i = 0; i < order.length; i++) {
4952
+ var p = order[i];
4953
+ if (p.from >= end || p.to <= begin) { continue }
4954
+ var ltr = p.level != 1;
4955
+ var endX = measureCharPrepared(cm, preparedMeasure, ltr ? Math.min(end, p.to) - 1 : Math.max(begin, p.from)).right;
4956
+ // Weigh against spans ending before this, so that they are only
4957
+ // picked if nothing ends after
4958
+ var dist = endX < x ? x - endX + 1e9 : endX - x;
4959
+ if (!part || closestDist > dist) {
4960
+ part = p;
4961
+ closestDist = dist;
4962
+ }
4963
+ }
4964
+ if (!part) { part = order[order.length - 1]; }
4965
+ // Clip the part to the wrapped line.
4966
+ if (part.from < begin) { part = {from: begin, to: part.to, level: part.level}; }
4967
+ if (part.to > end) { part = {from: part.from, to: end, level: part.level}; }
4968
+ return part
4969
+ }
4970
+
4971
+ var measureText;
4972
+ // Compute the default text height.
4973
+ function textHeight(display) {
4974
+ if (display.cachedTextHeight != null) { return display.cachedTextHeight }
4975
+ if (measureText == null) {
4976
+ measureText = elt("pre");
4977
+ // Measure a bunch of lines, for browsers that compute
4978
+ // fractional heights.
4979
+ for (var i = 0; i < 49; ++i) {
4980
+ measureText.appendChild(document.createTextNode("x"));
4981
+ measureText.appendChild(elt("br"));
4982
  }
4983
+ measureText.appendChild(document.createTextNode("x"));
4984
  }
4985
+ removeChildrenAndAdd(display.measure, measureText);
4986
+ var height = measureText.offsetHeight / 50;
4987
+ if (height > 3) { display.cachedTextHeight = height; }
4988
+ removeChildren(display.measure);
4989
+ return height || 1
4990
+ }
4991
+
4992
+ // Compute the default character width.
4993
+ function charWidth(display) {
4994
+ if (display.cachedCharWidth != null) { return display.cachedCharWidth }
4995
+ var anchor = elt("span", "xxxxxxxxxx");
4996
+ var pre = elt("pre", [anchor]);
4997
+ removeChildrenAndAdd(display.measure, pre);
4998
+ var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10;
4999
+ if (width > 2) { display.cachedCharWidth = width; }
5000
+ return width || 10
5001
+ }
5002
+
5003
+ // Do a bulk-read of the DOM positions and sizes needed to draw the
5004
+ // view, so that we don't interleave reading and writing to the DOM.
5005
+ function getDimensions(cm) {
5006
+ var d = cm.display, left = {}, width = {};
5007
+ var gutterLeft = d.gutters.clientLeft;
5008
+ for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
5009
+ left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft;
5010
+ width[cm.options.gutters[i]] = n.clientWidth;
5011
+ }
5012
+ return {fixedPos: compensateForHScroll(d),
5013
+ gutterTotalWidth: d.gutters.offsetWidth,
5014
+ gutterLeft: left,
5015
+ gutterWidth: width,
5016
+ wrapperWidth: d.wrapper.clientWidth}
5017
+ }
5018
+
5019
+ // Computes display.scroller.scrollLeft + display.gutters.offsetWidth,
5020
+ // but using getBoundingClientRect to get a sub-pixel-accurate
5021
+ // result.
5022
+ function compensateForHScroll(display) {
5023
+ return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left
5024
+ }
5025
+
5026
+ // Returns a function that estimates the height of a line, to use as
5027
+ // first approximation until the line becomes visible (and is thus
5028
+ // properly measurable).
5029
+ function estimateHeight(cm) {
5030
+ var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
5031
+ var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
5032
+ return function (line) {
5033
+ if (lineIsHidden(cm.doc, line)) { return 0 }
5034
+
5035
+ var widgetsHeight = 0;
5036
+ if (line.widgets) { for (var i = 0; i < line.widgets.length; i++) {
5037
+ if (line.widgets[i].height) { widgetsHeight += line.widgets[i].height; }
5038
+ } }
5039
 
5040
+ if (wrapping)
5041
+ { return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th }
5042
+ else
5043
+ { return widgetsHeight + th }
 
 
 
 
 
 
 
 
 
 
 
5044
  }
5045
  }
 
5046
 
5047
+ function estimateLineHeights(cm) {
5048
+ var doc = cm.doc, est = estimateHeight(cm);
5049
+ doc.iter(function (line) {
5050
+ var estHeight = est(line);
5051
+ if (estHeight != line.height) { updateLineHeight(line, estHeight); }
5052
+ });
5053
+ }
5054
 
5055
+ // Given a mouse event, find the corresponding position. If liberal
5056
+ // is false, it checks whether a gutter or scrollbar was clicked,
5057
+ // and returns null if it was. forRect is used by rectangular
5058
+ // selections, and tries to estimate a character position even for
5059
+ // coordinates beyond the right of the text.
5060
+ function posFromMouse(cm, e, liberal, forRect) {
5061
+ var display = cm.display;
5062
+ if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") { return null }
 
 
 
 
 
5063
 
5064
+ var x, y, space = display.lineSpace.getBoundingClientRect();
5065
+ // Fails unpredictably on IE[67] when mouse is dragged around quickly.
5066
+ try { x = e.clientX - space.left; y = e.clientY - space.top; }
5067
+ catch (e) { return null }
5068
+ var coords = coordsChar(cm, x, y), line;
5069
+ if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
5070
+ var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length;
5071
+ coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff));
5072
+ }
5073
+ return coords
5074
  }
 
 
5075
 
5076
+ // Find the view element corresponding to a given line. Return null
5077
+ // when the line isn't visible.
5078
+ function findViewIndex(cm, n) {
5079
+ if (n >= cm.display.viewTo) { return null }
5080
+ n -= cm.display.viewFrom;
5081
+ if (n < 0) { return null }
5082
+ var view = cm.display.view;
5083
+ for (var i = 0; i < view.length; i++) {
5084
+ n -= view[i].size;
5085
+ if (n < 0) { return i }
5086
+ }
5087
+ }
5088
 
5089
+ function updateSelection(cm) {
5090
+ cm.display.input.showSelection(cm.display.input.prepareSelection());
 
 
 
 
 
 
5091
  }
 
5092
 
5093
+ function prepareSelection(cm, primary) {
5094
+ if ( primary === void 0 ) primary = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
5095
 
5096
+ var doc = cm.doc, result = {};
5097
+ var curFragment = result.cursors = document.createDocumentFragment();
5098
+ var selFragment = result.selection = document.createDocumentFragment();
5099
 
5100
+ for (var i = 0; i < doc.sel.ranges.length; i++) {
5101
+ if (!primary && i == doc.sel.primIndex) { continue }
5102
+ var range$$1 = doc.sel.ranges[i];
5103
+ if (range$$1.from().line >= cm.display.viewTo || range$$1.to().line < cm.display.viewFrom) { continue }
5104
+ var collapsed = range$$1.empty();
5105
+ if (collapsed || cm.options.showCursorWhenSelecting)
5106
+ { drawSelectionCursor(cm, range$$1.head, curFragment); }
5107
+ if (!collapsed)
5108
+ { drawSelectionRange(cm, range$$1, selFragment); }
5109
+ }
5110
+ return result
5111
  }
 
5112
 
5113
+ // Draws a cursor for the given range
5114
+ function drawSelectionCursor(cm, head, output) {
5115
+ var pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine);
5116
+
5117
+ var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor"));
5118
+ cursor.style.left = pos.left + "px";
5119
+ cursor.style.top = pos.top + "px";
5120
+ cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
5121
+
5122
+ if (pos.other) {
5123
+ // Secondary cursor, shown when on a 'jump' in bi-directional text
5124
+ var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor"));
5125
+ otherCursor.style.display = "";
5126
+ otherCursor.style.left = pos.other.left + "px";
5127
+ otherCursor.style.top = pos.other.top + "px";
5128
+ otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
5129
+ }
5130
+ }
5131
+
5132
+ function cmpCoords(a, b) { return a.top - b.top || a.left - b.left }
5133
+
5134
+ // Draws the given range as a highlighted selection
5135
+ function drawSelectionRange(cm, range$$1, output) {
5136
+ var display = cm.display, doc = cm.doc;
5137
+ var fragment = document.createDocumentFragment();
5138
+ var padding = paddingH(cm.display), leftSide = padding.left;
5139
+ var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right;
5140
+ var docLTR = doc.direction == "ltr";
5141
+
5142
+ function add(left, top, width, bottom) {
5143
+ if (top < 0) { top = 0; }
5144
+ top = Math.round(top);
5145
+ bottom = Math.round(bottom);
5146
+ fragment.appendChild(elt("div", null, "CodeMirror-selected", ("position: absolute; left: " + left + "px;\n top: " + top + "px; width: " + (width == null ? rightSide - left : width) + "px;\n height: " + (bottom - top) + "px")));
5147
+ }
5148
+
5149
+ function drawForLine(line, fromArg, toArg) {
5150
+ var lineObj = getLine(doc, line);
5151
+ var lineLen = lineObj.text.length;
5152
+ var start, end;
5153
+ function coords(ch, bias) {
5154
+ return charCoords(cm, Pos(line, ch), "div", lineObj, bias)
5155
+ }
5156
+
5157
+ function wrapX(pos, dir, side) {
5158
+ var extent = wrappedLineExtentChar(cm, lineObj, null, pos);
5159
+ var prop = (dir == "ltr") == (side == "after") ? "left" : "right";
5160
+ var ch = side == "after" ? extent.begin : extent.end - (/\s/.test(lineObj.text.charAt(extent.end - 1)) ? 2 : 1);
5161
+ return coords(ch, prop)[prop]
5162
+ }
5163
+
5164
+ var order = getOrder(lineObj, doc.direction);
5165
+ iterateBidiSections(order, fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir, i) {
5166
+ var ltr = dir == "ltr";
5167
+ var fromPos = coords(from, ltr ? "left" : "right");
5168
+ var toPos = coords(to - 1, ltr ? "right" : "left");
5169
+
5170
+ var openStart = fromArg == null && from == 0, openEnd = toArg == null && to == lineLen;
5171
+ var first = i == 0, last = !order || i == order.length - 1;
5172
+ if (toPos.top - fromPos.top <= 3) { // Single line
5173
+ var openLeft = (docLTR ? openStart : openEnd) && first;
5174
+ var openRight = (docLTR ? openEnd : openStart) && last;
5175
+ var left = openLeft ? leftSide : (ltr ? fromPos : toPos).left;
5176
+ var right = openRight ? rightSide : (ltr ? toPos : fromPos).right;
5177
+ add(left, fromPos.top, right - left, fromPos.bottom);
5178
+ } else { // Multiple lines
5179
+ var topLeft, topRight, botLeft, botRight;
5180
+ if (ltr) {
5181
+ topLeft = docLTR && openStart && first ? leftSide : fromPos.left;
5182
+ topRight = docLTR ? rightSide : wrapX(from, dir, "before");
5183
+ botLeft = docLTR ? leftSide : wrapX(to, dir, "after");
5184
+ botRight = docLTR && openEnd && last ? rightSide : toPos.right;
5185
+ } else {
5186
+ topLeft = !docLTR ? leftSide : wrapX(from, dir, "before");
5187
+ topRight = !docLTR && openStart && first ? rightSide : fromPos.right;
5188
+ botLeft = !docLTR && openEnd && last ? leftSide : toPos.left;
5189
+ botRight = !docLTR ? rightSide : wrapX(to, dir, "after");
5190
+ }
5191
+ add(topLeft, fromPos.top, topRight - topLeft, fromPos.bottom);
5192
+ if (fromPos.bottom < toPos.top) { add(leftSide, fromPos.bottom, null, toPos.top); }
5193
+ add(botLeft, toPos.top, botRight - botLeft, toPos.bottom);
5194
+ }
5195
 
5196
+ if (!start || cmpCoords(fromPos, start) < 0) { start = fromPos; }
5197
+ if (cmpCoords(toPos, start) < 0) { start = toPos; }
5198
+ if (!end || cmpCoords(fromPos, end) < 0) { end = fromPos; }
5199
+ if (cmpCoords(toPos, end) < 0) { end = toPos; }
5200
+ });
5201
+ return {start: start, end: end}
5202
+ }
5203
 
5204
+ var sFrom = range$$1.from(), sTo = range$$1.to();
5205
+ if (sFrom.line == sTo.line) {
5206
+ drawForLine(sFrom.line, sFrom.ch, sTo.ch);
5207
+ } else {
5208
+ var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line);
5209
+ var singleVLine = visualLine(fromLine) == visualLine(toLine);
5210
+ var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end;
5211
+ var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start;
5212
+ if (singleVLine) {
5213
+ if (leftEnd.top < rightStart.top - 2) {
5214
+ add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);
5215
+ add(leftSide, rightStart.top, rightStart.left, rightStart.bottom);
5216
+ } else {
5217
+ add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);
5218
+ }
5219
+ }
5220
+ if (leftEnd.bottom < rightStart.top)
5221
+ { add(leftSide, leftEnd.bottom, null, rightStart.top); }
5222
+ }
5223
 
5224
+ output.appendChild(fragment);
5225
+ }
 
 
 
 
 
 
 
 
 
 
5226
 
5227
+ // Cursor-blinking
5228
+ function restartBlink(cm) {
5229
+ if (!cm.state.focused) { return }
5230
+ var display = cm.display;
5231
+ clearInterval(display.blinker);
5232
+ var on = true;
5233
+ display.cursorDiv.style.visibility = "";
5234
+ if (cm.options.cursorBlinkRate > 0)
5235
+ { display.blinker = setInterval(function () { return display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; },
5236
+ cm.options.cursorBlinkRate); }
5237
+ else if (cm.options.cursorBlinkRate < 0)
5238
+ { display.cursorDiv.style.visibility = "hidden"; }
5239
  }
 
5240
 
5241
+ function ensureFocus(cm) {
5242
+ if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); }
 
 
 
 
 
 
5243
  }
 
 
5244
 
5245
+ function delayBlurEvent(cm) {
5246
+ cm.state.delayingBlurEvent = true;
5247
+ setTimeout(function () { if (cm.state.delayingBlurEvent) {
5248
+ cm.state.delayingBlurEvent = false;
5249
+ onBlur(cm);
5250
+ } }, 100);
 
 
 
 
 
 
 
 
 
5251
  }
 
5252
 
5253
+ function onFocus(cm, e) {
5254
+ if (cm.state.delayingBlurEvent) { cm.state.delayingBlurEvent = false; }
 
 
 
 
 
 
 
5255
 
5256
+ if (cm.options.readOnly == "nocursor") { return }
5257
+ if (!cm.state.focused) {
5258
+ signal(cm, "focus", cm, e);
5259
+ cm.state.focused = true;
5260
+ addClass(cm.display.wrapper, "CodeMirror-focused");
5261
+ // This test prevents this from firing when a context
5262
+ // menu is closed (since the input reset would kill the
5263
+ // select-all detection hack)
5264
+ if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) {
5265
+ cm.display.input.reset();
5266
+ if (webkit) { setTimeout(function () { return cm.display.input.reset(true); }, 20); } // Issue #1730
5267
+ }
5268
+ cm.display.input.receivedFocus();
5269
+ }
5270
+ restartBlink(cm);
5271
  }
5272
+ function onBlur(cm, e) {
5273
+ if (cm.state.delayingBlurEvent) { return }
5274
+
5275
+ if (cm.state.focused) {
5276
+ signal(cm, "blur", cm, e);
5277
+ cm.state.focused = false;
5278
+ rmClass(cm.display.wrapper, "CodeMirror-focused");
5279
+ }
5280
+ clearInterval(cm.display.blinker);
5281
+ setTimeout(function () { if (!cm.state.focused) { cm.display.shift = false; } }, 150);
5282
+ }
5283
+
5284
+ // Read the actual heights of the rendered lines, and update their
5285
+ // stored heights to match.
5286
+ function updateHeightsInViewport(cm) {
5287
+ var display = cm.display;
5288
+ var prevBottom = display.lineDiv.offsetTop;
5289
+ for (var i = 0; i < display.view.length; i++) {
5290
+ var cur = display.view[i], height = (void 0);
5291
+ if (cur.hidden) { continue }
5292
+ if (ie && ie_version < 8) {
5293
+ var bot = cur.node.offsetTop + cur.node.offsetHeight;
5294
+ height = bot - prevBottom;
5295
+ prevBottom = bot;
5296
+ } else {
5297
+ var box = cur.node.getBoundingClientRect();
5298
+ height = box.bottom - box.top;
5299
+ }
5300
+ var diff = cur.line.height - height;
5301
+ if (height < 2) { height = textHeight(display); }
5302
+ if (diff > .005 || diff < -.005) {
5303
+ updateLineHeight(cur.line, height);
5304
+ updateWidgetHeight(cur.line);
5305
+ if (cur.rest) { for (var j = 0; j < cur.rest.length; j++)
5306
+ { updateWidgetHeight(cur.rest[j]); } }
5307
+ }
5308
+ }
5309
  }
5310
+
5311
+ // Read and store the height of line widgets associated with the
5312
+ // given line.
5313
+ function updateWidgetHeight(line) {
5314
+ if (line.widgets) { for (var i = 0; i < line.widgets.length; ++i) {
5315
+ var w = line.widgets[i], parent = w.node.parentNode;
5316
+ if (parent) { w.height = parent.offsetHeight; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5317
  } }
5318
  }
 
5319
 
5320
+ // Compute the lines that are visible in a given viewport (defaults
5321
+ // the the current scroll position). viewport may contain top,
5322
+ // height, and ensure (see op.scrollToPos) properties.
5323
+ function visibleLines(display, doc, viewport) {
5324
+ var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop;
5325
+ top = Math.floor(top - paddingTop(display));
5326
+ var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight;
5327
+
5328
+ var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom);
5329
+ // Ensure is a {from: {line, ch}, to: {line, ch}} object, and
5330
+ // forces those lines into the viewport (if possible).
5331
+ if (viewport && viewport.ensure) {
5332
+ var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line;
5333
+ if (ensureFrom < from) {
5334
+ from = ensureFrom;
5335
+ to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight);
5336
+ } else if (Math.min(ensureTo, doc.lastLine()) >= to) {
5337
+ from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight);
5338
+ to = ensureTo;
5339
+ }
5340
+ }
5341
+ return {from: from, to: Math.max(to, from + 1)}
5342
+ }
5343
+
5344
+ // Re-align line numbers and gutter marks to compensate for
5345
+ // horizontal scrolling.
5346
+ function alignHorizontally(cm) {
5347
+ var display = cm.display, view = display.view;
5348
+ if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) { return }
5349
+ var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
5350
+ var gutterW = display.gutters.offsetWidth, left = comp + "px";
5351
+ for (var i = 0; i < view.length; i++) { if (!view[i].hidden) {
5352
+ if (cm.options.fixedGutter) {
5353
+ if (view[i].gutter)
5354
+ { view[i].gutter.style.left = left; }
5355
+ if (view[i].gutterBackground)
5356
+ { view[i].gutterBackground.style.left = left; }
5357
+ }
5358
+ var align = view[i].alignable;
5359
+ if (align) { for (var j = 0; j < align.length; j++)
5360
+ { align[j].style.left = left; } }
5361
+ } }
5362
+ if (cm.options.fixedGutter)
5363
+ { display.gutters.style.left = (comp + gutterW) + "px"; }
5364
+ }
5365
+
5366
+ // Used to ensure that the line number gutter is still the right
5367
+ // size for the current document size. Returns true when an update
5368
+ // is needed.
5369
+ function maybeUpdateLineNumberWidth(cm) {
5370
+ if (!cm.options.lineNumbers) { return false }
5371
+ var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
5372
+ if (last.length != display.lineNumChars) {
5373
+ var test = display.measure.appendChild(elt("div", [elt("div", last)],
5374
+ "CodeMirror-linenumber CodeMirror-gutter-elt"));
5375
+ var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
5376
+ display.lineGutter.style.width = "";
5377
+ display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1;
5378
+ display.lineNumWidth = display.lineNumInnerWidth + padding;
5379
+ display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
5380
+ display.lineGutter.style.width = display.lineNumWidth + "px";
5381
+ updateGutterSpace(cm);
5382
+ return true
5383
+ }
5384
+ return false
5385
  }
 
 
5386
 
5387
+ // SCROLLING THINGS INTO VIEW
5388
+
5389
+ // If an editor sits on the top or bottom of the window, partially
5390
+ // scrolled out of view, this ensures that the cursor is visible.
5391
+ function maybeScrollWindow(cm, rect) {
5392
+ if (signalDOMEvent(cm, "scrollCursorIntoView")) { return }
5393
+
5394
+ var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null;
5395
+ if (rect.top + box.top < 0) { doScroll = true; }
5396
+ else if (rect.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) { doScroll = false; }
5397
+ if (doScroll != null && !phantom) {
5398
+ var scrollNode = elt("div", "\u200b", null, ("position: absolute;\n top: " + (rect.top - display.viewOffset - paddingTop(cm.display)) + "px;\n height: " + (rect.bottom - rect.top + scrollGap(cm) + display.barHeight) + "px;\n left: " + (rect.left) + "px; width: " + (Math.max(2, rect.right - rect.left)) + "px;"));
5399
+ cm.display.lineSpace.appendChild(scrollNode);
5400
+ scrollNode.scrollIntoView(doScroll);
5401
+ cm.display.lineSpace.removeChild(scrollNode);
5402
+ }
5403
+ }
5404
+
5405
+ // Scroll a given position into view (immediately), verifying that
5406
+ // it actually became visible (as line heights are accurately
5407
+ // measured, the position of something may 'drift' during drawing).
5408
+ function scrollPosIntoView(cm, pos, end, margin) {
5409
+ if (margin == null) { margin = 0; }
5410
+ var rect;
5411
+ if (!cm.options.lineWrapping && pos == end) {
5412
+ // Set pos and end to the cursor positions around the character pos sticks to
5413
+ // If pos.sticky == "before", that is around pos.ch - 1, otherwise around pos.ch
5414
+ // If pos == Pos(_, 0, "before"), pos and end are unchanged
5415
+ pos = pos.ch ? Pos(pos.line, pos.sticky == "before" ? pos.ch - 1 : pos.ch, "after") : pos;
5416
+ end = pos.sticky == "before" ? Pos(pos.line, pos.ch + 1, "before") : pos;
5417
+ }
5418
+ for (var limit = 0; limit < 5; limit++) {
5419
+ var changed = false;
5420
+ var coords = cursorCoords(cm, pos);
5421
+ var endCoords = !end || end == pos ? coords : cursorCoords(cm, end);
5422
+ rect = {left: Math.min(coords.left, endCoords.left),
5423
+ top: Math.min(coords.top, endCoords.top) - margin,
5424
+ right: Math.max(coords.left, endCoords.left),
5425
+ bottom: Math.max(coords.bottom, endCoords.bottom) + margin};
5426
+ var scrollPos = calculateScrollPos(cm, rect);
5427
+ var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
5428
+ if (scrollPos.scrollTop != null) {
5429
+ updateScrollTop(cm, scrollPos.scrollTop);
5430
+ if (Math.abs(cm.doc.scrollTop - startTop) > 1) { changed = true; }
5431
+ }
5432
+ if (scrollPos.scrollLeft != null) {
5433
+ setScrollLeft(cm, scrollPos.scrollLeft);
5434
+ if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) { changed = true; }
5435
+ }
5436
+ if (!changed) { break }
5437
+ }
5438
+ return rect
5439
+ }
5440
+
5441
+ // Scroll a given set of coordinates into view (immediately).
5442
+ function scrollIntoView(cm, rect) {
5443
+ var scrollPos = calculateScrollPos(cm, rect);
5444
+ if (scrollPos.scrollTop != null) { updateScrollTop(cm, scrollPos.scrollTop); }
5445
+ if (scrollPos.scrollLeft != null) { setScrollLeft(cm, scrollPos.scrollLeft); }
5446
+ }
5447
+
5448
+ // Calculate a new scroll position needed to scroll the given
5449
+ // rectangle into view. Returns an object with scrollTop and
5450
+ // scrollLeft properties. When these are undefined, the
5451
+ // vertical/horizontal position does not need to be adjusted.
5452
+ function calculateScrollPos(cm, rect) {
5453
+ var display = cm.display, snapMargin = textHeight(cm.display);
5454
+ if (rect.top < 0) { rect.top = 0; }
5455
+ var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop;
5456
+ var screen = displayHeight(cm), result = {};
5457
+ if (rect.bottom - rect.top > screen) { rect.bottom = rect.top + screen; }
5458
+ var docBottom = cm.doc.height + paddingVert(display);
5459
+ var atTop = rect.top < snapMargin, atBottom = rect.bottom > docBottom - snapMargin;
5460
+ if (rect.top < screentop) {
5461
+ result.scrollTop = atTop ? 0 : rect.top;
5462
+ } else if (rect.bottom > screentop + screen) {
5463
+ var newTop = Math.min(rect.top, (atBottom ? docBottom : rect.bottom) - screen);
5464
+ if (newTop != screentop) { result.scrollTop = newTop; }
5465
+ }
5466
+
5467
+ var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft;
5468
+ var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0);
5469
+ var tooWide = rect.right - rect.left > screenw;
5470
+ if (tooWide) { rect.right = rect.left + screenw; }
5471
+ if (rect.left < 10)
5472
+ { result.scrollLeft = 0; }
5473
+ else if (rect.left < screenleft)
5474
+ { result.scrollLeft = Math.max(0, rect.left - (tooWide ? 0 : 10)); }
5475
+ else if (rect.right > screenw + screenleft - 3)
5476
+ { result.scrollLeft = rect.right + (tooWide ? 0 : 10) - screenw; }
5477
+ return result
5478
+ }
5479
 
5480
+ // Store a relative adjustment to the scroll position in the current
5481
+ // operation (to be applied when the operation finishes).
5482
+ function addToScrollTop(cm, top) {
5483
+ if (top == null) { return }
5484
+ resolveScrollToPos(cm);
5485
+ cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top;
5486
+ }
5487
 
5488
+ // Make sure that at the end of the operation the current cursor is
5489
+ // shown.
5490
+ function ensureCursorVisible(cm) {
5491
+ resolveScrollToPos(cm);
5492
+ var cur = cm.getCursor();
5493
+ cm.curOp.scrollToPos = {from: cur, to: cur, margin: cm.options.cursorScrollMargin};
 
 
 
 
 
 
 
5494
  }
 
5495
 
5496
+ function scrollToCoords(cm, x, y) {
5497
+ if (x != null || y != null) { resolveScrollToPos(cm); }
5498
+ if (x != null) { cm.curOp.scrollLeft = x; }
5499
+ if (y != null) { cm.curOp.scrollTop = y; }
 
 
 
 
 
 
5500
  }
5501
+
5502
+ function scrollToRange(cm, range$$1) {
5503
+ resolveScrollToPos(cm);
5504
+ cm.curOp.scrollToPos = range$$1;
5505
  }
 
5506
 
5507
+ // When an operation has its scrollToPos property set, and another
5508
+ // scroll action is applied before the end of the operation, this
5509
+ // 'simulates' scrolling that position into view in a cheap way, so
5510
+ // that the effect of intermediate scroll commands is not ignored.
5511
+ function resolveScrollToPos(cm) {
5512
+ var range$$1 = cm.curOp.scrollToPos;
5513
+ if (range$$1) {
5514
+ cm.curOp.scrollToPos = null;
5515
+ var from = estimateCoords(cm, range$$1.from), to = estimateCoords(cm, range$$1.to);
5516
+ scrollToCoordsRange(cm, from, to, range$$1.margin);
5517
+ }
 
 
 
 
 
 
 
 
 
 
5518
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5519
 
5520
+ function scrollToCoordsRange(cm, from, to, margin) {
5521
+ var sPos = calculateScrollPos(cm, {
5522
+ left: Math.min(from.left, to.left),
5523
+ top: Math.min(from.top, to.top) - margin,
5524
+ right: Math.max(from.right, to.right),
5525
+ bottom: Math.max(from.bottom, to.bottom) + margin
5526
+ });
5527
+ scrollToCoords(cm, sPos.scrollLeft, sPos.scrollTop);
 
 
 
 
 
 
 
 
 
 
 
5528
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5529
 
5530
+ // Sync the scrollable area and scrollbars, ensure the viewport
5531
+ // covers the visible area.
5532
+ function updateScrollTop(cm, val) {
5533
+ if (Math.abs(cm.doc.scrollTop - val) < 2) { return }
5534
+ if (!gecko) { updateDisplaySimple(cm, {top: val}); }
5535
+ setScrollTop(cm, val, true);
5536
+ if (gecko) { updateDisplaySimple(cm); }
5537
+ startWorker(cm, 100);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5538
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5539
 
5540
+ function setScrollTop(cm, val, forceScroll) {
5541
+ val = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val);
5542
+ if (cm.display.scroller.scrollTop == val && !forceScroll) { return }
5543
+ cm.doc.scrollTop = val;
5544
+ cm.display.scrollbars.setScrollTop(val);
5545
+ if (cm.display.scroller.scrollTop != val) { cm.display.scroller.scrollTop = val; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5546
  }
 
 
 
 
 
 
 
 
 
 
 
 
5547
 
5548
+ // Sync scroller and scrollbar, ensure the gutter elements are
5549
+ // aligned.
5550
+ function setScrollLeft(cm, val, isScroller, forceScroll) {
5551
+ val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
5552
+ if ((isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) && !forceScroll) { return }
5553
+ cm.doc.scrollLeft = val;
5554
+ alignHorizontally(cm);
5555
+ if (cm.display.scroller.scrollLeft != val) { cm.display.scroller.scrollLeft = val; }
5556
+ cm.display.scrollbars.setScrollLeft(val);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5557
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5558
 
5559
+ // SCROLLBARS
 
 
 
 
 
 
 
 
 
 
5560
 
5561
+ // Prepare DOM reads needed to update the scrollbars. Done in one
5562
+ // shot to minimize update/measure roundtrips.
5563
+ function measureForScrollbars(cm) {
5564
+ var d = cm.display, gutterW = d.gutters.offsetWidth;
5565
+ var docH = Math.round(cm.doc.height + paddingVert(cm.display));
5566
+ return {
5567
+ clientHeight: d.scroller.clientHeight,
5568
+ viewHeight: d.wrapper.clientHeight,
5569
+ scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth,
5570
+ viewWidth: d.wrapper.clientWidth,
5571
+ barLeft: cm.options.fixedGutter ? gutterW : 0,
5572
+ docHeight: docH,
5573
+ scrollHeight: docH + scrollGap(cm) + d.barHeight,
5574
+ nativeBarWidth: d.nativeBarWidth,
5575
+ gutterWidth: gutterW
5576
+ }
5577
+ }
5578
+
5579
+ var NativeScrollbars = function(place, scroll, cm) {
5580
+ this.cm = cm;
5581
+ var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar");
5582
+ var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar");
5583
+ vert.tabIndex = horiz.tabIndex = -1;
5584
+ place(vert); place(horiz);
5585
+
5586
+ on(vert, "scroll", function () {
5587
+ if (vert.clientHeight) { scroll(vert.scrollTop, "vertical"); }
5588
+ });
5589
+ on(horiz, "scroll", function () {
5590
+ if (horiz.clientWidth) { scroll(horiz.scrollLeft, "horizontal"); }
5591
+ });
5592
 
5593
+ this.checkedZeroWidth = false;
5594
+ // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
5595
+ if (ie && ie_version < 8) { this.horiz.style.minHeight = this.vert.style.minWidth = "18px"; }
5596
+ };
 
 
5597
 
5598
+ NativeScrollbars.prototype.update = function (measure) {
5599
+ var needsH = measure.scrollWidth > measure.clientWidth + 1;
5600
+ var needsV = measure.scrollHeight > measure.clientHeight + 1;
5601
+ var sWidth = measure.nativeBarWidth;
5602
+
5603
+ if (needsV) {
5604
+ this.vert.style.display = "block";
5605
+ this.vert.style.bottom = needsH ? sWidth + "px" : "0";
5606
+ var totalHeight = measure.viewHeight - (needsH ? sWidth : 0);
5607
+ // A bug in IE8 can cause this value to be negative, so guard it.
5608
+ this.vert.firstChild.style.height =
5609
+ Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px";
5610
+ } else {
5611
+ this.vert.style.display = "";
5612
+ this.vert.firstChild.style.height = "0";
5613
+ }
5614
 
5615
+ if (needsH) {
5616
+ this.horiz.style.display = "block";
5617
+ this.horiz.style.right = needsV ? sWidth + "px" : "0";
5618
+ this.horiz.style.left = measure.barLeft + "px";
5619
+ var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0);
5620
+ this.horiz.firstChild.style.width =
5621
+ Math.max(0, measure.scrollWidth - measure.clientWidth + totalWidth) + "px";
5622
+ } else {
5623
+ this.horiz.style.display = "";
5624
+ this.horiz.firstChild.style.width = "0";
5625
+ }
5626
 
5627
+ if (!this.checkedZeroWidth && measure.clientHeight > 0) {
5628
+ if (sWidth == 0) { this.zeroWidthHack(); }
5629
+ this.checkedZeroWidth = true;
5630
+ }
 
 
5631
 
5632
+ return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0}
5633
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5634
 
5635
+ NativeScrollbars.prototype.setScrollLeft = function (pos) {
5636
+ if (this.horiz.scrollLeft != pos) { this.horiz.scrollLeft = pos; }
5637
+ if (this.disableHoriz) { this.enableZeroWidthBar(this.horiz, this.disableHoriz, "horiz"); }
5638
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5639
 
5640
+ NativeScrollbars.prototype.setScrollTop = function (pos) {
5641
+ if (this.vert.scrollTop != pos) { this.vert.scrollTop = pos; }
5642
+ if (this.disableVert) { this.enableZeroWidthBar(this.vert, this.disableVert, "vert"); }
5643
+ };
5644
 
5645
+ NativeScrollbars.prototype.zeroWidthHack = function () {
5646
+ var w = mac && !mac_geMountainLion ? "12px" : "18px";
5647
+ this.horiz.style.height = this.vert.style.width = w;
5648
+ this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none";
5649
+ this.disableHoriz = new Delayed;
5650
+ this.disableVert = new Delayed;
5651
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5652
 
5653
+ NativeScrollbars.prototype.enableZeroWidthBar = function (bar, delay, type) {
5654
+ bar.style.pointerEvents = "auto";
5655
+ function maybeDisable() {
5656
+ // To find out whether the scrollbar is still visible, we
5657
+ // check whether the element under the pixel in the bottom
5658
+ // right corner of the scrollbar box is the scrollbar box
5659
+ // itself (when the bar is still visible) or its filler child
5660
+ // (when the bar is hidden). If it is still visible, we keep
5661
+ // it enabled, if it's hidden, we disable pointer events.
5662
+ var box = bar.getBoundingClientRect();
5663
+ var elt$$1 = type == "vert" ? document.elementFromPoint(box.right - 1, (box.top + box.bottom) / 2)
5664
+ : document.elementFromPoint((box.right + box.left) / 2, box.bottom - 1);
5665
+ if (elt$$1 != bar) { bar.style.pointerEvents = "none"; }
5666
+ else { delay.set(1000, maybeDisable); }
5667
+ }
5668
+ delay.set(1000, maybeDisable);
5669
+ };
5670
 
5671
+ NativeScrollbars.prototype.clear = function () {
5672
+ var parent = this.horiz.parentNode;
5673
+ parent.removeChild(this.horiz);
5674
+ parent.removeChild(this.vert);
5675
+ };
5676
+
5677
+ var NullScrollbars = function () {};
5678
+
5679
+ NullScrollbars.prototype.update = function () { return {bottom: 0, right: 0} };
5680
+ NullScrollbars.prototype.setScrollLeft = function () {};
5681
+ NullScrollbars.prototype.setScrollTop = function () {};
5682
+ NullScrollbars.prototype.clear = function () {};
5683
+
5684
+ function updateScrollbars(cm, measure) {
5685
+ if (!measure) { measure = measureForScrollbars(cm); }
5686
+ var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight;
5687
+ updateScrollbarsInner(cm, measure);
5688
+ for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) {
5689
+ if (startWidth != cm.display.barWidth && cm.options.lineWrapping)
5690
+ { updateHeightsInViewport(cm); }
5691
+ updateScrollbarsInner(cm, measureForScrollbars(cm));
5692
+ startWidth = cm.display.barWidth; startHeight = cm.display.barHeight;
5693
+ }
5694
+ }
5695
+
5696
+ // Re-synchronize the fake scrollbars with the actual size of the
5697
+ // content.
5698
+ function updateScrollbarsInner(cm, measure) {
5699
+ var d = cm.display;
5700
+ var sizes = d.scrollbars.update(measure);
5701
+
5702
+ d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px";
5703
+ d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px";
5704
+ d.heightForcer.style.borderBottom = sizes.bottom + "px solid transparent";
5705
+
5706
+ if (sizes.right && sizes.bottom) {
5707
+ d.scrollbarFiller.style.display = "block";
5708
+ d.scrollbarFiller.style.height = sizes.bottom + "px";
5709
+ d.scrollbarFiller.style.width = sizes.right + "px";
5710
+ } else { d.scrollbarFiller.style.display = ""; }
5711
+ if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
5712
+ d.gutterFiller.style.display = "block";
5713
+ d.gutterFiller.style.height = sizes.bottom + "px";
5714
+ d.gutterFiller.style.width = measure.gutterWidth + "px";
5715
+ } else { d.gutterFiller.style.display = ""; }
5716
+ }
5717
+
5718
+ var scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars};
5719
+
5720
+ function initScrollbars(cm) {
5721
+ if (cm.display.scrollbars) {
5722
+ cm.display.scrollbars.clear();
5723
+ if (cm.display.scrollbars.addClass)
5724
+ { rmClass(cm.display.wrapper, cm.display.scrollbars.addClass); }
5725
+ }
5726
+
5727
+ cm.display.scrollbars = new scrollbarModel[cm.options.scrollbarStyle](function (node) {
5728
+ cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller);
5729
+ // Prevent clicks in the scrollbars from killing focus
5730
+ on(node, "mousedown", function () {
5731
+ if (cm.state.focused) { setTimeout(function () { return cm.display.input.focus(); }, 0); }
5732
+ });
5733
+ node.setAttribute("cm-not-content", "true");
5734
+ }, function (pos, axis) {
5735
+ if (axis == "horizontal") { setScrollLeft(cm, pos); }
5736
+ else { updateScrollTop(cm, pos); }
5737
+ }, cm);
5738
+ if (cm.display.scrollbars.addClass)
5739
+ { addClass(cm.display.wrapper, cm.display.scrollbars.addClass); }
5740
+ }
5741
+
5742
+ // Operations are used to wrap a series of changes to the editor
5743
+ // state in such a way that each change won't have to update the
5744
+ // cursor and display (which would be awkward, slow, and
5745
+ // error-prone). Instead, display updates are batched and then all
5746
+ // combined and executed at once.
5747
+
5748
+ var nextOpId = 0;
5749
+ // Start a new operation.
5750
+ function startOperation(cm) {
5751
+ cm.curOp = {
5752
+ cm: cm,
5753
+ viewChanged: false, // Flag that indicates that lines might need to be redrawn
5754
+ startHeight: cm.doc.height, // Used to detect need to update scrollbar
5755
+ forceUpdate: false, // Used to force a redraw
5756
+ updateInput: null, // Whether to reset the input textarea
5757
+ typing: false, // Whether this reset should be careful to leave existing text (for compositing)
5758
+ changeObjs: null, // Accumulated changes, for firing change events
5759
+ cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on
5760
+ cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already
5761
+ selectionChanged: false, // Whether the selection needs to be redrawn
5762
+ updateMaxLine: false, // Set when the widest line needs to be determined anew
5763
+ scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet
5764
+ scrollToPos: null, // Used to scroll to a specific position
5765
+ focus: false,
5766
+ id: ++nextOpId // Unique ID
5767
+ };
5768
+ pushOperation(cm.curOp);
5769
+ }
5770
 
5771
+ // Finish an operation, updating the display and signalling delayed events
5772
+ function endOperation(cm) {
5773
+ var op = cm.curOp;
5774
+ if (op) { finishOperation(op, function (group) {
5775
+ for (var i = 0; i < group.ops.length; i++)
5776
+ { group.ops[i].cm.curOp = null; }
5777
+ endOperations(group);
5778
+ }); }
 
 
 
 
 
 
 
 
 
 
 
5779
  }
 
5780
 
5781
+ // The DOM updates done when an operation finishes are batched so
5782
+ // that the minimum number of relayouts are required.
5783
+ function endOperations(group) {
5784
+ var ops = group.ops;
5785
+ for (var i = 0; i < ops.length; i++) // Read DOM
5786
+ { endOperation_R1(ops[i]); }
5787
+ for (var i$1 = 0; i$1 < ops.length; i$1++) // Write DOM (maybe)
5788
+ { endOperation_W1(ops[i$1]); }
5789
+ for (var i$2 = 0; i$2 < ops.length; i$2++) // Read DOM
5790
+ { endOperation_R2(ops[i$2]); }
5791
+ for (var i$3 = 0; i$3 < ops.length; i$3++) // Write DOM (maybe)
5792
+ { endOperation_W2(ops[i$3]); }
5793
+ for (var i$4 = 0; i$4 < ops.length; i$4++) // Read DOM
5794
+ { endOperation_finish(ops[i$4]); }
5795
+ }
5796
 
5797
+ function endOperation_R1(op) {
5798
+ var cm = op.cm, display = cm.display;
5799
+ maybeClipScrollbars(cm);
5800
+ if (op.updateMaxLine) { findMaxLine(cm); }
 
5801
 
5802
+ op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null ||
5803
+ op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom ||
5804
+ op.scrollToPos.to.line >= display.viewTo) ||
5805
+ display.maxLineChanged && cm.options.lineWrapping;
5806
+ op.update = op.mustUpdate &&
5807
+ new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate);
5808
+ }
5809
 
5810
+ function endOperation_W1(op) {
5811
+ op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update);
5812
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5813
 
5814
+ function endOperation_R2(op) {
5815
+ var cm = op.cm, display = cm.display;
5816
+ if (op.updatedDisplay) { updateHeightsInViewport(cm); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5817
 
5818
+ op.barMeasure = measureForScrollbars(cm);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5819
 
5820
+ // If the max line changed since it was last measured, measure it,
5821
+ // and ensure the document's width matches it.
5822
+ // updateDisplay_W2 will use these properties to do the actual resizing
5823
+ if (display.maxLineChanged && !cm.options.lineWrapping) {
5824
+ op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3;
5825
+ cm.display.sizerWidth = op.adjustWidthTo;
5826
+ op.barMeasure.scrollWidth =
5827
+ Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth);
5828
+ op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm));
 
 
5829
  }
5830
+
5831
+ if (op.updatedDisplay || op.selectionChanged)
5832
+ { op.preparedSelection = display.input.prepareSelection(); }
5833
  }
 
 
 
 
 
 
5834
 
5835
+ function endOperation_W2(op) {
5836
+ var cm = op.cm;
 
 
 
 
 
 
 
 
5837
 
5838
+ if (op.adjustWidthTo != null) {
5839
+ cm.display.sizer.style.minWidth = op.adjustWidthTo + "px";
5840
+ if (op.maxScrollLeft < cm.doc.scrollLeft)
5841
+ { setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true); }
5842
+ cm.display.maxLineChanged = false;
5843
+ }
 
 
 
 
 
 
 
 
 
5844
 
5845
+ var takeFocus = op.focus && op.focus == activeElt();
5846
+ if (op.preparedSelection)
5847
+ { cm.display.input.showSelection(op.preparedSelection, takeFocus); }
5848
+ if (op.updatedDisplay || op.startHeight != cm.doc.height)
5849
+ { updateScrollbars(cm, op.barMeasure); }
5850
+ if (op.updatedDisplay)
5851
+ { setDocumentHeight(cm, op.barMeasure); }
5852
 
5853
+ if (op.selectionChanged) { restartBlink(cm); }
 
 
 
 
 
 
 
 
 
 
 
 
5854
 
5855
+ if (cm.state.focused && op.updateInput)
5856
+ { cm.display.input.reset(op.typing); }
5857
+ if (takeFocus) { ensureFocus(op.cm); }
 
5858
  }
 
5859
 
5860
+ function endOperation_finish(op) {
5861
+ var cm = op.cm, display = cm.display, doc = cm.doc;
 
 
 
 
 
5862
 
5863
+ if (op.updatedDisplay) { postUpdateDisplay(cm, op.update); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5864
 
5865
+ // Abort mouse wheel delta measurement, when scrolling explicitly
5866
+ if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos))
5867
+ { display.wheelStartX = display.wheelStartY = null; }
 
 
 
 
 
 
 
 
 
5868
 
5869
+ // Propagate the scroll position to the actual DOM scroller
5870
+ if (op.scrollTop != null) { setScrollTop(cm, op.scrollTop, op.forceScroll); }
 
5871
 
5872
+ if (op.scrollLeft != null) { setScrollLeft(cm, op.scrollLeft, true, true); }
5873
+ // If we need to scroll a specific position into view, do so.
5874
+ if (op.scrollToPos) {
5875
+ var rect = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from),
5876
+ clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin);
5877
+ maybeScrollWindow(cm, rect);
5878
+ }
5879
 
5880
+ // Fire events for markers that are hidden/unidden by editing or
5881
+ // undoing
5882
+ var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;
5883
+ if (hidden) { for (var i = 0; i < hidden.length; ++i)
5884
+ { if (!hidden[i].lines.length) { signal(hidden[i], "hide"); } } }
5885
+ if (unhidden) { for (var i$1 = 0; i$1 < unhidden.length; ++i$1)
5886
+ { if (unhidden[i$1].lines.length) { signal(unhidden[i$1], "unhide"); } } }
5887
 
5888
+ if (display.wrapper.offsetHeight)
5889
+ { doc.scrollTop = cm.display.scroller.scrollTop; }
 
 
 
 
 
 
 
 
 
 
5890
 
5891
+ // Fire change events, and delayed event handlers
5892
+ if (op.changeObjs)
5893
+ { signal(cm, "changes", cm, op.changeObjs); }
5894
+ if (op.update)
5895
+ { op.update.finish(); }
5896
+ }
5897
 
5898
+ // Run the given function in an operation
5899
+ function runInOp(cm, f) {
5900
+ if (cm.curOp) { return f() }
5901
+ startOperation(cm);
5902
+ try { return f() }
5903
+ finally { endOperation(cm); }
5904
+ }
5905
+ // Wraps a function in an operation. Returns the wrapped function.
5906
+ function operation(cm, f) {
5907
+ return function() {
5908
+ if (cm.curOp) { return f.apply(cm, arguments) }
5909
+ startOperation(cm);
5910
+ try { return f.apply(cm, arguments) }
5911
+ finally { endOperation(cm); }
5912
+ }
5913
+ }
5914
+ // Used to add methods to editor and doc instances, wrapping them in
5915
+ // operations.
5916
+ function methodOp(f) {
5917
+ return function() {
5918
+ if (this.curOp) { return f.apply(this, arguments) }
5919
+ startOperation(this);
5920
+ try { return f.apply(this, arguments) }
5921
+ finally { endOperation(this); }
5922
+ }
5923
+ }
5924
+ function docMethodOp(f) {
5925
+ return function() {
5926
+ var cm = this.cm;
5927
+ if (!cm || cm.curOp) { return f.apply(this, arguments) }
5928
+ startOperation(cm);
5929
+ try { return f.apply(this, arguments) }
5930
+ finally { endOperation(cm); }
5931
+ }
5932
+ }
5933
+
5934
+ // Updates the display.view data structure for a given change to the
5935
+ // document. From and to are in pre-change coordinates. Lendiff is
5936
+ // the amount of lines added or subtracted by the change. This is
5937
+ // used for changes that span multiple lines, or change the way
5938
+ // lines are divided into visual lines. regLineChange (below)
5939
+ // registers single-line changes.
5940
+ function regChange(cm, from, to, lendiff) {
5941
+ if (from == null) { from = cm.doc.first; }
5942
+ if (to == null) { to = cm.doc.first + cm.doc.size; }
5943
+ if (!lendiff) { lendiff = 0; }
5944
+
5945
+ var display = cm.display;
5946
+ if (lendiff && to < display.viewTo &&
5947
+ (display.updateLineNumbers == null || display.updateLineNumbers > from))
5948
+ { display.updateLineNumbers = from; }
5949
+
5950
+ cm.curOp.viewChanged = true;
5951
+
5952
+ if (from >= display.viewTo) { // Change after
5953
+ if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo)
5954
+ { resetView(cm); }
5955
+ } else if (to <= display.viewFrom) { // Change before
5956
+ if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) {
5957
+ resetView(cm);
5958
+ } else {
5959
+ display.viewFrom += lendiff;
5960
+ display.viewTo += lendiff;
5961
+ }
5962
+ } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap
5963
+ resetView(cm);
5964
+ } else if (from <= display.viewFrom) { // Top overlap
5965
+ var cut = viewCuttingPoint(cm, to, to + lendiff, 1);
5966
+ if (cut) {
5967
+ display.view = display.view.slice(cut.index);
5968
+ display.viewFrom = cut.lineN;
5969
+ display.viewTo += lendiff;
5970
+ } else {
5971
+ resetView(cm);
5972
+ }
5973
+ } else if (to >= display.viewTo) { // Bottom overlap
5974
+ var cut$1 = viewCuttingPoint(cm, from, from, -1);
5975
+ if (cut$1) {
5976
+ display.view = display.view.slice(0, cut$1.index);
5977
+ display.viewTo = cut$1.lineN;
5978
+ } else {
5979
+ resetView(cm);
5980
+ }
5981
+ } else { // Gap in the middle
5982
+ var cutTop = viewCuttingPoint(cm, from, from, -1);
5983
+ var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1);
5984
+ if (cutTop && cutBot) {
5985
+ display.view = display.view.slice(0, cutTop.index)
5986
+ .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN))
5987
+ .concat(display.view.slice(cutBot.index));
5988
+ display.viewTo += lendiff;
5989
+ } else {
5990
+ resetView(cm);
5991
+ }
5992
+ }
5993
 
5994
+ var ext = display.externalMeasured;
5995
+ if (ext) {
5996
+ if (to < ext.lineN)
5997
+ { ext.lineN += lendiff; }
5998
+ else if (from < ext.lineN + ext.size)
5999
+ { display.externalMeasured = null; }
6000
+ }
6001
  }
 
6002
 
6003
+ // Register a change to a single line. Type must be one of "text",
6004
+ // "gutter", "class", "widget"
6005
+ function regLineChange(cm, line, type) {
6006
+ cm.curOp.viewChanged = true;
6007
+ var display = cm.display, ext = cm.display.externalMeasured;
6008
+ if (ext && line >= ext.lineN && line < ext.lineN + ext.size)
6009
+ { display.externalMeasured = null; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6010
 
6011
+ if (line < display.viewFrom || line >= display.viewTo) { return }
6012
+ var lineView = display.view[findViewIndex(cm, line)];
6013
+ if (lineView.node == null) { return }
6014
+ var arr = lineView.changes || (lineView.changes = []);
6015
+ if (indexOf(arr, type) == -1) { arr.push(type); }
6016
+ }
6017
+
6018
+ // Clear the view.
6019
+ function resetView(cm) {
6020
+ cm.display.viewFrom = cm.display.viewTo = cm.doc.first;
6021
+ cm.display.view = [];
6022
+ cm.display.viewOffset = 0;
6023
+ }
6024
+
6025
+ function viewCuttingPoint(cm, oldN, newN, dir) {
6026
+ var index = findViewIndex(cm, oldN), diff, view = cm.display.view;
6027
+ if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size)
6028
+ { return {index: index, lineN: newN} }
6029
+ var n = cm.display.viewFrom;
6030
+ for (var i = 0; i < index; i++)
6031
+ { n += view[i].size; }
6032
+ if (n != oldN) {
6033
+ if (dir > 0) {
6034
+ if (index == view.length - 1) { return null }
6035
+ diff = (n + view[index].size) - oldN;
6036
+ index++;
6037
  } else {
6038
+ diff = n - oldN;
6039
  }
6040
+ oldN += diff; newN += diff;
6041
  }
6042
+ while (visualLineNo(cm.doc, newN) != newN) {
6043
+ if (index == (dir < 0 ? 0 : view.length - 1)) { return null }
6044
+ newN += dir * view[index - (dir < 0 ? 1 : 0)].size;
6045
+ index += dir;
6046
+ }
6047
+ return {index: index, lineN: newN}
6048
  }
6049
 
6050
+ // Force the view to cover a given range, adding empty view element
6051
+ // or clipping off existing ones as needed.
6052
+ function adjustView(cm, from, to) {
6053
+ var display = cm.display, view = display.view;
6054
+ if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) {
6055
+ display.view = buildViewArray(cm, from, to);
6056
+ display.viewFrom = from;
6057
+ } else {
6058
+ if (display.viewFrom > from)
6059
+ { display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view); }
6060
+ else if (display.viewFrom < from)
6061
+ { display.view = display.view.slice(findViewIndex(cm, from)); }
6062
+ display.viewFrom = from;
6063
+ if (display.viewTo < to)
6064
+ { display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)); }
6065
+ else if (display.viewTo > to)
6066
+ { display.view = display.view.slice(0, findViewIndex(cm, to)); }
6067
+ }
6068
+ display.viewTo = to;
6069
+ }
6070
+
6071
+ // Count the number of lines in the view whose DOM representation is
6072
+ // out of date (or nonexistent).
6073
+ function countDirtyView(cm) {
6074
+ var view = cm.display.view, dirty = 0;
6075
+ for (var i = 0; i < view.length; i++) {
6076
+ var lineView = view[i];
6077
+ if (!lineView.hidden && (!lineView.node || lineView.changes)) { ++dirty; }
6078
+ }
6079
+ return dirty
6080
+ }
6081
+
6082
+ // HIGHLIGHT WORKER
6083
+
6084
+ function startWorker(cm, time) {
6085
+ if (cm.doc.highlightFrontier < cm.display.viewTo)
6086
+ { cm.state.highlight.set(time, bind(highlightWorker, cm)); }
6087
+ }
6088
+
6089
+ function highlightWorker(cm) {
6090
+ var doc = cm.doc;
6091
+ if (doc.highlightFrontier >= cm.display.viewTo) { return }
6092
+ var end = +new Date + cm.options.workTime;
6093
+ var context = getContextBefore(cm, doc.highlightFrontier);
6094
+ var changedLines = [];
6095
+
6096
+ doc.iter(context.line, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function (line) {
6097
+ if (context.line >= cm.display.viewFrom) { // Visible
6098
+ var oldStyles = line.styles;
6099
+ var resetState = line.text.length > cm.options.maxHighlightLength ? copyState(doc.mode, context.state) : null;
6100
+ var highlighted = highlightLine(cm, line, context, true);
6101
+ if (resetState) { context.state = resetState; }
6102
+ line.styles = highlighted.styles;
6103
+ var oldCls = line.styleClasses, newCls = highlighted.classes;
6104
+ if (newCls) { line.styleClasses = newCls; }
6105
+ else if (oldCls) { line.styleClasses = null; }
6106
+ var ischange = !oldStyles || oldStyles.length != line.styles.length ||
6107
+ oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass);
6108
+ for (var i = 0; !ischange && i < oldStyles.length; ++i) { ischange = oldStyles[i] != line.styles[i]; }
6109
+ if (ischange) { changedLines.push(context.line); }
6110
+ line.stateAfter = context.save();
6111
+ context.nextLine();
6112
+ } else {
6113
+ if (line.text.length <= cm.options.maxHighlightLength)
6114
+ { processLine(cm, line.text, context); }
6115
+ line.stateAfter = context.line % 5 == 0 ? context.save() : null;
6116
+ context.nextLine();
6117
+ }
6118
+ if (+new Date > end) {
6119
+ startWorker(cm, cm.options.workDelay);
6120
+ return true
6121
+ }
6122
+ });
6123
+ doc.highlightFrontier = context.line;
6124
+ doc.modeFrontier = Math.max(doc.modeFrontier, context.line);
6125
+ if (changedLines.length) { runInOp(cm, function () {
6126
+ for (var i = 0; i < changedLines.length; i++)
6127
+ { regLineChange(cm, changedLines[i], "text"); }
6128
+ }); }
6129
+ }
6130
+
6131
+ // DISPLAY DRAWING
6132
+
6133
+ var DisplayUpdate = function(cm, viewport, force) {
6134
+ var display = cm.display;
6135
+
6136
+ this.viewport = viewport;
6137
+ // Store some values that we'll need later (but don't want to force a relayout for)
6138
+ this.visible = visibleLines(display, cm.doc, viewport);
6139
+ this.editorIsHidden = !display.wrapper.offsetWidth;
6140
+ this.wrapperHeight = display.wrapper.clientHeight;
6141
+ this.wrapperWidth = display.wrapper.clientWidth;
6142
+ this.oldDisplayWidth = displayWidth(cm);
6143
+ this.force = force;
6144
+ this.dims = getDimensions(cm);
6145
+ this.events = [];
6146
+ };
6147
 
6148
+ DisplayUpdate.prototype.signal = function (emitter, type) {
6149
+ if (hasHandler(emitter, type))
6150
+ { this.events.push(arguments); }
6151
+ };
6152
+ DisplayUpdate.prototype.finish = function () {
6153
+ var this$1 = this;
6154
 
6155
+ for (var i = 0; i < this.events.length; i++)
6156
+ { signal.apply(null, this$1.events[i]); }
6157
+ };
 
 
 
 
6158
 
6159
+ function maybeClipScrollbars(cm) {
6160
+ var display = cm.display;
6161
+ if (!display.scrollbarsClipped && display.scroller.offsetWidth) {
6162
+ display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth;
6163
+ display.heightForcer.style.height = scrollGap(cm) + "px";
6164
+ display.sizer.style.marginBottom = -display.nativeBarWidth + "px";
6165
+ display.sizer.style.borderRightWidth = scrollGap(cm) + "px";
6166
+ display.scrollbarsClipped = true;
 
 
 
 
 
 
6167
  }
 
6168
  }
 
 
 
 
6169
 
6170
+ function selectionSnapshot(cm) {
6171
+ if (cm.hasFocus()) { return null }
6172
+ var active = activeElt();
6173
+ if (!active || !contains(cm.display.lineDiv, active)) { return null }
6174
+ var result = {activeElt: active};
6175
+ if (window.getSelection) {
6176
+ var sel = window.getSelection();
6177
+ if (sel.anchorNode && sel.extend && contains(cm.display.lineDiv, sel.anchorNode)) {
6178
+ result.anchorNode = sel.anchorNode;
6179
+ result.anchorOffset = sel.anchorOffset;
6180
+ result.focusNode = sel.focusNode;
6181
+ result.focusOffset = sel.focusOffset;
6182
+ }
6183
+ }
6184
+ return result
6185
  }
 
 
 
6186
 
6187
+ function restoreSelection(snapshot) {
6188
+ if (!snapshot || !snapshot.activeElt || snapshot.activeElt == activeElt()) { return }
6189
+ snapshot.activeElt.focus();
6190
+ if (snapshot.anchorNode && contains(document.body, snapshot.anchorNode) && contains(document.body, snapshot.focusNode)) {
6191
+ var sel = window.getSelection(), range$$1 = document.createRange();
6192
+ range$$1.setEnd(snapshot.anchorNode, snapshot.anchorOffset);
6193
+ range$$1.collapse(false);
6194
+ sel.removeAllRanges();
6195
+ sel.addRange(range$$1);
6196
+ sel.extend(snapshot.focusNode, snapshot.focusOffset);
 
 
 
 
 
 
 
 
 
 
 
 
 
6197
  }
6198
  }
 
6199
 
6200
+ // Does the actual updating of the line display. Bails out
6201
+ // (returning false) when there is nothing to be done and forced is
6202
+ // false.
6203
+ function updateDisplayIfNeeded(cm, update) {
6204
+ var display = cm.display, doc = cm.doc;
 
 
 
6205
 
6206
+ if (update.editorIsHidden) {
6207
+ resetView(cm);
6208
+ return false
6209
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6210
 
6211
+ // Bail out if the visible area is already rendered and nothing changed.
6212
+ if (!update.force &&
6213
+ update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo &&
6214
+ (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) &&
6215
+ display.renderedView == display.view && countDirtyView(cm) == 0)
6216
+ { return false }
6217
+
6218
+ if (maybeUpdateLineNumberWidth(cm)) {
6219
+ resetView(cm);
6220
+ update.dims = getDimensions(cm);
6221
+ }
6222
+
6223
+ // Compute a suitable new viewport (from & to)
6224
+ var end = doc.first + doc.size;
6225
+ var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first);
6226
+ var to = Math.min(end, update.visible.to + cm.options.viewportMargin);
6227
+ if (display.viewFrom < from && from - display.viewFrom < 20) { from = Math.max(doc.first, display.viewFrom); }
6228
+ if (display.viewTo > to && display.viewTo - to < 20) { to = Math.min(end, display.viewTo); }
6229
+ if (sawCollapsedSpans) {
6230
+ from = visualLineNo(cm.doc, from);
6231
+ to = visualLineEndNo(cm.doc, to);
6232
+ }
6233
+
6234
+ var different = from != display.viewFrom || to != display.viewTo ||
6235
+ display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth;
6236
+ adjustView(cm, from, to);
6237
+
6238
+ display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom));
6239
+ // Position the mover div to align with the current scroll position
6240
+ cm.display.mover.style.top = display.viewOffset + "px";
6241
+
6242
+ var toUpdate = countDirtyView(cm);
6243
+ if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view &&
6244
+ (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo))
6245
+ { return false }
6246
+
6247
+ // For big changes, we hide the enclosing element during the
6248
+ // update, since that speeds up the operations on most browsers.
6249
+ var selSnapshot = selectionSnapshot(cm);
6250
+ if (toUpdate > 4) { display.lineDiv.style.display = "none"; }
6251
+ patchDisplay(cm, display.updateLineNumbers, update.dims);
6252
+ if (toUpdate > 4) { display.lineDiv.style.display = ""; }
6253
+ display.renderedView = display.view;
6254
+ // There might have been a widget with a focused element that got
6255
+ // hidden or updated, if so re-focus it.
6256
+ restoreSelection(selSnapshot);
6257
+
6258
+ // Prevent selection and cursors from interfering with the scroll
6259
+ // width and height.
6260
+ removeChildren(display.cursorDiv);
6261
+ removeChildren(display.selectionDiv);
6262
+ display.gutters.style.height = display.sizer.style.minHeight = 0;
6263
+
6264
+ if (different) {
6265
+ display.lastWrapHeight = update.wrapperHeight;
6266
+ display.lastWrapWidth = update.wrapperWidth;
6267
+ startWorker(cm, 400);
6268
+ }
6269
+
6270
+ display.updateLineNumbers = null;
6271
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6272
  return true
6273
  }
 
 
 
 
6274
 
6275
+ function postUpdateDisplay(cm, update) {
6276
+ var viewport = update.viewport;
 
 
6277
 
6278
+ for (var first = true;; first = false) {
6279
+ if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) {
6280
+ // Clip forced viewport to actual scrollable area.
6281
+ if (viewport && viewport.top != null)
6282
+ { viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)}; }
6283
+ // Updated line heights might result in the drawn area not
6284
+ // actually covering the viewport. Keep looping until it does.
6285
+ update.visible = visibleLines(cm.display, cm.doc, viewport);
6286
+ if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)
6287
+ { break }
6288
+ }
6289
+ if (!updateDisplayIfNeeded(cm, update)) { break }
6290
+ updateHeightsInViewport(cm);
6291
+ var barMeasure = measureForScrollbars(cm);
6292
+ updateSelection(cm);
6293
+ updateScrollbars(cm, barMeasure);
6294
+ setDocumentHeight(cm, barMeasure);
6295
+ update.force = false;
6296
+ }
6297
+
6298
+ update.signal(cm, "update", cm);
6299
+ if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) {
6300
+ update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo);
6301
+ cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo;
6302
+ }
6303
+ }
6304
+
6305
+ function updateDisplaySimple(cm, viewport) {
6306
+ var update = new DisplayUpdate(cm, viewport);
6307
+ if (updateDisplayIfNeeded(cm, update)) {
6308
+ updateHeightsInViewport(cm);
6309
+ postUpdateDisplay(cm, update);
6310
+ var barMeasure = measureForScrollbars(cm);
6311
+ updateSelection(cm);
6312
+ updateScrollbars(cm, barMeasure);
6313
+ setDocumentHeight(cm, barMeasure);
6314
+ update.finish();
6315
+ }
6316
+ }
6317
+
6318
+ // Sync the actual display DOM structure with display.view, removing
6319
+ // nodes for lines that are no longer in view, and creating the ones
6320
+ // that are not there yet, and updating the ones that are out of
6321
+ // date.
6322
+ function patchDisplay(cm, updateNumbersFrom, dims) {
6323
+ var display = cm.display, lineNumbers = cm.options.lineNumbers;
6324
+ var container = display.lineDiv, cur = container.firstChild;
6325
+
6326
+ function rm(node) {
6327
+ var next = node.nextSibling;
6328
+ // Works around a throw-scroll bug in OS X Webkit
6329
+ if (webkit && mac && cm.display.currentWheelTarget == node)
6330
+ { node.style.display = "none"; }
6331
+ else
6332
+ { node.parentNode.removeChild(node); }
6333
+ return next
6334
+ }
6335
+
6336
+ var view = display.view, lineN = display.viewFrom;
6337
+ // Loop over the elements in the view, syncing cur (the DOM nodes
6338
+ // in display.lineDiv) with the view as we go.
6339
+ for (var i = 0; i < view.length; i++) {
6340
+ var lineView = view[i];
6341
+ if (lineView.hidden) ; else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet
6342
+ var node = buildLineElement(cm, lineView, lineN, dims);
6343
+ container.insertBefore(node, cur);
6344
+ } else { // Already drawn
6345
+ while (cur != lineView.node) { cur = rm(cur); }
6346
+ var updateNumber = lineNumbers && updateNumbersFrom != null &&
6347
+ updateNumbersFrom <= lineN && lineView.lineNumber;
6348
+ if (lineView.changes) {
6349
+ if (indexOf(lineView.changes, "gutter") > -1) { updateNumber = false; }
6350
+ updateLineForChanges(cm, lineView, lineN, dims);
6351
+ }
6352
+ if (updateNumber) {
6353
+ removeChildren(lineView.lineNumber);
6354
+ lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN)));
6355
+ }
6356
+ cur = lineView.node.nextSibling;
6357
+ }
6358
+ lineN += lineView.size;
6359
  }
6360
+ while (cur) { cur = rm(cur); }
6361
  }
 
 
6362
 
6363
+ function updateGutterSpace(cm) {
6364
+ var width = cm.display.gutters.offsetWidth;
6365
+ cm.display.sizer.style.marginLeft = width + "px";
6366
+ }
 
 
6367
 
6368
+ function setDocumentHeight(cm, measure) {
6369
+ cm.display.sizer.style.minHeight = measure.docHeight + "px";
6370
+ cm.display.heightForcer.style.top = measure.docHeight + "px";
6371
+ cm.display.gutters.style.height = (measure.docHeight + cm.display.barHeight + scrollGap(cm)) + "px";
6372
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6373
 
6374
+ // Rebuild the gutter elements, ensure the margin to the left of the
6375
+ // code matches their width.
6376
+ function updateGutters(cm) {
6377
+ var gutters = cm.display.gutters, specs = cm.options.gutters;
6378
+ removeChildren(gutters);
6379
+ var i = 0;
6380
+ for (; i < specs.length; ++i) {
6381
+ var gutterClass = specs[i];
6382
+ var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
6383
+ if (gutterClass == "CodeMirror-linenumbers") {
6384
+ cm.display.lineGutter = gElt;
6385
+ gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
6386
+ }
6387
+ }
6388
+ gutters.style.display = i ? "" : "none";
6389
+ updateGutterSpace(cm);
6390
+ }
6391
 
6392
+ // Make sure the gutters options contains the element
6393
+ // "CodeMirror-linenumbers" when the lineNumbers option is true.
6394
+ function setGuttersForLineNumbers(options) {
6395
+ var found = indexOf(options.gutters, "CodeMirror-linenumbers");
6396
+ if (found == -1 && options.lineNumbers) {
6397
+ options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]);
6398
+ } else if (found > -1 && !options.lineNumbers) {
6399
+ options.gutters = options.gutters.slice(0);
6400
+ options.gutters.splice(found, 1);
6401
+ }
6402
+ }
6403
 
6404
+ // Since the delta values reported on mouse wheel events are
6405
+ // unstandardized between browsers and even browser versions, and
6406
+ // generally horribly unpredictable, this code starts by measuring
6407
+ // the scroll effect that the first few mouse wheel events have,
6408
+ // and, from that, detects the way it can convert deltas to pixel
6409
+ // offsets afterwards.
6410
+ //
6411
+ // The reason we want to know the amount a wheel event will scroll
6412
+ // is that it gives us a chance to update the display before the
6413
+ // actual scrolling happens, reducing flickering.
6414
+
6415
+ var wheelSamples = 0, wheelPixelsPerUnit = null;
6416
+ // Fill in a browser-detected starting value on browsers where we
6417
+ // know one. These don't have to be accurate -- the result of them
6418
+ // being wrong would just be a slight flicker on the first wheel
6419
+ // scroll (if it is large enough).
6420
+ if (ie) { wheelPixelsPerUnit = -.53; }
6421
+ else if (gecko) { wheelPixelsPerUnit = 15; }
6422
+ else if (chrome) { wheelPixelsPerUnit = -.7; }
6423
+ else if (safari) { wheelPixelsPerUnit = -1/3; }
6424
+
6425
+ function wheelEventDelta(e) {
6426
+ var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
6427
+ if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) { dx = e.detail; }
6428
+ if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) { dy = e.detail; }
6429
+ else if (dy == null) { dy = e.wheelDelta; }
6430
+ return {x: dx, y: dy}
6431
+ }
6432
+ function wheelEventPixels(e) {
6433
+ var delta = wheelEventDelta(e);
6434
+ delta.x *= wheelPixelsPerUnit;
6435
+ delta.y *= wheelPixelsPerUnit;
6436
+ return delta
6437
+ }
6438
+
6439
+ function onScrollWheel(cm, e) {
6440
+ var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y;
6441
+
6442
+ var display = cm.display, scroll = display.scroller;
6443
+ // Quit if there's nothing to scroll here
6444
+ var canScrollX = scroll.scrollWidth > scroll.clientWidth;
6445
+ var canScrollY = scroll.scrollHeight > scroll.clientHeight;
6446
+ if (!(dx && canScrollX || dy && canScrollY)) { return }
6447
+
6448
+ // Webkit browsers on OS X abort momentum scrolls when the target
6449
+ // of the scroll event is removed from the scrollable element.
6450
+ // This hack (see related code in patchDisplay) makes sure the
6451
+ // element is kept around.
6452
+ if (dy && mac && webkit) {
6453
+ outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) {
6454
+ for (var i = 0; i < view.length; i++) {
6455
+ if (view[i].node == cur) {
6456
+ cm.display.currentWheelTarget = cur;
6457
+ break outer
6458
+ }
6459
+ }
6460
+ }
6461
+ }
6462
 
6463
+ // On some browsers, horizontal scrolling will cause redraws to
6464
+ // happen before the gutter has been realigned, causing it to
6465
+ // wriggle around in a most unseemly way. When we have an
6466
+ // estimated pixels/delta value, we just handle horizontal
6467
+ // scrolling entirely here. It'll be slightly off from native, but
6468
+ // better than glitching out.
6469
+ if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {
6470
+ if (dy && canScrollY)
6471
+ { updateScrollTop(cm, Math.max(0, scroll.scrollTop + dy * wheelPixelsPerUnit)); }
6472
+ setScrollLeft(cm, Math.max(0, scroll.scrollLeft + dx * wheelPixelsPerUnit));
6473
+ // Only prevent default scrolling if vertical scrolling is
6474
+ // actually possible. Otherwise, it causes vertical scroll
6475
+ // jitter on OSX trackpads when deltaX is small and deltaY
6476
+ // is large (issue #3579)
6477
+ if (!dy || (dy && canScrollY))
6478
+ { e_preventDefault(e); }
6479
+ display.wheelStartX = null; // Abort measurement, if in progress
6480
+ return
6481
+ }
6482
 
6483
+ // 'Project' the visible viewport to cover the area that is being
6484
+ // scrolled into view (if we know enough to estimate it).
6485
+ if (dy && wheelPixelsPerUnit != null) {
6486
+ var pixels = dy * wheelPixelsPerUnit;
6487
+ var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
6488
+ if (pixels < 0) { top = Math.max(0, top + pixels - 50); }
6489
+ else { bot = Math.min(cm.doc.height, bot + pixels + 50); }
6490
+ updateDisplaySimple(cm, {top: top, bottom: bot});
6491
+ }
6492
+
6493
+ if (wheelSamples < 20) {
6494
+ if (display.wheelStartX == null) {
6495
+ display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
6496
+ display.wheelDX = dx; display.wheelDY = dy;
6497
+ setTimeout(function () {
6498
+ if (display.wheelStartX == null) { return }
6499
+ var movedX = scroll.scrollLeft - display.wheelStartX;
6500
+ var movedY = scroll.scrollTop - display.wheelStartY;
6501
+ var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
6502
+ (movedX && display.wheelDX && movedX / display.wheelDX);
6503
+ display.wheelStartX = display.wheelStartY = null;
6504
+ if (!sample) { return }
6505
+ wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);
6506
+ ++wheelSamples;
6507
+ }, 200);
6508
+ } else {
6509
+ display.wheelDX += dx; display.wheelDY += dy;
6510
+ }
6511
+ }
6512
  }
 
6513
 
6514
+ // Selection objects are immutable. A new one is created every time
6515
+ // the selection changes. A selection is one or more non-overlapping
6516
+ // (and non-touching) ranges, sorted, and an integer that indicates
6517
+ // which one is the primary selection (the one that's scrolled into
6518
+ // view, that getCursor returns, etc).
6519
+ var Selection = function(ranges, primIndex) {
6520
+ this.ranges = ranges;
6521
+ this.primIndex = primIndex;
6522
+ };
6523
 
6524
+ Selection.prototype.primary = function () { return this.ranges[this.primIndex] };
 
 
 
 
 
 
 
 
6525
 
6526
+ Selection.prototype.equals = function (other) {
6527
+ var this$1 = this;
 
 
 
 
 
6528
 
6529
+ if (other == this) { return true }
6530
+ if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) { return false }
6531
+ for (var i = 0; i < this.ranges.length; i++) {
6532
+ var here = this$1.ranges[i], there = other.ranges[i];
6533
+ if (!equalCursorPos(here.anchor, there.anchor) || !equalCursorPos(here.head, there.head)) { return false }
6534
+ }
6535
+ return true
6536
+ };
 
 
6537
 
6538
+ Selection.prototype.deepCopy = function () {
6539
+ var this$1 = this;
6540
 
6541
+ var out = [];
6542
+ for (var i = 0; i < this.ranges.length; i++)
6543
+ { out[i] = new Range(copyPos(this$1.ranges[i].anchor), copyPos(this$1.ranges[i].head)); }
6544
+ return new Selection(out, this.primIndex)
6545
+ };
 
 
 
 
 
 
 
 
 
 
 
 
6546
 
6547
+ Selection.prototype.somethingSelected = function () {
6548
+ var this$1 = this;
 
 
 
 
6549
 
6550
+ for (var i = 0; i < this.ranges.length; i++)
6551
+ { if (!this$1.ranges[i].empty()) { return true } }
6552
+ return false
6553
+ };
 
 
6554
 
6555
+ Selection.prototype.contains = function (pos, end) {
6556
+ var this$1 = this;
 
 
6557
 
6558
+ if (!end) { end = pos; }
6559
+ for (var i = 0; i < this.ranges.length; i++) {
6560
+ var range = this$1.ranges[i];
6561
+ if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0)
6562
+ { return i }
6563
+ }
6564
+ return -1
6565
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6566
 
6567
+ var Range = function(anchor, head) {
6568
+ this.anchor = anchor; this.head = head;
6569
+ };
 
6570
 
6571
+ Range.prototype.from = function () { return minPos(this.anchor, this.head) };
6572
+ Range.prototype.to = function () { return maxPos(this.anchor, this.head) };
6573
+ Range.prototype.empty = function () { return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch };
 
6574
 
6575
+ // Take an unsorted, potentially overlapping set of ranges, and
6576
+ // build a selection out of it. 'Consumes' ranges array (modifying
6577
+ // it).
6578
+ function normalizeSelection(cm, ranges, primIndex) {
6579
+ var mayTouch = cm && cm.options.selectionsMayTouch;
6580
+ var prim = ranges[primIndex];
6581
+ ranges.sort(function (a, b) { return cmp(a.from(), b.from()); });
6582
+ primIndex = indexOf(ranges, prim);
6583
+ for (var i = 1; i < ranges.length; i++) {
6584
+ var cur = ranges[i], prev = ranges[i - 1];
6585
+ var diff = cmp(prev.to(), cur.from());
6586
+ if (mayTouch && !cur.empty() ? diff > 0 : diff >= 0) {
6587
+ var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to());
6588
+ var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head;
6589
+ if (i <= primIndex) { --primIndex; }
6590
+ ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to));
6591
+ }
6592
+ }
6593
+ return new Selection(ranges, primIndex)
6594
+ }
6595
 
6596
+ function simpleSelection(anchor, head) {
6597
+ return new Selection([new Range(anchor, head || anchor)], 0)
6598
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6599
 
6600
+ // Compute the position of the end of a change (its 'to' property
6601
+ // refers to the pre-change end).
6602
+ function changeEnd(change) {
6603
+ if (!change.text) { return change.to }
6604
+ return Pos(change.from.line + change.text.length - 1,
6605
+ lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0))
6606
+ }
6607
+
6608
+ // Adjust a position to refer to the post-change position of the
6609
+ // same text, or the end of the change if the change covers it.
6610
+ function adjustForChange(pos, change) {
6611
+ if (cmp(pos, change.from) < 0) { return pos }
6612
+ if (cmp(pos, change.to) <= 0) { return changeEnd(change) }
6613
 
6614
+ var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;
6615
+ if (pos.line == change.to.line) { ch += changeEnd(change).ch - change.to.ch; }
6616
+ return Pos(line, ch)
6617
+ }
6618
 
6619
+ function computeSelAfterChange(doc, change) {
6620
+ var out = [];
6621
+ for (var i = 0; i < doc.sel.ranges.length; i++) {
6622
+ var range = doc.sel.ranges[i];
6623
+ out.push(new Range(adjustForChange(range.anchor, change),
6624
+ adjustForChange(range.head, change)));
6625
+ }
6626
+ return normalizeSelection(doc.cm, out, doc.sel.primIndex)
6627
+ }
6628
 
6629
+ function offsetPos(pos, old, nw) {
6630
+ if (pos.line == old.line)
6631
+ { return Pos(nw.line, pos.ch - old.ch + nw.ch) }
6632
+ else
6633
+ { return Pos(nw.line + (pos.line - old.line), pos.ch) }
 
 
 
 
6634
  }
 
6635
 
6636
+ // Used by replaceSelections to allow moving the selection to the
6637
+ // start or around the replaced test. Hint may be "start" or "around".
6638
+ function computeReplacedSel(doc, changes, hint) {
6639
+ var out = [];
6640
+ var oldPrev = Pos(doc.first, 0), newPrev = oldPrev;
6641
+ for (var i = 0; i < changes.length; i++) {
6642
+ var change = changes[i];
6643
+ var from = offsetPos(change.from, oldPrev, newPrev);
6644
+ var to = offsetPos(changeEnd(change), oldPrev, newPrev);
6645
+ oldPrev = change.to;
6646
+ newPrev = to;
6647
+ if (hint == "around") {
6648
+ var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0;
6649
+ out[i] = new Range(inv ? to : from, inv ? from : to);
6650
+ } else {
6651
+ out[i] = new Range(from, from);
6652
+ }
6653
+ }
6654
+ return new Selection(out, doc.sel.primIndex)
6655
+ }
 
6656
 
6657
+ // Used to get the editor into a consistent state again when options change.
6658
 
6659
+ function loadMode(cm) {
6660
+ cm.doc.mode = getMode(cm.options, cm.doc.modeOption);
6661
+ resetModeState(cm);
 
 
6662
  }
6663
 
6664
+ function resetModeState(cm) {
6665
+ cm.doc.iter(function (line) {
6666
+ if (line.stateAfter) { line.stateAfter = null; }
6667
+ if (line.styles) { line.styles = null; }
 
6668
  });
6669
+ cm.doc.modeFrontier = cm.doc.highlightFrontier = cm.doc.first;
6670
+ startWorker(cm, 100);
6671
+ cm.state.modeGen++;
6672
+ if (cm.curOp) { regChange(cm); }
6673
+ }
6674
+
6675
+ // DOCUMENT DATA STRUCTURE
6676
+
6677
+ // By default, updates that start and end at the beginning of a line
6678
+ // are treated specially, in order to make the association of line
6679
+ // widgets and marker elements with the text behave more intuitive.
6680
+ function isWholeLineUpdate(doc, change) {
6681
+ return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" &&
6682
+ (!doc.cm || doc.cm.options.wholeLineUpdateBefore)
6683
+ }
6684
+
6685
+ // Perform a change on the document data structure.
6686
+ function updateDoc(doc, change, markedSpans, estimateHeight$$1) {
6687
+ function spansFor(n) {return markedSpans ? markedSpans[n] : null}
6688
+ function update(line, text, spans) {
6689
+ updateLine(line, text, spans, estimateHeight$$1);
6690
+ signalLater(line, "change", line, change);
6691
+ }
6692
+ function linesFor(start, end) {
6693
+ var result = [];
6694
+ for (var i = start; i < end; ++i)
6695
+ { result.push(new Line(text[i], spansFor(i), estimateHeight$$1)); }
6696
+ return result
6697
+ }
6698
+
6699
+ var from = change.from, to = change.to, text = change.text;
6700
+ var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
6701
+ var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
6702
+
6703
+ // Adjust the line structure
6704
+ if (change.full) {
6705
+ doc.insert(0, linesFor(0, text.length));
6706
+ doc.remove(text.length, doc.size - text.length);
6707
+ } else if (isWholeLineUpdate(doc, change)) {
6708
+ // This is a whole-line replace. Treated specially to make
6709
+ // sure line objects move the way they are supposed to.
6710
+ var added = linesFor(0, text.length - 1);
6711
+ update(lastLine, lastLine.text, lastSpans);
6712
+ if (nlines) { doc.remove(from.line, nlines); }
6713
+ if (added.length) { doc.insert(from.line, added); }
6714
+ } else if (firstLine == lastLine) {
6715
+ if (text.length == 1) {
6716
+ update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
6717
+ } else {
6718
+ var added$1 = linesFor(1, text.length - 1);
6719
+ added$1.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight$$1));
6720
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
6721
+ doc.insert(from.line + 1, added$1);
6722
+ }
6723
+ } else if (text.length == 1) {
6724
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0));
6725
+ doc.remove(from.line + 1, nlines);
6726
+ } else {
6727
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
6728
+ update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
6729
+ var added$2 = linesFor(1, text.length - 1);
6730
+ if (nlines > 1) { doc.remove(from.line + 1, nlines - 1); }
6731
+ doc.insert(from.line + 1, added$2);
6732
+ }
6733
 
6734
+ signalLater(doc, "change", doc, change);
6735
+ }
 
 
 
 
 
 
 
6736
 
6737
+ // Call f for all linked documents.
6738
+ function linkedDocs(doc, f, sharedHistOnly) {
6739
+ function propagate(doc, skip, sharedHist) {
6740
+ if (doc.linked) { for (var i = 0; i < doc.linked.length; ++i) {
6741
+ var rel = doc.linked[i];
6742
+ if (rel.doc == skip) { continue }
6743
+ var shared = sharedHist && rel.sharedHist;
6744
+ if (sharedHistOnly && !shared) { continue }
6745
+ f(rel.doc, shared);
6746
+ propagate(rel.doc, doc, shared);
6747
+ } }
6748
+ }
6749
+ propagate(doc, null, true);
6750
+ }
 
6751
 
6752
+ // Attach a document to an editor.
6753
+ function attachDoc(cm, doc) {
6754
+ if (doc.cm) { throw new Error("This document is already in use.") }
6755
+ cm.doc = doc;
6756
+ doc.cm = cm;
6757
+ estimateLineHeights(cm);
6758
+ loadMode(cm);
6759
+ setDirectionClass(cm);
6760
+ if (!cm.options.lineWrapping) { findMaxLine(cm); }
6761
+ cm.options.mode = doc.modeOption;
6762
+ regChange(cm);
6763
+ }
6764
 
6765
+ function setDirectionClass(cm) {
6766
+ (cm.doc.direction == "rtl" ? addClass : rmClass)(cm.display.lineDiv, "CodeMirror-rtl");
6767
+ }
6768
+
6769
+ function directionChanged(cm) {
6770
+ runInOp(cm, function () {
6771
+ setDirectionClass(cm);
6772
+ regChange(cm);
6773
+ });
6774
+ }
6775
 
6776
+ function History(startGen) {
6777
+ // Arrays of change events and selections. Doing something adds an
6778
+ // event to done and clears undo. Undoing moves events from done
6779
+ // to undone, redoing moves them in the other direction.
6780
+ this.done = []; this.undone = [];
6781
+ this.undoDepth = Infinity;
6782
+ // Used to track when changes can be merged into a single undo
6783
+ // event
6784
+ this.lastModTime = this.lastSelTime = 0;
6785
+ this.lastOp = this.lastSelOp = null;
6786
+ this.lastOrigin = this.lastSelOrigin = null;
6787
+ // Used by the isClean() method
6788
+ this.generation = this.maxGeneration = startGen || 1;
6789
+ }
6790
+
6791
+ // Create a history change event from an updateDoc-style change
6792
+ // object.
6793
+ function historyChangeFromChange(doc, change) {
6794
+ var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
6795
+ attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
6796
+ linkedDocs(doc, function (doc) { return attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); }, true);
6797
+ return histChange
6798
+ }
6799
+
6800
+ // Pop all selection events off the end of a history array. Stop at
6801
+ // a change event.
6802
+ function clearSelectionEvents(array) {
6803
+ while (array.length) {
6804
+ var last = lst(array);
6805
+ if (last.ranges) { array.pop(); }
6806
+ else { break }
6807
+ }
6808
+ }
6809
+
6810
+ // Find the top change event in the history. Pop off selection
6811
+ // events that are in the way.
6812
+ function lastChangeEvent(hist, force) {
6813
+ if (force) {
6814
+ clearSelectionEvents(hist.done);
6815
+ return lst(hist.done)
6816
+ } else if (hist.done.length && !lst(hist.done).ranges) {
6817
+ return lst(hist.done)
6818
+ } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) {
6819
+ hist.done.pop();
6820
+ return lst(hist.done)
6821
+ }
6822
+ }
6823
+
6824
+ // Register a change in the history. Merges changes that are within
6825
+ // a single operation, or are close together with an origin that
6826
+ // allows merging (starting with "+") into a single event.
6827
+ function addChangeToHistory(doc, change, selAfter, opId) {
6828
+ var hist = doc.history;
6829
+ hist.undone.length = 0;
6830
+ var time = +new Date, cur;
6831
+ var last;
6832
+
6833
+ if ((hist.lastOp == opId ||
6834
+ hist.lastOrigin == change.origin && change.origin &&
6835
+ ((change.origin.charAt(0) == "+" && hist.lastModTime > time - (doc.cm ? doc.cm.options.historyEventDelay : 500)) ||
6836
+ change.origin.charAt(0) == "*")) &&
6837
+ (cur = lastChangeEvent(hist, hist.lastOp == opId))) {
6838
+ // Merge this change into the last event
6839
+ last = lst(cur.changes);
6840
+ if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) {
6841
+ // Optimized case for simple insertion -- don't want to add
6842
+ // new changesets for every character typed
6843
+ last.to = changeEnd(change);
6844
+ } else {
6845
+ // Add new sub-event
6846
+ cur.changes.push(historyChangeFromChange(doc, change));
6847
+ }
6848
+ } else {
6849
+ // Can not be merged, start a new event.
6850
+ var before = lst(hist.done);
6851
+ if (!before || !before.ranges)
6852
+ { pushSelectionToHistory(doc.sel, hist.done); }
6853
+ cur = {changes: [historyChangeFromChange(doc, change)],
6854
+ generation: hist.generation};
6855
+ hist.done.push(cur);
6856
+ while (hist.done.length > hist.undoDepth) {
6857
+ hist.done.shift();
6858
+ if (!hist.done[0].ranges) { hist.done.shift(); }
6859
+ }
6860
+ }
6861
+ hist.done.push(selAfter);
6862
+ hist.generation = ++hist.maxGeneration;
6863
+ hist.lastModTime = hist.lastSelTime = time;
6864
+ hist.lastOp = hist.lastSelOp = opId;
6865
+ hist.lastOrigin = hist.lastSelOrigin = change.origin;
6866
+
6867
+ if (!last) { signal(doc, "historyAdded"); }
6868
+ }
6869
+
6870
+ function selectionEventCanBeMerged(doc, origin, prev, sel) {
6871
+ var ch = origin.charAt(0);
6872
+ return ch == "*" ||
6873
+ ch == "+" &&
6874
+ prev.ranges.length == sel.ranges.length &&
6875
+ prev.somethingSelected() == sel.somethingSelected() &&
6876
+ new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500)
6877
+ }
6878
+
6879
+ // Called whenever the selection changes, sets the new selection as
6880
+ // the pending selection in the history, and pushes the old pending
6881
+ // selection into the 'done' array when it was significantly
6882
+ // different (in number of selected ranges, emptiness, or time).
6883
+ function addSelectionToHistory(doc, sel, opId, options) {
6884
+ var hist = doc.history, origin = options && options.origin;
6885
+
6886
+ // A new event is started when the previous origin does not match
6887
+ // the current, or the origins don't allow matching. Origins
6888
+ // starting with * are always merged, those starting with + are
6889
+ // merged when similar and close together in time.
6890
+ if (opId == hist.lastSelOp ||
6891
+ (origin && hist.lastSelOrigin == origin &&
6892
+ (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin ||
6893
+ selectionEventCanBeMerged(doc, origin, lst(hist.done), sel))))
6894
+ { hist.done[hist.done.length - 1] = sel; }
6895
+ else
6896
+ { pushSelectionToHistory(sel, hist.done); }
6897
 
6898
+ hist.lastSelTime = +new Date;
6899
+ hist.lastSelOrigin = origin;
6900
+ hist.lastSelOp = opId;
6901
+ if (options && options.clearRedo !== false)
6902
+ { clearSelectionEvents(hist.undone); }
6903
+ }
6904
 
6905
+ function pushSelectionToHistory(sel, dest) {
6906
+ var top = lst(dest);
6907
+ if (!(top && top.ranges && top.equals(sel)))
6908
+ { dest.push(sel); }
 
 
 
 
 
6909
  }
6910
 
6911
+ // Used to store marked span information in the history.
6912
+ function attachLocalSpans(doc, change, from, to) {
6913
+ var existing = change["spans_" + doc.id], n = 0;
6914
+ doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function (line) {
6915
+ if (line.markedSpans)
6916
+ { (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans; }
6917
+ ++n;
6918
+ });
6919
+ }
6920
 
6921
+ // When un/re-doing restores text containing marked spans, those
6922
+ // that have been explicitly cleared should not be restored.
6923
+ function removeClearedSpans(spans) {
6924
+ if (!spans) { return null }
6925
+ var out;
6926
+ for (var i = 0; i < spans.length; ++i) {
6927
+ if (spans[i].marker.explicitlyCleared) { if (!out) { out = spans.slice(0, i); } }
6928
+ else if (out) { out.push(spans[i]); }
6929
+ }
6930
+ return !out ? spans : out.length ? out : null
6931
+ }
6932
+
6933
+ // Retrieve and filter the old marked spans stored in a change event.
6934
+ function getOldSpans(doc, change) {
6935
+ var found = change["spans_" + doc.id];
6936
+ if (!found) { return null }
6937
+ var nw = [];
6938
+ for (var i = 0; i < change.text.length; ++i)
6939
+ { nw.push(removeClearedSpans(found[i])); }
6940
+ return nw
6941
+ }
6942
+
6943
+ // Used for un/re-doing changes from the history. Combines the
6944
+ // result of computing the existing spans with the set of spans that
6945
+ // existed in the history (so that deleting around a span and then
6946
+ // undoing brings back the span).
6947
+ function mergeOldSpans(doc, change) {
6948
+ var old = getOldSpans(doc, change);
6949
+ var stretched = stretchSpansOverChange(doc, change);
6950
+ if (!old) { return stretched }
6951
+ if (!stretched) { return old }
6952
+
6953
+ for (var i = 0; i < old.length; ++i) {
6954
+ var oldCur = old[i], stretchCur = stretched[i];
6955
+ if (oldCur && stretchCur) {
6956
+ spans: for (var j = 0; j < stretchCur.length; ++j) {
6957
+ var span = stretchCur[j];
6958
+ for (var k = 0; k < oldCur.length; ++k)
6959
+ { if (oldCur[k].marker == span.marker) { continue spans } }
6960
+ oldCur.push(span);
6961
+ }
6962
+ } else if (stretchCur) {
6963
+ old[i] = stretchCur;
6964
+ }
6965
+ }
6966
+ return old
6967
+ }
6968
 
6969
+ // Used both to provide a JSON-safe object in .getHistory, and, when
6970
+ // detaching a document, to split the history in two
6971
+ function copyHistoryArray(events, newGroup, instantiateSel) {
6972
+ var copy = [];
6973
+ for (var i = 0; i < events.length; ++i) {
6974
+ var event = events[i];
6975
+ if (event.ranges) {
6976
+ copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event);
6977
+ continue
6978
+ }
6979
+ var changes = event.changes, newChanges = [];
6980
+ copy.push({changes: newChanges});
6981
+ for (var j = 0; j < changes.length; ++j) {
6982
+ var change = changes[j], m = (void 0);
6983
+ newChanges.push({from: change.from, to: change.to, text: change.text});
6984
+ if (newGroup) { for (var prop in change) { if (m = prop.match(/^spans_(\d+)$/)) {
6985
+ if (indexOf(newGroup, Number(m[1])) > -1) {
6986
+ lst(newChanges)[prop] = change[prop];
6987
+ delete change[prop];
6988
+ }
6989
+ } } }
6990
+ }
6991
+ }
6992
+ return copy
6993
  }
6994
 
6995
+ // The 'scroll' parameter given to many of these indicated whether
6996
+ // the new cursor position should be scrolled into view after
6997
+ // modifying the selection.
6998
+
6999
+ // If shift is held or the extend flag is set, extends a range to
7000
+ // include a given position (and optionally a second position).
7001
+ // Otherwise, simply returns the range between the given positions.
7002
+ // Used for cursor motion and such.
7003
+ function extendRange(range, head, other, extend) {
7004
+ if (extend) {
7005
+ var anchor = range.anchor;
7006
+ if (other) {
7007
+ var posBefore = cmp(head, anchor) < 0;
7008
+ if (posBefore != (cmp(other, anchor) < 0)) {
7009
+ anchor = head;
7010
+ head = other;
7011
+ } else if (posBefore != (cmp(head, other) < 0)) {
7012
+ head = other;
7013
+ }
7014
+ }
7015
+ return new Range(anchor, head)
7016
+ } else {
7017
+ return new Range(other || head, head)
7018
+ }
7019
+ }
7020
 
7021
+ // Extend the primary selection range, discard the rest.
7022
+ function extendSelection(doc, head, other, options, extend) {
7023
+ if (extend == null) { extend = doc.cm && (doc.cm.display.shift || doc.extend); }
7024
+ setSelection(doc, new Selection([extendRange(doc.sel.primary(), head, other, extend)], 0), options);
7025
+ }
7026
 
7027
+ // Extend all selections (pos is an array of selections with length
7028
+ // equal the number of selections)
7029
+ function extendSelections(doc, heads, options) {
7030
+ var out = [];
7031
+ var extend = doc.cm && (doc.cm.display.shift || doc.extend);
7032
+ for (var i = 0; i < doc.sel.ranges.length; i++)
7033
+ { out[i] = extendRange(doc.sel.ranges[i], heads[i], null, extend); }
7034
+ var newSel = normalizeSelection(doc.cm, out, doc.sel.primIndex);
7035
+ setSelection(doc, newSel, options);
7036
+ }
7037
 
7038
+ // Updates a single range in the selection.
7039
+ function replaceOneSelection(doc, i, range, options) {
7040
+ var ranges = doc.sel.ranges.slice(0);
7041
+ ranges[i] = range;
7042
+ setSelection(doc, normalizeSelection(doc.cm, ranges, doc.sel.primIndex), options);
7043
+ }
7044
 
7045
+ // Reset the selection to a single range.
7046
+ function setSimpleSelection(doc, anchor, head, options) {
7047
+ setSelection(doc, simpleSelection(anchor, head), options);
7048
+ }
7049
 
7050
+ // Give beforeSelectionChange handlers a change to influence a
7051
+ // selection update.
7052
+ function filterSelectionChange(doc, sel, options) {
7053
+ var obj = {
7054
+ ranges: sel.ranges,
7055
+ update: function(ranges) {
7056
+ var this$1 = this;
7057
 
7058
+ this.ranges = [];
7059
+ for (var i = 0; i < ranges.length; i++)
7060
+ { this$1.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),
7061
+ clipPos(doc, ranges[i].head)); }
7062
+ },
7063
+ origin: options && options.origin
7064
+ };
7065
+ signal(doc, "beforeSelectionChange", doc, obj);
7066
+ if (doc.cm) { signal(doc.cm, "beforeSelectionChange", doc.cm, obj); }
7067
+ if (obj.ranges != sel.ranges) { return normalizeSelection(doc.cm, obj.ranges, obj.ranges.length - 1) }
7068
+ else { return sel }
7069
+ }
7070
 
7071
+ function setSelectionReplaceHistory(doc, sel, options) {
7072
+ var done = doc.history.done, last = lst(done);
7073
+ if (last && last.ranges) {
7074
+ done[done.length - 1] = sel;
7075
+ setSelectionNoUndo(doc, sel, options);
7076
+ } else {
7077
+ setSelection(doc, sel, options);
7078
+ }
7079
  }
7080
 
7081
+ // Set a new selection.
7082
+ function setSelection(doc, sel, options) {
7083
+ setSelectionNoUndo(doc, sel, options);
7084
+ addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options);
7085
+ }
 
 
7086
 
7087
+ function setSelectionNoUndo(doc, sel, options) {
7088
+ if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
7089
+ { sel = filterSelectionChange(doc, sel, options); }
7090
 
7091
+ var bias = options && options.bias ||
7092
+ (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);
7093
+ setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));
 
 
 
7094
 
7095
+ if (!(options && options.scroll === false) && doc.cm)
7096
+ { ensureCursorVisible(doc.cm); }
 
 
 
 
 
 
 
 
 
 
 
 
7097
  }
7098
+
7099
+ function setSelectionInner(doc, sel) {
7100
+ if (sel.equals(doc.sel)) { return }
7101
+
7102
+ doc.sel = sel;
7103
+
7104
+ if (doc.cm) {
7105
+ doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true;
7106
+ signalCursorActivity(doc.cm);
7107
+ }
7108
+ signalLater(doc, "cursorActivity", doc);
7109
  }
7110
+
7111
+ // Verify that the selection does not partially select any atomic
7112
+ // marked ranges.
7113
+ function reCheckSelection(doc) {
7114
+ setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false));
 
 
 
7115
  }
 
7116
 
7117
+ // Return a selection that does not partially select any atomic
7118
+ // ranges.
7119
+ function skipAtomicInSelection(doc, sel, bias, mayClear) {
7120
+ var out;
7121
+ for (var i = 0; i < sel.ranges.length; i++) {
7122
+ var range = sel.ranges[i];
7123
+ var old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i];
7124
+ var newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear);
7125
+ var newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear);
7126
+ if (out || newAnchor != range.anchor || newHead != range.head) {
7127
+ if (!out) { out = sel.ranges.slice(0, i); }
7128
+ out[i] = new Range(newAnchor, newHead);
7129
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7130
  }
7131
+ return out ? normalizeSelection(doc.cm, out, sel.primIndex) : sel
7132
+ }
7133
+
7134
+ function skipAtomicInner(doc, pos, oldPos, dir, mayClear) {
7135
+ var line = getLine(doc, pos.line);
7136
+ if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) {
7137
+ var sp = line.markedSpans[i], m = sp.marker;
7138
+ if ((sp.from == null || (m.inclusiveLeft ? sp.from <= pos.ch : sp.from < pos.ch)) &&
7139
+ (sp.to == null || (m.inclusiveRight ? sp.to >= pos.ch : sp.to > pos.ch))) {
7140
+ if (mayClear) {
7141
+ signal(m, "beforeCursorEnter");
7142
+ if (m.explicitlyCleared) {
7143
+ if (!line.markedSpans) { break }
7144
+ else {--i; continue}
7145
+ }
7146
+ }
7147
+ if (!m.atomic) { continue }
7148
+
7149
+ if (oldPos) {
7150
+ var near = m.find(dir < 0 ? 1 : -1), diff = (void 0);
7151
+ if (dir < 0 ? m.inclusiveRight : m.inclusiveLeft)
7152
+ { near = movePos(doc, near, -dir, near && near.line == pos.line ? line : null); }
7153
+ if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0))
7154
+ { return skipAtomicInner(doc, near, pos, dir, mayClear) }
7155
+ }
7156
+
7157
+ var far = m.find(dir < 0 ? -1 : 1);
7158
+ if (dir < 0 ? m.inclusiveLeft : m.inclusiveRight)
7159
+ { far = movePos(doc, far, dir, far.line == pos.line ? line : null); }
7160
+ return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null
7161
+ }
7162
+ } }
7163
+ return pos
7164
+ }
7165
+
7166
+ // Ensure a given position is not inside an atomic range.
7167
+ function skipAtomic(doc, pos, oldPos, bias, mayClear) {
7168
+ var dir = bias || 1;
7169
+ var found = skipAtomicInner(doc, pos, oldPos, dir, mayClear) ||
7170
+ (!mayClear && skipAtomicInner(doc, pos, oldPos, dir, true)) ||
7171
+ skipAtomicInner(doc, pos, oldPos, -dir, mayClear) ||
7172
+ (!mayClear && skipAtomicInner(doc, pos, oldPos, -dir, true));
7173
+ if (!found) {
7174
+ doc.cantEdit = true;
7175
+ return Pos(doc.first, 0)
7176
  }
7177
+ return found
7178
+ }
7179
+
7180
+ function movePos(doc, pos, dir, line) {
7181
+ if (dir < 0 && pos.ch == 0) {
7182
+ if (pos.line > doc.first) { return clipPos(doc, Pos(pos.line - 1)) }
7183
+ else { return null }
7184
+ } else if (dir > 0 && pos.ch == (line || getLine(doc, pos.line)).text.length) {
7185
+ if (pos.line < doc.first + doc.size - 1) { return Pos(pos.line + 1, 0) }
7186
+ else { return null }
7187
  } else {
7188
+ return new Pos(pos.line, pos.ch + dir)
7189
  }
7190
  }
7191
 
7192
+ function selectAll(cm) {
7193
+ cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);
 
 
 
 
7194
  }
 
7195
 
7196
+ // UPDATING
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7197
 
7198
+ // Allow "beforeChange" event handlers to influence a change
7199
+ function filterChange(doc, change, update) {
7200
+ var obj = {
7201
+ canceled: false,
7202
+ from: change.from,
7203
+ to: change.to,
7204
+ text: change.text,
7205
+ origin: change.origin,
7206
+ cancel: function () { return obj.canceled = true; }
7207
+ };
7208
+ if (update) { obj.update = function (from, to, text, origin) {
7209
+ if (from) { obj.from = clipPos(doc, from); }
7210
+ if (to) { obj.to = clipPos(doc, to); }
7211
+ if (text) { obj.text = text; }
7212
+ if (origin !== undefined) { obj.origin = origin; }
7213
+ }; }
7214
+ signal(doc, "beforeChange", doc, obj);
7215
+ if (doc.cm) { signal(doc.cm, "beforeChange", doc.cm, obj); }
7216
+
7217
+ if (obj.canceled) { return null }
7218
+ return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin}
7219
+ }
7220
+
7221
+ // Apply a change to a document, and add it to the document's
7222
+ // history, and propagating it to all linked documents.
7223
+ function makeChange(doc, change, ignoreReadOnly) {
7224
+ if (doc.cm) {
7225
+ if (!doc.cm.curOp) { return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly) }
7226
+ if (doc.cm.state.suppressEdits) { return }
7227
+ }
7228
+
7229
+ if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) {
7230
+ change = filterChange(doc, change, true);
7231
+ if (!change) { return }
7232
+ }
7233
+
7234
+ // Possibly split or suppress the update based on the presence
7235
+ // of read-only spans in its range.
7236
+ var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);
7237
+ if (split) {
7238
+ for (var i = split.length - 1; i >= 0; --i)
7239
+ { makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text, origin: change.origin}); }
7240
  } else {
7241
+ makeChangeInner(doc, change);
7242
  }
 
7243
  }
 
 
 
 
 
 
 
7244
 
7245
+ function makeChangeInner(doc, change) {
7246
+ if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) { return }
7247
+ var selAfter = computeSelAfterChange(doc, change);
7248
+ addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);
7249
+
7250
+ makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));
7251
+ var rebased = [];
 
 
 
 
 
 
 
 
 
 
 
 
 
7252
 
7253
+ linkedDocs(doc, function (doc, sharedHist) {
7254
+ if (!sharedHist && indexOf(rebased, doc.history) == -1) {
7255
+ rebaseHist(doc.history, change);
7256
+ rebased.push(doc.history);
7257
+ }
7258
+ makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change));
7259
+ });
7260
  }
 
 
7261
 
7262
+ // Revert a change stored in a document's history.
7263
+ function makeChangeFromHistory(doc, type, allowSelectionOnly) {
7264
+ var suppress = doc.cm && doc.cm.state.suppressEdits;
7265
+ if (suppress && !allowSelectionOnly) { return }
7266
 
7267
+ var hist = doc.history, event, selAfter = doc.sel;
7268
+ var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done;
 
 
7269
 
7270
+ // Verify that there is a useable event (so that ctrl-z won't
7271
+ // needlessly clear selection events)
7272
+ var i = 0;
7273
+ for (; i < source.length; i++) {
7274
+ event = source[i];
7275
+ if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges)
7276
+ { break }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7277
  }
7278
+ if (i == source.length) { return }
7279
+ hist.lastOrigin = hist.lastSelOrigin = null;
7280
+
7281
+ for (;;) {
7282
+ event = source.pop();
7283
+ if (event.ranges) {
7284
+ pushSelectionToHistory(event, dest);
7285
+ if (allowSelectionOnly && !event.equals(doc.sel)) {
7286
+ setSelection(doc, event, {clearRedo: false});
7287
+ return
7288
+ }
7289
+ selAfter = event;
7290
+ } else if (suppress) {
7291
+ source.push(event);
7292
+ return
7293
+ } else { break }
7294
  }
 
 
 
 
 
 
 
 
7295
 
7296
+ // Build up a reverse change object to add to the opposite history
7297
+ // stack (redo when undoing, and vice versa).
7298
+ var antiChanges = [];
7299
+ pushSelectionToHistory(selAfter, dest);
7300
+ dest.push({changes: antiChanges, generation: hist.generation});
7301
+ hist.generation = event.generation || ++hist.maxGeneration;
 
 
 
 
 
 
 
 
 
 
7302
 
7303
+ var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange");
 
 
 
 
 
7304
 
7305
+ var loop = function ( i ) {
7306
+ var change = event.changes[i];
7307
+ change.origin = type;
7308
+ if (filter && !filterChange(doc, change, false)) {
7309
+ source.length = 0;
7310
+ return {}
7311
+ }
7312
 
7313
+ antiChanges.push(historyChangeFromChange(doc, change));
 
 
 
 
 
 
 
 
 
7314
 
7315
+ var after = i ? computeSelAfterChange(doc, change) : lst(source);
7316
+ makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
7317
+ if (!i && doc.cm) { doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)}); }
7318
+ var rebased = [];
 
 
 
 
 
 
 
 
 
 
 
 
7319
 
7320
+ // Propagate to the linked documents
7321
+ linkedDocs(doc, function (doc, sharedHist) {
7322
+ if (!sharedHist && indexOf(rebased, doc.history) == -1) {
7323
+ rebaseHist(doc.history, change);
7324
+ rebased.push(doc.history);
7325
+ }
7326
+ makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change));
7327
+ });
7328
+ };
 
 
 
7329
 
7330
+ for (var i$1 = event.changes.length - 1; i$1 >= 0; --i$1) {
7331
+ var returned = loop( i$1 );
 
 
 
7332
 
7333
+ if ( returned ) return returned.v;
7334
+ }
 
7335
  }
7336
 
7337
+ // Sub-views need their line numbers shifted when text is added
7338
+ // above or below them in the parent document.
7339
+ function shiftDoc(doc, distance) {
7340
+ if (distance == 0) { return }
7341
+ doc.first += distance;
7342
+ doc.sel = new Selection(map(doc.sel.ranges, function (range) { return new Range(
7343
+ Pos(range.anchor.line + distance, range.anchor.ch),
7344
+ Pos(range.head.line + distance, range.head.ch)
7345
+ ); }), doc.sel.primIndex);
7346
+ if (doc.cm) {
7347
+ regChange(doc.cm, doc.first, doc.first - distance, distance);
7348
+ for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++)
7349
+ { regLineChange(doc.cm, l, "gutter"); }
7350
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7351
  }
7352
 
7353
+ // More lower-level change function, handling only a single document
7354
+ // (not linked ones).
7355
+ function makeChangeSingleDoc(doc, change, selAfter, spans) {
7356
+ if (doc.cm && !doc.cm.curOp)
7357
+ { return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans) }
7358
 
7359
+ if (change.to.line < doc.first) {
7360
+ shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line));
7361
+ return
7362
+ }
7363
+ if (change.from.line > doc.lastLine()) { return }
7364
 
7365
+ // Clip the change to the size of this doc
7366
+ if (change.from.line < doc.first) {
7367
+ var shift = change.text.length - 1 - (doc.first - change.from.line);
7368
+ shiftDoc(doc, shift);
7369
+ change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),
7370
+ text: [lst(change.text)], origin: change.origin};
7371
+ }
7372
+ var last = doc.lastLine();
7373
+ if (change.to.line > last) {
7374
+ change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),
7375
+ text: [change.text[0]], origin: change.origin};
 
 
7376
  }
 
 
 
 
 
 
 
 
7377
 
7378
+ change.removed = getBetween(doc, change.from, change.to);
 
 
 
 
 
7379
 
7380
+ if (!selAfter) { selAfter = computeSelAfterChange(doc, change); }
7381
+ if (doc.cm) { makeChangeSingleDocInEditor(doc.cm, change, spans); }
7382
+ else { updateDoc(doc, change, spans); }
7383
+ setSelectionNoUndo(doc, selAfter, sel_dontScroll);
 
 
 
 
 
 
7384
  }
 
7385
 
7386
+ // Handle the interaction of a change to a document with the editor
7387
+ // that this document is part of.
7388
+ function makeChangeSingleDocInEditor(cm, change, spans) {
7389
+ var doc = cm.doc, display = cm.display, from = change.from, to = change.to;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7390
 
7391
+ var recomputeMaxLength = false, checkWidthStart = from.line;
7392
+ if (!cm.options.lineWrapping) {
7393
+ checkWidthStart = lineNo(visualLine(getLine(doc, from.line)));
7394
+ doc.iter(checkWidthStart, to.line + 1, function (line) {
7395
+ if (line == display.maxLine) {
7396
+ recomputeMaxLength = true;
7397
+ return true
7398
+ }
7399
+ });
7400
+ }
7401
 
7402
+ if (doc.sel.contains(change.from, change.to) > -1)
7403
+ { signalCursorActivity(cm); }
 
 
 
7404
 
7405
+ updateDoc(doc, change, spans, estimateHeight(cm));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7406
 
7407
+ if (!cm.options.lineWrapping) {
7408
+ doc.iter(checkWidthStart, from.line + change.text.length, function (line) {
7409
+ var len = lineLength(line);
7410
+ if (len > display.maxLineLength) {
7411
+ display.maxLine = line;
7412
+ display.maxLineLength = len;
7413
+ display.maxLineChanged = true;
7414
+ recomputeMaxLength = false;
7415
+ }
7416
+ });
7417
+ if (recomputeMaxLength) { cm.curOp.updateMaxLine = true; }
7418
+ }
7419
 
7420
+ retreatFrontier(doc, from.line);
7421
+ startWorker(cm, 400);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7422
 
7423
+ var lendiff = change.text.length - (to.line - from.line) - 1;
7424
+ // Remember that these lines changed, for updating the display
7425
+ if (change.full)
7426
+ { regChange(cm); }
7427
+ else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))
7428
+ { regLineChange(cm, from.line, "text"); }
7429
+ else
7430
+ { regChange(cm, from.line, to.line + 1, lendiff); }
7431
+
7432
+ var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change");
7433
+ if (changeHandler || changesHandler) {
7434
+ var obj = {
7435
+ from: from, to: to,
7436
+ text: change.text,
7437
+ removed: change.removed,
7438
+ origin: change.origin
7439
+ };
7440
+ if (changeHandler) { signalLater(cm, "change", cm, obj); }
7441
+ if (changesHandler) { (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7442
  }
7443
+ cm.display.selForContextMenu = null;
7444
  }
 
7445
 
7446
+ function replaceRange(doc, code, from, to, origin) {
7447
+ var assign;
 
 
 
 
 
 
 
7448
 
7449
+ if (!to) { to = from; }
7450
+ if (cmp(to, from) < 0) { (assign = [to, from], from = assign[0], to = assign[1]); }
7451
+ if (typeof code == "string") { code = doc.splitLines(code); }
7452
+ makeChange(doc, {from: from, to: to, text: code, origin: origin});
7453
+ }
7454
 
7455
+ // Rebasing/resetting history to deal with externally-sourced changes
 
7456
 
7457
+ function rebaseHistSelSingle(pos, from, to, diff) {
7458
+ if (to < pos.line) {
7459
+ pos.line += diff;
7460
+ } else if (from < pos.line) {
7461
+ pos.line = from;
7462
+ pos.ch = 0;
7463
+ }
7464
  }
 
 
7465
 
7466
+ // Tries to rebase an array of history events given a change in the
7467
+ // document. If the change touches the same lines as the event, the
7468
+ // event, and everything 'behind' it, is discarded. If the change is
7469
+ // before the event, the event's positions are updated. Uses a
7470
+ // copy-on-write scheme for the positions, to avoid having to
7471
+ // reallocate them all on every rebase, but also avoid problems with
7472
+ // shared position objects being unsafely updated.
7473
+ function rebaseHistArray(array, from, to, diff) {
7474
+ for (var i = 0; i < array.length; ++i) {
7475
+ var sub = array[i], ok = true;
7476
+ if (sub.ranges) {
7477
+ if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; }
7478
+ for (var j = 0; j < sub.ranges.length; j++) {
7479
+ rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff);
7480
+ rebaseHistSelSingle(sub.ranges[j].head, from, to, diff);
7481
+ }
7482
+ continue
7483
+ }
7484
+ for (var j$1 = 0; j$1 < sub.changes.length; ++j$1) {
7485
+ var cur = sub.changes[j$1];
7486
+ if (to < cur.from.line) {
7487
+ cur.from = Pos(cur.from.line + diff, cur.from.ch);
7488
+ cur.to = Pos(cur.to.line + diff, cur.to.ch);
7489
+ } else if (from <= cur.to.line) {
7490
+ ok = false;
7491
+ break
7492
+ }
7493
+ }
7494
+ if (!ok) {
7495
+ array.splice(0, i + 1);
7496
+ i = 0;
7497
+ }
7498
+ }
7499
+ }
7500
 
7501
+ function rebaseHist(hist, change) {
7502
+ var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1;
7503
+ rebaseHistArray(hist.done, from, to, diff);
7504
+ rebaseHistArray(hist.undone, from, to, diff);
7505
+ }
7506
 
7507
+ // Utility for applying a change to a line by handle or number,
7508
+ // returning the number and optionally registering the line as
7509
+ // changed.
7510
+ function changeLine(doc, handle, changeType, op) {
7511
+ var no = handle, line = handle;
7512
+ if (typeof handle == "number") { line = getLine(doc, clipLine(doc, handle)); }
7513
+ else { no = lineNo(handle); }
7514
+ if (no == null) { return null }
7515
+ if (op(line, no) && doc.cm) { regLineChange(doc.cm, no, changeType); }
7516
+ return line
7517
+ }
7518
 
7519
+ // The document is represented as a BTree consisting of leaves, with
7520
+ // chunk of lines in them, and branches, with up to ten leaves or
7521
+ // other branch nodes below them. The top node is always a branch
7522
+ // node, and is the document object itself (meaning it has
7523
+ // additional methods and properties).
7524
+ //
7525
+ // All nodes have parent links. The tree is used both to go from
7526
+ // line numbers to line objects, and to go from objects to numbers.
7527
+ // It also indexes by height, and is used to convert between height
7528
+ // and line object, and to find the total height of the document.
7529
+ //
7530
+ // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html
7531
 
7532
+ function LeafChunk(lines) {
7533
  var this$1 = this;
7534
 
7535
+ this.lines = lines;
7536
+ this.parent = null;
7537
+ var height = 0;
7538
+ for (var i = 0; i < lines.length; ++i) {
7539
+ lines[i].parent = this$1;
7540
+ height += lines[i].height;
7541
+ }
7542
+ this.height = height;
7543
  }
 
 
7544
 
7545
+ LeafChunk.prototype = {
7546
+ chunkSize: function() { return this.lines.length },
 
7547
 
7548
+ // Remove the n lines at offset 'at'.
7549
+ removeInner: function(at, n) {
7550
+ var this$1 = this;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7551
 
7552
+ for (var i = at, e = at + n; i < e; ++i) {
7553
+ var line = this$1.lines[i];
7554
+ this$1.height -= line.height;
7555
+ cleanUpLine(line);
7556
+ signalLater(line, "delete");
7557
+ }
7558
+ this.lines.splice(at, n);
7559
+ },
7560
 
7561
+ // Helper used to collapse a small branch into a single leaf.
7562
+ collapse: function(lines) {
7563
+ lines.push.apply(lines, this.lines);
7564
+ },
 
 
 
7565
 
7566
+ // Insert the given array of lines at offset 'at', count them as
7567
+ // having the given height.
7568
+ insertInner: function(at, lines, height) {
7569
+ var this$1 = this;
 
7570
 
7571
+ this.height += height;
7572
+ this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
7573
+ for (var i = 0; i < lines.length; ++i) { lines[i].parent = this$1; }
7574
+ },
7575
 
7576
+ // Used to iterate over a part of the tree.
7577
+ iterN: function(at, n, op) {
7578
+ var this$1 = this;
 
 
 
 
 
 
7579
 
7580
+ for (var e = at + n; at < e; ++at)
7581
+ { if (op(this$1.lines[at])) { return true } }
7582
+ }
7583
+ };
 
 
7584
 
7585
+ function BranchChunk(children) {
7586
+ var this$1 = this;
7587
+
7588
+ this.children = children;
7589
+ var size = 0, height = 0;
7590
+ for (var i = 0; i < children.length; ++i) {
7591
+ var ch = children[i];
7592
+ size += ch.chunkSize(); height += ch.height;
7593
+ ch.parent = this$1;
 
 
 
 
 
 
 
7594
  }
7595
+ this.size = size;
7596
+ this.height = height;
7597
+ this.parent = null;
7598
  }
 
 
7599
 
7600
+ BranchChunk.prototype = {
7601
+ chunkSize: function() { return this.size },
7602
 
7603
+ removeInner: function(at, n) {
7604
+ var this$1 = this;
 
 
7605
 
7606
+ this.size -= n;
7607
+ for (var i = 0; i < this.children.length; ++i) {
7608
+ var child = this$1.children[i], sz = child.chunkSize();
7609
+ if (at < sz) {
7610
+ var rm = Math.min(n, sz - at), oldHeight = child.height;
7611
+ child.removeInner(at, rm);
7612
+ this$1.height -= oldHeight - child.height;
7613
+ if (sz == rm) { this$1.children.splice(i--, 1); child.parent = null; }
7614
+ if ((n -= rm) == 0) { break }
7615
+ at = 0;
7616
+ } else { at -= sz; }
7617
+ }
7618
+ // If the result is smaller than 25 lines, ensure that it is a
7619
+ // single leaf node.
7620
+ if (this.size - n < 25 &&
7621
+ (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) {
7622
+ var lines = [];
7623
+ this.collapse(lines);
7624
+ this.children = [new LeafChunk(lines)];
7625
+ this.children[0].parent = this;
7626
+ }
7627
+ },
7628
 
7629
+ collapse: function(lines) {
7630
+ var this$1 = this;
7631
 
7632
+ for (var i = 0; i < this.children.length; ++i) { this$1.children[i].collapse(lines); }
7633
+ },
 
 
 
 
 
7634
 
7635
+ insertInner: function(at, lines, height) {
7636
+ var this$1 = this;
 
 
 
 
 
 
 
 
 
 
 
7637
 
7638
+ this.size += lines.length;
7639
+ this.height += height;
7640
+ for (var i = 0; i < this.children.length; ++i) {
7641
+ var child = this$1.children[i], sz = child.chunkSize();
7642
+ if (at <= sz) {
7643
+ child.insertInner(at, lines, height);
7644
+ if (child.lines && child.lines.length > 50) {
7645
+ // To avoid memory thrashing when child.lines is huge (e.g. first view of a large file), it's never spliced.
7646
+ // Instead, small slices are taken. They're taken in order because sequential memory accesses are fastest.
7647
+ var remaining = child.lines.length % 25 + 25;
7648
+ for (var pos = remaining; pos < child.lines.length;) {
7649
+ var leaf = new LeafChunk(child.lines.slice(pos, pos += 25));
7650
+ child.height -= leaf.height;
7651
+ this$1.children.splice(++i, 0, leaf);
7652
+ leaf.parent = this$1;
7653
+ }
7654
+ child.lines = child.lines.slice(0, remaining);
7655
+ this$1.maybeSpill();
7656
+ }
7657
+ break
7658
+ }
7659
+ at -= sz;
7660
+ }
7661
+ },
 
 
 
 
 
 
 
 
 
 
7662
 
7663
+ // When a node has grown, check whether it should be split.
7664
+ maybeSpill: function() {
7665
+ if (this.children.length <= 10) { return }
7666
+ var me = this;
7667
+ do {
7668
+ var spilled = me.children.splice(me.children.length - 5, 5);
7669
+ var sibling = new BranchChunk(spilled);
7670
+ if (!me.parent) { // Become the parent node
7671
+ var copy = new BranchChunk(me.children);
7672
+ copy.parent = me;
7673
+ me.children = [copy, sibling];
7674
+ me = copy;
7675
+ } else {
7676
+ me.size -= sibling.size;
7677
+ me.height -= sibling.height;
7678
+ var myIndex = indexOf(me.parent.children, me);
7679
+ me.parent.children.splice(myIndex + 1, 0, sibling);
7680
+ }
7681
+ sibling.parent = me.parent;
7682
+ } while (me.children.length > 10)
7683
+ me.parent.maybeSpill();
7684
+ },
7685
 
7686
+ iterN: function(at, n, op) {
7687
+ var this$1 = this;
 
 
 
 
 
 
 
 
 
 
 
 
7688
 
7689
+ for (var i = 0; i < this.children.length; ++i) {
7690
+ var child = this$1.children[i], sz = child.chunkSize();
7691
+ if (at < sz) {
7692
+ var used = Math.min(n, sz - at);
7693
+ if (child.iterN(at, used, op)) { return true }
7694
+ if ((n -= used) == 0) { break }
7695
+ at = 0;
7696
+ } else { at -= sz; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7697
  }
 
 
 
 
 
7698
  }
7699
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7700
 
7701
+ // Line widgets are block elements displayed above or below a line.
 
 
 
7702
 
7703
+ var LineWidget = function(doc, node, options) {
7704
+ var this$1 = this;
 
 
 
 
 
 
 
 
7705
 
7706
+ if (options) { for (var opt in options) { if (options.hasOwnProperty(opt))
7707
+ { this$1[opt] = options[opt]; } } }
7708
+ this.doc = doc;
7709
+ this.node = node;
7710
+ };
7711
 
7712
+ LineWidget.prototype.clear = function () {
7713
+ var this$1 = this;
7714
 
7715
+ var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line);
7716
+ if (no == null || !ws) { return }
7717
+ for (var i = 0; i < ws.length; ++i) { if (ws[i] == this$1) { ws.splice(i--, 1); } }
7718
+ if (!ws.length) { line.widgets = null; }
7719
+ var height = widgetHeight(this);
7720
+ updateLineHeight(line, Math.max(0, line.height - height));
7721
+ if (cm) {
7722
+ runInOp(cm, function () {
7723
+ adjustScrollWhenAboveVisible(cm, line, -height);
7724
+ regLineChange(cm, no, "widget");
7725
+ });
7726
+ signalLater(cm, "lineWidgetCleared", cm, this, no);
7727
  }
7728
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7729
 
7730
+ LineWidget.prototype.changed = function () {
7731
+ var this$1 = this;
7732
 
7733
+ var oldH = this.height, cm = this.doc.cm, line = this.line;
7734
+ this.height = null;
7735
+ var diff = widgetHeight(this) - oldH;
7736
+ if (!diff) { return }
7737
+ if (!lineIsHidden(this.doc, line)) { updateLineHeight(line, line.height + diff); }
7738
+ if (cm) {
7739
+ runInOp(cm, function () {
7740
+ cm.curOp.forceUpdate = true;
7741
+ adjustScrollWhenAboveVisible(cm, line, diff);
7742
+ signalLater(cm, "lineWidgetChanged", cm, this$1, lineNo(line));
7743
+ });
7744
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7745
  };
7746
+ eventMixin(LineWidget);
7747
+
7748
+ function adjustScrollWhenAboveVisible(cm, line, diff) {
7749
+ if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop))
7750
+ { addToScrollTop(cm, diff); }
7751
+ }
7752
+
7753
+ function addLineWidget(doc, handle, node, options) {
7754
+ var widget = new LineWidget(doc, node, options);
7755
+ var cm = doc.cm;
7756
+ if (cm && widget.noHScroll) { cm.display.alignWidgets = true; }
7757
+ changeLine(doc, handle, "widget", function (line) {
7758
+ var widgets = line.widgets || (line.widgets = []);
7759
+ if (widget.insertAt == null) { widgets.push(widget); }
7760
+ else { widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget); }
7761
+ widget.line = line;
7762
+ if (cm && !lineIsHidden(doc, line)) {
7763
+ var aboveVisible = heightAtLine(line) < doc.scrollTop;
7764
+ updateLineHeight(line, line.height + widgetHeight(widget));
7765
+ if (aboveVisible) { addToScrollTop(cm, widget.height); }
7766
+ cm.curOp.forceUpdate = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7767
  }
7768
+ return true
7769
  });
7770
+ if (cm) { signalLater(cm, "lineWidgetAdded", cm, widget, typeof handle == "number" ? handle : lineNo(handle)); }
7771
+ return widget
7772
  }
7773
 
7774
+ // TEXTMARKERS
 
7775
 
7776
+ // Created with markText and setBookmark methods. A TextMarker is a
7777
+ // handle that can be used to clear or find a marked position in the
7778
+ // document. Line objects hold arrays (markedSpans) containing
7779
+ // {from, to, marker} object pointing to such marker objects, and
7780
+ // indicating that such a marker is present on that line. Multiple
7781
+ // lines may point to the same marker when it spans across lines.
7782
+ // The spans will have null for their from/to properties when the
7783
+ // marker continues beyond the start/end of the line. Markers have
7784
+ // links back to the lines they currently touch.
7785
 
7786
+ // Collapsed markers have unique ids, in order to be able to order
7787
+ // them, which is needed for uniquely determining an outer marker
7788
+ // when they overlap (they may nest, but not partially overlap).
7789
+ var nextMarkerId = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7790
 
7791
+ var TextMarker = function(doc, type) {
7792
+ this.lines = [];
7793
+ this.type = type;
7794
+ this.doc = doc;
7795
+ this.id = ++nextMarkerId;
7796
+ };
7797
 
7798
+ // Clear the marker.
7799
+ TextMarker.prototype.clear = function () {
7800
+ var this$1 = this;
 
 
 
 
 
7801
 
7802
+ if (this.explicitlyCleared) { return }
7803
+ var cm = this.doc.cm, withOp = cm && !cm.curOp;
7804
+ if (withOp) { startOperation(cm); }
7805
+ if (hasHandler(this, "clear")) {
7806
+ var found = this.find();
7807
+ if (found) { signalLater(this, "clear", found.from, found.to); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7808
  }
7809
+ var min = null, max = null;
7810
+ for (var i = 0; i < this.lines.length; ++i) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7811
  var line = this$1.lines[i];
7812
+ var span = getMarkedSpanFor(line.markedSpans, this$1);
7813
+ if (cm && !this$1.collapsed) { regLineChange(cm, lineNo(line), "text"); }
7814
+ else if (cm) {
7815
+ if (span.to != null) { max = lineNo(line); }
7816
+ if (span.from != null) { min = lineNo(line); }
7817
+ }
7818
+ line.markedSpans = removeMarkedSpan(line.markedSpans, span);
7819
+ if (span.from == null && this$1.collapsed && !lineIsHidden(this$1.doc, line) && cm)
7820
+ { updateLineHeight(line, textHeight(cm.display)); }
7821
+ }
7822
+ if (cm && this.collapsed && !cm.options.lineWrapping) { for (var i$1 = 0; i$1 < this.lines.length; ++i$1) {
7823
+ var visual = visualLine(this$1.lines[i$1]), len = lineLength(visual);
7824
+ if (len > cm.display.maxLineLength) {
7825
+ cm.display.maxLine = visual;
7826
+ cm.display.maxLineLength = len;
7827
+ cm.display.maxLineChanged = true;
7828
+ }
7829
+ } }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7830
 
7831
+ if (min != null && cm && this.collapsed) { regChange(cm, min, max + 1); }
7832
+ this.lines.length = 0;
7833
+ this.explicitlyCleared = true;
7834
+ if (this.atomic && this.doc.cantEdit) {
7835
+ this.doc.cantEdit = false;
7836
+ if (cm) { reCheckSelection(cm.doc); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7837
  }
7838
+ if (cm) { signalLater(cm, "markerCleared", cm, this, min, max); }
7839
+ if (withOp) { endOperation(cm); }
7840
+ if (this.parent) { this.parent.clear(); }
7841
+ };
 
 
 
7842
 
7843
+ // Find the position of the marker in the document. Returns a {from,
7844
+ // to} object by default. Side can be passed to get a specific side
7845
+ // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the
7846
+ // Pos objects returned contain a line object, rather than a line
7847
+ // number (used to prevent looking up the same line twice).
7848
+ TextMarker.prototype.find = function (side, lineObj) {
7849
+ var this$1 = this;
7850
 
7851
+ if (side == null && this.type == "bookmark") { side = 1; }
7852
+ var from, to;
7853
+ for (var i = 0; i < this.lines.length; ++i) {
7854
+ var line = this$1.lines[i];
7855
+ var span = getMarkedSpanFor(line.markedSpans, this$1);
7856
+ if (span.from != null) {
7857
+ from = Pos(lineObj ? line : lineNo(line), span.from);
7858
+ if (side == -1) { return from }
7859
+ }
7860
+ if (span.to != null) {
7861
+ to = Pos(lineObj ? line : lineNo(line), span.to);
7862
+ if (side == 1) { return to }
 
 
 
 
 
 
 
 
7863
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7864
  }
7865
+ return from && {from: from, to: to}
7866
+ };
 
 
 
 
 
 
 
 
 
 
 
7867
 
7868
+ // Signals that the marker's widget changed, and surrounding layout
7869
+ // should be recomputed.
7870
+ TextMarker.prototype.changed = function () {
7871
+ var this$1 = this;
7872
 
7873
+ var pos = this.find(-1, true), widget = this, cm = this.doc.cm;
7874
+ if (!pos || !cm) { return }
 
 
 
 
 
7875
  runInOp(cm, function () {
7876
+ var line = pos.line, lineN = lineNo(pos.line);
7877
+ var view = findViewForLine(cm, lineN);
7878
+ if (view) {
7879
+ clearLineMeasurementCacheFor(view);
7880
+ cm.curOp.selectionChanged = cm.curOp.forceUpdate = true;
7881
+ }
7882
+ cm.curOp.updateMaxLine = true;
7883
+ if (!lineIsHidden(widget.doc, line) && widget.height != null) {
7884
+ var oldHeight = widget.height;
7885
+ widget.height = null;
7886
+ var dHeight = widgetHeight(widget) - oldHeight;
7887
+ if (dHeight)
7888
+ { updateLineHeight(line, line.height + dHeight); }
7889
+ }
7890
+ signalLater(cm, "markerChanged", cm, this$1);
7891
  });
7892
+ };
 
 
7893
 
7894
+ TextMarker.prototype.attachLine = function (line) {
7895
+ if (!this.lines.length && this.doc.cm) {
7896
+ var op = this.doc.cm.curOp;
7897
+ if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)
7898
+ { (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this); }
7899
+ }
7900
+ this.lines.push(line);
7901
+ };
7902
 
7903
+ TextMarker.prototype.detachLine = function (line) {
7904
+ this.lines.splice(indexOf(this.lines, line), 1);
7905
+ if (!this.lines.length && this.doc.cm) {
7906
+ var op = this.doc.cm.curOp
7907
+ ;(op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
7908
+ }
7909
+ };
7910
+ eventMixin(TextMarker);
7911
+
7912
+ // Create a marker, wire it up to the right lines, and
7913
+ function markText(doc, from, to, options, type) {
7914
+ // Shared markers (across linked documents) are handled separately
7915
+ // (markTextShared will call out to this again, once per
7916
+ // document).
7917
+ if (options && options.shared) { return markTextShared(doc, from, to, options, type) }
7918
+ // Ensure we are in an operation.
7919
+ if (doc.cm && !doc.cm.curOp) { return operation(doc.cm, markText)(doc, from, to, options, type) }
7920
+
7921
+ var marker = new TextMarker(doc, type), diff = cmp(from, to);
7922
+ if (options) { copyObj(options, marker, false); }
7923
+ // Don't connect empty markers unless clearWhenEmpty is false
7924
+ if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false)
7925
+ { return marker }
7926
+ if (marker.replacedWith) {
7927
+ // Showing up as a widget implies collapsed (widget replaces text)
7928
+ marker.collapsed = true;
7929
+ marker.widgetNode = eltP("span", [marker.replacedWith], "CodeMirror-widget");
7930
+ if (!options.handleMouseEvents) { marker.widgetNode.setAttribute("cm-ignore-events", "true"); }
7931
+ if (options.insertLeft) { marker.widgetNode.insertLeft = true; }
7932
+ }
7933
+ if (marker.collapsed) {
7934
+ if (conflictingCollapsedRange(doc, from.line, from, to, marker) ||
7935
+ from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker))
7936
+ { throw new Error("Inserting collapsed marker partially overlapping an existing one") }
7937
+ seeCollapsedSpans();
7938
+ }
7939
+
7940
+ if (marker.addToHistory)
7941
+ { addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN); }
7942
+
7943
+ var curLine = from.line, cm = doc.cm, updateMaxLine;
7944
+ doc.iter(curLine, to.line + 1, function (line) {
7945
+ if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine)
7946
+ { updateMaxLine = true; }
7947
+ if (marker.collapsed && curLine != from.line) { updateLineHeight(line, 0); }
7948
+ addMarkedSpan(line, new MarkedSpan(marker,
7949
+ curLine == from.line ? from.ch : null,
7950
+ curLine == to.line ? to.ch : null));
7951
+ ++curLine;
7952
  });
7953
+ // lineIsHidden depends on the presence of the spans, so needs a second pass
7954
+ if (marker.collapsed) { doc.iter(from.line, to.line + 1, function (line) {
7955
+ if (lineIsHidden(doc, line)) { updateLineHeight(line, 0); }
7956
+ }); }
7957
 
7958
+ if (marker.clearOnEnter) { on(marker, "beforeCursorEnter", function () { return marker.clear(); }); }
 
 
 
7959
 
7960
+ if (marker.readOnly) {
7961
+ seeReadOnlySpans();
7962
+ if (doc.history.done.length || doc.history.undone.length)
7963
+ { doc.clearHistory(); }
 
 
 
 
 
 
 
 
 
 
7964
  }
7965
+ if (marker.collapsed) {
7966
+ marker.id = ++nextMarkerId;
7967
+ marker.atomic = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7968
  }
7969
+ if (cm) {
7970
+ // Sync editor state
7971
+ if (updateMaxLine) { cm.curOp.updateMaxLine = true; }
7972
+ if (marker.collapsed)
7973
+ { regChange(cm, from.line, to.line + 1); }
7974
+ else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css)
7975
+ { for (var i = from.line; i <= to.line; i++) { regLineChange(cm, i, "text"); } }
7976
+ if (marker.atomic) { reCheckSelection(cm.doc); }
7977
+ signalLater(cm, "markerAdded", cm, marker);
7978
  }
7979
+ return marker
7980
  }
 
 
7981
 
7982
+ // SHARED TEXTMARKERS
 
 
 
7983
 
7984
+ // A shared marker spans multiple linked documents. It is
7985
+ // implemented as a meta-marker-object controlling multiple normal
7986
+ // markers.
7987
+ var SharedTextMarker = function(markers, primary) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7988
  var this$1 = this;
7989
 
7990
+ this.markers = markers;
7991
+ this.primary = primary;
7992
+ for (var i = 0; i < markers.length; ++i)
7993
+ { markers[i].parent = this$1; }
7994
+ };
 
7995
 
7996
+ SharedTextMarker.prototype.clear = function () {
7997
+ var this$1 = this;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7998
 
7999
+ if (this.explicitlyCleared) { return }
8000
+ this.explicitlyCleared = true;
8001
+ for (var i = 0; i < this.markers.length; ++i)
8002
+ { this$1.markers[i].clear(); }
8003
+ signalLater(this, "clear");
8004
+ };
8005
 
8006
+ SharedTextMarker.prototype.find = function (side, lineObj) {
8007
+ return this.primary.find(side, lineObj)
8008
+ };
8009
+ eventMixin(SharedTextMarker);
8010
+
8011
+ function markTextShared(doc, from, to, options, type) {
8012
+ options = copyObj(options);
8013
+ options.shared = false;
8014
+ var markers = [markText(doc, from, to, options, type)], primary = markers[0];
8015
+ var widget = options.widgetNode;
8016
+ linkedDocs(doc, function (doc) {
8017
+ if (widget) { options.widgetNode = widget.cloneNode(true); }
8018
+ markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
8019
+ for (var i = 0; i < doc.linked.length; ++i)
8020
+ { if (doc.linked[i].isParent) { return } }
8021
+ primary = lst(markers);
8022
+ });
8023
+ return new SharedTextMarker(markers, primary)
8024
+ }
8025
+
8026
+ function findSharedMarkers(doc) {
8027
+ return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), function (m) { return m.parent; })
8028
  }
 
8029
 
8030
+ function copySharedMarkers(doc, markers) {
8031
+ for (var i = 0; i < markers.length; i++) {
8032
+ var marker = markers[i], pos = marker.find();
8033
+ var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to);
8034
+ if (cmp(mFrom, mTo)) {
8035
+ var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type);
8036
+ marker.markers.push(subMark);
8037
+ subMark.parent = marker;
 
8038
  }
8039
  }
8040
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8041
 
8042
+ function detachSharedMarkers(markers) {
8043
+ var loop = function ( i ) {
8044
+ var marker = markers[i], linked = [marker.primary.doc];
8045
+ linkedDocs(marker.primary.doc, function (d) { return linked.push(d); });
8046
+ for (var j = 0; j < marker.markers.length; j++) {
8047
+ var subMarker = marker.markers[j];
8048
+ if (indexOf(linked, subMarker.doc) == -1) {
8049
+ subMarker.parent = null;
8050
+ marker.markers.splice(j--, 1);
8051
+ }
8052
+ }
8053
+ };
 
 
 
 
 
 
 
 
 
 
8054
 
8055
+ for (var i = 0; i < markers.length; i++) loop( i );
8056
+ }
8057
+
8058
+ var nextDocId = 0;
8059
+ var Doc = function(text, mode, firstLine, lineSep, direction) {
8060
+ if (!(this instanceof Doc)) { return new Doc(text, mode, firstLine, lineSep, direction) }
8061
+ if (firstLine == null) { firstLine = 0; }
8062
+
8063
+ BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
8064
+ this.first = firstLine;
8065
+ this.scrollTop = this.scrollLeft = 0;
8066
+ this.cantEdit = false;
8067
+ this.cleanGeneration = 1;
8068
+ this.modeFrontier = this.highlightFrontier = firstLine;
8069
+ var start = Pos(firstLine, 0);
8070
+ this.sel = simpleSelection(start);
8071
+ this.history = new History(null);
8072
+ this.id = ++nextDocId;
8073
+ this.modeOption = mode;
8074
+ this.lineSep = lineSep;
8075
+ this.direction = (direction == "rtl") ? "rtl" : "ltr";
8076
+ this.extend = false;
8077
+
8078
+ if (typeof text == "string") { text = this.splitLines(text); }
8079
+ updateDoc(this, {from: start, to: start, text: text});
8080
+ setSelection(this, simpleSelection(start), sel_dontScroll);
8081
+ };
8082
 
8083
+ Doc.prototype = createObj(BranchChunk.prototype, {
8084
+ constructor: Doc,
8085
+ // Iterate over the document. Supports two forms -- with only one
8086
+ // argument, it calls that for each line in the document. With
8087
+ // three, it iterates over the range given by the first two (with
8088
+ // the second being non-inclusive).
8089
+ iter: function(from, to, op) {
8090
+ if (op) { this.iterN(from - this.first, to - from, op); }
8091
+ else { this.iterN(this.first, this.first + this.size, from); }
8092
+ },
8093
 
8094
+ // Non-public interface for adding and removing lines.
8095
+ insert: function(at, lines) {
8096
+ var height = 0;
8097
+ for (var i = 0; i < lines.length; ++i) { height += lines[i].height; }
8098
+ this.insertInner(at - this.first, lines, height);
8099
+ },
8100
+ remove: function(at, n) { this.removeInner(at - this.first, n); },
8101
 
8102
+ // From here, the methods are part of the public interface. Most
8103
+ // are also available from CodeMirror (editor) instances.
 
8104
 
8105
+ getValue: function(lineSep) {
8106
+ var lines = getLines(this, this.first, this.first + this.size);
8107
+ if (lineSep === false) { return lines }
8108
+ return lines.join(lineSep || this.lineSeparator())
8109
+ },
8110
+ setValue: docMethodOp(function(code) {
8111
+ var top = Pos(this.first, 0), last = this.first + this.size - 1;
8112
+ makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
8113
+ text: this.splitLines(code), origin: "setValue", full: true}, true);
8114
+ if (this.cm) { scrollToCoords(this.cm, 0, 0); }
8115
+ setSelection(this, simpleSelection(top), sel_dontScroll);
8116
+ }),
8117
+ replaceRange: function(code, from, to, origin) {
8118
+ from = clipPos(this, from);
8119
+ to = to ? clipPos(this, to) : from;
8120
+ replaceRange(this, code, from, to, origin);
8121
+ },
8122
+ getRange: function(from, to, lineSep) {
8123
+ var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
8124
+ if (lineSep === false) { return lines }
8125
+ return lines.join(lineSep || this.lineSeparator())
8126
+ },
8127
 
8128
+ getLine: function(line) {var l = this.getLineHandle(line); return l && l.text},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8129
 
8130
+ getLineHandle: function(line) {if (isLine(this, line)) { return getLine(this, line) }},
8131
+ getLineNumber: function(line) {return lineNo(line)},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8132
 
8133
+ getLineHandleVisualStart: function(line) {
8134
+ if (typeof line == "number") { line = getLine(this, line); }
8135
+ return visualLine(line)
8136
+ },
 
 
 
 
 
 
8137
 
8138
+ lineCount: function() {return this.size},
8139
+ firstLine: function() {return this.first},
8140
+ lastLine: function() {return this.first + this.size - 1},
 
 
 
 
 
 
 
 
 
 
 
 
 
8141
 
8142
+ clipPos: function(pos) {return clipPos(this, pos)},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8143
 
8144
+ getCursor: function(start) {
8145
+ var range$$1 = this.sel.primary(), pos;
8146
+ if (start == null || start == "head") { pos = range$$1.head; }
8147
+ else if (start == "anchor") { pos = range$$1.anchor; }
8148
+ else if (start == "end" || start == "to" || start === false) { pos = range$$1.to(); }
8149
+ else { pos = range$$1.from(); }
8150
+ return pos
8151
+ },
8152
+ listSelections: function() { return this.sel.ranges },
8153
+ somethingSelected: function() {return this.sel.somethingSelected()},
 
8154
 
8155
+ setCursor: docMethodOp(function(line, ch, options) {
8156
+ setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options);
8157
+ }),
8158
+ setSelection: docMethodOp(function(anchor, head, options) {
8159
+ setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options);
8160
+ }),
8161
+ extendSelection: docMethodOp(function(head, other, options) {
8162
+ extendSelection(this, clipPos(this, head), other && clipPos(this, other), options);
8163
+ }),
8164
+ extendSelections: docMethodOp(function(heads, options) {
8165
+ extendSelections(this, clipPosArray(this, heads), options);
8166
+ }),
8167
+ extendSelectionsBy: docMethodOp(function(f, options) {
8168
+ var heads = map(this.sel.ranges, f);
8169
+ extendSelections(this, clipPosArray(this, heads), options);
8170
+ }),
8171
+ setSelections: docMethodOp(function(ranges, primary, options) {
8172
+ var this$1 = this;
8173
 
8174
+ if (!ranges.length) { return }
8175
+ var out = [];
8176
+ for (var i = 0; i < ranges.length; i++)
8177
+ { out[i] = new Range(clipPos(this$1, ranges[i].anchor),
8178
+ clipPos(this$1, ranges[i].head)); }
8179
+ if (primary == null) { primary = Math.min(ranges.length - 1, this.sel.primIndex); }
8180
+ setSelection(this, normalizeSelection(this.cm, out, primary), options);
8181
+ }),
8182
+ addSelection: docMethodOp(function(anchor, head, options) {
8183
+ var ranges = this.sel.ranges.slice(0);
8184
+ ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor)));
8185
+ setSelection(this, normalizeSelection(this.cm, ranges, ranges.length - 1), options);
8186
+ }),
8187
 
8188
+ getSelection: function(lineSep) {
8189
+ var this$1 = this;
8190
 
8191
+ var ranges = this.sel.ranges, lines;
8192
+ for (var i = 0; i < ranges.length; i++) {
8193
+ var sel = getBetween(this$1, ranges[i].from(), ranges[i].to());
8194
+ lines = lines ? lines.concat(sel) : sel;
 
 
 
8195
  }
8196
+ if (lineSep === false) { return lines }
8197
+ else { return lines.join(lineSep || this.lineSeparator()) }
8198
+ },
8199
+ getSelections: function(lineSep) {
8200
+ var this$1 = this;
 
 
 
 
 
 
 
 
 
 
 
 
 
8201
 
8202
+ var parts = [], ranges = this.sel.ranges;
8203
+ for (var i = 0; i < ranges.length; i++) {
8204
+ var sel = getBetween(this$1, ranges[i].from(), ranges[i].to());
8205
+ if (lineSep !== false) { sel = sel.join(lineSep || this$1.lineSeparator()); }
8206
+ parts[i] = sel;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8207
  }
8208
+ return parts
8209
+ },
8210
+ replaceSelection: function(code, collapse, origin) {
8211
+ var dup = [];
8212
+ for (var i = 0; i < this.sel.ranges.length; i++)
8213
+ { dup[i] = code; }
8214
+ this.replaceSelections(dup, collapse, origin || "+input");
8215
+ },
8216
+ replaceSelections: docMethodOp(function(code, collapse, origin) {
8217
+ var this$1 = this;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8218
 
8219
+ var changes = [], sel = this.sel;
8220
+ for (var i = 0; i < sel.ranges.length; i++) {
8221
+ var range$$1 = sel.ranges[i];
8222
+ changes[i] = {from: range$$1.from(), to: range$$1.to(), text: this$1.splitLines(code[i]), origin: origin};
8223
+ }
8224
+ var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse);
8225
+ for (var i$1 = changes.length - 1; i$1 >= 0; i$1--)
8226
+ { makeChange(this$1, changes[i$1]); }
8227
+ if (newSel) { setSelectionReplaceHistory(this, newSel); }
8228
+ else if (this.cm) { ensureCursorVisible(this.cm); }
8229
+ }),
8230
+ undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}),
8231
+ redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}),
8232
+ undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}),
8233
+ redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}),
8234
+
8235
+ setExtending: function(val) {this.extend = val;},
8236
+ getExtending: function() {return this.extend},
8237
+
8238
+ historySize: function() {
8239
+ var hist = this.history, done = 0, undone = 0;
8240
+ for (var i = 0; i < hist.done.length; i++) { if (!hist.done[i].ranges) { ++done; } }
8241
+ for (var i$1 = 0; i$1 < hist.undone.length; i$1++) { if (!hist.undone[i$1].ranges) { ++undone; } }
8242
+ return {undo: done, redo: undone}
8243
+ },
8244
+ clearHistory: function() {this.history = new History(this.history.maxGeneration);},
8245
 
8246
+ markClean: function() {
8247
+ this.cleanGeneration = this.changeGeneration(true);
8248
+ },
8249
+ changeGeneration: function(forceSplit) {
8250
+ if (forceSplit)
8251
+ { this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null; }
8252
+ return this.history.generation
8253
+ },
8254
+ isClean: function (gen) {
8255
+ return this.history.generation == (gen || this.cleanGeneration)
8256
+ },
 
 
 
8257
 
8258
+ getHistory: function() {
8259
+ return {done: copyHistoryArray(this.history.done),
8260
+ undone: copyHistoryArray(this.history.undone)}
8261
+ },
8262
+ setHistory: function(histData) {
8263
+ var hist = this.history = new History(this.history.maxGeneration);
8264
+ hist.done = copyHistoryArray(histData.done.slice(0), null, true);
8265
+ hist.undone = copyHistoryArray(histData.undone.slice(0), null, true);
8266
+ },
 
 
 
 
 
 
 
 
 
 
8267
 
8268
+ setGutterMarker: docMethodOp(function(line, gutterID, value) {
8269
+ return changeLine(this, line, "gutter", function (line) {
8270
+ var markers = line.gutterMarkers || (line.gutterMarkers = {});
8271
+ markers[gutterID] = value;
8272
+ if (!value && isEmpty(markers)) { line.gutterMarkers = null; }
8273
+ return true
8274
+ })
8275
+ }),
8276
 
8277
+ clearGutter: docMethodOp(function(gutterID) {
8278
+ var this$1 = this;
 
 
 
 
 
 
 
 
 
 
 
 
8279
 
8280
+ this.iter(function (line) {
8281
+ if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
8282
+ changeLine(this$1, line, "gutter", function () {
8283
+ line.gutterMarkers[gutterID] = null;
8284
+ if (isEmpty(line.gutterMarkers)) { line.gutterMarkers = null; }
8285
+ return true
8286
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8287
  }
8288
  });
8289
+ }),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8290
 
8291
+ lineInfo: function(line) {
8292
+ var n;
8293
+ if (typeof line == "number") {
8294
+ if (!isLine(this, line)) { return null }
8295
+ n = line;
8296
+ line = getLine(this, line);
8297
+ if (!line) { return null }
8298
+ } else {
8299
+ n = lineNo(line);
8300
+ if (n == null) { return null }
8301
+ }
8302
+ return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,
8303
+ textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,
8304
+ widgets: line.widgets}
8305
+ },
8306
 
8307
+ addLineClass: docMethodOp(function(handle, where, cls) {
8308
+ return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) {
8309
+ var prop = where == "text" ? "textClass"
8310
+ : where == "background" ? "bgClass"
8311
+ : where == "gutter" ? "gutterClass" : "wrapClass";
8312
+ if (!line[prop]) { line[prop] = cls; }
8313
+ else if (classTest(cls).test(line[prop])) { return false }
8314
+ else { line[prop] += " " + cls; }
8315
+ return true
8316
+ })
8317
+ }),
8318
+ removeLineClass: docMethodOp(function(handle, where, cls) {
8319
+ return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) {
8320
+ var prop = where == "text" ? "textClass"
8321
+ : where == "background" ? "bgClass"
8322
+ : where == "gutter" ? "gutterClass" : "wrapClass";
8323
+ var cur = line[prop];
8324
+ if (!cur) { return false }
8325
+ else if (cls == null) { line[prop] = null; }
8326
+ else {
8327
+ var found = cur.match(classTest(cls));
8328
+ if (!found) { return false }
8329
+ var end = found.index + found[0].length;
8330
+ line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null;
8331
+ }
8332
+ return true
8333
+ })
8334
+ }),
8335
 
8336
+ addLineWidget: docMethodOp(function(handle, node, options) {
8337
+ return addLineWidget(this, handle, node, options)
8338
+ }),
8339
+ removeLineWidget: function(widget) { widget.clear(); },
8340
 
8341
+ markText: function(from, to, options) {
8342
+ return markText(this, clipPos(this, from), clipPos(this, to), options, options && options.type || "range")
8343
+ },
8344
+ setBookmark: function(pos, options) {
8345
+ var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
8346
+ insertLeft: options && options.insertLeft,
8347
+ clearWhenEmpty: false, shared: options && options.shared,
8348
+ handleMouseEvents: options && options.handleMouseEvents};
8349
+ pos = clipPos(this, pos);
8350
+ return markText(this, pos, pos, realOpts, "bookmark")
8351
+ },
8352
+ findMarksAt: function(pos) {
8353
+ pos = clipPos(this, pos);
8354
+ var markers = [], spans = getLine(this, pos.line).markedSpans;
8355
+ if (spans) { for (var i = 0; i < spans.length; ++i) {
8356
+ var span = spans[i];
8357
+ if ((span.from == null || span.from <= pos.ch) &&
8358
+ (span.to == null || span.to >= pos.ch))
8359
+ { markers.push(span.marker.parent || span.marker); }
8360
+ } }
8361
+ return markers
8362
+ },
8363
+ findMarks: function(from, to, filter) {
8364
+ from = clipPos(this, from); to = clipPos(this, to);
8365
+ var found = [], lineNo$$1 = from.line;
8366
+ this.iter(from.line, to.line + 1, function (line) {
8367
+ var spans = line.markedSpans;
8368
+ if (spans) { for (var i = 0; i < spans.length; i++) {
8369
+ var span = spans[i];
8370
+ if (!(span.to != null && lineNo$$1 == from.line && from.ch >= span.to ||
8371
+ span.from == null && lineNo$$1 != from.line ||
8372
+ span.from != null && lineNo$$1 == to.line && span.from >= to.ch) &&
8373
+ (!filter || filter(span.marker)))
8374
+ { found.push(span.marker.parent || span.marker); }
8375
+ } }
8376
+ ++lineNo$$1;
8377
+ });
8378
+ return found
8379
+ },
8380
+ getAllMarks: function() {
8381
+ var markers = [];
8382
+ this.iter(function (line) {
8383
+ var sps = line.markedSpans;
8384
+ if (sps) { for (var i = 0; i < sps.length; ++i)
8385
+ { if (sps[i].from != null) { markers.push(sps[i].marker); } } }
8386
+ });
8387
+ return markers
8388
+ },
8389
 
8390
+ posFromIndex: function(off) {
8391
+ var ch, lineNo$$1 = this.first, sepSize = this.lineSeparator().length;
8392
+ this.iter(function (line) {
8393
+ var sz = line.text.length + sepSize;
8394
+ if (sz > off) { ch = off; return true }
8395
+ off -= sz;
8396
+ ++lineNo$$1;
8397
+ });
8398
+ return clipPos(this, Pos(lineNo$$1, ch))
8399
+ },
8400
+ indexFromPos: function (coords) {
8401
+ coords = clipPos(this, coords);
8402
+ var index = coords.ch;
8403
+ if (coords.line < this.first || coords.ch < 0) { return 0 }
8404
+ var sepSize = this.lineSeparator().length;
8405
+ this.iter(this.first, coords.line, function (line) { // iter aborts when callback returns a truthy value
8406
+ index += line.text.length + sepSize;
8407
+ });
8408
+ return index
8409
+ },
 
 
 
 
 
 
8410
 
8411
+ copy: function(copyHistory) {
8412
+ var doc = new Doc(getLines(this, this.first, this.first + this.size),
8413
+ this.modeOption, this.first, this.lineSep, this.direction);
8414
+ doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
8415
+ doc.sel = this.sel;
8416
+ doc.extend = false;
8417
+ if (copyHistory) {
8418
+ doc.history.undoDepth = this.history.undoDepth;
8419
+ doc.setHistory(this.getHistory());
8420
+ }
8421
+ return doc
8422
+ },
8423
 
8424
+ linkedDoc: function(options) {
8425
+ if (!options) { options = {}; }
8426
+ var from = this.first, to = this.first + this.size;
8427
+ if (options.from != null && options.from > from) { from = options.from; }
8428
+ if (options.to != null && options.to < to) { to = options.to; }
8429
+ var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep, this.direction);
8430
+ if (options.sharedHist) { copy.history = this.history
8431
+ ; }(this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
8432
+ copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
8433
+ copySharedMarkers(copy, findSharedMarkers(this));
8434
+ return copy
8435
+ },
8436
+ unlinkDoc: function(other) {
8437
+ var this$1 = this;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8438
 
8439
+ if (other instanceof CodeMirror) { other = other.doc; }
8440
+ if (this.linked) { for (var i = 0; i < this.linked.length; ++i) {
8441
+ var link = this$1.linked[i];
8442
+ if (link.doc != other) { continue }
8443
+ this$1.linked.splice(i, 1);
8444
+ other.unlinkDoc(this$1);
8445
+ detachSharedMarkers(findSharedMarkers(this$1));
8446
+ break
8447
+ } }
8448
+ // If the histories were shared, split them again
8449
+ if (other.history == this.history) {
8450
+ var splitIds = [other.id];
8451
+ linkedDocs(other, function (doc) { return splitIds.push(doc.id); }, true);
8452
+ other.history = new History(null);
8453
+ other.history.done = copyHistoryArray(this.history.done, splitIds);
8454
+ other.history.undone = copyHistoryArray(this.history.undone, splitIds);
 
 
 
 
 
8455
  }
8456
+ },
8457
+ iterLinkedDocs: function(f) {linkedDocs(this, f);},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8458
 
8459
+ getMode: function() {return this.mode},
8460
+ getEditor: function() {return this.cm},
 
 
 
 
8461
 
8462
+ splitLines: function(str) {
8463
+ if (this.lineSep) { return str.split(this.lineSep) }
8464
+ return splitLinesAuto(str)
8465
+ },
8466
+ lineSeparator: function() { return this.lineSep || "\n" },
8467
+
8468
+ setDirection: docMethodOp(function (dir) {
8469
+ if (dir != "rtl") { dir = "ltr"; }
8470
+ if (dir == this.direction) { return }
8471
+ this.direction = dir;
8472
+ this.iter(function (line) { return line.order = null; });
8473
+ if (this.cm) { directionChanged(this.cm); }
8474
+ })
8475
+ });
8476
 
8477
+ // Public alias.
8478
+ Doc.prototype.eachLine = Doc.prototype.iter;
 
 
 
 
 
 
 
 
8479
 
8480
+ // Kludge to work around strange IE behavior where it'll sometimes
8481
+ // re-fire a series of drag-related events right after the drop (#1551)
8482
+ var lastDrop = 0;
8483
 
8484
+ function onDrop(e) {
8485
+ var cm = this;
8486
+ clearDragCursor(cm);
8487
+ if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))
8488
+ { return }
8489
+ e_preventDefault(e);
8490
+ if (ie) { lastDrop = +new Date; }
8491
+ var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
8492
+ if (!pos || cm.isReadOnly()) { return }
8493
+ // Might be a file drop, in which case we simply extract the text
8494
+ // and insert it.
8495
+ if (files && files.length && window.FileReader && window.File) {
8496
+ var n = files.length, text = Array(n), read = 0;
8497
+ var loadFile = function (file, i) {
8498
+ if (cm.options.allowDropFileTypes &&
8499
+ indexOf(cm.options.allowDropFileTypes, file.type) == -1)
8500
+ { return }
8501
+
8502
+ var reader = new FileReader;
8503
+ reader.onload = operation(cm, function () {
8504
+ var content = reader.result;
8505
+ if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) { content = ""; }
8506
+ text[i] = content;
8507
+ if (++read == n) {
8508
+ pos = clipPos(cm.doc, pos);
8509
+ var change = {from: pos, to: pos,
8510
+ text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())),
8511
+ origin: "paste"};
8512
+ makeChange(cm.doc, change);
8513
+ setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));
8514
+ }
8515
+ });
8516
+ reader.readAsText(file);
8517
+ };
8518
+ for (var i = 0; i < n; ++i) { loadFile(files[i], i); }
8519
+ } else { // Normal drop
8520
+ // Don't do a replace if the drop happened inside of the selected text.
8521
+ if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) {
8522
+ cm.state.draggingText(e);
8523
+ // Ensure the editor is re-focused
8524
+ setTimeout(function () { return cm.display.input.focus(); }, 20);
8525
+ return
8526
+ }
8527
+ try {
8528
+ var text$1 = e.dataTransfer.getData("Text");
8529
+ if (text$1) {
8530
+ var selected;
8531
+ if (cm.state.draggingText && !cm.state.draggingText.copy)
8532
+ { selected = cm.listSelections(); }
8533
+ setSelectionNoUndo(cm.doc, simpleSelection(pos, pos));
8534
+ if (selected) { for (var i$1 = 0; i$1 < selected.length; ++i$1)
8535
+ { replaceRange(cm.doc, "", selected[i$1].anchor, selected[i$1].head, "drag"); } }
8536
+ cm.replaceSelection(text$1, "around", "paste");
8537
+ cm.display.input.focus();
8538
+ }
8539
  }
8540
+ catch(e){}
8541
  }
 
8542
  }
 
 
 
 
 
 
 
 
 
 
 
 
8543
 
8544
+ function onDragStart(cm, e) {
8545
+ if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return }
8546
+ if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) { return }
 
8547
 
8548
+ e.dataTransfer.setData("Text", cm.getSelection());
8549
+ e.dataTransfer.effectAllowed = "copyMove";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8550
 
8551
+ // Use dummy image instead of default browsers image.
8552
+ // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
8553
+ if (e.dataTransfer.setDragImage && !safari) {
8554
+ var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
8555
+ img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
8556
+ if (presto) {
8557
+ img.width = img.height = 1;
8558
+ cm.display.wrapper.appendChild(img);
8559
+ // Force a relayout, or Opera won't use our image for some obscure reason
8560
+ img._top = img.offsetTop;
8561
+ }
8562
+ e.dataTransfer.setDragImage(img, 0, 0);
8563
+ if (presto) { img.parentNode.removeChild(img); }
8564
+ }
 
8565
  }
8566
 
8567
+ function onDragOver(cm, e) {
8568
+ var pos = posFromMouse(cm, e);
8569
+ if (!pos) { return }
8570
+ var frag = document.createDocumentFragment();
8571
+ drawSelectionCursor(cm, pos, frag);
8572
+ if (!cm.display.dragCursor) {
8573
+ cm.display.dragCursor = elt("div", null, "CodeMirror-cursors CodeMirror-dragcursors");
8574
+ cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv);
 
 
 
 
 
 
 
 
8575
  }
8576
+ removeChildrenAndAdd(cm.display.dragCursor, frag);
8577
  }
8578
 
8579
+ function clearDragCursor(cm) {
8580
+ if (cm.display.dragCursor) {
8581
+ cm.display.lineSpace.removeChild(cm.display.dragCursor);
8582
+ cm.display.dragCursor = null;
 
 
 
 
 
 
 
 
 
 
 
8583
  }
8584
+ }
8585
 
8586
+ // These must be handled carefully, because naively registering a
8587
+ // handler for each editor will cause the editors to never be
8588
+ // garbage collected.
8589
 
8590
+ function forEachCodeMirror(f) {
8591
+ if (!document.getElementsByClassName) { return }
8592
+ var byClass = document.getElementsByClassName("CodeMirror");
8593
+ for (var i = 0; i < byClass.length; i++) {
8594
+ var cm = byClass[i].CodeMirror;
8595
+ if (cm) { f(cm); }
8596
+ }
8597
  }
8598
 
8599
+ var globalsRegistered = false;
8600
+ function ensureGlobalHandlers() {
8601
+ if (globalsRegistered) { return }
8602
+ registerGlobalHandlers();
8603
+ globalsRegistered = true;
8604
+ }
8605
+ function registerGlobalHandlers() {
8606
+ // When the window resizes, we need to refresh active editors.
8607
+ var resizeTimer;
8608
+ on(window, "resize", function () {
8609
+ if (resizeTimer == null) { resizeTimer = setTimeout(function () {
8610
+ resizeTimer = null;
8611
+ forEachCodeMirror(onResize);
8612
+ }, 100); }
8613
+ });
8614
+ // When the window loses focus, we want to show the editor as blurred
8615
+ on(window, "blur", function () { return forEachCodeMirror(onBlur); });
8616
+ }
8617
+ // Called when the window resizes
8618
+ function onResize(cm) {
8619
+ var d = cm.display;
8620
+ // Might be a text scaling operation, clear size caches.
8621
+ d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
8622
+ d.scrollbarsClipped = false;
8623
+ cm.setSize();
8624
+ }
8625
+
8626
+ var keyNames = {
8627
+ 3: "Pause", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
8628
+ 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
8629
+ 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
8630
+ 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod",
8631
+ 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete", 145: "ScrollLock",
8632
+ 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
8633
+ 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
8634
+ 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"
8635
+ };
8636
 
8637
+ // Number keys
8638
+ for (var i = 0; i < 10; i++) { keyNames[i + 48] = keyNames[i + 96] = String(i); }
8639
+ // Alphabetic keys
8640
+ for (var i$1 = 65; i$1 <= 90; i$1++) { keyNames[i$1] = String.fromCharCode(i$1); }
8641
+ // Function keys
8642
+ for (var i$2 = 1; i$2 <= 12; i$2++) { keyNames[i$2 + 111] = keyNames[i$2 + 63235] = "F" + i$2; }
8643
+
8644
+ var keyMap = {};
8645
+
8646
+ keyMap.basic = {
8647
+ "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
8648
+ "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
8649
+ "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore",
8650
+ "Tab": "defaultTab", "Shift-Tab": "indentAuto",
8651
+ "Enter": "newlineAndIndent", "Insert": "toggleOverwrite",
8652
+ "Esc": "singleSelection"
8653
+ };
8654
+ // Note that the save and find-related commands aren't defined by
8655
+ // default. User code or addons can define them. Unknown commands
8656
+ // are simply ignored.
8657
+ keyMap.pcDefault = {
8658
+ "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
8659
+ "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown",
8660
+ "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
8661
+ "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
8662
+ "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
8663
+ "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
8664
+ "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection",
8665
+ "fallthrough": "basic"
8666
+ };
8667
+ // Very basic readline/emacs-style bindings, which are standard on Mac.
8668
+ keyMap.emacsy = {
8669
+ "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
8670
+ "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
8671
+ "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
8672
+ "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars",
8673
+ "Ctrl-O": "openLine"
8674
+ };
8675
+ keyMap.macDefault = {
8676
+ "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
8677
+ "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
8678
+ "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore",
8679
+ "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
8680
+ "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
8681
+ "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight",
8682
+ "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd",
8683
+ "fallthrough": ["basic", "emacsy"]
8684
+ };
8685
+ keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
8686
+
8687
+ // KEYMAP DISPATCH
8688
+
8689
+ function normalizeKeyName(name) {
8690
+ var parts = name.split(/-(?!$)/);
8691
+ name = parts[parts.length - 1];
8692
+ var alt, ctrl, shift, cmd;
8693
+ for (var i = 0; i < parts.length - 1; i++) {
8694
+ var mod = parts[i];
8695
+ if (/^(cmd|meta|m)$/i.test(mod)) { cmd = true; }
8696
+ else if (/^a(lt)?$/i.test(mod)) { alt = true; }
8697
+ else if (/^(c|ctrl|control)$/i.test(mod)) { ctrl = true; }
8698
+ else if (/^s(hift)?$/i.test(mod)) { shift = true; }
8699
+ else { throw new Error("Unrecognized modifier name: " + mod) }
8700
+ }
8701
+ if (alt) { name = "Alt-" + name; }
8702
+ if (ctrl) { name = "Ctrl-" + name; }
8703
+ if (cmd) { name = "Cmd-" + name; }
8704
+ if (shift) { name = "Shift-" + name; }
8705
+ return name
8706
+ }
8707
+
8708
+ // This is a kludge to keep keymaps mostly working as raw objects
8709
+ // (backwards compatibility) while at the same time support features
8710
+ // like normalization and multi-stroke key bindings. It compiles a
8711
+ // new normalized keymap, and then updates the old object to reflect
8712
+ // this.
8713
+ function normalizeKeyMap(keymap) {
8714
+ var copy = {};
8715
+ for (var keyname in keymap) { if (keymap.hasOwnProperty(keyname)) {
8716
+ var value = keymap[keyname];
8717
+ if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) { continue }
8718
+ if (value == "...") { delete keymap[keyname]; continue }
8719
+
8720
+ var keys = map(keyname.split(" "), normalizeKeyName);
8721
+ for (var i = 0; i < keys.length; i++) {
8722
+ var val = (void 0), name = (void 0);
8723
+ if (i == keys.length - 1) {
8724
+ name = keys.join(" ");
8725
+ val = value;
8726
+ } else {
8727
+ name = keys.slice(0, i + 1).join(" ");
8728
+ val = "...";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8729
  }
8730
+ var prev = copy[name];
8731
+ if (!prev) { copy[name] = val; }
8732
+ else if (prev != val) { throw new Error("Inconsistent bindings for " + name) }
8733
  }
8734
+ delete keymap[keyname];
8735
+ } }
8736
+ for (var prop in copy) { keymap[prop] = copy[prop]; }
8737
+ return keymap
8738
+ }
 
 
 
 
 
 
 
 
 
 
 
8739
 
8740
+ function lookupKey(key, map$$1, handle, context) {
8741
+ map$$1 = getKeyMap(map$$1);
8742
+ var found = map$$1.call ? map$$1.call(key, context) : map$$1[key];
8743
+ if (found === false) { return "nothing" }
8744
+ if (found === "...") { return "multi" }
8745
+ if (found != null && handle(found)) { return "handled" }
8746
 
8747
+ if (map$$1.fallthrough) {
8748
+ if (Object.prototype.toString.call(map$$1.fallthrough) != "[object Array]")
8749
+ { return lookupKey(key, map$$1.fallthrough, handle, context) }
8750
+ for (var i = 0; i < map$$1.fallthrough.length; i++) {
8751
+ var result = lookupKey(key, map$$1.fallthrough[i], handle, context);
8752
+ if (result) { return result }
8753
+ }
8754
+ }
8755
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8756
 
8757
+ // Modifier key presses don't count as 'real' key presses for the
8758
+ // purpose of keymap fallthrough.
8759
+ function isModifierKey(value) {
8760
+ var name = typeof value == "string" ? value : keyNames[value.keyCode];
8761
+ return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod"
8762
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8763
 
8764
+ function addModifierNames(name, event, noShift) {
8765
+ var base = name;
8766
+ if (event.altKey && base != "Alt") { name = "Alt-" + name; }
8767
+ if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") { name = "Ctrl-" + name; }
8768
+ if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") { name = "Cmd-" + name; }
8769
+ if (!noShift && event.shiftKey && base != "Shift") { name = "Shift-" + name; }
8770
+ return name
8771
  }
 
 
 
8772
 
8773
+ // Look up the name of a key as indicated by an event object.
8774
+ function keyName(event, noShift) {
8775
+ if (presto && event.keyCode == 34 && event["char"]) { return false }
8776
+ var name = keyNames[event.keyCode];
8777
+ if (name == null || event.altGraphKey) { return false }
8778
+ // Ctrl-ScrollLock has keyCode 3, same as Ctrl-Pause,
8779
+ // so we'll use event.code when available (Chrome 48+, FF 38+, Safari 10.1+)
8780
+ if (event.keyCode == 3 && event.code) { name = event.code; }
8781
+ return addModifierNames(name, event, noShift)
8782
+ }
8783
 
8784
+ function getKeyMap(val) {
8785
+ return typeof val == "string" ? keyMap[val] : val
8786
+ }
8787
 
8788
+ // Helper for deleting text near the selection(s), used to implement
8789
+ // backspace, delete, and similar functionality.
8790
+ function deleteNearSelection(cm, compute) {
8791
+ var ranges = cm.doc.sel.ranges, kill = [];
8792
+ // Build up a set of ranges to kill first, merging overlapping
8793
+ // ranges.
8794
+ for (var i = 0; i < ranges.length; i++) {
8795
+ var toKill = compute(ranges[i]);
8796
+ while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) {
8797
+ var replaced = kill.pop();
8798
+ if (cmp(replaced.from, toKill.from) < 0) {
8799
+ toKill.from = replaced.from;
8800
+ break
8801
  }
8802
+ }
8803
+ kill.push(toKill);
8804
+ }
8805
+ // Next, remove those actual ranges.
8806
+ runInOp(cm, function () {
8807
+ for (var i = kill.length - 1; i >= 0; i--)
8808
+ { replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete"); }
8809
+ ensureCursorVisible(cm);
8810
+ });
8811
  }
 
 
 
 
 
 
 
 
 
 
8812
 
8813
+ function moveCharLogically(line, ch, dir) {
8814
+ var target = skipExtendingChars(line.text, ch + dir, dir);
8815
+ return target < 0 || target > line.text.length ? null : target
8816
  }
8817
 
8818
+ function moveLogically(line, start, dir) {
8819
+ var ch = moveCharLogically(line, start.ch, dir);
8820
+ return ch == null ? null : new Pos(start.line, ch, dir < 0 ? "after" : "before")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8821
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8822
 
8823
+ function endOfLine(visually, cm, lineObj, lineNo, dir) {
8824
+ if (visually) {
8825
+ var order = getOrder(lineObj, cm.doc.direction);
8826
+ if (order) {
8827
+ var part = dir < 0 ? lst(order) : order[0];
8828
+ var moveInStorageOrder = (dir < 0) == (part.level == 1);
8829
+ var sticky = moveInStorageOrder ? "after" : "before";
8830
+ var ch;
8831
+ // With a wrapped rtl chunk (possibly spanning multiple bidi parts),
8832
+ // it could be that the last bidi part is not on the last visual line,
8833
+ // since visual lines contain content order-consecutive chunks.
8834
+ // Thus, in rtl, we are looking for the first (content-order) character
8835
+ // in the rtl chunk that is on the last line (that is, the same line
8836
+ // as the last (content-order) character).
8837
+ if (part.level > 0 || cm.doc.direction == "rtl") {
8838
+ var prep = prepareMeasureForLine(cm, lineObj);
8839
+ ch = dir < 0 ? lineObj.text.length - 1 : 0;
8840
+ var targetTop = measureCharPrepared(cm, prep, ch).top;
8841
+ ch = findFirst(function (ch) { return measureCharPrepared(cm, prep, ch).top == targetTop; }, (dir < 0) == (part.level == 1) ? part.from : part.to - 1, ch);
8842
+ if (sticky == "before") { ch = moveCharLogically(lineObj, ch, 1); }
8843
+ } else { ch = dir < 0 ? part.to : part.from; }
8844
+ return new Pos(lineNo, ch, sticky)
8845
+ }
8846
+ }
8847
+ return new Pos(lineNo, dir < 0 ? lineObj.text.length : 0, dir < 0 ? "before" : "after")
8848
+ }
8849
+
8850
+ function moveVisually(cm, line, start, dir) {
8851
+ var bidi = getOrder(line, cm.doc.direction);
8852
+ if (!bidi) { return moveLogically(line, start, dir) }
8853
+ if (start.ch >= line.text.length) {
8854
+ start.ch = line.text.length;
8855
+ start.sticky = "before";
8856
+ } else if (start.ch <= 0) {
8857
+ start.ch = 0;
8858
+ start.sticky = "after";
8859
+ }
8860
+ var partPos = getBidiPartAt(bidi, start.ch, start.sticky), part = bidi[partPos];
8861
+ if (cm.doc.direction == "ltr" && part.level % 2 == 0 && (dir > 0 ? part.to > start.ch : part.from < start.ch)) {
8862
+ // Case 1: We move within an ltr part in an ltr editor. Even with wrapped lines,
8863
+ // nothing interesting happens.
8864
+ return moveLogically(line, start, dir)
8865
+ }
8866
+
8867
+ var mv = function (pos, dir) { return moveCharLogically(line, pos instanceof Pos ? pos.ch : pos, dir); };
8868
+ var prep;
8869
+ var getWrappedLineExtent = function (ch) {
8870
+ if (!cm.options.lineWrapping) { return {begin: 0, end: line.text.length} }
8871
+ prep = prep || prepareMeasureForLine(cm, line);
8872
+ return wrappedLineExtentChar(cm, line, prep, ch)
8873
+ };
8874
+ var wrappedLineExtent = getWrappedLineExtent(start.sticky == "before" ? mv(start, -1) : start.ch);
8875
 
8876
+ if (cm.doc.direction == "rtl" || part.level == 1) {
8877
+ var moveInStorageOrder = (part.level == 1) == (dir < 0);
8878
+ var ch = mv(start, moveInStorageOrder ? 1 : -1);
8879
+ if (ch != null && (!moveInStorageOrder ? ch >= part.from && ch >= wrappedLineExtent.begin : ch <= part.to && ch <= wrappedLineExtent.end)) {
8880
+ // Case 2: We move within an rtl part or in an rtl editor on the same visual line
8881
+ var sticky = moveInStorageOrder ? "before" : "after";
8882
+ return new Pos(start.line, ch, sticky)
8883
+ }
8884
  }
 
 
 
 
8885
 
8886
+ // Case 3: Could not move within this bidi part in this visual line, so leave
8887
+ // the current bidi part
 
 
8888
 
8889
+ var searchInVisualLine = function (partPos, dir, wrappedLineExtent) {
8890
+ var getRes = function (ch, moveInStorageOrder) { return moveInStorageOrder
8891
+ ? new Pos(start.line, mv(ch, 1), "before")
8892
+ : new Pos(start.line, ch, "after"); };
 
 
 
 
 
 
 
 
8893
 
8894
+ for (; partPos >= 0 && partPos < bidi.length; partPos += dir) {
8895
+ var part = bidi[partPos];
8896
+ var moveInStorageOrder = (dir > 0) == (part.level != 1);
8897
+ var ch = moveInStorageOrder ? wrappedLineExtent.begin : mv(wrappedLineExtent.end, -1);
8898
+ if (part.from <= ch && ch < part.to) { return getRes(ch, moveInStorageOrder) }
8899
+ ch = moveInStorageOrder ? part.from : mv(part.to, -1);
8900
+ if (wrappedLineExtent.begin <= ch && ch < wrappedLineExtent.end) { return getRes(ch, moveInStorageOrder) }
8901
+ }
8902
+ };
8903
 
8904
+ // Case 3a: Look for other bidi parts on the same visual line
8905
+ var res = searchInVisualLine(partPos + dir, dir, wrappedLineExtent);
8906
+ if (res) { return res }
 
 
8907
 
8908
+ // Case 3b: Look for other bidi parts on the next visual line
8909
+ var nextCh = dir > 0 ? wrappedLineExtent.end : mv(wrappedLineExtent.begin, -1);
8910
+ if (nextCh != null && !(dir > 0 && nextCh == line.text.length)) {
8911
+ res = searchInVisualLine(dir > 0 ? 0 : bidi.length - 1, dir, getWrappedLineExtent(nextCh));
8912
+ if (res) { return res }
8913
+ }
8914
 
8915
+ // Case 4: Nowhere to move
8916
+ return null
 
 
 
 
 
 
 
 
 
 
 
 
 
8917
  }
 
8918
 
8919
+ // Commands are parameter-less actions that can be performed on an
8920
+ // editor, mostly used for keybindings.
8921
+ var commands = {
8922
+ selectAll: selectAll,
8923
+ singleSelection: function (cm) { return cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll); },
8924
+ killLine: function (cm) { return deleteNearSelection(cm, function (range) {
8925
+ if (range.empty()) {
8926
+ var len = getLine(cm.doc, range.head.line).text.length;
8927
+ if (range.head.ch == len && range.head.line < cm.lastLine())
8928
+ { return {from: range.head, to: Pos(range.head.line + 1, 0)} }
8929
+ else
8930
+ { return {from: range.head, to: Pos(range.head.line, len)} }
8931
+ } else {
8932
+ return {from: range.from(), to: range.to()}
8933
+ }
8934
+ }); },
8935
+ deleteLine: function (cm) { return deleteNearSelection(cm, function (range) { return ({
8936
+ from: Pos(range.from().line, 0),
8937
+ to: clipPos(cm.doc, Pos(range.to().line + 1, 0))
8938
+ }); }); },
8939
+ delLineLeft: function (cm) { return deleteNearSelection(cm, function (range) { return ({
8940
+ from: Pos(range.from().line, 0), to: range.from()
8941
+ }); }); },
8942
+ delWrappedLineLeft: function (cm) { return deleteNearSelection(cm, function (range) {
8943
+ var top = cm.charCoords(range.head, "div").top + 5;
8944
+ var leftPos = cm.coordsChar({left: 0, top: top}, "div");
8945
+ return {from: leftPos, to: range.from()}
8946
+ }); },
8947
+ delWrappedLineRight: function (cm) { return deleteNearSelection(cm, function (range) {
8948
+ var top = cm.charCoords(range.head, "div").top + 5;
8949
+ var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div");
8950
+ return {from: range.from(), to: rightPos }
8951
+ }); },
8952
+ undo: function (cm) { return cm.undo(); },
8953
+ redo: function (cm) { return cm.redo(); },
8954
+ undoSelection: function (cm) { return cm.undoSelection(); },
8955
+ redoSelection: function (cm) { return cm.redoSelection(); },
8956
+ goDocStart: function (cm) { return cm.extendSelection(Pos(cm.firstLine(), 0)); },
8957
+ goDocEnd: function (cm) { return cm.extendSelection(Pos(cm.lastLine())); },
8958
+ goLineStart: function (cm) { return cm.extendSelectionsBy(function (range) { return lineStart(cm, range.head.line); },
8959
+ {origin: "+move", bias: 1}
8960
+ ); },
8961
+ goLineStartSmart: function (cm) { return cm.extendSelectionsBy(function (range) { return lineStartSmart(cm, range.head); },
8962
+ {origin: "+move", bias: 1}
8963
+ ); },
8964
+ goLineEnd: function (cm) { return cm.extendSelectionsBy(function (range) { return lineEnd(cm, range.head.line); },
8965
+ {origin: "+move", bias: -1}
8966
+ ); },
8967
+ goLineRight: function (cm) { return cm.extendSelectionsBy(function (range) {
8968
+ var top = cm.cursorCoords(range.head, "div").top + 5;
8969
+ return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div")
8970
+ }, sel_move); },
8971
+ goLineLeft: function (cm) { return cm.extendSelectionsBy(function (range) {
8972
+ var top = cm.cursorCoords(range.head, "div").top + 5;
8973
+ return cm.coordsChar({left: 0, top: top}, "div")
8974
+ }, sel_move); },
8975
+ goLineLeftSmart: function (cm) { return cm.extendSelectionsBy(function (range) {
8976
+ var top = cm.cursorCoords(range.head, "div").top + 5;
8977
+ var pos = cm.coordsChar({left: 0, top: top}, "div");
8978
+ if (pos.ch < cm.getLine(pos.line).search(/\S/)) { return lineStartSmart(cm, range.head) }
8979
+ return pos
8980
+ }, sel_move); },
8981
+ goLineUp: function (cm) { return cm.moveV(-1, "line"); },
8982
+ goLineDown: function (cm) { return cm.moveV(1, "line"); },
8983
+ goPageUp: function (cm) { return cm.moveV(-1, "page"); },
8984
+ goPageDown: function (cm) { return cm.moveV(1, "page"); },
8985
+ goCharLeft: function (cm) { return cm.moveH(-1, "char"); },
8986
+ goCharRight: function (cm) { return cm.moveH(1, "char"); },
8987
+ goColumnLeft: function (cm) { return cm.moveH(-1, "column"); },
8988
+ goColumnRight: function (cm) { return cm.moveH(1, "column"); },
8989
+ goWordLeft: function (cm) { return cm.moveH(-1, "word"); },
8990
+ goGroupRight: function (cm) { return cm.moveH(1, "group"); },
8991
+ goGroupLeft: function (cm) { return cm.moveH(-1, "group"); },
8992
+ goWordRight: function (cm) { return cm.moveH(1, "word"); },
8993
+ delCharBefore: function (cm) { return cm.deleteH(-1, "char"); },
8994
+ delCharAfter: function (cm) { return cm.deleteH(1, "char"); },
8995
+ delWordBefore: function (cm) { return cm.deleteH(-1, "word"); },
8996
+ delWordAfter: function (cm) { return cm.deleteH(1, "word"); },
8997
+ delGroupBefore: function (cm) { return cm.deleteH(-1, "group"); },
8998
+ delGroupAfter: function (cm) { return cm.deleteH(1, "group"); },
8999
+ indentAuto: function (cm) { return cm.indentSelection("smart"); },
9000
+ indentMore: function (cm) { return cm.indentSelection("add"); },
9001
+ indentLess: function (cm) { return cm.indentSelection("subtract"); },
9002
+ insertTab: function (cm) { return cm.replaceSelection("\t"); },
9003
+ insertSoftTab: function (cm) {
9004
+ var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize;
9005
+ for (var i = 0; i < ranges.length; i++) {
9006
+ var pos = ranges[i].from();
9007
+ var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize);
9008
+ spaces.push(spaceStr(tabSize - col % tabSize));
9009
+ }
9010
+ cm.replaceSelections(spaces);
9011
+ },
9012
+ defaultTab: function (cm) {
9013
+ if (cm.somethingSelected()) { cm.indentSelection("add"); }
9014
+ else { cm.execCommand("insertTab"); }
9015
+ },
9016
+ // Swap the two chars left and right of each selection's head.
9017
+ // Move cursor behind the two swapped characters afterwards.
9018
+ //
9019
+ // Doesn't consider line feeds a character.
9020
+ // Doesn't scan more than one line above to find a character.
9021
+ // Doesn't do anything on an empty line.
9022
+ // Doesn't do anything with non-empty selections.
9023
+ transposeChars: function (cm) { return runInOp(cm, function () {
9024
+ var ranges = cm.listSelections(), newSel = [];
9025
+ for (var i = 0; i < ranges.length; i++) {
9026
+ if (!ranges[i].empty()) { continue }
9027
+ var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text;
9028
+ if (line) {
9029
+ if (cur.ch == line.length) { cur = new Pos(cur.line, cur.ch - 1); }
9030
+ if (cur.ch > 0) {
9031
+ cur = new Pos(cur.line, cur.ch + 1);
9032
+ cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2),
9033
+ Pos(cur.line, cur.ch - 2), cur, "+transpose");
9034
+ } else if (cur.line > cm.doc.first) {
9035
+ var prev = getLine(cm.doc, cur.line - 1).text;
9036
+ if (prev) {
9037
+ cur = new Pos(cur.line, 1);
9038
+ cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() +
9039
+ prev.charAt(prev.length - 1),
9040
+ Pos(cur.line - 1, prev.length - 1), cur, "+transpose");
9041
+ }
9042
+ }
9043
+ }
9044
+ newSel.push(new Range(cur, cur));
9045
+ }
9046
+ cm.setSelections(newSel);
9047
+ }); },
9048
+ newlineAndIndent: function (cm) { return runInOp(cm, function () {
9049
+ var sels = cm.listSelections();
9050
+ for (var i = sels.length - 1; i >= 0; i--)
9051
+ { cm.replaceRange(cm.doc.lineSeparator(), sels[i].anchor, sels[i].head, "+input"); }
9052
+ sels = cm.listSelections();
9053
+ for (var i$1 = 0; i$1 < sels.length; i$1++)
9054
+ { cm.indentLine(sels[i$1].from().line, null, true); }
9055
+ ensureCursorVisible(cm);
9056
+ }); },
9057
+ openLine: function (cm) { return cm.replaceSelection("\n", "start"); },
9058
+ toggleOverwrite: function (cm) { return cm.toggleOverwrite(); }
9059
+ };
9060
 
 
 
 
 
 
9061
 
9062
+ function lineStart(cm, lineN) {
9063
+ var line = getLine(cm.doc, lineN);
9064
+ var visual = visualLine(line);
9065
+ if (visual != line) { lineN = lineNo(visual); }
9066
+ return endOfLine(true, cm, visual, lineN, 1)
9067
+ }
9068
+ function lineEnd(cm, lineN) {
9069
+ var line = getLine(cm.doc, lineN);
9070
+ var visual = visualLineEnd(line);
9071
+ if (visual != line) { lineN = lineNo(visual); }
9072
+ return endOfLine(true, cm, line, lineN, -1)
9073
+ }
9074
+ function lineStartSmart(cm, pos) {
9075
+ var start = lineStart(cm, pos.line);
9076
+ var line = getLine(cm.doc, start.line);
9077
+ var order = getOrder(line, cm.doc.direction);
9078
+ if (!order || order[0].level == 0) {
9079
+ var firstNonWS = Math.max(0, line.text.search(/\S/));
9080
+ var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch;
9081
+ return Pos(start.line, inWS ? 0 : firstNonWS, start.sticky)
9082
+ }
9083
+ return start
9084
+ }
9085
+
9086
+ // Run a handler that was bound to a key.
9087
+ function doHandleBinding(cm, bound, dropShift) {
9088
+ if (typeof bound == "string") {
9089
+ bound = commands[bound];
9090
+ if (!bound) { return false }
9091
+ }
9092
+ // Ensure previous input has been read, so that the handler sees a
9093
+ // consistent view of the document
9094
+ cm.display.input.ensurePolled();
9095
+ var prevShift = cm.display.shift, done = false;
9096
  try {
9097
  if (cm.isReadOnly()) { cm.state.suppressEdits = true; }
9098
+ if (dropShift) { cm.display.shift = false; }
9099
+ done = bound(cm) != Pass;
9100
  } finally {
9101
+ cm.display.shift = prevShift;
9102
  cm.state.suppressEdits = false;
9103
  }
9104
  return done
9105
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9106
 
9107
+ function lookupKeyForEditor(cm, name, handle) {
9108
+ for (var i = 0; i < cm.state.keyMaps.length; i++) {
9109
+ var result = lookupKey(name, cm.state.keyMaps[i], handle, cm);
9110
+ if (result) { return result }
9111
+ }
9112
+ return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm))
9113
+ || lookupKey(name, cm.options.keyMap, handle, cm)
9114
+ }
9115
 
9116
+ // Note that, despite the name, this function is also used to check
9117
+ // for bound mouse clicks.
9118
 
9119
+ var stopSeq = new Delayed;
 
 
 
 
 
 
 
 
9120
 
9121
+ function dispatchKey(cm, name, e, handle) {
9122
+ var seq = cm.state.keySeq;
9123
+ if (seq) {
9124
+ if (isModifierKey(name)) { return "handled" }
9125
+ if (/\'$/.test(name))
9126
+ { cm.state.keySeq = null; }
 
 
 
 
 
 
 
 
 
 
 
 
9127
  else
9128
+ { stopSeq.set(50, function () {
9129
+ if (cm.state.keySeq == seq) {
9130
+ cm.state.keySeq = null;
9131
+ cm.display.input.reset();
9132
+ }
9133
+ }); }
9134
+ if (dispatchKeyInner(cm, seq + " " + name, e, handle)) { return true }
9135
  }
9136
+ return dispatchKeyInner(cm, name, e, handle)
9137
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9138
 
9139
+ function dispatchKeyInner(cm, name, e, handle) {
9140
+ var result = lookupKeyForEditor(cm, name, handle);
 
 
9141
 
9142
+ if (result == "multi")
9143
+ { cm.state.keySeq = name; }
9144
+ if (result == "handled")
9145
+ { signalLater(cm, "keyHandled", cm, name, e); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9146
 
9147
+ if (result == "handled" || result == "multi") {
9148
+ e_preventDefault(e);
9149
+ restartBlink(cm);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9150
  }
 
9151
 
9152
+ return !!result
 
 
 
 
 
 
 
9153
  }
9154
 
9155
+ // Handle a key from the keydown event.
9156
+ function handleKeyBinding(cm, e) {
9157
+ var name = keyName(e, true);
9158
+ if (!name) { return false }
 
 
 
 
 
9159
 
9160
+ if (e.shiftKey && !cm.state.keySeq) {
9161
+ // First try to resolve full name (including 'Shift-'). Failing
9162
+ // that, see if there is a cursor-motion command (starting with
9163
+ // 'go') bound to the keyname without 'Shift-'.
9164
+ return dispatchKey(cm, "Shift-" + name, e, function (b) { return doHandleBinding(cm, b, true