Better WordPress reCAPTCHA (with no CAPTCHA reCAPTCHA) - Version 2.0.3

Version Description

(2016-01-13) =

  • New Features
    • Allow adding custom CSS rules to control the look and feel of recaptcha instances. To enable this feature, navigate to BWP reCAPT >> Theme Options, choose to enable Custom CSS, and then customize the default CSS rules however you like.
  • Enhancements
    • Allow setting a request method to work around the "invalid-json" error. With this change fsockopen is preferred to cURL, and will be the first to be used to communicate with reCAPTCHA's server.
  • Other Changes
    • Marked as compatible with WordPress 4.4+.
    • Update language template file and translation files. If you're a translator, please help translating this plugin (your name and website will be listed on this plugin's page!) For more info, see: http://betterwp.net/wordpress-tips/create-pot-file-using-poedit/
  • Bugs fixed
    • Fix a bug that results in captcha not showing on certain login pages. Affected login pages include:
      • Login page that uses secured HTTP (HTTPS)
      • Login page of a child blog in a sub-directory multisite installation.
Download this release

Release Info

Developer OddOneOut
Plugin Icon wp plugin Better WordPress reCAPTCHA (with no CAPTCHA reCAPTCHA)
Version 2.0.3
Comparing to
See all releases

Code changes from version 2.0.2 to 2.0.3

Files changed (57) hide show
  1. bwp-recaptcha.php +2 -2
  2. bwp-recaptcha.pot +516 -394
  3. includes/class-bwp-recaptcha.php +206 -21
  4. includes/provider/abstract-provider.php +15 -8
  5. includes/provider/v1.php +6 -0
  6. includes/provider/v2.php +73 -9
  7. languages/bwp-recaptcha-de_DE.mo +0 -0
  8. languages/bwp-recaptcha-de_DE.po +731 -427
  9. languages/bwp-recaptcha-es_ES.mo +0 -0
  10. languages/bwp-recaptcha-es_ES.po +760 -307
  11. languages/bwp-recaptcha-fr_FR.mo +0 -0
  12. languages/bwp-recaptcha-fr_FR.po +804 -492
  13. languages/bwp-recaptcha-hr.mo +0 -0
  14. languages/bwp-recaptcha-hr.po +717 -414
  15. languages/bwp-recaptcha-hu_HU.mo +0 -0
  16. languages/bwp-recaptcha-hu_HU.po +754 -307
  17. readme.txt +47 -20
  18. vendor/autoload.php +1 -1
  19. vendor/composer/ClassLoader.php +3 -3
  20. vendor/composer/autoload_classmap.php +69 -0
  21. vendor/composer/autoload_real.php +3 -8
  22. vendor/composer/installed.json +16 -12
  23. vendor/composer/installers/src/Composer/Installers/BaseInstaller.php +5 -1
  24. vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php +81 -3
  25. vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php +9 -0
  26. vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php +12 -6
  27. vendor/composer/installers/src/Composer/Installers/CraftInstaller.php +26 -0
  28. vendor/composer/installers/src/Composer/Installers/Installer.php +16 -3
  29. vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php +10 -0
  30. vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php +9 -0
  31. vendor/composer/installers/src/Composer/Installers/Plugin.php +17 -0
  32. vendor/kminh/bwp-framework/assets/option-page/css/less/bwp-tabs.less +50 -0
  33. vendor/kminh/bwp-framework/assets/option-page/css/less/bwp.less +275 -326
  34. vendor/kminh/bwp-framework/assets/option-page/css/less/codemirror.less +41 -0
  35. vendor/kminh/bwp-framework/assets/option-page/css/less/form.less +70 -2
  36. vendor/kminh/bwp-framework/assets/option-page/css/less/mixins.less +33 -0
  37. vendor/kminh/bwp-framework/assets/option-page/css/less/modal.less +0 -12
  38. vendor/kminh/bwp-framework/assets/option-page/css/less/style.less +4 -0
  39. vendor/kminh/bwp-framework/assets/option-page/css/less/table.less +137 -0
  40. vendor/kminh/bwp-framework/assets/option-page/css/less/variables.less +5 -0
  41. vendor/kminh/bwp-framework/assets/option-page/css/style.css +303 -149
  42. vendor/kminh/bwp-framework/assets/option-page/css/style.css.map +0 -1
  43. vendor/kminh/bwp-framework/assets/option-page/dist/css/op.min.css +1 -1
  44. vendor/kminh/bwp-framework/assets/option-page/dist/js/code-editor.min.js +6 -0
  45. vendor/kminh/bwp-framework/assets/option-page/dist/js/modal.min.js +1 -1
  46. vendor/kminh/bwp-framework/assets/option-page/dist/js/op.min.js +1 -1
  47. vendor/kminh/bwp-framework/assets/option-page/js/codemirror.js +118 -0
  48. vendor/kminh/bwp-framework/assets/option-page/js/modal.js +12 -0
  49. vendor/kminh/bwp-framework/assets/option-page/js/op.js +103 -6
  50. vendor/kminh/bwp-framework/assets/option-page/js/paypal.js +8 -5
  51. vendor/kminh/bwp-framework/assets/option-page/js/popover.js +5 -2
  52. vendor/kminh/bwp-framework/assets/vendor/codemirror/addon/display/placeholder.js +60 -0
  53. vendor/kminh/bwp-framework/assets/vendor/codemirror/addon/selection/active-line.js +71 -0
  54. vendor/kminh/bwp-framework/assets/vendor/codemirror/codemirror.css +334 -0
  55. vendor/kminh/bwp-framework/assets/vendor/codemirror/codemirror.js +8887 -0
  56. vendor/kminh/bwp-framework/assets/vendor/codemirror/codemirror.min.css +1 -0
  57. vendor/kminh/bwp-framework/assets/vendor/codemirror/mode/css/css.js +423 -0
bwp-recaptcha.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Better WordPress reCAPTCHA
4
  Plugin URI: http://betterwp.net/wordpress-plugins/bwp-recaptcha/
5
  Description: This plugin utilizes Google reCAPTCHA to help your blog stay clear of spams. BWP reCAPTCHA supports no CAPTCHA reCAPTCHA, Contact Form 7 and Akismet.
6
- Version: 2.0.2
7
  Text Domain: bwp-recaptcha
8
  Domain Path: /languages/
9
  Author: Khang Minh
@@ -19,7 +19,7 @@ if ((isset($bwp_capt) && $bwp_capt instanceof BWP_RECAPTCHA) || !defined('ABSPAT
19
 
20
  $bwp_capt_meta = array(
21
  'title' => 'Better WordPress reCAPTCHA',
22
- 'version' => '2.0.2',
23
  'domain' => 'bwp-recaptcha'
24
  );
25
 
3
  Plugin Name: Better WordPress reCAPTCHA
4
  Plugin URI: http://betterwp.net/wordpress-plugins/bwp-recaptcha/
5
  Description: This plugin utilizes Google reCAPTCHA to help your blog stay clear of spams. BWP reCAPTCHA supports no CAPTCHA reCAPTCHA, Contact Form 7 and Akismet.
6
+ Version: 2.0.3
7
  Text Domain: bwp-recaptcha
8
  Domain Path: /languages/
9
  Author: Khang Minh
19
 
20
  $bwp_capt_meta = array(
21
  'title' => 'Better WordPress reCAPTCHA',
22
+ 'version' => '2.0.3',
23
  'domain' => 'bwp-recaptcha'
24
  );
25
 
bwp-recaptcha.pot CHANGED
@@ -1,577 +1,699 @@
1
- #, fuzzy
 
 
 
 
2
  msgid ""
3
  msgstr ""
4
- "Project-Id-Version: BWP reCAPTCHA\n"
5
- "POT-Creation-Date: 2015-10-30 13:33+0700\n"
6
- "PO-Revision-Date: 2014-07-04 22:37+0700\n"
7
- "Last-Translator: Khang Minh <contact@betterwp.net>\n"
8
- "Language-Team: BWP <contact@betterwp.net>\n"
 
9
  "Language: en_US\n"
10
  "MIME-Version: 1.0\n"
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
- "X-Generator: Poedit 1.8.5\n"
14
- "X-Poedit-Basepath: .\n"
15
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
16
- "X-Poedit-SourceCharset: UTF-8\n"
17
- "X-Poedit-KeywordsList: __;_e;_;gettext;gettext_noop;_x;_ex;t;te\n"
18
- "X-Poedit-SearchPath-0: includes\n"
19
- "X-Poedit-SearchPath-1: vendor/kminh/bwp-framework/src\n"
20
 
21
- #: includes/addons/contact-form-7/captcha-shortcode.php:159
22
- #: includes/addons/contact-form-7/captcha-shortcode.php:196
23
- msgid "Name"
24
- msgstr ""
25
-
26
- #: includes/addons/contact-form-7/captcha-shortcode.php:170
27
- msgid "Insert Tag"
28
- msgstr ""
29
-
30
- #: includes/addons/contact-form-7/captcha-shortcode.php:205
31
- msgid "Copy this code and paste it into the form left."
32
  msgstr ""
 
 
 
33
 
34
- #: includes/addons/contact-form-7/captcha-shortcode.php:220
35
- msgid "This reCAPTCHA tag is provided by the BWP reCAPTCHA WordPress plugin."
36
- msgstr ""
37
 
38
- #: includes/addons/contact-form-7/captcha-shortcode.php:225
39
- #, php-format
40
  msgid ""
41
- "Please refer to <a target=\"_blank\" href=\"%s\">BWP reCAPTCHA's "
42
- "documentation</a> for a quick guide on how to customize the look and feel of "
43
- "this tag."
44
  msgstr ""
 
 
45
 
46
- #: includes/class-bwp-recaptcha.php:113
47
  msgid ""
48
  "<strong>ERROR:</strong> Incorrect or empty reCAPTCHA response, please try "
49
  "again."
50
  msgstr ""
 
 
 
 
 
 
51
 
52
- #: includes/class-bwp-recaptcha.php:115
 
 
 
 
53
  #, php-format
54
  msgid ""
55
- "Error: Incorrect or empty reCAPTCHA response, please click the back button "
56
- "on your browser's toolbar or click on %s to go back."
57
  msgstr ""
 
 
58
 
59
- #: includes/class-bwp-recaptcha.php:120
60
- msgid "Incorrect or empty reCAPTCHA response, please try again."
61
- msgstr ""
62
 
63
- #: includes/class-bwp-recaptcha.php:149 includes/class-bwp-recaptcha.php:526
64
- msgid "General Options"
 
65
  msgstr ""
 
66
 
67
- #: includes/class-bwp-recaptcha.php:152 includes/class-bwp-recaptcha.php:535
68
- msgid "Theme Options"
 
 
69
  msgstr ""
 
 
70
 
71
- #: includes/class-bwp-recaptcha.php:265
72
- msgid "Read Profile"
 
73
  msgstr ""
 
74
 
75
- #: includes/class-bwp-recaptcha.php:266
76
- msgid "Manage Options"
77
- msgstr ""
78
 
79
- #: includes/class-bwp-recaptcha.php:515
80
- msgid "Better WordPress reCAPTCHA"
81
- msgstr ""
82
 
83
- #: includes/class-bwp-recaptcha.php:525
84
- msgid "BWP reCAPTCHA General Options"
85
- msgstr ""
86
 
87
- #: includes/class-bwp-recaptcha.php:534
88
- msgid "BWP reCAPTCHA Theme Options"
89
- msgstr ""
90
 
91
- #: includes/class-bwp-recaptcha.php:601
92
- msgid "reCAPTCHA API Keys"
93
- msgstr ""
94
 
95
- #: includes/class-bwp-recaptcha.php:602
96
- msgid "Use main site's keys"
97
- msgstr ""
98
 
99
- #: includes/class-bwp-recaptcha.php:603
100
- msgid "Site Key"
101
- msgstr ""
102
 
103
- #: includes/class-bwp-recaptcha.php:604
104
- msgid "Secret Key"
105
- msgstr ""
106
 
107
- #: includes/class-bwp-recaptcha.php:605
108
- msgid "Plugin Functionality"
109
- msgstr ""
110
 
111
- #: includes/class-bwp-recaptcha.php:606
112
- msgid "Use reCAPTCHA version 1"
113
- msgstr ""
114
 
115
- #: includes/class-bwp-recaptcha.php:607
116
- msgid "Force https"
117
- msgstr ""
118
 
119
- #: includes/class-bwp-recaptcha.php:608
120
- msgid "Enable this plugin for"
121
- msgstr ""
122
 
123
- #: includes/class-bwp-recaptcha.php:609
124
- msgid "Hide captcha for"
125
- msgstr ""
126
 
127
- #: includes/class-bwp-recaptcha.php:610
128
- msgid "reCAPTCHA for comment form"
129
- msgstr ""
 
 
 
 
130
 
131
- #: includes/class-bwp-recaptcha.php:611
132
  msgid "Captcha position"
133
- msgstr ""
134
 
135
- #: includes/class-bwp-recaptcha.php:612
136
- msgid "If invalid captcha response"
137
- msgstr ""
138
 
139
- #: includes/class-bwp-recaptcha.php:613
140
- msgid "Auto fill comment field"
141
- msgstr ""
142
 
143
- #: includes/class-bwp-recaptcha.php:614 includes/class-bwp-recaptcha.php:615
144
- #: includes/class-bwp-recaptcha.php:622
145
- msgid "Invalid captcha error message"
146
- msgstr ""
147
 
148
- #: includes/class-bwp-recaptcha.php:616
149
- msgid "Akismet Integration for comment form"
150
- msgstr ""
151
 
152
- #: includes/class-bwp-recaptcha.php:617
153
- msgid "Integrate with Akismet"
154
- msgstr ""
155
 
156
- #: includes/class-bwp-recaptcha.php:618
157
- msgid "If correct captcha response"
158
- msgstr ""
159
 
160
- #: includes/class-bwp-recaptcha.php:619
161
- msgid "Contact Form 7 Integration"
162
- msgstr ""
163
 
164
- #: includes/class-bwp-recaptcha.php:620
165
- msgid "Integrate with Contact Form 7"
166
- msgstr ""
167
 
168
- #: includes/class-bwp-recaptcha.php:621
169
- msgid "Treat invalid captcha as spam"
170
- msgstr ""
171
 
172
- #: includes/class-bwp-recaptcha.php:650
 
 
 
 
173
  #, php-format
174
- msgid ""
175
- "For this plugin to work, you will need a pair of API keys, which is "
176
- "available for free <a href=\"%s\" target=\"_blank\">here</a>. Once you have "
177
- "created those two keys for the current domain, simply paste them below.</em>"
178
- msgstr ""
179
 
180
- #: includes/class-bwp-recaptcha.php:655
181
- msgid "Control how this plugin works."
182
- msgstr ""
183
 
184
- #: includes/class-bwp-recaptcha.php:656
185
- msgid "Settings that are applied to comment forms only."
186
- msgstr ""
187
-
188
- #: includes/class-bwp-recaptcha.php:658
189
- msgid "Integrate the comment form with Akismet for better end-user experience."
190
- msgstr ""
191
 
192
- #: includes/class-bwp-recaptcha.php:659 includes/class-bwp-recaptcha.php:726
193
  #, php-format
194
  msgid ""
195
- "This feature requires an active <a target=\"_blank\" href=\"%s\">PHP "
196
- "session</a>."
197
  msgstr ""
 
 
198
 
199
- #: includes/class-bwp-recaptcha.php:661
200
- msgid ""
201
- "Add reCAPTCHA to Contact Form 7. This only works if you have Contact Form 7 "
202
- "activated."
203
- msgstr ""
204
 
205
- #: includes/class-bwp-recaptcha.php:677
206
- msgid "After comment field"
207
- msgstr ""
208
 
209
- #: includes/class-bwp-recaptcha.php:678
210
- msgid "After form fields (name, email, website)"
211
- msgstr ""
212
 
213
- #: includes/class-bwp-recaptcha.php:681
214
- msgid "Redirect commenter back to the comment form with error message"
 
 
 
 
215
  msgstr ""
 
 
 
216
 
217
- #: includes/class-bwp-recaptcha.php:682
218
- msgid "Show an error page just like WordPress does"
219
- msgstr ""
220
 
221
- #: includes/class-bwp-recaptcha.php:685
222
- msgid "Approve comment immediately"
223
- msgstr ""
224
 
225
- #: includes/class-bwp-recaptcha.php:686
226
- msgid "Hold comment in moderation queue"
227
- msgstr ""
228
 
229
- #: includes/class-bwp-recaptcha.php:691
230
- msgid "Comment form"
231
- msgstr ""
232
 
233
- #: includes/class-bwp-recaptcha.php:694
234
- msgid "Registration form (user/site registration)"
235
- msgstr ""
236
 
237
- #: includes/class-bwp-recaptcha.php:697
238
- msgid "Login form"
239
- msgstr ""
240
 
241
- #: includes/class-bwp-recaptcha.php:700
242
- msgid "registered users <em>(even without any capabilities)</em>."
243
- msgstr ""
244
 
245
- #: includes/class-bwp-recaptcha.php:703
246
- msgid "users who can"
247
- msgstr ""
248
 
249
- #: includes/class-bwp-recaptcha.php:706
250
- msgid "visitors who have at least"
251
- msgstr ""
252
 
253
- #: includes/class-bwp-recaptcha.php:709
254
- msgid ""
255
- "Show captcha only when Akismet identifies a comment as spam. Highly "
256
- "recommended if you do not want to force your visitors to enter a captcha "
257
- "every time."
258
- msgstr ""
259
 
260
- #: includes/class-bwp-recaptcha.php:714
261
- msgid "Uncheck to use different key pairs for this site."
 
 
262
  msgstr ""
 
 
263
 
264
- #: includes/class-bwp-recaptcha.php:717
 
265
  msgid ""
266
- "Use the oldschool recaptcha instead of the new <em>nocaptcha</em> recaptcha."
 
267
  msgstr ""
 
 
268
 
269
- #: includes/class-bwp-recaptcha.php:720
270
- msgid "Make requests to recaptcha server always secured"
 
 
 
 
 
271
  msgstr ""
 
 
 
 
272
 
273
- #: includes/class-bwp-recaptcha.php:723
274
- msgid "After redirected, auto fill the comment field with previous comment."
275
- msgstr ""
276
 
277
- #: includes/class-bwp-recaptcha.php:731
278
- msgid ""
279
- "Add the <code>recaptcha</code> shortcode tag to your Contact Form 7 forms."
280
- msgstr ""
281
 
282
- #: includes/class-bwp-recaptcha.php:734
283
- msgid "Treat invalid captcha response as spam instead of validation error"
284
  msgstr ""
 
285
 
286
- #: includes/class-bwp-recaptcha.php:752
287
- msgid "approved comment(s)."
288
- msgstr ""
289
 
290
- #: includes/class-bwp-recaptcha.php:765
291
- msgid "A public key used to request captchas from reCAPTCHA server."
292
- msgstr ""
293
 
294
- #: includes/class-bwp-recaptcha.php:771
295
- msgid "A private (secret) key used to authenticate user's response."
296
- msgstr ""
 
297
 
298
- #: includes/class-bwp-recaptcha.php:777
299
  msgid ""
300
  "It is best to put comments identified as spam in moderation queue so you are "
301
  "able to review and instruct Akismet to correctly handle similar comments in "
302
  "the future."
303
  msgstr ""
 
 
 
304
 
305
- #: includes/class-bwp-recaptcha.php:783
306
- msgid ""
307
- "This is shown when the commenter is redirected back to the comment form."
308
- msgstr ""
309
 
310
- #: includes/class-bwp-recaptcha.php:788
311
- msgid "This is shown on the standard WordPress error page."
312
- msgstr ""
313
 
314
- #: includes/class-bwp-recaptcha.php:796
315
- msgid ""
316
- "This message is shown when invalid captcha response is treated as a standard "
317
- "validation error. Leave blank to not use."
318
- msgstr ""
319
 
320
- #: includes/class-bwp-recaptcha.php:879 includes/class-bwp-recaptcha.php:952
321
- msgid "reCAPTCHA theme"
322
- msgstr ""
323
 
324
- #: includes/class-bwp-recaptcha.php:880
325
- msgid "Use default CSS"
326
- msgstr ""
327
 
328
- #: includes/class-bwp-recaptcha.php:881
329
- msgid "Language for built-in themes"
330
- msgstr ""
331
 
332
- #: includes/class-bwp-recaptcha.php:882 includes/class-bwp-recaptcha.php:955
333
- msgid "Tabindex for captcha input field"
334
- msgstr ""
335
 
336
- #: includes/class-bwp-recaptcha.php:883 includes/class-bwp-recaptcha.php:956
337
- msgid "Preview your reCAPTCHA"
338
- msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
 
340
- #: includes/class-bwp-recaptcha.php:893 includes/class-bwp-recaptcha.php:966
 
 
 
 
 
341
  msgid ""
342
- "<em>Below you will see how your reCAPTCHA will look. Note that this might "
343
- "differ on your actual pages.<br /></em>"
 
344
  msgstr ""
 
 
 
345
 
346
- #: includes/class-bwp-recaptcha.php:898
347
- msgid "Default Theme (Red)"
348
- msgstr ""
349
 
350
- #: includes/class-bwp-recaptcha.php:899
351
- msgid "White Theme"
352
- msgstr ""
353
 
354
- #: includes/class-bwp-recaptcha.php:900
355
- msgid "Black Theme"
356
- msgstr ""
357
 
358
- #: includes/class-bwp-recaptcha.php:901
359
- msgid "Clean Theme"
360
- msgstr ""
361
 
362
- #: includes/class-bwp-recaptcha.php:902
363
- msgid "Custom Theme (use CSS)"
364
- msgstr ""
365
 
366
- #: includes/class-bwp-recaptcha.php:921
367
  #, php-format
368
  msgid ""
369
  "Read <a href=\"%s#recaptcha-version-1\" target=\"_blank\">here</a> to know "
370
  "how to use your own CSS for the Custom Theme."
371
  msgstr ""
 
 
372
 
373
- #: includes/class-bwp-recaptcha.php:930
374
- #, php-format
375
- msgid ""
376
- "If you want to add custom translations, please read <a href=\"%s\" target="
377
- "\"_blank\">this tip</a>."
378
- msgstr ""
379
-
380
- #: includes/class-bwp-recaptcha.php:953
381
- msgid "reCAPTCHA size"
382
- msgstr ""
383
 
384
- #: includes/class-bwp-recaptcha.php:954
385
- msgid "Language"
386
- msgstr ""
387
 
388
- #: includes/class-bwp-recaptcha.php:971
389
- msgid "Light"
390
- msgstr ""
391
 
392
- #: includes/class-bwp-recaptcha.php:972
393
- msgid "Dark"
394
- msgstr ""
395
 
396
- #: includes/class-bwp-recaptcha.php:975
397
- msgid "Normal"
398
- msgstr ""
399
 
400
- #: includes/class-bwp-recaptcha.php:976
401
- msgid "Compact"
402
- msgstr ""
403
 
404
- #: includes/class-bwp-recaptcha.php:979
405
- msgid "Auto-detected"
406
- msgstr ""
407
 
408
- #: includes/class-bwp-recaptcha.php:990
409
  msgid "Set to 0 to disable."
410
- msgstr ""
411
 
412
- #: includes/class-bwp-recaptcha.php:1030
413
- msgid "Warning"
414
- msgstr ""
415
 
416
- #: includes/class-bwp-recaptcha.php:1031
417
- #, php-format
418
- msgid ""
419
- "API key(s) missing. Please get an API key from <a href=\"%1$s\">%1$s</a> "
420
- "(free!)"
421
- msgstr ""
422
 
423
- #: includes/class-bwp-recaptcha.php:1042
424
- msgid "Notice"
425
- msgstr ""
 
 
 
 
426
 
427
- #: includes/class-bwp-recaptcha.php:1043
428
  msgid ""
429
- "You are enabling Akismet integration but Akismet is not currently active. "
430
- "Please activate Akismet for the integration to work."
 
431
  msgstr ""
 
 
 
432
 
433
- #: includes/class-bwp-recaptcha.php:1191
434
- msgid "Your comment was identified as spam, please complete the CAPTCHA below:"
435
- msgstr ""
436
 
437
- #: includes/class-bwp-recaptcha.php:1369
438
- msgid "this link"
439
- msgstr ""
440
 
441
- #: includes/provider/abstract-provider.php:96
 
 
 
 
 
 
 
 
442
  msgid ""
443
  "There is some problem with your reCAPTCHA API keys, please double check them."
444
  msgstr ""
 
445
 
446
- #: includes/provider/abstract-provider.php:100
447
  #, php-format
448
- msgid "Unknown error (%s). Please contact an administrator for more info."
 
 
449
  msgstr ""
 
 
450
 
451
- #: includes/provider/v1.php:90
452
- #, php-format
453
- msgid "To use reCAPTCHA you must get an API key from <a href=\"%1$s\">%1$s</a>"
454
- msgstr ""
455
 
456
- #: includes/provider/v1.php:156
457
- msgid "Get another challenge"
 
458
  msgstr ""
 
459
 
460
- #: includes/provider/v1.php:157
461
- msgid "Get audio reCAPTCHA"
 
 
462
  msgstr ""
 
 
463
 
464
- #: includes/provider/v1.php:158
465
- msgid "Get image reCAPTCHA"
466
- msgstr ""
467
 
468
- #: includes/provider/v1.php:159
469
- msgid "About reCAPTCHA"
 
470
  msgstr ""
 
471
 
472
- #: includes/provider/v1.php:163
473
- msgid "Type what you see"
 
 
 
 
474
  msgstr ""
 
 
 
 
475
 
476
- #: includes/provider/v1.php:164
 
 
 
 
 
 
 
 
 
 
 
 
477
  msgid "Type what you hear"
478
- msgstr ""
479
 
480
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:367
481
- msgid "Got a problem? Send me a feedback!"
482
- msgstr ""
483
 
484
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:367
485
- msgid "Support"
486
- msgstr ""
487
 
488
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:369
489
- msgid "Rate this plugin 5 stars!"
490
- msgstr ""
 
491
 
492
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:369
493
- msgid "Reviews"
494
- msgstr ""
495
 
496
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:371
497
- msgid "Frequently Asked Questions"
498
- msgstr ""
499
 
500
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:371
501
- msgid "FAQ"
502
- msgstr ""
503
 
504
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:378
505
  msgid ""
506
- "You can buy me some special coffees if you appreciate my work, thank you!"
507
  msgstr ""
 
508
 
509
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:392
510
- #, php-format
511
- msgid "Donate to %s"
512
- msgstr ""
513
 
514
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:394
515
- msgid "One cup $5.00"
516
- msgstr ""
517
 
518
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:395
519
- msgid "Two cups $10.00"
520
- msgstr ""
521
 
522
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:396
523
- msgid "Five cups! $25.00"
524
- msgstr ""
525
 
526
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:397
527
- msgid "One LL-cup!!! $50.00"
 
 
528
  msgstr ""
 
 
529
 
530
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:398
531
- msgid "... or any amount!"
532
- msgstr ""
 
533
 
534
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:413
535
- msgid "Latest updates from BetterWP.net!"
 
536
  msgstr ""
 
537
 
538
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:414
539
- msgid "Follow me on Twitter!"
540
  msgstr ""
 
541
 
542
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:424
543
- msgid "This Plugin is Proudly Sponsored By"
544
- msgstr ""
545
 
546
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:444
547
- #, php-format
548
- msgid "You are using version %s!"
549
- msgstr ""
550
 
551
- #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:1145
552
- msgid "Settings"
553
- msgstr ""
554
 
555
- #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:93
556
- msgid "Plugin Configurations"
557
- msgstr ""
558
 
559
- #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:312
560
- msgid "Save Changes"
561
- msgstr ""
562
 
563
- #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:444
564
- msgid "All options have been saved."
565
- msgstr ""
566
 
567
- #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:797
568
- msgid "View more info in a separate tab"
569
- msgstr ""
570
 
571
- #: vendor/kminh/bwp-framework/src/class-bwp-version.php:32
572
- #, php-format
573
- msgid ""
574
- "%s requires WordPress <strong>%s</strong> or higher and PHP <strong>%s</"
575
- "strong> or higher. The plugin will not function until you update your "
576
- "software. Please deactivate this plugin."
577
- msgstr ""
 
 
 
 
 
 
 
 
1
+ # English translations for BWP Recaptcha package.
2
+ # Copyright (C) 2016 Khang Minh
3
+ # This file is distributed under the same license as the BWP Recaptcha package.
4
+ # Automatically generated, 2016.
5
+ #
6
  msgid ""
7
  msgstr ""
8
+ "Project-Id-Version: BWP Recaptcha 2.0.3\n"
9
+ "Report-Msgid-Bugs-To: contact@betterwp.net\n"
10
+ "POT-Creation-Date: 2016-01-12 23:47+0700\n"
11
+ "PO-Revision-Date: 2016-01-12 23:47+0700\n"
12
+ "Last-Translator: Automatically generated\n"
13
+ "Language-Team: none\n"
14
  "Language: en_US\n"
15
  "MIME-Version: 1.0\n"
16
  "Content-Type: text/plain; charset=UTF-8\n"
17
  "Content-Transfer-Encoding: 8bit\n"
 
 
18
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 
 
 
19
 
20
+ #: vendor/kminh/bwp-framework/src/class-bwp-version.php:32
21
+ #, php-format
22
+ msgid ""
23
+ "%s requires WordPress <strong>%s</strong> or higher and PHP <strong>%s</"
24
+ "strong> or higher. The plugin will not function until you update your "
25
+ "software. Please deactivate this plugin."
 
 
 
 
 
26
  msgstr ""
27
+ "%s requires WordPress <strong>%s</strong> or higher and PHP <strong>%s</"
28
+ "strong> or higher. The plugin will not function until you update your "
29
+ "software. Please deactivate this plugin."
30
 
31
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:411
32
+ msgid "... or any amount!"
33
+ msgstr "... or any amount!"
34
 
35
+ #: includes/class-bwp-recaptcha.php:1006 includes/class-bwp-recaptcha.php:1101
 
36
  msgid ""
37
+ "<em>Below you will see how your reCAPTCHA will look. Note that this might "
38
+ "differ on your actual pages.</em>"
 
39
  msgstr ""
40
+ "<em>Below you will see how your reCAPTCHA will look. Note that this might "
41
+ "differ on your actual pages.</em>"
42
 
43
+ #: includes/class-bwp-recaptcha.php:118
44
  msgid ""
45
  "<strong>ERROR:</strong> Incorrect or empty reCAPTCHA response, please try "
46
  "again."
47
  msgstr ""
48
+ "<strong>ERROR:</strong> Incorrect or empty reCAPTCHA response, please try "
49
+ "again."
50
+
51
+ #: includes/class-bwp-recaptcha.php:867
52
+ msgid "A private (secret) key used to authenticate user's response."
53
+ msgstr "A private (secret) key used to authenticate user's response."
54
 
55
+ #: includes/class-bwp-recaptcha.php:861
56
+ msgid "A public key used to request captchas from reCAPTCHA server."
57
+ msgstr "A public key used to request captchas from reCAPTCHA server."
58
+
59
+ #: includes/class-bwp-recaptcha.php:1193
60
  #, php-format
61
  msgid ""
62
+ "API key(s) missing. Please get an API key from <a href=\"%1$s\">%1$s</a> "
63
+ "(free!)"
64
  msgstr ""
65
+ "API key(s) missing. Please get an API key from <a href=\"%1$s\">%1$s</a> "
66
+ "(free!)"
67
 
68
+ #: includes/provider/v1.php:165
69
+ msgid "About reCAPTCHA"
70
+ msgstr "About reCAPTCHA"
71
 
72
+ #: includes/class-bwp-recaptcha.php:1021 includes/class-bwp-recaptcha.php:1123
73
+ msgid ""
74
+ "Add additional CSS rules to all recaptcha instances. You can edit them below."
75
  msgstr ""
76
+ "Add additional CSS rules to all recaptcha instances. You can edit them below."
77
 
78
+ #: includes/class-bwp-recaptcha.php:756
79
+ msgid ""
80
+ "Add reCAPTCHA to Contact Form 7. This only works if you have Contact Form 7 "
81
+ "activated."
82
  msgstr ""
83
+ "Add reCAPTCHA to Contact Form 7. This only works if you have Contact Form 7 "
84
+ "activated."
85
 
86
+ #: includes/class-bwp-recaptcha.php:827
87
+ msgid ""
88
+ "Add the <code>recaptcha</code> shortcode tag to your Contact Form 7 forms."
89
  msgstr ""
90
+ "Add the <code>recaptcha</code> shortcode tag to your Contact Form 7 forms."
91
 
92
+ #: includes/class-bwp-recaptcha.php:773
93
+ msgid "After comment field"
94
+ msgstr "After comment field"
95
 
96
+ #: includes/class-bwp-recaptcha.php:774
97
+ msgid "After form fields (name, email, website)"
98
+ msgstr "After form fields (name, email, website)"
99
 
100
+ #: includes/class-bwp-recaptcha.php:819
101
+ msgid "After redirected, auto fill the comment field with previous comment."
102
+ msgstr "After redirected, auto fill the comment field with previous comment."
103
 
104
+ #: includes/class-bwp-recaptcha.php:708
105
+ msgid "Akismet Integration for comment form"
106
+ msgstr "Akismet Integration for comment form"
107
 
108
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:438
109
+ msgid "All options have been saved."
110
+ msgstr "All options have been saved."
111
 
112
+ #: includes/class-bwp-recaptcha.php:781
113
+ msgid "Approve comment immediately"
114
+ msgstr "Approve comment immediately"
115
 
116
+ #: includes/class-bwp-recaptcha.php:636
117
+ msgid "Auto detected"
118
+ msgstr "Auto detected"
119
 
120
+ #: includes/class-bwp-recaptcha.php:705
121
+ msgid "Auto fill comment field"
122
+ msgstr "Auto fill comment field"
123
 
124
+ #: includes/class-bwp-recaptcha.php:1114
125
+ msgid "Auto-detected"
126
+ msgstr "Auto-detected"
127
 
128
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:521
129
+ msgid "BWP Gems"
130
+ msgstr "BWP Gems"
131
 
132
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:531
133
+ msgid "BWP News"
134
+ msgstr "BWP News"
135
 
136
+ #: includes/class-bwp-recaptcha.php:595
137
+ msgid "BWP reCAPTCHA General Options"
138
+ msgstr "BWP reCAPTCHA General Options"
139
 
140
+ #: includes/class-bwp-recaptcha.php:604
141
+ msgid "BWP reCAPTCHA Theme Options"
142
+ msgstr "BWP reCAPTCHA Theme Options"
143
 
144
+ #: includes/class-bwp-recaptcha.php:585
145
+ msgid "Better WordPress reCAPTCHA"
146
+ msgstr "Better WordPress reCAPTCHA"
147
+
148
+ #: includes/class-bwp-recaptcha.php:1013
149
+ msgid "Black Theme"
150
+ msgstr "Black Theme"
151
 
152
+ #: includes/class-bwp-recaptcha.php:703
153
  msgid "Captcha position"
154
+ msgstr "Captcha position"
155
 
156
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:439
157
+ msgid "Check out this cool plugin"
158
+ msgstr "Check out this cool plugin"
159
 
160
+ #: includes/class-bwp-recaptcha.php:1014
161
+ msgid "Clean Theme"
162
+ msgstr "Clean Theme"
163
 
164
+ #: includes/class-bwp-recaptcha.php:787
165
+ msgid "Comment form"
166
+ msgstr "Comment form"
 
167
 
168
+ #: includes/class-bwp-recaptcha.php:1111
169
+ msgid "Compact"
170
+ msgstr "Compact"
171
 
172
+ #: includes/class-bwp-recaptcha.php:711
173
+ msgid "Contact Form 7 Integration"
174
+ msgstr "Contact Form 7 Integration"
175
 
176
+ #: includes/addons/contact-form-7/captcha-shortcode.php:205
177
+ msgid "Copy this code and paste it into the form left."
178
+ msgstr "Copy this code and paste it into the form left."
179
 
180
+ #: includes/class-bwp-recaptcha.php:1015
181
+ msgid "Custom Theme (use CSS)"
182
+ msgstr "Custom Theme (use CSS)"
183
 
184
+ #: includes/class-bwp-recaptcha.php:1107
185
+ msgid "Dark"
186
+ msgstr "Dark"
187
 
188
+ #: includes/class-bwp-recaptcha.php:1011
189
+ msgid "Default Theme (Red)"
190
+ msgstr "Default Theme (Red)"
191
 
192
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:1530
193
+ msgid "Dismiss this notice."
194
+ msgstr "Dismiss this notice."
195
+
196
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:405
197
  #, php-format
198
+ msgid "Donate to %s"
199
+ msgstr "Donate to %s"
 
 
 
200
 
201
+ #: includes/class-bwp-recaptcha.php:992 includes/class-bwp-recaptcha.php:1087
202
+ msgid "Enable custom CSS"
203
+ msgstr "Enable custom CSS"
204
 
205
+ #: includes/class-bwp-recaptcha.php:700
206
+ msgid "Enable this plugin for"
207
+ msgstr "Enable this plugin for"
 
 
 
 
208
 
209
+ #: includes/class-bwp-recaptcha.php:120
210
  #, php-format
211
  msgid ""
212
+ "Error: Incorrect or empty reCAPTCHA response, please click the back button "
213
+ "on your browser's toolbar or click on %s to go back."
214
  msgstr ""
215
+ "Error: Incorrect or empty reCAPTCHA response, please click the back button "
216
+ "on your browser's toolbar or click on %s to go back."
217
 
218
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:371
219
+ msgid "FAQ"
220
+ msgstr "FAQ"
 
 
221
 
222
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:409
223
+ msgid "Five cups! $25.00"
224
+ msgstr "Five cups! $25.00"
225
 
226
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:548
227
+ msgid "Follow"
228
+ msgstr "Follow"
229
 
230
+ #: includes/class-bwp-recaptcha.php:744
231
+ #, php-format
232
+ msgid ""
233
+ "For this plugin to work, you will need a pair of API keys, which is "
234
+ "available for free <a href=\"%s\" target=\"_blank\">here</a>. Once you have "
235
+ "created those two keys for the current domain, simply paste them below.</em>"
236
  msgstr ""
237
+ "For this plugin to work, you will need a pair of API keys, which is "
238
+ "available for free <a href=\"%s\" target=\"_blank\">here</a>. Once you have "
239
+ "created those two keys for the current domain, simply paste them below.</em>"
240
 
241
+ #: includes/class-bwp-recaptcha.php:697
242
+ msgid "Force https"
243
+ msgstr "Force https"
244
 
245
+ #: includes/class-bwp-recaptcha.php:159 includes/class-bwp-recaptcha.php:596
246
+ msgid "General Options"
247
+ msgstr "General Options"
248
 
249
+ #: includes/provider/v1.php:162
250
+ msgid "Get another challenge"
251
+ msgstr "Get another challenge"
252
 
253
+ #: includes/provider/v1.php:163
254
+ msgid "Get audio reCAPTCHA"
255
+ msgstr "Get audio reCAPTCHA"
256
 
257
+ #: includes/provider/v1.php:164
258
+ msgid "Get image reCAPTCHA"
259
+ msgstr "Get image reCAPTCHA"
260
 
261
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:374
262
+ msgid "Got a problem with this plugin? Please say it out loud!"
263
+ msgstr "Got a problem with this plugin? Please say it out loud!"
264
 
265
+ #: includes/class-bwp-recaptcha.php:701
266
+ msgid "Hide captcha for"
267
+ msgstr "Hide captcha for"
268
 
269
+ #: includes/class-bwp-recaptcha.php:782
270
+ msgid "Hold comment in moderation queue"
271
+ msgstr "Hold comment in moderation queue"
272
 
273
+ #: includes/class-bwp-recaptcha.php:710
274
+ msgid "If correct captcha response"
275
+ msgstr "If correct captcha response"
276
 
277
+ #: includes/class-bwp-recaptcha.php:704
278
+ msgid "If invalid captcha response"
279
+ msgstr "If invalid captcha response"
 
 
 
280
 
281
+ #: includes/class-bwp-recaptcha.php:880
282
+ msgid ""
283
+ "If you encounter error such as <code>Unknown error (invalid-json)</code>when "
284
+ "submitting a form, try selecting a specific request method here."
285
  msgstr ""
286
+ "If you encounter error such as <code>Unknown error (invalid-json)</code>when "
287
+ "submitting a form, try selecting a specific request method here."
288
 
289
+ #: includes/class-bwp-recaptcha.php:1054
290
+ #, php-format
291
  msgid ""
292
+ "If you want to add custom translations, please read <a href=\"%s\" target="
293
+ "\"_blank\">this tip</a>."
294
  msgstr ""
295
+ "If you want to add custom translations, please read <a href=\"%s\" target="
296
+ "\"_blank\">this tip</a>."
297
 
298
+ #: includes/class-bwp-recaptcha.php:1207
299
+ #, php-format
300
+ msgid ""
301
+ "In order to use the nocaptcha recaptcha (recaptcha v2), you need at least "
302
+ "<strong>PHP 5.3.2</strong> (your current PHP version is <strong>%s</"
303
+ "strong>), so only recaptcha v1 can be used. It is recommended to contact "
304
+ "your host to know how to update your current version of PHP."
305
  msgstr ""
306
+ "In order to use the nocaptcha recaptcha (recaptcha v2), you need at least "
307
+ "<strong>PHP 5.3.2</strong> (your current PHP version is <strong>%s</"
308
+ "strong>), so only recaptcha v1 can be used. It is recommended to contact "
309
+ "your host to know how to update your current version of PHP."
310
 
311
+ #: includes/class-bwp-recaptcha.php:125
312
+ msgid "Incorrect or empty reCAPTCHA response, please try again."
313
+ msgstr "Incorrect or empty reCAPTCHA response, please try again."
314
 
315
+ #: includes/addons/contact-form-7/captcha-shortcode.php:170
316
+ msgid "Insert Tag"
317
+ msgstr "Insert Tag"
 
318
 
319
+ #: includes/class-bwp-recaptcha.php:753
320
+ msgid "Integrate the comment form with Akismet for better end-user experience."
321
  msgstr ""
322
+ "Integrate the comment form with Akismet for better end-user experience."
323
 
324
+ #: includes/class-bwp-recaptcha.php:709
325
+ msgid "Integrate with Akismet"
326
+ msgstr "Integrate with Akismet"
327
 
328
+ #: includes/class-bwp-recaptcha.php:712
329
+ msgid "Integrate with Contact Form 7"
330
+ msgstr "Integrate with Contact Form 7"
331
 
332
+ #: includes/class-bwp-recaptcha.php:706 includes/class-bwp-recaptcha.php:707
333
+ #: includes/class-bwp-recaptcha.php:714
334
+ msgid "Invalid captcha error message"
335
+ msgstr "Invalid captcha error message"
336
 
337
+ #: includes/class-bwp-recaptcha.php:886
338
  msgid ""
339
  "It is best to put comments identified as spam in moderation queue so you are "
340
  "able to review and instruct Akismet to correctly handle similar comments in "
341
  "the future."
342
  msgstr ""
343
+ "It is best to put comments identified as spam in moderation queue so you are "
344
+ "able to review and instruct Akismet to correctly handle similar comments in "
345
+ "the future."
346
 
347
+ #: includes/class-bwp-recaptcha.php:1088
348
+ msgid "Language"
349
+ msgstr "Language"
 
350
 
351
+ #: includes/class-bwp-recaptcha.php:993
352
+ msgid "Language for built-in themes"
353
+ msgstr "Language for built-in themes"
354
 
355
+ #: includes/class-bwp-recaptcha.php:1106
356
+ msgid "Light"
357
+ msgstr "Light"
 
 
358
 
359
+ #: includes/class-bwp-recaptcha.php:793
360
+ msgid "Login form"
361
+ msgstr "Login form"
362
 
363
+ #: includes/class-bwp-recaptcha.php:699
364
+ msgid "Main Functionality"
365
+ msgstr "Main Functionality"
366
 
367
+ #: includes/class-bwp-recaptcha.php:816
368
+ msgid "Make requests to recaptcha server always secured."
369
+ msgstr "Make requests to recaptcha server always secured."
370
 
371
+ #: includes/class-bwp-recaptcha.php:317
372
+ msgid "Manage Options"
373
+ msgstr "Manage Options"
374
 
375
+ #: includes/addons/contact-form-7/captcha-shortcode.php:159
376
+ #: includes/addons/contact-form-7/captcha-shortcode.php:196
377
+ msgid "Name"
378
+ msgstr "Name"
379
+
380
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:503
381
+ msgid "Need a highly customizable theme?"
382
+ msgstr "Need a highly customizable theme?"
383
+
384
+ #: includes/class-bwp-recaptcha.php:1110
385
+ msgid "Normal"
386
+ msgstr "Normal"
387
+
388
+ #: includes/class-bwp-recaptcha.php:1205 includes/class-bwp-recaptcha.php:1227
389
+ msgid "Notice"
390
+ msgstr "Notice"
391
+
392
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:410
393
+ msgid "One LL-cup!!! $50.00"
394
+ msgstr "One LL-cup!!! $50.00"
395
 
396
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:407
397
+ msgid "One cup $5.00"
398
+ msgstr "One cup $5.00"
399
+
400
+ #: includes/addons/contact-form-7/captcha-shortcode.php:225
401
+ #, php-format
402
  msgid ""
403
+ "Please refer to <a target=\"_blank\" href=\"%s\">BWP reCAPTCHA's "
404
+ "documentation</a> for a quick guide on how to customize the look and feel of "
405
+ "this tag."
406
  msgstr ""
407
+ "Please refer to <a target=\"_blank\" href=\"%s\">BWP reCAPTCHA's "
408
+ "documentation</a> for a quick guide on how to customize the look and feel of "
409
+ "this tag."
410
 
411
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:93
412
+ msgid "Plugin Configurations"
413
+ msgstr "Plugin Configurations"
414
 
415
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:375
416
+ msgid "Plugin Support"
417
+ msgstr "Plugin Support"
418
 
419
+ #: includes/class-bwp-recaptcha.php:995 includes/class-bwp-recaptcha.php:1090
420
+ msgid "Preview your reCAPTCHA"
421
+ msgstr "Preview your reCAPTCHA"
422
 
423
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:378
424
+ msgid "Rate this plugin 5 stars if you like it, thank you!"
425
+ msgstr "Rate this plugin 5 stars if you like it, thank you!"
426
 
427
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:379
428
+ msgid "Rate this plugin 5 stars!"
429
+ msgstr "Rate this plugin 5 stars!"
430
 
431
+ #: includes/class-bwp-recaptcha.php:1045
432
  #, php-format
433
  msgid ""
434
  "Read <a href=\"%s#recaptcha-version-1\" target=\"_blank\">here</a> to know "
435
  "how to use your own CSS for the Custom Theme."
436
  msgstr ""
437
+ "Read <a href=\"%s#recaptcha-version-1\" target=\"_blank\">here</a> to know "
438
+ "how to use your own CSS for the Custom Theme."
439
 
440
+ #: includes/class-bwp-recaptcha.php:316
441
+ msgid "Read Profile"
442
+ msgstr "Read Profile"
 
 
 
 
 
 
 
443
 
444
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:370
445
+ msgid "Read this first before asking any question!"
446
+ msgstr "Read this first before asking any question!"
447
 
448
+ #: includes/class-bwp-recaptcha.php:777
449
+ msgid "Redirect commenter back to the comment form with error message"
450
+ msgstr "Redirect commenter back to the comment form with error message"
451
 
452
+ #: includes/class-bwp-recaptcha.php:790
453
+ msgid "Registration form (user/site registration)"
454
+ msgstr "Registration form (user/site registration)"
455
 
456
+ #: includes/class-bwp-recaptcha.php:698
457
+ msgid "Request method"
458
+ msgstr "Request method"
459
 
460
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:305
461
+ msgid "Save Changes"
462
+ msgstr "Save Changes"
463
 
464
+ #: includes/class-bwp-recaptcha.php:694
465
+ msgid "Secret Key"
466
+ msgstr "Secret Key"
467
 
468
+ #: includes/class-bwp-recaptcha.php:1129
469
  msgid "Set to 0 to disable."
470
+ msgstr "Set to 0 to disable."
471
 
472
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:1315
473
+ msgid "Settings"
474
+ msgstr "Settings"
475
 
476
+ #: includes/class-bwp-recaptcha.php:751
477
+ msgid "Settings that are applied to comment forms only."
478
+ msgstr "Settings that are applied to comment forms only."
 
 
 
479
 
480
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:431
481
+ msgid "Share the love for this plugin!"
482
+ msgstr "Share the love for this plugin!"
483
+
484
+ #: includes/class-bwp-recaptcha.php:778
485
+ msgid "Show an error page just like WordPress does"
486
+ msgstr "Show an error page just like WordPress does"
487
 
488
+ #: includes/class-bwp-recaptcha.php:805
489
  msgid ""
490
+ "Show captcha only when Akismet identifies a comment as spam. Highly "
491
+ "recommended if you do not want to force your visitors to enter a captcha "
492
+ "every time."
493
  msgstr ""
494
+ "Show captcha only when Akismet identifies a comment as spam. Highly "
495
+ "recommended if you do not want to force your visitors to enter a captcha "
496
+ "every time."
497
 
498
+ #: includes/class-bwp-recaptcha.php:693
499
+ msgid "Site Key"
500
+ msgstr "Site Key"
501
 
502
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:541
503
+ msgid "Subscribe"
504
+ msgstr "Subscribe"
505
 
506
+ #: includes/class-bwp-recaptcha.php:994 includes/class-bwp-recaptcha.php:1089
507
+ msgid "Tabindex for captcha input field"
508
+ msgstr "Tabindex for captcha input field"
509
+
510
+ #: includes/class-bwp-recaptcha.php:162 includes/class-bwp-recaptcha.php:605
511
+ msgid "Theme Options"
512
+ msgstr "Theme Options"
513
+
514
+ #: includes/provider/abstract-provider.php:103
515
  msgid ""
516
  "There is some problem with your reCAPTCHA API keys, please double check them."
517
  msgstr ""
518
+ "There is some problem with your reCAPTCHA API keys, please double check them."
519
 
520
+ #: includes/class-bwp-recaptcha.php:754 includes/class-bwp-recaptcha.php:822
521
  #, php-format
522
+ msgid ""
523
+ "This feature requires an active <a target=\"_blank\" href=\"%s\">PHP "
524
+ "session</a>."
525
  msgstr ""
526
+ "This feature requires an active <a target=\"_blank\" href=\"%s\">PHP "
527
+ "session</a>."
528
 
529
+ #: includes/class-bwp-recaptcha.php:897
530
+ msgid "This is shown on the standard WordPress error page."
531
+ msgstr "This is shown on the standard WordPress error page."
 
532
 
533
+ #: includes/class-bwp-recaptcha.php:892
534
+ msgid ""
535
+ "This is shown when the commenter is redirected back to the comment form."
536
  msgstr ""
537
+ "This is shown when the commenter is redirected back to the comment form."
538
 
539
+ #: includes/class-bwp-recaptcha.php:905
540
+ msgid ""
541
+ "This message is shown when invalid captcha response is treated as a standard "
542
+ "validation error. Leave blank to not use."
543
  msgstr ""
544
+ "This message is shown when invalid captcha response is treated as a standard "
545
+ "validation error. Leave blank to not use."
546
 
547
+ #: includes/addons/contact-form-7/captcha-shortcode.php:220
548
+ msgid "This reCAPTCHA tag is provided by the BWP reCAPTCHA WordPress plugin."
549
+ msgstr "This reCAPTCHA tag is provided by the BWP reCAPTCHA WordPress plugin."
550
 
551
+ #: includes/provider/v1.php:96
552
+ #, php-format
553
+ msgid "To use reCAPTCHA you must get an API key from <a href=\"%1$s\">%1$s</a>"
554
  msgstr ""
555
+ "To use reCAPTCHA you must get an API key from <a href=\"%1$s\">%1$s</a>"
556
 
557
+ #: includes/class-bwp-recaptcha.php:873
558
+ msgid ""
559
+ "To verify a captcha response, this plugin needs to send requests to the "
560
+ "reCAPTCHA server, using a specific request method. <br /><br />By default, "
561
+ "BWP reCAPTCHA use the first available request method, be it Socket "
562
+ "(<code>fsockopen</code>), cURL, or <code>file_get_contents</code>."
563
  msgstr ""
564
+ "To verify a captcha response, this plugin needs to send requests to the "
565
+ "reCAPTCHA server, using a specific request method. <br /><br />By default, "
566
+ "BWP reCAPTCHA use the first available request method, be it Socket "
567
+ "(<code>fsockopen</code>), cURL, or <code>file_get_contents</code>."
568
 
569
+ #: includes/class-bwp-recaptcha.php:713
570
+ msgid "Treat invalid captcha as spam"
571
+ msgstr "Treat invalid captcha as spam"
572
+
573
+ #: includes/class-bwp-recaptcha.php:830
574
+ msgid "Treat invalid captcha response as spam instead of validation error"
575
+ msgstr "Treat invalid captcha response as spam instead of validation error"
576
+
577
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:408
578
+ msgid "Two cups $10.00"
579
+ msgstr "Two cups $10.00"
580
+
581
+ #: includes/provider/v1.php:170
582
  msgid "Type what you hear"
583
+ msgstr "Type what you hear"
584
 
585
+ #: includes/provider/v1.php:169
586
+ msgid "Type what you see"
587
+ msgstr "Type what you see"
588
 
589
+ #: includes/class-bwp-recaptcha.php:810
590
+ msgid "Uncheck to use different key pairs for this site."
591
+ msgstr "Uncheck to use different key pairs for this site."
592
 
593
+ #: includes/provider/abstract-provider.php:107
594
+ #, php-format
595
+ msgid "Unknown error (%s). Please contact an administrator for more info."
596
+ msgstr "Unknown error (%s). Please contact an administrator for more info."
597
 
598
+ #: includes/class-bwp-recaptcha.php:991
599
+ msgid "Use default CSS"
600
+ msgstr "Use default CSS"
601
 
602
+ #: includes/class-bwp-recaptcha.php:692
603
+ msgid "Use main site's keys"
604
+ msgstr "Use main site's keys"
605
 
606
+ #: includes/class-bwp-recaptcha.php:696
607
+ msgid "Use reCAPTCHA version 1"
608
+ msgstr "Use reCAPTCHA version 1"
609
 
610
+ #: includes/class-bwp-recaptcha.php:813
611
  msgid ""
612
+ "Use the oldschool recaptcha instead of the new <em>nocaptcha</em> recaptcha."
613
  msgstr ""
614
+ "Use the oldschool recaptcha instead of the new <em>nocaptcha</em> recaptcha."
615
 
616
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:416
617
+ msgid "Via"
618
+ msgstr "Via"
 
619
 
620
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:827
621
+ msgid "View more info in a separate tab"
622
+ msgstr "View more info in a separate tab"
623
 
624
+ #: includes/class-bwp-recaptcha.php:1192
625
+ msgid "Warning"
626
+ msgstr "Warning"
627
 
628
+ #: includes/class-bwp-recaptcha.php:1012
629
+ msgid "White Theme"
630
+ msgstr "White Theme"
631
 
632
+ #: includes/class-bwp-recaptcha.php:1228
633
+ msgid ""
634
+ "You are enabling Akismet integration but Akismet is not currently active. "
635
+ "Please activate Akismet for the integration to work."
636
  msgstr ""
637
+ "You are enabling Akismet integration but Akismet is not currently active. "
638
+ "Please activate Akismet for the integration to work."
639
 
640
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:565
641
+ #, php-format
642
+ msgid "You are using version %s!"
643
+ msgstr "You are using version %s!"
644
 
645
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:391
646
+ msgid ""
647
+ "You can buy me some special coffees if you appreciate my work, thank you!"
648
  msgstr ""
649
+ "You can buy me some special coffees if you appreciate my work, thank you!"
650
 
651
+ #: includes/class-bwp-recaptcha.php:1376
652
+ msgid "Your comment was identified as spam, please complete the CAPTCHA below:"
653
  msgstr ""
654
+ "Your comment was identified as spam, please complete the CAPTCHA below:"
655
 
656
+ #: includes/class-bwp-recaptcha.php:848
657
+ msgid "approved comment(s)."
658
+ msgstr "approved comment(s)."
659
 
660
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:524
661
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:534
662
+ msgid "loading..."
663
+ msgstr "loading..."
664
 
665
+ #: includes/class-bwp-recaptcha.php:691
666
+ msgid "reCAPTCHA API Keys"
667
+ msgstr "reCAPTCHA API Keys"
668
 
669
+ #: includes/class-bwp-recaptcha.php:695
670
+ msgid "reCAPTCHA Settings"
671
+ msgstr "reCAPTCHA Settings"
672
 
673
+ #: includes/class-bwp-recaptcha.php:702
674
+ msgid "reCAPTCHA for comment form"
675
+ msgstr "reCAPTCHA for comment form"
676
 
677
+ #: includes/class-bwp-recaptcha.php:1086
678
+ msgid "reCAPTCHA size"
679
+ msgstr "reCAPTCHA size"
680
 
681
+ #: includes/class-bwp-recaptcha.php:990 includes/class-bwp-recaptcha.php:1085
682
+ msgid "reCAPTCHA theme"
683
+ msgstr "reCAPTCHA theme"
684
 
685
+ #: includes/class-bwp-recaptcha.php:796
686
+ msgid "registered users <em>(even without any capabilities)</em>."
687
+ msgstr "registered users <em>(even without any capabilities)</em>."
688
+
689
+ #: includes/class-bwp-recaptcha.php:1554
690
+ msgid "this link"
691
+ msgstr "this link"
692
+
693
+ #: includes/class-bwp-recaptcha.php:799
694
+ msgid "users who can"
695
+ msgstr "users who can"
696
+
697
+ #: includes/class-bwp-recaptcha.php:802
698
+ msgid "visitors who have at least"
699
+ msgstr "visitors who have at least"
includes/class-bwp-recaptcha.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  /**
4
- * Copyright (c) 2015 Khang Minh <betterwp.net>
5
  *
6
  * This program is free software: you can redistribute it and/or modify
7
  * it under the terms of the GNU General Public License as published by
@@ -33,6 +33,11 @@ function bwp_capt_comment_form($args = array(), $post_id = null)
33
 
34
  ob_start();
35
 
 
 
 
 
 
36
  do_action('bwp_recaptcha_add_markups');
37
  $recaptcha_html = ob_get_contents();
38
 
@@ -119,6 +124,8 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
119
  'input_tab' => 0,
120
  'input_error_cf7' => $this->bridge->t('Incorrect or empty reCAPTCHA response, '
121
  . 'please try again.', $this->domain),
 
 
122
  'enable_comment' => 'yes',
123
  'enable_registration' => '',
124
  'enable_login' => '',
@@ -128,6 +135,7 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
128
  'enable_auto_fill_comment' => '',
129
  'enable_css' => 'yes',
130
  'enable_v1_https' => '', // @since 2.0.0, force recaptcha v1 to use https
 
131
  'use_recaptcha_v1' => '', // @since 2.0.0 whether to use recaptcha v1
132
  'use_global_keys' => 'yes',
133
  'select_lang' => 'en',
@@ -140,9 +148,11 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
140
  'select_v2_size' => 'normal', // @since 2.0.0
141
  'select_v2_jsapi_position' => 'on_demand', // @since 2.0.0 load on all pages or only when needed
142
  'select_akismet_react' => 'hold',
 
143
  'hide_registered' => '',
144
  'hide_cap' => '',
145
- 'hide_approved' => ''
 
146
  );
147
 
148
  $this->add_option_key('BWP_CAPT_OPTION_GENERAL', 'bwp_capt_general',
@@ -157,6 +167,32 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
157
  'http://betterwp.net/wordpress-plugins/bwp-recaptcha/', false);
158
  }
159
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  /**
161
  * Whether we should use the old recaptcha
162
  *
@@ -261,6 +297,21 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
261
  $this->lang = include_once dirname(__FILE__) . '/provider/v1-languages.php';
262
  $this->v2_lang = include_once dirname(__FILE__) . '/provider/v2-languages.php';
263
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
  $this->caps = $this->bridge->apply_filters('bwp_capt_bypass_caps', array(
265
  $this->bridge->t('Read Profile', $this->domain) => 'read',
266
  $this->bridge->t('Manage Options', $this->domain) => 'manage_options'
@@ -313,25 +364,30 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
313
  */
314
  private function _wp_registration_url()
315
  {
316
- return apply_filters('register_url', site_url('wp-login.php?action=register', 'login'));
317
  }
318
 
319
  protected function determine_current_page()
320
  {
321
- $login_path = str_replace(home_url(), '', wp_login_url());
322
- $register_path = str_replace(home_url(), '', $this->_wp_registration_url());
 
 
 
 
323
 
324
- if (strpos($_SERVER['REQUEST_URI'], $register_path) === 0)
 
325
  {
326
  // whether user is requesting regular user registration page
327
  $this->is_reg = true;
328
  }
329
- elseif (strpos($_SERVER['REQUEST_URI'], $login_path) === 0)
330
  {
331
  // whether user is requesting the wp-login page
332
  $this->is_login = true;
333
  }
334
- elseif (strpos($_SERVER['REQUEST_URI'], 'wp-signup.php') !== false)
335
  {
336
  // whether user is requesting wp-signup page (multi-site page for
337
  // user/site registration)
@@ -458,6 +514,13 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
458
  if ($this->is_admin_page())
459
  {
460
  wp_enqueue_script('bwp-capt-admin', BWP_CAPT_JS . '/admin.js', array('bwp-op'), $this->plugin_ver, true);
 
 
 
 
 
 
 
461
  }
462
 
463
  if ('yes' == $this->options['enable_css'])
@@ -465,6 +528,13 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
465
  if ('custom' == $this->options['select_theme']
466
  && ($this->is_admin_page(BWP_CAPT_OPTION_THEME) || !is_admin())
467
  ) {
 
 
 
 
 
 
 
468
  $custom_theme_css = apply_filters('bwp_capt_css', BWP_CAPT_CSS . '/custom-theme.css');
469
  wp_enqueue_style('bwp-capt', $custom_theme_css);
470
  }
@@ -560,6 +630,24 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
560
  endif;
561
  }
562
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
563
  protected function build_option_page()
564
  {
565
  $page = $this->get_current_admin_page();
@@ -574,25 +662,27 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
574
 
575
  $form = array(
576
  'items' => array(
577
- 'heading',
578
  'checkbox',
579
  'input',
580
  'input',
581
- 'heading',
582
  'checkbox',
583
  'checkbox',
 
 
584
  'section',
585
  'section',
586
- 'heading',
587
  'select',
588
  'select',
589
  'checkbox',
590
  'input',
591
  'input',
592
- 'heading',
593
  'checkbox',
594
  'select',
595
- 'heading',
596
  'checkbox',
597
  'checkbox',
598
  'input'
@@ -602,9 +692,11 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
602
  __('Use main site\'s keys', $this->domain),
603
  __('Site Key', $this->domain),
604
  __('Secret Key', $this->domain),
605
- __('Plugin Functionality', $this->domain),
606
  __('Use reCAPTCHA version 1', $this->domain),
607
  __('Force https', $this->domain),
 
 
608
  __('Enable this plugin for', $this->domain),
609
  __('Hide captcha for', $this->domain),
610
  __('reCAPTCHA for comment form', $this->domain),
@@ -626,9 +718,11 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
626
  'use_global_keys',
627
  'input_pubkey',
628
  'input_prikey',
629
- 'heading_func',
630
  'use_recaptcha_v1',
631
  'enable_v1_https',
 
 
632
  'sec1',
633
  'sec2',
634
  'heading_comment',
@@ -652,7 +746,8 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
652
  . 'Once you have created those two keys for the current domain, '
653
  . 'simply paste them below.</em>', $this->domain),
654
  'https://www.google.com/recaptcha/admin/create'),
655
- 'heading_func' => '<em>' . __('Control how this plugin works.', $this->domain) . '</em>',
 
656
  'heading_comment' => '<em>' . __('Settings that are applied to '
657
  . 'comment forms only.', $this->domain) . '</em>',
658
  'h3' => '<em>' . __('Integrate the comment form with Akismet for better end-user experience.', $this->domain) . ' '
@@ -672,6 +767,7 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
672
  array('checkbox', 'name' => 'hide_approved')
673
  ),
674
  'select' => array(
 
675
  'select_cap' => $this->caps,
676
  'select_position' => array(
677
  __('After comment field', $this->domain) => 'after_comment_field',
@@ -717,7 +813,7 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
717
  __('Use the oldschool recaptcha instead of the new <em>nocaptcha</em> recaptcha.', $this->domain) => ''
718
  ),
719
  'enable_v1_https' => array(
720
- __('Make requests to recaptcha server always secured', $this->domain) => 'enable_v1_https'
721
  ),
722
  'enable_auto_fill_comment' => array(
723
  __('After redirected, auto fill the comment field with previous comment.', $this->domain)
@@ -772,6 +868,19 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
772
  . 'authenticate user\'s response.', $this->domain),
773
  'placement' => 'right'
774
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
775
  'select_akismet_react' => array(
776
  'target' => 'icon',
777
  'content' => __('It is best to put comments identified as spam in moderation queue '
@@ -837,6 +946,7 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
837
  'use_global_keys',
838
  'use_recaptcha_v1',
839
  'enable_v1_https',
 
840
  'input_pubkey',
841
  'input_prikey',
842
  'input_error',
@@ -871,6 +981,7 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
871
  'items' => array(
872
  'select',
873
  'checkbox',
 
874
  'select',
875
  'input',
876
  'heading'
@@ -878,6 +989,7 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
878
  'item_labels' => array(
879
  __('reCAPTCHA theme', $this->domain),
880
  __('Use default CSS', $this->domain),
 
881
  __('Language for built-in themes', $this->domain),
882
  __('Tabindex for captcha input field', $this->domain),
883
  __('Preview your reCAPTCHA', $this->domain)
@@ -885,13 +997,14 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
885
  'item_names' => array(
886
  'select_theme',
887
  'enable_css',
 
888
  'select_lang',
889
  'input_tab',
890
  'h1'
891
  ),
892
  'heading' => array(
893
  'h1' => __('<em>Below you will see how your reCAPTCHA will look. '
894
- . 'Note that this might differ on your actual pages.<br /></em>', $this->domain)
895
  ),
896
  'select' => array(
897
  'select_theme' => array(
@@ -904,13 +1017,24 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
904
  'select_lang' => $this->lang
905
  ),
906
  'checkbox' => array(
907
- 'enable_css' => array('' => '')
 
 
908
  ),
909
  'input' => array(
910
  'input_tab' => array(
911
  'size' => 3
912
  )
913
  ),
 
 
 
 
 
 
 
 
 
914
  'container' => array(
915
  ),
916
  'helps' => array(
@@ -938,12 +1062,21 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
938
  'class' => 'bwp-switch-select bwp-switch-on-load',
939
  'data-target' => 'enable_css',
940
  'data-toggle-value' => 'custom'
 
 
 
 
 
 
 
 
941
  )
942
  )
943
  ) : array(
944
  'items' => array(
945
  'select',
946
  'select',
 
947
  'select',
948
  'input',
949
  'heading'
@@ -951,6 +1084,7 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
951
  'item_labels' => array(
952
  __('reCAPTCHA theme', $this->domain),
953
  __('reCAPTCHA size', $this->domain),
 
954
  __('Language', $this->domain),
955
  __('Tabindex for captcha input field', $this->domain),
956
  __('Preview your reCAPTCHA', $this->domain)
@@ -958,13 +1092,14 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
958
  'item_names' => array(
959
  'select_v2_theme',
960
  'select_v2_size',
 
961
  'select_v2_lang',
962
  'input_tab',
963
  'h1'
964
  ),
965
  'heading' => array(
966
  'h1' => __('<em>Below you will see how your reCAPTCHA will look. '
967
- . 'Note that this might differ on your actual pages.<br /></em>', $this->domain)
968
  ),
969
  'select' => array(
970
  'select_v2_theme' => array(
@@ -984,11 +1119,34 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
984
  /* __('Manually', $this->domain) => 'manually' */
985
  /* ) */
986
  ),
 
 
 
 
987
  'input' => array(
988
  'input_tab' => array(
989
  'size' => 3,
990
  'label' => __('Set to 0 to disable.', $this->domain)
991
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
992
  )
993
  );
994
 
@@ -1006,12 +1164,16 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
1006
  'select_lang',
1007
  'select_theme',
1008
  'input_tab',
 
 
1009
  'enable_css'
1010
  ) : array(
1011
  'select_v2_theme',
1012
  'select_v2_size',
1013
  'select_v2_lang',
1014
- 'input_tab'
 
 
1015
  );
1016
  }
1017
  }
@@ -1034,6 +1196,29 @@ class BWP_RECAPTCHA extends BWP_Framework_V3
1034
  );
1035
  }
1036
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1037
  if ('yes' == $this->options['enable_akismet'] && !defined('AKISMET_VERSION'))
1038
  {
1039
  // add a notice if Akismet integration is enabled but Akismet
1
  <?php
2
 
3
  /**
4
+ * Copyright (c) 2011 Khang Minh <betterwp.net>
5
  *
6
  * This program is free software: you can redistribute it and/or modify
7
  * it under the terms of the GNU General Public License as published by
33
 
34
  ob_start();
35
 
36
+ /**
37
+ * Fire where a recaptcha should be rendered.
38
+ *
39
+ * This action hooks is mostly used to render the captcha in certain forms.
40
+ */
41
  do_action('bwp_recaptcha_add_markups');
42
  $recaptcha_html = ob_get_contents();
43
 
124
  'input_tab' => 0,
125
  'input_error_cf7' => $this->bridge->t('Incorrect or empty reCAPTCHA response, '
126
  . 'please try again.', $this->domain),
127
+ 'input_v1_styles' => $this->get_default_v1_custom_styles(), // @since 2.0.3
128
+ 'input_v2_styles' => $this->get_default_v2_custom_styles(), // @since 2.0.3
129
  'enable_comment' => 'yes',
130
  'enable_registration' => '',
131
  'enable_login' => '',
135
  'enable_auto_fill_comment' => '',
136
  'enable_css' => 'yes',
137
  'enable_v1_https' => '', // @since 2.0.0, force recaptcha v1 to use https
138
+ 'enable_custom_styles' => '', // @since 2.0.3
139
  'use_recaptcha_v1' => '', // @since 2.0.0 whether to use recaptcha v1
140
  'use_global_keys' => 'yes',
141
  'select_lang' => 'en',
148
  'select_v2_size' => 'normal', // @since 2.0.0
149
  'select_v2_jsapi_position' => 'on_demand', // @since 2.0.0 load on all pages or only when needed
150
  'select_akismet_react' => 'hold',
151
+ 'select_request_method' => 'auto', // @since 2.0.3
152
  'hide_registered' => '',
153
  'hide_cap' => '',
154
+ 'hide_approved' => '',
155
+ 'nag_only_recaptcha_v1' => 'yes'
156
  );
157
 
158
  $this->add_option_key('BWP_CAPT_OPTION_GENERAL', 'bwp_capt_general',
167
  'http://betterwp.net/wordpress-plugins/bwp-recaptcha/', false);
168
  }
169
 
170
+ private function get_default_v1_custom_styles()
171
+ {
172
+ $styles = array(
173
+ '#recaptcha_widget_div {',
174
+ ' display: block;',
175
+ ' clear: both;',
176
+ ' margin-bottom: 1em;',
177
+ '}'
178
+ );
179
+
180
+ return implode("\n", $styles);
181
+ }
182
+
183
+ private function get_default_v2_custom_styles()
184
+ {
185
+ $styles = array(
186
+ '.g-recaptcha {',
187
+ ' display: block;',
188
+ ' clear: both;',
189
+ ' margin-bottom: 1em;',
190
+ '}'
191
+ );
192
+
193
+ return implode("\n", $styles);
194
+ }
195
+
196
  /**
197
  * Whether we should use the old recaptcha
198
  *
297
  $this->lang = include_once dirname(__FILE__) . '/provider/v1-languages.php';
298
  $this->v2_lang = include_once dirname(__FILE__) . '/provider/v2-languages.php';
299
 
300
+ /**
301
+ * Filter WordPress capabilities that can bypass a recaptcha.
302
+ *
303
+ * @see https://codex.wordpress.org/Roles_and_Capabilities
304
+ *
305
+ * @param array $capabilities The capabilities to filter.
306
+ *
307
+ * @return array Example:
308
+ * ```
309
+ * return $caps = array(
310
+ * 'Read Profile' => 'read',
311
+ * 'Manage Options' => 'manage_options'
312
+ * );
313
+ * ```
314
+ */
315
  $this->caps = $this->bridge->apply_filters('bwp_capt_bypass_caps', array(
316
  $this->bridge->t('Read Profile', $this->domain) => 'read',
317
  $this->bridge->t('Manage Options', $this->domain) => 'manage_options'
364
  */
365
  private function _wp_registration_url()
366
  {
367
+ return $this->bridge->apply_filters('register_url', $this->bridge->site_url('wp-login.php?action=register', 'login'));
368
  }
369
 
370
  protected function determine_current_page()
371
  {
372
+ // @since 2.0.3 only strip the host and scheme (including https), so
373
+ // we can properly compare with REQUEST_URI later on.
374
+ $login_path = preg_replace('#https?://[^/]+/#i', '', $this->bridge->wp_login_url());
375
+ $register_path = preg_replace('#https?://[^/]+/#i', '', $this->_wp_registration_url());
376
+
377
+ global $pagenow;
378
 
379
+ $request_uri = ltrim($_SERVER['REQUEST_URI'], '/');
380
+ if (strpos($request_uri, $register_path) === 0)
381
  {
382
  // whether user is requesting regular user registration page
383
  $this->is_reg = true;
384
  }
385
+ elseif (strpos($request_uri, $login_path) === 0)
386
  {
387
  // whether user is requesting the wp-login page
388
  $this->is_login = true;
389
  }
390
+ elseif (!empty($pagenow) && $pagenow == 'wp-signup.php')
391
  {
392
  // whether user is requesting wp-signup page (multi-site page for
393
  // user/site registration)
514
  if ($this->is_admin_page())
515
  {
516
  wp_enqueue_script('bwp-capt-admin', BWP_CAPT_JS . '/admin.js', array('bwp-op'), $this->plugin_ver, true);
517
+
518
+ if ($this->is_admin_page(BWP_CAPT_OPTION_THEME))
519
+ {
520
+ wp_enqueue_style('bwp-codemirror');
521
+ wp_enqueue_script('bwp-codemirror-css');
522
+ wp_enqueue_script('bwp-op-codemirror');
523
+ }
524
  }
525
 
526
  if ('yes' == $this->options['enable_css'])
528
  if ('custom' == $this->options['select_theme']
529
  && ($this->is_admin_page(BWP_CAPT_OPTION_THEME) || !is_admin())
530
  ) {
531
+ /**
532
+ * Filter the CSS file used for Custom Theme.
533
+ *
534
+ * This filter is used for **reCAPTCHA version 1** only.
535
+ *
536
+ * @param string $css_file An absolute URL to the CSS file.
537
+ */
538
  $custom_theme_css = apply_filters('bwp_capt_css', BWP_CAPT_CSS . '/custom-theme.css');
539
  wp_enqueue_style('bwp-capt', $custom_theme_css);
540
  }
630
  endif;
631
  }
632
 
633
+ private function _get_available_request_methods()
634
+ {
635
+ $methods = array(
636
+ __('Auto detected', $this->domain) => 'auto'
637
+ );
638
+
639
+ if (function_exists('fsockopen'))
640
+ $methods['Socket (fsockopen)'] = 'socket';
641
+
642
+ if (extension_loaded('curl'))
643
+ $methods['cURL'] = 'curl';
644
+
645
+ if (ini_get('allow_url_fopen'))
646
+ $methods['file_get_contents'] = 'fileio';
647
+
648
+ return $methods;
649
+ }
650
+
651
  protected function build_option_page()
652
  {
653
  $page = $this->get_current_admin_page();
662
 
663
  $form = array(
664
  'items' => array(
665
+ 'heading', // recaptcha api keys
666
  'checkbox',
667
  'input',
668
  'input',
669
+ 'heading', // recaptcha setting
670
  'checkbox',
671
  'checkbox',
672
+ 'select',
673
+ 'heading', // main functionality
674
  'section',
675
  'section',
676
+ 'heading', // comment form
677
  'select',
678
  'select',
679
  'checkbox',
680
  'input',
681
  'input',
682
+ 'heading', // akistmet integration
683
  'checkbox',
684
  'select',
685
+ 'heading', // contact form 7 integration
686
  'checkbox',
687
  'checkbox',
688
  'input'
692
  __('Use main site\'s keys', $this->domain),
693
  __('Site Key', $this->domain),
694
  __('Secret Key', $this->domain),
695
+ __('reCAPTCHA Settings', $this->domain),
696
  __('Use reCAPTCHA version 1', $this->domain),
697
  __('Force https', $this->domain),
698
+ __('Request method', $this->domain),
699
+ __('Main Functionality', $this->domain),
700
  __('Enable this plugin for', $this->domain),
701
  __('Hide captcha for', $this->domain),
702
  __('reCAPTCHA for comment form', $this->domain),
718
  'use_global_keys',
719
  'input_pubkey',
720
  'input_prikey',
721
+ 'heading_recaptcha',
722
  'use_recaptcha_v1',
723
  'enable_v1_https',
724
+ 'select_request_method',
725
+ 'heading_func',
726
  'sec1',
727
  'sec2',
728
  'heading_comment',
746
  . 'Once you have created those two keys for the current domain, '
747
  . 'simply paste them below.</em>', $this->domain),
748
  'https://www.google.com/recaptcha/admin/create'),
749
+ 'heading_recaptcha' => '',
750
+ 'heading_func' => '',
751
  'heading_comment' => '<em>' . __('Settings that are applied to '
752
  . 'comment forms only.', $this->domain) . '</em>',
753
  'h3' => '<em>' . __('Integrate the comment form with Akismet for better end-user experience.', $this->domain) . ' '
767
  array('checkbox', 'name' => 'hide_approved')
768
  ),
769
  'select' => array(
770
+ 'select_request_method' => $this->_get_available_request_methods(),
771
  'select_cap' => $this->caps,
772
  'select_position' => array(
773
  __('After comment field', $this->domain) => 'after_comment_field',
813
  __('Use the oldschool recaptcha instead of the new <em>nocaptcha</em> recaptcha.', $this->domain) => ''
814
  ),
815
  'enable_v1_https' => array(
816
+ __('Make requests to recaptcha server always secured.', $this->domain) => 'enable_v1_https'
817
  ),
818
  'enable_auto_fill_comment' => array(
819
  __('After redirected, auto fill the comment field with previous comment.', $this->domain)
868
  . 'authenticate user\'s response.', $this->domain),
869
  'placement' => 'right'
870
  ),
871
+ 'select_request_method' => array(
872
+ 'target' => 'icon',
873
+ 'content' => __('To verify a captcha response, '
874
+ . 'this plugin needs to send requests to the reCAPTCHA server, '
875
+ . 'using a specific request method. '
876
+ . '<br /><br />'
877
+ . 'By default, BWP reCAPTCHA use the first available request method, '
878
+ . 'be it Socket (<code>fsockopen</code>), cURL, or <code>file_get_contents</code>.', $this->domain)
879
+ . '<br /><br />'
880
+ . __('If you encounter error such as <code>Unknown error (invalid-json)</code>'
881
+ . 'when submitting a form, try selecting a specific request method here.', $this->domain),
882
+ 'size' => 'small'
883
+ ),
884
  'select_akismet_react' => array(
885
  'target' => 'icon',
886
  'content' => __('It is best to put comments identified as spam in moderation queue '
946
  'use_global_keys',
947
  'use_recaptcha_v1',
948
  'enable_v1_https',
949
+ 'select_request_method',
950
  'input_pubkey',
951
  'input_prikey',
952
  'input_error',
981
  'items' => array(
982
  'select',
983
  'checkbox',
984
+ 'checkbox',
985
  'select',
986
  'input',
987
  'heading'
989
  'item_labels' => array(
990
  __('reCAPTCHA theme', $this->domain),
991
  __('Use default CSS', $this->domain),
992
+ __('Enable custom CSS', $this->domain),
993
  __('Language for built-in themes', $this->domain),
994
  __('Tabindex for captcha input field', $this->domain),
995
  __('Preview your reCAPTCHA', $this->domain)
997
  'item_names' => array(
998
  'select_theme',
999
  'enable_css',
1000
+ 'enable_custom_styles',
1001
  'select_lang',
1002
  'input_tab',
1003
  'h1'
1004
  ),
1005
  'heading' => array(
1006
  'h1' => __('<em>Below you will see how your reCAPTCHA will look. '
1007
+ . 'Note that this might differ on your actual pages.</em>', $this->domain)
1008
  ),
1009
  'select' => array(
1010
  'select_theme' => array(
1017
  'select_lang' => $this->lang
1018
  ),
1019
  'checkbox' => array(
1020
+ 'enable_css' => array('' => ''),
1021
+ 'enable_custom_styles' => array(__('Add additional CSS rules '
1022
+ . 'to all recaptcha instances. You can edit them below.', $this->domain) . '<br />' => '')
1023
  ),
1024
  'input' => array(
1025
  'input_tab' => array(
1026
  'size' => 3
1027
  )
1028
  ),
1029
+ 'textarea' => array(
1030
+ 'input_v1_styles' => array(
1031
+ 'cols' => 90,
1032
+ 'rows' => 10
1033
+ )
1034
+ ),
1035
+ 'inline_fields' => array(
1036
+ 'enable_custom_styles' => array('input_v1_styles' => 'textarea')
1037
+ ),
1038
  'container' => array(
1039
  ),
1040
  'helps' => array(
1062
  'class' => 'bwp-switch-select bwp-switch-on-load',
1063
  'data-target' => 'enable_css',
1064
  'data-toggle-value' => 'custom'
1065
+ ),
1066
+ 'enable_custom_styles' => array(
1067
+ 'class' => 'bwp-code-editor-cb',
1068
+ 'data-target' => 'input_v1_styles'
1069
+ ),
1070
+ 'input_v1_styles' => array(
1071
+ 'class' => 'bwp-form-control bwp-code-editor',
1072
+ 'data-mode' => 'css'
1073
  )
1074
  )
1075
  ) : array(
1076
  'items' => array(
1077
  'select',
1078
  'select',
1079
+ 'checkbox',
1080
  'select',
1081
  'input',
1082
  'heading'
1084
  'item_labels' => array(
1085
  __('reCAPTCHA theme', $this->domain),
1086
  __('reCAPTCHA size', $this->domain),
1087
+ __('Enable custom CSS', $this->domain),
1088
  __('Language', $this->domain),
1089
  __('Tabindex for captcha input field', $this->domain),
1090
  __('Preview your reCAPTCHA', $this->domain)
1092
  'item_names' => array(
1093
  'select_v2_theme',
1094
  'select_v2_size',
1095
+ 'enable_custom_styles',
1096
  'select_v2_lang',
1097
  'input_tab',
1098
  'h1'
1099
  ),
1100
  'heading' => array(
1101
  'h1' => __('<em>Below you will see how your reCAPTCHA will look. '
1102
+ . 'Note that this might differ on your actual pages.</em>', $this->domain)
1103
  ),
1104
  'select' => array(
1105
  'select_v2_theme' => array(
1119
  /* __('Manually', $this->domain) => 'manually' */
1120
  /* ) */
1121
  ),
1122
+ 'checkbox' => array(
1123
+ 'enable_custom_styles' => array(__('Add additional CSS rules '
1124
+ . 'to all recaptcha instances. You can edit them below.', $this->domain) . '<br />' => '')
1125
+ ),
1126
  'input' => array(
1127
  'input_tab' => array(
1128
  'size' => 3,
1129
  'label' => __('Set to 0 to disable.', $this->domain)
1130
  )
1131
+ ),
1132
+ 'textarea' => array(
1133
+ 'input_v2_styles' => array(
1134
+ 'cols' => 90,
1135
+ 'rows' => 10
1136
+ )
1137
+ ),
1138
+ 'inline_fields' => array(
1139
+ 'enable_custom_styles' => array('input_v2_styles' => 'textarea')
1140
+ ),
1141
+ 'attributes' => array(
1142
+ 'enable_custom_styles' => array(
1143
+ 'class' => 'bwp-code-editor-cb',
1144
+ 'data-target' => 'input_v2_styles'
1145
+ ),
1146
+ 'input_v2_styles' => array(
1147
+ 'class' => 'bwp-form-control bwp-code-editor',
1148
+ 'data-mode' => 'css'
1149
+ )
1150
  )
1151
  );
1152
 
1164
  'select_lang',
1165
  'select_theme',
1166
  'input_tab',
1167
+ 'enable_custom_styles',
1168
+ 'input_v1_styles',
1169
  'enable_css'
1170
  ) : array(
1171
  'select_v2_theme',
1172
  'select_v2_size',
1173
  'select_v2_lang',
1174
+ 'input_tab',
1175
+ 'enable_custom_styles',
1176
+ 'input_v2_styles'
1177
  );
1178
  }
1179
  }
1196
  );
1197
  }
1198
 
1199
+ // @since 2.0.3 if the current PHP version is smaller than 5.3.2, and we
1200
+ // need to nag user that only recaptcha v1 can be used
1201
+ if (! BWP_Version::get_current_php_version('5.3.2')
1202
+ && $this->options['nag_only_recaptcha_v1'] == 'yes'
1203
+ ) {
1204
+ $this->add_notice(
1205
+ '<strong>' . __('Notice') . ':</strong> '
1206
+ . sprintf(
1207
+ __('In order to use the nocaptcha recaptcha (recaptcha v2), '
1208
+ . 'you need at least <strong>PHP 5.3.2</strong> '
1209
+ . '(your current PHP version is <strong>%s</strong>), '
1210
+ . 'so only recaptcha v1 can be used. '
1211
+ . 'It is recommended to contact your host to '
1212
+ . 'know how to update your current version of PHP.', $this->domain),
1213
+ BWP_Version::get_current_php_version()
1214
+ )
1215
+ );
1216
+
1217
+ $this->update_some_options(BWP_CAPT_OPTION_GENERAL, array(
1218
+ 'nag_only_recaptcha_v1' => ''
1219
+ ));
1220
+ }
1221
+
1222
  if ('yes' == $this->options['enable_akismet'] && !defined('AKISMET_VERSION'))
1223
  {
1224
  // add a notice if Akismet integration is enabled but Akismet
includes/provider/abstract-provider.php CHANGED
@@ -16,10 +16,13 @@ abstract class BWP_Recaptcha_Provider
16
 
17
  protected $domain;
18
 
19
- public function __construct(array $options, $domain)
 
 
20
  {
21
  $this->options = $options;
22
  $this->domain = $domain;
 
23
  }
24
 
25
  public static function create(BWP_RECAPTCHA $plugin)
@@ -30,30 +33,34 @@ abstract class BWP_Recaptcha_Provider
30
  $providerOptions = array(
31
  'site_key' => $options['input_pubkey'],
32
  'secret_key' => $options['input_prikey'],
 
33
  'theme' => $options['select_theme'],
34
  'language' => $options['select_lang'],
35
  'tabindex' => $options['input_tab'],
36
  'invalid_response_message' => $options['input_error'],
37
  'invalid_response_message_cf7' => $options['input_error_cf7'],
 
38
  );
39
 
40
  // if instructed to use recaptcha v1, or the current PHP version is
41
  // less than 5.3.2, we need to use v1 provider
42
  if ($plugin->should_use_old_recaptcha()) {
43
  $providerOptions = array_merge($providerOptions, array(
44
- 'use_ssl' => $options['enable_v1_https']
 
45
  ));
46
 
47
- return new BWP_Recaptcha_Provider_V1($providerOptions, $domain);
48
  } else {
49
  $providerOptions = array_merge($providerOptions, array(
50
- 'language' => $options['select_v2_lang'],
51
- 'theme' => $options['select_v2_theme'],
52
- 'size' => $options['select_v2_size'],
53
- 'position' => $options['select_v2_jsapi_position']
 
54
  ));
55
 
56
- return new BWP_Recaptcha_Provider_V2($providerOptions, $domain);
57
  }
58
  }
59
 
16
 
17
  protected $domain;
18
 
19
+ protected $bridge;
20
+
21
+ public function __construct(array $options, $domain, BWP_WP_Bridge $bridge)
22
  {
23
  $this->options = $options;
24
  $this->domain = $domain;
25
+ $this->bridge = $bridge;
26
  }
27
 
28
  public static function create(BWP_RECAPTCHA $plugin)
33
  $providerOptions = array(
34
  'site_key' => $options['input_pubkey'],
35
  'secret_key' => $options['input_prikey'],
36
+ 'request_method' => $options['select_request_method'],
37
  'theme' => $options['select_theme'],
38
  'language' => $options['select_lang'],
39
  'tabindex' => $options['input_tab'],
40
  'invalid_response_message' => $options['input_error'],
41
  'invalid_response_message_cf7' => $options['input_error_cf7'],
42
+ 'use_custom_styles' => $options['enable_custom_styles'],
43
  );
44
 
45
  // if instructed to use recaptcha v1, or the current PHP version is
46
  // less than 5.3.2, we need to use v1 provider
47
  if ($plugin->should_use_old_recaptcha()) {
48
  $providerOptions = array_merge($providerOptions, array(
49
+ 'use_ssl' => $options['enable_v1_https'],
50
+ 'custom_styles' => $options['input_v1_styles']
51
  ));
52
 
53
+ return new BWP_Recaptcha_Provider_V1($providerOptions, $domain, $plugin->get_bridge());
54
  } else {
55
  $providerOptions = array_merge($providerOptions, array(
56
+ 'language' => $options['select_v2_lang'],
57
+ 'theme' => $options['select_v2_theme'],
58
+ 'size' => $options['select_v2_size'],
59
+ 'position' => $options['select_v2_jsapi_position'],
60
+ 'custom_styles' => $options['input_v2_styles']
61
  ));
62
 
63
+ return new BWP_Recaptcha_Provider_V2($providerOptions, $domain, $plugin->get_bridge());
64
  }
65
  }
66
 
includes/provider/v1.php CHANGED
@@ -44,6 +44,12 @@ class BWP_Recaptcha_Provider_V1 extends BWP_Recaptcha_Provider
44
  iframe[src="about:blank"] { display: none; }
45
  /* make sure the captcha uses auto table layout */
46
  .recaptchatable { table-layout: auto; }
 
 
 
 
 
 
47
  </style>
48
  <?php
49
  if ($this->options['theme'] != 'custom') {
44
  iframe[src="about:blank"] { display: none; }
45
  /* make sure the captcha uses auto table layout */
46
  .recaptchatable { table-layout: auto; }
47
+ <?php
48
+ // @since 2.0.3 allow adding custom styles to captcha instances
49
+ if ($this->options['use_custom_styles'] && !empty($this->options['custom_styles'])) {
50
+ echo esc_html($this->options['custom_styles']);
51
+ }
52
+ ?>
53
  </style>
54
  <?php
55
  if ($this->options['theme'] != 'custom') {
includes/provider/v2.php CHANGED
@@ -37,9 +37,19 @@ class BWP_Recaptcha_Provider_V2 extends BWP_Recaptcha_Provider
37
  */
38
  protected $instances = array();
39
 
40
- public function __construct(array $options, $domain)
 
 
 
 
 
 
 
 
 
 
41
  {
42
- parent::__construct($options, $domain);
43
 
44
  $this->_registerHooks();
45
  }
@@ -64,7 +74,24 @@ class BWP_Recaptcha_Provider_V2 extends BWP_Recaptcha_Provider
64
  $output[] = '<p class="bwp-recaptcha-error error">' . $captchaError . '</p>';
65
  }
66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  $output[] = implode('', array(
 
68
  '<input type="hidden" name="bwp-recaptcha-widget-id" value="' . esc_attr($this->_getWidgetId($formId)) . '" />',
69
  '<div id="' . $this->_getWidgetHtmlId($formId) . '" class="bwp-recaptcha g-recaptcha" ',
70
  /* 'data-sitekey="' . esc_attr($this->options['site_key']) . '" ', */
@@ -75,6 +102,12 @@ class BWP_Recaptcha_Provider_V2 extends BWP_Recaptcha_Provider
75
  '</div>'
76
  ));
77
 
 
 
 
 
 
 
78
  do_action('bwp_capt_before_add_captcha');
79
 
80
  echo implode("\n", $output);
@@ -152,7 +185,29 @@ class BWP_Recaptcha_Provider_V2 extends BWP_Recaptcha_Provider
152
  */
153
  private function _createRequestMethod()
154
  {
155
- // check for cURL first
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  if (extension_loaded('curl')) {
157
  return new CurlPost();
158
  }
@@ -162,9 +217,6 @@ class BWP_Recaptcha_Provider_V2 extends BWP_Recaptcha_Provider
162
  if (ini_get('allow_url_fopen')) {
163
  return new Post();
164
  }
165
-
166
- // last resort, use fsockopen
167
- return new SocketPost();
168
  }
169
 
170
  private function _registerHooks()
@@ -172,13 +224,25 @@ class BWP_Recaptcha_Provider_V2 extends BWP_Recaptcha_Provider
172
  $priority = 99999;
173
 
174
  // regular pages
175
- add_action('wp_footer', array($this, 'printRecaptchaJS'), $priority);
 
 
 
 
176
 
177
  // login/register page
178
- add_action('login_footer', array($this, 'printRecaptchaJS'), $priority);
 
 
 
 
179
 
180
  // admin theme preview page
181
- add_action('admin_footer-bwp-recapt_page_bwp_capt_theme', array($this, 'printRecaptchaJS'), $priority);
 
 
 
 
182
  }
183
 
184
  private function _getUniqueFormId($formId)
37
  */
38
  protected $instances = array();
39
 
40
+ /**
41
+ * Whether custom styles have been printed.
42
+ *
43
+ * Custom styles should only be printed once, so when it's printed this
44
+ * will become true to prevent further printing.
45
+ *
46
+ * @var bool
47
+ */
48
+ protected $custom_styles_printed = false;
49
+
50
+ public function __construct(array $options, $domain, BWP_WP_Bridge $bridge)
51
  {
52
+ parent::__construct($options, $domain, $bridge);
53
 
54
  $this->_registerHooks();
55
  }
74
  $output[] = '<p class="bwp-recaptcha-error error">' . $captchaError . '</p>';
75
  }
76
 
77
+ // @since 2.0.3 allow adding custom styles to captcha instances
78
+ if ($this->options['use_custom_styles'] && ! $this->custom_styles_printed
79
+ && !empty($this->options['custom_styles'])
80
+ ) {
81
+ $custom_styles = implode("\n", array(
82
+ '<style type="text/css">',
83
+ esc_html($this->options['custom_styles']),
84
+ '</style>'
85
+ ));
86
+
87
+ // only print custom styles once
88
+ $this->custom_styles_printed = true;
89
+ } else {
90
+ $custom_styles = '';
91
+ }
92
+
93
  $output[] = implode('', array(
94
+ $custom_styles,
95
  '<input type="hidden" name="bwp-recaptcha-widget-id" value="' . esc_attr($this->_getWidgetId($formId)) . '" />',
96
  '<div id="' . $this->_getWidgetHtmlId($formId) . '" class="bwp-recaptcha g-recaptcha" ',
97
  /* 'data-sitekey="' . esc_attr($this->options['site_key']) . '" ', */
102
  '</div>'
103
  ));
104
 
105
+ /**
106
+ * Fire before the captcha is shown.
107
+ *
108
+ * This action hook can be used to add custom markups before the
109
+ * captcha form.
110
+ */
111
  do_action('bwp_capt_before_add_captcha');
112
 
113
  echo implode("\n", $output);
185
  */
186
  private function _createRequestMethod()
187
  {
188
+ // @since 2.0.3 if there's a specific request method set, use it
189
+ if ($this->options['request_method'] !== 'auto') {
190
+ switch ($this->options['request_method']) {
191
+ case 'socket':
192
+ return new SocketPost();
193
+ break;
194
+
195
+ case 'curl':
196
+ return new CurlPost();
197
+ break;
198
+
199
+ case 'fileio':
200
+ return new Post();
201
+ break;
202
+ }
203
+ }
204
+
205
+ // @since 2.0.3 we try fsockopen first
206
+ if (function_exists('fsockopen')) {
207
+ return new SocketPost();
208
+ }
209
+
210
+ // next check for cURL
211
  if (extension_loaded('curl')) {
212
  return new CurlPost();
213
  }
217
  if (ini_get('allow_url_fopen')) {
218
  return new Post();
219
  }
 
 
 
220
  }
221
 
222
  private function _registerHooks()
224
  $priority = 99999;
225
 
226
  // regular pages
227
+ $this->bridge->add_action(
228
+ 'wp_footer',
229
+ array($this, 'printRecaptchaJS'),
230
+ $priority
231
+ );
232
 
233
  // login/register page
234
+ $this->bridge->add_action(
235
+ 'login_footer',
236
+ array($this, 'printRecaptchaJS'),
237
+ $priority
238
+ );
239
 
240
  // admin theme preview page
241
+ $this->bridge->add_action(
242
+ 'admin_footer-bwp-recapt_page_bwp_capt_theme',
243
+ array($this, 'printRecaptchaJS'),
244
+ $priority
245
+ );
246
  }
247
 
248
  private function _getUniqueFormId($formId)
languages/bwp-recaptcha-de_DE.mo CHANGED
Binary file
languages/bwp-recaptcha-de_DE.po CHANGED
@@ -1,9 +1,9 @@
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: BWP reCAPTCHA\n"
4
- "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: 2014-01-08 17:11+0700\n"
6
- "PO-Revision-Date: 2014-01-11 16:18+0100\n"
7
  "Last-Translator: Andreas Reitberger <andy.reitberger@gmail.com>\n"
8
  "Language-Team: wdbase.de <kontakt@wdbase.de>\n"
9
  "Language: de_DE\n"
@@ -13,11 +13,11 @@ msgstr ""
13
  "X-Poedit-KeywordsList: _;gettext;gettext_noop;__;_e\n"
14
  "X-Poedit-Basepath: .\n"
15
  "X-Poedit-SourceCharset: UTF-8\n"
16
- "X-Generator: Poedit 1.6.3\n"
17
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
18
  "X-Poedit-SearchPath-0: .\n"
19
 
20
- #: includes/class-bwp-framework.php:178
21
  #, php-format
22
  msgid ""
23
  "%s requires WordPress <strong>%s</strong> or higher and PHP <strong>%s</"
@@ -28,111 +28,186 @@ msgstr ""
28
  "strong> oder höher. Das Plugin wird erst funktionieren, wenn Sie Ihre "
29
  "Software aktualisiert haben. Bitte deaktivieren Sie bis dahin das Plugin."
30
 
31
- #: includes/class-bwp-framework.php:190
32
- msgid "Development Log"
33
- msgstr "Entwicklungslog"
34
 
35
- #: includes/class-bwp-framework.php:190
36
- msgid "Frequently Asked Questions"
37
- msgstr "Häufig gestellte Fragen"
 
 
 
 
 
 
38
 
39
- #: includes/class-bwp-framework.php:190
40
- msgid "FAQ"
41
- msgstr "FAQ"
 
 
 
 
42
 
43
- #: includes/class-bwp-framework.php:190
44
- msgid "Got a problem? Send me a feedback!"
45
- msgstr "Sie haben ein Problem? Senden Sie mir eine Rückmeldung!"
 
 
46
 
47
- #: includes/class-bwp-framework.php:190
48
- msgid "Contact"
49
- msgstr "Kontakt"
50
 
51
- #: includes/class-bwp-framework.php:197
 
52
  msgid ""
53
- "You can buy me some special coffees if you appreciate my work, thank you!"
 
54
  msgstr ""
55
- "Sie können mir einen speziellen Kaffe spendieren, wenn Ihnen meine Arbeit "
56
- "gefällt. Vielen Dank!"
57
 
58
- #: includes/class-bwp-framework.php:211
59
- msgid "Donate to "
60
- msgstr "Spende an"
61
 
62
- #: includes/class-bwp-framework.php:213
63
- msgid "One cup $5.00"
64
- msgstr "Eine Tasse $5.00"
 
65
 
66
- #: includes/class-bwp-framework.php:214
67
- msgid "Two cups $10.00"
68
- msgstr "Zwei Tassen $10.00"
 
 
69
 
70
- #: includes/class-bwp-framework.php:215
71
- msgid "Five cups! $25.00"
72
- msgstr "Fünf Tassen! $25.00"
 
73
 
74
- #: includes/class-bwp-framework.php:216
75
- msgid "One LL-cup!!! $50.00"
76
- msgstr "Eine riesen Tasse!!! $50.00"
 
77
 
78
- #: includes/class-bwp-framework.php:217
79
- msgid "... or any amount!"
80
- msgstr "... oder selbst Betrag wählen!"
81
 
82
- #: includes/class-bwp-framework.php:232
83
- msgid "Latest updates from BetterWP.net!"
84
- msgstr "Neusten Beiträge von BetterWP.net!"
85
 
86
- #: includes/class-bwp-framework.php:233
87
- msgid "Follow me on Twitter!"
88
- msgstr "Folgen Sie mir auf Twitter!"
 
89
 
90
- #: includes/class-bwp-framework.php:243
91
- msgid "This Plugin is Proudly Sponsored By"
92
- msgstr "Dieses Plugin wird stolz gesponsert von"
93
 
94
- #: includes/class-bwp-framework.php:260
95
- #, php-format
96
- msgid "You are using version %s!"
97
- msgstr "Sie benutzen aktuell die Version %s!"
98
 
99
- #: includes/class-bwp-framework.php:396
100
- msgid "Settings"
101
- msgstr "Einstellungen"
102
 
103
- #: includes/class-bwp-recaptcha.php:44
104
- msgid "Get another challenge"
105
- msgstr "Neues reCAPTACHA abrufen"
106
 
107
- #: includes/class-bwp-recaptcha.php:45
108
- msgid "Get audio reCAPTCHA"
109
- msgstr "Audio-reCAPTCHA abrufen"
110
 
111
- #: includes/class-bwp-recaptcha.php:46
112
- msgid "Get image reCAPTCHA"
113
- msgstr "Bild-reCPATCHA abrufen"
114
 
115
- #: includes/class-bwp-recaptcha.php:47
116
- msgid "About reCAPTCHA"
117
- msgstr "Über reCAPTCHA"
118
 
119
- #: includes/class-bwp-recaptcha.php:51
120
- msgid "Enter the two words in the box:"
121
- msgstr "Geben Sie die zwei Wörter hier ein:"
122
 
123
- #: includes/class-bwp-recaptcha.php:52
124
- msgid "Enter the numbers you hear:"
125
- msgstr "Geben Sie die Nummer ein, die Sie hören:"
126
 
127
- #: includes/class-bwp-recaptcha.php:132
128
- msgid ""
129
- "<strong>ERROR:</strong> Incorrect or empty reCAPTCHA response, please try "
130
- "again."
 
 
 
 
 
 
131
  msgstr ""
132
- "<strong>FEHLER:</strong> Falsche oder leere Antwort, bitte versuchen Sie es "
133
- "nochmals."
134
 
135
- #: includes/class-bwp-recaptcha.php:133
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  #, php-format
137
  msgid ""
138
  "Error: Incorrect or empty reCAPTCHA response, please click the back button "
@@ -141,392 +216,423 @@ msgstr ""
141
  "Fehler: Falsche oder leere Antwort, bitte klicken Sie auf den Zurück-Button "
142
  "in Ihrem Browser oder klicken Sie %s um zurück zu gehen."
143
 
144
- #: includes/class-bwp-recaptcha.php:155 includes/class-bwp-recaptcha.php:313
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  msgid "General Options"
146
  msgstr "Allgemeine Einstellungen"
147
 
148
- #: includes/class-bwp-recaptcha.php:156 includes/class-bwp-recaptcha.php:314
149
- msgid "Theme Options"
150
- msgstr "Designeinstellungen"
151
 
152
- #: includes/class-bwp-recaptcha.php:159
153
- msgid "English"
154
- msgstr "Englisch"
155
 
156
- #: includes/class-bwp-recaptcha.php:160
157
- msgid "Dutch"
158
- msgstr "Holländisch"
159
 
160
- #: includes/class-bwp-recaptcha.php:161
161
- msgid "French"
162
- msgstr "Holländisch"
163
 
164
- #: includes/class-bwp-recaptcha.php:162
165
- msgid "German"
166
- msgstr "Deutsch"
 
167
 
168
- #: includes/class-bwp-recaptcha.php:163
169
- msgid "Portuguese"
170
- msgstr "Portugiesisch"
171
 
172
- #: includes/class-bwp-recaptcha.php:164
173
- msgid "Russian"
174
- msgstr "Russisch"
 
175
 
176
- #: includes/class-bwp-recaptcha.php:165
177
- msgid "Spanish"
178
- msgstr "Spanisch"
 
179
 
180
- #: includes/class-bwp-recaptcha.php:166
181
- msgid "Turkish"
182
- msgstr "Türkisch"
 
 
183
 
184
- #: includes/class-bwp-recaptcha.php:170
185
- msgid "Read Profile"
186
- msgstr "Profil lesen"
 
 
 
187
 
188
- #: includes/class-bwp-recaptcha.php:171
189
- msgid "Manage Options"
190
- msgstr "Einstellungen bearbeiten"
 
 
 
 
 
191
 
192
- #: includes/class-bwp-recaptcha.php:311
193
- msgid "Better WordPress reCAPTCHA"
194
- msgstr "Better WordPress reCAPTCHA"
 
 
 
195
 
196
- #: includes/class-bwp-recaptcha.php:313
197
- msgid "BWP reCAPTCHA General Options"
198
- msgstr "BWP reCAPTCHA Designeinstellungen"
199
 
200
- #: includes/class-bwp-recaptcha.php:314
201
- msgid "BWP reCAPTCHA Theme Options"
202
- msgstr "BWP reCAPTCHA Designeinstellungen"
203
 
204
- #: includes/class-bwp-recaptcha.php:347
205
- msgid "You do not have sufficient permissions to access this page."
206
- msgstr "Sie haben nicht ausreichend Berechtigungen um diese Seite zu öffnen."
 
207
 
208
- #: includes/class-bwp-recaptcha.php:366
209
- msgid "What is reCAPTCHA?"
210
- msgstr "Was ist reCAPTACHA?"
 
211
 
212
- #: includes/class-bwp-recaptcha.php:367
213
- msgid "This plugin will be"
214
- msgstr "Dieses Plugin wird"
 
 
215
 
216
- #: includes/class-bwp-recaptcha.php:368
217
- msgid "Use main site's keys"
218
- msgstr "Nutze die Schlüssel der Hauptseite"
 
 
 
219
 
220
- #: includes/class-bwp-recaptcha.php:369
221
- msgid "Public Key"
222
- msgstr "Public Key"
223
 
224
- #: includes/class-bwp-recaptcha.php:370
225
- msgid "Private Key"
226
- msgstr "Private Key"
 
227
 
228
- #: includes/class-bwp-recaptcha.php:371
229
- msgid "Visibility Options (applied to comment forms)"
230
- msgstr "Sichtbarkeits-Einstellung (betrifft nur den Kommentarbereich)"
231
 
232
- #: includes/class-bwp-recaptcha.php:372
233
- msgid "Hide the CAPTCHA for"
234
- msgstr "Verstecke das CAPTCHA für"
235
 
236
- #: includes/class-bwp-recaptcha.php:373
237
- msgid "If wrong or empty response"
238
- msgstr "Bei falscher oder leerer Antwort"
239
 
240
- #: includes/class-bwp-recaptcha.php:374 includes/class-bwp-recaptcha.php:375
241
- msgid "Show the error message"
242
- msgstr "Zeige diese Fehlernachricht,"
243
 
244
- #: includes/class-bwp-recaptcha.php:376
245
- msgid "Akismet Integration (applied to comment forms)"
246
- msgstr "Akisment Integration (betrifft nur den Kommentarbereich)"
247
 
248
- #: includes/class-bwp-recaptcha.php:377
249
- msgid "Integrate with Akismet?"
250
- msgstr "Soll Akisment integriert werden?"
 
251
 
252
- #: includes/class-bwp-recaptcha.php:378
253
- msgid "If correct CAPTCHA response"
254
- msgstr "Bei richtiger CAPTCHA Antwort"
255
 
256
- #: includes/class-bwp-recaptcha.php:382
257
- msgid ""
258
- "reCAPTCHA is a free CAPTCHA service that helps to digitize books, newspapers "
259
- "and old time radio shows. You can read more about reCAPTCHA <a href=\"http://"
260
- "www.google.com/recaptcha/learnmore\" target=\"_blank\">here</a>."
261
  msgstr ""
262
- "reCAPTCHA ist ein kostenloser CAPTCHA Service von Google, welcher hilft "
263
- "Bücher, Zeitungen und alte Radioshows zu digitalisieren. Mehr über reCAPTCHA "
264
- "könnt Ihr <a href=\"http://www.google.com/recaptcha/learnmore\" target="
265
- "\"_blank\">hier</a> nachlesen."
266
 
267
- #: includes/class-bwp-recaptcha.php:383
 
 
 
 
 
 
 
 
 
 
 
 
 
268
  msgid ""
269
- "<em>This section allows you to determine when to show reCAPTCHA and how this "
270
- "plugin reacts to errors.</em>"
 
271
  msgstr ""
272
- "<em>Dieser Bereich erlaubt es Ihnen zu bestimmen, wo eine reCPATCHA Form "
273
- "angezeigt werden soll und wie deise bei einer falschen Eingabe reagieren "
274
- "soll.</em>"
 
275
 
276
- #: includes/class-bwp-recaptcha.php:384
277
- msgid ""
278
- "<em>Integrate with Akismet for better end-user experience. reCAPTCHA is "
279
- "optional and <strong>NO</strong> spam comment will be added to the spam/"
280
- "moderation queue, except likely legitimate comments. This makes the task of "
281
- "identifying sincere comments much easier. This integration is currently in "
282
- "beta stage.</em>"
283
- msgstr ""
284
- "<em>Eine Integration mit Akismet verbessert die Endnutzer-Erfahrung. "
285
- "reCAPTCHA ist optional und <strong>kein</strong> Spam Kommentar wird zur "
286
- "Spam/Moderationswarteschlange, ausgenommen Kommentaren von echten Nutzern, "
287
- "hinzugefügt. Das erleichtert das identifizieren von richtigen Kommentaren "
288
- "viel einfacher. Diese Integration ist aktuell noch in der Beta-Phase.</em>"
289
-
290
- #: includes/class-bwp-recaptcha.php:400
291
- msgid "Redirect commenter back to the comment form"
292
- msgstr "Leite den Kommentator zurück zum Kommentar Bereich"
293
 
294
- #: includes/class-bwp-recaptcha.php:401
295
- msgid "Show an error page just like WordPress does"
296
- msgstr "Zeige eine Fehlerseite, so wie es WordPress tut"
297
 
298
- #: includes/class-bwp-recaptcha.php:404
299
- msgid "Approve comment immediately"
300
- msgstr "Kommentar unverzüglich freischalten"
301
 
302
- #: includes/class-bwp-recaptcha.php:405
303
- msgid "Hold comment in moderation queue"
304
- msgstr "Verschiebe den Kommentar in die Moderationswarteschlange"
305
 
306
- #: includes/class-bwp-recaptcha.php:406
307
- msgid "Put comment in spam queue"
308
- msgstr "Verschiebe den Kommentar in die Spam-Warteschlange"
309
 
310
- #: includes/class-bwp-recaptcha.php:410
311
- msgid "enabled for comment forms."
312
- msgstr "für Kommentare aktiviert."
 
 
 
 
 
 
 
313
 
314
- #: includes/class-bwp-recaptcha.php:411
315
- msgid "enabled for registration form (user/site registration)."
 
 
 
 
 
 
 
 
 
 
316
  msgstr "für die Registrierung aktiviert (Mitglied/Seiten Registrierung)."
317
 
318
- #: includes/class-bwp-recaptcha.php:412
319
- msgid "enabled for login form."
320
- msgstr "für die Anmeldung (Login) aktiviert."
321
 
322
- #: includes/class-bwp-recaptcha.php:413
323
- msgid "registered users <em>(even without any capabilities)</em>."
324
- msgstr "Registrierte Mitglieder <em>(für alle, ohne Ausnahme)</em>."
325
 
326
- #: includes/class-bwp-recaptcha.php:414
327
- msgid "users who can"
328
- msgstr "Mitglieder mit foglenden Rechten"
329
 
330
- #: includes/class-bwp-recaptcha.php:415
331
- msgid "visitors who have at least"
332
- msgstr "Besucher, die mindestens"
 
 
 
 
 
 
 
 
 
333
 
334
- #: includes/class-bwp-recaptcha.php:416
 
 
 
 
 
 
 
 
 
 
335
  msgid ""
336
- "reCAPTCHA will only show when Akismet identifies a comment as spam. Highly "
337
- "recommended if you do not want to force your visitors to type the captcha "
338
  "every time."
339
  msgstr ""
340
  "reCAPTCHA wird nur angezeigt, wenn Akismet einen Kommentar als Spam "
341
  "identifiziert. Höchstens empfohlen, wenn Sie ihre echten Besucher nicht "
342
  "immer mit einer CAPTCHA Eingabe nerven wollen."
343
 
344
- #: includes/class-bwp-recaptcha.php:417
345
- msgid "uncheck to use different key pairs for this site."
 
 
 
 
 
346
  msgstr ""
347
- "abwählen, wenn Sie verschiedene Schlüsselpaare für diese Seite nutzen wollen."
348
 
349
- #: includes/class-bwp-recaptcha.php:420
350
- msgid "A public key used to request captchas from reCAPTCHA server."
351
- msgstr "Der Public Key wird genutzt, um CAPTCHAS vom Server zu laden."
352
 
353
- #: includes/class-bwp-recaptcha.php:421
354
- msgid "A private (secret) key used to authenticate user's response."
355
- msgstr ""
356
- "Der Private Key (Secret) wird genutzt, um die Antwort der Besucher zu "
357
- "authentifizieren."
358
 
359
- #: includes/class-bwp-recaptcha.php:422
360
  msgid ""
361
- "when redirect commenter back to the comment form (or when used in other "
362
- "forms such as contact forms)."
363
  msgstr ""
364
- "wenn der Kommentator zum Kommentarfeld weitergeleitet wird (oder wenn das "
365
- "reCAPTCHA Modul in andern Beriechen, wie Kontaktformen genutzt wird)."
366
-
367
- #: includes/class-bwp-recaptcha.php:423
368
- msgid "when show the normal error page with no redirection."
369
- msgstr "wenn die normale Fehlerseite (ohne Weiterleitung) angezeigt wird."
370
-
371
- #: includes/class-bwp-recaptcha.php:424
372
- msgid "approved comment(s)."
373
- msgstr "genehmigte(n) Kommentar(e) aufweisen."
374
 
375
- #: includes/class-bwp-recaptcha.php:427
 
376
  msgid ""
377
- "<em><strong>Note:</strong> For this plugin to work, you will need a pair of "
378
- "API keys (public and private), which is available for free <a href=\"https://"
379
- "www.google.com/recaptcha/admin/create\" target=\"_blank\">here</a>. Once you "
380
- "have created those two keys for this domain, simply paste them below.</em>"
381
  msgstr ""
382
- "<em><strong>Beachte:</strong> Damit dieses Plugin funktioniert, werden zwei "
383
- "API Schlüssel (Public und Private), welche Sie kostenlos <a href=\"https://"
384
- "www.google.com/recaptcha/admin/create\" target=\"_blank\">hier</a> "
385
- "erhältlich sind. Nachdem Sie diese zwei Schlüssel generiert haben, fügen Sie "
386
- "diese in die zwei folgenden Felder ein.</em>"
387
 
388
- #: includes/class-bwp-recaptcha.php:428
389
- msgid ""
390
- "<em><strong>Note:</strong> Now you may wonder, why put the comment in the "
391
- "spam queue? The benefit is Akismet will be able to mark the comment as False "
392
- "Positive, and thus will not possibly block that comment in the future. "
393
- "However, it is best to just put the comment in moderation queue as next time "
394
- "Akismet will put such comment in moderation queue immediately without the "
395
- "need of a CAPTCHA.</em>"
396
- msgstr ""
397
- "<em><strong>Beachte:</strong> Jetzt fragen Sie sich vielleicht, wieso die "
398
- "Kommentar in den Spam-Warteschlange verschoben werden solln? Der Vorteil von "
399
- "Akismet ist, dass es in der Lage ist, Kommentar als kein Spam zu markieren "
400
- "und folgende Kommentare werden nicht mehr geblockt. Jedoch ist es das beste, "
401
- "Kommentare in die Moderationswarteschlange zu verschieben, da Akisment beim "
402
- "nächstmal dies automtisch erledigt, ohne das wieder ein CAPTCHA ausgefüllt "
403
- "werden muss.</em>"
404
-
405
- #: includes/class-bwp-recaptcha.php:457
406
- msgid "Choose a theme"
407
- msgstr "Wähle ein Design"
408
-
409
- #: includes/class-bwp-recaptcha.php:458
410
- msgid "Use CSS provided by this plugin?"
411
- msgstr "Nutze den vom Plugin zu Verfügung gestellten CSS Style?"
412
 
413
- #: includes/class-bwp-recaptcha.php:459
414
- msgid "Load CSS, JS selectively?"
415
- msgstr "Lade CSS, JavaScript selektiv?"
 
 
416
 
417
- #: includes/class-bwp-recaptcha.php:460
418
- msgid "Choose a language for built-in themes"
419
- msgstr "Wählen Sie eine Sprache für die Standard Designs"
 
 
420
 
421
- #: includes/class-bwp-recaptcha.php:461
422
- msgid "Tabindex for captcha input field"
423
- msgstr "Tabindex für Captcha-Eingabefeld"
 
424
 
425
- #: includes/class-bwp-recaptcha.php:462
426
- msgid "Preview your reCAPTCHA"
427
- msgstr "Vorschau Ihre reCAPTCHA Form"
 
428
 
429
- #: includes/class-bwp-recaptcha.php:466
430
  msgid ""
431
- "<em>Below you will see how your reCAPTCHA will look. Note that this might "
432
- "differ on your actual pages.<br /></em>"
 
 
433
  msgstr ""
434
- "<em>Unterhalb sehen Sie, wie Ihre reCAPCHTA Form aussehen wird. Beachten Sie "
435
- "jedoch, dass das Aussehen auf Ihrer eigentlichen Seite abweichen kann.<br /"
436
- "></em>"
437
 
438
- #: includes/class-bwp-recaptcha.php:470
439
- msgid "Default Theme (Red)"
440
- msgstr "Standard (rot)"
441
 
442
- #: includes/class-bwp-recaptcha.php:471
443
- msgid "White Theme"
444
- msgstr "Weiß"
445
 
446
- #: includes/class-bwp-recaptcha.php:472
447
- msgid "Black Theme"
448
- msgstr "Schwarz"
449
 
450
- #: includes/class-bwp-recaptcha.php:473
451
- msgid "Clean Theme"
452
- msgstr "Schlicht"
453
 
454
- #: includes/class-bwp-recaptcha.php:474
455
- msgid "Custom Theme (use CSS)"
456
- msgstr "Eigenes Design (mit CSS)"
457
 
458
- #: includes/class-bwp-recaptcha.php:479
459
- msgid ""
460
- "This stylesheet is used to style the custom theme as well as the "
461
- "registration page. You can disable this or add appropriate filters to use "
462
- "your own."
463
  msgstr ""
464
- "Dieses Stylesheet wird dazu genutzt, dass eigen erstellte Design und die "
465
- "Registrierungsseite zu stylen. Sie können diese deaktivieren oder einen "
466
- "Verweis auf Ihr eigenes Stylesheet festlegen."
467
 
468
- #: includes/class-bwp-recaptcha.php:480
469
- msgid "This is only useful when you do not use any minify or cache plugin."
 
470
  msgstr ""
471
- "Das ist nur nützlich, wenn Sie keine Cache oder Code-Minify Plugins nutzen."
 
472
 
473
- #: includes/class-bwp-recaptcha.php:483
474
- msgid ""
475
- "Basically, this should be 4 if you place the captcha before the textarea, "
476
- "and 5 if you put it after. Set to 0 to disable."
477
  msgstr ""
478
- "Grundsätzlich sollte dies bei 4 belassen werden, wenn Sie das Captcha vor "
479
- "dem Textbereich setzen wollen, und 5, sollten Sie es danach setzen wollen. "
480
- "Der Wert 0 deaktiviert dies."
481
 
482
- #: includes/class-bwp-recaptcha.php:486
483
- #, php-format
484
- msgid ""
485
- "<em><strong>Note:</strong> The four built-in captcha themes will look OK in "
486
- "most WordPress themes; However, some times it is better to control how "
487
- "reCAPTCHA looks using CSS. Please read <a href=\"%s#customization\" target="
488
- "\"_blank\">this guide</a> if you would like to do so.</em>"
489
- msgstr ""
490
- "<em><strong>Beachte:</strong> Die vier eingebauten reCAPTCHA Designs passen "
491
- "in den meisten WordPress Themes. Jedoch ist es manchmal besser, das Aussehen "
492
- "per CSS zu ändern. Lesen Sie dazu diese <a href=\"%s#customization\" target="
493
- "\"_blank\">Anleitung</a>, wenn Sie das Design individuell anpassen wollen.</"
494
- "em>"
495
-
496
- #: includes/class-bwp-recaptcha.php:487
497
- #, php-format
498
  msgid ""
499
- "<em><strong>Note:</strong> Above you can select some built-in languages. If "
500
- "you would like to add your own language, please read <a href="
501
- "\"%s#customization\" target=\"_blank\">this guide</a>.</em>"
502
  msgstr ""
503
- "<em><strong>Beachte:</strong> Oben können Sie einige eingebaute Sprachen "
504
- "wählen. Wenn Sie Ihre eigene Sprache hinzufügen wollen lesen Sie bitte diese "
505
- "<a href=\"%s#customization\" target=\"_blank\">Anleitung</a>.</em>"
506
 
507
- #: includes/class-bwp-recaptcha.php:540
508
- msgid "All options have been saved."
509
- msgstr "Alle Optionen wurden erfolgreich gespeichert."
 
 
 
 
510
 
511
- #: includes/class-bwp-recaptcha.php:546
512
  msgid "Warning"
513
  msgstr "Warnung"
514
 
515
- #: includes/class-bwp-recaptcha.php:546
516
- msgid ""
517
- "API key(s) missing. Please get an API key from <a href='https://www.google."
518
- "com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</"
519
- "a> (free!)"
520
- msgstr ""
521
- "API Schlüssel(s) fehlen. Bitte generieren Sie einen API Schlüssel von <a "
522
- "href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/"
523
- "recaptcha/admin/create</a> (Kostenlos!)"
524
-
525
- #: includes/class-bwp-recaptcha.php:548
526
- msgid "Notice"
527
- msgstr "Beachte"
528
 
529
- #: includes/class-bwp-recaptcha.php:548
530
  msgid ""
531
  "You are enabling Akismet integration but Akismet is not currently active. "
532
  "Please activate Akismet for the integration to work."
@@ -535,70 +641,268 @@ msgstr ""
535
  "installiert oder aktiviert zu haben. Bitte installieren oder aktivieren Sie "
536
  "Akisment zuerst."
537
 
538
- #: includes/class-bwp-recaptcha.php:671
 
 
 
 
 
 
 
 
 
 
 
 
539
  msgid "Your comment was identified as spam, please complete the CAPTCHA below:"
540
  msgstr ""
541
  "Ihr Kommentar wurde als Spam identifiziert, sollte das falsch sein, füllen "
542
  "Sie biete folgendes CAPTCHA richtig aus:"
543
 
544
- #: includes/class-bwp-recaptcha.php:714
545
- msgid ""
546
- "To use reCAPTCHA you must get an API key from <a href='https://www.google."
547
- "com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>"
 
 
 
548
  msgstr ""
549
- "Um reCAPTCHA nutzen zu können, benötigen Sie zwei API Schlüssel von <a "
550
- "href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/"
551
- "recaptcha/admin/create</a>"
552
 
553
- #: includes/class-bwp-recaptcha.php:763 includes/class-bwp-recaptcha.php:808
554
- msgid "<strong>ERROR</strong>: Unknown captcha error."
555
- msgstr "<strong>FEHLER</strong>: Unbekannter reCAPTCHA fehler."
 
 
 
 
 
556
 
557
- #: includes/class-bwp-recaptcha.php:878
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
558
  msgid "this link"
559
  msgstr "dieser Link"
560
 
561
- #: includes/class-bwp-recaptcha.php:880
562
- msgid ""
563
- "There is some problem with your reCAPTCHA API keys, please double check them."
564
- msgstr ""
565
- "Es gibt ein Problem mit Ihrem reCAPTCHA API-Schlüssel, bitte überprüfen Sie "
566
- "diese nochmals."
567
 
568
- #: includes/class-bwp-recaptcha.php:882
569
- msgid "Unknown error. Please contact the administrator for more info."
570
- msgstr ""
571
- "Unbekannter Fehler. Kontaktieren Sie bitte den Admin um mehr Informationen "
572
- "zu erhalten."
573
 
574
- #: includes/class-bwp-recaptcha-cf7.php:107
575
- msgid "This reCAPTCHA tag is provided by the BWP reCAPTCHA WordPress plugin."
576
- msgstr ""
577
- "Diese reCPATCHA Form wird von BWP reCAPTCHA WordPress Plugins bereitgestellt."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
578
 
579
- #: includes/class-bwp-recaptcha-cf7.php:110
580
- msgid ""
581
- "Please refer to <a target=\"_blank\" href=\"http://betterwp.net/wordpress-"
582
- "plugins/bwp-recaptcha/#customization\">BWP reCAPTCHA's documentation </a> "
583
- "for a quick guide on how to customize the look and feel of this tag."
584
- msgstr ""
585
- "Bitte besuchen Sie <a target=\"_blank\" href=\"http://betterwp.net/wordpress-"
586
- "plugins/bwp-recaptcha/#customization\">BWP reCAPTCHA's Dokumentationen </a> "
587
- "für eine kurze Anleitung, wie Sie das Aussehen und Verhalten bearbeiten "
588
- "können."
589
 
590
- #: includes/class-bwp-recaptcha-cf7.php:116
591
- msgid "Name"
592
- msgstr "Name"
593
 
594
- #: includes/class-bwp-recaptcha-cf7.php:123
595
- msgid "Copy this code and paste it into the form left."
596
- msgstr "Kopieren Sie diesen Code und fügen Sie diesen in der Form links ein."
597
 
598
- #: includes/bwp-option-page/includes/class-bwp-option-page.php:80
599
- msgid "Plugin Configurations"
600
- msgstr "Plugin Konfiguration"
 
 
 
 
 
 
 
601
 
602
- #: includes/bwp-option-page/includes/class-bwp-option-page.php:398
603
- msgid "Save Changes"
604
- msgstr "Speichere Änderungen"
 
 
 
 
 
 
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: BWP reCAPTCHA\n"
4
+ "Report-Msgid-Bugs-To: contact@betterwp.net\n"
5
+ "POT-Creation-Date: 2016-01-12 23:47+0700\n"
6
+ "PO-Revision-Date: 2016-01-12 15:22+0700\n"
7
  "Last-Translator: Andreas Reitberger <andy.reitberger@gmail.com>\n"
8
  "Language-Team: wdbase.de <kontakt@wdbase.de>\n"
9
  "Language: de_DE\n"
13
  "X-Poedit-KeywordsList: _;gettext;gettext_noop;__;_e\n"
14
  "X-Poedit-Basepath: .\n"
15
  "X-Poedit-SourceCharset: UTF-8\n"
16
+ "X-Generator: Poedit 1.8.5\n"
17
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
18
  "X-Poedit-SearchPath-0: .\n"
19
 
20
+ #: vendor/kminh/bwp-framework/src/class-bwp-version.php:32
21
  #, php-format
22
  msgid ""
23
  "%s requires WordPress <strong>%s</strong> or higher and PHP <strong>%s</"
28
  "strong> oder höher. Das Plugin wird erst funktionieren, wenn Sie Ihre "
29
  "Software aktualisiert haben. Bitte deaktivieren Sie bis dahin das Plugin."
30
 
31
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:411
32
+ msgid "... or any amount!"
33
+ msgstr "... oder selbst Betrag wählen!"
34
 
35
+ #: includes/class-bwp-recaptcha.php:1006 includes/class-bwp-recaptcha.php:1101
36
+ #, fuzzy
37
+ msgid ""
38
+ "<em>Below you will see how your reCAPTCHA will look. Note that this might "
39
+ "differ on your actual pages.</em>"
40
+ msgstr ""
41
+ "<em>Unterhalb sehen Sie, wie Ihre reCAPCHTA Form aussehen wird. Beachten Sie "
42
+ "jedoch, dass das Aussehen auf Ihrer eigentlichen Seite abweichen kann.<br /"
43
+ "></em>"
44
 
45
+ #: includes/class-bwp-recaptcha.php:118
46
+ msgid ""
47
+ "<strong>ERROR:</strong> Incorrect or empty reCAPTCHA response, please try "
48
+ "again."
49
+ msgstr ""
50
+ "<strong>FEHLER:</strong> Falsche oder leere Antwort, bitte versuchen Sie es "
51
+ "nochmals."
52
 
53
+ #: includes/class-bwp-recaptcha.php:867
54
+ msgid "A private (secret) key used to authenticate user's response."
55
+ msgstr ""
56
+ "Der Private Key (Secret) wird genutzt, um die Antwort der Besucher zu "
57
+ "authentifizieren."
58
 
59
+ #: includes/class-bwp-recaptcha.php:861
60
+ msgid "A public key used to request captchas from reCAPTCHA server."
61
+ msgstr "Der Public Key wird genutzt, um CAPTCHAS vom Server zu laden."
62
 
63
+ #: includes/class-bwp-recaptcha.php:1193
64
+ #, php-format
65
  msgid ""
66
+ "API key(s) missing. Please get an API key from <a href=\"%1$s\">%1$s</a> "
67
+ "(free!)"
68
  msgstr ""
 
 
69
 
70
+ #: includes/provider/v1.php:165
71
+ msgid "About reCAPTCHA"
72
+ msgstr "Über reCAPTCHA"
73
 
74
+ #: includes/class-bwp-recaptcha.php:1021 includes/class-bwp-recaptcha.php:1123
75
+ msgid ""
76
+ "Add additional CSS rules to all recaptcha instances. You can edit them below."
77
+ msgstr ""
78
 
79
+ #: includes/class-bwp-recaptcha.php:756
80
+ msgid ""
81
+ "Add reCAPTCHA to Contact Form 7. This only works if you have Contact Form 7 "
82
+ "activated."
83
+ msgstr ""
84
 
85
+ #: includes/class-bwp-recaptcha.php:827
86
+ msgid ""
87
+ "Add the <code>recaptcha</code> shortcode tag to your Contact Form 7 forms."
88
+ msgstr ""
89
 
90
+ #: includes/class-bwp-recaptcha.php:773
91
+ #, fuzzy
92
+ msgid "After comment field"
93
+ msgstr "Kommentar unverzüglich freischalten"
94
 
95
+ #: includes/class-bwp-recaptcha.php:774
96
+ msgid "After form fields (name, email, website)"
97
+ msgstr ""
98
 
99
+ #: includes/class-bwp-recaptcha.php:819
100
+ msgid "After redirected, auto fill the comment field with previous comment."
101
+ msgstr ""
102
 
103
+ #: includes/class-bwp-recaptcha.php:708
104
+ #, fuzzy
105
+ msgid "Akismet Integration for comment form"
106
+ msgstr "Akisment Integration (betrifft nur den Kommentarbereich)"
107
 
108
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:438
109
+ msgid "All options have been saved."
110
+ msgstr "Alle Optionen wurden erfolgreich gespeichert."
111
 
112
+ #: includes/class-bwp-recaptcha.php:781
113
+ msgid "Approve comment immediately"
114
+ msgstr "Kommentar unverzüglich freischalten"
 
115
 
116
+ #: includes/class-bwp-recaptcha.php:636
117
+ msgid "Auto detected"
118
+ msgstr ""
119
 
120
+ #: includes/class-bwp-recaptcha.php:705
121
+ msgid "Auto fill comment field"
122
+ msgstr ""
123
 
124
+ #: includes/class-bwp-recaptcha.php:1114
125
+ msgid "Auto-detected"
126
+ msgstr ""
127
 
128
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:521
129
+ msgid "BWP Gems"
130
+ msgstr ""
131
 
132
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:531
133
+ msgid "BWP News"
134
+ msgstr ""
135
 
136
+ #: includes/class-bwp-recaptcha.php:595
137
+ msgid "BWP reCAPTCHA General Options"
138
+ msgstr "BWP reCAPTCHA Designeinstellungen"
139
 
140
+ #: includes/class-bwp-recaptcha.php:604
141
+ msgid "BWP reCAPTCHA Theme Options"
142
+ msgstr "BWP reCAPTCHA Designeinstellungen"
143
 
144
+ #: includes/class-bwp-recaptcha.php:585
145
+ msgid "Better WordPress reCAPTCHA"
146
+ msgstr "Better WordPress reCAPTCHA"
147
+
148
+ #: includes/class-bwp-recaptcha.php:1013
149
+ msgid "Black Theme"
150
+ msgstr "Schwarz"
151
+
152
+ #: includes/class-bwp-recaptcha.php:703
153
+ msgid "Captcha position"
154
  msgstr ""
 
 
155
 
156
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:439
157
+ msgid "Check out this cool plugin"
158
+ msgstr ""
159
+
160
+ #: includes/class-bwp-recaptcha.php:1014
161
+ msgid "Clean Theme"
162
+ msgstr "Schlicht"
163
+
164
+ #: includes/class-bwp-recaptcha.php:787
165
+ msgid "Comment form"
166
+ msgstr ""
167
+
168
+ #: includes/class-bwp-recaptcha.php:1111
169
+ msgid "Compact"
170
+ msgstr ""
171
+
172
+ #: includes/class-bwp-recaptcha.php:711
173
+ msgid "Contact Form 7 Integration"
174
+ msgstr ""
175
+
176
+ #: includes/addons/contact-form-7/captcha-shortcode.php:205
177
+ msgid "Copy this code and paste it into the form left."
178
+ msgstr "Kopieren Sie diesen Code und fügen Sie diesen in der Form links ein."
179
+
180
+ #: includes/class-bwp-recaptcha.php:1015
181
+ msgid "Custom Theme (use CSS)"
182
+ msgstr "Eigenes Design (mit CSS)"
183
+
184
+ #: includes/class-bwp-recaptcha.php:1107
185
+ msgid "Dark"
186
+ msgstr ""
187
+
188
+ #: includes/class-bwp-recaptcha.php:1011
189
+ msgid "Default Theme (Red)"
190
+ msgstr "Standard (rot)"
191
+
192
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:1530
193
+ msgid "Dismiss this notice."
194
+ msgstr ""
195
+
196
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:405
197
+ #, php-format
198
+ msgid "Donate to %s"
199
+ msgstr "Spende an %s"
200
+
201
+ #: includes/class-bwp-recaptcha.php:992 includes/class-bwp-recaptcha.php:1087
202
+ msgid "Enable custom CSS"
203
+ msgstr ""
204
+
205
+ #: includes/class-bwp-recaptcha.php:700
206
+ #, fuzzy
207
+ msgid "Enable this plugin for"
208
+ msgstr "für die Anmeldung (Login) aktiviert."
209
+
210
+ #: includes/class-bwp-recaptcha.php:120
211
  #, php-format
212
  msgid ""
213
  "Error: Incorrect or empty reCAPTCHA response, please click the back button "
216
  "Fehler: Falsche oder leere Antwort, bitte klicken Sie auf den Zurück-Button "
217
  "in Ihrem Browser oder klicken Sie %s um zurück zu gehen."
218
 
219
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:371
220
+ msgid "FAQ"
221
+ msgstr "FAQ"
222
+
223
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:409
224
+ msgid "Five cups! $25.00"
225
+ msgstr "Fünf Tassen! $25.00"
226
+
227
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:548
228
+ msgid "Follow"
229
+ msgstr ""
230
+
231
+ #: includes/class-bwp-recaptcha.php:744
232
+ #, fuzzy, php-format
233
+ msgid ""
234
+ "For this plugin to work, you will need a pair of API keys, which is "
235
+ "available for free <a href=\"%s\" target=\"_blank\">here</a>. Once you have "
236
+ "created those two keys for the current domain, simply paste them below.</em>"
237
+ msgstr ""
238
+ "<em><strong>Beachte:</strong> Damit dieses Plugin funktioniert, werden zwei "
239
+ "API Schlüssel (Public und Private), welche Sie kostenlos <a href=\"https://"
240
+ "www.google.com/recaptcha/admin/create\" target=\"_blank\">hier</a> "
241
+ "erhältlich sind. Nachdem Sie diese zwei Schlüssel generiert haben, fügen Sie "
242
+ "diese in die zwei folgenden Felder ein.</em>"
243
+
244
+ #: includes/class-bwp-recaptcha.php:697
245
+ msgid "Force https"
246
+ msgstr ""
247
+
248
+ #: includes/class-bwp-recaptcha.php:159 includes/class-bwp-recaptcha.php:596
249
  msgid "General Options"
250
  msgstr "Allgemeine Einstellungen"
251
 
252
+ #: includes/provider/v1.php:162
253
+ msgid "Get another challenge"
254
+ msgstr "Neues reCAPTACHA abrufen"
255
 
256
+ #: includes/provider/v1.php:163
257
+ msgid "Get audio reCAPTCHA"
258
+ msgstr "Audio-reCAPTCHA abrufen"
259
 
260
+ #: includes/provider/v1.php:164
261
+ msgid "Get image reCAPTCHA"
262
+ msgstr "Bild-reCPATCHA abrufen"
263
 
264
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:374
265
+ msgid "Got a problem with this plugin? Please say it out loud!"
266
+ msgstr ""
267
 
268
+ #: includes/class-bwp-recaptcha.php:701
269
+ #, fuzzy
270
+ msgid "Hide captcha for"
271
+ msgstr "Verstecke das CAPTCHA für"
272
 
273
+ #: includes/class-bwp-recaptcha.php:782
274
+ msgid "Hold comment in moderation queue"
275
+ msgstr "Verschiebe den Kommentar in die Moderationswarteschlange"
276
 
277
+ #: includes/class-bwp-recaptcha.php:710
278
+ #, fuzzy
279
+ msgid "If correct captcha response"
280
+ msgstr "Bei richtiger CAPTCHA Antwort"
281
 
282
+ #: includes/class-bwp-recaptcha.php:704
283
+ #, fuzzy
284
+ msgid "If invalid captcha response"
285
+ msgstr "Bei falscher oder leerer Antwort"
286
 
287
+ #: includes/class-bwp-recaptcha.php:880
288
+ msgid ""
289
+ "If you encounter error such as <code>Unknown error (invalid-json)</code>when "
290
+ "submitting a form, try selecting a specific request method here."
291
+ msgstr ""
292
 
293
+ #: includes/class-bwp-recaptcha.php:1054
294
+ #, php-format
295
+ msgid ""
296
+ "If you want to add custom translations, please read <a href=\"%s\" target="
297
+ "\"_blank\">this tip</a>."
298
+ msgstr ""
299
 
300
+ #: includes/class-bwp-recaptcha.php:1207
301
+ #, php-format
302
+ msgid ""
303
+ "In order to use the nocaptcha recaptcha (recaptcha v2), you need at least "
304
+ "<strong>PHP 5.3.2</strong> (your current PHP version is <strong>%s</"
305
+ "strong>), so only recaptcha v1 can be used. It is recommended to contact "
306
+ "your host to know how to update your current version of PHP."
307
+ msgstr ""
308
 
309
+ #: includes/class-bwp-recaptcha.php:125
310
+ #, fuzzy
311
+ msgid "Incorrect or empty reCAPTCHA response, please try again."
312
+ msgstr ""
313
+ "<strong>FEHLER:</strong> Falsche oder leere Antwort, bitte versuchen Sie es "
314
+ "nochmals."
315
 
316
+ #: includes/addons/contact-form-7/captcha-shortcode.php:170
317
+ msgid "Insert Tag"
318
+ msgstr ""
319
 
320
+ #: includes/class-bwp-recaptcha.php:753
321
+ msgid "Integrate the comment form with Akismet for better end-user experience."
322
+ msgstr ""
323
 
324
+ #: includes/class-bwp-recaptcha.php:709
325
+ #, fuzzy
326
+ msgid "Integrate with Akismet"
327
+ msgstr "Soll Akisment integriert werden?"
328
 
329
+ #: includes/class-bwp-recaptcha.php:712
330
+ #, fuzzy
331
+ msgid "Integrate with Contact Form 7"
332
+ msgstr "Soll Akisment integriert werden?"
333
 
334
+ #: includes/class-bwp-recaptcha.php:706 includes/class-bwp-recaptcha.php:707
335
+ #: includes/class-bwp-recaptcha.php:714
336
+ #, fuzzy
337
+ msgid "Invalid captcha error message"
338
+ msgstr "Zeige diese Fehlernachricht,"
339
 
340
+ #: includes/class-bwp-recaptcha.php:886
341
+ msgid ""
342
+ "It is best to put comments identified as spam in moderation queue so you are "
343
+ "able to review and instruct Akismet to correctly handle similar comments in "
344
+ "the future."
345
+ msgstr ""
346
 
347
+ #: includes/class-bwp-recaptcha.php:1088
348
+ msgid "Language"
349
+ msgstr ""
350
 
351
+ #: includes/class-bwp-recaptcha.php:993
352
+ #, fuzzy
353
+ msgid "Language for built-in themes"
354
+ msgstr "Wählen Sie eine Sprache für die Standard Designs"
355
 
356
+ #: includes/class-bwp-recaptcha.php:1106
357
+ msgid "Light"
358
+ msgstr ""
359
 
360
+ #: includes/class-bwp-recaptcha.php:793
361
+ msgid "Login form"
362
+ msgstr ""
363
 
364
+ #: includes/class-bwp-recaptcha.php:699
365
+ msgid "Main Functionality"
366
+ msgstr ""
367
 
368
+ #: includes/class-bwp-recaptcha.php:816
369
+ msgid "Make requests to recaptcha server always secured."
370
+ msgstr ""
371
 
372
+ #: includes/class-bwp-recaptcha.php:317
373
+ msgid "Manage Options"
374
+ msgstr "Einstellungen bearbeiten"
375
 
376
+ #: includes/addons/contact-form-7/captcha-shortcode.php:159
377
+ #: includes/addons/contact-form-7/captcha-shortcode.php:196
378
+ msgid "Name"
379
+ msgstr "Name"
380
 
381
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:503
382
+ msgid "Need a highly customizable theme?"
383
+ msgstr ""
384
 
385
+ #: includes/class-bwp-recaptcha.php:1110
386
+ msgid "Normal"
 
 
 
387
  msgstr ""
 
 
 
 
388
 
389
+ #: includes/class-bwp-recaptcha.php:1205 includes/class-bwp-recaptcha.php:1227
390
+ msgid "Notice"
391
+ msgstr "Beachte"
392
+
393
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:410
394
+ msgid "One LL-cup!!! $50.00"
395
+ msgstr "Eine riesen Tasse!!! $50.00"
396
+
397
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:407
398
+ msgid "One cup $5.00"
399
+ msgstr "Eine Tasse $5.00"
400
+
401
+ #: includes/addons/contact-form-7/captcha-shortcode.php:225
402
+ #, fuzzy, php-format
403
  msgid ""
404
+ "Please refer to <a target=\"_blank\" href=\"%s\">BWP reCAPTCHA's "
405
+ "documentation</a> for a quick guide on how to customize the look and feel of "
406
+ "this tag."
407
  msgstr ""
408
+ "Bitte besuchen Sie <a target=\"_blank\" href=\"http://betterwp.net/wordpress-"
409
+ "plugins/bwp-recaptcha/#customization\">BWP reCAPTCHA's Dokumentationen </a> "
410
+ "für eine kurze Anleitung, wie Sie das Aussehen und Verhalten bearbeiten "
411
+ "können."
412
 
413
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:93
414
+ msgid "Plugin Configurations"
415
+ msgstr "Plugin Konfiguration"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
416
 
417
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:375
418
+ msgid "Plugin Support"
419
+ msgstr ""
420
 
421
+ #: includes/class-bwp-recaptcha.php:995 includes/class-bwp-recaptcha.php:1090
422
+ msgid "Preview your reCAPTCHA"
423
+ msgstr "Vorschau Ihre reCAPTCHA Form"
424
 
425
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:378
426
+ msgid "Rate this plugin 5 stars if you like it, thank you!"
427
+ msgstr ""
428
 
429
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:379
430
+ msgid "Rate this plugin 5 stars!"
431
+ msgstr ""
432
 
433
+ #: includes/class-bwp-recaptcha.php:1045
434
+ #, php-format
435
+ msgid ""
436
+ "Read <a href=\"%s#recaptcha-version-1\" target=\"_blank\">here</a> to know "
437
+ "how to use your own CSS for the Custom Theme."
438
+ msgstr ""
439
+
440
+ #: includes/class-bwp-recaptcha.php:316
441
+ msgid "Read Profile"
442
+ msgstr "Profil lesen"
443
 
444
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:370
445
+ msgid "Read this first before asking any question!"
446
+ msgstr ""
447
+
448
+ #: includes/class-bwp-recaptcha.php:777
449
+ #, fuzzy
450
+ msgid "Redirect commenter back to the comment form with error message"
451
+ msgstr "Leite den Kommentator zurück zum Kommentar Bereich"
452
+
453
+ #: includes/class-bwp-recaptcha.php:790
454
+ #, fuzzy
455
+ msgid "Registration form (user/site registration)"
456
  msgstr "für die Registrierung aktiviert (Mitglied/Seiten Registrierung)."
457
 
458
+ #: includes/class-bwp-recaptcha.php:698
459
+ msgid "Request method"
460
+ msgstr ""
461
 
462
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:305
463
+ msgid "Save Changes"
464
+ msgstr "Speichere Änderungen"
465
 
466
+ #: includes/class-bwp-recaptcha.php:694
467
+ msgid "Secret Key"
468
+ msgstr ""
469
 
470
+ #: includes/class-bwp-recaptcha.php:1129
471
+ msgid "Set to 0 to disable."
472
+ msgstr ""
473
+
474
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:1315
475
+ msgid "Settings"
476
+ msgstr "Einstellungen"
477
+
478
+ #: includes/class-bwp-recaptcha.php:751
479
+ #, fuzzy
480
+ msgid "Settings that are applied to comment forms only."
481
+ msgstr "Akisment Integration (betrifft nur den Kommentarbereich)"
482
 
483
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:431
484
+ #, fuzzy
485
+ msgid "Share the love for this plugin!"
486
+ msgstr "Nutze den vom Plugin zu Verfügung gestellten CSS Style?"
487
+
488
+ #: includes/class-bwp-recaptcha.php:778
489
+ msgid "Show an error page just like WordPress does"
490
+ msgstr "Zeige eine Fehlerseite, so wie es WordPress tut"
491
+
492
+ #: includes/class-bwp-recaptcha.php:805
493
+ #, fuzzy
494
  msgid ""
495
+ "Show captcha only when Akismet identifies a comment as spam. Highly "
496
+ "recommended if you do not want to force your visitors to enter a captcha "
497
  "every time."
498
  msgstr ""
499
  "reCAPTCHA wird nur angezeigt, wenn Akismet einen Kommentar als Spam "
500
  "identifiziert. Höchstens empfohlen, wenn Sie ihre echten Besucher nicht "
501
  "immer mit einer CAPTCHA Eingabe nerven wollen."
502
 
503
+ #: includes/class-bwp-recaptcha.php:693
504
+ #, fuzzy
505
+ msgid "Site Key"
506
+ msgstr "Private Key"
507
+
508
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:541
509
+ msgid "Subscribe"
510
  msgstr ""
 
511
 
512
+ #: includes/class-bwp-recaptcha.php:994 includes/class-bwp-recaptcha.php:1089
513
+ msgid "Tabindex for captcha input field"
514
+ msgstr "Tabindex für Captcha-Eingabefeld"
515
 
516
+ #: includes/class-bwp-recaptcha.php:162 includes/class-bwp-recaptcha.php:605
517
+ msgid "Theme Options"
518
+ msgstr "Designeinstellungen"
 
 
519
 
520
+ #: includes/provider/abstract-provider.php:103
521
  msgid ""
522
+ "There is some problem with your reCAPTCHA API keys, please double check them."
 
523
  msgstr ""
524
+ "Es gibt ein Problem mit Ihrem reCAPTCHA API-Schlüssel, bitte überprüfen Sie "
525
+ "diese nochmals."
 
 
 
 
 
 
 
 
526
 
527
+ #: includes/class-bwp-recaptcha.php:754 includes/class-bwp-recaptcha.php:822
528
+ #, php-format
529
  msgid ""
530
+ "This feature requires an active <a target=\"_blank\" href=\"%s\">PHP "
531
+ "session</a>."
 
 
532
  msgstr ""
 
 
 
 
 
533
 
534
+ #: includes/class-bwp-recaptcha.php:897
535
+ msgid "This is shown on the standard WordPress error page."
536
+ msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
537
 
538
+ #: includes/class-bwp-recaptcha.php:892
539
+ #, fuzzy
540
+ msgid ""
541
+ "This is shown when the commenter is redirected back to the comment form."
542
+ msgstr "Leite den Kommentator zurück zum Kommentar Bereich"
543
 
544
+ #: includes/class-bwp-recaptcha.php:905
545
+ msgid ""
546
+ "This message is shown when invalid captcha response is treated as a standard "
547
+ "validation error. Leave blank to not use."
548
+ msgstr ""
549
 
550
+ #: includes/addons/contact-form-7/captcha-shortcode.php:220
551
+ msgid "This reCAPTCHA tag is provided by the BWP reCAPTCHA WordPress plugin."
552
+ msgstr ""
553
+ "Diese reCPATCHA Form wird von BWP reCAPTCHA WordPress Plugins bereitgestellt."
554
 
555
+ #: includes/provider/v1.php:96
556
+ #, php-format
557
+ msgid "To use reCAPTCHA you must get an API key from <a href=\"%1$s\">%1$s</a>"
558
+ msgstr ""
559
 
560
+ #: includes/class-bwp-recaptcha.php:873
561
  msgid ""
562
+ "To verify a captcha response, this plugin needs to send requests to the "
563
+ "reCAPTCHA server, using a specific request method. <br /><br />By default, "
564
+ "BWP reCAPTCHA use the first available request method, be it Socket "
565
+ "(<code>fsockopen</code>), cURL, or <code>file_get_contents</code>."
566
  msgstr ""
 
 
 
567
 
568
+ #: includes/class-bwp-recaptcha.php:713
569
+ msgid "Treat invalid captcha as spam"
570
+ msgstr ""
571
 
572
+ #: includes/class-bwp-recaptcha.php:830
573
+ msgid "Treat invalid captcha response as spam instead of validation error"
574
+ msgstr ""
575
 
576
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:408
577
+ msgid "Two cups $10.00"
578
+ msgstr "Zwei Tassen $10.00"
579
 
580
+ #: includes/provider/v1.php:170
581
+ msgid "Type what you hear"
582
+ msgstr ""
583
 
584
+ #: includes/provider/v1.php:169
585
+ msgid "Type what you see"
586
+ msgstr ""
587
 
588
+ #: includes/class-bwp-recaptcha.php:810
589
+ #, fuzzy
590
+ msgid "Uncheck to use different key pairs for this site."
 
 
591
  msgstr ""
592
+ "abwählen, wenn Sie verschiedene Schlüsselpaare für diese Seite nutzen wollen."
 
 
593
 
594
+ #: includes/provider/abstract-provider.php:107
595
+ #, fuzzy, php-format
596
+ msgid "Unknown error (%s). Please contact an administrator for more info."
597
  msgstr ""
598
+ "Unbekannter Fehler. Kontaktieren Sie bitte den Admin um mehr Informationen "
599
+ "zu erhalten."
600
 
601
+ #: includes/class-bwp-recaptcha.php:991
602
+ msgid "Use default CSS"
 
 
603
  msgstr ""
 
 
 
604
 
605
+ #: includes/class-bwp-recaptcha.php:692
606
+ msgid "Use main site's keys"
607
+ msgstr "Nutze die Schlüssel der Hauptseite"
608
+
609
+ #: includes/class-bwp-recaptcha.php:696
610
+ #, fuzzy
611
+ msgid "Use reCAPTCHA version 1"
612
+ msgstr "BWP reCAPTCHA Designeinstellungen"
613
+
614
+ #: includes/class-bwp-recaptcha.php:813
 
 
 
 
 
 
615
  msgid ""
616
+ "Use the oldschool recaptcha instead of the new <em>nocaptcha</em> recaptcha."
 
 
617
  msgstr ""
 
 
 
618
 
619
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:416
620
+ msgid "Via"
621
+ msgstr ""
622
+
623
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:827
624
+ msgid "View more info in a separate tab"
625
+ msgstr ""
626
 
627
+ #: includes/class-bwp-recaptcha.php:1192
628
  msgid "Warning"
629
  msgstr "Warnung"
630
 
631
+ #: includes/class-bwp-recaptcha.php:1012
632
+ msgid "White Theme"
633
+ msgstr "Weiß"
 
 
 
 
 
 
 
 
 
 
634
 
635
+ #: includes/class-bwp-recaptcha.php:1228
636
  msgid ""
637
  "You are enabling Akismet integration but Akismet is not currently active. "
638
  "Please activate Akismet for the integration to work."
641
  "installiert oder aktiviert zu haben. Bitte installieren oder aktivieren Sie "
642
  "Akisment zuerst."
643
 
644
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:565
645
+ #, php-format
646
+ msgid "You are using version %s!"
647
+ msgstr "Sie benutzen aktuell die Version %s!"
648
+
649
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:391
650
+ msgid ""
651
+ "You can buy me some special coffees if you appreciate my work, thank you!"
652
+ msgstr ""
653
+ "Sie können mir einen speziellen Kaffe spendieren, wenn Ihnen meine Arbeit "
654
+ "gefällt. Vielen Dank!"
655
+
656
+ #: includes/class-bwp-recaptcha.php:1376
657
  msgid "Your comment was identified as spam, please complete the CAPTCHA below:"
658
  msgstr ""
659
  "Ihr Kommentar wurde als Spam identifiziert, sollte das falsch sein, füllen "
660
  "Sie biete folgendes CAPTCHA richtig aus:"
661
 
662
+ #: includes/class-bwp-recaptcha.php:848
663
+ msgid "approved comment(s)."
664
+ msgstr "genehmigte(n) Kommentar(e) aufweisen."
665
+
666
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:524
667
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:534
668
+ msgid "loading..."
669
  msgstr ""
 
 
 
670
 
671
+ #: includes/class-bwp-recaptcha.php:691
672
+ msgid "reCAPTCHA API Keys"
673
+ msgstr ""
674
+
675
+ #: includes/class-bwp-recaptcha.php:695
676
+ #, fuzzy
677
+ msgid "reCAPTCHA Settings"
678
+ msgstr "BWP reCAPTCHA Designeinstellungen"
679
 
680
+ #: includes/class-bwp-recaptcha.php:702
681
+ #, fuzzy
682
+ msgid "reCAPTCHA for comment form"
683
+ msgstr "für Kommentare aktiviert."
684
+
685
+ #: includes/class-bwp-recaptcha.php:1086
686
+ #, fuzzy
687
+ msgid "reCAPTCHA size"
688
+ msgstr "Über reCAPTCHA"
689
+
690
+ #: includes/class-bwp-recaptcha.php:990 includes/class-bwp-recaptcha.php:1085
691
+ #, fuzzy
692
+ msgid "reCAPTCHA theme"
693
+ msgstr "BWP reCAPTCHA Designeinstellungen"
694
+
695
+ #: includes/class-bwp-recaptcha.php:796
696
+ msgid "registered users <em>(even without any capabilities)</em>."
697
+ msgstr "Registrierte Mitglieder <em>(für alle, ohne Ausnahme)</em>."
698
+
699
+ #: includes/class-bwp-recaptcha.php:1554
700
  msgid "this link"
701
  msgstr "dieser Link"
702
 
703
+ #: includes/class-bwp-recaptcha.php:799
704
+ msgid "users who can"
705
+ msgstr "Mitglieder mit foglenden Rechten"
 
 
 
706
 
707
+ #: includes/class-bwp-recaptcha.php:802
708
+ msgid "visitors who have at least"
709
+ msgstr "Besucher, die mindestens"
 
 
710
 
711
+ #~ msgid ""
712
+ #~ "<em><strong>Note:</strong> Above you can select some built-in languages. "
713
+ #~ "If you would like to add your own language, please read <a href="
714
+ #~ "\"%s#customization\" target=\"_blank\">this guide</a>.</em>"
715
+ #~ msgstr ""
716
+ #~ "<em><strong>Beachte:</strong> Oben können Sie einige eingebaute Sprachen "
717
+ #~ "wählen. Wenn Sie Ihre eigene Sprache hinzufügen wollen lesen Sie bitte "
718
+ #~ "diese <a href=\"%s#customization\" target=\"_blank\">Anleitung</a>.</em>"
719
+
720
+ #~ msgid ""
721
+ #~ "<em><strong>Note:</strong> Now you may wonder, why put the comment in the "
722
+ #~ "spam queue? The benefit is Akismet will be able to mark the comment as "
723
+ #~ "False Positive, and thus will not possibly block that comment in the "
724
+ #~ "future. However, it is best to just put the comment in moderation queue "
725
+ #~ "as next time Akismet will put such comment in moderation queue "
726
+ #~ "immediately without the need of a CAPTCHA.</em>"
727
+ #~ msgstr ""
728
+ #~ "<em><strong>Beachte:</strong> Jetzt fragen Sie sich vielleicht, wieso die "
729
+ #~ "Kommentar in den Spam-Warteschlange verschoben werden solln? Der Vorteil "
730
+ #~ "von Akismet ist, dass es in der Lage ist, Kommentar als kein Spam zu "
731
+ #~ "markieren und folgende Kommentare werden nicht mehr geblockt. Jedoch ist "
732
+ #~ "es das beste, Kommentare in die Moderationswarteschlange zu verschieben, "
733
+ #~ "da Akisment beim nächstmal dies automtisch erledigt, ohne das wieder ein "
734
+ #~ "CAPTCHA ausgefüllt werden muss.</em>"
735
+
736
+ #~ msgid ""
737
+ #~ "<em><strong>Note:</strong> The four built-in captcha themes will look OK "
738
+ #~ "in most WordPress themes; However, some times it is better to control how "
739
+ #~ "reCAPTCHA looks using CSS. Please read <a href=\"%s#customization\" "
740
+ #~ "target=\"_blank\">this guide</a> if you would like to do so.</em>"
741
+ #~ msgstr ""
742
+ #~ "<em><strong>Beachte:</strong> Die vier eingebauten reCAPTCHA Designs "
743
+ #~ "passen in den meisten WordPress Themes. Jedoch ist es manchmal besser, "
744
+ #~ "das Aussehen per CSS zu ändern. Lesen Sie dazu diese <a href="
745
+ #~ "\"%s#customization\" target=\"_blank\">Anleitung</a>, wenn Sie das Design "
746
+ #~ "individuell anpassen wollen.</em>"
747
+
748
+ #~ msgid ""
749
+ #~ "<em>Integrate with Akismet for better end-user experience. reCAPTCHA is "
750
+ #~ "optional and <strong>NO</strong> spam comment will be added to the spam/"
751
+ #~ "moderation queue, except likely legitimate comments. This makes the task "
752
+ #~ "of identifying sincere comments much easier. This integration is "
753
+ #~ "currently in beta stage.</em>"
754
+ #~ msgstr ""
755
+ #~ "<em>Eine Integration mit Akismet verbessert die Endnutzer-Erfahrung. "
756
+ #~ "reCAPTCHA ist optional und <strong>kein</strong> Spam Kommentar wird zur "
757
+ #~ "Spam/Moderationswarteschlange, ausgenommen Kommentaren von echten "
758
+ #~ "Nutzern, hinzugefügt. Das erleichtert das identifizieren von richtigen "
759
+ #~ "Kommentaren viel einfacher. Diese Integration ist aktuell noch in der "
760
+ #~ "Beta-Phase.</em>"
761
+
762
+ #~ msgid ""
763
+ #~ "<em>This section allows you to determine when to show reCAPTCHA and how "
764
+ #~ "this plugin reacts to errors.</em>"
765
+ #~ msgstr ""
766
+ #~ "<em>Dieser Bereich erlaubt es Ihnen zu bestimmen, wo eine reCPATCHA Form "
767
+ #~ "angezeigt werden soll und wie deise bei einer falschen Eingabe reagieren "
768
+ #~ "soll.</em>"
769
+
770
+ #~ msgid "<strong>ERROR</strong>: Unknown captcha error."
771
+ #~ msgstr "<strong>FEHLER</strong>: Unbekannter reCAPTCHA fehler."
772
+
773
+ #~ msgid ""
774
+ #~ "API key(s) missing. Please get an API key from <a href='https://www."
775
+ #~ "google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/"
776
+ #~ "create</a> (free!)"
777
+ #~ msgstr ""
778
+ #~ "API Schlüssel(s) fehlen. Bitte generieren Sie einen API Schlüssel von <a "
779
+ #~ "href='https://www.google.com/recaptcha/admin/create'>https://www.google."
780
+ #~ "com/recaptcha/admin/create</a> (Kostenlos!)"
781
+
782
+ #~ msgid ""
783
+ #~ "Basically, this should be 4 if you place the captcha before the textarea, "
784
+ #~ "and 5 if you put it after. Set to 0 to disable."
785
+ #~ msgstr ""
786
+ #~ "Grundsätzlich sollte dies bei 4 belassen werden, wenn Sie das Captcha vor "
787
+ #~ "dem Textbereich setzen wollen, und 5, sollten Sie es danach setzen "
788
+ #~ "wollen. Der Wert 0 deaktiviert dies."
789
+
790
+ #~ msgid "Choose a theme"
791
+ #~ msgstr "Wähle ein Design"
792
+
793
+ #~ msgid "Contact"
794
+ #~ msgstr "Kontakt"
795
+
796
+ #~ msgid "Development Log"
797
+ #~ msgstr "Entwicklungslog"
798
+
799
+ #~ msgid "Dutch"
800
+ #~ msgstr "Holländisch"
801
+
802
+ #~ msgid "English"
803
+ #~ msgstr "Englisch"
804
+
805
+ #~ msgid "Enter the numbers you hear:"
806
+ #~ msgstr "Geben Sie die Nummer ein, die Sie hören:"
807
+
808
+ #~ msgid "Enter the two words in the box:"
809
+ #~ msgstr "Geben Sie die zwei Wörter hier ein:"
810
+
811
+ #~ msgid "Follow me on Twitter!"
812
+ #~ msgstr "Folgen Sie mir auf Twitter!"
813
+
814
+ #~ msgid "French"
815
+ #~ msgstr "Holländisch"
816
+
817
+ #~ msgid "Frequently Asked Questions"
818
+ #~ msgstr "Häufig gestellte Fragen"
819
+
820
+ #~ msgid "German"
821
+ #~ msgstr "Deutsch"
822
+
823
+ #~ msgid "Got a problem? Send me a feedback!"
824
+ #~ msgstr "Sie haben ein Problem? Senden Sie mir eine Rückmeldung!"
825
+
826
+ #~ msgid "Latest updates from BetterWP.net!"
827
+ #~ msgstr "Neusten Beiträge von BetterWP.net!"
828
+
829
+ #~ msgid "Load CSS, JS selectively?"
830
+ #~ msgstr "Lade CSS, JavaScript selektiv?"
831
+
832
+ #~ msgid "Portuguese"
833
+ #~ msgstr "Portugiesisch"
834
+
835
+ #~ msgid "Public Key"
836
+ #~ msgstr "Public Key"
837
+
838
+ #~ msgid "Put comment in spam queue"
839
+ #~ msgstr "Verschiebe den Kommentar in die Spam-Warteschlange"
840
+
841
+ #~ msgid "Russian"
842
+ #~ msgstr "Russisch"
843
+
844
+ #~ msgid "Spanish"
845
+ #~ msgstr "Spanisch"
846
+
847
+ #~ msgid "This Plugin is Proudly Sponsored By"
848
+ #~ msgstr "Dieses Plugin wird stolz gesponsert von"
849
+
850
+ #~ msgid "This is only useful when you do not use any minify or cache plugin."
851
+ #~ msgstr ""
852
+ #~ "Das ist nur nützlich, wenn Sie keine Cache oder Code-Minify Plugins "
853
+ #~ "nutzen."
854
+
855
+ #~ msgid "This plugin will be"
856
+ #~ msgstr "Dieses Plugin wird"
857
+
858
+ #~ msgid ""
859
+ #~ "This stylesheet is used to style the custom theme as well as the "
860
+ #~ "registration page. You can disable this or add appropriate filters to use "
861
+ #~ "your own."
862
+ #~ msgstr ""
863
+ #~ "Dieses Stylesheet wird dazu genutzt, dass eigen erstellte Design und die "
864
+ #~ "Registrierungsseite zu stylen. Sie können diese deaktivieren oder einen "
865
+ #~ "Verweis auf Ihr eigenes Stylesheet festlegen."
866
+
867
+ #~ msgid ""
868
+ #~ "To use reCAPTCHA you must get an API key from <a href='https://www.google."
869
+ #~ "com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/"
870
+ #~ "create</a>"
871
+ #~ msgstr ""
872
+ #~ "Um reCAPTCHA nutzen zu können, benötigen Sie zwei API Schlüssel von <a "
873
+ #~ "href='https://www.google.com/recaptcha/admin/create'>https://www.google."
874
+ #~ "com/recaptcha/admin/create</a>"
875
+
876
+ #~ msgid "Turkish"
877
+ #~ msgstr "Türkisch"
878
 
879
+ #~ msgid "Visibility Options (applied to comment forms)"
880
+ #~ msgstr "Sichtbarkeits-Einstellung (betrifft nur den Kommentarbereich)"
 
 
 
 
 
 
 
 
881
 
882
+ #~ msgid "What is reCAPTCHA?"
883
+ #~ msgstr "Was ist reCAPTACHA?"
 
884
 
885
+ #~ msgid "You do not have sufficient permissions to access this page."
886
+ #~ msgstr ""
887
+ #~ "Sie haben nicht ausreichend Berechtigungen um diese Seite zu öffnen."
888
 
889
+ #~ msgid ""
890
+ #~ "reCAPTCHA is a free CAPTCHA service that helps to digitize books, "
891
+ #~ "newspapers and old time radio shows. You can read more about reCAPTCHA <a "
892
+ #~ "href=\"http://www.google.com/recaptcha/learnmore\" target=\"_blank"
893
+ #~ "\">here</a>."
894
+ #~ msgstr ""
895
+ #~ "reCAPTCHA ist ein kostenloser CAPTCHA Service von Google, welcher hilft "
896
+ #~ "Bücher, Zeitungen und alte Radioshows zu digitalisieren. Mehr über "
897
+ #~ "reCAPTCHA könnt Ihr <a href=\"http://www.google.com/recaptcha/learnmore\" "
898
+ #~ "target=\"_blank\">hier</a> nachlesen."
899
 
900
+ #~ msgid ""
901
+ #~ "when redirect commenter back to the comment form (or when used in other "
902
+ #~ "forms such as contact forms)."
903
+ #~ msgstr ""
904
+ #~ "wenn der Kommentator zum Kommentarfeld weitergeleitet wird (oder wenn das "
905
+ #~ "reCAPTCHA Modul in andern Beriechen, wie Kontaktformen genutzt wird)."
906
+
907
+ #~ msgid "when show the normal error page with no redirection."
908
+ #~ msgstr "wenn die normale Fehlerseite (ohne Weiterleitung) angezeigt wird."
languages/bwp-recaptcha-es_ES.mo CHANGED
Binary file
languages/bwp-recaptcha-es_ES.po CHANGED
@@ -1,440 +1,893 @@
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: BWP reCAPTCHA\n"
4
- "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: 2011-09-25 13:43+0700\n"
6
- "PO-Revision-Date: 2011-09-25 14:48+0700\n"
7
  "Last-Translator: \n"
8
  "Language-Team: \n"
 
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
  "X-Poedit-KeywordsList: _;gettext;gettext_noop;__;_e\n"
13
  "X-Poedit-Basepath: .\n"
14
  "X-Poedit-SourceCharset: utf-8\n"
15
- "X-Poedit-Language: Spanish\n"
16
- "X-Poedit-Country: SPAIN\n"
17
  "X-Poedit-SearchPath-0: .\n"
18
 
19
- #: includes/class-bwp-framework.php:172
20
  #, php-format
21
- msgid "%s requires WordPress <strong>%s</strong> or higher and PHP <strong>%s</strong> or higher. The plugin will not function until you update your software. Please deactivate this plugin."
22
- msgstr "%s requiere WordPress <strong>%s</strong> o mayor y PHP <strong>%s</strong> o mayor. El plugin no funcionará hasta que actualice su software. Por favor desactive este plugin."
 
 
 
 
 
 
23
 
24
- #: includes/class-bwp-framework.php:183
25
- msgid "Development Log"
26
- msgstr "Desarrollo Entrar"
27
 
28
- #: includes/class-bwp-framework.php:183
29
- msgid "Frequently Asked Questions"
30
- msgstr "Preguntas más frecuentes"
 
 
 
 
 
31
 
32
- #: includes/class-bwp-framework.php:183
33
- msgid "FAQ"
34
- msgstr "FAQ"
 
 
 
 
35
 
36
- #: includes/class-bwp-framework.php:183
37
- msgid "Got a problem? Send me a feedback!"
38
- msgstr "Tienes un problema? Envíame un feedback!"
 
 
39
 
40
- #: includes/class-bwp-framework.php:183
41
- msgid "Contact"
42
- msgstr "contacto"
 
43
 
44
- #: includes/class-bwp-framework.php:190
45
- msgid "You can buy me some special coffees if you appreciate my work, thank you!"
46
- msgstr "Me puedes comprar una tazas de café si te gusta mi trabajo, gracias!"
 
 
 
47
 
48
- #: includes/class-bwp-framework.php:204
49
- msgid "Donate to "
50
- msgstr "donar a"
51
 
52
- #: includes/class-bwp-framework.php:206
53
- msgid "One cup $5.00"
54
- msgstr "Una taza de $ 5,00"
 
55
 
56
- #: includes/class-bwp-framework.php:207
57
- msgid "Two cups $10.00"
58
- msgstr "Dos tazas de $ 10.00"
 
 
59
 
60
- #: includes/class-bwp-framework.php:208
61
- msgid "Five cups! $25.00"
62
- msgstr "Cinco tazas! $ 25.00"
 
63
 
64
- #: includes/class-bwp-framework.php:209
65
- msgid "One LL-cup!!! $50.00"
66
- msgstr "Una taza de LL-! $ 50.00"
 
67
 
68
- #: includes/class-bwp-framework.php:210
69
- msgid "... or any amount!"
70
- msgstr "... o cualquier cantidad!"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
 
72
- #: includes/class-bwp-framework.php:225
73
- msgid "Latest updates from BetterWP.net!"
74
- msgstr "Actualizaciones más recientes de BetterWP.net!"
75
 
76
- #: includes/class-bwp-framework.php:226
77
- msgid "Follow me on Twitter!"
78
- msgstr "Sígueme en Twitter!"
79
 
80
- #: includes/class-bwp-framework.php:235
 
 
 
 
 
 
 
 
81
  #, php-format
82
- msgid "You are using version %s!"
83
- msgstr "Usted esta usando la versión %s!"
84
 
85
- #: includes/class-bwp-framework.php:372
86
- msgid "Settings"
87
- msgstr "Configuraciones"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
- #: includes/class-bwp-recaptcha.php:45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  msgid "Get another challenge"
91
  msgstr "Obtén un nuevo reto"
92
 
93
- #: includes/class-bwp-recaptcha.php:46
94
  msgid "Get audio reCAPTCHA"
95
  msgstr "Obtén un audio reCAPTCHA"
96
 
97
- #: includes/class-bwp-recaptcha.php:47
98
  msgid "Get image reCAPTCHA"
99
  msgstr "Obtén una imagen reCAPTCHA"
100
 
101
- #: includes/class-bwp-recaptcha.php:48
102
- msgid "About reCAPTCHA"
103
- msgstr "Acerca de reCAPTCHA"
104
 
105
- #: includes/class-bwp-recaptcha.php:52
106
- msgid "Enter the two words in the box:"
107
- msgstr "Escribe las 2 palabras:"
 
108
 
109
- #: includes/class-bwp-recaptcha.php:53
110
- msgid "Enter the numbers you hear:"
111
- msgstr "Ingrese los números que escuche:"
112
 
113
- #: includes/class-bwp-recaptcha.php:98
114
- msgid "<strong>ERROR:</strong> Incorrect or empty reCAPTCHA response, please try again."
115
- msgstr "<strong>ERROR:</strong> Respuesta incorrecta o vacía de reCAPTCHA, por favor intente de nuevo."
 
 
 
 
 
 
 
 
 
 
 
 
116
 
117
- #: includes/class-bwp-recaptcha.php:99
118
  #, php-format
119
- msgid "Error: Incorrect or empty reCAPTCHA response, please click the back button on your browser's toolbar or click on %s to go back."
120
- msgstr "Error: la respuesta de reCAPTCHA esta vacía o es incorrecta, por favor haga clic en el botón Volver de la barra de herramientas de su navegador o haga clic en %s para volver."
 
 
121
 
122
- #: includes/class-bwp-recaptcha.php:119
123
- #: includes/class-bwp-recaptcha.php:250
124
- msgid "General Options"
125
- msgstr "Opciones Generales"
 
 
 
 
126
 
127
- #: includes/class-bwp-recaptcha.php:120
128
- #: includes/class-bwp-recaptcha.php:251
129
- msgid "Theme Options"
130
- msgstr "Opciones de Tema"
 
 
131
 
132
- #: includes/class-bwp-recaptcha.php:123
133
- msgid "English"
134
- msgstr "Inglés"
135
 
136
- #: includes/class-bwp-recaptcha.php:124
137
- msgid "Dutch"
138
- msgstr "Holandés"
139
 
140
- #: includes/class-bwp-recaptcha.php:125
141
- msgid "French"
142
- msgstr "Francés"
 
143
 
144
- #: includes/class-bwp-recaptcha.php:126
145
- msgid "German"
146
- msgstr "Alemán"
 
147
 
148
- #: includes/class-bwp-recaptcha.php:127
149
- msgid "Portuguese"
150
- msgstr "Portugués"
 
 
151
 
152
- #: includes/class-bwp-recaptcha.php:128
153
- msgid "Russian"
154
- msgstr "Ruso"
 
 
 
155
 
156
- #: includes/class-bwp-recaptcha.php:129
157
- msgid "Spanish"
158
- msgstr "Español"
159
 
160
- #: includes/class-bwp-recaptcha.php:130
161
- msgid "Turkish"
162
- msgstr "Turco"
 
163
 
164
- #: includes/class-bwp-recaptcha.php:134
165
- msgid "Read Profile"
166
- msgstr "Leer Perfil"
167
 
168
- #: includes/class-bwp-recaptcha.php:135
169
- msgid "Manage Options"
170
- msgstr "Gestionar Opciones"
171
 
172
- #: includes/class-bwp-recaptcha.php:248
173
- msgid "Better WordPress reCAPTCHA"
174
- msgstr "Better WordPress reCAPTCHA"
175
 
176
- #: includes/class-bwp-recaptcha.php:250
177
- msgid "BWP reCAPTCHA General Options"
178
- msgstr "BWP reCAPTCHA Opciones Generales"
179
 
180
- #: includes/class-bwp-recaptcha.php:251
181
- msgid "BWP reCAPTCHA Theme Options"
182
- msgstr "BWP reCAPTCHA Opciones de Tema"
183
 
184
- #: includes/class-bwp-recaptcha.php:262
185
- msgid "You do not have sufficient permissions to access this page."
186
- msgstr "Usted no tiene permisos suficientes para acceder a esta página."
 
187
 
188
- #: includes/class-bwp-recaptcha.php:281
189
- msgid "What is reCAPTCHA?"
190
- msgstr "¿Qué es re CAPTCHA?"
191
 
192
- #: includes/class-bwp-recaptcha.php:282
193
- msgid "This plugin will be"
194
- msgstr "Este plugin estará"
195
 
196
- #: includes/class-bwp-recaptcha.php:283
197
- msgid "Public Key"
198
- msgstr "Clave Pública"
199
 
200
- #: includes/class-bwp-recaptcha.php:284
201
- msgid "Private Key"
202
- msgstr "Clave Privada"
203
 
204
- #: includes/class-bwp-recaptcha.php:285
205
- msgid "Visibility Options (only applied to comment forms)"
206
- msgstr "Opciones de Visibilidad (sólo aplica para los formularios de comentarios)"
207
 
208
- #: includes/class-bwp-recaptcha.php:286
209
- msgid "Hide the CAPTCHA for"
210
- msgstr "Ocultar el CAPTCHA para"
 
 
 
 
211
 
212
- #: includes/class-bwp-recaptcha.php:287
213
- msgid "If wrong or empty response"
214
- msgstr "Si la respuesta es equivocada o vacía"
215
 
216
- #: includes/class-bwp-recaptcha.php:288
217
- #: includes/class-bwp-recaptcha.php:289
218
- msgid "Show the error message"
219
- msgstr "Mostrar el mensaje de error"
220
 
221
- #: includes/class-bwp-recaptcha.php:290
222
- msgid "Akismet Integration"
223
- msgstr "Integración con Akismet"
224
 
225
- #: includes/class-bwp-recaptcha.php:291
226
- msgid "Integrate with Akismet?"
227
- msgstr "Integrar con Akismet?"
228
 
229
- #: includes/class-bwp-recaptcha.php:292
230
- msgid "If correct CAPTCHA response"
231
- msgstr "Si la respuesta de CAPTCHA es correcta"
232
 
233
- #: includes/class-bwp-recaptcha.php:296
234
- msgid "reCAPTCHA is a free CAPTCHA service that helps to digitize books, newspapers and old time radio shows. You can read more about reCAPTCHA <a href=\"http://www.google.com/recaptcha/learnmore\" target=\"_blank\">here</a>."
235
- msgstr "reCAPTCHA es un servicio gratuito de CAPTCHA que ayuda a digitalizar libros, periódicos y viejos programas de radio. Puedes leer más acerca de reCAPTCHA <a href=\"http://www.google.com/recaptcha/learnmore\" target=\"_blank\">aquí</a>."
 
 
 
236
 
237
- #: includes/class-bwp-recaptcha.php:297
238
- msgid "<em>This section allows you to determine when to show reCAPTCHA and how this plugin reacts to errors.</em>"
239
- msgstr "<em>Esta sección le permite a usted determinar cuando mostrar reCAPTCHA y cómo este plugin reacciona a los errores.</em>"
240
 
241
- #: includes/class-bwp-recaptcha.php:298
242
- msgid "<em>Integrate with Akismet for better end-user experience. reCAPTCHA is optional and <strong>NO</strong> spam comment will be added to the spam/moderation queue, except likely legitimate comments. This makes the task of identifying sincere comments much easier. This integration is currently in beta stage.</em>"
243
- msgstr "<em>La integración con Akismet mejora la experiencia del usuario final. reCAPTCHA es opcional y <strong>NINGÚN</strong> comentario de spam será añadido a la cola de spam/moderación, excepto los comentarios legítimos. Esto hace que la tarea de identificar los comentarios sinceros sea mucho más fácil. Esta integración se encuentra actualmente en fase beta.</em>"
244
 
245
- #: includes/class-bwp-recaptcha.php:313
246
- msgid "Redirect commenter back to the comment form"
 
247
  msgstr "Redireccione al comentarista de vuelta al formulario de comentarios"
248
 
249
- #: includes/class-bwp-recaptcha.php:314
250
- msgid "Show an error page just like WordPress does"
251
- msgstr "Mostrar una página de error al igual que lo hace WordPress."
252
 
253
- #: includes/class-bwp-recaptcha.php:317
254
- msgid "Approve comment immediately"
255
- msgstr "Aprobar comentario inmediatamente"
256
 
257
- #: includes/class-bwp-recaptcha.php:318
258
- msgid "Hold comment in moderation queue"
259
- msgstr "Mantener el comentario en la cola de moderación"
260
 
261
- #: includes/class-bwp-recaptcha.php:319
262
- msgid "Put comment in spam queue"
263
- msgstr "Poner el comentario en la cola de spam"
264
 
265
- #: includes/class-bwp-recaptcha.php:323
266
- msgid "enabled for comment forms."
267
- msgstr "habilitado para formularios de comentarios."
268
 
269
- #: includes/class-bwp-recaptcha.php:324
270
- msgid "enabled for registration page."
271
- msgstr "habilitado para la página de registro."
272
 
273
- #: includes/class-bwp-recaptcha.php:325
274
- msgid "registered users <em>(even without any capabilities)</em>."
275
- msgstr "usuarios registrados <em>(incluso sin ninguna capacidad)</em>."
 
 
276
 
277
- #: includes/class-bwp-recaptcha.php:326
278
- msgid "users who can"
279
- msgstr "usuarios que puedan"
 
280
 
281
- #: includes/class-bwp-recaptcha.php:327
282
- msgid "visitors who have at least"
283
- msgstr "visitantes que tengan al menos"
284
 
285
- #: includes/class-bwp-recaptcha.php:328
286
- msgid "reCAPTCHA will only show when Akismet identifies a comment as spam. Highly recommended if you do not want to force your visitors to type the captcha every time."
287
- msgstr "reCAPTCHA sólo se muestrará cuando Akismet identifica un comentario como spam. Muy recomendable si usted no quiere forzar a sus visitantes a escribir el captcha cada vez."
 
 
 
 
 
 
 
288
 
289
- #: includes/class-bwp-recaptcha.php:331
290
- msgid "A public key used to request captchas from reCAPTCHA server."
291
- msgstr "Una clave pública se utiliza para solicitar captchas del servidor reCAPTCHA."
 
292
 
293
- #: includes/class-bwp-recaptcha.php:332
294
- msgid "A private (secret) key used to authenticate user's response."
295
- msgstr "Una clave privada (secreta) se utiliza para autenticar la respuesta del usuario."
296
 
297
- #: includes/class-bwp-recaptcha.php:333
298
- msgid "when redirect commenter back to the comment form."
299
- msgstr "cuando redireccione al comentarista de vuelta al formulario de comentarios."
300
 
301
- #: includes/class-bwp-recaptcha.php:334
302
- msgid "when show the normal error page with no redirection."
303
- msgstr "cuando muestra la página de error normal sin redirección."
304
 
305
- #: includes/class-bwp-recaptcha.php:335
306
- msgid "approved comment(s)."
307
- msgstr "comentario(s) aprobado(s)."
 
 
 
308
 
309
- #: includes/class-bwp-recaptcha.php:338
310
- msgid "<em><strong>Note:</strong> For this plugin to work, you will need a pair of API keys (public and private), which is available for free <a href=\"https://www.google.com/recaptcha/admin/create\" target=\"_blank\">here</a>. Once you have created those two keys for this domain, simply paste them below.</em>"
311
- msgstr "<em><strong>Nota:</strong> Para que este plugin funcione, usted necesitará de un par de claves API (pública y privada), que están disponibles de forma gratuita <a href=\"https://www.google.com/recaptcha/admin/create\" target=\"_blank\">aquí</a>. Una vez que haya creado las dos claves para este dominio, sólo tiene que pegarlas a continuación.</em>"
 
 
 
312
 
313
- #: includes/class-bwp-recaptcha.php:339
314
- msgid "<em><strong>Note:</strong> Now you may wonder, why put the comment in the spam queue? The benefit is Akismet will be able to mark the comment as False Positive, and thus will not possibly block that comment in the future. However, it is best to just put the comment in moderation queue as next time Akismet will put such comment in moderation queue immediately without the need of a CAPTCHA.</em>"
315
- msgstr "<em><strong>Nota:</strong> Ahora usted puede preguntarse, ¿por qué poner el comentario en la cola de spam? El beneficio de esto es que Akismet será capaz de marcar el comentario como Falso Positivo, y por lo tanto no será posible que bloqueé el comentario en el futuro. Sin embargo, es mejor sólo poner el comentario en la cola de moderación ya que la próxima vez Akismet pondrá esos comentarios en la cola de moderación inmediatamente sin la necesidad de un CAPTCHA.</em>"
316
 
317
- #: includes/class-bwp-recaptcha.php:364
318
- msgid "Choose a theme"
319
- msgstr "Elija un tema"
 
 
 
320
 
321
- #: includes/class-bwp-recaptcha.php:365
322
- msgid "Use CSS provided by this plugin?"
323
- msgstr "¿Usar los CSS proporcionados por este plugin?"
 
 
324
 
325
- #: includes/class-bwp-recaptcha.php:366
326
- msgid "Load CSS, JS selectively?"
327
- msgstr "¿Leer CSS, JS selectivamente?"
328
 
329
- #: includes/class-bwp-recaptcha.php:367
330
- msgid "Choose a language for built-in themes"
331
- msgstr "Elija un idioma para los temas integrados."
 
332
 
333
- #: includes/class-bwp-recaptcha.php:368
334
- msgid "Tabindex for captcha input field"
335
- msgstr "Tabindex para el campo de entrada de captcha"
 
 
 
 
336
 
337
- #: includes/class-bwp-recaptcha.php:369
338
- msgid "Preview your reCAPTCHA"
339
- msgstr "Vista previa de su reCAPTCHA"
340
 
341
- #: includes/class-bwp-recaptcha.php:373
342
- msgid "<em>Below you will see how your reCAPTCHA will look. Note that this might differ on your actual pages.<br /></em>"
343
- msgstr "<em>A continuación podrás apreciar cómo tu reCAPTCHA se verá. Tener en cuenta que esto puede variar en sus páginas reales.<br /></em>"
344
 
345
- #: includes/class-bwp-recaptcha.php:377
346
- msgid "Default Theme (Red)"
347
- msgstr "Tema por defecto (Rojo)"
348
 
349
- #: includes/class-bwp-recaptcha.php:378
350
- msgid "White Theme"
351
- msgstr "Tema Blanco"
352
 
353
- #: includes/class-bwp-recaptcha.php:379
354
- msgid "Black Theme"
355
- msgstr "Tema Negro"
356
 
357
- #: includes/class-bwp-recaptcha.php:380
358
- msgid "Clean Theme"
359
- msgstr "Tema Limpio"
360
 
361
- #: includes/class-bwp-recaptcha.php:381
362
- msgid "Custom Theme (use CSS)"
363
- msgstr "Tema Personalizado (usa CSS)"
 
 
 
364
 
365
- #: includes/class-bwp-recaptcha.php:386
366
- msgid "This stylesheet is used to style the custom theme as well as the registration page. You can disable this or add appropriate filters to use your own."
367
- msgstr "Esta hoja de estilos se usa para personalizar el tema así como la página de registro. Usted puede desactivar esto o añadir los filtros apropiados para utilizar los suyos propios."
368
 
369
- #: includes/class-bwp-recaptcha.php:387
370
- msgid "This is only useful when you do not use any minify or cache plugin."
371
- msgstr "Esto es útil solamente cuando usted no usa ningún plugin de minify o cache."
372
 
373
- #: includes/class-bwp-recaptcha.php:390
374
- msgid "Basically, this should be 4 if you place the captcha before the textarea, and 5 if you put it after."
375
- msgstr "Básicamente, este debe ser de 4 si se coloca el antes del área de texto, y 5 si lo pone después."
 
376
 
377
- #: includes/class-bwp-recaptcha.php:393
378
- #, php-format
379
- msgid "<em><strong>Note:</strong> The four built-in captcha themes will look OK in most WordPress themes; However, some times it is better to control how reCAPTCHA looks using CSS. Please read <a href=\"%s#customization\" target=\"_blank\">this guide</a> if you would like to do so.</em>"
380
- msgstr "<em><strong>Nota:</strong> Los cuatro temas integrados de captcha se verán bien en la mayoría de temas de WordPress, sin embargo, a veces es mejor controlar la forma en reCAPTCHA se luce haciendo uso de CSS. Por favor lea <a href=\"%s#customization\" target=\"_blank\">esta guía</a> si desea hacerlo."
381
 
382
- #: includes/class-bwp-recaptcha.php:394
383
- #, php-format
384
- msgid "<em><strong>Note:</strong> Above you can select some built-in languages. If you would like to add your own language, please read <a href=\"%s#customization\" target=\"_blank\">this guide</a>.</em>"
385
- msgstr "<em><strong>Nota:</strong> Arriba usted puede seleccionar algunos de los idiomas integrados. Si desea agregar su propio idioma, por favor lea <a href=\"%s#customization\" target=\"_blank\">esta guía</a>.</em>"
 
 
 
386
 
387
- #: includes/class-bwp-recaptcha.php:438
388
  msgid "Warning"
389
  msgstr "Advertencia"
390
 
391
- #: includes/class-bwp-recaptcha.php:438
392
- msgid "API key(s) missing. Please get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a> (free!)"
393
- msgstr "Faltan las claves de la API. Por favor obtenga una clave de la API de <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a> (es gratuito!)"
394
 
395
- #: includes/class-bwp-recaptcha.php:440
396
- msgid "Notice"
397
- msgstr "Nota"
 
 
 
 
398
 
399
- #: includes/class-bwp-recaptcha.php:440
400
- msgid "You are enabling Akismet integration but Akismet is not currently active. Please activate Akismet for the integration to work."
401
- msgstr "Usted está permitiendo la integración con Akismet, pero Akismet actualmente no está activo Por favor active Akismet para que funcione la integración."
 
402
 
403
- #: includes/class-bwp-recaptcha.php:548
 
 
 
 
 
404
  msgid "Your comment was identified as spam, please complete the CAPTCHA below:"
405
- msgstr "Su comentario fue identificado como spam, por favor complete el CAPTCHA a continuación:"
 
 
406
 
407
- #: includes/class-bwp-recaptcha.php:580
408
- msgid "To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>"
409
- msgstr "Para usar reCAPTCHA debe obtener una clave de API de <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>"
 
 
 
 
 
 
 
 
 
410
 
411
- #: includes/class-bwp-recaptcha.php:609
412
- msgid "<strong>ERROR</strong>: Captcha response is either empty or incorrect."
413
- msgstr "<strong>ERROR</strong>: La respuesta de captcha está vacía o es incorrecta."
 
414
 
415
- #: includes/class-bwp-recaptcha.php:611
416
- msgid "<strong>ERROR</strong>: Unknown captcha error."
417
- msgstr "<strong>ERROR</strong>: Error de captcha desconocido."
 
 
 
 
 
 
418
 
419
- #: includes/class-bwp-recaptcha.php:661
 
 
 
 
 
 
 
 
 
420
  msgid "this link"
421
  msgstr "este enlace"
422
 
423
- #: includes/class-bwp-recaptcha.php:663
424
- msgid "There is some problem with your reCAPTCHA API keys, please double check them."
425
- msgstr "Hay algún problema con sus claves de la API de reCAPTCHA, por favor, vuelva a comprobarlas."
426
 
427
- #: includes/class-bwp-recaptcha.php:665
428
- msgid "Unknown error. Please contact the administrator for more info."
429
- msgstr "Error desconocido. Póngase en contacto con el administrador para más información."
430
 
431
- #: includes/bwp-option-page/includes/class-bwp-option-page.php:80
432
- msgid "Plugin Configurations"
433
- msgstr "Configuraciones de Plugin"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434
 
435
- #: includes/bwp-option-page/includes/class-bwp-option-page.php:398
436
- msgid "Save Changes"
437
- msgstr "Guardar Cambios"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
438
 
439
  #~ msgid "log"
440
  #~ msgstr "blog"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: BWP reCAPTCHA\n"
4
+ "Report-Msgid-Bugs-To: contact@betterwp.net\n"
5
+ "POT-Creation-Date: 2016-01-12 23:47+0700\n"
6
+ "PO-Revision-Date: 2016-01-12 15:25+0700\n"
7
  "Last-Translator: \n"
8
  "Language-Team: \n"
9
+ "Language: es_ES\n"
10
  "MIME-Version: 1.0\n"
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
  "X-Poedit-KeywordsList: _;gettext;gettext_noop;__;_e\n"
14
  "X-Poedit-Basepath: .\n"
15
  "X-Poedit-SourceCharset: utf-8\n"
16
+ "X-Generator: Poedit 1.8.5\n"
 
17
  "X-Poedit-SearchPath-0: .\n"
18
 
19
+ #: vendor/kminh/bwp-framework/src/class-bwp-version.php:32
20
  #, php-format
21
+ msgid ""
22
+ "%s requires WordPress <strong>%s</strong> or higher and PHP <strong>%s</"
23
+ "strong> or higher. The plugin will not function until you update your "
24
+ "software. Please deactivate this plugin."
25
+ msgstr ""
26
+ "%s requiere WordPress <strong>%s</strong> o mayor y PHP <strong>%s</strong> "
27
+ "o mayor. El plugin no funcionará hasta que actualice su software. Por favor "
28
+ "desactive este plugin."
29
 
30
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:411
31
+ msgid "... or any amount!"
32
+ msgstr "... o cualquier cantidad!"
33
 
34
+ #: includes/class-bwp-recaptcha.php:1006 includes/class-bwp-recaptcha.php:1101
35
+ #, fuzzy
36
+ msgid ""
37
+ "<em>Below you will see how your reCAPTCHA will look. Note that this might "
38
+ "differ on your actual pages.</em>"
39
+ msgstr ""
40
+ "<em>A continuación podrás apreciar cómo tu reCAPTCHA se verá. Tener en "
41
+ "cuenta que esto puede variar en sus páginas reales.<br /></em>"
42
 
43
+ #: includes/class-bwp-recaptcha.php:118
44
+ msgid ""
45
+ "<strong>ERROR:</strong> Incorrect or empty reCAPTCHA response, please try "
46
+ "again."
47
+ msgstr ""
48
+ "<strong>ERROR:</strong> Respuesta incorrecta o vacía de reCAPTCHA, por favor "
49
+ "intente de nuevo."
50
 
51
+ #: includes/class-bwp-recaptcha.php:867
52
+ msgid "A private (secret) key used to authenticate user's response."
53
+ msgstr ""
54
+ "Una clave privada (secreta) se utiliza para autenticar la respuesta del "
55
+ "usuario."
56
 
57
+ #: includes/class-bwp-recaptcha.php:861
58
+ msgid "A public key used to request captchas from reCAPTCHA server."
59
+ msgstr ""
60
+ "Una clave pública se utiliza para solicitar captchas del servidor reCAPTCHA."
61
 
62
+ #: includes/class-bwp-recaptcha.php:1193
63
+ #, php-format
64
+ msgid ""
65
+ "API key(s) missing. Please get an API key from <a href=\"%1$s\">%1$s</a> "
66
+ "(free!)"
67
+ msgstr ""
68
 
69
+ #: includes/provider/v1.php:165
70
+ msgid "About reCAPTCHA"
71
+ msgstr "Acerca de reCAPTCHA"
72
 
73
+ #: includes/class-bwp-recaptcha.php:1021 includes/class-bwp-recaptcha.php:1123
74
+ msgid ""
75
+ "Add additional CSS rules to all recaptcha instances. You can edit them below."
76
+ msgstr ""
77
 
78
+ #: includes/class-bwp-recaptcha.php:756
79
+ msgid ""
80
+ "Add reCAPTCHA to Contact Form 7. This only works if you have Contact Form 7 "
81
+ "activated."
82
+ msgstr ""
83
 
84
+ #: includes/class-bwp-recaptcha.php:827
85
+ msgid ""
86
+ "Add the <code>recaptcha</code> shortcode tag to your Contact Form 7 forms."
87
+ msgstr ""
88
 
89
+ #: includes/class-bwp-recaptcha.php:773
90
+ #, fuzzy
91
+ msgid "After comment field"
92
+ msgstr "Aprobar comentario inmediatamente"
93
 
94
+ #: includes/class-bwp-recaptcha.php:774
95
+ msgid "After form fields (name, email, website)"
96
+ msgstr ""
97
+
98
+ #: includes/class-bwp-recaptcha.php:819
99
+ msgid "After redirected, auto fill the comment field with previous comment."
100
+ msgstr ""
101
+
102
+ #: includes/class-bwp-recaptcha.php:708
103
+ #, fuzzy
104
+ msgid "Akismet Integration for comment form"
105
+ msgstr "Integración con Akismet"
106
+
107
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:438
108
+ msgid "All options have been saved."
109
+ msgstr ""
110
+
111
+ #: includes/class-bwp-recaptcha.php:781
112
+ msgid "Approve comment immediately"
113
+ msgstr "Aprobar comentario inmediatamente"
114
+
115
+ #: includes/class-bwp-recaptcha.php:636
116
+ msgid "Auto detected"
117
+ msgstr ""
118
+
119
+ #: includes/class-bwp-recaptcha.php:705
120
+ msgid "Auto fill comment field"
121
+ msgstr ""
122
+
123
+ #: includes/class-bwp-recaptcha.php:1114
124
+ msgid "Auto-detected"
125
+ msgstr ""
126
+
127
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:521
128
+ msgid "BWP Gems"
129
+ msgstr ""
130
+
131
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:531
132
+ msgid "BWP News"
133
+ msgstr ""
134
+
135
+ #: includes/class-bwp-recaptcha.php:595
136
+ msgid "BWP reCAPTCHA General Options"
137
+ msgstr "BWP reCAPTCHA Opciones Generales"
138
+
139
+ #: includes/class-bwp-recaptcha.php:604
140
+ msgid "BWP reCAPTCHA Theme Options"
141
+ msgstr "BWP reCAPTCHA Opciones de Tema"
142
+
143
+ #: includes/class-bwp-recaptcha.php:585
144
+ msgid "Better WordPress reCAPTCHA"
145
+ msgstr "Better WordPress reCAPTCHA"
146
+
147
+ #: includes/class-bwp-recaptcha.php:1013
148
+ msgid "Black Theme"
149
+ msgstr "Tema Negro"
150
+
151
+ #: includes/class-bwp-recaptcha.php:703
152
+ msgid "Captcha position"
153
+ msgstr ""
154
+
155
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:439
156
+ msgid "Check out this cool plugin"
157
+ msgstr ""
158
+
159
+ #: includes/class-bwp-recaptcha.php:1014
160
+ msgid "Clean Theme"
161
+ msgstr "Tema Limpio"
162
+
163
+ #: includes/class-bwp-recaptcha.php:787
164
+ msgid "Comment form"
165
+ msgstr ""
166
+
167
+ #: includes/class-bwp-recaptcha.php:1111
168
+ msgid "Compact"
169
+ msgstr ""
170
+
171
+ #: includes/class-bwp-recaptcha.php:711
172
+ msgid "Contact Form 7 Integration"
173
+ msgstr ""
174
+
175
+ #: includes/addons/contact-form-7/captcha-shortcode.php:205
176
+ msgid "Copy this code and paste it into the form left."
177
+ msgstr ""
178
 
179
+ #: includes/class-bwp-recaptcha.php:1015
180
+ msgid "Custom Theme (use CSS)"
181
+ msgstr "Tema Personalizado (usa CSS)"
182
 
183
+ #: includes/class-bwp-recaptcha.php:1107
184
+ msgid "Dark"
185
+ msgstr ""
186
 
187
+ #: includes/class-bwp-recaptcha.php:1011
188
+ msgid "Default Theme (Red)"
189
+ msgstr "Tema por defecto (Rojo)"
190
+
191
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:1530
192
+ msgid "Dismiss this notice."
193
+ msgstr ""
194
+
195
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:405
196
  #, php-format
197
+ msgid "Donate to %s"
198
+ msgstr "donar a %s"
199
 
200
+ #: includes/class-bwp-recaptcha.php:992 includes/class-bwp-recaptcha.php:1087
201
+ msgid "Enable custom CSS"
202
+ msgstr ""
203
+
204
+ #: includes/class-bwp-recaptcha.php:700
205
+ msgid "Enable this plugin for"
206
+ msgstr ""
207
+
208
+ #: includes/class-bwp-recaptcha.php:120
209
+ #, php-format
210
+ msgid ""
211
+ "Error: Incorrect or empty reCAPTCHA response, please click the back button "
212
+ "on your browser's toolbar or click on %s to go back."
213
+ msgstr ""
214
+ "Error: la respuesta de reCAPTCHA esta vacía o es incorrecta, por favor haga "
215
+ "clic en el botón Volver de la barra de herramientas de su navegador o haga "
216
+ "clic en %s para volver."
217
 
218
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:371
219
+ msgid "FAQ"
220
+ msgstr "FAQ"
221
+
222
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:409
223
+ msgid "Five cups! $25.00"
224
+ msgstr "Cinco tazas! $ 25.00"
225
+
226
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:548
227
+ msgid "Follow"
228
+ msgstr ""
229
+
230
+ #: includes/class-bwp-recaptcha.php:744
231
+ #, fuzzy, php-format
232
+ msgid ""
233
+ "For this plugin to work, you will need a pair of API keys, which is "
234
+ "available for free <a href=\"%s\" target=\"_blank\">here</a>. Once you have "
235
+ "created those two keys for the current domain, simply paste them below.</em>"
236
+ msgstr ""
237
+ "<em><strong>Nota:</strong> Para que este plugin funcione, usted necesitará "
238
+ "de un par de claves API (pública y privada), que están disponibles de forma "
239
+ "gratuita <a href=\"https://www.google.com/recaptcha/admin/create\" target="
240
+ "\"_blank\">aquí</a>. Una vez que haya creado las dos claves para este "
241
+ "dominio, sólo tiene que pegarlas a continuación.</em>"
242
+
243
+ #: includes/class-bwp-recaptcha.php:697
244
+ msgid "Force https"
245
+ msgstr ""
246
+
247
+ #: includes/class-bwp-recaptcha.php:159 includes/class-bwp-recaptcha.php:596
248
+ msgid "General Options"
249
+ msgstr "Opciones Generales"
250
+
251
+ #: includes/provider/v1.php:162
252
  msgid "Get another challenge"
253
  msgstr "Obtén un nuevo reto"
254
 
255
+ #: includes/provider/v1.php:163
256
  msgid "Get audio reCAPTCHA"
257
  msgstr "Obtén un audio reCAPTCHA"
258
 
259
+ #: includes/provider/v1.php:164
260
  msgid "Get image reCAPTCHA"
261
  msgstr "Obtén una imagen reCAPTCHA"
262
 
263
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:374
264
+ msgid "Got a problem with this plugin? Please say it out loud!"
265
+ msgstr ""
266
 
267
+ #: includes/class-bwp-recaptcha.php:701
268
+ #, fuzzy
269
+ msgid "Hide captcha for"
270
+ msgstr "Ocultar el CAPTCHA para"
271
 
272
+ #: includes/class-bwp-recaptcha.php:782
273
+ msgid "Hold comment in moderation queue"
274
+ msgstr "Mantener el comentario en la cola de moderación"
275
 
276
+ #: includes/class-bwp-recaptcha.php:710
277
+ #, fuzzy
278
+ msgid "If correct captcha response"
279
+ msgstr "Si la respuesta de CAPTCHA es correcta"
280
+
281
+ #: includes/class-bwp-recaptcha.php:704
282
+ #, fuzzy
283
+ msgid "If invalid captcha response"
284
+ msgstr "Si la respuesta es equivocada o vacía"
285
+
286
+ #: includes/class-bwp-recaptcha.php:880
287
+ msgid ""
288
+ "If you encounter error such as <code>Unknown error (invalid-json)</code>when "
289
+ "submitting a form, try selecting a specific request method here."
290
+ msgstr ""
291
 
292
+ #: includes/class-bwp-recaptcha.php:1054
293
  #, php-format
294
+ msgid ""
295
+ "If you want to add custom translations, please read <a href=\"%s\" target="
296
+ "\"_blank\">this tip</a>."
297
+ msgstr ""
298
 
299
+ #: includes/class-bwp-recaptcha.php:1207
300
+ #, php-format
301
+ msgid ""
302
+ "In order to use the nocaptcha recaptcha (recaptcha v2), you need at least "
303
+ "<strong>PHP 5.3.2</strong> (your current PHP version is <strong>%s</"
304
+ "strong>), so only recaptcha v1 can be used. It is recommended to contact "
305
+ "your host to know how to update your current version of PHP."
306
+ msgstr ""
307
 
308
+ #: includes/class-bwp-recaptcha.php:125
309
+ #, fuzzy
310
+ msgid "Incorrect or empty reCAPTCHA response, please try again."
311
+ msgstr ""
312
+ "<strong>ERROR:</strong> Respuesta incorrecta o vacía de reCAPTCHA, por favor "
313
+ "intente de nuevo."
314
 
315
+ #: includes/addons/contact-form-7/captcha-shortcode.php:170
316
+ msgid "Insert Tag"
317
+ msgstr ""
318
 
319
+ #: includes/class-bwp-recaptcha.php:753
320
+ msgid "Integrate the comment form with Akismet for better end-user experience."
321
+ msgstr ""
322
 
323
+ #: includes/class-bwp-recaptcha.php:709
324
+ #, fuzzy
325
+ msgid "Integrate with Akismet"
326
+ msgstr "Integrar con Akismet?"
327
 
328
+ #: includes/class-bwp-recaptcha.php:712
329
+ #, fuzzy
330
+ msgid "Integrate with Contact Form 7"
331
+ msgstr "Integrar con Akismet?"
332
 
333
+ #: includes/class-bwp-recaptcha.php:706 includes/class-bwp-recaptcha.php:707
334
+ #: includes/class-bwp-recaptcha.php:714
335
+ #, fuzzy
336
+ msgid "Invalid captcha error message"
337
+ msgstr "Mostrar el mensaje de error"
338
 
339
+ #: includes/class-bwp-recaptcha.php:886
340
+ msgid ""
341
+ "It is best to put comments identified as spam in moderation queue so you are "
342
+ "able to review and instruct Akismet to correctly handle similar comments in "
343
+ "the future."
344
+ msgstr ""
345
 
346
+ #: includes/class-bwp-recaptcha.php:1088
347
+ msgid "Language"
348
+ msgstr ""
349
 
350
+ #: includes/class-bwp-recaptcha.php:993
351
+ #, fuzzy
352
+ msgid "Language for built-in themes"
353
+ msgstr "Elija un idioma para los temas integrados."
354
 
355
+ #: includes/class-bwp-recaptcha.php:1106
356
+ msgid "Light"
357
+ msgstr ""
358
 
359
+ #: includes/class-bwp-recaptcha.php:793
360
+ msgid "Login form"
361
+ msgstr ""
362
 
363
+ #: includes/class-bwp-recaptcha.php:699
364
+ msgid "Main Functionality"
365
+ msgstr ""
366
 
367
+ #: includes/class-bwp-recaptcha.php:816
368
+ msgid "Make requests to recaptcha server always secured."
369
+ msgstr ""
370
 
371
+ #: includes/class-bwp-recaptcha.php:317
372
+ msgid "Manage Options"
373
+ msgstr "Gestionar Opciones"
374
 
375
+ #: includes/addons/contact-form-7/captcha-shortcode.php:159
376
+ #: includes/addons/contact-form-7/captcha-shortcode.php:196
377
+ msgid "Name"
378
+ msgstr ""
379
 
380
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:503
381
+ msgid "Need a highly customizable theme?"
382
+ msgstr ""
383
 
384
+ #: includes/class-bwp-recaptcha.php:1110
385
+ msgid "Normal"
386
+ msgstr ""
387
 
388
+ #: includes/class-bwp-recaptcha.php:1205 includes/class-bwp-recaptcha.php:1227
389
+ msgid "Notice"
390
+ msgstr "Nota"
391
 
392
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:410
393
+ msgid "One LL-cup!!! $50.00"
394
+ msgstr "Una taza de LL-! $ 50.00"
395
 
396
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:407
397
+ msgid "One cup $5.00"
398
+ msgstr "Una taza de $ 5,00"
399
 
400
+ #: includes/addons/contact-form-7/captcha-shortcode.php:225
401
+ #, php-format
402
+ msgid ""
403
+ "Please refer to <a target=\"_blank\" href=\"%s\">BWP reCAPTCHA's "
404
+ "documentation</a> for a quick guide on how to customize the look and feel of "
405
+ "this tag."
406
+ msgstr ""
407
 
408
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:93
409
+ msgid "Plugin Configurations"
410
+ msgstr "Configuraciones de Plugin"
411
 
412
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:375
413
+ msgid "Plugin Support"
414
+ msgstr ""
 
415
 
416
+ #: includes/class-bwp-recaptcha.php:995 includes/class-bwp-recaptcha.php:1090
417
+ msgid "Preview your reCAPTCHA"
418
+ msgstr "Vista previa de su reCAPTCHA"
419
 
420
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:378
421
+ msgid "Rate this plugin 5 stars if you like it, thank you!"
422
+ msgstr ""
423
 
424
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:379
425
+ msgid "Rate this plugin 5 stars!"
426
+ msgstr ""
427
 
428
+ #: includes/class-bwp-recaptcha.php:1045
429
+ #, php-format
430
+ msgid ""
431
+ "Read <a href=\"%s#recaptcha-version-1\" target=\"_blank\">here</a> to know "
432
+ "how to use your own CSS for the Custom Theme."
433
+ msgstr ""
434
 
435
+ #: includes/class-bwp-recaptcha.php:316
436
+ msgid "Read Profile"
437
+ msgstr "Leer Perfil"
438
 
439
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:370
440
+ msgid "Read this first before asking any question!"
441
+ msgstr ""
442
 
443
+ #: includes/class-bwp-recaptcha.php:777
444
+ #, fuzzy
445
+ msgid "Redirect commenter back to the comment form with error message"
446
  msgstr "Redireccione al comentarista de vuelta al formulario de comentarios"
447
 
448
+ #: includes/class-bwp-recaptcha.php:790
449
+ msgid "Registration form (user/site registration)"
450
+ msgstr ""
451
 
452
+ #: includes/class-bwp-recaptcha.php:698
453
+ msgid "Request method"
454
+ msgstr ""
455
 
456
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:305
457
+ msgid "Save Changes"
458
+ msgstr "Guardar Cambios"
459
 
460
+ #: includes/class-bwp-recaptcha.php:694
461
+ msgid "Secret Key"
462
+ msgstr ""
463
 
464
+ #: includes/class-bwp-recaptcha.php:1129
465
+ msgid "Set to 0 to disable."
466
+ msgstr ""
467
 
468
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:1315
469
+ msgid "Settings"
470
+ msgstr "Configuraciones"
471
 
472
+ #: includes/class-bwp-recaptcha.php:751
473
+ #, fuzzy
474
+ msgid "Settings that are applied to comment forms only."
475
+ msgstr ""
476
+ "Opciones de Visibilidad (sólo aplica para los formularios de comentarios)"
477
 
478
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:431
479
+ #, fuzzy
480
+ msgid "Share the love for this plugin!"
481
+ msgstr "¿Usar los CSS proporcionados por este plugin?"
482
 
483
+ #: includes/class-bwp-recaptcha.php:778
484
+ msgid "Show an error page just like WordPress does"
485
+ msgstr "Mostrar una página de error al igual que lo hace WordPress."
486
 
487
+ #: includes/class-bwp-recaptcha.php:805
488
+ #, fuzzy
489
+ msgid ""
490
+ "Show captcha only when Akismet identifies a comment as spam. Highly "
491
+ "recommended if you do not want to force your visitors to enter a captcha "
492
+ "every time."
493
+ msgstr ""
494
+ "reCAPTCHA sólo se muestrará cuando Akismet identifica un comentario como "
495
+ "spam. Muy recomendable si usted no quiere forzar a sus visitantes a escribir "
496
+ "el captcha cada vez."
497
 
498
+ #: includes/class-bwp-recaptcha.php:693
499
+ #, fuzzy
500
+ msgid "Site Key"
501
+ msgstr "Clave Privada"
502
 
503
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:541
504
+ msgid "Subscribe"
505
+ msgstr ""
506
 
507
+ #: includes/class-bwp-recaptcha.php:994 includes/class-bwp-recaptcha.php:1089
508
+ msgid "Tabindex for captcha input field"
509
+ msgstr "Tabindex para el campo de entrada de captcha"
510
 
511
+ #: includes/class-bwp-recaptcha.php:162 includes/class-bwp-recaptcha.php:605
512
+ msgid "Theme Options"
513
+ msgstr "Opciones de Tema"
514
 
515
+ #: includes/provider/abstract-provider.php:103
516
+ msgid ""
517
+ "There is some problem with your reCAPTCHA API keys, please double check them."
518
+ msgstr ""
519
+ "Hay algún problema con sus claves de la API de reCAPTCHA, por favor, vuelva "
520
+ "a comprobarlas."
521
 
522
+ #: includes/class-bwp-recaptcha.php:754 includes/class-bwp-recaptcha.php:822
523
+ #, php-format
524
+ msgid ""
525
+ "This feature requires an active <a target=\"_blank\" href=\"%s\">PHP "
526
+ "session</a>."
527
+ msgstr ""
528
 
529
+ #: includes/class-bwp-recaptcha.php:897
530
+ msgid "This is shown on the standard WordPress error page."
531
+ msgstr ""
532
 
533
+ #: includes/class-bwp-recaptcha.php:892
534
+ #, fuzzy
535
+ msgid ""
536
+ "This is shown when the commenter is redirected back to the comment form."
537
+ msgstr ""
538
+ "cuando redireccione al comentarista de vuelta al formulario de comentarios."
539
 
540
+ #: includes/class-bwp-recaptcha.php:905
541
+ msgid ""
542
+ "This message is shown when invalid captcha response is treated as a standard "
543
+ "validation error. Leave blank to not use."
544
+ msgstr ""
545
 
546
+ #: includes/addons/contact-form-7/captcha-shortcode.php:220
547
+ msgid "This reCAPTCHA tag is provided by the BWP reCAPTCHA WordPress plugin."
548
+ msgstr ""
549
 
550
+ #: includes/provider/v1.php:96
551
+ #, php-format
552
+ msgid "To use reCAPTCHA you must get an API key from <a href=\"%1$s\">%1$s</a>"
553
+ msgstr ""
554
 
555
+ #: includes/class-bwp-recaptcha.php:873
556
+ msgid ""
557
+ "To verify a captcha response, this plugin needs to send requests to the "
558
+ "reCAPTCHA server, using a specific request method. <br /><br />By default, "
559
+ "BWP reCAPTCHA use the first available request method, be it Socket "
560
+ "(<code>fsockopen</code>), cURL, or <code>file_get_contents</code>."
561
+ msgstr ""
562
 
563
+ #: includes/class-bwp-recaptcha.php:713
564
+ msgid "Treat invalid captcha as spam"
565
+ msgstr ""
566
 
567
+ #: includes/class-bwp-recaptcha.php:830
568
+ msgid "Treat invalid captcha response as spam instead of validation error"
569
+ msgstr ""
570
 
571
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:408
572
+ msgid "Two cups $10.00"
573
+ msgstr "Dos tazas de $ 10.00"
574
 
575
+ #: includes/provider/v1.php:170
576
+ msgid "Type what you hear"
577
+ msgstr ""
578
 
579
+ #: includes/provider/v1.php:169
580
+ msgid "Type what you see"
581
+ msgstr ""
582
 
583
+ #: includes/class-bwp-recaptcha.php:810
584
+ msgid "Uncheck to use different key pairs for this site."
585
+ msgstr ""
586
 
587
+ #: includes/provider/abstract-provider.php:107
588
+ #, fuzzy, php-format
589
+ msgid "Unknown error (%s). Please contact an administrator for more info."
590
+ msgstr ""
591
+ "Error desconocido. Póngase en contacto con el administrador para más "
592
+ "información."
593
 
594
+ #: includes/class-bwp-recaptcha.php:991
595
+ msgid "Use default CSS"
596
+ msgstr ""
597
 
598
+ #: includes/class-bwp-recaptcha.php:692
599
+ msgid "Use main site's keys"
600
+ msgstr ""
601
 
602
+ #: includes/class-bwp-recaptcha.php:696
603
+ #, fuzzy
604
+ msgid "Use reCAPTCHA version 1"
605
+ msgstr "BWP reCAPTCHA Opciones Generales"
606
 
607
+ #: includes/class-bwp-recaptcha.php:813
608
+ msgid ""
609
+ "Use the oldschool recaptcha instead of the new <em>nocaptcha</em> recaptcha."
610
+ msgstr ""
611
 
612
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:416
613
+ msgid "Via"
614
+ msgstr ""
615
+
616
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:827
617
+ msgid "View more info in a separate tab"
618
+ msgstr ""
619
 
620
+ #: includes/class-bwp-recaptcha.php:1192
621
  msgid "Warning"
622
  msgstr "Advertencia"
623
 
624
+ #: includes/class-bwp-recaptcha.php:1012
625
+ msgid "White Theme"
626
+ msgstr "Tema Blanco"
627
 
628
+ #: includes/class-bwp-recaptcha.php:1228
629
+ msgid ""
630
+ "You are enabling Akismet integration but Akismet is not currently active. "
631
+ "Please activate Akismet for the integration to work."
632
+ msgstr ""
633
+ "Usted está permitiendo la integración con Akismet, pero Akismet actualmente "
634
+ "no está activo Por favor active Akismet para que funcione la integración."
635
 
636
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:565
637
+ #, php-format
638
+ msgid "You are using version %s!"
639
+ msgstr "Usted esta usando la versión %s!"
640
 
641
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:391
642
+ msgid ""
643
+ "You can buy me some special coffees if you appreciate my work, thank you!"
644
+ msgstr "Me puedes comprar una tazas de café si te gusta mi trabajo, gracias!"
645
+
646
+ #: includes/class-bwp-recaptcha.php:1376
647
  msgid "Your comment was identified as spam, please complete the CAPTCHA below:"
648
+ msgstr ""
649
+ "Su comentario fue identificado como spam, por favor complete el CAPTCHA a "
650
+ "continuación:"
651
 
652
+ #: includes/class-bwp-recaptcha.php:848
653
+ msgid "approved comment(s)."
654
+ msgstr "comentario(s) aprobado(s)."
655
+
656
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:524
657
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:534
658
+ msgid "loading..."
659
+ msgstr ""
660
+
661
+ #: includes/class-bwp-recaptcha.php:691
662
+ msgid "reCAPTCHA API Keys"
663
+ msgstr ""
664
 
665
+ #: includes/class-bwp-recaptcha.php:695
666
+ #, fuzzy
667
+ msgid "reCAPTCHA Settings"
668
+ msgstr "BWP reCAPTCHA Opciones de Tema"
669
 
670
+ #: includes/class-bwp-recaptcha.php:702
671
+ #, fuzzy
672
+ msgid "reCAPTCHA for comment form"
673
+ msgstr "habilitado para formularios de comentarios."
674
+
675
+ #: includes/class-bwp-recaptcha.php:1086
676
+ #, fuzzy
677
+ msgid "reCAPTCHA size"
678
+ msgstr "Acerca de reCAPTCHA"
679
 
680
+ #: includes/class-bwp-recaptcha.php:990 includes/class-bwp-recaptcha.php:1085
681
+ #, fuzzy
682
+ msgid "reCAPTCHA theme"
683
+ msgstr "BWP reCAPTCHA Opciones de Tema"
684
+
685
+ #: includes/class-bwp-recaptcha.php:796
686
+ msgid "registered users <em>(even without any capabilities)</em>."
687
+ msgstr "usuarios registrados <em>(incluso sin ninguna capacidad)</em>."
688
+
689
+ #: includes/class-bwp-recaptcha.php:1554
690
  msgid "this link"
691
  msgstr "este enlace"
692
 
693
+ #: includes/class-bwp-recaptcha.php:799
694
+ msgid "users who can"
695
+ msgstr "usuarios que puedan"
696
 
697
+ #: includes/class-bwp-recaptcha.php:802
698
+ msgid "visitors who have at least"
699
+ msgstr "visitantes que tengan al menos"
700
 
701
+ #~ msgid ""
702
+ #~ "<em><strong>Note:</strong> Above you can select some built-in languages. "
703
+ #~ "If you would like to add your own language, please read <a href="
704
+ #~ "\"%s#customization\" target=\"_blank\">this guide</a>.</em>"
705
+ #~ msgstr ""
706
+ #~ "<em><strong>Nota:</strong> Arriba usted puede seleccionar algunos de los "
707
+ #~ "idiomas integrados. Si desea agregar su propio idioma, por favor lea <a "
708
+ #~ "href=\"%s#customization\" target=\"_blank\">esta guía</a>.</em>"
709
+
710
+ #~ msgid ""
711
+ #~ "<em><strong>Note:</strong> Now you may wonder, why put the comment in the "
712
+ #~ "spam queue? The benefit is Akismet will be able to mark the comment as "
713
+ #~ "False Positive, and thus will not possibly block that comment in the "
714
+ #~ "future. However, it is best to just put the comment in moderation queue "
715
+ #~ "as next time Akismet will put such comment in moderation queue "
716
+ #~ "immediately without the need of a CAPTCHA.</em>"
717
+ #~ msgstr ""
718
+ #~ "<em><strong>Nota:</strong> Ahora usted puede preguntarse, ¿por qué poner "
719
+ #~ "el comentario en la cola de spam? El beneficio de esto es que Akismet "
720
+ #~ "será capaz de marcar el comentario como Falso Positivo, y por lo tanto no "
721
+ #~ "será posible que bloqueé el comentario en el futuro. Sin embargo, es "
722
+ #~ "mejor sólo poner el comentario en la cola de moderación ya que la próxima "
723
+ #~ "vez Akismet pondrá esos comentarios en la cola de moderación "
724
+ #~ "inmediatamente sin la necesidad de un CAPTCHA.</em>"
725
+
726
+ #~ msgid ""
727
+ #~ "<em><strong>Note:</strong> The four built-in captcha themes will look OK "
728
+ #~ "in most WordPress themes; However, some times it is better to control how "
729
+ #~ "reCAPTCHA looks using CSS. Please read <a href=\"%s#customization\" "
730
+ #~ "target=\"_blank\">this guide</a> if you would like to do so.</em>"
731
+ #~ msgstr ""
732
+ #~ "<em><strong>Nota:</strong> Los cuatro temas integrados de captcha se "
733
+ #~ "verán bien en la mayoría de temas de WordPress, sin embargo, a veces es "
734
+ #~ "mejor controlar la forma en reCAPTCHA se luce haciendo uso de CSS. Por "
735
+ #~ "favor lea <a href=\"%s#customization\" target=\"_blank\">esta guía</a> si "
736
+ #~ "desea hacerlo."
737
+
738
+ #~ msgid ""
739
+ #~ "<em>Integrate with Akismet for better end-user experience. reCAPTCHA is "
740
+ #~ "optional and <strong>NO</strong> spam comment will be added to the spam/"
741
+ #~ "moderation queue, except likely legitimate comments. This makes the task "
742
+ #~ "of identifying sincere comments much easier. This integration is "
743
+ #~ "currently in beta stage.</em>"
744
+ #~ msgstr ""
745
+ #~ "<em>La integración con Akismet mejora la experiencia del usuario final. "
746
+ #~ "reCAPTCHA es opcional y <strong>NINGÚN</strong> comentario de spam será "
747
+ #~ "añadido a la cola de spam/moderación, excepto los comentarios legítimos. "
748
+ #~ "Esto hace que la tarea de identificar los comentarios sinceros sea mucho "
749
+ #~ "más fácil. Esta integración se encuentra actualmente en fase beta.</em>"
750
+
751
+ #~ msgid ""
752
+ #~ "<em>This section allows you to determine when to show reCAPTCHA and how "
753
+ #~ "this plugin reacts to errors.</em>"
754
+ #~ msgstr ""
755
+ #~ "<em>Esta sección le permite a usted determinar cuando mostrar reCAPTCHA y "
756
+ #~ "cómo este plugin reacciona a los errores.</em>"
757
+
758
+ #~ msgid ""
759
+ #~ "<strong>ERROR</strong>: Captcha response is either empty or incorrect."
760
+ #~ msgstr ""
761
+ #~ "<strong>ERROR</strong>: La respuesta de captcha está vacía o es "
762
+ #~ "incorrecta."
763
+
764
+ #~ msgid "<strong>ERROR</strong>: Unknown captcha error."
765
+ #~ msgstr "<strong>ERROR</strong>: Error de captcha desconocido."
766
+
767
+ #~ msgid ""
768
+ #~ "API key(s) missing. Please get an API key from <a href='https://www."
769
+ #~ "google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/"
770
+ #~ "create</a> (free!)"
771
+ #~ msgstr ""
772
+ #~ "Faltan las claves de la API. Por favor obtenga una clave de la API de <a "
773
+ #~ "href='https://www.google.com/recaptcha/admin/create'>https://www.google."
774
+ #~ "com/recaptcha/admin/create</a> (es gratuito!)"
775
+
776
+ #~ msgid ""
777
+ #~ "Basically, this should be 4 if you place the captcha before the textarea, "
778
+ #~ "and 5 if you put it after."
779
+ #~ msgstr ""
780
+ #~ "Básicamente, este debe ser de 4 si se coloca el antes del área de texto, "
781
+ #~ "y 5 si lo pone después."
782
+
783
+ #~ msgid "Choose a theme"
784
+ #~ msgstr "Elija un tema"
785
+
786
+ #~ msgid "Contact"
787
+ #~ msgstr "contacto"
788
+
789
+ #~ msgid "Development Log"
790
+ #~ msgstr "Desarrollo Entrar"
791
+
792
+ #~ msgid "Dutch"
793
+ #~ msgstr "Holandés"
794
+
795
+ #~ msgid "English"
796
+ #~ msgstr "Inglés"
797
+
798
+ #~ msgid "Enter the numbers you hear:"
799
+ #~ msgstr "Ingrese los números que escuche:"
800
+
801
+ #~ msgid "Enter the two words in the box:"
802
+ #~ msgstr "Escribe las 2 palabras:"
803
+
804
+ #~ msgid "Follow me on Twitter!"
805
+ #~ msgstr "Sígueme en Twitter!"
806
+
807
+ #~ msgid "French"
808
+ #~ msgstr "Francés"
809
+
810
+ #~ msgid "Frequently Asked Questions"
811
+ #~ msgstr "Preguntas más frecuentes"
812
+
813
+ #~ msgid "German"
814
+ #~ msgstr "Alemán"
815
+
816
+ #~ msgid "Got a problem? Send me a feedback!"
817
+ #~ msgstr "Tienes un problema? Envíame un feedback!"
818
+
819
+ #~ msgid "Latest updates from BetterWP.net!"
820
+ #~ msgstr "Actualizaciones más recientes de BetterWP.net!"
821
+
822
+ #~ msgid "Load CSS, JS selectively?"
823
+ #~ msgstr "¿Leer CSS, JS selectivamente?"
824
+
825
+ #~ msgid "Portuguese"
826
+ #~ msgstr "Portugués"
827
+
828
+ #~ msgid "Public Key"
829
+ #~ msgstr "Clave Pública"
830
+
831
+ #~ msgid "Put comment in spam queue"
832
+ #~ msgstr "Poner el comentario en la cola de spam"
833
+
834
+ #~ msgid "Russian"
835
+ #~ msgstr "Ruso"
836
+
837
+ #~ msgid "Spanish"
838
+ #~ msgstr "Español"
839
+
840
+ #~ msgid "This is only useful when you do not use any minify or cache plugin."
841
+ #~ msgstr ""
842
+ #~ "Esto es útil solamente cuando usted no usa ningún plugin de minify o "
843
+ #~ "cache."
844
 
845
+ #~ msgid "This plugin will be"
846
+ #~ msgstr "Este plugin estará"
847
+
848
+ #~ msgid ""
849
+ #~ "This stylesheet is used to style the custom theme as well as the "
850
+ #~ "registration page. You can disable this or add appropriate filters to use "
851
+ #~ "your own."
852
+ #~ msgstr ""
853
+ #~ "Esta hoja de estilos se usa para personalizar el tema así como la página "
854
+ #~ "de registro. Usted puede desactivar esto o añadir los filtros apropiados "
855
+ #~ "para utilizar los suyos propios."
856
+
857
+ #~ msgid ""
858
+ #~ "To use reCAPTCHA you must get an API key from <a href='https://www.google."
859
+ #~ "com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/"
860
+ #~ "create</a>"
861
+ #~ msgstr ""
862
+ #~ "Para usar reCAPTCHA debe obtener una clave de API de <a href='https://www."
863
+ #~ "google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/"
864
+ #~ "create</a>"
865
+
866
+ #~ msgid "Turkish"
867
+ #~ msgstr "Turco"
868
+
869
+ #~ msgid "What is reCAPTCHA?"
870
+ #~ msgstr "¿Qué es re CAPTCHA?"
871
+
872
+ #~ msgid "You do not have sufficient permissions to access this page."
873
+ #~ msgstr "Usted no tiene permisos suficientes para acceder a esta página."
874
+
875
+ #~ msgid "enabled for registration page."
876
+ #~ msgstr "habilitado para la página de registro."
877
 
878
  #~ msgid "log"
879
  #~ msgstr "blog"
880
+
881
+ #~ msgid ""
882
+ #~ "reCAPTCHA is a free CAPTCHA service that helps to digitize books, "
883
+ #~ "newspapers and old time radio shows. You can read more about reCAPTCHA <a "
884
+ #~ "href=\"http://www.google.com/recaptcha/learnmore\" target=\"_blank"
885
+ #~ "\">here</a>."
886
+ #~ msgstr ""
887
+ #~ "reCAPTCHA es un servicio gratuito de CAPTCHA que ayuda a digitalizar "
888
+ #~ "libros, periódicos y viejos programas de radio. Puedes leer más acerca de "
889
+ #~ "reCAPTCHA <a href=\"http://www.google.com/recaptcha/learnmore\" target="
890
+ #~ "\"_blank\">aquí</a>."
891
+
892
+ #~ msgid "when show the normal error page with no redirection."
893
+ #~ msgstr "cuando muestra la página de error normal sin redirección."
languages/bwp-recaptcha-fr_FR.mo CHANGED
Binary file
languages/bwp-recaptcha-fr_FR.po CHANGED
@@ -1,26 +1,26 @@
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: BWP reCAPTCHA\n"
4
- "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: 2014-01-08 17:11+0700\n"
6
- "PO-Revision-Date: 2014-06-30 11:00+0700\n"
7
  "Last-Translator: Khang Minh <contact@betterwp.net>\n"
8
  "Language-Team: \n"
9
- "Language: en\n"
10
  "MIME-Version: 1.0\n"
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
  "Plural-Forms: nplurals=2; plural=n != 1;\n"
14
- "X-Poedit-SourceCharset: utf-8\n"
15
  "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;"
16
  "_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n"
17
  "X-Poedit-Basepath: .\n"
18
  "X-Textdomain-Support: yes\n"
19
- "X-Generator: Poedit 1.6.5\n"
20
  "X-Poedit-SearchPath-0: .\n"
21
 
22
  # @ bwp-recaptcha
23
- #: includes/class-bwp-framework.php:178
24
  #, php-format
25
  msgid ""
26
  "%s requires WordPress <strong>%s</strong> or higher and PHP <strong>%s</"
@@ -32,682 +32,994 @@ msgstr ""
32
  "à jour votre logiciel. Veuillez désactiver cette extension."
33
 
34
  # @ bwp-recaptcha
35
- #: includes/class-bwp-framework.php:190
36
- msgid "Development Log"
37
- msgstr "Historique des développements"
38
 
39
  # @ bwp-recaptcha
40
- #: includes/class-bwp-framework.php:190
41
- msgid "Frequently Asked Questions"
42
- msgstr "Questions fréquemment posées"
 
 
 
 
 
43
 
44
  # @ bwp-recaptcha
45
- #: includes/class-bwp-framework.php:190
46
- msgid "FAQ"
47
- msgstr "FAQ"
 
 
 
 
48
 
49
  # @ bwp-recaptcha
50
- #: includes/class-bwp-framework.php:190
51
- msgid "Got a problem? Send me a feedback!"
52
- msgstr "Un problème ? Envoyez-moi un retour !"
 
 
53
 
54
  # @ bwp-recaptcha
55
- #: includes/class-bwp-framework.php:190
56
- msgid "Contact"
57
- msgstr "Contact"
 
 
 
 
 
 
 
 
 
58
 
59
  # @ bwp-recaptcha
60
- #: includes/class-bwp-framework.php:197
 
 
 
 
61
  msgid ""
62
- "You can buy me some special coffees if you appreciate my work, thank you!"
63
  msgstr ""
64
- "Vous pouvez m'acheter des cafés spéciaux si vous appréciez mon travail, je "
65
- "vous remercie !"
66
 
67
- #: includes/class-bwp-framework.php:211
68
- msgid "Donate to "
69
- msgstr "Faire un don à"
 
 
 
 
 
 
 
70
 
71
  # @ bwp-recaptcha
72
- #: includes/class-bwp-framework.php:213
73
- msgid "One cup $5.00"
74
- msgstr "Une tasse $5.00"
 
 
 
 
 
 
 
 
 
75
 
76
  # @ bwp-recaptcha
77
- #: includes/class-bwp-framework.php:214
78
- msgid "Two cups $10.00"
79
- msgstr "Deux tasses $10.00"
 
 
 
 
 
80
 
81
  # @ bwp-recaptcha
82
- #: includes/class-bwp-framework.php:215
83
- msgid "Five cups! $25.00"
84
- msgstr "Cinq tasses ! $25.00"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
  # @ bwp-recaptcha
87
- #: includes/class-bwp-framework.php:216
88
- msgid "One LL-cup!!! $50.00"
89
- msgstr "Une grande tasse !!! $50.00"
90
 
91
  # @ bwp-recaptcha
92
- #: includes/class-bwp-framework.php:217
93
- msgid "... or any amount!"
94
- msgstr "... ou tout montant !"
95
 
96
  # @ bwp-recaptcha
97
- #: includes/class-bwp-framework.php:232
98
- msgid "Latest updates from BetterWP.net!"
99
- msgstr "Dernières mises à jour de BetterWP.net !"
100
 
101
  # @ bwp-recaptcha
102
- #: includes/class-bwp-framework.php:233
103
- msgid "Follow me on Twitter!"
104
- msgstr "Suivez-moi sur Twitter !"
 
 
 
 
105
 
106
- #: includes/class-bwp-framework.php:243
107
- msgid "This Plugin is Proudly Sponsored By"
108
- msgstr "Cette extension est fièrement soutenue par "
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
  # @ bwp-recaptcha
111
- #: includes/class-bwp-framework.php:260
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  #, php-format
113
- msgid "You are using version %s!"
114
- msgstr "Vous utilisez la version %s !"
115
 
116
- # @ default
117
- #: includes/class-bwp-framework.php:396
118
- msgid "Settings"
119
- msgstr "Réglages"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
 
121
  # @ bwp-recaptcha
122
- #: includes/class-bwp-recaptcha.php:44
123
  msgid "Get another challenge"
124
  msgstr "Obtenir un autre défi"
125
 
126
  # @ bwp-recaptcha
127
- #: includes/class-bwp-recaptcha.php:45
128
  msgid "Get audio reCAPTCHA"
129
  msgstr "Obtenir un reCAPTCHA audio"
130
 
131
  # @ bwp-recaptcha
132
- #: includes/class-bwp-recaptcha.php:46
133
  msgid "Get image reCAPTCHA"
134
  msgstr "Obtenir une image reCAPTCHA"
135
 
 
 
 
 
136
  # @ bwp-recaptcha
137
- #: includes/class-bwp-recaptcha.php:47
138
- msgid "About reCAPTCHA"
139
- msgstr "Au sujet de reCAPTCHA"
 
140
 
141
  # @ bwp-recaptcha
142
- #: includes/class-bwp-recaptcha.php:51
143
- msgid "Enter the two words in the box:"
144
- msgstr "Entrez les deux mots dans la boîte :"
145
 
146
  # @ bwp-recaptcha
147
- #: includes/class-bwp-recaptcha.php:52
148
- msgid "Enter the numbers you hear:"
149
- msgstr "Entrez les chiffres que vous entendez :"
 
150
 
151
  # @ bwp-recaptcha
152
- #: includes/class-bwp-recaptcha.php:132
 
 
 
 
 
153
  msgid ""
154
- "<strong>ERROR:</strong> Incorrect or empty reCAPTCHA response, please try "
155
- "again."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  msgstr ""
157
  "<strong>ERREUR :</strong> réponse reCAPTCHA incorrecte ou vide. Veuillez ré-"
158
  "essayer."
159
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  # @ bwp-recaptcha
161
- #: includes/class-bwp-recaptcha.php:133
162
- #, php-format
163
- msgid ""
164
- "Error: Incorrect or empty reCAPTCHA response, please click the back button "
165
- "on your browser's toolbar or click on %s to go back."
 
 
166
  msgstr ""
167
- "Erreur : la réponse reCAPTCHA est incorrecte ou vide. Veuillez cliquer sur "
168
- "le bouton de retour sur la barre d'outils de votre navigateur ou cliquez sur "
169
- "%s pour revenir en arrière."
170
 
171
  # @ bwp-recaptcha
172
- #: includes/class-bwp-recaptcha.php:155 includes/class-bwp-recaptcha.php:313
173
- msgid "General Options"
174
- msgstr "Options générales"
175
 
176
  # @ bwp-recaptcha
177
- #: includes/class-bwp-recaptcha.php:156 includes/class-bwp-recaptcha.php:314
178
  msgid "Theme Options"
179
  msgstr "Options du thème"
180
 
181
  # @ bwp-recaptcha
182
- #: includes/class-bwp-recaptcha.php:159
183
- msgid "English"
184
- msgstr "Anglais"
185
-
186
- # @ bwp-recaptcha
187
- #: includes/class-bwp-recaptcha.php:160
188
- msgid "Dutch"
189
- msgstr "Hollandais"
190
 
191
- # @ bwp-recaptcha
192
- #: includes/class-bwp-recaptcha.php:161
193
- msgid "French"
194
- msgstr "Français"
 
 
195
 
196
- # @ bwp-recaptcha
197
- #: includes/class-bwp-recaptcha.php:162
198
- msgid "German"
199
- msgstr "Allemand"
200
 
201
  # @ bwp-recaptcha
202
- #: includes/class-bwp-recaptcha.php:163
203
- msgid "Portuguese"
204
- msgstr "Portugais"
 
 
205
 
206
- # @ bwp-recaptcha
207
- #: includes/class-bwp-recaptcha.php:164
208
- msgid "Russian"
209
- msgstr "Russe"
 
210
 
211
- # @ bwp-recaptcha
212
- #: includes/class-bwp-recaptcha.php:165
213
- msgid "Spanish"
214
- msgstr "Espagnol"
 
215
 
216
- # @ bwp-recaptcha
217
- #: includes/class-bwp-recaptcha.php:166
218
- msgid "Turkish"
219
- msgstr "Turque"
220
 
221
- # @ bwp-recaptcha
222
- #: includes/class-bwp-recaptcha.php:170
223
- msgid "Read Profile"
224
- msgstr "Lire le profil"
 
 
 
225
 
226
- # @ bwp-recaptcha
227
- #: includes/class-bwp-recaptcha.php:171
228
- msgid "Manage Options"
229
- msgstr "Gérer les options"
230
 
231
- # @ bwp-recaptcha
232
- #: includes/class-bwp-recaptcha.php:311
233
- msgid "Better WordPress reCAPTCHA"
234
- msgstr "Better WordPress reCAPTCHA"
235
 
236
  # @ bwp-recaptcha
237
- #: includes/class-bwp-recaptcha.php:313
238
- msgid "BWP reCAPTCHA General Options"
239
- msgstr "Options générales de BWP reCAPTCHA"
240
 
241
- # @ bwp-recaptcha
242
- #: includes/class-bwp-recaptcha.php:314
243
- msgid "BWP reCAPTCHA Theme Options"
244
- msgstr "Options du thème de BWP reCAPTCHA"
245
 
246
- # @ default
247
- #: includes/class-bwp-recaptcha.php:347
248
- msgid "You do not have sufficient permissions to access this page."
249
  msgstr ""
250
- "Vous ne disposez pas des autorisations requises pour accéder à cette page."
251
 
252
- # @ bwp-recaptcha
253
- #: includes/class-bwp-recaptcha.php:366
254
- msgid "What is reCAPTCHA?"
255
- msgstr "Qu'est-ce que reCAPTCHA ?"
256
 
257
  # @ bwp-recaptcha
258
- #: includes/class-bwp-recaptcha.php:367
259
- msgid "This plugin will be"
260
- msgstr "Cette extension sera"
 
 
 
 
 
 
 
261
 
262
- #: includes/class-bwp-recaptcha.php:368
263
  msgid "Use main site's keys"
264
  msgstr "Utiliser les clés du site principal"
265
 
266
  # @ bwp-recaptcha
267
- #: includes/class-bwp-recaptcha.php:369
268
- msgid "Public Key"
269
- msgstr "Clé publique"
270
-
271
- # @ bwp-recaptcha
272
- #: includes/class-bwp-recaptcha.php:370
273
- msgid "Private Key"
274
- msgstr "Clé privée"
275
 
276
- # @ bwp-recaptcha
277
- #: includes/class-bwp-recaptcha.php:371
278
- msgid "Visibility Options (applied to comment forms)"
279
- msgstr "Options de visibilité (appliquées aux formulaires de commentaire)"
280
 
281
- # @ bwp-recaptcha
282
- #: includes/class-bwp-recaptcha.php:372
283
- msgid "Hide the CAPTCHA for"
284
- msgstr "Cacher le CAPTCHA pour"
285
 
286
- # @ bwp-recaptcha
287
- #: includes/class-bwp-recaptcha.php:373
288
- msgid "If wrong or empty response"
289
- msgstr "En cas de réponse erronée ou vide"
290
 
291
- # @ bwp-recaptcha
292
- #: includes/class-bwp-recaptcha.php:374 includes/class-bwp-recaptcha.php:375
293
- msgid "Show the error message"
294
- msgstr "Montrer le message d'erreur"
295
 
296
  # @ bwp-recaptcha
297
- #: includes/class-bwp-recaptcha.php:376
298
- msgid "Akismet Integration (applied to comment forms)"
299
- msgstr "Intégration Akismet (appliquée aux formulaires de commentaire)"
300
 
301
  # @ bwp-recaptcha
302
- #: includes/class-bwp-recaptcha.php:377
303
- msgid "Integrate with Akismet?"
304
- msgstr "Intégrer avec Akismet ?"
 
 
 
 
305
 
306
  # @ bwp-recaptcha
307
- #: includes/class-bwp-recaptcha.php:378
308
- msgid "If correct CAPTCHA response"
309
- msgstr "En cas de réponse correcte du CAPTCHA"
 
310
 
311
  # @ bwp-recaptcha
312
- #: includes/class-bwp-recaptcha.php:382
313
  msgid ""
314
- "reCAPTCHA is a free CAPTCHA service that helps to digitize books, newspapers "
315
- "and old time radio shows. You can read more about reCAPTCHA <a href=\"http://"
316
- "www.google.com/recaptcha/learnmore\" target=\"_blank\">here</a>."
317
  msgstr ""
318
- "reCAPTCHA est un service gratuit de CAPTCHA qui permet de numériser des "
319
- "livres, des journaux et de vieilles émissions de radio. Vous pouvez en "
320
- "savoir plus au sujet de reCAPTCHA <a href=\"http://www.google.com/recaptcha/"
321
- "learnmore\" target=\"_blank\">ici</a>."
322
 
323
  # @ bwp-recaptcha
324
- #: includes/class-bwp-recaptcha.php:383
325
- msgid ""
326
- "<em>This section allows you to determine when to show reCAPTCHA and how this "
327
- "plugin reacts to errors.</em>"
328
  msgstr ""
329
- "<em>Cette section vous permet de déterminer quand montrer reCAPTCHA et "
330
- "comment cette extension doit réagir aux erreurs.</em>"
331
-
332
- # @ bwp-recaptcha
333
- #: includes/class-bwp-recaptcha.php:384
334
- msgid ""
335
- "<em>Integrate with Akismet for better end-user experience. reCAPTCHA is "
336
- "optional and <strong>NO</strong> spam comment will be added to the spam/"
337
- "moderation queue, except likely legitimate comments. This makes the task of "
338
- "identifying sincere comments much easier. This integration is currently in "
339
- "beta stage.</em>"
340
- msgstr ""
341
- "<em>À intégrer avec Akismet pour une meilleure expérience utilisateur : "
342
- "reCAPTCHA est facultatif et <strong>AUCUN</strong> commentaire de type spam "
343
- "ne sera ajouté à la file de modération des spam, sauf les commentaires "
344
- "susceptibles d'être légitimes. Cela rend la tâche d'identification des "
345
- "commentaires sincères beaucoup plus facile. Cette intégration est "
346
- "actuellement en phase bêta.</em>"
347
-
348
- # @ bwp-recaptcha
349
- #: includes/class-bwp-recaptcha.php:400
350
- msgid "Redirect commenter back to the comment form"
351
- msgstr "Faire revenir le rédacteur du commentaire au formulaire de commentaire"
352
 
353
  # @ bwp-recaptcha
354
- #: includes/class-bwp-recaptcha.php:401
355
- msgid "Show an error page just like WordPress does"
356
- msgstr "Afficher une page d'erreur, de la même façon que WordPress"
357
 
358
- # @ bwp-recaptcha
359
- #: includes/class-bwp-recaptcha.php:404
360
- msgid "Approve comment immediately"
361
- msgstr "Approuver le commentaire immédiatement"
362
 
363
- # @ bwp-recaptcha
364
- #: includes/class-bwp-recaptcha.php:405
365
- msgid "Hold comment in moderation queue"
366
- msgstr "Retenir le commentaire en file d'attente de modération"
367
 
368
  # @ bwp-recaptcha
369
- #: includes/class-bwp-recaptcha.php:406
370
- msgid "Put comment in spam queue"
371
- msgstr "Mettre le commentaire dans la file de spam"
 
372
 
373
  # @ bwp-recaptcha
374
- #: includes/class-bwp-recaptcha.php:410
375
- msgid "enabled for comment forms."
 
376
  msgstr "activée pour les formulaires de commentaire."
377
 
378
  # @ bwp-recaptcha
379
- #: includes/class-bwp-recaptcha.php:411
380
- msgid "enabled for registration form (user/site registration)."
381
- msgstr ""
382
- "activée pour le formulaire d'inscription (inscription site/utilisateur)."
383
 
384
  # @ bwp-recaptcha
385
- #: includes/class-bwp-recaptcha.php:412
386
- msgid "enabled for login form."
387
- msgstr "activée pour le formulaire de connexion."
 
388
 
389
  # @ bwp-recaptcha
390
- #: includes/class-bwp-recaptcha.php:413
391
  msgid "registered users <em>(even without any capabilities)</em>."
392
  msgstr "les utilisateurs enregistrés <em>(même sans aucun droit)</em>."
393
 
394
  # @ bwp-recaptcha
395
- #: includes/class-bwp-recaptcha.php:414
 
 
 
 
 
396
  msgid "users who can"
397
  msgstr "les utilisateurs qui peuvent"
398
 
399
  # @ bwp-recaptcha
400
- #: includes/class-bwp-recaptcha.php:415
401
  msgid "visitors who have at least"
402
  msgstr "les visiteurs qui ont au moins"
403
 
404
  # @ bwp-recaptcha
405
- #: includes/class-bwp-recaptcha.php:416
406
- msgid ""
407
- "reCAPTCHA will only show when Akismet identifies a comment as spam. Highly "
408
- "recommended if you do not want to force your visitors to type the captcha "
409
- "every time."
410
- msgstr ""
411
- "reCAPTCHA s'affichera seulement lorsque Akismet identifiera un commentaire "
412
- "comme spam. Vivement recommandé si vous ne voulez pas forcer vos visiteurs à "
413
- "taper le captcha à chaque fois."
414
-
415
- #: includes/class-bwp-recaptcha.php:417
416
- msgid "uncheck to use different key pairs for this site."
417
- msgstr "décocher pour utiliser des paires de clés différentes pour ce site."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
418
 
419
- # @ bwp-recaptcha
420
- #: includes/class-bwp-recaptcha.php:420
421
- msgid "A public key used to request captchas from reCAPTCHA server."
422
- msgstr ""
423
- "Une clé publique utilisée pour demander des captchas à partir du serveur "
424
- "reCAPTCHA."
425
 
426
  # @ bwp-recaptcha
427
- #: includes/class-bwp-recaptcha.php:421
428
- msgid "A private (secret) key used to authenticate user's response."
429
- msgstr ""
430
- "Une clé privée (secrète) utilisée pour authentifier la réponse de "
431
- "l'utilisateur."
 
 
 
432
 
433
  # @ bwp-recaptcha
434
- #: includes/class-bwp-recaptcha.php:422
435
- msgid ""
436
- "when redirect commenter back to the comment form (or when used in other "
437
- "forms such as contact forms)."
438
- msgstr ""
439
- "lorsque le rédacteur du commentaire est redirigé vers le formulaire de "
440
- "commentaire (ou pour une utilisation dans d'autres formulaires tels que ceux "
441
- "de contact)."
442
 
443
  # @ bwp-recaptcha
444
- #: includes/class-bwp-recaptcha.php:423
445
- msgid "when show the normal error page with no redirection."
446
- msgstr "lorsque la page d'erreur normale est affichée sans redirection."
447
 
448
  # @ bwp-recaptcha
449
- #: includes/class-bwp-recaptcha.php:424
450
- msgid "approved comment(s)."
451
- msgstr "commentaire(s) approuvé(s)."
452
 
453
  # @ bwp-recaptcha
454
- #: includes/class-bwp-recaptcha.php:427
455
- msgid ""
456
- "<em><strong>Note:</strong> For this plugin to work, you will need a pair of "
457
- "API keys (public and private), which is available for free <a href=\"https://"
458
- "www.google.com/recaptcha/admin/create\" target=\"_blank\">here</a>. Once you "
459
- "have created those two keys for this domain, simply paste them below.</em>"
460
- msgstr ""
461
- "<em><strong>Remarque :</strong> Pour que cette extension fonctionne, vous "
462
- "aurez besoin d'une paire de clés API (publique et privée), qui sont "
463
- "disponibles gratuitement <a href=\"https://www.google.com/recaptcha/admin/"
464
- "create\" target=\"_blank\">ici</a>. Une fois que vous aurez créé ces deux "
465
- "clés pour ce domaine, copiez-les simplement ci-dessous.</em>"
466
 
467
  # @ bwp-recaptcha
468
- #: includes/class-bwp-recaptcha.php:428
469
- msgid ""
470
- "<em><strong>Note:</strong> Now you may wonder, why put the comment in the "
471
- "spam queue? The benefit is Akismet will be able to mark the comment as False "
472
- "Positive, and thus will not possibly block that comment in the future. "
473
- "However, it is best to just put the comment in moderation queue as next time "
474
- "Akismet will put such comment in moderation queue immediately without the "
475
- "need of a CAPTCHA.</em>"
476
- msgstr ""
477
- "<em><strong>Remarque :</strong> Maintenant, vous vous demander peut-être "
478
- "pourquoi mettre le commentaire dans la file d'attente de spam ? L'avantage "
479
- "est qu'Akismet sera en mesure de marquer le commentaire comme faux positif, "
480
- "et donc évitera que ce commentaire soit bloqué par la suite. Cependant, il "
481
- "est préférable de mettre simplement le commentaire dans la file d'attente de "
482
- "modération pour que la prochaine fois Akismet mette immédiatement de tels "
483
- "commentaires en file d'attente de modération sans avoir besoin d'un CAPTCHA."
484
- "</em>"
485
-
486
- # @ bwp-recaptcha
487
- #: includes/class-bwp-recaptcha.php:457
488
- msgid "Choose a theme"
489
- msgstr "Choisissez un thème"
490
-
491
- # @ bwp-recaptcha
492
- #: includes/class-bwp-recaptcha.php:458
493
- msgid "Use CSS provided by this plugin?"
494
- msgstr "Utiliser une feuille de style CSS fournie par cette extension ?"
495
 
496
  # @ bwp-recaptcha
497
- #: includes/class-bwp-recaptcha.php:459
498
- msgid "Load CSS, JS selectively?"
499
- msgstr "Charger sélectivement une CSS ou un JS ?"
500
 
501
  # @ bwp-recaptcha
502
- #: includes/class-bwp-recaptcha.php:460
503
- msgid "Choose a language for built-in themes"
504
- msgstr "Choisissez une langue pour les thèmes intégrés"
505
 
506
  # @ bwp-recaptcha
507
- #: includes/class-bwp-recaptcha.php:461
508
- msgid "Tabindex for captcha input field"
509
- msgstr "Indice de position pour le champ d'entrée du captcha"
510
 
511
  # @ bwp-recaptcha
512
- #: includes/class-bwp-recaptcha.php:462
513
- msgid "Preview your reCAPTCHA"
514
- msgstr "Aperçu de votre reCAPTCHA"
515
 
516
  # @ bwp-recaptcha
517
- #: includes/class-bwp-recaptcha.php:466
518
- msgid ""
519
- "<em>Below you will see how your reCAPTCHA will look. Note that this might "
520
- "differ on your actual pages.<br /></em>"
521
- msgstr ""
522
- "<em>Ci-dessous vous verrez à quoi votre reCAPTCHA ressemblera. Notez que ce "
523
- "pourrait être un peu différent sur vos pages réelles.<br /></em>"
524
 
525
  # @ bwp-recaptcha
526
- #: includes/class-bwp-recaptcha.php:470
527
- msgid "Default Theme (Red)"
528
- msgstr "Thème par défaut (rouge)"
529
 
530
  # @ bwp-recaptcha
531
- #: includes/class-bwp-recaptcha.php:471
532
- msgid "White Theme"
533
- msgstr "Thème blanc"
534
 
535
  # @ bwp-recaptcha
536
- #: includes/class-bwp-recaptcha.php:472
537
- msgid "Black Theme"
538
- msgstr "Thème noir"
539
 
540
  # @ bwp-recaptcha
541
- #: includes/class-bwp-recaptcha.php:473
542
- msgid "Clean Theme"
543
- msgstr "Thème transparent"
544
 
545
  # @ bwp-recaptcha
546
- #: includes/class-bwp-recaptcha.php:474
547
- msgid "Custom Theme (use CSS)"
548
- msgstr "Thème particulier (utiliser les CSS)"
549
 
550
  # @ bwp-recaptcha
551
- #: includes/class-bwp-recaptcha.php:479
552
- msgid ""
553
- "This stylesheet is used to style the custom theme as well as the "
554
- "registration page. You can disable this or add appropriate filters to use "
555
- "your own."
556
- msgstr ""
557
- "Cette feuille de style est utilisée pour le style du thème personnalisé "
558
- "ainsi que pour la page d'inscription. Vous pouvez la désactiver ou ajouter "
559
- "des filtres appropriés pour utiliser la vôtre."
560
 
561
  # @ bwp-recaptcha
562
- #: includes/class-bwp-recaptcha.php:480
563
- msgid "This is only useful when you do not use any minify or cache plugin."
564
- msgstr ""
565
- "Ce n'est utile que lorsque vous n'utilisez aucune extension de réduction "
566
- "(minify) ou de cache."
567
 
568
  # @ bwp-recaptcha
569
- #: includes/class-bwp-recaptcha.php:483
570
- msgid ""
571
- "Basically, this should be 4 if you place the captcha before the textarea, "
572
- "and 5 if you put it after. Set to 0 to disable."
573
- msgstr ""
574
- "Fondamentalement, cela devrait être 4 si vous placez le captcha avant la "
575
- "zone de saisie du texte, et 5 si vous le mettez après. Indiquer 0 pour "
576
- "désactiver."
577
 
578
  # @ bwp-recaptcha
579
- #: includes/class-bwp-recaptcha.php:486
580
- #, php-format
581
- msgid ""
582
- "<em><strong>Note:</strong> The four built-in captcha themes will look OK in "
583
- "most WordPress themes; However, some times it is better to control how "
584
- "reCAPTCHA looks using CSS. Please read <a href=\"%s#customization\" target="
585
- "\"_blank\">this guide</a> if you would like to do so.</em>"
586
- msgstr ""
587
- "<em><strong>Remarque :</strong> Les quatre thèmes captcha intégrés auront "
588
- "une apparence satisfaisante avec la plupart des thèmes WordPress. Cependant, "
589
- "parfois il est préférable de contrôler l'apparence du reCAPTCHA à l'aide de "
590
- "feuilles de style CSS. Veuillez lire <a href=\"%s#customization\" target="
591
- "\"_blank\">ce quide</a> si vous souhaitez le faire.</em>"
592
 
593
  # @ bwp-recaptcha
594
- #: includes/class-bwp-recaptcha.php:487
595
- #, php-format
596
- msgid ""
597
- "<em><strong>Note:</strong> Above you can select some built-in languages. If "
598
- "you would like to add your own language, please read <a href="
599
- "\"%s#customization\" target=\"_blank\">this guide</a>.</em>"
600
- msgstr ""
601
- "<em><strong>Remarque :</strong> Ci-dessus vous pouvez sélectionner certaines "
602
- "langues intégrées. Si vous souhaitez ajouter votre propre langue, veuillez "
603
- "lire <a href=\"%s#customization\" target=\"_blank\">ce guide</a>.</em>"
604
-
605
- #: includes/class-bwp-recaptcha.php:540
606
- msgid "All options have been saved."
607
- msgstr "Toutes les options ont été sauvegardées."
608
 
609
- # @ default
610
- #: includes/class-bwp-recaptcha.php:546
611
- msgid "Warning"
612
- msgstr "Avertissement"
613
 
614
  # @ bwp-recaptcha
615
- #: includes/class-bwp-recaptcha.php:546
616
- msgid ""
617
- "API key(s) missing. Please get an API key from <a href='https://www.google."
618
- "com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</"
619
- "a> (free!)"
620
- msgstr ""
621
- "Clé(s) API manquante(s). Veuillez obtenir une clé API à partir de <a "
622
- "href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/"
623
- "recaptcha/admin/create</a> (Gratuit !)"
624
-
625
- # @ default
626
- #: includes/class-bwp-recaptcha.php:548
627
- msgid "Notice"
628
- msgstr "Avis"
629
 
630
  # @ bwp-recaptcha
631
- #: includes/class-bwp-recaptcha.php:548
632
- msgid ""
633
- "You are enabling Akismet integration but Akismet is not currently active. "
634
- "Please activate Akismet for the integration to work."
635
- msgstr ""
636
- "Vous essayez d'activer l'intégration d'Akismet mais Akismet n'est pas actif "
637
- "actuellement. Veuillez activer Akismet pour que l'intégration fonctionne."
638
 
639
  # @ bwp-recaptcha
640
- #: includes/class-bwp-recaptcha.php:671
641
- msgid "Your comment was identified as spam, please complete the CAPTCHA below:"
642
- msgstr ""
643
- "Votre commentaire a été identifié comme spam. Veuillez compléter le CAPTCHA "
644
- "ci-dessous :"
 
 
 
645
 
646
  # @ bwp-recaptcha
647
- #: includes/class-bwp-recaptcha.php:714
648
- msgid ""
649
- "To use reCAPTCHA you must get an API key from <a href='https://www.google."
650
- "com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>"
651
- msgstr ""
652
- "Pour utiliser reCAPTCHA, vous devez obtenir une clé API depuis <a "
653
- "href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/"
654
- "recaptcha/admin/create</a>"
655
-
656
- # @ default
657
- #: includes/class-bwp-recaptcha.php:763 includes/class-bwp-recaptcha.php:808
658
- msgid "<strong>ERROR</strong>: Unknown captcha error."
659
- msgstr "<strong>ERREUR</strong> : erreur captcha inconnue."
660
 
661
  # @ bwp-recaptcha
662
- #: includes/class-bwp-recaptcha.php:878
663
- msgid "this link"
664
- msgstr "ce lien"
665
 
666
  # @ bwp-recaptcha
667
- #: includes/class-bwp-recaptcha.php:880
668
- msgid ""
669
- "There is some problem with your reCAPTCHA API keys, please double check them."
670
- msgstr ""
671
- "Il ya un problème avec vos clés API pour reCAPTCHA. Veuillez les re-vérifier."
672
 
673
  # @ bwp-recaptcha
674
- #: includes/class-bwp-recaptcha.php:882
675
- msgid "Unknown error. Please contact the administrator for more info."
676
- msgstr ""
677
- "Erreur inconnue. Veuillez contacter l'administrateur pour plus "
678
- "d'informations."
679
-
680
- #: includes/class-bwp-recaptcha-cf7.php:107
681
- msgid "This reCAPTCHA tag is provided by the BWP reCAPTCHA WordPress plugin."
682
- msgstr ""
683
- "Cette balise reCAPTCHA est fournie par l'extension BWP reCAPTCHA pour "
684
- "Wordpress."
685
-
686
- #: includes/class-bwp-recaptcha-cf7.php:110
687
- msgid ""
688
- "Please refer to <a target=\"_blank\" href=\"http://betterwp.net/wordpress-"
689
- "plugins/bwp-recaptcha/#customization\">BWP reCAPTCHA's documentation </a> "
690
- "for a quick guide on how to customize the look and feel of this tag."
691
- msgstr ""
692
- "Veuillez consulter <a target=\"_blank\" href=\"http://betterwp.net/wordpress-"
693
- "plugins/bwp-recaptcha/#customization\"> la documentation de BWP reCAPTCHA </"
694
- "a> pour une présentation rapide sur comment personnaliser l'apparence de "
695
- "cette balise."
696
-
697
- #: includes/class-bwp-recaptcha-cf7.php:116
698
- msgid "Name"
699
- msgstr "Nom"
700
-
701
- #: includes/class-bwp-recaptcha-cf7.php:123
702
- msgid "Copy this code and paste it into the form left."
703
- msgstr "Copier ce code et le coller dans le formulaire restant."
704
-
705
- # @ bwp-option-page
706
- #: includes/bwp-option-page/includes/class-bwp-option-page.php:80
707
- msgid "Plugin Configurations"
708
- msgstr "Configurations de l'extension"
709
 
710
  # @ default
711
- #: includes/bwp-option-page/includes/class-bwp-option-page.php:398
712
- msgid "Save Changes"
713
- msgstr "Enregistrer les modifications"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: BWP reCAPTCHA\n"
4
+ "Report-Msgid-Bugs-To: contact@betterwp.net\n"
5
+ "POT-Creation-Date: 2016-01-12 23:47+0700\n"
6
+ "PO-Revision-Date: 2016-01-12 15:25+0700\n"
7
  "Last-Translator: Khang Minh <contact@betterwp.net>\n"
8
  "Language-Team: \n"
9
+ "Language: fr\n"
10
  "MIME-Version: 1.0\n"
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
  "Plural-Forms: nplurals=2; plural=n != 1;\n"
14
+ "X-Poedit-SourceCharset: UTF-8\n"
15
  "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;"
16
  "_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n"
17
  "X-Poedit-Basepath: .\n"
18
  "X-Textdomain-Support: yes\n"
19
+ "X-Generator: Poedit 1.8.5\n"
20
  "X-Poedit-SearchPath-0: .\n"
21
 
22
  # @ bwp-recaptcha
23
+ #: vendor/kminh/bwp-framework/src/class-bwp-version.php:32
24
  #, php-format
25
  msgid ""
26
  "%s requires WordPress <strong>%s</strong> or higher and PHP <strong>%s</"
32
  "à jour votre logiciel. Veuillez désactiver cette extension."
33
 
34
  # @ bwp-recaptcha
35
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:411
36
+ msgid "... or any amount!"
37
+ msgstr "... ou tout montant !"
38
 
39
  # @ bwp-recaptcha
40
+ #: includes/class-bwp-recaptcha.php:1006 includes/class-bwp-recaptcha.php:1101
41
+ #, fuzzy
42
+ msgid ""
43
+ "<em>Below you will see how your reCAPTCHA will look. Note that this might "
44
+ "differ on your actual pages.</em>"
45
+ msgstr ""
46
+ "<em>Ci-dessous vous verrez à quoi votre reCAPTCHA ressemblera. Notez que ce "
47
+ "pourrait être un peu différent sur vos pages réelles.<br /></em>"
48
 
49
  # @ bwp-recaptcha
50
+ #: includes/class-bwp-recaptcha.php:118
51
+ msgid ""
52
+ "<strong>ERROR:</strong> Incorrect or empty reCAPTCHA response, please try "
53
+ "again."
54
+ msgstr ""
55
+ "<strong>ERREUR :</strong> réponse reCAPTCHA incorrecte ou vide. Veuillez ré-"
56
+ "essayer."
57
 
58
  # @ bwp-recaptcha
59
+ #: includes/class-bwp-recaptcha.php:867
60
+ msgid "A private (secret) key used to authenticate user's response."
61
+ msgstr ""
62
+ "Une clé privée (secrète) utilisée pour authentifier la réponse de "
63
+ "l'utilisateur."
64
 
65
  # @ bwp-recaptcha
66
+ #: includes/class-bwp-recaptcha.php:861
67
+ msgid "A public key used to request captchas from reCAPTCHA server."
68
+ msgstr ""
69
+ "Une clé publique utilisée pour demander des captchas à partir du serveur "
70
+ "reCAPTCHA."
71
+
72
+ #: includes/class-bwp-recaptcha.php:1193
73
+ #, php-format
74
+ msgid ""
75
+ "API key(s) missing. Please get an API key from <a href=\"%1$s\">%1$s</a> "
76
+ "(free!)"
77
+ msgstr ""
78
 
79
  # @ bwp-recaptcha
80
+ #: includes/provider/v1.php:165
81
+ msgid "About reCAPTCHA"
82
+ msgstr "Au sujet de reCAPTCHA"
83
+
84
+ #: includes/class-bwp-recaptcha.php:1021 includes/class-bwp-recaptcha.php:1123
85
  msgid ""
86
+ "Add additional CSS rules to all recaptcha instances. You can edit them below."
87
  msgstr ""
 
 
88
 
89
+ #: includes/class-bwp-recaptcha.php:756
90
+ msgid ""
91
+ "Add reCAPTCHA to Contact Form 7. This only works if you have Contact Form 7 "
92
+ "activated."
93
+ msgstr ""
94
+
95
+ #: includes/class-bwp-recaptcha.php:827
96
+ msgid ""
97
+ "Add the <code>recaptcha</code> shortcode tag to your Contact Form 7 forms."
98
+ msgstr ""
99
 
100
  # @ bwp-recaptcha
101
+ #: includes/class-bwp-recaptcha.php:773
102
+ #, fuzzy
103
+ msgid "After comment field"
104
+ msgstr "Approuver le commentaire immédiatement"
105
+
106
+ #: includes/class-bwp-recaptcha.php:774
107
+ msgid "After form fields (name, email, website)"
108
+ msgstr ""
109
+
110
+ #: includes/class-bwp-recaptcha.php:819
111
+ msgid "After redirected, auto fill the comment field with previous comment."
112
+ msgstr ""
113
 
114
  # @ bwp-recaptcha
115
+ #: includes/class-bwp-recaptcha.php:708
116
+ #, fuzzy
117
+ msgid "Akismet Integration for comment form"
118
+ msgstr "Intégration Akismet (appliquée aux formulaires de commentaire)"
119
+
120
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:438
121
+ msgid "All options have been saved."
122
+ msgstr "Toutes les options ont été sauvegardées."
123
 
124
  # @ bwp-recaptcha
125
+ #: includes/class-bwp-recaptcha.php:781
126
+ msgid "Approve comment immediately"
127
+ msgstr "Approuver le commentaire immédiatement"
128
+
129
+ #: includes/class-bwp-recaptcha.php:636
130
+ msgid "Auto detected"
131
+ msgstr ""
132
+
133
+ #: includes/class-bwp-recaptcha.php:705
134
+ msgid "Auto fill comment field"
135
+ msgstr ""
136
+
137
+ #: includes/class-bwp-recaptcha.php:1114
138
+ msgid "Auto-detected"
139
+ msgstr ""
140
+
141
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:521
142
+ msgid "BWP Gems"
143
+ msgstr ""
144
+
145
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:531
146
+ msgid "BWP News"
147
+ msgstr ""
148
 
149
  # @ bwp-recaptcha
150
+ #: includes/class-bwp-recaptcha.php:595
151
+ msgid "BWP reCAPTCHA General Options"
152
+ msgstr "Options générales de BWP reCAPTCHA"
153
 
154
  # @ bwp-recaptcha
155
+ #: includes/class-bwp-recaptcha.php:604
156
+ msgid "BWP reCAPTCHA Theme Options"
157
+ msgstr "Options du thème de BWP reCAPTCHA"
158
 
159
  # @ bwp-recaptcha
160
+ #: includes/class-bwp-recaptcha.php:585
161
+ msgid "Better WordPress reCAPTCHA"
162
+ msgstr "Better WordPress reCAPTCHA"
163
 
164
  # @ bwp-recaptcha
165
+ #: includes/class-bwp-recaptcha.php:1013
166
+ msgid "Black Theme"
167
+ msgstr "Thème noir"
168
+
169
+ #: includes/class-bwp-recaptcha.php:703
170
+ msgid "Captcha position"
171
+ msgstr ""
172
 
173
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:439
174
+ msgid "Check out this cool plugin"
175
+ msgstr ""
176
+
177
+ # @ bwp-recaptcha
178
+ #: includes/class-bwp-recaptcha.php:1014
179
+ msgid "Clean Theme"
180
+ msgstr "Thème transparent"
181
+
182
+ #: includes/class-bwp-recaptcha.php:787
183
+ msgid "Comment form"
184
+ msgstr ""
185
+
186
+ #: includes/class-bwp-recaptcha.php:1111
187
+ msgid "Compact"
188
+ msgstr ""
189
+
190
+ #: includes/class-bwp-recaptcha.php:711
191
+ msgid "Contact Form 7 Integration"
192
+ msgstr ""
193
+
194
+ #: includes/addons/contact-form-7/captcha-shortcode.php:205
195
+ msgid "Copy this code and paste it into the form left."
196
+ msgstr "Copier ce code et le coller dans le formulaire restant."
197
 
198
  # @ bwp-recaptcha
199
+ #: includes/class-bwp-recaptcha.php:1015
200
+ msgid "Custom Theme (use CSS)"
201
+ msgstr "Thème particulier (utiliser les CSS)"
202
+
203
+ #: includes/class-bwp-recaptcha.php:1107
204
+ msgid "Dark"
205
+ msgstr ""
206
+
207
+ # @ bwp-recaptcha
208
+ #: includes/class-bwp-recaptcha.php:1011
209
+ msgid "Default Theme (Red)"
210
+ msgstr "Thème par défaut (rouge)"
211
+
212
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:1530
213
+ msgid "Dismiss this notice."
214
+ msgstr ""
215
+
216
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:405
217
  #, php-format
218
+ msgid "Donate to %s"
219
+ msgstr "Faire un don à %s"
220
 
221
+ #: includes/class-bwp-recaptcha.php:992 includes/class-bwp-recaptcha.php:1087
222
+ msgid "Enable custom CSS"
223
+ msgstr ""
224
+
225
+ # @ bwp-recaptcha
226
+ #: includes/class-bwp-recaptcha.php:700
227
+ #, fuzzy
228
+ msgid "Enable this plugin for"
229
+ msgstr "activée pour le formulaire de connexion."
230
+
231
+ # @ bwp-recaptcha
232
+ #: includes/class-bwp-recaptcha.php:120
233
+ #, php-format
234
+ msgid ""
235
+ "Error: Incorrect or empty reCAPTCHA response, please click the back button "
236
+ "on your browser's toolbar or click on %s to go back."
237
+ msgstr ""
238
+ "Erreur : la réponse reCAPTCHA est incorrecte ou vide. Veuillez cliquer sur "
239
+ "le bouton de retour sur la barre d'outils de votre navigateur ou cliquez sur "
240
+ "%s pour revenir en arrière."
241
+
242
+ # @ bwp-recaptcha
243
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:371
244
+ msgid "FAQ"
245
+ msgstr "FAQ"
246
+
247
+ # @ bwp-recaptcha
248
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:409
249
+ msgid "Five cups! $25.00"
250
+ msgstr "Cinq tasses ! $25.00"
251
+
252
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:548
253
+ msgid "Follow"
254
+ msgstr ""
255
+
256
+ # @ bwp-recaptcha
257
+ #: includes/class-bwp-recaptcha.php:744
258
+ #, fuzzy, php-format
259
+ msgid ""
260
+ "For this plugin to work, you will need a pair of API keys, which is "
261
+ "available for free <a href=\"%s\" target=\"_blank\">here</a>. Once you have "
262
+ "created those two keys for the current domain, simply paste them below.</em>"
263
+ msgstr ""
264
+ "<em><strong>Remarque :</strong> Pour que cette extension fonctionne, vous "
265
+ "aurez besoin d'une paire de clés API (publique et privée), qui sont "
266
+ "disponibles gratuitement <a href=\"https://www.google.com/recaptcha/admin/"
267
+ "create\" target=\"_blank\">ici</a>. Une fois que vous aurez créé ces deux "
268
+ "clés pour ce domaine, copiez-les simplement ci-dessous.</em>"
269
+
270
+ #: includes/class-bwp-recaptcha.php:697
271
+ msgid "Force https"
272
+ msgstr ""
273
+
274
+ # @ bwp-recaptcha
275
+ #: includes/class-bwp-recaptcha.php:159 includes/class-bwp-recaptcha.php:596
276
+ msgid "General Options"
277
+ msgstr "Options générales"
278
 
279
  # @ bwp-recaptcha
280
+ #: includes/provider/v1.php:162
281
  msgid "Get another challenge"
282
  msgstr "Obtenir un autre défi"
283
 
284
  # @ bwp-recaptcha
285
+ #: includes/provider/v1.php:163
286
  msgid "Get audio reCAPTCHA"
287
  msgstr "Obtenir un reCAPTCHA audio"
288
 
289
  # @ bwp-recaptcha
290
+ #: includes/provider/v1.php:164
291
  msgid "Get image reCAPTCHA"
292
  msgstr "Obtenir une image reCAPTCHA"
293
 
294
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:374
295
+ msgid "Got a problem with this plugin? Please say it out loud!"
296
+ msgstr ""
297
+
298
  # @ bwp-recaptcha
299
+ #: includes/class-bwp-recaptcha.php:701
300
+ #, fuzzy
301
+ msgid "Hide captcha for"
302
+ msgstr "Cacher le CAPTCHA pour"
303
 
304
  # @ bwp-recaptcha
305
+ #: includes/class-bwp-recaptcha.php:782
306
+ msgid "Hold comment in moderation queue"
307
+ msgstr "Retenir le commentaire en file d'attente de modération"
308
 
309
  # @ bwp-recaptcha
310
+ #: includes/class-bwp-recaptcha.php:710
311
+ #, fuzzy
312
+ msgid "If correct captcha response"
313
+ msgstr "En cas de réponse correcte du CAPTCHA"
314
 
315
  # @ bwp-recaptcha
316
+ #: includes/class-bwp-recaptcha.php:704
317
+ #, fuzzy
318
+ msgid "If invalid captcha response"
319
+ msgstr "En cas de réponse erronée ou vide"
320
+
321
+ #: includes/class-bwp-recaptcha.php:880
322
  msgid ""
323
+ "If you encounter error such as <code>Unknown error (invalid-json)</code>when "
324
+ "submitting a form, try selecting a specific request method here."
325
+ msgstr ""
326
+
327
+ #: includes/class-bwp-recaptcha.php:1054
328
+ #, php-format
329
+ msgid ""
330
+ "If you want to add custom translations, please read <a href=\"%s\" target="
331
+ "\"_blank\">this tip</a>."
332
+ msgstr ""
333
+
334
+ #: includes/class-bwp-recaptcha.php:1207
335
+ #, php-format
336
+ msgid ""
337
+ "In order to use the nocaptcha recaptcha (recaptcha v2), you need at least "
338
+ "<strong>PHP 5.3.2</strong> (your current PHP version is <strong>%s</"
339
+ "strong>), so only recaptcha v1 can be used. It is recommended to contact "
340
+ "your host to know how to update your current version of PHP."
341
+ msgstr ""
342
+
343
+ # @ bwp-recaptcha
344
+ #: includes/class-bwp-recaptcha.php:125
345
+ #, fuzzy
346
+ msgid "Incorrect or empty reCAPTCHA response, please try again."
347
  msgstr ""
348
  "<strong>ERREUR :</strong> réponse reCAPTCHA incorrecte ou vide. Veuillez ré-"
349
  "essayer."
350
 
351
+ #: includes/addons/contact-form-7/captcha-shortcode.php:170
352
+ msgid "Insert Tag"
353
+ msgstr ""
354
+
355
+ #: includes/class-bwp-recaptcha.php:753
356
+ msgid "Integrate the comment form with Akismet for better end-user experience."
357
+ msgstr ""
358
+
359
+ # @ bwp-recaptcha
360
+ #: includes/class-bwp-recaptcha.php:709
361
+ #, fuzzy
362
+ msgid "Integrate with Akismet"
363
+ msgstr "Intégrer avec Akismet ?"
364
+
365
+ # @ bwp-recaptcha
366
+ #: includes/class-bwp-recaptcha.php:712
367
+ #, fuzzy
368
+ msgid "Integrate with Contact Form 7"
369
+ msgstr "Intégrer avec Akismet ?"
370
+
371
+ # @ bwp-recaptcha
372
+ #: includes/class-bwp-recaptcha.php:706 includes/class-bwp-recaptcha.php:707
373
+ #: includes/class-bwp-recaptcha.php:714
374
+ #, fuzzy
375
+ msgid "Invalid captcha error message"
376
+ msgstr "Montrer le message d'erreur"
377
+
378
+ #: includes/class-bwp-recaptcha.php:886
379
+ msgid ""
380
+ "It is best to put comments identified as spam in moderation queue so you are "
381
+ "able to review and instruct Akismet to correctly handle similar comments in "
382
+ "the future."
383
+ msgstr ""
384
+
385
+ #: includes/class-bwp-recaptcha.php:1088
386
+ msgid "Language"
387
+ msgstr ""
388
+
389
+ # @ bwp-recaptcha
390
+ #: includes/class-bwp-recaptcha.php:993
391
+ #, fuzzy
392
+ msgid "Language for built-in themes"
393
+ msgstr "Choisissez une langue pour les thèmes intégrés"
394
+
395
+ #: includes/class-bwp-recaptcha.php:1106
396
+ msgid "Light"
397
+ msgstr ""
398
+
399
+ #: includes/class-bwp-recaptcha.php:793
400
+ msgid "Login form"
401
+ msgstr ""
402
+
403
+ #: includes/class-bwp-recaptcha.php:699
404
+ msgid "Main Functionality"
405
+ msgstr ""
406
+
407
+ #: includes/class-bwp-recaptcha.php:816
408
+ msgid "Make requests to recaptcha server always secured."
409
+ msgstr ""
410
+
411
+ # @ bwp-recaptcha
412
+ #: includes/class-bwp-recaptcha.php:317
413
+ msgid "Manage Options"
414
+ msgstr "Gérer les options"
415
+
416
+ #: includes/addons/contact-form-7/captcha-shortcode.php:159
417
+ #: includes/addons/contact-form-7/captcha-shortcode.php:196
418
+ msgid "Name"
419
+ msgstr "Nom"
420
+
421
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:503
422
+ msgid "Need a highly customizable theme?"
423
+ msgstr ""
424
+
425
+ #: includes/class-bwp-recaptcha.php:1110
426
+ msgid "Normal"
427
+ msgstr ""
428
+
429
+ # @ default
430
+ #: includes/class-bwp-recaptcha.php:1205 includes/class-bwp-recaptcha.php:1227
431
+ msgid "Notice"
432
+ msgstr "Avis"
433
+
434
+ # @ bwp-recaptcha
435
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:410
436
+ msgid "One LL-cup!!! $50.00"
437
+ msgstr "Une grande tasse !!! $50.00"
438
+
439
+ # @ bwp-recaptcha
440
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:407
441
+ msgid "One cup $5.00"
442
+ msgstr "Une tasse $5.00"
443
+
444
+ #: includes/addons/contact-form-7/captcha-shortcode.php:225
445
+ #, fuzzy, php-format
446
+ msgid ""
447
+ "Please refer to <a target=\"_blank\" href=\"%s\">BWP reCAPTCHA's "
448
+ "documentation</a> for a quick guide on how to customize the look and feel of "
449
+ "this tag."
450
+ msgstr ""
451
+ "Veuillez consulter <a target=\"_blank\" href=\"http://betterwp.net/wordpress-"
452
+ "plugins/bwp-recaptcha/#customization\"> la documentation de BWP reCAPTCHA </"
453
+ "a> pour une présentation rapide sur comment personnaliser l'apparence de "
454
+ "cette balise."
455
+
456
+ # @ bwp-option-page
457
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:93
458
+ msgid "Plugin Configurations"
459
+ msgstr "Configurations de l'extension"
460
+
461
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:375
462
+ msgid "Plugin Support"
463
+ msgstr ""
464
+
465
+ # @ bwp-recaptcha
466
+ #: includes/class-bwp-recaptcha.php:995 includes/class-bwp-recaptcha.php:1090
467
+ msgid "Preview your reCAPTCHA"
468
+ msgstr "Aperçu de votre reCAPTCHA"
469
+
470
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:378
471
+ msgid "Rate this plugin 5 stars if you like it, thank you!"
472
+ msgstr ""
473
+
474
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:379
475
+ msgid "Rate this plugin 5 stars!"
476
+ msgstr ""
477
+
478
+ #: includes/class-bwp-recaptcha.php:1045
479
+ #, php-format
480
+ msgid ""
481
+ "Read <a href=\"%s#recaptcha-version-1\" target=\"_blank\">here</a> to know "
482
+ "how to use your own CSS for the Custom Theme."
483
+ msgstr ""
484
+
485
+ # @ bwp-recaptcha
486
+ #: includes/class-bwp-recaptcha.php:316
487
+ msgid "Read Profile"
488
+ msgstr "Lire le profil"
489
+
490
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:370
491
+ msgid "Read this first before asking any question!"
492
+ msgstr ""
493
+
494
+ # @ bwp-recaptcha
495
+ #: includes/class-bwp-recaptcha.php:777
496
+ #, fuzzy
497
+ msgid "Redirect commenter back to the comment form with error message"
498
+ msgstr "Faire revenir le rédacteur du commentaire au formulaire de commentaire"
499
+
500
+ # @ bwp-recaptcha
501
+ #: includes/class-bwp-recaptcha.php:790
502
+ #, fuzzy
503
+ msgid "Registration form (user/site registration)"
504
+ msgstr ""
505
+ "activée pour le formulaire d'inscription (inscription site/utilisateur)."
506
+
507
+ #: includes/class-bwp-recaptcha.php:698
508
+ msgid "Request method"
509
+ msgstr ""
510
+
511
+ # @ default
512
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:305
513
+ msgid "Save Changes"
514
+ msgstr "Enregistrer les modifications"
515
+
516
+ #: includes/class-bwp-recaptcha.php:694
517
+ msgid "Secret Key"
518
+ msgstr ""
519
+
520
+ #: includes/class-bwp-recaptcha.php:1129
521
+ msgid "Set to 0 to disable."
522
+ msgstr ""
523
+
524
+ # @ default
525
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:1315
526
+ msgid "Settings"
527
+ msgstr "Réglages"
528
+
529
+ # @ bwp-recaptcha
530
+ #: includes/class-bwp-recaptcha.php:751
531
+ #, fuzzy
532
+ msgid "Settings that are applied to comment forms only."
533
+ msgstr "Intégration Akismet (appliquée aux formulaires de commentaire)"
534
+
535
+ # @ bwp-recaptcha
536
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:431
537
+ #, fuzzy
538
+ msgid "Share the love for this plugin!"
539
+ msgstr "Utiliser une feuille de style CSS fournie par cette extension ?"
540
+
541
+ # @ bwp-recaptcha
542
+ #: includes/class-bwp-recaptcha.php:778
543
+ msgid "Show an error page just like WordPress does"
544
+ msgstr "Afficher une page d'erreur, de la même façon que WordPress"
545
+
546
+ # @ bwp-recaptcha
547
+ #: includes/class-bwp-recaptcha.php:805
548
+ #, fuzzy
549
+ msgid ""
550
+ "Show captcha only when Akismet identifies a comment as spam. Highly "
551
+ "recommended if you do not want to force your visitors to enter a captcha "
552
+ "every time."
553
+ msgstr ""
554
+ "reCAPTCHA s'affichera seulement lorsque Akismet identifiera un commentaire "
555
+ "comme spam. Vivement recommandé si vous ne voulez pas forcer vos visiteurs à "
556
+ "taper le captcha à chaque fois."
557
+
558
  # @ bwp-recaptcha
559
+ #: includes/class-bwp-recaptcha.php:693
560
+ #, fuzzy
561
+ msgid "Site Key"
562
+ msgstr "Clé privée"
563
+
564
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:541
565
+ msgid "Subscribe"
566
  msgstr ""
 
 
 
567
 
568
  # @ bwp-recaptcha
569
+ #: includes/class-bwp-recaptcha.php:994 includes/class-bwp-recaptcha.php:1089
570
+ msgid "Tabindex for captcha input field"
571
+ msgstr "Indice de position pour le champ d'entrée du captcha"
572
 
573
  # @ bwp-recaptcha
574
+ #: includes/class-bwp-recaptcha.php:162 includes/class-bwp-recaptcha.php:605
575
  msgid "Theme Options"
576
  msgstr "Options du thème"
577
 
578
  # @ bwp-recaptcha
579
+ #: includes/provider/abstract-provider.php:103
580
+ msgid ""
581
+ "There is some problem with your reCAPTCHA API keys, please double check them."
582
+ msgstr ""
583
+ "Il ya un problème avec vos clés API pour reCAPTCHA. Veuillez les re-vérifier."
 
 
 
584
 
585
+ #: includes/class-bwp-recaptcha.php:754 includes/class-bwp-recaptcha.php:822
586
+ #, php-format
587
+ msgid ""
588
+ "This feature requires an active <a target=\"_blank\" href=\"%s\">PHP "
589
+ "session</a>."
590
+ msgstr ""
591
 
592
+ #: includes/class-bwp-recaptcha.php:897
593
+ msgid "This is shown on the standard WordPress error page."
594
+ msgstr ""
 
595
 
596
  # @ bwp-recaptcha
597
+ #: includes/class-bwp-recaptcha.php:892
598
+ #, fuzzy
599
+ msgid ""
600
+ "This is shown when the commenter is redirected back to the comment form."
601
+ msgstr "Faire revenir le rédacteur du commentaire au formulaire de commentaire"
602
 
603
+ #: includes/class-bwp-recaptcha.php:905
604
+ msgid ""
605
+ "This message is shown when invalid captcha response is treated as a standard "
606
+ "validation error. Leave blank to not use."
607
+ msgstr ""
608
 
609
+ #: includes/addons/contact-form-7/captcha-shortcode.php:220
610
+ msgid "This reCAPTCHA tag is provided by the BWP reCAPTCHA WordPress plugin."
611
+ msgstr ""
612
+ "Cette balise reCAPTCHA est fournie par l'extension BWP reCAPTCHA pour "
613
+ "Wordpress."
614
 
615
+ #: includes/provider/v1.php:96
616
+ #, php-format
617
+ msgid "To use reCAPTCHA you must get an API key from <a href=\"%1$s\">%1$s</a>"
618
+ msgstr ""
619
 
620
+ #: includes/class-bwp-recaptcha.php:873
621
+ msgid ""
622
+ "To verify a captcha response, this plugin needs to send requests to the "
623
+ "reCAPTCHA server, using a specific request method. <br /><br />By default, "
624
+ "BWP reCAPTCHA use the first available request method, be it Socket "
625
+ "(<code>fsockopen</code>), cURL, or <code>file_get_contents</code>."
626
+ msgstr ""
627
 
628
+ #: includes/class-bwp-recaptcha.php:713
629
+ msgid "Treat invalid captcha as spam"
630
+ msgstr ""
 
631
 
632
+ #: includes/class-bwp-recaptcha.php:830
633
+ msgid "Treat invalid captcha response as spam instead of validation error"
634
+ msgstr ""
 
635
 
636
  # @ bwp-recaptcha
637
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:408
638
+ msgid "Two cups $10.00"
639
+ msgstr "Deux tasses $10.00"
640
 
641
+ #: includes/provider/v1.php:170
642
+ msgid "Type what you hear"
643
+ msgstr ""
 
644
 
645
+ #: includes/provider/v1.php:169
646
+ msgid "Type what you see"
 
647
  msgstr ""
 
648
 
649
+ #: includes/class-bwp-recaptcha.php:810
650
+ #, fuzzy
651
+ msgid "Uncheck to use different key pairs for this site."
652
+ msgstr "décocher pour utiliser des paires de clés différentes pour ce site."
653
 
654
  # @ bwp-recaptcha
655
+ #: includes/provider/abstract-provider.php:107
656
+ #, fuzzy, php-format
657
+ msgid "Unknown error (%s). Please contact an administrator for more info."
658
+ msgstr ""
659
+ "Erreur inconnue. Veuillez contacter l'administrateur pour plus "
660
+ "d'informations."
661
+
662
+ #: includes/class-bwp-recaptcha.php:991
663
+ msgid "Use default CSS"
664
+ msgstr ""
665
 
666
+ #: includes/class-bwp-recaptcha.php:692
667
  msgid "Use main site's keys"
668
  msgstr "Utiliser les clés du site principal"
669
 
670
  # @ bwp-recaptcha
671
+ #: includes/class-bwp-recaptcha.php:696
672
+ #, fuzzy
673
+ msgid "Use reCAPTCHA version 1"
674
+ msgstr "Options générales de BWP reCAPTCHA"
 
 
 
 
675
 
676
+ #: includes/class-bwp-recaptcha.php:813
677
+ msgid ""
678
+ "Use the oldschool recaptcha instead of the new <em>nocaptcha</em> recaptcha."
679
+ msgstr ""
680
 
681
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:416
682
+ msgid "Via"
683
+ msgstr ""
 
684
 
685
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:827
686
+ msgid "View more info in a separate tab"
687
+ msgstr ""
 
688
 
689
+ # @ default
690
+ #: includes/class-bwp-recaptcha.php:1192
691
+ msgid "Warning"
692
+ msgstr "Avertissement"
693
 
694
  # @ bwp-recaptcha
695
+ #: includes/class-bwp-recaptcha.php:1012
696
+ msgid "White Theme"
697
+ msgstr "Thème blanc"
698
 
699
  # @ bwp-recaptcha
700
+ #: includes/class-bwp-recaptcha.php:1228
701
+ msgid ""
702
+ "You are enabling Akismet integration but Akismet is not currently active. "
703
+ "Please activate Akismet for the integration to work."
704
+ msgstr ""
705
+ "Vous essayez d'activer l'intégration d'Akismet mais Akismet n'est pas actif "
706
+ "actuellement. Veuillez activer Akismet pour que l'intégration fonctionne."
707
 
708
  # @ bwp-recaptcha
709
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:565
710
+ #, php-format
711
+ msgid "You are using version %s!"
712
+ msgstr "Vous utilisez la version %s !"
713
 
714
  # @ bwp-recaptcha
715
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:391
716
  msgid ""
717
+ "You can buy me some special coffees if you appreciate my work, thank you!"
 
 
718
  msgstr ""
719
+ "Vous pouvez m'acheter des cafés spéciaux si vous appréciez mon travail, je "
720
+ "vous remercie !"
 
 
721
 
722
  # @ bwp-recaptcha
723
+ #: includes/class-bwp-recaptcha.php:1376
724
+ msgid "Your comment was identified as spam, please complete the CAPTCHA below:"
 
 
725
  msgstr ""
726
+ "Votre commentaire a été identifié comme spam. Veuillez compléter le CAPTCHA "
727
+ "ci-dessous :"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
728
 
729
  # @ bwp-recaptcha
730
+ #: includes/class-bwp-recaptcha.php:848
731
+ msgid "approved comment(s)."
732
+ msgstr "commentaire(s) approuvé(s)."
733
 
734
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:524
735
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:534
736
+ msgid "loading..."
737
+ msgstr ""
738
 
739
+ #: includes/class-bwp-recaptcha.php:691
740
+ msgid "reCAPTCHA API Keys"
741
+ msgstr ""
 
742
 
743
  # @ bwp-recaptcha
744
+ #: includes/class-bwp-recaptcha.php:695
745
+ #, fuzzy
746
+ msgid "reCAPTCHA Settings"
747
+ msgstr "Options du thème de BWP reCAPTCHA"
748
 
749
  # @ bwp-recaptcha
750
+ #: includes/class-bwp-recaptcha.php:702
751
+ #, fuzzy
752
+ msgid "reCAPTCHA for comment form"
753
  msgstr "activée pour les formulaires de commentaire."
754
 
755
  # @ bwp-recaptcha
756
+ #: includes/class-bwp-recaptcha.php:1086
757
+ #, fuzzy
758
+ msgid "reCAPTCHA size"
759
+ msgstr "Au sujet de reCAPTCHA"
760
 
761
  # @ bwp-recaptcha
762
+ #: includes/class-bwp-recaptcha.php:990 includes/class-bwp-recaptcha.php:1085
763
+ #, fuzzy
764
+ msgid "reCAPTCHA theme"
765
+ msgstr "Options du thème de BWP reCAPTCHA"
766
 
767
  # @ bwp-recaptcha
768
+ #: includes/class-bwp-recaptcha.php:796
769
  msgid "registered users <em>(even without any capabilities)</em>."
770
  msgstr "les utilisateurs enregistrés <em>(même sans aucun droit)</em>."
771
 
772
  # @ bwp-recaptcha
773
+ #: includes/class-bwp-recaptcha.php:1554
774
+ msgid "this link"
775
+ msgstr "ce lien"
776
+
777
+ # @ bwp-recaptcha
778
+ #: includes/class-bwp-recaptcha.php:799
779
  msgid "users who can"
780
  msgstr "les utilisateurs qui peuvent"
781
 
782
  # @ bwp-recaptcha
783
+ #: includes/class-bwp-recaptcha.php:802
784
  msgid "visitors who have at least"
785
  msgstr "les visiteurs qui ont au moins"
786
 
787
  # @ bwp-recaptcha
788
+ #~ msgid ""
789
+ #~ "<em><strong>Note:</strong> Above you can select some built-in languages. "
790
+ #~ "If you would like to add your own language, please read <a href="
791
+ #~ "\"%s#customization\" target=\"_blank\">this guide</a>.</em>"
792
+ #~ msgstr ""
793
+ #~ "<em><strong>Remarque :</strong> Ci-dessus vous pouvez sélectionner "
794
+ #~ "certaines langues intégrées. Si vous souhaitez ajouter votre propre "
795
+ #~ "langue, veuillez lire <a href=\"%s#customization\" target=\"_blank\">ce "
796
+ #~ "guide</a>.</em>"
797
+
798
+ # @ bwp-recaptcha
799
+ #~ msgid ""
800
+ #~ "<em><strong>Note:</strong> Now you may wonder, why put the comment in the "
801
+ #~ "spam queue? The benefit is Akismet will be able to mark the comment as "
802
+ #~ "False Positive, and thus will not possibly block that comment in the "
803
+ #~ "future. However, it is best to just put the comment in moderation queue "
804
+ #~ "as next time Akismet will put such comment in moderation queue "
805
+ #~ "immediately without the need of a CAPTCHA.</em>"
806
+ #~ msgstr ""
807
+ #~ "<em><strong>Remarque :</strong> Maintenant, vous vous demander peut-être "
808
+ #~ "pourquoi mettre le commentaire dans la file d'attente de spam ? "
809
+ #~ "L'avantage est qu'Akismet sera en mesure de marquer le commentaire comme "
810
+ #~ "faux positif, et donc évitera que ce commentaire soit bloqué par la "
811
+ #~ "suite. Cependant, il est préférable de mettre simplement le commentaire "
812
+ #~ "dans la file d'attente de modération pour que la prochaine fois Akismet "
813
+ #~ "mette immédiatement de tels commentaires en file d'attente de modération "
814
+ #~ "sans avoir besoin d'un CAPTCHA.</em>"
815
+
816
+ # @ bwp-recaptcha
817
+ #~ msgid ""
818
+ #~ "<em><strong>Note:</strong> The four built-in captcha themes will look OK "
819
+ #~ "in most WordPress themes; However, some times it is better to control how "
820
+ #~ "reCAPTCHA looks using CSS. Please read <a href=\"%s#customization\" "
821
+ #~ "target=\"_blank\">this guide</a> if you would like to do so.</em>"
822
+ #~ msgstr ""
823
+ #~ "<em><strong>Remarque :</strong> Les quatre thèmes captcha intégrés auront "
824
+ #~ "une apparence satisfaisante avec la plupart des thèmes WordPress. "
825
+ #~ "Cependant, parfois il est préférable de contrôler l'apparence du "
826
+ #~ "reCAPTCHA à l'aide de feuilles de style CSS. Veuillez lire <a href="
827
+ #~ "\"%s#customization\" target=\"_blank\">ce quide</a> si vous souhaitez le "
828
+ #~ "faire.</em>"
829
+
830
+ # @ bwp-recaptcha
831
+ #~ msgid ""
832
+ #~ "<em>Integrate with Akismet for better end-user experience. reCAPTCHA is "
833
+ #~ "optional and <strong>NO</strong> spam comment will be added to the spam/"
834
+ #~ "moderation queue, except likely legitimate comments. This makes the task "
835
+ #~ "of identifying sincere comments much easier. This integration is "
836
+ #~ "currently in beta stage.</em>"
837
+ #~ msgstr ""
838
+ #~ "<em>À intégrer avec Akismet pour une meilleure expérience utilisateur : "
839
+ #~ "reCAPTCHA est facultatif et <strong>AUCUN</strong> commentaire de type "
840
+ #~ "spam ne sera ajouté à la file de modération des spam, sauf les "
841
+ #~ "commentaires susceptibles d'être légitimes. Cela rend la tâche "
842
+ #~ "d'identification des commentaires sincères beaucoup plus facile. Cette "
843
+ #~ "intégration est actuellement en phase bêta.</em>"
844
+
845
+ # @ bwp-recaptcha
846
+ #~ msgid ""
847
+ #~ "<em>This section allows you to determine when to show reCAPTCHA and how "
848
+ #~ "this plugin reacts to errors.</em>"
849
+ #~ msgstr ""
850
+ #~ "<em>Cette section vous permet de déterminer quand montrer reCAPTCHA et "
851
+ #~ "comment cette extension doit réagir aux erreurs.</em>"
852
 
853
+ # @ default
854
+ #~ msgid "<strong>ERROR</strong>: Unknown captcha error."
855
+ #~ msgstr "<strong>ERREUR</strong> : erreur captcha inconnue."
 
 
 
856
 
857
  # @ bwp-recaptcha
858
+ #~ msgid ""
859
+ #~ "API key(s) missing. Please get an API key from <a href='https://www."
860
+ #~ "google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/"
861
+ #~ "create</a> (free!)"
862
+ #~ msgstr ""
863
+ #~ "Clé(s) API manquante(s). Veuillez obtenir une clé API à partir de <a "
864
+ #~ "href='https://www.google.com/recaptcha/admin/create'>https://www.google."
865
+ #~ "com/recaptcha/admin/create</a> (Gratuit !)"
866
 
867
  # @ bwp-recaptcha
868
+ #~ msgid ""
869
+ #~ "Basically, this should be 4 if you place the captcha before the textarea, "
870
+ #~ "and 5 if you put it after. Set to 0 to disable."
871
+ #~ msgstr ""
872
+ #~ "Fondamentalement, cela devrait être 4 si vous placez le captcha avant la "
873
+ #~ "zone de saisie du texte, et 5 si vous le mettez après. Indiquer 0 pour "
874
+ #~ "désactiver."
 
875
 
876
  # @ bwp-recaptcha
877
+ #~ msgid "Choose a theme"
878
+ #~ msgstr "Choisissez un thème"
 
879
 
880
  # @ bwp-recaptcha
881
+ #~ msgid "Contact"
882
+ #~ msgstr "Contact"
 
883
 
884
  # @ bwp-recaptcha
885
+ #~ msgid "Development Log"
886
+ #~ msgstr "Historique des développements"
 
 
 
 
 
 
 
 
 
 
887
 
888
  # @ bwp-recaptcha
889
+ #~ msgid "Dutch"
890
+ #~ msgstr "Hollandais"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
891
 
892
  # @ bwp-recaptcha
893
+ #~ msgid "English"
894
+ #~ msgstr "Anglais"
 
895
 
896
  # @ bwp-recaptcha
897
+ #~ msgid "Enter the numbers you hear:"
898
+ #~ msgstr "Entrez les chiffres que vous entendez :"
 
899
 
900
  # @ bwp-recaptcha
901
+ #~ msgid "Enter the two words in the box:"
902
+ #~ msgstr "Entrez les deux mots dans la boîte :"
 
903
 
904
  # @ bwp-recaptcha
905
+ #~ msgid "Follow me on Twitter!"
906
+ #~ msgstr "Suivez-moi sur Twitter !"
 
907
 
908
  # @ bwp-recaptcha
909
+ #~ msgid "French"
910
+ #~ msgstr "Français"
 
 
 
 
 
911
 
912
  # @ bwp-recaptcha
913
+ #~ msgid "Frequently Asked Questions"
914
+ #~ msgstr "Questions fréquemment posées"
 
915
 
916
  # @ bwp-recaptcha
917
+ #~ msgid "German"
918
+ #~ msgstr "Allemand"
 
919
 
920
  # @ bwp-recaptcha
921
+ #~ msgid "Got a problem? Send me a feedback!"
922
+ #~ msgstr "Un problème ? Envoyez-moi un retour !"
 
923
 
924
  # @ bwp-recaptcha
925
+ #~ msgid "Latest updates from BetterWP.net!"
926
+ #~ msgstr "Dernières mises à jour de BetterWP.net !"
 
927
 
928
  # @ bwp-recaptcha
929
+ #~ msgid "Load CSS, JS selectively?"
930
+ #~ msgstr "Charger sélectivement une CSS ou un JS ?"
 
931
 
932
  # @ bwp-recaptcha
933
+ #~ msgid "Portuguese"
934
+ #~ msgstr "Portugais"
 
 
 
 
 
 
 
935
 
936
  # @ bwp-recaptcha
937
+ #~ msgid "Public Key"
938
+ #~ msgstr "Clé publique"
 
 
 
939
 
940
  # @ bwp-recaptcha
941
+ #~ msgid "Put comment in spam queue"
942
+ #~ msgstr "Mettre le commentaire dans la file de spam"
 
 
 
 
 
 
943
 
944
  # @ bwp-recaptcha
945
+ #~ msgid "Russian"
946
+ #~ msgstr "Russe"
 
 
 
 
 
 
 
 
 
 
 
947
 
948
  # @ bwp-recaptcha
949
+ #~ msgid "Spanish"
950
+ #~ msgstr "Espagnol"
 
 
 
 
 
 
 
 
 
 
 
 
951
 
952
+ #~ msgid "This Plugin is Proudly Sponsored By"
953
+ #~ msgstr "Cette extension est fièrement soutenue par "
 
 
954
 
955
  # @ bwp-recaptcha
956
+ #~ msgid "This is only useful when you do not use any minify or cache plugin."
957
+ #~ msgstr ""
958
+ #~ "Ce n'est utile que lorsque vous n'utilisez aucune extension de réduction "
959
+ #~ "(minify) ou de cache."
 
 
 
 
 
 
 
 
 
 
960
 
961
  # @ bwp-recaptcha
962
+ #~ msgid "This plugin will be"
963
+ #~ msgstr "Cette extension sera"
 
 
 
 
 
964
 
965
  # @ bwp-recaptcha
966
+ #~ msgid ""
967
+ #~ "This stylesheet is used to style the custom theme as well as the "
968
+ #~ "registration page. You can disable this or add appropriate filters to use "
969
+ #~ "your own."
970
+ #~ msgstr ""
971
+ #~ "Cette feuille de style est utilisée pour le style du thème personnalisé "
972
+ #~ "ainsi que pour la page d'inscription. Vous pouvez la désactiver ou "
973
+ #~ "ajouter des filtres appropriés pour utiliser la vôtre."
974
 
975
  # @ bwp-recaptcha
976
+ #~ msgid ""
977
+ #~ "To use reCAPTCHA you must get an API key from <a href='https://www.google."
978
+ #~ "com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/"
979
+ #~ "create</a>"
980
+ #~ msgstr ""
981
+ #~ "Pour utiliser reCAPTCHA, vous devez obtenir une clé API depuis <a "
982
+ #~ "href='https://www.google.com/recaptcha/admin/create'>https://www.google."
983
+ #~ "com/recaptcha/admin/create</a>"
 
 
 
 
 
984
 
985
  # @ bwp-recaptcha
986
+ #~ msgid "Turkish"
987
+ #~ msgstr "Turque"
 
988
 
989
  # @ bwp-recaptcha
990
+ #~ msgid "Visibility Options (applied to comment forms)"
991
+ #~ msgstr "Options de visibilité (appliquées aux formulaires de commentaire)"
 
 
 
992
 
993
  # @ bwp-recaptcha
994
+ #~ msgid "What is reCAPTCHA?"
995
+ #~ msgstr "Qu'est-ce que reCAPTCHA ?"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
996
 
997
  # @ default
998
+ #~ msgid "You do not have sufficient permissions to access this page."
999
+ #~ msgstr ""
1000
+ #~ "Vous ne disposez pas des autorisations requises pour accéder à cette page."
1001
+
1002
+ # @ bwp-recaptcha
1003
+ #~ msgid ""
1004
+ #~ "reCAPTCHA is a free CAPTCHA service that helps to digitize books, "
1005
+ #~ "newspapers and old time radio shows. You can read more about reCAPTCHA <a "
1006
+ #~ "href=\"http://www.google.com/recaptcha/learnmore\" target=\"_blank"
1007
+ #~ "\">here</a>."
1008
+ #~ msgstr ""
1009
+ #~ "reCAPTCHA est un service gratuit de CAPTCHA qui permet de numériser des "
1010
+ #~ "livres, des journaux et de vieilles émissions de radio. Vous pouvez en "
1011
+ #~ "savoir plus au sujet de reCAPTCHA <a href=\"http://www.google.com/"
1012
+ #~ "recaptcha/learnmore\" target=\"_blank\">ici</a>."
1013
+
1014
+ # @ bwp-recaptcha
1015
+ #~ msgid ""
1016
+ #~ "when redirect commenter back to the comment form (or when used in other "
1017
+ #~ "forms such as contact forms)."
1018
+ #~ msgstr ""
1019
+ #~ "lorsque le rédacteur du commentaire est redirigé vers le formulaire de "
1020
+ #~ "commentaire (ou pour une utilisation dans d'autres formulaires tels que "
1021
+ #~ "ceux de contact)."
1022
+
1023
+ # @ bwp-recaptcha
1024
+ #~ msgid "when show the normal error page with no redirection."
1025
+ #~ msgstr "lorsque la page d'erreur normale est affichée sans redirection."
languages/bwp-recaptcha-hr.mo CHANGED
Binary file
languages/bwp-recaptcha-hr.po CHANGED
@@ -1,11 +1,12 @@
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: BWP reCAPTCHA\n"
4
- "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: 2014-01-08 17:11+0700\n"
6
- "PO-Revision-Date: 2015-08-16 15:32+0700\n"
7
  "Last-Translator: Gospodin Bajrudin <gbajro@gmail.com>\n"
8
  "Language-Team: Gospodin Bajrudin <gbajro@gmail.com>\n"
 
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
@@ -13,11 +14,10 @@ msgstr ""
13
  "X-Poedit-Basepath: .\n"
14
  "X-Poedit-SourceCharset: UTF-8\n"
15
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
16
- "Language: hr\n"
17
- "X-Generator: Poedit 1.8.2\n"
18
  "X-Poedit-SearchPath-0: .\n"
19
 
20
- #: includes/class-bwp-framework.php:178
21
  #, php-format
22
  msgid ""
23
  "%s requires WordPress <strong>%s</strong> or higher and PHP <strong>%s</"
@@ -28,109 +28,185 @@ msgstr ""
28
  "strong> ili noviji. Ovaj dodatak nece raditi dok ne azurirate svoj softver. "
29
  "Molimo deaktivirajte ovaj dodatak."
30
 
31
- #: includes/class-bwp-framework.php:190
32
- msgid "Development Log"
33
- msgstr "Razvojni zapis"
34
 
35
- #: includes/class-bwp-framework.php:190
36
- msgid "Frequently Asked Questions"
37
- msgstr "Često postavljana pitanja"
 
 
 
 
 
38
 
39
- #: includes/class-bwp-framework.php:190
40
- msgid "FAQ"
41
- msgstr "FAQ"
 
 
 
 
42
 
43
- #: includes/class-bwp-framework.php:190
44
- msgid "Got a problem? Send me a feedback!"
45
- msgstr "Imate problem? Pošaljite mi poruku!"
 
 
46
 
47
- #: includes/class-bwp-framework.php:190
48
- msgid "Contact"
49
- msgstr "Kontakt"
50
 
51
- #: includes/class-bwp-framework.php:197
 
52
  msgid ""
53
- "You can buy me some special coffees if you appreciate my work, thank you!"
54
- msgstr "Možete mi kupiti specijalnu kavu ako cijenite moj posao, hvala Vam!"
 
55
 
56
- #: includes/class-bwp-framework.php:211
57
- msgid "Donate to "
58
- msgstr "Donirati "
59
 
60
- #: includes/class-bwp-framework.php:213
61
- msgid "One cup $5.00"
62
- msgstr "Jedna šalica $5.00"
 
63
 
64
- #: includes/class-bwp-framework.php:214
65
- msgid "Two cups $10.00"
66
- msgstr "Dvije šalice $10.00"
 
 
67
 
68
- #: includes/class-bwp-framework.php:215
69
- msgid "Five cups! $25.00"
70
- msgstr "Pet šalica! $25.00"
 
71
 
72
- #: includes/class-bwp-framework.php:216
73
- msgid "One LL-cup!!! $50.00"
74
- msgstr "Jedna LL-šalica!!! $50.00"
 
75
 
76
- #: includes/class-bwp-framework.php:217
77
- msgid "... or any amount!"
78
- msgstr "... ili bilo koja svota!"
 
 
 
 
79
 
80
- #: includes/class-bwp-framework.php:232
81
- msgid "Latest updates from BetterWP.net!"
82
- msgstr "Zadnje nadogradnje od BetterWP.net!"
 
83
 
84
- #: includes/class-bwp-framework.php:233
85
- msgid "Follow me on Twitter!"
86
- msgstr "Slijedi me na Twitteru"
87
 
88
- #: includes/class-bwp-framework.php:243
89
- msgid "This Plugin is Proudly Sponsored By"
90
- msgstr "Ovaj dodatak je ponosno sponzoriran od"
91
 
92
- #: includes/class-bwp-framework.php:260
93
- #, php-format
94
- msgid "You are using version %s!"
95
- msgstr "Koristite inačicu %s!"
96
 
97
- #: includes/class-bwp-framework.php:396
98
- msgid "Settings"
99
- msgstr "Postavke"
100
 
101
- #: includes/class-bwp-recaptcha.php:44
102
- msgid "Get another challenge"
103
- msgstr "Ponovno generiraj kombinaciju"
104
 
105
- #: includes/class-bwp-recaptcha.php:45
106
- msgid "Get audio reCAPTCHA"
107
- msgstr "Generiraj zvučni reCAPTCHA"
108
 
109
- #: includes/class-bwp-recaptcha.php:46
110
- msgid "Get video reCAPTCHA"
111
- msgstr "Generiraj slikovni reCAPTCHA"
112
 
113
- #: includes/class-bwp-recaptcha.php:47
114
- msgid "About reCAPTCHA"
115
- msgstr "O reCAPTCHA"
116
 
117
- #: includes/class-bwp-recaptcha.php:51
118
- msgid "Enter the two words in the box:"
119
- msgstr "Unesite dvije riječi u polje:"
120
 
121
- #: includes/class-bwp-recaptcha.php:52
122
- msgid "Enter the numbers you hear:"
123
- msgstr "Unesite brojeve koje ste čuli:"
124
 
125
- #: includes/class-bwp-recaptcha.php:132
126
- msgid ""
127
- "<strong>ERROR:</strong> Incorrect or empty reCAPTCHA response, please try "
128
- "again."
 
 
129
  msgstr ""
130
- "<strong>POGREŠKA:</strong> Netočan ili prazan reCAPTCHA odgovor, pokušajte "
131
- "ponovno."
132
 
133
- #: includes/class-bwp-recaptcha.php:133
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  #, php-format
135
  msgid ""
136
  "Error: Incorrect or empty reCAPTCHA response, please click the back button "
@@ -139,383 +215,417 @@ msgstr ""
139
  "Pogreška: Netočan ili prazan reCAPTCHA odgovor, molimo kliknite tipku natrag "
140
  "na Vašem pregledniku ili kliknite na %s za vratiti se."
141
 
142
- #: includes/class-bwp-recaptcha.php:155 includes/class-bwp-recaptcha.php:313
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  msgid "General Options"
144
  msgstr "Globalne Opcije"
145
 
146
- #: includes/class-bwp-recaptcha.php:156 includes/class-bwp-recaptcha.php:314
147
- msgid "Theme Options"
148
- msgstr "Opcije teme"
149
 
150
- #: includes/class-bwp-recaptcha.php:159
151
- msgid "English"
152
- msgstr "Engleski"
153
 
154
- #: includes/class-bwp-recaptcha.php:160
155
- msgid "Dutch"
156
- msgstr "Nizozemski"
 
157
 
158
- #: includes/class-bwp-recaptcha.php:161
159
- msgid "French"
160
- msgstr "Francuski"
161
 
162
- #: includes/class-bwp-recaptcha.php:162
163
- msgid "German"
164
- msgstr "Njemački"
 
165
 
166
- #: includes/class-bwp-recaptcha.php:163
167
- msgid "Portuguese"
168
- msgstr "Portugalski"
169
 
170
- #: includes/class-bwp-recaptcha.php:164
171
- msgid "Russian"
172
- msgstr "Ruski"
 
173
 
174
- #: includes/class-bwp-recaptcha.php:165
175
- msgid "Spanish"
176
- msgstr "Španjolski"
 
177
 
178
- #: includes/class-bwp-recaptcha.php:166
179
- msgid "Turkish"
180
- msgstr "Turski"
 
 
181
 
182
- #: includes/class-bwp-recaptcha.php:170
183
- msgid "Read Profile"
184
- msgstr "Provjeri profil"
 
 
 
185
 
186
- #: includes/class-bwp-recaptcha.php:171
187
- msgid "Manage Options"
188
- msgstr "Upravljanje opcijama"
 
 
 
 
 
189
 
190
- #: includes/class-bwp-recaptcha.php:311
191
- msgid "Better WordPress reCAPTCHA"
192
- msgstr "Better WordPress reCAPTCHA"
 
 
 
193
 
194
- #: includes/class-bwp-recaptcha.php:313
195
- msgid "BWP reCAPTCHA General Options"
196
- msgstr "BWP reCAPTCHA Globalne Opcije"
197
 
198
- #: includes/class-bwp-recaptcha.php:314
199
- msgid "BWP reCAPTCHA Theme Options"
200
- msgstr "BWP reCAPTCHA Opcije Teme"
201
 
202
- #: includes/class-bwp-recaptcha.php:347
203
- msgid "You do not have sufficient permissions to access this page."
204
- msgstr "Nemate dovoljna prava za posjetiti ovu stranicu"
 
205
 
206
- #: includes/class-bwp-recaptcha.php:366
207
- msgid "What is reCAPTCHA?"
208
- msgstr "Što je reCAPTCHA"
 
209
 
210
- #: includes/class-bwp-recaptcha.php:367
211
- msgid "This plugin will be"
212
- msgstr "Ovaj dodatak će biti"
 
 
213
 
214
- #: includes/class-bwp-recaptcha.php:368
215
- msgid "Use main site's keys"
216
- msgstr "Koristite ključeve glavne stranice"
 
 
 
217
 
218
- #: includes/class-bwp-recaptcha.php:369
219
- msgid "Public Key"
220
- msgstr "Javni ključ"
221
 
222
- #: includes/class-bwp-recaptcha.php:370
223
- msgid "Private Key"
224
- msgstr "Privatni ključ"
 
225
 
226
- #: includes/class-bwp-recaptcha.php:371
227
- msgid "Visibility Options (applied to comment forms)"
228
- msgstr "Opcije prikaza (za komentare)"
229
 
230
- #: includes/class-bwp-recaptcha.php:372
231
- msgid "Hide the CAPTCHA for"
232
- msgstr "Sakrij CAPTCHU za"
233
 
234
- #: includes/class-bwp-recaptcha.php:373
235
- msgid "If wrong or empty response"
236
- msgstr "Ako je pokrešan ili prazan odgovor"
237
 
238
- #: includes/class-bwp-recaptcha.php:374 includes/class-bwp-recaptcha.php:375
239
- msgid "Show the error message"
240
- msgstr "Prikaži poruku o pogrešci"
241
 
242
- #: includes/class-bwp-recaptcha.php:376
243
- msgid "Akismet Integration (applied to comment forms)"
244
- msgstr "Akismet Integracija (za komentare)"
245
 
246
- #: includes/class-bwp-recaptcha.php:377
247
- msgid "Integrate with Akismet?"
248
- msgstr "Integrati s Akismetom?"
 
249
 
250
- #: includes/class-bwp-recaptcha.php:378
251
- msgid "If correct CAPTCHA response"
252
- msgstr "Za točan CAPTCHA odgovor"
253
 
254
- #: includes/class-bwp-recaptcha.php:382
255
- msgid ""
256
- "reCAPTCHA is a free CAPTCHA service that helps to digitize books, newspapers "
257
- "and old time radio shows. You can read more about reCAPTCHA <a href=\"http://"
258
- "www.google.com/recaptcha/learnmore\" target=\"_blank\">here</a>."
259
  msgstr ""
260
- "reCAPTCHA je besplatan CAPTCHA servis koji pomaže digitalizaciji knjiga, "
261
- "članaka i starih radio emisija. Više o reCAPTCHA možete saznati <a href="
262
- "\"http://www.google.com/recaptcha/learnmore\" target=\"_blank\">ovdje</a>."
263
 
264
- #: includes/class-bwp-recaptcha.php:383
 
 
 
 
 
 
 
 
 
 
 
 
 
265
  msgid ""
266
- "<em>This section allows you to determine when to show reCAPTCHA and how this "
267
- "plugin reacts to errors.</em>"
 
268
  msgstr ""
269
- "<em>Ovaj dio omogućava pregled opcija o prikazu reCAPTCHE i kako će se ovaj "
270
- "dodatak ponašati u slučaju pogrešaka.</em>"
 
271
 
272
- #: includes/class-bwp-recaptcha.php:384
273
- msgid ""
274
- "<em>Integrate with Akismet for better end-user experience. reCAPTCHA is "
275
- "optional and <strong>NO</strong> spam comment will be added to the spam/"
276
- "moderation queue, except likely legitimate comments. This makes the task of "
277
- "identifying sincere comments much easier. This integration is currently in "
278
- "beta stage.</em>"
279
- msgstr ""
280
- "<em>Integrati s Akismet dodatkom za bolje korisničko iskustvo. reCAPTCHA je "
281
- "neobavezna i <strong>NIJEDAN</strong> spam komentar neće se dodati u "
282
- "direktorij za spam/moderaciju, osim komentara koji su najvjerojatnije "
283
- "ispravni. To olakšava posao prepoznavanja ispravnih komentara. Ova "
284
- "integracija je trenutno u beta fazi.</em>"
285
-
286
- #: includes/class-bwp-recaptcha.php:400
287
- msgid "Redirect commenter back to the comment form"
288
- msgstr "Preusmjeri korisnika natrag formu za komentare"
289
 
290
- #: includes/class-bwp-recaptcha.php:401
291
- msgid "Show an error page just like WordPress does"
292
- msgstr "Prikaži stranicu o pogrešci kao što to radi WordPress"
293
 
294
- #: includes/class-bwp-recaptcha.php:404
295
- msgid "Approve comment immediately"
296
- msgstr "Odmah odobri komentar"
297
 
298
- #: includes/class-bwp-recaptcha.php:405
299
- msgid "Hold comment in moderation queue"
300
- msgstr "Zadrži komentar u moderaciji"
301
 
302
- #: includes/class-bwp-recaptcha.php:406
303
- msgid "Put comment in spam queue"
304
- msgstr "Stavi komentar u spam direktorij"
305
 
306
- #: includes/class-bwp-recaptcha.php:410
307
- msgid "enabled for comment forms."
308
- msgstr "omogućeno kod komentara"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
309
 
310
- #: includes/class-bwp-recaptcha.php:411
311
- msgid "enabled for registration form (user/site registration)."
 
312
  msgstr "omogućeno kod registracijske forme (za korisnike i stranice) "
313
 
314
- #: includes/class-bwp-recaptcha.php:412
315
- msgid "enabled for login form."
316
- msgstr "omogućeno kod forme za prijavu."
317
 
318
- #: includes/class-bwp-recaptcha.php:413
319
- msgid "registered users <em>(even without any capabilities)</em>."
320
- msgstr "registrirani korisnici <em>(čak i bez ikakvih mogućnosti)</em>."
321
 
322
- #: includes/class-bwp-recaptcha.php:414
323
- msgid "users who can"
324
- msgstr "korisnici koji mogu"
325
 
326
- #: includes/class-bwp-recaptcha.php:415
327
- msgid "visitors who have at least"
328
- msgstr "posjetitelji koji imaju najmanje"
 
 
 
 
329
 
330
- #: includes/class-bwp-recaptcha.php:416
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
331
  msgid ""
332
- "reCAPTCHA will only show when Akismet identifies a comment as spam. Highly "
333
- "recommended if you do not want to force your visitors to type the captcha "
334
  "every time."
335
  msgstr ""
336
  "reCAPTCHA će se prikazati samo ako Akismet identificira komentar kao spam. "
337
  "Preporučeno ukoliko se želi smanjiti broj prikazivanja reCAPTCHE "
338
  "posjetiteljima."
339
 
340
- #: includes/class-bwp-recaptcha.php:417
341
- msgid "uncheck to use different key pairs for this site."
342
- msgstr "odznači ako želiš za koristiti druge ključeve za svoju stranicu "
343
-
344
- #: includes/class-bwp-recaptcha.php:420
345
- msgid "A public key used to request captchas from reCAPTCHA server."
346
- msgstr "Javni ključ koristi se za dohvat CAPTCHE sa reCAPTCHA poslužitelja."
347
 
348
- #: includes/class-bwp-recaptcha.php:421
349
- msgid "A private (secret) key used to authenticate user's response."
350
  msgstr ""
351
- "Privatni ključ (tajni) koji se koristi za provjeru (autentikaciju) "
352
- "korisnikova odgovora."
353
 
354
- #: includes/class-bwp-recaptcha.php:422
355
- msgid ""
356
- "when redirect commenter back to the comment form (or when used in other "
357
- "forms such as contact forms)."
358
- msgstr ""
359
- "kod vraćanja korisnika na formular za komentar (ili kod korištenja u drugim "
360
- "formama, npr. kontakt formulara)."
361
 
362
- #: includes/class-bwp-recaptcha.php:423
363
- msgid "when show the normal error page with no redirection."
364
- msgstr "kod prikaza stranice s greškom kod koje nema preusmjeravanja"
365
 
366
- #: includes/class-bwp-recaptcha.php:424
367
- msgid "approved comment(s)."
368
- msgstr "Odobren(i) komentar(i)."
 
369
 
370
- #: includes/class-bwp-recaptcha.php:427
 
371
  msgid ""
372
- "<em><strong>Note:</strong> For this plugin to work, you will need a pair of "
373
- "API keys (public and private), which is available for free <a href=\"https://"
374
- "www.google.com/recaptcha/admin/create\" target=\"_blank\">here</a>. Once you "
375
- "have created those two keys for this domain, simply paste them below.</em>"
376
  msgstr ""
377
- "<em><strong>Pažnja:</strong> Kako bi ovaj dodatak mogao raditi, potrebno je "
378
- "koristiti API ključeve (javni i privatni), koji su besplatno dostupni <a "
379
- "href=\"https://www.google.com/recaptcha/admin/create\" target=\"_blank"
380
- "\">ovdje</a>. Nakon dobivanja ključeva za Vašu domenu, unesite ih ispod.</em>"
381
 
382
- #: includes/class-bwp-recaptcha.php:428
383
- msgid ""
384
- "<em><strong>Note:</strong> Now you may wonder, why put the comment in the "
385
- "spam queue? The benefit is Akismet will be able to mark the comment as False "
386
- "Positive, and thus will not possibly block that comment in the future. "
387
- "However, it is best to just put the comment in moderation queue as next time "
388
- "Akismet will put such comment in moderation queue immediately without the "
389
- "need of a CAPTCHA.</em>"
390
- msgstr ""
391
- "<em><strong>Pažnja:</strong> Zašto staviti komentar u spam direktorij? "
392
- "Akismet će provjeriti i biti u mogućnosti označiti komentar kao legitiman, "
393
- "te u budućnosti ne blokirati takav komentar. U principu, najbolje je staviti "
394
- "komentar u moderaciju, te će svaki slijedeći puta Akismet postaviti komentar "
395
- "direktno u moderaciju, bez potrebe za unošenjem CAPTCHA koda.</em>"
396
-
397
- #: includes/class-bwp-recaptcha.php:457
398
- msgid "Choose a theme"
399
- msgstr "Izaberi temu"
400
-
401
- #: includes/class-bwp-recaptcha.php:458
402
- msgid "Use CSS provided by this plugin?"
403
- msgstr "Koristi CSS koji je došao s ovim pluginom?"
404
 
405
- #: includes/class-bwp-recaptcha.php:459
406
- msgid "Load CSS, JS selectively?"
407
- msgstr "Učitaj CSS, JS opcionalno?"
 
 
408
 
409
- #: includes/class-bwp-recaptcha.php:460
410
- msgid "Choose a language for built-in themes"
411
- msgstr "Odaberi jezik za ugrađene teme"
 
 
412
 
413
- #: includes/class-bwp-recaptcha.php:461
414
- msgid "Tabindex for captcha input field"
415
- msgstr "Tab kod polja za unos"
 
416
 
417
- #: includes/class-bwp-recaptcha.php:462
418
- msgid "Preview your reCAPTCHA"
419
- msgstr "Pregledaj reCAPTCHU"
 
420
 
421
- #: includes/class-bwp-recaptcha.php:466
422
  msgid ""
423
- "<em>Below you will see how your reCAPTCHA will look. Note that this might "
424
- "differ on your actual pages.<br /></em>"
 
 
425
  msgstr ""
426
- "<em>Ispod je prikaz izgleda reCAPTCHE. Može se razlikovati na pravoj web "
427
- "stranici.<br /></em>"
428
 
429
- #: includes/class-bwp-recaptcha.php:470
430
- msgid "Default Theme (Red)"
431
- msgstr "Zadana Tema (Crvena)"
432
-
433
- #: includes/class-bwp-recaptcha.php:471
434
- msgid "White Theme"
435
- msgstr "Bijela Tema"
436
-
437
- #: includes/class-bwp-recaptcha.php:472
438
- msgid "Black Theme"
439
- msgstr "Crna Tema"
440
 
441
- #: includes/class-bwp-recaptcha.php:473
442
- msgid "Clean Theme"
443
- msgstr "Clean (čista) Tema"
444
 
445
- #: includes/class-bwp-recaptcha.php:474
446
- msgid "Custom Theme (use CSS)"
447
- msgstr "Vlastita tema (koristi CSS)"
448
 
449
- #: includes/class-bwp-recaptcha.php:479
450
- msgid ""
451
- "This stylesheet is used to style the custom theme as well as the "
452
- "registration page. You can disable this or add appropriate filters to use "
453
- "your own."
454
  msgstr ""
455
- "Ovaj stil se koristi za prikaz ručno napravljene teme kao i registracijske "
456
- "stranice. Može se onemogućiti ili urediti na željeni način."
457
 
458
- #: includes/class-bwp-recaptcha.php:480
459
- msgid "This is only useful when you do not use any minify or cache plugin."
460
  msgstr ""
461
- "Korisno kad se ne koristi dodaci koji uključuju spremnik (minify ili cache "
462
- "dodatak)."
463
 
464
- #: includes/class-bwp-recaptcha.php:483
465
- msgid ""
466
- "Basically, this should be 4 if you place the captcha before the textarea, "
467
- "and 5 if you put it after. Set to 0 to disable."
 
 
 
 
 
 
 
 
468
  msgstr ""
469
- "Ovo bi trebalo biti 4 ako će se captcha prikazivati prije unosa teksta, a 5 "
470
- "ako će se prikazivati poslije. Postaviti 0 da se onemogući."
471
 
472
- #: includes/class-bwp-recaptcha.php:486
473
- #, php-format
 
 
 
 
 
 
 
 
474
  msgid ""
475
- "<em><strong>Note:</strong> The four built-in captcha themes will look OK in "
476
- "most WordPress themes; However, some times it is better to control how "
477
- "reCAPTCHA looks using CSS. Please read <a href=\"%s#customization\" target="
478
- "\"_blank\">this guide</a> if you would like to do so.</em>"
479
  msgstr ""
480
- "<em><strong>Pažnja:</strong> Četiri ugrađene teme će izgledati dobro u "
481
- "većini WordPress tema. Ponekad je bolje koristiti CSS za kontroliranje "
482
- "reCAPTCHA izgleda. Pročitajte <a href=\"%s#customization\" target=\"_blank"
483
- "\">ove upute</a> ako želite promijeniti izgled.</em>"
484
 
485
- #: includes/class-bwp-recaptcha.php:487
486
- #, php-format
487
- msgid ""
488
- "<em><strong>Note:</strong> Above you can select some built-in languages. If "
489
- "you would like to add your own language, please read <a href="
490
- "\"%s#customization\" target=\"_blank\">this guide</a>.</em>"
491
  msgstr ""
492
- "<em><strong>Pažnja:</strong> Ovdje se mogu odabrati jezici za korištenje . "
493
- "Ukoliko želite dodati svoj, pročitajte <a href=\"%s#customization\" target="
494
- "\"_blank\">ove upute</a>.</em>"
495
 
496
- #: includes/class-bwp-recaptcha.php:540
497
- msgid "All options have been saved."
498
- msgstr "Sve opcije su spremljene."
499
 
500
- #: includes/class-bwp-recaptcha.php:546
501
  msgid "Warning"
502
  msgstr "Upozorenje"
503
 
504
- #: includes/class-bwp-recaptcha.php:546
505
- msgid ""
506
- "API key(s) missing. Please get an API key from <a href='https://www.google."
507
- "com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</"
508
- "a> (free!)"
509
- msgstr ""
510
- "Nedostaje/u API ključ(evi). Mogu se zatražiti na <a href='https://www."
511
- "google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/"
512
- "create</a> (besplatno!)"
513
-
514
- #: includes/class-bwp-recaptcha.php:548
515
- msgid "Notice"
516
- msgstr "Obavijest"
517
 
518
- #: includes/class-bwp-recaptcha.php:548
519
  msgid ""
520
  "You are enabling Akismet integration but Akismet is not currently active. "
521
  "Please activate Akismet for the integration to work."
@@ -523,63 +633,256 @@ msgstr ""
523
  "Omogućili ste Akismet integraciju ali Akismet trenutno nije aktivan. "
524
  "Aktivirajte Akismet kako bi integracija proradila."
525
 
526
- #: includes/class-bwp-recaptcha.php:671
 
 
 
 
 
 
 
 
 
 
527
  msgid "Your comment was identified as spam, please complete the CAPTCHA below:"
528
  msgstr "Vaš komentar je prepoznat kao spam, molimo popunite CAPTCHU:"
529
 
530
- #: includes/class-bwp-recaptcha.php:714
531
- msgid ""
532
- "To use reCAPTCHA you must get an API key from <a href='https://www.google."
533
- "com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>"
 
 
 
 
 
 
 
534
  msgstr ""
535
- "Za korištenje reCAPTCHA potrebno je preuzeti API ključ sa <a href='https://"
536
- "www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/"
537
- "admin/create</a>"
538
 
539
- #: includes/class-bwp-recaptcha.php:763 includes/class-bwp-recaptcha.php:808
540
- msgid "<strong>ERROR</strong>: Unknown captcha error."
541
- msgstr "<strong>POGREŠKA</strong>: Nepoznata captcha pogreška"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
542
 
543
- #: includes/class-bwp-recaptcha.php:878
544
  msgid "this link"
545
  msgstr "ovu poveznicu"
546
 
547
- #: includes/class-bwp-recaptcha.php:880
548
- msgid ""
549
- "There is some problem with your reCAPTCHA API keys, please double check them."
550
- msgstr "Postoji problem s reCAPTCHA API ključevima, provjerite ih još jednom."
551
 
552
- #: includes/class-bwp-recaptcha.php:882
553
- msgid "Unknown error. Please contact the administrator for more info."
554
- msgstr "Nepoznata greška. Kontaktirajte administratora za više informacija."
555
 
556
- #: includes/class-bwp-recaptcha-cf7.php:107
557
- msgid "This reCAPTCHA tag is provided by the BWP reCAPTCHA WordPress plugin."
558
- msgstr ""
559
- "Ovaj reCAPTCHA tag je dodjeljen od strane BWP reCAPTCHA WordPress dodatka."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
560
 
561
- #: includes/class-bwp-recaptcha-cf7.php:110
562
- msgid ""
563
- "Please refer to <a target=\"_blank\" href=\"http://betterwp.net/wordpress-"
564
- "plugins/bwp-recaptcha/#customization\">BWP reCAPTCHA's documentation </a> "
565
- "for a quick guide on how to customize the look and feel of this tag."
566
- msgstr ""
567
- "Pogledaj na <a target=\"_blank\" href=\"http://betterwp.net/wordpress-"
568
- "plugins/bwp-recaptcha/#customization\">BWP reCAPTCHA dokumentaciju </a> za "
569
- "kratke upute kako promijeniti izgled ovog taga."
570
 
571
- #: includes/class-bwp-recaptcha-cf7.php:116
572
- msgid "Name"
573
- msgstr "Ime"
574
 
575
- #: includes/class-bwp-recaptcha-cf7.php:123
576
- msgid "Copy this code and paste it into the form left."
577
- msgstr "Kopiraj ovaj dio koda i zalijepi lijevo u polje forme"
578
 
579
- #: includes/bwp-option-page/includes/class-bwp-option-page.php:80
580
- msgid "Plugin Configurations"
581
- msgstr "Postavke dodatka"
 
 
 
 
 
 
582
 
583
- #: includes/bwp-option-page/includes/class-bwp-option-page.php:398
584
- msgid "Save Changes"
585
- msgstr "Spremi promjene"
 
 
 
 
 
 
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: BWP reCAPTCHA\n"
4
+ "Report-Msgid-Bugs-To: contact@betterwp.net\n"
5
+ "POT-Creation-Date: 2016-01-12 23:47+0700\n"
6
+ "PO-Revision-Date: 2016-01-12 15:23+0700\n"
7
  "Last-Translator: Gospodin Bajrudin <gbajro@gmail.com>\n"
8
  "Language-Team: Gospodin Bajrudin <gbajro@gmail.com>\n"
9
+ "Language: hr\n"
10
  "MIME-Version: 1.0\n"
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
14
  "X-Poedit-Basepath: .\n"
15
  "X-Poedit-SourceCharset: UTF-8\n"
16
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
17
+ "X-Generator: Poedit 1.8.5\n"
 
18
  "X-Poedit-SearchPath-0: .\n"
19
 
20
+ #: vendor/kminh/bwp-framework/src/class-bwp-version.php:32
21
  #, php-format
22
  msgid ""
23
  "%s requires WordPress <strong>%s</strong> or higher and PHP <strong>%s</"
28
  "strong> ili noviji. Ovaj dodatak nece raditi dok ne azurirate svoj softver. "
29
  "Molimo deaktivirajte ovaj dodatak."
30
 
31
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:411
32
+ msgid "... or any amount!"
33
+ msgstr "... ili bilo koja svota!"
34
 
35
+ #: includes/class-bwp-recaptcha.php:1006 includes/class-bwp-recaptcha.php:1101
36
+ #, fuzzy
37
+ msgid ""
38
+ "<em>Below you will see how your reCAPTCHA will look. Note that this might "
39
+ "differ on your actual pages.</em>"
40
+ msgstr ""
41
+ "<em>Ispod je prikaz izgleda reCAPTCHE. Može se razlikovati na pravoj web "
42
+ "stranici.<br /></em>"
43
 
44
+ #: includes/class-bwp-recaptcha.php:118
45
+ msgid ""
46
+ "<strong>ERROR:</strong> Incorrect or empty reCAPTCHA response, please try "
47
+ "again."
48
+ msgstr ""
49
+ "<strong>POGREŠKA:</strong> Netočan ili prazan reCAPTCHA odgovor, pokušajte "
50
+ "ponovno."
51
 
52
+ #: includes/class-bwp-recaptcha.php:867
53
+ msgid "A private (secret) key used to authenticate user's response."
54
+ msgstr ""
55
+ "Privatni ključ (tajni) koji se koristi za provjeru (autentikaciju) "
56
+ "korisnikova odgovora."
57
 
58
+ #: includes/class-bwp-recaptcha.php:861
59
+ msgid "A public key used to request captchas from reCAPTCHA server."
60
+ msgstr "Javni ključ koristi se za dohvat CAPTCHE sa reCAPTCHA poslužitelja."
61
 
62
+ #: includes/class-bwp-recaptcha.php:1193
63
+ #, php-format
64
  msgid ""
65
+ "API key(s) missing. Please get an API key from <a href=\"%1$s\">%1$s</a> "
66
+ "(free!)"
67
+ msgstr ""
68
 
69
+ #: includes/provider/v1.php:165
70
+ msgid "About reCAPTCHA"
71
+ msgstr "O reCAPTCHA"
72
 
73
+ #: includes/class-bwp-recaptcha.php:1021 includes/class-bwp-recaptcha.php:1123
74
+ msgid ""
75
+ "Add additional CSS rules to all recaptcha instances. You can edit them below."
76
+ msgstr ""
77
 
78
+ #: includes/class-bwp-recaptcha.php:756
79
+ msgid ""
80
+ "Add reCAPTCHA to Contact Form 7. This only works if you have Contact Form 7 "
81
+ "activated."
82
+ msgstr ""
83
 
84
+ #: includes/class-bwp-recaptcha.php:827
85
+ msgid ""
86
+ "Add the <code>recaptcha</code> shortcode tag to your Contact Form 7 forms."
87
+ msgstr ""
88
 
89
+ #: includes/class-bwp-recaptcha.php:773
90
+ #, fuzzy
91
+ msgid "After comment field"
92
+ msgstr "Odmah odobri komentar"
93
 
94
+ #: includes/class-bwp-recaptcha.php:774
95
+ msgid "After form fields (name, email, website)"
96
+ msgstr ""
97
+
98
+ #: includes/class-bwp-recaptcha.php:819
99
+ msgid "After redirected, auto fill the comment field with previous comment."
100
+ msgstr ""
101
 
102
+ #: includes/class-bwp-recaptcha.php:708
103
+ #, fuzzy
104
+ msgid "Akismet Integration for comment form"
105
+ msgstr "Akismet Integracija (za komentare)"
106
 
107
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:438
108
+ msgid "All options have been saved."
109
+ msgstr "Sve opcije su spremljene."
110
 
111
+ #: includes/class-bwp-recaptcha.php:781
112
+ msgid "Approve comment immediately"
113
+ msgstr "Odmah odobri komentar"
114
 
115
+ #: includes/class-bwp-recaptcha.php:636
116
+ msgid "Auto detected"
117
+ msgstr ""
 
118
 
119
+ #: includes/class-bwp-recaptcha.php:705
120
+ msgid "Auto fill comment field"
121
+ msgstr ""
122
 
123
+ #: includes/class-bwp-recaptcha.php:1114
124
+ msgid "Auto-detected"
125
+ msgstr ""
126
 
127
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:521
128
+ msgid "BWP Gems"
129
+ msgstr ""
130
 
131
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:531
132
+ msgid "BWP News"
133
+ msgstr ""
134
 
135
+ #: includes/class-bwp-recaptcha.php:595
136
+ msgid "BWP reCAPTCHA General Options"
137
+ msgstr "BWP reCAPTCHA Globalne Opcije"
138
 
139
+ #: includes/class-bwp-recaptcha.php:604
140
+ msgid "BWP reCAPTCHA Theme Options"
141
+ msgstr "BWP reCAPTCHA Opcije Teme"
142
 
143
+ #: includes/class-bwp-recaptcha.php:585
144
+ msgid "Better WordPress reCAPTCHA"
145
+ msgstr "Better WordPress reCAPTCHA"
146
 
147
+ #: includes/class-bwp-recaptcha.php:1013
148
+ msgid "Black Theme"
149
+ msgstr "Crna Tema"
150
+
151
+ #: includes/class-bwp-recaptcha.php:703
152
+ msgid "Captcha position"
153
  msgstr ""
 
 
154
 
155
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:439
156
+ msgid "Check out this cool plugin"
157
+ msgstr ""
158
+
159
+ #: includes/class-bwp-recaptcha.php:1014
160
+ msgid "Clean Theme"
161
+ msgstr "Clean (čista) Tema"
162
+
163
+ #: includes/class-bwp-recaptcha.php:787
164
+ msgid "Comment form"
165
+ msgstr ""
166
+
167
+ #: includes/class-bwp-recaptcha.php:1111
168
+ msgid "Compact"
169
+ msgstr ""
170
+
171
+ #: includes/class-bwp-recaptcha.php:711
172
+ msgid "Contact Form 7 Integration"
173
+ msgstr ""
174
+
175
+ #: includes/addons/contact-form-7/captcha-shortcode.php:205
176
+ msgid "Copy this code and paste it into the form left."
177
+ msgstr "Kopiraj ovaj dio koda i zalijepi lijevo u polje forme"
178
+
179
+ #: includes/class-bwp-recaptcha.php:1015
180
+ msgid "Custom Theme (use CSS)"
181
+ msgstr "Vlastita tema (koristi CSS)"
182
+
183
+ #: includes/class-bwp-recaptcha.php:1107
184
+ msgid "Dark"
185
+ msgstr ""
186
+
187
+ #: includes/class-bwp-recaptcha.php:1011
188
+ msgid "Default Theme (Red)"
189
+ msgstr "Zadana Tema (Crvena)"
190
+
191
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:1530
192
+ msgid "Dismiss this notice."
193
+ msgstr ""
194
+
195
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:405
196
+ #, php-format
197
+ msgid "Donate to %s"
198
+ msgstr "Donirati %s"
199
+
200
+ #: includes/class-bwp-recaptcha.php:992 includes/class-bwp-recaptcha.php:1087
201
+ msgid "Enable custom CSS"
202
+ msgstr ""
203
+
204
+ #: includes/class-bwp-recaptcha.php:700
205
+ #, fuzzy
206
+ msgid "Enable this plugin for"
207
+ msgstr "omogućeno kod forme za prijavu."
208
+
209
+ #: includes/class-bwp-recaptcha.php:120
210
  #, php-format
211
  msgid ""
212
  "Error: Incorrect or empty reCAPTCHA response, please click the back button "
215
  "Pogreška: Netočan ili prazan reCAPTCHA odgovor, molimo kliknite tipku natrag "
216
  "na Vašem pregledniku ili kliknite na %s za vratiti se."
217
 
218
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:371
219
+ msgid "FAQ"
220
+ msgstr "FAQ"
221
+
222
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:409
223
+ msgid "Five cups! $25.00"
224
+ msgstr "Pet šalica! $25.00"
225
+
226
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:548
227
+ msgid "Follow"
228
+ msgstr ""
229
+
230
+ #: includes/class-bwp-recaptcha.php:744
231
+ #, fuzzy, php-format
232
+ msgid ""
233
+ "For this plugin to work, you will need a pair of API keys, which is "
234
+ "available for free <a href=\"%s\" target=\"_blank\">here</a>. Once you have "
235
+ "created those two keys for the current domain, simply paste them below.</em>"
236
+ msgstr ""
237
+ "<em><strong>Pažnja:</strong> Kako bi ovaj dodatak mogao raditi, potrebno je "
238
+ "koristiti API ključeve (javni i privatni), koji su besplatno dostupni <a "
239
+ "href=\"https://www.google.com/recaptcha/admin/create\" target=\"_blank"
240
+ "\">ovdje</a>. Nakon dobivanja ključeva za Vašu domenu, unesite ih ispod.</em>"
241
+
242
+ #: includes/class-bwp-recaptcha.php:697
243
+ msgid "Force https"
244
+ msgstr ""
245
+
246
+ #: includes/class-bwp-recaptcha.php:159 includes/class-bwp-recaptcha.php:596
247
  msgid "General Options"
248
  msgstr "Globalne Opcije"
249
 
250
+ #: includes/provider/v1.php:162
251
+ msgid "Get another challenge"
252
+ msgstr "Ponovno generiraj kombinaciju"
253
 
254
+ #: includes/provider/v1.php:163
255
+ msgid "Get audio reCAPTCHA"
256
+ msgstr "Generiraj zvučni reCAPTCHA"
257
 
258
+ #: includes/provider/v1.php:164
259
+ #, fuzzy
260
+ msgid "Get image reCAPTCHA"
261
+ msgstr "Generiraj slikovni reCAPTCHA"
262
 
263
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:374
264
+ msgid "Got a problem with this plugin? Please say it out loud!"
265
+ msgstr ""
266
 
267
+ #: includes/class-bwp-recaptcha.php:701
268
+ #, fuzzy
269
+ msgid "Hide captcha for"
270
+ msgstr "Sakrij CAPTCHU za"
271
 
272
+ #: includes/class-bwp-recaptcha.php:782
273
+ msgid "Hold comment in moderation queue"
274
+ msgstr "Zadrži komentar u moderaciji"
275
 
276
+ #: includes/class-bwp-recaptcha.php:710
277
+ #, fuzzy
278
+ msgid "If correct captcha response"
279
+ msgstr "Za točan CAPTCHA odgovor"
280
 
281
+ #: includes/class-bwp-recaptcha.php:704
282
+ #, fuzzy
283
+ msgid "If invalid captcha response"
284
+ msgstr "Ako je pokrešan ili prazan odgovor"
285
 
286
+ #: includes/class-bwp-recaptcha.php:880
287
+ msgid ""
288
+ "If you encounter error such as <code>Unknown error (invalid-json)</code>when "
289
+ "submitting a form, try selecting a specific request method here."
290
+ msgstr ""
291
 
292
+ #: includes/class-bwp-recaptcha.php:1054
293
+ #, php-format
294
+ msgid ""
295
+ "If you want to add custom translations, please read <a href=\"%s\" target="
296
+ "\"_blank\">this tip</a>."
297
+ msgstr ""
298
 
299
+ #: includes/class-bwp-recaptcha.php:1207
300
+ #, php-format
301
+ msgid ""
302
+ "In order to use the nocaptcha recaptcha (recaptcha v2), you need at least "
303
+ "<strong>PHP 5.3.2</strong> (your current PHP version is <strong>%s</"
304
+ "strong>), so only recaptcha v1 can be used. It is recommended to contact "
305
+ "your host to know how to update your current version of PHP."
306
+ msgstr ""
307
 
308
+ #: includes/class-bwp-recaptcha.php:125
309
+ #, fuzzy
310
+ msgid "Incorrect or empty reCAPTCHA response, please try again."
311
+ msgstr ""
312
+ "<strong>POGREŠKA:</strong> Netočan ili prazan reCAPTCHA odgovor, pokušajte "
313
+ "ponovno."
314
 
315
+ #: includes/addons/contact-form-7/captcha-shortcode.php:170
316
+ msgid "Insert Tag"
317
+ msgstr ""
318
 
319
+ #: includes/class-bwp-recaptcha.php:753
320
+ msgid "Integrate the comment form with Akismet for better end-user experience."
321
+ msgstr ""
322
 
323
+ #: includes/class-bwp-recaptcha.php:709
324
+ #, fuzzy
325
+ msgid "Integrate with Akismet"
326
+ msgstr "Integrati s Akismetom?"
327
 
328
+ #: includes/class-bwp-recaptcha.php:712
329
+ #, fuzzy
330
+ msgid "Integrate with Contact Form 7"
331
+ msgstr "Integrati s Akismetom?"
332
 
333
+ #: includes/class-bwp-recaptcha.php:706 includes/class-bwp-recaptcha.php:707
334
+ #: includes/class-bwp-recaptcha.php:714
335
+ #, fuzzy
336
+ msgid "Invalid captcha error message"
337
+ msgstr "Prikaži poruku o pogrešci"
338
 
339
+ #: includes/class-bwp-recaptcha.php:886
340
+ msgid ""
341
+ "It is best to put comments identified as spam in moderation queue so you are "
342
+ "able to review and instruct Akismet to correctly handle similar comments in "
343
+ "the future."
344
+ msgstr ""
345
 
346
+ #: includes/class-bwp-recaptcha.php:1088
347
+ msgid "Language"
348
+ msgstr ""
349
 
350
+ #: includes/class-bwp-recaptcha.php:993
351
+ #, fuzzy
352
+ msgid "Language for built-in themes"
353
+ msgstr "Odaberi jezik za ugrađene teme"
354
 
355
+ #: includes/class-bwp-recaptcha.php:1106
356
+ msgid "Light"
357
+ msgstr ""
358
 
359
+ #: includes/class-bwp-recaptcha.php:793
360
+ msgid "Login form"
361
+ msgstr ""
362
 
363
+ #: includes/class-bwp-recaptcha.php:699
364
+ msgid "Main Functionality"
365
+ msgstr ""
366
 
367
+ #: includes/class-bwp-recaptcha.php:816
368
+ msgid "Make requests to recaptcha server always secured."
369
+ msgstr ""
370
 
371
+ #: includes/class-bwp-recaptcha.php:317
372
+ msgid "Manage Options"
373
+ msgstr "Upravljanje opcijama"
374
 
375
+ #: includes/addons/contact-form-7/captcha-shortcode.php:159
376
+ #: includes/addons/contact-form-7/captcha-shortcode.php:196
377
+ msgid "Name"
378
+ msgstr "Ime"
379
 
380
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:503
381
+ msgid "Need a highly customizable theme?"
382
+ msgstr ""
383
 
384
+ #: includes/class-bwp-recaptcha.php:1110
385
+ msgid "Normal"
 
 
 
386
  msgstr ""
 
 
 
387
 
388
+ #: includes/class-bwp-recaptcha.php:1205 includes/class-bwp-recaptcha.php:1227
389
+ msgid "Notice"
390
+ msgstr "Obavijest"
391
+
392
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:410
393
+ msgid "One LL-cup!!! $50.00"
394
+ msgstr "Jedna LL-šalica!!! $50.00"
395
+
396
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:407
397
+ msgid "One cup $5.00"
398
+ msgstr "Jedna šalica $5.00"
399
+
400
+ #: includes/addons/contact-form-7/captcha-shortcode.php:225
401
+ #, fuzzy, php-format
402
  msgid ""
403
+ "Please refer to <a target=\"_blank\" href=\"%s\">BWP reCAPTCHA's "
404
+ "documentation</a> for a quick guide on how to customize the look and feel of "
405
+ "this tag."
406
  msgstr ""
407
+ "Pogledaj na <a target=\"_blank\" href=\"http://betterwp.net/wordpress-"
408
+ "plugins/bwp-recaptcha/#customization\">BWP reCAPTCHA dokumentaciju </a> za "
409
+ "kratke upute kako promijeniti izgled ovog taga."
410
 
411
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:93
412
+ msgid "Plugin Configurations"
413
+ msgstr "Postavke dodatka"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
414
 
415
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:375
416
+ msgid "Plugin Support"
417
+ msgstr ""
418
 
419
+ #: includes/class-bwp-recaptcha.php:995 includes/class-bwp-recaptcha.php:1090
420
+ msgid "Preview your reCAPTCHA"
421
+ msgstr "Pregledaj reCAPTCHU"
422
 
423
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:378
424
+ msgid "Rate this plugin 5 stars if you like it, thank you!"
425
+ msgstr ""
426
 
427
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:379
428
+ msgid "Rate this plugin 5 stars!"
429
+ msgstr ""
430
 
431
+ #: includes/class-bwp-recaptcha.php:1045
432
+ #, php-format
433
+ msgid ""
434
+ "Read <a href=\"%s#recaptcha-version-1\" target=\"_blank\">here</a> to know "
435
+ "how to use your own CSS for the Custom Theme."
436
+ msgstr ""
437
+
438
+ #: includes/class-bwp-recaptcha.php:316
439
+ msgid "Read Profile"
440
+ msgstr "Provjeri profil"
441
+
442
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:370
443
+ msgid "Read this first before asking any question!"
444
+ msgstr ""
445
+
446
+ #: includes/class-bwp-recaptcha.php:777
447
+ #, fuzzy
448
+ msgid "Redirect commenter back to the comment form with error message"
449
+ msgstr "Preusmjeri korisnika natrag formu za komentare"
450
 
451
+ #: includes/class-bwp-recaptcha.php:790
452
+ #, fuzzy
453
+ msgid "Registration form (user/site registration)"
454
  msgstr "omogućeno kod registracijske forme (za korisnike i stranice) "
455
 
456
+ #: includes/class-bwp-recaptcha.php:698
457
+ msgid "Request method"
458
+ msgstr ""
459
 
460
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:305
461
+ msgid "Save Changes"
462
+ msgstr "Spremi promjene"
463
 
464
+ #: includes/class-bwp-recaptcha.php:694
465
+ msgid "Secret Key"
466
+ msgstr ""
467
 
468
+ #: includes/class-bwp-recaptcha.php:1129
469
+ msgid "Set to 0 to disable."
470
+ msgstr ""
471
+
472
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:1315
473
+ msgid "Settings"
474
+ msgstr "Postavke"
475
 
476
+ #: includes/class-bwp-recaptcha.php:751
477
+ #, fuzzy
478
+ msgid "Settings that are applied to comment forms only."
479
+ msgstr "Akismet Integracija (za komentare)"
480
+
481
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:431
482
+ #, fuzzy
483
+ msgid "Share the love for this plugin!"
484
+ msgstr "Koristi CSS koji je došao s ovim pluginom?"
485
+
486
+ #: includes/class-bwp-recaptcha.php:778
487
+ msgid "Show an error page just like WordPress does"
488
+ msgstr "Prikaži stranicu o pogrešci kao što to radi WordPress"
489
+
490
+ #: includes/class-bwp-recaptcha.php:805
491
+ #, fuzzy
492
  msgid ""
493
+ "Show captcha only when Akismet identifies a comment as spam. Highly "
494
+ "recommended if you do not want to force your visitors to enter a captcha "
495
  "every time."
496
  msgstr ""
497
  "reCAPTCHA će se prikazati samo ako Akismet identificira komentar kao spam. "
498
  "Preporučeno ukoliko se želi smanjiti broj prikazivanja reCAPTCHE "
499
  "posjetiteljima."
500
 
501
+ #: includes/class-bwp-recaptcha.php:693
502
+ #, fuzzy
503
+ msgid "Site Key"
504
+ msgstr "Privatni ključ"
 
 
 
505
 
506
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:541
507
+ msgid "Subscribe"
508
  msgstr ""
 
 
509
 
510
+ #: includes/class-bwp-recaptcha.php:994 includes/class-bwp-recaptcha.php:1089
511
+ msgid "Tabindex for captcha input field"
512
+ msgstr "Tab kod polja za unos"
 
 
 
 
513
 
514
+ #: includes/class-bwp-recaptcha.php:162 includes/class-bwp-recaptcha.php:605
515
+ msgid "Theme Options"
516
+ msgstr "Opcije teme"
517
 
518
+ #: includes/provider/abstract-provider.php:103
519
+ msgid ""
520
+ "There is some problem with your reCAPTCHA API keys, please double check them."
521
+ msgstr "Postoji problem s reCAPTCHA API ključevima, provjerite ih još jednom."
522
 
523
+ #: includes/class-bwp-recaptcha.php:754 includes/class-bwp-recaptcha.php:822
524
+ #, php-format
525
  msgid ""
526
+ "This feature requires an active <a target=\"_blank\" href=\"%s\">PHP "
527
+ "session</a>."
 
 
528
  msgstr ""
 
 
 
 
529
 
530
+ #: includes/class-bwp-recaptcha.php:897
531
+ msgid "This is shown on the standard WordPress error page."
532
+ msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
533
 
534
+ #: includes/class-bwp-recaptcha.php:892
535
+ #, fuzzy
536
+ msgid ""
537
+ "This is shown when the commenter is redirected back to the comment form."
538
+ msgstr "Preusmjeri korisnika natrag formu za komentare"
539
 
540
+ #: includes/class-bwp-recaptcha.php:905
541
+ msgid ""
542
+ "This message is shown when invalid captcha response is treated as a standard "
543
+ "validation error. Leave blank to not use."
544
+ msgstr ""
545
 
546
+ #: includes/addons/contact-form-7/captcha-shortcode.php:220
547
+ msgid "This reCAPTCHA tag is provided by the BWP reCAPTCHA WordPress plugin."
548
+ msgstr ""
549
+ "Ovaj reCAPTCHA tag je dodjeljen od strane BWP reCAPTCHA WordPress dodatka."
550
 
551
+ #: includes/provider/v1.php:96
552
+ #, php-format
553
+ msgid "To use reCAPTCHA you must get an API key from <a href=\"%1$s\">%1$s</a>"
554
+ msgstr ""
555
 
556
+ #: includes/class-bwp-recaptcha.php:873
557
  msgid ""
558
+ "To verify a captcha response, this plugin needs to send requests to the "
559
+ "reCAPTCHA server, using a specific request method. <br /><br />By default, "
560
+ "BWP reCAPTCHA use the first available request method, be it Socket "
561
+ "(<code>fsockopen</code>), cURL, or <code>file_get_contents</code>."
562
  msgstr ""
 
 
563
 
564
+ #: includes/class-bwp-recaptcha.php:713
565
+ msgid "Treat invalid captcha as spam"
566
+ msgstr ""
 
 
 
 
 
 
 
 
567
 
568
+ #: includes/class-bwp-recaptcha.php:830
569
+ msgid "Treat invalid captcha response as spam instead of validation error"
570
+ msgstr ""
571
 
572
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:408
573
+ msgid "Two cups $10.00"
574
+ msgstr "Dvije šalice $10.00"
575
 
576
+ #: includes/provider/v1.php:170
577
+ msgid "Type what you hear"
 
 
 
578
  msgstr ""
 
 
579
 
580
+ #: includes/provider/v1.php:169
581
+ msgid "Type what you see"
582
  msgstr ""
 
 
583
 
584
+ #: includes/class-bwp-recaptcha.php:810
585
+ #, fuzzy
586
+ msgid "Uncheck to use different key pairs for this site."
587
+ msgstr "odznači ako želiš za koristiti druge ključeve za svoju stranicu "
588
+
589
+ #: includes/provider/abstract-provider.php:107
590
+ #, fuzzy, php-format
591
+ msgid "Unknown error (%s). Please contact an administrator for more info."
592
+ msgstr "Nepoznata greška. Kontaktirajte administratora za više informacija."
593
+
594
+ #: includes/class-bwp-recaptcha.php:991
595
+ msgid "Use default CSS"
596
  msgstr ""
 
 
597
 
598
+ #: includes/class-bwp-recaptcha.php:692
599
+ msgid "Use main site's keys"
600
+ msgstr "Koristite ključeve glavne stranice"
601
+
602
+ #: includes/class-bwp-recaptcha.php:696
603
+ #, fuzzy
604
+ msgid "Use reCAPTCHA version 1"
605
+ msgstr "BWP reCAPTCHA Globalne Opcije"
606
+
607
+ #: includes/class-bwp-recaptcha.php:813
608
  msgid ""
609
+ "Use the oldschool recaptcha instead of the new <em>nocaptcha</em> recaptcha."
 
 
 
610
  msgstr ""
 
 
 
 
611
 
612
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:416
613
+ msgid "Via"
 
 
 
 
614
  msgstr ""
 
 
 
615
 
616
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:827
617
+ msgid "View more info in a separate tab"
618
+ msgstr ""
619
 
620
+ #: includes/class-bwp-recaptcha.php:1192
621
  msgid "Warning"
622
  msgstr "Upozorenje"
623
 
624
+ #: includes/class-bwp-recaptcha.php:1012
625
+ msgid "White Theme"
626
+ msgstr "Bijela Tema"
 
 
 
 
 
 
 
 
 
 
627
 
628
+ #: includes/class-bwp-recaptcha.php:1228
629
  msgid ""
630
  "You are enabling Akismet integration but Akismet is not currently active. "
631
  "Please activate Akismet for the integration to work."
633
  "Omogućili ste Akismet integraciju ali Akismet trenutno nije aktivan. "
634
  "Aktivirajte Akismet kako bi integracija proradila."
635
 
636
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:565
637
+ #, php-format
638
+ msgid "You are using version %s!"
639
+ msgstr "Koristite inačicu %s!"
640
+
641
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:391
642
+ msgid ""
643
+ "You can buy me some special coffees if you appreciate my work, thank you!"
644
+ msgstr "Možete mi kupiti specijalnu kavu ako cijenite moj posao, hvala Vam!"
645
+
646
+ #: includes/class-bwp-recaptcha.php:1376
647
  msgid "Your comment was identified as spam, please complete the CAPTCHA below:"
648
  msgstr "Vaš komentar je prepoznat kao spam, molimo popunite CAPTCHU:"
649
 
650
+ #: includes/class-bwp-recaptcha.php:848
651
+ msgid "approved comment(s)."
652
+ msgstr "Odobren(i) komentar(i)."
653
+
654
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:524
655
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:534
656
+ msgid "loading..."
657
+ msgstr ""
658
+
659
+ #: includes/class-bwp-recaptcha.php:691
660
+ msgid "reCAPTCHA API Keys"
661
  msgstr ""
 
 
 
662
 
663
+ #: includes/class-bwp-recaptcha.php:695
664
+ #, fuzzy
665
+ msgid "reCAPTCHA Settings"
666
+ msgstr "BWP reCAPTCHA Opcije Teme"
667
+
668
+ #: includes/class-bwp-recaptcha.php:702
669
+ #, fuzzy
670
+ msgid "reCAPTCHA for comment form"
671
+ msgstr "omogućeno kod komentara"
672
+
673
+ #: includes/class-bwp-recaptcha.php:1086
674
+ #, fuzzy
675
+ msgid "reCAPTCHA size"
676
+ msgstr "O reCAPTCHA"
677
+
678
+ #: includes/class-bwp-recaptcha.php:990 includes/class-bwp-recaptcha.php:1085
679
+ #, fuzzy
680
+ msgid "reCAPTCHA theme"
681
+ msgstr "BWP reCAPTCHA Opcije Teme"
682
+
683
+ #: includes/class-bwp-recaptcha.php:796
684
+ msgid "registered users <em>(even without any capabilities)</em>."
685
+ msgstr "registrirani korisnici <em>(čak i bez ikakvih mogućnosti)</em>."
686
 
687
+ #: includes/class-bwp-recaptcha.php:1554
688
  msgid "this link"
689
  msgstr "ovu poveznicu"
690
 
691
+ #: includes/class-bwp-recaptcha.php:799
692
+ msgid "users who can"
693
+ msgstr "korisnici koji mogu"
 
694
 
695
+ #: includes/class-bwp-recaptcha.php:802
696
+ msgid "visitors who have at least"
697
+ msgstr "posjetitelji koji imaju najmanje"
698
 
699
+ #~ msgid ""
700
+ #~ "<em><strong>Note:</strong> Above you can select some built-in languages. "
701
+ #~ "If you would like to add your own language, please read <a href="
702
+ #~ "\"%s#customization\" target=\"_blank\">this guide</a>.</em>"
703
+ #~ msgstr ""
704
+ #~ "<em><strong>Pažnja:</strong> Ovdje se mogu odabrati jezici za "
705
+ #~ "korištenje . Ukoliko želite dodati svoj, pročitajte <a href="
706
+ #~ "\"%s#customization\" target=\"_blank\">ove upute</a>.</em>"
707
+
708
+ #~ msgid ""
709
+ #~ "<em><strong>Note:</strong> Now you may wonder, why put the comment in the "
710
+ #~ "spam queue? The benefit is Akismet will be able to mark the comment as "
711
+ #~ "False Positive, and thus will not possibly block that comment in the "
712
+ #~ "future. However, it is best to just put the comment in moderation queue "
713
+ #~ "as next time Akismet will put such comment in moderation queue "
714
+ #~ "immediately without the need of a CAPTCHA.</em>"
715
+ #~ msgstr ""
716
+ #~ "<em><strong>Pažnja:</strong> Zašto staviti komentar u spam direktorij? "
717
+ #~ "Akismet će provjeriti i biti u mogućnosti označiti komentar kao "
718
+ #~ "legitiman, te u budućnosti ne blokirati takav komentar. U principu, "
719
+ #~ "najbolje je staviti komentar u moderaciju, te će svaki slijedeći puta "
720
+ #~ "Akismet postaviti komentar direktno u moderaciju, bez potrebe za "
721
+ #~ "unošenjem CAPTCHA koda.</em>"
722
+
723
+ #~ msgid ""
724
+ #~ "<em><strong>Note:</strong> The four built-in captcha themes will look OK "
725
+ #~ "in most WordPress themes; However, some times it is better to control how "
726
+ #~ "reCAPTCHA looks using CSS. Please read <a href=\"%s#customization\" "
727
+ #~ "target=\"_blank\">this guide</a> if you would like to do so.</em>"
728
+ #~ msgstr ""
729
+ #~ "<em><strong>Pažnja:</strong> Četiri ugrađene teme će izgledati dobro u "
730
+ #~ "većini WordPress tema. Ponekad je bolje koristiti CSS za kontroliranje "
731
+ #~ "reCAPTCHA izgleda. Pročitajte <a href=\"%s#customization\" target=\"_blank"
732
+ #~ "\">ove upute</a> ako želite promijeniti izgled.</em>"
733
+
734
+ #~ msgid ""
735
+ #~ "<em>Integrate with Akismet for better end-user experience. reCAPTCHA is "
736
+ #~ "optional and <strong>NO</strong> spam comment will be added to the spam/"
737
+ #~ "moderation queue, except likely legitimate comments. This makes the task "
738
+ #~ "of identifying sincere comments much easier. This integration is "
739
+ #~ "currently in beta stage.</em>"
740
+ #~ msgstr ""
741
+ #~ "<em>Integrati s Akismet dodatkom za bolje korisničko iskustvo. reCAPTCHA "
742
+ #~ "je neobavezna i <strong>NIJEDAN</strong> spam komentar neće se dodati u "
743
+ #~ "direktorij za spam/moderaciju, osim komentara koji su najvjerojatnije "
744
+ #~ "ispravni. To olakšava posao prepoznavanja ispravnih komentara. Ova "
745
+ #~ "integracija je trenutno u beta fazi.</em>"
746
+
747
+ #~ msgid ""
748
+ #~ "<em>This section allows you to determine when to show reCAPTCHA and how "
749
+ #~ "this plugin reacts to errors.</em>"
750
+ #~ msgstr ""
751
+ #~ "<em>Ovaj dio omogućava pregled opcija o prikazu reCAPTCHE i kako će se "
752
+ #~ "ovaj dodatak ponašati u slučaju pogrešaka.</em>"
753
+
754
+ #~ msgid "<strong>ERROR</strong>: Unknown captcha error."
755
+ #~ msgstr "<strong>POGREŠKA</strong>: Nepoznata captcha pogreška"
756
+
757
+ #~ msgid ""
758
+ #~ "API key(s) missing. Please get an API key from <a href='https://www."
759
+ #~ "google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/"
760
+ #~ "create</a> (free!)"
761
+ #~ msgstr ""
762
+ #~ "Nedostaje/u API ključ(evi). Mogu se zatražiti na <a href='https://www."
763
+ #~ "google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/"
764
+ #~ "create</a> (besplatno!)"
765
+
766
+ #~ msgid ""
767
+ #~ "Basically, this should be 4 if you place the captcha before the textarea, "
768
+ #~ "and 5 if you put it after. Set to 0 to disable."
769
+ #~ msgstr ""
770
+ #~ "Ovo bi trebalo biti 4 ako će se captcha prikazivati prije unosa teksta, a "
771
+ #~ "5 ako će se prikazivati poslije. Postaviti 0 da se onemogući."
772
+
773
+ #~ msgid "Choose a theme"
774
+ #~ msgstr "Izaberi temu"
775
+
776
+ #~ msgid "Contact"
777
+ #~ msgstr "Kontakt"
778
+
779
+ #~ msgid "Development Log"
780
+ #~ msgstr "Razvojni zapis"
781
+
782
+ #~ msgid "Dutch"
783
+ #~ msgstr "Nizozemski"
784
+
785
+ #~ msgid "English"
786
+ #~ msgstr "Engleski"
787
+
788
+ #~ msgid "Enter the numbers you hear:"
789
+ #~ msgstr "Unesite brojeve koje ste čuli:"
790
+
791
+ #~ msgid "Enter the two words in the box:"
792
+ #~ msgstr "Unesite dvije riječi u polje:"
793
+
794
+ #~ msgid "Follow me on Twitter!"
795
+ #~ msgstr "Slijedi me na Twitteru"
796
+
797
+ #~ msgid "French"
798
+ #~ msgstr "Francuski"
799
+
800
+ #~ msgid "Frequently Asked Questions"
801
+ #~ msgstr "Često postavljana pitanja"
802
+
803
+ #~ msgid "German"
804
+ #~ msgstr "Njemački"
805
+
806
+ #~ msgid "Got a problem? Send me a feedback!"
807
+ #~ msgstr "Imate problem? Pošaljite mi poruku!"
808
+
809
+ #~ msgid "Latest updates from BetterWP.net!"
810
+ #~ msgstr "Zadnje nadogradnje od BetterWP.net!"
811
+
812
+ #~ msgid "Load CSS, JS selectively?"
813
+ #~ msgstr "Učitaj CSS, JS opcionalno?"
814
+
815
+ #~ msgid "Portuguese"
816
+ #~ msgstr "Portugalski"
817
+
818
+ #~ msgid "Public Key"
819
+ #~ msgstr "Javni ključ"
820
+
821
+ #~ msgid "Put comment in spam queue"
822
+ #~ msgstr "Stavi komentar u spam direktorij"
823
+
824
+ #~ msgid "Russian"
825
+ #~ msgstr "Ruski"
826
+
827
+ #~ msgid "Spanish"
828
+ #~ msgstr "Španjolski"
829
+
830
+ #~ msgid "This Plugin is Proudly Sponsored By"
831
+ #~ msgstr "Ovaj dodatak je ponosno sponzoriran od"
832
+
833
+ #~ msgid "This is only useful when you do not use any minify or cache plugin."
834
+ #~ msgstr ""
835
+ #~ "Korisno kad se ne koristi dodaci koji uključuju spremnik (minify ili "
836
+ #~ "cache dodatak)."
837
+
838
+ #~ msgid "This plugin will be"
839
+ #~ msgstr "Ovaj dodatak će biti"
840
+
841
+ #~ msgid ""
842
+ #~ "This stylesheet is used to style the custom theme as well as the "
843
+ #~ "registration page. You can disable this or add appropriate filters to use "
844
+ #~ "your own."
845
+ #~ msgstr ""
846
+ #~ "Ovaj stil se koristi za prikaz ručno napravljene teme kao i "
847
+ #~ "registracijske stranice. Može se onemogućiti ili urediti na željeni način."
848
+
849
+ #~ msgid ""
850
+ #~ "To use reCAPTCHA you must get an API key from <a href='https://www.google."
851
+ #~ "com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/"
852
+ #~ "create</a>"
853
+ #~ msgstr ""
854
+ #~ "Za korištenje reCAPTCHA potrebno je preuzeti API ključ sa <a "
855
+ #~ "href='https://www.google.com/recaptcha/admin/create'>https://www.google."
856
+ #~ "com/recaptcha/admin/create</a>"
857
+
858
+ #~ msgid "Turkish"
859
+ #~ msgstr "Turski"
860
 
861
+ #~ msgid "Visibility Options (applied to comment forms)"
862
+ #~ msgstr "Opcije prikaza (za komentare)"
 
 
 
 
 
 
 
863
 
864
+ #~ msgid "What is reCAPTCHA?"
865
+ #~ msgstr "Što je reCAPTCHA"
 
866
 
867
+ #~ msgid "You do not have sufficient permissions to access this page."
868
+ #~ msgstr "Nemate dovoljna prava za posjetiti ovu stranicu"
 
869
 
870
+ #~ msgid ""
871
+ #~ "reCAPTCHA is a free CAPTCHA service that helps to digitize books, "
872
+ #~ "newspapers and old time radio shows. You can read more about reCAPTCHA <a "
873
+ #~ "href=\"http://www.google.com/recaptcha/learnmore\" target=\"_blank"
874
+ #~ "\">here</a>."
875
+ #~ msgstr ""
876
+ #~ "reCAPTCHA je besplatan CAPTCHA servis koji pomaže digitalizaciji knjiga, "
877
+ #~ "članaka i starih radio emisija. Više o reCAPTCHA možete saznati <a href="
878
+ #~ "\"http://www.google.com/recaptcha/learnmore\" target=\"_blank\">ovdje</a>."
879
 
880
+ #~ msgid ""
881
+ #~ "when redirect commenter back to the comment form (or when used in other "
882
+ #~ "forms such as contact forms)."
883
+ #~ msgstr ""
884
+ #~ "kod vraćanja korisnika na formular za komentar (ili kod korištenja u "
885
+ #~ "drugim formama, npr. kontakt formulara)."
886
+
887
+ #~ msgid "when show the normal error page with no redirection."
888
+ #~ msgstr "kod prikaza stranice s greškom kod koje nema preusmjeravanja"
languages/bwp-recaptcha-hu_HU.mo CHANGED
Binary file
languages/bwp-recaptcha-hu_HU.po CHANGED
@@ -1,438 +1,885 @@
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: BWP reCAPTCHA\n"
4
- "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: 2011-09-25 13:43+0700\n"
6
- "PO-Revision-Date: 2012-02-05 13:17+0100\n"
7
  "Last-Translator: Brandon <brandon@helloftranslations.net>\n"
8
  "Language-Team: \n"
 
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=utf-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
  "X-Poedit-KeywordsList: _;gettext;gettext_noop;__;_e\n"
13
  "X-Poedit-Basepath: .\n"
14
- "X-Poedit-Language: Hungarian\n"
15
  "X-Poedit-SourceCharset: utf-8\n"
16
- "X-Poedit-Country: HUNGARY\n"
17
  "X-Poedit-SearchPath-0: .\n"
18
 
19
- #: includes/class-bwp-framework.php:172
20
  #, php-format
21
- msgid "%s requires WordPress <strong>%s</strong> or higher and PHP <strong>%s</strong> or higher. The plugin will not function until you update your software. Please deactivate this plugin."
22
- msgstr "%s legalább %s WordPresst és legalább %s PHP-t igényel. A plugin nem fog működni, amíg nem frissíted a szoftvert. Kérlek kapcsold ki ezt a plugint."
 
 
 
 
 
23
 
24
- #: includes/class-bwp-framework.php:183
25
- msgid "Development Log"
26
- msgstr "Fejlesztési napló"
27
 
28
- #: includes/class-bwp-framework.php:183
29
- msgid "Frequently Asked Questions"
30
- msgstr "Gyakran Ismételt Kérdések"
 
 
 
 
 
31
 
32
- #: includes/class-bwp-framework.php:183
33
- msgid "FAQ"
34
- msgstr "GyIK"
 
 
 
 
35
 
36
- #: includes/class-bwp-framework.php:183
37
- msgid "Got a problem? Send me a feedback!"
38
- msgstr "Hibát találtál? Küldj visszajelzést!"
39
 
40
- #: includes/class-bwp-framework.php:183
41
- msgid "Contact"
42
- msgstr "Kapcsolat"
 
 
43
 
44
- #: includes/class-bwp-framework.php:190
45
- msgid "You can buy me some special coffees if you appreciate my work, thank you!"
46
- msgstr "Vehetsz nekem pár különleges kávét, ha elégedett vagy a munkámmal, köszi!"
 
 
 
47
 
48
- #: includes/class-bwp-framework.php:204
49
- msgid "Donate to "
50
- msgstr "Támogatom"
51
 
52
- #: includes/class-bwp-framework.php:206
53
- msgid "One cup $5.00"
54
- msgstr "Egy csésze $5,00"
 
55
 
56
- #: includes/class-bwp-framework.php:207
57
- msgid "Two cups $10.00"
58
- msgstr "Két csésze $10,00"
 
 
59
 
60
- #: includes/class-bwp-framework.php:208
61
- msgid "Five cups! $25.00"
62
- msgstr "Öt csésze! $25,00"
 
63
 
64
- #: includes/class-bwp-framework.php:209
65
- msgid "One LL-cup!!! $50.00"
66
- msgstr "Egy extranagy bögre!!! $50,00"
 
67
 
68
- #: includes/class-bwp-framework.php:210
69
- msgid "... or any amount!"
70
- msgstr "... vagy akármennyit!"
71
 
72
- #: includes/class-bwp-framework.php:225
73
- msgid "Latest updates from BetterWP.net!"
74
- msgstr "Legújabb hírek a BetterWP.net-től!"
75
 
76
- #: includes/class-bwp-framework.php:226
77
- msgid "Follow me on Twitter!"
78
- msgstr "Kövess Twitteren!"
 
79
 
80
- #: includes/class-bwp-framework.php:235
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  #, php-format
82
- msgid "You are using version %s!"
83
- msgstr "Te a %s verziót használod!"
84
 
85
- #: includes/class-bwp-framework.php:372
86
- msgid "Settings"
87
- msgstr "Beállítások"
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
- #: includes/class-bwp-recaptcha.php:45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  msgid "Get another challenge"
91
  msgstr "Új kihívás kérése"
92
 
93
- #: includes/class-bwp-recaptcha.php:46
94
  msgid "Get audio reCAPTCHA"
95
  msgstr "Hangkihívás kérése"
96
 
97
- #: includes/class-bwp-recaptcha.php:47
98
  msgid "Get image reCAPTCHA"
99
  msgstr "Képkihívás kérése"
100
 
101
- #: includes/class-bwp-recaptcha.php:48
102
- msgid "About reCAPTCHA"
103
- msgstr "Súgó"
 
 
 
 
 
 
 
 
 
104
 
105
- #: includes/class-bwp-recaptcha.php:52
106
- msgid "Enter the two words in the box:"
107
- msgstr "Írd ide a két szót:"
 
108
 
109
- #: includes/class-bwp-recaptcha.php:53
110
- msgid "Enter the numbers you hear:"
111
- msgstr "Írd be a hallott számokat:"
 
112
 
113
- #: includes/class-bwp-recaptcha.php:98
114
- msgid "<strong>ERROR:</strong> Incorrect or empty reCAPTCHA response, please try again."
115
- msgstr "<strong>HIBA:</strong> Helytelen vagy üres reCAPTCHA válasz, kérlek próbáld újra."
 
 
116
 
117
- #: includes/class-bwp-recaptcha.php:99
118
  #, php-format
119
- msgid "Error: Incorrect or empty reCAPTCHA response, please click the back button on your browser's toolbar or click on %s to go back."
120
- msgstr "Hiba: Helytelen vagy üres reCAPTCHA válasz,, kérlek kattints a böngésző vissza gombjára vagy nyomd meg a %s gombot a visszatéréshez."
 
 
121
 
122
- #: includes/class-bwp-recaptcha.php:119
123
- #: includes/class-bwp-recaptcha.php:250
124
- msgid "General Options"
125
- msgstr "Alapbeállítások"
 
 
 
 
126
 
127
- #: includes/class-bwp-recaptcha.php:120
128
- #: includes/class-bwp-recaptcha.php:251
129
- msgid "Theme Options"
130
- msgstr "Témabeállítások"
 
 
131
 
132
- #: includes/class-bwp-recaptcha.php:123
133
- msgid "English"
134
- msgstr "Angol"
135
 
136
- #: includes/class-bwp-recaptcha.php:124
137
- msgid "Dutch"
138
- msgstr "Holland"
139
 
140
- #: includes/class-bwp-recaptcha.php:125
141
- msgid "French"
142
- msgstr "Francia"
 
143
 
144
- #: includes/class-bwp-recaptcha.php:126
145
- msgid "German"
146
- msgstr "Német"
 
147
 
148
- #: includes/class-bwp-recaptcha.php:127
149
- msgid "Portuguese"
150
- msgstr "Portugál"
 
 
151
 
152
- #: includes/class-bwp-recaptcha.php:128
153
- msgid "Russian"
154
- msgstr "Orosz"
 
 
 
155
 
156
- #: includes/class-bwp-recaptcha.php:129
157
- msgid "Spanish"
158
- msgstr "Spanyol"
159
 
160
- #: includes/class-bwp-recaptcha.php:130
161
- msgid "Turkish"
162
- msgstr "Török"
 
163
 
164
- #: includes/class-bwp-recaptcha.php:134
165
- msgid "Read Profile"
166
- msgstr "Profil Megtekintésére"
167
 
168
- #: includes/class-bwp-recaptcha.php:135
169
- msgid "Manage Options"
170
- msgstr "Beállítások Kezelésére"
171
 
172
- #: includes/class-bwp-recaptcha.php:248
173
- msgid "Better WordPress reCAPTCHA"
174
- msgstr "Fejlettebb Wordpress reCAPTCHA"
175
 
176
- #: includes/class-bwp-recaptcha.php:250
177
- msgid "BWP reCAPTCHA General Options"
178
- msgstr "BWP reCAPTCHA Alapbeállítások"
179
 
180
- #: includes/class-bwp-recaptcha.php:251
181
- msgid "BWP reCAPTCHA Theme Options"
182
- msgstr "BWP reCAPTCHA Témabeállítások"
183
 
184
- #: includes/class-bwp-recaptcha.php:262
185
- msgid "You do not have sufficient permissions to access this page."
186
- msgstr "Nincs engedélyed a lap megtekintéséhez."
 
187
 
188
- #: includes/class-bwp-recaptcha.php:281
189
- msgid "What is reCAPTCHA?"
190
- msgstr "Mi a reCAPTCHA?"
191
 
192
- #: includes/class-bwp-recaptcha.php:282
193
- msgid "This plugin will be"
194
- msgstr "Ez a plugin"
195
 
196
- #: includes/class-bwp-recaptcha.php:283
197
- msgid "Public Key"
198
- msgstr "Nyilvános Kulcs"
199
 
200
- #: includes/class-bwp-recaptcha.php:284
201
- msgid "Private Key"
202
- msgstr "Privát Kulcs"
203
 
204
- #: includes/class-bwp-recaptcha.php:285
205
- msgid "Visibility Options (only applied to comment forms)"
206
- msgstr "Láthatósági beállítások"
207
 
208
- #: includes/class-bwp-recaptcha.php:286
209
- msgid "Hide the CAPTCHA for"
210
- msgstr "CAPTCHA elrejtése a következők esetén:"
 
 
 
 
211
 
212
- #: includes/class-bwp-recaptcha.php:287
213
- msgid "If wrong or empty response"
214
- msgstr "Ha hibás vagy üres a válasz"
215
 
216
- #: includes/class-bwp-recaptcha.php:288
217
- #: includes/class-bwp-recaptcha.php:289
218
- msgid "Show the error message"
219
- msgstr "Mutasd ezt a hibaüzenetet"
220
 
221
- #: includes/class-bwp-recaptcha.php:290
222
- msgid "Akismet Integration"
223
- msgstr "Akismet Integráció"
224
 
225
- #: includes/class-bwp-recaptcha.php:291
226
- msgid "Integrate with Akismet?"
227
- msgstr "Integrálni szeretnéd az Akismet-el?"
228
 
229
- #: includes/class-bwp-recaptcha.php:292
230
- msgid "If correct CAPTCHA response"
231
- msgstr "Ha helyes a CAPTCHA válasz"
232
 
233
- #: includes/class-bwp-recaptcha.php:296
234
- msgid "reCAPTCHA is a free CAPTCHA service that helps to digitize books, newspapers and old time radio shows. You can read more about reCAPTCHA <a href=\"http://www.google.com/recaptcha/learnmore\" target=\"_blank\">here</a>."
235
- msgstr "reCAPTCHA egy ingyenes CAPTCHA egy ingyenes rendszer, ami CAPTCHA technológiát használ, hogy segítsen digitalizálni régi könyvek és rádióműsorok szövegét, miközben megvédi a weblapokat az automatikus szoftverektől, amelyek korlátozott területekhez akarnak hozzáférni, magukat embernek kiadva (pl. regisztráció). További információ a reCAPTCHA-ról <a href=\"http://www.google.com/recaptcha/learnmore\" target=\"_blank\">itt</a>."
 
 
 
236
 
237
- #: includes/class-bwp-recaptcha.php:297
238
- msgid "<em>This section allows you to determine when to show reCAPTCHA and how this plugin reacts to errors.</em>"
239
- msgstr "<em>Itt tudod beállítani mikor mutassa a reCAPTCHA-t, és hogy reagáljon a plugin a hibákra.</em>"
240
 
241
- #: includes/class-bwp-recaptcha.php:298
242
- msgid "<em>Integrate with Akismet for better end-user experience. reCAPTCHA is optional and <strong>NO</strong> spam comment will be added to the spam/moderation queue, except likely legitimate comments. This makes the task of identifying sincere comments much easier. This integration is currently in beta stage.</em>"
243
- msgstr "<em>Akismet-tel való integráció a jobb felhasználói élmény elérése érdekében. A reCAPTCHA nem kötelező és <strong>SEMMILYEN</strong> spam hozzászólás nem fog a szemétszűrési/moderációs listára kerülni, csak a valószínűleg létező személy által írt hozzászólások. Ez nagyban megkönnyíti a valós hozzászólások azonosítását. Az integráció jelenleg béta állapotban van.</em>"
244
 
245
- #: includes/class-bwp-recaptcha.php:313
246
- msgid "Redirect commenter back to the comment form"
 
247
  msgstr "Hozzászóló átirányítása a hozzászólási űrlaphoz."
248
 
249
- #: includes/class-bwp-recaptcha.php:314
250
- msgid "Show an error page just like WordPress does"
251
- msgstr "Egy hibajelző lap mutatása a WordPress-hez hasonlóan."
252
 
253
- #: includes/class-bwp-recaptcha.php:317
254
- msgid "Approve comment immediately"
255
- msgstr "Hozzászólások automatikus elfogadása"
256
 
257
- #: includes/class-bwp-recaptcha.php:318
258
- msgid "Hold comment in moderation queue"
259
- msgstr "Hozzászólások moderációs listára tétele"
260
 
261
- #: includes/class-bwp-recaptcha.php:319
262
- msgid "Put comment in spam queue"
263
- msgstr "Hozzászólások spam listára tétele"
264
 
265
- #: includes/class-bwp-recaptcha.php:323
266
- msgid "enabled for comment forms."
267
- msgstr "aktiválva a hozzászólások esetén."
268
 
269
- #: includes/class-bwp-recaptcha.php:324
270
- msgid "enabled for registration page."
271
- msgstr "aktiválva a regisztrációs űrlap esetén."
272
 
273
- #: includes/class-bwp-recaptcha.php:325
274
- msgid "registered users <em>(even without any capabilities)</em>."
275
- msgstr "regisztrált felhasználók <em>(még jogok nélkül is)</em>."
 
276
 
277
- #: includes/class-bwp-recaptcha.php:326
278
- msgid "users who can"
279
- msgstr "Felhasználók, akik képesek"
 
280
 
281
- #: includes/class-bwp-recaptcha.php:327
282
- msgid "visitors who have at least"
283
- msgstr "látogatók, akiknek minimum"
284
 
285
- #: includes/class-bwp-recaptcha.php:328
286
- msgid "reCAPTCHA will only show when Akismet identifies a comment as spam. Highly recommended if you do not want to force your visitors to type the captcha every time."
287
- msgstr "A reCAPTCHA csak akkor jelenik meg, ha az Akismet a hozzászólást spam-nek érzékeli. Nagyon ajánlott, ha nem akarod a látogatókra kényszeríteni a captcha beírását minden hozzászólásuknál."
 
 
 
 
 
 
 
288
 
289
- #: includes/class-bwp-recaptcha.php:331
290
- msgid "A public key used to request captchas from reCAPTCHA server."
291
- msgstr "Egy nyilvános kulcs ami captcha-k a reCAPTCHA szerverről való lekérésére szükséges."
 
292
 
293
- #: includes/class-bwp-recaptcha.php:332
294
- msgid "A private (secret) key used to authenticate user's response."
295
- msgstr "Egy privát (titkos) kulcs ami a felhasználó válaszát hitelesíti."
296
 
297
- #: includes/class-bwp-recaptcha.php:333
298
- msgid "when redirect commenter back to the comment form."
299
- msgstr "amikor a hozzászólót a hozzászóláshoz irányítjuk vissza."
300
 
301
- #: includes/class-bwp-recaptcha.php:334
302
- msgid "when show the normal error page with no redirection."
303
- msgstr "amikor a hibajelentő lapot mutatjuk átirányítás nélkül."
304
 
305
- #: includes/class-bwp-recaptcha.php:335
306
- msgid "approved comment(s)."
307
- msgstr "elfogadott hozzászólásuk van."
 
308
 
309
- #: includes/class-bwp-recaptcha.php:338
310
- msgid "<em><strong>Note:</strong> For this plugin to work, you will need a pair of API keys (public and private), which is available for free <a href=\"https://www.google.com/recaptcha/admin/create\" target=\"_blank\">here</a>. Once you have created those two keys for this domain, simply paste them below.</em>"
311
- msgstr "<em><strong>Megjegyzés:</strong> Ahhoz, hogy ez a plugin működjön, szükséged van két API kulcsra (nyilvános és privát), melyek ingyenesen elérhetők <a href=\"https://www.google.com/recaptcha/admin/create\" target=\"_blank\">innen</a>. Amint hozzájutottál a két kulcshoz, egyszerűen másold be alább.</em>"
 
 
 
312
 
313
- #: includes/class-bwp-recaptcha.php:339
314
- msgid "<em><strong>Note:</strong> Now you may wonder, why put the comment in the spam queue? The benefit is Akismet will be able to mark the comment as False Positive, and thus will not possibly block that comment in the future. However, it is best to just put the comment in moderation queue as next time Akismet will put such comment in moderation queue immediately without the need of a CAPTCHA.</em>"
315
- msgstr "<em><strong>Megjegyzés:</strong> Most azt kérdezhetnéd, mi értelme a hozzászólást a spam listára tenni? Ez azért lehet előnyös, mert az Akismet így képes a hozzászólást hibás találatnak jelölni, és így elkerülni, hogy következőleg blokkolja a hozzászólást. Ennek ellenére a legjobb, ha a hozzászólást a moderációs listára küldjük, mivel következőleg az Akismet automatikusan a moderációs listára fogja tenni az ilyen hozzászólásokat CAPTCHA használata nélkül.</em>"
316
 
317
- #: includes/class-bwp-recaptcha.php:364
318
- msgid "Choose a theme"
319
- msgstr "Válassz témát"
 
 
320
 
321
- #: includes/class-bwp-recaptcha.php:365
322
- msgid "Use CSS provided by this plugin?"
323
- msgstr "Használod a plugin beépített CSS-ét?"
 
 
324
 
325
- #: includes/class-bwp-recaptcha.php:366
326
- msgid "Load CSS, JS selectively?"
327
- msgstr "CSS és JS szelektív betöltése"
328
 
329
- #: includes/class-bwp-recaptcha.php:367
330
- msgid "Choose a language for built-in themes"
331
- msgstr "Nyelv választása a beépített témákhoz"
 
332
 
333
- #: includes/class-bwp-recaptcha.php:368
334
- msgid "Tabindex for captcha input field"
335
- msgstr "Tabindex a captcha beviteli mezőhöz"
 
 
 
 
336
 
337
- #: includes/class-bwp-recaptcha.php:369
338
- msgid "Preview your reCAPTCHA"
339
- msgstr "reCAPTCHA előnézete"
340
 
341
- #: includes/class-bwp-recaptcha.php:373
342
- msgid "<em>Below you will see how your reCAPTCHA will look. Note that this might differ on your actual pages.<br /></em>"
343
- msgstr "<em>Alább megtekintheted, hogy fog a reCAPTCHA kinézni. Ez különbözhet a tényleges oldalaidon.<br /></em>"
344
 
345
- #: includes/class-bwp-recaptcha.php:377
346
- msgid "Default Theme (Red)"
347
- msgstr "Alapértelmezett Téma (Piros)"
348
 
349
- #: includes/class-bwp-recaptcha.php:378
350
- msgid "White Theme"
351
- msgstr "Fehér Téma"
352
 
353
- #: includes/class-bwp-recaptcha.php:379
354
- msgid "Black Theme"
355
- msgstr "Fekete Téma"
356
 
357
- #: includes/class-bwp-recaptcha.php:380
358
- msgid "Clean Theme"
359
- msgstr "Letisztult Téma"
360
 
361
- #: includes/class-bwp-recaptcha.php:381
362
- msgid "Custom Theme (use CSS)"
363
- msgstr "Egyéni Téma (CSS használata)"
 
 
 
364
 
365
- #: includes/class-bwp-recaptcha.php:386
366
- msgid "This stylesheet is used to style the custom theme as well as the registration page. You can disable this or add appropriate filters to use your own."
367
- msgstr "Ezt a stíluslapot használja a testre szabott téma és a regisztrációs oldal is. Kikapcsolhatod ezt, vagy magad is hozzáathatsz megfelelő szűrőket."
368
 
369
- #: includes/class-bwp-recaptcha.php:387
370
- msgid "This is only useful when you do not use any minify or cache plugin."
371
- msgstr "Ez csak akkor hasznos, ha nem használsz semmilyen minify vagy gyorsítótár plugint."
372
 
373
- #: includes/class-bwp-recaptcha.php:390
374
- msgid "Basically, this should be 4 if you place the captcha before the textarea, and 5 if you put it after."
375
- msgstr "Gyakorlatilag itt 4-nek kell lennie, ha a captcha-t a szövegbeviteli mező elé szeretnéd helyezni és 5-nek, ha utána."
 
376
 
377
- #: includes/class-bwp-recaptcha.php:393
378
- #, php-format
379
- msgid "<em><strong>Note:</strong> The four built-in captcha themes will look OK in most WordPress themes; However, some times it is better to control how reCAPTCHA looks using CSS. Please read <a href=\"%s#customization\" target=\"_blank\">this guide</a> if you would like to do so.</em>"
380
- msgstr "<em><strong>Megjegyzés:</strong> A négy beépített captcha téma megfelelő a legtöbb WordPress témához; Mindazonáltal néha jobb a reCAPTCHA kinézetét CSS segítségével testre szabni. Ha érdekel, kérlek olvasd el <a href=\"%s#customization\" target=\"_blank\">ezt az útmutatót</a>.</em>"
381
 
382
- #: includes/class-bwp-recaptcha.php:394
383
- #, php-format
384
- msgid "<em><strong>Note:</strong> Above you can select some built-in languages. If you would like to add your own language, please read <a href=\"%s#customization\" target=\"_blank\">this guide</a>.</em>"
385
- msgstr "<em><strong>Megjegyzés:</strong> Fent választhatsz pár beépített nyelv közül. Ha hozzá szeretnéd adni a saját nyelvedet, kérlek olvasd el <a href=\"%s#customization\" target=\"_blank\">ezt az útmutatót</a>.</em>"
386
 
387
- #: includes/class-bwp-recaptcha.php:438
 
 
 
 
388
  msgid "Warning"
389
  msgstr "Figyelmeztetés"
390
 
391
- #: includes/class-bwp-recaptcha.php:438
392
- msgid "API key(s) missing. Please get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a> (free!)"
393
- msgstr "Az API kulcs(ok) hiányoznak. Kérlek szerezz be egy API kulcsot innen: <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a> (ingyenes!)"
394
 
395
- #: includes/class-bwp-recaptcha.php:440
396
- msgid "Notice"
397
- msgstr "Értesítés"
 
 
 
 
398
 
399
- #: includes/class-bwp-recaptcha.php:440
400
- msgid "You are enabling Akismet integration but Akismet is not currently active. Please activate Akismet for the integration to work."
401
- msgstr "Engedélyezed az Akismet integrációt, de az Akismet jelenleg nem aktív. Kérlek aktiváld az Akismet-et előbb."
 
402
 
403
- #: includes/class-bwp-recaptcha.php:548
 
 
 
 
 
 
404
  msgid "Your comment was identified as spam, please complete the CAPTCHA below:"
405
- msgstr "A hozzászólásod spam-ként lett azonosítva, kérlek válaszolj az alábbi CAPTCHA feladványra:"
 
 
 
 
 
 
406
 
407
- #: includes/class-bwp-recaptcha.php:580
408
- msgid "To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>"
409
- msgstr "A reCAPTCHA használatához API kulcsot kell szerezned innen: <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>"
 
410
 
411
- #: includes/class-bwp-recaptcha.php:609
412
- msgid "<strong>ERROR</strong>: Captcha response is either empty or incorrect."
413
- msgstr "<strong>HIBA</strong>: A captcha válasz hibás vagy üres."
414
 
415
- #: includes/class-bwp-recaptcha.php:611
416
- msgid "<strong>ERROR</strong>: Unknown captcha error."
417
- msgstr "<strong>HIBA</strong>: Ismeretlen captcha hiba."
 
418
 
419
- #: includes/class-bwp-recaptcha.php:661
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
420
  msgid "this link"
421
  msgstr "erre a címre"
422
 
423
- #: includes/class-bwp-recaptcha.php:663
424
- msgid "There is some problem with your reCAPTCHA API keys, please double check them."
425
- msgstr "Valami hiba van a reCAPTCHA API kulcsaiddal, kérlek ellenőrizd őket."
426
 
427
- #: includes/class-bwp-recaptcha.php:665
428
- msgid "Unknown error. Please contact the administrator for more info."
429
- msgstr "Ismeretlen hiba. További információért kérlek lépj kapcsolatba az adminisztrátorral."
430
 
431
- #: includes/bwp-option-page/includes/class-bwp-option-page.php:80
432
- msgid "Plugin Configurations"
433
- msgstr "Plugin beállítások"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434
 
435
- #: includes/bwp-option-page/includes/class-bwp-option-page.php:398
436
- msgid "Save Changes"
437
- msgstr "Változások mentése"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
438
 
 
 
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: BWP reCAPTCHA\n"
4
+ "Report-Msgid-Bugs-To: contact@betterwp.net\n"
5
+ "POT-Creation-Date: 2016-01-12 23:47+0700\n"
6
+ "PO-Revision-Date: 2016-01-12 15:24+0700\n"
7
  "Last-Translator: Brandon <brandon@helloftranslations.net>\n"
8
  "Language-Team: \n"
9
+ "Language: hu_HU\n"
10
  "MIME-Version: 1.0\n"
11
  "Content-Type: text/plain; charset=utf-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
  "X-Poedit-KeywordsList: _;gettext;gettext_noop;__;_e\n"
14
  "X-Poedit-Basepath: .\n"
 
15
  "X-Poedit-SourceCharset: utf-8\n"
16
+ "X-Generator: Poedit 1.8.5\n"
17
  "X-Poedit-SearchPath-0: .\n"
18
 
19
+ #: vendor/kminh/bwp-framework/src/class-bwp-version.php:32
20
  #, php-format
21
+ msgid ""
22
+ "%s requires WordPress <strong>%s</strong> or higher and PHP <strong>%s</"
23
+ "strong> or higher. The plugin will not function until you update your "
24
+ "software. Please deactivate this plugin."
25
+ msgstr ""
26
+ "%s legalább %s WordPresst és legalább %s PHP-t igényel. A plugin nem fog "
27
+ "működni, amíg nem frissíted a szoftvert. Kérlek kapcsold ki ezt a plugint."
28
 
29
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:411
30
+ msgid "... or any amount!"
31
+ msgstr "... vagy akármennyit!"
32
 
33
+ #: includes/class-bwp-recaptcha.php:1006 includes/class-bwp-recaptcha.php:1101
34
+ #, fuzzy
35
+ msgid ""
36
+ "<em>Below you will see how your reCAPTCHA will look. Note that this might "
37
+ "differ on your actual pages.</em>"
38
+ msgstr ""
39
+ "<em>Alább megtekintheted, hogy fog a reCAPTCHA kinézni. Ez különbözhet a "
40
+ "tényleges oldalaidon.<br /></em>"
41
 
42
+ #: includes/class-bwp-recaptcha.php:118
43
+ msgid ""
44
+ "<strong>ERROR:</strong> Incorrect or empty reCAPTCHA response, please try "
45
+ "again."
46
+ msgstr ""
47
+ "<strong>HIBA:</strong> Helytelen vagy üres reCAPTCHA válasz, kérlek próbáld "
48
+ "újra."
49
 
50
+ #: includes/class-bwp-recaptcha.php:867
51
+ msgid "A private (secret) key used to authenticate user's response."
52
+ msgstr "Egy privát (titkos) kulcs ami a felhasználó válaszát hitelesíti."
53
 
54
+ #: includes/class-bwp-recaptcha.php:861
55
+ msgid "A public key used to request captchas from reCAPTCHA server."
56
+ msgstr ""
57
+ "Egy nyilvános kulcs ami captcha-k a reCAPTCHA szerverről való lekérésére "
58
+ "szükséges."
59
 
60
+ #: includes/class-bwp-recaptcha.php:1193
61
+ #, php-format
62
+ msgid ""
63
+ "API key(s) missing. Please get an API key from <a href=\"%1$s\">%1$s</a> "
64
+ "(free!)"
65
+ msgstr ""
66
 
67
+ #: includes/provider/v1.php:165
68
+ msgid "About reCAPTCHA"
69
+ msgstr "Súgó"
70
 
71
+ #: includes/class-bwp-recaptcha.php:1021 includes/class-bwp-recaptcha.php:1123
72
+ msgid ""
73
+ "Add additional CSS rules to all recaptcha instances. You can edit them below."
74
+ msgstr ""
75
 
76
+ #: includes/class-bwp-recaptcha.php:756
77
+ msgid ""
78
+ "Add reCAPTCHA to Contact Form 7. This only works if you have Contact Form 7 "
79
+ "activated."
80
+ msgstr ""
81
 
82
+ #: includes/class-bwp-recaptcha.php:827
83
+ msgid ""
84
+ "Add the <code>recaptcha</code> shortcode tag to your Contact Form 7 forms."
85
+ msgstr ""
86
 
87
+ #: includes/class-bwp-recaptcha.php:773
88
+ #, fuzzy
89
+ msgid "After comment field"
90
+ msgstr "Hozzászólások automatikus elfogadása"
91
 
92
+ #: includes/class-bwp-recaptcha.php:774
93
+ msgid "After form fields (name, email, website)"
94
+ msgstr ""
95
 
96
+ #: includes/class-bwp-recaptcha.php:819
97
+ msgid "After redirected, auto fill the comment field with previous comment."
98
+ msgstr ""
99
 
100
+ #: includes/class-bwp-recaptcha.php:708
101
+ #, fuzzy
102
+ msgid "Akismet Integration for comment form"
103
+ msgstr "Akismet Integráció"
104
 
105
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:438
106
+ msgid "All options have been saved."
107
+ msgstr ""
108
+
109
+ #: includes/class-bwp-recaptcha.php:781
110
+ msgid "Approve comment immediately"
111
+ msgstr "Hozzászólások automatikus elfogadása"
112
+
113
+ #: includes/class-bwp-recaptcha.php:636
114
+ msgid "Auto detected"
115
+ msgstr ""
116
+
117
+ #: includes/class-bwp-recaptcha.php:705
118
+ msgid "Auto fill comment field"
119
+ msgstr ""
120
+
121
+ #: includes/class-bwp-recaptcha.php:1114
122
+ msgid "Auto-detected"
123
+ msgstr ""
124
+
125
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:521
126
+ msgid "BWP Gems"
127
+ msgstr ""
128
+
129
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:531
130
+ msgid "BWP News"
131
+ msgstr ""
132
+
133
+ #: includes/class-bwp-recaptcha.php:595
134
+ msgid "BWP reCAPTCHA General Options"
135
+ msgstr "BWP reCAPTCHA Alapbeállítások"
136
+
137
+ #: includes/class-bwp-recaptcha.php:604
138
+ msgid "BWP reCAPTCHA Theme Options"
139
+ msgstr "BWP reCAPTCHA Témabeállítások"
140
+
141
+ #: includes/class-bwp-recaptcha.php:585
142
+ msgid "Better WordPress reCAPTCHA"
143
+ msgstr "Fejlettebb Wordpress reCAPTCHA"
144
+
145
+ #: includes/class-bwp-recaptcha.php:1013
146
+ msgid "Black Theme"
147
+ msgstr "Fekete Téma"
148
+
149
+ #: includes/class-bwp-recaptcha.php:703
150
+ msgid "Captcha position"
151
+ msgstr ""
152
+
153
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:439
154
+ msgid "Check out this cool plugin"
155
+ msgstr ""
156
+
157
+ #: includes/class-bwp-recaptcha.php:1014
158
+ msgid "Clean Theme"
159
+ msgstr "Letisztult Téma"
160
+
161
+ #: includes/class-bwp-recaptcha.php:787
162
+ msgid "Comment form"
163
+ msgstr ""
164
+
165
+ #: includes/class-bwp-recaptcha.php:1111
166
+ msgid "Compact"
167
+ msgstr ""
168
+
169
+ #: includes/class-bwp-recaptcha.php:711
170
+ msgid "Contact Form 7 Integration"
171
+ msgstr ""
172
+
173
+ #: includes/addons/contact-form-7/captcha-shortcode.php:205
174
+ msgid "Copy this code and paste it into the form left."
175
+ msgstr ""
176
+
177
+ #: includes/class-bwp-recaptcha.php:1015
178
+ msgid "Custom Theme (use CSS)"
179
+ msgstr "Egyéni Téma (CSS használata)"
180
+
181
+ #: includes/class-bwp-recaptcha.php:1107
182
+ msgid "Dark"
183
+ msgstr ""
184
+
185
+ #: includes/class-bwp-recaptcha.php:1011
186
+ msgid "Default Theme (Red)"
187
+ msgstr "Alapértelmezett Téma (Piros)"
188
+
189
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:1530
190
+ msgid "Dismiss this notice."
191
+ msgstr ""
192
+
193
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:405
194
  #, php-format
195
+ msgid "Donate to %s"
196
+ msgstr "Támogatom %s"
197
 
198
+ #: includes/class-bwp-recaptcha.php:992 includes/class-bwp-recaptcha.php:1087
199
+ msgid "Enable custom CSS"
200
+ msgstr ""
201
+
202
+ #: includes/class-bwp-recaptcha.php:700
203
+ msgid "Enable this plugin for"
204
+ msgstr ""
205
+
206
+ #: includes/class-bwp-recaptcha.php:120
207
+ #, php-format
208
+ msgid ""
209
+ "Error: Incorrect or empty reCAPTCHA response, please click the back button "
210
+ "on your browser's toolbar or click on %s to go back."
211
+ msgstr ""
212
+ "Hiba: Helytelen vagy üres reCAPTCHA válasz,, kérlek kattints a böngésző "
213
+ "vissza gombjára vagy nyomd meg a %s gombot a visszatéréshez."
214
 
215
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:371
216
+ msgid "FAQ"
217
+ msgstr "GyIK"
218
+
219
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:409
220
+ msgid "Five cups! $25.00"
221
+ msgstr "Öt csésze! $25,00"
222
+
223
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:548
224
+ msgid "Follow"
225
+ msgstr ""
226
+
227
+ #: includes/class-bwp-recaptcha.php:744
228
+ #, fuzzy, php-format
229
+ msgid ""
230
+ "For this plugin to work, you will need a pair of API keys, which is "
231
+ "available for free <a href=\"%s\" target=\"_blank\">here</a>. Once you have "
232
+ "created those two keys for the current domain, simply paste them below.</em>"
233
+ msgstr ""
234
+ "<em><strong>Megjegyzés:</strong> Ahhoz, hogy ez a plugin működjön, szükséged "
235
+ "van két API kulcsra (nyilvános és privát), melyek ingyenesen elérhetők <a "
236
+ "href=\"https://www.google.com/recaptcha/admin/create\" target=\"_blank"
237
+ "\">innen</a>. Amint hozzájutottál a két kulcshoz, egyszerűen másold be alább."
238
+ "</em>"
239
+
240
+ #: includes/class-bwp-recaptcha.php:697
241
+ msgid "Force https"
242
+ msgstr ""
243
+
244
+ #: includes/class-bwp-recaptcha.php:159 includes/class-bwp-recaptcha.php:596
245
+ msgid "General Options"
246
+ msgstr "Alapbeállítások"
247
+
248
+ #: includes/provider/v1.php:162
249
  msgid "Get another challenge"
250
  msgstr "Új kihívás kérése"
251
 
252
+ #: includes/provider/v1.php:163
253
  msgid "Get audio reCAPTCHA"
254
  msgstr "Hangkihívás kérése"
255
 
256
+ #: includes/provider/v1.php:164
257
  msgid "Get image reCAPTCHA"
258
  msgstr "Képkihívás kérése"
259
 
260
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:374
261
+ msgid "Got a problem with this plugin? Please say it out loud!"
262
+ msgstr ""
263
+
264
+ #: includes/class-bwp-recaptcha.php:701
265
+ #, fuzzy
266
+ msgid "Hide captcha for"
267
+ msgstr "CAPTCHA elrejtése a következők esetén:"
268
+
269
+ #: includes/class-bwp-recaptcha.php:782
270
+ msgid "Hold comment in moderation queue"
271
+ msgstr "Hozzászólások moderációs listára tétele"
272
 
273
+ #: includes/class-bwp-recaptcha.php:710
274
+ #, fuzzy
275
+ msgid "If correct captcha response"
276
+ msgstr "Ha helyes a CAPTCHA válasz"
277
 
278
+ #: includes/class-bwp-recaptcha.php:704
279
+ #, fuzzy
280
+ msgid "If invalid captcha response"
281
+ msgstr "Ha hibás vagy üres a válasz"
282
 
283
+ #: includes/class-bwp-recaptcha.php:880
284
+ msgid ""
285
+ "If you encounter error such as <code>Unknown error (invalid-json)</code>when "
286
+ "submitting a form, try selecting a specific request method here."
287
+ msgstr ""
288
 
289
+ #: includes/class-bwp-recaptcha.php:1054
290
  #, php-format
291
+ msgid ""
292
+ "If you want to add custom translations, please read <a href=\"%s\" target="
293
+ "\"_blank\">this tip</a>."
294
+ msgstr ""
295
 
296
+ #: includes/class-bwp-recaptcha.php:1207
297
+ #, php-format
298
+ msgid ""
299
+ "In order to use the nocaptcha recaptcha (recaptcha v2), you need at least "
300
+ "<strong>PHP 5.3.2</strong> (your current PHP version is <strong>%s</"
301
+ "strong>), so only recaptcha v1 can be used. It is recommended to contact "
302
+ "your host to know how to update your current version of PHP."
303
+ msgstr ""
304
 
305
+ #: includes/class-bwp-recaptcha.php:125
306
+ #, fuzzy
307
+ msgid "Incorrect or empty reCAPTCHA response, please try again."
308
+ msgstr ""
309
+ "<strong>HIBA:</strong> Helytelen vagy üres reCAPTCHA válasz, kérlek próbáld "
310
+ "újra."
311
 
312
+ #: includes/addons/contact-form-7/captcha-shortcode.php:170
313
+ msgid "Insert Tag"
314
+ msgstr ""
315
 
316
+ #: includes/class-bwp-recaptcha.php:753
317
+ msgid "Integrate the comment form with Akismet for better end-user experience."
318
+ msgstr ""
319
 
320
+ #: includes/class-bwp-recaptcha.php:709
321
+ #, fuzzy
322
+ msgid "Integrate with Akismet"
323
+ msgstr "Integrálni szeretnéd az Akismet-el?"
324
 
325
+ #: includes/class-bwp-recaptcha.php:712
326
+ #, fuzzy
327
+ msgid "Integrate with Contact Form 7"
328
+ msgstr "Integrálni szeretnéd az Akismet-el?"
329
 
330
+ #: includes/class-bwp-recaptcha.php:706 includes/class-bwp-recaptcha.php:707
331
+ #: includes/class-bwp-recaptcha.php:714
332
+ #, fuzzy
333
+ msgid "Invalid captcha error message"
334
+ msgstr "Mutasd ezt a hibaüzenetet"
335
 
336
+ #: includes/class-bwp-recaptcha.php:886
337
+ msgid ""
338
+ "It is best to put comments identified as spam in moderation queue so you are "
339
+ "able to review and instruct Akismet to correctly handle similar comments in "
340
+ "the future."
341
+ msgstr ""
342
 
343
+ #: includes/class-bwp-recaptcha.php:1088
344
+ msgid "Language"
345
+ msgstr ""
346
 
347
+ #: includes/class-bwp-recaptcha.php:993
348
+ #, fuzzy
349
+ msgid "Language for built-in themes"
350
+ msgstr "Nyelv választása a beépített témákhoz"
351
 
352
+ #: includes/class-bwp-recaptcha.php:1106
353
+ msgid "Light"
354
+ msgstr ""
355
 
356
+ #: includes/class-bwp-recaptcha.php:793
357
+ msgid "Login form"
358
+ msgstr ""
359
 
360
+ #: includes/class-bwp-recaptcha.php:699
361
+ msgid "Main Functionality"
362
+ msgstr ""
363
 
364
+ #: includes/class-bwp-recaptcha.php:816
365
+ msgid "Make requests to recaptcha server always secured."
366
+ msgstr ""
367
 
368
+ #: includes/class-bwp-recaptcha.php:317
369
+ msgid "Manage Options"
370
+ msgstr "Beállítások Kezelésére"
371
 
372
+ #: includes/addons/contact-form-7/captcha-shortcode.php:159
373
+ #: includes/addons/contact-form-7/captcha-shortcode.php:196
374
+ msgid "Name"
375
+ msgstr ""
376
 
377
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:503
378
+ msgid "Need a highly customizable theme?"
379
+ msgstr ""
380
 
381
+ #: includes/class-bwp-recaptcha.php:1110
382
+ msgid "Normal"
383
+ msgstr ""
384
 
385
+ #: includes/class-bwp-recaptcha.php:1205 includes/class-bwp-recaptcha.php:1227
386
+ msgid "Notice"
387
+ msgstr "Értesítés"
388
 
389
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:410
390
+ msgid "One LL-cup!!! $50.00"
391
+ msgstr "Egy extranagy bögre!!! $50,00"
392
 
393
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:407
394
+ msgid "One cup $5.00"
395
+ msgstr "Egy csésze $5,00"
396
 
397
+ #: includes/addons/contact-form-7/captcha-shortcode.php:225
398
+ #, php-format
399
+ msgid ""
400
+ "Please refer to <a target=\"_blank\" href=\"%s\">BWP reCAPTCHA's "
401
+ "documentation</a> for a quick guide on how to customize the look and feel of "
402
+ "this tag."
403
+ msgstr ""
404
 
405
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:93
406
+ msgid "Plugin Configurations"
407
+ msgstr "Plugin beállítások"
408
 
409
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:375
410
+ msgid "Plugin Support"
411
+ msgstr ""
 
412
 
413
+ #: includes/class-bwp-recaptcha.php:995 includes/class-bwp-recaptcha.php:1090
414
+ msgid "Preview your reCAPTCHA"
415
+ msgstr "reCAPTCHA előnézete"
416
 
417
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:378
418
+ msgid "Rate this plugin 5 stars if you like it, thank you!"
419
+ msgstr ""
420
 
421
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:379
422
+ msgid "Rate this plugin 5 stars!"
423
+ msgstr ""
424
 
425
+ #: includes/class-bwp-recaptcha.php:1045
426
+ #, php-format
427
+ msgid ""
428
+ "Read <a href=\"%s#recaptcha-version-1\" target=\"_blank\">here</a> to know "
429
+ "how to use your own CSS for the Custom Theme."
430
+ msgstr ""
431
 
432
+ #: includes/class-bwp-recaptcha.php:316
433
+ msgid "Read Profile"
434
+ msgstr "Profil Megtekintésére"
435
 
436
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:370
437
+ msgid "Read this first before asking any question!"
438
+ msgstr ""
439
 
440
+ #: includes/class-bwp-recaptcha.php:777
441
+ #, fuzzy
442
+ msgid "Redirect commenter back to the comment form with error message"
443
  msgstr "Hozzászóló átirányítása a hozzászólási űrlaphoz."
444
 
445
+ #: includes/class-bwp-recaptcha.php:790
446
+ msgid "Registration form (user/site registration)"
447
+ msgstr ""
448
 
449
+ #: includes/class-bwp-recaptcha.php:698
450
+ msgid "Request method"
451
+ msgstr ""
452
 
453
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:305
454
+ msgid "Save Changes"
455
+ msgstr "Változások mentése"
456
 
457
+ #: includes/class-bwp-recaptcha.php:694
458
+ msgid "Secret Key"
459
+ msgstr ""
460
 
461
+ #: includes/class-bwp-recaptcha.php:1129
462
+ msgid "Set to 0 to disable."
463
+ msgstr ""
464
 
465
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:1315
466
+ msgid "Settings"
467
+ msgstr "Beállítások"
468
 
469
+ #: includes/class-bwp-recaptcha.php:751
470
+ #, fuzzy
471
+ msgid "Settings that are applied to comment forms only."
472
+ msgstr "Láthatósági beállítások"
473
 
474
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:431
475
+ #, fuzzy
476
+ msgid "Share the love for this plugin!"
477
+ msgstr "Használod a plugin beépített CSS-ét?"
478
 
479
+ #: includes/class-bwp-recaptcha.php:778
480
+ msgid "Show an error page just like WordPress does"
481
+ msgstr "Egy hibajelző lap mutatása a WordPress-hez hasonlóan."
482
 
483
+ #: includes/class-bwp-recaptcha.php:805
484
+ #, fuzzy
485
+ msgid ""
486
+ "Show captcha only when Akismet identifies a comment as spam. Highly "
487
+ "recommended if you do not want to force your visitors to enter a captcha "
488
+ "every time."
489
+ msgstr ""
490
+ "A reCAPTCHA csak akkor jelenik meg, ha az Akismet a hozzászólást spam-nek "
491
+ "érzékeli. Nagyon ajánlott, ha nem akarod a látogatókra kényszeríteni a "
492
+ "captcha beírását minden hozzászólásuknál."
493
 
494
+ #: includes/class-bwp-recaptcha.php:693
495
+ #, fuzzy
496
+ msgid "Site Key"
497
+ msgstr "Privát Kulcs"
498
 
499
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:541
500
+ msgid "Subscribe"
501
+ msgstr ""
502
 
503
+ #: includes/class-bwp-recaptcha.php:994 includes/class-bwp-recaptcha.php:1089
504
+ msgid "Tabindex for captcha input field"
505
+ msgstr "Tabindex a captcha beviteli mezőhöz"
506
 
507
+ #: includes/class-bwp-recaptcha.php:162 includes/class-bwp-recaptcha.php:605
508
+ msgid "Theme Options"
509
+ msgstr "Témabeállítások"
510
 
511
+ #: includes/provider/abstract-provider.php:103
512
+ msgid ""
513
+ "There is some problem with your reCAPTCHA API keys, please double check them."
514
+ msgstr "Valami hiba van a reCAPTCHA API kulcsaiddal, kérlek ellenőrizd őket."
515
 
516
+ #: includes/class-bwp-recaptcha.php:754 includes/class-bwp-recaptcha.php:822
517
+ #, php-format
518
+ msgid ""
519
+ "This feature requires an active <a target=\"_blank\" href=\"%s\">PHP "
520
+ "session</a>."
521
+ msgstr ""
522
 
523
+ #: includes/class-bwp-recaptcha.php:897
524
+ msgid "This is shown on the standard WordPress error page."
525
+ msgstr ""
526
 
527
+ #: includes/class-bwp-recaptcha.php:892
528
+ #, fuzzy
529
+ msgid ""
530
+ "This is shown when the commenter is redirected back to the comment form."
531
+ msgstr "amikor a hozzászólót a hozzászóláshoz irányítjuk vissza."
532
 
533
+ #: includes/class-bwp-recaptcha.php:905
534
+ msgid ""
535
+ "This message is shown when invalid captcha response is treated as a standard "
536
+ "validation error. Leave blank to not use."
537
+ msgstr ""
538
 
539
+ #: includes/addons/contact-form-7/captcha-shortcode.php:220
540
+ msgid "This reCAPTCHA tag is provided by the BWP reCAPTCHA WordPress plugin."
541
+ msgstr ""
542
 
543
+ #: includes/provider/v1.php:96
544
+ #, php-format
545
+ msgid "To use reCAPTCHA you must get an API key from <a href=\"%1$s\">%1$s</a>"
546
+ msgstr ""
547
 
548
+ #: includes/class-bwp-recaptcha.php:873
549
+ msgid ""
550
+ "To verify a captcha response, this plugin needs to send requests to the "
551
+ "reCAPTCHA server, using a specific request method. <br /><br />By default, "
552
+ "BWP reCAPTCHA use the first available request method, be it Socket "
553
+ "(<code>fsockopen</code>), cURL, or <code>file_get_contents</code>."
554
+ msgstr ""
555
 
556
+ #: includes/class-bwp-recaptcha.php:713
557
+ msgid "Treat invalid captcha as spam"
558
+ msgstr ""
559
 
560
+ #: includes/class-bwp-recaptcha.php:830
561
+ msgid "Treat invalid captcha response as spam instead of validation error"
562
+ msgstr ""
563
 
564
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:408
565
+ msgid "Two cups $10.00"
566
+ msgstr "Két csésze $10,00"
567
 
568
+ #: includes/provider/v1.php:170
569
+ msgid "Type what you hear"
570
+ msgstr ""
571
 
572
+ #: includes/provider/v1.php:169
573
+ msgid "Type what you see"
574
+ msgstr ""
575
 
576
+ #: includes/class-bwp-recaptcha.php:810
577
+ msgid "Uncheck to use different key pairs for this site."
578
+ msgstr ""
579
 
580
+ #: includes/provider/abstract-provider.php:107
581
+ #, fuzzy, php-format
582
+ msgid "Unknown error (%s). Please contact an administrator for more info."
583
+ msgstr ""
584
+ "Ismeretlen hiba. További információért kérlek lépj kapcsolatba az "
585
+ "adminisztrátorral."
586
 
587
+ #: includes/class-bwp-recaptcha.php:991
588
+ msgid "Use default CSS"
589
+ msgstr ""
590
 
591
+ #: includes/class-bwp-recaptcha.php:692
592
+ msgid "Use main site's keys"
593
+ msgstr ""
594
 
595
+ #: includes/class-bwp-recaptcha.php:696
596
+ #, fuzzy
597
+ msgid "Use reCAPTCHA version 1"
598
+ msgstr "BWP reCAPTCHA Alapbeállítások"
599
 
600
+ #: includes/class-bwp-recaptcha.php:813
601
+ msgid ""
602
+ "Use the oldschool recaptcha instead of the new <em>nocaptcha</em> recaptcha."
603
+ msgstr ""
604
 
605
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:416
606
+ msgid "Via"
607
+ msgstr ""
 
608
 
609
+ #: vendor/kminh/bwp-framework/src/class-bwp-option-page-v3.php:827
610
+ msgid "View more info in a separate tab"
611
+ msgstr ""
612
+
613
+ #: includes/class-bwp-recaptcha.php:1192
614
  msgid "Warning"
615
  msgstr "Figyelmeztetés"
616
 
617
+ #: includes/class-bwp-recaptcha.php:1012
618
+ msgid "White Theme"
619
+ msgstr "Fehér Téma"
620
 
621
+ #: includes/class-bwp-recaptcha.php:1228
622
+ msgid ""
623
+ "You are enabling Akismet integration but Akismet is not currently active. "
624
+ "Please activate Akismet for the integration to work."
625
+ msgstr ""
626
+ "Engedélyezed az Akismet integrációt, de az Akismet jelenleg nem aktív. "
627
+ "Kérlek aktiváld az Akismet-et előbb."
628
 
629
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:565
630
+ #, php-format
631
+ msgid "You are using version %s!"
632
+ msgstr "Te a %s verziót használod!"
633
 
634
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:391
635
+ msgid ""
636
+ "You can buy me some special coffees if you appreciate my work, thank you!"
637
+ msgstr ""
638
+ "Vehetsz nekem pár különleges kávét, ha elégedett vagy a munkámmal, köszi!"
639
+
640
+ #: includes/class-bwp-recaptcha.php:1376
641
  msgid "Your comment was identified as spam, please complete the CAPTCHA below:"
642
+ msgstr ""
643
+ "A hozzászólásod spam-ként lett azonosítva, kérlek válaszolj az alábbi "
644
+ "CAPTCHA feladványra:"
645
+
646
+ #: includes/class-bwp-recaptcha.php:848
647
+ msgid "approved comment(s)."
648
+ msgstr "elfogadott hozzászólásuk van."
649
 
650
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:524
651
+ #: vendor/kminh/bwp-framework/src/class-bwp-framework-v3.php:534
652
+ msgid "loading..."
653
+ msgstr ""
654
 
655
+ #: includes/class-bwp-recaptcha.php:691
656
+ msgid "reCAPTCHA API Keys"
657
+ msgstr ""
658
 
659
+ #: includes/class-bwp-recaptcha.php:695
660
+ #, fuzzy
661
+ msgid "reCAPTCHA Settings"
662
+ msgstr "BWP reCAPTCHA Témabeállítások"
663
 
664
+ #: includes/class-bwp-recaptcha.php:702
665
+ #, fuzzy
666
+ msgid "reCAPTCHA for comment form"
667
+ msgstr "aktiválva a hozzászólások esetén."
668
+
669
+ #: includes/class-bwp-recaptcha.php:1086
670
+ #, fuzzy
671
+ msgid "reCAPTCHA size"
672
+ msgstr "Súgó"
673
+
674
+ #: includes/class-bwp-recaptcha.php:990 includes/class-bwp-recaptcha.php:1085
675
+ #, fuzzy
676
+ msgid "reCAPTCHA theme"
677
+ msgstr "BWP reCAPTCHA Témabeállítások"
678
+
679
+ #: includes/class-bwp-recaptcha.php:796
680
+ msgid "registered users <em>(even without any capabilities)</em>."
681
+ msgstr "regisztrált felhasználók <em>(még jogok nélkül is)</em>."
682
+
683
+ #: includes/class-bwp-recaptcha.php:1554
684
  msgid "this link"
685
  msgstr "erre a címre"
686
 
687
+ #: includes/class-bwp-recaptcha.php:799
688
+ msgid "users who can"
689
+ msgstr "Felhasználók, akik képesek"
690
 
691
+ #: includes/class-bwp-recaptcha.php:802
692
+ msgid "visitors who have at least"
693
+ msgstr "látogatók, akiknek minimum"
694
 
695
+ #~ msgid ""
696
+ #~ "<em><strong>Note:</strong> Above you can select some built-in languages. "
697
+ #~ "If you would like to add your own language, please read <a href="
698
+ #~ "\"%s#customization\" target=\"_blank\">this guide</a>.</em>"
699
+ #~ msgstr ""
700
+ #~ "<em><strong>Megjegyzés:</strong> Fent választhatsz pár beépített nyelv "
701
+ #~ "közül. Ha hozzá szeretnéd adni a saját nyelvedet, kérlek olvasd el <a "
702
+ #~ "href=\"%s#customization\" target=\"_blank\">ezt az útmutatót</a>.</em>"
703
+
704
+ #~ msgid ""
705
+ #~ "<em><strong>Note:</strong> Now you may wonder, why put the comment in the "
706
+ #~ "spam queue? The benefit is Akismet will be able to mark the comment as "
707
+ #~ "False Positive, and thus will not possibly block that comment in the "
708
+ #~ "future. However, it is best to just put the comment in moderation queue "
709
+ #~ "as next time Akismet will put such comment in moderation queue "
710
+ #~ "immediately without the need of a CAPTCHA.</em>"
711
+ #~ msgstr ""
712
+ #~ "<em><strong>Megjegyzés:</strong> Most azt kérdezhetnéd, mi értelme a "
713
+ #~ "hozzászólást a spam listára tenni? Ez azért lehet előnyös, mert az "
714
+ #~ "Akismet így képes a hozzászólást hibás találatnak jelölni, és így "
715
+ #~ "elkerülni, hogy következőleg blokkolja a hozzászólást. Ennek ellenére a "
716
+ #~ "legjobb, ha a hozzászólást a moderációs listára küldjük, mivel "
717
+ #~ "következőleg az Akismet automatikusan a moderációs listára fogja tenni az "
718
+ #~ "ilyen hozzászólásokat CAPTCHA használata nélkül.</em>"
719
+
720
+ #~ msgid ""
721
+ #~ "<em><strong>Note:</strong> The four built-in captcha themes will look OK "
722
+ #~ "in most WordPress themes; However, some times it is better to control how "
723
+ #~ "reCAPTCHA looks using CSS. Please read <a href=\"%s#customization\" "
724
+ #~ "target=\"_blank\">this guide</a> if you would like to do so.</em>"
725
+ #~ msgstr ""
726
+ #~ "<em><strong>Megjegyzés:</strong> A négy beépített captcha téma megfelelő "
727
+ #~ "a legtöbb WordPress témához; Mindazonáltal néha jobb a reCAPTCHA "
728
+ #~ "kinézetét CSS segítségével testre szabni. Ha érdekel, kérlek olvasd el <a "
729
+ #~ "href=\"%s#customization\" target=\"_blank\">ezt az útmutatót</a>.</em>"
730
+
731
+ #~ msgid ""
732
+ #~ "<em>Integrate with Akismet for better end-user experience. reCAPTCHA is "
733
+ #~ "optional and <strong>NO</strong> spam comment will be added to the spam/"
734
+ #~ "moderation queue, except likely legitimate comments. This makes the task "
735
+ #~ "of identifying sincere comments much easier. This integration is "
736
+ #~ "currently in beta stage.</em>"
737
+ #~ msgstr ""
738
+ #~ "<em>Akismet-tel való integráció a jobb felhasználói élmény elérése "
739
+ #~ "érdekében. A reCAPTCHA nem kötelező és <strong>SEMMILYEN</strong> spam "
740
+ #~ "hozzászólás nem fog a szemétszűrési/moderációs listára kerülni, csak a "
741
+ #~ "valószínűleg létező személy által írt hozzászólások. Ez nagyban "
742
+ #~ "megkönnyíti a valós hozzászólások azonosítását. Az integráció jelenleg "
743
+ #~ "béta állapotban van.</em>"
744
+
745
+ #~ msgid ""
746
+ #~ "<em>This section allows you to determine when to show reCAPTCHA and how "
747
+ #~ "this plugin reacts to errors.</em>"
748
+ #~ msgstr ""
749
+ #~ "<em>Itt tudod beállítani mikor mutassa a reCAPTCHA-t, és hogy reagáljon a "
750
+ #~ "plugin a hibákra.</em>"
751
+
752
+ #~ msgid ""
753
+ #~ "<strong>ERROR</strong>: Captcha response is either empty or incorrect."
754
+ #~ msgstr "<strong>HIBA</strong>: A captcha válasz hibás vagy üres."
755
+
756
+ #~ msgid "<strong>ERROR</strong>: Unknown captcha error."
757
+ #~ msgstr "<strong>HIBA</strong>: Ismeretlen captcha hiba."
758
+
759
+ #~ msgid ""
760
+ #~ "API key(s) missing. Please get an API key from <a href='https://www."
761
+ #~ "google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/"
762
+ #~ "create</a> (free!)"
763
+ #~ msgstr ""
764
+ #~ "Az API kulcs(ok) hiányoznak. Kérlek szerezz be egy API kulcsot innen: <a "
765
+ #~ "href='https://www.google.com/recaptcha/admin/create'>https://www.google."
766
+ #~ "com/recaptcha/admin/create</a> (ingyenes!)"
767
+
768
+ #~ msgid ""
769
+ #~ "Basically, this should be 4 if you place the captcha before the textarea, "
770
+ #~ "and 5 if you put it after."
771
+ #~ msgstr ""
772
+ #~ "Gyakorlatilag itt 4-nek kell lennie, ha a captcha-t a szövegbeviteli mező "
773
+ #~ "elé szeretnéd helyezni és 5-nek, ha utána."
774
+
775
+ #~ msgid "Choose a theme"
776
+ #~ msgstr "Válassz témát"
777
+
778
+ #~ msgid "Contact"
779
+ #~ msgstr "Kapcsolat"
780
+
781
+ #~ msgid "Development Log"
782
+ #~ msgstr "Fejlesztési napló"
783
+
784
+ #~ msgid "Dutch"
785
+ #~ msgstr "Holland"
786
+
787
+ #~ msgid "English"
788
+ #~ msgstr "Angol"
789
+
790
+ #~ msgid "Enter the numbers you hear:"
791
+ #~ msgstr "Írd be a hallott számokat:"
792
+
793
+ #~ msgid "Enter the two words in the box:"
794
+ #~ msgstr "Írd ide a két szót:"
795
+
796
+ #~ msgid "Follow me on Twitter!"
797
+ #~ msgstr "Kövess Twitteren!"
798
+
799
+ #~ msgid "French"
800
+ #~ msgstr "Francia"
801
+
802
+ #~ msgid "Frequently Asked Questions"
803
+ #~ msgstr "Gyakran Ismételt Kérdések"
804
+
805
+ #~ msgid "German"
806
+ #~ msgstr "Német"
807
+
808
+ #~ msgid "Got a problem? Send me a feedback!"
809
+ #~ msgstr "Hibát találtál? Küldj visszajelzést!"
810
+
811
+ #~ msgid "Latest updates from BetterWP.net!"
812
+ #~ msgstr "Legújabb hírek a BetterWP.net-től!"
813
+
814
+ #~ msgid "Load CSS, JS selectively?"
815
+ #~ msgstr "CSS és JS szelektív betöltése"
816
+
817
+ #~ msgid "Portuguese"
818
+ #~ msgstr "Portugál"
819
+
820
+ #~ msgid "Public Key"
821
+ #~ msgstr "Nyilvános Kulcs"
822
+
823
+ #~ msgid "Put comment in spam queue"
824
+ #~ msgstr "Hozzászólások spam listára tétele"
825
+
826
+ #~ msgid "Russian"
827
+ #~ msgstr "Orosz"
828
+
829
+ #~ msgid "Spanish"
830
+ #~ msgstr "Spanyol"
831
+
832
+ #~ msgid "This is only useful when you do not use any minify or cache plugin."
833
+ #~ msgstr ""
834
+ #~ "Ez csak akkor hasznos, ha nem használsz semmilyen minify vagy gyorsítótár "
835
+ #~ "plugint."
836
+
837
+ #~ msgid "This plugin will be"
838
+ #~ msgstr "Ez a plugin"
839
+
840
+ #~ msgid ""
841
+ #~ "This stylesheet is used to style the custom theme as well as the "
842
+ #~ "registration page. You can disable this or add appropriate filters to use "
843
+ #~ "your own."
844
+ #~ msgstr ""
845
+ #~ "Ezt a stíluslapot használja a testre szabott téma és a regisztrációs "
846
+ #~ "oldal is. Kikapcsolhatod ezt, vagy magad is hozzáathatsz megfelelő "
847
+ #~ "szűrőket."
848
+
849
+ #~ msgid ""
850
+ #~ "To use reCAPTCHA you must get an API key from <a href='https://www.google."
851
+ #~ "com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/"
852
+ #~ "create</a>"
853
+ #~ msgstr ""
854
+ #~ "A reCAPTCHA használatához API kulcsot kell szerezned innen: <a "
855
+ #~ "href='https://www.google.com/recaptcha/admin/create'>https://www.google."
856
+ #~ "com/recaptcha/admin/create</a>"
857
+
858
+ #~ msgid "Turkish"
859
+ #~ msgstr "Török"
860
+
861
+ #~ msgid "What is reCAPTCHA?"
862
+ #~ msgstr "Mi a reCAPTCHA?"
863
 
864
+ #~ msgid "You do not have sufficient permissions to access this page."
865
+ #~ msgstr "Nincs engedélyed a lap megtekintéséhez."
866
+
867
+ #~ msgid "enabled for registration page."
868
+ #~ msgstr "aktiválva a regisztrációs űrlap esetén."
869
+
870
+ #~ msgid ""
871
+ #~ "reCAPTCHA is a free CAPTCHA service that helps to digitize books, "
872
+ #~ "newspapers and old time radio shows. You can read more about reCAPTCHA <a "
873
+ #~ "href=\"http://www.google.com/recaptcha/learnmore\" target=\"_blank"
874
+ #~ "\">here</a>."
875
+ #~ msgstr ""
876
+ #~ "reCAPTCHA egy ingyenes CAPTCHA egy ingyenes rendszer, ami CAPTCHA "
877
+ #~ "technológiát használ, hogy segítsen digitalizálni régi könyvek és "
878
+ #~ "rádióműsorok szövegét, miközben megvédi a weblapokat az automatikus "
879
+ #~ "szoftverektől, amelyek korlátozott területekhez akarnak hozzáférni, "
880
+ #~ "magukat embernek kiadva (pl. regisztráció). További információ a "
881
+ #~ "reCAPTCHA-ról <a href=\"http://www.google.com/recaptcha/learnmore\" "
882
+ #~ "target=\"_blank\">itt</a>."
883
 
884
+ #~ msgid "when show the normal error page with no redirection."
885
+ #~ msgstr "amikor a hibajelentő lapot mutatjuk átirányítás nélkül."
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === Better WordPress reCAPTCHA (with no CAPTCHA reCAPTCHA) ===
2
  Contributors: OddOneOut
3
  Donate link: http://betterwp.net/wordpress-plugins/bwp-recaptcha/#contributions
4
- Tags: recaptcha, captcha, no captcha, nocapthca, no captcha recaptcha, nocaptcha recaptcha, comment captcha, login captcha, user registration captcha, blog registration captcha, contact form, contact form 7, contact form 7 recaptcha, akismet, akismet integration, akismet captcha, anti-spam, antispam
5
  Requires at least: 3.6
6
- Tested up to: 4.3
7
- Stable tag: 2.0.2
8
  License: GPLv3 or later
9
 
10
  This plugin utilizes Google reCAPTCHA to help your blog stay clear of spams.
@@ -21,7 +21,7 @@ your blog stay clear of spams.
21
  The new no CAPTCHA reCAPTCHA, Contact Form 7 and Akismet are supported out of
22
  the box.
23
 
24
- **Useful resources:**
25
 
26
  [How-to: Add BWP reCAPTCHA to Contact Form 7](http://betterwp.net/wordpress-tips/how-to-add-bwp-recaptcha-to-contact-form-7/).
27
 
@@ -29,46 +29,47 @@ the box.
29
 
30
  [Official Documentation](http://betterwp.net/wordpress-plugins/bwp-recaptcha/).
31
 
32
- **Some Features**
33
 
34
  - Choose between reCAPTCHA version 2 (no CAPTCHA reCAPTCHA) or the oldschool
35
  reCAPTCHA.
36
  - You can add captcha to comment form, user registration form, site
37
  registration form and login form.
38
- - You can add captcha to form generated by Contact Form 7 plugin:
39
- - Choose to treat invalid captcha as spam or validation error
40
- - Customize the error message when captcha is invalid
41
  - Hide captcha for qualified visitors.
42
  - Comment Form:
43
- - You can position captcha before or after the comment field
44
- - Control how the plugin reacts when captcha response is invalid
45
- - Set error message when captcha response is invalid
46
  - Theme Features:
 
47
  - reCAPTCHA version 2:
48
  - Choose between 2 default themes
49
  - Normal or compact size
50
  - More than 50 languages
51
  - reCAPTCHA version 1:
52
  - Choose between 4 default themes or create your own (sample CSS and images
53
- provided)
54
- - Use built-in languages or add custom translations
55
  - Integrate with Akismet for better end-users experience, i.e. "only force a
56
  CAPTCHA when a comment looks like spam".
57
  - WordPress Multi-site compatible: you can set different key pair for each
58
  site or use a single key pair for all sites.
59
  - And more...
60
 
61
- **Support this plugin**
62
 
63
- Please don't forget to rate this plugin [5 shining stars](http://wordpress.org/support/view/plugin-reviews/bwp-recaptcha?filter=5) if you like it, thanks!
64
 
65
- **Get in touch**
66
 
67
  * Found a bug? Have a feature request? [Let me know](http://betterwp.net/wordpress-plugins/bwp-recaptcha/#report-issues)!
68
  * Follow me on [Twitter](http://twitter.com/0dd0ne0ut).
69
  * Check out [latest WordPress Tips and Ideas](http://feeds.feedburner.com/BetterWPnet) from BetterWP.net.
70
 
71
- **Languages**
72
 
73
  * English (default)
74
  * Spanish - Espanol (es_ES) - Thanks to Ivan Leomuro!
@@ -81,11 +82,13 @@ Please [help translate](http://betterwp.net/wordpress-tips/create-pot-file-using
81
 
82
  == Installation ==
83
 
84
- [View instructions with images](http://betterwp.net/wordpress-plugins/bwp-recaptcha/installation/).
85
 
86
  == Frequently Asked Questions ==
87
 
88
- [View current FAQs](http://betterwp.net/wordpress-plugins/bwp-recaptcha/faq/).
 
 
89
 
90
  == Screenshots ==
91
 
@@ -97,6 +100,30 @@ Please [help translate](http://betterwp.net/wordpress-tips/create-pot-file-using
97
 
98
  == Changelog ==
99
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  = 2.0.2 (2015-10-30) =
101
 
102
  - **New Features**
@@ -169,4 +196,4 @@ Please [help translate](http://betterwp.net/wordpress-tips/create-pot-file-using
169
 
170
  == Upgrade Notice ==
171
 
172
- Nothing here yet.
1
  === Better WordPress reCAPTCHA (with no CAPTCHA reCAPTCHA) ===
2
  Contributors: OddOneOut
3
  Donate link: http://betterwp.net/wordpress-plugins/bwp-recaptcha/#contributions
4
+ Tags: recaptcha, captcha, no captcha, nocapthca, nocaptcha recaptcha, comment captcha, login captcha, user registration captcha, blog registration captcha, contact form, contact form 7, contact form 7 recaptcha, akismet, akismet captcha, anti-spam, antispam
5
  Requires at least: 3.6
6
+ Tested up to: 4.4
7
+ Stable tag: 2.0.3
8
  License: GPLv3 or later
9
 
10
  This plugin utilizes Google reCAPTCHA to help your blog stay clear of spams.
21
  The new no CAPTCHA reCAPTCHA, Contact Form 7 and Akismet are supported out of
22
  the box.
23
 
24
+ = Useful resources =
25
 
26
  [How-to: Add BWP reCAPTCHA to Contact Form 7](http://betterwp.net/wordpress-tips/how-to-add-bwp-recaptcha-to-contact-form-7/).
27
 
29
 
30
  [Official Documentation](http://betterwp.net/wordpress-plugins/bwp-recaptcha/).
31
 
32
+ = Some Features =
33
 
34
  - Choose between reCAPTCHA version 2 (no CAPTCHA reCAPTCHA) or the oldschool
35
  reCAPTCHA.
36
  - You can add captcha to comment form, user registration form, site
37
  registration form and login form.
38
+ - You can add captcha to forms generated by Contact Form 7 plugin:
39
+ - Choose to treat invalid captcha as spam or validation error.
40
+ - Customize the error message when captcha is invalid.
41
  - Hide captcha for qualified visitors.
42
  - Comment Form:
43
+ - You can position captcha before or after the comment field.
44
+ - Control how the plugin reacts when captcha response is invalid.
45
+ - Set error message when captcha response is invalid.
46
  - Theme Features:
47
+ - Ability to use custom CSS rules (**new in 2.0.3**)
48
  - reCAPTCHA version 2:
49
  - Choose between 2 default themes
50
  - Normal or compact size
51
  - More than 50 languages
52
  - reCAPTCHA version 1:
53
  - Choose between 4 default themes or create your own (sample CSS and images
54
+ provided).
55
+ - Use built-in languages or add custom translations.
56
  - Integrate with Akismet for better end-users experience, i.e. "only force a
57
  CAPTCHA when a comment looks like spam".
58
  - WordPress Multi-site compatible: you can set different key pair for each
59
  site or use a single key pair for all sites.
60
  - And more...
61
 
62
+ = Support this plugin =
63
 
64
+ Don't forget to rate this plugin [5 shining stars](http://wordpress.org/support/view/plugin-reviews/bwp-recaptcha?filter=5) if you like it, thanks!
65
 
66
+ = Get in touch =
67
 
68
  * Found a bug? Have a feature request? [Let me know](http://betterwp.net/wordpress-plugins/bwp-recaptcha/#report-issues)!
69
  * Follow me on [Twitter](http://twitter.com/0dd0ne0ut).
70
  * Check out [latest WordPress Tips and Ideas](http://feeds.feedburner.com/BetterWPnet) from BetterWP.net.
71
 
72
+ = Languages =
73
 
74
  * English (default)
75
  * Spanish - Espanol (es_ES) - Thanks to Ivan Leomuro!
82
 
83
  == Installation ==
84
 
85
+ [View instructions with images and video](http://betterwp.net/wordpress-plugins/bwp-recaptcha/installation/).
86
 
87
  == Frequently Asked Questions ==
88
 
89
+ If you have trouble using this plugin, consider giving the [Frequently Asked
90
+ Questions](http://betterwp.net/wordpress-plugins/bwp-recaptcha/faq/) page a
91
+ look.
92
 
93
  == Screenshots ==
94
 
100
 
101
  == Changelog ==
102
 
103
+ = 2.0.3 (2016-01-13) =
104
+
105
+ - **New Features**
106
+ - Allow adding custom CSS rules to control the look and feel of
107
+ recaptcha instances. To enable this feature, navigate to *BWP
108
+ reCAPT >> Theme Options*, choose to enable Custom CSS, and then
109
+ customize the default CSS rules however you like.
110
+ - **Enhancements**
111
+ - Allow setting a request method to work around the "invalid-json" error.
112
+ With this change fsockopen is preferred to cURL, and will be the first
113
+ to be used to communicate with reCAPTCHA's server.
114
+ - **Other Changes**
115
+ - Marked as compatible with WordPress 4.4+.
116
+ - Update language template file and translation files. If you're a
117
+ translator, please help translating this plugin (your name and website
118
+ will be listed on this plugin's page!) For more info, see:
119
+ <http://betterwp.net/wordpress-tips/create-pot-file-using-poedit/>
120
+ - **Bugs fixed**
121
+ - Fix a bug that results in captcha not showing on certain login pages.
122
+ Affected login pages include:
123
+ - Login page that uses secured HTTP (HTTPS)
124
+ - Login page of a child blog in a sub-directory multisite
125
+ installation.
126
+
127
  = 2.0.2 (2015-10-30) =
128
 
129
  - **New Features**
196
 
197
  == Upgrade Notice ==
198
 
199
+ Nothing here.
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
- return ComposerAutoloaderInite7d0f0445ae97bf38aa36b7fc574449a::getLoader();
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit5c2e350ddfa6a7621d396a1eef6fdc4e::getLoader();
vendor/composer/ClassLoader.php CHANGED
@@ -13,9 +13,7 @@
13
  namespace Composer\Autoload;
14
 
15
  /**
16
- * ClassLoader implements a PSR-0 class loader
17
- *
18
- * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
19
  *
20
  * $loader = new \Composer\Autoload\ClassLoader();
21
  *
@@ -39,6 +37,8 @@ namespace Composer\Autoload;
39
  *
40
  * @author Fabien Potencier <fabien@symfony.com>
41
  * @author Jordi Boggiano <j.boggiano@seld.be>
 
 
42
  */
43
  class ClassLoader
44
  {
13
  namespace Composer\Autoload;
14
 
15
  /**
16
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
 
 
17
  *
18
  * $loader = new \Composer\Autoload\ClassLoader();
19
  *
37
  *
38
  * @author Fabien Potencier <fabien@symfony.com>
39
  * @author Jordi Boggiano <j.boggiano@seld.be>
40
+ * @see http://www.php-fig.org/psr/psr-0/
41
+ * @see http://www.php-fig.org/psr/psr-4/
42
  */
43
  class ClassLoader
44
  {
vendor/composer/autoload_classmap.php CHANGED
@@ -26,5 +26,74 @@ return array(
26
  'BWP_Recaptcha_Provider_V2' => $baseDir . '/includes/provider/v2.php',
27
  'BWP_Version' => $vendorDir . '/kminh/bwp-framework/src/class-bwp-version.php',
28
  'BWP_WP_Bridge' => $vendorDir . '/kminh/bwp-framework/src/class-bwp-wp-bridge.php',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  'ReCaptchaResponse' => $baseDir . '/includes/provider/recaptcha/response.php',
 
 
 
 
 
 
 
 
 
30
  );
26
  'BWP_Recaptcha_Provider_V2' => $baseDir . '/includes/provider/v2.php',
27
  'BWP_Version' => $vendorDir . '/kminh/bwp-framework/src/class-bwp-version.php',
28
  'BWP_WP_Bridge' => $vendorDir . '/kminh/bwp-framework/src/class-bwp-wp-bridge.php',
29
+ 'Composer\\Installers\\AglInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AglInstaller.php',
30
+ 'Composer\\Installers\\AimeosInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AimeosInstaller.php',
31
+ 'Composer\\Installers\\AnnotateCmsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php',
32
+ 'Composer\\Installers\\AsgardInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AsgardInstaller.php',
33
+ 'Composer\\Installers\\BaseInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/BaseInstaller.php',
34
+ 'Composer\\Installers\\BitrixInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/BitrixInstaller.php',
35
+ 'Composer\\Installers\\BonefishInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/BonefishInstaller.php',
36
+ 'Composer\\Installers\\CakePHPInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CakePHPInstaller.php',
37
+ 'Composer\\Installers\\ChefInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ChefInstaller.php',
38
+ 'Composer\\Installers\\ClanCatsFrameworkInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php',
39
+ 'Composer\\Installers\\CodeIgniterInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php',
40
+ 'Composer\\Installers\\Concrete5Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Concrete5Installer.php',
41
+ 'Composer\\Installers\\CraftInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CraftInstaller.php',
42
+ 'Composer\\Installers\\CroogoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CroogoInstaller.php',
43
+ 'Composer\\Installers\\DokuWikiInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DokuWikiInstaller.php',
44
+ 'Composer\\Installers\\DolibarrInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DolibarrInstaller.php',
45
+ 'Composer\\Installers\\DrupalInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DrupalInstaller.php',
46
+ 'Composer\\Installers\\ElggInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ElggInstaller.php',
47
+ 'Composer\\Installers\\FuelInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/FuelInstaller.php',
48
+ 'Composer\\Installers\\FuelphpInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/FuelphpInstaller.php',
49
+ 'Composer\\Installers\\GravInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/GravInstaller.php',
50
+ 'Composer\\Installers\\HuradInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/HuradInstaller.php',
51
+ 'Composer\\Installers\\Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Installer.php',
52
+ 'Composer\\Installers\\JoomlaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/JoomlaInstaller.php',
53
+ 'Composer\\Installers\\KirbyInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KirbyInstaller.php',
54
+ 'Composer\\Installers\\KodiCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KodiCMSInstaller.php',
55
+ 'Composer\\Installers\\KohanaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KohanaInstaller.php',
56
+ 'Composer\\Installers\\LaravelInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/LaravelInstaller.php',
57
+ 'Composer\\Installers\\LithiumInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/LithiumInstaller.php',
58
+ 'Composer\\Installers\\MODULEWorkInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php',
59
+ 'Composer\\Installers\\MODXEvoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MODXEvoInstaller.php',
60
+ 'Composer\\Installers\\MagentoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MagentoInstaller.php',
61
+ 'Composer\\Installers\\MakoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MakoInstaller.php',
62
+ 'Composer\\Installers\\MediaWikiInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MediaWikiInstaller.php',
63
+ 'Composer\\Installers\\MicroweberInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MicroweberInstaller.php',
64
+ 'Composer\\Installers\\MoodleInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MoodleInstaller.php',
65
+ 'Composer\\Installers\\OctoberInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/OctoberInstaller.php',
66
+ 'Composer\\Installers\\OxidInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/OxidInstaller.php',
67
+ 'Composer\\Installers\\PPIInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PPIInstaller.php',
68
+ 'Composer\\Installers\\PhpBBInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PhpBBInstaller.php',
69
+ 'Composer\\Installers\\PimcoreInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PimcoreInstaller.php',
70
+ 'Composer\\Installers\\PiwikInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PiwikInstaller.php',
71
+ 'Composer\\Installers\\Plugin' => $vendorDir . '/composer/installers/src/Composer/Installers/Plugin.php',
72
+ 'Composer\\Installers\\PrestashopInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PrestashopInstaller.php',
73
+ 'Composer\\Installers\\PuppetInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PuppetInstaller.php',
74
+ 'Composer\\Installers\\RedaxoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/RedaxoInstaller.php',
75
+ 'Composer\\Installers\\RoundcubeInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/RoundcubeInstaller.php',
76
+ 'Composer\\Installers\\SMFInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SMFInstaller.php',
77
+ 'Composer\\Installers\\ShopwareInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ShopwareInstaller.php',
78
+ 'Composer\\Installers\\SilverStripeInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SilverStripeInstaller.php',
79
+ 'Composer\\Installers\\Symfony1Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Symfony1Installer.php',
80
+ 'Composer\\Installers\\TYPO3CmsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php',
81
+ 'Composer\\Installers\\TYPO3FlowInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php',
82
+ 'Composer\\Installers\\TheliaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TheliaInstaller.php',
83
+ 'Composer\\Installers\\TuskInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TuskInstaller.php',
84
+ 'Composer\\Installers\\WHMCSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/WHMCSInstaller.php',
85
+ 'Composer\\Installers\\WolfCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/WolfCMSInstaller.php',
86
+ 'Composer\\Installers\\WordPressInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/WordPressInstaller.php',
87
+ 'Composer\\Installers\\ZendInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ZendInstaller.php',
88
+ 'Composer\\Installers\\ZikulaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ZikulaInstaller.php',
89
  'ReCaptchaResponse' => $baseDir . '/includes/provider/recaptcha/response.php',
90
+ 'ReCaptcha\\ReCaptcha' => $vendorDir . '/google/recaptcha/src/ReCaptcha/ReCaptcha.php',
91
+ 'ReCaptcha\\RequestMethod' => $vendorDir . '/google/recaptcha/src/ReCaptcha/RequestMethod.php',
92
+ 'ReCaptcha\\RequestMethod\\Curl' => $vendorDir . '/google/recaptcha/src/ReCaptcha/RequestMethod/Curl.php',
93
+ 'ReCaptcha\\RequestMethod\\CurlPost' => $vendorDir . '/google/recaptcha/src/ReCaptcha/RequestMethod/CurlPost.php',
94
+ 'ReCaptcha\\RequestMethod\\Post' => $vendorDir . '/google/recaptcha/src/ReCaptcha/RequestMethod/Post.php',
95
+ 'ReCaptcha\\RequestMethod\\Socket' => $vendorDir . '/google/recaptcha/src/ReCaptcha/RequestMethod/Socket.php',
96
+ 'ReCaptcha\\RequestMethod\\SocketPost' => $vendorDir . '/google/recaptcha/src/ReCaptcha/RequestMethod/SocketPost.php',
97
+ 'ReCaptcha\\RequestParameters' => $vendorDir . '/google/recaptcha/src/ReCaptcha/RequestParameters.php',
98
+ 'ReCaptcha\\Response' => $vendorDir . '/google/recaptcha/src/ReCaptcha/Response.php',
99
  );
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInite7d0f0445ae97bf38aa36b7fc574449a
6
  {
7
  private static $loader;
8
 
@@ -19,9 +19,9 @@ class ComposerAutoloaderInite7d0f0445ae97bf38aa36b7fc574449a
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInite7d0f0445ae97bf38aa36b7fc574449a', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInite7d0f0445ae97bf38aa36b7fc574449a', 'loadClassLoader'));
25
 
26
  $map = require __DIR__ . '/autoload_namespaces.php';
27
  foreach ($map as $namespace => $path) {
@@ -43,8 +43,3 @@ class ComposerAutoloaderInite7d0f0445ae97bf38aa36b7fc574449a
43
  return $loader;
44
  }
45
  }
46
-
47
- function composerRequiree7d0f0445ae97bf38aa36b7fc574449a($file)
48
- {
49
- require $file;
50
- }
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit5c2e350ddfa6a7621d396a1eef6fdc4e
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit5c2e350ddfa6a7621d396a1eef6fdc4e', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit5c2e350ddfa6a7621d396a1eef6fdc4e', 'loadClassLoader'));
25
 
26
  $map = require __DIR__ . '/autoload_namespaces.php';
27
  foreach ($map as $namespace => $path) {
43
  return $loader;
44
  }
45
  }
 
 
 
 
 
vendor/composer/installed.json CHANGED
@@ -1,19 +1,22 @@
1
  [
2
  {
3
  "name": "composer/installers",
4
- "version": "v1.0.21",
5
- "version_normalized": "1.0.21.0",
6
  "source": {
7
  "type": "git",
8
  "url": "https://github.com/composer/installers.git",
9
- "reference": "d64e23fce42a4063d63262b19b8e7c0f3b5e4c45"
10
  },
11
  "dist": {
12
  "type": "zip",
13
- "url": "https://api.github.com/repos/composer/installers/zipball/d64e23fce42a4063d63262b19b8e7c0f3b5e4c45",
14
- "reference": "d64e23fce42a4063d63262b19b8e7c0f3b5e4c45",
15
  "shasum": ""
16
  },
 
 
 
17
  "replace": {
18
  "roundcube/plugin-installer": "*",
19
  "shama/baton": "*"
@@ -22,10 +25,10 @@
22
  "composer/composer": "1.0.*@dev",
23
  "phpunit/phpunit": "4.1.*"
24
  },
25
- "time": "2015-02-18 17:17:01",
26
- "type": "composer-installer",
27
  "extra": {
28
- "class": "Composer\\Installers\\Installer",
29
  "branch-alias": {
30
  "dev-master": "1.0-dev"
31
  }
@@ -150,7 +153,7 @@
150
  "source": {
151
  "type": "git",
152
  "url": "https://github.com/kminh/bwp-framework",
153
- "reference": "423d2c5386790200e259d70cf81b1829deb23ecb"
154
  },
155
  "require": {
156
  "php": "^5.2.0"
@@ -164,14 +167,15 @@
164
  "mockery/mockery": "^0.9.4",
165
  "phpunit/phpunit": "^4.8"
166
  },
167
- "time": "2015-10-31 09:27:32",
168
  "bin": [
169
- "bin/install-wp-tests.sh"
 
170
  ],
171
  "type": "library",
172
  "extra": {
173
  "branch-alias": {
174
- "dev-master": "3.2.x-dev"
175
  }
176
  },
177
  "installation-source": "source",
1
  [
2
  {
3
  "name": "composer/installers",
4
+ "version": "v1.0.22",
5
+ "version_normalized": "1.0.22.0",
6
  "source": {
7
  "type": "git",
8
  "url": "https://github.com/composer/installers.git",
9
+ "reference": "bd9b14f094c89c8b5804a4e41edeb7853bb85046"
10
  },
11
  "dist": {
12
  "type": "zip",
13
+ "url": "https://api.github.com/repos/composer/installers/zipball/bd9b14f094c89c8b5804a4e41edeb7853bb85046",
14
+ "reference": "bd9b14f094c89c8b5804a4e41edeb7853bb85046",
15
  "shasum": ""
16
  },
17
+ "require": {
18
+ "composer-plugin-api": "1.0.0"
19
+ },
20
  "replace": {
21
  "roundcube/plugin-installer": "*",
22
  "shama/baton": "*"
25
  "composer/composer": "1.0.*@dev",
26
  "phpunit/phpunit": "4.1.*"
27
  },
28
+ "time": "2015-10-29 23:28:48",
29
+ "type": "composer-plugin",
30
  "extra": {
31
+ "class": "Composer\\Installers\\Plugin",
32
  "branch-alias": {
33
  "dev-master": "1.0-dev"
34
  }
153
  "source": {
154
  "type": "git",
155
  "url": "https://github.com/kminh/bwp-framework",
156
+ "reference": "b23725dc0bf58bd0cde6df1268db3121a9e68577"
157
  },
158
  "require": {
159
  "php": "^5.2.0"
167
  "mockery/mockery": "^0.9.4",
168
  "phpunit/phpunit": "^4.8"
169
  },
170
+ "time": "2016-01-14 01:49:54",
171
  "bin": [
172
+ "bin/install-wp-tests.sh",
173
+ "bin/build-translations"
174
  ],
175
  "type": "library",
176
  "extra": {
177
  "branch-alias": {
178
+ "dev-master": "3.4.x-dev"
179
  }
180
  },
181
  "installation-source": "source",
vendor/composer/installers/src/Composer/Installers/BaseInstaller.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
  namespace Composer\Installers;
3
 
 
4
  use Composer\Composer;
5
  use Composer\Package\PackageInterface;
6
 
@@ -9,17 +10,20 @@ abstract class BaseInstaller
9
  protected $locations = array();
10
  protected $composer;
11
  protected $package;
 
12
 
13
  /**
14
  * Initializes base installer.
15
  *
16
  * @param PackageInterface $package
17
  * @param Composer $composer
 
18
  */
19
- public function __construct(PackageInterface $package = null, Composer $composer = null)
20
  {
21
  $this->composer = $composer;
22
  $this->package = $package;
 
23
  }
24
 
25
  /**
1
  <?php
2
  namespace Composer\Installers;
3
 
4
+ use Composer\IO\IOInterface;
5
  use Composer\Composer;
6
  use Composer\Package\PackageInterface;
7
 
10
  protected $locations = array();
11
  protected $composer;
12
  protected $package;
13
+ protected $io;
14
 
15
  /**
16
  * Initializes base installer.
17
  *
18
  * @param PackageInterface $package
19
  * @param Composer $composer
20
+ * @param IOInterface $io
21
  */
22
+ public function __construct(PackageInterface $package = null, Composer $composer = null, IOInterface $io = null)
23
  {
24
  $this->composer = $composer;
25
  $this->package = $package;
26
+ $this->io = $io;
27
  }
28
 
29
  /**
vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php CHANGED
@@ -1,11 +1,89 @@
1
  <?php
2
  namespace Composer\Installers;
3
 
 
 
 
 
 
 
 
 
4
  class BitrixInstaller extends BaseInstaller
5
  {
6
  protected $locations = array(
7
- 'module' => 'local/modules/{$name}/',
8
- 'component' => 'local/components/{$name}/',
9
- 'theme' => 'local/templates/{$name}/'
10
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  }
1
  <?php
2
  namespace Composer\Installers;
3
 
4
+ use Composer\Util\Filesystem;
5
+
6
+ /**
7
+ * Installer for Bitrix Framework
8
+ *
9
+ * @author Nik Samokhvalov <nik@samokhvalov.info>
10
+ * @author Denis Kulichkin <onexhovia@gmail.com>
11
+ */
12
  class BitrixInstaller extends BaseInstaller
13
  {
14
  protected $locations = array(
15
+ 'module' => 'bitrix/modules/{$name}/',
16
+ 'component' => 'bitrix/components/{$name}/',
17
+ 'theme' => 'bitrix/templates/{$name}/',
18
  );
19
+
20
+ /**
21
+ * @var array Storage for informations about duplicates at all the time of installation packages
22
+ */
23
+ private static $checkedDuplicates = array();
24
+
25
+ /**
26
+ * {@inheritdoc}
27
+ */
28
+ protected function templatePath($path, array $vars = array())
29
+ {
30
+ $templatePath = parent::templatePath($path, $vars);
31
+ $this->checkDuplicates($templatePath, $vars);
32
+
33
+ return $templatePath;
34
+ }
35
+
36
+ /**
37
+ * Duplicates search packages
38
+ *
39
+ * @param string $templatePath
40
+ * @param array $vars
41
+ */
42
+ protected function checkDuplicates($templatePath, array $vars = array())
43
+ {
44
+ /**
45
+ * Incorrect paths for backward compatibility
46
+ */
47
+ $oldLocations = array(
48
+ 'module' => 'local/modules/{$name}/',
49
+ 'component' => 'local/components/{$name}/',
50
+ 'theme' => 'local/templates/{$name}/'
51
+ );
52
+
53
+ $packageType = substr($vars['type'], strlen('bitrix') + 1);
54
+ $oldLocation = str_replace('{$name}', $vars['name'], $oldLocations[$packageType]);
55
+
56
+ if (in_array($oldLocation, static::$checkedDuplicates)) {
57
+ return;
58
+ }
59
+
60
+ if ($oldLocation !== $templatePath && file_exists($oldLocation) && $this->io && $this->io->isInteractive()) {
61
+
62
+ $this->io->writeError(' <error>Duplication of packages:</error>');
63
+ $this->io->writeError(' <info>Package ' . $oldLocation . ' will be called instead package ' . $templatePath . '</info>');
64
+
65
+ while (true) {
66
+ switch ($this->io->ask(' <info>Delete ' . $oldLocation . ' [y,n,?]?</info> ', '?')) {
67
+ case 'y':
68
+ $fs = new Filesystem();
69
+ $fs->removeDirectory($oldLocation);
70
+ break 2;
71
+
72
+ case 'n':
73
+ break 2;
74
+
75
+ case '?':
76
+ default:
77
+ $this->io->writeError(array(
78
+ ' y - delete package ' . $oldLocation . ' and to continue with the installation',
79
+ ' n - don\'t delete and to continue with the installation',
80
+ ));
81
+ $this->io->writeError(' ? - print help');
82
+ break;
83
+ }
84
+ }
85
+ }
86
+
87
+ static::$checkedDuplicates[] = $oldLocation;
88
+ }
89
  }
vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class BonefishInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'package' => 'Packages/{$vendor}/{$name}/'
8
+ );
9
+ }
vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php CHANGED
@@ -3,8 +3,6 @@ namespace Composer\Installers;
3
 
4
  use Composer\DependencyResolver\Pool;
5
  use Composer\Package\PackageInterface;
6
- use Composer\Package\LinkConstraint\MultiConstraint;
7
- use Composer\Package\LinkConstraint\VersionConstraint;
8
 
9
  class CakePHPInstaller extends BaseInstaller
10
  {
@@ -52,21 +50,29 @@ class CakePHPInstaller extends BaseInstaller
52
  */
53
  protected function matchesCakeVersion($matcher, $version)
54
  {
 
 
 
 
 
 
 
 
55
  $repositoryManager = $this->composer->getRepositoryManager();
56
  if ($repositoryManager) {
57
  $repos = $repositoryManager->getLocalRepository();
58
  if (!$repos) {
59
  return false;
60
  }
61
- $cake3 = new MultiConstraint(array(
62
- new VersionConstraint($matcher, $version),
63
- new VersionConstraint('!=', '9999999-dev'),
64
  ));
65
  $pool = new Pool('dev');
66
  $pool->addRepository($repos);
67
  $packages = $pool->whatProvides('cakephp/cakephp');
68
  foreach ($packages as $package) {
69
- $installed = new VersionConstraint('=', $package->getVersion());
70
  if ($cake3->matches($installed)) {
71
  return true;
72
  break;
3
 
4
  use Composer\DependencyResolver\Pool;
5
  use Composer\Package\PackageInterface;
 
 
6
 
7
  class CakePHPInstaller extends BaseInstaller
8
  {
50
  */
51
  protected function matchesCakeVersion($matcher, $version)
52
  {
53
+ if (class_exists('Composer\Semver\Constraint\MultiConstraint')) {
54
+ $multiClass = 'Composer\Semver\Constraint\MultiConstraint';
55
+ $constraintClass = 'Composer\Semver\Constraint\Constraint';
56
+ } else {
57
+ $multiClass = 'Composer\Package\LinkConstraint\MultiConstraint';
58
+ $constraintClass = 'Composer\Package\LinkConstraint\VersionConstraint';
59
+ }
60
+
61
  $repositoryManager = $this->composer->getRepositoryManager();
62
  if ($repositoryManager) {
63
  $repos = $repositoryManager->getLocalRepository();
64
  if (!$repos) {
65
  return false;
66
  }
67
+ $cake3 = new $multiClass(array(
68
+ new $constraintClass($matcher, $version),
69
+ new $constraintClass('!=', '9999999-dev'),
70
  ));
71
  $pool = new Pool('dev');
72
  $pool->addRepository($repos);
73
  $packages = $pool->whatProvides('cakephp/cakephp');
74
  foreach ($packages as $package) {
75
+ $installed = new $constraintClass('=', $package->getVersion());
76
  if ($cake3->matches($installed)) {
77
  return true;
78
  break;
vendor/composer/installers/src/Composer/Installers/CraftInstaller.php CHANGED
@@ -1,9 +1,35 @@
1
  <?php
2
  namespace Composer\Installers;
3
 
 
 
 
4
  class CraftInstaller extends BaseInstaller
5
  {
 
 
 
6
  protected $locations = array(
7
  'plugin' => 'craft/plugins/{$name}/',
8
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  }
1
  <?php
2
  namespace Composer\Installers;
3
 
4
+ /**
5
+ * Installer for Craft Plugins
6
+ */
7
  class CraftInstaller extends BaseInstaller
8
  {
9
+ const NAME_PREFIX = 'craft';
10
+ const NAME_SUFFIX = 'plugin';
11
+
12
  protected $locations = array(
13
  'plugin' => 'craft/plugins/{$name}/',
14
  );
15
+
16
+ /**
17
+ * Strip `craft-` prefix and/or `-plugin` suffix from package names
18
+ *
19
+ * @param array $vars
20
+ *
21
+ * @return array
22
+ */
23
+ final public function inflectPackageVars($vars)
24
+ {
25
+ return $this->inflectPluginVars($vars);
26
+ }
27
+
28
+ private function inflectPluginVars($vars)
29
+ {
30
+ $vars['name'] = preg_replace('/-' . self::NAME_SUFFIX . '$/i', '', $vars['name']);
31
+ $vars['name'] = preg_replace('/^' . self::NAME_PREFIX . '-/i', '', $vars['name']);
32
+
33
+ return $vars;
34
+ }
35
  }
vendor/composer/installers/src/Composer/Installers/Installer.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
  namespace Composer\Installers;
3
 
 
4
  use Composer\Installer\LibraryInstaller;
5
  use Composer\Package\PackageInterface;
6
  use Composer\Repository\InstalledRepositoryInterface;
@@ -18,6 +19,7 @@ class Installer extends LibraryInstaller
18
  'agl' => 'AglInstaller',
19
  'annotatecms' => 'AnnotateCmsInstaller',
20
  'bitrix' => 'BitrixInstaller',
 
21
  'cakephp' => 'CakePHPInstaller',
22
  'chef' => 'ChefInstaller',
23
  'ccframework' => 'ClanCatsFrameworkInstaller',
@@ -35,6 +37,7 @@ class Installer extends LibraryInstaller
35
  'hurad' => 'HuradInstaller',
36
  'joomla' => 'JoomlaInstaller',
37
  'kirby' => 'KirbyInstaller',
 
38
  'kohana' => 'KohanaInstaller',
39
  'laravel' => 'LaravelInstaller',
40
  'lithium' => 'LithiumInstaller',
@@ -67,7 +70,7 @@ class Installer extends LibraryInstaller
67
  'wordpress' => 'WordPressInstaller',
68
  'zend' => 'ZendInstaller',
69
  'zikula' => 'ZikulaInstaller',
70
- 'prestashop' => 'PrestashopInstaller',
71
  );
72
 
73
  /**
@@ -85,7 +88,7 @@ class Installer extends LibraryInstaller
85
  }
86
 
87
  $class = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
88
- $installer = new $class($package, $this->composer);
89
 
90
  return $installer->getInstallPath($package, $frameworkType);
91
  }
@@ -153,11 +156,21 @@ class Installer extends LibraryInstaller
153
  if (!empty($this->supportedTypes[$frameworkType])) {
154
  $frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
155
  /** @var BaseInstaller $framework */
156
- $framework = new $frameworkClass(null, $this->composer);
157
  $locations = array_keys($framework->getLocations());
158
  $pattern = $locations ? '(' . implode('|', $locations) . ')' : false;
159
  }
160
 
161
  return $pattern ? : '(\w+)';
162
  }
 
 
 
 
 
 
 
 
 
 
163
  }
1
  <?php
2
  namespace Composer\Installers;
3
 
4
+ use Composer\IO\IOInterface;
5
  use Composer\Installer\LibraryInstaller;
6
  use Composer\Package\PackageInterface;
7
  use Composer\Repository\InstalledRepositoryInterface;
19
  'agl' => 'AglInstaller',
20
  'annotatecms' => 'AnnotateCmsInstaller',
21
  'bitrix' => 'BitrixInstaller',
22
+ 'bonefish' => 'BonefishInstaller',
23
  'cakephp' => 'CakePHPInstaller',
24
  'chef' => 'ChefInstaller',
25
  'ccframework' => 'ClanCatsFrameworkInstaller',
37
  'hurad' => 'HuradInstaller',
38
  'joomla' => 'JoomlaInstaller',
39
  'kirby' => 'KirbyInstaller',
40
+ 'kodicms' => 'KodiCMSInstaller',
41
  'kohana' => 'KohanaInstaller',
42
  'laravel' => 'LaravelInstaller',
43
  'lithium' => 'LithiumInstaller',
70
  'wordpress' => 'WordPressInstaller',
71
  'zend' => 'ZendInstaller',
72
  'zikula' => 'ZikulaInstaller',
73
+ 'prestashop' => 'PrestashopInstaller'
74
  );
75
 
76
  /**
88
  }
89
 
90
  $class = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
91
+ $installer = new $class($package, $this->composer, $this->getIO());
92
 
93
  return $installer->getInstallPath($package, $frameworkType);
94
  }
156
  if (!empty($this->supportedTypes[$frameworkType])) {
157
  $frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
158
  /** @var BaseInstaller $framework */
159
+ $framework = new $frameworkClass(null, $this->composer, $this->getIO());
160
  $locations = array_keys($framework->getLocations());
161
  $pattern = $locations ? '(' . implode('|', $locations) . ')' : false;
162
  }
163
 
164
  return $pattern ? : '(\w+)';
165
  }
166
+
167
+ /**
168
+ * Get I/O object
169
+ *
170
+ * @return IOInterface
171
+ */
172
+ private function getIO()
173
+ {
174
+ return $this->io;
175
+ }
176
  }
vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class KodiCMSInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'plugin' => 'cms/plugins/{$name}/',
8
+ 'media' => 'cms/media/vendor/{$name}/'
9
+ );
10
+ }
vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php CHANGED
@@ -6,6 +6,7 @@ class MoodleInstaller extends BaseInstaller
6
  protected $locations = array(
7
  'mod' => 'mod/{$name}/',
8
  'admin_report' => 'admin/report/{$name}/',
 
9
  'tool' => 'admin/tool/{$name}/',
10
  'assignment' => 'mod/assignment/type/{$name}/',
11
  'assignsubmission' => 'mod/assign/submission/{$name}/',
@@ -13,6 +14,9 @@ class MoodleInstaller extends BaseInstaller
13
  'auth' => 'auth/{$name}/',
14
  'availability' => 'availability/condition/{$name}/',
15
  'block' => 'blocks/{$name}/',
 
 
 
16
  'calendartype' => 'calendar/type/{$name}/',
17
  'format' => 'course/format/{$name}/',
18
  'coursereport' => 'course/report/{$name}/',
@@ -26,7 +30,11 @@ class MoodleInstaller extends BaseInstaller
26
  'gradereport' => 'grade/report/{$name}/',
27
  'gradingform' => 'grade/grading/form/{$name}/',
28
  'local' => 'local/{$name}/',
 
 
 
29
  'message' => 'message/output/{$name}/',
 
30
  'plagiarism' => 'plagiarism/{$name}/',
31
  'portfolio' => 'portfolio/{$name}/',
32
  'qbehaviour' => 'question/behaviour/{$name}/',
@@ -38,6 +46,7 @@ class MoodleInstaller extends BaseInstaller
38
  'repository' => 'repository/{$name}/',
39
  'scormreport' => 'mod/scorm/report/{$name}/',
40
  'theme' => 'theme/{$name}/',
 
41
  'profilefield' => 'user/profile/field/{$name}/',
42
  'webservice' => 'webservice/{$name}/',
43
  'workshopallocation' => 'mod/workshop/allocation/{$name}/',
6
  protected $locations = array(
7
  'mod' => 'mod/{$name}/',
8
  'admin_report' => 'admin/report/{$name}/',
9
+ 'atto' => 'lib/editor/atto/plugins/{$name}/',
10
  'tool' => 'admin/tool/{$name}/',
11
  'assignment' => 'mod/assignment/type/{$name}/',
12
  'assignsubmission' => 'mod/assign/submission/{$name}/',
14
  'auth' => 'auth/{$name}/',
15
  'availability' => 'availability/condition/{$name}/',
16
  'block' => 'blocks/{$name}/',
17
+ 'booktool' => 'mod/book/tool/{$name}/',
18
+ 'cachestore' => 'cache/stores/{$name}/',
19
+ 'cachelock' => 'cache/locks/{$name}/',
20
  'calendartype' => 'calendar/type/{$name}/',
21
  'format' => 'course/format/{$name}/',
22
  'coursereport' => 'course/report/{$name}/',
30
  'gradereport' => 'grade/report/{$name}/',
31
  'gradingform' => 'grade/grading/form/{$name}/',
32
  'local' => 'local/{$name}/',
33
+ 'logstore' => 'admin/tool/log/store/{$name}/',
34
+ 'ltisource' => 'mod/lti/source/{$name}/',
35
+ 'ltiservice' => 'mod/lti/service/{$name}/',
36
  'message' => 'message/output/{$name}/',
37
+ 'mnetservice' => 'mnet/service/{$name}/',
38
  'plagiarism' => 'plagiarism/{$name}/',
39
  'portfolio' => 'portfolio/{$name}/',
40
  'qbehaviour' => 'question/behaviour/{$name}/',
46
  'repository' => 'repository/{$name}/',
47
  'scormreport' => 'mod/scorm/report/{$name}/',
48
  'theme' => 'theme/{$name}/',
49
+ 'tinymce' => 'lib/editor/tinymce/plugins/{$name}/',
50
  'profilefield' => 'user/profile/field/{$name}/',
51
  'webservice' => 'webservice/{$name}/',
52
  'workshopallocation' => 'mod/workshop/allocation/{$name}/',
vendor/composer/installers/src/Composer/Installers/Plugin.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Composer\Installers;
4
+
5
+ use Composer\Composer;
6
+ use Composer\IO\IOInterface;
7
+ use Composer\Plugin\PluginInterface;
8
+
9
+ class Plugin implements PluginInterface
10
+ {
11
+
12
+ public function activate(Composer $composer, IOInterface $io)
13
+ {
14
+ $installer = new Installer($io, $composer);
15
+ $composer->getInstallationManager()->addInstaller($installer);
16
+ }
17
+ }
vendor/kminh/bwp-framework/assets/option-page/css/less/bwp-tabs.less ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* For WordPress of older versions */
2
+ .nav-tab{
3
+ border-style:solid;
4
+ border-color:#ccc #ccc #f9f9f9;
5
+ border-width:1px 1px 0;
6
+ color:#c1c1c1;
7
+ text-shadow:rgba(255,255,255,1) 0 1px 0;
8
+ font-size:12px;
9
+ line-height:16px;
10
+ display:inline-block;
11
+ padding:4px 14px 6px;
12
+ text-decoration:none;
13
+ margin:0 3px -1px 0;
14
+ /* -moz-border-radius:5px 5px 0 0; */
15
+ /* -webkit-border-top-left-radius:5px; */
16
+ /* -webkit-border-top-right-radius:5px; */
17
+ /* -khtml-border-top-left-radius:5px; */
18
+ /* -khtml-border-top-right-radius:5px; */
19
+ /* border-top-left-radius:5px; */
20
+ /* border-top-right-radius:5px; */
21
+ }
22
+ .nav-tab-active{
23
+ border-width:1px;
24
+ border-bottom-color: transparent;
25
+ color: #000000;
26
+ }
27
+ h2.nav-tab-wrapper, h3.nav-tab-wrapper{
28
+ border-bottom:1px solid #ccc;
29
+ padding-bottom:0;
30
+ }
31
+ h2 .nav-tab{padding:6px 15px 6px;}
32
+
33
+ .wrap .bwp-option-page-tabs {
34
+ border-bottom: 1px solid #CCCCCC;
35
+ padding-bottom: 0px;
36
+ margin-bottom: 20px;
37
+ }
38
+
39
+ .bwp-option-page-tabs {
40
+ a {
41
+ font-size: 18px;
42
+ line-height: 24px;
43
+ font-style: italic;
44
+
45
+ &.version {
46
+ font-size: 14px;
47
+ line-height: 14px;
48
+ }
49
+ }
50
+ }
vendor/kminh/bwp-framework/assets/option-page/css/less/bwp.less CHANGED
@@ -1,326 +1,275 @@
1
- /* For WordPress of older versions */
2
- .nav-tab{
3
- border-style:solid;
4
- border-color:#ccc #ccc #f9f9f9;
5
- border-width:1px 1px 0;
6
- color:#c1c1c1;
7
- text-shadow:rgba(255,255,255,1) 0 1px 0;
8
- font-size:12px;
9
- line-height:16px;
10
- display:inline-block;
11
- padding:4px 14px 6px;
12
- text-decoration:none;
13
- margin:0 3px -1px 0;
14
- /* -moz-border-radius:5px 5px 0 0; */
15
- /* -webkit-border-top-left-radius:5px; */
16
- /* -webkit-border-top-right-radius:5px; */
17
- /* -khtml-border-top-left-radius:5px; */
18
- /* -khtml-border-top-right-radius:5px; */
19
- /* border-top-left-radius:5px; */
20
- /* border-top-right-radius:5px; */
21
- }
22
- .nav-tab-active{
23
- border-width:1px;
24
- border-bottom-color: transparent;
25
- color: #000000;
26
- }
27
- h2.nav-tab-wrapper, h3.nav-tab-wrapper{
28
- border-bottom:1px solid #ccc;
29
- padding-bottom:0;
30
- }
31
- h2 .nav-tab{padding:6px 15px 6px;}
32
-
33
- .bwp-option-page {
34
- margin-top: 1em;
35
- }
36
-
37
- /*--- Common ---*/
38
- .bwp-option-page h4 {
39
- font-size: 1em;
40
- margin: 1em 0;
41
- }
42
-
43
- .bwp-option-page p {
44
- margin-top: 0px;
45
- margin-bottom: 0px;
46
- zoom: 1;
47
- }
48
-
49
- .bwp-option-page .bwp-paragraph {
50
- margin: 1em 0;
51
- }
52
-
53
- .bwp-option-page li.bwp-clear, .bwp-option-page div.bwp-clear {
54
- clear: left;
55
- /* display: block; */
56
- margin: 1em 0 0 0;
57
- zoom: 1;
58
- }
59
-
60
- .bwp-option-page p.submit {
61
- /* clear: both; */
62
- padding-top: 1.5em;
63
- }
64
-
65
- .wrap .bwp-option-page-tabs {
66
- border-bottom: 1px solid #CCCCCC;
67
- padding-bottom: 0px;
68
- margin-bottom: 20px;
69
- }
70
-
71
- .bwp-option-page-tabs a {
72
- font-size: 18px;
73
- line-height: 24px;
74
- font-style: italic;
75
- }
76
-
77
- .bwp-option-page-tabs a.version {
78
- font-size: 14px;
79
- line-height: 14px;
80
- }
81
-
82
- .bwp-opton-page-label {
83
- display: block;
84
- float: left;
85
- width: 200px;
86
- margin: 5px 0 1em 0;
87
- }
88
-
89
- .type-checkbox {
90
- margin-top: 0px;
91
- }
92
-
93
- p.bwp-option-page-inputs {
94
- margin: 0 0 0 220px;
95
- padding: 0;
96
- }
97
-
98
- .bwp-option-page-inputs input[type="text"], .bwp-option-page-inputs select {
99
- margin: 0 0 5px 0;
100
- }
101
-
102
- .bwp-option-page-inputs label {
103
- margin: 0;
104
- }
105
-
106
- .bwp-option-page-inputs select {
107
- /* margin: 1px 0 0 0; */
108
- }
109
-
110
- .bwp-option-page-inputs input[type="checkbox"] {
111
- margin-left: 2px;
112
- }
113
-
114
- .bwp-no-display {
115
- display: none;
116
- }
117
-
118
- .bwp-hidden {
119
- visibility: hidden;
120
- }
121
- /*--- End Common ---*/
122
-
123
- /*--- Button ---*/
124
- .wp-core-ui .button-inline {
125
- vertical-align: middle;
126
- }
127
-
128
- .bwp-button {
129
- .dashicons {
130
- width: auto;
131
- height: 14px;
132
- font-size: 14px;
133
- vertical-align: middle;
134
- }
135
- }
136
- /*--- End Button ---*/
137
-
138
- /*--- Table ---*/
139
- .bwp-table-md {
140
- width: 50%;
141
- }
142
-
143
- .bwp-table-lg {
144
- width: 70%;
145
- }
146
-
147
- .bwp-table-inline {
148
- clear: none;
149
- }
150
-
151
- table.dataTable.no-footer {
152
- border-bottom: 1px solid #e1e1e1;
153
- }
154
-
155
- .bwp-table th,
156
- .bwp-table td,
157
- table.dataTable tbody th,
158
- table.dataTable tbody td,
159
- table.dataTable thead th,
160
- table.dataTable thead td {
161
- font-size: 13px;
162
- padding: 5px 10px;
163
- }
164
-
165
- table.dataTable thead th,
166
- table.dataTable tfoot th {
167
- font-weight: 600;
168
- }
169
-
170
- .bwp-table-fixed-headers thead tr {
171
- display: block;
172
- position: relative;
173
- }
174
-
175
- .bwp-table-fixed-headers tbody {
176
- display: block;
177
- overflow: auto;
178
- width: 100%;
179
- max-height: 297px;
180
- }
181
-
182
- .bwp-table-fixed-headers td.ordinal,
183
- .bwp-table-fixed-headers th.ordinal {
184
- min-width: 30px;
185
- }
186
-
187
- .bwp-table-fixed-headers-old-id-wrapper {
188
- width: 50%;
189
- max-height: 297px;
190
- overflow-x: hidden;
191
- overflow-y: auto;
192
- }
193
-
194
- .bwp-table-fixed-headers-old-id-wrapper tbody {
195
- height: auto;
196
- }
197
-
198
- table.dataTable thead th,
199
- table.dataTable thead td {
200
- border-bottom: 1px solid #e1e1e1;
201
- }
202
-
203
- table.dataTable, table.dataTable th, table.dataTable td {
204
- box-sizing: border-box;
205
- }
206
-
207
- .dataTables_wrapper table.dataTable,
208
- .dataTables_wrapper .dataTables_filter,
209
- .dataTables_wrapper .dataTables_length,
210
- .dataTables_wrapper .dataTables_info,
211
- .dataTables_wrapper .dataTables_paginate {
212
- color: #444;
213
- }
214
-
215
- .dataTables_length {
216
- margin-bottom: 1em;
217
- }
218
-
219
- .dataTables_wrapper .dataTables_info {
220
- font-weight: 600;
221
- }
222
-
223
- .dataTables_wrapper .dataTables_paginate .paginate_button {
224
- border: none;
225
- color: #0073aa !important;
226
- }
227
-
228
- .dataTables_wrapper .dataTables_paginate .paginate_button:hover {
229
- background: none;
230
- border: none;
231
- color: #00a0d2 !important;
232
- }
233
-
234
- .dataTables_wrapper .dataTables_paginate .paginate_button:active {
235
- background: none;
236
- box-shadow: none;
237
- color: #00a0d2 !important;
238
- }
239
-
240
- .dataTables_wrapper .dataTables_paginate .paginate_button.disabled,
241
- .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,
242
- .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active {
243
- border: none;
244
- }
245
-
246
- .dataTables_wrapper .dataTables_paginate .paginate_button.current,
247
- .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
248
- background: none;
249
- border: none;
250
- color: #444 !important;
251
- }
252
- /*--- End Table ---*/
253
-
254
- #icon-betterwp-net {
255
- background: url("betterwp.jpg") no-repeat transparent;
256
- border: 1px solid #E3E3E3;
257
- height: 32px;
258
- width: 32px;
259
- }
260
-
261
- #icon-bwp-plugin {
262
- background-repeat: no-repeat;
263
- background-position: left center;
264
- margin-top: 21px; margin-left: 5px;
265
- width: 36px;
266
- }
267
-
268
- #bwp-info-place {
269
- float: right;
270
- margin: 0 0 10px 10px;
271
- }
272
-
273
- #bwp-donation, #bwp-contact, #bwp-ads {
274
- width: 255px;
275
- padding: 7px; padding-bottom: 0px;
276
- background-color: #ffffff;
277
- border: 1px solid #cccccc;
278
- text-align: center;
279
- }
280
-
281
- #bwp-donation p, #bwp-ads p {
282
- margin: 0.5em 0 1em 0;
283
- }
284
-
285
- #bwp-ads {
286
- padding-bottom: 5px;
287
- }
288
-
289
- #bwp-ads p {
290
- text-decoration: underline;
291
- }
292
-
293
- #bwp-info-place small {
294
- font-size: 0.8em;
295
- }
296
-
297
- #bwp-donation .paypal-submit {
298
- vertical-align: bottom;
299
- display: inline-block;
300
- margin: 0 0 1px 2px;
301
- padding: 0px;
302
- }
303
-
304
- .bwp-separator {
305
- width: 271px;
306
- }
307
-
308
- #bwp-contact {
309
- text-align: left;
310
- padding: 7px;
311
- }
312
-
313
- #bwp-contact a {
314
- display: block;
315
- height: 20px;
316
- font-size: 0.8em;
317
- padding-left: 25px;
318
- }
319
-
320
- #bwp-contact .bwp-rss {
321
- background: transparent url("../images/icon-rss.png") no-repeat left center;
322
- }
323
-
324
- #bwp-contact .bwp-twitter {
325
- background: transparent url("../images/icon-twitter.png") no-repeat left center;
326
- }
1
+ /*--- Common ---*/
2
+ .bwp-option-page {
3
+ margin-top: 1em;
4
+ padding-bottom: 1em;
5
+
6
+ h4 {
7
+ font-size: 1.1em;
8
+ margin: 1em 0;
9
+ }
10
+
11
+ p {
12
+ margin-top: 0px;
13
+ margin-bottom: 0px;
14
+ zoom: 1;
15
+ }
16
+
17
+ .bwp-paragraph {
18
+ margin: 1em 0;
19
+ }
20
+
21
+ li.bwp-clear, div.bwp-clear {
22
+ clear: left;
23
+ margin: 1em 0 0 0;
24
+ zoom: 1;
25
+ }
26
+
27
+ div.bwp-clear {
28
+ margin-bottom: 1.7em;
29
+ }
30
+ }
31
+
32
+ .bwp-no-display {
33
+ display: none;
34
+ }
35
+
36
+ .bwp-hidden {
37
+ visibility: hidden;
38
+ }
39
+
40
+ .bwp-meta {
41
+ color: #999;
42
+ }
43
+
44
+ .bwp-justin {
45
+ display: inline-block;
46
+ position: relative;
47
+ bottom: 0.5em;
48
+ font-size: 0.85em;
49
+ font-weight: 600;
50
+ color: #f26522;
51
+ }
52
+ /*--- End Common ---*/
53
+
54
+ /*--- Main ---*/
55
+ .bwp-wrap {
56
+ clear: both;
57
+ }
58
+
59
+ #bwp-main {
60
+ width: auto;
61
+ overflow: hidden;
62
+
63
+ .updated, .error {
64
+ margin-top: 15px;
65
+ margin-bottom: 0;
66
+
67
+ &.first {
68
+ margin-top: 20px;
69
+ }
70
+ }
71
+ }
72
+ /*--- End Main ---*/
73
+
74
+ /*--- Header ---*/
75
+ #bwp-header {
76
+ margin-bottom: 15px;
77
+ padding-top: 5px;
78
+
79
+ h1 {
80
+ padding: 0;
81
+ margin-top: 0;
82
+ margin-bottom: 15px;
83
+
84
+ color: #32373c;
85
+ font-size: 2em;
86
+ font-weight: 400;
87
+ line-height: 1.2em;
88
+ }
89
+ }
90
+
91
+ #bwp-donation {
92
+ display: none;
93
+ }
94
+
95
+ #bwp-get-social {
96
+ max-width: 450px;
97
+ margin-top: 15px;
98
+ margin-bottom: 0;
99
+
100
+ overflow: hidden;
101
+
102
+ .inside {
103
+ padding-bottom: 0;
104
+ }
105
+
106
+ h2 {
107
+ cursor: default;
108
+ font-size: 14px;
109
+ line-height: 1.4;
110
+ margin: 0;
111
+ padding: 8px 12px;
112
+ }
113
+ }
114
+
115
+ #bwp-social-buttons {
116
+ height: 20px;
117
+ padding-top: 3px;
118
+
119
+ .bwp-twitter-buttons, .bwp-gplus-buttons, .bwp-fb-buttons {
120
+ float: left;
121
+ margin-right: 15px;
122
+ }
123
+
124
+ .bwp-fb-buttons {
125
+ // max-width: 100px;
126
+ }
127
+
128
+ .bwp-gplus-buttons {
129
+ max-width: 80px;
130
+ margin-right: 0;
131
+ }
132
+
133
+ .bwp-twitter-buttons {
134
+ // width: 230px;
135
+ }
136
+ }
137
+ /*--- End Header ---*/
138
+
139
+ /*--- Tabs ---*/
140
+ .bwp-option-page-tabs {
141
+ a {
142
+ padding-left: 15px;
143
+ padding-right: 15px;
144
+
145
+ color: #c1c1c1;
146
+ font-size: 18px;
147
+ font-weight: 600;
148
+ }
149
+
150
+ a.nav-tab-active {
151
+ color: #000;
152
+ }
153
+ }
154
+
155
+ .wrap .bwp-option-page-tabs {
156
+ padding-left: 6px;
157
+ }
158
+ /*--- End Tabs ---*/
159
+
160
+ /*--- Button ---*/
161
+ .wp-core-ui .button-inline {
162
+ vertical-align: middle;
163
+ }
164
+
165
+ .bwp-button {
166
+ .dashicons {
167
+ width: auto;
168
+ height: 18px;
169
+ font-size: 14px;
170
+ vertical-align: middle;
171
+ }
172
+ }
173
+
174
+ .bwp-button-paypal {
175
+ .bwp-mixin-button(#003580; #ffe3b7; #ffc975) !important;
176
+
177
+ font-weight: 600;
178
+
179
+ .paypal-pay, .paypal-pal {
180
+ font-weight: bold;
181
+ font-style: italic;
182
+ }
183
+
184
+ .paypal-pay {
185
+ color: #003580;
186
+ }
187
+
188
+ .paypal-pal {
189
+ color: #009DD8;
190
+ }
191
+ }
192
+ /*--- End Button ---*/
193
+
194
+ /*--- Sidebars ---*/
195
+ #bwp-sidebar-right {
196
+ width: 276px;
197
+ margin: 0 0 10px 20px;
198
+ float: right;
199
+
200
+ .postbox {
201
+ .inside {
202
+ max-width: 250px;
203
+
204
+ padding-bottom: 0;
205
+
206
+ line-height: 1;
207
+ }
208
+
209
+ .hndle {
210
+ margin: 0;
211
+ padding: 8px 12px;
212
+
213
+ font-size: 14px;
214
+ line-height: 1.4;
215
+
216
+ cursor: default;
217
+ }
218
+ }
219
+ }
220
+
221
+ #bwp-ads {
222
+ margin-top: 10px;
223
+
224
+ a {
225
+ line-height: 1;
226
+ }
227
+ }
228
+
229
+ #bwp-news {
230
+ a {
231
+ margin-right: 5px;
232
+ }
233
+ }
234
+
235
+ .bwp-button-rss {
236
+ .bwp-mixin-button(#fff; @brand-color-rss) !important;
237
+ }
238
+
239
+ .bwp-button-twitter {
240
+ .bwp-mixin-button(#fff; @brand-color-twitter) !important;
241
+ }
242
+
243
+ .bwp-feed {
244
+ list-style: outside none none;
245
+ margin: 0;
246
+ padding: 0;
247
+
248
+ li {
249
+ margin-bottom: 8px;
250
+ line-height: 1.5em;
251
+ }
252
+
253
+ a {
254
+ font-size: 13px;
255
+ font-weight: 400;
256
+ text-decoration: none;
257
+ }
258
+ }
259
+
260
+ .bwp-feed-buttons {
261
+ padding: 12px;
262
+
263
+ background-color: #fafafa;
264
+ border-top: 1px solid #eee;
265
+ }
266
+ /*--- End Sidebars ---*/
267
+
268
+ /*--- Icons ---*/
269
+ #icon-bwp-plugin {
270
+ background-repeat: no-repeat;
271
+ background-position: left center;
272
+ margin-top: 21px; margin-left: 5px;
273
+ width: 36px;
274
+ }
275
+ /*--- End Icons ---*/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/kminh/bwp-framework/assets/option-page/css/less/codemirror.less ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .CodeMirror {
2
+ border: 1px solid #ddd;
3
+ height: auto;
4
+ .vendor(box-shadow, 0 1px 2px rgba(0, 0, 0, 0.07) inset);
5
+
6
+ font-size: 12px;
7
+ }
8
+
9
+ .CodeMirror-readonly {
10
+ // border: 1px solid #e1e1e1;
11
+ background-color: #eee !important;
12
+ }
13
+
14
+ .CodeMirror-scroll {
15
+ max-height: 200px;
16
+ }
17
+
18
+ .CodeMirror-lines {
19
+ padding: 4px;
20
+ }
21
+
22
+ .bwp-code-editor-large + .CodeMirror .CodeMirror-scroll {
23
+ max-height: 300px;
24
+ }
25
+
26
+ .bwp-option-page-inputs {
27
+ .CodeMirror, .bwp-code-editor {
28
+ margin: 1.3em 0 1.7em 0;
29
+ }
30
+ }
31
+
32
+ .CodeMirror, .bwp-code-editor {
33
+ & + .bwp-form-help-block {
34
+ margin-top: unit(-1.7/2, em);
35
+ margin-bottom: 1.2em;
36
+ }
37
+
38
+ pre.CodeMirror-placeholder {
39
+ color: #999;
40
+ }
41
+ }
vendor/kminh/bwp-framework/assets/option-page/css/less/form.less CHANGED
@@ -1,5 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  .bwp-inline-form-wrapper-lg {
2
- max-width: 70%;
3
  }
4
 
5
  .bwp-inline-form-wrapper-md {
@@ -114,9 +134,52 @@
114
  // pointer-events: none;
115
  }
116
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  .bwp-form-help-block {
118
  display: block;
119
- margin: 1em 0;
120
  color: lighten(@text-color, 25%);
121
  }
122
 
@@ -162,3 +225,8 @@ select, input[type="text"], textarea {
162
  margin-bottom: 5px;
163
  }
164
  }
 
 
 
 
 
1
+ .bwp-option-page {
2
+ p.submit {
3
+ clear: left;
4
+ margin-top: 2em;
5
+ padding-top: 0;
6
+
7
+ button, input {
8
+ margin-right: 0.3em;
9
+ }
10
+ }
11
+ }
12
+
13
+ .bwp-fields {
14
+ margin: 0;
15
+ }
16
+
17
+ .bwp-inline-form-wrapper-full {
18
+ max-width: 100%;
19
+ }
20
+
21
  .bwp-inline-form-wrapper-lg {
22
+ max-width: 75%;
23
  }
24
 
25
  .bwp-inline-form-wrapper-md {
134
  // pointer-events: none;
135
  }
136
 
137
+ .bwp-opton-page-label {
138
+ display: block;
139
+ float: left;
140
+ width: 200px;
141
+ margin: 3px 0 1em 0;
142
+ }
143
+
144
+ .type-checkbox {
145
+ margin-top: 3px;
146
+ margin-bottom: 1.5em;
147
+ }
148
+
149
+ .type-input {
150
+ margin-top: 5px;
151
+ }
152
+
153
+ .type-select {
154
+ margin-top: 6px;
155
+ }
156
+
157
+ p.bwp-option-page-inputs {
158
+ margin: 0 0 0 220px;
159
+ padding: 0;
160
+ }
161
+
162
+ .bwp-option-page-inputs {
163
+ input[type="text"], select {
164
+ margin: 0 0 5px 0;
165
+ }
166
+
167
+ label {
168
+ margin: 0;
169
+ }
170
+
171
+ select {
172
+ /* margin: 1px 0 0 0; */
173
+ }
174
+
175
+ input[type="checkbox"] {
176
+ // margin-left: 2px;
177
+ }
178
+ }
179
+
180
  .bwp-form-help-block {
181
  display: block;
182
+ margin: -0.5em 0 1em 0;
183
  color: lighten(@text-color, 25%);
184
  }
185
 
225
  margin-bottom: 5px;
226
  }
227
  }
228
+
229
+ .bwp-code-editor {
230
+ display: block;
231
+ max-height: 200px;
232
+ }
vendor/kminh/bwp-framework/assets/option-page/css/less/mixins.less ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .vendor(@property, @value) {
2
+ -webkit-@{property}: @value;
3
+ -khtml-@{property}: @value;
4
+ -moz-@{property}: @value;
5
+ @{property}: @value;
6
+ }
7
+
8
+ .bwp-mixin-button(@color; @bgcolor; @bordercolor:'') {
9
+ color: @color;
10
+ text-shadow: 0px 1px 1px darken(@bgcolor, 10%);
11
+ background: @bgcolor none repeat scroll 0 0;
12
+
13
+ border-color: darken(@bgcolor, 10%);
14
+ box-shadow: 0 1px 0 darken(@bgcolor, 10%);
15
+
16
+ & when (iscolor(@bordercolor)) {
17
+ border-color: @bordercolor;
18
+ box-shadow: 0 1px 0 @bordercolor;
19
+ }
20
+
21
+ &:hover, &:active {
22
+ background: lighten(@bgcolor, 3%) none repeat scroll 0 0;
23
+ border-color: darken(@bgcolor, 15%);
24
+
25
+ & when (iscolor(@bordercolor)) {
26
+ border-color: darken(@bordercolor, 10%);
27
+ }
28
+ }
29
+
30
+ &:active {
31
+ box-shadow: 0 2px 5px -3px fade(darken(@bgcolor, 50%), 50%) inset;
32
+ }
33
+ }
vendor/kminh/bwp-framework/assets/option-page/css/less/modal.less CHANGED
@@ -5,18 +5,6 @@
5
  }
6
  }
7
 
8
- .bwp-modal-dialog {
9
- padding-top: 7%;
10
-
11
- &.bwp-modal-lg {
12
- padding-top: 0;
13
- }
14
-
15
- &.bwp-modal-sm {
16
- padding-top: 17%;
17
- }
18
- }
19
-
20
  .bwp-modal-sm {
21
  width: 350px;
22
  }
5
  }
6
  }
7
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  .bwp-modal-sm {
9
  width: 350px;
10
  }
vendor/kminh/bwp-framework/assets/option-page/css/less/style.less CHANGED
@@ -1,6 +1,10 @@
 
 
1
  @import "bootstrap.less";
2
  @import "bwp.less";
 
3
  @import "form.less";
4
  @import "modal.less";
5
  @import "popover.less";
6
  @import "datetimepicker.less";
 
1
+ @import "variables.less";
2
+ @import "mixins.less";
3
  @import "bootstrap.less";
4
  @import "bwp.less";
5
+ @import "table.less";
6
  @import "form.less";
7
  @import "modal.less";
8
  @import "popover.less";
9
  @import "datetimepicker.less";
10
+ @import "codemirror.less";
vendor/kminh/bwp-framework/assets/option-page/css/less/table.less ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .bwp-table-md {
2
+ width: 50%;
3
+ }
4
+
5
+ .bwp-table-full {
6
+ width: 100%;
7
+ }
8
+
9
+ .bwp-table-lg {
10
+ width: 75%;
11
+ }
12
+
13
+ .bwp-table-inline {
14
+ clear: none;
15
+ }
16
+
17
+ table.dataTable {
18
+ clear: left;
19
+ }
20
+
21
+ table.dataTable.no-footer {
22
+ border-bottom: 1px solid #e1e1e1;
23
+ }
24
+
25
+ .bwp-table th,
26
+ .bwp-table td,
27
+ table.dataTable tbody th,
28
+ table.dataTable tbody td,
29
+ table.dataTable thead th,
30
+ table.dataTable thead td {
31
+ font-size: 13px;
32
+ padding: 5px 10px;
33
+ }
34
+
35
+ table.dataTable thead th,
36
+ table.dataTable tfoot th {
37
+ font-weight: 600;
38
+ }
39
+
40
+ .bwp-table-fixed-headers thead tr {
41
+ display: block;
42
+ position: relative;
43
+ }
44
+
45
+ .bwp-table-fixed-headers tbody {
46
+ display: block;
47
+ overflow: auto;
48
+ width: 100%;
49
+ max-height: 297px;
50
+ }
51
+
52
+ .bwp-table-fixed-headers td.ordinal,
53
+ .bwp-table-fixed-headers th.ordinal {
54
+ min-width: 30px;
55
+ }
56
+
57
+ .bwp-table-fixed-headers-old-id-wrapper {
58
+ width: 50%;
59
+ max-height: 297px;
60
+ overflow-x: hidden;
61
+ overflow-y: auto;
62
+ }
63
+
64
+ .bwp-table-fixed-headers-old-id-wrapper tbody {
65
+ height: auto;
66
+ }
67
+
68
+ .bwp-table-valign-middle td {
69
+ vertical-align: middle;
70
+ }
71
+
72
+ table.dataTable thead th,
73
+ table.dataTable thead td {
74
+ border-bottom: 1px solid #e1e1e1;
75
+ }
76
+
77
+ table.dataTable, table.dataTable th, table.dataTable td {
78
+ box-sizing: border-box;
79
+ }
80
+
81
+ .dataTables_wrapper table.dataTable,
82
+ .dataTables_wrapper .dataTables_filter,
83
+ .dataTables_wrapper .dataTables_length,
84
+ .dataTables_wrapper .dataTables_info,
85
+ .dataTables_wrapper .dataTables_paginate {
86
+ color: #444;
87
+ }
88
+
89
+ .dataTables_wrapper {
90
+ .dataTables_filter {
91
+ input {
92
+ margin-right: 0;
93
+ }
94
+ }
95
+ }
96
+
97
+ .dataTables_length {
98
+ margin-bottom: 1em;
99
+ }
100
+
101
+ .dataTables_wrapper {
102
+ clear: left;
103
+ }
104
+
105
+ .dataTables_wrapper .dataTables_info {
106
+ font-weight: 600;
107
+ }
108
+
109
+ .dataTables_wrapper .dataTables_paginate .paginate_button {
110
+ border: none;
111
+ color: #0073aa !important;
112
+ }
113
+
114
+ .dataTables_wrapper .dataTables_paginate .paginate_button:hover {
115
+ background: none;
116
+ border: none;
117
+ color: #00a0d2 !important;
118
+ }
119
+
120
+ .dataTables_wrapper .dataTables_paginate .paginate_button:active {
121
+ background: none;
122
+ box-shadow: none;
123
+ color: #00a0d2 !important;
124
+ }
125
+
126
+ .dataTables_wrapper .dataTables_paginate .paginate_button.disabled,
127
+ .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,
128
+ .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active {
129
+ border: none;
130
+ }
131
+
132
+ .dataTables_wrapper .dataTables_paginate .paginate_button.current,
133
+ .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
134
+ background: none;
135
+ border: none;
136
+ color: #444 !important;
137
+ }
vendor/kminh/bwp-framework/assets/option-page/css/less/variables.less ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ @brand-color-twitter: rgb(85,172,238);
2
+ @brand-color-rss: rgb(242,101,34);
3
+ @brand-color-paypal-pay: rgb(0, 53, 128);
4
+ @brand-color-paypal-pal: rgb(0, 157, 216);
5
+ @brand-color-paypal-bg: rgb(255, 221, 168);
vendor/kminh/bwp-framework/assets/option-page/css/style.css CHANGED
@@ -566,46 +566,13 @@ a.bg-danger:hover,
566
  a.bg-danger:focus {
567
  background-color: #e4b9b9;
568
  }
569
- /* For WordPress of older versions */
570
- .nav-tab {
571
- border-style: solid;
572
- border-color: #ccc #ccc #f9f9f9;
573
- border-width: 1px 1px 0;
574
- color: #c1c1c1;
575
- text-shadow: #ffffff 0 1px 0;
576
- font-size: 12px;
577
- line-height: 16px;
578
- display: inline-block;
579
- padding: 4px 14px 6px;
580
- text-decoration: none;
581
- margin: 0 3px -1px 0;
582
- /* -moz-border-radius:5px 5px 0 0; */
583
- /* -webkit-border-top-left-radius:5px; */
584
- /* -webkit-border-top-right-radius:5px; */
585
- /* -khtml-border-top-left-radius:5px; */
586
- /* -khtml-border-top-right-radius:5px; */
587
- /* border-top-left-radius:5px; */
588
- /* border-top-right-radius:5px; */
589
- }
590
- .nav-tab-active {
591
- border-width: 1px;
592
- border-bottom-color: transparent;
593
- color: #000000;
594
- }
595
- h2.nav-tab-wrapper,
596
- h3.nav-tab-wrapper {
597
- border-bottom: 1px solid #ccc;
598
- padding-bottom: 0;
599
- }
600
- h2 .nav-tab {
601
- padding: 6px 15px 6px;
602
- }
603
  .bwp-option-page {
604
  margin-top: 1em;
 
605
  }
606
- /*--- Common ---*/
607
  .bwp-option-page h4 {
608
- font-size: 1em;
609
  margin: 1em 0;
610
  }
611
  .bwp-option-page p {
@@ -619,82 +586,252 @@ h2 .nav-tab {
619
  .bwp-option-page li.bwp-clear,
620
  .bwp-option-page div.bwp-clear {
621
  clear: left;
622
- /* display: block; */
623
  margin: 1em 0 0 0;
624
  zoom: 1;
625
  }
626
- .bwp-option-page p.submit {
627
- /* clear: both; */
628
- padding-top: 1.5em;
629
  }
630
- .wrap .bwp-option-page-tabs {
631
- border-bottom: 1px solid #CCCCCC;
632
- padding-bottom: 0px;
633
- margin-bottom: 20px;
634
  }
635
- .bwp-option-page-tabs a {
636
- font-size: 18px;
637
- line-height: 24px;
638
- font-style: italic;
639
  }
640
- .bwp-option-page-tabs a.version {
641
- font-size: 14px;
642
- line-height: 14px;
643
  }
644
- .bwp-opton-page-label {
645
- display: block;
646
- float: left;
647
- width: 200px;
648
- margin: 5px 0 1em 0;
 
 
649
  }
650
- .type-checkbox {
651
- margin-top: 0px;
 
 
652
  }
653
- p.bwp-option-page-inputs {
654
- margin: 0 0 0 220px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
655
  padding: 0;
 
 
 
 
 
 
656
  }
657
- .bwp-option-page-inputs input[type="text"],
658
- .bwp-option-page-inputs select {
659
- margin: 0 0 5px 0;
660
  }
661
- .bwp-option-page-inputs label {
 
 
 
 
 
 
 
 
 
 
 
 
662
  margin: 0;
 
663
  }
664
- .bwp-option-page-inputs select {
665
- /* margin: 1px 0 0 0; */
 
666
  }
667
- .bwp-option-page-inputs input[type="checkbox"] {
668
- margin-left: 2px;
 
 
 
669
  }
670
- .bwp-no-display {
671
- display: none;
 
672
  }
673
- .bwp-hidden {
674
- visibility: hidden;
 
 
 
 
 
 
675
  }
676
- /*--- End Common ---*/
 
 
 
 
 
 
677
  /*--- Button ---*/
678
  .wp-core-ui .button-inline {
679
  vertical-align: middle;
680
  }
681
  .bwp-button .dashicons {
682
  width: auto;
683
- height: 14px;
684
  font-size: 14px;
685
  vertical-align: middle;
686
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
687
  /*--- End Button ---*/
688
- /*--- Table ---*/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
689
  .bwp-table-md {
690
  width: 50%;
691
  }
 
 
 
692
  .bwp-table-lg {
693
- width: 70%;
694
  }
695
  .bwp-table-inline {
696
  clear: none;
697
  }
 
 
 
698
  table.dataTable.no-footer {
699
  border-bottom: 1px solid #e1e1e1;
700
  }
@@ -734,6 +871,9 @@ table.dataTable tfoot th {
734
  .bwp-table-fixed-headers-old-id-wrapper tbody {
735
  height: auto;
736
  }
 
 
 
737
  table.dataTable thead th,
738
  table.dataTable thead td {
739
  border-bottom: 1px solid #e1e1e1;
@@ -750,9 +890,15 @@ table.dataTable td {
750
  .dataTables_wrapper .dataTables_paginate {
751
  color: #444;
752
  }
 
 
 
753
  .dataTables_length {
754
  margin-bottom: 1em;
755
  }
 
 
 
756
  .dataTables_wrapper .dataTables_info {
757
  font-weight: 600;
758
  }
@@ -781,74 +927,23 @@ table.dataTable td {
781
  border: none;
782
  color: #444 !important;
783
  }
784
- /*--- End Table ---*/
785
- #icon-betterwp-net {
786
- background: url("betterwp.jpg") no-repeat transparent;
787
- border: 1px solid #E3E3E3;
788
- height: 32px;
789
- width: 32px;
790
- }
791
- #icon-bwp-plugin {
792
- background-repeat: no-repeat;
793
- background-position: left center;
794
- margin-top: 21px;
795
- margin-left: 5px;
796
- width: 36px;
797
- }
798
- #bwp-info-place {
799
- float: right;
800
- margin: 0 0 10px 10px;
801
- }
802
- #bwp-donation,
803
- #bwp-contact,
804
- #bwp-ads {
805
- width: 255px;
806
- padding: 7px;
807
- padding-bottom: 0px;
808
- background-color: #ffffff;
809
- border: 1px solid #cccccc;
810
- text-align: center;
811
- }
812
- #bwp-donation p,
813
- #bwp-ads p {
814
- margin: 0.5em 0 1em 0;
815
- }
816
- #bwp-ads {
817
- padding-bottom: 5px;
818
- }
819
- #bwp-ads p {
820
- text-decoration: underline;
821
- }
822
- #bwp-info-place small {
823
- font-size: 0.8em;
824
- }
825
- #bwp-donation .paypal-submit {
826
- vertical-align: bottom;
827
- display: inline-block;
828
- margin: 0 0 1px 2px;
829
- padding: 0px;
830
- }
831
- .bwp-separator {
832
- width: 271px;
833
- }
834
- #bwp-contact {
835
- text-align: left;
836
- padding: 7px;
837
  }
838
- #bwp-contact a {
839
- display: block;
840
- height: 20px;
841
- font-size: 0.8em;
842
- padding-left: 25px;
843
  }
844
- #bwp-contact .bwp-rss {
845
- background: transparent url("../images/icon-rss.png") no-repeat left center;
846
  }
847
- #bwp-contact .bwp-twitter {
848
- background: transparent url("../images/icon-twitter.png") no-repeat left center;
849
  }
850
  .bwp-inline-form-wrapper-lg {
851
- max-width: 70%;
852
  }
853
  .bwp-inline-form-wrapper-md {
854
  max-width: 50%;
@@ -929,9 +1024,39 @@ table.dataTable td {
929
  line-height: 20px;
930
  cursor: pointer;
931
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
932
  .bwp-form-help-block {
933
  display: block;
934
- margin: 1em 0;
935
  color: #737373;
936
  }
937
  .bwp-form-help-block-first {
@@ -968,19 +1093,14 @@ textarea + .bwp-field-help-link span {
968
  display: inline-block;
969
  margin-bottom: 5px;
970
  }
 
 
 
 
971
  .bwp-modal-header h4 {
972
  margin: 0;
973
  font-size: 1.1em;
974
  }
975
- .bwp-modal-dialog {
976
- padding-top: 7%;
977
- }
978
- .bwp-modal-dialog.bwp-modal-lg {
979
- padding-top: 0;
980
- }
981
- .bwp-modal-dialog.bwp-modal-sm {
982
- padding-top: 17%;
983
- }
984
  .bwp-modal-sm {
985
  width: 350px;
986
  }
@@ -1054,4 +1174,38 @@ textarea + .bwp-field-help-link span {
1054
  .ui-datepicker-trigger {
1055
  display: none;
1056
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1057
  /*# sourceMappingURL=style.css.map */
566
  a.bg-danger:focus {
567
  background-color: #e4b9b9;
568
  }
569
+ /*--- Common ---*/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
570
  .bwp-option-page {
571
  margin-top: 1em;
572
+ padding-bottom: 1em;
573
  }
 
574
  .bwp-option-page h4 {
575
+ font-size: 1.1em;
576
  margin: 1em 0;
577
  }
578
  .bwp-option-page p {
586
  .bwp-option-page li.bwp-clear,
587
  .bwp-option-page div.bwp-clear {
588
  clear: left;
 
589
  margin: 1em 0 0 0;
590
  zoom: 1;
591
  }
592
+ .bwp-option-page div.bwp-clear {
593
+ margin-bottom: 1.7em;
 
594
  }
595
+ .bwp-no-display {
596
+ display: none;
 
 
597
  }
598
+ .bwp-hidden {
599
+ visibility: hidden;
 
 
600
  }
601
+ .bwp-meta {
602
+ color: #999;
 
603
  }
604
+ .bwp-justin {
605
+ display: inline-block;
606
+ position: relative;
607
+ bottom: 0.5em;
608
+ font-size: 0.85em;
609
+ font-weight: 600;
610
+ color: #f26522;
611
  }
612
+ /*--- End Common ---*/
613
+ /*--- Main ---*/
614
+ .bwp-wrap {
615
+ clear: both;
616
  }
617
+ #bwp-main {
618
+ width: auto;
619
+ overflow: hidden;
620
+ }
621
+ #bwp-main .updated,
622
+ #bwp-main .error {
623
+ margin-top: 15px;
624
+ margin-bottom: 0;
625
+ }
626
+ #bwp-main .updated.first,
627
+ #bwp-main .error.first {
628
+ margin-top: 20px;
629
+ }
630
+ /*--- End Main ---*/
631
+ /*--- Header ---*/
632
+ #bwp-header {
633
+ margin-bottom: 15px;
634
+ padding-top: 5px;
635
+ }
636
+ #bwp-header h1 {
637
  padding: 0;
638
+ margin-top: 0;
639
+ margin-bottom: 15px;
640
+ color: #32373c;
641
+ font-size: 2em;
642
+ font-weight: 400;
643
+ line-height: 1.2em;
644
  }
645
+ #bwp-donation {
646
+ display: none;
 
647
  }
648
+ #bwp-get-social {
649
+ max-width: 450px;
650
+ margin-top: 15px;
651
+ margin-bottom: 0;
652
+ overflow: hidden;
653
+ }
654
+ #bwp-get-social .inside {
655
+ padding-bottom: 0;
656
+ }
657
+ #bwp-get-social h2 {
658
+ cursor: default;
659
+ font-size: 14px;
660
+ line-height: 1.4;
661
  margin: 0;
662
+ padding: 8px 12px;
663
  }
664
+ #bwp-social-buttons {
665
+ height: 20px;
666
+ padding-top: 3px;
667
  }
668
+ #bwp-social-buttons .bwp-twitter-buttons,
669
+ #bwp-social-buttons .bwp-gplus-buttons,
670
+ #bwp-social-buttons .bwp-fb-buttons {
671
+ float: left;
672
+ margin-right: 15px;
673
  }
674
+ #bwp-social-buttons .bwp-gplus-buttons {
675
+ max-width: 80px;
676
+ margin-right: 0;
677
  }
678
+ /*--- End Header ---*/
679
+ /*--- Tabs ---*/
680
+ .bwp-option-page-tabs a {
681
+ padding-left: 15px;
682
+ padding-right: 15px;
683
+ color: #c1c1c1;
684
+ font-size: 18px;
685
+ font-weight: 600;
686
  }
687
+ .bwp-option-page-tabs a.nav-tab-active {
688
+ color: #000;
689
+ }
690
+ .wrap .bwp-option-page-tabs {
691
+ padding-left: 6px;
692
+ }
693
+ /*--- End Tabs ---*/
694
  /*--- Button ---*/
695
  .wp-core-ui .button-inline {
696
  vertical-align: middle;
697
  }
698
  .bwp-button .dashicons {
699
  width: auto;
700
+ height: 18px;
701
  font-size: 14px;
702
  vertical-align: middle;
703
  }
704
+ .bwp-button-paypal {
705
+ color: #003580 !important;
706
+ text-shadow: 0px 1px 1px #ffcf84 !important;
707
+ background: #ffe3b7 none repeat scroll 0 0 !important;
708
+ border-color: #ffcf84 !important;
709
+ box-shadow: 0 1px 0 #ffcf84 !important;
710
+ border-color: #ffc975 !important;
711
+ box-shadow: 0 1px 0 #ffc975 !important;
712
+ font-weight: 600;
713
+ }
714
+ .bwp-button-paypal:hover,
715
+ .bwp-button-paypal:active {
716
+ background: #ffe9c6 none repeat scroll 0 0 !important;
717
+ border-color: #ffc56b !important;
718
+ border-color: #ffb542 !important;
719
+ }
720
+ .bwp-button-paypal:active {
721
+ box-shadow: 0 2px 5px -3px rgba(183, 112, 0, 0.5) inset !important;
722
+ }
723
+ .bwp-button-paypal .paypal-pay,
724
+ .bwp-button-paypal .paypal-pal {
725
+ font-weight: bold;
726
+ font-style: italic;
727
+ }
728
+ .bwp-button-paypal .paypal-pay {
729
+ color: #003580;
730
+ }
731
+ .bwp-button-paypal .paypal-pal {
732
+ color: #009DD8;
733
+ }
734
  /*--- End Button ---*/
735
+ /*--- Sidebars ---*/
736
+ #bwp-sidebar-right {
737
+ width: 276px;
738
+ margin: 0 0 10px 20px;
739
+ float: right;
740
+ }
741
+ #bwp-sidebar-right .postbox .inside {
742
+ max-width: 250px;
743
+ padding-bottom: 0;
744
+ line-height: 1;
745
+ }
746
+ #bwp-sidebar-right .postbox .hndle {
747
+ margin: 0;
748
+ padding: 8px 12px;
749
+ font-size: 14px;
750
+ line-height: 1.4;
751
+ cursor: default;
752
+ }
753
+ #bwp-ads {
754
+ margin-top: 10px;
755
+ }
756
+ #bwp-ads a {
757
+ line-height: 1;
758
+ }
759
+ #bwp-news a {
760
+ margin-right: 5px;
761
+ }
762
+ .bwp-button-rss {
763
+ color: #ffffff !important;
764
+ text-shadow: 0px 1px 1px #d44d0d !important;
765
+ background: #f26522 none repeat scroll 0 0 !important;
766
+ border-color: #d44d0d !important;
767
+ box-shadow: 0 1px 0 #d44d0d !important;
768
+ }
769
+ .bwp-button-rss:hover,
770
+ .bwp-button-rss:active {
771
+ background: #f36f30 none repeat scroll 0 0 !important;
772
+ border-color: #bc440b !important;
773
+ }
774
+ .bwp-button-rss:active {
775
+ box-shadow: 0 2px 5px -3px rgba(20, 7, 1, 0.5) inset !important;
776
+ }
777
+ .bwp-button-twitter {
778
+ color: #ffffff !important;
779
+ text-shadow: 0px 1px 1px #2795e9 !important;
780
+ background: #55acee none repeat scroll 0 0 !important;
781
+ border-color: #2795e9 !important;
782
+ box-shadow: 0 1px 0 #2795e9 !important;
783
+ }
784
+ .bwp-button-twitter:hover,
785
+ .bwp-button-twitter:active {
786
+ background: #63b3ef none repeat scroll 0 0 !important;
787
+ border-color: #1689e0 !important;
788
+ }
789
+ .bwp-button-twitter:active {
790
+ box-shadow: 0 2px 5px -3px rgba(6, 38, 62, 0.5) inset !important;
791
+ }
792
+ .bwp-feed {
793
+ list-style: outside none none;
794
+ margin: 0;
795
+ padding: 0;
796
+ }
797
+ .bwp-feed li {
798
+ margin-bottom: 8px;
799
+ line-height: 1.5em;
800
+ }
801
+ .bwp-feed a {
802
+ font-size: 13px;
803
+ font-weight: 400;
804
+ text-decoration: none;
805
+ }
806
+ .bwp-feed-buttons {
807
+ padding: 12px;
808
+ background-color: #fafafa;
809
+ border-top: 1px solid #eee;
810
+ }
811
+ /*--- End Sidebars ---*/
812
+ /*--- Icons ---*/
813
+ #icon-bwp-plugin {
814
+ background-repeat: no-repeat;
815
+ background-position: left center;
816
+ margin-top: 21px;
817
+ margin-left: 5px;
818
+ width: 36px;
819
+ }
820
  .bwp-table-md {
821
  width: 50%;
822
  }
823
+ .bwp-table-full {
824
+ width: 100%;
825
+ }
826
  .bwp-table-lg {
827
+ width: 75%;
828
  }
829
  .bwp-table-inline {
830
  clear: none;
831
  }
832
+ table.dataTable {
833
+ clear: left;
834
+ }
835
  table.dataTable.no-footer {
836
  border-bottom: 1px solid #e1e1e1;
837
  }
871
  .bwp-table-fixed-headers-old-id-wrapper tbody {
872
  height: auto;
873
  }
874
+ .bwp-table-valign-middle td {
875
+ vertical-align: middle;
876
+ }
877
  table.dataTable thead th,
878
  table.dataTable thead td {
879
  border-bottom: 1px solid #e1e1e1;
890
  .dataTables_wrapper .dataTables_paginate {
891
  color: #444;
892
  }
893
+ .dataTables_wrapper .dataTables_filter input {
894
+ margin-right: 0;
895
+ }
896
  .dataTables_length {
897
  margin-bottom: 1em;
898
  }
899
+ .dataTables_wrapper {
900
+ clear: left;
901
+ }
902
  .dataTables_wrapper .dataTables_info {
903
  font-weight: 600;
904
  }
927
  border: none;
928
  color: #444 !important;
929
  }
930
+ .bwp-option-page p.submit {
931
+ clear: left;
932
+ margin-top: 2em;
933
+ padding-top: 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
934
  }
935
+ .bwp-option-page p.submit button,
936
+ .bwp-option-page p.submit input {
937
+ margin-right: 0.3em;
 
 
938
  }
939
+ .bwp-fields {
940
+ margin: 0;
941
  }
942
+ .bwp-inline-form-wrapper-full {
943
+ max-width: 100%;
944
  }
945
  .bwp-inline-form-wrapper-lg {
946
+ max-width: 75%;
947
  }
948
  .bwp-inline-form-wrapper-md {
949
  max-width: 50%;
1024
  line-height: 20px;
1025
  cursor: pointer;
1026
  }
1027
+ .bwp-opton-page-label {
1028
+ display: block;
1029
+ float: left;
1030
+ width: 200px;
1031
+ margin: 3px 0 1em 0;
1032
+ }
1033
+ .type-checkbox {
1034
+ margin-top: 3px;
1035
+ margin-bottom: 1.5em;
1036
+ }
1037
+ .type-input {
1038
+ margin-top: 5px;
1039
+ }
1040
+ .type-select {
1041
+ margin-top: 6px;
1042
+ }
1043
+ p.bwp-option-page-inputs {
1044
+ margin: 0 0 0 220px;
1045
+ padding: 0;
1046
+ }
1047
+ .bwp-option-page-inputs input[type="text"],
1048
+ .bwp-option-page-inputs select {
1049
+ margin: 0 0 5px 0;
1050
+ }
1051
+ .bwp-option-page-inputs label {
1052
+ margin: 0;
1053
+ }
1054
+ .bwp-option-page-inputs select {
1055
+ /* margin: 1px 0 0 0; */
1056
+ }
1057
  .bwp-form-help-block {
1058
  display: block;
1059
+ margin: -0.5em 0 1em 0;
1060
  color: #737373;
1061
  }
1062
  .bwp-form-help-block-first {
1093
  display: inline-block;
1094
  margin-bottom: 5px;
1095
  }
1096
+ .bwp-code-editor {
1097
+ display: block;
1098
+ max-height: 200px;
1099
+ }
1100
  .bwp-modal-header h4 {
1101
  margin: 0;
1102
  font-size: 1.1em;
1103
  }
 
 
 
 
 
 
 
 
 
1104
  .bwp-modal-sm {
1105
  width: 350px;
1106
  }
1174
  .ui-datepicker-trigger {
1175
  display: none;
1176
  }
1177
+ .CodeMirror {
1178
+ border: 1px solid #ddd;
1179
+ height: auto;
1180
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07) inset;
1181
+ -khtml-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07) inset;
1182
+ -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07) inset;
1183
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07) inset;
1184
+ font-size: 12px;
1185
+ }
1186
+ .CodeMirror-readonly {
1187
+ background-color: #eee !important;
1188
+ }
1189
+ .CodeMirror-scroll {
1190
+ max-height: 200px;
1191
+ }
1192
+ .CodeMirror-lines {
1193
+ padding: 4px;
1194
+ }
1195
+ .bwp-code-editor-large + .CodeMirror .CodeMirror-scroll {
1196
+ max-height: 300px;
1197
+ }
1198
+ .bwp-option-page-inputs .CodeMirror,
1199
+ .bwp-option-page-inputs .bwp-code-editor {
1200
+ margin: 1.3em 0 1.7em 0;
1201
+ }
1202
+ .CodeMirror + .bwp-form-help-block,
1203
+ .bwp-code-editor + .bwp-form-help-block {
1204
+ margin-top: -0.85em;
1205
+ margin-bottom: 1.2em;
1206
+ }
1207
+ .CodeMirror pre.CodeMirror-placeholder,
1208
+ .bwp-code-editor pre.CodeMirror-placeholder {
1209
+ color: #999;
1210
+ }
1211
  /*# sourceMappingURL=style.css.map */
vendor/kminh/bwp-framework/assets/option-page/css/style.css.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/assets/vendor/bootstrap/less/component-animations.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/bower_components/bootstrap/less/mixins/vendor-prefixes.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/assets/vendor/bootstrap/less/close.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/bower_components/bootstrap/less/mixins/opacity.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/assets/vendor/bootstrap/less/modals.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/assets/vendor/bootstrap/less/tooltip.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/bower_components/bootstrap/less/mixins/reset-text.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/assets/vendor/bootstrap/less/popovers.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/bower_components/bootstrap/less/mixins/clearfix.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/bower_components/bootstrap/less/utilities.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/bower_components/bootstrap/less/mixins/center-block.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/bower_components/bootstrap/less/mixins/hide-text.less","less/bootstrap.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/bower_components/bootstrap/less/mixins/text-emphasis.less","less//home/kminh/src/php/bwp/community/bwp-recaptcha/vendor/kminh/bwp-framework/bower_components/bootstrap/less/mixins/background-variant.less","less/bwp.less","less/form.less","less/modal.less","less/popover.less","less/datetimepicker.less"],"names":[],"mappings":"AASA;EACE,UAAA;ECoLA,wCAAA;EACK,mCAAA;EACG,gCAAA;;ADpLR,SAAC;EACC,UAAA;;AAIJ;EACE,aAAA;;AAEA,aAAC;EAAW,cAAA;;AACZ,EAAE,aAAC;EAAS,kBAAA;;AACZ,KAAK,aAAC;EAAM,wBAAA;;AAGd;EACE,kBAAA;EACA,SAAA;EACA,gBAAA;ECuKA,+CAAA;EACQ,uCAAA;EAOR,kCAAA;EACQ,0BAAA;EAGR,wCAAA;EACQ,gCAAA;;AC3MV;EACE,YAAA;EACA,iBAAA;EACA,iBAAA;EACA,cAAA;EACA,cAAA;EACA,4BAAA;ECRA,YAAA;EAGA,yBAAA;;ADQA,UAAC;AACD,UAAC;EACC,cAAA;EACA,qBAAA;EACA,eAAA;ECfF,YAAA;EAGA,yBAAA;;ADoBA,MAAM;EACJ,UAAA;EACA,eAAA;EACA,uBAAA;EACA,SAAA;EACA,wBAAA;;AErBJ;EACE,gBAAA;;AAIF;EACE,aAAA;EACA,gBAAA;EACA,eAAA;EACA,MAAA;EACA,QAAA;EACA,SAAA;EACA,OAAA;EACA,aAAA;EACA,iCAAA;EAIA,UAAA;;AAGA,UAAC,SAAU;EH+GX,mBAAmB,kBAAnB;EACI,eAAe,kBAAf;EACC,cAAc,kBAAd;EACG,WAAW,kBAAX;EAkER,mDAAA;EACG,6CAAA;EACE,yCAAA;EACG,mCAAA;;AGnLR,UAAC,GAAI;EH2GL,mBAAmB,eAAnB;EACI,eAAe,eAAf;EACC,cAAc,eAAd;EACG,WAAW,eAAX;;AG5GV,eAAgB;EACd,kBAAA;EACA,gBAAA;;AAIF;EACE,kBAAA;EACA,WAAA;EACA,YAAA;;AAIF;EACE,kBAAA;EACA,yBAAA;EACA,yBAAA;EACA,oCAAA;EACA,kBAAA;EHaA,gDAAA;EACQ,wCAAA;EGZR,4BAAA;EAEA,UAAA;;AAIF;EACE,eAAA;EACA,MAAA;EACA,QAAA;EACA,SAAA;EACA,OAAA;EACA,aAAA;EACA,yBAAA;;AAEA,mBAAC;EDrED,UAAA;EAGA,wBAAA;;ACmEA,mBAAC;EDtED,YAAA;EAGA,yBAAA;;ACwEF;EACE,aAAA;EACA,gCAAA;EACA,yBAAA;;AAGF,iBAAkB;EAChB,gBAAA;;AAIF;EACE,SAAA;EACA,uBAAA;;AAKF;EACE,kBAAA;EACA,aAAA;;AAIF;EACE,aAAA;EACA,iBAAA;EACA,6BAAA;;AAHF,iBAOE,SAAS;EACP,gBAAA;EACA,gBAAA;;AATJ,iBAYE,eAAe,SAAS;EACtB,iBAAA;;AAbJ,iBAgBE,eAAe;EACb,cAAA;;AAKJ;EACE,kBAAA;EACA,YAAA;EACA,WAAA;EACA,YAAA;EACA,gBAAA;;AAkBF,QAdmC;EAEjC;IACE,YAAA;IACA,iBAAA;;EAEF;IHvEA,iDAAA;IACQ,yCAAA;;EG2ER;IAAgB,YAAA;;;AAMlB,QAHmC;EACjC;IAAgB,YAAA;;;AC9IlB;EACE,kBAAA;EACA,aAAA;EACA,cAAA;ECRA,oBAAA;EAEA,kBAAA;EACA,mBAAA;EACA,sBAAA;EACA,gBAAA;EACA,uBAAA;EACA,gBAAA;EACA,iBAAA;EACA,qBAAA;EACA,iBAAA;EACA,oBAAA;EACA,mBAAA;EACA,kBAAA;EACA,oBAAA;EACA,iBAAA;EDHA,eAAA;EFVA,UAAA;EAGA,wBAAA;;AEWA,YAAC;EFdD,YAAA;EAGA,yBAAA;;AEYA,YAAC;EAAU,gBAAA;EAAmB,cAAA;;AAC9B,YAAC;EAAU,gBAAA;EAAmB,cAAA;;AAC9B,YAAC;EAAU,eAAA;EAAmB,cAAA;;AAC9B,YAAC;EAAU,iBAAA;EAAmB,cAAA;;AAIhC;EACE,gBAAA;EACA,gBAAA;EACA,cAAA;EACA,kBAAA;EACA,yBAAA;EACA,kBAAA;;AAIF;EACE,kBAAA;EACA,QAAA;EACA,SAAA;EACA,yBAAA;EACA,mBAAA;;AAIA,YAAC,IAAK;EACJ,SAAA;EACA,SAAA;EACA,iBAAA;EACA,uBAAA;EACA,yBAAA;;AAEF,YAAC,SAAU;EACT,SAAA;EACA,UAAA;EACA,mBAAA;EACA,uBAAA;EACA,yBAAA;;AAEF,YAAC,UAAW;EACV,SAAA;EACA,SAAA;EACA,mBAAA;EACA,uBAAA;EACA,yBAAA;;AAEF,YAAC,MAAO;EACN,QAAA;EACA,OAAA;EACA,gBAAA;EACA,2BAAA;EACA,2BAAA;;AAEF,YAAC,KAAM;EACL,QAAA;EACA,QAAA;EACA,gBAAA;EACA,2BAAA;EACA,0BAAA;;AAEF,YAAC,OAAQ;EACP,MAAA;EACA,SAAA;EACA,iBAAA;EACA,uBAAA;EACA,4BAAA;;AAEF,YAAC,YAAa;EACZ,MAAA;EACA,UAAA;EACA,gBAAA;EACA,uBAAA;EACA,4BAAA;;AAEF,YAAC,aAAc;EACb,MAAA;EACA,SAAA;EACA,gBAAA;EACA,uBAAA;EACA,4BAAA;;AE7FJ;EACE,kBAAA;EACA,MAAA;EACA,OAAA;EACA,aAAA;EACA,aAAA;EACA,gBAAA;EACA,YAAA;EDXA,oBAAA;EAEA,kBAAA;EACA,mBAAA;EACA,sBAAA;EACA,gBAAA;EACA,uBAAA;EACA,gBAAA;EACA,iBAAA;EACA,qBAAA;EACA,iBAAA;EACA,oBAAA;EACA,mBAAA;EACA,kBAAA;EACA,oBAAA;EACA,iBAAA;ECAA,eAAA;EAEA,yBAAA;EACA,4BAAA;EACA,yBAAA;EACA,oCAAA;EACA,kBAAA;EN8CA,iDAAA;EACQ,yCAAA;;AM3CR,YAAC;EAAW,iBAAA;;AACZ,YAAC;EAAW,iBAAA;;AACZ,YAAC;EAAW,gBAAA;;AACZ,YAAC;EAAW,kBAAA;;AAGd;EACE,SAAA;EACA,iBAAA;EACA,eAAA;EACA,yBAAA;EACA,gCAAA;EACA,4BAAA;;AAGF;EACE,iBAAA;;AAQA,YADW;AAEX,YAFW,aAEV;EACC,kBAAA;EACA,cAAA;EACA,QAAA;EACA,SAAA;EACA,yBAAA;EACA,mBAAA;;AAGJ,YAAa;EACX,kBAAA;;AAEF,YAAa,aAAY;EACvB,kBAAA;EACA,SAAS,EAAT;;AAIA,YAAC,IAAK;EACJ,SAAA;EACA,kBAAA;EACA,sBAAA;EACA,yBAAA;EACA,qCAAA;EACA,aAAA;;AACA,YAPD,IAAK,aAOH;EACC,SAAS,GAAT;EACA,WAAA;EACA,kBAAA;EACA,sBAAA;EACA,yBAAA;;AAGJ,YAAC,MAAO;EACN,QAAA;EACA,WAAA;EACA,iBAAA;EACA,oBAAA;EACA,2BAAA;EACA,uCAAA;;AACA,YAPD,MAAO,aAOL;EACC,SAAS,GAAT;EACA,SAAA;EACA,aAAA;EACA,oBAAA;EACA,2BAAA;;AAGJ,YAAC,OAAQ;EACP,SAAA;EACA,kBAAA;EACA,mBAAA;EACA,4BAAA;EACA,wCAAA;EACA,UAAA;;AACA,YAPD,OAAQ,aAON;EACC,SAAS,GAAT;EACA,QAAA;EACA,kBAAA;EACA,mBAAA;EACA,4BAAA;;AAIJ,YAAC,KAAM;EACL,QAAA;EACA,YAAA;EACA,iBAAA;EACA,qBAAA;EACA,0BAAA;EACA,sCAAA;;AACA,YAPD,KAAM,aAOJ;EACC,SAAS,GAAT;EACA,UAAA;EACA,qBAAA;EACA,0BAAA;EACA,aAAA;;AClHJ,SAAC;AACD,SAAC;AJwFH,iBIzFG;AJyFH,iBIxFG;EACC,SAAS,GAAT;EACA,cAAA;;AAEF,SAAC;AJoFH,iBIpFG;EACC,WAAA;;ACRJ;ECRE,cAAA;EACA,iBAAA;EACA,kBAAA;;ADSF;EACE,uBAAA;;AAEF;EACE,sBAAA;;AAQF;EACE,wBAAA;;AAEF;EACE,yBAAA;;AAEF;EACE,kBAAA;;AAEF;EEzBE,WAAA;EACA,kBAAA;EACA,iBAAA;EACA,6BAAA;EACA,SAAA;;AF8BF;EACE,wBAAA;;AAOF;EACE,eAAA;;AGNF;EAAuB,gBAAA;;AACvB;EAAuB,iBAAA;;AACvB;EAAuB,kBAAA;;AACvB;EAAuB,mBAAA;;AACvB;EAAuB,mBAAA;;AAGvB;EAAuB,yBAAA;;AACvB;EAAuB,yBAAA;;AACvB;EAAuB,0BAAA;;AAGvB;EACC,cAAA;;AAED;EC3DE,cAAA;;AACA,CAAC,aAAC;AACF,CAAC,aAAC;EACA,cAAA;;AD2DJ;EC9DE,YAAA;;AACA,CAAC,aAAC;AACF,CAAC,aAAC;EACA,cAAA;;AD8DJ;ECjEE,cAAA;;AACA,CAAC,UAAC;AACF,CAAC,UAAC;EACA,cAAA;;ADiEJ;ECpEE,cAAA;;AACA,CAAC,aAAC;AACF,CAAC,aAAC;EACA,cAAA;;ADoEJ;ECvEE,cAAA;;AACA,CAAC,YAAC;AACF,CAAC,YAAC;EACA,cAAA;;AD2EJ;EAGC,WAAA;EEjFC,yBAAA;;AACA,CAAC,WAAC;AACF,CAAC,WAAC;EACA,yBAAA;;AFiFJ;EEpFE,yBAAA;;AACA,CAAC,WAAC;AACF,CAAC,WAAC;EACA,yBAAA;;AFoFJ;EEvFE,yBAAA;;AACA,CAAC,QAAC;AACF,CAAC,QAAC;EACA,yBAAA;;AFuFJ;EE1FE,yBAAA;;AACA,CAAC,WAAC;AACF,CAAC,WAAC;EACA,yBAAA;;AF0FJ;EE7FE,yBAAA;;AACA,CAAC,UAAC;AACF,CAAC,UAAC;EACA,yBAAA;;;ACLJ;EACI,mBAAA;EACA,+BAAA;EACA,uBAAA;EACA,cAAA;EACA,4BAAA;EACA,eAAA;EACA,iBAAA;EACA,qBAAA;EACA,qBAAA;EACA,qBAAA;EACA,oBAAA;;;;;;;;;AASJ;EACI,iBAAA;EACA,gCAAA;EACA,cAAA;;AAEJ,EAAE;AAAkB,EAAE;EAClB,6BAAA;EACA,iBAAA;;AAEJ,EAAG;EAAS,qBAAA;;AAEZ;EACC,eAAA;;;AAID,gBAAiB;EAChB,cAAA;EACA,aAAA;;AAGD,gBAAiB;EAChB,eAAA;EACA,kBAAA;EACA,OAAA;;AAGD,gBAAiB;EAChB,aAAA;;AAGD,gBAAiB,GAAE;AAAY,gBAAiB,IAAG;EAClD,WAAA;;EAEA,iBAAA;EACA,OAAA;;AAGD,gBAAiB,EAAC;;EAEjB,kBAAA;;AAGD,KAAM;EACL,gCAAA;EACA,mBAAA;EACA,mBAAA;;AAGD,qBAAsB;EACrB,eAAA;EACG,iBAAA;EACA,kBAAA;;AAGJ,qBAAsB,EAAC;EACtB,eAAA;EACA,iBAAA;;AAGD;EACC,cAAA;EACA,WAAA;EACA,YAAA;EACA,mBAAA;;AAGD;EACC,eAAA;;AAGD,CAAC;EACA,mBAAA;EACA,UAAA;;AAGD,uBAAwB,MAAK;AAAe,uBAAwB;EACnE,iBAAA;;AAGD,uBAAwB;EACvB,SAAA;;AAGD,uBAAwB;;;AAIxB,uBAAwB,MAAK;EAC5B,gBAAA;;AAGD;EACC,aAAA;;AAGD;EACC,kBAAA;;;;AAKD,WAAY;EACX,sBAAA;;AAGD,WACC;EACC,WAAA;EACA,YAAA;EACA,eAAA;EACA,sBAAA;;;;AAMF;EACC,UAAA;;AAGD;EACC,UAAA;;AAGD;EACC,WAAA;;AAGD,KAAK,UAAU;EACd,gCAAA;;AAGD,UAAW;AACX,UAAW;AACX,KAAK,UAAW,MAAM;AACtB,KAAK,UAAW,MAAM;AACtB,KAAK,UAAW,MAAM;AACtB,KAAK,UAAW,MAAM;EACrB,eAAA;EACA,iBAAA;;AAGD,KAAK,UAAW,MAAM;AACtB,KAAK,UAAW,MAAM;EACrB,gBAAA;;AAGD,wBAAyB,MAAM;EAC9B,cAAA;EACA,kBAAA;;AAGD,wBAAyB;EACxB,cAAA;EACA,cAAA;EACA,WAAA;EACA,iBAAA;;AAGD,wBAAyB,GAAE;AAC3B,wBAAyB,GAAE;EAC1B,eAAA;;AAGD;EACC,UAAA;EACA,iBAAA;EACA,kBAAA;EACA,gBAAA;;AAGD,uCAAwC;EACvC,YAAA;;AAGD,KAAK,UAAW,MAAM;AACtB,KAAK,UAAW,MAAM;EACrB,gCAAA;;AAGD,KAAK;AAAY,KAAK,UAAW;AAAI,KAAK,UAAW;EACpD,sBAAA;;AAGD,mBAAoB,MAAK;AACzB,mBAAoB;AACpB,mBAAoB;AACpB,mBAAoB;AACpB,mBAAoB;EACnB,WAAA;;AAGD;EACC,kBAAA;;AAGD,mBAAoB;EACnB,gBAAA;;AAGD,mBAAoB,qBAAqB;EACxC,YAAA;EACA,yBAAA;;AAGD,mBAAoB,qBAAqB,iBAAgB;EACxD,gBAAA;EACA,YAAA;EACA,yBAAA;;AAGD,mBAAoB,qBAAqB,iBAAgB;EACxD,gBAAA;EACA,gBAAA;EACA,yBAAA;;AAGD,mBAAoB,qBAAqB,iBAAgB;AACzD,mBAAoB,qBAAqB,iBAAgB,SAAS;AAClE,mBAAoB,qBAAqB,iBAAgB,SAAS;EACjE,YAAA;;AAGD,mBAAoB,qBAAqB,iBAAgB;AACzD,mBAAoB,qBAAqB,iBAAgB,QAAQ;EAChE,gBAAA;EACA,YAAA;EACA,sBAAA;;;AAID;EACC,gBAAgB,qCAAhB;EACA,yBAAA;EACA,YAAA;EACA,WAAA;;AAGD;EACC,4BAAA;EACA,gCAAA;EACA,gBAAA;EAAkB,gBAAA;EAClB,WAAA;;AAGD;EACC,YAAA;EACA,qBAAA;;AAGD;AAAe;AAAc;EAC5B,YAAA;EACA,YAAA;EAAc,mBAAA;EACd,yBAAA;EACA,yBAAA;EACA,kBAAA;;AAGD,aAAc;AAAG,QAAS;EACzB,qBAAA;;AAGD;EACC,mBAAA;;AAGD,QAAS;EACR,0BAAA;;AAGD,eAAgB;EACf,gBAAA;;AAGD,aAAc;EACb,sBAAA;EACA,qBAAA;EACA,mBAAA;EACA,YAAA;;AAGD;EACC,YAAA;;AAGD;EACC,gBAAA;EACA,YAAA;;AAGD,YAAa;EACZ,cAAA;EACA,YAAA;EACA,gBAAA;EACA,kBAAA;;AAGD,YAAa;EACZ,4BAA4B,+CAA5B;;AAGD,YAAa;EACZ,4BAA4B,mDAA5B;;ACpUD;EACC,cAAA;;AAGD;EACC,cAAA;;AAGD;EACC,kBAAA;;AAGD;EACC,eAAA;;AAGD;EACC,kBAAA;;AADD,eAGC;EACC,qBAAA;EACA,kBAAA;EACA,eAAA;;AANF,eASC;EACC,cAAA;EACA,WAAA;;AAIF,kBACC;EACC,cAAA;;AAFF,kBAKC;EACC,UAAA;;AANF,kBASC;EACC,UAAA;;AAVF,kBAaC;EACC,UAAA;;AAIF,kBACC;EACC,cAAA;;AAFF,kBAKC;EACC,UAAA;;AANF,kBASC;EACC,UAAA;;AAVF,kBAaC;EACC,UAAA;;AAIF;EACC,kBAAA;;AADD,iBAGC;EACC,wBAAA;;AAIF,wBACC,mBACC;AAFF,wBACC,mBACQ,MAAK;EACX,gBAAA;EACA,UAAA;;AAJH,wBACC,mBAMC;EACC,SAAA;;AAKH;EACC,cAAA;EACA,WAAA;;AAGD;EACC,mBAAA;;AAGD;EACC,cAAA;EACA,WAAA;EACA,YAAA;EAEA,iBAAA;EAEA,kBAAA;EACA,SAAA;EACA,QAAA;EACA,UAAA;EAEA,kBAAA;EACA,iBAAA;EAEA,eAAA;;AAID;EACC,cAAA;EACA,aAAA;EACA,cAAA;;AAGD;EACC,aAAA;;AAGD;EACC,gBAAA;;AAGD;EAEC,qBAAA;;AAEA,oBAAC;EACA,gBAAA;;AAKF;EACC,sBAAA;EAEA,cAAA;;AAEA,eAAC;AAAQ,eAAC;AAAS,eAAC;EACnB,eAAA;EACA,cAAA;;AAGD,eAAC;EACA,cAAA;;AAQD,MAAE;AAAF,KADY,aACV;AAAF,QAAE;AAAmB,MAAE,uBAAuB;AAAzB,KADT,aACW,uBAAuB;AAAzB,QAAE,uBAAuB;EAC7C,qBAAA;EACA,kBAAA;;ACjKF,iBACC;EACC,SAAA;EACA,gBAAA;;AAIF;EACC,eAAA;;AAEA,iBAAC;EACA,cAAA;;AAGD,iBAAC;EACA,gBAAA;;AAIF;EACC,YAAA;;AAGD;EhB6CE,gDAAA;EACQ,wCAAA;;AgBpCV,QANmC;EAClC;IhBwCC,gDAAA;IACQ,wCAAA;;;AOxDR,iBAAC;AACD,iBAAC;EACC,SAAS,GAAT;EACA,cAAA;;AAEF,iBAAC;EACC,WAAA;;AANF,iBAAC;AACD,iBAAC;EACC,SAAS,GAAT;EACA,cAAA;;AAEF,iBAAC;EACC,WAAA;;AScJ,iBAGC;EACC,gBAAA;;AAIF;ERvBE,sBAAA;EG6BqB,gBAAA;EKFtB,cAAA;EACA,cAAA;EACA,iBAAA;;AC/CD;EACC,eAAA;;AAGD;EACC,cAAA;;AAGD;EACC,cAAA;;AAGD;EACC,cAAA;;AAGD;EjBoDE,gDAAA;EACQ,wCAAA;;AiBlDT,YAAC;EAAW,iBAAA;;AACZ,YAAC;EAAW,iBAAA;;AACZ,YAAC;EAAW,gBAAA;;AACZ,YAAC;EAAW,kBAAA;;AAGb;EACC,iBAAA;;AC1BD;EACC,aAAA","file":"style.css"}
 
vendor/kminh/bwp-framework/assets/option-page/dist/css/op.min.css CHANGED
@@ -1 +1 @@
1
- .bwp-collapsing,.bwp-modal,.bwp-modal-open{overflow:hidden}.bwp-fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.bwp-fade.in{opacity:1}.bwp-collapse{display:none}.bwp-collapse.in{display:block}tr.bwp-collapse.in{display:table-row}tbody.bwp-collapse.in{display:table-row-group}.bwp-collapsing{position:relative;height:0;-webkit-transition-property:height,visibility;transition-property:height,visibility;-webkit-transition-duration:.35s;transition-duration:.35s;-webkit-transition-timing-function:ease;transition-timing-function:ease}.bwp-close{float:right;font-size:19.5px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.bwp-popover,.bwp-tooltip{font-family:inherit;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;text-decoration:none}.bwp-modal-title,.bwp-popover,.bwp-tooltip{line-height:1.42857143}.bwp-close:focus,.bwp-close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.bwp-close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.bwp-modal{display:none;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.bwp-modal.bwp-fade .bwp-modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.bwp-modal.in .bwp-modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.bwp-modal-open .bwp-modal{overflow-x:hidden;overflow-y:auto}.bwp-modal-dialog{position:relative;width:auto;margin:10px}.bwp-modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:0;background-clip:padding-box;outline:0}.bwp-modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#f1f1f1}.bwp-modal-backdrop.bwp-fade{opacity:0;filter:alpha(opacity=0)}.bwp-modal-backdrop.in{opacity:.8;filter:alpha(opacity=80)}.bwp-modal-header{padding:15px;border-bottom:1px solid #e5e5e5;min-height:16.43px}.bwp-modal-header .bwp-close{margin-top:-2px}.bwp-modal-title{margin:0}.bwp-modal-body{position:relative;padding:15px}.bwp-modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.bwp-modal-footer .bwp-btn+.bwp-btn{margin-left:5px;margin-bottom:0}.bwp-modal-footer .bwp-btn-group .bwp-btn+.bwp-btn{margin-left:-1px}.bwp-modal-footer .bwp-btn-block+.bwp-btn-block{margin-left:0}.bwp-modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.bwp-modal-dialog{width:600px;margin:30px auto}.bwp-modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.bwp-modal-sm{width:300px}}@media (min-width:992px){.bwp-modal-lg{width:900px}}.bwp-tooltip{position:absolute;z-index:1070;display:block;text-align:left;text-align:start;text-shadow:none;font-size:12px;opacity:0;filter:alpha(opacity=0)}.bwp-tooltip.in{opacity:.9;filter:alpha(opacity=90)}.bwp-tooltip.top{margin-top:-3px;padding:5px 0}.bwp-tooltip.right{margin-left:3px;padding:0 5px}.bwp-tooltip.bottom{margin-top:3px;padding:5px 0}.bwp-tooltip.left{margin-left:-3px;padding:0 5px}.bwp-tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:0}.bwp-popover,.text-left{text-align:left}.bwp-tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.bwp-tooltip.top .bwp-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.bwp-tooltip.top-left .bwp-tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.bwp-tooltip.top-right .bwp-tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.bwp-tooltip.right .bwp-tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.bwp-tooltip.left .bwp-tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.bwp-tooltip.bottom .bwp-tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.bwp-tooltip.bottom-left .bwp-tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.bwp-tooltip.bottom-right .bwp-tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.bwp-popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;text-align:start;text-shadow:none;font-size:13px;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:0}.bwp-popover-title{margin:0;font-size:13px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:-1px -1px 0 0}.bwp-popover-content{padding:9px 14px}.bwp-popover>.bwp-arrow,.bwp-popover>.bwp-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.bwp-popover>.bwp-arrow{border-width:11px}.bwp-popover>.bwp-arrow:after{border-width:10px;content:""}.bwp-popover.top>.bwp-arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,0,0,.25);bottom:-11px}.bwp-popover.top>.bwp-arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#fff}.bwp-popover.right>.bwp-arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,.25)}.bwp-popover.right>.bwp-arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#fff}.bwp-popover.bottom>.bwp-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25);top:-11px}.bwp-popover.bottom>.bwp-arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.bwp-popover.left>.bwp-arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.bwp-popover.left>.bwp-arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px}.bwp-modal-footer:after,.bwp-modal-footer:before,.clearfix:after,.clearfix:before{content:" ";display:table}.bwp-modal-footer:after,.clearfix:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.dataTables_wrapper .dataTables_info,table.dataTable tfoot th,table.dataTable thead th{font-weight:600}.hidden{display:none!important}.affix{position:fixed}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:green}a.text-success:focus,a.text-success:hover{color:#004d00}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#dd3d36}a.text-danger:focus,a.text-danger:hover{color:#c02720}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.nav-tab{border-style:solid;border-color:#ccc #ccc #f9f9f9;border-width:1px 1px 0;color:#c1c1c1;text-shadow:#fff 0 1px 0;font-size:12px;line-height:16px;display:inline-block;padding:4px 14px 6px;text-decoration:none;margin:0 3px -1px 0}.nav-tab-active{border-width:1px;border-bottom-color:transparent;color:#000}h2.nav-tab-wrapper,h3.nav-tab-wrapper{border-bottom:1px solid #ccc;padding-bottom:0}h2 .nav-tab{padding:6px 15px}.bwp-option-page{margin-top:1em}.bwp-option-page h4{font-size:1em;margin:1em 0}.bwp-option-page p{margin-top:0;margin-bottom:0;zoom:1}.bwp-option-page .bwp-paragraph{margin:1em 0}.bwp-option-page div.bwp-clear,.bwp-option-page li.bwp-clear{clear:left;margin:1em 0 0;zoom:1}.bwp-option-page p.submit{padding-top:1.5em}.wrap .bwp-option-page-tabs{border-bottom:1px solid #CCC;padding-bottom:0;margin-bottom:20px}table.dataTable thead td,table.dataTable thead th,table.dataTable.no-footer{border-bottom:1px solid #e1e1e1}.bwp-option-page-tabs a{font-size:18px;line-height:24px;font-style:italic}.bwp-option-page-tabs a.version{font-size:14px;line-height:14px}.bwp-opton-page-label{display:block;float:left;width:200px;margin:5px 0 1em}.type-checkbox{margin-top:0}p.bwp-option-page-inputs{margin:0 0 0 220px;padding:0}.bwp-option-page-inputs input[type=text],.bwp-option-page-inputs select{margin:0 0 5px}.bwp-option-page-inputs label{margin:0}.bwp-option-page-inputs input[type=checkbox]{margin-left:2px}.bwp-no-display{display:none}.bwp-hidden{visibility:hidden}.wp-core-ui .button-inline{vertical-align:middle}.bwp-button .dashicons{width:auto;height:14px;font-size:14px;vertical-align:middle}.bwp-table-md{width:50%}.bwp-table-lg{width:70%}.bwp-table-inline{clear:none}.bwp-table td,.bwp-table th,table.dataTable tbody td,table.dataTable tbody th,table.dataTable thead td,table.dataTable thead th{font-size:13px;padding:5px 10px}#bwp-contact a,#bwp-info-place small{font-size:.8em}.bwp-table-fixed-headers thead tr{display:block;position:relative}.bwp-table-fixed-headers tbody{display:block;overflow:auto;width:100%;max-height:297px}.bwp-table-fixed-headers td.ordinal,.bwp-table-fixed-headers th.ordinal{min-width:30px}.bwp-table-fixed-headers-old-id-wrapper{width:50%;max-height:297px;overflow-x:hidden;overflow-y:auto}.bwp-table-fixed-headers-old-id-wrapper tbody{height:auto}table.dataTable,table.dataTable td,table.dataTable th{box-sizing:border-box}.dataTables_wrapper .dataTables_filter,.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_paginate,.dataTables_wrapper table.dataTable{color:#444}.dataTables_length{margin-bottom:1em}.dataTables_wrapper .dataTables_paginate .paginate_button{border:none;color:#0073aa!important}.dataTables_wrapper .dataTables_paginate .paginate_button:hover{background:0 0;border:none;color:#00a0d2!important}.dataTables_wrapper .dataTables_paginate .paginate_button:active{background:0 0;box-shadow:none;color:#00a0d2!important}.dataTables_wrapper .dataTables_paginate .paginate_button.disabled,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover{border:none}.dataTables_wrapper .dataTables_paginate .paginate_button.current,.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{background:0 0;border:none;color:#444!important}#icon-betterwp-net{background:url(betterwp.jpg) no-repeat;border:1px solid #E3E3E3;height:32px;width:32px}#icon-bwp-plugin{background-repeat:no-repeat;background-position:left center;margin-top:21px;margin-left:5px;width:36px}#bwp-info-place{float:right;margin:0 0 10px 10px}#bwp-ads,#bwp-contact,#bwp-donation{width:255px;padding:7px 7px 0;background-color:#fff;border:1px solid #ccc;text-align:center}#bwp-ads p,#bwp-donation p{margin:.5em 0 1em}#bwp-ads{padding-bottom:5px}#bwp-ads p{text-decoration:underline}#bwp-donation .paypal-submit{vertical-align:bottom;display:inline-block;margin:0 0 1px 2px;padding:0}.bwp-separator{width:271px}#bwp-contact{text-align:left;padding:7px}#bwp-contact a{display:block;height:20px;padding-left:25px}#bwp-contact .bwp-rss{background:url(../images/icon-rss.png) left center no-repeat}#bwp-contact .bwp-twitter{background:url(../images/icon-twitter.png) left center no-repeat}.bwp-inline-form-wrapper-lg{max-width:70%}.bwp-inline-form-wrapper-md{max-width:50%}.bwp-form-group{margin-bottom:1em;position:relative}.bwp-form-group-first{margin-top:1em}.bwp-form-group label{display:inline-block;margin-bottom:5px;max-width:100%}.bwp-form-group select{display:block;width:100%}.bwp-form-group-sm label{max-width:50%}.bwp-form-group-sm .bwp-form-control,.bwp-form-group-sm select{width:50%}.bwp-form-group-sm .bwp-form-control-icon{right:50%}.bwp-form-group-xs label{max-width:25%}.bwp-form-group-xs .bwp-form-control,.bwp-form-group-xs select{width:25%}.bwp-form-group-xs .bwp-form-control-icon{right:25%}.bwp-button-group{margin-bottom:1em}.bwp-button-group .button-secondary{vertical-align:baseline}.bwp-inline-form-wrapper .select2-container input,.bwp-inline-form-wrapper .select2-container input:focus{box-shadow:none;padding:0}.bwp-inline-form-wrapper .select2-container li{margin:0}.bwp-form-control{display:block;width:100%}.bwp-form-control-with-icon{padding-right:30px}.bwp-form-control-icon{display:block;width:20px;height:20px;margin-right:4px;position:absolute;top:28px;right:0;z-index:2;text-align:center;line-height:20px;cursor:pointer}.bwp-form-help-block{display:block;margin:1em 0;color:#737373}.bwp-form-help-block-first{margin-top:0}.bwp-form-help-block-last{margin-bottom:0}.bwp-field-help-link{text-decoration:none}.bwp-field-help-link:focus{box-shadow:none}.bwp-field-help{vertical-align:middle;color:#0073aa}.bwp-field-help:active,.bwp-field-help:focus,.bwp-field-help:hover{cursor:pointer;color:#00a0d2}.bwp-field-help:focus{color:#124964}input[type=text]+.bwp-field-help,input[type=text]+.bwp-field-help-link span,select+.bwp-field-help,select+.bwp-field-help-link span,textarea+.bwp-field-help,textarea+.bwp-field-help-link span{display:inline-block;margin-bottom:5px}.bwp-modal-header h4{margin:0;font-size:1.1em}.bwp-modal-dialog{padding-top:7%}.bwp-modal-dialog.bwp-modal-lg{padding-top:0}.bwp-modal-dialog.bwp-modal-sm{padding-top:17%}.bwp-modal-sm{width:350px}.bwp-modal-content{-webkit-box-shadow:0 3px 9px rgba(0,0,0,.2);box-shadow:0 3px 9px rgba(0,0,0,.2)}@media (min-width:768px){.bwp-modal-content{-webkit-box-shadow:0 3px 9px rgba(0,0,0,.2);box-shadow:0 3px 9px rgba(0,0,0,.2)}}.bwp-modal-footer:after,.bwp-modal-footer:before{content:" ";display:table}.bwp-modal-footer:after{clear:both}.bwp-modal-footer .bwp-btn{margin-left:5px}.bwp-modal-message{float:left!important;text-align:left;display:block;max-width:50%;margin-right:1em}.bwp-popover-full{max-width:100%}.bwp-popover-lg{max-width:75%}.bwp-popover-md{max-width:50%}.bwp-popover-sm{max-width:25%}.bwp-popover{-webkit-box-shadow:0 3px 6px rgba(0,0,0,.1);box-shadow:0 3px 6px rgba(0,0,0,.1)}.bwp-popover.top{margin-top:-15px}.bwp-popover.right{margin-left:15px}.bwp-popover.bottom{margin-top:15px}.bwp-popover.left{margin-left:-15px}.bwp-popover-title{padding:4px 14px}.ui-datepicker-trigger{display:none}
1
+ .bwp-collapsing,.bwp-modal,.bwp-modal-open{overflow:hidden}.bwp-fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.bwp-fade.in{opacity:1}.bwp-collapse{display:none}.bwp-collapse.in{display:block}tr.bwp-collapse.in{display:table-row}tbody.bwp-collapse.in{display:table-row-group}.bwp-collapsing{position:relative;height:0;-webkit-transition-property:height,visibility;transition-property:height,visibility;-webkit-transition-duration:.35s;transition-duration:.35s;-webkit-transition-timing-function:ease;transition-timing-function:ease}.bwp-close{float:right;font-size:19.5px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.bwp-popover,.bwp-tooltip{font-family:inherit;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;text-decoration:none}.bwp-modal-title,.bwp-popover,.bwp-tooltip{line-height:1.42857143}.bwp-close:focus,.bwp-close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.bwp-close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.bwp-modal{display:none;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.bwp-modal.bwp-fade .bwp-modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.bwp-modal.in .bwp-modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.bwp-modal-open .bwp-modal{overflow-x:hidden;overflow-y:auto}.bwp-modal-dialog{position:relative;width:auto;margin:10px}.bwp-modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:0;background-clip:padding-box;outline:0}.bwp-modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#f1f1f1}.bwp-modal-backdrop.bwp-fade{opacity:0;filter:alpha(opacity=0)}.bwp-modal-backdrop.in{opacity:.8;filter:alpha(opacity=80)}.bwp-modal-header{padding:15px;border-bottom:1px solid #e5e5e5;min-height:16.43px}.bwp-modal-header .bwp-close{margin-top:-2px}.bwp-modal-title{margin:0}.bwp-modal-body{position:relative;padding:15px}.bwp-modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.bwp-modal-footer .bwp-btn+.bwp-btn{margin-left:5px;margin-bottom:0}.bwp-modal-footer .bwp-btn-group .bwp-btn+.bwp-btn{margin-left:-1px}.bwp-modal-footer .bwp-btn-block+.bwp-btn-block{margin-left:0}.bwp-modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.bwp-modal-dialog{width:600px;margin:30px auto}.bwp-modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.bwp-modal-sm{width:300px}}@media (min-width:992px){.bwp-modal-lg{width:900px}}.bwp-tooltip{position:absolute;z-index:1070;display:block;text-align:left;text-align:start;text-shadow:none;font-size:12px;opacity:0;filter:alpha(opacity=0)}.bwp-tooltip.in{opacity:.9;filter:alpha(opacity=90)}.bwp-tooltip.top{margin-top:-3px;padding:5px 0}.bwp-tooltip.right{margin-left:3px;padding:0 5px}.bwp-tooltip.bottom{margin-top:3px;padding:5px 0}.bwp-tooltip.left{margin-left:-3px;padding:0 5px}.bwp-tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:0}.bwp-tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.bwp-tooltip.top .bwp-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.bwp-tooltip.top-left .bwp-tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.bwp-tooltip.top-right .bwp-tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.bwp-tooltip.right .bwp-tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.bwp-tooltip.left .bwp-tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.bwp-tooltip.bottom .bwp-tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.bwp-tooltip.bottom-left .bwp-tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.bwp-tooltip.bottom-right .bwp-tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.bwp-popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;text-align:left;text-align:start;text-shadow:none;font-size:13px;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:0}.bwp-popover-title{margin:0;font-size:13px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:-1px -1px 0 0}.bwp-popover-content{padding:9px 14px}.bwp-popover>.bwp-arrow,.bwp-popover>.bwp-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.bwp-popover>.bwp-arrow{border-width:11px}.bwp-popover>.bwp-arrow:after{border-width:10px;content:""}.bwp-popover.top>.bwp-arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,0,0,.25);bottom:-11px}.bwp-popover.top>.bwp-arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#fff}.bwp-popover.right>.bwp-arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,.25)}.bwp-popover.right>.bwp-arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#fff}.bwp-popover.bottom>.bwp-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25);top:-11px}.bwp-popover.bottom>.bwp-arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.bwp-popover.left>.bwp-arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.bwp-popover.left>.bwp-arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px}.bwp-modal-footer:after,.bwp-modal-footer:before,.clearfix:after,.clearfix:before{content:" ";display:table}.bwp-modal-footer:after,.clearfix:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:green}a.text-success:focus,a.text-success:hover{color:#004d00}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#dd3d36}a.text-danger:focus,a.text-danger:hover{color:#c02720}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.bwp-option-page{margin-top:1em;padding-bottom:1em}.bwp-option-page h4{font-size:1.1em;margin:1em 0}.bwp-option-page p{margin-top:0;margin-bottom:0;zoom:1}.bwp-option-page .bwp-paragraph{margin:1em 0}.bwp-option-page div.bwp-clear,.bwp-option-page li.bwp-clear{clear:left;margin:1em 0 0;zoom:1}.bwp-option-page div.bwp-clear{margin-bottom:1.7em}.bwp-no-display{display:none}.bwp-hidden{visibility:hidden}.bwp-meta{color:#999}.bwp-justin{display:inline-block;position:relative;bottom:.5em;font-size:.85em;font-weight:600;color:#f26522}.bwp-wrap{clear:both}#bwp-main{width:auto;overflow:hidden}#bwp-main .error,#bwp-main .updated{margin-top:15px;margin-bottom:0}#bwp-main .error.first,#bwp-main .updated.first{margin-top:20px}#bwp-header{margin-bottom:15px;padding-top:5px}#bwp-header h1{padding:0;margin-top:0;margin-bottom:15px;color:#32373c;font-size:2em;font-weight:400;line-height:1.2em}#bwp-donation{display:none}#bwp-get-social{max-width:450px;margin-top:15px;margin-bottom:0;overflow:hidden}#bwp-get-social .inside{padding-bottom:0}#bwp-get-social h2{cursor:default;font-size:14px;line-height:1.4;margin:0;padding:8px 12px}#bwp-social-buttons{height:20px;padding-top:3px}#bwp-social-buttons .bwp-fb-buttons,#bwp-social-buttons .bwp-gplus-buttons,#bwp-social-buttons .bwp-twitter-buttons{float:left;margin-right:15px}#bwp-social-buttons .bwp-gplus-buttons{max-width:80px;margin-right:0}.bwp-option-page-tabs a{padding-left:15px;padding-right:15px;color:#c1c1c1;font-size:18px;font-weight:600}.bwp-option-page-tabs a.nav-tab-active{color:#000}.wrap .bwp-option-page-tabs{padding-left:6px}.wp-core-ui .button-inline{vertical-align:middle}.bwp-button .dashicons{width:auto;height:18px;font-size:14px;vertical-align:middle}.bwp-button-paypal{color:#003580!important;text-shadow:0 1px 1px #ffcf84!important;background:#ffe3b7!important;border-color:#ffc975!important;box-shadow:0 1px 0 #ffc975!important;font-weight:600}.bwp-button-paypal:active,.bwp-button-paypal:hover{background:#ffe9c6!important;border-color:#ffb542!important}.bwp-button-paypal:active{box-shadow:0 2px 5px -3px rgba(183,112,0,.5) inset!important}.bwp-button-paypal .paypal-pal,.bwp-button-paypal .paypal-pay{font-weight:700;font-style:italic}.bwp-button-paypal .paypal-pay{color:#003580}.bwp-button-paypal .paypal-pal{color:#009DD8}#bwp-sidebar-right{width:276px;margin:0 0 10px 20px;float:right}#bwp-sidebar-right .postbox .inside{max-width:250px;padding-bottom:0;line-height:1}#bwp-sidebar-right .postbox .hndle{margin:0;padding:8px 12px;font-size:14px;line-height:1.4;cursor:default}#bwp-ads{margin-top:10px}#bwp-ads a{line-height:1}#bwp-news a{margin-right:5px}.bwp-button-rss{color:#fff!important;text-shadow:0 1px 1px #d44d0d!important;background:#f26522!important;border-color:#d44d0d!important;box-shadow:0 1px 0 #d44d0d!important}.bwp-button-rss:active,.bwp-button-rss:hover{background:#f36f30!important;border-color:#bc440b!important}.bwp-button-rss:active{box-shadow:0 2px 5px -3px rgba(20,7,1,.5) inset!important}.bwp-button-twitter{color:#fff!important;text-shadow:0 1px 1px #2795e9!important;background:#55acee!important;border-color:#2795e9!important;box-shadow:0 1px 0 #2795e9!important}.bwp-button-twitter:active,.bwp-button-twitter:hover{background:#63b3ef!important;border-color:#1689e0!important}table.dataTable thead td,table.dataTable thead th,table.dataTable.no-footer{border-bottom:1px solid #e1e1e1}.bwp-button-twitter:active{box-shadow:0 2px 5px -3px rgba(6,38,62,.5) inset!important}.bwp-feed{list-style:none;margin:0;padding:0}.bwp-feed li{margin-bottom:8px;line-height:1.5em}.bwp-feed a{font-size:13px;font-weight:400;text-decoration:none}.dataTables_wrapper .dataTables_info,table.dataTable tfoot th,table.dataTable thead th{font-weight:600}.bwp-feed-buttons{padding:12px;background-color:#fafafa;border-top:1px solid #eee}#icon-bwp-plugin{background-repeat:no-repeat;background-position:left center;margin-top:21px;margin-left:5px;width:36px}.bwp-table-md{width:50%}.bwp-table-full{width:100%}.bwp-table-lg{width:75%}.bwp-table-inline{clear:none}.dataTables_wrapper,table.dataTable{clear:left}.bwp-table td,.bwp-table th,table.dataTable tbody td,table.dataTable tbody th,table.dataTable thead td,table.dataTable thead th{font-size:13px;padding:5px 10px}.bwp-table-fixed-headers thead tr{display:block;position:relative}.bwp-table-fixed-headers tbody{display:block;overflow:auto;width:100%;max-height:297px}.bwp-table-fixed-headers td.ordinal,.bwp-table-fixed-headers th.ordinal{min-width:30px}.bwp-table-fixed-headers-old-id-wrapper{width:50%;max-height:297px;overflow-x:hidden;overflow-y:auto}.CodeMirror-scroll,.bwp-code-editor{max-height:200px}.bwp-table-fixed-headers-old-id-wrapper tbody{height:auto}.bwp-table-valign-middle td{vertical-align:middle}table.dataTable,table.dataTable td,table.dataTable th{box-sizing:border-box}.dataTables_wrapper .dataTables_filter,.dataTables_wrapper .dataTables_info,.dataTables_wrapper .dataTables_length,.dataTables_wrapper .dataTables_paginate,.dataTables_wrapper table.dataTable{color:#444}.dataTables_wrapper .dataTables_filter input{margin-right:0}.dataTables_length{margin-bottom:1em}.dataTables_wrapper .dataTables_paginate .paginate_button{border:none;color:#0073aa!important}.dataTables_wrapper .dataTables_paginate .paginate_button:hover{background:0 0;border:none;color:#00a0d2!important}.dataTables_wrapper .dataTables_paginate .paginate_button:active{background:0 0;box-shadow:none;color:#00a0d2!important}.dataTables_wrapper .dataTables_paginate .paginate_button.disabled,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active,.dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover{border:none}.dataTables_wrapper .dataTables_paginate .paginate_button.current,.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{background:0 0;border:none;color:#444!important}.bwp-option-page p.submit{clear:left;margin-top:2em;padding-top:0}.bwp-option-page p.submit button,.bwp-option-page p.submit input{margin-right:.3em}.bwp-fields{margin:0}.bwp-inline-form-wrapper-full{max-width:100%}.bwp-inline-form-wrapper-lg{max-width:75%}.bwp-inline-form-wrapper-md{max-width:50%}.bwp-form-group{margin-bottom:1em;position:relative}.bwp-form-group-first{margin-top:1em}.bwp-form-group label{display:inline-block;margin-bottom:5px;max-width:100%}.bwp-form-group select{display:block;width:100%}.bwp-form-group-sm label{max-width:50%}.bwp-form-group-sm .bwp-form-control,.bwp-form-group-sm select{width:50%}.bwp-form-group-sm .bwp-form-control-icon{right:50%}.bwp-form-group-xs label{max-width:25%}.bwp-form-group-xs .bwp-form-control,.bwp-form-group-xs select{width:25%}.bwp-form-group-xs .bwp-form-control-icon{right:25%}.bwp-button-group{margin-bottom:1em}.bwp-button-group .button-secondary{vertical-align:baseline}.bwp-inline-form-wrapper .select2-container input,.bwp-inline-form-wrapper .select2-container input:focus{box-shadow:none;padding:0}.bwp-inline-form-wrapper .select2-container li{margin:0}.bwp-form-control{display:block;width:100%}.bwp-form-control-with-icon{padding-right:30px}.bwp-form-control-icon{display:block;width:20px;height:20px;margin-right:4px;position:absolute;top:28px;right:0;z-index:2;text-align:center;line-height:20px;cursor:pointer}.bwp-opton-page-label{display:block;float:left;width:200px;margin:3px 0 1em}.type-checkbox{margin-top:3px;margin-bottom:1.5em}.type-input{margin-top:5px}.type-select{margin-top:6px}p.bwp-option-page-inputs{margin:0 0 0 220px;padding:0}.bwp-option-page-inputs input[type=text],.bwp-option-page-inputs select{margin:0 0 5px}.bwp-option-page-inputs label{margin:0}.bwp-form-help-block{display:block;margin:-.5em 0 1em;color:#737373}.bwp-form-help-block-first{margin-top:0}.bwp-form-help-block-last{margin-bottom:0}.bwp-field-help-link{text-decoration:none}.bwp-field-help-link:focus{box-shadow:none}.bwp-field-help{vertical-align:middle;color:#0073aa}.bwp-field-help:active,.bwp-field-help:focus,.bwp-field-help:hover{cursor:pointer;color:#00a0d2}.bwp-field-help:focus{color:#124964}input[type=text]+.bwp-field-help,input[type=text]+.bwp-field-help-link span,select+.bwp-field-help,select+.bwp-field-help-link span,textarea+.bwp-field-help,textarea+.bwp-field-help-link span{display:inline-block;margin-bottom:5px}.bwp-code-editor{display:block}.bwp-modal-header h4{margin:0;font-size:1.1em}.bwp-modal-sm{width:350px}.bwp-modal-content{-webkit-box-shadow:0 3px 9px rgba(0,0,0,.2);box-shadow:0 3px 9px rgba(0,0,0,.2)}@media (min-width:768px){.bwp-modal-content{-webkit-box-shadow:0 3px 9px rgba(0,0,0,.2);box-shadow:0 3px 9px rgba(0,0,0,.2)}}.bwp-modal-footer:after,.bwp-modal-footer:before{content:" ";display:table}.bwp-modal-footer:after{clear:both}.bwp-modal-footer .bwp-btn{margin-left:5px}.bwp-modal-message{float:left!important;text-align:left;display:block;max-width:50%;margin-right:1em}.bwp-popover-full{max-width:100%}.bwp-popover-lg{max-width:75%}.bwp-popover-md{max-width:50%}.bwp-popover-sm{max-width:25%}.bwp-popover{-webkit-box-shadow:0 3px 6px rgba(0,0,0,.1);box-shadow:0 3px 6px rgba(0,0,0,.1)}.bwp-popover.top{margin-top:-15px}.bwp-popover.right{margin-left:15px}.bwp-popover.bottom{margin-top:15px}.bwp-popover.left{margin-left:-15px}.bwp-popover-title{padding:4px 14px}.ui-datepicker-trigger{display:none}.CodeMirror{border:1px solid #ddd;height:auto;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.07) inset;-khtml-box-shadow:0 1px 2px rgba(0,0,0,.07) inset;-moz-box-shadow:0 1px 2px rgba(0,0,0,.07) inset;box-shadow:0 1px 2px rgba(0,0,0,.07) inset;font-size:12px}.CodeMirror-readonly{background-color:#eee!important}.CodeMirror-lines{padding:4px}.bwp-code-editor-large+.CodeMirror .CodeMirror-scroll{max-height:300px}.bwp-option-page-inputs .CodeMirror,.bwp-option-page-inputs .bwp-code-editor{margin:1.3em 0 1.7em}.CodeMirror+.bwp-form-help-block,.bwp-code-editor+.bwp-form-help-block{margin-top:-.85em;margin-bottom:1.2em}.CodeMirror pre.CodeMirror-placeholder,.bwp-code-editor pre.CodeMirror-placeholder{color:#999}
vendor/kminh/bwp-framework/assets/option-page/dist/js/code-editor.min.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ !function(a){if("object"==typeof exports&&"object"==typeof module)module.exports=a();else{if("function"==typeof define&&define.amd)return define([],a);(this||window).CodeMirror=a()}}(function(){"use strict";function a(c,d){if(!(this instanceof a))return new a(c,d);this.options=d=d?Ke(d):{},Ke($f,d,!1),n(d);var e=d.value;"string"==typeof e&&(e=new wg(e,d.mode,null,d.lineSeparator)),this.doc=e;var f=new a.inputStyles[d.inputStyle](this),g=this.display=new b(c,e,f);g.wrapper.CodeMirror=this,j(this),h(this),d.lineWrapping&&(this.display.wrapper.className+=" CodeMirror-wrap"),d.autofocus&&!Cf&&g.input.focus(),r(this),this.state={keyMaps:[],overlays:[],modeGen:0,overwrite:!1,delayingBlurEvent:!1,focused:!1,suppressEdits:!1,pasteIncoming:!1,cutIncoming:!1,selectingText:!1,draggingText:!1,highlight:new De,keySeq:null,specialChars:null};var i=this;sf&&11>tf&&setTimeout(function(){i.display.input.reset(!0)},20),Qb(this),We(),ub(this),this.curOp.forceUpdate=!0,Xd(this,e),d.autofocus&&!Cf||i.hasFocus()?setTimeout(Le(qc,this),20):rc(this);for(var k in _f)_f.hasOwnProperty(k)&&_f[k](this,d[k],ag);w(this),d.finishInit&&d.finishInit(this);for(var l=0;l<eg.length;++l)eg[l](this);wb(this),uf&&d.lineWrapping&&"optimizelegibility"==getComputedStyle(g.lineDiv).textRendering&&(g.lineDiv.style.textRendering="auto")}function b(a,b,c){var d=this;this.input=c,d.scrollbarFiller=Pe("div",null,"CodeMirror-scrollbar-filler"),d.scrollbarFiller.setAttribute("cm-not-content","true"),d.gutterFiller=Pe("div",null,"CodeMirror-gutter-filler"),d.gutterFiller.setAttribute("cm-not-content","true"),d.lineDiv=Pe("div",null,"CodeMirror-code"),d.selectionDiv=Pe("div",null,null,"position: relative; z-index: 1"),d.cursorDiv=Pe("div",null,"CodeMirror-cursors"),d.measure=Pe("div",null,"CodeMirror-measure"),d.lineMeasure=Pe("div",null,"CodeMirror-measure"),d.lineSpace=Pe("div",[d.measure,d.lineMeasure,d.selectionDiv,d.cursorDiv,d.lineDiv],null,"position: relative; outline: none"),d.mover=Pe("div",[Pe("div",[d.lineSpace],"CodeMirror-lines")],null,"position: relative"),d.sizer=Pe("div",[d.mover],"CodeMirror-sizer"),d.sizerWidth=null,d.heightForcer=Pe("div",null,null,"position: absolute; height: "+Hg+"px; width: 1px;"),d.gutters=Pe("div",null,"CodeMirror-gutters"),d.lineGutter=null,d.scroller=Pe("div",[d.sizer,d.heightForcer,d.gutters],"CodeMirror-scroll"),d.scroller.setAttribute("tabIndex","-1"),d.wrapper=Pe("div",[d.scrollbarFiller,d.gutterFiller,d.scroller],"CodeMirror"),sf&&8>tf&&(d.gutters.style.zIndex=-1,d.scroller.style.paddingRight=0),uf||pf&&Cf||(d.scroller.draggable=!0),a&&(a.appendChild?a.appendChild(d.wrapper):a(d.wrapper)),d.viewFrom=d.viewTo=b.first,d.reportedViewFrom=d.reportedViewTo=b.first,d.view=[],d.renderedView=null,d.externalMeasured=null,d.viewOffset=0,d.lastWrapHeight=d.lastWrapWidth=0,d.updateLineNumbers=null,d.nativeBarWidth=d.barHeight=d.barWidth=0,d.scrollbarsClipped=!1,d.lineNumWidth=d.lineNumInnerWidth=d.lineNumChars=null,d.alignWidgets=!1,d.cachedCharWidth=d.cachedTextHeight=d.cachedPaddingH=null,d.maxLine=null,d.maxLineLength=0,d.maxLineChanged=!1,d.wheelDX=d.wheelDY=d.wheelStartX=d.wheelStartY=null,d.shift=!1,d.selForContextMenu=null,d.activeTouch=null,c.init(d)}function c(b){b.doc.mode=a.getMode(b.options,b.doc.modeOption),d(b)}function d(a){a.doc.iter(function(a){a.stateAfter&&(a.stateAfter=null),a.styles&&(a.styles=null)}),a.doc.frontier=a.doc.first,Na(a,100),a.state.modeGen++,a.curOp&&Jb(a)}function e(a){a.options.lineWrapping?(Yg(a.display.wrapper,"CodeMirror-wrap"),a.display.sizer.style.minWidth="",a.display.sizerWidth=null):(Xg(a.display.wrapper,"CodeMirror-wrap"),m(a)),g(a),Jb(a),hb(a),setTimeout(function(){s(a)},100)}function f(a){var b=sb(a.display),c=a.options.lineWrapping,d=c&&Math.max(5,a.display.scroller.clientWidth/tb(a.display)-3);return function(e){if(vd(a.doc,e))return 0;var f=0;if(e.widgets)for(var g=0;g<e.widgets.length;g++)e.widgets[g].height&&(f+=e.widgets[g].height);return c?f+(Math.ceil(e.text.length/d)||1)*b:f+b}}function g(a){var b=a.doc,c=f(a);b.iter(function(a){var b=c(a);b!=a.height&&_d(a,b)})}function h(a){a.display.wrapper.className=a.display.wrapper.className.replace(/\s*cm-s-\S+/g,"")+a.options.theme.replace(/(^|\s)\s*/g," cm-s-"),hb(a)}function i(a){j(a),Jb(a),setTimeout(function(){v(a)},20)}function j(a){var b=a.display.gutters,c=a.options.gutters;Qe(b);for(var d=0;d<c.length;++d){var e=c[d],f=b.appendChild(Pe("div",null,"CodeMirror-gutter "+e));"CodeMirror-linenumbers"==e&&(a.display.lineGutter=f,f.style.width=(a.display.lineNumWidth||1)+"px")}b.style.display=d?"":"none",k(a)}function k(a){var b=a.display.gutters.offsetWidth;a.display.sizer.style.marginLeft=b+"px"}function l(a){if(0==a.height)return 0;for(var b,c=a.text.length,d=a;b=od(d);){var e=b.find(0,!0);d=e.from.line,c+=e.from.ch-e.to.ch}for(d=a;b=pd(d);){var e=b.find(0,!0);c-=d.text.length-e.from.ch,d=e.to.line,c+=d.text.length-e.to.ch}return c}function m(a){var b=a.display,c=a.doc;b.maxLine=Yd(c,c.first),b.maxLineLength=l(b.maxLine),b.maxLineChanged=!0,c.iter(function(a){var c=l(a);c>b.maxLineLength&&(b.maxLineLength=c,b.maxLine=a)})}function n(a){var b=Ge(a.gutters,"CodeMirror-linenumbers");-1==b&&a.lineNumbers?a.gutters=a.gutters.concat(["CodeMirror-linenumbers"]):b>-1&&!a.lineNumbers&&(a.gutters=a.gutters.slice(0),a.gutters.splice(b,1))}function o(a){var b=a.display,c=b.gutters.offsetWidth,d=Math.round(a.doc.height+Sa(a.display));return{clientHeight:b.scroller.clientHeight,viewHeight:b.wrapper.clientHeight,scrollWidth:b.scroller.scrollWidth,clientWidth:b.scroller.clientWidth,viewWidth:b.wrapper.clientWidth,barLeft:a.options.fixedGutter?c:0,docHeight:d,scrollHeight:d+Ua(a)+b.barHeight,nativeBarWidth:b.nativeBarWidth,gutterWidth:c}}function p(a,b,c){this.cm=c;var d=this.vert=Pe("div",[Pe("div",null,null,"min-width: 1px")],"CodeMirror-vscrollbar"),e=this.horiz=Pe("div",[Pe("div",null,null,"height: 100%; min-height: 1px")],"CodeMirror-hscrollbar");a(d),a(e),Cg(d,"scroll",function(){d.clientHeight&&b(d.scrollTop,"vertical")}),Cg(e,"scroll",function(){e.clientWidth&&b(e.scrollLeft,"horizontal")}),this.checkedZeroWidth=!1,sf&&8>tf&&(this.horiz.style.minHeight=this.vert.style.minWidth="18px")}function q(){}function r(b){b.display.scrollbars&&(b.display.scrollbars.clear(),b.display.scrollbars.addClass&&Xg(b.display.wrapper,b.display.scrollbars.addClass)),b.display.scrollbars=new a.scrollbarModel[b.options.scrollbarStyle](function(a){b.display.wrapper.insertBefore(a,b.display.scrollbarFiller),Cg(a,"mousedown",function(){b.state.focused&&setTimeout(function(){b.display.input.focus()},0)}),a.setAttribute("cm-not-content","true")},function(a,c){"horizontal"==c?ec(b,a):dc(b,a)},b),b.display.scrollbars.addClass&&Yg(b.display.wrapper,b.display.scrollbars.addClass)}function s(a,b){b||(b=o(a));var c=a.display.barWidth,d=a.display.barHeight;t(a,b);for(var e=0;4>e&&c!=a.display.barWidth||d!=a.display.barHeight;e++)c!=a.display.barWidth&&a.options.lineWrapping&&F(a),t(a,o(a)),c=a.display.barWidth,d=a.display.barHeight}function t(a,b){var c=a.display,d=c.scrollbars.update(b);c.sizer.style.paddingRight=(c.barWidth=d.right)+"px",c.sizer.style.paddingBottom=(c.barHeight=d.bottom)+"px",d.right&&d.bottom?(c.scrollbarFiller.style.display="block",c.scrollbarFiller.style.height=d.bottom+"px",c.scrollbarFiller.style.width=d.right+"px"):c.scrollbarFiller.style.display="",d.bottom&&a.options.coverGutterNextToScrollbar&&a.options.fixedGutter?(c.gutterFiller.style.display="block",c.gutterFiller.style.height=d.bottom+"px",c.gutterFiller.style.width=b.gutterWidth+"px"):c.gutterFiller.style.display=""}function u(a,b,c){var d=c&&null!=c.top?Math.max(0,c.top):a.scroller.scrollTop;d=Math.floor(d-Ra(a));var e=c&&null!=c.bottom?c.bottom:d+a.wrapper.clientHeight,f=be(b,d),g=be(b,e);if(c&&c.ensure){var h=c.ensure.from.line,i=c.ensure.to.line;f>h?(f=h,g=be(b,ce(Yd(b,h))+a.wrapper.clientHeight)):Math.min(i,b.lastLine())>=g&&(f=be(b,ce(Yd(b,i))-a.wrapper.clientHeight),g=i)}return{from:f,to:Math.max(g,f+1)}}function v(a){var b=a.display,c=b.view;if(b.alignWidgets||b.gutters.firstChild&&a.options.fixedGutter){for(var d=y(b)-b.scroller.scrollLeft+a.doc.scrollLeft,e=b.gutters.offsetWidth,f=d+"px",g=0;g<c.length;g++)if(!c[g].hidden){a.options.fixedGutter&&c[g].gutter&&(c[g].gutter.style.left=f);var h=c[g].alignable;if(h)for(var i=0;i<h.length;i++)h[i].style.left=f}a.options.fixedGutter&&(b.gutters.style.left=d+e+"px")}}function w(a){if(!a.options.lineNumbers)return!1;var b=a.doc,c=x(a.options,b.first+b.size-1),d=a.display;if(c.length!=d.lineNumChars){var e=d.measure.appendChild(Pe("div",[Pe("div",c)],"CodeMirror-linenumber CodeMirror-gutter-elt")),f=e.firstChild.offsetWidth,g=e.offsetWidth-f;return d.lineGutter.style.width="",d.lineNumInnerWidth=Math.max(f,d.lineGutter.offsetWidth-g)+1,d.lineNumWidth=d.lineNumInnerWidth+g,d.lineNumChars=d.lineNumInnerWidth?c.length:-1,d.lineGutter.style.width=d.lineNumWidth+"px",k(a),!0}return!1}function x(a,b){return String(a.lineNumberFormatter(b+a.firstLineNumber))}function y(a){return a.scroller.getBoundingClientRect().left-a.sizer.getBoundingClientRect().left}function z(a,b,c){var d=a.display;this.viewport=b,this.visible=u(d,a.doc,b),this.editorIsHidden=!d.wrapper.offsetWidth,this.wrapperHeight=d.wrapper.clientHeight,this.wrapperWidth=d.wrapper.clientWidth,this.oldDisplayWidth=Va(a),this.force=c,this.dims=H(a),this.events=[]}function A(a){var b=a.display;!b.scrollbarsClipped&&b.scroller.offsetWidth&&(b.nativeBarWidth=b.scroller.offsetWidth-b.scroller.clientWidth,b.heightForcer.style.height=Ua(a)+"px",b.sizer.style.marginBottom=-b.nativeBarWidth+"px",b.sizer.style.borderRightWidth=Ua(a)+"px",b.scrollbarsClipped=!0)}function B(a,b){var c=a.display,d=a.doc;if(b.editorIsHidden)return Lb(a),!1;if(!b.force&&b.visible.from>=c.viewFrom&&b.visible.to<=c.viewTo&&(null==c.updateLineNumbers||c.updateLineNumbers>=c.viewTo)&&c.renderedView==c.view&&0==Pb(a))return!1;w(a)&&(Lb(a),b.dims=H(a));var e=d.first+d.size,f=Math.max(b.visible.from-a.options.viewportMargin,d.first),g=Math.min(e,b.visible.to+a.options.viewportMargin);c.viewFrom<f&&f-c.viewFrom<20&&(f=Math.max(d.first,c.viewFrom)),c.viewTo>g&&c.viewTo-g<20&&(g=Math.min(e,c.viewTo)),Jf&&(f=td(a.doc,f),g=ud(a.doc,g));var h=f!=c.viewFrom||g!=c.viewTo||c.lastWrapHeight!=b.wrapperHeight||c.lastWrapWidth!=b.wrapperWidth;Ob(a,f,g),c.viewOffset=ce(Yd(a.doc,c.viewFrom)),a.display.mover.style.top=c.viewOffset+"px";var i=Pb(a);if(!h&&0==i&&!b.force&&c.renderedView==c.view&&(null==c.updateLineNumbers||c.updateLineNumbers>=c.viewTo))return!1;var j=Se();return i>4&&(c.lineDiv.style.display="none"),I(a,c.updateLineNumbers,b.dims),i>4&&(c.lineDiv.style.display=""),c.renderedView=c.view,j&&Se()!=j&&j.offsetHeight&&j.focus(),Qe(c.cursorDiv),Qe(c.selectionDiv),c.gutters.style.height=c.sizer.style.minHeight=0,h&&(c.lastWrapHeight=b.wrapperHeight,c.lastWrapWidth=b.wrapperWidth,Na(a,400)),c.updateLineNumbers=null,!0}function C(a,b){for(var c=b.viewport,d=!0;(d&&a.options.lineWrapping&&b.oldDisplayWidth!=Va(a)||(c&&null!=c.top&&(c={top:Math.min(a.doc.height+Sa(a.display)-Wa(a),c.top)}),b.visible=u(a.display,a.doc,c),!(b.visible.from>=a.display.viewFrom&&b.visible.to<=a.display.viewTo)))&&B(a,b);d=!1){F(a);var e=o(a);Ia(a),E(a,e),s(a,e)}b.signal(a,"update",a),(a.display.viewFrom!=a.display.reportedViewFrom||a.display.viewTo!=a.display.reportedViewTo)&&(b.signal(a,"viewportChange",a,a.display.viewFrom,a.display.viewTo),a.display.reportedViewFrom=a.display.viewFrom,a.display.reportedViewTo=a.display.viewTo)}function D(a,b){var c=new z(a,b);if(B(a,c)){F(a),C(a,c);var d=o(a);Ia(a),E(a,d),s(a,d),c.finish()}}function E(a,b){a.display.sizer.style.minHeight=b.docHeight+"px";var c=b.docHeight+a.display.barHeight;a.display.heightForcer.style.top=c+"px",a.display.gutters.style.height=Math.max(c+Ua(a),b.clientHeight)+"px"}function F(a){for(var b=a.display,c=b.lineDiv.offsetTop,d=0;d<b.view.length;d++){var e,f=b.view[d];if(!f.hidden){if(sf&&8>tf){var g=f.node.offsetTop+f.node.offsetHeight;e=g-c,c=g}else{var h=f.node.getBoundingClientRect();e=h.bottom-h.top}var i=f.line.height-e;if(2>e&&(e=sb(b)),(i>.001||-.001>i)&&(_d(f.line,e),G(f.line),f.rest))for(var j=0;j<f.rest.length;j++)G(f.rest[j])}}}function G(a){if(a.widgets)for(var b=0;b<a.widgets.length;++b)a.widgets[b].height=a.widgets[b].node.parentNode.offsetHeight}function H(a){for(var b=a.display,c={},d={},e=b.gutters.clientLeft,f=b.gutters.firstChild,g=0;f;f=f.nextSibling,++g)c[a.options.gutters[g]]=f.offsetLeft+f.clientLeft+e,d[a.options.gutters[g]]=f.clientWidth;return{fixedPos:y(b),gutterTotalWidth:b.gutters.offsetWidth,gutterLeft:c,gutterWidth:d,wrapperWidth:b.wrapper.clientWidth}}function I(a,b,c){function d(b){var c=b.nextSibling;return uf&&Df&&a.display.currentWheelTarget==b?b.style.display="none":b.parentNode.removeChild(b),c}for(var e=a.display,f=a.options.lineNumbers,g=e.lineDiv,h=g.firstChild,i=e.view,j=e.viewFrom,k=0;k<i.length;k++){var l=i[k];if(l.hidden);else if(l.node&&l.node.parentNode==g){for(;h!=l.node;)h=d(h);var m=f&&null!=b&&j>=b&&l.lineNumber;l.changes&&(Ge(l.changes,"gutter")>-1&&(m=!1),J(a,l,j,c)),m&&(Qe(l.lineNumber),l.lineNumber.appendChild(document.createTextNode(x(a.options,j)))),h=l.node.nextSibling}else{var n=R(a,l,j,c);g.insertBefore(n,h)}j+=l.size}for(;h;)h=d(h)}function J(a,b,c,d){for(var e=0;e<b.changes.length;e++){var f=b.changes[e];"text"==f?N(a,b):"gutter"==f?P(a,b,c,d):"class"==f?O(b):"widget"==f&&Q(a,b,d)}b.changes=null}function K(a){return a.node==a.text&&(a.node=Pe("div",null,null,"position: relative"),a.text.parentNode&&a.text.parentNode.replaceChild(a.node,a.text),a.node.appendChild(a.text),sf&&8>tf&&(a.node.style.zIndex=2)),a.node}function L(a){var b=a.bgClass?a.bgClass+" "+(a.line.bgClass||""):a.line.bgClass;if(b&&(b+=" CodeMirror-linebackground"),a.background)b?a.background.className=b:(a.background.parentNode.removeChild(a.background),a.background=null);else if(b){var c=K(a);a.background=c.insertBefore(Pe("div",null,b),c.firstChild)}}function M(a,b){var c=a.display.externalMeasured;return c&&c.line==b.line?(a.display.externalMeasured=null,b.measure=c.measure,c.built):Ld(a,b)}function N(a,b){var c=b.text.className,d=M(a,b);b.text==b.node&&(b.node=d.pre),b.text.parentNode.replaceChild(d.pre,b.text),b.text=d.pre,d.bgClass!=b.bgClass||d.textClass!=b.textClass?(b.bgClass=d.bgClass,b.textClass=d.textClass,O(b)):c&&(b.text.className=c)}function O(a){L(a),a.line.wrapClass?K(a).className=a.line.wrapClass:a.node!=a.text&&(a.node.className="");var b=a.textClass?a.textClass+" "+(a.line.textClass||""):a.line.textClass;a.text.className=b||""}function P(a,b,c,d){if(b.gutter&&(b.node.removeChild(b.gutter),b.gutter=null),b.gutterBackground&&(b.node.removeChild(b.gutterBackground),b.gutterBackground=null),b.line.gutterClass){var e=K(b);b.gutterBackground=Pe("div",null,"CodeMirror-gutter-background "+b.line.gutterClass,"left: "+(a.options.fixedGutter?d.fixedPos:-d.gutterTotalWidth)+"px; width: "+d.gutterTotalWidth+"px"),e.insertBefore(b.gutterBackground,b.text)}var f=b.line.gutterMarkers;if(a.options.lineNumbers||f){var e=K(b),g=b.gutter=Pe("div",null,"CodeMirror-gutter-wrapper","left: "+(a.options.fixedGutter?d.fixedPos:-d.gutterTotalWidth)+"px");if(a.display.input.setUneditable(g),e.insertBefore(g,b.text),b.line.gutterClass&&(g.className+=" "+b.line.gutterClass),!a.options.lineNumbers||f&&f["CodeMirror-linenumbers"]||(b.lineNumber=g.appendChild(Pe("div",x(a.options,c),"CodeMirror-linenumber CodeMirror-gutter-elt","left: "+d.gutterLeft["CodeMirror-linenumbers"]+"px; width: "+a.display.lineNumInnerWidth+"px"))),f)for(var h=0;h<a.options.gutters.length;++h){var i=a.options.gutters[h],j=f.hasOwnProperty(i)&&f[i];j&&g.appendChild(Pe("div",[j],"CodeMirror-gutter-elt","left: "+d.gutterLeft[i]+"px; width: "+d.gutterWidth[i]+"px"))}}}function Q(a,b,c){b.alignable&&(b.alignable=null);for(var d,e=b.node.firstChild;e;e=d){var d=e.nextSibling;"CodeMirror-linewidget"==e.className&&b.node.removeChild(e)}S(a,b,c)}function R(a,b,c,d){var e=M(a,b);return b.text=b.node=e.pre,e.bgClass&&(b.bgClass=e.bgClass),e.textClass&&(b.textClass=e.textClass),O(b),P(a,b,c,d),S(a,b,d),b.node}function S(a,b,c){if(T(a,b.line,b,c,!0),b.rest)for(var d=0;d<b.rest.length;d++)T(a,b.rest[d],b,c,!1)}function T(a,b,c,d,e){if(b.widgets)for(var f=K(c),g=0,h=b.widgets;g<h.length;++g){var i=h[g],j=Pe("div",[i.node],"CodeMirror-linewidget");i.handleMouseEvents||j.setAttribute("cm-ignore-events","true"),U(i,j,c,d),a.display.input.setUneditable(j),e&&i.above?f.insertBefore(j,c.gutter||c.text):f.appendChild(j),xe(i,"redraw")}}function U(a,b,c,d){if(a.noHScroll){(c.alignable||(c.alignable=[])).push(b);var e=d.wrapperWidth;b.style.left=d.fixedPos+"px",a.coverGutter||(e-=d.gutterTotalWidth,b.style.paddingLeft=d.gutterTotalWidth+"px"),b.style.width=e+"px"}a.coverGutter&&(b.style.zIndex=5,b.style.position="relative",a.noHScroll||(b.style.marginLeft=-d.gutterTotalWidth+"px"))}function V(a){return Kf(a.line,a.ch)}function W(a,b){return Lf(a,b)<0?b:a}function X(a,b){return Lf(a,b)<0?a:b}function Y(a){a.state.focused||(a.display.input.focus(),qc(a))}function Z(a,b,c,d,e){var f=a.doc;a.display.shift=!1,d||(d=f.sel);var g=a.state.pasteIncoming||"paste"==e,h=f.splitLines(b),i=null;if(g&&d.ranges.length>1)if(Mf&&Mf.join("\n")==b){if(d.ranges.length%Mf.length==0){i=[];for(var j=0;j<Mf.length;j++)i.push(f.splitLines(Mf[j]))}}else h.length==d.ranges.length&&(i=He(h,function(a){return[a]}));for(var j=d.ranges.length-1;j>=0;j--){var k=d.ranges[j],l=k.from(),m=k.to();k.empty()&&(c&&c>0?l=Kf(l.line,l.ch-c):a.state.overwrite&&!g&&(m=Kf(m.line,Math.min(Yd(f,m.line).text.length,m.ch+Fe(h).length))));var n=a.curOp.updateInput,o={from:l,to:m,text:i?i[j%i.length]:h,origin:e||(g?"paste":a.state.cutIncoming?"cut":"+input")};zc(a.doc,o),xe(a,"inputRead",a,o)}b&&!g&&_(a,b),Lc(a),a.curOp.updateInput=n,a.curOp.typing=!0,a.state.pasteIncoming=a.state.cutIncoming=!1}function $(a,b){var c=a.clipboardData&&a.clipboardData.getData("text/plain");return c?(a.preventDefault(),b.isReadOnly()||b.options.disableInput||Db(b,function(){Z(b,c,0,null,"paste")}),!0):void 0}function _(a,b){if(a.options.electricChars&&a.options.smartIndent)for(var c=a.doc.sel,d=c.ranges.length-1;d>=0;d--){var e=c.ranges[d];if(!(e.head.ch>100||d&&c.ranges[d-1].head.line==e.head.line)){var f=a.getModeAt(e.head),g=!1;if(f.electricChars){for(var h=0;h<f.electricChars.length;h++)if(b.indexOf(f.electricChars.charAt(h))>-1){g=Nc(a,e.head.line,"smart");break}}else f.electricInput&&f.electricInput.test(Yd(a.doc,e.head.line).text.slice(0,e.head.ch))&&(g=Nc(a,e.head.line,"smart"));g&&xe(a,"electricInput",a,e.head.line)}}}function aa(a){for(var b=[],c=[],d=0;d<a.doc.sel.ranges.length;d++){var e=a.doc.sel.ranges[d].head.line,f={anchor:Kf(e,0),head:Kf(e+1,0)};c.push(f),b.push(a.getRange(f.anchor,f.head))}return{text:b,ranges:c}}function ba(a){a.setAttribute("autocorrect","off"),a.setAttribute("autocapitalize","off"),a.setAttribute("spellcheck","false")}function ca(a){this.cm=a,this.prevInput="",this.pollingFast=!1,this.polling=new De,this.inaccurateSelection=!1,this.hasSelection=!1,this.composing=null}function da(){var a=Pe("textarea",null,null,"position: absolute; padding: 0; width: 1px; height: 1em; outline: none"),b=Pe("div",[a],null,"overflow: hidden; position: relative; width: 3px; height: 0px;");return uf?a.style.width="1000px":a.setAttribute("wrap","off"),Bf&&(a.style.border="1px solid black"),ba(a),b}function ea(a){this.cm=a,this.lastAnchorNode=this.lastAnchorOffset=this.lastFocusNode=this.lastFocusOffset=null,this.polling=new De,this.gracePeriod=!1}function fa(a,b){var c=_a(a,b.line);if(!c||c.hidden)return null;var d=Yd(a.doc,b.line),e=Ya(c,d,b.line),f=de(d),g="left";if(f){var h=jf(f,b.ch);g=h%2?"right":"left"}var i=cb(e.map,b.ch,g);return i.offset="right"==i.collapse?i.end:i.start,i}function ga(a,b){return b&&(a.bad=!0),a}function ha(a,b,c){var d;if(b==a.display.lineDiv){if(d=a.display.lineDiv.childNodes[c],!d)return ga(a.clipPos(Kf(a.display.viewTo-1)),!0);b=null,c=0}else for(d=b;;d=d.parentNode){if(!d||d==a.display.lineDiv)return null;if(d.parentNode&&d.parentNode==a.display.lineDiv)break}for(var e=0;e<a.display.view.length;e++){var f=a.display.view[e];if(f.node==d)return ia(f,b,c)}}function ia(a,b,c){function d(b,c,d){for(var e=-1;e<(k?k.length:0);e++)for(var f=0>e?j.map:k[e],g=0;g<f.length;g+=3){var h=f[g+2];if(h==b||h==c){var i=ae(0>e?a.line:a.rest[e]),l=f[g]+d;return(0>d||h!=b)&&(l=f[g+(d?1:0)]),Kf(i,l)}}}var e=a.text.firstChild,f=!1;if(!b||!Ug(e,b))return ga(Kf(ae(a.line),0),!0);if(b==e&&(f=!0,b=e.childNodes[c],c=0,!b)){var g=a.rest?Fe(a.rest):a.line;return ga(Kf(ae(g),g.text.length),f)}var h=3==b.nodeType?b:null,i=b;for(h||1!=b.childNodes.length||3!=b.firstChild.nodeType||(h=b.firstChild,c&&(c=h.nodeValue.length));i.parentNode!=e;)i=i.parentNode;var j=a.measure,k=j.maps,l=d(h,i,c);if(l)return ga(l,f);for(var m=i.nextSibling,n=h?h.nodeValue.length-c:0;m;m=m.nextSibling){if(l=d(m,m.firstChild,0))return ga(Kf(l.line,l.ch-n),f);n+=m.textContent.length}for(var o=i.previousSibling,n=c;o;o=o.previousSibling){if(l=d(o,o.firstChild,-1))return ga(Kf(l.line,l.ch+n),f);n+=m.textContent.length}}function ja(a,b,c,d,e){function f(a){return function(b){return b.id==a}}function g(b){if(1==b.nodeType){var c=b.getAttribute("cm-text");if(null!=c)return""==c&&(c=b.textContent.replace(/\u200b/g,"")),void(h+=c);var k,l=b.getAttribute("cm-marker");if(l){var m=a.findMarks(Kf(d,0),Kf(e+1,0),f(+l));return void(m.length&&(k=m[0].find())&&(h+=Zd(a.doc,k.from,k.to).join(j)))}if("false"==b.getAttribute("contenteditable"))return;for(var n=0;n<b.childNodes.length;n++)g(b.childNodes[n]);/^(pre|div|p)$/i.test(b.nodeName)&&(i=!0)}else if(3==b.nodeType){var o=b.nodeValue;if(!o)return;i&&(h+=j,i=!1),h+=o}}for(var h="",i=!1,j=a.doc.lineSeparator();g(b),b!=c;)b=b.nextSibling;return h}function ka(a,b){this.ranges=a,this.primIndex=b}function la(a,b){this.anchor=a,this.head=b}function ma(a,b){var c=a[b];a.sort(function(a,b){return Lf(a.from(),b.from())}),b=Ge(a,c);for(var d=1;d<a.length;d++){var e=a[d],f=a[d-1];if(Lf(f.to(),e.from())>=0){var g=X(f.from(),e.from()),h=W(f.to(),e.to()),i=f.empty()?e.from()==e.head:f.from()==f.head;b>=d&&--b,a.splice(--d,2,new la(i?h:g,i?g:h))}}return new ka(a,b)}function na(a,b){return new ka([new la(a,b||a)],0)}function oa(a,b){return Math.max(a.first,Math.min(b,a.first+a.size-1))}function pa(a,b){if(b.line<a.first)return Kf(a.first,0);var c=a.first+a.size-1;return b.line>c?Kf(c,Yd(a,c).text.length):qa(b,Yd(a,b.line).text.length)}function qa(a,b){var c=a.ch;return null==c||c>b?Kf(a.line,b):0>c?Kf(a.line,0):a}function ra(a,b){return b>=a.first&&b<a.first+a.size}function sa(a,b){for(var c=[],d=0;d<b.length;d++)c[d]=pa(a,b[d]);return c}function ta(a,b,c,d){if(a.cm&&a.cm.display.shift||a.extend){var e=b.anchor;if(d){var f=Lf(c,e)<0;f!=Lf(d,e)<0?(e=c,c=d):f!=Lf(c,d)<0&&(c=d)}return new la(e,c)}return new la(d||c,c)}function ua(a,b,c,d){Aa(a,new ka([ta(a,a.sel.primary(),b,c)],0),d)}function va(a,b,c){for(var d=[],e=0;e<a.sel.ranges.length;e++)d[e]=ta(a,a.sel.ranges[e],b[e],null);var f=ma(d,a.sel.primIndex);Aa(a,f,c)}function wa(a,b,c,d){var e=a.sel.ranges.slice(0);e[b]=c,Aa(a,ma(e,a.sel.primIndex),d)}function xa(a,b,c,d){Aa(a,na(b,c),d)}function ya(a,b,c){var d={ranges:b.ranges,update:function(b){this.ranges=[];for(var c=0;c<b.length;c++)this.ranges[c]=new la(pa(a,b[c].anchor),pa(a,b[c].head))},origin:c&&c.origin};return Fg(a,"beforeSelectionChange",a,d),a.cm&&Fg(a.cm,"beforeSelectionChange",a.cm,d),d.ranges!=b.ranges?ma(d.ranges,d.ranges.length-1):b}function za(a,b,c){var d=a.history.done,e=Fe(d);e&&e.ranges?(d[d.length-1]=b,Ba(a,b,c)):Aa(a,b,c)}function Aa(a,b,c){Ba(a,b,c),ke(a,a.sel,a.cm?a.cm.curOp.id:NaN,c)}function Ba(a,b,c){(Be(a,"beforeSelectionChange")||a.cm&&Be(a.cm,"beforeSelectionChange"))&&(b=ya(a,b,c));var d=c&&c.bias||(Lf(b.primary().head,a.sel.primary().head)<0?-1:1);Ca(a,Ea(a,b,d,!0)),c&&c.scroll===!1||!a.cm||Lc(a.cm)}function Ca(a,b){b.equals(a.sel)||(a.sel=b,a.cm&&(a.cm.curOp.updateInput=a.cm.curOp.selectionChanged=!0,Ae(a.cm)),xe(a,"cursorActivity",a))}function Da(a){Ca(a,Ea(a,a.sel,null,!1),Jg)}function Ea(a,b,c,d){for(var e,f=0;f<b.ranges.length;f++){var g=b.ranges[f],h=b.ranges.length==a.sel.ranges.length&&a.sel.ranges[f],i=Ga(a,g.anchor,h&&h.anchor,c,d),j=Ga(a,g.head,h&&h.head,c,d);(e||i!=g.anchor||j!=g.head)&&(e||(e=b.ranges.slice(0,f)),e[f]=new la(i,j))}return e?ma(e,b.primIndex):b}function Fa(a,b,c,d,e){var f=Yd(a,b.line);if(f.markedSpans)for(var g=0;g<f.markedSpans.length;++g){var h=f.markedSpans[g],i=h.marker;if((null==h.from||(i.inclusiveLeft?h.from<=b.ch:h.from<b.ch))&&(null==h.to||(i.inclusiveRight?h.to>=b.ch:h.to>b.ch))){if(e&&(Fg(i,"beforeCursorEnter"),i.explicitlyCleared)){if(f.markedSpans){--g;continue}break}if(!i.atomic)continue;if(c){var j,k=i.find(0>d?1:-1);if((0>d?i.inclusiveRight:i.inclusiveLeft)&&(k=Ha(a,k,-d,f)),k&&k.line==b.line&&(j=Lf(k,c))&&(0>d?0>j:j>0))return Fa(a,k,b,d,e)}var l=i.find(0>d?-1:1);return(0>d?i.inclusiveLeft:i.inclusiveRight)&&(l=Ha(a,l,d,f)),l?Fa(a,l,b,d,e):null}}return b}function Ga(a,b,c,d,e){var f=d||1,g=Fa(a,b,c,f,e)||!e&&Fa(a,b,c,f,!0)||Fa(a,b,c,-f,e)||!e&&Fa(a,b,c,-f,!0);return g?g:(a.cantEdit=!0,Kf(a.first,0))}function Ha(a,b,c,d){return 0>c&&0==b.ch?b.line>a.first?pa(a,Kf(b.line-1)):null:c>0&&b.ch==(d||Yd(a,b.line)).text.length?b.line<a.first+a.size-1?Kf(b.line+1,0):null:new Kf(b.line,b.ch+c)}function Ia(a){a.display.input.showSelection(a.display.input.prepareSelection())}function Ja(a,b){for(var c=a.doc,d={},e=d.cursors=document.createDocumentFragment(),f=d.selection=document.createDocumentFragment(),g=0;g<c.sel.ranges.length;g++)if(b!==!1||g!=c.sel.primIndex){var h=c.sel.ranges[g],i=h.empty();(i||a.options.showCursorWhenSelecting)&&Ka(a,h.head,e),i||La(a,h,f)}return d}function Ka(a,b,c){var d=nb(a,b,"div",null,null,!a.options.singleCursorHeightPerLine),e=c.appendChild(Pe("div"," ","CodeMirror-cursor"));if(e.style.left=d.left+"px",e.style.top=d.top+"px",e.style.height=Math.max(0,d.bottom-d.top)*a.options.cursorHeight+"px",d.other){var f=c.appendChild(Pe("div"," ","CodeMirror-cursor CodeMirror-secondarycursor"));f.style.display="",f.style.left=d.other.left+"px",f.style.top=d.other.top+"px",f.style.height=.85*(d.other.bottom-d.other.top)+"px"}}function La(a,b,c){function d(a,b,c,d){0>b&&(b=0),b=Math.round(b),d=Math.round(d),h.appendChild(Pe("div",null,"CodeMirror-selected","position: absolute; left: "+a+"px; top: "+b+"px; width: "+(null==c?k-a:c)+"px; height: "+(d-b)+"px"))}function e(b,c,e){function f(c,d){return mb(a,Kf(b,c),"div",l,d)}var h,i,l=Yd(g,b),m=l.text.length;return _e(de(l),c||0,null==e?m:e,function(a,b,g){var l,n,o,p=f(a,"left");if(a==b)l=p,n=o=p.left;else{if(l=f(b-1,"right"),"rtl"==g){var q=p;p=l,l=q}n=p.left,o=l.right}null==c&&0==a&&(n=j),l.top-p.top>3&&(d(n,p.top,null,p.bottom),n=j,p.bottom<l.top&&d(n,p.bottom,null,l.top)),null==e&&b==m&&(o=k),(!h||p.top<h.top||p.top==h.top&&p.left<h.left)&&(h=p),(!i||l.bottom>i.bottom||l.bottom==i.bottom&&l.right>i.right)&&(i=l),j+1>n&&(n=j),d(n,l.top,o-n,l.bottom)}),{start:h,end:i}}var f=a.display,g=a.doc,h=document.createDocumentFragment(),i=Ta(a.display),j=i.left,k=Math.max(f.sizerWidth,Va(a)-f.sizer.offsetLeft)-i.right,l=b.from(),m=b.to();if(l.line==m.line)e(l.line,l.ch,m.ch);else{var n=Yd(g,l.line),o=Yd(g,m.line),p=rd(n)==rd(o),q=e(l.line,l.ch,p?n.text.length+1:null).end,r=e(m.line,p?0:null,m.ch).start;p&&(q.top<r.top-2?(d(q.right,q.top,null,q.bottom),d(j,r.top,r.left,r.bottom)):d(q.right,q.top,r.left-q.right,q.bottom)),q.bottom<r.top&&d(j,q.bottom,null,r.top)}c.appendChild(h)}function Ma(a){if(a.state.focused){var b=a.display;clearInterval(b.blinker);var c=!0;b.cursorDiv.style.visibility="",a.options.cursorBlinkRate>0?b.blinker=setInterval(function(){b.cursorDiv.style.visibility=(c=!c)?"":"hidden"},a.options.cursorBlinkRate):a.options.cursorBlinkRate<0&&(b.cursorDiv.style.visibility="hidden")}}function Na(a,b){a.doc.mode.startState&&a.doc.frontier<a.display.viewTo&&a.state.highlight.set(b,Le(Oa,a))}function Oa(a){var b=a.doc;if(b.frontier<b.first&&(b.frontier=b.first),!(b.frontier>=a.display.viewTo)){var c=+new Date+a.options.workTime,d=gg(b.mode,Qa(a,b.frontier)),e=[];b.iter(b.frontier,Math.min(b.first+b.size,a.display.viewTo+500),function(f){if(b.frontier>=a.display.viewFrom){var g=f.styles,h=f.text.length>a.options.maxHighlightLength,i=Hd(a,f,h?gg(b.mode,d):d,!0);f.styles=i.styles;var j=f.styleClasses,k=i.classes;k?f.styleClasses=k:j&&(f.styleClasses=null);for(var l=!g||g.length!=f.styles.length||j!=k&&(!j||!k||j.bgClass!=k.bgClass||j.textClass!=k.textClass),m=0;!l&&m<g.length;++m)l=g[m]!=f.styles[m];l&&e.push(b.frontier),f.stateAfter=h?d:gg(b.mode,d)}else f.text.length<=a.options.maxHighlightLength&&Jd(a,f.text,d),f.stateAfter=b.frontier%5==0?gg(b.mode,d):null;return++b.frontier,+new Date>c?(Na(a,a.options.workDelay),!0):void 0}),e.length&&Db(a,function(){for(var b=0;b<e.length;b++)Kb(a,e[b],"text")})}}function Pa(a,b,c){for(var d,e,f=a.doc,g=c?-1:b-(a.doc.mode.innerMode?1e3:100),h=b;h>g;--h){if(h<=f.first)return f.first;var i=Yd(f,h-1);if(i.stateAfter&&(!c||h<=f.frontier))return h;var j=Mg(i.text,null,a.options.tabSize);(null==e||d>j)&&(e=h-1,d=j)}return e}function Qa(a,b,c){var d=a.doc,e=a.display;if(!d.mode.startState)return!0;var f=Pa(a,b,c),g=f>d.first&&Yd(d,f-1).stateAfter;return g=g?gg(d.mode,g):hg(d.mode),d.iter(f,b,function(c){Jd(a,c.text,g);var h=f==b-1||f%5==0||f>=e.viewFrom&&f<e.viewTo;c.stateAfter=h?gg(d.mode,g):null,++f}),c&&(d.frontier=f),g}function Ra(a){return a.lineSpace.offsetTop}function Sa(a){return a.mover.offsetHeight-a.lineSpace.offsetHeight}function Ta(a){if(a.cachedPaddingH)return a.cachedPaddingH;var b=Re(a.measure,Pe("pre","x")),c=window.getComputedStyle?window.getComputedStyle(b):b.currentStyle,d={left:parseInt(c.paddingLeft),right:parseInt(c.paddingRight)};return isNaN(d.left)||isNaN(d.right)||(a.cachedPaddingH=d),d}function Ua(a){return Hg-a.display.nativeBarWidth}function Va(a){return a.display.scroller.clientWidth-Ua(a)-a.display.barWidth}function Wa(a){return a.display.scroller.clientHeight-Ua(a)-a.display.barHeight}function Xa(a,b,c){var d=a.options.lineWrapping,e=d&&Va(a);if(!b.measure.heights||d&&b.measure.width!=e){var f=b.measure.heights=[];if(d){b.measure.width=e;for(var g=b.text.firstChild.getClientRects(),h=0;h<g.length-1;h++){var i=g[h],j=g[h+1];Math.abs(i.bottom-j.bottom)>2&&f.push((i.bottom+j.top)/2-c.top)}}f.push(c.bottom-c.top)}}function Ya(a,b,c){if(a.line==b)return{map:a.measure.map,cache:a.measure.cache};for(var d=0;d<a.rest.length;d++)if(a.rest[d]==b)return{map:a.measure.maps[d],cache:a.measure.caches[d]};for(var d=0;d<a.rest.length;d++)if(ae(a.rest[d])>c)return{map:a.measure.maps[d],cache:a.measure.caches[d],before:!0}}function Za(a,b){b=rd(b);var c=ae(b),d=a.display.externalMeasured=new Hb(a.doc,b,c);d.lineN=c;var e=d.built=Ld(a,d);return d.text=e.pre,Re(a.display.lineMeasure,e.pre),d}function $a(a,b,c,d){return bb(a,ab(a,b),c,d)}function _a(a,b){if(b>=a.display.viewFrom&&b<a.display.viewTo)return a.display.view[Mb(a,b)];var c=a.display.externalMeasured;return c&&b>=c.lineN&&b<c.lineN+c.size?c:void 0}function ab(a,b){var c=ae(b),d=_a(a,c);d&&!d.text?d=null:d&&d.changes&&(J(a,d,c,H(a)),a.curOp.forceUpdate=!0),d||(d=Za(a,b));var e=Ya(d,b,c);return{line:b,view:d,rect:null,map:e.map,cache:e.cache,before:e.before,hasHeights:!1}}function bb(a,b,c,d,e){b.before&&(c=-1);var f,g=c+(d||"");return b.cache.hasOwnProperty(g)?f=b.cache[g]:(b.rect||(b.rect=b.view.text.getBoundingClientRect()),b.hasHeights||(Xa(a,b.view,b.rect),b.hasHeights=!0),f=db(a,b,c,d),f.bogus||(b.cache[g]=f)),{left:f.left,right:f.right,top:e?f.rtop:f.top,bottom:e?f.rbottom:f.bottom}}function cb(a,b,c){for(var d,e,f,g,h=0;h<a.length;h+=3){var i=a[h],j=a[h+1];if(i>b?(e=0,f=1,g="left"):j>b?(e=b-i,f=e+1):(h==a.length-3||b==j&&a[h+3]>b)&&(f=j-i,e=f-1,b>=j&&(g="right")),null!=e){if(d=a[h+2],i==j&&c==(d.insertLeft?"left":"right")&&(g=c),"left"==c&&0==e)for(;h&&a[h-2]==a[h-3]&&a[h-1].insertLeft;)d=a[(h-=3)+2],g="left";if("right"==c&&e==j-i)for(;h<a.length-3&&a[h+3]==a[h+4]&&!a[h+5].insertLeft;)d=a[(h+=3)+2],
2
+ g="right";break}}return{node:d,start:e,end:f,collapse:g,coverStart:i,coverEnd:j}}function db(a,b,c,d){var e,f=cb(b.map,c,d),g=f.node,h=f.start,i=f.end,j=f.collapse;if(3==g.nodeType){for(var k=0;4>k;k++){for(;h&&Oe(b.line.text.charAt(f.coverStart+h));)--h;for(;f.coverStart+i<f.coverEnd&&Oe(b.line.text.charAt(f.coverStart+i));)++i;if(sf&&9>tf&&0==h&&i==f.coverEnd-f.coverStart)e=g.parentNode.getBoundingClientRect();else if(sf&&a.options.lineWrapping){var l=Qg(g,h,i).getClientRects();e=l.length?l["right"==d?l.length-1:0]:Qf}else e=Qg(g,h,i).getBoundingClientRect()||Qf;if(e.left||e.right||0==h)break;i=h,h-=1,j="right"}sf&&11>tf&&(e=eb(a.display.measure,e))}else{h>0&&(j=d="right");var l;e=a.options.lineWrapping&&(l=g.getClientRects()).length>1?l["right"==d?l.length-1:0]:g.getBoundingClientRect()}if(sf&&9>tf&&!h&&(!e||!e.left&&!e.right)){var m=g.parentNode.getClientRects()[0];e=m?{left:m.left,right:m.left+tb(a.display),top:m.top,bottom:m.bottom}:Qf}for(var n=e.top-b.rect.top,o=e.bottom-b.rect.top,p=(n+o)/2,q=b.view.measure.heights,k=0;k<q.length-1&&!(p<q[k]);k++);var r=k?q[k-1]:0,s=q[k],t={left:("right"==j?e.right:e.left)-b.rect.left,right:("left"==j?e.left:e.right)-b.rect.left,top:r,bottom:s};return e.left||e.right||(t.bogus=!0),a.options.singleCursorHeightPerLine||(t.rtop=n,t.rbottom=o),t}function eb(a,b){if(!window.screen||null==screen.logicalXDPI||screen.logicalXDPI==screen.deviceXDPI||!$e(a))return b;var c=screen.logicalXDPI/screen.deviceXDPI,d=screen.logicalYDPI/screen.deviceYDPI;return{left:b.left*c,right:b.right*c,top:b.top*d,bottom:b.bottom*d}}function fb(a){if(a.measure&&(a.measure.cache={},a.measure.heights=null,a.rest))for(var b=0;b<a.rest.length;b++)a.measure.caches[b]={}}function gb(a){a.display.externalMeasure=null,Qe(a.display.lineMeasure);for(var b=0;b<a.display.view.length;b++)fb(a.display.view[b])}function hb(a){gb(a),a.display.cachedCharWidth=a.display.cachedTextHeight=a.display.cachedPaddingH=null,a.options.lineWrapping||(a.display.maxLineChanged=!0),a.display.lineNumChars=null}function ib(){return window.pageXOffset||(document.documentElement||document.body).scrollLeft}function jb(){return window.pageYOffset||(document.documentElement||document.body).scrollTop}function kb(a,b,c,d){if(b.widgets)for(var e=0;e<b.widgets.length;++e)if(b.widgets[e].above){var f=yd(b.widgets[e]);c.top+=f,c.bottom+=f}if("line"==d)return c;d||(d="local");var g=ce(b);if("local"==d?g+=Ra(a.display):g-=a.display.viewOffset,"page"==d||"window"==d){var h=a.display.lineSpace.getBoundingClientRect();g+=h.top+("window"==d?0:jb());var i=h.left+("window"==d?0:ib());c.left+=i,c.right+=i}return c.top+=g,c.bottom+=g,c}function lb(a,b,c){if("div"==c)return b;var d=b.left,e=b.top;if("page"==c)d-=ib(),e-=jb();else if("local"==c||!c){var f=a.display.sizer.getBoundingClientRect();d+=f.left,e+=f.top}var g=a.display.lineSpace.getBoundingClientRect();return{left:d-g.left,top:e-g.top}}function mb(a,b,c,d,e){return d||(d=Yd(a.doc,b.line)),kb(a,d,$a(a,d,b.ch,e),c)}function nb(a,b,c,d,e,f){function g(b,g){var h=bb(a,e,b,g?"right":"left",f);return g?h.left=h.right:h.right=h.left,kb(a,d,h,c)}function h(a,b){var c=i[b],d=c.level%2;return a==af(c)&&b&&c.level<i[b-1].level?(c=i[--b],a=bf(c)-(c.level%2?0:1),d=!0):a==bf(c)&&b<i.length-1&&c.level<i[b+1].level&&(c=i[++b],a=af(c)-c.level%2,d=!1),d&&a==c.to&&a>c.from?g(a-1):g(a,d)}d=d||Yd(a.doc,b.line),e||(e=ab(a,d));var i=de(d),j=b.ch;if(!i)return g(j);var k=jf(i,j),l=h(j,k);return null!=eh&&(l.other=h(j,eh)),l}function ob(a,b){var c=0,b=pa(a.doc,b);a.options.lineWrapping||(c=tb(a.display)*b.ch);var d=Yd(a.doc,b.line),e=ce(d)+Ra(a.display);return{left:c,right:c,top:e,bottom:e+d.height}}function pb(a,b,c,d){var e=Kf(a,b);return e.xRel=d,c&&(e.outside=!0),e}function qb(a,b,c){var d=a.doc;if(c+=a.display.viewOffset,0>c)return pb(d.first,0,!0,-1);var e=be(d,c),f=d.first+d.size-1;if(e>f)return pb(d.first+d.size-1,Yd(d,f).text.length,!0,1);0>b&&(b=0);for(var g=Yd(d,e);;){var h=rb(a,g,e,b,c),i=pd(g),j=i&&i.find(0,!0);if(!i||!(h.ch>j.from.ch||h.ch==j.from.ch&&h.xRel>0))return h;e=ae(g=j.to.line)}}function rb(a,b,c,d,e){function f(d){var e=nb(a,Kf(c,d),"line",b,j);return h=!0,g>e.bottom?e.left-i:g<e.top?e.left+i:(h=!1,e.left)}var g=e-ce(b),h=!1,i=2*a.display.wrapper.clientWidth,j=ab(a,b),k=de(b),l=b.text.length,m=cf(b),n=df(b),o=f(m),p=h,q=f(n),r=h;if(d>q)return pb(c,n,r,1);for(;;){if(k?n==m||n==lf(b,m,1):1>=n-m){for(var s=o>d||q-d>=d-o?m:n,t=d-(s==m?o:q);Oe(b.text.charAt(s));)++s;var u=pb(c,s,s==m?p:r,-1>t?-1:t>1?1:0);return u}var v=Math.ceil(l/2),w=m+v;if(k){w=m;for(var x=0;v>x;++x)w=lf(b,w,1)}var y=f(w);y>d?(n=w,q=y,(r=h)&&(q+=1e3),l=v):(m=w,o=y,p=h,l-=v)}}function sb(a){if(null!=a.cachedTextHeight)return a.cachedTextHeight;if(null==Nf){Nf=Pe("pre");for(var b=0;49>b;++b)Nf.appendChild(document.createTextNode("x")),Nf.appendChild(Pe("br"));Nf.appendChild(document.createTextNode("x"))}Re(a.measure,Nf);var c=Nf.offsetHeight/50;return c>3&&(a.cachedTextHeight=c),Qe(a.measure),c||1}function tb(a){if(null!=a.cachedCharWidth)return a.cachedCharWidth;var b=Pe("span","xxxxxxxxxx"),c=Pe("pre",[b]);Re(a.measure,c);var d=b.getBoundingClientRect(),e=(d.right-d.left)/10;return e>2&&(a.cachedCharWidth=e),e||10}function ub(a){a.curOp={cm:a,viewChanged:!1,startHeight:a.doc.height,forceUpdate:!1,updateInput:null,typing:!1,changeObjs:null,cursorActivityHandlers:null,cursorActivityCalled:0,selectionChanged:!1,updateMaxLine:!1,scrollLeft:null,scrollTop:null,scrollToPos:null,focus:!1,id:++Sf},Rf?Rf.ops.push(a.curOp):a.curOp.ownsGroup=Rf={ops:[a.curOp],delayedCallbacks:[]}}function vb(a){var b=a.delayedCallbacks,c=0;do{for(;c<b.length;c++)b[c].call(null);for(var d=0;d<a.ops.length;d++){var e=a.ops[d];if(e.cursorActivityHandlers)for(;e.cursorActivityCalled<e.cursorActivityHandlers.length;)e.cursorActivityHandlers[e.cursorActivityCalled++].call(null,e.cm)}}while(c<b.length)}function wb(a){var b=a.curOp,c=b.ownsGroup;if(c)try{vb(c)}finally{Rf=null;for(var d=0;d<c.ops.length;d++)c.ops[d].cm.curOp=null;xb(c)}}function xb(a){for(var b=a.ops,c=0;c<b.length;c++)yb(b[c]);for(var c=0;c<b.length;c++)zb(b[c]);for(var c=0;c<b.length;c++)Ab(b[c]);for(var c=0;c<b.length;c++)Bb(b[c]);for(var c=0;c<b.length;c++)Cb(b[c])}function yb(a){var b=a.cm,c=b.display;A(b),a.updateMaxLine&&m(b),a.mustUpdate=a.viewChanged||a.forceUpdate||null!=a.scrollTop||a.scrollToPos&&(a.scrollToPos.from.line<c.viewFrom||a.scrollToPos.to.line>=c.viewTo)||c.maxLineChanged&&b.options.lineWrapping,a.update=a.mustUpdate&&new z(b,a.mustUpdate&&{top:a.scrollTop,ensure:a.scrollToPos},a.forceUpdate)}function zb(a){a.updatedDisplay=a.mustUpdate&&B(a.cm,a.update)}function Ab(a){var b=a.cm,c=b.display;a.updatedDisplay&&F(b),a.barMeasure=o(b),c.maxLineChanged&&!b.options.lineWrapping&&(a.adjustWidthTo=$a(b,c.maxLine,c.maxLine.text.length).left+3,b.display.sizerWidth=a.adjustWidthTo,a.barMeasure.scrollWidth=Math.max(c.scroller.clientWidth,c.sizer.offsetLeft+a.adjustWidthTo+Ua(b)+b.display.barWidth),a.maxScrollLeft=Math.max(0,c.sizer.offsetLeft+a.adjustWidthTo-Va(b))),(a.updatedDisplay||a.selectionChanged)&&(a.preparedSelection=c.input.prepareSelection())}function Bb(a){var b=a.cm;null!=a.adjustWidthTo&&(b.display.sizer.style.minWidth=a.adjustWidthTo+"px",a.maxScrollLeft<b.doc.scrollLeft&&ec(b,Math.min(b.display.scroller.scrollLeft,a.maxScrollLeft),!0),b.display.maxLineChanged=!1),a.preparedSelection&&b.display.input.showSelection(a.preparedSelection),a.updatedDisplay&&E(b,a.barMeasure),(a.updatedDisplay||a.startHeight!=b.doc.height)&&s(b,a.barMeasure),a.selectionChanged&&Ma(b),b.state.focused&&a.updateInput&&b.display.input.reset(a.typing),!a.focus||a.focus!=Se()||document.hasFocus&&!document.hasFocus()||Y(a.cm)}function Cb(a){var b=a.cm,c=b.display,d=b.doc;if(a.updatedDisplay&&C(b,a.update),null==c.wheelStartX||null==a.scrollTop&&null==a.scrollLeft&&!a.scrollToPos||(c.wheelStartX=c.wheelStartY=null),null==a.scrollTop||c.scroller.scrollTop==a.scrollTop&&!a.forceScroll||(d.scrollTop=Math.max(0,Math.min(c.scroller.scrollHeight-c.scroller.clientHeight,a.scrollTop)),c.scrollbars.setScrollTop(d.scrollTop),c.scroller.scrollTop=d.scrollTop),null==a.scrollLeft||c.scroller.scrollLeft==a.scrollLeft&&!a.forceScroll||(d.scrollLeft=Math.max(0,Math.min(c.scroller.scrollWidth-Va(b),a.scrollLeft)),c.scrollbars.setScrollLeft(d.scrollLeft),c.scroller.scrollLeft=d.scrollLeft,v(b)),a.scrollToPos){var e=Hc(b,pa(d,a.scrollToPos.from),pa(d,a.scrollToPos.to),a.scrollToPos.margin);a.scrollToPos.isCursor&&b.state.focused&&Gc(b,e)}var f=a.maybeHiddenMarkers,g=a.maybeUnhiddenMarkers;if(f)for(var h=0;h<f.length;++h)f[h].lines.length||Fg(f[h],"hide");if(g)for(var h=0;h<g.length;++h)g[h].lines.length&&Fg(g[h],"unhide");c.wrapper.offsetHeight&&(d.scrollTop=b.display.scroller.scrollTop),a.changeObjs&&Fg(b,"changes",b,a.changeObjs),a.update&&a.update.finish()}function Db(a,b){if(a.curOp)return b();ub(a);try{return b()}finally{wb(a)}}function Eb(a,b){return function(){if(a.curOp)return b.apply(a,arguments);ub(a);try{return b.apply(a,arguments)}finally{wb(a)}}}function Fb(a){return function(){if(this.curOp)return a.apply(this,arguments);ub(this);try{return a.apply(this,arguments)}finally{wb(this)}}}function Gb(a){return function(){var b=this.cm;if(!b||b.curOp)return a.apply(this,arguments);ub(b);try{return a.apply(this,arguments)}finally{wb(b)}}}function Hb(a,b,c){this.line=b,this.rest=sd(b),this.size=this.rest?ae(Fe(this.rest))-c+1:1,this.node=this.text=null,this.hidden=vd(a,b)}function Ib(a,b,c){for(var d,e=[],f=b;c>f;f=d){var g=new Hb(a.doc,Yd(a.doc,f),f);d=f+g.size,e.push(g)}return e}function Jb(a,b,c,d){null==b&&(b=a.doc.first),null==c&&(c=a.doc.first+a.doc.size),d||(d=0);var e=a.display;if(d&&c<e.viewTo&&(null==e.updateLineNumbers||e.updateLineNumbers>b)&&(e.updateLineNumbers=b),a.curOp.viewChanged=!0,b>=e.viewTo)Jf&&td(a.doc,b)<e.viewTo&&Lb(a);else if(c<=e.viewFrom)Jf&&ud(a.doc,c+d)>e.viewFrom?Lb(a):(e.viewFrom+=d,e.viewTo+=d);else if(b<=e.viewFrom&&c>=e.viewTo)Lb(a);else if(b<=e.viewFrom){var f=Nb(a,c,c+d,1);f?(e.view=e.view.slice(f.index),e.viewFrom=f.lineN,e.viewTo+=d):Lb(a)}else if(c>=e.viewTo){var f=Nb(a,b,b,-1);f?(e.view=e.view.slice(0,f.index),e.viewTo=f.lineN):Lb(a)}else{var g=Nb(a,b,b,-1),h=Nb(a,c,c+d,1);g&&h?(e.view=e.view.slice(0,g.index).concat(Ib(a,g.lineN,h.lineN)).concat(e.view.slice(h.index)),e.viewTo+=d):Lb(a)}var i=e.externalMeasured;i&&(c<i.lineN?i.lineN+=d:b<i.lineN+i.size&&(e.externalMeasured=null))}function Kb(a,b,c){a.curOp.viewChanged=!0;var d=a.display,e=a.display.externalMeasured;if(e&&b>=e.lineN&&b<e.lineN+e.size&&(d.externalMeasured=null),!(b<d.viewFrom||b>=d.viewTo)){var f=d.view[Mb(a,b)];if(null!=f.node){var g=f.changes||(f.changes=[]);-1==Ge(g,c)&&g.push(c)}}}function Lb(a){a.display.viewFrom=a.display.viewTo=a.doc.first,a.display.view=[],a.display.viewOffset=0}function Mb(a,b){if(b>=a.display.viewTo)return null;if(b-=a.display.viewFrom,0>b)return null;for(var c=a.display.view,d=0;d<c.length;d++)if(b-=c[d].size,0>b)return d}function Nb(a,b,c,d){var e,f=Mb(a,b),g=a.display.view;if(!Jf||c==a.doc.first+a.doc.size)return{index:f,lineN:c};for(var h=0,i=a.display.viewFrom;f>h;h++)i+=g[h].size;if(i!=b){if(d>0){if(f==g.length-1)return null;e=i+g[f].size-b,f++}else e=i-b;b+=e,c+=e}for(;td(a.doc,c)!=c;){if(f==(0>d?0:g.length-1))return null;c+=d*g[f-(0>d?1:0)].size,f+=d}return{index:f,lineN:c}}function Ob(a,b,c){var d=a.display,e=d.view;0==e.length||b>=d.viewTo||c<=d.viewFrom?(d.view=Ib(a,b,c),d.viewFrom=b):(d.viewFrom>b?d.view=Ib(a,b,d.viewFrom).concat(d.view):d.viewFrom<b&&(d.view=d.view.slice(Mb(a,b))),d.viewFrom=b,d.viewTo<c?d.view=d.view.concat(Ib(a,d.viewTo,c)):d.viewTo>c&&(d.view=d.view.slice(0,Mb(a,c)))),d.viewTo=c}function Pb(a){for(var b=a.display.view,c=0,d=0;d<b.length;d++){var e=b[d];e.hidden||e.node&&!e.changes||++c}return c}function Qb(a){function b(){e.activeTouch&&(f=setTimeout(function(){e.activeTouch=null},1e3),g=e.activeTouch,g.end=+new Date)}function c(a){if(1!=a.touches.length)return!1;var b=a.touches[0];return b.radiusX<=1&&b.radiusY<=1}function d(a,b){if(null==b.left)return!0;var c=b.left-a.left,d=b.top-a.top;return c*c+d*d>400}var e=a.display;Cg(e.scroller,"mousedown",Eb(a,Vb)),sf&&11>tf?Cg(e.scroller,"dblclick",Eb(a,function(b){if(!ze(a,b)){var c=Ub(a,b);if(c&&!$b(a,b)&&!Tb(a.display,b)){zg(b);var d=a.findWordAt(c);ua(a.doc,d.anchor,d.head)}}})):Cg(e.scroller,"dblclick",function(b){ze(a,b)||zg(b)}),Hf||Cg(e.scroller,"contextmenu",function(b){sc(a,b)});var f,g={end:0};Cg(e.scroller,"touchstart",function(a){if(!c(a)){clearTimeout(f);var b=+new Date;e.activeTouch={start:b,moved:!1,prev:b-g.end<=300?g:null},1==a.touches.length&&(e.activeTouch.left=a.touches[0].pageX,e.activeTouch.top=a.touches[0].pageY)}}),Cg(e.scroller,"touchmove",function(){e.activeTouch&&(e.activeTouch.moved=!0)}),Cg(e.scroller,"touchend",function(c){var f=e.activeTouch;if(f&&!Tb(e,c)&&null!=f.left&&!f.moved&&new Date-f.start<300){var g,h=a.coordsChar(e.activeTouch,"page");g=!f.prev||d(f,f.prev)?new la(h,h):!f.prev.prev||d(f,f.prev.prev)?a.findWordAt(h):new la(Kf(h.line,0),pa(a.doc,Kf(h.line+1,0))),a.setSelection(g.anchor,g.head),a.focus(),zg(c)}b()}),Cg(e.scroller,"touchcancel",b),Cg(e.scroller,"scroll",function(){e.scroller.clientHeight&&(dc(a,e.scroller.scrollTop),ec(a,e.scroller.scrollLeft,!0),Fg(a,"scroll",a))}),Cg(e.scroller,"mousewheel",function(b){fc(a,b)}),Cg(e.scroller,"DOMMouseScroll",function(b){fc(a,b)}),Cg(e.wrapper,"scroll",function(){e.wrapper.scrollTop=e.wrapper.scrollLeft=0}),e.dragFunctions={enter:function(b){ze(a,b)||Bg(b)},over:function(b){ze(a,b)||(bc(a,b),Bg(b))},start:function(b){ac(a,b)},drop:Eb(a,_b),leave:function(){cc(a)}};var h=e.input.getField();Cg(h,"keyup",function(b){nc.call(a,b)}),Cg(h,"keydown",Eb(a,lc)),Cg(h,"keypress",Eb(a,oc)),Cg(h,"focus",Le(qc,a)),Cg(h,"blur",Le(rc,a))}function Rb(b,c,d){var e=d&&d!=a.Init;if(!c!=!e){var f=b.display.dragFunctions,g=c?Cg:Eg;g(b.display.scroller,"dragstart",f.start),g(b.display.scroller,"dragenter",f.enter),g(b.display.scroller,"dragover",f.over),g(b.display.scroller,"dragleave",f.leave),g(b.display.scroller,"drop",f.drop)}}function Sb(a){var b=a.display;(b.lastWrapHeight!=b.wrapper.clientHeight||b.lastWrapWidth!=b.wrapper.clientWidth)&&(b.cachedCharWidth=b.cachedTextHeight=b.cachedPaddingH=null,b.scrollbarsClipped=!1,a.setSize())}function Tb(a,b){for(var c=ue(b);c!=a.wrapper;c=c.parentNode)if(!c||1==c.nodeType&&"true"==c.getAttribute("cm-ignore-events")||c.parentNode==a.sizer&&c!=a.mover)return!0}function Ub(a,b,c,d){var e=a.display;if(!c&&"true"==ue(b).getAttribute("cm-not-content"))return null;var f,g,h=e.lineSpace.getBoundingClientRect();try{f=b.clientX-h.left,g=b.clientY-h.top}catch(b){return null}var i,j=qb(a,f,g);if(d&&1==j.xRel&&(i=Yd(a.doc,j.line).text).length==j.ch){var k=Mg(i,i.length,a.options.tabSize)-i.length;j=Kf(j.line,Math.max(0,Math.round((f-Ta(a.display).left)/tb(a.display))-k))}return j}function Vb(a){var b=this,c=b.display;if(!(c.activeTouch&&c.input.supportsTouch()||ze(b,a))){if(c.shift=a.shiftKey,Tb(c,a))return void(uf||(c.scroller.draggable=!1,setTimeout(function(){c.scroller.draggable=!0},100)));if(!$b(b,a)){var d=Ub(b,a);switch(window.focus(),ve(a)){case 1:b.state.selectingText?b.state.selectingText(a):d?Wb(b,a,d):ue(a)==c.scroller&&zg(a);break;case 2:uf&&(b.state.lastMiddleDown=+new Date),d&&ua(b.doc,d),setTimeout(function(){c.input.focus()},20),zg(a);break;case 3:Hf?sc(b,a):pc(b)}}}}function Wb(a,b,c){sf?setTimeout(Le(Y,a),0):a.curOp.focus=Se();var d,e=+new Date;Pf&&Pf.time>e-400&&0==Lf(Pf.pos,c)?d="triple":Of&&Of.time>e-400&&0==Lf(Of.pos,c)?(d="double",Pf={time:e,pos:c}):(d="single",Of={time:e,pos:c});var f,g=a.doc.sel,h=Df?b.metaKey:b.ctrlKey;a.options.dragDrop&&$g&&!a.isReadOnly()&&"single"==d&&(f=g.contains(c))>-1&&(Lf((f=g.ranges[f]).from(),c)<0||c.xRel>0)&&(Lf(f.to(),c)>0||c.xRel<0)?Xb(a,b,c,h):Yb(a,b,c,d,h)}function Xb(a,b,c,d){var e=a.display,f=+new Date,g=Eb(a,function(h){uf&&(e.scroller.draggable=!1),a.state.draggingText=!1,Eg(document,"mouseup",g),Eg(e.scroller,"drop",g),Math.abs(b.clientX-h.clientX)+Math.abs(b.clientY-h.clientY)<10&&(zg(h),!d&&+new Date-200<f&&ua(a.doc,c),uf||sf&&9==tf?setTimeout(function(){document.body.focus(),e.input.focus()},20):e.input.focus())});uf&&(e.scroller.draggable=!0),a.state.draggingText=g,e.scroller.dragDrop&&e.scroller.dragDrop(),Cg(document,"mouseup",g),Cg(e.scroller,"drop",g)}function Yb(a,b,c,d,e){function f(b){if(0!=Lf(q,b))if(q=b,"rect"==d){for(var e=[],f=a.options.tabSize,g=Mg(Yd(j,c.line).text,c.ch,f),h=Mg(Yd(j,b.line).text,b.ch,f),i=Math.min(g,h),n=Math.max(g,h),o=Math.min(c.line,b.line),p=Math.min(a.lastLine(),Math.max(c.line,b.line));p>=o;o++){var r=Yd(j,o).text,s=Ng(r,i,f);i==n?e.push(new la(Kf(o,s),Kf(o,s))):r.length>s&&e.push(new la(Kf(o,s),Kf(o,Ng(r,n,f))))}e.length||e.push(new la(c,c)),Aa(j,ma(m.ranges.slice(0,l).concat(e),l),{origin:"*mouse",scroll:!1}),a.scrollIntoView(b)}else{var t=k,u=t.anchor,v=b;if("single"!=d){if("double"==d)var w=a.findWordAt(b);else var w=new la(Kf(b.line,0),pa(j,Kf(b.line+1,0)));Lf(w.anchor,u)>0?(v=w.head,u=X(t.from(),w.anchor)):(v=w.anchor,u=W(t.to(),w.head))}var e=m.ranges.slice(0);e[l]=new la(pa(j,u),v),Aa(j,ma(e,l),Kg)}}function g(b){var c=++s,e=Ub(a,b,!0,"rect"==d);if(e)if(0!=Lf(e,q)){a.curOp.focus=Se(),f(e);var h=u(i,j);(e.line>=h.to||e.line<h.from)&&setTimeout(Eb(a,function(){s==c&&g(b)}),150)}else{var k=b.clientY<r.top?-20:b.clientY>r.bottom?20:0;k&&setTimeout(Eb(a,function(){s==c&&(i.scroller.scrollTop+=k,g(b))}),50)}}function h(b){a.state.selectingText=!1,s=1/0,zg(b),i.input.focus(),Eg(document,"mousemove",t),Eg(document,"mouseup",v),j.history.lastSelOrigin=null}var i=a.display,j=a.doc;zg(b);var k,l,m=j.sel,n=m.ranges;if(e&&!b.shiftKey?(l=j.sel.contains(c),k=l>-1?n[l]:new la(c,c)):(k=j.sel.primary(),l=j.sel.primIndex),b.altKey)d="rect",e||(k=new la(c,c)),c=Ub(a,b,!0,!0),l=-1;else if("double"==d){var o=a.findWordAt(c);k=a.display.shift||j.extend?ta(j,k,o.anchor,o.head):o}else if("triple"==d){var p=new la(Kf(c.line,0),pa(j,Kf(c.line+1,0)));k=a.display.shift||j.extend?ta(j,k,p.anchor,p.head):p}else k=ta(j,k,c);e?-1==l?(l=n.length,Aa(j,ma(n.concat([k]),l),{scroll:!1,origin:"*mouse"})):n.length>1&&n[l].empty()&&"single"==d&&!b.shiftKey?(Aa(j,ma(n.slice(0,l).concat(n.slice(l+1)),0),{scroll:!1,origin:"*mouse"}),m=j.sel):wa(j,l,k,Kg):(l=0,Aa(j,new ka([k],0),Kg),m=j.sel);var q=c,r=i.wrapper.getBoundingClientRect(),s=0,t=Eb(a,function(a){ve(a)?g(a):h(a)}),v=Eb(a,h);a.state.selectingText=v,Cg(document,"mousemove",t),Cg(document,"mouseup",v)}function Zb(a,b,c,d){try{var e=b.clientX,f=b.clientY}catch(b){return!1}if(e>=Math.floor(a.display.gutters.getBoundingClientRect().right))return!1;d&&zg(b);var g=a.display,h=g.lineDiv.getBoundingClientRect();if(f>h.bottom||!Be(a,c))return te(b);f-=h.top-g.viewOffset;for(var i=0;i<a.options.gutters.length;++i){var j=g.gutters.childNodes[i];if(j&&j.getBoundingClientRect().right>=e){var k=be(a.doc,f),l=a.options.gutters[i];return Fg(a,c,a,k,l,b),te(b)}}}function $b(a,b){return Zb(a,b,"gutterClick",!0)}function _b(a){var b=this;if(cc(b),!ze(b,a)&&!Tb(b.display,a)){zg(a),sf&&(Tf=+new Date);var c=Ub(b,a,!0),d=a.dataTransfer.files;if(c&&!b.isReadOnly())if(d&&d.length&&window.FileReader&&window.File)for(var e=d.length,f=Array(e),g=0,h=function(a,d){if(!b.options.allowDropFileTypes||-1!=Ge(b.options.allowDropFileTypes,a.type)){var h=new FileReader;h.onload=Eb(b,function(){var a=h.result;if(/[\x00-\x08\x0e-\x1f]{2}/.test(a)&&(a=""),f[d]=a,++g==e){c=pa(b.doc,c);var i={from:c,to:c,text:b.doc.splitLines(f.join(b.doc.lineSeparator())),origin:"paste"};zc(b.doc,i),za(b.doc,na(c,Zf(i)))}}),h.readAsText(a)}},i=0;e>i;++i)h(d[i],i);else{if(b.state.draggingText&&b.doc.sel.contains(c)>-1)return b.state.draggingText(a),void setTimeout(function(){b.display.input.focus()},20);try{var f=a.dataTransfer.getData("Text");if(f){if(b.state.draggingText&&!(Df?a.altKey:a.ctrlKey))var j=b.listSelections();if(Ba(b.doc,na(c,c)),j)for(var i=0;i<j.length;++i)Fc(b.doc,"",j[i].anchor,j[i].head,"drag");b.replaceSelection(f,"around","paste"),b.display.input.focus()}}catch(a){}}}}function ac(a,b){if(sf&&(!a.state.draggingText||+new Date-Tf<100))return void Bg(b);if(!ze(a,b)&&!Tb(a.display,b)&&(b.dataTransfer.setData("Text",a.getSelection()),b.dataTransfer.setDragImage&&!yf)){var c=Pe("img",null,null,"position: fixed; left: 0; top: 0;");c.src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",xf&&(c.width=c.height=1,a.display.wrapper.appendChild(c),c._top=c.offsetTop),b.dataTransfer.setDragImage(c,0,0),xf&&c.parentNode.removeChild(c)}}function bc(a,b){var c=Ub(a,b);if(c){var d=document.createDocumentFragment();Ka(a,c,d),a.display.dragCursor||(a.display.dragCursor=Pe("div",null,"CodeMirror-cursors CodeMirror-dragcursors"),a.display.lineSpace.insertBefore(a.display.dragCursor,a.display.cursorDiv)),Re(a.display.dragCursor,d)}}function cc(a){a.display.dragCursor&&(a.display.lineSpace.removeChild(a.display.dragCursor),a.display.dragCursor=null)}function dc(a,b){Math.abs(a.doc.scrollTop-b)<2||(a.doc.scrollTop=b,pf||D(a,{top:b}),a.display.scroller.scrollTop!=b&&(a.display.scroller.scrollTop=b),a.display.scrollbars.setScrollTop(b),pf&&D(a),Na(a,100))}function ec(a,b,c){(c?b==a.doc.scrollLeft:Math.abs(a.doc.scrollLeft-b)<2)||(b=Math.min(b,a.display.scroller.scrollWidth-a.display.scroller.clientWidth),a.doc.scrollLeft=b,v(a),a.display.scroller.scrollLeft!=b&&(a.display.scroller.scrollLeft=b),a.display.scrollbars.setScrollLeft(b))}function fc(a,b){var c=Wf(b),d=c.x,e=c.y,f=a.display,g=f.scroller,h=g.scrollWidth>g.clientWidth,i=g.scrollHeight>g.clientHeight;if(d&&h||e&&i){if(e&&Df&&uf)a:for(var j=b.target,k=f.view;j!=g;j=j.parentNode)for(var l=0;l<k.length;l++)if(k[l].node==j){a.display.currentWheelTarget=j;break a}if(d&&!pf&&!xf&&null!=Vf)return e&&i&&dc(a,Math.max(0,Math.min(g.scrollTop+e*Vf,g.scrollHeight-g.clientHeight))),ec(a,Math.max(0,Math.min(g.scrollLeft+d*Vf,g.scrollWidth-g.clientWidth))),(!e||e&&i)&&zg(b),void(f.wheelStartX=null);if(e&&null!=Vf){var m=e*Vf,n=a.doc.scrollTop,o=n+f.wrapper.clientHeight;0>m?n=Math.max(0,n+m-50):o=Math.min(a.doc.height,o+m+50),D(a,{top:n,bottom:o})}20>Uf&&(null==f.wheelStartX?(f.wheelStartX=g.scrollLeft,f.wheelStartY=g.scrollTop,f.wheelDX=d,f.wheelDY=e,setTimeout(function(){if(null!=f.wheelStartX){var a=g.scrollLeft-f.wheelStartX,b=g.scrollTop-f.wheelStartY,c=b&&f.wheelDY&&b/f.wheelDY||a&&f.wheelDX&&a/f.wheelDX;f.wheelStartX=f.wheelStartY=null,c&&(Vf=(Vf*Uf+c)/(Uf+1),++Uf)}},200)):(f.wheelDX+=d,f.wheelDY+=e))}}function gc(a,b,c){if("string"==typeof b&&(b=ig[b],!b))return!1;a.display.input.ensurePolled();var d=a.display.shift,e=!1;try{a.isReadOnly()&&(a.state.suppressEdits=!0),c&&(a.display.shift=!1),e=b(a)!=Ig}finally{a.display.shift=d,a.state.suppressEdits=!1}return e}function hc(a,b,c){for(var d=0;d<a.state.keyMaps.length;d++){var e=kg(b,a.state.keyMaps[d],c,a);if(e)return e}return a.options.extraKeys&&kg(b,a.options.extraKeys,c,a)||kg(b,a.options.keyMap,c,a)}function ic(a,b,c,d){var e=a.state.keySeq;if(e){if(lg(b))return"handled";Xf.set(50,function(){a.state.keySeq==e&&(a.state.keySeq=null,a.display.input.reset())}),b=e+" "+b}var f=hc(a,b,d);return"multi"==f&&(a.state.keySeq=b),"handled"==f&&xe(a,"keyHandled",a,b,c),("handled"==f||"multi"==f)&&(zg(c),Ma(a)),e&&!f&&/\'$/.test(b)?(zg(c),!0):!!f}function jc(a,b){var c=mg(b,!0);return c?b.shiftKey&&!a.state.keySeq?ic(a,"Shift-"+c,b,function(b){return gc(a,b,!0)})||ic(a,c,b,function(b){return("string"==typeof b?/^go[A-Z]/.test(b):b.motion)?gc(a,b):void 0}):ic(a,c,b,function(b){return gc(a,b)}):!1}function kc(a,b,c){return ic(a,"'"+c+"'",b,function(b){return gc(a,b,!0)})}function lc(a){var b=this;if(b.curOp.focus=Se(),!ze(b,a)){sf&&11>tf&&27==a.keyCode&&(a.returnValue=!1);var c=a.keyCode;b.display.shift=16==c||a.shiftKey;var d=jc(b,a);xf&&(Yf=d?c:null,!d&&88==c&&!bh&&(Df?a.metaKey:a.ctrlKey)&&b.replaceSelection("",null,"cut")),18!=c||/\bCodeMirror-crosshair\b/.test(b.display.lineDiv.className)||mc(b)}}function mc(a){function b(a){18!=a.keyCode&&a.altKey||(Xg(c,"CodeMirror-crosshair"),Eg(document,"keyup",b),Eg(document,"mouseover",b))}var c=a.display.lineDiv;Yg(c,"CodeMirror-crosshair"),Cg(document,"keyup",b),Cg(document,"mouseover",b)}function nc(a){16==a.keyCode&&(this.doc.sel.shift=!1),ze(this,a)}function oc(a){var b=this;if(!(Tb(b.display,a)||ze(b,a)||a.ctrlKey&&!a.altKey||Df&&a.metaKey)){var c=a.keyCode,d=a.charCode;if(xf&&c==Yf)return Yf=null,void zg(a);if(!xf||a.which&&!(a.which<10)||!jc(b,a)){var e=String.fromCharCode(null==d?c:d);kc(b,a,e)||b.display.input.onKeyPress(a)}}}function pc(a){a.state.delayingBlurEvent=!0,setTimeout(function(){a.state.delayingBlurEvent&&(a.state.delayingBlurEvent=!1,rc(a))},100)}function qc(a){a.state.delayingBlurEvent&&(a.state.delayingBlurEvent=!1),"nocursor"!=a.options.readOnly&&(a.state.focused||(Fg(a,"focus",a),a.state.focused=!0,Yg(a.display.wrapper,"CodeMirror-focused"),a.curOp||a.display.selForContextMenu==a.doc.sel||(a.display.input.reset(),uf&&setTimeout(function(){a.display.input.reset(!0)},20)),a.display.input.receivedFocus()),Ma(a))}function rc(a){a.state.delayingBlurEvent||(a.state.focused&&(Fg(a,"blur",a),a.state.focused=!1,Xg(a.display.wrapper,"CodeMirror-focused")),clearInterval(a.display.blinker),setTimeout(function(){a.state.focused||(a.display.shift=!1)},150))}function sc(a,b){Tb(a.display,b)||tc(a,b)||ze(a,b,"contextmenu")||a.display.input.onContextMenu(b)}function tc(a,b){return Be(a,"gutterContextMenu")?Zb(a,b,"gutterContextMenu",!1):!1}function uc(a,b){if(Lf(a,b.from)<0)return a;if(Lf(a,b.to)<=0)return Zf(b);var c=a.line+b.text.length-(b.to.line-b.from.line)-1,d=a.ch;return a.line==b.to.line&&(d+=Zf(b).ch-b.to.ch),Kf(c,d)}function vc(a,b){for(var c=[],d=0;d<a.sel.ranges.length;d++){var e=a.sel.ranges[d];c.push(new la(uc(e.anchor,b),uc(e.head,b)))}return ma(c,a.sel.primIndex)}function wc(a,b,c){return a.line==b.line?Kf(c.line,a.ch-b.ch+c.ch):Kf(c.line+(a.line-b.line),a.ch)}function xc(a,b,c){for(var d=[],e=Kf(a.first,0),f=e,g=0;g<b.length;g++){var h=b[g],i=wc(h.from,e,f),j=wc(Zf(h),e,f);if(e=h.to,f=j,"around"==c){var k=a.sel.ranges[g],l=Lf(k.head,k.anchor)<0;d[g]=new la(l?j:i,l?i:j)}else d[g]=new la(i,i)}return new ka(d,a.sel.primIndex)}function yc(a,b,c){var d={canceled:!1,from:b.from,to:b.to,text:b.text,origin:b.origin,cancel:function(){this.canceled=!0}};return c&&(d.update=function(b,c,d,e){b&&(this.from=pa(a,b)),c&&(this.to=pa(a,c)),d&&(this.text=d),void 0!==e&&(this.origin=e)}),Fg(a,"beforeChange",a,d),a.cm&&Fg(a.cm,"beforeChange",a.cm,d),d.canceled?null:{from:d.from,to:d.to,text:d.text,origin:d.origin}}function zc(a,b,c){if(a.cm){if(!a.cm.curOp)return Eb(a.cm,zc)(a,b,c);if(a.cm.state.suppressEdits)return}if(!(Be(a,"beforeChange")||a.cm&&Be(a.cm,"beforeChange"))||(b=yc(a,b,!0))){var d=If&&!c&&hd(a,b.from,b.to);if(d)for(var e=d.length-1;e>=0;--e)Ac(a,{from:d[e].from,to:d[e].to,text:e?[""]:b.text});else Ac(a,b)}}function Ac(a,b){if(1!=b.text.length||""!=b.text[0]||0!=Lf(b.from,b.to)){var c=vc(a,b);ie(a,b,c,a.cm?a.cm.curOp.id:NaN),Dc(a,b,c,ed(a,b));var d=[];Wd(a,function(a,c){c||-1!=Ge(d,a.history)||(se(a.history,b),d.push(a.history)),Dc(a,b,null,ed(a,b))})}}function Bc(a,b,c){if(!a.cm||!a.cm.state.suppressEdits){for(var d,e=a.history,f=a.sel,g="undo"==b?e.done:e.undone,h="undo"==b?e.undone:e.done,i=0;i<g.length&&(d=g[i],c?!d.ranges||d.equals(a.sel):d.ranges);i++);if(i!=g.length){for(e.lastOrigin=e.lastSelOrigin=null;d=g.pop(),d.ranges;){if(le(d,h),c&&!d.equals(a.sel))return void Aa(a,d,{clearRedo:!1});f=d}var j=[];le(f,h),h.push({changes:j,generation:e.generation}),e.generation=d.generation||++e.maxGeneration;for(var k=Be(a,"beforeChange")||a.cm&&Be(a.cm,"beforeChange"),i=d.changes.length-1;i>=0;--i){var l=d.changes[i];if(l.origin=b,k&&!yc(a,l,!1))return void(g.length=0);j.push(fe(a,l));var m=i?vc(a,l):Fe(g);Dc(a,l,m,gd(a,l)),!i&&a.cm&&a.cm.scrollIntoView({from:l.from,to:Zf(l)});var n=[];Wd(a,function(a,b){b||-1!=Ge(n,a.history)||(se(a.history,l),n.push(a.history)),Dc(a,l,null,gd(a,l))})}}}}function Cc(a,b){if(0!=b&&(a.first+=b,a.sel=new ka(He(a.sel.ranges,function(a){return new la(Kf(a.anchor.line+b,a.anchor.ch),Kf(a.head.line+b,a.head.ch))}),a.sel.primIndex),a.cm)){Jb(a.cm,a.first,a.first-b,b);for(var c=a.cm.display,d=c.viewFrom;d<c.viewTo;d++)Kb(a.cm,d,"gutter")}}function Dc(a,b,c,d){if(a.cm&&!a.cm.curOp)return Eb(a.cm,Dc)(a,b,c,d);if(b.to.line<a.first)return void Cc(a,b.text.length-1-(b.to.line-b.from.line));if(!(b.from.line>a.lastLine())){if(b.from.line<a.first){var e=b.text.length-1-(a.first-b.from.line);Cc(a,e),b={from:Kf(a.first,0),to:Kf(b.to.line+e,b.to.ch),text:[Fe(b.text)],origin:b.origin}}var f=a.lastLine();b.to.line>f&&(b={from:b.from,to:Kf(f,Yd(a,f).text.length),text:[b.text[0]],origin:b.origin}),b.removed=Zd(a,b.from,b.to),c||(c=vc(a,b)),a.cm?Ec(a.cm,b,d):Td(a,b,d),Ba(a,c,Jg)}}function Ec(a,b,c){var d=a.doc,e=a.display,g=b.from,h=b.to,i=!1,j=g.line;a.options.lineWrapping||(j=ae(rd(Yd(d,g.line))),d.iter(j,h.line+1,function(a){return a==e.maxLine?(i=!0,!0):void 0})),d.sel.contains(b.from,b.to)>-1&&Ae(a),Td(d,b,c,f(a)),a.options.lineWrapping||(d.iter(j,g.line+b.text.length,function(a){var b=l(a);b>e.maxLineLength&&(e.maxLine=a,e.maxLineLength=b,e.maxLineChanged=!0,i=!1)}),i&&(a.curOp.updateMaxLine=!0)),d.frontier=Math.min(d.frontier,g.line),Na(a,400);var k=b.text.length-(h.line-g.line)-1;b.full?Jb(a):g.line!=h.line||1!=b.text.length||Sd(a.doc,b)?Jb(a,g.line,h.line+1,k):Kb(a,g.line,"text");var m=Be(a,"changes"),n=Be(a,"change");if(n||m){var o={from:g,to:h,text:b.text,removed:b.removed,origin:b.origin};n&&xe(a,"change",a,o),m&&(a.curOp.changeObjs||(a.curOp.changeObjs=[])).push(o)}a.display.selForContextMenu=null}function Fc(a,b,c,d,e){if(d||(d=c),Lf(d,c)<0){var f=d;d=c,c=f}"string"==typeof b&&(b=a.splitLines(b)),zc(a,{from:c,to:d,text:b,origin:e})}function Gc(a,b){if(!ze(a,"scrollCursorIntoView")){var c=a.display,d=c.sizer.getBoundingClientRect(),e=null;if(b.top+d.top<0?e=!0:b.bottom+d.top>(window.innerHeight||document.documentElement.clientHeight)&&(e=!1),null!=e&&!Af){var f=Pe("div","​",null,"position: absolute; top: "+(b.top-c.viewOffset-Ra(a.display))+"px; height: "+(b.bottom-b.top+Ua(a)+c.barHeight)+"px; left: "+b.left+"px; width: 2px;");a.display.lineSpace.appendChild(f),f.scrollIntoView(e),a.display.lineSpace.removeChild(f)}}}function Hc(a,b,c,d){null==d&&(d=0);for(var e=0;5>e;e++){var f=!1,g=nb(a,b),h=c&&c!=b?nb(a,c):g,i=Jc(a,Math.min(g.left,h.left),Math.min(g.top,h.top)-d,Math.max(g.left,h.left),Math.max(g.bottom,h.bottom)+d),j=a.doc.scrollTop,k=a.doc.scrollLeft;if(null!=i.scrollTop&&(dc(a,i.scrollTop),Math.abs(a.doc.scrollTop-j)>1&&(f=!0)),null!=i.scrollLeft&&(ec(a,i.scrollLeft),Math.abs(a.doc.scrollLeft-k)>1&&(f=!0)),!f)break}return g}function Ic(a,b,c,d,e){var f=Jc(a,b,c,d,e);null!=f.scrollTop&&dc(a,f.scrollTop),null!=f.scrollLeft&&ec(a,f.scrollLeft)}function Jc(a,b,c,d,e){var f=a.display,g=sb(a.display);0>c&&(c=0);var h=a.curOp&&null!=a.curOp.scrollTop?a.curOp.scrollTop:f.scroller.scrollTop,i=Wa(a),j={};e-c>i&&(e=c+i);var k=a.doc.height+Sa(f),l=g>c,m=e>k-g;if(h>c)j.scrollTop=l?0:c;else if(e>h+i){var n=Math.min(c,(m?k:e)-i);n!=h&&(j.scrollTop=n)}var o=a.curOp&&null!=a.curOp.scrollLeft?a.curOp.scrollLeft:f.scroller.scrollLeft,p=Va(a)-(a.options.fixedGutter?f.gutters.offsetWidth:0),q=d-b>p;return q&&(d=b+p),10>b?j.scrollLeft=0:o>b?j.scrollLeft=Math.max(0,b-(q?0:10)):d>p+o-3&&(j.scrollLeft=d+(q?0:10)-p),j}function Kc(a,b,c){(null!=b||null!=c)&&Mc(a),null!=b&&(a.curOp.scrollLeft=(null==a.curOp.scrollLeft?a.doc.scrollLeft:a.curOp.scrollLeft)+b),null!=c&&(a.curOp.scrollTop=(null==a.curOp.scrollTop?a.doc.scrollTop:a.curOp.scrollTop)+c)}function Lc(a){Mc(a);var b=a.getCursor(),c=b,d=b;a.options.lineWrapping||(c=b.ch?Kf(b.line,b.ch-1):b,d=Kf(b.line,b.ch+1)),a.curOp.scrollToPos={from:c,to:d,margin:a.options.cursorScrollMargin,isCursor:!0}}function Mc(a){var b=a.curOp.scrollToPos;if(b){a.curOp.scrollToPos=null;var c=ob(a,b.from),d=ob(a,b.to),e=Jc(a,Math.min(c.left,d.left),Math.min(c.top,d.top)-b.margin,Math.max(c.right,d.right),Math.max(c.bottom,d.bottom)+b.margin);
3
+ a.scrollTo(e.scrollLeft,e.scrollTop)}}function Nc(a,b,c,d){var e,f=a.doc;null==c&&(c="add"),"smart"==c&&(f.mode.indent?e=Qa(a,b):c="prev");var g=a.options.tabSize,h=Yd(f,b),i=Mg(h.text,null,g);h.stateAfter&&(h.stateAfter=null);var j,k=h.text.match(/^\s*/)[0];if(d||/\S/.test(h.text)){if("smart"==c&&(j=f.mode.indent(e,h.text.slice(k.length),h.text),j==Ig||j>150)){if(!d)return;c="prev"}}else j=0,c="not";"prev"==c?j=b>f.first?Mg(Yd(f,b-1).text,null,g):0:"add"==c?j=i+a.options.indentUnit:"subtract"==c?j=i-a.options.indentUnit:"number"==typeof c&&(j=i+c),j=Math.max(0,j);var l="",m=0;if(a.options.indentWithTabs)for(var n=Math.floor(j/g);n;--n)m+=g,l+=" ";if(j>m&&(l+=Ee(j-m)),l!=k)return Fc(f,l,Kf(b,0),Kf(b,k.length),"+input"),h.stateAfter=null,!0;for(var n=0;n<f.sel.ranges.length;n++){var o=f.sel.ranges[n];if(o.head.line==b&&o.head.ch<k.length){var m=Kf(b,k.length);wa(f,n,new la(m,m));break}}}function Oc(a,b,c,d){var e=b,f=b;return"number"==typeof b?f=Yd(a,oa(a,b)):e=ae(b),null==e?null:(d(f,e)&&a.cm&&Kb(a.cm,e,c),f)}function Pc(a,b){for(var c=a.doc.sel.ranges,d=[],e=0;e<c.length;e++){for(var f=b(c[e]);d.length&&Lf(f.from,Fe(d).to)<=0;){var g=d.pop();if(Lf(g.from,f.from)<0){f.from=g.from;break}}d.push(f)}Db(a,function(){for(var b=d.length-1;b>=0;b--)Fc(a.doc,"",d[b].from,d[b].to,"+delete");Lc(a)})}function Qc(a,b,c,d,e){function f(){var b=h+c;return b<a.first||b>=a.first+a.size?l=!1:(h=b,k=Yd(a,b))}function g(a){var b=(e?lf:mf)(k,i,c,!0);if(null==b){if(a||!f())return l=!1;i=e?(0>c?df:cf)(k):0>c?k.text.length:0}else i=b;return!0}var h=b.line,i=b.ch,j=c,k=Yd(a,h),l=!0;if("char"==d)g();else if("column"==d)g(!0);else if("word"==d||"group"==d)for(var m=null,n="group"==d,o=a.cm&&a.cm.getHelper(b,"wordChars"),p=!0;!(0>c)||g(!p);p=!1){var q=k.text.charAt(i)||"\n",r=Me(q,o)?"w":n&&"\n"==q?"n":!n||/\s/.test(q)?null:"p";if(!n||p||r||(r="s"),m&&m!=r){0>c&&(c=1,g());break}if(r&&(m=r),c>0&&!g(!p))break}var s=Ga(a,Kf(h,i),b,j,!0);return l||(s.hitSide=!0),s}function Rc(a,b,c,d){var e,f=a.doc,g=b.left;if("page"==d){var h=Math.min(a.display.wrapper.clientHeight,window.innerHeight||document.documentElement.clientHeight);e=b.top+c*(h-(0>c?1.5:.5)*sb(a.display))}else"line"==d&&(e=c>0?b.bottom+3:b.top-3);for(;;){var i=qb(a,g,e);if(!i.outside)break;if(0>c?0>=e:e>=f.height){i.hitSide=!0;break}e+=5*c}return i}function Sc(b,c,d,e){a.defaults[b]=c,d&&(_f[b]=e?function(a,b,c){c!=ag&&d(a,b,c)}:d)}function Tc(a){for(var b,c,d,e,f=a.split(/-(?!$)/),a=f[f.length-1],g=0;g<f.length-1;g++){var h=f[g];if(/^(cmd|meta|m)$/i.test(h))e=!0;else if(/^a(lt)?$/i.test(h))b=!0;else if(/^(c|ctrl|control)$/i.test(h))c=!0;else{if(!/^s(hift)$/i.test(h))throw new Error("Unrecognized modifier name: "+h);d=!0}}return b&&(a="Alt-"+a),c&&(a="Ctrl-"+a),e&&(a="Cmd-"+a),d&&(a="Shift-"+a),a}function Uc(a){return"string"==typeof a?jg[a]:a}function Vc(a,b,c,d,e){if(d&&d.shared)return Wc(a,b,c,d,e);if(a.cm&&!a.cm.curOp)return Eb(a.cm,Vc)(a,b,c,d,e);var f=new pg(a,e),g=Lf(b,c);if(d&&Ke(d,f,!1),g>0||0==g&&f.clearWhenEmpty!==!1)return f;if(f.replacedWith&&(f.collapsed=!0,f.widgetNode=Pe("span",[f.replacedWith],"CodeMirror-widget"),d.handleMouseEvents||f.widgetNode.setAttribute("cm-ignore-events","true"),d.insertLeft&&(f.widgetNode.insertLeft=!0)),f.collapsed){if(qd(a,b.line,b,c,f)||b.line!=c.line&&qd(a,c.line,b,c,f))throw new Error("Inserting collapsed marker partially overlapping an existing one");Jf=!0}f.addToHistory&&ie(a,{from:b,to:c,origin:"markText"},a.sel,NaN);var h,i=b.line,j=a.cm;if(a.iter(i,c.line+1,function(a){j&&f.collapsed&&!j.options.lineWrapping&&rd(a)==j.display.maxLine&&(h=!0),f.collapsed&&i!=b.line&&_d(a,0),bd(a,new $c(f,i==b.line?b.ch:null,i==c.line?c.ch:null)),++i}),f.collapsed&&a.iter(b.line,c.line+1,function(b){vd(a,b)&&_d(b,0)}),f.clearOnEnter&&Cg(f,"beforeCursorEnter",function(){f.clear()}),f.readOnly&&(If=!0,(a.history.done.length||a.history.undone.length)&&a.clearHistory()),f.collapsed&&(f.id=++og,f.atomic=!0),j){if(h&&(j.curOp.updateMaxLine=!0),f.collapsed)Jb(j,b.line,c.line+1);else if(f.className||f.title||f.startStyle||f.endStyle||f.css)for(var k=b.line;k<=c.line;k++)Kb(j,k,"text");f.atomic&&Da(j.doc),xe(j,"markerAdded",j,f)}return f}function Wc(a,b,c,d,e){d=Ke(d),d.shared=!1;var f=[Vc(a,b,c,d,e)],g=f[0],h=d.widgetNode;return Wd(a,function(a){h&&(d.widgetNode=h.cloneNode(!0)),f.push(Vc(a,pa(a,b),pa(a,c),d,e));for(var i=0;i<a.linked.length;++i)if(a.linked[i].isParent)return;g=Fe(f)}),new qg(f,g)}function Xc(a){return a.findMarks(Kf(a.first,0),a.clipPos(Kf(a.lastLine())),function(a){return a.parent})}function Yc(a,b){for(var c=0;c<b.length;c++){var d=b[c],e=d.find(),f=a.clipPos(e.from),g=a.clipPos(e.to);if(Lf(f,g)){var h=Vc(a,f,g,d.primary,d.primary.type);d.markers.push(h),h.parent=d}}}function Zc(a){for(var b=0;b<a.length;b++){var c=a[b],d=[c.primary.doc];Wd(c.primary.doc,function(a){d.push(a)});for(var e=0;e<c.markers.length;e++){var f=c.markers[e];-1==Ge(d,f.doc)&&(f.parent=null,c.markers.splice(e--,1))}}}function $c(a,b,c){this.marker=a,this.from=b,this.to=c}function _c(a,b){if(a)for(var c=0;c<a.length;++c){var d=a[c];if(d.marker==b)return d}}function ad(a,b){for(var c,d=0;d<a.length;++d)a[d]!=b&&(c||(c=[])).push(a[d]);return c}function bd(a,b){a.markedSpans=a.markedSpans?a.markedSpans.concat([b]):[b],b.marker.attachLine(a)}function cd(a,b,c){if(a)for(var d,e=0;e<a.length;++e){var f=a[e],g=f.marker,h=null==f.from||(g.inclusiveLeft?f.from<=b:f.from<b);if(h||f.from==b&&"bookmark"==g.type&&(!c||!f.marker.insertLeft)){var i=null==f.to||(g.inclusiveRight?f.to>=b:f.to>b);(d||(d=[])).push(new $c(g,f.from,i?null:f.to))}}return d}function dd(a,b,c){if(a)for(var d,e=0;e<a.length;++e){var f=a[e],g=f.marker,h=null==f.to||(g.inclusiveRight?f.to>=b:f.to>b);if(h||f.from==b&&"bookmark"==g.type&&(!c||f.marker.insertLeft)){var i=null==f.from||(g.inclusiveLeft?f.from<=b:f.from<b);(d||(d=[])).push(new $c(g,i?null:f.from-b,null==f.to?null:f.to-b))}}return d}function ed(a,b){if(b.full)return null;var c=ra(a,b.from.line)&&Yd(a,b.from.line).markedSpans,d=ra(a,b.to.line)&&Yd(a,b.to.line).markedSpans;if(!c&&!d)return null;var e=b.from.ch,f=b.to.ch,g=0==Lf(b.from,b.to),h=cd(c,e,g),i=dd(d,f,g),j=1==b.text.length,k=Fe(b.text).length+(j?e:0);if(h)for(var l=0;l<h.length;++l){var m=h[l];if(null==m.to){var n=_c(i,m.marker);n?j&&(m.to=null==n.to?null:n.to+k):m.to=e}}if(i)for(var l=0;l<i.length;++l){var m=i[l];if(null!=m.to&&(m.to+=k),null==m.from){var n=_c(h,m.marker);n||(m.from=k,j&&(h||(h=[])).push(m))}else m.from+=k,j&&(h||(h=[])).push(m)}h&&(h=fd(h)),i&&i!=h&&(i=fd(i));var o=[h];if(!j){var p,q=b.text.length-2;if(q>0&&h)for(var l=0;l<h.length;++l)null==h[l].to&&(p||(p=[])).push(new $c(h[l].marker,null,null));for(var l=0;q>l;++l)o.push(p);o.push(i)}return o}function fd(a){for(var b=0;b<a.length;++b){var c=a[b];null!=c.from&&c.from==c.to&&c.marker.clearWhenEmpty!==!1&&a.splice(b--,1)}return a.length?a:null}function gd(a,b){var c=oe(a,b),d=ed(a,b);if(!c)return d;if(!d)return c;for(var e=0;e<c.length;++e){var f=c[e],g=d[e];if(f&&g)a:for(var h=0;h<g.length;++h){for(var i=g[h],j=0;j<f.length;++j)if(f[j].marker==i.marker)continue a;f.push(i)}else g&&(c[e]=g)}return c}function hd(a,b,c){var d=null;if(a.iter(b.line,c.line+1,function(a){if(a.markedSpans)for(var b=0;b<a.markedSpans.length;++b){var c=a.markedSpans[b].marker;!c.readOnly||d&&-1!=Ge(d,c)||(d||(d=[])).push(c)}}),!d)return null;for(var e=[{from:b,to:c}],f=0;f<d.length;++f)for(var g=d[f],h=g.find(0),i=0;i<e.length;++i){var j=e[i];if(!(Lf(j.to,h.from)<0||Lf(j.from,h.to)>0)){var k=[i,1],l=Lf(j.from,h.from),m=Lf(j.to,h.to);(0>l||!g.inclusiveLeft&&!l)&&k.push({from:j.from,to:h.from}),(m>0||!g.inclusiveRight&&!m)&&k.push({from:h.to,to:j.to}),e.splice.apply(e,k),i+=k.length-1}}return e}function id(a){var b=a.markedSpans;if(b){for(var c=0;c<b.length;++c)b[c].marker.detachLine(a);a.markedSpans=null}}function jd(a,b){if(b){for(var c=0;c<b.length;++c)b[c].marker.attachLine(a);a.markedSpans=b}}function kd(a){return a.inclusiveLeft?-1:0}function ld(a){return a.inclusiveRight?1:0}function md(a,b){var c=a.lines.length-b.lines.length;if(0!=c)return c;var d=a.find(),e=b.find(),f=Lf(d.from,e.from)||kd(a)-kd(b);if(f)return-f;var g=Lf(d.to,e.to)||ld(a)-ld(b);return g?g:b.id-a.id}function nd(a,b){var c,d=Jf&&a.markedSpans;if(d)for(var e,f=0;f<d.length;++f)e=d[f],e.marker.collapsed&&null==(b?e.from:e.to)&&(!c||md(c,e.marker)<0)&&(c=e.marker);return c}function od(a){return nd(a,!0)}function pd(a){return nd(a,!1)}function qd(a,b,c,d,e){var f=Yd(a,b),g=Jf&&f.markedSpans;if(g)for(var h=0;h<g.length;++h){var i=g[h];if(i.marker.collapsed){var j=i.marker.find(0),k=Lf(j.from,c)||kd(i.marker)-kd(e),l=Lf(j.to,d)||ld(i.marker)-ld(e);if(!(k>=0&&0>=l||0>=k&&l>=0)&&(0>=k&&(Lf(j.to,c)>0||i.marker.inclusiveRight&&e.inclusiveLeft)||k>=0&&(Lf(j.from,d)<0||i.marker.inclusiveLeft&&e.inclusiveRight)))return!0}}}function rd(a){for(var b;b=od(a);)a=b.find(-1,!0).line;return a}function sd(a){for(var b,c;b=pd(a);)a=b.find(1,!0).line,(c||(c=[])).push(a);return c}function td(a,b){var c=Yd(a,b),d=rd(c);return c==d?b:ae(d)}function ud(a,b){if(b>a.lastLine())return b;var c,d=Yd(a,b);if(!vd(a,d))return b;for(;c=pd(d);)d=c.find(1,!0).line;return ae(d)+1}function vd(a,b){var c=Jf&&b.markedSpans;if(c)for(var d,e=0;e<c.length;++e)if(d=c[e],d.marker.collapsed){if(null==d.from)return!0;if(!d.marker.widgetNode&&0==d.from&&d.marker.inclusiveLeft&&wd(a,b,d))return!0}}function wd(a,b,c){if(null==c.to){var d=c.marker.find(1,!0);return wd(a,d.line,_c(d.line.markedSpans,c.marker))}if(c.marker.inclusiveRight&&c.to==b.text.length)return!0;for(var e,f=0;f<b.markedSpans.length;++f)if(e=b.markedSpans[f],e.marker.collapsed&&!e.marker.widgetNode&&e.from==c.to&&(null==e.to||e.to!=c.from)&&(e.marker.inclusiveLeft||c.marker.inclusiveRight)&&wd(a,b,e))return!0}function xd(a,b,c){ce(b)<(a.curOp&&a.curOp.scrollTop||a.doc.scrollTop)&&Kc(a,null,c)}function yd(a){if(null!=a.height)return a.height;var b=a.doc.cm;if(!b)return 0;if(!Ug(document.body,a.node)){var c="position: relative;";a.coverGutter&&(c+="margin-left: -"+b.display.gutters.offsetWidth+"px;"),a.noHScroll&&(c+="width: "+b.display.wrapper.clientWidth+"px;"),Re(b.display.measure,Pe("div",[a.node],null,c))}return a.height=a.node.parentNode.offsetHeight}function zd(a,b,c,d){var e=new rg(a,c,d),f=a.cm;return f&&e.noHScroll&&(f.display.alignWidgets=!0),Oc(a,b,"widget",function(b){var c=b.widgets||(b.widgets=[]);if(null==e.insertAt?c.push(e):c.splice(Math.min(c.length-1,Math.max(0,e.insertAt)),0,e),e.line=b,f&&!vd(a,b)){var d=ce(b)<a.scrollTop;_d(b,b.height+yd(e)),d&&Kc(f,null,e.height),f.curOp.forceUpdate=!0}return!0}),e}function Ad(a,b,c,d){a.text=b,a.stateAfter&&(a.stateAfter=null),a.styles&&(a.styles=null),null!=a.order&&(a.order=null),id(a),jd(a,c);var e=d?d(a):1;e!=a.height&&_d(a,e)}function Bd(a){a.parent=null,id(a)}function Cd(a,b){if(a)for(;;){var c=a.match(/(?:^|\s+)line-(background-)?(\S+)/);if(!c)break;a=a.slice(0,c.index)+a.slice(c.index+c[0].length);var d=c[1]?"bgClass":"textClass";null==b[d]?b[d]=c[2]:new RegExp("(?:^|s)"+c[2]+"(?:$|s)").test(b[d])||(b[d]+=" "+c[2])}return a}function Dd(b,c){if(b.blankLine)return b.blankLine(c);if(b.innerMode){var d=a.innerMode(b,c);return d.mode.blankLine?d.mode.blankLine(d.state):void 0}}function Ed(b,c,d,e){for(var f=0;10>f;f++){e&&(e[0]=a.innerMode(b,d).mode);var g=b.token(c,d);if(c.pos>c.start)return g}throw new Error("Mode "+b.name+" failed to advance stream.")}function Fd(a,b,c,d){function e(a){return{start:l.start,end:l.pos,string:l.current(),type:f||null,state:a?gg(g.mode,k):k}}var f,g=a.doc,h=g.mode;b=pa(g,b);var i,j=Yd(g,b.line),k=Qa(a,b.line,c),l=new ng(j.text,a.options.tabSize);for(d&&(i=[]);(d||l.pos<b.ch)&&!l.eol();)l.start=l.pos,f=Ed(h,l,k),d&&i.push(e(!0));return d?i:e()}function Gd(a,b,c,d,e,f,g){var h=c.flattenSpans;null==h&&(h=a.options.flattenSpans);var i,j=0,k=null,l=new ng(b,a.options.tabSize),m=a.options.addModeClass&&[null];for(""==b&&Cd(Dd(c,d),f);!l.eol();){if(l.pos>a.options.maxHighlightLength?(h=!1,g&&Jd(a,b,d,l.pos),l.pos=b.length,i=null):i=Cd(Ed(c,l,d,m),f),m){var n=m[0].name;n&&(i="m-"+(i?n+" "+i:n))}if(!h||k!=i){for(;j<l.start;)j=Math.min(l.start,j+5e4),e(j,k);k=i}l.start=l.pos}for(;j<l.pos;){var o=Math.min(l.pos,j+5e4);e(o,k),j=o}}function Hd(a,b,c,d){var e=[a.state.modeGen],f={};Gd(a,b.text,a.doc.mode,c,function(a,b){e.push(a,b)},f,d);for(var g=0;g<a.state.overlays.length;++g){var h=a.state.overlays[g],i=1,j=0;Gd(a,b.text,h.mode,!0,function(a,b){for(var c=i;a>j;){var d=e[i];d>a&&e.splice(i,1,a,e[i+1],d),i+=2,j=Math.min(a,d)}if(b)if(h.opaque)e.splice(c,i-c,a,"cm-overlay "+b),i=c+2;else for(;i>c;c+=2){var f=e[c+1];e[c+1]=(f?f+" ":"")+"cm-overlay "+b}},f)}return{styles:e,classes:f.bgClass||f.textClass?f:null}}function Id(a,b,c){if(!b.styles||b.styles[0]!=a.state.modeGen){var d=Qa(a,ae(b)),e=Hd(a,b,b.text.length>a.options.maxHighlightLength?gg(a.doc.mode,d):d);b.stateAfter=d,b.styles=e.styles,e.classes?b.styleClasses=e.classes:b.styleClasses&&(b.styleClasses=null),c===a.doc.frontier&&a.doc.frontier++}return b.styles}function Jd(a,b,c,d){var e=a.doc.mode,f=new ng(b,a.options.tabSize);for(f.start=f.pos=d||0,""==b&&Dd(e,c);!f.eol();)Ed(e,f,c),f.start=f.pos}function Kd(a,b){if(!a||/^\s*$/.test(a))return null;var c=b.addModeClass?ug:tg;return c[a]||(c[a]=a.replace(/\S+/g,"cm-$&"))}function Ld(a,b){var c=Pe("span",null,null,uf?"padding-right: .1px":null),d={pre:Pe("pre",[c],"CodeMirror-line"),content:c,col:0,pos:0,cm:a,splitSpaces:(sf||uf)&&a.getOption("lineWrapping")};b.measure={};for(var e=0;e<=(b.rest?b.rest.length:0);e++){var f,g=e?b.rest[e-1]:b.line;d.pos=0,d.addToken=Nd,Ze(a.display.measure)&&(f=de(g))&&(d.addToken=Pd(d.addToken,f)),d.map=[];var h=b!=a.display.externalMeasured&&ae(g);Rd(g,d,Id(a,g,h)),g.styleClasses&&(g.styleClasses.bgClass&&(d.bgClass=Ue(g.styleClasses.bgClass,d.bgClass||"")),g.styleClasses.textClass&&(d.textClass=Ue(g.styleClasses.textClass,d.textClass||""))),0==d.map.length&&d.map.push(0,0,d.content.appendChild(Ye(a.display.measure))),0==e?(b.measure.map=d.map,b.measure.cache={}):((b.measure.maps||(b.measure.maps=[])).push(d.map),(b.measure.caches||(b.measure.caches=[])).push({}))}return uf&&/\bcm-tab\b/.test(d.content.lastChild.className)&&(d.content.className="cm-tab-wrap-hack"),Fg(a,"renderLine",a,b.line,d.pre),d.pre.className&&(d.textClass=Ue(d.pre.className,d.textClass||"")),d}function Md(a){var b=Pe("span","•","cm-invalidchar");return b.title="\\u"+a.charCodeAt(0).toString(16),b.setAttribute("aria-label",b.title),b}function Nd(a,b,c,d,e,f,g){if(b){var h=a.splitSpaces?b.replace(/ {3,}/g,Od):b,i=a.cm.state.specialChars,j=!1;if(i.test(b))for(var k=document.createDocumentFragment(),l=0;;){i.lastIndex=l;var m=i.exec(b),n=m?m.index-l:b.length-l;if(n){var o=document.createTextNode(h.slice(l,l+n));sf&&9>tf?k.appendChild(Pe("span",[o])):k.appendChild(o),a.map.push(a.pos,a.pos+n,o),a.col+=n,a.pos+=n}if(!m)break;if(l+=n+1," "==m[0]){var p=a.cm.options.tabSize,q=p-a.col%p,o=k.appendChild(Pe("span",Ee(q),"cm-tab"));o.setAttribute("role","presentation"),o.setAttribute("cm-text"," "),a.col+=q}else if("\r"==m[0]||"\n"==m[0]){var o=k.appendChild(Pe("span","\r"==m[0]?"␍":"␤","cm-invalidchar"));o.setAttribute("cm-text",m[0]),a.col+=1}else{var o=a.cm.options.specialCharPlaceholder(m[0]);o.setAttribute("cm-text",m[0]),sf&&9>tf?k.appendChild(Pe("span",[o])):k.appendChild(o),a.col+=1}a.map.push(a.pos,a.pos+1,o),a.pos++}else{a.col+=b.length;var k=document.createTextNode(h);a.map.push(a.pos,a.pos+b.length,k),sf&&9>tf&&(j=!0),a.pos+=b.length}if(c||d||e||j||g){var r=c||"";d&&(r+=d),e&&(r+=e);var s=Pe("span",[k],r,g);return f&&(s.title=f),a.content.appendChild(s)}a.content.appendChild(k)}}function Od(a){for(var b=" ",c=0;c<a.length-2;++c)b+=c%2?" ":" ";return b+=" "}function Pd(a,b){return function(c,d,e,f,g,h,i){e=e?e+" cm-force-border":"cm-force-border";for(var j=c.pos,k=j+d.length;;){for(var l=0;l<b.length;l++){var m=b[l];if(m.to>j&&m.from<=j)break}if(m.to>=k)return a(c,d,e,f,g,h,i);a(c,d.slice(0,m.to-j),e,f,null,h,i),f=null,d=d.slice(m.to-j),j=m.to}}}function Qd(a,b,c,d){var e=!d&&c.widgetNode;e&&a.map.push(a.pos,a.pos+b,e),!d&&a.cm.display.input.needsContentAttribute&&(e||(e=a.content.appendChild(document.createElement("span"))),e.setAttribute("cm-marker",c.id)),e&&(a.cm.display.input.setUneditable(e),a.content.appendChild(e)),a.pos+=b}function Rd(a,b,c){var d=a.markedSpans,e=a.text,f=0;if(d)for(var g,h,i,j,k,l,m,n=e.length,o=0,p=1,q="",r=0;;){if(r==o){i=j=k=l=h="",m=null,r=1/0;for(var s,t=[],u=0;u<d.length;++u){var v=d[u],w=v.marker;"bookmark"==w.type&&v.from==o&&w.widgetNode?t.push(w):v.from<=o&&(null==v.to||v.to>o||w.collapsed&&v.to==o&&v.from==o)?(null!=v.to&&v.to!=o&&r>v.to&&(r=v.to,j=""),w.className&&(i+=" "+w.className),w.css&&(h=(h?h+";":"")+w.css),w.startStyle&&v.from==o&&(k+=" "+w.startStyle),w.endStyle&&v.to==r&&(s||(s=[])).push(w.endStyle,v.to),w.title&&!l&&(l=w.title),w.collapsed&&(!m||md(m.marker,w)<0)&&(m=v)):v.from>o&&r>v.from&&(r=v.from)}if(s)for(var u=0;u<s.length;u+=2)s[u+1]==r&&(j+=" "+s[u]);if(m&&(m.from||0)==o){if(Qd(b,(null==m.to?n+1:m.to)-o,m.marker,null==m.from),null==m.to)return;m.to==o&&(m=!1)}if(!m&&t.length)for(var u=0;u<t.length;++u)Qd(b,0,t[u])}if(o>=n)break;for(var x=Math.min(n,r);;){if(q){var y=o+q.length;if(!m){var z=y>x?q.slice(0,x-o):q;b.addToken(b,z,g?g+i:i,k,o+z.length==r?j:"",l,h)}if(y>=x){q=q.slice(x-o),o=x;break}o=y,k=""}q=e.slice(f,f=c[p++]),g=Kd(c[p++],b.cm.options)}}else for(var p=1;p<c.length;p+=2)b.addToken(b,e.slice(f,f=c[p]),Kd(c[p+1],b.cm.options))}function Sd(a,b){return 0==b.from.ch&&0==b.to.ch&&""==Fe(b.text)&&(!a.cm||a.cm.options.wholeLineUpdateBefore)}function Td(a,b,c,d){function e(a){return c?c[a]:null}function f(a,c,e){Ad(a,c,e,d),xe(a,"change",a,b)}function g(a,b){for(var c=a,f=[];b>c;++c)f.push(new sg(j[c],e(c),d));return f}var h=b.from,i=b.to,j=b.text,k=Yd(a,h.line),l=Yd(a,i.line),m=Fe(j),n=e(j.length-1),o=i.line-h.line;if(b.full)a.insert(0,g(0,j.length)),a.remove(j.length,a.size-j.length);else if(Sd(a,b)){var p=g(0,j.length-1);f(l,l.text,n),o&&a.remove(h.line,o),p.length&&a.insert(h.line,p)}else if(k==l)if(1==j.length)f(k,k.text.slice(0,h.ch)+m+k.text.slice(i.ch),n);else{var p=g(1,j.length-1);p.push(new sg(m+k.text.slice(i.ch),n,d)),f(k,k.text.slice(0,h.ch)+j[0],e(0)),a.insert(h.line+1,p)}else if(1==j.length)f(k,k.text.slice(0,h.ch)+j[0]+l.text.slice(i.ch),e(0)),a.remove(h.line+1,o);else{f(k,k.text.slice(0,h.ch)+j[0],e(0)),f(l,m+l.text.slice(i.ch),n);var p=g(1,j.length-1);o>1&&a.remove(h.line+1,o-1),a.insert(h.line+1,p)}xe(a,"change",a,b)}function Ud(a){this.lines=a,this.parent=null;for(var b=0,c=0;b<a.length;++b)a[b].parent=this,c+=a[b].height;this.height=c}function Vd(a){this.children=a;for(var b=0,c=0,d=0;d<a.length;++d){var e=a[d];b+=e.chunkSize(),c+=e.height,e.parent=this}this.size=b,this.height=c,this.parent=null}function Wd(a,b,c){function d(a,e,f){if(a.linked)for(var g=0;g<a.linked.length;++g){var h=a.linked[g];if(h.doc!=e){var i=f&&h.sharedHist;(!c||i)&&(b(h.doc,i),d(h.doc,a,i))}}}d(a,null,!0)}function Xd(a,b){if(b.cm)throw new Error("This document is already in use.");a.doc=b,b.cm=a,g(a),c(a),a.options.lineWrapping||m(a),a.options.mode=b.modeOption,Jb(a)}function Yd(a,b){if(b-=a.first,0>b||b>=a.size)throw new Error("There is no line "+(b+a.first)+" in the document.");for(var c=a;!c.lines;)for(var d=0;;++d){var e=c.children[d],f=e.chunkSize();if(f>b){c=e;break}b-=f}return c.lines[b]}function Zd(a,b,c){var d=[],e=b.line;return a.iter(b.line,c.line+1,function(a){var f=a.text;e==c.line&&(f=f.slice(0,c.ch)),e==b.line&&(f=f.slice(b.ch)),d.push(f),++e}),d}function $d(a,b,c){var d=[];return a.iter(b,c,function(a){d.push(a.text)}),d}function _d(a,b){var c=b-a.height;if(c)for(var d=a;d;d=d.parent)d.height+=c}function ae(a){if(null==a.parent)return null;for(var b=a.parent,c=Ge(b.lines,a),d=b.parent;d;b=d,d=d.parent)for(var e=0;d.children[e]!=b;++e)c+=d.children[e].chunkSize();return c+b.first}function be(a,b){var c=a.first;a:do{for(var d=0;d<a.children.length;++d){var e=a.children[d],f=e.height;if(f>b){a=e;continue a}b-=f,c+=e.chunkSize()}return c}while(!a.lines);for(var d=0;d<a.lines.length;++d){var g=a.lines[d],h=g.height;if(h>b)break;b-=h}return c+d}function ce(a){a=rd(a);for(var b=0,c=a.parent,d=0;d<c.lines.length;++d){var e=c.lines[d];if(e==a)break;b+=e.height}for(var f=c.parent;f;c=f,f=c.parent)for(var d=0;d<f.children.length;++d){var g=f.children[d];if(g==c)break;b+=g.height}return b}function de(a){var b=a.order;return null==b&&(b=a.order=fh(a.text)),b}function ee(a){this.done=[],this.undone=[],this.undoDepth=1/0,this.lastModTime=this.lastSelTime=0,this.lastOp=this.lastSelOp=null,this.lastOrigin=this.lastSelOrigin=null,this.generation=this.maxGeneration=a||1}function fe(a,b){var c={from:V(b.from),to:Zf(b),text:Zd(a,b.from,b.to)};return me(a,c,b.from.line,b.to.line+1),Wd(a,function(a){me(a,c,b.from.line,b.to.line+1)},!0),c}function ge(a){for(;a.length;){var b=Fe(a);if(!b.ranges)break;a.pop()}}function he(a,b){return b?(ge(a.done),Fe(a.done)):a.done.length&&!Fe(a.done).ranges?Fe(a.done):a.done.length>1&&!a.done[a.done.length-2].ranges?(a.done.pop(),Fe(a.done)):void 0}function ie(a,b,c,d){var e=a.history;e.undone.length=0;var f,g=+new Date;if((e.lastOp==d||e.lastOrigin==b.origin&&b.origin&&("+"==b.origin.charAt(0)&&a.cm&&e.lastModTime>g-a.cm.options.historyEventDelay||"*"==b.origin.charAt(0)))&&(f=he(e,e.lastOp==d))){var h=Fe(f.changes);0==Lf(b.from,b.to)&&0==Lf(b.from,h.to)?h.to=Zf(b):f.changes.push(fe(a,b))}else{var i=Fe(e.done);for(i&&i.ranges||le(a.sel,e.done),f={changes:[fe(a,b)],generation:e.generation},e.done.push(f);e.done.length>e.undoDepth;)e.done.shift(),e.done[0].ranges||e.done.shift()}e.done.push(c),e.generation=++e.maxGeneration,e.lastModTime=e.lastSelTime=g,e.lastOp=e.lastSelOp=d,e.lastOrigin=e.lastSelOrigin=b.origin,h||Fg(a,"historyAdded")}function je(a,b,c,d){var e=b.charAt(0);return"*"==e||"+"==e&&c.ranges.length==d.ranges.length&&c.somethingSelected()==d.somethingSelected()&&new Date-a.history.lastSelTime<=(a.cm?a.cm.options.historyEventDelay:500)}function ke(a,b,c,d){var e=a.history,f=d&&d.origin;c==e.lastSelOp||f&&e.lastSelOrigin==f&&(e.lastModTime==e.lastSelTime&&e.lastOrigin==f||je(a,f,Fe(e.done),b))?e.done[e.done.length-1]=b:le(b,e.done),e.lastSelTime=+new Date,e.lastSelOrigin=f,e.lastSelOp=c,d&&d.clearRedo!==!1&&ge(e.undone)}function le(a,b){var c=Fe(b);c&&c.ranges&&c.equals(a)||b.push(a)}function me(a,b,c,d){var e=b["spans_"+a.id],f=0;a.iter(Math.max(a.first,c),Math.min(a.first+a.size,d),function(c){c.markedSpans&&((e||(e=b["spans_"+a.id]={}))[f]=c.markedSpans),++f})}function ne(a){if(!a)return null;for(var b,c=0;c<a.length;++c)a[c].marker.explicitlyCleared?b||(b=a.slice(0,c)):b&&b.push(a[c]);return b?b.length?b:null:a}function oe(a,b){var c=b["spans_"+a.id];if(!c)return null;for(var d=0,e=[];d<b.text.length;++d)e.push(ne(c[d]));return e}function pe(a,b,c){for(var d=0,e=[];d<a.length;++d){var f=a[d];if(f.ranges)e.push(c?ka.prototype.deepCopy.call(f):f);else{var g=f.changes,h=[];e.push({changes:h});for(var i=0;i<g.length;++i){var j,k=g[i];if(h.push({from:k.from,to:k.to,text:k.text}),b)for(var l in k)(j=l.match(/^spans_(\d+)$/))&&Ge(b,Number(j[1]))>-1&&(Fe(h)[l]=k[l],delete k[l])}}}return e}function qe(a,b,c,d){c<a.line?a.line+=d:b<a.line&&(a.line=b,a.ch=0)}function re(a,b,c,d){for(var e=0;e<a.length;++e){var f=a[e],g=!0;if(f.ranges){f.copied||(f=a[e]=f.deepCopy(),f.copied=!0);for(var h=0;h<f.ranges.length;h++)qe(f.ranges[h].anchor,b,c,d),qe(f.ranges[h].head,b,c,d)}else{for(var h=0;h<f.changes.length;++h){var i=f.changes[h];if(c<i.from.line)i.from=Kf(i.from.line+d,i.from.ch),i.to=Kf(i.to.line+d,i.to.ch);else if(b<=i.to.line){g=!1;break}}g||(a.splice(0,e+1),e=0)}}}function se(a,b){var c=b.from.line,d=b.to.line,e=b.text.length-(d-c)-1;re(a.done,c,d,e),re(a.undone,c,d,e)}function te(a){return null!=a.defaultPrevented?a.defaultPrevented:0==a.returnValue}function ue(a){return a.target||a.srcElement}function ve(a){var b=a.which;return null==b&&(1&a.button?b=1:2&a.button?b=3:4&a.button&&(b=2)),Df&&a.ctrlKey&&1==b&&(b=3),b}function we(a,b,c){var d=a._handlers&&a._handlers[b];return c?d&&d.length>0?d.slice():Dg:d||Dg}function xe(a,b){function c(a){return function(){a.apply(null,f)}}var d=we(a,b,!1);if(d.length){var e,f=Array.prototype.slice.call(arguments,2);Rf?e=Rf.delayedCallbacks:Gg?e=Gg:(e=Gg=[],setTimeout(ye,0));for(var g=0;g<d.length;++g)e.push(c(d[g]))}}function ye(){var a=Gg;Gg=null;for(var b=0;b<a.length;++b)a[b]()}function ze(a,b,c){return"string"==typeof b&&(b={type:b,preventDefault:function(){this.defaultPrevented=!0}}),Fg(a,c||b.type,a,b),te(b)||b.codemirrorIgnore}function Ae(a){var b=a._handlers&&a._handlers.cursorActivity;if(b)for(var c=a.curOp.cursorActivityHandlers||(a.curOp.cursorActivityHandlers=[]),d=0;d<b.length;++d)-1==Ge(c,b[d])&&c.push(b[d])}function Be(a,b){return we(a,b).length>0}function Ce(a){a.prototype.on=function(a,b){Cg(this,a,b)},a.prototype.off=function(a,b){Eg(this,a,b)}}function De(){this.id=null}function Ee(a){for(;Og.length<=a;)Og.push(Fe(Og)+" ");return Og[a]}function Fe(a){return a[a.length-1]}function Ge(a,b){for(var c=0;c<a.length;++c)if(a[c]==b)return c;return-1}function He(a,b){for(var c=[],d=0;d<a.length;d++)c[d]=b(a[d],d);return c}function Ie(){}function Je(a,b){var c;return Object.create?c=Object.create(a):(Ie.prototype=a,c=new Ie),b&&Ke(b,c),c}function Ke(a,b,c){b||(b={});for(var d in a)!a.hasOwnProperty(d)||c===!1&&b.hasOwnProperty(d)||(b[d]=a[d]);return b}function Le(a){var b=Array.prototype.slice.call(arguments,1);return function(){return a.apply(null,b)}}function Me(a,b){return b?b.source.indexOf("\\w")>-1&&Sg(a)?!0:b.test(a):Sg(a)}function Ne(a){for(var b in a)if(a.hasOwnProperty(b)&&a[b])return!1;return!0}function Oe(a){return a.charCodeAt(0)>=768&&Tg.test(a)}function Pe(a,b,c,d){var e=document.createElement(a);if(c&&(e.className=c),d&&(e.style.cssText=d),"string"==typeof b)e.appendChild(document.createTextNode(b));else if(b)for(var f=0;f<b.length;++f)e.appendChild(b[f]);return e}function Qe(a){for(var b=a.childNodes.length;b>0;--b)a.removeChild(a.firstChild);return a}function Re(a,b){return Qe(a).appendChild(b)}function Se(){for(var a=document.activeElement;a&&a.root&&a.root.activeElement;)a=a.root.activeElement;return a}function Te(a){return new RegExp("(^|\\s)"+a+"(?:$|\\s)\\s*")}function Ue(a,b){for(var c=a.split(" "),d=0;d<c.length;d++)c[d]&&!Te(c[d]).test(b)&&(b+=" "+c[d]);return b}function Ve(a){if(document.body.getElementsByClassName)for(var b=document.body.getElementsByClassName("CodeMirror"),c=0;c<b.length;c++){var d=b[c].CodeMirror;d&&a(d)}}function We(){Zg||(Xe(),Zg=!0)}function Xe(){var a;Cg(window,"resize",function(){null==a&&(a=setTimeout(function(){a=null,Ve(Sb)},100))}),Cg(window,"blur",function(){Ve(rc)})}function Ye(a){if(null==Vg){var b=Pe("span","​");Re(a,Pe("span",[b,document.createTextNode("x")])),0!=a.firstChild.offsetHeight&&(Vg=b.offsetWidth<=1&&b.offsetHeight>2&&!(sf&&8>tf))}var c=Vg?Pe("span","​"):Pe("span"," ",null,"display: inline-block; width: 1px; margin-right: -1px");return c.setAttribute("cm-text",""),c}function Ze(a){if(null!=Wg)return Wg;var b=Re(a,document.createTextNode("AخA")),c=Qg(b,0,1).getBoundingClientRect();if(!c||c.left==c.right)return!1;var d=Qg(b,1,2).getBoundingClientRect();return Wg=d.right-c.right<3}function $e(a){if(null!=ch)return ch;var b=Re(a,Pe("span","x")),c=b.getBoundingClientRect(),d=Qg(b,0,1).getBoundingClientRect();return ch=Math.abs(c.left-d.left)>1}function _e(a,b,c,d){if(!a)return d(b,c,"ltr");for(var e=!1,f=0;f<a.length;++f){var g=a[f];(g.from<c&&g.to>b||b==c&&g.to==b)&&(d(Math.max(g.from,b),Math.min(g.to,c),1==g.level?"rtl":"ltr"),e=!0)}e||d(b,c,"ltr")}function af(a){return a.level%2?a.to:a.from}function bf(a){return a.level%2?a.from:a.to}function cf(a){var b=de(a);return b?af(b[0]):0}function df(a){var b=de(a);return b?bf(Fe(b)):a.text.length}function ef(a,b){var c=Yd(a.doc,b),d=rd(c);d!=c&&(b=ae(d));var e=de(d),f=e?e[0].level%2?df(d):cf(d):0;return Kf(b,f)}function ff(a,b){for(var c,d=Yd(a.doc,b);c=pd(d);)d=c.find(1,!0).line,b=null;var e=de(d),f=e?e[0].level%2?cf(d):df(d):d.text.length;return Kf(null==b?ae(d):b,f)}function gf(a,b){var c=ef(a,b.line),d=Yd(a.doc,c.line),e=de(d);if(!e||0==e[0].level){var f=Math.max(0,d.text.search(/\S/)),g=b.line==c.line&&b.ch<=f&&b.ch;return Kf(c.line,g?0:f)}return c}function hf(a,b,c){var d=a[0].level;return b==d?!0:c==d?!1:c>b}function jf(a,b){eh=null;for(var c,d=0;d<a.length;++d){var e=a[d];if(e.from<b&&e.to>b)return d;if(e.from==b||e.to==b){if(null!=c)return hf(a,e.level,a[c].level)?(e.from!=e.to&&(eh=c),d):(e.from!=e.to&&(eh=d),c);c=d}}return c}function kf(a,b,c,d){if(!d)return b+c;do b+=c;while(b>0&&Oe(a.text.charAt(b)));return b}function lf(a,b,c,d){var e=de(a);if(!e)return mf(a,b,c,d);for(var f=jf(e,b),g=e[f],h=kf(a,b,g.level%2?-c:c,d);;){if(h>g.from&&h<g.to)return h;if(h==g.from||h==g.to)return jf(e,h)==f?h:(g=e[f+=c],c>0==g.level%2?g.to:g.from);if(g=e[f+=c],!g)return null;h=c>0==g.level%2?kf(a,g.to,-1,d):kf(a,g.from,1,d)}}function mf(a,b,c,d){var e=b+c;if(d)for(;e>0&&Oe(a.text.charAt(e));)e+=c;return 0>e||e>a.text.length?null:e}var nf=navigator.userAgent,of=navigator.platform,pf=/gecko\/\d/i.test(nf),qf=/MSIE \d/.test(nf),rf=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(nf),sf=qf||rf,tf=sf&&(qf?document.documentMode||6:rf[1]),uf=/WebKit\//.test(nf),vf=uf&&/Qt\/\d+\.\d+/.test(nf),wf=/Chrome\//.test(nf),xf=/Opera\//.test(nf),yf=/Apple Computer/.test(navigator.vendor),zf=/Mac OS X 1\d\D([8-9]|\d\d)\D/.test(nf),Af=/PhantomJS/.test(nf),Bf=/AppleWebKit/.test(nf)&&/Mobile\/\w+/.test(nf),Cf=Bf||/Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(nf),Df=Bf||/Mac/.test(of),Ef=/win/i.test(of),Ff=xf&&nf.match(/Version\/(\d*\.\d*)/);Ff&&(Ff=Number(Ff[1])),Ff&&Ff>=15&&(xf=!1,uf=!0);var Gf=Df&&(vf||xf&&(null==Ff||12.11>Ff)),Hf=pf||sf&&tf>=9,If=!1,Jf=!1;p.prototype=Ke({update:function(a){var b=a.scrollWidth>a.clientWidth+1,c=a.scrollHeight>a.clientHeight+1,d=a.nativeBarWidth;if(c){this.vert.style.display="block",this.vert.style.bottom=b?d+"px":"0";var e=a.viewHeight-(b?d:0);this.vert.firstChild.style.height=Math.max(0,a.scrollHeight-a.clientHeight+e)+"px"}else this.vert.style.display="",this.vert.firstChild.style.height="0";if(b){this.horiz.style.display="block",this.horiz.style.right=c?d+"px":"0",this.horiz.style.left=a.barLeft+"px";var f=a.viewWidth-a.barLeft-(c?d:0);this.horiz.firstChild.style.width=a.scrollWidth-a.clientWidth+f+"px"}else this.horiz.style.display="",this.horiz.firstChild.style.width="0";return!this.checkedZeroWidth&&a.clientHeight>0&&(0==d&&this.zeroWidthHack(),this.checkedZeroWidth=!0),{right:c?d:0,bottom:b?d:0}},setScrollLeft:function(a){this.horiz.scrollLeft!=a&&(this.horiz.scrollLeft=a),this.disableHoriz&&this.enableZeroWidthBar(this.horiz,this.disableHoriz)},setScrollTop:function(a){this.vert.scrollTop!=a&&(this.vert.scrollTop=a),this.disableVert&&this.enableZeroWidthBar(this.vert,this.disableVert)},zeroWidthHack:function(){var a=Df&&!zf?"12px":"18px";this.horiz.style.height=this.vert.style.width=a,this.horiz.style.pointerEvents=this.vert.style.pointerEvents="none",this.disableHoriz=new De,this.disableVert=new De},enableZeroWidthBar:function(a,b){function c(){var d=a.getBoundingClientRect(),e=document.elementFromPoint(d.left+1,d.bottom-1);e!=a?a.style.pointerEvents="none":b.set(1e3,c)}a.style.pointerEvents="auto",b.set(1e3,c)},clear:function(){var a=this.horiz.parentNode;a.removeChild(this.horiz),a.removeChild(this.vert)}},p.prototype),q.prototype=Ke({update:function(){return{bottom:0,right:0}},setScrollLeft:function(){},setScrollTop:function(){},clear:function(){}},q.prototype),a.scrollbarModel={"native":p,"null":q},z.prototype.signal=function(a,b){Be(a,b)&&this.events.push(arguments)},z.prototype.finish=function(){for(var a=0;a<this.events.length;a++)Fg.apply(null,this.events[a])};var Kf=a.Pos=function(a,b){return this instanceof Kf?(this.line=a,void(this.ch=b)):new Kf(a,b)},Lf=a.cmpPos=function(a,b){return a.line-b.line||a.ch-b.ch},Mf=null;ca.prototype=Ke({init:function(a){function b(a){
4
+ if(d.somethingSelected())Mf=d.getSelections(),c.inaccurateSelection&&(c.prevInput="",c.inaccurateSelection=!1,f.value=Mf.join("\n"),Pg(f));else{if(!d.options.lineWiseCopyCut)return;var b=aa(d);Mf=b.text,"cut"==a.type?d.setSelections(b.ranges,null,Jg):(c.prevInput="",f.value=b.text.join("\n"),Pg(f))}"cut"==a.type&&(d.state.cutIncoming=!0)}var c=this,d=this.cm,e=this.wrapper=da(),f=this.textarea=e.firstChild;a.wrapper.insertBefore(e,a.wrapper.firstChild),Bf&&(f.style.width="0px"),Cg(f,"input",function(){sf&&tf>=9&&c.hasSelection&&(c.hasSelection=null),c.poll()}),Cg(f,"paste",function(a){ze(d,a)||$(a,d)||(d.state.pasteIncoming=!0,c.fastPoll())}),Cg(f,"cut",b),Cg(f,"copy",b),Cg(a.scroller,"paste",function(b){Tb(a,b)||ze(d,b)||(d.state.pasteIncoming=!0,c.focus())}),Cg(a.lineSpace,"selectstart",function(b){Tb(a,b)||zg(b)}),Cg(f,"compositionstart",function(){var a=d.getCursor("from");c.composing&&c.composing.range.clear(),c.composing={start:a,range:d.markText(a,d.getCursor("to"),{className:"CodeMirror-composing"})}}),Cg(f,"compositionend",function(){c.composing&&(c.poll(),c.composing.range.clear(),c.composing=null)})},prepareSelection:function(){var a=this.cm,b=a.display,c=a.doc,d=Ja(a);if(a.options.moveInputWithCursor){var e=nb(a,c.sel.primary().head,"div"),f=b.wrapper.getBoundingClientRect(),g=b.lineDiv.getBoundingClientRect();d.teTop=Math.max(0,Math.min(b.wrapper.clientHeight-10,e.top+g.top-f.top)),d.teLeft=Math.max(0,Math.min(b.wrapper.clientWidth-10,e.left+g.left-f.left))}return d},showSelection:function(a){var b=this.cm,c=b.display;Re(c.cursorDiv,a.cursors),Re(c.selectionDiv,a.selection),null!=a.teTop&&(this.wrapper.style.top=a.teTop+"px",this.wrapper.style.left=a.teLeft+"px")},reset:function(a){if(!this.contextMenuPending){var b,c,d=this.cm,e=d.doc;if(d.somethingSelected()){this.prevInput="";var f=e.sel.primary();b=bh&&(f.to().line-f.from().line>100||(c=d.getSelection()).length>1e3);var g=b?"-":c||d.getSelection();this.textarea.value=g,d.state.focused&&Pg(this.textarea),sf&&tf>=9&&(this.hasSelection=g)}else a||(this.prevInput=this.textarea.value="",sf&&tf>=9&&(this.hasSelection=null));this.inaccurateSelection=b}},getField:function(){return this.textarea},supportsTouch:function(){return!1},focus:function(){if("nocursor"!=this.cm.options.readOnly&&(!Cf||Se()!=this.textarea))try{this.textarea.focus()}catch(a){}},blur:function(){this.textarea.blur()},resetPosition:function(){this.wrapper.style.top=this.wrapper.style.left=0},receivedFocus:function(){this.slowPoll()},slowPoll:function(){var a=this;a.pollingFast||a.polling.set(this.cm.options.pollInterval,function(){a.poll(),a.cm.state.focused&&a.slowPoll()})},fastPoll:function(){function a(){var d=c.poll();d||b?(c.pollingFast=!1,c.slowPoll()):(b=!0,c.polling.set(60,a))}var b=!1,c=this;c.pollingFast=!0,c.polling.set(20,a)},poll:function(){var a=this.cm,b=this.textarea,c=this.prevInput;if(this.contextMenuPending||!a.state.focused||ah(b)&&!c&&!this.composing||a.isReadOnly()||a.options.disableInput||a.state.keySeq)return!1;var d=b.value;if(d==c&&!a.somethingSelected())return!1;if(sf&&tf>=9&&this.hasSelection===d||Df&&/[\uf700-\uf7ff]/.test(d))return a.display.input.reset(),!1;if(a.doc.sel==a.display.selForContextMenu){var e=d.charCodeAt(0);if(8203!=e||c||(c="​"),8666==e)return this.reset(),this.cm.execCommand("undo")}for(var f=0,g=Math.min(c.length,d.length);g>f&&c.charCodeAt(f)==d.charCodeAt(f);)++f;var h=this;return Db(a,function(){Z(a,d.slice(f),c.length-f,null,h.composing?"*compose":null),d.length>1e3||d.indexOf("\n")>-1?b.value=h.prevInput="":h.prevInput=d,h.composing&&(h.composing.range.clear(),h.composing.range=a.markText(h.composing.start,a.getCursor("to"),{className:"CodeMirror-composing"}))}),!0},ensurePolled:function(){this.pollingFast&&this.poll()&&(this.pollingFast=!1)},onKeyPress:function(){sf&&tf>=9&&(this.hasSelection=null),this.fastPoll()},onContextMenu:function(a){function b(){if(null!=g.selectionStart){var a=e.somethingSelected(),b="​"+(a?g.value:"");g.value="⇚",g.value=b,d.prevInput=a?"":"​",g.selectionStart=1,g.selectionEnd=b.length,f.selForContextMenu=e.doc.sel}}function c(){if(d.contextMenuPending=!1,d.wrapper.style.position="relative",g.style.cssText=k,sf&&9>tf&&f.scrollbars.setScrollTop(f.scroller.scrollTop=i),null!=g.selectionStart){(!sf||sf&&9>tf)&&b();var a=0,c=function(){f.selForContextMenu==e.doc.sel&&0==g.selectionStart&&g.selectionEnd>0&&"​"==d.prevInput?Eb(e,ig.selectAll)(e):a++<10?f.detectingSelectAll=setTimeout(c,500):f.input.reset()};f.detectingSelectAll=setTimeout(c,200)}}var d=this,e=d.cm,f=e.display,g=d.textarea,h=Ub(e,a),i=f.scroller.scrollTop;if(h&&!xf){var j=e.options.resetSelectionOnContextMenu;j&&-1==e.doc.sel.contains(h)&&Eb(e,Aa)(e.doc,na(h),Jg);var k=g.style.cssText;if(d.wrapper.style.position="absolute",g.style.cssText="position: fixed; width: 30px; height: 30px; top: "+(a.clientY-5)+"px; left: "+(a.clientX-5)+"px; z-index: 1000; background: "+(sf?"rgba(255, 255, 255, .05)":"transparent")+"; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);",uf)var l=window.scrollY;if(f.input.focus(),uf&&window.scrollTo(null,l),f.input.reset(),e.somethingSelected()||(g.value=d.prevInput=" "),d.contextMenuPending=!0,f.selForContextMenu=e.doc.sel,clearTimeout(f.detectingSelectAll),sf&&tf>=9&&b(),Hf){Bg(a);var m=function(){Eg(window,"mouseup",m),setTimeout(c,20)};Cg(window,"mouseup",m)}else setTimeout(c,50)}},readOnlyChanged:function(a){a||this.reset()},setUneditable:Ie,needsContentAttribute:!1},ca.prototype),ea.prototype=Ke({init:function(a){function b(a){if(d.somethingSelected())Mf=d.getSelections(),"cut"==a.type&&d.replaceSelection("",null,"cut");else{if(!d.options.lineWiseCopyCut)return;var b=aa(d);Mf=b.text,"cut"==a.type&&d.operation(function(){d.setSelections(b.ranges,0,Jg),d.replaceSelection("",null,"cut")})}if(a.clipboardData&&!Bf)a.preventDefault(),a.clipboardData.clearData(),a.clipboardData.setData("text/plain",Mf.join("\n"));else{var c=da(),e=c.firstChild;d.display.lineSpace.insertBefore(c,d.display.lineSpace.firstChild),e.value=Mf.join("\n");var f=document.activeElement;Pg(e),setTimeout(function(){d.display.lineSpace.removeChild(c),f.focus()},50)}}var c=this,d=c.cm,e=c.div=a.lineDiv;ba(e),Cg(e,"paste",function(a){ze(d,a)||$(a,d)}),Cg(e,"compositionstart",function(a){var b=a.data;if(c.composing={sel:d.doc.sel,data:b,startData:b},b){var e=d.doc.sel.primary(),f=d.getLine(e.head.line),g=f.indexOf(b,Math.max(0,e.head.ch-b.length));g>-1&&g<=e.head.ch&&(c.composing.sel=na(Kf(e.head.line,g),Kf(e.head.line,g+b.length)))}}),Cg(e,"compositionupdate",function(a){c.composing.data=a.data}),Cg(e,"compositionend",function(a){var b=c.composing;b&&(a.data==b.startData||/\u200b/.test(a.data)||(b.data=a.data),setTimeout(function(){b.handled||c.applyComposition(b),c.composing==b&&(c.composing=null)},50))}),Cg(e,"touchstart",function(){c.forceCompositionEnd()}),Cg(e,"input",function(){c.composing||(d.isReadOnly()||!c.pollContent())&&Db(c.cm,function(){Jb(d)})}),Cg(e,"copy",b),Cg(e,"cut",b)},prepareSelection:function(){var a=Ja(this.cm,!1);return a.focus=this.cm.state.focused,a},showSelection:function(a){a&&this.cm.display.view.length&&(a.focus&&this.showPrimarySelection(),this.showMultipleSelections(a))},showPrimarySelection:function(){var a=window.getSelection(),b=this.cm.doc.sel.primary(),c=ha(this.cm,a.anchorNode,a.anchorOffset),d=ha(this.cm,a.focusNode,a.focusOffset);if(!c||c.bad||!d||d.bad||0!=Lf(X(c,d),b.from())||0!=Lf(W(c,d),b.to())){var e=fa(this.cm,b.from()),f=fa(this.cm,b.to());if(e||f){var g=this.cm.display.view,h=a.rangeCount&&a.getRangeAt(0);if(e){if(!f){var i=g[g.length-1].measure,j=i.maps?i.maps[i.maps.length-1]:i.map;f={node:j[j.length-1],offset:j[j.length-2]-j[j.length-3]}}}else e={node:g[0].measure.map[2],offset:0};try{var k=Qg(e.node,e.offset,f.offset,f.node)}catch(l){}k&&(!pf&&this.cm.state.focused?(a.collapse(e.node,e.offset),k.collapsed||a.addRange(k)):(a.removeAllRanges(),a.addRange(k)),h&&null==a.anchorNode?a.addRange(h):pf&&this.startGracePeriod()),this.rememberSelection()}}},startGracePeriod:function(){var a=this;clearTimeout(this.gracePeriod),this.gracePeriod=setTimeout(function(){a.gracePeriod=!1,a.selectionChanged()&&a.cm.operation(function(){a.cm.curOp.selectionChanged=!0})},20)},showMultipleSelections:function(a){Re(this.cm.display.cursorDiv,a.cursors),Re(this.cm.display.selectionDiv,a.selection)},rememberSelection:function(){var a=window.getSelection();this.lastAnchorNode=a.anchorNode,this.lastAnchorOffset=a.anchorOffset,this.lastFocusNode=a.focusNode,this.lastFocusOffset=a.focusOffset},selectionInEditor:function(){var a=window.getSelection();if(!a.rangeCount)return!1;var b=a.getRangeAt(0).commonAncestorContainer;return Ug(this.div,b)},focus:function(){"nocursor"!=this.cm.options.readOnly&&this.div.focus()},blur:function(){this.div.blur()},getField:function(){return this.div},supportsTouch:function(){return!0},receivedFocus:function(){function a(){b.cm.state.focused&&(b.pollSelection(),b.polling.set(b.cm.options.pollInterval,a))}var b=this;this.selectionInEditor()?this.pollSelection():Db(this.cm,function(){b.cm.curOp.selectionChanged=!0}),this.polling.set(this.cm.options.pollInterval,a)},selectionChanged:function(){var a=window.getSelection();return a.anchorNode!=this.lastAnchorNode||a.anchorOffset!=this.lastAnchorOffset||a.focusNode!=this.lastFocusNode||a.focusOffset!=this.lastFocusOffset},pollSelection:function(){if(!this.composing&&!this.gracePeriod&&this.selectionChanged()){var a=window.getSelection(),b=this.cm;this.rememberSelection();var c=ha(b,a.anchorNode,a.anchorOffset),d=ha(b,a.focusNode,a.focusOffset);c&&d&&Db(b,function(){Aa(b.doc,na(c,d),Jg),(c.bad||d.bad)&&(b.curOp.selectionChanged=!0)})}},pollContent:function(){var a=this.cm,b=a.display,c=a.doc.sel.primary(),d=c.from(),e=c.to();if(d.line<b.viewFrom||e.line>b.viewTo-1)return!1;var f;if(d.line==b.viewFrom||0==(f=Mb(a,d.line)))var g=ae(b.view[0].line),h=b.view[0].node;else var g=ae(b.view[f].line),h=b.view[f-1].node.nextSibling;var i=Mb(a,e.line);if(i==b.view.length-1)var j=b.viewTo-1,k=b.lineDiv.lastChild;else var j=ae(b.view[i+1].line)-1,k=b.view[i+1].node.previousSibling;for(var l=a.doc.splitLines(ja(a,h,k,g,j)),m=Zd(a.doc,Kf(g,0),Kf(j,Yd(a.doc,j).text.length));l.length>1&&m.length>1;)if(Fe(l)==Fe(m))l.pop(),m.pop(),j--;else{if(l[0]!=m[0])break;l.shift(),m.shift(),g++}for(var n=0,o=0,p=l[0],q=m[0],r=Math.min(p.length,q.length);r>n&&p.charCodeAt(n)==q.charCodeAt(n);)++n;for(var s=Fe(l),t=Fe(m),u=Math.min(s.length-(1==l.length?n:0),t.length-(1==m.length?n:0));u>o&&s.charCodeAt(s.length-o-1)==t.charCodeAt(t.length-o-1);)++o;l[l.length-1]=s.slice(0,s.length-o),l[0]=l[0].slice(n);var v=Kf(g,n),w=Kf(j,m.length?Fe(m).length-o:0);return l.length>1||l[0]||Lf(v,w)?(Fc(a.doc,l,v,w,"+input"),!0):void 0},ensurePolled:function(){this.forceCompositionEnd()},reset:function(){this.forceCompositionEnd()},forceCompositionEnd:function(){this.composing&&!this.composing.handled&&(this.applyComposition(this.composing),this.composing.handled=!0,this.div.blur(),this.div.focus())},applyComposition:function(a){this.cm.isReadOnly()?Eb(this.cm,Jb)(this.cm):a.data&&a.data!=a.startData&&Eb(this.cm,Z)(this.cm,a.data,0,a.sel)},setUneditable:function(a){a.contentEditable="false"},onKeyPress:function(a){a.preventDefault(),this.cm.isReadOnly()||Eb(this.cm,Z)(this.cm,String.fromCharCode(null==a.charCode?a.keyCode:a.charCode),0)},readOnlyChanged:function(a){this.div.contentEditable=String("nocursor"!=a)},onContextMenu:Ie,resetPosition:Ie,needsContentAttribute:!0},ea.prototype),a.inputStyles={textarea:ca,contenteditable:ea},ka.prototype={primary:function(){return this.ranges[this.primIndex]},equals:function(a){if(a==this)return!0;if(a.primIndex!=this.primIndex||a.ranges.length!=this.ranges.length)return!1;for(var b=0;b<this.ranges.length;b++){var c=this.ranges[b],d=a.ranges[b];if(0!=Lf(c.anchor,d.anchor)||0!=Lf(c.head,d.head))return!1}return!0},deepCopy:function(){for(var a=[],b=0;b<this.ranges.length;b++)a[b]=new la(V(this.ranges[b].anchor),V(this.ranges[b].head));return new ka(a,this.primIndex)},somethingSelected:function(){for(var a=0;a<this.ranges.length;a++)if(!this.ranges[a].empty())return!0;return!1},contains:function(a,b){b||(b=a);for(var c=0;c<this.ranges.length;c++){var d=this.ranges[c];if(Lf(b,d.from())>=0&&Lf(a,d.to())<=0)return c}return-1}},la.prototype={from:function(){return X(this.anchor,this.head)},to:function(){return W(this.anchor,this.head)},empty:function(){return this.head.line==this.anchor.line&&this.head.ch==this.anchor.ch}};var Nf,Of,Pf,Qf={left:0,right:0,top:0,bottom:0},Rf=null,Sf=0,Tf=0,Uf=0,Vf=null;sf?Vf=-.53:pf?Vf=15:wf?Vf=-.7:yf&&(Vf=-1/3);var Wf=function(a){var b=a.wheelDeltaX,c=a.wheelDeltaY;return null==b&&a.detail&&a.axis==a.HORIZONTAL_AXIS&&(b=a.detail),null==c&&a.detail&&a.axis==a.VERTICAL_AXIS?c=a.detail:null==c&&(c=a.wheelDelta),{x:b,y:c}};a.wheelEventPixels=function(a){var b=Wf(a);return b.x*=Vf,b.y*=Vf,b};var Xf=new De,Yf=null,Zf=a.changeEnd=function(a){return a.text?Kf(a.from.line+a.text.length-1,Fe(a.text).length+(1==a.text.length?a.from.ch:0)):a.to};a.prototype={constructor:a,focus:function(){window.focus(),this.display.input.focus()},setOption:function(a,b){var c=this.options,d=c[a];(c[a]!=b||"mode"==a)&&(c[a]=b,_f.hasOwnProperty(a)&&Eb(this,_f[a])(this,b,d))},getOption:function(a){return this.options[a]},getDoc:function(){return this.doc},addKeyMap:function(a,b){this.state.keyMaps[b?"push":"unshift"](Uc(a))},removeKeyMap:function(a){for(var b=this.state.keyMaps,c=0;c<b.length;++c)if(b[c]==a||b[c].name==a)return b.splice(c,1),!0},addOverlay:Fb(function(b,c){var d=b.token?b:a.getMode(this.options,b);if(d.startState)throw new Error("Overlays may not be stateful.");this.state.overlays.push({mode:d,modeSpec:b,opaque:c&&c.opaque}),this.state.modeGen++,Jb(this)}),removeOverlay:Fb(function(a){for(var b=this.state.overlays,c=0;c<b.length;++c){var d=b[c].modeSpec;if(d==a||"string"==typeof a&&d.name==a)return b.splice(c,1),this.state.modeGen++,void Jb(this)}}),indentLine:Fb(function(a,b,c){"string"!=typeof b&&"number"!=typeof b&&(b=null==b?this.options.smartIndent?"smart":"prev":b?"add":"subtract"),ra(this.doc,a)&&Nc(this,a,b,c)}),indentSelection:Fb(function(a){for(var b=this.doc.sel.ranges,c=-1,d=0;d<b.length;d++){var e=b[d];if(e.empty())e.head.line>c&&(Nc(this,e.head.line,a,!0),c=e.head.line,d==this.doc.sel.primIndex&&Lc(this));else{var f=e.from(),g=e.to(),h=Math.max(c,f.line);c=Math.min(this.lastLine(),g.line-(g.ch?0:1))+1;for(var i=h;c>i;++i)Nc(this,i,a);var j=this.doc.sel.ranges;0==f.ch&&b.length==j.length&&j[d].from().ch>0&&wa(this.doc,d,new la(f,j[d].to()),Jg)}}}),getTokenAt:function(a,b){return Fd(this,a,b)},getLineTokens:function(a,b){return Fd(this,Kf(a),b,!0)},getTokenTypeAt:function(a){a=pa(this.doc,a);var b,c=Id(this,Yd(this.doc,a.line)),d=0,e=(c.length-1)/2,f=a.ch;if(0==f)b=c[2];else for(;;){var g=d+e>>1;if((g?c[2*g-1]:0)>=f)e=g;else{if(!(c[2*g+1]<f)){b=c[2*g+2];break}d=g+1}}var h=b?b.indexOf("cm-overlay "):-1;return 0>h?b:0==h?null:b.slice(0,h-1)},getModeAt:function(b){var c=this.doc.mode;return c.innerMode?a.innerMode(c,this.getTokenAt(b).state).mode:c},getHelper:function(a,b){return this.getHelpers(a,b)[0]},getHelpers:function(a,b){var c=[];if(!fg.hasOwnProperty(b))return c;var d=fg[b],e=this.getModeAt(a);if("string"==typeof e[b])d[e[b]]&&c.push(d[e[b]]);else if(e[b])for(var f=0;f<e[b].length;f++){var g=d[e[b][f]];g&&c.push(g)}else e.helperType&&d[e.helperType]?c.push(d[e.helperType]):d[e.name]&&c.push(d[e.name]);for(var f=0;f<d._global.length;f++){var h=d._global[f];h.pred(e,this)&&-1==Ge(c,h.val)&&c.push(h.val)}return c},getStateAfter:function(a,b){var c=this.doc;return a=oa(c,null==a?c.first+c.size-1:a),Qa(this,a+1,b)},cursorCoords:function(a,b){var c,d=this.doc.sel.primary();return c=null==a?d.head:"object"==typeof a?pa(this.doc,a):a?d.from():d.to(),nb(this,c,b||"page")},charCoords:function(a,b){return mb(this,pa(this.doc,a),b||"page")},coordsChar:function(a,b){return a=lb(this,a,b||"page"),qb(this,a.left,a.top)},lineAtHeight:function(a,b){return a=lb(this,{top:a,left:0},b||"page").top,be(this.doc,a+this.display.viewOffset)},heightAtLine:function(a,b){var c,d=!1;if("number"==typeof a){var e=this.doc.first+this.doc.size-1;a<this.doc.first?a=this.doc.first:a>e&&(a=e,d=!0),c=Yd(this.doc,a)}else c=a;return kb(this,c,{top:0,left:0},b||"page").top+(d?this.doc.height-ce(c):0)},defaultTextHeight:function(){return sb(this.display)},defaultCharWidth:function(){return tb(this.display)},setGutterMarker:Fb(function(a,b,c){return Oc(this.doc,a,"gutter",function(a){var d=a.gutterMarkers||(a.gutterMarkers={});return d[b]=c,!c&&Ne(d)&&(a.gutterMarkers=null),!0})}),clearGutter:Fb(function(a){var b=this,c=b.doc,d=c.first;c.iter(function(c){c.gutterMarkers&&c.gutterMarkers[a]&&(c.gutterMarkers[a]=null,Kb(b,d,"gutter"),Ne(c.gutterMarkers)&&(c.gutterMarkers=null)),++d})}),lineInfo:function(a){if("number"==typeof a){if(!ra(this.doc,a))return null;var b=a;if(a=Yd(this.doc,a),!a)return null}else{var b=ae(a);if(null==b)return null}return{line:b,handle:a,text:a.text,gutterMarkers:a.gutterMarkers,textClass:a.textClass,bgClass:a.bgClass,wrapClass:a.wrapClass,widgets:a.widgets}},getViewport:function(){return{from:this.display.viewFrom,to:this.display.viewTo}},addWidget:function(a,b,c,d,e){var f=this.display;a=nb(this,pa(this.doc,a));var g=a.bottom,h=a.left;if(b.style.position="absolute",b.setAttribute("cm-ignore-events","true"),this.display.input.setUneditable(b),f.sizer.appendChild(b),"over"==d)g=a.top;else if("above"==d||"near"==d){var i=Math.max(f.wrapper.clientHeight,this.doc.height),j=Math.max(f.sizer.clientWidth,f.lineSpace.clientWidth);("above"==d||a.bottom+b.offsetHeight>i)&&a.top>b.offsetHeight?g=a.top-b.offsetHeight:a.bottom+b.offsetHeight<=i&&(g=a.bottom),h+b.offsetWidth>j&&(h=j-b.offsetWidth)}b.style.top=g+"px",b.style.left=b.style.right="","right"==e?(h=f.sizer.clientWidth-b.offsetWidth,b.style.right="0px"):("left"==e?h=0:"middle"==e&&(h=(f.sizer.clientWidth-b.offsetWidth)/2),b.style.left=h+"px"),c&&Ic(this,h,g,h+b.offsetWidth,g+b.offsetHeight)},triggerOnKeyDown:Fb(lc),triggerOnKeyPress:Fb(oc),triggerOnKeyUp:nc,execCommand:function(a){return ig.hasOwnProperty(a)?ig[a].call(null,this):void 0},triggerElectric:Fb(function(a){_(this,a)}),findPosH:function(a,b,c,d){var e=1;0>b&&(e=-1,b=-b);for(var f=0,g=pa(this.doc,a);b>f&&(g=Qc(this.doc,g,e,c,d),!g.hitSide);++f);return g},moveH:Fb(function(a,b){var c=this;c.extendSelectionsBy(function(d){return c.display.shift||c.doc.extend||d.empty()?Qc(c.doc,d.head,a,b,c.options.rtlMoveVisually):0>a?d.from():d.to()},Lg)}),deleteH:Fb(function(a,b){var c=this.doc.sel,d=this.doc;c.somethingSelected()?d.replaceSelection("",null,"+delete"):Pc(this,function(c){var e=Qc(d,c.head,a,b,!1);return 0>a?{from:e,to:c.head}:{from:c.head,to:e}})}),findPosV:function(a,b,c,d){var e=1,f=d;0>b&&(e=-1,b=-b);for(var g=0,h=pa(this.doc,a);b>g;++g){var i=nb(this,h,"div");if(null==f?f=i.left:i.left=f,h=Rc(this,i,e,c),h.hitSide)break}return h},moveV:Fb(function(a,b){var c=this,d=this.doc,e=[],f=!c.display.shift&&!d.extend&&d.sel.somethingSelected();if(d.extendSelectionsBy(function(g){if(f)return 0>a?g.from():g.to();var h=nb(c,g.head,"div");null!=g.goalColumn&&(h.left=g.goalColumn),e.push(h.left);var i=Rc(c,h,a,b);return"page"==b&&g==d.sel.primary()&&Kc(c,null,mb(c,i,"div").top-h.top),i},Lg),e.length)for(var g=0;g<d.sel.ranges.length;g++)d.sel.ranges[g].goalColumn=e[g]}),findWordAt:function(a){var b=this.doc,c=Yd(b,a.line).text,d=a.ch,e=a.ch;if(c){var f=this.getHelper(a,"wordChars");(a.xRel<0||e==c.length)&&d?--d:++e;for(var g=c.charAt(d),h=Me(g,f)?function(a){return Me(a,f)}:/\s/.test(g)?function(a){return/\s/.test(a)}:function(a){return!/\s/.test(a)&&!Me(a)};d>0&&h(c.charAt(d-1));)--d;for(;e<c.length&&h(c.charAt(e));)++e}return new la(Kf(a.line,d),Kf(a.line,e))},toggleOverwrite:function(a){(null==a||a!=this.state.overwrite)&&((this.state.overwrite=!this.state.overwrite)?Yg(this.display.cursorDiv,"CodeMirror-overwrite"):Xg(this.display.cursorDiv,"CodeMirror-overwrite"),Fg(this,"overwriteToggle",this,this.state.overwrite))},hasFocus:function(){return this.display.input.getField()==Se()},isReadOnly:function(){return!(!this.options.readOnly&&!this.doc.cantEdit)},scrollTo:Fb(function(a,b){(null!=a||null!=b)&&Mc(this),null!=a&&(this.curOp.scrollLeft=a),null!=b&&(this.curOp.scrollTop=b)}),getScrollInfo:function(){var a=this.display.scroller;return{left:a.scrollLeft,top:a.scrollTop,height:a.scrollHeight-Ua(this)-this.display.barHeight,width:a.scrollWidth-Ua(this)-this.display.barWidth,clientHeight:Wa(this),clientWidth:Va(this)}},scrollIntoView:Fb(function(a,b){if(null==a?(a={from:this.doc.sel.primary().head,to:null},null==b&&(b=this.options.cursorScrollMargin)):"number"==typeof a?a={from:Kf(a,0),to:null}:null==a.from&&(a={from:a,to:null}),a.to||(a.to=a.from),a.margin=b||0,null!=a.from.line)Mc(this),this.curOp.scrollToPos=a;else{var c=Jc(this,Math.min(a.from.left,a.to.left),Math.min(a.from.top,a.to.top)-a.margin,Math.max(a.from.right,a.to.right),Math.max(a.from.bottom,a.to.bottom)+a.margin);this.scrollTo(c.scrollLeft,c.scrollTop)}}),setSize:Fb(function(a,b){function c(a){return"number"==typeof a||/^\d+$/.test(String(a))?a+"px":a}var d=this;null!=a&&(d.display.wrapper.style.width=c(a)),null!=b&&(d.display.wrapper.style.height=c(b)),d.options.lineWrapping&&gb(this);var e=d.display.viewFrom;d.doc.iter(e,d.display.viewTo,function(a){if(a.widgets)for(var b=0;b<a.widgets.length;b++)if(a.widgets[b].noHScroll){Kb(d,e,"widget");break}++e}),d.curOp.forceUpdate=!0,Fg(d,"refresh",this)}),operation:function(a){return Db(this,a)},refresh:Fb(function(){var a=this.display.cachedTextHeight;Jb(this),this.curOp.forceUpdate=!0,hb(this),this.scrollTo(this.doc.scrollLeft,this.doc.scrollTop),k(this),(null==a||Math.abs(a-sb(this.display))>.5)&&g(this),Fg(this,"refresh",this)}),swapDoc:Fb(function(a){var b=this.doc;return b.cm=null,Xd(this,a),hb(this),this.display.input.reset(),this.scrollTo(a.scrollLeft,a.scrollTop),this.curOp.forceScroll=!0,xe(this,"swapDoc",this,b),b}),getInputField:function(){return this.display.input.getField()},getWrapperElement:function(){return this.display.wrapper},getScrollerElement:function(){return this.display.scroller},getGutterElement:function(){return this.display.gutters}},Ce(a);var $f=a.defaults={},_f=a.optionHandlers={},ag=a.Init={toString:function(){return"CodeMirror.Init"}};Sc("value","",function(a,b){a.setValue(b)},!0),Sc("mode",null,function(a,b){a.doc.modeOption=b,c(a)},!0),Sc("indentUnit",2,c,!0),Sc("indentWithTabs",!1),Sc("smartIndent",!0),Sc("tabSize",4,function(a){d(a),hb(a),Jb(a)},!0),Sc("lineSeparator",null,function(a,b){if(a.doc.lineSep=b,b){var c=[],d=a.doc.first;a.doc.iter(function(a){for(var e=0;;){var f=a.text.indexOf(b,e);if(-1==f)break;e=f+b.length,c.push(Kf(d,f))}d++});for(var e=c.length-1;e>=0;e--)Fc(a.doc,b,c[e],Kf(c[e].line,c[e].ch+b.length))}}),Sc("specialChars",/[\t\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g,function(b,c,d){b.state.specialChars=new RegExp(c.source+(c.test(" ")?"":"| "),"g"),d!=a.Init&&b.refresh()}),Sc("specialCharPlaceholder",Md,function(a){a.refresh()},!0),Sc("electricChars",!0),Sc("inputStyle",Cf?"contenteditable":"textarea",function(){throw new Error("inputStyle can not (yet) be changed in a running editor")},!0),Sc("rtlMoveVisually",!Ef),Sc("wholeLineUpdateBefore",!0),Sc("theme","default",function(a){h(a),i(a)},!0),Sc("keyMap","default",function(b,c,d){var e=Uc(c),f=d!=a.Init&&Uc(d);f&&f.detach&&f.detach(b,e),e.attach&&e.attach(b,f||null)}),Sc("extraKeys",null),Sc("lineWrapping",!1,e,!0),Sc("gutters",[],function(a){n(a.options),i(a)},!0),Sc("fixedGutter",!0,function(a,b){a.display.gutters.style.left=b?y(a.display)+"px":"0",a.refresh()},!0),Sc("coverGutterNextToScrollbar",!1,function(a){s(a)},!0),Sc("scrollbarStyle","native",function(a){r(a),s(a),a.display.scrollbars.setScrollTop(a.doc.scrollTop),a.display.scrollbars.setScrollLeft(a.doc.scrollLeft)},!0),Sc("lineNumbers",!1,function(a){n(a.options),i(a)},!0),Sc("firstLineNumber",1,i,!0),Sc("lineNumberFormatter",function(a){return a},i,!0),Sc("showCursorWhenSelecting",!1,Ia,!0),Sc("resetSelectionOnContextMenu",!0),Sc("lineWiseCopyCut",!0),Sc("readOnly",!1,function(a,b){"nocursor"==b?(rc(a),a.display.input.blur(),a.display.disabled=!0):a.display.disabled=!1,a.display.input.readOnlyChanged(b)}),Sc("disableInput",!1,function(a,b){b||a.display.input.reset()},!0),Sc("dragDrop",!0,Rb),Sc("allowDropFileTypes",null),Sc("cursorBlinkRate",530),Sc("cursorScrollMargin",0),Sc("cursorHeight",1,Ia,!0),Sc("singleCursorHeightPerLine",!0,Ia,!0),Sc("workTime",100),Sc("workDelay",100),Sc("flattenSpans",!0,d,!0),Sc("addModeClass",!1,d,!0),Sc("pollInterval",100),Sc("undoDepth",200,function(a,b){a.doc.history.undoDepth=b}),Sc("historyEventDelay",1250),Sc("viewportMargin",10,function(a){a.refresh()},!0),Sc("maxHighlightLength",1e4,d,!0),Sc("moveInputWithCursor",!0,function(a,b){b||a.display.input.resetPosition()}),Sc("tabindex",null,function(a,b){a.display.input.getField().tabIndex=b||""}),Sc("autofocus",null);var bg=a.modes={},cg=a.mimeModes={};a.defineMode=function(b,c){a.defaults.mode||"null"==b||(a.defaults.mode=b),arguments.length>2&&(c.dependencies=Array.prototype.slice.call(arguments,2)),bg[b]=c},a.defineMIME=function(a,b){cg[a]=b},a.resolveMode=function(b){if("string"==typeof b&&cg.hasOwnProperty(b))b=cg[b];else if(b&&"string"==typeof b.name&&cg.hasOwnProperty(b.name)){var c=cg[b.name];"string"==typeof c&&(c={name:c}),b=Je(c,b),b.name=c.name}else if("string"==typeof b&&/^[\w\-]+\/[\w\-]+\+xml$/.test(b))return a.resolveMode("application/xml");return"string"==typeof b?{name:b}:b||{name:"null"}},a.getMode=function(b,c){var c=a.resolveMode(c),d=bg[c.name];if(!d)return a.getMode(b,"text/plain");var e=d(b,c);if(dg.hasOwnProperty(c.name)){var f=dg[c.name];for(var g in f)f.hasOwnProperty(g)&&(e.hasOwnProperty(g)&&(e["_"+g]=e[g]),e[g]=f[g])}if(e.name=c.name,c.helperType&&(e.helperType=c.helperType),c.modeProps)for(var g in c.modeProps)e[g]=c.modeProps[g];return e},a.defineMode("null",function(){return{token:function(a){a.skipToEnd()}}}),a.defineMIME("text/plain","null");var dg=a.modeExtensions={};a.extendMode=function(a,b){var c=dg.hasOwnProperty(a)?dg[a]:dg[a]={};Ke(b,c)},a.defineExtension=function(b,c){a.prototype[b]=c},a.defineDocExtension=function(a,b){wg.prototype[a]=b},a.defineOption=Sc;var eg=[];a.defineInitHook=function(a){eg.push(a)};var fg=a.helpers={};a.registerHelper=function(b,c,d){fg.hasOwnProperty(b)||(fg[b]=a[b]={_global:[]}),fg[b][c]=d},a.registerGlobalHelper=function(b,c,d,e){a.registerHelper(b,c,e),fg[b]._global.push({pred:d,val:e})};var gg=a.copyState=function(a,b){if(b===!0)return b;if(a.copyState)return a.copyState(b);var c={};for(var d in b){var e=b[d];e instanceof Array&&(e=e.concat([])),c[d]=e}return c},hg=a.startState=function(a,b,c){return a.startState?a.startState(b,c):!0};a.innerMode=function(a,b){for(;a.innerMode;){var c=a.innerMode(b);if(!c||c.mode==a)break;b=c.state,a=c.mode}return c||{mode:a,state:b}};var ig=a.commands={selectAll:function(a){a.setSelection(Kf(a.firstLine(),0),Kf(a.lastLine()),Jg)},singleSelection:function(a){a.setSelection(a.getCursor("anchor"),a.getCursor("head"),Jg)},killLine:function(a){Pc(a,function(b){if(b.empty()){var c=Yd(a.doc,b.head.line).text.length;return b.head.ch==c&&b.head.line<a.lastLine()?{from:b.head,to:Kf(b.head.line+1,0)}:{from:b.head,to:Kf(b.head.line,c)}}return{from:b.from(),to:b.to()}})},deleteLine:function(a){Pc(a,function(b){return{from:Kf(b.from().line,0),to:pa(a.doc,Kf(b.to().line+1,0))}})},delLineLeft:function(a){Pc(a,function(a){return{from:Kf(a.from().line,0),to:a.from()}})},delWrappedLineLeft:function(a){Pc(a,function(b){var c=a.charCoords(b.head,"div").top+5,d=a.coordsChar({left:0,top:c},"div");return{from:d,to:b.from()}})},delWrappedLineRight:function(a){Pc(a,function(b){var c=a.charCoords(b.head,"div").top+5,d=a.coordsChar({left:a.display.lineDiv.offsetWidth+100,top:c},"div");return{from:b.from(),to:d}})},undo:function(a){a.undo()},redo:function(a){a.redo()},undoSelection:function(a){a.undoSelection()},redoSelection:function(a){a.redoSelection()},goDocStart:function(a){a.extendSelection(Kf(a.firstLine(),0))},goDocEnd:function(a){a.extendSelection(Kf(a.lastLine()))},goLineStart:function(a){a.extendSelectionsBy(function(b){return ef(a,b.head.line)},{origin:"+move",bias:1})},goLineStartSmart:function(a){a.extendSelectionsBy(function(b){return gf(a,b.head)},{origin:"+move",bias:1})},goLineEnd:function(a){a.extendSelectionsBy(function(b){return ff(a,b.head.line)},{origin:"+move",bias:-1})},goLineRight:function(a){a.extendSelectionsBy(function(b){var c=a.charCoords(b.head,"div").top+5;return a.coordsChar({left:a.display.lineDiv.offsetWidth+100,top:c},"div")},Lg)},goLineLeft:function(a){a.extendSelectionsBy(function(b){var c=a.charCoords(b.head,"div").top+5;return a.coordsChar({left:0,top:c},"div")},Lg)},goLineLeftSmart:function(a){a.extendSelectionsBy(function(b){var c=a.charCoords(b.head,"div").top+5,d=a.coordsChar({left:0,top:c},"div");return d.ch<a.getLine(d.line).search(/\S/)?gf(a,b.head):d},Lg)},goLineUp:function(a){a.moveV(-1,"line")},goLineDown:function(a){a.moveV(1,"line")},goPageUp:function(a){a.moveV(-1,"page")},goPageDown:function(a){a.moveV(1,"page")},goCharLeft:function(a){a.moveH(-1,"char")},goCharRight:function(a){a.moveH(1,"char")},goColumnLeft:function(a){a.moveH(-1,"column")},goColumnRight:function(a){a.moveH(1,"column")},goWordLeft:function(a){a.moveH(-1,"word")},goGroupRight:function(a){a.moveH(1,"group")},goGroupLeft:function(a){a.moveH(-1,"group")},goWordRight:function(a){a.moveH(1,"word")},delCharBefore:function(a){a.deleteH(-1,"char")},delCharAfter:function(a){a.deleteH(1,"char")},delWordBefore:function(a){a.deleteH(-1,"word")},delWordAfter:function(a){a.deleteH(1,"word")},delGroupBefore:function(a){a.deleteH(-1,"group")},delGroupAfter:function(a){a.deleteH(1,"group")},indentAuto:function(a){a.indentSelection("smart")},indentMore:function(a){a.indentSelection("add")},indentLess:function(a){a.indentSelection("subtract")},insertTab:function(a){a.replaceSelection(" ")},insertSoftTab:function(a){for(var b=[],c=a.listSelections(),d=a.options.tabSize,e=0;e<c.length;e++){var f=c[e].from(),g=Mg(a.getLine(f.line),f.ch,d);b.push(new Array(d-g%d+1).join(" "))}a.replaceSelections(b)},defaultTab:function(a){a.somethingSelected()?a.indentSelection("add"):a.execCommand("insertTab")},transposeChars:function(a){Db(a,function(){for(var b=a.listSelections(),c=[],d=0;d<b.length;d++){var e=b[d].head,f=Yd(a.doc,e.line).text;if(f)if(e.ch==f.length&&(e=new Kf(e.line,e.ch-1)),e.ch>0)e=new Kf(e.line,e.ch+1),a.replaceRange(f.charAt(e.ch-1)+f.charAt(e.ch-2),Kf(e.line,e.ch-2),e,"+transpose");else if(e.line>a.doc.first){var g=Yd(a.doc,e.line-1).text;g&&a.replaceRange(f.charAt(0)+a.doc.lineSeparator()+g.charAt(g.length-1),Kf(e.line-1,g.length-1),Kf(e.line,1),"+transpose")}c.push(new la(e,e))}a.setSelections(c)})},newlineAndIndent:function(a){Db(a,function(){for(var b=a.listSelections().length,c=0;b>c;c++){var d=a.listSelections()[c];a.replaceRange(a.doc.lineSeparator(),d.anchor,d.head,"+input"),a.indentLine(d.from().line+1,null,!0)}Lc(a)})},toggleOverwrite:function(a){a.toggleOverwrite()}},jg=a.keyMap={};jg.basic={Left:"goCharLeft",Right:"goCharRight",Up:"goLineUp",Down:"goLineDown",End:"goLineEnd",Home:"goLineStartSmart",PageUp:"goPageUp",PageDown:"goPageDown",Delete:"delCharAfter",Backspace:"delCharBefore","Shift-Backspace":"delCharBefore",Tab:"defaultTab","Shift-Tab":"indentAuto",Enter:"newlineAndIndent",Insert:"toggleOverwrite",Esc:"singleSelection"},jg.pcDefault={"Ctrl-A":"selectAll","Ctrl-D":"deleteLine","Ctrl-Z":"undo","Shift-Ctrl-Z":"redo","Ctrl-Y":"redo","Ctrl-Home":"goDocStart","Ctrl-End":"goDocEnd","Ctrl-Up":"goLineUp","Ctrl-Down":"goLineDown","Ctrl-Left":"goGroupLeft","Ctrl-Right":"goGroupRight","Alt-Left":"goLineStart","Alt-Right":"goLineEnd","Ctrl-Backspace":"delGroupBefore","Ctrl-Delete":"delGroupAfter",
5
+ "Ctrl-S":"save","Ctrl-F":"find","Ctrl-G":"findNext","Shift-Ctrl-G":"findPrev","Shift-Ctrl-F":"replace","Shift-Ctrl-R":"replaceAll","Ctrl-[":"indentLess","Ctrl-]":"indentMore","Ctrl-U":"undoSelection","Shift-Ctrl-U":"redoSelection","Alt-U":"redoSelection",fallthrough:"basic"},jg.emacsy={"Ctrl-F":"goCharRight","Ctrl-B":"goCharLeft","Ctrl-P":"goLineUp","Ctrl-N":"goLineDown","Alt-F":"goWordRight","Alt-B":"goWordLeft","Ctrl-A":"goLineStart","Ctrl-E":"goLineEnd","Ctrl-V":"goPageDown","Shift-Ctrl-V":"goPageUp","Ctrl-D":"delCharAfter","Ctrl-H":"delCharBefore","Alt-D":"delWordAfter","Alt-Backspace":"delWordBefore","Ctrl-K":"killLine","Ctrl-T":"transposeChars"},jg.macDefault={"Cmd-A":"selectAll","Cmd-D":"deleteLine","Cmd-Z":"undo","Shift-Cmd-Z":"redo","Cmd-Y":"redo","Cmd-Home":"goDocStart","Cmd-Up":"goDocStart","Cmd-End":"goDocEnd","Cmd-Down":"goDocEnd","Alt-Left":"goGroupLeft","Alt-Right":"goGroupRight","Cmd-Left":"goLineLeft","Cmd-Right":"goLineRight","Alt-Backspace":"delGroupBefore","Ctrl-Alt-Backspace":"delGroupAfter","Alt-Delete":"delGroupAfter","Cmd-S":"save","Cmd-F":"find","Cmd-G":"findNext","Shift-Cmd-G":"findPrev","Cmd-Alt-F":"replace","Shift-Cmd-Alt-F":"replaceAll","Cmd-[":"indentLess","Cmd-]":"indentMore","Cmd-Backspace":"delWrappedLineLeft","Cmd-Delete":"delWrappedLineRight","Cmd-U":"undoSelection","Shift-Cmd-U":"redoSelection","Ctrl-Up":"goDocStart","Ctrl-Down":"goDocEnd",fallthrough:["basic","emacsy"]},jg["default"]=Df?jg.macDefault:jg.pcDefault,a.normalizeKeyMap=function(a){var b={};for(var c in a)if(a.hasOwnProperty(c)){var d=a[c];if(/^(name|fallthrough|(de|at)tach)$/.test(c))continue;if("..."==d){delete a[c];continue}for(var e=He(c.split(" "),Tc),f=0;f<e.length;f++){var g,h;f==e.length-1?(h=e.join(" "),g=d):(h=e.slice(0,f+1).join(" "),g="...");var i=b[h];if(i){if(i!=g)throw new Error("Inconsistent bindings for "+h)}else b[h]=g}delete a[c]}for(var j in b)a[j]=b[j];return a};var kg=a.lookupKey=function(a,b,c,d){b=Uc(b);var e=b.call?b.call(a,d):b[a];if(e===!1)return"nothing";if("..."===e)return"multi";if(null!=e&&c(e))return"handled";if(b.fallthrough){if("[object Array]"!=Object.prototype.toString.call(b.fallthrough))return kg(a,b.fallthrough,c,d);for(var f=0;f<b.fallthrough.length;f++){var g=kg(a,b.fallthrough[f],c,d);if(g)return g}}},lg=a.isModifierKey=function(a){var b="string"==typeof a?a:dh[a.keyCode];return"Ctrl"==b||"Alt"==b||"Shift"==b||"Mod"==b},mg=a.keyName=function(a,b){if(xf&&34==a.keyCode&&a["char"])return!1;var c=dh[a.keyCode],d=c;return null==d||a.altGraphKey?!1:(a.altKey&&"Alt"!=c&&(d="Alt-"+d),(Gf?a.metaKey:a.ctrlKey)&&"Ctrl"!=c&&(d="Ctrl-"+d),(Gf?a.ctrlKey:a.metaKey)&&"Cmd"!=c&&(d="Cmd-"+d),!b&&a.shiftKey&&"Shift"!=c&&(d="Shift-"+d),d)};a.fromTextArea=function(b,c){function d(){b.value=j.getValue()}if(c=c?Ke(c):{},c.value=b.value,!c.tabindex&&b.tabIndex&&(c.tabindex=b.tabIndex),!c.placeholder&&b.placeholder&&(c.placeholder=b.placeholder),null==c.autofocus){var e=Se();c.autofocus=e==b||null!=b.getAttribute("autofocus")&&e==document.body}if(b.form&&(Cg(b.form,"submit",d),!c.leaveSubmitMethodAlone)){var f=b.form,g=f.submit;try{var h=f.submit=function(){d(),f.submit=g,f.submit(),f.submit=h}}catch(i){}}c.finishInit=function(a){a.save=d,a.getTextArea=function(){return b},a.toTextArea=function(){a.toTextArea=isNaN,d(),b.parentNode.removeChild(a.getWrapperElement()),b.style.display="",b.form&&(Eg(b.form,"submit",d),"function"==typeof b.form.submit&&(b.form.submit=g))}},b.style.display="none";var j=a(function(a){b.parentNode.insertBefore(a,b.nextSibling)},c);return j};var ng=a.StringStream=function(a,b){this.pos=this.start=0,this.string=a,this.tabSize=b||8,this.lastColumnPos=this.lastColumnValue=0,this.lineStart=0};ng.prototype={eol:function(){return this.pos>=this.string.length},sol:function(){return this.pos==this.lineStart},peek:function(){return this.string.charAt(this.pos)||void 0},next:function(){return this.pos<this.string.length?this.string.charAt(this.pos++):void 0},eat:function(a){var b=this.string.charAt(this.pos);if("string"==typeof a)var c=b==a;else var c=b&&(a.test?a.test(b):a(b));return c?(++this.pos,b):void 0},eatWhile:function(a){for(var b=this.pos;this.eat(a););return this.pos>b},eatSpace:function(){for(var a=this.pos;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>a},skipToEnd:function(){this.pos=this.string.length},skipTo:function(a){var b=this.string.indexOf(a,this.pos);return b>-1?(this.pos=b,!0):void 0},backUp:function(a){this.pos-=a},column:function(){return this.lastColumnPos<this.start&&(this.lastColumnValue=Mg(this.string,this.start,this.tabSize,this.lastColumnPos,this.lastColumnValue),this.lastColumnPos=this.start),this.lastColumnValue-(this.lineStart?Mg(this.string,this.lineStart,this.tabSize):0)},indentation:function(){return Mg(this.string,null,this.tabSize)-(this.lineStart?Mg(this.string,this.lineStart,this.tabSize):0)},match:function(a,b,c){if("string"!=typeof a){var d=this.string.slice(this.pos).match(a);return d&&d.index>0?null:(d&&b!==!1&&(this.pos+=d[0].length),d)}var e=function(a){return c?a.toLowerCase():a},f=this.string.substr(this.pos,a.length);return e(f)==e(a)?(b!==!1&&(this.pos+=a.length),!0):void 0},current:function(){return this.string.slice(this.start,this.pos)},hideFirstChars:function(a,b){this.lineStart+=a;try{return b()}finally{this.lineStart-=a}}};var og=0,pg=a.TextMarker=function(a,b){this.lines=[],this.type=b,this.doc=a,this.id=++og};Ce(pg),pg.prototype.clear=function(){if(!this.explicitlyCleared){var a=this.doc.cm,b=a&&!a.curOp;if(b&&ub(a),Be(this,"clear")){var c=this.find();c&&xe(this,"clear",c.from,c.to)}for(var d=null,e=null,f=0;f<this.lines.length;++f){var g=this.lines[f],h=_c(g.markedSpans,this);a&&!this.collapsed?Kb(a,ae(g),"text"):a&&(null!=h.to&&(e=ae(g)),null!=h.from&&(d=ae(g))),g.markedSpans=ad(g.markedSpans,h),null==h.from&&this.collapsed&&!vd(this.doc,g)&&a&&_d(g,sb(a.display))}if(a&&this.collapsed&&!a.options.lineWrapping)for(var f=0;f<this.lines.length;++f){var i=rd(this.lines[f]),j=l(i);j>a.display.maxLineLength&&(a.display.maxLine=i,a.display.maxLineLength=j,a.display.maxLineChanged=!0)}null!=d&&a&&this.collapsed&&Jb(a,d,e+1),this.lines.length=0,this.explicitlyCleared=!0,this.atomic&&this.doc.cantEdit&&(this.doc.cantEdit=!1,a&&Da(a.doc)),a&&xe(a,"markerCleared",a,this),b&&wb(a),this.parent&&this.parent.clear()}},pg.prototype.find=function(a,b){null==a&&"bookmark"==this.type&&(a=1);for(var c,d,e=0;e<this.lines.length;++e){var f=this.lines[e],g=_c(f.markedSpans,this);if(null!=g.from&&(c=Kf(b?f:ae(f),g.from),-1==a))return c;if(null!=g.to&&(d=Kf(b?f:ae(f),g.to),1==a))return d}return c&&{from:c,to:d}},pg.prototype.changed=function(){var a=this.find(-1,!0),b=this,c=this.doc.cm;a&&c&&Db(c,function(){var d=a.line,e=ae(a.line),f=_a(c,e);if(f&&(fb(f),c.curOp.selectionChanged=c.curOp.forceUpdate=!0),c.curOp.updateMaxLine=!0,!vd(b.doc,d)&&null!=b.height){var g=b.height;b.height=null;var h=yd(b)-g;h&&_d(d,d.height+h)}})},pg.prototype.attachLine=function(a){if(!this.lines.length&&this.doc.cm){var b=this.doc.cm.curOp;b.maybeHiddenMarkers&&-1!=Ge(b.maybeHiddenMarkers,this)||(b.maybeUnhiddenMarkers||(b.maybeUnhiddenMarkers=[])).push(this)}this.lines.push(a)},pg.prototype.detachLine=function(a){if(this.lines.splice(Ge(this.lines,a),1),!this.lines.length&&this.doc.cm){var b=this.doc.cm.curOp;(b.maybeHiddenMarkers||(b.maybeHiddenMarkers=[])).push(this)}};var og=0,qg=a.SharedTextMarker=function(a,b){this.markers=a,this.primary=b;for(var c=0;c<a.length;++c)a[c].parent=this};Ce(qg),qg.prototype.clear=function(){if(!this.explicitlyCleared){this.explicitlyCleared=!0;for(var a=0;a<this.markers.length;++a)this.markers[a].clear();xe(this,"clear")}},qg.prototype.find=function(a,b){return this.primary.find(a,b)};var rg=a.LineWidget=function(a,b,c){if(c)for(var d in c)c.hasOwnProperty(d)&&(this[d]=c[d]);this.doc=a,this.node=b};Ce(rg),rg.prototype.clear=function(){var a=this.doc.cm,b=this.line.widgets,c=this.line,d=ae(c);if(null!=d&&b){for(var e=0;e<b.length;++e)b[e]==this&&b.splice(e--,1);b.length||(c.widgets=null);var f=yd(this);_d(c,Math.max(0,c.height-f)),a&&Db(a,function(){xd(a,c,-f),Kb(a,d,"widget")})}},rg.prototype.changed=function(){var a=this.height,b=this.doc.cm,c=this.line;this.height=null;var d=yd(this)-a;d&&(_d(c,c.height+d),b&&Db(b,function(){b.curOp.forceUpdate=!0,xd(b,c,d)}))};var sg=a.Line=function(a,b,c){this.text=a,jd(this,b),this.height=c?c(this):1};Ce(sg),sg.prototype.lineNo=function(){return ae(this)};var tg={},ug={};Ud.prototype={chunkSize:function(){return this.lines.length},removeInner:function(a,b){for(var c=a,d=a+b;d>c;++c){var e=this.lines[c];this.height-=e.height,Bd(e),xe(e,"delete")}this.lines.splice(a,b)},collapse:function(a){a.push.apply(a,this.lines)},insertInner:function(a,b,c){this.height+=c,this.lines=this.lines.slice(0,a).concat(b).concat(this.lines.slice(a));for(var d=0;d<b.length;++d)b[d].parent=this},iterN:function(a,b,c){for(var d=a+b;d>a;++a)if(c(this.lines[a]))return!0}},Vd.prototype={chunkSize:function(){return this.size},removeInner:function(a,b){this.size-=b;for(var c=0;c<this.children.length;++c){var d=this.children[c],e=d.chunkSize();if(e>a){var f=Math.min(b,e-a),g=d.height;if(d.removeInner(a,f),this.height-=g-d.height,e==f&&(this.children.splice(c--,1),d.parent=null),0==(b-=f))break;a=0}else a-=e}if(this.size-b<25&&(this.children.length>1||!(this.children[0]instanceof Ud))){var h=[];this.collapse(h),this.children=[new Ud(h)],this.children[0].parent=this}},collapse:function(a){for(var b=0;b<this.children.length;++b)this.children[b].collapse(a)},insertInner:function(a,b,c){this.size+=b.length,this.height+=c;for(var d=0;d<this.children.length;++d){var e=this.children[d],f=e.chunkSize();if(f>=a){if(e.insertInner(a,b,c),e.lines&&e.lines.length>50){for(;e.lines.length>50;){var g=e.lines.splice(e.lines.length-25,25),h=new Ud(g);e.height-=h.height,this.children.splice(d+1,0,h),h.parent=this}this.maybeSpill()}break}a-=f}},maybeSpill:function(){if(!(this.children.length<=10)){var a=this;do{var b=a.children.splice(a.children.length-5,5),c=new Vd(b);if(a.parent){a.size-=c.size,a.height-=c.height;var d=Ge(a.parent.children,a);a.parent.children.splice(d+1,0,c)}else{var e=new Vd(a.children);e.parent=a,a.children=[e,c],a=e}c.parent=a.parent}while(a.children.length>10);a.parent.maybeSpill()}},iterN:function(a,b,c){for(var d=0;d<this.children.length;++d){var e=this.children[d],f=e.chunkSize();if(f>a){var g=Math.min(b,f-a);if(e.iterN(a,g,c))return!0;if(0==(b-=g))break;a=0}else a-=f}}};var vg=0,wg=a.Doc=function(a,b,c,d){if(!(this instanceof wg))return new wg(a,b,c,d);null==c&&(c=0),Vd.call(this,[new Ud([new sg("",null)])]),this.first=c,this.scrollTop=this.scrollLeft=0,this.cantEdit=!1,this.cleanGeneration=1,this.frontier=c;var e=Kf(c,0);this.sel=na(e),this.history=new ee(null),this.id=++vg,this.modeOption=b,this.lineSep=d,this.extend=!1,"string"==typeof a&&(a=this.splitLines(a)),Td(this,{from:e,to:e,text:a}),Aa(this,na(e),Jg)};wg.prototype=Je(Vd.prototype,{constructor:wg,iter:function(a,b,c){c?this.iterN(a-this.first,b-a,c):this.iterN(this.first,this.first+this.size,a)},insert:function(a,b){for(var c=0,d=0;d<b.length;++d)c+=b[d].height;this.insertInner(a-this.first,b,c)},remove:function(a,b){this.removeInner(a-this.first,b)},getValue:function(a){var b=$d(this,this.first,this.first+this.size);return a===!1?b:b.join(a||this.lineSeparator())},setValue:Gb(function(a){var b=Kf(this.first,0),c=this.first+this.size-1;zc(this,{from:b,to:Kf(c,Yd(this,c).text.length),text:this.splitLines(a),origin:"setValue",full:!0},!0),Aa(this,na(b))}),replaceRange:function(a,b,c,d){b=pa(this,b),c=c?pa(this,c):b,Fc(this,a,b,c,d)},getRange:function(a,b,c){var d=Zd(this,pa(this,a),pa(this,b));return c===!1?d:d.join(c||this.lineSeparator())},getLine:function(a){var b=this.getLineHandle(a);return b&&b.text},getLineHandle:function(a){return ra(this,a)?Yd(this,a):void 0},getLineNumber:function(a){return ae(a)},getLineHandleVisualStart:function(a){return"number"==typeof a&&(a=Yd(this,a)),rd(a)},lineCount:function(){return this.size},firstLine:function(){return this.first},lastLine:function(){return this.first+this.size-1},clipPos:function(a){return pa(this,a)},getCursor:function(a){var b,c=this.sel.primary();return b=null==a||"head"==a?c.head:"anchor"==a?c.anchor:"end"==a||"to"==a||a===!1?c.to():c.from()},listSelections:function(){return this.sel.ranges},somethingSelected:function(){return this.sel.somethingSelected()},setCursor:Gb(function(a,b,c){xa(this,pa(this,"number"==typeof a?Kf(a,b||0):a),null,c)}),setSelection:Gb(function(a,b,c){xa(this,pa(this,a),pa(this,b||a),c)}),extendSelection:Gb(function(a,b,c){ua(this,pa(this,a),b&&pa(this,b),c)}),extendSelections:Gb(function(a,b){va(this,sa(this,a),b)}),extendSelectionsBy:Gb(function(a,b){var c=He(this.sel.ranges,a);va(this,sa(this,c),b)}),setSelections:Gb(function(a,b,c){if(a.length){for(var d=0,e=[];d<a.length;d++)e[d]=new la(pa(this,a[d].anchor),pa(this,a[d].head));null==b&&(b=Math.min(a.length-1,this.sel.primIndex)),Aa(this,ma(e,b),c)}}),addSelection:Gb(function(a,b,c){var d=this.sel.ranges.slice(0);d.push(new la(pa(this,a),pa(this,b||a))),Aa(this,ma(d,d.length-1),c)}),getSelection:function(a){for(var b,c=this.sel.ranges,d=0;d<c.length;d++){var e=Zd(this,c[d].from(),c[d].to());b=b?b.concat(e):e}return a===!1?b:b.join(a||this.lineSeparator())},getSelections:function(a){for(var b=[],c=this.sel.ranges,d=0;d<c.length;d++){var e=Zd(this,c[d].from(),c[d].to());a!==!1&&(e=e.join(a||this.lineSeparator())),b[d]=e}return b},replaceSelection:function(a,b,c){for(var d=[],e=0;e<this.sel.ranges.length;e++)d[e]=a;this.replaceSelections(d,b,c||"+input")},replaceSelections:Gb(function(a,b,c){for(var d=[],e=this.sel,f=0;f<e.ranges.length;f++){var g=e.ranges[f];d[f]={from:g.from(),to:g.to(),text:this.splitLines(a[f]),origin:c}}for(var h=b&&"end"!=b&&xc(this,d,b),f=d.length-1;f>=0;f--)zc(this,d[f]);h?za(this,h):this.cm&&Lc(this.cm)}),undo:Gb(function(){Bc(this,"undo")}),redo:Gb(function(){Bc(this,"redo")}),undoSelection:Gb(function(){Bc(this,"undo",!0)}),redoSelection:Gb(function(){Bc(this,"redo",!0)}),setExtending:function(a){this.extend=a},getExtending:function(){return this.extend},historySize:function(){for(var a=this.history,b=0,c=0,d=0;d<a.done.length;d++)a.done[d].ranges||++b;for(var d=0;d<a.undone.length;d++)a.undone[d].ranges||++c;return{undo:b,redo:c}},clearHistory:function(){this.history=new ee(this.history.maxGeneration)},markClean:function(){this.cleanGeneration=this.changeGeneration(!0)},changeGeneration:function(a){return a&&(this.history.lastOp=this.history.lastSelOp=this.history.lastOrigin=null),this.history.generation},isClean:function(a){return this.history.generation==(a||this.cleanGeneration)},getHistory:function(){return{done:pe(this.history.done),undone:pe(this.history.undone)}},setHistory:function(a){var b=this.history=new ee(this.history.maxGeneration);b.done=pe(a.done.slice(0),null,!0),b.undone=pe(a.undone.slice(0),null,!0)},addLineClass:Gb(function(a,b,c){return Oc(this,a,"gutter"==b?"gutter":"class",function(a){var d="text"==b?"textClass":"background"==b?"bgClass":"gutter"==b?"gutterClass":"wrapClass";if(a[d]){if(Te(c).test(a[d]))return!1;a[d]+=" "+c}else a[d]=c;return!0})}),removeLineClass:Gb(function(a,b,c){return Oc(this,a,"gutter"==b?"gutter":"class",function(a){var d="text"==b?"textClass":"background"==b?"bgClass":"gutter"==b?"gutterClass":"wrapClass",e=a[d];if(!e)return!1;if(null==c)a[d]=null;else{var f=e.match(Te(c));if(!f)return!1;var g=f.index+f[0].length;a[d]=e.slice(0,f.index)+(f.index&&g!=e.length?" ":"")+e.slice(g)||null}return!0})}),addLineWidget:Gb(function(a,b,c){return zd(this,a,b,c)}),removeLineWidget:function(a){a.clear()},markText:function(a,b,c){return Vc(this,pa(this,a),pa(this,b),c,c&&c.type||"range")},setBookmark:function(a,b){var c={replacedWith:b&&(null==b.nodeType?b.widget:b),insertLeft:b&&b.insertLeft,clearWhenEmpty:!1,shared:b&&b.shared,handleMouseEvents:b&&b.handleMouseEvents};return a=pa(this,a),Vc(this,a,a,c,"bookmark")},findMarksAt:function(a){a=pa(this,a);var b=[],c=Yd(this,a.line).markedSpans;if(c)for(var d=0;d<c.length;++d){var e=c[d];(null==e.from||e.from<=a.ch)&&(null==e.to||e.to>=a.ch)&&b.push(e.marker.parent||e.marker)}return b},findMarks:function(a,b,c){a=pa(this,a),b=pa(this,b);var d=[],e=a.line;return this.iter(a.line,b.line+1,function(f){var g=f.markedSpans;if(g)for(var h=0;h<g.length;h++){var i=g[h];e==a.line&&a.ch>i.to||null==i.from&&e!=a.line||e==b.line&&i.from>b.ch||c&&!c(i.marker)||d.push(i.marker.parent||i.marker)}++e}),d},getAllMarks:function(){var a=[];return this.iter(function(b){var c=b.markedSpans;if(c)for(var d=0;d<c.length;++d)null!=c[d].from&&a.push(c[d].marker)}),a},posFromIndex:function(a){var b,c=this.first;return this.iter(function(d){var e=d.text.length+1;return e>a?(b=a,!0):(a-=e,void++c)}),pa(this,Kf(c,b))},indexFromPos:function(a){a=pa(this,a);var b=a.ch;return a.line<this.first||a.ch<0?0:(this.iter(this.first,a.line,function(a){b+=a.text.length+1}),b)},copy:function(a){var b=new wg($d(this,this.first,this.first+this.size),this.modeOption,this.first,this.lineSep);return b.scrollTop=this.scrollTop,b.scrollLeft=this.scrollLeft,b.sel=this.sel,b.extend=!1,a&&(b.history.undoDepth=this.history.undoDepth,b.setHistory(this.getHistory())),b},linkedDoc:function(a){a||(a={});var b=this.first,c=this.first+this.size;null!=a.from&&a.from>b&&(b=a.from),null!=a.to&&a.to<c&&(c=a.to);var d=new wg($d(this,b,c),a.mode||this.modeOption,b,this.lineSep);return a.sharedHist&&(d.history=this.history),(this.linked||(this.linked=[])).push({doc:d,sharedHist:a.sharedHist}),d.linked=[{doc:this,isParent:!0,sharedHist:a.sharedHist}],Yc(d,Xc(this)),d},unlinkDoc:function(b){if(b instanceof a&&(b=b.doc),this.linked)for(var c=0;c<this.linked.length;++c){var d=this.linked[c];if(d.doc==b){this.linked.splice(c,1),b.unlinkDoc(this),Zc(Xc(this));break}}if(b.history==this.history){var e=[b.id];Wd(b,function(a){e.push(a.id)},!0),b.history=new ee(null),b.history.done=pe(this.history.done,e),b.history.undone=pe(this.history.undone,e)}},iterLinkedDocs:function(a){Wd(this,a)},getMode:function(){return this.mode},getEditor:function(){return this.cm},splitLines:function(a){return this.lineSep?a.split(this.lineSep):_g(a)},lineSeparator:function(){return this.lineSep||"\n"}}),wg.prototype.eachLine=wg.prototype.iter;var xg="iter insert remove copy getEditor constructor".split(" ");for(var yg in wg.prototype)wg.prototype.hasOwnProperty(yg)&&Ge(xg,yg)<0&&(a.prototype[yg]=function(a){return function(){return a.apply(this.doc,arguments)}}(wg.prototype[yg]));Ce(wg);var zg=a.e_preventDefault=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1},Ag=a.e_stopPropagation=function(a){a.stopPropagation?a.stopPropagation():a.cancelBubble=!0},Bg=a.e_stop=function(a){zg(a),Ag(a)},Cg=a.on=function(a,b,c){if(a.addEventListener)a.addEventListener(b,c,!1);else if(a.attachEvent)a.attachEvent("on"+b,c);else{var d=a._handlers||(a._handlers={}),e=d[b]||(d[b]=[]);e.push(c)}},Dg=[],Eg=a.off=function(a,b,c){if(a.removeEventListener)a.removeEventListener(b,c,!1);else if(a.detachEvent)a.detachEvent("on"+b,c);else for(var d=we(a,b,!1),e=0;e<d.length;++e)if(d[e]==c){d.splice(e,1);break}},Fg=a.signal=function(a,b){var c=we(a,b,!0);if(c.length)for(var d=Array.prototype.slice.call(arguments,2),e=0;e<c.length;++e)c[e].apply(null,d)},Gg=null,Hg=30,Ig=a.Pass={toString:function(){return"CodeMirror.Pass"}},Jg={scroll:!1},Kg={origin:"*mouse"},Lg={origin:"+move"};De.prototype.set=function(a,b){clearTimeout(this.id),this.id=setTimeout(b,a)};var Mg=a.countColumn=function(a,b,c,d,e){null==b&&(b=a.search(/[^\s\u00a0]/),-1==b&&(b=a.length));for(var f=d||0,g=e||0;;){var h=a.indexOf(" ",f);if(0>h||h>=b)return g+(b-f);g+=h-f,g+=c-g%c,f=h+1}},Ng=a.findColumn=function(a,b,c){for(var d=0,e=0;;){var f=a.indexOf(" ",d);-1==f&&(f=a.length);var g=f-d;if(f==a.length||e+g>=b)return d+Math.min(g,b-e);if(e+=f-d,e+=c-e%c,d=f+1,e>=b)return d}},Og=[""],Pg=function(a){a.select()};Bf?Pg=function(a){a.selectionStart=0,a.selectionEnd=a.value.length}:sf&&(Pg=function(a){try{a.select()}catch(b){}});var Qg,Rg=/[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/,Sg=a.isWordChar=function(a){return/\w/.test(a)||a>"€"&&(a.toUpperCase()!=a.toLowerCase()||Rg.test(a))},Tg=/[\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]/;Qg=document.createRange?function(a,b,c,d){var e=document.createRange();return e.setEnd(d||a,c),e.setStart(a,b),e}:function(a,b,c){var d=document.body.createTextRange();try{d.moveToElementText(a.parentNode)}catch(e){return d}return d.collapse(!0),d.moveEnd("character",c),d.moveStart("character",b),d};var Ug=a.contains=function(a,b){if(3==b.nodeType&&(b=b.parentNode),a.contains)return a.contains(b);do if(11==b.nodeType&&(b=b.host),b==a)return!0;while(b=b.parentNode)};sf&&11>tf&&(Se=function(){try{return document.activeElement}catch(a){return document.body}});var Vg,Wg,Xg=a.rmClass=function(a,b){var c=a.className,d=Te(b).exec(c);if(d){var e=c.slice(d.index+d[0].length);a.className=c.slice(0,d.index)+(e?d[1]+e:"")}},Yg=a.addClass=function(a,b){var c=a.className;Te(b).test(c)||(a.className+=(c?" ":"")+b)},Zg=!1,$g=function(){if(sf&&9>tf)return!1;var a=Pe("div");return"draggable"in a||"dragDrop"in a}(),_g=a.splitLines=3!="\n\nb".split(/\n/).length?function(a){for(var b=0,c=[],d=a.length;d>=b;){var e=a.indexOf("\n",b);-1==e&&(e=a.length);var f=a.slice(b,"\r"==a.charAt(e-1)?e-1:e),g=f.indexOf("\r");-1!=g?(c.push(f.slice(0,g)),b+=g+1):(c.push(f),b=e+1)}return c}:function(a){return a.split(/\r\n?|\n/)},ah=window.getSelection?function(a){try{return a.selectionStart!=a.selectionEnd}catch(b){return!1}}:function(a){try{var b=a.ownerDocument.selection.createRange()}catch(c){}return b&&b.parentElement()==a?0!=b.compareEndPoints("StartToEnd",b):!1},bh=function(){var a=Pe("div");return"oncopy"in a?!0:(a.setAttribute("oncopy","return;"),"function"==typeof a.oncopy)}(),ch=null,dh=a.keyNames={3:"Enter",8:"Backspace",9:"Tab",13:"Enter",16:"Shift",17:"Ctrl",18:"Alt",19:"Pause",20:"CapsLock",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"PrintScrn",45:"Insert",46:"Delete",59:";",61:"=",91:"Mod",92:"Mod",93:"Mod",106:"*",107:"=",109:"-",110:".",111:"/",127:"Delete",173:"-",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",63232:"Up",63233:"Down",63234:"Left",63235:"Right",63272:"Delete",63273:"Home",63275:"End",63276:"PageUp",63277:"PageDown",63302:"Insert"};!function(){for(var a=0;10>a;a++)dh[a+48]=dh[a+96]=String(a);for(var a=65;90>=a;a++)dh[a]=String.fromCharCode(a);for(var a=1;12>=a;a++)dh[a+111]=dh[a+63235]="F"+a}();var eh,fh=function(){function a(a){return 247>=a?c.charAt(a):a>=1424&&1524>=a?"R":a>=1536&&1773>=a?d.charAt(a-1536):a>=1774&&2220>=a?"r":a>=8192&&8203>=a?"w":8204==a?"b":"L"}function b(a,b,c){this.level=a,this.from=b,this.to=c}var c="bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN",d="rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm",e=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/,f=/[stwN]/,g=/[LRr]/,h=/[Lb1n]/,i=/[1n]/,j="L";return function(c){if(!e.test(c))return!1;for(var d,k=c.length,l=[],m=0;k>m;++m)l.push(d=a(c.charCodeAt(m)));for(var m=0,n=j;k>m;++m){var d=l[m];"m"==d?l[m]=n:n=d}for(var m=0,o=j;k>m;++m){var d=l[m];"1"==d&&"r"==o?l[m]="n":g.test(d)&&(o=d,"r"==d&&(l[m]="R"))}for(var m=1,n=l[0];k-1>m;++m){var d=l[m];"+"==d&&"1"==n&&"1"==l[m+1]?l[m]="1":","!=d||n!=l[m+1]||"1"!=n&&"n"!=n||(l[m]=n),n=d}for(var m=0;k>m;++m){var d=l[m];if(","==d)l[m]="N";else if("%"==d){for(var p=m+1;k>p&&"%"==l[p];++p);for(var q=m&&"!"==l[m-1]||k>p&&"1"==l[p]?"1":"N",r=m;p>r;++r)l[r]=q;m=p-1}}for(var m=0,o=j;k>m;++m){var d=l[m];"L"==o&&"1"==d?l[m]="L":g.test(d)&&(o=d)}for(var m=0;k>m;++m)if(f.test(l[m])){for(var p=m+1;k>p&&f.test(l[p]);++p);for(var s="L"==(m?l[m-1]:j),t="L"==(k>p?l[p]:j),q=s||t?"L":"R",r=m;p>r;++r)l[r]=q;m=p-1}for(var u,v=[],m=0;k>m;)if(h.test(l[m])){var w=m;for(++m;k>m&&h.test(l[m]);++m);v.push(new b(0,w,m))}else{var x=m,y=v.length;for(++m;k>m&&"L"!=l[m];++m);for(var r=x;m>r;)if(i.test(l[r])){r>x&&v.splice(y,0,new b(1,x,r));var z=r;for(++r;m>r&&i.test(l[r]);++r);v.splice(y,0,new b(2,z,r)),x=r}else++r;m>x&&v.splice(y,0,new b(1,x,m))}return 1==v[0].level&&(u=c.match(/^\s+/))&&(v[0].from=u[0].length,v.unshift(new b(0,0,u[0].length))),1==Fe(v).level&&(u=c.match(/\s+$/))&&(Fe(v).to-=u[0].length,v.push(new b(0,k-u[0].length,k))),2==v[0].level&&v.unshift(new b(1,v[0].to,v[0].to)),v[0].level!=Fe(v).level&&v.push(new b(v[0].level,k,k)),v}}();return a.version="5.10.0",a}),function(a){"object"==typeof exports&&"object"==typeof module?a(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],a):a(CodeMirror)}(function(a){"use strict";function b(a){for(var b={},c=0;c<a.length;++c)b[a[c]]=!0;return b}function c(a,b){for(var c,d=!1;null!=(c=a.next());){if(d&&"/"==c){b.tokenize=null;break}d="*"==c}return["comment","comment"]}a.defineMode("css",function(b,c){function d(a,b){return o=b,a}function e(a,b){var c=a.next();if(r[c]){var e=r[c](a,b);if(e!==!1)return e}return"@"==c?(a.eatWhile(/[\w\\\-]/),d("def",a.current())):"="==c||("~"==c||"|"==c)&&a.eat("=")?d(null,"compare"):'"'==c||"'"==c?(b.tokenize=f(c),b.tokenize(a,b)):"#"==c?(a.eatWhile(/[\w\\\-]/),d("atom","hash")):"!"==c?(a.match(/^\s*\w*/),d("keyword","important")):/\d/.test(c)||"."==c&&a.eat(/\d/)?(a.eatWhile(/[\w.%]/),d("number","unit")):"-"!==c?/[,+>*\/]/.test(c)?d(null,"select-op"):"."==c&&a.match(/^-?[_a-z][_a-z0-9-]*/i)?d("qualifier","qualifier"):/[:;{}\[\]\(\)]/.test(c)?d(null,c):"u"==c&&a.match(/rl(-prefix)?\(/)||"d"==c&&a.match("omain(")||"r"==c&&a.match("egexp(")?(a.backUp(1),b.tokenize=g,d("property","word")):/[\w\\\-]/.test(c)?(a.eatWhile(/[\w\\\-]/),d("property","word")):d(null,null):/[\d.]/.test(a.peek())?(a.eatWhile(/[\w.%]/),d("number","unit")):a.match(/^-[\w\\\-]+/)?(a.eatWhile(/[\w\\\-]/),a.match(/^\s*:/,!1)?d("variable-2","variable-definition"):d("variable-2","variable")):a.match(/^\w+-/)?d("meta","meta"):void 0}function f(a){return function(b,c){for(var e,f=!1;null!=(e=b.next());){if(e==a&&!f){")"==a&&b.backUp(1);break}f=!f&&"\\"==e}return(e==a||!f&&")"!=a)&&(c.tokenize=null),d("string","string")}}function g(a,b){return a.next(),a.match(/\s*[\"\')]/,!1)?b.tokenize=null:b.tokenize=f(")"),d(null,"(")}function h(a,b,c){this.type=a,this.indent=b,this.prev=c}function i(a,b,c,d){return a.context=new h(c,b.indentation()+(d===!1?0:q),a.context),c}function j(a){return a.context.prev&&(a.context=a.context.prev),a.context.type}function k(a,b,c){return E[c.context.type](a,b,c)}function l(a,b,c,d){for(var e=d||1;e>0;e--)c.context=c.context.prev;return k(a,b,c)}function m(a){var b=a.current().toLowerCase();p=B.hasOwnProperty(b)?"atom":A.hasOwnProperty(b)?"keyword":"variable"}var n=c.inline;c.propertyKeywords||(c=a.resolveMode("text/css"));var o,p,q=b.indentUnit,r=c.tokenHooks,s=c.documentTypes||{},t=c.mediaTypes||{},u=c.mediaFeatures||{},v=c.mediaValueKeywords||{},w=c.propertyKeywords||{},x=c.nonStandardPropertyKeywords||{},y=c.fontProperties||{},z=c.counterDescriptors||{},A=c.colorKeywords||{},B=c.valueKeywords||{},C=c.allowNested,D=c.supportsAtComponent===!0,E={};return E.top=function(a,b,c){if("{"==a)return i(c,b,"block");if("}"==a&&c.context.prev)return j(c);if(D&&/@component/.test(a))return i(c,b,"atComponentBlock");if(/^@(-moz-)?document$/.test(a))return i(c,b,"documentTypes");if(/^@(media|supports|(-moz-)?document|import)$/.test(a))return i(c,b,"atBlock");if(/^@(font-face|counter-style)/.test(a))return c.stateArg=a,"restricted_atBlock_before";if(/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(a))return"keyframes";if(a&&"@"==a.charAt(0))return i(c,b,"at");if("hash"==a)p="builtin";else if("word"==a)p="tag";else{if("variable-definition"==a)return"maybeprop";if("interpolation"==a)return i(c,b,"interpolation");if(":"==a)return"pseudo";if(C&&"("==a)return i(c,b,"parens")}return c.context.type},E.block=function(a,b,c){if("word"==a){var d=b.current().toLowerCase();return w.hasOwnProperty(d)?(p="property","maybeprop"):x.hasOwnProperty(d)?(p="string-2","maybeprop"):C?(p=b.match(/^\s*:(?:\s|$)/,!1)?"property":"tag","block"):(p+=" error","maybeprop")}return"meta"==a?"block":C||"hash"!=a&&"qualifier"!=a?E.top(a,b,c):(p="error","block")},E.maybeprop=function(a,b,c){return":"==a?i(c,b,"prop"):k(a,b,c)},E.prop=function(a,b,c){if(";"==a)return j(c);if("{"==a&&C)return i(c,b,"propBlock");if("}"==a||"{"==a)return l(a,b,c);if("("==a)return i(c,b,"parens");if("hash"!=a||/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(b.current())){if("word"==a)m(b);else if("interpolation"==a)return i(c,b,"interpolation")}else p+=" error";return"prop"},E.propBlock=function(a,b,c){return"}"==a?j(c):"word"==a?(p="property","maybeprop"):c.context.type},E.parens=function(a,b,c){return"{"==a||"}"==a?l(a,b,c):")"==a?j(c):"("==a?i(c,b,"parens"):"interpolation"==a?i(c,b,"interpolation"):("word"==a&&m(b),"parens")},E.pseudo=function(a,b,c){return"word"==a?(p="variable-3",c.context.type):k(a,b,c)},E.documentTypes=function(a,b,c){return"word"==a&&s.hasOwnProperty(b.current())?(p="tag",c.context.type):E.atBlock(a,b,c)},E.atBlock=function(a,b,c){if("("==a)return i(c,b,"atBlock_parens");if("}"==a||";"==a)return l(a,b,c);if("{"==a)return j(c)&&i(c,b,C?"block":"top");if("interpolation"==a)return i(c,b,"interpolation");if("word"==a){var d=b.current().toLowerCase();p="only"==d||"not"==d||"and"==d||"or"==d?"keyword":t.hasOwnProperty(d)?"attribute":u.hasOwnProperty(d)?"property":v.hasOwnProperty(d)?"keyword":w.hasOwnProperty(d)?"property":x.hasOwnProperty(d)?"string-2":B.hasOwnProperty(d)?"atom":A.hasOwnProperty(d)?"keyword":"error"}return c.context.type},E.atComponentBlock=function(a,b,c){
6
+ return"}"==a?l(a,b,c):"{"==a?j(c)&&i(c,b,C?"block":"top",!1):("word"==a&&(p="error"),c.context.type)},E.atBlock_parens=function(a,b,c){return")"==a?j(c):"{"==a||"}"==a?l(a,b,c,2):E.atBlock(a,b,c)},E.restricted_atBlock_before=function(a,b,c){return"{"==a?i(c,b,"restricted_atBlock"):"word"==a&&"@counter-style"==c.stateArg?(p="variable","restricted_atBlock_before"):k(a,b,c)},E.restricted_atBlock=function(a,b,c){return"}"==a?(c.stateArg=null,j(c)):"word"==a?(p="@font-face"==c.stateArg&&!y.hasOwnProperty(b.current().toLowerCase())||"@counter-style"==c.stateArg&&!z.hasOwnProperty(b.current().toLowerCase())?"error":"property","maybeprop"):"restricted_atBlock"},E.keyframes=function(a,b,c){return"word"==a?(p="variable","keyframes"):"{"==a?i(c,b,"top"):k(a,b,c)},E.at=function(a,b,c){return";"==a?j(c):"{"==a||"}"==a?l(a,b,c):("word"==a?p="tag":"hash"==a&&(p="builtin"),"at")},E.interpolation=function(a,b,c){return"}"==a?j(c):"{"==a||";"==a?l(a,b,c):("word"==a?p="variable":"variable"!=a&&"("!=a&&")"!=a&&(p="error"),"interpolation")},{startState:function(a){return{tokenize:null,state:n?"block":"top",stateArg:null,context:new h(n?"block":"top",a||0,null)}},token:function(a,b){if(!b.tokenize&&a.eatSpace())return null;var c=(b.tokenize||e)(a,b);return c&&"object"==typeof c&&(o=c[1],c=c[0]),p=c,b.state=E[b.state](o,a,b),p},indent:function(a,b){var c=a.context,d=b&&b.charAt(0),e=c.indent;return"prop"!=c.type||"}"!=d&&")"!=d||(c=c.prev),c.prev&&("}"!=d||"block"!=c.type&&"top"!=c.type&&"interpolation"!=c.type&&"restricted_atBlock"!=c.type?(")"==d&&("parens"==c.type||"atBlock_parens"==c.type)||"{"==d&&("at"==c.type||"atBlock"==c.type))&&(e=Math.max(0,c.indent-q),c=c.prev):(c=c.prev,e=c.indent)),e},electricChars:"}",blockCommentStart:"/*",blockCommentEnd:"*/",fold:"brace"}});var d=["domain","regexp","url","url-prefix"],e=b(d),f=["all","aural","braille","handheld","print","projection","screen","tty","tv","embossed"],g=b(f),h=["width","min-width","max-width","height","min-height","max-height","device-width","min-device-width","max-device-width","device-height","min-device-height","max-device-height","aspect-ratio","min-aspect-ratio","max-aspect-ratio","device-aspect-ratio","min-device-aspect-ratio","max-device-aspect-ratio","color","min-color","max-color","color-index","min-color-index","max-color-index","monochrome","min-monochrome","max-monochrome","resolution","min-resolution","max-resolution","scan","grid","orientation","device-pixel-ratio","min-device-pixel-ratio","max-device-pixel-ratio","pointer","any-pointer","hover","any-hover"],i=b(h),j=["landscape","portrait","none","coarse","fine","on-demand","hover","interlace","progressive"],k=b(j),l=["align-content","align-items","align-self","alignment-adjust","alignment-baseline","anchor-point","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","appearance","azimuth","backface-visibility","background","background-attachment","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","baseline-shift","binding","bleed","bookmark-label","bookmark-level","bookmark-state","bookmark-target","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","clear","clip","color","color-profile","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","crop","cue","cue-after","cue-before","cursor","direction","display","dominant-baseline","drop-initial-after-adjust","drop-initial-after-align","drop-initial-before-adjust","drop-initial-before-align","drop-initial-size","drop-initial-value","elevation","empty-cells","fit","fit-position","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","float-offset","flow-from","flow-into","font","font-feature-settings","font-family","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-synthesis","font-variant","font-variant-alternates","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-weight","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-position","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","inline-box-align","justify-content","left","letter-spacing","line-break","line-height","line-stacking","line-stacking-ruby","line-stacking-shift","line-stacking-strategy","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marker-offset","marks","marquee-direction","marquee-loop","marquee-play-count","marquee-speed","marquee-style","max-height","max-width","min-height","min-width","move-to","nav-down","nav-index","nav-left","nav-right","nav-up","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-style","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page","page-break-after","page-break-before","page-break-inside","page-policy","pause","pause-after","pause-before","perspective","perspective-origin","pitch","pitch-range","play-during","position","presentation-level","punctuation-trim","quotes","region-break-after","region-break-before","region-break-inside","region-fragment","rendering-intent","resize","rest","rest-after","rest-before","richness","right","rotation","rotation-point","ruby-align","ruby-overhang","ruby-position","ruby-span","shape-image-threshold","shape-inside","shape-margin","shape-outside","size","speak","speak-as","speak-header","speak-numeral","speak-punctuation","speech-rate","stress","string-set","tab-size","table-layout","target","target-name","target-new","target-position","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-skip","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-height","text-indent","text-justify","text-outline","text-overflow","text-shadow","text-size-adjust","text-space-collapse","text-transform","text-underline-position","text-wrap","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","volume","white-space","widows","width","word-break","word-spacing","word-wrap","z-index","clip-path","clip-rule","mask","enable-background","filter","flood-color","flood-opacity","lighting-color","stop-color","stop-opacity","pointer-events","color-interpolation","color-interpolation-filters","color-rendering","fill","fill-opacity","fill-rule","image-rendering","marker","marker-end","marker-mid","marker-start","shape-rendering","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-rendering","baseline-shift","dominant-baseline","glyph-orientation-horizontal","glyph-orientation-vertical","text-anchor","writing-mode"],m=b(l),n=["scrollbar-arrow-color","scrollbar-base-color","scrollbar-dark-shadow-color","scrollbar-face-color","scrollbar-highlight-color","scrollbar-shadow-color","scrollbar-3d-light-color","scrollbar-track-color","shape-inside","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","zoom"],o=b(n),p=["font-family","src","unicode-range","font-variant","font-feature-settings","font-stretch","font-weight","font-style"],q=b(p),r=["additive-symbols","fallback","negative","pad","prefix","range","speak-as","suffix","symbols","system"],s=b(r),t=["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"],u=b(t),v=["above","absolute","activeborder","additive","activecaption","afar","after-white-space","ahead","alias","all","all-scroll","alphabetic","alternate","always","amharic","amharic-abegede","antialiased","appworkspace","arabic-indic","armenian","asterisks","attr","auto","avoid","avoid-column","avoid-page","avoid-region","background","backwards","baseline","below","bidi-override","binary","bengali","blink","block","block-axis","bold","bolder","border","border-box","both","bottom","break","break-all","break-word","bullets","button","button-bevel","buttonface","buttonhighlight","buttonshadow","buttontext","calc","cambodian","capitalize","caps-lock-indicator","caption","captiontext","caret","cell","center","checkbox","circle","cjk-decimal","cjk-earthly-branch","cjk-heavenly-stem","cjk-ideographic","clear","clip","close-quote","col-resize","collapse","column","column-reverse","compact","condensed","contain","content","content-box","context-menu","continuous","copy","counter","counters","cover","crop","cross","crosshair","currentcolor","cursive","cyclic","dashed","decimal","decimal-leading-zero","default","default-button","destination-atop","destination-in","destination-out","destination-over","devanagari","disc","discard","disclosure-closed","disclosure-open","document","dot-dash","dot-dot-dash","dotted","double","down","e-resize","ease","ease-in","ease-in-out","ease-out","element","ellipse","ellipsis","embed","end","ethiopic","ethiopic-abegede","ethiopic-abegede-am-et","ethiopic-abegede-gez","ethiopic-abegede-ti-er","ethiopic-abegede-ti-et","ethiopic-halehame-aa-er","ethiopic-halehame-aa-et","ethiopic-halehame-am-et","ethiopic-halehame-gez","ethiopic-halehame-om-et","ethiopic-halehame-sid-et","ethiopic-halehame-so-et","ethiopic-halehame-ti-er","ethiopic-halehame-ti-et","ethiopic-halehame-tig","ethiopic-numeric","ew-resize","expanded","extends","extra-condensed","extra-expanded","fantasy","fast","fill","fixed","flat","flex","flex-end","flex-start","footnotes","forwards","from","geometricPrecision","georgian","graytext","groove","gujarati","gurmukhi","hand","hangul","hangul-consonant","hebrew","help","hidden","hide","higher","highlight","highlighttext","hiragana","hiragana-iroha","horizontal","hsl","hsla","icon","ignore","inactiveborder","inactivecaption","inactivecaptiontext","infinite","infobackground","infotext","inherit","initial","inline","inline-axis","inline-block","inline-flex","inline-table","inset","inside","intrinsic","invert","italic","japanese-formal","japanese-informal","justify","kannada","katakana","katakana-iroha","keep-all","khmer","korean-hangul-formal","korean-hanja-formal","korean-hanja-informal","landscape","lao","large","larger","left","level","lighter","line-through","linear","linear-gradient","lines","list-item","listbox","listitem","local","logical","loud","lower","lower-alpha","lower-armenian","lower-greek","lower-hexadecimal","lower-latin","lower-norwegian","lower-roman","lowercase","ltr","malayalam","match","matrix","matrix3d","media-controls-background","media-current-time-display","media-fullscreen-button","media-mute-button","media-play-button","media-return-to-realtime-button","media-rewind-button","media-seek-back-button","media-seek-forward-button","media-slider","media-sliderthumb","media-time-remaining-display","media-volume-slider","media-volume-slider-container","media-volume-sliderthumb","medium","menu","menulist","menulist-button","menulist-text","menulist-textfield","menutext","message-box","middle","min-intrinsic","mix","mongolian","monospace","move","multiple","myanmar","n-resize","narrower","ne-resize","nesw-resize","no-close-quote","no-drop","no-open-quote","no-repeat","none","normal","not-allowed","nowrap","ns-resize","numbers","numeric","nw-resize","nwse-resize","oblique","octal","open-quote","optimizeLegibility","optimizeSpeed","oriya","oromo","outset","outside","outside-shape","overlay","overline","padding","padding-box","painted","page","paused","persian","perspective","plus-darker","plus-lighter","pointer","polygon","portrait","pre","pre-line","pre-wrap","preserve-3d","progress","push-button","radial-gradient","radio","read-only","read-write","read-write-plaintext-only","rectangle","region","relative","repeat","repeating-linear-gradient","repeating-radial-gradient","repeat-x","repeat-y","reset","reverse","rgb","rgba","ridge","right","rotate","rotate3d","rotateX","rotateY","rotateZ","round","row","row-resize","row-reverse","rtl","run-in","running","s-resize","sans-serif","scale","scale3d","scaleX","scaleY","scaleZ","scroll","scrollbar","se-resize","searchfield","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","semi-condensed","semi-expanded","separate","serif","show","sidama","simp-chinese-formal","simp-chinese-informal","single","skew","skewX","skewY","skip-white-space","slide","slider-horizontal","slider-vertical","sliderthumb-horizontal","sliderthumb-vertical","slow","small","small-caps","small-caption","smaller","solid","somali","source-atop","source-in","source-out","source-over","space","space-around","space-between","spell-out","square","square-button","start","static","status-bar","stretch","stroke","sub","subpixel-antialiased","super","sw-resize","symbolic","symbols","table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row","table-row-group","tamil","telugu","text","text-bottom","text-top","textarea","textfield","thai","thick","thin","threeddarkshadow","threedface","threedhighlight","threedlightshadow","threedshadow","tibetan","tigre","tigrinya-er","tigrinya-er-abegede","tigrinya-et","tigrinya-et-abegede","to","top","trad-chinese-formal","trad-chinese-informal","translate","translate3d","translateX","translateY","translateZ","transparent","ultra-condensed","ultra-expanded","underline","up","upper-alpha","upper-armenian","upper-greek","upper-hexadecimal","upper-latin","upper-norwegian","upper-roman","uppercase","urdu","url","var","vertical","vertical-text","visible","visibleFill","visiblePainted","visibleStroke","visual","w-resize","wait","wave","wider","window","windowframe","windowtext","words","wrap","wrap-reverse","x-large","x-small","xor","xx-large","xx-small"],w=b(v),x=d.concat(f).concat(h).concat(j).concat(l).concat(n).concat(t).concat(v);a.registerHelper("hintWords","css",x),a.defineMIME("text/css",{documentTypes:e,mediaTypes:g,mediaFeatures:i,mediaValueKeywords:k,propertyKeywords:m,nonStandardPropertyKeywords:o,fontProperties:q,counterDescriptors:s,colorKeywords:u,valueKeywords:w,tokenHooks:{"/":function(a,b){return a.eat("*")?(b.tokenize=c,c(a,b)):!1}},name:"css"}),a.defineMIME("text/x-scss",{mediaTypes:g,mediaFeatures:i,mediaValueKeywords:k,propertyKeywords:m,nonStandardPropertyKeywords:o,colorKeywords:u,valueKeywords:w,fontProperties:q,allowNested:!0,tokenHooks:{"/":function(a,b){return a.eat("/")?(a.skipToEnd(),["comment","comment"]):a.eat("*")?(b.tokenize=c,c(a,b)):["operator","operator"]},":":function(a){return a.match(/\s*\{/)?[null,"{"]:!1},$:function(a){return a.match(/^[\w-]+/),a.match(/^\s*:/,!1)?["variable-2","variable-definition"]:["variable-2","variable"]},"#":function(a){return a.eat("{")?[null,"interpolation"]:!1}},name:"css",helperType:"scss"}),a.defineMIME("text/x-less",{mediaTypes:g,mediaFeatures:i,mediaValueKeywords:k,propertyKeywords:m,nonStandardPropertyKeywords:o,colorKeywords:u,valueKeywords:w,fontProperties:q,allowNested:!0,tokenHooks:{"/":function(a,b){return a.eat("/")?(a.skipToEnd(),["comment","comment"]):a.eat("*")?(b.tokenize=c,c(a,b)):["operator","operator"]},"@":function(a){return a.eat("{")?[null,"interpolation"]:a.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/,!1)?!1:(a.eatWhile(/[\w\\\-]/),a.match(/^\s*:/,!1)?["variable-2","variable-definition"]:["variable-2","variable"])},"&":function(){return["atom","atom"]}},name:"css",helperType:"less"}),a.defineMIME("text/x-gss",{documentTypes:e,mediaTypes:g,mediaFeatures:i,propertyKeywords:m,nonStandardPropertyKeywords:o,fontProperties:q,counterDescriptors:s,colorKeywords:u,valueKeywords:w,supportsAtComponent:!0,tokenHooks:{"/":function(a,b){return a.eat("*")?(b.tokenize=c,c(a,b)):!1}},name:"css",helperType:"gss"})}),function(a){"object"==typeof exports&&"object"==typeof module?a(require("../../lib/codemirror"),require("../xml/xml"),require("../javascript/javascript"),require("../css/css")):"function"==typeof define&&define.amd?define(["../../lib/codemirror","../xml/xml","../javascript/javascript","../css/css"],a):a(CodeMirror)}(function(a){"use strict";function b(a,b,c){var d=a.current(),e=d.search(b);return e>-1?a.backUp(d.length-e):d.match(/<\/?$/)&&(a.backUp(d.length),a.match(b,!1)||a.match(d)),c}function c(a){var b=i[a];return b?b:i[a]=new RegExp("\\s+"+a+"\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*")}function d(a,b){for(var d,e=a.pos;e>=0&&"<"!==a.string.charAt(e);)e--;return 0>e?e:(d=a.string.slice(e,a.pos).match(c(b)))?d[2]:""}function e(a,b){return new RegExp((b?"^":"")+"</s*"+a+"s*>","i")}function f(a,b){for(var c in a)for(var d=b[c]||(b[c]=[]),e=a[c],f=e.length-1;f>=0;f--)d.unshift(e[f])}function g(a,b){for(var c=0;c<a.length;c++){var e=a[c];if(!e[0]||e[1].test(d(b,e[0])))return e[2]}}var h={script:[["lang",/(javascript|babel)/i,"javascript"],["type",/^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i,"javascript"],["type",/./,"text/plain"],[null,null,"javascript"]],style:[["lang",/^css$/i,"css"],["type",/^(text\/)?(x-)?(stylesheet|css)$/i,"css"],["type",/./,"text/plain"],[null,null,"css"]]},i={};a.defineMode("htmlmixed",function(c,d){function i(d,f){var h,l=f.htmlState.tagName&&f.htmlState.tagName.toLowerCase(),m=l&&k.hasOwnProperty(l)&&k[l],n=j.token(d,f.htmlState);if(m&&/\btag\b/.test(n)&&">"===d.current()&&(h=g(m,d))){var o=a.getMode(c,h),p=e(l,!0),q=e(l,!1);f.token=function(a,c){return a.match(p,!1)?(c.token=i,c.localState=c.localMode=null,null):b(a,q,c.localMode.token(a,c.localState))},f.localMode=o,f.localState=a.startState(o,j.indent(f.htmlState,""))}return n}var j=a.getMode(c,{name:"xml",htmlMode:!0,multilineTagIndentFactor:d.multilineTagIndentFactor,multilineTagIndentPastTag:d.multilineTagIndentPastTag}),k={},l=d&&d.tags,m=d&&d.scriptTypes;if(f(h,k),l&&f(l,k),m)for(var n=m.length-1;n>=0;n--)k.script.unshift(["type",m[n].matches,m[n].mode]);return{startState:function(){var a=j.startState();return{token:i,localMode:null,localState:null,htmlState:a}},copyState:function(b){var c;return b.localState&&(c=a.copyState(b.localMode,b.localState)),{token:b.token,localMode:b.localMode,localState:c,htmlState:a.copyState(j,b.htmlState)}},token:function(a,b){return b.token(a,b)},indent:function(b,c){return!b.localMode||/^\s*<\//.test(c)?j.indent(b.htmlState,c):b.localMode.indent?b.localMode.indent(b.localState,c):a.Pass},innerMode:function(a){return{state:a.localState||a.htmlState,mode:a.localMode||j}}}},"xml","javascript","css"),a.defineMIME("text/html","htmlmixed")}),function(a){"object"==typeof exports&&"object"==typeof module?a(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],a):a(CodeMirror)}(function(a){function b(a){a.state.placeholder&&(a.state.placeholder.parentNode.removeChild(a.state.placeholder),a.state.placeholder=null)}function c(a){b(a);var c=a.state.placeholder=document.createElement("pre");c.style.cssText="height: 0; overflow: visible",c.className="CodeMirror-placeholder";var d=a.getOption("placeholder");"string"==typeof d&&(d=document.createTextNode(d)),c.appendChild(d),a.display.lineSpace.insertBefore(c,a.display.lineSpace.firstChild)}function d(a){f(a)&&c(a)}function e(a){var d=a.getWrapperElement(),e=f(a);d.className=d.className.replace(" CodeMirror-empty","")+(e?" CodeMirror-empty":""),e?c(a):b(a)}function f(a){return 1===a.lineCount()&&""===a.getLine(0)}a.defineOption("placeholder","",function(c,f,g){var h=g&&g!=a.Init;if(f&&!h)c.on("blur",d),c.on("change",e),e(c);else if(!f&&h){c.off("blur",d),c.off("change",e),b(c);var i=c.getWrapperElement();i.className=i.className.replace(" CodeMirror-empty","")}f&&!c.hasFocus()&&d(c)})}),function(a){"object"==typeof exports&&"object"==typeof module?a(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],a):a(CodeMirror)}(function(a){"use strict";function b(a){for(var b=0;b<a.state.activeLines.length;b++)a.removeLineClass(a.state.activeLines[b],"wrap",f),a.removeLineClass(a.state.activeLines[b],"background",g)}function c(a,b){if(a.length!=b.length)return!1;for(var c=0;c<a.length;c++)if(a[c]!=b[c])return!1;return!0}function d(a,d){for(var e=[],h=0;h<d.length;h++){var i=d[h];if(i.empty()){var j=a.getLineHandleVisualStart(i.head.line);e[e.length-1]!=j&&e.push(j)}}c(a.state.activeLines,e)||a.operation(function(){b(a);for(var c=0;c<e.length;c++)a.addLineClass(e[c],"wrap",f),a.addLineClass(e[c],"background",g);a.state.activeLines=e})}function e(a,b){d(a,b.ranges)}var f="CodeMirror-activeline",g="CodeMirror-activeline-background";a.defineOption("styleActiveLine",!1,function(c,f,g){var h=g&&g!=a.Init;f&&!h?(c.state.activeLines=[],d(c,c.listSelections()),c.on("beforeSelectionChange",e)):!f&&h&&(c.off("beforeSelectionChange",e),b(c),delete c.state.activeLines)})});var bwp_editors=function(a,b){function c(c){var d=a(c).attr("id");if("undefined"==typeof h[d]){var e=a(c).data("mode"),f=a(c).data("linenr"),i=a(c).data("readOnly")||a(c).prop("readonly"),j=a(c).data("cursorline"),k=h[d]=b.fromTextArea(c,a.extend(g,{mode:e,lineNumbers:f?!0:!1,readOnly:i?!0:!1,styleActiveLine:j?!0:!1}));a(k.getWrapperElement()).attr("id",d+"_cm")}}function d(b,c){if("undefined"!=typeof h[b]){var d=h[b];c="undefined"==typeof c?!0:c,a("#"+b).prop("readonly",!1),a(d.getWrapperElement()).removeClass("CodeMirror-readonly"),d.setOption("readOnly",!1),c&&d.focus()}}function e(b){if("undefined"!=typeof h[b]){var c=h[b];a("#"+b).prop("readonly",!0),a(c.getWrapperElement()).addClass("CodeMirror-readonly"),c.setOption("readOnly",!0)}}function f(b){var c=a(this).data("target");b="undefined"==typeof b?!0:b,a(this).is(":checked")?d(c,b):e(c)}var g={indentUnit:4,readOnly:!1,theme:"neo"},h={};return a(function(){"use strict";a("body").on("click",".bwp-button-code-editor",function(b){b.preventDefault();var d=a(this),e=d.data("target");if(e){var f=a("#"+e);"undefined"!=typeof h[e]?(h[e].toTextArea(),delete h[e],f.hide()):(f.show(),c(f.get(0)))}}),a(".bwp-code-editor").each(function(a,b){c(b)}),a("body").on("change",".bwp-code-editor-cb",f),a(".bwp-code-editor-cb").each(function(){f.call(this,!1)})}),{editors:h,edit:d,stop:e}}(jQuery,CodeMirror);
vendor/kminh/bwp-framework/assets/option-page/dist/js/modal.min.js CHANGED
@@ -1 +1 @@
1
- !function(a,b){"use strict";"function"==typeof define&&define.amd?define(["jquery"],b):"object"==typeof exports?module.exports=b(require("jquery")):a.bootbox=b(a.jQuery)}(this,function a(b,c){"use strict";function d(a){var b=q[o.locale];return b?b[a]:q.en[a]}function e(a,c,d){a.stopPropagation(),a.preventDefault();var e=b.isFunction(d)&&d.call(c,a)===!1;e||c.modal("hide")}function f(a){var b,c=0;for(b in a)c++;return c}function g(a,c){var d=0;b.each(a,function(a,b){c(a,b,d++)})}function h(a){var c,d;if("object"!=typeof a)throw new Error("Please supply an object of options");if(!a.message)throw new Error("Please specify a message");return a=b.extend({},o,a),a.buttons||(a.buttons={}),c=a.buttons,d=f(c),g(c,function(a,e,f){if(b.isFunction(e)&&(e=c[a]={callback:e}),"object"!==b.type(e))throw new Error("button with key "+a+" must be an object");e.label||(e.label=a),e.className||(2>=d&&f===d-1?e.className="bwp-btn-primary button-primary":e.className="bwp-btn-default button-secondary")}),a}function i(a,b){var c=a.length,d={};if(1>c||c>2)throw new Error("Invalid argument length");return 2===c||"string"==typeof a[0]?(d[b[0]]=a[0],d[b[1]]=a[1]):d=a[0],d}function j(a,c,d){return b.extend(!0,{},a,i(c,d))}function k(a,b,c,d){var e={className:"bootbox-"+a,buttons:l.apply(null,b)};return m(j(e,d,c),b)}function l(){for(var a={},b=0,c=arguments.length;c>b;b++){var e=arguments[b],f=e.toLowerCase(),g=e.toUpperCase();a[f]={label:d(g)}}return a}function m(a,b){var d={};return g(b,function(a,b){d[b]=!0}),g(a.buttons,function(a){if(d[a]===c)throw new Error("button key "+a+" is not allowed (options are "+b.join("\n")+")")}),a}var n={dialog:"<div class='bootbox bwp-modal' tabindex='-1' role='dialog'><div class='bwp-modal-dialog'><div class='bwp-modal-content'><div class='bwp-modal-body'><div class='bootbox-body'></div></div></div></div></div>",header:"<div class='bwp-modal-header'><h4 class='bwp-modal-title'></h4></div>",footer:"<div class='bwp-modal-footer'></div>",closeButton:" <button type='button' class='bootbox-close-button bwp-close' data-dismiss='modal' aria-hidden='true'>&times;</button>",form:"<form class='bootbox-form'></form>",inputs:{text:"<input class='bootbox-input bootbox-input-text form-control' autocomplete=off type=text />",textarea:"<textarea class='bootbox-input bootbox-input-textarea form-control'></textarea>",email:"<input class='bootbox-input bootbox-input-email form-control' autocomplete='off' type='email' />",select:"<select class='bootbox-input bootbox-input-select form-control'></select>",checkbox:"<div class='checkbox'><label><input class='bootbox-input bootbox-input-checkbox' type='checkbox' /></label></div>",date:"<input class='bootbox-input bootbox-input-date form-control' autocomplete=off type='date' />",time:"<input class='bootbox-input bootbox-input-time form-control' autocomplete=off type='time' />",number:"<input class='bootbox-input bootbox-input-number form-control' autocomplete=off type='number' />",password:"<input class='bootbox-input bootbox-input-password form-control' autocomplete='off' type='password' />"}},o={locale:"en",backdrop:"static",animate:!0,className:null,closeButton:!0,show:!0,container:"body"},p={};p.alert=function(){var a;if(a=k("alert",["ok"],["message","callback"],arguments),a.callback&&!b.isFunction(a.callback))throw new Error("alert requires callback property to be a function when provided");return a.buttons.ok.callback=a.onEscape=function(){return b.isFunction(a.callback)?a.callback.call(this):!0},p.dialog(a)},p.confirm=function(){var a;if(a=k("confirm",["cancel","confirm"],["message","callback"],arguments),a.buttons.cancel.callback=a.onEscape=function(){return a.callback.call(this,!1)},a.buttons.confirm.callback=function(){return a.callback.call(this,!0)},!b.isFunction(a.callback))throw new Error("confirm requires a callback");return p.dialog(a)},p.prompt=function(){var a,d,e,f,h,i,k;if(f=b(n.form),d={className:"bootbox-prompt",buttons:l("cancel","confirm"),value:"",inputType:"text"},a=m(j(d,arguments,["title","callback"]),["cancel","confirm"]),i=a.show===c?!0:a.show,a.message=f,a.buttons.cancel.callback=a.onEscape=function(){return a.callback.call(this,null)},a.buttons.confirm.callback=function(){var c;switch(a.inputType){case"text":case"textarea":case"email":case"select":case"date":case"time":case"number":case"password":c=h.val();break;case"checkbox":var d=h.find("input:checked");c=[],g(d,function(a,d){c.push(b(d).val())})}return a.callback.call(this,c)},a.show=!1,!a.title)throw new Error("prompt requires a title");if(!b.isFunction(a.callback))throw new Error("prompt requires a callback");if(!n.inputs[a.inputType])throw new Error("invalid prompt type");switch(h=b(n.inputs[a.inputType]),a.inputType){case"text":case"textarea":case"email":case"date":case"time":case"number":case"password":h.val(a.value);break;case"select":var o={};if(k=a.inputOptions||[],!b.isArray(k))throw new Error("Please pass an array of input options");if(!k.length)throw new Error("prompt with select requires options");g(k,function(a,d){var e=h;if(d.value===c||d.text===c)throw new Error("given options in wrong format");d.group&&(o[d.group]||(o[d.group]=b("<optgroup/>").attr("label",d.group)),e=o[d.group]),e.append("<option value='"+d.value+"'>"+d.text+"</option>")}),g(o,function(a,b){h.append(b)}),h.val(a.value);break;case"checkbox":var q=b.isArray(a.value)?a.value:[a.value];if(k=a.inputOptions||[],!k.length)throw new Error("prompt with checkbox requires options");if(!k[0].value||!k[0].text)throw new Error("given options in wrong format");h=b("<div/>"),g(k,function(c,d){var e=b(n.inputs[a.inputType]);e.find("input").attr("value",d.value),e.find("label").append(d.text),g(q,function(a,b){b===d.value&&e.find("input").prop("checked",!0)}),h.append(e)})}return a.placeholder&&h.attr("placeholder",a.placeholder),a.pattern&&h.attr("pattern",a.pattern),a.maxlength&&h.attr("maxlength",a.maxlength),f.append(h),f.on("submit",function(a){a.preventDefault(),a.stopPropagation(),e.find(".bwp-btn-primary").click()}),e=p.dialog(a),e.off("shown.bs.modal"),e.on("shown.bs.modal",function(){h.focus()}),i===!0&&e.modal("show"),e},p.dialog=function(a){a=h(a);var d=b(n.dialog),f=d.find(".bwp-modal-dialog"),i=d.find(".bwp-modal-body"),j=a.buttons,k="",l={onEscape:a.onEscape};if(b.fn.modal===c)throw new Error("$.fn.modal is not defined; please double check you have included the Bootstrap JavaScript library. See http://getbootstrap.com/javascript/ for more details.");if(g(j,function(a,b){k+=" <button data-bb-handler='"+a+"' type='button' class='bwp-btn "+b.className+"'>"+b.label+"</button>",l[a]=b.callback}),i.find(".bootbox-body").html(a.message),a.animate===!0&&d.addClass("fade"),a.className&&d.addClass(a.className),"large"===a.size?f.addClass("bwp-modal-lg"):"small"===a.size&&f.addClass("bwp-modal-sm"),a.title&&i.before(n.header),a.closeButton){var m=b(n.closeButton);a.title?d.find(".bwp-modal-header").prepend(m):m.css("margin-top","-10px").prependTo(i)}return a.title&&d.find(".bwp-modal-title").html(a.title),k.length&&(i.after(n.footer),d.find(".bwp-modal-footer").html(k)),d.on("hidden.bs.modal",function(a){a.target===this&&d.remove()}),d.on("shown.bs.modal",function(){d.find(".bwp-btn-primary:first").focus()}),"static"!==a.backdrop&&d.on("click.dismiss.bs.modal",function(a){d.children(".bwp-modal-backdrop").length&&(a.currentTarget=d.children(".bwp-modal-backdrop").get(0)),a.target===a.currentTarget&&d.trigger("escape.close.bb")}),d.on("escape.close.bb",function(a){l.onEscape&&e(a,d,l.onEscape)}),d.on("click",".bwp-modal-footer button",function(a){var c=b(this).data("bb-handler");e(a,d,l[c])}),d.on("click",".bootbox-close-button",function(a){e(a,d,l.onEscape)}),d.on("keyup",function(a){27===a.which&&d.trigger("escape.close.bb")}),b(a.container).append(d),d.modal({backdrop:a.backdrop?"static":!1,keyboard:!1,show:!1}),a.show&&d.modal("show"),d},p.setDefaults=function(){var a={};2===arguments.length?a[arguments[0]]=arguments[1]:a=arguments[0],b.extend(o,a)},p.hideAll=function(){return b(".bootbox").modal("hide"),p};var q={bg_BG:{OK:"Ок",CANCEL:"Отказ",CONFIRM:"Потвърждавам"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},cs:{OK:"OK",CANCEL:"Zrušit",CONFIRM:"Potvrdit"},da:{OK:"OK",CANCEL:"Annuller",CONFIRM:"Accepter"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},el:{OK:"Εντάξει",CANCEL:"Ακύρωση",CONFIRM:"Επιβεβαίωση"},en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},et:{OK:"OK",CANCEL:"Katkesta",CONFIRM:"OK"},fa:{OK:"قبول",CANCEL:"لغو",CONFIRM:"تایید"},fi:{OK:"OK",CANCEL:"Peruuta",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},he:{OK:"אישור",CANCEL:"ביטול",CONFIRM:"אישור"},hu:{OK:"OK",CANCEL:"Mégsem",CONFIRM:"Megerősít"},hr:{OK:"OK",CANCEL:"Odustani",CONFIRM:"Potvrdi"},id:{OK:"OK",CANCEL:"Batal",CONFIRM:"OK"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"},ja:{OK:"OK",CANCEL:"キャンセル",CONFIRM:"確認"},lt:{OK:"Gerai",CANCEL:"Atšaukti",CONFIRM:"Patvirtinti"},lv:{OK:"Labi",CANCEL:"Atcelt",CONFIRM:"Apstiprināt"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},no:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},pl:{OK:"OK",CANCEL:"Anuluj",CONFIRM:"Potwierdź"},pt:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Confirmar"},ru:{OK:"OK",CANCEL:"Отмена",CONFIRM:"Применить"},sq:{OK:"OK",CANCEL:"Anulo",CONFIRM:"Prano"},sv:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},th:{OK:"ตกลง",CANCEL:"ยกเลิก",CONFIRM:"ยืนยัน"},tr:{OK:"Tamam",CANCEL:"İptal",CONFIRM:"Onayla"},zh_CN:{OK:"OK",CANCEL:"取消",CONFIRM:"确认"},zh_TW:{OK:"OK",CANCEL:"取消",CONFIRM:"確認"}};return p.addLocale=function(a,c){return b.each(["OK","CANCEL","CONFIRM"],function(a,b){if(!c[b])throw new Error("Please supply a translation for '"+b+"'")}),q[a]={OK:c.OK,CANCEL:c.CANCEL,CONFIRM:c.CONFIRM},p},p.removeLocale=function(a){return delete q[a],p},p.setLocale=function(a){return p.setDefaults("locale",a)},p.init=function(c){return a(c||b)},p});var bwp_bootbox=function(a,b){"use strict";return b.setDefaults({animation:!1,closeButton:!1}),{alert:function(c,d,e){e=e||{},e=a.extend(e,{size:"small",message:c,callback:d}),b.alert(e)},confirm:function(c,d,e){e=e||{},e=a.extend(e,{size:"small",message:c,callback:function(a){a?d():e.callback_cancel&&e.callback_cancel()}}),b.confirm(e)}}}(jQuery,bootbox);jQuery(function(a){"use strict";var b;a("body").on("click",".bwp-button-modal",function(b){b.preventDefault();var c=a(this),d=c.data("target"),e=c.data("ajaxAction");if("undefined"==typeof e)a(d).modal();else{var f=c.data("loader"),g=c.data("ajaxCallback");a.get(ajaxurl,{action:e,id:c.data("id"),custom:c.data("custom")},function(b){a(d).find(".bwp-modal-content").html(b),bwp_common.enhance_form_fields(a(d)),"undefined"!=typeof g&&window[g](a,b,c),f&&a("#"+f).hide(),a(d).modal()})}}),a(".bwp-modal").on("submit","form",function(c){c.preventDefault();var d=a(this),e=d.parents(".bwp-modal").find(".bwp-button-modal-submit"),f=e.data("ajaxCallback"),g=e.data("ajaxErrorCallback"),h=d.serialize();d.find(":input").prop("disabled",!0);var i=e.parents(".bwp-modal-footer").find(".bwp-modal-message");i.removeClass("text-success text-danger").text(i.data("workingText")).show(),a.post(ajaxurl,h,function(b){"undefined"!=typeof f&&window[f](a,b,e,d),0===e.parents(".bwp-modal-footer").find(".bwp-button-modal-reset").length&&d.trigger("reset"),0===parseInt(b,10)||b.error?i.addClass("text-danger"):i.addClass("text-success")},"json").fail(function(b){"undefined"!=typeof g&&window[g](a,b,e,d),i.addClass("text-danger")}).always(function(a){d.find(":input").prop("disabled",!1),a.message?(i.text(a.message),"undefined"!=typeof b&&clearTimeout(b),b=setTimeout(function(){i.fadeOut("fast")},5e3)):i.fadeOut("fast")})}),a(".bwp-modal").on("click",".bwp-button-modal-submit",function(b){b.preventDefault();var c=a(this).parents(".bwp-modal").find("form");c.submit()}),a(".bwp-modal").on("click",".bwp-button-modal-reset",function(b){b.preventDefault();var c=a(this);c.parents(".bwp-modal").find("form").trigger("reset")}),a(".bwp-modal").on("show.bs.modal",function(b){var c=a(this);c.find("form").trigger("reset"),c.find(".bwp-modal-message").removeClass("text-success text-danger").hide()})});
1
+ !function(a,b){"use strict";"function"==typeof define&&define.amd?define(["jquery"],b):"object"==typeof exports?module.exports=b(require("jquery")):a.bootbox=b(a.jQuery)}(this,function a(b,c){"use strict";function d(a){var b=q[o.locale];return b?b[a]:q.en[a]}function e(a,c,d){a.stopPropagation(),a.preventDefault();var e=b.isFunction(d)&&d.call(c,a)===!1;e||c.modal("hide")}function f(a){var b,c=0;for(b in a)c++;return c}function g(a,c){var d=0;b.each(a,function(a,b){c(a,b,d++)})}function h(a){var c,d;if("object"!=typeof a)throw new Error("Please supply an object of options");if(!a.message)throw new Error("Please specify a message");return a=b.extend({},o,a),a.buttons||(a.buttons={}),c=a.buttons,d=f(c),g(c,function(a,e,f){if(b.isFunction(e)&&(e=c[a]={callback:e}),"object"!==b.type(e))throw new Error("button with key "+a+" must be an object");e.label||(e.label=a),e.className||(2>=d&&f===d-1?e.className="bwp-btn-primary button-primary":e.className="bwp-btn-default button-secondary")}),a}function i(a,b){var c=a.length,d={};if(1>c||c>2)throw new Error("Invalid argument length");return 2===c||"string"==typeof a[0]?(d[b[0]]=a[0],d[b[1]]=a[1]):d=a[0],d}function j(a,c,d){return b.extend(!0,{},a,i(c,d))}function k(a,b,c,d){var e={className:"bootbox-"+a,buttons:l.apply(null,b)};return m(j(e,d,c),b)}function l(){for(var a={},b=0,c=arguments.length;c>b;b++){var e=arguments[b],f=e.toLowerCase(),g=e.toUpperCase();a[f]={label:d(g)}}return a}function m(a,b){var d={};return g(b,function(a,b){d[b]=!0}),g(a.buttons,function(a){if(d[a]===c)throw new Error("button key "+a+" is not allowed (options are "+b.join("\n")+")")}),a}var n={dialog:"<div class='bootbox bwp-modal' tabindex='-1' role='dialog'><div class='bwp-modal-dialog'><div class='bwp-modal-content'><div class='bwp-modal-body'><div class='bootbox-body'></div></div></div></div></div>",header:"<div class='bwp-modal-header'><h4 class='bwp-modal-title'></h4></div>",footer:"<div class='bwp-modal-footer'></div>",closeButton:" <button type='button' class='bootbox-close-button bwp-close' data-dismiss='modal' aria-hidden='true'>&times;</button>",form:"<form class='bootbox-form'></form>",inputs:{text:"<input class='bootbox-input bootbox-input-text form-control' autocomplete=off type=text />",textarea:"<textarea class='bootbox-input bootbox-input-textarea form-control'></textarea>",email:"<input class='bootbox-input bootbox-input-email form-control' autocomplete='off' type='email' />",select:"<select class='bootbox-input bootbox-input-select form-control'></select>",checkbox:"<div class='checkbox'><label><input class='bootbox-input bootbox-input-checkbox' type='checkbox' /></label></div>",date:"<input class='bootbox-input bootbox-input-date form-control' autocomplete=off type='date' />",time:"<input class='bootbox-input bootbox-input-time form-control' autocomplete=off type='time' />",number:"<input class='bootbox-input bootbox-input-number form-control' autocomplete=off type='number' />",password:"<input class='bootbox-input bootbox-input-password form-control' autocomplete='off' type='password' />"}},o={locale:"en",backdrop:"static",animate:!0,className:null,closeButton:!0,show:!0,container:"body"},p={};p.alert=function(){var a;if(a=k("alert",["ok"],["message","callback"],arguments),a.callback&&!b.isFunction(a.callback))throw new Error("alert requires callback property to be a function when provided");return a.buttons.ok.callback=a.onEscape=function(){return b.isFunction(a.callback)?a.callback.call(this):!0},p.dialog(a)},p.confirm=function(){var a;if(a=k("confirm",["cancel","confirm"],["message","callback"],arguments),a.buttons.cancel.callback=a.onEscape=function(){return a.callback.call(this,!1)},a.buttons.confirm.callback=function(){return a.callback.call(this,!0)},!b.isFunction(a.callback))throw new Error("confirm requires a callback");return p.dialog(a)},p.prompt=function(){var a,d,e,f,h,i,k;if(f=b(n.form),d={className:"bootbox-prompt",buttons:l("cancel","confirm"),value:"",inputType:"text"},a=m(j(d,arguments,["title","callback"]),["cancel","confirm"]),i=a.show===c?!0:a.show,a.message=f,a.buttons.cancel.callback=a.onEscape=function(){return a.callback.call(this,null)},a.buttons.confirm.callback=function(){var c;switch(a.inputType){case"text":case"textarea":case"email":case"select":case"date":case"time":case"number":case"password":c=h.val();break;case"checkbox":var d=h.find("input:checked");c=[],g(d,function(a,d){c.push(b(d).val())})}return a.callback.call(this,c)},a.show=!1,!a.title)throw new Error("prompt requires a title");if(!b.isFunction(a.callback))throw new Error("prompt requires a callback");if(!n.inputs[a.inputType])throw new Error("invalid prompt type");switch(h=b(n.inputs[a.inputType]),a.inputType){case"text":case"textarea":case"email":case"date":case"time":case"number":case"password":h.val(a.value);break;case"select":var o={};if(k=a.inputOptions||[],!b.isArray(k))throw new Error("Please pass an array of input options");if(!k.length)throw new Error("prompt with select requires options");g(k,function(a,d){var e=h;if(d.value===c||d.text===c)throw new Error("given options in wrong format");d.group&&(o[d.group]||(o[d.group]=b("<optgroup/>").attr("label",d.group)),e=o[d.group]),e.append("<option value='"+d.value+"'>"+d.text+"</option>")}),g(o,function(a,b){h.append(b)}),h.val(a.value);break;case"checkbox":var q=b.isArray(a.value)?a.value:[a.value];if(k=a.inputOptions||[],!k.length)throw new Error("prompt with checkbox requires options");if(!k[0].value||!k[0].text)throw new Error("given options in wrong format");h=b("<div/>"),g(k,function(c,d){var e=b(n.inputs[a.inputType]);e.find("input").attr("value",d.value),e.find("label").append(d.text),g(q,function(a,b){b===d.value&&e.find("input").prop("checked",!0)}),h.append(e)})}return a.placeholder&&h.attr("placeholder",a.placeholder),a.pattern&&h.attr("pattern",a.pattern),a.maxlength&&h.attr("maxlength",a.maxlength),f.append(h),f.on("submit",function(a){a.preventDefault(),a.stopPropagation(),e.find(".bwp-btn-primary").click()}),e=p.dialog(a),e.off("shown.bs.modal"),e.on("shown.bs.modal",function(){h.focus()}),i===!0&&e.modal("show"),e},p.dialog=function(a){a=h(a);var d=b(n.dialog),f=d.find(".bwp-modal-dialog"),i=d.find(".bwp-modal-body"),j=a.buttons,k="",l={onEscape:a.onEscape};if(b.fn.modal===c)throw new Error("$.fn.modal is not defined; please double check you have included the Bootstrap JavaScript library. See http://getbootstrap.com/javascript/ for more details.");if(g(j,function(a,b){k+=" <button data-bb-handler='"+a+"' type='button' class='bwp-btn "+b.className+"'>"+b.label+"</button>",l[a]=b.callback}),i.find(".bootbox-body").html(a.message),a.animate===!0&&d.addClass("fade"),a.className&&d.addClass(a.className),"large"===a.size?f.addClass("bwp-modal-lg"):"small"===a.size&&f.addClass("bwp-modal-sm"),a.title&&i.before(n.header),a.closeButton){var m=b(n.closeButton);a.title?d.find(".bwp-modal-header").prepend(m):m.css("margin-top","-10px").prependTo(i)}return a.title&&d.find(".bwp-modal-title").html(a.title),k.length&&(i.after(n.footer),d.find(".bwp-modal-footer").html(k)),d.on("hidden.bs.modal",function(a){a.target===this&&d.remove()}),d.on("shown.bs.modal",function(){d.find(".bwp-btn-primary:first").focus()}),"static"!==a.backdrop&&d.on("click.dismiss.bs.modal",function(a){d.children(".bwp-modal-backdrop").length&&(a.currentTarget=d.children(".bwp-modal-backdrop").get(0)),a.target===a.currentTarget&&d.trigger("escape.close.bb")}),d.on("escape.close.bb",function(a){l.onEscape&&e(a,d,l.onEscape)}),d.on("click",".bwp-modal-footer button",function(a){var c=b(this).data("bb-handler");e(a,d,l[c])}),d.on("click",".bootbox-close-button",function(a){e(a,d,l.onEscape)}),d.on("keyup",function(a){27===a.which&&d.trigger("escape.close.bb")}),b(a.container).append(d),d.modal({backdrop:a.backdrop?"static":!1,keyboard:!1,show:!1}),a.show&&d.modal("show"),d},p.setDefaults=function(){var a={};2===arguments.length?a[arguments[0]]=arguments[1]:a=arguments[0],b.extend(o,a)},p.hideAll=function(){return b(".bootbox").modal("hide"),p};var q={bg_BG:{OK:"Ок",CANCEL:"Отказ",CONFIRM:"Потвърждавам"},br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},cs:{OK:"OK",CANCEL:"Zrušit",CONFIRM:"Potvrdit"},da:{OK:"OK",CANCEL:"Annuller",CONFIRM:"Accepter"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},el:{OK:"Εντάξει",CANCEL:"Ακύρωση",CONFIRM:"Επιβεβαίωση"},en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},et:{OK:"OK",CANCEL:"Katkesta",CONFIRM:"OK"},fa:{OK:"قبول",CANCEL:"لغو",CONFIRM:"تایید"},fi:{OK:"OK",CANCEL:"Peruuta",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},he:{OK:"אישור",CANCEL:"ביטול",CONFIRM:"אישור"},hu:{OK:"OK",CANCEL:"Mégsem",CONFIRM:"Megerősít"},hr:{OK:"OK",CANCEL:"Odustani",CONFIRM:"Potvrdi"},id:{OK:"OK",CANCEL:"Batal",CONFIRM:"OK"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"},ja:{OK:"OK",CANCEL:"キャンセル",CONFIRM:"確認"},lt:{OK:"Gerai",CANCEL:"Atšaukti",CONFIRM:"Patvirtinti"},lv:{OK:"Labi",CANCEL:"Atcelt",CONFIRM:"Apstiprināt"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},no:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},pl:{OK:"OK",CANCEL:"Anuluj",CONFIRM:"Potwierdź"},pt:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Confirmar"},ru:{OK:"OK",CANCEL:"Отмена",CONFIRM:"Применить"},sq:{OK:"OK",CANCEL:"Anulo",CONFIRM:"Prano"},sv:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},th:{OK:"ตกลง",CANCEL:"ยกเลิก",CONFIRM:"ยืนยัน"},tr:{OK:"Tamam",CANCEL:"İptal",CONFIRM:"Onayla"},zh_CN:{OK:"OK",CANCEL:"取消",CONFIRM:"确认"},zh_TW:{OK:"OK",CANCEL:"取消",CONFIRM:"確認"}};return p.addLocale=function(a,c){return b.each(["OK","CANCEL","CONFIRM"],function(a,b){if(!c[b])throw new Error("Please supply a translation for '"+b+"'")}),q[a]={OK:c.OK,CANCEL:c.CANCEL,CONFIRM:c.CONFIRM},p},p.removeLocale=function(a){return delete q[a],p},p.setLocale=function(a){return p.setDefaults("locale",a)},p.init=function(c){return a(c||b)},p});var bwp_bootbox=function(a,b){"use strict";return b.setDefaults({animation:!1,closeButton:!1}),{alert:function(c,d,e){e=e||{},e=a.extend(e,{size:"small",message:c,callback:d}),b.alert(e)},confirm:function(c,d,e){e=e||{},e=a.extend(e,{size:"small",message:c,callback:function(a){a?d():e.callback_cancel&&e.callback_cancel()}}),b.confirm(e)}}}(jQuery,bootbox);jQuery(function(a){"use strict";var b;a("body").on("click",".bwp-button-modal",function(b){b.preventDefault();var c=a(this),d=c.data("target"),e=c.data("ajaxAction");if("undefined"==typeof e)a(d).modal();else{var f=c.data("loader"),g=c.data("ajaxCallback");a.get(ajaxurl,{action:e,id:c.data("id"),custom:c.data("custom")},function(b){a(d).find(".bwp-modal-content").html(b),bwp_common.enhance_form_fields(a(d)),"undefined"!=typeof g&&window[g](a,b,c),f&&a("#"+f).hide(),a(d).modal()})}}),a(".bwp-modal").on("submit","form",function(c){c.preventDefault();var d=a(this),e=d.parents(".bwp-modal").find(".bwp-button-modal-submit"),f=e.data("ajaxCallback"),g=e.data("ajaxErrorCallback"),h=d.serialize();d.find(":input").prop("disabled",!0);var i=e.parents(".bwp-modal-footer").find(".bwp-modal-message");i.removeClass("text-success text-danger").text(i.data("workingText")).show(),a.post(ajaxurl,h,function(b){"undefined"!=typeof f&&window[f](a,b,e,d),0===e.parents(".bwp-modal-footer").find(".bwp-button-modal-reset").length&&d.trigger("reset"),0===parseInt(b,10)||b.error?i.addClass("text-danger"):i.addClass("text-success")},"json").fail(function(b){"undefined"!=typeof g&&window[g](a,b,e,d),i.addClass("text-danger")}).always(function(a){d.find(":input").prop("disabled",!1),a.message?(i.text(a.message),"undefined"!=typeof b&&clearTimeout(b),b=setTimeout(function(){i.fadeOut("fast")},5e3)):i.fadeOut("fast")})}),a(".bwp-modal").on("click",".bwp-button-modal-submit",function(b){b.preventDefault();var c=a(this).parents(".bwp-modal").find("form");c.submit()}),a(".bwp-modal").on("click",".bwp-button-modal-reset",function(b){b.preventDefault();var c=a(this);c.parents(".bwp-modal").find("form").trigger("reset")}),a(".bwp-modal").on("show.bs.modal",function(b){var c=a(this);c.find("form").trigger("reset"),c.find(".bwp-modal-message").removeClass("text-success text-danger").hide()}),a("body").on("shown.bs.modal",".bwp-modal",function(b){var c=a(this).find(".bwp-modal-dialog");c.css({top:"50%","margin-top":function(){return-(c.height()/2)}})})});
vendor/kminh/bwp-framework/assets/option-page/dist/js/op.min.js CHANGED
@@ -1 +1 @@
1
- function AnchorJS(a){"use strict";this.options=a||{},this._applyRemainingDefaultOptions=function(a){this.options.icon=this.options.hasOwnProperty("icon")?a.icon:"",this.options.visible=this.options.hasOwnProperty("visible")?a.visible:"hover",this.options.placement=this.options.hasOwnProperty("placement")?a.placement:"right",this.options["class"]=this.options.hasOwnProperty("class")?a["class"]:""},this._applyRemainingDefaultOptions(a),this.add=function(a){var b,c,d,e,f,g,h,i,j,k,l,m;if(this._applyRemainingDefaultOptions(this.options),a){if("string"!=typeof a)throw new Error("The selector provided to AnchorJS was invalid.")}else a="h1, h2, h3, h4, h5, h6";if(b=document.querySelectorAll(a),0===b.length)return!1;for(this._addBaselineStyles(),c=document.querySelectorAll("[id]"),d=[].map.call(c,function(a){return a.id}),f=0;f<b.length;f++){if(b[f].hasAttribute("id"))e=b[f].getAttribute("id");else{g=b[f].textContent,h=g.replace(/[^\w\s-]/gi,"").replace(/\s+/g,"-").replace(/-{2,}/g,"-").substring(0,64).replace(/^-+|-+$/gm,"").toLowerCase(),k=h,j=0;do void 0!==i&&(k=h+"-"+j),i=d.indexOf(k),j+=1;while(-1!==i);i=void 0,d.push(k),b[f].setAttribute("id",k),e=k}l=e.replace(/-/g," "),m=document.createElement("a"),m.className="anchorjs-link "+this.options["class"],m.href="#"+e,m.setAttribute("aria-label","Anchor link for: "+l),m.setAttribute("data-anchorjs-icon",this.options.icon),"always"===this.options.visible&&(m.style.opacity="1"),""===this.options.icon&&(m.style.fontFamily="anchorjs-icons",m.style.fontStyle="normal",m.style.fontVariant="normal",m.style.fontWeight="normal",m.style.lineHeight=1,"left"===this.options.placement&&(m.style.lineHeight="inherit")),"left"===this.options.placement?(m.style.position="absolute",m.style.marginLeft="-1em",m.style.paddingRight="0.5em",b[f].insertBefore(m,b[f].firstChild)):(m.style.paddingLeft="0.375em",b[f].appendChild(m))}return this},this.remove=function(a){for(var b,c=document.querySelectorAll(a),d=0;d<c.length;d++)b=c[d].querySelector(".anchorjs-link"),b&&c[d].removeChild(b);return this},this._addBaselineStyles=function(){if(null===document.head.querySelector("style.anchorjs")){var a,b=document.createElement("style"),c=" .anchorjs-link { opacity: 0; text-decoration: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }",d=" *:hover > .anchorjs-link, .anchorjs-link:focus { opacity: 1; }",e=' @font-face { font-family: "anchorjs-icons"; font-style: normal; font-weight: normal; src: url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBTUAAAC8AAAAYGNtYXAWi9QdAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5Zgq29TcAAAF4AAABNGhlYWQEZM3pAAACrAAAADZoaGVhBhUDxgAAAuQAAAAkaG10eASAADEAAAMIAAAAFGxvY2EAKACuAAADHAAAAAxtYXhwAAgAVwAAAygAAAAgbmFtZQ5yJ3cAAANIAAAB2nBvc3QAAwAAAAAFJAAAACAAAwJAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpywPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6cv//f//AAAAAAAg6cv//f//AAH/4xY5AAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAACADEARAJTAsAAKwBUAAABIiYnJjQ/AT4BMzIWFxYUDwEGIicmND8BNjQnLgEjIgYPAQYUFxYUBw4BIwciJicmND8BNjIXFhQPAQYUFx4BMzI2PwE2NCcmNDc2MhcWFA8BDgEjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAEAAAABAACiToc1Xw889QALBAAAAAAA0XnFFgAAAADRecUWAAAAAAJTAsAAAAAIAAIAAAAAAAAAAQAAA8D/wAAABAAAAAAAAlMAAQAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAACAAAAAoAAMQAAAAAACgAUAB4AmgABAAAABQBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEADgAAAAEAAAAAAAIABwCfAAEAAAAAAAMADgBLAAEAAAAAAAQADgC0AAEAAAAAAAUACwAqAAEAAAAAAAYADgB1AAEAAAAAAAoAGgDeAAMAAQQJAAEAHAAOAAMAAQQJAAIADgCmAAMAAQQJAAMAHABZAAMAAQQJAAQAHADCAAMAAQQJAAUAFgA1AAMAAQQJAAYAHACDAAMAAQQJAAoANAD4YW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzVmVyc2lvbiAxLjAAVgBlAHIAcwBpAG8AbgAgADEALgAwYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzUmVndWxhcgBSAGUAZwB1AGwAYQByYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzRm9udCBnZW5lcmF0ZWQgYnkgSWNvTW9vbi4ARgBvAG4AdAAgAGcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAuAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format("truetype"); }',f=" [data-anchorjs-icon]::after { content: attr(data-anchorjs-icon); }";b.className="anchorjs",b.appendChild(document.createTextNode("")),a=document.head.querySelector('[rel="stylesheet"], style'),void 0===a?document.head.appendChild(b):document.head.insertBefore(b,a),b.sheet.insertRule(c,b.sheet.cssRules.length),b.sheet.insertRule(d,b.sheet.cssRules.length),b.sheet.insertRule(f,b.sheet.cssRules.length),b.sheet.insertRule(e,b.sheet.cssRules.length)}}}var anchors=new AnchorJS;jQuery(function(a){"use strict";var b=function(b){var c=b.data("contentId");return c?a("#"+c).html():void 0},c=function(b,c){return a(c).data("placement")?a(c).data("placement"):"auto top"};a("#wpcontent").popover({selector:".bwp-popover-hover",trigger:"hover",viewport:{selector:"#wpcontent",padding:10},placement:c,html:!0,content:b(a(this))}),a(".wrap").popover({selector:".bwp-popover-focus",trigger:"focus",viewport:{selector:"#wpcontent",padding:10},placement:c,html:!0,content:b(a(this))}),a(".wrap").on("click",".bwp-popover-switch",function(d){d.preventDefault();var e=a(this);e.data("bs.popover")||e.popover({trigger:"manual",viewport:{selector:"#wpcontent",padding:10},placement:c,html:!0,content:b(e)}),e.popover("toggle")}).on("click",function(b){var c=a(b.target);c.is(".bwp-popover")||c.parents(".bwp-popover").length>0||c.is(".bwp-popover-switch")||c.is(".bwp-popover-focus")||a(".bwp-popover-switch").popover("hide")}).on("show.bs.popover",".bwp-popover-switch",function(b){var c=a(this),d=c.data("bs.popover").$tip,e=c.data("submitCallback");d.on("click",".bwp-popover-close",function(a){a.preventDefault(),c.popover("hide")}),d.on("click",".bwp-popover-submit",function(b){b.preventDefault();var f=a(this).data("submitCallback");"undefined"!=typeof f?window[f](a,a(this),c,d):"undefined"!=typeof e&&window[e](a,a(this),c,d),c.popover("hide")})}).on("hide.bs.popover",".bwp-popover-switch",function(b){var c=a(this),d=c.data("bs.popover").$tip;d.off("click",".bwp-popover-close"),d.off("click",".bwp-popover-submit")}),a(".wrap").on("show.bs.popover",".bwp-popover-hover, .bwp-popover-focus, .bwp-popover-switch",function(){var b=a(this),c=b.data("popoverClass");c&&b.data("bs.popover").$tip.addClass(c)})}),jQuery(function(a){"use strict";function b(b){var c=b.data("target"),d=b.data("toggleValue"),e=a.trim(b.val()),f=b.data("toggledLabel");if(b.is(":button")&&f){var g=b.text()?b.text():b.val();b.data("toggledLabel",g),b.text(f)}var h=a("#"+c).is(":input")||a("#"+c).is("h3")?a("#"+c).parents(".bwp-clear"):a("#"+c);if(d)b.is(":button")||h.toggleClass("bwp-no-display",d!==e);else if(b.is(":button"))h.toggleClass("bwp-no-display");else if(b.is(":checkbox")){var i=b.data("checkboxInvert");i?h.toggleClass("bwp-no-display",b.prop("checked")):h.toggleClass("bwp-no-display",!b.prop("checked"))}else h.toggleClass("bwp-no-display",""===e);b.prop("disabled",!1)}function c(b){var c=b.data("callbackAfter");"function"==typeof window[c]&&window[c](a,b)}function d(d){var e=d.data("loader"),f=d.data("callback");e&&a("#"+e).show(),d.prop("disabled",!0),"function"==typeof window[f]?e?window[f](a,d,function(){a("#"+e).hide(),b(d),c(d)}):(window[f](a,d),b(d),c(d)):(a("#"+e).hide(),b(d),c(d))}a(".bwp-switch-select").on("change",function(b){d(a(this)),b.preventDefault()}),a(".bwp-switch-button").on("click",function(b){d(a(this)),b.preventDefault()}),a(".bwp-switch-on-load").each(function(){b(a(this))})}),jQuery(function(a){"use strict";bwp_common.enhance_form_fields(),anchors.add(".wrap h3")});
1
+ function AnchorJS(a){"use strict";this.options=a||{},this._applyRemainingDefaultOptions=function(a){this.options.icon=this.options.hasOwnProperty("icon")?a.icon:"",this.options.visible=this.options.hasOwnProperty("visible")?a.visible:"hover",this.options.placement=this.options.hasOwnProperty("placement")?a.placement:"right",this.options["class"]=this.options.hasOwnProperty("class")?a["class"]:""},this._applyRemainingDefaultOptions(a),this.add=function(a){var b,c,d,e,f,g,h,i,j,k,l,m;if(this._applyRemainingDefaultOptions(this.options),a){if("string"!=typeof a)throw new Error("The selector provided to AnchorJS was invalid.")}else a="h1, h2, h3, h4, h5, h6";if(b=document.querySelectorAll(a),0===b.length)return!1;for(this._addBaselineStyles(),c=document.querySelectorAll("[id]"),d=[].map.call(c,function(a){return a.id}),f=0;f<b.length;f++){if(b[f].hasAttribute("id"))e=b[f].getAttribute("id");else{g=b[f].textContent,h=g.replace(/[^\w\s-]/gi,"").replace(/\s+/g,"-").replace(/-{2,}/g,"-").substring(0,64).replace(/^-+|-+$/gm,"").toLowerCase(),k=h,j=0;do void 0!==i&&(k=h+"-"+j),i=d.indexOf(k),j+=1;while(-1!==i);i=void 0,d.push(k),b[f].setAttribute("id",k),e=k}l=e.replace(/-/g," "),m=document.createElement("a"),m.className="anchorjs-link "+this.options["class"],m.href="#"+e,m.setAttribute("aria-label","Anchor link for: "+l),m.setAttribute("data-anchorjs-icon",this.options.icon),"always"===this.options.visible&&(m.style.opacity="1"),""===this.options.icon&&(m.style.fontFamily="anchorjs-icons",m.style.fontStyle="normal",m.style.fontVariant="normal",m.style.fontWeight="normal",m.style.lineHeight=1,"left"===this.options.placement&&(m.style.lineHeight="inherit")),"left"===this.options.placement?(m.style.position="absolute",m.style.marginLeft="-1em",m.style.paddingRight="0.5em",b[f].insertBefore(m,b[f].firstChild)):(m.style.paddingLeft="0.375em",b[f].appendChild(m))}return this},this.remove=function(a){for(var b,c=document.querySelectorAll(a),d=0;d<c.length;d++)b=c[d].querySelector(".anchorjs-link"),b&&c[d].removeChild(b);return this},this._addBaselineStyles=function(){if(null===document.head.querySelector("style.anchorjs")){var a,b=document.createElement("style"),c=" .anchorjs-link { opacity: 0; text-decoration: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }",d=" *:hover > .anchorjs-link, .anchorjs-link:focus { opacity: 1; }",e=' @font-face { font-family: "anchorjs-icons"; font-style: normal; font-weight: normal; src: url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBTUAAAC8AAAAYGNtYXAWi9QdAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5Zgq29TcAAAF4AAABNGhlYWQEZM3pAAACrAAAADZoaGVhBhUDxgAAAuQAAAAkaG10eASAADEAAAMIAAAAFGxvY2EAKACuAAADHAAAAAxtYXhwAAgAVwAAAygAAAAgbmFtZQ5yJ3cAAANIAAAB2nBvc3QAAwAAAAAFJAAAACAAAwJAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpywPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6cv//f//AAAAAAAg6cv//f//AAH/4xY5AAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAACADEARAJTAsAAKwBUAAABIiYnJjQ/AT4BMzIWFxYUDwEGIicmND8BNjQnLgEjIgYPAQYUFxYUBw4BIwciJicmND8BNjIXFhQPAQYUFx4BMzI2PwE2NCcmNDc2MhcWFA8BDgEjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAEAAAABAACiToc1Xw889QALBAAAAAAA0XnFFgAAAADRecUWAAAAAAJTAsAAAAAIAAIAAAAAAAAAAQAAA8D/wAAABAAAAAAAAlMAAQAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAACAAAAAoAAMQAAAAAACgAUAB4AmgABAAAABQBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEADgAAAAEAAAAAAAIABwCfAAEAAAAAAAMADgBLAAEAAAAAAAQADgC0AAEAAAAAAAUACwAqAAEAAAAAAAYADgB1AAEAAAAAAAoAGgDeAAMAAQQJAAEAHAAOAAMAAQQJAAIADgCmAAMAAQQJAAMAHABZAAMAAQQJAAQAHADCAAMAAQQJAAUAFgA1AAMAAQQJAAYAHACDAAMAAQQJAAoANAD4YW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzVmVyc2lvbiAxLjAAVgBlAHIAcwBpAG8AbgAgADEALgAwYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzUmVndWxhcgBSAGUAZwB1AGwAYQByYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzRm9udCBnZW5lcmF0ZWQgYnkgSWNvTW9vbi4ARgBvAG4AdAAgAGcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAuAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format("truetype"); }',f=" [data-anchorjs-icon]::after { content: attr(data-anchorjs-icon); }";b.className="anchorjs",b.appendChild(document.createTextNode("")),a=document.head.querySelector('[rel="stylesheet"], style'),void 0===a?document.head.appendChild(b):document.head.insertBefore(b,a),b.sheet.insertRule(c,b.sheet.cssRules.length),b.sheet.insertRule(d,b.sheet.cssRules.length),b.sheet.insertRule(f,b.sheet.cssRules.length),b.sheet.insertRule(e,b.sheet.cssRules.length)}}}function bwp_populate_feed_news(a){bwp_op.populate_feed_news(a)}function bwp_populate_feed_gems(a){bwp_op.populate_feed_gems(a)}var anchors=new AnchorJS;jQuery(function(a){"use strict";var b=function(b){var c=b.data("contentId");return c?a("#"+c).html():void 0},c=function(b,c){return a(c).data("placement")?a(c).data("placement"):"auto top"};a("#wpcontent").popover({selector:".bwp-popover-hover",trigger:"hover",viewport:{selector:"#wpcontent",padding:10},placement:c,html:!0,content:b(a(this))}),a(".wrap").popover({selector:".bwp-popover-focus",trigger:"focus",viewport:{selector:"#wpcontent",padding:10},placement:c,html:!0,content:b(a(this))}),a(".wrap").on("click",".bwp-popover-switch",function(d){d.preventDefault();var e=a(this);e.data("bs.popover")||e.popover({trigger:"manual",viewport:{selector:"#wpcontent",padding:10},placement:c,html:!0,content:b(e)}),e.popover("toggle")}).on("click",function(b){var c=a(b.target);c.is(".bwp-popover")||c.parents(".bwp-popover").length>0||!c.is(".bwp-popover-switch")&&!c.is(".bwp-popover-focus")&&!c.parents(".bwp-popover-switch").length>0&&!c.parents(".bwp-popover-focus").length>0&&a(".bwp-popover-switch").popover("hide")}).on("show.bs.popover",".bwp-popover-switch",function(b){var c=a(this),d=c.data("bs.popover").$tip,e=c.data("submitCallback");d.on("click",".bwp-popover-close",function(a){a.preventDefault(),c.popover("hide")}),d.on("click",".bwp-popover-submit",function(b){b.preventDefault();var f=a(this).data("submitCallback");"undefined"!=typeof f?window[f](a,a(this),c,d):"undefined"!=typeof e&&window[e](a,a(this),c,d),c.popover("hide")})}).on("hide.bs.popover",".bwp-popover-switch",function(b){var c=a(this),d=c.data("bs.popover").$tip;d.off("click",".bwp-popover-close"),d.off("click",".bwp-popover-submit")}),a(".wrap").on("show.bs.popover",".bwp-popover-hover, .bwp-popover-focus, .bwp-popover-switch",function(){var b=a(this),c=b.data("popoverClass");c&&b.data("bs.popover").$tip.addClass(c)})}),jQuery(function(a){"use strict";function b(b){var c=b.data("target"),d=b.data("toggleValue"),e=a.trim(b.val()),f=b.data("toggledLabel");if(b.is(":button")&&f){var g=b.text()?b.text():b.val();b.data("toggledLabel",g),b.text(f)}var h=a("#"+c).is(":input")||a("#"+c).is("h3")?a("#"+c).parents(".bwp-clear"):a("#"+c);if(d)b.is(":button")||h.toggleClass("bwp-no-display",d!==e);else if(b.is(":button"))h.toggleClass("bwp-no-display");else if(b.is(":checkbox")){var i=b.data("checkboxInvert");i?h.toggleClass("bwp-no-display",b.prop("checked")):h.toggleClass("bwp-no-display",!b.prop("checked"))}else h.toggleClass("bwp-no-display",""===e);b.prop("disabled",!1)}function c(b){var c=b.data("callbackAfter");"function"==typeof window[c]&&window[c](a,b)}function d(d){var e=d.data("loader"),f=d.data("callback");e&&a("#"+e).show(),d.prop("disabled",!0),"function"==typeof window[f]?e?window[f](a,d,function(){a("#"+e).hide(),b(d),c(d)}):(window[f](a,d),b(d),c(d)):(a("#"+e).hide(),b(d),c(d))}a(".bwp-switch-select").on("change",function(b){d(a(this)),b.preventDefault()}),a(".bwp-switch-button").on("click",function(b){d(a(this)),b.preventDefault()}),a(".bwp-switch-on-load").each(function(){b(a(this))})});var bwp_op=function(a){function b(b,c){a.each(b,function(b,d){var e=a("<li>");if(a("<a>",{text:d.title}).attr("target","_blank").attr("href",d.permalink+"?utm_source="+c.data("pluginKey")+"&utm_medium=feed&utm_campaign=sidebar-2016"+(d.just_in?"&utm_content=justin":"")).appendTo(e),d.just_in&&a("<span />",{"class":"bwp-justin",text:" Just in!"}).appendTo(e),a("<br />").appendTo(e),d.views){var f=d.comment_count?""+parseInt(d.comment_count,10)+' <span class="bwp-meta">comments</span><span class="bwp-meta"> / </span>':"";f=f+parseInt(d.views/1e3,10)+'k+ <span class="bwp-meta">views</span>',a("<span />",{html:f}).appendTo(e)}else a("<span />",{"class":"bwp-meta",text:d.post_date_gmt}).appendTo(e);e.appendTo(c.find(".bwp-feed"))}),c.find(".bwp-loader").hide()}function c(c){b(c,a("#bwp-news"))}function d(c){b(c,a("#bwp-gems"))}function e(b,c){b+="?_jsonp=?",a.ajax(b,{cache:!0,dataType:"jsonp",jsonpCallback:c})}return a(function(){"use strict";bwp_common.enhance_form_fields(),"undefined"!=typeof anchors&&anchors.add(".bwp-option-page h3"),e("http://betterwp.net/wp-json/bwp/v1/news","bwp_populate_feed_news"),e("http://betterwp.net/wp-json/bwp/v1/gems","bwp_populate_feed_gems")}),{populate_feed_news:c,populate_feed_gems:d}}(jQuery);
vendor/kminh/bwp-framework/assets/option-page/js/codemirror.js ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global jQuery,CodeMirror */
2
+ var bwp_editors = (function($, cm) {
3
+ var defaults = {
4
+ indentUnit: 4,
5
+ readOnly: false,
6
+ theme: 'neo'
7
+ };
8
+
9
+ var editors = {};
10
+
11
+ function init_editor(node) {
12
+ var id = $(node).attr('id');
13
+ // editor already initialized
14
+ if (typeof editors[id] !== 'undefined') {
15
+ return;
16
+ }
17
+
18
+ var mode = $(node).data('mode');
19
+ var ln = $(node).data('linenr');
20
+ var ro = $(node).data('readOnly') || $(node).prop('readonly');
21
+ var cursorline = $(node).data('cursorline');
22
+
23
+ var editor = editors[id] = cm.fromTextArea(node, $.extend(defaults, {
24
+ mode: mode,
25
+ lineNumbers: ln ? true : false,
26
+ readOnly: ro ? true : false,
27
+ styleActiveLine: cursorline ? true : false
28
+ }));
29
+
30
+ // add an id to the editor's wrapper to make it more accessible
31
+ $(editor.getWrapperElement()).attr('id', id + '_cm');
32
+ }
33
+
34
+ function start_edit(node_id, focus) {
35
+ if (typeof editors[node_id] === 'undefined') {
36
+ return;
37
+ }
38
+
39
+ var editor = editors[node_id];
40
+ focus = typeof focus === 'undefined' ? true : focus;
41
+
42
+ $('#' + node_id).prop('readonly', false);
43
+ $(editor.getWrapperElement()).removeClass('CodeMirror-readonly');
44
+ editor.setOption('readOnly', false);
45
+
46
+ if (focus) {
47
+ editor.focus();
48
+ }
49
+ }
50
+
51
+ function stop_edit(node_id) {
52
+ if (typeof editors[node_id] === 'undefined') {
53
+ return;
54
+ }
55
+
56
+ var editor = editors[node_id];
57
+
58
+ $('#' + node_id).prop('readonly', true);
59
+ $(editor.getWrapperElement()).addClass('CodeMirror-readonly');
60
+ editor.setOption('readOnly', true);
61
+ }
62
+
63
+ function toggle_edit(focus) {
64
+ var target_id = $(this).data('target');
65
+ focus = typeof focus === 'undefined' ? true : focus;
66
+ if ($(this).is(':checked')) {
67
+ start_edit(target_id, focus);
68
+ } else {
69
+ stop_edit(target_id);
70
+ }
71
+ }
72
+
73
+ $(function() {
74
+ 'use strict';
75
+
76
+ $('body').on('click', '.bwp-button-code-editor', function(e) {
77
+ e.preventDefault();
78
+
79
+ var $t = $(this);
80
+ var target_id = $t.data('target'); // this does NOT includes the '#'
81
+
82
+ // no target, nothing to do
83
+ if (!target_id) {
84
+ return;
85
+ }
86
+
87
+ var $target = $('#' + target_id);
88
+
89
+ // editor already initialized, remove it and hide the node
90
+ if (typeof editors[target_id] !== 'undefined') {
91
+ editors[target_id].toTextArea();
92
+ delete editors[target_id];
93
+ $target.hide();
94
+ } else {
95
+ // show the node and init the editor
96
+ $target.show();
97
+ init_editor($target.get(0));
98
+ }
99
+ });
100
+
101
+ // init the code editor for all found elements
102
+ $('.bwp-code-editor').each(function(i, node) {
103
+ init_editor(node);
104
+ });
105
+
106
+ // allow toggling the code editor's readonly attribute
107
+ $('body').on('change', '.bwp-code-editor-cb', toggle_edit);
108
+ $('.bwp-code-editor-cb').each(function() {
109
+ toggle_edit.call(this, false);
110
+ });
111
+ });
112
+
113
+ return {
114
+ editors: editors,
115
+ edit: start_edit,
116
+ stop: stop_edit
117
+ };
118
+ })(jQuery, CodeMirror);
vendor/kminh/bwp-framework/assets/option-page/js/modal.js CHANGED
@@ -149,4 +149,16 @@ jQuery(function($) {
149
  .removeClass('text-success text-danger')
150
  .hide();
151
  });
 
 
 
 
 
 
 
 
 
 
 
 
152
  });
149
  .removeClass('text-success text-danger')
150
  .hide();
151
  });
152
+
153
+ // vertically center any modal
154
+ $('body').on('shown.bs.modal', '.bwp-modal', function(e) {
155
+ var $dialog = $(this).find('.bwp-modal-dialog');
156
+
157
+ $dialog.css({
158
+ top: '50%',
159
+ 'margin-top': function() {
160
+ return -($dialog.height() / 2);
161
+ }
162
+ });
163
+ });
164
  });
vendor/kminh/bwp-framework/assets/option-page/js/op.js CHANGED
@@ -1,9 +1,106 @@
1
  /*global jQuery,anchors,bwp_common*/
2
- jQuery(function($) {
3
- 'use strict';
 
4
 
5
- // do these once on document ready
6
- bwp_common.enhance_form_fields();
 
7
 
8
- anchors.add('.wrap h3');
9
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  /*global jQuery,anchors,bwp_common*/
2
+ function bwp_populate_feed_news(posts) {
3
+ bwp_op.populate_feed_news(posts);
4
+ }
5
 
6
+ function bwp_populate_feed_gems(posts) {
7
+ bwp_op.populate_feed_gems(posts);
8
+ }
9
 
10
+ var bwp_op = (function($) {
11
+ function populate_feed_items(posts, container) {
12
+ $.each(posts, function(i, post) {
13
+ var $li = $('<li>');
14
+
15
+ $('<a>', { text: post.title, })
16
+ .attr('target', '_blank')
17
+ .attr('href', post.permalink
18
+ + '?utm_source=' + container.data('pluginKey')
19
+ + '&utm_medium=feed'
20
+ + '&utm_campaign=sidebar-2016'
21
+ + (post.just_in ? '&utm_content=justin' : '')
22
+ )
23
+ .appendTo($li);
24
+
25
+ // indicate fresh articles
26
+ if (post.just_in) {
27
+ $('<span />', {
28
+ 'class': 'bwp-justin',
29
+ text: ' Just in!'
30
+ })
31
+ .appendTo($li)
32
+ }
33
+
34
+ $('<br />').appendTo($li);
35
+
36
+ if (post.views) {
37
+ var span_tpl = post.comment_count
38
+ ? ''
39
+ + parseInt(post.comment_count, 10)
40
+ + ' '
41
+ + '<span class="bwp-meta">comments</span>'
42
+ + '<span class="bwp-meta"> / </span>'
43
+ : '';
44
+
45
+ span_tpl = span_tpl
46
+ + parseInt(post.views / 1000, 10)
47
+ + 'k+ <span class="bwp-meta">views</span>';
48
+
49
+ $('<span />', {
50
+ html: span_tpl
51
+ })
52
+ .appendTo($li);
53
+ } else {
54
+ $('<span />', {
55
+ 'class': 'bwp-meta',
56
+ text: post.post_date_gmt
57
+ })
58
+ .appendTo($li);
59
+ }
60
+
61
+ $li.appendTo(container.find('.bwp-feed'));
62
+ });
63
+
64
+ container.find('.bwp-loader').hide();
65
+ }
66
+
67
+ function populate_feed_news(posts) {
68
+ populate_feed_items(posts, $('#bwp-news'));
69
+ }
70
+
71
+ function populate_feed_gems(posts) {
72
+ populate_feed_items(posts, $('#bwp-gems'));
73
+ }
74
+
75
+ function load_feed(url, jsonpCallback) {
76
+ // use jsonp
77
+ url = url + '?_jsonp=?';
78
+
79
+ $.ajax(url, {
80
+ cache: true,
81
+ dataType: 'jsonp',
82
+ jsonpCallback: jsonpCallback
83
+ });
84
+ }
85
+
86
+ $(function() {
87
+ 'use strict';
88
+
89
+ // do these once on document ready
90
+ bwp_common.enhance_form_fields();
91
+
92
+ // allow easy referencing inside admin pages
93
+ if (typeof anchors !== 'undefined') {
94
+ anchors.add('.bwp-option-page h3');
95
+ }
96
+
97
+ // load feeds
98
+ load_feed('http://betterwp.net/wp-json/bwp/v1/news', 'bwp_populate_feed_news');
99
+ load_feed('http://betterwp.net/wp-json/bwp/v1/gems', 'bwp_populate_feed_gems');
100
+ });
101
+
102
+ return {
103
+ populate_feed_news: populate_feed_news,
104
+ populate_feed_gems: populate_feed_gems
105
+ };
106
+ })(jQuery);
vendor/kminh/bwp-framework/assets/option-page/js/paypal.js CHANGED
@@ -1,11 +1,14 @@
 
1
  jQuery(document).ready(function($){
2
  /* Paypal form */
3
- $('.paypal-form select[name="amount"]').change(function() {
4
- if ($(this).val() == '100.00') {
5
- $(this).hide();
 
6
 
7
- $('.paypal-alternate-input')
8
- .append('<input type="text" style="padding: 3px; width: 70px; text-align: right; line-height: 1;" name="amount" value="15.00" /> <code>$</code>')
 
9
  .show();
10
  }
11
  });
1
+ /* global jQuery*/
2
  jQuery(document).ready(function($){
3
  /* Paypal form */
4
+ $('.wrap').on('change', '.paypal-form select[name="amount"]', function() {
5
+ var $t = $(this);
6
+ if ($t.val() == '100.00') {
7
+ $t.hide();
8
 
9
+ $t.parent()
10
+ .find('.paypal-alternate-input')
11
+ .append('$ <input type="text" style="width: 70px; text-align: right;" name="amount" value="15.00" />')
12
  .show();
13
  }
14
  });
vendor/kminh/bwp-framework/assets/option-page/js/popover.js CHANGED
@@ -72,8 +72,11 @@ jQuery(function($) {
72
  return;
73
  }
74
 
75
- // hide all popovers if the current target is not a popover switch itself
76
- if (! $t.is('.bwp-popover-switch') && ! $t.is('.bwp-popover-focus')) {
 
 
 
77
  $('.bwp-popover-switch').popover('hide');
78
  }
79
  })
72
  return;
73
  }
74
 
75
+ // hide all popovers if the current target is not a popover switch
76
+ // itself, or it has a parent that is a popover switch
77
+ if (! $t.is('.bwp-popover-switch') && ! $t.is('.bwp-popover-focus')
78
+ && ! $t.parents('.bwp-popover-switch').length > 0 && ! $t.parents('.bwp-popover-focus').length > 0
79
+ ) {
80
  $('.bwp-popover-switch').popover('hide');
81
  }
82
  })
vendor/kminh/bwp-framework/assets/vendor/codemirror/addon/display/placeholder.js ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ CodeMirror.defineOption("placeholder", "", function(cm, val, old) {
13
+ var prev = old && old != CodeMirror.Init;
14
+ if (val && !prev) {
15
+ cm.on("blur", onBlur);
16
+ cm.on("change", onChange);
17
+ onChange(cm);
18
+ } else if (!val && prev) {
19
+ cm.off("blur", onBlur);
20
+ cm.off("change", onChange);
21
+ clearPlaceholder(cm);
22
+ var wrapper = cm.getWrapperElement();
23
+ wrapper.className = wrapper.className.replace(" CodeMirror-empty", "");
24
+ }
25
+
26
+ if (val && !cm.hasFocus()) onBlur(cm);
27
+ });
28
+
29
+ function clearPlaceholder(cm) {
30
+ if (cm.state.placeholder) {
31
+ cm.state.placeholder.parentNode.removeChild(cm.state.placeholder);
32
+ cm.state.placeholder = null;
33
+ }
34
+ }
35
+ function setPlaceholder(cm) {
36
+ clearPlaceholder(cm);
37
+ var elt = cm.state.placeholder = document.createElement("pre");
38
+ elt.style.cssText = "height: 0; overflow: visible";
39
+ elt.className = "CodeMirror-placeholder";
40
+ var placeHolder = cm.getOption("placeholder")
41
+ if (typeof placeHolder == "string") placeHolder = document.createTextNode(placeHolder)
42
+ elt.appendChild(placeHolder)
43
+ cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild);
44
+ }
45
+
46
+ function onBlur(cm) {
47
+ if (isEmpty(cm)) setPlaceholder(cm);
48
+ }
49
+ function onChange(cm) {
50
+ var wrapper = cm.getWrapperElement(), empty = isEmpty(cm);
51
+ wrapper.className = wrapper.className.replace(" CodeMirror-empty", "") + (empty ? " CodeMirror-empty" : "");
52
+
53
+ if (empty) setPlaceholder(cm);
54
+ else clearPlaceholder(cm);
55
+ }
56
+
57
+ function isEmpty(cm) {
58
+ return (cm.lineCount() === 1) && (cm.getLine(0) === "");
59
+ }
60
+ });
vendor/kminh/bwp-framework/assets/vendor/codemirror/addon/selection/active-line.js ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ // Because sometimes you need to style the cursor's line.
5
+ //
6
+ // Adds an option 'styleActiveLine' which, when enabled, gives the
7
+ // active line's wrapping <div> the CSS class "CodeMirror-activeline",
8
+ // and gives its background <div> the class "CodeMirror-activeline-background".
9
+
10
+ (function(mod) {
11
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
12
+ mod(require("../../lib/codemirror"));
13
+ else if (typeof define == "function" && define.amd) // AMD
14
+ define(["../../lib/codemirror"], mod);
15
+ else // Plain browser env
16
+ mod(CodeMirror);
17
+ })(function(CodeMirror) {
18
+ "use strict";
19
+ var WRAP_CLASS = "CodeMirror-activeline";
20
+ var BACK_CLASS = "CodeMirror-activeline-background";
21
+
22
+ CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) {
23
+ var prev = old && old != CodeMirror.Init;
24
+ if (val && !prev) {
25
+ cm.state.activeLines = [];
26
+ updateActiveLines(cm, cm.listSelections());
27
+ cm.on("beforeSelectionChange", selectionChange);
28
+ } else if (!val && prev) {
29
+ cm.off("beforeSelectionChange", selectionChange);
30
+ clearActiveLines(cm);
31
+ delete cm.state.activeLines;
32
+ }
33
+ });
34
+
35
+ function clearActiveLines(cm) {
36
+ for (var i = 0; i < cm.state.activeLines.length; i++) {
37
+ cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS);
38
+ cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS);
39
+ }
40
+ }
41
+
42
+ function sameArray(a, b) {
43
+ if (a.length != b.length) return false;
44
+ for (var i = 0; i < a.length; i++)
45
+ if (a[i] != b[i]) return false;
46
+ return true;
47
+ }
48
+
49
+ function updateActiveLines(cm, ranges) {
50
+ var active = [];
51
+ for (var i = 0; i < ranges.length; i++) {
52
+ var range = ranges[i];
53
+ if (!range.empty()) continue;
54
+ var line = cm.getLineHandleVisualStart(range.head.line);
55
+ if (active[active.length - 1] != line) active.push(line);
56
+ }
57
+ if (sameArray(cm.state.activeLines, active)) return;
58
+ cm.operation(function() {
59
+ clearActiveLines(cm);
60
+ for (var i = 0; i < active.length; i++) {
61
+ cm.addLineClass(active[i], "wrap", WRAP_CLASS);
62
+ cm.addLineClass(active[i], "background", BACK_CLASS);
63
+ }
64
+ cm.state.activeLines = active;
65
+ });
66
+ }
67
+
68
+ function selectionChange(cm, sel) {
69
+ updateActiveLines(cm, sel.ranges);
70
+ }
71
+ });
vendor/kminh/bwp-framework/assets/vendor/codemirror/codemirror.css ADDED
@@ -0,0 +1,334 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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;
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-ruler {
92
+ border-left: 1px solid #ccc;
93
+ position: absolute;
94
+ }
95
+
96
+ /* DEFAULT THEME */
97
+
98
+ .cm-s-default .cm-header {color: blue;}
99
+ .cm-s-default .cm-quote {color: #090;}
100
+ .cm-negative {color: #d44;}
101
+ .cm-positive {color: #292;}
102
+ .cm-header, .cm-strong {font-weight: bold;}
103
+ .cm-em {font-style: italic;}
104
+ .cm-link {text-decoration: underline;}
105
+ .cm-strikethrough {text-decoration: line-through;}
106
+
107
+ .cm-s-default .cm-keyword {color: #708;}
108
+ .cm-s-default .cm-atom {color: #219;}
109
+ .cm-s-default .cm-number {color: #164;}
110
+ .cm-s-default .cm-def {color: #00f;}
111
+ .cm-s-default .cm-variable,
112
+ .cm-s-default .cm-punctuation,
113
+ .cm-s-default .cm-property,
114
+ .cm-s-default .cm-operator {}
115
+ .cm-s-default .cm-variable-2 {color: #05a;}
116
+ .cm-s-default .cm-variable-3 {color: #085;}
117
+ .cm-s-default .cm-comment {color: #a50;}
118
+ .cm-s-default .cm-string {color: #a11;}
119
+ .cm-s-default .cm-string-2 {color: #f50;}
120
+ .cm-s-default .cm-meta {color: #555;}
121
+ .cm-s-default .cm-qualifier {color: #555;}
122
+ .cm-s-default .cm-builtin {color: #30a;}
123
+ .cm-s-default .cm-bracket {color: #997;}
124
+ .cm-s-default .cm-tag {color: #170;}
125
+ .cm-s-default .cm-attribute {color: #00c;}
126
+ .cm-s-default .cm-hr {color: #999;}
127
+ .cm-s-default .cm-link {color: #00c;}
128
+
129
+ .cm-s-default .cm-error {color: #f00;}
130
+ .cm-invalidchar {color: #f00;}
131
+
132
+ .CodeMirror-composing { border-bottom: 2px solid; }
133
+
134
+ /* Default styles for common addons */
135
+
136
+ div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
137
+ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
138
+ .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
139
+ .CodeMirror-activeline-background {background: #e8f2ff;}
140
+
141
+ /* STOP */
142
+
143
+ /* The rest of this file contains styles related to the mechanics of
144
+ the editor. You probably shouldn't touch them. */
145
+
146
+ .CodeMirror {
147
+ position: relative;
148
+ overflow: hidden;
149
+ background: white;
150
+ }
151
+
152
+ .CodeMirror-scroll {
153
+ overflow: scroll !important; /* Things will break if this is overridden */
154
+ /* 30px is the magic margin used to hide the element's real scrollbars */
155
+ /* See overflow: hidden in .CodeMirror */
156
+ margin-bottom: -30px; margin-right: -30px;
157
+ padding-bottom: 30px;
158
+ height: 100%;
159
+ outline: none; /* Prevent dragging from highlighting the element */
160
+ position: relative;
161
+ }
162
+ .CodeMirror-sizer {
163
+ position: relative;
164
+ border-right: 30px solid transparent;
165
+ }
166
+
167
+ /* The fake, visible scrollbars. Used to force redraw during scrolling
168
+ before actual scrolling happens, thus preventing shaking and
169
+ flickering artifacts. */
170
+ .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
171
+ position: absolute;
172
+ z-index: 6;
173
+ display: none;
174
+ }
175
+ .CodeMirror-vscrollbar {
176
+ right: 0; top: 0;
177
+ overflow-x: hidden;
178
+ overflow-y: scroll;
179
+ }
180
+ .CodeMirror-hscrollbar {
181
+ bottom: 0; left: 0;
182
+ overflow-y: hidden;
183
+ overflow-x: scroll;
184
+ }
185
+ .CodeMirror-scrollbar-filler {
186
+ right: 0; bottom: 0;
187
+ }
188
+ .CodeMirror-gutter-filler {
189
+ left: 0; bottom: 0;
190
+ }
191
+
192
+ .CodeMirror-gutters {
193
+ position: absolute; left: 0; top: 0;
194
+ z-index: 3;
195
+ }
196
+ .CodeMirror-gutter {
197
+ white-space: normal;
198
+ height: 100%;
199
+ display: inline-block;
200
+ margin-bottom: -30px;
201
+ /* Hack to make IE7 behave */
202
+ *zoom:1;
203
+ *display:inline;
204
+ }
205
+ .CodeMirror-gutter-wrapper {
206
+ position: absolute;
207
+ z-index: 4;
208
+ background: none !important;
209
+ border: none !important;
210
+ }
211
+ .CodeMirror-gutter-background {
212
+ position: absolute;
213
+ top: 0; bottom: 0;
214
+ z-index: 4;
215
+ }
216
+ .CodeMirror-gutter-elt {
217
+ position: absolute;
218
+ cursor: default;
219
+ z-index: 4;
220
+ }
221
+ .CodeMirror-gutter-wrapper {
222
+ -webkit-user-select: none;
223
+ -moz-user-select: none;
224
+ user-select: none;
225
+ }
226
+
227
+ .CodeMirror-lines {
228
+ cursor: text;
229
+ min-height: 1px; /* prevents collapsing before first draw */
230
+ }
231
+ .CodeMirror pre {
232
+ /* Reset some styles that the rest of the page might have set */
233
+ -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
234
+ border-width: 0;
235
+ background: transparent;
236
+ font-family: inherit;
237
+ font-size: inherit;
238
+ margin: 0;
239
+ white-space: pre;
240
+ word-wrap: normal;
241
+ line-height: inherit;
242
+ color: inherit;
243
+ z-index: 2;
244
+ position: relative;
245
+ overflow: visible;
246
+ -webkit-tap-highlight-color: transparent;
247
+ }
248
+ .CodeMirror-wrap pre {
249
+ word-wrap: break-word;
250
+ white-space: pre-wrap;
251
+ word-break: normal;
252
+ }
253
+
254
+ .CodeMirror-linebackground {
255
+ position: absolute;
256
+ left: 0; right: 0; top: 0; bottom: 0;
257
+ z-index: 0;
258
+ }
259
+
260
+ .CodeMirror-linewidget {
261
+ position: relative;
262
+ z-index: 2;
263
+ overflow: auto;
264
+ }
265
+
266
+ .CodeMirror-widget {}
267
+
268
+ .CodeMirror-code {
269
+ outline: none;
270
+ }
271
+
272
+ /* Force content-box sizing for the elements where we expect it */
273
+ .CodeMirror-scroll,
274
+ .CodeMirror-sizer,
275
+ .CodeMirror-gutter,
276
+ .CodeMirror-gutters,
277
+ .CodeMirror-linenumber {
278
+ -moz-box-sizing: content-box;
279
+ box-sizing: content-box;
280
+ }
281
+
282
+ .CodeMirror-measure {
283
+ position: absolute;
284
+ width: 100%;
285
+ height: 0;
286
+ overflow: hidden;
287
+ visibility: hidden;
288
+ }
289
+
290
+ .CodeMirror-cursor { position: absolute; }
291
+ .CodeMirror-measure pre { position: static; }
292
+
293
+ div.CodeMirror-cursors {
294
+ visibility: hidden;
295
+ position: relative;
296
+ z-index: 3;
297
+ }
298
+ div.CodeMirror-dragcursors {
299
+ visibility: visible;
300
+ }
301
+
302
+ .CodeMirror-focused div.CodeMirror-cursors {
303
+ visibility: visible;
304
+ }
305
+
306
+ .CodeMirror-selected { background: #d9d9d9; }
307
+ .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
308
+ .CodeMirror-crosshair { cursor: crosshair; }
309
+ .CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
310
+ .CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
311
+
312
+ .cm-searching {
313
+ background: #ffa;
314
+ background: rgba(255, 255, 0, .4);
315
+ }
316
+
317
+ /* IE7 hack to prevent it from returning funny offsetTops on the spans */
318
+ .CodeMirror span { *vertical-align: text-bottom; }
319
+
320
+ /* Used to force a border model for a node */
321
+ .cm-force-border { padding-right: .1px; }
322
+
323
+ @media print {
324
+ /* Hide the cursor when printing */
325
+ .CodeMirror div.CodeMirror-cursors {
326
+ visibility: hidden;
327
+ }
328
+ }
329
+
330
+ /* See issue #2901 */
331
+ .cm-tab-wrap-hack:after { content: ''; }
332
+
333
+ /* Help users use markselection to safely style text background */
334
+ span.CodeMirror-selectedtext { background: none; }
vendor/kminh/bwp-framework/assets/vendor/codemirror/codemirror.js ADDED
@@ -0,0 +1,8887 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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(mod) {
11
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
12
+ module.exports = mod();
13
+ else if (typeof define == "function" && define.amd) // AMD
14
+ return define([], mod);
15
+ else // Plain browser env
16
+ (this || window).CodeMirror = mod();
17
+ })(function() {
18
+ "use strict";
19
+
20
+ // BROWSER SNIFFING
21
+
22
+ // Kludges for bugs and behavior differences that can't be feature
23
+ // detected are enabled based on userAgent etc sniffing.
24
+ var userAgent = navigator.userAgent;
25
+ var platform = navigator.platform;
26
+
27
+ var gecko = /gecko\/\d/i.test(userAgent);
28
+ var ie_upto10 = /MSIE \d/.test(userAgent);
29
+ var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent);
30
+ var ie = ie_upto10 || ie_11up;
31
+ var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]);
32
+ var webkit = /WebKit\//.test(userAgent);
33
+ var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent);
34
+ var chrome = /Chrome\//.test(userAgent);
35
+ var presto = /Opera\//.test(userAgent);
36
+ var safari = /Apple Computer/.test(navigator.vendor);
37
+ var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent);
38
+ var phantom = /PhantomJS/.test(userAgent);
39
+
40
+ var ios = /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent);
41
+ // This is woefully incomplete. Suggestions for alternative methods welcome.
42
+ var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent);
43
+ var mac = ios || /Mac/.test(platform);
44
+ var windows = /win/i.test(platform);
45
+
46
+ var presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/);
47
+ if (presto_version) presto_version = Number(presto_version[1]);
48
+ if (presto_version && presto_version >= 15) { presto = false; webkit = true; }
49
+ // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
50
+ var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11));
51
+ var captureRightClick = gecko || (ie && ie_version >= 9);
52
+
53
+ // Optimize some code when these features are not used.
54
+ var sawReadOnlySpans = false, sawCollapsedSpans = false;
55
+
56
+ // EDITOR CONSTRUCTOR
57
+
58
+ // A CodeMirror instance represents an editor. This is the object
59
+ // that user code is usually dealing with.
60
+
61
+ function CodeMirror(place, options) {
62
+ if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);
63
+
64
+ this.options = options = options ? copyObj(options) : {};
65
+ // Determine effective options based on given values and defaults.
66
+ copyObj(defaults, options, false);
67
+ setGuttersForLineNumbers(options);
68
+
69
+ var doc = options.value;
70
+ if (typeof doc == "string") doc = new Doc(doc, options.mode, null, options.lineSeparator);
71
+ this.doc = doc;
72
+
73
+ var input = new CodeMirror.inputStyles[options.inputStyle](this);
74
+ var display = this.display = new Display(place, doc, input);
75
+ display.wrapper.CodeMirror = this;
76
+ updateGutters(this);
77
+ themeChanged(this);
78
+ if (options.lineWrapping)
79
+ this.display.wrapper.className += " CodeMirror-wrap";
80
+ if (options.autofocus && !mobile) display.input.focus();
81
+ initScrollbars(this);
82
+
83
+ this.state = {
84
+ keyMaps: [], // stores maps added by addKeyMap
85
+ overlays: [], // highlighting overlays, as added by addOverlay
86
+ modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info
87
+ overwrite: false,
88
+ delayingBlurEvent: false,
89
+ focused: false,
90
+ suppressEdits: false, // used to disable editing during key handlers when in readOnly mode
91
+ pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll
92
+ selectingText: false,
93
+ draggingText: false,
94
+ highlight: new Delayed(), // stores highlight worker timeout
95
+ keySeq: null, // Unfinished key sequence
96
+ specialChars: null
97
+ };
98
+
99
+ var cm = this;
100
+
101
+ // Override magic textarea content restore that IE sometimes does
102
+ // on our hidden textarea on reload
103
+ if (ie && ie_version < 11) setTimeout(function() { cm.display.input.reset(true); }, 20);
104
+
105
+ registerEventHandlers(this);
106
+ ensureGlobalHandlers();
107
+
108
+ startOperation(this);
109
+ this.curOp.forceUpdate = true;
110
+ attachDoc(this, doc);
111
+
112
+ if ((options.autofocus && !mobile) || cm.hasFocus())
113
+ setTimeout(bind(onFocus, this), 20);
114
+ else
115
+ onBlur(this);
116
+
117
+ for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt))
118
+ optionHandlers[opt](this, options[opt], Init);
119
+ maybeUpdateLineNumberWidth(this);
120
+ if (options.finishInit) options.finishInit(this);
121
+ for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);
122
+ endOperation(this);
123
+ // Suppress optimizelegibility in Webkit, since it breaks text
124
+ // measuring on line wrapping boundaries.
125
+ if (webkit && options.lineWrapping &&
126
+ getComputedStyle(display.lineDiv).textRendering == "optimizelegibility")
127
+ display.lineDiv.style.textRendering = "auto";
128
+ }
129
+
130
+ // DISPLAY CONSTRUCTOR
131
+
132
+ // The display handles the DOM integration, both for input reading
133
+ // and content drawing. It holds references to DOM nodes and
134
+ // display-related state.
135
+
136
+ function Display(place, doc, input) {
137
+ var d = this;
138
+ this.input = input;
139
+
140
+ // Covers bottom-right square when both scrollbars are present.
141
+ d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
142
+ d.scrollbarFiller.setAttribute("cm-not-content", "true");
143
+ // Covers bottom of gutter when coverGutterNextToScrollbar is on
144
+ // and h scrollbar is present.
145
+ d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
146
+ d.gutterFiller.setAttribute("cm-not-content", "true");
147
+ // Will contain the actual code, positioned to cover the viewport.
148
+ d.lineDiv = elt("div", null, "CodeMirror-code");
149
+ // Elements are added to these to represent selection and cursors.
150
+ d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
151
+ d.cursorDiv = elt("div", null, "CodeMirror-cursors");
152
+ // A visibility: hidden element used to find the size of things.
153
+ d.measure = elt("div", null, "CodeMirror-measure");
154
+ // When lines outside of the viewport are measured, they are drawn in this.
155
+ d.lineMeasure = elt("div", null, "CodeMirror-measure");
156
+ // Wraps everything that needs to exist inside the vertically-padded coordinate system
157
+ d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],
158
+ null, "position: relative; outline: none");
159
+ // Moved around its parent to cover visible view.
160
+ d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative");
161
+ // Set to the height of the document, allowing scrolling.
162
+ d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
163
+ d.sizerWidth = null;
164
+ // Behavior of elts with overflow: auto and padding is
165
+ // inconsistent across browsers. This is used to ensure the
166
+ // scrollable area is big enough.
167
+ d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;");
168
+ // Will contain the gutters, if any.
169
+ d.gutters = elt("div", null, "CodeMirror-gutters");
170
+ d.lineGutter = null;
171
+ // Actual scrollable element.
172
+ d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
173
+ d.scroller.setAttribute("tabIndex", "-1");
174
+ // The element in which the editor lives.
175
+ d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
176
+
177
+ // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)
178
+ if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
179
+ if (!webkit && !(gecko && mobile)) d.scroller.draggable = true;
180
+
181
+ if (place) {
182
+ if (place.appendChild) place.appendChild(d.wrapper);
183
+ else place(d.wrapper);
184
+ }
185
+
186
+ // Current rendered range (may be bigger than the view window).
187
+ d.viewFrom = d.viewTo = doc.first;
188
+ d.reportedViewFrom = d.reportedViewTo = doc.first;
189
+ // Information about the rendered lines.
190
+ d.view = [];
191
+ d.renderedView = null;
192
+ // Holds info about a single rendered line when it was rendered
193
+ // for measurement, while not in view.
194
+ d.externalMeasured = null;
195
+ // Empty space (in pixels) above the view
196
+ d.viewOffset = 0;
197
+ d.lastWrapHeight = d.lastWrapWidth = 0;
198
+ d.updateLineNumbers = null;
199
+
200
+ d.nativeBarWidth = d.barHeight = d.barWidth = 0;
201
+ d.scrollbarsClipped = false;
202
+
203
+ // Used to only resize the line number gutter when necessary (when
204
+ // the amount of lines crosses a boundary that makes its width change)
205
+ d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
206
+ // Set to true when a non-horizontal-scrolling line widget is
207
+ // added. As an optimization, line widget aligning is skipped when
208
+ // this is false.
209
+ d.alignWidgets = false;
210
+
211
+ d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
212
+
213
+ // Tracks the maximum line length so that the horizontal scrollbar
214
+ // can be kept static when scrolling.
215
+ d.maxLine = null;
216
+ d.maxLineLength = 0;
217
+ d.maxLineChanged = false;
218
+
219
+ // Used for measuring wheel scrolling granularity
220
+ d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
221
+
222
+ // True when shift is held down.
223
+ d.shift = false;
224
+
225
+ // Used to track whether anything happened since the context menu
226
+ // was opened.
227
+ d.selForContextMenu = null;
228
+
229
+ d.activeTouch = null;
230
+
231
+ input.init(d);
232
+ }
233
+
234
+ // STATE UPDATES
235
+
236
+ // Used to get the editor into a consistent state again when options change.
237
+
238
+ function loadMode(cm) {
239
+ cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption);
240
+ resetModeState(cm);
241
+ }
242
+
243
+ function resetModeState(cm) {
244
+ cm.doc.iter(function(line) {
245
+ if (line.stateAfter) line.stateAfter = null;
246
+ if (line.styles) line.styles = null;
247
+ });
248
+ cm.doc.frontier = cm.doc.first;
249
+ startWorker(cm, 100);
250
+ cm.state.modeGen++;
251
+ if (cm.curOp) regChange(cm);
252
+ }
253
+
254
+ function wrappingChanged(cm) {
255
+ if (cm.options.lineWrapping) {
256
+ addClass(cm.display.wrapper, "CodeMirror-wrap");
257
+ cm.display.sizer.style.minWidth = "";
258
+ cm.display.sizerWidth = null;
259
+ } else {
260
+ rmClass(cm.display.wrapper, "CodeMirror-wrap");
261
+ findMaxLine(cm);
262
+ }
263
+ estimateLineHeights(cm);
264
+ regChange(cm);
265
+ clearCaches(cm);
266
+ setTimeout(function(){updateScrollbars(cm);}, 100);
267
+ }
268
+
269
+ // Returns a function that estimates the height of a line, to use as
270
+ // first approximation until the line becomes visible (and is thus
271
+ // properly measurable).
272
+ function estimateHeight(cm) {
273
+ var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
274
+ var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
275
+ return function(line) {
276
+ if (lineIsHidden(cm.doc, line)) return 0;
277
+
278
+ var widgetsHeight = 0;
279
+ if (line.widgets) for (var i = 0; i < line.widgets.length; i++) {
280
+ if (line.widgets[i].height) widgetsHeight += line.widgets[i].height;
281
+ }
282
+
283
+ if (wrapping)
284
+ return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th;
285
+ else
286
+ return widgetsHeight + th;
287
+ };
288
+ }
289
+
290
+ function estimateLineHeights(cm) {
291
+ var doc = cm.doc, est = estimateHeight(cm);
292
+ doc.iter(function(line) {
293
+ var estHeight = est(line);
294
+ if (estHeight != line.height) updateLineHeight(line, estHeight);
295
+ });
296
+ }
297
+
298
+ function themeChanged(cm) {
299
+ cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
300
+ cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
301
+ clearCaches(cm);
302
+ }
303
+
304
+ function guttersChanged(cm) {
305
+ updateGutters(cm);
306
+ regChange(cm);
307
+ setTimeout(function(){alignHorizontally(cm);}, 20);
308
+ }
309
+
310
+ // Rebuild the gutter elements, ensure the margin to the left of the
311
+ // code matches their width.
312
+ function updateGutters(cm) {
313
+ var gutters = cm.display.gutters, specs = cm.options.gutters;
314
+ removeChildren(gutters);
315
+ for (var i = 0; i < specs.length; ++i) {
316
+ var gutterClass = specs[i];
317
+ var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
318
+ if (gutterClass == "CodeMirror-linenumbers") {
319
+ cm.display.lineGutter = gElt;
320
+ gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
321
+ }
322
+ }
323
+ gutters.style.display = i ? "" : "none";
324
+ updateGutterSpace(cm);
325
+ }
326
+
327
+ function updateGutterSpace(cm) {
328
+ var width = cm.display.gutters.offsetWidth;
329
+ cm.display.sizer.style.marginLeft = width + "px";
330
+ }
331
+
332
+ // Compute the character length of a line, taking into account
333
+ // collapsed ranges (see markText) that might hide parts, and join
334
+ // other lines onto it.
335
+ function lineLength(line) {
336
+ if (line.height == 0) return 0;
337
+ var len = line.text.length, merged, cur = line;
338
+ while (merged = collapsedSpanAtStart(cur)) {
339
+ var found = merged.find(0, true);
340
+ cur = found.from.line;
341
+ len += found.from.ch - found.to.ch;
342
+ }
343
+ cur = line;
344
+ while (merged = collapsedSpanAtEnd(cur)) {
345
+ var found = merged.find(0, true);
346
+ len -= cur.text.length - found.from.ch;
347
+ cur = found.to.line;
348
+ len += cur.text.length - found.to.ch;
349
+ }
350
+ return len;
351
+ }
352
+
353
+ // Find the longest line in the document.
354
+ function findMaxLine(cm) {
355
+ var d = cm.display, doc = cm.doc;
356
+ d.maxLine = getLine(doc, doc.first);
357
+ d.maxLineLength = lineLength(d.maxLine);
358
+ d.maxLineChanged = true;
359
+ doc.iter(function(line) {
360
+ var len = lineLength(line);
361
+ if (len > d.maxLineLength) {
362
+ d.maxLineLength = len;
363
+ d.maxLine = line;
364
+ }
365
+ });
366
+ }
367
+
368
+ // Make sure the gutters options contains the element
369
+ // "CodeMirror-linenumbers" when the lineNumbers option is true.
370
+ function setGuttersForLineNumbers(options) {
371
+ var found = indexOf(options.gutters, "CodeMirror-linenumbers");
372
+ if (found == -1 && options.lineNumbers) {
373
+ options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]);
374
+ } else if (found > -1 && !options.lineNumbers) {
375
+ options.gutters = options.gutters.slice(0);
376
+ options.gutters.splice(found, 1);
377
+ }
378
+ }
379
+
380
+ // SCROLLBARS
381
+
382
+ // Prepare DOM reads needed to update the scrollbars. Done in one
383
+ // shot to minimize update/measure roundtrips.
384
+ function measureForScrollbars(cm) {
385
+ var d = cm.display, gutterW = d.gutters.offsetWidth;
386
+ var docH = Math.round(cm.doc.height + paddingVert(cm.display));
387
+ return {
388
+ clientHeight: d.scroller.clientHeight,
389
+ viewHeight: d.wrapper.clientHeight,
390
+ scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth,
391
+ viewWidth: d.wrapper.clientWidth,
392
+ barLeft: cm.options.fixedGutter ? gutterW : 0,
393
+ docHeight: docH,
394
+ scrollHeight: docH + scrollGap(cm) + d.barHeight,
395
+ nativeBarWidth: d.nativeBarWidth,
396
+ gutterWidth: gutterW
397
+ };
398
+ }
399
+
400
+ function NativeScrollbars(place, scroll, cm) {
401
+ this.cm = cm;
402
+ var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar");
403
+ var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar");
404
+ place(vert); place(horiz);
405
+
406
+ on(vert, "scroll", function() {
407
+ if (vert.clientHeight) scroll(vert.scrollTop, "vertical");
408
+ });
409
+ on(horiz, "scroll", function() {
410
+ if (horiz.clientWidth) scroll(horiz.scrollLeft, "horizontal");
411
+ });
412
+
413
+ this.checkedZeroWidth = false;
414
+ // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
415
+ if (ie && ie_version < 8) this.horiz.style.minHeight = this.vert.style.minWidth = "18px";
416
+ }
417
+
418
+ NativeScrollbars.prototype = copyObj({
419
+ update: function(measure) {
420
+ var needsH = measure.scrollWidth > measure.clientWidth + 1;
421
+ var needsV = measure.scrollHeight > measure.clientHeight + 1;
422
+ var sWidth = measure.nativeBarWidth;
423
+
424
+ if (needsV) {
425
+ this.vert.style.display = "block";
426
+ this.vert.style.bottom = needsH ? sWidth + "px" : "0";
427
+ var totalHeight = measure.viewHeight - (needsH ? sWidth : 0);
428
+ // A bug in IE8 can cause this value to be negative, so guard it.
429
+ this.vert.firstChild.style.height =
430
+ Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px";
431
+ } else {
432
+ this.vert.style.display = "";
433
+ this.vert.firstChild.style.height = "0";
434
+ }
435
+
436
+ if (needsH) {
437
+ this.horiz.style.display = "block";
438
+ this.horiz.style.right = needsV ? sWidth + "px" : "0";
439
+ this.horiz.style.left = measure.barLeft + "px";
440
+ var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0);
441
+ this.horiz.firstChild.style.width =
442
+ (measure.scrollWidth - measure.clientWidth + totalWidth) + "px";
443
+ } else {
444
+ this.horiz.style.display = "";
445
+ this.horiz.firstChild.style.width = "0";
446
+ }
447
+
448
+ if (!this.checkedZeroWidth && measure.clientHeight > 0) {
449
+ if (sWidth == 0) this.zeroWidthHack();
450
+ this.checkedZeroWidth = true;
451
+ }
452
+
453
+ return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0};
454
+ },
455
+ setScrollLeft: function(pos) {
456
+ if (this.horiz.scrollLeft != pos) this.horiz.scrollLeft = pos;
457
+ if (this.disableHoriz) this.enableZeroWidthBar(this.horiz, this.disableHoriz);
458
+ },
459
+ setScrollTop: function(pos) {
460
+ if (this.vert.scrollTop != pos) this.vert.scrollTop = pos;
461
+ if (this.disableVert) this.enableZeroWidthBar(this.vert, this.disableVert);
462
+ },
463
+ zeroWidthHack: function() {
464
+ var w = mac && !mac_geMountainLion ? "12px" : "18px";
465
+ this.horiz.style.height = this.vert.style.width = w;
466
+ this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none";
467
+ this.disableHoriz = new Delayed;
468
+ this.disableVert = new Delayed;
469
+ },
470
+ enableZeroWidthBar: function(bar, delay) {
471
+ bar.style.pointerEvents = "auto";
472
+ function maybeDisable() {
473
+ // To find out whether the scrollbar is still visible, we
474
+ // check whether the element under the pixel in the bottom
475
+ // left corner of the scrollbar box is the scrollbar box
476
+ // itself (when the bar is still visible) or its filler child
477
+ // (when the bar is hidden). If it is still visible, we keep
478
+ // it enabled, if it's hidden, we disable pointer events.
479
+ var box = bar.getBoundingClientRect();
480
+ var elt = document.elementFromPoint(box.left + 1, box.bottom - 1);
481
+ if (elt != bar) bar.style.pointerEvents = "none";
482
+ else delay.set(1000, maybeDisable);
483
+ }
484
+ delay.set(1000, maybeDisable);
485
+ },
486
+ clear: function() {
487
+ var parent = this.horiz.parentNode;
488
+ parent.removeChild(this.horiz);
489
+ parent.removeChild(this.vert);
490
+ }
491
+ }, NativeScrollbars.prototype);
492
+
493
+ function NullScrollbars() {}
494
+
495
+ NullScrollbars.prototype = copyObj({
496
+ update: function() { return {bottom: 0, right: 0}; },
497
+ setScrollLeft: function() {},
498
+ setScrollTop: function() {},
499
+ clear: function() {}
500
+ }, NullScrollbars.prototype);
501
+
502
+ CodeMirror.scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars};
503
+
504
+ function initScrollbars(cm) {
505
+ if (cm.display.scrollbars) {
506
+ cm.display.scrollbars.clear();
507
+ if (cm.display.scrollbars.addClass)
508
+ rmClass(cm.display.wrapper, cm.display.scrollbars.addClass);
509
+ }
510
+
511
+ cm.display.scrollbars = new CodeMirror.scrollbarModel[cm.options.scrollbarStyle](function(node) {
512
+ cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller);
513
+ // Prevent clicks in the scrollbars from killing focus
514
+ on(node, "mousedown", function() {
515
+ if (cm.state.focused) setTimeout(function() { cm.display.input.focus(); }, 0);
516
+ });
517
+ node.setAttribute("cm-not-content", "true");
518
+ }, function(pos, axis) {
519
+ if (axis == "horizontal") setScrollLeft(cm, pos);
520
+ else setScrollTop(cm, pos);
521
+ }, cm);
522
+ if (cm.display.scrollbars.addClass)
523
+ addClass(cm.display.wrapper, cm.display.scrollbars.addClass);
524
+ }
525
+
526
+ function updateScrollbars(cm, measure) {
527
+ if (!measure) measure = measureForScrollbars(cm);
528
+ var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight;
529
+ updateScrollbarsInner(cm, measure);
530
+ for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) {
531
+ if (startWidth != cm.display.barWidth && cm.options.lineWrapping)
532
+ updateHeightsInViewport(cm);
533
+ updateScrollbarsInner(cm, measureForScrollbars(cm));
534
+ startWidth = cm.display.barWidth; startHeight = cm.display.barHeight;
535
+ }
536
+ }
537
+
538
+ // Re-synchronize the fake scrollbars with the actual size of the
539
+ // content.
540
+ function updateScrollbarsInner(cm, measure) {
541
+ var d = cm.display;
542
+ var sizes = d.scrollbars.update(measure);
543
+
544
+ d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px";
545
+ d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px";
546
+
547
+ if (sizes.right && sizes.bottom) {
548
+ d.scrollbarFiller.style.display = "block";
549
+ d.scrollbarFiller.style.height = sizes.bottom + "px";
550
+ d.scrollbarFiller.style.width = sizes.right + "px";
551
+ } else d.scrollbarFiller.style.display = "";
552
+ if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
553
+ d.gutterFiller.style.display = "block";
554
+ d.gutterFiller.style.height = sizes.bottom + "px";
555
+ d.gutterFiller.style.width = measure.gutterWidth + "px";
556
+ } else d.gutterFiller.style.display = "";
557
+ }
558
+
559
+ // Compute the lines that are visible in a given viewport (defaults
560
+ // the the current scroll position). viewport may contain top,
561
+ // height, and ensure (see op.scrollToPos) properties.
562
+ function visibleLines(display, doc, viewport) {
563
+ var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop;
564
+ top = Math.floor(top - paddingTop(display));
565
+ var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight;
566
+
567
+ var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom);
568
+ // Ensure is a {from: {line, ch}, to: {line, ch}} object, and
569
+ // forces those lines into the viewport (if possible).
570
+ if (viewport && viewport.ensure) {
571
+ var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line;
572
+ if (ensureFrom < from) {
573
+ from = ensureFrom;
574
+ to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight);
575
+ } else if (Math.min(ensureTo, doc.lastLine()) >= to) {
576
+ from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight);
577
+ to = ensureTo;
578
+ }
579
+ }
580
+ return {from: from, to: Math.max(to, from + 1)};
581
+ }
582
+
583
+ // LINE NUMBERS
584
+
585
+ // Re-align line numbers and gutter marks to compensate for
586
+ // horizontal scrolling.
587
+ function alignHorizontally(cm) {
588
+ var display = cm.display, view = display.view;
589
+ if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return;
590
+ var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
591
+ var gutterW = display.gutters.offsetWidth, left = comp + "px";
592
+ for (var i = 0; i < view.length; i++) if (!view[i].hidden) {
593
+ if (cm.options.fixedGutter && view[i].gutter)
594
+ view[i].gutter.style.left = left;
595
+ var align = view[i].alignable;
596
+ if (align) for (var j = 0; j < align.length; j++)
597
+ align[j].style.left = left;
598
+ }
599
+ if (cm.options.fixedGutter)
600
+ display.gutters.style.left = (comp + gutterW) + "px";
601
+ }
602
+
603
+ // Used to ensure that the line number gutter is still the right
604
+ // size for the current document size. Returns true when an update
605
+ // is needed.
606
+ function maybeUpdateLineNumberWidth(cm) {
607
+ if (!cm.options.lineNumbers) return false;
608
+ var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
609
+ if (last.length != display.lineNumChars) {
610
+ var test = display.measure.appendChild(elt("div", [elt("div", last)],
611
+ "CodeMirror-linenumber CodeMirror-gutter-elt"));
612
+ var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
613
+ display.lineGutter.style.width = "";
614
+ display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1;
615
+ display.lineNumWidth = display.lineNumInnerWidth + padding;
616
+ display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
617
+ display.lineGutter.style.width = display.lineNumWidth + "px";
618
+ updateGutterSpace(cm);
619
+ return true;
620
+ }
621
+ return false;
622
+ }
623
+
624
+ function lineNumberFor(options, i) {
625
+ return String(options.lineNumberFormatter(i + options.firstLineNumber));
626
+ }
627
+
628
+ // Computes display.scroller.scrollLeft + display.gutters.offsetWidth,
629
+ // but using getBoundingClientRect to get a sub-pixel-accurate
630
+ // result.
631
+ function compensateForHScroll(display) {
632
+ return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left;
633
+ }
634
+
635
+ // DISPLAY DRAWING
636
+
637
+ function DisplayUpdate(cm, viewport, force) {
638
+ var display = cm.display;
639
+
640
+ this.viewport = viewport;
641
+ // Store some values that we'll need later (but don't want to force a relayout for)
642
+ this.visible = visibleLines(display, cm.doc, viewport);
643
+ this.editorIsHidden = !display.wrapper.offsetWidth;
644
+ this.wrapperHeight = display.wrapper.clientHeight;
645
+ this.wrapperWidth = display.wrapper.clientWidth;
646
+ this.oldDisplayWidth = displayWidth(cm);
647
+ this.force = force;
648
+ this.dims = getDimensions(cm);
649
+ this.events = [];
650
+ }
651
+
652
+ DisplayUpdate.prototype.signal = function(emitter, type) {
653
+ if (hasHandler(emitter, type))
654
+ this.events.push(arguments);
655
+ };
656
+ DisplayUpdate.prototype.finish = function() {
657
+ for (var i = 0; i < this.events.length; i++)
658
+ signal.apply(null, this.events[i]);
659
+ };
660
+
661
+ function maybeClipScrollbars(cm) {
662
+ var display = cm.display;
663
+ if (!display.scrollbarsClipped && display.scroller.offsetWidth) {
664
+ display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth;
665
+ display.heightForcer.style.height = scrollGap(cm) + "px";
666
+ display.sizer.style.marginBottom = -display.nativeBarWidth + "px";
667
+ display.sizer.style.borderRightWidth = scrollGap(cm) + "px";
668
+ display.scrollbarsClipped = true;
669
+ }
670
+ }
671
+
672
+ // Does the actual updating of the line display. Bails out
673
+ // (returning false) when there is nothing to be done and forced is
674
+ // false.
675
+ function updateDisplayIfNeeded(cm, update) {
676
+ var display = cm.display, doc = cm.doc;
677
+
678
+ if (update.editorIsHidden) {
679
+ resetView(cm);
680
+ return false;
681
+ }
682
+
683
+ // Bail out if the visible area is already rendered and nothing changed.
684
+ if (!update.force &&
685
+ update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo &&
686
+ (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) &&
687
+ display.renderedView == display.view && countDirtyView(cm) == 0)
688
+ return false;
689
+
690
+ if (maybeUpdateLineNumberWidth(cm)) {
691
+ resetView(cm);
692
+ update.dims = getDimensions(cm);
693
+ }
694
+
695
+ // Compute a suitable new viewport (from & to)
696
+ var end = doc.first + doc.size;
697
+ var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first);
698
+ var to = Math.min(end, update.visible.to + cm.options.viewportMargin);
699
+ if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom);
700
+ if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo);
701
+ if (sawCollapsedSpans) {
702
+ from = visualLineNo(cm.doc, from);
703
+ to = visualLineEndNo(cm.doc, to);
704
+ }
705
+
706
+ var different = from != display.viewFrom || to != display.viewTo ||
707
+ display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth;
708
+ adjustView(cm, from, to);
709
+
710
+ display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom));
711
+ // Position the mover div to align with the current scroll position
712
+ cm.display.mover.style.top = display.viewOffset + "px";
713
+
714
+ var toUpdate = countDirtyView(cm);
715
+ if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view &&
716
+ (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo))
717
+ return false;
718
+
719
+ // For big changes, we hide the enclosing element during the
720
+ // update, since that speeds up the operations on most browsers.
721
+ var focused = activeElt();
722
+ if (toUpdate > 4) display.lineDiv.style.display = "none";
723
+ patchDisplay(cm, display.updateLineNumbers, update.dims);
724
+ if (toUpdate > 4) display.lineDiv.style.display = "";
725
+ display.renderedView = display.view;
726
+ // There might have been a widget with a focused element that got
727
+ // hidden or updated, if so re-focus it.
728
+ if (focused && activeElt() != focused && focused.offsetHeight) focused.focus();
729
+
730
+ // Prevent selection and cursors from interfering with the scroll
731
+ // width and height.
732
+ removeChildren(display.cursorDiv);
733
+ removeChildren(display.selectionDiv);
734
+ display.gutters.style.height = display.sizer.style.minHeight = 0;
735
+
736
+ if (different) {
737
+ display.lastWrapHeight = update.wrapperHeight;
738
+ display.lastWrapWidth = update.wrapperWidth;
739
+ startWorker(cm, 400);
740
+ }
741
+
742
+ display.updateLineNumbers = null;
743
+
744
+ return true;
745
+ }
746
+
747
+ function postUpdateDisplay(cm, update) {
748
+ var viewport = update.viewport;
749
+ for (var first = true;; first = false) {
750
+ if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) {
751
+ // Clip forced viewport to actual scrollable area.
752
+ if (viewport && viewport.top != null)
753
+ viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)};
754
+ // Updated line heights might result in the drawn area not
755
+ // actually covering the viewport. Keep looping until it does.
756
+ update.visible = visibleLines(cm.display, cm.doc, viewport);
757
+ if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)
758
+ break;
759
+ }
760
+ if (!updateDisplayIfNeeded(cm, update)) break;
761
+ updateHeightsInViewport(cm);
762
+ var barMeasure = measureForScrollbars(cm);
763
+ updateSelection(cm);
764
+ setDocumentHeight(cm, barMeasure);
765
+ updateScrollbars(cm, barMeasure);
766
+ }
767
+
768
+ update.signal(cm, "update", cm);
769
+ if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) {
770
+ update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo);
771
+ cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo;
772
+ }
773
+ }
774
+
775
+ function updateDisplaySimple(cm, viewport) {
776
+ var update = new DisplayUpdate(cm, viewport);
777
+ if (updateDisplayIfNeeded(cm, update)) {
778
+ updateHeightsInViewport(cm);
779
+ postUpdateDisplay(cm, update);
780
+ var barMeasure = measureForScrollbars(cm);
781
+ updateSelection(cm);
782
+ setDocumentHeight(cm, barMeasure);
783
+ updateScrollbars(cm, barMeasure);
784
+ update.finish();
785
+ }
786
+ }
787
+
788
+ function setDocumentHeight(cm, measure) {
789
+ cm.display.sizer.style.minHeight = measure.docHeight + "px";
790
+ var total = measure.docHeight + cm.display.barHeight;
791
+ cm.display.heightForcer.style.top = total + "px";
792
+ cm.display.gutters.style.height = Math.max(total + scrollGap(cm), measure.clientHeight) + "px";
793
+ }
794
+
795
+ // Read the actual heights of the rendered lines, and update their
796
+ // stored heights to match.
797
+ function updateHeightsInViewport(cm) {
798
+ var display = cm.display;
799
+ var prevBottom = display.lineDiv.offsetTop;
800
+ for (var i = 0; i < display.view.length; i++) {
801
+ var cur = display.view[i], height;
802
+ if (cur.hidden) continue;
803
+ if (ie && ie_version < 8) {
804
+ var bot = cur.node.offsetTop + cur.node.offsetHeight;
805
+ height = bot - prevBottom;
806
+ prevBottom = bot;
807
+ } else {
808
+ var box = cur.node.getBoundingClientRect();
809
+ height = box.bottom - box.top;
810
+ }
811
+ var diff = cur.line.height - height;
812
+ if (height < 2) height = textHeight(display);
813
+ if (diff > .001 || diff < -.001) {
814
+ updateLineHeight(cur.line, height);
815
+ updateWidgetHeight(cur.line);
816
+ if (cur.rest) for (var j = 0; j < cur.rest.length; j++)
817
+ updateWidgetHeight(cur.rest[j]);
818
+ }
819
+ }
820
+ }
821
+
822
+ // Read and store the height of line widgets associated with the
823
+ // given line.
824
+ function updateWidgetHeight(line) {
825
+ if (line.widgets) for (var i = 0; i < line.widgets.length; ++i)
826
+ line.widgets[i].height = line.widgets[i].node.parentNode.offsetHeight;
827
+ }
828
+
829
+ // Do a bulk-read of the DOM positions and sizes needed to draw the
830
+ // view, so that we don't interleave reading and writing to the DOM.
831
+ function getDimensions(cm) {
832
+ var d = cm.display, left = {}, width = {};
833
+ var gutterLeft = d.gutters.clientLeft;
834
+ for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
835
+ left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft;
836
+ width[cm.options.gutters[i]] = n.clientWidth;
837
+ }
838
+ return {fixedPos: compensateForHScroll(d),
839
+ gutterTotalWidth: d.gutters.offsetWidth,
840
+ gutterLeft: left,
841
+ gutterWidth: width,
842
+ wrapperWidth: d.wrapper.clientWidth};
843
+ }
844
+
845
+ // Sync the actual display DOM structure with display.view, removing
846
+ // nodes for lines that are no longer in view, and creating the ones
847
+ // that are not there yet, and updating the ones that are out of
848
+ // date.
849
+ function patchDisplay(cm, updateNumbersFrom, dims) {
850
+ var display = cm.display, lineNumbers = cm.options.lineNumbers;
851
+ var container = display.lineDiv, cur = container.firstChild;
852
+
853
+ function rm(node) {
854
+ var next = node.nextSibling;
855
+ // Works around a throw-scroll bug in OS X Webkit
856
+ if (webkit && mac && cm.display.currentWheelTarget == node)
857
+ node.style.display = "none";
858
+ else
859
+ node.parentNode.removeChild(node);
860
+ return next;
861
+ }
862
+
863
+ var view = display.view, lineN = display.viewFrom;
864
+ // Loop over the elements in the view, syncing cur (the DOM nodes
865
+ // in display.lineDiv) with the view as we go.
866
+ for (var i = 0; i < view.length; i++) {
867
+ var lineView = view[i];
868
+ if (lineView.hidden) {
869
+ } else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet
870
+ var node = buildLineElement(cm, lineView, lineN, dims);
871
+ container.insertBefore(node, cur);
872
+ } else { // Already drawn
873
+ while (cur != lineView.node) cur = rm(cur);
874
+ var updateNumber = lineNumbers && updateNumbersFrom != null &&
875
+ updateNumbersFrom <= lineN && lineView.lineNumber;
876
+ if (lineView.changes) {
877
+ if (indexOf(lineView.changes, "gutter") > -1) updateNumber = false;
878
+ updateLineForChanges(cm, lineView, lineN, dims);
879
+ }
880
+ if (updateNumber) {
881
+ removeChildren(lineView.lineNumber);
882
+ lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN)));
883
+ }
884
+ cur = lineView.node.nextSibling;
885
+ }
886
+ lineN += lineView.size;
887
+ }
888
+ while (cur) cur = rm(cur);
889
+ }
890
+
891
+ // When an aspect of a line changes, a string is added to
892
+ // lineView.changes. This updates the relevant part of the line's
893
+ // DOM structure.
894
+ function updateLineForChanges(cm, lineView, lineN, dims) {
895
+ for (var j = 0; j < lineView.changes.length; j++) {
896
+ var type = lineView.changes[j];
897
+ if (type == "text") updateLineText(cm, lineView);
898
+ else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims);
899
+ else if (type == "class") updateLineClasses(lineView);
900
+ else if (type == "widget") updateLineWidgets(cm, lineView, dims);
901
+ }
902
+ lineView.changes = null;
903
+ }
904
+
905
+ // Lines with gutter elements, widgets or a background class need to
906
+ // be wrapped, and have the extra elements added to the wrapper div
907
+ function ensureLineWrapped(lineView) {
908
+ if (lineView.node == lineView.text) {
909
+ lineView.node = elt("div", null, null, "position: relative");
910
+ if (lineView.text.parentNode)
911
+ lineView.text.parentNode.replaceChild(lineView.node, lineView.text);
912
+ lineView.node.appendChild(lineView.text);
913
+ if (ie && ie_version < 8) lineView.node.style.zIndex = 2;
914
+ }
915
+ return lineView.node;
916
+ }
917
+
918
+ function updateLineBackground(lineView) {
919
+ var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass;
920
+ if (cls) cls += " CodeMirror-linebackground";
921
+ if (lineView.background) {
922
+ if (cls) lineView.background.className = cls;
923
+ else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; }
924
+ } else if (cls) {
925
+ var wrap = ensureLineWrapped(lineView);
926
+ lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild);
927
+ }
928
+ }
929
+
930
+ // Wrapper around buildLineContent which will reuse the structure
931
+ // in display.externalMeasured when possible.
932
+ function getLineContent(cm, lineView) {
933
+ var ext = cm.display.externalMeasured;
934
+ if (ext && ext.line == lineView.line) {
935
+ cm.display.externalMeasured = null;
936
+ lineView.measure = ext.measure;
937
+ return ext.built;
938
+ }
939
+ return buildLineContent(cm, lineView);
940
+ }
941
+
942
+ // Redraw the line's text. Interacts with the background and text
943
+ // classes because the mode may output tokens that influence these
944
+ // classes.
945
+ function updateLineText(cm, lineView) {
946
+ var cls = lineView.text.className;
947
+ var built = getLineContent(cm, lineView);
948
+ if (lineView.text == lineView.node) lineView.node = built.pre;
949
+ lineView.text.parentNode.replaceChild(built.pre, lineView.text);
950
+ lineView.text = built.pre;
951
+ if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) {
952
+ lineView.bgClass = built.bgClass;
953
+ lineView.textClass = built.textClass;
954
+ updateLineClasses(lineView);
955
+ } else if (cls) {
956
+ lineView.text.className = cls;
957
+ }
958
+ }
959
+
960
+ function updateLineClasses(lineView) {
961
+ updateLineBackground(lineView);
962
+ if (lineView.line.wrapClass)
963
+ ensureLineWrapped(lineView).className = lineView.line.wrapClass;
964
+ else if (lineView.node != lineView.text)
965
+ lineView.node.className = "";
966
+ var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass;
967
+ lineView.text.className = textClass || "";
968
+ }
969
+
970
+ function updateLineGutter(cm, lineView, lineN, dims) {
971
+ if (lineView.gutter) {
972
+ lineView.node.removeChild(lineView.gutter);
973
+ lineView.gutter = null;
974
+ }
975
+ if (lineView.gutterBackground) {
976
+ lineView.node.removeChild(lineView.gutterBackground);
977
+ lineView.gutterBackground = null;
978
+ }
979
+ if (lineView.line.gutterClass) {
980
+ var wrap = ensureLineWrapped(lineView);
981
+ lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass,
982
+ "left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) +
983
+ "px; width: " + dims.gutterTotalWidth + "px");
984
+ wrap.insertBefore(lineView.gutterBackground, lineView.text);
985
+ }
986
+ var markers = lineView.line.gutterMarkers;
987
+ if (cm.options.lineNumbers || markers) {
988
+ var wrap = ensureLineWrapped(lineView);
989
+ var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", "left: " +
990
+ (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px");
991
+ cm.display.input.setUneditable(gutterWrap);
992
+ wrap.insertBefore(gutterWrap, lineView.text);
993
+ if (lineView.line.gutterClass)
994
+ gutterWrap.className += " " + lineView.line.gutterClass;
995
+ if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
996
+ lineView.lineNumber = gutterWrap.appendChild(
997
+ elt("div", lineNumberFor(cm.options, lineN),
998
+ "CodeMirror-linenumber CodeMirror-gutter-elt",
999
+ "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: "
1000
+ + cm.display.lineNumInnerWidth + "px"));
1001
+ if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) {
1002
+ var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
1003
+ if (found)
1004
+ gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " +
1005
+ dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px"));
1006
+ }
1007
+ }
1008
+ }
1009
+
1010
+ function updateLineWidgets(cm, lineView, dims) {
1011
+ if (lineView.alignable) lineView.alignable = null;
1012
+ for (var node = lineView.node.firstChild, next; node; node = next) {
1013
+ var next = node.nextSibling;
1014
+ if (node.className == "CodeMirror-linewidget")
1015
+ lineView.node.removeChild(node);
1016
+ }
1017
+ insertLineWidgets(cm, lineView, dims);
1018
+ }
1019
+
1020
+ // Build a line's DOM representation from scratch
1021
+ function buildLineElement(cm, lineView, lineN, dims) {
1022
+ var built = getLineContent(cm, lineView);
1023
+ lineView.text = lineView.node = built.pre;
1024
+ if (built.bgClass) lineView.bgClass = built.bgClass;
1025
+ if (built.textClass) lineView.textClass = built.textClass;
1026
+
1027
+ updateLineClasses(lineView);
1028
+ updateLineGutter(cm, lineView, lineN, dims);
1029
+ insertLineWidgets(cm, lineView, dims);
1030
+ return lineView.node;
1031
+ }
1032
+
1033
+ // A lineView may contain multiple logical lines (when merged by
1034
+ // collapsed spans). The widgets for all of them need to be drawn.
1035
+ function insertLineWidgets(cm, lineView, dims) {
1036
+ insertLineWidgetsFor(cm, lineView.line, lineView, dims, true);
1037
+ if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)
1038
+ insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false);
1039
+ }
1040
+
1041
+ function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) {
1042
+ if (!line.widgets) return;
1043
+ var wrap = ensureLineWrapped(lineView);
1044
+ for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
1045
+ var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
1046
+ if (!widget.handleMouseEvents) node.setAttribute("cm-ignore-events", "true");
1047
+ positionLineWidget(widget, node, lineView, dims);
1048
+ cm.display.input.setUneditable(node);
1049
+ if (allowAbove && widget.above)
1050
+ wrap.insertBefore(node, lineView.gutter || lineView.text);
1051
+ else
1052
+ wrap.appendChild(node);
1053
+ signalLater(widget, "redraw");
1054
+ }
1055
+ }
1056
+
1057
+ function positionLineWidget(widget, node, lineView, dims) {
1058
+ if (widget.noHScroll) {
1059
+ (lineView.alignable || (lineView.alignable = [])).push(node);
1060
+ var width = dims.wrapperWidth;
1061
+ node.style.left = dims.fixedPos + "px";
1062
+ if (!widget.coverGutter) {
1063
+ width -= dims.gutterTotalWidth;
1064
+ node.style.paddingLeft = dims.gutterTotalWidth + "px";
1065
+ }
1066
+ node.style.width = width + "px";
1067
+ }
1068
+ if (widget.coverGutter) {
1069
+ node.style.zIndex = 5;
1070
+ node.style.position = "relative";
1071
+ if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px";
1072
+ }
1073
+ }
1074
+
1075
+ // POSITION OBJECT
1076
+
1077
+ // A Pos instance represents a position within the text.
1078
+ var Pos = CodeMirror.Pos = function(line, ch) {
1079
+ if (!(this instanceof Pos)) return new Pos(line, ch);
1080
+ this.line = line; this.ch = ch;
1081
+ };
1082
+
1083
+ // Compare two positions, return 0 if they are the same, a negative
1084
+ // number when a is less, and a positive number otherwise.
1085
+ var cmp = CodeMirror.cmpPos = function(a, b) { return a.line - b.line || a.ch - b.ch; };
1086
+
1087
+ function copyPos(x) {return Pos(x.line, x.ch);}
1088
+ function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; }
1089
+ function minPos(a, b) { return cmp(a, b) < 0 ? a : b; }
1090
+
1091
+ // INPUT HANDLING
1092
+
1093
+ function ensureFocus(cm) {
1094
+ if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); }
1095
+ }
1096
+
1097
+ // This will be set to an array of strings when copying, so that,
1098
+ // when pasting, we know what kind of selections the copied text
1099
+ // was made out of.
1100
+ var lastCopied = null;
1101
+
1102
+ function applyTextInput(cm, inserted, deleted, sel, origin) {
1103
+ var doc = cm.doc;
1104
+ cm.display.shift = false;
1105
+ if (!sel) sel = doc.sel;
1106
+
1107
+ var paste = cm.state.pasteIncoming || origin == "paste";
1108
+ var textLines = doc.splitLines(inserted), multiPaste = null;
1109
+ // When pasing N lines into N selections, insert one line per selection
1110
+ if (paste && sel.ranges.length > 1) {
1111
+ if (lastCopied && lastCopied.join("\n") == inserted) {
1112
+ if (sel.ranges.length % lastCopied.length == 0) {
1113
+ multiPaste = [];
1114
+ for (var i = 0; i < lastCopied.length; i++)
1115
+ multiPaste.push(doc.splitLines(lastCopied[i]));
1116
+ }
1117
+ } else if (textLines.length == sel.ranges.length) {
1118
+ multiPaste = map(textLines, function(l) { return [l]; });
1119
+ }
1120
+ }
1121
+
1122
+ // Normal behavior is to insert the new text into every selection
1123
+ for (var i = sel.ranges.length - 1; i >= 0; i--) {
1124
+ var range = sel.ranges[i];
1125
+ var from = range.from(), to = range.to();
1126
+ if (range.empty()) {
1127
+ if (deleted && deleted > 0) // Handle deletion
1128
+ from = Pos(from.line, from.ch - deleted);
1129
+ else if (cm.state.overwrite && !paste) // Handle overwrite
1130
+ to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length));
1131
+ }
1132
+ var updateInput = cm.curOp.updateInput;
1133
+ var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines,
1134
+ origin: origin || (paste ? "paste" : cm.state.cutIncoming ? "cut" : "+input")};
1135
+ makeChange(cm.doc, changeEvent);
1136
+ signalLater(cm, "inputRead", cm, changeEvent);
1137
+ }
1138
+ if (inserted && !paste)
1139
+ triggerElectric(cm, inserted);
1140
+
1141
+ ensureCursorVisible(cm);
1142
+ cm.curOp.updateInput = updateInput;
1143
+ cm.curOp.typing = true;
1144
+ cm.state.pasteIncoming = cm.state.cutIncoming = false;
1145
+ }
1146
+
1147
+ function handlePaste(e, cm) {
1148
+ var pasted = e.clipboardData && e.clipboardData.getData("text/plain");
1149
+ if (pasted) {
1150
+ e.preventDefault();
1151
+ if (!cm.isReadOnly() && !cm.options.disableInput)
1152
+ runInOp(cm, function() { applyTextInput(cm, pasted, 0, null, "paste"); });
1153
+ return true;
1154
+ }
1155
+ }
1156
+
1157
+ function triggerElectric(cm, inserted) {
1158
+ // When an 'electric' character is inserted, immediately trigger a reindent
1159
+ if (!cm.options.electricChars || !cm.options.smartIndent) return;
1160
+ var sel = cm.doc.sel;
1161
+
1162
+ for (var i = sel.ranges.length - 1; i >= 0; i--) {
1163
+ var range = sel.ranges[i];
1164
+ if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) continue;
1165
+ var mode = cm.getModeAt(range.head);
1166
+ var indented = false;
1167
+ if (mode.electricChars) {
1168
+ for (var j = 0; j < mode.electricChars.length; j++)
1169
+ if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {
1170
+ indented = indentLine(cm, range.head.line, "smart");
1171
+ break;
1172
+ }
1173
+ } else if (mode.electricInput) {
1174
+ if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch)))
1175
+ indented = indentLine(cm, range.head.line, "smart");
1176
+ }
1177
+ if (indented) signalLater(cm, "electricInput", cm, range.head.line);
1178
+ }
1179
+ }
1180
+
1181
+ function copyableRanges(cm) {
1182
+ var text = [], ranges = [];
1183
+ for (var i = 0; i < cm.doc.sel.ranges.length; i++) {
1184
+ var line = cm.doc.sel.ranges[i].head.line;
1185
+ var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)};
1186
+ ranges.push(lineRange);
1187
+ text.push(cm.getRange(lineRange.anchor, lineRange.head));
1188
+ }
1189
+ return {text: text, ranges: ranges};
1190
+ }
1191
+
1192
+ function disableBrowserMagic(field) {
1193
+ field.setAttribute("autocorrect", "off");
1194
+ field.setAttribute("autocapitalize", "off");
1195
+ field.setAttribute("spellcheck", "false");
1196
+ }
1197
+
1198
+ // TEXTAREA INPUT STYLE
1199
+
1200
+ function TextareaInput(cm) {
1201
+ this.cm = cm;
1202
+ // See input.poll and input.reset
1203
+ this.prevInput = "";
1204
+
1205
+ // Flag that indicates whether we expect input to appear real soon
1206
+ // now (after some event like 'keypress' or 'input') and are
1207
+ // polling intensively.
1208
+ this.pollingFast = false;
1209
+ // Self-resetting timeout for the poller
1210
+ this.polling = new Delayed();
1211
+ // Tracks when input.reset has punted to just putting a short
1212
+ // string into the textarea instead of the full selection.
1213
+ this.inaccurateSelection = false;
1214
+ // Used to work around IE issue with selection being forgotten when focus moves away from textarea
1215
+ this.hasSelection = false;
1216
+ this.composing = null;
1217
+ };
1218
+
1219
+ function hiddenTextarea() {
1220
+ var te = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none");
1221
+ var div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
1222
+ // The textarea is kept positioned near the cursor to prevent the
1223
+ // fact that it'll be scrolled into view on input from scrolling
1224
+ // our fake cursor out of view. On webkit, when wrap=off, paste is
1225
+ // very slow. So make the area wide instead.
1226
+ if (webkit) te.style.width = "1000px";
1227
+ else te.setAttribute("wrap", "off");
1228
+ // If border: 0; -- iOS fails to open keyboard (issue #1287)
1229
+ if (ios) te.style.border = "1px solid black";
1230
+ disableBrowserMagic(te);
1231
+ return div;
1232
+ }
1233
+
1234
+ TextareaInput.prototype = copyObj({
1235
+ init: function(display) {
1236
+ var input = this, cm = this.cm;
1237
+
1238
+ // Wraps and hides input textarea
1239
+ var div = this.wrapper = hiddenTextarea();
1240
+ // The semihidden textarea that is focused when the editor is
1241
+ // focused, and receives input.
1242
+ var te = this.textarea = div.firstChild;
1243
+ display.wrapper.insertBefore(div, display.wrapper.firstChild);
1244
+
1245
+ // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore)
1246
+ if (ios) te.style.width = "0px";
1247
+
1248
+ on(te, "input", function() {
1249
+ if (ie && ie_version >= 9 && input.hasSelection) input.hasSelection = null;
1250
+ input.poll();
1251
+ });
1252
+
1253
+ on(te, "paste", function(e) {
1254
+ if (signalDOMEvent(cm, e) || handlePaste(e, cm)) return
1255
+
1256
+ cm.state.pasteIncoming = true;
1257
+ input.fastPoll();
1258
+ });
1259
+
1260
+ function prepareCopyCut(e) {
1261
+ if (cm.somethingSelected()) {
1262
+ lastCopied = cm.getSelections();
1263
+ if (input.inaccurateSelection) {
1264
+ input.prevInput = "";
1265
+ input.inaccurateSelection = false;
1266
+ te.value = lastCopied.join("\n");
1267
+ selectInput(te);
1268
+ }
1269
+ } else if (!cm.options.lineWiseCopyCut) {
1270
+ return;
1271
+ } else {
1272
+ var ranges = copyableRanges(cm);
1273
+ lastCopied = ranges.text;
1274
+ if (e.type == "cut") {
1275
+ cm.setSelections(ranges.ranges, null, sel_dontScroll);
1276
+ } else {
1277
+ input.prevInput = "";
1278
+ te.value = ranges.text.join("\n");
1279
+ selectInput(te);
1280
+ }
1281
+ }
1282
+ if (e.type == "cut") cm.state.cutIncoming = true;
1283
+ }
1284
+ on(te, "cut", prepareCopyCut);
1285
+ on(te, "copy", prepareCopyCut);
1286
+
1287
+ on(display.scroller, "paste", function(e) {
1288
+ if (eventInWidget(display, e) || signalDOMEvent(cm, e)) return;
1289
+ cm.state.pasteIncoming = true;
1290
+ input.focus();
1291
+ });
1292
+
1293
+ // Prevent normal selection in the editor (we handle our own)
1294
+ on(display.lineSpace, "selectstart", function(e) {
1295
+ if (!eventInWidget(display, e)) e_preventDefault(e);
1296
+ });
1297
+
1298
+ on(te, "compositionstart", function() {
1299
+ var start = cm.getCursor("from");
1300
+ if (input.composing) input.composing.range.clear()
1301
+ input.composing = {
1302
+ start: start,
1303
+ range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"})
1304
+ };
1305
+ });
1306
+ on(te, "compositionend", function() {
1307
+ if (input.composing) {
1308
+ input.poll();
1309
+ input.composing.range.clear();
1310
+ input.composing = null;
1311
+ }
1312
+ });
1313
+ },
1314
+
1315
+ prepareSelection: function() {
1316
+ // Redraw the selection and/or cursor
1317
+ var cm = this.cm, display = cm.display, doc = cm.doc;
1318
+ var result = prepareSelection(cm);
1319
+
1320
+ // Move the hidden textarea near the cursor to prevent scrolling artifacts
1321
+ if (cm.options.moveInputWithCursor) {
1322
+ var headPos = cursorCoords(cm, doc.sel.primary().head, "div");
1323
+ var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect();
1324
+ result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
1325
+ headPos.top + lineOff.top - wrapOff.top));
1326
+ result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
1327
+ headPos.left + lineOff.left - wrapOff.left));
1328
+ }
1329
+
1330
+ return result;
1331
+ },
1332
+
1333
+ showSelection: function(drawn) {
1334
+ var cm = this.cm, display = cm.display;
1335
+ removeChildrenAndAdd(display.cursorDiv, drawn.cursors);
1336
+ removeChildrenAndAdd(display.selectionDiv, drawn.selection);
1337
+ if (drawn.teTop != null) {
1338
+ this.wrapper.style.top = drawn.teTop + "px";
1339
+ this.wrapper.style.left = drawn.teLeft + "px";
1340
+ }
1341
+ },
1342
+
1343
+ // Reset the input to correspond to the selection (or to be empty,
1344
+ // when not typing and nothing is selected)
1345
+ reset: function(typing) {
1346
+ if (this.contextMenuPending) return;
1347
+ var minimal, selected, cm = this.cm, doc = cm.doc;
1348
+ if (cm.somethingSelected()) {
1349
+ this.prevInput = "";
1350
+ var range = doc.sel.primary();
1351
+ minimal = hasCopyEvent &&
1352
+ (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000);
1353
+ var content = minimal ? "-" : selected || cm.getSelection();
1354
+ this.textarea.value = content;
1355
+ if (cm.state.focused) selectInput(this.textarea);
1356
+ if (ie && ie_version >= 9) this.hasSelection = content;
1357
+ } else if (!typing) {
1358
+ this.prevInput = this.textarea.value = "";
1359
+ if (ie && ie_version >= 9) this.hasSelection = null;
1360
+ }
1361
+ this.inaccurateSelection = minimal;
1362
+ },
1363
+
1364
+ getField: function() { return this.textarea; },
1365
+
1366
+ supportsTouch: function() { return false; },
1367
+
1368
+ focus: function() {
1369
+ if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) {
1370
+ try { this.textarea.focus(); }
1371
+ catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM
1372
+ }
1373
+ },
1374
+
1375
+ blur: function() { this.textarea.blur(); },
1376
+
1377
+ resetPosition: function() {
1378
+ this.wrapper.style.top = this.wrapper.style.left = 0;
1379
+ },
1380
+
1381
+ receivedFocus: function() { this.slowPoll(); },
1382
+
1383
+ // Poll for input changes, using the normal rate of polling. This
1384
+ // runs as long as the editor is focused.
1385
+ slowPoll: function() {
1386
+ var input = this;
1387
+ if (input.pollingFast) return;
1388
+ input.polling.set(this.cm.options.pollInterval, function() {
1389
+ input.poll();
1390
+ if (input.cm.state.focused) input.slowPoll();
1391
+ });
1392
+ },
1393
+
1394
+ // When an event has just come in that is likely to add or change
1395
+ // something in the input textarea, we poll faster, to ensure that
1396
+ // the change appears on the screen quickly.
1397
+ fastPoll: function() {
1398
+ var missed = false, input = this;
1399
+ input.pollingFast = true;
1400
+ function p() {
1401
+ var changed = input.poll();
1402
+ if (!changed && !missed) {missed = true; input.polling.set(60, p);}
1403
+ else {input.pollingFast = false; input.slowPoll();}
1404
+ }
1405
+ input.polling.set(20, p);
1406
+ },
1407
+
1408
+ // Read input from the textarea, and update the document to match.
1409
+ // When something is selected, it is present in the textarea, and
1410
+ // selected (unless it is huge, in which case a placeholder is
1411
+ // used). When nothing is selected, the cursor sits after previously
1412
+ // seen text (can be empty), which is stored in prevInput (we must
1413
+ // not reset the textarea when typing, because that breaks IME).
1414
+ poll: function() {
1415
+ var cm = this.cm, input = this.textarea, prevInput = this.prevInput;
1416
+ // Since this is called a *lot*, try to bail out as cheaply as
1417
+ // possible when it is clear that nothing happened. hasSelection
1418
+ // will be the case when there is a lot of text in the textarea,
1419
+ // in which case reading its value would be expensive.
1420
+ if (this.contextMenuPending || !cm.state.focused ||
1421
+ (hasSelection(input) && !prevInput && !this.composing) ||
1422
+ cm.isReadOnly() || cm.options.disableInput || cm.state.keySeq)
1423
+ return false;
1424
+
1425
+ var text = input.value;
1426
+ // If nothing changed, bail.
1427
+ if (text == prevInput && !cm.somethingSelected()) return false;
1428
+ // Work around nonsensical selection resetting in IE9/10, and
1429
+ // inexplicable appearance of private area unicode characters on
1430
+ // some key combos in Mac (#2689).
1431
+ if (ie && ie_version >= 9 && this.hasSelection === text ||
1432
+ mac && /[\uf700-\uf7ff]/.test(text)) {
1433
+ cm.display.input.reset();
1434
+ return false;
1435
+ }
1436
+
1437
+ if (cm.doc.sel == cm.display.selForContextMenu) {
1438
+ var first = text.charCodeAt(0);
1439
+ if (first == 0x200b && !prevInput) prevInput = "\u200b";
1440
+ if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo"); }
1441
+ }
1442
+ // Find the part of the input that is actually new
1443
+ var same = 0, l = Math.min(prevInput.length, text.length);
1444
+ while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;
1445
+
1446
+ var self = this;
1447
+ runInOp(cm, function() {
1448
+ applyTextInput(cm, text.slice(same), prevInput.length - same,
1449
+ null, self.composing ? "*compose" : null);
1450
+
1451
+ // Don't leave long text in the textarea, since it makes further polling slow
1452
+ if (text.length > 1000 || text.indexOf("\n") > -1) input.value = self.prevInput = "";
1453
+ else self.prevInput = text;
1454
+
1455
+ if (self.composing) {
1456
+ self.composing.range.clear();
1457
+ self.composing.range = cm.markText(self.composing.start, cm.getCursor("to"),
1458
+ {className: "CodeMirror-composing"});
1459
+ }
1460
+ });
1461
+ return true;
1462
+ },
1463
+
1464
+ ensurePolled: function() {
1465
+ if (this.pollingFast && this.poll()) this.pollingFast = false;
1466
+ },
1467
+
1468
+ onKeyPress: function() {
1469
+ if (ie && ie_version >= 9) this.hasSelection = null;
1470
+ this.fastPoll();
1471
+ },
1472
+
1473
+ onContextMenu: function(e) {
1474
+ var input = this, cm = input.cm, display = cm.display, te = input.textarea;
1475
+ var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
1476
+ if (!pos || presto) return; // Opera is difficult.
1477
+
1478
+ // Reset the current text selection only if the click is done outside of the selection
1479
+ // and 'resetSelectionOnContextMenu' option is true.
1480
+ var reset = cm.options.resetSelectionOnContextMenu;
1481
+ if (reset && cm.doc.sel.contains(pos) == -1)
1482
+ operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll);
1483
+
1484
+ var oldCSS = te.style.cssText;
1485
+ input.wrapper.style.position = "absolute";
1486
+ te.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
1487
+ "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: " +
1488
+ (ie ? "rgba(255, 255, 255, .05)" : "transparent") +
1489
+ "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
1490
+ if (webkit) var oldScrollY = window.scrollY; // Work around Chrome issue (#2712)
1491
+ display.input.focus();
1492
+ if (webkit) window.scrollTo(null, oldScrollY);
1493
+ display.input.reset();
1494
+ // Adds "Select all" to context menu in FF
1495
+ if (!cm.somethingSelected()) te.value = input.prevInput = " ";
1496
+ input.contextMenuPending = true;
1497
+ display.selForContextMenu = cm.doc.sel;
1498
+ clearTimeout(display.detectingSelectAll);
1499
+
1500
+ // Select-all will be greyed out if there's nothing to select, so
1501
+ // this adds a zero-width space so that we can later check whether
1502
+ // it got selected.
1503
+ function prepareSelectAllHack() {
1504
+ if (te.selectionStart != null) {
1505
+ var selected = cm.somethingSelected();
1506
+ var extval = "\u200b" + (selected ? te.value : "");
1507
+ te.value = "\u21da"; // Used to catch context-menu undo
1508
+ te.value = extval;
1509
+ input.prevInput = selected ? "" : "\u200b";
1510
+ te.selectionStart = 1; te.selectionEnd = extval.length;
1511
+ // Re-set this, in case some other handler touched the
1512
+ // selection in the meantime.
1513
+ display.selForContextMenu = cm.doc.sel;
1514
+ }
1515
+ }
1516
+ function rehide() {
1517
+ input.contextMenuPending = false;
1518
+ input.wrapper.style.position = "relative";
1519
+ te.style.cssText = oldCSS;
1520
+ if (ie && ie_version < 9) display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos);
1521
+
1522
+ // Try to detect the user choosing select-all
1523
+ if (te.selectionStart != null) {
1524
+ if (!ie || (ie && ie_version < 9)) prepareSelectAllHack();
1525
+ var i = 0, poll = function() {
1526
+ if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 &&
1527
+ te.selectionEnd > 0 && input.prevInput == "\u200b")
1528
+ operation(cm, commands.selectAll)(cm);
1529
+ else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500);
1530
+ else display.input.reset();
1531
+ };
1532
+ display.detectingSelectAll = setTimeout(poll, 200);
1533
+ }
1534
+ }
1535
+
1536
+ if (ie && ie_version >= 9) prepareSelectAllHack();
1537
+ if (captureRightClick) {
1538
+ e_stop(e);
1539
+ var mouseup = function() {
1540
+ off(window, "mouseup", mouseup);
1541
+ setTimeout(rehide, 20);
1542
+ };
1543
+ on(window, "mouseup", mouseup);
1544
+ } else {
1545
+ setTimeout(rehide, 50);
1546
+ }
1547
+ },
1548
+
1549
+ readOnlyChanged: function(val) {
1550
+ if (!val) this.reset();
1551
+ },
1552
+
1553
+ setUneditable: nothing,
1554
+
1555
+ needsContentAttribute: false
1556
+ }, TextareaInput.prototype);
1557
+
1558
+ // CONTENTEDITABLE INPUT STYLE
1559
+
1560
+ function ContentEditableInput(cm) {
1561
+ this.cm = cm;
1562
+ this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null;
1563
+ this.polling = new Delayed();
1564
+ this.gracePeriod = false;
1565
+ }
1566
+
1567
+ ContentEditableInput.prototype = copyObj({
1568
+ init: function(display) {
1569
+ var input = this, cm = input.cm;
1570
+ var div = input.div = display.lineDiv;
1571
+ disableBrowserMagic(div);
1572
+
1573
+ on(div, "paste", function(e) {
1574
+ if (!signalDOMEvent(cm, e)) handlePaste(e, cm);
1575
+ })
1576
+
1577
+ on(div, "compositionstart", function(e) {
1578
+ var data = e.data;
1579
+ input.composing = {sel: cm.doc.sel, data: data, startData: data};
1580
+ if (!data) return;
1581
+ var prim = cm.doc.sel.primary();
1582
+ var line = cm.getLine(prim.head.line);
1583
+ var found = line.indexOf(data, Math.max(0, prim.head.ch - data.length));
1584
+ if (found > -1 && found <= prim.head.ch)
1585
+ input.composing.sel = simpleSelection(Pos(prim.head.line, found),
1586
+ Pos(prim.head.line, found + data.length));
1587
+ });
1588
+ on(div, "compositionupdate", function(e) {
1589
+ input.composing.data = e.data;
1590
+ });
1591
+ on(div, "compositionend", function(e) {
1592
+ var ours = input.composing;
1593
+ if (!ours) return;
1594
+ if (e.data != ours.startData && !/\u200b/.test(e.data))
1595
+ ours.data = e.data;
1596
+ // Need a small delay to prevent other code (input event,
1597
+ // selection polling) from doing damage when fired right after
1598
+ // compositionend.
1599
+ setTimeout(function() {
1600
+ if (!ours.handled)
1601
+ input.applyComposition(ours);
1602
+ if (input.composing == ours)
1603
+ input.composing = null;
1604
+ }, 50);
1605
+ });
1606
+
1607
+ on(div, "touchstart", function() {
1608
+ input.forceCompositionEnd();
1609
+ });
1610
+
1611
+ on(div, "input", function() {
1612
+ if (input.composing) return;
1613
+ if (cm.isReadOnly() || !input.pollContent())
1614
+ runInOp(input.cm, function() {regChange(cm);});
1615
+ });
1616
+
1617
+ function onCopyCut(e) {
1618
+ if (cm.somethingSelected()) {
1619
+ lastCopied = cm.getSelections();
1620
+ if (e.type == "cut") cm.replaceSelection("", null, "cut");
1621
+ } else if (!cm.options.lineWiseCopyCut) {
1622
+ return;
1623
+ } else {
1624
+ var ranges = copyableRanges(cm);
1625
+ lastCopied = ranges.text;
1626
+ if (e.type == "cut") {
1627
+ cm.operation(function() {
1628
+ cm.setSelections(ranges.ranges, 0, sel_dontScroll);
1629
+ cm.replaceSelection("", null, "cut");
1630
+ });
1631
+ }
1632
+ }
1633
+ // iOS exposes the clipboard API, but seems to discard content inserted into it
1634
+ if (e.clipboardData && !ios) {
1635
+ e.preventDefault();
1636
+ e.clipboardData.clearData();
1637
+ e.clipboardData.setData("text/plain", lastCopied.join("\n"));
1638
+ } else {
1639
+ // Old-fashioned briefly-focus-a-textarea hack
1640
+ var kludge = hiddenTextarea(), te = kludge.firstChild;
1641
+ cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild);
1642
+ te.value = lastCopied.join("\n");
1643
+ var hadFocus = document.activeElement;
1644
+ selectInput(te);
1645
+ setTimeout(function() {
1646
+ cm.display.lineSpace.removeChild(kludge);
1647
+ hadFocus.focus();
1648
+ }, 50);
1649
+ }
1650
+ }
1651
+ on(div, "copy", onCopyCut);
1652
+ on(div, "cut", onCopyCut);
1653
+ },
1654
+
1655
+ prepareSelection: function() {
1656
+ var result = prepareSelection(this.cm, false);
1657
+ result.focus = this.cm.state.focused;
1658
+ return result;
1659
+ },
1660
+
1661
+ showSelection: function(info) {
1662
+ if (!info || !this.cm.display.view.length) return;
1663
+ if (info.focus) this.showPrimarySelection();
1664
+ this.showMultipleSelections(info);
1665
+ },
1666
+
1667
+ showPrimarySelection: function() {
1668
+ var sel = window.getSelection(), prim = this.cm.doc.sel.primary();
1669
+ var curAnchor = domToPos(this.cm, sel.anchorNode, sel.anchorOffset);
1670
+ var curFocus = domToPos(this.cm, sel.focusNode, sel.focusOffset);
1671
+ if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad &&
1672
+ cmp(minPos(curAnchor, curFocus), prim.from()) == 0 &&
1673
+ cmp(maxPos(curAnchor, curFocus), prim.to()) == 0)
1674
+ return;
1675
+
1676
+ var start = posToDOM(this.cm, prim.from());
1677
+ var end = posToDOM(this.cm, prim.to());
1678
+ if (!start && !end) return;
1679
+
1680
+ var view = this.cm.display.view;
1681
+ var old = sel.rangeCount && sel.getRangeAt(0);
1682
+ if (!start) {
1683
+ start = {node: view[0].measure.map[2], offset: 0};
1684
+ } else if (!end) { // FIXME dangerously hacky
1685
+ var measure = view[view.length - 1].measure;
1686
+ var map = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map;
1687
+ end = {node: map[map.length - 1], offset: map[map.length - 2] - map[map.length - 3]};
1688
+ }
1689
+
1690
+ try { var rng = range(start.node, start.offset, end.offset, end.node); }
1691
+ catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible
1692
+ if (rng) {
1693
+ if (!gecko && this.cm.state.focused) {
1694
+ sel.collapse(start.node, start.offset);
1695
+ if (!rng.collapsed) sel.addRange(rng);
1696
+ } else {
1697
+ sel.removeAllRanges();
1698
+ sel.addRange(rng);
1699
+ }
1700
+ if (old && sel.anchorNode == null) sel.addRange(old);
1701
+ else if (gecko) this.startGracePeriod();
1702
+ }
1703
+ this.rememberSelection();
1704
+ },
1705
+
1706
+ startGracePeriod: function() {
1707
+ var input = this;
1708
+ clearTimeout(this.gracePeriod);
1709
+ this.gracePeriod = setTimeout(function() {
1710
+ input.gracePeriod = false;
1711
+ if (input.selectionChanged())
1712
+ input.cm.operation(function() { input.cm.curOp.selectionChanged = true; });
1713
+ }, 20);
1714
+ },
1715
+
1716
+ showMultipleSelections: function(info) {
1717
+ removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors);
1718
+ removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection);
1719
+ },
1720
+
1721
+ rememberSelection: function() {
1722
+ var sel = window.getSelection();
1723
+ this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset;
1724
+ this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset;
1725
+ },
1726
+
1727
+ selectionInEditor: function() {
1728
+ var sel = window.getSelection();
1729
+ if (!sel.rangeCount) return false;
1730
+ var node = sel.getRangeAt(0).commonAncestorContainer;
1731
+ return contains(this.div, node);
1732
+ },
1733
+
1734
+ focus: function() {
1735
+ if (this.cm.options.readOnly != "nocursor") this.div.focus();
1736
+ },
1737
+ blur: function() { this.div.blur(); },
1738
+ getField: function() { return this.div; },
1739
+
1740
+ supportsTouch: function() { return true; },
1741
+
1742
+ receivedFocus: function() {
1743
+ var input = this;
1744
+ if (this.selectionInEditor())
1745
+ this.pollSelection();
1746
+ else
1747
+ runInOp(this.cm, function() { input.cm.curOp.selectionChanged = true; });
1748
+
1749
+ function poll() {
1750
+ if (input.cm.state.focused) {
1751
+ input.pollSelection();
1752
+ input.polling.set(input.cm.options.pollInterval, poll);
1753
+ }
1754
+ }
1755
+ this.polling.set(this.cm.options.pollInterval, poll);
1756
+ },
1757
+
1758
+ selectionChanged: function() {
1759
+ var sel = window.getSelection();
1760
+ return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset ||
1761
+ sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset;
1762
+ },
1763
+
1764
+ pollSelection: function() {
1765
+ if (!this.composing && !this.gracePeriod && this.selectionChanged()) {
1766
+ var sel = window.getSelection(), cm = this.cm;
1767
+ this.rememberSelection();
1768
+ var anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset);
1769
+ var head = domToPos(cm, sel.focusNode, sel.focusOffset);
1770
+ if (anchor && head) runInOp(cm, function() {
1771
+ setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll);
1772
+ if (anchor.bad || head.bad) cm.curOp.selectionChanged = true;
1773
+ });
1774
+ }
1775
+ },
1776
+
1777
+ pollContent: function() {
1778
+ var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary();
1779
+ var from = sel.from(), to = sel.to();
1780
+ if (from.line < display.viewFrom || to.line > display.viewTo - 1) return false;
1781
+
1782
+ var fromIndex;
1783
+ if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) {
1784
+ var fromLine = lineNo(display.view[0].line);
1785
+ var fromNode = display.view[0].node;
1786
+ } else {
1787
+ var fromLine = lineNo(display.view[fromIndex].line);
1788
+ var fromNode = display.view[fromIndex - 1].node.nextSibling;
1789
+ }
1790
+ var toIndex = findViewIndex(cm, to.line);
1791
+ if (toIndex == display.view.length - 1) {
1792
+ var toLine = display.viewTo - 1;
1793
+ var toNode = display.lineDiv.lastChild;
1794
+ } else {
1795
+ var toLine = lineNo(display.view[toIndex + 1].line) - 1;
1796
+ var toNode = display.view[toIndex + 1].node.previousSibling;
1797
+ }
1798
+
1799
+ var newText = cm.doc.splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine));
1800
+ var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length));
1801
+ while (newText.length > 1 && oldText.length > 1) {
1802
+ if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine--; }
1803
+ else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++; }
1804
+ else break;
1805
+ }
1806
+
1807
+ var cutFront = 0, cutEnd = 0;
1808
+ var newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length);
1809
+ while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront))
1810
+ ++cutFront;
1811
+ var newBot = lst(newText), oldBot = lst(oldText);
1812
+ var maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0),
1813
+ oldBot.length - (oldText.length == 1 ? cutFront : 0));
1814
+ while (cutEnd < maxCutEnd &&
1815
+ newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1))
1816
+ ++cutEnd;
1817
+
1818
+ newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd);
1819
+ newText[0] = newText[0].slice(cutFront);
1820
+
1821
+ var chFrom = Pos(fromLine, cutFront);
1822
+ var chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0);
1823
+ if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) {
1824
+ replaceRange(cm.doc, newText, chFrom, chTo, "+input");
1825
+ return true;
1826
+ }
1827
+ },
1828
+
1829
+ ensurePolled: function() {
1830
+ this.forceCompositionEnd();
1831
+ },
1832
+ reset: function() {
1833
+ this.forceCompositionEnd();
1834
+ },
1835
+ forceCompositionEnd: function() {
1836
+ if (!this.composing || this.composing.handled) return;
1837
+ this.applyComposition(this.composing);
1838
+ this.composing.handled = true;
1839
+ this.div.blur();
1840
+ this.div.focus();
1841
+ },
1842
+ applyComposition: function(composing) {
1843
+ if (this.cm.isReadOnly())
1844
+ operation(this.cm, regChange)(this.cm)
1845
+ else if (composing.data && composing.data != composing.startData)
1846
+ operation(this.cm, applyTextInput)(this.cm, composing.data, 0, composing.sel);
1847
+ },
1848
+
1849
+ setUneditable: function(node) {
1850
+ node.contentEditable = "false"
1851
+ },
1852
+
1853
+ onKeyPress: function(e) {
1854
+ e.preventDefault();
1855
+ if (!this.cm.isReadOnly())
1856
+ operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0);
1857
+ },
1858
+
1859
+ readOnlyChanged: function(val) {
1860
+ this.div.contentEditable = String(val != "nocursor")
1861
+ },
1862
+
1863
+ onContextMenu: nothing,
1864
+ resetPosition: nothing,
1865
+
1866
+ needsContentAttribute: true
1867
+ }, ContentEditableInput.prototype);
1868
+
1869
+ function posToDOM(cm, pos) {
1870
+ var view = findViewForLine(cm, pos.line);
1871
+ if (!view || view.hidden) return null;
1872
+ var line = getLine(cm.doc, pos.line);
1873
+ var info = mapFromLineView(view, line, pos.line);
1874
+
1875
+ var order = getOrder(line), side = "left";
1876
+ if (order) {
1877
+ var partPos = getBidiPartAt(order, pos.ch);
1878
+ side = partPos % 2 ? "right" : "left";
1879
+ }
1880
+ var result = nodeAndOffsetInLineMap(info.map, pos.ch, side);
1881
+ result.offset = result.collapse == "right" ? result.end : result.start;
1882
+ return result;
1883
+ }
1884
+
1885
+ function badPos(pos, bad) { if (bad) pos.bad = true; return pos; }
1886
+
1887
+ function domToPos(cm, node, offset) {
1888
+ var lineNode;
1889
+ if (node == cm.display.lineDiv) {
1890
+ lineNode = cm.display.lineDiv.childNodes[offset];
1891
+ if (!lineNode) return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true);
1892
+ node = null; offset = 0;
1893
+ } else {
1894
+ for (lineNode = node;; lineNode = lineNode.parentNode) {
1895
+ if (!lineNode || lineNode == cm.display.lineDiv) return null;
1896
+ if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) break;
1897
+ }
1898
+ }
1899
+ for (var i = 0; i < cm.display.view.length; i++) {
1900
+ var lineView = cm.display.view[i];
1901
+ if (lineView.node == lineNode)
1902
+ return locateNodeInLineView(lineView, node, offset);
1903
+ }
1904
+ }
1905
+
1906
+ function locateNodeInLineView(lineView, node, offset) {
1907
+ var wrapper = lineView.text.firstChild, bad = false;
1908
+ if (!node || !contains(wrapper, node)) return badPos(Pos(lineNo(lineView.line), 0), true);
1909
+ if (node == wrapper) {
1910
+ bad = true;
1911
+ node = wrapper.childNodes[offset];
1912
+ offset = 0;
1913
+ if (!node) {
1914
+ var line = lineView.rest ? lst(lineView.rest) : lineView.line;
1915
+ return badPos(Pos(lineNo(line), line.text.length), bad);
1916
+ }
1917
+ }
1918
+
1919
+ var textNode = node.nodeType == 3 ? node : null, topNode = node;
1920
+ if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) {
1921
+ textNode = node.firstChild;
1922
+ if (offset) offset = textNode.nodeValue.length;
1923
+ }
1924
+ while (topNode.parentNode != wrapper) topNode = topNode.parentNode;
1925
+ var measure = lineView.measure, maps = measure.maps;
1926
+
1927
+ function find(textNode, topNode, offset) {
1928
+ for (var i = -1; i < (maps ? maps.length : 0); i++) {
1929
+ var map = i < 0 ? measure.map : maps[i];
1930
+ for (var j = 0; j < map.length; j += 3) {
1931
+ var curNode = map[j + 2];
1932
+ if (curNode == textNode || curNode == topNode) {
1933
+ var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]);
1934
+ var ch = map[j] + offset;
1935
+ if (offset < 0 || curNode != textNode) ch = map[j + (offset ? 1 : 0)];
1936
+ return Pos(line, ch);
1937
+ }
1938
+ }
1939
+ }
1940
+ }
1941
+ var found = find(textNode, topNode, offset);
1942
+ if (found) return badPos(found, bad);
1943
+
1944
+ // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems
1945
+ for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) {
1946
+ found = find(after, after.firstChild, 0);
1947
+ if (found)
1948
+ return badPos(Pos(found.line, found.ch - dist), bad);
1949
+ else
1950
+ dist += after.textContent.length;
1951
+ }
1952
+ for (var before = topNode.previousSibling, dist = offset; before; before = before.previousSibling) {
1953
+ found = find(before, before.firstChild, -1);
1954
+ if (found)
1955
+ return badPos(Pos(found.line, found.ch + dist), bad);
1956
+ else
1957
+ dist += after.textContent.length;
1958
+ }
1959
+ }
1960
+
1961
+ function domTextBetween(cm, from, to, fromLine, toLine) {
1962
+ var text = "", closing = false, lineSep = cm.doc.lineSeparator();
1963
+ function recognizeMarker(id) { return function(marker) { return marker.id == id; }; }
1964
+ function walk(node) {
1965
+ if (node.nodeType == 1) {
1966
+ var cmText = node.getAttribute("cm-text");
1967
+ if (cmText != null) {
1968
+ if (cmText == "") cmText = node.textContent.replace(/\u200b/g, "");
1969
+ text += cmText;
1970
+ return;
1971
+ }
1972
+ var markerID = node.getAttribute("cm-marker"), range;
1973
+ if (markerID) {
1974
+ var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID));
1975
+ if (found.length && (range = found[0].find()))
1976
+ text += getBetween(cm.doc, range.from, range.to).join(lineSep);
1977
+ return;
1978
+ }
1979
+ if (node.getAttribute("contenteditable") == "false") return;
1980
+ for (var i = 0; i < node.childNodes.length; i++)
1981
+ walk(node.childNodes[i]);
1982
+ if (/^(pre|div|p)$/i.test(node.nodeName))
1983
+ closing = true;
1984
+ } else if (node.nodeType == 3) {
1985
+ var val = node.nodeValue;
1986
+ if (!val) return;
1987
+ if (closing) {
1988
+ text += lineSep;
1989
+ closing = false;
1990
+ }
1991
+ text += val;
1992
+ }
1993
+ }
1994
+ for (;;) {
1995
+ walk(from);
1996
+ if (from == to) break;
1997
+ from = from.nextSibling;
1998
+ }
1999
+ return text;
2000
+ }
2001
+
2002
+ CodeMirror.inputStyles = {"textarea": TextareaInput, "contenteditable": ContentEditableInput};
2003
+
2004
+ // SELECTION / CURSOR
2005
+
2006
+ // Selection objects are immutable. A new one is created every time
2007
+ // the selection changes. A selection is one or more non-overlapping
2008
+ // (and non-touching) ranges, sorted, and an integer that indicates
2009
+ // which one is the primary selection (the one that's scrolled into
2010
+ // view, that getCursor returns, etc).
2011
+ function Selection(ranges, primIndex) {
2012
+ this.ranges = ranges;
2013
+ this.primIndex = primIndex;
2014
+ }
2015
+
2016
+ Selection.prototype = {
2017
+ primary: function() { return this.ranges[this.primIndex]; },
2018
+ equals: function(other) {
2019
+ if (other == this) return true;
2020
+ if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false;
2021
+ for (var i = 0; i < this.ranges.length; i++) {
2022
+ var here = this.ranges[i], there = other.ranges[i];
2023
+ if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false;
2024
+ }
2025
+ return true;
2026
+ },
2027
+ deepCopy: function() {
2028
+ for (var out = [], i = 0; i < this.ranges.length; i++)
2029
+ out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head));
2030
+ return new Selection(out, this.primIndex);
2031
+ },
2032
+ somethingSelected: function() {
2033
+ for (var i = 0; i < this.ranges.length; i++)
2034
+ if (!this.ranges[i].empty()) return true;
2035
+ return false;
2036
+ },
2037
+ contains: function(pos, end) {
2038
+ if (!end) end = pos;
2039
+ for (var i = 0; i < this.ranges.length; i++) {
2040
+ var range = this.ranges[i];
2041
+ if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0)
2042
+ return i;
2043
+ }
2044
+ return -1;
2045
+ }
2046
+ };
2047
+
2048
+ function Range(anchor, head) {
2049
+ this.anchor = anchor; this.head = head;
2050
+ }
2051
+
2052
+ Range.prototype = {
2053
+ from: function() { return minPos(this.anchor, this.head); },
2054
+ to: function() { return maxPos(this.anchor, this.head); },
2055
+ empty: function() {
2056
+ return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch;
2057
+ }
2058
+ };
2059
+
2060
+ // Take an unsorted, potentially overlapping set of ranges, and
2061
+ // build a selection out of it. 'Consumes' ranges array (modifying
2062
+ // it).
2063
+ function normalizeSelection(ranges, primIndex) {
2064
+ var prim = ranges[primIndex];
2065
+ ranges.sort(function(a, b) { return cmp(a.from(), b.from()); });
2066
+ primIndex = indexOf(ranges, prim);
2067
+ for (var i = 1; i < ranges.length; i++) {
2068
+ var cur = ranges[i], prev = ranges[i - 1];
2069
+ if (cmp(prev.to(), cur.from()) >= 0) {
2070
+ var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to());
2071
+ var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head;
2072
+ if (i <= primIndex) --primIndex;
2073
+ ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to));
2074
+ }
2075
+ }
2076
+ return new Selection(ranges, primIndex);
2077
+ }
2078
+
2079
+ function simpleSelection(anchor, head) {
2080
+ return new Selection([new Range(anchor, head || anchor)], 0);
2081
+ }
2082
+
2083
+ // Most of the external API clips given positions to make sure they
2084
+ // actually exist within the document.
2085
+ function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));}
2086
+ function clipPos(doc, pos) {
2087
+ if (pos.line < doc.first) return Pos(doc.first, 0);
2088
+ var last = doc.first + doc.size - 1;
2089
+ if (pos.line > last) return Pos(last, getLine(doc, last).text.length);
2090
+ return clipToLen(pos, getLine(doc, pos.line).text.length);
2091
+ }
2092
+ function clipToLen(pos, linelen) {
2093
+ var ch = pos.ch;
2094
+ if (ch == null || ch > linelen) return Pos(pos.line, linelen);
2095
+ else if (ch < 0) return Pos(pos.line, 0);
2096
+ else return pos;
2097
+ }
2098
+ function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;}
2099
+ function clipPosArray(doc, array) {
2100
+ for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]);
2101
+ return out;
2102
+ }
2103
+
2104
+ // SELECTION UPDATES
2105
+
2106
+ // The 'scroll' parameter given to many of these indicated whether
2107
+ // the new cursor position should be scrolled into view after
2108
+ // modifying the selection.
2109
+
2110
+ // If shift is held or the extend flag is set, extends a range to
2111
+ // include a given position (and optionally a second position).
2112
+ // Otherwise, simply returns the range between the given positions.
2113
+ // Used for cursor motion and such.
2114
+ function extendRange(doc, range, head, other) {
2115
+ if (doc.cm && doc.cm.display.shift || doc.extend) {
2116
+ var anchor = range.anchor;
2117
+ if (other) {
2118
+ var posBefore = cmp(head, anchor) < 0;
2119
+ if (posBefore != (cmp(other, anchor) < 0)) {
2120
+ anchor = head;
2121
+ head = other;
2122
+ } else if (posBefore != (cmp(head, other) < 0)) {
2123
+ head = other;
2124
+ }
2125
+ }
2126
+ return new Range(anchor, head);
2127
+ } else {
2128
+ return new Range(other || head, head);
2129
+ }
2130
+ }
2131
+
2132
+ // Extend the primary selection range, discard the rest.
2133
+ function extendSelection(doc, head, other, options) {
2134
+ setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options);
2135
+ }
2136
+
2137
+ // Extend all selections (pos is an array of selections with length
2138
+ // equal the number of selections)
2139
+ function extendSelections(doc, heads, options) {
2140
+ for (var out = [], i = 0; i < doc.sel.ranges.length; i++)
2141
+ out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null);
2142
+ var newSel = normalizeSelection(out, doc.sel.primIndex);
2143
+ setSelection(doc, newSel, options);
2144
+ }
2145
+
2146
+ // Updates a single range in the selection.
2147
+ function replaceOneSelection(doc, i, range, options) {
2148
+ var ranges = doc.sel.ranges.slice(0);
2149
+ ranges[i] = range;
2150
+ setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options);
2151
+ }
2152
+
2153
+ // Reset the selection to a single range.
2154
+ function setSimpleSelection(doc, anchor, head, options) {
2155
+ setSelection(doc, simpleSelection(anchor, head), options);
2156
+ }
2157
+
2158
+ // Give beforeSelectionChange handlers a change to influence a
2159
+ // selection update.
2160
+ function filterSelectionChange(doc, sel, options) {
2161
+ var obj = {
2162
+ ranges: sel.ranges,
2163
+ update: function(ranges) {
2164
+ this.ranges = [];
2165
+ for (var i = 0; i < ranges.length; i++)
2166
+ this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),
2167
+ clipPos(doc, ranges[i].head));
2168
+ },
2169
+ origin: options && options.origin
2170
+ };
2171
+ signal(doc, "beforeSelectionChange", doc, obj);
2172
+ if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj);
2173
+ if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1);
2174
+ else return sel;
2175
+ }
2176
+
2177
+ function setSelectionReplaceHistory(doc, sel, options) {
2178
+ var done = doc.history.done, last = lst(done);
2179
+ if (last && last.ranges) {
2180
+ done[done.length - 1] = sel;
2181
+ setSelectionNoUndo(doc, sel, options);
2182
+ } else {
2183
+ setSelection(doc, sel, options);
2184
+ }
2185
+ }
2186
+
2187
+ // Set a new selection.
2188
+ function setSelection(doc, sel, options) {
2189
+ setSelectionNoUndo(doc, sel, options);
2190
+ addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options);
2191
+ }
2192
+
2193
+ function setSelectionNoUndo(doc, sel, options) {
2194
+ if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
2195
+ sel = filterSelectionChange(doc, sel, options);
2196
+
2197
+ var bias = options && options.bias ||
2198
+ (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);
2199
+ setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));
2200
+
2201
+ if (!(options && options.scroll === false) && doc.cm)
2202
+ ensureCursorVisible(doc.cm);
2203
+ }
2204
+
2205
+ function setSelectionInner(doc, sel) {
2206
+ if (sel.equals(doc.sel)) return;
2207
+
2208
+ doc.sel = sel;
2209
+
2210
+ if (doc.cm) {
2211
+ doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true;
2212
+ signalCursorActivity(doc.cm);
2213
+ }
2214
+ signalLater(doc, "cursorActivity", doc);
2215
+ }
2216
+
2217
+ // Verify that the selection does not partially select any atomic
2218
+ // marked ranges.
2219
+ function reCheckSelection(doc) {
2220
+ setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll);
2221
+ }
2222
+
2223
+ // Return a selection that does not partially select any atomic
2224
+ // ranges.
2225
+ function skipAtomicInSelection(doc, sel, bias, mayClear) {
2226
+ var out;
2227
+ for (var i = 0; i < sel.ranges.length; i++) {
2228
+ var range = sel.ranges[i];
2229
+ var old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i];
2230
+ var newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear);
2231
+ var newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear);
2232
+ if (out || newAnchor != range.anchor || newHead != range.head) {
2233
+ if (!out) out = sel.ranges.slice(0, i);
2234
+ out[i] = new Range(newAnchor, newHead);
2235
+ }
2236
+ }
2237
+ return out ? normalizeSelection(out, sel.primIndex) : sel;
2238
+ }
2239
+
2240
+ function skipAtomicInner(doc, pos, oldPos, dir, mayClear) {
2241
+ var line = getLine(doc, pos.line);
2242
+ if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) {
2243
+ var sp = line.markedSpans[i], m = sp.marker;
2244
+ if ((sp.from == null || (m.inclusiveLeft ? sp.from <= pos.ch : sp.from < pos.ch)) &&
2245
+ (sp.to == null || (m.inclusiveRight ? sp.to >= pos.ch : sp.to > pos.ch))) {
2246
+ if (mayClear) {
2247
+ signal(m, "beforeCursorEnter");
2248
+ if (m.explicitlyCleared) {
2249
+ if (!line.markedSpans) break;
2250
+ else {--i; continue;}
2251
+ }
2252
+ }
2253
+ if (!m.atomic) continue;
2254
+
2255
+ if (oldPos) {
2256
+ var near = m.find(dir < 0 ? 1 : -1), diff;
2257
+ if (dir < 0 ? m.inclusiveRight : m.inclusiveLeft) near = movePos(doc, near, -dir, line);
2258
+ if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0))
2259
+ return skipAtomicInner(doc, near, pos, dir, mayClear);
2260
+ }
2261
+
2262
+ var far = m.find(dir < 0 ? -1 : 1);
2263
+ if (dir < 0 ? m.inclusiveLeft : m.inclusiveRight) far = movePos(doc, far, dir, line);
2264
+ return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null;
2265
+ }
2266
+ }
2267
+ return pos;
2268
+ }
2269
+
2270
+ // Ensure a given position is not inside an atomic range.
2271
+ function skipAtomic(doc, pos, oldPos, bias, mayClear) {
2272
+ var dir = bias || 1;
2273
+ var found = skipAtomicInner(doc, pos, oldPos, dir, mayClear) ||
2274
+ (!mayClear && skipAtomicInner(doc, pos, oldPos, dir, true)) ||
2275
+ skipAtomicInner(doc, pos, oldPos, -dir, mayClear) ||
2276
+ (!mayClear && skipAtomicInner(doc, pos, oldPos, -dir, true));
2277
+ if (!found) {
2278
+ doc.cantEdit = true;
2279
+ return Pos(doc.first, 0);
2280
+ }
2281
+ return found;
2282
+ }
2283
+
2284
+ function movePos(doc, pos, dir, line) {
2285
+ if (dir < 0 && pos.ch == 0) {
2286
+ if (pos.line > doc.first) return clipPos(doc, Pos(pos.line - 1));
2287
+ else return null;
2288
+ } else if (dir > 0 && pos.ch == (line || getLine(doc, pos.line)).text.length) {
2289
+ if (pos.line < doc.first + doc.size - 1) return Pos(pos.line + 1, 0);
2290
+ else return null;
2291
+ } else {
2292
+ return new Pos(pos.line, pos.ch + dir);
2293
+ }
2294
+ }
2295
+
2296
+ // SELECTION DRAWING
2297
+
2298
+ function updateSelection(cm) {
2299
+ cm.display.input.showSelection(cm.display.input.prepareSelection());
2300
+ }
2301
+
2302
+ function prepareSelection(cm, primary) {
2303
+ var doc = cm.doc, result = {};
2304
+ var curFragment = result.cursors = document.createDocumentFragment();
2305
+ var selFragment = result.selection = document.createDocumentFragment();
2306
+
2307
+ for (var i = 0; i < doc.sel.ranges.length; i++) {
2308
+ if (primary === false && i == doc.sel.primIndex) continue;
2309
+ var range = doc.sel.ranges[i];
2310
+ var collapsed = range.empty();
2311
+ if (collapsed || cm.options.showCursorWhenSelecting)
2312
+ drawSelectionCursor(cm, range.head, curFragment);
2313
+ if (!collapsed)
2314
+ drawSelectionRange(cm, range, selFragment);
2315
+ }
2316
+ return result;
2317
+ }
2318
+
2319
+ // Draws a cursor for the given range
2320
+ function drawSelectionCursor(cm, head, output) {
2321
+ var pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine);
2322
+
2323
+ var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor"));
2324
+ cursor.style.left = pos.left + "px";
2325
+ cursor.style.top = pos.top + "px";
2326
+ cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
2327
+
2328
+ if (pos.other) {
2329
+ // Secondary cursor, shown when on a 'jump' in bi-directional text
2330
+ var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor"));
2331
+ otherCursor.style.display = "";
2332
+ otherCursor.style.left = pos.other.left + "px";
2333
+ otherCursor.style.top = pos.other.top + "px";
2334
+ otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
2335
+ }
2336
+ }
2337
+
2338
+ // Draws the given range as a highlighted selection
2339
+ function drawSelectionRange(cm, range, output) {
2340
+ var display = cm.display, doc = cm.doc;
2341
+ var fragment = document.createDocumentFragment();
2342
+ var padding = paddingH(cm.display), leftSide = padding.left;
2343
+ var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right;
2344
+
2345
+ function add(left, top, width, bottom) {
2346
+ if (top < 0) top = 0;
2347
+ top = Math.round(top);
2348
+ bottom = Math.round(bottom);
2349
+ fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left +
2350
+ "px; top: " + top + "px; width: " + (width == null ? rightSide - left : width) +
2351
+ "px; height: " + (bottom - top) + "px"));
2352
+ }
2353
+
2354
+ function drawForLine(line, fromArg, toArg) {
2355
+ var lineObj = getLine(doc, line);
2356
+ var lineLen = lineObj.text.length;
2357
+ var start, end;
2358
+ function coords(ch, bias) {
2359
+ return charCoords(cm, Pos(line, ch), "div", lineObj, bias);
2360
+ }
2361
+
2362
+ iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) {
2363
+ var leftPos = coords(from, "left"), rightPos, left, right;
2364
+ if (from == to) {
2365
+ rightPos = leftPos;
2366
+ left = right = leftPos.left;
2367
+ } else {
2368
+ rightPos = coords(to - 1, "right");
2369
+ if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; }
2370
+ left = leftPos.left;
2371
+ right = rightPos.right;
2372
+ }
2373
+ if (fromArg == null && from == 0) left = leftSide;
2374
+ if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part
2375
+ add(left, leftPos.top, null, leftPos.bottom);
2376
+ left = leftSide;
2377
+ if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top);
2378
+ }
2379
+ if (toArg == null && to == lineLen) right = rightSide;
2380
+ if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)
2381
+ start = leftPos;
2382
+ if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)
2383
+ end = rightPos;
2384
+ if (left < leftSide + 1) left = leftSide;
2385
+ add(left, rightPos.top, right - left, rightPos.bottom);
2386
+ });
2387
+ return {start: start, end: end};
2388
+ }
2389
+
2390
+ var sFrom = range.from(), sTo = range.to();
2391
+ if (sFrom.line == sTo.line) {
2392
+ drawForLine(sFrom.line, sFrom.ch, sTo.ch);
2393
+ } else {
2394
+ var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line);
2395
+ var singleVLine = visualLine(fromLine) == visualLine(toLine);
2396
+ var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end;
2397
+ var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start;
2398
+ if (singleVLine) {
2399
+ if (leftEnd.top < rightStart.top - 2) {
2400
+ add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);
2401
+ add(leftSide, rightStart.top, rightStart.left, rightStart.bottom);
2402
+ } else {
2403
+ add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);
2404
+ }
2405
+ }
2406
+ if (leftEnd.bottom < rightStart.top)
2407
+ add(leftSide, leftEnd.bottom, null, rightStart.top);
2408
+ }
2409
+
2410
+ output.appendChild(fragment);
2411
+ }
2412
+
2413
+ // Cursor-blinking
2414
+ function restartBlink(cm) {
2415
+ if (!cm.state.focused) return;
2416
+ var display = cm.display;
2417
+ clearInterval(display.blinker);
2418
+ var on = true;
2419
+ display.cursorDiv.style.visibility = "";
2420
+ if (cm.options.cursorBlinkRate > 0)
2421
+ display.blinker = setInterval(function() {
2422
+ display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden";
2423
+ }, cm.options.cursorBlinkRate);
2424
+ else if (cm.options.cursorBlinkRate < 0)
2425
+ display.cursorDiv.style.visibility = "hidden";
2426
+ }
2427
+
2428
+ // HIGHLIGHT WORKER
2429
+
2430
+ function startWorker(cm, time) {
2431
+ if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo)
2432
+ cm.state.highlight.set(time, bind(highlightWorker, cm));
2433
+ }
2434
+
2435
+ function highlightWorker(cm) {
2436
+ var doc = cm.doc;
2437
+ if (doc.frontier < doc.first) doc.frontier = doc.first;
2438
+ if (doc.frontier >= cm.display.viewTo) return;
2439
+ var end = +new Date + cm.options.workTime;
2440
+ var state = copyState(doc.mode, getStateBefore(cm, doc.frontier));
2441
+ var changedLines = [];
2442
+
2443
+ doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) {
2444
+ if (doc.frontier >= cm.display.viewFrom) { // Visible
2445
+ var oldStyles = line.styles, tooLong = line.text.length > cm.options.maxHighlightLength;
2446
+ var highlighted = highlightLine(cm, line, tooLong ? copyState(doc.mode, state) : state, true);
2447
+ line.styles = highlighted.styles;
2448
+ var oldCls = line.styleClasses, newCls = highlighted.classes;
2449
+ if (newCls) line.styleClasses = newCls;
2450
+ else if (oldCls) line.styleClasses = null;
2451
+ var ischange = !oldStyles || oldStyles.length != line.styles.length ||
2452
+ oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass);
2453
+ for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];
2454
+ if (ischange) changedLines.push(doc.frontier);
2455
+ line.stateAfter = tooLong ? state : copyState(doc.mode, state);
2456
+ } else {
2457
+ if (line.text.length <= cm.options.maxHighlightLength)
2458
+ processLine(cm, line.text, state);
2459
+ line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;
2460
+ }
2461
+ ++doc.frontier;
2462
+ if (+new Date > end) {
2463
+ startWorker(cm, cm.options.workDelay);
2464
+ return true;
2465
+ }
2466
+ });
2467
+ if (changedLines.length) runInOp(cm, function() {
2468
+ for (var i = 0; i < changedLines.length; i++)
2469
+ regLineChange(cm, changedLines[i], "text");
2470
+ });
2471
+ }
2472
+
2473
+ // Finds the line to start with when starting a parse. Tries to
2474
+ // find a line with a stateAfter, so that it can start with a
2475
+ // valid state. If that fails, it returns the line with the
2476
+ // smallest indentation, which tends to need the least context to
2477
+ // parse correctly.
2478
+ function findStartLine(cm, n, precise) {
2479
+ var minindent, minline, doc = cm.doc;
2480
+ var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100);
2481
+ for (var search = n; search > lim; --search) {
2482
+ if (search <= doc.first) return doc.first;
2483
+ var line = getLine(doc, search - 1);
2484
+ if (line.stateAfter && (!precise || search <= doc.frontier)) return search;
2485
+ var indented = countColumn(line.text, null, cm.options.tabSize);
2486
+ if (minline == null || minindent > indented) {
2487
+ minline = search - 1;
2488
+ minindent = indented;
2489
+ }
2490
+ }
2491
+ return minline;
2492
+ }
2493
+
2494
+ function getStateBefore(cm, n, precise) {
2495
+ var doc = cm.doc, display = cm.display;
2496
+ if (!doc.mode.startState) return true;
2497
+ var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter;
2498
+ if (!state) state = startState(doc.mode);
2499
+ else state = copyState(doc.mode, state);
2500
+ doc.iter(pos, n, function(line) {
2501
+ processLine(cm, line.text, state);
2502
+ var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo;
2503
+ line.stateAfter = save ? copyState(doc.mode, state) : null;
2504
+ ++pos;
2505
+ });
2506
+ if (precise) doc.frontier = pos;
2507
+ return state;
2508
+ }
2509
+
2510
+ // POSITION MEASUREMENT
2511
+
2512
+ function paddingTop(display) {return display.lineSpace.offsetTop;}
2513
+ function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;}
2514
+ function paddingH(display) {
2515
+ if (display.cachedPaddingH) return display.cachedPaddingH;
2516
+ var e = removeChildrenAndAdd(display.measure, elt("pre", "x"));
2517
+ var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle;
2518
+ var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)};
2519
+ if (!isNaN(data.left) && !isNaN(data.right)) display.cachedPaddingH = data;
2520
+ return data;
2521
+ }
2522
+
2523
+ function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth; }
2524
+ function displayWidth(cm) {
2525
+ return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth;
2526
+ }
2527
+ function displayHeight(cm) {
2528
+ return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight;
2529
+ }
2530
+
2531
+ // Ensure the lineView.wrapping.heights array is populated. This is
2532
+ // an array of bottom offsets for the lines that make up a drawn
2533
+ // line. When lineWrapping is on, there might be more than one
2534
+ // height.
2535
+ function ensureLineHeights(cm, lineView, rect) {
2536
+ var wrapping = cm.options.lineWrapping;
2537
+ var curWidth = wrapping && displayWidth(cm);
2538
+ if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) {
2539
+ var heights = lineView.measure.heights = [];
2540
+ if (wrapping) {
2541
+ lineView.measure.width = curWidth;
2542
+ var rects = lineView.text.firstChild.getClientRects();
2543
+ for (var i = 0; i < rects.length - 1; i++) {
2544
+ var cur = rects[i], next = rects[i + 1];
2545
+ if (Math.abs(cur.bottom - next.bottom) > 2)
2546
+ heights.push((cur.bottom + next.top) / 2 - rect.top);
2547
+ }
2548
+ }
2549
+ heights.push(rect.bottom - rect.top);
2550
+ }
2551
+ }
2552
+
2553
+ // Find a line map (mapping character offsets to text nodes) and a
2554
+ // measurement cache for the given line number. (A line view might
2555
+ // contain multiple lines when collapsed ranges are present.)
2556
+ function mapFromLineView(lineView, line, lineN) {
2557
+ if (lineView.line == line)
2558
+ return {map: lineView.measure.map, cache: lineView.measure.cache};
2559
+ for (var i = 0; i < lineView.rest.length; i++)
2560
+ if (lineView.rest[i] == line)
2561
+ return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]};
2562
+ for (var i = 0; i < lineView.rest.length; i++)
2563
+ if (lineNo(lineView.rest[i]) > lineN)
2564
+ return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true};
2565
+ }
2566
+
2567
+ // Render a line into the hidden node display.externalMeasured. Used
2568
+ // when measurement is needed for a line that's not in the viewport.
2569
+ function updateExternalMeasurement(cm, line) {
2570
+ line = visualLine(line);
2571
+ var lineN = lineNo(line);
2572
+ var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN);
2573
+ view.lineN = lineN;
2574
+ var built = view.built = buildLineContent(cm, view);
2575
+ view.text = built.pre;
2576
+ removeChildrenAndAdd(cm.display.lineMeasure, built.pre);
2577
+ return view;
2578
+ }
2579
+
2580
+ // Get a {top, bottom, left, right} box (in line-local coordinates)
2581
+ // for a given character.
2582
+ function measureChar(cm, line, ch, bias) {
2583
+ return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias);
2584
+ }
2585
+
2586
+ // Find a line view that corresponds to the given line number.
2587
+ function findViewForLine(cm, lineN) {
2588
+ if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo)
2589
+ return cm.display.view[findViewIndex(cm, lineN)];
2590
+ var ext = cm.display.externalMeasured;
2591
+ if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size)
2592
+ return ext;
2593
+ }
2594
+
2595
+ // Measurement can be split in two steps, the set-up work that
2596
+ // applies to the whole line, and the measurement of the actual
2597
+ // character. Functions like coordsChar, that need to do a lot of
2598
+ // measurements in a row, can thus ensure that the set-up work is
2599
+ // only done once.
2600
+ function prepareMeasureForLine(cm, line) {
2601
+ var lineN = lineNo(line);
2602
+ var view = findViewForLine(cm, lineN);
2603
+ if (view && !view.text) {
2604
+ view = null;
2605
+ } else if (view && view.changes) {
2606
+ updateLineForChanges(cm, view, lineN, getDimensions(cm));
2607
+ cm.curOp.forceUpdate = true;
2608
+ }
2609
+ if (!view)
2610
+ view = updateExternalMeasurement(cm, line);
2611
+
2612
+ var info = mapFromLineView(view, line, lineN);
2613
+ return {
2614
+ line: line, view: view, rect: null,
2615
+ map: info.map, cache: info.cache, before: info.before,
2616
+ hasHeights: false
2617
+ };
2618
+ }
2619
+
2620
+ // Given a prepared measurement object, measures the position of an
2621
+ // actual character (or fetches it from the cache).
2622
+ function measureCharPrepared(cm, prepared, ch, bias, varHeight) {
2623
+ if (prepared.before) ch = -1;
2624
+ var key = ch + (bias || ""), found;
2625
+ if (prepared.cache.hasOwnProperty(key)) {
2626
+ found = prepared.cache[key];
2627
+ } else {
2628
+ if (!prepared.rect)
2629
+ prepared.rect = prepared.view.text.getBoundingClientRect();
2630
+ if (!prepared.hasHeights) {
2631
+ ensureLineHeights(cm, prepared.view, prepared.rect);
2632
+ prepared.hasHeights = true;
2633
+ }
2634
+ found = measureCharInner(cm, prepared, ch, bias);
2635
+ if (!found.bogus) prepared.cache[key] = found;
2636
+ }
2637
+ return {left: found.left, right: found.right,
2638
+ top: varHeight ? found.rtop : found.top,
2639
+ bottom: varHeight ? found.rbottom : found.bottom};
2640
+ }
2641
+
2642
+ var nullRect = {left: 0, right: 0, top: 0, bottom: 0};
2643
+
2644
+ function nodeAndOffsetInLineMap(map, ch, bias) {
2645
+ var node, start, end, collapse;
2646
+ // First, search the line map for the text node corresponding to,
2647
+ // or closest to, the target character.
2648
+ for (var i = 0; i < map.length; i += 3) {
2649
+ var mStart = map[i], mEnd = map[i + 1];
2650
+ if (ch < mStart) {
2651
+ start = 0; end = 1;
2652
+ collapse = "left";
2653
+ } else if (ch < mEnd) {
2654
+ start = ch - mStart;
2655
+ end = start + 1;
2656
+ } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) {
2657
+ end = mEnd - mStart;
2658
+ start = end - 1;
2659
+ if (ch >= mEnd) collapse = "right";
2660
+ }
2661
+ if (start != null) {
2662
+ node = map[i + 2];
2663
+ if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right"))
2664
+ collapse = bias;
2665
+ if (bias == "left" && start == 0)
2666
+ while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) {
2667
+ node = map[(i -= 3) + 2];
2668
+ collapse = "left";
2669
+ }
2670
+ if (bias == "right" && start == mEnd - mStart)
2671
+ while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) {
2672
+ node = map[(i += 3) + 2];
2673
+ collapse = "right";
2674
+ }
2675
+ break;
2676
+ }
2677
+ }
2678
+ return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd};
2679
+ }
2680
+
2681
+ function measureCharInner(cm, prepared, ch, bias) {
2682
+ var place = nodeAndOffsetInLineMap(prepared.map, ch, bias);
2683
+ var node = place.node, start = place.start, end = place.end, collapse = place.collapse;
2684
+
2685
+ var rect;
2686
+ if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates.
2687
+ for (var i = 0; i < 4; i++) { // Retry a maximum of 4 times when nonsense rectangles are returned
2688
+ while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) --start;
2689
+ while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) ++end;
2690
+ if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart) {
2691
+ rect = node.parentNode.getBoundingClientRect();
2692
+ } else if (ie && cm.options.lineWrapping) {
2693
+ var rects = range(node, start, end).getClientRects();
2694
+ if (rects.length)
2695
+ rect = rects[bias == "right" ? rects.length - 1 : 0];
2696
+ else
2697
+ rect = nullRect;
2698
+ } else {
2699
+ rect = range(node, start, end).getBoundingClientRect() || nullRect;
2700
+ }
2701
+ if (rect.left || rect.right || start == 0) break;
2702
+ end = start;
2703
+ start = start - 1;
2704
+ collapse = "right";
2705
+ }
2706
+ if (ie && ie_version < 11) rect = maybeUpdateRectForZooming(cm.display.measure, rect);
2707
+ } else { // If it is a widget, simply get the box for the whole widget.
2708
+ if (start > 0) collapse = bias = "right";
2709
+ var rects;
2710
+ if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1)
2711
+ rect = rects[bias == "right" ? rects.length - 1 : 0];
2712
+ else
2713
+ rect = node.getBoundingClientRect();
2714
+ }
2715
+ if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) {
2716
+ var rSpan = node.parentNode.getClientRects()[0];
2717
+ if (rSpan)
2718
+ rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom};
2719
+ else
2720
+ rect = nullRect;
2721
+ }
2722
+
2723
+ var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top;
2724
+ var mid = (rtop + rbot) / 2;
2725
+ var heights = prepared.view.measure.heights;
2726
+ for (var i = 0; i < heights.length - 1; i++)
2727
+ if (mid < heights[i]) break;
2728
+ var top = i ? heights[i - 1] : 0, bot = heights[i];
2729
+ var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left,
2730
+ right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left,
2731
+ top: top, bottom: bot};
2732
+ if (!rect.left && !rect.right) result.bogus = true;
2733
+ if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; }
2734
+
2735
+ return result;
2736
+ }
2737
+
2738
+ // Work around problem with bounding client rects on ranges being
2739
+ // returned incorrectly when zoomed on IE10 and below.
2740
+ function maybeUpdateRectForZooming(measure, rect) {
2741
+ if (!window.screen || screen.logicalXDPI == null ||
2742
+ screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure))
2743
+ return rect;
2744
+ var scaleX = screen.logicalXDPI / screen.deviceXDPI;
2745
+ var scaleY = screen.logicalYDPI / screen.deviceYDPI;
2746
+ return {left: rect.left * scaleX, right: rect.right * scaleX,
2747
+ top: rect.top * scaleY, bottom: rect.bottom * scaleY};
2748
+ }
2749
+
2750
+ function clearLineMeasurementCacheFor(lineView) {
2751
+ if (lineView.measure) {
2752
+ lineView.measure.cache = {};
2753
+ lineView.measure.heights = null;
2754
+ if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)
2755
+ lineView.measure.caches[i] = {};
2756
+ }
2757
+ }
2758
+
2759
+ function clearLineMeasurementCache(cm) {
2760
+ cm.display.externalMeasure = null;
2761
+ removeChildren(cm.display.lineMeasure);
2762
+ for (var i = 0; i < cm.display.view.length; i++)
2763
+ clearLineMeasurementCacheFor(cm.display.view[i]);
2764
+ }
2765
+
2766
+ function clearCaches(cm) {
2767
+ clearLineMeasurementCache(cm);
2768
+ cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null;
2769
+ if (!cm.options.lineWrapping) cm.display.maxLineChanged = true;
2770
+ cm.display.lineNumChars = null;
2771
+ }
2772
+
2773
+ function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; }
2774
+ function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; }
2775
+
2776
+ // Converts a {top, bottom, left, right} box from line-local
2777
+ // coordinates into another coordinate system. Context may be one of
2778
+ // "line", "div" (display.lineDiv), "local"/null (editor), "window",
2779
+ // or "page".
2780
+ function intoCoordSystem(cm, lineObj, rect, context) {
2781
+ if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) {
2782
+ var size = widgetHeight(lineObj.widgets[i]);
2783
+ rect.top += size; rect.bottom += size;
2784
+ }
2785
+ if (context == "line") return rect;
2786
+ if (!context) context = "local";
2787
+ var yOff = heightAtLine(lineObj);
2788
+ if (context == "local") yOff += paddingTop(cm.display);
2789
+ else yOff -= cm.display.viewOffset;
2790
+ if (context == "page" || context == "window") {
2791
+ var lOff = cm.display.lineSpace.getBoundingClientRect();
2792
+ yOff += lOff.top + (context == "window" ? 0 : pageScrollY());
2793
+ var xOff = lOff.left + (context == "window" ? 0 : pageScrollX());
2794
+ rect.left += xOff; rect.right += xOff;
2795
+ }
2796
+ rect.top += yOff; rect.bottom += yOff;
2797
+ return rect;
2798
+ }
2799
+
2800
+ // Coverts a box from "div" coords to another coordinate system.
2801
+ // Context may be "window", "page", "div", or "local"/null.
2802
+ function fromCoordSystem(cm, coords, context) {
2803
+ if (context == "div") return coords;
2804
+ var left = coords.left, top = coords.top;
2805
+ // First move into "page" coordinate system
2806
+ if (context == "page") {
2807
+ left -= pageScrollX();
2808
+ top -= pageScrollY();
2809
+ } else if (context == "local" || !context) {
2810
+ var localBox = cm.display.sizer.getBoundingClientRect();
2811
+ left += localBox.left;
2812
+ top += localBox.top;
2813
+ }
2814
+
2815
+ var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect();
2816
+ return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top};
2817
+ }
2818
+
2819
+ function charCoords(cm, pos, context, lineObj, bias) {
2820
+ if (!lineObj) lineObj = getLine(cm.doc, pos.line);
2821
+ return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context);
2822
+ }
2823
+
2824
+ // Returns a box for a given cursor position, which may have an
2825
+ // 'other' property containing the position of the secondary cursor
2826
+ // on a bidi boundary.
2827
+ function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) {
2828
+ lineObj = lineObj || getLine(cm.doc, pos.line);
2829
+ if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj);
2830
+ function get(ch, right) {
2831
+ var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight);
2832
+ if (right) m.left = m.right; else m.right = m.left;
2833
+ return intoCoordSystem(cm, lineObj, m, context);
2834
+ }
2835
+ function getBidi(ch, partPos) {
2836
+ var part = order[partPos], right = part.level % 2;
2837
+ if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) {
2838
+ part = order[--partPos];
2839
+ ch = bidiRight(part) - (part.level % 2 ? 0 : 1);
2840
+ right = true;
2841
+ } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) {
2842
+ part = order[++partPos];
2843
+ ch = bidiLeft(part) - part.level % 2;
2844
+ right = false;
2845
+ }
2846
+ if (right && ch == part.to && ch > part.from) return get(ch - 1);
2847
+ return get(ch, right);
2848
+ }
2849
+ var order = getOrder(lineObj), ch = pos.ch;
2850
+ if (!order) return get(ch);
2851
+ var partPos = getBidiPartAt(order, ch);
2852
+ var val = getBidi(ch, partPos);
2853
+ if (bidiOther != null) val.other = getBidi(ch, bidiOther);
2854
+ return val;
2855
+ }
2856
+
2857
+ // Used to cheaply estimate the coordinates for a position. Used for
2858
+ // intermediate scroll updates.
2859
+ function estimateCoords(cm, pos) {
2860
+ var left = 0, pos = clipPos(cm.doc, pos);
2861
+ if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch;
2862
+ var lineObj = getLine(cm.doc, pos.line);
2863
+ var top = heightAtLine(lineObj) + paddingTop(cm.display);
2864
+ return {left: left, right: left, top: top, bottom: top + lineObj.height};
2865
+ }
2866
+
2867
+ // Positions returned by coordsChar contain some extra information.
2868
+ // xRel is the relative x position of the input coordinates compared
2869
+ // to the found position (so xRel > 0 means the coordinates are to
2870
+ // the right of the character position, for example). When outside
2871
+ // is true, that means the coordinates lie outside the line's
2872
+ // vertical range.
2873
+ function PosWithInfo(line, ch, outside, xRel) {
2874
+ var pos = Pos(line, ch);
2875
+ pos.xRel = xRel;
2876
+ if (outside) pos.outside = true;
2877
+ return pos;
2878
+ }
2879
+
2880
+ // Compute the character position closest to the given coordinates.
2881
+ // Input must be lineSpace-local ("div" coordinate system).
2882
+ function coordsChar(cm, x, y) {
2883
+ var doc = cm.doc;
2884
+ y += cm.display.viewOffset;
2885
+ if (y < 0) return PosWithInfo(doc.first, 0, true, -1);
2886
+ var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
2887
+ if (lineN > last)
2888
+ return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1);
2889
+ if (x < 0) x = 0;
2890
+
2891
+ var lineObj = getLine(doc, lineN);
2892
+ for (;;) {
2893
+ var found = coordsCharInner(cm, lineObj, lineN, x, y);
2894
+ var merged = collapsedSpanAtEnd(lineObj);
2895
+ var mergedPos = merged && merged.find(0, true);
2896
+ if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))
2897
+ lineN = lineNo(lineObj = mergedPos.to.line);
2898
+ else
2899
+ return found;
2900
+ }
2901
+ }
2902
+
2903
+ function coordsCharInner(cm, lineObj, lineNo, x, y) {
2904
+ var innerOff = y - heightAtLine(lineObj);
2905
+ var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth;
2906
+ var preparedMeasure = prepareMeasureForLine(cm, lineObj);
2907
+
2908
+ function getX(ch) {
2909
+ var sp = cursorCoords(cm, Pos(lineNo, ch), "line", lineObj, preparedMeasure);
2910
+ wrongLine = true;
2911
+ if (innerOff > sp.bottom) return sp.left - adjust;
2912
+ else if (innerOff < sp.top) return sp.left + adjust;
2913
+ else wrongLine = false;
2914
+ return sp.left;
2915
+ }
2916
+
2917
+ var bidi = getOrder(lineObj), dist = lineObj.text.length;
2918
+ var from = lineLeft(lineObj), to = lineRight(lineObj);
2919
+ var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine;
2920
+
2921
+ if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1);
2922
+ // Do a binary search between these bounds.
2923
+ for (;;) {
2924
+ if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {
2925
+ var ch = x < fromX || x - fromX <= toX - x ? from : to;
2926
+ var xDiff = x - (ch == from ? fromX : toX);
2927
+ while (isExtendingChar(lineObj.text.charAt(ch))) ++ch;
2928
+ var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside,
2929
+ xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0);
2930
+ return pos;
2931
+ }
2932
+ var step = Math.ceil(dist / 2), middle = from + step;
2933
+ if (bidi) {
2934
+ middle = from;
2935
+ for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1);
2936
+ }
2937
+ var middleX = getX(middle);
2938
+ if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;}
2939
+ else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;}
2940
+ }
2941
+ }
2942
+
2943
+ var measureText;
2944
+ // Compute the default text height.
2945
+ function textHeight(display) {
2946
+ if (display.cachedTextHeight != null) return display.cachedTextHeight;
2947
+ if (measureText == null) {
2948
+ measureText = elt("pre");
2949
+ // Measure a bunch of lines, for browsers that compute
2950
+ // fractional heights.
2951
+ for (var i = 0; i < 49; ++i) {
2952
+ measureText.appendChild(document.createTextNode("x"));
2953
+ measureText.appendChild(elt("br"));
2954
+ }
2955
+ measureText.appendChild(document.createTextNode("x"));
2956
+ }
2957
+ removeChildrenAndAdd(display.measure, measureText);
2958
+ var height = measureText.offsetHeight / 50;
2959
+ if (height > 3) display.cachedTextHeight = height;
2960
+ removeChildren(display.measure);
2961
+ return height || 1;
2962
+ }
2963
+
2964
+ // Compute the default character width.
2965
+ function charWidth(display) {
2966
+ if (display.cachedCharWidth != null) return display.cachedCharWidth;
2967
+ var anchor = elt("span", "xxxxxxxxxx");
2968
+ var pre = elt("pre", [anchor]);
2969
+ removeChildrenAndAdd(display.measure, pre);
2970
+ var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10;
2971
+ if (width > 2) display.cachedCharWidth = width;
2972
+ return width || 10;
2973
+ }
2974
+
2975
+ // OPERATIONS
2976
+
2977
+ // Operations are used to wrap a series of changes to the editor
2978
+ // state in such a way that each change won't have to update the
2979
+ // cursor and display (which would be awkward, slow, and
2980
+ // error-prone). Instead, display updates are batched and then all
2981
+ // combined and executed at once.
2982
+
2983
+ var operationGroup = null;
2984
+
2985
+ var nextOpId = 0;
2986
+ // Start a new operation.
2987
+ function startOperation(cm) {
2988
+ cm.curOp = {
2989
+ cm: cm,
2990
+ viewChanged: false, // Flag that indicates that lines might need to be redrawn
2991
+ startHeight: cm.doc.height, // Used to detect need to update scrollbar
2992
+ forceUpdate: false, // Used to force a redraw
2993
+ updateInput: null, // Whether to reset the input textarea
2994
+ typing: false, // Whether this reset should be careful to leave existing text (for compositing)
2995
+ changeObjs: null, // Accumulated changes, for firing change events
2996
+ cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on
2997
+ cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already
2998
+ selectionChanged: false, // Whether the selection needs to be redrawn
2999
+ updateMaxLine: false, // Set when the widest line needs to be determined anew
3000
+ scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet
3001
+ scrollToPos: null, // Used to scroll to a specific position
3002
+ focus: false,
3003
+ id: ++nextOpId // Unique ID
3004
+ };
3005
+ if (operationGroup) {
3006
+ operationGroup.ops.push(cm.curOp);
3007
+ } else {
3008
+ cm.curOp.ownsGroup = operationGroup = {
3009
+ ops: [cm.curOp],
3010
+ delayedCallbacks: []
3011
+ };
3012
+ }
3013
+ }
3014
+
3015
+ function fireCallbacksForOps(group) {
3016
+ // Calls delayed callbacks and cursorActivity handlers until no
3017
+ // new ones appear
3018
+ var callbacks = group.delayedCallbacks, i = 0;
3019
+ do {
3020
+ for (; i < callbacks.length; i++)
3021
+ callbacks[i].call(null);
3022
+ for (var j = 0; j < group.ops.length; j++) {
3023
+ var op = group.ops[j];
3024
+ if (op.cursorActivityHandlers)
3025
+ while (op.cursorActivityCalled < op.cursorActivityHandlers.length)
3026
+ op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm);
3027
+ }
3028
+ } while (i < callbacks.length);
3029
+ }
3030
+
3031
+ // Finish an operation, updating the display and signalling delayed events
3032
+ function endOperation(cm) {
3033
+ var op = cm.curOp, group = op.ownsGroup;
3034
+ if (!group) return;
3035
+
3036
+ try { fireCallbacksForOps(group); }
3037
+ finally {
3038
+ operationGroup = null;
3039
+ for (var i = 0; i < group.ops.length; i++)
3040
+ group.ops[i].cm.curOp = null;
3041
+ endOperations(group);
3042
+ }
3043
+ }
3044
+
3045
+ // The DOM updates done when an operation finishes are batched so
3046
+ // that the minimum number of relayouts are required.
3047
+ function endOperations(group) {
3048
+ var ops = group.ops;
3049
+ for (var i = 0; i < ops.length; i++) // Read DOM
3050
+ endOperation_R1(ops[i]);
3051
+ for (var i = 0; i < ops.length; i++) // Write DOM (maybe)
3052
+ endOperation_W1(ops[i]);
3053
+ for (var i = 0; i < ops.length; i++) // Read DOM
3054
+ endOperation_R2(ops[i]);
3055
+ for (var i = 0; i < ops.length; i++) // Write DOM (maybe)
3056
+ endOperation_W2(ops[i]);
3057
+ for (var i = 0; i < ops.length; i++) // Read DOM
3058
+ endOperation_finish(ops[i]);
3059
+ }
3060
+
3061
+ function endOperation_R1(op) {
3062
+ var cm = op.cm, display = cm.display;
3063
+ maybeClipScrollbars(cm);
3064
+ if (op.updateMaxLine) findMaxLine(cm);
3065
+
3066
+ op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null ||
3067
+ op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom ||
3068
+ op.scrollToPos.to.line >= display.viewTo) ||
3069
+ display.maxLineChanged && cm.options.lineWrapping;
3070
+ op.update = op.mustUpdate &&
3071
+ new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate);
3072
+ }
3073
+
3074
+ function endOperation_W1(op) {
3075
+ op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update);
3076
+ }
3077
+
3078
+ function endOperation_R2(op) {
3079
+ var cm = op.cm, display = cm.display;
3080
+ if (op.updatedDisplay) updateHeightsInViewport(cm);
3081
+
3082
+ op.barMeasure = measureForScrollbars(cm);
3083
+
3084
+ // If the max line changed since it was last measured, measure it,
3085
+ // and ensure the document's width matches it.
3086
+ // updateDisplay_W2 will use these properties to do the actual resizing
3087
+ if (display.maxLineChanged && !cm.options.lineWrapping) {
3088
+ op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3;
3089
+ cm.display.sizerWidth = op.adjustWidthTo;
3090
+ op.barMeasure.scrollWidth =
3091
+ Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth);
3092
+ op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm));
3093
+ }
3094
+
3095
+ if (op.updatedDisplay || op.selectionChanged)
3096
+ op.preparedSelection = display.input.prepareSelection();
3097
+ }
3098
+
3099
+ function endOperation_W2(op) {
3100
+ var cm = op.cm;
3101
+
3102
+ if (op.adjustWidthTo != null) {
3103
+ cm.display.sizer.style.minWidth = op.adjustWidthTo + "px";
3104
+ if (op.maxScrollLeft < cm.doc.scrollLeft)
3105
+ setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true);
3106
+ cm.display.maxLineChanged = false;
3107
+ }
3108
+
3109
+ if (op.preparedSelection)
3110
+ cm.display.input.showSelection(op.preparedSelection);
3111
+ if (op.updatedDisplay)
3112
+ setDocumentHeight(cm, op.barMeasure);
3113
+ if (op.updatedDisplay || op.startHeight != cm.doc.height)
3114
+ updateScrollbars(cm, op.barMeasure);
3115
+
3116
+ if (op.selectionChanged) restartBlink(cm);
3117
+
3118
+ if (cm.state.focused && op.updateInput)
3119
+ cm.display.input.reset(op.typing);
3120
+ if (op.focus && op.focus == activeElt() && (!document.hasFocus || document.hasFocus()))
3121
+ ensureFocus(op.cm);
3122
+ }
3123
+
3124
+ function endOperation_finish(op) {
3125
+ var cm = op.cm, display = cm.display, doc = cm.doc;
3126
+
3127
+ if (op.updatedDisplay) postUpdateDisplay(cm, op.update);
3128
+
3129
+ // Abort mouse wheel delta measurement, when scrolling explicitly
3130
+ if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos))
3131
+ display.wheelStartX = display.wheelStartY = null;
3132
+
3133
+ // Propagate the scroll position to the actual DOM scroller
3134
+ if (op.scrollTop != null && (display.scroller.scrollTop != op.scrollTop || op.forceScroll)) {
3135
+ doc.scrollTop = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop));
3136
+ display.scrollbars.setScrollTop(doc.scrollTop);
3137
+ display.scroller.scrollTop = doc.scrollTop;
3138
+ }
3139
+ if (op.scrollLeft != null && (display.scroller.scrollLeft != op.scrollLeft || op.forceScroll)) {
3140
+ doc.scrollLeft = Math.max(0, Math.min(display.scroller.scrollWidth - displayWidth(cm), op.scrollLeft));
3141
+ display.scrollbars.setScrollLeft(doc.scrollLeft);
3142
+ display.scroller.scrollLeft = doc.scrollLeft;
3143
+ alignHorizontally(cm);
3144
+ }
3145
+ // If we need to scroll a specific position into view, do so.
3146
+ if (op.scrollToPos) {
3147
+ var coords = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from),
3148
+ clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin);
3149
+ if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords);
3150
+ }
3151
+
3152
+ // Fire events for markers that are hidden/unidden by editing or
3153
+ // undoing
3154
+ var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;
3155
+ if (hidden) for (var i = 0; i < hidden.length; ++i)
3156
+ if (!hidden[i].lines.length) signal(hidden[i], "hide");
3157
+ if (unhidden) for (var i = 0; i < unhidden.length; ++i)
3158
+ if (unhidden[i].lines.length) signal(unhidden[i], "unhide");
3159
+
3160
+ if (display.wrapper.offsetHeight)
3161
+ doc.scrollTop = cm.display.scroller.scrollTop;
3162
+
3163
+ // Fire change events, and delayed event handlers
3164
+ if (op.changeObjs)
3165
+ signal(cm, "changes", cm, op.changeObjs);
3166
+ if (op.update)
3167
+ op.update.finish();
3168
+ }
3169
+
3170
+ // Run the given function in an operation
3171
+ function runInOp(cm, f) {
3172
+ if (cm.curOp) return f();
3173
+ startOperation(cm);
3174
+ try { return f(); }
3175
+ finally { endOperation(cm); }
3176
+ }
3177
+ // Wraps a function in an operation. Returns the wrapped function.
3178
+ function operation(cm, f) {
3179
+ return function() {
3180
+ if (cm.curOp) return f.apply(cm, arguments);
3181
+ startOperation(cm);
3182
+ try { return f.apply(cm, arguments); }
3183
+ finally { endOperation(cm); }
3184
+ };
3185
+ }
3186
+ // Used to add methods to editor and doc instances, wrapping them in
3187
+ // operations.
3188
+ function methodOp(f) {
3189
+ return function() {
3190
+ if (this.curOp) return f.apply(this, arguments);
3191
+ startOperation(this);
3192
+ try { return f.apply(this, arguments); }
3193
+ finally { endOperation(this); }
3194
+ };
3195
+ }
3196
+ function docMethodOp(f) {
3197
+ return function() {
3198
+ var cm = this.cm;
3199
+ if (!cm || cm.curOp) return f.apply(this, arguments);
3200
+ startOperation(cm);
3201
+ try { return f.apply(this, arguments); }
3202
+ finally { endOperation(cm); }
3203
+ };
3204
+ }
3205
+
3206
+ // VIEW TRACKING
3207
+
3208
+ // These objects are used to represent the visible (currently drawn)
3209
+ // part of the document. A LineView may correspond to multiple
3210
+ // logical lines, if those are connected by collapsed ranges.
3211
+ function LineView(doc, line, lineN) {
3212
+ // The starting line
3213
+ this.line = line;
3214
+ // Continuing lines, if any
3215
+ this.rest = visualLineContinued(line);
3216
+ // Number of logical lines in this visual line
3217
+ this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1;
3218
+ this.node = this.text = null;
3219
+ this.hidden = lineIsHidden(doc, line);
3220
+ }
3221
+
3222
+ // Create a range of LineView objects for the given lines.
3223
+ function buildViewArray(cm, from, to) {
3224
+ var array = [], nextPos;
3225
+ for (var pos = from; pos < to; pos = nextPos) {
3226
+ var view = new LineView(cm.doc, getLine(cm.doc, pos), pos);
3227
+ nextPos = pos + view.size;
3228
+ array.push(view);
3229
+ }
3230
+ return array;
3231
+ }
3232
+
3233
+ // Updates the display.view data structure for a given change to the
3234
+ // document. From and to are in pre-change coordinates. Lendiff is
3235
+ // the amount of lines added or subtracted by the change. This is
3236
+ // used for changes that span multiple lines, or change the way
3237
+ // lines are divided into visual lines. regLineChange (below)
3238
+ // registers single-line changes.
3239
+ function regChange(cm, from, to, lendiff) {
3240
+ if (from == null) from = cm.doc.first;
3241
+ if (to == null) to = cm.doc.first + cm.doc.size;
3242
+ if (!lendiff) lendiff = 0;
3243
+
3244
+ var display = cm.display;
3245
+ if (lendiff && to < display.viewTo &&
3246
+ (display.updateLineNumbers == null || display.updateLineNumbers > from))
3247
+ display.updateLineNumbers = from;
3248
+
3249
+ cm.curOp.viewChanged = true;
3250
+
3251
+ if (from >= display.viewTo) { // Change after
3252
+ if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo)
3253
+ resetView(cm);
3254
+ } else if (to <= display.viewFrom) { // Change before
3255
+ if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) {
3256
+ resetView(cm);
3257
+ } else {
3258
+ display.viewFrom += lendiff;
3259
+ display.viewTo += lendiff;
3260
+ }
3261
+ } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap
3262
+ resetView(cm);
3263
+ } else if (from <= display.viewFrom) { // Top overlap
3264
+ var cut = viewCuttingPoint(cm, to, to + lendiff, 1);
3265
+ if (cut) {
3266
+ display.view = display.view.slice(cut.index);
3267
+ display.viewFrom = cut.lineN;
3268
+ display.viewTo += lendiff;
3269
+ } else {
3270
+ resetView(cm);
3271
+ }
3272
+ } else if (to >= display.viewTo) { // Bottom overlap
3273
+ var cut = viewCuttingPoint(cm, from, from, -1);
3274
+ if (cut) {
3275
+ display.view = display.view.slice(0, cut.index);
3276
+ display.viewTo = cut.lineN;
3277
+ } else {
3278
+ resetView(cm);
3279
+ }
3280
+ } else { // Gap in the middle
3281
+ var cutTop = viewCuttingPoint(cm, from, from, -1);
3282
+ var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1);
3283
+ if (cutTop && cutBot) {
3284
+ display.view = display.view.slice(0, cutTop.index)
3285
+ .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN))
3286
+ .concat(display.view.slice(cutBot.index));
3287
+ display.viewTo += lendiff;
3288
+ } else {
3289
+ resetView(cm);
3290
+ }
3291
+ }
3292
+
3293
+ var ext = display.externalMeasured;
3294
+ if (ext) {
3295
+ if (to < ext.lineN)
3296
+ ext.lineN += lendiff;
3297
+ else if (from < ext.lineN + ext.size)
3298
+ display.externalMeasured = null;
3299
+ }
3300
+ }
3301
+
3302
+ // Register a change to a single line. Type must be one of "text",
3303
+ // "gutter", "class", "widget"
3304
+ function regLineChange(cm, line, type) {
3305
+ cm.curOp.viewChanged = true;
3306
+ var display = cm.display, ext = cm.display.externalMeasured;
3307
+ if (ext && line >= ext.lineN && line < ext.lineN + ext.size)
3308
+ display.externalMeasured = null;
3309
+
3310
+ if (line < display.viewFrom || line >= display.viewTo) return;
3311
+ var lineView = display.view[findViewIndex(cm, line)];
3312
+ if (lineView.node == null) return;
3313
+ var arr = lineView.changes || (lineView.changes = []);
3314
+ if (indexOf(arr, type) == -1) arr.push(type);
3315
+ }
3316
+
3317
+ // Clear the view.
3318
+ function resetView(cm) {
3319
+ cm.display.viewFrom = cm.display.viewTo = cm.doc.first;
3320
+ cm.display.view = [];
3321
+ cm.display.viewOffset = 0;
3322
+ }
3323
+
3324
+ // Find the view element corresponding to a given line. Return null
3325
+ // when the line isn't visible.
3326
+ function findViewIndex(cm, n) {
3327
+ if (n >= cm.display.viewTo) return null;
3328
+ n -= cm.display.viewFrom;
3329
+ if (n < 0) return null;
3330
+ var view = cm.display.view;
3331
+ for (var i = 0; i < view.length; i++) {
3332
+ n -= view[i].size;
3333
+ if (n < 0) return i;
3334
+ }
3335
+ }
3336
+
3337
+ function viewCuttingPoint(cm, oldN, newN, dir) {
3338
+ var index = findViewIndex(cm, oldN), diff, view = cm.display.view;
3339
+ if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size)
3340
+ return {index: index, lineN: newN};
3341
+ for (var i = 0, n = cm.display.viewFrom; i < index; i++)
3342
+ n += view[i].size;
3343
+ if (n != oldN) {
3344
+ if (dir > 0) {
3345
+ if (index == view.length - 1) return null;
3346
+ diff = (n + view[index].size) - oldN;
3347
+ index++;
3348
+ } else {
3349
+ diff = n - oldN;
3350
+ }
3351
+ oldN += diff; newN += diff;
3352
+ }
3353
+ while (visualLineNo(cm.doc, newN) != newN) {
3354
+ if (index == (dir < 0 ? 0 : view.length - 1)) return null;
3355
+ newN += dir * view[index - (dir < 0 ? 1 : 0)].size;
3356
+ index += dir;
3357
+ }
3358
+ return {index: index, lineN: newN};
3359
+ }
3360
+
3361
+ // Force the view to cover a given range, adding empty view element
3362
+ // or clipping off existing ones as needed.
3363
+ function adjustView(cm, from, to) {
3364
+ var display = cm.display, view = display.view;
3365
+ if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) {
3366
+ display.view = buildViewArray(cm, from, to);
3367
+ display.viewFrom = from;
3368
+ } else {
3369
+ if (display.viewFrom > from)
3370
+ display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view);
3371
+ else if (display.viewFrom < from)
3372
+ display.view = display.view.slice(findViewIndex(cm, from));
3373
+ display.viewFrom = from;
3374
+ if (display.viewTo < to)
3375
+ display.view = display.view.concat(buildViewArray(cm, display.viewTo, to));
3376
+ else if (display.viewTo > to)
3377
+ display.view = display.view.slice(0, findViewIndex(cm, to));
3378
+ }
3379
+ display.viewTo = to;
3380
+ }
3381
+
3382
+ // Count the number of lines in the view whose DOM representation is
3383
+ // out of date (or nonexistent).
3384
+ function countDirtyView(cm) {
3385
+ var view = cm.display.view, dirty = 0;
3386
+ for (var i = 0; i < view.length; i++) {
3387
+ var lineView = view[i];
3388
+ if (!lineView.hidden && (!lineView.node || lineView.changes)) ++dirty;
3389
+ }
3390
+ return dirty;
3391
+ }
3392
+
3393
+ // EVENT HANDLERS
3394
+
3395
+ // Attach the necessary event handlers when initializing the editor
3396
+ function registerEventHandlers(cm) {
3397
+ var d = cm.display;
3398
+ on(d.scroller, "mousedown", operation(cm, onMouseDown));
3399
+ // Older IE's will not fire a second mousedown for a double click
3400
+ if (ie && ie_version < 11)
3401
+ on(d.scroller, "dblclick", operation(cm, function(e) {
3402
+ if (signalDOMEvent(cm, e)) return;
3403
+ var pos = posFromMouse(cm, e);
3404
+ if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return;
3405
+ e_preventDefault(e);
3406
+ var word = cm.findWordAt(pos);
3407
+ extendSelection(cm.doc, word.anchor, word.head);
3408
+ }));
3409
+ else
3410
+ on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); });
3411
+ // Some browsers fire contextmenu *after* opening the menu, at
3412
+ // which point we can't mess with it anymore. Context menu is
3413
+ // handled in onMouseDown for these browsers.
3414
+ if (!captureRightClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);});
3415
+
3416
+ // Used to suppress mouse event handling when a touch happens
3417
+ var touchFinished, prevTouch = {end: 0};
3418
+ function finishTouch() {
3419
+ if (d.activeTouch) {
3420
+ touchFinished = setTimeout(function() {d.activeTouch = null;}, 1000);
3421
+ prevTouch = d.activeTouch;
3422
+ prevTouch.end = +new Date;
3423
+ }
3424
+ };
3425
+ function isMouseLikeTouchEvent(e) {
3426
+ if (e.touches.length != 1) return false;
3427
+ var touch = e.touches[0];
3428
+ return touch.radiusX <= 1 && touch.radiusY <= 1;
3429
+ }
3430
+ function farAway(touch, other) {
3431
+ if (other.left == null) return true;
3432
+ var dx = other.left - touch.left, dy = other.top - touch.top;
3433
+ return dx * dx + dy * dy > 20 * 20;
3434
+ }
3435
+ on(d.scroller, "touchstart", function(e) {
3436
+ if (!isMouseLikeTouchEvent(e)) {
3437
+ clearTimeout(touchFinished);
3438
+ var now = +new Date;
3439
+ d.activeTouch = {start: now, moved: false,
3440
+ prev: now - prevTouch.end <= 300 ? prevTouch : null};
3441
+ if (e.touches.length == 1) {
3442
+ d.activeTouch.left = e.touches[0].pageX;
3443
+ d.activeTouch.top = e.touches[0].pageY;
3444
+ }
3445
+ }
3446
+ });
3447
+ on(d.scroller, "touchmove", function() {
3448
+ if (d.activeTouch) d.activeTouch.moved = true;
3449
+ });
3450
+ on(d.scroller, "touchend", function(e) {
3451
+ var touch = d.activeTouch;
3452
+ if (touch && !eventInWidget(d, e) && touch.left != null &&
3453
+ !touch.moved && new Date - touch.start < 300) {
3454
+ var pos = cm.coordsChar(d.activeTouch, "page"), range;
3455
+ if (!touch.prev || farAway(touch, touch.prev)) // Single tap
3456
+ range = new Range(pos, pos);
3457
+ else if (!touch.prev.prev || farAway(touch, touch.prev.prev)) // Double tap
3458
+ range = cm.findWordAt(pos);
3459
+ else // Triple tap
3460
+ range = new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0)));
3461
+ cm.setSelection(range.anchor, range.head);
3462
+ cm.focus();
3463
+ e_preventDefault(e);
3464
+ }
3465
+ finishTouch();
3466
+ });
3467
+ on(d.scroller, "touchcancel", finishTouch);
3468
+
3469
+ // Sync scrolling between fake scrollbars and real scrollable
3470
+ // area, ensure viewport is updated when scrolling.
3471
+ on(d.scroller, "scroll", function() {
3472
+ if (d.scroller.clientHeight) {
3473
+ setScrollTop(cm, d.scroller.scrollTop);
3474
+ setScrollLeft(cm, d.scroller.scrollLeft, true);
3475
+ signal(cm, "scroll", cm);
3476
+ }
3477
+ });
3478
+
3479
+ // Listen to wheel events in order to try and update the viewport on time.
3480
+ on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);});
3481
+ on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);});
3482
+
3483
+ // Prevent wrapper from ever scrolling
3484
+ on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
3485
+
3486
+ d.dragFunctions = {
3487
+ enter: function(e) {if (!signalDOMEvent(cm, e)) e_stop(e);},
3488
+ over: function(e) {if (!signalDOMEvent(cm, e)) { onDragOver(cm, e); e_stop(e); }},
3489
+ start: function(e){onDragStart(cm, e);},
3490
+ drop: operation(cm, onDrop),
3491
+ leave: function() {clearDragCursor(cm);}
3492
+ };
3493
+
3494
+ var inp = d.input.getField();
3495
+ on(inp, "keyup", function(e) { onKeyUp.call(cm, e); });
3496
+ on(inp, "keydown", operation(cm, onKeyDown));
3497
+ on(inp, "keypress", operation(cm, onKeyPress));
3498
+ on(inp, "focus", bind(onFocus, cm));
3499
+ on(inp, "blur", bind(onBlur, cm));
3500
+ }
3501
+
3502
+ function dragDropChanged(cm, value, old) {
3503
+ var wasOn = old && old != CodeMirror.Init;
3504
+ if (!value != !wasOn) {
3505
+ var funcs = cm.display.dragFunctions;
3506
+ var toggle = value ? on : off;
3507
+ toggle(cm.display.scroller, "dragstart", funcs.start);
3508
+ toggle(cm.display.scroller, "dragenter", funcs.enter);
3509
+ toggle(cm.display.scroller, "dragover", funcs.over);
3510
+ toggle(cm.display.scroller, "dragleave", funcs.leave);
3511
+ toggle(cm.display.scroller, "drop", funcs.drop);
3512
+ }
3513
+ }
3514
+
3515
+ // Called when the window resizes
3516
+ function onResize(cm) {
3517
+ var d = cm.display;
3518
+ if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth)
3519
+ return;
3520
+ // Might be a text scaling operation, clear size caches.
3521
+ d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
3522
+ d.scrollbarsClipped = false;
3523
+ cm.setSize();
3524
+ }
3525
+
3526
+ // MOUSE EVENTS
3527
+
3528
+ // Return true when the given mouse event happened in a widget
3529
+ function eventInWidget(display, e) {
3530
+ for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
3531
+ if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") ||
3532
+ (n.parentNode == display.sizer && n != display.mover))
3533
+ return true;
3534
+ }
3535
+ }
3536
+
3537
+ // Given a mouse event, find the corresponding position. If liberal
3538
+ // is false, it checks whether a gutter or scrollbar was clicked,
3539
+ // and returns null if it was. forRect is used by rectangular
3540
+ // selections, and tries to estimate a character position even for
3541
+ // coordinates beyond the right of the text.
3542
+ function posFromMouse(cm, e, liberal, forRect) {
3543
+ var display = cm.display;
3544
+ if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") return null;
3545
+
3546
+ var x, y, space = display.lineSpace.getBoundingClientRect();
3547
+ // Fails unpredictably on IE[67] when mouse is dragged around quickly.
3548
+ try { x = e.clientX - space.left; y = e.clientY - space.top; }
3549
+ catch (e) { return null; }
3550
+ var coords = coordsChar(cm, x, y), line;
3551
+ if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
3552
+ var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length;
3553
+ coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff));
3554
+ }
3555
+ return coords;
3556
+ }
3557
+
3558
+ // A mouse down can be a single click, double click, triple click,
3559
+ // start of selection drag, start of text drag, new cursor
3560
+ // (ctrl-click), rectangle drag (alt-drag), or xwin
3561
+ // middle-click-paste. Or it might be a click on something we should
3562
+ // not interfere with, such as a scrollbar or widget.
3563
+ function onMouseDown(e) {
3564
+ var cm = this, display = cm.display;
3565
+ if (display.activeTouch && display.input.supportsTouch() || signalDOMEvent(cm, e)) return;
3566
+ display.shift = e.shiftKey;
3567
+
3568
+ if (eventInWidget(display, e)) {
3569
+ if (!webkit) {
3570
+ // Briefly turn off draggability, to allow widgets to do
3571
+ // normal dragging things.
3572
+ display.scroller.draggable = false;
3573
+ setTimeout(function(){display.scroller.draggable = true;}, 100);
3574
+ }
3575
+ return;
3576
+ }
3577
+ if (clickInGutter(cm, e)) return;
3578
+ var start = posFromMouse(cm, e);
3579
+ window.focus();
3580
+
3581
+ switch (e_button(e)) {
3582
+ case 1:
3583
+ // #3261: make sure, that we're not starting a second selection
3584
+ if (cm.state.selectingText)
3585
+ cm.state.selectingText(e);
3586
+ else if (start)
3587
+ leftButtonDown(cm, e, start);
3588
+ else if (e_target(e) == display.scroller)
3589
+ e_preventDefault(e);
3590
+ break;
3591
+ case 2:
3592
+ if (webkit) cm.state.lastMiddleDown = +new Date;
3593
+ if (start) extendSelection(cm.doc, start);
3594
+ setTimeout(function() {display.input.focus();}, 20);
3595
+ e_preventDefault(e);
3596
+ break;
3597
+ case 3:
3598
+ if (captureRightClick) onContextMenu(cm, e);
3599
+ else delayBlurEvent(cm);
3600
+ break;
3601
+ }
3602
+ }
3603
+
3604
+ var lastClick, lastDoubleClick;
3605
+ function leftButtonDown(cm, e, start) {
3606
+ if (ie) setTimeout(bind(ensureFocus, cm), 0);
3607
+ else cm.curOp.focus = activeElt();
3608
+
3609
+ var now = +new Date, type;
3610
+ if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) {
3611
+ type = "triple";
3612
+ } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) {
3613
+ type = "double";
3614
+ lastDoubleClick = {time: now, pos: start};
3615
+ } else {
3616
+ type = "single";
3617
+ lastClick = {time: now, pos: start};
3618
+ }
3619
+
3620
+ var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey, contained;
3621
+ if (cm.options.dragDrop && dragAndDrop && !cm.isReadOnly() &&
3622
+ type == "single" && (contained = sel.contains(start)) > -1 &&
3623
+ (cmp((contained = sel.ranges[contained]).from(), start) < 0 || start.xRel > 0) &&
3624
+ (cmp(contained.to(), start) > 0 || start.xRel < 0))
3625
+ leftButtonStartDrag(cm, e, start, modifier);
3626
+ else
3627
+ leftButtonSelect(cm, e, start, type, modifier);
3628
+ }
3629
+
3630
+ // Start a text drag. When it ends, see if any dragging actually
3631
+ // happen, and treat as a click if it didn't.
3632
+ function leftButtonStartDrag(cm, e, start, modifier) {
3633
+ var display = cm.display, startTime = +new Date;
3634
+ var dragEnd = operation(cm, function(e2) {
3635
+ if (webkit) display.scroller.draggable = false;
3636
+ cm.state.draggingText = false;
3637
+ off(document, "mouseup", dragEnd);
3638
+ off(display.scroller, "drop", dragEnd);
3639
+ if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
3640
+ e_preventDefault(e2);
3641
+ if (!modifier && +new Date - 200 < startTime)
3642
+ extendSelection(cm.doc, start);
3643
+ // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081)
3644
+ if (webkit || ie && ie_version == 9)
3645
+ setTimeout(function() {document.body.focus(); display.input.focus();}, 20);
3646
+ else
3647
+ display.input.focus();
3648
+ }
3649
+ });
3650
+ // Let the drag handler handle this.
3651
+ if (webkit) display.scroller.draggable = true;
3652
+ cm.state.draggingText = dragEnd;
3653
+ // IE's approach to draggable
3654
+ if (display.scroller.dragDrop) display.scroller.dragDrop();
3655
+ on(document, "mouseup", dragEnd);
3656
+ on(display.scroller, "drop", dragEnd);
3657
+ }
3658
+
3659
+ // Normal selection, as opposed to text dragging.
3660
+ function leftButtonSelect(cm, e, start, type, addNew) {
3661
+ var display = cm.display, doc = cm.doc;
3662
+ e_preventDefault(e);
3663
+
3664
+ var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges;
3665
+ if (addNew && !e.shiftKey) {
3666
+ ourIndex = doc.sel.contains(start);
3667
+ if (ourIndex > -1)
3668
+ ourRange = ranges[ourIndex];
3669
+ else
3670
+ ourRange = new Range(start, start);
3671
+ } else {
3672
+ ourRange = doc.sel.primary();
3673
+ ourIndex = doc.sel.primIndex;
3674
+ }
3675
+
3676
+ if (e.altKey) {
3677
+ type = "rect";
3678
+ if (!addNew) ourRange = new Range(start, start);
3679
+ start = posFromMouse(cm, e, true, true);
3680
+ ourIndex = -1;
3681
+ } else if (type == "double") {
3682
+ var word = cm.findWordAt(start);
3683
+ if (cm.display.shift || doc.extend)
3684
+ ourRange = extendRange(doc, ourRange, word.anchor, word.head);
3685
+ else
3686
+ ourRange = word;
3687
+ } else if (type == "triple") {
3688
+ var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0)));
3689
+ if (cm.display.shift || doc.extend)
3690
+ ourRange = extendRange(doc, ourRange, line.anchor, line.head);
3691
+ else
3692
+ ourRange = line;
3693
+ } else {
3694
+ ourRange = extendRange(doc, ourRange, start);
3695
+ }
3696
+
3697
+ if (!addNew) {
3698
+ ourIndex = 0;
3699
+ setSelection(doc, new Selection([ourRange], 0), sel_mouse);
3700
+ startSel = doc.sel;
3701
+ } else if (ourIndex == -1) {
3702
+ ourIndex = ranges.length;
3703
+ setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex),
3704
+ {scroll: false, origin: "*mouse"});
3705
+ } else if (ranges.length > 1 && ranges[ourIndex].empty() && type == "single" && !e.shiftKey) {
3706
+ setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0),
3707
+ {scroll: false, origin: "*mouse"});
3708
+ startSel = doc.sel;
3709
+ } else {
3710
+ replaceOneSelection(doc, ourIndex, ourRange, sel_mouse);
3711
+ }
3712
+
3713
+ var lastPos = start;
3714
+ function extendTo(pos) {
3715
+ if (cmp(lastPos, pos) == 0) return;
3716
+ lastPos = pos;
3717
+
3718
+ if (type == "rect") {
3719
+ var ranges = [], tabSize = cm.options.tabSize;
3720
+ var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize);
3721
+ var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize);
3722
+ var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol);
3723
+ for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line));
3724
+ line <= end; line++) {
3725
+ var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize);
3726
+ if (left == right)
3727
+ ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos)));
3728
+ else if (text.length > leftPos)
3729
+ ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize))));
3730
+ }
3731
+ if (!ranges.length) ranges.push(new Range(start, start));
3732
+ setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex),
3733
+ {origin: "*mouse", scroll: false});
3734
+ cm.scrollIntoView(pos);
3735
+ } else {
3736
+ var oldRange = ourRange;
3737
+ var anchor = oldRange.anchor, head = pos;
3738
+ if (type != "single") {
3739
+ if (type == "double")
3740
+ var range = cm.findWordAt(pos);
3741
+ else
3742
+ var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0)));
3743
+ if (cmp(range.anchor, anchor) > 0) {
3744
+ head = range.head;
3745
+ anchor = minPos(oldRange.from(), range.anchor);
3746
+ } else {
3747
+ head = range.anchor;
3748
+ anchor = maxPos(oldRange.to(), range.head);
3749
+ }
3750
+ }
3751
+ var ranges = startSel.ranges.slice(0);
3752
+ ranges[ourIndex] = new Range(clipPos(doc, anchor), head);
3753
+ setSelection(doc, normalizeSelection(ranges, ourIndex), sel_mouse);
3754
+ }
3755
+ }
3756
+
3757
+ var editorSize = display.wrapper.getBoundingClientRect();
3758
+ // Used to ensure timeout re-tries don't fire when another extend
3759
+ // happened in the meantime (clearTimeout isn't reliable -- at
3760
+ // least on Chrome, the timeouts still happen even when cleared,
3761
+ // if the clear happens after their scheduled firing time).
3762
+ var counter = 0;
3763
+
3764
+ function extend(e) {
3765
+ var curCount = ++counter;
3766
+ var cur = posFromMouse(cm, e, true, type == "rect");
3767
+ if (!cur) return;
3768
+ if (cmp(cur, lastPos) != 0) {
3769
+ cm.curOp.focus = activeElt();
3770
+ extendTo(cur);
3771
+ var visible = visibleLines(display, doc);
3772
+ if (cur.line >= visible.to || cur.line < visible.from)
3773
+ setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150);
3774
+ } else {
3775
+ var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0;
3776
+ if (outside) setTimeout(operation(cm, function() {
3777
+ if (counter != curCount) return;
3778
+ display.scroller.scrollTop += outside;
3779
+ extend(e);
3780
+ }), 50);
3781
+ }
3782
+ }
3783
+
3784
+ function done(e) {
3785
+ cm.state.selectingText = false;
3786
+ counter = Infinity;
3787
+ e_preventDefault(e);
3788
+ display.input.focus();
3789
+ off(document, "mousemove", move);
3790
+ off(document, "mouseup", up);
3791
+ doc.history.lastSelOrigin = null;
3792
+ }
3793
+
3794
+ var move = operation(cm, function(e) {
3795
+ if (!e_button(e)) done(e);
3796
+ else extend(e);
3797
+ });
3798
+ var up = operation(cm, done);
3799
+ cm.state.selectingText = up;
3800
+ on(document, "mousemove", move);
3801
+ on(document, "mouseup", up);
3802
+ }
3803
+
3804
+ // Determines whether an event happened in the gutter, and fires the
3805
+ // handlers for the corresponding event.
3806
+ function gutterEvent(cm, e, type, prevent) {
3807
+ try { var mX = e.clientX, mY = e.clientY; }
3808
+ catch(e) { return false; }
3809
+ if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false;
3810
+ if (prevent) e_preventDefault(e);
3811
+
3812
+ var display = cm.display;
3813
+ var lineBox = display.lineDiv.getBoundingClientRect();
3814
+
3815
+ if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e);
3816
+ mY -= lineBox.top - display.viewOffset;
3817
+
3818
+ for (var i = 0; i < cm.options.gutters.length; ++i) {
3819
+ var g = display.gutters.childNodes[i];
3820
+ if (g && g.getBoundingClientRect().right >= mX) {
3821
+ var line = lineAtHeight(cm.doc, mY);
3822
+ var gutter = cm.options.gutters[i];
3823
+ signal(cm, type, cm, line, gutter, e);
3824
+ return e_defaultPrevented(e);
3825
+ }
3826
+ }
3827
+ }
3828
+
3829
+ function clickInGutter(cm, e) {
3830
+ return gutterEvent(cm, e, "gutterClick", true);
3831
+ }
3832
+
3833
+ // Kludge to work around strange IE behavior where it'll sometimes
3834
+ // re-fire a series of drag-related events right after the drop (#1551)
3835
+ var lastDrop = 0;
3836
+
3837
+ function onDrop(e) {
3838
+ var cm = this;
3839
+ clearDragCursor(cm);
3840
+ if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))
3841
+ return;
3842
+ e_preventDefault(e);
3843
+ if (ie) lastDrop = +new Date;
3844
+ var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
3845
+ if (!pos || cm.isReadOnly()) return;
3846
+ // Might be a file drop, in which case we simply extract the text
3847
+ // and insert it.
3848
+ if (files && files.length && window.FileReader && window.File) {
3849
+ var n = files.length, text = Array(n), read = 0;
3850
+ var loadFile = function(file, i) {
3851
+ if (cm.options.allowDropFileTypes &&
3852
+ indexOf(cm.options.allowDropFileTypes, file.type) == -1)
3853
+ return;
3854
+
3855
+ var reader = new FileReader;
3856
+ reader.onload = operation(cm, function() {
3857
+ var content = reader.result;
3858
+ if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) content = "";
3859
+ text[i] = content;
3860
+ if (++read == n) {
3861
+ pos = clipPos(cm.doc, pos);
3862
+ var change = {from: pos, to: pos,
3863
+ text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())),
3864
+ origin: "paste"};
3865
+ makeChange(cm.doc, change);
3866
+ setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));
3867
+ }
3868
+ });
3869
+ reader.readAsText(file);
3870
+ };
3871
+ for (var i = 0; i < n; ++i) loadFile(files[i], i);
3872
+ } else { // Normal drop
3873
+ // Don't do a replace if the drop happened inside of the selected text.
3874
+ if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) {
3875
+ cm.state.draggingText(e);
3876
+ // Ensure the editor is re-focused
3877
+ setTimeout(function() {cm.display.input.focus();}, 20);
3878
+ return;
3879
+ }
3880
+ try {
3881
+ var text = e.dataTransfer.getData("Text");
3882
+ if (text) {
3883
+ if (cm.state.draggingText && !(mac ? e.altKey : e.ctrlKey))
3884
+ var selected = cm.listSelections();
3885
+ setSelectionNoUndo(cm.doc, simpleSelection(pos, pos));
3886
+ if (selected) for (var i = 0; i < selected.length; ++i)
3887
+ replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag");
3888
+ cm.replaceSelection(text, "around", "paste");
3889
+ cm.display.input.focus();
3890
+ }
3891
+ }
3892
+ catch(e){}
3893
+ }
3894
+ }
3895
+
3896
+ function onDragStart(cm, e) {
3897
+ if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; }
3898
+ if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return;
3899
+
3900
+ e.dataTransfer.setData("Text", cm.getSelection());
3901
+
3902
+ // Use dummy image instead of default browsers image.
3903
+ // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
3904
+ if (e.dataTransfer.setDragImage && !safari) {
3905
+ var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
3906
+ img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
3907
+ if (presto) {
3908
+ img.width = img.height = 1;
3909
+ cm.display.wrapper.appendChild(img);
3910
+ // Force a relayout, or Opera won't use our image for some obscure reason
3911
+ img._top = img.offsetTop;
3912
+ }
3913
+ e.dataTransfer.setDragImage(img, 0, 0);
3914
+ if (presto) img.parentNode.removeChild(img);
3915
+ }
3916
+ }
3917
+
3918
+ function onDragOver(cm, e) {
3919
+ var pos = posFromMouse(cm, e);
3920
+ if (!pos) return;
3921
+ var frag = document.createDocumentFragment();
3922
+ drawSelectionCursor(cm, pos, frag);
3923
+ if (!cm.display.dragCursor) {
3924
+ cm.display.dragCursor = elt("div", null, "CodeMirror-cursors CodeMirror-dragcursors");
3925
+ cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv);
3926
+ }
3927
+ removeChildrenAndAdd(cm.display.dragCursor, frag);
3928
+ }
3929
+
3930
+ function clearDragCursor(cm) {
3931
+ if (cm.display.dragCursor) {
3932
+ cm.display.lineSpace.removeChild(cm.display.dragCursor);
3933
+ cm.display.dragCursor = null;
3934
+ }
3935
+ }
3936
+
3937
+ // SCROLL EVENTS
3938
+
3939
+ // Sync the scrollable area and scrollbars, ensure the viewport
3940
+ // covers the visible area.
3941
+ function setScrollTop(cm, val) {
3942
+ if (Math.abs(cm.doc.scrollTop - val) < 2) return;
3943
+ cm.doc.scrollTop = val;
3944
+ if (!gecko) updateDisplaySimple(cm, {top: val});
3945
+ if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;
3946
+ cm.display.scrollbars.setScrollTop(val);
3947
+ if (gecko) updateDisplaySimple(cm);
3948
+ startWorker(cm, 100);
3949
+ }
3950
+ // Sync scroller and scrollbar, ensure the gutter elements are
3951
+ // aligned.
3952
+ function setScrollLeft(cm, val, isScroller) {
3953
+ if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return;
3954
+ val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
3955
+ cm.doc.scrollLeft = val;
3956
+ alignHorizontally(cm);
3957
+ if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val;
3958
+ cm.display.scrollbars.setScrollLeft(val);
3959
+ }
3960
+
3961
+ // Since the delta values reported on mouse wheel events are
3962
+ // unstandardized between browsers and even browser versions, and
3963
+ // generally horribly unpredictable, this code starts by measuring
3964
+ // the scroll effect that the first few mouse wheel events have,
3965
+ // and, from that, detects the way it can convert deltas to pixel
3966
+ // offsets afterwards.
3967
+ //
3968
+ // The reason we want to know the amount a wheel event will scroll
3969
+ // is that it gives us a chance to update the display before the
3970
+ // actual scrolling happens, reducing flickering.
3971
+
3972
+ var wheelSamples = 0, wheelPixelsPerUnit = null;
3973
+ // Fill in a browser-detected starting value on browsers where we
3974
+ // know one. These don't have to be accurate -- the result of them
3975
+ // being wrong would just be a slight flicker on the first wheel
3976
+ // scroll (if it is large enough).
3977
+ if (ie) wheelPixelsPerUnit = -.53;
3978
+ else if (gecko) wheelPixelsPerUnit = 15;
3979
+ else if (chrome) wheelPixelsPerUnit = -.7;
3980
+ else if (safari) wheelPixelsPerUnit = -1/3;
3981
+
3982
+ var wheelEventDelta = function(e) {
3983
+ var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
3984
+ if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail;
3985
+ if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail;
3986
+ else if (dy == null) dy = e.wheelDelta;
3987
+ return {x: dx, y: dy};
3988
+ };
3989
+ CodeMirror.wheelEventPixels = function(e) {
3990
+ var delta = wheelEventDelta(e);
3991
+ delta.x *= wheelPixelsPerUnit;
3992
+ delta.y *= wheelPixelsPerUnit;
3993
+ return delta;
3994
+ };
3995
+
3996
+ function onScrollWheel(cm, e) {
3997
+ var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y;
3998
+
3999
+ var display = cm.display, scroll = display.scroller;
4000
+ // Quit if there's nothing to scroll here
4001
+ var canScrollX = scroll.scrollWidth > scroll.clientWidth;
4002
+ var canScrollY = scroll.scrollHeight > scroll.clientHeight;
4003
+ if (!(dx && canScrollX || dy && canScrollY)) return;
4004
+
4005
+ // Webkit browsers on OS X abort momentum scrolls when the target
4006
+ // of the scroll event is removed from the scrollable element.
4007
+ // This hack (see related code in patchDisplay) makes sure the
4008
+ // element is kept around.
4009
+ if (dy && mac && webkit) {
4010
+ outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) {
4011
+ for (var i = 0; i < view.length; i++) {
4012
+ if (view[i].node == cur) {
4013
+ cm.display.currentWheelTarget = cur;
4014
+ break outer;
4015
+ }
4016
+ }
4017
+ }
4018
+ }
4019
+
4020
+ // On some browsers, horizontal scrolling will cause redraws to
4021
+ // happen before the gutter has been realigned, causing it to
4022
+ // wriggle around in a most unseemly way. When we have an
4023
+ // estimated pixels/delta value, we just handle horizontal
4024
+ // scrolling entirely here. It'll be slightly off from native, but
4025
+ // better than glitching out.
4026
+ if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {
4027
+ if (dy && canScrollY)
4028
+ setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));
4029
+ setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));
4030
+ // Only prevent default scrolling if vertical scrolling is
4031
+ // actually possible. Otherwise, it causes vertical scroll
4032
+ // jitter on OSX trackpads when deltaX is small and deltaY
4033
+ // is large (issue #3579)
4034
+ if (!dy || (dy && canScrollY))
4035
+ e_preventDefault(e);
4036
+ display.wheelStartX = null; // Abort measurement, if in progress
4037
+ return;
4038
+ }
4039
+
4040
+ // 'Project' the visible viewport to cover the area that is being
4041
+ // scrolled into view (if we know enough to estimate it).
4042
+ if (dy && wheelPixelsPerUnit != null) {
4043
+ var pixels = dy * wheelPixelsPerUnit;
4044
+ var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
4045
+ if (pixels < 0) top = Math.max(0, top + pixels - 50);
4046
+ else bot = Math.min(cm.doc.height, bot + pixels + 50);
4047
+ updateDisplaySimple(cm, {top: top, bottom: bot});
4048
+ }
4049
+
4050
+ if (wheelSamples < 20) {
4051
+ if (display.wheelStartX == null) {
4052
+ display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
4053
+ display.wheelDX = dx; display.wheelDY = dy;
4054
+ setTimeout(function() {
4055
+ if (display.wheelStartX == null) return;
4056
+ var movedX = scroll.scrollLeft - display.wheelStartX;
4057
+ var movedY = scroll.scrollTop - display.wheelStartY;
4058
+ var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
4059
+ (movedX && display.wheelDX && movedX / display.wheelDX);
4060
+ display.wheelStartX = display.wheelStartY = null;
4061
+ if (!sample) return;
4062
+ wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);
4063
+ ++wheelSamples;
4064
+ }, 200);
4065
+ } else {
4066
+ display.wheelDX += dx; display.wheelDY += dy;
4067
+ }
4068
+ }
4069
+ }
4070
+
4071
+ // KEY EVENTS
4072
+
4073
+ // Run a handler that was bound to a key.
4074
+ function doHandleBinding(cm, bound, dropShift) {
4075
+ if (typeof bound == "string") {
4076
+ bound = commands[bound];
4077
+ if (!bound) return false;
4078
+ }
4079
+ // Ensure previous input has been read, so that the handler sees a
4080
+ // consistent view of the document
4081
+ cm.display.input.ensurePolled();
4082
+ var prevShift = cm.display.shift, done = false;
4083
+ try {
4084
+ if (cm.isReadOnly()) cm.state.suppressEdits = true;
4085
+ if (dropShift) cm.display.shift = false;
4086
+ done = bound(cm) != Pass;
4087
+ } finally {
4088
+ cm.display.shift = prevShift;
4089
+ cm.state.suppressEdits = false;
4090
+ }
4091
+ return done;
4092
+ }
4093
+
4094
+ function lookupKeyForEditor(cm, name, handle) {
4095
+ for (var i = 0; i < cm.state.keyMaps.length; i++) {
4096
+ var result = lookupKey(name, cm.state.keyMaps[i], handle, cm);
4097
+ if (result) return result;
4098
+ }
4099
+ return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm))
4100
+ || lookupKey(name, cm.options.keyMap, handle, cm);
4101
+ }
4102
+
4103
+ var stopSeq = new Delayed;
4104
+ function dispatchKey(cm, name, e, handle) {
4105
+ var seq = cm.state.keySeq;
4106
+ if (seq) {
4107
+ if (isModifierKey(name)) return "handled";
4108
+ stopSeq.set(50, function() {
4109
+ if (cm.state.keySeq == seq) {
4110
+ cm.state.keySeq = null;
4111
+ cm.display.input.reset();
4112
+ }
4113
+ });
4114
+ name = seq + " " + name;
4115
+ }
4116
+ var result = lookupKeyForEditor(cm, name, handle);
4117
+
4118
+ if (result == "multi")
4119
+ cm.state.keySeq = name;
4120
+ if (result == "handled")
4121
+ signalLater(cm, "keyHandled", cm, name, e);
4122
+
4123
+ if (result == "handled" || result == "multi") {
4124
+ e_preventDefault(e);
4125
+ restartBlink(cm);
4126
+ }
4127
+
4128
+ if (seq && !result && /\'$/.test(name)) {
4129
+ e_preventDefault(e);
4130
+ return true;
4131
+ }
4132
+ return !!result;
4133
+ }
4134
+
4135
+ // Handle a key from the keydown event.
4136
+ function handleKeyBinding(cm, e) {
4137
+ var name = keyName(e, true);
4138
+ if (!name) return false;
4139
+
4140
+ if (e.shiftKey && !cm.state.keySeq) {
4141
+ // First try to resolve full name (including 'Shift-'). Failing
4142
+ // that, see if there is a cursor-motion command (starting with
4143
+ // 'go') bound to the keyname without 'Shift-'.
4144
+ return dispatchKey(cm, "Shift-" + name, e, function(b) {return doHandleBinding(cm, b, true);})
4145
+ || dispatchKey(cm, name, e, function(b) {
4146
+ if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion)
4147
+ return doHandleBinding(cm, b);
4148
+ });
4149
+ } else {
4150
+ return dispatchKey(cm, name, e, function(b) { return doHandleBinding(cm, b); });
4151
+ }
4152
+ }
4153
+
4154
+ // Handle a key from the keypress event
4155
+ function handleCharBinding(cm, e, ch) {
4156
+ return dispatchKey(cm, "'" + ch + "'", e,
4157
+ function(b) { return doHandleBinding(cm, b, true); });
4158
+ }
4159
+
4160
+ var lastStoppedKey = null;
4161
+ function onKeyDown(e) {
4162
+ var cm = this;
4163
+ cm.curOp.focus = activeElt();
4164
+ if (signalDOMEvent(cm, e)) return;
4165
+ // IE does strange things with escape.
4166
+ if (ie && ie_version < 11 && e.keyCode == 27) e.returnValue = false;
4167
+ var code = e.keyCode;
4168
+ cm.display.shift = code == 16 || e.shiftKey;
4169
+ var handled = handleKeyBinding(cm, e);
4170
+ if (presto) {
4171
+ lastStoppedKey = handled ? code : null;
4172
+ // Opera has no cut event... we try to at least catch the key combo
4173
+ if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))
4174
+ cm.replaceSelection("", null, "cut");
4175
+ }
4176
+
4177
+ // Turn mouse into crosshair when Alt is held on Mac.
4178
+ if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className))
4179
+ showCrossHair(cm);
4180
+ }
4181
+
4182
+ function showCrossHair(cm) {
4183
+ var lineDiv = cm.display.lineDiv;
4184
+ addClass(lineDiv, "CodeMirror-crosshair");
4185
+
4186
+ function up(e) {
4187
+ if (e.keyCode == 18 || !e.altKey) {
4188
+ rmClass(lineDiv, "CodeMirror-crosshair");
4189
+ off(document, "keyup", up);
4190
+ off(document, "mouseover", up);
4191
+ }
4192
+ }
4193
+ on(document, "keyup", up);
4194
+ on(document, "mouseover", up);
4195
+ }
4196
+
4197
+ function onKeyUp(e) {
4198
+ if (e.keyCode == 16) this.doc.sel.shift = false;
4199
+ signalDOMEvent(this, e);
4200
+ }
4201
+
4202
+ function onKeyPress(e) {
4203
+ var cm = this;
4204
+ if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) return;
4205
+ var keyCode = e.keyCode, charCode = e.charCode;
4206
+ if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
4207
+ if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) return;
4208
+ var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
4209
+ if (handleCharBinding(cm, e, ch)) return;
4210
+ cm.display.input.onKeyPress(e);
4211
+ }
4212
+
4213
+ // FOCUS/BLUR EVENTS
4214
+
4215
+ function delayBlurEvent(cm) {
4216
+ cm.state.delayingBlurEvent = true;
4217
+ setTimeout(function() {
4218
+ if (cm.state.delayingBlurEvent) {
4219
+ cm.state.delayingBlurEvent = false;
4220
+ onBlur(cm);
4221
+ }
4222
+ }, 100);
4223
+ }
4224
+
4225
+ function onFocus(cm) {
4226
+ if (cm.state.delayingBlurEvent) cm.state.delayingBlurEvent = false;
4227
+
4228
+ if (cm.options.readOnly == "nocursor") return;
4229
+ if (!cm.state.focused) {
4230
+ signal(cm, "focus", cm);
4231
+ cm.state.focused = true;
4232
+ addClass(cm.display.wrapper, "CodeMirror-focused");
4233
+ // This test prevents this from firing when a context
4234
+ // menu is closed (since the input reset would kill the
4235
+ // select-all detection hack)
4236
+ if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) {
4237
+ cm.display.input.reset();
4238
+ if (webkit) setTimeout(function() { cm.display.input.reset(true); }, 20); // Issue #1730
4239
+ }
4240
+ cm.display.input.receivedFocus();
4241
+ }
4242
+ restartBlink(cm);
4243
+ }
4244
+ function onBlur(cm) {
4245
+ if (cm.state.delayingBlurEvent) return;
4246
+
4247
+ if (cm.state.focused) {
4248
+ signal(cm, "blur", cm);
4249
+ cm.state.focused = false;
4250
+ rmClass(cm.display.wrapper, "CodeMirror-focused");
4251
+ }
4252
+ clearInterval(cm.display.blinker);
4253
+ setTimeout(function() {if (!cm.state.focused) cm.display.shift = false;}, 150);
4254
+ }
4255
+
4256
+ // CONTEXT MENU HANDLING
4257
+
4258
+ // To make the context menu work, we need to briefly unhide the
4259
+ // textarea (making it as unobtrusive as possible) to let the
4260
+ // right-click take effect on it.
4261
+ function onContextMenu(cm, e) {
4262
+ if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) return;
4263
+ if (signalDOMEvent(cm, e, "contextmenu")) return;
4264
+ cm.display.input.onContextMenu(e);
4265
+ }
4266
+
4267
+ function contextMenuInGutter(cm, e) {
4268
+ if (!hasHandler(cm, "gutterContextMenu")) return false;
4269
+ return gutterEvent(cm, e, "gutterContextMenu", false);
4270
+ }
4271
+
4272
+ // UPDATING
4273
+
4274
+ // Compute the position of the end of a change (its 'to' property
4275
+ // refers to the pre-change end).
4276
+ var changeEnd = CodeMirror.changeEnd = function(change) {
4277
+ if (!change.text) return change.to;
4278
+ return Pos(change.from.line + change.text.length - 1,
4279
+ lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0));
4280
+ };
4281
+
4282
+ // Adjust a position to refer to the post-change position of the
4283
+ // same text, or the end of the change if the change covers it.
4284
+ function adjustForChange(pos, change) {
4285
+ if (cmp(pos, change.from) < 0) return pos;
4286
+ if (cmp(pos, change.to) <= 0) return changeEnd(change);
4287
+
4288
+ var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;
4289
+ if (pos.line == change.to.line) ch += changeEnd(change).ch - change.to.ch;
4290
+ return Pos(line, ch);
4291
+ }
4292
+
4293
+ function computeSelAfterChange(doc, change) {
4294
+ var out = [];
4295
+ for (var i = 0; i < doc.sel.ranges.length; i++) {
4296
+ var range = doc.sel.ranges[i];
4297
+ out.push(new Range(adjustForChange(range.anchor, change),
4298
+ adjustForChange(range.head, change)));
4299
+ }
4300
+ return normalizeSelection(out, doc.sel.primIndex);
4301
+ }
4302
+
4303
+ function offsetPos(pos, old, nw) {
4304
+ if (pos.line == old.line)
4305
+ return Pos(nw.line, pos.ch - old.ch + nw.ch);
4306
+ else
4307
+ return Pos(nw.line + (pos.line - old.line), pos.ch);
4308
+ }
4309
+
4310
+ // Used by replaceSelections to allow moving the selection to the
4311
+ // start or around the replaced test. Hint may be "start" or "around".
4312
+ function computeReplacedSel(doc, changes, hint) {
4313
+ var out = [];
4314
+ var oldPrev = Pos(doc.first, 0), newPrev = oldPrev;
4315
+ for (var i = 0; i < changes.length; i++) {
4316
+ var change = changes[i];
4317
+ var from = offsetPos(change.from, oldPrev, newPrev);
4318
+ var to = offsetPos(changeEnd(change), oldPrev, newPrev);
4319
+ oldPrev = change.to;
4320
+ newPrev = to;
4321
+ if (hint == "around") {
4322
+ var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0;
4323
+ out[i] = new Range(inv ? to : from, inv ? from : to);
4324
+ } else {
4325
+ out[i] = new Range(from, from);
4326
+ }
4327
+ }
4328
+ return new Selection(out, doc.sel.primIndex);
4329
+ }
4330
+
4331
+ // Allow "beforeChange" event handlers to influence a change
4332
+ function filterChange(doc, change, update) {
4333
+ var obj = {
4334
+ canceled: false,
4335
+ from: change.from,
4336
+ to: change.to,
4337
+ text: change.text,
4338
+ origin: change.origin,
4339
+ cancel: function() { this.canceled = true; }
4340
+ };
4341
+ if (update) obj.update = function(from, to, text, origin) {
4342
+ if (from) this.from = clipPos(doc, from);
4343
+ if (to) this.to = clipPos(doc, to);
4344
+ if (text) this.text = text;
4345
+ if (origin !== undefined) this.origin = origin;
4346
+ };
4347
+ signal(doc, "beforeChange", doc, obj);
4348
+ if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj);
4349
+
4350
+ if (obj.canceled) return null;
4351
+ return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin};
4352
+ }
4353
+
4354
+ // Apply a change to a document, and add it to the document's
4355
+ // history, and propagating it to all linked documents.
4356
+ function makeChange(doc, change, ignoreReadOnly) {
4357
+ if (doc.cm) {
4358
+ if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly);
4359
+ if (doc.cm.state.suppressEdits) return;
4360
+ }
4361
+
4362
+ if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) {
4363
+ change = filterChange(doc, change, true);
4364
+ if (!change) return;
4365
+ }
4366
+
4367
+ // Possibly split or suppress the update based on the presence
4368
+ // of read-only spans in its range.
4369
+ var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);
4370
+ if (split) {
4371
+ for (var i = split.length - 1; i >= 0; --i)
4372
+ makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text});
4373
+ } else {
4374
+ makeChangeInner(doc, change);
4375
+ }
4376
+ }
4377
+
4378
+ function makeChangeInner(doc, change) {
4379
+ if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) return;
4380
+ var selAfter = computeSelAfterChange(doc, change);
4381
+ addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);
4382
+
4383
+ makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));
4384
+ var rebased = [];
4385
+
4386
+ linkedDocs(doc, function(doc, sharedHist) {
4387
+ if (!sharedHist && indexOf(rebased, doc.history) == -1) {
4388
+ rebaseHist(doc.history, change);
4389
+ rebased.push(doc.history);
4390
+ }
4391
+ makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change));
4392
+ });
4393
+ }
4394
+
4395
+ // Revert a change stored in a document's history.
4396
+ function makeChangeFromHistory(doc, type, allowSelectionOnly) {
4397
+ if (doc.cm && doc.cm.state.suppressEdits) return;
4398
+
4399
+ var hist = doc.history, event, selAfter = doc.sel;
4400
+ var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done;
4401
+
4402
+ // Verify that there is a useable event (so that ctrl-z won't
4403
+ // needlessly clear selection events)
4404
+ for (var i = 0; i < source.length; i++) {
4405
+ event = source[i];
4406
+ if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges)
4407
+ break;
4408
+ }
4409
+ if (i == source.length) return;
4410
+ hist.lastOrigin = hist.lastSelOrigin = null;
4411
+
4412
+ for (;;) {
4413
+ event = source.pop();
4414
+ if (event.ranges) {
4415
+ pushSelectionToHistory(event, dest);
4416
+ if (allowSelectionOnly && !event.equals(doc.sel)) {
4417
+ setSelection(doc, event, {clearRedo: false});
4418
+ return;
4419
+ }
4420
+ selAfter = event;
4421
+ }
4422
+ else break;
4423
+ }
4424
+
4425
+ // Build up a reverse change object to add to the opposite history
4426
+ // stack (redo when undoing, and vice versa).
4427
+ var antiChanges = [];
4428
+ pushSelectionToHistory(selAfter, dest);
4429
+ dest.push({changes: antiChanges, generation: hist.generation});
4430
+ hist.generation = event.generation || ++hist.maxGeneration;
4431
+
4432
+ var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange");
4433
+
4434
+ for (var i = event.changes.length - 1; i >= 0; --i) {
4435
+ var change = event.changes[i];
4436
+ change.origin = type;
4437
+ if (filter && !filterChange(doc, change, false)) {
4438
+ source.length = 0;
4439
+ return;
4440
+ }
4441
+
4442
+ antiChanges.push(historyChangeFromChange(doc, change));
4443
+
4444
+ var after = i ? computeSelAfterChange(doc, change) : lst(source);
4445
+ makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
4446
+ if (!i && doc.cm) doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)});
4447
+ var rebased = [];
4448
+
4449
+ // Propagate to the linked documents
4450
+ linkedDocs(doc, function(doc, sharedHist) {
4451
+ if (!sharedHist && indexOf(rebased, doc.history) == -1) {
4452
+ rebaseHist(doc.history, change);
4453
+ rebased.push(doc.history);
4454
+ }
4455
+ makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change));
4456
+ });
4457
+ }
4458
+ }
4459
+
4460
+ // Sub-views need their line numbers shifted when text is added
4461
+ // above or below them in the parent document.
4462
+ function shiftDoc(doc, distance) {
4463
+ if (distance == 0) return;
4464
+ doc.first += distance;
4465
+ doc.sel = new Selection(map(doc.sel.ranges, function(range) {
4466
+ return new Range(Pos(range.anchor.line + distance, range.anchor.ch),
4467
+ Pos(range.head.line + distance, range.head.ch));
4468
+ }), doc.sel.primIndex);
4469
+ if (doc.cm) {
4470
+ regChange(doc.cm, doc.first, doc.first - distance, distance);
4471
+ for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++)
4472
+ regLineChange(doc.cm, l, "gutter");
4473
+ }
4474
+ }
4475
+
4476
+ // More lower-level change function, handling only a single document
4477
+ // (not linked ones).
4478
+ function makeChangeSingleDoc(doc, change, selAfter, spans) {
4479
+ if (doc.cm && !doc.cm.curOp)
4480
+ return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans);
4481
+
4482
+ if (change.to.line < doc.first) {
4483
+ shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line));
4484
+ return;
4485
+ }
4486
+ if (change.from.line > doc.lastLine()) return;
4487
+
4488
+ // Clip the change to the size of this doc
4489
+ if (change.from.line < doc.first) {
4490
+ var shift = change.text.length - 1 - (doc.first - change.from.line);
4491
+ shiftDoc(doc, shift);
4492
+ change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),
4493
+ text: [lst(change.text)], origin: change.origin};
4494
+ }
4495
+ var last = doc.lastLine();
4496
+ if (change.to.line > last) {
4497
+ change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),
4498
+ text: [change.text[0]], origin: change.origin};
4499
+ }
4500
+
4501
+ change.removed = getBetween(doc, change.from, change.to);
4502
+
4503
+ if (!selAfter) selAfter = computeSelAfterChange(doc, change);
4504
+ if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans);
4505
+ else updateDoc(doc, change, spans);
4506
+ setSelectionNoUndo(doc, selAfter, sel_dontScroll);
4507
+ }
4508
+
4509
+ // Handle the interaction of a change to a document with the editor
4510
+ // that this document is part of.
4511
+ function makeChangeSingleDocInEditor(cm, change, spans) {
4512
+ var doc = cm.doc, display = cm.display, from = change.from, to = change.to;
4513
+
4514
+ var recomputeMaxLength = false, checkWidthStart = from.line;
4515
+ if (!cm.options.lineWrapping) {
4516
+ checkWidthStart = lineNo(visualLine(getLine(doc, from.line)));
4517
+ doc.iter(checkWidthStart, to.line + 1, function(line) {
4518
+ if (line == display.maxLine) {
4519
+ recomputeMaxLength = true;
4520
+ return true;
4521
+ }
4522
+ });
4523
+ }
4524
+
4525
+ if (doc.sel.contains(change.from, change.to) > -1)
4526
+ signalCursorActivity(cm);
4527
+
4528
+ updateDoc(doc, change, spans, estimateHeight(cm));
4529
+
4530
+ if (!cm.options.lineWrapping) {
4531
+ doc.iter(checkWidthStart, from.line + change.text.length, function(line) {
4532
+ var len = lineLength(line);
4533
+ if (len > display.maxLineLength) {
4534
+ display.maxLine = line;
4535
+ display.maxLineLength = len;
4536
+ display.maxLineChanged = true;
4537
+ recomputeMaxLength = false;
4538
+ }
4539
+ });
4540
+ if (recomputeMaxLength) cm.curOp.updateMaxLine = true;
4541
+ }
4542
+
4543
+ // Adjust frontier, schedule worker
4544
+ doc.frontier = Math.min(doc.frontier, from.line);
4545
+ startWorker(cm, 400);
4546
+
4547
+ var lendiff = change.text.length - (to.line - from.line) - 1;
4548
+ // Remember that these lines changed, for updating the display
4549
+ if (change.full)
4550
+ regChange(cm);
4551
+ else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))
4552
+ regLineChange(cm, from.line, "text");
4553
+ else
4554
+ regChange(cm, from.line, to.line + 1, lendiff);
4555
+
4556
+ var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change");
4557
+ if (changeHandler || changesHandler) {
4558
+ var obj = {
4559
+ from: from, to: to,
4560
+ text: change.text,
4561
+ removed: change.removed,
4562
+ origin: change.origin
4563
+ };
4564
+ if (changeHandler) signalLater(cm, "change", cm, obj);
4565
+ if (changesHandler) (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj);
4566
+ }
4567
+ cm.display.selForContextMenu = null;
4568
+ }
4569
+
4570
+ function replaceRange(doc, code, from, to, origin) {
4571
+ if (!to) to = from;
4572
+ if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; }
4573
+ if (typeof code == "string") code = doc.splitLines(code);
4574
+ makeChange(doc, {from: from, to: to, text: code, origin: origin});
4575
+ }
4576
+
4577
+ // SCROLLING THINGS INTO VIEW
4578
+
4579
+ // If an editor sits on the top or bottom of the window, partially
4580
+ // scrolled out of view, this ensures that the cursor is visible.
4581
+ function maybeScrollWindow(cm, coords) {
4582
+ if (signalDOMEvent(cm, "scrollCursorIntoView")) return;
4583
+
4584
+ var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null;
4585
+ if (coords.top + box.top < 0) doScroll = true;
4586
+ else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
4587
+ if (doScroll != null && !phantom) {
4588
+ var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " +
4589
+ (coords.top - display.viewOffset - paddingTop(cm.display)) + "px; height: " +
4590
+ (coords.bottom - coords.top + scrollGap(cm) + display.barHeight) + "px; left: " +
4591
+ coords.left + "px; width: 2px;");
4592
+ cm.display.lineSpace.appendChild(scrollNode);
4593
+ scrollNode.scrollIntoView(doScroll);
4594
+ cm.display.lineSpace.removeChild(scrollNode);
4595
+ }
4596
+ }
4597
+
4598
+ // Scroll a given position into view (immediately), verifying that
4599
+ // it actually became visible (as line heights are accurately
4600
+ // measured, the position of something may 'drift' during drawing).
4601
+ function scrollPosIntoView(cm, pos, end, margin) {
4602
+ if (margin == null) margin = 0;
4603
+ for (var limit = 0; limit < 5; limit++) {
4604
+ var changed = false, coords = cursorCoords(cm, pos);
4605
+ var endCoords = !end || end == pos ? coords : cursorCoords(cm, end);
4606
+ var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left),
4607
+ Math.min(coords.top, endCoords.top) - margin,
4608
+ Math.max(coords.left, endCoords.left),
4609
+ Math.max(coords.bottom, endCoords.bottom) + margin);
4610
+ var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
4611
+ if (scrollPos.scrollTop != null) {
4612
+ setScrollTop(cm, scrollPos.scrollTop);
4613
+ if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true;
4614
+ }
4615
+ if (scrollPos.scrollLeft != null) {
4616
+ setScrollLeft(cm, scrollPos.scrollLeft);
4617
+ if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true;
4618
+ }
4619
+ if (!changed) break;
4620
+ }
4621
+ return coords;
4622
+ }
4623
+
4624
+ // Scroll a given set of coordinates into view (immediately).
4625
+ function scrollIntoView(cm, x1, y1, x2, y2) {
4626
+ var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2);
4627
+ if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop);
4628
+ if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft);
4629
+ }
4630
+
4631
+ // Calculate a new scroll position needed to scroll the given
4632
+ // rectangle into view. Returns an object with scrollTop and
4633
+ // scrollLeft properties. When these are undefined, the
4634
+ // vertical/horizontal position does not need to be adjusted.
4635
+ function calculateScrollPos(cm, x1, y1, x2, y2) {
4636
+ var display = cm.display, snapMargin = textHeight(cm.display);
4637
+ if (y1 < 0) y1 = 0;
4638
+ var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop;
4639
+ var screen = displayHeight(cm), result = {};
4640
+ if (y2 - y1 > screen) y2 = y1 + screen;
4641
+ var docBottom = cm.doc.height + paddingVert(display);
4642
+ var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin;
4643
+ if (y1 < screentop) {
4644
+ result.scrollTop = atTop ? 0 : y1;
4645
+ } else if (y2 > screentop + screen) {
4646
+ var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen);
4647
+ if (newTop != screentop) result.scrollTop = newTop;
4648
+ }
4649
+
4650
+ var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft;
4651
+ var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0);
4652
+ var tooWide = x2 - x1 > screenw;
4653
+ if (tooWide) x2 = x1 + screenw;
4654
+ if (x1 < 10)
4655
+ result.scrollLeft = 0;
4656
+ else if (x1 < screenleft)
4657
+ result.scrollLeft = Math.max(0, x1 - (tooWide ? 0 : 10));
4658
+ else if (x2 > screenw + screenleft - 3)
4659
+ result.scrollLeft = x2 + (tooWide ? 0 : 10) - screenw;
4660
+ return result;
4661
+ }
4662
+
4663
+ // Store a relative adjustment to the scroll position in the current
4664
+ // operation (to be applied when the operation finishes).
4665
+ function addToScrollPos(cm, left, top) {
4666
+ if (left != null || top != null) resolveScrollToPos(cm);
4667
+ if (left != null)
4668
+ cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left;
4669
+ if (top != null)
4670
+ cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top;
4671
+ }
4672
+
4673
+ // Make sure that at the end of the operation the current cursor is
4674
+ // shown.
4675
+ function ensureCursorVisible(cm) {
4676
+ resolveScrollToPos(cm);
4677
+ var cur = cm.getCursor(), from = cur, to = cur;
4678
+ if (!cm.options.lineWrapping) {
4679
+ from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur;
4680
+ to = Pos(cur.line, cur.ch + 1);
4681
+ }
4682
+ cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin, isCursor: true};
4683
+ }
4684
+
4685
+ // When an operation has its scrollToPos property set, and another
4686
+ // scroll action is applied before the end of the operation, this
4687
+ // 'simulates' scrolling that position into view in a cheap way, so
4688
+ // that the effect of intermediate scroll commands is not ignored.
4689
+ function resolveScrollToPos(cm) {
4690
+ var range = cm.curOp.scrollToPos;
4691
+ if (range) {
4692
+ cm.curOp.scrollToPos = null;
4693
+ var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to);
4694
+ var sPos = calculateScrollPos(cm, Math.min(from.left, to.left),
4695
+ Math.min(from.top, to.top) - range.margin,
4696
+ Math.max(from.right, to.right),
4697
+ Math.max(from.bottom, to.bottom) + range.margin);
4698
+ cm.scrollTo(sPos.scrollLeft, sPos.scrollTop);
4699
+ }
4700
+ }
4701
+
4702
+ // API UTILITIES
4703
+
4704
+ // Indent the given line. The how parameter can be "smart",
4705
+ // "add"/null, "subtract", or "prev". When aggressive is false
4706
+ // (typically set to true for forced single-line indents), empty
4707
+ // lines are not indented, and places where the mode returns Pass
4708
+ // are left alone.
4709
+ function indentLine(cm, n, how, aggressive) {
4710
+ var doc = cm.doc, state;
4711
+ if (how == null) how = "add";
4712
+ if (how == "smart") {
4713
+ // Fall back to "prev" when the mode doesn't have an indentation
4714
+ // method.
4715
+ if (!doc.mode.indent) how = "prev";
4716
+ else state = getStateBefore(cm, n);
4717
+ }
4718
+
4719
+ var tabSize = cm.options.tabSize;
4720
+ var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);
4721
+ if (line.stateAfter) line.stateAfter = null;
4722
+ var curSpaceString = line.text.match(/^\s*/)[0], indentation;
4723
+ if (!aggressive && !/\S/.test(line.text)) {
4724
+ indentation = 0;
4725
+ how = "not";
4726
+ } else if (how == "smart") {
4727
+ indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);
4728
+ if (indentation == Pass || indentation > 150) {
4729
+ if (!aggressive) return;
4730
+ how = "prev";
4731
+ }
4732
+ }
4733
+ if (how == "prev") {
4734
+ if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize);
4735
+ else indentation = 0;
4736
+ } else if (how == "add") {
4737
+ indentation = curSpace + cm.options.indentUnit;
4738
+ } else if (how == "subtract") {
4739
+ indentation = curSpace - cm.options.indentUnit;
4740
+ } else if (typeof how == "number") {
4741
+ indentation = curSpace + how;
4742
+ }
4743
+ indentation = Math.max(0, indentation);
4744
+
4745
+ var indentString = "", pos = 0;
4746
+ if (cm.options.indentWithTabs)
4747
+ for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";}
4748
+ if (pos < indentation) indentString += spaceStr(indentation - pos);
4749
+
4750
+ if (indentString != curSpaceString) {
4751
+ replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
4752
+ line.stateAfter = null;
4753
+ return true;
4754
+ } else {
4755
+ // Ensure that, if the cursor was in the whitespace at the start
4756
+ // of the line, it is moved to the end of that space.
4757
+ for (var i = 0; i < doc.sel.ranges.length; i++) {
4758
+ var range = doc.sel.ranges[i];
4759
+ if (range.head.line == n && range.head.ch < curSpaceString.length) {
4760
+ var pos = Pos(n, curSpaceString.length);
4761
+ replaceOneSelection(doc, i, new Range(pos, pos));
4762
+ break;
4763
+ }
4764
+ }
4765
+ }
4766
+ }
4767
+
4768
+ // Utility for applying a change to a line by handle or number,
4769
+ // returning the number and optionally registering the line as
4770
+ // changed.
4771
+ function changeLine(doc, handle, changeType, op) {
4772
+ var no = handle, line = handle;
4773
+ if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle));
4774
+ else no = lineNo(handle);
4775
+ if (no == null) return null;
4776
+ if (op(line, no) && doc.cm) regLineChange(doc.cm, no, changeType);
4777
+ return line;
4778
+ }
4779
+
4780
+ // Helper for deleting text near the selection(s), used to implement
4781
+ // backspace, delete, and similar functionality.
4782
+ function deleteNearSelection(cm, compute) {
4783
+ var ranges = cm.doc.sel.ranges, kill = [];
4784
+ // Build up a set of ranges to kill first, merging overlapping
4785
+ // ranges.
4786
+ for (var i = 0; i < ranges.length; i++) {
4787
+ var toKill = compute(ranges[i]);
4788
+ while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) {
4789
+ var replaced = kill.pop();
4790
+ if (cmp(replaced.from, toKill.from) < 0) {
4791
+ toKill.from = replaced.from;
4792
+ break;
4793
+ }
4794
+ }
4795
+ kill.push(toKill);
4796
+ }
4797
+ // Next, remove those actual ranges.
4798
+ runInOp(cm, function() {
4799
+ for (var i = kill.length - 1; i >= 0; i--)
4800
+ replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete");
4801
+ ensureCursorVisible(cm);
4802
+ });
4803
+ }
4804
+
4805
+ // Used for horizontal relative motion. Dir is -1 or 1 (left or
4806
+ // right), unit can be "char", "column" (like char, but doesn't
4807
+ // cross line boundaries), "word" (across next word), or "group" (to
4808
+ // the start of next group of word or non-word-non-whitespace
4809
+ // chars). The visually param controls whether, in right-to-left
4810
+ // text, direction 1 means to move towards the next index in the
4811
+ // string, or towards the character to the right of the current
4812
+ // position. The resulting position will have a hitSide=true
4813
+ // property if it reached the end of the document.
4814
+ function findPosH(doc, pos, dir, unit, visually) {
4815
+ var line = pos.line, ch = pos.ch, origDir = dir;
4816
+ var lineObj = getLine(doc, line);
4817
+ var possible = true;
4818
+ function findNextLine() {
4819
+ var l = line + dir;
4820
+ if (l < doc.first || l >= doc.first + doc.size) return (possible = false);
4821
+ line = l;
4822
+ return lineObj = getLine(doc, l);
4823
+ }
4824
+ function moveOnce(boundToLine) {
4825
+ var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true);
4826
+ if (next == null) {
4827
+ if (!boundToLine && findNextLine()) {
4828
+ if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj);
4829
+ else ch = dir < 0 ? lineObj.text.length : 0;
4830
+ } else return (possible = false);
4831
+ } else ch = next;
4832
+ return true;
4833
+ }
4834
+
4835
+ if (unit == "char") moveOnce();
4836
+ else if (unit == "column") moveOnce(true);
4837
+ else if (unit == "word" || unit == "group") {
4838
+ var sawType = null, group = unit == "group";
4839
+ var helper = doc.cm && doc.cm.getHelper(pos, "wordChars");
4840
+ for (var first = true;; first = false) {
4841
+ if (dir < 0 && !moveOnce(!first)) break;
4842
+ var cur = lineObj.text.charAt(ch) || "\n";
4843
+ var type = isWordChar(cur, helper) ? "w"
4844
+ : group && cur == "\n" ? "n"
4845
+ : !group || /\s/.test(cur) ? null
4846
+ : "p";
4847
+ if (group && !first && !type) type = "s";
4848
+ if (sawType && sawType != type) {
4849
+ if (dir < 0) {dir = 1; moveOnce();}
4850
+ break;
4851
+ }
4852
+
4853
+ if (type) sawType = type;
4854
+ if (dir > 0 && !moveOnce(!first)) break;
4855
+ }
4856
+ }
4857
+ var result = skipAtomic(doc, Pos(line, ch), pos, origDir, true);
4858
+ if (!possible) result.hitSide = true;
4859
+ return result;
4860
+ }
4861
+
4862
+ // For relative vertical movement. Dir may be -1 or 1. Unit can be
4863
+ // "page" or "line". The resulting position will have a hitSide=true
4864
+ // property if it reached the end of the document.
4865
+ function findPosV(cm, pos, dir, unit) {
4866
+ var doc = cm.doc, x = pos.left, y;
4867
+ if (unit == "page") {
4868
+ var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight);
4869
+ y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display));
4870
+ } else if (unit == "line") {
4871
+ y = dir > 0 ? pos.bottom + 3 : pos.top - 3;
4872
+ }
4873
+ for (;;) {
4874
+ var target = coordsChar(cm, x, y);
4875
+ if (!target.outside) break;
4876
+ if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; }
4877
+ y += dir * 5;
4878
+ }
4879
+ return target;
4880
+ }
4881
+
4882
+ // EDITOR METHODS
4883
+
4884
+ // The publicly visible API. Note that methodOp(f) means
4885
+ // 'wrap f in an operation, performed on its `this` parameter'.
4886
+
4887
+ // This is not the complete set of editor methods. Most of the
4888
+ // methods defined on the Doc type are also injected into
4889
+ // CodeMirror.prototype, for backwards compatibility and
4890
+ // convenience.
4891
+
4892
+ CodeMirror.prototype = {
4893
+ constructor: CodeMirror,
4894
+ focus: function(){window.focus(); this.display.input.focus();},
4895
+
4896
+ setOption: function(option, value) {
4897
+ var options = this.options, old = options[option];
4898
+ if (options[option] == value && option != "mode") return;
4899
+ options[option] = value;
4900
+ if (optionHandlers.hasOwnProperty(option))
4901
+ operation(this, optionHandlers[option])(this, value, old);
4902
+ },
4903
+
4904
+ getOption: function(option) {return this.options[option];},
4905
+ getDoc: function() {return this.doc;},
4906
+
4907
+ addKeyMap: function(map, bottom) {
4908
+ this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map));
4909
+ },
4910
+ removeKeyMap: function(map) {
4911
+ var maps = this.state.keyMaps;
4912
+ for (var i = 0; i < maps.length; ++i)
4913
+ if (maps[i] == map || maps[i].name == map) {
4914
+ maps.splice(i, 1);
4915
+ return true;
4916
+ }
4917
+ },
4918
+
4919
+ addOverlay: methodOp(function(spec, options) {
4920
+ var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);
4921
+ if (mode.startState) throw new Error("Overlays may not be stateful.");
4922
+ this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque});
4923
+ this.state.modeGen++;
4924
+ regChange(this);
4925
+ }),
4926
+ removeOverlay: methodOp(function(spec) {
4927
+ var overlays = this.state.overlays;
4928
+ for (var i = 0; i < overlays.length; ++i) {
4929
+ var cur = overlays[i].modeSpec;
4930
+ if (cur == spec || typeof spec == "string" && cur.name == spec) {
4931
+ overlays.splice(i, 1);
4932
+ this.state.modeGen++;
4933
+ regChange(this);
4934
+ return;
4935
+ }
4936
+ }
4937
+ }),
4938
+
4939
+ indentLine: methodOp(function(n, dir, aggressive) {
4940
+ if (typeof dir != "string" && typeof dir != "number") {
4941
+ if (dir == null) dir = this.options.smartIndent ? "smart" : "prev";
4942
+ else dir = dir ? "add" : "subtract";
4943
+ }
4944
+ if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive);
4945
+ }),
4946
+ indentSelection: methodOp(function(how) {
4947
+ var ranges = this.doc.sel.ranges, end = -1;
4948
+ for (var i = 0; i < ranges.length; i++) {
4949
+ var range = ranges[i];
4950
+ if (!range.empty()) {
4951
+ var from = range.from(), to = range.to();
4952
+ var start = Math.max(end, from.line);
4953
+ end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1;
4954
+ for (var j = start; j < end; ++j)
4955
+ indentLine(this, j, how);
4956
+ var newRanges = this.doc.sel.ranges;
4957
+ if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0)
4958
+ replaceOneSelection(this.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll);
4959
+ } else if (range.head.line > end) {
4960
+ indentLine(this, range.head.line, how, true);
4961
+ end = range.head.line;
4962
+ if (i == this.doc.sel.primIndex) ensureCursorVisible(this);
4963
+ }
4964
+ }
4965
+ }),
4966
+
4967
+ // Fetch the parser token for a given character. Useful for hacks
4968
+ // that want to inspect the mode state (say, for completion).
4969
+ getTokenAt: function(pos, precise) {
4970
+ return takeToken(this, pos, precise);
4971
+ },
4972
+
4973
+ getLineTokens: function(line, precise) {
4974
+ return takeToken(this, Pos(line), precise, true);
4975
+ },
4976
+
4977
+ getTokenTypeAt: function(pos) {
4978
+ pos = clipPos(this.doc, pos);
4979
+ var styles = getLineStyles(this, getLine(this.doc, pos.line));
4980
+ var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;
4981
+ var type;
4982
+ if (ch == 0) type = styles[2];
4983
+ else for (;;) {
4984
+ var mid = (before + after) >> 1;
4985
+ if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid;
4986
+ else if (styles[mid * 2 + 1] < ch) before = mid + 1;
4987
+ else { type = styles[mid * 2 + 2]; break; }
4988
+ }
4989
+ var cut = type ? type.indexOf("cm-overlay ") : -1;
4990
+ return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1);
4991
+ },
4992
+
4993
+ getModeAt: function(pos) {
4994
+ var mode = this.doc.mode;
4995
+ if (!mode.innerMode) return mode;
4996
+ return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode;
4997
+ },
4998
+
4999
+ getHelper: function(pos, type) {
5000
+ return this.getHelpers(pos, type)[0];
5001
+ },
5002
+
5003
+ getHelpers: function(pos, type) {
5004
+ var found = [];
5005
+ if (!helpers.hasOwnProperty(type)) return found;
5006
+ var help = helpers[type], mode = this.getModeAt(pos);
5007
+ if (typeof mode[type] == "string") {
5008
+ if (help[mode[type]]) found.push(help[mode[type]]);
5009
+ } else if (mode[type]) {
5010
+ for (var i = 0; i < mode[type].length; i++) {
5011
+ var val = help[mode[type][i]];
5012
+ if (val) found.push(val);
5013
+ }
5014
+ } else if (mode.helperType && help[mode.helperType]) {
5015
+ found.push(help[mode.helperType]);
5016
+ } else if (help[mode.name]) {
5017
+ found.push(help[mode.name]);
5018
+ }
5019
+ for (var i = 0; i < help._global.length; i++) {
5020
+ var cur = help._global[i];
5021
+ if (cur.pred(mode, this) && indexOf(found, cur.val) == -1)
5022
+ found.push(cur.val);
5023
+ }
5024
+ return found;
5025
+ },
5026
+
5027
+ getStateAfter: function(line, precise) {
5028
+ var doc = this.doc;
5029
+ line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);
5030
+ return getStateBefore(this, line + 1, precise);
5031
+ },
5032
+
5033
+ cursorCoords: function(start, mode) {
5034
+ var pos, range = this.doc.sel.primary();
5035
+ if (start == null) pos = range.head;
5036
+ else if (typeof start == "object") pos = clipPos(this.doc, start);
5037
+ else pos = start ? range.from() : range.to();
5038
+ return cursorCoords(this, pos, mode || "page");
5039
+ },
5040
+
5041
+ charCoords: function(pos, mode) {
5042
+ return charCoords(this, clipPos(this.doc, pos), mode || "page");
5043
+ },
5044
+
5045
+ coordsChar: function(coords, mode) {
5046
+ coords = fromCoordSystem(this, coords, mode || "page");
5047
+ return coordsChar(this, coords.left, coords.top);
5048
+ },
5049
+
5050
+ lineAtHeight: function(height, mode) {
5051
+ height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top;
5052
+ return lineAtHeight(this.doc, height + this.display.viewOffset);
5053
+ },
5054
+ heightAtLine: function(line, mode) {
5055
+ var end = false, lineObj;
5056
+ if (typeof line == "number") {
5057
+ var last = this.doc.first + this.doc.size - 1;
5058
+ if (line < this.doc.first) line = this.doc.first;
5059
+ else if (line > last) { line = last; end = true; }
5060
+ lineObj = getLine(this.doc, line);
5061
+ } else {
5062
+ lineObj = line;
5063
+ }
5064
+ return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page").top +
5065
+ (end ? this.doc.height - heightAtLine(lineObj) : 0);
5066
+ },
5067
+
5068
+ defaultTextHeight: function() { return textHeight(this.display); },
5069
+ defaultCharWidth: function() { return charWidth(this.display); },
5070
+
5071
+ setGutterMarker: methodOp(function(line, gutterID, value) {
5072
+ return changeLine(this.doc, line, "gutter", function(line) {
5073
+ var markers = line.gutterMarkers || (line.gutterMarkers = {});
5074
+ markers[gutterID] = value;
5075
+ if (!value && isEmpty(markers)) line.gutterMarkers = null;
5076
+ return true;
5077
+ });
5078
+ }),
5079
+
5080
+ clearGutter: methodOp(function(gutterID) {
5081
+ var cm = this, doc = cm.doc, i = doc.first;
5082
+ doc.iter(function(line) {
5083
+ if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
5084
+ line.gutterMarkers[gutterID] = null;
5085
+ regLineChange(cm, i, "gutter");
5086
+ if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null;
5087
+ }
5088
+ ++i;
5089
+ });
5090
+ }),
5091
+
5092
+ lineInfo: function(line) {
5093
+ if (typeof line == "number") {
5094
+ if (!isLine(this.doc, line)) return null;
5095
+ var n = line;
5096
+ line = getLine(this.doc, line);
5097
+ if (!line) return null;
5098
+ } else {
5099
+ var n = lineNo(line);
5100
+ if (n == null) return null;
5101
+ }
5102
+ return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,
5103
+ textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,
5104
+ widgets: line.widgets};
5105
+ },
5106
+
5107
+ getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo};},
5108
+
5109
+ addWidget: function(pos, node, scroll, vert, horiz) {
5110
+ var display = this.display;
5111
+ pos = cursorCoords(this, clipPos(this.doc, pos));
5112
+ var top = pos.bottom, left = pos.left;
5113
+ node.style.position = "absolute";
5114
+ node.setAttribute("cm-ignore-events", "true");
5115
+ this.display.input.setUneditable(node);
5116
+ display.sizer.appendChild(node);
5117
+ if (vert == "over") {
5118
+ top = pos.top;
5119
+ } else if (vert == "above" || vert == "near") {
5120
+ var vspace = Math.max(display.wrapper.clientHeight, this.doc.height),
5121
+ hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth);
5122
+ // Default to positioning above (if specified and possible); otherwise default to positioning below
5123
+ if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight)
5124
+ top = pos.top - node.offsetHeight;
5125
+ else if (pos.bottom + node.offsetHeight <= vspace)
5126
+ top = pos.bottom;
5127
+ if (left + node.offsetWidth > hspace)
5128
+ left = hspace - node.offsetWidth;
5129
+ }
5130
+ node.style.top = top + "px";
5131
+ node.style.left = node.style.right = "";
5132
+ if (horiz == "right") {
5133
+ left = display.sizer.clientWidth - node.offsetWidth;
5134
+ node.style.right = "0px";
5135
+ } else {
5136
+ if (horiz == "left") left = 0;
5137
+ else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2;
5138
+ node.style.left = left + "px";
5139
+ }
5140
+ if (scroll)
5141
+ scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight);
5142
+ },
5143
+
5144
+ triggerOnKeyDown: methodOp(onKeyDown),
5145
+ triggerOnKeyPress: methodOp(onKeyPress),
5146
+ triggerOnKeyUp: onKeyUp,
5147
+
5148
+ execCommand: function(cmd) {
5149
+ if (commands.hasOwnProperty(cmd))
5150
+ return commands[cmd].call(null, this);
5151
+ },
5152
+
5153
+ triggerElectric: methodOp(function(text) { triggerElectric(this, text); }),
5154
+
5155
+ findPosH: function(from, amount, unit, visually) {
5156
+ var dir = 1;
5157
+ if (amount < 0) { dir = -1; amount = -amount; }
5158
+ for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
5159
+ cur = findPosH(this.doc, cur, dir, unit, visually);
5160
+ if (cur.hitSide) break;
5161
+ }
5162
+ return cur;
5163
+ },
5164
+
5165
+ moveH: methodOp(function(dir, unit) {
5166
+ var cm = this;
5167
+ cm.extendSelectionsBy(function(range) {
5168
+ if (cm.display.shift || cm.doc.extend || range.empty())
5169
+ return findPosH(cm.doc, range.head, dir, unit, cm.options.rtlMoveVisually);
5170
+ else
5171
+ return dir < 0 ? range.from() : range.to();
5172
+ }, sel_move);
5173
+ }),
5174
+
5175
+ deleteH: methodOp(function(dir, unit) {
5176
+ var sel = this.doc.sel, doc = this.doc;
5177
+ if (sel.somethingSelected())
5178
+ doc.replaceSelection("", null, "+delete");
5179
+ else
5180
+ deleteNearSelection(this, function(range) {
5181
+ var other = findPosH(doc, range.head, dir, unit, false);
5182
+ return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other};
5183
+ });
5184
+ }),
5185
+
5186
+ findPosV: function(from, amount, unit, goalColumn) {
5187
+ var dir = 1, x = goalColumn;
5188
+ if (amount < 0) { dir = -1; amount = -amount; }
5189
+ for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
5190
+ var coords = cursorCoords(this, cur, "div");
5191
+ if (x == null) x = coords.left;
5192
+ else coords.left = x;
5193
+ cur = findPosV(this, coords, dir, unit);
5194
+ if (cur.hitSide) break;
5195
+ }
5196
+ return cur;
5197
+ },
5198
+
5199
+ moveV: methodOp(function(dir, unit) {
5200
+ var cm = this, doc = this.doc, goals = [];
5201
+ var collapse = !cm.display.shift && !doc.extend && doc.sel.somethingSelected();
5202
+ doc.extendSelectionsBy(function(range) {
5203
+ if (collapse)
5204
+ return dir < 0 ? range.from() : range.to();
5205
+ var headPos = cursorCoords(cm, range.head, "div");
5206
+ if (range.goalColumn != null) headPos.left = range.goalColumn;
5207
+ goals.push(headPos.left);
5208
+ var pos = findPosV(cm, headPos, dir, unit);
5209
+ if (unit == "page" && range == doc.sel.primary())
5210
+ addToScrollPos(cm, null, charCoords(cm, pos, "div").top - headPos.top);
5211
+ return pos;
5212
+ }, sel_move);
5213
+ if (goals.length) for (var i = 0; i < doc.sel.ranges.length; i++)
5214
+ doc.sel.ranges[i].goalColumn = goals[i];
5215
+ }),
5216
+
5217
+ // Find the word at the given position (as returned by coordsChar).
5218
+ findWordAt: function(pos) {
5219
+ var doc = this.doc, line = getLine(doc, pos.line).text;
5220
+ var start = pos.ch, end = pos.ch;
5221
+ if (line) {
5222
+ var helper = this.getHelper(pos, "wordChars");
5223
+ if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end;
5224
+ var startChar = line.charAt(start);
5225
+ var check = isWordChar(startChar, helper)
5226
+ ? function(ch) { return isWordChar(ch, helper); }
5227
+ : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);}
5228
+ : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);};
5229
+ while (start > 0 && check(line.charAt(start - 1))) --start;
5230
+ while (end < line.length && check(line.charAt(end))) ++end;
5231
+ }
5232
+ return new Range(Pos(pos.line, start), Pos(pos.line, end));
5233
+ },
5234
+
5235
+ toggleOverwrite: function(value) {
5236
+ if (value != null && value == this.state.overwrite) return;
5237
+ if (this.state.overwrite = !this.state.overwrite)
5238
+ addClass(this.display.cursorDiv, "CodeMirror-overwrite");
5239
+ else
5240
+ rmClass(this.display.cursorDiv, "CodeMirror-overwrite");
5241
+
5242
+ signal(this, "overwriteToggle", this, this.state.overwrite);
5243
+ },
5244
+ hasFocus: function() { return this.display.input.getField() == activeElt(); },
5245
+ isReadOnly: function() { return !!(this.options.readOnly || this.doc.cantEdit); },
5246
+
5247
+ scrollTo: methodOp(function(x, y) {
5248
+ if (x != null || y != null) resolveScrollToPos(this);
5249
+ if (x != null) this.curOp.scrollLeft = x;
5250
+ if (y != null) this.curOp.scrollTop = y;
5251
+ }),
5252
+ getScrollInfo: function() {
5253
+ var scroller = this.display.scroller;
5254
+ return {left: scroller.scrollLeft, top: scroller.scrollTop,
5255
+ height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight,
5256
+ width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth,
5257
+ clientHeight: displayHeight(this), clientWidth: displayWidth(this)};
5258
+ },
5259
+
5260
+ scrollIntoView: methodOp(function(range, margin) {
5261
+ if (range == null) {
5262
+ range = {from: this.doc.sel.primary().head, to: null};
5263
+ if (margin == null) margin = this.options.cursorScrollMargin;
5264
+ } else if (typeof range == "number") {
5265
+ range = {from: Pos(range, 0), to: null};
5266
+ } else if (range.from == null) {
5267
+ range = {from: range, to: null};
5268
+ }
5269
+ if (!range.to) range.to = range.from;
5270
+ range.margin = margin || 0;
5271
+
5272
+ if (range.from.line != null) {
5273
+ resolveScrollToPos(this);
5274
+ this.curOp.scrollToPos = range;
5275
+ } else {
5276
+ var sPos = calculateScrollPos(this, Math.min(range.from.left, range.to.left),
5277
+ Math.min(range.from.top, range.to.top) - range.margin,
5278
+ Math.max(range.from.right, range.to.right),
5279
+ Math.max(range.from.bottom, range.to.bottom) + range.margin);
5280
+ this.scrollTo(sPos.scrollLeft, sPos.scrollTop);
5281
+ }
5282
+ }),
5283
+
5284
+ setSize: methodOp(function(width, height) {
5285
+ var cm = this;
5286
+ function interpret(val) {
5287
+ return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val;
5288
+ }
5289
+ if (width != null) cm.display.wrapper.style.width = interpret(width);
5290
+ if (height != null) cm.display.wrapper.style.height = interpret(height);
5291
+ if (cm.options.lineWrapping) clearLineMeasurementCache(this);
5292
+ var lineNo = cm.display.viewFrom;
5293
+ cm.doc.iter(lineNo, cm.display.viewTo, function(line) {
5294
+ if (line.widgets) for (var i = 0; i < line.widgets.length; i++)
5295
+ if (line.widgets[i].noHScroll) { regLineChange(cm, lineNo, "widget"); break; }
5296
+ ++lineNo;
5297
+ });
5298
+ cm.curOp.forceUpdate = true;
5299
+ signal(cm, "refresh", this);
5300
+ }),
5301
+
5302
+ operation: function(f){return runInOp(this, f);},
5303
+
5304
+ refresh: methodOp(function() {
5305
+ var oldHeight = this.display.cachedTextHeight;
5306
+ regChange(this);
5307
+ this.curOp.forceUpdate = true;
5308
+ clearCaches(this);
5309
+ this.scrollTo(this.doc.scrollLeft, this.doc.scrollTop);
5310
+ updateGutterSpace(this);
5311
+ if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)
5312
+ estimateLineHeights(this);
5313
+ signal(this, "refresh", this);
5314
+ }),
5315
+
5316
+ swapDoc: methodOp(function(doc) {
5317
+ var old = this.doc;
5318
+ old.cm = null;
5319
+ attachDoc(this, doc);
5320
+ clearCaches(this);
5321
+ this.display.input.reset();
5322
+ this.scrollTo(doc.scrollLeft, doc.scrollTop);
5323
+ this.curOp.forceScroll = true;
5324
+ signalLater(this, "swapDoc", this, old);
5325
+ return old;
5326
+ }),
5327
+
5328
+ getInputField: function(){return this.display.input.getField();},
5329
+ getWrapperElement: function(){return this.display.wrapper;},
5330
+ getScrollerElement: function(){return this.display.scroller;},
5331
+ getGutterElement: function(){return this.display.gutters;}
5332
+ };
5333
+ eventMixin(CodeMirror);
5334
+
5335
+ // OPTION DEFAULTS
5336
+
5337
+ // The default configuration options.
5338
+ var defaults = CodeMirror.defaults = {};
5339
+ // Functions to run when options are changed.
5340
+ var optionHandlers = CodeMirror.optionHandlers = {};
5341
+
5342
+ function option(name, deflt, handle, notOnInit) {
5343
+ CodeMirror.defaults[name] = deflt;
5344
+ if (handle) optionHandlers[name] =
5345
+ notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle;
5346
+ }
5347
+
5348
+ // Passed to option handlers when there is no old value.
5349
+ var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}};
5350
+
5351
+ // These two are, on init, called from the constructor because they
5352
+ // have to be initialized before the editor can start at all.
5353
+ option("value", "", function(cm, val) {
5354
+ cm.setValue(val);
5355
+ }, true);
5356
+ option("mode", null, function(cm, val) {
5357
+ cm.doc.modeOption = val;
5358
+ loadMode(cm);
5359
+ }, true);
5360
+
5361
+ option("indentUnit", 2, loadMode, true);
5362
+ option("indentWithTabs", false);
5363
+ option("smartIndent", true);
5364
+ option("tabSize", 4, function(cm) {
5365
+ resetModeState(cm);
5366
+ clearCaches(cm);
5367
+ regChange(cm);
5368
+ }, true);
5369
+ option("lineSeparator", null, function(cm, val) {
5370
+ cm.doc.lineSep = val;
5371
+ if (!val) return;
5372
+ var newBreaks = [], lineNo = cm.doc.first;
5373
+ cm.doc.iter(function(line) {
5374
+ for (var pos = 0;;) {
5375
+ var found = line.text.indexOf(val, pos);
5376
+ if (found == -1) break;
5377
+ pos = found + val.length;
5378
+ newBreaks.push(Pos(lineNo, found));
5379
+ }
5380
+ lineNo++;
5381
+ });
5382
+ for (var i = newBreaks.length - 1; i >= 0; i--)
5383
+ replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length))
5384
+ });
5385
+ option("specialChars", /[\t\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g, function(cm, val, old) {
5386
+ cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
5387
+ if (old != CodeMirror.Init) cm.refresh();
5388
+ });
5389
+ option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true);
5390
+ option("electricChars", true);
5391
+ option("inputStyle", mobile ? "contenteditable" : "textarea", function() {
5392
+ throw new Error("inputStyle can not (yet) be changed in a running editor"); // FIXME
5393
+ }, true);
5394
+ option("rtlMoveVisually", !windows);
5395
+ option("wholeLineUpdateBefore", true);
5396
+
5397
+ option("theme", "default", function(cm) {
5398
+ themeChanged(cm);
5399
+ guttersChanged(cm);
5400
+ }, true);
5401
+ option("keyMap", "default", function(cm, val, old) {
5402
+ var next = getKeyMap(val);
5403
+ var prev = old != CodeMirror.Init && getKeyMap(old);
5404
+ if (prev && prev.detach) prev.detach(cm, next);
5405
+ if (next.attach) next.attach(cm, prev || null);
5406
+ });
5407
+ option("extraKeys", null);
5408
+
5409
+ option("lineWrapping", false, wrappingChanged, true);
5410
+ option("gutters", [], function(cm) {
5411
+ setGuttersForLineNumbers(cm.options);
5412
+ guttersChanged(cm);
5413
+ }, true);
5414
+ option("fixedGutter", true, function(cm, val) {
5415
+ cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0";
5416
+ cm.refresh();
5417
+ }, true);
5418
+ option("coverGutterNextToScrollbar", false, function(cm) {updateScrollbars(cm);}, true);
5419
+ option("scrollbarStyle", "native", function(cm) {
5420
+ initScrollbars(cm);
5421
+ updateScrollbars(cm);
5422
+ cm.display.scrollbars.setScrollTop(cm.doc.scrollTop);
5423
+ cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft);
5424
+ }, true);
5425
+ option("lineNumbers", false, function(cm) {
5426
+ setGuttersForLineNumbers(cm.options);
5427
+ guttersChanged(cm);
5428
+ }, true);
5429
+ option("firstLineNumber", 1, guttersChanged, true);
5430
+ option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true);
5431
+ option("showCursorWhenSelecting", false, updateSelection, true);
5432
+
5433
+ option("resetSelectionOnContextMenu", true);
5434
+ option("lineWiseCopyCut", true);
5435
+
5436
+ option("readOnly", false, function(cm, val) {
5437
+ if (val == "nocursor") {
5438
+ onBlur(cm);
5439
+ cm.display.input.blur();
5440
+ cm.display.disabled = true;
5441
+ } else {
5442
+ cm.display.disabled = false;
5443
+ }
5444
+ cm.display.input.readOnlyChanged(val)
5445
+ });
5446
+ option("disableInput", false, function(cm, val) {if (!val) cm.display.input.reset();}, true);
5447
+ option("dragDrop", true, dragDropChanged);
5448
+ option("allowDropFileTypes", null);
5449
+
5450
+ option("cursorBlinkRate", 530);
5451
+ option("cursorScrollMargin", 0);
5452
+ option("cursorHeight", 1, updateSelection, true);
5453
+ option("singleCursorHeightPerLine", true, updateSelection, true);
5454
+ option("workTime", 100);
5455
+ option("workDelay", 100);
5456
+ option("flattenSpans", true, resetModeState, true);
5457
+ option("addModeClass", false, resetModeState, true);
5458
+ option("pollInterval", 100);
5459
+ option("undoDepth", 200, function(cm, val){cm.doc.history.undoDepth = val;});
5460
+ option("historyEventDelay", 1250);
5461
+ option("viewportMargin", 10, function(cm){cm.refresh();}, true);
5462
+ option("maxHighlightLength", 10000, resetModeState, true);
5463
+ option("moveInputWithCursor", true, function(cm, val) {
5464
+ if (!val) cm.display.input.resetPosition();
5465
+ });
5466
+
5467
+ option("tabindex", null, function(cm, val) {
5468
+ cm.display.input.getField().tabIndex = val || "";
5469
+ });
5470
+ option("autofocus", null);
5471
+
5472
+ // MODE DEFINITION AND QUERYING
5473
+
5474
+ // Known modes, by name and by MIME
5475
+ var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
5476
+
5477
+ // Extra arguments are stored as the mode's dependencies, which is
5478
+ // used by (legacy) mechanisms like loadmode.js to automatically
5479
+ // load a mode. (Preferred mechanism is the require/define calls.)
5480
+ CodeMirror.defineMode = function(name, mode) {
5481
+ if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
5482
+ if (arguments.length > 2)
5483
+ mode.dependencies = Array.prototype.slice.call(arguments, 2);
5484
+ modes[name] = mode;
5485
+ };
5486
+
5487
+ CodeMirror.defineMIME = function(mime, spec) {
5488
+ mimeModes[mime] = spec;
5489
+ };
5490
+
5491
+ // Given a MIME type, a {name, ...options} config object, or a name
5492
+ // string, return a mode config object.
5493
+ CodeMirror.resolveMode = function(spec) {
5494
+ if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
5495
+ spec = mimeModes[spec];
5496
+ } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
5497
+ var found = mimeModes[spec.name];
5498
+ if (typeof found == "string") found = {name: found};
5499
+ spec = createObj(found, spec);
5500
+ spec.name = found.name;
5501
+ } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
5502
+ return CodeMirror.resolveMode("application/xml");
5503
+ }
5504
+ if (typeof spec == "string") return {name: spec};
5505
+ else return spec || {name: "null"};
5506
+ };
5507
+
5508
+ // Given a mode spec (anything that resolveMode accepts), find and
5509
+ // initialize an actual mode object.
5510
+ CodeMirror.getMode = function(options, spec) {
5511
+ var spec = CodeMirror.resolveMode(spec);
5512
+ var mfactory = modes[spec.name];
5513
+ if (!mfactory) return CodeMirror.getMode(options, "text/plain");
5514
+ var modeObj = mfactory(options, spec);
5515
+ if (modeExtensions.hasOwnProperty(spec.name)) {
5516
+ var exts = modeExtensions[spec.name];
5517
+ for (var prop in exts) {
5518
+ if (!exts.hasOwnProperty(prop)) continue;
5519
+ if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
5520
+ modeObj[prop] = exts[prop];
5521
+ }
5522
+ }
5523
+ modeObj.name = spec.name;
5524
+ if (spec.helperType) modeObj.helperType = spec.helperType;
5525
+ if (spec.modeProps) for (var prop in spec.modeProps)
5526
+ modeObj[prop] = spec.modeProps[prop];
5527
+
5528
+ return modeObj;
5529
+ };
5530
+
5531
+ // Minimal default mode.
5532
+ CodeMirror.defineMode("null", function() {
5533
+ return {token: function(stream) {stream.skipToEnd();}};
5534
+ });
5535
+ CodeMirror.defineMIME("text/plain", "null");
5536
+
5537
+ // This can be used to attach properties to mode objects from
5538
+ // outside the actual mode definition.
5539
+ var modeExtensions = CodeMirror.modeExtensions = {};
5540
+ CodeMirror.extendMode = function(mode, properties) {
5541
+ var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
5542
+ copyObj(properties, exts);
5543
+ };
5544
+
5545
+ // EXTENSIONS
5546
+
5547
+ CodeMirror.defineExtension = function(name, func) {
5548
+ CodeMirror.prototype[name] = func;
5549
+ };
5550
+ CodeMirror.defineDocExtension = function(name, func) {
5551
+ Doc.prototype[name] = func;
5552
+ };
5553
+ CodeMirror.defineOption = option;
5554
+
5555
+ var initHooks = [];
5556
+ CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
5557
+
5558
+ var helpers = CodeMirror.helpers = {};
5559
+ CodeMirror.registerHelper = function(type, name, value) {
5560
+ if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {_global: []};
5561
+ helpers[type][name] = value;
5562
+ };
5563
+ CodeMirror.registerGlobalHelper = function(type, name, predicate, value) {
5564
+ CodeMirror.registerHelper(type, name, value);
5565
+ helpers[type]._global.push({pred: predicate, val: value});
5566
+ };
5567
+
5568
+ // MODE STATE HANDLING
5569
+
5570
+ // Utility functions for working with state. Exported because nested
5571
+ // modes need to do this for their inner modes.
5572
+
5573
+ var copyState = CodeMirror.copyState = function(mode, state) {
5574
+ if (state === true) return state;
5575
+ if (mode.copyState) return mode.copyState(state);
5576
+ var nstate = {};
5577
+ for (var n in state) {
5578
+ var val = state[n];
5579
+ if (val instanceof Array) val = val.concat([]);
5580
+ nstate[n] = val;
5581
+ }
5582
+ return nstate;
5583
+ };
5584
+
5585
+ var startState = CodeMirror.startState = function(mode, a1, a2) {
5586
+ return mode.startState ? mode.startState(a1, a2) : true;
5587
+ };
5588
+
5589
+ // Given a mode and a state (for that mode), find the inner mode and
5590
+ // state at the position that the state refers to.
5591
+ CodeMirror.innerMode = function(mode, state) {
5592
+ while (mode.innerMode) {
5593
+ var info = mode.innerMode(state);
5594
+ if (!info || info.mode == mode) break;
5595
+ state = info.state;
5596
+ mode = info.mode;
5597
+ }
5598
+ return info || {mode: mode, state: state};
5599
+ };
5600
+
5601
+ // STANDARD COMMANDS
5602
+
5603
+ // Commands are parameter-less actions that can be performed on an
5604
+ // editor, mostly used for keybindings.
5605
+ var commands = CodeMirror.commands = {
5606
+ selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);},
5607
+ singleSelection: function(cm) {
5608
+ cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll);
5609
+ },
5610
+ killLine: function(cm) {
5611
+ deleteNearSelection(cm, function(range) {
5612
+ if (range.empty()) {
5613
+ var len = getLine(cm.doc, range.head.line).text.length;
5614
+ if (range.head.ch == len && range.head.line < cm.lastLine())
5615
+ return {from: range.head, to: Pos(range.head.line + 1, 0)};
5616
+ else
5617
+ return {from: range.head, to: Pos(range.head.line, len)};
5618
+ } else {
5619
+ return {from: range.from(), to: range.to()};
5620
+ }
5621
+ });
5622
+ },
5623
+ deleteLine: function(cm) {
5624
+ deleteNearSelection(cm, function(range) {
5625
+ return {from: Pos(range.from().line, 0),
5626
+ to: clipPos(cm.doc, Pos(range.to().line + 1, 0))};
5627
+ });
5628
+ },
5629
+ delLineLeft: function(cm) {
5630
+ deleteNearSelection(cm, function(range) {
5631
+ return {from: Pos(range.from().line, 0), to: range.from()};
5632
+ });
5633
+ },
5634
+ delWrappedLineLeft: function(cm) {
5635
+ deleteNearSelection(cm, function(range) {
5636
+ var top = cm.charCoords(range.head, "div").top + 5;
5637
+ var leftPos = cm.coordsChar({left: 0, top: top}, "div");
5638
+ return {from: leftPos, to: range.from()};
5639
+ });
5640
+ },
5641
+ delWrappedLineRight: function(cm) {
5642
+ deleteNearSelection(cm, function(range) {
5643
+ var top = cm.charCoords(range.head, "div").top + 5;
5644
+ var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div");
5645
+ return {from: range.from(), to: rightPos };
5646
+ });
5647
+ },
5648
+ undo: function(cm) {cm.undo();},
5649
+ redo: function(cm) {cm.redo();},
5650
+ undoSelection: function(cm) {cm.undoSelection();},
5651
+ redoSelection: function(cm) {cm.redoSelection();},
5652
+ goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));},
5653
+ goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));},
5654
+ goLineStart: function(cm) {
5655
+ cm.extendSelectionsBy(function(range) { return lineStart(cm, range.head.line); },
5656
+ {origin: "+move", bias: 1});
5657
+ },
5658
+ goLineStartSmart: function(cm) {
5659
+ cm.extendSelectionsBy(function(range) {
5660
+ return lineStartSmart(cm, range.head);
5661
+ }, {origin: "+move", bias: 1});
5662
+ },
5663
+ goLineEnd: function(cm) {
5664
+ cm.extendSelectionsBy(function(range) { return lineEnd(cm, range.head.line); },
5665
+ {origin: "+move", bias: -1});
5666
+ },
5667
+ goLineRight: function(cm) {
5668
+ cm.extendSelectionsBy(function(range) {
5669
+ var top = cm.charCoords(range.head, "div").top + 5;
5670
+ return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div");
5671
+ }, sel_move);
5672
+ },
5673
+ goLineLeft: function(cm) {
5674
+ cm.extendSelectionsBy(function(range) {
5675
+ var top = cm.charCoords(range.head, "div").top + 5;
5676
+ return cm.coordsChar({left: 0, top: top}, "div");
5677
+ }, sel_move);
5678
+ },
5679
+ goLineLeftSmart: function(cm) {
5680
+ cm.extendSelectionsBy(function(range) {
5681
+ var top = cm.charCoords(range.head, "div").top + 5;
5682
+ var pos = cm.coordsChar({left: 0, top: top}, "div");
5683
+ if (pos.ch < cm.getLine(pos.line).search(/\S/)) return lineStartSmart(cm, range.head);
5684
+ return pos;
5685
+ }, sel_move);
5686
+ },
5687
+ goLineUp: function(cm) {cm.moveV(-1, "line");},
5688
+ goLineDown: function(cm) {cm.moveV(1, "line");},
5689
+ goPageUp: function(cm) {cm.moveV(-1, "page");},
5690
+ goPageDown: function(cm) {cm.moveV(1, "page");},
5691
+ goCharLeft: function(cm) {cm.moveH(-1, "char");},
5692
+ goCharRight: function(cm) {cm.moveH(1, "char");},
5693
+ goColumnLeft: function(cm) {cm.moveH(-1, "column");},
5694
+ goColumnRight: function(cm) {cm.moveH(1, "column");},
5695
+ goWordLeft: function(cm) {cm.moveH(-1, "word");},
5696
+ goGroupRight: function(cm) {cm.moveH(1, "group");},
5697
+ goGroupLeft: function(cm) {cm.moveH(-1, "group");},
5698
+ goWordRight: function(cm) {cm.moveH(1, "word");},
5699
+ delCharBefore: function(cm) {cm.deleteH(-1, "char");},
5700
+ delCharAfter: function(cm) {cm.deleteH(1, "char");},
5701
+ delWordBefore: function(cm) {cm.deleteH(-1, "word");},
5702
+ delWordAfter: function(cm) {cm.deleteH(1, "word");},
5703
+ delGroupBefore: function(cm) {cm.deleteH(-1, "group");},
5704
+ delGroupAfter: function(cm) {cm.deleteH(1, "group");},
5705
+ indentAuto: function(cm) {cm.indentSelection("smart");},
5706
+ indentMore: function(cm) {cm.indentSelection("add");},
5707
+ indentLess: function(cm) {cm.indentSelection("subtract");},
5708
+ insertTab: function(cm) {cm.replaceSelection("\t");},
5709
+ insertSoftTab: function(cm) {
5710
+ var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize;
5711
+ for (var i = 0; i < ranges.length; i++) {
5712
+ var pos = ranges[i].from();
5713
+ var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize);
5714
+ spaces.push(new Array(tabSize - col % tabSize + 1).join(" "));
5715
+ }
5716
+ cm.replaceSelections(spaces);
5717
+ },
5718
+ defaultTab: function(cm) {
5719
+ if (cm.somethingSelected()) cm.indentSelection("add");
5720
+ else cm.execCommand("insertTab");
5721
+ },
5722
+ transposeChars: function(cm) {
5723
+ runInOp(cm, function() {
5724
+ var ranges = cm.listSelections(), newSel = [];
5725
+ for (var i = 0; i < ranges.length; i++) {
5726
+ var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text;
5727
+ if (line) {
5728
+ if (cur.ch == line.length) cur = new Pos(cur.line, cur.ch - 1);
5729
+ if (cur.ch > 0) {
5730
+ cur = new Pos(cur.line, cur.ch + 1);
5731
+ cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2),
5732
+ Pos(cur.line, cur.ch - 2), cur, "+transpose");
5733
+ } else if (cur.line > cm.doc.first) {
5734
+ var prev = getLine(cm.doc, cur.line - 1).text;
5735
+ if (prev)
5736
+ cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() +
5737
+ prev.charAt(prev.length - 1),
5738
+ Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose");
5739
+ }
5740
+ }
5741
+ newSel.push(new Range(cur, cur));
5742
+ }
5743
+ cm.setSelections(newSel);
5744
+ });
5745
+ },
5746
+ newlineAndIndent: function(cm) {
5747
+ runInOp(cm, function() {
5748
+ var len = cm.listSelections().length;
5749
+ for (var i = 0; i < len; i++) {
5750
+ var range = cm.listSelections()[i];
5751
+ cm.replaceRange(cm.doc.lineSeparator(), range.anchor, range.head, "+input");
5752
+ cm.indentLine(range.from().line + 1, null, true);
5753
+ }
5754
+ ensureCursorVisible(cm);
5755
+ });
5756
+ },
5757
+ toggleOverwrite: function(cm) {cm.toggleOverwrite();}
5758
+ };
5759
+
5760
+
5761
+ // STANDARD KEYMAPS
5762
+
5763
+ var keyMap = CodeMirror.keyMap = {};
5764
+
5765
+ keyMap.basic = {
5766
+ "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
5767
+ "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
5768
+ "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore",
5769
+ "Tab": "defaultTab", "Shift-Tab": "indentAuto",
5770
+ "Enter": "newlineAndIndent", "Insert": "toggleOverwrite",
5771
+ "Esc": "singleSelection"
5772
+ };
5773
+ // Note that the save and find-related commands aren't defined by
5774
+ // default. User code or addons can define them. Unknown commands
5775
+ // are simply ignored.
5776
+ keyMap.pcDefault = {
5777
+ "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
5778
+ "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown",
5779
+ "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
5780
+ "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
5781
+ "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
5782
+ "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
5783
+ "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection",
5784
+ fallthrough: "basic"
5785
+ };
5786
+ // Very basic readline/emacs-style bindings, which are standard on Mac.
5787
+ keyMap.emacsy = {
5788
+ "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
5789
+ "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
5790
+ "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
5791
+ "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
5792
+ };
5793
+ keyMap.macDefault = {
5794
+ "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
5795
+ "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
5796
+ "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore",
5797
+ "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
5798
+ "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
5799
+ "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight",
5800
+ "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd",
5801
+ fallthrough: ["basic", "emacsy"]
5802
+ };
5803
+ keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
5804
+
5805
+ // KEYMAP DISPATCH
5806
+
5807
+ function normalizeKeyName(name) {
5808
+ var parts = name.split(/-(?!$)/), name = parts[parts.length - 1];
5809
+ var alt, ctrl, shift, cmd;
5810
+ for (var i = 0; i < parts.length - 1; i++) {
5811
+ var mod = parts[i];
5812
+ if (/^(cmd|meta|m)$/i.test(mod)) cmd = true;
5813
+ else if (/^a(lt)?$/i.test(mod)) alt = true;
5814
+ else if (/^(c|ctrl|control)$/i.test(mod)) ctrl = true;
5815
+ else if (/^s(hift)$/i.test(mod)) shift = true;
5816
+ else throw new Error("Unrecognized modifier name: " + mod);
5817
+ }
5818
+ if (alt) name = "Alt-" + name;
5819
+ if (ctrl) name = "Ctrl-" + name;
5820
+ if (cmd) name = "Cmd-" + name;
5821
+ if (shift) name = "Shift-" + name;
5822
+ return name;
5823
+ }
5824
+
5825
+ // This is a kludge to keep keymaps mostly working as raw objects
5826
+ // (backwards compatibility) while at the same time support features
5827
+ // like normalization and multi-stroke key bindings. It compiles a
5828
+ // new normalized keymap, and then updates the old object to reflect
5829
+ // this.
5830
+ CodeMirror.normalizeKeyMap = function(keymap) {
5831
+ var copy = {};
5832
+ for (var keyname in keymap) if (keymap.hasOwnProperty(keyname)) {
5833
+ var value = keymap[keyname];
5834
+ if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) continue;
5835
+ if (value == "...") { delete keymap[keyname]; continue; }
5836
+
5837
+ var keys = map(keyname.split(" "), normalizeKeyName);
5838
+ for (var i = 0; i < keys.length; i++) {
5839
+ var val, name;
5840
+ if (i == keys.length - 1) {
5841
+ name = keys.join(" ");
5842
+ val = value;
5843
+ } else {
5844
+ name = keys.slice(0, i + 1).join(" ");
5845
+ val = "...";
5846
+ }
5847
+ var prev = copy[name];
5848
+ if (!prev) copy[name] = val;
5849
+ else if (prev != val) throw new Error("Inconsistent bindings for " + name);
5850
+ }
5851
+ delete keymap[keyname];
5852
+ }
5853
+ for (var prop in copy) keymap[prop] = copy[prop];
5854
+ return keymap;
5855
+ };
5856
+
5857
+ var lookupKey = CodeMirror.lookupKey = function(key, map, handle, context) {
5858
+ map = getKeyMap(map);
5859
+ var found = map.call ? map.call(key, context) : map[key];
5860
+ if (found === false) return "nothing";
5861
+ if (found === "...") return "multi";
5862
+ if (found != null && handle(found)) return "handled";
5863
+
5864
+ if (map.fallthrough) {
5865
+ if (Object.prototype.toString.call(map.fallthrough) != "[object Array]")
5866
+ return lookupKey(key, map.fallthrough, handle, context);
5867
+ for (var i = 0; i < map.fallthrough.length; i++) {
5868
+ var result = lookupKey(key, map.fallthrough[i], handle, context);
5869
+ if (result) return result;
5870
+ }
5871
+ }
5872
+ };
5873
+
5874
+ // Modifier key presses don't count as 'real' key presses for the
5875
+ // purpose of keymap fallthrough.
5876
+ var isModifierKey = CodeMirror.isModifierKey = function(value) {
5877
+ var name = typeof value == "string" ? value : keyNames[value.keyCode];
5878
+ return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
5879
+ };
5880
+
5881
+ // Look up the name of a key as indicated by an event object.
5882
+ var keyName = CodeMirror.keyName = function(event, noShift) {
5883
+ if (presto && event.keyCode == 34 && event["char"]) return false;
5884
+ var base = keyNames[event.keyCode], name = base;
5885
+ if (name == null || event.altGraphKey) return false;
5886
+ if (event.altKey && base != "Alt") name = "Alt-" + name;
5887
+ if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") name = "Ctrl-" + name;
5888
+ if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") name = "Cmd-" + name;
5889
+ if (!noShift && event.shiftKey && base != "Shift") name = "Shift-" + name;
5890
+ return name;
5891
+ };
5892
+
5893
+ function getKeyMap(val) {
5894
+ return typeof val == "string" ? keyMap[val] : val;
5895
+ }
5896
+
5897
+ // FROMTEXTAREA
5898
+
5899
+ CodeMirror.fromTextArea = function(textarea, options) {
5900
+ options = options ? copyObj(options) : {};
5901
+ options.value = textarea.value;
5902
+ if (!options.tabindex && textarea.tabIndex)
5903
+ options.tabindex = textarea.tabIndex;
5904
+ if (!options.placeholder && textarea.placeholder)
5905
+ options.placeholder = textarea.placeholder;
5906
+ // Set autofocus to true if this textarea is focused, or if it has
5907
+ // autofocus and no other element is focused.
5908
+ if (options.autofocus == null) {
5909
+ var hasFocus = activeElt();
5910
+ options.autofocus = hasFocus == textarea ||
5911
+ textarea.getAttribute("autofocus") != null && hasFocus == document.body;
5912
+ }
5913
+
5914
+ function save() {textarea.value = cm.getValue();}
5915
+ if (textarea.form) {
5916
+ on(textarea.form, "submit", save);
5917
+ // Deplorable hack to make the submit method do the right thing.
5918
+ if (!options.leaveSubmitMethodAlone) {
5919
+ var form = textarea.form, realSubmit = form.submit;
5920
+ try {
5921
+ var wrappedSubmit = form.submit = function() {
5922
+ save();
5923
+ form.submit = realSubmit;
5924
+ form.submit();
5925
+ form.submit = wrappedSubmit;
5926
+ };
5927
+ } catch(e) {}
5928
+ }
5929
+ }
5930
+
5931
+ options.finishInit = function(cm) {
5932
+ cm.save = save;
5933
+ cm.getTextArea = function() { return textarea; };
5934
+ cm.toTextArea = function() {
5935
+ cm.toTextArea = isNaN; // Prevent this from being ran twice
5936
+ save();
5937
+ textarea.parentNode.removeChild(cm.getWrapperElement());
5938
+ textarea.style.display = "";
5939
+ if (textarea.form) {
5940
+ off(textarea.form, "submit", save);
5941
+ if (typeof textarea.form.submit == "function")
5942
+ textarea.form.submit = realSubmit;
5943
+ }
5944
+ };
5945
+ };
5946
+
5947
+ textarea.style.display = "none";
5948
+ var cm = CodeMirror(function(node) {
5949
+ textarea.parentNode.insertBefore(node, textarea.nextSibling);
5950
+ }, options);
5951
+ return cm;
5952
+ };
5953
+
5954
+ // STRING STREAM
5955
+
5956
+ // Fed to the mode parsers, provides helper functions to make
5957
+ // parsers more succinct.
5958
+
5959
+ var StringStream = CodeMirror.StringStream = function(string, tabSize) {
5960
+ this.pos = this.start = 0;
5961
+ this.string = string;
5962
+ this.tabSize = tabSize || 8;
5963
+ this.lastColumnPos = this.lastColumnValue = 0;
5964
+ this.lineStart = 0;
5965
+ };
5966
+
5967
+ StringStream.prototype = {
5968
+ eol: function() {return this.pos >= this.string.length;},
5969
+ sol: function() {return this.pos == this.lineStart;},
5970
+ peek: function() {return this.string.charAt(this.pos) || undefined;},
5971
+ next: function() {
5972
+ if (this.pos < this.string.length)
5973
+ return this.string.charAt(this.pos++);
5974
+ },
5975
+ eat: function(match) {
5976
+ var ch = this.string.charAt(this.pos);
5977
+ if (typeof match == "string") var ok = ch == match;
5978
+ else var ok = ch && (match.test ? match.test(ch) : match(ch));
5979
+ if (ok) {++this.pos; return ch;}
5980
+ },
5981
+ eatWhile: function(match) {
5982
+ var start = this.pos;
5983
+ while (this.eat(match)){}
5984
+ return this.pos > start;
5985
+ },
5986
+ eatSpace: function() {
5987
+ var start = this.pos;
5988
+ while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
5989
+ return this.pos > start;
5990
+ },
5991
+ skipToEnd: function() {this.pos = this.string.length;},
5992
+ skipTo: function(ch) {
5993
+ var found = this.string.indexOf(ch, this.pos);
5994
+ if (found > -1) {this.pos = found; return true;}
5995
+ },
5996
+ backUp: function(n) {this.pos -= n;},
5997
+ column: function() {
5998
+ if (this.lastColumnPos < this.start) {
5999
+ this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
6000
+ this.lastColumnPos = this.start;
6001
+ }
6002
+ return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
6003
+ },
6004
+ indentation: function() {
6005
+ return countColumn(this.string, null, this.tabSize) -
6006
+ (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
6007
+ },
6008
+ match: function(pattern, consume, caseInsensitive) {
6009
+ if (typeof pattern == "string") {
6010
+ var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
6011
+ var substr = this.string.substr(this.pos, pattern.length);
6012
+ if (cased(substr) == cased(pattern)) {
6013
+ if (consume !== false) this.pos += pattern.length;
6014
+ return true;
6015
+ }
6016
+ } else {
6017
+ var match = this.string.slice(this.pos).match(pattern);
6018
+ if (match && match.index > 0) return null;
6019
+ if (match && consume !== false) this.pos += match[0].length;
6020
+ return match;
6021
+ }
6022
+ },
6023
+ current: function(){return this.string.slice(this.start, this.pos);},
6024
+ hideFirstChars: function(n, inner) {
6025
+ this.lineStart += n;
6026
+ try { return inner(); }
6027
+ finally { this.lineStart -= n; }
6028
+ }
6029
+ };
6030
+
6031
+ // TEXTMARKERS
6032
+
6033
+ // Created with markText and setBookmark methods. A TextMarker is a
6034
+ // handle that can be used to clear or find a marked position in the
6035
+ // document. Line objects hold arrays (markedSpans) containing
6036
+ // {from, to, marker} object pointing to such marker objects, and
6037
+ // indicating that such a marker is present on that line. Multiple
6038
+ // lines may point to the same marker when it spans across lines.
6039
+ // The spans will have null for their from/to properties when the
6040
+ // marker continues beyond the start/end of the line. Markers have
6041
+ // links back to the lines they currently touch.
6042
+
6043
+ var nextMarkerId = 0;
6044
+
6045
+ var TextMarker = CodeMirror.TextMarker = function(doc, type) {
6046
+ this.lines = [];
6047
+ this.type = type;
6048
+ this.doc = doc;
6049
+ this.id = ++nextMarkerId;
6050
+ };
6051
+ eventMixin(TextMarker);
6052
+
6053
+ // Clear the marker.
6054
+ TextMarker.prototype.clear = function() {
6055
+ if (this.explicitlyCleared) return;
6056
+ var cm = this.doc.cm, withOp = cm && !cm.curOp;
6057
+ if (withOp) startOperation(cm);
6058
+ if (hasHandler(this, "clear")) {
6059
+ var found = this.find();
6060
+ if (found) signalLater(this, "clear", found.from, found.to);
6061
+ }
6062
+ var min = null, max = null;
6063
+ for (var i = 0; i < this.lines.length; ++i) {
6064
+ var line = this.lines[i];
6065
+ var span = getMarkedSpanFor(line.markedSpans, this);
6066
+ if (cm && !this.collapsed) regLineChange(cm, lineNo(line), "text");
6067
+ else if (cm) {
6068
+ if (span.to != null) max = lineNo(line);
6069
+ if (span.from != null) min = lineNo(line);
6070
+ }
6071
+ line.markedSpans = removeMarkedSpan(line.markedSpans, span);
6072
+ if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm)
6073
+ updateLineHeight(line, textHeight(cm.display));
6074
+ }
6075
+ if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) {
6076
+ var visual = visualLine(this.lines[i]), len = lineLength(visual);
6077
+ if (len > cm.display.maxLineLength) {
6078
+ cm.display.maxLine = visual;
6079
+ cm.display.maxLineLength = len;
6080
+ cm.display.maxLineChanged = true;
6081
+ }
6082
+ }
6083
+
6084
+ if (min != null && cm && this.collapsed) regChange(cm, min, max + 1);
6085
+ this.lines.length = 0;
6086
+ this.explicitlyCleared = true;
6087
+ if (this.atomic && this.doc.cantEdit) {
6088
+ this.doc.cantEdit = false;
6089
+ if (cm) reCheckSelection(cm.doc);
6090
+ }
6091
+ if (cm) signalLater(cm, "markerCleared", cm, this);
6092
+ if (withOp) endOperation(cm);
6093
+ if (this.parent) this.parent.clear();
6094
+ };
6095
+
6096
+ // Find the position of the marker in the document. Returns a {from,
6097
+ // to} object by default. Side can be passed to get a specific side
6098
+ // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the
6099
+ // Pos objects returned contain a line object, rather than a line
6100
+ // number (used to prevent looking up the same line twice).
6101
+ TextMarker.prototype.find = function(side, lineObj) {
6102
+ if (side == null && this.type == "bookmark") side = 1;
6103
+ var from, to;
6104
+ for (var i = 0; i < this.lines.length; ++i) {
6105
+ var line = this.lines[i];
6106
+ var span = getMarkedSpanFor(line.markedSpans, this);
6107
+ if (span.from != null) {
6108
+ from = Pos(lineObj ? line : lineNo(line), span.from);
6109
+ if (side == -1) return from;
6110
+ }
6111
+ if (span.to != null) {
6112
+ to = Pos(lineObj ? line : lineNo(line), span.to);
6113
+ if (side == 1) return to;
6114
+ }
6115
+ }
6116
+ return from && {from: from, to: to};
6117
+ };
6118
+
6119
+ // Signals that the marker's widget changed, and surrounding layout
6120
+ // should be recomputed.
6121
+ TextMarker.prototype.changed = function() {
6122
+ var pos = this.find(-1, true), widget = this, cm = this.doc.cm;
6123
+ if (!pos || !cm) return;
6124
+ runInOp(cm, function() {
6125
+ var line = pos.line, lineN = lineNo(pos.line);
6126
+ var view = findViewForLine(cm, lineN);
6127
+ if (view) {
6128
+ clearLineMeasurementCacheFor(view);
6129
+ cm.curOp.selectionChanged = cm.curOp.forceUpdate = true;
6130
+ }
6131
+ cm.curOp.updateMaxLine = true;
6132
+ if (!lineIsHidden(widget.doc, line) && widget.height != null) {
6133
+ var oldHeight = widget.height;
6134
+ widget.height = null;
6135
+ var dHeight = widgetHeight(widget) - oldHeight;
6136
+ if (dHeight)
6137
+ updateLineHeight(line, line.height + dHeight);
6138
+ }
6139
+ });
6140
+ };
6141
+
6142
+ TextMarker.prototype.attachLine = function(line) {
6143
+ if (!this.lines.length && this.doc.cm) {
6144
+ var op = this.doc.cm.curOp;
6145
+ if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)
6146
+ (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this);
6147
+ }
6148
+ this.lines.push(line);
6149
+ };
6150
+ TextMarker.prototype.detachLine = function(line) {
6151
+ this.lines.splice(indexOf(this.lines, line), 1);
6152
+ if (!this.lines.length && this.doc.cm) {
6153
+ var op = this.doc.cm.curOp;
6154
+ (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
6155
+ }
6156
+ };
6157
+
6158
+ // Collapsed markers have unique ids, in order to be able to order
6159
+ // them, which is needed for uniquely determining an outer marker
6160
+ // when they overlap (they may nest, but not partially overlap).
6161
+ var nextMarkerId = 0;
6162
+
6163
+ // Create a marker, wire it up to the right lines, and
6164
+ function markText(doc, from, to, options, type) {
6165
+ // Shared markers (across linked documents) are handled separately
6166
+ // (markTextShared will call out to this again, once per
6167
+ // document).
6168
+ if (options && options.shared) return markTextShared(doc, from, to, options, type);
6169
+ // Ensure we are in an operation.
6170
+ if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);
6171
+
6172
+ var marker = new TextMarker(doc, type), diff = cmp(from, to);
6173
+ if (options) copyObj(options, marker, false);
6174
+ // Don't connect empty markers unless clearWhenEmpty is false
6175
+ if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false)
6176
+ return marker;
6177
+ if (marker.replacedWith) {
6178
+ // Showing up as a widget implies collapsed (widget replaces text)
6179
+ marker.collapsed = true;
6180
+ marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget");
6181
+ if (!options.handleMouseEvents) marker.widgetNode.setAttribute("cm-ignore-events", "true");
6182
+ if (options.insertLeft) marker.widgetNode.insertLeft = true;
6183
+ }
6184
+ if (marker.collapsed) {
6185
+ if (conflictingCollapsedRange(doc, from.line, from, to, marker) ||
6186
+ from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker))
6187
+ throw new Error("Inserting collapsed marker partially overlapping an existing one");
6188
+ sawCollapsedSpans = true;
6189
+ }
6190
+
6191
+ if (marker.addToHistory)
6192
+ addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN);
6193
+
6194
+ var curLine = from.line, cm = doc.cm, updateMaxLine;
6195
+ doc.iter(curLine, to.line + 1, function(line) {
6196
+ if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine)
6197
+ updateMaxLine = true;
6198
+ if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0);
6199
+ addMarkedSpan(line, new MarkedSpan(marker,
6200
+ curLine == from.line ? from.ch : null,
6201
+ curLine == to.line ? to.ch : null));
6202
+ ++curLine;
6203
+ });
6204
+ // lineIsHidden depends on the presence of the spans, so needs a second pass
6205
+ if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) {
6206
+ if (lineIsHidden(doc, line)) updateLineHeight(line, 0);
6207
+ });
6208
+
6209
+ if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); });
6210
+
6211
+ if (marker.readOnly) {
6212
+ sawReadOnlySpans = true;
6213
+ if (doc.history.done.length || doc.history.undone.length)
6214
+ doc.clearHistory();
6215
+ }
6216
+ if (marker.collapsed) {
6217
+ marker.id = ++nextMarkerId;
6218
+ marker.atomic = true;
6219
+ }
6220
+ if (cm) {
6221
+ // Sync editor state
6222
+ if (updateMaxLine) cm.curOp.updateMaxLine = true;
6223
+ if (marker.collapsed)
6224
+ regChange(cm, from.line, to.line + 1);
6225
+ else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css)
6226
+ for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, "text");
6227
+ if (marker.atomic) reCheckSelection(cm.doc);
6228
+ signalLater(cm, "markerAdded", cm, marker);
6229
+ }
6230
+ return marker;
6231
+ }
6232
+
6233
+ // SHARED TEXTMARKERS
6234
+
6235
+ // A shared marker spans multiple linked documents. It is
6236
+ // implemented as a meta-marker-object controlling multiple normal
6237
+ // markers.
6238
+ var SharedTextMarker = CodeMirror.SharedTextMarker = function(markers, primary) {
6239
+ this.markers = markers;
6240
+ this.primary = primary;
6241
+ for (var i = 0; i < markers.length; ++i)
6242
+ markers[i].parent = this;
6243
+ };
6244
+ eventMixin(SharedTextMarker);
6245
+
6246
+ SharedTextMarker.prototype.clear = function() {
6247
+ if (this.explicitlyCleared) return;
6248
+ this.explicitlyCleared = true;
6249
+ for (var i = 0; i < this.markers.length; ++i)
6250
+ this.markers[i].clear();
6251
+ signalLater(this, "clear");
6252
+ };
6253
+ SharedTextMarker.prototype.find = function(side, lineObj) {
6254
+ return this.primary.find(side, lineObj);
6255
+ };
6256
+
6257
+ function markTextShared(doc, from, to, options, type) {
6258
+ options = copyObj(options);
6259
+ options.shared = false;
6260
+ var markers = [markText(doc, from, to, options, type)], primary = markers[0];
6261
+ var widget = options.widgetNode;
6262
+ linkedDocs(doc, function(doc) {
6263
+ if (widget) options.widgetNode = widget.cloneNode(true);
6264
+ markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
6265
+ for (var i = 0; i < doc.linked.length; ++i)
6266
+ if (doc.linked[i].isParent) return;
6267
+ primary = lst(markers);
6268
+ });
6269
+ return new SharedTextMarker(markers, primary);
6270
+ }
6271
+
6272
+ function findSharedMarkers(doc) {
6273
+ return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())),
6274
+ function(m) { return m.parent; });
6275
+ }
6276
+
6277
+ function copySharedMarkers(doc, markers) {
6278
+ for (var i = 0; i < markers.length; i++) {
6279
+ var marker = markers[i], pos = marker.find();
6280
+ var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to);
6281
+ if (cmp(mFrom, mTo)) {
6282
+ var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type);
6283
+ marker.markers.push(subMark);
6284
+ subMark.parent = marker;
6285
+ }
6286
+ }
6287
+ }
6288
+
6289
+ function detachSharedMarkers(markers) {
6290
+ for (var i = 0; i < markers.length; i++) {
6291
+ var marker = markers[i], linked = [marker.primary.doc];;
6292
+ linkedDocs(marker.primary.doc, function(d) { linked.push(d); });
6293
+ for (var j = 0; j < marker.markers.length; j++) {
6294
+ var subMarker = marker.markers[j];
6295
+ if (indexOf(linked, subMarker.doc) == -1) {
6296
+ subMarker.parent = null;
6297
+ marker.markers.splice(j--, 1);
6298
+ }
6299
+ }
6300
+ }
6301
+ }
6302
+
6303
+ // TEXTMARKER SPANS
6304
+
6305
+ function MarkedSpan(marker, from, to) {
6306
+ this.marker = marker;
6307
+ this.from = from; this.to = to;
6308
+ }
6309
+
6310
+ // Search an array of spans for a span matching the given marker.
6311
+ function getMarkedSpanFor(spans, marker) {
6312
+ if (spans) for (var i = 0; i < spans.length; ++i) {
6313
+ var span = spans[i];
6314
+ if (span.marker == marker) return span;
6315
+ }
6316
+ }
6317
+ // Remove a span from an array, returning undefined if no spans are
6318
+ // left (we don't store arrays for lines without spans).
6319
+ function removeMarkedSpan(spans, span) {
6320
+ for (var r, i = 0; i < spans.length; ++i)
6321
+ if (spans[i] != span) (r || (r = [])).push(spans[i]);
6322
+ return r;
6323
+ }
6324
+ // Add a span to a line.
6325
+ function addMarkedSpan(line, span) {
6326
+ line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
6327
+ span.marker.attachLine(line);
6328
+ }
6329
+
6330
+ // Used for the algorithm that adjusts markers for a change in the
6331
+ // document. These functions cut an array of spans at a given
6332
+ // character position, returning an array of remaining chunks (or
6333
+ // undefined if nothing remains).
6334
+ function markedSpansBefore(old, startCh, isInsert) {
6335
+ if (old) for (var i = 0, nw; i < old.length; ++i) {
6336
+ var span = old[i], marker = span.marker;
6337
+ var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
6338
+ if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) {
6339
+ var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
6340
+ (nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to));
6341
+ }
6342
+ }
6343
+ return nw;
6344
+ }
6345
+ function markedSpansAfter(old, endCh, isInsert) {
6346
+ if (old) for (var i = 0, nw; i < old.length; ++i) {
6347
+ var span = old[i], marker = span.marker;
6348
+ var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
6349
+ if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) {
6350
+ var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
6351
+ (nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh,
6352
+ span.to == null ? null : span.to - endCh));
6353
+ }
6354
+ }
6355
+ return nw;
6356
+ }
6357
+
6358
+ // Given a change object, compute the new set of marker spans that
6359
+ // cover the line in which the change took place. Removes spans
6360
+ // entirely within the change, reconnects spans belonging to the
6361
+ // same marker that appear on both sides of the change, and cuts off
6362
+ // spans partially within the change. Returns an array of span
6363
+ // arrays with one element for each line in (after) the change.
6364
+ function stretchSpansOverChange(doc, change) {
6365
+ if (change.full) return null;
6366
+ var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
6367
+ var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
6368
+ if (!oldFirst && !oldLast) return null;
6369
+
6370
+ var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0;
6371
+ // Get the spans that 'stick out' on both sides
6372
+ var first = markedSpansBefore(oldFirst, startCh, isInsert);
6373
+ var last = markedSpansAfter(oldLast, endCh, isInsert);
6374
+
6375
+ // Next, merge those two ends
6376
+ var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
6377
+ if (first) {
6378
+ // Fix up .to properties of first
6379
+ for (var i = 0; i < first.length; ++i) {
6380
+ var span = first[i];
6381
+ if (span.to == null) {
6382
+ var found = getMarkedSpanFor(last, span.marker);
6383
+ if (!found) span.to = startCh;
6384
+ else if (sameLine) span.to = found.to == null ? null : found.to + offset;
6385
+ }
6386
+ }
6387
+ }
6388
+ if (last) {
6389
+ // Fix up .from in last (or move them into first in case of sameLine)
6390
+ for (var i = 0; i < last.length; ++i) {
6391
+ var span = last[i];
6392
+ if (span.to != null) span.to += offset;
6393
+ if (span.from == null) {
6394
+ var found = getMarkedSpanFor(first, span.marker);
6395
+ if (!found) {
6396
+ span.from = offset;
6397
+ if (sameLine) (first || (first = [])).push(span);
6398
+ }
6399
+ } else {
6400
+ span.from += offset;
6401
+ if (sameLine) (first || (first = [])).push(span);
6402
+ }
6403
+ }
6404
+ }
6405
+ // Make sure we didn't create any zero-length spans
6406
+ if (first) first = clearEmptySpans(first);
6407
+ if (last && last != first) last = clearEmptySpans(last);
6408
+
6409
+ var newMarkers = [first];
6410
+ if (!sameLine) {
6411
+ // Fill gap with whole-line-spans
6412
+ var gap = change.text.length - 2, gapMarkers;
6413
+ if (gap > 0 && first)
6414
+ for (var i = 0; i < first.length; ++i)
6415
+ if (first[i].to == null)
6416
+ (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null));
6417
+ for (var i = 0; i < gap; ++i)
6418
+ newMarkers.push(gapMarkers);
6419
+ newMarkers.push(last);
6420
+ }
6421
+ return newMarkers;
6422
+ }
6423
+
6424
+ // Remove spans that are empty and don't have a clearWhenEmpty
6425
+ // option of false.
6426
+ function clearEmptySpans(spans) {
6427
+ for (var i = 0; i < spans.length; ++i) {
6428
+ var span = spans[i];
6429
+ if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false)
6430
+ spans.splice(i--, 1);
6431
+ }
6432
+ if (!spans.length) return null;
6433
+ return spans;
6434
+ }
6435
+
6436
+ // Used for un/re-doing changes from the history. Combines the
6437
+ // result of computing the existing spans with the set of spans that
6438
+ // existed in the history (so that deleting around a span and then
6439
+ // undoing brings back the span).
6440
+ function mergeOldSpans(doc, change) {
6441
+ var old = getOldSpans(doc, change);
6442
+ var stretched = stretchSpansOverChange(doc, change);
6443
+ if (!old) return stretched;
6444
+ if (!stretched) return old;
6445
+
6446
+ for (var i = 0; i < old.length; ++i) {
6447
+ var oldCur = old[i], stretchCur = stretched[i];
6448
+ if (oldCur && stretchCur) {
6449
+ spans: for (var j = 0; j < stretchCur.length; ++j) {
6450
+ var span = stretchCur[j];
6451
+ for (var k = 0; k < oldCur.length; ++k)
6452
+ if (oldCur[k].marker == span.marker) continue spans;
6453
+ oldCur.push(span);
6454
+ }
6455
+ } else if (stretchCur) {
6456
+ old[i] = stretchCur;
6457
+ }
6458
+ }
6459
+ return old;
6460
+ }
6461
+
6462
+ // Used to 'clip' out readOnly ranges when making a change.
6463
+ function removeReadOnlyRanges(doc, from, to) {
6464
+ var markers = null;
6465
+ doc.iter(from.line, to.line + 1, function(line) {
6466
+ if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) {
6467
+ var mark = line.markedSpans[i].marker;
6468
+ if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))
6469
+ (markers || (markers = [])).push(mark);
6470
+ }
6471
+ });
6472
+ if (!markers) return null;
6473
+ var parts = [{from: from, to: to}];
6474
+ for (var i = 0; i < markers.length; ++i) {
6475
+ var mk = markers[i], m = mk.find(0);
6476
+ for (var j = 0; j < parts.length; ++j) {
6477
+ var p = parts[j];
6478
+ if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) continue;
6479
+ var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to);
6480
+ if (dfrom < 0 || !mk.inclusiveLeft && !dfrom)
6481
+ newParts.push({from: p.from, to: m.from});
6482
+ if (dto > 0 || !mk.inclusiveRight && !dto)
6483
+ newParts.push({from: m.to, to: p.to});
6484
+ parts.splice.apply(parts, newParts);
6485
+ j += newParts.length - 1;
6486
+ }
6487
+ }
6488
+ return parts;
6489
+ }
6490
+
6491
+ // Connect or disconnect spans from a line.
6492
+ function detachMarkedSpans(line) {
6493
+ var spans = line.markedSpans;
6494
+ if (!spans) return;
6495
+ for (var i = 0; i < spans.length; ++i)
6496
+ spans[i].marker.detachLine(line);
6497
+ line.markedSpans = null;
6498
+ }
6499
+ function attachMarkedSpans(line, spans) {
6500
+ if (!spans) return;
6501
+ for (var i = 0; i < spans.length; ++i)
6502
+ spans[i].marker.attachLine(line);
6503
+ line.markedSpans = spans;
6504
+ }
6505
+
6506
+ // Helpers used when computing which overlapping collapsed span
6507
+ // counts as the larger one.
6508
+ function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; }
6509
+ function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; }
6510
+
6511
+ // Returns a number indicating which of two overlapping collapsed
6512
+ // spans is larger (and thus includes the other). Falls back to
6513
+ // comparing ids when the spans cover exactly the same range.
6514
+ function compareCollapsedMarkers(a, b) {
6515
+ var lenDiff = a.lines.length - b.lines.length;
6516
+ if (lenDiff != 0) return lenDiff;
6517
+ var aPos = a.find(), bPos = b.find();
6518
+ var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b);
6519
+ if (fromCmp) return -fromCmp;
6520
+ var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b);
6521
+ if (toCmp) return toCmp;
6522
+ return b.id - a.id;
6523
+ }
6524
+
6525
+ // Find out whether a line ends or starts in a collapsed span. If
6526
+ // so, return the marker for that span.
6527
+ function collapsedSpanAtSide(line, start) {
6528
+ var sps = sawCollapsedSpans && line.markedSpans, found;
6529
+ if (sps) for (var sp, i = 0; i < sps.length; ++i) {
6530
+ sp = sps[i];
6531
+ if (sp.marker.collapsed && (start ? sp.from : sp.to) == null &&
6532
+ (!found || compareCollapsedMarkers(found, sp.marker) < 0))
6533
+ found = sp.marker;
6534
+ }
6535
+ return found;
6536
+ }
6537
+ function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); }
6538
+ function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); }
6539
+
6540
+ // Test whether there exists a collapsed span that partially
6541
+ // overlaps (covers the start or end, but not both) of a new span.
6542
+ // Such overlap is not allowed.
6543
+ function conflictingCollapsedRange(doc, lineNo, from, to, marker) {
6544
+ var line = getLine(doc, lineNo);
6545
+ var sps = sawCollapsedSpans && line.markedSpans;
6546
+ if (sps) for (var i = 0; i < sps.length; ++i) {
6547
+ var sp = sps[i];
6548
+ if (!sp.marker.collapsed) continue;
6549
+ var found = sp.marker.find(0);
6550
+ var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker);
6551
+ var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker);
6552
+ if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue;
6553
+ if (fromCmp <= 0 && (cmp(found.to, from) > 0 || (sp.marker.inclusiveRight && marker.inclusiveLeft)) ||
6554
+ fromCmp >= 0 && (cmp(found.from, to) < 0 || (sp.marker.inclusiveLeft && marker.inclusiveRight)))
6555
+ return true;
6556
+ }
6557
+ }
6558
+
6559
+ // A visual line is a line as drawn on the screen. Folding, for
6560
+ // example, can cause multiple logical lines to appear on the same
6561
+ // visual line. This finds the start of the visual line that the
6562
+ // given line is part of (usually that is the line itself).
6563
+ function visualLine(line) {
6564
+ var merged;
6565
+ while (merged = collapsedSpanAtStart(line))
6566
+ line = merged.find(-1, true).line;
6567
+ return line;
6568
+ }
6569
+
6570
+ // Returns an array of logical lines that continue the visual line
6571
+ // started by the argument, or undefined if there are no such lines.
6572
+ function visualLineContinued(line) {
6573
+ var merged, lines;
6574
+ while (merged = collapsedSpanAtEnd(line)) {
6575
+ line = merged.find(1, true).line;
6576
+ (lines || (lines = [])).push(line);
6577
+ }
6578
+ return lines;
6579
+ }
6580
+
6581
+ // Get the line number of the start of the visual line that the
6582
+ // given line number is part of.
6583
+ function visualLineNo(doc, lineN) {
6584
+ var line = getLine(doc, lineN), vis = visualLine(line);
6585
+ if (line == vis) return lineN;
6586
+ return lineNo(vis);
6587
+ }
6588
+ // Get the line number of the start of the next visual line after
6589
+ // the given line.
6590
+ function visualLineEndNo(doc, lineN) {
6591
+ if (lineN > doc.lastLine()) return lineN;
6592
+ var line = getLine(doc, lineN), merged;
6593
+ if (!lineIsHidden(doc, line)) return lineN;
6594
+ while (merged = collapsedSpanAtEnd(line))
6595
+ line = merged.find(1, true).line;
6596
+ return lineNo(line) + 1;
6597
+ }
6598
+
6599
+ // Compute whether a line is hidden. Lines count as hidden when they
6600
+ // are part of a visual line that starts with another line, or when
6601
+ // they are entirely covered by collapsed, non-widget span.
6602
+ function lineIsHidden(doc, line) {
6603
+ var sps = sawCollapsedSpans && line.markedSpans;
6604
+ if (sps) for (var sp, i = 0; i < sps.length; ++i) {
6605
+ sp = sps[i];
6606
+ if (!sp.marker.collapsed) continue;
6607
+ if (sp.from == null) return true;
6608
+ if (sp.marker.widgetNode) continue;
6609
+ if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))
6610
+ return true;
6611
+ }
6612
+ }
6613
+ function lineIsHiddenInner(doc, line, span) {
6614
+ if (span.to == null) {
6615
+ var end = span.marker.find(1, true);
6616
+ return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker));
6617
+ }
6618
+ if (span.marker.inclusiveRight && span.to == line.text.length)
6619
+ return true;
6620
+ for (var sp, i = 0; i < line.markedSpans.length; ++i) {
6621
+ sp = line.markedSpans[i];
6622
+ if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to &&
6623
+ (sp.to == null || sp.to != span.from) &&
6624
+ (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
6625
+ lineIsHiddenInner(doc, line, sp)) return true;
6626
+ }
6627
+ }
6628
+
6629
+ // LINE WIDGETS
6630
+
6631
+ // Line widgets are block elements displayed above or below a line.
6632
+
6633
+ var LineWidget = CodeMirror.LineWidget = function(doc, node, options) {
6634
+ if (options) for (var opt in options) if (options.hasOwnProperty(opt))
6635
+ this[opt] = options[opt];
6636
+ this.doc = doc;
6637
+ this.node = node;
6638
+ };
6639
+ eventMixin(LineWidget);
6640
+
6641
+ function adjustScrollWhenAboveVisible(cm, line, diff) {
6642
+ if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop))
6643
+ addToScrollPos(cm, null, diff);
6644
+ }
6645
+
6646
+ LineWidget.prototype.clear = function() {
6647
+ var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line);
6648
+ if (no == null || !ws) return;
6649
+ for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);
6650
+ if (!ws.length) line.widgets = null;
6651
+ var height = widgetHeight(this);
6652
+ updateLineHeight(line, Math.max(0, line.height - height));
6653
+ if (cm) runInOp(cm, function() {
6654
+ adjustScrollWhenAboveVisible(cm, line, -height);
6655
+ regLineChange(cm, no, "widget");
6656
+ });
6657
+ };
6658
+ LineWidget.prototype.changed = function() {
6659
+ var oldH = this.height, cm = this.doc.cm, line = this.line;
6660
+ this.height = null;
6661
+ var diff = widgetHeight(this) - oldH;
6662
+ if (!diff) return;
6663
+ updateLineHeight(line, line.height + diff);
6664
+ if (cm) runInOp(cm, function() {
6665
+ cm.curOp.forceUpdate = true;
6666
+ adjustScrollWhenAboveVisible(cm, line, diff);
6667
+ });
6668
+ };
6669
+
6670
+ function widgetHeight(widget) {
6671
+ if (widget.height != null) return widget.height;
6672
+ var cm = widget.doc.cm;
6673
+ if (!cm) return 0;
6674
+ if (!contains(document.body, widget.node)) {
6675
+ var parentStyle = "position: relative;";
6676
+ if (widget.coverGutter)
6677
+ parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;";
6678
+ if (widget.noHScroll)
6679
+ parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;";
6680
+ removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle));
6681
+ }
6682
+ return widget.height = widget.node.parentNode.offsetHeight;
6683
+ }
6684
+
6685
+ function addLineWidget(doc, handle, node, options) {
6686
+ var widget = new LineWidget(doc, node, options);
6687
+ var cm = doc.cm;
6688
+ if (cm && widget.noHScroll) cm.display.alignWidgets = true;
6689
+ changeLine(doc, handle, "widget", function(line) {
6690
+ var widgets = line.widgets || (line.widgets = []);
6691
+ if (widget.insertAt == null) widgets.push(widget);
6692
+ else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget);
6693
+ widget.line = line;
6694
+ if (cm && !lineIsHidden(doc, line)) {
6695
+ var aboveVisible = heightAtLine(line) < doc.scrollTop;
6696
+ updateLineHeight(line, line.height + widgetHeight(widget));
6697
+ if (aboveVisible) addToScrollPos(cm, null, widget.height);
6698
+ cm.curOp.forceUpdate = true;
6699
+ }
6700
+ return true;
6701
+ });
6702
+ return widget;
6703
+ }
6704
+
6705
+ // LINE DATA STRUCTURE
6706
+
6707
+ // Line objects. These hold state related to a line, including
6708
+ // highlighting info (the styles array).
6709
+ var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) {
6710
+ this.text = text;
6711
+ attachMarkedSpans(this, markedSpans);
6712
+ this.height = estimateHeight ? estimateHeight(this) : 1;
6713
+ };
6714
+ eventMixin(Line);
6715
+ Line.prototype.lineNo = function() { return lineNo(this); };
6716
+
6717
+ // Change the content (text, markers) of a line. Automatically
6718
+ // invalidates cached information and tries to re-estimate the
6719
+ // line's height.
6720
+ function updateLine(line, text, markedSpans, estimateHeight) {
6721
+ line.text = text;
6722
+ if (line.stateAfter) line.stateAfter = null;
6723
+ if (line.styles) line.styles = null;
6724
+ if (line.order != null) line.order = null;
6725
+ detachMarkedSpans(line);
6726
+ attachMarkedSpans(line, markedSpans);
6727
+ var estHeight = estimateHeight ? estimateHeight(line) : 1;
6728
+ if (estHeight != line.height) updateLineHeight(line, estHeight);
6729
+ }
6730
+
6731
+ // Detach a line from the document tree and its markers.
6732
+ function cleanUpLine(line) {
6733
+ line.parent = null;
6734
+ detachMarkedSpans(line);
6735
+ }
6736
+
6737
+ function extractLineClasses(type, output) {
6738
+ if (type) for (;;) {
6739
+ var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/);
6740
+ if (!lineClass) break;
6741
+ type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length);
6742
+ var prop = lineClass[1] ? "bgClass" : "textClass";
6743
+ if (output[prop] == null)
6744
+ output[prop] = lineClass[2];
6745
+ else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop]))
6746
+ output[prop] += " " + lineClass[2];
6747
+ }
6748
+ return type;
6749
+ }
6750
+
6751
+ function callBlankLine(mode, state) {
6752
+ if (mode.blankLine) return mode.blankLine(state);
6753
+ if (!mode.innerMode) return;
6754
+ var inner = CodeMirror.innerMode(mode, state);
6755
+ if (inner.mode.blankLine) return inner.mode.blankLine(inner.state);
6756
+ }
6757
+
6758
+ function readToken(mode, stream, state, inner) {
6759
+ for (var i = 0; i < 10; i++) {
6760
+ if (inner) inner[0] = CodeMirror.innerMode(mode, state).mode;
6761
+ var style = mode.token(stream, state);
6762
+ if (stream.pos > stream.start) return style;
6763
+ }
6764
+ throw new Error("Mode " + mode.name + " failed to advance stream.");
6765
+ }
6766
+
6767
+ // Utility for getTokenAt and getLineTokens
6768
+ function takeToken(cm, pos, precise, asArray) {
6769
+ function getObj(copy) {
6770
+ return {start: stream.start, end: stream.pos,
6771
+ string: stream.current(),
6772
+ type: style || null,
6773
+ state: copy ? copyState(doc.mode, state) : state};
6774
+ }
6775
+
6776
+ var doc = cm.doc, mode = doc.mode, style;
6777
+ pos = clipPos(doc, pos);
6778
+ var line = getLine(doc, pos.line), state = getStateBefore(cm, pos.line, precise);
6779
+ var stream = new StringStream(line.text, cm.options.tabSize), tokens;
6780
+ if (asArray) tokens = [];
6781
+ while ((asArray || stream.pos < pos.ch) && !stream.eol()) {
6782
+ stream.start = stream.pos;
6783
+ style = readToken(mode, stream, state);
6784
+ if (asArray) tokens.push(getObj(true));
6785
+ }
6786
+ return asArray ? tokens : getObj();
6787
+ }
6788
+
6789
+ // Run the given mode's parser over a line, calling f for each token.
6790
+ function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) {
6791
+ var flattenSpans = mode.flattenSpans;
6792
+ if (flattenSpans == null) flattenSpans = cm.options.flattenSpans;
6793
+ var curStart = 0, curStyle = null;
6794
+ var stream = new StringStream(text, cm.options.tabSize), style;
6795
+ var inner = cm.options.addModeClass && [null];
6796
+ if (text == "") extractLineClasses(callBlankLine(mode, state), lineClasses);
6797
+ while (!stream.eol()) {
6798
+ if (stream.pos > cm.options.maxHighlightLength) {
6799
+ flattenSpans = false;
6800
+ if (forceToEnd) processLine(cm, text, state, stream.pos);
6801
+ stream.pos = text.length;
6802
+ style = null;
6803
+ } else {
6804
+ style = extractLineClasses(readToken(mode, stream, state, inner), lineClasses);
6805
+ }
6806
+ if (inner) {
6807
+ var mName = inner[0].name;
6808
+ if (mName) style = "m-" + (style ? mName + " " + style : mName);
6809
+ }
6810
+ if (!flattenSpans || curStyle != style) {
6811
+ while (curStart < stream.start) {
6812
+ curStart = Math.min(stream.start, curStart + 50000);
6813
+ f(curStart, curStyle);
6814
+ }
6815
+ curStyle = style;
6816
+ }
6817
+ stream.start = stream.pos;
6818
+ }
6819
+ while (curStart < stream.pos) {
6820
+ // Webkit seems to refuse to render text nodes longer than 57444 characters
6821
+ var pos = Math.min(stream.pos, curStart + 50000);
6822
+ f(pos, curStyle);
6823
+ curStart = pos;
6824
+ }
6825
+ }
6826
+
6827
+ // Compute a style array (an array starting with a mode generation
6828
+ // -- for invalidation -- followed by pairs of end positions and
6829
+ // style strings), which is used to highlight the tokens on the
6830
+ // line.
6831
+ function highlightLine(cm, line, state, forceToEnd) {
6832
+ // A styles array always starts with a number identifying the
6833
+ // mode/overlays that it is based on (for easy invalidation).
6834
+ var st = [cm.state.modeGen], lineClasses = {};
6835
+ // Compute the base array of styles
6836
+ runMode(cm, line.text, cm.doc.mode, state, function(end, style) {
6837
+ st.push(end, style);
6838
+ }, lineClasses, forceToEnd);
6839
+
6840
+ // Run overlays, adjust style array.
6841
+ for (var o = 0; o < cm.state.overlays.length; ++o) {
6842
+ var overlay = cm.state.overlays[o], i = 1, at = 0;
6843
+ runMode(cm, line.text, overlay.mode, true, function(end, style) {
6844
+ var start = i;
6845
+ // Ensure there's a token end at the current position, and that i points at it
6846
+ while (at < end) {
6847
+ var i_end = st[i];
6848
+ if (i_end > end)
6849
+ st.splice(i, 1, end, st[i+1], i_end);
6850
+ i += 2;
6851
+ at = Math.min(end, i_end);
6852
+ }
6853
+ if (!style) return;
6854
+ if (overlay.opaque) {
6855
+ st.splice(start, i - start, end, "cm-overlay " + style);
6856
+ i = start + 2;
6857
+ } else {
6858
+ for (; start < i; start += 2) {
6859
+ var cur = st[start+1];
6860
+ st[start+1] = (cur ? cur + " " : "") + "cm-overlay " + style;
6861
+ }
6862
+ }
6863
+ }, lineClasses);
6864
+ }
6865
+
6866
+ return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null};
6867
+ }
6868
+
6869
+ function getLineStyles(cm, line, updateFrontier) {
6870
+ if (!line.styles || line.styles[0] != cm.state.modeGen) {
6871
+ var state = getStateBefore(cm, lineNo(line));
6872
+ var result = highlightLine(cm, line, line.text.length > cm.options.maxHighlightLength ? copyState(cm.doc.mode, state) : state);
6873
+ line.stateAfter = state;
6874
+ line.styles = result.styles;
6875
+ if (result.classes) line.styleClasses = result.classes;
6876
+ else if (line.styleClasses) line.styleClasses = null;
6877
+ if (updateFrontier === cm.doc.frontier) cm.doc.frontier++;
6878
+ }
6879
+ return line.styles;
6880
+ }
6881
+
6882
+ // Lightweight form of highlight -- proceed over this line and
6883
+ // update state, but don't save a style array. Used for lines that
6884
+ // aren't currently visible.
6885
+ function processLine(cm, text, state, startAt) {
6886
+ var mode = cm.doc.mode;
6887
+ var stream = new StringStream(text, cm.options.tabSize);
6888
+ stream.start = stream.pos = startAt || 0;
6889
+ if (text == "") callBlankLine(mode, state);
6890
+ while (!stream.eol()) {
6891
+ readToken(mode, stream, state);
6892
+ stream.start = stream.pos;
6893
+ }
6894
+ }
6895
+
6896
+ // Convert a style as returned by a mode (either null, or a string
6897
+ // containing one or more styles) to a CSS style. This is cached,
6898
+ // and also looks for line-wide styles.
6899
+ var styleToClassCache = {}, styleToClassCacheWithMode = {};
6900
+ function interpretTokenStyle(style, options) {
6901
+ if (!style || /^\s*$/.test(style)) return null;
6902
+ var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache;
6903
+ return cache[style] ||
6904
+ (cache[style] = style.replace(/\S+/g, "cm-$&"));
6905
+ }
6906
+
6907
+ // Render the DOM representation of the text of a line. Also builds
6908
+ // up a 'line map', which points at the DOM nodes that represent
6909
+ // specific stretches of text, and is used by the measuring code.
6910
+ // The returned object contains the DOM node, this map, and
6911
+ // information about line-wide styles that were set by the mode.
6912
+ function buildLineContent(cm, lineView) {
6913
+ // The padding-right forces the element to have a 'border', which
6914
+ // is needed on Webkit to be able to get line-level bounding
6915
+ // rectangles for it (in measureChar).
6916
+ var content = elt("span", null, null, webkit ? "padding-right: .1px" : null);
6917
+ var builder = {pre: elt("pre", [content], "CodeMirror-line"), content: content,
6918
+ col: 0, pos: 0, cm: cm,
6919
+ splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")};
6920
+ lineView.measure = {};
6921
+
6922
+ // Iterate over the logical lines that make up this visual line.
6923
+ for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) {
6924
+ var line = i ? lineView.rest[i - 1] : lineView.line, order;
6925
+ builder.pos = 0;
6926
+ builder.addToken = buildToken;
6927
+ // Optionally wire in some hacks into the token-rendering
6928
+ // algorithm, to deal with browser quirks.
6929
+ if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line)))
6930
+ builder.addToken = buildTokenBadBidi(builder.addToken, order);
6931
+ builder.map = [];
6932
+ var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line);
6933
+ insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate));
6934
+ if (line.styleClasses) {
6935
+ if (line.styleClasses.bgClass)
6936
+ builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || "");
6937
+ if (line.styleClasses.textClass)
6938
+ builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || "");
6939
+ }
6940
+
6941
+ // Ensure at least a single node is present, for measuring.
6942
+ if (builder.map.length == 0)
6943
+ builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure)));
6944
+
6945
+ // Store the map and a cache object for the current logical line
6946
+ if (i == 0) {
6947
+ lineView.measure.map = builder.map;
6948
+ lineView.measure.cache = {};
6949
+ } else {
6950
+ (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map);
6951
+ (lineView.measure.caches || (lineView.measure.caches = [])).push({});
6952
+ }
6953
+ }
6954
+
6955
+ // See issue #2901
6956
+ if (webkit && /\bcm-tab\b/.test(builder.content.lastChild.className))
6957
+ builder.content.className = "cm-tab-wrap-hack";
6958
+
6959
+ signal(cm, "renderLine", cm, lineView.line, builder.pre);
6960
+ if (builder.pre.className)
6961
+ builder.textClass = joinClasses(builder.pre.className, builder.textClass || "");
6962
+
6963
+ return builder;
6964
+ }
6965
+
6966
+ function defaultSpecialCharPlaceholder(ch) {
6967
+ var token = elt("span", "\u2022", "cm-invalidchar");
6968
+ token.title = "\\u" + ch.charCodeAt(0).toString(16);
6969
+ token.setAttribute("aria-label", token.title);
6970
+ return token;
6971
+ }
6972
+
6973
+ // Build up the DOM representation for a single token, and add it to
6974
+ // the line map. Takes care to render special characters separately.
6975
+ function buildToken(builder, text, style, startStyle, endStyle, title, css) {
6976
+ if (!text) return;
6977
+ var displayText = builder.splitSpaces ? text.replace(/ {3,}/g, splitSpaces) : text;
6978
+ var special = builder.cm.state.specialChars, mustWrap = false;
6979
+ if (!special.test(text)) {
6980
+ builder.col += text.length;
6981
+ var content = document.createTextNode(displayText);
6982
+ builder.map.push(builder.pos, builder.pos + text.length, content);
6983
+ if (ie && ie_version < 9) mustWrap = true;
6984
+ builder.pos += text.length;
6985
+ } else {
6986
+ var content = document.createDocumentFragment(), pos = 0;
6987
+ while (true) {
6988
+ special.lastIndex = pos;
6989
+ var m = special.exec(text);
6990
+ var skipped = m ? m.index - pos : text.length - pos;
6991
+ if (skipped) {
6992
+ var txt = document.createTextNode(displayText.slice(pos, pos + skipped));
6993
+ if (ie && ie_version < 9) content.appendChild(elt("span", [txt]));
6994
+ else content.appendChild(txt);
6995
+ builder.map.push(builder.pos, builder.pos + skipped, txt);
6996
+ builder.col += skipped;
6997
+ builder.pos += skipped;
6998
+ }
6999
+ if (!m) break;
7000
+ pos += skipped + 1;
7001
+ if (m[0] == "\t") {
7002
+ var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
7003
+ var txt = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
7004
+ txt.setAttribute("role", "presentation");
7005
+ txt.setAttribute("cm-text", "\t");
7006
+ builder.col += tabWidth;
7007
+ } else if (m[0] == "\r" || m[0] == "\n") {
7008
+ var txt = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar"));
7009
+ txt.setAttribute("cm-text", m[0]);
7010
+ builder.col += 1;
7011
+ } else {
7012
+ var txt = builder.cm.options.specialCharPlaceholder(m[0]);
7013
+ txt.setAttribute("cm-text", m[0]);
7014
+ if (ie && ie_version < 9) content.appendChild(elt("span", [txt]));
7015
+ else content.appendChild(txt);
7016
+ builder.col += 1;
7017
+ }
7018
+ builder.map.push(builder.pos, builder.pos + 1, txt);
7019
+ builder.pos++;
7020
+ }
7021
+ }
7022
+ if (style || startStyle || endStyle || mustWrap || css) {
7023
+ var fullStyle = style || "";
7024
+ if (startStyle) fullStyle += startStyle;
7025
+ if (endStyle) fullStyle += endStyle;
7026
+ var token = elt("span", [content], fullStyle, css);
7027
+ if (title) token.title = title;
7028
+ return builder.content.appendChild(token);
7029
+ }
7030
+ builder.content.appendChild(content);
7031
+ }
7032
+
7033
+ function splitSpaces(old) {
7034
+ var out = " ";
7035
+ for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0";
7036
+ out += " ";
7037
+ return out;
7038
+ }
7039
+
7040
+ // Work around nonsense dimensions being reported for stretches of
7041
+ // right-to-left text.
7042
+ function buildTokenBadBidi(inner, order) {
7043
+ return function(builder, text, style, startStyle, endStyle, title, css) {
7044
+ style = style ? style + " cm-force-border" : "cm-force-border";
7045
+ var start = builder.pos, end = start + text.length;
7046
+ for (;;) {
7047
+ // Find the part that overlaps with the start of this text
7048
+ for (var i = 0; i < order.length; i++) {
7049
+ var part = order[i];
7050
+ if (part.to > start && part.from <= start) break;
7051
+ }
7052
+ if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title, css);
7053
+ inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css);
7054
+ startStyle = null;
7055
+ text = text.slice(part.to - start);
7056
+ start = part.to;
7057
+ }
7058
+ };
7059
+ }
7060
+
7061
+ function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
7062
+ var widget = !ignoreWidget && marker.widgetNode;
7063
+ if (widget) builder.map.push(builder.pos, builder.pos + size, widget);
7064
+ if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) {
7065
+ if (!widget)
7066
+ widget = builder.content.appendChild(document.createElement("span"));
7067
+ widget.setAttribute("cm-marker", marker.id);
7068
+ }
7069
+ if (widget) {
7070
+ builder.cm.display.input.setUneditable(widget);
7071
+ builder.content.appendChild(widget);
7072
+ }
7073
+ builder.pos += size;
7074
+ }
7075
+
7076
+ // Outputs a number of spans to make up a line, taking highlighting
7077
+ // and marked text into account.
7078
+ function insertLineContent(line, builder, styles) {
7079
+ var spans = line.markedSpans, allText = line.text, at = 0;
7080
+ if (!spans) {
7081
+ for (var i = 1; i < styles.length; i+=2)
7082
+ builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder.cm.options));
7083
+ return;
7084
+ }
7085
+
7086
+ var len = allText.length, pos = 0, i = 1, text = "", style, css;
7087
+ var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
7088
+ for (;;) {
7089
+ if (nextChange == pos) { // Update current marker set
7090
+ spanStyle = spanEndStyle = spanStartStyle = title = css = "";
7091
+ collapsed = null; nextChange = Infinity;
7092
+ var foundBookmarks = [], endStyles
7093
+ for (var j = 0; j < spans.length; ++j) {
7094
+ var sp = spans[j], m = sp.marker;
7095
+ if (m.type == "bookmark" && sp.from == pos && m.widgetNode) {
7096
+ foundBookmarks.push(m);
7097
+ } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) {
7098
+ if (sp.to != null && sp.to != pos && nextChange > sp.to) {
7099
+ nextChange = sp.to;
7100
+ spanEndStyle = "";
7101
+ }
7102
+ if (m.className) spanStyle += " " + m.className;
7103
+ if (m.css) css = (css ? css + ";" : "") + m.css;
7104
+ if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
7105
+ if (m.endStyle && sp.to == nextChange) (endStyles || (endStyles = [])).push(m.endStyle, sp.to)
7106
+ if (m.title && !title) title = m.title;
7107
+ if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))
7108
+ collapsed = sp;
7109
+ } else if (sp.from > pos && nextChange > sp.from) {
7110
+ nextChange = sp.from;
7111
+ }
7112
+ }
7113
+ if (endStyles) for (var j = 0; j < endStyles.length; j += 2)
7114
+ if (endStyles[j + 1] == nextChange) spanEndStyle += " " + endStyles[j]
7115
+
7116
+ if (collapsed && (collapsed.from || 0) == pos) {
7117
+ buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos,
7118
+ collapsed.marker, collapsed.from == null);
7119
+ if (collapsed.to == null) return;
7120
+ if (collapsed.to == pos) collapsed = false;
7121
+ }
7122
+ if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j)
7123
+ buildCollapsedSpan(builder, 0, foundBookmarks[j]);
7124
+ }
7125
+ if (pos >= len) break;
7126
+
7127
+ var upto = Math.min(len, nextChange);
7128
+ while (true) {
7129
+ if (text) {
7130
+ var end = pos + text.length;
7131
+ if (!collapsed) {
7132
+ var tokenText = end > upto ? text.slice(0, upto - pos) : text;
7133
+ builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
7134
+ spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css);
7135
+ }
7136
+ if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
7137
+ pos = end;
7138
+ spanStartStyle = "";
7139
+ }
7140
+ text = allText.slice(at, at = styles[i++]);
7141
+ style = interpretTokenStyle(styles[i++], builder.cm.options);
7142
+ }
7143
+ }
7144
+ }
7145
+
7146
+ // DOCUMENT DATA STRUCTURE
7147
+
7148
+ // By default, updates that start and end at the beginning of a line
7149
+ // are treated specially, in order to make the association of line
7150
+ // widgets and marker elements with the text behave more intuitive.
7151
+ function isWholeLineUpdate(doc, change) {
7152
+ return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" &&
7153
+ (!doc.cm || doc.cm.options.wholeLineUpdateBefore);
7154
+ }
7155
+
7156
+ // Perform a change on the document data structure.
7157
+ function updateDoc(doc, change, markedSpans, estimateHeight) {
7158
+ function spansFor(n) {return markedSpans ? markedSpans[n] : null;}
7159
+ function update(line, text, spans) {
7160
+ updateLine(line, text, spans, estimateHeight);
7161
+ signalLater(line, "change", line, change);
7162
+ }
7163
+ function linesFor(start, end) {
7164
+ for (var i = start, result = []; i < end; ++i)
7165
+ result.push(new Line(text[i], spansFor(i), estimateHeight));
7166
+ return result;
7167
+ }
7168
+
7169
+ var from = change.from, to = change.to, text = change.text;
7170
+ var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
7171
+ var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
7172
+
7173
+ // Adjust the line structure
7174
+ if (change.full) {
7175
+ doc.insert(0, linesFor(0, text.length));
7176
+ doc.remove(text.length, doc.size - text.length);
7177
+ } else if (isWholeLineUpdate(doc, change)) {
7178
+ // This is a whole-line replace. Treated specially to make
7179
+ // sure line objects move the way they are supposed to.
7180
+ var added = linesFor(0, text.length - 1);
7181
+ update(lastLine, lastLine.text, lastSpans);
7182
+ if (nlines) doc.remove(from.line, nlines);
7183
+ if (added.length) doc.insert(from.line, added);
7184
+ } else if (firstLine == lastLine) {
7185
+ if (text.length == 1) {
7186
+ update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
7187
+ } else {
7188
+ var added = linesFor(1, text.length - 1);
7189
+ added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
7190
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
7191
+ doc.insert(from.line + 1, added);
7192
+ }
7193
+ } else if (text.length == 1) {
7194
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0));
7195
+ doc.remove(from.line + 1, nlines);
7196
+ } else {
7197
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
7198
+ update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
7199
+ var added = linesFor(1, text.length - 1);
7200
+ if (nlines > 1) doc.remove(from.line + 1, nlines - 1);
7201
+ doc.insert(from.line + 1, added);
7202
+ }
7203
+
7204
+ signalLater(doc, "change", doc, change);
7205
+ }
7206
+
7207
+ // The document is represented as a BTree consisting of leaves, with
7208
+ // chunk of lines in them, and branches, with up to ten leaves or
7209
+ // other branch nodes below them. The top node is always a branch
7210
+ // node, and is the document object itself (meaning it has
7211
+ // additional methods and properties).
7212
+ //
7213
+ // All nodes have parent links. The tree is used both to go from
7214
+ // line numbers to line objects, and to go from objects to numbers.
7215
+ // It also indexes by height, and is used to convert between height
7216
+ // and line object, and to find the total height of the document.
7217
+ //
7218
+ // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html
7219
+
7220
+ function LeafChunk(lines) {
7221
+ this.lines = lines;
7222
+ this.parent = null;
7223
+ for (var i = 0, height = 0; i < lines.length; ++i) {
7224
+ lines[i].parent = this;
7225
+ height += lines[i].height;
7226
+ }
7227
+ this.height = height;
7228
+ }
7229
+
7230
+ LeafChunk.prototype = {
7231
+ chunkSize: function() { return this.lines.length; },
7232
+ // Remove the n lines at offset 'at'.
7233
+ removeInner: function(at, n) {
7234
+ for (var i = at, e = at + n; i < e; ++i) {
7235
+ var line = this.lines[i];
7236
+ this.height -= line.height;
7237
+ cleanUpLine(line);
7238
+ signalLater(line, "delete");
7239
+ }
7240
+ this.lines.splice(at, n);
7241
+ },
7242
+ // Helper used to collapse a small branch into a single leaf.
7243
+ collapse: function(lines) {
7244
+ lines.push.apply(lines, this.lines);
7245
+ },
7246
+ // Insert the given array of lines at offset 'at', count them as
7247
+ // having the given height.
7248
+ insertInner: function(at, lines, height) {
7249
+ this.height += height;
7250
+ this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
7251
+ for (var i = 0; i < lines.length; ++i) lines[i].parent = this;
7252
+ },
7253
+ // Used to iterate over a part of the tree.
7254
+ iterN: function(at, n, op) {
7255
+ for (var e = at + n; at < e; ++at)
7256
+ if (op(this.lines[at])) return true;
7257
+ }
7258
+ };
7259
+
7260
+ function BranchChunk(children) {
7261
+ this.children = children;
7262
+ var size = 0, height = 0;
7263
+ for (var i = 0; i < children.length; ++i) {
7264
+ var ch = children[i];
7265
+ size += ch.chunkSize(); height += ch.height;
7266
+ ch.parent = this;
7267
+ }
7268
+ this.size = size;
7269
+ this.height = height;
7270
+ this.parent = null;
7271
+ }
7272
+
7273
+ BranchChunk.prototype = {
7274
+ chunkSize: function() { return this.size; },
7275
+ removeInner: function(at, n) {
7276
+ this.size -= n;
7277
+ for (var i = 0; i < this.children.length; ++i) {
7278
+ var child = this.children[i], sz = child.chunkSize();
7279
+ if (at < sz) {
7280
+ var rm = Math.min(n, sz - at), oldHeight = child.height;
7281
+ child.removeInner(at, rm);
7282
+ this.height -= oldHeight - child.height;
7283
+ if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
7284
+ if ((n -= rm) == 0) break;
7285
+ at = 0;
7286
+ } else at -= sz;
7287
+ }
7288
+ // If the result is smaller than 25 lines, ensure that it is a
7289
+ // single leaf node.
7290
+ if (this.size - n < 25 &&
7291
+ (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) {
7292
+ var lines = [];
7293
+ this.collapse(lines);
7294
+ this.children = [new LeafChunk(lines)];
7295
+ this.children[0].parent = this;
7296
+ }
7297
+ },
7298
+ collapse: function(lines) {
7299
+ for (var i = 0; i < this.children.length; ++i) this.children[i].collapse(lines);
7300
+ },
7301
+ insertInner: function(at, lines, height) {
7302
+ this.size += lines.length;
7303
+ this.height += height;
7304
+ for (var i = 0; i < this.children.length; ++i) {
7305
+ var child = this.children[i], sz = child.chunkSize();
7306
+ if (at <= sz) {
7307
+ child.insertInner(at, lines, height);
7308
+ if (child.lines && child.lines.length > 50) {
7309
+ while (child.lines.length > 50) {
7310
+ var spilled = child.lines.splice(child.lines.length - 25, 25);
7311
+ var newleaf = new LeafChunk(spilled);
7312
+ child.height -= newleaf.height;
7313
+ this.children.splice(i + 1, 0, newleaf);
7314
+ newleaf.parent = this;
7315
+ }
7316
+ this.maybeSpill();
7317
+ }
7318
+ break;
7319
+ }
7320
+ at -= sz;
7321
+ }
7322
+ },
7323
+ // When a node has grown, check whether it should be split.
7324
+ maybeSpill: function() {
7325
+ if (this.children.length <= 10) return;
7326
+ var me = this;
7327
+ do {
7328
+ var spilled = me.children.splice(me.children.length - 5, 5);
7329
+ var sibling = new BranchChunk(spilled);
7330
+ if (!me.parent) { // Become the parent node
7331
+ var copy = new BranchChunk(me.children);
7332
+ copy.parent = me;
7333
+ me.children = [copy, sibling];
7334
+ me = copy;
7335
+ } else {
7336
+ me.size -= sibling.size;
7337
+ me.height -= sibling.height;
7338
+ var myIndex = indexOf(me.parent.children, me);
7339
+ me.parent.children.splice(myIndex + 1, 0, sibling);
7340
+ }
7341
+ sibling.parent = me.parent;
7342
+ } while (me.children.length > 10);
7343
+ me.parent.maybeSpill();
7344
+ },
7345
+ iterN: function(at, n, op) {
7346
+ for (var i = 0; i < this.children.length; ++i) {
7347
+ var child = this.children[i], sz = child.chunkSize();
7348
+ if (at < sz) {
7349
+ var used = Math.min(n, sz - at);
7350
+ if (child.iterN(at, used, op)) return true;
7351
+ if ((n -= used) == 0) break;
7352
+ at = 0;
7353
+ } else at -= sz;
7354
+ }
7355
+ }
7356
+ };
7357
+
7358
+ var nextDocId = 0;
7359
+ var Doc = CodeMirror.Doc = function(text, mode, firstLine, lineSep) {
7360
+ if (!(this instanceof Doc)) return new Doc(text, mode, firstLine, lineSep);
7361
+ if (firstLine == null) firstLine = 0;
7362
+
7363
+ BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
7364
+ this.first = firstLine;
7365
+ this.scrollTop = this.scrollLeft = 0;
7366
+ this.cantEdit = false;
7367
+ this.cleanGeneration = 1;
7368
+ this.frontier = firstLine;
7369
+ var start = Pos(firstLine, 0);
7370
+ this.sel = simpleSelection(start);
7371
+ this.history = new History(null);
7372
+ this.id = ++nextDocId;
7373
+ this.modeOption = mode;
7374
+ this.lineSep = lineSep;
7375
+ this.extend = false;
7376
+
7377
+ if (typeof text == "string") text = this.splitLines(text);
7378
+ updateDoc(this, {from: start, to: start, text: text});
7379
+ setSelection(this, simpleSelection(start), sel_dontScroll);
7380
+ };
7381
+
7382
+ Doc.prototype = createObj(BranchChunk.prototype, {
7383
+ constructor: Doc,
7384
+ // Iterate over the document. Supports two forms -- with only one
7385
+ // argument, it calls that for each line in the document. With
7386
+ // three, it iterates over the range given by the first two (with
7387
+ // the second being non-inclusive).
7388
+ iter: function(from, to, op) {
7389
+ if (op) this.iterN(from - this.first, to - from, op);
7390
+ else this.iterN(this.first, this.first + this.size, from);
7391
+ },
7392
+
7393
+ // Non-public interface for adding and removing lines.
7394
+ insert: function(at, lines) {
7395
+ var height = 0;
7396
+ for (var i = 0; i < lines.length; ++i) height += lines[i].height;
7397
+ this.insertInner(at - this.first, lines, height);
7398
+ },
7399
+ remove: function(at, n) { this.removeInner(at - this.first, n); },
7400
+
7401
+ // From here, the methods are part of the public interface. Most
7402
+ // are also available from CodeMirror (editor) instances.
7403
+
7404
+ getValue: function(lineSep) {
7405
+ var lines = getLines(this, this.first, this.first + this.size);
7406
+ if (lineSep === false) return lines;
7407
+ return lines.join(lineSep || this.lineSeparator());
7408
+ },
7409
+ setValue: docMethodOp(function(code) {
7410
+ var top = Pos(this.first, 0), last = this.first + this.size - 1;
7411
+ makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
7412
+ text: this.splitLines(code), origin: "setValue", full: true}, true);
7413
+ setSelection(this, simpleSelection(top));
7414
+ }),
7415
+ replaceRange: function(code, from, to, origin) {
7416
+ from = clipPos(this, from);
7417
+ to = to ? clipPos(this, to) : from;
7418
+ replaceRange(this, code, from, to, origin);
7419
+ },
7420
+ getRange: function(from, to, lineSep) {
7421
+ var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
7422
+ if (lineSep === false) return lines;
7423
+ return lines.join(lineSep || this.lineSeparator());
7424
+ },
7425
+
7426
+ getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},
7427
+
7428
+ getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);},
7429
+ getLineNumber: function(line) {return lineNo(line);},
7430
+
7431
+ getLineHandleVisualStart: function(line) {
7432
+ if (typeof line == "number") line = getLine(this, line);
7433
+ return visualLine(line);
7434
+ },
7435
+
7436
+ lineCount: function() {return this.size;},
7437
+ firstLine: function() {return this.first;},
7438
+ lastLine: function() {return this.first + this.size - 1;},
7439
+
7440
+ clipPos: function(pos) {return clipPos(this, pos);},
7441
+
7442
+ getCursor: function(start) {
7443
+ var range = this.sel.primary(), pos;
7444
+ if (start == null || start == "head") pos = range.head;
7445
+ else if (start == "anchor") pos = range.anchor;
7446
+ else if (start == "end" || start == "to" || start === false) pos = range.to();
7447
+ else pos = range.from();
7448
+ return pos;
7449
+ },
7450
+ listSelections: function() { return this.sel.ranges; },
7451
+ somethingSelected: function() {return this.sel.somethingSelected();},
7452
+
7453
+ setCursor: docMethodOp(function(line, ch, options) {
7454
+ setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options);
7455
+ }),
7456
+ setSelection: docMethodOp(function(anchor, head, options) {
7457
+ setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options);
7458
+ }),
7459
+ extendSelection: docMethodOp(function(head, other, options) {
7460
+ extendSelection(this, clipPos(this, head), other && clipPos(this, other), options);
7461
+ }),
7462
+ extendSelections: docMethodOp(function(heads, options) {
7463
+ extendSelections(this, clipPosArray(this, heads), options);
7464
+ }),
7465
+ extendSelectionsBy: docMethodOp(function(f, options) {
7466
+ var heads = map(this.sel.ranges, f);
7467
+ extendSelections(this, clipPosArray(this, heads), options);
7468
+ }),
7469
+ setSelections: docMethodOp(function(ranges, primary, options) {
7470
+ if (!ranges.length) return;
7471
+ for (var i = 0, out = []; i < ranges.length; i++)
7472
+ out[i] = new Range(clipPos(this, ranges[i].anchor),
7473
+ clipPos(this, ranges[i].head));
7474
+ if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex);
7475
+ setSelection(this, normalizeSelection(out, primary), options);
7476
+ }),
7477
+ addSelection: docMethodOp(function(anchor, head, options) {
7478
+ var ranges = this.sel.ranges.slice(0);
7479
+ ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor)));
7480
+ setSelection(this, normalizeSelection(ranges, ranges.length - 1), options);
7481
+ }),
7482
+
7483
+ getSelection: function(lineSep) {
7484
+ var ranges = this.sel.ranges, lines;
7485
+ for (var i = 0; i < ranges.length; i++) {
7486
+ var sel = getBetween(this, ranges[i].from(), ranges[i].to());
7487
+ lines = lines ? lines.concat(sel) : sel;
7488
+ }
7489
+ if (lineSep === false) return lines;
7490
+ else return lines.join(lineSep || this.lineSeparator());
7491
+ },
7492
+ getSelections: function(lineSep) {
7493
+ var parts = [], ranges = this.sel.ranges;
7494
+ for (var i = 0; i < ranges.length; i++) {
7495
+ var sel = getBetween(this, ranges[i].from(), ranges[i].to());
7496
+ if (lineSep !== false) sel = sel.join(lineSep || this.lineSeparator());
7497
+ parts[i] = sel;
7498
+ }
7499
+ return parts;
7500
+ },
7501
+ replaceSelection: function(code, collapse, origin) {
7502
+ var dup = [];
7503
+ for (var i = 0; i < this.sel.ranges.length; i++)
7504
+ dup[i] = code;
7505
+ this.replaceSelections(dup, collapse, origin || "+input");
7506
+ },
7507
+ replaceSelections: docMethodOp(function(code, collapse, origin) {
7508
+ var changes = [], sel = this.sel;
7509
+ for (var i = 0; i < sel.ranges.length; i++) {
7510
+ var range = sel.ranges[i];
7511
+ changes[i] = {from: range.from(), to: range.to(), text: this.splitLines(code[i]), origin: origin};
7512
+ }
7513
+ var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse);
7514
+ for (var i = changes.length - 1; i >= 0; i--)
7515
+ makeChange(this, changes[i]);
7516
+ if (newSel) setSelectionReplaceHistory(this, newSel);
7517
+ else if (this.cm) ensureCursorVisible(this.cm);
7518
+ }),
7519
+ undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}),
7520
+ redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}),
7521
+ undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}),
7522
+ redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}),
7523
+
7524
+ setExtending: function(val) {this.extend = val;},
7525
+ getExtending: function() {return this.extend;},
7526
+
7527
+ historySize: function() {
7528
+ var hist = this.history, done = 0, undone = 0;
7529
+ for (var i = 0; i < hist.done.length; i++) if (!hist.done[i].ranges) ++done;
7530
+ for (var i = 0; i < hist.undone.length; i++) if (!hist.undone[i].ranges) ++undone;
7531
+ return {undo: done, redo: undone};
7532
+ },
7533
+ clearHistory: function() {this.history = new History(this.history.maxGeneration);},
7534
+
7535
+ markClean: function() {
7536
+ this.cleanGeneration = this.changeGeneration(true);
7537
+ },
7538
+ changeGeneration: function(forceSplit) {
7539
+ if (forceSplit)
7540
+ this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null;
7541
+ return this.history.generation;
7542
+ },
7543
+ isClean: function (gen) {
7544
+ return this.history.generation == (gen || this.cleanGeneration);
7545
+ },
7546
+
7547
+ getHistory: function() {
7548
+ return {done: copyHistoryArray(this.history.done),
7549
+ undone: copyHistoryArray(this.history.undone)};
7550
+ },
7551
+ setHistory: function(histData) {
7552
+ var hist = this.history = new History(this.history.maxGeneration);
7553
+ hist.done = copyHistoryArray(histData.done.slice(0), null, true);
7554
+ hist.undone = copyHistoryArray(histData.undone.slice(0), null, true);
7555
+ },
7556
+
7557
+ addLineClass: docMethodOp(function(handle, where, cls) {
7558
+ return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function(line) {
7559
+ var prop = where == "text" ? "textClass"
7560
+ : where == "background" ? "bgClass"
7561
+ : where == "gutter" ? "gutterClass" : "wrapClass";
7562
+ if (!line[prop]) line[prop] = cls;
7563
+ else if (classTest(cls).test(line[prop])) return false;
7564
+ else line[prop] += " " + cls;
7565
+ return true;
7566
+ });
7567
+ }),
7568
+ removeLineClass: docMethodOp(function(handle, where, cls) {
7569
+ return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function(line) {
7570
+ var prop = where == "text" ? "textClass"
7571
+ : where == "background" ? "bgClass"
7572
+ : where == "gutter" ? "gutterClass" : "wrapClass";
7573
+ var cur = line[prop];
7574
+ if (!cur) return false;
7575
+ else if (cls == null) line[prop] = null;
7576
+ else {
7577
+ var found = cur.match(classTest(cls));
7578
+ if (!found) return false;
7579
+ var end = found.index + found[0].length;
7580
+ line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null;
7581
+ }
7582
+ return true;
7583
+ });
7584
+ }),
7585
+
7586
+ addLineWidget: docMethodOp(function(handle, node, options) {
7587
+ return addLineWidget(this, handle, node, options);
7588
+ }),
7589
+ removeLineWidget: function(widget) { widget.clear(); },
7590
+
7591
+ markText: function(from, to, options) {
7592
+ return markText(this, clipPos(this, from), clipPos(this, to), options, options && options.type || "range");
7593
+ },
7594
+ setBookmark: function(pos, options) {
7595
+ var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
7596
+ insertLeft: options && options.insertLeft,
7597
+ clearWhenEmpty: false, shared: options && options.shared,
7598
+ handleMouseEvents: options && options.handleMouseEvents};
7599
+ pos = clipPos(this, pos);
7600
+ return markText(this, pos, pos, realOpts, "bookmark");
7601
+ },
7602
+ findMarksAt: function(pos) {
7603
+ pos = clipPos(this, pos);
7604
+ var markers = [], spans = getLine(this, pos.line).markedSpans;
7605
+ if (spans) for (var i = 0; i < spans.length; ++i) {
7606
+ var span = spans[i];
7607
+ if ((span.from == null || span.from <= pos.ch) &&
7608
+ (span.to == null || span.to >= pos.ch))
7609
+ markers.push(span.marker.parent || span.marker);
7610
+ }
7611
+ return markers;
7612
+ },
7613
+ findMarks: function(from, to, filter) {
7614
+ from = clipPos(this, from); to = clipPos(this, to);
7615
+ var found = [], lineNo = from.line;
7616
+ this.iter(from.line, to.line + 1, function(line) {
7617
+ var spans = line.markedSpans;
7618
+ if (spans) for (var i = 0; i < spans.length; i++) {
7619
+ var span = spans[i];
7620
+ if (!(lineNo == from.line && from.ch > span.to ||
7621
+ span.from == null && lineNo != from.line||
7622
+ lineNo == to.line && span.from > to.ch) &&
7623
+ (!filter || filter(span.marker)))
7624
+ found.push(span.marker.parent || span.marker);
7625
+ }
7626
+ ++lineNo;
7627
+ });
7628
+ return found;
7629
+ },
7630
+ getAllMarks: function() {
7631
+ var markers = [];
7632
+ this.iter(function(line) {
7633
+ var sps = line.markedSpans;
7634
+ if (sps) for (var i = 0; i < sps.length; ++i)
7635
+ if (sps[i].from != null) markers.push(sps[i].marker);
7636
+ });
7637
+ return markers;
7638
+ },
7639
+
7640
+ posFromIndex: function(off) {
7641
+ var ch, lineNo = this.first;
7642
+ this.iter(function(line) {
7643
+ var sz = line.text.length + 1;
7644
+ if (sz > off) { ch = off; return true; }
7645
+ off -= sz;
7646
+ ++lineNo;
7647
+ });
7648
+ return clipPos(this, Pos(lineNo, ch));
7649
+ },
7650
+ indexFromPos: function (coords) {
7651
+ coords = clipPos(this, coords);
7652
+ var index = coords.ch;
7653
+ if (coords.line < this.first || coords.ch < 0) return 0;
7654
+ this.iter(this.first, coords.line, function (line) {
7655
+ index += line.text.length + 1;
7656
+ });
7657
+ return index;
7658
+ },
7659
+
7660
+ copy: function(copyHistory) {
7661
+ var doc = new Doc(getLines(this, this.first, this.first + this.size),
7662
+ this.modeOption, this.first, this.lineSep);
7663
+ doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
7664
+ doc.sel = this.sel;
7665
+ doc.extend = false;
7666
+ if (copyHistory) {
7667
+ doc.history.undoDepth = this.history.undoDepth;
7668
+ doc.setHistory(this.getHistory());
7669
+ }
7670
+ return doc;
7671
+ },
7672
+
7673
+ linkedDoc: function(options) {
7674
+ if (!options) options = {};
7675
+ var from = this.first, to = this.first + this.size;
7676
+ if (options.from != null && options.from > from) from = options.from;
7677
+ if (options.to != null && options.to < to) to = options.to;
7678
+ var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep);
7679
+ if (options.sharedHist) copy.history = this.history;
7680
+ (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
7681
+ copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
7682
+ copySharedMarkers(copy, findSharedMarkers(this));
7683
+ return copy;
7684
+ },
7685
+ unlinkDoc: function(other) {
7686
+ if (other instanceof CodeMirror) other = other.doc;
7687
+ if (this.linked) for (var i = 0; i < this.linked.length; ++i) {
7688
+ var link = this.linked[i];
7689
+ if (link.doc != other) continue;
7690
+ this.linked.splice(i, 1);
7691
+ other.unlinkDoc(this);
7692
+ detachSharedMarkers(findSharedMarkers(this));
7693
+ break;
7694
+ }
7695
+ // If the histories were shared, split them again
7696
+ if (other.history == this.history) {
7697
+ var splitIds = [other.id];
7698
+ linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true);
7699
+ other.history = new History(null);
7700
+ other.history.done = copyHistoryArray(this.history.done, splitIds);
7701
+ other.history.undone = copyHistoryArray(this.history.undone, splitIds);
7702
+ }
7703
+ },
7704
+ iterLinkedDocs: function(f) {linkedDocs(this, f);},
7705
+
7706
+ getMode: function() {return this.mode;},
7707
+ getEditor: function() {return this.cm;},
7708
+
7709
+ splitLines: function(str) {
7710
+ if (this.lineSep) return str.split(this.lineSep);
7711
+ return splitLinesAuto(str);
7712
+ },
7713
+ lineSeparator: function() { return this.lineSep || "\n"; }
7714
+ });
7715
+
7716
+ // Public alias.
7717
+ Doc.prototype.eachLine = Doc.prototype.iter;
7718
+
7719
+ // Set up methods on CodeMirror's prototype to redirect to the editor's document.
7720
+ var dontDelegate = "iter insert remove copy getEditor constructor".split(" ");
7721
+ for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)
7722
+ CodeMirror.prototype[prop] = (function(method) {
7723
+ return function() {return method.apply(this.doc, arguments);};
7724
+ })(Doc.prototype[prop]);
7725
+
7726
+ eventMixin(Doc);
7727
+
7728
+ // Call f for all linked documents.
7729
+ function linkedDocs(doc, f, sharedHistOnly) {
7730
+ function propagate(doc, skip, sharedHist) {
7731
+ if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) {
7732
+ var rel = doc.linked[i];
7733
+ if (rel.doc == skip) continue;
7734
+ var shared = sharedHist && rel.sharedHist;
7735
+ if (sharedHistOnly && !shared) continue;
7736
+ f(rel.doc, shared);
7737
+ propagate(rel.doc, doc, shared);
7738
+ }
7739
+ }
7740
+ propagate(doc, null, true);
7741
+ }
7742
+
7743
+ // Attach a document to an editor.
7744
+ function attachDoc(cm, doc) {
7745
+ if (doc.cm) throw new Error("This document is already in use.");
7746
+ cm.doc = doc;
7747
+ doc.cm = cm;
7748
+ estimateLineHeights(cm);
7749
+ loadMode(cm);
7750
+ if (!cm.options.lineWrapping) findMaxLine(cm);
7751
+ cm.options.mode = doc.modeOption;
7752
+ regChange(cm);
7753
+ }
7754
+
7755
+ // LINE UTILITIES
7756
+
7757
+ // Find the line object corresponding to the given line number.
7758
+ function getLine(doc, n) {
7759
+ n -= doc.first;
7760
+ if (n < 0 || n >= doc.size) throw new Error("There is no line " + (n + doc.first) + " in the document.");
7761
+ for (var chunk = doc; !chunk.lines;) {
7762
+ for (var i = 0;; ++i) {
7763
+ var child = chunk.children[i], sz = child.chunkSize();
7764
+ if (n < sz) { chunk = child; break; }
7765
+ n -= sz;
7766
+ }
7767
+ }
7768
+ return chunk.lines[n];
7769
+ }
7770
+
7771
+ // Get the part of a document between two positions, as an array of
7772
+ // strings.
7773
+ function getBetween(doc, start, end) {
7774
+ var out = [], n = start.line;
7775
+ doc.iter(start.line, end.line + 1, function(line) {
7776
+ var text = line.text;
7777
+ if (n == end.line) text = text.slice(0, end.ch);
7778
+ if (n == start.line) text = text.slice(start.ch);
7779
+ out.push(text);
7780
+ ++n;
7781
+ });
7782
+ return out;
7783
+ }
7784
+ // Get the lines between from and to, as array of strings.
7785
+ function getLines(doc, from, to) {
7786
+ var out = [];
7787
+ doc.iter(from, to, function(line) { out.push(line.text); });
7788
+ return out;
7789
+ }
7790
+
7791
+ // Update the height of a line, propagating the height change
7792
+ // upwards to parent nodes.
7793
+ function updateLineHeight(line, height) {
7794
+ var diff = height - line.height;
7795
+ if (diff) for (var n = line; n; n = n.parent) n.height += diff;
7796
+ }
7797
+
7798
+ // Given a line object, find its line number by walking up through
7799
+ // its parent links.
7800
+ function lineNo(line) {
7801
+ if (line.parent == null) return null;
7802
+ var cur = line.parent, no = indexOf(cur.lines, line);
7803
+ for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
7804
+ for (var i = 0;; ++i) {
7805
+ if (chunk.children[i] == cur) break;
7806
+ no += chunk.children[i].chunkSize();
7807
+ }
7808
+ }
7809
+ return no + cur.first;
7810
+ }
7811
+
7812
+ // Find the line at the given vertical position, using the height
7813
+ // information in the document tree.
7814
+ function lineAtHeight(chunk, h) {
7815
+ var n = chunk.first;
7816
+ outer: do {
7817
+ for (var i = 0; i < chunk.children.length; ++i) {
7818
+ var child = chunk.children[i], ch = child.height;
7819
+ if (h < ch) { chunk = child; continue outer; }
7820
+ h -= ch;
7821
+ n += child.chunkSize();
7822
+ }
7823
+ return n;
7824
+ } while (!chunk.lines);
7825
+ for (var i = 0; i < chunk.lines.length; ++i) {
7826
+ var line = chunk.lines[i], lh = line.height;
7827
+ if (h < lh) break;
7828
+ h -= lh;
7829
+ }
7830
+ return n + i;
7831
+ }
7832
+
7833
+
7834
+ // Find the height above the given line.
7835
+ function heightAtLine(lineObj) {
7836
+ lineObj = visualLine(lineObj);
7837
+
7838
+ var h = 0, chunk = lineObj.parent;
7839
+ for (var i = 0; i < chunk.lines.length; ++i) {
7840
+ var line = chunk.lines[i];
7841
+ if (line == lineObj) break;
7842
+ else h += line.height;
7843
+ }
7844
+ for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {
7845
+ for (var i = 0; i < p.children.length; ++i) {
7846
+ var cur = p.children[i];
7847
+ if (cur == chunk) break;
7848
+ else h += cur.height;
7849
+ }
7850
+ }
7851
+ return h;
7852
+ }
7853
+
7854
+ // Get the bidi ordering for the given line (and cache it). Returns
7855
+ // false for lines that are fully left-to-right, and an array of
7856
+ // BidiSpan objects otherwise.
7857
+ function getOrder(line) {
7858
+ var order = line.order;
7859
+ if (order == null) order = line.order = bidiOrdering(line.text);
7860
+ return order;
7861
+ }
7862
+
7863
+ // HISTORY
7864
+
7865
+ function History(startGen) {
7866
+ // Arrays of change events and selections. Doing something adds an
7867
+ // event to done and clears undo. Undoing moves events from done
7868
+ // to undone, redoing moves them in the other direction.
7869
+ this.done = []; this.undone = [];
7870
+ this.undoDepth = Infinity;
7871
+ // Used to track when changes can be merged into a single undo
7872
+ // event
7873
+ this.lastModTime = this.lastSelTime = 0;
7874
+ this.lastOp = this.lastSelOp = null;
7875
+ this.lastOrigin = this.lastSelOrigin = null;
7876
+ // Used by the isClean() method
7877
+ this.generation = this.maxGeneration = startGen || 1;
7878
+ }
7879
+
7880
+ // Create a history change event from an updateDoc-style change
7881
+ // object.
7882
+ function historyChangeFromChange(doc, change) {
7883
+ var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
7884
+ attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
7885
+ linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true);
7886
+ return histChange;
7887
+ }
7888
+
7889
+ // Pop all selection events off the end of a history array. Stop at
7890
+ // a change event.
7891
+ function clearSelectionEvents(array) {
7892
+ while (array.length) {
7893
+ var last = lst(array);
7894
+ if (last.ranges) array.pop();
7895
+ else break;
7896
+ }
7897
+ }
7898
+
7899
+ // Find the top change event in the history. Pop off selection
7900
+ // events that are in the way.
7901
+ function lastChangeEvent(hist, force) {
7902
+ if (force) {
7903
+ clearSelectionEvents(hist.done);
7904
+ return lst(hist.done);
7905
+ } else if (hist.done.length && !lst(hist.done).ranges) {
7906
+ return lst(hist.done);
7907
+ } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) {
7908
+ hist.done.pop();
7909
+ return lst(hist.done);
7910
+ }
7911
+ }
7912
+
7913
+ // Register a change in the history. Merges changes that are within
7914
+ // a single operation, ore are close together with an origin that
7915
+ // allows merging (starting with "+") into a single event.
7916
+ function addChangeToHistory(doc, change, selAfter, opId) {
7917
+ var hist = doc.history;
7918
+ hist.undone.length = 0;
7919
+ var time = +new Date, cur;
7920
+
7921
+ if ((hist.lastOp == opId ||
7922
+ hist.lastOrigin == change.origin && change.origin &&
7923
+ ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) ||
7924
+ change.origin.charAt(0) == "*")) &&
7925
+ (cur = lastChangeEvent(hist, hist.lastOp == opId))) {
7926
+ // Merge this change into the last event
7927
+ var last = lst(cur.changes);
7928
+ if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) {
7929
+ // Optimized case for simple insertion -- don't want to add
7930
+ // new changesets for every character typed
7931
+ last.to = changeEnd(change);
7932
+ } else {
7933
+ // Add new sub-event
7934
+ cur.changes.push(historyChangeFromChange(doc, change));
7935
+ }
7936
+ } else {
7937
+ // Can not be merged, start a new event.
7938
+ var before = lst(hist.done);
7939
+ if (!before || !before.ranges)
7940
+ pushSelectionToHistory(doc.sel, hist.done);
7941
+ cur = {changes: [historyChangeFromChange(doc, change)],
7942
+ generation: hist.generation};
7943
+ hist.done.push(cur);
7944
+ while (hist.done.length > hist.undoDepth) {
7945
+ hist.done.shift();
7946
+ if (!hist.done[0].ranges) hist.done.shift();
7947
+ }
7948
+ }
7949
+ hist.done.push(selAfter);
7950
+ hist.generation = ++hist.maxGeneration;
7951
+ hist.lastModTime = hist.lastSelTime = time;
7952
+ hist.lastOp = hist.lastSelOp = opId;
7953
+ hist.lastOrigin = hist.lastSelOrigin = change.origin;
7954
+
7955
+ if (!last) signal(doc, "historyAdded");
7956
+ }
7957
+
7958
+ function selectionEventCanBeMerged(doc, origin, prev, sel) {
7959
+ var ch = origin.charAt(0);
7960
+ return ch == "*" ||
7961
+ ch == "+" &&
7962
+ prev.ranges.length == sel.ranges.length &&
7963
+ prev.somethingSelected() == sel.somethingSelected() &&
7964
+ new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500);
7965
+ }
7966
+
7967
+ // Called whenever the selection changes, sets the new selection as
7968
+ // the pending selection in the history, and pushes the old pending
7969
+ // selection into the 'done' array when it was significantly
7970
+ // different (in number of selected ranges, emptiness, or time).
7971
+ function addSelectionToHistory(doc, sel, opId, options) {
7972
+ var hist = doc.history, origin = options && options.origin;
7973
+
7974
+ // A new event is started when the previous origin does not match
7975
+ // the current, or the origins don't allow matching. Origins
7976
+ // starting with * are always merged, those starting with + are
7977
+ // merged when similar and close together in time.
7978
+ if (opId == hist.lastSelOp ||
7979
+ (origin && hist.lastSelOrigin == origin &&
7980
+ (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin ||
7981
+ selectionEventCanBeMerged(doc, origin, lst(hist.done), sel))))
7982
+ hist.done[hist.done.length - 1] = sel;
7983
+ else
7984
+ pushSelectionToHistory(sel, hist.done);
7985
+
7986
+ hist.lastSelTime = +new Date;
7987
+ hist.lastSelOrigin = origin;
7988
+ hist.lastSelOp = opId;
7989
+ if (options && options.clearRedo !== false)
7990
+ clearSelectionEvents(hist.undone);
7991
+ }
7992
+
7993
+ function pushSelectionToHistory(sel, dest) {
7994
+ var top = lst(dest);
7995
+ if (!(top && top.ranges && top.equals(sel)))
7996
+ dest.push(sel);
7997
+ }
7998
+
7999
+ // Used to store marked span information in the history.
8000
+ function attachLocalSpans(doc, change, from, to) {
8001
+ var existing = change["spans_" + doc.id], n = 0;
8002
+ doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) {
8003
+ if (line.markedSpans)
8004
+ (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans;
8005
+ ++n;
8006
+ });
8007
+ }
8008
+
8009
+ // When un/re-doing restores text containing marked spans, those
8010
+ // that have been explicitly cleared should not be restored.
8011
+ function removeClearedSpans(spans) {
8012
+ if (!spans) return null;
8013
+ for (var i = 0, out; i < spans.length; ++i) {
8014
+ if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); }
8015
+ else if (out) out.push(spans[i]);
8016
+ }
8017
+ return !out ? spans : out.length ? out : null;
8018
+ }
8019
+
8020
+ // Retrieve and filter the old marked spans stored in a change event.
8021
+ function getOldSpans(doc, change) {
8022
+ var found = change["spans_" + doc.id];
8023
+ if (!found) return null;
8024
+ for (var i = 0, nw = []; i < change.text.length; ++i)
8025
+ nw.push(removeClearedSpans(found[i]));
8026
+ return nw;
8027
+ }
8028
+
8029
+ // Used both to provide a JSON-safe object in .getHistory, and, when
8030
+ // detaching a document, to split the history in two
8031
+ function copyHistoryArray(events, newGroup, instantiateSel) {
8032
+ for (var i = 0, copy = []; i < events.length; ++i) {
8033
+ var event = events[i];
8034
+ if (event.ranges) {
8035
+ copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event);
8036
+ continue;
8037
+ }
8038
+ var changes = event.changes, newChanges = [];
8039
+ copy.push({changes: newChanges});
8040
+ for (var j = 0; j < changes.length; ++j) {
8041
+ var change = changes[j], m;
8042
+ newChanges.push({from: change.from, to: change.to, text: change.text});
8043
+ if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) {
8044
+ if (indexOf(newGroup, Number(m[1])) > -1) {
8045
+ lst(newChanges)[prop] = change[prop];
8046
+ delete change[prop];
8047
+ }
8048
+ }
8049
+ }
8050
+ }
8051
+ return copy;
8052
+ }
8053
+
8054
+ // Rebasing/resetting history to deal with externally-sourced changes
8055
+
8056
+ function rebaseHistSelSingle(pos, from, to, diff) {
8057
+ if (to < pos.line) {
8058
+ pos.line += diff;
8059
+ } else if (from < pos.line) {
8060
+ pos.line = from;
8061
+ pos.ch = 0;
8062
+ }
8063
+ }
8064
+
8065
+ // Tries to rebase an array of history events given a change in the
8066
+ // document. If the change touches the same lines as the event, the
8067
+ // event, and everything 'behind' it, is discarded. If the change is
8068
+ // before the event, the event's positions are updated. Uses a
8069
+ // copy-on-write scheme for the positions, to avoid having to
8070
+ // reallocate them all on every rebase, but also avoid problems with
8071
+ // shared position objects being unsafely updated.
8072
+ function rebaseHistArray(array, from, to, diff) {
8073
+ for (var i = 0; i < array.length; ++i) {
8074
+ var sub = array[i], ok = true;
8075
+ if (sub.ranges) {
8076
+ if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; }
8077
+ for (var j = 0; j < sub.ranges.length; j++) {
8078
+ rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff);
8079
+ rebaseHistSelSingle(sub.ranges[j].head, from, to, diff);
8080
+ }
8081
+ continue;
8082
+ }
8083
+ for (var j = 0; j < sub.changes.length; ++j) {
8084
+ var cur = sub.changes[j];
8085
+ if (to < cur.from.line) {
8086
+ cur.from = Pos(cur.from.line + diff, cur.from.ch);
8087
+ cur.to = Pos(cur.to.line + diff, cur.to.ch);
8088
+ } else if (from <= cur.to.line) {
8089
+ ok = false;
8090
+ break;
8091
+ }
8092
+ }
8093
+ if (!ok) {
8094
+ array.splice(0, i + 1);
8095
+ i = 0;
8096
+ }
8097
+ }
8098
+ }
8099
+
8100
+ function rebaseHist(hist, change) {
8101
+ var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1;
8102
+ rebaseHistArray(hist.done, from, to, diff);
8103
+ rebaseHistArray(hist.undone, from, to, diff);
8104
+ }
8105
+
8106
+ // EVENT UTILITIES
8107
+
8108
+ // Due to the fact that we still support jurassic IE versions, some
8109
+ // compatibility wrappers are needed.
8110
+
8111
+ var e_preventDefault = CodeMirror.e_preventDefault = function(e) {
8112
+ if (e.preventDefault) e.preventDefault();
8113
+ else e.returnValue = false;
8114
+ };
8115
+ var e_stopPropagation = CodeMirror.e_stopPropagation = function(e) {
8116
+ if (e.stopPropagation) e.stopPropagation();
8117
+ else e.cancelBubble = true;
8118
+ };
8119
+ function e_defaultPrevented(e) {
8120
+ return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false;
8121
+ }
8122
+ var e_stop = CodeMirror.e_stop = function(e) {e_preventDefault(e); e_stopPropagation(e);};
8123
+
8124
+ function e_target(e) {return e.target || e.srcElement;}
8125
+ function e_button(e) {
8126
+ var b = e.which;
8127
+ if (b == null) {
8128
+ if (e.button & 1) b = 1;
8129
+ else if (e.button & 2) b = 3;
8130
+ else if (e.button & 4) b = 2;
8131
+ }
8132
+ if (mac && e.ctrlKey && b == 1) b = 3;
8133
+ return b;
8134
+ }
8135
+
8136
+ // EVENT HANDLING
8137
+
8138
+ // Lightweight event framework. on/off also work on DOM nodes,
8139
+ // registering native DOM handlers.
8140
+
8141
+ var on = CodeMirror.on = function(emitter, type, f) {
8142
+ if (emitter.addEventListener)
8143
+ emitter.addEventListener(type, f, false);
8144
+ else if (emitter.attachEvent)
8145
+ emitter.attachEvent("on" + type, f);
8146
+ else {
8147
+ var map = emitter._handlers || (emitter._handlers = {});
8148
+ var arr = map[type] || (map[type] = []);
8149
+ arr.push(f);
8150
+ }
8151
+ };
8152
+
8153
+ var noHandlers = []
8154
+ function getHandlers(emitter, type, copy) {
8155
+ var arr = emitter._handlers && emitter._handlers[type]
8156
+ if (copy) return arr && arr.length > 0 ? arr.slice() : noHandlers
8157
+ else return arr || noHandlers
8158
+ }
8159
+
8160
+ var off = CodeMirror.off = function(emitter, type, f) {
8161
+ if (emitter.removeEventListener)
8162
+ emitter.removeEventListener(type, f, false);
8163
+ else if (emitter.detachEvent)
8164
+ emitter.detachEvent("on" + type, f);
8165
+ else {
8166
+ var handlers = getHandlers(emitter, type, false)
8167
+ for (var i = 0; i < handlers.length; ++i)
8168
+ if (handlers[i] == f) { handlers.splice(i, 1); break; }
8169
+ }
8170
+ };
8171
+
8172
+ var signal = CodeMirror.signal = function(emitter, type /*, values...*/) {
8173
+ var handlers = getHandlers(emitter, type, true)
8174
+ if (!handlers.length) return;
8175
+ var args = Array.prototype.slice.call(arguments, 2);
8176
+ for (var i = 0; i < handlers.length; ++i) handlers[i].apply(null, args);
8177
+ };
8178
+
8179
+ var orphanDelayedCallbacks = null;
8180
+
8181
+ // Often, we want to signal events at a point where we are in the
8182
+ // middle of some work, but don't want the handler to start calling
8183
+ // other methods on the editor, which might be in an inconsistent
8184
+ // state or simply not expect any other events to happen.
8185
+ // signalLater looks whether there are any handlers, and schedules
8186
+ // them to be executed when the last operation ends, or, if no
8187
+ // operation is active, when a timeout fires.
8188
+ function signalLater(emitter, type /*, values...*/) {
8189
+ var arr = getHandlers(emitter, type, false)
8190
+ if (!arr.length) return;
8191
+ var args = Array.prototype.slice.call(arguments, 2), list;
8192
+ if (operationGroup) {
8193
+ list = operationGroup.delayedCallbacks;
8194
+ } else if (orphanDelayedCallbacks) {
8195
+ list = orphanDelayedCallbacks;
8196
+ } else {
8197
+ list = orphanDelayedCallbacks = [];
8198
+ setTimeout(fireOrphanDelayed, 0);
8199
+ }
8200
+ function bnd(f) {return function(){f.apply(null, args);};};
8201
+ for (var i = 0; i < arr.length; ++i)
8202
+ list.push(bnd(arr[i]));
8203
+ }
8204
+
8205
+ function fireOrphanDelayed() {
8206
+ var delayed = orphanDelayedCallbacks;
8207
+ orphanDelayedCallbacks = null;
8208
+ for (var i = 0; i < delayed.length; ++i) delayed[i]();
8209
+ }
8210
+
8211
+ // The DOM events that CodeMirror handles can be overridden by
8212
+ // registering a (non-DOM) handler on the editor for the event name,
8213
+ // and preventDefault-ing the event in that handler.
8214
+ function signalDOMEvent(cm, e, override) {
8215
+ if (typeof e == "string")
8216
+ e = {type: e, preventDefault: function() { this.defaultPrevented = true; }};
8217
+ signal(cm, override || e.type, cm, e);
8218
+ return e_defaultPrevented(e) || e.codemirrorIgnore;
8219
+ }
8220
+
8221
+ function signalCursorActivity(cm) {
8222
+ var arr = cm._handlers && cm._handlers.cursorActivity;
8223
+ if (!arr) return;
8224
+ var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []);
8225
+ for (var i = 0; i < arr.length; ++i) if (indexOf(set, arr[i]) == -1)
8226
+ set.push(arr[i]);
8227
+ }
8228
+
8229
+ function hasHandler(emitter, type) {
8230
+ return getHandlers(emitter, type).length > 0
8231
+ }
8232
+
8233
+ // Add on and off methods to a constructor's prototype, to make
8234
+ // registering events on such objects more convenient.
8235
+ function eventMixin(ctor) {
8236
+ ctor.prototype.on = function(type, f) {on(this, type, f);};
8237
+ ctor.prototype.off = function(type, f) {off(this, type, f);};
8238
+ }
8239
+
8240
+ // MISC UTILITIES
8241
+
8242
+ // Number of pixels added to scroller and sizer to hide scrollbar
8243
+ var scrollerGap = 30;
8244
+
8245
+ // Returned or thrown by various protocols to signal 'I'm not
8246
+ // handling this'.
8247
+ var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};
8248
+
8249
+ // Reused option objects for setSelection & friends
8250
+ var sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"};
8251
+
8252
+ function Delayed() {this.id = null;}
8253
+ Delayed.prototype.set = function(ms, f) {
8254
+ clearTimeout(this.id);
8255
+ this.id = setTimeout(f, ms);
8256
+ };
8257
+
8258
+ // Counts the column offset in a string, taking tabs into account.
8259
+ // Used mostly to find indentation.
8260
+ var countColumn = CodeMirror.countColumn = function(string, end, tabSize, startIndex, startValue) {
8261
+ if (end == null) {
8262
+ end = string.search(/[^\s\u00a0]/);
8263
+ if (end == -1) end = string.length;
8264
+ }
8265
+ for (var i = startIndex || 0, n = startValue || 0;;) {
8266
+ var nextTab = string.indexOf("\t", i);
8267
+ if (nextTab < 0 || nextTab >= end)
8268
+ return n + (end - i);
8269
+ n += nextTab - i;
8270
+ n += tabSize - (n % tabSize);
8271
+ i = nextTab + 1;
8272
+ }
8273
+ };
8274
+
8275
+ // The inverse of countColumn -- find the offset that corresponds to
8276
+ // a particular column.
8277
+ var findColumn = CodeMirror.findColumn = function(string, goal, tabSize) {
8278
+ for (var pos = 0, col = 0;;) {
8279
+ var nextTab = string.indexOf("\t", pos);
8280
+ if (nextTab == -1) nextTab = string.length;
8281
+ var skipped = nextTab - pos;
8282
+ if (nextTab == string.length || col + skipped >= goal)
8283
+ return pos + Math.min(skipped, goal - col);
8284
+ col += nextTab - pos;
8285
+ col += tabSize - (col % tabSize);
8286
+ pos = nextTab + 1;
8287
+ if (col >= goal) return pos;
8288
+ }
8289
+ }
8290
+
8291
+ var spaceStrs = [""];
8292
+ function spaceStr(n) {
8293
+ while (spaceStrs.length <= n)
8294
+ spaceStrs.push(lst(spaceStrs) + " ");
8295
+ return spaceStrs[n];
8296
+ }
8297
+
8298
+ function lst(arr) { return arr[arr.length-1]; }
8299
+
8300
+ var selectInput = function(node) { node.select(); };
8301
+ if (ios) // Mobile Safari apparently has a bug where select() is broken.
8302
+ selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; };
8303
+ else if (ie) // Suppress mysterious IE10 errors
8304
+ selectInput = function(node) { try { node.select(); } catch(_e) {} };
8305
+
8306
+ function indexOf(array, elt) {
8307
+ for (var i = 0; i < array.length; ++i)
8308
+ if (array[i] == elt) return i;
8309
+ return -1;
8310
+ }
8311
+ function map(array, f) {
8312
+ var out = [];
8313
+ for (var i = 0; i < array.length; i++) out[i] = f(array[i], i);
8314
+ return out;
8315
+ }
8316
+
8317
+ function nothing() {}
8318
+
8319
+ function createObj(base, props) {
8320
+ var inst;
8321
+ if (Object.create) {
8322
+ inst = Object.create(base);
8323
+ } else {
8324
+ nothing.prototype = base;
8325
+ inst = new nothing();
8326
+ }
8327
+ if (props) copyObj(props, inst);
8328
+ return inst;
8329
+ };
8330
+
8331
+ function copyObj(obj, target, overwrite) {
8332
+ if (!target) target = {};
8333
+ for (var prop in obj)
8334
+ if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
8335
+ target[prop] = obj[prop];
8336
+ return target;
8337
+ }
8338
+
8339
+ function bind(f) {
8340
+ var args = Array.prototype.slice.call(arguments, 1);
8341
+ return function(){return f.apply(null, args);};
8342
+ }
8343
+
8344
+ var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
8345
+ var isWordCharBasic = CodeMirror.isWordChar = function(ch) {
8346
+ return /\w/.test(ch) || ch > "\x80" &&
8347
+ (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));
8348
+ };
8349
+ function isWordChar(ch, helper) {
8350
+ if (!helper) return isWordCharBasic(ch);
8351
+ if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) return true;
8352
+ return helper.test(ch);
8353
+ }
8354
+
8355
+ function isEmpty(obj) {
8356
+ for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false;
8357
+ return true;
8358
+ }
8359
+
8360
+ // Extending unicode characters. A series of a non-extending char +
8361
+ // any number of extending chars is treated as a single unit as far
8362
+ // as editing and measuring is concerned. This is not fully correct,
8363
+ // since some scripts/fonts/browsers also treat other configurations
8364
+ // of code points as a group.
8365
+ 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]/;
8366
+ function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch); }
8367
+
8368
+ // DOM UTILITIES
8369
+
8370
+ function elt(tag, content, className, style) {
8371
+ var e = document.createElement(tag);
8372
+ if (className) e.className = className;
8373
+ if (style) e.style.cssText = style;
8374
+ if (typeof content == "string") e.appendChild(document.createTextNode(content));
8375
+ else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
8376
+ return e;
8377
+ }
8378
+
8379
+ var range;
8380
+ if (document.createRange) range = function(node, start, end, endNode) {
8381
+ var r = document.createRange();
8382
+ r.setEnd(endNode || node, end);
8383
+ r.setStart(node, start);
8384
+ return r;
8385
+ };
8386
+ else range = function(node, start, end) {
8387
+ var r = document.body.createTextRange();
8388
+ try { r.moveToElementText(node.parentNode); }
8389
+ catch(e) { return r; }
8390
+ r.collapse(true);
8391
+ r.moveEnd("character", end);
8392
+ r.moveStart("character", start);
8393
+ return r;
8394
+ };
8395
+
8396
+ function removeChildren(e) {
8397
+ for (var count = e.childNodes.length; count > 0; --count)
8398
+ e.removeChild(e.firstChild);
8399
+ return e;
8400
+ }
8401
+
8402
+ function removeChildrenAndAdd(parent, e) {
8403
+ return removeChildren(parent).appendChild(e);
8404
+ }
8405
+
8406
+ var contains = CodeMirror.contains = function(parent, child) {
8407
+ if (child.nodeType == 3) // Android browser always returns false when child is a textnode
8408
+ child = child.parentNode;
8409
+ if (parent.contains)
8410
+ return parent.contains(child);
8411
+ do {
8412
+ if (child.nodeType == 11) child = child.host;
8413
+ if (child == parent) return true;
8414
+ } while (child = child.parentNode);
8415
+ };
8416
+
8417
+ function activeElt() {
8418
+ var activeElement = document.activeElement;
8419
+ while (activeElement && activeElement.root && activeElement.root.activeElement)
8420
+ activeElement = activeElement.root.activeElement;
8421
+ return activeElement;
8422
+ }
8423
+ // Older versions of IE throws unspecified error when touching
8424
+ // document.activeElement in some cases (during loading, in iframe)
8425
+ if (ie && ie_version < 11) activeElt = function() {
8426
+ try { return document.activeElement; }
8427
+ catch(e) { return document.body; }
8428
+ };
8429
+
8430
+ function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*"); }
8431
+ var rmClass = CodeMirror.rmClass = function(node, cls) {
8432
+ var current = node.className;
8433
+ var match = classTest(cls).exec(current);
8434
+ if (match) {
8435
+ var after = current.slice(match.index + match[0].length);
8436
+ node.className = current.slice(0, match.index) + (after ? match[1] + after : "");
8437
+ }
8438
+ };
8439
+ var addClass = CodeMirror.addClass = function(node, cls) {
8440
+ var current = node.className;
8441
+ if (!classTest(cls).test(current)) node.className += (current ? " " : "") + cls;
8442
+ };
8443
+ function joinClasses(a, b) {
8444
+ var as = a.split(" ");
8445
+ for (var i = 0; i < as.length; i++)
8446
+ if (as[i] && !classTest(as[i]).test(b)) b += " " + as[i];
8447
+ return b;
8448
+ }
8449
+
8450
+ // WINDOW-WIDE EVENTS
8451
+
8452
+ // These must be handled carefully, because naively registering a
8453
+ // handler for each editor will cause the editors to never be
8454
+ // garbage collected.
8455
+
8456
+ function forEachCodeMirror(f) {
8457
+ if (!document.body.getElementsByClassName) return;
8458
+ var byClass = document.body.getElementsByClassName("CodeMirror");
8459
+ for (var i = 0; i < byClass.length; i++) {
8460
+ var cm = byClass[i].CodeMirror;
8461
+ if (cm) f(cm);
8462
+ }
8463
+ }
8464
+
8465
+ var globalsRegistered = false;
8466
+ function ensureGlobalHandlers() {
8467
+ if (globalsRegistered) return;
8468
+ registerGlobalHandlers();
8469
+ globalsRegistered = true;
8470
+ }
8471
+ function registerGlobalHandlers() {
8472
+ // When the window resizes, we need to refresh active editors.
8473
+ var resizeTimer;
8474
+ on(window, "resize", function() {
8475
+ if (resizeTimer == null) resizeTimer = setTimeout(function() {
8476
+ resizeTimer = null;
8477
+ forEachCodeMirror(onResize);
8478
+ }, 100);
8479
+ });
8480
+ // When the window loses focus, we want to show the editor as blurred
8481
+ on(window, "blur", function() {
8482
+ forEachCodeMirror(onBlur);
8483
+ });
8484
+ }
8485
+
8486
+ // FEATURE DETECTION
8487
+
8488
+ // Detect drag-and-drop
8489
+ var dragAndDrop = function() {
8490
+ // There is *some* kind of drag-and-drop support in IE6-8, but I
8491
+ // couldn't get it to work yet.
8492
+ if (ie && ie_version < 9) return false;
8493
+ var div = elt('div');
8494
+ return "draggable" in div || "dragDrop" in div;
8495
+ }();
8496
+
8497
+ var zwspSupported;
8498
+ function zeroWidthElement(measure) {
8499
+ if (zwspSupported == null) {
8500
+ var test = elt("span", "\u200b");
8501
+ removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")]));
8502
+ if (measure.firstChild.offsetHeight != 0)
8503
+ zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8);
8504
+ }
8505
+ var node = zwspSupported ? elt("span", "\u200b") :
8506
+ elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
8507
+ node.setAttribute("cm-text", "");
8508
+ return node;
8509
+ }
8510
+
8511
+ // Feature-detect IE's crummy client rect reporting for bidi text
8512
+ var badBidiRects;
8513
+ function hasBadBidiRects(measure) {
8514
+ if (badBidiRects != null) return badBidiRects;
8515
+ var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA"));
8516
+ var r0 = range(txt, 0, 1).getBoundingClientRect();
8517
+ if (!r0 || r0.left == r0.right) return false; // Safari returns null in some cases (#2780)
8518
+ var r1 = range(txt, 1, 2).getBoundingClientRect();
8519
+ return badBidiRects = (r1.right - r0.right < 3);
8520
+ }
8521
+
8522
+ // See if "".split is the broken IE version, if so, provide an
8523
+ // alternative way to split lines.
8524
+ var splitLinesAuto = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
8525
+ var pos = 0, result = [], l = string.length;
8526
+ while (pos <= l) {
8527
+ var nl = string.indexOf("\n", pos);
8528
+ if (nl == -1) nl = string.length;
8529
+ var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl);
8530
+ var rt = line.indexOf("\r");
8531
+ if (rt != -1) {
8532
+ result.push(line.slice(0, rt));
8533
+ pos += rt + 1;
8534
+ } else {
8535
+ result.push(line);
8536
+ pos = nl + 1;
8537
+ }
8538
+ }
8539
+ return result;
8540
+ } : function(string){return string.split(/\r\n?|\n/);};
8541
+
8542
+ var hasSelection = window.getSelection ? function(te) {
8543
+ try { return te.selectionStart != te.selectionEnd; }
8544
+ catch(e) { return false; }
8545
+ } : function(te) {
8546
+ try {var range = te.ownerDocument.selection.createRange();}
8547
+ catch(e) {}
8548
+ if (!range || range.parentElement() != te) return false;
8549
+ return range.compareEndPoints("StartToEnd", range) != 0;
8550
+ };
8551
+
8552
+ var hasCopyEvent = (function() {
8553
+ var e = elt("div");
8554
+ if ("oncopy" in e) return true;
8555
+ e.setAttribute("oncopy", "return;");
8556
+ return typeof e.oncopy == "function";
8557
+ })();
8558
+
8559
+ var badZoomedRects = null;
8560
+ function hasBadZoomedRects(measure) {
8561
+ if (badZoomedRects != null) return badZoomedRects;
8562
+ var node = removeChildrenAndAdd(measure, elt("span", "x"));
8563
+ var normal = node.getBoundingClientRect();
8564
+ var fromRange = range(node, 0, 1).getBoundingClientRect();
8565
+ return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1;
8566
+ }
8567
+
8568
+ // KEY NAMES
8569
+
8570
+ var keyNames = CodeMirror.keyNames = {
8571
+ 3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
8572
+ 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
8573
+ 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
8574
+ 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod",
8575
+ 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete",
8576
+ 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
8577
+ 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
8578
+ 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"
8579
+ };
8580
+ (function() {
8581
+ // Number keys
8582
+ for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i);
8583
+ // Alphabetic keys
8584
+ for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
8585
+ // Function keys
8586
+ for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
8587
+ })();
8588
+
8589
+ // BIDI HELPERS
8590
+
8591
+ function iterateBidiSections(order, from, to, f) {
8592
+ if (!order) return f(from, to, "ltr");
8593
+ var found = false;
8594
+ for (var i = 0; i < order.length; ++i) {
8595
+ var part = order[i];
8596
+ if (part.from < to && part.to > from || from == to && part.to == from) {
8597
+ f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr");
8598
+ found = true;
8599
+ }
8600
+ }
8601
+ if (!found) f(from, to, "ltr");
8602
+ }
8603
+
8604
+ function bidiLeft(part) { return part.level % 2 ? part.to : part.from; }
8605
+ function bidiRight(part) { return part.level % 2 ? part.from : part.to; }
8606
+
8607
+ function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; }
8608
+ function lineRight(line) {
8609
+ var order = getOrder(line);
8610
+ if (!order) return line.text.length;
8611
+ return bidiRight(lst(order));
8612
+ }
8613
+
8614
+ function lineStart(cm, lineN) {
8615
+ var line = getLine(cm.doc, lineN);
8616
+ var visual = visualLine(line);
8617
+ if (visual != line) lineN = lineNo(visual);
8618
+ var order = getOrder(visual);
8619
+ var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual);
8620
+ return Pos(lineN, ch);
8621
+ }
8622
+ function lineEnd(cm, lineN) {
8623
+ var merged, line = getLine(cm.doc, lineN);
8624
+ while (merged = collapsedSpanAtEnd(line)) {
8625
+ line = merged.find(1, true).line;
8626
+ lineN = null;
8627
+ }
8628
+ var order = getOrder(line);
8629
+ var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line);
8630
+ return Pos(lineN == null ? lineNo(line) : lineN, ch);
8631
+ }
8632
+ function lineStartSmart(cm, pos) {
8633
+ var start = lineStart(cm, pos.line);
8634
+ var line = getLine(cm.doc, start.line);
8635
+ var order = getOrder(line);
8636
+ if (!order || order[0].level == 0) {
8637
+ var firstNonWS = Math.max(0, line.text.search(/\S/));
8638
+ var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch;
8639
+ return Pos(start.line, inWS ? 0 : firstNonWS);
8640
+ }
8641
+ return start;
8642
+ }
8643
+
8644
+ function compareBidiLevel(order, a, b) {
8645
+ var linedir = order[0].level;
8646
+ if (a == linedir) return true;
8647
+ if (b == linedir) return false;
8648
+ return a < b;
8649
+ }
8650
+ var bidiOther;
8651
+ function getBidiPartAt(order, pos) {
8652
+ bidiOther = null;
8653
+ for (var i = 0, found; i < order.length; ++i) {
8654
+ var cur = order[i];
8655
+ if (cur.from < pos && cur.to > pos) return i;
8656
+ if ((cur.from == pos || cur.to == pos)) {
8657
+ if (found == null) {
8658
+ found = i;
8659
+ } else if (compareBidiLevel(order, cur.level, order[found].level)) {
8660
+ if (cur.from != cur.to) bidiOther = found;
8661
+ return i;
8662
+ } else {
8663
+ if (cur.from != cur.to) bidiOther = i;
8664
+ return found;
8665
+ }
8666
+ }
8667
+ }
8668
+ return found;
8669
+ }
8670
+
8671
+ function moveInLine(line, pos, dir, byUnit) {
8672
+ if (!byUnit) return pos + dir;
8673
+ do pos += dir;
8674
+ while (pos > 0 && isExtendingChar(line.text.charAt(pos)));
8675
+ return pos;
8676
+ }
8677
+
8678
+ // This is needed in order to move 'visually' through bi-directional
8679
+ // text -- i.e., pressing left should make the cursor go left, even
8680
+ // when in RTL text. The tricky part is the 'jumps', where RTL and
8681
+ // LTR text touch each other. This often requires the cursor offset
8682
+ // to move more than one unit, in order to visually move one unit.
8683
+ function moveVisually(line, start, dir, byUnit) {
8684
+ var bidi = getOrder(line);
8685
+ if (!bidi) return moveLogically(line, start, dir, byUnit);
8686
+ var pos = getBidiPartAt(bidi, start), part = bidi[pos];
8687
+ var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit);
8688
+
8689
+ for (;;) {
8690
+ if (target > part.from && target < part.to) return target;
8691
+ if (target == part.from || target == part.to) {
8692
+ if (getBidiPartAt(bidi, target) == pos) return target;
8693
+ part = bidi[pos += dir];
8694
+ return (dir > 0) == part.level % 2 ? part.to : part.from;
8695
+ } else {
8696
+ part = bidi[pos += dir];
8697
+ if (!part) return null;
8698
+ if ((dir > 0) == part.level % 2)
8699
+ target = moveInLine(line, part.to, -1, byUnit);
8700
+ else
8701
+ target = moveInLine(line, part.from, 1, byUnit);
8702
+ }
8703
+ }
8704
+ }
8705
+
8706
+ function moveLogically(line, start, dir, byUnit) {
8707
+ var target = start + dir;
8708
+ if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir;
8709
+ return target < 0 || target > line.text.length ? null : target;
8710
+ }
8711
+
8712
+ // Bidirectional ordering algorithm
8713
+ // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm
8714
+ // that this (partially) implements.
8715
+
8716
+ // One-char codes used for character types:
8717
+ // L (L): Left-to-Right
8718
+ // R (R): Right-to-Left
8719
+ // r (AL): Right-to-Left Arabic
8720
+ // 1 (EN): European Number
8721
+ // + (ES): European Number Separator
8722
+ // % (ET): European Number Terminator
8723
+ // n (AN): Arabic Number
8724
+ // , (CS): Common Number Separator
8725
+ // m (NSM): Non-Spacing Mark
8726
+ // b (BN): Boundary Neutral
8727
+ // s (B): Paragraph Separator
8728
+ // t (S): Segment Separator
8729
+ // w (WS): Whitespace
8730
+ // N (ON): Other Neutrals
8731
+
8732
+ // Returns null if characters are ordered as they appear
8733
+ // (left-to-right), or an array of sections ({from, to, level}
8734
+ // objects) in the order in which they occur visually.
8735
+ var bidiOrdering = (function() {
8736
+ // Character types for codepoints 0 to 0xff
8737
+ var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN";
8738
+ // Character types for codepoints 0x600 to 0x6ff
8739
+ var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm";
8740
+ function charType(code) {
8741
+ if (code <= 0xf7) return lowTypes.charAt(code);
8742
+ else if (0x590 <= code && code <= 0x5f4) return "R";
8743
+ else if (0x600 <= code && code <= 0x6ed) return arabicTypes.charAt(code - 0x600);
8744
+ else if (0x6ee <= code && code <= 0x8ac) return "r";
8745
+ else if (0x2000 <= code && code <= 0x200b) return "w";
8746
+ else if (code == 0x200c) return "b";
8747
+ else return "L";
8748
+ }
8749
+
8750
+ var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
8751
+ var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;
8752
+ // Browsers seem to always treat the boundaries of block elements as being L.
8753
+ var outerType = "L";
8754
+
8755
+ function BidiSpan(level, from, to) {
8756
+ this.level = level;
8757
+ this.from = from; this.to = to;
8758
+ }
8759
+
8760
+ return function(str) {
8761
+ if (!bidiRE.test(str)) return false;
8762
+ var len = str.length, types = [];
8763
+ for (var i = 0, type; i < len; ++i)
8764
+ types.push(type = charType(str.charCodeAt(i)));
8765
+
8766
+ // W1. Examine each non-spacing mark (NSM) in the level run, and
8767
+ // change the type of the NSM to the type of the previous
8768
+ // character. If the NSM is at the start of the level run, it will
8769
+ // get the type of sor.
8770
+ for (var i = 0, prev = outerType; i < len; ++i) {
8771
+ var type = types[i];
8772
+ if (type == "m") types[i] = prev;
8773
+ else prev = type;
8774
+ }
8775
+
8776
+ // W2. Search backwards from each instance of a European number
8777
+ // until the first strong type (R, L, AL, or sor) is found. If an
8778
+ // AL is found, change the type of the European number to Arabic
8779
+ // number.
8780
+ // W3. Change all ALs to R.
8781
+ for (var i = 0, cur = outerType; i < len; ++i) {
8782
+ var type = types[i];
8783
+ if (type == "1" && cur == "r") types[i] = "n";
8784
+ else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; }
8785
+ }
8786
+
8787
+ // W4. A single European separator between two European numbers
8788
+ // changes to a European number. A single common separator between
8789
+ // two numbers of the same type changes to that type.
8790
+ for (var i = 1, prev = types[0]; i < len - 1; ++i) {
8791
+ var type = types[i];
8792
+ if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1";
8793
+ else if (type == "," && prev == types[i+1] &&
8794
+ (prev == "1" || prev == "n")) types[i] = prev;
8795
+ prev = type;
8796
+ }
8797
+
8798
+ // W5. A sequence of European terminators adjacent to European
8799
+ // numbers changes to all European numbers.
8800
+ // W6. Otherwise, separators and terminators change to Other
8801
+ // Neutral.
8802
+ for (var i = 0; i < len; ++i) {
8803
+ var type = types[i];
8804
+ if (type == ",") types[i] = "N";
8805
+ else if (type == "%") {
8806
+ for (var end = i + 1; end < len && types[end] == "%"; ++end) {}
8807
+ var replace = (i && types[i-1] == "!") || (end < len && types[end] == "1") ? "1" : "N";
8808
+ for (var j = i; j < end; ++j) types[j] = replace;
8809
+ i = end - 1;
8810
+ }
8811
+ }
8812
+
8813
+ // W7. Search backwards from each instance of a European number
8814
+ // until the first strong type (R, L, or sor) is found. If an L is
8815
+ // found, then change the type of the European number to L.
8816
+ for (var i = 0, cur = outerType; i < len; ++i) {
8817
+ var type = types[i];
8818
+ if (cur == "L" && type == "1") types[i] = "L";
8819
+ else if (isStrong.test(type)) cur = type;
8820
+ }
8821
+
8822
+ // N1. A sequence of neutrals takes the direction of the
8823
+ // surrounding strong text if the text on both sides has the same
8824
+ // direction. European and Arabic numbers act as if they were R in
8825
+ // terms of their influence on neutrals. Start-of-level-run (sor)
8826
+ // and end-of-level-run (eor) are used at level run boundaries.
8827
+ // N2. Any remaining neutrals take the embedding direction.
8828
+ for (var i = 0; i < len; ++i) {
8829
+ if (isNeutral.test(types[i])) {
8830
+ for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {}
8831
+ var before = (i ? types[i-1] : outerType) == "L";
8832
+ var after = (end < len ? types[end] : outerType) == "L";
8833
+ var replace = before || after ? "L" : "R";
8834
+ for (var j = i; j < end; ++j) types[j] = replace;
8835
+ i = end - 1;
8836
+ }
8837
+ }
8838
+
8839
+ // Here we depart from the documented algorithm, in order to avoid
8840
+ // building up an actual levels array. Since there are only three
8841
+ // levels (0, 1, 2) in an implementation that doesn't take
8842
+ // explicit embedding into account, we can build up the order on
8843
+ // the fly, without following the level-based algorithm.
8844
+ var order = [], m;
8845
+ for (var i = 0; i < len;) {
8846
+ if (countsAsLeft.test(types[i])) {
8847
+ var start = i;
8848
+ for (++i; i < len && countsAsLeft.test(types[i]); ++i) {}
8849
+ order.push(new BidiSpan(0, start, i));
8850
+ } else {
8851
+ var pos = i, at = order.length;
8852
+ for (++i; i < len && types[i] != "L"; ++i) {}
8853
+ for (var j = pos; j < i;) {
8854
+ if (countsAsNum.test(types[j])) {
8855
+ if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j));
8856
+ var nstart = j;
8857
+ for (++j; j < i && countsAsNum.test(types[j]); ++j) {}
8858
+ order.splice(at, 0, new BidiSpan(2, nstart, j));
8859
+ pos = j;
8860
+ } else ++j;
8861
+ }
8862
+ if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i));
8863
+ }
8864
+ }
8865
+ if (order[0].level == 1 && (m = str.match(/^\s+/))) {
8866
+ order[0].from = m[0].length;
8867
+ order.unshift(new BidiSpan(0, 0, m[0].length));
8868
+ }
8869
+ if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
8870
+ lst(order).to -= m[0].length;
8871
+ order.push(new BidiSpan(0, len - m[0].length, len));
8872
+ }
8873
+ if (order[0].level == 2)
8874
+ order.unshift(new BidiSpan(1, order[0].to, order[0].to));
8875
+ if (order[0].level != lst(order).level)
8876
+ order.push(new BidiSpan(order[0].level, len, len));
8877
+
8878
+ return order;
8879
+ };
8880
+ })();
8881
+
8882
+ // THE END
8883
+
8884
+ CodeMirror.version = "5.10.0";
8885
+
8886
+ return CodeMirror;
8887
+ });
vendor/kminh/bwp-framework/assets/vendor/codemirror/codemirror.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .CodeMirror{font-family:monospace;height:300px;color:#000}.CodeMirror-lines{padding:4px 0}.CodeMirror pre{padding:0 4px}.CodeMirror-gutter-filler,.CodeMirror-scrollbar-filler{background-color:#fff}.CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;white-space:nowrap}.CodeMirror-guttermarker{color:#000}.CodeMirror-guttermarker-subtle{color:#999}.CodeMirror-cursor{border-left:1px solid #000;border-right:none;width:0}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.cm-fat-cursor .CodeMirror-cursor{width:auto;border:0;background:#7e7}.cm-fat-cursor div.CodeMirror-cursors{z-index:1}.cm-animate-fat-cursor{width:auto;border:0;-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite;background-color:#7e7}@-moz-keyframes blink{50%{background-color:transparent}}@-webkit-keyframes blink{50%{background-color:transparent}}@keyframes blink{50%{background-color:transparent}}.cm-tab{display:inline-block;text-decoration:inherit}.CodeMirror-ruler{border-left:1px solid #ccc;position:absolute}.cm-s-default .cm-header{color:#00f}.cm-s-default .cm-quote{color:#090}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:700}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-strikethrough{text-decoration:line-through}.cm-s-default .cm-keyword{color:#708}.cm-s-default .cm-atom{color:#219}.cm-s-default .cm-number{color:#164}.cm-s-default .cm-def{color:#00f}.cm-s-default .cm-variable-2{color:#05a}.cm-s-default .cm-variable-3{color:#085}.cm-s-default .cm-comment{color:#a50}.cm-s-default .cm-string{color:#a11}.cm-s-default .cm-string-2{color:#f50}.cm-s-default .cm-meta,.cm-s-default .cm-qualifier{color:#555}.cm-s-default .cm-builtin{color:#30a}.cm-s-default .cm-bracket{color:#997}.cm-s-default .cm-tag{color:#170}.cm-s-default .cm-attribute{color:#00c}.cm-s-default .cm-hr{color:#999}.cm-s-default .cm-link{color:#00c}.cm-invalidchar,.cm-s-default .cm-error{color:red}.CodeMirror-composing{border-bottom:2px solid}div.CodeMirror span.CodeMirror-matchingbracket{color:#0f0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#f22}.CodeMirror-matchingtag{background:rgba(255,150,0,.3)}.CodeMirror-activeline-background{background:#e8f2ff}.CodeMirror{position:relative;overflow:hidden;background:#fff}.CodeMirror-scroll{overflow:scroll!important;margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:0;position:relative}.CodeMirror-sizer{position:relative;border-right:30px solid transparent}.CodeMirror-gutter-filler,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-vscrollbar{position:absolute;z-index:6;display:none}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom:0}.CodeMirror-gutters{position:absolute;left:0;top:0;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;display:inline-block;margin-bottom:-30px}.CodeMirror-gutter-wrapper{position:absolute;z-index:4;background:0 0!important;border:none!important;-webkit-user-select:none;-moz-user-select:none;user-select:none}.CodeMirror-gutter-background{position:absolute;top:0;bottom:0;z-index:4}.CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.CodeMirror-lines{cursor:text;min-height:1px}.CodeMirror pre{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;border-width:0;background:0 0;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible;-webkit-tap-highlight-color:transparent}.CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;overflow:auto}.CodeMirror-code{outline:0}.CodeMirror-gutter,.CodeMirror-gutters,.CodeMirror-linenumber,.CodeMirror-scroll,.CodeMirror-sizer{-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-cursor{position:absolute}.CodeMirror-measure pre{position:static}div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}.CodeMirror-focused div.CodeMirror-cursors,div.CodeMirror-dragcursors{visibility:visible}.CodeMirror-selected{background:#d9d9d9}.CodeMirror-focused .CodeMirror-selected,.CodeMirror-line::selection,.CodeMirror-line>span::selection,.CodeMirror-line>span>span::selection{background:#d7d4f0}.CodeMirror-crosshair{cursor:crosshair}.CodeMirror-line::-moz-selection,.CodeMirror-line>span::-moz-selection,.CodeMirror-line>span>span::-moz-selection{background:#d7d4f0}.cm-searching{background:#ffa;background:rgba(255,255,0,.4)}.cm-force-border{padding-right:.1px}@media print{.CodeMirror div.CodeMirror-cursors{visibility:hidden}}.cm-tab-wrap-hack:after{content:''}span.CodeMirror-selectedtext{background:0 0}.cm-s-neo.CodeMirror{background-color:#fff;color:#2e383c;line-height:1.4375}.cm-s-neo .cm-comment{color:#75787b}.cm-s-neo .cm-keyword,.cm-s-neo .cm-property{color:#1d75b3}.cm-s-neo .cm-atom,.cm-s-neo .cm-number{color:#75438a}.cm-s-neo .cm-node,.cm-s-neo .cm-tag{color:#9c3328}.cm-s-neo .cm-string{color:#b35e14}.cm-s-neo .cm-qualifier,.cm-s-neo .cm-variable{color:#047d65}.cm-s-neo pre{padding:0}.cm-s-neo .CodeMirror-gutters{border:none;border-right:10px solid transparent;background-color:transparent}.cm-s-neo .CodeMirror-linenumber{padding:0;color:#e0e2e5}.cm-s-neo .CodeMirror-guttermarker{color:#1d75b3}.cm-s-neo .CodeMirror-guttermarker-subtle{color:#e0e2e5}.cm-s-neo .CodeMirror-cursor{width:auto;border:0;background:rgba(155,157,162,.37);z-index:1}
vendor/kminh/bwp-framework/assets/vendor/codemirror/mode/css/css.js ADDED
@@ -0,0 +1,824 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ supportsAtComponent = parserConfig.supportsAtComponent === true;
32
+
33
+ var type, override;
34
+ function ret(style, tp) { type = tp; return style; }
35
+
36
+ // Tokenizers
37
+
38
+ function tokenBase(stream, state) {
39
+ var ch = stream.next();
40
+ if (tokenHooks[ch]) {
41
+ var result = tokenHooks[ch](stream, state);
42
+ if (result !== false) return result;
43
+ }
44
+ if (ch == "@") {
45
+ stream.eatWhile(/[\w\\\-]/);
46
+ return ret("def", stream.current());
47
+ } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
48
+ return ret(null, "compare");
49
+ } else if (ch == "\"" || ch == "'") {
50
+ state.tokenize = tokenString(ch);
51
+ return state.tokenize(stream, state);
52
+ } else if (ch == "#") {
53
+ stream.eatWhile(/[\w\\\-]/);
54
+ return ret("atom", "hash");
55
+ } else if (ch == "!") {
56
+ stream.match(/^\s*\w*/);
57
+ return ret("keyword", "important");
58
+ } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
59
+ stream.eatWhile(/[\w.%]/);
60
+ return ret("number", "unit");
61
+ } else if (ch === "-") {
62
+ if (/[\d.]/.test(stream.peek())) {
63
+ stream.eatWhile(/[\w.%]/);
64
+ return ret("number", "unit");
65
+ } else if (stream.match(/^-[\w\\\-]+/)) {
66
+ stream.eatWhile(/[\w\\\-]/);
67
+ if (stream.match(/^\s*:/, false))
68
+ return ret("variable-2", "variable-definition");
69
+ return ret("variable-2", "variable");
70
+ } else if (stream.match(/^\w+-/)) {
71
+ return ret("meta", "meta");
72
+ }
73
+ } else if (/[,+>*\/]/.test(ch)) {
74
+ return ret(null, "select-op");
75
+ } else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
76
+ return ret("qualifier", "qualifier");
77
+ } else if (/[:;{}\[\]\(\)]/.test(ch)) {
78
+ return ret(null, ch);
79
+ } else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) ||
80
+ (ch == "d" && stream.match("omain(")) ||
81
+ (ch == "r" && stream.match("egexp("))) {
82
+ stream.backUp(1);
83
+ state.tokenize = tokenParenthesized;
84
+ return ret("property", "word");
85
+ } else if (/[\w\\\-]/.test(ch)) {
86
+ stream.eatWhile(/[\w\\\-]/);
87
+ return ret("property", "word");
88
+ } else {
89
+ return ret(null, null);
90
+ }
91
+ }
92
+
93
+ function tokenString(quote) {
94
+ return function(stream, state) {
95
+ var escaped = false, ch;
96
+ while ((ch = stream.next()) != null) {
97
+ if (ch == quote && !escaped) {
98
+ if (quote == ")") stream.backUp(1);
99
+ break;
100
+ }
101
+ escaped = !escaped && ch == "\\";
102
+ }
103
+ if (ch == quote || !escaped && quote != ")") state.tokenize = null;
104
+ return ret("string", "string");
105
+ };
106
+ }
107
+
108
+ function tokenParenthesized(stream, state) {
109
+ stream.next(); // Must be '('
110
+ if (!stream.match(/\s*[\"\')]/, false))
111
+ state.tokenize = tokenString(")");
112
+ else
113
+ state.tokenize = null;
114
+ return ret(null, "(");
115
+ }
116
+
117
+ // Context management
118
+
119
+ function Context(type, indent, prev) {
120
+ this.type = type;
121
+ this.indent = indent;
122
+ this.prev = prev;
123
+ }
124
+
125
+ function pushContext(state, stream, type, indent) {
126
+ state.context = new Context(type, stream.indentation() + (indent === false ? 0 : indentUnit), state.context);
127
+ return type;
128
+ }
129
+
130
+ function popContext(state) {
131
+ if (state.context.prev)
132
+ state.context = state.context.prev;
133
+ return state.context.type;
134
+ }
135
+
136
+ function pass(type, stream, state) {
137
+ return states[state.context.type](type, stream, state);
138
+ }
139
+ function popAndPass(type, stream, state, n) {
140
+ for (var i = n || 1; i > 0; i--)
141
+ state.context = state.context.prev;
142
+ return pass(type, stream, state);
143
+ }
144
+
145
+ // Parser
146
+
147
+ function wordAsValue(stream) {
148
+ var word = stream.current().toLowerCase();
149
+ if (valueKeywords.hasOwnProperty(word))
150
+ override = "atom";
151
+ else if (colorKeywords.hasOwnProperty(word))
152
+ override = "keyword";
153
+ else
154
+ override = "variable";
155
+ }
156
+
157
+ var states = {};
158
+
159
+ states.top = function(type, stream, state) {
160
+ if (type == "{") {
161
+ return pushContext(state, stream, "block");
162
+ } else if (type == "}" && state.context.prev) {
163
+ return popContext(state);
164
+ } else if (supportsAtComponent && /@component/.test(type)) {
165
+ return pushContext(state, stream, "atComponentBlock");
166
+ } else if (/^@(-moz-)?document$/.test(type)) {
167
+ return pushContext(state, stream, "documentTypes");
168
+ } else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) {
169
+ return pushContext(state, stream, "atBlock");
170
+ } else if (/^@(font-face|counter-style)/.test(type)) {
171
+ state.stateArg = type;
172
+ return "restricted_atBlock_before";
173
+ } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
174
+ return "keyframes";
175
+ } else if (type && type.charAt(0) == "@") {
176
+ return pushContext(state, stream, "at");
177
+ } else if (type == "hash") {
178
+ override = "builtin";
179
+ } else if (type == "word") {
180
+ override = "tag";
181
+ } else if (type == "variable-definition") {
182
+ return "maybeprop";
183
+ } else if (type == "interpolation") {
184
+ return pushContext(state, stream, "interpolation");
185
+ } else if (type == ":") {
186
+ return "pseudo";
187
+ } else if (allowNested && type == "(") {
188
+ return pushContext(state, stream, "parens");
189
+ }
190
+ return state.context.type;
191
+ };
192
+
193
+ states.block = function(type, stream, state) {
194
+ if (type == "word") {
195
+ var word = stream.current().toLowerCase();
196
+ if (propertyKeywords.hasOwnProperty(word)) {
197
+ override = "property";
198
+ return "maybeprop";
199
+ } else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
200
+ override = "string-2";
201
+ return "maybeprop";
202
+ } else if (allowNested) {
203
+ override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag";
204
+ return "block";
205
+ } else {
206
+ override += " error";
207
+ return "maybeprop";
208
+ }
209
+ } else if (type == "meta") {
210
+ return "block";
211
+ } else if (!allowNested && (type == "hash" || type == "qualifier")) {
212
+ override = "error";
213
+ return "block";
214
+ } else {
215
+ return states.top(type, stream, state);
216
+ }
217
+ };
218
+
219
+ states.maybeprop = function(type, stream, state) {
220
+ if (type == ":") return pushContext(state, stream, "prop");
221
+ return pass(type, stream, state);
222
+ };
223
+
224
+ states.prop = function(type, stream, state) {
225
+ if (type == ";") return popContext(state);
226
+ if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
227
+ if (type == "}" || type == "{") return popAndPass(type, stream, state);
228
+ if (type == "(") return pushContext(state, stream, "parens");
229
+
230
+ if (type == "hash" && !/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())) {
231
+ override += " error";
232
+ } else if (type == "word") {
233
+ wordAsValue(stream);
234
+ } else if (type == "interpolation") {
235
+ return pushContext(state, stream, "interpolation");
236
+ }
237
+ return "prop";
238
+ };
239
+
240
+ states.propBlock = function(type, _stream, state) {
241
+ if (type == "}") return popContext(state);
242
+ if (type == "word") { override = "property"; return "maybeprop"; }
243
+ return state.context.type;
244
+ };
245
+
246
+ states.parens = function(type, stream, state) {
247
+ if (type == "{" || type == "}") return popAndPass(type, stream, state);
248
+ if (type == ")") return popContext(state);
249
+ if (type == "(") return pushContext(state, stream, "parens");
250
+ if (type == "interpolation") return pushContext(state, stream, "interpolation");
251
+ if (type == "word") wordAsValue(stream);
252
+ return "parens";
253
+ };
254
+
255
+ states.pseudo = function(type, stream, state) {
256
+ if (type == "word") {
257
+ override = "variable-3";
258
+ return state.context.type;
259
+ }
260
+ return pass(type, stream, state);
261
+ };
262
+
263
+ states.documentTypes = function(type, stream, state) {
264
+ if (type == "word" && documentTypes.hasOwnProperty(stream.current())) {
265
+ override = "tag";
266
+ return state.context.type;
267
+ } else {
268
+ return states.atBlock(type, stream, state);
269
+ }
270
+ };
271
+
272
+ states.atBlock = function(type, stream, state) {
273
+ if (type == "(") return pushContext(state, stream, "atBlock_parens");
274
+ if (type == "}" || type == ";") return popAndPass(type, stream, state);
275
+ if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
276
+
277
+ if (type == "interpolation") return pushContext(state, stream, "interpolation");
278
+
279
+ if (type == "word") {
280
+ var word = stream.current().toLowerCase();
281
+ if (word == "only" || word == "not" || word == "and" || word == "or")
282
+ override = "keyword";
283
+ else if (mediaTypes.hasOwnProperty(word))
284
+ override = "attribute";
285
+ else if (mediaFeatures.hasOwnProperty(word))
286
+ override = "property";
287
+ else if (mediaValueKeywords.hasOwnProperty(word))
288
+ override = "keyword";
289
+ else if (propertyKeywords.hasOwnProperty(word))
290
+ override = "property";
291
+ else if (nonStandardPropertyKeywords.hasOwnProperty(word))
292
+ override = "string-2";
293
+ else if (valueKeywords.hasOwnProperty(word))
294
+ override = "atom";
295
+ else if (colorKeywords.hasOwnProperty(word))
296
+ override = "keyword";
297
+ else
298
+ override = "error";
299
+ }
300
+ return state.context.type;
301
+ };
302
+
303
+ states.atComponentBlock = function(type, stream, state) {
304
+ if (type == "}")
305
+ return popAndPass(type, stream, state);
306
+ if (type == "{")
307
+ return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top", false);
308
+ if (type == "word")
309
+ override = "error";
310
+ return state.context.type;
311
+ };
312
+
313
+ states.atBlock_parens = function(type, stream, state) {
314
+ if (type == ")") return popContext(state);
315
+ if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
316
+ return states.atBlock(type, stream, state);
317
+ };
318
+
319
+ states.restricted_atBlock_before = function(type, stream, state) {
320
+ if (type == "{")
321
+ return pushContext(state, stream, "restricted_atBlock");
322
+ if (type == "word" && state.stateArg == "@counter-style") {
323
+ override = "variable";
324
+ return "restricted_atBlock_before";
325
+ }
326
+ return pass(type, stream, state);
327
+ };
328
+
329
+ states.restricted_atBlock = function(type, stream, state) {
330
+ if (type == "}") {
331
+ state.stateArg = null;
332
+ return popContext(state);
333
+ }
334
+ if (type == "word") {
335
+ if ((state.stateArg == "@font-face" && !fontProperties.hasOwnProperty(stream.current().toLowerCase())) ||
336
+ (state.stateArg == "@counter-style" && !counterDescriptors.hasOwnProperty(stream.current().toLowerCase())))
337
+ override = "error";
338
+ else
339
+ override = "property";
340
+ return "maybeprop";
341
+ }
342
+ return "restricted_atBlock";
343
+ };
344
+
345
+ states.keyframes = function(type, stream, state) {
346
+ if (type == "word") { override = "variable"; return "keyframes"; }
347
+ if (type == "{") return pushContext(state, stream, "top");
348
+ return pass(type, stream, state);
349
+ };
350
+
351
+ states.at = function(type, stream, state) {
352
+ if (type == ";") return popContext(state);
353
+ if (type == "{" || type == "}") return popAndPass(type, stream, state);
354
+ if (type == "word") override = "tag";
355
+ else if (type == "hash") override = "builtin";
356
+ return "at";
357
+ };
358
+
359
+ states.interpolation = function(type, stream, state) {
360
+ if (type == "}") return popContext(state);
361
+ if (type == "{" || type == ";") return popAndPass(type, stream, state);
362
+ if (type == "word") override = "variable";
363
+ else if (type != "variable" && type != "(" && type != ")") override = "error";
364
+ return "interpolation";
365
+ };
366
+
367
+ return {
368
+ startState: function(base) {
369
+ return {tokenize: null,
370
+ state: inline ? "block" : "top",
371
+ stateArg: null,
372
+ context: new Context(inline ? "block" : "top", base || 0, null)};
373
+ },
374
+
375
+ token: function(stream, state) {
376
+ if (!state.tokenize && stream.eatSpace()) return null;
377
+ var style = (state.tokenize || tokenBase)(stream, state);
378
+ if (style && typeof style == "object") {
379
+ type = style[1];
380
+ style = style[0];
381
+ }
382
+ override = style;
383
+ state.state = states[state.state](type, stream, state);
384
+ return override;
385
+ },
386
+
387
+ indent: function(state, textAfter) {
388
+ var cx = state.context, ch = textAfter && textAfter.charAt(0);
389
+ var indent = cx.indent;
390
+ if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
391
+ if (cx.prev) {
392
+ if (ch == "}" && (cx.type == "block" || cx.type == "top" ||
393
+ cx.type == "interpolation" || cx.type == "restricted_atBlock")) {
394
+ // Resume indentation from parent context.
395
+ cx = cx.prev;
396
+ indent = cx.indent;
397
+ } else if (ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
398
+ ch == "{" && (cx.type == "at" || cx.type == "atBlock")) {
399
+ // Dedent relative to current context.
400
+ indent = Math.max(0, cx.indent - indentUnit);
401
+ cx = cx.prev;
402
+ }
403
+ }
404
+ return indent;
405
+ },
406
+
407
+ electricChars: "}",
408
+ blockCommentStart: "/*",
409
+ blockCommentEnd: "*/",
410
+ fold: "brace"
411
+ };
412
+ });
413
+
414
+ function keySet(array) {
415
+ var keys = {};
416
+ for (var i = 0; i < array.length; ++i) {
417
+ keys[array[i]] = true;
418
+ }
419
+ return keys;
420
+ }
421
+
422
+ var documentTypes_ = [
423
+ "domain", "regexp", "url", "url-pr