WP Meta and Date Remover - Version 1.5

Version Description

Download this release

Release Info

Developer prasadkirpekar
Plugin Icon 128x128 WP Meta and Date Remover
Version 1.5
Comparing to
See all releases

Code changes from version 1.3.0 to 1.5

Hello-world-after.png DELETED
Binary file
Hello-world-before.png DELETED
Binary file
admin/options.php DELETED
@@ -1,39 +0,0 @@
1
- <div class='wrap'>
2
- <h2>WP meta and Date Remover<span style="float:right;text-decoration:underline;"><a target="_blank" href="http://bit.ly/2bzAUb6">Buy Premium support</a>
3
- <br/>
4
- <a target="_blank" href="https://wordpress.org/support/view/plugin-reviews/wp-meta-and-date-remover?rate=5#postform">Vote up this plugin</a>
5
- <br/>
6
- <a href="https://paypal.me/prasadkirpekar">Donate few bucks</a>
7
- <br/>
8
- </span></h2>
9
-
10
- <form method='post' action="<?php echo $action_url ?>">
11
-
12
- <input type="hidden" name="submitted" value="1" />
13
- <table class="form-table">
14
-
15
- <tr>
16
- <th>Remove from Home page<p>Plugin will remove meta and date from home page</p></th>
17
- <td><input type="checkbox" value="1" <?php if($from_['home']=="1") echo "checked='checked'" ;?> name="wpmdr_from_home"/></td>
18
- </tr>
19
- <tr>
20
- <th>Disable PHP removal<p>Plugin will not remove Meta and Date information from source code</p></th>
21
- <td><input type="checkbox" value="1" <?php if(get_option('wpmdr_disable_php')=="1") echo "checked='checked'" ;?> name="wpmdr_disable_php"/></td>
22
- </tr>
23
- <tr>
24
- <th>Disable CSS removal<p>Plugin will not hide Meta data classes of theme</p></th>
25
- <td><input type="checkbox" value="1" <?php if(get_option('wpmdr_disable_css')=="1") echo "checked='checked'" ;?> name="wpmdr_disable_css"/></td>
26
- </tr>
27
- <tr>
28
- <th>Customize CSS<p>This CSS is being used to hide Meta data classes of theme</p></th>
29
- <td><a target="_blank" href="http://bit.ly/2bzAUb6">I need help to set up this</a><br/><textarea style="width:50%;height:200px;" name='wpmdr_css'><?php echo $css; ?></textarea></td>
30
- </tr>
31
- <tr>
32
- <td><?php submit_button(); ?></td>
33
- <td></td>
34
- </tr>
35
- <tr><td><a href="http://prasadkirpekar.com/wordpress/wordpress-tutorials/how-to-remove-meta-and-date-from-wordpress-posts-or-pages/" target="_blank">Addtional Text like <i>By</i> or <i>posted by</i> is still visible?</a></td><tr>
36
- </table>
37
- </form>
38
-
39
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/wpmdr-options.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="card" style="max-width:100%;margin:10px!important">
2
+ <div class="card-content">
3
+ <h4>WP Meta and Date Remover</h4>
4
+ <a href="http://bit.ly/DCPfW" style="margin-left:63%; " class="waves-effect violet wpmdr-hover waves-light btn">Build Custom Feature for your Website</a>
5
+
6
+ </div>
7
+ </div>
8
+ <div class="row">
9
+ <div class="col m9">
10
+ <div class="card" style="max-width:100%;height:850px">
11
+ <div class="card-content">
12
+ <form method="post" action="<?php echo $action_url;?>">
13
+ <input type="hidden" name="submitted" value="1" />
14
+ <p>
15
+ <input type="checkbox" value="1" <?php if($from_['home']=="1") echo "checked='checked'" ;?> name="wpmdr_from_home" id="home_remove" />
16
+ <label for="home_remove">Remove from Home Page</label>
17
+ <p><blockquote style="font-size:18px">Uncheck this if you want to show dates on Home Page or Post list page.</blockquote></p>
18
+ </p>
19
+ <p>
20
+ <input type="checkbox" value="1" <?php if(get_option('wpmdr_disable_php')=="1") echo "checked='checked'" ;?> name="wpmdr_disable_php" id="php_remove" />
21
+ <label for="php_remove">Disable PHP removal</label>
22
+ <p><blockquote style="font-size:18px">Clicking this will disable php filter for your dates and other meta data.
23
+ Search engines will show your dates in snippet.</blockquote></p>
24
+ </p>
25
+ <br/>
26
+ <p>
27
+ <input type="checkbox" value="1" <?php if(get_option('wpmdr_disable_css')=="1") echo "checked='checked'" ;?> name="wpmdr_disable_css" id="css_remove" />
28
+ <label for="css_remove">Disable CSS removal</label>
29
+ <p><blockquote style="font-size:18px">Clicking this will disable CSS filter for your dates and other meta data.
30
+ Sometimes disabling this leaves unwanted text, icons on page that were added by theme.</blockquote></p>
31
+ </p>
32
+ <p>
33
+ <blockquote style="font-size:18px">Also Read <a target="_blank" href="http://bit.ly/2tx3gHD">How to remove additional text like <b>"by", "posted by"</b> etc</a></blockquote>
34
+ </p>
35
+ <br/>
36
+ <p>
37
+ <p><label style="font-size:18px">
38
+ Set Custom CSS
39
+
40
+ <a style="margin-left:65.5%" class="btn purpule wpmdr-hover">I need help to setup this</a>
41
+ </label></p>
42
+
43
+ <textarea id="ct" name='wpmdr_css'><?php echo $css; ?></textarea>
44
+ <a href="http://bit.ly/2sHInch" target="_blank" class="btn orange grey side-btn">Advanced Custom CSS</a>
45
+ <script>
46
+ jQuery(window).on("load",function(){
47
+ var se = CodeMirror.fromTextArea(document.getElementById("ct"), {
48
+
49
+ matchBrackets: true,
50
+ autofocus: true,
51
+ theme:"dracula",
52
+ mode: "css"
53
+ });
54
+ });
55
+ </script>
56
+ </p>
57
+ <p>
58
+
59
+
60
+
61
+ <br/>
62
+ <input value="Save Changes" type="submit" style="float:right" class="waves-effect waves-light btn" />
63
+ </p>
64
+ </form>
65
+ </div>
66
+ </div>
67
+ </div>
68
+ <div class="col m3">
69
+ <div class="card">
70
+ <div class="card-content">
71
+ <a target="_blank" href="https://wordpress.org/support/view/plugin-reviews/wp-meta-and-date-remover?rate=5#postform" class="btn green pulse side-btn">Vote Up</a>
72
+ <br/><br/>
73
+ <a href="http://bit.ly/PKDonate" class="btn blue pulse side-btn">Donate</a>
74
+ <br/><br/>
75
+ <a target="_blank" href="http://bit.ly/2bzAUb6" class="btn orange pulse side-btn">Buy Support</a>
76
+
77
+ </div>
78
+ </div>
79
+ </div>
80
+ </div>
81
+
include/codemirror/autorefresh.js ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"))
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod)
9
+ else // Plain browser env
10
+ mod(CodeMirror)
11
+ })(function(CodeMirror) {
12
+ "use strict"
13
+
14
+ CodeMirror.defineOption("autoRefresh", false, function(cm, val) {
15
+ if (cm.state.autoRefresh) {
16
+ stopListening(cm, cm.state.autoRefresh)
17
+ cm.state.autoRefresh = null
18
+ }
19
+ if (val && cm.display.wrapper.offsetHeight == 0)
20
+ startListening(cm, cm.state.autoRefresh = {delay: val.delay || 250})
21
+ })
22
+
23
+ function startListening(cm, state) {
24
+ function check() {
25
+ if (cm.display.wrapper.offsetHeight) {
26
+ stopListening(cm, state)
27
+ if (cm.display.lastWrapHeight != cm.display.wrapper.clientHeight)
28
+ cm.refresh()
29
+ } else {
30
+ state.timeout = setTimeout(check, state.delay)
31
+ }
32
+ }
33
+ state.timeout = setTimeout(check, state.delay)
34
+ state.hurry = function() {
35
+ clearTimeout(state.timeout)
36
+ state.timeout = setTimeout(check, 50)
37
+ }
38
+ CodeMirror.on(window, "mouseup", state.hurry)
39
+ CodeMirror.on(window, "keyup", state.hurry)
40
+ }
41
+
42
+ function stopListening(_cm, state) {
43
+ clearTimeout(state.timeout)
44
+ CodeMirror.off(window, "mouseup", state.hurry)
45
+ CodeMirror.off(window, "keyup", state.hurry)
46
+ }
47
+ });
include/codemirror/cm_init.js ADDED
File without changes
include/codemirror/codemirror.css ADDED
@@ -0,0 +1,340 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* BASICS */
2
+
3
+ .CodeMirror {
4
+ /* Set height, width, borders, and global font properties here */
5
+ font-family: monospace;
6
+ height: 300px;
7
+ color: black;
8
+ }
9
+
10
+ /* PADDING */
11
+
12
+ .CodeMirror-lines {
13
+ padding: 4px 0; /* Vertical padding around content */
14
+ }
15
+ .CodeMirror pre {
16
+ padding: 0 4px; /* Horizontal padding of content */
17
+ }
18
+
19
+ .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
20
+ background-color: white; /* The little square between H and V scrollbars */
21
+ }
22
+
23
+ /* GUTTER */
24
+
25
+ .CodeMirror-gutters {
26
+ border-right: 1px solid #ddd;
27
+ background-color: #f7f7f7;
28
+ white-space: nowrap;
29
+ }
30
+ .CodeMirror-linenumbers {}
31
+ .CodeMirror-linenumber {
32
+ padding: 0 3px 0 5px;
33
+ min-width: 20px;
34
+ text-align: right;
35
+ color: #999;
36
+ white-space: nowrap;
37
+ }
38
+
39
+ .CodeMirror-guttermarker { color: black; }
40
+ .CodeMirror-guttermarker-subtle { color: #999; }
41
+
42
+ /* CURSOR */
43
+
44
+ .CodeMirror-cursor {
45
+ border-left: 1px solid black;
46
+ border-right: none;
47
+ width: 0;
48
+ }
49
+ /* Shown when moving in bi-directional text */
50
+ .CodeMirror div.CodeMirror-secondarycursor {
51
+ border-left: 1px solid silver;
52
+ }
53
+ .cm-fat-cursor .CodeMirror-cursor {
54
+ width: auto;
55
+ border: 0 !important;
56
+ background: #7e7;
57
+ }
58
+ .cm-fat-cursor div.CodeMirror-cursors {
59
+ z-index: 1;
60
+ }
61
+
62
+ .cm-animate-fat-cursor {
63
+ width: auto;
64
+ border: 0;
65
+ -webkit-animation: blink 1.06s steps(1) infinite;
66
+ -moz-animation: blink 1.06s steps(1) infinite;
67
+ animation: blink 1.06s steps(1) infinite;
68
+ background-color: #7e7;
69
+ }
70
+ @-moz-keyframes blink {
71
+ 0% {}
72
+ 50% { background-color: transparent; }
73
+ 100% {}
74
+ }
75
+ @-webkit-keyframes blink {
76
+ 0% {}
77
+ 50% { background-color: transparent; }
78
+ 100% {}
79
+ }
80
+ @keyframes blink {
81
+ 0% {}
82
+ 50% { background-color: transparent; }
83
+ 100% {}
84
+ }
85
+
86
+ /* Can style cursor different in overwrite (non-insert) mode */
87
+ .CodeMirror-overwrite .CodeMirror-cursor {}
88
+
89
+ .cm-tab { display: inline-block; text-decoration: inherit; }
90
+
91
+ .CodeMirror-rulers {
92
+ position: absolute;
93
+ left: 0; right: 0; top: -50px; bottom: -20px;
94
+ overflow: hidden;
95
+ }
96
+ .CodeMirror-ruler {
97
+ border-left: 1px solid #ccc;
98
+ top: 0; bottom: 0;
99
+ position: absolute;
100
+ }
101
+
102
+ /* DEFAULT THEME */
103
+
104
+ .cm-s-default .cm-header {color: blue;}
105
+ .cm-s-default .cm-quote {color: #090;}
106
+ .cm-negative {color: #d44;}
107
+ .cm-positive {color: #292;}
108
+ .cm-header, .cm-strong {font-weight: bold;}
109
+ .cm-em {font-style: italic;}
110
+ .cm-link {text-decoration: underline;}
111
+ .cm-strikethrough {text-decoration: line-through;}
112
+
113
+ .cm-s-default .cm-keyword {color: #708;}
114
+ .cm-s-default .cm-atom {color: #219;}
115
+ .cm-s-default .cm-number {color: #164;}
116
+ .cm-s-default .cm-def {color: #00f;}
117
+ .cm-s-default .cm-variable,
118
+ .cm-s-default .cm-punctuation,
119
+ .cm-s-default .cm-property,
120
+ .cm-s-default .cm-operator {}
121
+ .cm-s-default .cm-variable-2 {color: #05a;}
122
+ .cm-s-default .cm-variable-3 {color: #085;}
123
+ .cm-s-default .cm-comment {color: #a50;}
124
+ .cm-s-default .cm-string {color: #a11;}
125
+ .cm-s-default .cm-string-2 {color: #f50;}
126
+ .cm-s-default .cm-meta {color: #555;}
127
+ .cm-s-default .cm-qualifier {color: #555;}
128
+ .cm-s-default .cm-builtin {color: #30a;}
129
+ .cm-s-default .cm-bracket {color: #997;}
130
+ .cm-s-default .cm-tag {color: #170;}
131
+ .cm-s-default .cm-attribute {color: #00c;}
132
+ .cm-s-default .cm-hr {color: #999;}
133
+ .cm-s-default .cm-link {color: #00c;}
134
+
135
+ .cm-s-default .cm-error {color: #f00;}
136
+ .cm-invalidchar {color: #f00;}
137
+
138
+ .CodeMirror-composing { border-bottom: 2px solid; }
139
+
140
+ /* Default styles for common addons */
141
+
142
+ div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
143
+ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
144
+ .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
145
+ .CodeMirror-activeline-background {background: #e8f2ff;}
146
+
147
+ /* STOP */
148
+
149
+ /* The rest of this file contains styles related to the mechanics of
150
+ the editor. You probably shouldn't touch them. */
151
+
152
+ .CodeMirror {
153
+ position: relative;
154
+ overflow: hidden;
155
+ background: white;
156
+ }
157
+
158
+ .CodeMirror-scroll {
159
+ overflow: scroll !important; /* Things will break if this is overridden */
160
+ /* 30px is the magic margin used to hide the element's real scrollbars */
161
+ /* See overflow: hidden in .CodeMirror */
162
+ margin-bottom: -30px; margin-right: -30px;
163
+ padding-bottom: 30px;
164
+ height: 100%;
165
+ outline: none; /* Prevent dragging from highlighting the element */
166
+ position: relative;
167
+ }
168
+ .CodeMirror-sizer {
169
+ position: relative;
170
+ border-right: 30px solid transparent;
171
+ }
172
+
173
+ /* The fake, visible scrollbars. Used to force redraw during scrolling
174
+ before actual scrolling happens, thus preventing shaking and
175
+ flickering artifacts. */
176
+ .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
177
+ position: absolute;
178
+ z-index: 6;
179
+ display: none;
180
+ }
181
+ .CodeMirror-vscrollbar {
182
+ right: 0; top: 0;
183
+ overflow-x: hidden;
184
+ overflow-y: scroll;
185
+ }
186
+ .CodeMirror-hscrollbar {
187
+ bottom: 0; left: 0;
188
+ overflow-y: hidden;
189
+ overflow-x: scroll;
190
+ }
191
+ .CodeMirror-scrollbar-filler {
192
+ right: 0; bottom: 0;
193
+ }
194
+ .CodeMirror-gutter-filler {
195
+ left: 0; bottom: 0;
196
+ }
197
+
198
+ .CodeMirror-gutters {
199
+ position: absolute; left: 0; top: 0;
200
+ min-height: 100%;
201
+ z-index: 3;
202
+ }
203
+ .CodeMirror-gutter {
204
+ white-space: normal;
205
+ height: 100%;
206
+ display: inline-block;
207
+ vertical-align: top;
208
+ margin-bottom: -30px;
209
+ }
210
+ .CodeMirror-gutter-wrapper {
211
+ position: absolute;
212
+ z-index: 4;
213
+ background: none !important;
214
+ border: none !important;
215
+ }
216
+ .CodeMirror-gutter-background {
217
+ position: absolute;
218
+ top: 0; bottom: 0;
219
+ z-index: 4;
220
+ }
221
+ .CodeMirror-gutter-elt {
222
+ position: absolute;
223
+ cursor: default;
224
+ z-index: 4;
225
+ }
226
+ .CodeMirror-gutter-wrapper ::selection { background-color: transparent }
227
+ .CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
228
+
229
+ .CodeMirror-lines {
230
+ cursor: text;
231
+ min-height: 1px; /* prevents collapsing before first draw */
232
+ }
233
+ .CodeMirror pre {
234
+ /* Reset some styles that the rest of the page might have set */
235
+ -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
236
+ border-width: 0;
237
+ background: transparent;
238
+ font-family: inherit;
239
+ font-size: inherit;
240
+ margin: 0;
241
+ white-space: pre;
242
+ word-wrap: normal;
243
+ line-height: inherit;
244
+ color: inherit;
245
+ z-index: 2;
246
+ position: relative;
247
+ overflow: visible;
248
+ -webkit-tap-highlight-color: transparent;
249
+ -webkit-font-variant-ligatures: contextual;
250
+ font-variant-ligatures: contextual;
251
+ }
252
+ .CodeMirror-wrap pre {
253
+ word-wrap: break-word;
254
+ white-space: pre-wrap;
255
+ word-break: normal;
256
+ }
257
+
258
+ .CodeMirror-linebackground {
259
+ position: absolute;
260
+ left: 0; right: 0; top: 0; bottom: 0;
261
+ z-index: 0;
262
+ }
263
+
264
+ .CodeMirror-linewidget {
265
+ position: relative;
266
+ z-index: 2;
267
+ overflow: auto;
268
+ }
269
+
270
+ .CodeMirror-widget {}
271
+
272
+ .CodeMirror-rtl pre { direction: rtl; }
273
+
274
+ .CodeMirror-code {
275
+ outline: none;
276
+ }
277
+
278
+ /* Force content-box sizing for the elements where we expect it */
279
+ .CodeMirror-scroll,
280
+ .CodeMirror-sizer,
281
+ .CodeMirror-gutter,
282
+ .CodeMirror-gutters,
283
+ .CodeMirror-linenumber {
284
+ -moz-box-sizing: content-box;
285
+ box-sizing: content-box;
286
+ }
287
+
288
+ .CodeMirror-measure {
289
+ position: absolute;
290
+ width: 100%;
291
+ height: 0;
292
+ overflow: hidden;
293
+ visibility: hidden;
294
+ }
295
+
296
+ .CodeMirror-cursor {
297
+ position: absolute;
298
+ pointer-events: none;
299
+ }
300
+ .CodeMirror-measure pre { position: static; }
301
+
302
+ div.CodeMirror-cursors {
303
+ visibility: hidden;
304
+ position: relative;
305
+ z-index: 3;
306
+ }
307
+ div.CodeMirror-dragcursors {
308
+ visibility: visible;
309
+ }
310
+
311
+ .CodeMirror-focused div.CodeMirror-cursors {
312
+ visibility: visible;
313
+ }
314
+
315
+ .CodeMirror-selected { background: #d9d9d9; }
316
+ .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
317
+ .CodeMirror-crosshair { cursor: crosshair; }
318
+ .CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
319
+ .CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
320
+
321
+ .cm-searching {
322
+ background: #ffa;
323
+ background: rgba(255, 255, 0, .4);
324
+ }
325
+
326
+ /* Used to force a border model for a node */
327
+ .cm-force-border { padding-right: .1px; }
328
+
329
+ @media print {
330
+ /* Hide the cursor when printing */
331
+ .CodeMirror div.CodeMirror-cursors {
332
+ visibility: hidden;
333
+ }
334
+ }
335
+
336
+ /* See issue #2901 */
337
+ .cm-tab-wrap-hack:after { content: ''; }
338
+
339
+ /* Help users use markselection to safely style text background */
340
+ span.CodeMirror-selectedtext { background: none; }
include/codemirror/codemirror.js ADDED
@@ -0,0 +1,9351 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ // This is CodeMirror (http://codemirror.net), a code editor
5
+ // implemented in JavaScript on top of the browser's DOM.
6
+ //
7
+ // You can find some technical background for some of the code below
8
+ // at http://marijnhaverbeke.nl/blog/#cm-internals .
9
+
10
+ (function (global, factory) {
11
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
12
+ typeof define === 'function' && define.amd ? define(factory) :
13
+ (global.CodeMirror = factory());
14
+ }(this, (function () { 'use strict';
15
+
16
+ // Kludges for bugs and behavior differences that can't be feature
17
+ // detected are enabled based on userAgent etc sniffing.
18
+ var userAgent = navigator.userAgent
19
+ var platform = navigator.platform
20
+
21
+ var gecko = /gecko\/\d/i.test(userAgent)
22
+ var ie_upto10 = /MSIE \d/.test(userAgent)
23
+ var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent)
24
+ var edge = /Edge\/(\d+)/.exec(userAgent)
25
+ var ie = ie_upto10 || ie_11up || edge
26
+ var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : +(edge || ie_11up)[1])
27
+ var webkit = !edge && /WebKit\//.test(userAgent)
28
+ var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent)
29
+ var chrome = !edge && /Chrome\//.test(userAgent)
30
+ var presto = /Opera\//.test(userAgent)
31
+ var safari = /Apple Computer/.test(navigator.vendor)
32
+ var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent)
33
+ var phantom = /PhantomJS/.test(userAgent)
34
+
35
+ var ios = !edge && /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent)
36
+ var android = /Android/.test(userAgent)
37
+ // This is woefully incomplete. Suggestions for alternative methods welcome.
38
+ var mobile = ios || android || /webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent)
39
+ var mac = ios || /Mac/.test(platform)
40
+ var chromeOS = /\bCrOS\b/.test(userAgent)
41
+ var windows = /win/i.test(platform)
42
+
43
+ var presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/)
44
+ if (presto_version) { presto_version = Number(presto_version[1]) }
45
+ if (presto_version && presto_version >= 15) { presto = false; webkit = true }
46
+ // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
47
+ var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11))
48
+ var captureRightClick = gecko || (ie && ie_version >= 9)
49
+
50
+ function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") }
51
+
52
+ var rmClass = function(node, cls) {
53
+ var current = node.className
54
+ var match = classTest(cls).exec(current)
55
+ if (match) {
56
+ var after = current.slice(match.index + match[0].length)
57
+ node.className = current.slice(0, match.index) + (after ? match[1] + after : "")
58
+ }
59
+ }
60
+
61
+ function removeChildren(e) {
62
+ for (var count = e.childNodes.length; count > 0; --count)
63
+ { e.removeChild(e.firstChild) }
64
+ return e
65
+ }
66
+
67
+ function removeChildrenAndAdd(parent, e) {
68
+ return removeChildren(parent).appendChild(e)
69
+ }
70
+
71
+ function elt(tag, content, className, style) {
72
+ var e = document.createElement(tag)
73
+ if (className) { e.className = className }
74
+ if (style) { e.style.cssText = style }
75
+ if (typeof content == "string") { e.appendChild(document.createTextNode(content)) }
76
+ else if (content) { for (var i = 0; i < content.length; ++i) { e.appendChild(content[i]) } }
77
+ return e
78
+ }
79
+ // wrapper for elt, which removes the elt from the accessibility tree
80
+ function eltP(tag, content, className, style) {
81
+ var e = elt(tag, content, className, style)
82
+ e.setAttribute("role", "presentation")
83
+ return e
84
+ }
85
+
86
+ var range
87
+ if (document.createRange) { range = function(node, start, end, endNode) {
88
+ var r = document.createRange()
89
+ r.setEnd(endNode || node, end)
90
+ r.setStart(node, start)
91
+ return r
92
+ } }
93
+ else { range = function(node, start, end) {
94
+ var r = document.body.createTextRange()
95
+ try { r.moveToElementText(node.parentNode) }
96
+ catch(e) { return r }
97
+ r.collapse(true)
98
+ r.moveEnd("character", end)
99
+ r.moveStart("character", start)
100
+ return r
101
+ } }
102
+
103
+ function contains(parent, child) {
104
+ if (child.nodeType == 3) // Android browser always returns false when child is a textnode
105
+ { child = child.parentNode }
106
+ if (parent.contains)
107
+ { return parent.contains(child) }
108
+ do {
109
+ if (child.nodeType == 11) { child = child.host }
110
+ if (child == parent) { return true }
111
+ } while (child = child.parentNode)
112
+ }
113
+
114
+ function activeElt() {
115
+ // IE and Edge may throw an "Unspecified Error" when accessing document.activeElement.
116
+ // IE < 10 will throw when accessed while the page is loading or in an iframe.
117
+ // IE > 9 and Edge will throw when accessed in an iframe if document.body is unavailable.
118
+ var activeElement
119
+ try {
120
+ activeElement = document.activeElement
121
+ } catch(e) {
122
+ activeElement = document.body || null
123
+ }
124
+ while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement)
125
+ { activeElement = activeElement.shadowRoot.activeElement }
126
+ return activeElement
127
+ }
128
+
129
+ function addClass(node, cls) {
130
+ var current = node.className
131
+ if (!classTest(cls).test(current)) { node.className += (current ? " " : "") + cls }
132
+ }
133
+ function joinClasses(a, b) {
134
+ var as = a.split(" ")
135
+ for (var i = 0; i < as.length; i++)
136
+ { if (as[i] && !classTest(as[i]).test(b)) { b += " " + as[i] } }
137
+ return b
138
+ }
139
+
140
+ var selectInput = function(node) { node.select() }
141
+ if (ios) // Mobile Safari apparently has a bug where select() is broken.
142
+ { selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length } }
143
+ else if (ie) // Suppress mysterious IE10 errors
144
+ { selectInput = function(node) { try { node.select() } catch(_e) {} } }
145
+
146
+ function bind(f) {
147
+ var args = Array.prototype.slice.call(arguments, 1)
148
+ return function(){return f.apply(null, args)}
149
+ }
150
+
151
+ function copyObj(obj, target, overwrite) {
152
+ if (!target) { target = {} }
153
+ for (var prop in obj)
154
+ { if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
155
+ { target[prop] = obj[prop] } }
156
+ return target
157
+ }
158
+
159
+ // Counts the column offset in a string, taking tabs into account.
160
+ // Used mostly to find indentation.
161
+ function countColumn(string, end, tabSize, startIndex, startValue) {
162
+ if (end == null) {
163
+ end = string.search(/[^\s\u00a0]/)
164
+ if (end == -1) { end = string.length }
165
+ }
166
+ for (var i = startIndex || 0, n = startValue || 0;;) {
167
+ var nextTab = string.indexOf("\t", i)
168
+ if (nextTab < 0 || nextTab >= end)
169
+ { return n + (end - i) }
170
+ n += nextTab - i
171
+ n += tabSize - (n % tabSize)
172
+ i = nextTab + 1
173
+ }
174
+ }
175
+
176
+ var Delayed = function() {this.id = null};
177
+ Delayed.prototype.set = function (ms, f) {
178
+ clearTimeout(this.id)
179
+ this.id = setTimeout(f, ms)
180
+ };
181
+
182
+ function indexOf(array, elt) {
183
+ for (var i = 0; i < array.length; ++i)
184
+ { if (array[i] == elt) { return i } }
185
+ return -1
186
+ }
187
+
188
+ // Number of pixels added to scroller and sizer to hide scrollbar
189
+ var scrollerGap = 30
190
+
191
+ // Returned or thrown by various protocols to signal 'I'm not
192
+ // handling this'.
193
+ var Pass = {toString: function(){return "CodeMirror.Pass"}}
194
+
195
+ // Reused option objects for setSelection & friends
196
+ var sel_dontScroll = {scroll: false};
197
+ var sel_mouse = {origin: "*mouse"};
198
+ var sel_move = {origin: "+move"};
199
+ // The inverse of countColumn -- find the offset that corresponds to
200
+ // a particular column.
201
+ function findColumn(string, goal, tabSize) {
202
+ for (var pos = 0, col = 0;;) {
203
+ var nextTab = string.indexOf("\t", pos)
204
+ if (nextTab == -1) { nextTab = string.length }
205
+ var skipped = nextTab - pos
206
+ if (nextTab == string.length || col + skipped >= goal)
207
+ { return pos + Math.min(skipped, goal - col) }
208
+ col += nextTab - pos
209
+ col += tabSize - (col % tabSize)
210
+ pos = nextTab + 1
211
+ if (col >= goal) { return pos }
212
+ }
213
+ }
214
+
215
+ var spaceStrs = [""]
216
+ function spaceStr(n) {
217
+ while (spaceStrs.length <= n)
218
+ { spaceStrs.push(lst(spaceStrs) + " ") }
219
+ return spaceStrs[n]
220
+ }
221
+
222
+ function lst(arr) { return arr[arr.length-1] }
223
+
224
+ function map(array, f) {
225
+ var out = []
226
+ for (var i = 0; i < array.length; i++) { out[i] = f(array[i], i) }
227
+ return out
228
+ }
229
+
230
+ function insertSorted(array, value, score) {
231
+ var pos = 0, priority = score(value)
232
+ while (pos < array.length && score(array[pos]) <= priority) { pos++ }
233
+ array.splice(pos, 0, value)
234
+ }
235
+
236
+ function nothing() {}
237
+
238
+ function createObj(base, props) {
239
+ var inst
240
+ if (Object.create) {
241
+ inst = Object.create(base)
242
+ } else {
243
+ nothing.prototype = base
244
+ inst = new nothing()
245
+ }
246
+ if (props) { copyObj(props, inst) }
247
+ return inst
248
+ }
249
+
250
+ var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/
251
+ function isWordCharBasic(ch) {
252
+ return /\w/.test(ch) || ch > "\x80" &&
253
+ (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch))
254
+ }
255
+ function isWordChar(ch, helper) {
256
+ if (!helper) { return isWordCharBasic(ch) }
257
+ if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) { return true }
258
+ return helper.test(ch)
259
+ }
260
+
261
+ function isEmpty(obj) {
262
+ for (var n in obj) { if (obj.hasOwnProperty(n) && obj[n]) { return false } }
263
+ return true
264
+ }
265
+
266
+ // Extending unicode characters. A series of a non-extending char +
267
+ // any number of extending chars is treated as a single unit as far
268
+ // as editing and measuring is concerned. This is not fully correct,
269
+ // since some scripts/fonts/browsers also treat other configurations
270
+ // of code points as a group.
271
+ 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]/
272
+ function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch) }
273
+
274
+ // Returns a number from the range [`0`; `str.length`] unless `pos` is outside that range.
275
+ function skipExtendingChars(str, pos, dir) {
276
+ while ((dir < 0 ? pos > 0 : pos < str.length) && isExtendingChar(str.charAt(pos))) { pos += dir }
277
+ return pos
278
+ }
279
+
280
+ // Returns the value from the range [`from`; `to`] that satisfies
281
+ // `pred` and is closest to `from`. Assumes that at least `to` satisfies `pred`.
282
+ function findFirst(pred, from, to) {
283
+ for (;;) {
284
+ if (Math.abs(from - to) <= 1) { return pred(from) ? from : to }
285
+ var mid = Math.floor((from + to) / 2)
286
+ if (pred(mid)) { to = mid }
287
+ else { from = mid }
288
+ }
289
+ }
290
+
291
+ // The display handles the DOM integration, both for input reading
292
+ // and content drawing. It holds references to DOM nodes and
293
+ // display-related state.
294
+
295
+ function Display(place, doc, input) {
296
+ var d = this
297
+ this.input = input
298
+
299
+ // Covers bottom-right square when both scrollbars are present.
300
+ d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler")
301
+ d.scrollbarFiller.setAttribute("cm-not-content", "true")
302
+ // Covers bottom of gutter when coverGutterNextToScrollbar is on
303
+ // and h scrollbar is present.
304
+ d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler")
305
+ d.gutterFiller.setAttribute("cm-not-content", "true")
306
+ // Will contain the actual code, positioned to cover the viewport.
307
+ d.lineDiv = eltP("div", null, "CodeMirror-code")
308
+ // Elements are added to these to represent selection and cursors.
309
+ d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1")
310
+ d.cursorDiv = elt("div", null, "CodeMirror-cursors")
311
+ // A visibility: hidden element used to find the size of things.
312
+ d.measure = elt("div", null, "CodeMirror-measure")
313
+ // When lines outside of the viewport are measured, they are drawn in this.
314
+ d.lineMeasure = elt("div", null, "CodeMirror-measure")
315
+ // Wraps everything that needs to exist inside the vertically-padded coordinate system
316
+ d.lineSpace = eltP("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],
317
+ null, "position: relative; outline: none")
318
+ var lines = eltP("div", [d.lineSpace], "CodeMirror-lines")
319
+ // Moved around its parent to cover visible view.
320
+ d.mover = elt("div", [lines], null, "position: relative")
321
+ // Set to the height of the document, allowing scrolling.
322
+ d.sizer = elt("div", [d.mover], "CodeMirror-sizer")
323
+ d.sizerWidth = null
324
+ // Behavior of elts with overflow: auto and padding is
325
+ // inconsistent across browsers. This is used to ensure the
326
+ // scrollable area is big enough.
327
+ d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;")
328
+ // Will contain the gutters, if any.
329
+ d.gutters = elt("div", null, "CodeMirror-gutters")
330
+ d.lineGutter = null
331
+ // Actual scrollable element.
332
+ d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll")
333
+ d.scroller.setAttribute("tabIndex", "-1")
334
+ // The element in which the editor lives.
335
+ d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror")
336
+
337
+ // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)
338
+ if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0 }
339
+ if (!webkit && !(gecko && mobile)) { d.scroller.draggable = true }
340
+
341
+ if (place) {
342
+ if (place.appendChild) { place.appendChild(d.wrapper) }
343
+ else { place(d.wrapper) }
344
+ }
345
+
346
+ // Current rendered range (may be bigger than the view window).
347
+ d.viewFrom = d.viewTo = doc.first
348
+ d.reportedViewFrom = d.reportedViewTo = doc.first
349
+ // Information about the rendered lines.
350
+ d.view = []
351
+ d.renderedView = null
352
+ // Holds info about a single rendered line when it was rendered
353
+ // for measurement, while not in view.
354
+ d.externalMeasured = null
355
+ // Empty space (in pixels) above the view
356
+ d.viewOffset = 0
357
+ d.lastWrapHeight = d.lastWrapWidth = 0
358
+ d.updateLineNumbers = null
359
+
360
+ d.nativeBarWidth = d.barHeight = d.barWidth = 0
361
+ d.scrollbarsClipped = false
362
+
363
+ // Used to only resize the line number gutter when necessary (when
364
+ // the amount of lines crosses a boundary that makes its width change)
365
+ d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null
366
+ // Set to true when a non-horizontal-scrolling line widget is
367
+ // added. As an optimization, line widget aligning is skipped when
368
+ // this is false.
369
+ d.alignWidgets = false
370
+
371
+ d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null
372
+
373
+ // Tracks the maximum line length so that the horizontal scrollbar
374
+ // can be kept static when scrolling.
375
+ d.maxLine = null
376
+ d.maxLineLength = 0
377
+ d.maxLineChanged = false
378
+
379
+ // Used for measuring wheel scrolling granularity
380
+ d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null
381
+
382
+ // True when shift is held down.
383
+ d.shift = false
384
+
385
+ // Used to track whether anything happened since the context menu
386
+ // was opened.
387
+ d.selForContextMenu = null
388
+
389
+ d.activeTouch = null
390
+
391
+ input.init(d)
392
+ }
393
+
394
+ // Find the line object corresponding to the given line number.
395
+ function getLine(doc, n) {
396
+ n -= doc.first
397
+ if (n < 0 || n >= doc.size) { throw new Error("There is no line " + (n + doc.first) + " in the document.") }
398
+ var chunk = doc
399
+ while (!chunk.lines) {
400
+ for (var i = 0;; ++i) {
401
+ var child = chunk.children[i], sz = child.chunkSize()
402
+ if (n < sz) { chunk = child; break }
403
+ n -= sz
404
+ }
405
+ }
406
+ return chunk.lines[n]
407
+ }
408
+
409
+ // Get the part of a document between two positions, as an array of
410
+ // strings.
411
+ function getBetween(doc, start, end) {
412
+ var out = [], n = start.line
413
+ doc.iter(start.line, end.line + 1, function (line) {
414
+ var text = line.text
415
+ if (n == end.line) { text = text.slice(0, end.ch) }
416
+ if (n == start.line) { text = text.slice(start.ch) }
417
+ out.push(text)
418
+ ++n
419
+ })
420
+ return out
421
+ }
422
+ // Get the lines between from and to, as array of strings.
423
+ function getLines(doc, from, to) {
424
+ var out = []
425
+ doc.iter(from, to, function (line) { out.push(line.text) }) // iter aborts when callback returns truthy value
426
+ return out
427
+ }
428
+
429
+ // Update the height of a line, propagating the height change
430
+ // upwards to parent nodes.
431
+ function updateLineHeight(line, height) {
432
+ var diff = height - line.height
433
+ if (diff) { for (var n = line; n; n = n.parent) { n.height += diff } }
434
+ }
435
+
436
+ // Given a line object, find its line number by walking up through
437
+ // its parent links.
438
+ function lineNo(line) {
439
+ if (line.parent == null) { return null }
440
+ var cur = line.parent, no = indexOf(cur.lines, line)
441
+ for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
442
+ for (var i = 0;; ++i) {
443
+ if (chunk.children[i] == cur) { break }
444
+ no += chunk.children[i].chunkSize()
445
+ }
446
+ }
447
+ return no + cur.first
448
+ }
449
+
450
+ // Find the line at the given vertical position, using the height
451
+ // information in the document tree.
452
+ function lineAtHeight(chunk, h) {
453
+ var n = chunk.first
454
+ outer: do {
455
+ for (var i$1 = 0; i$1 < chunk.children.length; ++i$1) {
456
+ var child = chunk.children[i$1], ch = child.height
457
+ if (h < ch) { chunk = child; continue outer }
458
+ h -= ch
459
+ n += child.chunkSize()
460
+ }
461
+ return n
462
+ } while (!chunk.lines)
463
+ var i = 0
464
+ for (; i < chunk.lines.length; ++i) {
465
+ var line = chunk.lines[i], lh = line.height
466
+ if (h < lh) { break }
467
+ h -= lh
468
+ }
469
+ return n + i
470
+ }
471
+
472
+ function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size}
473
+
474
+ function lineNumberFor(options, i) {
475
+ return String(options.lineNumberFormatter(i + options.firstLineNumber))
476
+ }
477
+
478
+ // A Pos instance represents a position within the text.
479
+ function Pos(line, ch, sticky) {
480
+ if ( sticky === void 0 ) sticky = null;
481
+
482
+ if (!(this instanceof Pos)) { return new Pos(line, ch, sticky) }
483
+ this.line = line
484
+ this.ch = ch
485
+ this.sticky = sticky
486
+ }
487
+
488
+ // Compare two positions, return 0 if they are the same, a negative
489
+ // number when a is less, and a positive number otherwise.
490
+ function cmp(a, b) { return a.line - b.line || a.ch - b.ch }
491
+
492
+ function equalCursorPos(a, b) { return a.sticky == b.sticky && cmp(a, b) == 0 }
493
+
494
+ function copyPos(x) {return Pos(x.line, x.ch)}
495
+ function maxPos(a, b) { return cmp(a, b) < 0 ? b : a }
496
+ function minPos(a, b) { return cmp(a, b) < 0 ? a : b }
497
+
498
+ // Most of the external API clips given positions to make sure they
499
+ // actually exist within the document.
500
+ function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1))}
501
+ function clipPos(doc, pos) {
502
+ if (pos.line < doc.first) { return Pos(doc.first, 0) }
503
+ var last = doc.first + doc.size - 1
504
+ if (pos.line > last) { return Pos(last, getLine(doc, last).text.length) }
505
+ return clipToLen(pos, getLine(doc, pos.line).text.length)
506
+ }
507
+ function clipToLen(pos, linelen) {
508
+ var ch = pos.ch
509
+ if (ch == null || ch > linelen) { return Pos(pos.line, linelen) }
510
+ else if (ch < 0) { return Pos(pos.line, 0) }
511
+ else { return pos }
512
+ }
513
+ function clipPosArray(doc, array) {
514
+ var out = []
515
+ for (var i = 0; i < array.length; i++) { out[i] = clipPos(doc, array[i]) }
516
+ return out
517
+ }
518
+
519
+ // Optimize some code when these features are not used.
520
+ var sawReadOnlySpans = false;
521
+ var sawCollapsedSpans = false;
522
+ function seeReadOnlySpans() {
523
+ sawReadOnlySpans = true
524
+ }
525
+
526
+ function seeCollapsedSpans() {
527
+ sawCollapsedSpans = true
528
+ }
529
+
530
+ // TEXTMARKER SPANS
531
+
532
+ function MarkedSpan(marker, from, to) {
533
+ this.marker = marker
534
+ this.from = from; this.to = to
535
+ }
536
+
537
+ // Search an array of spans for a span matching the given marker.
538
+ function getMarkedSpanFor(spans, marker) {
539
+ if (spans) { for (var i = 0; i < spans.length; ++i) {
540
+ var span = spans[i]
541
+ if (span.marker == marker) { return span }
542
+ } }
543
+ }
544
+ // Remove a span from an array, returning undefined if no spans are
545
+ // left (we don't store arrays for lines without spans).
546
+ function removeMarkedSpan(spans, span) {
547
+ var r
548
+ for (var i = 0; i < spans.length; ++i)
549
+ { if (spans[i] != span) { (r || (r = [])).push(spans[i]) } }
550
+ return r
551
+ }
552
+ // Add a span to a line.
553
+ function addMarkedSpan(line, span) {
554
+ line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span]
555
+ span.marker.attachLine(line)
556
+ }
557
+
558
+ // Used for the algorithm that adjusts markers for a change in the
559
+ // document. These functions cut an array of spans at a given
560
+ // character position, returning an array of remaining chunks (or
561
+ // undefined if nothing remains).
562
+ function markedSpansBefore(old, startCh, isInsert) {
563
+ var nw
564
+ if (old) { for (var i = 0; i < old.length; ++i) {
565
+ var span = old[i], marker = span.marker
566
+ var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh)
567
+ if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) {
568
+ var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh)
569
+ ;(nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to))
570
+ }
571
+ } }
572
+ return nw
573
+ }
574
+ function markedSpansAfter(old, endCh, isInsert) {
575
+ var nw
576
+ if (old) { for (var i = 0; i < old.length; ++i) {
577
+ var span = old[i], marker = span.marker
578
+ var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh)
579
+ if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) {
580
+ var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh)
581
+ ;(nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh,
582
+ span.to == null ? null : span.to - endCh))
583
+ }
584
+ } }
585
+ return nw
586
+ }
587
+
588
+ // Given a change object, compute the new set of marker spans that
589
+ // cover the line in which the change took place. Removes spans
590
+ // entirely within the change, reconnects spans belonging to the
591
+ // same marker that appear on both sides of the change, and cuts off
592
+ // spans partially within the change. Returns an array of span
593
+ // arrays with one element for each line in (after) the change.
594
+ function stretchSpansOverChange(doc, change) {
595
+ if (change.full) { return null }
596
+ var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans
597
+ var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans
598
+ if (!oldFirst && !oldLast) { return null }
599
+
600
+ var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0
601
+ // Get the spans that 'stick out' on both sides
602
+ var first = markedSpansBefore(oldFirst, startCh, isInsert)
603
+ var last = markedSpansAfter(oldLast, endCh, isInsert)
604
+
605
+ // Next, merge those two ends
606
+ var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0)
607
+ if (first) {
608
+ // Fix up .to properties of first
609
+ for (var i = 0; i < first.length; ++i) {
610
+ var span = first[i]
611
+ if (span.to == null) {
612
+ var found = getMarkedSpanFor(last, span.marker)
613
+ if (!found) { span.to = startCh }
614
+ else if (sameLine) { span.to = found.to == null ? null : found.to + offset }
615
+ }
616
+ }
617
+ }
618
+ if (last) {
619
+ // Fix up .from in last (or move them into first in case of sameLine)
620
+ for (var i$1 = 0; i$1 < last.length; ++i$1) {
621
+ var span$1 = last[i$1]
622
+ if (span$1.to != null) { span$1.to += offset }
623
+ if (span$1.from == null) {
624
+ var found$1 = getMarkedSpanFor(first, span$1.marker)
625
+ if (!found$1) {
626
+ span$1.from = offset
627
+ if (sameLine) { (first || (first = [])).push(span$1) }
628
+ }
629
+ } else {
630
+ span$1.from += offset
631
+ if (sameLine) { (first || (first = [])).push(span$1) }
632
+ }
633
+ }
634
+ }
635
+ // Make sure we didn't create any zero-length spans
636
+ if (first) { first = clearEmptySpans(first) }
637
+ if (last && last != first) { last = clearEmptySpans(last) }
638
+
639
+ var newMarkers = [first]
640
+ if (!sameLine) {
641
+ // Fill gap with whole-line-spans
642
+ var gap = change.text.length - 2, gapMarkers
643
+ if (gap > 0 && first)
644
+ { for (var i$2 = 0; i$2 < first.length; ++i$2)
645
+ { if (first[i$2].to == null)
646
+ { (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i$2].marker, null, null)) } } }
647
+ for (var i$3 = 0; i$3 < gap; ++i$3)
648
+ { newMarkers.push(gapMarkers) }
649
+ newMarkers.push(last)
650
+ }
651
+ return newMarkers
652
+ }
653
+
654
+ // Remove spans that are empty and don't have a clearWhenEmpty
655
+ // option of false.
656
+ function clearEmptySpans(spans) {
657
+ for (var i = 0; i < spans.length; ++i) {
658
+ var span = spans[i]
659
+ if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false)
660
+ { spans.splice(i--, 1) }
661
+ }
662
+ if (!spans.length) { return null }
663
+ return spans
664
+ }
665
+
666
+ // Used to 'clip' out readOnly ranges when making a change.
667
+ function removeReadOnlyRanges(doc, from, to) {
668
+ var markers = null
669
+ doc.iter(from.line, to.line + 1, function (line) {
670
+ if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) {
671
+ var mark = line.markedSpans[i].marker
672
+ if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))
673
+ { (markers || (markers = [])).push(mark) }
674
+ } }
675
+ })
676
+ if (!markers) { return null }
677
+ var parts = [{from: from, to: to}]
678
+ for (var i = 0; i < markers.length; ++i) {
679
+ var mk = markers[i], m = mk.find(0)
680
+ for (var j = 0; j < parts.length; ++j) {
681
+ var p = parts[j]
682
+ if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) { continue }
683
+ var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to)
684
+ if (dfrom < 0 || !mk.inclusiveLeft && !dfrom)
685
+ { newParts.push({from: p.from, to: m.from}) }
686
+ if (dto > 0 || !mk.inclusiveRight && !dto)
687
+ { newParts.push({from: m.to, to: p.to}) }
688
+ parts.splice.apply(parts, newParts)
689
+ j += newParts.length - 3
690
+ }
691
+ }
692
+ return parts
693
+ }
694
+
695
+ // Connect or disconnect spans from a line.
696
+ function detachMarkedSpans(line) {
697
+ var spans = line.markedSpans
698
+ if (!spans) { return }
699
+ for (var i = 0; i < spans.length; ++i)
700
+ { spans[i].marker.detachLine(line) }
701
+ line.markedSpans = null
702
+ }
703
+ function attachMarkedSpans(line, spans) {
704
+ if (!spans) { return }
705
+ for (var i = 0; i < spans.length; ++i)
706
+ { spans[i].marker.attachLine(line) }
707
+ line.markedSpans = spans
708
+ }
709
+
710
+ // Helpers used when computing which overlapping collapsed span
711
+ // counts as the larger one.
712
+ function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0 }
713
+ function extraRight(marker) { return marker.inclusiveRight ? 1 : 0 }
714
+
715
+ // Returns a number indicating which of two overlapping collapsed
716
+ // spans is larger (and thus includes the other). Falls back to
717
+ // comparing ids when the spans cover exactly the same range.
718
+ function compareCollapsedMarkers(a, b) {
719
+ var lenDiff = a.lines.length - b.lines.length
720
+ if (lenDiff != 0) { return lenDiff }
721
+ var aPos = a.find(), bPos = b.find()
722
+ var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b)
723
+ if (fromCmp) { return -fromCmp }
724
+ var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b)
725
+ if (toCmp) { return toCmp }
726
+ return b.id - a.id
727
+ }
728
+
729
+ // Find out whether a line ends or starts in a collapsed span. If
730
+ // so, return the marker for that span.
731
+ function collapsedSpanAtSide(line, start) {
732
+ var sps = sawCollapsedSpans && line.markedSpans, found
733
+ if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) {
734
+ sp = sps[i]
735
+ if (sp.marker.collapsed && (start ? sp.from : sp.to) == null &&
736
+ (!found || compareCollapsedMarkers(found, sp.marker) < 0))
737
+ { found = sp.marker }
738
+ } }
739
+ return found
740
+ }
741
+ function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true) }
742
+ function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false) }
743
+
744
+ // Test whether there exists a collapsed span that partially
745
+ // overlaps (covers the start or end, but not both) of a new span.
746
+ // Such overlap is not allowed.
747
+ function conflictingCollapsedRange(doc, lineNo, from, to, marker) {
748
+ var line = getLine(doc, lineNo)
749
+ var sps = sawCollapsedSpans && line.markedSpans
750
+ if (sps) { for (var i = 0; i < sps.length; ++i) {
751
+ var sp = sps[i]
752
+ if (!sp.marker.collapsed) { continue }
753
+ var found = sp.marker.find(0)
754
+ var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker)
755
+ var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker)
756
+ if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) { continue }
757
+ if (fromCmp <= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.to, from) >= 0 : cmp(found.to, from) > 0) ||
758
+ fromCmp >= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.from, to) <= 0 : cmp(found.from, to) < 0))
759
+ { return true }
760
+ } }
761
+ }
762
+
763
+ // A visual line is a line as drawn on the screen. Folding, for
764
+ // example, can cause multiple logical lines to appear on the same
765
+ // visual line. This finds the start of the visual line that the
766
+ // given line is part of (usually that is the line itself).
767
+ function visualLine(line) {
768
+ var merged
769
+ while (merged = collapsedSpanAtStart(line))
770
+ { line = merged.find(-1, true).line }
771
+ return line
772
+ }
773
+
774
+ function visualLineEnd(line) {
775
+ var merged
776
+ while (merged = collapsedSpanAtEnd(line))
777
+ { line = merged.find(1, true).line }
778
+ return line
779
+ }
780
+
781
+ // Returns an array of logical lines that continue the visual line
782
+ // started by the argument, or undefined if there are no such lines.
783
+ function visualLineContinued(line) {
784
+ var merged, lines
785
+ while (merged = collapsedSpanAtEnd(line)) {
786
+ line = merged.find(1, true).line
787
+ ;(lines || (lines = [])).push(line)
788
+ }
789
+ return lines
790
+ }
791
+
792
+ // Get the line number of the start of the visual line that the
793
+ // given line number is part of.
794
+ function visualLineNo(doc, lineN) {
795
+ var line = getLine(doc, lineN), vis = visualLine(line)
796
+ if (line == vis) { return lineN }
797
+ return lineNo(vis)
798
+ }
799
+
800
+ // Get the line number of the start of the next visual line after
801
+ // the given line.
802
+ function visualLineEndNo(doc, lineN) {
803
+ if (lineN > doc.lastLine()) { return lineN }
804
+ var line = getLine(doc, lineN), merged
805
+ if (!lineIsHidden(doc, line)) { return lineN }
806
+ while (merged = collapsedSpanAtEnd(line))
807
+ { line = merged.find(1, true).line }
808
+ return lineNo(line) + 1
809
+ }
810
+
811
+ // Compute whether a line is hidden. Lines count as hidden when they
812
+ // are part of a visual line that starts with another line, or when
813
+ // they are entirely covered by collapsed, non-widget span.
814
+ function lineIsHidden(doc, line) {
815
+ var sps = sawCollapsedSpans && line.markedSpans
816
+ if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) {
817
+ sp = sps[i]
818
+ if (!sp.marker.collapsed) { continue }
819
+ if (sp.from == null) { return true }
820
+ if (sp.marker.widgetNode) { continue }
821
+ if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))
822
+ { return true }
823
+ } }
824
+ }
825
+ function lineIsHiddenInner(doc, line, span) {
826
+ if (span.to == null) {
827
+ var end = span.marker.find(1, true)
828
+ return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker))
829
+ }
830
+ if (span.marker.inclusiveRight && span.to == line.text.length)
831
+ { return true }
832
+ for (var sp = (void 0), i = 0; i < line.markedSpans.length; ++i) {
833
+ sp = line.markedSpans[i]
834
+ if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to &&
835
+ (sp.to == null || sp.to != span.from) &&
836
+ (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
837
+ lineIsHiddenInner(doc, line, sp)) { return true }
838
+ }
839
+ }
840
+
841
+ // Find the height above the given line.
842
+ function heightAtLine(lineObj) {
843
+ lineObj = visualLine(lineObj)
844
+
845
+ var h = 0, chunk = lineObj.parent
846
+ for (var i = 0; i < chunk.lines.length; ++i) {
847
+ var line = chunk.lines[i]
848
+ if (line == lineObj) { break }
849
+ else { h += line.height }
850
+ }
851
+ for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {
852
+ for (var i$1 = 0; i$1 < p.children.length; ++i$1) {
853
+ var cur = p.children[i$1]
854
+ if (cur == chunk) { break }
855
+ else { h += cur.height }
856
+ }
857
+ }
858
+ return h
859
+ }
860
+
861
+ // Compute the character length of a line, taking into account
862
+ // collapsed ranges (see markText) that might hide parts, and join
863
+ // other lines onto it.
864
+ function lineLength(line) {
865
+ if (line.height == 0) { return 0 }
866
+ var len = line.text.length, merged, cur = line
867
+ while (merged = collapsedSpanAtStart(cur)) {
868
+ var found = merged.find(0, true)
869
+ cur = found.from.line
870
+ len += found.from.ch - found.to.ch
871
+ }
872
+ cur = line
873
+ while (merged = collapsedSpanAtEnd(cur)) {
874
+ var found$1 = merged.find(0, true)
875
+ len -= cur.text.length - found$1.from.ch
876
+ cur = found$1.to.line
877
+ len += cur.text.length - found$1.to.ch
878
+ }
879
+ return len
880
+ }
881
+
882
+ // Find the longest line in the document.
883
+ function findMaxLine(cm) {
884
+ var d = cm.display, doc = cm.doc
885
+ d.maxLine = getLine(doc, doc.first)
886
+ d.maxLineLength = lineLength(d.maxLine)
887
+ d.maxLineChanged = true
888
+ doc.iter(function (line) {
889
+ var len = lineLength(line)
890
+ if (len > d.maxLineLength) {
891
+ d.maxLineLength = len
892
+ d.maxLine = line
893
+ }
894
+ })
895
+ }
896
+
897
+ // BIDI HELPERS
898
+
899
+ function iterateBidiSections(order, from, to, f) {
900
+ if (!order) { return f(from, to, "ltr") }
901
+ var found = false
902
+ for (var i = 0; i < order.length; ++i) {
903
+ var part = order[i]
904
+ if (part.from < to && part.to > from || from == to && part.to == from) {
905
+ f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr")
906
+ found = true
907
+ }
908
+ }
909
+ if (!found) { f(from, to, "ltr") }
910
+ }
911
+
912
+ var bidiOther = null
913
+ function getBidiPartAt(order, ch, sticky) {
914
+ var found
915
+ bidiOther = null
916
+ for (var i = 0; i < order.length; ++i) {
917
+ var cur = order[i]
918
+ if (cur.from < ch && cur.to > ch) { return i }
919
+ if (cur.to == ch) {
920
+ if (cur.from != cur.to && sticky == "before") { found = i }
921
+ else { bidiOther = i }
922
+ }
923
+ if (cur.from == ch) {
924
+ if (cur.from != cur.to && sticky != "before") { found = i }
925
+ else { bidiOther = i }
926
+ }
927
+ }
928
+ return found != null ? found : bidiOther
929
+ }
930
+
931
+ // Bidirectional ordering algorithm
932
+ // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm
933
+ // that this (partially) implements.
934
+
935
+ // One-char codes used for character types:
936
+ // L (L): Left-to-Right
937
+ // R (R): Right-to-Left
938
+ // r (AL): Right-to-Left Arabic
939
+ // 1 (EN): European Number
940
+ // + (ES): European Number Separator
941
+ // % (ET): European Number Terminator
942
+ // n (AN): Arabic Number
943
+ // , (CS): Common Number Separator
944
+ // m (NSM): Non-Spacing Mark
945
+ // b (BN): Boundary Neutral
946
+ // s (B): Paragraph Separator
947
+ // t (S): Segment Separator
948
+ // w (WS): Whitespace
949
+ // N (ON): Other Neutrals
950
+
951
+ // Returns null if characters are ordered as they appear
952
+ // (left-to-right), or an array of sections ({from, to, level}
953
+ // objects) in the order in which they occur visually.
954
+ var bidiOrdering = (function() {
955
+ // Character types for codepoints 0 to 0xff
956
+ var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN"
957
+ // Character types for codepoints 0x600 to 0x6f9
958
+ var arabicTypes = "nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111"
959
+ function charType(code) {
960
+ if (code <= 0xf7) { return lowTypes.charAt(code) }
961
+ else if (0x590 <= code && code <= 0x5f4) { return "R" }
962
+ else if (0x600 <= code && code <= 0x6f9) { return arabicTypes.charAt(code - 0x600) }
963
+ else if (0x6ee <= code && code <= 0x8ac) { return "r" }
964
+ else if (0x2000 <= code && code <= 0x200b) { return "w" }
965
+ else if (code == 0x200c) { return "b" }
966
+ else { return "L" }
967
+ }
968
+
969
+ var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/
970
+ var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/
971
+
972
+ function BidiSpan(level, from, to) {
973
+ this.level = level
974
+ this.from = from; this.to = to
975
+ }
976
+
977
+ return function(str, direction) {
978
+ var outerType = direction == "ltr" ? "L" : "R"
979
+
980
+ if (str.length == 0 || direction == "ltr" && !bidiRE.test(str)) { return false }
981
+ var len = str.length, types = []
982
+ for (var i = 0; i < len; ++i)
983
+ { types.push(charType(str.charCodeAt(i))) }
984
+
985
+ // W1. Examine each non-spacing mark (NSM) in the level run, and
986
+ // change the type of the NSM to the type of the previous
987
+ // character. If the NSM is at the start of the level run, it will
988
+ // get the type of sor.
989
+ for (var i$1 = 0, prev = outerType; i$1 < len; ++i$1) {
990
+ var type = types[i$1]
991
+ if (type == "m") { types[i$1] = prev }
992
+ else { prev = type }
993
+ }
994
+
995
+ // W2. Search backwards from each instance of a European number
996
+ // until the first strong type (R, L, AL, or sor) is found. If an
997
+ // AL is found, change the type of the European number to Arabic
998
+ // number.
999
+ // W3. Change all ALs to R.
1000
+ for (var i$2 = 0, cur = outerType; i$2 < len; ++i$2) {
1001
+ var type$1 = types[i$2]
1002
+ if (type$1 == "1" && cur == "r") { types[i$2] = "n" }
1003
+ else if (isStrong.test(type$1)) { cur = type$1; if (type$1 == "r") { types[i$2] = "R" } }
1004
+ }
1005
+
1006
+ // W4. A single European separator between two European numbers
1007
+ // changes to a European number. A single common separator between
1008
+ // two numbers of the same type changes to that type.
1009
+ for (var i$3 = 1, prev$1 = types[0]; i$3 < len - 1; ++i$3) {
1010
+ var type$2 = types[i$3]
1011
+ if (type$2 == "+" && prev$1 == "1" && types[i$3+1] == "1") { types[i$3] = "1" }
1012
+ else if (type$2 == "," && prev$1 == types[i$3+1] &&
1013
+ (prev$1 == "1" || prev$1 == "n")) { types[i$3] = prev$1 }
1014
+ prev$1 = type$2
1015
+ }
1016
+
1017
+ // W5. A sequence of European terminators adjacent to European
1018
+ // numbers changes to all European numbers.
1019
+ // W6. Otherwise, separators and terminators change to Other
1020
+ // Neutral.
1021
+ for (var i$4 = 0; i$4 < len; ++i$4) {
1022
+ var type$3 = types[i$4]
1023
+ if (type$3 == ",") { types[i$4] = "N" }
1024
+ else if (type$3 == "%") {
1025
+ var end = (void 0)
1026
+ for (end = i$4 + 1; end < len && types[end] == "%"; ++end) {}
1027
+ var replace = (i$4 && types[i$4-1] == "!") || (end < len && types[end] == "1") ? "1" : "N"
1028
+ for (var j = i$4; j < end; ++j) { types[j] = replace }
1029
+ i$4 = end - 1
1030
+ }
1031
+ }
1032
+
1033
+ // W7. Search backwards from each instance of a European number
1034
+ // until the first strong type (R, L, or sor) is found. If an L is
1035
+ // found, then change the type of the European number to L.
1036
+ for (var i$5 = 0, cur$1 = outerType; i$5 < len; ++i$5) {
1037
+ var type$4 = types[i$5]
1038
+ if (cur$1 == "L" && type$4 == "1") { types[i$5] = "L" }
1039
+ else if (isStrong.test(type$4)) { cur$1 = type$4 }
1040
+ }
1041
+
1042
+ // N1. A sequence of neutrals takes the direction of the
1043
+ // surrounding strong text if the text on both sides has the same
1044
+ // direction. European and Arabic numbers act as if they were R in
1045
+ // terms of their influence on neutrals. Start-of-level-run (sor)
1046
+ // and end-of-level-run (eor) are used at level run boundaries.
1047
+ // N2. Any remaining neutrals take the embedding direction.
1048
+ for (var i$6 = 0; i$6 < len; ++i$6) {
1049
+ if (isNeutral.test(types[i$6])) {
1050
+ var end$1 = (void 0)
1051
+ for (end$1 = i$6 + 1; end$1 < len && isNeutral.test(types[end$1]); ++end$1) {}
1052
+ var before = (i$6 ? types[i$6-1] : outerType) == "L"
1053
+ var after = (end$1 < len ? types[end$1] : outerType) == "L"
1054
+ var replace$1 = before == after ? (before ? "L" : "R") : outerType
1055
+ for (var j$1 = i$6; j$1 < end$1; ++j$1) { types[j$1] = replace$1 }
1056
+ i$6 = end$1 - 1
1057
+ }
1058
+ }
1059
+
1060
+ // Here we depart from the documented algorithm, in order to avoid
1061
+ // building up an actual levels array. Since there are only three
1062
+ // levels (0, 1, 2) in an implementation that doesn't take
1063
+ // explicit embedding into account, we can build up the order on
1064
+ // the fly, without following the level-based algorithm.
1065
+ var order = [], m
1066
+ for (var i$7 = 0; i$7 < len;) {
1067
+ if (countsAsLeft.test(types[i$7])) {
1068
+ var start = i$7
1069
+ for (++i$7; i$7 < len && countsAsLeft.test(types[i$7]); ++i$7) {}
1070
+ order.push(new BidiSpan(0, start, i$7))
1071
+ } else {
1072
+ var pos = i$7, at = order.length
1073
+ for (++i$7; i$7 < len && types[i$7] != "L"; ++i$7) {}
1074
+ for (var j$2 = pos; j$2 < i$7;) {
1075
+ if (countsAsNum.test(types[j$2])) {
1076
+ if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)) }
1077
+ var nstart = j$2
1078
+ for (++j$2; j$2 < i$7 && countsAsNum.test(types[j$2]); ++j$2) {}
1079
+ order.splice(at, 0, new BidiSpan(2, nstart, j$2))
1080
+ pos = j$2
1081
+ } else { ++j$2 }
1082
+ }
1083
+ if (pos < i$7) { order.splice(at, 0, new BidiSpan(1, pos, i$7)) }
1084
+ }
1085
+ }
1086
+ if (order[0].level == 1 && (m = str.match(/^\s+/))) {
1087
+ order[0].from = m[0].length
1088
+ order.unshift(new BidiSpan(0, 0, m[0].length))
1089
+ }
1090
+ if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
1091
+ lst(order).to -= m[0].length
1092
+ order.push(new BidiSpan(0, len - m[0].length, len))
1093
+ }
1094
+
1095
+ return direction == "rtl" ? order.reverse() : order
1096
+ }
1097
+ })()
1098
+
1099
+ // Get the bidi ordering for the given line (and cache it). Returns
1100
+ // false for lines that are fully left-to-right, and an array of
1101
+ // BidiSpan objects otherwise.
1102
+ function getOrder(line, direction) {
1103
+ var order = line.order
1104
+ if (order == null) { order = line.order = bidiOrdering(line.text, direction) }
1105
+ return order
1106
+ }
1107
+
1108
+ function moveCharLogically(line, ch, dir) {
1109
+ var target = skipExtendingChars(line.text, ch + dir, dir)
1110
+ return target < 0 || target > line.text.length ? null : target
1111
+ }
1112
+
1113
+ function moveLogically(line, start, dir) {
1114
+ var ch = moveCharLogically(line, start.ch, dir)
1115
+ return ch == null ? null : new Pos(start.line, ch, dir < 0 ? "after" : "before")
1116
+ }
1117
+
1118
+ function endOfLine(visually, cm, lineObj, lineNo, dir) {
1119
+ if (visually) {
1120
+ var order = getOrder(lineObj, cm.doc.direction)
1121
+ if (order) {
1122
+ var part = dir < 0 ? lst(order) : order[0]
1123
+ var moveInStorageOrder = (dir < 0) == (part.level == 1)
1124
+ var sticky = moveInStorageOrder ? "after" : "before"
1125
+ var ch
1126
+ // With a wrapped rtl chunk (possibly spanning multiple bidi parts),
1127
+ // it could be that the last bidi part is not on the last visual line,
1128
+ // since visual lines contain content order-consecutive chunks.
1129
+ // Thus, in rtl, we are looking for the first (content-order) character
1130
+ // in the rtl chunk that is on the last line (that is, the same line
1131
+ // as the last (content-order) character).
1132
+ if (part.level > 0) {
1133
+ var prep = prepareMeasureForLine(cm, lineObj)
1134
+ ch = dir < 0 ? lineObj.text.length - 1 : 0
1135
+ var targetTop = measureCharPrepared(cm, prep, ch).top
1136
+ ch = findFirst(function (ch) { return measureCharPrepared(cm, prep, ch).top == targetTop; }, (dir < 0) == (part.level == 1) ? part.from : part.to - 1, ch)
1137
+ if (sticky == "before") { ch = moveCharLogically(lineObj, ch, 1) }
1138
+ } else { ch = dir < 0 ? part.to : part.from }
1139
+ return new Pos(lineNo, ch, sticky)
1140
+ }
1141
+ }
1142
+ return new Pos(lineNo, dir < 0 ? lineObj.text.length : 0, dir < 0 ? "before" : "after")
1143
+ }
1144
+
1145
+ function moveVisually(cm, line, start, dir) {
1146
+ var bidi = getOrder(line, cm.doc.direction)
1147
+ if (!bidi) { return moveLogically(line, start, dir) }
1148
+ if (start.ch >= line.text.length) {
1149
+ start.ch = line.text.length
1150
+ start.sticky = "before"
1151
+ } else if (start.ch <= 0) {
1152
+ start.ch = 0
1153
+ start.sticky = "after"
1154
+ }
1155
+ var partPos = getBidiPartAt(bidi, start.ch, start.sticky), part = bidi[partPos]
1156
+ if (cm.doc.direction == "ltr" && part.level % 2 == 0 && (dir > 0 ? part.to > start.ch : part.from < start.ch)) {
1157
+ // Case 1: We move within an ltr part in an ltr editor. Even with wrapped lines,
1158
+ // nothing interesting happens.
1159
+ return moveLogically(line, start, dir)
1160
+ }
1161
+
1162
+ var mv = function (pos, dir) { return moveCharLogically(line, pos instanceof Pos ? pos.ch : pos, dir); }
1163
+ var prep
1164
+ var getWrappedLineExtent = function (ch) {
1165
+ if (!cm.options.lineWrapping) { return {begin: 0, end: line.text.length} }
1166
+ prep = prep || prepareMeasureForLine(cm, line)
1167
+ return wrappedLineExtentChar(cm, line, prep, ch)
1168
+ }
1169
+ var wrappedLineExtent = getWrappedLineExtent(start.sticky == "before" ? mv(start, -1) : start.ch)
1170
+
1171
+ if (cm.doc.direction == "rtl" || part.level == 1) {
1172
+ var moveInStorageOrder = (part.level == 1) == (dir < 0)
1173
+ var ch = mv(start, moveInStorageOrder ? 1 : -1)
1174
+ if (ch != null && (!moveInStorageOrder ? ch >= part.from && ch >= wrappedLineExtent.begin : ch <= part.to && ch <= wrappedLineExtent.end)) {
1175
+ // Case 2: We move within an rtl part or in an rtl editor on the same visual line
1176
+ var sticky = moveInStorageOrder ? "before" : "after"
1177
+ return new Pos(start.line, ch, sticky)
1178
+ }
1179
+ }
1180
+
1181
+ // Case 3: Could not move within this bidi part in this visual line, so leave
1182
+ // the current bidi part
1183
+
1184
+ var searchInVisualLine = function (partPos, dir, wrappedLineExtent) {
1185
+ var getRes = function (ch, moveInStorageOrder) { return moveInStorageOrder
1186
+ ? new Pos(start.line, mv(ch, 1), "before")
1187
+ : new Pos(start.line, ch, "after"); }
1188
+
1189
+ for (; partPos >= 0 && partPos < bidi.length; partPos += dir) {
1190
+ var part = bidi[partPos]
1191
+ var moveInStorageOrder = (dir > 0) == (part.level != 1)
1192
+ var ch = moveInStorageOrder ? wrappedLineExtent.begin : mv(wrappedLineExtent.end, -1)
1193
+ if (part.from <= ch && ch < part.to) { return getRes(ch, moveInStorageOrder) }
1194
+ ch = moveInStorageOrder ? part.from : mv(part.to, -1)
1195
+ if (wrappedLineExtent.begin <= ch && ch < wrappedLineExtent.end) { return getRes(ch, moveInStorageOrder) }
1196
+ }
1197
+ }
1198
+
1199
+ // Case 3a: Look for other bidi parts on the same visual line
1200
+ var res = searchInVisualLine(partPos + dir, dir, wrappedLineExtent)
1201
+ if (res) { return res }
1202
+
1203
+ // Case 3b: Look for other bidi parts on the next visual line
1204
+ var nextCh = dir > 0 ? wrappedLineExtent.end : mv(wrappedLineExtent.begin, -1)
1205
+ if (nextCh != null && !(dir > 0 && nextCh == line.text.length)) {
1206
+ res = searchInVisualLine(dir > 0 ? 0 : bidi.length - 1, dir, getWrappedLineExtent(nextCh))
1207
+ if (res) { return res }
1208
+ }
1209
+
1210
+ // Case 4: Nowhere to move
1211
+ return null
1212
+ }
1213
+
1214
+ // EVENT HANDLING
1215
+
1216
+ // Lightweight event framework. on/off also work on DOM nodes,
1217
+ // registering native DOM handlers.
1218
+
1219
+ var noHandlers = []
1220
+
1221
+ var on = function(emitter, type, f) {
1222
+ if (emitter.addEventListener) {
1223
+ emitter.addEventListener(type, f, false)
1224
+ } else if (emitter.attachEvent) {
1225
+ emitter.attachEvent("on" + type, f)
1226
+ } else {
1227
+ var map = emitter._handlers || (emitter._handlers = {})
1228
+ map[type] = (map[type] || noHandlers).concat(f)
1229
+ }
1230
+ }
1231
+
1232
+ function getHandlers(emitter, type) {
1233
+ return emitter._handlers && emitter._handlers[type] || noHandlers
1234
+ }
1235
+
1236
+ function off(emitter, type, f) {
1237
+ if (emitter.removeEventListener) {
1238
+ emitter.removeEventListener(type, f, false)
1239
+ } else if (emitter.detachEvent) {
1240
+ emitter.detachEvent("on" + type, f)
1241
+ } else {
1242
+ var map = emitter._handlers, arr = map && map[type]
1243
+ if (arr) {
1244
+ var index = indexOf(arr, f)
1245
+ if (index > -1)
1246
+ { map[type] = arr.slice(0, index).concat(arr.slice(index + 1)) }
1247
+ }
1248
+ }
1249
+ }
1250
+
1251
+ function signal(emitter, type /*, values...*/) {
1252
+ var handlers = getHandlers(emitter, type)
1253
+ if (!handlers.length) { return }
1254
+ var args = Array.prototype.slice.call(arguments, 2)
1255
+ for (var i = 0; i < handlers.length; ++i) { handlers[i].apply(null, args) }
1256
+ }
1257
+
1258
+ // The DOM events that CodeMirror handles can be overridden by
1259
+ // registering a (non-DOM) handler on the editor for the event name,
1260
+ // and preventDefault-ing the event in that handler.
1261
+ function signalDOMEvent(cm, e, override) {
1262
+ if (typeof e == "string")
1263
+ { e = {type: e, preventDefault: function() { this.defaultPrevented = true }} }
1264
+ signal(cm, override || e.type, cm, e)
1265
+ return e_defaultPrevented(e) || e.codemirrorIgnore
1266
+ }
1267
+
1268
+ function signalCursorActivity(cm) {
1269
+ var arr = cm._handlers && cm._handlers.cursorActivity
1270
+ if (!arr) { return }
1271
+ var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = [])
1272
+ for (var i = 0; i < arr.length; ++i) { if (indexOf(set, arr[i]) == -1)
1273
+ { set.push(arr[i]) } }
1274
+ }
1275
+
1276
+ function hasHandler(emitter, type) {
1277
+ return getHandlers(emitter, type).length > 0
1278
+ }
1279
+
1280
+ // Add on and off methods to a constructor's prototype, to make
1281
+ // registering events on such objects more convenient.
1282
+ function eventMixin(ctor) {
1283
+ ctor.prototype.on = function(type, f) {on(this, type, f)}
1284
+ ctor.prototype.off = function(type, f) {off(this, type, f)}
1285
+ }
1286
+
1287
+ // Due to the fact that we still support jurassic IE versions, some
1288
+ // compatibility wrappers are needed.
1289
+
1290
+ function e_preventDefault(e) {
1291
+ if (e.preventDefault) { e.preventDefault() }
1292
+ else { e.returnValue = false }
1293
+ }
1294
+ function e_stopPropagation(e) {
1295
+ if (e.stopPropagation) { e.stopPropagation() }
1296
+ else { e.cancelBubble = true }
1297
+ }
1298
+ function e_defaultPrevented(e) {
1299
+ return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false
1300
+ }
1301
+ function e_stop(e) {e_preventDefault(e); e_stopPropagation(e)}
1302
+
1303
+ function e_target(e) {return e.target || e.srcElement}
1304
+ function e_button(e) {
1305
+ var b = e.which
1306
+ if (b == null) {
1307
+ if (e.button & 1) { b = 1 }
1308
+ else if (e.button & 2) { b = 3 }
1309
+ else if (e.button & 4) { b = 2 }
1310
+ }
1311
+ if (mac && e.ctrlKey && b == 1) { b = 3 }
1312
+ return b
1313
+ }
1314
+
1315
+ // Detect drag-and-drop
1316
+ var dragAndDrop = function() {
1317
+ // There is *some* kind of drag-and-drop support in IE6-8, but I
1318
+ // couldn't get it to work yet.
1319
+ if (ie && ie_version < 9) { return false }
1320
+ var div = elt('div')
1321
+ return "draggable" in div || "dragDrop" in div
1322
+ }()
1323
+
1324
+ var zwspSupported
1325
+ function zeroWidthElement(measure) {
1326
+ if (zwspSupported == null) {
1327
+ var test = elt("span", "\u200b")
1328
+ removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")]))
1329
+ if (measure.firstChild.offsetHeight != 0)
1330
+ { zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8) }
1331
+ }
1332
+ var node = zwspSupported ? elt("span", "\u200b") :
1333
+ elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px")
1334
+ node.setAttribute("cm-text", "")
1335
+ return node
1336
+ }
1337
+
1338
+ // Feature-detect IE's crummy client rect reporting for bidi text
1339
+ var badBidiRects
1340
+ function hasBadBidiRects(measure) {
1341
+ if (badBidiRects != null) { return badBidiRects }
1342
+ var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA"))
1343
+ var r0 = range(txt, 0, 1).getBoundingClientRect()
1344
+ var r1 = range(txt, 1, 2).getBoundingClientRect()
1345
+ removeChildren(measure)
1346
+ if (!r0 || r0.left == r0.right) { return false } // Safari returns null in some cases (#2780)
1347
+ return badBidiRects = (r1.right - r0.right < 3)
1348
+ }
1349
+
1350
+ // See if "".split is the broken IE version, if so, provide an
1351
+ // alternative way to split lines.
1352
+ var splitLinesAuto = "\n\nb".split(/\n/).length != 3 ? function (string) {
1353
+ var pos = 0, result = [], l = string.length
1354
+ while (pos <= l) {
1355
+ var nl = string.indexOf("\n", pos)
1356
+ if (nl == -1) { nl = string.length }
1357
+ var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl)
1358
+ var rt = line.indexOf("\r")
1359
+ if (rt != -1) {
1360
+ result.push(line.slice(0, rt))
1361
+ pos += rt + 1
1362
+ } else {
1363
+ result.push(line)
1364
+ pos = nl + 1
1365
+ }
1366
+ }
1367
+ return result
1368
+ } : function (string) { return string.split(/\r\n?|\n/); }
1369
+
1370
+ var hasSelection = window.getSelection ? function (te) {
1371
+ try { return te.selectionStart != te.selectionEnd }
1372
+ catch(e) { return false }
1373
+ } : function (te) {
1374
+ var range
1375
+ try {range = te.ownerDocument.selection.createRange()}
1376
+ catch(e) {}
1377
+ if (!range || range.parentElement() != te) { return false }
1378
+ return range.compareEndPoints("StartToEnd", range) != 0
1379
+ }
1380
+
1381
+ var hasCopyEvent = (function () {
1382
+ var e = elt("div")
1383
+ if ("oncopy" in e) { return true }
1384
+ e.setAttribute("oncopy", "return;")
1385
+ return typeof e.oncopy == "function"
1386
+ })()
1387
+
1388
+ var badZoomedRects = null
1389
+ function hasBadZoomedRects(measure) {
1390
+ if (badZoomedRects != null) { return badZoomedRects }
1391
+ var node = removeChildrenAndAdd(measure, elt("span", "x"))
1392
+ var normal = node.getBoundingClientRect()
1393
+ var fromRange = range(node, 0, 1).getBoundingClientRect()
1394
+ return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1
1395
+ }
1396
+
1397
+ var modes = {};
1398
+ var mimeModes = {};
1399
+ // Extra arguments are stored as the mode's dependencies, which is
1400
+ // used by (legacy) mechanisms like loadmode.js to automatically
1401
+ // load a mode. (Preferred mechanism is the require/define calls.)
1402
+ function defineMode(name, mode) {
1403
+ if (arguments.length > 2)
1404
+ { mode.dependencies = Array.prototype.slice.call(arguments, 2) }
1405
+ modes[name] = mode
1406
+ }
1407
+
1408
+ function defineMIME(mime, spec) {
1409
+ mimeModes[mime] = spec
1410
+ }
1411
+
1412
+ // Given a MIME type, a {name, ...options} config object, or a name
1413
+ // string, return a mode config object.
1414
+ function resolveMode(spec) {
1415
+ if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
1416
+ spec = mimeModes[spec]
1417
+ } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
1418
+ var found = mimeModes[spec.name]
1419
+ if (typeof found == "string") { found = {name: found} }
1420
+ spec = createObj(found, spec)
1421
+ spec.name = found.name
1422
+ } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
1423
+ return resolveMode("application/xml")
1424
+ } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+json$/.test(spec)) {
1425
+ return resolveMode("application/json")
1426
+ }
1427
+ if (typeof spec == "string") { return {name: spec} }
1428
+ else { return spec || {name: "null"} }
1429
+ }
1430
+
1431
+ // Given a mode spec (anything that resolveMode accepts), find and
1432
+ // initialize an actual mode object.
1433
+ function getMode(options, spec) {
1434
+ spec = resolveMode(spec)
1435
+ var mfactory = modes[spec.name]
1436
+ if (!mfactory) { return getMode(options, "text/plain") }
1437
+ var modeObj = mfactory(options, spec)
1438
+ if (modeExtensions.hasOwnProperty(spec.name)) {
1439
+ var exts = modeExtensions[spec.name]
1440
+ for (var prop in exts) {
1441
+ if (!exts.hasOwnProperty(prop)) { continue }
1442
+ if (modeObj.hasOwnProperty(prop)) { modeObj["_" + prop] = modeObj[prop] }
1443
+ modeObj[prop] = exts[prop]
1444
+ }
1445
+ }
1446
+ modeObj.name = spec.name
1447
+ if (spec.helperType) { modeObj.helperType = spec.helperType }
1448
+ if (spec.modeProps) { for (var prop$1 in spec.modeProps)
1449
+ { modeObj[prop$1] = spec.modeProps[prop$1] } }
1450
+
1451
+ return modeObj
1452
+ }
1453
+
1454
+ // This can be used to attach properties to mode objects from
1455
+ // outside the actual mode definition.
1456
+ var modeExtensions = {}
1457
+ function extendMode(mode, properties) {
1458
+ var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {})
1459
+ copyObj(properties, exts)
1460
+ }
1461
+
1462
+ function copyState(mode, state) {
1463
+ if (state === true) { return state }
1464
+ if (mode.copyState) { return mode.copyState(state) }
1465
+ var nstate = {}
1466
+ for (var n in state) {
1467
+ var val = state[n]
1468
+ if (val instanceof Array) { val = val.concat([]) }
1469
+ nstate[n] = val
1470
+ }
1471
+ return nstate
1472
+ }
1473
+
1474
+ // Given a mode and a state (for that mode), find the inner mode and
1475
+ // state at the position that the state refers to.
1476
+ function innerMode(mode, state) {
1477
+ var info
1478
+ while (mode.innerMode) {
1479
+ info = mode.innerMode(state)
1480
+ if (!info || info.mode == mode) { break }
1481
+ state = info.state
1482
+ mode = info.mode
1483
+ }
1484
+ return info || {mode: mode, state: state}
1485
+ }
1486
+
1487
+ function startState(mode, a1, a2) {
1488
+ return mode.startState ? mode.startState(a1, a2) : true
1489
+ }
1490
+
1491
+ // STRING STREAM
1492
+
1493
+ // Fed to the mode parsers, provides helper functions to make
1494
+ // parsers more succinct.
1495
+
1496
+ var StringStream = function(string, tabSize) {
1497
+ this.pos = this.start = 0
1498
+ this.string = string
1499
+ this.tabSize = tabSize || 8
1500
+ this.lastColumnPos = this.lastColumnValue = 0
1501
+ this.lineStart = 0
1502
+ };
1503
+
1504
+ StringStream.prototype.eol = function () {return this.pos >= this.string.length};
1505
+ StringStream.prototype.sol = function () {return this.pos == this.lineStart};
1506
+ StringStream.prototype.peek = function () {return this.string.charAt(this.pos) || undefined};
1507
+ StringStream.prototype.next = function () {
1508
+ if (this.pos < this.string.length)
1509
+ { return this.string.charAt(this.pos++) }
1510
+ };
1511
+ StringStream.prototype.eat = function (match) {
1512
+ var ch = this.string.charAt(this.pos)
1513
+ var ok
1514
+ if (typeof match == "string") { ok = ch == match }
1515
+ else { ok = ch && (match.test ? match.test(ch) : match(ch)) }
1516
+ if (ok) {++this.pos; return ch}
1517
+ };
1518
+ StringStream.prototype.eatWhile = function (match) {
1519
+ var start = this.pos
1520
+ while (this.eat(match)){}
1521
+ return this.pos > start
1522
+ };
1523
+ StringStream.prototype.eatSpace = function () {
1524
+ var this$1 = this;
1525
+
1526
+ var start = this.pos
1527
+ while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this$1.pos }
1528
+ return this.pos > start
1529
+ };
1530
+ StringStream.prototype.skipToEnd = function () {this.pos = this.string.length};
1531
+ StringStream.prototype.skipTo = function (ch) {
1532
+ var found = this.string.indexOf(ch, this.pos)
1533
+ if (found > -1) {this.pos = found; return true}
1534
+ };
1535
+ StringStream.prototype.backUp = function (n) {this.pos -= n};
1536
+ StringStream.prototype.column = function () {
1537
+ if (this.lastColumnPos < this.start) {
1538
+ this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue)
1539
+ this.lastColumnPos = this.start
1540
+ }
1541
+ return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
1542
+ };
1543
+ StringStream.prototype.indentation = function () {
1544
+ return countColumn(this.string, null, this.tabSize) -
1545
+ (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
1546
+ };
1547
+ StringStream.prototype.match = function (pattern, consume, caseInsensitive) {
1548
+ if (typeof pattern == "string") {
1549
+ var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; }
1550
+ var substr = this.string.substr(this.pos, pattern.length)
1551
+ if (cased(substr) == cased(pattern)) {
1552
+ if (consume !== false) { this.pos += pattern.length }
1553
+ return true
1554
+ }
1555
+ } else {
1556
+ var match = this.string.slice(this.pos).match(pattern)
1557
+ if (match && match.index > 0) { return null }
1558
+ if (match && consume !== false) { this.pos += match[0].length }
1559
+ return match
1560
+ }
1561
+ };
1562
+ StringStream.prototype.current = function (){return this.string.slice(this.start, this.pos)};
1563
+ StringStream.prototype.hideFirstChars = function (n, inner) {
1564
+ this.lineStart += n
1565
+ try { return inner() }
1566
+ finally { this.lineStart -= n }
1567
+ };
1568
+
1569
+ // Compute a style array (an array starting with a mode generation
1570
+ // -- for invalidation -- followed by pairs of end positions and
1571
+ // style strings), which is used to highlight the tokens on the
1572
+ // line.
1573
+ function highlightLine(cm, line, state, forceToEnd) {
1574
+ // A styles array always starts with a number identifying the
1575
+ // mode/overlays that it is based on (for easy invalidation).
1576
+ var st = [cm.state.modeGen], lineClasses = {}
1577
+ // Compute the base array of styles
1578
+ runMode(cm, line.text, cm.doc.mode, state, function (end, style) { return st.push(end, style); },
1579
+ lineClasses, forceToEnd)
1580
+
1581
+ // Run overlays, adjust style array.
1582
+ var loop = function ( o ) {
1583
+ var overlay = cm.state.overlays[o], i = 1, at = 0
1584
+ runMode(cm, line.text, overlay.mode, true, function (end, style) {
1585
+ var start = i
1586
+ // Ensure there's a token end at the current position, and that i points at it
1587
+ while (at < end) {
1588
+ var i_end = st[i]
1589
+ if (i_end > end)
1590
+ { st.splice(i, 1, end, st[i+1], i_end) }
1591
+ i += 2
1592
+ at = Math.min(end, i_end)
1593
+ }
1594
+ if (!style) { return }
1595
+ if (overlay.opaque) {
1596
+ st.splice(start, i - start, end, "overlay " + style)
1597
+ i = start + 2
1598
+ } else {
1599
+ for (; start < i; start += 2) {
1600
+ var cur = st[start+1]
1601
+ st[start+1] = (cur ? cur + " " : "") + "overlay " + style
1602
+ }
1603
+ }
1604
+ }, lineClasses)
1605
+ };
1606
+
1607
+ for (var o = 0; o < cm.state.overlays.length; ++o) loop( o );
1608
+
1609
+ return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null}
1610
+ }
1611
+
1612
+ function getLineStyles(cm, line, updateFrontier) {
1613
+ if (!line.styles || line.styles[0] != cm.state.modeGen) {
1614
+ var state = getStateBefore(cm, lineNo(line))
1615
+ var result = highlightLine(cm, line, line.text.length > cm.options.maxHighlightLength ? copyState(cm.doc.mode, state) : state)
1616
+ line.stateAfter = state
1617
+ line.styles = result.styles
1618
+ if (result.classes) { line.styleClasses = result.classes }
1619
+ else if (line.styleClasses) { line.styleClasses = null }
1620
+ if (updateFrontier === cm.doc.frontier) { cm.doc.frontier++ }
1621
+ }
1622
+ return line.styles
1623
+ }
1624
+
1625
+ function getStateBefore(cm, n, precise) {
1626
+ var doc = cm.doc, display = cm.display
1627
+ if (!doc.mode.startState) { return true }
1628
+ var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter
1629
+ if (!state) { state = startState(doc.mode) }
1630
+ else { state = copyState(doc.mode, state) }
1631
+ doc.iter(pos, n, function (line) {
1632
+ processLine(cm, line.text, state)
1633
+ var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo
1634
+ line.stateAfter = save ? copyState(doc.mode, state) : null
1635
+ ++pos
1636
+ })
1637
+ if (precise) { doc.frontier = pos }
1638
+ return state
1639
+ }
1640
+
1641
+ // Lightweight form of highlight -- proceed over this line and
1642
+ // update state, but don't save a style array. Used for lines that
1643
+ // aren't currently visible.
1644
+ function processLine(cm, text, state, startAt) {
1645
+ var mode = cm.doc.mode
1646
+ var stream = new StringStream(text, cm.options.tabSize)
1647
+ stream.start = stream.pos = startAt || 0
1648
+ if (text == "") { callBlankLine(mode, state) }
1649
+ while (!stream.eol()) {
1650
+ readToken(mode, stream, state)
1651
+ stream.start = stream.pos
1652
+ }
1653
+ }
1654
+
1655
+ function callBlankLine(mode, state) {
1656
+ if (mode.blankLine) { return mode.blankLine(state) }
1657
+ if (!mode.innerMode) { return }
1658
+ var inner = innerMode(mode, state)
1659
+ if (inner.mode.blankLine) { return inner.mode.blankLine(inner.state) }
1660
+ }
1661
+
1662
+ function readToken(mode, stream, state, inner) {
1663
+ for (var i = 0; i < 10; i++) {
1664
+ if (inner) { inner[0] = innerMode(mode, state).mode }
1665
+ var style = mode.token(stream, state)
1666
+ if (stream.pos > stream.start) { return style }
1667
+ }
1668
+ throw new Error("Mode " + mode.name + " failed to advance stream.")
1669
+ }
1670
+
1671
+ // Utility for getTokenAt and getLineTokens
1672
+ function takeToken(cm, pos, precise, asArray) {
1673
+ var getObj = function (copy) { return ({
1674
+ start: stream.start, end: stream.pos,
1675
+ string: stream.current(),
1676
+ type: style || null,
1677
+ state: copy ? copyState(doc.mode, state) : state
1678
+ }); }
1679
+
1680
+ var doc = cm.doc, mode = doc.mode, style
1681
+ pos = clipPos(doc, pos)
1682
+ var line = getLine(doc, pos.line), state = getStateBefore(cm, pos.line, precise)
1683
+ var stream = new StringStream(line.text, cm.options.tabSize), tokens
1684
+ if (asArray) { tokens = [] }
1685
+ while ((asArray || stream.pos < pos.ch) && !stream.eol()) {
1686
+ stream.start = stream.pos
1687
+ style = readToken(mode, stream, state)
1688
+ if (asArray) { tokens.push(getObj(true)) }
1689
+ }
1690
+ return asArray ? tokens : getObj()
1691
+ }
1692
+
1693
+ function extractLineClasses(type, output) {
1694
+ if (type) { for (;;) {
1695
+ var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/)
1696
+ if (!lineClass) { break }
1697
+ type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length)
1698
+ var prop = lineClass[1] ? "bgClass" : "textClass"
1699
+ if (output[prop] == null)
1700
+ { output[prop] = lineClass[2] }
1701
+ else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop]))
1702
+ { output[prop] += " " + lineClass[2] }
1703
+ } }
1704
+ return type
1705
+ }
1706
+
1707
+ // Run the given mode's parser over a line, calling f for each token.
1708
+ function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) {
1709
+ var flattenSpans = mode.flattenSpans
1710
+ if (flattenSpans == null) { flattenSpans = cm.options.flattenSpans }
1711
+ var curStart = 0, curStyle = null
1712
+ var stream = new StringStream(text, cm.options.tabSize), style
1713
+ var inner = cm.options.addModeClass && [null]
1714
+ if (text == "") { extractLineClasses(callBlankLine(mode, state), lineClasses) }
1715
+ while (!stream.eol()) {
1716
+ if (stream.pos > cm.options.maxHighlightLength) {
1717
+ flattenSpans = false
1718
+ if (forceToEnd) { processLine(cm, text, state, stream.pos) }
1719
+ stream.pos = text.length
1720
+ style = null
1721
+ } else {
1722
+ style = extractLineClasses(readToken(mode, stream, state, inner), lineClasses)
1723
+ }
1724
+ if (inner) {
1725
+ var mName = inner[0].name
1726
+ if (mName) { style = "m-" + (style ? mName + " " + style : mName) }
1727
+ }
1728
+ if (!flattenSpans || curStyle != style) {
1729
+ while (curStart < stream.start) {
1730
+ curStart = Math.min(stream.start, curStart + 5000)
1731
+ f(curStart, curStyle)
1732
+ }
1733
+ curStyle = style
1734
+ }
1735
+ stream.start = stream.pos
1736
+ }
1737
+ while (curStart < stream.pos) {
1738
+ // Webkit seems to refuse to render text nodes longer than 57444
1739
+ // characters, and returns inaccurate measurements in nodes
1740
+ // starting around 5000 chars.
1741
+ var pos = Math.min(stream.pos, curStart + 5000)
1742
+ f(pos, curStyle)
1743
+ curStart = pos
1744
+ }
1745
+ }
1746
+
1747
+ // Finds the line to start with when starting a parse. Tries to
1748
+ // find a line with a stateAfter, so that it can start with a
1749
+ // valid state. If that fails, it returns the line with the
1750
+ // smallest indentation, which tends to need the least context to
1751
+ // parse correctly.
1752
+ function findStartLine(cm, n, precise) {
1753
+ var minindent, minline, doc = cm.doc
1754
+ var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100)
1755
+ for (var search = n; search > lim; --search) {
1756
+ if (search <= doc.first) { return doc.first }
1757
+ var line = getLine(doc, search - 1)
1758
+ if (line.stateAfter && (!precise || search <= doc.frontier)) { return search }
1759
+ var indented = countColumn(line.text, null, cm.options.tabSize)
1760
+ if (minline == null || minindent > indented) {
1761
+ minline = search - 1
1762
+ minindent = indented
1763
+ }
1764
+ }
1765
+ return minline
1766
+ }
1767
+
1768
+ // LINE DATA STRUCTURE
1769
+
1770
+ // Line objects. These hold state related to a line, including
1771
+ // highlighting info (the styles array).
1772
+ var Line = function(text, markedSpans, estimateHeight) {
1773
+ this.text = text
1774
+ attachMarkedSpans(this, markedSpans)
1775
+ this.height = estimateHeight ? estimateHeight(this) : 1
1776
+ };
1777
+
1778
+ Line.prototype.lineNo = function () { return lineNo(this) };
1779
+ eventMixin(Line)
1780
+
1781
+ // Change the content (text, markers) of a line. Automatically
1782
+ // invalidates cached information and tries to re-estimate the
1783
+ // line's height.
1784
+ function updateLine(line, text, markedSpans, estimateHeight) {
1785
+ line.text = text
1786
+ if (line.stateAfter) { line.stateAfter = null }
1787
+ if (line.styles) { line.styles = null }
1788
+ if (line.order != null) { line.order = null }
1789
+ detachMarkedSpans(line)
1790
+ attachMarkedSpans(line, markedSpans)
1791
+ var estHeight = estimateHeight ? estimateHeight(line) : 1
1792
+ if (estHeight != line.height) { updateLineHeight(line, estHeight) }
1793
+ }
1794
+
1795
+ // Detach a line from the document tree and its markers.
1796
+ function cleanUpLine(line) {
1797
+ line.parent = null
1798
+ detachMarkedSpans(line)
1799
+ }
1800
+
1801
+ // Convert a style as returned by a mode (either null, or a string
1802
+ // containing one or more styles) to a CSS style. This is cached,
1803
+ // and also looks for line-wide styles.
1804
+ var styleToClassCache = {};
1805
+ var styleToClassCacheWithMode = {};
1806
+ function interpretTokenStyle(style, options) {
1807
+ if (!style || /^\s*$/.test(style)) { return null }
1808
+ var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache
1809
+ return cache[style] ||
1810
+ (cache[style] = style.replace(/\S+/g, "cm-$&"))
1811
+ }
1812
+
1813
+ // Render the DOM representation of the text of a line. Also builds
1814
+ // up a 'line map', which points at the DOM nodes that represent
1815
+ // specific stretches of text, and is used by the measuring code.
1816
+ // The returned object contains the DOM node, this map, and
1817
+ // information about line-wide styles that were set by the mode.
1818
+ function buildLineContent(cm, lineView) {
1819
+ // The padding-right forces the element to have a 'border', which
1820
+ // is needed on Webkit to be able to get line-level bounding
1821
+ // rectangles for it (in measureChar).
1822
+ var content = eltP("span", null, null, webkit ? "padding-right: .1px" : null)
1823
+ var builder = {pre: eltP("pre", [content], "CodeMirror-line"), content: content,
1824
+ col: 0, pos: 0, cm: cm,
1825
+ trailingSpace: false,
1826
+ splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")}
1827
+ lineView.measure = {}
1828
+
1829
+ // Iterate over the logical lines that make up this visual line.
1830
+ for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) {
1831
+ var line = i ? lineView.rest[i - 1] : lineView.line, order = (void 0)
1832
+ builder.pos = 0
1833
+ builder.addToken = buildToken
1834
+ // Optionally wire in some hacks into the token-rendering
1835
+ // algorithm, to deal with browser quirks.
1836
+ if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line, cm.doc.direction)))
1837
+ { builder.addToken = buildTokenBadBidi(builder.addToken, order) }
1838
+ builder.map = []
1839
+ var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line)
1840
+ insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate))
1841
+ if (line.styleClasses) {
1842
+ if (line.styleClasses.bgClass)
1843
+ { builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || "") }
1844
+ if (line.styleClasses.textClass)
1845
+ { builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || "") }
1846
+ }
1847
+
1848
+ // Ensure at least a single node is present, for measuring.
1849
+ if (builder.map.length == 0)
1850
+ { builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))) }
1851
+
1852
+ // Store the map and a cache object for the current logical line
1853
+ if (i == 0) {
1854
+ lineView.measure.map = builder.map
1855
+ lineView.measure.cache = {}
1856
+ } else {
1857
+ ;(lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map)
1858
+ ;(lineView.measure.caches || (lineView.measure.caches = [])).push({})
1859
+ }
1860
+ }
1861
+
1862
+ // See issue #2901
1863
+ if (webkit) {
1864
+ var last = builder.content.lastChild
1865
+ if (/\bcm-tab\b/.test(last.className) || (last.querySelector && last.querySelector(".cm-tab")))
1866
+ { builder.content.className = "cm-tab-wrap-hack" }
1867
+ }
1868
+
1869
+ signal(cm, "renderLine", cm, lineView.line, builder.pre)
1870
+ if (builder.pre.className)
1871
+ { builder.textClass = joinClasses(builder.pre.className, builder.textClass || "") }
1872
+
1873
+ return builder
1874
+ }
1875
+
1876
+ function defaultSpecialCharPlaceholder(ch) {
1877
+ var token = elt("span", "\u2022", "cm-invalidchar")
1878
+ token.title = "\\u" + ch.charCodeAt(0).toString(16)
1879
+ token.setAttribute("aria-label", token.title)
1880
+ return token
1881
+ }
1882
+
1883
+ // Build up the DOM representation for a single token, and add it to
1884
+ // the line map. Takes care to render special characters separately.
1885
+ function buildToken(builder, text, style, startStyle, endStyle, title, css) {
1886
+ if (!text) { return }
1887
+ var displayText = builder.splitSpaces ? splitSpaces(text, builder.trailingSpace) : text
1888
+ var special = builder.cm.state.specialChars, mustWrap = false
1889
+ var content
1890
+ if (!special.test(text)) {
1891
+ builder.col += text.length
1892
+ content = document.createTextNode(displayText)
1893
+ builder.map.push(builder.pos, builder.pos + text.length, content)
1894
+ if (ie && ie_version < 9) { mustWrap = true }
1895
+ builder.pos += text.length
1896
+ } else {
1897
+ content = document.createDocumentFragment()
1898
+ var pos = 0
1899
+ while (true) {
1900
+ special.lastIndex = pos
1901
+ var m = special.exec(text)
1902
+ var skipped = m ? m.index - pos : text.length - pos
1903
+ if (skipped) {
1904
+ var txt = document.createTextNode(displayText.slice(pos, pos + skipped))
1905
+ if (ie && ie_version < 9) { content.appendChild(elt("span", [txt])) }
1906
+ else { content.appendChild(txt) }
1907
+ builder.map.push(builder.pos, builder.pos + skipped, txt)
1908
+ builder.col += skipped
1909
+ builder.pos += skipped
1910
+ }
1911
+ if (!m) { break }
1912
+ pos += skipped + 1
1913
+ var txt$1 = (void 0)
1914
+ if (m[0] == "\t") {
1915
+ var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize
1916
+ txt$1 = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"))
1917
+ txt$1.setAttribute("role", "presentation")
1918
+ txt$1.setAttribute("cm-text", "\t")
1919
+ builder.col += tabWidth
1920
+ } else if (m[0] == "\r" || m[0] == "\n") {
1921
+ txt$1 = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar"))
1922
+ txt$1.setAttribute("cm-text", m[0])
1923
+ builder.col += 1
1924
+ } else {
1925
+ txt$1 = builder.cm.options.specialCharPlaceholder(m[0])
1926
+ txt$1.setAttribute("cm-text", m[0])
1927
+ if (ie && ie_version < 9) { content.appendChild(elt("span", [txt$1])) }
1928
+ else { content.appendChild(txt$1) }
1929
+ builder.col += 1
1930
+ }
1931
+ builder.map.push(builder.pos, builder.pos + 1, txt$1)
1932
+ builder.pos++
1933
+ }
1934
+ }
1935
+ builder.trailingSpace = displayText.charCodeAt(text.length - 1) == 32
1936
+ if (style || startStyle || endStyle || mustWrap || css) {
1937
+ var fullStyle = style || ""
1938
+ if (startStyle) { fullStyle += startStyle }
1939
+ if (endStyle) { fullStyle += endStyle }
1940
+ var token = elt("span", [content], fullStyle, css)
1941
+ if (title) { token.title = title }
1942
+ return builder.content.appendChild(token)
1943
+ }
1944
+ builder.content.appendChild(content)
1945
+ }
1946
+
1947
+ function splitSpaces(text, trailingBefore) {
1948
+ if (text.length > 1 && !/ /.test(text)) { return text }
1949
+ var spaceBefore = trailingBefore, result = ""
1950
+ for (var i = 0; i < text.length; i++) {
1951
+ var ch = text.charAt(i)
1952
+ if (ch == " " && spaceBefore && (i == text.length - 1 || text.charCodeAt(i + 1) == 32))
1953
+ { ch = "\u00a0" }
1954
+ result += ch
1955
+ spaceBefore = ch == " "
1956
+ }
1957
+ return result
1958
+ }
1959
+
1960
+ // Work around nonsense dimensions being reported for stretches of
1961
+ // right-to-left text.
1962
+ function buildTokenBadBidi(inner, order) {
1963
+ return function (builder, text, style, startStyle, endStyle, title, css) {
1964
+ style = style ? style + " cm-force-border" : "cm-force-border"
1965
+ var start = builder.pos, end = start + text.length
1966
+ for (;;) {
1967
+ // Find the part that overlaps with the start of this text
1968
+ var part = (void 0)
1969
+ for (var i = 0; i < order.length; i++) {
1970
+ part = order[i]
1971
+ if (part.to > start && part.from <= start) { break }
1972
+ }
1973
+ if (part.to >= end) { return inner(builder, text, style, startStyle, endStyle, title, css) }
1974
+ inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css)
1975
+ startStyle = null
1976
+ text = text.slice(part.to - start)
1977
+ start = part.to
1978
+ }
1979
+ }
1980
+ }
1981
+
1982
+ function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
1983
+ var widget = !ignoreWidget && marker.widgetNode
1984
+ if (widget) { builder.map.push(builder.pos, builder.pos + size, widget) }
1985
+ if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) {
1986
+ if (!widget)
1987
+ { widget = builder.content.appendChild(document.createElement("span")) }
1988
+ widget.setAttribute("cm-marker", marker.id)
1989
+ }
1990
+ if (widget) {
1991
+ builder.cm.display.input.setUneditable(widget)
1992
+ builder.content.appendChild(widget)
1993
+ }
1994
+ builder.pos += size
1995
+ builder.trailingSpace = false
1996
+ }
1997
+
1998
+ // Outputs a number of spans to make up a line, taking highlighting
1999
+ // and marked text into account.
2000
+ function insertLineContent(line, builder, styles) {
2001
+ var spans = line.markedSpans, allText = line.text, at = 0
2002
+ if (!spans) {
2003
+ for (var i$1 = 1; i$1 < styles.length; i$1+=2)
2004
+ { builder.addToken(builder, allText.slice(at, at = styles[i$1]), interpretTokenStyle(styles[i$1+1], builder.cm.options)) }
2005
+ return
2006
+ }
2007
+
2008
+ var len = allText.length, pos = 0, i = 1, text = "", style, css
2009
+ var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed
2010
+ for (;;) {
2011
+ if (nextChange == pos) { // Update current marker set
2012
+ spanStyle = spanEndStyle = spanStartStyle = title = css = ""
2013
+ collapsed = null; nextChange = Infinity
2014
+ var foundBookmarks = [], endStyles = (void 0)
2015
+ for (var j = 0; j < spans.length; ++j) {
2016
+ var sp = spans[j], m = sp.marker
2017
+ if (m.type == "bookmark" && sp.from == pos && m.widgetNode) {
2018
+ foundBookmarks.push(m)
2019
+ } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) {
2020
+ if (sp.to != null && sp.to != pos && nextChange > sp.to) {
2021
+ nextChange = sp.to
2022
+ spanEndStyle = ""
2023
+ }
2024
+ if (m.className) { spanStyle += " " + m.className }
2025
+ if (m.css) { css = (css ? css + ";" : "") + m.css }
2026
+ if (m.startStyle && sp.from == pos) { spanStartStyle += " " + m.startStyle }
2027
+ if (m.endStyle && sp.to == nextChange) { (endStyles || (endStyles = [])).push(m.endStyle, sp.to) }
2028
+ if (m.title && !title) { title = m.title }
2029
+ if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))
2030
+ { collapsed = sp }
2031
+ } else if (sp.from > pos && nextChange > sp.from) {
2032
+ nextChange = sp.from
2033
+ }
2034
+ }
2035
+ if (endStyles) { for (var j$1 = 0; j$1 < endStyles.length; j$1 += 2)
2036
+ { if (endStyles[j$1 + 1] == nextChange) { spanEndStyle += " " + endStyles[j$1] } } }
2037
+
2038
+ if (!collapsed || collapsed.from == pos) { for (var j$2 = 0; j$2 < foundBookmarks.length; ++j$2)
2039
+ { buildCollapsedSpan(builder, 0, foundBookmarks[j$2]) } }
2040
+ if (collapsed && (collapsed.from || 0) == pos) {
2041
+ buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos,
2042
+ collapsed.marker, collapsed.from == null)
2043
+ if (collapsed.to == null) { return }
2044
+ if (collapsed.to == pos) { collapsed = false }
2045
+ }
2046
+ }
2047
+ if (pos >= len) { break }
2048
+
2049
+ var upto = Math.min(len, nextChange)
2050
+ while (true) {
2051
+ if (text) {
2052
+ var end = pos + text.length
2053
+ if (!collapsed) {
2054
+ var tokenText = end > upto ? text.slice(0, upto - pos) : text
2055
+ builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
2056
+ spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css)
2057
+ }
2058
+ if (end >= upto) {text = text.slice(upto - pos); pos = upto; break}
2059
+ pos = end
2060
+ spanStartStyle = ""
2061
+ }
2062
+ text = allText.slice(at, at = styles[i++])
2063
+ style = interpretTokenStyle(styles[i++], builder.cm.options)
2064
+ }
2065
+ }
2066
+ }
2067
+
2068
+
2069
+ // These objects are used to represent the visible (currently drawn)
2070
+ // part of the document. A LineView may correspond to multiple
2071
+ // logical lines, if those are connected by collapsed ranges.
2072
+ function LineView(doc, line, lineN) {
2073
+ // The starting line
2074
+ this.line = line
2075
+ // Continuing lines, if any
2076
+ this.rest = visualLineContinued(line)
2077
+ // Number of logical lines in this visual line
2078
+ this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1
2079
+ this.node = this.text = null
2080
+ this.hidden = lineIsHidden(doc, line)
2081
+ }
2082
+
2083
+ // Create a range of LineView objects for the given lines.
2084
+ function buildViewArray(cm, from, to) {
2085
+ var array = [], nextPos
2086
+ for (var pos = from; pos < to; pos = nextPos) {
2087
+ var view = new LineView(cm.doc, getLine(cm.doc, pos), pos)
2088
+ nextPos = pos + view.size
2089
+ array.push(view)
2090
+ }
2091
+ return array
2092
+ }
2093
+
2094
+ var operationGroup = null
2095
+
2096
+ function pushOperation(op) {
2097
+ if (operationGroup) {
2098
+ operationGroup.ops.push(op)
2099
+ } else {
2100
+ op.ownsGroup = operationGroup = {
2101
+ ops: [op],
2102
+ delayedCallbacks: []
2103
+ }
2104
+ }
2105
+ }
2106
+
2107
+ function fireCallbacksForOps(group) {
2108
+ // Calls delayed callbacks and cursorActivity handlers until no
2109
+ // new ones appear
2110
+ var callbacks = group.delayedCallbacks, i = 0
2111
+ do {
2112
+ for (; i < callbacks.length; i++)
2113
+ { callbacks[i].call(null) }
2114
+ for (var j = 0; j < group.ops.length; j++) {
2115
+ var op = group.ops[j]
2116
+ if (op.cursorActivityHandlers)
2117
+ { while (op.cursorActivityCalled < op.cursorActivityHandlers.length)
2118
+ { op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm) } }
2119
+ }
2120
+ } while (i < callbacks.length)
2121
+ }
2122
+
2123
+ function finishOperation(op, endCb) {
2124
+ var group = op.ownsGroup
2125
+ if (!group) { return }
2126
+
2127
+ try { fireCallbacksForOps(group) }
2128
+ finally {
2129
+ operationGroup = null
2130
+ endCb(group)
2131
+ }
2132
+ }
2133
+
2134
+ var orphanDelayedCallbacks = null
2135
+
2136
+ // Often, we want to signal events at a point where we are in the
2137
+ // middle of some work, but don't want the handler to start calling
2138
+ // other methods on the editor, which might be in an inconsistent
2139
+ // state or simply not expect any other events to happen.
2140
+ // signalLater looks whether there are any handlers, and schedules
2141
+ // them to be executed when the last operation ends, or, if no
2142
+ // operation is active, when a timeout fires.
2143
+ function signalLater(emitter, type /*, values...*/) {
2144
+ var arr = getHandlers(emitter, type)
2145
+ if (!arr.length) { return }
2146
+ var args = Array.prototype.slice.call(arguments, 2), list
2147
+ if (operationGroup) {
2148
+ list = operationGroup.delayedCallbacks
2149
+ } else if (orphanDelayedCallbacks) {
2150
+ list = orphanDelayedCallbacks
2151
+ } else {
2152
+ list = orphanDelayedCallbacks = []
2153
+ setTimeout(fireOrphanDelayed, 0)
2154
+ }
2155
+ var loop = function ( i ) {
2156
+ list.push(function () { return arr[i].apply(null, args); })
2157
+ };
2158
+
2159
+ for (var i = 0; i < arr.length; ++i)
2160
+ loop( i );
2161
+ }
2162
+
2163
+ function fireOrphanDelayed() {
2164
+ var delayed = orphanDelayedCallbacks
2165
+ orphanDelayedCallbacks = null
2166
+ for (var i = 0; i < delayed.length; ++i) { delayed[i]() }
2167
+ }
2168
+
2169
+ // When an aspect of a line changes, a string is added to
2170
+ // lineView.changes. This updates the relevant part of the line's
2171
+ // DOM structure.
2172
+ function updateLineForChanges(cm, lineView, lineN, dims) {
2173
+ for (var j = 0; j < lineView.changes.length; j++) {
2174
+ var type = lineView.changes[j]
2175
+ if (type == "text") { updateLineText(cm, lineView) }
2176
+ else if (type == "gutter") { updateLineGutter(cm, lineView, lineN, dims) }
2177
+ else if (type == "class") { updateLineClasses(cm, lineView) }
2178
+ else if (type == "widget") { updateLineWidgets(cm, lineView, dims) }
2179
+ }
2180
+ lineView.changes = null
2181
+ }
2182
+
2183
+ // Lines with gutter elements, widgets or a background class need to
2184
+ // be wrapped, and have the extra elements added to the wrapper div
2185
+ function ensureLineWrapped(lineView) {
2186
+ if (lineView.node == lineView.text) {
2187
+ lineView.node = elt("div", null, null, "position: relative")
2188
+ if (lineView.text.parentNode)
2189
+ { lineView.text.parentNode.replaceChild(lineView.node, lineView.text) }
2190
+ lineView.node.appendChild(lineView.text)
2191
+ if (ie && ie_version < 8) { lineView.node.style.zIndex = 2 }
2192
+ }
2193
+ return lineView.node
2194
+ }
2195
+
2196
+ function updateLineBackground(cm, lineView) {
2197
+ var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass
2198
+ if (cls) { cls += " CodeMirror-linebackground" }
2199
+ if (lineView.background) {
2200
+ if (cls) { lineView.background.className = cls }
2201
+ else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null }
2202
+ } else if (cls) {
2203
+ var wrap = ensureLineWrapped(lineView)
2204
+ lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild)
2205
+ cm.display.input.setUneditable(lineView.background)
2206
+ }
2207
+ }
2208
+
2209
+ // Wrapper around buildLineContent which will reuse the structure
2210
+ // in display.externalMeasured when possible.
2211
+ function getLineContent(cm, lineView) {
2212
+ var ext = cm.display.externalMeasured
2213
+ if (ext && ext.line == lineView.line) {
2214
+ cm.display.externalMeasured = null
2215
+ lineView.measure = ext.measure
2216
+ return ext.built
2217
+ }
2218
+ return buildLineContent(cm, lineView)
2219
+ }
2220
+
2221
+ // Redraw the line's text. Interacts with the background and text
2222
+ // classes because the mode may output tokens that influence these
2223
+ // classes.
2224
+ function updateLineText(cm, lineView) {
2225
+ var cls = lineView.text.className
2226
+ var built = getLineContent(cm, lineView)
2227
+ if (lineView.text == lineView.node) { lineView.node = built.pre }
2228
+ lineView.text.parentNode.replaceChild(built.pre, lineView.text)
2229
+ lineView.text = built.pre
2230
+ if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) {
2231
+ lineView.bgClass = built.bgClass
2232
+ lineView.textClass = built.textClass
2233
+ updateLineClasses(cm, lineView)
2234
+ } else if (cls) {
2235
+ lineView.text.className = cls
2236
+ }
2237
+ }
2238
+
2239
+ function updateLineClasses(cm, lineView) {
2240
+ updateLineBackground(cm, lineView)
2241
+ if (lineView.line.wrapClass)
2242
+ { ensureLineWrapped(lineView).className = lineView.line.wrapClass }
2243
+ else if (lineView.node != lineView.text)
2244
+ { lineView.node.className = "" }
2245
+ var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass
2246
+ lineView.text.className = textClass || ""
2247
+ }
2248
+
2249
+ function updateLineGutter(cm, lineView, lineN, dims) {
2250
+ if (lineView.gutter) {
2251
+ lineView.node.removeChild(lineView.gutter)
2252
+ lineView.gutter = null
2253
+ }
2254
+ if (lineView.gutterBackground) {
2255
+ lineView.node.removeChild(lineView.gutterBackground)
2256
+ lineView.gutterBackground = null
2257
+ }
2258
+ if (lineView.line.gutterClass) {
2259
+ var wrap = ensureLineWrapped(lineView)
2260
+ lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass,
2261
+ ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px; width: " + (dims.gutterTotalWidth) + "px"))
2262
+ cm.display.input.setUneditable(lineView.gutterBackground)
2263
+ wrap.insertBefore(lineView.gutterBackground, lineView.text)
2264
+ }
2265
+ var markers = lineView.line.gutterMarkers
2266
+ if (cm.options.lineNumbers || markers) {
2267
+ var wrap$1 = ensureLineWrapped(lineView)
2268
+ var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"))
2269
+ cm.display.input.setUneditable(gutterWrap)
2270
+ wrap$1.insertBefore(gutterWrap, lineView.text)
2271
+ if (lineView.line.gutterClass)
2272
+ { gutterWrap.className += " " + lineView.line.gutterClass }
2273
+ if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
2274
+ { lineView.lineNumber = gutterWrap.appendChild(
2275
+ elt("div", lineNumberFor(cm.options, lineN),
2276
+ "CodeMirror-linenumber CodeMirror-gutter-elt",
2277
+ ("left: " + (dims.gutterLeft["CodeMirror-linenumbers"]) + "px; width: " + (cm.display.lineNumInnerWidth) + "px"))) }
2278
+ if (markers) { for (var k = 0; k < cm.options.gutters.length; ++k) {
2279
+ var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id]
2280
+ if (found)
2281
+ { gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt",
2282
+ ("left: " + (dims.gutterLeft[id]) + "px; width: " + (dims.gutterWidth[id]) + "px"))) }
2283
+ } }
2284
+ }
2285
+ }
2286
+
2287
+ function updateLineWidgets(cm, lineView, dims) {
2288
+ if (lineView.alignable) { lineView.alignable = null }
2289
+ for (var node = lineView.node.firstChild, next = (void 0); node; node = next) {
2290
+ next = node.nextSibling
2291
+ if (node.className == "CodeMirror-linewidget")
2292
+ { lineView.node.removeChild(node) }
2293
+ }
2294
+ insertLineWidgets(cm, lineView, dims)
2295
+ }
2296
+
2297
+ // Build a line's DOM representation from scratch
2298
+ function buildLineElement(cm, lineView, lineN, dims) {
2299
+ var built = getLineContent(cm, lineView)
2300
+ lineView.text = lineView.node = built.pre
2301
+ if (built.bgClass) { lineView.bgClass = built.bgClass }
2302
+ if (built.textClass) { lineView.textClass = built.textClass }
2303
+
2304
+ updateLineClasses(cm, lineView)
2305
+ updateLineGutter(cm, lineView, lineN, dims)
2306
+ insertLineWidgets(cm, lineView, dims)
2307
+ return lineView.node
2308
+ }
2309
+
2310
+ // A lineView may contain multiple logical lines (when merged by
2311
+ // collapsed spans). The widgets for all of them need to be drawn.
2312
+ function insertLineWidgets(cm, lineView, dims) {
2313
+ insertLineWidgetsFor(cm, lineView.line, lineView, dims, true)
2314
+ if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++)
2315
+ { insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false) } }
2316
+ }
2317
+
2318
+ function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) {
2319
+ if (!line.widgets) { return }
2320
+ var wrap = ensureLineWrapped(lineView)
2321
+ for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
2322
+ var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget")
2323
+ if (!widget.handleMouseEvents) { node.setAttribute("cm-ignore-events", "true") }
2324
+ positionLineWidget(widget, node, lineView, dims)
2325
+ cm.display.input.setUneditable(node)
2326
+ if (allowAbove && widget.above)
2327
+ { wrap.insertBefore(node, lineView.gutter || lineView.text) }
2328
+ else
2329
+ { wrap.appendChild(node) }
2330
+ signalLater(widget, "redraw")
2331
+ }
2332
+ }
2333
+
2334
+ function positionLineWidget(widget, node, lineView, dims) {
2335
+ if (widget.noHScroll) {
2336
+ ;(lineView.alignable || (lineView.alignable = [])).push(node)
2337
+ var width = dims.wrapperWidth
2338
+ node.style.left = dims.fixedPos + "px"
2339
+ if (!widget.coverGutter) {
2340
+ width -= dims.gutterTotalWidth
2341
+ node.style.paddingLeft = dims.gutterTotalWidth + "px"
2342
+ }
2343
+ node.style.width = width + "px"
2344
+ }
2345
+ if (widget.coverGutter) {
2346
+ node.style.zIndex = 5
2347
+ node.style.position = "relative"
2348
+ if (!widget.noHScroll) { node.style.marginLeft = -dims.gutterTotalWidth + "px" }
2349
+ }
2350
+ }
2351
+
2352
+ function widgetHeight(widget) {
2353
+ if (widget.height != null) { return widget.height }
2354
+ var cm = widget.doc.cm
2355
+ if (!cm) { return 0 }
2356
+ if (!contains(document.body, widget.node)) {
2357
+ var parentStyle = "position: relative;"
2358
+ if (widget.coverGutter)
2359
+ { parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;" }
2360
+ if (widget.noHScroll)
2361
+ { parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;" }
2362
+ removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle))
2363
+ }
2364
+ return widget.height = widget.node.parentNode.offsetHeight
2365
+ }
2366
+
2367
+ // Return true when the given mouse event happened in a widget
2368
+ function eventInWidget(display, e) {
2369
+ for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
2370
+ if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") ||
2371
+ (n.parentNode == display.sizer && n != display.mover))
2372
+ { return true }
2373
+ }
2374
+ }
2375
+
2376
+ // POSITION MEASUREMENT
2377
+
2378
+ function paddingTop(display) {return display.lineSpace.offsetTop}
2379
+ function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight}
2380
+ function paddingH(display) {
2381
+ if (display.cachedPaddingH) { return display.cachedPaddingH }
2382
+ var e = removeChildrenAndAdd(display.measure, elt("pre", "x"))
2383
+ var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle
2384
+ var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)}
2385
+ if (!isNaN(data.left) && !isNaN(data.right)) { display.cachedPaddingH = data }
2386
+ return data
2387
+ }
2388
+
2389
+ function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth }
2390
+ function displayWidth(cm) {
2391
+ return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth
2392
+ }
2393
+ function displayHeight(cm) {
2394
+ return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight
2395
+ }
2396
+
2397
+ // Ensure the lineView.wrapping.heights array is populated. This is
2398
+ // an array of bottom offsets for the lines that make up a drawn
2399
+ // line. When lineWrapping is on, there might be more than one
2400
+ // height.
2401
+ function ensureLineHeights(cm, lineView, rect) {
2402
+ var wrapping = cm.options.lineWrapping
2403
+ var curWidth = wrapping && displayWidth(cm)
2404
+ if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) {
2405
+ var heights = lineView.measure.heights = []
2406
+ if (wrapping) {
2407
+ lineView.measure.width = curWidth
2408
+ var rects = lineView.text.firstChild.getClientRects()
2409
+ for (var i = 0; i < rects.length - 1; i++) {
2410
+ var cur = rects[i], next = rects[i + 1]
2411
+ if (Math.abs(cur.bottom - next.bottom) > 2)
2412
+ { heights.push((cur.bottom + next.top) / 2 - rect.top) }
2413
+ }
2414
+ }
2415
+ heights.push(rect.bottom - rect.top)
2416
+ }
2417
+ }
2418
+
2419
+ // Find a line map (mapping character offsets to text nodes) and a
2420
+ // measurement cache for the given line number. (A line view might
2421
+ // contain multiple lines when collapsed ranges are present.)
2422
+ function mapFromLineView(lineView, line, lineN) {
2423
+ if (lineView.line == line)
2424
+ { return {map: lineView.measure.map, cache: lineView.measure.cache} }
2425
+ for (var i = 0; i < lineView.rest.length; i++)
2426
+ { if (lineView.rest[i] == line)
2427
+ { return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]} } }
2428
+ for (var i$1 = 0; i$1 < lineView.rest.length; i$1++)
2429
+ { if (lineNo(lineView.rest[i$1]) > lineN)
2430
+ { return {map: lineView.measure.maps[i$1], cache: lineView.measure.caches[i$1], before: true} } }
2431
+ }
2432
+
2433
+ // Render a line into the hidden node display.externalMeasured. Used
2434
+ // when measurement is needed for a line that's not in the viewport.
2435
+ function updateExternalMeasurement(cm, line) {
2436
+ line = visualLine(line)
2437
+ var lineN = lineNo(line)
2438
+ var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN)
2439
+ view.lineN = lineN
2440
+ var built = view.built = buildLineContent(cm, view)
2441
+ view.text = built.pre
2442
+ removeChildrenAndAdd(cm.display.lineMeasure, built.pre)
2443
+ return view
2444
+ }
2445
+
2446
+ // Get a {top, bottom, left, right} box (in line-local coordinates)
2447
+ // for a given character.
2448
+ function measureChar(cm, line, ch, bias) {
2449
+ return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias)
2450
+ }
2451
+
2452
+ // Find a line view that corresponds to the given line number.
2453
+ function findViewForLine(cm, lineN) {
2454
+ if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo)
2455
+ { return cm.display.view[findViewIndex(cm, lineN)] }
2456
+ var ext = cm.display.externalMeasured
2457
+ if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size)
2458
+ { return ext }
2459
+ }
2460
+
2461
+ // Measurement can be split in two steps, the set-up work that
2462
+ // applies to the whole line, and the measurement of the actual
2463
+ // character. Functions like coordsChar, that need to do a lot of
2464
+ // measurements in a row, can thus ensure that the set-up work is
2465
+ // only done once.
2466
+ function prepareMeasureForLine(cm, line) {
2467
+ var lineN = lineNo(line)
2468
+ var view = findViewForLine(cm, lineN)
2469
+ if (view && !view.text) {
2470
+ view = null
2471
+ } else if (view && view.changes) {
2472
+ updateLineForChanges(cm, view, lineN, getDimensions(cm))
2473
+ cm.curOp.forceUpdate = true
2474
+ }
2475
+ if (!view)
2476
+ { view = updateExternalMeasurement(cm, line) }
2477
+
2478
+ var info = mapFromLineView(view, line, lineN)
2479
+ return {
2480
+ line: line, view: view, rect: null,
2481
+ map: info.map, cache: info.cache, before: info.before,
2482
+ hasHeights: false
2483
+ }
2484
+ }
2485
+
2486
+ // Given a prepared measurement object, measures the position of an
2487
+ // actual character (or fetches it from the cache).
2488
+ function measureCharPrepared(cm, prepared, ch, bias, varHeight) {
2489
+ if (prepared.before) { ch = -1 }
2490
+ var key = ch + (bias || ""), found
2491
+ if (prepared.cache.hasOwnProperty(key)) {
2492
+ found = prepared.cache[key]
2493
+ } else {
2494
+ if (!prepared.rect)
2495
+ { prepared.rect = prepared.view.text.getBoundingClientRect() }
2496
+ if (!prepared.hasHeights) {
2497
+ ensureLineHeights(cm, prepared.view, prepared.rect)
2498
+ prepared.hasHeights = true
2499
+ }
2500
+ found = measureCharInner(cm, prepared, ch, bias)
2501
+ if (!found.bogus) { prepared.cache[key] = found }
2502
+ }
2503
+ return {left: found.left, right: found.right,
2504
+ top: varHeight ? found.rtop : found.top,
2505
+ bottom: varHeight ? found.rbottom : found.bottom}
2506
+ }
2507
+
2508
+ var nullRect = {left: 0, right: 0, top: 0, bottom: 0}
2509
+
2510
+ function nodeAndOffsetInLineMap(map, ch, bias) {
2511
+ var node, start, end, collapse, mStart, mEnd
2512
+ // First, search the line map for the text node corresponding to,
2513
+ // or closest to, the target character.
2514
+ for (var i = 0; i < map.length; i += 3) {
2515
+ mStart = map[i]
2516
+ mEnd = map[i + 1]
2517
+ if (ch < mStart) {
2518
+ start = 0; end = 1
2519
+ collapse = "left"
2520
+ } else if (ch < mEnd) {
2521
+ start = ch - mStart
2522
+ end = start + 1
2523
+ } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) {
2524
+ end = mEnd - mStart
2525
+ start = end - 1
2526
+ if (ch >= mEnd) { collapse = "right" }
2527
+ }
2528
+ if (start != null) {
2529
+ node = map[i + 2]
2530
+ if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right"))
2531
+ { collapse = bias }
2532
+ if (bias == "left" && start == 0)
2533
+ { while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) {
2534
+ node = map[(i -= 3) + 2]
2535
+ collapse = "left"
2536
+ } }
2537
+ if (bias == "right" && start == mEnd - mStart)
2538
+ { while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) {
2539
+ node = map[(i += 3) + 2]
2540
+ collapse = "right"
2541
+ } }
2542
+ break
2543
+ }
2544
+ }
2545
+ return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd}
2546
+ }
2547
+
2548
+ function getUsefulRect(rects, bias) {
2549
+ var rect = nullRect
2550
+ if (bias == "left") { for (var i = 0; i < rects.length; i++) {
2551
+ if ((rect = rects[i]).left != rect.right) { break }
2552
+ } } else { for (var i$1 = rects.length - 1; i$1 >= 0; i$1--) {
2553
+ if ((rect = rects[i$1]).left != rect.right) { break }
2554
+ } }
2555
+ return rect
2556
+ }
2557
+
2558
+ function measureCharInner(cm, prepared, ch, bias) {
2559
+ var place = nodeAndOffsetInLineMap(prepared.map, ch, bias)
2560
+ var node = place.node, start = place.start, end = place.end, collapse = place.collapse
2561
+
2562
+ var rect
2563
+ if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates.
2564
+ for (var i$1 = 0; i$1 < 4; i$1++) { // Retry a maximum of 4 times when nonsense rectangles are returned
2565
+ while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) { --start }
2566
+ while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) { ++end }
2567
+ if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart)
2568
+ { rect = node.parentNode.getBoundingClientRect() }
2569
+ else
2570
+ { rect = getUsefulRect(range(node, start, end).getClientRects(), bias) }
2571
+ if (rect.left || rect.right || start == 0) { break }
2572
+ end = start
2573
+ start = start - 1
2574
+ collapse = "right"
2575
+ }
2576
+ if (ie && ie_version < 11) { rect = maybeUpdateRectForZooming(cm.display.measure, rect) }
2577
+ } else { // If it is a widget, simply get the box for the whole widget.
2578
+ if (start > 0) { collapse = bias = "right" }
2579
+ var rects
2580
+ if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1)
2581
+ { rect = rects[bias == "right" ? rects.length - 1 : 0] }
2582
+ else
2583
+ { rect = node.getBoundingClientRect() }
2584
+ }
2585
+ if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) {
2586
+ var rSpan = node.parentNode.getClientRects()[0]
2587
+ if (rSpan)
2588
+ { rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom} }
2589
+ else
2590
+ { rect = nullRect }
2591
+ }
2592
+
2593
+ var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top
2594
+ var mid = (rtop + rbot) / 2
2595
+ var heights = prepared.view.measure.heights
2596
+ var i = 0
2597
+ for (; i < heights.length - 1; i++)
2598
+ { if (mid < heights[i]) { break } }
2599
+ var top = i ? heights[i - 1] : 0, bot = heights[i]
2600
+ var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left,
2601
+ right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left,
2602
+ top: top, bottom: bot}
2603
+ if (!rect.left && !rect.right) { result.bogus = true }
2604
+ if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot }
2605
+
2606
+ return result
2607
+ }
2608
+
2609
+ // Work around problem with bounding client rects on ranges being
2610
+ // returned incorrectly when zoomed on IE10 and below.
2611
+ function maybeUpdateRectForZooming(measure, rect) {
2612
+ if (!window.screen || screen.logicalXDPI == null ||
2613
+ screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure))
2614
+ { return rect }
2615
+ var scaleX = screen.logicalXDPI / screen.deviceXDPI
2616
+ var scaleY = screen.logicalYDPI / screen.deviceYDPI
2617
+ return {left: rect.left * scaleX, right: rect.right * scaleX,
2618
+ top: rect.top * scaleY, bottom: rect.bottom * scaleY}
2619
+ }
2620
+
2621
+ function clearLineMeasurementCacheFor(lineView) {
2622
+ if (lineView.measure) {
2623
+ lineView.measure.cache = {}
2624
+ lineView.measure.heights = null
2625
+ if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++)
2626
+ { lineView.measure.caches[i] = {} } }
2627
+ }
2628
+ }
2629
+
2630
+ function clearLineMeasurementCache(cm) {
2631
+ cm.display.externalMeasure = null
2632
+ removeChildren(cm.display.lineMeasure)
2633
+ for (var i = 0; i < cm.display.view.length; i++)
2634
+ { clearLineMeasurementCacheFor(cm.display.view[i]) }
2635
+ }
2636
+
2637
+ function clearCaches(cm) {
2638
+ clearLineMeasurementCache(cm)
2639
+ cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null
2640
+ if (!cm.options.lineWrapping) { cm.display.maxLineChanged = true }
2641
+ cm.display.lineNumChars = null
2642
+ }
2643
+
2644
+ function pageScrollX() {
2645
+ // Work around https://bugs.chromium.org/p/chromium/issues/detail?id=489206
2646
+ // which causes page_Offset and bounding client rects to use
2647
+ // different reference viewports and invalidate our calculations.
2648
+ if (chrome && android) { return -(document.body.getBoundingClientRect().left - parseInt(getComputedStyle(document.body).marginLeft)) }
2649
+ return window.pageXOffset || (document.documentElement || document.body).scrollLeft
2650
+ }
2651
+ function pageScrollY() {
2652
+ if (chrome && android) { return -(document.body.getBoundingClientRect().top - parseInt(getComputedStyle(document.body).marginTop)) }
2653
+ return window.pageYOffset || (document.documentElement || document.body).scrollTop
2654
+ }
2655
+
2656
+ // Converts a {top, bottom, left, right} box from line-local
2657
+ // coordinates into another coordinate system. Context may be one of
2658
+ // "line", "div" (display.lineDiv), "local"./null (editor), "window",
2659
+ // or "page".
2660
+ function intoCoordSystem(cm, lineObj, rect, context, includeWidgets) {
2661
+ if (!includeWidgets && lineObj.widgets) { for (var i = 0; i < lineObj.widgets.length; ++i) { if (lineObj.widgets[i].above) {
2662
+ var size = widgetHeight(lineObj.widgets[i])
2663
+ rect.top += size; rect.bottom += size
2664
+ } } }
2665
+ if (context == "line") { return rect }
2666
+ if (!context) { context = "local" }
2667
+ var yOff = heightAtLine(lineObj)
2668
+ if (context == "local") { yOff += paddingTop(cm.display) }
2669
+ else { yOff -= cm.display.viewOffset }
2670
+ if (context == "page" || context == "window") {
2671
+ var lOff = cm.display.lineSpace.getBoundingClientRect()
2672
+ yOff += lOff.top + (context == "window" ? 0 : pageScrollY())
2673
+ var xOff = lOff.left + (context == "window" ? 0 : pageScrollX())
2674
+ rect.left += xOff; rect.right += xOff
2675
+ }
2676
+ rect.top += yOff; rect.bottom += yOff
2677
+ return rect
2678
+ }
2679
+
2680
+ // Coverts a box from "div" coords to another coordinate system.
2681
+ // Context may be "window", "page", "div", or "local"./null.
2682
+ function fromCoordSystem(cm, coords, context) {
2683
+ if (context == "div") { return coords }
2684
+ var left = coords.left, top = coords.top
2685
+ // First move into "page" coordinate system
2686
+ if (context == "page") {
2687
+ left -= pageScrollX()
2688
+ top -= pageScrollY()
2689
+ } else if (context == "local" || !context) {
2690
+ var localBox = cm.display.sizer.getBoundingClientRect()
2691
+ left += localBox.left
2692
+ top += localBox.top
2693
+ }
2694
+
2695
+ var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect()
2696
+ return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top}
2697
+ }
2698
+
2699
+ function charCoords(cm, pos, context, lineObj, bias) {
2700
+ if (!lineObj) { lineObj = getLine(cm.doc, pos.line) }
2701
+ return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context)
2702
+ }
2703
+
2704
+ // Returns a box for a given cursor position, which may have an
2705
+ // 'other' property containing the position of the secondary cursor
2706
+ // on a bidi boundary.
2707
+ // A cursor Pos(line, char, "before") is on the same visual line as `char - 1`
2708
+ // and after `char - 1` in writing order of `char - 1`
2709
+ // A cursor Pos(line, char, "after") is on the same visual line as `char`
2710
+ // and before `char` in writing order of `char`
2711
+ // Examples (upper-case letters are RTL, lower-case are LTR):
2712
+ // Pos(0, 1, ...)
2713
+ // before after
2714
+ // ab a|b a|b
2715
+ // aB a|B aB|
2716
+ // Ab |Ab A|b
2717
+ // AB B|A B|A
2718
+ // Every position after the last character on a line is considered to stick
2719
+ // to the last character on the line.
2720
+ function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) {
2721
+ lineObj = lineObj || getLine(cm.doc, pos.line)
2722
+ if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj) }
2723
+ function get(ch, right) {
2724
+ var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight)
2725
+ if (right) { m.left = m.right; } else { m.right = m.left }
2726
+ return intoCoordSystem(cm, lineObj, m, context)
2727
+ }
2728
+ var order = getOrder(lineObj, cm.doc.direction), ch = pos.ch, sticky = pos.sticky
2729
+ if (ch >= lineObj.text.length) {
2730
+ ch = lineObj.text.length
2731
+ sticky = "before"
2732
+ } else if (ch <= 0) {
2733
+ ch = 0
2734
+ sticky = "after"
2735
+ }
2736
+ if (!order) { return get(sticky == "before" ? ch - 1 : ch, sticky == "before") }
2737
+
2738
+ function getBidi(ch, partPos, invert) {
2739
+ var part = order[partPos], right = (part.level % 2) != 0
2740
+ return get(invert ? ch - 1 : ch, right != invert)
2741
+ }
2742
+ var partPos = getBidiPartAt(order, ch, sticky)
2743
+ var other = bidiOther
2744
+ var val = getBidi(ch, partPos, sticky == "before")
2745
+ if (other != null) { val.other = getBidi(ch, other, sticky != "before") }
2746
+ return val
2747
+ }
2748
+
2749
+ // Used to cheaply estimate the coordinates for a position. Used for
2750
+ // intermediate scroll updates.
2751
+ function estimateCoords(cm, pos) {
2752
+ var left = 0
2753
+ pos = clipPos(cm.doc, pos)
2754
+ if (!cm.options.lineWrapping) { left = charWidth(cm.display) * pos.ch }
2755
+ var lineObj = getLine(cm.doc, pos.line)
2756
+ var top = heightAtLine(lineObj) + paddingTop(cm.display)
2757
+ return {left: left, right: left, top: top, bottom: top + lineObj.height}
2758
+ }
2759
+
2760
+ // Positions returned by coordsChar contain some extra information.
2761
+ // xRel is the relative x position of the input coordinates compared
2762
+ // to the found position (so xRel > 0 means the coordinates are to
2763
+ // the right of the character position, for example). When outside
2764
+ // is true, that means the coordinates lie outside the line's
2765
+ // vertical range.
2766
+ function PosWithInfo(line, ch, sticky, outside, xRel) {
2767
+ var pos = Pos(line, ch, sticky)
2768
+ pos.xRel = xRel
2769
+ if (outside) { pos.outside = true }
2770
+ return pos
2771
+ }
2772
+
2773
+ // Compute the character position closest to the given coordinates.
2774
+ // Input must be lineSpace-local ("div" coordinate system).
2775
+ function coordsChar(cm, x, y) {
2776
+ var doc = cm.doc
2777
+ y += cm.display.viewOffset
2778
+ if (y < 0) { return PosWithInfo(doc.first, 0, null, true, -1) }
2779
+ var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1
2780
+ if (lineN > last)
2781
+ { return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, null, true, 1) }
2782
+ if (x < 0) { x = 0 }
2783
+
2784
+ var lineObj = getLine(doc, lineN)
2785
+ for (;;) {
2786
+ var found = coordsCharInner(cm, lineObj, lineN, x, y)
2787
+ var merged = collapsedSpanAtEnd(lineObj)
2788
+ var mergedPos = merged && merged.find(0, true)
2789
+ if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))
2790
+ { lineN = lineNo(lineObj = mergedPos.to.line) }
2791
+ else
2792
+ { return found }
2793
+ }
2794
+ }
2795
+
2796
+ function wrappedLineExtent(cm, lineObj, preparedMeasure, y) {
2797
+ var measure = function (ch) { return intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, ch), "line"); }
2798
+ var end = lineObj.text.length
2799
+ var begin = findFirst(function (ch) { return measure(ch - 1).bottom <= y; }, end, 0)
2800
+ end = findFirst(function (ch) { return measure(ch).top > y; }, begin, end)
2801
+ return {begin: begin, end: end}
2802
+ }
2803
+
2804
+ function wrappedLineExtentChar(cm, lineObj, preparedMeasure, target) {
2805
+ var targetTop = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, target), "line").top
2806
+ return wrappedLineExtent(cm, lineObj, preparedMeasure, targetTop)
2807
+ }
2808
+
2809
+ function coordsCharInner(cm, lineObj, lineNo, x, y) {
2810
+ y -= heightAtLine(lineObj)
2811
+ var begin = 0, end = lineObj.text.length
2812
+ var preparedMeasure = prepareMeasureForLine(cm, lineObj)
2813
+ var pos
2814
+ var order = getOrder(lineObj, cm.doc.direction)
2815
+ if (order) {
2816
+ if (cm.options.lineWrapping) {
2817
+ ;var assign;
2818
+ ((assign = wrappedLineExtent(cm, lineObj, preparedMeasure, y), begin = assign.begin, end = assign.end, assign))
2819
+ }
2820
+ pos = new Pos(lineNo, begin)
2821
+ var beginLeft = cursorCoords(cm, pos, "line", lineObj, preparedMeasure).left
2822
+ var dir = beginLeft < x ? 1 : -1
2823
+ var prevDiff, diff = beginLeft - x, prevPos
2824
+ do {
2825
+ prevDiff = diff
2826
+ prevPos = pos
2827
+ pos = moveVisually(cm, lineObj, pos, dir)
2828
+ if (pos == null || pos.ch < begin || end <= (pos.sticky == "before" ? pos.ch - 1 : pos.ch)) {
2829
+ pos = prevPos
2830
+ break
2831
+ }
2832
+ diff = cursorCoords(cm, pos, "line", lineObj, preparedMeasure).left - x
2833
+ } while ((dir < 0) != (diff < 0) && (Math.abs(diff) <= Math.abs(prevDiff)))
2834
+ if (Math.abs(diff) > Math.abs(prevDiff)) {
2835
+ if ((diff < 0) == (prevDiff < 0)) { throw new Error("Broke out of infinite loop in coordsCharInner") }
2836
+ pos = prevPos
2837
+ }
2838
+ } else {
2839
+ var ch = findFirst(function (ch) {
2840
+ var box = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, ch), "line")
2841
+ if (box.top > y) {
2842
+ // For the cursor stickiness
2843
+ end = Math.min(ch, end)
2844
+ return true
2845
+ }
2846
+ else if (box.bottom <= y) { return false }
2847
+ else if (box.left > x) { return true }
2848
+ else if (box.right < x) { return false }
2849
+ else { return (x - box.left < box.right - x) }
2850
+ }, begin, end)
2851
+ ch = skipExtendingChars(lineObj.text, ch, 1)
2852
+ pos = new Pos(lineNo, ch, ch == end ? "before" : "after")
2853
+ }
2854
+ var coords = cursorCoords(cm, pos, "line", lineObj, preparedMeasure)
2855
+ if (y < coords.top || coords.bottom < y) { pos.outside = true }
2856
+ pos.xRel = x < coords.left ? -1 : (x > coords.right ? 1 : 0)
2857
+ return pos
2858
+ }
2859
+
2860
+ var measureText
2861
+ // Compute the default text height.
2862
+ function textHeight(display) {
2863
+ if (display.cachedTextHeight != null) { return display.cachedTextHeight }
2864
+ if (measureText == null) {
2865
+ measureText = elt("pre")
2866
+ // Measure a bunch of lines, for browsers that compute
2867
+ // fractional heights.
2868
+ for (var i = 0; i < 49; ++i) {
2869
+ measureText.appendChild(document.createTextNode("x"))
2870
+ measureText.appendChild(elt("br"))
2871
+ }
2872
+ measureText.appendChild(document.createTextNode("x"))
2873
+ }
2874
+ removeChildrenAndAdd(display.measure, measureText)
2875
+ var height = measureText.offsetHeight / 50
2876
+ if (height > 3) { display.cachedTextHeight = height }
2877
+ removeChildren(display.measure)
2878
+ return height || 1
2879
+ }
2880
+
2881
+ // Compute the default character width.
2882
+ function charWidth(display) {
2883
+ if (display.cachedCharWidth != null) { return display.cachedCharWidth }
2884
+ var anchor = elt("span", "xxxxxxxxxx")
2885
+ var pre = elt("pre", [anchor])
2886
+ removeChildrenAndAdd(display.measure, pre)
2887
+ var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10
2888
+ if (width > 2) { display.cachedCharWidth = width }
2889
+ return width || 10
2890
+ }
2891
+
2892
+ // Do a bulk-read of the DOM positions and sizes needed to draw the
2893
+ // view, so that we don't interleave reading and writing to the DOM.
2894
+ function getDimensions(cm) {
2895
+ var d = cm.display, left = {}, width = {}
2896
+ var gutterLeft = d.gutters.clientLeft
2897
+ for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
2898
+ left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft
2899
+ width[cm.options.gutters[i]] = n.clientWidth
2900
+ }
2901
+ return {fixedPos: compensateForHScroll(d),
2902
+ gutterTotalWidth: d.gutters.offsetWidth,
2903
+ gutterLeft: left,
2904
+ gutterWidth: width,
2905
+ wrapperWidth: d.wrapper.clientWidth}
2906
+ }
2907
+
2908
+ // Computes display.scroller.scrollLeft + display.gutters.offsetWidth,
2909
+ // but using getBoundingClientRect to get a sub-pixel-accurate
2910
+ // result.
2911
+ function compensateForHScroll(display) {
2912
+ return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left
2913
+ }
2914
+
2915
+ // Returns a function that estimates the height of a line, to use as
2916
+ // first approximation until the line becomes visible (and is thus
2917
+ // properly measurable).
2918
+ function estimateHeight(cm) {
2919
+ var th = textHeight(cm.display), wrapping = cm.options.lineWrapping
2920
+ var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3)
2921
+ return function (line) {
2922
+ if (lineIsHidden(cm.doc, line)) { return 0 }
2923
+
2924
+ var widgetsHeight = 0
2925
+ if (line.widgets) { for (var i = 0; i < line.widgets.length; i++) {
2926
+ if (line.widgets[i].height) { widgetsHeight += line.widgets[i].height }
2927
+ } }
2928
+
2929
+ if (wrapping)
2930
+ { return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th }
2931
+ else
2932
+ { return widgetsHeight + th }
2933
+ }
2934
+ }
2935
+
2936
+ function estimateLineHeights(cm) {
2937
+ var doc = cm.doc, est = estimateHeight(cm)
2938
+ doc.iter(function (line) {
2939
+ var estHeight = est(line)
2940
+ if (estHeight != line.height) { updateLineHeight(line, estHeight) }
2941
+ })
2942
+ }
2943
+
2944
+ // Given a mouse event, find the corresponding position. If liberal
2945
+ // is false, it checks whether a gutter or scrollbar was clicked,
2946
+ // and returns null if it was. forRect is used by rectangular
2947
+ // selections, and tries to estimate a character position even for
2948
+ // coordinates beyond the right of the text.
2949
+ function posFromMouse(cm, e, liberal, forRect) {
2950
+ var display = cm.display
2951
+ if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") { return null }
2952
+
2953
+ var x, y, space = display.lineSpace.getBoundingClientRect()
2954
+ // Fails unpredictably on IE[67] when mouse is dragged around quickly.
2955
+ try { x = e.clientX - space.left; y = e.clientY - space.top }
2956
+ catch (e) { return null }
2957
+ var coords = coordsChar(cm, x, y), line
2958
+ if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
2959
+ var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length
2960
+ coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff))
2961
+ }
2962
+ return coords
2963
+ }
2964
+
2965
+ // Find the view element corresponding to a given line. Return null
2966
+ // when the line isn't visible.
2967
+ function findViewIndex(cm, n) {
2968
+ if (n >= cm.display.viewTo) { return null }
2969
+ n -= cm.display.viewFrom
2970
+ if (n < 0) { return null }
2971
+ var view = cm.display.view
2972
+ for (var i = 0; i < view.length; i++) {
2973
+ n -= view[i].size
2974
+ if (n < 0) { return i }
2975
+ }
2976
+ }
2977
+
2978
+ function updateSelection(cm) {
2979
+ cm.display.input.showSelection(cm.display.input.prepareSelection())
2980
+ }
2981
+
2982
+ function prepareSelection(cm, primary) {
2983
+ var doc = cm.doc, result = {}
2984
+ var curFragment = result.cursors = document.createDocumentFragment()
2985
+ var selFragment = result.selection = document.createDocumentFragment()
2986
+
2987
+ for (var i = 0; i < doc.sel.ranges.length; i++) {
2988
+ if (primary === false && i == doc.sel.primIndex) { continue }
2989
+ var range = doc.sel.ranges[i]
2990
+ if (range.from().line >= cm.display.viewTo || range.to().line < cm.display.viewFrom) { continue }
2991
+ var collapsed = range.empty()
2992
+ if (collapsed || cm.options.showCursorWhenSelecting)
2993
+ { drawSelectionCursor(cm, range.head, curFragment) }
2994
+ if (!collapsed)
2995
+ { drawSelectionRange(cm, range, selFragment) }
2996
+ }
2997
+ return result
2998
+ }
2999
+
3000
+ // Draws a cursor for the given range
3001
+ function drawSelectionCursor(cm, head, output) {
3002
+ var pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine)
3003
+
3004
+ var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor"))
3005
+ cursor.style.left = pos.left + "px"
3006
+ cursor.style.top = pos.top + "px"
3007
+ cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px"
3008
+
3009
+ if (pos.other) {
3010
+ // Secondary cursor, shown when on a 'jump' in bi-directional text
3011
+ var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor"))
3012
+ otherCursor.style.display = ""
3013
+ otherCursor.style.left = pos.other.left + "px"
3014
+ otherCursor.style.top = pos.other.top + "px"
3015
+ otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px"
3016
+ }
3017
+ }
3018
+
3019
+ // Draws the given range as a highlighted selection
3020
+ function drawSelectionRange(cm, range, output) {
3021
+ var display = cm.display, doc = cm.doc
3022
+ var fragment = document.createDocumentFragment()
3023
+ var padding = paddingH(cm.display), leftSide = padding.left
3024
+ var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right
3025
+
3026
+ function add(left, top, width, bottom) {
3027
+ if (top < 0) { top = 0 }
3028
+ top = Math.round(top)
3029
+ bottom = Math.round(bottom)
3030
+ 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")))
3031
+ }
3032
+
3033
+ function drawForLine(line, fromArg, toArg) {
3034
+ var lineObj = getLine(doc, line)
3035
+ var lineLen = lineObj.text.length
3036
+ var start, end
3037
+ function coords(ch, bias) {
3038
+ return charCoords(cm, Pos(line, ch), "div", lineObj, bias)
3039
+ }
3040
+
3041
+ iterateBidiSections(getOrder(lineObj, doc.direction), fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir) {
3042
+ var leftPos = coords(from, "left"), rightPos, left, right
3043
+ if (from == to) {
3044
+ rightPos = leftPos
3045
+ left = right = leftPos.left
3046
+ } else {
3047
+ rightPos = coords(to - 1, "right")
3048
+ if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp }
3049
+ left = leftPos.left
3050
+ right = rightPos.right
3051
+ }
3052
+ if (fromArg == null && from == 0) { left = leftSide }
3053
+ if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part
3054
+ add(left, leftPos.top, null, leftPos.bottom)
3055
+ left = leftSide
3056
+ if (leftPos.bottom < rightPos.top) { add(left, leftPos.bottom, null, rightPos.top) }
3057
+ }
3058
+ if (toArg == null && to == lineLen) { right = rightSide }
3059
+ if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)
3060
+ { start = leftPos }
3061
+ if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)
3062
+ { end = rightPos }
3063
+ if (left < leftSide + 1) { left = leftSide }
3064
+ add(left, rightPos.top, right - left, rightPos.bottom)
3065
+ })
3066
+ return {start: start, end: end}
3067
+ }
3068
+
3069
+ var sFrom = range.from(), sTo = range.to()
3070
+ if (sFrom.line == sTo.line) {
3071
+ drawForLine(sFrom.line, sFrom.ch, sTo.ch)
3072
+ } else {
3073
+ var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line)
3074
+ var singleVLine = visualLine(fromLine) == visualLine(toLine)
3075
+ var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end
3076
+ var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start
3077
+ if (singleVLine) {
3078
+ if (leftEnd.top < rightStart.top - 2) {
3079
+ add(leftEnd.right, leftEnd.top, null, leftEnd.bottom)
3080
+ add(leftSide, rightStart.top, rightStart.left, rightStart.bottom)
3081
+ } else {
3082
+ add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom)
3083
+ }
3084
+ }
3085
+ if (leftEnd.bottom < rightStart.top)
3086
+ { add(leftSide, leftEnd.bottom, null, rightStart.top) }
3087
+ }
3088
+
3089
+ output.appendChild(fragment)
3090
+ }
3091
+
3092
+ // Cursor-blinking
3093
+ function restartBlink(cm) {
3094
+ if (!cm.state.focused) { return }
3095
+ var display = cm.display
3096
+ clearInterval(display.blinker)
3097
+ var on = true
3098
+ display.cursorDiv.style.visibility = ""
3099
+ if (cm.options.cursorBlinkRate > 0)
3100
+ { display.blinker = setInterval(function () { return display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; },
3101
+ cm.options.cursorBlinkRate) }
3102
+ else if (cm.options.cursorBlinkRate < 0)
3103
+ { display.cursorDiv.style.visibility = "hidden" }
3104
+ }
3105
+
3106
+ function ensureFocus(cm) {
3107
+ if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm) }
3108
+ }
3109
+
3110
+ function delayBlurEvent(cm) {
3111
+ cm.state.delayingBlurEvent = true
3112
+ setTimeout(function () { if (cm.state.delayingBlurEvent) {
3113
+ cm.state.delayingBlurEvent = false
3114
+ onBlur(cm)
3115
+ } }, 100)
3116
+ }
3117
+
3118
+ function onFocus(cm, e) {
3119
+ if (cm.state.delayingBlurEvent) { cm.state.delayingBlurEvent = false }
3120
+
3121
+ if (cm.options.readOnly == "nocursor") { return }
3122
+ if (!cm.state.focused) {
3123
+ signal(cm, "focus", cm, e)
3124
+ cm.state.focused = true
3125
+ addClass(cm.display.wrapper, "CodeMirror-focused")
3126
+ // This test prevents this from firing when a context
3127
+ // menu is closed (since the input reset would kill the
3128
+ // select-all detection hack)
3129
+ if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) {
3130
+ cm.display.input.reset()
3131
+ if (webkit) { setTimeout(function () { return cm.display.input.reset(true); }, 20) } // Issue #1730
3132
+ }
3133
+ cm.display.input.receivedFocus()
3134
+ }
3135
+ restartBlink(cm)
3136
+ }
3137
+ function onBlur(cm, e) {
3138
+ if (cm.state.delayingBlurEvent) { return }
3139
+
3140
+ if (cm.state.focused) {
3141
+ signal(cm, "blur", cm, e)
3142
+ cm.state.focused = false
3143
+ rmClass(cm.display.wrapper, "CodeMirror-focused")
3144
+ }
3145
+ clearInterval(cm.display.blinker)
3146
+ setTimeout(function () { if (!cm.state.focused) { cm.display.shift = false } }, 150)
3147
+ }
3148
+
3149
+ // Read the actual heights of the rendered lines, and update their
3150
+ // stored heights to match.
3151
+ function updateHeightsInViewport(cm) {
3152
+ var display = cm.display
3153
+ var prevBottom = display.lineDiv.offsetTop
3154
+ for (var i = 0; i < display.view.length; i++) {
3155
+ var cur = display.view[i], height = (void 0)
3156
+ if (cur.hidden) { continue }
3157
+ if (ie && ie_version < 8) {
3158
+ var bot = cur.node.offsetTop + cur.node.offsetHeight
3159
+ height = bot - prevBottom
3160
+ prevBottom = bot
3161
+ } else {
3162
+ var box = cur.node.getBoundingClientRect()
3163
+ height = box.bottom - box.top
3164
+ }
3165
+ var diff = cur.line.height - height
3166
+ if (height < 2) { height = textHeight(display) }
3167
+ if (diff > .001 || diff < -.001) {
3168
+ updateLineHeight(cur.line, height)
3169
+ updateWidgetHeight(cur.line)
3170
+ if (cur.rest) { for (var j = 0; j < cur.rest.length; j++)
3171
+ { updateWidgetHeight(cur.rest[j]) } }
3172
+ }
3173
+ }
3174
+ }
3175
+
3176
+ // Read and store the height of line widgets associated with the
3177
+ // given line.
3178
+ function updateWidgetHeight(line) {
3179
+ if (line.widgets) { for (var i = 0; i < line.widgets.length; ++i)
3180
+ { line.widgets[i].height = line.widgets[i].node.parentNode.offsetHeight } }
3181
+ }
3182
+
3183
+ // Compute the lines that are visible in a given viewport (defaults
3184
+ // the the current scroll position). viewport may contain top,
3185
+ // height, and ensure (see op.scrollToPos) properties.
3186
+ function visibleLines(display, doc, viewport) {
3187
+ var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop
3188
+ top = Math.floor(top - paddingTop(display))
3189
+ var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight
3190
+
3191
+ var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom)
3192
+ // Ensure is a {from: {line, ch}, to: {line, ch}} object, and
3193
+ // forces those lines into the viewport (if possible).
3194
+ if (viewport && viewport.ensure) {
3195
+ var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line
3196
+ if (ensureFrom < from) {
3197
+ from = ensureFrom
3198
+ to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight)
3199
+ } else if (Math.min(ensureTo, doc.lastLine()) >= to) {
3200
+ from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight)
3201
+ to = ensureTo
3202
+ }
3203
+ }
3204
+ return {from: from, to: Math.max(to, from + 1)}
3205
+ }
3206
+
3207
+ // Re-align line numbers and gutter marks to compensate for
3208
+ // horizontal scrolling.
3209
+ function alignHorizontally(cm) {
3210
+ var display = cm.display, view = display.view
3211
+ if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) { return }
3212
+ var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft
3213
+ var gutterW = display.gutters.offsetWidth, left = comp + "px"
3214
+ for (var i = 0; i < view.length; i++) { if (!view[i].hidden) {
3215
+ if (cm.options.fixedGutter) {
3216
+ if (view[i].gutter)
3217
+ { view[i].gutter.style.left = left }
3218
+ if (view[i].gutterBackground)
3219
+ { view[i].gutterBackground.style.left = left }
3220
+ }
3221
+ var align = view[i].alignable
3222
+ if (align) { for (var j = 0; j < align.length; j++)
3223
+ { align[j].style.left = left } }
3224
+ } }
3225
+ if (cm.options.fixedGutter)
3226
+ { display.gutters.style.left = (comp + gutterW) + "px" }
3227
+ }
3228
+
3229
+ // Used to ensure that the line number gutter is still the right
3230
+ // size for the current document size. Returns true when an update
3231
+ // is needed.
3232
+ function maybeUpdateLineNumberWidth(cm) {
3233
+ if (!cm.options.lineNumbers) { return false }
3234
+ var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display
3235
+ if (last.length != display.lineNumChars) {
3236
+ var test = display.measure.appendChild(elt("div", [elt("div", last)],
3237
+ "CodeMirror-linenumber CodeMirror-gutter-elt"))
3238
+ var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW
3239
+ display.lineGutter.style.width = ""
3240
+ display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1
3241
+ display.lineNumWidth = display.lineNumInnerWidth + padding
3242
+ display.lineNumChars = display.lineNumInnerWidth ? last.length : -1
3243
+ display.lineGutter.style.width = display.lineNumWidth + "px"
3244
+ updateGutterSpace(cm)
3245
+ return true
3246
+ }
3247
+ return false
3248
+ }
3249
+
3250
+ // SCROLLING THINGS INTO VIEW
3251
+
3252
+ // If an editor sits on the top or bottom of the window, partially
3253
+ // scrolled out of view, this ensures that the cursor is visible.
3254
+ function maybeScrollWindow(cm, rect) {
3255
+ if (signalDOMEvent(cm, "scrollCursorIntoView")) { return }
3256
+
3257
+ var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null
3258
+ if (rect.top + box.top < 0) { doScroll = true }
3259
+ else if (rect.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) { doScroll = false }
3260
+ if (doScroll != null && !phantom) {
3261
+ 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;"))
3262
+ cm.display.lineSpace.appendChild(scrollNode)
3263
+ scrollNode.scrollIntoView(doScroll)
3264
+ cm.display.lineSpace.removeChild(scrollNode)
3265
+ }
3266
+ }
3267
+
3268
+ // Scroll a given position into view (immediately), verifying that
3269
+ // it actually became visible (as line heights are accurately
3270
+ // measured, the position of something may 'drift' during drawing).
3271
+ function scrollPosIntoView(cm, pos, end, margin) {
3272
+ if (margin == null) { margin = 0 }
3273
+ var rect
3274
+ for (var limit = 0; limit < 5; limit++) {
3275
+ var changed = false
3276
+ var coords = cursorCoords(cm, pos)
3277
+ var endCoords = !end || end == pos ? coords : cursorCoords(cm, end)
3278
+ rect = {left: Math.min(coords.left, endCoords.left),
3279
+ top: Math.min(coords.top, endCoords.top) - margin,
3280
+ right: Math.max(coords.left, endCoords.left),
3281
+ bottom: Math.max(coords.bottom, endCoords.bottom) + margin}
3282
+ var scrollPos = calculateScrollPos(cm, rect)
3283
+ var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft
3284
+ if (scrollPos.scrollTop != null) {
3285
+ updateScrollTop(cm, scrollPos.scrollTop)
3286
+ if (Math.abs(cm.doc.scrollTop - startTop) > 1) { changed = true }
3287
+ }
3288
+ if (scrollPos.scrollLeft != null) {
3289
+ setScrollLeft(cm, scrollPos.scrollLeft)
3290
+ if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) { changed = true }
3291
+ }
3292
+ if (!changed) { break }
3293
+ }
3294
+ return rect
3295
+ }
3296
+
3297
+ // Scroll a given set of coordinates into view (immediately).
3298
+ function scrollIntoView(cm, rect) {
3299
+ var scrollPos = calculateScrollPos(cm, rect)
3300
+ if (scrollPos.scrollTop != null) { updateScrollTop(cm, scrollPos.scrollTop) }
3301
+ if (scrollPos.scrollLeft != null) { setScrollLeft(cm, scrollPos.scrollLeft) }
3302
+ }
3303
+
3304
+ // Calculate a new scroll position needed to scroll the given
3305
+ // rectangle into view. Returns an object with scrollTop and
3306
+ // scrollLeft properties. When these are undefined, the
3307
+ // vertical/horizontal position does not need to be adjusted.
3308
+ function calculateScrollPos(cm, rect) {
3309
+ var display = cm.display, snapMargin = textHeight(cm.display)
3310
+ if (rect.top < 0) { rect.top = 0 }
3311
+ var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop
3312
+ var screen = displayHeight(cm), result = {}
3313
+ if (rect.bottom - rect.top > screen) { rect.bottom = rect.top + screen }
3314
+ var docBottom = cm.doc.height + paddingVert(display)
3315
+ var atTop = rect.top < snapMargin, atBottom = rect.bottom > docBottom - snapMargin
3316
+ if (rect.top < screentop) {
3317
+ result.scrollTop = atTop ? 0 : rect.top
3318
+ } else if (rect.bottom > screentop + screen) {
3319
+ var newTop = Math.min(rect.top, (atBottom ? docBottom : rect.bottom) - screen)
3320
+ if (newTop != screentop) { result.scrollTop = newTop }
3321
+ }
3322
+
3323
+ var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft
3324
+ var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0)
3325
+ var tooWide = rect.right - rect.left > screenw
3326
+ if (tooWide) { rect.right = rect.left + screenw }
3327
+ if (rect.left < 10)
3328
+ { result.scrollLeft = 0 }
3329
+ else if (rect.left < screenleft)
3330
+ { result.scrollLeft = Math.max(0, rect.left - (tooWide ? 0 : 10)) }
3331
+ else if (rect.right > screenw + screenleft - 3)
3332
+ { result.scrollLeft = rect.right + (tooWide ? 0 : 10) - screenw }
3333
+ return result
3334
+ }
3335
+
3336
+ // Store a relative adjustment to the scroll position in the current
3337
+ // operation (to be applied when the operation finishes).
3338
+ function addToScrollTop(cm, top) {
3339
+ if (top == null) { return }
3340
+ resolveScrollToPos(cm)
3341
+ cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top
3342
+ }
3343
+
3344
+ // Make sure that at the end of the operation the current cursor is
3345
+ // shown.
3346
+ function ensureCursorVisible(cm) {
3347
+ resolveScrollToPos(cm)
3348
+ var cur = cm.getCursor(), from = cur, to = cur
3349
+ if (!cm.options.lineWrapping) {
3350
+ from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur
3351
+ to = Pos(cur.line, cur.ch + 1)
3352
+ }
3353
+ cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin}
3354
+ }
3355
+
3356
+ function scrollToCoords(cm, x, y) {
3357
+ if (x != null || y != null) { resolveScrollToPos(cm) }
3358
+ if (x != null) { cm.curOp.scrollLeft = x }
3359
+ if (y != null) { cm.curOp.scrollTop = y }
3360
+ }
3361
+
3362
+ function scrollToRange(cm, range) {
3363
+ resolveScrollToPos(cm)
3364
+ cm.curOp.scrollToPos = range
3365
+ }
3366
+
3367
+ // When an operation has its scrollToPos property set, and another
3368
+ // scroll action is applied before the end of the operation, this
3369
+ // 'simulates' scrolling that position into view in a cheap way, so
3370
+ // that the effect of intermediate scroll commands is not ignored.
3371
+ function resolveScrollToPos(cm) {
3372
+ var range = cm.curOp.scrollToPos
3373
+ if (range) {
3374
+ cm.curOp.scrollToPos = null
3375
+ var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to)
3376
+ scrollToCoordsRange(cm, from, to, range.margin)
3377
+ }
3378
+ }
3379
+
3380
+ function scrollToCoordsRange(cm, from, to, margin) {
3381
+ var sPos = calculateScrollPos(cm, {
3382
+ left: Math.min(from.left, to.left),
3383
+ top: Math.min(from.top, to.top) - margin,
3384
+ right: Math.max(from.right, to.right),
3385
+ bottom: Math.max(from.bottom, to.bottom) + margin
3386
+ })
3387
+ scrollToCoords(cm, sPos.scrollLeft, sPos.scrollTop)
3388
+ }
3389
+
3390
+ // Sync the scrollable area and scrollbars, ensure the viewport
3391
+ // covers the visible area.
3392
+ function updateScrollTop(cm, val) {
3393
+ if (Math.abs(cm.doc.scrollTop - val) < 2) { return }
3394
+ if (!gecko) { updateDisplaySimple(cm, {top: val}) }
3395
+ setScrollTop(cm, val, true)
3396
+ if (gecko) { updateDisplaySimple(cm) }
3397
+ startWorker(cm, 100)
3398
+ }
3399
+
3400
+ function setScrollTop(cm, val, forceScroll) {
3401
+ val = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val)
3402
+ if (cm.display.scroller.scrollTop == val && !forceScroll) { return }
3403
+ cm.doc.scrollTop = val
3404
+ cm.display.scrollbars.setScrollTop(val)
3405
+ if (cm.display.scroller.scrollTop != val) { cm.display.scroller.scrollTop = val }
3406
+ }
3407
+
3408
+ // Sync scroller and scrollbar, ensure the gutter elements are
3409
+ // aligned.
3410
+ function setScrollLeft(cm, val, isScroller, forceScroll) {
3411
+ val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth)
3412
+ if ((isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) && !forceScroll) { return }
3413
+ cm.doc.scrollLeft = val
3414
+ alignHorizontally(cm)
3415
+ if (cm.display.scroller.scrollLeft != val) { cm.display.scroller.scrollLeft = val }
3416
+ cm.display.scrollbars.setScrollLeft(val)
3417
+ }
3418
+
3419
+ // SCROLLBARS
3420
+
3421
+ // Prepare DOM reads needed to update the scrollbars. Done in one
3422
+ // shot to minimize update/measure roundtrips.
3423
+ function measureForScrollbars(cm) {
3424
+ var d = cm.display, gutterW = d.gutters.offsetWidth
3425
+ var docH = Math.round(cm.doc.height + paddingVert(cm.display))
3426
+ return {
3427
+ clientHeight: d.scroller.clientHeight,
3428
+ viewHeight: d.wrapper.clientHeight,
3429
+ scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth,
3430
+ viewWidth: d.wrapper.clientWidth,
3431
+ barLeft: cm.options.fixedGutter ? gutterW : 0,
3432
+ docHeight: docH,
3433
+ scrollHeight: docH + scrollGap(cm) + d.barHeight,
3434
+ nativeBarWidth: d.nativeBarWidth,
3435
+ gutterWidth: gutterW
3436
+ }
3437
+ }
3438
+
3439
+ var NativeScrollbars = function(place, scroll, cm) {
3440
+ this.cm = cm
3441
+ var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar")
3442
+ var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar")
3443
+ place(vert); place(horiz)
3444
+
3445
+ on(vert, "scroll", function () {
3446
+ if (vert.clientHeight) { scroll(vert.scrollTop, "vertical") }
3447
+ })
3448
+ on(horiz, "scroll", function () {
3449
+ if (horiz.clientWidth) { scroll(horiz.scrollLeft, "horizontal") }
3450
+ })
3451
+
3452
+ this.checkedZeroWidth = false
3453
+ // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
3454
+ if (ie && ie_version < 8) { this.horiz.style.minHeight = this.vert.style.minWidth = "18px" }
3455
+ };
3456
+
3457
+ NativeScrollbars.prototype.update = function (measure) {
3458
+ var needsH = measure.scrollWidth > measure.clientWidth + 1
3459
+ var needsV = measure.scrollHeight > measure.clientHeight + 1
3460
+ var sWidth = measure.nativeBarWidth
3461
+
3462
+ if (needsV) {
3463
+ this.vert.style.display = "block"
3464
+ this.vert.style.bottom = needsH ? sWidth + "px" : "0"
3465
+ var totalHeight = measure.viewHeight - (needsH ? sWidth : 0)
3466
+ // A bug in IE8 can cause this value to be negative, so guard it.
3467
+ this.vert.firstChild.style.height =
3468
+ Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px"
3469
+ } else {
3470
+ this.vert.style.display = ""
3471
+ this.vert.firstChild.style.height = "0"
3472
+ }
3473
+
3474
+ if (needsH) {
3475
+ this.horiz.style.display = "block"
3476
+ this.horiz.style.right = needsV ? sWidth + "px" : "0"
3477
+ this.horiz.style.left = measure.barLeft + "px"
3478
+ var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0)
3479
+ this.horiz.firstChild.style.width =
3480
+ Math.max(0, measure.scrollWidth - measure.clientWidth + totalWidth) + "px"
3481
+ } else {
3482
+ this.horiz.style.display = ""
3483
+ this.horiz.firstChild.style.width = "0"
3484
+ }
3485
+
3486
+ if (!this.checkedZeroWidth && measure.clientHeight > 0) {
3487
+ if (sWidth == 0) { this.zeroWidthHack() }
3488
+ this.checkedZeroWidth = true
3489
+ }
3490
+
3491
+ return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0}
3492
+ };
3493
+
3494
+ NativeScrollbars.prototype.setScrollLeft = function (pos) {
3495
+ if (this.horiz.scrollLeft != pos) { this.horiz.scrollLeft = pos }
3496
+ if (this.disableHoriz) { this.enableZeroWidthBar(this.horiz, this.disableHoriz, "horiz") }
3497
+ };
3498
+
3499
+ NativeScrollbars.prototype.setScrollTop = function (pos) {
3500
+ if (this.vert.scrollTop != pos) { this.vert.scrollTop = pos }
3501
+ if (this.disableVert) { this.enableZeroWidthBar(this.vert, this.disableVert, "vert") }
3502
+ };
3503
+
3504
+ NativeScrollbars.prototype.zeroWidthHack = function () {
3505
+ var w = mac && !mac_geMountainLion ? "12px" : "18px"
3506
+ this.horiz.style.height = this.vert.style.width = w
3507
+ this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none"
3508
+ this.disableHoriz = new Delayed
3509
+ this.disableVert = new Delayed
3510
+ };
3511
+
3512
+ NativeScrollbars.prototype.enableZeroWidthBar = function (bar, delay, type) {
3513
+ bar.style.pointerEvents = "auto"
3514
+ function maybeDisable() {
3515
+ // To find out whether the scrollbar is still visible, we
3516
+ // check whether the element under the pixel in the bottom
3517
+ // right corner of the scrollbar box is the scrollbar box
3518
+ // itself (when the bar is still visible) or its filler child
3519
+ // (when the bar is hidden). If it is still visible, we keep
3520
+ // it enabled, if it's hidden, we disable pointer events.
3521
+ var box = bar.getBoundingClientRect()
3522
+ var elt = type == "vert" ? document.elementFromPoint(box.right - 1, (box.top + box.bottom) / 2)
3523
+ : document.elementFromPoint((box.right + box.left) / 2, box.bottom - 1)
3524
+ if (elt != bar) { bar.style.pointerEvents = "none" }
3525
+ else { delay.set(1000, maybeDisable) }
3526
+ }
3527
+ delay.set(1000, maybeDisable)
3528
+ };
3529
+
3530
+ NativeScrollbars.prototype.clear = function () {
3531
+ var parent = this.horiz.parentNode
3532
+ parent.removeChild(this.horiz)
3533
+ parent.removeChild(this.vert)
3534
+ };
3535
+
3536
+ var NullScrollbars = function () {};
3537
+
3538
+ NullScrollbars.prototype.update = function () { return {bottom: 0, right: 0} };
3539
+ NullScrollbars.prototype.setScrollLeft = function () {};
3540
+ NullScrollbars.prototype.setScrollTop = function () {};
3541
+ NullScrollbars.prototype.clear = function () {};
3542
+
3543
+ function updateScrollbars(cm, measure) {
3544
+ if (!measure) { measure = measureForScrollbars(cm) }
3545
+ var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight
3546
+ updateScrollbarsInner(cm, measure)
3547
+ for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) {
3548
+ if (startWidth != cm.display.barWidth && cm.options.lineWrapping)
3549
+ { updateHeightsInViewport(cm) }
3550
+ updateScrollbarsInner(cm, measureForScrollbars(cm))
3551
+ startWidth = cm.display.barWidth; startHeight = cm.display.barHeight
3552
+ }
3553
+ }
3554
+
3555
+ // Re-synchronize the fake scrollbars with the actual size of the
3556
+ // content.
3557
+ function updateScrollbarsInner(cm, measure) {
3558
+ var d = cm.display
3559
+ var sizes = d.scrollbars.update(measure)
3560
+
3561
+ d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px"
3562
+ d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px"
3563
+ d.heightForcer.style.borderBottom = sizes.bottom + "px solid transparent"
3564
+
3565
+ if (sizes.right && sizes.bottom) {
3566
+ d.scrollbarFiller.style.display = "block"
3567
+ d.scrollbarFiller.style.height = sizes.bottom + "px"
3568
+ d.scrollbarFiller.style.width = sizes.right + "px"
3569
+ } else { d.scrollbarFiller.style.display = "" }
3570
+ if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
3571
+ d.gutterFiller.style.display = "block"
3572
+ d.gutterFiller.style.height = sizes.bottom + "px"
3573
+ d.gutterFiller.style.width = measure.gutterWidth + "px"
3574
+ } else { d.gutterFiller.style.display = "" }
3575
+ }
3576
+
3577
+ var scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars}
3578
+
3579
+ function initScrollbars(cm) {
3580
+ if (cm.display.scrollbars) {
3581
+ cm.display.scrollbars.clear()
3582
+ if (cm.display.scrollbars.addClass)
3583
+ { rmClass(cm.display.wrapper, cm.display.scrollbars.addClass) }
3584
+ }
3585
+
3586
+ cm.display.scrollbars = new scrollbarModel[cm.options.scrollbarStyle](function (node) {
3587
+ cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller)
3588
+ // Prevent clicks in the scrollbars from killing focus
3589
+ on(node, "mousedown", function () {
3590
+ if (cm.state.focused) { setTimeout(function () { return cm.display.input.focus(); }, 0) }
3591
+ })
3592
+ node.setAttribute("cm-not-content", "true")
3593
+ }, function (pos, axis) {
3594
+ if (axis == "horizontal") { setScrollLeft(cm, pos) }
3595
+ else { updateScrollTop(cm, pos) }
3596
+ }, cm)
3597
+ if (cm.display.scrollbars.addClass)
3598
+ { addClass(cm.display.wrapper, cm.display.scrollbars.addClass) }
3599
+ }
3600
+
3601
+ // Operations are used to wrap a series of changes to the editor
3602
+ // state in such a way that each change won't have to update the
3603
+ // cursor and display (which would be awkward, slow, and
3604
+ // error-prone). Instead, display updates are batched and then all
3605
+ // combined and executed at once.
3606
+
3607
+ var nextOpId = 0
3608
+ // Start a new operation.
3609
+ function startOperation(cm) {
3610
+ cm.curOp = {
3611
+ cm: cm,
3612
+ viewChanged: false, // Flag that indicates that lines might need to be redrawn
3613
+ startHeight: cm.doc.height, // Used to detect need to update scrollbar
3614
+ forceUpdate: false, // Used to force a redraw
3615
+ updateInput: null, // Whether to reset the input textarea
3616
+ typing: false, // Whether this reset should be careful to leave existing text (for compositing)
3617
+ changeObjs: null, // Accumulated changes, for firing change events
3618
+ cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on
3619
+ cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already
3620
+ selectionChanged: false, // Whether the selection needs to be redrawn
3621
+ updateMaxLine: false, // Set when the widest line needs to be determined anew
3622
+ scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet
3623
+ scrollToPos: null, // Used to scroll to a specific position
3624
+ focus: false,
3625
+ id: ++nextOpId // Unique ID
3626
+ }
3627
+ pushOperation(cm.curOp)
3628
+ }
3629
+
3630
+ // Finish an operation, updating the display and signalling delayed events
3631
+ function endOperation(cm) {
3632
+ var op = cm.curOp
3633
+ finishOperation(op, function (group) {
3634
+ for (var i = 0; i < group.ops.length; i++)
3635
+ { group.ops[i].cm.curOp = null }
3636
+ endOperations(group)
3637
+ })
3638
+ }
3639
+
3640
+ // The DOM updates done when an operation finishes are batched so
3641
+ // that the minimum number of relayouts are required.
3642
+ function endOperations(group) {
3643
+ var ops = group.ops
3644
+ for (var i = 0; i < ops.length; i++) // Read DOM
3645
+ { endOperation_R1(ops[i]) }
3646
+ for (var i$1 = 0; i$1 < ops.length; i$1++) // Write DOM (maybe)
3647
+ { endOperation_W1(ops[i$1]) }
3648
+ for (var i$2 = 0; i$2 < ops.length; i$2++) // Read DOM
3649
+ { endOperation_R2(ops[i$2]) }
3650
+ for (var i$3 = 0; i$3 < ops.length; i$3++) // Write DOM (maybe)
3651
+ { endOperation_W2(ops[i$3]) }
3652
+ for (var i$4 = 0; i$4 < ops.length; i$4++) // Read DOM
3653
+ { endOperation_finish(ops[i$4]) }
3654
+ }
3655
+
3656
+ function endOperation_R1(op) {
3657
+ var cm = op.cm, display = cm.display
3658
+ maybeClipScrollbars(cm)
3659
+ if (op.updateMaxLine) { findMaxLine(cm) }
3660
+
3661
+ op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null ||
3662
+ op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom ||
3663
+ op.scrollToPos.to.line >= display.viewTo) ||
3664
+ display.maxLineChanged && cm.options.lineWrapping
3665
+ op.update = op.mustUpdate &&
3666
+ new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate)
3667
+ }
3668
+
3669
+ function endOperation_W1(op) {
3670
+ op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update)
3671
+ }
3672
+
3673
+ function endOperation_R2(op) {
3674
+ var cm = op.cm, display = cm.display
3675
+ if (op.updatedDisplay) { updateHeightsInViewport(cm) }
3676
+
3677
+ op.barMeasure = measureForScrollbars(cm)
3678
+
3679
+ // If the max line changed since it was last measured, measure it,
3680
+ // and ensure the document's width matches it.
3681
+ // updateDisplay_W2 will use these properties to do the actual resizing
3682
+ if (display.maxLineChanged && !cm.options.lineWrapping) {
3683
+ op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3
3684
+ cm.display.sizerWidth = op.adjustWidthTo
3685
+ op.barMeasure.scrollWidth =
3686
+ Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth)
3687
+ op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm))
3688
+ }
3689
+
3690
+ if (op.updatedDisplay || op.selectionChanged)
3691
+ { op.preparedSelection = display.input.prepareSelection(op.focus) }
3692
+ }
3693
+
3694
+ function endOperation_W2(op) {
3695
+ var cm = op.cm
3696
+
3697
+ if (op.adjustWidthTo != null) {
3698
+ cm.display.sizer.style.minWidth = op.adjustWidthTo + "px"
3699
+ if (op.maxScrollLeft < cm.doc.scrollLeft)
3700
+ { setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true) }
3701
+ cm.display.maxLineChanged = false
3702
+ }
3703
+
3704
+ var takeFocus = op.focus && op.focus == activeElt() && (!document.hasFocus || document.hasFocus())
3705
+ if (op.preparedSelection)
3706
+ { cm.display.input.showSelection(op.preparedSelection, takeFocus) }
3707
+ if (op.updatedDisplay || op.startHeight != cm.doc.height)
3708
+ { updateScrollbars(cm, op.barMeasure) }
3709
+ if (op.updatedDisplay)
3710
+ { setDocumentHeight(cm, op.barMeasure) }
3711
+
3712
+ if (op.selectionChanged) { restartBlink(cm) }
3713
+
3714
+ if (cm.state.focused && op.updateInput)
3715
+ { cm.display.input.reset(op.typing) }
3716
+ if (takeFocus) { ensureFocus(op.cm) }
3717
+ }
3718
+
3719
+ function endOperation_finish(op) {
3720
+ var cm = op.cm, display = cm.display, doc = cm.doc
3721
+
3722
+ if (op.updatedDisplay) { postUpdateDisplay(cm, op.update) }
3723
+
3724
+ // Abort mouse wheel delta measurement, when scrolling explicitly
3725
+ if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos))
3726
+ { display.wheelStartX = display.wheelStartY = null }
3727
+
3728
+ // Propagate the scroll position to the actual DOM scroller
3729
+ if (op.scrollTop != null) { setScrollTop(cm, op.scrollTop, op.forceScroll) }
3730
+
3731
+ if (op.scrollLeft != null) { setScrollLeft(cm, op.scrollLeft, true, true) }
3732
+ // If we need to scroll a specific position into view, do so.
3733
+ if (op.scrollToPos) {
3734
+ var rect = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from),
3735
+ clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin)
3736
+ maybeScrollWindow(cm, rect)
3737
+ }
3738
+
3739
+ // Fire events for markers that are hidden/unidden by editing or
3740
+ // undoing
3741
+ var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers
3742
+ if (hidden) { for (var i = 0; i < hidden.length; ++i)
3743
+ { if (!hidden[i].lines.length) { signal(hidden[i], "hide") } } }
3744
+ if (unhidden) { for (var i$1 = 0; i$1 < unhidden.length; ++i$1)
3745
+ { if (unhidden[i$1].lines.length) { signal(unhidden[i$1], "unhide") } } }
3746
+
3747
+ if (display.wrapper.offsetHeight)
3748
+ { doc.scrollTop = cm.display.scroller.scrollTop }
3749
+
3750
+ // Fire change events, and delayed event handlers
3751
+ if (op.changeObjs)
3752
+ { signal(cm, "changes", cm, op.changeObjs) }
3753
+ if (op.update)
3754
+ { op.update.finish() }
3755
+ }
3756
+
3757
+ // Run the given function in an operation
3758
+ function runInOp(cm, f) {
3759
+ if (cm.curOp) { return f() }
3760
+ startOperation(cm)
3761
+ try { return f() }
3762
+ finally { endOperation(cm) }
3763
+ }
3764
+ // Wraps a function in an operation. Returns the wrapped function.
3765
+ function operation(cm, f) {
3766
+ return function() {
3767
+ if (cm.curOp) { return f.apply(cm, arguments) }
3768
+ startOperation(cm)
3769
+ try { return f.apply(cm, arguments) }
3770
+ finally { endOperation(cm) }
3771
+ }
3772
+ }
3773
+ // Used to add methods to editor and doc instances, wrapping them in
3774
+ // operations.
3775
+ function methodOp(f) {
3776
+ return function() {
3777
+ if (this.curOp) { return f.apply(this, arguments) }
3778
+ startOperation(this)
3779
+ try { return f.apply(this, arguments) }
3780
+ finally { endOperation(this) }
3781
+ }
3782
+ }
3783
+ function docMethodOp(f) {
3784
+ return function() {
3785
+ var cm = this.cm
3786
+ if (!cm || cm.curOp) { return f.apply(this, arguments) }
3787
+ startOperation(cm)
3788
+ try { return f.apply(this, arguments) }
3789
+ finally { endOperation(cm) }
3790
+ }
3791
+ }
3792
+
3793
+ // Updates the display.view data structure for a given change to the
3794
+ // document. From and to are in pre-change coordinates. Lendiff is
3795
+ // the amount of lines added or subtracted by the change. This is
3796
+ // used for changes that span multiple lines, or change the way
3797
+ // lines are divided into visual lines. regLineChange (below)
3798
+ // registers single-line changes.
3799
+ function regChange(cm, from, to, lendiff) {
3800
+ if (from == null) { from = cm.doc.first }
3801
+ if (to == null) { to = cm.doc.first + cm.doc.size }
3802
+ if (!lendiff) { lendiff = 0 }
3803
+
3804
+ var display = cm.display
3805
+ if (lendiff && to < display.viewTo &&
3806
+ (display.updateLineNumbers == null || display.updateLineNumbers > from))
3807
+ { display.updateLineNumbers = from }
3808
+
3809
+ cm.curOp.viewChanged = true
3810
+
3811
+ if (from >= display.viewTo) { // Change after
3812
+ if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo)
3813
+ { resetView(cm) }
3814
+ } else if (to <= display.viewFrom) { // Change before
3815
+ if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) {
3816
+ resetView(cm)
3817
+ } else {
3818
+ display.viewFrom += lendiff
3819
+ display.viewTo += lendiff
3820
+ }
3821
+ } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap
3822
+ resetView(cm)
3823
+ } else if (from <= display.viewFrom) { // Top overlap
3824
+ var cut = viewCuttingPoint(cm, to, to + lendiff, 1)
3825
+ if (cut) {
3826
+ display.view = display.view.slice(cut.index)
3827
+ display.viewFrom = cut.lineN
3828
+ display.viewTo += lendiff
3829
+ } else {
3830
+ resetView(cm)
3831
+ }
3832
+ } else if (to >= display.viewTo) { // Bottom overlap
3833
+ var cut$1 = viewCuttingPoint(cm, from, from, -1)
3834
+ if (cut$1) {
3835
+ display.view = display.view.slice(0, cut$1.index)
3836
+ display.viewTo = cut$1.lineN
3837
+ } else {
3838
+ resetView(cm)
3839
+ }
3840
+ } else { // Gap in the middle
3841
+ var cutTop = viewCuttingPoint(cm, from, from, -1)
3842
+ var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1)
3843
+ if (cutTop && cutBot) {
3844
+ display.view = display.view.slice(0, cutTop.index)
3845
+ .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN))
3846
+ .concat(display.view.slice(cutBot.index))
3847
+ display.viewTo += lendiff
3848
+ } else {
3849
+ resetView(cm)
3850
+ }
3851
+ }
3852
+
3853
+ var ext = display.externalMeasured
3854
+ if (ext) {
3855
+ if (to < ext.lineN)
3856
+ { ext.lineN += lendiff }
3857
+ else if (from < ext.lineN + ext.size)
3858
+ { display.externalMeasured = null }
3859
+ }
3860
+ }
3861
+
3862
+ // Register a change to a single line. Type must be one of "text",
3863
+ // "gutter", "class", "widget"
3864
+ function regLineChange(cm, line, type) {
3865
+ cm.curOp.viewChanged = true
3866
+ var display = cm.display, ext = cm.display.externalMeasured
3867
+ if (ext && line >= ext.lineN && line < ext.lineN + ext.size)
3868
+ { display.externalMeasured = null }
3869
+
3870
+ if (line < display.viewFrom || line >= display.viewTo) { return }
3871
+ var lineView = display.view[findViewIndex(cm, line)]
3872
+ if (lineView.node == null) { return }
3873
+ var arr = lineView.changes || (lineView.changes = [])
3874
+ if (indexOf(arr, type) == -1) { arr.push(type) }
3875
+ }
3876
+
3877
+ // Clear the view.
3878
+ function resetView(cm) {
3879
+ cm.display.viewFrom = cm.display.viewTo = cm.doc.first
3880
+ cm.display.view = []
3881
+ cm.display.viewOffset = 0
3882
+ }
3883
+
3884
+ function viewCuttingPoint(cm, oldN, newN, dir) {
3885
+ var index = findViewIndex(cm, oldN), diff, view = cm.display.view
3886
+ if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size)
3887
+ { return {index: index, lineN: newN} }
3888
+ var n = cm.display.viewFrom
3889
+ for (var i = 0; i < index; i++)
3890
+ { n += view[i].size }
3891
+ if (n != oldN) {
3892
+ if (dir > 0) {
3893
+ if (index == view.length - 1) { return null }
3894
+ diff = (n + view[index].size) - oldN
3895
+ index++
3896
+ } else {
3897
+ diff = n - oldN
3898
+ }
3899
+ oldN += diff; newN += diff
3900
+ }
3901
+ while (visualLineNo(cm.doc, newN) != newN) {
3902
+ if (index == (dir < 0 ? 0 : view.length - 1)) { return null }
3903
+ newN += dir * view[index - (dir < 0 ? 1 : 0)].size
3904
+ index += dir
3905
+ }
3906
+ return {index: index, lineN: newN}
3907
+ }
3908
+
3909
+ // Force the view to cover a given range, adding empty view element
3910
+ // or clipping off existing ones as needed.
3911
+ function adjustView(cm, from, to) {
3912
+ var display = cm.display, view = display.view
3913
+ if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) {
3914
+ display.view = buildViewArray(cm, from, to)
3915
+ display.viewFrom = from
3916
+ } else {
3917
+ if (display.viewFrom > from)
3918
+ { display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view) }
3919
+ else if (display.viewFrom < from)
3920
+ { display.view = display.view.slice(findViewIndex(cm, from)) }
3921
+ display.viewFrom = from
3922
+ if (display.viewTo < to)
3923
+ { display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)) }
3924
+ else if (display.viewTo > to)
3925
+ { display.view = display.view.slice(0, findViewIndex(cm, to)) }
3926
+ }
3927
+ display.viewTo = to
3928
+ }
3929
+
3930
+ // Count the number of lines in the view whose DOM representation is
3931
+ // out of date (or nonexistent).
3932
+ function countDirtyView(cm) {
3933
+ var view = cm.display.view, dirty = 0
3934
+ for (var i = 0; i < view.length; i++) {
3935
+ var lineView = view[i]
3936
+ if (!lineView.hidden && (!lineView.node || lineView.changes)) { ++dirty }
3937
+ }
3938
+ return dirty
3939
+ }
3940
+
3941
+ // HIGHLIGHT WORKER
3942
+
3943
+ function startWorker(cm, time) {
3944
+ if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo)
3945
+ { cm.state.highlight.set(time, bind(highlightWorker, cm)) }
3946
+ }
3947
+
3948
+ function highlightWorker(cm) {
3949
+ var doc = cm.doc
3950
+ if (doc.frontier < doc.first) { doc.frontier = doc.first }
3951
+ if (doc.frontier >= cm.display.viewTo) { return }
3952
+ var end = +new Date + cm.options.workTime
3953
+ var state = copyState(doc.mode, getStateBefore(cm, doc.frontier))
3954
+ var changedLines = []
3955
+
3956
+ doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function (line) {
3957
+ if (doc.frontier >= cm.display.viewFrom) { // Visible
3958
+ var oldStyles = line.styles, tooLong = line.text.length > cm.options.maxHighlightLength
3959
+ var highlighted = highlightLine(cm, line, tooLong ? copyState(doc.mode, state) : state, true)
3960
+ line.styles = highlighted.styles
3961
+ var oldCls = line.styleClasses, newCls = highlighted.classes
3962
+ if (newCls) { line.styleClasses = newCls }
3963
+ else if (oldCls) { line.styleClasses = null }
3964
+ var ischange = !oldStyles || oldStyles.length != line.styles.length ||
3965
+ oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass)
3966
+ for (var i = 0; !ischange && i < oldStyles.length; ++i) { ischange = oldStyles[i] != line.styles[i] }
3967
+ if (ischange) { changedLines.push(doc.frontier) }
3968
+ line.stateAfter = tooLong ? state : copyState(doc.mode, state)
3969
+ } else {
3970
+ if (line.text.length <= cm.options.maxHighlightLength)
3971
+ { processLine(cm, line.text, state) }
3972
+ line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null
3973
+ }
3974
+ ++doc.frontier
3975
+ if (+new Date > end) {
3976
+ startWorker(cm, cm.options.workDelay)
3977
+ return true
3978
+ }
3979
+ })
3980
+ if (changedLines.length) { runInOp(cm, function () {
3981
+ for (var i = 0; i < changedLines.length; i++)
3982
+ { regLineChange(cm, changedLines[i], "text") }
3983
+ }) }
3984
+ }
3985
+
3986
+ // DISPLAY DRAWING
3987
+
3988
+ var DisplayUpdate = function(cm, viewport, force) {
3989
+ var display = cm.display
3990
+
3991
+ this.viewport = viewport
3992
+ // Store some values that we'll need later (but don't want to force a relayout for)
3993
+ this.visible = visibleLines(display, cm.doc, viewport)
3994
+ this.editorIsHidden = !display.wrapper.offsetWidth
3995
+ this.wrapperHeight = display.wrapper.clientHeight
3996
+ this.wrapperWidth = display.wrapper.clientWidth
3997
+ this.oldDisplayWidth = displayWidth(cm)
3998
+ this.force = force
3999
+ this.dims = getDimensions(cm)
4000
+ this.events = []
4001
+ };
4002
+
4003
+ DisplayUpdate.prototype.signal = function (emitter, type) {
4004
+ if (hasHandler(emitter, type))
4005
+ { this.events.push(arguments) }
4006
+ };
4007
+ DisplayUpdate.prototype.finish = function () {
4008
+ var this$1 = this;
4009
+
4010
+ for (var i = 0; i < this.events.length; i++)
4011
+ { signal.apply(null, this$1.events[i]) }
4012
+ };
4013
+
4014
+ function maybeClipScrollbars(cm) {
4015
+ var display = cm.display
4016
+ if (!display.scrollbarsClipped && display.scroller.offsetWidth) {
4017
+ display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth
4018
+ display.heightForcer.style.height = scrollGap(cm) + "px"
4019
+ display.sizer.style.marginBottom = -display.nativeBarWidth + "px"
4020
+ display.sizer.style.borderRightWidth = scrollGap(cm) + "px"
4021
+ display.scrollbarsClipped = true
4022
+ }
4023
+ }
4024
+
4025
+ function selectionSnapshot(cm) {
4026
+ if (cm.hasFocus()) { return null }
4027
+ var active = activeElt()
4028
+ if (!active || !contains(cm.display.lineDiv, active)) { return null }
4029
+ var result = {activeElt: active}
4030
+ if (window.getSelection) {
4031
+ var sel = window.getSelection()
4032
+ if (sel.anchorNode && sel.extend && contains(cm.display.lineDiv, sel.anchorNode)) {
4033
+ result.anchorNode = sel.anchorNode
4034
+ result.anchorOffset = sel.anchorOffset
4035
+ result.focusNode = sel.focusNode
4036
+ result.focusOffset = sel.focusOffset
4037
+ }
4038
+ }
4039
+ return result
4040
+ }
4041
+
4042
+ function restoreSelection(snapshot) {
4043
+ if (!snapshot || !snapshot.activeElt || snapshot.activeElt == activeElt()) { return }
4044
+ snapshot.activeElt.focus()
4045
+ if (snapshot.anchorNode && contains(document.body, snapshot.anchorNode) && contains(document.body, snapshot.focusNode)) {
4046
+ var sel = window.getSelection(), range = document.createRange()
4047
+ range.setEnd(snapshot.anchorNode, snapshot.anchorOffset)
4048
+ range.collapse(false)
4049
+ sel.removeAllRanges()
4050
+ sel.addRange(range)
4051
+ sel.extend(snapshot.focusNode, snapshot.focusOffset)
4052
+ }
4053
+ }
4054
+
4055
+ // Does the actual updating of the line display. Bails out
4056
+ // (returning false) when there is nothing to be done and forced is
4057
+ // false.
4058
+ function updateDisplayIfNeeded(cm, update) {
4059
+ var display = cm.display, doc = cm.doc
4060
+
4061
+ if (update.editorIsHidden) {
4062
+ resetView(cm)
4063
+ return false
4064
+ }
4065
+
4066
+ // Bail out if the visible area is already rendered and nothing changed.
4067
+ if (!update.force &&
4068
+ update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo &&
4069
+ (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) &&
4070
+ display.renderedView == display.view && countDirtyView(cm) == 0)
4071
+ { return false }
4072
+
4073
+ if (maybeUpdateLineNumberWidth(cm)) {
4074
+ resetView(cm)
4075
+ update.dims = getDimensions(cm)
4076
+ }
4077
+
4078
+ // Compute a suitable new viewport (from & to)
4079
+ var end = doc.first + doc.size
4080
+ var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first)
4081
+ var to = Math.min(end, update.visible.to + cm.options.viewportMargin)
4082
+ if (display.viewFrom < from && from - display.viewFrom < 20) { from = Math.max(doc.first, display.viewFrom) }
4083
+ if (display.viewTo > to && display.viewTo - to < 20) { to = Math.min(end, display.viewTo) }
4084
+ if (sawCollapsedSpans) {
4085
+ from = visualLineNo(cm.doc, from)
4086
+ to = visualLineEndNo(cm.doc, to)
4087
+ }
4088
+
4089
+ var different = from != display.viewFrom || to != display.viewTo ||
4090
+ display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth
4091
+ adjustView(cm, from, to)
4092
+
4093
+ display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom))
4094
+ // Position the mover div to align with the current scroll position
4095
+ cm.display.mover.style.top = display.viewOffset + "px"
4096
+
4097
+ var toUpdate = countDirtyView(cm)
4098
+ if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view &&
4099
+ (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo))
4100
+ { return false }
4101
+
4102
+ // For big changes, we hide the enclosing element during the
4103
+ // update, since that speeds up the operations on most browsers.
4104
+ var selSnapshot = selectionSnapshot(cm)
4105
+ if (toUpdate > 4) { display.lineDiv.style.display = "none" }
4106
+ patchDisplay(cm, display.updateLineNumbers, update.dims)
4107
+ if (toUpdate > 4) { display.lineDiv.style.display = "" }
4108
+ display.renderedView = display.view
4109
+ // There might have been a widget with a focused element that got
4110
+ // hidden or updated, if so re-focus it.
4111
+ restoreSelection(selSnapshot)
4112
+
4113
+ // Prevent selection and cursors from interfering with the scroll
4114
+ // width and height.
4115
+ removeChildren(display.cursorDiv)
4116
+ removeChildren(display.selectionDiv)
4117
+ display.gutters.style.height = display.sizer.style.minHeight = 0
4118
+
4119
+ if (different) {
4120
+ display.lastWrapHeight = update.wrapperHeight
4121
+ display.lastWrapWidth = update.wrapperWidth
4122
+ startWorker(cm, 400)
4123
+ }
4124
+
4125
+ display.updateLineNumbers = null
4126
+
4127
+ return true
4128
+ }
4129
+
4130
+ function postUpdateDisplay(cm, update) {
4131
+ var viewport = update.viewport
4132
+
4133
+ for (var first = true;; first = false) {
4134
+ if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) {
4135
+ // Clip forced viewport to actual scrollable area.
4136
+ if (viewport && viewport.top != null)
4137
+ { viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)} }
4138
+ // Updated line heights might result in the drawn area not
4139
+ // actually covering the viewport. Keep looping until it does.
4140
+ update.visible = visibleLines(cm.display, cm.doc, viewport)
4141
+ if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)
4142
+ { break }
4143
+ }
4144
+ if (!updateDisplayIfNeeded(cm, update)) { break }
4145
+ updateHeightsInViewport(cm)
4146
+ var barMeasure = measureForScrollbars(cm)
4147
+ updateSelection(cm)
4148
+ updateScrollbars(cm, barMeasure)
4149
+ setDocumentHeight(cm, barMeasure)
4150
+ }
4151
+
4152
+ update.signal(cm, "update", cm)
4153
+ if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) {
4154
+ update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo)
4155
+ cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo
4156
+ }
4157
+ }
4158
+
4159
+ function updateDisplaySimple(cm, viewport) {
4160
+ var update = new DisplayUpdate(cm, viewport)
4161
+ if (updateDisplayIfNeeded(cm, update)) {
4162
+ updateHeightsInViewport(cm)
4163
+ postUpdateDisplay(cm, update)
4164
+ var barMeasure = measureForScrollbars(cm)
4165
+ updateSelection(cm)
4166
+ updateScrollbars(cm, barMeasure)
4167
+ setDocumentHeight(cm, barMeasure)
4168
+ update.finish()
4169
+ }
4170
+ }
4171
+
4172
+ // Sync the actual display DOM structure with display.view, removing
4173
+ // nodes for lines that are no longer in view, and creating the ones
4174
+ // that are not there yet, and updating the ones that are out of
4175
+ // date.
4176
+ function patchDisplay(cm, updateNumbersFrom, dims) {
4177
+ var display = cm.display, lineNumbers = cm.options.lineNumbers
4178
+ var container = display.lineDiv, cur = container.firstChild
4179
+
4180
+ function rm(node) {
4181
+ var next = node.nextSibling
4182
+ // Works around a throw-scroll bug in OS X Webkit
4183
+ if (webkit && mac && cm.display.currentWheelTarget == node)
4184
+ { node.style.display = "none" }
4185
+ else
4186
+ { node.parentNode.removeChild(node) }
4187
+ return next
4188
+ }
4189
+
4190
+ var view = display.view, lineN = display.viewFrom
4191
+ // Loop over the elements in the view, syncing cur (the DOM nodes
4192
+ // in display.lineDiv) with the view as we go.
4193
+ for (var i = 0; i < view.length; i++) {
4194
+ var lineView = view[i]
4195
+ if (lineView.hidden) {
4196
+ } else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet
4197
+ var node = buildLineElement(cm, lineView, lineN, dims)
4198
+ container.insertBefore(node, cur)
4199
+ } else { // Already drawn
4200
+ while (cur != lineView.node) { cur = rm(cur) }
4201
+ var updateNumber = lineNumbers && updateNumbersFrom != null &&
4202
+ updateNumbersFrom <= lineN && lineView.lineNumber
4203
+ if (lineView.changes) {
4204
+ if (indexOf(lineView.changes, "gutter") > -1) { updateNumber = false }
4205
+ updateLineForChanges(cm, lineView, lineN, dims)
4206
+ }
4207
+ if (updateNumber) {
4208
+ removeChildren(lineView.lineNumber)
4209
+ lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN)))
4210
+ }
4211
+ cur = lineView.node.nextSibling
4212
+ }
4213
+ lineN += lineView.size
4214
+ }
4215
+ while (cur) { cur = rm(cur) }
4216
+ }
4217
+
4218
+ function updateGutterSpace(cm) {
4219
+ var width = cm.display.gutters.offsetWidth
4220
+ cm.display.sizer.style.marginLeft = width + "px"
4221
+ }
4222
+
4223
+ function setDocumentHeight(cm, measure) {
4224
+ cm.display.sizer.style.minHeight = measure.docHeight + "px"
4225
+ cm.display.heightForcer.style.top = measure.docHeight + "px"
4226
+ cm.display.gutters.style.height = (measure.docHeight + cm.display.barHeight + scrollGap(cm)) + "px"
4227
+ }
4228
+
4229
+ // Rebuild the gutter elements, ensure the margin to the left of the
4230
+ // code matches their width.
4231
+ function updateGutters(cm) {
4232
+ var gutters = cm.display.gutters, specs = cm.options.gutters
4233
+ removeChildren(gutters)
4234
+ var i = 0
4235
+ for (; i < specs.length; ++i) {
4236
+ var gutterClass = specs[i]
4237
+ var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass))
4238
+ if (gutterClass == "CodeMirror-linenumbers") {
4239
+ cm.display.lineGutter = gElt
4240
+ gElt.style.width = (cm.display.lineNumWidth || 1) + "px"
4241
+ }
4242
+ }
4243
+ gutters.style.display = i ? "" : "none"
4244
+ updateGutterSpace(cm)
4245
+ }
4246
+
4247
+ // Make sure the gutters options contains the element
4248
+ // "CodeMirror-linenumbers" when the lineNumbers option is true.
4249
+ function setGuttersForLineNumbers(options) {
4250
+ var found = indexOf(options.gutters, "CodeMirror-linenumbers")
4251
+ if (found == -1 && options.lineNumbers) {
4252
+ options.gutters = options.gutters.concat(["CodeMirror-linenumbers"])
4253
+ } else if (found > -1 && !options.lineNumbers) {
4254
+ options.gutters = options.gutters.slice(0)
4255
+ options.gutters.splice(found, 1)
4256
+ }
4257
+ }
4258
+
4259
+ var wheelSamples = 0;
4260
+ var wheelPixelsPerUnit = null;
4261
+ // Fill in a browser-detected starting value on browsers where we
4262
+ // know one. These don't have to be accurate -- the result of them
4263
+ // being wrong would just be a slight flicker on the first wheel
4264
+ // scroll (if it is large enough).
4265
+ if (ie) { wheelPixelsPerUnit = -.53 }
4266
+ else if (gecko) { wheelPixelsPerUnit = 15 }
4267
+ else if (chrome) { wheelPixelsPerUnit = -.7 }
4268
+ else if (safari) { wheelPixelsPerUnit = -1/3 }
4269
+
4270
+ function wheelEventDelta(e) {
4271
+ var dx = e.wheelDeltaX, dy = e.wheelDeltaY
4272
+ if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) { dx = e.detail }
4273
+ if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) { dy = e.detail }
4274
+ else if (dy == null) { dy = e.wheelDelta }
4275
+ return {x: dx, y: dy}
4276
+ }
4277
+ function wheelEventPixels(e) {
4278
+ var delta = wheelEventDelta(e)
4279
+ delta.x *= wheelPixelsPerUnit
4280
+ delta.y *= wheelPixelsPerUnit
4281
+ return delta
4282
+ }
4283
+
4284
+ function onScrollWheel(cm, e) {
4285
+ var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y
4286
+
4287
+ var display = cm.display, scroll = display.scroller
4288
+ // Quit if there's nothing to scroll here
4289
+ var canScrollX = scroll.scrollWidth > scroll.clientWidth
4290
+ var canScrollY = scroll.scrollHeight > scroll.clientHeight
4291
+ if (!(dx && canScrollX || dy && canScrollY)) { return }
4292
+
4293
+ // Webkit browsers on OS X abort momentum scrolls when the target
4294
+ // of the scroll event is removed from the scrollable element.
4295
+ // This hack (see related code in patchDisplay) makes sure the
4296
+ // element is kept around.
4297
+ if (dy && mac && webkit) {
4298
+ outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) {
4299
+ for (var i = 0; i < view.length; i++) {
4300
+ if (view[i].node == cur) {
4301
+ cm.display.currentWheelTarget = cur
4302
+ break outer
4303
+ }
4304
+ }
4305
+ }
4306
+ }
4307
+
4308
+ // On some browsers, horizontal scrolling will cause redraws to
4309
+ // happen before the gutter has been realigned, causing it to
4310
+ // wriggle around in a most unseemly way. When we have an
4311
+ // estimated pixels/delta value, we just handle horizontal
4312
+ // scrolling entirely here. It'll be slightly off from native, but
4313
+ // better than glitching out.
4314
+ if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {
4315
+ if (dy && canScrollY)
4316
+ { updateScrollTop(cm, Math.max(0, scroll.scrollTop + dy * wheelPixelsPerUnit)) }
4317
+ setScrollLeft(cm, Math.max(0, scroll.scrollLeft + dx * wheelPixelsPerUnit))
4318
+ // Only prevent default scrolling if vertical scrolling is
4319
+ // actually possible. Otherwise, it causes vertical scroll
4320
+ // jitter on OSX trackpads when deltaX is small and deltaY
4321
+ // is large (issue #3579)
4322
+ if (!dy || (dy && canScrollY))
4323
+ { e_preventDefault(e) }
4324
+ display.wheelStartX = null // Abort measurement, if in progress
4325
+ return
4326
+ }
4327
+
4328
+ // 'Project' the visible viewport to cover the area that is being
4329
+ // scrolled into view (if we know enough to estimate it).
4330
+ if (dy && wheelPixelsPerUnit != null) {
4331
+ var pixels = dy * wheelPixelsPerUnit
4332
+ var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight
4333
+ if (pixels < 0) { top = Math.max(0, top + pixels - 50) }
4334
+ else { bot = Math.min(cm.doc.height, bot + pixels + 50) }
4335
+ updateDisplaySimple(cm, {top: top, bottom: bot})
4336
+ }
4337
+
4338
+ if (wheelSamples < 20) {
4339
+ if (display.wheelStartX == null) {
4340
+ display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop
4341
+ display.wheelDX = dx; display.wheelDY = dy
4342
+ setTimeout(function () {
4343
+ if (display.wheelStartX == null) { return }
4344
+ var movedX = scroll.scrollLeft - display.wheelStartX
4345
+ var movedY = scroll.scrollTop - display.wheelStartY
4346
+ var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
4347
+ (movedX && display.wheelDX && movedX / display.wheelDX)
4348
+ display.wheelStartX = display.wheelStartY = null
4349
+ if (!sample) { return }
4350
+ wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1)
4351
+ ++wheelSamples
4352
+ }, 200)
4353
+ } else {
4354
+ display.wheelDX += dx; display.wheelDY += dy
4355
+ }
4356
+ }
4357
+ }
4358
+
4359
+ // Selection objects are immutable. A new one is created every time
4360
+ // the selection changes. A selection is one or more non-overlapping
4361
+ // (and non-touching) ranges, sorted, and an integer that indicates
4362
+ // which one is the primary selection (the one that's scrolled into
4363
+ // view, that getCursor returns, etc).
4364
+ var Selection = function(ranges, primIndex) {
4365
+ this.ranges = ranges
4366
+ this.primIndex = primIndex
4367
+ };
4368
+
4369
+ Selection.prototype.primary = function () { return this.ranges[this.primIndex] };
4370
+
4371
+ Selection.prototype.equals = function (other) {
4372
+ var this$1 = this;
4373
+
4374
+ if (other == this) { return true }
4375
+ if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) { return false }
4376
+ for (var i = 0; i < this.ranges.length; i++) {
4377
+ var here = this$1.ranges[i], there = other.ranges[i]
4378
+ if (!equalCursorPos(here.anchor, there.anchor) || !equalCursorPos(here.head, there.head)) { return false }
4379
+ }
4380
+ return true
4381
+ };
4382
+
4383
+ Selection.prototype.deepCopy = function () {
4384
+ var this$1 = this;
4385
+
4386
+ var out = []
4387
+ for (var i = 0; i < this.ranges.length; i++)
4388
+ { out[i] = new Range(copyPos(this$1.ranges[i].anchor), copyPos(this$1.ranges[i].head)) }
4389
+ return new Selection(out, this.primIndex)
4390
+ };
4391
+
4392
+ Selection.prototype.somethingSelected = function () {
4393
+ var this$1 = this;
4394
+
4395
+ for (var i = 0; i < this.ranges.length; i++)
4396
+ { if (!this$1.ranges[i].empty()) { return true } }
4397
+ return false
4398
+ };
4399
+
4400
+ Selection.prototype.contains = function (pos, end) {
4401
+ var this$1 = this;
4402
+
4403
+ if (!end) { end = pos }
4404
+ for (var i = 0; i < this.ranges.length; i++) {
4405
+ var range = this$1.ranges[i]
4406
+ if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0)
4407
+ { return i }
4408
+ }
4409
+ return -1
4410
+ };
4411
+
4412
+ var Range = function(anchor, head) {
4413
+ this.anchor = anchor; this.head = head
4414
+ };
4415
+
4416
+ Range.prototype.from = function () { return minPos(this.anchor, this.head) };
4417
+ Range.prototype.to = function () { return maxPos(this.anchor, this.head) };
4418
+ Range.prototype.empty = function () { return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch };
4419
+
4420
+ // Take an unsorted, potentially overlapping set of ranges, and
4421
+ // build a selection out of it. 'Consumes' ranges array (modifying
4422
+ // it).
4423
+ function normalizeSelection(ranges, primIndex) {
4424
+ var prim = ranges[primIndex]
4425
+ ranges.sort(function (a, b) { return cmp(a.from(), b.from()); })
4426
+ primIndex = indexOf(ranges, prim)
4427
+ for (var i = 1; i < ranges.length; i++) {
4428
+ var cur = ranges[i], prev = ranges[i - 1]
4429
+ if (cmp(prev.to(), cur.from()) >= 0) {
4430
+ var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to())
4431
+ var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head
4432
+ if (i <= primIndex) { --primIndex }
4433
+ ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to))
4434
+ }
4435
+ }
4436
+ return new Selection(ranges, primIndex)
4437
+ }
4438
+
4439
+ function simpleSelection(anchor, head) {
4440
+ return new Selection([new Range(anchor, head || anchor)], 0)
4441
+ }
4442
+
4443
+ // Compute the position of the end of a change (its 'to' property
4444
+ // refers to the pre-change end).
4445
+ function changeEnd(change) {
4446
+ if (!change.text) { return change.to }
4447
+ return Pos(change.from.line + change.text.length - 1,
4448
+ lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0))
4449
+ }
4450
+
4451
+ // Adjust a position to refer to the post-change position of the
4452
+ // same text, or the end of the change if the change covers it.
4453
+ function adjustForChange(pos, change) {
4454
+ if (cmp(pos, change.from) < 0) { return pos }
4455
+ if (cmp(pos, change.to) <= 0) { return changeEnd(change) }
4456
+
4457
+ var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch
4458
+ if (pos.line == change.to.line) { ch += changeEnd(change).ch - change.to.ch }
4459
+ return Pos(line, ch)
4460
+ }
4461
+
4462
+ function computeSelAfterChange(doc, change) {
4463
+ var out = []
4464
+ for (var i = 0; i < doc.sel.ranges.length; i++) {
4465
+ var range = doc.sel.ranges[i]
4466
+ out.push(new Range(adjustForChange(range.anchor, change),
4467
+ adjustForChange(range.head, change)))
4468
+ }
4469
+ return normalizeSelection(out, doc.sel.primIndex)
4470
+ }
4471
+
4472
+ function offsetPos(pos, old, nw) {
4473
+ if (pos.line == old.line)
4474
+ { return Pos(nw.line, pos.ch - old.ch + nw.ch) }
4475
+ else
4476
+ { return Pos(nw.line + (pos.line - old.line), pos.ch) }
4477
+ }
4478
+
4479
+ // Used by replaceSelections to allow moving the selection to the
4480
+ // start or around the replaced test. Hint may be "start" or "around".
4481
+ function computeReplacedSel(doc, changes, hint) {
4482
+ var out = []
4483
+ var oldPrev = Pos(doc.first, 0), newPrev = oldPrev
4484
+ for (var i = 0; i < changes.length; i++) {
4485
+ var change = changes[i]
4486
+ var from = offsetPos(change.from, oldPrev, newPrev)
4487
+ var to = offsetPos(changeEnd(change), oldPrev, newPrev)
4488
+ oldPrev = change.to
4489
+ newPrev = to
4490
+ if (hint == "around") {
4491
+ var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0
4492
+ out[i] = new Range(inv ? to : from, inv ? from : to)
4493
+ } else {
4494
+ out[i] = new Range(from, from)
4495
+ }
4496
+ }
4497
+ return new Selection(out, doc.sel.primIndex)
4498
+ }
4499
+
4500
+ // Used to get the editor into a consistent state again when options change.
4501
+
4502
+ function loadMode(cm) {
4503
+ cm.doc.mode = getMode(cm.options, cm.doc.modeOption)
4504
+ resetModeState(cm)
4505
+ }
4506
+
4507
+ function resetModeState(cm) {
4508
+ cm.doc.iter(function (line) {
4509
+ if (line.stateAfter) { line.stateAfter = null }
4510
+ if (line.styles) { line.styles = null }
4511
+ })
4512
+ cm.doc.frontier = cm.doc.first
4513
+ startWorker(cm, 100)
4514
+ cm.state.modeGen++
4515
+ if (cm.curOp) { regChange(cm) }
4516
+ }
4517
+
4518
+ // DOCUMENT DATA STRUCTURE
4519
+
4520
+ // By default, updates that start and end at the beginning of a line
4521
+ // are treated specially, in order to make the association of line
4522
+ // widgets and marker elements with the text behave more intuitive.
4523
+ function isWholeLineUpdate(doc, change) {
4524
+ return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" &&
4525
+ (!doc.cm || doc.cm.options.wholeLineUpdateBefore)
4526
+ }
4527
+
4528
+ // Perform a change on the document data structure.
4529
+ function updateDoc(doc, change, markedSpans, estimateHeight) {
4530
+ function spansFor(n) {return markedSpans ? markedSpans[n] : null}
4531
+ function update(line, text, spans) {
4532
+ updateLine(line, text, spans, estimateHeight)
4533
+ signalLater(line, "change", line, change)
4534
+ }
4535
+ function linesFor(start, end) {
4536
+ var result = []
4537
+ for (var i = start; i < end; ++i)
4538
+ { result.push(new Line(text[i], spansFor(i), estimateHeight)) }
4539
+ return result
4540
+ }
4541
+
4542
+ var from = change.from, to = change.to, text = change.text
4543
+ var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line)
4544
+ var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line
4545
+
4546
+ // Adjust the line structure
4547
+ if (change.full) {
4548
+ doc.insert(0, linesFor(0, text.length))
4549
+ doc.remove(text.length, doc.size - text.length)
4550
+ } else if (isWholeLineUpdate(doc, change)) {
4551
+ // This is a whole-line replace. Treated specially to make
4552
+ // sure line objects move the way they are supposed to.
4553
+ var added = linesFor(0, text.length - 1)
4554
+ update(lastLine, lastLine.text, lastSpans)
4555
+ if (nlines) { doc.remove(from.line, nlines) }
4556
+ if (added.length) { doc.insert(from.line, added) }
4557
+ } else if (firstLine == lastLine) {
4558
+ if (text.length == 1) {
4559
+ update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans)
4560
+ } else {
4561
+ var added$1 = linesFor(1, text.length - 1)
4562
+ added$1.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight))
4563
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0))
4564
+ doc.insert(from.line + 1, added$1)
4565
+ }
4566
+ } else if (text.length == 1) {
4567
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0))
4568
+ doc.remove(from.line + 1, nlines)
4569
+ } else {
4570
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0))
4571
+ update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans)
4572
+ var added$2 = linesFor(1, text.length - 1)
4573
+ if (nlines > 1) { doc.remove(from.line + 1, nlines - 1) }
4574
+ doc.insert(from.line + 1, added$2)
4575
+ }
4576
+
4577
+ signalLater(doc, "change", doc, change)
4578
+ }
4579
+
4580
+ // Call f for all linked documents.
4581
+ function linkedDocs(doc, f, sharedHistOnly) {
4582
+ function propagate(doc, skip, sharedHist) {
4583
+ if (doc.linked) { for (var i = 0; i < doc.linked.length; ++i) {
4584
+ var rel = doc.linked[i]
4585
+ if (rel.doc == skip) { continue }
4586
+ var shared = sharedHist && rel.sharedHist
4587
+ if (sharedHistOnly && !shared) { continue }
4588
+ f(rel.doc, shared)
4589
+ propagate(rel.doc, doc, shared)
4590
+ } }
4591
+ }
4592
+ propagate(doc, null, true)
4593
+ }
4594
+
4595
+ // Attach a document to an editor.
4596
+ function attachDoc(cm, doc) {
4597
+ if (doc.cm) { throw new Error("This document is already in use.") }
4598
+ cm.doc = doc
4599
+ doc.cm = cm
4600
+ estimateLineHeights(cm)
4601
+ loadMode(cm)
4602
+ setDirectionClass(cm)
4603
+ if (!cm.options.lineWrapping) { findMaxLine(cm) }
4604
+ cm.options.mode = doc.modeOption
4605
+ regChange(cm)
4606
+ }
4607
+
4608
+ function setDirectionClass(cm) {
4609
+ ;(cm.doc.direction == "rtl" ? addClass : rmClass)(cm.display.lineDiv, "CodeMirror-rtl")
4610
+ }
4611
+
4612
+ function directionChanged(cm) {
4613
+ runInOp(cm, function () {
4614
+ setDirectionClass(cm)
4615
+ regChange(cm)
4616
+ })
4617
+ }
4618
+
4619
+ function History(startGen) {
4620
+ // Arrays of change events and selections. Doing something adds an
4621
+ // event to done and clears undo. Undoing moves events from done
4622
+ // to undone, redoing moves them in the other direction.
4623
+ this.done = []; this.undone = []
4624
+ this.undoDepth = Infinity
4625
+ // Used to track when changes can be merged into a single undo
4626
+ // event
4627
+ this.lastModTime = this.lastSelTime = 0
4628
+ this.lastOp = this.lastSelOp = null
4629
+ this.lastOrigin = this.lastSelOrigin = null
4630
+ // Used by the isClean() method
4631
+ this.generation = this.maxGeneration = startGen || 1
4632
+ }
4633
+
4634
+ // Create a history change event from an updateDoc-style change
4635
+ // object.
4636
+ function historyChangeFromChange(doc, change) {
4637
+ var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)}
4638
+ attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1)
4639
+ linkedDocs(doc, function (doc) { return attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); }, true)
4640
+ return histChange
4641
+ }
4642
+
4643
+ // Pop all selection events off the end of a history array. Stop at
4644
+ // a change event.
4645
+ function clearSelectionEvents(array) {
4646
+ while (array.length) {
4647
+ var last = lst(array)
4648
+ if (last.ranges) { array.pop() }
4649
+ else { break }
4650
+ }
4651
+ }
4652
+
4653
+ // Find the top change event in the history. Pop off selection
4654
+ // events that are in the way.
4655
+ function lastChangeEvent(hist, force) {
4656
+ if (force) {
4657
+ clearSelectionEvents(hist.done)
4658
+ return lst(hist.done)
4659
+ } else if (hist.done.length && !lst(hist.done).ranges) {
4660
+ return lst(hist.done)
4661
+ } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) {
4662
+ hist.done.pop()
4663
+ return lst(hist.done)
4664
+ }
4665
+ }
4666
+
4667
+ // Register a change in the history. Merges changes that are within
4668
+ // a single operation, or are close together with an origin that
4669
+ // allows merging (starting with "+") into a single event.
4670
+ function addChangeToHistory(doc, change, selAfter, opId) {
4671
+ var hist = doc.history
4672
+ hist.undone.length = 0
4673
+ var time = +new Date, cur
4674
+ var last
4675
+
4676
+ if ((hist.lastOp == opId ||
4677
+ hist.lastOrigin == change.origin && change.origin &&
4678
+ ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) ||
4679
+ change.origin.charAt(0) == "*")) &&
4680
+ (cur = lastChangeEvent(hist, hist.lastOp == opId))) {
4681
+ // Merge this change into the last event
4682
+ last = lst(cur.changes)
4683
+ if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) {
4684
+ // Optimized case for simple insertion -- don't want to add
4685
+ // new changesets for every character typed
4686
+ last.to = changeEnd(change)
4687
+ } else {
4688
+ // Add new sub-event
4689
+ cur.changes.push(historyChangeFromChange(doc, change))
4690
+ }
4691
+ } else {
4692
+ // Can not be merged, start a new event.
4693
+ var before = lst(hist.done)
4694
+ if (!before || !before.ranges)
4695
+ { pushSelectionToHistory(doc.sel, hist.done) }
4696
+ cur = {changes: [historyChangeFromChange(doc, change)],
4697
+ generation: hist.generation}
4698
+ hist.done.push(cur)
4699
+ while (hist.done.length > hist.undoDepth) {
4700
+ hist.done.shift()
4701
+ if (!hist.done[0].ranges) { hist.done.shift() }
4702
+ }
4703
+ }
4704
+ hist.done.push(selAfter)
4705
+ hist.generation = ++hist.maxGeneration
4706
+ hist.lastModTime = hist.lastSelTime = time
4707
+ hist.lastOp = hist.lastSelOp = opId
4708
+ hist.lastOrigin = hist.lastSelOrigin = change.origin
4709
+
4710
+ if (!last) { signal(doc, "historyAdded") }
4711
+ }
4712
+
4713
+ function selectionEventCanBeMerged(doc, origin, prev, sel) {
4714
+ var ch = origin.charAt(0)
4715
+ return ch == "*" ||
4716
+ ch == "+" &&
4717
+ prev.ranges.length == sel.ranges.length &&
4718
+ prev.somethingSelected() == sel.somethingSelected() &&
4719
+ new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500)
4720
+ }
4721
+
4722
+ // Called whenever the selection changes, sets the new selection as
4723
+ // the pending selection in the history, and pushes the old pending
4724
+ // selection into the 'done' array when it was significantly
4725
+ // different (in number of selected ranges, emptiness, or time).
4726
+ function addSelectionToHistory(doc, sel, opId, options) {
4727
+ var hist = doc.history, origin = options && options.origin
4728
+
4729
+ // A new event is started when the previous origin does not match
4730
+ // the current, or the origins don't allow matching. Origins
4731
+ // starting with * are always merged, those starting with + are
4732
+ // merged when similar and close together in time.
4733
+ if (opId == hist.lastSelOp ||
4734
+ (origin && hist.lastSelOrigin == origin &&
4735
+ (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin ||
4736
+ selectionEventCanBeMerged(doc, origin, lst(hist.done), sel))))
4737
+ { hist.done[hist.done.length - 1] = sel }
4738
+ else
4739
+ { pushSelectionToHistory(sel, hist.done) }
4740
+
4741
+ hist.lastSelTime = +new Date
4742
+ hist.lastSelOrigin = origin
4743
+ hist.lastSelOp = opId
4744
+ if (options && options.clearRedo !== false)
4745
+ { clearSelectionEvents(hist.undone) }
4746
+ }
4747
+
4748
+ function pushSelectionToHistory(sel, dest) {
4749
+ var top = lst(dest)
4750
+ if (!(top && top.ranges && top.equals(sel)))
4751
+ { dest.push(sel) }
4752
+ }
4753
+
4754
+ // Used to store marked span information in the history.
4755
+ function attachLocalSpans(doc, change, from, to) {
4756
+ var existing = change["spans_" + doc.id], n = 0
4757
+ doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function (line) {
4758
+ if (line.markedSpans)
4759
+ { (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans }
4760
+ ++n
4761
+ })
4762
+ }
4763
+
4764
+ // When un/re-doing restores text containing marked spans, those
4765
+ // that have been explicitly cleared should not be restored.
4766
+ function removeClearedSpans(spans) {
4767
+ if (!spans) { return null }
4768
+ var out
4769
+ for (var i = 0; i < spans.length; ++i) {
4770
+ if (spans[i].marker.explicitlyCleared) { if (!out) { out = spans.slice(0, i) } }
4771
+ else if (out) { out.push(spans[i]) }
4772
+ }
4773
+ return !out ? spans : out.length ? out : null
4774
+ }
4775
+
4776
+ // Retrieve and filter the old marked spans stored in a change event.
4777
+ function getOldSpans(doc, change) {
4778
+ var found = change["spans_" + doc.id]
4779
+ if (!found) { return null }
4780
+ var nw = []
4781
+ for (var i = 0; i < change.text.length; ++i)
4782
+ { nw.push(removeClearedSpans(found[i])) }
4783
+ return nw
4784
+ }
4785
+
4786
+ // Used for un/re-doing changes from the history. Combines the
4787
+ // result of computing the existing spans with the set of spans that
4788
+ // existed in the history (so that deleting around a span and then
4789
+ // undoing brings back the span).
4790
+ function mergeOldSpans(doc, change) {
4791
+ var old = getOldSpans(doc, change)
4792
+ var stretched = stretchSpansOverChange(doc, change)
4793
+ if (!old) { return stretched }
4794
+ if (!stretched) { return old }
4795
+
4796
+ for (var i = 0; i < old.length; ++i) {
4797
+ var oldCur = old[i], stretchCur = stretched[i]
4798
+ if (oldCur && stretchCur) {
4799
+ spans: for (var j = 0; j < stretchCur.length; ++j) {
4800
+ var span = stretchCur[j]
4801
+ for (var k = 0; k < oldCur.length; ++k)
4802
+ { if (oldCur[k].marker == span.marker) { continue spans } }
4803
+ oldCur.push(span)
4804
+ }
4805
+ } else if (stretchCur) {
4806
+ old[i] = stretchCur
4807
+ }
4808
+ }
4809
+ return old
4810
+ }
4811
+
4812
+ // Used both to provide a JSON-safe object in .getHistory, and, when
4813
+ // detaching a document, to split the history in two
4814
+ function copyHistoryArray(events, newGroup, instantiateSel) {
4815
+ var copy = []
4816
+ for (var i = 0; i < events.length; ++i) {
4817
+ var event = events[i]
4818
+ if (event.ranges) {
4819
+ copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event)
4820
+ continue
4821
+ }
4822
+ var changes = event.changes, newChanges = []
4823
+ copy.push({changes: newChanges})
4824
+ for (var j = 0; j < changes.length; ++j) {
4825
+ var change = changes[j], m = (void 0)
4826
+ newChanges.push({from: change.from, to: change.to, text: change.text})
4827
+ if (newGroup) { for (var prop in change) { if (m = prop.match(/^spans_(\d+)$/)) {
4828
+ if (indexOf(newGroup, Number(m[1])) > -1) {
4829
+ lst(newChanges)[prop] = change[prop]
4830
+ delete change[prop]
4831
+ }
4832
+ } } }
4833
+ }
4834
+ }
4835
+ return copy
4836
+ }
4837
+
4838
+ // The 'scroll' parameter given to many of these indicated whether
4839
+ // the new cursor position should be scrolled into view after
4840
+ // modifying the selection.
4841
+
4842
+ // If shift is held or the extend flag is set, extends a range to
4843
+ // include a given position (and optionally a second position).
4844
+ // Otherwise, simply returns the range between the given positions.
4845
+ // Used for cursor motion and such.
4846
+ function extendRange(doc, range, head, other) {
4847
+ if (doc.cm && doc.cm.display.shift || doc.extend) {
4848
+ var anchor = range.anchor
4849
+ if (other) {
4850
+ var posBefore = cmp(head, anchor) < 0
4851
+ if (posBefore != (cmp(other, anchor) < 0)) {
4852
+ anchor = head
4853
+ head = other
4854
+ } else if (posBefore != (cmp(head, other) < 0)) {
4855
+ head = other
4856
+ }
4857
+ }
4858
+ return new Range(anchor, head)
4859
+ } else {
4860
+ return new Range(other || head, head)
4861
+ }
4862
+ }
4863
+
4864
+ // Extend the primary selection range, discard the rest.
4865
+ function extendSelection(doc, head, other, options) {
4866
+ setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options)
4867
+ }
4868
+
4869
+ // Extend all selections (pos is an array of selections with length
4870
+ // equal the number of selections)
4871
+ function extendSelections(doc, heads, options) {
4872
+ var out = []
4873
+ for (var i = 0; i < doc.sel.ranges.length; i++)
4874
+ { out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null) }
4875
+ var newSel = normalizeSelection(out, doc.sel.primIndex)
4876
+ setSelection(doc, newSel, options)
4877
+ }
4878
+
4879
+ // Updates a single range in the selection.
4880
+ function replaceOneSelection(doc, i, range, options) {
4881
+ var ranges = doc.sel.ranges.slice(0)
4882
+ ranges[i] = range
4883
+ setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options)
4884
+ }
4885
+
4886
+ // Reset the selection to a single range.
4887
+ function setSimpleSelection(doc, anchor, head, options) {
4888
+ setSelection(doc, simpleSelection(anchor, head), options)
4889
+ }
4890
+
4891
+ // Give beforeSelectionChange handlers a change to influence a
4892
+ // selection update.
4893
+ function filterSelectionChange(doc, sel, options) {
4894
+ var obj = {
4895
+ ranges: sel.ranges,
4896
+ update: function(ranges) {
4897
+ var this$1 = this;
4898
+
4899
+ this.ranges = []
4900
+ for (var i = 0; i < ranges.length; i++)
4901
+ { this$1.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),
4902
+ clipPos(doc, ranges[i].head)) }
4903
+ },
4904
+ origin: options && options.origin
4905
+ }
4906
+ signal(doc, "beforeSelectionChange", doc, obj)
4907
+ if (doc.cm) { signal(doc.cm, "beforeSelectionChange", doc.cm, obj) }
4908
+ if (obj.ranges != sel.ranges) { return normalizeSelection(obj.ranges, obj.ranges.length - 1) }
4909
+ else { return sel }
4910
+ }
4911
+
4912
+ function setSelectionReplaceHistory(doc, sel, options) {
4913
+ var done = doc.history.done, last = lst(done)
4914
+ if (last && last.ranges) {
4915
+ done[done.length - 1] = sel
4916
+ setSelectionNoUndo(doc, sel, options)
4917
+ } else {
4918
+ setSelection(doc, sel, options)
4919
+ }
4920
+ }
4921
+
4922
+ // Set a new selection.
4923
+ function setSelection(doc, sel, options) {
4924
+ setSelectionNoUndo(doc, sel, options)
4925
+ addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options)
4926
+ }
4927
+
4928
+ function setSelectionNoUndo(doc, sel, options) {
4929
+ if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
4930
+ { sel = filterSelectionChange(doc, sel, options) }
4931
+
4932
+ var bias = options && options.bias ||
4933
+ (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1)
4934
+ setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true))
4935
+
4936
+ if (!(options && options.scroll === false) && doc.cm)
4937
+ { ensureCursorVisible(doc.cm) }
4938
+ }
4939
+
4940
+ function setSelectionInner(doc, sel) {
4941
+ if (sel.equals(doc.sel)) { return }
4942
+
4943
+ doc.sel = sel
4944
+
4945
+ if (doc.cm) {
4946
+ doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true
4947
+ signalCursorActivity(doc.cm)
4948
+ }
4949
+ signalLater(doc, "cursorActivity", doc)
4950
+ }
4951
+
4952
+ // Verify that the selection does not partially select any atomic
4953
+ // marked ranges.
4954
+ function reCheckSelection(doc) {
4955
+ setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false))
4956
+ }
4957
+
4958
+ // Return a selection that does not partially select any atomic
4959
+ // ranges.
4960
+ function skipAtomicInSelection(doc, sel, bias, mayClear) {
4961
+ var out
4962
+ for (var i = 0; i < sel.ranges.length; i++) {
4963
+ var range = sel.ranges[i]
4964
+ var old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i]
4965
+ var newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear)
4966
+ var newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear)
4967
+ if (out || newAnchor != range.anchor || newHead != range.head) {
4968
+ if (!out) { out = sel.ranges.slice(0, i) }
4969
+ out[i] = new Range(newAnchor, newHead)
4970
+ }
4971
+ }
4972
+ return out ? normalizeSelection(out, sel.primIndex) : sel
4973
+ }
4974
+
4975
+ function skipAtomicInner(doc, pos, oldPos, dir, mayClear) {
4976
+ var line = getLine(doc, pos.line)
4977
+ if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) {
4978
+ var sp = line.markedSpans[i], m = sp.marker
4979
+ if ((sp.from == null || (m.inclusiveLeft ? sp.from <= pos.ch : sp.from < pos.ch)) &&
4980
+ (sp.to == null || (m.inclusiveRight ? sp.to >= pos.ch : sp.to > pos.ch))) {
4981
+ if (mayClear) {
4982
+ signal(m, "beforeCursorEnter")
4983
+ if (m.explicitlyCleared) {
4984
+ if (!line.markedSpans) { break }
4985
+ else {--i; continue}
4986
+ }
4987
+ }
4988
+ if (!m.atomic) { continue }
4989
+
4990
+ if (oldPos) {
4991
+ var near = m.find(dir < 0 ? 1 : -1), diff = (void 0)
4992
+ if (dir < 0 ? m.inclusiveRight : m.inclusiveLeft)
4993
+ { near = movePos(doc, near, -dir, near && near.line == pos.line ? line : null) }
4994
+ if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0))
4995
+ { return skipAtomicInner(doc, near, pos, dir, mayClear) }
4996
+ }
4997
+
4998
+ var far = m.find(dir < 0 ? -1 : 1)
4999
+ if (dir < 0 ? m.inclusiveLeft : m.inclusiveRight)
5000
+ { far = movePos(doc, far, dir, far.line == pos.line ? line : null) }
5001
+ return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null
5002
+ }
5003
+ } }
5004
+ return pos
5005
+ }
5006
+
5007
+ // Ensure a given position is not inside an atomic range.
5008
+ function skipAtomic(doc, pos, oldPos, bias, mayClear) {
5009
+ var dir = bias || 1
5010
+ var found = skipAtomicInner(doc, pos, oldPos, dir, mayClear) ||
5011
+ (!mayClear && skipAtomicInner(doc, pos, oldPos, dir, true)) ||
5012
+ skipAtomicInner(doc, pos, oldPos, -dir, mayClear) ||
5013
+ (!mayClear && skipAtomicInner(doc, pos, oldPos, -dir, true))
5014
+ if (!found) {
5015
+ doc.cantEdit = true
5016
+ return Pos(doc.first, 0)
5017
+ }
5018
+ return found
5019
+ }
5020
+
5021
+ function movePos(doc, pos, dir, line) {
5022
+ if (dir < 0 && pos.ch == 0) {
5023
+ if (pos.line > doc.first) { return clipPos(doc, Pos(pos.line - 1)) }
5024
+ else { return null }
5025
+ } else if (dir > 0 && pos.ch == (line || getLine(doc, pos.line)).text.length) {
5026
+ if (pos.line < doc.first + doc.size - 1) { return Pos(pos.line + 1, 0) }
5027
+ else { return null }
5028
+ } else {
5029
+ return new Pos(pos.line, pos.ch + dir)
5030
+ }
5031
+ }
5032
+
5033
+ function selectAll(cm) {
5034
+ cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll)
5035
+ }
5036
+
5037
+ // UPDATING
5038
+
5039
+ // Allow "beforeChange" event handlers to influence a change
5040
+ function filterChange(doc, change, update) {
5041
+ var obj = {
5042
+ canceled: false,
5043
+ from: change.from,
5044
+ to: change.to,
5045
+ text: change.text,
5046
+ origin: change.origin,
5047
+ cancel: function () { return obj.canceled = true; }
5048
+ }
5049
+ if (update) { obj.update = function (from, to, text, origin) {
5050
+ if (from) { obj.from = clipPos(doc, from) }
5051
+ if (to) { obj.to = clipPos(doc, to) }
5052
+ if (text) { obj.text = text }
5053
+ if (origin !== undefined) { obj.origin = origin }
5054
+ } }
5055
+ signal(doc, "beforeChange", doc, obj)
5056
+ if (doc.cm) { signal(doc.cm, "beforeChange", doc.cm, obj) }
5057
+
5058
+ if (obj.canceled) { return null }
5059
+ return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin}
5060
+ }
5061
+
5062
+ // Apply a change to a document, and add it to the document's
5063
+ // history, and propagating it to all linked documents.
5064
+ function makeChange(doc, change, ignoreReadOnly) {
5065
+ if (doc.cm) {
5066
+ if (!doc.cm.curOp) { return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly) }
5067
+ if (doc.cm.state.suppressEdits) { return }
5068
+ }
5069
+
5070
+ if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) {
5071
+ change = filterChange(doc, change, true)
5072
+ if (!change) { return }
5073
+ }
5074
+
5075
+ // Possibly split or suppress the update based on the presence
5076
+ // of read-only spans in its range.
5077
+ var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to)
5078
+ if (split) {
5079
+ for (var i = split.length - 1; i >= 0; --i)
5080
+ { makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text}) }
5081
+ } else {
5082
+ makeChangeInner(doc, change)
5083
+ }
5084
+ }
5085
+
5086
+ function makeChangeInner(doc, change) {
5087
+ if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) { return }
5088
+ var selAfter = computeSelAfterChange(doc, change)
5089
+ addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN)
5090
+
5091
+ makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change))
5092
+ var rebased = []
5093
+
5094
+ linkedDocs(doc, function (doc, sharedHist) {
5095
+ if (!sharedHist && indexOf(rebased, doc.history) == -1) {
5096
+ rebaseHist(doc.history, change)
5097
+ rebased.push(doc.history)
5098
+ }
5099
+ makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change))
5100
+ })
5101
+ }
5102
+
5103
+ // Revert a change stored in a document's history.
5104
+ function makeChangeFromHistory(doc, type, allowSelectionOnly) {
5105
+ if (doc.cm && doc.cm.state.suppressEdits && !allowSelectionOnly) { return }
5106
+
5107
+ var hist = doc.history, event, selAfter = doc.sel
5108
+ var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done
5109
+
5110
+ // Verify that there is a useable event (so that ctrl-z won't
5111
+ // needlessly clear selection events)
5112
+ var i = 0
5113
+ for (; i < source.length; i++) {
5114
+ event = source[i]
5115
+ if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges)
5116
+ { break }
5117
+ }
5118
+ if (i == source.length) { return }
5119
+ hist.lastOrigin = hist.lastSelOrigin = null
5120
+
5121
+ for (;;) {
5122
+ event = source.pop()
5123
+ if (event.ranges) {
5124
+ pushSelectionToHistory(event, dest)
5125
+ if (allowSelectionOnly && !event.equals(doc.sel)) {
5126
+ setSelection(doc, event, {clearRedo: false})
5127
+ return
5128
+ }
5129
+ selAfter = event
5130
+ }
5131
+ else { break }
5132
+ }
5133
+
5134
+ // Build up a reverse change object to add to the opposite history
5135
+ // stack (redo when undoing, and vice versa).
5136
+ var antiChanges = []
5137
+ pushSelectionToHistory(selAfter, dest)
5138
+ dest.push({changes: antiChanges, generation: hist.generation})
5139
+ hist.generation = event.generation || ++hist.maxGeneration
5140
+
5141
+ var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")
5142
+
5143
+ var loop = function ( i ) {
5144
+ var change = event.changes[i]
5145
+ change.origin = type
5146
+ if (filter && !filterChange(doc, change, false)) {
5147
+ source.length = 0
5148
+ return {}
5149
+ }
5150
+
5151
+ antiChanges.push(historyChangeFromChange(doc, change))
5152
+
5153
+ var after = i ? computeSelAfterChange(doc, change) : lst(source)
5154
+ makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change))
5155
+ if (!i && doc.cm) { doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)}) }
5156
+ var rebased = []
5157
+
5158
+ // Propagate to the linked documents
5159
+ linkedDocs(doc, function (doc, sharedHist) {
5160
+ if (!sharedHist && indexOf(rebased, doc.history) == -1) {
5161
+ rebaseHist(doc.history, change)
5162
+ rebased.push(doc.history)
5163
+ }
5164
+ makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change))
5165
+ })
5166
+ };
5167
+
5168
+ for (var i$1 = event.changes.length - 1; i$1 >= 0; --i$1) {
5169
+ var returned = loop( i$1 );
5170
+
5171
+ if ( returned ) return returned.v;
5172
+ }
5173
+ }
5174
+
5175
+ // Sub-views need their line numbers shifted when text is added
5176
+ // above or below them in the parent document.
5177
+ function shiftDoc(doc, distance) {
5178
+ if (distance == 0) { return }
5179
+ doc.first += distance
5180
+ doc.sel = new Selection(map(doc.sel.ranges, function (range) { return new Range(
5181
+ Pos(range.anchor.line + distance, range.anchor.ch),
5182
+ Pos(range.head.line + distance, range.head.ch)
5183
+ ); }), doc.sel.primIndex)
5184
+ if (doc.cm) {
5185
+ regChange(doc.cm, doc.first, doc.first - distance, distance)
5186
+ for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++)
5187
+ { regLineChange(doc.cm, l, "gutter") }
5188
+ }
5189
+ }
5190
+
5191
+ // More lower-level change function, handling only a single document
5192
+ // (not linked ones).
5193
+ function makeChangeSingleDoc(doc, change, selAfter, spans) {
5194
+ if (doc.cm && !doc.cm.curOp)
5195
+ { return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans) }
5196
+
5197
+ if (change.to.line < doc.first) {
5198
+ shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line))
5199
+ return
5200
+ }
5201
+ if (change.from.line > doc.lastLine()) { return }
5202
+
5203
+ // Clip the change to the size of this doc
5204
+ if (change.from.line < doc.first) {
5205
+ var shift = change.text.length - 1 - (doc.first - change.from.line)
5206
+ shiftDoc(doc, shift)
5207
+ change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),
5208
+ text: [lst(change.text)], origin: change.origin}
5209
+ }
5210
+ var last = doc.lastLine()
5211
+ if (change.to.line > last) {
5212
+ change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),
5213
+ text: [change.text[0]], origin: change.origin}
5214
+ }
5215
+
5216
+ change.removed = getBetween(doc, change.from, change.to)
5217
+
5218
+ if (!selAfter) { selAfter = computeSelAfterChange(doc, change) }
5219
+ if (doc.cm) { makeChangeSingleDocInEditor(doc.cm, change, spans) }
5220
+ else { updateDoc(doc, change, spans) }
5221
+ setSelectionNoUndo(doc, selAfter, sel_dontScroll)
5222
+ }
5223
+
5224
+ // Handle the interaction of a change to a document with the editor
5225
+ // that this document is part of.
5226
+ function makeChangeSingleDocInEditor(cm, change, spans) {
5227
+ var doc = cm.doc, display = cm.display, from = change.from, to = change.to
5228
+
5229
+ var recomputeMaxLength = false, checkWidthStart = from.line
5230
+ if (!cm.options.lineWrapping) {
5231
+ checkWidthStart = lineNo(visualLine(getLine(doc, from.line)))
5232
+ doc.iter(checkWidthStart, to.line + 1, function (line) {
5233
+ if (line == display.maxLine) {
5234
+ recomputeMaxLength = true
5235
+ return true
5236
+ }
5237
+ })
5238
+ }
5239
+
5240
+ if (doc.sel.contains(change.from, change.to) > -1)
5241
+ { signalCursorActivity(cm) }
5242
+
5243
+ updateDoc(doc, change, spans, estimateHeight(cm))
5244
+
5245
+ if (!cm.options.lineWrapping) {
5246
+ doc.iter(checkWidthStart, from.line + change.text.length, function (line) {
5247
+ var len = lineLength(line)
5248
+ if (len > display.maxLineLength) {
5249
+ display.maxLine = line
5250
+ display.maxLineLength = len
5251
+ display.maxLineChanged = true
5252
+ recomputeMaxLength = false
5253
+ }
5254
+ })
5255
+ if (recomputeMaxLength) { cm.curOp.updateMaxLine = true }
5256
+ }
5257
+
5258
+ // Adjust frontier, schedule worker
5259
+ doc.frontier = Math.min(doc.frontier, from.line)
5260
+ startWorker(cm, 400)
5261
+
5262
+ var lendiff = change.text.length - (to.line - from.line) - 1
5263
+ // Remember that these lines changed, for updating the display
5264
+ if (change.full)
5265
+ { regChange(cm) }
5266
+ else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))
5267
+ { regLineChange(cm, from.line, "text") }
5268
+ else
5269
+ { regChange(cm, from.line, to.line + 1, lendiff) }
5270
+
5271
+ var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change")
5272
+ if (changeHandler || changesHandler) {
5273
+ var obj = {
5274
+ from: from, to: to,
5275
+ text: change.text,
5276
+ removed: change.removed,
5277
+ origin: change.origin
5278
+ }
5279
+ if (changeHandler) { signalLater(cm, "change", cm, obj) }
5280
+ if (changesHandler) { (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj) }
5281
+ }
5282
+ cm.display.selForContextMenu = null
5283
+ }
5284
+
5285
+ function replaceRange(doc, code, from, to, origin) {
5286
+ if (!to) { to = from }
5287
+ if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp }
5288
+ if (typeof code == "string") { code = doc.splitLines(code) }
5289
+ makeChange(doc, {from: from, to: to, text: code, origin: origin})
5290
+ }
5291
+
5292
+ // Rebasing/resetting history to deal with externally-sourced changes
5293
+
5294
+ function rebaseHistSelSingle(pos, from, to, diff) {
5295
+ if (to < pos.line) {
5296
+ pos.line += diff
5297
+ } else if (from < pos.line) {
5298
+ pos.line = from
5299
+ pos.ch = 0
5300
+ }
5301
+ }
5302
+
5303
+ // Tries to rebase an array of history events given a change in the
5304
+ // document. If the change touches the same lines as the event, the
5305
+ // event, and everything 'behind' it, is discarded. If the change is
5306
+ // before the event, the event's positions are updated. Uses a
5307
+ // copy-on-write scheme for the positions, to avoid having to
5308
+ // reallocate them all on every rebase, but also avoid problems with
5309
+ // shared position objects being unsafely updated.
5310
+ function rebaseHistArray(array, from, to, diff) {
5311
+ for (var i = 0; i < array.length; ++i) {
5312
+ var sub = array[i], ok = true
5313
+ if (sub.ranges) {
5314
+ if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true }
5315
+ for (var j = 0; j < sub.ranges.length; j++) {
5316
+ rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff)
5317
+ rebaseHistSelSingle(sub.ranges[j].head, from, to, diff)
5318
+ }
5319
+ continue
5320
+ }
5321
+ for (var j$1 = 0; j$1 < sub.changes.length; ++j$1) {
5322
+ var cur = sub.changes[j$1]
5323
+ if (to < cur.from.line) {
5324
+ cur.from = Pos(cur.from.line + diff, cur.from.ch)
5325
+ cur.to = Pos(cur.to.line + diff, cur.to.ch)
5326
+ } else if (from <= cur.to.line) {
5327
+ ok = false
5328
+ break
5329
+ }
5330
+ }
5331
+ if (!ok) {
5332
+ array.splice(0, i + 1)
5333
+ i = 0
5334
+ }
5335
+ }
5336
+ }
5337
+
5338
+ function rebaseHist(hist, change) {
5339
+ var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1
5340
+ rebaseHistArray(hist.done, from, to, diff)
5341
+ rebaseHistArray(hist.undone, from, to, diff)
5342
+ }
5343
+
5344
+ // Utility for applying a change to a line by handle or number,
5345
+ // returning the number and optionally registering the line as
5346
+ // changed.
5347
+ function changeLine(doc, handle, changeType, op) {
5348
+ var no = handle, line = handle
5349
+ if (typeof handle == "number") { line = getLine(doc, clipLine(doc, handle)) }
5350
+ else { no = lineNo(handle) }
5351
+ if (no == null) { return null }
5352
+ if (op(line, no) && doc.cm) { regLineChange(doc.cm, no, changeType) }
5353
+ return line
5354
+ }
5355
+
5356
+ // The document is represented as a BTree consisting of leaves, with
5357
+ // chunk of lines in them, and branches, with up to ten leaves or
5358
+ // other branch nodes below them. The top node is always a branch
5359
+ // node, and is the document object itself (meaning it has
5360
+ // additional methods and properties).
5361
+ //
5362
+ // All nodes have parent links. The tree is used both to go from
5363
+ // line numbers to line objects, and to go from objects to numbers.
5364
+ // It also indexes by height, and is used to convert between height
5365
+ // and line object, and to find the total height of the document.
5366
+ //
5367
+ // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html
5368
+
5369
+ var LeafChunk = function(lines) {
5370
+ var this$1 = this;
5371
+
5372
+ this.lines = lines
5373
+ this.parent = null
5374
+ var height = 0
5375
+ for (var i = 0; i < lines.length; ++i) {
5376
+ lines[i].parent = this$1
5377
+ height += lines[i].height
5378
+ }
5379
+ this.height = height
5380
+ };
5381
+
5382
+ LeafChunk.prototype.chunkSize = function () { return this.lines.length };
5383
+
5384
+ // Remove the n lines at offset 'at'.
5385
+ LeafChunk.prototype.removeInner = function (at, n) {
5386
+ var this$1 = this;
5387
+
5388
+ for (var i = at, e = at + n; i < e; ++i) {
5389
+ var line = this$1.lines[i]
5390
+ this$1.height -= line.height
5391
+ cleanUpLine(line)
5392
+ signalLater(line, "delete")
5393
+ }
5394
+ this.lines.splice(at, n)
5395
+ };
5396
+
5397
+ // Helper used to collapse a small branch into a single leaf.
5398
+ LeafChunk.prototype.collapse = function (lines) {
5399
+ lines.push.apply(lines, this.lines)
5400
+ };
5401
+
5402
+ // Insert the given array of lines at offset 'at', count them as
5403
+ // having the given height.
5404
+ LeafChunk.prototype.insertInner = function (at, lines, height) {
5405
+ var this$1 = this;
5406
+
5407
+ this.height += height
5408
+ this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at))
5409
+ for (var i = 0; i < lines.length; ++i) { lines[i].parent = this$1 }
5410
+ };
5411
+
5412
+ // Used to iterate over a part of the tree.
5413
+ LeafChunk.prototype.iterN = function (at, n, op) {
5414
+ var this$1 = this;
5415
+
5416
+ for (var e = at + n; at < e; ++at)
5417
+ { if (op(this$1.lines[at])) { return true } }
5418
+ };
5419
+
5420
+ var BranchChunk = function(children) {
5421
+ var this$1 = this;
5422
+
5423
+ this.children = children
5424
+ var size = 0, height = 0
5425
+ for (var i = 0; i < children.length; ++i) {
5426
+ var ch = children[i]
5427
+ size += ch.chunkSize(); height += ch.height
5428
+ ch.parent = this$1
5429
+ }
5430
+ this.size = size
5431
+ this.height = height
5432
+ this.parent = null
5433
+ };
5434
+
5435
+ BranchChunk.prototype.chunkSize = function () { return this.size };
5436
+
5437
+ BranchChunk.prototype.removeInner = function (at, n) {
5438
+ var this$1 = this;
5439
+
5440
+ this.size -= n
5441
+ for (var i = 0; i < this.children.length; ++i) {
5442
+ var child = this$1.children[i], sz = child.chunkSize()
5443
+ if (at < sz) {
5444
+ var rm = Math.min(n, sz - at), oldHeight = child.height
5445
+ child.removeInner(at, rm)
5446
+ this$1.height -= oldHeight - child.height
5447
+ if (sz == rm) { this$1.children.splice(i--, 1); child.parent = null }
5448
+ if ((n -= rm) == 0) { break }
5449
+ at = 0
5450
+ } else { at -= sz }
5451
+ }
5452
+ // If the result is smaller than 25 lines, ensure that it is a
5453
+ // single leaf node.
5454
+ if (this.size - n < 25 &&
5455
+ (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) {
5456
+ var lines = []
5457
+ this.collapse(lines)
5458
+ this.children = [new LeafChunk(lines)]
5459
+ this.children[0].parent = this
5460
+ }
5461
+ };
5462
+
5463
+ BranchChunk.prototype.collapse = function (lines) {
5464
+ var this$1 = this;
5465
+
5466
+ for (var i = 0; i < this.children.length; ++i) { this$1.children[i].collapse(lines) }
5467
+ };
5468
+
5469
+ BranchChunk.prototype.insertInner = function (at, lines, height) {
5470
+ var this$1 = this;
5471
+
5472
+ this.size += lines.length
5473
+ this.height += height
5474
+ for (var i = 0; i < this.children.length; ++i) {
5475
+ var child = this$1.children[i], sz = child.chunkSize()
5476
+ if (at <= sz) {
5477
+ child.insertInner(at, lines, height)
5478
+ if (child.lines && child.lines.length > 50) {
5479
+ // To avoid memory thrashing when child.lines is huge (e.g. first view of a large file), it's never spliced.
5480
+ // Instead, small slices are taken. They're taken in order because sequential memory accesses are fastest.
5481
+ var remaining = child.lines.length % 25 + 25
5482
+ for (var pos = remaining; pos < child.lines.length;) {
5483
+ var leaf = new LeafChunk(child.lines.slice(pos, pos += 25))
5484
+ child.height -= leaf.height
5485
+ this$1.children.splice(++i, 0, leaf)
5486
+ leaf.parent = this$1
5487
+ }
5488
+ child.lines = child.lines.slice(0, remaining)
5489
+ this$1.maybeSpill()
5490
+ }
5491
+ break
5492
+ }
5493
+ at -= sz
5494
+ }
5495
+ };
5496
+
5497
+ // When a node has grown, check whether it should be split.
5498
+ BranchChunk.prototype.maybeSpill = function () {
5499
+ if (this.children.length <= 10) { return }
5500
+ var me = this
5501
+ do {
5502
+ var spilled = me.children.splice(me.children.length - 5, 5)
5503
+ var sibling = new BranchChunk(spilled)
5504
+ if (!me.parent) { // Become the parent node
5505
+ var copy = new BranchChunk(me.children)
5506
+ copy.parent = me
5507
+ me.children = [copy, sibling]
5508
+ me = copy
5509
+ } else {
5510
+ me.size -= sibling.size
5511
+ me.height -= sibling.height
5512
+ var myIndex = indexOf(me.parent.children, me)
5513
+ me.parent.children.splice(myIndex + 1, 0, sibling)
5514
+ }
5515
+ sibling.parent = me.parent
5516
+ } while (me.children.length > 10)
5517
+ me.parent.maybeSpill()
5518
+ };
5519
+
5520
+ BranchChunk.prototype.iterN = function (at, n, op) {
5521
+ var this$1 = this;
5522
+
5523
+ for (var i = 0; i < this.children.length; ++i) {
5524
+ var child = this$1.children[i], sz = child.chunkSize()
5525
+ if (at < sz) {
5526
+ var used = Math.min(n, sz - at)
5527
+ if (child.iterN(at, used, op)) { return true }
5528
+ if ((n -= used) == 0) { break }
5529
+ at = 0
5530
+ } else { at -= sz }
5531
+ }
5532
+ };
5533
+
5534
+ // Line widgets are block elements displayed above or below a line.
5535
+
5536
+ var LineWidget = function(doc, node, options) {
5537
+ var this$1 = this;
5538
+
5539
+ if (options) { for (var opt in options) { if (options.hasOwnProperty(opt))
5540
+ { this$1[opt] = options[opt] } } }
5541
+ this.doc = doc
5542
+ this.node = node
5543
+ };
5544
+
5545
+ LineWidget.prototype.clear = function () {
5546
+ var this$1 = this;
5547
+
5548
+ var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line)
5549
+ if (no == null || !ws) { return }
5550
+ for (var i = 0; i < ws.length; ++i) { if (ws[i] == this$1) { ws.splice(i--, 1) } }
5551
+ if (!ws.length) { line.widgets = null }
5552
+ var height = widgetHeight(this)
5553
+ updateLineHeight(line, Math.max(0, line.height - height))
5554
+ if (cm) {
5555
+ runInOp(cm, function () {
5556
+ adjustScrollWhenAboveVisible(cm, line, -height)
5557
+ regLineChange(cm, no, "widget")
5558
+ })
5559
+ signalLater(cm, "lineWidgetCleared", cm, this, no)
5560
+ }
5561
+ };
5562
+
5563
+ LineWidget.prototype.changed = function () {
5564
+ var this$1 = this;
5565
+
5566
+ var oldH = this.height, cm = this.doc.cm, line = this.line
5567
+ this.height = null
5568
+ var diff = widgetHeight(this) - oldH
5569
+ if (!diff) { return }
5570
+ updateLineHeight(line, line.height + diff)
5571
+ if (cm) {
5572
+ runInOp(cm, function () {
5573
+ cm.curOp.forceUpdate = true
5574
+ adjustScrollWhenAboveVisible(cm, line, diff)
5575
+ signalLater(cm, "lineWidgetChanged", cm, this$1, lineNo(line))
5576
+ })
5577
+ }
5578
+ };
5579
+ eventMixin(LineWidget)
5580
+
5581
+ function adjustScrollWhenAboveVisible(cm, line, diff) {
5582
+ if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop))
5583
+ { addToScrollTop(cm, diff) }
5584
+ }
5585
+
5586
+ function addLineWidget(doc, handle, node, options) {
5587
+ var widget = new LineWidget(doc, node, options)
5588
+ var cm = doc.cm
5589
+ if (cm && widget.noHScroll) { cm.display.alignWidgets = true }
5590
+ changeLine(doc, handle, "widget", function (line) {
5591
+ var widgets = line.widgets || (line.widgets = [])
5592
+ if (widget.insertAt == null) { widgets.push(widget) }
5593
+ else { widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget) }
5594
+ widget.line = line
5595
+ if (cm && !lineIsHidden(doc, line)) {
5596
+ var aboveVisible = heightAtLine(line) < doc.scrollTop
5597
+ updateLineHeight(line, line.height + widgetHeight(widget))
5598
+ if (aboveVisible) { addToScrollTop(cm, widget.height) }
5599
+ cm.curOp.forceUpdate = true
5600
+ }
5601
+ return true
5602
+ })
5603
+ signalLater(cm, "lineWidgetAdded", cm, widget, typeof handle == "number" ? handle : lineNo(handle))
5604
+ return widget
5605
+ }
5606
+
5607
+ // TEXTMARKERS
5608
+
5609
+ // Created with markText and setBookmark methods. A TextMarker is a
5610
+ // handle that can be used to clear or find a marked position in the
5611
+ // document. Line objects hold arrays (markedSpans) containing
5612
+ // {from, to, marker} object pointing to such marker objects, and
5613
+ // indicating that such a marker is present on that line. Multiple
5614
+ // lines may point to the same marker when it spans across lines.
5615
+ // The spans will have null for their from/to properties when the
5616
+ // marker continues beyond the start/end of the line. Markers have
5617
+ // links back to the lines they currently touch.
5618
+
5619
+ // Collapsed markers have unique ids, in order to be able to order
5620
+ // them, which is needed for uniquely determining an outer marker
5621
+ // when they overlap (they may nest, but not partially overlap).
5622
+ var nextMarkerId = 0
5623
+
5624
+ var TextMarker = function(doc, type) {
5625
+ this.lines = []
5626
+ this.type = type
5627
+ this.doc = doc
5628
+ this.id = ++nextMarkerId
5629
+ };
5630
+
5631
+ // Clear the marker.
5632
+ TextMarker.prototype.clear = function () {
5633
+ var this$1 = this;
5634
+
5635
+ if (this.explicitlyCleared) { return }
5636
+ var cm = this.doc.cm, withOp = cm && !cm.curOp
5637
+ if (withOp) { startOperation(cm) }
5638
+ if (hasHandler(this, "clear")) {
5639
+ var found = this.find()
5640
+ if (found) { signalLater(this, "clear", found.from, found.to) }
5641
+ }
5642
+ var min = null, max = null
5643
+ for (var i = 0; i < this.lines.length; ++i) {
5644
+ var line = this$1.lines[i]
5645
+ var span = getMarkedSpanFor(line.markedSpans, this$1)
5646
+ if (cm && !this$1.collapsed) { regLineChange(cm, lineNo(line), "text") }
5647
+ else if (cm) {
5648
+ if (span.to != null) { max = lineNo(line) }
5649
+ if (span.from != null) { min = lineNo(line) }
5650
+ }
5651
+ line.markedSpans = removeMarkedSpan(line.markedSpans, span)
5652
+ if (span.from == null && this$1.collapsed && !lineIsHidden(this$1.doc, line) && cm)
5653
+ { updateLineHeight(line, textHeight(cm.display)) }
5654
+ }
5655
+ if (cm && this.collapsed && !cm.options.lineWrapping) { for (var i$1 = 0; i$1 < this.lines.length; ++i$1) {
5656
+ var visual = visualLine(this$1.lines[i$1]), len = lineLength(visual)
5657
+ if (len > cm.display.maxLineLength) {
5658
+ cm.display.maxLine = visual
5659
+ cm.display.maxLineLength = len
5660
+ cm.display.maxLineChanged = true
5661
+ }
5662
+ } }
5663
+
5664
+ if (min != null && cm && this.collapsed) { regChange(cm, min, max + 1) }
5665
+ this.lines.length = 0
5666
+ this.explicitlyCleared = true
5667
+ if (this.atomic && this.doc.cantEdit) {
5668
+ this.doc.cantEdit = false
5669
+ if (cm) { reCheckSelection(cm.doc) }
5670
+ }
5671
+ if (cm) { signalLater(cm, "markerCleared", cm, this, min, max) }
5672
+ if (withOp) { endOperation(cm) }
5673
+ if (this.parent) { this.parent.clear() }
5674
+ };
5675
+
5676
+ // Find the position of the marker in the document. Returns a {from,
5677
+ // to} object by default. Side can be passed to get a specific side
5678
+ // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the
5679
+ // Pos objects returned contain a line object, rather than a line
5680
+ // number (used to prevent looking up the same line twice).
5681
+ TextMarker.prototype.find = function (side, lineObj) {
5682
+ var this$1 = this;
5683
+
5684
+ if (side == null && this.type == "bookmark") { side = 1 }
5685
+ var from, to
5686
+ for (var i = 0; i < this.lines.length; ++i) {
5687
+ var line = this$1.lines[i]
5688
+ var span = getMarkedSpanFor(line.markedSpans, this$1)
5689
+ if (span.from != null) {
5690
+ from = Pos(lineObj ? line : lineNo(line), span.from)
5691
+ if (side == -1) { return from }
5692
+ }
5693
+ if (span.to != null) {
5694
+ to = Pos(lineObj ? line : lineNo(line), span.to)
5695
+ if (side == 1) { return to }
5696
+ }
5697
+ }
5698
+ return from && {from: from, to: to}
5699
+ };
5700
+
5701
+ // Signals that the marker's widget changed, and surrounding layout
5702
+ // should be recomputed.
5703
+ TextMarker.prototype.changed = function () {
5704
+ var this$1 = this;
5705
+
5706
+ var pos = this.find(-1, true), widget = this, cm = this.doc.cm
5707
+ if (!pos || !cm) { return }
5708
+ runInOp(cm, function () {
5709
+ var line = pos.line, lineN = lineNo(pos.line)
5710
+ var view = findViewForLine(cm, lineN)
5711
+ if (view) {
5712
+ clearLineMeasurementCacheFor(view)
5713
+ cm.curOp.selectionChanged = cm.curOp.forceUpdate = true
5714
+ }
5715
+ cm.curOp.updateMaxLine = true
5716
+ if (!lineIsHidden(widget.doc, line) && widget.height != null) {
5717
+ var oldHeight = widget.height
5718
+ widget.height = null
5719
+ var dHeight = widgetHeight(widget) - oldHeight
5720
+ if (dHeight)
5721
+ { updateLineHeight(line, line.height + dHeight) }
5722
+ }
5723
+ signalLater(cm, "markerChanged", cm, this$1)
5724
+ })
5725
+ };
5726
+
5727
+ TextMarker.prototype.attachLine = function (line) {
5728
+ if (!this.lines.length && this.doc.cm) {
5729
+ var op = this.doc.cm.curOp
5730
+ if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)
5731
+ { (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this) }
5732
+ }
5733
+ this.lines.push(line)
5734
+ };
5735
+
5736
+ TextMarker.prototype.detachLine = function (line) {
5737
+ this.lines.splice(indexOf(this.lines, line), 1)
5738
+ if (!this.lines.length && this.doc.cm) {
5739
+ var op = this.doc.cm.curOp
5740
+ ;(op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this)
5741
+ }
5742
+ };
5743
+ eventMixin(TextMarker)
5744
+
5745
+ // Create a marker, wire it up to the right lines, and
5746
+ function markText(doc, from, to, options, type) {
5747
+ // Shared markers (across linked documents) are handled separately
5748
+ // (markTextShared will call out to this again, once per
5749
+ // document).
5750
+ if (options && options.shared) { return markTextShared(doc, from, to, options, type) }
5751
+ // Ensure we are in an operation.
5752
+ if (doc.cm && !doc.cm.curOp) { return operation(doc.cm, markText)(doc, from, to, options, type) }
5753
+
5754
+ var marker = new TextMarker(doc, type), diff = cmp(from, to)
5755
+ if (options) { copyObj(options, marker, false) }
5756
+ // Don't connect empty markers unless clearWhenEmpty is false
5757
+ if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false)
5758
+ { return marker }
5759
+ if (marker.replacedWith) {
5760
+ // Showing up as a widget implies collapsed (widget replaces text)
5761
+ marker.collapsed = true
5762
+ marker.widgetNode = eltP("span", [marker.replacedWith], "CodeMirror-widget")
5763
+ if (!options.handleMouseEvents) { marker.widgetNode.setAttribute("cm-ignore-events", "true") }
5764
+ if (options.insertLeft) { marker.widgetNode.insertLeft = true }
5765
+ }
5766
+ if (marker.collapsed) {
5767
+ if (conflictingCollapsedRange(doc, from.line, from, to, marker) ||
5768
+ from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker))
5769
+ { throw new Error("Inserting collapsed marker partially overlapping an existing one") }
5770
+ seeCollapsedSpans()
5771
+ }
5772
+
5773
+ if (marker.addToHistory)
5774
+ { addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN) }
5775
+
5776
+ var curLine = from.line, cm = doc.cm, updateMaxLine
5777
+ doc.iter(curLine, to.line + 1, function (line) {
5778
+ if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine)
5779
+ { updateMaxLine = true }
5780
+ if (marker.collapsed && curLine != from.line) { updateLineHeight(line, 0) }
5781
+ addMarkedSpan(line, new MarkedSpan(marker,
5782
+ curLine == from.line ? from.ch : null,
5783
+ curLine == to.line ? to.ch : null))
5784
+ ++curLine
5785
+ })
5786
+ // lineIsHidden depends on the presence of the spans, so needs a second pass
5787
+ if (marker.collapsed) { doc.iter(from.line, to.line + 1, function (line) {
5788
+ if (lineIsHidden(doc, line)) { updateLineHeight(line, 0) }
5789
+ }) }
5790
+
5791
+ if (marker.clearOnEnter) { on(marker, "beforeCursorEnter", function () { return marker.clear(); }) }
5792
+
5793
+ if (marker.readOnly) {
5794
+ seeReadOnlySpans()
5795
+ if (doc.history.done.length || doc.history.undone.length)
5796
+ { doc.clearHistory() }
5797
+ }
5798
+ if (marker.collapsed) {
5799
+ marker.id = ++nextMarkerId
5800
+ marker.atomic = true
5801
+ }
5802
+ if (cm) {
5803
+ // Sync editor state
5804
+ if (updateMaxLine) { cm.curOp.updateMaxLine = true }
5805
+ if (marker.collapsed)
5806
+ { regChange(cm, from.line, to.line + 1) }
5807
+ else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css)
5808
+ { for (var i = from.line; i <= to.line; i++) { regLineChange(cm, i, "text") } }
5809
+ if (marker.atomic) { reCheckSelection(cm.doc) }
5810
+ signalLater(cm, "markerAdded", cm, marker)
5811
+ }
5812
+ return marker
5813
+ }
5814
+
5815
+ // SHARED TEXTMARKERS
5816
+
5817
+ // A shared marker spans multiple linked documents. It is
5818
+ // implemented as a meta-marker-object controlling multiple normal
5819
+ // markers.
5820
+ var SharedTextMarker = function(markers, primary) {
5821
+ var this$1 = this;
5822
+
5823
+ this.markers = markers
5824
+ this.primary = primary
5825
+ for (var i = 0; i < markers.length; ++i)
5826
+ { markers[i].parent = this$1 }
5827
+ };
5828
+
5829
+ SharedTextMarker.prototype.clear = function () {
5830
+ var this$1 = this;
5831
+
5832
+ if (this.explicitlyCleared) { return }
5833
+ this.explicitlyCleared = true
5834
+ for (var i = 0; i < this.markers.length; ++i)
5835
+ { this$1.markers[i].clear() }
5836
+ signalLater(this, "clear")
5837
+ };
5838
+
5839
+ SharedTextMarker.prototype.find = function (side, lineObj) {
5840
+ return this.primary.find(side, lineObj)
5841
+ };
5842
+ eventMixin(SharedTextMarker)
5843
+
5844
+ function markTextShared(doc, from, to, options, type) {
5845
+ options = copyObj(options)
5846
+ options.shared = false
5847
+ var markers = [markText(doc, from, to, options, type)], primary = markers[0]
5848
+ var widget = options.widgetNode
5849
+ linkedDocs(doc, function (doc) {
5850
+ if (widget) { options.widgetNode = widget.cloneNode(true) }
5851
+ markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type))
5852
+ for (var i = 0; i < doc.linked.length; ++i)
5853
+ { if (doc.linked[i].isParent) { return } }
5854
+ primary = lst(markers)
5855
+ })
5856
+ return new SharedTextMarker(markers, primary)
5857
+ }
5858
+
5859
+ function findSharedMarkers(doc) {
5860
+ return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), function (m) { return m.parent; })
5861
+ }
5862
+
5863
+ function copySharedMarkers(doc, markers) {
5864
+ for (var i = 0; i < markers.length; i++) {
5865
+ var marker = markers[i], pos = marker.find()
5866
+ var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to)
5867
+ if (cmp(mFrom, mTo)) {
5868
+ var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type)
5869
+ marker.markers.push(subMark)
5870
+ subMark.parent = marker
5871
+ }
5872
+ }
5873
+ }
5874
+
5875
+ function detachSharedMarkers(markers) {
5876
+ var loop = function ( i ) {
5877
+ var marker = markers[i], linked = [marker.primary.doc]
5878
+ linkedDocs(marker.primary.doc, function (d) { return linked.push(d); })
5879
+ for (var j = 0; j < marker.markers.length; j++) {
5880
+ var subMarker = marker.markers[j]
5881
+ if (indexOf(linked, subMarker.doc) == -1) {
5882
+ subMarker.parent = null
5883
+ marker.markers.splice(j--, 1)
5884
+ }
5885
+ }
5886
+ };
5887
+
5888
+ for (var i = 0; i < markers.length; i++) loop( i );
5889
+ }
5890
+
5891
+ var nextDocId = 0
5892
+ var Doc = function(text, mode, firstLine, lineSep, direction) {
5893
+ if (!(this instanceof Doc)) { return new Doc(text, mode, firstLine, lineSep, direction) }
5894
+ if (firstLine == null) { firstLine = 0 }
5895
+
5896
+ BranchChunk.call(this, [new LeafChunk([new Line("", null)])])
5897
+ this.first = firstLine
5898
+ this.scrollTop = this.scrollLeft = 0
5899
+ this.cantEdit = false
5900
+ this.cleanGeneration = 1
5901
+ this.frontier = firstLine
5902
+ var start = Pos(firstLine, 0)
5903
+ this.sel = simpleSelection(start)
5904
+ this.history = new History(null)
5905
+ this.id = ++nextDocId
5906
+ this.modeOption = mode
5907
+ this.lineSep = lineSep
5908
+ this.direction = (direction == "rtl") ? "rtl" : "ltr"
5909
+ this.extend = false
5910
+
5911
+ if (typeof text == "string") { text = this.splitLines(text) }
5912
+ updateDoc(this, {from: start, to: start, text: text})
5913
+ setSelection(this, simpleSelection(start), sel_dontScroll)
5914
+ }
5915
+
5916
+ Doc.prototype = createObj(BranchChunk.prototype, {
5917
+ constructor: Doc,
5918
+ // Iterate over the document. Supports two forms -- with only one
5919
+ // argument, it calls that for each line in the document. With
5920
+ // three, it iterates over the range given by the first two (with
5921
+ // the second being non-inclusive).
5922
+ iter: function(from, to, op) {
5923
+ if (op) { this.iterN(from - this.first, to - from, op) }
5924
+ else { this.iterN(this.first, this.first + this.size, from) }
5925
+ },
5926
+
5927
+ // Non-public interface for adding and removing lines.
5928
+ insert: function(at, lines) {
5929
+ var height = 0
5930
+ for (var i = 0; i < lines.length; ++i) { height += lines[i].height }
5931
+ this.insertInner(at - this.first, lines, height)
5932
+ },
5933
+ remove: function(at, n) { this.removeInner(at - this.first, n) },
5934
+
5935
+ // From here, the methods are part of the public interface. Most
5936
+ // are also available from CodeMirror (editor) instances.
5937
+
5938
+ getValue: function(lineSep) {
5939
+ var lines = getLines(this, this.first, this.first + this.size)
5940
+ if (lineSep === false) { return lines }
5941
+ return lines.join(lineSep || this.lineSeparator())
5942
+ },
5943
+ setValue: docMethodOp(function(code) {
5944
+ var top = Pos(this.first, 0), last = this.first + this.size - 1
5945
+ makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
5946
+ text: this.splitLines(code), origin: "setValue", full: true}, true)
5947
+ if (this.cm) { scrollToCoords(this.cm, 0, 0) }
5948
+ setSelection(this, simpleSelection(top), sel_dontScroll)
5949
+ }),
5950
+ replaceRange: function(code, from, to, origin) {
5951
+ from = clipPos(this, from)
5952
+ to = to ? clipPos(this, to) : from
5953
+ replaceRange(this, code, from, to, origin)
5954
+ },
5955
+ getRange: function(from, to, lineSep) {
5956
+ var lines = getBetween(this, clipPos(this, from), clipPos(this, to))
5957
+ if (lineSep === false) { return lines }
5958
+ return lines.join(lineSep || this.lineSeparator())
5959
+ },
5960
+
5961
+ getLine: function(line) {var l = this.getLineHandle(line); return l && l.text},
5962
+
5963
+ getLineHandle: function(line) {if (isLine(this, line)) { return getLine(this, line) }},
5964
+ getLineNumber: function(line) {return lineNo(line)},
5965
+
5966
+ getLineHandleVisualStart: function(line) {
5967
+ if (typeof line == "number") { line = getLine(this, line) }
5968
+ return visualLine(line)
5969
+ },
5970
+
5971
+ lineCount: function() {return this.size},
5972
+ firstLine: function() {return this.first},
5973
+ lastLine: function() {return this.first + this.size - 1},
5974
+
5975
+ clipPos: function(pos) {return clipPos(this, pos)},
5976
+
5977
+ getCursor: function(start) {
5978
+ var range = this.sel.primary(), pos
5979
+ if (start == null || start == "head") { pos = range.head }
5980
+ else if (start == "anchor") { pos = range.anchor }
5981
+ else if (start == "end" || start == "to" || start === false) { pos = range.to() }
5982
+ else { pos = range.from() }
5983
+ return pos
5984
+ },
5985
+ listSelections: function() { return this.sel.ranges },
5986
+ somethingSelected: function() {return this.sel.somethingSelected()},
5987
+
5988
+ setCursor: docMethodOp(function(line, ch, options) {
5989
+ setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options)
5990
+ }),
5991
+ setSelection: docMethodOp(function(anchor, head, options) {
5992
+ setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options)
5993
+ }),
5994
+ extendSelection: docMethodOp(function(head, other, options) {
5995
+ extendSelection(this, clipPos(this, head), other && clipPos(this, other), options)
5996
+ }),
5997
+ extendSelections: docMethodOp(function(heads, options) {
5998
+ extendSelections(this, clipPosArray(this, heads), options)
5999
+ }),
6000
+ extendSelectionsBy: docMethodOp(function(f, options) {
6001
+ var heads = map(this.sel.ranges, f)
6002
+ extendSelections(this, clipPosArray(this, heads), options)
6003
+ }),
6004
+ setSelections: docMethodOp(function(ranges, primary, options) {
6005
+ var this$1 = this;
6006
+
6007
+ if (!ranges.length) { return }
6008
+ var out = []
6009
+ for (var i = 0; i < ranges.length; i++)
6010
+ { out[i] = new Range(clipPos(this$1, ranges[i].anchor),
6011
+ clipPos(this$1, ranges[i].head)) }
6012
+ if (primary == null) { primary = Math.min(ranges.length - 1, this.sel.primIndex) }
6013
+ setSelection(this, normalizeSelection(out, primary), options)
6014
+ }),
6015
+ addSelection: docMethodOp(function(anchor, head, options) {
6016
+ var ranges = this.sel.ranges.slice(0)
6017
+ ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor)))
6018
+ setSelection(this, normalizeSelection(ranges, ranges.length - 1), options)
6019
+ }),
6020
+
6021
+ getSelection: function(lineSep) {
6022
+ var this$1 = this;
6023
+
6024
+ var ranges = this.sel.ranges, lines
6025
+ for (var i = 0; i < ranges.length; i++) {
6026
+ var sel = getBetween(this$1, ranges[i].from(), ranges[i].to())
6027
+ lines = lines ? lines.concat(sel) : sel
6028
+ }
6029
+ if (lineSep === false) { return lines }
6030
+ else { return lines.join(lineSep || this.lineSeparator()) }
6031
+ },
6032
+ getSelections: function(lineSep) {
6033
+ var this$1 = this;
6034
+
6035
+ var parts = [], ranges = this.sel.ranges
6036
+ for (var i = 0; i < ranges.length; i++) {
6037
+ var sel = getBetween(this$1, ranges[i].from(), ranges[i].to())
6038
+ if (lineSep !== false) { sel = sel.join(lineSep || this$1.lineSeparator()) }
6039
+ parts[i] = sel
6040
+ }
6041
+ return parts
6042
+ },
6043
+ replaceSelection: function(code, collapse, origin) {
6044
+ var dup = []
6045
+ for (var i = 0; i < this.sel.ranges.length; i++)
6046
+ { dup[i] = code }
6047
+ this.replaceSelections(dup, collapse, origin || "+input")
6048
+ },
6049
+ replaceSelections: docMethodOp(function(code, collapse, origin) {
6050
+ var this$1 = this;
6051
+
6052
+ var changes = [], sel = this.sel
6053
+ for (var i = 0; i < sel.ranges.length; i++) {
6054
+ var range = sel.ranges[i]
6055
+ changes[i] = {from: range.from(), to: range.to(), text: this$1.splitLines(code[i]), origin: origin}
6056
+ }
6057
+ var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse)
6058
+ for (var i$1 = changes.length - 1; i$1 >= 0; i$1--)
6059
+ { makeChange(this$1, changes[i$1]) }
6060
+ if (newSel) { setSelectionReplaceHistory(this, newSel) }
6061
+ else if (this.cm) { ensureCursorVisible(this.cm) }
6062
+ }),
6063
+ undo: docMethodOp(function() {makeChangeFromHistory(this, "undo")}),
6064
+ redo: docMethodOp(function() {makeChangeFromHistory(this, "redo")}),
6065
+ undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true)}),
6066
+ redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true)}),
6067
+
6068
+ setExtending: function(val) {this.extend = val},
6069
+ getExtending: function() {return this.extend},
6070
+
6071
+ historySize: function() {
6072
+ var hist = this.history, done = 0, undone = 0
6073
+ for (var i = 0; i < hist.done.length; i++) { if (!hist.done[i].ranges) { ++done } }
6074
+ for (var i$1 = 0; i$1 < hist.undone.length; i$1++) { if (!hist.undone[i$1].ranges) { ++undone } }
6075
+ return {undo: done, redo: undone}
6076
+ },
6077
+ clearHistory: function() {this.history = new History(this.history.maxGeneration)},
6078
+
6079
+ markClean: function() {
6080
+ this.cleanGeneration = this.changeGeneration(true)
6081
+ },
6082
+ changeGeneration: function(forceSplit) {
6083
+ if (forceSplit)
6084
+ { this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null }
6085
+ return this.history.generation
6086
+ },
6087
+ isClean: function (gen) {
6088
+ return this.history.generation == (gen || this.cleanGeneration)
6089
+ },
6090
+
6091
+ getHistory: function() {
6092
+ return {done: copyHistoryArray(this.history.done),
6093
+ undone: copyHistoryArray(this.history.undone)}
6094
+ },
6095
+ setHistory: function(histData) {
6096
+ var hist = this.history = new History(this.history.maxGeneration)
6097
+ hist.done = copyHistoryArray(histData.done.slice(0), null, true)
6098
+ hist.undone = copyHistoryArray(histData.undone.slice(0), null, true)
6099
+ },
6100
+
6101
+ setGutterMarker: docMethodOp(function(line, gutterID, value) {
6102
+ return changeLine(this, line, "gutter", function (line) {
6103
+ var markers = line.gutterMarkers || (line.gutterMarkers = {})
6104
+ markers[gutterID] = value
6105
+ if (!value && isEmpty(markers)) { line.gutterMarkers = null }
6106
+ return true
6107
+ })
6108
+ }),
6109
+
6110
+ clearGutter: docMethodOp(function(gutterID) {
6111
+ var this$1 = this;
6112
+
6113
+ this.iter(function (line) {
6114
+ if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
6115
+ changeLine(this$1, line, "gutter", function () {
6116
+ line.gutterMarkers[gutterID] = null
6117
+ if (isEmpty(line.gutterMarkers)) { line.gutterMarkers = null }
6118
+ return true
6119
+ })
6120
+ }
6121
+ })
6122
+ }),
6123
+
6124
+ lineInfo: function(line) {
6125
+ var n
6126
+ if (typeof line == "number") {
6127
+ if (!isLine(this, line)) { return null }
6128
+ n = line
6129
+ line = getLine(this, line)
6130
+ if (!line) { return null }
6131
+ } else {
6132
+ n = lineNo(line)
6133
+ if (n == null) { return null }
6134
+ }
6135
+ return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,
6136
+ textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,
6137
+ widgets: line.widgets}
6138
+ },
6139
+
6140
+ addLineClass: docMethodOp(function(handle, where, cls) {
6141
+ return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) {
6142
+ var prop = where == "text" ? "textClass"
6143
+ : where == "background" ? "bgClass"
6144
+ : where == "gutter" ? "gutterClass" : "wrapClass"
6145
+ if (!line[prop]) { line[prop] = cls }
6146
+ else if (classTest(cls).test(line[prop])) { return false }
6147
+ else { line[prop] += " " + cls }
6148
+ return true
6149
+ })
6150
+ }),
6151
+ removeLineClass: docMethodOp(function(handle, where, cls) {
6152
+ return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) {
6153
+ var prop = where == "text" ? "textClass"
6154
+ : where == "background" ? "bgClass"
6155
+ : where == "gutter" ? "gutterClass" : "wrapClass"
6156
+ var cur = line[prop]
6157
+ if (!cur) { return false }
6158
+ else if (cls == null) { line[prop] = null }
6159
+ else {
6160
+ var found = cur.match(classTest(cls))
6161
+ if (!found) { return false }
6162
+ var end = found.index + found[0].length
6163
+ line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null
6164
+ }
6165
+ return true
6166
+ })
6167
+ }),
6168
+
6169
+ addLineWidget: docMethodOp(function(handle, node, options) {
6170
+ return addLineWidget(this, handle, node, options)
6171
+ }),
6172
+ removeLineWidget: function(widget) { widget.clear() },
6173
+
6174
+ markText: function(from, to, options) {
6175
+ return markText(this, clipPos(this, from), clipPos(this, to), options, options && options.type || "range")
6176
+ },
6177
+ setBookmark: function(pos, options) {
6178
+ var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
6179
+ insertLeft: options && options.insertLeft,
6180
+ clearWhenEmpty: false, shared: options && options.shared,
6181
+ handleMouseEvents: options && options.handleMouseEvents}
6182
+ pos = clipPos(this, pos)
6183
+ return markText(this, pos, pos, realOpts, "bookmark")
6184
+ },
6185
+ findMarksAt: function(pos) {
6186
+ pos = clipPos(this, pos)
6187
+ var markers = [], spans = getLine(this, pos.line).markedSpans
6188
+ if (spans) { for (var i = 0; i < spans.length; ++i) {
6189
+ var span = spans[i]
6190
+ if ((span.from == null || span.from <= pos.ch) &&
6191
+ (span.to == null || span.to >= pos.ch))
6192
+ { markers.push(span.marker.parent || span.marker) }
6193
+ } }
6194
+ return markers
6195
+ },
6196
+ findMarks: function(from, to, filter) {
6197
+ from = clipPos(this, from); to = clipPos(this, to)
6198
+ var found = [], lineNo = from.line
6199
+ this.iter(from.line, to.line + 1, function (line) {
6200
+ var spans = line.markedSpans
6201
+ if (spans) { for (var i = 0; i < spans.length; i++) {
6202
+ var span = spans[i]
6203
+ if (!(span.to != null && lineNo == from.line && from.ch >= span.to ||
6204
+ span.from == null && lineNo != from.line ||
6205
+ span.from != null && lineNo == to.line && span.from >= to.ch) &&
6206
+ (!filter || filter(span.marker)))
6207
+ { found.push(span.marker.parent || span.marker) }
6208
+ } }
6209
+ ++lineNo
6210
+ })
6211
+ return found
6212
+ },
6213
+ getAllMarks: function() {
6214
+ var markers = []
6215
+ this.iter(function (line) {
6216
+ var sps = line.markedSpans
6217
+ if (sps) { for (var i = 0; i < sps.length; ++i)
6218
+ { if (sps[i].from != null) { markers.push(sps[i].marker) } } }
6219
+ })
6220
+ return markers
6221
+ },
6222
+
6223
+ posFromIndex: function(off) {
6224
+ var ch, lineNo = this.first, sepSize = this.lineSeparator().length
6225
+ this.iter(function (line) {
6226
+ var sz = line.text.length + sepSize
6227
+ if (sz > off) { ch = off; return true }
6228
+ off -= sz
6229
+ ++lineNo
6230
+ })
6231
+ return clipPos(this, Pos(lineNo, ch))
6232
+ },
6233
+ indexFromPos: function (coords) {
6234
+ coords = clipPos(this, coords)
6235
+ var index = coords.ch
6236
+ if (coords.line < this.first || coords.ch < 0) { return 0 }
6237
+ var sepSize = this.lineSeparator().length
6238
+ this.iter(this.first, coords.line, function (line) { // iter aborts when callback returns a truthy value
6239
+ index += line.text.length + sepSize
6240
+ })
6241
+ return index
6242
+ },
6243
+
6244
+ copy: function(copyHistory) {
6245
+ var doc = new Doc(getLines(this, this.first, this.first + this.size),
6246
+ this.modeOption, this.first, this.lineSep, this.direction)
6247
+ doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft
6248
+ doc.sel = this.sel
6249
+ doc.extend = false
6250
+ if (copyHistory) {
6251
+ doc.history.undoDepth = this.history.undoDepth
6252
+ doc.setHistory(this.getHistory())
6253
+ }
6254
+ return doc
6255
+ },
6256
+
6257
+ linkedDoc: function(options) {
6258
+ if (!options) { options = {} }
6259
+ var from = this.first, to = this.first + this.size
6260
+ if (options.from != null && options.from > from) { from = options.from }
6261
+ if (options.to != null && options.to < to) { to = options.to }
6262
+ var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep, this.direction)
6263
+ if (options.sharedHist) { copy.history = this.history
6264
+ ; }(this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist})
6265
+ copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}]
6266
+ copySharedMarkers(copy, findSharedMarkers(this))
6267
+ return copy
6268
+ },
6269
+ unlinkDoc: function(other) {
6270
+ var this$1 = this;
6271
+
6272
+ if (other instanceof CodeMirror) { other = other.doc }
6273
+ if (this.linked) { for (var i = 0; i < this.linked.length; ++i) {
6274
+ var link = this$1.linked[i]
6275
+ if (link.doc != other) { continue }
6276
+ this$1.linked.splice(i, 1)
6277
+ other.unlinkDoc(this$1)
6278
+ detachSharedMarkers(findSharedMarkers(this$1))
6279
+ break
6280
+ } }
6281
+ // If the histories were shared, split them again
6282
+ if (other.history == this.history) {
6283
+ var splitIds = [other.id]
6284
+ linkedDocs(other, function (doc) { return splitIds.push(doc.id); }, true)
6285
+ other.history = new History(null)
6286
+ other.history.done = copyHistoryArray(this.history.done, splitIds)
6287
+ other.history.undone = copyHistoryArray(this.history.undone, splitIds)
6288
+ }
6289
+ },
6290
+ iterLinkedDocs: function(f) {linkedDocs(this, f)},
6291
+
6292
+ getMode: function() {return this.mode},
6293
+ getEditor: function() {return this.cm},
6294
+
6295
+ splitLines: function(str) {
6296
+ if (this.lineSep) { return str.split(this.lineSep) }
6297
+ return splitLinesAuto(str)
6298
+ },
6299
+ lineSeparator: function() { return this.lineSep || "\n" },
6300
+
6301
+ setDirection: docMethodOp(function (dir) {
6302
+ if (dir != "rtl") { dir = "ltr" }
6303
+ if (dir == this.direction) { return }
6304
+ this.direction = dir
6305
+ this.iter(function (line) { return line.order = null; })
6306
+ if (this.cm) { directionChanged(this.cm) }
6307
+ })
6308
+ })
6309
+
6310
+ // Public alias.
6311
+ Doc.prototype.eachLine = Doc.prototype.iter
6312
+
6313
+ // Kludge to work around strange IE behavior where it'll sometimes
6314
+ // re-fire a series of drag-related events right after the drop (#1551)
6315
+ var lastDrop = 0
6316
+
6317
+ function onDrop(e) {
6318
+ var cm = this
6319
+ clearDragCursor(cm)
6320
+ if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))
6321
+ { return }
6322
+ e_preventDefault(e)
6323
+ if (ie) { lastDrop = +new Date }
6324
+ var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files
6325
+ if (!pos || cm.isReadOnly()) { return }
6326
+ // Might be a file drop, in which case we simply extract the text
6327
+ // and insert it.
6328
+ if (files && files.length && window.FileReader && window.File) {
6329
+ var n = files.length, text = Array(n), read = 0
6330
+ var loadFile = function (file, i) {
6331
+ if (cm.options.allowDropFileTypes &&
6332
+ indexOf(cm.options.allowDropFileTypes, file.type) == -1)
6333
+ { return }
6334
+
6335
+ var reader = new FileReader
6336
+ reader.onload = operation(cm, function () {
6337
+ var content = reader.result
6338
+ if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) { content = "" }
6339
+ text[i] = content
6340
+ if (++read == n) {
6341
+ pos = clipPos(cm.doc, pos)
6342
+ var change = {from: pos, to: pos,
6343
+ text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())),
6344
+ origin: "paste"}
6345
+ makeChange(cm.doc, change)
6346
+ setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)))
6347
+ }
6348
+ })
6349
+ reader.readAsText(file)
6350
+ }
6351
+ for (var i = 0; i < n; ++i) { loadFile(files[i], i) }
6352
+ } else { // Normal drop
6353
+ // Don't do a replace if the drop happened inside of the selected text.
6354
+ if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) {
6355
+ cm.state.draggingText(e)
6356
+ // Ensure the editor is re-focused
6357
+ setTimeout(function () { return cm.display.input.focus(); }, 20)
6358
+ return
6359
+ }
6360
+ try {
6361
+ var text$1 = e.dataTransfer.getData("Text")
6362
+ if (text$1) {
6363
+ var selected
6364
+ if (cm.state.draggingText && !cm.state.draggingText.copy)
6365
+ { selected = cm.listSelections() }
6366
+ setSelectionNoUndo(cm.doc, simpleSelection(pos, pos))
6367
+ if (selected) { for (var i$1 = 0; i$1 < selected.length; ++i$1)
6368
+ { replaceRange(cm.doc, "", selected[i$1].anchor, selected[i$1].head, "drag") } }
6369
+ cm.replaceSelection(text$1, "around", "paste")
6370
+ cm.display.input.focus()
6371
+ }
6372
+ }
6373
+ catch(e){}
6374
+ }
6375
+ }
6376
+
6377
+ function onDragStart(cm, e) {
6378
+ if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return }
6379
+ if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) { return }
6380
+
6381
+ e.dataTransfer.setData("Text", cm.getSelection())
6382
+ e.dataTransfer.effectAllowed = "copyMove"
6383
+
6384
+ // Use dummy image instead of default browsers image.
6385
+ // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
6386
+ if (e.dataTransfer.setDragImage && !safari) {
6387
+ var img = elt("img", null, null, "position: fixed; left: 0; top: 0;")
6388
+ img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
6389
+ if (presto) {
6390
+ img.width = img.height = 1
6391
+ cm.display.wrapper.appendChild(img)
6392
+ // Force a relayout, or Opera won't use our image for some obscure reason
6393
+ img._top = img.offsetTop
6394
+ }
6395
+ e.dataTransfer.setDragImage(img, 0, 0)
6396
+ if (presto) { img.parentNode.removeChild(img) }
6397
+ }
6398
+ }
6399
+
6400
+ function onDragOver(cm, e) {
6401
+ var pos = posFromMouse(cm, e)
6402
+ if (!pos) { return }
6403
+ var frag = document.createDocumentFragment()
6404
+ drawSelectionCursor(cm, pos, frag)
6405
+ if (!cm.display.dragCursor) {
6406
+ cm.display.dragCursor = elt("div", null, "CodeMirror-cursors CodeMirror-dragcursors")
6407
+ cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv)
6408
+ }
6409
+ removeChildrenAndAdd(cm.display.dragCursor, frag)
6410
+ }
6411
+
6412
+ function clearDragCursor(cm) {
6413
+ if (cm.display.dragCursor) {
6414
+ cm.display.lineSpace.removeChild(cm.display.dragCursor)
6415
+ cm.display.dragCursor = null
6416
+ }
6417
+ }
6418
+
6419
+ // These must be handled carefully, because naively registering a
6420
+ // handler for each editor will cause the editors to never be
6421
+ // garbage collected.
6422
+
6423
+ function forEachCodeMirror(f) {
6424
+ if (!document.body.getElementsByClassName) { return }
6425
+ var byClass = document.body.getElementsByClassName("CodeMirror")
6426
+ for (var i = 0; i < byClass.length; i++) {
6427
+ var cm = byClass[i].CodeMirror
6428
+ if (cm) { f(cm) }
6429
+ }
6430
+ }
6431
+
6432
+ var globalsRegistered = false
6433
+ function ensureGlobalHandlers() {
6434
+ if (globalsRegistered) { return }
6435
+ registerGlobalHandlers()
6436
+ globalsRegistered = true
6437
+ }
6438
+ function registerGlobalHandlers() {
6439
+ // When the window resizes, we need to refresh active editors.
6440
+ var resizeTimer
6441
+ on(window, "resize", function () {
6442
+ if (resizeTimer == null) { resizeTimer = setTimeout(function () {
6443
+ resizeTimer = null
6444
+ forEachCodeMirror(onResize)
6445
+ }, 100) }
6446
+ })
6447
+ // When the window loses focus, we want to show the editor as blurred
6448
+ on(window, "blur", function () { return forEachCodeMirror(onBlur); })
6449
+ }
6450
+ // Called when the window resizes
6451
+ function onResize(cm) {
6452
+ var d = cm.display
6453
+ if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth)
6454
+ { return }
6455
+ // Might be a text scaling operation, clear size caches.
6456
+ d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null
6457
+ d.scrollbarsClipped = false
6458
+ cm.setSize()
6459
+ }
6460
+
6461
+ var keyNames = {
6462
+ 3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
6463
+ 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
6464
+ 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
6465
+ 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod",
6466
+ 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete",
6467
+ 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
6468
+ 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
6469
+ 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"
6470
+ }
6471
+
6472
+ // Number keys
6473
+ for (var i = 0; i < 10; i++) { keyNames[i + 48] = keyNames[i + 96] = String(i) }
6474
+ // Alphabetic keys
6475
+ for (var i$1 = 65; i$1 <= 90; i$1++) { keyNames[i$1] = String.fromCharCode(i$1) }
6476
+ // Function keys
6477
+ for (var i$2 = 1; i$2 <= 12; i$2++) { keyNames[i$2 + 111] = keyNames[i$2 + 63235] = "F" + i$2 }
6478
+
6479
+ var keyMap = {}
6480
+
6481
+ keyMap.basic = {
6482
+ "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
6483
+ "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
6484
+ "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore",
6485
+ "Tab": "defaultTab", "Shift-Tab": "indentAuto",
6486
+ "Enter": "newlineAndIndent", "Insert": "toggleOverwrite",
6487
+ "Esc": "singleSelection"
6488
+ }
6489
+ // Note that the save and find-related commands aren't defined by
6490
+ // default. User code or addons can define them. Unknown commands
6491
+ // are simply ignored.
6492
+ keyMap.pcDefault = {
6493
+ "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
6494
+ "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown",
6495
+ "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
6496
+ "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
6497
+ "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
6498
+ "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
6499
+ "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection",
6500
+ fallthrough: "basic"
6501
+ }
6502
+ // Very basic readline/emacs-style bindings, which are standard on Mac.
6503
+ keyMap.emacsy = {
6504
+ "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
6505
+ "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
6506
+ "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
6507
+ "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars",
6508
+ "Ctrl-O": "openLine"
6509
+ }
6510
+ keyMap.macDefault = {
6511
+ "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
6512
+ "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
6513
+ "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore",
6514
+ "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
6515
+ "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
6516
+ "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight",
6517
+ "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd",
6518
+ fallthrough: ["basic", "emacsy"]
6519
+ }
6520
+ keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault
6521
+
6522
+ // KEYMAP DISPATCH
6523
+
6524
+ function normalizeKeyName(name) {
6525
+ var parts = name.split(/-(?!$)/)
6526
+ name = parts[parts.length - 1]
6527
+ var alt, ctrl, shift, cmd
6528
+ for (var i = 0; i < parts.length - 1; i++) {
6529
+ var mod = parts[i]
6530
+ if (/^(cmd|meta|m)$/i.test(mod)) { cmd = true }
6531
+ else if (/^a(lt)?$/i.test(mod)) { alt = true }
6532
+ else if (/^(c|ctrl|control)$/i.test(mod)) { ctrl = true }
6533
+ else if (/^s(hift)?$/i.test(mod)) { shift = true }
6534
+ else { throw new Error("Unrecognized modifier name: " + mod) }
6535
+ }
6536
+ if (alt) { name = "Alt-" + name }
6537
+ if (ctrl) { name = "Ctrl-" + name }
6538
+ if (cmd) { name = "Cmd-" + name }
6539
+ if (shift) { name = "Shift-" + name }
6540
+ return name
6541
+ }
6542
+
6543
+ // This is a kludge to keep keymaps mostly working as raw objects
6544
+ // (backwards compatibility) while at the same time support features
6545
+ // like normalization and multi-stroke key bindings. It compiles a
6546
+ // new normalized keymap, and then updates the old object to reflect
6547
+ // this.
6548
+ function normalizeKeyMap(keymap) {
6549
+ var copy = {}
6550
+ for (var keyname in keymap) { if (keymap.hasOwnProperty(keyname)) {
6551
+ var value = keymap[keyname]
6552
+ if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) { continue }
6553
+ if (value == "...") { delete keymap[keyname]; continue }
6554
+
6555
+ var keys = map(keyname.split(" "), normalizeKeyName)
6556
+ for (var i = 0; i < keys.length; i++) {
6557
+ var val = (void 0), name = (void 0)
6558
+ if (i == keys.length - 1) {
6559
+ name = keys.join(" ")
6560
+ val = value
6561
+ } else {
6562
+ name = keys.slice(0, i + 1).join(" ")
6563
+ val = "..."
6564
+ }
6565
+ var prev = copy[name]
6566
+ if (!prev) { copy[name] = val }
6567
+ else if (prev != val) { throw new Error("Inconsistent bindings for " + name) }
6568
+ }
6569
+ delete keymap[keyname]
6570
+ } }
6571
+ for (var prop in copy) { keymap[prop] = copy[prop] }
6572
+ return keymap
6573
+ }
6574
+
6575
+ function lookupKey(key, map, handle, context) {
6576
+ map = getKeyMap(map)
6577
+ var found = map.call ? map.call(key, context) : map[key]
6578
+ if (found === false) { return "nothing" }
6579
+ if (found === "...") { return "multi" }
6580
+ if (found != null && handle(found)) { return "handled" }
6581
+
6582
+ if (map.fallthrough) {
6583
+ if (Object.prototype.toString.call(map.fallthrough) != "[object Array]")
6584
+ { return lookupKey(key, map.fallthrough, handle, context) }
6585
+ for (var i = 0; i < map.fallthrough.length; i++) {
6586
+ var result = lookupKey(key, map.fallthrough[i], handle, context)
6587
+ if (result) { return result }
6588
+ }
6589
+ }
6590
+ }
6591
+
6592
+ // Modifier key presses don't count as 'real' key presses for the
6593
+ // purpose of keymap fallthrough.
6594
+ function isModifierKey(value) {
6595
+ var name = typeof value == "string" ? value : keyNames[value.keyCode]
6596
+ return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod"
6597
+ }
6598
+
6599
+ // Look up the name of a key as indicated by an event object.
6600
+ function keyName(event, noShift) {
6601
+ if (presto && event.keyCode == 34 && event["char"]) { return false }
6602
+ var base = keyNames[event.keyCode], name = base
6603
+ if (name == null || event.altGraphKey) { return false }
6604
+ if (event.altKey && base != "Alt") { name = "Alt-" + name }
6605
+ if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") { name = "Ctrl-" + name }
6606
+ if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") { name = "Cmd-" + name }
6607
+ if (!noShift && event.shiftKey && base != "Shift") { name = "Shift-" + name }
6608
+ return name
6609
+ }
6610
+
6611
+ function getKeyMap(val) {
6612
+ return typeof val == "string" ? keyMap[val] : val
6613
+ }
6614
+
6615
+ // Helper for deleting text near the selection(s), used to implement
6616
+ // backspace, delete, and similar functionality.
6617
+ function deleteNearSelection(cm, compute) {
6618
+ var ranges = cm.doc.sel.ranges, kill = []
6619
+ // Build up a set of ranges to kill first, merging overlapping
6620
+ // ranges.
6621
+ for (var i = 0; i < ranges.length; i++) {
6622
+ var toKill = compute(ranges[i])
6623
+ while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) {
6624
+ var replaced = kill.pop()
6625
+ if (cmp(replaced.from, toKill.from) < 0) {
6626
+ toKill.from = replaced.from
6627
+ break
6628
+ }
6629
+ }
6630
+ kill.push(toKill)
6631
+ }
6632
+ // Next, remove those actual ranges.
6633
+ runInOp(cm, function () {
6634
+ for (var i = kill.length - 1; i >= 0; i--)
6635
+ { replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete") }
6636
+ ensureCursorVisible(cm)
6637
+ })
6638
+ }
6639
+
6640
+ // Commands are parameter-less actions that can be performed on an
6641
+ // editor, mostly used for keybindings.
6642
+ var commands = {
6643
+ selectAll: selectAll,
6644
+ singleSelection: function (cm) { return cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll); },
6645
+ killLine: function (cm) { return deleteNearSelection(cm, function (range) {
6646
+ if (range.empty()) {
6647
+ var len = getLine(cm.doc, range.head.line).text.length
6648
+ if (range.head.ch == len && range.head.line < cm.lastLine())
6649
+ { return {from: range.head, to: Pos(range.head.line + 1, 0)} }
6650
+ else
6651
+ { return {from: range.head, to: Pos(range.head.line, len)} }
6652
+ } else {
6653
+ return {from: range.from(), to: range.to()}
6654
+ }
6655
+ }); },
6656
+ deleteLine: function (cm) { return deleteNearSelection(cm, function (range) { return ({
6657
+ from: Pos(range.from().line, 0),
6658
+ to: clipPos(cm.doc, Pos(range.to().line + 1, 0))
6659
+ }); }); },
6660
+ delLineLeft: function (cm) { return deleteNearSelection(cm, function (range) { return ({
6661
+ from: Pos(range.from().line, 0), to: range.from()
6662
+ }); }); },
6663
+ delWrappedLineLeft: function (cm) { return deleteNearSelection(cm, function (range) {
6664
+ var top = cm.charCoords(range.head, "div").top + 5
6665
+ var leftPos = cm.coordsChar({left: 0, top: top}, "div")
6666
+ return {from: leftPos, to: range.from()}
6667
+ }); },
6668
+ delWrappedLineRight: function (cm) { return deleteNearSelection(cm, function (range) {
6669
+ var top = cm.charCoords(range.head, "div").top + 5
6670
+ var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div")
6671
+ return {from: range.from(), to: rightPos }
6672
+ }); },
6673
+ undo: function (cm) { return cm.undo(); },
6674
+ redo: function (cm) { return cm.redo(); },
6675
+ undoSelection: function (cm) { return cm.undoSelection(); },
6676
+ redoSelection: function (cm) { return cm.redoSelection(); },
6677
+ goDocStart: function (cm) { return cm.extendSelection(Pos(cm.firstLine(), 0)); },
6678
+ goDocEnd: function (cm) { return cm.extendSelection(Pos(cm.lastLine())); },
6679
+ goLineStart: function (cm) { return cm.extendSelectionsBy(function (range) { return lineStart(cm, range.head.line); },
6680
+ {origin: "+move", bias: 1}
6681
+ ); },
6682
+ goLineStartSmart: function (cm) { return cm.extendSelectionsBy(function (range) { return lineStartSmart(cm, range.head); },
6683
+ {origin: "+move", bias: 1}
6684
+ ); },
6685
+ goLineEnd: function (cm) { return cm.extendSelectionsBy(function (range) { return lineEnd(cm, range.head.line); },
6686
+ {origin: "+move", bias: -1}
6687
+ ); },
6688
+ goLineRight: function (cm) { return cm.extendSelectionsBy(function (range) {
6689
+ var top = cm.charCoords(range.head, "div").top + 5
6690
+ return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div")
6691
+ }, sel_move); },
6692
+ goLineLeft: function (cm) { return cm.extendSelectionsBy(function (range) {
6693
+ var top = cm.charCoords(range.head, "div").top + 5
6694
+ return cm.coordsChar({left: 0, top: top}, "div")
6695
+ }, sel_move); },
6696
+ goLineLeftSmart: function (cm) { return cm.extendSelectionsBy(function (range) {
6697
+ var top = cm.charCoords(range.head, "div").top + 5
6698
+ var pos = cm.coordsChar({left: 0, top: top}, "div")
6699
+ if (pos.ch < cm.getLine(pos.line).search(/\S/)) { return lineStartSmart(cm, range.head) }
6700
+ return pos
6701
+ }, sel_move); },
6702
+ goLineUp: function (cm) { return cm.moveV(-1, "line"); },
6703
+ goLineDown: function (cm) { return cm.moveV(1, "line"); },
6704
+ goPageUp: function (cm) { return cm.moveV(-1, "page"); },
6705
+ goPageDown: function (cm) { return cm.moveV(1, "page"); },
6706
+ goCharLeft: function (cm) { return cm.moveH(-1, "char"); },
6707
+ goCharRight: function (cm) { return cm.moveH(1, "char"); },
6708
+ goColumnLeft: function (cm) { return cm.moveH(-1, "column"); },
6709
+ goColumnRight: function (cm) { return cm.moveH(1, "column"); },
6710
+ goWordLeft: function (cm) { return cm.moveH(-1, "word"); },
6711
+ goGroupRight: function (cm) { return cm.moveH(1, "group"); },
6712
+ goGroupLeft: function (cm) { return cm.moveH(-1, "group"); },
6713
+ goWordRight: function (cm) { return cm.moveH(1, "word"); },
6714
+ delCharBefore: function (cm) { return cm.deleteH(-1, "char"); },
6715
+ delCharAfter: function (cm) { return cm.deleteH(1, "char"); },
6716
+ delWordBefore: function (cm) { return cm.deleteH(-1, "word"); },
6717
+ delWordAfter: function (cm) { return cm.deleteH(1, "word"); },
6718
+ delGroupBefore: function (cm) { return cm.deleteH(-1, "group"); },
6719
+ delGroupAfter: function (cm) { return cm.deleteH(1, "group"); },
6720
+ indentAuto: function (cm) { return cm.indentSelection("smart"); },
6721
+ indentMore: function (cm) { return cm.indentSelection("add"); },
6722
+ indentLess: function (cm) { return cm.indentSelection("subtract"); },
6723
+ insertTab: function (cm) { return cm.replaceSelection("\t"); },
6724
+ insertSoftTab: function (cm) {
6725
+ var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize
6726
+ for (var i = 0; i < ranges.length; i++) {
6727
+ var pos = ranges[i].from()
6728
+ var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize)
6729
+ spaces.push(spaceStr(tabSize - col % tabSize))
6730
+ }
6731
+ cm.replaceSelections(spaces)
6732
+ },
6733
+ defaultTab: function (cm) {
6734
+ if (cm.somethingSelected()) { cm.indentSelection("add") }
6735
+ else { cm.execCommand("insertTab") }
6736
+ },
6737
+ // Swap the two chars left and right of each selection's head.
6738
+ // Move cursor behind the two swapped characters afterwards.
6739
+ //
6740
+ // Doesn't consider line feeds a character.
6741
+ // Doesn't scan more than one line above to find a character.
6742
+ // Doesn't do anything on an empty line.
6743
+ // Doesn't do anything with non-empty selections.
6744
+ transposeChars: function (cm) { return runInOp(cm, function () {
6745
+ var ranges = cm.listSelections(), newSel = []
6746
+ for (var i = 0; i < ranges.length; i++) {
6747
+ if (!ranges[i].empty()) { continue }
6748
+ var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text
6749
+ if (line) {
6750
+ if (cur.ch == line.length) { cur = new Pos(cur.line, cur.ch - 1) }
6751
+ if (cur.ch > 0) {
6752
+ cur = new Pos(cur.line, cur.ch + 1)
6753
+ cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2),
6754
+ Pos(cur.line, cur.ch - 2), cur, "+transpose")
6755
+ } else if (cur.line > cm.doc.first) {
6756
+ var prev = getLine(cm.doc, cur.line - 1).text
6757
+ if (prev) {
6758
+ cur = new Pos(cur.line, 1)
6759
+ cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() +
6760
+ prev.charAt(prev.length - 1),
6761
+ Pos(cur.line - 1, prev.length - 1), cur, "+transpose")
6762
+ }
6763
+ }
6764
+ }
6765
+ newSel.push(new Range(cur, cur))
6766
+ }
6767
+ cm.setSelections(newSel)
6768
+ }); },
6769
+ newlineAndIndent: function (cm) { return runInOp(cm, function () {
6770
+ var sels = cm.listSelections()
6771
+ for (var i = sels.length - 1; i >= 0; i--)
6772
+ { cm.replaceRange(cm.doc.lineSeparator(), sels[i].anchor, sels[i].head, "+input") }
6773
+ sels = cm.listSelections()
6774
+ for (var i$1 = 0; i$1 < sels.length; i$1++)
6775
+ { cm.indentLine(sels[i$1].from().line, null, true) }
6776
+ ensureCursorVisible(cm)
6777
+ }); },
6778
+ openLine: function (cm) { return cm.replaceSelection("\n", "start"); },
6779
+ toggleOverwrite: function (cm) { return cm.toggleOverwrite(); }
6780
+ }
6781
+
6782
+
6783
+ function lineStart(cm, lineN) {
6784
+ var line = getLine(cm.doc, lineN)
6785
+ var visual = visualLine(line)
6786
+ if (visual != line) { lineN = lineNo(visual) }
6787
+ return endOfLine(true, cm, visual, lineN, 1)
6788
+ }
6789
+ function lineEnd(cm, lineN) {
6790
+ var line = getLine(cm.doc, lineN)
6791
+ var visual = visualLineEnd(line)
6792
+ if (visual != line) { lineN = lineNo(visual) }
6793
+ return endOfLine(true, cm, line, lineN, -1)
6794
+ }
6795
+ function lineStartSmart(cm, pos) {
6796
+ var start = lineStart(cm, pos.line)
6797
+ var line = getLine(cm.doc, start.line)
6798
+ var order = getOrder(line, cm.doc.direction)
6799
+ if (!order || order[0].level == 0) {
6800
+ var firstNonWS = Math.max(0, line.text.search(/\S/))
6801
+ var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch
6802
+ return Pos(start.line, inWS ? 0 : firstNonWS, start.sticky)
6803
+ }
6804
+ return start
6805
+ }
6806
+
6807
+ // Run a handler that was bound to a key.
6808
+ function doHandleBinding(cm, bound, dropShift) {
6809
+ if (typeof bound == "string") {
6810
+ bound = commands[bound]
6811
+ if (!bound) { return false }
6812
+ }
6813
+ // Ensure previous input has been read, so that the handler sees a
6814
+ // consistent view of the document
6815
+ cm.display.input.ensurePolled()
6816
+ var prevShift = cm.display.shift, done = false
6817
+ try {
6818
+ if (cm.isReadOnly()) { cm.state.suppressEdits = true }
6819
+ if (dropShift) { cm.display.shift = false }
6820
+ done = bound(cm) != Pass
6821
+ } finally {
6822
+ cm.display.shift = prevShift
6823
+ cm.state.suppressEdits = false
6824
+ }
6825
+ return done
6826
+ }
6827
+
6828
+ function lookupKeyForEditor(cm, name, handle) {
6829
+ for (var i = 0; i < cm.state.keyMaps.length; i++) {
6830
+ var result = lookupKey(name, cm.state.keyMaps[i], handle, cm)
6831
+ if (result) { return result }
6832
+ }
6833
+ return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm))
6834
+ || lookupKey(name, cm.options.keyMap, handle, cm)
6835
+ }
6836
+
6837
+ var stopSeq = new Delayed
6838
+ function dispatchKey(cm, name, e, handle) {
6839
+ var seq = cm.state.keySeq
6840
+ if (seq) {
6841
+ if (isModifierKey(name)) { return "handled" }
6842
+ stopSeq.set(50, function () {
6843
+ if (cm.state.keySeq == seq) {
6844
+ cm.state.keySeq = null
6845
+ cm.display.input.reset()
6846
+ }
6847
+ })
6848
+ name = seq + " " + name
6849
+ }
6850
+ var result = lookupKeyForEditor(cm, name, handle)
6851
+
6852
+ if (result == "multi")
6853
+ { cm.state.keySeq = name }
6854
+ if (result == "handled")
6855
+ { signalLater(cm, "keyHandled", cm, name, e) }
6856
+
6857
+ if (result == "handled" || result == "multi") {
6858
+ e_preventDefault(e)
6859
+ restartBlink(cm)
6860
+ }
6861
+
6862
+ if (seq && !result && /\'$/.test(name)) {
6863
+ e_preventDefault(e)
6864
+ return true
6865
+ }
6866
+ return !!result
6867
+ }
6868
+
6869
+ // Handle a key from the keydown event.
6870
+ function handleKeyBinding(cm, e) {
6871
+ var name = keyName(e, true)
6872
+ if (!name) { return false }
6873
+
6874
+ if (e.shiftKey && !cm.state.keySeq) {
6875
+ // First try to resolve full name (including 'Shift-'). Failing
6876
+ // that, see if there is a cursor-motion command (starting with
6877
+ // 'go') bound to the keyname without 'Shift-'.
6878
+ return dispatchKey(cm, "Shift-" + name, e, function (b) { return doHandleBinding(cm, b, true); })
6879
+ || dispatchKey(cm, name, e, function (b) {
6880
+ if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion)
6881
+ { return doHandleBinding(cm, b) }
6882
+ })
6883
+ } else {
6884
+ return dispatchKey(cm, name, e, function (b) { return doHandleBinding(cm, b); })
6885
+ }
6886
+ }
6887
+
6888
+ // Handle a key from the keypress event
6889
+ function handleCharBinding(cm, e, ch) {
6890
+ return dispatchKey(cm, "'" + ch + "'", e, function (b) { return doHandleBinding(cm, b, true); })
6891
+ }
6892
+
6893
+ var lastStoppedKey = null
6894
+ function onKeyDown(e) {
6895
+ var cm = this
6896
+ cm.curOp.focus = activeElt()
6897
+ if (signalDOMEvent(cm, e)) { return }
6898
+ // IE does strange things with escape.
6899
+ if (ie && ie_version < 11 && e.keyCode == 27) { e.returnValue = false }
6900
+ var code = e.keyCode
6901
+ cm.display.shift = code == 16 || e.shiftKey
6902
+ var handled = handleKeyBinding(cm, e)
6903
+ if (presto) {
6904
+ lastStoppedKey = handled ? code : null
6905
+ // Opera has no cut event... we try to at least catch the key combo
6906
+ if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))
6907
+ { cm.replaceSelection("", null, "cut") }
6908
+ }
6909
+
6910
+ // Turn mouse into crosshair when Alt is held on Mac.
6911
+ if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className))
6912
+ { showCrossHair(cm) }
6913
+ }
6914
+
6915
+ function showCrossHair(cm) {
6916
+ var lineDiv = cm.display.lineDiv
6917
+ addClass(lineDiv, "CodeMirror-crosshair")
6918
+
6919
+ function up(e) {
6920
+ if (e.keyCode == 18 || !e.altKey) {
6921
+ rmClass(lineDiv, "CodeMirror-crosshair")
6922
+ off(document, "keyup", up)
6923
+ off(document, "mouseover", up)
6924
+ }
6925
+ }
6926
+ on(document, "keyup", up)
6927
+ on(document, "mouseover", up)
6928
+ }
6929
+
6930
+ function onKeyUp(e) {
6931
+ if (e.keyCode == 16) { this.doc.sel.shift = false }
6932
+ signalDOMEvent(this, e)
6933
+ }
6934
+
6935
+ function onKeyPress(e) {
6936
+ var cm = this
6937
+ if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) { return }
6938
+ var keyCode = e.keyCode, charCode = e.charCode
6939
+ if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return}
6940
+ if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) { return }
6941
+ var ch = String.fromCharCode(charCode == null ? keyCode : charCode)
6942
+ // Some browsers fire keypress events for backspace
6943
+ if (ch == "\x08") { return }
6944
+ if (handleCharBinding(cm, e, ch)) { return }
6945
+ cm.display.input.onKeyPress(e)
6946
+ }
6947
+
6948
+ // A mouse down can be a single click, double click, triple click,
6949
+ // start of selection drag, start of text drag, new cursor
6950
+ // (ctrl-click), rectangle drag (alt-drag), or xwin
6951
+ // middle-click-paste. Or it might be a click on something we should
6952
+ // not interfere with, such as a scrollbar or widget.
6953
+ function onMouseDown(e) {
6954
+ var cm = this, display = cm.display
6955
+ if (signalDOMEvent(cm, e) || display.activeTouch && display.input.supportsTouch()) { return }
6956
+ display.input.ensurePolled()
6957
+ display.shift = e.shiftKey
6958
+
6959
+ if (eventInWidget(display, e)) {
6960
+ if (!webkit) {
6961
+ // Briefly turn off draggability, to allow widgets to do
6962
+ // normal dragging things.
6963
+ display.scroller.draggable = false
6964
+ setTimeout(function () { return display.scroller.draggable = true; }, 100)
6965
+ }
6966
+ return
6967
+ }
6968
+ if (clickInGutter(cm, e)) { return }
6969
+ var start = posFromMouse(cm, e)
6970
+ window.focus()
6971
+
6972
+ switch (e_button(e)) {
6973
+ case 1:
6974
+ // #3261: make sure, that we're not starting a second selection
6975
+ if (cm.state.selectingText)
6976
+ { cm.state.selectingText(e) }
6977
+ else if (start)
6978
+ { leftButtonDown(cm, e, start) }
6979
+ else if (e_target(e) == display.scroller)
6980
+ { e_preventDefault(e) }
6981
+ break
6982
+ case 2:
6983
+ if (webkit) { cm.state.lastMiddleDown = +new Date }
6984
+ if (start) { extendSelection(cm.doc, start) }
6985
+ setTimeout(function () { return display.input.focus(); }, 20)
6986
+ e_preventDefault(e)
6987
+ break
6988
+ case 3:
6989
+ if (captureRightClick) { onContextMenu(cm, e) }
6990
+ else { delayBlurEvent(cm) }
6991
+ break
6992
+ }
6993
+ }
6994
+
6995
+ var lastClick;
6996
+ var lastDoubleClick;
6997
+ function leftButtonDown(cm, e, start) {
6998
+ if (ie) { setTimeout(bind(ensureFocus, cm), 0) }
6999
+ else { cm.curOp.focus = activeElt() }
7000
+
7001
+ var now = +new Date, type
7002
+ if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) {
7003
+ type = "triple"
7004
+ } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) {
7005
+ type = "double"
7006
+ lastDoubleClick = {time: now, pos: start}
7007
+ } else {
7008
+ type = "single"
7009
+ lastClick = {time: now, pos: start}
7010
+ }
7011
+
7012
+ var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey, contained
7013
+ if (cm.options.dragDrop && dragAndDrop && !cm.isReadOnly() &&
7014
+ type == "single" && (contained = sel.contains(start)) > -1 &&
7015
+ (cmp((contained = sel.ranges[contained]).from(), start) < 0 || start.xRel > 0) &&
7016
+ (cmp(contained.to(), start) > 0 || start.xRel < 0))
7017
+ { leftButtonStartDrag(cm, e, start, modifier) }
7018
+ else
7019
+ { leftButtonSelect(cm, e, start, type, modifier) }
7020
+ }
7021
+
7022
+ // Start a text drag. When it ends, see if any dragging actually
7023
+ // happen, and treat as a click if it didn't.
7024
+ function leftButtonStartDrag(cm, e, start, modifier) {
7025
+ var display = cm.display, moved = false
7026
+ var dragEnd = operation(cm, function (e) {
7027
+ if (webkit) { display.scroller.draggable = false }
7028
+ cm.state.draggingText = false
7029
+ off(document, "mouseup", dragEnd)
7030
+ off(document, "mousemove", mouseMove)
7031
+ off(display.scroller, "dragstart", dragStart)
7032
+ off(display.scroller, "drop", dragEnd)
7033
+ if (!moved) {
7034
+ e_preventDefault(e)
7035
+ if (!modifier)
7036
+ { extendSelection(cm.doc, start) }
7037
+ // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081)
7038
+ if (webkit || ie && ie_version == 9)
7039
+ { setTimeout(function () {document.body.focus(); display.input.focus()}, 20) }
7040
+ else
7041
+ { display.input.focus() }
7042
+ }
7043
+ })
7044
+ var mouseMove = function(e2) {
7045
+ moved = moved || Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) >= 10
7046
+ }
7047
+ var dragStart = function () { return moved = true; }
7048
+ // Let the drag handler handle this.
7049
+ if (webkit) { display.scroller.draggable = true }
7050
+ cm.state.draggingText = dragEnd
7051
+ dragEnd.copy = mac ? e.altKey : e.ctrlKey
7052
+ // IE's approach to draggable
7053
+ if (display.scroller.dragDrop) { display.scroller.dragDrop() }
7054
+ on(document, "mouseup", dragEnd)
7055
+ on(document, "mousemove", mouseMove)
7056
+ on(display.scroller, "dragstart", dragStart)
7057
+ on(display.scroller, "drop", dragEnd)
7058
+
7059
+ delayBlurEvent(cm)
7060
+ setTimeout(function () { return display.input.focus(); }, 20)
7061
+ }
7062
+
7063
+ // Normal selection, as opposed to text dragging.
7064
+ function leftButtonSelect(cm, e, start, type, addNew) {
7065
+ var display = cm.display, doc = cm.doc
7066
+ e_preventDefault(e)
7067
+
7068
+ var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges
7069
+ if (addNew && !e.shiftKey) {
7070
+ ourIndex = doc.sel.contains(start)
7071
+ if (ourIndex > -1)
7072
+ { ourRange = ranges[ourIndex] }
7073
+ else
7074
+ { ourRange = new Range(start, start) }
7075
+ } else {
7076
+ ourRange = doc.sel.primary()
7077
+ ourIndex = doc.sel.primIndex
7078
+ }
7079
+
7080
+ if (chromeOS ? e.shiftKey && e.metaKey : e.altKey) {
7081
+ type = "rect"
7082
+ if (!addNew) { ourRange = new Range(start, start) }
7083
+ start = posFromMouse(cm, e, true, true)
7084
+ ourIndex = -1
7085
+ } else if (type == "double") {
7086
+ var word = cm.findWordAt(start)
7087
+ if (cm.display.shift || doc.extend)
7088
+ { ourRange = extendRange(doc, ourRange, word.anchor, word.head) }
7089
+ else
7090
+ { ourRange = word }
7091
+ } else if (type == "triple") {
7092
+ var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0)))
7093
+ if (cm.display.shift || doc.extend)
7094
+ { ourRange = extendRange(doc, ourRange, line.anchor, line.head) }
7095
+ else
7096
+ { ourRange = line }
7097
+ } else {
7098
+ ourRange = extendRange(doc, ourRange, start)
7099
+ }
7100
+
7101
+ if (!addNew) {
7102
+ ourIndex = 0
7103
+ setSelection(doc, new Selection([ourRange], 0), sel_mouse)
7104
+ startSel = doc.sel
7105
+ } else if (ourIndex == -1) {
7106
+ ourIndex = ranges.length
7107
+ setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex),
7108
+ {scroll: false, origin: "*mouse"})
7109
+ } else if (ranges.length > 1 && ranges[ourIndex].empty() && type == "single" && !e.shiftKey) {
7110
+ setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0),
7111
+ {scroll: false, origin: "*mouse"})
7112
+ startSel = doc.sel
7113
+ } else {
7114
+ replaceOneSelection(doc, ourIndex, ourRange, sel_mouse)
7115
+ }
7116
+
7117
+ var lastPos = start
7118
+ function extendTo(pos) {
7119
+ if (cmp(lastPos, pos) == 0) { return }
7120
+ lastPos = pos
7121
+
7122
+ if (type == "rect") {
7123
+ var ranges = [], tabSize = cm.options.tabSize
7124
+ var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize)
7125
+ var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize)
7126
+ var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol)
7127
+ for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line));
7128
+ line <= end; line++) {
7129
+ var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize)
7130
+ if (left == right)
7131
+ { ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))) }
7132
+ else if (text.length > leftPos)
7133
+ { ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))) }
7134
+ }
7135
+ if (!ranges.length) { ranges.push(new Range(start, start)) }
7136
+ setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex),
7137
+ {origin: "*mouse", scroll: false})
7138
+ cm.scrollIntoView(pos)
7139
+ } else {
7140
+ var oldRange = ourRange
7141
+ var anchor = oldRange.anchor, head = pos
7142
+ if (type != "single") {
7143
+ var range
7144
+ if (type == "double")
7145
+ { range = cm.findWordAt(pos) }
7146
+ else
7147
+ { range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0))) }
7148
+ if (cmp(range.anchor, anchor) > 0) {
7149
+ head = range.head
7150
+ anchor = minPos(oldRange.from(), range.anchor)
7151
+ } else {
7152
+ head = range.anchor
7153
+ anchor = maxPos(oldRange.to(), range.head)
7154
+ }
7155
+ }
7156
+ var ranges$1 = startSel.ranges.slice(0)
7157
+ ranges$1[ourIndex] = new Range(clipPos(doc, anchor), head)
7158
+ setSelection(doc, normalizeSelection(ranges$1, ourIndex), sel_mouse)
7159
+ }
7160
+ }
7161
+
7162
+ var editorSize = display.wrapper.getBoundingClientRect()
7163
+ // Used to ensure timeout re-tries don't fire when another extend
7164
+ // happened in the meantime (clearTimeout isn't reliable -- at
7165
+ // least on Chrome, the timeouts still happen even when cleared,
7166
+ // if the clear happens after their scheduled firing time).
7167
+ var counter = 0
7168
+
7169
+ function extend(e) {
7170
+ var curCount = ++counter
7171
+ var cur = posFromMouse(cm, e, true, type == "rect")
7172
+ if (!cur) { return }
7173
+ if (cmp(cur, lastPos) != 0) {
7174
+ cm.curOp.focus = activeElt()
7175
+ extendTo(cur)
7176
+ var visible = visibleLines(display, doc)
7177
+ if (cur.line >= visible.to || cur.line < visible.from)
7178
+ { setTimeout(operation(cm, function () {if (counter == curCount) { extend(e) }}), 150) }
7179
+ } else {
7180
+ var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0
7181
+ if (outside) { setTimeout(operation(cm, function () {
7182
+ if (counter != curCount) { return }
7183
+ display.scroller.scrollTop += outside
7184
+ extend(e)
7185
+ }), 50) }
7186
+ }
7187
+ }
7188
+
7189
+ function done(e) {
7190
+ cm.state.selectingText = false
7191
+ counter = Infinity
7192
+ e_preventDefault(e)
7193
+ display.input.focus()
7194
+ off(document, "mousemove", move)
7195
+ off(document, "mouseup", up)
7196
+ doc.history.lastSelOrigin = null
7197
+ }
7198
+
7199
+ var move = operation(cm, function (e) {
7200
+ if (!e_button(e)) { done(e) }
7201
+ else { extend(e) }
7202
+ })
7203
+ var up = operation(cm, done)
7204
+ cm.state.selectingText = up
7205
+ on(document, "mousemove", move)
7206
+ on(document, "mouseup", up)
7207
+ }
7208
+
7209
+
7210
+ // Determines whether an event happened in the gutter, and fires the
7211
+ // handlers for the corresponding event.
7212
+ function gutterEvent(cm, e, type, prevent) {
7213
+ var mX, mY
7214
+ try { mX = e.clientX; mY = e.clientY }
7215
+ catch(e) { return false }
7216
+ if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) { return false }
7217
+ if (prevent) { e_preventDefault(e) }
7218
+
7219
+ var display = cm.display
7220
+ var lineBox = display.lineDiv.getBoundingClientRect()
7221
+
7222
+ if (mY > lineBox.bottom || !hasHandler(cm, type)) { return e_defaultPrevented(e) }
7223
+ mY -= lineBox.top - display.viewOffset
7224
+
7225
+ for (var i = 0; i < cm.options.gutters.length; ++i) {
7226
+ var g = display.gutters.childNodes[i]
7227
+ if (g && g.getBoundingClientRect().right >= mX) {
7228
+ var line = lineAtHeight(cm.doc, mY)
7229
+ var gutter = cm.options.gutters[i]
7230
+ signal(cm, type, cm, line, gutter, e)
7231
+ return e_defaultPrevented(e)
7232
+ }
7233
+ }
7234
+ }
7235
+
7236
+ function clickInGutter(cm, e) {
7237
+ return gutterEvent(cm, e, "gutterClick", true)
7238
+ }
7239
+
7240
+ // CONTEXT MENU HANDLING
7241
+
7242
+ // To make the context menu work, we need to briefly unhide the
7243
+ // textarea (making it as unobtrusive as possible) to let the
7244
+ // right-click take effect on it.
7245
+ function onContextMenu(cm, e) {
7246
+ if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) { return }
7247
+ if (signalDOMEvent(cm, e, "contextmenu")) { return }
7248
+ cm.display.input.onContextMenu(e)
7249
+ }
7250
+
7251
+ function contextMenuInGutter(cm, e) {
7252
+ if (!hasHandler(cm, "gutterContextMenu")) { return false }
7253
+ return gutterEvent(cm, e, "gutterContextMenu", false)
7254
+ }
7255
+
7256
+ function themeChanged(cm) {
7257
+ cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
7258
+ cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-")
7259
+ clearCaches(cm)
7260
+ }
7261
+
7262
+ var Init = {toString: function(){return "CodeMirror.Init"}}
7263
+
7264
+ var defaults = {}
7265
+ var optionHandlers = {}
7266
+
7267
+ function defineOptions(CodeMirror) {
7268
+ var optionHandlers = CodeMirror.optionHandlers
7269
+
7270
+ function option(name, deflt, handle, notOnInit) {
7271
+ CodeMirror.defaults[name] = deflt
7272
+ if (handle) { optionHandlers[name] =
7273
+ notOnInit ? function (cm, val, old) {if (old != Init) { handle(cm, val, old) }} : handle }
7274
+ }
7275
+
7276
+ CodeMirror.defineOption = option
7277
+
7278
+ // Passed to option handlers when there is no old value.
7279
+ CodeMirror.Init = Init
7280
+
7281
+ // These two are, on init, called from the constructor because they
7282
+ // have to be initialized before the editor can start at all.
7283
+ option("value", "", function (cm, val) { return cm.setValue(val); }, true)
7284
+ option("mode", null, function (cm, val) {
7285
+ cm.doc.modeOption = val
7286
+ loadMode(cm)
7287
+ }, true)
7288
+
7289
+ option("indentUnit", 2, loadMode, true)
7290
+ option("indentWithTabs", false)
7291
+ option("smartIndent", true)
7292
+ option("tabSize", 4, function (cm) {
7293
+ resetModeState(cm)
7294
+ clearCaches(cm)
7295
+ regChange(cm)
7296
+ }, true)
7297
+ option("lineSeparator", null, function (cm, val) {
7298
+ cm.doc.lineSep = val
7299
+ if (!val) { return }
7300
+ var newBreaks = [], lineNo = cm.doc.first
7301
+ cm.doc.iter(function (line) {
7302
+ for (var pos = 0;;) {
7303
+ var found = line.text.indexOf(val, pos)
7304
+ if (found == -1) { break }
7305
+ pos = found + val.length
7306
+ newBreaks.push(Pos(lineNo, found))
7307
+ }
7308
+ lineNo++
7309
+ })
7310
+ for (var i = newBreaks.length - 1; i >= 0; i--)
7311
+ { replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)) }
7312
+ })
7313
+ option("specialChars", /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff]/g, function (cm, val, old) {
7314
+ cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g")
7315
+ if (old != Init) { cm.refresh() }
7316
+ })
7317
+ option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function (cm) { return cm.refresh(); }, true)
7318
+ option("electricChars", true)
7319
+ option("inputStyle", mobile ? "contenteditable" : "textarea", function () {
7320
+ throw new Error("inputStyle can not (yet) be changed in a running editor") // FIXME
7321
+ }, true)
7322
+ option("spellcheck", false, function (cm, val) { return cm.getInputField().spellcheck = val; }, true)
7323
+ option("rtlMoveVisually", !windows)
7324
+ option("wholeLineUpdateBefore", true)
7325
+
7326
+ option("theme", "default", function (cm) {
7327
+ themeChanged(cm)
7328
+ guttersChanged(cm)
7329
+ }, true)
7330
+ option("keyMap", "default", function (cm, val, old) {
7331
+ var next = getKeyMap(val)
7332
+ var prev = old != Init && getKeyMap(old)
7333
+ if (prev && prev.detach) { prev.detach(cm, next) }
7334
+ if (next.attach) { next.attach(cm, prev || null) }
7335
+ })
7336
+ option("extraKeys", null)
7337
+
7338
+ option("lineWrapping", false, wrappingChanged, true)
7339
+ option("gutters", [], function (cm) {
7340
+ setGuttersForLineNumbers(cm.options)
7341
+ guttersChanged(cm)
7342
+ }, true)
7343
+ option("fixedGutter", true, function (cm, val) {
7344
+ cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0"
7345
+ cm.refresh()
7346
+ }, true)
7347
+ option("coverGutterNextToScrollbar", false, function (cm) { return updateScrollbars(cm); }, true)
7348
+ option("scrollbarStyle", "native", function (cm) {
7349
+ initScrollbars(cm)
7350
+ updateScrollbars(cm)
7351
+ cm.display.scrollbars.setScrollTop(cm.doc.scrollTop)
7352
+ cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft)
7353
+ }, true)
7354
+ option("lineNumbers", false, function (cm) {
7355
+ setGuttersForLineNumbers(cm.options)
7356
+ guttersChanged(cm)
7357
+ }, true)
7358
+ option("firstLineNumber", 1, guttersChanged, true)
7359
+ option("lineNumberFormatter", function (integer) { return integer; }, guttersChanged, true)
7360
+ option("showCursorWhenSelecting", false, updateSelection, true)
7361
+
7362
+ option("resetSelectionOnContextMenu", true)
7363
+ option("lineWiseCopyCut", true)
7364
+
7365
+ option("readOnly", false, function (cm, val) {
7366
+ if (val == "nocursor") {
7367
+ onBlur(cm)
7368
+ cm.display.input.blur()
7369
+ cm.display.disabled = true
7370
+ } else {
7371
+ cm.display.disabled = false
7372
+ }
7373
+ cm.display.input.readOnlyChanged(val)
7374
+ })
7375
+ option("disableInput", false, function (cm, val) {if (!val) { cm.display.input.reset() }}, true)
7376
+ option("dragDrop", true, dragDropChanged)
7377
+ option("allowDropFileTypes", null)
7378
+
7379
+ option("cursorBlinkRate", 530)
7380
+ option("cursorScrollMargin", 0)
7381
+ option("cursorHeight", 1, updateSelection, true)
7382
+ option("singleCursorHeightPerLine", true, updateSelection, true)
7383
+ option("workTime", 100)
7384
+ option("workDelay", 100)
7385
+ option("flattenSpans", true, resetModeState, true)
7386
+ option("addModeClass", false, resetModeState, true)
7387
+ option("pollInterval", 100)
7388
+ option("undoDepth", 200, function (cm, val) { return cm.doc.history.undoDepth = val; })
7389
+ option("historyEventDelay", 1250)
7390
+ option("viewportMargin", 10, function (cm) { return cm.refresh(); }, true)
7391
+ option("maxHighlightLength", 10000, resetModeState, true)
7392
+ option("moveInputWithCursor", true, function (cm, val) {
7393
+ if (!val) { cm.display.input.resetPosition() }
7394
+ })
7395
+
7396
+ option("tabindex", null, function (cm, val) { return cm.display.input.getField().tabIndex = val || ""; })
7397
+ option("autofocus", null)
7398
+ option("direction", "ltr", function (cm, val) { return cm.doc.setDirection(val); }, true)
7399
+ }
7400
+
7401
+ function guttersChanged(cm) {
7402
+ updateGutters(cm)
7403
+ regChange(cm)
7404
+ alignHorizontally(cm)
7405
+ }
7406
+
7407
+ function dragDropChanged(cm, value, old) {
7408
+ var wasOn = old && old != Init
7409
+ if (!value != !wasOn) {
7410
+ var funcs = cm.display.dragFunctions
7411
+ var toggle = value ? on : off
7412
+ toggle(cm.display.scroller, "dragstart", funcs.start)
7413
+ toggle(cm.display.scroller, "dragenter", funcs.enter)
7414
+ toggle(cm.display.scroller, "dragover", funcs.over)
7415
+ toggle(cm.display.scroller, "dragleave", funcs.leave)
7416
+ toggle(cm.display.scroller, "drop", funcs.drop)
7417
+ }
7418
+ }
7419
+
7420
+ function wrappingChanged(cm) {
7421
+ if (cm.options.lineWrapping) {
7422
+ addClass(cm.display.wrapper, "CodeMirror-wrap")
7423
+ cm.display.sizer.style.minWidth = ""
7424
+ cm.display.sizerWidth = null
7425
+ } else {
7426
+ rmClass(cm.display.wrapper, "CodeMirror-wrap")
7427
+ findMaxLine(cm)
7428
+ }
7429
+ estimateLineHeights(cm)
7430
+ regChange(cm)
7431
+ clearCaches(cm)
7432
+ setTimeout(function () { return updateScrollbars(cm); }, 100)
7433
+ }
7434
+
7435
+ // A CodeMirror instance represents an editor. This is the object
7436
+ // that user code is usually dealing with.
7437
+
7438
+ function CodeMirror(place, options) {
7439
+ var this$1 = this;
7440
+
7441
+ if (!(this instanceof CodeMirror)) { return new CodeMirror(place, options) }
7442
+
7443
+ this.options = options = options ? copyObj(options) : {}
7444
+ // Determine effective options based on given values and defaults.
7445
+ copyObj(defaults, options, false)
7446
+ setGuttersForLineNumbers(options)
7447
+
7448
+ var doc = options.value
7449
+ if (typeof doc == "string") { doc = new Doc(doc, options.mode, null, options.lineSeparator, options.direction) }
7450
+ this.doc = doc
7451
+
7452
+ var input = new CodeMirror.inputStyles[options.inputStyle](this)
7453
+ var display = this.display = new Display(place, doc, input)
7454
+ display.wrapper.CodeMirror = this
7455
+ updateGutters(this)
7456
+ themeChanged(this)
7457
+ if (options.lineWrapping)
7458
+ { this.display.wrapper.className += " CodeMirror-wrap" }
7459
+ initScrollbars(this)
7460
+
7461
+ this.state = {
7462
+ keyMaps: [], // stores maps added by addKeyMap
7463
+ overlays: [], // highlighting overlays, as added by addOverlay
7464
+ modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info
7465
+ overwrite: false,
7466
+ delayingBlurEvent: false,
7467
+ focused: false,
7468
+ suppressEdits: false, // used to disable editing during key handlers when in readOnly mode
7469
+ pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll
7470
+ selectingText: false,
7471
+ draggingText: false,
7472
+ highlight: new Delayed(), // stores highlight worker timeout
7473
+ keySeq: null, // Unfinished key sequence
7474
+ specialChars: null
7475
+ }
7476
+
7477
+ if (options.autofocus && !mobile) { display.input.focus() }
7478
+
7479
+ // Override magic textarea content restore that IE sometimes does
7480
+ // on our hidden textarea on reload
7481
+ if (ie && ie_version < 11) { setTimeout(function () { return this$1.display.input.reset(true); }, 20) }
7482
+
7483
+ registerEventHandlers(this)
7484
+ ensureGlobalHandlers()
7485
+
7486
+ startOperation(this)
7487
+ this.curOp.forceUpdate = true
7488
+ attachDoc(this, doc)
7489
+
7490
+ if ((options.autofocus && !mobile) || this.hasFocus())
7491
+ { setTimeout(bind(onFocus, this), 20) }
7492
+ else
7493
+ { onBlur(this) }
7494
+
7495
+ for (var opt in optionHandlers) { if (optionHandlers.hasOwnProperty(opt))
7496
+ { optionHandlers[opt](this$1, options[opt], Init) } }
7497
+ maybeUpdateLineNumberWidth(this)
7498
+ if (options.finishInit) { options.finishInit(this) }
7499
+ for (var i = 0; i < initHooks.length; ++i) { initHooks[i](this$1) }
7500
+ endOperation(this)
7501
+ // Suppress optimizelegibility in Webkit, since it breaks text
7502
+ // measuring on line wrapping boundaries.
7503
+ if (webkit && options.lineWrapping &&
7504
+ getComputedStyle(display.lineDiv).textRendering == "optimizelegibility")
7505
+ { display.lineDiv.style.textRendering = "auto" }
7506
+ }
7507
+
7508
+ // The default configuration options.
7509
+ CodeMirror.defaults = defaults
7510
+ // Functions to run when options are changed.
7511
+ CodeMirror.optionHandlers = optionHandlers
7512
+
7513
+ // Attach the necessary event handlers when initializing the editor
7514
+ function registerEventHandlers(cm) {
7515
+ var d = cm.display
7516
+ on(d.scroller, "mousedown", operation(cm, onMouseDown))
7517
+ // Older IE's will not fire a second mousedown for a double click
7518
+ if (ie && ie_version < 11)
7519
+ { on(d.scroller, "dblclick", operation(cm, function (e) {
7520
+ if (signalDOMEvent(cm, e)) { return }
7521
+ var pos = posFromMouse(cm, e)
7522
+ if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) { return }
7523
+ e_preventDefault(e)
7524
+ var word = cm.findWordAt(pos)
7525
+ extendSelection(cm.doc, word.anchor, word.head)
7526
+ })) }
7527
+ else
7528
+ { on(d.scroller, "dblclick", function (e) { return signalDOMEvent(cm, e) || e_preventDefault(e); }) }
7529
+ // Some browsers fire contextmenu *after* opening the menu, at
7530
+ // which point we can't mess with it anymore. Context menu is
7531
+ // handled in onMouseDown for these browsers.
7532
+ if (!captureRightClick) { on(d.scroller, "contextmenu", function (e) { return onContextMenu(cm, e); }) }
7533
+
7534
+ // Used to suppress mouse event handling when a touch happens
7535
+ var touchFinished, prevTouch = {end: 0}
7536
+ function finishTouch() {
7537
+ if (d.activeTouch) {
7538
+ touchFinished = setTimeout(function () { return d.activeTouch = null; }, 1000)
7539
+ prevTouch = d.activeTouch
7540
+ prevTouch.end = +new Date
7541
+ }
7542
+ }
7543
+ function isMouseLikeTouchEvent(e) {
7544
+ if (e.touches.length != 1) { return false }
7545
+ var touch = e.touches[0]
7546
+ return touch.radiusX <= 1 && touch.radiusY <= 1
7547
+ }
7548
+ function farAway(touch, other) {
7549
+ if (other.left == null) { return true }
7550
+ var dx = other.left - touch.left, dy = other.top - touch.top
7551
+ return dx * dx + dy * dy > 20 * 20
7552
+ }
7553
+ on(d.scroller, "touchstart", function (e) {
7554
+ if (!signalDOMEvent(cm, e) && !isMouseLikeTouchEvent(e)) {
7555
+ d.input.ensurePolled()
7556
+ clearTimeout(touchFinished)
7557
+ var now = +new Date
7558
+ d.activeTouch = {start: now, moved: false,
7559
+ prev: now - prevTouch.end <= 300 ? prevTouch : null}
7560
+ if (e.touches.length == 1) {
7561
+ d.activeTouch.left = e.touches[0].pageX
7562
+ d.activeTouch.top = e.touches[0].pageY
7563
+ }
7564
+ }
7565
+ })
7566
+ on(d.scroller, "touchmove", function () {
7567
+ if (d.activeTouch) { d.activeTouch.moved = true }
7568
+ })
7569
+ on(d.scroller, "touchend", function (e) {
7570
+ var touch = d.activeTouch
7571
+ if (touch && !eventInWidget(d, e) && touch.left != null &&
7572
+ !touch.moved && new Date - touch.start < 300) {
7573
+ var pos = cm.coordsChar(d.activeTouch, "page"), range
7574
+ if (!touch.prev || farAway(touch, touch.prev)) // Single tap
7575
+ { range = new Range(pos, pos) }
7576
+ else if (!touch.prev.prev || farAway(touch, touch.prev.prev)) // Double tap
7577
+ { range = cm.findWordAt(pos) }
7578
+ else // Triple tap
7579
+ { range = new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))) }
7580
+ cm.setSelection(range.anchor, range.head)
7581
+ cm.focus()
7582
+ e_preventDefault(e)
7583
+ }
7584
+ finishTouch()
7585
+ })
7586
+ on(d.scroller, "touchcancel", finishTouch)
7587
+
7588
+ // Sync scrolling between fake scrollbars and real scrollable
7589
+ // area, ensure viewport is updated when scrolling.
7590
+ on(d.scroller, "scroll", function () {
7591
+ if (d.scroller.clientHeight) {
7592
+ updateScrollTop(cm, d.scroller.scrollTop)
7593
+ setScrollLeft(cm, d.scroller.scrollLeft, true)
7594
+ signal(cm, "scroll", cm)
7595
+ }
7596
+ })
7597
+
7598
+ // Listen to wheel events in order to try and update the viewport on time.
7599
+ on(d.scroller, "mousewheel", function (e) { return onScrollWheel(cm, e); })
7600
+ on(d.scroller, "DOMMouseScroll", function (e) { return onScrollWheel(cm, e); })
7601
+
7602
+ // Prevent wrapper from ever scrolling
7603
+ on(d.wrapper, "scroll", function () { return d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; })
7604
+
7605
+ d.dragFunctions = {
7606
+ enter: function (e) {if (!signalDOMEvent(cm, e)) { e_stop(e) }},
7607
+ over: function (e) {if (!signalDOMEvent(cm, e)) { onDragOver(cm, e); e_stop(e) }},
7608
+ start: function (e) { return onDragStart(cm, e); },
7609
+ drop: operation(cm, onDrop),
7610
+ leave: function (e) {if (!signalDOMEvent(cm, e)) { clearDragCursor(cm) }}
7611
+ }
7612
+
7613
+ var inp = d.input.getField()
7614
+ on(inp, "keyup", function (e) { return onKeyUp.call(cm, e); })
7615
+ on(inp, "keydown", operation(cm, onKeyDown))
7616
+ on(inp, "keypress", operation(cm, onKeyPress))
7617
+ on(inp, "focus", function (e) { return onFocus(cm, e); })
7618
+ on(inp, "blur", function (e) { return onBlur(cm, e); })
7619
+ }
7620
+
7621
+ var initHooks = []
7622
+ CodeMirror.defineInitHook = function (f) { return initHooks.push(f); }
7623
+
7624
+ // Indent the given line. The how parameter can be "smart",
7625
+ // "add"/null, "subtract", or "prev". When aggressive is false
7626
+ // (typically set to true for forced single-line indents), empty
7627
+ // lines are not indented, and places where the mode returns Pass
7628
+ // are left alone.
7629
+ function indentLine(cm, n, how, aggressive) {
7630
+ var doc = cm.doc, state
7631
+ if (how == null) { how = "add" }
7632
+ if (how == "smart") {
7633
+ // Fall back to "prev" when the mode doesn't have an indentation
7634
+ // method.
7635
+ if (!doc.mode.indent) { how = "prev" }
7636
+ else { state = getStateBefore(cm, n) }
7637
+ }
7638
+
7639
+ var tabSize = cm.options.tabSize
7640
+ var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize)
7641
+ if (line.stateAfter) { line.stateAfter = null }
7642
+ var curSpaceString = line.text.match(/^\s*/)[0], indentation
7643
+ if (!aggressive && !/\S/.test(line.text)) {
7644
+ indentation = 0
7645
+ how = "not"
7646
+ } else if (how == "smart") {
7647
+ indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text)
7648
+ if (indentation == Pass || indentation > 150) {
7649
+ if (!aggressive) { return }
7650
+ how = "prev"
7651
+ }
7652
+ }
7653
+ if (how == "prev") {
7654
+ if (n > doc.first) { indentation = countColumn(getLine(doc, n-1).text, null, tabSize) }
7655
+ else { indentation = 0 }
7656
+ } else if (how == "add") {
7657
+ indentation = curSpace + cm.options.indentUnit
7658
+ } else if (how == "subtract") {
7659
+ indentation = curSpace - cm.options.indentUnit
7660
+ } else if (typeof how == "number") {
7661
+ indentation = curSpace + how
7662
+ }
7663
+ indentation = Math.max(0, indentation)
7664
+
7665
+ var indentString = "", pos = 0
7666
+ if (cm.options.indentWithTabs)
7667
+ { for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t"} }
7668
+ if (pos < indentation) { indentString += spaceStr(indentation - pos) }
7669
+
7670
+ if (indentString != curSpaceString) {
7671
+ replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input")
7672
+ line.stateAfter = null
7673
+ return true
7674
+ } else {
7675
+ // Ensure that, if the cursor was in the whitespace at the start
7676
+ // of the line, it is moved to the end of that space.
7677
+ for (var i$1 = 0; i$1 < doc.sel.ranges.length; i$1++) {
7678
+ var range = doc.sel.ranges[i$1]
7679
+ if (range.head.line == n && range.head.ch < curSpaceString.length) {
7680
+ var pos$1 = Pos(n, curSpaceString.length)
7681
+ replaceOneSelection(doc, i$1, new Range(pos$1, pos$1))
7682
+ break
7683
+ }
7684
+ }
7685
+ }
7686
+ }
7687
+
7688
+ // This will be set to a {lineWise: bool, text: [string]} object, so
7689
+ // that, when pasting, we know what kind of selections the copied
7690
+ // text was made out of.
7691
+ var lastCopied = null
7692
+
7693
+ function setLastCopied(newLastCopied) {
7694
+ lastCopied = newLastCopied
7695
+ }
7696
+
7697
+ function applyTextInput(cm, inserted, deleted, sel, origin) {
7698
+ var doc = cm.doc
7699
+ cm.display.shift = false
7700
+ if (!sel) { sel = doc.sel }
7701
+
7702
+ var paste = cm.state.pasteIncoming || origin == "paste"
7703
+ var textLines = splitLinesAuto(inserted), multiPaste = null
7704
+ // When pasing N lines into N selections, insert one line per selection
7705
+ if (paste && sel.ranges.length > 1) {
7706
+ if (lastCopied && lastCopied.text.join("\n") == inserted) {
7707
+ if (sel.ranges.length % lastCopied.text.length == 0) {
7708
+ multiPaste = []
7709
+ for (var i = 0; i < lastCopied.text.length; i++)
7710
+ { multiPaste.push(doc.splitLines(lastCopied.text[i])) }
7711
+ }
7712
+ } else if (textLines.length == sel.ranges.length) {
7713
+ multiPaste = map(textLines, function (l) { return [l]; })
7714
+ }
7715
+ }
7716
+
7717
+ var updateInput
7718
+ // Normal behavior is to insert the new text into every selection
7719
+ for (var i$1 = sel.ranges.length - 1; i$1 >= 0; i$1--) {
7720
+ var range = sel.ranges[i$1]
7721
+ var from = range.from(), to = range.to()
7722
+ if (range.empty()) {
7723
+ if (deleted && deleted > 0) // Handle deletion
7724
+ { from = Pos(from.line, from.ch - deleted) }
7725
+ else if (cm.state.overwrite && !paste) // Handle overwrite
7726
+ { to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)) }
7727
+ else if (lastCopied && lastCopied.lineWise && lastCopied.text.join("\n") == inserted)
7728
+ { from = to = Pos(from.line, 0) }
7729
+ }
7730
+ updateInput = cm.curOp.updateInput
7731
+ var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i$1 % multiPaste.length] : textLines,
7732
+ origin: origin || (paste ? "paste" : cm.state.cutIncoming ? "cut" : "+input")}
7733
+ makeChange(cm.doc, changeEvent)
7734
+ signalLater(cm, "inputRead", cm, changeEvent)
7735
+ }
7736
+ if (inserted && !paste)
7737
+ { triggerElectric(cm, inserted) }
7738
+
7739
+ ensureCursorVisible(cm)
7740
+ cm.curOp.updateInput = updateInput
7741
+ cm.curOp.typing = true
7742
+ cm.state.pasteIncoming = cm.state.cutIncoming = false
7743
+ }
7744
+
7745
+ function handlePaste(e, cm) {
7746
+ var pasted = e.clipboardData && e.clipboardData.getData("Text")
7747
+ if (pasted) {
7748
+ e.preventDefault()
7749
+ if (!cm.isReadOnly() && !cm.options.disableInput)
7750
+ { runInOp(cm, function () { return applyTextInput(cm, pasted, 0, null, "paste"); }) }
7751
+ return true
7752
+ }
7753
+ }
7754
+
7755
+ function triggerElectric(cm, inserted) {
7756
+ // When an 'electric' character is inserted, immediately trigger a reindent
7757
+ if (!cm.options.electricChars || !cm.options.smartIndent) { return }
7758
+ var sel = cm.doc.sel
7759
+
7760
+ for (var i = sel.ranges.length - 1; i >= 0; i--) {
7761
+ var range = sel.ranges[i]
7762
+ if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) { continue }
7763
+ var mode = cm.getModeAt(range.head)
7764
+ var indented = false
7765
+ if (mode.electricChars) {
7766
+ for (var j = 0; j < mode.electricChars.length; j++)
7767
+ { if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {
7768
+ indented = indentLine(cm, range.head.line, "smart")
7769
+ break
7770
+ } }
7771
+ } else if (mode.electricInput) {
7772
+ if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch)))
7773
+ { indented = indentLine(cm, range.head.line, "smart") }
7774
+ }
7775
+ if (indented) { signalLater(cm, "electricInput", cm, range.head.line) }
7776
+ }
7777
+ }
7778
+
7779
+ function copyableRanges(cm) {
7780
+ var text = [], ranges = []
7781
+ for (var i = 0; i < cm.doc.sel.ranges.length; i++) {
7782
+ var line = cm.doc.sel.ranges[i].head.line
7783
+ var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)}
7784
+ ranges.push(lineRange)
7785
+ text.push(cm.getRange(lineRange.anchor, lineRange.head))
7786
+ }
7787
+ return {text: text, ranges: ranges}
7788
+ }
7789
+
7790
+ function disableBrowserMagic(field, spellcheck) {
7791
+ field.setAttribute("autocorrect", "off")
7792
+ field.setAttribute("autocapitalize", "off")
7793
+ field.setAttribute("spellcheck", !!spellcheck)
7794
+ }
7795
+
7796
+ function hiddenTextarea() {
7797
+ var te = elt("textarea", null, null, "position: absolute; bottom: -1em; padding: 0; width: 1px; height: 1em; outline: none")
7798
+ var div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;")
7799
+ // The textarea is kept positioned near the cursor to prevent the
7800
+ // fact that it'll be scrolled into view on input from scrolling
7801
+ // our fake cursor out of view. On webkit, when wrap=off, paste is
7802
+ // very slow. So make the area wide instead.
7803
+ if (webkit) { te.style.width = "1000px" }
7804
+ else { te.setAttribute("wrap", "off") }
7805
+ // If border: 0; -- iOS fails to open keyboard (issue #1287)
7806
+ if (ios) { te.style.border = "1px solid black" }
7807
+ disableBrowserMagic(te)
7808
+ return div
7809
+ }
7810
+
7811
+ // The publicly visible API. Note that methodOp(f) means
7812
+ // 'wrap f in an operation, performed on its `this` parameter'.
7813
+
7814
+ // This is not the complete set of editor methods. Most of the
7815
+ // methods defined on the Doc type are also injected into
7816
+ // CodeMirror.prototype, for backwards compatibility and
7817
+ // convenience.
7818
+
7819
+ function addEditorMethods(CodeMirror) {
7820
+ var optionHandlers = CodeMirror.optionHandlers
7821
+
7822
+ var helpers = CodeMirror.helpers = {}
7823
+
7824
+ CodeMirror.prototype = {
7825
+ constructor: CodeMirror,
7826
+ focus: function(){window.focus(); this.display.input.focus()},
7827
+
7828
+ setOption: function(option, value) {
7829
+ var options = this.options, old = options[option]
7830
+ if (options[option] == value && option != "mode") { return }
7831
+ options[option] = value
7832
+ if (optionHandlers.hasOwnProperty(option))
7833
+ { operation(this, optionHandlers[option])(this, value, old) }
7834
+ signal(this, "optionChange", this, option)
7835
+ },
7836
+
7837
+ getOption: function(option) {return this.options[option]},
7838
+ getDoc: function() {return this.doc},
7839
+
7840
+ addKeyMap: function(map, bottom) {
7841
+ this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map))
7842
+ },
7843
+ removeKeyMap: function(map) {
7844
+ var maps = this.state.keyMaps
7845
+ for (var i = 0; i < maps.length; ++i)
7846
+ { if (maps[i] == map || maps[i].name == map) {
7847
+ maps.splice(i, 1)
7848
+ return true
7849
+ } }
7850
+ },
7851
+
7852
+ addOverlay: methodOp(function(spec, options) {
7853
+ var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec)
7854
+ if (mode.startState) { throw new Error("Overlays may not be stateful.") }
7855
+ insertSorted(this.state.overlays,
7856
+ {mode: mode, modeSpec: spec, opaque: options && options.opaque,
7857
+ priority: (options && options.priority) || 0},
7858
+ function (overlay) { return overlay.priority; })
7859
+ this.state.modeGen++
7860
+ regChange(this)
7861
+ }),
7862
+ removeOverlay: methodOp(function(spec) {
7863
+ var this$1 = this;
7864
+
7865
+ var overlays = this.state.overlays
7866
+ for (var i = 0; i < overlays.length; ++i) {
7867
+ var cur = overlays[i].modeSpec
7868
+ if (cur == spec || typeof spec == "string" && cur.name == spec) {
7869
+ overlays.splice(i, 1)
7870
+ this$1.state.modeGen++
7871
+ regChange(this$1)
7872
+ return
7873
+ }
7874
+ }
7875
+ }),
7876
+
7877
+ indentLine: methodOp(function(n, dir, aggressive) {
7878
+ if (typeof dir != "string" && typeof dir != "number") {
7879
+ if (dir == null) { dir = this.options.smartIndent ? "smart" : "prev" }
7880
+ else { dir = dir ? "add" : "subtract" }
7881
+ }
7882
+ if (isLine(this.doc, n)) { indentLine(this, n, dir, aggressive) }
7883
+ }),
7884
+ indentSelection: methodOp(function(how) {
7885
+ var this$1 = this;
7886
+
7887
+ var ranges = this.doc.sel.ranges, end = -1
7888
+ for (var i = 0; i < ranges.length; i++) {
7889
+ var range = ranges[i]
7890
+ if (!range.empty()) {
7891
+ var from = range.from(), to = range.to()
7892
+ var start = Math.max(end, from.line)
7893
+ end = Math.min(this$1.lastLine(), to.line - (to.ch ? 0 : 1)) + 1
7894
+ for (var j = start; j < end; ++j)
7895
+ { indentLine(this$1, j, how) }
7896
+ var newRanges = this$1.doc.sel.ranges
7897
+ if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0)
7898
+ { replaceOneSelection(this$1.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll) }
7899
+ } else if (range.head.line > end) {
7900
+ indentLine(this$1, range.head.line, how, true)
7901
+ end = range.head.line
7902
+ if (i == this$1.doc.sel.primIndex) { ensureCursorVisible(this$1) }
7903
+ }
7904
+ }
7905
+ }),
7906
+
7907
+ // Fetch the parser token for a given character. Useful for hacks
7908
+ // that want to inspect the mode state (say, for completion).
7909
+ getTokenAt: function(pos, precise) {
7910
+ return takeToken(this, pos, precise)
7911
+ },
7912
+
7913
+ getLineTokens: function(line, precise) {
7914
+ return takeToken(this, Pos(line), precise, true)
7915
+ },
7916
+
7917
+ getTokenTypeAt: function(pos) {
7918
+ pos = clipPos(this.doc, pos)
7919
+ var styles = getLineStyles(this, getLine(this.doc, pos.line))
7920
+ var before = 0, after = (styles.length - 1) / 2, ch = pos.ch
7921
+ var type
7922
+ if (ch == 0) { type = styles[2] }
7923
+ else { for (;;) {
7924
+ var mid = (before + after) >> 1
7925
+ if ((mid ? styles[mid * 2 - 1] : 0) >= ch) { after = mid }
7926
+ else if (styles[mid * 2 + 1] < ch) { before = mid + 1 }
7927
+ else { type = styles[mid * 2 + 2]; break }
7928
+ } }
7929
+ var cut = type ? type.indexOf("overlay ") : -1
7930
+ return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1)
7931
+ },
7932
+
7933
+ getModeAt: function(pos) {
7934
+ var mode = this.doc.mode
7935
+ if (!mode.innerMode) { return mode }
7936
+ return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode
7937
+ },
7938
+
7939
+ getHelper: function(pos, type) {
7940
+ return this.getHelpers(pos, type)[0]
7941
+ },
7942
+
7943
+ getHelpers: function(pos, type) {
7944
+ var this$1 = this;
7945
+
7946
+ var found = []
7947
+ if (!helpers.hasOwnProperty(type)) { return found }
7948
+ var help = helpers[type], mode = this.getModeAt(pos)
7949
+ if (typeof mode[type] == "string") {
7950
+ if (help[mode[type]]) { found.push(help[mode[type]]) }
7951
+ } else if (mode[type]) {
7952
+ for (var i = 0; i < mode[type].length; i++) {
7953
+ var val = help[mode[type][i]]
7954
+ if (val) { found.push(val) }
7955
+ }
7956
+ } else if (mode.helperType && help[mode.helperType]) {
7957
+ found.push(help[mode.helperType])
7958
+ } else if (help[mode.name]) {
7959
+ found.push(help[mode.name])
7960
+ }
7961
+ for (var i$1 = 0; i$1 < help._global.length; i$1++) {
7962
+ var cur = help._global[i$1]
7963
+ if (cur.pred(mode, this$1) && indexOf(found, cur.val) == -1)
7964
+ { found.push(cur.val) }
7965
+ }
7966
+ return found
7967
+ },
7968
+
7969
+ getStateAfter: function(line, precise) {
7970
+ var doc = this.doc
7971
+ line = clipLine(doc, line == null ? doc.first + doc.size - 1: line)
7972
+ return getStateBefore(this, line + 1, precise)
7973
+ },
7974
+
7975
+ cursorCoords: function(start, mode) {
7976
+ var pos, range = this.doc.sel.primary()
7977
+ if (start == null) { pos = range.head }
7978
+ else if (typeof start == "object") { pos = clipPos(this.doc, start) }
7979
+ else { pos = start ? range.from() : range.to() }
7980
+ return cursorCoords(this, pos, mode || "page")
7981
+ },
7982
+
7983
+ charCoords: function(pos, mode) {
7984
+ return charCoords(this, clipPos(this.doc, pos), mode || "page")
7985
+ },
7986
+
7987
+ coordsChar: function(coords, mode) {
7988
+ coords = fromCoordSystem(this, coords, mode || "page")
7989
+ return coordsChar(this, coords.left, coords.top)
7990
+ },
7991
+
7992
+ lineAtHeight: function(height, mode) {
7993
+ height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top
7994
+ return lineAtHeight(this.doc, height + this.display.viewOffset)
7995
+ },
7996
+ heightAtLine: function(line, mode, includeWidgets) {
7997
+ var end = false, lineObj
7998
+ if (typeof line == "number") {
7999
+ var last = this.doc.first + this.doc.size - 1
8000
+ if (line < this.doc.first) { line = this.doc.first }
8001
+ else if (line > last) { line = last; end = true }
8002
+ lineObj = getLine(this.doc, line)
8003
+ } else {
8004
+ lineObj = line
8005
+ }
8006
+ return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page", includeWidgets || end).top +
8007
+ (end ? this.doc.height - heightAtLine(lineObj) : 0)
8008
+ },
8009
+
8010
+ defaultTextHeight: function() { return textHeight(this.display) },
8011
+ defaultCharWidth: function() { return charWidth(this.display) },
8012
+
8013
+ getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo}},
8014
+
8015
+ addWidget: function(pos, node, scroll, vert, horiz) {
8016
+ var display = this.display
8017
+ pos = cursorCoords(this, clipPos(this.doc, pos))
8018
+ var top = pos.bottom, left = pos.left
8019
+ node.style.position = "absolute"
8020
+ node.setAttribute("cm-ignore-events", "true")
8021
+ this.display.input.setUneditable(node)
8022
+ display.sizer.appendChild(node)
8023
+ if (vert == "over") {
8024
+ top = pos.top
8025
+ } else if (vert == "above" || vert == "near") {
8026
+ var vspace = Math.max(display.wrapper.clientHeight, this.doc.height),
8027
+ hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth)
8028
+ // Default to positioning above (if specified and possible); otherwise default to positioning below
8029
+ if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight)
8030
+ { top = pos.top - node.offsetHeight }
8031
+ else if (pos.bottom + node.offsetHeight <= vspace)
8032
+ { top = pos.bottom }
8033
+ if (left + node.offsetWidth > hspace)
8034
+ { left = hspace - node.offsetWidth }
8035
+ }
8036
+ node.style.top = top + "px"
8037
+ node.style.left = node.style.right = ""
8038
+ if (horiz == "right") {
8039
+ left = display.sizer.clientWidth - node.offsetWidth
8040
+ node.style.right = "0px"
8041
+ } else {
8042
+ if (horiz == "left") { left = 0 }
8043
+ else if (horiz == "middle") { left = (display.sizer.clientWidth - node.offsetWidth) / 2 }
8044
+ node.style.left = left + "px"
8045
+ }
8046
+ if (scroll)
8047
+ { scrollIntoView(this, {left: left, top: top, right: left + node.offsetWidth, bottom: top + node.offsetHeight}) }
8048
+ },
8049
+
8050
+ triggerOnKeyDown: methodOp(onKeyDown),
8051
+ triggerOnKeyPress: methodOp(onKeyPress),
8052
+ triggerOnKeyUp: onKeyUp,
8053
+
8054
+ execCommand: function(cmd) {
8055
+ if (commands.hasOwnProperty(cmd))
8056
+ { return commands[cmd].call(null, this) }
8057
+ },
8058
+
8059
+ triggerElectric: methodOp(function(text) { triggerElectric(this, text) }),
8060
+
8061
+ findPosH: function(from, amount, unit, visually) {
8062
+ var this$1 = this;
8063
+
8064
+ var dir = 1
8065
+ if (amount < 0) { dir = -1; amount = -amount }
8066
+ var cur = clipPos(this.doc, from)
8067
+ for (var i = 0; i < amount; ++i) {
8068
+ cur = findPosH(this$1.doc, cur, dir, unit, visually)
8069
+ if (cur.hitSide) { break }
8070
+ }
8071
+ return cur
8072
+ },
8073
+
8074
+ moveH: methodOp(function(dir, unit) {
8075
+ var this$1 = this;
8076
+
8077
+ this.extendSelectionsBy(function (range) {
8078
+ if (this$1.display.shift || this$1.doc.extend || range.empty())
8079
+ { return findPosH(this$1.doc, range.head, dir, unit, this$1.options.rtlMoveVisually) }
8080
+ else
8081
+ { return dir < 0 ? range.from() : range.to() }
8082
+ }, sel_move)
8083
+ }),
8084
+
8085
+ deleteH: methodOp(function(dir, unit) {
8086
+ var sel = this.doc.sel, doc = this.doc
8087
+ if (sel.somethingSelected())
8088
+ { doc.replaceSelection("", null, "+delete") }
8089
+ else
8090
+ { deleteNearSelection(this, function (range) {
8091
+ var other = findPosH(doc, range.head, dir, unit, false)
8092
+ return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other}
8093
+ }) }
8094
+ }),
8095
+
8096
+ findPosV: function(from, amount, unit, goalColumn) {
8097
+ var this$1 = this;
8098
+
8099
+ var dir = 1, x = goalColumn
8100
+ if (amount < 0) { dir = -1; amount = -amount }
8101
+ var cur = clipPos(this.doc, from)
8102
+ for (var i = 0; i < amount; ++i) {
8103
+ var coords = cursorCoords(this$1, cur, "div")
8104
+ if (x == null) { x = coords.left }
8105
+ else { coords.left = x }
8106
+ cur = findPosV(this$1, coords, dir, unit)
8107
+ if (cur.hitSide) { break }
8108
+ }
8109
+ return cur
8110
+ },
8111
+
8112
+ moveV: methodOp(function(dir, unit) {
8113
+ var this$1 = this;
8114
+
8115
+ var doc = this.doc, goals = []
8116
+ var collapse = !this.display.shift && !doc.extend && doc.sel.somethingSelected()
8117
+ doc.extendSelectionsBy(function (range) {
8118
+ if (collapse)
8119
+ { return dir < 0 ? range.from() : range.to() }
8120
+ var headPos = cursorCoords(this$1, range.head, "div")
8121
+ if (range.goalColumn != null) { headPos.left = range.goalColumn }
8122
+ goals.push(headPos.left)
8123
+ var pos = findPosV(this$1, headPos, dir, unit)
8124
+ if (unit == "page" && range == doc.sel.primary())
8125
+ { addToScrollTop(this$1, charCoords(this$1, pos, "div").top - headPos.top) }
8126
+ return pos
8127
+ }, sel_move)
8128
+ if (goals.length) { for (var i = 0; i < doc.sel.ranges.length; i++)
8129
+ { doc.sel.ranges[i].goalColumn = goals[i] } }
8130
+ }),
8131
+
8132
+ // Find the word at the given position (as returned by coordsChar).
8133
+ findWordAt: function(pos) {
8134
+ var doc = this.doc, line = getLine(doc, pos.line).text
8135
+ var start = pos.ch, end = pos.ch
8136
+ if (line) {
8137
+ var helper = this.getHelper(pos, "wordChars")
8138
+ if ((pos.sticky == "before" || end == line.length) && start) { --start; } else { ++end }
8139
+ var startChar = line.charAt(start)
8140
+ var check = isWordChar(startChar, helper)
8141
+ ? function (ch) { return isWordChar(ch, helper); }
8142
+ : /\s/.test(startChar) ? function (ch) { return /\s/.test(ch); }
8143
+ : function (ch) { return (!/\s/.test(ch) && !isWordChar(ch)); }
8144
+ while (start > 0 && check(line.charAt(start - 1))) { --start }
8145
+ while (end < line.length && check(line.charAt(end))) { ++end }
8146
+ }
8147
+ return new Range(Pos(pos.line, start), Pos(pos.line, end))
8148
+ },
8149
+
8150
+ toggleOverwrite: function(value) {
8151
+ if (value != null && value == this.state.overwrite) { return }
8152
+ if (this.state.overwrite = !this.state.overwrite)
8153
+ { addClass(this.display.cursorDiv, "CodeMirror-overwrite") }
8154
+ else
8155
+ { rmClass(this.display.cursorDiv, "CodeMirror-overwrite") }
8156
+
8157
+ signal(this, "overwriteToggle", this, this.state.overwrite)
8158
+ },
8159
+ hasFocus: function() { return this.display.input.getField() == activeElt() },
8160
+ isReadOnly: function() { return !!(this.options.readOnly || this.doc.cantEdit) },
8161
+
8162
+ scrollTo: methodOp(function (x, y) { scrollToCoords(this, x, y) }),
8163
+ getScrollInfo: function() {
8164
+ var scroller = this.display.scroller
8165
+ return {left: scroller.scrollLeft, top: scroller.scrollTop,
8166
+ height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight,
8167
+ width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth,
8168
+ clientHeight: displayHeight(this), clientWidth: displayWidth(this)}
8169
+ },
8170
+
8171
+ scrollIntoView: methodOp(function(range, margin) {
8172
+ if (range == null) {
8173
+ range = {from: this.doc.sel.primary().head, to: null}
8174
+ if (margin == null) { margin = this.options.cursorScrollMargin }
8175
+ } else if (typeof range == "number") {
8176
+ range = {from: Pos(range, 0), to: null}
8177
+ } else if (range.from == null) {
8178
+ range = {from: range, to: null}
8179
+ }
8180
+ if (!range.to) { range.to = range.from }
8181
+ range.margin = margin || 0
8182
+
8183
+ if (range.from.line != null) {
8184
+ scrollToRange(this, range)
8185
+ } else {
8186
+ scrollToCoordsRange(this, range.from, range.to, range.margin)
8187
+ }
8188
+ }),
8189
+
8190
+ setSize: methodOp(function(width, height) {
8191
+ var this$1 = this;
8192
+
8193
+ var interpret = function (val) { return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val; }
8194
+ if (width != null) { this.display.wrapper.style.width = interpret(width) }
8195
+ if (height != null) { this.display.wrapper.style.height = interpret(height) }
8196
+ if (this.options.lineWrapping) { clearLineMeasurementCache(this) }
8197
+ var lineNo = this.display.viewFrom
8198
+ this.doc.iter(lineNo, this.display.viewTo, function (line) {
8199
+ if (line.widgets) { for (var i = 0; i < line.widgets.length; i++)
8200
+ { if (line.widgets[i].noHScroll) { regLineChange(this$1, lineNo, "widget"); break } } }
8201
+ ++lineNo
8202
+ })
8203
+ this.curOp.forceUpdate = true
8204
+ signal(this, "refresh", this)
8205
+ }),
8206
+
8207
+ operation: function(f){return runInOp(this, f)},
8208
+
8209
+ refresh: methodOp(function() {
8210
+ var oldHeight = this.display.cachedTextHeight
8211
+ regChange(this)
8212
+ this.curOp.forceUpdate = true
8213
+ clearCaches(this)
8214
+ scrollToCoords(this, this.doc.scrollLeft, this.doc.scrollTop)
8215
+ updateGutterSpace(this)
8216
+ if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)
8217
+ { estimateLineHeights(this) }
8218
+ signal(this, "refresh", this)
8219
+ }),
8220
+
8221
+ swapDoc: methodOp(function(doc) {
8222
+ var old = this.doc
8223
+ old.cm = null
8224
+ attachDoc(this, doc)
8225
+ clearCaches(this)
8226
+ this.display.input.reset()
8227
+ scrollToCoords(this, doc.scrollLeft, doc.scrollTop)
8228
+ this.curOp.forceScroll = true
8229
+ signalLater(this, "swapDoc", this, old)
8230
+ return old
8231
+ }),
8232
+
8233
+ getInputField: function(){return this.display.input.getField()},
8234
+ getWrapperElement: function(){return this.display.wrapper},
8235
+ getScrollerElement: function(){return this.display.scroller},
8236
+ getGutterElement: function(){return this.display.gutters}
8237
+ }
8238
+ eventMixin(CodeMirror)
8239
+
8240
+ CodeMirror.registerHelper = function(type, name, value) {
8241
+ if (!helpers.hasOwnProperty(type)) { helpers[type] = CodeMirror[type] = {_global: []} }
8242
+ helpers[type][name] = value
8243
+ }
8244
+ CodeMirror.registerGlobalHelper = function(type, name, predicate, value) {
8245
+ CodeMirror.registerHelper(type, name, value)
8246
+ helpers[type]._global.push({pred: predicate, val: value})
8247
+ }
8248
+ }
8249
+
8250
+ // Used for horizontal relative motion. Dir is -1 or 1 (left or
8251
+ // right), unit can be "char", "column" (like char, but doesn't
8252
+ // cross line boundaries), "word" (across next word), or "group" (to
8253
+ // the start of next group of word or non-word-non-whitespace
8254
+ // chars). The visually param controls whether, in right-to-left
8255
+ // text, direction 1 means to move towards the next index in the
8256
+ // string, or towards the character to the right of the current
8257
+ // position. The resulting position will have a hitSide=true
8258
+ // property if it reached the end of the document.
8259
+ function findPosH(doc, pos, dir, unit, visually) {
8260
+ var oldPos = pos
8261
+ var origDir = dir
8262
+ var lineObj = getLine(doc, pos.line)
8263
+ function findNextLine() {
8264
+ var l = pos.line + dir
8265
+ if (l < doc.first || l >= doc.first + doc.size) { return false }
8266
+ pos = new Pos(l, pos.ch, pos.sticky)
8267
+ return lineObj = getLine(doc, l)
8268
+ }
8269
+ function moveOnce(boundToLine) {
8270
+ var next
8271
+ if (visually) {
8272
+ next = moveVisually(doc.cm, lineObj, pos, dir)
8273
+ } else {
8274
+ next = moveLogically(lineObj, pos, dir)
8275
+ }
8276
+ if (next == null) {
8277
+ if (!boundToLine && findNextLine())
8278
+ { pos = endOfLine(visually, doc.cm, lineObj, pos.line, dir) }
8279
+ else
8280
+ { return false }
8281
+ } else {
8282
+ pos = next
8283
+ }
8284
+ return true
8285
+ }
8286
+
8287
+ if (unit == "char") {
8288
+ moveOnce()
8289
+ } else if (unit == "column") {
8290
+ moveOnce(true)
8291
+ } else if (unit == "word" || unit == "group") {
8292
+ var sawType = null, group = unit == "group"
8293
+ var helper = doc.cm && doc.cm.getHelper(pos, "wordChars")
8294
+ for (var first = true;; first = false) {
8295
+ if (dir < 0 && !moveOnce(!first)) { break }
8296
+ var cur = lineObj.text.charAt(pos.ch) || "\n"
8297
+ var type = isWordChar(cur, helper) ? "w"
8298
+ : group && cur == "\n" ? "n"
8299
+ : !group || /\s/.test(cur) ? null
8300
+ : "p"
8301
+ if (group && !first && !type) { type = "s" }
8302
+ if (sawType && sawType != type) {
8303
+ if (dir < 0) {dir = 1; moveOnce(); pos.sticky = "after"}
8304
+ break
8305
+ }
8306
+
8307
+ if (type) { sawType = type }
8308
+ if (dir > 0 && !moveOnce(!first)) { break }
8309
+ }
8310
+ }
8311
+ var result = skipAtomic(doc, pos, oldPos, origDir, true)
8312
+ if (equalCursorPos(oldPos, result)) { result.hitSide = true }
8313
+ return result
8314
+ }
8315
+
8316
+ // For relative vertical movement. Dir may be -1 or 1. Unit can be
8317
+ // "page" or "line". The resulting position will have a hitSide=true
8318
+ // property if it reached the end of the document.
8319
+ function findPosV(cm, pos, dir, unit) {
8320
+ var doc = cm.doc, x = pos.left, y
8321
+ if (unit == "page") {
8322
+ var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight)
8323
+ var moveAmount = Math.max(pageSize - .5 * textHeight(cm.display), 3)
8324
+ y = (dir > 0 ? pos.bottom : pos.top) + dir * moveAmount
8325
+
8326
+ } else if (unit == "line") {
8327
+ y = dir > 0 ? pos.bottom + 3 : pos.top - 3
8328
+ }
8329
+ var target
8330
+ for (;;) {
8331
+ target = coordsChar(cm, x, y)
8332
+ if (!target.outside) { break }
8333
+ if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break }
8334
+ y += dir * 5
8335
+ }
8336
+ return target
8337
+ }
8338
+
8339
+ // CONTENTEDITABLE INPUT STYLE
8340
+
8341
+ var ContentEditableInput = function(cm) {
8342
+ this.cm = cm
8343
+ this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null
8344
+ this.polling = new Delayed()
8345
+ this.composing = null
8346
+ this.gracePeriod = false
8347
+ this.readDOMTimeout = null
8348
+ };
8349
+
8350
+ ContentEditableInput.prototype.init = function (display) {
8351
+ var this$1 = this;
8352
+
8353
+ var input = this, cm = input.cm
8354
+ var div = input.div = display.lineDiv
8355
+ disableBrowserMagic(div, cm.options.spellcheck)
8356
+
8357
+ on(div, "paste", function (e) {
8358
+ if (signalDOMEvent(cm, e) || handlePaste(e, cm)) { return }
8359
+ // IE doesn't fire input events, so we schedule a read for the pasted content in this way
8360
+ if (ie_version <= 11) { setTimeout(operation(cm, function () { return this$1.updateFromDOM(); }), 20) }
8361
+ })
8362
+
8363
+ on(div, "compositionstart", function (e) {
8364
+ this$1.composing = {data: e.data, done: false}
8365
+ })
8366
+ on(div, "compositionupdate", function (e) {
8367
+ if (!this$1.composing) { this$1.composing = {data: e.data, done: false} }
8368
+ })
8369
+ on(div, "compositionend", function (e) {
8370
+ if (this$1.composing) {
8371
+ if (e.data != this$1.composing.data) { this$1.readFromDOMSoon() }
8372
+ this$1.composing.done = true
8373
+ }
8374
+ })
8375
+
8376
+ on(div, "touchstart", function () { return input.forceCompositionEnd(); })
8377
+
8378
+ on(div, "input", function () {
8379
+ if (!this$1.composing) { this$1.readFromDOMSoon() }
8380
+ })
8381
+
8382
+ function onCopyCut(e) {
8383
+ if (signalDOMEvent(cm, e)) { return }
8384
+ if (cm.somethingSelected()) {
8385
+ setLastCopied({lineWise: false, text: cm.getSelections()})
8386
+ if (e.type == "cut") { cm.replaceSelection("", null, "cut") }
8387
+ } else if (!cm.options.lineWiseCopyCut) {
8388
+ return
8389
+ } else {
8390
+ var ranges = copyableRanges(cm)
8391
+ setLastCopied({lineWise: true, text: ranges.text})
8392
+ if (e.type == "cut") {
8393
+ cm.operation(function () {
8394
+ cm.setSelections(ranges.ranges, 0, sel_dontScroll)
8395
+ cm.replaceSelection("", null, "cut")
8396
+ })
8397
+ }
8398
+ }
8399
+ if (e.clipboardData) {
8400
+ e.clipboardData.clearData()
8401
+ var content = lastCopied.text.join("\n")
8402
+ // iOS exposes the clipboard API, but seems to discard content inserted into it
8403
+ e.clipboardData.setData("Text", content)
8404
+ if (e.clipboardData.getData("Text") == content) {
8405
+ e.preventDefault()
8406
+ return
8407
+ }
8408
+ }
8409
+ // Old-fashioned briefly-focus-a-textarea hack
8410
+ var kludge = hiddenTextarea(), te = kludge.firstChild
8411
+ cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild)
8412
+ te.value = lastCopied.text.join("\n")
8413
+ var hadFocus = document.activeElement
8414
+ selectInput(te)
8415
+ setTimeout(function () {
8416
+ cm.display.lineSpace.removeChild(kludge)
8417
+ hadFocus.focus()
8418
+ if (hadFocus == div) { input.showPrimarySelection() }
8419
+ }, 50)
8420
+ }
8421
+ on(div, "copy", onCopyCut)
8422
+ on(div, "cut", onCopyCut)
8423
+ };
8424
+
8425
+ ContentEditableInput.prototype.prepareSelection = function () {
8426
+ var result = prepareSelection(this.cm, false)
8427
+ result.focus = this.cm.state.focused
8428
+ return result
8429
+ };
8430
+
8431
+ ContentEditableInput.prototype.showSelection = function (info, takeFocus) {
8432
+ if (!info || !this.cm.display.view.length) { return }
8433
+ if (info.focus || takeFocus) { this.showPrimarySelection() }
8434
+ this.showMultipleSelections(info)
8435
+ };
8436
+
8437
+ ContentEditableInput.prototype.showPrimarySelection = function () {
8438
+ var sel = window.getSelection(), cm = this.cm, prim = cm.doc.sel.primary()
8439
+ var from = prim.from(), to = prim.to()
8440
+
8441
+ if (cm.display.viewTo == cm.display.viewFrom || from.line >= cm.display.viewTo || to.line < cm.display.viewFrom) {
8442
+ sel.removeAllRanges()
8443
+ return
8444
+ }
8445
+
8446
+ var curAnchor = domToPos(cm, sel.anchorNode, sel.anchorOffset)
8447
+ var curFocus = domToPos(cm, sel.focusNode, sel.focusOffset)
8448
+ if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad &&
8449
+ cmp(minPos(curAnchor, curFocus), from) == 0 &&
8450
+ cmp(maxPos(curAnchor, curFocus), to) == 0)
8451
+ { return }
8452
+
8453
+ var view = cm.display.view
8454
+ var start = (from.line >= cm.display.viewFrom && posToDOM(cm, from)) ||
8455
+ {node: view[0].measure.map[2], offset: 0}
8456
+ var end = to.line < cm.display.viewTo && posToDOM(cm, to)
8457
+ if (!end) {
8458
+ var measure = view[view.length - 1].measure
8459
+ var map = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map
8460
+ end = {node: map[map.length - 1], offset: map[map.length - 2] - map[map.length - 3]}
8461
+ }
8462
+
8463
+ if (!start || !end) {
8464
+ sel.removeAllRanges()
8465
+ return
8466
+ }
8467
+
8468
+ var old = sel.rangeCount && sel.getRangeAt(0), rng
8469
+ try { rng = range(start.node, start.offset, end.offset, end.node) }
8470
+ catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible
8471
+ if (rng) {
8472
+ if (!gecko && cm.state.focused) {
8473
+ sel.collapse(start.node, start.offset)
8474
+ if (!rng.collapsed) {
8475
+ sel.removeAllRanges()
8476
+ sel.addRange(rng)
8477
+ }
8478
+ } else {
8479
+ sel.removeAllRanges()
8480
+ sel.addRange(rng)
8481
+ }
8482
+ if (old && sel.anchorNode == null) { sel.addRange(old) }
8483
+ else if (gecko) { this.startGracePeriod() }
8484
+ }
8485
+ this.rememberSelection()
8486
+ };
8487
+
8488
+ ContentEditableInput.prototype.startGracePeriod = function () {
8489
+ var this$1 = this;
8490
+
8491
+ clearTimeout(this.gracePeriod)
8492
+ this.gracePeriod = setTimeout(function () {
8493
+ this$1.gracePeriod = false
8494
+ if (this$1.selectionChanged())
8495
+ { this$1.cm.operation(function () { return this$1.cm.curOp.selectionChanged = true; }) }
8496
+ }, 20)
8497
+ };
8498
+
8499
+ ContentEditableInput.prototype.showMultipleSelections = function (info) {
8500
+ removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors)
8501
+ removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection)
8502
+ };
8503
+
8504
+ ContentEditableInput.prototype.rememberSelection = function () {
8505
+ var sel = window.getSelection()
8506
+ this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset
8507
+ this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset
8508
+ };
8509
+
8510
+ ContentEditableInput.prototype.selectionInEditor = function () {
8511
+ var sel = window.getSelection()
8512
+ if (!sel.rangeCount) { return false }
8513
+ var node = sel.getRangeAt(0).commonAncestorContainer
8514
+ return contains(this.div, node)
8515
+ };
8516
+
8517
+ ContentEditableInput.prototype.focus = function () {
8518
+ if (this.cm.options.readOnly != "nocursor") {
8519
+ if (!this.selectionInEditor())
8520
+ { this.showSelection(this.prepareSelection(), true) }
8521
+ this.div.focus()
8522
+ }
8523
+ };
8524
+ ContentEditableInput.prototype.blur = function () { this.div.blur() };
8525
+ ContentEditableInput.prototype.getField = function () { return this.div };
8526
+
8527
+ ContentEditableInput.prototype.supportsTouch = function () { return true };
8528
+
8529
+ ContentEditableInput.prototype.receivedFocus = function () {
8530
+ var input = this
8531
+ if (this.selectionInEditor())
8532
+ { this.pollSelection() }
8533
+ else
8534
+ { runInOp(this.cm, function () { return input.cm.curOp.selectionChanged = true; }) }
8535
+
8536
+ function poll() {
8537
+ if (input.cm.state.focused) {
8538
+ input.pollSelection()
8539
+ input.polling.set(input.cm.options.pollInterval, poll)
8540
+ }
8541
+ }
8542
+ this.polling.set(this.cm.options.pollInterval, poll)
8543
+ };
8544
+
8545
+ ContentEditableInput.prototype.selectionChanged = function () {
8546
+ var sel = window.getSelection()
8547
+ return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset ||
8548
+ sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset
8549
+ };
8550
+
8551
+ ContentEditableInput.prototype.pollSelection = function () {
8552
+ if (this.readDOMTimeout != null || this.gracePeriod || !this.selectionChanged()) { return }
8553
+ var sel = window.getSelection(), cm = this.cm
8554
+ // On Android Chrome (version 56, at least), backspacing into an
8555
+ // uneditable block element will put the cursor in that element,
8556
+ // and then, because it's not editable, hide the virtual keyboard.
8557
+ // Because Android doesn't allow us to actually detect backspace
8558
+ // presses in a sane way, this code checks for when that happens
8559
+ // and simulates a backspace press in this case.
8560
+ if (android && chrome && this.cm.options.gutters.length && isInGutter(sel.anchorNode)) {
8561
+ this.cm.triggerOnKeyDown({type: "keydown", keyCode: 8, preventDefault: Math.abs})
8562
+ this.blur()
8563
+ this.focus()
8564
+ return
8565
+ }
8566
+ if (this.composing) { return }
8567
+ this.rememberSelection()
8568
+ var anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset)
8569
+ var head = domToPos(cm, sel.focusNode, sel.focusOffset)
8570
+ if (anchor && head) { runInOp(cm, function () {
8571
+ setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll)
8572
+ if (anchor.bad || head.bad) { cm.curOp.selectionChanged = true }
8573
+ }) }
8574
+ };
8575
+
8576
+ ContentEditableInput.prototype.pollContent = function () {
8577
+ if (this.readDOMTimeout != null) {
8578
+ clearTimeout(this.readDOMTimeout)
8579
+ this.readDOMTimeout = null
8580
+ }
8581
+
8582
+ var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary()
8583
+ var from = sel.from(), to = sel.to()
8584
+ if (from.ch == 0 && from.line > cm.firstLine())
8585
+ { from = Pos(from.line - 1, getLine(cm.doc, from.line - 1).length) }
8586
+ if (to.ch == getLine(cm.doc, to.line).text.length && to.line < cm.lastLine())
8587
+ { to = Pos(to.line + 1, 0) }
8588
+ if (from.line < display.viewFrom || to.line > display.viewTo - 1) { return false }
8589
+
8590
+ var fromIndex, fromLine, fromNode
8591
+ if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) {
8592
+ fromLine = lineNo(display.view[0].line)
8593
+ fromNode = display.view[0].node
8594
+ } else {
8595
+ fromLine = lineNo(display.view[fromIndex].line)
8596
+ fromNode = display.view[fromIndex - 1].node.nextSibling
8597
+ }
8598
+ var toIndex = findViewIndex(cm, to.line)
8599
+ var toLine, toNode
8600
+ if (toIndex == display.view.length - 1) {
8601
+ toLine = display.viewTo - 1
8602
+ toNode = display.lineDiv.lastChild
8603
+ } else {
8604
+ toLine = lineNo(display.view[toIndex + 1].line) - 1
8605
+ toNode = display.view[toIndex + 1].node.previousSibling
8606
+ }
8607
+
8608
+ if (!fromNode) { return false }
8609
+ var newText = cm.doc.splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine))
8610
+ var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length))
8611
+ while (newText.length > 1 && oldText.length > 1) {
8612
+ if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine-- }
8613
+ else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++ }
8614
+ else { break }
8615
+ }
8616
+
8617
+ var cutFront = 0, cutEnd = 0
8618
+ var newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length)
8619
+ while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront))
8620
+ { ++cutFront }
8621
+ var newBot = lst(newText), oldBot = lst(oldText)
8622
+ var maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0),
8623
+ oldBot.length - (oldText.length == 1 ? cutFront : 0))
8624
+ while (cutEnd < maxCutEnd &&
8625
+ newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1))
8626
+ { ++cutEnd }
8627
+ // Try to move start of change to start of selection if ambiguous
8628
+ if (newText.length == 1 && oldText.length == 1 && fromLine == from.line) {
8629
+ while (cutFront && cutFront > from.ch &&
8630
+ newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1)) {
8631
+ cutFront--
8632
+ cutEnd++
8633
+ }
8634
+ }
8635
+
8636
+ newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd).replace(/^\u200b+/, "")
8637
+ newText[0] = newText[0].slice(cutFront).replace(/\u200b+$/, "")
8638
+
8639
+ var chFrom = Pos(fromLine, cutFront)
8640
+ var chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0)
8641
+ if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) {
8642
+ replaceRange(cm.doc, newText, chFrom, chTo, "+input")
8643
+ return true
8644
+ }
8645
+ };
8646
+
8647
+ ContentEditableInput.prototype.ensurePolled = function () {
8648
+ this.forceCompositionEnd()
8649
+ };
8650
+ ContentEditableInput.prototype.reset = function () {
8651
+ this.forceCompositionEnd()
8652
+ };
8653
+ ContentEditableInput.prototype.forceCompositionEnd = function () {
8654
+ if (!this.composing) { return }
8655
+ clearTimeout(this.readDOMTimeout)
8656
+ this.composing = null
8657
+ this.updateFromDOM()
8658
+ this.div.blur()
8659
+ this.div.focus()
8660
+ };
8661
+ ContentEditableInput.prototype.readFromDOMSoon = function () {
8662
+ var this$1 = this;
8663
+
8664
+ if (this.readDOMTimeout != null) { return }
8665
+ this.readDOMTimeout = setTimeout(function () {
8666
+ this$1.readDOMTimeout = null
8667
+ if (this$1.composing) {
8668
+ if (this$1.composing.done) { this$1.composing = null }
8669
+ else { return }
8670
+ }
8671
+ this$1.updateFromDOM()
8672
+ }, 80)
8673
+ };
8674
+
8675
+ ContentEditableInput.prototype.updateFromDOM = function () {
8676
+ var this$1 = this;
8677
+
8678
+ if (this.cm.isReadOnly() || !this.pollContent())
8679
+ { runInOp(this.cm, function () { return regChange(this$1.cm); }) }
8680
+ };
8681
+
8682
+ ContentEditableInput.prototype.setUneditable = function (node) {
8683
+ node.contentEditable = "false"
8684
+ };
8685
+
8686
+ ContentEditableInput.prototype.onKeyPress = function (e) {
8687
+ if (e.charCode == 0) { return }
8688
+ e.preventDefault()
8689
+ if (!this.cm.isReadOnly())
8690
+ { operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0) }
8691
+ };
8692
+
8693
+ ContentEditableInput.prototype.readOnlyChanged = function (val) {
8694
+ this.div.contentEditable = String(val != "nocursor")
8695
+ };
8696
+
8697
+ ContentEditableInput.prototype.onContextMenu = function () {};
8698
+ ContentEditableInput.prototype.resetPosition = function () {};
8699
+
8700
+ ContentEditableInput.prototype.needsContentAttribute = true
8701
+
8702
+ function posToDOM(cm, pos) {
8703
+ var view = findViewForLine(cm, pos.line)
8704
+ if (!view || view.hidden) { return null }
8705
+ var line = getLine(cm.doc, pos.line)
8706
+ var info = mapFromLineView(view, line, pos.line)
8707
+
8708
+ var order = getOrder(line, cm.doc.direction), side = "left"
8709
+ if (order) {
8710
+ var partPos = getBidiPartAt(order, pos.ch)
8711
+ side = partPos % 2 ? "right" : "left"
8712
+ }
8713
+ var result = nodeAndOffsetInLineMap(info.map, pos.ch, side)
8714
+ result.offset = result.collapse == "right" ? result.end : result.start
8715
+ return result
8716
+ }
8717
+
8718
+ function isInGutter(node) {
8719
+ for (var scan = node; scan; scan = scan.parentNode)
8720
+ { if (/CodeMirror-gutter-wrapper/.test(scan.className)) { return true } }
8721
+ return false
8722
+ }
8723
+
8724
+ function badPos(pos, bad) { if (bad) { pos.bad = true; } return pos }
8725
+
8726
+ function domTextBetween(cm, from, to, fromLine, toLine) {
8727
+ var text = "", closing = false, lineSep = cm.doc.lineSeparator()
8728
+ function recognizeMarker(id) { return function (marker) { return marker.id == id; } }
8729
+ function close() {
8730
+ if (closing) {
8731
+ text += lineSep
8732
+ closing = false
8733
+ }
8734
+ }
8735
+ function addText(str) {
8736
+ if (str) {
8737
+ close()
8738
+ text += str
8739
+ }
8740
+ }
8741
+ function walk(node) {
8742
+ if (node.nodeType == 1) {
8743
+ var cmText = node.getAttribute("cm-text")
8744
+ if (cmText != null) {
8745
+ addText(cmText || node.textContent.replace(/\u200b/g, ""))
8746
+ return
8747
+ }
8748
+ var markerID = node.getAttribute("cm-marker"), range
8749
+ if (markerID) {
8750
+ var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID))
8751
+ if (found.length && (range = found[0].find()))
8752
+ { addText(getBetween(cm.doc, range.from, range.to).join(lineSep)) }
8753
+ return
8754
+ }
8755
+ if (node.getAttribute("contenteditable") == "false") { return }
8756
+ var isBlock = /^(pre|div|p)$/i.test(node.nodeName)
8757
+ if (isBlock) { close() }
8758
+ for (var i = 0; i < node.childNodes.length; i++)
8759
+ { walk(node.childNodes[i]) }
8760
+ if (isBlock) { closing = true }
8761
+ } else if (node.nodeType == 3) {
8762
+ addText(node.nodeValue)
8763
+ }
8764
+ }
8765
+ for (;;) {
8766
+ walk(from)
8767
+ if (from == to) { break }
8768
+ from = from.nextSibling
8769
+ }
8770
+ return text
8771
+ }
8772
+
8773
+ function domToPos(cm, node, offset) {
8774
+ var lineNode
8775
+ if (node == cm.display.lineDiv) {
8776
+ lineNode = cm.display.lineDiv.childNodes[offset]
8777
+ if (!lineNode) { return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true) }
8778
+ node = null; offset = 0
8779
+ } else {
8780
+ for (lineNode = node;; lineNode = lineNode.parentNode) {
8781
+ if (!lineNode || lineNode == cm.display.lineDiv) { return null }
8782
+ if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) { break }
8783
+ }
8784
+ }
8785
+ for (var i = 0; i < cm.display.view.length; i++) {
8786
+ var lineView = cm.display.view[i]
8787
+ if (lineView.node == lineNode)
8788
+ { return locateNodeInLineView(lineView, node, offset) }
8789
+ }
8790
+ }
8791
+
8792
+ function locateNodeInLineView(lineView, node, offset) {
8793
+ var wrapper = lineView.text.firstChild, bad = false
8794
+ if (!node || !contains(wrapper, node)) { return badPos(Pos(lineNo(lineView.line), 0), true) }
8795
+ if (node == wrapper) {
8796
+ bad = true
8797
+ node = wrapper.childNodes[offset]
8798
+ offset = 0
8799
+ if (!node) {
8800
+ var line = lineView.rest ? lst(lineView.rest) : lineView.line
8801
+ return badPos(Pos(lineNo(line), line.text.length), bad)
8802
+ }
8803
+ }
8804
+
8805
+ var textNode = node.nodeType == 3 ? node : null, topNode = node
8806
+ if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) {
8807
+ textNode = node.firstChild
8808
+ if (offset) { offset = textNode.nodeValue.length }
8809
+ }
8810
+ while (topNode.parentNode != wrapper) { topNode = topNode.parentNode }
8811
+ var measure = lineView.measure, maps = measure.maps
8812
+
8813
+ function find(textNode, topNode, offset) {
8814
+ for (var i = -1; i < (maps ? maps.length : 0); i++) {
8815
+ var map = i < 0 ? measure.map : maps[i]
8816
+ for (var j = 0; j < map.length; j += 3) {
8817
+ var curNode = map[j + 2]
8818
+ if (curNode == textNode || curNode == topNode) {
8819
+ var line = lineNo(i < 0 ? lineView.line : lineView.rest[i])
8820
+ var ch = map[j] + offset
8821
+ if (offset < 0 || curNode != textNode) { ch = map[j + (offset ? 1 : 0)] }
8822
+ return Pos(line, ch)
8823
+ }
8824
+ }
8825
+ }
8826
+ }
8827
+ var found = find(textNode, topNode, offset)
8828
+ if (found) { return badPos(found, bad) }
8829
+
8830
+ // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems
8831
+ for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) {
8832
+ found = find(after, after.firstChild, 0)
8833
+ if (found)
8834
+ { return badPos(Pos(found.line, found.ch - dist), bad) }
8835
+ else
8836
+ { dist += after.textContent.length }
8837
+ }
8838
+ for (var before = topNode.previousSibling, dist$1 = offset; before; before = before.previousSibling) {
8839
+ found = find(before, before.firstChild, -1)
8840
+ if (found)
8841
+ { return badPos(Pos(found.line, found.ch + dist$1), bad) }
8842
+ else
8843
+ { dist$1 += before.textContent.length }
8844
+ }
8845
+ }
8846
+
8847
+ // TEXTAREA INPUT STYLE
8848
+
8849
+ var TextareaInput = function(cm) {
8850
+ this.cm = cm
8851
+ // See input.poll and input.reset
8852
+ this.prevInput = ""
8853
+
8854
+ // Flag that indicates whether we expect input to appear real soon
8855
+ // now (after some event like 'keypress' or 'input') and are
8856
+ // polling intensively.
8857
+ this.pollingFast = false
8858
+ // Self-resetting timeout for the poller
8859
+ this.polling = new Delayed()
8860
+ // Tracks when input.reset has punted to just putting a short
8861
+ // string into the textarea instead of the full selection.
8862
+ this.inaccurateSelection = false
8863
+ // Used to work around IE issue with selection being forgotten when focus moves away from textarea
8864
+ this.hasSelection = false
8865
+ this.composing = null
8866
+ };
8867
+
8868
+ TextareaInput.prototype.init = function (display) {
8869
+ var this$1 = this;
8870
+
8871
+ var input = this, cm = this.cm
8872
+
8873
+ // Wraps and hides input textarea
8874
+ var div = this.wrapper = hiddenTextarea()
8875
+ // The semihidden textarea that is focused when the editor is
8876
+ // focused, and receives input.
8877
+ var te = this.textarea = div.firstChild
8878
+ display.wrapper.insertBefore(div, display.wrapper.firstChild)
8879
+
8880
+ // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore)
8881
+ if (ios) { te.style.width = "0px" }
8882
+
8883
+ on(te, "input", function () {
8884
+ if (ie && ie_version >= 9 && this$1.hasSelection) { this$1.hasSelection = null }
8885
+ input.poll()
8886
+ })
8887
+
8888
+ on(te, "paste", function (e) {
8889
+ if (signalDOMEvent(cm, e) || handlePaste(e, cm)) { return }
8890
+
8891
+ cm.state.pasteIncoming = true
8892
+ input.fastPoll()
8893
+ })
8894
+
8895
+ function prepareCopyCut(e) {
8896
+ if (signalDOMEvent(cm, e)) { return }
8897
+ if (cm.somethingSelected()) {
8898
+ setLastCopied({lineWise: false, text: cm.getSelections()})
8899
+ if (input.inaccurateSelection) {
8900
+ input.prevInput = ""
8901
+ input.inaccurateSelection = false
8902
+ te.value = lastCopied.text.join("\n")
8903
+ selectInput(te)
8904
+ }
8905
+ } else if (!cm.options.lineWiseCopyCut) {
8906
+ return
8907
+ } else {
8908
+ var ranges = copyableRanges(cm)
8909
+ setLastCopied({lineWise: true, text: ranges.text})
8910
+ if (e.type == "cut") {
8911
+ cm.setSelections(ranges.ranges, null, sel_dontScroll)
8912
+ } else {
8913
+ input.prevInput = ""
8914
+ te.value = ranges.text.join("\n")
8915
+ selectInput(te)
8916
+ }
8917
+ }
8918
+ if (e.type == "cut") { cm.state.cutIncoming = true }
8919
+ }
8920
+ on(te, "cut", prepareCopyCut)
8921
+ on(te, "copy", prepareCopyCut)
8922
+
8923
+ on(display.scroller, "paste", function (e) {
8924
+ if (eventInWidget(display, e) || signalDOMEvent(cm, e)) { return }
8925
+ cm.state.pasteIncoming = true
8926
+ input.focus()
8927
+ })
8928
+
8929
+ // Prevent normal selection in the editor (we handle our own)
8930
+ on(display.lineSpace, "selectstart", function (e) {
8931
+ if (!eventInWidget(display, e)) { e_preventDefault(e) }
8932
+ })
8933
+
8934
+ on(te, "compositionstart", function () {
8935
+ var start = cm.getCursor("from")
8936
+ if (input.composing) { input.composing.range.clear() }
8937
+ input.composing = {
8938
+ start: start,
8939
+ range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"})
8940
+ }
8941
+ })
8942
+ on(te, "compositionend", function () {
8943
+ if (input.composing) {
8944
+ input.poll()
8945
+ input.composing.range.clear()
8946
+ input.composing = null
8947
+ }
8948
+ })
8949
+ };
8950
+
8951
+ TextareaInput.prototype.prepareSelection = function () {
8952
+ // Redraw the selection and/or cursor
8953
+ var cm = this.cm, display = cm.display, doc = cm.doc
8954
+ var result = prepareSelection(cm)
8955
+
8956
+ // Move the hidden textarea near the cursor to prevent scrolling artifacts
8957
+ if (cm.options.moveInputWithCursor) {
8958
+ var headPos = cursorCoords(cm, doc.sel.primary().head, "div")
8959
+ var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect()
8960
+ result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
8961
+ headPos.top + lineOff.top - wrapOff.top))
8962
+ result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
8963
+ headPos.left + lineOff.left - wrapOff.left))
8964
+ }
8965
+
8966
+ return result
8967
+ };
8968
+
8969
+ TextareaInput.prototype.showSelection = function (drawn) {
8970
+ var cm = this.cm, display = cm.display
8971
+ removeChildrenAndAdd(display.cursorDiv, drawn.cursors)
8972
+ removeChildrenAndAdd(display.selectionDiv, drawn.selection)
8973
+ if (drawn.teTop != null) {
8974
+ this.wrapper.style.top = drawn.teTop + "px"
8975
+ this.wrapper.style.left = drawn.teLeft + "px"
8976
+ }
8977
+ };
8978
+
8979
+ // Reset the input to correspond to the selection (or to be empty,
8980
+ // when not typing and nothing is selected)
8981
+ TextareaInput.prototype.reset = function (typing) {
8982
+ if (this.contextMenuPending || this.composing) { return }
8983
+ var minimal, selected, cm = this.cm, doc = cm.doc
8984
+ if (cm.somethingSelected()) {
8985
+ this.prevInput = ""
8986
+ var range = doc.sel.primary()
8987
+ minimal = hasCopyEvent &&
8988
+ (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000)
8989
+ var content = minimal ? "-" : selected || cm.getSelection()
8990
+ this.textarea.value = content
8991
+ if (cm.state.focused) { selectInput(this.textarea) }
8992
+ if (ie && ie_version >= 9) { this.hasSelection = content }
8993
+ } else if (!typing) {
8994
+ this.prevInput = this.textarea.value = ""
8995
+ if (ie && ie_version >= 9) { this.hasSelection = null }
8996
+ }
8997
+ this.inaccurateSelection = minimal
8998
+ };
8999
+
9000
+ TextareaInput.prototype.getField = function () { return this.textarea };
9001
+
9002
+ TextareaInput.prototype.supportsTouch = function () { return false };
9003
+
9004
+ TextareaInput.prototype.focus = function () {
9005
+ if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) {
9006
+ try { this.textarea.focus() }
9007
+ catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM
9008
+ }
9009
+ };
9010
+
9011
+ TextareaInput.prototype.blur = function () { this.textarea.blur() };
9012
+
9013
+ TextareaInput.prototype.resetPosition = function () {
9014
+ this.wrapper.style.top = this.wrapper.style.left = 0
9015
+ };
9016
+
9017
+ TextareaInput.prototype.receivedFocus = function () { this.slowPoll() };
9018
+
9019
+ // Poll for input changes, using the normal rate of polling. This
9020
+ // runs as long as the editor is focused.
9021
+ TextareaInput.prototype.slowPoll = function () {
9022
+ var this$1 = this;
9023
+
9024
+ if (this.pollingFast) { return }
9025
+ this.polling.set(this.cm.options.pollInterval, function () {
9026
+ this$1.poll()
9027
+ if (this$1.cm.state.focused) { this$1.slowPoll() }
9028
+ })
9029
+ };
9030
+
9031
+ // When an event has just come in that is likely to add or change
9032
+ // something in the input textarea, we poll faster, to ensure that
9033
+ // the change appears on the screen quickly.
9034
+ TextareaInput.prototype.fastPoll = function () {
9035
+ var missed = false, input = this
9036
+ input.pollingFast = true
9037
+ function p() {
9038
+ var changed = input.poll()
9039
+ if (!changed && !missed) {missed = true; input.polling.set(60, p)}
9040
+ else {input.pollingFast = false; input.slowPoll()}
9041
+ }
9042
+ input.polling.set(20, p)
9043
+ };
9044
+
9045
+ // Read input from the textarea, and update the document to match.
9046
+ // When something is selected, it is present in the textarea, and
9047
+ // selected (unless it is huge, in which case a placeholder is
9048
+ // used). When nothing is selected, the cursor sits after previously
9049
+ // seen text (can be empty), which is stored in prevInput (we must
9050
+ // not reset the textarea when typing, because that breaks IME).
9051
+ TextareaInput.prototype.poll = function () {
9052
+ var this$1 = this;
9053
+
9054
+ var cm = this.cm, input = this.textarea, prevInput = this.prevInput
9055
+ // Since this is called a *lot*, try to bail out as cheaply as
9056
+ // possible when it is clear that nothing happened. hasSelection
9057
+ // will be the case when there is a lot of text in the textarea,
9058
+ // in which case reading its value would be expensive.
9059
+ if (this.contextMenuPending || !cm.state.focused ||
9060
+ (hasSelection(input) && !prevInput && !this.composing) ||
9061
+ cm.isReadOnly() || cm.options.disableInput || cm.state.keySeq)
9062
+ { return false }
9063
+
9064
+ var text = input.value
9065
+ // If nothing changed, bail.
9066
+ if (text == prevInput && !cm.somethingSelected()) { return false }
9067
+ // Work around nonsensical selection resetting in IE9/10, and
9068
+ // inexplicable appearance of private area unicode characters on
9069
+ // some key combos in Mac (#2689).
9070
+ if (ie && ie_version >= 9 && this.hasSelection === text ||
9071
+ mac && /[\uf700-\uf7ff]/.test(text)) {
9072
+ cm.display.input.reset()
9073
+ return false
9074
+ }
9075
+
9076
+ if (cm.doc.sel == cm.display.selForContextMenu) {
9077
+ var first = text.charCodeAt(0)
9078
+ if (first == 0x200b && !prevInput) { prevInput = "\u200b" }
9079
+ if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo") }
9080
+ }
9081
+ // Find the part of the input that is actually new
9082
+ var same = 0, l = Math.min(prevInput.length, text.length)
9083
+ while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) { ++same }
9084
+
9085
+ runInOp(cm, function () {
9086
+ applyTextInput(cm, text.slice(same), prevInput.length - same,
9087
+ null, this$1.composing ? "*compose" : null)
9088
+
9089
+ // Don't leave long text in the textarea, since it makes further polling slow
9090
+ if (text.length > 1000 || text.indexOf("\n") > -1) { input.value = this$1.prevInput = "" }
9091
+ else { this$1.prevInput = text }
9092
+
9093
+ if (this$1.composing) {
9094
+ this$1.composing.range.clear()
9095
+ this$1.composing.range = cm.markText(this$1.composing.start, cm.getCursor("to"),
9096
+ {className: "CodeMirror-composing"})
9097
+ }
9098
+ })
9099
+ return true
9100
+ };
9101
+
9102
+ TextareaInput.prototype.ensurePolled = function () {
9103
+ if (this.pollingFast && this.poll()) { this.pollingFast = false }
9104
+ };
9105
+
9106
+ TextareaInput.prototype.onKeyPress = function () {
9107
+ if (ie && ie_version >= 9) { this.hasSelection = null }
9108
+ this.fastPoll()
9109
+ };
9110
+
9111
+ TextareaInput.prototype.onContextMenu = function (e) {
9112
+ var input = this, cm = input.cm, display = cm.display, te = input.textarea
9113
+ var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop
9114
+ if (!pos || presto) { return } // Opera is difficult.
9115
+
9116
+ // Reset the current text selection only if the click is done outside of the selection
9117
+ // and 'resetSelectionOnContextMenu' option is true.
9118
+ var reset = cm.options.resetSelectionOnContextMenu
9119
+ if (reset && cm.doc.sel.contains(pos) == -1)
9120
+ { operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll) }
9121
+
9122
+ var oldCSS = te.style.cssText, oldWrapperCSS = input.wrapper.style.cssText
9123
+ input.wrapper.style.cssText = "position: absolute"
9124
+ var wrapperBox = input.wrapper.getBoundingClientRect()
9125
+ te.style.cssText = "position: absolute; width: 30px; height: 30px;\n top: " + (e.clientY - wrapperBox.top - 5) + "px; left: " + (e.clientX - wrapperBox.left - 5) + "px;\n z-index: 1000; background: " + (ie ? "rgba(255, 255, 255, .05)" : "transparent") + ";\n outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);"
9126
+ var oldScrollY
9127
+ if (webkit) { oldScrollY = window.scrollY } // Work around Chrome issue (#2712)
9128
+ display.input.focus()
9129
+ if (webkit) { window.scrollTo(null, oldScrollY) }
9130
+ display.input.reset()
9131
+ // Adds "Select all" to context menu in FF
9132
+ if (!cm.somethingSelected()) { te.value = input.prevInput = " " }
9133
+ input.contextMenuPending = true
9134
+ display.selForContextMenu = cm.doc.sel
9135
+ clearTimeout(display.detectingSelectAll)
9136
+
9137
+ // Select-all will be greyed out if there's nothing to select, so
9138
+ // this adds a zero-width space so that we can later check whether
9139
+ // it got selected.
9140
+ function prepareSelectAllHack() {
9141
+ if (te.selectionStart != null) {
9142
+ var selected = cm.somethingSelected()
9143
+ var extval = "\u200b" + (selected ? te.value : "")
9144
+ te.value = "\u21da" // Used to catch context-menu undo
9145
+ te.value = extval
9146
+ input.prevInput = selected ? "" : "\u200b"
9147
+ te.selectionStart = 1; te.selectionEnd = extval.length
9148
+ // Re-set this, in case some other handler touched the
9149
+ // selection in the meantime.
9150
+ display.selForContextMenu = cm.doc.sel
9151
+ }
9152
+ }
9153
+ function rehide() {
9154
+ input.contextMenuPending = false
9155
+ input.wrapper.style.cssText = oldWrapperCSS
9156
+ te.style.cssText = oldCSS
9157
+ if (ie && ie_version < 9) { display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos) }
9158
+
9159
+ // Try to detect the user choosing select-all
9160
+ if (te.selectionStart != null) {
9161
+ if (!ie || (ie && ie_version < 9)) { prepareSelectAllHack() }
9162
+ var i = 0, poll = function () {
9163
+ if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 &&
9164
+ te.selectionEnd > 0 && input.prevInput == "\u200b") {
9165
+ operation(cm, selectAll)(cm)
9166
+ } else if (i++ < 10) {
9167
+ display.detectingSelectAll = setTimeout(poll, 500)
9168
+ } else {
9169
+ display.selForContextMenu = null
9170
+ display.input.reset()
9171
+ }
9172
+ }
9173
+ display.detectingSelectAll = setTimeout(poll, 200)
9174
+ }
9175
+ }
9176
+
9177
+ if (ie && ie_version >= 9) { prepareSelectAllHack() }
9178
+ if (captureRightClick) {
9179
+ e_stop(e)
9180
+ var mouseup = function () {
9181
+ off(window, "mouseup", mouseup)
9182
+ setTimeout(rehide, 20)
9183
+ }
9184
+ on(window, "mouseup", mouseup)
9185
+ } else {
9186
+ setTimeout(rehide, 50)
9187
+ }
9188
+ };
9189
+
9190
+ TextareaInput.prototype.readOnlyChanged = function (val) {
9191
+ if (!val) { this.reset() }
9192
+ };
9193
+
9194
+ TextareaInput.prototype.setUneditable = function () {};
9195
+
9196
+ TextareaInput.prototype.needsContentAttribute = false
9197
+
9198
+ function fromTextArea(textarea, options) {
9199
+ options = options ? copyObj(options) : {}
9200
+ options.value = textarea.value
9201
+ if (!options.tabindex && textarea.tabIndex)
9202
+ { options.tabindex = textarea.tabIndex }
9203
+ if (!options.placeholder && textarea.placeholder)
9204
+ { options.placeholder = textarea.placeholder }
9205
+ // Set autofocus to true if this textarea is focused, or if it has
9206
+ // autofocus and no other element is focused.
9207
+ if (options.autofocus == null) {
9208
+ var hasFocus = activeElt()
9209
+ options.autofocus = hasFocus == textarea ||
9210
+ textarea.getAttribute("autofocus") != null && hasFocus == document.body
9211
+ }
9212
+
9213
+ function save() {textarea.value = cm.getValue()}
9214
+
9215
+ var realSubmit
9216
+ if (textarea.form) {
9217
+ on(textarea.form, "submit", save)
9218
+ // Deplorable hack to make the submit method do the right thing.
9219
+ if (!options.leaveSubmitMethodAlone) {
9220
+ var form = textarea.form
9221
+ realSubmit = form.submit
9222
+ try {
9223
+ var wrappedSubmit = form.submit = function () {
9224
+ save()
9225
+ form.submit = realSubmit
9226
+ form.submit()
9227
+ form.submit = wrappedSubmit
9228
+ }
9229
+ } catch(e) {}
9230
+ }
9231
+ }
9232
+
9233
+ options.finishInit = function (cm) {
9234
+ cm.save = save
9235
+ cm.getTextArea = function () { return textarea; }
9236
+ cm.toTextArea = function () {
9237
+ cm.toTextArea = isNaN // Prevent this from being ran twice
9238
+ save()
9239
+ textarea.parentNode.removeChild(cm.getWrapperElement())
9240
+ textarea.style.display = ""
9241
+ if (textarea.form) {
9242
+ off(textarea.form, "submit", save)
9243
+ if (typeof textarea.form.submit == "function")
9244
+ { textarea.form.submit = realSubmit }
9245
+ }
9246
+ }
9247
+ }
9248
+
9249
+ textarea.style.display = "none"
9250
+ var cm = CodeMirror(function (node) { return textarea.parentNode.insertBefore(node, textarea.nextSibling); },
9251
+ options)
9252
+ return cm
9253
+ }
9254
+
9255
+ function addLegacyProps(CodeMirror) {
9256
+ CodeMirror.off = off
9257
+ CodeMirror.on = on
9258
+ CodeMirror.wheelEventPixels = wheelEventPixels
9259
+ CodeMirror.Doc = Doc
9260
+ CodeMirror.splitLines = splitLinesAuto
9261
+ CodeMirror.countColumn = countColumn
9262
+ CodeMirror.findColumn = findColumn
9263
+ CodeMirror.isWordChar = isWordCharBasic
9264
+ CodeMirror.Pass = Pass
9265
+ CodeMirror.signal = signal
9266
+ CodeMirror.Line = Line
9267
+ CodeMirror.changeEnd = changeEnd
9268
+ CodeMirror.scrollbarModel = scrollbarModel
9269
+ CodeMirror.Pos = Pos
9270
+ CodeMirror.cmpPos = cmp
9271
+ CodeMirror.modes = modes
9272
+ CodeMirror.mimeModes = mimeModes
9273
+ CodeMirror.resolveMode = resolveMode
9274
+ CodeMirror.getMode = getMode
9275
+ CodeMirror.modeExtensions = modeExtensions
9276
+ CodeMirror.extendMode = extendMode
9277
+ CodeMirror.copyState = copyState
9278
+ CodeMirror.startState = startState
9279
+ CodeMirror.innerMode = innerMode
9280
+ CodeMirror.commands = commands
9281
+ CodeMirror.keyMap = keyMap
9282
+ CodeMirror.keyName = keyName
9283
+ CodeMirror.isModifierKey = isModifierKey
9284
+ CodeMirror.lookupKey = lookupKey
9285
+ CodeMirror.normalizeKeyMap = normalizeKeyMap
9286
+ CodeMirror.StringStream = StringStream
9287
+ CodeMirror.SharedTextMarker = SharedTextMarker
9288
+ CodeMirror.TextMarker = TextMarker
9289
+ CodeMirror.LineWidget = LineWidget
9290
+ CodeMirror.e_preventDefault = e_preventDefault
9291
+ CodeMirror.e_stopPropagation = e_stopPropagation
9292
+ CodeMirror.e_stop = e_stop
9293
+ CodeMirror.addClass = addClass
9294
+ CodeMirror.contains = contains
9295
+ CodeMirror.rmClass = rmClass
9296
+ CodeMirror.keyNames = keyNames
9297
+ }
9298
+
9299
+ // EDITOR CONSTRUCTOR
9300
+
9301
+ defineOptions(CodeMirror)
9302
+
9303
+ addEditorMethods(CodeMirror)
9304
+
9305
+ // Set up methods on CodeMirror's prototype to redirect to the editor's document.
9306
+ var dontDelegate = "iter insert remove copy getEditor constructor".split(" ")
9307
+ for (var prop in Doc.prototype) { if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)
9308
+ { CodeMirror.prototype[prop] = (function(method) {
9309
+ return function() {return method.apply(this.doc, arguments)}
9310
+ })(Doc.prototype[prop]) } }
9311
+
9312
+ eventMixin(Doc)
9313
+
9314
+ // INPUT HANDLING
9315
+
9316
+ CodeMirror.inputStyles = {"textarea": TextareaInput, "contenteditable": ContentEditableInput}
9317
+
9318
+ // MODE DEFINITION AND QUERYING
9319
+
9320
+ // Extra arguments are stored as the mode's dependencies, which is
9321
+ // used by (legacy) mechanisms like loadmode.js to automatically
9322
+ // load a mode. (Preferred mechanism is the require/define calls.)
9323
+ CodeMirror.defineMode = function(name/*, mode, …*/) {
9324
+ if (!CodeMirror.defaults.mode && name != "null") { CodeMirror.defaults.mode = name }
9325
+ defineMode.apply(this, arguments)
9326
+ }
9327
+
9328
+ CodeMirror.defineMIME = defineMIME
9329
+
9330
+ // Minimal default mode.
9331
+ CodeMirror.defineMode("null", function () { return ({token: function (stream) { return stream.skipToEnd(); }}); })
9332
+ CodeMirror.defineMIME("text/plain", "null")
9333
+
9334
+ // EXTENSIONS
9335
+
9336
+ CodeMirror.defineExtension = function (name, func) {
9337
+ CodeMirror.prototype[name] = func
9338
+ }
9339
+ CodeMirror.defineDocExtension = function (name, func) {
9340
+ Doc.prototype[name] = func
9341
+ }
9342
+
9343
+ CodeMirror.fromTextArea = fromTextArea
9344
+
9345
+ addLegacyProps(CodeMirror)
9346
+
9347
+ CodeMirror.version = "5.26.0"
9348
+
9349
+ return CodeMirror;
9350
+
9351
+ })));
include/codemirror/css.js ADDED
@@ -0,0 +1,830 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ CodeMirror.defineMode("css", function(config, parserConfig) {
15
+ var inline = parserConfig.inline
16
+ if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
17
+
18
+ var indentUnit = config.indentUnit,
19
+ tokenHooks = parserConfig.tokenHooks,
20
+ documentTypes = parserConfig.documentTypes || {},
21
+ mediaTypes = parserConfig.mediaTypes || {},
22
+ mediaFeatures = parserConfig.mediaFeatures || {},
23
+ mediaValueKeywords = parserConfig.mediaValueKeywords || {},
24
+ propertyKeywords = parserConfig.propertyKeywords || {},
25
+ nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
26
+ fontProperties = parserConfig.fontProperties || {},
27
+ counterDescriptors = parserConfig.counterDescriptors || {},
28
+ colorKeywords = parserConfig.colorKeywords || {},
29
+ valueKeywords = parserConfig.valueKeywords || {},
30
+ allowNested = parserConfig.allowNested,
31
+ lineComment = parserConfig.lineComment,
32
+ supportsAtComponent = parserConfig.supportsAtComponent === true;
33
+
34
+ var type, override;
35
+ function ret(style, tp) { type = tp; return style; }
36
+
37
+ // Tokenizers
38
+
39
+ function tokenBase(stream, state) {
40
+ var ch = stream.next();
41
+ if (tokenHooks[ch]) {
42
+ var result = tokenHooks[ch](stream, state);
43
+ if (result !== false) return result;
44
+ }
45
+ if (ch == "@") {
46
+ stream.eatWhile(/[\w\\\-]/);
47
+ return ret("def", stream.current());
48
+ } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
49
+ return ret(null, "compare");
50
+ } else if (ch == "\"" || ch == "'") {
51
+ state.tokenize = tokenString(ch);
52
+ return state.tokenize(stream, state);
53
+ } else if (ch == "#") {
54
+ stream.eatWhile(/[\w\\\-]/);
55
+ return ret("atom", "hash");
56
+ } else if (ch == "!") {
57
+ stream.match(/^\s*\w*/);
58
+ return ret("keyword", "important");
59
+ } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
60
+ stream.eatWhile(/[\w.%]/);
61
+ return ret("number", "unit");
62
+ } else if (ch === "-") {
63
+ if (/[\d.]/.test(stream.peek())) {
64
+ stream.eatWhile(/[\w.%]/);
65
+ return ret("number", "unit");
66
+ } else if (stream.match(/^-[\w\\\-]+/)) {
67
+ stream.eatWhile(/[\w\\\-]/);
68
+ if (stream.match(/^\s*:/, false))
69
+ return ret("variable-2", "variable-definition");
70
+ return ret("variable-2", "variable");
71
+ } else if (stream.match(/^\w+-/)) {
72
+ return ret("meta", "meta");
73
+ }
74
+ } else if (/[,+>*\/]/.test(ch)) {
75
+ return ret(null, "select-op");
76
+ } else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
77
+ return ret("qualifier", "qualifier");
78
+ } else if (/[:;{}\[\]\(\)]/.test(ch)) {
79
+ return ret(null, ch);
80
+ } else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) ||
81
+ (ch == "d" && stream.match("omain(")) ||
82
+ (ch == "r" && stream.match("egexp("))) {
83
+ stream.backUp(1);
84
+ state.tokenize = tokenParenthesized;
85
+ return ret("property", "word");
86
+ } else if (/[\w\\\-]/.test(ch)) {
87
+ stream.eatWhile(/[\w\\\-]/);
88
+ return ret("property", "word");
89
+ } else {
90
+ return ret(null, null);
91
+ }
92
+ }
93
+
94
+ function tokenString(quote) {
95
+ return function(stream, state) {
96
+ var escaped = false, ch;
97
+ while ((ch = stream.next()) != null) {
98
+ if (ch == quote && !escaped) {
99
+ if (quote == ")") stream.backUp(1);
100
+ break;
101
+ }
102
+ escaped = !escaped && ch == "\\";
103
+ }
104
+ if (ch == quote || !escaped && quote != ")") state.tokenize = null;
105
+ return ret("string", "string");
106
+ };
107
+ }
108
+
109
+ function tokenParenthesized(stream, state) {
110
+ stream.next(); // Must be '('
111
+ if (!stream.match(/\s*[\"\')]/, false))
112
+ state.tokenize = tokenString(")");
113
+ else
114
+ state.tokenize = null;
115
+ return ret(null, "(");
116
+ }
117
+
118
+ // Context management
119
+
120
+ function Context(type, indent, prev) {
121
+ this.type = type;
122
+ this.indent = indent;
123
+ this.prev = prev;
124
+ }
125
+
126
+ function pushContext(state, stream, type, indent) {
127
+ state.context = new Context(type, stream.indentation() + (indent === false ? 0 : indentUnit), state.context);
128
+ return type;
129
+ }
130
+
131
+ function popContext(state) {
132
+ if (state.context.prev)
133
+ state.context = state.context.prev;
134
+ return state.context.type;
135
+ }
136
+
137
+ function pass(type, stream, state) {
138
+ return states[state.context.type](type, stream, state);
139
+ }
140
+ function popAndPass(type, stream, state, n) {
141
+ for (var i = n || 1; i > 0; i--)
142
+ state.context = state.context.prev;
143
+ return pass(type, stream, state);
144
+ }
145
+
146
+ // Parser
147
+
148
+ function wordAsValue(stream) {
149
+ var word = stream.current().toLowerCase();
150
+ if (valueKeywords.hasOwnProperty(word))
151
+ override = "atom";
152
+ else if (colorKeywords.hasOwnProperty(word))
153
+ override = "keyword";
154
+ else
155
+ override = "variable";
156
+ }
157
+
158
+ var states = {};
159
+
160
+ states.top = function(type, stream, state) {
161
+ if (type == "{") {
162
+ return pushContext(state, stream, "block");
163
+ } else if (type == "}" && state.context.prev) {
164
+ return popContext(state);
165
+ } else if (supportsAtComponent && /@component/.test(type)) {
166
+ return pushContext(state, stream, "atComponentBlock");
167
+ } else if (/^@(-moz-)?document$/.test(type)) {
168
+ return pushContext(state, stream, "documentTypes");
169
+ } else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) {
170
+ return pushContext(state, stream, "atBlock");
171
+ } else if (/^@(font-face|counter-style)/.test(type)) {
172
+ state.stateArg = type;
173
+ return "restricted_atBlock_before";
174
+ } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
175
+ return "keyframes";
176
+ } else if (type && type.charAt(0) == "@") {
177
+ return pushContext(state, stream, "at");
178
+ } else if (type == "hash") {
179
+ override = "builtin";
180
+ } else if (type == "word") {
181
+ override = "tag";
182
+ } else if (type == "variable-definition") {
183
+ return "maybeprop";
184
+ } else if (type == "interpolation") {
185
+ return pushContext(state, stream, "interpolation");
186
+ } else if (type == ":") {
187
+ return "pseudo";
188
+ } else if (allowNested && type == "(") {
189
+ return pushContext(state, stream, "parens");
190
+ }
191
+ return state.context.type;
192
+ };
193
+
194
+ states.block = function(type, stream, state) {
195
+ if (type == "word") {
196
+ var word = stream.current().toLowerCase();
197
+ if (propertyKeywords.hasOwnProperty(word)) {
198
+ override = "property";
199
+ return "maybeprop";
200
+ } else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
201
+ override = "string-2";
202
+ return "maybeprop";
203
+ } else if (allowNested) {
204
+ override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag";
205
+ return "block";
206
+ } else {
207
+ override += " error";
208
+ return "maybeprop";
209
+ }
210
+ } else if (type == "meta") {
211
+ return "block";
212
+ } else if (!allowNested && (type == "hash" || type == "qualifier")) {
213
+ override = "error";
214
+ return "block";
215
+ } else {
216
+ return states.top(type, stream, state);
217
+ }
218
+ };
219
+
220
+ states.maybeprop = function(type, stream, state) {
221
+ if (type == ":") return pushContext(state, stream, "prop");
222
+ return pass(type, stream, state);
223
+ };
224
+
225
+ states.prop = function(type, stream, state) {
226
+ if (type == ";") return popContext(state);
227
+ if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
228
+ if (type == "}" || type == "{") return popAndPass(type, stream, state);
229
+ if (type == "(") return pushContext(state, stream, "parens");
230
+
231
+ if (type == "hash" && !/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())) {
232
+ override += " error";
233
+ } else if (type == "word") {
234
+ wordAsValue(stream);
235
+ } else if (type == "interpolation") {
236
+ return pushContext(state, stream, "interpolation");
237
+ }
238
+ return "prop";
239
+ };
240
+
241
+ states.propBlock = function(type, _stream, state) {
242
+ if (type == "}") return popContext(state);
243
+ if (type == "word") { override = "property"; return "maybeprop"; }
244
+ return state.context.type;
245
+ };
246
+
247
+ states.parens = function(type, stream, state) {
248
+ if (type == "{" || type == "}") return popAndPass(type, stream, state);
249
+ if (type == ")") return popContext(state);
250
+ if (type == "(") return pushContext(state, stream, "parens");
251
+ if (type == "interpolation") return pushContext(state, stream, "interpolation");
252
+ if (type == "word") wordAsValue(stream);
253
+ return "parens";
254
+ };
255
+
256
+ states.pseudo = function(type, stream, state) {
257
+ if (type == "meta") return "pseudo";
258
+
259
+ if (type == "word") {
260
+ override = "variable-3";
261
+ return state.context.type;
262
+ }
263
+ return pass(type, stream, state);
264
+ };
265
+
266
+ states.documentTypes = function(type, stream, state) {
267
+ if (type == "word" && documentTypes.hasOwnProperty(stream.current())) {
268
+ override = "tag";
269
+ return state.context.type;
270
+ } else {
271
+ return states.atBlock(type, stream, state);
272
+ }
273
+ };
274
+
275
+ states.atBlock = function(type, stream, state) {
276
+ if (type == "(") return pushContext(state, stream, "atBlock_parens");
277
+ if (type == "}" || type == ";") return popAndPass(type, stream, state);
278
+ if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
279
+
280
+ if (type == "interpolation") return pushContext(state, stream, "interpolation");
281
+
282
+ if (type == "word") {
283
+ var word = stream.current().toLowerCase();
284
+ if (word == "only" || word == "not" || word == "and" || word == "or")
285
+ override = "keyword";
286
+ else if (mediaTypes.hasOwnProperty(word))
287
+ override = "attribute";
288
+ else if (mediaFeatures.hasOwnProperty(word))
289
+ override = "property";
290
+ else if (mediaValueKeywords.hasOwnProperty(word))
291
+ override = "keyword";
292
+ else if (propertyKeywords.hasOwnProperty(word))
293
+ override = "property";
294
+ else if (nonStandardPropertyKeywords.hasOwnProperty(word))
295
+ override = "string-2";
296
+ else if (valueKeywords.hasOwnProperty(word))
297
+ override = "atom";
298
+ else if (colorKeywords.hasOwnProperty(word))
299
+ override = "keyword";
300
+ else
301
+ override = "error";
302
+ }
303
+ return state.context.type;
304
+ };
305
+
306
+ states.atComponentBlock = function(type, stream, state) {
307
+ if (type == "}")
308
+ return popAndPass(type, stream, state);
309
+ if (type == "{")
310
+ return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top", false);
311
+ if (type == "word")
312
+ override = "error";
313
+ return state.context.type;
314
+ };
315
+
316
+ states.atBlock_parens = function(type, stream, state) {
317
+ if (type == ")") return popContext(state);
318
+ if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
319
+ return states.atBlock(type, stream, state);
320
+ };
321
+
322
+ states.restricted_atBlock_before = function(type, stream, state) {
323
+ if (type == "{")
324
+ return pushContext(state, stream, "restricted_atBlock");
325
+ if (type == "word" && state.stateArg == "@counter-style") {
326
+ override = "variable";
327
+ return "restricted_atBlock_before";
328
+ }
329
+ return pass(type, stream, state);
330
+ };
331
+
332
+ states.restricted_atBlock = function(type, stream, state) {
333
+ if (type == "}") {
334
+ state.stateArg = null;
335
+ return popContext(state);
336
+ }
337
+ if (type == "word") {
338
+ if ((state.stateArg == "@font-face" && !fontProperties.hasOwnProperty(stream.current().toLowerCase())) ||
339
+ (state.stateArg == "@counter-style" && !counterDescriptors.hasOwnProperty(stream.current().toLowerCase())))
340
+ override = "error";
341
+ else
342
+ override = "property";
343
+ return "maybeprop";
344
+ }
345
+ return "restricted_atBlock";
346
+ };
347
+
348
+ states.keyframes = function(type, stream, state) {
349
+ if (type == "word") { override = "variable"; return "keyframes"; }
350
+ if (type == "{") return pushContext(state, stream, "top");
351
+ return pass(type, stream, state);
352
+ };
353
+
354
+ states.at = function(type, stream, state) {
355
+ if (type == ";") return popContext(state);
356
+ if (type == "{" || type == "}") return popAndPass(type, stream, state);
357
+ if (type == "word") override = "tag";
358
+ else if (type == "hash") override = "builtin";
359
+ return "at";
360
+ };
361
+
362
+ states.interpolation = function(type, stream, state) {
363
+ if (type == "}") return popContext(state);
364
+ if (type == "{" || type == ";") return popAndPass(type, stream, state);
365
+ if (type == "word") override = "variable";
366
+ else if (type != "variable" && type != "(" && type != ")") override = "error";
367
+ return "interpolation";
368
+ };
369
+
370
+ return {
371
+ startState: function(base) {
372
+ return {tokenize: null,
373
+ state: inline ? "block" : "top",
374
+ stateArg: null,
375
+ context: new Context(inline ? "block" : "top", base || 0, null)};
376
+ },
377
+
378
+ token: function(stream, state) {
379
+ if (!state.tokenize && stream.eatSpace()) return null;
380
+ var style = (state.tokenize || tokenBase)(stream, state);
381
+ if (style && typeof style == "object") {
382
+ type = style[1];
383
+ style = style[0];
384
+ }
385
+ override = style;
386
+ state.state = states[state.state](type, stream, state);
387
+ return override;
388
+ },
389
+
390
+ indent: function(state, textAfter) {
391
+ var cx = state.context, ch = textAfter && textAfter.charAt(0);
392
+ var indent = cx.indent;
393
+ if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
394
+ if (cx.prev) {
395
+ if (ch == "}" && (cx.type == "block" || cx.type == "top" ||
396
+ cx.type == "interpolation" || cx.type == "restricted_atBlock")) {
397
+ // Resume indentation from parent context.
398
+ cx = cx.prev;
399
+ indent = cx.indent;
400
+ } else if (ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
401
+ ch == "{" && (cx.type == "at" || cx.type == "atBlock")) {
402
+ // Dedent relative to current context.
403
+ indent = Math.max(0, cx.indent - indentUnit);
404
+ }
405
+ }
406
+ return indent;
407
+ },
408
+
409
+ electricChars: "}",
410
+ blockCommentStart: "/*",
411
+ blockCommentEnd: "*/",
412
+ lineComment: lineComment,
413
+ fold: "brace"
414
+ };
415
+ });
416
+
417
+ function keySet(array) {
418
+ var keys = {};
419
+ for (var i = 0; i < array.length; ++i) {
420
+ keys[array[i].toLowerCase()] = true;
421
+ }
422
+ return keys;
423
+ }
424
+
425
+ var documentTypes_ = [
426
+ "domain", "regexp", "url", "url-prefix"
427
+ ], documentTypes = keySet(documentTypes_);
428
+
429
+ var mediaTypes_ = [
430
+ "all", "aural", "braille", "handheld", "print", "projection", "screen",
431
+ "tty", "tv", "embossed"
432
+ ], mediaTypes = keySet(mediaTypes_);
433
+
434
+ var mediaFeatures_ = [
435
+ "width", "min-width", "max-width", "height", "min-height", "max-height",
436
+ "device-width", "min-device-width", "max-device-width", "device-height",
437
+ "min-device-height", "max-device-height", "aspect-ratio",
438
+ "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
439
+ "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
440
+ "max-color", "color-index", "min-color-index", "max-color-index",
441
+ "monochrome", "min-monochrome", "max-monochrome", "resolution",
442
+ "min-resolution", "max-resolution", "scan", "grid", "orientation",
443
+ "device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio",
444
+ "pointer", "any-pointer", "hover", "any-hover"
445
+ ], mediaFeatures = keySet(mediaFeatures_);
446
+
447
+ var mediaValueKeywords_ = [
448
+ "landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover",
449
+ "interlace", "progressive"
450
+ ], mediaValueKeywords = keySet(mediaValueKeywords_);
451
+
452
+ var propertyKeywords_ = [
453
+ "align-content", "align-items", "align-self", "alignment-adjust",
454
+ "alignment-baseline", "anchor-point", "animation", "animation-delay",
455
+ "animation-direction", "animation-duration", "animation-fill-mode",
456
+ "animation-iteration-count", "animation-name", "animation-play-state",
457
+ "animation-timing-function", "appearance", "azimuth", "backface-visibility",
458
+ "background", "background-attachment", "background-blend-mode", "background-clip",
459
+ "background-color", "background-image", "background-origin", "background-position",
460
+ "background-repeat", "background-size", "baseline-shift", "binding",
461
+ "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
462
+ "bookmark-target", "border", "border-bottom", "border-bottom-color",
463
+ "border-bottom-left-radius", "border-bottom-right-radius",
464
+ "border-bottom-style", "border-bottom-width", "border-collapse",
465
+ "border-color", "border-image", "border-image-outset",
466
+ "border-image-repeat", "border-image-slice", "border-image-source",
467
+ "border-image-width", "border-left", "border-left-color",
468
+ "border-left-style", "border-left-width", "border-radius", "border-right",
469
+ "border-right-color", "border-right-style", "border-right-width",
470
+ "border-spacing", "border-style", "border-top", "border-top-color",
471
+ "border-top-left-radius", "border-top-right-radius", "border-top-style",
472
+ "border-top-width", "border-width", "bottom", "box-decoration-break",
473
+ "box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
474
+ "caption-side", "caret-color", "clear", "clip", "color", "color-profile", "column-count",
475
+ "column-fill", "column-gap", "column-rule", "column-rule-color",
476
+ "column-rule-style", "column-rule-width", "column-span", "column-width",
477
+ "columns", "content", "counter-increment", "counter-reset", "crop", "cue",
478
+ "cue-after", "cue-before", "cursor", "direction", "display",
479
+ "dominant-baseline", "drop-initial-after-adjust",
480
+ "drop-initial-after-align", "drop-initial-before-adjust",
481
+ "drop-initial-before-align", "drop-initial-size", "drop-initial-value",
482
+ "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
483
+ "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
484
+ "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
485
+ "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
486
+ "font-stretch", "font-style", "font-synthesis", "font-variant",
487
+ "font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
488
+ "font-variant-ligatures", "font-variant-numeric", "font-variant-position",
489
+ "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
490
+ "grid-auto-rows", "grid-column", "grid-column-end", "grid-column-gap",
491
+ "grid-column-start", "grid-gap", "grid-row", "grid-row-end", "grid-row-gap",
492
+ "grid-row-start", "grid-template", "grid-template-areas", "grid-template-columns",
493
+ "grid-template-rows", "hanging-punctuation", "height", "hyphens",
494
+ "icon", "image-orientation", "image-rendering", "image-resolution",
495
+ "inline-box-align", "justify-content", "justify-items", "justify-self", "left", "letter-spacing",
496
+ "line-break", "line-height", "line-stacking", "line-stacking-ruby",
497
+ "line-stacking-shift", "line-stacking-strategy", "list-style",
498
+ "list-style-image", "list-style-position", "list-style-type", "margin",
499
+ "margin-bottom", "margin-left", "margin-right", "margin-top",
500
+ "marks", "marquee-direction", "marquee-loop",
501
+ "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
502
+ "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
503
+ "nav-left", "nav-right", "nav-up", "object-fit", "object-position",
504
+ "opacity", "order", "orphans", "outline",
505
+ "outline-color", "outline-offset", "outline-style", "outline-width",
506
+ "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
507
+ "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
508
+ "page", "page-break-after", "page-break-before", "page-break-inside",
509
+ "page-policy", "pause", "pause-after", "pause-before", "perspective",
510
+ "perspective-origin", "pitch", "pitch-range", "place-content", "place-items", "place-self", "play-during", "position",
511
+ "presentation-level", "punctuation-trim", "quotes", "region-break-after",
512
+ "region-break-before", "region-break-inside", "region-fragment",
513
+ "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
514
+ "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
515
+ "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
516
+ "shape-outside", "size", "speak", "speak-as", "speak-header",
517
+ "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
518
+ "tab-size", "table-layout", "target", "target-name", "target-new",
519
+ "target-position", "text-align", "text-align-last", "text-decoration",
520
+ "text-decoration-color", "text-decoration-line", "text-decoration-skip",
521
+ "text-decoration-style", "text-emphasis", "text-emphasis-color",
522
+ "text-emphasis-position", "text-emphasis-style", "text-height",
523
+ "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
524
+ "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
525
+ "text-wrap", "top", "transform", "transform-origin", "transform-style",
526
+ "transition", "transition-delay", "transition-duration",
527
+ "transition-property", "transition-timing-function", "unicode-bidi",
528
+ "user-select", "vertical-align", "visibility", "voice-balance", "voice-duration",
529
+ "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
530
+ "voice-volume", "volume", "white-space", "widows", "width", "will-change", "word-break",
531
+ "word-spacing", "word-wrap", "z-index",
532
+ // SVG-specific
533
+ "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
534
+ "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
535
+ "color-interpolation", "color-interpolation-filters",
536
+ "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
537
+ "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
538
+ "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
539
+ "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
540
+ "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
541
+ "glyph-orientation-vertical", "text-anchor", "writing-mode"
542
+ ], propertyKeywords = keySet(propertyKeywords_);
543
+
544
+ var nonStandardPropertyKeywords_ = [
545
+ "scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
546
+ "scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
547
+ "scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
548
+ "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
549
+ "searchfield-results-decoration", "zoom"
550
+ ], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
551
+
552
+ var fontProperties_ = [
553
+ "font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
554
+ "font-stretch", "font-weight", "font-style"
555
+ ], fontProperties = keySet(fontProperties_);
556
+
557
+ var counterDescriptors_ = [
558
+ "additive-symbols", "fallback", "negative", "pad", "prefix", "range",
559
+ "speak-as", "suffix", "symbols", "system"
560
+ ], counterDescriptors = keySet(counterDescriptors_);
561
+
562
+ var colorKeywords_ = [
563
+ "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
564
+ "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
565
+ "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
566
+ "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
567
+ "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
568
+ "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
569
+ "darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
570
+ "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
571
+ "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
572
+ "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
573
+ "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
574
+ "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
575
+ "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
576
+ "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
577
+ "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
578
+ "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
579
+ "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
580
+ "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
581
+ "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
582
+ "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
583
+ "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
584
+ "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
585
+ "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
586
+ "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
587
+ "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
588
+ "whitesmoke", "yellow", "yellowgreen"
589
+ ], colorKeywords = keySet(colorKeywords_);
590
+
591
+ var valueKeywords_ = [
592
+ "above", "absolute", "activeborder", "additive", "activecaption", "afar",
593
+ "after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
594
+ "always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
595
+ "arabic-indic", "armenian", "asterisks", "attr", "auto", "auto-flow", "avoid", "avoid-column", "avoid-page",
596
+ "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
597
+ "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
598
+ "both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel",
599
+ "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
600
+ "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
601
+ "cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
602
+ "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
603
+ "col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse",
604
+ "compact", "condensed", "contain", "content", "contents",
605
+ "content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop",
606
+ "cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal",
607
+ "decimal-leading-zero", "default", "default-button", "dense", "destination-atop",
608
+ "destination-in", "destination-out", "destination-over", "devanagari", "difference",
609
+ "disc", "discard", "disclosure-closed", "disclosure-open", "document",
610
+ "dot-dash", "dot-dot-dash",
611
+ "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
612
+ "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
613
+ "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
614
+ "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
615
+ "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
616
+ "ethiopic-halehame-gez", "ethiopic-halehame-om-et",
617
+ "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
618
+ "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
619
+ "ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed",
620
+ "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
621
+ "forwards", "from", "geometricPrecision", "georgian", "graytext", "grid", "groove",
622
+ "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew",
623
+ "help", "hidden", "hide", "higher", "highlight", "highlighttext",
624
+ "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "icon", "ignore",
625
+ "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
626
+ "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
627
+ "inline-block", "inline-flex", "inline-grid", "inline-table", "inset", "inside", "intrinsic", "invert",
628
+ "italic", "japanese-formal", "japanese-informal", "justify", "kannada",
629
+ "katakana", "katakana-iroha", "keep-all", "khmer",
630
+ "korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal",
631
+ "landscape", "lao", "large", "larger", "left", "level", "lighter", "lighten",
632
+ "line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
633
+ "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
634
+ "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
635
+ "lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d",
636
+ "media-controls-background", "media-current-time-display",
637
+ "media-fullscreen-button", "media-mute-button", "media-play-button",
638
+ "media-return-to-realtime-button", "media-rewind-button",
639
+ "media-seek-back-button", "media-seek-forward-button", "media-slider",
640
+ "media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
641
+ "media-volume-slider-container", "media-volume-sliderthumb", "medium",
642
+ "menu", "menulist", "menulist-button", "menulist-text",
643
+ "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
644
+ "mix", "mongolian", "monospace", "move", "multiple", "multiply", "myanmar", "n-resize",
645
+ "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
646
+ "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
647
+ "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "opacity", "open-quote",
648
+ "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
649
+ "outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
650
+ "painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter",
651
+ "pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
652
+ "progress", "push-button", "radial-gradient", "radio", "read-only",
653
+ "read-write", "read-write-plaintext-only", "rectangle", "region",
654
+ "relative", "repeat", "repeating-linear-gradient",
655
+ "repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
656
+ "rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
657
+ "rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running",
658
+ "s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
659
+ "scroll", "scrollbar", "scroll-position", "se-resize", "searchfield",
660
+ "searchfield-cancel-button", "searchfield-decoration",
661
+ "searchfield-results-button", "searchfield-results-decoration", "self-start", "self-end",
662
+ "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
663
+ "simp-chinese-formal", "simp-chinese-informal", "single",
664
+ "skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
665
+ "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
666
+ "small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali",
667
+ "source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "space-evenly", "spell-out", "square",
668
+ "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
669
+ "subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "system-ui", "table",
670
+ "table-caption", "table-cell", "table-column", "table-column-group",
671
+ "table-footer-group", "table-header-group", "table-row", "table-row-group",
672
+ "tamil",
673
+ "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
674
+ "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
675
+ "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
676
+ "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
677
+ "trad-chinese-formal", "trad-chinese-informal", "transform",
678
+ "translate", "translate3d", "translateX", "translateY", "translateZ",
679
+ "transparent", "ultra-condensed", "ultra-expanded", "underline", "unset", "up",
680
+ "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
681
+ "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
682
+ "var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
683
+ "visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
684
+ "window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor",
685
+ "xx-large", "xx-small"
686
+ ], valueKeywords = keySet(valueKeywords_);
687
+
688
+ var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(mediaValueKeywords_)
689
+ .concat(propertyKeywords_).concat(nonStandardPropertyKeywords_).concat(colorKeywords_)
690
+ .concat(valueKeywords_);
691
+ CodeMirror.registerHelper("hintWords", "css", allWords);
692
+
693
+ function tokenCComment(stream, state) {
694
+ var maybeEnd = false, ch;
695
+ while ((ch = stream.next()) != null) {
696
+ if (maybeEnd && ch == "/") {
697
+ state.tokenize = null;
698
+ break;
699
+ }
700
+ maybeEnd = (ch == "*");
701
+ }
702
+ return ["comment", "comment"];
703
+ }
704
+
705
+ CodeMirror.defineMIME("text/css", {
706
+ documentTypes: documentTypes,
707
+ mediaTypes: mediaTypes,
708
+ mediaFeatures: mediaFeatures,
709
+ mediaValueKeywords: mediaValueKeywords,
710
+ propertyKeywords: propertyKeywords,
711
+ nonStandardPropertyKeywords: nonStandardPropertyKeywords,
712
+ fontProperties: fontProperties,
713
+ counterDescriptors: counterDescriptors,
714
+ colorKeywords: colorKeywords,
715
+ valueKeywords: valueKeywords,
716
+ tokenHooks: {
717
+ "/": function(stream, state) {
718
+ if (!stream.eat("*")) return false;
719
+ state.tokenize = tokenCComment;
720
+ return tokenCComment(stream, state);
721
+ }
722
+ },
723
+ name: "css"
724
+ });
725
+
726
+ CodeMirror.defineMIME("text/x-scss", {
727
+ mediaTypes: mediaTypes,
728
+ mediaFeatures: mediaFeatures,
729
+ mediaValueKeywords: mediaValueKeywords,
730
+ propertyKeywords: propertyKeywords,
731
+ nonStandardPropertyKeywords: nonStandardPropertyKeywords,
732
+ colorKeywords: colorKeywords,
733
+ valueKeywords: valueKeywords,
734
+ fontProperties: fontProperties,
735
+ allowNested: true,
736
+ lineComment: "//",
737
+ tokenHooks: {
738
+ "/": function(stream, state) {
739
+ if (stream.eat("/")) {
740
+ stream.skipToEnd();
741
+ return ["comment", "comment"];
742
+ } else if (stream.eat("*")) {
743
+ state.tokenize = tokenCComment;
744
+ return tokenCComment(stream, state);
745
+ } else {
746
+ return ["operator", "operator"];
747
+ }
748
+ },
749
+ ":": function(stream) {
750
+ if (stream.match(/\s*\{/, false))
751
+ return [null, null]
752
+ return false;
753
+ },
754
+ "$": function(stream) {
755
+ stream.match(/^[\w-]+/);
756
+ if (stream.match(/^\s*:/, false))
757
+ return ["variable-2", "variable-definition"];
758
+ return ["variable-2", "variable"];
759
+ },
760
+ "#": function(stream) {
761
+ if (!stream.eat("{")) return false;
762
+ return [null, "interpolation"];
763
+ }
764
+ },
765
+ name: "css",
766
+ helperType: "scss"
767
+ });
768
+
769
+ CodeMirror.defineMIME("text/x-less", {
770
+ mediaTypes: mediaTypes,
771
+ mediaFeatures: mediaFeatures,
772
+ mediaValueKeywords: mediaValueKeywords,
773
+ propertyKeywords: propertyKeywords,
774
+ nonStandardPropertyKeywords: nonStandardPropertyKeywords,
775
+ colorKeywords: colorKeywords,
776
+ valueKeywords: valueKeywords,
777
+ fontProperties: fontProperties,
778
+ allowNested: true,
779
+ lineComment: "//",
780
+ tokenHooks: {
781
+ "/": function(stream, state) {
782
+ if (stream.eat("/")) {
783
+ stream.skipToEnd();
784
+ return ["comment", "comment"];
785
+ } else if (stream.eat("*")) {
786
+ state.tokenize = tokenCComment;
787
+ return tokenCComment(stream, state);
788
+ } else {
789
+ return ["operator", "operator"];
790
+ }
791
+ },
792
+ "@": function(stream) {
793
+ if (stream.eat("{")) return [null, "interpolation"];
794
+ if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
795
+ stream.eatWhile(/[\w\\\-]/);
796
+ if (stream.match(/^\s*:/, false))
797
+ return ["variable-2", "variable-definition"];
798
+ return ["variable-2", "variable"];
799
+ },
800
+ "&": function() {
801
+ return ["atom", "atom"];
802
+ }
803
+ },
804
+ name: "css",
805
+ helperType: "less"
806
+ });
807
+
808
+ CodeMirror.defineMIME("text/x-gss", {
809
+ documentTypes: documentTypes,
810
+ mediaTypes: mediaTypes,
811
+ mediaFeatures: mediaFeatures,
812
+ propertyKeywords: propertyKeywords,
813
+ nonStandardPropertyKeywords: nonStandardPropertyKeywords,
814
+ fontProperties: fontProperties,
815
+ counterDescriptors: counterDescriptors,
816
+ colorKeywords: colorKeywords,
817
+ valueKeywords: valueKeywords,
818
+ supportsAtComponent: true,
819
+ tokenHooks: {
820
+ "/": function(stream, state) {
821
+ if (!stream.eat("*")) return false;
822
+ state.tokenize = tokenCComment;
823
+ return tokenCComment(stream, state);
824
+ }
825
+ },
826
+ name: "css",
827
+ helperType: "gss"
828
+ });
829
+
830
+ });
include/codemirror/dracula.css ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+
3
+ Name: dracula
4
+ Author: Michael Kaminsky (http://github.com/mkaminsky11)
5
+
6
+ Original dracula color scheme by Zeno Rocha (https://github.com/zenorocha/dracula-theme)
7
+
8
+ */
9
+
10
+
11
+ .cm-s-dracula.CodeMirror, .cm-s-dracula .CodeMirror-gutters {
12
+ background-color: #282a36 !important;
13
+ color: #f8f8f2 !important;
14
+ border: none;
15
+ }
16
+ .cm-s-dracula .CodeMirror-gutters { color: #282a36; }
17
+ .cm-s-dracula .CodeMirror-cursor { border-left: solid thin #f8f8f0; }
18
+ .cm-s-dracula .CodeMirror-linenumber { color: #6D8A88; }
19
+ .cm-s-dracula .CodeMirror-selected { background: rgba(255, 255, 255, 0.10); }
20
+ .cm-s-dracula .CodeMirror-line::selection, .cm-s-dracula .CodeMirror-line > span::selection, .cm-s-dracula .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); }
21
+ .cm-s-dracula .CodeMirror-line::-moz-selection, .cm-s-dracula .CodeMirror-line > span::-moz-selection, .cm-s-dracula .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); }
22
+ .cm-s-dracula span.cm-comment { color: #6272a4; }
23
+ .cm-s-dracula span.cm-string, .cm-s-dracula span.cm-string-2 { color: #f1fa8c; }
24
+ .cm-s-dracula span.cm-number { color: #bd93f9; }
25
+ .cm-s-dracula span.cm-variable { color: #50fa7b; }
26
+ .cm-s-dracula span.cm-variable-2 { color: white; }
27
+ .cm-s-dracula span.cm-def { color: #50fa7b; }
28
+ .cm-s-dracula span.cm-operator { color: #ff79c6; }
29
+ .cm-s-dracula span.cm-keyword { color: #ff79c6; }
30
+ .cm-s-dracula span.cm-atom { color: #bd93f9; }
31
+ .cm-s-dracula span.cm-meta { color: #f8f8f2; }
32
+ .cm-s-dracula span.cm-tag { color: #ff79c6; }
33
+ .cm-s-dracula span.cm-attribute { color: #50fa7b; }
34
+ .cm-s-dracula span.cm-qualifier { color: #50fa7b; }
35
+ .cm-s-dracula span.cm-property { color: #66d9ef; }
36
+ .cm-s-dracula span.cm-builtin { color: #50fa7b; }
37
+ .cm-s-dracula span.cm-variable-3, .cm-s-dracula span.cm-type { color: #ffb86c; }
38
+
39
+ .cm-s-dracula .CodeMirror-activeline-background { background: rgba(255,255,255,0.1); }
40
+ .cm-s-dracula .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
include/fonts/roboto/Roboto-Bold.woff ADDED
Binary file
include/fonts/roboto/Roboto-Bold.woff2 ADDED
Binary file
include/fonts/roboto/Roboto-Light.woff ADDED
Binary file
include/fonts/roboto/Roboto-Light.woff2 ADDED
Binary file
include/fonts/roboto/Roboto-Medium.woff ADDED
Binary file
include/fonts/roboto/Roboto-Medium.woff2 ADDED
Binary file
include/fonts/roboto/Roboto-Regular.woff ADDED
Binary file
include/fonts/roboto/Roboto-Regular.woff2 ADDED
Binary file
include/fonts/roboto/Roboto-Thin.woff ADDED
Binary file
include/fonts/roboto/Roboto-Thin.woff2 ADDED
Binary file
include/materialize/materialize.min.css ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Materialize v0.98.2 (http://materializecss.com)
3
+ * Copyright 2014-2015 Materialize
4
+ * MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE)
5
+ */
6
+ .materialize-red{background-color:#e51c23 !important}.materialize-red-text{color:#e51c23 !important}.materialize-red.lighten-5{background-color:#fdeaeb !important}.materialize-red-text.text-lighten-5{color:#fdeaeb !important}.materialize-red.lighten-4{background-color:#f8c1c3 !important}.materialize-red-text.text-lighten-4{color:#f8c1c3 !important}.materialize-red.lighten-3{background-color:#f3989b !important}.materialize-red-text.text-lighten-3{color:#f3989b !important}.materialize-red.lighten-2{background-color:#ee6e73 !important}.materialize-red-text.text-lighten-2{color:#ee6e73 !important}.materialize-red.lighten-1{background-color:#ea454b !important}.materialize-red-text.text-lighten-1{color:#ea454b !important}.materialize-red.darken-1{background-color:#d0181e !important}.materialize-red-text.text-darken-1{color:#d0181e !important}.materialize-red.darken-2{background-color:#b9151b !important}.materialize-red-text.text-darken-2{color:#b9151b !important}.materialize-red.darken-3{background-color:#a21318 !important}.materialize-red-text.text-darken-3{color:#a21318 !important}.materialize-red.darken-4{background-color:#8b1014 !important}.materialize-red-text.text-darken-4{color:#8b1014 !important}.red{background-color:#F44336 !important}.red-text{color:#F44336 !important}.red.lighten-5{background-color:#FFEBEE !important}.red-text.text-lighten-5{color:#FFEBEE !important}.red.lighten-4{background-color:#FFCDD2 !important}.red-text.text-lighten-4{color:#FFCDD2 !important}.red.lighten-3{background-color:#EF9A9A !important}.red-text.text-lighten-3{color:#EF9A9A !important}.red.lighten-2{background-color:#E57373 !important}.red-text.text-lighten-2{color:#E57373 !important}.red.lighten-1{background-color:#EF5350 !important}.red-text.text-lighten-1{color:#EF5350 !important}.red.darken-1{background-color:#E53935 !important}.red-text.text-darken-1{color:#E53935 !important}.red.darken-2{background-color:#D32F2F !important}.red-text.text-darken-2{color:#D32F2F !important}.red.darken-3{background-color:#C62828 !important}.red-text.text-darken-3{color:#C62828 !important}.red.darken-4{background-color:#B71C1C !important}.red-text.text-darken-4{color:#B71C1C !important}.red.accent-1{background-color:#FF8A80 !important}.red-text.text-accent-1{color:#FF8A80 !important}.red.accent-2{background-color:#FF5252 !important}.red-text.text-accent-2{color:#FF5252 !important}.red.accent-3{background-color:#FF1744 !important}.red-text.text-accent-3{color:#FF1744 !important}.red.accent-4{background-color:#D50000 !important}.red-text.text-accent-4{color:#D50000 !important}.pink{background-color:#e91e63 !important}.pink-text{color:#e91e63 !important}.pink.lighten-5{background-color:#fce4ec !important}.pink-text.text-lighten-5{color:#fce4ec !important}.pink.lighten-4{background-color:#f8bbd0 !important}.pink-text.text-lighten-4{color:#f8bbd0 !important}.pink.lighten-3{background-color:#f48fb1 !important}.pink-text.text-lighten-3{color:#f48fb1 !important}.pink.lighten-2{background-color:#f06292 !important}.pink-text.text-lighten-2{color:#f06292 !important}.pink.lighten-1{background-color:#ec407a !important}.pink-text.text-lighten-1{color:#ec407a !important}.pink.darken-1{background-color:#d81b60 !important}.pink-text.text-darken-1{color:#d81b60 !important}.pink.darken-2{background-color:#c2185b !important}.pink-text.text-darken-2{color:#c2185b !important}.pink.darken-3{background-color:#ad1457 !important}.pink-text.text-darken-3{color:#ad1457 !important}.pink.darken-4{background-color:#880e4f !important}.pink-text.text-darken-4{color:#880e4f !important}.pink.accent-1{background-color:#ff80ab !important}.pink-text.text-accent-1{color:#ff80ab !important}.pink.accent-2{background-color:#ff4081 !important}.pink-text.text-accent-2{color:#ff4081 !important}.pink.accent-3{background-color:#f50057 !important}.pink-text.text-accent-3{color:#f50057 !important}.pink.accent-4{background-color:#c51162 !important}.pink-text.text-accent-4{color:#c51162 !important}.purple{background-color:#9c27b0 !important}.purple-text{color:#9c27b0 !important}.purple.lighten-5{background-color:#f3e5f5 !important}.purple-text.text-lighten-5{color:#f3e5f5 !important}.purple.lighten-4{background-color:#e1bee7 !important}.purple-text.text-lighten-4{color:#e1bee7 !important}.purple.lighten-3{background-color:#ce93d8 !important}.purple-text.text-lighten-3{color:#ce93d8 !important}.purple.lighten-2{background-color:#ba68c8 !important}.purple-text.text-lighten-2{color:#ba68c8 !important}.purple.lighten-1{background-color:#ab47bc !important}.purple-text.text-lighten-1{color:#ab47bc !important}.purple.darken-1{background-color:#8e24aa !important}.purple-text.text-darken-1{color:#8e24aa !important}.purple.darken-2{background-color:#7b1fa2 !important}.purple-text.text-darken-2{color:#7b1fa2 !important}.purple.darken-3{background-color:#6a1b9a !important}.purple-text.text-darken-3{color:#6a1b9a !important}.purple.darken-4{background-color:#4a148c !important}.purple-text.text-darken-4{color:#4a148c !important}.purple.accent-1{background-color:#ea80fc !important}.purple-text.text-accent-1{color:#ea80fc !important}.purple.accent-2{background-color:#e040fb !important}.purple-text.text-accent-2{color:#e040fb !important}.purple.accent-3{background-color:#d500f9 !important}.purple-text.text-accent-3{color:#d500f9 !important}.purple.accent-4{background-color:#a0f !important}.purple-text.text-accent-4{color:#a0f !important}.deep-purple{background-color:#673ab7 !important}.deep-purple-text{color:#673ab7 !important}.deep-purple.lighten-5{background-color:#ede7f6 !important}.deep-purple-text.text-lighten-5{color:#ede7f6 !important}.deep-purple.lighten-4{background-color:#d1c4e9 !important}.deep-purple-text.text-lighten-4{color:#d1c4e9 !important}.deep-purple.lighten-3{background-color:#b39ddb !important}.deep-purple-text.text-lighten-3{color:#b39ddb !important}.deep-purple.lighten-2{background-color:#9575cd !important}.deep-purple-text.text-lighten-2{color:#9575cd !important}.deep-purple.lighten-1{background-color:#7e57c2 !important}.deep-purple-text.text-lighten-1{color:#7e57c2 !important}.deep-purple.darken-1{background-color:#5e35b1 !important}.deep-purple-text.text-darken-1{color:#5e35b1 !important}.deep-purple.darken-2{background-color:#512da8 !important}.deep-purple-text.text-darken-2{color:#512da8 !important}.deep-purple.darken-3{background-color:#4527a0 !important}.deep-purple-text.text-darken-3{color:#4527a0 !important}.deep-purple.darken-4{background-color:#311b92 !important}.deep-purple-text.text-darken-4{color:#311b92 !important}.deep-purple.accent-1{background-color:#b388ff !important}.deep-purple-text.text-accent-1{color:#b388ff !important}.deep-purple.accent-2{background-color:#7c4dff !important}.deep-purple-text.text-accent-2{color:#7c4dff !important}.deep-purple.accent-3{background-color:#651fff !important}.deep-purple-text.text-accent-3{color:#651fff !important}.deep-purple.accent-4{background-color:#6200ea !important}.deep-purple-text.text-accent-4{color:#6200ea !important}.indigo{background-color:#3f51b5 !important}.indigo-text{color:#3f51b5 !important}.indigo.lighten-5{background-color:#e8eaf6 !important}.indigo-text.text-lighten-5{color:#e8eaf6 !important}.indigo.lighten-4{background-color:#c5cae9 !important}.indigo-text.text-lighten-4{color:#c5cae9 !important}.indigo.lighten-3{background-color:#9fa8da !important}.indigo-text.text-lighten-3{color:#9fa8da !important}.indigo.lighten-2{background-color:#7986cb !important}.indigo-text.text-lighten-2{color:#7986cb !important}.indigo.lighten-1{background-color:#5c6bc0 !important}.indigo-text.text-lighten-1{color:#5c6bc0 !important}.indigo.darken-1{background-color:#3949ab !important}.indigo-text.text-darken-1{color:#3949ab !important}.indigo.darken-2{background-color:#303f9f !important}.indigo-text.text-darken-2{color:#303f9f !important}.indigo.darken-3{background-color:#283593 !important}.indigo-text.text-darken-3{color:#283593 !important}.indigo.darken-4{background-color:#1a237e !important}.indigo-text.text-darken-4{color:#1a237e !important}.indigo.accent-1{background-color:#8c9eff !important}.indigo-text.text-accent-1{color:#8c9eff !important}.indigo.accent-2{background-color:#536dfe !important}.indigo-text.text-accent-2{color:#536dfe !important}.indigo.accent-3{background-color:#3d5afe !important}.indigo-text.text-accent-3{color:#3d5afe !important}.indigo.accent-4{background-color:#304ffe !important}.indigo-text.text-accent-4{color:#304ffe !important}.blue{background-color:#2196F3 !important}.blue-text{color:#2196F3 !important}.blue.lighten-5{background-color:#E3F2FD !important}.blue-text.text-lighten-5{color:#E3F2FD !important}.blue.lighten-4{background-color:#BBDEFB !important}.blue-text.text-lighten-4{color:#BBDEFB !important}.blue.lighten-3{background-color:#90CAF9 !important}.blue-text.text-lighten-3{color:#90CAF9 !important}.blue.lighten-2{background-color:#64B5F6 !important}.blue-text.text-lighten-2{color:#64B5F6 !important}.blue.lighten-1{background-color:#42A5F5 !important}.blue-text.text-lighten-1{color:#42A5F5 !important}.blue.darken-1{background-color:#1E88E5 !important}.blue-text.text-darken-1{color:#1E88E5 !important}.blue.darken-2{background-color:#1976D2 !important}.blue-text.text-darken-2{color:#1976D2 !important}.blue.darken-3{background-color:#1565C0 !important}.blue-text.text-darken-3{color:#1565C0 !important}.blue.darken-4{background-color:#0D47A1 !important}.blue-text.text-darken-4{color:#0D47A1 !important}.blue.accent-1{background-color:#82B1FF !important}.blue-text.text-accent-1{color:#82B1FF !important}.blue.accent-2{background-color:#448AFF !important}.blue-text.text-accent-2{color:#448AFF !important}.blue.accent-3{background-color:#2979FF !important}.blue-text.text-accent-3{color:#2979FF !important}.blue.accent-4{background-color:#2962FF !important}.blue-text.text-accent-4{color:#2962FF !important}.light-blue{background-color:#03a9f4 !important}.light-blue-text{color:#03a9f4 !important}.light-blue.lighten-5{background-color:#e1f5fe !important}.light-blue-text.text-lighten-5{color:#e1f5fe !important}.light-blue.lighten-4{background-color:#b3e5fc !important}.light-blue-text.text-lighten-4{color:#b3e5fc !important}.light-blue.lighten-3{background-color:#81d4fa !important}.light-blue-text.text-lighten-3{color:#81d4fa !important}.light-blue.lighten-2{background-color:#4fc3f7 !important}.light-blue-text.text-lighten-2{color:#4fc3f7 !important}.light-blue.lighten-1{background-color:#29b6f6 !important}.light-blue-text.text-lighten-1{color:#29b6f6 !important}.light-blue.darken-1{background-color:#039be5 !important}.light-blue-text.text-darken-1{color:#039be5 !important}.light-blue.darken-2{background-color:#0288d1 !important}.light-blue-text.text-darken-2{color:#0288d1 !important}.light-blue.darken-3{background-color:#0277bd !important}.light-blue-text.text-darken-3{color:#0277bd !important}.light-blue.darken-4{background-color:#01579b !important}.light-blue-text.text-darken-4{color:#01579b !important}.light-blue.accent-1{background-color:#80d8ff !important}.light-blue-text.text-accent-1{color:#80d8ff !important}.light-blue.accent-2{background-color:#40c4ff !important}.light-blue-text.text-accent-2{color:#40c4ff !important}.light-blue.accent-3{background-color:#00b0ff !important}.light-blue-text.text-accent-3{color:#00b0ff !important}.light-blue.accent-4{background-color:#0091ea !important}.light-blue-text.text-accent-4{color:#0091ea !important}.cyan{background-color:#00bcd4 !important}.cyan-text{color:#00bcd4 !important}.cyan.lighten-5{background-color:#e0f7fa !important}.cyan-text.text-lighten-5{color:#e0f7fa !important}.cyan.lighten-4{background-color:#b2ebf2 !important}.cyan-text.text-lighten-4{color:#b2ebf2 !important}.cyan.lighten-3{background-color:#80deea !important}.cyan-text.text-lighten-3{color:#80deea !important}.cyan.lighten-2{background-color:#4dd0e1 !important}.cyan-text.text-lighten-2{color:#4dd0e1 !important}.cyan.lighten-1{background-color:#26c6da !important}.cyan-text.text-lighten-1{color:#26c6da !important}.cyan.darken-1{background-color:#00acc1 !important}.cyan-text.text-darken-1{color:#00acc1 !important}.cyan.darken-2{background-color:#0097a7 !important}.cyan-text.text-darken-2{color:#0097a7 !important}.cyan.darken-3{background-color:#00838f !important}.cyan-text.text-darken-3{color:#00838f !important}.cyan.darken-4{background-color:#006064 !important}.cyan-text.text-darken-4{color:#006064 !important}.cyan.accent-1{background-color:#84ffff !important}.cyan-text.text-accent-1{color:#84ffff !important}.cyan.accent-2{background-color:#18ffff !important}.cyan-text.text-accent-2{color:#18ffff !important}.cyan.accent-3{background-color:#00e5ff !important}.cyan-text.text-accent-3{color:#00e5ff !important}.cyan.accent-4{background-color:#00b8d4 !important}.cyan-text.text-accent-4{color:#00b8d4 !important}.teal{background-color:#009688 !important}.teal-text{color:#009688 !important}.teal.lighten-5{background-color:#e0f2f1 !important}.teal-text.text-lighten-5{color:#e0f2f1 !important}.teal.lighten-4{background-color:#b2dfdb !important}.teal-text.text-lighten-4{color:#b2dfdb !important}.teal.lighten-3{background-color:#80cbc4 !important}.teal-text.text-lighten-3{color:#80cbc4 !important}.teal.lighten-2{background-color:#4db6ac !important}.teal-text.text-lighten-2{color:#4db6ac !important}.teal.lighten-1{background-color:#26a69a !important}.teal-text.text-lighten-1{color:#26a69a !important}.teal.darken-1{background-color:#00897b !important}.teal-text.text-darken-1{color:#00897b !important}.teal.darken-2{background-color:#00796b !important}.teal-text.text-darken-2{color:#00796b !important}.teal.darken-3{background-color:#00695c !important}.teal-text.text-darken-3{color:#00695c !important}.teal.darken-4{background-color:#004d40 !important}.teal-text.text-darken-4{color:#004d40 !important}.teal.accent-1{background-color:#a7ffeb !important}.teal-text.text-accent-1{color:#a7ffeb !important}.teal.accent-2{background-color:#64ffda !important}.teal-text.text-accent-2{color:#64ffda !important}.teal.accent-3{background-color:#1de9b6 !important}.teal-text.text-accent-3{color:#1de9b6 !important}.teal.accent-4{background-color:#00bfa5 !important}.teal-text.text-accent-4{color:#00bfa5 !important}.green{background-color:#4CAF50 !important}.green-text{color:#4CAF50 !important}.green.lighten-5{background-color:#E8F5E9 !important}.green-text.text-lighten-5{color:#E8F5E9 !important}.green.lighten-4{background-color:#C8E6C9 !important}.green-text.text-lighten-4{color:#C8E6C9 !important}.green.lighten-3{background-color:#A5D6A7 !important}.green-text.text-lighten-3{color:#A5D6A7 !important}.green.lighten-2{background-color:#81C784 !important}.green-text.text-lighten-2{color:#81C784 !important}.green.lighten-1{background-color:#66BB6A !important}.green-text.text-lighten-1{color:#66BB6A !important}.green.darken-1{background-color:#43A047 !important}.green-text.text-darken-1{color:#43A047 !important}.green.darken-2{background-color:#388E3C !important}.green-text.text-darken-2{color:#388E3C !important}.green.darken-3{background-color:#2E7D32 !important}.green-text.text-darken-3{color:#2E7D32 !important}.green.darken-4{background-color:#1B5E20 !important}.green-text.text-darken-4{color:#1B5E20 !important}.green.accent-1{background-color:#B9F6CA !important}.green-text.text-accent-1{color:#B9F6CA !important}.green.accent-2{background-color:#69F0AE !important}.green-text.text-accent-2{color:#69F0AE !important}.green.accent-3{background-color:#00E676 !important}.green-text.text-accent-3{color:#00E676 !important}.green.accent-4{background-color:#00C853 !important}.green-text.text-accent-4{color:#00C853 !important}.light-green{background-color:#8bc34a !important}.light-green-text{color:#8bc34a !important}.light-green.lighten-5{background-color:#f1f8e9 !important}.light-green-text.text-lighten-5{color:#f1f8e9 !important}.light-green.lighten-4{background-color:#dcedc8 !important}.light-green-text.text-lighten-4{color:#dcedc8 !important}.light-green.lighten-3{background-color:#c5e1a5 !important}.light-green-text.text-lighten-3{color:#c5e1a5 !important}.light-green.lighten-2{background-color:#aed581 !important}.light-green-text.text-lighten-2{color:#aed581 !important}.light-green.lighten-1{background-color:#9ccc65 !important}.light-green-text.text-lighten-1{color:#9ccc65 !important}.light-green.darken-1{background-color:#7cb342 !important}.light-green-text.text-darken-1{color:#7cb342 !important}.light-green.darken-2{background-color:#689f38 !important}.light-green-text.text-darken-2{color:#689f38 !important}.light-green.darken-3{background-color:#558b2f !important}.light-green-text.text-darken-3{color:#558b2f !important}.light-green.darken-4{background-color:#33691e !important}.light-green-text.text-darken-4{color:#33691e !important}.light-green.accent-1{background-color:#ccff90 !important}.light-green-text.text-accent-1{color:#ccff90 !important}.light-green.accent-2{background-color:#b2ff59 !important}.light-green-text.text-accent-2{color:#b2ff59 !important}.light-green.accent-3{background-color:#76ff03 !important}.light-green-text.text-accent-3{color:#76ff03 !important}.light-green.accent-4{background-color:#64dd17 !important}.light-green-text.text-accent-4{color:#64dd17 !important}.lime{background-color:#cddc39 !important}.lime-text{color:#cddc39 !important}.lime.lighten-5{background-color:#f9fbe7 !important}.lime-text.text-lighten-5{color:#f9fbe7 !important}.lime.lighten-4{background-color:#f0f4c3 !important}.lime-text.text-lighten-4{color:#f0f4c3 !important}.lime.lighten-3{background-color:#e6ee9c !important}.lime-text.text-lighten-3{color:#e6ee9c !important}.lime.lighten-2{background-color:#dce775 !important}.lime-text.text-lighten-2{color:#dce775 !important}.lime.lighten-1{background-color:#d4e157 !important}.lime-text.text-lighten-1{color:#d4e157 !important}.lime.darken-1{background-color:#c0ca33 !important}.lime-text.text-darken-1{color:#c0ca33 !important}.lime.darken-2{background-color:#afb42b !important}.lime-text.text-darken-2{color:#afb42b !important}.lime.darken-3{background-color:#9e9d24 !important}.lime-text.text-darken-3{color:#9e9d24 !important}.lime.darken-4{background-color:#827717 !important}.lime-text.text-darken-4{color:#827717 !important}.lime.accent-1{background-color:#f4ff81 !important}.lime-text.text-accent-1{color:#f4ff81 !important}.lime.accent-2{background-color:#eeff41 !important}.lime-text.text-accent-2{color:#eeff41 !important}.lime.accent-3{background-color:#c6ff00 !important}.lime-text.text-accent-3{color:#c6ff00 !important}.lime.accent-4{background-color:#aeea00 !important}.lime-text.text-accent-4{color:#aeea00 !important}.yellow{background-color:#ffeb3b !important}.yellow-text{color:#ffeb3b !important}.yellow.lighten-5{background-color:#fffde7 !important}.yellow-text.text-lighten-5{color:#fffde7 !important}.yellow.lighten-4{background-color:#fff9c4 !important}.yellow-text.text-lighten-4{color:#fff9c4 !important}.yellow.lighten-3{background-color:#fff59d !important}.yellow-text.text-lighten-3{color:#fff59d !important}.yellow.lighten-2{background-color:#fff176 !important}.yellow-text.text-lighten-2{color:#fff176 !important}.yellow.lighten-1{background-color:#ffee58 !important}.yellow-text.text-lighten-1{color:#ffee58 !important}.yellow.darken-1{background-color:#fdd835 !important}.yellow-text.text-darken-1{color:#fdd835 !important}.yellow.darken-2{background-color:#fbc02d !important}.yellow-text.text-darken-2{color:#fbc02d !important}.yellow.darken-3{background-color:#f9a825 !important}.yellow-text.text-darken-3{color:#f9a825 !important}.yellow.darken-4{background-color:#f57f17 !important}.yellow-text.text-darken-4{color:#f57f17 !important}.yellow.accent-1{background-color:#ffff8d !important}.yellow-text.text-accent-1{color:#ffff8d !important}.yellow.accent-2{background-color:#ff0 !important}.yellow-text.text-accent-2{color:#ff0 !important}.yellow.accent-3{background-color:#ffea00 !important}.yellow-text.text-accent-3{color:#ffea00 !important}.yellow.accent-4{background-color:#ffd600 !important}.yellow-text.text-accent-4{color:#ffd600 !important}.amber{background-color:#ffc107 !important}.amber-text{color:#ffc107 !important}.amber.lighten-5{background-color:#fff8e1 !important}.amber-text.text-lighten-5{color:#fff8e1 !important}.amber.lighten-4{background-color:#ffecb3 !important}.amber-text.text-lighten-4{color:#ffecb3 !important}.amber.lighten-3{background-color:#ffe082 !important}.amber-text.text-lighten-3{color:#ffe082 !important}.amber.lighten-2{background-color:#ffd54f !important}.amber-text.text-lighten-2{color:#ffd54f !important}.amber.lighten-1{background-color:#ffca28 !important}.amber-text.text-lighten-1{color:#ffca28 !important}.amber.darken-1{background-color:#ffb300 !important}.amber-text.text-darken-1{color:#ffb300 !important}.amber.darken-2{background-color:#ffa000 !important}.amber-text.text-darken-2{color:#ffa000 !important}.amber.darken-3{background-color:#ff8f00 !important}.amber-text.text-darken-3{color:#ff8f00 !important}.amber.darken-4{background-color:#ff6f00 !important}.amber-text.text-darken-4{color:#ff6f00 !important}.amber.accent-1{background-color:#ffe57f !important}.amber-text.text-accent-1{color:#ffe57f !important}.amber.accent-2{background-color:#ffd740 !important}.amber-text.text-accent-2{color:#ffd740 !important}.amber.accent-3{background-color:#ffc400 !important}.amber-text.text-accent-3{color:#ffc400 !important}.amber.accent-4{background-color:#ffab00 !important}.amber-text.text-accent-4{color:#ffab00 !important}.orange{background-color:#ff9800 !important}.orange-text{color:#ff9800 !important}.orange.lighten-5{background-color:#fff3e0 !important}.orange-text.text-lighten-5{color:#fff3e0 !important}.orange.lighten-4{background-color:#ffe0b2 !important}.orange-text.text-lighten-4{color:#ffe0b2 !important}.orange.lighten-3{background-color:#ffcc80 !important}.orange-text.text-lighten-3{color:#ffcc80 !important}.orange.lighten-2{background-color:#ffb74d !important}.orange-text.text-lighten-2{color:#ffb74d !important}.orange.lighten-1{background-color:#ffa726 !important}.orange-text.text-lighten-1{color:#ffa726 !important}.orange.darken-1{background-color:#fb8c00 !important}.orange-text.text-darken-1{color:#fb8c00 !important}.orange.darken-2{background-color:#f57c00 !important}.orange-text.text-darken-2{color:#f57c00 !important}.orange.darken-3{background-color:#ef6c00 !important}.orange-text.text-darken-3{color:#ef6c00 !important}.orange.darken-4{background-color:#e65100 !important}.orange-text.text-darken-4{color:#e65100 !important}.orange.accent-1{background-color:#ffd180 !important}.orange-text.text-accent-1{color:#ffd180 !important}.orange.accent-2{background-color:#ffab40 !important}.orange-text.text-accent-2{color:#ffab40 !important}.orange.accent-3{background-color:#ff9100 !important}.orange-text.text-accent-3{color:#ff9100 !important}.orange.accent-4{background-color:#ff6d00 !important}.orange-text.text-accent-4{color:#ff6d00 !important}.deep-orange{background-color:#ff5722 !important}.deep-orange-text{color:#ff5722 !important}.deep-orange.lighten-5{background-color:#fbe9e7 !important}.deep-orange-text.text-lighten-5{color:#fbe9e7 !important}.deep-orange.lighten-4{background-color:#ffccbc !important}.deep-orange-text.text-lighten-4{color:#ffccbc !important}.deep-orange.lighten-3{background-color:#ffab91 !important}.deep-orange-text.text-lighten-3{color:#ffab91 !important}.deep-orange.lighten-2{background-color:#ff8a65 !important}.deep-orange-text.text-lighten-2{color:#ff8a65 !important}.deep-orange.lighten-1{background-color:#ff7043 !important}.deep-orange-text.text-lighten-1{color:#ff7043 !important}.deep-orange.darken-1{background-color:#f4511e !important}.deep-orange-text.text-darken-1{color:#f4511e !important}.deep-orange.darken-2{background-color:#e64a19 !important}.deep-orange-text.text-darken-2{color:#e64a19 !important}.deep-orange.darken-3{background-color:#d84315 !important}.deep-orange-text.text-darken-3{color:#d84315 !important}.deep-orange.darken-4{background-color:#bf360c !important}.deep-orange-text.text-darken-4{color:#bf360c !important}.deep-orange.accent-1{background-color:#ff9e80 !important}.deep-orange-text.text-accent-1{color:#ff9e80 !important}.deep-orange.accent-2{background-color:#ff6e40 !important}.deep-orange-text.text-accent-2{color:#ff6e40 !important}.deep-orange.accent-3{background-color:#ff3d00 !important}.deep-orange-text.text-accent-3{color:#ff3d00 !important}.deep-orange.accent-4{background-color:#dd2c00 !important}.deep-orange-text.text-accent-4{color:#dd2c00 !important}.brown{background-color:#795548 !important}.brown-text{color:#795548 !important}.brown.lighten-5{background-color:#efebe9 !important}.brown-text.text-lighten-5{color:#efebe9 !important}.brown.lighten-4{background-color:#d7ccc8 !important}.brown-text.text-lighten-4{color:#d7ccc8 !important}.brown.lighten-3{background-color:#bcaaa4 !important}.brown-text.text-lighten-3{color:#bcaaa4 !important}.brown.lighten-2{background-color:#a1887f !important}.brown-text.text-lighten-2{color:#a1887f !important}.brown.lighten-1{background-color:#8d6e63 !important}.brown-text.text-lighten-1{color:#8d6e63 !important}.brown.darken-1{background-color:#6d4c41 !important}.brown-text.text-darken-1{color:#6d4c41 !important}.brown.darken-2{background-color:#5d4037 !important}.brown-text.text-darken-2{color:#5d4037 !important}.brown.darken-3{background-color:#4e342e !important}.brown-text.text-darken-3{color:#4e342e !important}.brown.darken-4{background-color:#3e2723 !important}.brown-text.text-darken-4{color:#3e2723 !important}.blue-grey{background-color:#607d8b !important}.blue-grey-text{color:#607d8b !important}.blue-grey.lighten-5{background-color:#eceff1 !important}.blue-grey-text.text-lighten-5{color:#eceff1 !important}.blue-grey.lighten-4{background-color:#cfd8dc !important}.blue-grey-text.text-lighten-4{color:#cfd8dc !important}.blue-grey.lighten-3{background-color:#b0bec5 !important}.blue-grey-text.text-lighten-3{color:#b0bec5 !important}.blue-grey.lighten-2{background-color:#90a4ae !important}.blue-grey-text.text-lighten-2{color:#90a4ae !important}.blue-grey.lighten-1{background-color:#78909c !important}.blue-grey-text.text-lighten-1{color:#78909c !important}.blue-grey.darken-1{background-color:#546e7a !important}.blue-grey-text.text-darken-1{color:#546e7a !important}.blue-grey.darken-2{background-color:#455a64 !important}.blue-grey-text.text-darken-2{color:#455a64 !important}.blue-grey.darken-3{background-color:#37474f !important}.blue-grey-text.text-darken-3{color:#37474f !important}.blue-grey.darken-4{background-color:#263238 !important}.blue-grey-text.text-darken-4{color:#263238 !important}.grey{background-color:#9e9e9e !important}.grey-text{color:#9e9e9e !important}.grey.lighten-5{background-color:#fafafa !important}.grey-text.text-lighten-5{color:#fafafa !important}.grey.lighten-4{background-color:#f5f5f5 !important}.grey-text.text-lighten-4{color:#f5f5f5 !important}.grey.lighten-3{background-color:#eee !important}.grey-text.text-lighten-3{color:#eee !important}.grey.lighten-2{background-color:#e0e0e0 !important}.grey-text.text-lighten-2{color:#e0e0e0 !important}.grey.lighten-1{background-color:#bdbdbd !important}.grey-text.text-lighten-1{color:#bdbdbd !important}.grey.darken-1{background-color:#757575 !important}.grey-text.text-darken-1{color:#757575 !important}.grey.darken-2{background-color:#616161 !important}.grey-text.text-darken-2{color:#616161 !important}.grey.darken-3{background-color:#424242 !important}.grey-text.text-darken-3{color:#424242 !important}.grey.darken-4{background-color:#212121 !important}.grey-text.text-darken-4{color:#212121 !important}.black{background-color:#000 !important}.black-text{color:#000 !important}.white{background-color:#fff !important}.white-text{color:#fff !important}.transparent{background-color:transparent !important}.transparent-text{color:transparent !important}/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}ul:not(.browser-default){padding-left:0;list-style-type:none}ul:not(.browser-default) li{list-style-type:none}a{color:#039be5;text-decoration:none;-webkit-tap-highlight-color:transparent}.valign-wrapper{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.clearfix{clear:both}.z-depth-0{box-shadow:none !important}.z-depth-1,nav,.card-panel,.card,.toast,.btn,.btn-large,.btn-floating,.dropdown-content,.collapsible,.side-nav{box-shadow:0 2px 2px 0 rgba(0,0,0,0.14),0 1px 5px 0 rgba(0,0,0,0.12),0 3px 1px -2px rgba(0,0,0,0.2)}.z-depth-1-half,.btn:hover,.btn-large:hover,.btn-floating:hover{box-shadow:0 3px 3px 0 rgba(0,0,0,0.14),0 1px 7px 0 rgba(0,0,0,0.12),0 3px 1px -1px rgba(0,0,0,0.2)}.z-depth-2{box-shadow:0 4px 5px 0 rgba(0,0,0,0.14),0 1px 10px 0 rgba(0,0,0,0.12),0 2px 4px -1px rgba(0,0,0,0.3)}.z-depth-3{box-shadow:0 6px 10px 0 rgba(0,0,0,0.14),0 1px 18px 0 rgba(0,0,0,0.12),0 3px 5px -1px rgba(0,0,0,0.3)}.z-depth-4,.modal{box-shadow:0 8px 10px 1px rgba(0,0,0,0.14),0 3px 14px 2px rgba(0,0,0,0.12),0 5px 5px -3px rgba(0,0,0,0.3)}.z-depth-5{box-shadow:0 16px 24px 2px rgba(0,0,0,0.14),0 6px 30px 5px rgba(0,0,0,0.12),0 8px 10px -5px rgba(0,0,0,0.3)}.hoverable{transition:box-shadow .25s;box-shadow:0}.hoverable:hover{transition:box-shadow .25s;box-shadow:0 8px 17px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19)}.divider{height:1px;overflow:hidden;background-color:#e0e0e0}blockquote{margin:20px 0;padding-left:1.5rem;border-left:5px solid #ee6e73}i{line-height:inherit}i.left{float:left;margin-right:15px}i.right{float:right;margin-left:15px}i.tiny{font-size:1rem}i.small{font-size:2rem}i.medium{font-size:4rem}i.large{font-size:6rem}img.responsive-img,video.responsive-video{max-width:100%;height:auto}.pagination li{display:inline-block;border-radius:2px;text-align:center;vertical-align:top;height:30px}.pagination li a{color:#444;display:inline-block;font-size:1.2rem;padding:0 10px;line-height:30px}.pagination li.active a{color:#fff}.pagination li.active{background-color:#ee6e73}.pagination li.disabled a{cursor:default;color:#999}.pagination li i{font-size:2rem}.pagination li.pages ul li{display:inline-block;float:none}@media only screen and (max-width: 992px){.pagination{width:100%}.pagination li.prev,.pagination li.next{width:10%}.pagination li.pages{width:80%;overflow:hidden;white-space:nowrap}}.breadcrumb{font-size:18px;color:rgba(255,255,255,0.7)}.breadcrumb i,.breadcrumb [class^="mdi-"],.breadcrumb [class*="mdi-"],.breadcrumb i.material-icons{display:inline-block;float:left;font-size:24px}.breadcrumb:before{content:'\E5CC';color:rgba(255,255,255,0.7);vertical-align:top;display:inline-block;font-family:'Material Icons';font-weight:normal;font-style:normal;font-size:25px;margin:0 10px 0 8px;-webkit-font-smoothing:antialiased}.breadcrumb:first-child:before{display:none}.breadcrumb:last-child{color:#fff}.parallax-container{position:relative;overflow:hidden;height:500px}.parallax{position:absolute;top:0;left:0;right:0;bottom:0;z-index:-1}.parallax img{display:none;position:absolute;left:50%;bottom:0;min-width:100%;min-height:100%;-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);-webkit-transform:translateX(-50%);transform:translateX(-50%)}.pin-top,.pin-bottom{position:relative}.pinned{position:fixed !important}ul.staggered-list li{opacity:0}.fade-in{opacity:0;-webkit-transform-origin:0 50%;transform-origin:0 50%}@media only screen and (max-width: 600px){.hide-on-small-only,.hide-on-small-and-down{display:none !important}}@media only screen and (max-width: 992px){.hide-on-med-and-down{display:none !important}}@media only screen and (min-width: 601px){.hide-on-med-and-up{display:none !important}}@media only screen and (min-width: 600px) and (max-width: 992px){.hide-on-med-only{display:none !important}}@media only screen and (min-width: 993px){.hide-on-large-only{display:none !important}}@media only screen and (min-width: 993px){.show-on-large{display:block !important}}@media only screen and (min-width: 600px) and (max-width: 992px){.show-on-medium{display:block !important}}@media only screen and (max-width: 600px){.show-on-small{display:block !important}}@media only screen and (min-width: 601px){.show-on-medium-and-up{display:block !important}}@media only screen and (max-width: 992px){.show-on-medium-and-down{display:block !important}}@media only screen and (max-width: 600px){.center-on-small-only{text-align:center}}.page-footer{padding-top:20px;background-color:#ee6e73}.page-footer .footer-copyright{overflow:hidden;min-height:50px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;padding:10px 0px;color:rgba(255,255,255,0.8);background-color:rgba(51,51,51,0.08)}table,th,td{border:none}table{width:100%;display:table}table.bordered>thead>tr,table.bordered>tbody>tr{border-bottom:1px solid #d0d0d0}table.striped>tbody>tr:nth-child(odd){background-color:#f2f2f2}table.striped>tbody>tr>td{border-radius:0}table.highlight>tbody>tr{transition:background-color .25s ease}table.highlight>tbody>tr:hover{background-color:#f2f2f2}table.centered thead tr th,table.centered tbody tr td{text-align:center}thead{border-bottom:1px solid #d0d0d0}td,th{padding:15px 5px;display:table-cell;text-align:left;vertical-align:middle;border-radius:2px}@media only screen and (max-width: 992px){table.responsive-table{width:100%;border-collapse:collapse;border-spacing:0;display:block;position:relative}table.responsive-table td:empty:before{content:'\00a0'}table.responsive-table th,table.responsive-table td{margin:0;vertical-align:top}table.responsive-table th{text-align:left}table.responsive-table thead{display:block;float:left}table.responsive-table thead tr{display:block;padding:0 10px 0 0}table.responsive-table thead tr th::before{content:"\00a0"}table.responsive-table tbody{display:block;width:auto;position:relative;overflow-x:auto;white-space:nowrap}table.responsive-table tbody tr{display:inline-block;vertical-align:top}table.responsive-table th{display:block;text-align:right}table.responsive-table td{display:block;min-height:1.25em;text-align:left}table.responsive-table tr{padding:0 10px}table.responsive-table thead{border:0;border-right:1px solid #d0d0d0}table.responsive-table.bordered th{border-bottom:0;border-left:0}table.responsive-table.bordered td{border-left:0;border-right:0;border-bottom:0}table.responsive-table.bordered tr{border:0}table.responsive-table.bordered tbody tr{border-right:1px solid #d0d0d0}}.collection{margin:.5rem 0 1rem 0;border:1px solid #e0e0e0;border-radius:2px;overflow:hidden;position:relative}.collection .collection-item{background-color:#fff;line-height:1.5rem;padding:10px 20px;margin:0;border-bottom:1px solid #e0e0e0}.collection .collection-item.avatar{min-height:84px;padding-left:72px;position:relative}.collection .collection-item.avatar .circle{position:absolute;width:42px;height:42px;overflow:hidden;left:15px;display:inline-block;vertical-align:middle}.collection .collection-item.avatar i.circle{font-size:18px;line-height:42px;color:#fff;background-color:#999;text-align:center}.collection .collection-item.avatar .title{font-size:16px}.collection .collection-item.avatar p{margin:0}.collection .collection-item.avatar .secondary-content{position:absolute;top:16px;right:16px}.collection .collection-item:last-child{border-bottom:none}.collection .collection-item.active{background-color:#26a69a;color:#eafaf9}.collection .collection-item.active .secondary-content{color:#fff}.collection a.collection-item{display:block;transition:.25s;color:#26a69a}.collection a.collection-item:not(.active):hover{background-color:#ddd}.collection.with-header .collection-header{background-color:#fff;border-bottom:1px solid #e0e0e0;padding:10px 20px}.collection.with-header .collection-item{padding-left:30px}.collection.with-header .collection-item.avatar{padding-left:72px}.secondary-content{float:right;color:#26a69a}.collapsible .collection{margin:0;border:none}.video-container{position:relative;padding-bottom:56.25%;height:0;overflow:hidden}.video-container iframe,.video-container object,.video-container embed{position:absolute;top:0;left:0;width:100%;height:100%}.progress{position:relative;height:4px;display:block;width:100%;background-color:#acece6;border-radius:2px;margin:.5rem 0 1rem 0;overflow:hidden}.progress .determinate{position:absolute;top:0;left:0;bottom:0;background-color:#26a69a;transition:width .3s linear}.progress .indeterminate{background-color:#26a69a}.progress .indeterminate:before{content:'';position:absolute;background-color:inherit;top:0;left:0;bottom:0;will-change:left, right;-webkit-animation:indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;animation:indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite}.progress .indeterminate:after{content:'';position:absolute;background-color:inherit;top:0;left:0;bottom:0;will-change:left, right;-webkit-animation:indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;animation:indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;-webkit-animation-delay:1.15s;animation-delay:1.15s}@-webkit-keyframes indeterminate{0%{left:-35%;right:100%}60%{left:100%;right:-90%}100%{left:100%;right:-90%}}@keyframes indeterminate{0%{left:-35%;right:100%}60%{left:100%;right:-90%}100%{left:100%;right:-90%}}@-webkit-keyframes indeterminate-short{0%{left:-200%;right:100%}60%{left:107%;right:-8%}100%{left:107%;right:-8%}}@keyframes indeterminate-short{0%{left:-200%;right:100%}60%{left:107%;right:-8%}100%{left:107%;right:-8%}}.hide{display:none !important}.left-align{text-align:left}.right-align{text-align:right}.center,.center-align{text-align:center}.left{float:left !important}.right{float:right !important}.no-select,input[type=range],input[type=range]+.thumb{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.circle{border-radius:50%}.center-block{display:block;margin-left:auto;margin-right:auto}.truncate{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.no-padding{padding:0 !important}span.badge{min-width:3rem;padding:0 6px;margin-left:14px;text-align:center;font-size:1rem;line-height:22px;height:22px;color:#757575;float:right;box-sizing:border-box}span.badge.new{font-weight:300;font-size:0.8rem;color:#fff;background-color:#26a69a;border-radius:2px}span.badge.new:after{content:" new"}span.badge[data-badge-caption]::after{content:" " attr(data-badge-caption)}nav ul a span.badge{display:inline-block;float:none;margin-left:4px;line-height:22px;height:22px}.collection-item span.badge{margin-top:calc(.75rem - 11px)}.collapsible span.badge{margin-top:calc(1.5rem - 11px)}.side-nav span.badge{margin-top:calc(24px - 11px)}.material-icons{text-rendering:optimizeLegibility;-webkit-font-feature-settings:'liga';-moz-font-feature-settings:'liga';font-feature-settings:'liga'}.container{margin:0 auto;max-width:1280px;width:90%}@media only screen and (min-width: 601px){.container{width:85%}}@media only screen and (min-width: 993px){.container{width:70%}}.container .row{margin-left:-.75rem;margin-right:-.75rem}.section{padding-top:1rem;padding-bottom:1rem}.section.no-pad{padding:0}.section.no-pad-bot{padding-bottom:0}.section.no-pad-top{padding-top:0}.row{margin-left:auto;margin-right:auto;margin-bottom:20px}.row:after{content:"";display:table;clear:both}.row .col{float:left;box-sizing:border-box;padding:0 .75rem;min-height:1px}.row .col[class*="push-"],.row .col[class*="pull-"]{position:relative}.row .col.s1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.s4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.s7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.s10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.s11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.s12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-s1{margin-left:8.3333333333%}.row .col.pull-s1{right:8.3333333333%}.row .col.push-s1{left:8.3333333333%}.row .col.offset-s2{margin-left:16.6666666667%}.row .col.pull-s2{right:16.6666666667%}.row .col.push-s2{left:16.6666666667%}.row .col.offset-s3{margin-left:25%}.row .col.pull-s3{right:25%}.row .col.push-s3{left:25%}.row .col.offset-s4{margin-left:33.3333333333%}.row .col.pull-s4{right:33.3333333333%}.row .col.push-s4{left:33.3333333333%}.row .col.offset-s5{margin-left:41.6666666667%}.row .col.pull-s5{right:41.6666666667%}.row .col.push-s5{left:41.6666666667%}.row .col.offset-s6{margin-left:50%}.row .col.pull-s6{right:50%}.row .col.push-s6{left:50%}.row .col.offset-s7{margin-left:58.3333333333%}.row .col.pull-s7{right:58.3333333333%}.row .col.push-s7{left:58.3333333333%}.row .col.offset-s8{margin-left:66.6666666667%}.row .col.pull-s8{right:66.6666666667%}.row .col.push-s8{left:66.6666666667%}.row .col.offset-s9{margin-left:75%}.row .col.pull-s9{right:75%}.row .col.push-s9{left:75%}.row .col.offset-s10{margin-left:83.3333333333%}.row .col.pull-s10{right:83.3333333333%}.row .col.push-s10{left:83.3333333333%}.row .col.offset-s11{margin-left:91.6666666667%}.row .col.pull-s11{right:91.6666666667%}.row .col.push-s11{left:91.6666666667%}.row .col.offset-s12{margin-left:100%}.row .col.pull-s12{right:100%}.row .col.push-s12{left:100%}@media only screen and (min-width: 601px){.row .col.m1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.m4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.m7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.m10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.m11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.m12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-m1{margin-left:8.3333333333%}.row .col.pull-m1{right:8.3333333333%}.row .col.push-m1{left:8.3333333333%}.row .col.offset-m2{margin-left:16.6666666667%}.row .col.pull-m2{right:16.6666666667%}.row .col.push-m2{left:16.6666666667%}.row .col.offset-m3{margin-left:25%}.row .col.pull-m3{right:25%}.row .col.push-m3{left:25%}.row .col.offset-m4{margin-left:33.3333333333%}.row .col.pull-m4{right:33.3333333333%}.row .col.push-m4{left:33.3333333333%}.row .col.offset-m5{margin-left:41.6666666667%}.row .col.pull-m5{right:41.6666666667%}.row .col.push-m5{left:41.6666666667%}.row .col.offset-m6{margin-left:50%}.row .col.pull-m6{right:50%}.row .col.push-m6{left:50%}.row .col.offset-m7{margin-left:58.3333333333%}.row .col.pull-m7{right:58.3333333333%}.row .col.push-m7{left:58.3333333333%}.row .col.offset-m8{margin-left:66.6666666667%}.row .col.pull-m8{right:66.6666666667%}.row .col.push-m8{left:66.6666666667%}.row .col.offset-m9{margin-left:75%}.row .col.pull-m9{right:75%}.row .col.push-m9{left:75%}.row .col.offset-m10{margin-left:83.3333333333%}.row .col.pull-m10{right:83.3333333333%}.row .col.push-m10{left:83.3333333333%}.row .col.offset-m11{margin-left:91.6666666667%}.row .col.pull-m11{right:91.6666666667%}.row .col.push-m11{left:91.6666666667%}.row .col.offset-m12{margin-left:100%}.row .col.pull-m12{right:100%}.row .col.push-m12{left:100%}}@media only screen and (min-width: 993px){.row .col.l1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.l4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.l7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.l10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.l11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.l12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-l1{margin-left:8.3333333333%}.row .col.pull-l1{right:8.3333333333%}.row .col.push-l1{left:8.3333333333%}.row .col.offset-l2{margin-left:16.6666666667%}.row .col.pull-l2{right:16.6666666667%}.row .col.push-l2{left:16.6666666667%}.row .col.offset-l3{margin-left:25%}.row .col.pull-l3{right:25%}.row .col.push-l3{left:25%}.row .col.offset-l4{margin-left:33.3333333333%}.row .col.pull-l4{right:33.3333333333%}.row .col.push-l4{left:33.3333333333%}.row .col.offset-l5{margin-left:41.6666666667%}.row .col.pull-l5{right:41.6666666667%}.row .col.push-l5{left:41.6666666667%}.row .col.offset-l6{margin-left:50%}.row .col.pull-l6{right:50%}.row .col.push-l6{left:50%}.row .col.offset-l7{margin-left:58.3333333333%}.row .col.pull-l7{right:58.3333333333%}.row .col.push-l7{left:58.3333333333%}.row .col.offset-l8{margin-left:66.6666666667%}.row .col.pull-l8{right:66.6666666667%}.row .col.push-l8{left:66.6666666667%}.row .col.offset-l9{margin-left:75%}.row .col.pull-l9{right:75%}.row .col.push-l9{left:75%}.row .col.offset-l10{margin-left:83.3333333333%}.row .col.pull-l10{right:83.3333333333%}.row .col.push-l10{left:83.3333333333%}.row .col.offset-l11{margin-left:91.6666666667%}.row .col.pull-l11{right:91.6666666667%}.row .col.push-l11{left:91.6666666667%}.row .col.offset-l12{margin-left:100%}.row .col.pull-l12{right:100%}.row .col.push-l12{left:100%}}@media only screen and (min-width: 1201px){.row .col.xl1{width:8.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.xl2{width:16.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.xl3{width:25%;margin-left:auto;left:auto;right:auto}.row .col.xl4{width:33.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.xl5{width:41.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.xl6{width:50%;margin-left:auto;left:auto;right:auto}.row .col.xl7{width:58.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.xl8{width:66.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.xl9{width:75%;margin-left:auto;left:auto;right:auto}.row .col.xl10{width:83.3333333333%;margin-left:auto;left:auto;right:auto}.row .col.xl11{width:91.6666666667%;margin-left:auto;left:auto;right:auto}.row .col.xl12{width:100%;margin-left:auto;left:auto;right:auto}.row .col.offset-xl1{margin-left:8.3333333333%}.row .col.pull-xl1{right:8.3333333333%}.row .col.push-xl1{left:8.3333333333%}.row .col.offset-xl2{margin-left:16.6666666667%}.row .col.pull-xl2{right:16.6666666667%}.row .col.push-xl2{left:16.6666666667%}.row .col.offset-xl3{margin-left:25%}.row .col.pull-xl3{right:25%}.row .col.push-xl3{left:25%}.row .col.offset-xl4{margin-left:33.3333333333%}.row .col.pull-xl4{right:33.3333333333%}.row .col.push-xl4{left:33.3333333333%}.row .col.offset-xl5{margin-left:41.6666666667%}.row .col.pull-xl5{right:41.6666666667%}.row .col.push-xl5{left:41.6666666667%}.row .col.offset-xl6{margin-left:50%}.row .col.pull-xl6{right:50%}.row .col.push-xl6{left:50%}.row .col.offset-xl7{margin-left:58.3333333333%}.row .col.pull-xl7{right:58.3333333333%}.row .col.push-xl7{left:58.3333333333%}.row .col.offset-xl8{margin-left:66.6666666667%}.row .col.pull-xl8{right:66.6666666667%}.row .col.push-xl8{left:66.6666666667%}.row .col.offset-xl9{margin-left:75%}.row .col.pull-xl9{right:75%}.row .col.push-xl9{left:75%}.row .col.offset-xl10{margin-left:83.3333333333%}.row .col.pull-xl10{right:83.3333333333%}.row .col.push-xl10{left:83.3333333333%}.row .col.offset-xl11{margin-left:91.6666666667%}.row .col.pull-xl11{right:91.6666666667%}.row .col.push-xl11{left:91.6666666667%}.row .col.offset-xl12{margin-left:100%}.row .col.pull-xl12{right:100%}.row .col.push-xl12{left:100%}}nav{color:#fff;background-color:#ee6e73;width:100%;height:56px;line-height:56px}nav.nav-extended{height:auto}nav.nav-extended .nav-wrapper{min-height:56px;height:auto}nav.nav-extended .nav-content{position:relative;line-height:normal}nav a{color:#fff}nav i,nav [class^="mdi-"],nav [class*="mdi-"],nav i.material-icons{display:block;font-size:24px;height:56px;line-height:56px}nav .nav-wrapper{position:relative;height:100%}@media only screen and (min-width: 993px){nav a.button-collapse{display:none}}nav .button-collapse{float:left;position:relative;z-index:1;height:56px;margin:0 18px}nav .button-collapse i{height:56px;line-height:56px}nav .brand-logo{position:absolute;color:#fff;display:inline-block;font-size:2.1rem;padding:0;white-space:nowrap}nav .brand-logo.center{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}@media only screen and (max-width: 992px){nav .brand-logo{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}nav .brand-logo.left,nav .brand-logo.right{padding:0;-webkit-transform:none;transform:none}nav .brand-logo.left{left:0.5rem}nav .brand-logo.right{right:0.5rem;left:auto}}nav .brand-logo.right{right:0.5rem;padding:0}nav .brand-logo i,nav .brand-logo [class^="mdi-"],nav .brand-logo [class*="mdi-"],nav .brand-logo i.material-icons{float:left;margin-right:15px}nav .nav-title{display:inline-block;font-size:32px;padding:28px 0}nav ul{margin:0}nav ul li{transition:background-color .3s;float:left;padding:0}nav ul li.active{background-color:rgba(0,0,0,0.1)}nav ul a{transition:background-color .3s;font-size:1rem;color:#fff;display:block;padding:0 15px;cursor:pointer}nav ul a.btn,nav ul a.btn-large,nav ul a.btn-large,nav ul a.btn-flat,nav ul a.btn-floating{margin-top:-2px;margin-left:15px;margin-right:15px}nav ul a.btn>.material-icons,nav ul a.btn-large>.material-icons,nav ul a.btn-large>.material-icons,nav ul a.btn-flat>.material-icons,nav ul a.btn-floating>.material-icons{height:inherit;line-height:inherit}nav ul a:hover{background-color:rgba(0,0,0,0.1)}nav ul.left{float:left}nav form{height:100%}nav .input-field{margin:0;height:100%}nav .input-field input{height:100%;font-size:1.2rem;border:none;padding-left:2rem}nav .input-field input:focus,nav .input-field input[type=text]:valid,nav .input-field input[type=password]:valid,nav .input-field input[type=email]:valid,nav .input-field input[type=url]:valid,nav .input-field input[type=date]:valid{border:none;box-shadow:none}nav .input-field label{top:0;left:0}nav .input-field label i{color:rgba(255,255,255,0.7);transition:color .3s}nav .input-field label.active i{color:#fff}.navbar-fixed{position:relative;height:56px;z-index:997}.navbar-fixed nav{position:fixed}@media only screen and (min-width: 601px){nav.nav-extended .nav-wrapper{min-height:64px}nav,nav .nav-wrapper i,nav a.button-collapse,nav a.button-collapse i{height:64px;line-height:64px}.navbar-fixed{height:64px}}@font-face{font-family:"Roboto";src:local(Roboto Thin),url("../fonts/roboto/Roboto-Thin.woff2") format("woff2"),url("../fonts/roboto/Roboto-Thin.woff") format("woff");font-weight:100}@font-face{font-family:"Roboto";src:local(Roboto Light),url("../fonts/roboto/Roboto-Light.woff2") format("woff2"),url("../fonts/roboto/Roboto-Light.woff") format("woff");font-weight:300}@font-face{font-family:"Roboto";src:local(Roboto Regular),url("../fonts/roboto/Roboto-Regular.woff2") format("woff2"),url("../fonts/roboto/Roboto-Regular.woff") format("woff");font-weight:400}@font-face{font-family:"Roboto";src:local(Roboto Medium),url("../fonts/roboto/Roboto-Medium.woff2") format("woff2"),url("../fonts/roboto/Roboto-Medium.woff") format("woff");font-weight:500}@font-face{font-family:"Roboto";src:local(Roboto Bold),url("../fonts/roboto/Roboto-Bold.woff2") format("woff2"),url("../fonts/roboto/Roboto-Bold.woff") format("woff");font-weight:700}a{text-decoration:none}html{line-height:1.5;font-family:"Roboto", sans-serif;font-weight:normal;color:rgba(0,0,0,0.87)}@media only screen and (min-width: 0){html{font-size:14px}}@media only screen and (min-width: 992px){html{font-size:14.5px}}@media only screen and (min-width: 1200px){html{font-size:15px}}h1,h2,h3,h4,h5,h6{font-weight:400;line-height:1.1}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{font-weight:inherit}h1{font-size:4.2rem;line-height:110%;margin:2.1rem 0 1.68rem 0}h2{font-size:3.56rem;line-height:110%;margin:1.78rem 0 1.424rem 0}h3{font-size:2.92rem;line-height:110%;margin:1.46rem 0 1.168rem 0}h4{font-size:2.28rem;line-height:110%;margin:1.14rem 0 .912rem 0}h5{font-size:1.64rem;line-height:110%;margin:.82rem 0 .656rem 0}h6{font-size:1rem;line-height:110%;margin:.5rem 0 .4rem 0}em{font-style:italic}strong{font-weight:500}small{font-size:75%}.light,.page-footer .footer-copyright{font-weight:300}.thin{font-weight:200}.flow-text{font-weight:300}@media only screen and (min-width: 360px){.flow-text{font-size:1.2rem}}@media only screen and (min-width: 390px){.flow-text{font-size:1.224rem}}@media only screen and (min-width: 420px){.flow-text{font-size:1.248rem}}@media only screen and (min-width: 450px){.flow-text{font-size:1.272rem}}@media only screen and (min-width: 480px){.flow-text{font-size:1.296rem}}@media only screen and (min-width: 510px){.flow-text{font-size:1.32rem}}@media only screen and (min-width: 540px){.flow-text{font-size:1.344rem}}@media only screen and (min-width: 570px){.flow-text{font-size:1.368rem}}@media only screen and (min-width: 600px){.flow-text{font-size:1.392rem}}@media only screen and (min-width: 630px){.flow-text{font-size:1.416rem}}@media only screen and (min-width: 660px){.flow-text{font-size:1.44rem}}@media only screen and (min-width: 690px){.flow-text{font-size:1.464rem}}@media only screen and (min-width: 720px){.flow-text{font-size:1.488rem}}@media only screen and (min-width: 750px){.flow-text{font-size:1.512rem}}@media only screen and (min-width: 780px){.flow-text{font-size:1.536rem}}@media only screen and (min-width: 810px){.flow-text{font-size:1.56rem}}@media only screen and (min-width: 840px){.flow-text{font-size:1.584rem}}@media only screen and (min-width: 870px){.flow-text{font-size:1.608rem}}@media only screen and (min-width: 900px){.flow-text{font-size:1.632rem}}@media only screen and (min-width: 930px){.flow-text{font-size:1.656rem}}@media only screen and (min-width: 960px){.flow-text{font-size:1.68rem}}@media only screen and (max-width: 360px){.flow-text{font-size:1.2rem}}.scale-transition{transition:-webkit-transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important;transition:transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important;transition:transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63), -webkit-transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important}.scale-transition.scale-out{-webkit-transform:scale(0);transform:scale(0);transition:-webkit-transform .2s !important;transition:transform .2s !important;transition:transform .2s, -webkit-transform .2s !important}.scale-transition.scale-in{-webkit-transform:scale(1);transform:scale(1)}.card-panel{transition:box-shadow .25s;padding:24px;margin:.5rem 0 1rem 0;border-radius:2px;background-color:#fff}.card{position:relative;margin:.5rem 0 1rem 0;background-color:#fff;transition:box-shadow .25s;border-radius:2px}.card .card-title{font-size:24px;font-weight:300}.card .card-title.activator{cursor:pointer}.card.small,.card.medium,.card.large{position:relative}.card.small .card-image,.card.medium .card-image,.card.large .card-image{max-height:60%;overflow:hidden}.card.small .card-image+.card-content,.card.medium .card-image+.card-content,.card.large .card-image+.card-content{max-height:40%}.card.small .card-content,.card.medium .card-content,.card.large .card-content{max-height:100%;overflow:hidden}.card.small .card-action,.card.medium .card-action,.card.large .card-action{position:absolute;bottom:0;left:0;right:0}.card.small{height:300px}.card.medium{height:400px}.card.large{height:500px}.card.horizontal{display:-webkit-flex;display:-ms-flexbox;display:flex}.card.horizontal.small .card-image,.card.horizontal.medium .card-image,.card.horizontal.large .card-image{height:100%;max-height:none;overflow:visible}.card.horizontal.small .card-image img,.card.horizontal.medium .card-image img,.card.horizontal.large .card-image img{height:100%}.card.horizontal .card-image{max-width:50%}.card.horizontal .card-image img{border-radius:2px 0 0 2px;max-width:100%;width:auto}.card.horizontal .card-stacked{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex:1;-ms-flex:1;flex:1;position:relative}.card.horizontal .card-stacked .card-content{-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.card.sticky-action .card-action{z-index:2}.card.sticky-action .card-reveal{z-index:1;padding-bottom:64px}.card .card-image{position:relative}.card .card-image img{display:block;border-radius:2px 2px 0 0;position:relative;left:0;right:0;top:0;bottom:0;width:100%}.card .card-image .card-title{color:#fff;position:absolute;bottom:0;left:0;max-width:100%;padding:24px}.card .card-content{padding:24px;border-radius:0 0 2px 2px}.card .card-content p{margin:0;color:inherit}.card .card-content .card-title{display:block;line-height:32px;margin-bottom:8px}.card .card-content .card-title i{line-height:32px}.card .card-action{position:relative;background-color:inherit;border-top:1px solid rgba(160,160,160,0.2);padding:16px 24px}.card .card-action:last-child{border-radius:0 0 2px 2px}.card .card-action a:not(.btn):not(.btn-large):not(.btn-large):not(.btn-floating){color:#ffab40;margin-right:24px;transition:color .3s ease;text-transform:uppercase}.card .card-action a:not(.btn):not(.btn-large):not(.btn-large):not(.btn-floating):hover{color:#ffd8a6}.card .card-reveal{padding:24px;position:absolute;background-color:#fff;width:100%;overflow-y:auto;left:0;top:100%;height:100%;z-index:3;display:none}.card .card-reveal .card-title{cursor:pointer;display:block}#toast-container{display:block;position:fixed;z-index:10000}@media only screen and (max-width: 600px){#toast-container{min-width:100%;bottom:0%}}@media only screen and (min-width: 601px) and (max-width: 992px){#toast-container{left:5%;bottom:7%;max-width:90%}}@media only screen and (min-width: 993px){#toast-container{top:10%;right:7%;max-width:86%}}.toast{border-radius:2px;top:35px;width:auto;clear:both;margin-top:10px;position:relative;max-width:100%;height:auto;min-height:48px;line-height:1.5em;word-break:break-all;background-color:#323232;padding:10px 25px;font-size:1.1rem;font-weight:300;color:#fff;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.toast .btn,.toast .btn-large,.toast .btn-flat{margin:0;margin-left:3rem}.toast.rounded{border-radius:24px}@media only screen and (max-width: 600px){.toast{width:100%;border-radius:0}}@media only screen and (min-width: 601px) and (max-width: 992px){.toast{float:left}}@media only screen and (min-width: 993px){.toast{float:right}}.tabs{position:relative;overflow-x:auto;overflow-y:hidden;height:48px;width:100%;background-color:#fff;margin:0 auto;white-space:nowrap}.tabs.tabs-transparent{background-color:transparent}.tabs.tabs-transparent .tab a,.tabs.tabs-transparent .tab.disabled a,.tabs.tabs-transparent .tab.disabled a:hover{color:rgba(255,255,255,0.7)}.tabs.tabs-transparent .tab a:hover,.tabs.tabs-transparent .tab a.active{color:#fff}.tabs.tabs-transparent .indicator{background-color:#fff}.tabs.tabs-fixed-width{display:-webkit-flex;display:-ms-flexbox;display:flex}.tabs.tabs-fixed-width .tab{-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.tabs .tab{display:inline-block;text-align:center;line-height:48px;height:48px;padding:0;margin:0;text-transform:uppercase}.tabs .tab a{color:rgba(238,110,115,0.7);display:block;width:100%;height:100%;padding:0 24px;font-size:14px;text-overflow:ellipsis;overflow:hidden;transition:color .28s ease}.tabs .tab a:hover,.tabs .tab a.active{background-color:transparent;color:#ee6e73}.tabs .tab.disabled a,.tabs .tab.disabled a:hover{color:rgba(238,110,115,0.7);cursor:default}.tabs .indicator{position:absolute;bottom:0;height:2px;background-color:#f6b2b5;will-change:left, right}@media only screen and (max-width: 992px){.tabs{display:-webkit-flex;display:-ms-flexbox;display:flex}.tabs .tab{-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.tabs .tab a{padding:0 12px}}.material-tooltip{padding:10px 8px;font-size:1rem;z-index:2000;background-color:transparent;border-radius:2px;color:#fff;min-height:36px;line-height:120%;opacity:0;position:absolute;text-align:center;max-width:calc(100% - 4px);overflow:hidden;left:0;top:0;pointer-events:none;visibility:hidden}.backdrop{position:absolute;opacity:0;height:7px;width:14px;border-radius:0 0 50% 50%;background-color:#323232;z-index:-1;-webkit-transform-origin:50% 0%;transform-origin:50% 0%;visibility:hidden}.btn,.btn-large,.btn-flat{border:none;border-radius:2px;display:inline-block;height:36px;line-height:36px;padding:0 2rem;text-transform:uppercase;vertical-align:middle;-webkit-tap-highlight-color:transparent}.btn.disabled,.disabled.btn-large,.btn-floating.disabled,.btn-large.disabled,.btn-flat.disabled,.btn:disabled,.btn-large:disabled,.btn-floating:disabled,.btn-large:disabled,.btn-flat:disabled,.btn[disabled],[disabled].btn-large,.btn-floating[disabled],.btn-large[disabled],.btn-flat[disabled]{pointer-events:none;background-color:#DFDFDF !important;box-shadow:none;color:#9F9F9F !important;cursor:default}.btn.disabled:hover,.disabled.btn-large:hover,.btn-floating.disabled:hover,.btn-large.disabled:hover,.btn-flat.disabled:hover,.btn:disabled:hover,.btn-large:disabled:hover,.btn-floating:disabled:hover,.btn-large:disabled:hover,.btn-flat:disabled:hover,.btn[disabled]:hover,[disabled].btn-large:hover,.btn-floating[disabled]:hover,.btn-large[disabled]:hover,.btn-flat[disabled]:hover{background-color:#DFDFDF !important;color:#9F9F9F !important}.btn,.btn-large,.btn-floating,.btn-large,.btn-flat{font-size:1rem;outline:0}.btn i,.btn-large i,.btn-floating i,.btn-large i,.btn-flat i{font-size:1.3rem;line-height:inherit}.btn:focus,.btn-large:focus,.btn-floating:focus{background-color:#1d7d74}.btn,.btn-large{text-decoration:none;color:#fff;background-color:#26a69a;text-align:center;letter-spacing:.5px;transition:.2s ease-out;cursor:pointer}.btn:hover,.btn-large:hover{background-color:#2bbbad}.btn-floating{display:inline-block;color:#fff;position:relative;overflow:hidden;z-index:1;width:40px;height:40px;line-height:40px;padding:0;background-color:#26a69a;border-radius:50%;transition:.3s;cursor:pointer;vertical-align:middle}.btn-floating:hover{background-color:#26a69a}.btn-floating:before{border-radius:0}.btn-floating.btn-large{width:56px;height:56px}.btn-floating.btn-large.halfway-fab{bottom:-28px}.btn-floating.btn-large i{line-height:56px}.btn-floating.halfway-fab{position:absolute;right:24px;bottom:-20px}.btn-floating.halfway-fab.left{right:auto;left:24px}.btn-floating i{width:inherit;display:inline-block;text-align:center;color:#fff;font-size:1.6rem;line-height:40px}button.btn-floating{border:none}.fixed-action-btn{position:fixed;right:23px;bottom:23px;padding-top:15px;margin-bottom:0;z-index:998}.fixed-action-btn.active ul{visibility:visible}.fixed-action-btn.horizontal{padding:0 0 0 15px}.fixed-action-btn.horizontal ul{text-align:right;right:64px;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);height:100%;left:auto;width:500px}.fixed-action-btn.horizontal ul li{display:inline-block;margin:15px 15px 0 0}.fixed-action-btn.toolbar{padding:0;height:56px}.fixed-action-btn.toolbar.active>a i{opacity:0}.fixed-action-btn.toolbar ul{display:-webkit-flex;display:-ms-flexbox;display:flex;top:0;bottom:0}.fixed-action-btn.toolbar ul li{-webkit-flex:1;-ms-flex:1;flex:1;display:inline-block;margin:0;height:100%;transition:none}.fixed-action-btn.toolbar ul li a{display:block;overflow:hidden;position:relative;width:100%;height:100%;background-color:transparent;box-shadow:none;color:#fff;line-height:56px;z-index:1}.fixed-action-btn.toolbar ul li a i{line-height:inherit}.fixed-action-btn ul{left:0;right:0;text-align:center;position:absolute;bottom:64px;margin:0;visibility:hidden}.fixed-action-btn ul li{margin-bottom:15px}.fixed-action-btn ul a.btn-floating{opacity:0}.fixed-action-btn .fab-backdrop{position:absolute;top:0;left:0;z-index:-1;width:40px;height:40px;background-color:#26a69a;border-radius:50%;-webkit-transform:scale(0);transform:scale(0)}.btn-flat{box-shadow:none;background-color:transparent;color:#343434;cursor:pointer;transition:background-color .2s}.btn-flat:focus,.btn-flat:active{background-color:transparent}.btn-flat:focus,.btn-flat:hover{background-color:rgba(0,0,0,0.1);box-shadow:none}.btn-flat:active{background-color:rgba(0,0,0,0.2)}.btn-flat.disabled{background-color:transparent !important;color:#b3b3b3 !important;cursor:default}.btn-large{height:54px;line-height:54px}.btn-large i{font-size:1.6rem}.btn-block{display:block}.dropdown-content{background-color:#fff;margin:0;display:none;min-width:100px;max-height:650px;overflow-y:auto;opacity:0;position:absolute;z-index:999;will-change:width, height}.dropdown-content li{clear:both;color:rgba(0,0,0,0.87);cursor:pointer;min-height:50px;line-height:1.5rem;width:100%;text-align:left;text-transform:none}.dropdown-content li:hover,.dropdown-content li.active,.dropdown-content li.selected{background-color:#eee}.dropdown-content li.active.selected{background-color:#e1e1e1}.dropdown-content li.divider{min-height:0;height:1px}.dropdown-content li>a,.dropdown-content li>span{font-size:16px;color:#26a69a;display:block;line-height:22px;padding:14px 16px}.dropdown-content li>span>label{top:1px;left:0;height:18px}.dropdown-content li>a>i{height:inherit;line-height:inherit;float:left;margin:0 24px 0 0;width:24px}.input-field.col .dropdown-content [type="checkbox"]+label{top:1px;left:0;height:18px}/*!
7
+ * Waves v0.6.0
8
+ * http://fian.my.id/Waves
9
+ *
10
+ * Copyright 2014 Alfiana E. Sibuea and other contributors
11
+ * Released under the MIT license
12
+ * https://github.com/fians/Waves/blob/master/LICENSE
13
+ */.waves-effect{position:relative;cursor:pointer;display:inline-block;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;vertical-align:middle;z-index:1;transition:.3s ease-out}.waves-effect .waves-ripple{position:absolute;border-radius:50%;width:20px;height:20px;margin-top:-10px;margin-left:-10px;opacity:0;background:rgba(0,0,0,0.2);transition:all 0.7s ease-out;transition-property:opacity, -webkit-transform;transition-property:transform, opacity;transition-property:transform, opacity, -webkit-transform;-webkit-transform:scale(0);transform:scale(0);pointer-events:none}.waves-effect.waves-light .waves-ripple{background-color:rgba(255,255,255,0.45)}.waves-effect.waves-red .waves-ripple{background-color:rgba(244,67,54,0.7)}.waves-effect.waves-yellow .waves-ripple{background-color:rgba(255,235,59,0.7)}.waves-effect.waves-orange .waves-ripple{background-color:rgba(255,152,0,0.7)}.waves-effect.waves-purple .waves-ripple{background-color:rgba(156,39,176,0.7)}.waves-effect.waves-green .waves-ripple{background-color:rgba(76,175,80,0.7)}.waves-effect.waves-teal .waves-ripple{background-color:rgba(0,150,136,0.7)}.waves-effect input[type="button"],.waves-effect input[type="reset"],.waves-effect input[type="submit"]{border:0;font-style:normal;font-size:inherit;text-transform:inherit;background:none}.waves-effect img{position:relative;z-index:-1}.waves-notransition{transition:none !important}.waves-circle{-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-mask-image:-webkit-radial-gradient(circle, #fff 100%, #000 100%)}.waves-input-wrapper{border-radius:0.2em;vertical-align:bottom}.waves-input-wrapper .waves-button-input{position:relative;top:0;left:0;z-index:1}.waves-circle{text-align:center;width:2.5em;height:2.5em;line-height:2.5em;border-radius:50%;-webkit-mask-image:none}.waves-block{display:block}.waves-effect .waves-ripple{z-index:-1}.modal{display:none;position:fixed;left:0;right:0;background-color:#fafafa;padding:0;max-height:70%;width:55%;margin:auto;overflow-y:auto;border-radius:2px;will-change:top, opacity}@media only screen and (max-width: 992px){.modal{width:80%}}.modal h1,.modal h2,.modal h3,.modal h4{margin-top:0}.modal .modal-content{padding:24px}.modal .modal-close{cursor:pointer}.modal .modal-footer{border-radius:0 0 2px 2px;background-color:#fafafa;padding:4px 6px;height:56px;width:100%}.modal .modal-footer .btn,.modal .modal-footer .btn-large,.modal .modal-footer .btn-flat{float:right;margin:6px 0}.modal-overlay{position:fixed;z-index:999;top:-100px;left:0;bottom:0;right:0;height:125%;width:100%;background:#000;display:none;will-change:opacity}.modal.modal-fixed-footer{padding:0;height:70%}.modal.modal-fixed-footer .modal-content{position:absolute;height:calc(100% - 56px);max-height:100%;width:100%;overflow-y:auto}.modal.modal-fixed-footer .modal-footer{border-top:1px solid rgba(0,0,0,0.1);position:absolute;bottom:0}.modal.bottom-sheet{top:auto;bottom:-100%;margin:0;width:100%;max-height:45%;border-radius:0;will-change:bottom, opacity}.collapsible{border-top:1px solid #ddd;border-right:1px solid #ddd;border-left:1px solid #ddd;margin:.5rem 0 1rem 0}.collapsible-header{display:block;cursor:pointer;min-height:3rem;line-height:3rem;padding:0 1rem;background-color:#fff;border-bottom:1px solid #ddd}.collapsible-header i{width:2rem;font-size:1.6rem;line-height:3rem;display:block;float:left;text-align:center;margin-right:1rem}.collapsible-body{display:none;border-bottom:1px solid #ddd;box-sizing:border-box;padding:2rem}.side-nav .collapsible,.side-nav.fixed .collapsible{border:none;box-shadow:none}.side-nav .collapsible li,.side-nav.fixed .collapsible li{padding:0}.side-nav .collapsible-header,.side-nav.fixed .collapsible-header{background-color:transparent;border:none;line-height:inherit;height:inherit;padding:0 16px}.side-nav .collapsible-header:hover,.side-nav.fixed .collapsible-header:hover{background-color:rgba(0,0,0,0.05)}.side-nav .collapsible-header i,.side-nav.fixed .collapsible-header i{line-height:inherit}.side-nav .collapsible-body,.side-nav.fixed .collapsible-body{border:0;background-color:#fff}.side-nav .collapsible-body li a,.side-nav.fixed .collapsible-body li a{padding:0 23.5px 0 31px}.collapsible.popout{border:none;box-shadow:none}.collapsible.popout>li{box-shadow:0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12);margin:0 24px;transition:margin 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94)}.collapsible.popout>li.active{box-shadow:0 5px 11px 0 rgba(0,0,0,0.18),0 4px 15px 0 rgba(0,0,0,0.15);margin:16px 0}.chip{display:inline-block;height:32px;font-size:13px;font-weight:500;color:rgba(0,0,0,0.6);line-height:32px;padding:0 12px;border-radius:16px;background-color:#e4e4e4;margin-bottom:5px;margin-right:5px}.chip>img{float:left;margin:0 8px 0 -12px;height:32px;width:32px;border-radius:50%}.chip .close{cursor:pointer;float:right;font-size:16px;line-height:32px;padding-left:8px}.chips{border:none;border-bottom:1px solid #9e9e9e;box-shadow:none;margin:0 0 20px 0;min-height:45px;outline:none;transition:all .3s}.chips.focus{border-bottom:1px solid #26a69a;box-shadow:0 1px 0 0 #26a69a}.chips:hover{cursor:text}.chips .chip.selected{background-color:#26a69a;color:#fff}.chips .input{background:none;border:0;color:rgba(0,0,0,0.6);display:inline-block;font-size:1rem;height:3rem;line-height:32px;outline:0;margin:0;padding:0 !important;width:120px !important}.chips .input:focus{border:0 !important;box-shadow:none !important}.chips .autocomplete-content{margin-top:0}.prefix ~ .chips{margin-left:3rem;width:92%;width:calc(100% - 3rem)}.chips:empty ~ label{font-size:0.8rem;-webkit-transform:translateY(-140%);transform:translateY(-140%)}.materialboxed{display:block;cursor:-webkit-zoom-in;cursor:zoom-in;position:relative;transition:opacity .4s;-webkit-backface-visibility:hidden}.materialboxed:hover:not(.active){opacity:.8}.materialboxed.active{cursor:-webkit-zoom-out;cursor:zoom-out}#materialbox-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background-color:#292929;z-index:1000;will-change:opacity}.materialbox-caption{position:fixed;display:none;color:#fff;line-height:50px;bottom:0;left:0;width:100%;text-align:center;padding:0% 15%;height:50px;z-index:1000;-webkit-font-smoothing:antialiased}select:focus{outline:1px solid #c9f3ef}button:focus{outline:none;background-color:#2ab7a9}label{font-size:.8rem;color:#9e9e9e}::-webkit-input-placeholder{color:#d1d1d1}:-moz-placeholder{color:#d1d1d1}::-moz-placeholder{color:#d1d1d1}:-ms-input-placeholder{color:#d1d1d1}input:not([type]),input[type=text],input[type=password],input[type=email],input[type=url],input[type=time],input[type=date],input[type=datetime],input[type=datetime-local],input[type=tel],input[type=number],input[type=search],textarea.materialize-textarea{background-color:transparent;border:none;border-bottom:1px solid #9e9e9e;border-radius:0;outline:none;height:3rem;width:100%;font-size:1rem;margin:0 0 20px 0;padding:0;box-shadow:none;box-sizing:content-box;transition:all 0.3s}input:not([type]):disabled,input:not([type])[readonly="readonly"],input[type=text]:disabled,input[type=text][readonly="readonly"],input[type=password]:disabled,input[type=password][readonly="readonly"],input[type=email]:disabled,input[type=email][readonly="readonly"],input[type=url]:disabled,input[type=url][readonly="readonly"],input[type=time]:disabled,input[type=time][readonly="readonly"],input[type=date]:disabled,input[type=date][readonly="readonly"],input[type=datetime]:disabled,input[type=datetime][readonly="readonly"],input[type=datetime-local]:disabled,input[type=datetime-local][readonly="readonly"],input[type=tel]:disabled,input[type=tel][readonly="readonly"],input[type=number]:disabled,input[type=number][readonly="readonly"],input[type=search]:disabled,input[type=search][readonly="readonly"],textarea.materialize-textarea:disabled,textarea.materialize-textarea[readonly="readonly"]{color:rgba(0,0,0,0.26);border-bottom:1px dotted rgba(0,0,0,0.26)}input:not([type]):disabled+label,input:not([type])[readonly="readonly"]+label,input[type=text]:disabled+label,input[type=text][readonly="readonly"]+label,input[type=password]:disabled+label,input[type=password][readonly="readonly"]+label,input[type=email]:disabled+label,input[type=email][readonly="readonly"]+label,input[type=url]:disabled+label,input[type=url][readonly="readonly"]+label,input[type=time]:disabled+label,input[type=time][readonly="readonly"]+label,input[type=date]:disabled+label,input[type=date][readonly="readonly"]+label,input[type=datetime]:disabled+label,input[type=datetime][readonly="readonly"]+label,input[type=datetime-local]:disabled+label,input[type=datetime-local][readonly="readonly"]+label,input[type=tel]:disabled+label,input[type=tel][readonly="readonly"]+label,input[type=number]:disabled+label,input[type=number][readonly="readonly"]+label,input[type=search]:disabled+label,input[type=search][readonly="readonly"]+label,textarea.materialize-textarea:disabled+label,textarea.materialize-textarea[readonly="readonly"]+label{color:rgba(0,0,0,0.26)}input:not([type]):focus:not([readonly]),input[type=text]:focus:not([readonly]),input[type=password]:focus:not([readonly]),input[type=email]:focus:not([readonly]),input[type=url]:focus:not([readonly]),input[type=time]:focus:not([readonly]),input[type=date]:focus:not([readonly]),input[type=datetime]:focus:not([readonly]),input[type=datetime-local]:focus:not([readonly]),input[type=tel]:focus:not([readonly]),input[type=number]:focus:not([readonly]),input[type=search]:focus:not([readonly]),textarea.materialize-textarea:focus:not([readonly]){border-bottom:1px solid #26a69a;box-shadow:0 1px 0 0 #26a69a}input:not([type]):focus:not([readonly])+label,input[type=text]:focus:not([readonly])+label,input[type=password]:focus:not([readonly])+label,input[type=email]:focus:not([readonly])+label,input[type=url]:focus:not([readonly])+label,input[type=time]:focus:not([readonly])+label,input[type=date]:focus:not([readonly])+label,input[type=datetime]:focus:not([readonly])+label,input[type=datetime-local]:focus:not([readonly])+label,input[type=tel]:focus:not([readonly])+label,input[type=number]:focus:not([readonly])+label,input[type=search]:focus:not([readonly])+label,textarea.materialize-textarea:focus:not([readonly])+label{color:#26a69a}input:not([type]).valid,input:not([type]):focus.valid,input[type=text].valid,input[type=text]:focus.valid,input[type=password].valid,input[type=password]:focus.valid,input[type=email].valid,input[type=email]:focus.valid,input[type=url].valid,input[type=url]:focus.valid,input[type=time].valid,input[type=time]:focus.valid,input[type=date].valid,input[type=date]:focus.valid,input[type=datetime].valid,input[type=datetime]:focus.valid,input[type=datetime-local].valid,input[type=datetime-local]:focus.valid,input[type=tel].valid,input[type=tel]:focus.valid,input[type=number].valid,input[type=number]:focus.valid,input[type=search].valid,input[type=search]:focus.valid,textarea.materialize-textarea.valid,textarea.materialize-textarea:focus.valid{border-bottom:1px solid #4CAF50;box-shadow:0 1px 0 0 #4CAF50}input:not([type]).valid+label:after,input:not([type]):focus.valid+label:after,input[type=text].valid+label:after,input[type=text]:focus.valid+label:after,input[type=password].valid+label:after,input[type=password]:focus.valid+label:after,input[type=email].valid+label:after,input[type=email]:focus.valid+label:after,input[type=url].valid+label:after,input[type=url]:focus.valid+label:after,input[type=time].valid+label:after,input[type=time]:focus.valid+label:after,input[type=date].valid+label:after,input[type=date]:focus.valid+label:after,input[type=datetime].valid+label:after,input[type=datetime]:focus.valid+label:after,input[type=datetime-local].valid+label:after,input[type=datetime-local]:focus.valid+label:after,input[type=tel].valid+label:after,input[type=tel]:focus.valid+label:after,input[type=number].valid+label:after,input[type=number]:focus.valid+label:after,input[type=search].valid+label:after,input[type=search]:focus.valid+label:after,textarea.materialize-textarea.valid+label:after,textarea.materialize-textarea:focus.valid+label:after{content:attr(data-success);color:#4CAF50;opacity:1}input:not([type]).invalid,input:not([type]):focus.invalid,input[type=text].invalid,input[type=text]:focus.invalid,input[type=password].invalid,input[type=password]:focus.invalid,input[type=email].invalid,input[type=email]:focus.invalid,input[type=url].invalid,input[type=url]:focus.invalid,input[type=time].invalid,input[type=time]:focus.invalid,input[type=date].invalid,input[type=date]:focus.invalid,input[type=datetime].invalid,input[type=datetime]:focus.invalid,input[type=datetime-local].invalid,input[type=datetime-local]:focus.invalid,input[type=tel].invalid,input[type=tel]:focus.invalid,input[type=number].invalid,input[type=number]:focus.invalid,input[type=search].invalid,input[type=search]:focus.invalid,textarea.materialize-textarea.invalid,textarea.materialize-textarea:focus.invalid{border-bottom:1px solid #F44336;box-shadow:0 1px 0 0 #F44336}input:not([type]).invalid+label:after,input:not([type]):focus.invalid+label:after,input[type=text].invalid+label:after,input[type=text]:focus.invalid+label:after,input[type=password].invalid+label:after,input[type=password]:focus.invalid+label:after,input[type=email].invalid+label:after,input[type=email]:focus.invalid+label:after,input[type=url].invalid+label:after,input[type=url]:focus.invalid+label:after,input[type=time].invalid+label:after,input[type=time]:focus.invalid+label:after,input[type=date].invalid+label:after,input[type=date]:focus.invalid+label:after,input[type=datetime].invalid+label:after,input[type=datetime]:focus.invalid+label:after,input[type=datetime-local].invalid+label:after,input[type=datetime-local]:focus.invalid+label:after,input[type=tel].invalid+label:after,input[type=tel]:focus.invalid+label:after,input[type=number].invalid+label:after,input[type=number]:focus.invalid+label:after,input[type=search].invalid+label:after,input[type=search]:focus.invalid+label:after,textarea.materialize-textarea.invalid+label:after,textarea.materialize-textarea:focus.invalid+label:after{content:attr(data-error);color:#F44336;opacity:1}input:not([type]).validate+label,input[type=text].validate+label,input[type=password].validate+label,input[type=email].validate+label,input[type=url].validate+label,input[type=time].validate+label,input[type=date].validate+label,input[type=datetime].validate+label,input[type=datetime-local].validate+label,input[type=tel].validate+label,input[type=number].validate+label,input[type=search].validate+label,textarea.materialize-textarea.validate+label{width:100%;pointer-events:none}input:not([type])+label:after,input[type=text]+label:after,input[type=password]+label:after,input[type=email]+label:after,input[type=url]+label:after,input[type=time]+label:after,input[type=date]+label:after,input[type=datetime]+label:after,input[type=datetime-local]+label:after,input[type=tel]+label:after,input[type=number]+label:after,input[type=search]+label:after,textarea.materialize-textarea+label:after{display:block;content:"";position:absolute;top:60px;opacity:0;transition:.2s opacity ease-out, .2s color ease-out}.input-field{position:relative;margin-top:1rem}.input-field.inline{display:inline-block;vertical-align:middle;margin-left:5px}.input-field.inline input,.input-field.inline .select-dropdown{margin-bottom:1rem}.input-field.col label{left:.75rem}.input-field.col .prefix ~ label,.input-field.col .prefix ~ .validate ~ label{width:calc(100% - 3rem - 1.5rem)}.input-field label{color:#9e9e9e;position:absolute;top:0.8rem;left:0;font-size:1rem;cursor:text;transition:.2s ease-out;text-align:initial}.input-field label:not(.label-icon).active{font-size:.8rem;-webkit-transform:translateY(-140%);transform:translateY(-140%)}.input-field .prefix{position:absolute;width:3rem;font-size:2rem;transition:color .2s}.input-field .prefix.active{color:#26a69a}.input-field .prefix ~ input,.input-field .prefix ~ textarea,.input-field .prefix ~ label,.input-field .prefix ~ .validate ~ label,.input-field .prefix ~ .autocomplete-content{margin-left:3rem;width:92%;width:calc(100% - 3rem)}.input-field .prefix ~ label{margin-left:3rem}@media only screen and (max-width: 992px){.input-field .prefix ~ input{width:86%;width:calc(100% - 3rem)}}@media only screen and (max-width: 600px){.input-field .prefix ~ input{width:80%;width:calc(100% - 3rem)}}.input-field input[type=search]{display:block;line-height:inherit;padding-left:4rem;width:calc(100% - 4rem)}.input-field input[type=search]:focus{background-color:#fff;border:0;box-shadow:none;color:#444}.input-field input[type=search]:focus+label i,.input-field input[type=search]:focus ~ .mdi-navigation-close,.input-field input[type=search]:focus ~ .material-icons{color:#444}.input-field input[type=search]+label{left:1rem}.input-field input[type=search] ~ .mdi-navigation-close,.input-field input[type=search] ~ .material-icons{position:absolute;top:0;right:1rem;color:transparent;cursor:pointer;font-size:2rem;transition:.3s color}textarea{width:100%;height:3rem;background-color:transparent}textarea.materialize-textarea{overflow-y:hidden;padding:.8rem 0 1.6rem 0;resize:none;min-height:3rem}.hiddendiv{display:none;white-space:pre-wrap;word-wrap:break-word;overflow-wrap:break-word;padding-top:1.2rem;position:absolute;top:0}.autocomplete-content{margin-top:-20px;display:block;opacity:1;position:static}.autocomplete-content li .highlight{color:#444}.autocomplete-content li img{height:40px;width:40px;margin:5px 15px}[type="radio"]:not(:checked),[type="radio"]:checked{position:absolute;left:-9999px;opacity:0}[type="radio"]:not(:checked)+label,[type="radio"]:checked+label{position:relative;padding-left:35px;cursor:pointer;display:inline-block;height:25px;line-height:25px;font-size:1rem;transition:.28s ease;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}[type="radio"]+label:before,[type="radio"]+label:after{content:'';position:absolute;left:0;top:0;margin:4px;width:16px;height:16px;z-index:0;transition:.28s ease}[type="radio"]:not(:checked)+label:before,[type="radio"]:not(:checked)+label:after,[type="radio"]:checked+label:before,[type="radio"]:checked+label:after,[type="radio"].with-gap:checked+label:before,[type="radio"].with-gap:checked+label:after{border-radius:50%}[type="radio"]:not(:checked)+label:before,[type="radio"]:not(:checked)+label:after{border:2px solid #5a5a5a}[type="radio"]:not(:checked)+label:after{-webkit-transform:scale(0);transform:scale(0)}[type="radio"]:checked+label:before{border:2px solid transparent}[type="radio"]:checked+label:after,[type="radio"].with-gap:checked+label:before,[type="radio"].with-gap:checked+label:after{border:2px solid #26a69a}[type="radio"]:checked+label:after,[type="radio"].with-gap:checked+label:after{background-color:#26a69a}[type="radio"]:checked+label:after{-webkit-transform:scale(1.02);transform:scale(1.02)}[type="radio"].with-gap:checked+label:after{-webkit-transform:scale(0.5);transform:scale(0.5)}[type="radio"].tabbed:focus+label:before{box-shadow:0 0 0 10px rgba(0,0,0,0.1)}[type="radio"].with-gap:disabled:checked+label:before{border:2px solid rgba(0,0,0,0.26)}[type="radio"].with-gap:disabled:checked+label:after{border:none;background-color:rgba(0,0,0,0.26)}[type="radio"]:disabled:not(:checked)+label:before,[type="radio"]:disabled:checked+label:before{background-color:transparent;border-color:rgba(0,0,0,0.26)}[type="radio"]:disabled+label{color:rgba(0,0,0,0.26)}[type="radio"]:disabled:not(:checked)+label:before{border-color:rgba(0,0,0,0.26)}[type="radio"]:disabled:checked+label:after{background-color:rgba(0,0,0,0.26);border-color:#BDBDBD}form p{margin-bottom:10px;text-align:left}form p:last-child{margin-bottom:0}[type="checkbox"]:not(:checked),[type="checkbox"]:checked{position:absolute;left:-9999px;opacity:0}[type="checkbox"]+label{position:relative;padding-left:35px;cursor:pointer;display:inline-block;height:25px;line-height:25px;font-size:1rem;-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none}[type="checkbox"]+label:before,[type="checkbox"]:not(.filled-in)+label:after{content:'';position:absolute;top:0;left:0;width:18px;height:18px;z-index:0;border:2px solid #5a5a5a;border-radius:1px;margin-top:2px;transition:.2s}[type="checkbox"]:not(.filled-in)+label:after{border:0;-webkit-transform:scale(0);transform:scale(0)}[type="checkbox"]:not(:checked):disabled+label:before{border:none;background-color:rgba(0,0,0,0.26)}[type="checkbox"].tabbed:focus+label:after{-webkit-transform:scale(1);transform:scale(1);border:0;border-radius:50%;box-shadow:0 0 0 10px rgba(0,0,0,0.1);background-color:rgba(0,0,0,0.1)}[type="checkbox"]:checked+label:before{top:-4px;left:-5px;width:12px;height:22px;border-top:2px solid transparent;border-left:2px solid transparent;border-right:2px solid #26a69a;border-bottom:2px solid #26a69a;-webkit-transform:rotate(40deg);transform:rotate(40deg);-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform-origin:100% 100%;transform-origin:100% 100%}[type="checkbox"]:checked:disabled+label:before{border-right:2px solid rgba(0,0,0,0.26);border-bottom:2px solid rgba(0,0,0,0.26)}[type="checkbox"]:indeterminate+label:before{top:-11px;left:-12px;width:10px;height:22px;border-top:none;border-left:none;border-right:2px solid #26a69a;border-bottom:none;-webkit-transform:rotate(90deg);transform:rotate(90deg);-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform-origin:100% 100%;transform-origin:100% 100%}[type="checkbox"]:indeterminate:disabled+label:before{border-right:2px solid rgba(0,0,0,0.26);background-color:transparent}[type="checkbox"].filled-in+label:after{border-radius:2px}[type="checkbox"].filled-in+label:before,[type="checkbox"].filled-in+label:after{content:'';left:0;position:absolute;transition:border .25s, background-color .25s, width .20s .1s, height .20s .1s, top .20s .1s, left .20s .1s;z-index:1}[type="checkbox"].filled-in:not(:checked)+label:before{width:0;height:0;border:3px solid transparent;left:6px;top:10px;-webkit-transform:rotateZ(37deg);transform:rotateZ(37deg);-webkit-transform-origin:20% 40%;transform-origin:100% 100%}[type="checkbox"].filled-in:not(:checked)+label:after{height:20px;width:20px;background-color:transparent;border:2px solid #5a5a5a;top:0px;z-index:0}[type="checkbox"].filled-in:checked+label:before{top:0;left:1px;width:8px;height:13px;border-top:2px solid transparent;border-left:2px solid transparent;border-right:2px solid #fff;border-bottom:2px solid #fff;-webkit-transform:rotateZ(37deg);transform:rotateZ(37deg);-webkit-transform-origin:100% 100%;transform-origin:100% 100%}[type="checkbox"].filled-in:checked+label:after{top:0;width:20px;height:20px;border:2px solid #26a69a;background-color:#26a69a;z-index:0}[type="checkbox"].filled-in.tabbed:focus+label:after{border-radius:2px;border-color:#5a5a5a;background-color:rgba(0,0,0,0.1)}[type="checkbox"].filled-in.tabbed:checked:focus+label:after{border-radius:2px;background-color:#26a69a;border-color:#26a69a}[type="checkbox"].filled-in:disabled:not(:checked)+label:before{background-color:transparent;border:2px solid transparent}[type="checkbox"].filled-in:disabled:not(:checked)+label:after{border-color:transparent;background-color:#BDBDBD}[type="checkbox"].filled-in:disabled:checked+label:before{background-color:transparent}[type="checkbox"].filled-in:disabled:checked+label:after{background-color:#BDBDBD;border-color:#BDBDBD}.switch,.switch *{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none}.switch label{cursor:pointer}.switch label input[type=checkbox]{opacity:0;width:0;height:0}.switch label input[type=checkbox]:checked+.lever{background-color:#84c7c1}.switch label input[type=checkbox]:checked+.lever:after{background-color:#26a69a;left:24px}.switch label .lever{content:"";display:inline-block;position:relative;width:40px;height:15px;background-color:#818181;border-radius:15px;margin-right:10px;transition:background 0.3s ease;vertical-align:middle;margin:0 16px}.switch label .lever:after{content:"";position:absolute;display:inline-block;width:21px;height:21px;background-color:#F1F1F1;border-radius:21px;box-shadow:0 1px 3px 1px rgba(0,0,0,0.4);left:-5px;top:-3px;transition:left 0.3s ease, background .3s ease, box-shadow 0.1s ease}input[type=checkbox]:checked:not(:disabled) ~ .lever:active::after,input[type=checkbox]:checked:not(:disabled).tabbed:focus ~ .lever::after{box-shadow:0 1px 3px 1px rgba(0,0,0,0.4),0 0 0 15px rgba(38,166,154,0.1)}input[type=checkbox]:not(:disabled) ~ .lever:active:after,input[type=checkbox]:not(:disabled).tabbed:focus ~ .lever::after{box-shadow:0 1px 3px 1px rgba(0,0,0,0.4),0 0 0 15px rgba(0,0,0,0.08)}.switch input[type=checkbox][disabled]+.lever{cursor:default}.switch label input[type=checkbox][disabled]+.lever:after,.switch label input[type=checkbox][disabled]:checked+.lever:after{background-color:#BDBDBD}select{display:none}select.browser-default{display:block}select{background-color:rgba(255,255,255,0.9);width:100%;padding:5px;border:1px solid #f2f2f2;border-radius:2px;height:3rem}.select-label{position:absolute}.select-wrapper{position:relative}.select-wrapper input.select-dropdown{position:relative;cursor:pointer;background-color:transparent;border:none;border-bottom:1px solid #9e9e9e;outline:none;height:3rem;line-height:3rem;width:100%;font-size:1rem;margin:0 0 20px 0;padding:0;display:block}.select-wrapper span.caret{color:initial;position:absolute;right:0;top:0;bottom:0;height:10px;margin:auto 0;font-size:10px;line-height:10px}.select-wrapper span.caret.disabled{color:rgba(0,0,0,0.26)}.select-wrapper+label{position:absolute;top:-14px;font-size:.8rem}select:disabled{color:rgba(0,0,0,0.3)}.select-wrapper input.select-dropdown:disabled{color:rgba(0,0,0,0.3);cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;border-bottom:1px solid rgba(0,0,0,0.3)}.select-wrapper i{color:rgba(0,0,0,0.3)}.select-dropdown li.disabled,.select-dropdown li.disabled>span,.select-dropdown li.optgroup{color:rgba(0,0,0,0.3);background-color:transparent}.prefix ~ .select-wrapper{margin-left:3rem;width:92%;width:calc(100% - 3rem)}.prefix ~ label{margin-left:3rem}.select-dropdown li img{height:40px;width:40px;margin:5px 15px;float:right}.select-dropdown li.optgroup{border-top:1px solid #eee}.select-dropdown li.optgroup.selected>span{color:rgba(0,0,0,0.7)}.select-dropdown li.optgroup>span{color:rgba(0,0,0,0.4)}.select-dropdown li.optgroup ~ li.optgroup-option{padding-left:1rem}.file-field{position:relative}.file-field .file-path-wrapper{overflow:hidden;padding-left:10px}.file-field input.file-path{width:100%}.file-field .btn,.file-field .btn-large{float:left;height:3rem;line-height:3rem}.file-field span{cursor:pointer}.file-field input[type=file]{position:absolute;top:0;right:0;left:0;bottom:0;width:100%;margin:0;padding:0;font-size:20px;cursor:pointer;opacity:0;filter:alpha(opacity=0)}.range-field{position:relative}input[type=range],input[type=range]+.thumb{cursor:pointer}input[type=range]{position:relative;background-color:transparent;border:none;outline:none;width:100%;margin:15px 0;padding:0}input[type=range]:focus{outline:none}input[type=range]+.thumb{position:absolute;top:10px;left:0;border:none;height:0;width:0;border-radius:50%;background-color:#26a69a;margin-left:7px;-webkit-transform-origin:50% 50%;transform-origin:50% 50%;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}input[type=range]+.thumb .value{display:block;width:30px;text-align:center;color:#26a69a;font-size:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}input[type=range]+.thumb.active{border-radius:50% 50% 50% 0}input[type=range]+.thumb.active .value{color:#fff;margin-left:-1px;margin-top:8px;font-size:10px}input[type=range]{-webkit-appearance:none}input[type=range]::-webkit-slider-runnable-track{height:3px;background:#c2c0c2;border:none}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;border:none;height:14px;width:14px;border-radius:50%;background-color:#26a69a;-webkit-transform-origin:50% 50%;transform-origin:50% 50%;margin:-5px 0 0 0;transition:.3s}input[type=range]:focus::-webkit-slider-runnable-track{background:#ccc}input[type=range]{border:1px solid white}input[type=range]::-moz-range-track{height:3px;background:#ddd;border:none}input[type=range]::-moz-range-thumb{border:none;height:14px;width:14px;border-radius:50%;background:#26a69a;margin-top:-5px}input[type=range]:-moz-focusring{outline:1px solid #fff;outline-offset:-1px}input[type=range]:focus::-moz-range-track{background:#ccc}input[type=range]::-ms-track{height:3px;background:transparent;border-color:transparent;border-width:6px 0;color:transparent}input[type=range]::-ms-fill-lower{background:#777}input[type=range]::-ms-fill-upper{background:#ddd}input[type=range]::-ms-thumb{border:none;height:14px;width:14px;border-radius:50%;background:#26a69a}input[type=range]:focus::-ms-fill-lower{background:#888}input[type=range]:focus::-ms-fill-upper{background:#ccc}.table-of-contents.fixed{position:fixed}.table-of-contents li{padding:2px 0}.table-of-contents a{display:inline-block;font-weight:300;color:#757575;padding-left:20px;height:1.5rem;line-height:1.5rem;letter-spacing:.4;display:inline-block}.table-of-contents a:hover{color:#a8a8a8;padding-left:19px;border-left:1px solid #ee6e73}.table-of-contents a.active{font-weight:500;padding-left:18px;border-left:2px solid #ee6e73}.side-nav{position:fixed;width:300px;left:0;top:0;margin:0;-webkit-transform:translateX(-100%);transform:translateX(-100%);height:100%;height:calc(100% + 60px);height:-moz-calc(100%);padding-bottom:60px;background-color:#fff;z-index:999;overflow-y:auto;will-change:transform;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform:translateX(-105%);transform:translateX(-105%)}.side-nav.right-aligned{right:0;-webkit-transform:translateX(105%);transform:translateX(105%);left:auto;-webkit-transform:translateX(100%);transform:translateX(100%)}.side-nav .collapsible{margin:0}.side-nav li{float:none;line-height:48px}.side-nav li.active{background-color:rgba(0,0,0,0.05)}.side-nav li>a{color:rgba(0,0,0,0.87);display:block;font-size:14px;font-weight:500;height:48px;line-height:48px;padding:0 32px}.side-nav li>a:hover{background-color:rgba(0,0,0,0.05)}.side-nav li>a.btn,.side-nav li>a.btn-large,.side-nav li>a.btn-large,.side-nav li>a.btn-flat,.side-nav li>a.btn-floating{margin:10px 15px}.side-nav li>a.btn,.side-nav li>a.btn-large,.side-nav li>a.btn-large,.side-nav li>a.btn-floating{color:#fff}.side-nav li>a.btn-flat{color:#343434}.side-nav li>a.btn:hover,.side-nav li>a.btn-large:hover,.side-nav li>a.btn-large:hover{background-color:#2bbbad}.side-nav li>a.btn-floating:hover{background-color:#26a69a}.side-nav li>a>i,.side-nav li>a>[class^="mdi-"],.side-nav li>a li>a>[class*="mdi-"],.side-nav li>a>i.material-icons{float:left;height:48px;line-height:48px;margin:0 32px 0 0;width:24px;color:rgba(0,0,0,0.54)}.side-nav .divider{margin:8px 0 0 0}.side-nav .subheader{cursor:initial;pointer-events:none;color:rgba(0,0,0,0.54);font-size:14px;font-weight:500;line-height:48px}.side-nav .subheader:hover{background-color:transparent}.side-nav .userView{position:relative;padding:32px 32px 0;margin-bottom:8px}.side-nav .userView>a{height:auto;padding:0}.side-nav .userView>a:hover{background-color:transparent}.side-nav .userView .background{overflow:hidden;position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1}.side-nav .userView .circle,.side-nav .userView .name,.side-nav .userView .email{display:block}.side-nav .userView .circle{height:64px;width:64px}.side-nav .userView .name,.side-nav .userView .email{font-size:14px;line-height:24px}.side-nav .userView .name{margin-top:16px;font-weight:500}.side-nav .userView .email{padding-bottom:16px;font-weight:400}.drag-target{height:100%;width:10px;position:fixed;top:0;z-index:998}.side-nav.fixed{left:0;-webkit-transform:translateX(0);transform:translateX(0);position:fixed}.side-nav.fixed.right-aligned{right:0;left:auto}@media only screen and (max-width: 992px){.side-nav.fixed{-webkit-transform:translateX(-105%);transform:translateX(-105%)}.side-nav.fixed.right-aligned{-webkit-transform:translateX(105%);transform:translateX(105%)}.side-nav a{padding:0 16px}.side-nav .userView{padding:16px 16px 0}}.side-nav .collapsible-body>ul:not(.collapsible)>li.active,.side-nav.fixed .collapsible-body>ul:not(.collapsible)>li.active{background-color:#ee6e73}.side-nav .collapsible-body>ul:not(.collapsible)>li.active a,.side-nav.fixed .collapsible-body>ul:not(.collapsible)>li.active a{color:#fff}.side-nav .collapsible-body{padding:0}#sidenav-overlay{position:fixed;top:0;left:0;right:0;height:120vh;background-color:rgba(0,0,0,0.5);z-index:997;will-change:opacity}.preloader-wrapper{display:inline-block;position:relative;width:50px;height:50px}.preloader-wrapper.small{width:36px;height:36px}.preloader-wrapper.big{width:64px;height:64px}.preloader-wrapper.active{-webkit-animation:container-rotate 1568ms linear infinite;animation:container-rotate 1568ms linear infinite}@-webkit-keyframes container-rotate{to{-webkit-transform:rotate(360deg)}}@keyframes container-rotate{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-layer{position:absolute;width:100%;height:100%;opacity:0;border-color:#26a69a}.spinner-blue,.spinner-blue-only{border-color:#4285f4}.spinner-red,.spinner-red-only{border-color:#db4437}.spinner-yellow,.spinner-yellow-only{border-color:#f4b400}.spinner-green,.spinner-green-only{border-color:#0f9d58}.active .spinner-layer.spinner-blue{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,blue-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,blue-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-red{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,red-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,red-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-yellow{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,yellow-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,yellow-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-green{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,green-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,green-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer,.active .spinner-layer.spinner-blue-only,.active .spinner-layer.spinner-red-only,.active .spinner-layer.spinner-yellow-only,.active .spinner-layer.spinner-green-only{opacity:1;-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}@-webkit-keyframes fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg)}}@keyframes fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg);transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg);transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg);transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg);transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg);transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg);transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg);transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg);transform:rotate(1080deg)}}@-webkit-keyframes blue-fade-in-out{from{opacity:1}25%{opacity:1}26%{opacity:0}89%{opacity:0}90%{opacity:1}100%{opacity:1}}@keyframes blue-fade-in-out{from{opacity:1}25%{opacity:1}26%{opacity:0}89%{opacity:0}90%{opacity:1}100%{opacity:1}}@-webkit-keyframes red-fade-in-out{from{opacity:0}15%{opacity:0}25%{opacity:1}50%{opacity:1}51%{opacity:0}}@keyframes red-fade-in-out{from{opacity:0}15%{opacity:0}25%{opacity:1}50%{opacity:1}51%{opacity:0}}@-webkit-keyframes yellow-fade-in-out{from{opacity:0}40%{opacity:0}50%{opacity:1}75%{opacity:1}76%{opacity:0}}@keyframes yellow-fade-in-out{from{opacity:0}40%{opacity:0}50%{opacity:1}75%{opacity:1}76%{opacity:0}}@-webkit-keyframes green-fade-in-out{from{opacity:0}65%{opacity:0}75%{opacity:1}90%{opacity:1}100%{opacity:0}}@keyframes green-fade-in-out{from{opacity:0}65%{opacity:0}75%{opacity:1}90%{opacity:1}100%{opacity:0}}.gap-patch{position:absolute;top:0;left:45%;width:10%;height:100%;overflow:hidden;border-color:inherit}.gap-patch .circle{width:1000%;left:-450%}.circle-clipper{display:inline-block;position:relative;width:50%;height:100%;overflow:hidden;border-color:inherit}.circle-clipper .circle{width:200%;height:100%;border-width:3px;border-style:solid;border-color:inherit;border-bottom-color:transparent !important;border-radius:50%;-webkit-animation:none;animation:none;position:absolute;top:0;right:0;bottom:0}.circle-clipper.left .circle{left:0;border-right-color:transparent !important;-webkit-transform:rotate(129deg);transform:rotate(129deg)}.circle-clipper.right .circle{left:-100%;border-left-color:transparent !important;-webkit-transform:rotate(-129deg);transform:rotate(-129deg)}.active .circle-clipper.left .circle{-webkit-animation:left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .circle-clipper.right .circle{-webkit-animation:right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}@-webkit-keyframes left-spin{from{-webkit-transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg)}}@keyframes left-spin{from{-webkit-transform:rotate(130deg);transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg);transform:rotate(130deg)}}@-webkit-keyframes right-spin{from{-webkit-transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg)}}@keyframes right-spin{from{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg);transform:rotate(-130deg)}}#spinnerContainer.cooldown{-webkit-animation:container-rotate 1568ms linear infinite,fade-out 400ms cubic-bezier(0.4, 0, 0.2, 1);animation:container-rotate 1568ms linear infinite,fade-out 400ms cubic-bezier(0.4, 0, 0.2, 1)}@-webkit-keyframes fade-out{from{opacity:1}to{opacity:0}}@keyframes fade-out{from{opacity:1}to{opacity:0}}.slider{position:relative;height:400px;width:100%}.slider.fullscreen{height:100%;width:100%;position:absolute;top:0;left:0;right:0;bottom:0}.slider.fullscreen ul.slides{height:100%}.slider.fullscreen ul.indicators{z-index:2;bottom:30px}.slider .slides{background-color:#9e9e9e;margin:0;height:400px}.slider .slides li{opacity:0;position:absolute;top:0;left:0;z-index:1;width:100%;height:inherit;overflow:hidden}.slider .slides li img{height:100%;width:100%;background-size:cover;background-position:center}.slider .slides li .caption{color:#fff;position:absolute;top:15%;left:15%;width:70%;opacity:0}.slider .slides li .caption p{color:#e0e0e0}.slider .slides li.active{z-index:2}.slider .indicators{position:absolute;text-align:center;left:0;right:0;bottom:0;margin:0}.slider .indicators .indicator-item{display:inline-block;position:relative;cursor:pointer;height:16px;width:16px;margin:0 12px;background-color:#e0e0e0;transition:background-color .3s;border-radius:50%}.slider .indicators .indicator-item.active{background-color:#4CAF50}.carousel{overflow:hidden;position:relative;width:100%;height:400px;-webkit-perspective:500px;perspective:500px;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transform-origin:0% 50%;transform-origin:0% 50%}.carousel.carousel-slider{top:0;left:0;height:0}.carousel.carousel-slider .carousel-fixed-item{position:absolute;left:0;right:0;bottom:20px;z-index:1}.carousel.carousel-slider .carousel-fixed-item.with-indicators{bottom:68px}.carousel.carousel-slider .carousel-item{width:100%;height:100%;min-height:400px;position:absolute;top:0;left:0}.carousel.carousel-slider .carousel-item h2{font-size:24px;font-weight:500;line-height:32px}.carousel.carousel-slider .carousel-item p{font-size:15px}.carousel .carousel-item{display:none;width:200px;height:200px;position:absolute;top:0;left:0}.carousel .carousel-item>img{width:100%}.carousel .indicators{position:absolute;text-align:center;left:0;right:0;bottom:0;margin:0}.carousel .indicators .indicator-item{display:inline-block;position:relative;cursor:pointer;height:8px;width:8px;margin:24px 4px;background-color:rgba(255,255,255,0.5);transition:background-color .3s;border-radius:50%}.carousel .indicators .indicator-item.active{background-color:#fff}.carousel.scrolling .carousel-item .materialboxed,.carousel .carousel-item:not(.active) .materialboxed{pointer-events:none}.tap-target-wrapper{width:800px;height:800px;position:fixed;z-index:1000;visibility:hidden;transition:visibility 0s .3s}.tap-target-wrapper.open{visibility:visible;transition:visibility 0s}.tap-target-wrapper.open .tap-target{-webkit-transform:scale(1);transform:scale(1);opacity:.95;transition:opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1),-webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1);transition:transform 0.3s cubic-bezier(0.42, 0, 0.58, 1),opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1);transition:transform 0.3s cubic-bezier(0.42, 0, 0.58, 1),opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1),-webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1)}.tap-target-wrapper.open .tap-target-wave::before{-webkit-transform:scale(1);transform:scale(1)}.tap-target-wrapper.open .tap-target-wave::after{visibility:visible;-webkit-animation:pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite;animation:pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite;transition:opacity .3s, visibility 0s 1s, -webkit-transform .3s;transition:opacity .3s, transform .3s, visibility 0s 1s;transition:opacity .3s, transform .3s, visibility 0s 1s, -webkit-transform .3s}.tap-target{position:absolute;font-size:1rem;border-radius:50%;background-color:#ee6e73;box-shadow:0 20px 20px 0 rgba(0,0,0,0.14),0 10px 50px 0 rgba(0,0,0,0.12),0 30px 10px -20px rgba(0,0,0,0.2);width:100%;height:100%;opacity:0;-webkit-transform:scale(0);transform:scale(0);transition:opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1),-webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1);transition:transform 0.3s cubic-bezier(0.42, 0, 0.58, 1),opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1);transition:transform 0.3s cubic-bezier(0.42, 0, 0.58, 1),opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1),-webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1)}.tap-target-content{position:relative;display:table-cell}.tap-target-wave{position:absolute;border-radius:50%;z-index:10001}.tap-target-wave::before,.tap-target-wave::after{content:'';display:block;position:absolute;width:100%;height:100%;border-radius:50%;background-color:#ffffff}.tap-target-wave::before{-webkit-transform:scale(0);transform:scale(0);transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s, -webkit-transform .3s}.tap-target-wave::after{visibility:hidden;transition:opacity .3s, visibility 0s, -webkit-transform .3s;transition:opacity .3s, transform .3s, visibility 0s;transition:opacity .3s, transform .3s, visibility 0s, -webkit-transform .3s;z-index:-1}.tap-target-origin{top:50%;left:50%;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);z-index:10002;position:absolute !important}.tap-target-origin:not(.btn):not(.btn-large),.tap-target-origin:not(.btn):not(.btn-large):hover{background:none}@media only screen and (max-width: 600px){.tap-target,.tap-target-wrapper{width:600px;height:600px}}.pulse{overflow:initial;position:relative}.pulse::before{content:'';display:block;position:absolute;width:100%;height:100%;top:0;left:0;background-color:inherit;border-radius:inherit;transition:opacity .3s, -webkit-transform .3s;transition:opacity .3s, transform .3s;transition:opacity .3s, transform .3s, -webkit-transform .3s;-webkit-animation:pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite;animation:pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite;z-index:-1}@-webkit-keyframes pulse-animation{0%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}50%{opacity:0;-webkit-transform:scale(1.5);transform:scale(1.5)}100%{opacity:0;-webkit-transform:scale(1.5);transform:scale(1.5)}}@keyframes pulse-animation{0%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}50%{opacity:0;-webkit-transform:scale(1.5);transform:scale(1.5)}100%{opacity:0;-webkit-transform:scale(1.5);transform:scale(1.5)}}.picker{font-size:16px;text-align:left;line-height:1.2;color:#000000;position:absolute;z-index:10000;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.picker__input{cursor:default}.picker__input.picker__input--active{border-color:#0089ec}.picker__holder{width:100%;overflow-y:auto;-webkit-overflow-scrolling:touch}/*!
14
+ * Default mobile-first, responsive styling for pickadate.js
15
+ * Demo: http://amsul.github.io/pickadate.js
16
+ */.picker__holder,.picker__frame{bottom:0;left:0;right:0;top:100%}.picker__holder{position:fixed;transition:background 0.15s ease-out, top 0s 0.15s;-webkit-backface-visibility:hidden}.picker__frame{position:absolute;margin:0 auto;min-width:256px;width:300px;max-height:350px;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";filter:alpha(opacity=0);-moz-opacity:0;opacity:0;transition:all 0.15s ease-out}@media (min-height: 28.875em){.picker__frame{overflow:visible;top:auto;bottom:-100%;max-height:80%}}@media (min-height: 40.125em){.picker__frame{margin-bottom:7.5%}}.picker__wrap{display:table;width:100%;height:100%}@media (min-height: 28.875em){.picker__wrap{display:block}}.picker__box{background:#ffffff;display:table-cell;vertical-align:middle}@media (min-height: 28.875em){.picker__box{display:block;border:1px solid #777777;border-top-color:#898989;border-bottom-width:0;border-radius:5px 5px 0 0;box-shadow:0 12px 36px 16px rgba(0,0,0,0.24)}}.picker--opened .picker__holder{top:0;background:transparent;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#1E000000,endColorstr=#1E000000)";zoom:1;background:rgba(0,0,0,0.32);transition:background 0.15s ease-out}.picker--opened .picker__frame{top:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";filter:alpha(opacity=100);-moz-opacity:1;opacity:1}@media (min-height: 35.875em){.picker--opened .picker__frame{top:10%;bottom:auto}}.picker__input.picker__input--active{border-color:#E3F2FD}.picker__frame{margin:0 auto;max-width:325px}@media (min-height: 38.875em){.picker--opened .picker__frame{top:10%;bottom:auto}}.picker__box{padding:0 1em}.picker__header{text-align:center;position:relative;margin-top:.75em}.picker__month,.picker__year{display:inline-block;margin-left:.25em;margin-right:.25em}.picker__select--month,.picker__select--year{height:2em;padding:0;margin-left:.25em;margin-right:.25em}.picker__select--month.browser-default{display:inline;background-color:#FFFFFF;width:40%}.picker__select--year.browser-default{display:inline;background-color:#FFFFFF;width:26%}.picker__select--month:focus,.picker__select--year:focus{border-color:rgba(0,0,0,0.05)}.picker__nav--prev,.picker__nav--next{position:absolute;padding:.5em 1.25em;width:1em;height:1em;box-sizing:content-box;top:-0.25em}.picker__nav--prev{left:-1em;padding-right:1.25em}.picker__nav--next{right:-1em;padding-left:1.25em}.picker__nav--disabled,.picker__nav--disabled:hover,.picker__nav--disabled:before,.picker__nav--disabled:before:hover{cursor:default;background:none;border-right-color:#f5f5f5;border-left-color:#f5f5f5}.picker__table{text-align:center;border-collapse:collapse;border-spacing:0;table-layout:fixed;font-size:1rem;width:100%;margin-top:.75em;margin-bottom:.5em}.picker__table th,.picker__table td{text-align:center}.picker__table td{margin:0;padding:0}.picker__weekday{width:14.285714286%;font-size:.75em;padding-bottom:.25em;color:#999999;font-weight:500}@media (min-height: 33.875em){.picker__weekday{padding-bottom:.5em}}.picker__day--today{position:relative;color:#595959;letter-spacing:-.3;padding:.75rem 0;font-weight:400;border:1px solid transparent}.picker__day--disabled:before{border-top-color:#aaaaaa}.picker__day--infocus:hover{cursor:pointer;color:#000;font-weight:500}.picker__day--outfocus{display:none;padding:.75rem 0;color:#fff}.picker__day--outfocus:hover{cursor:pointer;color:#dddddd;font-weight:500}.picker__day--highlighted:hover,.picker--focused .picker__day--highlighted{cursor:pointer}.picker__day--selected,.picker__day--selected:hover,.picker--focused .picker__day--selected{border-radius:50%;-webkit-transform:scale(0.75);transform:scale(0.75);background:#0089ec;color:#ffffff}.picker__day--disabled,.picker__day--disabled:hover,.picker--focused .picker__day--disabled{background:#f5f5f5;border-color:#f5f5f5;color:#dddddd;cursor:default}.picker__day--highlighted.picker__day--disabled,.picker__day--highlighted.picker__day--disabled:hover{background:#bbbbbb}.picker__footer{text-align:center;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.picker__button--today,.picker__button--clear,.picker__button--close{border:1px solid #ffffff;background:#ffffff;font-size:.8em;padding:.66em 0;font-weight:bold;width:33%;display:inline-block;vertical-align:bottom}.picker__button--today:hover,.picker__button--clear:hover,.picker__button--close:hover{cursor:pointer;color:#000000;background:#b1dcfb;border-bottom-color:#b1dcfb}.picker__button--today:focus,.picker__button--clear:focus,.picker__button--close:focus{background:#b1dcfb;border-color:rgba(0,0,0,0.05);outline:none}.picker__button--today:before,.picker__button--clear:before,.picker__button--close:before{position:relative;display:inline-block;height:0}.picker__button--today:before,.picker__button--clear:before{content:" ";margin-right:.45em}.picker__button--today:before{top:-0.05em;width:0;border-top:0.66em solid #0059bc;border-left:.66em solid transparent}.picker__button--clear:before{top:-0.25em;width:.66em;border-top:3px solid #ee2200}.picker__button--close:before{content:"\D7";top:-0.1em;vertical-align:top;font-size:1.1em;margin-right:.35em;color:#777777}.picker__button--today[disabled],.picker__button--today[disabled]:hover{background:#f5f5f5;border-color:#f5f5f5;color:#dddddd;cursor:default}.picker__button--today[disabled]:before{border-top-color:#aaaaaa}.picker__box{border-radius:2px;overflow:hidden}.picker__date-display{text-align:center;background-color:#26a69a;color:#fff;padding-bottom:15px;font-weight:300}.picker__nav--prev:hover,.picker__nav--next:hover{cursor:pointer;color:#000000;background:#a1ded8}.picker__weekday-display{background-color:#1f897f;padding:10px;font-weight:200;letter-spacing:.5;font-size:1rem;margin-bottom:15px}.picker__month-display{text-transform:uppercase;font-size:2rem}.picker__day-display{font-size:4.5rem;font-weight:400}.picker__year-display{font-size:1.8rem;color:rgba(255,255,255,0.4)}.picker__box{padding:0}.picker__calendar-container{padding:0 1rem}.picker__calendar-container thead{border:none}.picker__table{margin-top:0;margin-bottom:.5em}.picker__day--infocus{color:#595959;letter-spacing:-.3;padding:.75rem 0;font-weight:400;border:1px solid transparent}.picker__day.picker__day--today{color:#26a69a}.picker__day.picker__day--today.picker__day--selected{color:#fff}.picker__weekday{font-size:.9rem}.picker__day--selected,.picker__day--selected:hover,.picker--focused .picker__day--selected{border-radius:50%;-webkit-transform:scale(0.9);transform:scale(0.9);background-color:#26a69a;color:#ffffff}.picker__day--selected.picker__day--outfocus,.picker__day--selected:hover.picker__day--outfocus,.picker--focused .picker__day--selected.picker__day--outfocus{background-color:#a1ded8}.picker__footer{text-align:right;padding:5px 10px}.picker__close,.picker__today{font-size:1.1rem;padding:0 1rem;color:#26a69a}.picker__nav--prev:before,.picker__nav--next:before{content:" ";border-top:.5em solid transparent;border-bottom:.5em solid transparent;border-right:0.75em solid #676767;width:0;height:0;display:block;margin:0 auto}.picker__nav--next:before{border-right:0;border-left:0.75em solid #676767}button.picker__today:focus,button.picker__clear:focus,button.picker__close:focus{background-color:#a1ded8}.picker__list{list-style:none;padding:0.75em 0 4.2em;margin:0}.picker__list-item{border-bottom:1px solid #dddddd;border-top:1px solid #dddddd;margin-bottom:-1px;position:relative;background:#ffffff;padding:.75em 1.25em}@media (min-height: 46.75em){.picker__list-item{padding:.5em 1em}}.picker__list-item:hover{cursor:pointer;color:#000000;background:#b1dcfb;border-color:#0089ec;z-index:10}.picker__list-item--highlighted{border-color:#0089ec;z-index:10}.picker__list-item--highlighted:hover,.picker--focused .picker__list-item--highlighted{cursor:pointer;color:#000000;background:#b1dcfb}.picker__list-item--selected,.picker__list-item--selected:hover,.picker--focused .picker__list-item--selected{background:#0089ec;color:#ffffff;z-index:10}.picker__list-item--disabled,.picker__list-item--disabled:hover,.picker--focused .picker__list-item--disabled{background:#f5f5f5;border-color:#f5f5f5;color:#dddddd;cursor:default;border-color:#dddddd;z-index:auto}.picker--time .picker__button--clear{display:block;width:80%;margin:1em auto 0;padding:1em 1.25em;background:none;border:0;font-weight:500;font-size:.67em;text-align:center;text-transform:uppercase;color:#666}.picker--time .picker__button--clear:hover,.picker--time .picker__button--clear:focus{color:#000000;background:#b1dcfb;background:#ee2200;border-color:#ee2200;cursor:pointer;color:#ffffff;outline:none}.picker--time .picker__button--clear:before{top:-0.25em;color:#666;font-size:1.25em;font-weight:bold}.picker--time .picker__button--clear:hover:before,.picker--time .picker__button--clear:focus:before{color:#ffffff}.picker--time .picker__frame{min-width:256px;max-width:320px}.picker--time .picker__box{font-size:1em;background:#f2f2f2;padding:0}@media (min-height: 40.125em){.picker--time .picker__box{margin-bottom:5em}}
include/materialize/materialize.min.js ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Materialize v0.98.2 (http://materializecss.com)
3
+ * Copyright 2014-2015 Materialize
4
+ * MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE)
5
+ */
6
+ if("undefined"==typeof jQuery){var jQuery;jQuery="function"==typeof require?$=require("jquery"):$}jQuery.easing.jswing=jQuery.easing.swing,jQuery.extend(jQuery.easing,{def:"easeOutQuad",swing:function(a,b,c,d,e){return jQuery.easing[jQuery.easing.def](a,b,c,d,e)},easeInQuad:function(a,b,c,d,e){return d*(b/=e)*b+c},easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c},easeInOutQuad:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b+c:-d/2*(--b*(b-2)-1)+c},easeInCubic:function(a,b,c,d,e){return d*(b/=e)*b*b+c},easeOutCubic:function(a,b,c,d,e){return d*((b=b/e-1)*b*b+1)+c},easeInOutCubic:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b+c:d/2*((b-=2)*b*b+2)+c},easeInQuart:function(a,b,c,d,e){return d*(b/=e)*b*b*b+c},easeOutQuart:function(a,b,c,d,e){return-d*((b=b/e-1)*b*b*b-1)+c},easeInOutQuart:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b*b+c:-d/2*((b-=2)*b*b*b-2)+c},easeInQuint:function(a,b,c,d,e){return d*(b/=e)*b*b*b*b+c},easeOutQuint:function(a,b,c,d,e){return d*((b=b/e-1)*b*b*b*b+1)+c},easeInOutQuint:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b*b*b+c:d/2*((b-=2)*b*b*b*b+2)+c},easeInSine:function(a,b,c,d,e){return-d*Math.cos(b/e*(Math.PI/2))+d+c},easeOutSine:function(a,b,c,d,e){return d*Math.sin(b/e*(Math.PI/2))+c},easeInOutSine:function(a,b,c,d,e){return-d/2*(Math.cos(Math.PI*b/e)-1)+c},easeInExpo:function(a,b,c,d,e){return 0==b?c:d*Math.pow(2,10*(b/e-1))+c},easeOutExpo:function(a,b,c,d,e){return b==e?c+d:d*(-Math.pow(2,-10*b/e)+1)+c},easeInOutExpo:function(a,b,c,d,e){return 0==b?c:b==e?c+d:(b/=e/2)<1?d/2*Math.pow(2,10*(b-1))+c:d/2*(-Math.pow(2,-10*--b)+2)+c},easeInCirc:function(a,b,c,d,e){return-d*(Math.sqrt(1-(b/=e)*b)-1)+c},easeOutCirc:function(a,b,c,d,e){return d*Math.sqrt(1-(b=b/e-1)*b)+c},easeInOutCirc:function(a,b,c,d,e){return(b/=e/2)<1?-d/2*(Math.sqrt(1-b*b)-1)+c:d/2*(Math.sqrt(1-(b-=2)*b)+1)+c},easeInElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(0==b)return c;if(1==(b/=e))return c+d;if(g||(g=.3*e),h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return-(h*Math.pow(2,10*(b-=1))*Math.sin((b*e-f)*(2*Math.PI)/g))+c},easeOutElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(0==b)return c;if(1==(b/=e))return c+d;if(g||(g=.3*e),h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return h*Math.pow(2,-10*b)*Math.sin((b*e-f)*(2*Math.PI)/g)+d+c},easeInOutElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(0==b)return c;if(2==(b/=e/2))return c+d;if(g||(g=e*(.3*1.5)),h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return b<1?-.5*(h*Math.pow(2,10*(b-=1))*Math.sin((b*e-f)*(2*Math.PI)/g))+c:h*Math.pow(2,-10*(b-=1))*Math.sin((b*e-f)*(2*Math.PI)/g)*.5+d+c},easeInBack:function(a,b,c,d,e,f){return void 0==f&&(f=1.70158),d*(b/=e)*b*((f+1)*b-f)+c},easeOutBack:function(a,b,c,d,e,f){return void 0==f&&(f=1.70158),d*((b=b/e-1)*b*((f+1)*b+f)+1)+c},easeInOutBack:function(a,b,c,d,e,f){return void 0==f&&(f=1.70158),(b/=e/2)<1?d/2*(b*b*(((f*=1.525)+1)*b-f))+c:d/2*((b-=2)*b*(((f*=1.525)+1)*b+f)+2)+c},easeInBounce:function(a,b,c,d,e){return d-jQuery.easing.easeOutBounce(a,e-b,0,d,e)+c},easeOutBounce:function(a,b,c,d,e){return(b/=e)<1/2.75?d*(7.5625*b*b)+c:b<2/2.75?d*(7.5625*(b-=1.5/2.75)*b+.75)+c:b<2.5/2.75?d*(7.5625*(b-=2.25/2.75)*b+.9375)+c:d*(7.5625*(b-=2.625/2.75)*b+.984375)+c},easeInOutBounce:function(a,b,c,d,e){return b<e/2?.5*jQuery.easing.easeInBounce(a,2*b,0,d,e)+c:.5*jQuery.easing.easeOutBounce(a,2*b-e,0,d,e)+.5*d+c}}),jQuery.extend(jQuery.easing,{easeInOutMaterial:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b+c:d/4*((b-=2)*b*b+2)+c}}),jQuery.Velocity?console.log("Velocity is already loaded. You may be needlessly importing Velocity again; note that Materialize includes Velocity."):(!function(a){function b(a){var b=a.length,d=c.type(a);return"function"!==d&&!c.isWindow(a)&&(!(1!==a.nodeType||!b)||("array"===d||0===b||"number"==typeof b&&b>0&&b-1 in a))}if(!a.jQuery){var c=function(a,b){return new c.fn.init(a,b)};c.isWindow=function(a){return null!=a&&a==a.window},c.type=function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?e[g.call(a)]||"object":typeof a},c.isArray=Array.isArray||function(a){return"array"===c.type(a)},c.isPlainObject=function(a){var b;if(!a||"object"!==c.type(a)||a.nodeType||c.isWindow(a))return!1;try{if(a.constructor&&!f.call(a,"constructor")&&!f.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(d){return!1}for(b in a);return void 0===b||f.call(a,b)},c.each=function(a,c,d){var e,f=0,g=a.length,h=b(a);if(d){if(h)for(;g>f&&(e=c.apply(a[f],d),e!==!1);f++);else for(f in a)if(e=c.apply(a[f],d),e===!1)break}else if(h)for(;g>f&&(e=c.call(a[f],f,a[f]),e!==!1);f++);else for(f in a)if(e=c.call(a[f],f,a[f]),e===!1)break;return a},c.data=function(a,b,e){if(void 0===e){var f=a[c.expando],g=f&&d[f];if(void 0===b)return g;if(g&&b in g)return g[b]}else if(void 0!==b){var f=a[c.expando]||(a[c.expando]=++c.uuid);return d[f]=d[f]||{},d[f][b]=e,e}},c.removeData=function(a,b){var e=a[c.expando],f=e&&d[e];f&&c.each(b,function(a,b){delete f[b]})},c.extend=function(){var a,b,d,e,f,g,h=arguments[0]||{},i=1,j=arguments.length,k=!1;for("boolean"==typeof h&&(k=h,h=arguments[i]||{},i++),"object"!=typeof h&&"function"!==c.type(h)&&(h={}),i===j&&(h=this,i--);j>i;i++)if(null!=(f=arguments[i]))for(e in f)a=h[e],d=f[e],h!==d&&(k&&d&&(c.isPlainObject(d)||(b=c.isArray(d)))?(b?(b=!1,g=a&&c.isArray(a)?a:[]):g=a&&c.isPlainObject(a)?a:{},h[e]=c.extend(k,g,d)):void 0!==d&&(h[e]=d));return h},c.queue=function(a,d,e){function f(a,c){var d=c||[];return null!=a&&(b(Object(a))?!function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;)a[e++]=b[d++];if(c!==c)for(;void 0!==b[d];)a[e++]=b[d++];return a.length=e,a}(d,"string"==typeof a?[a]:a):[].push.call(d,a)),d}if(a){d=(d||"fx")+"queue";var g=c.data(a,d);return e?(!g||c.isArray(e)?g=c.data(a,d,f(e)):g.push(e),g):g||[]}},c.dequeue=function(a,b){c.each(a.nodeType?[a]:a,function(a,d){b=b||"fx";var e=c.queue(d,b),f=e.shift();"inprogress"===f&&(f=e.shift()),f&&("fx"===b&&e.unshift("inprogress"),f.call(d,function(){c.dequeue(d,b)}))})},c.fn=c.prototype={init:function(a){if(a.nodeType)return this[0]=a,this;throw new Error("Not a DOM node.")},offset:function(){var b=this[0].getBoundingClientRect?this[0].getBoundingClientRect():{top:0,left:0};return{top:b.top+(a.pageYOffset||document.scrollTop||0)-(document.clientTop||0),left:b.left+(a.pageXOffset||document.scrollLeft||0)-(document.clientLeft||0)}},position:function(){function a(){for(var a=this.offsetParent||document;a&&"html"===!a.nodeType.toLowerCase&&"static"===a.style.position;)a=a.offsetParent;return a||document}var b=this[0],a=a.apply(b),d=this.offset(),e=/^(?:body|html)$/i.test(a.nodeName)?{top:0,left:0}:c(a).offset();return d.top-=parseFloat(b.style.marginTop)||0,d.left-=parseFloat(b.style.marginLeft)||0,a.style&&(e.top+=parseFloat(a.style.borderTopWidth)||0,e.left+=parseFloat(a.style.borderLeftWidth)||0),{top:d.top-e.top,left:d.left-e.left}}};var d={};c.expando="velocity"+(new Date).getTime(),c.uuid=0;for(var e={},f=e.hasOwnProperty,g=e.toString,h="Boolean Number String Function Array Date RegExp Object Error".split(" "),i=0;i<h.length;i++)e["[object "+h[i]+"]"]=h[i].toLowerCase();c.fn.init.prototype=c.fn,a.Velocity={Utilities:c}}}(window),function(a){"object"==typeof module&&"object"==typeof module.exports?module.exports=a():"function"==typeof define&&define.amd?define(a):a()}(function(){return function(a,b,c,d){function e(a){for(var b=-1,c=a?a.length:0,d=[];++b<c;){var e=a[b];e&&d.push(e)}return d}function f(a){return p.isWrapped(a)?a=[].slice.call(a):p.isNode(a)&&(a=[a]),a}function g(a){var b=m.data(a,"velocity");return null===b?d:b}function h(a){return function(b){return Math.round(b*a)*(1/a)}}function i(a,c,d,e){function f(a,b){return 1-3*b+3*a}function g(a,b){return 3*b-6*a}function h(a){return 3*a}function i(a,b,c){return((f(b,c)*a+g(b,c))*a+h(b))*a}function j(a,b,c){return 3*f(b,c)*a*a+2*g(b,c)*a+h(b)}function k(b,c){for(var e=0;p>e;++e){var f=j(c,a,d);if(0===f)return c;var g=i(c,a,d)-b;c-=g/f}return c}function l(){for(var b=0;t>b;++b)x[b]=i(b*u,a,d)}function m(b,c,e){var f,g,h=0;do g=c+(e-c)/2,f=i(g,a,d)-b,f>0?e=g:c=g;while(Math.abs(f)>r&&++h<s);return g}function n(b){for(var c=0,e=1,f=t-1;e!=f&&x[e]<=b;++e)c+=u;--e;var g=(b-x[e])/(x[e+1]-x[e]),h=c+g*u,i=j(h,a,d);return i>=q?k(b,h):0==i?h:m(b,c,c+u)}function o(){y=!0,(a!=c||d!=e)&&l()}var p=4,q=.001,r=1e-7,s=10,t=11,u=1/(t-1),v="Float32Array"in b;if(4!==arguments.length)return!1;for(var w=0;4>w;++w)if("number"!=typeof arguments[w]||isNaN(arguments[w])||!isFinite(arguments[w]))return!1;a=Math.min(a,1),d=Math.min(d,1),a=Math.max(a,0),d=Math.max(d,0);var x=v?new Float32Array(t):new Array(t),y=!1,z=function(b){return y||o(),a===c&&d===e?b:0===b?0:1===b?1:i(n(b),c,e)};z.getControlPoints=function(){return[{x:a,y:c},{x:d,y:e}]};var A="generateBezier("+[a,c,d,e]+")";return z.toString=function(){return A},z}function j(a,b){var c=a;return p.isString(a)?t.Easings[a]||(c=!1):c=p.isArray(a)&&1===a.length?h.apply(null,a):p.isArray(a)&&2===a.length?u.apply(null,a.concat([b])):!(!p.isArray(a)||4!==a.length)&&i.apply(null,a),c===!1&&(c=t.Easings[t.defaults.easing]?t.defaults.easing:s),c}function k(a){if(a){var b=(new Date).getTime(),c=t.State.calls.length;c>1e4&&(t.State.calls=e(t.State.calls));for(var f=0;c>f;f++)if(t.State.calls[f]){var h=t.State.calls[f],i=h[0],j=h[2],n=h[3],o=!!n,q=null;n||(n=t.State.calls[f][3]=b-16);for(var r=Math.min((b-n)/j.duration,1),s=0,u=i.length;u>s;s++){var w=i[s],y=w.element;if(g(y)){var z=!1;if(j.display!==d&&null!==j.display&&"none"!==j.display){if("flex"===j.display){var A=["-webkit-box","-moz-box","-ms-flexbox","-webkit-flex"];m.each(A,function(a,b){v.setPropertyValue(y,"display",b)})}v.setPropertyValue(y,"display",j.display)}j.visibility!==d&&"hidden"!==j.visibility&&v.setPropertyValue(y,"visibility",j.visibility);for(var B in w)if("element"!==B){var C,D=w[B],E=p.isString(D.easing)?t.Easings[D.easing]:D.easing;if(1===r)C=D.endValue;else{var F=D.endValue-D.startValue;if(C=D.startValue+F*E(r,j,F),!o&&C===D.currentValue)continue}if(D.currentValue=C,"tween"===B)q=C;else{if(v.Hooks.registered[B]){var G=v.Hooks.getRoot(B),H=g(y).rootPropertyValueCache[G];H&&(D.rootPropertyValue=H)}var I=v.setPropertyValue(y,B,D.currentValue+(0===parseFloat(C)?"":D.unitType),D.rootPropertyValue,D.scrollData);v.Hooks.registered[B]&&(g(y).rootPropertyValueCache[G]=v.Normalizations.registered[G]?v.Normalizations.registered[G]("extract",null,I[1]):I[1]),"transform"===I[0]&&(z=!0)}}j.mobileHA&&g(y).transformCache.translate3d===d&&(g(y).transformCache.translate3d="(0px, 0px, 0px)",z=!0),z&&v.flushTransformCache(y)}}j.display!==d&&"none"!==j.display&&(t.State.calls[f][2].display=!1),j.visibility!==d&&"hidden"!==j.visibility&&(t.State.calls[f][2].visibility=!1),j.progress&&j.progress.call(h[1],h[1],r,Math.max(0,n+j.duration-b),n,q),1===r&&l(f)}}t.State.isTicking&&x(k)}function l(a,b){if(!t.State.calls[a])return!1;for(var c=t.State.calls[a][0],e=t.State.calls[a][1],f=t.State.calls[a][2],h=t.State.calls[a][4],i=!1,j=0,k=c.length;k>j;j++){var l=c[j].element;if(b||f.loop||("none"===f.display&&v.setPropertyValue(l,"display",f.display),"hidden"===f.visibility&&v.setPropertyValue(l,"visibility",f.visibility)),f.loop!==!0&&(m.queue(l)[1]===d||!/\.velocityQueueEntryFlag/i.test(m.queue(l)[1]))&&g(l)){g(l).isAnimating=!1,g(l).rootPropertyValueCache={};var n=!1;m.each(v.Lists.transforms3D,function(a,b){var c=/^scale/.test(b)?1:0,e=g(l).transformCache[b];g(l).transformCache[b]!==d&&new RegExp("^\\("+c+"[^.]").test(e)&&(n=!0,delete g(l).transformCache[b])}),f.mobileHA&&(n=!0,delete g(l).transformCache.translate3d),n&&v.flushTransformCache(l),v.Values.removeClass(l,"velocity-animating")}if(!b&&f.complete&&!f.loop&&j===k-1)try{f.complete.call(e,e)}catch(o){setTimeout(function(){throw o},1)}h&&f.loop!==!0&&h(e),g(l)&&f.loop===!0&&!b&&(m.each(g(l).tweensContainer,function(a,b){/^rotate/.test(a)&&360===parseFloat(b.endValue)&&(b.endValue=0,b.startValue=360),/^backgroundPosition/.test(a)&&100===parseFloat(b.endValue)&&"%"===b.unitType&&(b.endValue=0,b.startValue=100)}),t(l,"reverse",{loop:!0,delay:f.delay})),f.queue!==!1&&m.dequeue(l,f.queue)}t.State.calls[a]=!1;for(var p=0,q=t.State.calls.length;q>p;p++)if(t.State.calls[p]!==!1){i=!0;break}i===!1&&(t.State.isTicking=!1,delete t.State.calls,t.State.calls=[])}var m,n=function(){if(c.documentMode)return c.documentMode;for(var a=7;a>4;a--){var b=c.createElement("div");if(b.innerHTML="<!--[if IE "+a+"]><span></span><![endif]-->",b.getElementsByTagName("span").length)return b=null,a}return d}(),o=function(){var a=0;return b.webkitRequestAnimationFrame||b.mozRequestAnimationFrame||function(b){var c,d=(new Date).getTime();return c=Math.max(0,16-(d-a)),a=d+c,setTimeout(function(){b(d+c)},c)}}(),p={isString:function(a){return"string"==typeof a},isArray:Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)},isFunction:function(a){return"[object Function]"===Object.prototype.toString.call(a)},isNode:function(a){return a&&a.nodeType},isNodeList:function(a){return"object"==typeof a&&/^\[object (HTMLCollection|NodeList|Object)\]$/.test(Object.prototype.toString.call(a))&&a.length!==d&&(0===a.length||"object"==typeof a[0]&&a[0].nodeType>0)},isWrapped:function(a){return a&&(a.jquery||b.Zepto&&b.Zepto.zepto.isZ(a))},isSVG:function(a){return b.SVGElement&&a instanceof b.SVGElement},isEmptyObject:function(a){for(var b in a)return!1;return!0}},q=!1;if(a.fn&&a.fn.jquery?(m=a,q=!0):m=b.Velocity.Utilities,8>=n&&!q)throw new Error("Velocity: IE8 and below require jQuery to be loaded before Velocity.");if(7>=n)return void(jQuery.fn.velocity=jQuery.fn.animate);var r=400,s="swing",t={State:{isMobile:/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),isAndroid:/Android/i.test(navigator.userAgent),isGingerbread:/Android 2\.3\.[3-7]/i.test(navigator.userAgent),isChrome:b.chrome,isFirefox:/Firefox/i.test(navigator.userAgent),prefixElement:c.createElement("div"),prefixMatches:{},scrollAnchor:null,scrollPropertyLeft:null,scrollPropertyTop:null,isTicking:!1,calls:[]},CSS:{},Utilities:m,Redirects:{},Easings:{},Promise:b.Promise,defaults:{queue:"",duration:r,easing:s,begin:d,complete:d,progress:d,display:d,visibility:d,loop:!1,delay:!1,mobileHA:!0,_cacheValues:!0},init:function(a){m.data(a,"velocity",{isSVG:p.isSVG(a),isAnimating:!1,computedStyle:null,tweensContainer:null,rootPropertyValueCache:{},transformCache:{}})},hook:null,mock:!1,version:{major:1,minor:2,patch:2},debug:!1};b.pageYOffset!==d?(t.State.scrollAnchor=b,t.State.scrollPropertyLeft="pageXOffset",t.State.scrollPropertyTop="pageYOffset"):(t.State.scrollAnchor=c.documentElement||c.body.parentNode||c.body,t.State.scrollPropertyLeft="scrollLeft",t.State.scrollPropertyTop="scrollTop");var u=function(){function a(a){return-a.tension*a.x-a.friction*a.v}function b(b,c,d){var e={x:b.x+d.dx*c,v:b.v+d.dv*c,tension:b.tension,friction:b.friction};return{dx:e.v,dv:a(e)}}function c(c,d){var e={dx:c.v,dv:a(c)},f=b(c,.5*d,e),g=b(c,.5*d,f),h=b(c,d,g),i=1/6*(e.dx+2*(f.dx+g.dx)+h.dx),j=1/6*(e.dv+2*(f.dv+g.dv)+h.dv);return c.x=c.x+i*d,c.v=c.v+j*d,c}return function d(a,b,e){var f,g,h,i={x:-1,v:0,tension:null,friction:null},j=[0],k=0,l=1e-4,m=.016;for(a=parseFloat(a)||500,b=parseFloat(b)||20,e=e||null,i.tension=a,i.friction=b,f=null!==e,f?(k=d(a,b),g=k/e*m):g=m;h=c(h||i,g),j.push(1+h.x),k+=16,Math.abs(h.x)>l&&Math.abs(h.v)>l;);return f?function(a){return j[a*(j.length-1)|0]}:k}}();t.Easings={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},spring:function(a){return 1-Math.cos(4.5*a*Math.PI)*Math.exp(6*-a)}},m.each([["ease",[.25,.1,.25,1]],["ease-in",[.42,0,1,1]],["ease-out",[0,0,.58,1]],["ease-in-out",[.42,0,.58,1]],["easeInSine",[.47,0,.745,.715]],["easeOutSine",[.39,.575,.565,1]],["easeInOutSine",[.445,.05,.55,.95]],["easeInQuad",[.55,.085,.68,.53]],["easeOutQuad",[.25,.46,.45,.94]],["easeInOutQuad",[.455,.03,.515,.955]],["easeInCubic",[.55,.055,.675,.19]],["easeOutCubic",[.215,.61,.355,1]],["easeInOutCubic",[.645,.045,.355,1]],["easeInQuart",[.895,.03,.685,.22]],["easeOutQuart",[.165,.84,.44,1]],["easeInOutQuart",[.77,0,.175,1]],["easeInQuint",[.755,.05,.855,.06]],["easeOutQuint",[.23,1,.32,1]],["easeInOutQuint",[.86,0,.07,1]],["easeInExpo",[.95,.05,.795,.035]],["easeOutExpo",[.19,1,.22,1]],["easeInOutExpo",[1,0,0,1]],["easeInCirc",[.6,.04,.98,.335]],["easeOutCirc",[.075,.82,.165,1]],["easeInOutCirc",[.785,.135,.15,.86]]],function(a,b){t.Easings[b[0]]=i.apply(null,b[1])});var v=t.CSS={RegEx:{isHex:/^#([A-f\d]{3}){1,2}$/i,valueUnwrap:/^[A-z]+\((.*)\)$/i,wrappedValueAlreadyExtracted:/[0-9.]+ [0-9.]+ [0-9.]+( [0-9.]+)?/,valueSplit:/([A-z]+\(.+\))|(([A-z0-9#-.]+?)(?=\s|$))/gi},Lists:{colors:["fill","stroke","stopColor","color","backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor"],transformsBase:["translateX","translateY","scale","scaleX","scaleY","skewX","skewY","rotateZ"],transforms3D:["transformPerspective","translateZ","scaleZ","rotateX","rotateY"]},Hooks:{templates:{textShadow:["Color X Y Blur","black 0px 0px 0px"],boxShadow:["Color X Y Blur Spread","black 0px 0px 0px 0px"],clip:["Top Right Bottom Left","0px 0px 0px 0px"],backgroundPosition:["X Y","0% 0%"],transformOrigin:["X Y Z","50% 50% 0px"],perspectiveOrigin:["X Y","50% 50%"]},registered:{},register:function(){for(var a=0;a<v.Lists.colors.length;a++){var b="color"===v.Lists.colors[a]?"0 0 0 1":"255 255 255 1";v.Hooks.templates[v.Lists.colors[a]]=["Red Green Blue Alpha",b]}var c,d,e;if(n)for(c in v.Hooks.templates){d=v.Hooks.templates[c],e=d[0].split(" ");var f=d[1].match(v.RegEx.valueSplit);"Color"===e[0]&&(e.push(e.shift()),f.push(f.shift()),v.Hooks.templates[c]=[e.join(" "),f.join(" ")])}for(c in v.Hooks.templates){d=v.Hooks.templates[c],e=d[0].split(" ");for(var a in e){var g=c+e[a],h=a;v.Hooks.registered[g]=[c,h]}}},getRoot:function(a){var b=v.Hooks.registered[a];return b?b[0]:a},cleanRootPropertyValue:function(a,b){return v.RegEx.valueUnwrap.test(b)&&(b=b.match(v.RegEx.valueUnwrap)[1]),v.Values.isCSSNullValue(b)&&(b=v.Hooks.templates[a][1]),b},extractValue:function(a,b){var c=v.Hooks.registered[a];if(c){var d=c[0],e=c[1];return b=v.Hooks.cleanRootPropertyValue(d,b),b.toString().match(v.RegEx.valueSplit)[e]}return b},injectValue:function(a,b,c){var d=v.Hooks.registered[a];if(d){var e,f,g=d[0],h=d[1];return c=v.Hooks.cleanRootPropertyValue(g,c),e=c.toString().match(v.RegEx.valueSplit),e[h]=b,f=e.join(" ")}return c}},Normalizations:{registered:{clip:function(a,b,c){switch(a){case"name":return"clip";case"extract":var d;return v.RegEx.wrappedValueAlreadyExtracted.test(c)?d=c:(d=c.toString().match(v.RegEx.valueUnwrap),d=d?d[1].replace(/,(\s+)?/g," "):c),d;case"inject":return"rect("+c+")"}},blur:function(a,b,c){switch(a){case"name":return t.State.isFirefox?"filter":"-webkit-filter";case"extract":var d=parseFloat(c);if(!d&&0!==d){var e=c.toString().match(/blur\(([0-9]+[A-z]+)\)/i);d=e?e[1]:0}return d;case"inject":return parseFloat(c)?"blur("+c+")":"none"}},opacity:function(a,b,c){if(8>=n)switch(a){case"name":return"filter";case"extract":var d=c.toString().match(/alpha\(opacity=(.*)\)/i);return c=d?d[1]/100:1;case"inject":return b.style.zoom=1,parseFloat(c)>=1?"":"alpha(opacity="+parseInt(100*parseFloat(c),10)+")"}else switch(a){case"name":return"opacity";case"extract":return c;case"inject":return c}}},register:function(){9>=n||t.State.isGingerbread||(v.Lists.transformsBase=v.Lists.transformsBase.concat(v.Lists.transforms3D));for(var a=0;a<v.Lists.transformsBase.length;a++)!function(){var b=v.Lists.transformsBase[a];v.Normalizations.registered[b]=function(a,c,e){switch(a){case"name":return"transform";case"extract":return g(c)===d||g(c).transformCache[b]===d?/^scale/i.test(b)?1:0:g(c).transformCache[b].replace(/[()]/g,"");case"inject":var f=!1;switch(b.substr(0,b.length-1)){case"translate":f=!/(%|px|em|rem|vw|vh|\d)$/i.test(e);break;case"scal":case"scale":t.State.isAndroid&&g(c).transformCache[b]===d&&1>e&&(e=1),f=!/(\d)$/i.test(e);break;case"skew":f=!/(deg|\d)$/i.test(e);break;case"rotate":f=!/(deg|\d)$/i.test(e)}return f||(g(c).transformCache[b]="("+e+")"),g(c).transformCache[b]}}}();for(var a=0;a<v.Lists.colors.length;a++)!function(){var b=v.Lists.colors[a];v.Normalizations.registered[b]=function(a,c,e){switch(a){case"name":return b;case"extract":var f;if(v.RegEx.wrappedValueAlreadyExtracted.test(e))f=e;else{var g,h={black:"rgb(0, 0, 0)",blue:"rgb(0, 0, 255)",gray:"rgb(128, 128, 128)",green:"rgb(0, 128, 0)",red:"rgb(255, 0, 0)",white:"rgb(255, 255, 255)"};/^[A-z]+$/i.test(e)?g=h[e]!==d?h[e]:h.black:v.RegEx.isHex.test(e)?g="rgb("+v.Values.hexToRgb(e).join(" ")+")":/^rgba?\(/i.test(e)||(g=h.black),f=(g||e).toString().match(v.RegEx.valueUnwrap)[1].replace(/,(\s+)?/g," ")}return 8>=n||3!==f.split(" ").length||(f+=" 1"),f;case"inject":return 8>=n?4===e.split(" ").length&&(e=e.split(/\s+/).slice(0,3).join(" ")):3===e.split(" ").length&&(e+=" 1"),(8>=n?"rgb":"rgba")+"("+e.replace(/\s+/g,",").replace(/\.(\d)+(?=,)/g,"")+")"}}}()}},Names:{camelCase:function(a){return a.replace(/-(\w)/g,function(a,b){return b.toUpperCase()})},SVGAttribute:function(a){var b="width|height|x|y|cx|cy|r|rx|ry|x1|x2|y1|y2";return(n||t.State.isAndroid&&!t.State.isChrome)&&(b+="|transform"),new RegExp("^("+b+")$","i").test(a)},prefixCheck:function(a){if(t.State.prefixMatches[a])return[t.State.prefixMatches[a],!0];for(var b=["","Webkit","Moz","ms","O"],c=0,d=b.length;d>c;c++){var e;if(e=0===c?a:b[c]+a.replace(/^\w/,function(a){return a.toUpperCase()}),p.isString(t.State.prefixElement.style[e]))return t.State.prefixMatches[a]=e,[e,!0]}return[a,!1]}},Values:{hexToRgb:function(a){var b,c=/^#?([a-f\d])([a-f\d])([a-f\d])$/i,d=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;return a=a.replace(c,function(a,b,c,d){return b+b+c+c+d+d}),b=d.exec(a),b?[parseInt(b[1],16),parseInt(b[2],16),parseInt(b[3],16)]:[0,0,0]},isCSSNullValue:function(a){return 0==a||/^(none|auto|transparent|(rgba\(0, ?0, ?0, ?0\)))$/i.test(a)},getUnitType:function(a){return/^(rotate|skew)/i.test(a)?"deg":/(^(scale|scaleX|scaleY|scaleZ|alpha|flexGrow|flexHeight|zIndex|fontWeight)$)|((opacity|red|green|blue|alpha)$)/i.test(a)?"":"px"},getDisplayType:function(a){var b=a&&a.tagName.toString().toLowerCase();return/^(b|big|i|small|tt|abbr|acronym|cite|code|dfn|em|kbd|strong|samp|var|a|bdo|br|img|map|object|q|script|span|sub|sup|button|input|label|select|textarea)$/i.test(b)?"inline":/^(li)$/i.test(b)?"list-item":/^(tr)$/i.test(b)?"table-row":/^(table)$/i.test(b)?"table":/^(tbody)$/i.test(b)?"table-row-group":"block"},addClass:function(a,b){a.classList?a.classList.add(b):a.className+=(a.className.length?" ":"")+b},removeClass:function(a,b){a.classList?a.classList.remove(b):a.className=a.className.toString().replace(new RegExp("(^|\\s)"+b.split(" ").join("|")+"(\\s|$)","gi")," ")}},getPropertyValue:function(a,c,e,f){function h(a,c){function e(){j&&v.setPropertyValue(a,"display","none")}var i=0;if(8>=n)i=m.css(a,c);else{var j=!1;if(/^(width|height)$/.test(c)&&0===v.getPropertyValue(a,"display")&&(j=!0,v.setPropertyValue(a,"display",v.Values.getDisplayType(a))),!f){if("height"===c&&"border-box"!==v.getPropertyValue(a,"boxSizing").toString().toLowerCase()){var k=a.offsetHeight-(parseFloat(v.getPropertyValue(a,"borderTopWidth"))||0)-(parseFloat(v.getPropertyValue(a,"borderBottomWidth"))||0)-(parseFloat(v.getPropertyValue(a,"paddingTop"))||0)-(parseFloat(v.getPropertyValue(a,"paddingBottom"))||0);return e(),k}if("width"===c&&"border-box"!==v.getPropertyValue(a,"boxSizing").toString().toLowerCase()){var l=a.offsetWidth-(parseFloat(v.getPropertyValue(a,"borderLeftWidth"))||0)-(parseFloat(v.getPropertyValue(a,"borderRightWidth"))||0)-(parseFloat(v.getPropertyValue(a,"paddingLeft"))||0)-(parseFloat(v.getPropertyValue(a,"paddingRight"))||0);return e(),l}}var o;o=g(a)===d?b.getComputedStyle(a,null):g(a).computedStyle?g(a).computedStyle:g(a).computedStyle=b.getComputedStyle(a,null),"borderColor"===c&&(c="borderTopColor"),i=9===n&&"filter"===c?o.getPropertyValue(c):o[c],(""===i||null===i)&&(i=a.style[c]),e()}if("auto"===i&&/^(top|right|bottom|left)$/i.test(c)){var p=h(a,"position");("fixed"===p||"absolute"===p&&/top|left/i.test(c))&&(i=m(a).position()[c]+"px")}return i}var i;if(v.Hooks.registered[c]){var j=c,k=v.Hooks.getRoot(j);e===d&&(e=v.getPropertyValue(a,v.Names.prefixCheck(k)[0])),v.Normalizations.registered[k]&&(e=v.Normalizations.registered[k]("extract",a,e)),i=v.Hooks.extractValue(j,e)}else if(v.Normalizations.registered[c]){var l,o;l=v.Normalizations.registered[c]("name",a),"transform"!==l&&(o=h(a,v.Names.prefixCheck(l)[0]),v.Values.isCSSNullValue(o)&&v.Hooks.templates[c]&&(o=v.Hooks.templates[c][1])),i=v.Normalizations.registered[c]("extract",a,o)}if(!/^[\d-]/.test(i))if(g(a)&&g(a).isSVG&&v.Names.SVGAttribute(c))if(/^(height|width)$/i.test(c))try{i=a.getBBox()[c]}catch(p){i=0}else i=a.getAttribute(c);else i=h(a,v.Names.prefixCheck(c)[0]);return v.Values.isCSSNullValue(i)&&(i=0),t.debug>=2&&console.log("Get "+c+": "+i),i},setPropertyValue:function(a,c,d,e,f){var h=c;if("scroll"===c)f.container?f.container["scroll"+f.direction]=d:"Left"===f.direction?b.scrollTo(d,f.alternateValue):b.scrollTo(f.alternateValue,d);else if(v.Normalizations.registered[c]&&"transform"===v.Normalizations.registered[c]("name",a))v.Normalizations.registered[c]("inject",a,d),h="transform",d=g(a).transformCache[c];else{if(v.Hooks.registered[c]){var i=c,j=v.Hooks.getRoot(c);e=e||v.getPropertyValue(a,j),d=v.Hooks.injectValue(i,d,e),c=j}if(v.Normalizations.registered[c]&&(d=v.Normalizations.registered[c]("inject",a,d),c=v.Normalizations.registered[c]("name",a)),h=v.Names.prefixCheck(c)[0],8>=n)try{a.style[h]=d}catch(k){t.debug&&console.log("Browser does not support ["+d+"] for ["+h+"]")}else g(a)&&g(a).isSVG&&v.Names.SVGAttribute(c)?a.setAttribute(c,d):a.style[h]=d;t.debug>=2&&console.log("Set "+c+" ("+h+"): "+d)}return[h,d]},flushTransformCache:function(a){function b(b){return parseFloat(v.getPropertyValue(a,b))}var c="";if((n||t.State.isAndroid&&!t.State.isChrome)&&g(a).isSVG){var d={translate:[b("translateX"),b("translateY")],skewX:[b("skewX")],skewY:[b("skewY")],scale:1!==b("scale")?[b("scale"),b("scale")]:[b("scaleX"),b("scaleY")],rotate:[b("rotateZ"),0,0]};m.each(g(a).transformCache,function(a){/^translate/i.test(a)?a="translate":/^scale/i.test(a)?a="scale":/^rotate/i.test(a)&&(a="rotate"),d[a]&&(c+=a+"("+d[a].join(" ")+") ",delete d[a])})}else{var e,f;m.each(g(a).transformCache,function(b){return e=g(a).transformCache[b],"transformPerspective"===b?(f=e,!0):(9===n&&"rotateZ"===b&&(b="rotate"),void(c+=b+e+" "))}),f&&(c="perspective"+f+" "+c)}v.setPropertyValue(a,"transform",c)}};v.Hooks.register(),v.Normalizations.register(),t.hook=function(a,b,c){var e=d;return a=f(a),m.each(a,function(a,f){if(g(f)===d&&t.init(f),c===d)e===d&&(e=t.CSS.getPropertyValue(f,b));else{var h=t.CSS.setPropertyValue(f,b,c);"transform"===h[0]&&t.CSS.flushTransformCache(f),e=h}}),e};var w=function(){function a(){return h?B.promise||null:i}function e(){function a(a){function l(a,b){var c=d,e=d,g=d;return p.isArray(a)?(c=a[0],!p.isArray(a[1])&&/^[\d-]/.test(a[1])||p.isFunction(a[1])||v.RegEx.isHex.test(a[1])?g=a[1]:(p.isString(a[1])&&!v.RegEx.isHex.test(a[1])||p.isArray(a[1]))&&(e=b?a[1]:j(a[1],h.duration),a[2]!==d&&(g=a[2]))):c=a,b||(e=e||h.easing),p.isFunction(c)&&(c=c.call(f,y,x)),p.isFunction(g)&&(g=g.call(f,y,x)),[c||0,e,g]}function n(a,b){var c,d;return d=(b||"0").toString().toLowerCase().replace(/[%A-z]+$/,function(a){return c=a,""}),c||(c=v.Values.getUnitType(a)),[d,c]}function r(){var a={myParent:f.parentNode||c.body,position:v.getPropertyValue(f,"position"),fontSize:v.getPropertyValue(f,"fontSize")},d=a.position===I.lastPosition&&a.myParent===I.lastParent,e=a.fontSize===I.lastFontSize;I.lastParent=a.myParent,I.lastPosition=a.position,I.lastFontSize=a.fontSize;var h=100,i={};if(e&&d)i.emToPx=I.lastEmToPx,i.percentToPxWidth=I.lastPercentToPxWidth,i.percentToPxHeight=I.lastPercentToPxHeight;else{var j=g(f).isSVG?c.createElementNS("http://www.w3.org/2000/svg","rect"):c.createElement("div");t.init(j),a.myParent.appendChild(j),m.each(["overflow","overflowX","overflowY"],function(a,b){t.CSS.setPropertyValue(j,b,"hidden")}),t.CSS.setPropertyValue(j,"position",a.position),t.CSS.setPropertyValue(j,"fontSize",a.fontSize),t.CSS.setPropertyValue(j,"boxSizing","content-box"),m.each(["minWidth","maxWidth","width","minHeight","maxHeight","height"],function(a,b){t.CSS.setPropertyValue(j,b,h+"%")}),t.CSS.setPropertyValue(j,"paddingLeft",h+"em"),i.percentToPxWidth=I.lastPercentToPxWidth=(parseFloat(v.getPropertyValue(j,"width",null,!0))||1)/h,i.percentToPxHeight=I.lastPercentToPxHeight=(parseFloat(v.getPropertyValue(j,"height",null,!0))||1)/h,i.emToPx=I.lastEmToPx=(parseFloat(v.getPropertyValue(j,"paddingLeft"))||1)/h,a.myParent.removeChild(j)}return null===I.remToPx&&(I.remToPx=parseFloat(v.getPropertyValue(c.body,"fontSize"))||16),null===I.vwToPx&&(I.vwToPx=parseFloat(b.innerWidth)/100,I.vhToPx=parseFloat(b.innerHeight)/100),i.remToPx=I.remToPx,i.vwToPx=I.vwToPx,i.vhToPx=I.vhToPx,t.debug>=1&&console.log("Unit ratios: "+JSON.stringify(i),f),i}if(h.begin&&0===y)try{h.begin.call(o,o)}catch(u){setTimeout(function(){throw u},1)}if("scroll"===C){var w,z,A,D=/^x$/i.test(h.axis)?"Left":"Top",E=parseFloat(h.offset)||0;h.container?p.isWrapped(h.container)||p.isNode(h.container)?(h.container=h.container[0]||h.container,w=h.container["scroll"+D],A=w+m(f).position()[D.toLowerCase()]+E):h.container=null:(w=t.State.scrollAnchor[t.State["scrollProperty"+D]],z=t.State.scrollAnchor[t.State["scrollProperty"+("Left"===D?"Top":"Left")]],A=m(f).offset()[D.toLowerCase()]+E),i={scroll:{rootPropertyValue:!1,startValue:w,currentValue:w,endValue:A,unitType:"",easing:h.easing,scrollData:{container:h.container,direction:D,alternateValue:z}},element:f},t.debug&&console.log("tweensContainer (scroll): ",i.scroll,f)}else if("reverse"===C){if(!g(f).tweensContainer)return void m.dequeue(f,h.queue);"none"===g(f).opts.display&&(g(f).opts.display="auto"),"hidden"===g(f).opts.visibility&&(g(f).opts.visibility="visible"),g(f).opts.loop=!1,g(f).opts.begin=null,g(f).opts.complete=null,s.easing||delete h.easing,s.duration||delete h.duration,h=m.extend({},g(f).opts,h);var F=m.extend(!0,{},g(f).tweensContainer);for(var G in F)if("element"!==G){var H=F[G].startValue;F[G].startValue=F[G].currentValue=F[G].endValue,F[G].endValue=H,p.isEmptyObject(s)||(F[G].easing=h.easing),t.debug&&console.log("reverse tweensContainer ("+G+"): "+JSON.stringify(F[G]),f)}i=F}else if("start"===C){var F;g(f).tweensContainer&&g(f).isAnimating===!0&&(F=g(f).tweensContainer),m.each(q,function(a,b){if(RegExp("^"+v.Lists.colors.join("$|^")+"$").test(a)){var c=l(b,!0),e=c[0],f=c[1],g=c[2];if(v.RegEx.isHex.test(e)){for(var h=["Red","Green","Blue"],i=v.Values.hexToRgb(e),j=g?v.Values.hexToRgb(g):d,k=0;k<h.length;k++){var m=[i[k]];f&&m.push(f),j!==d&&m.push(j[k]),q[a+h[k]]=m}delete q[a]}}});for(var K in q){var L=l(q[K]),M=L[0],N=L[1],O=L[2];K=v.Names.camelCase(K);var P=v.Hooks.getRoot(K),Q=!1;if(g(f).isSVG||"tween"===P||v.Names.prefixCheck(P)[1]!==!1||v.Normalizations.registered[P]!==d){(h.display!==d&&null!==h.display&&"none"!==h.display||h.visibility!==d&&"hidden"!==h.visibility)&&/opacity|filter/.test(K)&&!O&&0!==M&&(O=0),h._cacheValues&&F&&F[K]?(O===d&&(O=F[K].endValue+F[K].unitType),Q=g(f).rootPropertyValueCache[P]):v.Hooks.registered[K]?O===d?(Q=v.getPropertyValue(f,P),O=v.getPropertyValue(f,K,Q)):Q=v.Hooks.templates[P][1]:O===d&&(O=v.getPropertyValue(f,K));var R,S,T,U=!1;if(R=n(K,O),O=R[0],T=R[1],R=n(K,M),M=R[0].replace(/^([+-\/*])=/,function(a,b){return U=b,""}),S=R[1],O=parseFloat(O)||0,M=parseFloat(M)||0,"%"===S&&(/^(fontSize|lineHeight)$/.test(K)?(M/=100,S="em"):/^scale/.test(K)?(M/=100,S=""):/(Red|Green|Blue)$/i.test(K)&&(M=M/100*255,S="")),/[\/*]/.test(U))S=T;else if(T!==S&&0!==O)if(0===M)S=T;else{e=e||r();var V=/margin|padding|left|right|width|text|word|letter/i.test(K)||/X$/.test(K)||"x"===K?"x":"y";
7
+ switch(T){case"%":O*="x"===V?e.percentToPxWidth:e.percentToPxHeight;break;case"px":break;default:O*=e[T+"ToPx"]}switch(S){case"%":O*=1/("x"===V?e.percentToPxWidth:e.percentToPxHeight);break;case"px":break;default:O*=1/e[S+"ToPx"]}}switch(U){case"+":M=O+M;break;case"-":M=O-M;break;case"*":M=O*M;break;case"/":M=O/M}i[K]={rootPropertyValue:Q,startValue:O,currentValue:O,endValue:M,unitType:S,easing:N},t.debug&&console.log("tweensContainer ("+K+"): "+JSON.stringify(i[K]),f)}else t.debug&&console.log("Skipping ["+P+"] due to a lack of browser support.")}i.element=f}i.element&&(v.Values.addClass(f,"velocity-animating"),J.push(i),""===h.queue&&(g(f).tweensContainer=i,g(f).opts=h),g(f).isAnimating=!0,y===x-1?(t.State.calls.push([J,o,h,null,B.resolver]),t.State.isTicking===!1&&(t.State.isTicking=!0,k())):y++)}var e,f=this,h=m.extend({},t.defaults,s),i={};switch(g(f)===d&&t.init(f),parseFloat(h.delay)&&h.queue!==!1&&m.queue(f,h.queue,function(a){t.velocityQueueEntryFlag=!0,g(f).delayTimer={setTimeout:setTimeout(a,parseFloat(h.delay)),next:a}}),h.duration.toString().toLowerCase()){case"fast":h.duration=200;break;case"normal":h.duration=r;break;case"slow":h.duration=600;break;default:h.duration=parseFloat(h.duration)||1}t.mock!==!1&&(t.mock===!0?h.duration=h.delay=1:(h.duration*=parseFloat(t.mock)||1,h.delay*=parseFloat(t.mock)||1)),h.easing=j(h.easing,h.duration),h.begin&&!p.isFunction(h.begin)&&(h.begin=null),h.progress&&!p.isFunction(h.progress)&&(h.progress=null),h.complete&&!p.isFunction(h.complete)&&(h.complete=null),h.display!==d&&null!==h.display&&(h.display=h.display.toString().toLowerCase(),"auto"===h.display&&(h.display=t.CSS.Values.getDisplayType(f))),h.visibility!==d&&null!==h.visibility&&(h.visibility=h.visibility.toString().toLowerCase()),h.mobileHA=h.mobileHA&&t.State.isMobile&&!t.State.isGingerbread,h.queue===!1?h.delay?setTimeout(a,h.delay):a():m.queue(f,h.queue,function(b,c){return c===!0?(B.promise&&B.resolver(o),!0):(t.velocityQueueEntryFlag=!0,void a(b))}),""!==h.queue&&"fx"!==h.queue||"inprogress"===m.queue(f)[0]||m.dequeue(f)}var h,i,n,o,q,s,u=arguments[0]&&(arguments[0].p||m.isPlainObject(arguments[0].properties)&&!arguments[0].properties.names||p.isString(arguments[0].properties));if(p.isWrapped(this)?(h=!1,n=0,o=this,i=this):(h=!0,n=1,o=u?arguments[0].elements||arguments[0].e:arguments[0]),o=f(o)){u?(q=arguments[0].properties||arguments[0].p,s=arguments[0].options||arguments[0].o):(q=arguments[n],s=arguments[n+1]);var x=o.length,y=0;if(!/^(stop|finish)$/i.test(q)&&!m.isPlainObject(s)){var z=n+1;s={};for(var A=z;A<arguments.length;A++)p.isArray(arguments[A])||!/^(fast|normal|slow)$/i.test(arguments[A])&&!/^\d/.test(arguments[A])?p.isString(arguments[A])||p.isArray(arguments[A])?s.easing=arguments[A]:p.isFunction(arguments[A])&&(s.complete=arguments[A]):s.duration=arguments[A]}var B={promise:null,resolver:null,rejecter:null};h&&t.Promise&&(B.promise=new t.Promise(function(a,b){B.resolver=a,B.rejecter=b}));var C;switch(q){case"scroll":C="scroll";break;case"reverse":C="reverse";break;case"finish":case"stop":m.each(o,function(a,b){g(b)&&g(b).delayTimer&&(clearTimeout(g(b).delayTimer.setTimeout),g(b).delayTimer.next&&g(b).delayTimer.next(),delete g(b).delayTimer)});var D=[];return m.each(t.State.calls,function(a,b){b&&m.each(b[1],function(c,e){var f=s===d?"":s;return f!==!0&&b[2].queue!==f&&(s!==d||b[2].queue!==!1)||void m.each(o,function(c,d){d===e&&((s===!0||p.isString(s))&&(m.each(m.queue(d,p.isString(s)?s:""),function(a,b){p.isFunction(b)&&b(null,!0)}),m.queue(d,p.isString(s)?s:"",[])),"stop"===q?(g(d)&&g(d).tweensContainer&&f!==!1&&m.each(g(d).tweensContainer,function(a,b){b.endValue=b.currentValue}),D.push(a)):"finish"===q&&(b[2].duration=1))})})}),"stop"===q&&(m.each(D,function(a,b){l(b,!0)}),B.promise&&B.resolver(o)),a();default:if(!m.isPlainObject(q)||p.isEmptyObject(q)){if(p.isString(q)&&t.Redirects[q]){var E=m.extend({},s),F=E.duration,G=E.delay||0;return E.backwards===!0&&(o=m.extend(!0,[],o).reverse()),m.each(o,function(a,b){parseFloat(E.stagger)?E.delay=G+parseFloat(E.stagger)*a:p.isFunction(E.stagger)&&(E.delay=G+E.stagger.call(b,a,x)),E.drag&&(E.duration=parseFloat(F)||(/^(callout|transition)/.test(q)?1e3:r),E.duration=Math.max(E.duration*(E.backwards?1-a/x:(a+1)/x),.75*E.duration,200)),t.Redirects[q].call(b,b,E||{},a,x,o,B.promise?B:d)}),a()}var H="Velocity: First argument ("+q+") was not a property map, a known action, or a registered redirect. Aborting.";return B.promise?B.rejecter(new Error(H)):console.log(H),a()}C="start"}var I={lastParent:null,lastPosition:null,lastFontSize:null,lastPercentToPxWidth:null,lastPercentToPxHeight:null,lastEmToPx:null,remToPx:null,vwToPx:null,vhToPx:null},J=[];m.each(o,function(a,b){p.isNode(b)&&e.call(b)});var K,E=m.extend({},t.defaults,s);if(E.loop=parseInt(E.loop),K=2*E.loop-1,E.loop)for(var L=0;K>L;L++){var M={delay:E.delay,progress:E.progress};L===K-1&&(M.display=E.display,M.visibility=E.visibility,M.complete=E.complete),w(o,"reverse",M)}return a()}};t=m.extend(w,t),t.animate=w;var x=b.requestAnimationFrame||o;return t.State.isMobile||c.hidden===d||c.addEventListener("visibilitychange",function(){c.hidden?(x=function(a){return setTimeout(function(){a(!0)},16)},k()):x=b.requestAnimationFrame||o}),a.Velocity=t,a!==b&&(a.fn.velocity=w,a.fn.velocity.defaults=t.defaults),m.each(["Down","Up"],function(a,b){t.Redirects["slide"+b]=function(a,c,e,f,g,h){var i=m.extend({},c),j=i.begin,k=i.complete,l={height:"",marginTop:"",marginBottom:"",paddingTop:"",paddingBottom:""},n={};i.display===d&&(i.display="Down"===b?"inline"===t.CSS.Values.getDisplayType(a)?"inline-block":"block":"none"),i.begin=function(){j&&j.call(g,g);for(var c in l){n[c]=a.style[c];var d=t.CSS.getPropertyValue(a,c);l[c]="Down"===b?[d,0]:[0,d]}n.overflow=a.style.overflow,a.style.overflow="hidden"},i.complete=function(){for(var b in n)a.style[b]=n[b];k&&k.call(g,g),h&&h.resolver(g)},t(a,l,i)}}),m.each(["In","Out"],function(a,b){t.Redirects["fade"+b]=function(a,c,e,f,g,h){var i=m.extend({},c),j={opacity:"In"===b?1:0},k=i.complete;i.complete=e!==f-1?i.begin=null:function(){k&&k.call(g,g),h&&h.resolver(g)},i.display===d&&(i.display="In"===b?"auto":"none"),t(this,j,i)}}),t}(window.jQuery||window.Zepto||window,window,document)})),!function(a,b,c,d){"use strict";function e(a,b,c){return setTimeout(k(a,c),b)}function f(a,b,c){return!!Array.isArray(a)&&(g(a,c[b],c),!0)}function g(a,b,c){var e;if(a)if(a.forEach)a.forEach(b,c);else if(a.length!==d)for(e=0;e<a.length;)b.call(c,a[e],e,a),e++;else for(e in a)a.hasOwnProperty(e)&&b.call(c,a[e],e,a)}function h(a,b,c){for(var e=Object.keys(b),f=0;f<e.length;)(!c||c&&a[e[f]]===d)&&(a[e[f]]=b[e[f]]),f++;return a}function i(a,b){return h(a,b,!0)}function j(a,b,c){var d,e=b.prototype;d=a.prototype=Object.create(e),d.constructor=a,d._super=e,c&&h(d,c)}function k(a,b){return function(){return a.apply(b,arguments)}}function l(a,b){return typeof a==ka?a.apply(b?b[0]||d:d,b):a}function m(a,b){return a===d?b:a}function n(a,b,c){g(r(b),function(b){a.addEventListener(b,c,!1)})}function o(a,b,c){g(r(b),function(b){a.removeEventListener(b,c,!1)})}function p(a,b){for(;a;){if(a==b)return!0;a=a.parentNode}return!1}function q(a,b){return a.indexOf(b)>-1}function r(a){return a.trim().split(/\s+/g)}function s(a,b,c){if(a.indexOf&&!c)return a.indexOf(b);for(var d=0;d<a.length;){if(c&&a[d][c]==b||!c&&a[d]===b)return d;d++}return-1}function t(a){return Array.prototype.slice.call(a,0)}function u(a,b,c){for(var d=[],e=[],f=0;f<a.length;){var g=b?a[f][b]:a[f];s(e,g)<0&&d.push(a[f]),e[f]=g,f++}return c&&(d=b?d.sort(function(a,c){return a[b]>c[b]}):d.sort()),d}function v(a,b){for(var c,e,f=b[0].toUpperCase()+b.slice(1),g=0;g<ia.length;){if(c=ia[g],e=c?c+f:b,e in a)return e;g++}return d}function w(){return oa++}function x(a){var b=a.ownerDocument;return b.defaultView||b.parentWindow}function y(a,b){var c=this;this.manager=a,this.callback=b,this.element=a.element,this.target=a.options.inputTarget,this.domHandler=function(b){l(a.options.enable,[a])&&c.handler(b)},this.init()}function z(a){var b,c=a.options.inputClass;return new(b=c?c:ra?N:sa?Q:qa?S:M)(a,A)}function A(a,b,c){var d=c.pointers.length,e=c.changedPointers.length,f=b&ya&&0===d-e,g=b&(Aa|Ba)&&0===d-e;c.isFirst=!!f,c.isFinal=!!g,f&&(a.session={}),c.eventType=b,B(a,c),a.emit("hammer.input",c),a.recognize(c),a.session.prevInput=c}function B(a,b){var c=a.session,d=b.pointers,e=d.length;c.firstInput||(c.firstInput=E(b)),e>1&&!c.firstMultiple?c.firstMultiple=E(b):1===e&&(c.firstMultiple=!1);var f=c.firstInput,g=c.firstMultiple,h=g?g.center:f.center,i=b.center=F(d);b.timeStamp=na(),b.deltaTime=b.timeStamp-f.timeStamp,b.angle=J(h,i),b.distance=I(h,i),C(c,b),b.offsetDirection=H(b.deltaX,b.deltaY),b.scale=g?L(g.pointers,d):1,b.rotation=g?K(g.pointers,d):0,D(c,b);var j=a.element;p(b.srcEvent.target,j)&&(j=b.srcEvent.target),b.target=j}function C(a,b){var c=b.center,d=a.offsetDelta||{},e=a.prevDelta||{},f=a.prevInput||{};(b.eventType===ya||f.eventType===Aa)&&(e=a.prevDelta={x:f.deltaX||0,y:f.deltaY||0},d=a.offsetDelta={x:c.x,y:c.y}),b.deltaX=e.x+(c.x-d.x),b.deltaY=e.y+(c.y-d.y)}function D(a,b){var c,e,f,g,h=a.lastInterval||b,i=b.timeStamp-h.timeStamp;if(b.eventType!=Ba&&(i>xa||h.velocity===d)){var j=h.deltaX-b.deltaX,k=h.deltaY-b.deltaY,l=G(i,j,k);e=l.x,f=l.y,c=ma(l.x)>ma(l.y)?l.x:l.y,g=H(j,k),a.lastInterval=b}else c=h.velocity,e=h.velocityX,f=h.velocityY,g=h.direction;b.velocity=c,b.velocityX=e,b.velocityY=f,b.direction=g}function E(a){for(var b=[],c=0;c<a.pointers.length;)b[c]={clientX:la(a.pointers[c].clientX),clientY:la(a.pointers[c].clientY)},c++;return{timeStamp:na(),pointers:b,center:F(b),deltaX:a.deltaX,deltaY:a.deltaY}}function F(a){var b=a.length;if(1===b)return{x:la(a[0].clientX),y:la(a[0].clientY)};for(var c=0,d=0,e=0;b>e;)c+=a[e].clientX,d+=a[e].clientY,e++;return{x:la(c/b),y:la(d/b)}}function G(a,b,c){return{x:b/a||0,y:c/a||0}}function H(a,b){return a===b?Ca:ma(a)>=ma(b)?a>0?Da:Ea:b>0?Fa:Ga}function I(a,b,c){c||(c=Ka);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return Math.sqrt(d*d+e*e)}function J(a,b,c){c||(c=Ka);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return 180*Math.atan2(e,d)/Math.PI}function K(a,b){return J(b[1],b[0],La)-J(a[1],a[0],La)}function L(a,b){return I(b[0],b[1],La)/I(a[0],a[1],La)}function M(){this.evEl=Na,this.evWin=Oa,this.allow=!0,this.pressed=!1,y.apply(this,arguments)}function N(){this.evEl=Ra,this.evWin=Sa,y.apply(this,arguments),this.store=this.manager.session.pointerEvents=[]}function O(){this.evTarget=Ua,this.evWin=Va,this.started=!1,y.apply(this,arguments)}function P(a,b){var c=t(a.touches),d=t(a.changedTouches);return b&(Aa|Ba)&&(c=u(c.concat(d),"identifier",!0)),[c,d]}function Q(){this.evTarget=Xa,this.targetIds={},y.apply(this,arguments)}function R(a,b){var c=t(a.touches),d=this.targetIds;if(b&(ya|za)&&1===c.length)return d[c[0].identifier]=!0,[c,c];var e,f,g=t(a.changedTouches),h=[],i=this.target;if(f=c.filter(function(a){return p(a.target,i)}),b===ya)for(e=0;e<f.length;)d[f[e].identifier]=!0,e++;for(e=0;e<g.length;)d[g[e].identifier]&&h.push(g[e]),b&(Aa|Ba)&&delete d[g[e].identifier],e++;return h.length?[u(f.concat(h),"identifier",!0),h]:void 0}function S(){y.apply(this,arguments);var a=k(this.handler,this);this.touch=new Q(this.manager,a),this.mouse=new M(this.manager,a)}function T(a,b){this.manager=a,this.set(b)}function U(a){if(q(a,bb))return bb;var b=q(a,cb),c=q(a,db);return b&&c?cb+" "+db:b||c?b?cb:db:q(a,ab)?ab:_a}function V(a){this.id=w(),this.manager=null,this.options=i(a||{},this.defaults),this.options.enable=m(this.options.enable,!0),this.state=eb,this.simultaneous={},this.requireFail=[]}function W(a){return a&jb?"cancel":a&hb?"end":a&gb?"move":a&fb?"start":""}function X(a){return a==Ga?"down":a==Fa?"up":a==Da?"left":a==Ea?"right":""}function Y(a,b){var c=b.manager;return c?c.get(a):a}function Z(){V.apply(this,arguments)}function $(){Z.apply(this,arguments),this.pX=null,this.pY=null}function _(){Z.apply(this,arguments)}function aa(){V.apply(this,arguments),this._timer=null,this._input=null}function ba(){Z.apply(this,arguments)}function ca(){Z.apply(this,arguments)}function da(){V.apply(this,arguments),this.pTime=!1,this.pCenter=!1,this._timer=null,this._input=null,this.count=0}function ea(a,b){return b=b||{},b.recognizers=m(b.recognizers,ea.defaults.preset),new fa(a,b)}function fa(a,b){b=b||{},this.options=i(b,ea.defaults),this.options.inputTarget=this.options.inputTarget||a,this.handlers={},this.session={},this.recognizers=[],this.element=a,this.input=z(this),this.touchAction=new T(this,this.options.touchAction),ga(this,!0),g(b.recognizers,function(a){var b=this.add(new a[0](a[1]));a[2]&&b.recognizeWith(a[2]),a[3]&&b.requireFailure(a[3])},this)}function ga(a,b){var c=a.element;g(a.options.cssProps,function(a,d){c.style[v(c.style,d)]=b?a:""})}function ha(a,c){var d=b.createEvent("Event");d.initEvent(a,!0,!0),d.gesture=c,c.target.dispatchEvent(d)}var ia=["","webkit","moz","MS","ms","o"],ja=b.createElement("div"),ka="function",la=Math.round,ma=Math.abs,na=Date.now,oa=1,pa=/mobile|tablet|ip(ad|hone|od)|android/i,qa="ontouchstart"in a,ra=v(a,"PointerEvent")!==d,sa=qa&&pa.test(navigator.userAgent),ta="touch",ua="pen",va="mouse",wa="kinect",xa=25,ya=1,za=2,Aa=4,Ba=8,Ca=1,Da=2,Ea=4,Fa=8,Ga=16,Ha=Da|Ea,Ia=Fa|Ga,Ja=Ha|Ia,Ka=["x","y"],La=["clientX","clientY"];y.prototype={handler:function(){},init:function(){this.evEl&&n(this.element,this.evEl,this.domHandler),this.evTarget&&n(this.target,this.evTarget,this.domHandler),this.evWin&&n(x(this.element),this.evWin,this.domHandler)},destroy:function(){this.evEl&&o(this.element,this.evEl,this.domHandler),this.evTarget&&o(this.target,this.evTarget,this.domHandler),this.evWin&&o(x(this.element),this.evWin,this.domHandler)}};var Ma={mousedown:ya,mousemove:za,mouseup:Aa},Na="mousedown",Oa="mousemove mouseup";j(M,y,{handler:function(a){var b=Ma[a.type];b&ya&&0===a.button&&(this.pressed=!0),b&za&&1!==a.which&&(b=Aa),this.pressed&&this.allow&&(b&Aa&&(this.pressed=!1),this.callback(this.manager,b,{pointers:[a],changedPointers:[a],pointerType:va,srcEvent:a}))}});var Pa={pointerdown:ya,pointermove:za,pointerup:Aa,pointercancel:Ba,pointerout:Ba},Qa={2:ta,3:ua,4:va,5:wa},Ra="pointerdown",Sa="pointermove pointerup pointercancel";a.MSPointerEvent&&(Ra="MSPointerDown",Sa="MSPointerMove MSPointerUp MSPointerCancel"),j(N,y,{handler:function(a){var b=this.store,c=!1,d=a.type.toLowerCase().replace("ms",""),e=Pa[d],f=Qa[a.pointerType]||a.pointerType,g=f==ta,h=s(b,a.pointerId,"pointerId");e&ya&&(0===a.button||g)?0>h&&(b.push(a),h=b.length-1):e&(Aa|Ba)&&(c=!0),0>h||(b[h]=a,this.callback(this.manager,e,{pointers:b,changedPointers:[a],pointerType:f,srcEvent:a}),c&&b.splice(h,1))}});var Ta={touchstart:ya,touchmove:za,touchend:Aa,touchcancel:Ba},Ua="touchstart",Va="touchstart touchmove touchend touchcancel";j(O,y,{handler:function(a){var b=Ta[a.type];if(b===ya&&(this.started=!0),this.started){var c=P.call(this,a,b);b&(Aa|Ba)&&0===c[0].length-c[1].length&&(this.started=!1),this.callback(this.manager,b,{pointers:c[0],changedPointers:c[1],pointerType:ta,srcEvent:a})}}});var Wa={touchstart:ya,touchmove:za,touchend:Aa,touchcancel:Ba},Xa="touchstart touchmove touchend touchcancel";j(Q,y,{handler:function(a){var b=Wa[a.type],c=R.call(this,a,b);c&&this.callback(this.manager,b,{pointers:c[0],changedPointers:c[1],pointerType:ta,srcEvent:a})}}),j(S,y,{handler:function(a,b,c){var d=c.pointerType==ta,e=c.pointerType==va;if(d)this.mouse.allow=!1;else if(e&&!this.mouse.allow)return;b&(Aa|Ba)&&(this.mouse.allow=!0),this.callback(a,b,c)},destroy:function(){this.touch.destroy(),this.mouse.destroy()}});var Ya=v(ja.style,"touchAction"),Za=Ya!==d,$a="compute",_a="auto",ab="manipulation",bb="none",cb="pan-x",db="pan-y";T.prototype={set:function(a){a==$a&&(a=this.compute()),Za&&(this.manager.element.style[Ya]=a),this.actions=a.toLowerCase().trim()},update:function(){this.set(this.manager.options.touchAction)},compute:function(){var a=[];return g(this.manager.recognizers,function(b){l(b.options.enable,[b])&&(a=a.concat(b.getTouchAction()))}),U(a.join(" "))},preventDefaults:function(a){if(!Za){var b=a.srcEvent,c=a.offsetDirection;if(this.manager.session.prevented)return void b.preventDefault();var d=this.actions,e=q(d,bb),f=q(d,db),g=q(d,cb);return e||f&&c&Ha||g&&c&Ia?this.preventSrc(b):void 0}},preventSrc:function(a){this.manager.session.prevented=!0,a.preventDefault()}};var eb=1,fb=2,gb=4,hb=8,ib=hb,jb=16,kb=32;V.prototype={defaults:{},set:function(a){return h(this.options,a),this.manager&&this.manager.touchAction.update(),this},recognizeWith:function(a){if(f(a,"recognizeWith",this))return this;var b=this.simultaneous;return a=Y(a,this),b[a.id]||(b[a.id]=a,a.recognizeWith(this)),this},dropRecognizeWith:function(a){return f(a,"dropRecognizeWith",this)?this:(a=Y(a,this),delete this.simultaneous[a.id],this)},requireFailure:function(a){if(f(a,"requireFailure",this))return this;var b=this.requireFail;return a=Y(a,this),-1===s(b,a)&&(b.push(a),a.requireFailure(this)),this},dropRequireFailure:function(a){if(f(a,"dropRequireFailure",this))return this;a=Y(a,this);var b=s(this.requireFail,a);return b>-1&&this.requireFail.splice(b,1),this},hasRequireFailures:function(){return this.requireFail.length>0},canRecognizeWith:function(a){return!!this.simultaneous[a.id]},emit:function(a){function b(b){c.manager.emit(c.options.event+(b?W(d):""),a)}var c=this,d=this.state;hb>d&&b(!0),b(),d>=hb&&b(!0)},tryEmit:function(a){return this.canEmit()?this.emit(a):void(this.state=kb)},canEmit:function(){for(var a=0;a<this.requireFail.length;){if(!(this.requireFail[a].state&(kb|eb)))return!1;a++}return!0},recognize:function(a){var b=h({},a);return l(this.options.enable,[this,b])?(this.state&(ib|jb|kb)&&(this.state=eb),this.state=this.process(b),void(this.state&(fb|gb|hb|jb)&&this.tryEmit(b))):(this.reset(),void(this.state=kb))},process:function(){},getTouchAction:function(){},reset:function(){}},j(Z,V,{defaults:{pointers:1},attrTest:function(a){var b=this.options.pointers;return 0===b||a.pointers.length===b},process:function(a){var b=this.state,c=a.eventType,d=b&(fb|gb),e=this.attrTest(a);return d&&(c&Ba||!e)?b|jb:d||e?c&Aa?b|hb:b&fb?b|gb:fb:kb}}),j($,Z,{defaults:{event:"pan",threshold:10,pointers:1,direction:Ja},getTouchAction:function(){var a=this.options.direction,b=[];return a&Ha&&b.push(db),a&Ia&&b.push(cb),b},directionTest:function(a){var b=this.options,c=!0,d=a.distance,e=a.direction,f=a.deltaX,g=a.deltaY;return e&b.direction||(b.direction&Ha?(e=0===f?Ca:0>f?Da:Ea,c=f!=this.pX,d=Math.abs(a.deltaX)):(e=0===g?Ca:0>g?Fa:Ga,c=g!=this.pY,d=Math.abs(a.deltaY))),a.direction=e,c&&d>b.threshold&&e&b.direction},attrTest:function(a){return Z.prototype.attrTest.call(this,a)&&(this.state&fb||!(this.state&fb)&&this.directionTest(a))},emit:function(a){this.pX=a.deltaX,this.pY=a.deltaY;var b=X(a.direction);b&&this.manager.emit(this.options.event+b,a),this._super.emit.call(this,a)}}),j(_,Z,{defaults:{event:"pinch",threshold:0,pointers:2},getTouchAction:function(){return[bb]},attrTest:function(a){return this._super.attrTest.call(this,a)&&(Math.abs(a.scale-1)>this.options.threshold||this.state&fb)},emit:function(a){if(this._super.emit.call(this,a),1!==a.scale){var b=a.scale<1?"in":"out";this.manager.emit(this.options.event+b,a)}}}),j(aa,V,{defaults:{event:"press",pointers:1,time:500,threshold:5},getTouchAction:function(){return[_a]},process:function(a){var b=this.options,c=a.pointers.length===b.pointers,d=a.distance<b.threshold,f=a.deltaTime>b.time;if(this._input=a,!d||!c||a.eventType&(Aa|Ba)&&!f)this.reset();else if(a.eventType&ya)this.reset(),this._timer=e(function(){this.state=ib,this.tryEmit()},b.time,this);else if(a.eventType&Aa)return ib;return kb},reset:function(){clearTimeout(this._timer)},emit:function(a){this.state===ib&&(a&&a.eventType&Aa?this.manager.emit(this.options.event+"up",a):(this._input.timeStamp=na(),this.manager.emit(this.options.event,this._input)))}}),j(ba,Z,{defaults:{event:"rotate",threshold:0,pointers:2},getTouchAction:function(){return[bb]},attrTest:function(a){return this._super.attrTest.call(this,a)&&(Math.abs(a.rotation)>this.options.threshold||this.state&fb)}}),j(ca,Z,{defaults:{event:"swipe",threshold:10,velocity:.65,direction:Ha|Ia,pointers:1},getTouchAction:function(){return $.prototype.getTouchAction.call(this)},attrTest:function(a){var b,c=this.options.direction;return c&(Ha|Ia)?b=a.velocity:c&Ha?b=a.velocityX:c&Ia&&(b=a.velocityY),this._super.attrTest.call(this,a)&&c&a.direction&&a.distance>this.options.threshold&&ma(b)>this.options.velocity&&a.eventType&Aa},emit:function(a){var b=X(a.direction);b&&this.manager.emit(this.options.event+b,a),this.manager.emit(this.options.event,a)}}),j(da,V,{defaults:{event:"tap",pointers:1,taps:1,interval:300,time:250,threshold:2,posThreshold:10},getTouchAction:function(){return[ab]},process:function(a){var b=this.options,c=a.pointers.length===b.pointers,d=a.distance<b.threshold,f=a.deltaTime<b.time;if(this.reset(),a.eventType&ya&&0===this.count)return this.failTimeout();if(d&&f&&c){if(a.eventType!=Aa)return this.failTimeout();var g=!this.pTime||a.timeStamp-this.pTime<b.interval,h=!this.pCenter||I(this.pCenter,a.center)<b.posThreshold;this.pTime=a.timeStamp,this.pCenter=a.center,h&&g?this.count+=1:this.count=1,this._input=a;var i=this.count%b.taps;if(0===i)return this.hasRequireFailures()?(this._timer=e(function(){this.state=ib,this.tryEmit()},b.interval,this),fb):ib}return kb},failTimeout:function(){return this._timer=e(function(){this.state=kb},this.options.interval,this),kb},reset:function(){clearTimeout(this._timer)},emit:function(){this.state==ib&&(this._input.tapCount=this.count,this.manager.emit(this.options.event,this._input))}}),ea.VERSION="2.0.4",ea.defaults={domEvents:!1,touchAction:$a,enable:!0,inputTarget:null,inputClass:null,preset:[[ba,{enable:!1}],[_,{enable:!1},["rotate"]],[ca,{direction:Ha}],[$,{direction:Ha},["swipe"]],[da],[da,{event:"doubletap",taps:2},["tap"]],[aa]],cssProps:{userSelect:"default",touchSelect:"none",touchCallout:"none",contentZooming:"none",userDrag:"none",tapHighlightColor:"rgba(0,0,0,0)"}};var lb=1,mb=2;fa.prototype={set:function(a){return h(this.options,a),a.touchAction&&this.touchAction.update(),a.inputTarget&&(this.input.destroy(),this.input.target=a.inputTarget,this.input.init()),this},stop:function(a){this.session.stopped=a?mb:lb},recognize:function(a){var b=this.session;if(!b.stopped){this.touchAction.preventDefaults(a);var c,d=this.recognizers,e=b.curRecognizer;(!e||e&&e.state&ib)&&(e=b.curRecognizer=null);for(var f=0;f<d.length;)c=d[f],b.stopped===mb||e&&c!=e&&!c.canRecognizeWith(e)?c.reset():c.recognize(a),!e&&c.state&(fb|gb|hb)&&(e=b.curRecognizer=c),f++}},get:function(a){if(a instanceof V)return a;for(var b=this.recognizers,c=0;c<b.length;c++)if(b[c].options.event==a)return b[c];return null},add:function(a){if(f(a,"add",this))return this;var b=this.get(a.options.event);return b&&this.remove(b),this.recognizers.push(a),a.manager=this,this.touchAction.update(),a},remove:function(a){if(f(a,"remove",this))return this;var b=this.recognizers;return a=this.get(a),b.splice(s(b,a),1),this.touchAction.update(),this},on:function(a,b){var c=this.handlers;return g(r(a),function(a){c[a]=c[a]||[],c[a].push(b)}),this},off:function(a,b){var c=this.handlers;return g(r(a),function(a){b?c[a].splice(s(c[a],b),1):delete c[a]}),this},emit:function(a,b){this.options.domEvents&&ha(a,b);var c=this.handlers[a]&&this.handlers[a].slice();if(c&&c.length){b.type=a,b.preventDefault=function(){b.srcEvent.preventDefault()};for(var d=0;d<c.length;)c[d](b),d++}},destroy:function(){this.element&&ga(this,!1),this.handlers={},this.session={},this.input.destroy(),this.element=null}},h(ea,{INPUT_START:ya,INPUT_MOVE:za,INPUT_END:Aa,INPUT_CANCEL:Ba,STATE_POSSIBLE:eb,STATE_BEGAN:fb,STATE_CHANGED:gb,STATE_ENDED:hb,STATE_RECOGNIZED:ib,STATE_CANCELLED:jb,STATE_FAILED:kb,DIRECTION_NONE:Ca,DIRECTION_LEFT:Da,DIRECTION_RIGHT:Ea,DIRECTION_UP:Fa,DIRECTION_DOWN:Ga,DIRECTION_HORIZONTAL:Ha,DIRECTION_VERTICAL:Ia,DIRECTION_ALL:Ja,Manager:fa,Input:y,TouchAction:T,TouchInput:Q,MouseInput:M,PointerEventInput:N,TouchMouseInput:S,SingleTouchInput:O,Recognizer:V,AttrRecognizer:Z,Tap:da,Pan:$,Swipe:ca,Pinch:_,Rotate:ba,Press:aa,on:n,off:o,each:g,merge:i,extend:h,inherit:j,bindFn:k,prefixed:v}),typeof define==ka&&define.amd?define(function(){return ea}):"undefined"!=typeof module&&module.exports?module.exports=ea:a[c]=ea}(window,document,"Hammer"),function(a){"function"==typeof define&&define.amd?define(["jquery","hammerjs"],a):"object"==typeof exports?a(require("jquery"),require("hammerjs")):a(jQuery,Hammer)}(function(a,b){function c(c,d){var e=a(c);e.data("hammer")||e.data("hammer",new b(e[0],d))}a.fn.hammer=function(a){return this.each(function(){c(this,a)})},b.Manager.prototype.emit=function(b){return function(c,d){b.call(this,c,d),a(this.element).trigger({type:c,gesture:d})}}(b.Manager.prototype.emit)}),function(a){a.Package?Materialize={}:a.Materialize={}}(window),function(a){for(var b=0,c=["webkit","moz"],d=a.requestAnimationFrame,e=a.cancelAnimationFrame,f=c.length;--f>=0&&!d;)d=a[c[f]+"RequestAnimationFrame"],e=a[c[f]+"CancelRequestAnimationFrame"];d&&e||(d=function(a){var c=+Date.now(),d=Math.max(b+16,c);return setTimeout(function(){a(b=d)},d-c)},e=clearTimeout),a.requestAnimationFrame=d,a.cancelAnimationFrame=e}(window),Materialize.objectSelectorString=function(a){var b=a.prop("tagName")||"",c=a.attr("id")||"",d=a.attr("class")||"";return(b+c+d).replace(/\s/g,"")},Materialize.guid=function(){function a(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)}return function(){return a()+a()+"-"+a()+"-"+a()+"-"+a()+"-"+a()+a()+a()}}(),Materialize.escapeHash=function(a){return a.replace(/(:|\.|\[|\]|,|=)/g,"\\$1")},Materialize.elementOrParentIsFixed=function(a){var b=$(a),c=b.add(b.parents()),d=!1;return c.each(function(){if("fixed"===$(this).css("position"))return d=!0,!1}),d};var getTime=Date.now||function(){return(new Date).getTime()};Materialize.throttle=function(a,b,c){var d,e,f,g=null,h=0;c||(c={});var i=function(){h=c.leading===!1?0:getTime(),g=null,f=a.apply(d,e),d=e=null};return function(){var j=getTime();h||c.leading!==!1||(h=j);var k=b-(j-h);return d=this,e=arguments,k<=0?(clearTimeout(g),g=null,h=j,f=a.apply(d,e),d=e=null):g||c.trailing===!1||(g=setTimeout(i,k)),f}};var Vel;Vel=jQuery?jQuery.Velocity:$?$.Velocity:Velocity,function(a){a.fn.collapsible=function(b,c){var d={accordion:void 0,onOpen:void 0,onClose:void 0},e=b;return b=a.extend(d,b),this.each(function(){function d(b){m=l.find("> li > .collapsible-header"),b.hasClass("active")?b.parent().addClass("active"):b.parent().removeClass("active"),b.parent().hasClass("active")?b.siblings(".collapsible-body").stop(!0,!1).slideDown({duration:350,easing:"easeOutQuart",queue:!1,complete:function(){a(this).css("height","")}}):b.siblings(".collapsible-body").stop(!0,!1).slideUp({duration:350,easing:"easeOutQuart",queue:!1,complete:function(){a(this).css("height","")}}),m.not(b).removeClass("active").parent().removeClass("active"),m.not(b).parent().children(".collapsible-body").stop(!0,!1).each(function(){a(this).is(":visible")&&a(this).slideUp({duration:350,easing:"easeOutQuart",queue:!1,complete:function(){a(this).css("height",""),h(a(this).siblings(".collapsible-header"))}})})}function f(b){b.hasClass("active")?b.parent().addClass("active"):b.parent().removeClass("active"),b.parent().hasClass("active")?b.siblings(".collapsible-body").stop(!0,!1).slideDown({duration:350,easing:"easeOutQuart",queue:!1,complete:function(){a(this).css("height","")}}):b.siblings(".collapsible-body").stop(!0,!1).slideUp({duration:350,easing:"easeOutQuart",queue:!1,complete:function(){a(this).css("height","")}})}function g(a,c){c||a.toggleClass("active"),b.accordion||"accordion"===n||void 0===n?d(a):f(a),h(a)}function h(a){a.hasClass("active")?"function"==typeof b.onOpen&&b.onOpen.call(this,a.parent()):"function"==typeof b.onClose&&b.onClose.call(this,a.parent())}function i(a){var b=j(a);return b.length>0}function j(a){return a.closest("li > .collapsible-header")}function k(){l.off("click.collapse","> li > .collapsible-header")}var l=a(this),m=a(this).find("> li > .collapsible-header"),n=l.data("collapsible");if("destroy"===e)return void k();if(c>=0&&c<m.length){var o=m.eq(c);return void(o.length&&("open"===e||"close"===e&&o.hasClass("active"))&&g(o))}k(),l.on("click.collapse","> li > .collapsible-header",function(b){var c=a(b.target);i(c)&&(c=j(c)),g(c)}),b.accordion||"accordion"===n||void 0===n?g(m.filter(".active").first(),!0):m.filter(".active").each(function(){g(a(this),!0)})})},a(document).ready(function(){a(".collapsible").collapsible()})}(jQuery),function(a){a.fn.scrollTo=function(b){return a(this).scrollTop(a(this).scrollTop()-a(this).offset().top+a(b).offset().top),this},a.fn.dropdown=function(b){var c={inDuration:300,outDuration:225,constrainWidth:!0,hover:!1,gutter:0,belowOrigin:!1,alignment:"left",stopPropagation:!1};return"open"===b?(this.each(function(){a(this).trigger("open")}),!1):"close"===b?(this.each(function(){a(this).trigger("close")}),!1):void this.each(function(){function d(){void 0!==g.data("induration")&&(h.inDuration=g.data("induration")),void 0!==g.data("outduration")&&(h.outDuration=g.data("outduration")),void 0!==g.data("constrainwidth")&&(h.constrainWidth=g.data("constrainwidth")),void 0!==g.data("hover")&&(h.hover=g.data("hover")),void 0!==g.data("gutter")&&(h.gutter=g.data("gutter")),void 0!==g.data("beloworigin")&&(h.belowOrigin=g.data("beloworigin")),void 0!==g.data("alignment")&&(h.alignment=g.data("alignment")),void 0!==g.data("stoppropagation")&&(h.stopPropagation=g.data("stoppropagation"))}function e(b){"focus"===b&&(i=!0),d(),j.addClass("active"),g.addClass("active"),h.constrainWidth===!0?j.css("width",g.outerWidth()):j.css("white-space","nowrap");var c=window.innerHeight,e=g.innerHeight(),k=g.offset().left,l=g.offset().top-a(window).scrollTop(),m=h.alignment,n=0,o=0,p=0;h.belowOrigin===!0&&(p=e);var q=0,r=0,s=g.parent();if(s.is("body")||(s[0].scrollHeight>s[0].clientHeight&&(q=s[0].scrollTop),s[0].scrollWidth>s[0].clientWidth&&(r=s[0].scrollLeft)),k+j.innerWidth()>a(window).width()?m="right":k-j.innerWidth()+g.innerWidth()<0&&(m="left"),l+j.innerHeight()>c)if(l+e-j.innerHeight()<0){var t=c-l-p;j.css("max-height",t)}else p||(p+=e),p-=j.innerHeight();if("left"===m)n=h.gutter,o=g.position().left+n;else if("right"===m){var u=g.position().left+g.outerWidth()-j.outerWidth();n=-h.gutter,o=u+n}j.css({position:"absolute",top:g.position().top+p+q,left:o+r}),j.stop(!0,!0).css("opacity",0).slideDown({queue:!1,duration:h.inDuration,easing:"easeOutCubic",complete:function(){a(this).css("height","")}}).animate({opacity:1},{queue:!1,duration:h.inDuration,easing:"easeOutSine"}),setTimeout(function(){a(document).bind("click."+j.attr("id"),function(b){f(),a(document).unbind("click."+j.attr("id"))})},0)}function f(){i=!1,j.fadeOut(h.outDuration),j.removeClass("active"),g.removeClass("active"),a(document).unbind("click."+j.attr("id")),setTimeout(function(){j.css("max-height","")},h.outDuration)}var g=a(this),h=a.extend({},c,b),i=!1,j=a("#"+g.attr("data-activates"));if(d(),g.after(j),h.hover){var k=!1;g.unbind("click."+g.attr("id")),g.on("mouseenter",function(a){k===!1&&(e(),k=!0)}),g.on("mouseleave",function(b){var c=b.toElement||b.relatedTarget;a(c).closest(".dropdown-content").is(j)||(j.stop(!0,!0),f(),k=!1)}),j.on("mouseleave",function(b){var c=b.toElement||b.relatedTarget;a(c).closest(".dropdown-button").is(g)||(j.stop(!0,!0),f(),k=!1)})}else g.unbind("click."+g.attr("id")),g.bind("click."+g.attr("id"),function(b){i||(g[0]!=b.currentTarget||g.hasClass("active")||0!==a(b.target).closest(".dropdown-content").length?g.hasClass("active")&&(f(),a(document).unbind("click."+j.attr("id"))):(b.preventDefault(),h.stopPropagation&&b.stopPropagation(),e("click")))});g.on("open",function(a,b){e(b)}),g.on("close",f)})},a(document).ready(function(){a(".dropdown-button").dropdown()})}(jQuery),function(a){
8
+ var b=0,c=0,d=function(){return c++,"materialize-modal-overlay-"+c},e={init:function(c){var e={opacity:.5,inDuration:350,outDuration:250,ready:void 0,complete:void 0,dismissible:!0,startingTop:"4%",endingTop:"10%"};return c=a.extend(e,c),this.each(function(){var e=a(this),f=a(this).attr("id")||"#"+a(this).data("target"),g=function(){var d=e.data("overlay-id"),f=a("#"+d);e.removeClass("open"),a("body").css({overflow:"",width:""}),e.find(".modal-close").off("click.close"),a(document).off("keyup.modal"+d),f.velocity({opacity:0},{duration:c.outDuration,queue:!1,ease:"easeOutQuart"});var g={duration:c.outDuration,queue:!1,ease:"easeOutCubic",complete:function(){a(this).css({display:"none"}),"function"==typeof c.complete&&c.complete.call(this,e),f.remove(),b--}};e.hasClass("bottom-sheet")?e.velocity({bottom:"-100%",opacity:0},g):e.velocity({top:c.startingTop,opacity:0,scaleX:.7},g)},h=function(f){var h=a("body"),i=h.innerWidth();if(h.css("overflow","hidden"),h.width(i),!e.hasClass("open")){var j=d(),k=a('<div class="modal-overlay"></div>');lStack=++b,k.attr("id",j).css("z-index",1e3+2*lStack),e.data("overlay-id",j).css("z-index",1e3+2*lStack+1),e.addClass("open"),a("body").append(k),c.dismissible&&(k.click(function(){g()}),a(document).on("keyup.modal"+j,function(a){27===a.keyCode&&g()})),e.find(".modal-close").on("click.close",function(a){g()}),k.css({display:"block",opacity:0}),e.css({display:"block",opacity:0}),k.velocity({opacity:c.opacity},{duration:c.inDuration,queue:!1,ease:"easeOutCubic"}),e.data("associated-overlay",k[0]);var l={duration:c.inDuration,queue:!1,ease:"easeOutCubic",complete:function(){"function"==typeof c.ready&&c.ready.call(this,e,f)}};e.hasClass("bottom-sheet")?e.velocity({bottom:"0",opacity:1},l):(a.Velocity.hook(e,"scaleX",.7),e.css({top:c.startingTop}),e.velocity({top:c.endingTop,opacity:1,scaleX:"1"},l))}};a(document).off("click.modalTrigger",'a[href="#'+f+'"], [data-target="'+f+'"]'),a(this).off("openModal"),a(this).off("closeModal"),a(document).on("click.modalTrigger",'a[href="#'+f+'"], [data-target="'+f+'"]',function(b){c.startingTop=(a(this).offset().top-a(window).scrollTop())/1.15,h(a(this)),b.preventDefault()}),a(this).on("openModal",function(){a(this).attr("href")||"#"+a(this).data("target");h()}),a(this).on("closeModal",function(){g()})})},open:function(){a(this).trigger("openModal")},close:function(){a(this).trigger("closeModal")}};a.fn.modal=function(b){return e[b]?e[b].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof b&&b?void a.error("Method "+b+" does not exist on jQuery.modal"):e.init.apply(this,arguments)}}(jQuery),function(a){a.fn.materialbox=function(){return this.each(function(){function b(){f=!1;var b=i.parent(".material-placeholder"),d=(window.innerWidth,window.innerHeight,i.data("width")),g=i.data("height");i.velocity("stop",!0),a("#materialbox-overlay").velocity("stop",!0),a(".materialbox-caption").velocity("stop",!0),a("#materialbox-overlay").velocity({opacity:0},{duration:h,queue:!1,easing:"easeOutQuad",complete:function(){e=!1,a(this).remove()}}),i.velocity({width:d,height:g,left:0,top:0},{duration:h,queue:!1,easing:"easeOutQuad",complete:function(){b.css({height:"",width:"",position:"",top:"",left:""}),i.removeAttr("style"),i.attr("style",k),i.removeClass("active"),f=!0,c&&c.css("overflow","")}}),a(".materialbox-caption").velocity({opacity:0},{duration:h,queue:!1,easing:"easeOutQuad",complete:function(){a(this).remove()}})}if(!a(this).hasClass("initialized")){a(this).addClass("initialized");var c,d,e=!1,f=!0,g=275,h=200,i=a(this),j=a("<div></div>").addClass("material-placeholder"),k=i.attr("style");i.wrap(j),i.on("click",function(){var h=i.parent(".material-placeholder"),j=window.innerWidth,k=window.innerHeight,l=i.width(),m=i.height();if(f===!1)return b(),!1;if(e&&f===!0)return b(),!1;f=!1,i.addClass("active"),e=!0,h.css({width:h[0].getBoundingClientRect().width,height:h[0].getBoundingClientRect().height,position:"relative",top:0,left:0}),c=void 0,d=h[0].parentNode;for(;null!==d&&!a(d).is(document);){var n=a(d);"visible"!==n.css("overflow")&&(n.css("overflow","visible"),c=void 0===c?n:c.add(n)),d=d.parentNode}i.css({position:"absolute","z-index":1e3,"will-change":"left, top, width, height"}).data("width",l).data("height",m);var o=a('<div id="materialbox-overlay"></div>').css({opacity:0}).click(function(){f===!0&&b()});i.before(o);var p=o[0].getBoundingClientRect();if(o.css({width:j,height:k,left:-1*p.left,top:-1*p.top}),o.velocity({opacity:1},{duration:g,queue:!1,easing:"easeOutQuad"}),""!==i.data("caption")){var q=a('<div class="materialbox-caption"></div>');q.text(i.data("caption")),a("body").append(q),q.css({display:"inline"}),q.velocity({opacity:1},{duration:g,queue:!1,easing:"easeOutQuad"})}var r=0,s=l/j,t=m/k,u=0,v=0;s>t?(r=m/l,u=.9*j,v=.9*j*r):(r=l/m,u=.9*k*r,v=.9*k),i.hasClass("responsive-img")?i.velocity({"max-width":u,width:l},{duration:0,queue:!1,complete:function(){i.css({left:0,top:0}).velocity({height:v,width:u,left:a(document).scrollLeft()+j/2-i.parent(".material-placeholder").offset().left-u/2,top:a(document).scrollTop()+k/2-i.parent(".material-placeholder").offset().top-v/2},{duration:g,queue:!1,easing:"easeOutQuad",complete:function(){f=!0}})}}):i.css("left",0).css("top",0).velocity({height:v,width:u,left:a(document).scrollLeft()+j/2-i.parent(".material-placeholder").offset().left-u/2,top:a(document).scrollTop()+k/2-i.parent(".material-placeholder").offset().top-v/2},{duration:g,queue:!1,easing:"easeOutQuad",complete:function(){f=!0}})}),a(window).scroll(function(){e&&b()}),a(document).keyup(function(a){27===a.keyCode&&f===!0&&e&&b()})}})},a(document).ready(function(){a(".materialboxed").materialbox()})}(jQuery),function(a){a.fn.parallax=function(){var b=a(window).width();return this.each(function(c){function d(c){var d;d=b<601?e.height()>0?e.height():e.children("img").height():e.height()>0?e.height():500;var f=e.children("img").first(),g=f.height(),h=g-d,i=e.offset().top+d,j=e.offset().top,k=a(window).scrollTop(),l=window.innerHeight,m=k+l,n=(m-j)/(d+l),o=Math.round(h*n);c&&f.css("display","block"),i>k&&j<k+l&&f.css("transform","translate3D(-50%,"+o+"px, 0)")}var e=a(this);e.addClass("parallax"),e.children("img").one("load",function(){d(!0)}).each(function(){this.complete&&a(this).trigger("load")}),a(window).scroll(function(){b=a(window).width(),d(!1)}),a(window).resize(function(){b=a(window).width(),d(!1)})})}}(jQuery),function(a){var b={init:function(b){var c={onShow:null,swipeable:!1,responsiveThreshold:1/0};b=a.extend(c,b);var d=Materialize.objectSelectorString(a(this));return this.each(function(c){var e,f,g,h,i,j=d+c,k=a(this),l=a(window).width(),m=k.find("li.tab a"),n=k.width(),o=a(),p=Math.max(n,k[0].scrollWidth)/m.length,q=prev_index=0,r=!1,s=300,t=function(a){return Math.ceil(n-a.position().left-a.outerWidth()-k.scrollLeft())},u=function(a){return Math.floor(a.position().left+k.scrollLeft())},v=function(a){q-a>=0?(h.velocity({right:t(e)},{duration:s,queue:!1,easing:"easeOutQuad"}),h.velocity({left:u(e)},{duration:s,queue:!1,easing:"easeOutQuad",delay:90})):(h.velocity({left:u(e)},{duration:s,queue:!1,easing:"easeOutQuad"}),h.velocity({right:t(e)},{duration:s,queue:!1,easing:"easeOutQuad",delay:90}))};b.swipeable&&l>b.responsiveThreshold&&(b.swipeable=!1),e=a(m.filter('[href="'+location.hash+'"]')),0===e.length&&(e=a(this).find("li.tab a.active").first()),0===e.length&&(e=a(this).find("li.tab a").first()),e.addClass("active"),q=m.index(e),q<0&&(q=0),void 0!==e[0]&&(f=a(e[0].hash),f.addClass("active")),k.find(".indicator").length||k.append('<div class="indicator"></div>'),h=k.find(".indicator"),k.append(h),k.is(":visible")&&setTimeout(function(){h.css({right:t(e)}),h.css({left:u(e)})},0),a(window).off("resize.tabs-"+j).on("resize.tabs-"+j,function(){n=k.width(),p=Math.max(n,k[0].scrollWidth)/m.length,q<0&&(q=0),0!==p&&0!==n&&(h.css({right:t(e)}),h.css({left:u(e)}))}),b.swipeable?(m.each(function(){var b=a(Materialize.escapeHash(this.hash));b.addClass("carousel-item"),o=o.add(b)}),g=o.wrapAll('<div class="tabs-content carousel"></div>'),o.css("display",""),a(".tabs-content.carousel").carousel({fullWidth:!0,noWrap:!0,onCycleTo:function(a){if(!r){var b=q;q=g.index(a),e=m.eq(q),v(b)}}})):m.not(e).each(function(){a(Materialize.escapeHash(this.hash)).hide()}),k.off("click.tabs").on("click.tabs","a",function(c){if(a(this).parent().hasClass("disabled"))return void c.preventDefault();if(!a(this).attr("target")){r=!0,n=k.width(),p=Math.max(n,k[0].scrollWidth)/m.length,e.removeClass("active");var d=f;e=a(this),f=a(Materialize.escapeHash(this.hash)),m=k.find("li.tab a");e.position();e.addClass("active"),prev_index=q,q=m.index(a(this)),q<0&&(q=0),b.swipeable?o.length&&o.carousel("set",q):(void 0!==f&&(f.show(),f.addClass("active"),"function"==typeof b.onShow&&b.onShow.call(this,f)),void 0===d||d.is(f)||(d.hide(),d.removeClass("active"))),i=setTimeout(function(){r=!1},s),v(prev_index),c.preventDefault()}})})},select_tab:function(a){this.find('a[href="#'+a+'"]').trigger("click")}};a.fn.tabs=function(c){return b[c]?b[c].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof c&&c?void a.error("Method "+c+" does not exist on jQuery.tabs"):b.init.apply(this,arguments)},a(document).ready(function(){a("ul.tabs").tabs()})}(jQuery),function(a){a.fn.tooltip=function(c){var d=5,e={delay:350,tooltip:"",position:"bottom",html:!1};return"remove"===c?(this.each(function(){a("#"+a(this).attr("data-tooltip-id")).remove(),a(this).off("mouseenter.tooltip mouseleave.tooltip")}),!1):(c=a.extend(e,c),this.each(function(){var e=Materialize.guid(),f=a(this);f.attr("data-tooltip-id")&&a("#"+f.attr("data-tooltip-id")).remove(),f.attr("data-tooltip-id",e);var g,h,i,j,k,l,m=function(){g=f.attr("data-html")?"true"===f.attr("data-html"):c.html,h=f.attr("data-delay"),h=void 0===h||""===h?c.delay:h,i=f.attr("data-position"),i=void 0===i||""===i?c.position:i,j=f.attr("data-tooltip"),j=void 0===j||""===j?c.tooltip:j};m();var n=function(){var b=a('<div class="material-tooltip"></div>');return j=g?a("<span></span>").html(j):a("<span></span>").text(j),b.append(j).appendTo(a("body")).attr("id",e),l=a('<div class="backdrop"></div>'),l.appendTo(b),b};k=n(),f.off("mouseenter.tooltip mouseleave.tooltip");var o,p=!1;f.on({"mouseenter.tooltip":function(a){var c=function(){m(),p=!0,k.velocity("stop"),l.velocity("stop"),k.css({visibility:"visible",left:"0px",top:"0px"});var a,c,e,g=f.outerWidth(),h=f.outerHeight(),j=k.outerHeight(),n=k.outerWidth(),o="0px",q="0px",r=l[0].offsetWidth,s=l[0].offsetHeight,t=8,u=8,v=0;"top"===i?(a=f.offset().top-j-d,c=f.offset().left+g/2-n/2,e=b(c,a,n,j),o="-10px",l.css({bottom:0,left:0,borderRadius:"14px 14px 0 0",transformOrigin:"50% 100%",marginTop:j,marginLeft:n/2-r/2})):"left"===i?(a=f.offset().top+h/2-j/2,c=f.offset().left-n-d,e=b(c,a,n,j),q="-10px",l.css({top:"-7px",right:0,width:"14px",height:"14px",borderRadius:"14px 0 0 14px",transformOrigin:"95% 50%",marginTop:j/2,marginLeft:n})):"right"===i?(a=f.offset().top+h/2-j/2,c=f.offset().left+g+d,e=b(c,a,n,j),q="+10px",l.css({top:"-7px",left:0,width:"14px",height:"14px",borderRadius:"0 14px 14px 0",transformOrigin:"5% 50%",marginTop:j/2,marginLeft:"0px"})):(a=f.offset().top+f.outerHeight()+d,c=f.offset().left+g/2-n/2,e=b(c,a,n,j),o="+10px",l.css({top:0,left:0,marginLeft:n/2-r/2})),k.css({top:e.y,left:e.x}),t=Math.SQRT2*n/parseInt(r),u=Math.SQRT2*j/parseInt(s),v=Math.max(t,u),k.velocity({translateY:o,translateX:q},{duration:350,queue:!1}).velocity({opacity:1},{duration:300,delay:50,queue:!1}),l.css({visibility:"visible"}).velocity({opacity:1},{duration:55,delay:0,queue:!1}).velocity({scaleX:v,scaleY:v},{duration:300,delay:0,queue:!1,easing:"easeInOutQuad"})};o=setTimeout(c,h)},"mouseleave.tooltip":function(){p=!1,clearTimeout(o),setTimeout(function(){p!==!0&&(k.velocity({opacity:0,translateY:0,translateX:0},{duration:225,queue:!1}),l.velocity({opacity:0,scaleX:1,scaleY:1},{duration:225,queue:!1,complete:function(){l.css({visibility:"hidden"}),k.css({visibility:"hidden"}),p=!1}}))},225)}})}))};var b=function(b,c,d,e){var f=b,g=c;return f<0?f=4:f+d>window.innerWidth&&(f-=f+d-window.innerWidth),g<0?g=4:g+e>window.innerHeight+a(window).scrollTop&&(g-=g+e-window.innerHeight),{x:f,y:g}};a(document).ready(function(){a(".tooltipped").tooltip()})}(jQuery),function(a){"use strict";function b(a){return null!==a&&a===a.window}function c(a){return b(a)?a:9===a.nodeType&&a.defaultView}function d(a){var b,d,e={top:0,left:0},f=a&&a.ownerDocument;return b=f.documentElement,"undefined"!=typeof a.getBoundingClientRect&&(e=a.getBoundingClientRect()),d=c(f),{top:e.top+d.pageYOffset-b.clientTop,left:e.left+d.pageXOffset-b.clientLeft}}function e(a){var b="";for(var c in a)a.hasOwnProperty(c)&&(b+=c+":"+a[c]+";");return b}function f(a){if(k.allowEvent(a)===!1)return null;for(var b=null,c=a.target||a.srcElement;null!==c.parentElement;){if(!(c instanceof SVGElement||c.className.indexOf("waves-effect")===-1)){b=c;break}if(c.classList.contains("waves-effect")){b=c;break}c=c.parentElement}return b}function g(b){var c=f(b);null!==c&&(j.show(b,c),"ontouchstart"in a&&(c.addEventListener("touchend",j.hide,!1),c.addEventListener("touchcancel",j.hide,!1)),c.addEventListener("mouseup",j.hide,!1),c.addEventListener("mouseleave",j.hide,!1))}var h=h||{},i=document.querySelectorAll.bind(document),j={duration:750,show:function(a,b){if(2===a.button)return!1;var c=b||this,f=document.createElement("div");f.className="waves-ripple",c.appendChild(f);var g=d(c),h=a.pageY-g.top,i=a.pageX-g.left,k="scale("+c.clientWidth/100*10+")";"touches"in a&&(h=a.touches[0].pageY-g.top,i=a.touches[0].pageX-g.left),f.setAttribute("data-hold",Date.now()),f.setAttribute("data-scale",k),f.setAttribute("data-x",i),f.setAttribute("data-y",h);var l={top:h+"px",left:i+"px"};f.className=f.className+" waves-notransition",f.setAttribute("style",e(l)),f.className=f.className.replace("waves-notransition",""),l["-webkit-transform"]=k,l["-moz-transform"]=k,l["-ms-transform"]=k,l["-o-transform"]=k,l.transform=k,l.opacity="1",l["-webkit-transition-duration"]=j.duration+"ms",l["-moz-transition-duration"]=j.duration+"ms",l["-o-transition-duration"]=j.duration+"ms",l["transition-duration"]=j.duration+"ms",l["-webkit-transition-timing-function"]="cubic-bezier(0.250, 0.460, 0.450, 0.940)",l["-moz-transition-timing-function"]="cubic-bezier(0.250, 0.460, 0.450, 0.940)",l["-o-transition-timing-function"]="cubic-bezier(0.250, 0.460, 0.450, 0.940)",l["transition-timing-function"]="cubic-bezier(0.250, 0.460, 0.450, 0.940)",f.setAttribute("style",e(l))},hide:function(a){k.touchup(a);var b=this,c=(1.4*b.clientWidth,null),d=b.getElementsByClassName("waves-ripple");if(!(d.length>0))return!1;c=d[d.length-1];var f=c.getAttribute("data-x"),g=c.getAttribute("data-y"),h=c.getAttribute("data-scale"),i=Date.now()-Number(c.getAttribute("data-hold")),l=350-i;l<0&&(l=0),setTimeout(function(){var a={top:g+"px",left:f+"px",opacity:"0","-webkit-transition-duration":j.duration+"ms","-moz-transition-duration":j.duration+"ms","-o-transition-duration":j.duration+"ms","transition-duration":j.duration+"ms","-webkit-transform":h,"-moz-transform":h,"-ms-transform":h,"-o-transform":h,transform:h};c.setAttribute("style",e(a)),setTimeout(function(){try{b.removeChild(c)}catch(a){return!1}},j.duration)},l)},wrapInput:function(a){for(var b=0;b<a.length;b++){var c=a[b];if("input"===c.tagName.toLowerCase()){var d=c.parentNode;if("i"===d.tagName.toLowerCase()&&d.className.indexOf("waves-effect")!==-1)continue;var e=document.createElement("i");e.className=c.className+" waves-input-wrapper";var f=c.getAttribute("style");f||(f=""),e.setAttribute("style",f),c.className="waves-button-input",c.removeAttribute("style"),d.replaceChild(e,c),e.appendChild(c)}}}},k={touches:0,allowEvent:function(a){var b=!0;return"touchstart"===a.type?k.touches+=1:"touchend"===a.type||"touchcancel"===a.type?setTimeout(function(){k.touches>0&&(k.touches-=1)},500):"mousedown"===a.type&&k.touches>0&&(b=!1),b},touchup:function(a){k.allowEvent(a)}};h.displayEffect=function(b){b=b||{},"duration"in b&&(j.duration=b.duration),j.wrapInput(i(".waves-effect")),"ontouchstart"in a&&document.body.addEventListener("touchstart",g,!1),document.body.addEventListener("mousedown",g,!1)},h.attach=function(b){"input"===b.tagName.toLowerCase()&&(j.wrapInput([b]),b=b.parentElement),"ontouchstart"in a&&b.addEventListener("touchstart",g,!1),b.addEventListener("mousedown",g,!1)},a.Waves=h,document.addEventListener("DOMContentLoaded",function(){h.displayEffect()},!1)}(window),Materialize.toast=function(a,b,c,d){function e(a){var b=document.createElement("div");if(b.classList.add("toast"),c)for(var e=c.split(" "),f=0,g=e.length;f<g;f++)b.classList.add(e[f]);("object"==typeof HTMLElement?a instanceof HTMLElement:a&&"object"==typeof a&&null!==a&&1===a.nodeType&&"string"==typeof a.nodeName)?b.appendChild(a):a instanceof jQuery?b.appendChild(a[0]):b.innerHTML=a;var h=new Hammer(b,{prevent_default:!1});return h.on("pan",function(a){var c=a.deltaX,d=80;b.classList.contains("panning")||b.classList.add("panning");var e=1-Math.abs(c/d);e<0&&(e=0),Vel(b,{left:c,opacity:e},{duration:50,queue:!1,easing:"easeOutQuad"})}),h.on("panend",function(a){var c=a.deltaX,e=80;Math.abs(c)>e?Vel(b,{marginTop:"-40px"},{duration:375,easing:"easeOutExpo",queue:!1,complete:function(){"function"==typeof d&&d(),b.parentNode.removeChild(b)}}):(b.classList.remove("panning"),Vel(b,{left:0,opacity:1},{duration:300,easing:"easeOutExpo",queue:!1}))}),b}c=c||"";var f=document.getElementById("toast-container");null===f&&(f=document.createElement("div"),f.id="toast-container",document.body.appendChild(f));var g=e(a);a&&f.appendChild(g),g.style.opacity=0,Vel(g,{translateY:"-35px",opacity:1},{duration:300,easing:"easeOutCubic",queue:!1});var h,i=b;null!=i&&(h=setInterval(function(){null===g.parentNode&&window.clearInterval(h),g.classList.contains("panning")||(i-=20),i<=0&&(Vel(g,{opacity:0,marginTop:"-40px"},{duration:375,easing:"easeOutExpo",queue:!1,complete:function(){"function"==typeof d&&d(),this[0].parentNode.removeChild(this[0])}}),window.clearInterval(h))},20))},function(a){var b={init:function(b){var c={menuWidth:300,edge:"left",closeOnClick:!1,draggable:!0};b=a.extend(c,b),a(this).each(function(){var c=a(this),d=c.attr("data-activates"),e=a("#"+d);300!=b.menuWidth&&e.css("width",b.menuWidth);var f=a('.drag-target[data-sidenav="'+d+'"]');b.draggable?(f.length&&f.remove(),f=a('<div class="drag-target"></div>').attr("data-sidenav",d),a("body").append(f)):f=a(),"left"==b.edge?(e.css("transform","translateX(-100%)"),f.css({left:0})):(e.addClass("right-aligned").css("transform","translateX(100%)"),f.css({right:0})),e.hasClass("fixed")&&window.innerWidth>992&&e.css("transform","translateX(0)"),e.hasClass("fixed")&&a(window).resize(function(){window.innerWidth>992?0!==a("#sidenav-overlay").length&&i?g(!0):e.css("transform","translateX(0%)"):i===!1&&("left"===b.edge?e.css("transform","translateX(-100%)"):e.css("transform","translateX(100%)"))}),b.closeOnClick===!0&&e.on("click.itemclick","a:not(.collapsible-header)",function(){g()});var g=function(c){h=!1,i=!1,a("body").css({overflow:"",width:""}),a("#sidenav-overlay").velocity({opacity:0},{duration:200,queue:!1,easing:"easeOutQuad",complete:function(){a(this).remove()}}),"left"===b.edge?(f.css({width:"",right:"",left:"0"}),e.velocity({translateX:"-100%"},{duration:200,queue:!1,easing:"easeOutCubic",complete:function(){c===!0&&(e.removeAttr("style"),e.css("width",b.menuWidth))}})):(f.css({width:"",right:"0",left:""}),e.velocity({translateX:"100%"},{duration:200,queue:!1,easing:"easeOutCubic",complete:function(){c===!0&&(e.removeAttr("style"),e.css("width",b.menuWidth))}}))},h=!1,i=!1;b.draggable&&(f.on("click",function(){i&&g()}),f.hammer({prevent_default:!1}).bind("pan",function(c){if("touch"==c.gesture.pointerType){var d=(c.gesture.direction,c.gesture.center.x),f=(c.gesture.center.y,c.gesture.velocityX,a("body")),h=a("#sidenav-overlay"),j=f.innerWidth();if(f.css("overflow","hidden"),f.width(j),0===h.length&&(h=a('<div id="sidenav-overlay"></div>'),h.css("opacity",0).click(function(){g()}),a("body").append(h)),"left"===b.edge&&(d>b.menuWidth?d=b.menuWidth:d<0&&(d=0)),"left"===b.edge)d<b.menuWidth/2?i=!1:d>=b.menuWidth/2&&(i=!0),e.css("transform","translateX("+(d-b.menuWidth)+"px)");else{d<window.innerWidth-b.menuWidth/2?i=!0:d>=window.innerWidth-b.menuWidth/2&&(i=!1);var k=d-b.menuWidth/2;k<0&&(k=0),e.css("transform","translateX("+k+"px)")}var l;"left"===b.edge?(l=d/b.menuWidth,h.velocity({opacity:l},{duration:10,queue:!1,easing:"easeOutQuad"})):(l=Math.abs((d-window.innerWidth)/b.menuWidth),h.velocity({opacity:l},{duration:10,queue:!1,easing:"easeOutQuad"}))}}).bind("panend",function(c){if("touch"==c.gesture.pointerType){var d=a("#sidenav-overlay"),g=c.gesture.velocityX,j=c.gesture.center.x,k=j-b.menuWidth,l=j-b.menuWidth/2;k>0&&(k=0),l<0&&(l=0),h=!1,"left"===b.edge?i&&g<=.3||g<-.5?(0!==k&&e.velocity({translateX:[0,k]},{duration:300,queue:!1,easing:"easeOutQuad"}),d.velocity({opacity:1},{duration:50,queue:!1,easing:"easeOutQuad"}),f.css({width:"50%",right:0,left:""}),i=!0):(!i||g>.3)&&(a("body").css({overflow:"",width:""}),e.velocity({translateX:[-1*b.menuWidth-10,k]},{duration:200,queue:!1,easing:"easeOutQuad"}),d.velocity({opacity:0},{duration:200,queue:!1,easing:"easeOutQuad",complete:function(){a(this).remove()}}),f.css({width:"10px",right:"",left:0})):i&&g>=-.3||g>.5?(0!==l&&e.velocity({translateX:[0,l]},{duration:300,queue:!1,easing:"easeOutQuad"}),d.velocity({opacity:1},{duration:50,queue:!1,easing:"easeOutQuad"}),f.css({width:"50%",right:"",left:0}),i=!0):(!i||g<-.3)&&(a("body").css({overflow:"",width:""}),e.velocity({translateX:[b.menuWidth+10,l]},{duration:200,queue:!1,easing:"easeOutQuad"}),d.velocity({opacity:0},{duration:200,queue:!1,easing:"easeOutQuad",complete:function(){a(this).remove()}}),f.css({width:"10px",right:0,left:""}))}})),c.off("click.sidenav").on("click.sidenav",function(){if(i===!0)i=!1,h=!1,g();else{var c=a("body"),d=a('<div id="sidenav-overlay"></div>'),j=c.innerWidth();c.css("overflow","hidden"),c.width(j),a("body").append(f),"left"===b.edge?(f.css({width:"50%",right:0,left:""}),e.velocity({translateX:[0,-1*b.menuWidth]},{duration:300,queue:!1,easing:"easeOutQuad"})):(f.css({width:"50%",right:"",left:0}),e.velocity({translateX:[0,b.menuWidth]},{duration:300,queue:!1,easing:"easeOutQuad"})),d.css("opacity",0).click(function(){i=!1,h=!1,g(),d.velocity({opacity:0},{duration:300,queue:!1,easing:"easeOutQuad",complete:function(){a(this).remove()}})}),a("body").append(d),d.velocity({opacity:1},{duration:300,queue:!1,easing:"easeOutQuad",complete:function(){i=!0,h=!1}})}return!1})})},destroy:function(){var b=a("#sidenav-overlay"),c=a('.drag-target[data-sidenav="'+a(this).attr("data-activates")+'"]');b.trigger("click"),c.remove(),a(this).off("click"),b.remove()},show:function(){this.trigger("click")},hide:function(){a("#sidenav-overlay").trigger("click")}};a.fn.sideNav=function(c){return b[c]?b[c].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof c&&c?void a.error("Method "+c+" does not exist on jQuery.sideNav"):b.init.apply(this,arguments)}}(jQuery),function(a){function b(b,c,d,e){var g=a();return a.each(f,function(a,f){if(f.height()>0){var h=f.offset().top,i=f.offset().left,j=i+f.width(),k=h+f.height(),l=!(i>c||j<e||h>d||k<b);l&&g.push(f)}}),g}function c(c){++i;var d=e.scrollTop(),f=e.scrollLeft(),h=f+e.width(),k=d+e.height(),l=b(d+j.top+c||200,h+j.right,k+j.bottom,f+j.left);a.each(l,function(a,b){var c=b.data("scrollSpy:ticks");"number"!=typeof c&&b.triggerHandler("scrollSpy:enter"),b.data("scrollSpy:ticks",i)}),a.each(g,function(a,b){var c=b.data("scrollSpy:ticks");"number"==typeof c&&c!==i&&(b.triggerHandler("scrollSpy:exit"),b.data("scrollSpy:ticks",null))}),g=l}function d(){e.trigger("scrollSpy:winSize")}var e=a(window),f=[],g=[],h=!1,i=0,j={top:0,right:0,bottom:0,left:0};a.scrollSpy=function(b,d){var g={throttle:100,scrollOffset:200};d=a.extend(g,d);var i=[];b=a(b),b.each(function(b,c){f.push(a(c)),a(c).data("scrollSpy:id",b),a('a[href="#'+a(c).attr("id")+'"]').click(function(b){b.preventDefault();var c=a(Materialize.escapeHash(this.hash)).offset().top+1;a("html, body").animate({scrollTop:c-d.scrollOffset},{duration:400,queue:!1,easing:"easeOutCubic"})})}),j.top=d.offsetTop||0,j.right=d.offsetRight||0,j.bottom=d.offsetBottom||0,j.left=d.offsetLeft||0;var k=Materialize.throttle(function(){c(d.scrollOffset)},d.throttle||100),l=function(){a(document).ready(k)};return h||(e.on("scroll",l),e.on("resize",l),h=!0),setTimeout(l,0),b.on("scrollSpy:enter",function(){i=a.grep(i,function(a){return 0!=a.height()});var b=a(this);i[0]?(a('a[href="#'+i[0].attr("id")+'"]').removeClass("active"),b.data("scrollSpy:id")<i[0].data("scrollSpy:id")?i.unshift(a(this)):i.push(a(this))):i.push(a(this)),a('a[href="#'+i[0].attr("id")+'"]').addClass("active")}),b.on("scrollSpy:exit",function(){if(i=a.grep(i,function(a){return 0!=a.height()}),i[0]){a('a[href="#'+i[0].attr("id")+'"]').removeClass("active");var b=a(this);i=a.grep(i,function(a){return a.attr("id")!=b.attr("id")}),i[0]&&a('a[href="#'+i[0].attr("id")+'"]').addClass("active")}}),b},a.winSizeSpy=function(b){return a.winSizeSpy=function(){return e},b=b||{throttle:100},e.on("resize",Materialize.throttle(d,b.throttle||100))},a.fn.scrollSpy=function(b){return a.scrollSpy(a(this),b)}}(jQuery),function(a){a(document).ready(function(){function b(b){var c=b.css("font-family"),d=b.css("font-size"),f=b.css("line-height");d&&e.css("font-size",d),c&&e.css("font-family",c),f&&e.css("line-height",f),"off"===b.attr("wrap")&&e.css("overflow-wrap","normal").css("white-space","pre"),e.text(b.val()+"\n");var g=e.html().replace(/\n/g,"<br>");e.html(g),b.is(":visible")?e.css("width",b.width()):e.css("width",a(window).width()/2),b.data("original-height")<=e.height()?b.css("height",e.height()):b.val().length<b.data("previous-length")&&b.css("height",b.data("original-height")),b.data("previous-length",b.val().length)}Materialize.updateTextFields=function(){var b="input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea";a(b).each(function(b,c){var d=a(this);a(c).val().length>0||c.autofocus||void 0!==d.attr("placeholder")?d.siblings("label").addClass("active"):a(c)[0].validity?d.siblings("label").toggleClass("active",a(c)[0].validity.badInput===!0):d.siblings("label").removeClass("active")})};var c="input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea";a(document).on("change",c,function(){0===a(this).val().length&&void 0===a(this).attr("placeholder")||a(this).siblings("label").addClass("active"),validate_field(a(this))}),a(document).ready(function(){Materialize.updateTextFields()}),a(document).on("reset",function(b){var d=a(b.target);d.is("form")&&(d.find(c).removeClass("valid").removeClass("invalid"),d.find(c).each(function(){""===a(this).attr("value")&&a(this).siblings("label").removeClass("active")}),d.find("select.initialized").each(function(){var a=d.find("option[selected]").text();d.siblings("input.select-dropdown").val(a)}))}),a(document).on("focus",c,function(){a(this).siblings("label, .prefix").addClass("active")}),a(document).on("blur",c,function(){var b=a(this),c=".prefix";0===b.val().length&&b[0].validity.badInput!==!0&&void 0===b.attr("placeholder")&&(c+=", label"),b.siblings(c).removeClass("active"),validate_field(b)}),window.validate_field=function(a){var b=void 0!==a.attr("data-length"),c=parseInt(a.attr("data-length")),d=a.val().length;0===a.val().length&&a[0].validity.badInput===!1?a.hasClass("validate")&&(a.removeClass("valid"),a.removeClass("invalid")):a.hasClass("validate")&&(a.is(":valid")&&b&&d<=c||a.is(":valid")&&!b?(a.removeClass("invalid"),a.addClass("valid")):(a.removeClass("valid"),a.addClass("invalid")))};var d="input[type=radio], input[type=checkbox]";a(document).on("keyup.radio",d,function(b){if(9===b.which){a(this).addClass("tabbed");var c=a(this);return void c.one("blur",function(b){a(this).removeClass("tabbed")})}});var e=a(".hiddendiv").first();e.length||(e=a('<div class="hiddendiv common"></div>'),a("body").append(e));var f=".materialize-textarea";a(f).each(function(){var b=a(this);b.data("original-height",b.height()),b.data("previous-length",b.val().length)}),a("body").on("keyup keydown autoresize",f,function(){b(a(this))}),a(document).on("change",'.file-field input[type="file"]',function(){for(var b=a(this).closest(".file-field"),c=b.find("input.file-path"),d=a(this)[0].files,e=[],f=0;f<d.length;f++)e.push(d[f].name);c.val(e.join(", ")),c.trigger("change")});var g="input[type=range]",h=!1;a(g).each(function(){var b=a('<span class="thumb"><span class="value"></span></span>');a(this).after(b)});var i=function(a){var b=parseInt(a.parent().css("padding-left")),c=-7+b+"px";a.velocity({height:"30px",width:"30px",top:"-30px",marginLeft:c},{duration:300,easing:"easeOutExpo"})},j=function(a){var b=a.width()-15,c=parseFloat(a.attr("max")),d=parseFloat(a.attr("min")),e=(parseFloat(a.val())-d)/(c-d);return e*b},k=".range-field";a(document).on("change",g,function(b){var c=a(this).siblings(".thumb");c.find(".value").html(a(this).val()),c.hasClass("active")||i(c);var d=j(a(this));c.addClass("active").css("left",d)}),a(document).on("mousedown touchstart",g,function(b){var c=a(this).siblings(".thumb");if(c.length<=0&&(c=a('<span class="thumb"><span class="value"></span></span>'),a(this).after(c)),c.find(".value").html(a(this).val()),h=!0,a(this).addClass("active"),c.hasClass("active")||i(c),"input"!==b.type){var d=j(a(this));c.addClass("active").css("left",d)}}),a(document).on("mouseup touchend",k,function(){h=!1,a(this).removeClass("active")}),a(document).on("input mousemove touchmove",k,function(b){var c=a(this).children(".thumb"),d=a(this).find(g);if(h){c.hasClass("active")||i(c);var e=j(d);c.addClass("active").css("left",e),c.find(".value").html(c.siblings(g).val())}}),a(document).on("mouseout touchleave",k,function(){if(!h){var b=a(this).children(".thumb"),c=parseInt(a(this).css("padding-left")),d=7+c+"px";b.hasClass("active")&&b.velocity({height:"0",width:"0",top:"10px",marginLeft:d},{duration:100}),b.removeClass("active")}}),a.fn.autocomplete=function(b){var c={data:{},limit:1/0,onAutocomplete:null,minLength:1};return b=a.extend(c,b),this.each(function(){var c,d=a(this),e=b.data,f=0,g=-1,h=d.closest(".input-field");if(!a.isEmptyObject(e)){var i,j=a('<ul class="autocomplete-content dropdown-content"></ul>');h.length?(i=h.children(".autocomplete-content.dropdown-content").first(),i.length||h.append(j)):(i=d.next(".autocomplete-content.dropdown-content"),i.length||d.after(j)),i.length&&(j=i);var k=function(a,b){var c=b.find("img"),d=b.text().toLowerCase().indexOf(""+a.toLowerCase()),e=d+a.length-1,f=b.text().slice(0,d),g=b.text().slice(d,e+1),h=b.text().slice(e+1);b.html("<span>"+f+"<span class='highlight'>"+g+"</span>"+h+"</span>"),c.length&&b.prepend(c)},l=function(){g=-1,j.find(".active").removeClass("active")},m=function(){j.empty(),l(),c=void 0};d.off("blur.autocomplete").on("blur.autocomplete",function(){m()}),d.off("keyup.autocomplete focus.autocomplete").on("keyup.autocomplete focus.autocomplete",function(g){f=0;var h=d.val().toLowerCase();if(13!==g.which&&38!==g.which&&40!==g.which){if(c!==h&&(m(),h.length>=b.minLength))for(var i in e)if(e.hasOwnProperty(i)&&i.toLowerCase().indexOf(h)!==-1&&i.toLowerCase()!==h){if(f>=b.limit)break;var l=a("<li></li>");e[i]?l.append('<img src="'+e[i]+'" class="right circle"><span>'+i+"</span>"):l.append("<span>"+i+"</span>"),j.append(l),k(h,l),f++}c=h}}),d.off("keydown.autocomplete").on("keydown.autocomplete",function(a){var b,c=a.which,d=j.children("li").length,e=j.children(".active").first();return 13===c&&g>=0?(b=j.children("li").eq(g),void(b.length&&(b.trigger("mousedown.autocomplete"),a.preventDefault()))):void(38!==c&&40!==c||(a.preventDefault(),
9
+ 38===c&&g>0&&g--,40===c&&g<d-1&&g++,e.removeClass("active"),g>=0&&j.children("li").eq(g).addClass("active")))}),j.on("mousedown.autocomplete touchstart.autocomplete","li",function(){var c=a(this).text().trim();d.val(c),d.trigger("change"),m(),"function"==typeof b.onAutocomplete&&b.onAutocomplete.call(this,c)})}})}}),a.fn.material_select=function(b){function c(a,b,c){var e=a.indexOf(b),f=e===-1;return f?a.push(b):a.splice(e,1),c.siblings("ul.dropdown-content").find("li:not(.optgroup)").eq(b).toggleClass("active"),c.find("option").eq(b).prop("selected",f),d(a,c),f}function d(a,b){for(var c="",d=0,e=a.length;d<e;d++){var f=b.find("option").eq(a[d]).text();c+=0===d?f:", "+f}""===c&&(c=b.find("option:disabled").eq(0).text()),b.siblings("input.select-dropdown").val(c)}a(this).each(function(){var d=a(this);if(!d.hasClass("browser-default")){var e=!!d.attr("multiple"),f=d.data("select-id");if(f&&(d.parent().find("span.caret").remove(),d.parent().find("input").remove(),d.unwrap(),a("ul#select-options-"+f).remove()),"destroy"===b)return void d.data("select-id",null).removeClass("initialized");var g=Materialize.guid();d.data("select-id",g);var h=a('<div class="select-wrapper"></div>');h.addClass(d.attr("class"));var i=a('<ul id="select-options-'+g+'" class="dropdown-content select-dropdown '+(e?"multiple-select-dropdown":"")+'"></ul>'),j=d.children("option, optgroup"),k=[],l=!1,m=d.find("option:selected").html()||d.find("option:first").html()||"",n=function(b,c,d){var f=c.is(":disabled")?"disabled ":"",g="optgroup-option"===d?"optgroup-option ":"",h=e?'<input type="checkbox"'+f+"/><label></label>":"",j=c.data("icon"),k=c.attr("class");if(j){var l="";return k&&(l=' class="'+k+'"'),i.append(a('<li class="'+f+g+'"><img alt="" src="'+j+'"'+l+"><span>"+h+c.html()+"</span></li>")),!0}i.append(a('<li class="'+f+g+'"><span>'+h+c.html()+"</span></li>"))};j.length&&j.each(function(){if(a(this).is("option"))e?n(d,a(this),"multiple"):n(d,a(this));else if(a(this).is("optgroup")){var b=a(this).children("option");i.append(a('<li class="optgroup"><span>'+a(this).attr("label")+"</span></li>")),b.each(function(){n(d,a(this),"optgroup-option")})}}),i.find("li:not(.optgroup)").each(function(f){a(this).click(function(g){if(!a(this).hasClass("disabled")&&!a(this).hasClass("optgroup")){var h=!0;e?(a('input[type="checkbox"]',this).prop("checked",function(a,b){return!b}),h=c(k,f,d),q.trigger("focus")):(i.find("li").removeClass("active"),a(this).toggleClass("active"),q.val(a(this).text())),r(i,a(this)),d.find("option").eq(f).prop("selected",h),d.trigger("change"),"undefined"!=typeof b&&b()}g.stopPropagation()})}),d.wrap(h);var o=a('<span class="caret">&#9660;</span>');d.is(":disabled")&&o.addClass("disabled");var p=m.replace(/"/g,"&quot;"),q=a('<input type="text" class="select-dropdown" readonly="true" '+(d.is(":disabled")?"disabled":"")+' data-activates="select-options-'+g+'" value="'+p+'"/>');d.before(q),q.before(o),q.after(i),d.is(":disabled")||q.dropdown({hover:!1}),d.attr("tabindex")&&a(q[0]).attr("tabindex",d.attr("tabindex")),d.addClass("initialized"),q.on({focus:function(){if(a("ul.select-dropdown").not(i[0]).is(":visible")&&a("input.select-dropdown").trigger("close"),!i.is(":visible")){a(this).trigger("open",["focus"]);var b=a(this).val();e&&b.indexOf(",")>=0&&(b=b.split(",")[0]);var c=i.find("li").filter(function(){return a(this).text().toLowerCase()===b.toLowerCase()})[0];r(i,c,!0)}},click:function(a){a.stopPropagation()}}),q.on("blur",function(){e||a(this).trigger("close"),i.find("li.selected").removeClass("selected")}),i.hover(function(){l=!0},function(){l=!1}),a(window).on({click:function(){e&&(l||q.trigger("close"))}}),e&&d.find("option:selected:not(:disabled)").each(function(){var b=a(this).index();c(k,b,d),i.find("li").eq(b).find(":checkbox").prop("checked",!0)});var r=function(b,c,d){if(c){b.find("li.selected").removeClass("selected");var f=a(c);f.addClass("selected"),e&&!d||i.scrollTo(f)}},s=[],t=function(b){if(9==b.which)return void q.trigger("close");if(40==b.which&&!i.is(":visible"))return void q.trigger("open");if(13!=b.which||i.is(":visible")){b.preventDefault();var c=String.fromCharCode(b.which).toLowerCase(),d=[9,13,27,38,40];if(c&&d.indexOf(b.which)===-1){s.push(c);var f=s.join(""),g=i.find("li").filter(function(){return 0===a(this).text().toLowerCase().indexOf(f)})[0];g&&r(i,g)}if(13==b.which){var h=i.find("li.selected:not(.disabled)")[0];h&&(a(h).trigger("click"),e||q.trigger("close"))}40==b.which&&(g=i.find("li.selected").length?i.find("li.selected").next("li:not(.disabled)")[0]:i.find("li:not(.disabled)")[0],r(i,g)),27==b.which&&q.trigger("close"),38==b.which&&(g=i.find("li.selected").prev("li:not(.disabled)")[0],g&&r(i,g)),setTimeout(function(){s=[]},1e3)}};q.on("keydown",t)}})}}(jQuery),function(a){var b={init:function(b){var c={indicators:!0,height:400,transition:500,interval:6e3};return b=a.extend(c,b),this.each(function(){function c(a,b){a.hasClass("center-align")?a.velocity({opacity:0,translateY:-100},{duration:b,queue:!1}):a.hasClass("right-align")?a.velocity({opacity:0,translateX:100},{duration:b,queue:!1}):a.hasClass("left-align")&&a.velocity({opacity:0,translateX:-100},{duration:b,queue:!1})}function d(a){a>=j.length?a=0:a<0&&(a=j.length-1),k=i.find(".active").index(),k!=a&&(e=j.eq(k),$caption=e.find(".caption"),e.removeClass("active"),e.velocity({opacity:0},{duration:b.transition,queue:!1,easing:"easeOutQuad",complete:function(){j.not(".active").velocity({opacity:0,translateX:0,translateY:0},{duration:0,queue:!1})}}),c($caption,b.transition),b.indicators&&f.eq(k).removeClass("active"),j.eq(a).velocity({opacity:1},{duration:b.transition,queue:!1,easing:"easeOutQuad"}),j.eq(a).find(".caption").velocity({opacity:1,translateX:0,translateY:0},{duration:b.transition,delay:b.transition,queue:!1,easing:"easeOutQuad"}),j.eq(a).addClass("active"),b.indicators&&f.eq(a).addClass("active"))}var e,f,g,h=a(this),i=h.find("ul.slides").first(),j=i.find("> li"),k=i.find(".active").index();k!=-1&&(e=j.eq(k)),h.hasClass("fullscreen")||(b.indicators?h.height(b.height+40):h.height(b.height),i.height(b.height)),j.find(".caption").each(function(){c(a(this),0)}),j.find("img").each(function(){var b="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";a(this).attr("src")!==b&&(a(this).css("background-image","url("+a(this).attr("src")+")"),a(this).attr("src",b))}),b.indicators&&(f=a('<ul class="indicators"></ul>'),j.each(function(c){var e=a('<li class="indicator-item"></li>');e.click(function(){var c=i.parent(),e=c.find(a(this)).index();d(e),clearInterval(g),g=setInterval(function(){k=i.find(".active").index(),j.length==k+1?k=0:k+=1,d(k)},b.transition+b.interval)}),f.append(e)}),h.append(f),f=h.find("ul.indicators").find("li.indicator-item")),e?e.show():(j.first().addClass("active").velocity({opacity:1},{duration:b.transition,queue:!1,easing:"easeOutQuad"}),k=0,e=j.eq(k),b.indicators&&f.eq(k).addClass("active")),e.find("img").each(function(){e.find(".caption").velocity({opacity:1,translateX:0,translateY:0},{duration:b.transition,queue:!1,easing:"easeOutQuad"})}),g=setInterval(function(){k=i.find(".active").index(),d(k+1)},b.transition+b.interval);var l=!1,m=!1,n=!1;h.hammer({prevent_default:!1}).bind("pan",function(a){if("touch"===a.gesture.pointerType){clearInterval(g);var b=a.gesture.direction,c=a.gesture.deltaX,d=a.gesture.velocityX,e=a.gesture.velocityY;$curr_slide=i.find(".active"),Math.abs(d)>Math.abs(e)&&$curr_slide.velocity({translateX:c},{duration:50,queue:!1,easing:"easeOutQuad"}),4===b&&(c>h.innerWidth()/2||d<-.65)?n=!0:2===b&&(c<-1*h.innerWidth()/2||d>.65)&&(m=!0);var f;m&&(f=$curr_slide.next(),0===f.length&&(f=j.first()),f.velocity({opacity:1},{duration:300,queue:!1,easing:"easeOutQuad"})),n&&(f=$curr_slide.prev(),0===f.length&&(f=j.last()),f.velocity({opacity:1},{duration:300,queue:!1,easing:"easeOutQuad"}))}}).bind("panend",function(a){"touch"===a.gesture.pointerType&&($curr_slide=i.find(".active"),l=!1,curr_index=i.find(".active").index(),!n&&!m||j.length<=1?$curr_slide.velocity({translateX:0},{duration:300,queue:!1,easing:"easeOutQuad"}):m?(d(curr_index+1),$curr_slide.velocity({translateX:-1*h.innerWidth()},{duration:300,queue:!1,easing:"easeOutQuad",complete:function(){$curr_slide.velocity({opacity:0,translateX:0},{duration:0,queue:!1})}})):n&&(d(curr_index-1),$curr_slide.velocity({translateX:h.innerWidth()},{duration:300,queue:!1,easing:"easeOutQuad",complete:function(){$curr_slide.velocity({opacity:0,translateX:0},{duration:0,queue:!1})}})),m=!1,n=!1,clearInterval(g),g=setInterval(function(){k=i.find(".active").index(),j.length==k+1?k=0:k+=1,d(k)},b.transition+b.interval))}),h.on("sliderPause",function(){clearInterval(g)}),h.on("sliderStart",function(){clearInterval(g),g=setInterval(function(){k=i.find(".active").index(),j.length==k+1?k=0:k+=1,d(k)},b.transition+b.interval)}),h.on("sliderNext",function(){k=i.find(".active").index(),d(k+1)}),h.on("sliderPrev",function(){k=i.find(".active").index(),d(k-1)})})},pause:function(){a(this).trigger("sliderPause")},start:function(){a(this).trigger("sliderStart")},next:function(){a(this).trigger("sliderNext")},prev:function(){a(this).trigger("sliderPrev")}};a.fn.slider=function(c){return b[c]?b[c].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof c&&c?void a.error("Method "+c+" does not exist on jQuery.tooltip"):b.init.apply(this,arguments)}}(jQuery),function(a){a(document).ready(function(){a(document).on("click.card",".card",function(b){a(this).find("> .card-reveal").length&&(a(b.target).is(a(".card-reveal .card-title"))||a(b.target).is(a(".card-reveal .card-title i"))?a(this).find(".card-reveal").velocity({translateY:0},{duration:225,queue:!1,easing:"easeInOutQuad",complete:function(){a(this).css({display:"none"})}}):(a(b.target).is(a(".card .activator"))||a(b.target).is(a(".card .activator i")))&&(a(b.target).closest(".card").css("overflow","hidden"),a(this).find(".card-reveal").css({display:"block"}).velocity("stop",!1).velocity({translateY:"-100%"},{duration:300,queue:!1,easing:"easeInOutQuad"})))})})}(jQuery),function(a){var b={data:[],placeholder:"",secondaryPlaceholder:"",autocompleteOptions:{}};a(document).ready(function(){a(document).on("click",".chip .close",function(b){var c=a(this).closest(".chips");c.attr("data-initialized")||a(this).closest(".chip").remove()})}),a.fn.material_chip=function(c){var d=this;if(this.$el=a(this),this.$document=a(document),this.SELS={CHIPS:".chips",CHIP:".chip",INPUT:"input",DELETE:".material-icons",SELECTED_CHIP:".selected"},"data"===c)return this.$el.data("chips");var e=a.extend({},b,c);d.hasAutocomplete=!a.isEmptyObject(e.autocompleteOptions.data),this.init=function(){var b=0;d.$el.each(function(){var c=a(this),f=Materialize.guid();d.chipId=f,e.data&&e.data instanceof Array||(e.data=[]),c.data("chips",e.data),c.attr("data-index",b),c.attr("data-initialized",!0),c.hasClass(d.SELS.CHIPS)||c.addClass("chips"),d.chips(c,f),b++})},this.handleEvents=function(){var b=d.SELS;d.$document.off("click.chips-focus",b.CHIPS).on("click.chips-focus",b.CHIPS,function(c){a(c.target).find(b.INPUT).focus()}),d.$document.off("click.chips-select",b.CHIP).on("click.chips-select",b.CHIP,function(c){var e=a(c.target);if(e.length){var f=e.hasClass("selected"),g=e.closest(b.CHIPS);a(b.CHIP).removeClass("selected"),f||d.selectChip(e.index(),g)}}),d.$document.off("keydown.chips").on("keydown.chips",function(c){if(!a(c.target).is("input, textarea")){var e,f=d.$document.find(b.CHIP+b.SELECTED_CHIP),g=f.closest(b.CHIPS),h=f.siblings(b.CHIP).length;if(f.length)if(8===c.which||46===c.which){c.preventDefault(),e=f.index(),d.deleteChip(e,g);var i=null;e+1<h?i=e:e!==h&&e+1!==h||(i=h-1),i<0&&(i=null),null!==i&&d.selectChip(i,g),h||g.find("input").focus()}else if(37===c.which){if(e=f.index()-1,e<0)return;a(b.CHIP).removeClass("selected"),d.selectChip(e,g)}else if(39===c.which){if(e=f.index()+1,a(b.CHIP).removeClass("selected"),e>h)return void g.find("input").focus();d.selectChip(e,g)}}}),d.$document.off("focusin.chips",b.CHIPS+" "+b.INPUT).on("focusin.chips",b.CHIPS+" "+b.INPUT,function(c){var d=a(c.target).closest(b.CHIPS);d.addClass("focus"),d.siblings("label, .prefix").addClass("active"),a(b.CHIP).removeClass("selected")}),d.$document.off("focusout.chips",b.CHIPS+" "+b.INPUT).on("focusout.chips",b.CHIPS+" "+b.INPUT,function(c){var d=a(c.target).closest(b.CHIPS);d.removeClass("focus"),d.data("chips").length||d.siblings("label").removeClass("active"),d.siblings(".prefix").removeClass("active")}),d.$document.off("keydown.chips-add",b.CHIPS+" "+b.INPUT).on("keydown.chips-add",b.CHIPS+" "+b.INPUT,function(c){var e=a(c.target),f=e.closest(b.CHIPS),g=f.children(b.CHIP).length;if(13===c.which){if(d.hasAutocomplete&&f.find(".autocomplete-content.dropdown-content").length&&f.find(".autocomplete-content.dropdown-content").children().length)return;return c.preventDefault(),d.addChip({tag:e.val()},f),void e.val("")}if((8===c.keyCode||37===c.keyCode)&&""===e.val()&&g)return c.preventDefault(),d.selectChip(g-1,f),void e.blur()}),d.$document.off("click.chips-delete",b.CHIPS+" "+b.DELETE).on("click.chips-delete",b.CHIPS+" "+b.DELETE,function(c){var e=a(c.target),f=e.closest(b.CHIPS),g=e.closest(b.CHIP);c.stopPropagation(),d.deleteChip(g.index(),f),f.find("input").focus()})},this.chips=function(b,c){b.empty(),b.data("chips").forEach(function(a){b.append(d.renderChip(a))}),b.append(a('<input id="'+c+'" class="input" placeholder="">')),d.setPlaceholder(b);var f=b.next("label");f.length&&(f.attr("for",c),b.data("chips").length&&f.addClass("active"));var g=a("#"+c);d.hasAutocomplete&&(e.autocompleteOptions.onAutocomplete=function(a){d.addChip({tag:a},b),g.val(""),g.focus()},g.autocomplete(e.autocompleteOptions))},this.renderChip=function(b){if(b.tag){var c=a('<div class="chip"></div>');return c.text(b.tag),c.append(a('<i class="material-icons close">close</i>')),c}},this.setPlaceholder=function(a){a.data("chips").length&&e.placeholder?a.find("input").prop("placeholder",e.placeholder):!a.data("chips").length&&e.secondaryPlaceholder&&a.find("input").prop("placeholder",e.secondaryPlaceholder)},this.isValid=function(a,b){for(var c=a.data("chips"),d=!1,e=0;e<c.length;e++)if(c[e].tag===b.tag)return void(d=!0);return""!==b.tag&&!d},this.addChip=function(a,b){if(d.isValid(b,a)){for(var c=d.renderChip(a),e=[],f=b.data("chips"),g=0;g<f.length;g++)e.push(f[g]);e.push(a),b.data("chips",e),c.insertBefore(b.find("input")),b.trigger("chip.add",a),d.setPlaceholder(b)}},this.deleteChip=function(a,b){var c=b.data("chips")[a];b.find(".chip").eq(a).remove();for(var e=[],f=b.data("chips"),g=0;g<f.length;g++)g!==a&&e.push(f[g]);b.data("chips",e),b.trigger("chip.delete",c),d.setPlaceholder(b)},this.selectChip=function(a,b){var c=b.find(".chip").eq(a);c&&!1===c.hasClass("selected")&&(c.addClass("selected"),b.trigger("chip.select",b.data("chips")[a]))},this.getChipsElement=function(a,b){return b.eq(a)},this.init(),this.handleEvents()}}(jQuery),function(a){a.fn.pushpin=function(b){var c={top:0,bottom:1/0,offset:0};return"remove"===b?(this.each(function(){(id=a(this).data("pushpin-id"))&&(a(window).off("scroll."+id),a(this).removeData("pushpin-id").removeClass("pin-top pinned pin-bottom").removeAttr("style"))}),!1):(b=a.extend(c,b),$index=0,this.each(function(){function c(a){a.removeClass("pin-top"),a.removeClass("pinned"),a.removeClass("pin-bottom")}function d(d,e){d.each(function(){b.top<=e&&b.bottom>=e&&!a(this).hasClass("pinned")&&(c(a(this)),a(this).css("top",b.offset),a(this).addClass("pinned")),e<b.top&&!a(this).hasClass("pin-top")&&(c(a(this)),a(this).css("top",0),a(this).addClass("pin-top")),e>b.bottom&&!a(this).hasClass("pin-bottom")&&(c(a(this)),a(this).addClass("pin-bottom"),a(this).css("top",b.bottom-g))})}var e=Materialize.guid(),f=a(this),g=a(this).offset().top;a(this).data("pushpin-id",e),d(f,a(window).scrollTop()),a(window).on("scroll."+e,function(){var c=a(window).scrollTop()+b.offset;d(f,c)})}))}}(jQuery),function(a){a(document).ready(function(){a.fn.reverse=[].reverse,a(document).on("mouseenter.fixedActionBtn",".fixed-action-btn:not(.click-to-toggle):not(.toolbar)",function(c){var d=a(this);b(d)}),a(document).on("mouseleave.fixedActionBtn",".fixed-action-btn:not(.click-to-toggle):not(.toolbar)",function(b){var d=a(this);c(d)}),a(document).on("click.fabClickToggle",".fixed-action-btn.click-to-toggle > a",function(d){var e=a(this),f=e.parent();f.hasClass("active")?c(f):b(f)}),a(document).on("click.fabToolbar",".fixed-action-btn.toolbar > a",function(b){var c=a(this),e=c.parent();d(e)})}),a.fn.extend({openFAB:function(){b(a(this))},closeFAB:function(){c(a(this))},openToolbar:function(){d(a(this))},closeToolbar:function(){e(a(this))}});var b=function(b){var c=b;if(c.hasClass("active")===!1){var d,e,f=c.hasClass("horizontal");f===!0?e=40:d=40,c.addClass("active"),c.find("ul .btn-floating").velocity({scaleY:".4",scaleX:".4",translateY:d+"px",translateX:e+"px"},{duration:0});var g=0;c.find("ul .btn-floating").reverse().each(function(){a(this).velocity({opacity:"1",scaleX:"1",scaleY:"1",translateY:"0",translateX:"0"},{duration:80,delay:g}),g+=40})}},c=function(a){var b,c,d=a,e=d.hasClass("horizontal");e===!0?c=40:b=40,d.removeClass("active");d.find("ul .btn-floating").velocity("stop",!0),d.find("ul .btn-floating").velocity({opacity:"0",scaleX:".4",scaleY:".4",translateY:b+"px",translateX:c+"px"},{duration:80})},d=function(b){if("true"!==b.attr("data-open")){var c,d,f,g=window.innerWidth,h=window.innerHeight,i=b[0].getBoundingClientRect(),j=b.find("> a").first(),k=b.find("> ul").first(),l=a('<div class="fab-backdrop"></div>'),m=j.css("background-color");j.append(l),c=i.left-g/2+i.width/2,d=h-i.bottom,f=g/l.width(),b.attr("data-origin-bottom",i.bottom),b.attr("data-origin-left",i.left),b.attr("data-origin-width",i.width),b.addClass("active"),b.attr("data-open",!0),b.css({"text-align":"center",width:"100%",bottom:0,left:0,transform:"translateX("+c+"px)",transition:"none"}),j.css({transform:"translateY("+-d+"px)",transition:"none"}),l.css({"background-color":m}),setTimeout(function(){b.css({transform:"",transition:"transform .2s cubic-bezier(0.550, 0.085, 0.680, 0.530), background-color 0s linear .2s"}),j.css({overflow:"visible",transform:"",transition:"transform .2s"}),setTimeout(function(){b.css({overflow:"hidden","background-color":m}),l.css({transform:"scale("+f+")",transition:"transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)"}),k.find("> li > a").css({opacity:1}),a(window).on("scroll.fabToolbarClose",function(){e(b),a(window).off("scroll.fabToolbarClose"),a(document).off("click.fabToolbarClose")}),a(document).on("click.fabToolbarClose",function(c){a(c.target).closest(k).length||(e(b),a(window).off("scroll.fabToolbarClose"),a(document).off("click.fabToolbarClose"))})},100)},0)}},e=function(a){if("true"===a.attr("data-open")){var b,c,d,e=window.innerWidth,f=window.innerHeight,g=a.attr("data-origin-width"),h=a.attr("data-origin-bottom"),i=a.attr("data-origin-left"),j=a.find("> .btn-floating").first(),k=a.find("> ul").first(),l=a.find(".fab-backdrop"),m=j.css("background-color");b=i-e/2+g/2,c=f-h,d=e/l.width(),a.removeClass("active"),a.attr("data-open",!1),a.css({"background-color":"transparent",transition:"none"}),j.css({transition:"none"}),l.css({transform:"scale(0)","background-color":m}),k.find("> li > a").css({opacity:""}),setTimeout(function(){l.remove(),a.css({"text-align":"",width:"",bottom:"",left:"",overflow:"","background-color":"",transform:"translate3d("+-b+"px,0,0)"}),j.css({overflow:"",transform:"translate3d(0,"+c+"px,0)"}),setTimeout(function(){a.css({transform:"translate3d(0,0,0)",transition:"transform .2s"}),j.css({transform:"translate3d(0,0,0)",transition:"transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)"})},20)},200)}}}(jQuery),function(a){Materialize.fadeInImage=function(b){var c;if("string"==typeof b)c=a(b);else{if("object"!=typeof b)return;c=b}c.css({opacity:0}),a(c).velocity({opacity:1},{duration:650,queue:!1,easing:"easeOutSine"}),a(c).velocity({opacity:1},{duration:1300,queue:!1,easing:"swing",step:function(b,c){c.start=100;var d=b/100,e=150-(100-b)/1.75;e<100&&(e=100),b>=0&&a(this).css({"-webkit-filter":"grayscale("+d+")brightness("+e+"%)",filter:"grayscale("+d+")brightness("+e+"%)"})}})},Materialize.showStaggeredList=function(b){var c;if("string"==typeof b)c=a(b);else{if("object"!=typeof b)return;c=b}var d=0;c.find("li").velocity({translateX:"-100px"},{duration:0}),c.find("li").each(function(){a(this).velocity({opacity:"1",translateX:"0"},{duration:800,delay:d,easing:[60,10]}),d+=120})},a(document).ready(function(){var b=!1,c=!1;a(".dismissable").each(function(){a(this).hammer({prevent_default:!1}).bind("pan",function(d){if("touch"===d.gesture.pointerType){var e=a(this),f=d.gesture.direction,g=d.gesture.deltaX,h=d.gesture.velocityX;e.velocity({translateX:g},{duration:50,queue:!1,easing:"easeOutQuad"}),4===f&&(g>e.innerWidth()/2||h<-.75)&&(b=!0),2===f&&(g<-1*e.innerWidth()/2||h>.75)&&(c=!0)}}).bind("panend",function(d){if(Math.abs(d.gesture.deltaX)<a(this).innerWidth()/2&&(c=!1,b=!1),"touch"===d.gesture.pointerType){var e=a(this);if(b||c){var f;f=b?e.innerWidth():-1*e.innerWidth(),e.velocity({translateX:f},{duration:100,queue:!1,easing:"easeOutQuad",complete:function(){e.css("border","none"),e.velocity({height:0,padding:0},{duration:200,queue:!1,easing:"easeOutQuad",complete:function(){e.remove()}})}})}else e.velocity({translateX:0},{duration:100,queue:!1,easing:"easeOutQuad"});b=!1,c=!1}})})})}(jQuery),function(a){var b=!1;Materialize.scrollFire=function(a){var c=function(){for(var b=window.pageYOffset+window.innerHeight,c=0;c<a.length;c++){var d=a[c],e=d.selector,f=d.offset,g=d.callback,h=document.querySelector(e);if(null!==h){var i=h.getBoundingClientRect().top+window.pageYOffset;if(b>i+f&&d.done!==!0){if("function"==typeof g)g.call(this,h);else if("string"==typeof g){var j=new Function(g);j(h)}d.done=!0}}}},d=Materialize.throttle(function(){c()},a.throttle||100);b||(window.addEventListener("scroll",d),window.addEventListener("resize",d),b=!0),setTimeout(d,0)}}(jQuery),function(a){"function"==typeof define&&define.amd?define("picker",["jquery"],a):"object"==typeof exports?module.exports=a(require("jquery")):this.Picker=a(jQuery)}(function(a){function b(f,g,i,l){function m(){return b._.node("div",b._.node("div",b._.node("div",b._.node("div",y.component.nodes(t.open),v.box),v.wrap),v.frame),v.holder)}function n(){w.data(g,y).addClass(v.input).attr("tabindex",-1).val(w.data("value")?y.get("select",u.format):f.value),u.editable||w.on("focus."+t.id+" click."+t.id,function(a){a.preventDefault(),y.$root.eq(0).focus()}).on("keydown."+t.id,q),e(f,{haspopup:!0,expanded:!1,readonly:!1,owns:f.id+"_root"})}function o(){y.$root.on({keydown:q,focusin:function(a){y.$root.removeClass(v.focused),a.stopPropagation()},"mousedown click":function(b){var c=b.target;c!=y.$root.children()[0]&&(b.stopPropagation(),"mousedown"!=b.type||a(c).is("input, select, textarea, button, option")||(b.preventDefault(),y.$root.eq(0).focus()))}}).on({focus:function(){w.addClass(v.target)},blur:function(){w.removeClass(v.target)}}).on("focus.toOpen",r).on("click","[data-pick], [data-nav], [data-clear], [data-close]",function(){var b=a(this),c=b.data(),d=b.hasClass(v.navDisabled)||b.hasClass(v.disabled),e=h();e=e&&(e.type||e.href),(d||e&&!a.contains(y.$root[0],e))&&y.$root.eq(0).focus(),!d&&c.nav?y.set("highlight",y.component.item.highlight,{nav:c.nav}):!d&&"pick"in c?y.set("select",c.pick):c.clear?y.clear().close(!0):c.close&&y.close(!0)}),e(y.$root[0],"hidden",!0)}function p(){var b;u.hiddenName===!0?(b=f.name,f.name=""):(b=["string"==typeof u.hiddenPrefix?u.hiddenPrefix:"","string"==typeof u.hiddenSuffix?u.hiddenSuffix:"_submit"],b=b[0]+f.name+b[1]),y._hidden=a('<input type=hidden name="'+b+'"'+(w.data("value")||f.value?' value="'+y.get("select",u.formatSubmit)+'"':"")+">")[0],w.on("change."+t.id,function(){y._hidden.value=f.value?y.get("select",u.formatSubmit):""}),u.container?a(u.container).append(y._hidden):w.after(y._hidden)}function q(a){var b=a.keyCode,c=/^(8|46)$/.test(b);return 27==b?(y.close(),!1):void((32==b||c||!t.open&&y.component.key[b])&&(a.preventDefault(),a.stopPropagation(),c?y.clear().close():y.open()))}function r(a){a.stopPropagation(),"focus"==a.type&&y.$root.addClass(v.focused),y.open()}if(!f)return b;var s=!1,t={id:f.id||"P"+Math.abs(~~(Math.random()*new Date))},u=i?a.extend(!0,{},i.defaults,l):l||{},v=a.extend({},b.klasses(),u.klass),w=a(f),x=function(){return this.start()},y=x.prototype={constructor:x,$node:w,start:function(){return t&&t.start?y:(t.methods={},t.start=!0,t.open=!1,t.type=f.type,f.autofocus=f==h(),f.readOnly=!u.editable,f.id=f.id||t.id,"text"!=f.type&&(f.type="text"),y.component=new i(y,u),y.$root=a(b._.node("div",m(),v.picker,'id="'+f.id+'_root" tabindex="0"')),o(),u.formatSubmit&&p(),n(),u.container?a(u.container).append(y.$root):w.after(y.$root),y.on({start:y.component.onStart,render:y.component.onRender,stop:y.component.onStop,open:y.component.onOpen,close:y.component.onClose,set:y.component.onSet}).on({start:u.onStart,render:u.onRender,stop:u.onStop,open:u.onOpen,close:u.onClose,set:u.onSet}),s=c(y.$root.children()[0]),f.autofocus&&y.open(),y.trigger("start").trigger("render"))},render:function(a){return a?y.$root.html(m()):y.$root.find("."+v.box).html(y.component.nodes(t.open)),y.trigger("render")},stop:function(){return t.start?(y.close(),y._hidden&&y._hidden.parentNode.removeChild(y._hidden),y.$root.remove(),w.removeClass(v.input).removeData(g),setTimeout(function(){w.off("."+t.id)},0),f.type=t.type,f.readOnly=!1,y.trigger("stop"),t.methods={},t.start=!1,y):y},open:function(c){return t.open?y:(w.addClass(v.active),e(f,"expanded",!0),setTimeout(function(){y.$root.addClass(v.opened),e(y.$root[0],"hidden",!1)},0),c!==!1&&(t.open=!0,s&&k.css("overflow","hidden").css("padding-right","+="+d()),y.$root.eq(0).focus(),j.on("click."+t.id+" focusin."+t.id,function(a){var b=a.target;b!=f&&b!=document&&3!=a.which&&y.close(b===y.$root.children()[0])}).on("keydown."+t.id,function(c){var d=c.keyCode,e=y.component.key[d],f=c.target;27==d?y.close(!0):f!=y.$root[0]||!e&&13!=d?a.contains(y.$root[0],f)&&13==d&&(c.preventDefault(),f.click()):(c.preventDefault(),e?b._.trigger(y.component.key.go,y,[b._.trigger(e)]):y.$root.find("."+v.highlighted).hasClass(v.disabled)||y.set("select",y.component.item.highlight).close())})),y.trigger("open"))},close:function(a){return a&&(y.$root.off("focus.toOpen").eq(0).focus(),setTimeout(function(){y.$root.on("focus.toOpen",r)},0)),w.removeClass(v.active),e(f,"expanded",!1),setTimeout(function(){y.$root.removeClass(v.opened+" "+v.focused),e(y.$root[0],"hidden",!0)},0),t.open?(t.open=!1,s&&k.css("overflow","").css("padding-right","-="+d()),j.off("."+t.id),y.trigger("close")):y},clear:function(a){return y.set("clear",null,a)},set:function(b,c,d){var e,f,g=a.isPlainObject(b),h=g?b:{};if(d=g&&a.isPlainObject(c)?c:d||{},b){g||(h[b]=c);for(e in h)f=h[e],e in y.component.item&&(void 0===f&&(f=null),y.component.set(e,f,d)),"select"!=e&&"clear"!=e||w.val("clear"==e?"":y.get(e,u.format)).trigger("change");y.render()}return d.muted?y:y.trigger("set",h)},get:function(a,c){if(a=a||"value",null!=t[a])return t[a];if("valueSubmit"==a){if(y._hidden)return y._hidden.value;a="value"}if("value"==a)return f.value;if(a in y.component.item){if("string"==typeof c){var d=y.component.get(a);return d?b._.trigger(y.component.formats.toString,y.component,[c,d]):""}return y.component.get(a)}},on:function(b,c,d){var e,f,g=a.isPlainObject(b),h=g?b:{};if(b){g||(h[b]=c);for(e in h)f=h[e],d&&(e="_"+e),t.methods[e]=t.methods[e]||[],t.methods[e].push(f)}return y},off:function(){var a,b,c=arguments;for(a=0,namesCount=c.length;a<namesCount;a+=1)b=c[a],b in t.methods&&delete t.methods[b];return y},trigger:function(a,c){var d=function(a){var d=t.methods[a];d&&d.map(function(a){b._.trigger(a,y,[c])})};return d("_"+a),d(a),y}};return new x}function c(a){var b,c="position";return a.currentStyle?b=a.currentStyle[c]:window.getComputedStyle&&(b=getComputedStyle(a)[c]),"fixed"==b}function d(){if(k.height()<=i.height())return 0;var b=a('<div style="visibility:hidden;width:100px" />').appendTo("body"),c=b[0].offsetWidth;b.css("overflow","scroll");var d=a('<div style="width:100%" />').appendTo(b),e=d[0].offsetWidth;return b.remove(),c-e}function e(b,c,d){if(a.isPlainObject(c))for(var e in c)f(b,e,c[e]);else f(b,c,d)}function f(a,b,c){a.setAttribute(("role"==b?"":"aria-")+b,c)}function g(b,c){a.isPlainObject(b)||(b={attribute:c}),c="";for(var d in b){var e=("role"==d?"":"aria-")+d,f=b[d];c+=null==f?"":e+'="'+b[d]+'"'}return c}function h(){try{return document.activeElement}catch(a){}}var i=a(window),j=a(document),k=a(document.documentElement);return b.klasses=function(a){return a=a||"picker",{picker:a,opened:a+"--opened",focused:a+"--focused",input:a+"__input",active:a+"__input--active",target:a+"__input--target",holder:a+"__holder",frame:a+"__frame",wrap:a+"__wrap",box:a+"__box"}},b._={group:function(a){for(var c,d="",e=b._.trigger(a.min,a);e<=b._.trigger(a.max,a,[e]);e+=a.i)c=b._.trigger(a.item,a,[e]),d+=b._.node(a.node,c[0],c[1],c[2]);return d},node:function(b,c,d,e){return c?(c=a.isArray(c)?c.join(""):c,d=d?' class="'+d+'"':"",e=e?" "+e:"","<"+b+d+e+">"+c+"</"+b+">"):""},lead:function(a){return(a<10?"0":"")+a},trigger:function(a,b,c){return"function"==typeof a?a.apply(b,c||[]):a},digits:function(a){return/\d/.test(a[1])?2:1},isDate:function(a){return{}.toString.call(a).indexOf("Date")>-1&&this.isInteger(a.getDate())},isInteger:function(a){return{}.toString.call(a).indexOf("Number")>-1&&a%1===0},ariaAttr:g},b.extend=function(c,d){a.fn[c]=function(e,f){var g=this.data(c);return"picker"==e?g:g&&"string"==typeof e?b._.trigger(g[e],g,[f]):this.each(function(){var f=a(this);f.data(c)||new b(this,c,d,e)})},a.fn[c].defaults=d.defaults},b}),function(a){"function"==typeof define&&define.amd?define(["picker","jquery"],a):"object"==typeof exports?module.exports=a(require("./picker.js"),require("jquery")):a(Picker,jQuery)}(function(a,b){function c(a,b){var c=this,d=a.$node[0],e=d.value,f=a.$node.data("value"),g=f||e,h=f?b.formatSubmit:b.format,i=function(){return d.currentStyle?"rtl"==d.currentStyle.direction:"rtl"==getComputedStyle(a.$root[0]).direction};c.settings=b,c.$node=a.$node,c.queue={min:"measure create",max:"measure create",now:"now create",select:"parse create validate",highlight:"parse navigate create validate",view:"parse create validate viewset",disable:"deactivate",enable:"activate"},c.item={},c.item.clear=null,c.item.disable=(b.disable||[]).slice(0),c.item.enable=-function(a){return a[0]===!0?a.shift():-1}(c.item.disable),c.set("min",b.min).set("max",b.max).set("now"),g?c.set("select",g,{format:h}):c.set("select",null).set("highlight",c.item.now),c.key={40:7,38:-7,39:function(){return i()?-1:1},37:function(){return i()?1:-1},go:function(a){var b=c.item.highlight,d=new Date(b.year,b.month,b.date+a);c.set("highlight",d,{interval:a}),this.render()}},a.on("render",function(){a.$root.find("."+b.klass.selectMonth).on("change",function(){var c=this.value;c&&(a.set("highlight",[a.get("view").year,c,a.get("highlight").date]),a.$root.find("."+b.klass.selectMonth).trigger("focus"))}),a.$root.find("."+b.klass.selectYear).on("change",function(){var c=this.value;c&&(a.set("highlight",[c,a.get("view").month,a.get("highlight").date]),a.$root.find("."+b.klass.selectYear).trigger("focus"))})},1).on("open",function(){var d="";c.disabled(c.get("now"))&&(d=":not(."+b.klass.buttonToday+")"),a.$root.find("button"+d+", select").attr("disabled",!1)},1).on("close",function(){a.$root.find("button, select").attr("disabled",!0)},1)}var d=7,e=6,f=a._;c.prototype.set=function(a,b,c){var d=this,e=d.item;return null===b?("clear"==a&&(a="select"),e[a]=b,d):(e["enable"==a?"disable":"flip"==a?"enable":a]=d.queue[a].split(" ").map(function(e){return b=d[e](a,b,c)}).pop(),"select"==a?d.set("highlight",e.select,c):"highlight"==a?d.set("view",e.highlight,c):a.match(/^(flip|min|max|disable|enable)$/)&&(e.select&&d.disabled(e.select)&&d.set("select",e.select,c),
10
+ e.highlight&&d.disabled(e.highlight)&&d.set("highlight",e.highlight,c)),d)},c.prototype.get=function(a){return this.item[a]},c.prototype.create=function(a,c,d){var e,g=this;return c=void 0===c?a:c,c==-(1/0)||c==1/0?e=c:b.isPlainObject(c)&&f.isInteger(c.pick)?c=c.obj:b.isArray(c)?(c=new Date(c[0],c[1],c[2]),c=f.isDate(c)?c:g.create().obj):c=f.isInteger(c)||f.isDate(c)?g.normalize(new Date(c),d):g.now(a,c,d),{year:e||c.getFullYear(),month:e||c.getMonth(),date:e||c.getDate(),day:e||c.getDay(),obj:e||c,pick:e||c.getTime()}},c.prototype.createRange=function(a,c){var d=this,e=function(a){return a===!0||b.isArray(a)||f.isDate(a)?d.create(a):a};return f.isInteger(a)||(a=e(a)),f.isInteger(c)||(c=e(c)),f.isInteger(a)&&b.isPlainObject(c)?a=[c.year,c.month,c.date+a]:f.isInteger(c)&&b.isPlainObject(a)&&(c=[a.year,a.month,a.date+c]),{from:e(a),to:e(c)}},c.prototype.withinRange=function(a,b){return a=this.createRange(a.from,a.to),b.pick>=a.from.pick&&b.pick<=a.to.pick},c.prototype.overlapRanges=function(a,b){var c=this;return a=c.createRange(a.from,a.to),b=c.createRange(b.from,b.to),c.withinRange(a,b.from)||c.withinRange(a,b.to)||c.withinRange(b,a.from)||c.withinRange(b,a.to)},c.prototype.now=function(a,b,c){return b=new Date,c&&c.rel&&b.setDate(b.getDate()+c.rel),this.normalize(b,c)},c.prototype.navigate=function(a,c,d){var e,f,g,h,i=b.isArray(c),j=b.isPlainObject(c),k=this.item.view;if(i||j){for(j?(f=c.year,g=c.month,h=c.date):(f=+c[0],g=+c[1],h=+c[2]),d&&d.nav&&k&&k.month!==g&&(f=k.year,g=k.month),e=new Date(f,g+(d&&d.nav?d.nav:0),1),f=e.getFullYear(),g=e.getMonth();new Date(f,g,h).getMonth()!==g;)h-=1;c=[f,g,h]}return c},c.prototype.normalize=function(a){return a.setHours(0,0,0,0),a},c.prototype.measure=function(a,b){var c=this;return b?"string"==typeof b?b=c.parse(a,b):f.isInteger(b)&&(b=c.now(a,b,{rel:b})):b="min"==a?-(1/0):1/0,b},c.prototype.viewset=function(a,b){return this.create([b.year,b.month,1])},c.prototype.validate=function(a,c,d){var e,g,h,i,j=this,k=c,l=d&&d.interval?d.interval:1,m=j.item.enable===-1,n=j.item.min,o=j.item.max,p=m&&j.item.disable.filter(function(a){if(b.isArray(a)){var d=j.create(a).pick;d<c.pick?e=!0:d>c.pick&&(g=!0)}return f.isInteger(a)}).length;if((!d||!d.nav)&&(!m&&j.disabled(c)||m&&j.disabled(c)&&(p||e||g)||!m&&(c.pick<=n.pick||c.pick>=o.pick)))for(m&&!p&&(!g&&l>0||!e&&l<0)&&(l*=-1);j.disabled(c)&&(Math.abs(l)>1&&(c.month<k.month||c.month>k.month)&&(c=k,l=l>0?1:-1),c.pick<=n.pick?(h=!0,l=1,c=j.create([n.year,n.month,n.date+(c.pick===n.pick?0:-1)])):c.pick>=o.pick&&(i=!0,l=-1,c=j.create([o.year,o.month,o.date+(c.pick===o.pick?0:1)])),!h||!i);)c=j.create([c.year,c.month,c.date+l]);return c},c.prototype.disabled=function(a){var c=this,d=c.item.disable.filter(function(d){return f.isInteger(d)?a.day===(c.settings.firstDay?d:d-1)%7:b.isArray(d)||f.isDate(d)?a.pick===c.create(d).pick:b.isPlainObject(d)?c.withinRange(d,a):void 0});return d=d.length&&!d.filter(function(a){return b.isArray(a)&&"inverted"==a[3]||b.isPlainObject(a)&&a.inverted}).length,c.item.enable===-1?!d:d||a.pick<c.item.min.pick||a.pick>c.item.max.pick},c.prototype.parse=function(a,b,c){var d=this,e={};return b&&"string"==typeof b?(c&&c.format||(c=c||{},c.format=d.settings.format),d.formats.toArray(c.format).map(function(a){var c=d.formats[a],g=c?f.trigger(c,d,[b,e]):a.replace(/^!/,"").length;c&&(e[a]=b.substr(0,g)),b=b.substr(g)}),[e.yyyy||e.yy,+(e.mm||e.m)-1,e.dd||e.d]):b},c.prototype.formats=function(){function a(a,b,c){var d=a.match(/\w+/)[0];return c.mm||c.m||(c.m=b.indexOf(d)+1),d.length}function b(a){return a.match(/\w+/)[0].length}return{d:function(a,b){return a?f.digits(a):b.date},dd:function(a,b){return a?2:f.lead(b.date)},ddd:function(a,c){return a?b(a):this.settings.weekdaysShort[c.day]},dddd:function(a,c){return a?b(a):this.settings.weekdaysFull[c.day]},m:function(a,b){return a?f.digits(a):b.month+1},mm:function(a,b){return a?2:f.lead(b.month+1)},mmm:function(b,c){var d=this.settings.monthsShort;return b?a(b,d,c):d[c.month]},mmmm:function(b,c){var d=this.settings.monthsFull;return b?a(b,d,c):d[c.month]},yy:function(a,b){return a?2:(""+b.year).slice(2)},yyyy:function(a,b){return a?4:b.year},toArray:function(a){return a.split(/(d{1,4}|m{1,4}|y{4}|yy|!.)/g)},toString:function(a,b){var c=this;return c.formats.toArray(a).map(function(a){return f.trigger(c.formats[a],c,[0,b])||a.replace(/^!/,"")}).join("")}}}(),c.prototype.isDateExact=function(a,c){var d=this;return f.isInteger(a)&&f.isInteger(c)||"boolean"==typeof a&&"boolean"==typeof c?a===c:(f.isDate(a)||b.isArray(a))&&(f.isDate(c)||b.isArray(c))?d.create(a).pick===d.create(c).pick:!(!b.isPlainObject(a)||!b.isPlainObject(c))&&(d.isDateExact(a.from,c.from)&&d.isDateExact(a.to,c.to))},c.prototype.isDateOverlap=function(a,c){var d=this,e=d.settings.firstDay?1:0;return f.isInteger(a)&&(f.isDate(c)||b.isArray(c))?(a=a%7+e,a===d.create(c).day+1):f.isInteger(c)&&(f.isDate(a)||b.isArray(a))?(c=c%7+e,c===d.create(a).day+1):!(!b.isPlainObject(a)||!b.isPlainObject(c))&&d.overlapRanges(a,c)},c.prototype.flipEnable=function(a){var b=this.item;b.enable=a||(b.enable==-1?1:-1)},c.prototype.deactivate=function(a,c){var d=this,e=d.item.disable.slice(0);return"flip"==c?d.flipEnable():c===!1?(d.flipEnable(1),e=[]):c===!0?(d.flipEnable(-1),e=[]):c.map(function(a){for(var c,g=0;g<e.length;g+=1)if(d.isDateExact(a,e[g])){c=!0;break}c||(f.isInteger(a)||f.isDate(a)||b.isArray(a)||b.isPlainObject(a)&&a.from&&a.to)&&e.push(a)}),e},c.prototype.activate=function(a,c){var d=this,e=d.item.disable,g=e.length;return"flip"==c?d.flipEnable():c===!0?(d.flipEnable(1),e=[]):c===!1?(d.flipEnable(-1),e=[]):c.map(function(a){var c,h,i,j;for(i=0;i<g;i+=1){if(h=e[i],d.isDateExact(h,a)){c=e[i]=null,j=!0;break}if(d.isDateOverlap(h,a)){b.isPlainObject(a)?(a.inverted=!0,c=a):b.isArray(a)?(c=a,c[3]||c.push("inverted")):f.isDate(a)&&(c=[a.getFullYear(),a.getMonth(),a.getDate(),"inverted"]);break}}if(c)for(i=0;i<g;i+=1)if(d.isDateExact(e[i],a)){e[i]=null;break}if(j)for(i=0;i<g;i+=1)if(d.isDateOverlap(e[i],a)){e[i]=null;break}c&&e.push(c)}),e.filter(function(a){return null!=a})},c.prototype.nodes=function(a){var b=this,c=b.settings,g=b.item,h=g.now,i=g.select,j=g.highlight,k=g.view,l=g.disable,m=g.min,n=g.max,o=function(a,b){return c.firstDay&&(a.push(a.shift()),b.push(b.shift())),f.node("thead",f.node("tr",f.group({min:0,max:d-1,i:1,node:"th",item:function(d){return[a[d],c.klass.weekdays,'scope=col title="'+b[d]+'"']}})))}((c.showWeekdaysFull?c.weekdaysFull:c.weekdaysLetter).slice(0),c.weekdaysFull.slice(0)),p=function(a){return f.node("div"," ",c.klass["nav"+(a?"Next":"Prev")]+(a&&k.year>=n.year&&k.month>=n.month||!a&&k.year<=m.year&&k.month<=m.month?" "+c.klass.navDisabled:""),"data-nav="+(a||-1)+" "+f.ariaAttr({role:"button",controls:b.$node[0].id+"_table"})+' title="'+(a?c.labelMonthNext:c.labelMonthPrev)+'"')},q=function(d){var e=c.showMonthsShort?c.monthsShort:c.monthsFull;return"short_months"==d&&(e=c.monthsShort),c.selectMonths&&void 0==d?f.node("select",f.group({min:0,max:11,i:1,node:"option",item:function(a){return[e[a],0,"value="+a+(k.month==a?" selected":"")+(k.year==m.year&&a<m.month||k.year==n.year&&a>n.month?" disabled":"")]}}),c.klass.selectMonth+" browser-default",(a?"":"disabled")+" "+f.ariaAttr({controls:b.$node[0].id+"_table"})+' title="'+c.labelMonthSelect+'"'):"short_months"==d?null!=i?f.node("div",e[i.month]):f.node("div",e[k.month]):f.node("div",e[k.month],c.klass.month)},r=function(d){var e=k.year,g=c.selectYears===!0?5:~~(c.selectYears/2);if(g){var h=m.year,i=n.year,j=e-g,l=e+g;if(h>j&&(l+=h-j,j=h),i<l){var o=j-h,p=l-i;j-=o>p?p:o,l=i}if(c.selectYears&&void 0==d)return f.node("select",f.group({min:j,max:l,i:1,node:"option",item:function(a){return[a,0,"value="+a+(e==a?" selected":"")]}}),c.klass.selectYear+" browser-default",(a?"":"disabled")+" "+f.ariaAttr({controls:b.$node[0].id+"_table"})+' title="'+c.labelYearSelect+'"')}return"raw"==d?f.node("div",e):f.node("div",e,c.klass.year)};return createDayLabel=function(){return null!=i?f.node("div",i.date):f.node("div",h.date)},createWeekdayLabel=function(){var a;a=null!=i?i.day:h.day;var b=c.weekdaysFull[a];return b},f.node("div",f.node("div",createWeekdayLabel(),"picker__weekday-display")+f.node("div",q("short_months"),c.klass.month_display)+f.node("div",createDayLabel(),c.klass.day_display)+f.node("div",r("raw"),c.klass.year_display),c.klass.date_display)+f.node("div",f.node("div",(c.selectYears?q()+r():q()+r())+p()+p(1),c.klass.header)+f.node("table",o+f.node("tbody",f.group({min:0,max:e-1,i:1,node:"tr",item:function(a){var e=c.firstDay&&0===b.create([k.year,k.month,1]).day?-7:0;return[f.group({min:d*a-k.day+e+1,max:function(){return this.min+d-1},i:1,node:"td",item:function(a){a=b.create([k.year,k.month,a+(c.firstDay?1:0)]);var d=i&&i.pick==a.pick,e=j&&j.pick==a.pick,g=l&&b.disabled(a)||a.pick<m.pick||a.pick>n.pick,o=f.trigger(b.formats.toString,b,[c.format,a]);return[f.node("div",a.date,function(b){return b.push(k.month==a.month?c.klass.infocus:c.klass.outfocus),h.pick==a.pick&&b.push(c.klass.now),d&&b.push(c.klass.selected),e&&b.push(c.klass.highlighted),g&&b.push(c.klass.disabled),b.join(" ")}([c.klass.day]),"data-pick="+a.pick+" "+f.ariaAttr({role:"gridcell",label:o,selected:!(!d||b.$node.val()!==o)||null,activedescendant:!!e||null,disabled:!!g||null})),"",f.ariaAttr({role:"presentation"})]}})]}})),c.klass.table,'id="'+b.$node[0].id+'_table" '+f.ariaAttr({role:"grid",controls:b.$node[0].id,readonly:!0})),c.klass.calendar_container)+f.node("div",f.node("button",c.today,"btn-flat picker__today","type=button data-pick="+h.pick+(a&&!b.disabled(h)?"":" disabled")+" "+f.ariaAttr({controls:b.$node[0].id}))+f.node("button",c.clear,"btn-flat picker__clear","type=button data-clear=1"+(a?"":" disabled")+" "+f.ariaAttr({controls:b.$node[0].id}))+f.node("button",c.close,"btn-flat picker__close","type=button data-close=true "+(a?"":" disabled")+" "+f.ariaAttr({controls:b.$node[0].id})),c.klass.footer)},c.defaults=function(a){return{labelMonthNext:"Next month",labelMonthPrev:"Previous month",labelMonthSelect:"Select a month",labelYearSelect:"Select a year",monthsFull:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],weekdaysFull:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],weekdaysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],weekdaysLetter:["S","M","T","W","T","F","S"],today:"Today",clear:"Clear",close:"Close",format:"d mmmm, yyyy",klass:{table:a+"table",header:a+"header",date_display:a+"date-display",day_display:a+"day-display",month_display:a+"month-display",year_display:a+"year-display",calendar_container:a+"calendar-container",navPrev:a+"nav--prev",navNext:a+"nav--next",navDisabled:a+"nav--disabled",month:a+"month",year:a+"year",selectMonth:a+"select--month",selectYear:a+"select--year",weekdays:a+"weekday",day:a+"day",disabled:a+"day--disabled",selected:a+"day--selected",highlighted:a+"day--highlighted",now:a+"day--today",infocus:a+"day--infocus",outfocus:a+"day--outfocus",footer:a+"footer",buttonClear:a+"button--clear",buttonToday:a+"button--today",buttonClose:a+"button--close"}}}(a.klasses().picker+"__"),a.extend("pickadate",c)}),function(a){function b(){var b=+a(this).attr("data-length"),c=+a(this).val().length,d=c<=b;a(this).parent().find('span[class="character-counter"]').html(c+"/"+b),e(d,a(this))}function c(b){var c=b.parent().find('span[class="character-counter"]');c.length||(c=a("<span/>").addClass("character-counter").css("float","right").css("font-size","12px").css("height",1),b.parent().append(c))}function d(){a(this).parent().find('span[class="character-counter"]').html("")}function e(a,b){var c=b.hasClass("invalid");a&&c?b.removeClass("invalid"):a||c||(b.removeClass("valid"),b.addClass("invalid"))}a.fn.characterCounter=function(){return this.each(function(){var e=a(this),f=e.parent().find('span[class="character-counter"]');if(!f.length){var g=void 0!==e.attr("data-length");g&&(e.on("input",b),e.on("focus",b),e.on("blur",d),c(e))}})},a(document).ready(function(){a("input, textarea").characterCounter()})}(jQuery),function(a){var b={init:function(b){var c={duration:200,dist:-100,shift:0,padding:0,fullWidth:!1,indicators:!1,noWrap:!1,onCycleTo:null};b=a.extend(c,b);var d=Materialize.objectSelectorString(a(this));return this.each(function(c){function e(){"undefined"!=typeof window.ontouchstart&&(O[0].addEventListener("touchstart",n),O[0].addEventListener("touchmove",o),O[0].addEventListener("touchend",p)),O[0].addEventListener("mousedown",n),O[0].addEventListener("mousemove",o),O[0].addEventListener("mouseup",p),O[0].addEventListener("mouseleave",p),O[0].addEventListener("click",l)}function f(a){return a.targetTouches&&a.targetTouches.length>=1?a.targetTouches[0].clientX:a.clientX}function g(a){return a.targetTouches&&a.targetTouches.length>=1?a.targetTouches[0].clientY:a.clientY}function h(a){return a>=x?a%x:a<0?h(x+a%x):a}function i(c){E=!0,O.hasClass("scrolling")||O.addClass("scrolling"),null!=N&&window.clearTimeout(N),N=window.setTimeout(function(){E=!1,O.removeClass("scrolling")},b.duration);var d,e,f,g,i,j,k,l=u;if(t="number"==typeof c?c:t,u=Math.floor((t+w/2)/w),f=t-u*w,g=f<0?1:-1,i=-g*f*2/w,e=x>>1,b.fullWidth?k="translateX(0)":(k="translateX("+(O[0].clientWidth-r)/2+"px) ",k+="translateY("+(O[0].clientHeight-s)/2+"px)"),P){var m=u%x,n=M.find(".indicator-item.active");n.index()!==m&&(n.removeClass("active"),M.find(".indicator-item").eq(m).addClass("active"))}for((!b.noWrap||u>=0&&u<x)&&(j=q[h(u)],a(j).hasClass("active")||(O.find(".carousel-item").removeClass("active"),a(j).addClass("active")),j.style[F]=k+" translateX("+-f/2+"px) translateX("+g*b.shift*i*d+"px) translateZ("+b.dist*i+"px)",j.style.zIndex=0,b.fullWidth?tweenedOpacity=1:tweenedOpacity=1-.2*i,j.style.opacity=tweenedOpacity,j.style.display="block"),d=1;d<=e;++d)b.fullWidth?(zTranslation=b.dist,tweenedOpacity=d===e&&f<0?1-i:1):(zTranslation=b.dist*(2*d+i*g),tweenedOpacity=1-.2*(2*d+i*g)),(!b.noWrap||u+d<x)&&(j=q[h(u+d)],j.style[F]=k+" translateX("+(b.shift+(w*d-f)/2)+"px) translateZ("+zTranslation+"px)",j.style.zIndex=-d,j.style.opacity=tweenedOpacity,j.style.display="block"),b.fullWidth?(zTranslation=b.dist,tweenedOpacity=d===e&&f>0?1-i:1):(zTranslation=b.dist*(2*d-i*g),tweenedOpacity=1-.2*(2*d-i*g)),(!b.noWrap||u-d>=0)&&(j=q[h(u-d)],j.style[F]=k+" translateX("+(-b.shift+(-w*d-f)/2)+"px) translateZ("+zTranslation+"px)",j.style.zIndex=-d,j.style.opacity=tweenedOpacity,j.style.display="block");if((!b.noWrap||u>=0&&u<x)&&(j=q[h(u)],j.style[F]=k+" translateX("+-f/2+"px) translateX("+g*b.shift*i+"px) translateZ("+b.dist*i+"px)",j.style.zIndex=0,b.fullWidth?tweenedOpacity=1:tweenedOpacity=1-.2*i,j.style.opacity=tweenedOpacity,j.style.display="block"),l!==u&&"function"==typeof b.onCycleTo){var o=O.find(".carousel-item").eq(h(u));b.onCycleTo.call(this,o,J)}}function j(){var a,b,c,d;a=Date.now(),b=a-H,H=a,c=t-G,G=t,d=1e3*c/(1+b),D=.8*d+.2*D}function k(){var a,c;B&&(a=Date.now()-H,c=B*Math.exp(-a/b.duration),c>2||c<-2?(i(C-c),requestAnimationFrame(k)):i(C))}function l(c){if(J)return c.preventDefault(),c.stopPropagation(),!1;if(!b.fullWidth){var d=a(c.target).closest(".carousel-item").index(),e=u%x-d;0!==e&&(c.preventDefault(),c.stopPropagation()),m(d)}}function m(a){var c=u%x-a;b.noWrap||(c<0?Math.abs(c+x)<Math.abs(c)&&(c+=x):c>0&&Math.abs(c-x)<c&&(c-=x)),c<0?O.trigger("carouselNext",[Math.abs(c)]):c>0&&O.trigger("carouselPrev",[c])}function n(a){a.preventDefault(),v=!0,J=!1,K=!1,z=f(a),A=g(a),D=B=0,G=t,H=Date.now(),clearInterval(I),I=setInterval(j,100)}function o(a){var b,c,d;if(v)if(b=f(a),y=g(a),c=z-b,d=Math.abs(A-y),d<30&&!K)(c>2||c<-2)&&(J=!0,z=b,i(t+c));else{if(J)return a.preventDefault(),a.stopPropagation(),!1;K=!0}if(J)return a.preventDefault(),a.stopPropagation(),!1}function p(a){if(v)return v=!1,clearInterval(I),C=t,(D>10||D<-10)&&(B=.9*D,C=t+B),C=Math.round(C/w)*w,b.noWrap&&(C>=w*(x-1)?C=w*(x-1):C<0&&(C=0)),B=C-t,H=Date.now(),requestAnimationFrame(k),J&&(a.preventDefault(),a.stopPropagation()),!1}var q,r,s,t,u,v,w,x,z,A,B,C,D,E,F,G,H,I,J,K,L=d+c,M=a('<ul class="indicators"></ul>'),N=null,O=a(this),P=O.attr("data-indicators")||b.indicators,Q=function(){var b=O.find(".carousel-item img").first();if(b.length)b.prop("complete")?O.css("height",b.height()):b.on("load",function(){O.css("height",a(this).height())});else{var c=O.find(".carousel-item").first().height();O.css("height",c)}};return b.fullWidth&&(b.dist=0,Q(),P&&O.find(".carousel-fixed-item").addClass("with-indicators")),O.hasClass("initialized")?(a(window).trigger("resize"),a(this).trigger("carouselNext",[1e-6]),!0):(O.addClass("initialized"),v=!1,t=C=0,q=[],r=O.find(".carousel-item").first().innerWidth(),s=O.find(".carousel-item").first().innerHeight(),w=2*r+b.padding,O.find(".carousel-item").each(function(b){if(q.push(a(this)[0]),P){var c=a('<li class="indicator-item"></li>');0===b&&c.addClass("active"),c.click(function(b){b.stopPropagation();var c=a(this).index();m(c)}),M.append(c)}}),P&&O.append(M),x=q.length,F="transform",["webkit","Moz","O","ms"].every(function(a){var b=a+"Transform";return"undefined"==typeof document.body.style[b]||(F=b,!1)}),a(window).off("resize.carousel-"+L).on("resize.carousel-"+L,function(){b.fullWidth?(r=O.find(".carousel-item").first().innerWidth(),s=O.find(".carousel-item").first().innerHeight(),w=2*r+b.padding,t=2*u*r,C=t):i()}),e(),i(t),a(this).on("carouselNext",function(a,b){void 0===b&&(b=1),C=w*Math.round(t/w)+w*b,t!==C&&(B=C-t,H=Date.now(),requestAnimationFrame(k))}),a(this).on("carouselPrev",function(a,b){void 0===b&&(b=1),C=w*Math.round(t/w)-w*b,t!==C&&(B=C-t,H=Date.now(),requestAnimationFrame(k))}),void a(this).on("carouselSet",function(a,b){void 0===b&&(b=0),m(b)}))})},next:function(b){a(this).trigger("carouselNext",[b])},prev:function(b){a(this).trigger("carouselPrev",[b])},set:function(b){a(this).trigger("carouselSet",[b])}};a.fn.carousel=function(c){return b[c]?b[c].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof c&&c?void a.error("Method "+c+" does not exist on jQuery.carousel"):b.init.apply(this,arguments)}}(jQuery),function(a){var b={init:function(b){return this.each(function(){var c=a("#"+a(this).attr("data-activates")),d=(a("body"),a(this)),e=d.parent(".tap-target-wrapper"),f=e.find(".tap-target-wave"),g=e.find(".tap-target-origin"),h=d.find(".tap-target-content");e.length||(e=d.wrap(a('<div class="tap-target-wrapper"></div>')).parent()),h.length||(h=a('<div class="tap-target-content"></div>'),d.append(h)),f.length||(f=a('<div class="tap-target-wave"></div>'),g.length||(g=c.clone(!0,!0),g.addClass("tap-target-origin"),g.removeAttr("id"),g.removeAttr("style"),f.append(g)),e.append(f));var i=function(){e.is(".open")||(e.addClass("open"),setTimeout(function(){g.off("click.tapTarget").on("click.tapTarget",function(a){j(),g.off("click.tapTarget")}),a(document).off("click.tapTarget").on("click.tapTarget",function(b){j(),a(document).off("click.tapTarget")});var b=Materialize.throttle(function(){k()},200);a(window).off("resize.tapTarget").on("resize.tapTarget",b)},0))},j=function(){e.is(".open")&&(e.removeClass("open"),g.off("click.tapTarget"),a(document).off("click.tapTarget"),a(window).off("resize.tapTarget"))},k=function(){var b="fixed"===c.css("position");if(!b)for(var g=c.parents(),i=0;i<g.length&&!(b="fixed"==a(g[i]).css("position"));i++);var j=c.outerWidth(),k=c.outerHeight(),l=b?c.offset().top-a(document).scrollTop():c.offset().top,m=b?c.offset().left-a(document).scrollLeft():c.offset().left,n=a(window).width(),o=a(window).height(),p=n/2,q=o/2,r=m<=p,s=m>p,t=l<=q,u=l>q,v=m>=.25*n&&m<=.75*n,w=d.outerWidth(),x=d.outerHeight(),y=l+k/2-x/2,z=m+j/2-w/2,A=b?"fixed":"absolute",B=v?w:w/2+j,C=x/2,D=t?x/2:0,E=0,F=r&&!v?w/2-j:0,G=0,H=j,I=u?"bottom":"top",J=j>k?2*j:2*j,K=J,L=x/2-K/2,M=w/2-J/2,N={};N.top=t?y:"",N.right=s?n-z-w:"",N.bottom=u?o-y-x:"",N.left=r?z:"",N.position=A,e.css(N),h.css({width:B,height:C,top:D,right:G,bottom:E,left:F,padding:H,verticalAlign:I}),f.css({top:L,left:M,width:J,height:K})};"open"==b&&(k(),i()),"close"==b&&j()})},open:function(){},close:function(){}};a.fn.tapTarget=function(c){return b[c]||"object"==typeof c?b.init.apply(this,arguments):void a.error("Method "+c+" does not exist on jQuery.tap-target")}}(jQuery);
include/wpmdr.css ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ a{
2
+ box-shadow:0 0 0 0!important;
3
+ }
4
+ .side-btn{
5
+ width:100%;
6
+ }
7
+ .side-btn:hover{
8
+ color:white;
9
+ }
10
+ .wpmdr-hover:hover{
11
+ color:white;
12
+ }
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: Prasad Kirpekar
3
  Donate link: - https://paypal.me/prasadkirpekar
4
  Tags: free,theme,meta,date,author, website, posts, pages, metadata, post, home page, remover, entry-meta, css,front page
5
  Requires at least: 3.0.1
6
- Tested up to: 4.7
7
- Stable tag: 1.3.0
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -13,24 +13,25 @@ Remove meta author and date information from posts and pages. Hide from Humans a
13
  == Description ==
14
 
15
  Remove Meta,Author and Date in click. Install. Activate. And Done!
16
- <h2>How to remove Author Meta and Date from posts and pages?</h2>
17
 
18
- 1. Install WP Meta and Date remover.
19
- 2. Activate Plugin.
20
- 3. Choose whether to hide from Backend(Page Source) or Frontend or Both
21
- 4. Save settings
22
- 5. And you done!
23
 
24
 
25
- <h2>Two way removal</h2>
26
 
27
  This plugin uses two methods to erase your meta
28
- <h2>Removal using CSS file</h2>
 
29
  Plugin register custom CSS which hides any information contained by meda data class.
30
  CSS file provided with this plugin works great. You also can edit that n file in plugin editor.
31
  For more support [Buy premium support](https://www.fiverr.com/prasadkirpekar/customize-your-theme-css)
32
 
33
- <h2>Removal using php</h2>
34
  Plugin filters results of functions like get_date(),get_time() etc.
35
  In some cases CSS file doesn't work, thats why there is removal using php code.
36
  Plugin removes Meta data from source code. Which means even search engines can't see it.
@@ -60,10 +61,14 @@ Use built in automatic installer or,
60
  == Screenshots ==
61
 
62
  1. Settings Window
63
- 2. Before activation
64
- 3. After activation
65
 
66
  == Changelog ==
 
 
 
 
67
  1.3.0
68
  * Added option to choose whether to hide from home page or not.
69
  1.2.2
3
  Donate link: - https://paypal.me/prasadkirpekar
4
  Tags: free,theme,meta,date,author, website, posts, pages, metadata, post, home page, remover, entry-meta, css,front page
5
  Requires at least: 3.0.1
6
+ Tested up to: 4.8
7
+ Stable tag: 1.5.0
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
13
  == Description ==
14
 
15
  Remove Meta,Author and Date in click. Install. Activate. And Done!
16
+ ==How to remove Author Meta and Date from posts and pages?==
17
 
18
+ 1. Install WP Meta and Date remover.
19
+ 2. Activate Plugin.
20
+ 3. Choose whether to hide from Backend(Page Source) or Frontend or Both
21
+ 4. Save settings
22
+ 5. And you done!
23
 
24
 
25
+ ==Two way removal==
26
 
27
  This plugin uses two methods to erase your meta
28
+
29
+ **Removal using CSS file**
30
  Plugin register custom CSS which hides any information contained by meda data class.
31
  CSS file provided with this plugin works great. You also can edit that n file in plugin editor.
32
  For more support [Buy premium support](https://www.fiverr.com/prasadkirpekar/customize-your-theme-css)
33
 
34
+ **Removal using php**
35
  Plugin filters results of functions like get_date(),get_time() etc.
36
  In some cases CSS file doesn't work, thats why there is removal using php code.
37
  Plugin removes Meta data from source code. Which means even search engines can't see it.
61
  == Screenshots ==
62
 
63
  1. Settings Window
64
+ 2. After activation
65
+ 3. Before activation
66
 
67
  == Changelog ==
68
+ 1.5
69
+ * Improved User Interface
70
+ 1.4.0
71
+ * You can now choose to show Date and Meta on indivisual posts.
72
  1.3.0
73
  * Added option to choose whether to hide from home page or not.
74
  1.2.2
wp-meta-and-date-remover.php CHANGED
@@ -3,9 +3,9 @@
3
  Plugin Name: WP Meta and Date Remover
4
  Plugin URI: mailto:prasadkirpekar@outlook.com
5
  Description: Remove Meta information such as Author and Date from posts and pages.
6
- Version: 1.3.0
7
  Author: Prasad Kirpekar
8
- Author URI: http://twitter.com.com/kirpekarprasad
9
  License: GPL v2
10
  Copyright: Prasad Kirpekar
11
 
@@ -25,7 +25,7 @@ Copyright: Prasad Kirpekar
25
  */
26
 
27
  function wpmdr_extra_links($links){
28
- $donate="<a href='https://paypal.me/prasadkirpekar'>Support Development</a>";
29
  $fiverr="<a href='http://bit.ly/2bzAUb6'>More Customization</a>";
30
  $setting_link = '<a href="../wp-admin/options-general.php?page=wp-meta-and-date-remover.php">Settings</a>';
31
 
@@ -37,6 +37,26 @@ $setting_link = '<a href="../wp-admin/options-general.php?page=wp-meta-and-date-
37
  }
38
  $plugin = plugin_basename(__FILE__);
39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  //Removal using css
41
 
42
  function wpmdr_inline_style(){
@@ -50,6 +70,7 @@ function wpmdr_settings()
50
  $disable_php=get_option('wpmdr_disable_php');
51
  $disable_css=get_option('wpmdr_disable_css');
52
  $from_=get_option('wpmdr_from_');
 
53
  if(isset($_POST['submitted']))
54
  {
55
  if(isset($_POST['wpmdr_from_home'])) $from_['home']="1";
@@ -70,43 +91,126 @@ function wpmdr_settings()
70
  echo '<div class="updated fade"><p>Settings Saved! </p></div>';
71
  }
72
  $action_url = $_SERVER['REQUEST_URI'];
73
- include "admin/options.php";
74
  }
75
 
76
  function wpmdr_admin_settings()
77
  {
78
- add_options_page('WP Meta and Date Remover', 'WP Meta and Date Remover', 'manage_options', basename(__FILE__), 'wpmdr_settings');
79
-
80
  }
81
  function wpmdr_init_option(){
82
  $css=".entry-meta {display:none !important;}.home .entry-meta { display: none; }.entry-footer {display:none !important;}.home .entry-footer { display: none; }";
83
 
84
- add_option('wpmdr_from_',array('home'=>'1'));
 
 
 
85
  add_option('wpmdr_css',$css);
86
  add_option('wpmdr_disable_php',"0");
87
  add_option('wpmdr_disable_css',"0");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  }
89
 
 
 
 
90
  function wpmdr_php_filter_option(){
91
  $from_=get_option('wpmdr_from_');
92
- if(is_front_page()||is_home()){
93
  if($from_['home']=="1") wpmdr_remove_meta_php();
94
  else return;
95
  }
96
- else wpmdr_remove_meta_php();
 
 
 
 
 
 
 
 
97
  }
98
 
99
 
100
  function wpmdr_css_filter_option(){
101
  $from_=get_option('wpmdr_from_');
102
- if(is_front_page()||is_home()){
103
  if($from_['home']=="1") wpmdr_inline_style();
104
  else return;
105
  }
106
- else wpmdr_inline_style();
 
 
 
 
 
 
 
 
107
  }
108
-
109
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
 
111
  // removal using php.
112
  //some times css removal don't work for every theme.
@@ -126,10 +230,14 @@ function wpmdr_remove_meta_php() {
126
 
127
  }
128
 
 
129
  //do everything
130
  register_activation_hook(__FILE__, 'wpmdr_init_option');
131
 
132
- add_action('wp_head','wpmdr_inline_style');
133
  add_filter("plugin_action_links_$plugin", 'wpmdr_extra_links' );
134
  add_action('loop_start', 'wpmdr_php_filter_option');
135
- add_action('admin_menu','wpmdr_admin_settings');
 
 
 
3
  Plugin Name: WP Meta and Date Remover
4
  Plugin URI: mailto:prasadkirpekar@outlook.com
5
  Description: Remove Meta information such as Author and Date from posts and pages.
6
+ Version: 1.5
7
  Author: Prasad Kirpekar
8
+ Author URI: http://twitter.com/kirpekarprasad
9
  License: GPL v2
10
  Copyright: Prasad Kirpekar
11
 
25
  */
26
 
27
  function wpmdr_extra_links($links){
28
+ $donate="<a href='http://bit.ly/PKDonate'>Support Development</a>";
29
  $fiverr="<a href='http://bit.ly/2bzAUb6'>More Customization</a>";
30
  $setting_link = '<a href="../wp-admin/options-general.php?page=wp-meta-and-date-remover.php">Settings</a>';
31
 
37
  }
38
  $plugin = plugin_basename(__FILE__);
39
 
40
+ function wpmdr_reg_scripts(){
41
+ wp_register_script( 'wpmdr_md_script',plugin_dir_url(__FILE__).'include/materialize/materialize.min.js' );
42
+ wp_register_script( 'wpmdr_cm_script',plugin_dir_url(__FILE__).'include/codemirror/codemirror.js' );
43
+ wp_register_script('wpmdr_cm_lang',plugin_dir_url(__FILE__).'include/codemirror/css.js' );
44
+ wp_register_script( 'wpmdr_cm_init',plugin_dir_url(__FILE__).'include/codemirror/cm_init.js' );
45
+ wp_register_script( 'wpmdr_cm_ar',plugin_dir_url(__FILE__).'include/codemirror/autorefresh.js' );
46
+ }
47
+ function wpmdr_enqueue_scripts(){
48
+ wp_enqueue_script('wpmdr_md_script');
49
+ wp_enqueue_script('wpmdr_cm_script');
50
+ wp_enqueue_script('wpmdr_cm_lang');
51
+ wp_enqueue_script('wpmdr_cm_init');
52
+ wp_enqueue_script('wpmdr_cm_ar');
53
+ wp_enqueue_style('wpmdr_md_style',plugin_dir_url(__FILE__).'include/materialize/materialize.min.css');
54
+ wp_enqueue_style('wpmdr_cm_style',plugin_dir_url(__FILE__).'include/codemirror/codemirror.css');
55
+ wp_enqueue_style('wpmdr_cm_theme',plugin_dir_url(__FILE__).'include/codemirror/dracula.css');
56
+ wp_enqueue_style('wpmdr_css',plugin_dir_url(__FILE__).'include/wpmdr.css');
57
+ }
58
+ add_action('admin_init','wpmdr_reg_scripts');
59
+
60
  //Removal using css
61
 
62
  function wpmdr_inline_style(){
70
  $disable_php=get_option('wpmdr_disable_php');
71
  $disable_css=get_option('wpmdr_disable_css');
72
  $from_=get_option('wpmdr_from_');
73
+
74
  if(isset($_POST['submitted']))
75
  {
76
  if(isset($_POST['wpmdr_from_home'])) $from_['home']="1";
91
  echo '<div class="updated fade"><p>Settings Saved! </p></div>';
92
  }
93
  $action_url = $_SERVER['REQUEST_URI'];
94
+ include "admin/wpmdr-options.php";
95
  }
96
 
97
  function wpmdr_admin_settings()
98
  {
99
+ $page=add_options_page('WP Meta and Date Remover', 'WP Meta and Date Remover', 'manage_options', basename(__FILE__), 'wpmdr_settings');
100
+ add_action('admin_print_scripts-' . $page, 'wpmdr_enqueue_scripts');
101
  }
102
  function wpmdr_init_option(){
103
  $css=".entry-meta {display:none !important;}.home .entry-meta { display: none; }.entry-footer {display:none !important;}.home .entry-footer { display: none; }";
104
 
105
+
106
+ if(!add_option('wpmdr_from_',array('home'=>'1','help_notice'=>'0'))){
107
+ update_option('wpmdr_from_',array('home'=>'1','help_notice'=>'0'));
108
+ }
109
  add_option('wpmdr_css',$css);
110
  add_option('wpmdr_disable_php',"0");
111
  add_option('wpmdr_disable_css',"0");
112
+ add_action( 'admin_notices', 'wpmdr_notice' );
113
+ }
114
+
115
+
116
+
117
+ function wpmdr_menu()
118
+ {
119
+ global $post;
120
+
121
+ /* check if this is a post, if not then we won't add the custom field */
122
+ /* change this post type to any type you want to add the custom field to */
123
+ if (get_post_type($post) != 'post') return false;
124
+
125
+ /* get the value corrent value of the custom field */
126
+ $value = get_post_meta($post->ID, 'wpmdr_menu', true);
127
+ if(empty($value)){
128
+ add_post_meta($postid, 'wpmdr_menu', 1, true );
129
+ $value=1;
130
+
131
+ }
132
+
133
+ ?>
134
+ <div class="misc-pub-section">
135
+ <label><input type="checkbox"<?php echo (($value==1)? ' checked="checked"' :null ) ?> value="1" name="wpmdr_menu" /> Remove Meta and Date</label>
136
+ </div>
137
+ <?php
138
+ }
139
+
140
+ function wpmdr_save_postdata($postid)
141
+ {
142
+
143
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return false;
144
+
145
+
146
+ if ( !current_user_can( 'edit_page', $postid ) ) return false;
147
+
148
+
149
+ if(empty($postid) || $_POST['post_type'] != 'post' ) return false;
150
+
151
+ if(isset($_POST['wpmdr_menu'])){
152
+
153
+ update_post_meta($postid, 'wpmdr_menu',1);
154
+ }
155
+ else{
156
+
157
+ update_post_meta($postid, 'wpmdr_menu',2);
158
+ }
159
  }
160
 
161
+ add_action( 'post_submitbox_misc_actions', 'wpmdr_menu' );
162
+ add_action( 'save_post', 'wpmdr_save_postdata');
163
+
164
  function wpmdr_php_filter_option(){
165
  $from_=get_option('wpmdr_from_');
166
+ if(is_home() || is_front_page() ){
167
  if($from_['home']=="1") wpmdr_remove_meta_php();
168
  else return;
169
  }
170
+ else{
171
+ global $post;
172
+ if (get_post_type($post) == 'post'){
173
+ if(get_post_meta($post->ID, 'wpmdr_menu', true)!=1)
174
+ return;
175
+ else wpmdr_remove_meta_php();
176
+ }
177
+ return;
178
+ }
179
  }
180
 
181
 
182
  function wpmdr_css_filter_option(){
183
  $from_=get_option('wpmdr_from_');
184
+ if(is_home() || is_front_page()){
185
  if($from_['home']=="1") wpmdr_inline_style();
186
  else return;
187
  }
188
+ else{
189
+ global $post;
190
+ if (get_post_type($post) == 'post'){
191
+ if(get_post_meta($post->ID, 'wpmdr_menu', true)!=1)
192
+ return;
193
+ else wpmdr_inline_style();
194
+ }
195
+ return;
196
+ }
197
  }
198
+ function wpmdr_notice() {
199
+ $from_=get_option('wpmdr_from_');
200
+
201
+ if($from_['help_notice']=="0"){
202
+ echo '
203
+ <div class="notice notice-success is-dismissible">
204
+ <p>Thank you for Installing WP Meta and Date Remover. Read this post see <a href="http://bit.ly/2tx3gHD" target="_blank"><b>how to configure this plugin.</b></a><br/>
205
+ You may support development of this plugin by donating tiny amount <a href="http://bit.ly/PKDonate" target="_blank"><b>here</b></a>.
206
+ </p>
207
+ </div>';;
208
+ $from_['help_notice']="1";
209
+ update_option('wpmdr_from_',$from_);
210
+ }
211
+
212
+ }
213
+ add_action( 'admin_notices', 'wpmdr_notice' );
214
 
215
  // removal using php.
216
  //some times css removal don't work for every theme.
230
 
231
  }
232
 
233
+
234
  //do everything
235
  register_activation_hook(__FILE__, 'wpmdr_init_option');
236
 
237
+ add_action('wp_head','wpmdr_css_filter_option');
238
  add_filter("plugin_action_links_$plugin", 'wpmdr_extra_links' );
239
  add_action('loop_start', 'wpmdr_php_filter_option');
240
+ add_action('admin_menu','wpmdr_admin_settings');
241
+
242
+
243
+