/lenasys/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/lenasys/trunk

« back to all changes in this revision

Viewing changes to js/ace/ace.js

  • Committer: gustav.hartvigsson at gmail
  • Date: 2013-04-03 11:52:56 UTC
  • Revision ID: gustav.hartvigsson@gmail.com-20130403115256-sz6zermzoom4lifc
Ignored .DS_Store files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* ***** BEGIN LICENSE BLOCK *****
2
 
 * Distributed under the BSD license:
3
 
 *
4
 
 * Copyright (c) 2010, Ajax.org B.V.
5
 
 * All rights reserved.
6
 
 * 
7
 
 * Redistribution and use in source and binary forms, with or without
8
 
 * modification, are permitted provided that the following conditions are met:
9
 
 *     * Redistributions of source code must retain the above copyright
10
 
 *       notice, this list of conditions and the following disclaimer.
11
 
 *     * Redistributions in binary form must reproduce the above copyright
12
 
 *       notice, this list of conditions and the following disclaimer in the
13
 
 *       documentation and/or other materials provided with the distribution.
14
 
 *     * Neither the name of Ajax.org B.V. nor the
15
 
 *       names of its contributors may be used to endorse or promote products
16
 
 *       derived from this software without specific prior written permission.
17
 
 * 
18
 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
 
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
22
 
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
 
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
 
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
 
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 
 *
29
 
 * ***** END LICENSE BLOCK ***** */
30
 
 
31
 
(function() {
32
 
 
33
 
var ACE_NAMESPACE = "";
34
 
 
35
 
var global = (function() {
36
 
    return this;
37
 
})();
38
 
 
39
 
 
40
 
if (!ACE_NAMESPACE && typeof requirejs !== "undefined")
41
 
    return;
42
 
 
43
 
 
44
 
var _define = function(module, deps, payload) {
45
 
    if (typeof module !== 'string') {
46
 
        if (_define.original)
47
 
            _define.original.apply(window, arguments);
48
 
        else {
49
 
            console.error('dropping module because define wasn\'t a string.');
50
 
            console.trace();
51
 
        }
52
 
        return;
53
 
    }
54
 
 
55
 
    if (arguments.length == 2)
56
 
        payload = deps;
57
 
 
58
 
    if (!_define.modules)
59
 
        _define.modules = {};
60
 
 
61
 
    _define.modules[module] = payload;
62
 
};
63
 
var _require = function(parentId, module, callback) {
64
 
    if (Object.prototype.toString.call(module) === "[object Array]") {
65
 
        var params = [];
66
 
        for (var i = 0, l = module.length; i < l; ++i) {
67
 
            var dep = lookup(parentId, module[i]);
68
 
            if (!dep && _require.original)
69
 
                return _require.original.apply(window, arguments);
70
 
            params.push(dep);
71
 
        }
72
 
        if (callback) {
73
 
            callback.apply(null, params);
74
 
        }
75
 
    }
76
 
    else if (typeof module === 'string') {
77
 
        var payload = lookup(parentId, module);
78
 
        if (!payload && _require.original)
79
 
            return _require.original.apply(window, arguments);
80
 
 
81
 
        if (callback) {
82
 
            callback();
83
 
        }
84
 
 
85
 
        return payload;
86
 
    }
87
 
    else {
88
 
        if (_require.original)
89
 
            return _require.original.apply(window, arguments);
90
 
    }
91
 
};
92
 
 
93
 
var normalizeModule = function(parentId, moduleName) {
94
 
    if (moduleName.indexOf("!") !== -1) {
95
 
        var chunks = moduleName.split("!");
96
 
        return normalizeModule(parentId, chunks[0]) + "!" + normalizeModule(parentId, chunks[1]);
97
 
    }
98
 
    if (moduleName.charAt(0) == ".") {
99
 
        var base = parentId.split("/").slice(0, -1).join("/");
100
 
        moduleName = base + "/" + moduleName;
101
 
 
102
 
        while(moduleName.indexOf(".") !== -1 && previous != moduleName) {
103
 
            var previous = moduleName;
104
 
            moduleName = moduleName.replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, "");
105
 
        }
106
 
    }
107
 
 
108
 
    return moduleName;
109
 
};
110
 
var lookup = function(parentId, moduleName) {
111
 
 
112
 
    moduleName = normalizeModule(parentId, moduleName);
113
 
 
114
 
    var module = _define.modules[moduleName];
115
 
    if (!module) {
116
 
        return null;
117
 
    }
118
 
 
119
 
    if (typeof module === 'function') {
120
 
        var exports = {};
121
 
        var mod = {
122
 
            id: moduleName,
123
 
            uri: '',
124
 
            exports: exports,
125
 
            packaged: true
126
 
        };
127
 
 
128
 
        var req = function(module, callback) {
129
 
            return _require(moduleName, module, callback);
130
 
        };
131
 
 
132
 
        var returnValue = module(req, exports, mod);
133
 
        exports = returnValue || mod.exports;
134
 
        _define.modules[moduleName] = exports;
135
 
        return exports;
136
 
    }
137
 
 
138
 
    return module;
139
 
};
140
 
 
141
 
function exportAce(ns) {
142
 
    var require = function(module, callback) {
143
 
        return _require("", module, callback);
144
 
    };    
145
 
 
146
 
    var root = global;
147
 
    if (ns) {
148
 
        if (!global[ns])
149
 
            global[ns] = {};
150
 
        root = global[ns];
151
 
    }
152
 
 
153
 
    if (!root.define || !root.define.packaged) {
154
 
        _define.original = root.define;
155
 
        root.define = _define;
156
 
        root.define.packaged = true;
157
 
    }
158
 
 
159
 
    if (!root.require || !root.require.packaged) {
160
 
        _require.original = root.require;
161
 
        root.require = require;
162
 
        root.require.packaged = true;
163
 
    }
164
 
}
165
 
 
166
 
exportAce(ACE_NAMESPACE);
167
 
 
168
 
})();
169
 
 
170
 
define('ace/ace', ['require', 'exports', 'module' , 'ace/lib/fixoldbrowsers', 'ace/lib/dom', 'ace/lib/event', 'ace/editor', 'ace/edit_session', 'ace/undomanager', 'ace/virtual_renderer', 'ace/multi_select', 'ace/worker/worker_client', 'ace/keyboard/hash_handler', 'ace/placeholder', 'ace/mode/folding/fold_mode', 'ace/theme/textmate', 'ace/config'], function(require, exports, module) {
171
 
 
172
 
 
173
 
require("./lib/fixoldbrowsers");
174
 
 
175
 
var dom = require("./lib/dom");
176
 
var event = require("./lib/event");
177
 
 
178
 
var Editor = require("./editor").Editor;
179
 
var EditSession = require("./edit_session").EditSession;
180
 
var UndoManager = require("./undomanager").UndoManager;
181
 
var Renderer = require("./virtual_renderer").VirtualRenderer;
182
 
var MultiSelect = require("./multi_select").MultiSelect;
183
 
require("./worker/worker_client");
184
 
require("./keyboard/hash_handler");
185
 
require("./placeholder");
186
 
require("./mode/folding/fold_mode");
187
 
require("./theme/textmate");
188
 
 
189
 
exports.config = require("./config");
190
 
exports.require = require;
191
 
exports.edit = function(el) {
192
 
    if (typeof(el) == "string") {
193
 
        var _id = el;
194
 
        var el = document.getElementById(_id);
195
 
        if (!el)
196
 
            throw "ace.edit can't find div #" + _id;
197
 
    }
198
 
 
199
 
    if (el.env && el.env.editor instanceof Editor)
200
 
        return el.env.editor;
201
 
 
202
 
    var doc = exports.createEditSession(dom.getInnerText(el));
203
 
    el.innerHTML = '';
204
 
 
205
 
    var editor = new Editor(new Renderer(el));
206
 
    new MultiSelect(editor);
207
 
    editor.setSession(doc);
208
 
 
209
 
    var env = {
210
 
        document: doc,
211
 
        editor: editor,
212
 
        onResize: editor.resize.bind(editor, null)
213
 
    };
214
 
    event.addListener(window, "resize", env.onResize);
215
 
    editor.on("destroy", function() {
216
 
        event.removeListener(window, "resize", env.onResize);
217
 
    });
218
 
    el.env = editor.env = env;
219
 
    return editor;
220
 
};
221
 
exports.createEditSession = function(text, mode) {
222
 
    var doc = new EditSession(text, doc);
223
 
    doc.setUndoManager(new UndoManager());
224
 
    return doc;
225
 
}
226
 
exports.EditSession = EditSession;
227
 
exports.UndoManager = UndoManager;
228
 
});
229
 
 
230
 
define('ace/lib/fixoldbrowsers', ['require', 'exports', 'module' , 'ace/lib/regexp', 'ace/lib/es5-shim'], function(require, exports, module) {
231
 
 
232
 
 
233
 
require("./regexp");
234
 
require("./es5-shim");
235
 
 
236
 
});
237
 
 
238
 
define('ace/lib/regexp', ['require', 'exports', 'module' ], function(require, exports, module) {
239
 
 
240
 
    var real = {
241
 
            exec: RegExp.prototype.exec,
242
 
            test: RegExp.prototype.test,
243
 
            match: String.prototype.match,
244
 
            replace: String.prototype.replace,
245
 
            split: String.prototype.split
246
 
        },
247
 
        compliantExecNpcg = real.exec.call(/()??/, "")[1] === undefined, // check `exec` handling of nonparticipating capturing groups
248
 
        compliantLastIndexIncrement = function () {
249
 
            var x = /^/g;
250
 
            real.test.call(x, "");
251
 
            return !x.lastIndex;
252
 
        }();
253
 
 
254
 
    if (compliantLastIndexIncrement && compliantExecNpcg)
255
 
        return;
256
 
    RegExp.prototype.exec = function (str) {
257
 
        var match = real.exec.apply(this, arguments),
258
 
            name, r2;
259
 
        if ( typeof(str) == 'string' && match) {
260
 
            if (!compliantExecNpcg && match.length > 1 && indexOf(match, "") > -1) {
261
 
                r2 = RegExp(this.source, real.replace.call(getNativeFlags(this), "g", ""));
262
 
                real.replace.call(str.slice(match.index), r2, function () {
263
 
                    for (var i = 1; i < arguments.length - 2; i++) {
264
 
                        if (arguments[i] === undefined)
265
 
                            match[i] = undefined;
266
 
                    }
267
 
                });
268
 
            }
269
 
            if (this._xregexp && this._xregexp.captureNames) {
270
 
                for (var i = 1; i < match.length; i++) {
271
 
                    name = this._xregexp.captureNames[i - 1];
272
 
                    if (name)
273
 
                       match[name] = match[i];
274
 
                }
275
 
            }
276
 
            if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index))
277
 
                this.lastIndex--;
278
 
        }
279
 
        return match;
280
 
    };
281
 
    if (!compliantLastIndexIncrement) {
282
 
        RegExp.prototype.test = function (str) {
283
 
            var match = real.exec.call(this, str);
284
 
            if (match && this.global && !match[0].length && (this.lastIndex > match.index))
285
 
                this.lastIndex--;
286
 
            return !!match;
287
 
        };
288
 
    }
289
 
 
290
 
    function getNativeFlags (regex) {
291
 
        return (regex.global     ? "g" : "") +
292
 
               (regex.ignoreCase ? "i" : "") +
293
 
               (regex.multiline  ? "m" : "") +
294
 
               (regex.extended   ? "x" : "") + // Proposed for ES4; included in AS3
295
 
               (regex.sticky     ? "y" : "");
296
 
    }
297
 
 
298
 
    function indexOf (array, item, from) {
299
 
        if (Array.prototype.indexOf) // Use the native array method if available
300
 
            return array.indexOf(item, from);
301
 
        for (var i = from || 0; i < array.length; i++) {
302
 
            if (array[i] === item)
303
 
                return i;
304
 
        }
305
 
        return -1;
306
 
    }
307
 
 
308
 
});
309
 
 
310
 
define('ace/lib/es5-shim', ['require', 'exports', 'module' ], function(require, exports, module) {
311
 
 
312
 
function Empty() {}
313
 
 
314
 
if (!Function.prototype.bind) {
315
 
    Function.prototype.bind = function bind(that) { // .length is 1
316
 
        var target = this;
317
 
        if (typeof target != "function") {
318
 
            throw new TypeError("Function.prototype.bind called on incompatible " + target);
319
 
        }
320
 
        var args = slice.call(arguments, 1); // for normal call
321
 
        var bound = function () {
322
 
 
323
 
            if (this instanceof bound) {
324
 
 
325
 
                var result = target.apply(
326
 
                    this,
327
 
                    args.concat(slice.call(arguments))
328
 
                );
329
 
                if (Object(result) === result) {
330
 
                    return result;
331
 
                }
332
 
                return this;
333
 
 
334
 
            } else {
335
 
                return target.apply(
336
 
                    that,
337
 
                    args.concat(slice.call(arguments))
338
 
                );
339
 
 
340
 
            }
341
 
 
342
 
        };
343
 
        if(target.prototype) {
344
 
            Empty.prototype = target.prototype;
345
 
            bound.prototype = new Empty();
346
 
            Empty.prototype = null;
347
 
        }
348
 
        return bound;
349
 
    };
350
 
}
351
 
var call = Function.prototype.call;
352
 
var prototypeOfArray = Array.prototype;
353
 
var prototypeOfObject = Object.prototype;
354
 
var slice = prototypeOfArray.slice;
355
 
var _toString = call.bind(prototypeOfObject.toString);
356
 
var owns = call.bind(prototypeOfObject.hasOwnProperty);
357
 
var defineGetter;
358
 
var defineSetter;
359
 
var lookupGetter;
360
 
var lookupSetter;
361
 
var supportsAccessors;
362
 
if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
363
 
    defineGetter = call.bind(prototypeOfObject.__defineGetter__);
364
 
    defineSetter = call.bind(prototypeOfObject.__defineSetter__);
365
 
    lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
366
 
    lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
367
 
}
368
 
if ([1,2].splice(0).length != 2) {
369
 
    if(function() { // test IE < 9 to splice bug - see issue #138
370
 
        function makeArray(l) {
371
 
            var a = new Array(l+2);
372
 
            a[0] = a[1] = 0;
373
 
            return a;
374
 
        }
375
 
        var array = [], lengthBefore;
376
 
        
377
 
        array.splice.apply(array, makeArray(20));
378
 
        array.splice.apply(array, makeArray(26));
379
 
 
380
 
        lengthBefore = array.length; //46
381
 
        array.splice(5, 0, "XXX"); // add one element
382
 
 
383
 
        lengthBefore + 1 == array.length
384
 
 
385
 
        if (lengthBefore + 1 == array.length) {
386
 
            return true;// has right splice implementation without bugs
387
 
        }
388
 
    }()) {//IE 6/7
389
 
        var array_splice = Array.prototype.splice;
390
 
        Array.prototype.splice = function(start, deleteCount) {
391
 
            if (!arguments.length) {
392
 
                return [];
393
 
            } else {
394
 
                return array_splice.apply(this, [
395
 
                    start === void 0 ? 0 : start,
396
 
                    deleteCount === void 0 ? (this.length - start) : deleteCount
397
 
                ].concat(slice.call(arguments, 2)))
398
 
            }
399
 
        };
400
 
    } else {//IE8
401
 
        Array.prototype.splice = function(pos, removeCount){
402
 
            var length = this.length;
403
 
            if (pos > 0) {
404
 
                if (pos > length)
405
 
                    pos = length;
406
 
            } else if (pos == void 0) {
407
 
                pos = 0;
408
 
            } else if (pos < 0) {
409
 
                pos = Math.max(length + pos, 0);
410
 
            }
411
 
 
412
 
            if (!(pos+removeCount < length))
413
 
                removeCount = length - pos;
414
 
 
415
 
            var removed = this.slice(pos, pos+removeCount);
416
 
            var insert = slice.call(arguments, 2);
417
 
            var add = insert.length;            
418
 
            if (pos === length) {
419
 
                if (add) {
420
 
                    this.push.apply(this, insert);
421
 
                }
422
 
            } else {
423
 
                var remove = Math.min(removeCount, length - pos);
424
 
                var tailOldPos = pos + remove;
425
 
                var tailNewPos = tailOldPos + add - remove;
426
 
                var tailCount = length - tailOldPos;
427
 
                var lengthAfterRemove = length - remove;
428
 
 
429
 
                if (tailNewPos < tailOldPos) { // case A
430
 
                    for (var i = 0; i < tailCount; ++i) {
431
 
                        this[tailNewPos+i] = this[tailOldPos+i];
432
 
                    }
433
 
                } else if (tailNewPos > tailOldPos) { // case B
434
 
                    for (i = tailCount; i--; ) {
435
 
                        this[tailNewPos+i] = this[tailOldPos+i];
436
 
                    }
437
 
                } // else, add == remove (nothing to do)
438
 
 
439
 
                if (add && pos === lengthAfterRemove) {
440
 
                    this.length = lengthAfterRemove; // truncate array
441
 
                    this.push.apply(this, insert);
442
 
                } else {
443
 
                    this.length = lengthAfterRemove + add; // reserves space
444
 
                    for (i = 0; i < add; ++i) {
445
 
                        this[pos+i] = insert[i];
446
 
                    }
447
 
                }
448
 
            }
449
 
            return removed;
450
 
        };
451
 
    }
452
 
}
453
 
if (!Array.isArray) {
454
 
    Array.isArray = function isArray(obj) {
455
 
        return _toString(obj) == "[object Array]";
456
 
    };
457
 
}
458
 
var boxedString = Object("a"),
459
 
    splitString = boxedString[0] != "a" || !(0 in boxedString);
460
 
 
461
 
if (!Array.prototype.forEach) {
462
 
    Array.prototype.forEach = function forEach(fun /*, thisp*/) {
463
 
        var object = toObject(this),
464
 
            self = splitString && _toString(this) == "[object String]" ?
465
 
                this.split("") :
466
 
                object,
467
 
            thisp = arguments[1],
468
 
            i = -1,
469
 
            length = self.length >>> 0;
470
 
        if (_toString(fun) != "[object Function]") {
471
 
            throw new TypeError(); // TODO message
472
 
        }
473
 
 
474
 
        while (++i < length) {
475
 
            if (i in self) {
476
 
                fun.call(thisp, self[i], i, object);
477
 
            }
478
 
        }
479
 
    };
480
 
}
481
 
if (!Array.prototype.map) {
482
 
    Array.prototype.map = function map(fun /*, thisp*/) {
483
 
        var object = toObject(this),
484
 
            self = splitString && _toString(this) == "[object String]" ?
485
 
                this.split("") :
486
 
                object,
487
 
            length = self.length >>> 0,
488
 
            result = Array(length),
489
 
            thisp = arguments[1];
490
 
        if (_toString(fun) != "[object Function]") {
491
 
            throw new TypeError(fun + " is not a function");
492
 
        }
493
 
 
494
 
        for (var i = 0; i < length; i++) {
495
 
            if (i in self)
496
 
                result[i] = fun.call(thisp, self[i], i, object);
497
 
        }
498
 
        return result;
499
 
    };
500
 
}
501
 
if (!Array.prototype.filter) {
502
 
    Array.prototype.filter = function filter(fun /*, thisp */) {
503
 
        var object = toObject(this),
504
 
            self = splitString && _toString(this) == "[object String]" ?
505
 
                this.split("") :
506
 
                    object,
507
 
            length = self.length >>> 0,
508
 
            result = [],
509
 
            value,
510
 
            thisp = arguments[1];
511
 
        if (_toString(fun) != "[object Function]") {
512
 
            throw new TypeError(fun + " is not a function");
513
 
        }
514
 
 
515
 
        for (var i = 0; i < length; i++) {
516
 
            if (i in self) {
517
 
                value = self[i];
518
 
                if (fun.call(thisp, value, i, object)) {
519
 
                    result.push(value);
520
 
                }
521
 
            }
522
 
        }
523
 
        return result;
524
 
    };
525
 
}
526
 
if (!Array.prototype.every) {
527
 
    Array.prototype.every = function every(fun /*, thisp */) {
528
 
        var object = toObject(this),
529
 
            self = splitString && _toString(this) == "[object String]" ?
530
 
                this.split("") :
531
 
                object,
532
 
            length = self.length >>> 0,
533
 
            thisp = arguments[1];
534
 
        if (_toString(fun) != "[object Function]") {
535
 
            throw new TypeError(fun + " is not a function");
536
 
        }
537
 
 
538
 
        for (var i = 0; i < length; i++) {
539
 
            if (i in self && !fun.call(thisp, self[i], i, object)) {
540
 
                return false;
541
 
            }
542
 
        }
543
 
        return true;
544
 
    };
545
 
}
546
 
if (!Array.prototype.some) {
547
 
    Array.prototype.some = function some(fun /*, thisp */) {
548
 
        var object = toObject(this),
549
 
            self = splitString && _toString(this) == "[object String]" ?
550
 
                this.split("") :
551
 
                object,
552
 
            length = self.length >>> 0,
553
 
            thisp = arguments[1];
554
 
        if (_toString(fun) != "[object Function]") {
555
 
            throw new TypeError(fun + " is not a function");
556
 
        }
557
 
 
558
 
        for (var i = 0; i < length; i++) {
559
 
            if (i in self && fun.call(thisp, self[i], i, object)) {
560
 
                return true;
561
 
            }
562
 
        }
563
 
        return false;
564
 
    };
565
 
}
566
 
if (!Array.prototype.reduce) {
567
 
    Array.prototype.reduce = function reduce(fun /*, initial*/) {
568
 
        var object = toObject(this),
569
 
            self = splitString && _toString(this) == "[object String]" ?
570
 
                this.split("") :
571
 
                object,
572
 
            length = self.length >>> 0;
573
 
        if (_toString(fun) != "[object Function]") {
574
 
            throw new TypeError(fun + " is not a function");
575
 
        }
576
 
        if (!length && arguments.length == 1) {
577
 
            throw new TypeError("reduce of empty array with no initial value");
578
 
        }
579
 
 
580
 
        var i = 0;
581
 
        var result;
582
 
        if (arguments.length >= 2) {
583
 
            result = arguments[1];
584
 
        } else {
585
 
            do {
586
 
                if (i in self) {
587
 
                    result = self[i++];
588
 
                    break;
589
 
                }
590
 
                if (++i >= length) {
591
 
                    throw new TypeError("reduce of empty array with no initial value");
592
 
                }
593
 
            } while (true);
594
 
        }
595
 
 
596
 
        for (; i < length; i++) {
597
 
            if (i in self) {
598
 
                result = fun.call(void 0, result, self[i], i, object);
599
 
            }
600
 
        }
601
 
 
602
 
        return result;
603
 
    };
604
 
}
605
 
if (!Array.prototype.reduceRight) {
606
 
    Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
607
 
        var object = toObject(this),
608
 
            self = splitString && _toString(this) == "[object String]" ?
609
 
                this.split("") :
610
 
                object,
611
 
            length = self.length >>> 0;
612
 
        if (_toString(fun) != "[object Function]") {
613
 
            throw new TypeError(fun + " is not a function");
614
 
        }
615
 
        if (!length && arguments.length == 1) {
616
 
            throw new TypeError("reduceRight of empty array with no initial value");
617
 
        }
618
 
 
619
 
        var result, i = length - 1;
620
 
        if (arguments.length >= 2) {
621
 
            result = arguments[1];
622
 
        } else {
623
 
            do {
624
 
                if (i in self) {
625
 
                    result = self[i--];
626
 
                    break;
627
 
                }
628
 
                if (--i < 0) {
629
 
                    throw new TypeError("reduceRight of empty array with no initial value");
630
 
                }
631
 
            } while (true);
632
 
        }
633
 
 
634
 
        do {
635
 
            if (i in this) {
636
 
                result = fun.call(void 0, result, self[i], i, object);
637
 
            }
638
 
        } while (i--);
639
 
 
640
 
        return result;
641
 
    };
642
 
}
643
 
if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) {
644
 
    Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
645
 
        var self = splitString && _toString(this) == "[object String]" ?
646
 
                this.split("") :
647
 
                toObject(this),
648
 
            length = self.length >>> 0;
649
 
 
650
 
        if (!length) {
651
 
            return -1;
652
 
        }
653
 
 
654
 
        var i = 0;
655
 
        if (arguments.length > 1) {
656
 
            i = toInteger(arguments[1]);
657
 
        }
658
 
        i = i >= 0 ? i : Math.max(0, length + i);
659
 
        for (; i < length; i++) {
660
 
            if (i in self && self[i] === sought) {
661
 
                return i;
662
 
            }
663
 
        }
664
 
        return -1;
665
 
    };
666
 
}
667
 
if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) {
668
 
    Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
669
 
        var self = splitString && _toString(this) == "[object String]" ?
670
 
                this.split("") :
671
 
                toObject(this),
672
 
            length = self.length >>> 0;
673
 
 
674
 
        if (!length) {
675
 
            return -1;
676
 
        }
677
 
        var i = length - 1;
678
 
        if (arguments.length > 1) {
679
 
            i = Math.min(i, toInteger(arguments[1]));
680
 
        }
681
 
        i = i >= 0 ? i : length - Math.abs(i);
682
 
        for (; i >= 0; i--) {
683
 
            if (i in self && sought === self[i]) {
684
 
                return i;
685
 
            }
686
 
        }
687
 
        return -1;
688
 
    };
689
 
}
690
 
if (!Object.getPrototypeOf) {
691
 
    Object.getPrototypeOf = function getPrototypeOf(object) {
692
 
        return object.__proto__ || (
693
 
            object.constructor ?
694
 
            object.constructor.prototype :
695
 
            prototypeOfObject
696
 
        );
697
 
    };
698
 
}
699
 
if (!Object.getOwnPropertyDescriptor) {
700
 
    var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " +
701
 
                         "non-object: ";
702
 
    Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
703
 
        if ((typeof object != "object" && typeof object != "function") || object === null)
704
 
            throw new TypeError(ERR_NON_OBJECT + object);
705
 
        if (!owns(object, property))
706
 
            return;
707
 
 
708
 
        var descriptor, getter, setter;
709
 
        descriptor =  { enumerable: true, configurable: true };
710
 
        if (supportsAccessors) {
711
 
            var prototype = object.__proto__;
712
 
            object.__proto__ = prototypeOfObject;
713
 
 
714
 
            var getter = lookupGetter(object, property);
715
 
            var setter = lookupSetter(object, property);
716
 
            object.__proto__ = prototype;
717
 
 
718
 
            if (getter || setter) {
719
 
                if (getter) descriptor.get = getter;
720
 
                if (setter) descriptor.set = setter;
721
 
                return descriptor;
722
 
            }
723
 
        }
724
 
        descriptor.value = object[property];
725
 
        return descriptor;
726
 
    };
727
 
}
728
 
if (!Object.getOwnPropertyNames) {
729
 
    Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
730
 
        return Object.keys(object);
731
 
    };
732
 
}
733
 
if (!Object.create) {
734
 
    var createEmpty;
735
 
    if (Object.prototype.__proto__ === null) {
736
 
        createEmpty = function () {
737
 
            return { "__proto__": null };
738
 
        };
739
 
    } else {
740
 
        createEmpty = function () {
741
 
            var empty = {};
742
 
            for (var i in empty)
743
 
                empty[i] = null;
744
 
            empty.constructor =
745
 
            empty.hasOwnProperty =
746
 
            empty.propertyIsEnumerable =
747
 
            empty.isPrototypeOf =
748
 
            empty.toLocaleString =
749
 
            empty.toString =
750
 
            empty.valueOf =
751
 
            empty.__proto__ = null;
752
 
            return empty;
753
 
        }
754
 
    }
755
 
 
756
 
    Object.create = function create(prototype, properties) {
757
 
        var object;
758
 
        if (prototype === null) {
759
 
            object = createEmpty();
760
 
        } else {
761
 
            if (typeof prototype != "object")
762
 
                throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'");
763
 
            var Type = function () {};
764
 
            Type.prototype = prototype;
765
 
            object = new Type();
766
 
            object.__proto__ = prototype;
767
 
        }
768
 
        if (properties !== void 0)
769
 
            Object.defineProperties(object, properties);
770
 
        return object;
771
 
    };
772
 
}
773
 
 
774
 
function doesDefinePropertyWork(object) {
775
 
    try {
776
 
        Object.defineProperty(object, "sentinel", {});
777
 
        return "sentinel" in object;
778
 
    } catch (exception) {
779
 
    }
780
 
}
781
 
if (Object.defineProperty) {
782
 
    var definePropertyWorksOnObject = doesDefinePropertyWork({});
783
 
    var definePropertyWorksOnDom = typeof document == "undefined" ||
784
 
        doesDefinePropertyWork(document.createElement("div"));
785
 
    if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
786
 
        var definePropertyFallback = Object.defineProperty;
787
 
    }
788
 
}
789
 
 
790
 
if (!Object.defineProperty || definePropertyFallback) {
791
 
    var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
792
 
    var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: "
793
 
    var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " +
794
 
                                      "on this javascript engine";
795
 
 
796
 
    Object.defineProperty = function defineProperty(object, property, descriptor) {
797
 
        if ((typeof object != "object" && typeof object != "function") || object === null)
798
 
            throw new TypeError(ERR_NON_OBJECT_TARGET + object);
799
 
        if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null)
800
 
            throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
801
 
        if (definePropertyFallback) {
802
 
            try {
803
 
                return definePropertyFallback.call(Object, object, property, descriptor);
804
 
            } catch (exception) {
805
 
            }
806
 
        }
807
 
        if (owns(descriptor, "value")) {
808
 
 
809
 
            if (supportsAccessors && (lookupGetter(object, property) ||
810
 
                                      lookupSetter(object, property)))
811
 
            {
812
 
                var prototype = object.__proto__;
813
 
                object.__proto__ = prototypeOfObject;
814
 
                delete object[property];
815
 
                object[property] = descriptor.value;
816
 
                object.__proto__ = prototype;
817
 
            } else {
818
 
                object[property] = descriptor.value;
819
 
            }
820
 
        } else {
821
 
            if (!supportsAccessors)
822
 
                throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
823
 
            if (owns(descriptor, "get"))
824
 
                defineGetter(object, property, descriptor.get);
825
 
            if (owns(descriptor, "set"))
826
 
                defineSetter(object, property, descriptor.set);
827
 
        }
828
 
 
829
 
        return object;
830
 
    };
831
 
}
832
 
if (!Object.defineProperties) {
833
 
    Object.defineProperties = function defineProperties(object, properties) {
834
 
        for (var property in properties) {
835
 
            if (owns(properties, property))
836
 
                Object.defineProperty(object, property, properties[property]);
837
 
        }
838
 
        return object;
839
 
    };
840
 
}
841
 
if (!Object.seal) {
842
 
    Object.seal = function seal(object) {
843
 
        return object;
844
 
    };
845
 
}
846
 
if (!Object.freeze) {
847
 
    Object.freeze = function freeze(object) {
848
 
        return object;
849
 
    };
850
 
}
851
 
try {
852
 
    Object.freeze(function () {});
853
 
} catch (exception) {
854
 
    Object.freeze = (function freeze(freezeObject) {
855
 
        return function freeze(object) {
856
 
            if (typeof object == "function") {
857
 
                return object;
858
 
            } else {
859
 
                return freezeObject(object);
860
 
            }
861
 
        };
862
 
    })(Object.freeze);
863
 
}
864
 
if (!Object.preventExtensions) {
865
 
    Object.preventExtensions = function preventExtensions(object) {
866
 
        return object;
867
 
    };
868
 
}
869
 
if (!Object.isSealed) {
870
 
    Object.isSealed = function isSealed(object) {
871
 
        return false;
872
 
    };
873
 
}
874
 
if (!Object.isFrozen) {
875
 
    Object.isFrozen = function isFrozen(object) {
876
 
        return false;
877
 
    };
878
 
}
879
 
if (!Object.isExtensible) {
880
 
    Object.isExtensible = function isExtensible(object) {
881
 
        if (Object(object) === object) {
882
 
            throw new TypeError(); // TODO message
883
 
        }
884
 
        var name = '';
885
 
        while (owns(object, name)) {
886
 
            name += '?';
887
 
        }
888
 
        object[name] = true;
889
 
        var returnValue = owns(object, name);
890
 
        delete object[name];
891
 
        return returnValue;
892
 
    };
893
 
}
894
 
if (!Object.keys) {
895
 
    var hasDontEnumBug = true,
896
 
        dontEnums = [
897
 
            "toString",
898
 
            "toLocaleString",
899
 
            "valueOf",
900
 
            "hasOwnProperty",
901
 
            "isPrototypeOf",
902
 
            "propertyIsEnumerable",
903
 
            "constructor"
904
 
        ],
905
 
        dontEnumsLength = dontEnums.length;
906
 
 
907
 
    for (var key in {"toString": null}) {
908
 
        hasDontEnumBug = false;
909
 
    }
910
 
 
911
 
    Object.keys = function keys(object) {
912
 
 
913
 
        if (
914
 
            (typeof object != "object" && typeof object != "function") ||
915
 
            object === null
916
 
        ) {
917
 
            throw new TypeError("Object.keys called on a non-object");
918
 
        }
919
 
 
920
 
        var keys = [];
921
 
        for (var name in object) {
922
 
            if (owns(object, name)) {
923
 
                keys.push(name);
924
 
            }
925
 
        }
926
 
 
927
 
        if (hasDontEnumBug) {
928
 
            for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
929
 
                var dontEnum = dontEnums[i];
930
 
                if (owns(object, dontEnum)) {
931
 
                    keys.push(dontEnum);
932
 
                }
933
 
            }
934
 
        }
935
 
        return keys;
936
 
    };
937
 
 
938
 
}
939
 
if (!Date.now) {
940
 
    Date.now = function now() {
941
 
        return new Date().getTime();
942
 
    };
943
 
}
944
 
var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
945
 
    "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
946
 
    "\u2029\uFEFF";
947
 
if (!String.prototype.trim || ws.trim()) {
948
 
    ws = "[" + ws + "]";
949
 
    var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
950
 
        trimEndRegexp = new RegExp(ws + ws + "*$");
951
 
    String.prototype.trim = function trim() {
952
 
        return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
953
 
    };
954
 
}
955
 
 
956
 
function toInteger(n) {
957
 
    n = +n;
958
 
    if (n !== n) { // isNaN
959
 
        n = 0;
960
 
    } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) {
961
 
        n = (n > 0 || -1) * Math.floor(Math.abs(n));
962
 
    }
963
 
    return n;
964
 
}
965
 
 
966
 
function isPrimitive(input) {
967
 
    var type = typeof input;
968
 
    return (
969
 
        input === null ||
970
 
        type === "undefined" ||
971
 
        type === "boolean" ||
972
 
        type === "number" ||
973
 
        type === "string"
974
 
    );
975
 
}
976
 
 
977
 
function toPrimitive(input) {
978
 
    var val, valueOf, toString;
979
 
    if (isPrimitive(input)) {
980
 
        return input;
981
 
    }
982
 
    valueOf = input.valueOf;
983
 
    if (typeof valueOf === "function") {
984
 
        val = valueOf.call(input);
985
 
        if (isPrimitive(val)) {
986
 
            return val;
987
 
        }
988
 
    }
989
 
    toString = input.toString;
990
 
    if (typeof toString === "function") {
991
 
        val = toString.call(input);
992
 
        if (isPrimitive(val)) {
993
 
            return val;
994
 
        }
995
 
    }
996
 
    throw new TypeError();
997
 
}
998
 
var toObject = function (o) {
999
 
    if (o == null) { // this matches both null and undefined
1000
 
        throw new TypeError("can't convert "+o+" to object");
1001
 
    }
1002
 
    return Object(o);
1003
 
};
1004
 
 
1005
 
});
1006
 
 
1007
 
define('ace/lib/dom', ['require', 'exports', 'module' ], function(require, exports, module) {
1008
 
 
1009
 
 
1010
 
if (typeof document == "undefined")
1011
 
    return;
1012
 
 
1013
 
var XHTML_NS = "http://www.w3.org/1999/xhtml";
1014
 
 
1015
 
exports.getDocumentHead = function(doc) {
1016
 
    if (!doc)
1017
 
        doc = document;
1018
 
    return doc.head || doc.getElementsByTagName("head")[0] || doc.documentElement;
1019
 
}
1020
 
 
1021
 
exports.createElement = function(tag, ns) {
1022
 
    return document.createElementNS ?
1023
 
           document.createElementNS(ns || XHTML_NS, tag) :
1024
 
           document.createElement(tag);
1025
 
};
1026
 
 
1027
 
exports.hasCssClass = function(el, name) {
1028
 
    var classes = el.className.split(/\s+/g);
1029
 
    return classes.indexOf(name) !== -1;
1030
 
};
1031
 
exports.addCssClass = function(el, name) {
1032
 
    if (!exports.hasCssClass(el, name)) {
1033
 
        el.className += " " + name;
1034
 
    }
1035
 
};
1036
 
exports.removeCssClass = function(el, name) {
1037
 
    var classes = el.className.split(/\s+/g);
1038
 
    while (true) {
1039
 
        var index = classes.indexOf(name);
1040
 
        if (index == -1) {
1041
 
            break;
1042
 
        }
1043
 
        classes.splice(index, 1);
1044
 
    }
1045
 
    el.className = classes.join(" ");
1046
 
};
1047
 
 
1048
 
exports.toggleCssClass = function(el, name) {
1049
 
    var classes = el.className.split(/\s+/g), add = true;
1050
 
    while (true) {
1051
 
        var index = classes.indexOf(name);
1052
 
        if (index == -1) {
1053
 
            break;
1054
 
        }
1055
 
        add = false;
1056
 
        classes.splice(index, 1);
1057
 
    }
1058
 
    if(add)
1059
 
        classes.push(name);
1060
 
 
1061
 
    el.className = classes.join(" ");
1062
 
    return add;
1063
 
};
1064
 
exports.setCssClass = function(node, className, include) {
1065
 
    if (include) {
1066
 
        exports.addCssClass(node, className);
1067
 
    } else {
1068
 
        exports.removeCssClass(node, className);
1069
 
    }
1070
 
};
1071
 
 
1072
 
exports.hasCssString = function(id, doc) {
1073
 
    var index = 0, sheets;
1074
 
    doc = doc || document;
1075
 
 
1076
 
    if (doc.createStyleSheet && (sheets = doc.styleSheets)) {
1077
 
        while (index < sheets.length)
1078
 
            if (sheets[index++].owningElement.id === id) return true;
1079
 
    } else if ((sheets = doc.getElementsByTagName("style"))) {
1080
 
        while (index < sheets.length)
1081
 
            if (sheets[index++].id === id) return true;
1082
 
    }
1083
 
 
1084
 
    return false;
1085
 
};
1086
 
 
1087
 
exports.importCssString = function importCssString(cssText, id, doc) {
1088
 
    doc = doc || document;
1089
 
    if (id && exports.hasCssString(id, doc))
1090
 
        return null;
1091
 
    
1092
 
    var style;
1093
 
    
1094
 
    if (doc.createStyleSheet) {
1095
 
        style = doc.createStyleSheet();
1096
 
        style.cssText = cssText;
1097
 
        if (id)
1098
 
            style.owningElement.id = id;
1099
 
    } else {
1100
 
        style = doc.createElementNS
1101
 
            ? doc.createElementNS(XHTML_NS, "style")
1102
 
            : doc.createElement("style");
1103
 
 
1104
 
        style.appendChild(doc.createTextNode(cssText));
1105
 
        if (id)
1106
 
            style.id = id;
1107
 
 
1108
 
        exports.getDocumentHead(doc).appendChild(style);
1109
 
    }
1110
 
};
1111
 
 
1112
 
exports.importCssStylsheet = function(uri, doc) {
1113
 
    if (doc.createStyleSheet) {
1114
 
        doc.createStyleSheet(uri);
1115
 
    } else {
1116
 
        var link = exports.createElement('link');
1117
 
        link.rel = 'stylesheet';
1118
 
        link.href = uri;
1119
 
 
1120
 
        exports.getDocumentHead(doc).appendChild(link);
1121
 
    }
1122
 
};
1123
 
 
1124
 
exports.getInnerWidth = function(element) {
1125
 
    return (
1126
 
        parseInt(exports.computedStyle(element, "paddingLeft"), 10) +
1127
 
        parseInt(exports.computedStyle(element, "paddingRight"), 10) + 
1128
 
        element.clientWidth
1129
 
    );
1130
 
};
1131
 
 
1132
 
exports.getInnerHeight = function(element) {
1133
 
    return (
1134
 
        parseInt(exports.computedStyle(element, "paddingTop"), 10) +
1135
 
        parseInt(exports.computedStyle(element, "paddingBottom"), 10) +
1136
 
        element.clientHeight
1137
 
    );
1138
 
};
1139
 
 
1140
 
if (window.pageYOffset !== undefined) {
1141
 
    exports.getPageScrollTop = function() {
1142
 
        return window.pageYOffset;
1143
 
    };
1144
 
 
1145
 
    exports.getPageScrollLeft = function() {
1146
 
        return window.pageXOffset;
1147
 
    };
1148
 
}
1149
 
else {
1150
 
    exports.getPageScrollTop = function() {
1151
 
        return document.body.scrollTop;
1152
 
    };
1153
 
 
1154
 
    exports.getPageScrollLeft = function() {
1155
 
        return document.body.scrollLeft;
1156
 
    };
1157
 
}
1158
 
 
1159
 
if (window.getComputedStyle)
1160
 
    exports.computedStyle = function(element, style) {
1161
 
        if (style)
1162
 
            return (window.getComputedStyle(element, "") || {})[style] || "";
1163
 
        return window.getComputedStyle(element, "") || {};
1164
 
    };
1165
 
else
1166
 
    exports.computedStyle = function(element, style) {
1167
 
        if (style)
1168
 
            return element.currentStyle[style];
1169
 
        return element.currentStyle;
1170
 
    };
1171
 
 
1172
 
exports.scrollbarWidth = function(document) {
1173
 
    var inner = exports.createElement("ace_inner");
1174
 
    inner.style.width = "100%";
1175
 
    inner.style.minWidth = "0px";
1176
 
    inner.style.height = "200px";
1177
 
    inner.style.display = "block";
1178
 
 
1179
 
    var outer = exports.createElement("ace_outer");
1180
 
    var style = outer.style;
1181
 
 
1182
 
    style.position = "absolute";
1183
 
    style.left = "-10000px";
1184
 
    style.overflow = "hidden";
1185
 
    style.width = "200px";
1186
 
    style.minWidth = "0px";
1187
 
    style.height = "150px";
1188
 
    style.display = "block";
1189
 
 
1190
 
    outer.appendChild(inner);
1191
 
 
1192
 
    var body = document.documentElement;
1193
 
    body.appendChild(outer);
1194
 
 
1195
 
    var noScrollbar = inner.offsetWidth;
1196
 
 
1197
 
    style.overflow = "scroll";
1198
 
    var withScrollbar = inner.offsetWidth;
1199
 
 
1200
 
    if (noScrollbar == withScrollbar) {
1201
 
        withScrollbar = outer.clientWidth;
1202
 
    }
1203
 
 
1204
 
    body.removeChild(outer);
1205
 
 
1206
 
    return noScrollbar-withScrollbar;
1207
 
};
1208
 
exports.setInnerHtml = function(el, innerHtml) {
1209
 
    var element = el.cloneNode(false);//document.createElement("div");
1210
 
    element.innerHTML = innerHtml;
1211
 
    el.parentNode.replaceChild(element, el);
1212
 
    return element;
1213
 
};
1214
 
 
1215
 
if ("textContent" in document.documentElement) {
1216
 
    exports.setInnerText = function(el, innerText) {
1217
 
        el.textContent = innerText;
1218
 
    };
1219
 
 
1220
 
    exports.getInnerText = function(el) {
1221
 
        return el.textContent;
1222
 
    };
1223
 
}
1224
 
else {
1225
 
    exports.setInnerText = function(el, innerText) {
1226
 
        el.innerText = innerText;
1227
 
    };
1228
 
 
1229
 
    exports.getInnerText = function(el) {
1230
 
        return el.innerText;
1231
 
    };
1232
 
}
1233
 
 
1234
 
exports.getParentWindow = function(document) {
1235
 
    return document.defaultView || document.parentWindow;
1236
 
};
1237
 
 
1238
 
});
1239
 
 
1240
 
define('ace/lib/event', ['require', 'exports', 'module' , 'ace/lib/keys', 'ace/lib/useragent', 'ace/lib/dom'], function(require, exports, module) {
1241
 
 
1242
 
 
1243
 
var keys = require("./keys");
1244
 
var useragent = require("./useragent");
1245
 
var dom = require("./dom");
1246
 
 
1247
 
exports.addListener = function(elem, type, callback) {
1248
 
    if (elem.addEventListener) {
1249
 
        return elem.addEventListener(type, callback, false);
1250
 
    }
1251
 
    if (elem.attachEvent) {
1252
 
        var wrapper = function() {
1253
 
            callback(window.event);
1254
 
        };
1255
 
        callback._wrapper = wrapper;
1256
 
        elem.attachEvent("on" + type, wrapper);
1257
 
    }
1258
 
};
1259
 
 
1260
 
exports.removeListener = function(elem, type, callback) {
1261
 
    if (elem.removeEventListener) {
1262
 
        return elem.removeEventListener(type, callback, false);
1263
 
    }
1264
 
    if (elem.detachEvent) {
1265
 
        elem.detachEvent("on" + type, callback._wrapper || callback);
1266
 
    }
1267
 
};
1268
 
exports.stopEvent = function(e) {
1269
 
    exports.stopPropagation(e);
1270
 
    exports.preventDefault(e);
1271
 
    return false;
1272
 
};
1273
 
 
1274
 
exports.stopPropagation = function(e) {
1275
 
    if (e.stopPropagation)
1276
 
        e.stopPropagation();
1277
 
    else
1278
 
        e.cancelBubble = true;
1279
 
};
1280
 
 
1281
 
exports.preventDefault = function(e) {
1282
 
    if (e.preventDefault)
1283
 
        e.preventDefault();
1284
 
    else
1285
 
        e.returnValue = false;
1286
 
};
1287
 
exports.getButton = function(e) {
1288
 
    if (e.type == "dblclick")
1289
 
        return 0;
1290
 
    if (e.type == "contextmenu" || (e.ctrlKey && useragent.isMac))
1291
 
        return 2;
1292
 
    if (e.preventDefault) {
1293
 
        return e.button;
1294
 
    }
1295
 
    else {
1296
 
        return {1:0, 2:2, 4:1}[e.button];
1297
 
    }
1298
 
};
1299
 
 
1300
 
if (document.documentElement.setCapture) {
1301
 
    exports.capture = function(el, eventHandler, releaseCaptureHandler) {
1302
 
        var called = false;
1303
 
        function onReleaseCapture(e) {
1304
 
            eventHandler(e);
1305
 
 
1306
 
            if (!called) {
1307
 
                called = true;
1308
 
                releaseCaptureHandler(e);
1309
 
            }
1310
 
 
1311
 
            exports.removeListener(el, "mousemove", eventHandler);
1312
 
            exports.removeListener(el, "mouseup", onReleaseCapture);
1313
 
            exports.removeListener(el, "losecapture", onReleaseCapture);
1314
 
 
1315
 
            el.releaseCapture();
1316
 
        }
1317
 
 
1318
 
        exports.addListener(el, "mousemove", eventHandler);
1319
 
        exports.addListener(el, "mouseup", onReleaseCapture);
1320
 
        exports.addListener(el, "losecapture", onReleaseCapture);
1321
 
        el.setCapture();
1322
 
    };
1323
 
}
1324
 
else {
1325
 
    exports.capture = function(el, eventHandler, releaseCaptureHandler) {
1326
 
        function onMouseUp(e) {
1327
 
            eventHandler && eventHandler(e);
1328
 
            releaseCaptureHandler && releaseCaptureHandler(e);
1329
 
 
1330
 
            document.removeEventListener("mousemove", eventHandler, true);
1331
 
            document.removeEventListener("mouseup", onMouseUp, true);
1332
 
 
1333
 
            e.stopPropagation();
1334
 
        }
1335
 
 
1336
 
        document.addEventListener("mousemove", eventHandler, true);
1337
 
        document.addEventListener("mouseup", onMouseUp, true);
1338
 
    };
1339
 
}
1340
 
 
1341
 
exports.addMouseWheelListener = function(el, callback) {
1342
 
    var factor = 8;
1343
 
    var listener = function(e) {
1344
 
        if (e.wheelDelta !== undefined) {
1345
 
            if (e.wheelDeltaX !== undefined) {
1346
 
                e.wheelX = -e.wheelDeltaX / factor;
1347
 
                e.wheelY = -e.wheelDeltaY / factor;
1348
 
            } else {
1349
 
                e.wheelX = 0;
1350
 
                e.wheelY = -e.wheelDelta / factor;
1351
 
            }
1352
 
        }
1353
 
        else {
1354
 
            if (e.axis && e.axis == e.HORIZONTAL_AXIS) {
1355
 
                e.wheelX = (e.detail || 0) * 5;
1356
 
                e.wheelY = 0;
1357
 
            } else {
1358
 
                e.wheelX = 0;
1359
 
                e.wheelY = (e.detail || 0) * 5;
1360
 
            }
1361
 
        }
1362
 
        callback(e);
1363
 
    };
1364
 
    exports.addListener(el, "DOMMouseScroll", listener);
1365
 
    exports.addListener(el, "mousewheel", listener);
1366
 
};
1367
 
 
1368
 
exports.addMultiMouseDownListener = function(el, timeouts, eventHandler, callbackName) {
1369
 
    var clicks = 0;
1370
 
    var startX, startY, timer;
1371
 
    var eventNames = {
1372
 
        2: "dblclick",
1373
 
        3: "tripleclick",
1374
 
        4: "quadclick"
1375
 
    };
1376
 
 
1377
 
    exports.addListener(el, "mousedown", function(e) {
1378
 
        if (exports.getButton(e) != 0) {
1379
 
            clicks = 0;
1380
 
        } else {
1381
 
            var isNewClick = Math.abs(e.clientX - startX) > 5 || Math.abs(e.clientY - startY) > 5;
1382
 
 
1383
 
            if (!timer || isNewClick)
1384
 
                clicks = 0;
1385
 
 
1386
 
            clicks += 1;
1387
 
 
1388
 
            if (timer)
1389
 
                clearTimeout(timer)
1390
 
            timer = setTimeout(function() {timer = null}, timeouts[clicks - 1] || 600);
1391
 
        }
1392
 
        if (clicks == 1) {
1393
 
            startX = e.clientX;
1394
 
            startY = e.clientY;
1395
 
        }
1396
 
 
1397
 
        eventHandler[callbackName]("mousedown", e);
1398
 
 
1399
 
        if (clicks > 4)
1400
 
            clicks = 0;
1401
 
        else if (clicks > 1)
1402
 
            return eventHandler[callbackName](eventNames[clicks], e);
1403
 
    });
1404
 
 
1405
 
    if (useragent.isOldIE) {
1406
 
        exports.addListener(el, "dblclick", function(e) {
1407
 
            clicks = 2;
1408
 
            if (timer)
1409
 
                clearTimeout(timer);
1410
 
            timer = setTimeout(function() {timer = null}, timeouts[clicks - 1] || 600);
1411
 
            eventHandler[callbackName]("mousedown", e);
1412
 
            eventHandler[callbackName](eventNames[clicks], e);
1413
 
        });
1414
 
    }
1415
 
};
1416
 
 
1417
 
function normalizeCommandKeys(callback, e, keyCode) {
1418
 
    var hashId = 0;
1419
 
    if ((useragent.isOpera && !("KeyboardEvent" in window)) && useragent.isMac) {
1420
 
        hashId = 0 | (e.metaKey ? 1 : 0) | (e.altKey ? 2 : 0)
1421
 
            | (e.shiftKey ? 4 : 0) | (e.ctrlKey ? 8 : 0);
1422
 
    } else {
1423
 
        hashId = 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0)
1424
 
            | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0);
1425
 
    }
1426
 
 
1427
 
    if (keyCode in keys.MODIFIER_KEYS) {
1428
 
        switch (keys.MODIFIER_KEYS[keyCode]) {
1429
 
            case "Alt":
1430
 
                hashId = 2;
1431
 
                break;
1432
 
            case "Shift":
1433
 
                hashId = 4;
1434
 
                break;
1435
 
            case "Ctrl":
1436
 
                hashId = 1;
1437
 
                break;
1438
 
            default:
1439
 
                hashId = 8;
1440
 
                break;
1441
 
        }
1442
 
        keyCode = 0;
1443
 
    }
1444
 
 
1445
 
    if (hashId & 8 && (keyCode == 91 || keyCode == 93)) {
1446
 
        keyCode = 0;
1447
 
    }
1448
 
    if (!hashId && !(keyCode in keys.FUNCTION_KEYS) && !(keyCode in keys.PRINTABLE_KEYS)) {
1449
 
        return false;
1450
 
    }
1451
 
    return callback(e, hashId, keyCode);
1452
 
}
1453
 
 
1454
 
exports.addCommandKeyListener = function(el, callback) {
1455
 
    var addListener = exports.addListener;
1456
 
    if (useragent.isOldGecko || (useragent.isOpera && !("KeyboardEvent" in window))) {
1457
 
        var lastKeyDownKeyCode = null;
1458
 
        addListener(el, "keydown", function(e) {
1459
 
            lastKeyDownKeyCode = e.keyCode;
1460
 
        });
1461
 
        addListener(el, "keypress", function(e) {
1462
 
            return normalizeCommandKeys(callback, e, lastKeyDownKeyCode);
1463
 
        });
1464
 
    } else {
1465
 
        var lastDown = null;
1466
 
 
1467
 
        addListener(el, "keydown", function(e) {
1468
 
            lastDown = e.keyIdentifier || e.keyCode;
1469
 
            return normalizeCommandKeys(callback, e, e.keyCode);
1470
 
        });
1471
 
    }
1472
 
};
1473
 
 
1474
 
if (window.postMessage && !useragent.isOldIE) {
1475
 
    var postMessageId = 1;
1476
 
    exports.nextTick = function(callback, win) {
1477
 
        win = win || window;
1478
 
        var messageName = "zero-timeout-message-" + postMessageId;
1479
 
        exports.addListener(win, "message", function listener(e) {
1480
 
            if (e.data == messageName) {
1481
 
                exports.stopPropagation(e);
1482
 
                exports.removeListener(win, "message", listener);
1483
 
                callback();
1484
 
            }
1485
 
        });
1486
 
        win.postMessage(messageName, "*");
1487
 
    };
1488
 
}
1489
 
 
1490
 
 
1491
 
exports.nextFrame = window.requestAnimationFrame ||
1492
 
    window.mozRequestAnimationFrame ||
1493
 
    window.webkitRequestAnimationFrame ||
1494
 
    window.msRequestAnimationFrame ||
1495
 
    window.oRequestAnimationFrame;
1496
 
 
1497
 
if (exports.nextFrame)
1498
 
    exports.nextFrame = exports.nextFrame.bind(window);
1499
 
else
1500
 
    exports.nextFrame = function(callback) {
1501
 
        setTimeout(callback, 17);
1502
 
    };
1503
 
});
1504
 
 
1505
 
define('ace/lib/keys', ['require', 'exports', 'module' , 'ace/lib/oop'], function(require, exports, module) {
1506
 
 
1507
 
 
1508
 
var oop = require("./oop");
1509
 
var Keys = (function() {
1510
 
    var ret = {
1511
 
        MODIFIER_KEYS: {
1512
 
            16: 'Shift', 17: 'Ctrl', 18: 'Alt', 224: 'Meta'
1513
 
        },
1514
 
 
1515
 
        KEY_MODS: {
1516
 
            "ctrl": 1, "alt": 2, "option" : 2,
1517
 
            "shift": 4, "meta": 8, "command": 8
1518
 
        },
1519
 
 
1520
 
        FUNCTION_KEYS : {
1521
 
            8  : "Backspace",
1522
 
            9  : "Tab",
1523
 
            13 : "Return",
1524
 
            19 : "Pause",
1525
 
            27 : "Esc",
1526
 
            32 : "Space",
1527
 
            33 : "PageUp",
1528
 
            34 : "PageDown",
1529
 
            35 : "End",
1530
 
            36 : "Home",
1531
 
            37 : "Left",
1532
 
            38 : "Up",
1533
 
            39 : "Right",
1534
 
            40 : "Down",
1535
 
            44 : "Print",
1536
 
            45 : "Insert",
1537
 
            46 : "Delete",
1538
 
            96 : "Numpad0",
1539
 
            97 : "Numpad1",
1540
 
            98 : "Numpad2",
1541
 
            99 : "Numpad3",
1542
 
            100: "Numpad4",
1543
 
            101: "Numpad5",
1544
 
            102: "Numpad6",
1545
 
            103: "Numpad7",
1546
 
            104: "Numpad8",
1547
 
            105: "Numpad9",
1548
 
            112: "F1",
1549
 
            113: "F2",
1550
 
            114: "F3",
1551
 
            115: "F4",
1552
 
            116: "F5",
1553
 
            117: "F6",
1554
 
            118: "F7",
1555
 
            119: "F8",
1556
 
            120: "F9",
1557
 
            121: "F10",
1558
 
            122: "F11",
1559
 
            123: "F12",
1560
 
            144: "Numlock",
1561
 
            145: "Scrolllock"
1562
 
        },
1563
 
 
1564
 
        PRINTABLE_KEYS: {
1565
 
           32: ' ',  48: '0',  49: '1',  50: '2',  51: '3',  52: '4', 53:  '5',
1566
 
           54: '6',  55: '7',  56: '8',  57: '9',  59: ';',  61: '=', 65:  'a',
1567
 
           66: 'b',  67: 'c',  68: 'd',  69: 'e',  70: 'f',  71: 'g', 72:  'h',
1568
 
           73: 'i',  74: 'j',  75: 'k',  76: 'l',  77: 'm',  78: 'n', 79:  'o',
1569
 
           80: 'p',  81: 'q',  82: 'r',  83: 's',  84: 't',  85: 'u', 86:  'v',
1570
 
           87: 'w',  88: 'x',  89: 'y',  90: 'z', 107: '+', 109: '-', 110: '.',
1571
 
          188: ',', 190: '.', 191: '/', 192: '`', 219: '[', 220: '\\',
1572
 
          221: ']', 222: '\''
1573
 
        }
1574
 
    };
1575
 
    for (var i in ret.FUNCTION_KEYS) {
1576
 
        var name = ret.FUNCTION_KEYS[i].toLowerCase();
1577
 
        ret[name] = parseInt(i, 10);
1578
 
    }
1579
 
    oop.mixin(ret, ret.MODIFIER_KEYS);
1580
 
    oop.mixin(ret, ret.PRINTABLE_KEYS);
1581
 
    oop.mixin(ret, ret.FUNCTION_KEYS);
1582
 
    ret.enter = ret["return"];
1583
 
    ret.escape = ret.esc;
1584
 
    ret.del = ret["delete"];
1585
 
    ret[173] = '-';
1586
 
 
1587
 
    return ret;
1588
 
})();
1589
 
oop.mixin(exports, Keys);
1590
 
 
1591
 
exports.keyCodeToString = function(keyCode) {
1592
 
    return (Keys[keyCode] || String.fromCharCode(keyCode)).toLowerCase();
1593
 
}
1594
 
 
1595
 
});
1596
 
 
1597
 
define('ace/lib/oop', ['require', 'exports', 'module' ], function(require, exports, module) {
1598
 
 
1599
 
 
1600
 
exports.inherits = (function() {
1601
 
    var tempCtor = function() {};
1602
 
    return function(ctor, superCtor) {
1603
 
        tempCtor.prototype = superCtor.prototype;
1604
 
        ctor.super_ = superCtor.prototype;
1605
 
        ctor.prototype = new tempCtor();
1606
 
        ctor.prototype.constructor = ctor;
1607
 
    };
1608
 
}());
1609
 
 
1610
 
exports.mixin = function(obj, mixin) {
1611
 
    for (var key in mixin) {
1612
 
        obj[key] = mixin[key];
1613
 
    }
1614
 
};
1615
 
 
1616
 
exports.implement = function(proto, mixin) {
1617
 
    exports.mixin(proto, mixin);
1618
 
};
1619
 
 
1620
 
});
1621
 
 
1622
 
define('ace/lib/useragent', ['require', 'exports', 'module' ], function(require, exports, module) {
1623
 
exports.OS = {
1624
 
    LINUX: "LINUX",
1625
 
    MAC: "MAC",
1626
 
    WINDOWS: "WINDOWS"
1627
 
};
1628
 
exports.getOS = function() {
1629
 
    if (exports.isMac) {
1630
 
        return exports.OS.MAC;
1631
 
    } else if (exports.isLinux) {
1632
 
        return exports.OS.LINUX;
1633
 
    } else {
1634
 
        return exports.OS.WINDOWS;
1635
 
    }
1636
 
};
1637
 
if (typeof navigator != "object")
1638
 
    return;
1639
 
 
1640
 
var os = (navigator.platform.match(/mac|win|linux/i) || ["other"])[0].toLowerCase();
1641
 
var ua = navigator.userAgent;
1642
 
exports.isWin = (os == "win");
1643
 
exports.isMac = (os == "mac");
1644
 
exports.isLinux = (os == "linux");
1645
 
exports.isIE = 
1646
 
    (navigator.appName == "Microsoft Internet Explorer" || navigator.appName.indexOf("MSAppHost") >= 0)
1647
 
    && parseFloat(navigator.userAgent.match(/MSIE ([0-9]+[\.0-9]+)/)[1]);
1648
 
    
1649
 
exports.isOldIE = exports.isIE && exports.isIE < 9;
1650
 
exports.isGecko = exports.isMozilla = window.controllers && window.navigator.product === "Gecko";
1651
 
exports.isOldGecko = exports.isGecko && parseInt((navigator.userAgent.match(/rv\:(\d+)/)||[])[1], 10) < 4;
1652
 
exports.isOpera = window.opera && Object.prototype.toString.call(window.opera) == "[object Opera]";
1653
 
exports.isWebKit = parseFloat(ua.split("WebKit/")[1]) || undefined;
1654
 
 
1655
 
exports.isChrome = parseFloat(ua.split(" Chrome/")[1]) || undefined;
1656
 
 
1657
 
exports.isAIR = ua.indexOf("AdobeAIR") >= 0;
1658
 
 
1659
 
exports.isIPad = ua.indexOf("iPad") >= 0;
1660
 
 
1661
 
exports.isTouchPad = ua.indexOf("TouchPad") >= 0;
1662
 
 
1663
 
});
1664
 
 
1665
 
define('ace/editor', ['require', 'exports', 'module' , 'ace/lib/fixoldbrowsers', 'ace/lib/oop', 'ace/lib/lang', 'ace/lib/useragent', 'ace/keyboard/textinput', 'ace/mouse/mouse_handler', 'ace/mouse/fold_handler', 'ace/keyboard/keybinding', 'ace/edit_session', 'ace/search', 'ace/range', 'ace/lib/event_emitter', 'ace/commands/command_manager', 'ace/commands/default_commands', 'ace/config'], function(require, exports, module) {
1666
 
 
1667
 
 
1668
 
require("./lib/fixoldbrowsers");
1669
 
 
1670
 
var oop = require("./lib/oop");
1671
 
var lang = require("./lib/lang");
1672
 
var useragent = require("./lib/useragent");
1673
 
var TextInput = require("./keyboard/textinput").TextInput;
1674
 
var MouseHandler = require("./mouse/mouse_handler").MouseHandler;
1675
 
var FoldHandler = require("./mouse/fold_handler").FoldHandler;
1676
 
var KeyBinding = require("./keyboard/keybinding").KeyBinding;
1677
 
var EditSession = require("./edit_session").EditSession;
1678
 
var Search = require("./search").Search;
1679
 
var Range = require("./range").Range;
1680
 
var EventEmitter = require("./lib/event_emitter").EventEmitter;
1681
 
var CommandManager = require("./commands/command_manager").CommandManager;
1682
 
var defaultCommands = require("./commands/default_commands").commands;
1683
 
var config = require("./config");
1684
 
var Editor = function(renderer, session) {
1685
 
    var container = renderer.getContainerElement();
1686
 
    this.container = container;
1687
 
    this.renderer = renderer;
1688
 
 
1689
 
    this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands);
1690
 
    this.textInput  = new TextInput(renderer.getTextAreaContainer(), this);
1691
 
    this.renderer.textarea = this.textInput.getElement();
1692
 
    this.keyBinding = new KeyBinding(this);
1693
 
    this.$mouseHandler = new MouseHandler(this);
1694
 
    new FoldHandler(this);
1695
 
 
1696
 
    this.$blockScrolling = 0;
1697
 
    this.$search = new Search().set({
1698
 
        wrap: true
1699
 
    });
1700
 
 
1701
 
    this.setSession(session || new EditSession(""));
1702
 
    config.resetOptions(this);
1703
 
    config._emit("editor", this);
1704
 
};
1705
 
 
1706
 
(function(){
1707
 
 
1708
 
    oop.implement(this, EventEmitter);
1709
 
    this.setKeyboardHandler = function(keyboardHandler) {
1710
 
        if (typeof keyboardHandler == "string" && keyboardHandler) {
1711
 
            this.$keybindingId = keyboardHandler;
1712
 
            var _self = this;
1713
 
            config.loadModule(["keybinding", keyboardHandler], function(module) {
1714
 
                if (_self.$keybindingId == keyboardHandler)
1715
 
                    _self.keyBinding.setKeyboardHandler(module && module.handler);
1716
 
            });
1717
 
        } else {
1718
 
            delete this.$keybindingId;
1719
 
            this.keyBinding.setKeyboardHandler(keyboardHandler);
1720
 
        }
1721
 
    };
1722
 
    this.getKeyboardHandler = function() {
1723
 
        return this.keyBinding.getKeyboardHandler();
1724
 
    };
1725
 
    this.setSession = function(session) {
1726
 
        if (this.session == session)
1727
 
            return;
1728
 
 
1729
 
        if (this.session) {
1730
 
            var oldSession = this.session;
1731
 
            this.session.removeEventListener("change", this.$onDocumentChange);
1732
 
            this.session.removeEventListener("changeMode", this.$onChangeMode);
1733
 
            this.session.removeEventListener("tokenizerUpdate", this.$onTokenizerUpdate);
1734
 
            this.session.removeEventListener("changeTabSize", this.$onChangeTabSize);
1735
 
            this.session.removeEventListener("changeWrapLimit", this.$onChangeWrapLimit);
1736
 
            this.session.removeEventListener("changeWrapMode", this.$onChangeWrapMode);
1737
 
            this.session.removeEventListener("onChangeFold", this.$onChangeFold);
1738
 
            this.session.removeEventListener("changeFrontMarker", this.$onChangeFrontMarker);
1739
 
            this.session.removeEventListener("changeBackMarker", this.$onChangeBackMarker);
1740
 
            this.session.removeEventListener("changeBreakpoint", this.$onChangeBreakpoint);
1741
 
            this.session.removeEventListener("changeAnnotation", this.$onChangeAnnotation);
1742
 
            this.session.removeEventListener("changeOverwrite", this.$onCursorChange);
1743
 
            this.session.removeEventListener("changeScrollTop", this.$onScrollTopChange);
1744
 
            this.session.removeEventListener("changeLeftTop", this.$onScrollLeftChange);
1745
 
 
1746
 
            var selection = this.session.getSelection();
1747
 
            selection.removeEventListener("changeCursor", this.$onCursorChange);
1748
 
            selection.removeEventListener("changeSelection", this.$onSelectionChange);
1749
 
        }
1750
 
 
1751
 
        this.session = session;
1752
 
 
1753
 
        this.$onDocumentChange = this.onDocumentChange.bind(this);
1754
 
        session.addEventListener("change", this.$onDocumentChange);
1755
 
        this.renderer.setSession(session);
1756
 
 
1757
 
        this.$onChangeMode = this.onChangeMode.bind(this);
1758
 
        session.addEventListener("changeMode", this.$onChangeMode);
1759
 
 
1760
 
        this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this);
1761
 
        session.addEventListener("tokenizerUpdate", this.$onTokenizerUpdate);
1762
 
 
1763
 
        this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer);
1764
 
        session.addEventListener("changeTabSize", this.$onChangeTabSize);
1765
 
 
1766
 
        this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this);
1767
 
        session.addEventListener("changeWrapLimit", this.$onChangeWrapLimit);
1768
 
 
1769
 
        this.$onChangeWrapMode = this.onChangeWrapMode.bind(this);
1770
 
        session.addEventListener("changeWrapMode", this.$onChangeWrapMode);
1771
 
 
1772
 
        this.$onChangeFold = this.onChangeFold.bind(this);
1773
 
        session.addEventListener("changeFold", this.$onChangeFold);
1774
 
 
1775
 
        this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this);
1776
 
        this.session.addEventListener("changeFrontMarker", this.$onChangeFrontMarker);
1777
 
 
1778
 
        this.$onChangeBackMarker = this.onChangeBackMarker.bind(this);
1779
 
        this.session.addEventListener("changeBackMarker", this.$onChangeBackMarker);
1780
 
 
1781
 
        this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this);
1782
 
        this.session.addEventListener("changeBreakpoint", this.$onChangeBreakpoint);
1783
 
 
1784
 
        this.$onChangeAnnotation = this.onChangeAnnotation.bind(this);
1785
 
        this.session.addEventListener("changeAnnotation", this.$onChangeAnnotation);
1786
 
 
1787
 
        this.$onCursorChange = this.onCursorChange.bind(this);
1788
 
        this.session.addEventListener("changeOverwrite", this.$onCursorChange);
1789
 
 
1790
 
        this.$onScrollTopChange = this.onScrollTopChange.bind(this);
1791
 
        this.session.addEventListener("changeScrollTop", this.$onScrollTopChange);
1792
 
 
1793
 
        this.$onScrollLeftChange = this.onScrollLeftChange.bind(this);
1794
 
        this.session.addEventListener("changeScrollLeft", this.$onScrollLeftChange);
1795
 
 
1796
 
        this.selection = session.getSelection();
1797
 
        this.selection.addEventListener("changeCursor", this.$onCursorChange);
1798
 
 
1799
 
        this.$onSelectionChange = this.onSelectionChange.bind(this);
1800
 
        this.selection.addEventListener("changeSelection", this.$onSelectionChange);
1801
 
 
1802
 
        this.onChangeMode();
1803
 
 
1804
 
        this.$blockScrolling += 1;
1805
 
        this.onCursorChange();
1806
 
        this.$blockScrolling -= 1;
1807
 
 
1808
 
        this.onScrollTopChange();
1809
 
        this.onScrollLeftChange();
1810
 
        this.onSelectionChange();
1811
 
        this.onChangeFrontMarker();
1812
 
        this.onChangeBackMarker();
1813
 
        this.onChangeBreakpoint();
1814
 
        this.onChangeAnnotation();
1815
 
        this.session.getUseWrapMode() && this.renderer.adjustWrapLimit();
1816
 
        this.renderer.updateFull();
1817
 
 
1818
 
        this._emit("changeSession", {
1819
 
            session: session,
1820
 
            oldSession: oldSession
1821
 
        });
1822
 
    };
1823
 
    this.getSession = function() {
1824
 
        return this.session;
1825
 
    };
1826
 
    this.setValue = function(val, cursorPos) {
1827
 
        this.session.doc.setValue(val);
1828
 
 
1829
 
        if (!cursorPos)
1830
 
            this.selectAll();
1831
 
        else if (cursorPos == 1)
1832
 
            this.navigateFileEnd();
1833
 
        else if (cursorPos == -1)
1834
 
            this.navigateFileStart();
1835
 
 
1836
 
        return val;
1837
 
    };
1838
 
    this.getValue = function() {
1839
 
        return this.session.getValue();
1840
 
    };
1841
 
    this.getSelection = function() {
1842
 
        return this.selection;
1843
 
    };
1844
 
    this.resize = function(force) {
1845
 
        this.renderer.onResize(force);
1846
 
    };
1847
 
    this.setTheme = function(theme) {
1848
 
        this.renderer.setTheme(theme);
1849
 
    };
1850
 
    this.getTheme = function() {
1851
 
        return this.renderer.getTheme();
1852
 
    };
1853
 
    this.setStyle = function(style) {
1854
 
        this.renderer.setStyle(style);
1855
 
    };
1856
 
    this.unsetStyle = function(style) {
1857
 
        this.renderer.unsetStyle(style);
1858
 
    };
1859
 
    this.setFontSize = function(size) {
1860
 
        if (typeof size == "number")
1861
 
            size = size + "px";
1862
 
        this.container.style.fontSize = size;
1863
 
        this.renderer.updateFontSize();
1864
 
    };
1865
 
 
1866
 
    this.$highlightBrackets = function() {
1867
 
        if (this.session.$bracketHighlight) {
1868
 
            this.session.removeMarker(this.session.$bracketHighlight);
1869
 
            this.session.$bracketHighlight = null;
1870
 
        }
1871
 
 
1872
 
        if (this.$highlightPending) {
1873
 
            return;
1874
 
        }
1875
 
        var self = this;
1876
 
        this.$highlightPending = true;
1877
 
        setTimeout(function() {
1878
 
            self.$highlightPending = false;
1879
 
 
1880
 
            var pos = self.session.findMatchingBracket(self.getCursorPosition());
1881
 
            if (pos) {
1882
 
                var range = new Range(pos.row, pos.column, pos.row, pos.column+1);
1883
 
            } else if (self.session.$mode.getMatching) {
1884
 
                var range = self.session.$mode.getMatching(self.session);
1885
 
            }
1886
 
            if (range)
1887
 
                self.session.$bracketHighlight = self.session.addMarker(range, "ace_bracket", "text");
1888
 
        }, 50);
1889
 
    };
1890
 
    this.focus = function() {
1891
 
        var _self = this;
1892
 
        setTimeout(function() {
1893
 
            _self.textInput.focus();
1894
 
        });
1895
 
        this.textInput.focus();
1896
 
    };
1897
 
    this.isFocused = function() {
1898
 
        return this.textInput.isFocused();
1899
 
    };
1900
 
    this.blur = function() {
1901
 
        this.textInput.blur();
1902
 
    };
1903
 
    this.onFocus = function() {
1904
 
        if (this.$isFocused)
1905
 
            return;
1906
 
        this.$isFocused = true;
1907
 
        this.renderer.showCursor();
1908
 
        this.renderer.visualizeFocus();
1909
 
        this._emit("focus");
1910
 
    };
1911
 
    this.onBlur = function() {
1912
 
        if (!this.$isFocused)
1913
 
            return;
1914
 
        this.$isFocused = false;
1915
 
        this.renderer.hideCursor();
1916
 
        this.renderer.visualizeBlur();
1917
 
        this._emit("blur");
1918
 
    };
1919
 
 
1920
 
    this.$cursorChange = function() {
1921
 
        this.renderer.updateCursor();
1922
 
    };
1923
 
    this.onDocumentChange = function(e) {
1924
 
        var delta = e.data;
1925
 
        var range = delta.range;
1926
 
        var lastRow;
1927
 
 
1928
 
        if (range.start.row == range.end.row && delta.action != "insertLines" && delta.action != "removeLines")
1929
 
            lastRow = range.end.row;
1930
 
        else
1931
 
            lastRow = Infinity;
1932
 
        this.renderer.updateLines(range.start.row, lastRow);
1933
 
 
1934
 
        this._emit("change", e);
1935
 
        this.$cursorChange();
1936
 
    };
1937
 
 
1938
 
    this.onTokenizerUpdate = function(e) {
1939
 
        var rows = e.data;
1940
 
        this.renderer.updateLines(rows.first, rows.last);
1941
 
    };
1942
 
 
1943
 
 
1944
 
    this.onScrollTopChange = function() {
1945
 
        this.renderer.scrollToY(this.session.getScrollTop());
1946
 
    };
1947
 
 
1948
 
    this.onScrollLeftChange = function() {
1949
 
        this.renderer.scrollToX(this.session.getScrollLeft());
1950
 
    };
1951
 
    this.onCursorChange = function() {
1952
 
        this.$cursorChange();
1953
 
 
1954
 
        if (!this.$blockScrolling) {
1955
 
            this.renderer.scrollCursorIntoView();
1956
 
        }
1957
 
 
1958
 
        this.$highlightBrackets();
1959
 
        this.$updateHighlightActiveLine();
1960
 
        this._emit("changeSelection");
1961
 
    };
1962
 
 
1963
 
    this.$updateHighlightActiveLine = function() {
1964
 
        var session = this.getSession();
1965
 
 
1966
 
        var highlight;
1967
 
        if (this.$highlightActiveLine) {
1968
 
            if ((this.$selectionStyle != "line" || !this.selection.isMultiLine()))
1969
 
                highlight = this.getCursorPosition();
1970
 
        }
1971
 
 
1972
 
        if (session.$highlightLineMarker && !highlight) {
1973
 
            session.removeMarker(session.$highlightLineMarker.id);
1974
 
            session.$highlightLineMarker = null;
1975
 
        } else if (!session.$highlightLineMarker && highlight) {
1976
 
            var range = new Range(highlight.row, highlight.column, highlight.row, Infinity);
1977
 
            range.id = session.addMarker(range, "ace_active-line", "screenLine");
1978
 
            session.$highlightLineMarker = range;
1979
 
        } else if (highlight) {
1980
 
            session.$highlightLineMarker.start.row = highlight.row;
1981
 
            session.$highlightLineMarker.end.row = highlight.row;
1982
 
            session.$highlightLineMarker.start.column = highlight.column;
1983
 
            session._emit("changeBackMarker");
1984
 
        }
1985
 
    };
1986
 
 
1987
 
    this.onSelectionChange = function(e) {
1988
 
        var session = this.session;
1989
 
 
1990
 
        if (session.$selectionMarker) {
1991
 
            session.removeMarker(session.$selectionMarker);
1992
 
        }
1993
 
        session.$selectionMarker = null;
1994
 
 
1995
 
        if (!this.selection.isEmpty()) {
1996
 
            var range = this.selection.getRange();
1997
 
            var style = this.getSelectionStyle();
1998
 
            session.$selectionMarker = session.addMarker(range, "ace_selection", style);
1999
 
        } else {
2000
 
            this.$updateHighlightActiveLine();
2001
 
        }
2002
 
 
2003
 
        var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp()
2004
 
        this.session.highlight(re);
2005
 
 
2006
 
        this._emit("changeSelection");
2007
 
    };
2008
 
 
2009
 
    this.$getSelectionHighLightRegexp = function() {
2010
 
        var session = this.session;
2011
 
 
2012
 
        var selection = this.getSelectionRange();
2013
 
        if (selection.isEmpty() || selection.isMultiLine())
2014
 
            return;
2015
 
 
2016
 
        var startOuter = selection.start.column - 1;
2017
 
        var endOuter = selection.end.column + 1;
2018
 
        var line = session.getLine(selection.start.row);
2019
 
        var lineCols = line.length;
2020
 
        var needle = line.substring(Math.max(startOuter, 0),
2021
 
                                    Math.min(endOuter, lineCols));
2022
 
        if ((startOuter >= 0 && /^[\w\d]/.test(needle)) ||
2023
 
            (endOuter <= lineCols && /[\w\d]$/.test(needle)))
2024
 
            return;
2025
 
 
2026
 
        needle = line.substring(selection.start.column, selection.end.column);
2027
 
        if (!/^[\w\d]+$/.test(needle))
2028
 
            return;
2029
 
 
2030
 
        var re = this.$search.$assembleRegExp({
2031
 
            wholeWord: true,
2032
 
            caseSensitive: true,
2033
 
            needle: needle
2034
 
        });
2035
 
 
2036
 
        return re;
2037
 
    };
2038
 
 
2039
 
 
2040
 
    this.onChangeFrontMarker = function() {
2041
 
        this.renderer.updateFrontMarkers();
2042
 
    };
2043
 
 
2044
 
    this.onChangeBackMarker = function() {
2045
 
        this.renderer.updateBackMarkers();
2046
 
    };
2047
 
 
2048
 
 
2049
 
    this.onChangeBreakpoint = function() {
2050
 
        this.renderer.updateBreakpoints();
2051
 
    };
2052
 
 
2053
 
    this.onChangeAnnotation = function() {
2054
 
        this.renderer.setAnnotations(this.session.getAnnotations());
2055
 
    };
2056
 
 
2057
 
 
2058
 
    this.onChangeMode = function(e) {
2059
 
        this.renderer.updateText();
2060
 
        this._emit("changeMode", e);
2061
 
    };
2062
 
 
2063
 
 
2064
 
    this.onChangeWrapLimit = function() {
2065
 
        this.renderer.updateFull();
2066
 
    };
2067
 
 
2068
 
    this.onChangeWrapMode = function() {
2069
 
        this.renderer.onResize(true);
2070
 
    };
2071
 
 
2072
 
 
2073
 
    this.onChangeFold = function() {
2074
 
        this.$updateHighlightActiveLine();
2075
 
        this.renderer.updateFull();
2076
 
    };
2077
 
 
2078
 
    this.getCopyText = function() {
2079
 
        var text = "";
2080
 
        if (!this.selection.isEmpty())
2081
 
            text = this.session.getTextRange(this.getSelectionRange());
2082
 
 
2083
 
        this._emit("copy", text);
2084
 
        return text;
2085
 
    };
2086
 
    this.onCopy = function() {
2087
 
        this.commands.exec("copy", this);
2088
 
    };
2089
 
    this.onCut = function() {
2090
 
        this.commands.exec("cut", this);
2091
 
    };
2092
 
    this.onPaste = function(text) {
2093
 
        if (this.$readOnly)
2094
 
            return;
2095
 
        this._emit("paste", text);
2096
 
        this.insert(text);
2097
 
    };
2098
 
 
2099
 
 
2100
 
    this.execCommand = function(command, args) {
2101
 
        this.commands.exec(command, this, args);
2102
 
    };
2103
 
    this.insert = function(text) {
2104
 
        var session = this.session;
2105
 
        var mode = session.getMode();
2106
 
        var cursor = this.getCursorPosition();
2107
 
 
2108
 
        if (this.getBehavioursEnabled()) {
2109
 
            var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text);
2110
 
            if (transform)
2111
 
                text = transform.text;
2112
 
        }
2113
 
 
2114
 
        text = text.replace("\t", this.session.getTabString());
2115
 
        if (!this.selection.isEmpty()) {
2116
 
            cursor = this.session.remove(this.getSelectionRange());
2117
 
            this.clearSelection();
2118
 
        }
2119
 
        else if (this.session.getOverwrite()) {
2120
 
            var range = new Range.fromPoints(cursor, cursor);
2121
 
            range.end.column += text.length;
2122
 
            this.session.remove(range);
2123
 
        }
2124
 
 
2125
 
        this.clearSelection();
2126
 
 
2127
 
        var start = cursor.column;
2128
 
        var lineState = session.getState(cursor.row);
2129
 
        var line = session.getLine(cursor.row);
2130
 
        var shouldOutdent = mode.checkOutdent(lineState, line, text);
2131
 
        var end = session.insert(cursor, text);
2132
 
 
2133
 
        if (transform && transform.selection) {
2134
 
            if (transform.selection.length == 2) { // Transform relative to the current column
2135
 
                this.selection.setSelectionRange(
2136
 
                    new Range(cursor.row, start + transform.selection[0],
2137
 
                              cursor.row, start + transform.selection[1]));
2138
 
            } else { // Transform relative to the current row.
2139
 
                this.selection.setSelectionRange(
2140
 
                    new Range(cursor.row + transform.selection[0],
2141
 
                              transform.selection[1],
2142
 
                              cursor.row + transform.selection[2],
2143
 
                              transform.selection[3]));
2144
 
            }
2145
 
        }
2146
 
        if (session.getDocument().isNewLine(text)) {
2147
 
            var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString());
2148
 
 
2149
 
            this.moveCursorTo(cursor.row+1, 0);
2150
 
 
2151
 
            var size = session.getTabSize();
2152
 
            var minIndent = Number.MAX_VALUE;
2153
 
 
2154
 
            for (var row = cursor.row + 1; row <= end.row; ++row) {
2155
 
                var indent = 0;
2156
 
 
2157
 
                line = session.getLine(row);
2158
 
                for (var i = 0; i < line.length; ++i)
2159
 
                    if (line.charAt(i) == '\t')
2160
 
                        indent += size;
2161
 
                    else if (line.charAt(i) == ' ')
2162
 
                        indent += 1;
2163
 
                    else
2164
 
                        break;
2165
 
                if (/[^\s]/.test(line))
2166
 
                    minIndent = Math.min(indent, minIndent);
2167
 
            }
2168
 
 
2169
 
            for (var row = cursor.row + 1; row <= end.row; ++row) {
2170
 
                var outdent = minIndent;
2171
 
 
2172
 
                line = session.getLine(row);
2173
 
                for (var i = 0; i < line.length && outdent > 0; ++i)
2174
 
                    if (line.charAt(i) == '\t')
2175
 
                        outdent -= size;
2176
 
                    else if (line.charAt(i) == ' ')
2177
 
                        outdent -= 1;
2178
 
                session.remove(new Range(row, 0, row, i));
2179
 
            }
2180
 
            session.indentRows(cursor.row + 1, end.row, lineIndent);
2181
 
        }
2182
 
        if (shouldOutdent)
2183
 
            mode.autoOutdent(lineState, session, cursor.row);
2184
 
    };
2185
 
 
2186
 
    this.onTextInput = function(text) {
2187
 
        this.keyBinding.onTextInput(text);
2188
 
    };
2189
 
 
2190
 
    this.onCommandKey = function(e, hashId, keyCode) {
2191
 
        this.keyBinding.onCommandKey(e, hashId, keyCode);
2192
 
    };
2193
 
    this.setOverwrite = function(overwrite) {
2194
 
        this.session.setOverwrite(overwrite);
2195
 
    };
2196
 
    this.getOverwrite = function() {
2197
 
        return this.session.getOverwrite();
2198
 
    };
2199
 
    this.toggleOverwrite = function() {
2200
 
        this.session.toggleOverwrite();
2201
 
    };
2202
 
    this.setScrollSpeed = function(speed) {
2203
 
        this.setOption("scrollSpeed", speed);
2204
 
    };
2205
 
    this.getScrollSpeed = function() {
2206
 
        return this.getOption("scrollSpeed");
2207
 
    };
2208
 
    this.setDragDelay = function(dragDelay) {
2209
 
        this.setOption("dragDelay", dragDelay);
2210
 
    };
2211
 
    this.getDragDelay = function() {
2212
 
        return this.getOption("dragDelay");
2213
 
    };
2214
 
    this.setSelectionStyle = function(val) {
2215
 
        this.setOption("selectionStyle", val);
2216
 
    };
2217
 
    this.getSelectionStyle = function() {
2218
 
        return this.getOption("selectionStyle");
2219
 
    };
2220
 
    this.setHighlightActiveLine = function(shouldHighlight) {
2221
 
        this.setOption("highlightActiveLine", shouldHighlight);
2222
 
    };
2223
 
    this.getHighlightActiveLine = function() {
2224
 
        return this.getOption("highlightActiveLine");
2225
 
    };
2226
 
    this.setHighlightGutterLine = function(shouldHighlight) {
2227
 
        this.setOption("highlightGutterLine", shouldHighlight);
2228
 
    };
2229
 
 
2230
 
    this.getHighlightGutterLine = function() {
2231
 
        return this.getOption("highlightGutterLine");
2232
 
    };
2233
 
    this.setHighlightSelectedWord = function(shouldHighlight) {
2234
 
        this.setOption("highlightSelectedWord", shouldHighlight);
2235
 
    };
2236
 
    this.getHighlightSelectedWord = function() {
2237
 
        return this.$highlightSelectedWord;
2238
 
    };
2239
 
 
2240
 
    this.setAnimatedScroll = function(shouldAnimate){
2241
 
        this.renderer.setAnimatedScroll(shouldAnimate);
2242
 
    };
2243
 
 
2244
 
    this.getAnimatedScroll = function(){
2245
 
        return this.renderer.getAnimatedScroll();
2246
 
    };
2247
 
    this.setShowInvisibles = function(showInvisibles) {
2248
 
        this.renderer.setShowInvisibles(showInvisibles);
2249
 
    };
2250
 
    this.getShowInvisibles = function() {
2251
 
        return this.renderer.getShowInvisibles();
2252
 
    };
2253
 
 
2254
 
    this.setDisplayIndentGuides = function(display) {
2255
 
        this.renderer.setDisplayIndentGuides(display);
2256
 
    };
2257
 
 
2258
 
    this.getDisplayIndentGuides = function() {
2259
 
        return this.renderer.getDisplayIndentGuides();
2260
 
    };
2261
 
    this.setShowPrintMargin = function(showPrintMargin) {
2262
 
        this.renderer.setShowPrintMargin(showPrintMargin);
2263
 
    };
2264
 
    this.getShowPrintMargin = function() {
2265
 
        return this.renderer.getShowPrintMargin();
2266
 
    };
2267
 
    this.setPrintMarginColumn = function(showPrintMargin) {
2268
 
        this.renderer.setPrintMarginColumn(showPrintMargin);
2269
 
    };
2270
 
    this.getPrintMarginColumn = function() {
2271
 
        return this.renderer.getPrintMarginColumn();
2272
 
    };
2273
 
    this.setReadOnly = function(readOnly) {
2274
 
        this.setOption("readOnly", readOnly);
2275
 
    };
2276
 
    this.getReadOnly = function() {
2277
 
        return this.getOption("readOnly");
2278
 
    };
2279
 
    this.setBehavioursEnabled = function (enabled) {
2280
 
        this.setOption("behavioursEnabled", enabled);
2281
 
    };
2282
 
    this.getBehavioursEnabled = function () {
2283
 
        return this.getOption("behavioursEnabled");
2284
 
    };
2285
 
    this.setWrapBehavioursEnabled = function (enabled) {
2286
 
        this.setOption("wrapBehavioursEnabled", enabled);
2287
 
    };
2288
 
    this.getWrapBehavioursEnabled = function () {
2289
 
        return this.getOption("wrapBehavioursEnabled");
2290
 
    };
2291
 
    this.setShowFoldWidgets = function(show) {
2292
 
        this.setOption("showFoldWidgets", show);
2293
 
 
2294
 
    };
2295
 
    this.getShowFoldWidgets = function() {
2296
 
        return this.getOption("showFoldWidgets");
2297
 
    };
2298
 
 
2299
 
    this.setFadeFoldWidgets = function(fade) {
2300
 
        this.setOption("fadeFoldWidgets", fade);
2301
 
    };
2302
 
 
2303
 
    this.getFadeFoldWidgets = function() {
2304
 
        return this.getOption("fadeFoldWidgets");
2305
 
    };
2306
 
    this.remove = function(dir) {
2307
 
        if (this.selection.isEmpty()){
2308
 
            if (dir == "left")
2309
 
                this.selection.selectLeft();
2310
 
            else
2311
 
                this.selection.selectRight();
2312
 
        }
2313
 
 
2314
 
        var range = this.getSelectionRange();
2315
 
        if (this.getBehavioursEnabled()) {
2316
 
            var session = this.session;
2317
 
            var state = session.getState(range.start.row);
2318
 
            var new_range = session.getMode().transformAction(state, 'deletion', this, session, range);
2319
 
            if (new_range)
2320
 
                range = new_range;
2321
 
        }
2322
 
 
2323
 
        this.session.remove(range);
2324
 
        this.clearSelection();
2325
 
    };
2326
 
    this.removeWordRight = function() {
2327
 
        if (this.selection.isEmpty())
2328
 
            this.selection.selectWordRight();
2329
 
 
2330
 
        this.session.remove(this.getSelectionRange());
2331
 
        this.clearSelection();
2332
 
    };
2333
 
    this.removeWordLeft = function() {
2334
 
        if (this.selection.isEmpty())
2335
 
            this.selection.selectWordLeft();
2336
 
 
2337
 
        this.session.remove(this.getSelectionRange());
2338
 
        this.clearSelection();
2339
 
    };
2340
 
    this.removeToLineStart = function() {
2341
 
        if (this.selection.isEmpty())
2342
 
            this.selection.selectLineStart();
2343
 
 
2344
 
        this.session.remove(this.getSelectionRange());
2345
 
        this.clearSelection();
2346
 
    };
2347
 
    this.removeToLineEnd = function() {
2348
 
        if (this.selection.isEmpty())
2349
 
            this.selection.selectLineEnd();
2350
 
 
2351
 
        var range = this.getSelectionRange();
2352
 
        if (range.start.column == range.end.column && range.start.row == range.end.row) {
2353
 
            range.end.column = 0;
2354
 
            range.end.row++;
2355
 
        }
2356
 
 
2357
 
        this.session.remove(range);
2358
 
        this.clearSelection();
2359
 
    };
2360
 
    this.splitLine = function() {
2361
 
        if (!this.selection.isEmpty()) {
2362
 
            this.session.remove(this.getSelectionRange());
2363
 
            this.clearSelection();
2364
 
        }
2365
 
 
2366
 
        var cursor = this.getCursorPosition();
2367
 
        this.insert("\n");
2368
 
        this.moveCursorToPosition(cursor);
2369
 
    };
2370
 
    this.transposeLetters = function() {
2371
 
        if (!this.selection.isEmpty()) {
2372
 
            return;
2373
 
        }
2374
 
 
2375
 
        var cursor = this.getCursorPosition();
2376
 
        var column = cursor.column;
2377
 
        if (column === 0)
2378
 
            return;
2379
 
 
2380
 
        var line = this.session.getLine(cursor.row);
2381
 
        var swap, range;
2382
 
        if (column < line.length) {
2383
 
            swap = line.charAt(column) + line.charAt(column-1);
2384
 
            range = new Range(cursor.row, column-1, cursor.row, column+1);
2385
 
        }
2386
 
        else {
2387
 
            swap = line.charAt(column-1) + line.charAt(column-2);
2388
 
            range = new Range(cursor.row, column-2, cursor.row, column);
2389
 
        }
2390
 
        this.session.replace(range, swap);
2391
 
    };
2392
 
    this.toLowerCase = function() {
2393
 
        var originalRange = this.getSelectionRange();
2394
 
        if (this.selection.isEmpty()) {
2395
 
            this.selection.selectWord();
2396
 
        }
2397
 
 
2398
 
        var range = this.getSelectionRange();
2399
 
        var text = this.session.getTextRange(range);
2400
 
        this.session.replace(range, text.toLowerCase());
2401
 
        this.selection.setSelectionRange(originalRange);
2402
 
    };
2403
 
    this.toUpperCase = function() {
2404
 
        var originalRange = this.getSelectionRange();
2405
 
        if (this.selection.isEmpty()) {
2406
 
            this.selection.selectWord();
2407
 
        }
2408
 
 
2409
 
        var range = this.getSelectionRange();
2410
 
        var text = this.session.getTextRange(range);
2411
 
        this.session.replace(range, text.toUpperCase());
2412
 
        this.selection.setSelectionRange(originalRange);
2413
 
    };
2414
 
    this.indent = function() {
2415
 
        var session = this.session;
2416
 
        var range = this.getSelectionRange();
2417
 
 
2418
 
        if (range.start.row < range.end.row || range.start.column < range.end.column) {
2419
 
            var rows = this.$getSelectedRows();
2420
 
            session.indentRows(rows.first, rows.last, "\t");
2421
 
        } else {
2422
 
            var indentString;
2423
 
 
2424
 
            if (this.session.getUseSoftTabs()) {
2425
 
                var size        = session.getTabSize(),
2426
 
                    position    = this.getCursorPosition(),
2427
 
                    column      = session.documentToScreenColumn(position.row, position.column),
2428
 
                    count       = (size - column % size);
2429
 
 
2430
 
                indentString = lang.stringRepeat(" ", count);
2431
 
            } else
2432
 
                indentString = "\t";
2433
 
            return this.insert(indentString);
2434
 
        }
2435
 
    };
2436
 
    this.blockIndent = function() {
2437
 
        var rows = this.$getSelectedRows();
2438
 
        this.session.indentRows(rows.first, rows.last, "\t");
2439
 
    };
2440
 
    this.blockOutdent = function() {
2441
 
        var selection = this.session.getSelection();
2442
 
        this.session.outdentRows(selection.getRange());
2443
 
    };
2444
 
    this.sortLines = function() {
2445
 
        var rows = this.$getSelectedRows();
2446
 
        var session = this.session;
2447
 
 
2448
 
        var lines = [];
2449
 
        for (i = rows.first; i <= rows.last; i++)
2450
 
            lines.push(session.getLine(i));
2451
 
 
2452
 
        lines.sort(function(a, b) {
2453
 
            if (a.toLowerCase() < b.toLowerCase()) return -1;
2454
 
            if (a.toLowerCase() > b.toLowerCase()) return 1;
2455
 
            return 0;
2456
 
        });
2457
 
 
2458
 
        var deleteRange = new Range(0, 0, 0, 0);
2459
 
        for (var i = rows.first; i <= rows.last; i++) {
2460
 
            var line = session.getLine(i);
2461
 
            deleteRange.start.row = i;
2462
 
            deleteRange.end.row = i;
2463
 
            deleteRange.end.column = line.length;
2464
 
            session.replace(deleteRange, lines[i-rows.first]);
2465
 
        }
2466
 
    };
2467
 
    this.toggleCommentLines = function() {
2468
 
        var state = this.session.getState(this.getCursorPosition().row);
2469
 
        var rows = this.$getSelectedRows();
2470
 
        this.session.getMode().toggleCommentLines(state, this.session, rows.first, rows.last);
2471
 
    };
2472
 
    this.getNumberAt = function( row, column ) {
2473
 
        var _numberRx = /[\-]?[0-9]+(?:\.[0-9]+)?/g
2474
 
        _numberRx.lastIndex = 0
2475
 
 
2476
 
        var s = this.session.getLine(row)
2477
 
        while(_numberRx.lastIndex < column - 1 ){
2478
 
            var m = _numberRx.exec(s)
2479
 
            if(m.index <= column && m.index+m[0].length >= column){
2480
 
                var number = {
2481
 
                    value: m[0],
2482
 
                    start: m.index,
2483
 
                    end: m.index+m[0].length
2484
 
 
2485
 
                }
2486
 
                return number
2487
 
            }
2488
 
        }
2489
 
        return null;
2490
 
    };
2491
 
    this.modifyNumber = function(amount) {
2492
 
        var row = this.selection.getCursor().row;
2493
 
        var column = this.selection.getCursor().column;
2494
 
        var charRange = new Range(row, column-1, row, column);
2495
 
 
2496
 
        var c = this.session.getTextRange(charRange);
2497
 
        if (!isNaN(parseFloat(c)) && isFinite(c)) {
2498
 
            var nr = this.getNumberAt(row, column);
2499
 
            if (nr) {
2500
 
                var fp = nr.value.indexOf(".") >= 0 ? nr.start + nr.value.indexOf(".") + 1 : nr.end;
2501
 
                var decimals = nr.start + nr.value.length - fp;
2502
 
 
2503
 
                var t = parseFloat(nr.value);
2504
 
                t *= Math.pow(10, decimals);
2505
 
 
2506
 
 
2507
 
                if(fp !== nr.end && column < fp){
2508
 
                    amount *= Math.pow(10, nr.end - column - 1);
2509
 
                } else {
2510
 
                    amount *= Math.pow(10, nr.end - column);
2511
 
                }
2512
 
 
2513
 
                t += amount;
2514
 
                t /= Math.pow(10, decimals);
2515
 
                var nnr = t.toFixed(decimals);
2516
 
                var replaceRange = new Range(row, nr.start, row, nr.end);
2517
 
                this.session.replace(replaceRange, nnr);
2518
 
                this.moveCursorTo(row, Math.max(nr.start +1, column + nnr.length - nr.value.length));
2519
 
 
2520
 
            }
2521
 
        }
2522
 
    };
2523
 
    this.removeLines = function() {
2524
 
        var rows = this.$getSelectedRows();
2525
 
        var range;
2526
 
        if (rows.first === 0 || rows.last+1 < this.session.getLength())
2527
 
            range = new Range(rows.first, 0, rows.last+1, 0);
2528
 
        else
2529
 
            range = new Range(
2530
 
                rows.first-1, this.session.getLine(rows.first-1).length,
2531
 
                rows.last, this.session.getLine(rows.last).length
2532
 
            );
2533
 
        this.session.remove(range);
2534
 
        this.clearSelection();
2535
 
    };
2536
 
 
2537
 
    this.duplicateSelection = function() {
2538
 
        var sel = this.selection;
2539
 
        var doc = this.session;
2540
 
        var range = sel.getRange();
2541
 
        if (range.isEmpty()) {
2542
 
            var row = range.start.row;
2543
 
            doc.duplicateLines(row, row);
2544
 
        } else {
2545
 
            var point = reverse ? range.start : range.end;
2546
 
            var endPoint = doc.insert(point, doc.getTextRange(range), false);
2547
 
            range.start = point;
2548
 
            range.end = endPoint;
2549
 
 
2550
 
            sel.setSelectionRange(range, reverse)
2551
 
        }
2552
 
    };
2553
 
    this.moveLinesDown = function() {
2554
 
        this.$moveLines(function(firstRow, lastRow) {
2555
 
            return this.session.moveLinesDown(firstRow, lastRow);
2556
 
        });
2557
 
    };
2558
 
    this.moveLinesUp = function() {
2559
 
        this.$moveLines(function(firstRow, lastRow) {
2560
 
            return this.session.moveLinesUp(firstRow, lastRow);
2561
 
        });
2562
 
    };
2563
 
    this.moveText = function(range, toPosition) {
2564
 
        return this.session.moveText(range, toPosition);
2565
 
    };
2566
 
    this.copyLinesUp = function() {
2567
 
        this.$moveLines(function(firstRow, lastRow) {
2568
 
            this.session.duplicateLines(firstRow, lastRow);
2569
 
            return 0;
2570
 
        });
2571
 
    };
2572
 
    this.copyLinesDown = function() {
2573
 
        this.$moveLines(function(firstRow, lastRow) {
2574
 
            return this.session.duplicateLines(firstRow, lastRow);
2575
 
        });
2576
 
    };
2577
 
    this.$moveLines = function(mover) {
2578
 
        var selection = this.selection;
2579
 
        if (!selection.inMultiSelectMode || this.inVirtualSelectionMode) {
2580
 
            var range = selection.toOrientedRange();
2581
 
            var rows = this.$getSelectedRows(range);
2582
 
            var linesMoved = mover.call(this, rows.first, rows.last);
2583
 
            range.moveBy(linesMoved, 0);
2584
 
            selection.fromOrientedRange(range);
2585
 
        } else {
2586
 
            var ranges = selection.rangeList.ranges;
2587
 
            selection.rangeList.detach(this.session);
2588
 
            
2589
 
            for (var i = ranges.length; i--; ) {
2590
 
                var rangeIndex = i;
2591
 
                var rows = ranges[i].collapseRows();
2592
 
                var last = rows.end.row;
2593
 
                var first = rows.start.row;
2594
 
                while (i--) {
2595
 
                    var rows = ranges[i].collapseRows();
2596
 
                    if (first - rows.end.row <= 1)
2597
 
                        first = rows.end.row;
2598
 
                    else
2599
 
                        break;
2600
 
                }
2601
 
                i++;
2602
 
                
2603
 
                var linesMoved = mover.call(this, first, last);
2604
 
                while (rangeIndex >= i) {
2605
 
                    ranges[rangeIndex].moveBy(linesMoved, 0);
2606
 
                    rangeIndex--;
2607
 
                }
2608
 
            }
2609
 
            selection.fromOrientedRange(selection.ranges[0]);
2610
 
            selection.rangeList.attach(this.session);
2611
 
        }
2612
 
    };
2613
 
    this.$getSelectedRows = function() {
2614
 
        var range = this.getSelectionRange().collapseRows();
2615
 
 
2616
 
        return {
2617
 
            first: range.start.row,
2618
 
            last: range.end.row
2619
 
        };
2620
 
    };
2621
 
 
2622
 
    this.onCompositionStart = function(text) {
2623
 
        this.renderer.showComposition(this.getCursorPosition());
2624
 
    };
2625
 
 
2626
 
    this.onCompositionUpdate = function(text) {
2627
 
        this.renderer.setCompositionText(text);
2628
 
    };
2629
 
 
2630
 
    this.onCompositionEnd = function() {
2631
 
        this.renderer.hideComposition();
2632
 
    };
2633
 
    this.getFirstVisibleRow = function() {
2634
 
        return this.renderer.getFirstVisibleRow();
2635
 
    };
2636
 
    this.getLastVisibleRow = function() {
2637
 
        return this.renderer.getLastVisibleRow();
2638
 
    };
2639
 
    this.isRowVisible = function(row) {
2640
 
        return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow());
2641
 
    };
2642
 
    this.isRowFullyVisible = function(row) {
2643
 
        return (row >= this.renderer.getFirstFullyVisibleRow() && row <= this.renderer.getLastFullyVisibleRow());
2644
 
    };
2645
 
    this.$getVisibleRowCount = function() {
2646
 
        return this.renderer.getScrollBottomRow() - this.renderer.getScrollTopRow() + 1;
2647
 
    };
2648
 
 
2649
 
    this.$moveByPage = function(dir, select) {
2650
 
        var renderer = this.renderer;
2651
 
        var config = this.renderer.layerConfig;
2652
 
        var rows = dir * Math.floor(config.height / config.lineHeight);
2653
 
 
2654
 
        this.$blockScrolling++;
2655
 
        if (select == true) {
2656
 
            this.selection.$moveSelection(function(){
2657
 
                this.moveCursorBy(rows, 0);
2658
 
            });
2659
 
        } else if (select == false) {
2660
 
            this.selection.moveCursorBy(rows, 0);
2661
 
            this.selection.clearSelection();
2662
 
        }
2663
 
        this.$blockScrolling--;
2664
 
 
2665
 
        var scrollTop = renderer.scrollTop;
2666
 
 
2667
 
        renderer.scrollBy(0, rows * config.lineHeight);
2668
 
        if (select != null)
2669
 
            renderer.scrollCursorIntoView(null, 0.5);
2670
 
 
2671
 
        renderer.animateScrolling(scrollTop);
2672
 
    };
2673
 
    this.selectPageDown = function() {
2674
 
        this.$moveByPage(1, true);
2675
 
    };
2676
 
    this.selectPageUp = function() {
2677
 
        this.$moveByPage(-1, true);
2678
 
    };
2679
 
    this.gotoPageDown = function() {
2680
 
       this.$moveByPage(1, false);
2681
 
    };
2682
 
    this.gotoPageUp = function() {
2683
 
        this.$moveByPage(-1, false);
2684
 
    };
2685
 
    this.scrollPageDown = function() {
2686
 
        this.$moveByPage(1);
2687
 
    };
2688
 
    this.scrollPageUp = function() {
2689
 
        this.$moveByPage(-1);
2690
 
    };
2691
 
    this.scrollToRow = function(row) {
2692
 
        this.renderer.scrollToRow(row);
2693
 
    };
2694
 
    this.scrollToLine = function(line, center, animate, callback) {
2695
 
        this.renderer.scrollToLine(line, center, animate, callback);
2696
 
    };
2697
 
    this.centerSelection = function() {
2698
 
        var range = this.getSelectionRange();
2699
 
        var pos = {
2700
 
            row: Math.floor(range.start.row + (range.end.row - range.start.row) / 2),
2701
 
            column: Math.floor(range.start.column + (range.end.column - range.start.column) / 2)
2702
 
        }
2703
 
        this.renderer.alignCursor(pos, 0.5);
2704
 
    };
2705
 
    this.getCursorPosition = function() {
2706
 
        return this.selection.getCursor();
2707
 
    };
2708
 
    this.getCursorPositionScreen = function() {
2709
 
        return this.session.documentToScreenPosition(this.getCursorPosition());
2710
 
    };
2711
 
    this.getSelectionRange = function() {
2712
 
        return this.selection.getRange();
2713
 
    };
2714
 
    this.selectAll = function() {
2715
 
        this.$blockScrolling += 1;
2716
 
        this.selection.selectAll();
2717
 
        this.$blockScrolling -= 1;
2718
 
    };
2719
 
    this.clearSelection = function() {
2720
 
        this.selection.clearSelection();
2721
 
    };
2722
 
    this.moveCursorTo = function(row, column) {
2723
 
        this.selection.moveCursorTo(row, column);
2724
 
    };
2725
 
    this.moveCursorToPosition = function(pos) {
2726
 
        this.selection.moveCursorToPosition(pos);
2727
 
    };
2728
 
    this.jumpToMatching = function(select) {
2729
 
        var cursor = this.getCursorPosition();
2730
 
 
2731
 
        var range = this.session.getBracketRange(cursor);
2732
 
        if (!range) {
2733
 
            range = this.find({
2734
 
                needle: /[{}()\[\]]/g,
2735
 
                preventScroll:true,
2736
 
                start: {row: cursor.row, column: cursor.column - 1}
2737
 
            });
2738
 
            if (!range)
2739
 
                return;
2740
 
            var pos = range.start;
2741
 
            if (pos.row == cursor.row && Math.abs(pos.column - cursor.column) < 2)
2742
 
                range = this.session.getBracketRange(pos);
2743
 
        }
2744
 
 
2745
 
        pos = range && range.cursor || pos;
2746
 
        if (pos) {
2747
 
            if (select) {
2748
 
                if (range && range.isEqual(this.getSelectionRange()))
2749
 
                    this.clearSelection();
2750
 
                else
2751
 
                    this.selection.selectTo(pos.row, pos.column);
2752
 
            } else {
2753
 
                this.clearSelection();
2754
 
                this.moveCursorTo(pos.row, pos.column);
2755
 
            }
2756
 
        }
2757
 
    };
2758
 
    this.gotoLine = function(lineNumber, column, animate) {
2759
 
        this.selection.clearSelection();
2760
 
        this.session.unfold({row: lineNumber - 1, column: column || 0});
2761
 
 
2762
 
        this.$blockScrolling += 1;
2763
 
        this.moveCursorTo(lineNumber - 1, column || 0);
2764
 
        this.$blockScrolling -= 1;
2765
 
 
2766
 
        if (!this.isRowFullyVisible(lineNumber - 1))
2767
 
            this.scrollToLine(lineNumber - 1, true, animate);
2768
 
    };
2769
 
    this.navigateTo = function(row, column) {
2770
 
        this.clearSelection();
2771
 
        this.moveCursorTo(row, column);
2772
 
    };
2773
 
    this.navigateUp = function(times) {
2774
 
        if (this.selection.isMultiLine() && !this.selection.isBackwards()) {
2775
 
            var selectionStart = this.selection.anchor.getPosition();
2776
 
            return this.moveCursorToPosition(selectionStart);
2777
 
        }
2778
 
        this.selection.clearSelection();
2779
 
        times = times || 1;
2780
 
        this.selection.moveCursorBy(-times, 0);
2781
 
    };
2782
 
    this.navigateDown = function(times) {
2783
 
        if (this.selection.isMultiLine() && this.selection.isBackwards()) {
2784
 
            var selectionEnd = this.selection.anchor.getPosition();
2785
 
            return this.moveCursorToPosition(selectionEnd);
2786
 
        }
2787
 
        this.selection.clearSelection();
2788
 
        times = times || 1;
2789
 
        this.selection.moveCursorBy(times, 0);
2790
 
    };
2791
 
    this.navigateLeft = function(times) {
2792
 
        if (!this.selection.isEmpty()) {
2793
 
            var selectionStart = this.getSelectionRange().start;
2794
 
            this.moveCursorToPosition(selectionStart);
2795
 
        }
2796
 
        else {
2797
 
            times = times || 1;
2798
 
            while (times--) {
2799
 
                this.selection.moveCursorLeft();
2800
 
            }
2801
 
        }
2802
 
        this.clearSelection();
2803
 
    };
2804
 
    this.navigateRight = function(times) {
2805
 
        if (!this.selection.isEmpty()) {
2806
 
            var selectionEnd = this.getSelectionRange().end;
2807
 
            this.moveCursorToPosition(selectionEnd);
2808
 
        }
2809
 
        else {
2810
 
            times = times || 1;
2811
 
            while (times--) {
2812
 
                this.selection.moveCursorRight();
2813
 
            }
2814
 
        }
2815
 
        this.clearSelection();
2816
 
    };
2817
 
    this.navigateLineStart = function() {
2818
 
        this.selection.moveCursorLineStart();
2819
 
        this.clearSelection();
2820
 
    };
2821
 
    this.navigateLineEnd = function() {
2822
 
        this.selection.moveCursorLineEnd();
2823
 
        this.clearSelection();
2824
 
    };
2825
 
    this.navigateFileEnd = function() {
2826
 
        var scrollTop = this.renderer.scrollTop;
2827
 
        this.selection.moveCursorFileEnd();
2828
 
        this.clearSelection();
2829
 
        this.renderer.animateScrolling(scrollTop);
2830
 
    };
2831
 
    this.navigateFileStart = function() {
2832
 
        var scrollTop = this.renderer.scrollTop;
2833
 
        this.selection.moveCursorFileStart();
2834
 
        this.clearSelection();
2835
 
        this.renderer.animateScrolling(scrollTop);
2836
 
    };
2837
 
    this.navigateWordRight = function() {
2838
 
        this.selection.moveCursorWordRight();
2839
 
        this.clearSelection();
2840
 
    };
2841
 
    this.navigateWordLeft = function() {
2842
 
        this.selection.moveCursorWordLeft();
2843
 
        this.clearSelection();
2844
 
    };
2845
 
    this.replace = function(replacement, options) {
2846
 
        if (options)
2847
 
            this.$search.set(options);
2848
 
 
2849
 
        var range = this.$search.find(this.session);
2850
 
        var replaced = 0;
2851
 
        if (!range)
2852
 
            return replaced;
2853
 
 
2854
 
        if (this.$tryReplace(range, replacement)) {
2855
 
            replaced = 1;
2856
 
        }
2857
 
        if (range !== null) {
2858
 
            this.selection.setSelectionRange(range);
2859
 
            this.renderer.scrollSelectionIntoView(range.start, range.end);
2860
 
        }
2861
 
 
2862
 
        return replaced;
2863
 
    };
2864
 
    this.replaceAll = function(replacement, options) {
2865
 
        if (options) {
2866
 
            this.$search.set(options);
2867
 
        }
2868
 
 
2869
 
        var ranges = this.$search.findAll(this.session);
2870
 
        var replaced = 0;
2871
 
        if (!ranges.length)
2872
 
            return replaced;
2873
 
 
2874
 
        this.$blockScrolling += 1;
2875
 
 
2876
 
        var selection = this.getSelectionRange();
2877
 
        this.clearSelection();
2878
 
        this.selection.moveCursorTo(0, 0);
2879
 
 
2880
 
        for (var i = ranges.length - 1; i >= 0; --i) {
2881
 
            if(this.$tryReplace(ranges[i], replacement)) {
2882
 
                replaced++;
2883
 
            }
2884
 
        }
2885
 
 
2886
 
        this.selection.setSelectionRange(selection);
2887
 
        this.$blockScrolling -= 1;
2888
 
 
2889
 
        return replaced;
2890
 
    };
2891
 
 
2892
 
    this.$tryReplace = function(range, replacement) {
2893
 
        var input = this.session.getTextRange(range);
2894
 
        replacement = this.$search.replace(input, replacement);
2895
 
        if (replacement !== null) {
2896
 
            range.end = this.session.replace(range, replacement);
2897
 
            return range;
2898
 
        } else {
2899
 
            return null;
2900
 
        }
2901
 
    };
2902
 
    this.getLastSearchOptions = function() {
2903
 
        return this.$search.getOptions();
2904
 
    };
2905
 
    this.find = function(needle, options, animate) {
2906
 
        if (!options)
2907
 
            options = {};
2908
 
 
2909
 
        if (typeof needle == "string" || needle instanceof RegExp)
2910
 
            options.needle = needle;
2911
 
        else if (typeof needle == "object")
2912
 
            oop.mixin(options, needle);
2913
 
 
2914
 
        var range = this.selection.getRange();
2915
 
        if (options.needle == null) {
2916
 
            needle = this.session.getTextRange(range)
2917
 
                || this.$search.$options.needle;
2918
 
            if (!needle) {
2919
 
                range = this.session.getWordRange(range.start.row, range.start.column);
2920
 
                needle = this.session.getTextRange(range);
2921
 
            }
2922
 
            this.$search.set({needle: needle});
2923
 
        }
2924
 
 
2925
 
        this.$search.set(options);
2926
 
        if (!options.start)
2927
 
            this.$search.set({start: range});
2928
 
 
2929
 
        var newRange = this.$search.find(this.session);
2930
 
        if (options.preventScroll)
2931
 
            return newRange;
2932
 
        if (newRange) {
2933
 
            this.revealRange(newRange, animate);
2934
 
            return newRange;
2935
 
        }
2936
 
        if (options.backwards)
2937
 
            range.start = range.end;
2938
 
        else
2939
 
            range.end = range.start;
2940
 
        this.selection.setRange(range);
2941
 
    };
2942
 
    this.findNext = function(options, animate) {
2943
 
        this.find({skipCurrent: true, backwards: false}, options, animate);
2944
 
    };
2945
 
    this.findPrevious = function(options, animate) {
2946
 
        this.find(options, {skipCurrent: true, backwards: true}, animate);
2947
 
    };
2948
 
 
2949
 
    this.revealRange = function(range, animate) {
2950
 
        this.$blockScrolling += 1;
2951
 
        this.session.unfold(range);
2952
 
        this.selection.setSelectionRange(range);
2953
 
        this.$blockScrolling -= 1;
2954
 
 
2955
 
        var scrollTop = this.renderer.scrollTop;
2956
 
        this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5);
2957
 
        if (animate != false)
2958
 
            this.renderer.animateScrolling(scrollTop);
2959
 
    };
2960
 
    this.undo = function() {
2961
 
        this.$blockScrolling++;
2962
 
        this.session.getUndoManager().undo();
2963
 
        this.$blockScrolling--;
2964
 
        this.renderer.scrollCursorIntoView(null, 0.5);
2965
 
    };
2966
 
    this.redo = function() {
2967
 
        this.$blockScrolling++;
2968
 
        this.session.getUndoManager().redo();
2969
 
        this.$blockScrolling--;
2970
 
        this.renderer.scrollCursorIntoView(null, 0.5);
2971
 
    };
2972
 
    this.destroy = function() {
2973
 
        this.renderer.destroy();
2974
 
        this._emit("destroy", this);
2975
 
    };
2976
 
    this.setAutoScrollEditorIntoView = function(enable) {
2977
 
        if (enable === true)
2978
 
            return;
2979
 
        var rect;
2980
 
        var self = this;
2981
 
        var shouldScroll = false;
2982
 
        if (!this.$scrollAnchor)
2983
 
            this.$scrollAnchor = document.createElement("div");
2984
 
        var scrollAnchor = this.$scrollAnchor;
2985
 
        scrollAnchor.style.cssText = "position:absolute";
2986
 
        this.container.insertBefore(scrollAnchor, this.container.firstChild);
2987
 
        var onChangeSelection = this.on("changeSelection", function() {
2988
 
            shouldScroll = true;
2989
 
        });
2990
 
        var onBeforeRender = this.renderer.on("beforeRender", function() {
2991
 
            if (shouldScroll)
2992
 
                rect = self.renderer.container.getBoundingClientRect();
2993
 
        });
2994
 
        var onAfterRender = this.renderer.on("afterRender", function() {
2995
 
            if (shouldScroll && rect && self.isFocused()) {
2996
 
                var renderer = self.renderer;
2997
 
                var pos = renderer.$cursorLayer.$pixelPos;
2998
 
                var config = renderer.layerConfig;
2999
 
                var top = pos.top - config.offset;
3000
 
                if (pos.top >= 0 && top + rect.top < 0) {
3001
 
                    shouldScroll = true;
3002
 
                } else if (pos.top < config.height &&
3003
 
                    pos.top + rect.top + config.lineHeight > window.innerHeight) {
3004
 
                    shouldScroll = false;
3005
 
                } else {
3006
 
                    shouldScroll = null;
3007
 
                }
3008
 
                if (shouldScroll != null) {
3009
 
                    scrollAnchor.style.top = top + "px";
3010
 
                    scrollAnchor.style.left = pos.left + "px";
3011
 
                    scrollAnchor.style.height = config.lineHeight + "px";
3012
 
                    scrollAnchor.scrollIntoView(shouldScroll);
3013
 
                }
3014
 
                shouldScroll = rect = null;
3015
 
            }
3016
 
        });
3017
 
        this.setAutoScrollEditorIntoView = function(enable) {
3018
 
            if (enable === false)
3019
 
                return;
3020
 
            delete this.setAutoScrollEditorIntoView;
3021
 
            this.removeEventListener("changeSelection", onChangeSelection);
3022
 
            this.renderer.removeEventListener("afterRender", onAfterRender);
3023
 
            this.renderer.removeEventListener("beforeRender", onBeforeRender);
3024
 
        };
3025
 
    };
3026
 
 
3027
 
}).call(Editor.prototype);
3028
 
 
3029
 
 
3030
 
 
3031
 
config.defineOptions(Editor.prototype, "editor", {
3032
 
    selectionStyle: {
3033
 
        set: function(style) {
3034
 
            this.onSelectionChange();
3035
 
            this._emit("changeSelectionStyle", {data: style});
3036
 
        },
3037
 
        initialValue: "line",
3038
 
    },
3039
 
    highlightActiveLine: {
3040
 
        set: function() {this.$updateHighlightActiveLine();},
3041
 
        initialValue: true
3042
 
    },
3043
 
    highlightSelectedWord: {
3044
 
        set: function(shouldHighlight) {this.$onSelectionChange();},
3045
 
        initialValue: true
3046
 
    },
3047
 
    readOnly: {
3048
 
        set: function(readOnly) {
3049
 
            this.textInput.setReadOnly(readOnly);
3050
 
            this.renderer.$cursorLayer.setBlinking(!readOnly);
3051
 
        },
3052
 
        initialValue: false
3053
 
    },
3054
 
    behavioursEnabled: {initialValue: true},
3055
 
    wrapBehavioursEnabled: {initialValue: true},
3056
 
 
3057
 
    highlightGutterLine: "renderer",
3058
 
    animatedScroll: "renderer",
3059
 
    showInvisibles: "renderer",
3060
 
    showPrintMargin: "renderer",
3061
 
    printMarginColumn: "renderer",
3062
 
    fadeFoldWidgets: "renderer",
3063
 
    showFoldWidgets: "renderer",
3064
 
    showGutter: "renderer",
3065
 
    displayIndentGuides: "renderer",
3066
 
 
3067
 
    scrollSpeed: "$mouseHandler",
3068
 
    dragDelay: "$mouseHandler",
3069
 
    focusTimout: "$mouseHandler",
3070
 
 
3071
 
    firstLineNumber: "session",
3072
 
    useWorker: "session",
3073
 
    useSoftTabs: "session",
3074
 
    tabSize: "session",
3075
 
    wrap: "session"
3076
 
});
3077
 
 
3078
 
exports.Editor = Editor;
3079
 
});
3080
 
 
3081
 
define('ace/lib/lang', ['require', 'exports', 'module' ], function(require, exports, module) {
3082
 
 
3083
 
 
3084
 
exports.stringReverse = function(string) {
3085
 
    return string.split("").reverse().join("");
3086
 
};
3087
 
 
3088
 
exports.stringRepeat = function (string, count) {
3089
 
    var result = '';
3090
 
    while (count > 0) {
3091
 
        if (count & 1)
3092
 
            result += string;
3093
 
 
3094
 
        if (count >>= 1)
3095
 
            string += string;
3096
 
    }
3097
 
    return result;
3098
 
};
3099
 
 
3100
 
var trimBeginRegexp = /^\s\s*/;
3101
 
var trimEndRegexp = /\s\s*$/;
3102
 
 
3103
 
exports.stringTrimLeft = function (string) {
3104
 
    return string.replace(trimBeginRegexp, '');
3105
 
};
3106
 
 
3107
 
exports.stringTrimRight = function (string) {
3108
 
    return string.replace(trimEndRegexp, '');
3109
 
};
3110
 
 
3111
 
exports.copyObject = function(obj) {
3112
 
    var copy = {};
3113
 
    for (var key in obj) {
3114
 
        copy[key] = obj[key];
3115
 
    }
3116
 
    return copy;
3117
 
};
3118
 
 
3119
 
exports.copyArray = function(array){
3120
 
    var copy = [];
3121
 
    for (var i=0, l=array.length; i<l; i++) {
3122
 
        if (array[i] && typeof array[i] == "object")
3123
 
            copy[i] = this.copyObject( array[i] );
3124
 
        else 
3125
 
            copy[i] = array[i];
3126
 
    }
3127
 
    return copy;
3128
 
};
3129
 
 
3130
 
exports.deepCopy = function (obj) {
3131
 
    if (typeof obj != "object") {
3132
 
        return obj;
3133
 
    }
3134
 
    
3135
 
    var copy = obj.constructor();
3136
 
    for (var key in obj) {
3137
 
        if (typeof obj[key] == "object") {
3138
 
            copy[key] = this.deepCopy(obj[key]);
3139
 
        } else {
3140
 
            copy[key] = obj[key];
3141
 
        }
3142
 
    }
3143
 
    return copy;
3144
 
};
3145
 
 
3146
 
exports.arrayToMap = function(arr) {
3147
 
    var map = {};
3148
 
    for (var i=0; i<arr.length; i++) {
3149
 
        map[arr[i]] = 1;
3150
 
    }
3151
 
    return map;
3152
 
 
3153
 
};
3154
 
 
3155
 
exports.createMap = function(props) {
3156
 
    var map = Object.create(null);
3157
 
    for (var i in props) {
3158
 
        map[i] = props[i];
3159
 
    }
3160
 
    return map;
3161
 
};
3162
 
exports.arrayRemove = function(array, value) {
3163
 
  for (var i = 0; i <= array.length; i++) {
3164
 
    if (value === array[i]) {
3165
 
      array.splice(i, 1);
3166
 
    }
3167
 
  }
3168
 
};
3169
 
 
3170
 
exports.escapeRegExp = function(str) {
3171
 
    return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
3172
 
};
3173
 
 
3174
 
exports.escapeHTML = function(str) {
3175
 
    return str.replace(/&/g, "&#38;").replace(/"/g, "&#34;").replace(/'/g, "&#39;").replace(/</g, "&#60;");
3176
 
};
3177
 
 
3178
 
exports.getMatchOffsets = function(string, regExp) {
3179
 
    var matches = [];
3180
 
 
3181
 
    string.replace(regExp, function(str) {
3182
 
        matches.push({
3183
 
            offset: arguments[arguments.length-2],
3184
 
            length: str.length
3185
 
        });
3186
 
    });
3187
 
 
3188
 
    return matches;
3189
 
};
3190
 
exports.deferredCall = function(fcn) {
3191
 
 
3192
 
    var timer = null;
3193
 
    var callback = function() {
3194
 
        timer = null;
3195
 
        fcn();
3196
 
    };
3197
 
 
3198
 
    var deferred = function(timeout) {
3199
 
        deferred.cancel();
3200
 
        timer = setTimeout(callback, timeout || 0);
3201
 
        return deferred;
3202
 
    };
3203
 
 
3204
 
    deferred.schedule = deferred;
3205
 
 
3206
 
    deferred.call = function() {
3207
 
        this.cancel();
3208
 
        fcn();
3209
 
        return deferred;
3210
 
    };
3211
 
 
3212
 
    deferred.cancel = function() {
3213
 
        clearTimeout(timer);
3214
 
        timer = null;
3215
 
        return deferred;
3216
 
    };
3217
 
 
3218
 
    return deferred;
3219
 
};
3220
 
 
3221
 
 
3222
 
exports.delayedCall = function(fcn, defaultTimeout) {
3223
 
    var timer = null;
3224
 
    var callback = function() {
3225
 
        timer = null;
3226
 
        fcn();
3227
 
    };
3228
 
 
3229
 
    var _self = function(timeout) {
3230
 
        timer && clearTimeout(timer);
3231
 
        timer = setTimeout(callback, timeout || defaultTimeout);
3232
 
    };
3233
 
 
3234
 
    _self.delay = _self;
3235
 
    _self.schedule = function(timeout) {
3236
 
        if (timer == null)
3237
 
            timer = setTimeout(callback, timeout || 0);
3238
 
    };
3239
 
 
3240
 
    _self.call = function() {
3241
 
        this.cancel();
3242
 
        fcn();
3243
 
    };
3244
 
 
3245
 
    _self.cancel = function() {
3246
 
        timer && clearTimeout(timer);
3247
 
        timer = null;
3248
 
    };
3249
 
 
3250
 
    _self.isPending = function() {
3251
 
        return timer;
3252
 
    };
3253
 
 
3254
 
    return _self;
3255
 
};
3256
 
});
3257
 
 
3258
 
define('ace/keyboard/textinput', ['require', 'exports', 'module' , 'ace/lib/event', 'ace/lib/useragent', 'ace/lib/dom', 'ace/lib/lang'], function(require, exports, module) {
3259
 
 
3260
 
 
3261
 
var event = require("../lib/event");
3262
 
var useragent = require("../lib/useragent");
3263
 
var dom = require("../lib/dom");
3264
 
var lang = require("../lib/lang");
3265
 
var BROKEN_SETDATA = useragent.isChrome < 18;
3266
 
 
3267
 
var TextInput = function(parentNode, host) {
3268
 
    var text = dom.createElement("textarea");
3269
 
    text.className = "ace_text-input";
3270
 
    if (useragent.isTouchPad)
3271
 
        text.setAttribute("x-palm-disable-auto-cap", true);
3272
 
 
3273
 
    text.wrap = "off";
3274
 
    text.autocorrect = "off";
3275
 
    text.autocapitalize = "off";
3276
 
    text.spellcheck = false;
3277
 
 
3278
 
    text.style.bottom = "2000em";
3279
 
    parentNode.insertBefore(text, parentNode.firstChild);
3280
 
 
3281
 
    var PLACEHOLDER = "\x01\x01";
3282
 
 
3283
 
    var cut = false;
3284
 
    var copied = false;
3285
 
    var pasted = false;
3286
 
    var inCompostion = false;
3287
 
    var tempStyle = '';
3288
 
    var isSelectionEmpty = true;
3289
 
    try { var isFocused = document.activeElement === text; } catch(e) {}
3290
 
    
3291
 
    event.addListener(text, "blur", function() {
3292
 
        host.onBlur();
3293
 
        isFocused = false;
3294
 
    });
3295
 
    event.addListener(text, "focus", function() {
3296
 
        isFocused = true;
3297
 
        host.onFocus();
3298
 
        resetSelection();
3299
 
    });
3300
 
    this.focus = function() { text.focus(); };
3301
 
    this.blur = function() { text.blur(); };
3302
 
    this.isFocused = function() {
3303
 
        return isFocused;
3304
 
    };
3305
 
    var syncSelection = lang.delayedCall(function() {
3306
 
        isFocused && resetSelection(isSelectionEmpty);
3307
 
    });
3308
 
    var syncValue = lang.delayedCall(function() {
3309
 
         if (!inCompostion) {
3310
 
            text.value = PLACEHOLDER;
3311
 
            isFocused && resetSelection();
3312
 
         }
3313
 
    });
3314
 
 
3315
 
    function resetSelection(isEmpty) {
3316
 
        if (inCompostion)
3317
 
            return;
3318
 
        if (inputHandler) {
3319
 
            selectionStart = 0;
3320
 
            selectionEnd = isEmpty ? 0 : text.value.length - 1;
3321
 
        } else {
3322
 
            var selectionStart = isEmpty ? 2 : 1;
3323
 
            var selectionEnd = 2;
3324
 
        }
3325
 
        try {
3326
 
            text.setSelectionRange(selectionStart, selectionEnd);
3327
 
        } catch(e){}
3328
 
    }
3329
 
 
3330
 
    function resetValue() {
3331
 
        if (inCompostion)
3332
 
            return;
3333
 
        text.value = PLACEHOLDER;
3334
 
        if (useragent.isWebKit)
3335
 
            syncValue.schedule();
3336
 
    }
3337
 
 
3338
 
    useragent.isWebKit || host.addEventListener('changeSelection', function() {
3339
 
        if (host.selection.isEmpty() != isSelectionEmpty) {
3340
 
            isSelectionEmpty = !isSelectionEmpty;
3341
 
            syncSelection.schedule();
3342
 
        }
3343
 
    });
3344
 
 
3345
 
    resetValue();
3346
 
    if (isFocused)
3347
 
        host.onFocus();
3348
 
 
3349
 
 
3350
 
    var isAllSelected = function(text) {
3351
 
        return text.selectionStart === 0 && text.selectionEnd === text.value.length;
3352
 
    };
3353
 
    if (!text.setSelectionRange && text.createTextRange) {
3354
 
        text.setSelectionRange = function(selectionStart, selectionEnd) {
3355
 
            var range = this.createTextRange();
3356
 
            range.collapse(true);
3357
 
            range.moveStart('character', selectionStart);
3358
 
            range.moveEnd('character', selectionEnd);
3359
 
            range.select();
3360
 
        };
3361
 
        isAllSelected = function(text) {
3362
 
            try {
3363
 
                var range = text.ownerDocument.selection.createRange();
3364
 
            }catch(e) {}
3365
 
            if (!range || range.parentElement() != text) return false;
3366
 
                return range.text == text.value;
3367
 
        }
3368
 
    }
3369
 
    if (useragent.isOldIE) {
3370
 
        var inPropertyChange = false;
3371
 
        var onPropertyChange = function(e){
3372
 
            if (inPropertyChange)
3373
 
                return;
3374
 
            var data = text.value;
3375
 
            if (inCompostion || !data || data == PLACEHOLDER)
3376
 
                return;
3377
 
            if (e && data == PLACEHOLDER[0])
3378
 
                return syncProperty.schedule();
3379
 
 
3380
 
            sendText(data);
3381
 
            inPropertyChange = true;
3382
 
            resetValue();
3383
 
            inPropertyChange = false;
3384
 
        };
3385
 
        var syncProperty = lang.delayedCall(onPropertyChange);
3386
 
        event.addListener(text, "propertychange", onPropertyChange);
3387
 
 
3388
 
        var keytable = { 13:1, 27:1 };
3389
 
        event.addListener(text, "keyup", function (e) {
3390
 
            if (inCompostion && (!text.value || keytable[e.keyCode]))
3391
 
                setTimeout(onCompositionEnd, 0);
3392
 
            if ((text.value.charCodeAt(0)||0) < 129) {
3393
 
                return;
3394
 
            }
3395
 
            inCompostion ? onCompositionUpdate() : onCompositionStart();
3396
 
        });
3397
 
    }
3398
 
 
3399
 
    var onSelect = function(e) {
3400
 
        if (cut) {
3401
 
            cut = false;
3402
 
        } else if (copied) {
3403
 
            copied = false;
3404
 
        } else if (isAllSelected(text)) {
3405
 
            host.selectAll();
3406
 
            resetSelection();
3407
 
        } else if (inputHandler) {
3408
 
            resetSelection(host.selection.isEmpty());
3409
 
        }
3410
 
    };
3411
 
 
3412
 
    var inputHandler = null;
3413
 
    this.setInputHandler = function(cb) {inputHandler = cb};
3414
 
    this.getInputHandler = function() {return inputHandler};
3415
 
    
3416
 
    var sendText = function(data) {
3417
 
        if (inputHandler) {
3418
 
            data = inputHandler(data);
3419
 
            inputHandler = null;
3420
 
        }
3421
 
        if (pasted) {
3422
 
            resetSelection();
3423
 
            if (data)
3424
 
                host.onPaste(data);
3425
 
            pasted = false;
3426
 
        } else if (data == PLACEHOLDER[0]) {
3427
 
            if (Date.now() - lastCompositionTime > 100)
3428
 
                host.execCommand("del", {source: "ace"});
3429
 
        } else {
3430
 
            if (data.substring(0, 2) == PLACEHOLDER)
3431
 
                data = data.substr(2);
3432
 
            else if (data[0] == PLACEHOLDER[0])
3433
 
                data = data.substr(1);
3434
 
            else if (data[data.length - 1] == PLACEHOLDER[0])
3435
 
                data = data.slice(0, -1);
3436
 
            if (data[data.length - 1] == PLACEHOLDER[0])
3437
 
                data = data.slice(0, -1);
3438
 
            
3439
 
            if (data)
3440
 
                host.onTextInput(data);
3441
 
        }
3442
 
    };
3443
 
    var onInput = function(e) {
3444
 
        if (inCompostion)
3445
 
            return;
3446
 
        var data = text.value;
3447
 
        sendText(data);
3448
 
        resetValue();
3449
 
    };
3450
 
 
3451
 
    var onCut = function(e) {
3452
 
        var data = host.getCopyText();
3453
 
        if (!data) {
3454
 
            event.preventDefault(e);
3455
 
            return;
3456
 
        }
3457
 
 
3458
 
        var clipboardData = e.clipboardData || window.clipboardData;
3459
 
 
3460
 
        if (clipboardData && !BROKEN_SETDATA) {
3461
 
            var supported = clipboardData.setData("Text", data);
3462
 
            if (supported) {
3463
 
                host.onCut();
3464
 
                event.preventDefault(e);
3465
 
            }
3466
 
        }
3467
 
 
3468
 
        if (!supported) {
3469
 
            cut = true;
3470
 
            text.value = data;
3471
 
            text.select();
3472
 
            setTimeout(function(){
3473
 
                cut = false;
3474
 
                resetValue();
3475
 
                resetSelection();
3476
 
                host.onCut();
3477
 
            });
3478
 
        }
3479
 
    };
3480
 
 
3481
 
    var onCopy = function(e) {
3482
 
        var data = host.getCopyText();
3483
 
        if (!data) {
3484
 
            event.preventDefault(e);
3485
 
            return;
3486
 
        }
3487
 
 
3488
 
        var clipboardData = e.clipboardData || window.clipboardData;
3489
 
        if (clipboardData && !BROKEN_SETDATA) {
3490
 
            var supported = clipboardData.setData("Text", data);
3491
 
            if (supported) {
3492
 
                host.onCopy();
3493
 
                event.preventDefault(e);
3494
 
            }
3495
 
        }
3496
 
        if (!supported) {
3497
 
            copied = true;
3498
 
            text.value = data;
3499
 
            text.select();
3500
 
            setTimeout(function(){
3501
 
                copied = false;
3502
 
                resetValue();
3503
 
                resetSelection();
3504
 
                host.onCopy();
3505
 
            });
3506
 
        }
3507
 
    };
3508
 
 
3509
 
    var onPaste = function(e) {
3510
 
        var clipboardData = e.clipboardData || window.clipboardData;
3511
 
 
3512
 
        if (clipboardData) {
3513
 
            var data = clipboardData.getData("Text");
3514
 
            if (data)
3515
 
                host.onPaste(data);
3516
 
            if (useragent.isIE)
3517
 
                setTimeout(resetSelection);
3518
 
            event.preventDefault(e);
3519
 
        }
3520
 
        else {
3521
 
            text.value = "";
3522
 
            pasted = true;
3523
 
        }
3524
 
    };
3525
 
 
3526
 
    event.addCommandKeyListener(text, host.onCommandKey.bind(host));
3527
 
 
3528
 
    event.addListener(text, "select", onSelect);
3529
 
 
3530
 
    event.addListener(text, "input", onInput);
3531
 
 
3532
 
    event.addListener(text, "cut", onCut);
3533
 
    event.addListener(text, "copy", onCopy);
3534
 
    event.addListener(text, "paste", onPaste);
3535
 
    if (!('oncut' in text) || !('oncopy' in text) || !('onpaste' in text)){
3536
 
        event.addListener(parentNode, "keydown", function(e) {
3537
 
            if ((useragent.isMac && !e.metaKey) || !e.ctrlKey)
3538
 
            return;
3539
 
 
3540
 
            switch (e.keyCode) {
3541
 
                case 67:
3542
 
                    onCopy(e);
3543
 
                    break;
3544
 
                case 86:
3545
 
                    onPaste(e);
3546
 
                    break;
3547
 
                case 88:
3548
 
                    onCut(e);
3549
 
                    break;
3550
 
            }
3551
 
        });
3552
 
    }
3553
 
    var onCompositionStart = function(e) {
3554
 
        inCompostion = true;
3555
 
        host.onCompositionStart();
3556
 
        setTimeout(onCompositionUpdate, 0);
3557
 
    };
3558
 
 
3559
 
    var onCompositionUpdate = function() {
3560
 
        if (!inCompostion) return;
3561
 
        host.onCompositionUpdate(text.value);
3562
 
    };
3563
 
    
3564
 
    var lastCompositionTime = -1;
3565
 
    var onCompositionEnd = function(e) {
3566
 
        inCompostion = false;
3567
 
        host.onCompositionEnd();
3568
 
        lastCompositionTime = Date.now();
3569
 
    };
3570
 
 
3571
 
    var syncComposition = lang.delayedCall(onCompositionUpdate, 50);
3572
 
 
3573
 
    event.addListener(text, "compositionstart", onCompositionStart);
3574
 
    event.addListener(text, useragent.isGecko ? "text" : "keyup", function(){syncComposition.schedule()});
3575
 
    event.addListener(text, "compositionend", onCompositionEnd);
3576
 
 
3577
 
    this.getElement = function() {
3578
 
        return text;
3579
 
    };
3580
 
 
3581
 
    this.setReadOnly = function(readOnly) {
3582
 
       text.readOnly = readOnly;
3583
 
    };
3584
 
 
3585
 
    this.onContextMenu = function(e) {
3586
 
        if (!tempStyle)
3587
 
            tempStyle = text.style.cssText;
3588
 
 
3589
 
        text.style.cssText = "z-index:100000;" + (useragent.isIE ? "opacity:0.1;" : "");
3590
 
 
3591
 
        resetSelection(host.selection.isEmpty());
3592
 
        host._emit("nativecontextmenu", {target: host});
3593
 
        var rect = host.container.getBoundingClientRect();
3594
 
        var style = dom.computedStyle(host.container);
3595
 
        var top = rect.top + (parseInt(style.borderTopWidth) || 0);
3596
 
        var left = rect.left + (parseInt(rect.borderLeftWidth) || 0);
3597
 
        var maxTop = rect.bottom - top - text.clientHeight;
3598
 
        var move = function(e) {
3599
 
            text.style.left = e.clientX - left - 2 + "px";
3600
 
            text.style.top = Math.min(e.clientY - top - 2, maxTop) + "px";
3601
 
        }; 
3602
 
        move(e);
3603
 
 
3604
 
        if (e.type != "mousedown")
3605
 
            return;
3606
 
 
3607
 
        if (host.renderer.$keepTextAreaAtCursor)
3608
 
            host.renderer.$keepTextAreaAtCursor = null;
3609
 
        if (useragent.isWin)
3610
 
            event.capture(host.container, move, onContextMenuClose);
3611
 
    };
3612
 
 
3613
 
    this.onContextMenuClose = onContextMenuClose;
3614
 
    function onContextMenuClose() {
3615
 
        setTimeout(function () {
3616
 
            if (tempStyle) {
3617
 
                text.style.cssText = tempStyle;
3618
 
                tempStyle = '';
3619
 
            }
3620
 
            if (host.renderer.$keepTextAreaAtCursor == null) {
3621
 
                host.renderer.$keepTextAreaAtCursor = true;
3622
 
                host.renderer.$moveTextAreaToCursor();
3623
 
            }
3624
 
        }, 0);
3625
 
    }
3626
 
    if (!useragent.isGecko) {
3627
 
        event.addListener(text, "contextmenu", function(e) {
3628
 
            host.textInput.onContextMenu(e);
3629
 
            onContextMenuClose();
3630
 
        });
3631
 
    }
3632
 
};
3633
 
 
3634
 
exports.TextInput = TextInput;
3635
 
});
3636
 
 
3637
 
define('ace/mouse/mouse_handler', ['require', 'exports', 'module' , 'ace/lib/event', 'ace/lib/useragent', 'ace/mouse/default_handlers', 'ace/mouse/default_gutter_handler', 'ace/mouse/mouse_event', 'ace/mouse/dragdrop', 'ace/config'], function(require, exports, module) {
3638
 
 
3639
 
 
3640
 
var event = require("../lib/event");
3641
 
var useragent = require("../lib/useragent");
3642
 
var DefaultHandlers = require("./default_handlers").DefaultHandlers;
3643
 
var DefaultGutterHandler = require("./default_gutter_handler").GutterHandler;
3644
 
var MouseEvent = require("./mouse_event").MouseEvent;
3645
 
var DragdropHandler = require("./dragdrop").DragdropHandler;
3646
 
var config = require("../config");
3647
 
 
3648
 
var MouseHandler = function(editor) {
3649
 
    this.editor = editor;
3650
 
 
3651
 
    new DefaultHandlers(this);
3652
 
    new DefaultGutterHandler(this);
3653
 
    new DragdropHandler(this);
3654
 
 
3655
 
    event.addListener(editor.container, "mousedown", function(e) {
3656
 
        editor.focus();
3657
 
        return event.preventDefault(e);
3658
 
    });
3659
 
 
3660
 
    var mouseTarget = editor.renderer.getMouseEventTarget();
3661
 
    event.addListener(mouseTarget, "click", this.onMouseEvent.bind(this, "click"));
3662
 
    event.addListener(mouseTarget, "mousemove", this.onMouseMove.bind(this, "mousemove"));
3663
 
    event.addMultiMouseDownListener(mouseTarget, [300, 300, 250], this, "onMouseEvent");
3664
 
    event.addMouseWheelListener(editor.container, this.onMouseWheel.bind(this, "mousewheel"));
3665
 
 
3666
 
    var gutterEl = editor.renderer.$gutter;
3667
 
    event.addListener(gutterEl, "mousedown", this.onMouseEvent.bind(this, "guttermousedown"));
3668
 
    event.addListener(gutterEl, "click", this.onMouseEvent.bind(this, "gutterclick"));
3669
 
    event.addListener(gutterEl, "dblclick", this.onMouseEvent.bind(this, "gutterdblclick"));
3670
 
    event.addListener(gutterEl, "mousemove", this.onMouseEvent.bind(this, "guttermousemove"));
3671
 
};
3672
 
 
3673
 
(function() {
3674
 
    this.onMouseEvent = function(name, e) {
3675
 
        this.editor._emit(name, new MouseEvent(e, this.editor));
3676
 
    };
3677
 
 
3678
 
    this.onMouseMove = function(name, e) {
3679
 
        var listeners = this.editor._eventRegistry && this.editor._eventRegistry.mousemove;
3680
 
        if (!listeners || !listeners.length)
3681
 
            return;
3682
 
 
3683
 
        this.editor._emit(name, new MouseEvent(e, this.editor));
3684
 
    };
3685
 
 
3686
 
    this.onMouseWheel = function(name, e) {
3687
 
        var mouseEvent = new MouseEvent(e, this.editor);
3688
 
        mouseEvent.speed = this.$scrollSpeed * 2;
3689
 
        mouseEvent.wheelX = e.wheelX;
3690
 
        mouseEvent.wheelY = e.wheelY;
3691
 
 
3692
 
        this.editor._emit(name, mouseEvent);
3693
 
    };
3694
 
 
3695
 
    this.setState = function(state) {
3696
 
        this.state = state;
3697
 
    };
3698
 
 
3699
 
    this.captureMouse = function(ev, state) {
3700
 
        if (state)
3701
 
            this.setState(state);
3702
 
 
3703
 
        this.x = ev.x;
3704
 
        this.y = ev.y;
3705
 
        
3706
 
        this.isMousePressed = true;
3707
 
        var renderer = this.editor.renderer;
3708
 
        if (renderer.$keepTextAreaAtCursor)
3709
 
            renderer.$keepTextAreaAtCursor = null;
3710
 
 
3711
 
        var self = this;
3712
 
        var onMouseMove = function(e) {
3713
 
            self.x = e.clientX;
3714
 
            self.y = e.clientY;
3715
 
        };
3716
 
 
3717
 
        var onCaptureEnd = function(e) {
3718
 
            clearInterval(timerId);
3719
 
            onCaptureInterval();
3720
 
            self[self.state + "End"] && self[self.state + "End"](e);
3721
 
            self.$clickSelection = null;
3722
 
            if (renderer.$keepTextAreaAtCursor == null) {
3723
 
                renderer.$keepTextAreaAtCursor = true;
3724
 
                renderer.$moveTextAreaToCursor();
3725
 
            }
3726
 
            self.isMousePressed = false;
3727
 
        };
3728
 
 
3729
 
        var onCaptureInterval = function() {
3730
 
            self[self.state] && self[self.state]();
3731
 
        };
3732
 
        
3733
 
        if (useragent.isOldIE && ev.domEvent.type == "dblclick") {
3734
 
            return setTimeout(function() {onCaptureEnd(ev.domEvent);});
3735
 
        }
3736
 
 
3737
 
        event.capture(this.editor.container, onMouseMove, onCaptureEnd);
3738
 
        var timerId = setInterval(onCaptureInterval, 20);
3739
 
    };
3740
 
}).call(MouseHandler.prototype);
3741
 
 
3742
 
config.defineOptions(MouseHandler.prototype, "mouseHandler", {
3743
 
    scrollSpeed: {initialValue: 1},
3744
 
    dragDelay: {initialValue: 150},
3745
 
    focusTimout: {initialValue: 0}
3746
 
});
3747
 
 
3748
 
 
3749
 
exports.MouseHandler = MouseHandler;
3750
 
});
3751
 
 
3752
 
define('ace/mouse/default_handlers', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/useragent'], function(require, exports, module) {
3753
 
 
3754
 
 
3755
 
var dom = require("../lib/dom");
3756
 
var useragent = require("../lib/useragent");
3757
 
 
3758
 
var DRAG_OFFSET = 0; // pixels
3759
 
 
3760
 
function DefaultHandlers(mouseHandler) {
3761
 
    mouseHandler.$clickSelection = null;
3762
 
 
3763
 
    var editor = mouseHandler.editor;
3764
 
    editor.setDefaultHandler("mousedown", this.onMouseDown.bind(mouseHandler));
3765
 
    editor.setDefaultHandler("dblclick", this.onDoubleClick.bind(mouseHandler));
3766
 
    editor.setDefaultHandler("tripleclick", this.onTripleClick.bind(mouseHandler));
3767
 
    editor.setDefaultHandler("quadclick", this.onQuadClick.bind(mouseHandler));
3768
 
    editor.setDefaultHandler("mousewheel", this.onMouseWheel.bind(mouseHandler));
3769
 
 
3770
 
    var exports = ["select", "startSelect", "drag", "dragEnd", "dragWait",
3771
 
        "dragWaitEnd", "startDrag", "focusWait"];
3772
 
 
3773
 
    exports.forEach(function(x) {
3774
 
        mouseHandler[x] = this[x];
3775
 
    }, this);
3776
 
 
3777
 
    mouseHandler.selectByLines = this.extendSelectionBy.bind(mouseHandler, "getLineRange");
3778
 
    mouseHandler.selectByWords = this.extendSelectionBy.bind(mouseHandler, "getWordRange");
3779
 
}
3780
 
 
3781
 
(function() {
3782
 
 
3783
 
    this.onMouseDown = function(ev) {
3784
 
        var inSelection = ev.inSelection();
3785
 
        var pos = ev.getDocumentPosition();
3786
 
        this.mousedownEvent = ev;
3787
 
        var editor = this.editor;
3788
 
 
3789
 
        var button = ev.getButton();
3790
 
        if (button !== 0) {
3791
 
            var selectionRange = editor.getSelectionRange();
3792
 
            var selectionEmpty = selectionRange.isEmpty();
3793
 
 
3794
 
            if (selectionEmpty) {
3795
 
                editor.moveCursorToPosition(pos);
3796
 
                editor.selection.clearSelection();
3797
 
            }
3798
 
            editor.textInput.onContextMenu(ev.domEvent);
3799
 
            return; // stopping event here breaks contextmenu on ff mac
3800
 
        }
3801
 
        if (inSelection && !editor.isFocused()) {
3802
 
            editor.focus();
3803
 
            if (this.$focusTimout && !this.$clickSelection && !editor.inMultiSelectMode) {
3804
 
                this.setState("focusWait");
3805
 
                this.captureMouse(ev);
3806
 
                return ev.preventDefault();
3807
 
            }
3808
 
        }
3809
 
 
3810
 
        if (!inSelection || this.$clickSelection || ev.getShiftKey() || editor.inMultiSelectMode) {
3811
 
            this.startSelect(pos);
3812
 
        } else if (inSelection) {
3813
 
            this.mousedownEvent.time = (new Date()).getTime();
3814
 
            this.setState("dragWait");
3815
 
        }
3816
 
 
3817
 
        this.captureMouse(ev);
3818
 
        return ev.preventDefault();
3819
 
    };
3820
 
 
3821
 
    this.startSelect = function(pos) {
3822
 
        pos = pos || this.editor.renderer.screenToTextCoordinates(this.x, this.y);
3823
 
        if (this.mousedownEvent.getShiftKey()) {
3824
 
            this.editor.selection.selectToPosition(pos);
3825
 
        }
3826
 
        else if (!this.$clickSelection) {
3827
 
            this.editor.moveCursorToPosition(pos);
3828
 
            this.editor.selection.clearSelection();
3829
 
        }
3830
 
        this.setState("select");
3831
 
    };
3832
 
 
3833
 
    this.select = function() {
3834
 
        var anchor, editor = this.editor;
3835
 
        var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);
3836
 
 
3837
 
        if (this.$clickSelection) {
3838
 
            var cmp = this.$clickSelection.comparePoint(cursor);
3839
 
 
3840
 
            if (cmp == -1) {
3841
 
                anchor = this.$clickSelection.end;
3842
 
            } else if (cmp == 1) {
3843
 
                anchor = this.$clickSelection.start;
3844
 
            } else {
3845
 
                var orientedRange = calcRangeOrientation(this.$clickSelection, cursor);
3846
 
                cursor = orientedRange.cursor;
3847
 
                anchor = orientedRange.anchor;
3848
 
            }
3849
 
            editor.selection.setSelectionAnchor(anchor.row, anchor.column);
3850
 
        }
3851
 
        editor.selection.selectToPosition(cursor);
3852
 
 
3853
 
        editor.renderer.scrollCursorIntoView();
3854
 
    };
3855
 
 
3856
 
    this.extendSelectionBy = function(unitName) {
3857
 
        var anchor, editor = this.editor;
3858
 
        var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);
3859
 
        var range = editor.selection[unitName](cursor.row, cursor.column);
3860
 
 
3861
 
        if (this.$clickSelection) {
3862
 
            var cmpStart = this.$clickSelection.comparePoint(range.start);
3863
 
            var cmpEnd = this.$clickSelection.comparePoint(range.end);
3864
 
 
3865
 
            if (cmpStart == -1 && cmpEnd <= 0) {
3866
 
                anchor = this.$clickSelection.end;
3867
 
                if (range.end.row != cursor.row || range.end.column != cursor.column)
3868
 
                    cursor = range.start;
3869
 
            } else if (cmpEnd == 1 && cmpStart >= 0) {
3870
 
                anchor = this.$clickSelection.start;
3871
 
                if (range.start.row != cursor.row || range.start.column != cursor.column)
3872
 
                    cursor = range.end;
3873
 
            } else if (cmpStart == -1 && cmpEnd == 1) {
3874
 
                cursor = range.end;
3875
 
                anchor = range.start;
3876
 
            } else {
3877
 
                var orientedRange = calcRangeOrientation(this.$clickSelection, cursor);
3878
 
                cursor = orientedRange.cursor;
3879
 
                anchor = orientedRange.anchor;
3880
 
            }
3881
 
            editor.selection.setSelectionAnchor(anchor.row, anchor.column);
3882
 
        }
3883
 
        editor.selection.selectToPosition(cursor);
3884
 
 
3885
 
        editor.renderer.scrollCursorIntoView();
3886
 
    };
3887
 
 
3888
 
    this.startDrag = function() {
3889
 
        var editor = this.editor;
3890
 
        this.setState("drag");
3891
 
        this.dragRange = editor.getSelectionRange();
3892
 
        var style = editor.getSelectionStyle();
3893
 
        this.dragSelectionMarker = editor.session.addMarker(this.dragRange, "ace_selection", style);
3894
 
        editor.clearSelection();
3895
 
        dom.addCssClass(editor.container, "ace_dragging");
3896
 
        if (!this.$dragKeybinding) {
3897
 
            this.$dragKeybinding = {
3898
 
                handleKeyboard: function(data, hashId, keyString, keyCode) {
3899
 
                    if (keyString == "esc")
3900
 
                        return {command: this.command};
3901
 
                },
3902
 
                command: {
3903
 
                    exec: function(editor) {
3904
 
                        var self = editor.$mouseHandler;
3905
 
                        self.dragCursor = null;
3906
 
                        self.dragEnd();
3907
 
                        self.startSelect();
3908
 
                    }
3909
 
                }
3910
 
            }
3911
 
        }
3912
 
 
3913
 
        editor.keyBinding.addKeyboardHandler(this.$dragKeybinding);
3914
 
    };
3915
 
 
3916
 
    this.focusWait = function() {
3917
 
        var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
3918
 
        var time = (new Date()).getTime();
3919
 
 
3920
 
        if (distance > DRAG_OFFSET || time - this.mousedownEvent.time > this.$focusTimout)
3921
 
            this.startSelect(this.mousedownEvent.getDocumentPosition());
3922
 
    };
3923
 
 
3924
 
    this.dragWait = function(e) {
3925
 
        var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
3926
 
        var time = (new Date()).getTime();
3927
 
        var editor = this.editor;
3928
 
 
3929
 
        if (distance > DRAG_OFFSET) {
3930
 
            this.startSelect(this.mousedownEvent.getDocumentPosition());
3931
 
        } else if (time - this.mousedownEvent.time > editor.$mouseHandler.$dragDelay) {
3932
 
            this.startDrag();
3933
 
        }
3934
 
    };
3935
 
 
3936
 
    this.dragWaitEnd = function(e) {
3937
 
        this.mousedownEvent.domEvent = e;
3938
 
        this.startSelect();
3939
 
    };
3940
 
 
3941
 
    this.drag = function() {
3942
 
        var editor = this.editor;
3943
 
        this.dragCursor = editor.renderer.screenToTextCoordinates(this.x, this.y);
3944
 
        editor.moveCursorToPosition(this.dragCursor);
3945
 
        editor.renderer.scrollCursorIntoView();
3946
 
    };
3947
 
 
3948
 
    this.dragEnd = function(e) {
3949
 
        var editor = this.editor;
3950
 
        var dragCursor = this.dragCursor;
3951
 
        var dragRange = this.dragRange;
3952
 
        dom.removeCssClass(editor.container, "ace_dragging");
3953
 
        editor.session.removeMarker(this.dragSelectionMarker);
3954
 
        editor.keyBinding.removeKeyboardHandler(this.$dragKeybinding);
3955
 
 
3956
 
        if (!dragCursor)
3957
 
            return;
3958
 
 
3959
 
        editor.clearSelection();
3960
 
        if (e && (e.ctrlKey || e.altKey)) {
3961
 
            var session = editor.session;
3962
 
            var newRange = dragRange;
3963
 
            newRange.end = session.insert(dragCursor, session.getTextRange(dragRange));
3964
 
            newRange.start = dragCursor;
3965
 
        } else if (dragRange.contains(dragCursor.row, dragCursor.column)) {
3966
 
            return;
3967
 
        } else {
3968
 
            var newRange = editor.moveText(dragRange, dragCursor);
3969
 
        }
3970
 
 
3971
 
        if (!newRange)
3972
 
            return;
3973
 
 
3974
 
        editor.selection.setSelectionRange(newRange);
3975
 
    };
3976
 
 
3977
 
    this.onDoubleClick = function(ev) {
3978
 
        var pos = ev.getDocumentPosition();
3979
 
        var editor = this.editor;
3980
 
        var session = editor.session;
3981
 
 
3982
 
        var range = session.getBracketRange(pos);
3983
 
        if (range) {
3984
 
            if (range.isEmpty()) {
3985
 
                range.start.column--;
3986
 
                range.end.column++;
3987
 
            }
3988
 
            this.$clickSelection = range;
3989
 
            this.setState("select");
3990
 
            return;
3991
 
        }
3992
 
 
3993
 
        this.$clickSelection = editor.selection.getWordRange(pos.row, pos.column);
3994
 
        this.setState("selectByWords");
3995
 
    };
3996
 
 
3997
 
    this.onTripleClick = function(ev) {
3998
 
        var pos = ev.getDocumentPosition();
3999
 
        var editor = this.editor;
4000
 
 
4001
 
        this.setState("selectByLines");
4002
 
        this.$clickSelection = editor.selection.getLineRange(pos.row);
4003
 
    };
4004
 
 
4005
 
    this.onQuadClick = function(ev) {
4006
 
        var editor = this.editor;
4007
 
 
4008
 
        editor.selectAll();
4009
 
        this.$clickSelection = editor.getSelectionRange();
4010
 
        this.setState("null");
4011
 
    };
4012
 
 
4013
 
    this.onMouseWheel = function(ev) {
4014
 
        if (ev.getShiftKey() || ev.getAccelKey())
4015
 
            return;
4016
 
        var t = ev.domEvent.timeStamp;
4017
 
        var dt = t - (this.$lastScrollTime||0);
4018
 
        
4019
 
        var editor = this.editor;
4020
 
        var isScrolable = editor.renderer.isScrollableBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed);
4021
 
        if (isScrolable || dt < 200) {
4022
 
            this.$lastScrollTime = t;
4023
 
            editor.renderer.scrollBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed);
4024
 
            return ev.stop();
4025
 
        }
4026
 
    };
4027
 
 
4028
 
}).call(DefaultHandlers.prototype);
4029
 
 
4030
 
exports.DefaultHandlers = DefaultHandlers;
4031
 
 
4032
 
function calcDistance(ax, ay, bx, by) {
4033
 
    return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));
4034
 
}
4035
 
 
4036
 
function calcRangeOrientation(range, cursor) {
4037
 
    if (range.start.row == range.end.row)
4038
 
        var cmp = 2 * cursor.column - range.start.column - range.end.column;
4039
 
    else
4040
 
        var cmp = 2 * cursor.row - range.start.row - range.end.row;
4041
 
 
4042
 
    if (cmp < 0)
4043
 
        return {cursor: range.start, anchor: range.end};
4044
 
    else
4045
 
        return {cursor: range.end, anchor: range.start};
4046
 
}
4047
 
 
4048
 
});
4049
 
 
4050
 
define('ace/mouse/default_gutter_handler', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/event'], function(require, exports, module) {
4051
 
 
4052
 
var dom = require("../lib/dom");
4053
 
var event = require("../lib/event");
4054
 
 
4055
 
function GutterHandler(mouseHandler) {
4056
 
    var editor = mouseHandler.editor;
4057
 
    var gutter = editor.renderer.$gutterLayer;
4058
 
 
4059
 
    mouseHandler.editor.setDefaultHandler("guttermousedown", function(e) {
4060
 
        if (!editor.isFocused())
4061
 
            return;
4062
 
        var gutterRegion = gutter.getRegion(e);
4063
 
 
4064
 
        if (gutterRegion == "foldWidgets")
4065
 
            return;
4066
 
 
4067
 
        var row = e.getDocumentPosition().row;
4068
 
        var selection = editor.session.selection;
4069
 
 
4070
 
        if (e.getShiftKey())
4071
 
            selection.selectTo(row, 0);
4072
 
        else {
4073
 
            if (e.domEvent.detail == 2) {
4074
 
                editor.selectAll();
4075
 
                return e.preventDefault();
4076
 
            }
4077
 
            mouseHandler.$clickSelection = editor.selection.getLineRange(row);
4078
 
        }
4079
 
        mouseHandler.captureMouse(e, "selectByLines");
4080
 
        return e.preventDefault();
4081
 
    });
4082
 
 
4083
 
 
4084
 
    var tooltipTimeout, mouseEvent, tooltip, tooltipAnnotation;
4085
 
    function createTooltip() {
4086
 
        tooltip = dom.createElement("div");
4087
 
        tooltip.className = "ace_gutter-tooltip";
4088
 
        tooltip.style.display = "none";
4089
 
        editor.container.appendChild(tooltip);
4090
 
    }
4091
 
 
4092
 
    function showTooltip() {
4093
 
        if (!tooltip) {
4094
 
            createTooltip();
4095
 
        }
4096
 
        var row = mouseEvent.getDocumentPosition().row;
4097
 
        var annotation = gutter.$annotations[row];
4098
 
        if (!annotation)
4099
 
            return hideTooltip();
4100
 
 
4101
 
        var maxRow = editor.session.getLength();
4102
 
        if (row == maxRow) {
4103
 
            var screenRow = editor.renderer.pixelToScreenCoordinates(0, mouseEvent.y).row;
4104
 
            var pos = mouseEvent.$pos;
4105
 
            if (screenRow > editor.session.documentToScreenRow(pos.row, pos.column))
4106
 
                return hideTooltip();
4107
 
        }
4108
 
 
4109
 
        if (tooltipAnnotation == annotation)
4110
 
            return;
4111
 
        tooltipAnnotation = annotation.text.join("<br/>");
4112
 
 
4113
 
        tooltip.style.display = "block";
4114
 
        tooltip.innerHTML = tooltipAnnotation;
4115
 
        editor.on("mousewheel", hideTooltip);
4116
 
 
4117
 
        moveTooltip(mouseEvent);
4118
 
    }
4119
 
 
4120
 
    function hideTooltip() {
4121
 
        if (tooltipTimeout)
4122
 
            tooltipTimeout = clearTimeout(tooltipTimeout);
4123
 
        if (tooltipAnnotation) {
4124
 
            tooltip.style.display = "none";
4125
 
            tooltipAnnotation = null;
4126
 
            editor.removeEventListener("mousewheel", hideTooltip);
4127
 
        }
4128
 
    }
4129
 
 
4130
 
    function moveTooltip(e) {
4131
 
        var rect = editor.renderer.$gutter.getBoundingClientRect();
4132
 
        tooltip.style.left = e.x + 15 + "px";
4133
 
        if (e.y + 3 * editor.renderer.lineHeight + 15 < rect.bottom) {
4134
 
            tooltip.style.bottom =  "";
4135
 
            tooltip.style.top =  e.y + 15 + "px";
4136
 
        } else {
4137
 
            tooltip.style.top =  "";
4138
 
            tooltip.style.bottom = rect.bottom - e.y + 5 + "px";
4139
 
        }
4140
 
    }
4141
 
 
4142
 
    mouseHandler.editor.setDefaultHandler("guttermousemove", function(e) {
4143
 
        var target = e.domEvent.target || e.domEvent.srcElement;
4144
 
        if (dom.hasCssClass(target, "ace_fold-widget"))
4145
 
            return hideTooltip();
4146
 
 
4147
 
        if (tooltipAnnotation)
4148
 
            moveTooltip(e);
4149
 
 
4150
 
        mouseEvent = e;
4151
 
        if (tooltipTimeout)
4152
 
            return;
4153
 
        tooltipTimeout = setTimeout(function() {
4154
 
            tooltipTimeout = null;
4155
 
            if (mouseEvent && !mouseHandler.isMousePressed)
4156
 
                showTooltip();
4157
 
            else
4158
 
                hideTooltip();
4159
 
        }, 50);
4160
 
    });
4161
 
 
4162
 
    event.addListener(editor.renderer.$gutter, "mouseout", function(e) {
4163
 
        mouseEvent = null;
4164
 
        if (!tooltipAnnotation || tooltipTimeout)
4165
 
            return;
4166
 
 
4167
 
        tooltipTimeout = setTimeout(function() {
4168
 
            tooltipTimeout = null;
4169
 
            hideTooltip();
4170
 
        }, 50);
4171
 
    });
4172
 
 
4173
 
}
4174
 
 
4175
 
exports.GutterHandler = GutterHandler;
4176
 
 
4177
 
});
4178
 
 
4179
 
define('ace/mouse/mouse_event', ['require', 'exports', 'module' , 'ace/lib/event', 'ace/lib/useragent'], function(require, exports, module) {
4180
 
 
4181
 
 
4182
 
var event = require("../lib/event");
4183
 
var useragent = require("../lib/useragent");
4184
 
var MouseEvent = exports.MouseEvent = function(domEvent, editor) {
4185
 
    this.domEvent = domEvent;
4186
 
    this.editor = editor;
4187
 
    
4188
 
    this.x = this.clientX = domEvent.clientX;
4189
 
    this.y = this.clientY = domEvent.clientY;
4190
 
 
4191
 
    this.$pos = null;
4192
 
    this.$inSelection = null;
4193
 
    
4194
 
    this.propagationStopped = false;
4195
 
    this.defaultPrevented = false;
4196
 
};
4197
 
 
4198
 
(function() {  
4199
 
    
4200
 
    this.stopPropagation = function() {
4201
 
        event.stopPropagation(this.domEvent);
4202
 
        this.propagationStopped = true;
4203
 
    };
4204
 
    
4205
 
    this.preventDefault = function() {
4206
 
        event.preventDefault(this.domEvent);
4207
 
        this.defaultPrevented = true;
4208
 
    };
4209
 
    
4210
 
    this.stop = function() {
4211
 
        this.stopPropagation();
4212
 
        this.preventDefault();
4213
 
    };
4214
 
    this.getDocumentPosition = function() {
4215
 
        if (this.$pos)
4216
 
            return this.$pos;
4217
 
        
4218
 
        this.$pos = this.editor.renderer.screenToTextCoordinates(this.clientX, this.clientY);
4219
 
        return this.$pos;
4220
 
    };
4221
 
    this.inSelection = function() {
4222
 
        if (this.$inSelection !== null)
4223
 
            return this.$inSelection;
4224
 
            
4225
 
        var editor = this.editor;
4226
 
        
4227
 
        if (editor.getReadOnly()) {
4228
 
            this.$inSelection = false;
4229
 
        }
4230
 
        else {
4231
 
            var selectionRange = editor.getSelectionRange();
4232
 
            if (selectionRange.isEmpty())
4233
 
                this.$inSelection = false;
4234
 
            else {
4235
 
                var pos = this.getDocumentPosition();
4236
 
                this.$inSelection = selectionRange.contains(pos.row, pos.column);
4237
 
            }
4238
 
        }
4239
 
        return this.$inSelection;
4240
 
    };
4241
 
    this.getButton = function() {
4242
 
        return event.getButton(this.domEvent);
4243
 
    };
4244
 
    this.getShiftKey = function() {
4245
 
        return this.domEvent.shiftKey;
4246
 
    };
4247
 
    
4248
 
    this.getAccelKey = useragent.isMac
4249
 
        ? function() { return this.domEvent.metaKey; }
4250
 
        : function() { return this.domEvent.ctrlKey; };
4251
 
    
4252
 
}).call(MouseEvent.prototype);
4253
 
 
4254
 
});
4255
 
 
4256
 
define('ace/mouse/dragdrop', ['require', 'exports', 'module' , 'ace/lib/event'], function(require, exports, module) {
4257
 
 
4258
 
 
4259
 
var event = require("../lib/event");
4260
 
 
4261
 
var DragdropHandler = function(mouseHandler) {
4262
 
    var editor = mouseHandler.editor;
4263
 
    var dragSelectionMarker, x, y;
4264
 
    var timerId, range;
4265
 
    var dragCursor, counter = 0;
4266
 
 
4267
 
    var mouseTarget = editor.container;
4268
 
    event.addListener(mouseTarget, "dragenter", function(e) {
4269
 
        if (editor.getReadOnly())
4270
 
            return;
4271
 
        var types = e.dataTransfer.types;
4272
 
        if (types && Array.prototype.indexOf.call(types, "text/plain") === -1)
4273
 
            return;
4274
 
        if (!dragSelectionMarker)
4275
 
            addDragMarker();
4276
 
        counter++;
4277
 
        return event.preventDefault(e);
4278
 
    });
4279
 
 
4280
 
    event.addListener(mouseTarget, "dragover", function(e) {
4281
 
        if (editor.getReadOnly())
4282
 
            return;
4283
 
        var types = e.dataTransfer.types;
4284
 
        if (types && Array.prototype.indexOf.call(types, "text/plain") === -1)
4285
 
            return;
4286
 
        if (onMouseMoveTimer !== null)
4287
 
            onMouseMoveTimer = null;
4288
 
        x = e.clientX;
4289
 
        y = e.clientY;
4290
 
        return event.preventDefault(e);
4291
 
    });
4292
 
 
4293
 
    var onDragInterval =  function() {
4294
 
        dragCursor = editor.renderer.screenToTextCoordinates(x, y);
4295
 
        editor.moveCursorToPosition(dragCursor);
4296
 
        editor.renderer.scrollCursorIntoView();
4297
 
    };
4298
 
 
4299
 
    event.addListener(mouseTarget, "dragleave", function(e) {
4300
 
        counter--;
4301
 
        if (counter <= 0 && dragSelectionMarker) {
4302
 
            clearDragMarker();
4303
 
            return event.preventDefault(e);
4304
 
        }
4305
 
    });
4306
 
 
4307
 
    event.addListener(mouseTarget, "drop", function(e) {
4308
 
        if (!dragSelectionMarker)
4309
 
            return;
4310
 
        range.end = editor.session.insert(dragCursor, e.dataTransfer.getData('Text'));
4311
 
        range.start = dragCursor;
4312
 
        clearDragMarker();
4313
 
        editor.focus();
4314
 
        return event.preventDefault(e);
4315
 
    });
4316
 
 
4317
 
    function addDragMarker() {
4318
 
        range = editor.selection.toOrientedRange();
4319
 
        dragSelectionMarker = editor.session.addMarker(range, "ace_selection", editor.getSelectionStyle());
4320
 
        editor.clearSelection();
4321
 
        clearInterval(timerId);
4322
 
        timerId = setInterval(onDragInterval, 20);
4323
 
        counter = 0;
4324
 
        event.addListener(document, "mousemove", onMouseMove);
4325
 
    }
4326
 
    function clearDragMarker() {
4327
 
        clearInterval(timerId);
4328
 
        editor.session.removeMarker(dragSelectionMarker);
4329
 
        dragSelectionMarker = null;
4330
 
        editor.selection.fromOrientedRange(range);
4331
 
        counter = 0;
4332
 
        event.removeListener(document, "mousemove", onMouseMove);
4333
 
    }
4334
 
    var onMouseMoveTimer = null;
4335
 
    function onMouseMove() {
4336
 
        if (onMouseMoveTimer == null) {
4337
 
            onMouseMoveTimer = setTimeout(function() {
4338
 
                if (onMouseMoveTimer != null && dragSelectionMarker)
4339
 
                    clearDragMarker();
4340
 
            }, 20);
4341
 
        }
4342
 
    }
4343
 
};
4344
 
 
4345
 
exports.DragdropHandler = DragdropHandler;
4346
 
});
4347
 
 
4348
 
define('ace/config', ['require', 'exports', 'module' , 'ace/lib/lang', 'ace/lib/oop', 'ace/lib/net', 'ace/lib/event_emitter'], function(require, exports, module) {
4349
 
"no use strict";
4350
 
 
4351
 
var lang = require("./lib/lang");
4352
 
var oop = require("./lib/oop");
4353
 
var net = require("./lib/net");
4354
 
var EventEmitter = require("./lib/event_emitter").EventEmitter;
4355
 
 
4356
 
var global = (function() {
4357
 
    return this;
4358
 
})();
4359
 
 
4360
 
var options = {
4361
 
    packaged: false,
4362
 
    workerPath: null,
4363
 
    modePath: null,
4364
 
    themePath: null,
4365
 
    basePath: "",
4366
 
    suffix: ".js",
4367
 
    $moduleUrls: {}
4368
 
};
4369
 
 
4370
 
exports.get = function(key) {
4371
 
    if (!options.hasOwnProperty(key))
4372
 
        throw new Error("Unknown config key: " + key);
4373
 
 
4374
 
    return options[key];
4375
 
};
4376
 
 
4377
 
exports.set = function(key, value) {
4378
 
    if (!options.hasOwnProperty(key))
4379
 
        throw new Error("Unknown config key: " + key);
4380
 
 
4381
 
    options[key] = value;
4382
 
};
4383
 
 
4384
 
exports.all = function() {
4385
 
    return lang.copyObject(options);
4386
 
};
4387
 
oop.implement(exports, EventEmitter);
4388
 
 
4389
 
exports.moduleUrl = function(name, component) {
4390
 
    if (options.$moduleUrls[name])
4391
 
        return options.$moduleUrls[name];
4392
 
 
4393
 
    var parts = name.split("/");
4394
 
    component = component || parts[parts.length - 2] || "";
4395
 
    var base = parts[parts.length - 1].replace(component, "").replace(/(^[\-_])|([\-_]$)/, "");
4396
 
 
4397
 
    if (!base && parts.length > 1)
4398
 
        base = parts[parts.length - 2];
4399
 
    var path = options[component + "Path"];
4400
 
    if (path == null)
4401
 
        path = options.basePath;
4402
 
    if (path && path.slice(-1) != "/")
4403
 
        path += "/";
4404
 
    return path + component + "-" + base + this.get("suffix");
4405
 
};
4406
 
 
4407
 
exports.setModuleUrl = function(name, subst) {
4408
 
    return options.$moduleUrls[name] = subst;
4409
 
};
4410
 
 
4411
 
exports.loadModule = function(moduleName, onLoad) {
4412
 
    var module, moduleType;
4413
 
    if (Array.isArray(moduleName)) {
4414
 
        moduleType = moduleName[0];
4415
 
        moduleName = moduleName[1];
4416
 
    }
4417
 
    try {
4418
 
        module = require(moduleName);
4419
 
    } catch (e) {};
4420
 
    if (module)
4421
 
        return onLoad && onLoad(module);
4422
 
 
4423
 
    var afterLoad = function() {
4424
 
        require([moduleName], function(module) {
4425
 
            exports._emit("load.module", {name: moduleName, module: module});
4426
 
            onLoad && onLoad(module);
4427
 
        });
4428
 
    };
4429
 
 
4430
 
    if (!exports.get("packaged"))
4431
 
        return afterLoad();
4432
 
    net.loadScript(exports.moduleUrl(moduleName, moduleType), afterLoad);
4433
 
};
4434
 
exports.init = function() {
4435
 
    options.packaged = require.packaged || module.packaged || (global.define && define.packaged);
4436
 
 
4437
 
    if (!global.document)
4438
 
        return "";
4439
 
 
4440
 
    var scriptOptions = {};
4441
 
    var scriptUrl = "";
4442
 
 
4443
 
    var scripts = document.getElementsByTagName("script");
4444
 
    for (var i=0; i<scripts.length; i++) {
4445
 
        var script = scripts[i];
4446
 
 
4447
 
        var src = script.src || script.getAttribute("src");
4448
 
        if (!src)
4449
 
            continue;
4450
 
 
4451
 
        var attributes = script.attributes;
4452
 
        for (var j=0, l=attributes.length; j < l; j++) {
4453
 
            var attr = attributes[j];
4454
 
            if (attr.name.indexOf("data-ace-") === 0) {
4455
 
                scriptOptions[deHyphenate(attr.name.replace(/^data-ace-/, ""))] = attr.value;
4456
 
            }
4457
 
        }
4458
 
 
4459
 
        var m = src.match(/^(.*)\/ace(\-\w+)?\.js(\?|$)/);
4460
 
        if (m)
4461
 
            scriptUrl = m[1];
4462
 
    }
4463
 
 
4464
 
    if (scriptUrl) {
4465
 
        scriptOptions.base = scriptOptions.base || scriptUrl;
4466
 
        scriptOptions.packaged = true;
4467
 
    }
4468
 
 
4469
 
    scriptOptions.basePath = scriptOptions.base;
4470
 
    scriptOptions.workerPath = scriptOptions.workerPath || scriptOptions.base;
4471
 
    scriptOptions.modePath = scriptOptions.modePath || scriptOptions.base;
4472
 
    scriptOptions.themePath = scriptOptions.themePath || scriptOptions.base;
4473
 
    delete scriptOptions.base;
4474
 
 
4475
 
    for (var key in scriptOptions)
4476
 
        if (typeof scriptOptions[key] !== "undefined")
4477
 
            exports.set(key, scriptOptions[key]);
4478
 
};
4479
 
 
4480
 
function deHyphenate(str) {
4481
 
    return str.replace(/-(.)/g, function(m, m1) { return m1.toUpperCase(); });
4482
 
}
4483
 
 
4484
 
var optionsProvider = {
4485
 
    setOptions: function(optList) {
4486
 
        Object.keys(optList).forEach(function(key) {
4487
 
            this.setOption(key, optList[key]);
4488
 
        }, this);
4489
 
    },
4490
 
    getOptions: function(a) {
4491
 
        var b = {};
4492
 
        Object.keys(a).forEach(function(key) {
4493
 
            b[key] = this.getOption(key);
4494
 
        }, this);
4495
 
        return b;
4496
 
    },
4497
 
    setOption: function(name, value) {
4498
 
        if (this["$" + name] === value)
4499
 
            return;
4500
 
        var opt = this.$options[name];
4501
 
        if (!opt)
4502
 
            return undefined;
4503
 
        if (opt.forwardTo)
4504
 
            return this[opt.forwardTo] && this[opt.forwardTo].setOption(name, value);
4505
 
 
4506
 
        if (!opt.handlesSet)
4507
 
            this["$" + name] = value;
4508
 
        if (opt && opt.set)
4509
 
            opt.set.call(this, value);
4510
 
    },
4511
 
    getOption: function(name) {
4512
 
        var opt = this.$options[name];
4513
 
        if (!opt)
4514
 
            return undefined;
4515
 
        if (opt.forwardTo)
4516
 
            return this[opt.forwardTo] && this[opt.forwardTo].getOption(name);
4517
 
        return opt && opt.get ? opt.get.call(this) : this["$" + name];
4518
 
    }
4519
 
};
4520
 
 
4521
 
var defaultOptions = {};
4522
 
exports.defineOptions = function(obj, path, options) {
4523
 
    if (!obj.$options)
4524
 
        defaultOptions[path] = obj.$options = {};
4525
 
 
4526
 
    Object.keys(options).forEach(function(key) {
4527
 
        var opt = options[key];
4528
 
        if (typeof opt == "string")
4529
 
            opt = {forwardTo: opt};
4530
 
 
4531
 
        opt.name || (opt.name = key);
4532
 
        obj.$options[opt.name] = opt;
4533
 
        if ("initialValue" in opt)
4534
 
            obj["$" + opt.name] = opt.initialValue;
4535
 
    });
4536
 
    oop.implement(obj, optionsProvider);
4537
 
 
4538
 
    return this;
4539
 
};
4540
 
 
4541
 
exports.resetOptions = function(obj) {
4542
 
    Object.keys(obj.$options).forEach(function(key) {
4543
 
        var opt = obj.$options[key];
4544
 
        if ("value" in opt)
4545
 
            obj.setOption(key, opt.value);
4546
 
    });
4547
 
};
4548
 
 
4549
 
exports.setDefaultValue = function(path, name, value) {
4550
 
    var opts = defaultOptions[path] || (defaultOptions[path] = {});
4551
 
    if (opts[name]) {
4552
 
        if (opts.forwardTo)
4553
 
            exports.setDefaultValue(opts.forwardTo, name, value)
4554
 
        else
4555
 
            opts[name].value = value;
4556
 
    }
4557
 
};
4558
 
 
4559
 
exports.setDefaultValues = function(path, optionHash) {
4560
 
    Object.keys(optionHash).forEach(function(key) {
4561
 
        exports.setDefaultValue(path, key, optionHash[key]);
4562
 
    });
4563
 
};
4564
 
 
4565
 
});
4566
 
define('ace/lib/net', ['require', 'exports', 'module' , 'ace/lib/dom'], function(require, exports, module) {
4567
 
 
4568
 
var dom = require("./dom");
4569
 
 
4570
 
exports.get = function (url, callback) {
4571
 
    var xhr = new XMLHttpRequest();
4572
 
    xhr.open('GET', url, true);
4573
 
    xhr.onreadystatechange = function () {
4574
 
        if (xhr.readyState === 4) {
4575
 
            callback(xhr.responseText);
4576
 
        }
4577
 
    };
4578
 
    xhr.send(null);
4579
 
};
4580
 
 
4581
 
exports.loadScript = function(path, callback) {
4582
 
    var head = dom.getDocumentHead();
4583
 
    var s = document.createElement('script');
4584
 
 
4585
 
    s.src = path;
4586
 
    head.appendChild(s);
4587
 
 
4588
 
    s.onload = s.onreadystatechange = function(_, isAbort) {
4589
 
        if (isAbort || !s.readyState || s.readyState == "loaded" || s.readyState == "complete") {
4590
 
            s = s.onload = s.onreadystatechange = null;
4591
 
            if (!isAbort)
4592
 
                callback();
4593
 
        }
4594
 
    };
4595
 
};
4596
 
 
4597
 
});
4598
 
 
4599
 
define('ace/lib/event_emitter', ['require', 'exports', 'module' ], function(require, exports, module) {
4600
 
 
4601
 
 
4602
 
var EventEmitter = {};
4603
 
var stopPropagation = function() { this.propagationStopped = true; };
4604
 
var preventDefault = function() { this.defaultPrevented = true; };
4605
 
 
4606
 
EventEmitter._emit =
4607
 
EventEmitter._dispatchEvent = function(eventName, e) {
4608
 
    this._eventRegistry || (this._eventRegistry = {});
4609
 
    this._defaultHandlers || (this._defaultHandlers = {});
4610
 
 
4611
 
    var listeners = this._eventRegistry[eventName] || [];
4612
 
    var defaultHandler = this._defaultHandlers[eventName];
4613
 
    if (!listeners.length && !defaultHandler)
4614
 
        return;
4615
 
 
4616
 
    if (typeof e != "object" || !e)
4617
 
        e = {};
4618
 
 
4619
 
    if (!e.type)
4620
 
        e.type = eventName;
4621
 
    if (!e.stopPropagation)
4622
 
        e.stopPropagation = stopPropagation;
4623
 
    if (!e.preventDefault)
4624
 
        e.preventDefault = preventDefault;
4625
 
    if (!e.target)
4626
 
        e.target = this;
4627
 
 
4628
 
    for (var i=0; i<listeners.length; i++) {
4629
 
        listeners[i](e);
4630
 
        if (e.propagationStopped)
4631
 
            break;
4632
 
    }
4633
 
    
4634
 
    if (defaultHandler && !e.defaultPrevented)
4635
 
        return defaultHandler(e);
4636
 
};
4637
 
 
4638
 
 
4639
 
EventEmitter._signal = function(eventName, e) {
4640
 
    var listeners = (this._eventRegistry || {})[eventName];
4641
 
    if (!listeners)
4642
 
        return;
4643
 
 
4644
 
    for (var i=0; i<listeners.length; i++)
4645
 
        listeners[i](e);
4646
 
};
4647
 
 
4648
 
EventEmitter.once = function(eventName, callback) {
4649
 
    var _self = this;
4650
 
    var newCallback = function() {
4651
 
        fun && fun.apply(null, arguments);
4652
 
        _self.removeEventListener(event, newCallback);
4653
 
    };
4654
 
    this.addEventListener(event, newCallback);
4655
 
};
4656
 
 
4657
 
 
4658
 
EventEmitter.setDefaultHandler = function(eventName, callback) {
4659
 
    this._defaultHandlers = this._defaultHandlers || {};
4660
 
    
4661
 
    if (this._defaultHandlers[eventName])
4662
 
        throw new Error("The default handler for '" + eventName + "' is already set");
4663
 
        
4664
 
    this._defaultHandlers[eventName] = callback;
4665
 
};
4666
 
 
4667
 
EventEmitter.on =
4668
 
EventEmitter.addEventListener = function(eventName, callback, capturing) {
4669
 
    this._eventRegistry = this._eventRegistry || {};
4670
 
 
4671
 
    var listeners = this._eventRegistry[eventName];
4672
 
    if (!listeners)
4673
 
        listeners = this._eventRegistry[eventName] = [];
4674
 
 
4675
 
    if (listeners.indexOf(callback) == -1)
4676
 
        listeners[capturing ? "unshift" : "push"](callback);
4677
 
    return callback;
4678
 
};
4679
 
 
4680
 
EventEmitter.removeListener =
4681
 
EventEmitter.removeEventListener = function(eventName, callback) {
4682
 
    this._eventRegistry = this._eventRegistry || {};
4683
 
 
4684
 
    var listeners = this._eventRegistry[eventName];
4685
 
    if (!listeners)
4686
 
        return;
4687
 
 
4688
 
    var index = listeners.indexOf(callback);
4689
 
    if (index !== -1)
4690
 
        listeners.splice(index, 1);
4691
 
};
4692
 
 
4693
 
EventEmitter.removeAllListeners = function(eventName) {
4694
 
    if (this._eventRegistry) this._eventRegistry[eventName] = [];
4695
 
};
4696
 
 
4697
 
exports.EventEmitter = EventEmitter;
4698
 
 
4699
 
});
4700
 
 
4701
 
define('ace/mouse/fold_handler', ['require', 'exports', 'module' ], function(require, exports, module) {
4702
 
 
4703
 
 
4704
 
function FoldHandler(editor) {
4705
 
 
4706
 
    editor.on("click", function(e) {
4707
 
        var position = e.getDocumentPosition();
4708
 
        var session = editor.session;
4709
 
        var fold = session.getFoldAt(position.row, position.column, 1);
4710
 
        if (fold) {
4711
 
            if (e.getAccelKey())
4712
 
                session.removeFold(fold);
4713
 
            else
4714
 
                session.expandFold(fold);
4715
 
 
4716
 
            e.stop();
4717
 
        }
4718
 
    });
4719
 
 
4720
 
    editor.on("guttermousedown", function(e) {
4721
 
        var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);
4722
 
 
4723
 
        if (gutterRegion == "foldWidgets") {
4724
 
            var row = e.getDocumentPosition().row;
4725
 
            var session = editor.session;
4726
 
            if (session.foldWidgets && session.foldWidgets[row])
4727
 
                editor.session.onFoldWidgetClick(row, e);
4728
 
            if (!editor.isFocused())
4729
 
                editor.focus();
4730
 
            e.stop();
4731
 
        }
4732
 
    });
4733
 
 
4734
 
    editor.on("gutterdblclick", function(e) {
4735
 
        var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);
4736
 
 
4737
 
        if (gutterRegion == "foldWidgets") {
4738
 
            var row = e.getDocumentPosition().row;
4739
 
            var session = editor.session;
4740
 
            var data = session.getParentFoldRangeData(row, true);
4741
 
            var range = data.range || data.firstRange;
4742
 
 
4743
 
            if (range) {
4744
 
                var row = range.start.row;
4745
 
                var fold = session.getFoldAt(row, session.getLine(row).length, 1);
4746
 
 
4747
 
                if (fold) {
4748
 
                    session.removeFold(fold);
4749
 
                } else {
4750
 
                    session.addFold("...", range);
4751
 
                    editor.renderer.scrollCursorIntoView({row: range.start.row, column: 0});
4752
 
                }
4753
 
            }
4754
 
            e.stop();
4755
 
        }
4756
 
    });
4757
 
}
4758
 
 
4759
 
exports.FoldHandler = FoldHandler;
4760
 
 
4761
 
});
4762
 
 
4763
 
define('ace/keyboard/keybinding', ['require', 'exports', 'module' , 'ace/lib/keys', 'ace/lib/event'], function(require, exports, module) {
4764
 
 
4765
 
 
4766
 
var keyUtil  = require("../lib/keys");
4767
 
var event = require("../lib/event");
4768
 
 
4769
 
var KeyBinding = function(editor) {
4770
 
    this.$editor = editor;
4771
 
    this.$data = { };
4772
 
    this.$handlers = [];
4773
 
    this.setDefaultHandler(editor.commands);
4774
 
};
4775
 
 
4776
 
(function() {
4777
 
    this.setDefaultHandler = function(kb) {
4778
 
        this.removeKeyboardHandler(this.$defaultHandler);
4779
 
        this.$defaultHandler = kb;
4780
 
        this.addKeyboardHandler(kb, 0);
4781
 
        this.$data = {editor: this.$editor};
4782
 
    };
4783
 
 
4784
 
    this.setKeyboardHandler = function(kb) {
4785
 
        if (this.$handlers[this.$handlers.length - 1] == kb)
4786
 
            return;
4787
 
 
4788
 
        while (this.$handlers[1])
4789
 
            this.removeKeyboardHandler(this.$handlers[1]);
4790
 
 
4791
 
        this.addKeyboardHandler(kb, 1);
4792
 
    };
4793
 
 
4794
 
    this.addKeyboardHandler = function(kb, pos) {
4795
 
        if (!kb)
4796
 
            return;
4797
 
        var i = this.$handlers.indexOf(kb);
4798
 
        if (i != -1)
4799
 
            this.$handlers.splice(i, 1);
4800
 
 
4801
 
        if (pos == undefined)
4802
 
            this.$handlers.push(kb);
4803
 
        else
4804
 
            this.$handlers.splice(pos, 0, kb);
4805
 
 
4806
 
        if (i == -1 && kb.attach)
4807
 
            kb.attach(this.$editor);
4808
 
    };
4809
 
 
4810
 
    this.removeKeyboardHandler = function(kb) {
4811
 
        var i = this.$handlers.indexOf(kb);
4812
 
        if (i == -1)
4813
 
            return false;
4814
 
        this.$handlers.splice(i, 1);
4815
 
        kb.detach && kb.detach(this.$editor);
4816
 
        return true;
4817
 
    };
4818
 
 
4819
 
    this.getKeyboardHandler = function() {
4820
 
        return this.$handlers[this.$handlers.length - 1];
4821
 
    };
4822
 
 
4823
 
    this.$callKeyboardHandlers = function (hashId, keyString, keyCode, e) {
4824
 
        var toExecute;
4825
 
        var success = false;
4826
 
        var commands = this.$editor.commands;
4827
 
 
4828
 
        for (var i = this.$handlers.length; i--;) {
4829
 
            toExecute = this.$handlers[i].handleKeyboard(
4830
 
                this.$data, hashId, keyString, keyCode, e
4831
 
            );
4832
 
            if (!toExecute || !toExecute.command)
4833
 
                continue;
4834
 
            if (toExecute.command == "null") {
4835
 
                success = toExecute.passEvent != true;
4836
 
            } else {
4837
 
                success = commands.exec(toExecute.command, this.$editor, toExecute.args, e);                
4838
 
            }
4839
 
            if (success && e && hashId != -1)
4840
 
                event.stopEvent(e);
4841
 
            if (success)
4842
 
                break;
4843
 
        }
4844
 
        return success;
4845
 
    };
4846
 
 
4847
 
    this.onCommandKey = function(e, hashId, keyCode) {
4848
 
        var keyString = keyUtil.keyCodeToString(keyCode);
4849
 
        this.$callKeyboardHandlers(hashId, keyString, keyCode, e);
4850
 
    };
4851
 
 
4852
 
    this.onTextInput = function(text) {
4853
 
        var success = this.$callKeyboardHandlers(-1, text);
4854
 
        if (!success)
4855
 
            this.$editor.commands.exec("insertstring", this.$editor, text);
4856
 
    };
4857
 
 
4858
 
}).call(KeyBinding.prototype);
4859
 
 
4860
 
exports.KeyBinding = KeyBinding;
4861
 
});
4862
 
 
4863
 
define('ace/edit_session', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/lang', 'ace/config', 'ace/lib/event_emitter', 'ace/selection', 'ace/mode/text', 'ace/range', 'ace/document', 'ace/background_tokenizer', 'ace/search_highlight', 'ace/edit_session/folding', 'ace/edit_session/bracket_match'], function(require, exports, module) {
4864
 
 
4865
 
 
4866
 
var oop = require("./lib/oop");
4867
 
var lang = require("./lib/lang");
4868
 
var config = require("./config");
4869
 
var EventEmitter = require("./lib/event_emitter").EventEmitter;
4870
 
var Selection = require("./selection").Selection;
4871
 
var TextMode = require("./mode/text").Mode;
4872
 
var Range = require("./range").Range;
4873
 
var Document = require("./document").Document;
4874
 
var BackgroundTokenizer = require("./background_tokenizer").BackgroundTokenizer;
4875
 
var SearchHighlight = require("./search_highlight").SearchHighlight;
4876
 
 
4877
 
var EditSession = function(text, mode) {
4878
 
    this.$breakpoints = [];
4879
 
    this.$decorations = [];
4880
 
    this.$frontMarkers = {};
4881
 
    this.$backMarkers = {};
4882
 
    this.$markerId = 1;
4883
 
    this.$undoSelect = true;
4884
 
 
4885
 
    this.$foldData = [];
4886
 
    this.$foldData.toString = function() {
4887
 
        return this.join("\n");
4888
 
    }
4889
 
    this.on("changeFold", this.onChangeFold.bind(this));
4890
 
    this.$onChange = this.onChange.bind(this);
4891
 
 
4892
 
    if (typeof text != "object" || !text.getLine)
4893
 
        text = new Document(text);
4894
 
 
4895
 
    this.setDocument(text);
4896
 
 
4897
 
    this.selection = new Selection(this);
4898
 
    this.setMode(mode);
4899
 
 
4900
 
    config.resetOptions(this);
4901
 
    config._emit("session", this);
4902
 
};
4903
 
 
4904
 
 
4905
 
(function() {
4906
 
 
4907
 
    oop.implement(this, EventEmitter);
4908
 
    this.setDocument = function(doc) {
4909
 
        if (this.doc)
4910
 
            this.doc.removeListener("change", this.$onChange);
4911
 
 
4912
 
        this.doc = doc;
4913
 
        doc.on("change", this.$onChange);
4914
 
 
4915
 
        if (this.bgTokenizer)
4916
 
            this.bgTokenizer.setDocument(this.getDocument());
4917
 
 
4918
 
        this.resetCaches();
4919
 
    };
4920
 
    this.getDocument = function() {
4921
 
        return this.doc;
4922
 
    };
4923
 
    this.$resetRowCache = function(docRow) {
4924
 
        if (!docRow) {
4925
 
            this.$docRowCache = [];
4926
 
            this.$screenRowCache = [];
4927
 
            return;
4928
 
        }
4929
 
        var l = this.$docRowCache.length;
4930
 
        var i = this.$getRowCacheIndex(this.$docRowCache, docRow) + 1;
4931
 
        if (l > i) {
4932
 
            this.$docRowCache.splice(i, l);
4933
 
            this.$screenRowCache.splice(i, l);
4934
 
        }
4935
 
    };
4936
 
 
4937
 
    this.$getRowCacheIndex = function(cacheArray, val) {
4938
 
        var low = 0;
4939
 
        var hi = cacheArray.length - 1;
4940
 
 
4941
 
        while (low <= hi) {
4942
 
            var mid = (low + hi) >> 1;
4943
 
            var c = cacheArray[mid];
4944
 
 
4945
 
            if (val > c)
4946
 
                low = mid + 1;
4947
 
            else if (val < c)
4948
 
                hi = mid - 1;
4949
 
            else
4950
 
                return mid;
4951
 
        }
4952
 
 
4953
 
        return low -1;
4954
 
    };
4955
 
 
4956
 
    this.resetCaches = function() {
4957
 
        this.$modified = true;
4958
 
        this.$wrapData = [];
4959
 
        this.$rowLengthCache = [];
4960
 
        this.$resetRowCache(0);
4961
 
        if (this.bgTokenizer)
4962
 
            this.bgTokenizer.start(0);
4963
 
    };
4964
 
 
4965
 
    this.onChangeFold = function(e) {
4966
 
        var fold = e.data;
4967
 
        this.$resetRowCache(fold.start.row);
4968
 
    };
4969
 
 
4970
 
    this.onChange = function(e) {
4971
 
        var delta = e.data;
4972
 
        this.$modified = true;
4973
 
 
4974
 
        this.$resetRowCache(delta.range.start.row);
4975
 
 
4976
 
        var removedFolds = this.$updateInternalDataOnChange(e);
4977
 
        if (!this.$fromUndo && this.$undoManager && !delta.ignore) {
4978
 
            this.$deltasDoc.push(delta);
4979
 
            if (removedFolds && removedFolds.length != 0) {
4980
 
                this.$deltasFold.push({
4981
 
                    action: "removeFolds",
4982
 
                    folds:  removedFolds
4983
 
                });
4984
 
            }
4985
 
 
4986
 
            this.$informUndoManager.schedule();
4987
 
        }
4988
 
 
4989
 
        this.bgTokenizer.$updateOnChange(delta);
4990
 
        this._emit("change", e);
4991
 
    };
4992
 
    this.setValue = function(text) {
4993
 
        this.doc.setValue(text);
4994
 
        this.selection.moveCursorTo(0, 0);
4995
 
        this.selection.clearSelection();
4996
 
 
4997
 
        this.$resetRowCache(0);
4998
 
        this.$deltas = [];
4999
 
        this.$deltasDoc = [];
5000
 
        this.$deltasFold = [];
5001
 
        this.getUndoManager().reset();
5002
 
    };
5003
 
    this.getValue =
5004
 
    this.toString = function() {
5005
 
        return this.doc.getValue();
5006
 
    };
5007
 
    this.getSelection = function() {
5008
 
        return this.selection;
5009
 
    };
5010
 
    this.getState = function(row) {
5011
 
        return this.bgTokenizer.getState(row);
5012
 
    };
5013
 
    this.getTokens = function(row) {
5014
 
        return this.bgTokenizer.getTokens(row);
5015
 
    };
5016
 
    this.getTokenAt = function(row, column) {
5017
 
        var tokens = this.bgTokenizer.getTokens(row);
5018
 
        var token, c = 0;
5019
 
        if (column == null) {
5020
 
            i = tokens.length - 1;
5021
 
            c = this.getLine(row).length;
5022
 
        } else {
5023
 
            for (var i = 0; i < tokens.length; i++) {
5024
 
                c += tokens[i].value.length;
5025
 
                if (c >= column)
5026
 
                    break;
5027
 
            }
5028
 
        }
5029
 
        token = tokens[i];
5030
 
        if (!token)
5031
 
            return null;
5032
 
        token.index = i;
5033
 
        token.start = c - token.value.length;
5034
 
        return token;
5035
 
    };
5036
 
    this.setUndoManager = function(undoManager) {
5037
 
        this.$undoManager = undoManager;
5038
 
        this.$deltas = [];
5039
 
        this.$deltasDoc = [];
5040
 
        this.$deltasFold = [];
5041
 
 
5042
 
        if (this.$informUndoManager)
5043
 
            this.$informUndoManager.cancel();
5044
 
 
5045
 
        if (undoManager) {
5046
 
            var self = this;
5047
 
 
5048
 
            this.$syncInformUndoManager = function() {
5049
 
                self.$informUndoManager.cancel();
5050
 
 
5051
 
                if (self.$deltasFold.length) {
5052
 
                    self.$deltas.push({
5053
 
                        group: "fold",
5054
 
                        deltas: self.$deltasFold
5055
 
                    });
5056
 
                    self.$deltasFold = [];
5057
 
                }
5058
 
 
5059
 
                if (self.$deltasDoc.length) {
5060
 
                    self.$deltas.push({
5061
 
                        group: "doc",
5062
 
                        deltas: self.$deltasDoc
5063
 
                    });
5064
 
                    self.$deltasDoc = [];
5065
 
                }
5066
 
 
5067
 
                if (self.$deltas.length > 0) {
5068
 
                    undoManager.execute({
5069
 
                        action: "aceupdate",
5070
 
                        args: [self.$deltas, self]
5071
 
                    });
5072
 
                }
5073
 
 
5074
 
                self.$deltas = [];
5075
 
            }
5076
 
            this.$informUndoManager = lang.delayedCall(this.$syncInformUndoManager);
5077
 
        }
5078
 
    };
5079
 
 
5080
 
    this.$defaultUndoManager = {
5081
 
        undo: function() {},
5082
 
        redo: function() {},
5083
 
        reset: function() {}
5084
 
    };
5085
 
    this.getUndoManager = function() {
5086
 
        return this.$undoManager || this.$defaultUndoManager;
5087
 
    };
5088
 
    this.getTabString = function() {
5089
 
        if (this.getUseSoftTabs()) {
5090
 
            return lang.stringRepeat(" ", this.getTabSize());
5091
 
        } else {
5092
 
            return "\t";
5093
 
        }
5094
 
    };
5095
 
    this.setUseSoftTabs = function(val) {
5096
 
        this.setOption("useSoftTabs", val);
5097
 
    };
5098
 
    this.getUseSoftTabs = function() {
5099
 
         return this.$useSoftTabs;
5100
 
    };
5101
 
    this.setTabSize = function(tabSize) {
5102
 
        this.setOption("tabSize", tabSize)
5103
 
    };
5104
 
    this.getTabSize = function() {
5105
 
        return this.$tabSize;
5106
 
    };
5107
 
    this.isTabStop = function(position) {
5108
 
        return this.$useSoftTabs && (position.column % this.$tabSize == 0);
5109
 
    };
5110
 
 
5111
 
    this.$overwrite = false;
5112
 
    this.setOverwrite = function(overwrite) {
5113
 
        if (this.$overwrite == overwrite) return;
5114
 
 
5115
 
        this.$overwrite = overwrite;
5116
 
        this._emit("changeOverwrite");
5117
 
    };
5118
 
    this.getOverwrite = function() {
5119
 
        return this.$overwrite;
5120
 
    };
5121
 
    this.toggleOverwrite = function() {
5122
 
        this.setOverwrite(!this.$overwrite);
5123
 
    };
5124
 
    this.addGutterDecoration = function(row, className) {
5125
 
        if (!this.$decorations[row])
5126
 
            this.$decorations[row] = "";
5127
 
        this.$decorations[row] += " " + className;
5128
 
        this._emit("changeBreakpoint", {});
5129
 
    };
5130
 
    this.removeGutterDecoration = function(row, className) {
5131
 
        this.$decorations[row] = (this.$decorations[row] || "").replace(" " + className, "");
5132
 
        this._emit("changeBreakpoint", {});
5133
 
    };
5134
 
    this.getBreakpoints = function() {
5135
 
        return this.$breakpoints;
5136
 
    };
5137
 
    this.setBreakpoints = function(rows) {
5138
 
        this.$breakpoints = [];
5139
 
        for (var i=0; i<rows.length; i++) {
5140
 
            this.$breakpoints[rows[i]] = "ace_breakpoint";
5141
 
        }
5142
 
        this._emit("changeBreakpoint", {});
5143
 
    };
5144
 
    this.clearBreakpoints = function() {
5145
 
        this.$breakpoints = [];
5146
 
        this._emit("changeBreakpoint", {});
5147
 
    };
5148
 
    this.setBreakpoint = function(row, className) {
5149
 
        if (className === undefined)
5150
 
            className = "ace_breakpoint";
5151
 
        if (className)
5152
 
            this.$breakpoints[row] = className;
5153
 
        else
5154
 
            delete this.$breakpoints[row];
5155
 
        this._emit("changeBreakpoint", {});
5156
 
    };
5157
 
    this.clearBreakpoint = function(row) {
5158
 
        delete this.$breakpoints[row];
5159
 
        this._emit("changeBreakpoint", {});
5160
 
    };
5161
 
    this.addMarker = function(range, clazz, type, inFront) {
5162
 
        var id = this.$markerId++;
5163
 
 
5164
 
        var marker = {
5165
 
            range : range,
5166
 
            type : type || "line",
5167
 
            renderer: typeof type == "function" ? type : null,
5168
 
            clazz : clazz,
5169
 
            inFront: !!inFront,
5170
 
            id: id
5171
 
        }
5172
 
 
5173
 
        if (inFront) {
5174
 
            this.$frontMarkers[id] = marker;
5175
 
            this._emit("changeFrontMarker")
5176
 
        } else {
5177
 
            this.$backMarkers[id] = marker;
5178
 
            this._emit("changeBackMarker")
5179
 
        }
5180
 
 
5181
 
        return id;
5182
 
    };
5183
 
    this.addDynamicMarker = function(marker, inFront) {
5184
 
        if (!marker.update)
5185
 
            return;
5186
 
        var id = this.$markerId++;
5187
 
        marker.id = id;
5188
 
        marker.inFront = !!inFront;
5189
 
 
5190
 
        if (inFront) {
5191
 
            this.$frontMarkers[id] = marker;
5192
 
            this._emit("changeFrontMarker")
5193
 
        } else {
5194
 
            this.$backMarkers[id] = marker;
5195
 
            this._emit("changeBackMarker")
5196
 
        }
5197
 
 
5198
 
        return marker;
5199
 
    };
5200
 
    this.removeMarker = function(markerId) {
5201
 
        var marker = this.$frontMarkers[markerId] || this.$backMarkers[markerId];
5202
 
        if (!marker)
5203
 
            return;
5204
 
 
5205
 
        var markers = marker.inFront ? this.$frontMarkers : this.$backMarkers;
5206
 
        if (marker) {
5207
 
            delete (markers[markerId]);
5208
 
            this._emit(marker.inFront ? "changeFrontMarker" : "changeBackMarker");
5209
 
        }
5210
 
    };
5211
 
    this.getMarkers = function(inFront) {
5212
 
        return inFront ? this.$frontMarkers : this.$backMarkers;
5213
 
    };
5214
 
 
5215
 
    this.highlight = function(re) {
5216
 
        if (!this.$searchHighlight) {
5217
 
            var highlight = new SearchHighlight(null, "ace_selected-word", "text");
5218
 
            this.$searchHighlight = this.addDynamicMarker(highlight);
5219
 
        }
5220
 
        this.$searchHighlight.setRegexp(re);
5221
 
    }
5222
 
    this.highlightLines = function(startRow, endRow, clazz, inFront) {
5223
 
        if (typeof endRow != "number") {
5224
 
            clazz = endRow;
5225
 
            endRow = startRow;
5226
 
        }
5227
 
        if (!clazz)
5228
 
            clazz = "ace_step";
5229
 
 
5230
 
        var range = new Range(startRow, 0, endRow, Infinity);
5231
 
        range.id = this.addMarker(range, clazz, "fullLine", inFront);
5232
 
        return range;
5233
 
    };
5234
 
    this.setAnnotations = function(annotations) {
5235
 
        this.$annotations = annotations;
5236
 
        this._emit("changeAnnotation", {});
5237
 
    };
5238
 
    this.getAnnotations = function() {
5239
 
        return this.$annotations || [];
5240
 
    };
5241
 
    this.clearAnnotations = function() {
5242
 
        this.setAnnotations([]);
5243
 
    };
5244
 
    this.$detectNewLine = function(text) {
5245
 
        var match = text.match(/^.*?(\r?\n)/m);
5246
 
        if (match) {
5247
 
            this.$autoNewLine = match[1];
5248
 
        } else {
5249
 
            this.$autoNewLine = "\n";
5250
 
        }
5251
 
    };
5252
 
    this.getWordRange = function(row, column) {
5253
 
        var line = this.getLine(row);
5254
 
 
5255
 
        var inToken = false;
5256
 
        if (column > 0)
5257
 
            inToken = !!line.charAt(column - 1).match(this.tokenRe);
5258
 
 
5259
 
        if (!inToken)
5260
 
            inToken = !!line.charAt(column).match(this.tokenRe);
5261
 
 
5262
 
        if (inToken)
5263
 
            var re = this.tokenRe;
5264
 
        else if (/^\s+$/.test(line.slice(column-1, column+1)))
5265
 
            var re = /\s/;
5266
 
        else
5267
 
            var re = this.nonTokenRe;
5268
 
 
5269
 
        var start = column;
5270
 
        if (start > 0) {
5271
 
            do {
5272
 
                start--;
5273
 
            }
5274
 
            while (start >= 0 && line.charAt(start).match(re));
5275
 
            start++;
5276
 
        }
5277
 
 
5278
 
        var end = column;
5279
 
        while (end < line.length && line.charAt(end).match(re)) {
5280
 
            end++;
5281
 
        }
5282
 
 
5283
 
        return new Range(row, start, row, end);
5284
 
    };
5285
 
    this.getAWordRange = function(row, column) {
5286
 
        var wordRange = this.getWordRange(row, column);
5287
 
        var line = this.getLine(wordRange.end.row);
5288
 
 
5289
 
        while (line.charAt(wordRange.end.column).match(/[ \t]/)) {
5290
 
            wordRange.end.column += 1;
5291
 
        }
5292
 
        return wordRange;
5293
 
    };
5294
 
    this.setNewLineMode = function(newLineMode) {
5295
 
        this.doc.setNewLineMode(newLineMode);
5296
 
    };
5297
 
    this.getNewLineMode = function() {
5298
 
        return this.doc.getNewLineMode();
5299
 
    };
5300
 
    this.setUseWorker = function(useWorker) { this.setOption("useWorker", useWorker); };
5301
 
    this.getUseWorker = function() { return this.$useWorker; };
5302
 
    this.onReloadTokenizer = function(e) {
5303
 
        var rows = e.data;
5304
 
        this.bgTokenizer.start(rows.first);
5305
 
        this._emit("tokenizerUpdate", e);
5306
 
    };
5307
 
 
5308
 
    this.$modes = {};
5309
 
    this.$mode = null;
5310
 
    this.$modeId = null;
5311
 
    this.setMode = function(mode) {
5312
 
        if (mode && typeof mode === "object") {
5313
 
            if (mode.getTokenizer)
5314
 
                return this.$onChangeMode(mode);
5315
 
            var options = mode;
5316
 
            var path = options.path;
5317
 
        } else {
5318
 
            path = mode || "ace/mode/text";
5319
 
        }
5320
 
        if (!this.$modes["ace/mode/text"])
5321
 
            this.$modes["ace/mode/text"] = new TextMode();
5322
 
 
5323
 
        if (this.$modes[path] && !options)
5324
 
            return this.$onChangeMode(this.$modes[path]);
5325
 
        this.$modeId = path;
5326
 
        config.loadModule(["mode", path], function(m) {
5327
 
            if (this.$modeId !== path)
5328
 
                return;
5329
 
            if (this.$modes[path] && !options)
5330
 
                return this.$onChangeMode(this.$modes[path]);
5331
 
            if (m && m.Mode) {
5332
 
                m = new m.Mode(options);
5333
 
                if (!options) {
5334
 
                    this.$modes[path] = m;
5335
 
                    m.$id = path;
5336
 
                }
5337
 
                this.$onChangeMode(m)
5338
 
            }
5339
 
        }.bind(this));
5340
 
        if (!this.$mode)
5341
 
            this.$onChangeMode(this.$modes["ace/mode/text"], true);
5342
 
    };
5343
 
 
5344
 
    this.$onChangeMode = function(mode, $isPlaceholder) {
5345
 
        if (this.$mode === mode) return;
5346
 
        this.$mode = mode;
5347
 
 
5348
 
        this.$stopWorker();
5349
 
 
5350
 
        if (this.$useWorker)
5351
 
            this.$startWorker();
5352
 
 
5353
 
        var tokenizer = mode.getTokenizer();
5354
 
 
5355
 
        if(tokenizer.addEventListener !== undefined) {
5356
 
            var onReloadTokenizer = this.onReloadTokenizer.bind(this);
5357
 
            tokenizer.addEventListener("update", onReloadTokenizer);
5358
 
        }
5359
 
 
5360
 
        if (!this.bgTokenizer) {
5361
 
            this.bgTokenizer = new BackgroundTokenizer(tokenizer);
5362
 
            var _self = this;
5363
 
            this.bgTokenizer.addEventListener("update", function(e) {
5364
 
                _self._emit("tokenizerUpdate", e);
5365
 
            });
5366
 
        } else {
5367
 
            this.bgTokenizer.setTokenizer(tokenizer);
5368
 
        }
5369
 
 
5370
 
        this.bgTokenizer.setDocument(this.getDocument());
5371
 
 
5372
 
        this.tokenRe = mode.tokenRe;
5373
 
        this.nonTokenRe = mode.nonTokenRe;
5374
 
 
5375
 
 
5376
 
        if (!$isPlaceholder) {
5377
 
            this.$modeId = mode.$id;
5378
 
            this.$setFolding(mode.foldingRules);
5379
 
            this._emit("changeMode");
5380
 
            this.bgTokenizer.start(0);
5381
 
        }
5382
 
    };
5383
 
 
5384
 
 
5385
 
    this.$stopWorker = function() {
5386
 
        if (this.$worker)
5387
 
            this.$worker.terminate();
5388
 
 
5389
 
        this.$worker = null;
5390
 
    };
5391
 
 
5392
 
    this.$startWorker = function() {
5393
 
        if (typeof Worker !== "undefined" && !require.noWorker) {
5394
 
            try {
5395
 
                this.$worker = this.$mode.createWorker(this);
5396
 
            } catch (e) {
5397
 
                console.log("Could not load worker");
5398
 
                console.log(e);
5399
 
                this.$worker = null;
5400
 
            }
5401
 
        }
5402
 
        else
5403
 
            this.$worker = null;
5404
 
    };
5405
 
    this.getMode = function() {
5406
 
        return this.$mode;
5407
 
    };
5408
 
 
5409
 
    this.$scrollTop = 0;
5410
 
    this.setScrollTop = function(scrollTop) {
5411
 
        scrollTop = Math.round(Math.max(0, scrollTop));
5412
 
        if (this.$scrollTop === scrollTop || isNaN(scrollTop))
5413
 
            return;
5414
 
 
5415
 
        this.$scrollTop = scrollTop;
5416
 
        this._signal("changeScrollTop", scrollTop);
5417
 
    };
5418
 
    this.getScrollTop = function() {
5419
 
        return this.$scrollTop;
5420
 
    };
5421
 
 
5422
 
    this.$scrollLeft = 0;
5423
 
    this.setScrollLeft = function(scrollLeft) {
5424
 
        scrollLeft = Math.round(Math.max(0, scrollLeft));
5425
 
        if (this.$scrollLeft === scrollLeft || isNaN(scrollLeft))
5426
 
            return;
5427
 
 
5428
 
        this.$scrollLeft = scrollLeft;
5429
 
        this._signal("changeScrollLeft", scrollLeft);
5430
 
    };
5431
 
    this.getScrollLeft = function() {
5432
 
        return this.$scrollLeft;
5433
 
    };
5434
 
    this.getScreenWidth = function() {
5435
 
        this.$computeWidth();
5436
 
        return this.screenWidth;
5437
 
    };
5438
 
 
5439
 
    this.$computeWidth = function(force) {
5440
 
        if (this.$modified || force) {
5441
 
            this.$modified = false;
5442
 
 
5443
 
            if (this.$useWrapMode)
5444
 
                return this.screenWidth = this.$wrapLimit;
5445
 
 
5446
 
            var lines = this.doc.getAllLines();
5447
 
            var cache = this.$rowLengthCache;
5448
 
            var longestScreenLine = 0;
5449
 
            var foldIndex = 0;
5450
 
            var foldLine = this.$foldData[foldIndex];
5451
 
            var foldStart = foldLine ? foldLine.start.row : Infinity;
5452
 
            var len = lines.length;
5453
 
 
5454
 
            for (var i = 0; i < len; i++) {
5455
 
                if (i > foldStart) {
5456
 
                    i = foldLine.end.row + 1;
5457
 
                    if (i >= len)
5458
 
                        break;
5459
 
                    foldLine = this.$foldData[foldIndex++];
5460
 
                    foldStart = foldLine ? foldLine.start.row : Infinity;
5461
 
                }
5462
 
 
5463
 
                if (cache[i] == null)
5464
 
                    cache[i] = this.$getStringScreenWidth(lines[i])[0];
5465
 
 
5466
 
                if (cache[i] > longestScreenLine)
5467
 
                    longestScreenLine = cache[i];
5468
 
            }
5469
 
            this.screenWidth = longestScreenLine;
5470
 
        }
5471
 
    };
5472
 
    this.getLine = function(row) {
5473
 
        return this.doc.getLine(row);
5474
 
    };
5475
 
    this.getLines = function(firstRow, lastRow) {
5476
 
        return this.doc.getLines(firstRow, lastRow);
5477
 
    };
5478
 
    this.getLength = function() {
5479
 
        return this.doc.getLength();
5480
 
    };
5481
 
    this.getTextRange = function(range) {
5482
 
        return this.doc.getTextRange(range || this.selection.getRange());
5483
 
    };
5484
 
    this.insert = function(position, text) {
5485
 
        return this.doc.insert(position, text);
5486
 
    };
5487
 
    this.remove = function(range) {
5488
 
        return this.doc.remove(range);
5489
 
    };
5490
 
    this.undoChanges = function(deltas, dontSelect) {
5491
 
        if (!deltas.length)
5492
 
            return;
5493
 
 
5494
 
        this.$fromUndo = true;
5495
 
        var lastUndoRange = null;
5496
 
        for (var i = deltas.length - 1; i != -1; i--) {
5497
 
            var delta = deltas[i];
5498
 
            if (delta.group == "doc") {
5499
 
                this.doc.revertDeltas(delta.deltas);
5500
 
                lastUndoRange =
5501
 
                    this.$getUndoSelection(delta.deltas, true, lastUndoRange);
5502
 
            } else {
5503
 
                delta.deltas.forEach(function(foldDelta) {
5504
 
                    this.addFolds(foldDelta.folds);
5505
 
                }, this);
5506
 
            }
5507
 
        }
5508
 
        this.$fromUndo = false;
5509
 
        lastUndoRange &&
5510
 
            this.$undoSelect &&
5511
 
            !dontSelect &&
5512
 
            this.selection.setSelectionRange(lastUndoRange);
5513
 
        return lastUndoRange;
5514
 
    };
5515
 
    this.redoChanges = function(deltas, dontSelect) {
5516
 
        if (!deltas.length)
5517
 
            return;
5518
 
 
5519
 
        this.$fromUndo = true;
5520
 
        var lastUndoRange = null;
5521
 
        for (var i = 0; i < deltas.length; i++) {
5522
 
            var delta = deltas[i];
5523
 
            if (delta.group == "doc") {
5524
 
                this.doc.applyDeltas(delta.deltas);
5525
 
                lastUndoRange =
5526
 
                    this.$getUndoSelection(delta.deltas, false, lastUndoRange);
5527
 
            }
5528
 
        }
5529
 
        this.$fromUndo = false;
5530
 
        lastUndoRange &&
5531
 
            this.$undoSelect &&
5532
 
            !dontSelect &&
5533
 
            this.selection.setSelectionRange(lastUndoRange);
5534
 
        return lastUndoRange;
5535
 
    };
5536
 
    this.setUndoSelect = function(enable) {
5537
 
        this.$undoSelect = enable;
5538
 
    };
5539
 
 
5540
 
    this.$getUndoSelection = function(deltas, isUndo, lastUndoRange) {
5541
 
        function isInsert(delta) {
5542
 
            var insert =
5543
 
                delta.action === "insertText" || delta.action === "insertLines";
5544
 
            return isUndo ? !insert : insert;
5545
 
        }
5546
 
 
5547
 
        var delta = deltas[0];
5548
 
        var range, point;
5549
 
        var lastDeltaIsInsert = false;
5550
 
        if (isInsert(delta)) {
5551
 
            range = delta.range.clone();
5552
 
            lastDeltaIsInsert = true;
5553
 
        } else {
5554
 
            range = Range.fromPoints(delta.range.start, delta.range.start);
5555
 
            lastDeltaIsInsert = false;
5556
 
        }
5557
 
 
5558
 
        for (var i = 1; i < deltas.length; i++) {
5559
 
            delta = deltas[i];
5560
 
            if (isInsert(delta)) {
5561
 
                point = delta.range.start;
5562
 
                if (range.compare(point.row, point.column) == -1) {
5563
 
                    range.setStart(delta.range.start);
5564
 
                }
5565
 
                point = delta.range.end;
5566
 
                if (range.compare(point.row, point.column) == 1) {
5567
 
                    range.setEnd(delta.range.end);
5568
 
                }
5569
 
                lastDeltaIsInsert = true;
5570
 
            } else {
5571
 
                point = delta.range.start;
5572
 
                if (range.compare(point.row, point.column) == -1) {
5573
 
                    range =
5574
 
                        Range.fromPoints(delta.range.start, delta.range.start);
5575
 
                }
5576
 
                lastDeltaIsInsert = false;
5577
 
            }
5578
 
        }
5579
 
        if (lastUndoRange != null) {
5580
 
            var cmp = lastUndoRange.compareRange(range);
5581
 
            if (cmp == 1) {
5582
 
                range.setStart(lastUndoRange.start);
5583
 
            } else if (cmp == -1) {
5584
 
                range.setEnd(lastUndoRange.end);
5585
 
            }
5586
 
        }
5587
 
 
5588
 
        return range;
5589
 
    };
5590
 
    this.replace = function(range, text) {
5591
 
        return this.doc.replace(range, text);
5592
 
    };
5593
 
    this.moveText = function(fromRange, toPosition, copy) {
5594
 
        var text = this.getTextRange(fromRange);
5595
 
        var folds = this.getFoldsInRange(fromRange);
5596
 
 
5597
 
        var toRange = Range.fromPoints(toPosition, toPosition);
5598
 
        if (!copy) {
5599
 
            this.remove(fromRange);
5600
 
            var rowDiff = fromRange.start.row - fromRange.end.row;
5601
 
            var collDiff = rowDiff ? -fromRange.end.column : fromRange.start.column - fromRange.end.column;
5602
 
            if (collDiff) {
5603
 
                if (toRange.start.row == fromRange.end.row && toRange.start.column > fromRange.end.column)
5604
 
                    toRange.start.column += collDiff;
5605
 
                if (toRange.end.row == fromRange.end.row && toRange.end.column > fromRange.end.column)
5606
 
                    toRange.end.column += collDiff;
5607
 
            }
5608
 
            if (rowDiff && toRange.start.row >= fromRange.end.row) {
5609
 
                toRange.start.row += rowDiff;
5610
 
                toRange.end.row += rowDiff;
5611
 
            }
5612
 
        }
5613
 
 
5614
 
        this.insert(toRange.start, text);
5615
 
        if (folds.length) {
5616
 
            var oldStart = fromRange.start;
5617
 
            var newStart = toRange.start;
5618
 
            var rowDiff = newStart.row - oldStart.row;
5619
 
            var collDiff = newStart.column - oldStart.column;
5620
 
            this.addFolds(folds.map(function(x) {
5621
 
                x = x.clone();
5622
 
                if (x.start.row == oldStart.row)
5623
 
                    x.start.column += collDiff;
5624
 
                if (x.end.row == oldStart.row)
5625
 
                    x.end.column += collDiff;
5626
 
                x.start.row += rowDiff;
5627
 
                x.end.row += rowDiff;
5628
 
                return x;
5629
 
            }));
5630
 
        }
5631
 
 
5632
 
        return toRange;
5633
 
    };
5634
 
    this.indentRows = function(startRow, endRow, indentString) {
5635
 
        indentString = indentString.replace(/\t/g, this.getTabString());
5636
 
        for (var row=startRow; row<=endRow; row++)
5637
 
            this.insert({row: row, column:0}, indentString);
5638
 
    };
5639
 
    this.outdentRows = function (range) {
5640
 
        var rowRange = range.collapseRows();
5641
 
        var deleteRange = new Range(0, 0, 0, 0);
5642
 
        var size = this.getTabSize();
5643
 
 
5644
 
        for (var i = rowRange.start.row; i <= rowRange.end.row; ++i) {
5645
 
            var line = this.getLine(i);
5646
 
 
5647
 
            deleteRange.start.row = i;
5648
 
            deleteRange.end.row = i;
5649
 
            for (var j = 0; j < size; ++j)
5650
 
                if (line.charAt(j) != ' ')
5651
 
                    break;
5652
 
            if (j < size && line.charAt(j) == '\t') {
5653
 
                deleteRange.start.column = j;
5654
 
                deleteRange.end.column = j + 1;
5655
 
            } else {
5656
 
                deleteRange.start.column = 0;
5657
 
                deleteRange.end.column = j;
5658
 
            }
5659
 
            this.remove(deleteRange);
5660
 
        }
5661
 
    };
5662
 
 
5663
 
    this.$moveLines = function(firstRow, lastRow, dir) {
5664
 
        firstRow = this.getRowFoldStart(firstRow);
5665
 
        lastRow = this.getRowFoldEnd(lastRow);
5666
 
        if (dir < 0) {
5667
 
            var row = this.getRowFoldStart(firstRow + dir);
5668
 
            if (row < 0) return 0;
5669
 
            var diff = row-firstRow;
5670
 
        } else if (dir > 0) {
5671
 
            var row = this.getRowFoldEnd(lastRow + dir);
5672
 
            if (row > this.doc.getLength()-1) return 0;
5673
 
            var diff = row-lastRow;
5674
 
        } else {
5675
 
            firstRow = this.$clipRowToDocument(firstRow);
5676
 
            lastRow = this.$clipRowToDocument(lastRow);
5677
 
            var diff = lastRow - firstRow + 1;
5678
 
        }
5679
 
 
5680
 
        var range = new Range(firstRow, 0, lastRow, Number.MAX_VALUE);
5681
 
        var folds = this.getFoldsInRange(range).map(function(x){
5682
 
            x = x.clone();
5683
 
            x.start.row += diff;
5684
 
            x.end.row += diff;
5685
 
            return x;
5686
 
        });
5687
 
 
5688
 
        var lines = dir == 0
5689
 
            ? this.doc.getLines(firstRow, lastRow)
5690
 
            : this.doc.removeLines(firstRow, lastRow);
5691
 
        this.doc.insertLines(firstRow+diff, lines);
5692
 
        folds.length && this.addFolds(folds);
5693
 
        return diff;
5694
 
    };
5695
 
    this.moveLinesUp = function(firstRow, lastRow) {
5696
 
        return this.$moveLines(firstRow, lastRow, -1);
5697
 
    };
5698
 
    this.moveLinesDown = function(firstRow, lastRow) {
5699
 
        return this.$moveLines(firstRow, lastRow, 1);
5700
 
    };
5701
 
    this.duplicateLines = function(firstRow, lastRow) {
5702
 
        return this.$moveLines(firstRow, lastRow, 0);
5703
 
    };
5704
 
 
5705
 
 
5706
 
    this.$clipRowToDocument = function(row) {
5707
 
        return Math.max(0, Math.min(row, this.doc.getLength()-1));
5708
 
    };
5709
 
 
5710
 
    this.$clipColumnToRow = function(row, column) {
5711
 
        if (column < 0)
5712
 
            return 0;
5713
 
        return Math.min(this.doc.getLine(row).length, column);
5714
 
    };
5715
 
 
5716
 
 
5717
 
    this.$clipPositionToDocument = function(row, column) {
5718
 
        column = Math.max(0, column);
5719
 
 
5720
 
        if (row < 0) {
5721
 
            row = 0;
5722
 
            column = 0;
5723
 
        } else {
5724
 
            var len = this.doc.getLength();
5725
 
            if (row >= len) {
5726
 
                row = len - 1;
5727
 
                column = this.doc.getLine(len-1).length;
5728
 
            } else {
5729
 
                column = Math.min(this.doc.getLine(row).length, column);
5730
 
            }
5731
 
        }
5732
 
 
5733
 
        return {
5734
 
            row: row,
5735
 
            column: column
5736
 
        };
5737
 
    };
5738
 
 
5739
 
    this.$clipRangeToDocument = function(range) {
5740
 
        if (range.start.row < 0) {
5741
 
            range.start.row = 0;
5742
 
            range.start.column = 0;
5743
 
        } else {
5744
 
            range.start.column = this.$clipColumnToRow(
5745
 
                range.start.row,
5746
 
                range.start.column
5747
 
            );
5748
 
        }
5749
 
 
5750
 
        var len = this.doc.getLength() - 1;
5751
 
        if (range.end.row > len) {
5752
 
            range.end.row = len;
5753
 
            range.end.column = this.doc.getLine(len).length;
5754
 
        } else {
5755
 
            range.end.column = this.$clipColumnToRow(
5756
 
                range.end.row,
5757
 
                range.end.column
5758
 
            );
5759
 
        }
5760
 
        return range;
5761
 
    };
5762
 
    this.$wrapLimit = 80;
5763
 
    this.$useWrapMode = false;
5764
 
    this.$wrapLimitRange = {
5765
 
        min : null,
5766
 
        max : null
5767
 
    };
5768
 
    this.setUseWrapMode = function(useWrapMode) {
5769
 
        if (useWrapMode != this.$useWrapMode) {
5770
 
            this.$useWrapMode = useWrapMode;
5771
 
            this.$modified = true;
5772
 
            this.$resetRowCache(0);
5773
 
            if (useWrapMode) {
5774
 
                var len = this.getLength();
5775
 
                this.$wrapData = [];
5776
 
                for (var i = 0; i < len; i++) {
5777
 
                    this.$wrapData.push([]);
5778
 
                }
5779
 
                this.$updateWrapData(0, len - 1);
5780
 
            }
5781
 
 
5782
 
            this._emit("changeWrapMode");
5783
 
        }
5784
 
    };
5785
 
    this.getUseWrapMode = function() {
5786
 
        return this.$useWrapMode;
5787
 
    };
5788
 
    this.setWrapLimitRange = function(min, max) {
5789
 
        if (this.$wrapLimitRange.min !== min || this.$wrapLimitRange.max !== max) {
5790
 
            this.$wrapLimitRange.min = min;
5791
 
            this.$wrapLimitRange.max = max;
5792
 
            this.$modified = true;
5793
 
            this._emit("changeWrapMode");
5794
 
        }
5795
 
    };
5796
 
    this.adjustWrapLimit = function(desiredLimit) {
5797
 
        var wrapLimit = this.$constrainWrapLimit(desiredLimit);
5798
 
        if (wrapLimit != this.$wrapLimit && wrapLimit > 0) {
5799
 
            this.$wrapLimit = wrapLimit;
5800
 
            this.$modified = true;
5801
 
            if (this.$useWrapMode) {
5802
 
                this.$updateWrapData(0, this.getLength() - 1);
5803
 
                this.$resetRowCache(0);
5804
 
                this._emit("changeWrapLimit");
5805
 
            }
5806
 
            return true;
5807
 
        }
5808
 
        return false;
5809
 
    };
5810
 
 
5811
 
    this.$constrainWrapLimit = function(wrapLimit) {
5812
 
        var min = this.$wrapLimitRange.min;
5813
 
        if (min)
5814
 
            wrapLimit = Math.max(min, wrapLimit);
5815
 
 
5816
 
        var max = this.$wrapLimitRange.max;
5817
 
        if (max)
5818
 
            wrapLimit = Math.min(max, wrapLimit);
5819
 
        return Math.max(1, wrapLimit);
5820
 
    };
5821
 
    this.getWrapLimit = function() {
5822
 
        return this.$wrapLimit;
5823
 
    };
5824
 
    this.getWrapLimitRange = function() {
5825
 
        return {
5826
 
            min : this.$wrapLimitRange.min,
5827
 
            max : this.$wrapLimitRange.max
5828
 
        };
5829
 
    };
5830
 
 
5831
 
    this.$updateInternalDataOnChange = function(e) {
5832
 
        var useWrapMode = this.$useWrapMode;
5833
 
        var len;
5834
 
        var action = e.data.action;
5835
 
        var firstRow = e.data.range.start.row;
5836
 
        var lastRow = e.data.range.end.row;
5837
 
        var start = e.data.range.start;
5838
 
        var end = e.data.range.end;
5839
 
        var removedFolds = null;
5840
 
 
5841
 
        if (action.indexOf("Lines") != -1) {
5842
 
            if (action == "insertLines") {
5843
 
                lastRow = firstRow + (e.data.lines.length);
5844
 
            } else {
5845
 
                lastRow = firstRow;
5846
 
            }
5847
 
            len = e.data.lines ? e.data.lines.length : lastRow - firstRow;
5848
 
        } else {
5849
 
            len = lastRow - firstRow;
5850
 
        }
5851
 
 
5852
 
        if (len != 0) {
5853
 
            if (action.indexOf("remove") != -1) {
5854
 
                this[useWrapMode ? "$wrapData" : "$rowLengthCache"].splice(firstRow, len);
5855
 
 
5856
 
                var foldLines = this.$foldData;
5857
 
                removedFolds = this.getFoldsInRange(e.data.range);
5858
 
                this.removeFolds(removedFolds);
5859
 
 
5860
 
                var foldLine = this.getFoldLine(end.row);
5861
 
                var idx = 0;
5862
 
                if (foldLine) {
5863
 
                    foldLine.addRemoveChars(end.row, end.column, start.column - end.column);
5864
 
                    foldLine.shiftRow(-len);
5865
 
 
5866
 
                    var foldLineBefore = this.getFoldLine(firstRow);
5867
 
                    if (foldLineBefore && foldLineBefore !== foldLine) {
5868
 
                        foldLineBefore.merge(foldLine);
5869
 
                        foldLine = foldLineBefore;
5870
 
                    }
5871
 
                    idx = foldLines.indexOf(foldLine) + 1;
5872
 
                }
5873
 
 
5874
 
                for (idx; idx < foldLines.length; idx++) {
5875
 
                    var foldLine = foldLines[idx];
5876
 
                    if (foldLine.start.row >= end.row) {
5877
 
                        foldLine.shiftRow(-len);
5878
 
                    }
5879
 
                }
5880
 
 
5881
 
                lastRow = firstRow;
5882
 
            } else {
5883
 
                var args;
5884
 
                if (useWrapMode) {
5885
 
                    args = [firstRow, 0];
5886
 
                    for (var i = 0; i < len; i++) args.push([]);
5887
 
                    this.$wrapData.splice.apply(this.$wrapData, args);
5888
 
                } else {
5889
 
                    args = Array(len);
5890
 
                    args.unshift(firstRow, 0);
5891
 
                    this.$rowLengthCache.splice.apply(this.$rowLengthCache, args);
5892
 
                }
5893
 
                var foldLines = this.$foldData;
5894
 
                var foldLine = this.getFoldLine(firstRow);
5895
 
                var idx = 0;
5896
 
                if (foldLine) {
5897
 
                    var cmp = foldLine.range.compareInside(start.row, start.column)
5898
 
                    if (cmp == 0) {
5899
 
                        foldLine = foldLine.split(start.row, start.column);
5900
 
                        foldLine.shiftRow(len);
5901
 
                        foldLine.addRemoveChars(
5902
 
                            lastRow, 0, end.column - start.column);
5903
 
                    } else
5904
 
                    if (cmp == -1) {
5905
 
                        foldLine.addRemoveChars(firstRow, 0, end.column - start.column);
5906
 
                        foldLine.shiftRow(len);
5907
 
                    }
5908
 
                    idx = foldLines.indexOf(foldLine) + 1;
5909
 
                }
5910
 
 
5911
 
                for (idx; idx < foldLines.length; idx++) {
5912
 
                    var foldLine = foldLines[idx];
5913
 
                    if (foldLine.start.row >= firstRow) {
5914
 
                        foldLine.shiftRow(len);
5915
 
                    }
5916
 
                }
5917
 
            }
5918
 
        } else {
5919
 
            len = Math.abs(e.data.range.start.column - e.data.range.end.column);
5920
 
            if (action.indexOf("remove") != -1) {
5921
 
                removedFolds = this.getFoldsInRange(e.data.range);
5922
 
                this.removeFolds(removedFolds);
5923
 
 
5924
 
                len = -len;
5925
 
            }
5926
 
            var foldLine = this.getFoldLine(firstRow);
5927
 
            if (foldLine) {
5928
 
                foldLine.addRemoveChars(firstRow, start.column, len);
5929
 
            }
5930
 
        }
5931
 
 
5932
 
        if (useWrapMode && this.$wrapData.length != this.doc.getLength()) {
5933
 
            console.error("doc.getLength() and $wrapData.length have to be the same!");
5934
 
        }
5935
 
 
5936
 
        if (useWrapMode)
5937
 
            this.$updateWrapData(firstRow, lastRow);
5938
 
        else
5939
 
            this.$updateRowLengthCache(firstRow, lastRow);
5940
 
 
5941
 
        return removedFolds;
5942
 
    };
5943
 
 
5944
 
    this.$updateRowLengthCache = function(firstRow, lastRow, b) {
5945
 
        this.$rowLengthCache[firstRow] = null;
5946
 
        this.$rowLengthCache[lastRow] = null;
5947
 
    };
5948
 
 
5949
 
    this.$updateWrapData = function(firstRow, lastRow) {
5950
 
        var lines = this.doc.getAllLines();
5951
 
        var tabSize = this.getTabSize();
5952
 
        var wrapData = this.$wrapData;
5953
 
        var wrapLimit = this.$wrapLimit;
5954
 
        var tokens;
5955
 
        var foldLine;
5956
 
 
5957
 
        var row = firstRow;
5958
 
        lastRow = Math.min(lastRow, lines.length - 1);
5959
 
        while (row <= lastRow) {
5960
 
            foldLine = this.getFoldLine(row, foldLine);
5961
 
            if (!foldLine) {
5962
 
                tokens = this.$getDisplayTokens(lang.stringTrimRight(lines[row]));
5963
 
                wrapData[row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize);
5964
 
                row ++;
5965
 
            } else {
5966
 
                tokens = [];
5967
 
                foldLine.walk(function(placeholder, row, column, lastColumn) {
5968
 
                        var walkTokens;
5969
 
                        if (placeholder != null) {
5970
 
                            walkTokens = this.$getDisplayTokens(
5971
 
                                            placeholder, tokens.length);
5972
 
                            walkTokens[0] = PLACEHOLDER_START;
5973
 
                            for (var i = 1; i < walkTokens.length; i++) {
5974
 
                                walkTokens[i] = PLACEHOLDER_BODY;
5975
 
                            }
5976
 
                        } else {
5977
 
                            walkTokens = this.$getDisplayTokens(
5978
 
                                lines[row].substring(lastColumn, column),
5979
 
                                tokens.length);
5980
 
                        }
5981
 
                        tokens = tokens.concat(walkTokens);
5982
 
                    }.bind(this),
5983
 
                    foldLine.end.row,
5984
 
                    lines[foldLine.end.row].length + 1
5985
 
                );
5986
 
                while (tokens.length != 0 && tokens[tokens.length - 1] >= SPACE)
5987
 
                    tokens.pop();
5988
 
 
5989
 
                wrapData[foldLine.start.row]
5990
 
                    = this.$computeWrapSplits(tokens, wrapLimit, tabSize);
5991
 
                row = foldLine.end.row + 1;
5992
 
            }
5993
 
        }
5994
 
    };
5995
 
    var CHAR = 1,
5996
 
        CHAR_EXT = 2,
5997
 
        PLACEHOLDER_START = 3,
5998
 
        PLACEHOLDER_BODY =  4,
5999
 
        PUNCTUATION = 9,
6000
 
        SPACE = 10,
6001
 
        TAB = 11,
6002
 
        TAB_SPACE = 12;
6003
 
 
6004
 
 
6005
 
    this.$computeWrapSplits = function(tokens, wrapLimit) {
6006
 
        if (tokens.length == 0) {
6007
 
            return [];
6008
 
        }
6009
 
 
6010
 
        var splits = [];
6011
 
        var displayLength = tokens.length;
6012
 
        var lastSplit = 0, lastDocSplit = 0;
6013
 
 
6014
 
        function addSplit(screenPos) {
6015
 
            var displayed = tokens.slice(lastSplit, screenPos);
6016
 
            var len = displayed.length;
6017
 
            displayed.join("").
6018
 
                replace(/12/g, function() {
6019
 
                    len -= 1;
6020
 
                }).
6021
 
                replace(/2/g, function() {
6022
 
                    len -= 1;
6023
 
                });
6024
 
 
6025
 
            lastDocSplit += len;
6026
 
            splits.push(lastDocSplit);
6027
 
            lastSplit = screenPos;
6028
 
        }
6029
 
 
6030
 
        while (displayLength - lastSplit > wrapLimit) {
6031
 
            var split = lastSplit + wrapLimit;
6032
 
            if (tokens[split] >= SPACE) {
6033
 
                while (tokens[split] >= SPACE) {
6034
 
                    split ++;
6035
 
                }
6036
 
                addSplit(split);
6037
 
                continue;
6038
 
            }
6039
 
            if (tokens[split] == PLACEHOLDER_START
6040
 
                || tokens[split] == PLACEHOLDER_BODY)
6041
 
            {
6042
 
                for (split; split != lastSplit - 1; split--) {
6043
 
                    if (tokens[split] == PLACEHOLDER_START) {
6044
 
                        break;
6045
 
                    }
6046
 
                }
6047
 
                if (split > lastSplit) {
6048
 
                    addSplit(split);
6049
 
                    continue;
6050
 
                }
6051
 
                split = lastSplit + wrapLimit;
6052
 
                for (split; split < tokens.length; split++) {
6053
 
                    if (tokens[split] != PLACEHOLDER_BODY)
6054
 
                    {
6055
 
                        break;
6056
 
                    }
6057
 
                }
6058
 
                if (split == tokens.length) {
6059
 
                    break;  // Breaks the while-loop.
6060
 
                }
6061
 
                addSplit(split);
6062
 
                continue;
6063
 
            }
6064
 
            var minSplit = Math.max(split - 10, lastSplit - 1);
6065
 
            while (split > minSplit && tokens[split] < PLACEHOLDER_START) {
6066
 
                split --;
6067
 
            }
6068
 
            while (split > minSplit && tokens[split] == PUNCTUATION) {
6069
 
                split --;
6070
 
            }
6071
 
            if (split > minSplit) {
6072
 
                addSplit(++split);
6073
 
                continue;
6074
 
            }
6075
 
            split = lastSplit + wrapLimit;
6076
 
            addSplit(split);
6077
 
        }
6078
 
        return splits;
6079
 
    };
6080
 
    this.$getDisplayTokens = function(str, offset) {
6081
 
        var arr = [];
6082
 
        var tabSize;
6083
 
        offset = offset || 0;
6084
 
 
6085
 
        for (var i = 0; i < str.length; i++) {
6086
 
            var c = str.charCodeAt(i);
6087
 
            if (c == 9) {
6088
 
                tabSize = this.getScreenTabSize(arr.length + offset);
6089
 
                arr.push(TAB);
6090
 
                for (var n = 1; n < tabSize; n++) {
6091
 
                    arr.push(TAB_SPACE);
6092
 
                }
6093
 
            }
6094
 
            else if (c == 32) {
6095
 
                arr.push(SPACE);
6096
 
            } else if((c > 39 && c < 48) || (c > 57 && c < 64)) {
6097
 
                arr.push(PUNCTUATION);
6098
 
            }
6099
 
            else if (c >= 0x1100 && isFullWidth(c)) {
6100
 
                arr.push(CHAR, CHAR_EXT);
6101
 
            } else {
6102
 
                arr.push(CHAR);
6103
 
            }
6104
 
        }
6105
 
        return arr;
6106
 
    };
6107
 
    this.$getStringScreenWidth = function(str, maxScreenColumn, screenColumn) {
6108
 
        if (maxScreenColumn == 0)
6109
 
            return [0, 0];
6110
 
        if (maxScreenColumn == null)
6111
 
            maxScreenColumn = Infinity;
6112
 
        screenColumn = screenColumn || 0;
6113
 
 
6114
 
        var c, column;
6115
 
        for (column = 0; column < str.length; column++) {
6116
 
            c = str.charCodeAt(column);
6117
 
            if (c == 9) {
6118
 
                screenColumn += this.getScreenTabSize(screenColumn);
6119
 
            }
6120
 
            else if (c >= 0x1100 && isFullWidth(c)) {
6121
 
                screenColumn += 2;
6122
 
            } else {
6123
 
                screenColumn += 1;
6124
 
            }
6125
 
            if (screenColumn > maxScreenColumn) {
6126
 
                break;
6127
 
            }
6128
 
        }
6129
 
 
6130
 
        return [screenColumn, column];
6131
 
    };
6132
 
    this.getRowLength = function(row) {
6133
 
        if (!this.$useWrapMode || !this.$wrapData[row]) {
6134
 
            return 1;
6135
 
        } else {
6136
 
            return this.$wrapData[row].length + 1;
6137
 
        }
6138
 
    };
6139
 
    this.getScreenLastRowColumn = function(screenRow) {
6140
 
        var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE);
6141
 
        return this.documentToScreenColumn(pos.row, pos.column);
6142
 
    };
6143
 
    this.getDocumentLastRowColumn = function(docRow, docColumn) {
6144
 
        var screenRow = this.documentToScreenRow(docRow, docColumn);
6145
 
        return this.getScreenLastRowColumn(screenRow);
6146
 
    };
6147
 
    this.getDocumentLastRowColumnPosition = function(docRow, docColumn) {
6148
 
        var screenRow = this.documentToScreenRow(docRow, docColumn);
6149
 
        return this.screenToDocumentPosition(screenRow, Number.MAX_VALUE / 10);
6150
 
    };
6151
 
    this.getRowSplitData = function(row) {
6152
 
        if (!this.$useWrapMode) {
6153
 
            return undefined;
6154
 
        } else {
6155
 
            return this.$wrapData[row];
6156
 
        }
6157
 
    };
6158
 
    this.getScreenTabSize = function(screenColumn) {
6159
 
        return this.$tabSize - screenColumn % this.$tabSize;
6160
 
    };
6161
 
 
6162
 
 
6163
 
    this.screenToDocumentRow = function(screenRow, screenColumn) {
6164
 
        return this.screenToDocumentPosition(screenRow, screenColumn).row;
6165
 
    };
6166
 
 
6167
 
 
6168
 
    this.screenToDocumentColumn = function(screenRow, screenColumn) {
6169
 
        return this.screenToDocumentPosition(screenRow, screenColumn).column;
6170
 
    };
6171
 
    this.screenToDocumentPosition = function(screenRow, screenColumn) {
6172
 
        if (screenRow < 0)
6173
 
            return {row: 0, column: 0};
6174
 
 
6175
 
        var line;
6176
 
        var docRow = 0;
6177
 
        var docColumn = 0;
6178
 
        var column;
6179
 
        var row = 0;
6180
 
        var rowLength = 0;
6181
 
 
6182
 
        var rowCache = this.$screenRowCache;
6183
 
        var i = this.$getRowCacheIndex(rowCache, screenRow);
6184
 
        var l = rowCache.length;
6185
 
        if (l && i >= 0) {
6186
 
            var row = rowCache[i];
6187
 
            var docRow = this.$docRowCache[i];
6188
 
            var doCache = screenRow > rowCache[l - 1];
6189
 
        } else {
6190
 
            var doCache = !l;
6191
 
        }
6192
 
 
6193
 
        var maxRow = this.getLength() - 1;
6194
 
        var foldLine = this.getNextFoldLine(docRow);
6195
 
        var foldStart = foldLine ? foldLine.start.row : Infinity;
6196
 
 
6197
 
        while (row <= screenRow) {
6198
 
            rowLength = this.getRowLength(docRow);
6199
 
            if (row + rowLength - 1 >= screenRow || docRow >= maxRow) {
6200
 
                break;
6201
 
            } else {
6202
 
                row += rowLength;
6203
 
                docRow++;
6204
 
                if (docRow > foldStart) {
6205
 
                    docRow = foldLine.end.row+1;
6206
 
                    foldLine = this.getNextFoldLine(docRow, foldLine);
6207
 
                    foldStart = foldLine ? foldLine.start.row : Infinity;
6208
 
                }
6209
 
            }
6210
 
 
6211
 
            if (doCache) {
6212
 
                this.$docRowCache.push(docRow);
6213
 
                this.$screenRowCache.push(row);
6214
 
            }
6215
 
        }
6216
 
 
6217
 
        if (foldLine && foldLine.start.row <= docRow) {
6218
 
            line = this.getFoldDisplayLine(foldLine);
6219
 
            docRow = foldLine.start.row;
6220
 
        } else if (row + rowLength <= screenRow || docRow > maxRow) {
6221
 
            return {
6222
 
                row: maxRow,
6223
 
                column: this.getLine(maxRow).length
6224
 
            }
6225
 
        } else {
6226
 
            line = this.getLine(docRow);
6227
 
            foldLine = null;
6228
 
        }
6229
 
 
6230
 
        if (this.$useWrapMode) {
6231
 
            var splits = this.$wrapData[docRow];
6232
 
            if (splits) {
6233
 
                column = splits[screenRow - row];
6234
 
                if(screenRow > row && splits.length) {
6235
 
                    docColumn = splits[screenRow - row - 1] || splits[splits.length - 1];
6236
 
                    line = line.substring(docColumn);
6237
 
                }
6238
 
            }
6239
 
        }
6240
 
 
6241
 
        docColumn += this.$getStringScreenWidth(line, screenColumn)[1];
6242
 
        if (this.$useWrapMode && docColumn >= column)
6243
 
            docColumn = column - 1;
6244
 
 
6245
 
        if (foldLine)
6246
 
            return foldLine.idxToPosition(docColumn);
6247
 
 
6248
 
        return {row: docRow, column: docColumn};
6249
 
    };
6250
 
    this.documentToScreenPosition = function(docRow, docColumn) {
6251
 
        if (typeof docColumn === "undefined")
6252
 
            var pos = this.$clipPositionToDocument(docRow.row, docRow.column);
6253
 
        else
6254
 
            pos = this.$clipPositionToDocument(docRow, docColumn);
6255
 
 
6256
 
        docRow = pos.row;
6257
 
        docColumn = pos.column;
6258
 
 
6259
 
        var screenRow = 0;
6260
 
        var foldStartRow = null;
6261
 
        var fold = null;
6262
 
        fold = this.getFoldAt(docRow, docColumn, 1);
6263
 
        if (fold) {
6264
 
            docRow = fold.start.row;
6265
 
            docColumn = fold.start.column;
6266
 
        }
6267
 
 
6268
 
        var rowEnd, row = 0;
6269
 
 
6270
 
 
6271
 
        var rowCache = this.$docRowCache;
6272
 
        var i = this.$getRowCacheIndex(rowCache, docRow);
6273
 
        var l = rowCache.length;
6274
 
        if (l && i >= 0) {
6275
 
            var row = rowCache[i];
6276
 
            var screenRow = this.$screenRowCache[i];
6277
 
            var doCache = docRow > rowCache[l - 1];
6278
 
        } else {
6279
 
            var doCache = !l;
6280
 
        }
6281
 
 
6282
 
        var foldLine = this.getNextFoldLine(row);
6283
 
        var foldStart = foldLine ?foldLine.start.row :Infinity;
6284
 
 
6285
 
        while (row < docRow) {
6286
 
            if (row >= foldStart) {
6287
 
                rowEnd = foldLine.end.row + 1;
6288
 
                if (rowEnd > docRow)
6289
 
                    break;
6290
 
                foldLine = this.getNextFoldLine(rowEnd, foldLine);
6291
 
                foldStart = foldLine ?foldLine.start.row :Infinity;
6292
 
            }
6293
 
            else {
6294
 
                rowEnd = row + 1;
6295
 
            }
6296
 
 
6297
 
            screenRow += this.getRowLength(row);
6298
 
            row = rowEnd;
6299
 
 
6300
 
            if (doCache) {
6301
 
                this.$docRowCache.push(row);
6302
 
                this.$screenRowCache.push(screenRow);
6303
 
            }
6304
 
        }
6305
 
        var textLine = "";
6306
 
        if (foldLine && row >= foldStart) {
6307
 
            textLine = this.getFoldDisplayLine(foldLine, docRow, docColumn);
6308
 
            foldStartRow = foldLine.start.row;
6309
 
        } else {
6310
 
            textLine = this.getLine(docRow).substring(0, docColumn);
6311
 
            foldStartRow = docRow;
6312
 
        }
6313
 
        if (this.$useWrapMode) {
6314
 
            var wrapRow = this.$wrapData[foldStartRow];
6315
 
            var screenRowOffset = 0;
6316
 
            while (textLine.length >= wrapRow[screenRowOffset]) {
6317
 
                screenRow ++;
6318
 
                screenRowOffset++;
6319
 
            }
6320
 
            textLine = textLine.substring(
6321
 
                wrapRow[screenRowOffset - 1] || 0, textLine.length
6322
 
            );
6323
 
        }
6324
 
 
6325
 
        return {
6326
 
            row: screenRow,
6327
 
            column: this.$getStringScreenWidth(textLine)[0]
6328
 
        };
6329
 
    };
6330
 
    this.documentToScreenColumn = function(row, docColumn) {
6331
 
        return this.documentToScreenPosition(row, docColumn).column;
6332
 
    };
6333
 
    this.documentToScreenRow = function(docRow, docColumn) {
6334
 
        return this.documentToScreenPosition(docRow, docColumn).row;
6335
 
    };
6336
 
    this.getScreenLength = function() {
6337
 
        var screenRows = 0;
6338
 
        var fold = null;
6339
 
        if (!this.$useWrapMode) {
6340
 
            screenRows = this.getLength();
6341
 
            var foldData = this.$foldData;
6342
 
            for (var i = 0; i < foldData.length; i++) {
6343
 
                fold = foldData[i];
6344
 
                screenRows -= fold.end.row - fold.start.row;
6345
 
            }
6346
 
        } else {
6347
 
            var lastRow = this.$wrapData.length;
6348
 
            var row = 0, i = 0;
6349
 
            var fold = this.$foldData[i++];
6350
 
            var foldStart = fold ? fold.start.row :Infinity;
6351
 
 
6352
 
            while (row < lastRow) {
6353
 
                screenRows += this.$wrapData[row].length + 1;
6354
 
                row ++;
6355
 
                if (row > foldStart) {
6356
 
                    row = fold.end.row+1;
6357
 
                    fold = this.$foldData[i++];
6358
 
                    foldStart = fold ?fold.start.row :Infinity;
6359
 
                }
6360
 
            }
6361
 
        }
6362
 
 
6363
 
        return screenRows;
6364
 
    };
6365
 
    function isFullWidth(c) {
6366
 
        if (c < 0x1100)
6367
 
            return false;
6368
 
        return c >= 0x1100 && c <= 0x115F ||
6369
 
               c >= 0x11A3 && c <= 0x11A7 ||
6370
 
               c >= 0x11FA && c <= 0x11FF ||
6371
 
               c >= 0x2329 && c <= 0x232A ||
6372
 
               c >= 0x2E80 && c <= 0x2E99 ||
6373
 
               c >= 0x2E9B && c <= 0x2EF3 ||
6374
 
               c >= 0x2F00 && c <= 0x2FD5 ||
6375
 
               c >= 0x2FF0 && c <= 0x2FFB ||
6376
 
               c >= 0x3000 && c <= 0x303E ||
6377
 
               c >= 0x3041 && c <= 0x3096 ||
6378
 
               c >= 0x3099 && c <= 0x30FF ||
6379
 
               c >= 0x3105 && c <= 0x312D ||
6380
 
               c >= 0x3131 && c <= 0x318E ||
6381
 
               c >= 0x3190 && c <= 0x31BA ||
6382
 
               c >= 0x31C0 && c <= 0x31E3 ||
6383
 
               c >= 0x31F0 && c <= 0x321E ||
6384
 
               c >= 0x3220 && c <= 0x3247 ||
6385
 
               c >= 0x3250 && c <= 0x32FE ||
6386
 
               c >= 0x3300 && c <= 0x4DBF ||
6387
 
               c >= 0x4E00 && c <= 0xA48C ||
6388
 
               c >= 0xA490 && c <= 0xA4C6 ||
6389
 
               c >= 0xA960 && c <= 0xA97C ||
6390
 
               c >= 0xAC00 && c <= 0xD7A3 ||
6391
 
               c >= 0xD7B0 && c <= 0xD7C6 ||
6392
 
               c >= 0xD7CB && c <= 0xD7FB ||
6393
 
               c >= 0xF900 && c <= 0xFAFF ||
6394
 
               c >= 0xFE10 && c <= 0xFE19 ||
6395
 
               c >= 0xFE30 && c <= 0xFE52 ||
6396
 
               c >= 0xFE54 && c <= 0xFE66 ||
6397
 
               c >= 0xFE68 && c <= 0xFE6B ||
6398
 
               c >= 0xFF01 && c <= 0xFF60 ||
6399
 
               c >= 0xFFE0 && c <= 0xFFE6;
6400
 
    };
6401
 
 
6402
 
}).call(EditSession.prototype);
6403
 
 
6404
 
require("./edit_session/folding").Folding.call(EditSession.prototype);
6405
 
require("./edit_session/bracket_match").BracketMatch.call(EditSession.prototype);
6406
 
 
6407
 
 
6408
 
config.defineOptions(EditSession.prototype, "session", {
6409
 
    wrap: {
6410
 
        set: function(value) {
6411
 
            if (!value || value == "off")
6412
 
                value = false;
6413
 
            else if (value == "free")
6414
 
                value = true;
6415
 
            else if (typeof value == "string")
6416
 
                value = parseInt(value, 10) || false;
6417
 
 
6418
 
            if (!value) {
6419
 
                this.setUseWrapMode(false);
6420
 
            } else {
6421
 
                var col = typeof value == "number" ? value : null;
6422
 
                this.setUseWrapMode(true);
6423
 
                this.setWrapLimitRange(col, col);
6424
 
            }
6425
 
            this.$wrap = value;
6426
 
        },
6427
 
        get: function() {
6428
 
            return this.getUseWrapMode() ? this.getWrapLimitRange().min || "free" : "off";
6429
 
        },
6430
 
        handlesSet: true
6431
 
    },
6432
 
    firstLineNumber: {
6433
 
        set: function() {this._emit("changeBreakpoint");},
6434
 
        initialValue: 1
6435
 
    },
6436
 
    useWorker: {
6437
 
        set: function(useWorker) {
6438
 
            this.$useWorker = useWorker;
6439
 
 
6440
 
            this.$stopWorker();
6441
 
            if (useWorker)
6442
 
                this.$startWorker();
6443
 
        },
6444
 
        initialValue: true
6445
 
    },
6446
 
    useSoftTabs: {initialValue: true},
6447
 
    tabSize: {
6448
 
        set: function(tabSize) {
6449
 
            if (isNaN(tabSize) || this.$tabSize === tabSize) return;
6450
 
 
6451
 
            this.$modified = true;
6452
 
            this.$rowLengthCache = [];
6453
 
            this.$tabSize = tabSize;
6454
 
            this._emit("changeTabSize");
6455
 
        },
6456
 
        initialValue: 4,
6457
 
        handlesSet: true
6458
 
    }
6459
 
});
6460
 
 
6461
 
exports.EditSession = EditSession;
6462
 
});
6463
 
 
6464
 
define('ace/selection', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/lang', 'ace/lib/event_emitter', 'ace/range'], function(require, exports, module) {
6465
 
 
6466
 
 
6467
 
var oop = require("./lib/oop");
6468
 
var lang = require("./lib/lang");
6469
 
var EventEmitter = require("./lib/event_emitter").EventEmitter;
6470
 
var Range = require("./range").Range;
6471
 
var Selection = function(session) {
6472
 
    this.session = session;
6473
 
    this.doc = session.getDocument();
6474
 
 
6475
 
    this.clearSelection();
6476
 
    this.lead = this.selectionLead = this.doc.createAnchor(0, 0);
6477
 
    this.anchor = this.selectionAnchor = this.doc.createAnchor(0, 0);
6478
 
 
6479
 
    var self = this;
6480
 
    this.lead.on("change", function(e) {
6481
 
        self._emit("changeCursor");
6482
 
        if (!self.$isEmpty)
6483
 
            self._emit("changeSelection");
6484
 
        if (!self.$keepDesiredColumnOnChange && e.old.column != e.value.column)
6485
 
            self.$desiredColumn = null;
6486
 
    });
6487
 
 
6488
 
    this.selectionAnchor.on("change", function() {
6489
 
        if (!self.$isEmpty)
6490
 
            self._emit("changeSelection");
6491
 
    });
6492
 
};
6493
 
 
6494
 
(function() {
6495
 
 
6496
 
    oop.implement(this, EventEmitter);
6497
 
    this.isEmpty = function() {
6498
 
        return (this.$isEmpty || (
6499
 
            this.anchor.row == this.lead.row &&
6500
 
            this.anchor.column == this.lead.column
6501
 
        ));
6502
 
    };
6503
 
    this.isMultiLine = function() {
6504
 
        if (this.isEmpty()) {
6505
 
            return false;
6506
 
        }
6507
 
 
6508
 
        return this.getRange().isMultiLine();
6509
 
    };
6510
 
    this.getCursor = function() {
6511
 
        return this.lead.getPosition();
6512
 
    };
6513
 
    this.setSelectionAnchor = function(row, column) {
6514
 
        this.anchor.setPosition(row, column);
6515
 
 
6516
 
        if (this.$isEmpty) {
6517
 
            this.$isEmpty = false;
6518
 
            this._emit("changeSelection");
6519
 
        }
6520
 
    };
6521
 
    this.getSelectionAnchor = function() {
6522
 
        if (this.$isEmpty)
6523
 
            return this.getSelectionLead()
6524
 
        else
6525
 
            return this.anchor.getPosition();
6526
 
    };
6527
 
    this.getSelectionLead = function() {
6528
 
        return this.lead.getPosition();
6529
 
    };
6530
 
    this.shiftSelection = function(columns) {
6531
 
        if (this.$isEmpty) {
6532
 
            this.moveCursorTo(this.lead.row, this.lead.column + columns);
6533
 
            return;
6534
 
        };
6535
 
 
6536
 
        var anchor = this.getSelectionAnchor();
6537
 
        var lead = this.getSelectionLead();
6538
 
 
6539
 
        var isBackwards = this.isBackwards();
6540
 
 
6541
 
        if (!isBackwards || anchor.column !== 0)
6542
 
            this.setSelectionAnchor(anchor.row, anchor.column + columns);
6543
 
 
6544
 
        if (isBackwards || lead.column !== 0) {
6545
 
            this.$moveSelection(function() {
6546
 
                this.moveCursorTo(lead.row, lead.column + columns);
6547
 
            });
6548
 
        }
6549
 
    };
6550
 
    this.isBackwards = function() {
6551
 
        var anchor = this.anchor;
6552
 
        var lead = this.lead;
6553
 
        return (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column));
6554
 
    };
6555
 
    this.getRange = function() {
6556
 
        var anchor = this.anchor;
6557
 
        var lead = this.lead;
6558
 
 
6559
 
        if (this.isEmpty())
6560
 
            return Range.fromPoints(lead, lead);
6561
 
 
6562
 
        if (this.isBackwards()) {
6563
 
            return Range.fromPoints(lead, anchor);
6564
 
        }
6565
 
        else {
6566
 
            return Range.fromPoints(anchor, lead);
6567
 
        }
6568
 
    };
6569
 
    this.clearSelection = function() {
6570
 
        if (!this.$isEmpty) {
6571
 
            this.$isEmpty = true;
6572
 
            this._emit("changeSelection");
6573
 
        }
6574
 
    };
6575
 
    this.selectAll = function() {
6576
 
        var lastRow = this.doc.getLength() - 1;
6577
 
        this.setSelectionAnchor(0, 0);
6578
 
        this.moveCursorTo(lastRow, this.doc.getLine(lastRow).length);
6579
 
    };
6580
 
    this.setRange =
6581
 
    this.setSelectionRange = function(range, reverse) {
6582
 
        if (reverse) {
6583
 
            this.setSelectionAnchor(range.end.row, range.end.column);
6584
 
            this.selectTo(range.start.row, range.start.column);
6585
 
        } else {
6586
 
            this.setSelectionAnchor(range.start.row, range.start.column);
6587
 
            this.selectTo(range.end.row, range.end.column);
6588
 
        }
6589
 
        this.$desiredColumn = null;
6590
 
    };
6591
 
 
6592
 
    this.$moveSelection = function(mover) {
6593
 
        var lead = this.lead;
6594
 
        if (this.$isEmpty)
6595
 
            this.setSelectionAnchor(lead.row, lead.column);
6596
 
 
6597
 
        mover.call(this);
6598
 
    };
6599
 
    this.selectTo = function(row, column) {
6600
 
        this.$moveSelection(function() {
6601
 
            this.moveCursorTo(row, column);
6602
 
        });
6603
 
    };
6604
 
    this.selectToPosition = function(pos) {
6605
 
        this.$moveSelection(function() {
6606
 
            this.moveCursorToPosition(pos);
6607
 
        });
6608
 
    };
6609
 
    this.selectUp = function() {
6610
 
        this.$moveSelection(this.moveCursorUp);
6611
 
    };
6612
 
    this.selectDown = function() {
6613
 
        this.$moveSelection(this.moveCursorDown);
6614
 
    };
6615
 
    this.selectRight = function() {
6616
 
        this.$moveSelection(this.moveCursorRight);
6617
 
    };
6618
 
    this.selectLeft = function() {
6619
 
        this.$moveSelection(this.moveCursorLeft);
6620
 
    };
6621
 
    this.selectLineStart = function() {
6622
 
        this.$moveSelection(this.moveCursorLineStart);
6623
 
    };
6624
 
    this.selectLineEnd = function() {
6625
 
        this.$moveSelection(this.moveCursorLineEnd);
6626
 
    };
6627
 
    this.selectFileEnd = function() {
6628
 
        this.$moveSelection(this.moveCursorFileEnd);
6629
 
    };
6630
 
    this.selectFileStart = function() {
6631
 
        this.$moveSelection(this.moveCursorFileStart);
6632
 
    };
6633
 
    this.selectWordRight = function() {
6634
 
        this.$moveSelection(this.moveCursorWordRight);
6635
 
    };
6636
 
    this.selectWordLeft = function() {
6637
 
        this.$moveSelection(this.moveCursorWordLeft);
6638
 
    };
6639
 
    this.getWordRange = function(row, column) {
6640
 
        if (typeof column == "undefined") {
6641
 
            var cursor = row || this.lead;
6642
 
            row = cursor.row;
6643
 
            column = cursor.column;
6644
 
        }
6645
 
        return this.session.getWordRange(row, column);
6646
 
    };
6647
 
    this.selectWord = function() {
6648
 
        this.setSelectionRange(this.getWordRange());
6649
 
    };
6650
 
    this.selectAWord = function() {
6651
 
        var cursor = this.getCursor();
6652
 
        var range = this.session.getAWordRange(cursor.row, cursor.column);
6653
 
        this.setSelectionRange(range);
6654
 
    };
6655
 
 
6656
 
    this.getLineRange = function(row, excludeLastChar) {
6657
 
        var rowStart = typeof row == "number" ? row : this.lead.row;
6658
 
        var rowEnd;
6659
 
 
6660
 
        var foldLine = this.session.getFoldLine(rowStart);
6661
 
        if (foldLine) {
6662
 
            rowStart = foldLine.start.row;
6663
 
            rowEnd = foldLine.end.row;
6664
 
        } else {
6665
 
            rowEnd = rowStart;
6666
 
        }
6667
 
        if (excludeLastChar)
6668
 
            return new Range(rowStart, 0, rowEnd, this.session.getLine(rowEnd).length);
6669
 
        else
6670
 
            return new Range(rowStart, 0, rowEnd + 1, 0);
6671
 
    };
6672
 
    this.selectLine = function() {
6673
 
        this.setSelectionRange(this.getLineRange());
6674
 
    };
6675
 
    this.moveCursorUp = function() {
6676
 
        this.moveCursorBy(-1, 0);
6677
 
    };
6678
 
    this.moveCursorDown = function() {
6679
 
        this.moveCursorBy(1, 0);
6680
 
    };
6681
 
    this.moveCursorLeft = function() {
6682
 
        var cursor = this.lead.getPosition(),
6683
 
            fold;
6684
 
 
6685
 
        if (fold = this.session.getFoldAt(cursor.row, cursor.column, -1)) {
6686
 
            this.moveCursorTo(fold.start.row, fold.start.column);
6687
 
        } else if (cursor.column == 0) {
6688
 
            if (cursor.row > 0) {
6689
 
                this.moveCursorTo(cursor.row - 1, this.doc.getLine(cursor.row - 1).length);
6690
 
            }
6691
 
        }
6692
 
        else {
6693
 
            var tabSize = this.session.getTabSize();
6694
 
            if (this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(cursor.column-tabSize, cursor.column).split(" ").length-1 == tabSize)
6695
 
                this.moveCursorBy(0, -tabSize);
6696
 
            else
6697
 
                this.moveCursorBy(0, -1);
6698
 
        }
6699
 
    };
6700
 
    this.moveCursorRight = function() {
6701
 
        var cursor = this.lead.getPosition(),
6702
 
            fold;
6703
 
        if (fold = this.session.getFoldAt(cursor.row, cursor.column, 1)) {
6704
 
            this.moveCursorTo(fold.end.row, fold.end.column);
6705
 
        }
6706
 
        else if (this.lead.column == this.doc.getLine(this.lead.row).length) {
6707
 
            if (this.lead.row < this.doc.getLength() - 1) {
6708
 
                this.moveCursorTo(this.lead.row + 1, 0);
6709
 
            }
6710
 
        }
6711
 
        else {
6712
 
            var tabSize = this.session.getTabSize();
6713
 
            var cursor = this.lead;
6714
 
            if (this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(cursor.column, cursor.column+tabSize).split(" ").length-1 == tabSize)
6715
 
                this.moveCursorBy(0, tabSize);
6716
 
            else
6717
 
                this.moveCursorBy(0, 1);
6718
 
        }
6719
 
    };
6720
 
    this.moveCursorLineStart = function() {
6721
 
        var row = this.lead.row;
6722
 
        var column = this.lead.column;
6723
 
        var screenRow = this.session.documentToScreenRow(row, column);
6724
 
        var firstColumnPosition = this.session.screenToDocumentPosition(screenRow, 0);
6725
 
        var beforeCursor = this.session.getDisplayLine(
6726
 
            row, null, firstColumnPosition.row,
6727
 
            firstColumnPosition.column
6728
 
        );
6729
 
 
6730
 
        var leadingSpace = beforeCursor.match(/^\s*/);
6731
 
        if (leadingSpace[0].length != column && !this.session.$useEmacsStyleLineStart)
6732
 
            firstColumnPosition.column += leadingSpace[0].length;
6733
 
        this.moveCursorToPosition(firstColumnPosition);
6734
 
    };
6735
 
    this.moveCursorLineEnd = function() {
6736
 
        var lead = this.lead;
6737
 
        var lineEnd = this.session.getDocumentLastRowColumnPosition(lead.row, lead.column);
6738
 
        if (this.lead.column == lineEnd.column) {
6739
 
            var line = this.session.getLine(lineEnd.row);
6740
 
            if (lineEnd.column == line.length) {
6741
 
                var textEnd = line.search(/\s+$/);
6742
 
                if (textEnd > 0)
6743
 
                    lineEnd.column = textEnd;
6744
 
            }
6745
 
        }
6746
 
 
6747
 
        this.moveCursorTo(lineEnd.row, lineEnd.column);
6748
 
    };
6749
 
    this.moveCursorFileEnd = function() {
6750
 
        var row = this.doc.getLength() - 1;
6751
 
        var column = this.doc.getLine(row).length;
6752
 
        this.moveCursorTo(row, column);
6753
 
    };
6754
 
    this.moveCursorFileStart = function() {
6755
 
        this.moveCursorTo(0, 0);
6756
 
    };
6757
 
    this.moveCursorLongWordRight = function() {
6758
 
        var row = this.lead.row;
6759
 
        var column = this.lead.column;
6760
 
        var line = this.doc.getLine(row);
6761
 
        var rightOfCursor = line.substring(column);
6762
 
 
6763
 
        var match;
6764
 
        this.session.nonTokenRe.lastIndex = 0;
6765
 
        this.session.tokenRe.lastIndex = 0;
6766
 
        var fold = this.session.getFoldAt(row, column, 1);
6767
 
        if (fold) {
6768
 
            this.moveCursorTo(fold.end.row, fold.end.column);
6769
 
            return;
6770
 
        }
6771
 
        if (match = this.session.nonTokenRe.exec(rightOfCursor)) {
6772
 
            column += this.session.nonTokenRe.lastIndex;
6773
 
            this.session.nonTokenRe.lastIndex = 0;
6774
 
            rightOfCursor = line.substring(column);
6775
 
        }
6776
 
        if (column >= line.length) {
6777
 
            this.moveCursorTo(row, line.length);
6778
 
            this.moveCursorRight();
6779
 
            if (row < this.doc.getLength() - 1)
6780
 
                this.moveCursorWordRight();
6781
 
            return;
6782
 
        }
6783
 
        if (match = this.session.tokenRe.exec(rightOfCursor)) {
6784
 
            column += this.session.tokenRe.lastIndex;
6785
 
            this.session.tokenRe.lastIndex = 0;
6786
 
        }
6787
 
 
6788
 
        this.moveCursorTo(row, column);
6789
 
    };
6790
 
    this.moveCursorLongWordLeft = function() {
6791
 
        var row = this.lead.row;
6792
 
        var column = this.lead.column;
6793
 
        var fold;
6794
 
        if (fold = this.session.getFoldAt(row, column, -1)) {
6795
 
            this.moveCursorTo(fold.start.row, fold.start.column);
6796
 
            return;
6797
 
        }
6798
 
 
6799
 
        var str = this.session.getFoldStringAt(row, column, -1);
6800
 
        if (str == null) {
6801
 
            str = this.doc.getLine(row).substring(0, column)
6802
 
        }
6803
 
 
6804
 
        var leftOfCursor = lang.stringReverse(str);
6805
 
        var match;
6806
 
        this.session.nonTokenRe.lastIndex = 0;
6807
 
        this.session.tokenRe.lastIndex = 0;
6808
 
        if (match = this.session.nonTokenRe.exec(leftOfCursor)) {
6809
 
            column -= this.session.nonTokenRe.lastIndex;
6810
 
            leftOfCursor = leftOfCursor.slice(this.session.nonTokenRe.lastIndex);
6811
 
            this.session.nonTokenRe.lastIndex = 0;
6812
 
        }
6813
 
        if (column <= 0) {
6814
 
            this.moveCursorTo(row, 0);
6815
 
            this.moveCursorLeft();
6816
 
            if (row > 0)
6817
 
                this.moveCursorWordLeft();
6818
 
            return;
6819
 
        }
6820
 
        if (match = this.session.tokenRe.exec(leftOfCursor)) {
6821
 
            column -= this.session.tokenRe.lastIndex;
6822
 
            this.session.tokenRe.lastIndex = 0;
6823
 
        }
6824
 
 
6825
 
        this.moveCursorTo(row, column);
6826
 
    };
6827
 
 
6828
 
    this.$shortWordEndIndex = function(rightOfCursor) {
6829
 
        var match, index = 0, ch;
6830
 
        var whitespaceRe = /\s/;
6831
 
        var tokenRe = this.session.tokenRe;
6832
 
 
6833
 
        tokenRe.lastIndex = 0;
6834
 
        if (match = this.session.tokenRe.exec(rightOfCursor)) {
6835
 
            index = this.session.tokenRe.lastIndex;
6836
 
        } else {
6837
 
            while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch))
6838
 
                index ++;
6839
 
 
6840
 
            if (index <= 1) {
6841
 
                tokenRe.lastIndex = 0;
6842
 
                 while ((ch = rightOfCursor[index]) && !tokenRe.test(ch)) {
6843
 
                    tokenRe.lastIndex = 0;
6844
 
                    index ++;
6845
 
                    if (whitespaceRe.test(ch)) {
6846
 
                        if (index > 2) {
6847
 
                            index--
6848
 
                            break;
6849
 
                        } else {
6850
 
                            while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch))
6851
 
                                index ++;
6852
 
                            if (index > 2)
6853
 
                                break
6854
 
                        }
6855
 
                    }
6856
 
                }
6857
 
            }
6858
 
        }
6859
 
        tokenRe.lastIndex = 0;
6860
 
 
6861
 
        return index;
6862
 
    };
6863
 
 
6864
 
    this.moveCursorShortWordRight = function() {
6865
 
        var row = this.lead.row;
6866
 
        var column = this.lead.column;
6867
 
        var line = this.doc.getLine(row);
6868
 
        var rightOfCursor = line.substring(column);
6869
 
 
6870
 
        var fold = this.session.getFoldAt(row, column, 1);
6871
 
        if (fold)
6872
 
            return this.moveCursorTo(fold.end.row, fold.end.column);
6873
 
 
6874
 
        if (column == line.length) {
6875
 
            var l = this.doc.getLength();
6876
 
            do {    
6877
 
                row++;
6878
 
                rightOfCursor = this.doc.getLine(row)
6879
 
            } while (row < l && /^\s*$/.test(rightOfCursor))
6880
 
            
6881
 
            if (!/^\s+/.test(rightOfCursor))
6882
 
                rightOfCursor = ""
6883
 
            column = 0;
6884
 
        }
6885
 
 
6886
 
        var index = this.$shortWordEndIndex(rightOfCursor);
6887
 
 
6888
 
        this.moveCursorTo(row, column + index);
6889
 
    };
6890
 
 
6891
 
    this.moveCursorShortWordLeft = function() {
6892
 
        var row = this.lead.row;
6893
 
        var column = this.lead.column;
6894
 
 
6895
 
        var fold;
6896
 
        if (fold = this.session.getFoldAt(row, column, -1))
6897
 
            return this.moveCursorTo(fold.start.row, fold.start.column);
6898
 
 
6899
 
        var line = this.session.getLine(row).substring(0, column);
6900
 
        if (column == 0) {
6901
 
            do {    
6902
 
                row--;
6903
 
                line = this.doc.getLine(row);
6904
 
            } while (row > 0 && /^\s*$/.test(line))
6905
 
            
6906
 
            column = line.length;
6907
 
            if (!/\s+$/.test(line))
6908
 
                line = ""
6909
 
        }
6910
 
 
6911
 
        var leftOfCursor = lang.stringReverse(line);
6912
 
        var index = this.$shortWordEndIndex(leftOfCursor);
6913
 
 
6914
 
        return this.moveCursorTo(row, column - index);
6915
 
    };
6916
 
 
6917
 
    this.moveCursorWordRight = function() {
6918
 
        if (this.session.$selectLongWords)
6919
 
            this.moveCursorLongWordRight();
6920
 
        else
6921
 
            this.moveCursorShortWordRight();
6922
 
    };
6923
 
 
6924
 
    this.moveCursorWordLeft = function() {
6925
 
        if (this.session.$selectLongWords)
6926
 
            this.moveCursorLongWordLeft();
6927
 
        else
6928
 
            this.moveCursorShortWordLeft();
6929
 
    };
6930
 
    this.moveCursorBy = function(rows, chars) {
6931
 
        var screenPos = this.session.documentToScreenPosition(
6932
 
            this.lead.row,
6933
 
            this.lead.column
6934
 
        );
6935
 
 
6936
 
        if (chars === 0) {
6937
 
            if (this.$desiredColumn)
6938
 
                screenPos.column = this.$desiredColumn;
6939
 
            else
6940
 
                this.$desiredColumn = screenPos.column;
6941
 
        }
6942
 
 
6943
 
        var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenPos.column);
6944
 
        this.moveCursorTo(docPos.row, docPos.column + chars, chars === 0);
6945
 
    };
6946
 
    this.moveCursorToPosition = function(position) {
6947
 
        this.moveCursorTo(position.row, position.column);
6948
 
    };
6949
 
    this.moveCursorTo = function(row, column, keepDesiredColumn) {
6950
 
        var fold = this.session.getFoldAt(row, column, 1);
6951
 
        if (fold) {
6952
 
            row = fold.start.row;
6953
 
            column = fold.start.column;
6954
 
        }
6955
 
 
6956
 
        this.$keepDesiredColumnOnChange = true;
6957
 
        this.lead.setPosition(row, column);
6958
 
        this.$keepDesiredColumnOnChange = false;
6959
 
 
6960
 
        if (!keepDesiredColumn)
6961
 
            this.$desiredColumn = null;
6962
 
    };
6963
 
    this.moveCursorToScreen = function(row, column, keepDesiredColumn) {
6964
 
        var pos = this.session.screenToDocumentPosition(row, column);
6965
 
        this.moveCursorTo(pos.row, pos.column, keepDesiredColumn);
6966
 
    };
6967
 
    this.detach = function() {
6968
 
        this.lead.detach();
6969
 
        this.anchor.detach();
6970
 
        this.session = this.doc = null;
6971
 
    }
6972
 
 
6973
 
    this.fromOrientedRange = function(range) {
6974
 
        this.setSelectionRange(range, range.cursor == range.start);
6975
 
        this.$desiredColumn = range.desiredColumn || this.$desiredColumn;
6976
 
    }
6977
 
 
6978
 
    this.toOrientedRange = function(range) {
6979
 
        var r = this.getRange();
6980
 
        if (range) {
6981
 
            range.start.column = r.start.column;
6982
 
            range.start.row = r.start.row;
6983
 
            range.end.column = r.end.column;
6984
 
            range.end.row = r.end.row;
6985
 
        } else {
6986
 
            range = r;
6987
 
        }
6988
 
 
6989
 
        range.cursor = this.isBackwards() ? range.start : range.end;
6990
 
        range.desiredColumn = this.$desiredColumn;
6991
 
        return range;
6992
 
    }
6993
 
 
6994
 
}).call(Selection.prototype);
6995
 
 
6996
 
exports.Selection = Selection;
6997
 
});
6998
 
 
6999
 
define('ace/range', ['require', 'exports', 'module' ], function(require, exports, module) {
7000
 
 
7001
 
var comparePoints = function(p1, p2) {
7002
 
    return p1.row - p2.row || p1.column - p2.column;
7003
 
};
7004
 
var Range = function(startRow, startColumn, endRow, endColumn) {
7005
 
    this.start = {
7006
 
        row: startRow,
7007
 
        column: startColumn
7008
 
    };
7009
 
 
7010
 
    this.end = {
7011
 
        row: endRow,
7012
 
        column: endColumn
7013
 
    };
7014
 
};
7015
 
 
7016
 
(function() {
7017
 
    this.isEqual = function(range) {
7018
 
        return this.start.row === range.start.row &&
7019
 
            this.end.row === range.end.row &&
7020
 
            this.start.column === range.start.column &&
7021
 
            this.end.column === range.end.column;
7022
 
    };
7023
 
    this.toString = function() {
7024
 
        return ("Range: [" + this.start.row + "/" + this.start.column +
7025
 
            "] -> [" + this.end.row + "/" + this.end.column + "]");
7026
 
    };
7027
 
 
7028
 
    this.contains = function(row, column) {
7029
 
        return this.compare(row, column) == 0;
7030
 
    };
7031
 
    this.compareRange = function(range) {
7032
 
        var cmp,
7033
 
            end = range.end,
7034
 
            start = range.start;
7035
 
 
7036
 
        cmp = this.compare(end.row, end.column);
7037
 
        if (cmp == 1) {
7038
 
            cmp = this.compare(start.row, start.column);
7039
 
            if (cmp == 1) {
7040
 
                return 2;
7041
 
            } else if (cmp == 0) {
7042
 
                return 1;
7043
 
            } else {
7044
 
                return 0;
7045
 
            }
7046
 
        } else if (cmp == -1) {
7047
 
            return -2;
7048
 
        } else {
7049
 
            cmp = this.compare(start.row, start.column);
7050
 
            if (cmp == -1) {
7051
 
                return -1;
7052
 
            } else if (cmp == 1) {
7053
 
                return 42;
7054
 
            } else {
7055
 
                return 0;
7056
 
            }
7057
 
        }
7058
 
    };
7059
 
    this.comparePoint = function(p) {
7060
 
        return this.compare(p.row, p.column);
7061
 
    };
7062
 
    this.containsRange = function(range) {
7063
 
        return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
7064
 
    };
7065
 
    this.intersects = function(range) {
7066
 
        var cmp = this.compareRange(range);
7067
 
        return (cmp == -1 || cmp == 0 || cmp == 1);
7068
 
    };
7069
 
    this.isEnd = function(row, column) {
7070
 
        return this.end.row == row && this.end.column == column;
7071
 
    };
7072
 
    this.isStart = function(row, column) {
7073
 
        return this.start.row == row && this.start.column == column;
7074
 
    };
7075
 
    this.setStart = function(row, column) {
7076
 
        if (typeof row == "object") {
7077
 
            this.start.column = row.column;
7078
 
            this.start.row = row.row;
7079
 
        } else {
7080
 
            this.start.row = row;
7081
 
            this.start.column = column;
7082
 
        }
7083
 
    };
7084
 
    this.setEnd = function(row, column) {
7085
 
        if (typeof row == "object") {
7086
 
            this.end.column = row.column;
7087
 
            this.end.row = row.row;
7088
 
        } else {
7089
 
            this.end.row = row;
7090
 
            this.end.column = column;
7091
 
        }
7092
 
    };
7093
 
    this.inside = function(row, column) {
7094
 
        if (this.compare(row, column) == 0) {
7095
 
            if (this.isEnd(row, column) || this.isStart(row, column)) {
7096
 
                return false;
7097
 
            } else {
7098
 
                return true;
7099
 
            }
7100
 
        }
7101
 
        return false;
7102
 
    };
7103
 
    this.insideStart = function(row, column) {
7104
 
        if (this.compare(row, column) == 0) {
7105
 
            if (this.isEnd(row, column)) {
7106
 
                return false;
7107
 
            } else {
7108
 
                return true;
7109
 
            }
7110
 
        }
7111
 
        return false;
7112
 
    };
7113
 
    this.insideEnd = function(row, column) {
7114
 
        if (this.compare(row, column) == 0) {
7115
 
            if (this.isStart(row, column)) {
7116
 
                return false;
7117
 
            } else {
7118
 
                return true;
7119
 
            }
7120
 
        }
7121
 
        return false;
7122
 
    };
7123
 
    this.compare = function(row, column) {
7124
 
        if (!this.isMultiLine()) {
7125
 
            if (row === this.start.row) {
7126
 
                return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0);
7127
 
            };
7128
 
        }
7129
 
 
7130
 
        if (row < this.start.row)
7131
 
            return -1;
7132
 
 
7133
 
        if (row > this.end.row)
7134
 
            return 1;
7135
 
 
7136
 
        if (this.start.row === row)
7137
 
            return column >= this.start.column ? 0 : -1;
7138
 
 
7139
 
        if (this.end.row === row)
7140
 
            return column <= this.end.column ? 0 : 1;
7141
 
 
7142
 
        return 0;
7143
 
    };
7144
 
    this.compareStart = function(row, column) {
7145
 
        if (this.start.row == row && this.start.column == column) {
7146
 
            return -1;
7147
 
        } else {
7148
 
            return this.compare(row, column);
7149
 
        }
7150
 
    };
7151
 
    this.compareEnd = function(row, column) {
7152
 
        if (this.end.row == row && this.end.column == column) {
7153
 
            return 1;
7154
 
        } else {
7155
 
            return this.compare(row, column);
7156
 
        }
7157
 
    };
7158
 
    this.compareInside = function(row, column) {
7159
 
        if (this.end.row == row && this.end.column == column) {
7160
 
            return 1;
7161
 
        } else if (this.start.row == row && this.start.column == column) {
7162
 
            return -1;
7163
 
        } else {
7164
 
            return this.compare(row, column);
7165
 
        }
7166
 
    };
7167
 
    this.clipRows = function(firstRow, lastRow) {
7168
 
        if (this.end.row > lastRow)
7169
 
            var end = {row: lastRow + 1, column: 0};
7170
 
        else if (this.end.row < firstRow)
7171
 
            var end = {row: firstRow, column: 0};
7172
 
 
7173
 
        if (this.start.row > lastRow)
7174
 
            var start = {row: lastRow + 1, column: 0};
7175
 
        else if (this.start.row < firstRow)
7176
 
            var start = {row: firstRow, column: 0};
7177
 
 
7178
 
        return Range.fromPoints(start || this.start, end || this.end);
7179
 
    };
7180
 
    this.extend = function(row, column) {
7181
 
        var cmp = this.compare(row, column);
7182
 
 
7183
 
        if (cmp == 0)
7184
 
            return this;
7185
 
        else if (cmp == -1)
7186
 
            var start = {row: row, column: column};
7187
 
        else
7188
 
            var end = {row: row, column: column};
7189
 
 
7190
 
        return Range.fromPoints(start || this.start, end || this.end);
7191
 
    };
7192
 
 
7193
 
    this.isEmpty = function() {
7194
 
        return (this.start.row === this.end.row && this.start.column === this.end.column);
7195
 
    };
7196
 
    this.isMultiLine = function() {
7197
 
        return (this.start.row !== this.end.row);
7198
 
    };
7199
 
    this.clone = function() {
7200
 
        return Range.fromPoints(this.start, this.end);
7201
 
    };
7202
 
    this.collapseRows = function() {
7203
 
        if (this.end.column == 0)
7204
 
            return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0)
7205
 
        else
7206
 
            return new Range(this.start.row, 0, this.end.row, 0)
7207
 
    };
7208
 
    this.toScreenRange = function(session) {
7209
 
        var screenPosStart = session.documentToScreenPosition(this.start);
7210
 
        var screenPosEnd = session.documentToScreenPosition(this.end);
7211
 
 
7212
 
        return new Range(
7213
 
            screenPosStart.row, screenPosStart.column,
7214
 
            screenPosEnd.row, screenPosEnd.column
7215
 
        );
7216
 
    };
7217
 
    this.moveBy = function(row, column) {
7218
 
        this.start.row += row;
7219
 
        this.start.column += column;
7220
 
        this.end.row += row;
7221
 
        this.end.column += column;
7222
 
    };
7223
 
 
7224
 
}).call(Range.prototype);
7225
 
Range.fromPoints = function(start, end) {
7226
 
    return new Range(start.row, start.column, end.row, end.column);
7227
 
};
7228
 
Range.comparePoints = comparePoints;
7229
 
 
7230
 
exports.Range = Range;
7231
 
});
7232
 
 
7233
 
define('ace/mode/text', ['require', 'exports', 'module' , 'ace/tokenizer', 'ace/mode/text_highlight_rules', 'ace/mode/behaviour', 'ace/unicode', 'ace/lib/lang'], function(require, exports, module) {
7234
 
 
7235
 
 
7236
 
var Tokenizer = require("../tokenizer").Tokenizer;
7237
 
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
7238
 
var Behaviour = require("./behaviour").Behaviour;
7239
 
var unicode = require("../unicode");
7240
 
var lang = require("../lib/lang");
7241
 
 
7242
 
var Mode = function() {
7243
 
    this.$tokenizer = new Tokenizer(new TextHighlightRules().getRules());
7244
 
    this.$behaviour = new Behaviour();
7245
 
};
7246
 
 
7247
 
(function() {
7248
 
 
7249
 
    this.tokenRe = new RegExp("^["
7250
 
        + unicode.packages.L
7251
 
        + unicode.packages.Mn + unicode.packages.Mc
7252
 
        + unicode.packages.Nd
7253
 
        + unicode.packages.Pc + "\\$_]+", "g"
7254
 
    );
7255
 
    
7256
 
    this.nonTokenRe = new RegExp("^(?:[^"
7257
 
        + unicode.packages.L
7258
 
        + unicode.packages.Mn + unicode.packages.Mc
7259
 
        + unicode.packages.Nd
7260
 
        + unicode.packages.Pc + "\\$_]|\s])+", "g"
7261
 
    );
7262
 
 
7263
 
    this.getTokenizer = function() {
7264
 
        return this.$tokenizer;
7265
 
    };
7266
 
 
7267
 
    this.toggleCommentLines = function(state, session, startRow, endRow) {
7268
 
        var doc = session.doc;
7269
 
        var regexpStart, lineCommentStart;
7270
 
        if (!this.lineCommentStart) {
7271
 
            return false
7272
 
        } else if (Array.isArray(this.lineCommentStart)) {
7273
 
            regexpStart = this.lineCommentStart.map(lang.escapeRegExp).join("|");
7274
 
            lineCommentStart = this.lineCommentStart[0];
7275
 
        } else {
7276
 
            regexpStart = lang.escapeRegExp(this.lineCommentStart);
7277
 
            lineCommentStart = this.lineCommentStart;
7278
 
        }
7279
 
        regexpStart = new RegExp("^\\s*(?:" + regexpStart + ") ?");
7280
 
 
7281
 
        var removeComment = true;
7282
 
        var minSpace = Infinity;
7283
 
        var indentations = [];
7284
 
 
7285
 
        for (var i = startRow; i <= endRow; i++) {
7286
 
            var line = doc.getLine(i);
7287
 
            var indent = line.search(/\S|$/);
7288
 
            indentations[i] = indent;
7289
 
            if (indent < minSpace)
7290
 
                minSpace = indent;
7291
 
            if (removeComment && !regexpStart.test(line))
7292
 
                removeComment = false;
7293
 
        }
7294
 
 
7295
 
        if (removeComment) {
7296
 
            for (var i = startRow; i <= endRow; i++) {
7297
 
                var line = doc.getLine(i);
7298
 
                var m = line.match(regexpStart);
7299
 
                doc.removeInLine(i, indentations[i], m[0].length);
7300
 
            }
7301
 
        } else {
7302
 
            lineCommentStart += " ";
7303
 
            for (var i = startRow; i <= endRow; i++) {
7304
 
                doc.insertInLine({row: i, column: minSpace}, lineCommentStart);
7305
 
            }
7306
 
        }
7307
 
    };
7308
 
 
7309
 
    this.getNextLineIndent = function(state, line, tab) {
7310
 
        return this.$getIndent(line);
7311
 
    };
7312
 
 
7313
 
    this.checkOutdent = function(state, line, input) {
7314
 
        return false;
7315
 
    };
7316
 
 
7317
 
    this.autoOutdent = function(state, doc, row) {
7318
 
    };
7319
 
 
7320
 
    this.$getIndent = function(line) {
7321
 
        return line.match(/^\s*/)[0];
7322
 
    };
7323
 
    
7324
 
    this.createWorker = function(session) {
7325
 
        return null;
7326
 
    };
7327
 
 
7328
 
    this.createModeDelegates = function (mapping) {
7329
 
        if (!this.$embeds) {
7330
 
            return;
7331
 
        }
7332
 
        this.$modes = {};
7333
 
        for (var i = 0; i < this.$embeds.length; i++) {
7334
 
            if (mapping[this.$embeds[i]]) {
7335
 
                this.$modes[this.$embeds[i]] = new mapping[this.$embeds[i]]();
7336
 
            }
7337
 
        }
7338
 
        
7339
 
        var delegations = ['toggleCommentLines', 'getNextLineIndent', 'checkOutdent', 'autoOutdent', 'transformAction'];
7340
 
 
7341
 
        for (var i = 0; i < delegations.length; i++) {
7342
 
            (function(scope) {
7343
 
              var functionName = delegations[i];
7344
 
              var defaultHandler = scope[functionName];
7345
 
              scope[delegations[i]] = function() {
7346
 
                  return this.$delegator(functionName, arguments, defaultHandler);
7347
 
              }
7348
 
            } (this));
7349
 
        }
7350
 
    }
7351
 
    
7352
 
    this.$delegator = function(method, args, defaultHandler) {
7353
 
        var state = args[0];
7354
 
        
7355
 
        for (var i = 0; i < this.$embeds.length; i++) {
7356
 
            if (!this.$modes[this.$embeds[i]]) continue;
7357
 
            
7358
 
            var split = state.split(this.$embeds[i]);
7359
 
            if (!split[0] && split[1]) {
7360
 
                args[0] = split[1];
7361
 
                var mode = this.$modes[this.$embeds[i]];
7362
 
                return mode[method].apply(mode, args);
7363
 
            }
7364
 
        }
7365
 
        var ret = defaultHandler.apply(this, args);
7366
 
        return defaultHandler ? ret : undefined;
7367
 
    };
7368
 
    
7369
 
    this.transformAction = function(state, action, editor, session, param) {
7370
 
        if (this.$behaviour) {
7371
 
            var behaviours = this.$behaviour.getBehaviours();
7372
 
            for (var key in behaviours) {
7373
 
                if (behaviours[key][action]) {
7374
 
                    var ret = behaviours[key][action].apply(this, arguments);
7375
 
                    if (ret) {
7376
 
                        return ret;
7377
 
                    }
7378
 
                }
7379
 
            }
7380
 
        }
7381
 
    }
7382
 
    
7383
 
}).call(Mode.prototype);
7384
 
 
7385
 
exports.Mode = Mode;
7386
 
});
7387
 
 
7388
 
define('ace/tokenizer', ['require', 'exports', 'module' ], function(require, exports, module) {
7389
 
var MAX_TOKEN_COUNT = 1000;
7390
 
var Tokenizer = function(rules) {
7391
 
    this.states = rules;
7392
 
 
7393
 
    this.regExps = {};
7394
 
    this.matchMappings = {};
7395
 
    for (var key in this.states) {
7396
 
        var state = this.states[key];
7397
 
        var ruleRegExps = [];
7398
 
        var matchTotal = 0;
7399
 
        var mapping = this.matchMappings[key] = {defaultToken: "text"};
7400
 
        var flag = "g";
7401
 
 
7402
 
        for (var i = 0; i < state.length; i++) {
7403
 
            var rule = state[i];
7404
 
            if (rule.defaultToken)
7405
 
                mapping.defaultToken = rule.defaultToken;
7406
 
            if (rule.caseInsensitive)
7407
 
                flag = "gi";
7408
 
            if (rule.regex == null)
7409
 
                continue;
7410
 
            
7411
 
            if (rule.regex instanceof RegExp)
7412
 
                rule.regex = rule.regex.toString().slice(1, -1);
7413
 
            var adjustedregex = rule.regex;
7414
 
            var matchcount = new RegExp("(?:(" + adjustedregex + ")|(.))").exec("a").length - 2;
7415
 
            if (Array.isArray(rule.token)) {
7416
 
                if (rule.token.length == 1) {
7417
 
                    rule.token = rule.token[0];
7418
 
                } else {
7419
 
                    rule.tokenArray = rule.token;
7420
 
                    rule.onMatch = this.$arrayTokens;
7421
 
                }
7422
 
            } else if (typeof rule.token == "function" && !rule.onMatch) {
7423
 
                if (matchcount > 1)
7424
 
                    rule.onMatch = this.$applyToken;
7425
 
                else
7426
 
                    rule.onMatch = rule.token;
7427
 
            }
7428
 
            
7429
 
            if (matchcount > 1) {
7430
 
                if (/\\\d/.test(rule.regex)) {
7431
 
                    adjustedregex = rule.regex.replace(/\\([0-9]+)/g, function (match, digit) {
7432
 
                        return "\\" + (parseInt(digit, 10) + matchTotal + 1);
7433
 
                    });
7434
 
                } else {
7435
 
                    matchcount = 1;
7436
 
                    adjustedregex = this.removeCapturingGroups(rule.regex);
7437
 
                }
7438
 
                if (!rule.splitRegex && typeof rule.token != "string")
7439
 
                    rule.splitRegex = this.createSplitterRegexp(rule.regex, flag);
7440
 
            }
7441
 
 
7442
 
            mapping[matchTotal] = i;
7443
 
            matchTotal += matchcount;
7444
 
 
7445
 
            ruleRegExps.push(adjustedregex);
7446
 
            if (!rule.onMatch)
7447
 
                rule.onMatch = null;
7448
 
            rule.__proto__ = null;
7449
 
        }
7450
 
 
7451
 
        this.regExps[key] = new RegExp("(" + ruleRegExps.join(")|(") + ")|($)", flag);
7452
 
    }
7453
 
};
7454
 
 
7455
 
(function() {
7456
 
    this.$applyToken = function(str) {
7457
 
        var values = this.splitRegex.exec(str).slice(1);
7458
 
        var types = this.token.apply(this, values);
7459
 
        if (typeof types === "string")
7460
 
            return [{type: types, value: str}];
7461
 
 
7462
 
        var tokens = [];
7463
 
        for (var i = 0, l = types.length; i < l; i++) {
7464
 
            if (values[i])
7465
 
                tokens[tokens.length] = {
7466
 
                    type: types[i],
7467
 
                    value: values[i]
7468
 
                };
7469
 
        }
7470
 
        return tokens;
7471
 
    },
7472
 
 
7473
 
    this.$arrayTokens = function(str) {
7474
 
        if (!str)
7475
 
            return [];
7476
 
        var values = this.splitRegex.exec(str);
7477
 
        var tokens = [];
7478
 
        var types = this.tokenArray;
7479
 
        if (types.length != values.length - 1) {
7480
 
            if (window.console)
7481
 
                console.error(types , values, str, this.splitRegex, this);
7482
 
            return [{type: "error.invalid", value: str}];
7483
 
        }
7484
 
        for (var i = 0, l = types.length; i < l; i++) {
7485
 
            if (values[i + 1])
7486
 
                tokens[tokens.length] = {
7487
 
                    type: types[i],
7488
 
                    value: values[i + 1]
7489
 
                };
7490
 
        }
7491
 
        return tokens;
7492
 
    };
7493
 
    
7494
 
    this.removeCapturingGroups = function(src) {
7495
 
        var r = src.replace(
7496
 
            /\[(?:\\.|[^\]])*?\]|\\.|\(\?[:=!]|(\()/g,
7497
 
            function(x, y) {return y ? "(?:" : x;}
7498
 
        );
7499
 
        return r;
7500
 
    };
7501
 
    
7502
 
    this.createSplitterRegexp = function(src, flag) {
7503
 
        if (src.indexOf("(?=") != -1) {
7504
 
            var stack = 0;
7505
 
            var inChClass = false;
7506
 
            var lastCapture = {};
7507
 
            src.replace(/(\\.)|(\((?:\?[=!])?)|(\))|([])/g, function(
7508
 
                m, esc, parenOpen, parenClose, square, index
7509
 
            ) {
7510
 
                if (inChClass) {
7511
 
                    inChClass = square != "]";
7512
 
                } else if (square) {
7513
 
                    inChClass = true;
7514
 
                } else if (parenClose) {
7515
 
                    if (stack == lastCapture.stack)
7516
 
                        lastCapture.end = index+1
7517
 
                    stack--;
7518
 
                } else if (parenOpen) {
7519
 
                    stack++;
7520
 
                    if (parenOpen.length != 1) {
7521
 
                        lastCapture.stack = stack
7522
 
                        lastCapture.start = index;
7523
 
                    }
7524
 
                }
7525
 
                return m;
7526
 
            });
7527
 
 
7528
 
            if (lastCapture.end != null && /^\)*$/.test(src.substr(lastCapture.end)))
7529
 
                src = src.substring(0, lastCapture.start) + src.substr(lastCapture.end);
7530
 
        }
7531
 
        return new RegExp(src, (flag||"").replace("g", ""));
7532
 
    };
7533
 
    this.getLineTokens = function(line, startState) {
7534
 
        if (startState && typeof startState != "string") {
7535
 
            var stack = startState.slice(0);
7536
 
            startState = stack[0];
7537
 
        } else
7538
 
            var stack = [];
7539
 
 
7540
 
        var currentState = startState || "start";
7541
 
        var state = this.states[currentState];
7542
 
        var mapping = this.matchMappings[currentState];
7543
 
        var re = this.regExps[currentState];
7544
 
        re.lastIndex = 0;
7545
 
 
7546
 
        var match, tokens = [];
7547
 
        var lastIndex = 0;
7548
 
 
7549
 
        var token = {type: null, value: ""};
7550
 
 
7551
 
        while (match = re.exec(line)) {
7552
 
            var type = mapping.defaultToken;
7553
 
            var rule = null;
7554
 
            var value = match[0];
7555
 
            var index = re.lastIndex;
7556
 
 
7557
 
            if (index - value.length > lastIndex) {
7558
 
                var skipped = line.substring(lastIndex, index - value.length);
7559
 
                if (token.type == type) {
7560
 
                    token.value += skipped;
7561
 
                } else {
7562
 
                    if (token.type)
7563
 
                        tokens.push(token);
7564
 
                    token = {type: type, value: skipped};
7565
 
                }
7566
 
            }
7567
 
 
7568
 
            for (var i = 0; i < match.length-2; i++) {
7569
 
                if (match[i + 1] === undefined)
7570
 
                    continue;
7571
 
 
7572
 
                rule = state[mapping[i]];
7573
 
 
7574
 
                if (rule.onMatch)
7575
 
                    type = rule.onMatch(value, currentState, stack);
7576
 
                else
7577
 
                    type = rule.token;
7578
 
 
7579
 
                if (rule.next) {
7580
 
                    if (typeof rule.next == "string")
7581
 
                        currentState = rule.next;
7582
 
                    else
7583
 
                        currentState = rule.next(currentState, stack);
7584
 
 
7585
 
                    state = this.states[currentState];
7586
 
                    if (!state) {
7587
 
                        window.console && console.error && console.error(currentState, "doesn't exist");
7588
 
                        currentState = "start";
7589
 
                        state = this.states[currentState];
7590
 
                    }
7591
 
                    mapping = this.matchMappings[currentState];
7592
 
                    lastIndex = index;
7593
 
                    re = this.regExps[currentState];
7594
 
                    re.lastIndex = index;
7595
 
                }
7596
 
                break;
7597
 
            }
7598
 
 
7599
 
            if (value) {
7600
 
                if (typeof type == "string") {
7601
 
                    if ((!rule || rule.merge !== false) && token.type === type) {
7602
 
                        token.value += value;
7603
 
                    } else {
7604
 
                        if (token.type)
7605
 
                            tokens.push(token);
7606
 
                        token = {type: type, value: value};
7607
 
                    }
7608
 
                } else {
7609
 
                    if (token.type)
7610
 
                        tokens.push(token);
7611
 
                    token = {type: null, value: ""};
7612
 
                    for (var i = 0; i < type.length; i++)
7613
 
                        tokens.push(type[i]);
7614
 
                }
7615
 
            }
7616
 
 
7617
 
            if (lastIndex == line.length)
7618
 
                break;
7619
 
 
7620
 
            lastIndex = index;
7621
 
 
7622
 
            if (tokens.length > MAX_TOKEN_COUNT) {
7623
 
                token.value += line.substr(lastIndex);
7624
 
                currentState = "start"
7625
 
                break;
7626
 
            }
7627
 
        }
7628
 
 
7629
 
        if (token.type)
7630
 
            tokens.push(token);
7631
 
 
7632
 
        return {
7633
 
            tokens : tokens,
7634
 
            state : stack.length ? stack : currentState
7635
 
        };
7636
 
    };
7637
 
 
7638
 
}).call(Tokenizer.prototype);
7639
 
 
7640
 
exports.Tokenizer = Tokenizer;
7641
 
});
7642
 
 
7643
 
define('ace/mode/text_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/lang'], function(require, exports, module) {
7644
 
 
7645
 
 
7646
 
var lang = require("../lib/lang");
7647
 
 
7648
 
var TextHighlightRules = function() {
7649
 
 
7650
 
    this.$rules = {
7651
 
        "start" : [{
7652
 
            token : "empty_line",
7653
 
            regex : '^$'
7654
 
        }, {
7655
 
            defaultToken : "text"
7656
 
        }]
7657
 
    };
7658
 
};
7659
 
 
7660
 
(function() {
7661
 
 
7662
 
    this.addRules = function(rules, prefix) {
7663
 
        for (var key in rules) {
7664
 
            var state = rules[key];
7665
 
            for (var i = 0; i < state.length; i++) {
7666
 
                var rule = state[i];
7667
 
                if (rule.next) {
7668
 
                    rule.next = prefix + rule.next;
7669
 
                }
7670
 
            }
7671
 
            this.$rules[prefix + key] = state;
7672
 
        }
7673
 
    };
7674
 
 
7675
 
    this.getRules = function() {
7676
 
        return this.$rules;
7677
 
    };
7678
 
 
7679
 
    this.embedRules = function (HighlightRules, prefix, escapeRules, states, append) {
7680
 
        var embedRules = new HighlightRules().getRules();
7681
 
        if (states) {
7682
 
            for (var i = 0; i < states.length; i++)
7683
 
                states[i] = prefix + states[i];
7684
 
        } else {
7685
 
            states = [];
7686
 
            for (var key in embedRules)
7687
 
                states.push(prefix + key);
7688
 
        }
7689
 
 
7690
 
        this.addRules(embedRules, prefix);
7691
 
 
7692
 
        if (escapeRules) {
7693
 
            var addRules = Array.prototype[append ? "push" : "unshift"];
7694
 
            for (var i = 0; i < states.length; i++)
7695
 
                addRules.apply(this.$rules[states[i]], lang.deepCopy(escapeRules));
7696
 
        }
7697
 
 
7698
 
        if (!this.$embeds)
7699
 
            this.$embeds = [];
7700
 
        this.$embeds.push(prefix);
7701
 
    }
7702
 
 
7703
 
    this.getEmbeds = function() {
7704
 
        return this.$embeds;
7705
 
    };
7706
 
 
7707
 
    var pushState = function(currentState, stack) {
7708
 
        if (currentState != "start")
7709
 
            stack.unshift(this.nextState, currentState);
7710
 
        return this.nextState;
7711
 
    };
7712
 
    var popState = function(currentState, stack) {
7713
 
        if (stack[0] !== currentState)
7714
 
            return "start";
7715
 
        stack.shift();
7716
 
        return stack.shift();
7717
 
    };
7718
 
 
7719
 
    this.normalizeRules = function() {
7720
 
        var id = 0;
7721
 
        var rules = this.$rules;
7722
 
        function processState(key) {
7723
 
            var state = rules[key];
7724
 
            state.processed = true;
7725
 
            for (var i = 0; i < state.length; i++) {
7726
 
                var rule = state[i];
7727
 
                if (!rule.regex && rule.start) {
7728
 
                    rule.regex = rule.start;
7729
 
                    if (!rule.next)
7730
 
                        rule.next = [];
7731
 
                    rule.next.push({
7732
 
                        defaultToken: rule.token
7733
 
                    }, {
7734
 
                        token: rule.token + ".end",
7735
 
                        regex: rule.end || rule.start,
7736
 
                        next: "pop"
7737
 
                    });
7738
 
                    rule.token = rule.token + ".start";
7739
 
                    rule.push = true;
7740
 
                }
7741
 
                var next = rule.next || rule.push;
7742
 
                if (next && Array.isArray(next)) {
7743
 
                    var stateName = rule.stateName || (rule.token + id++);
7744
 
                    rules[stateName] = next;
7745
 
                    rule.next = stateName;
7746
 
                    processState(stateName);
7747
 
                } else if (next == "pop") {
7748
 
                    rule.next = popState;
7749
 
                }
7750
 
 
7751
 
                if (rule.push) {
7752
 
                    rule.nextState = rule.next || rule.push;
7753
 
                    rule.next = pushState;
7754
 
                    delete rule.push;
7755
 
                }
7756
 
 
7757
 
                if (rule.rules) {
7758
 
                    for (var r in rule.rules) {
7759
 
                        if (rules[r]) {
7760
 
                            if (rules[r].push)
7761
 
                                rules[r].push.apply(rules[r], rule.rules[r]);
7762
 
                        } else {
7763
 
                            rules[r] = rule.rules[r];
7764
 
                        }
7765
 
                    }
7766
 
                }
7767
 
                if (rule.include || typeof rule == "string") {
7768
 
                    var includeName = rule.include || rule;
7769
 
                    var toInsert = rules[includeName];
7770
 
                } else if (Array.isArray(rule))
7771
 
                    toInsert = rule;
7772
 
 
7773
 
                if (toInsert) {
7774
 
                    var args = [i, 1].concat(toInsert);
7775
 
                    if (rule.noEscape)
7776
 
                        args = args.filter(function(x) {return !x.next;});
7777
 
                    state.splice.apply(state, args);
7778
 
                    i--;
7779
 
                    toInsert = null
7780
 
                }
7781
 
            }
7782
 
        };
7783
 
        Object.keys(rules).forEach(processState);
7784
 
    };
7785
 
 
7786
 
    this.createKeywordMapper = function(map, defaultToken, ignoreCase, splitChar) {
7787
 
        var keywords = Object.create(null);
7788
 
        Object.keys(map).forEach(function(className) {
7789
 
            var a = map[className];
7790
 
            if (ignoreCase)
7791
 
                a = a.toLowerCase();
7792
 
            var list = a.split(splitChar || "|");
7793
 
            for (var i = list.length; i--; )
7794
 
                keywords[list[i]] = className;
7795
 
        });
7796
 
        map = null;
7797
 
        return ignoreCase
7798
 
            ? function(value) {return keywords[value.toLowerCase()] || defaultToken }
7799
 
            : function(value) {return keywords[value] || defaultToken };
7800
 
    }
7801
 
 
7802
 
    this.getKeywords = function() {
7803
 
        return this.$keywords;
7804
 
    };
7805
 
 
7806
 
}).call(TextHighlightRules.prototype);
7807
 
 
7808
 
exports.TextHighlightRules = TextHighlightRules;
7809
 
});
7810
 
 
7811
 
define('ace/mode/behaviour', ['require', 'exports', 'module' ], function(require, exports, module) {
7812
 
 
7813
 
 
7814
 
var Behaviour = function() {
7815
 
   this.$behaviours = {};
7816
 
};
7817
 
 
7818
 
(function () {
7819
 
 
7820
 
    this.add = function (name, action, callback) {
7821
 
        switch (undefined) {
7822
 
          case this.$behaviours:
7823
 
              this.$behaviours = {};
7824
 
          case this.$behaviours[name]:
7825
 
              this.$behaviours[name] = {};
7826
 
        }
7827
 
        this.$behaviours[name][action] = callback;
7828
 
    }
7829
 
    
7830
 
    this.addBehaviours = function (behaviours) {
7831
 
        for (var key in behaviours) {
7832
 
            for (var action in behaviours[key]) {
7833
 
                this.add(key, action, behaviours[key][action]);
7834
 
            }
7835
 
        }
7836
 
    }
7837
 
    
7838
 
    this.remove = function (name) {
7839
 
        if (this.$behaviours && this.$behaviours[name]) {
7840
 
            delete this.$behaviours[name];
7841
 
        }
7842
 
    }
7843
 
    
7844
 
    this.inherit = function (mode, filter) {
7845
 
        if (typeof mode === "function") {
7846
 
            var behaviours = new mode().getBehaviours(filter);
7847
 
        } else {
7848
 
            var behaviours = mode.getBehaviours(filter);
7849
 
        }
7850
 
        this.addBehaviours(behaviours);
7851
 
    }
7852
 
    
7853
 
    this.getBehaviours = function (filter) {
7854
 
        if (!filter) {
7855
 
            return this.$behaviours;
7856
 
        } else {
7857
 
            var ret = {}
7858
 
            for (var i = 0; i < filter.length; i++) {
7859
 
                if (this.$behaviours[filter[i]]) {
7860
 
                    ret[filter[i]] = this.$behaviours[filter[i]];
7861
 
                }
7862
 
            }
7863
 
            return ret;
7864
 
        }
7865
 
    }
7866
 
 
7867
 
}).call(Behaviour.prototype);
7868
 
 
7869
 
exports.Behaviour = Behaviour;
7870
 
});
7871
 
define('ace/unicode', ['require', 'exports', 'module' ], function(require, exports, module) {
7872
 
exports.packages = {};
7873
 
 
7874
 
addUnicodePackage({
7875
 
    L:  "0041-005A0061-007A00AA00B500BA00C0-00D600D8-00F600F8-02C102C6-02D102E0-02E402EC02EE0370-037403760377037A-037D03860388-038A038C038E-03A103A3-03F503F7-0481048A-05250531-055605590561-058705D0-05EA05F0-05F20621-064A066E066F0671-06D306D506E506E606EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA07F407F507FA0800-0815081A082408280904-0939093D09500958-0961097109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E460E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EC60EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10A0-10C510D0-10FA10FC1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317D717DC1820-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541AA71B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C7D1CE9-1CEC1CEE-1CF11D00-1DBF1E00-1F151F18-1F1D1F20-1F451F48-1F4D1F50-1F571F591F5B1F5D1F5F-1F7D1F80-1FB41FB6-1FBC1FBE1FC2-1FC41FC6-1FCC1FD0-1FD31FD6-1FDB1FE0-1FEC1FF2-1FF41FF6-1FFC2071207F2090-209421022107210A-211321152119-211D212421262128212A-212D212F-2139213C-213F2145-2149214E218321842C00-2C2E2C30-2C5E2C60-2CE42CEB-2CEE2D00-2D252D30-2D652D6F2D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE2E2F300530063031-3035303B303C3041-3096309D-309F30A1-30FA30FC-30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A48CA4D0-A4FDA500-A60CA610-A61FA62AA62BA640-A65FA662-A66EA67F-A697A6A0-A6E5A717-A71FA722-A788A78BA78CA7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2A9CFAA00-AA28AA40-AA42AA44-AA4BAA60-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADB-AADDABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB00-FB06FB13-FB17FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF21-FF3AFF41-FF5AFF66-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC",
7876
 
    Ll: "0061-007A00AA00B500BA00DF-00F600F8-00FF01010103010501070109010B010D010F01110113011501170119011B011D011F01210123012501270129012B012D012F01310133013501370138013A013C013E014001420144014601480149014B014D014F01510153015501570159015B015D015F01610163016501670169016B016D016F0171017301750177017A017C017E-0180018301850188018C018D019201950199-019B019E01A101A301A501A801AA01AB01AD01B001B401B601B901BA01BD-01BF01C601C901CC01CE01D001D201D401D601D801DA01DC01DD01DF01E101E301E501E701E901EB01ED01EF01F001F301F501F901FB01FD01FF02010203020502070209020B020D020F02110213021502170219021B021D021F02210223022502270229022B022D022F02310233-0239023C023F0240024202470249024B024D024F-02930295-02AF037103730377037B-037D039003AC-03CE03D003D103D5-03D703D903DB03DD03DF03E103E303E503E703E903EB03ED03EF-03F303F503F803FB03FC0430-045F04610463046504670469046B046D046F04710473047504770479047B047D047F0481048B048D048F04910493049504970499049B049D049F04A104A304A504A704A904AB04AD04AF04B104B304B504B704B904BB04BD04BF04C204C404C604C804CA04CC04CE04CF04D104D304D504D704D904DB04DD04DF04E104E304E504E704E904EB04ED04EF04F104F304F504F704F904FB04FD04FF05010503050505070509050B050D050F05110513051505170519051B051D051F0521052305250561-05871D00-1D2B1D62-1D771D79-1D9A1E011E031E051E071E091E0B1E0D1E0F1E111E131E151E171E191E1B1E1D1E1F1E211E231E251E271E291E2B1E2D1E2F1E311E331E351E371E391E3B1E3D1E3F1E411E431E451E471E491E4B1E4D1E4F1E511E531E551E571E591E5B1E5D1E5F1E611E631E651E671E691E6B1E6D1E6F1E711E731E751E771E791E7B1E7D1E7F1E811E831E851E871E891E8B1E8D1E8F1E911E931E95-1E9D1E9F1EA11EA31EA51EA71EA91EAB1EAD1EAF1EB11EB31EB51EB71EB91EBB1EBD1EBF1EC11EC31EC51EC71EC91ECB1ECD1ECF1ED11ED31ED51ED71ED91EDB1EDD1EDF1EE11EE31EE51EE71EE91EEB1EED1EEF1EF11EF31EF51EF71EF91EFB1EFD1EFF-1F071F10-1F151F20-1F271F30-1F371F40-1F451F50-1F571F60-1F671F70-1F7D1F80-1F871F90-1F971FA0-1FA71FB0-1FB41FB61FB71FBE1FC2-1FC41FC61FC71FD0-1FD31FD61FD71FE0-1FE71FF2-1FF41FF61FF7210A210E210F2113212F21342139213C213D2146-2149214E21842C30-2C5E2C612C652C662C682C6A2C6C2C712C732C742C76-2C7C2C812C832C852C872C892C8B2C8D2C8F2C912C932C952C972C992C9B2C9D2C9F2CA12CA32CA52CA72CA92CAB2CAD2CAF2CB12CB32CB52CB72CB92CBB2CBD2CBF2CC12CC32CC52CC72CC92CCB2CCD2CCF2CD12CD32CD52CD72CD92CDB2CDD2CDF2CE12CE32CE42CEC2CEE2D00-2D25A641A643A645A647A649A64BA64DA64FA651A653A655A657A659A65BA65DA65FA663A665A667A669A66BA66DA681A683A685A687A689A68BA68DA68FA691A693A695A697A723A725A727A729A72BA72DA72F-A731A733A735A737A739A73BA73DA73FA741A743A745A747A749A74BA74DA74FA751A753A755A757A759A75BA75DA75FA761A763A765A767A769A76BA76DA76FA771-A778A77AA77CA77FA781A783A785A787A78CFB00-FB06FB13-FB17FF41-FF5A",
7877
 
    Lu: "0041-005A00C0-00D600D8-00DE01000102010401060108010A010C010E01100112011401160118011A011C011E01200122012401260128012A012C012E01300132013401360139013B013D013F0141014301450147014A014C014E01500152015401560158015A015C015E01600162016401660168016A016C016E017001720174017601780179017B017D018101820184018601870189-018B018E-0191019301940196-0198019C019D019F01A001A201A401A601A701A901AC01AE01AF01B1-01B301B501B701B801BC01C401C701CA01CD01CF01D101D301D501D701D901DB01DE01E001E201E401E601E801EA01EC01EE01F101F401F6-01F801FA01FC01FE02000202020402060208020A020C020E02100212021402160218021A021C021E02200222022402260228022A022C022E02300232023A023B023D023E02410243-02460248024A024C024E03700372037603860388-038A038C038E038F0391-03A103A3-03AB03CF03D2-03D403D803DA03DC03DE03E003E203E403E603E803EA03EC03EE03F403F703F903FA03FD-042F04600462046404660468046A046C046E04700472047404760478047A047C047E0480048A048C048E04900492049404960498049A049C049E04A004A204A404A604A804AA04AC04AE04B004B204B404B604B804BA04BC04BE04C004C104C304C504C704C904CB04CD04D004D204D404D604D804DA04DC04DE04E004E204E404E604E804EA04EC04EE04F004F204F404F604F804FA04FC04FE05000502050405060508050A050C050E05100512051405160518051A051C051E0520052205240531-055610A0-10C51E001E021E041E061E081E0A1E0C1E0E1E101E121E141E161E181E1A1E1C1E1E1E201E221E241E261E281E2A1E2C1E2E1E301E321E341E361E381E3A1E3C1E3E1E401E421E441E461E481E4A1E4C1E4E1E501E521E541E561E581E5A1E5C1E5E1E601E621E641E661E681E6A1E6C1E6E1E701E721E741E761E781E7A1E7C1E7E1E801E821E841E861E881E8A1E8C1E8E1E901E921E941E9E1EA01EA21EA41EA61EA81EAA1EAC1EAE1EB01EB21EB41EB61EB81EBA1EBC1EBE1EC01EC21EC41EC61EC81ECA1ECC1ECE1ED01ED21ED41ED61ED81EDA1EDC1EDE1EE01EE21EE41EE61EE81EEA1EEC1EEE1EF01EF21EF41EF61EF81EFA1EFC1EFE1F08-1F0F1F18-1F1D1F28-1F2F1F38-1F3F1F48-1F4D1F591F5B1F5D1F5F1F68-1F6F1FB8-1FBB1FC8-1FCB1FD8-1FDB1FE8-1FEC1FF8-1FFB21022107210B-210D2110-211221152119-211D212421262128212A-212D2130-2133213E213F214521832C00-2C2E2C602C62-2C642C672C692C6B2C6D-2C702C722C752C7E-2C802C822C842C862C882C8A2C8C2C8E2C902C922C942C962C982C9A2C9C2C9E2CA02CA22CA42CA62CA82CAA2CAC2CAE2CB02CB22CB42CB62CB82CBA2CBC2CBE2CC02CC22CC42CC62CC82CCA2CCC2CCE2CD02CD22CD42CD62CD82CDA2CDC2CDE2CE02CE22CEB2CEDA640A642A644A646A648A64AA64CA64EA650A652A654A656A658A65AA65CA65EA662A664A666A668A66AA66CA680A682A684A686A688A68AA68CA68EA690A692A694A696A722A724A726A728A72AA72CA72EA732A734A736A738A73AA73CA73EA740A742A744A746A748A74AA74CA74EA750A752A754A756A758A75AA75CA75EA760A762A764A766A768A76AA76CA76EA779A77BA77DA77EA780A782A784A786A78BFF21-FF3A",
7878
 
    Lt: "01C501C801CB01F21F88-1F8F1F98-1F9F1FA8-1FAF1FBC1FCC1FFC",
7879
 
    Lm: "02B0-02C102C6-02D102E0-02E402EC02EE0374037A0559064006E506E607F407F507FA081A0824082809710E460EC610FC17D718431AA71C78-1C7D1D2C-1D611D781D9B-1DBF2071207F2090-20942C7D2D6F2E2F30053031-3035303B309D309E30FC-30FEA015A4F8-A4FDA60CA67FA717-A71FA770A788A9CFAA70AADDFF70FF9EFF9F",
7880
 
    Lo: "01BB01C0-01C3029405D0-05EA05F0-05F20621-063F0641-064A066E066F0671-06D306D506EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA0800-08150904-0939093D09500958-096109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E450E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10D0-10FA1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317DC1820-18421844-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C771CE9-1CEC1CEE-1CF12135-21382D30-2D652D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE3006303C3041-3096309F30A1-30FA30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A014A016-A48CA4D0-A4F7A500-A60BA610-A61FA62AA62BA66EA6A0-A6E5A7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2AA00-AA28AA40-AA42AA44-AA4BAA60-AA6FAA71-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADBAADCABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF66-FF6FFF71-FF9DFFA0-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC",
7881
 
    M:  "0300-036F0483-04890591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DE-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0903093C093E-094E0951-0955096209630981-098309BC09BE-09C409C709C809CB-09CD09D709E209E30A01-0A030A3C0A3E-0A420A470A480A4B-0A4D0A510A700A710A750A81-0A830ABC0ABE-0AC50AC7-0AC90ACB-0ACD0AE20AE30B01-0B030B3C0B3E-0B440B470B480B4B-0B4D0B560B570B620B630B820BBE-0BC20BC6-0BC80BCA-0BCD0BD70C01-0C030C3E-0C440C46-0C480C4A-0C4D0C550C560C620C630C820C830CBC0CBE-0CC40CC6-0CC80CCA-0CCD0CD50CD60CE20CE30D020D030D3E-0D440D46-0D480D4A-0D4D0D570D620D630D820D830DCA0DCF-0DD40DD60DD8-0DDF0DF20DF30E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F3E0F3F0F71-0F840F860F870F90-0F970F99-0FBC0FC6102B-103E1056-1059105E-10601062-10641067-106D1071-10741082-108D108F109A-109D135F1712-17141732-1734175217531772177317B6-17D317DD180B-180D18A91920-192B1930-193B19B0-19C019C819C91A17-1A1B1A55-1A5E1A60-1A7C1A7F1B00-1B041B34-1B441B6B-1B731B80-1B821BA1-1BAA1C24-1C371CD0-1CD21CD4-1CE81CED1CF21DC0-1DE61DFD-1DFF20D0-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66F-A672A67CA67DA6F0A6F1A802A806A80BA823-A827A880A881A8B4-A8C4A8E0-A8F1A926-A92DA947-A953A980-A983A9B3-A9C0AA29-AA36AA43AA4CAA4DAA7BAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE3-ABEAABECABEDFB1EFE00-FE0FFE20-FE26",
7882
 
    Mn: "0300-036F0483-04870591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DF-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0902093C0941-0948094D0951-095509620963098109BC09C1-09C409CD09E209E30A010A020A3C0A410A420A470A480A4B-0A4D0A510A700A710A750A810A820ABC0AC1-0AC50AC70AC80ACD0AE20AE30B010B3C0B3F0B41-0B440B4D0B560B620B630B820BC00BCD0C3E-0C400C46-0C480C4A-0C4D0C550C560C620C630CBC0CBF0CC60CCC0CCD0CE20CE30D41-0D440D4D0D620D630DCA0DD2-0DD40DD60E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F71-0F7E0F80-0F840F860F870F90-0F970F99-0FBC0FC6102D-10301032-10371039103A103D103E10581059105E-10601071-1074108210851086108D109D135F1712-17141732-1734175217531772177317B7-17BD17C617C9-17D317DD180B-180D18A91920-19221927192819321939-193B1A171A181A561A58-1A5E1A601A621A65-1A6C1A73-1A7C1A7F1B00-1B031B341B36-1B3A1B3C1B421B6B-1B731B801B811BA2-1BA51BA81BA91C2C-1C331C361C371CD0-1CD21CD4-1CE01CE2-1CE81CED1DC0-1DE61DFD-1DFF20D0-20DC20E120E5-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66FA67CA67DA6F0A6F1A802A806A80BA825A826A8C4A8E0-A8F1A926-A92DA947-A951A980-A982A9B3A9B6-A9B9A9BCAA29-AA2EAA31AA32AA35AA36AA43AA4CAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE5ABE8ABEDFB1EFE00-FE0FFE20-FE26",
7883
 
    Mc: "0903093E-09400949-094C094E0982098309BE-09C009C709C809CB09CC09D70A030A3E-0A400A830ABE-0AC00AC90ACB0ACC0B020B030B3E0B400B470B480B4B0B4C0B570BBE0BBF0BC10BC20BC6-0BC80BCA-0BCC0BD70C01-0C030C41-0C440C820C830CBE0CC0-0CC40CC70CC80CCA0CCB0CD50CD60D020D030D3E-0D400D46-0D480D4A-0D4C0D570D820D830DCF-0DD10DD8-0DDF0DF20DF30F3E0F3F0F7F102B102C10311038103B103C105610571062-10641067-106D108310841087-108C108F109A-109C17B617BE-17C517C717C81923-19261929-192B193019311933-193819B0-19C019C819C91A19-1A1B1A551A571A611A631A641A6D-1A721B041B351B3B1B3D-1B411B431B441B821BA11BA61BA71BAA1C24-1C2B1C341C351CE11CF2A823A824A827A880A881A8B4-A8C3A952A953A983A9B4A9B5A9BAA9BBA9BD-A9C0AA2FAA30AA33AA34AA4DAA7BABE3ABE4ABE6ABE7ABE9ABEAABEC",
7884
 
    Me: "0488048906DE20DD-20E020E2-20E4A670-A672",
7885
 
    N:  "0030-003900B200B300B900BC-00BE0660-066906F0-06F907C0-07C90966-096F09E6-09EF09F4-09F90A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BF20C66-0C6F0C78-0C7E0CE6-0CEF0D66-0D750E50-0E590ED0-0ED90F20-0F331040-10491090-10991369-137C16EE-16F017E0-17E917F0-17F91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C5920702074-20792080-20892150-21822185-21892460-249B24EA-24FF2776-27932CFD30073021-30293038-303A3192-31953220-32293251-325F3280-328932B1-32BFA620-A629A6E6-A6EFA830-A835A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19",
7886
 
    Nd: "0030-00390660-066906F0-06F907C0-07C90966-096F09E6-09EF0A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BEF0C66-0C6F0CE6-0CEF0D66-0D6F0E50-0E590ED0-0ED90F20-0F291040-10491090-109917E0-17E91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C59A620-A629A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19",
7887
 
    Nl: "16EE-16F02160-21822185-218830073021-30293038-303AA6E6-A6EF",
7888
 
    No: "00B200B300B900BC-00BE09F4-09F90BF0-0BF20C78-0C7E0D70-0D750F2A-0F331369-137C17F0-17F920702074-20792080-20892150-215F21892460-249B24EA-24FF2776-27932CFD3192-31953220-32293251-325F3280-328932B1-32BFA830-A835",
7889
 
    P:  "0021-00230025-002A002C-002F003A003B003F0040005B-005D005F007B007D00A100AB00B700BB00BF037E0387055A-055F0589058A05BE05C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F3A-0F3D0F850FD0-0FD4104A-104F10FB1361-13681400166D166E169B169C16EB-16ED1735173617D4-17D617D8-17DA1800-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD32010-20272030-20432045-20512053-205E207D207E208D208E2329232A2768-277527C527C627E6-27EF2983-299829D8-29DB29FC29FD2CF9-2CFC2CFE2CFF2E00-2E2E2E302E313001-30033008-30113014-301F3030303D30A030FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFD3EFD3FFE10-FE19FE30-FE52FE54-FE61FE63FE68FE6AFE6BFF01-FF03FF05-FF0AFF0C-FF0FFF1AFF1BFF1FFF20FF3B-FF3DFF3FFF5BFF5DFF5F-FF65",
7890
 
    Pd: "002D058A05BE140018062010-20152E172E1A301C303030A0FE31FE32FE58FE63FF0D",
7891
 
    Ps: "0028005B007B0F3A0F3C169B201A201E2045207D208D23292768276A276C276E27702772277427C527E627E827EA27EC27EE2983298529872989298B298D298F299129932995299729D829DA29FC2E222E242E262E283008300A300C300E3010301430163018301A301DFD3EFE17FE35FE37FE39FE3BFE3DFE3FFE41FE43FE47FE59FE5BFE5DFF08FF3BFF5BFF5FFF62",
7892
 
    Pe: "0029005D007D0F3B0F3D169C2046207E208E232A2769276B276D276F27712773277527C627E727E927EB27ED27EF298429862988298A298C298E2990299229942996299829D929DB29FD2E232E252E272E293009300B300D300F3011301530173019301B301E301FFD3FFE18FE36FE38FE3AFE3CFE3EFE40FE42FE44FE48FE5AFE5CFE5EFF09FF3DFF5DFF60FF63",
7893
 
    Pi: "00AB2018201B201C201F20392E022E042E092E0C2E1C2E20",
7894
 
    Pf: "00BB2019201D203A2E032E052E0A2E0D2E1D2E21",
7895
 
    Pc: "005F203F20402054FE33FE34FE4D-FE4FFF3F",
7896
 
    Po: "0021-00230025-0027002A002C002E002F003A003B003F0040005C00A100B700BF037E0387055A-055F058905C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F850FD0-0FD4104A-104F10FB1361-1368166D166E16EB-16ED1735173617D4-17D617D8-17DA1800-18051807-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD3201620172020-20272030-2038203B-203E2041-20432047-205120532055-205E2CF9-2CFC2CFE2CFF2E002E012E06-2E082E0B2E0E-2E162E182E192E1B2E1E2E1F2E2A-2E2E2E302E313001-3003303D30FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFE10-FE16FE19FE30FE45FE46FE49-FE4CFE50-FE52FE54-FE57FE5F-FE61FE68FE6AFE6BFF01-FF03FF05-FF07FF0AFF0CFF0EFF0FFF1AFF1BFF1FFF20FF3CFF61FF64FF65",
7897
 
    S:  "0024002B003C-003E005E0060007C007E00A2-00A900AC00AE-00B100B400B600B800D700F702C2-02C502D2-02DF02E5-02EB02ED02EF-02FF03750384038503F604820606-0608060B060E060F06E906FD06FE07F609F209F309FA09FB0AF10B700BF3-0BFA0C7F0CF10CF20D790E3F0F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-139917DB194019E0-19FF1B61-1B6A1B74-1B7C1FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE20442052207A-207C208A-208C20A0-20B8210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B2140-2144214A-214D214F2190-2328232B-23E82400-24262440-244A249C-24E92500-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE27C0-27C427C7-27CA27CC27D0-27E527F0-29822999-29D729DC-29FB29FE-2B4C2B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F309B309C319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A700-A716A720A721A789A78AA828-A82BA836-A839AA77-AA79FB29FDFCFDFDFE62FE64-FE66FE69FF04FF0BFF1C-FF1EFF3EFF40FF5CFF5EFFE0-FFE6FFE8-FFEEFFFCFFFD",
7898
 
    Sm: "002B003C-003E007C007E00AC00B100D700F703F60606-060820442052207A-207C208A-208C2140-2144214B2190-2194219A219B21A021A321A621AE21CE21CF21D221D421F4-22FF2308-230B23202321237C239B-23B323DC-23E125B725C125F8-25FF266F27C0-27C427C7-27CA27CC27D0-27E527F0-27FF2900-29822999-29D729DC-29FB29FE-2AFF2B30-2B442B47-2B4CFB29FE62FE64-FE66FF0BFF1C-FF1EFF5CFF5EFFE2FFE9-FFEC",
7899
 
    Sc: "002400A2-00A5060B09F209F309FB0AF10BF90E3F17DB20A0-20B8A838FDFCFE69FF04FFE0FFE1FFE5FFE6",
7900
 
    Sk: "005E006000A800AF00B400B802C2-02C502D2-02DF02E5-02EB02ED02EF-02FF0375038403851FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE309B309CA700-A716A720A721A789A78AFF3EFF40FFE3",
7901
 
    So: "00A600A700A900AE00B000B60482060E060F06E906FD06FE07F609FA0B700BF3-0BF80BFA0C7F0CF10CF20D790F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-1399194019E0-19FF1B61-1B6A1B74-1B7C210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B214A214C214D214F2195-2199219C-219F21A121A221A421A521A7-21AD21AF-21CD21D021D121D321D5-21F32300-2307230C-231F2322-2328232B-237B237D-239A23B4-23DB23E2-23E82400-24262440-244A249C-24E92500-25B625B8-25C025C2-25F72600-266E2670-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE2800-28FF2B00-2B2F2B452B462B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A828-A82BA836A837A839AA77-AA79FDFDFFE4FFE8FFEDFFEEFFFCFFFD",
7902
 
    Z:  "002000A01680180E2000-200A20282029202F205F3000",
7903
 
    Zs: "002000A01680180E2000-200A202F205F3000",
7904
 
    Zl: "2028",
7905
 
    Zp: "2029",
7906
 
    C:  "0000-001F007F-009F00AD03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-0605061C061D0620065F06DD070E070F074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17B417B517DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF200B-200F202A-202E2060-206F20722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-F8FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFD-FF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFFBFFFEFFFF",
7907
 
    Cc: "0000-001F007F-009F",
7908
 
    Cf: "00AD0600-060306DD070F17B417B5200B-200F202A-202E2060-2064206A-206FFEFFFFF9-FFFB",
7909
 
    Co: "E000-F8FF",
7910
 
    Cs: "D800-DFFF",
7911
 
    Cn: "03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-05FF06040605061C061D0620065F070E074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF2065-206920722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-D7FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFDFEFEFF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFF8FFFEFFFF"
7912
 
});
7913
 
 
7914
 
function addUnicodePackage (pack) {
7915
 
    var codePoint = /\w{4}/g;
7916
 
    for (var name in pack)
7917
 
        exports.packages[name] = pack[name].replace(codePoint, "\\u$&");
7918
 
};
7919
 
 
7920
 
});
7921
 
 
7922
 
define('ace/document', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter', 'ace/range', 'ace/anchor'], function(require, exports, module) {
7923
 
 
7924
 
 
7925
 
var oop = require("./lib/oop");
7926
 
var EventEmitter = require("./lib/event_emitter").EventEmitter;
7927
 
var Range = require("./range").Range;
7928
 
var Anchor = require("./anchor").Anchor;
7929
 
 
7930
 
var Document = function(text) {
7931
 
    this.$lines = [];
7932
 
    if (text.length == 0) {
7933
 
        this.$lines = [""];
7934
 
    } else if (Array.isArray(text)) {
7935
 
        this.insertLines(0, text);
7936
 
    } else {
7937
 
        this.insert({row: 0, column:0}, text);
7938
 
    }
7939
 
};
7940
 
 
7941
 
(function() {
7942
 
 
7943
 
    oop.implement(this, EventEmitter);
7944
 
    this.setValue = function(text) {
7945
 
        var len = this.getLength();
7946
 
        this.remove(new Range(0, 0, len, this.getLine(len-1).length));
7947
 
        this.insert({row: 0, column:0}, text);
7948
 
    };
7949
 
    this.getValue = function() {
7950
 
        return this.getAllLines().join(this.getNewLineCharacter());
7951
 
    };
7952
 
    this.createAnchor = function(row, column) {
7953
 
        return new Anchor(this, row, column);
7954
 
    };
7955
 
    if ("aaa".split(/a/).length == 0)
7956
 
        this.$split = function(text) {
7957
 
            return text.replace(/\r\n|\r/g, "\n").split("\n");
7958
 
        }
7959
 
    else
7960
 
        this.$split = function(text) {
7961
 
            return text.split(/\r\n|\r|\n/);
7962
 
        };
7963
 
 
7964
 
 
7965
 
 
7966
 
    this.$detectNewLine = function(text) {
7967
 
        var match = text.match(/^.*?(\r\n|\r|\n)/m);
7968
 
        if (match) {
7969
 
            this.$autoNewLine = match[1];
7970
 
        } else {
7971
 
            this.$autoNewLine = "\n";
7972
 
        }
7973
 
    };
7974
 
    this.getNewLineCharacter = function() {
7975
 
        switch (this.$newLineMode) {
7976
 
          case "windows":
7977
 
            return "\r\n";
7978
 
 
7979
 
          case "unix":
7980
 
            return "\n";
7981
 
 
7982
 
          default:
7983
 
            return this.$autoNewLine;
7984
 
        }
7985
 
    };
7986
 
 
7987
 
    this.$autoNewLine = "\n";
7988
 
    this.$newLineMode = "auto";
7989
 
    this.setNewLineMode = function(newLineMode) {
7990
 
        if (this.$newLineMode === newLineMode)
7991
 
            return;
7992
 
 
7993
 
        this.$newLineMode = newLineMode;
7994
 
    };
7995
 
    this.getNewLineMode = function() {
7996
 
        return this.$newLineMode;
7997
 
    };
7998
 
    this.isNewLine = function(text) {
7999
 
        return (text == "\r\n" || text == "\r" || text == "\n");
8000
 
    };
8001
 
    this.getLine = function(row) {
8002
 
        return this.$lines[row] || "";
8003
 
    };
8004
 
    this.getLines = function(firstRow, lastRow) {
8005
 
        return this.$lines.slice(firstRow, lastRow + 1);
8006
 
    };
8007
 
    this.getAllLines = function() {
8008
 
        return this.getLines(0, this.getLength());
8009
 
    };
8010
 
    this.getLength = function() {
8011
 
        return this.$lines.length;
8012
 
    };
8013
 
    this.getTextRange = function(range) {
8014
 
        if (range.start.row == range.end.row) {
8015
 
            return this.$lines[range.start.row].substring(range.start.column,
8016
 
                                                         range.end.column);
8017
 
        }
8018
 
        else {
8019
 
            var lines = this.getLines(range.start.row+1, range.end.row-1);
8020
 
            lines.unshift((this.$lines[range.start.row] || "").substring(range.start.column));
8021
 
            lines.push((this.$lines[range.end.row] || "").substring(0, range.end.column));
8022
 
            return lines.join(this.getNewLineCharacter());
8023
 
        }
8024
 
    };
8025
 
 
8026
 
    this.$clipPosition = function(position) {
8027
 
        var length = this.getLength();
8028
 
        if (position.row >= length) {
8029
 
            position.row = Math.max(0, length - 1);
8030
 
            position.column = this.getLine(length-1).length;
8031
 
        }
8032
 
        return position;
8033
 
    };
8034
 
    this.insert = function(position, text) {
8035
 
        if (!text || text.length === 0)
8036
 
            return position;
8037
 
 
8038
 
        position = this.$clipPosition(position);
8039
 
        if (this.getLength() <= 1)
8040
 
            this.$detectNewLine(text);
8041
 
 
8042
 
        var lines = this.$split(text);
8043
 
        var firstLine = lines.splice(0, 1)[0];
8044
 
        var lastLine = lines.length == 0 ? null : lines.splice(lines.length - 1, 1)[0];
8045
 
 
8046
 
        position = this.insertInLine(position, firstLine);
8047
 
        if (lastLine !== null) {
8048
 
            position = this.insertNewLine(position); // terminate first line
8049
 
            position = this.insertLines(position.row, lines);
8050
 
            position = this.insertInLine(position, lastLine || "");
8051
 
        }
8052
 
        return position;
8053
 
    };
8054
 
    this.insertLines = function(row, lines) {
8055
 
        if (lines.length == 0)
8056
 
            return {row: row, column: 0};
8057
 
        if (lines.length > 0xFFFF) {
8058
 
            var end = this.insertLines(row, lines.slice(0xFFFF));
8059
 
            lines = lines.slice(0, 0xFFFF);
8060
 
        }
8061
 
 
8062
 
        var args = [row, 0];
8063
 
        args.push.apply(args, lines);
8064
 
        this.$lines.splice.apply(this.$lines, args);
8065
 
 
8066
 
        var range = new Range(row, 0, row + lines.length, 0);
8067
 
        var delta = {
8068
 
            action: "insertLines",
8069
 
            range: range,
8070
 
            lines: lines
8071
 
        };
8072
 
        this._emit("change", { data: delta });
8073
 
        return end || range.end;
8074
 
    };
8075
 
    this.insertNewLine = function(position) {
8076
 
        position = this.$clipPosition(position);
8077
 
        var line = this.$lines[position.row] || "";
8078
 
 
8079
 
        this.$lines[position.row] = line.substring(0, position.column);
8080
 
        this.$lines.splice(position.row + 1, 0, line.substring(position.column, line.length));
8081
 
 
8082
 
        var end = {
8083
 
            row : position.row + 1,
8084
 
            column : 0
8085
 
        };
8086
 
 
8087
 
        var delta = {
8088
 
            action: "insertText",
8089
 
            range: Range.fromPoints(position, end),
8090
 
            text: this.getNewLineCharacter()
8091
 
        };
8092
 
        this._emit("change", { data: delta });
8093
 
 
8094
 
        return end;
8095
 
    };
8096
 
    this.insertInLine = function(position, text) {
8097
 
        if (text.length == 0)
8098
 
            return position;
8099
 
 
8100
 
        var line = this.$lines[position.row] || "";
8101
 
 
8102
 
        this.$lines[position.row] = line.substring(0, position.column) + text
8103
 
                + line.substring(position.column);
8104
 
 
8105
 
        var end = {
8106
 
            row : position.row,
8107
 
            column : position.column + text.length
8108
 
        };
8109
 
 
8110
 
        var delta = {
8111
 
            action: "insertText",
8112
 
            range: Range.fromPoints(position, end),
8113
 
            text: text
8114
 
        };
8115
 
        this._emit("change", { data: delta });
8116
 
 
8117
 
        return end;
8118
 
    };
8119
 
    this.remove = function(range) {
8120
 
        range.start = this.$clipPosition(range.start);
8121
 
        range.end = this.$clipPosition(range.end);
8122
 
 
8123
 
        if (range.isEmpty())
8124
 
            return range.start;
8125
 
 
8126
 
        var firstRow = range.start.row;
8127
 
        var lastRow = range.end.row;
8128
 
 
8129
 
        if (range.isMultiLine()) {
8130
 
            var firstFullRow = range.start.column == 0 ? firstRow : firstRow + 1;
8131
 
            var lastFullRow = lastRow - 1;
8132
 
 
8133
 
            if (range.end.column > 0)
8134
 
                this.removeInLine(lastRow, 0, range.end.column);
8135
 
 
8136
 
            if (lastFullRow >= firstFullRow)
8137
 
                this.removeLines(firstFullRow, lastFullRow);
8138
 
 
8139
 
            if (firstFullRow != firstRow) {
8140
 
                this.removeInLine(firstRow, range.start.column, this.getLine(firstRow).length);
8141
 
                this.removeNewLine(range.start.row);
8142
 
            }
8143
 
        }
8144
 
        else {
8145
 
            this.removeInLine(firstRow, range.start.column, range.end.column);
8146
 
        }
8147
 
        return range.start;
8148
 
    };
8149
 
    this.removeInLine = function(row, startColumn, endColumn) {
8150
 
        if (startColumn == endColumn)
8151
 
            return;
8152
 
 
8153
 
        var range = new Range(row, startColumn, row, endColumn);
8154
 
        var line = this.getLine(row);
8155
 
        var removed = line.substring(startColumn, endColumn);
8156
 
        var newLine = line.substring(0, startColumn) + line.substring(endColumn, line.length);
8157
 
        this.$lines.splice(row, 1, newLine);
8158
 
 
8159
 
        var delta = {
8160
 
            action: "removeText",
8161
 
            range: range,
8162
 
            text: removed
8163
 
        };
8164
 
        this._emit("change", { data: delta });
8165
 
        return range.start;
8166
 
    };
8167
 
    this.removeLines = function(firstRow, lastRow) {
8168
 
        var range = new Range(firstRow, 0, lastRow + 1, 0);
8169
 
        var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1);
8170
 
 
8171
 
        var delta = {
8172
 
            action: "removeLines",
8173
 
            range: range,
8174
 
            nl: this.getNewLineCharacter(),
8175
 
            lines: removed
8176
 
        };
8177
 
        this._emit("change", { data: delta });
8178
 
        return removed;
8179
 
    };
8180
 
    this.removeNewLine = function(row) {
8181
 
        var firstLine = this.getLine(row);
8182
 
        var secondLine = this.getLine(row+1);
8183
 
 
8184
 
        var range = new Range(row, firstLine.length, row+1, 0);
8185
 
        var line = firstLine + secondLine;
8186
 
 
8187
 
        this.$lines.splice(row, 2, line);
8188
 
 
8189
 
        var delta = {
8190
 
            action: "removeText",
8191
 
            range: range,
8192
 
            text: this.getNewLineCharacter()
8193
 
        };
8194
 
        this._emit("change", { data: delta });
8195
 
    };
8196
 
    this.replace = function(range, text) {
8197
 
        if (text.length == 0 && range.isEmpty())
8198
 
            return range.start;
8199
 
        if (text == this.getTextRange(range))
8200
 
            return range.end;
8201
 
 
8202
 
        this.remove(range);
8203
 
        if (text) {
8204
 
            var end = this.insert(range.start, text);
8205
 
        }
8206
 
        else {
8207
 
            end = range.start;
8208
 
        }
8209
 
 
8210
 
        return end;
8211
 
    };
8212
 
    this.applyDeltas = function(deltas) {
8213
 
        for (var i=0; i<deltas.length; i++) {
8214
 
            var delta = deltas[i];
8215
 
            var range = Range.fromPoints(delta.range.start, delta.range.end);
8216
 
 
8217
 
            if (delta.action == "insertLines")
8218
 
                this.insertLines(range.start.row, delta.lines);
8219
 
            else if (delta.action == "insertText")
8220
 
                this.insert(range.start, delta.text);
8221
 
            else if (delta.action == "removeLines")
8222
 
                this.removeLines(range.start.row, range.end.row - 1);
8223
 
            else if (delta.action == "removeText")
8224
 
                this.remove(range);
8225
 
        }
8226
 
    };
8227
 
    this.revertDeltas = function(deltas) {
8228
 
        for (var i=deltas.length-1; i>=0; i--) {
8229
 
            var delta = deltas[i];
8230
 
 
8231
 
            var range = Range.fromPoints(delta.range.start, delta.range.end);
8232
 
 
8233
 
            if (delta.action == "insertLines")
8234
 
                this.removeLines(range.start.row, range.end.row - 1);
8235
 
            else if (delta.action == "insertText")
8236
 
                this.remove(range);
8237
 
            else if (delta.action == "removeLines")
8238
 
                this.insertLines(range.start.row, delta.lines);
8239
 
            else if (delta.action == "removeText")
8240
 
                this.insert(range.start, delta.text);
8241
 
        }
8242
 
    };
8243
 
    this.indexToPosition = function(index, startRow) {
8244
 
        var lines = this.$lines || this.getAllLines();
8245
 
        var newlineLength = this.getNewLineCharacter().length;
8246
 
        for (var i = startRow || 0, l = lines.length; i < l; i++) {
8247
 
            index -= lines[i].length + newlineLength;
8248
 
            if (index < 0)
8249
 
                return {row: i, column: index + lines[i].length + newlineLength};
8250
 
        }
8251
 
        return {row: l-1, column: lines[l-1].length};
8252
 
    };
8253
 
    this.positionToIndex = function(pos, startRow) {
8254
 
        var lines = this.$lines || this.getAllLines();
8255
 
        var newlineLength = this.getNewLineCharacter().length;
8256
 
        var index = 0;
8257
 
        var row = Math.min(pos.row, lines.length);
8258
 
        for (var i = startRow || 0; i < row; ++i)
8259
 
            index += lines[i].length;
8260
 
 
8261
 
        return index + newlineLength * i + pos.column;
8262
 
    };
8263
 
 
8264
 
}).call(Document.prototype);
8265
 
 
8266
 
exports.Document = Document;
8267
 
});
8268
 
 
8269
 
define('ace/anchor', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter'], function(require, exports, module) {
8270
 
 
8271
 
 
8272
 
var oop = require("./lib/oop");
8273
 
var EventEmitter = require("./lib/event_emitter").EventEmitter;
8274
 
 
8275
 
var Anchor = exports.Anchor = function(doc, row, column) {
8276
 
    this.document = doc;
8277
 
    
8278
 
    if (typeof column == "undefined")
8279
 
        this.setPosition(row.row, row.column);
8280
 
    else
8281
 
        this.setPosition(row, column);
8282
 
 
8283
 
    this.$onChange = this.onChange.bind(this);
8284
 
    doc.on("change", this.$onChange);
8285
 
};
8286
 
 
8287
 
(function() {
8288
 
 
8289
 
    oop.implement(this, EventEmitter);
8290
 
 
8291
 
    this.getPosition = function() {
8292
 
        return this.$clipPositionToDocument(this.row, this.column);
8293
 
    };
8294
 
        
8295
 
    this.getDocument = function() {
8296
 
        return this.document;
8297
 
    };
8298
 
 
8299
 
    this.onChange = function(e) {
8300
 
        var delta = e.data;
8301
 
        var range = delta.range;
8302
 
            
8303
 
        if (range.start.row == range.end.row && range.start.row != this.row)
8304
 
            return;
8305
 
            
8306
 
        if (range.start.row > this.row)
8307
 
            return;
8308
 
            
8309
 
        if (range.start.row == this.row && range.start.column > this.column)
8310
 
            return;
8311
 
    
8312
 
        var row = this.row;
8313
 
        var column = this.column;
8314
 
        
8315
 
        if (delta.action === "insertText") {
8316
 
            if (range.start.row === row && range.start.column <= column) {
8317
 
                if (range.start.row === range.end.row) {
8318
 
                    column += range.end.column - range.start.column;
8319
 
                }
8320
 
                else {
8321
 
                    column -= range.start.column;
8322
 
                    row += range.end.row - range.start.row;
8323
 
                }
8324
 
            }
8325
 
            else if (range.start.row !== range.end.row && range.start.row < row) {
8326
 
                row += range.end.row - range.start.row;
8327
 
            }
8328
 
        } else if (delta.action === "insertLines") {
8329
 
            if (range.start.row <= row) {
8330
 
                row += range.end.row - range.start.row;
8331
 
            }
8332
 
        }
8333
 
        else if (delta.action == "removeText") {
8334
 
            if (range.start.row == row && range.start.column < column) {
8335
 
                if (range.end.column >= column)
8336
 
                    column = range.start.column;
8337
 
                else
8338
 
                    column = Math.max(0, column - (range.end.column - range.start.column));
8339
 
                
8340
 
            } else if (range.start.row !== range.end.row && range.start.row < row) {
8341
 
                if (range.end.row == row) {
8342
 
                    column = Math.max(0, column - range.end.column) + range.start.column;
8343
 
                }
8344
 
                row -= (range.end.row - range.start.row);
8345
 
            }
8346
 
            else if (range.end.row == row) {
8347
 
                row -= range.end.row - range.start.row;
8348
 
                column = Math.max(0, column - range.end.column) + range.start.column;
8349
 
            }
8350
 
        } else if (delta.action == "removeLines") {
8351
 
            if (range.start.row <= row) {
8352
 
                if (range.end.row <= row)
8353
 
                    row -= range.end.row - range.start.row;
8354
 
                else {
8355
 
                    row = range.start.row;
8356
 
                    column = 0;
8357
 
                }
8358
 
            }
8359
 
        }
8360
 
 
8361
 
        this.setPosition(row, column, true);
8362
 
    };
8363
 
 
8364
 
    this.setPosition = function(row, column, noClip) {
8365
 
        var pos;
8366
 
        if (noClip) {
8367
 
            pos = {
8368
 
                row: row,
8369
 
                column: column
8370
 
            };
8371
 
        }
8372
 
        else {
8373
 
            pos = this.$clipPositionToDocument(row, column);
8374
 
        }
8375
 
        
8376
 
        if (this.row == pos.row && this.column == pos.column)
8377
 
            return;
8378
 
            
8379
 
        var old = {
8380
 
            row: this.row,
8381
 
            column: this.column
8382
 
        };
8383
 
        
8384
 
        this.row = pos.row;
8385
 
        this.column = pos.column;
8386
 
        this._emit("change", {
8387
 
            old: old,
8388
 
            value: pos
8389
 
        });
8390
 
    };
8391
 
 
8392
 
    this.detach = function() {
8393
 
        this.document.removeEventListener("change", this.$onChange);
8394
 
    };
8395
 
    this.$clipPositionToDocument = function(row, column) {
8396
 
        var pos = {};
8397
 
    
8398
 
        if (row >= this.document.getLength()) {
8399
 
            pos.row = Math.max(0, this.document.getLength() - 1);
8400
 
            pos.column = this.document.getLine(pos.row).length;
8401
 
        }
8402
 
        else if (row < 0) {
8403
 
            pos.row = 0;
8404
 
            pos.column = 0;
8405
 
        }
8406
 
        else {
8407
 
            pos.row = row;
8408
 
            pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column));
8409
 
        }
8410
 
        
8411
 
        if (column < 0)
8412
 
            pos.column = 0;
8413
 
            
8414
 
        return pos;
8415
 
    };
8416
 
    
8417
 
}).call(Anchor.prototype);
8418
 
 
8419
 
});
8420
 
 
8421
 
define('ace/background_tokenizer', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter'], function(require, exports, module) {
8422
 
 
8423
 
 
8424
 
var oop = require("./lib/oop");
8425
 
var EventEmitter = require("./lib/event_emitter").EventEmitter;
8426
 
 
8427
 
var BackgroundTokenizer = function(tokenizer, editor) {
8428
 
    this.running = false;
8429
 
    this.lines = [];
8430
 
    this.states = [];
8431
 
    this.currentLine = 0;
8432
 
    this.tokenizer = tokenizer;
8433
 
 
8434
 
    var self = this;
8435
 
 
8436
 
    this.$worker = function() {
8437
 
        if (!self.running) { return; }
8438
 
 
8439
 
        var workerStart = new Date();
8440
 
        var startLine = self.currentLine;
8441
 
        var doc = self.doc;
8442
 
 
8443
 
        var processedLines = 0;
8444
 
 
8445
 
        var len = doc.getLength();
8446
 
        while (self.currentLine < len) {
8447
 
            self.$tokenizeRow(self.currentLine);
8448
 
            while (self.lines[self.currentLine])
8449
 
                self.currentLine++;
8450
 
            processedLines ++;
8451
 
            if ((processedLines % 5 == 0) && (new Date() - workerStart) > 20) {
8452
 
                self.fireUpdateEvent(startLine, self.currentLine-1);
8453
 
                self.running = setTimeout(self.$worker, 20);
8454
 
                return;
8455
 
            }
8456
 
        }
8457
 
 
8458
 
        self.running = false;
8459
 
 
8460
 
        self.fireUpdateEvent(startLine, len - 1);
8461
 
    };
8462
 
};
8463
 
 
8464
 
(function(){
8465
 
 
8466
 
    oop.implement(this, EventEmitter);
8467
 
    this.setTokenizer = function(tokenizer) {
8468
 
        this.tokenizer = tokenizer;
8469
 
        this.lines = [];
8470
 
        this.states = [];
8471
 
 
8472
 
        this.start(0);
8473
 
    };
8474
 
    this.setDocument = function(doc) {
8475
 
        this.doc = doc;
8476
 
        this.lines = [];
8477
 
        this.states = [];
8478
 
 
8479
 
        this.stop();
8480
 
    };
8481
 
    this.fireUpdateEvent = function(firstRow, lastRow) {
8482
 
        var data = {
8483
 
            first: firstRow,
8484
 
            last: lastRow
8485
 
        };
8486
 
        this._emit("update", {data: data});
8487
 
    };
8488
 
    this.start = function(startRow) {
8489
 
        this.currentLine = Math.min(startRow || 0, this.currentLine, this.doc.getLength());
8490
 
        this.lines.splice(this.currentLine, this.lines.length);
8491
 
        this.states.splice(this.currentLine, this.states.length);
8492
 
 
8493
 
        this.stop();
8494
 
        this.running = setTimeout(this.$worker, 700);
8495
 
    };
8496
 
 
8497
 
    this.$updateOnChange = function(delta) {
8498
 
        var range = delta.range;
8499
 
        var startRow = range.start.row;
8500
 
        var len = range.end.row - startRow;
8501
 
 
8502
 
        if (len === 0) {
8503
 
            this.lines[startRow] = null;
8504
 
        } else if (delta.action == "removeText" || delta.action == "removeLines") {
8505
 
            this.lines.splice(startRow, len + 1, null);
8506
 
            this.states.splice(startRow, len + 1, null);
8507
 
        } else {
8508
 
            var args = Array(len + 1);
8509
 
            args.unshift(startRow, 1);
8510
 
            this.lines.splice.apply(this.lines, args);
8511
 
            this.states.splice.apply(this.states, args);
8512
 
        }
8513
 
 
8514
 
        this.currentLine = Math.min(startRow, this.currentLine, this.doc.getLength());
8515
 
 
8516
 
        this.stop();
8517
 
        this.running = setTimeout(this.$worker, 700);
8518
 
    };
8519
 
    this.stop = function() {
8520
 
        if (this.running)
8521
 
            clearTimeout(this.running);
8522
 
        this.running = false;
8523
 
    };
8524
 
    this.getTokens = function(row) {
8525
 
        return this.lines[row] || this.$tokenizeRow(row);
8526
 
    };
8527
 
    this.getState = function(row) {
8528
 
        if (this.currentLine == row)
8529
 
            this.$tokenizeRow(row);
8530
 
        return this.states[row] || "start";
8531
 
    };
8532
 
 
8533
 
    this.$tokenizeRow = function(row) {
8534
 
        var line = this.doc.getLine(row);
8535
 
        var state = this.states[row - 1];
8536
 
 
8537
 
        var data = this.tokenizer.getLineTokens(line, state, row);
8538
 
 
8539
 
        if (this.states[row] + "" !== data.state + "") {
8540
 
            this.states[row] = data.state;
8541
 
            this.lines[row + 1] = null;
8542
 
            if (this.currentLine > row + 1)
8543
 
                this.currentLine = row + 1;
8544
 
        } else if (this.currentLine == row) {
8545
 
            this.currentLine = row + 1;
8546
 
        }
8547
 
 
8548
 
        return this.lines[row] = data.tokens;
8549
 
    };
8550
 
 
8551
 
}).call(BackgroundTokenizer.prototype);
8552
 
 
8553
 
exports.BackgroundTokenizer = BackgroundTokenizer;
8554
 
});
8555
 
 
8556
 
define('ace/search_highlight', ['require', 'exports', 'module' , 'ace/lib/lang', 'ace/lib/oop', 'ace/range'], function(require, exports, module) {
8557
 
 
8558
 
 
8559
 
var lang = require("./lib/lang");
8560
 
var oop = require("./lib/oop");
8561
 
var Range = require("./range").Range;
8562
 
 
8563
 
var SearchHighlight = function(regExp, clazz, type) {
8564
 
    this.setRegexp(regExp);
8565
 
    this.clazz = clazz;
8566
 
    this.type = type || "text";
8567
 
};
8568
 
 
8569
 
(function() {
8570
 
    this.MAX_RANGES = 500;
8571
 
    
8572
 
    this.setRegexp = function(regExp) {
8573
 
        if (this.regExp+"" == regExp+"")
8574
 
            return;
8575
 
        this.regExp = regExp;
8576
 
        this.cache = [];
8577
 
    };
8578
 
 
8579
 
    this.update = function(html, markerLayer, session, config) {
8580
 
        if (!this.regExp)
8581
 
            return;
8582
 
        var start = config.firstRow, end = config.lastRow;
8583
 
 
8584
 
        for (var i = start; i <= end; i++) {
8585
 
            var ranges = this.cache[i];
8586
 
            if (ranges == null) {
8587
 
                ranges = lang.getMatchOffsets(session.getLine(i), this.regExp);
8588
 
                if (ranges.length > this.MAX_RANGES)
8589
 
                    ranges = ranges.slice(0, this.MAX_RANGES);
8590
 
                ranges = ranges.map(function(match) {
8591
 
                    return new Range(i, match.offset, i, match.offset + match.length);
8592
 
                });
8593
 
                this.cache[i] = ranges.length ? ranges : "";
8594
 
            }
8595
 
 
8596
 
            for (var j = ranges.length; j --; ) {
8597
 
                markerLayer.drawSingleLineMarker(
8598
 
                    html, ranges[j].toScreenRange(session), this.clazz, config,
8599
 
                    null, this.type
8600
 
                );
8601
 
            }
8602
 
        }
8603
 
    };
8604
 
 
8605
 
}).call(SearchHighlight.prototype);
8606
 
 
8607
 
exports.SearchHighlight = SearchHighlight;
8608
 
});
8609
 
 
8610
 
define('ace/edit_session/folding', ['require', 'exports', 'module' , 'ace/range', 'ace/edit_session/fold_line', 'ace/edit_session/fold', 'ace/token_iterator'], function(require, exports, module) {
8611
 
 
8612
 
 
8613
 
var Range = require("../range").Range;
8614
 
var FoldLine = require("./fold_line").FoldLine;
8615
 
var Fold = require("./fold").Fold;
8616
 
var TokenIterator = require("../token_iterator").TokenIterator;
8617
 
 
8618
 
function Folding() {
8619
 
    this.getFoldAt = function(row, column, side) {
8620
 
        var foldLine = this.getFoldLine(row);
8621
 
        if (!foldLine)
8622
 
            return null;
8623
 
 
8624
 
        var folds = foldLine.folds;
8625
 
        for (var i = 0; i < folds.length; i++) {
8626
 
            var fold = folds[i];
8627
 
            if (fold.range.contains(row, column)) {
8628
 
                if (side == 1 && fold.range.isEnd(row, column)) {
8629
 
                    continue;
8630
 
                } else if (side == -1 && fold.range.isStart(row, column)) {
8631
 
                    continue;
8632
 
                }
8633
 
                return fold;
8634
 
            }
8635
 
        }
8636
 
    };
8637
 
    this.getFoldsInRange = function(range) {
8638
 
        var start = range.start;
8639
 
        var end = range.end;
8640
 
        var foldLines = this.$foldData;
8641
 
        var foundFolds = [];
8642
 
 
8643
 
        start.column += 1;
8644
 
        end.column -= 1;
8645
 
 
8646
 
        for (var i = 0; i < foldLines.length; i++) {
8647
 
            var cmp = foldLines[i].range.compareRange(range);
8648
 
            if (cmp == 2) {
8649
 
                continue;
8650
 
            }
8651
 
            else if (cmp == -2) {
8652
 
                break;
8653
 
            }
8654
 
 
8655
 
            var folds = foldLines[i].folds;
8656
 
            for (var j = 0; j < folds.length; j++) {
8657
 
                var fold = folds[j];
8658
 
                cmp = fold.range.compareRange(range);
8659
 
                if (cmp == -2) {
8660
 
                    break;
8661
 
                } else if (cmp == 2) {
8662
 
                    continue;
8663
 
                } else
8664
 
                if (cmp == 42) {
8665
 
                    break;
8666
 
                }
8667
 
                foundFolds.push(fold);
8668
 
            }
8669
 
        }
8670
 
        start.column -= 1;
8671
 
        end.column += 1;
8672
 
 
8673
 
        return foundFolds;
8674
 
    };
8675
 
    this.getAllFolds = function() {
8676
 
        var folds = [];
8677
 
        var foldLines = this.$foldData;
8678
 
        
8679
 
        function addFold(fold) {
8680
 
            folds.push(fold);
8681
 
        }
8682
 
        
8683
 
        for (var i = 0; i < foldLines.length; i++)
8684
 
            for (var j = 0; j < foldLines[i].folds.length; j++)
8685
 
                addFold(foldLines[i].folds[j]);
8686
 
 
8687
 
        return folds;
8688
 
    };
8689
 
    this.getFoldStringAt = function(row, column, trim, foldLine) {
8690
 
        foldLine = foldLine || this.getFoldLine(row);
8691
 
        if (!foldLine)
8692
 
            return null;
8693
 
 
8694
 
        var lastFold = {
8695
 
            end: { column: 0 }
8696
 
        };
8697
 
        var str, fold;
8698
 
        for (var i = 0; i < foldLine.folds.length; i++) {
8699
 
            fold = foldLine.folds[i];
8700
 
            var cmp = fold.range.compareEnd(row, column);
8701
 
            if (cmp == -1) {
8702
 
                str = this
8703
 
                    .getLine(fold.start.row)
8704
 
                    .substring(lastFold.end.column, fold.start.column);
8705
 
                break;
8706
 
            }
8707
 
            else if (cmp === 0) {
8708
 
                return null;
8709
 
            }
8710
 
            lastFold = fold;
8711
 
        }
8712
 
        if (!str)
8713
 
            str = this.getLine(fold.start.row).substring(lastFold.end.column);
8714
 
 
8715
 
        if (trim == -1)
8716
 
            return str.substring(0, column - lastFold.end.column);
8717
 
        else if (trim == 1)
8718
 
            return str.substring(column - lastFold.end.column);
8719
 
        else
8720
 
            return str;
8721
 
    };
8722
 
 
8723
 
    this.getFoldLine = function(docRow, startFoldLine) {
8724
 
        var foldData = this.$foldData;
8725
 
        var i = 0;
8726
 
        if (startFoldLine)
8727
 
            i = foldData.indexOf(startFoldLine);
8728
 
        if (i == -1)
8729
 
            i = 0;
8730
 
        for (i; i < foldData.length; i++) {
8731
 
            var foldLine = foldData[i];
8732
 
            if (foldLine.start.row <= docRow && foldLine.end.row >= docRow) {
8733
 
                return foldLine;
8734
 
            } else if (foldLine.end.row > docRow) {
8735
 
                return null;
8736
 
            }
8737
 
        }
8738
 
        return null;
8739
 
    };
8740
 
    this.getNextFoldLine = function(docRow, startFoldLine) {
8741
 
        var foldData = this.$foldData;
8742
 
        var i = 0;
8743
 
        if (startFoldLine)
8744
 
            i = foldData.indexOf(startFoldLine);
8745
 
        if (i == -1)
8746
 
            i = 0;
8747
 
        for (i; i < foldData.length; i++) {
8748
 
            var foldLine = foldData[i];
8749
 
            if (foldLine.end.row >= docRow) {
8750
 
                return foldLine;
8751
 
            }
8752
 
        }
8753
 
        return null;
8754
 
    };
8755
 
 
8756
 
    this.getFoldedRowCount = function(first, last) {
8757
 
        var foldData = this.$foldData, rowCount = last-first+1;
8758
 
        for (var i = 0; i < foldData.length; i++) {
8759
 
            var foldLine = foldData[i],
8760
 
                end = foldLine.end.row,
8761
 
                start = foldLine.start.row;
8762
 
            if (end >= last) {
8763
 
                if(start < last) {
8764
 
                    if(start >= first)
8765
 
                        rowCount -= last-start;
8766
 
                    else
8767
 
                        rowCount = 0;//in one fold
8768
 
                }
8769
 
                break;
8770
 
            } else if(end >= first){
8771
 
                if (start >= first) //fold inside range
8772
 
                    rowCount -=  end-start;
8773
 
                else
8774
 
                    rowCount -=  end-first+1;
8775
 
            }
8776
 
        }
8777
 
        return rowCount;
8778
 
    };
8779
 
 
8780
 
    this.$addFoldLine = function(foldLine) {
8781
 
        this.$foldData.push(foldLine);
8782
 
        this.$foldData.sort(function(a, b) {
8783
 
            return a.start.row - b.start.row;
8784
 
        });
8785
 
        return foldLine;
8786
 
    };
8787
 
    this.addFold = function(placeholder, range) {
8788
 
        var foldData = this.$foldData;
8789
 
        var added = false;
8790
 
        var fold;
8791
 
        
8792
 
        if (placeholder instanceof Fold)
8793
 
            fold = placeholder;
8794
 
        else {
8795
 
            fold = new Fold(range, placeholder);
8796
 
            fold.collapseChildren = range.collapseChildren;
8797
 
        }
8798
 
        this.$clipRangeToDocument(fold.range);
8799
 
 
8800
 
        var startRow = fold.start.row;
8801
 
        var startColumn = fold.start.column;
8802
 
        var endRow = fold.end.row;
8803
 
        var endColumn = fold.end.column;
8804
 
        if (startRow == endRow && endColumn - startColumn < 2)
8805
 
            throw "The range has to be at least 2 characters width";
8806
 
 
8807
 
        var startFold = this.getFoldAt(startRow, startColumn, 1);
8808
 
        var endFold = this.getFoldAt(endRow, endColumn, -1);
8809
 
        if (startFold && endFold == startFold)
8810
 
            return startFold.addSubFold(fold);
8811
 
 
8812
 
        if (
8813
 
            (startFold && !startFold.range.isStart(startRow, startColumn))
8814
 
            || (endFold && !endFold.range.isEnd(endRow, endColumn))
8815
 
        ) {
8816
 
            throw "A fold can't intersect already existing fold" + fold.range + startFold.range;
8817
 
        }
8818
 
        var folds = this.getFoldsInRange(fold.range);
8819
 
        if (folds.length > 0) {
8820
 
            this.removeFolds(folds);
8821
 
            folds.forEach(function(subFold) {
8822
 
                fold.addSubFold(subFold);
8823
 
            });
8824
 
        }
8825
 
 
8826
 
        for (var i = 0; i < foldData.length; i++) {
8827
 
            var foldLine = foldData[i];
8828
 
            if (endRow == foldLine.start.row) {
8829
 
                foldLine.addFold(fold);
8830
 
                added = true;
8831
 
                break;
8832
 
            } else if (startRow == foldLine.end.row) {
8833
 
                foldLine.addFold(fold);
8834
 
                added = true;
8835
 
                if (!fold.sameRow) {
8836
 
                    var foldLineNext = foldData[i + 1];
8837
 
                    if (foldLineNext && foldLineNext.start.row == endRow) {
8838
 
                        foldLine.merge(foldLineNext);
8839
 
                        break;
8840
 
                    }
8841
 
                }
8842
 
                break;
8843
 
            } else if (endRow <= foldLine.start.row) {
8844
 
                break;
8845
 
            }
8846
 
        }
8847
 
 
8848
 
        if (!added)
8849
 
            foldLine = this.$addFoldLine(new FoldLine(this.$foldData, fold));
8850
 
 
8851
 
        if (this.$useWrapMode)
8852
 
            this.$updateWrapData(foldLine.start.row, foldLine.start.row);
8853
 
        else
8854
 
            this.$updateRowLengthCache(foldLine.start.row, foldLine.start.row);
8855
 
        this.$modified = true;
8856
 
        this._emit("changeFold", { data: fold });
8857
 
 
8858
 
        return fold;
8859
 
    };
8860
 
 
8861
 
    this.addFolds = function(folds) {
8862
 
        folds.forEach(function(fold) {
8863
 
            this.addFold(fold);
8864
 
        }, this);
8865
 
    };
8866
 
 
8867
 
    this.removeFold = function(fold) {
8868
 
        var foldLine = fold.foldLine;
8869
 
        var startRow = foldLine.start.row;
8870
 
        var endRow = foldLine.end.row;
8871
 
 
8872
 
        var foldLines = this.$foldData;
8873
 
        var folds = foldLine.folds;
8874
 
        if (folds.length == 1) {
8875
 
            foldLines.splice(foldLines.indexOf(foldLine), 1);
8876
 
        } else
8877
 
        if (foldLine.range.isEnd(fold.end.row, fold.end.column)) {
8878
 
            folds.pop();
8879
 
            foldLine.end.row = folds[folds.length - 1].end.row;
8880
 
            foldLine.end.column = folds[folds.length - 1].end.column;
8881
 
        } else
8882
 
        if (foldLine.range.isStart(fold.start.row, fold.start.column)) {
8883
 
            folds.shift();
8884
 
            foldLine.start.row = folds[0].start.row;
8885
 
            foldLine.start.column = folds[0].start.column;
8886
 
        } else
8887
 
        if (fold.sameRow) {
8888
 
            folds.splice(folds.indexOf(fold), 1);
8889
 
        } else
8890
 
        {
8891
 
            var newFoldLine = foldLine.split(fold.start.row, fold.start.column);
8892
 
            folds = newFoldLine.folds;
8893
 
            folds.shift();
8894
 
            newFoldLine.start.row = folds[0].start.row;
8895
 
            newFoldLine.start.column = folds[0].start.column;
8896
 
        }
8897
 
 
8898
 
        if (this.$useWrapMode)
8899
 
            this.$updateWrapData(startRow, endRow);
8900
 
        else
8901
 
            this.$updateRowLengthCache(startRow, endRow);
8902
 
        this.$modified = true;
8903
 
        this._emit("changeFold", { data: fold });
8904
 
    };
8905
 
 
8906
 
    this.removeFolds = function(folds) {
8907
 
        var cloneFolds = [];
8908
 
        for (var i = 0; i < folds.length; i++) {
8909
 
            cloneFolds.push(folds[i]);
8910
 
        }
8911
 
 
8912
 
        cloneFolds.forEach(function(fold) {
8913
 
            this.removeFold(fold);
8914
 
        }, this);
8915
 
        this.$modified = true;
8916
 
    };
8917
 
 
8918
 
    this.expandFold = function(fold) {
8919
 
        this.removeFold(fold);        
8920
 
        fold.subFolds.forEach(function(subFold) {
8921
 
            fold.restoreRange(subFold);
8922
 
            this.addFold(subFold);
8923
 
        }, this);
8924
 
        if (fold.collapseChildren > 0) {
8925
 
            this.foldAll(fold.start.row+1, fold.end.row, fold.collapseChildren-1);
8926
 
        }
8927
 
        fold.subFolds = [];
8928
 
    };
8929
 
 
8930
 
    this.expandFolds = function(folds) {
8931
 
        folds.forEach(function(fold) {
8932
 
            this.expandFold(fold);
8933
 
        }, this);
8934
 
    };
8935
 
 
8936
 
    this.unfold = function(location, expandInner) {
8937
 
        var range, folds;
8938
 
        if (location == null) {
8939
 
            range = new Range(0, 0, this.getLength(), 0);
8940
 
            expandInner = true;
8941
 
        } else if (typeof location == "number")
8942
 
            range = new Range(location, 0, location, this.getLine(location).length);
8943
 
        else if ("row" in location)
8944
 
            range = Range.fromPoints(location, location);
8945
 
        else
8946
 
            range = location;
8947
 
 
8948
 
        folds = this.getFoldsInRange(range);
8949
 
        if (expandInner) {
8950
 
            this.removeFolds(folds);
8951
 
        } else {
8952
 
            while (folds.length) {
8953
 
                this.expandFolds(folds);
8954
 
                folds = this.getFoldsInRange(range);
8955
 
            }
8956
 
        }
8957
 
    };
8958
 
    this.isRowFolded = function(docRow, startFoldRow) {
8959
 
        return !!this.getFoldLine(docRow, startFoldRow);
8960
 
    };
8961
 
 
8962
 
    this.getRowFoldEnd = function(docRow, startFoldRow) {
8963
 
        var foldLine = this.getFoldLine(docRow, startFoldRow);
8964
 
        return foldLine ? foldLine.end.row : docRow;
8965
 
    };
8966
 
 
8967
 
    this.getRowFoldStart = function(docRow, startFoldRow) {
8968
 
        var foldLine = this.getFoldLine(docRow, startFoldRow);
8969
 
        return foldLine ? foldLine.start.row : docRow;
8970
 
    };
8971
 
 
8972
 
    this.getFoldDisplayLine = function(foldLine, endRow, endColumn, startRow, startColumn) {
8973
 
        if (startRow == null) {
8974
 
            startRow = foldLine.start.row;
8975
 
            startColumn = 0;
8976
 
        }
8977
 
 
8978
 
        if (endRow == null) {
8979
 
            endRow = foldLine.end.row;
8980
 
            endColumn = this.getLine(endRow).length;
8981
 
        }
8982
 
        var doc = this.doc;
8983
 
        var textLine = "";
8984
 
 
8985
 
        foldLine.walk(function(placeholder, row, column, lastColumn) {
8986
 
            if (row < startRow)
8987
 
                return;
8988
 
            if (row == startRow) {
8989
 
                if (column < startColumn)
8990
 
                    return;
8991
 
                lastColumn = Math.max(startColumn, lastColumn);
8992
 
            }
8993
 
 
8994
 
            if (placeholder != null) {
8995
 
                textLine += placeholder;
8996
 
            } else {
8997
 
                textLine += doc.getLine(row).substring(lastColumn, column);
8998
 
            }
8999
 
        }, endRow, endColumn);
9000
 
        return textLine;
9001
 
    };
9002
 
 
9003
 
    this.getDisplayLine = function(row, endColumn, startRow, startColumn) {
9004
 
        var foldLine = this.getFoldLine(row);
9005
 
 
9006
 
        if (!foldLine) {
9007
 
            var line;
9008
 
            line = this.doc.getLine(row);
9009
 
            return line.substring(startColumn || 0, endColumn || line.length);
9010
 
        } else {
9011
 
            return this.getFoldDisplayLine(
9012
 
                foldLine, row, endColumn, startRow, startColumn);
9013
 
        }
9014
 
    };
9015
 
 
9016
 
    this.$cloneFoldData = function() {
9017
 
        var fd = [];
9018
 
        fd = this.$foldData.map(function(foldLine) {
9019
 
            var folds = foldLine.folds.map(function(fold) {
9020
 
                return fold.clone();
9021
 
            });
9022
 
            return new FoldLine(fd, folds);
9023
 
        });
9024
 
 
9025
 
        return fd;
9026
 
    };
9027
 
 
9028
 
    this.toggleFold = function(tryToUnfold) {
9029
 
        var selection = this.selection;
9030
 
        var range = selection.getRange();
9031
 
        var fold;
9032
 
        var bracketPos;
9033
 
 
9034
 
        if (range.isEmpty()) {
9035
 
            var cursor = range.start;
9036
 
            fold = this.getFoldAt(cursor.row, cursor.column);
9037
 
 
9038
 
            if (fold) {
9039
 
                this.expandFold(fold);
9040
 
                return;
9041
 
            } else if (bracketPos = this.findMatchingBracket(cursor)) {
9042
 
                if (range.comparePoint(bracketPos) == 1) {
9043
 
                    range.end = bracketPos;
9044
 
                } else {
9045
 
                    range.start = bracketPos;
9046
 
                    range.start.column++;
9047
 
                    range.end.column--;
9048
 
                }
9049
 
            } else if (bracketPos = this.findMatchingBracket({row: cursor.row, column: cursor.column + 1})) {
9050
 
                if (range.comparePoint(bracketPos) == 1)
9051
 
                    range.end = bracketPos;
9052
 
                else
9053
 
                    range.start = bracketPos;
9054
 
 
9055
 
                range.start.column++;
9056
 
            } else {
9057
 
                range = this.getCommentFoldRange(cursor.row, cursor.column) || range;
9058
 
            }
9059
 
        } else {
9060
 
            var folds = this.getFoldsInRange(range);
9061
 
            if (tryToUnfold && folds.length) {
9062
 
                this.expandFolds(folds);
9063
 
                return;
9064
 
            } else if (folds.length == 1 ) {
9065
 
                fold = folds[0];
9066
 
            }
9067
 
        }
9068
 
 
9069
 
        if (!fold)
9070
 
            fold = this.getFoldAt(range.start.row, range.start.column);
9071
 
 
9072
 
        if (fold && fold.range.toString() == range.toString()) {
9073
 
            this.expandFold(fold);
9074
 
            return;
9075
 
        }
9076
 
 
9077
 
        var placeholder = "...";
9078
 
        if (!range.isMultiLine()) {
9079
 
            placeholder = this.getTextRange(range);
9080
 
            if(placeholder.length < 4)
9081
 
                return;
9082
 
            placeholder = placeholder.trim().substring(0, 2) + "..";
9083
 
        }
9084
 
 
9085
 
        this.addFold(placeholder, range);
9086
 
    };
9087
 
 
9088
 
    this.getCommentFoldRange = function(row, column, dir) {
9089
 
        var iterator = new TokenIterator(this, row, column);
9090
 
        var token = iterator.getCurrentToken();
9091
 
        if (token && /^comment|string/.test(token.type)) {
9092
 
            var range = new Range();
9093
 
            var re = new RegExp(token.type.replace(/\..*/, "\\."));
9094
 
            if (dir != 1) {
9095
 
                do {
9096
 
                    token = iterator.stepBackward();
9097
 
                } while(token && re.test(token.type));
9098
 
                iterator.stepForward();
9099
 
            }
9100
 
            
9101
 
            range.start.row = iterator.getCurrentTokenRow();
9102
 
            range.start.column = iterator.getCurrentTokenColumn() + 2;
9103
 
 
9104
 
            iterator = new TokenIterator(this, row, column);
9105
 
            
9106
 
            if (dir != -1) {
9107
 
                do {
9108
 
                    token = iterator.stepForward();
9109
 
                } while(token && re.test(token.type));
9110
 
                token = iterator.stepBackward();
9111
 
            } else
9112
 
                token = iterator.getCurrentToken();
9113
 
 
9114
 
            range.end.row = iterator.getCurrentTokenRow();
9115
 
            range.end.column = iterator.getCurrentTokenColumn() + token.value.length - 2;
9116
 
            return range;
9117
 
        }
9118
 
    };
9119
 
 
9120
 
    this.foldAll = function(startRow, endRow, depth) {
9121
 
        if (depth == undefined)
9122
 
            depth = 100000; // JSON.stringify doesn't hanle Infinity
9123
 
        var foldWidgets = this.foldWidgets;
9124
 
        endRow = endRow || this.getLength();
9125
 
        for (var row = startRow || 0; row < endRow; row++) {
9126
 
            if (foldWidgets[row] == null)
9127
 
                foldWidgets[row] = this.getFoldWidget(row);
9128
 
            if (foldWidgets[row] != "start")
9129
 
                continue;
9130
 
 
9131
 
            var range = this.getFoldWidgetRange(row);
9132
 
            if (range && range.end.row <= endRow) try {
9133
 
                var fold = this.addFold("...", range);
9134
 
                fold.collapseChildren = depth;
9135
 
            } catch(e) {}
9136
 
            row = range.end.row;
9137
 
        }
9138
 
    };
9139
 
    this.$foldStyles = {
9140
 
        "manual": 1,
9141
 
        "markbegin": 1,
9142
 
        "markbeginend": 1
9143
 
    };
9144
 
    this.$foldStyle = "markbegin";
9145
 
    this.setFoldStyle = function(style) {
9146
 
        if (!this.$foldStyles[style])
9147
 
            throw new Error("invalid fold style: " + style + "[" + Object.keys(this.$foldStyles).join(", ") + "]");
9148
 
        
9149
 
        if (this.$foldStyle == style)
9150
 
            return;
9151
 
 
9152
 
        this.$foldStyle = style;
9153
 
        
9154
 
        if (style == "manual")
9155
 
            this.unfold();
9156
 
        var mode = this.$foldMode;
9157
 
        this.$setFolding(null);
9158
 
        this.$setFolding(mode);
9159
 
    };
9160
 
 
9161
 
    this.$setFolding = function(foldMode) {
9162
 
        if (this.$foldMode == foldMode)
9163
 
            return;
9164
 
            
9165
 
        this.$foldMode = foldMode;
9166
 
        
9167
 
        this.removeListener('change', this.$updateFoldWidgets);
9168
 
        this._emit("changeAnnotation");
9169
 
        
9170
 
        if (!foldMode || this.$foldStyle == "manual") {
9171
 
            this.foldWidgets = null;
9172
 
            return;
9173
 
        }
9174
 
        
9175
 
        this.foldWidgets = [];
9176
 
        this.getFoldWidget = foldMode.getFoldWidget.bind(foldMode, this, this.$foldStyle);
9177
 
        this.getFoldWidgetRange = foldMode.getFoldWidgetRange.bind(foldMode, this, this.$foldStyle);
9178
 
        
9179
 
        this.$updateFoldWidgets = this.updateFoldWidgets.bind(this);
9180
 
        this.on('change', this.$updateFoldWidgets);
9181
 
        
9182
 
    };
9183
 
 
9184
 
    this.getParentFoldRangeData = function (row, ignoreCurrent) {
9185
 
        var fw = this.foldWidgets;
9186
 
        if (!fw || (ignoreCurrent && fw[row]))
9187
 
            return {};
9188
 
 
9189
 
        var i = row - 1, firstRange;
9190
 
        while (i >= 0) {
9191
 
            var c = fw[i];
9192
 
            if (c == null)
9193
 
                c = fw[i] = this.getFoldWidget(i);
9194
 
 
9195
 
            if (c == "start") {
9196
 
                var range = this.getFoldWidgetRange(i);
9197
 
                if (!firstRange)
9198
 
                    firstRange = range;
9199
 
                if (range && range.end.row >= row)
9200
 
                    break;
9201
 
            }
9202
 
            i--;
9203
 
        }
9204
 
 
9205
 
        return {
9206
 
            range: i !== -1 && range,
9207
 
            firstRange: firstRange
9208
 
        };
9209
 
    }
9210
 
 
9211
 
    this.onFoldWidgetClick = function(row, e) {
9212
 
        var type = this.getFoldWidget(row);
9213
 
        var line = this.getLine(row);
9214
 
        e = e.domEvent;
9215
 
        var children = e.shiftKey;
9216
 
        var all = e.ctrlKey || e.metaKey;
9217
 
        var siblings = e.altKey;
9218
 
 
9219
 
        var dir = type === "end" ? -1 : 1;
9220
 
        var fold = this.getFoldAt(row, dir === -1 ? 0 : line.length, dir);
9221
 
 
9222
 
        if (fold) {
9223
 
            if (children || all)
9224
 
                this.removeFold(fold);
9225
 
            else
9226
 
                this.expandFold(fold);
9227
 
            return;
9228
 
        }
9229
 
 
9230
 
        var range = this.getFoldWidgetRange(row);
9231
 
        if (range && !range.isMultiLine()) {
9232
 
            fold = this.getFoldAt(range.start.row, range.start.column, 1);
9233
 
            if (fold && range.isEqual(fold.range)) {
9234
 
                this.removeFold(fold);
9235
 
                return;
9236
 
            }
9237
 
        }
9238
 
        
9239
 
        if (siblings) {
9240
 
            var data = this.getParentFoldRangeData(row);
9241
 
            if (data.range) {
9242
 
                var startRow = data.range.start.row + 1;
9243
 
                var endRow = data.range.end.row;
9244
 
            }
9245
 
            this.foldAll(startRow, endRow, all ? 10000 : 0);
9246
 
        } else if (children) {
9247
 
            var endRow = range ? range.end.row : this.getLength();
9248
 
            this.foldAll(row + 1, range.end.row, all ? 10000 : 0);
9249
 
        } else if (range) {
9250
 
            if (all) 
9251
 
                range.collapseChildren = 10000;
9252
 
            this.addFold("...", range);
9253
 
        }
9254
 
        
9255
 
        if (!range)
9256
 
            (e.target || e.srcElement).className += " ace_invalid"
9257
 
    };
9258
 
 
9259
 
    this.updateFoldWidgets = function(e) {
9260
 
        var delta = e.data;
9261
 
        var range = delta.range;
9262
 
        var firstRow = range.start.row;
9263
 
        var len = range.end.row - firstRow;
9264
 
 
9265
 
        if (len === 0) {
9266
 
            this.foldWidgets[firstRow] = null;
9267
 
        } else if (delta.action == "removeText" || delta.action == "removeLines") {
9268
 
            this.foldWidgets.splice(firstRow, len + 1, null);
9269
 
        } else {
9270
 
            var args = Array(len + 1);
9271
 
            args.unshift(firstRow, 1);
9272
 
            this.foldWidgets.splice.apply(this.foldWidgets, args);
9273
 
        }
9274
 
    };
9275
 
 
9276
 
}
9277
 
 
9278
 
exports.Folding = Folding;
9279
 
 
9280
 
});
9281
 
 
9282
 
define('ace/edit_session/fold_line', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
9283
 
 
9284
 
 
9285
 
var Range = require("../range").Range;
9286
 
function FoldLine(foldData, folds) {
9287
 
    this.foldData = foldData;
9288
 
    if (Array.isArray(folds)) {
9289
 
        this.folds = folds;
9290
 
    } else {
9291
 
        folds = this.folds = [ folds ];
9292
 
    }
9293
 
 
9294
 
    var last = folds[folds.length - 1]
9295
 
    this.range = new Range(folds[0].start.row, folds[0].start.column,
9296
 
                           last.end.row, last.end.column);
9297
 
    this.start = this.range.start;
9298
 
    this.end   = this.range.end;
9299
 
 
9300
 
    this.folds.forEach(function(fold) {
9301
 
        fold.setFoldLine(this);
9302
 
    }, this);
9303
 
}
9304
 
 
9305
 
(function() {
9306
 
    this.shiftRow = function(shift) {
9307
 
        this.start.row += shift;
9308
 
        this.end.row += shift;
9309
 
        this.folds.forEach(function(fold) {
9310
 
            fold.start.row += shift;
9311
 
            fold.end.row += shift;
9312
 
        });
9313
 
    }
9314
 
 
9315
 
    this.addFold = function(fold) {
9316
 
        if (fold.sameRow) {
9317
 
            if (fold.start.row < this.startRow || fold.endRow > this.endRow) {
9318
 
                throw "Can't add a fold to this FoldLine as it has no connection";
9319
 
            }
9320
 
            this.folds.push(fold);
9321
 
            this.folds.sort(function(a, b) {
9322
 
                return -a.range.compareEnd(b.start.row, b.start.column);
9323
 
            });
9324
 
            if (this.range.compareEnd(fold.start.row, fold.start.column) > 0) {
9325
 
                this.end.row = fold.end.row;
9326
 
                this.end.column =  fold.end.column;
9327
 
            } else if (this.range.compareStart(fold.end.row, fold.end.column) < 0) {
9328
 
                this.start.row = fold.start.row;
9329
 
                this.start.column = fold.start.column;
9330
 
            }
9331
 
        } else if (fold.start.row == this.end.row) {
9332
 
            this.folds.push(fold);
9333
 
            this.end.row = fold.end.row;
9334
 
            this.end.column = fold.end.column;
9335
 
        } else if (fold.end.row == this.start.row) {
9336
 
            this.folds.unshift(fold);
9337
 
            this.start.row = fold.start.row;
9338
 
            this.start.column = fold.start.column;
9339
 
        } else {
9340
 
            throw "Trying to add fold to FoldRow that doesn't have a matching row";
9341
 
        }
9342
 
        fold.foldLine = this;
9343
 
    }
9344
 
 
9345
 
    this.containsRow = function(row) {
9346
 
        return row >= this.start.row && row <= this.end.row;
9347
 
    }
9348
 
 
9349
 
    this.walk = function(callback, endRow, endColumn) {
9350
 
        var lastEnd = 0,
9351
 
            folds = this.folds,
9352
 
            fold,
9353
 
            comp, stop, isNewRow = true;
9354
 
 
9355
 
        if (endRow == null) {
9356
 
            endRow = this.end.row;
9357
 
            endColumn = this.end.column;
9358
 
        }
9359
 
 
9360
 
        for (var i = 0; i < folds.length; i++) {
9361
 
            fold = folds[i];
9362
 
 
9363
 
            comp = fold.range.compareStart(endRow, endColumn);
9364
 
            if (comp == -1) {
9365
 
                callback(null, endRow, endColumn, lastEnd, isNewRow);
9366
 
                return;
9367
 
            }
9368
 
 
9369
 
            stop = callback(null, fold.start.row, fold.start.column, lastEnd, isNewRow);
9370
 
            stop = !stop && callback(fold.placeholder, fold.start.row, fold.start.column, lastEnd);
9371
 
            if (stop || comp == 0) {
9372
 
                return;
9373
 
            }
9374
 
            isNewRow = !fold.sameRow;
9375
 
            lastEnd = fold.end.column;
9376
 
        }
9377
 
        callback(null, endRow, endColumn, lastEnd, isNewRow);
9378
 
    }
9379
 
 
9380
 
    this.getNextFoldTo = function(row, column) {
9381
 
        var fold, cmp;
9382
 
        for (var i = 0; i < this.folds.length; i++) {
9383
 
            fold = this.folds[i];
9384
 
            cmp = fold.range.compareEnd(row, column);
9385
 
            if (cmp == -1) {
9386
 
                return {
9387
 
                    fold: fold,
9388
 
                    kind: "after"
9389
 
                };
9390
 
            } else if (cmp == 0) {
9391
 
                return {
9392
 
                    fold: fold,
9393
 
                    kind: "inside"
9394
 
                }
9395
 
            }
9396
 
        }
9397
 
        return null;
9398
 
    }
9399
 
 
9400
 
    this.addRemoveChars = function(row, column, len) {
9401
 
        var ret = this.getNextFoldTo(row, column),
9402
 
            fold, folds;
9403
 
        if (ret) {
9404
 
            fold = ret.fold;
9405
 
            if (ret.kind == "inside"
9406
 
                && fold.start.column != column
9407
 
                && fold.start.row != row)
9408
 
            {
9409
 
                window.console && window.console.log(row, column, fold);
9410
 
            } else if (fold.start.row == row) {
9411
 
                folds = this.folds;
9412
 
                var i = folds.indexOf(fold);
9413
 
                if (i == 0) {
9414
 
                    this.start.column += len;
9415
 
                }
9416
 
                for (i; i < folds.length; i++) {
9417
 
                    fold = folds[i];
9418
 
                    fold.start.column += len;
9419
 
                    if (!fold.sameRow) {
9420
 
                        return;
9421
 
                    }
9422
 
                    fold.end.column += len;
9423
 
                }
9424
 
                this.end.column += len;
9425
 
            }
9426
 
        }
9427
 
    }
9428
 
 
9429
 
    this.split = function(row, column) {
9430
 
        var fold = this.getNextFoldTo(row, column).fold;
9431
 
        var folds = this.folds;
9432
 
        var foldData = this.foldData;
9433
 
 
9434
 
        if (!fold)
9435
 
            return null;
9436
 
 
9437
 
        var i = folds.indexOf(fold);
9438
 
        var foldBefore = folds[i - 1];
9439
 
        this.end.row = foldBefore.end.row;
9440
 
        this.end.column = foldBefore.end.column;
9441
 
        folds = folds.splice(i, folds.length - i);
9442
 
 
9443
 
        var newFoldLine = new FoldLine(foldData, folds);
9444
 
        foldData.splice(foldData.indexOf(this) + 1, 0, newFoldLine);
9445
 
        return newFoldLine;
9446
 
    }
9447
 
 
9448
 
    this.merge = function(foldLineNext) {
9449
 
        var folds = foldLineNext.folds;
9450
 
        for (var i = 0; i < folds.length; i++) {
9451
 
            this.addFold(folds[i]);
9452
 
        }
9453
 
        var foldData = this.foldData;
9454
 
        foldData.splice(foldData.indexOf(foldLineNext), 1);
9455
 
    }
9456
 
 
9457
 
    this.toString = function() {
9458
 
        var ret = [this.range.toString() + ": [" ];
9459
 
 
9460
 
        this.folds.forEach(function(fold) {
9461
 
            ret.push("  " + fold.toString());
9462
 
        });
9463
 
        ret.push("]")
9464
 
        return ret.join("\n");
9465
 
    }
9466
 
 
9467
 
    this.idxToPosition = function(idx) {
9468
 
        var lastFoldEndColumn = 0;
9469
 
        var fold;
9470
 
 
9471
 
        for (var i = 0; i < this.folds.length; i++) {
9472
 
            var fold = this.folds[i];
9473
 
 
9474
 
            idx -= fold.start.column - lastFoldEndColumn;
9475
 
            if (idx < 0) {
9476
 
                return {
9477
 
                    row: fold.start.row,
9478
 
                    column: fold.start.column + idx
9479
 
                };
9480
 
            }
9481
 
 
9482
 
            idx -= fold.placeholder.length;
9483
 
            if (idx < 0) {
9484
 
                return fold.start;
9485
 
            }
9486
 
 
9487
 
            lastFoldEndColumn = fold.end.column;
9488
 
        }
9489
 
 
9490
 
        return {
9491
 
            row: this.end.row,
9492
 
            column: this.end.column + idx
9493
 
        };
9494
 
    }
9495
 
}).call(FoldLine.prototype);
9496
 
 
9497
 
exports.FoldLine = FoldLine;
9498
 
});
9499
 
 
9500
 
define('ace/edit_session/fold', ['require', 'exports', 'module' , 'ace/range', 'ace/range_list', 'ace/lib/oop'], function(require, exports, module) {
9501
 
 
9502
 
 
9503
 
var Range = require("../range").Range;
9504
 
var RangeList = require("../range_list").RangeList;
9505
 
var oop = require("../lib/oop")
9506
 
var Fold = exports.Fold = function(range, placeholder) {
9507
 
    this.foldLine = null;
9508
 
    this.placeholder = placeholder;
9509
 
    this.range = range;
9510
 
    this.start = range.start;
9511
 
    this.end = range.end;
9512
 
 
9513
 
    this.sameRow = range.start.row == range.end.row;
9514
 
    this.subFolds = this.ranges = [];
9515
 
};
9516
 
 
9517
 
oop.inherits(Fold, RangeList);
9518
 
 
9519
 
(function() {
9520
 
 
9521
 
    this.toString = function() {
9522
 
        return '"' + this.placeholder + '" ' + this.range.toString();
9523
 
    };
9524
 
 
9525
 
    this.setFoldLine = function(foldLine) {
9526
 
        this.foldLine = foldLine;
9527
 
        this.subFolds.forEach(function(fold) {
9528
 
            fold.setFoldLine(foldLine);
9529
 
        });
9530
 
    };
9531
 
 
9532
 
    this.clone = function() {
9533
 
        var range = this.range.clone();
9534
 
        var fold = new Fold(range, this.placeholder);
9535
 
        this.subFolds.forEach(function(subFold) {
9536
 
            fold.subFolds.push(subFold.clone());
9537
 
        });
9538
 
        fold.collapseChildren = this.collapseChildren;
9539
 
        return fold;
9540
 
    };
9541
 
 
9542
 
    this.addSubFold = function(fold) {
9543
 
        if (this.range.isEqual(fold))
9544
 
            return;
9545
 
 
9546
 
        if (!this.range.containsRange(fold))
9547
 
            throw "A fold can't intersect already existing fold" + fold.range + this.range;
9548
 
        consumeRange(fold, this.start);
9549
 
 
9550
 
        var row = fold.start.row, column = fold.start.column;
9551
 
        for (var i = 0, cmp = -1; i < this.subFolds.length; i++) {
9552
 
            cmp = this.subFolds[i].range.compare(row, column);
9553
 
            if (cmp != 1)
9554
 
                break;
9555
 
        }
9556
 
        var afterStart = this.subFolds[i];
9557
 
 
9558
 
        if (cmp == 0)
9559
 
            return afterStart.addSubFold(fold);
9560
 
        var row = fold.range.end.row, column = fold.range.end.column;
9561
 
        for (var j = i, cmp = -1; j < this.subFolds.length; j++) {
9562
 
            cmp = this.subFolds[j].range.compare(row, column);
9563
 
            if (cmp != 1)
9564
 
                break;
9565
 
        }
9566
 
        var afterEnd = this.subFolds[j];
9567
 
 
9568
 
        if (cmp == 0)
9569
 
            throw "A fold can't intersect already existing fold" + fold.range + this.range;
9570
 
 
9571
 
        var consumedFolds = this.subFolds.splice(i, j - i, fold);
9572
 
        fold.setFoldLine(this.foldLine);
9573
 
 
9574
 
        return fold;
9575
 
    };
9576
 
    
9577
 
    this.restoreRange = function(range) {
9578
 
        return restoreRange(range, this.start);
9579
 
    };
9580
 
 
9581
 
}).call(Fold.prototype);
9582
 
 
9583
 
function consumePoint(point, anchor) {
9584
 
    point.row -= anchor.row;
9585
 
    if (point.row == 0)
9586
 
        point.column -= anchor.column;
9587
 
}
9588
 
function consumeRange(range, anchor) {
9589
 
    consumePoint(range.start, anchor);
9590
 
    consumePoint(range.end, anchor);
9591
 
}
9592
 
function restorePoint(point, anchor) {
9593
 
    if (point.row == 0)
9594
 
        point.column += anchor.column;
9595
 
    point.row += anchor.row;
9596
 
}
9597
 
function restoreRange(range, anchor) {
9598
 
    restorePoint(range.start, anchor);
9599
 
    restorePoint(range.end, anchor);
9600
 
}
9601
 
 
9602
 
});
9603
 
 
9604
 
define('ace/range_list', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
9605
 
 
9606
 
var Range = require("./range").Range;
9607
 
var comparePoints = Range.comparePoints;
9608
 
 
9609
 
var RangeList = function() {
9610
 
    this.ranges = [];
9611
 
};
9612
 
 
9613
 
(function() {
9614
 
    this.comparePoints = comparePoints;
9615
 
 
9616
 
    this.pointIndex = function(pos, excludeEdges, startIndex) {
9617
 
        var list = this.ranges;
9618
 
 
9619
 
        for (var i = startIndex || 0; i < list.length; i++) {
9620
 
            var range = list[i];
9621
 
            var cmpEnd = comparePoints(pos, range.end);
9622
 
            if (cmpEnd > 0)
9623
 
                continue;
9624
 
            var cmpStart = comparePoints(pos, range.start);
9625
 
            if (cmpEnd === 0)
9626
 
                return excludeEdges && cmpStart !== 0 ? -i-2 : i;
9627
 
            if (cmpStart > 0 || (cmpStart === 0 && !excludeEdges))
9628
 
                return i;
9629
 
 
9630
 
            return -i-1;
9631
 
        }
9632
 
        return -i - 1;
9633
 
    };
9634
 
 
9635
 
    this.add = function(range) {
9636
 
        var excludeEdges = !range.isEmpty();
9637
 
        var startIndex = this.pointIndex(range.start, excludeEdges);
9638
 
        if (startIndex < 0)
9639
 
            startIndex = -startIndex - 1;
9640
 
 
9641
 
        var endIndex = this.pointIndex(range.end, excludeEdges, startIndex);
9642
 
 
9643
 
        if (endIndex < 0)
9644
 
            endIndex = -endIndex - 1;
9645
 
        else
9646
 
            endIndex++;
9647
 
        return this.ranges.splice(startIndex, endIndex - startIndex, range);
9648
 
    };
9649
 
 
9650
 
    this.addList = function(list) {
9651
 
        var removed = [];
9652
 
        for (var i = list.length; i--; ) {
9653
 
            removed.push.call(removed, this.add(list[i]));
9654
 
        }
9655
 
        return removed;
9656
 
    };
9657
 
 
9658
 
    this.substractPoint = function(pos) {
9659
 
        var i = this.pointIndex(pos);
9660
 
 
9661
 
        if (i >= 0)
9662
 
            return this.ranges.splice(i, 1);
9663
 
    };
9664
 
    this.merge = function() {
9665
 
        var removed = [];
9666
 
        var list = this.ranges;
9667
 
        
9668
 
        list = list.sort(function(a, b) {
9669
 
            return comparePoints(a.start, b.start);
9670
 
        });
9671
 
        
9672
 
        var next = list[0], range;
9673
 
        for (var i = 1; i < list.length; i++) {
9674
 
            range = next;
9675
 
            next = list[i];
9676
 
            var cmp = comparePoints(range.end, next.start);
9677
 
            if (cmp < 0)
9678
 
                continue;
9679
 
 
9680
 
            if (cmp == 0 && !range.isEmpty() && !next.isEmpty())
9681
 
                continue;
9682
 
 
9683
 
            if (comparePoints(range.end, next.end) < 0) {
9684
 
                range.end.row = next.end.row;
9685
 
                range.end.column = next.end.column;
9686
 
            }
9687
 
 
9688
 
            list.splice(i, 1);
9689
 
            removed.push(next);
9690
 
            next = range;
9691
 
            i--;
9692
 
        }
9693
 
        
9694
 
        this.ranges = list;
9695
 
 
9696
 
        return removed;
9697
 
    };
9698
 
 
9699
 
    this.contains = function(row, column) {
9700
 
        return this.pointIndex({row: row, column: column}) >= 0;
9701
 
    };
9702
 
 
9703
 
    this.containsPoint = function(pos) {
9704
 
        return this.pointIndex(pos) >= 0;
9705
 
    };
9706
 
 
9707
 
    this.rangeAtPoint = function(pos) {
9708
 
        var i = this.pointIndex(pos);
9709
 
        if (i >= 0)
9710
 
            return this.ranges[i];
9711
 
    };
9712
 
 
9713
 
 
9714
 
    this.clipRows = function(startRow, endRow) {
9715
 
        var list = this.ranges;
9716
 
        if (list[0].start.row > endRow || list[list.length - 1].start.row < startRow)
9717
 
            return [];
9718
 
 
9719
 
        var startIndex = this.pointIndex({row: startRow, column: 0});
9720
 
        if (startIndex < 0)
9721
 
            startIndex = -startIndex - 1;
9722
 
        var endIndex = this.pointIndex({row: endRow, column: 0}, startIndex);
9723
 
        if (endIndex < 0)
9724
 
            endIndex = -endIndex - 1;
9725
 
 
9726
 
        var clipped = [];
9727
 
        for (var i = startIndex; i < endIndex; i++) {
9728
 
            clipped.push(list[i]);
9729
 
        }
9730
 
        return clipped;
9731
 
    };
9732
 
 
9733
 
    this.removeAll = function() {
9734
 
        return this.ranges.splice(0, this.ranges.length);
9735
 
    };
9736
 
 
9737
 
    this.attach = function(session) {
9738
 
        if (this.session)
9739
 
            this.detach();
9740
 
 
9741
 
        this.session = session;
9742
 
        this.onChange = this.$onChange.bind(this);
9743
 
 
9744
 
        this.session.on('change', this.onChange);
9745
 
    };
9746
 
 
9747
 
    this.detach = function() {
9748
 
        if (!this.session)
9749
 
            return;
9750
 
        this.session.removeListener('change', this.onChange);
9751
 
        this.session = null;
9752
 
    };
9753
 
 
9754
 
    this.$onChange = function(e) {
9755
 
        var changeRange = e.data.range;
9756
 
        if (e.data.action[0] == "i"){
9757
 
            var start = changeRange.start;
9758
 
            var end = changeRange.end;
9759
 
        } else {
9760
 
            var end = changeRange.start;
9761
 
            var start = changeRange.end;
9762
 
        }
9763
 
        var startRow = start.row;
9764
 
        var endRow = end.row;
9765
 
        var lineDif = endRow - startRow;
9766
 
 
9767
 
        var colDiff = -start.column + end.column;
9768
 
        var ranges = this.ranges;
9769
 
 
9770
 
        for (var i = 0, n = ranges.length; i < n; i++) {
9771
 
            var r = ranges[i];
9772
 
            if (r.end.row < startRow)
9773
 
                continue;
9774
 
            if (r.start.row > startRow)
9775
 
                break;
9776
 
 
9777
 
            if (r.start.row == startRow && r.start.column >= start.column ) {
9778
 
                
9779
 
                r.start.column += colDiff;
9780
 
                r.start.row += lineDif;
9781
 
            }
9782
 
            if (r.end.row == startRow && r.end.column >= start.column) {
9783
 
                if (r.end.column == start.column && colDiff > 0 && i < n - 1) {                
9784
 
                    if (r.end.column > r.start.column && r.end.column == ranges[i+1].start.column)
9785
 
                        r.end.column -= colDiff;
9786
 
                }
9787
 
                r.end.column += colDiff;
9788
 
                r.end.row += lineDif;
9789
 
            }
9790
 
        }
9791
 
 
9792
 
        if (lineDif != 0 && i < n) {
9793
 
            for (; i < n; i++) {
9794
 
                var r = ranges[i];
9795
 
                r.start.row += lineDif;
9796
 
                r.end.row += lineDif;
9797
 
            }
9798
 
        }
9799
 
    };
9800
 
 
9801
 
}).call(RangeList.prototype);
9802
 
 
9803
 
exports.RangeList = RangeList;
9804
 
});
9805
 
 
9806
 
define('ace/token_iterator', ['require', 'exports', 'module' ], function(require, exports, module) {
9807
 
var TokenIterator = function(session, initialRow, initialColumn) {
9808
 
    this.$session = session;
9809
 
    this.$row = initialRow;
9810
 
    this.$rowTokens = session.getTokens(initialRow);
9811
 
 
9812
 
    var token = session.getTokenAt(initialRow, initialColumn);
9813
 
    this.$tokenIndex = token ? token.index : -1;
9814
 
};
9815
 
 
9816
 
(function() { 
9817
 
    this.stepBackward = function() {
9818
 
        this.$tokenIndex -= 1;
9819
 
        
9820
 
        while (this.$tokenIndex < 0) {
9821
 
            this.$row -= 1;
9822
 
            if (this.$row < 0) {
9823
 
                this.$row = 0;
9824
 
                return null;
9825
 
            }
9826
 
                
9827
 
            this.$rowTokens = this.$session.getTokens(this.$row);
9828
 
            this.$tokenIndex = this.$rowTokens.length - 1;
9829
 
        }
9830
 
            
9831
 
        return this.$rowTokens[this.$tokenIndex];
9832
 
    };   
9833
 
    this.stepForward = function() {
9834
 
        this.$tokenIndex += 1;
9835
 
        var rowCount;
9836
 
        while (this.$tokenIndex >= this.$rowTokens.length) {
9837
 
            this.$row += 1;
9838
 
            if (!rowCount)
9839
 
                rowCount = this.$session.getLength();
9840
 
            if (this.$row >= rowCount) {
9841
 
                this.$row = rowCount - 1;
9842
 
                return null;
9843
 
            }
9844
 
 
9845
 
            this.$rowTokens = this.$session.getTokens(this.$row);
9846
 
            this.$tokenIndex = 0;
9847
 
        }
9848
 
            
9849
 
        return this.$rowTokens[this.$tokenIndex];
9850
 
    };      
9851
 
    this.getCurrentToken = function () {
9852
 
        return this.$rowTokens[this.$tokenIndex];
9853
 
    };      
9854
 
    this.getCurrentTokenRow = function () {
9855
 
        return this.$row;
9856
 
    };     
9857
 
    this.getCurrentTokenColumn = function() {
9858
 
        var rowTokens = this.$rowTokens;
9859
 
        var tokenIndex = this.$tokenIndex;
9860
 
        var column = rowTokens[tokenIndex].start;
9861
 
        if (column !== undefined)
9862
 
            return column;
9863
 
            
9864
 
        column = 0;
9865
 
        while (tokenIndex > 0) {
9866
 
            tokenIndex -= 1;
9867
 
            column += rowTokens[tokenIndex].value.length;
9868
 
        }
9869
 
        
9870
 
        return column;  
9871
 
    };
9872
 
            
9873
 
}).call(TokenIterator.prototype);
9874
 
 
9875
 
exports.TokenIterator = TokenIterator;
9876
 
});
9877
 
 
9878
 
define('ace/edit_session/bracket_match', ['require', 'exports', 'module' , 'ace/token_iterator', 'ace/range'], function(require, exports, module) {
9879
 
 
9880
 
 
9881
 
var TokenIterator = require("../token_iterator").TokenIterator;
9882
 
var Range = require("../range").Range;
9883
 
 
9884
 
 
9885
 
function BracketMatch() {
9886
 
 
9887
 
    this.findMatchingBracket = function(position, chr) {
9888
 
        if (position.column == 0) return null;
9889
 
 
9890
 
        var charBeforeCursor = chr || this.getLine(position.row).charAt(position.column-1);
9891
 
        if (charBeforeCursor == "") return null;
9892
 
 
9893
 
        var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/);
9894
 
        if (!match)
9895
 
            return null;
9896
 
 
9897
 
        if (match[1])
9898
 
            return this.$findClosingBracket(match[1], position);
9899
 
        else
9900
 
            return this.$findOpeningBracket(match[2], position);
9901
 
    };
9902
 
    
9903
 
    this.getBracketRange = function(pos) {
9904
 
        var line = this.getLine(pos.row);
9905
 
        var before = true, range;
9906
 
 
9907
 
        var chr = line.charAt(pos.column-1);
9908
 
        var match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
9909
 
        if (!match) {
9910
 
            chr = line.charAt(pos.column);
9911
 
            pos = {row: pos.row, column: pos.column + 1};
9912
 
            match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
9913
 
            before = false;
9914
 
        }
9915
 
        if (!match)
9916
 
            return null;
9917
 
 
9918
 
        if (match[1]) {
9919
 
            var bracketPos = this.$findClosingBracket(match[1], pos);
9920
 
            if (!bracketPos)
9921
 
                return null;
9922
 
            range = Range.fromPoints(pos, bracketPos);
9923
 
            if (!before) {
9924
 
                range.end.column++;
9925
 
                range.start.column--;
9926
 
            }
9927
 
            range.cursor = range.end;
9928
 
        } else {
9929
 
            var bracketPos = this.$findOpeningBracket(match[2], pos);
9930
 
            if (!bracketPos)
9931
 
                return null;
9932
 
            range = Range.fromPoints(bracketPos, pos);
9933
 
            if (!before) {
9934
 
                range.start.column++;
9935
 
                range.end.column--;
9936
 
            }
9937
 
            range.cursor = range.start;
9938
 
        }
9939
 
        
9940
 
        return range;
9941
 
    };
9942
 
 
9943
 
    this.$brackets = {
9944
 
        ")": "(",
9945
 
        "(": ")",
9946
 
        "]": "[",
9947
 
        "[": "]",
9948
 
        "{": "}",
9949
 
        "}": "{"
9950
 
    };
9951
 
 
9952
 
    this.$findOpeningBracket = function(bracket, position, typeRe) {
9953
 
        var openBracket = this.$brackets[bracket];
9954
 
        var depth = 1;
9955
 
 
9956
 
        var iterator = new TokenIterator(this, position.row, position.column);
9957
 
        var token = iterator.getCurrentToken();
9958
 
        if (!token)
9959
 
            token = iterator.stepForward();
9960
 
        if (!token)
9961
 
            return;
9962
 
        
9963
 
         if (!typeRe){
9964
 
            typeRe = new RegExp(
9965
 
                "(\\.?" +
9966
 
                token.type.replace(".", "\\.").replace("rparen", ".paren")
9967
 
                + ")+"
9968
 
            );
9969
 
        }
9970
 
        var valueIndex = position.column - iterator.getCurrentTokenColumn() - 2;
9971
 
        var value = token.value;
9972
 
        
9973
 
        while (true) {
9974
 
        
9975
 
            while (valueIndex >= 0) {
9976
 
                var chr = value.charAt(valueIndex);
9977
 
                if (chr == openBracket) {
9978
 
                    depth -= 1;
9979
 
                    if (depth == 0) {
9980
 
                        return {row: iterator.getCurrentTokenRow(),
9981
 
                            column: valueIndex + iterator.getCurrentTokenColumn()};
9982
 
                    }
9983
 
                }
9984
 
                else if (chr == bracket) {
9985
 
                    depth += 1;
9986
 
                }
9987
 
                valueIndex -= 1;
9988
 
            }
9989
 
            do {
9990
 
                token = iterator.stepBackward();
9991
 
            } while (token && !typeRe.test(token.type));
9992
 
 
9993
 
            if (token == null)
9994
 
                break;
9995
 
                
9996
 
            value = token.value;
9997
 
            valueIndex = value.length - 1;
9998
 
        }
9999
 
        
10000
 
        return null;
10001
 
    };
10002
 
 
10003
 
    this.$findClosingBracket = function(bracket, position, typeRe) {
10004
 
        var closingBracket = this.$brackets[bracket];
10005
 
        var depth = 1;
10006
 
 
10007
 
        var iterator = new TokenIterator(this, position.row, position.column);
10008
 
        var token = iterator.getCurrentToken();
10009
 
        if (!token)
10010
 
            token = iterator.stepForward();
10011
 
        if (!token)
10012
 
            return;
10013
 
 
10014
 
        if (!typeRe){
10015
 
            typeRe = new RegExp(
10016
 
                "(\\.?" +
10017
 
                token.type.replace(".", "\\.").replace("lparen", ".paren")
10018
 
                + ")+"
10019
 
            );
10020
 
        }
10021
 
        var valueIndex = position.column - iterator.getCurrentTokenColumn();
10022
 
 
10023
 
        while (true) {
10024
 
 
10025
 
            var value = token.value;
10026
 
            var valueLength = value.length;
10027
 
            while (valueIndex < valueLength) {
10028
 
                var chr = value.charAt(valueIndex);
10029
 
                if (chr == closingBracket) {
10030
 
                    depth -= 1;
10031
 
                    if (depth == 0) {
10032
 
                        return {row: iterator.getCurrentTokenRow(),
10033
 
                            column: valueIndex + iterator.getCurrentTokenColumn()};
10034
 
                    }
10035
 
                }
10036
 
                else if (chr == bracket) {
10037
 
                    depth += 1;
10038
 
                }
10039
 
                valueIndex += 1;
10040
 
            }
10041
 
            do {
10042
 
                token = iterator.stepForward();
10043
 
            } while (token && !typeRe.test(token.type));
10044
 
 
10045
 
            if (token == null)
10046
 
                break;
10047
 
 
10048
 
            valueIndex = 0;
10049
 
        }
10050
 
        
10051
 
        return null;
10052
 
    };
10053
 
}
10054
 
exports.BracketMatch = BracketMatch;
10055
 
 
10056
 
});
10057
 
 
10058
 
define('ace/search', ['require', 'exports', 'module' , 'ace/lib/lang', 'ace/lib/oop', 'ace/range'], function(require, exports, module) {
10059
 
 
10060
 
 
10061
 
var lang = require("./lib/lang");
10062
 
var oop = require("./lib/oop");
10063
 
var Range = require("./range").Range;
10064
 
 
10065
 
var Search = function() {
10066
 
    this.$options = {};
10067
 
};
10068
 
 
10069
 
(function() {
10070
 
    this.set = function(options) {
10071
 
        oop.mixin(this.$options, options);
10072
 
        return this;
10073
 
    };
10074
 
    this.getOptions = function() {
10075
 
        return lang.copyObject(this.$options);
10076
 
    };
10077
 
    this.setOptions = function(options) {
10078
 
        this.$options = options;
10079
 
    };
10080
 
    this.find = function(session) {
10081
 
        var iterator = this.$matchIterator(session, this.$options);
10082
 
 
10083
 
        if (!iterator)
10084
 
            return false;
10085
 
 
10086
 
        var firstRange = null;
10087
 
        iterator.forEach(function(range, row, offset) {
10088
 
            if (!range.start) {
10089
 
                var column = range.offset + (offset || 0);
10090
 
                firstRange = new Range(row, column, row, column+range.length);
10091
 
            } else
10092
 
                firstRange = range;
10093
 
            return true;
10094
 
        });
10095
 
 
10096
 
        return firstRange;
10097
 
    };
10098
 
    this.findAll = function(session) {
10099
 
        var options = this.$options;
10100
 
        if (!options.needle)
10101
 
            return [];
10102
 
        this.$assembleRegExp(options);
10103
 
 
10104
 
        var range = options.range;
10105
 
        var lines = range
10106
 
            ? session.getLines(range.start.row, range.end.row)
10107
 
            : session.doc.getAllLines();
10108
 
 
10109
 
        var ranges = [];
10110
 
        var re = options.re;
10111
 
        if (options.$isMultiLine) {
10112
 
            var len = re.length;
10113
 
            var maxRow = lines.length - len;
10114
 
            for (var row = re.offset || 0; row <= maxRow; row++) {
10115
 
                for (var j = 0; j < len; j++)
10116
 
                    if (lines[row + j].search(re[j]) == -1)
10117
 
                        break;
10118
 
                
10119
 
                var startLine = lines[row];
10120
 
                var line = lines[row + len - 1];
10121
 
                var startIndex = startLine.match(re[0])[0].length;
10122
 
                var endIndex = line.match(re[len - 1])[0].length;
10123
 
 
10124
 
                ranges.push(new Range(
10125
 
                    row, startLine.length - startIndex,
10126
 
                    row + len - 1, endIndex
10127
 
                ));
10128
 
            }
10129
 
        } else {
10130
 
            for (var i = 0; i < lines.length; i++) {
10131
 
                var matches = lang.getMatchOffsets(lines[i], re);
10132
 
                for (var j = 0; j < matches.length; j++) {
10133
 
                    var match = matches[j];
10134
 
                    ranges.push(new Range(i, match.offset, i, match.offset + match.length));
10135
 
                }
10136
 
            }
10137
 
        }
10138
 
 
10139
 
        if (range) {
10140
 
            var startColumn = range.start.column;
10141
 
            var endColumn = range.start.column;
10142
 
            var i = 0, j = ranges.length - 1;
10143
 
            while (i < j && ranges[i].start.column < startColumn && ranges[i].start.row == range.start.row)
10144
 
                i++;
10145
 
 
10146
 
            while (i < j && ranges[j].end.column > endColumn && ranges[j].end.row == range.end.row)
10147
 
                j--;
10148
 
            return ranges.slice(i, j + 1);
10149
 
        }
10150
 
 
10151
 
        return ranges;
10152
 
    };
10153
 
    this.replace = function(input, replacement) {
10154
 
        var options = this.$options;
10155
 
 
10156
 
        var re = this.$assembleRegExp(options);
10157
 
        if (options.$isMultiLine)
10158
 
            return replacement;
10159
 
 
10160
 
        if (!re)
10161
 
            return;
10162
 
 
10163
 
        var match = re.exec(input);
10164
 
        if (!match || match[0].length != input.length)
10165
 
            return null;
10166
 
        
10167
 
        replacement = input.replace(re, replacement);
10168
 
        if (options.preserveCase) {
10169
 
            replacement = replacement.split("");
10170
 
            for (var i = Math.min(input.length, input.length); i--; ) {
10171
 
                var ch = input[i];
10172
 
                if (ch && ch.toLowerCase() != ch)
10173
 
                    replacement[i] = replacement[i].toUpperCase();
10174
 
                else
10175
 
                    replacement[i] = replacement[i].toLowerCase();
10176
 
            }
10177
 
            replacement = replacement.join("");
10178
 
        }
10179
 
        
10180
 
        return replacement;
10181
 
    };
10182
 
 
10183
 
    this.$matchIterator = function(session, options) {
10184
 
        var re = this.$assembleRegExp(options);
10185
 
        if (!re)
10186
 
            return false;
10187
 
 
10188
 
        var self = this, callback, backwards = options.backwards;
10189
 
 
10190
 
        if (options.$isMultiLine) {
10191
 
            var len = re.length;
10192
 
            var matchIterator = function(line, row, offset) {
10193
 
                var startIndex = line.search(re[0]);
10194
 
                if (startIndex == -1)
10195
 
                    return;
10196
 
                for (var i = 1; i < len; i++) {
10197
 
                    line = session.getLine(row + i);
10198
 
                    if (line.search(re[i]) == -1)
10199
 
                        return;
10200
 
                }
10201
 
 
10202
 
                var endIndex = line.match(re[len - 1])[0].length;
10203
 
 
10204
 
                var range = new Range(row, startIndex, row + len - 1, endIndex);
10205
 
                if (re.offset == 1) {
10206
 
                    range.start.row--;
10207
 
                    range.start.column = Number.MAX_VALUE;
10208
 
                } else if (offset)
10209
 
                    range.start.column += offset;
10210
 
 
10211
 
                if (callback(range))
10212
 
                    return true;
10213
 
            };
10214
 
        } else if (backwards) {
10215
 
            var matchIterator = function(line, row, startIndex) {
10216
 
                var matches = lang.getMatchOffsets(line, re);
10217
 
                for (var i = matches.length-1; i >= 0; i--)
10218
 
                    if (callback(matches[i], row, startIndex))
10219
 
                        return true;
10220
 
            };
10221
 
        } else {
10222
 
            var matchIterator = function(line, row, startIndex) {
10223
 
                var matches = lang.getMatchOffsets(line, re);
10224
 
                for (var i = 0; i < matches.length; i++)
10225
 
                    if (callback(matches[i], row, startIndex))
10226
 
                        return true;
10227
 
            };
10228
 
        }
10229
 
 
10230
 
        return {
10231
 
            forEach: function(_callback) {
10232
 
                callback = _callback;
10233
 
                self.$lineIterator(session, options).forEach(matchIterator);
10234
 
            }
10235
 
        };
10236
 
    };
10237
 
 
10238
 
    this.$assembleRegExp = function(options) {
10239
 
        if (options.needle instanceof RegExp)
10240
 
            return options.re = options.needle;
10241
 
 
10242
 
        var needle = options.needle;
10243
 
 
10244
 
        if (!options.needle)
10245
 
            return options.re = false;
10246
 
 
10247
 
        if (!options.regExp)
10248
 
            needle = lang.escapeRegExp(needle);
10249
 
 
10250
 
        if (options.wholeWord)
10251
 
            needle = "\\b" + needle + "\\b";
10252
 
 
10253
 
        var modifier = options.caseSensitive ? "g" : "gi";
10254
 
 
10255
 
        options.$isMultiLine = /[\n\r]/.test(needle);
10256
 
        if (options.$isMultiLine)
10257
 
            return options.re = this.$assembleMultilineRegExp(needle, modifier);
10258
 
 
10259
 
        try {
10260
 
            var re = new RegExp(needle, modifier);
10261
 
        } catch(e) {
10262
 
            re = false;
10263
 
        }
10264
 
        return options.re = re;
10265
 
    };
10266
 
 
10267
 
    this.$assembleMultilineRegExp = function(needle, modifier) {
10268
 
        var parts = needle.replace(/\r\n|\r|\n/g, "$\n^").split("\n");
10269
 
        var re = [];
10270
 
        for (var i = 0; i < parts.length; i++) try {
10271
 
            re.push(new RegExp(parts[i], modifier));
10272
 
        } catch(e) {
10273
 
            return false;
10274
 
        }
10275
 
        if (parts[0] == "") {
10276
 
            re.shift();
10277
 
            re.offset = 1;
10278
 
        } else {
10279
 
            re.offset = 0;
10280
 
        }
10281
 
        return re;
10282
 
    };
10283
 
 
10284
 
    this.$lineIterator = function(session, options) {
10285
 
        var backwards = options.backwards == true;
10286
 
        var skipCurrent = options.skipCurrent != false;
10287
 
 
10288
 
        var range = options.range;
10289
 
        var start = options.start;
10290
 
        if (!start)
10291
 
            start = range ? range[backwards ? "end" : "start"] : session.selection.getRange();
10292
 
         
10293
 
        if (start.start)
10294
 
            start = start[skipCurrent != backwards ? "end" : "start"];
10295
 
 
10296
 
        var firstRow = range ? range.start.row : 0;
10297
 
        var lastRow = range ? range.end.row : session.getLength() - 1;
10298
 
 
10299
 
        var forEach = backwards ? function(callback) {
10300
 
                var row = start.row;
10301
 
 
10302
 
                var line = session.getLine(row).substring(0, start.column);
10303
 
                if (callback(line, row))
10304
 
                    return;
10305
 
 
10306
 
                for (row--; row >= firstRow; row--)
10307
 
                    if (callback(session.getLine(row), row))
10308
 
                        return;
10309
 
 
10310
 
                if (options.wrap == false)
10311
 
                    return;
10312
 
 
10313
 
                for (row = lastRow, firstRow = start.row; row >= firstRow; row--)
10314
 
                    if (callback(session.getLine(row), row))
10315
 
                        return;
10316
 
            } : function(callback) {
10317
 
                var row = start.row;
10318
 
 
10319
 
                var line = session.getLine(row).substr(start.column);
10320
 
                if (callback(line, row, start.column))
10321
 
                    return;
10322
 
 
10323
 
                for (row = row+1; row <= lastRow; row++)
10324
 
                    if (callback(session.getLine(row), row))
10325
 
                        return;
10326
 
 
10327
 
                if (options.wrap == false)
10328
 
                    return;
10329
 
 
10330
 
                for (row = firstRow, lastRow = start.row; row <= lastRow; row++)
10331
 
                    if (callback(session.getLine(row), row))
10332
 
                        return;
10333
 
            };
10334
 
        
10335
 
        return {forEach: forEach};
10336
 
    };
10337
 
 
10338
 
}).call(Search.prototype);
10339
 
 
10340
 
exports.Search = Search;
10341
 
});
10342
 
define('ace/commands/command_manager', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/keyboard/hash_handler', 'ace/lib/event_emitter'], function(require, exports, module) {
10343
 
 
10344
 
 
10345
 
var oop = require("../lib/oop");
10346
 
var HashHandler = require("../keyboard/hash_handler").HashHandler;
10347
 
var EventEmitter = require("../lib/event_emitter").EventEmitter;
10348
 
 
10349
 
var CommandManager = function(platform, commands) {
10350
 
    this.platform = platform;
10351
 
    this.commands = this.byName = {};
10352
 
    this.commmandKeyBinding = {};
10353
 
 
10354
 
    this.addCommands(commands);
10355
 
 
10356
 
    this.setDefaultHandler("exec", function(e) {
10357
 
        return e.command.exec(e.editor, e.args || {});
10358
 
    });
10359
 
};
10360
 
 
10361
 
oop.inherits(CommandManager, HashHandler);
10362
 
 
10363
 
(function() {
10364
 
 
10365
 
    oop.implement(this, EventEmitter);
10366
 
 
10367
 
    this.exec = function(command, editor, args) {
10368
 
        if (typeof command === 'string')
10369
 
            command = this.commands[command];
10370
 
 
10371
 
        if (!command)
10372
 
            return false;
10373
 
 
10374
 
        if (editor && editor.$readOnly && !command.readOnly)
10375
 
            return false;
10376
 
 
10377
 
        var e = {editor: editor, command: command, args: args};
10378
 
        var retvalue = this._emit("exec", e);
10379
 
        this._signal("afterExec", e);
10380
 
 
10381
 
        return retvalue === false ? false : true;
10382
 
    };
10383
 
 
10384
 
    this.toggleRecording = function(editor) {
10385
 
        if (this.$inReplay)
10386
 
            return;
10387
 
 
10388
 
        editor && editor._emit("changeStatus");
10389
 
        if (this.recording) {
10390
 
            this.macro.pop();
10391
 
            this.removeEventListener("exec", this.$addCommandToMacro);
10392
 
 
10393
 
            if (!this.macro.length)
10394
 
                this.macro = this.oldMacro;
10395
 
 
10396
 
            return this.recording = false;
10397
 
        }
10398
 
        if (!this.$addCommandToMacro) {
10399
 
            this.$addCommandToMacro = function(e) {
10400
 
                this.macro.push([e.command, e.args]);
10401
 
            }.bind(this);
10402
 
        }
10403
 
 
10404
 
        this.oldMacro = this.macro;
10405
 
        this.macro = [];
10406
 
        this.on("exec", this.$addCommandToMacro);
10407
 
        return this.recording = true;
10408
 
    };
10409
 
 
10410
 
    this.replay = function(editor) {
10411
 
        if (this.$inReplay || !this.macro)
10412
 
            return;
10413
 
 
10414
 
        if (this.recording)
10415
 
            return this.toggleRecording(editor);
10416
 
 
10417
 
        try {
10418
 
            this.$inReplay = true;
10419
 
            this.macro.forEach(function(x) {
10420
 
                if (typeof x == "string")
10421
 
                    this.exec(x, editor);
10422
 
                else
10423
 
                    this.exec(x[0], editor, x[1]);
10424
 
            }, this);
10425
 
        } finally {
10426
 
            this.$inReplay = false;
10427
 
        }
10428
 
    };
10429
 
 
10430
 
    this.trimMacro = function(m) {
10431
 
        return m.map(function(x){
10432
 
            if (typeof x[0] != "string")
10433
 
                x[0] = x[0].name;
10434
 
            if (!x[1])
10435
 
                x = x[0];
10436
 
            return x;
10437
 
        });
10438
 
    };
10439
 
 
10440
 
}).call(CommandManager.prototype);
10441
 
 
10442
 
exports.CommandManager = CommandManager;
10443
 
 
10444
 
});
10445
 
 
10446
 
define('ace/keyboard/hash_handler', ['require', 'exports', 'module' , 'ace/lib/keys'], function(require, exports, module) {
10447
 
 
10448
 
 
10449
 
var keyUtil = require("../lib/keys");
10450
 
 
10451
 
function HashHandler(config, platform) {
10452
 
    this.platform = platform;
10453
 
    this.commands = {};
10454
 
    this.commmandKeyBinding = {};
10455
 
 
10456
 
    this.addCommands(config);
10457
 
};
10458
 
 
10459
 
(function() {
10460
 
 
10461
 
    this.addCommand = function(command) {
10462
 
        if (this.commands[command.name])
10463
 
            this.removeCommand(command);
10464
 
 
10465
 
        this.commands[command.name] = command;
10466
 
 
10467
 
        if (command.bindKey)
10468
 
            this._buildKeyHash(command);
10469
 
    };
10470
 
 
10471
 
    this.removeCommand = function(command) {
10472
 
        var name = (typeof command === 'string' ? command : command.name);
10473
 
        command = this.commands[name];
10474
 
        delete this.commands[name];
10475
 
        var ckb = this.commmandKeyBinding;
10476
 
        for (var hashId in ckb) {
10477
 
            for (var key in ckb[hashId]) {
10478
 
                if (ckb[hashId][key] == command)
10479
 
                    delete ckb[hashId][key];
10480
 
            }
10481
 
        }
10482
 
    };
10483
 
 
10484
 
    this.bindKey = function(key, command) {
10485
 
        if(!key)
10486
 
            return;
10487
 
        if (typeof command == "function") {
10488
 
            this.addCommand({exec: command, bindKey: key, name: command.name || key});
10489
 
            return;
10490
 
        }
10491
 
 
10492
 
        var ckb = this.commmandKeyBinding;
10493
 
        key.split("|").forEach(function(keyPart) {
10494
 
            var binding = this.parseKeys(keyPart, command);
10495
 
            var hashId = binding.hashId;
10496
 
            (ckb[hashId] || (ckb[hashId] = {}))[binding.key] = command;
10497
 
        }, this);
10498
 
    };
10499
 
 
10500
 
    this.addCommands = function(commands) {
10501
 
        commands && Object.keys(commands).forEach(function(name) {
10502
 
            var command = commands[name];
10503
 
            if (typeof command === "string")
10504
 
                return this.bindKey(command, name);
10505
 
 
10506
 
            if (typeof command === "function")
10507
 
                command = { exec: command };
10508
 
 
10509
 
            if (!command.name)
10510
 
                command.name = name;
10511
 
 
10512
 
            this.addCommand(command);
10513
 
        }, this);
10514
 
    };
10515
 
 
10516
 
    this.removeCommands = function(commands) {
10517
 
        Object.keys(commands).forEach(function(name) {
10518
 
            this.removeCommand(commands[name]);
10519
 
        }, this);
10520
 
    };
10521
 
 
10522
 
    this.bindKeys = function(keyList) {
10523
 
        Object.keys(keyList).forEach(function(key) {
10524
 
            this.bindKey(key, keyList[key]);
10525
 
        }, this);
10526
 
    };
10527
 
 
10528
 
    this._buildKeyHash = function(command) {
10529
 
        var binding = command.bindKey;
10530
 
        if (!binding)
10531
 
            return;
10532
 
 
10533
 
        var key = typeof binding == "string" ? binding: binding[this.platform];
10534
 
        this.bindKey(key, command);
10535
 
    };
10536
 
    this.parseKeys = function(keys) {
10537
 
        if (keys.indexOf(" ") != -1)
10538
 
            keys = keys.split(/\s+/).pop();
10539
 
 
10540
 
        var parts = keys.toLowerCase().split(/[\-\+]([\-\+])?/).filter(function(x){return x});
10541
 
        var key = parts.pop();
10542
 
 
10543
 
        var keyCode = keyUtil[key];
10544
 
        if (keyUtil.FUNCTION_KEYS[keyCode])
10545
 
            key = keyUtil.FUNCTION_KEYS[keyCode].toLowerCase();
10546
 
        else if (!parts.length)
10547
 
            return {key: key, hashId: -1};
10548
 
        else if (parts.length == 1 && parts[0] == "shift")
10549
 
            return {key: key.toUpperCase(), hashId: -1};
10550
 
 
10551
 
        var hashId = 0;
10552
 
        for (var i = parts.length; i--;) {
10553
 
            var modifier = keyUtil.KEY_MODS[parts[i]];
10554
 
            if (modifier == null) {
10555
 
                if (typeof console != "undefined")
10556
 
                console.error("invalid modifier " + parts[i] + " in " + keys);
10557
 
                return false;
10558
 
            }
10559
 
            hashId |= modifier;
10560
 
        }
10561
 
        return {key: key, hashId: hashId};
10562
 
    };
10563
 
 
10564
 
    this.findKeyCommand = function findKeyCommand(hashId, keyString) {
10565
 
        var ckbr = this.commmandKeyBinding;
10566
 
        return ckbr[hashId] && ckbr[hashId][keyString];
10567
 
    };
10568
 
 
10569
 
    this.handleKeyboard = function(data, hashId, keyString, keyCode) {
10570
 
        return {
10571
 
            command: this.findKeyCommand(hashId, keyString)
10572
 
        };
10573
 
    };
10574
 
 
10575
 
}).call(HashHandler.prototype)
10576
 
 
10577
 
exports.HashHandler = HashHandler;
10578
 
});
10579
 
 
10580
 
define('ace/commands/default_commands', ['require', 'exports', 'module' , 'ace/lib/lang', 'ace/config'], function(require, exports, module) {
10581
 
 
10582
 
 
10583
 
var lang = require("../lib/lang");
10584
 
var config = require("../config");
10585
 
 
10586
 
function bindKey(win, mac) {
10587
 
    return {
10588
 
        win: win,
10589
 
        mac: mac
10590
 
    };
10591
 
}
10592
 
 
10593
 
exports.commands = [{
10594
 
    name: "selectall",
10595
 
    bindKey: bindKey("Ctrl-A", "Command-A"),
10596
 
    exec: function(editor) { editor.selectAll(); },
10597
 
    readOnly: true
10598
 
}, {
10599
 
    name: "centerselection",
10600
 
    bindKey: bindKey(null, "Ctrl-L"),
10601
 
    exec: function(editor) { editor.centerSelection(); },
10602
 
    readOnly: true
10603
 
}, {
10604
 
    name: "gotoline",
10605
 
    bindKey: bindKey("Ctrl-L", "Command-L"),
10606
 
    exec: function(editor) {
10607
 
        var line = parseInt(prompt("Enter line number:"), 10);
10608
 
        if (!isNaN(line)) {
10609
 
            editor.gotoLine(line);
10610
 
        }
10611
 
    },
10612
 
    readOnly: true
10613
 
}, {
10614
 
    name: "fold",
10615
 
    bindKey: bindKey("Alt-L|Ctrl-F1", "Command-Alt-L|Command-F1"),
10616
 
    exec: function(editor) { editor.session.toggleFold(false); },
10617
 
    readOnly: true
10618
 
}, {
10619
 
    name: "unfold",
10620
 
    bindKey: bindKey("Alt-Shift-L|Ctrl-Shift-F1", "Command-Alt-Shift-L|Command-Shift-F1"),
10621
 
    exec: function(editor) { editor.session.toggleFold(true); },
10622
 
    readOnly: true
10623
 
}, {
10624
 
    name: "foldall",
10625
 
    bindKey: bindKey("Alt-0", "Command-Option-0"),
10626
 
    exec: function(editor) { editor.session.foldAll(); },
10627
 
    readOnly: true
10628
 
}, {
10629
 
    name: "unfoldall",
10630
 
    bindKey: bindKey("Alt-Shift-0", "Command-Option-Shift-0"),
10631
 
    exec: function(editor) { editor.session.unfold(); },
10632
 
    readOnly: true
10633
 
}, {
10634
 
    name: "findnext",
10635
 
    bindKey: bindKey("Ctrl-K", "Command-G"),
10636
 
    exec: function(editor) { editor.findNext(); },
10637
 
    readOnly: true
10638
 
}, {
10639
 
    name: "findprevious",
10640
 
    bindKey: bindKey("Ctrl-Shift-K", "Command-Shift-G"),
10641
 
    exec: function(editor) { editor.findPrevious(); },
10642
 
    readOnly: true
10643
 
}, {
10644
 
    name: "find",
10645
 
    bindKey: bindKey("Ctrl-F", "Command-F"),
10646
 
    exec: function(editor) {
10647
 
        config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor)});
10648
 
    },
10649
 
    readOnly: true
10650
 
}, {
10651
 
    name: "overwrite",
10652
 
    bindKey: "Insert",
10653
 
    exec: function(editor) { editor.toggleOverwrite(); },
10654
 
    readOnly: true
10655
 
}, {
10656
 
    name: "selecttostart",
10657
 
    bindKey: bindKey("Ctrl-Shift-Home", "Command-Shift-Up"),
10658
 
    exec: function(editor) { editor.getSelection().selectFileStart(); },
10659
 
    multiSelectAction: "forEach",
10660
 
    readOnly: true
10661
 
}, {
10662
 
    name: "gotostart",
10663
 
    bindKey: bindKey("Ctrl-Home", "Command-Home|Command-Up"),
10664
 
    exec: function(editor) { editor.navigateFileStart(); },
10665
 
    multiSelectAction: "forEach",
10666
 
    readOnly: true
10667
 
}, {
10668
 
    name: "selectup",
10669
 
    bindKey: bindKey("Shift-Up", "Shift-Up"),
10670
 
    exec: function(editor) { editor.getSelection().selectUp(); },
10671
 
    multiSelectAction: "forEach",
10672
 
    readOnly: true
10673
 
}, {
10674
 
    name: "golineup",
10675
 
    bindKey: bindKey("Up", "Up|Ctrl-P"),
10676
 
    exec: function(editor, args) { editor.navigateUp(args.times); },
10677
 
    multiSelectAction: "forEach",
10678
 
    readOnly: true
10679
 
}, {
10680
 
    name: "selecttoend",
10681
 
    bindKey: bindKey("Ctrl-Shift-End", "Command-Shift-Down"),
10682
 
    exec: function(editor) { editor.getSelection().selectFileEnd(); },
10683
 
    multiSelectAction: "forEach",
10684
 
    readOnly: true
10685
 
}, {
10686
 
    name: "gotoend",
10687
 
    bindKey: bindKey("Ctrl-End", "Command-End|Command-Down"),
10688
 
    exec: function(editor) { editor.navigateFileEnd(); },
10689
 
    multiSelectAction: "forEach",
10690
 
    readOnly: true
10691
 
}, {
10692
 
    name: "selectdown",
10693
 
    bindKey: bindKey("Shift-Down", "Shift-Down"),
10694
 
    exec: function(editor) { editor.getSelection().selectDown(); },
10695
 
    multiSelectAction: "forEach",
10696
 
    readOnly: true
10697
 
}, {
10698
 
    name: "golinedown",
10699
 
    bindKey: bindKey("Down", "Down|Ctrl-N"),
10700
 
    exec: function(editor, args) { editor.navigateDown(args.times); },
10701
 
    multiSelectAction: "forEach",
10702
 
    readOnly: true
10703
 
}, {
10704
 
    name: "selectwordleft",
10705
 
    bindKey: bindKey("Ctrl-Shift-Left", "Option-Shift-Left"),
10706
 
    exec: function(editor) { editor.getSelection().selectWordLeft(); },
10707
 
    multiSelectAction: "forEach",
10708
 
    readOnly: true
10709
 
}, {
10710
 
    name: "gotowordleft",
10711
 
    bindKey: bindKey("Ctrl-Left", "Option-Left"),
10712
 
    exec: function(editor) { editor.navigateWordLeft(); },
10713
 
    multiSelectAction: "forEach",
10714
 
    readOnly: true
10715
 
}, {
10716
 
    name: "selecttolinestart",
10717
 
    bindKey: bindKey("Alt-Shift-Left", "Command-Shift-Left"),
10718
 
    exec: function(editor) { editor.getSelection().selectLineStart(); },
10719
 
    multiSelectAction: "forEach",
10720
 
    readOnly: true
10721
 
}, {
10722
 
    name: "gotolinestart",
10723
 
    bindKey: bindKey("Alt-Left|Home", "Command-Left|Home|Ctrl-A"),
10724
 
    exec: function(editor) { editor.navigateLineStart(); },
10725
 
    multiSelectAction: "forEach",
10726
 
    readOnly: true
10727
 
}, {
10728
 
    name: "selectleft",
10729
 
    bindKey: bindKey("Shift-Left", "Shift-Left"),
10730
 
    exec: function(editor) { editor.getSelection().selectLeft(); },
10731
 
    multiSelectAction: "forEach",
10732
 
    readOnly: true
10733
 
}, {
10734
 
    name: "gotoleft",
10735
 
    bindKey: bindKey("Left", "Left|Ctrl-B"),
10736
 
    exec: function(editor, args) { editor.navigateLeft(args.times); },
10737
 
    multiSelectAction: "forEach",
10738
 
    readOnly: true
10739
 
}, {
10740
 
    name: "selectwordright",
10741
 
    bindKey: bindKey("Ctrl-Shift-Right", "Option-Shift-Right"),
10742
 
    exec: function(editor) { editor.getSelection().selectWordRight(); },
10743
 
    multiSelectAction: "forEach",
10744
 
    readOnly: true
10745
 
}, {
10746
 
    name: "gotowordright",
10747
 
    bindKey: bindKey("Ctrl-Right", "Option-Right"),
10748
 
    exec: function(editor) { editor.navigateWordRight(); },
10749
 
    multiSelectAction: "forEach",
10750
 
    readOnly: true
10751
 
}, {
10752
 
    name: "selecttolineend",
10753
 
    bindKey: bindKey("Alt-Shift-Right", "Command-Shift-Right"),
10754
 
    exec: function(editor) { editor.getSelection().selectLineEnd(); },
10755
 
    multiSelectAction: "forEach",
10756
 
    readOnly: true
10757
 
}, {
10758
 
    name: "gotolineend",
10759
 
    bindKey: bindKey("Alt-Right|End", "Command-Right|End|Ctrl-E"),
10760
 
    exec: function(editor) { editor.navigateLineEnd(); },
10761
 
    multiSelectAction: "forEach",
10762
 
    readOnly: true
10763
 
}, {
10764
 
    name: "selectright",
10765
 
    bindKey: bindKey("Shift-Right", "Shift-Right"),
10766
 
    exec: function(editor) { editor.getSelection().selectRight(); },
10767
 
    multiSelectAction: "forEach",
10768
 
    readOnly: true
10769
 
}, {
10770
 
    name: "gotoright",
10771
 
    bindKey: bindKey("Right", "Right|Ctrl-F"),
10772
 
    exec: function(editor, args) { editor.navigateRight(args.times); },
10773
 
    multiSelectAction: "forEach",
10774
 
    readOnly: true
10775
 
}, {
10776
 
    name: "selectpagedown",
10777
 
    bindKey: "Shift-PageDown",
10778
 
    exec: function(editor) { editor.selectPageDown(); },
10779
 
    readOnly: true
10780
 
}, {
10781
 
    name: "pagedown",
10782
 
    bindKey: bindKey(null, "Option-PageDown"),
10783
 
    exec: function(editor) { editor.scrollPageDown(); },
10784
 
    readOnly: true
10785
 
}, {
10786
 
    name: "gotopagedown",
10787
 
    bindKey: bindKey("PageDown", "PageDown|Ctrl-V"),
10788
 
    exec: function(editor) { editor.gotoPageDown(); },
10789
 
    readOnly: true
10790
 
}, {
10791
 
    name: "selectpageup",
10792
 
    bindKey: "Shift-PageUp",
10793
 
    exec: function(editor) { editor.selectPageUp(); },
10794
 
    readOnly: true
10795
 
}, {
10796
 
    name: "pageup",
10797
 
    bindKey: bindKey(null, "Option-PageUp"),
10798
 
    exec: function(editor) { editor.scrollPageUp(); },
10799
 
    readOnly: true
10800
 
}, {
10801
 
    name: "gotopageup",
10802
 
    bindKey: "PageUp",
10803
 
    exec: function(editor) { editor.gotoPageUp(); },
10804
 
    readOnly: true
10805
 
}, {
10806
 
    name: "scrollup",
10807
 
    bindKey: bindKey("Ctrl-Up", null),
10808
 
    exec: function(e) { e.renderer.scrollBy(0, -2 * e.renderer.layerConfig.lineHeight); },
10809
 
    readOnly: true
10810
 
}, {
10811
 
    name: "scrolldown",
10812
 
    bindKey: bindKey("Ctrl-Down", null),
10813
 
    exec: function(e) { e.renderer.scrollBy(0, 2 * e.renderer.layerConfig.lineHeight); },
10814
 
    readOnly: true
10815
 
}, {
10816
 
    name: "selectlinestart",
10817
 
    bindKey: "Shift-Home",
10818
 
    exec: function(editor) { editor.getSelection().selectLineStart(); },
10819
 
    multiSelectAction: "forEach",
10820
 
    readOnly: true
10821
 
}, {
10822
 
    name: "selectlineend",
10823
 
    bindKey: "Shift-End",
10824
 
    exec: function(editor) { editor.getSelection().selectLineEnd(); },
10825
 
    multiSelectAction: "forEach",
10826
 
    readOnly: true
10827
 
}, {
10828
 
    name: "togglerecording",
10829
 
    bindKey: bindKey("Ctrl-Alt-E", "Command-Option-E"),
10830
 
    exec: function(editor) { editor.commands.toggleRecording(editor); },
10831
 
    readOnly: true
10832
 
}, {
10833
 
    name: "replaymacro",
10834
 
    bindKey: bindKey("Ctrl-Shift-E", "Command-Shift-E"),
10835
 
    exec: function(editor) { editor.commands.replay(editor); },
10836
 
    readOnly: true
10837
 
}, {
10838
 
    name: "jumptomatching",
10839
 
    bindKey: bindKey("Ctrl-P", "Ctrl-Shift-P"),
10840
 
    exec: function(editor) { editor.jumpToMatching(); },
10841
 
    multiSelectAction: "forEach",
10842
 
    readOnly: true
10843
 
}, {
10844
 
    name: "selecttomatching",
10845
 
    bindKey: bindKey("Ctrl-Shift-P", null),
10846
 
    exec: function(editor) { editor.jumpToMatching(true); },
10847
 
    multiSelectAction: "forEach",
10848
 
    readOnly: true
10849
 
}, 
10850
 
{
10851
 
    name: "cut",
10852
 
    exec: function(editor) {
10853
 
        var range = editor.getSelectionRange();
10854
 
        editor._emit("cut", range);
10855
 
 
10856
 
        if (!editor.selection.isEmpty()) {
10857
 
            editor.session.remove(range);
10858
 
            editor.clearSelection();
10859
 
        }
10860
 
    },
10861
 
    multiSelectAction: "forEach"
10862
 
}, {
10863
 
    name: "removeline",
10864
 
    bindKey: bindKey("Ctrl-D", "Command-D"),
10865
 
    exec: function(editor) { editor.removeLines(); },
10866
 
    multiSelectAction: "forEachLine"
10867
 
}, {
10868
 
    name: "duplicateSelection",
10869
 
    bindKey: bindKey("Ctrl-Shift-D", "Command-Shift-D"),
10870
 
    exec: function(editor) { editor.duplicateSelection(); },
10871
 
    multiSelectAction: "forEach"
10872
 
}, {
10873
 
    name: "sortlines",
10874
 
    bindKey: bindKey("Ctrl-Alt-S", "Command-Alt-S"),
10875
 
    exec: function(editor) { editor.sortLines(); },
10876
 
    multiSelectAction: "forEachLine"
10877
 
}, {
10878
 
    name: "togglecomment",
10879
 
    bindKey: bindKey("Ctrl-/", "Command-/"),
10880
 
    exec: function(editor) { editor.toggleCommentLines(); },
10881
 
    multiSelectAction: "forEachLine"
10882
 
}, {
10883
 
    name: "modifyNumberUp",
10884
 
    bindKey: bindKey("Ctrl-Shift-Up", "Alt-Shift-Up"),
10885
 
    exec: function(editor) { editor.modifyNumber(1); },
10886
 
    multiSelectAction: "forEach"
10887
 
}, {
10888
 
    name: "modifyNumberDown",
10889
 
    bindKey: bindKey("Ctrl-Shift-Down", "Alt-Shift-Down"),
10890
 
    exec: function(editor) { editor.modifyNumber(-1); },
10891
 
    multiSelectAction: "forEach"
10892
 
}, {
10893
 
    name: "replace",
10894
 
    bindKey: bindKey("Ctrl-H", "Command-Option-F"),
10895
 
    exec: function(editor) {
10896
 
        config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor, true)});
10897
 
    }
10898
 
}, {
10899
 
    name: "undo",
10900
 
    bindKey: bindKey("Ctrl-Z", "Command-Z"),
10901
 
    exec: function(editor) { editor.undo(); }
10902
 
}, {
10903
 
    name: "redo",
10904
 
    bindKey: bindKey("Ctrl-Shift-Z|Ctrl-Y", "Command-Shift-Z|Command-Y"),
10905
 
    exec: function(editor) { editor.redo(); }
10906
 
}, {
10907
 
    name: "copylinesup",
10908
 
    bindKey: bindKey("Alt-Shift-Up", "Command-Option-Up"),
10909
 
    exec: function(editor) { editor.copyLinesUp(); }
10910
 
}, {
10911
 
    name: "movelinesup",
10912
 
    bindKey: bindKey("Alt-Up", "Option-Up"),
10913
 
    exec: function(editor) { editor.moveLinesUp(); }
10914
 
}, {
10915
 
    name: "copylinesdown",
10916
 
    bindKey: bindKey("Alt-Shift-Down", "Command-Option-Down"),
10917
 
    exec: function(editor) { editor.copyLinesDown(); }
10918
 
}, {
10919
 
    name: "movelinesdown",
10920
 
    bindKey: bindKey("Alt-Down", "Option-Down"),
10921
 
    exec: function(editor) { editor.moveLinesDown(); }
10922
 
}, {
10923
 
    name: "del",
10924
 
    bindKey: bindKey("Delete", "Delete|Ctrl-D"),
10925
 
    exec: function(editor) { editor.remove("right"); },
10926
 
    multiSelectAction: "forEach"
10927
 
}, {
10928
 
    name: "backspace",
10929
 
    bindKey: bindKey(
10930
 
        "Command-Backspace|Option-Backspace|Shift-Backspace|Backspace",
10931
 
        "Ctrl-Backspace|Command-Backspace|Shift-Backspace|Backspace|Ctrl-H"
10932
 
    ),
10933
 
    exec: function(editor) { editor.remove("left"); },
10934
 
    multiSelectAction: "forEach"
10935
 
}, {
10936
 
    name: "removetolinestart",
10937
 
    bindKey: bindKey("Alt-Backspace", "Command-Backspace"),
10938
 
    exec: function(editor) { editor.removeToLineStart(); },
10939
 
    multiSelectAction: "forEach"
10940
 
}, {
10941
 
    name: "removetolineend",
10942
 
    bindKey: bindKey("Alt-Delete", "Ctrl-K"),
10943
 
    exec: function(editor) { editor.removeToLineEnd(); },
10944
 
    multiSelectAction: "forEach"
10945
 
}, {
10946
 
    name: "removewordleft",
10947
 
    bindKey: bindKey("Ctrl-Backspace", "Alt-Backspace|Ctrl-Alt-Backspace"),
10948
 
    exec: function(editor) { editor.removeWordLeft(); },
10949
 
    multiSelectAction: "forEach"
10950
 
}, {
10951
 
    name: "removewordright",
10952
 
    bindKey: bindKey("Ctrl-Delete", "Alt-Delete"),
10953
 
    exec: function(editor) { editor.removeWordRight(); },
10954
 
    multiSelectAction: "forEach"
10955
 
}, {
10956
 
    name: "outdent",
10957
 
    bindKey: bindKey("Shift-Tab", "Shift-Tab"),
10958
 
    exec: function(editor) { editor.blockOutdent(); },
10959
 
    multiSelectAction: "forEach"
10960
 
}, {
10961
 
    name: "indent",
10962
 
    bindKey: bindKey("Tab", "Tab"),
10963
 
    exec: function(editor) { editor.indent(); },
10964
 
    multiSelectAction: "forEach"
10965
 
},{
10966
 
    name: "blockoutdent",
10967
 
    bindKey: bindKey("Ctrl-[", "Ctrl-["),
10968
 
    exec: function(editor) { editor.blockOutdent(); },
10969
 
    multiSelectAction: "forEachLine"
10970
 
},{
10971
 
    name: "blockindent",
10972
 
    bindKey: bindKey("Ctrl-]", "Ctrl-]"),
10973
 
    exec: function(editor) { editor.blockIndent(); },
10974
 
    multiSelectAction: "forEachLine"
10975
 
}, {
10976
 
    name: "insertstring",
10977
 
    exec: function(editor, str) { editor.insert(str); },
10978
 
    multiSelectAction: "forEach"
10979
 
}, {
10980
 
    name: "inserttext",
10981
 
    exec: function(editor, args) {
10982
 
        editor.insert(lang.stringRepeat(args.text  || "", args.times || 1));
10983
 
    },
10984
 
    multiSelectAction: "forEach"
10985
 
}, {
10986
 
    name: "splitline",
10987
 
    bindKey: bindKey(null, "Ctrl-O"),
10988
 
    exec: function(editor) { editor.splitLine(); },
10989
 
    multiSelectAction: "forEach"
10990
 
}, {
10991
 
    name: "transposeletters",
10992
 
    bindKey: bindKey("Ctrl-T", "Ctrl-T"),
10993
 
    exec: function(editor) { editor.transposeLetters(); },
10994
 
    multiSelectAction: function(editor) {editor.transposeSelections(1); }
10995
 
}, {
10996
 
    name: "touppercase",
10997
 
    bindKey: bindKey("Ctrl-U", "Ctrl-U"),
10998
 
    exec: function(editor) { editor.toUpperCase(); },
10999
 
    multiSelectAction: "forEach"
11000
 
}, {
11001
 
    name: "tolowercase",
11002
 
    bindKey: bindKey("Ctrl-Shift-U", "Ctrl-Shift-U"),
11003
 
    exec: function(editor) { editor.toLowerCase(); },
11004
 
    multiSelectAction: "forEach"
11005
 
}];
11006
 
 
11007
 
});
11008
 
 
11009
 
define('ace/undomanager', ['require', 'exports', 'module' ], function(require, exports, module) {
11010
 
var UndoManager = function() {
11011
 
    this.reset();
11012
 
};
11013
 
 
11014
 
(function() {
11015
 
    this.execute = function(options) {
11016
 
        var deltas = options.args[0];
11017
 
        this.$doc  = options.args[1];
11018
 
        this.$undoStack.push(deltas);
11019
 
        this.$redoStack = [];
11020
 
    };
11021
 
    this.undo = function(dontSelect) {
11022
 
        var deltas = this.$undoStack.pop();
11023
 
        var undoSelectionRange = null;
11024
 
        if (deltas) {
11025
 
            undoSelectionRange =
11026
 
                this.$doc.undoChanges(deltas, dontSelect);
11027
 
            this.$redoStack.push(deltas);
11028
 
        }
11029
 
        return undoSelectionRange;
11030
 
    };
11031
 
    this.redo = function(dontSelect) {
11032
 
        var deltas = this.$redoStack.pop();
11033
 
        var redoSelectionRange = null;
11034
 
        if (deltas) {
11035
 
            redoSelectionRange =
11036
 
                this.$doc.redoChanges(deltas, dontSelect);
11037
 
            this.$undoStack.push(deltas);
11038
 
        }
11039
 
        return redoSelectionRange;
11040
 
    };
11041
 
    this.reset = function() {
11042
 
        this.$undoStack = [];
11043
 
        this.$redoStack = [];
11044
 
    };
11045
 
    this.hasUndo = function() {
11046
 
        return this.$undoStack.length > 0;
11047
 
    };
11048
 
    this.hasRedo = function() {
11049
 
        return this.$redoStack.length > 0;
11050
 
    };
11051
 
 
11052
 
}).call(UndoManager.prototype);
11053
 
 
11054
 
exports.UndoManager = UndoManager;
11055
 
});
11056
 
 
11057
 
define('ace/virtual_renderer', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/dom', 'ace/lib/event', 'ace/lib/useragent', 'ace/config', 'ace/layer/gutter', 'ace/layer/marker', 'ace/layer/text', 'ace/layer/cursor', 'ace/scrollbar', 'ace/renderloop', 'ace/lib/event_emitter'], function(require, exports, module) {
11058
 
 
11059
 
 
11060
 
var oop = require("./lib/oop");
11061
 
var dom = require("./lib/dom");
11062
 
var event = require("./lib/event");
11063
 
var useragent = require("./lib/useragent");
11064
 
var config = require("./config");
11065
 
var GutterLayer = require("./layer/gutter").Gutter;
11066
 
var MarkerLayer = require("./layer/marker").Marker;
11067
 
var TextLayer = require("./layer/text").Text;
11068
 
var CursorLayer = require("./layer/cursor").Cursor;
11069
 
var ScrollBar = require("./scrollbar").ScrollBar;
11070
 
var RenderLoop = require("./renderloop").RenderLoop;
11071
 
var EventEmitter = require("./lib/event_emitter").EventEmitter;
11072
 
var editorCss = ".ace_editor {\
11073
 
position: relative;\
11074
 
overflow: hidden;\
11075
 
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;\
11076
 
font-size: 12px;\
11077
 
line-height: normal;\
11078
 
}\
11079
 
.ace_scroller {\
11080
 
position: absolute;\
11081
 
overflow: hidden;\
11082
 
top: 0;\
11083
 
bottom: 0;\
11084
 
}\
11085
 
.ace_content {\
11086
 
position: absolute;\
11087
 
-moz-box-sizing: border-box;\
11088
 
-webkit-box-sizing: border-box;\
11089
 
box-sizing: border-box;\
11090
 
cursor: text;\
11091
 
}\
11092
 
.ace_gutter {\
11093
 
position: absolute;\
11094
 
overflow : hidden;\
11095
 
width: auto;\
11096
 
top: 0;\
11097
 
bottom: 0;\
11098
 
left: 0;\
11099
 
cursor: default;\
11100
 
z-index: 4;\
11101
 
}\
11102
 
.ace_gutter-active-line {\
11103
 
position: absolute;\
11104
 
left: 0;\
11105
 
right: 0;\
11106
 
}\
11107
 
.ace_scroller.ace_scroll-left {\
11108
 
box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;\
11109
 
}\
11110
 
.ace_gutter-cell {\
11111
 
padding-left: 19px;\
11112
 
padding-right: 6px;\
11113
 
background-repeat: no-repeat;\
11114
 
}\
11115
 
.ace_gutter-cell.ace_error {\
11116
 
background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QUM2OEZDQTQ4RTU0MTFFMUEzM0VFRTM2RUY1M0RBMjYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QUM2OEZDQTU4RTU0MTFFMUEzM0VFRTM2RUY1M0RBMjYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpBQzY4RkNBMjhFNTQxMUUxQTMzRUVFMzZFRjUzREEyNiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpBQzY4RkNBMzhFNTQxMUUxQTMzRUVFMzZFRjUzREEyNiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PkgXxbAAAAJbSURBVHjapFNNaBNBFH4zs5vdZLP5sQmNpT82QY209heh1ioWisaDRcSKF0WKJ0GQnrzrxasHsR6EnlrwD0TagxJabaVEpFYxLWlLSS822tr87m66ccfd2GKyVhA6MMybgfe97/vmPUQphd0sZjto9XIn9OOsvlu2nkqRzVU+6vvlzPf8W6bk8dxQ0NPbxAALgCgg2JkaQuhzQau/El0zbmUA7U0Es8v2CiYmKQJHGO1QICCLoqilMhkmurDAyapKgqItezi/USRdJqEYY4D5jCy03ht2yMkkvL91jTTX10qzyyu2hruPRN7jgbH+EOsXcMLgYiThEgAMhABW85oqy1DXdRIdvP1AHJ2acQXvDIrVHcdQNrEKNYSVMSZGMjEzIIAwDXIo+6G/FxcGnzkC3T2oMhLjre49sBB+RRcHLqdafK6sYdE/GGBwU1VpFNj0aN8pJbe+BkZyevUrvLl6Xmm0W9IuTc0DxrDNAJd5oEvI/KRsNC3bQyNjPO9yQ1YHcfj2QvfQc/5TUhJTBc2iM0U7AWDQtc1nJHvD/cfO2s7jaGkiTEfa/Ep8coLu7zmNmh8+dc5lZDuUeFAGUNA/OY6JVaypQ0vjr7XYjUvJM37vt+j1vuTK5DgVfVUoTjVe+y3/LxMxY2GgU+CSLy4cpfsYorRXuXIOi0Vt40h67uZFTdIo6nLaZcwUJWAzwNS0tBnqqKzQDnjdG/iPyZxo46HaKUpbvYkj8qYRTZsBhge+JHhZyh0x9b95JqjVJkT084kZIPwu/mPWqPgfQ5jXh2+92Ay7HedfAgwA6KDWafb4w3cAAAAASUVORK5CYII=\");\
11117
 
background-repeat: no-repeat;\
11118
 
background-position: 2px center;\
11119
 
}\
11120
 
.ace_gutter-cell.ace_warning {\
11121
 
background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QUM2OEZDQTg4RTU0MTFFMUEzM0VFRTM2RUY1M0RBMjYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QUM2OEZDQTk4RTU0MTFFMUEzM0VFRTM2RUY1M0RBMjYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpBQzY4RkNBNjhFNTQxMUUxQTMzRUVFMzZFRjUzREEyNiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpBQzY4RkNBNzhFNTQxMUUxQTMzRUVFMzZFRjUzREEyNiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pgd7PfIAAAGmSURBVHjaYvr//z8DJZiJgUIANoCRkREb9gLiSVAaQx4OQM7AAkwd7XU2/v++/rOttdYGEB9dASEvOMydGKfH8Gv/p4XTkvRBfLxeQAP+1cUhXopyvzhP7P/IoSj7g7Mw09cNKO6J1QQ0L4gICPIv/veg/8W+JdFvQNLHVsW9/nmn9zk7B+cCkDwhL7gt6knSZnx9/LuCEOcvkIAMP+cvto9nfqyZmmUAksfnBUtbM60gX/3/kgyv3/xSFOL5DZT+L8vP+Yfh5cvfPvp/xUHyQHXGyAYwgpwBjZYFT3Y1OEl/OfCH4ffv3wzc4iwMvNIsDJ+f/mH4+vIPAxsb631WW0Yln6ZpQLXdMK/DXGDflh+sIv37EivD5x//Gb7+YWT4y86sl7BCCkSD+Z++/1dkvsFRl+HnD1Rvje4F8whjMXmGj58YGf5zsDMwcnAwfPvKcml62DsQDeaDxN+/Y0qwlpEHqrdB94IRNIDUgfgfKJChGK4OikEW3gTiXUB950ASLFAF54AC94A0G9QAfOnmF9DCDzABFqS08IHYDIScdijOjQABBgC+/9awBH96jwAAAABJRU5ErkJggg==\");\
11122
 
background-position: 2px center;\
11123
 
}\
11124
 
.ace_gutter-cell.ace_info {\
11125
 
background-image: url(\"data:image/gif;base64,R0lGODlhEAAQAMQAAAAAAEFBQVJSUl5eXmRkZGtra39/f4WFhYmJiZGRkaampry8vMPDw8zMzNXV1dzc3OTk5Orq6vDw8P///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABQALAAAAAAQABAAAAUuICWOZGmeaBml5XGwFCQSBGyXRSAwtqQIiRuiwIM5BoYVbEFIyGCQoeJGrVptIQA7\");\
11126
 
background-position: 2px center;\
11127
 
}\
11128
 
.ace_dark .ace_gutter-cell.ace_info {\
11129
 
background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpGRTk5MTVGREIxNDkxMUUxOTc5Q0FFREQyMTNGMjBFQyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpGRTk5MTVGRUIxNDkxMUUxOTc5Q0FFREQyMTNGMjBFQyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkZFOTkxNUZCQjE0OTExRTE5NzlDQUVERDIxM0YyMEVDIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkZFOTkxNUZDQjE0OTExRTE5NzlDQUVERDIxM0YyMEVDIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+SIDkjAAAAJ1JREFUeNpi/P//PwMlgImBQkB7A6qrq/+DMC55FkIGKCoq4pVnpFkgTp069f/+/fv/r1u37r+tre1/kg0A+ptn9uzZYLaRkRHpLvjw4cNXWVlZhufPnzOcO3eOdAO0tbVPAjHDmzdvGA4fPsxIsgGSkpJmv379Ynj37h2DjIyMCMkG3LhxQ/T27dsMampqDHZ2dq/pH41DxwCAAAMAFdc68dUsFZgAAAAASUVORK5CYII=\");\
11130
 
}\
11131
 
.ace_scrollbar {\
11132
 
position: absolute;\
11133
 
overflow-x: hidden;\
11134
 
overflow-y: scroll;\
11135
 
right: 0;\
11136
 
top: 0;\
11137
 
bottom: 0;\
11138
 
}\
11139
 
.ace_scrollbar-inner {\
11140
 
position: absolute;\
11141
 
width: 1px;\
11142
 
left: 0;\
11143
 
}\
11144
 
.ace_print-margin {\
11145
 
position: absolute;\
11146
 
height: 100%;\
11147
 
}\
11148
 
.ace_text-input {\
11149
 
position: absolute;\
11150
 
z-index: 0;\
11151
 
width: 0.5em;\
11152
 
height: 1em;\
11153
 
opacity: 0;\
11154
 
background: transparent;\
11155
 
-moz-appearance: none;\
11156
 
appearance: none;\
11157
 
border: none;\
11158
 
resize: none;\
11159
 
outline: none;\
11160
 
overflow: hidden;\
11161
 
font: inherit;\
11162
 
}\
11163
 
.ace_text-input.ace_composition {\
11164
 
background: #f8f8f8;\
11165
 
color: #111;\
11166
 
z-index: 1000;\
11167
 
opacity: 1;\
11168
 
border: solid lightgray 1px;\
11169
 
margin: -1px;\
11170
 
padding: 0 1px;\
11171
 
}\
11172
 
.ace_layer {\
11173
 
z-index: 1;\
11174
 
position: absolute;\
11175
 
overflow: hidden;\
11176
 
white-space: nowrap;\
11177
 
height: 100%;\
11178
 
width: 100%;\
11179
 
-moz-box-sizing: border-box;\
11180
 
-webkit-box-sizing: border-box;\
11181
 
box-sizing: border-box;\
11182
 
/* setting pointer-events: auto; on node under the mouse, which changes\
11183
 
during scroll, will break mouse wheel scrolling in Safari */\
11184
 
pointer-events: none;\
11185
 
}\
11186
 
.ace_gutter-layer {\
11187
 
position: relative;\
11188
 
width: auto;\
11189
 
text-align: right;\
11190
 
pointer-events: auto;\
11191
 
}\
11192
 
.ace_text-layer {\
11193
 
color: black;\
11194
 
font: inherit !important;\
11195
 
}\
11196
 
.ace_cjk {\
11197
 
display: inline-block;\
11198
 
text-align: center;\
11199
 
}\
11200
 
.ace_cursor-layer {\
11201
 
z-index: 4;\
11202
 
}\
11203
 
.ace_cursor {\
11204
 
z-index: 4;\
11205
 
position: absolute;\
11206
 
-moz-box-sizing: border-box;\
11207
 
-webkit-box-sizing: border-box;\
11208
 
box-sizing: border-box;\
11209
 
}\
11210
 
.ace_hidden-cursors .ace_cursor {\
11211
 
opacity: 0.2;\
11212
 
}\
11213
 
.ace_smooth-blinking .ace_cursor {\
11214
 
-moz-transition: opacity 0.18s;\
11215
 
-webkit-transition: opacity 0.18s;\
11216
 
-o-transition: opacity 0.18s;\
11217
 
-ms-transition: opacity 0.18s;\
11218
 
transition: opacity 0.18s;\
11219
 
}\
11220
 
.ace_cursor[style*=\"opacity: 0\"]{\
11221
 
-ms-filter: \"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)\";\
11222
 
}\
11223
 
.ace_editor.ace_multiselect .ace_cursor {\
11224
 
border-left-width: 1px;\
11225
 
}\
11226
 
.ace_line {\
11227
 
white-space: nowrap;\
11228
 
}\
11229
 
.ace_marker-layer .ace_step {\
11230
 
position: absolute;\
11231
 
z-index: 3;\
11232
 
}\
11233
 
.ace_marker-layer .ace_selection {\
11234
 
position: absolute;\
11235
 
z-index: 5;\
11236
 
}\
11237
 
.ace_marker-layer .ace_bracket {\
11238
 
position: absolute;\
11239
 
z-index: 6;\
11240
 
}\
11241
 
.ace_marker-layer .ace_active-line {\
11242
 
position: absolute;\
11243
 
z-index: 2;\
11244
 
}\
11245
 
.ace_marker-layer .ace_selected-word {\
11246
 
position: absolute;\
11247
 
z-index: 4;\
11248
 
-moz-box-sizing: border-box;\
11249
 
-webkit-box-sizing: border-box;\
11250
 
box-sizing: border-box;\
11251
 
}\
11252
 
.ace_line .ace_fold {\
11253
 
-moz-box-sizing: border-box;\
11254
 
-webkit-box-sizing: border-box;\
11255
 
box-sizing: border-box;\
11256
 
display: inline-block;\
11257
 
height: 11px;\
11258
 
margin-top: -2px;\
11259
 
vertical-align: middle;\
11260
 
background-image:\
11261
 
url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%11%00%00%00%09%08%06%00%00%00%D4%E8%C7%0C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%B5IDAT(%15%A5%91%3D%0E%02!%10%85ac%E1%05%D6%CE%D6%C6%CE%D2%E8%ED%CD%DE%C0%C6%D6N.%E0V%F8%3D%9Ca%891XH%C2%BE%D9y%3F%90!%E6%9C%C3%BFk%E5%011%C6-%F5%C8N%04%DF%BD%FF%89%DFt%83DN%60%3E%F3%AB%A0%DE%1A%5Dg%BE%10Q%97%1B%40%9C%A8o%10%8F%5E%828%B4%1B%60%87%F6%02%26%85%1Ch%1E%C1%2B%5Bk%FF%86%EE%B7j%09%9A%DA%9B%ACe%A3%F9%EC%DA!9%B4%D5%A6%81%86%86%98%CC%3C%5B%40%FA%81%B3%E9%CB%23%94%C16Azo%05%D4%E1%C1%95a%3B%8A'%A0%E8%CC%17%22%85%1D%BA%00%A2%FA%DC%0A%94%D1%D1%8D%8B%3A%84%17B%C7%60%1A%25Z%FC%8D%00%00%00%00IEND%AEB%60%82\"),\
11262
 
url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%007%08%06%00%00%00%C4%DD%80C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%3AIDAT8%11c%FC%FF%FF%7F%18%03%1A%60%01%F2%3F%A0%891%80%04%FF%11-%F8%17%9BJ%E2%05%B1ZD%81v%26t%E7%80%F8%A3%82h%A12%1A%20%A3%01%02%0F%01%BA%25%06%00%19%C0%0D%AEF%D5%3ES%00%00%00%00IEND%AEB%60%82\");\
11263
 
background-repeat: no-repeat, repeat-x;\
11264
 
background-position: center center, top left;\
11265
 
color: transparent;\
11266
 
border: 1px solid black;\
11267
 
-moz-border-radius: 2px;\
11268
 
-webkit-border-radius: 2px;\
11269
 
border-radius: 2px;\
11270
 
cursor: pointer;\
11271
 
pointer-events: auto;\
11272
 
}\
11273
 
.ace_dark .ace_fold {\
11274
 
}\
11275
 
.ace_fold:hover{\
11276
 
background-image:\
11277
 
url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%11%00%00%00%09%08%06%00%00%00%D4%E8%C7%0C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%B5IDAT(%15%A5%91%3D%0E%02!%10%85ac%E1%05%D6%CE%D6%C6%CE%D2%E8%ED%CD%DE%C0%C6%D6N.%E0V%F8%3D%9Ca%891XH%C2%BE%D9y%3F%90!%E6%9C%C3%BFk%E5%011%C6-%F5%C8N%04%DF%BD%FF%89%DFt%83DN%60%3E%F3%AB%A0%DE%1A%5Dg%BE%10Q%97%1B%40%9C%A8o%10%8F%5E%828%B4%1B%60%87%F6%02%26%85%1Ch%1E%C1%2B%5Bk%FF%86%EE%B7j%09%9A%DA%9B%ACe%A3%F9%EC%DA!9%B4%D5%A6%81%86%86%98%CC%3C%5B%40%FA%81%B3%E9%CB%23%94%C16Azo%05%D4%E1%C1%95a%3B%8A'%A0%E8%CC%17%22%85%1D%BA%00%A2%FA%DC%0A%94%D1%D1%8D%8B%3A%84%17B%C7%60%1A%25Z%FC%8D%00%00%00%00IEND%AEB%60%82\"),\
11278
 
url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%007%08%06%00%00%00%C4%DD%80C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%003IDAT8%11c%FC%FF%FF%7F%3E%03%1A%60%01%F2%3F%A3%891%80%04%FFQ%26%F8w%C0%B43%A1%DB%0C%E2%8F%0A%A2%85%CAh%80%8C%06%08%3C%04%E8%96%18%00%A3S%0D%CD%CF%D8%C1%9D%00%00%00%00IEND%AEB%60%82\");\
11279
 
background-repeat: no-repeat, repeat-x;\
11280
 
background-position: center center, top left;\
11281
 
}\
11282
 
.ace_editor.ace_dragging .ace_content {\
11283
 
cursor: move;\
11284
 
}\
11285
 
.ace_gutter-tooltip {\
11286
 
background-color: #FFF;\
11287
 
background-image: -webkit-linear-gradient(top, transparent, rgba(0, 0, 0, 0.1));\
11288
 
background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));\
11289
 
border: 1px solid gray;\
11290
 
border-radius: 1px;\
11291
 
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);\
11292
 
color: black;\
11293
 
display: inline-block;\
11294
 
max-width: 500px;\
11295
 
padding: 4px;\
11296
 
position: fixed;\
11297
 
z-index: 300;\
11298
 
-moz-box-sizing: border-box;\
11299
 
-webkit-box-sizing: border-box;\
11300
 
box-sizing: border-box;\
11301
 
cursor: default;\
11302
 
white-space: pre-line;\
11303
 
word-wrap: break-word;\
11304
 
line-height: normal;\
11305
 
font-style: normal;\
11306
 
font-weight: normal;\
11307
 
letter-spacing: normal;\
11308
 
}\
11309
 
.ace_folding-enabled > .ace_gutter-cell {\
11310
 
padding-right: 13px;\
11311
 
}\
11312
 
.ace_fold-widget {\
11313
 
-moz-box-sizing: border-box;\
11314
 
-webkit-box-sizing: border-box;\
11315
 
box-sizing: border-box;\
11316
 
margin: 0 -12px 0 1px;\
11317
 
display: inline-block;\
11318
 
width: 11px;\
11319
 
vertical-align: top;\
11320
 
background-image: url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%00%05%08%06%00%00%00%8Do%26%E5%00%00%004IDATx%DAe%8A%B1%0D%000%0C%C2%F2%2CK%96%BC%D0%8F9%81%88H%E9%D0%0E%96%C0%10%92%3E%02%80%5E%82%E4%A9*-%EEsw%C8%CC%11%EE%96w%D8%DC%E9*Eh%0C%151(%00%00%00%00IEND%AEB%60%82\");\
11321
 
background-repeat: no-repeat;\
11322
 
background-position: center;\
11323
 
border-radius: 3px;\
11324
 
border: 1px solid transparent;\
11325
 
}\
11326
 
.ace_fold-widget.ace_end {\
11327
 
background-image: url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%00%05%08%06%00%00%00%8Do%26%E5%00%00%004IDATx%DAm%C7%C1%09%000%08C%D1%8C%ECE%C8E(%8E%EC%02)%1EZJ%F1%C1'%04%07I%E1%E5%EE%CAL%F5%A2%99%99%22%E2%D6%1FU%B5%FE0%D9x%A7%26Wz5%0E%D5%00%00%00%00IEND%AEB%60%82\");\
11328
 
}\
11329
 
.ace_fold-widget.ace_closed {\
11330
 
background-image: url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%03%00%00%00%06%08%06%00%00%00%06%E5%24%0C%00%00%009IDATx%DA5%CA%C1%09%000%08%03%C0%AC*(%3E%04%C1%0D%BA%B1%23%A4Uh%E0%20%81%C0%CC%F8%82%81%AA%A2%AArGfr%88%08%11%11%1C%DD%7D%E0%EE%5B%F6%F6%CB%B8%05Q%2F%E9tai%D9%00%00%00%00IEND%AEB%60%82\");\
11331
 
}\
11332
 
.ace_fold-widget:hover {\
11333
 
border: 1px solid rgba(0, 0, 0, 0.3);\
11334
 
background-color: rgba(255, 255, 255, 0.2);\
11335
 
-moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\
11336
 
-webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\
11337
 
box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\
11338
 
}\
11339
 
.ace_fold-widget:active {\
11340
 
border: 1px solid rgba(0, 0, 0, 0.4);\
11341
 
background-color: rgba(0, 0, 0, 0.05);\
11342
 
-moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\
11343
 
-webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\
11344
 
box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\
11345
 
}\
11346
 
/**\
11347
 
* Dark version for fold widgets\
11348
 
*/\
11349
 
.ace_dark .ace_fold-widget {\
11350
 
background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC\");\
11351
 
}\
11352
 
.ace_dark .ace_fold-widget.ace_end {\
11353
 
background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==\");\
11354
 
}\
11355
 
.ace_dark .ace_fold-widget.ace_closed {\
11356
 
background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==\");\
11357
 
}\
11358
 
.ace_dark .ace_fold-widget:hover {\
11359
 
box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\
11360
 
background-color: rgba(255, 255, 255, 0.1);\
11361
 
}\
11362
 
.ace_dark .ace_fold-widget:active {\
11363
 
-moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\
11364
 
-webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\
11365
 
box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\
11366
 
}\
11367
 
.ace_fold-widget.ace_invalid {\
11368
 
background-color: #FFB4B4;\
11369
 
border-color: #DE5555;\
11370
 
}\
11371
 
.ace_fade-fold-widgets .ace_fold-widget {\
11372
 
-moz-transition: opacity 0.4s ease 0.05s;\
11373
 
-webkit-transition: opacity 0.4s ease 0.05s;\
11374
 
-o-transition: opacity 0.4s ease 0.05s;\
11375
 
-ms-transition: opacity 0.4s ease 0.05s;\
11376
 
transition: opacity 0.4s ease 0.05s;\
11377
 
opacity: 0;\
11378
 
}\
11379
 
.ace_fade-fold-widgets:hover .ace_fold-widget {\
11380
 
-moz-transition: opacity 0.05s ease 0.05s;\
11381
 
-webkit-transition: opacity 0.05s ease 0.05s;\
11382
 
-o-transition: opacity 0.05s ease 0.05s;\
11383
 
-ms-transition: opacity 0.05s ease 0.05s;\
11384
 
transition: opacity 0.05s ease 0.05s;\
11385
 
opacity:1;\
11386
 
}\
11387
 
.ace_underline {\
11388
 
text-decoration: underline;\
11389
 
}\
11390
 
.ace_bold {\
11391
 
font-weight: bold;\
11392
 
}\
11393
 
.ace_nobold .ace_bold {\
11394
 
font-weight: normal;\
11395
 
}\
11396
 
.ace_italic {\
11397
 
font-style: italic;\
11398
 
}\
11399
 
";
11400
 
 
11401
 
dom.importCssString(editorCss, "ace_editor");
11402
 
 
11403
 
var VirtualRenderer = function(container, theme) {
11404
 
    var _self = this;
11405
 
 
11406
 
    this.container = container || dom.createElement("div");
11407
 
    this.$keepTextAreaAtCursor = !useragent.isIE;
11408
 
 
11409
 
    dom.addCssClass(this.container, "ace_editor");
11410
 
 
11411
 
    this.setTheme(theme);
11412
 
 
11413
 
    this.$gutter = dom.createElement("div");
11414
 
    this.$gutter.className = "ace_gutter";
11415
 
    this.container.appendChild(this.$gutter);
11416
 
 
11417
 
    this.scroller = dom.createElement("div");
11418
 
    this.scroller.className = "ace_scroller";
11419
 
    this.container.appendChild(this.scroller);
11420
 
 
11421
 
    this.content = dom.createElement("div");
11422
 
    this.content.className = "ace_content";
11423
 
    this.scroller.appendChild(this.content);
11424
 
 
11425
 
    this.$gutterLayer = new GutterLayer(this.$gutter);
11426
 
    this.$gutterLayer.on("changeGutterWidth", this.onGutterResize.bind(this));
11427
 
 
11428
 
    this.$markerBack = new MarkerLayer(this.content);
11429
 
 
11430
 
    var textLayer = this.$textLayer = new TextLayer(this.content);
11431
 
    this.canvas = textLayer.element;
11432
 
 
11433
 
    this.$markerFront = new MarkerLayer(this.content);
11434
 
 
11435
 
    this.$cursorLayer = new CursorLayer(this.content);
11436
 
    this.$horizScroll = false;
11437
 
    this.$horizScrollAlwaysVisible = false;
11438
 
 
11439
 
    this.scrollBar = new ScrollBar(this.container);
11440
 
    this.scrollBar.addEventListener("scroll", function(e) {
11441
 
        if (!_self.$inScrollAnimation)
11442
 
            _self.session.setScrollTop(e.data);
11443
 
    });
11444
 
 
11445
 
    this.scrollTop = 0;
11446
 
    this.scrollLeft = 0;
11447
 
 
11448
 
    event.addListener(this.scroller, "scroll", function() {
11449
 
        var scrollLeft = _self.scroller.scrollLeft;
11450
 
        _self.scrollLeft = scrollLeft;
11451
 
        _self.session.setScrollLeft(scrollLeft);
11452
 
    });
11453
 
 
11454
 
    this.cursorPos = {
11455
 
        row : 0,
11456
 
        column : 0
11457
 
    };
11458
 
 
11459
 
    this.$textLayer.addEventListener("changeCharacterSize", function() {
11460
 
        _self.updateCharacterSize();
11461
 
        _self.onResize(true);
11462
 
    });
11463
 
 
11464
 
    this.$size = {
11465
 
        width: 0,
11466
 
        height: 0,
11467
 
        scrollerHeight: 0,
11468
 
        scrollerWidth: 0
11469
 
    };
11470
 
 
11471
 
    this.layerConfig = {
11472
 
        width : 1,
11473
 
        padding : 0,
11474
 
        firstRow : 0,
11475
 
        firstRowScreen: 0,
11476
 
        lastRow : 0,
11477
 
        lineHeight : 1,
11478
 
        characterWidth : 1,
11479
 
        minHeight : 1,
11480
 
        maxHeight : 1,
11481
 
        offset : 0,
11482
 
        height : 1
11483
 
    };
11484
 
 
11485
 
    this.$loop = new RenderLoop(
11486
 
        this.$renderChanges.bind(this),
11487
 
        this.container.ownerDocument.defaultView
11488
 
    );
11489
 
    this.$loop.schedule(this.CHANGE_FULL);
11490
 
 
11491
 
    this.updateCharacterSize();
11492
 
    this.setPadding(4);
11493
 
    config.resetOptions(this);
11494
 
    config._emit("renderer", this);
11495
 
};
11496
 
 
11497
 
(function() {
11498
 
 
11499
 
    this.CHANGE_CURSOR = 1;
11500
 
    this.CHANGE_MARKER = 2;
11501
 
    this.CHANGE_GUTTER = 4;
11502
 
    this.CHANGE_SCROLL = 8;
11503
 
    this.CHANGE_LINES = 16;
11504
 
    this.CHANGE_TEXT = 32;
11505
 
    this.CHANGE_SIZE = 64;
11506
 
    this.CHANGE_MARKER_BACK = 128;
11507
 
    this.CHANGE_MARKER_FRONT = 256;
11508
 
    this.CHANGE_FULL = 512;
11509
 
    this.CHANGE_H_SCROLL = 1024;
11510
 
 
11511
 
    oop.implement(this, EventEmitter);
11512
 
 
11513
 
    this.updateCharacterSize = function() {
11514
 
        if (this.$textLayer.allowBoldFonts != this.$allowBoldFonts) {
11515
 
            this.$allowBoldFonts = this.$textLayer.allowBoldFonts;
11516
 
            this.setStyle("ace_nobold", !this.$allowBoldFonts);
11517
 
        }
11518
 
 
11519
 
        this.characterWidth = this.$textLayer.getCharacterWidth();
11520
 
        this.lineHeight = this.$textLayer.getLineHeight();
11521
 
        this.$updatePrintMargin();
11522
 
    };
11523
 
    this.setSession = function(session) {
11524
 
        this.session = session;
11525
 
 
11526
 
        this.scroller.className = "ace_scroller";
11527
 
 
11528
 
        this.$cursorLayer.setSession(session);
11529
 
        this.$markerBack.setSession(session);
11530
 
        this.$markerFront.setSession(session);
11531
 
        this.$gutterLayer.setSession(session);
11532
 
        this.$textLayer.setSession(session);
11533
 
        this.$loop.schedule(this.CHANGE_FULL);
11534
 
 
11535
 
    };
11536
 
    this.updateLines = function(firstRow, lastRow) {
11537
 
        if (lastRow === undefined)
11538
 
            lastRow = Infinity;
11539
 
 
11540
 
        if (!this.$changedLines) {
11541
 
            this.$changedLines = {
11542
 
                firstRow: firstRow,
11543
 
                lastRow: lastRow
11544
 
            };
11545
 
        }
11546
 
        else {
11547
 
            if (this.$changedLines.firstRow > firstRow)
11548
 
                this.$changedLines.firstRow = firstRow;
11549
 
 
11550
 
            if (this.$changedLines.lastRow < lastRow)
11551
 
                this.$changedLines.lastRow = lastRow;
11552
 
        }
11553
 
 
11554
 
        if (this.$changedLines.firstRow > this.layerConfig.lastRow ||
11555
 
            this.$changedLines.lastRow < this.layerConfig.firstRow)
11556
 
            return;
11557
 
        this.$loop.schedule(this.CHANGE_LINES);
11558
 
    };
11559
 
 
11560
 
    this.onChangeTabSize = function() {
11561
 
        this.$loop.schedule(this.CHANGE_TEXT | this.CHANGE_MARKER);
11562
 
        this.$textLayer.onChangeTabSize();
11563
 
    };
11564
 
    this.updateText = function() {
11565
 
        this.$loop.schedule(this.CHANGE_TEXT);
11566
 
    };
11567
 
    this.updateFull = function(force) {
11568
 
        if (force)
11569
 
            this.$renderChanges(this.CHANGE_FULL, true);
11570
 
        else
11571
 
            this.$loop.schedule(this.CHANGE_FULL);
11572
 
    };
11573
 
    this.updateFontSize = function() {
11574
 
        this.$textLayer.checkForSizeChanges();
11575
 
    };
11576
 
    this.onResize = function(force, gutterWidth, width, height) {
11577
 
        var changes = 0;
11578
 
        var size = this.$size;
11579
 
 
11580
 
        if (this.resizing > 2)
11581
 
            return;
11582
 
        else if (this.resizing > 1)
11583
 
            this.resizing++;
11584
 
        else
11585
 
            this.resizing = force ? 1 : 0;
11586
 
        if (!height)
11587
 
            height = dom.getInnerHeight(this.container);
11588
 
 
11589
 
        if (height && (force || size.height != height)) {
11590
 
            size.height = height;
11591
 
            changes = this.CHANGE_SIZE;
11592
 
 
11593
 
            size.scrollerHeight = this.scroller.clientHeight;
11594
 
            if (!size.scrollerHeight) {
11595
 
                size.scrollerHeight = size.height;
11596
 
                if (this.$horizScroll)
11597
 
                    size.scrollerHeight -= this.scrollBar.getWidth();
11598
 
            }
11599
 
            this.scrollBar.setHeight(size.scrollerHeight);
11600
 
 
11601
 
            if (this.session) {
11602
 
                this.session.setScrollTop(this.getScrollTop());
11603
 
                changes = changes | this.CHANGE_FULL;
11604
 
            }
11605
 
        }
11606
 
 
11607
 
        if (!width)
11608
 
            width = dom.getInnerWidth(this.container);
11609
 
 
11610
 
        if (width && (force || this.resizing > 1 || size.width != width)) {
11611
 
            changes = this.CHANGE_SIZE;
11612
 
            size.width = width;
11613
 
 
11614
 
            var gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
11615
 
            this.scroller.style.left = gutterWidth + "px";
11616
 
            size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBar.getWidth());
11617
 
            this.scroller.style.right = this.scrollBar.getWidth() + "px";
11618
 
 
11619
 
            if (this.session.getUseWrapMode() && this.adjustWrapLimit() || force)
11620
 
                changes = changes | this.CHANGE_FULL;
11621
 
        }
11622
 
 
11623
 
        if (force)
11624
 
            this.$renderChanges(changes, true);
11625
 
        else
11626
 
            this.$loop.schedule(changes);
11627
 
 
11628
 
        if (force)
11629
 
            this.$gutterLayer.$padding = null;
11630
 
 
11631
 
        if (force)
11632
 
            delete this.resizing;
11633
 
    };
11634
 
 
11635
 
    this.onGutterResize = function() {
11636
 
        var width = this.$size.width;
11637
 
        var gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
11638
 
        this.scroller.style.left = gutterWidth + "px";
11639
 
        this.$size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBar.getWidth());
11640
 
 
11641
 
        if (this.session.getUseWrapMode() && this.adjustWrapLimit())
11642
 
            this.$loop.schedule(this.CHANGE_FULL);
11643
 
    };
11644
 
    this.adjustWrapLimit = function() {
11645
 
        var availableWidth = this.$size.scrollerWidth - this.$padding * 2;
11646
 
        var limit = Math.floor(availableWidth / this.characterWidth);
11647
 
        return this.session.adjustWrapLimit(limit);
11648
 
    };
11649
 
    this.setAnimatedScroll = function(shouldAnimate){
11650
 
        this.setOption("animatedScroll", shouldAnimate);
11651
 
    };
11652
 
    this.getAnimatedScroll = function() {
11653
 
        return this.$animatedScroll;
11654
 
    };
11655
 
    this.setShowInvisibles = function(showInvisibles) {
11656
 
        this.setOption("showInvisibles", showInvisibles);
11657
 
    };
11658
 
    this.getShowInvisibles = function() {
11659
 
        return this.getOption("showInvisibles");
11660
 
    };
11661
 
    this.getDisplayIndentGuides = function() {
11662
 
        return this.getOption("displayIndentGuides");
11663
 
    };
11664
 
 
11665
 
    this.setDisplayIndentGuides = function(display) {
11666
 
        this.setOption("displayIndentGuides", display);
11667
 
    };
11668
 
    this.setShowPrintMargin = function(showPrintMargin) {
11669
 
        this.setOption("showPrintMargin", showPrintMargin);
11670
 
    };
11671
 
    this.getShowPrintMargin = function() {
11672
 
        this.getOption("showPrintMargin");
11673
 
    };
11674
 
    this.setPrintMarginColumn = function(showPrintMargin) {
11675
 
        this.setOption("printMarginColumn", showPrintMargin);
11676
 
    };
11677
 
    this.getPrintMarginColumn = function() {
11678
 
        return this.getOption("printMarginColumn");
11679
 
    };
11680
 
    this.getShowGutter = function(){
11681
 
        return this.getOption("showGutter");
11682
 
    };
11683
 
    this.setShowGutter = function(show){
11684
 
        return this.setOption("showGutter", show);
11685
 
    };
11686
 
 
11687
 
    this.getFadeFoldWidgets = function(){
11688
 
        return this.getOption("fadeFoldWidgets")
11689
 
    };
11690
 
 
11691
 
    this.setFadeFoldWidgets = function(show) {
11692
 
        this.setOption("fadeFoldWidgets", show);
11693
 
    };
11694
 
 
11695
 
    this.setHighlightGutterLine = function(shouldHighlight) {
11696
 
        this.setOption("highlightGutterLine", shouldHighlight);
11697
 
    };
11698
 
 
11699
 
    this.getHighlightGutterLine = function() {
11700
 
        return this.getOption("highlightGutterLine");
11701
 
    };
11702
 
 
11703
 
    this.$updateGutterLineHighlight = function() {
11704
 
        var pos = this.$cursorLayer.$pixelPos;
11705
 
        var height = this.layerConfig.lineHeight;
11706
 
        if (this.session.getUseWrapMode()) {
11707
 
            var cursor = this.session.selection.getCursor();
11708
 
            cursor.column = 0;
11709
 
            pos = this.$cursorLayer.getPixelPosition(cursor, true);
11710
 
            height *= this.session.getRowLength(cursor.row);
11711
 
        }
11712
 
        this.$gutterLineHighlight.style.top = pos.top - this.layerConfig.offset + "px";
11713
 
        this.$gutterLineHighlight.style.height = height + "px";
11714
 
    };
11715
 
 
11716
 
    this.$updatePrintMargin = function() {
11717
 
        if (!this.$showPrintMargin && !this.$printMarginEl)
11718
 
            return;
11719
 
 
11720
 
        if (!this.$printMarginEl) {
11721
 
            var containerEl = dom.createElement("div");
11722
 
            containerEl.className = "ace_layer ace_print-margin-layer";
11723
 
            this.$printMarginEl = dom.createElement("div");
11724
 
            this.$printMarginEl.className = "ace_print-margin";
11725
 
            containerEl.appendChild(this.$printMarginEl);
11726
 
            this.content.insertBefore(containerEl, this.content.firstChild);
11727
 
        }
11728
 
 
11729
 
        var style = this.$printMarginEl.style;
11730
 
        style.left = ((this.characterWidth * this.$printMarginColumn) + this.$padding) + "px";
11731
 
        style.visibility = this.$showPrintMargin ? "visible" : "hidden";
11732
 
    };
11733
 
    this.getContainerElement = function() {
11734
 
        return this.container;
11735
 
    };
11736
 
    this.getMouseEventTarget = function() {
11737
 
        return this.content;
11738
 
    };
11739
 
    this.getTextAreaContainer = function() {
11740
 
        return this.container;
11741
 
    };
11742
 
    this.$moveTextAreaToCursor = function() {
11743
 
        if (!this.$keepTextAreaAtCursor)
11744
 
            return;
11745
 
        var config = this.layerConfig;
11746
 
        var posTop = this.$cursorLayer.$pixelPos.top;
11747
 
        var posLeft = this.$cursorLayer.$pixelPos.left;
11748
 
        posTop -= config.offset;
11749
 
 
11750
 
        if (posTop < 0 || posTop > config.height - this.lineHeight)
11751
 
            return;
11752
 
 
11753
 
        var w = this.characterWidth;
11754
 
        if (this.$composition) {
11755
 
            var val = this.textarea.value.replace(/^\x01+/, "");
11756
 
            w *= this.session.$getStringScreenWidth(val)[0];
11757
 
        }
11758
 
        posLeft -= this.scrollLeft;
11759
 
        if (posLeft > this.$size.scrollerWidth - w)
11760
 
            posLeft = this.$size.scrollerWidth - w;
11761
 
 
11762
 
        posLeft -= this.scrollBar.width;
11763
 
 
11764
 
        this.textarea.style.height = this.lineHeight + "px";
11765
 
        this.textarea.style.width = w + "px";
11766
 
        this.textarea.style.right = Math.max(0, this.$size.scrollerWidth - posLeft - w) + "px";
11767
 
        this.textarea.style.bottom = Math.max(0, this.$size.height - posTop - this.lineHeight) + "px";
11768
 
    };
11769
 
    this.getFirstVisibleRow = function() {
11770
 
        return this.layerConfig.firstRow;
11771
 
    };
11772
 
    this.getFirstFullyVisibleRow = function() {
11773
 
        return this.layerConfig.firstRow + (this.layerConfig.offset === 0 ? 0 : 1);
11774
 
    };
11775
 
    this.getLastFullyVisibleRow = function() {
11776
 
        var flint = Math.floor((this.layerConfig.height + this.layerConfig.offset) / this.layerConfig.lineHeight);
11777
 
        return this.layerConfig.firstRow - 1 + flint;
11778
 
    };
11779
 
    this.getLastVisibleRow = function() {
11780
 
        return this.layerConfig.lastRow;
11781
 
    };
11782
 
 
11783
 
    this.$padding = null;
11784
 
    this.setPadding = function(padding) {
11785
 
        this.$padding = padding;
11786
 
        this.$textLayer.setPadding(padding);
11787
 
        this.$cursorLayer.setPadding(padding);
11788
 
        this.$markerFront.setPadding(padding);
11789
 
        this.$markerBack.setPadding(padding);
11790
 
        this.$loop.schedule(this.CHANGE_FULL);
11791
 
        this.$updatePrintMargin();
11792
 
    };
11793
 
    this.getHScrollBarAlwaysVisible = function() {
11794
 
        return this.$horizScrollAlwaysVisible;
11795
 
    };
11796
 
    this.setHScrollBarAlwaysVisible = function(alwaysVisible) {
11797
 
        if (this.$horizScrollAlwaysVisible != alwaysVisible) {
11798
 
            this.$horizScrollAlwaysVisible = alwaysVisible;
11799
 
            if (!this.$horizScrollAlwaysVisible || !this.$horizScroll)
11800
 
                this.$loop.schedule(this.CHANGE_SCROLL);
11801
 
        }
11802
 
    };
11803
 
 
11804
 
    this.$updateScrollBar = function() {
11805
 
        this.scrollBar.setInnerHeight(this.layerConfig.maxHeight);
11806
 
        this.scrollBar.setScrollTop(this.scrollTop);
11807
 
    };
11808
 
 
11809
 
    this.$renderChanges = function(changes, force) {
11810
 
        if (!force && (!changes || !this.session || !this.container.offsetWidth))
11811
 
            return;
11812
 
 
11813
 
        this._signal("beforeRender");
11814
 
        if (changes & this.CHANGE_FULL ||
11815
 
            changes & this.CHANGE_SIZE ||
11816
 
            changes & this.CHANGE_TEXT ||
11817
 
            changes & this.CHANGE_LINES ||
11818
 
            changes & this.CHANGE_SCROLL
11819
 
        )
11820
 
            this.$computeLayerConfig();
11821
 
        if (changes & this.CHANGE_H_SCROLL) {
11822
 
            this.scroller.scrollLeft = this.scrollLeft;
11823
 
            var scrollLeft = this.scroller.scrollLeft;
11824
 
            this.scrollLeft = scrollLeft;
11825
 
            this.session.setScrollLeft(scrollLeft);
11826
 
 
11827
 
            this.scroller.className = this.scrollLeft == 0 ? "ace_scroller" : "ace_scroller ace_scroll-left";
11828
 
        }
11829
 
        if (changes & this.CHANGE_FULL) {
11830
 
            this.$textLayer.checkForSizeChanges();
11831
 
            this.$updateScrollBar();
11832
 
            this.$textLayer.update(this.layerConfig);
11833
 
            if (this.$showGutter)
11834
 
                this.$gutterLayer.update(this.layerConfig);
11835
 
            this.$markerBack.update(this.layerConfig);
11836
 
            this.$markerFront.update(this.layerConfig);
11837
 
            this.$cursorLayer.update(this.layerConfig);
11838
 
            this.$moveTextAreaToCursor();
11839
 
            this.$highlightGutterLine && this.$updateGutterLineHighlight();
11840
 
            this._signal("afterRender");
11841
 
            return;
11842
 
        }
11843
 
        if (changes & this.CHANGE_SCROLL) {
11844
 
            if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES)
11845
 
                this.$textLayer.update(this.layerConfig);
11846
 
            else
11847
 
                this.$textLayer.scrollLines(this.layerConfig);
11848
 
 
11849
 
            if (this.$showGutter)
11850
 
                this.$gutterLayer.update(this.layerConfig);
11851
 
            this.$markerBack.update(this.layerConfig);
11852
 
            this.$markerFront.update(this.layerConfig);
11853
 
            this.$cursorLayer.update(this.layerConfig);
11854
 
            this.$highlightGutterLine && this.$updateGutterLineHighlight();
11855
 
            this.$moveTextAreaToCursor();
11856
 
            this.$updateScrollBar();
11857
 
            this._signal("afterRender");
11858
 
            return;
11859
 
        }
11860
 
 
11861
 
        if (changes & this.CHANGE_TEXT) {
11862
 
            this.$textLayer.update(this.layerConfig);
11863
 
            if (this.$showGutter)
11864
 
                this.$gutterLayer.update(this.layerConfig);
11865
 
        }
11866
 
        else if (changes & this.CHANGE_LINES) {
11867
 
            if (this.$updateLines() || (changes & this.CHANGE_GUTTER) && this.$showGutter)
11868
 
                this.$gutterLayer.update(this.layerConfig);
11869
 
        }
11870
 
        else if (changes & this.CHANGE_TEXT || changes & this.CHANGE_GUTTER) {
11871
 
            if (this.$showGutter)
11872
 
                this.$gutterLayer.update(this.layerConfig);
11873
 
        }
11874
 
 
11875
 
        if (changes & this.CHANGE_CURSOR) {
11876
 
            this.$cursorLayer.update(this.layerConfig);
11877
 
            this.$moveTextAreaToCursor();
11878
 
            this.$highlightGutterLine && this.$updateGutterLineHighlight();
11879
 
        }
11880
 
 
11881
 
        if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT)) {
11882
 
            this.$markerFront.update(this.layerConfig);
11883
 
        }
11884
 
 
11885
 
        if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_BACK)) {
11886
 
            this.$markerBack.update(this.layerConfig);
11887
 
        }
11888
 
 
11889
 
        if (changes & this.CHANGE_SIZE)
11890
 
            this.$updateScrollBar();
11891
 
 
11892
 
        this._signal("afterRender");
11893
 
    };
11894
 
 
11895
 
    this.$computeLayerConfig = function() {
11896
 
        if (!this.$size.scrollerHeight)
11897
 
            return this.onResize(true);
11898
 
 
11899
 
        var session = this.session;
11900
 
 
11901
 
        var offset = this.scrollTop % this.lineHeight;
11902
 
        var minHeight = this.$size.scrollerHeight + this.lineHeight;
11903
 
 
11904
 
        var longestLine = this.$getLongestLine();
11905
 
 
11906
 
        var horizScroll = this.$horizScrollAlwaysVisible || this.$size.scrollerWidth - longestLine < 0;
11907
 
        var horizScrollChanged = this.$horizScroll !== horizScroll;
11908
 
        this.$horizScroll = horizScroll;
11909
 
        if (horizScrollChanged) {
11910
 
            this.scroller.style.overflowX = horizScroll ? "scroll" : "hidden";
11911
 
            if (!horizScroll)
11912
 
                this.session.setScrollLeft(0);
11913
 
        }
11914
 
        var maxHeight = this.session.getScreenLength() * this.lineHeight;
11915
 
        this.session.setScrollTop(Math.max(0, Math.min(this.scrollTop, maxHeight - this.$size.scrollerHeight)));
11916
 
 
11917
 
        var lineCount = Math.ceil(minHeight / this.lineHeight) - 1;
11918
 
        var firstRow = Math.max(0, Math.round((this.scrollTop - offset) / this.lineHeight));
11919
 
        var lastRow = firstRow + lineCount;
11920
 
        var firstRowScreen, firstRowHeight;
11921
 
        var lineHeight = this.lineHeight;
11922
 
        firstRow = session.screenToDocumentRow(firstRow, 0);
11923
 
        var foldLine = session.getFoldLine(firstRow);
11924
 
        if (foldLine) {
11925
 
            firstRow = foldLine.start.row;
11926
 
        }
11927
 
 
11928
 
        firstRowScreen = session.documentToScreenRow(firstRow, 0);
11929
 
        firstRowHeight = session.getRowLength(firstRow) * lineHeight;
11930
 
 
11931
 
        lastRow = Math.min(session.screenToDocumentRow(lastRow, 0), session.getLength() - 1);
11932
 
        minHeight = this.$size.scrollerHeight + session.getRowLength(lastRow) * lineHeight +
11933
 
                                                firstRowHeight;
11934
 
 
11935
 
        offset = this.scrollTop - firstRowScreen * lineHeight;
11936
 
 
11937
 
        this.layerConfig = {
11938
 
            width : longestLine,
11939
 
            padding : this.$padding,
11940
 
            firstRow : firstRow,
11941
 
            firstRowScreen: firstRowScreen,
11942
 
            lastRow : lastRow,
11943
 
            lineHeight : lineHeight,
11944
 
            characterWidth : this.characterWidth,
11945
 
            minHeight : minHeight,
11946
 
            maxHeight : maxHeight,
11947
 
            offset : offset,
11948
 
            height : this.$size.scrollerHeight
11949
 
        };
11950
 
 
11951
 
        this.$gutterLayer.element.style.marginTop = (-offset) + "px";
11952
 
        this.content.style.marginTop = (-offset) + "px";
11953
 
        this.content.style.width = longestLine + 2 * this.$padding + "px";
11954
 
        this.content.style.height = minHeight + "px";
11955
 
        if (horizScrollChanged)
11956
 
            this.onResize(true);
11957
 
    };
11958
 
 
11959
 
    this.$updateLines = function() {
11960
 
        var firstRow = this.$changedLines.firstRow;
11961
 
        var lastRow = this.$changedLines.lastRow;
11962
 
        this.$changedLines = null;
11963
 
 
11964
 
        var layerConfig = this.layerConfig;
11965
 
 
11966
 
        if (firstRow > layerConfig.lastRow + 1) { return; }
11967
 
        if (lastRow < layerConfig.firstRow) { return; }
11968
 
        if (lastRow === Infinity) {
11969
 
            if (this.$showGutter)
11970
 
                this.$gutterLayer.update(layerConfig);
11971
 
            this.$textLayer.update(layerConfig);
11972
 
            return;
11973
 
        }
11974
 
        this.$textLayer.updateLines(layerConfig, firstRow, lastRow);
11975
 
        return true;
11976
 
    };
11977
 
 
11978
 
    this.$getLongestLine = function() {
11979
 
        var charCount = this.session.getScreenWidth();
11980
 
        if (this.$textLayer.showInvisibles)
11981
 
            charCount += 1;
11982
 
 
11983
 
        return Math.max(this.$size.scrollerWidth - 2 * this.$padding, Math.round(charCount * this.characterWidth));
11984
 
    };
11985
 
    this.updateFrontMarkers = function() {
11986
 
        this.$markerFront.setMarkers(this.session.getMarkers(true));
11987
 
        this.$loop.schedule(this.CHANGE_MARKER_FRONT);
11988
 
    };
11989
 
    this.updateBackMarkers = function() {
11990
 
        this.$markerBack.setMarkers(this.session.getMarkers());
11991
 
        this.$loop.schedule(this.CHANGE_MARKER_BACK);
11992
 
    };
11993
 
    this.addGutterDecoration = function(row, className){
11994
 
        this.$gutterLayer.addGutterDecoration(row, className);
11995
 
    };
11996
 
    this.removeGutterDecoration = function(row, className){
11997
 
        this.$gutterLayer.removeGutterDecoration(row, className);
11998
 
    };
11999
 
    this.updateBreakpoints = function(rows) {
12000
 
        this.$loop.schedule(this.CHANGE_GUTTER);
12001
 
    };
12002
 
    this.setAnnotations = function(annotations) {
12003
 
        this.$gutterLayer.setAnnotations(annotations);
12004
 
        this.$loop.schedule(this.CHANGE_GUTTER);
12005
 
    };
12006
 
    this.updateCursor = function() {
12007
 
        this.$loop.schedule(this.CHANGE_CURSOR);
12008
 
    };
12009
 
    this.hideCursor = function() {
12010
 
        this.$cursorLayer.hideCursor();
12011
 
    };
12012
 
    this.showCursor = function() {
12013
 
        this.$cursorLayer.showCursor();
12014
 
    };
12015
 
 
12016
 
    this.scrollSelectionIntoView = function(anchor, lead, offset) {
12017
 
        this.scrollCursorIntoView(anchor, offset);
12018
 
        this.scrollCursorIntoView(lead, offset);
12019
 
    };
12020
 
    this.scrollCursorIntoView = function(cursor, offset) {
12021
 
        if (this.$size.scrollerHeight === 0)
12022
 
            return;
12023
 
 
12024
 
        var pos = this.$cursorLayer.getPixelPosition(cursor);
12025
 
 
12026
 
        var left = pos.left;
12027
 
        var top = pos.top;
12028
 
 
12029
 
        if (this.scrollTop > top) {
12030
 
            if (offset)
12031
 
                top -= offset * this.$size.scrollerHeight;
12032
 
            this.session.setScrollTop(top);
12033
 
        } else if (this.scrollTop + this.$size.scrollerHeight < top + this.lineHeight) {
12034
 
            if (offset)
12035
 
                top += offset * this.$size.scrollerHeight;
12036
 
            this.session.setScrollTop(top + this.lineHeight - this.$size.scrollerHeight);
12037
 
        }
12038
 
 
12039
 
        var scrollLeft = this.scrollLeft;
12040
 
 
12041
 
        if (scrollLeft > left) {
12042
 
            if (left < this.$padding + 2 * this.layerConfig.characterWidth)
12043
 
                left = 0;
12044
 
            this.session.setScrollLeft(left);
12045
 
        } else if (scrollLeft + this.$size.scrollerWidth < left + this.characterWidth) {
12046
 
            this.session.setScrollLeft(Math.round(left + this.characterWidth - this.$size.scrollerWidth));
12047
 
        }
12048
 
    };
12049
 
    this.getScrollTop = function() {
12050
 
        return this.session.getScrollTop();
12051
 
    };
12052
 
    this.getScrollLeft = function() {
12053
 
        return this.session.getScrollLeft();
12054
 
    };
12055
 
    this.getScrollTopRow = function() {
12056
 
        return this.scrollTop / this.lineHeight;
12057
 
    };
12058
 
    this.getScrollBottomRow = function() {
12059
 
        return Math.max(0, Math.floor((this.scrollTop + this.$size.scrollerHeight) / this.lineHeight) - 1);
12060
 
    };
12061
 
    this.scrollToRow = function(row) {
12062
 
        this.session.setScrollTop(row * this.lineHeight);
12063
 
    };
12064
 
 
12065
 
    this.alignCursor = function(cursor, alignment) {
12066
 
        if (typeof cursor == "number")
12067
 
            cursor = {row: cursor, column: 0};
12068
 
 
12069
 
        var pos = this.$cursorLayer.getPixelPosition(cursor);
12070
 
        var h = this.$size.scrollerHeight - this.lineHeight;
12071
 
        var offset = pos.top - h * (alignment || 0);
12072
 
 
12073
 
        this.session.setScrollTop(offset);
12074
 
        return offset;
12075
 
    };
12076
 
 
12077
 
    this.STEPS = 8;
12078
 
    this.$calcSteps = function(fromValue, toValue){
12079
 
        var i = 0;
12080
 
        var l = this.STEPS;
12081
 
        var steps = [];
12082
 
 
12083
 
        var func  = function(t, x_min, dx) {
12084
 
            return dx * (Math.pow(t - 1, 3) + 1) + x_min;
12085
 
        };
12086
 
 
12087
 
        for (i = 0; i < l; ++i)
12088
 
            steps.push(func(i / this.STEPS, fromValue, toValue - fromValue));
12089
 
 
12090
 
        return steps;
12091
 
    };
12092
 
    this.scrollToLine = function(line, center, animate, callback) {
12093
 
        var pos = this.$cursorLayer.getPixelPosition({row: line, column: 0});
12094
 
        var offset = pos.top;
12095
 
        if (center)
12096
 
            offset -= this.$size.scrollerHeight / 2;
12097
 
 
12098
 
        var initialScroll = this.scrollTop;
12099
 
        this.session.setScrollTop(offset);
12100
 
        if (animate !== false)
12101
 
            this.animateScrolling(initialScroll, callback);
12102
 
    };
12103
 
 
12104
 
    this.animateScrolling = function(fromValue, callback) {
12105
 
        var toValue = this.scrollTop;
12106
 
        if (this.$animatedScroll && Math.abs(fromValue - toValue) < 100000) {
12107
 
            var _self = this;
12108
 
            var steps = _self.$calcSteps(fromValue, toValue);
12109
 
            this.$inScrollAnimation = true;
12110
 
 
12111
 
            clearInterval(this.$timer);
12112
 
 
12113
 
            _self.session.setScrollTop(steps.shift());
12114
 
            this.$timer = setInterval(function() {
12115
 
                if (steps.length) {
12116
 
                    _self.session.setScrollTop(steps.shift());
12117
 
                    _self.session.$scrollTop = toValue;
12118
 
                } else if (toValue != null) {
12119
 
                    _self.session.$scrollTop = -1;
12120
 
                    _self.session.setScrollTop(toValue);
12121
 
                    toValue = null;
12122
 
                } else {
12123
 
                    _self.$timer = clearInterval(_self.$timer);
12124
 
                    _self.$inScrollAnimation = false;
12125
 
                    callback && callback();
12126
 
                }
12127
 
            }, 10);
12128
 
        }
12129
 
    };
12130
 
    this.scrollToY = function(scrollTop) {
12131
 
        if (this.scrollTop !== scrollTop) {
12132
 
            this.$loop.schedule(this.CHANGE_SCROLL);
12133
 
            this.scrollTop = scrollTop;
12134
 
        }
12135
 
    };
12136
 
    this.scrollToX = function(scrollLeft) {
12137
 
        if (scrollLeft < 0)
12138
 
            scrollLeft = 0;
12139
 
 
12140
 
        if (this.scrollLeft !== scrollLeft)
12141
 
            this.scrollLeft = scrollLeft;
12142
 
        this.$loop.schedule(this.CHANGE_H_SCROLL);
12143
 
    };
12144
 
    this.scrollBy = function(deltaX, deltaY) {
12145
 
        deltaY && this.session.setScrollTop(this.session.getScrollTop() + deltaY);
12146
 
        deltaX && this.session.setScrollLeft(this.session.getScrollLeft() + deltaX);
12147
 
    };
12148
 
    this.isScrollableBy = function(deltaX, deltaY) {
12149
 
        if (deltaY < 0 && this.session.getScrollTop() >= 1)
12150
 
           return true;
12151
 
        if (deltaY > 0 && this.session.getScrollTop() + this.$size.scrollerHeight - this.layerConfig.maxHeight < -1)
12152
 
           return true;
12153
 
    };
12154
 
 
12155
 
    this.pixelToScreenCoordinates = function(x, y) {
12156
 
        var canvasPos = this.scroller.getBoundingClientRect();
12157
 
 
12158
 
        var offset = (x + this.scrollLeft - canvasPos.left - this.$padding) / this.characterWidth;
12159
 
        var row = Math.floor((y + this.scrollTop - canvasPos.top) / this.lineHeight);
12160
 
        var col = Math.round(offset);
12161
 
 
12162
 
        return {row: row, column: col, side: offset - col > 0 ? 1 : -1};
12163
 
    };
12164
 
 
12165
 
    this.screenToTextCoordinates = function(x, y) {
12166
 
        var canvasPos = this.scroller.getBoundingClientRect();
12167
 
 
12168
 
        var col = Math.round(
12169
 
            (x + this.scrollLeft - canvasPos.left - this.$padding) / this.characterWidth
12170
 
        );
12171
 
        var row = Math.floor(
12172
 
            (y + this.scrollTop - canvasPos.top) / this.lineHeight
12173
 
        );
12174
 
 
12175
 
        return this.session.screenToDocumentPosition(row, Math.max(col, 0));
12176
 
    };
12177
 
    this.textToScreenCoordinates = function(row, column) {
12178
 
        var canvasPos = this.scroller.getBoundingClientRect();
12179
 
        var pos = this.session.documentToScreenPosition(row, column);
12180
 
 
12181
 
        var x = this.$padding + Math.round(pos.column * this.characterWidth);
12182
 
        var y = pos.row * this.lineHeight;
12183
 
 
12184
 
        return {
12185
 
            pageX: canvasPos.left + x - this.scrollLeft,
12186
 
            pageY: canvasPos.top + y - this.scrollTop
12187
 
        };
12188
 
    };
12189
 
    this.visualizeFocus = function() {
12190
 
        dom.addCssClass(this.container, "ace_focus");
12191
 
    };
12192
 
    this.visualizeBlur = function() {
12193
 
        dom.removeCssClass(this.container, "ace_focus");
12194
 
    };
12195
 
    this.showComposition = function(position) {
12196
 
        if (!this.$composition)
12197
 
            this.$composition = {
12198
 
                keepTextAreaAtCursor: this.$keepTextAreaAtCursor,
12199
 
                cssText: this.textarea.style.cssText
12200
 
            };
12201
 
 
12202
 
        this.$keepTextAreaAtCursor = true;
12203
 
        dom.addCssClass(this.textarea, "ace_composition");
12204
 
        this.textarea.style.cssText = "";
12205
 
        this.$moveTextAreaToCursor();
12206
 
    };
12207
 
    this.setCompositionText = function(text) {
12208
 
        this.$moveTextAreaToCursor();
12209
 
    };
12210
 
    this.hideComposition = function() {
12211
 
        if (!this.$composition)
12212
 
            return;
12213
 
 
12214
 
        dom.removeCssClass(this.textarea, "ace_composition");
12215
 
        this.$keepTextAreaAtCursor = this.$composition.keepTextAreaAtCursor;
12216
 
        this.textarea.style.cssText = this.$composition.cssText;
12217
 
        this.$composition = null;
12218
 
    };
12219
 
    this.setTheme = function(theme) {
12220
 
        var _self = this;
12221
 
        this.$themeValue = theme;
12222
 
        _self._dispatchEvent('themeChange',{theme:theme});
12223
 
 
12224
 
        if (!theme || typeof theme == "string") {
12225
 
            var moduleName = theme || "ace/theme/textmate";
12226
 
            config.loadModule(["theme", moduleName], afterLoad);
12227
 
        } else {
12228
 
            afterLoad(theme);
12229
 
        }
12230
 
 
12231
 
        function afterLoad(theme) {
12232
 
            dom.importCssString(
12233
 
                theme.cssText,
12234
 
                theme.cssClass,
12235
 
                _self.container.ownerDocument
12236
 
            );
12237
 
 
12238
 
            if (_self.theme)
12239
 
                dom.removeCssClass(_self.container, _self.theme.cssClass);
12240
 
            _self.$theme = theme.cssClass;
12241
 
 
12242
 
            _self.theme = theme;
12243
 
            dom.addCssClass(_self.container, theme.cssClass);
12244
 
            dom.setCssClass(_self.container, "ace_dark", theme.isDark);
12245
 
 
12246
 
            var padding = theme.padding || 4;
12247
 
            if (_self.$padding && padding != _self.$padding)
12248
 
                _self.setPadding(padding);
12249
 
            if (_self.$size) {
12250
 
                _self.$size.width = 0;
12251
 
                _self.onResize();
12252
 
            }
12253
 
 
12254
 
            _self._dispatchEvent('themeLoaded',{theme:theme});
12255
 
        }
12256
 
    };
12257
 
    this.getTheme = function() {
12258
 
        return this.$themeValue;
12259
 
    };
12260
 
    this.setStyle = function setStyle(style, include) {
12261
 
        dom.setCssClass(this.container, style, include != false);
12262
 
    };
12263
 
    this.unsetStyle = function unsetStyle(style) {
12264
 
        dom.removeCssClass(this.container, style);
12265
 
    };
12266
 
    this.destroy = function() {
12267
 
        this.$textLayer.destroy();
12268
 
        this.$cursorLayer.destroy();
12269
 
    };
12270
 
 
12271
 
}).call(VirtualRenderer.prototype);
12272
 
 
12273
 
 
12274
 
config.defineOptions(VirtualRenderer.prototype, "renderer", {
12275
 
    animatedScroll: {initialValue: false},
12276
 
    showInvisibles: {
12277
 
        set: function(value) {
12278
 
            if (this.$textLayer.setShowInvisibles(value))
12279
 
                this.$loop.schedule(this.CHANGE_TEXT);
12280
 
        },
12281
 
        initialValue: false
12282
 
    },
12283
 
    showPrintMargin: {
12284
 
        set: function() { this.$updatePrintMargin(); },
12285
 
        initialValue: true
12286
 
    },
12287
 
    printMarginColumn: {
12288
 
        set: function() { this.$updatePrintMargin(); },
12289
 
        initialValue: 80
12290
 
    },
12291
 
    showGutter: {
12292
 
        set: function(show){
12293
 
            this.$gutter.style.display = show ? "block" : "none";
12294
 
            this.onGutterResize();
12295
 
        },
12296
 
        initialValue: true
12297
 
    },
12298
 
    fadeFoldWidgets: {
12299
 
        set: function(show) {
12300
 
            dom.setCssClass(this.$gutter, "ace_fade-fold-widgets", show);
12301
 
        },
12302
 
        initialValue: false
12303
 
    },
12304
 
    showFoldWidgets: {
12305
 
        set: function(show) {this.$gutterLayer.setShowFoldWidgets(show)},
12306
 
        initialValue: true
12307
 
    },
12308
 
    displayIndentGuides: {
12309
 
        set: function(show) {
12310
 
            if (this.$textLayer.setDisplayIndentGuides(show))
12311
 
                this.$loop.schedule(this.CHANGE_TEXT);
12312
 
        },
12313
 
        initialValue: true
12314
 
    },
12315
 
    highlightGutterLine: {
12316
 
        set: function(shouldHighlight) {
12317
 
            if (!this.$gutterLineHighlight) {
12318
 
                this.$gutterLineHighlight = dom.createElement("div");
12319
 
                this.$gutterLineHighlight.className = "ace_gutter-active-line";
12320
 
                this.$gutter.appendChild(this.$gutterLineHighlight);
12321
 
                return;
12322
 
            }
12323
 
 
12324
 
            this.$gutterLineHighlight.style.display = shouldHighlight ? "" : "none";
12325
 
            if (this.$cursorLayer.$pixelPos)
12326
 
                this.$updateGutterLineHighlight();
12327
 
        },
12328
 
        initialValue: false,
12329
 
        value: true
12330
 
    }
12331
 
});
12332
 
 
12333
 
exports.VirtualRenderer = VirtualRenderer;
12334
 
});
12335
 
 
12336
 
define('ace/layer/gutter', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/oop', 'ace/lib/lang', 'ace/lib/event_emitter'], function(require, exports, module) {
12337
 
 
12338
 
 
12339
 
var dom = require("../lib/dom");
12340
 
var oop = require("../lib/oop");
12341
 
var lang = require("../lib/lang");
12342
 
var EventEmitter = require("../lib/event_emitter").EventEmitter;
12343
 
 
12344
 
var Gutter = function(parentEl) {
12345
 
    this.element = dom.createElement("div");
12346
 
    this.element.className = "ace_layer ace_gutter-layer";
12347
 
    parentEl.appendChild(this.element);
12348
 
    this.setShowFoldWidgets(this.$showFoldWidgets);
12349
 
    
12350
 
    this.gutterWidth = 0;
12351
 
 
12352
 
    this.$annotations = [];
12353
 
    this.$updateAnnotations = this.$updateAnnotations.bind(this);
12354
 
};
12355
 
 
12356
 
(function() {
12357
 
 
12358
 
    oop.implement(this, EventEmitter);
12359
 
 
12360
 
    this.setSession = function(session) {
12361
 
        if (this.session)
12362
 
            this.session.removeEventListener("change", this.$updateAnnotations);
12363
 
        this.session = session;
12364
 
        session.on("change", this.$updateAnnotations);
12365
 
    };
12366
 
 
12367
 
    this.addGutterDecoration = function(row, className){
12368
 
        if (window.console)
12369
 
            console.warn && console.warn("deprecated use session.addGutterDecoration");
12370
 
        this.session.addGutterDecoration(row, className);
12371
 
    };
12372
 
 
12373
 
    this.removeGutterDecoration = function(row, className){
12374
 
        if (window.console)
12375
 
            console.warn && console.warn("deprecated use session.removeGutterDecoration");
12376
 
        this.session.removeGutterDecoration(row, className);
12377
 
    };
12378
 
 
12379
 
    this.setAnnotations = function(annotations) {
12380
 
        this.$annotations = []
12381
 
        var rowInfo, row;
12382
 
        for (var i = 0; i < annotations.length; i++) {
12383
 
            var annotation = annotations[i];
12384
 
            var row = annotation.row;
12385
 
            var rowInfo = this.$annotations[row];
12386
 
            if (!rowInfo)
12387
 
                rowInfo = this.$annotations[row] = {text: []};
12388
 
           
12389
 
            var annoText = annotation.text;
12390
 
            annoText = annoText ? lang.escapeHTML(annoText) : annotation.html || "";
12391
 
 
12392
 
            if (rowInfo.text.indexOf(annoText) === -1)
12393
 
                rowInfo.text.push(annoText);
12394
 
 
12395
 
            var type = annotation.type;
12396
 
            if (type == "error")
12397
 
                rowInfo.className = " ace_error";
12398
 
            else if (type == "warning" && rowInfo.className != " ace_error")
12399
 
                rowInfo.className = " ace_warning";
12400
 
            else if (type == "info" && (!rowInfo.className))
12401
 
                rowInfo.className = " ace_info";
12402
 
        }
12403
 
    };
12404
 
 
12405
 
    this.$updateAnnotations = function (e) {
12406
 
        if (!this.$annotations.length)
12407
 
            return;
12408
 
        var delta = e.data;
12409
 
        var range = delta.range;
12410
 
        var firstRow = range.start.row;
12411
 
        var len = range.end.row - firstRow;
12412
 
        if (len === 0) {
12413
 
        } else if (delta.action == "removeText" || delta.action == "removeLines") {
12414
 
            this.$annotations.splice(firstRow, len + 1, null);
12415
 
        } else {
12416
 
            var args = Array(len + 1);
12417
 
            args.unshift(firstRow, 1);
12418
 
            this.$annotations.splice.apply(this.$annotations, args);
12419
 
        }
12420
 
    };
12421
 
 
12422
 
    this.update = function(config) {
12423
 
        var emptyAnno = {className: ""};
12424
 
        var html = [];
12425
 
        var i = config.firstRow;
12426
 
        var lastRow = config.lastRow;
12427
 
        var fold = this.session.getNextFoldLine(i);
12428
 
        var foldStart = fold ? fold.start.row : Infinity;
12429
 
        var foldWidgets = this.$showFoldWidgets && this.session.foldWidgets;
12430
 
        var breakpoints = this.session.$breakpoints;
12431
 
        var decorations = this.session.$decorations;
12432
 
        var firstLineNumber = this.session.$firstLineNumber;
12433
 
        var lastLineNumber = 0;
12434
 
 
12435
 
        while (true) {
12436
 
            if(i > foldStart) {
12437
 
                i = fold.end.row + 1;
12438
 
                fold = this.session.getNextFoldLine(i, fold);
12439
 
                foldStart = fold ?fold.start.row :Infinity;
12440
 
            }
12441
 
            if(i > lastRow)
12442
 
                break;
12443
 
 
12444
 
            var annotation = this.$annotations[i] || emptyAnno;
12445
 
            html.push(
12446
 
                "<div class='ace_gutter-cell ",
12447
 
                breakpoints[i] || "", decorations[i] || "", annotation.className,
12448
 
                "' style='height:", this.session.getRowLength(i) * config.lineHeight, "px;'>", 
12449
 
                lastLineNumber = i + firstLineNumber
12450
 
            );
12451
 
 
12452
 
            if (foldWidgets) {
12453
 
                var c = foldWidgets[i];
12454
 
                if (c == null)
12455
 
                    c = foldWidgets[i] = this.session.getFoldWidget(i);
12456
 
                if (c)
12457
 
                    html.push(
12458
 
                        "<span class='ace_fold-widget ace_", c,
12459
 
                        c == "start" && i == foldStart && i < fold.end.row ? " ace_closed" : " ace_open",
12460
 
                        "' style='height:", config.lineHeight, "px",
12461
 
                        "'></span>"
12462
 
                    );
12463
 
            }
12464
 
 
12465
 
            html.push("</div>");
12466
 
 
12467
 
            i++;
12468
 
        }
12469
 
 
12470
 
        this.element = dom.setInnerHtml(this.element, html.join(""));
12471
 
        this.element.style.height = config.minHeight + "px";
12472
 
        
12473
 
        if (this.session.$useWrapMode)
12474
 
            lastLineNumber = this.session.getLength();
12475
 
        
12476
 
        var gutterWidth = ("" + lastLineNumber).length * config.characterWidth;
12477
 
        var padding = this.$padding || this.$computePadding();
12478
 
        gutterWidth += padding.left + padding.right;
12479
 
        if (gutterWidth !== this.gutterWidth) {
12480
 
            this.gutterWidth = gutterWidth;
12481
 
            this.element.style.width = Math.ceil(this.gutterWidth) + "px";
12482
 
            this._emit("changeGutterWidth", gutterWidth);
12483
 
        }
12484
 
    };
12485
 
 
12486
 
    this.$showFoldWidgets = true;
12487
 
    this.setShowFoldWidgets = function(show) {
12488
 
        if (show)
12489
 
            dom.addCssClass(this.element, "ace_folding-enabled");
12490
 
        else
12491
 
            dom.removeCssClass(this.element, "ace_folding-enabled");
12492
 
 
12493
 
        this.$showFoldWidgets = show;
12494
 
        this.$padding = null;
12495
 
    };
12496
 
    
12497
 
    this.getShowFoldWidgets = function() {
12498
 
        return this.$showFoldWidgets;
12499
 
    };
12500
 
 
12501
 
    this.$computePadding = function() {
12502
 
        if (!this.element.firstChild)
12503
 
            return {left: 0, right: 0};
12504
 
        var style = dom.computedStyle(this.element.firstChild);
12505
 
        this.$padding = {}
12506
 
        this.$padding.left = parseInt(style.paddingLeft) + 1;
12507
 
        this.$padding.right = parseInt(style.paddingRight);  
12508
 
        return this.$padding;
12509
 
    };
12510
 
 
12511
 
    this.getRegion = function(point) {
12512
 
        var padding = this.$padding || this.$computePadding();
12513
 
        var rect = this.element.getBoundingClientRect();
12514
 
        if (point.x < padding.left + rect.left)
12515
 
            return "markers";
12516
 
        if (this.$showFoldWidgets && point.x > rect.right - padding.right)
12517
 
            return "foldWidgets";
12518
 
    };
12519
 
 
12520
 
}).call(Gutter.prototype);
12521
 
 
12522
 
exports.Gutter = Gutter;
12523
 
 
12524
 
});
12525
 
 
12526
 
define('ace/layer/marker', ['require', 'exports', 'module' , 'ace/range', 'ace/lib/dom'], function(require, exports, module) {
12527
 
 
12528
 
 
12529
 
var Range = require("../range").Range;
12530
 
var dom = require("../lib/dom");
12531
 
 
12532
 
var Marker = function(parentEl) {
12533
 
    this.element = dom.createElement("div");
12534
 
    this.element.className = "ace_layer ace_marker-layer";
12535
 
    parentEl.appendChild(this.element);
12536
 
};
12537
 
 
12538
 
(function() {
12539
 
 
12540
 
    this.$padding = 0;
12541
 
 
12542
 
    this.setPadding = function(padding) {
12543
 
        this.$padding = padding;
12544
 
    };
12545
 
    this.setSession = function(session) {
12546
 
        this.session = session;
12547
 
    };
12548
 
    
12549
 
    this.setMarkers = function(markers) {
12550
 
        this.markers = markers;
12551
 
    };
12552
 
 
12553
 
    this.update = function(config) {
12554
 
        var config = config || this.config;
12555
 
        if (!config)
12556
 
            return;
12557
 
 
12558
 
        this.config = config;
12559
 
 
12560
 
 
12561
 
        var html = [];
12562
 
        for (var key in this.markers) {
12563
 
            var marker = this.markers[key];
12564
 
 
12565
 
            if (!marker.range) {
12566
 
                marker.update(html, this, this.session, config);
12567
 
                continue;
12568
 
            }
12569
 
 
12570
 
            var range = marker.range.clipRows(config.firstRow, config.lastRow);
12571
 
            if (range.isEmpty()) continue;
12572
 
 
12573
 
            range = range.toScreenRange(this.session);
12574
 
            if (marker.renderer) {
12575
 
                var top = this.$getTop(range.start.row, config);
12576
 
                var left = this.$padding + range.start.column * config.characterWidth;
12577
 
                marker.renderer(html, range, left, top, config);
12578
 
            } else if (marker.type == "fullLine") {
12579
 
                this.drawFullLineMarker(html, range, marker.clazz, config);
12580
 
            } else if (marker.type == "screenLine") {
12581
 
                this.drawScreenLineMarker(html, range, marker.clazz, config);
12582
 
            } else if (range.isMultiLine()) {
12583
 
                if (marker.type == "text")
12584
 
                    this.drawTextMarker(html, range, marker.clazz, config);
12585
 
                else
12586
 
                    this.drawMultiLineMarker(html, range, marker.clazz, config);
12587
 
            } else {
12588
 
                this.drawSingleLineMarker(html, range, marker.clazz + " ace_start", config);
12589
 
            }
12590
 
        }
12591
 
        this.element = dom.setInnerHtml(this.element, html.join(""));
12592
 
    };
12593
 
 
12594
 
    this.$getTop = function(row, layerConfig) {
12595
 
        return (row - layerConfig.firstRowScreen) * layerConfig.lineHeight;
12596
 
    };
12597
 
    this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig) {
12598
 
        var row = range.start.row;
12599
 
 
12600
 
        var lineRange = new Range(
12601
 
            row, range.start.column,
12602
 
            row, this.session.getScreenLastRowColumn(row)
12603
 
        );
12604
 
        this.drawSingleLineMarker(stringBuilder, lineRange, clazz + " ace_start", layerConfig, 1, "text");
12605
 
        row = range.end.row;
12606
 
        lineRange = new Range(row, 0, row, range.end.column);
12607
 
        this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 0, "text");
12608
 
 
12609
 
        for (row = range.start.row + 1; row < range.end.row; row++) {
12610
 
            lineRange.start.row = row;
12611
 
            lineRange.end.row = row;
12612
 
            lineRange.end.column = this.session.getScreenLastRowColumn(row);
12613
 
            this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1, "text");
12614
 
        }
12615
 
    };
12616
 
    this.drawMultiLineMarker = function(stringBuilder, range, clazz, config, type) {
12617
 
        var padding = this.$padding;
12618
 
        var height = config.lineHeight;
12619
 
        var top = this.$getTop(range.start.row, config);
12620
 
        var left = padding + range.start.column * config.characterWidth;
12621
 
 
12622
 
        stringBuilder.push(
12623
 
            "<div class='", clazz, " ace_start' style='",
12624
 
            "height:", height, "px;",
12625
 
            "right:0;",
12626
 
            "top:", top, "px;",
12627
 
            "left:", left, "px;'></div>"
12628
 
        );
12629
 
        top = this.$getTop(range.end.row, config);
12630
 
        var width = range.end.column * config.characterWidth;
12631
 
 
12632
 
        stringBuilder.push(
12633
 
            "<div class='", clazz, "' style='",
12634
 
            "height:", height, "px;",
12635
 
            "width:", width, "px;",
12636
 
            "top:", top, "px;",
12637
 
            "left:", padding, "px;'></div>"
12638
 
        );
12639
 
        height = (range.end.row - range.start.row - 1) * config.lineHeight;
12640
 
        if (height < 0)
12641
 
            return;
12642
 
        top = this.$getTop(range.start.row + 1, config);
12643
 
 
12644
 
        stringBuilder.push(
12645
 
            "<div class='", clazz, "' style='",
12646
 
            "height:", height, "px;",
12647
 
            "right:0;",
12648
 
            "top:", top, "px;",
12649
 
            "left:", padding, "px;'></div>"
12650
 
        );
12651
 
    };
12652
 
    this.drawSingleLineMarker = function(stringBuilder, range, clazz, config, extraLength) {
12653
 
        var height = config.lineHeight;
12654
 
        var width = (range.end.column + (extraLength || 0) - range.start.column) * config.characterWidth;
12655
 
 
12656
 
        var top = this.$getTop(range.start.row, config);
12657
 
        var left = this.$padding + range.start.column * config.characterWidth;
12658
 
 
12659
 
        stringBuilder.push(
12660
 
            "<div class='", clazz, "' style='",
12661
 
            "height:", height, "px;",
12662
 
            "width:", width, "px;",
12663
 
            "top:", top, "px;",
12664
 
            "left:", left,"px;'></div>"
12665
 
        );
12666
 
    };
12667
 
 
12668
 
    this.drawFullLineMarker = function(stringBuilder, range, clazz, config) {
12669
 
        var top = this.$getTop(range.start.row, config);
12670
 
        var height = config.lineHeight;
12671
 
        if (range.start.row != range.end.row)
12672
 
            height += this.$getTop(range.end.row, config) - top;
12673
 
 
12674
 
        stringBuilder.push(
12675
 
            "<div class='", clazz, "' style='",
12676
 
            "height:", height, "px;",
12677
 
            "top:", top, "px;",
12678
 
            "left:0;right:0;'></div>"
12679
 
        );
12680
 
    };
12681
 
    
12682
 
    this.drawScreenLineMarker = function(stringBuilder, range, clazz, config) {
12683
 
        var top = this.$getTop(range.start.row, config);
12684
 
        var height = config.lineHeight;
12685
 
 
12686
 
        stringBuilder.push(
12687
 
            "<div class='", clazz, "' style='",
12688
 
            "height:", height, "px;",
12689
 
            "top:", top, "px;",
12690
 
            "left:0;right:0;'></div>"
12691
 
        );
12692
 
    };
12693
 
 
12694
 
}).call(Marker.prototype);
12695
 
 
12696
 
exports.Marker = Marker;
12697
 
 
12698
 
});
12699
 
 
12700
 
define('ace/layer/text', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/dom', 'ace/lib/lang', 'ace/lib/useragent', 'ace/lib/event_emitter'], function(require, exports, module) {
12701
 
 
12702
 
 
12703
 
var oop = require("../lib/oop");
12704
 
var dom = require("../lib/dom");
12705
 
var lang = require("../lib/lang");
12706
 
var useragent = require("../lib/useragent");
12707
 
var EventEmitter = require("../lib/event_emitter").EventEmitter;
12708
 
 
12709
 
var Text = function(parentEl) {
12710
 
    this.element = dom.createElement("div");
12711
 
    this.element.className = "ace_layer ace_text-layer";
12712
 
    parentEl.appendChild(this.element);
12713
 
 
12714
 
    this.$characterSize = {width: 0, height: 0};
12715
 
    this.checkForSizeChanges();
12716
 
    this.$pollSizeChanges();
12717
 
};
12718
 
 
12719
 
(function() {
12720
 
 
12721
 
    oop.implement(this, EventEmitter);
12722
 
 
12723
 
    this.EOF_CHAR = "\xB6"; //"&para;";
12724
 
    this.EOL_CHAR = "\xAC"; //"&not;";
12725
 
    this.TAB_CHAR = "\u2192"; //"&rarr;" "\u21E5";
12726
 
    this.SPACE_CHAR = "\xB7"; //"&middot;";
12727
 
    this.$padding = 0;
12728
 
 
12729
 
    this.setPadding = function(padding) {
12730
 
        this.$padding = padding;
12731
 
        this.element.style.padding = "0 " + padding + "px";
12732
 
    };
12733
 
 
12734
 
    this.getLineHeight = function() {
12735
 
        return this.$characterSize.height || 1;
12736
 
    };
12737
 
 
12738
 
    this.getCharacterWidth = function() {
12739
 
        return this.$characterSize.width || 1;
12740
 
    };
12741
 
 
12742
 
    this.checkForSizeChanges = function() {
12743
 
        var size = this.$measureSizes();
12744
 
        if (size && (this.$characterSize.width !== size.width || this.$characterSize.height !== size.height)) {
12745
 
            this.$measureNode.style.fontWeight = "bold";
12746
 
            var boldSize = this.$measureSizes();
12747
 
            this.$measureNode.style.fontWeight = "";
12748
 
            this.$characterSize = size;
12749
 
            this.allowBoldFonts = boldSize && boldSize.width === size.width && boldSize.height === size.height;
12750
 
            this._emit("changeCharacterSize", {data: size});
12751
 
        }
12752
 
    };
12753
 
 
12754
 
    this.$pollSizeChanges = function() {
12755
 
        var self = this;
12756
 
        this.$pollSizeChangesTimer = setInterval(function() {
12757
 
            self.checkForSizeChanges();
12758
 
        }, 500);
12759
 
    };
12760
 
 
12761
 
    this.$fontStyles = {
12762
 
        fontFamily : 1,
12763
 
        fontSize : 1,
12764
 
        fontWeight : 1,
12765
 
        fontStyle : 1,
12766
 
        lineHeight : 1
12767
 
    };
12768
 
 
12769
 
    this.$measureSizes = useragent.isIE || useragent.isOldGecko ? function() {
12770
 
        var n = 1000;
12771
 
        if (!this.$measureNode) {
12772
 
            var measureNode = this.$measureNode = dom.createElement("div");
12773
 
            var style = measureNode.style;
12774
 
 
12775
 
            style.width = style.height = "auto";
12776
 
            style.left = style.top = (-n * 40)  + "px";
12777
 
 
12778
 
            style.visibility = "hidden";
12779
 
            style.position = "fixed";
12780
 
            style.overflow = "visible";
12781
 
            style.whiteSpace = "nowrap";
12782
 
            measureNode.innerHTML = lang.stringRepeat("Xy", n);
12783
 
 
12784
 
            if (this.element.ownerDocument.body) {
12785
 
                this.element.ownerDocument.body.appendChild(measureNode);
12786
 
            } else {
12787
 
                var container = this.element.parentNode;
12788
 
                while (!dom.hasCssClass(container, "ace_editor"))
12789
 
                    container = container.parentNode;
12790
 
                container.appendChild(measureNode);
12791
 
            }
12792
 
        }
12793
 
        if (!this.element.offsetWidth)
12794
 
            return null;
12795
 
 
12796
 
        var style = this.$measureNode.style;
12797
 
        var computedStyle = dom.computedStyle(this.element);
12798
 
        for (var prop in this.$fontStyles)
12799
 
            style[prop] = computedStyle[prop];
12800
 
 
12801
 
        var size = {
12802
 
            height: this.$measureNode.offsetHeight,
12803
 
            width: this.$measureNode.offsetWidth / (n * 2)
12804
 
        };
12805
 
        if (size.width == 0 || size.height == 0)
12806
 
            return null;
12807
 
 
12808
 
        return size;
12809
 
    }
12810
 
    : function() {
12811
 
        if (!this.$measureNode) {
12812
 
            var measureNode = this.$measureNode = dom.createElement("div");
12813
 
            var style = measureNode.style;
12814
 
 
12815
 
            style.width = style.height = "auto";
12816
 
            style.left = style.top = -100 + "px";
12817
 
 
12818
 
            style.visibility = "hidden";
12819
 
            style.position = "fixed";
12820
 
            style.overflow = "visible";
12821
 
            style.whiteSpace = "nowrap";
12822
 
 
12823
 
            measureNode.innerHTML = "X";
12824
 
 
12825
 
            var container = this.element.parentNode;
12826
 
            while (container && !dom.hasCssClass(container, "ace_editor"))
12827
 
                container = container.parentNode;
12828
 
 
12829
 
            if (!container)
12830
 
                return this.$measureNode = null;
12831
 
 
12832
 
            container.appendChild(measureNode);
12833
 
        }
12834
 
 
12835
 
        var rect = this.$measureNode.getBoundingClientRect();
12836
 
 
12837
 
        var size = {
12838
 
            height: rect.height,
12839
 
            width: rect.width
12840
 
        };
12841
 
        if (size.width == 0 || size.height == 0)
12842
 
            return null;
12843
 
 
12844
 
        return size;
12845
 
    };
12846
 
 
12847
 
    this.setSession = function(session) {
12848
 
        this.session = session;
12849
 
        this.$computeTabString();
12850
 
    };
12851
 
 
12852
 
    this.showInvisibles = false;
12853
 
    this.setShowInvisibles = function(showInvisibles) {
12854
 
        if (this.showInvisibles == showInvisibles)
12855
 
            return false;
12856
 
 
12857
 
        this.showInvisibles = showInvisibles;
12858
 
        this.$computeTabString();
12859
 
        return true;
12860
 
    };
12861
 
 
12862
 
    this.displayIndentGuides = true;
12863
 
    this.setDisplayIndentGuides = function(display) {
12864
 
        if (this.displayIndentGuides == display)
12865
 
            return false;
12866
 
 
12867
 
        this.displayIndentGuides = display;
12868
 
        this.$computeTabString();
12869
 
        return true;
12870
 
    };
12871
 
 
12872
 
    this.$tabStrings = [];
12873
 
    this.onChangeTabSize =
12874
 
    this.$computeTabString = function() {
12875
 
        var tabSize = this.session.getTabSize();
12876
 
        this.tabSize = tabSize;
12877
 
        var tabStr = this.$tabStrings = [0];
12878
 
        for (var i = 1; i < tabSize + 1; i++) {
12879
 
            if (this.showInvisibles) {
12880
 
                tabStr.push("<span class='ace_invisible'>"
12881
 
                    + this.TAB_CHAR
12882
 
                    + lang.stringRepeat("\xa0", i - 1)
12883
 
                    + "</span>");
12884
 
            } else {
12885
 
                tabStr.push(lang.stringRepeat("\xa0", i));
12886
 
            }
12887
 
        }
12888
 
        if (this.displayIndentGuides) {
12889
 
            this.$indentGuideRe =  /\s\S| \t|\t |\s$/;
12890
 
            var className = "ace_indent-guide";
12891
 
            if (this.showInvisibles) {
12892
 
                className += " ace_invisible";
12893
 
                var spaceContent = lang.stringRepeat(this.SPACE_CHAR, this.tabSize);
12894
 
                var tabContent = this.TAB_CHAR + lang.stringRepeat("\xa0", this.tabSize - 1);
12895
 
            } else{
12896
 
                var spaceContent = lang.stringRepeat("\xa0", this.tabSize);
12897
 
                var tabContent = spaceContent;
12898
 
            }
12899
 
 
12900
 
            this.$tabStrings[" "] = "<span class='" + className + "'>" + spaceContent + "</span>";
12901
 
            this.$tabStrings["\t"] = "<span class='" + className + "'>" + tabContent + "</span>";
12902
 
        }
12903
 
    };
12904
 
 
12905
 
    this.updateLines = function(config, firstRow, lastRow) {
12906
 
        if (this.config.lastRow != config.lastRow ||
12907
 
            this.config.firstRow != config.firstRow) {
12908
 
            this.scrollLines(config);
12909
 
        }
12910
 
        this.config = config;
12911
 
 
12912
 
        var first = Math.max(firstRow, config.firstRow);
12913
 
        var last = Math.min(lastRow, config.lastRow);
12914
 
 
12915
 
        var lineElements = this.element.childNodes;
12916
 
        var lineElementsIdx = 0;
12917
 
 
12918
 
        for (var row = config.firstRow; row < first; row++) {
12919
 
            var foldLine = this.session.getFoldLine(row);
12920
 
            if (foldLine) {
12921
 
                if (foldLine.containsRow(first)) {
12922
 
                    first = foldLine.start.row;
12923
 
                    break;
12924
 
                } else {
12925
 
                    row = foldLine.end.row;
12926
 
                }
12927
 
            }
12928
 
            lineElementsIdx ++;
12929
 
        }
12930
 
 
12931
 
        var row = first;
12932
 
        var foldLine = this.session.getNextFoldLine(row);
12933
 
        var foldStart = foldLine ? foldLine.start.row : Infinity;
12934
 
 
12935
 
        while (true) {
12936
 
            if (row > foldStart) {
12937
 
                row = foldLine.end.row+1;
12938
 
                foldLine = this.session.getNextFoldLine(row, foldLine);
12939
 
                foldStart = foldLine ? foldLine.start.row :Infinity;
12940
 
            }
12941
 
            if (row > last)
12942
 
                break;
12943
 
 
12944
 
            var lineElement = lineElements[lineElementsIdx++];
12945
 
            if (lineElement) {
12946
 
                var html = [];
12947
 
                this.$renderLine(
12948
 
                    html, row, !this.$useLineGroups(), row == foldStart ? foldLine : false
12949
 
                );
12950
 
                dom.setInnerHtml(lineElement, html.join(""));
12951
 
            }
12952
 
            row++;
12953
 
        }
12954
 
    };
12955
 
 
12956
 
    this.scrollLines = function(config) {
12957
 
        var oldConfig = this.config;
12958
 
        this.config = config;
12959
 
 
12960
 
        if (!oldConfig || oldConfig.lastRow < config.firstRow)
12961
 
            return this.update(config);
12962
 
 
12963
 
        if (config.lastRow < oldConfig.firstRow)
12964
 
            return this.update(config);
12965
 
 
12966
 
        var el = this.element;
12967
 
        if (oldConfig.firstRow < config.firstRow)
12968
 
            for (var row=this.session.getFoldedRowCount(oldConfig.firstRow, config.firstRow - 1); row>0; row--)
12969
 
                el.removeChild(el.firstChild);
12970
 
 
12971
 
        if (oldConfig.lastRow > config.lastRow)
12972
 
            for (var row=this.session.getFoldedRowCount(config.lastRow + 1, oldConfig.lastRow); row>0; row--)
12973
 
                el.removeChild(el.lastChild);
12974
 
 
12975
 
        if (config.firstRow < oldConfig.firstRow) {
12976
 
            var fragment = this.$renderLinesFragment(config, config.firstRow, oldConfig.firstRow - 1);
12977
 
            if (el.firstChild)
12978
 
                el.insertBefore(fragment, el.firstChild);
12979
 
            else
12980
 
                el.appendChild(fragment);
12981
 
        }
12982
 
 
12983
 
        if (config.lastRow > oldConfig.lastRow) {
12984
 
            var fragment = this.$renderLinesFragment(config, oldConfig.lastRow + 1, config.lastRow);
12985
 
            el.appendChild(fragment);
12986
 
        }
12987
 
    };
12988
 
 
12989
 
    this.$renderLinesFragment = function(config, firstRow, lastRow) {
12990
 
        var fragment = this.element.ownerDocument.createDocumentFragment();
12991
 
        var row = firstRow;
12992
 
        var foldLine = this.session.getNextFoldLine(row);
12993
 
        var foldStart = foldLine ? foldLine.start.row : Infinity;
12994
 
 
12995
 
        while (true) {
12996
 
            if (row > foldStart) {
12997
 
                row = foldLine.end.row+1;
12998
 
                foldLine = this.session.getNextFoldLine(row, foldLine);
12999
 
                foldStart = foldLine ? foldLine.start.row : Infinity;
13000
 
            }
13001
 
            if (row > lastRow)
13002
 
                break;
13003
 
 
13004
 
            var container = dom.createElement("div");
13005
 
 
13006
 
            var html = [];
13007
 
            this.$renderLine(html, row, false, row == foldStart ? foldLine : false);
13008
 
            container.innerHTML = html.join("");
13009
 
            if (this.$useLineGroups()) {
13010
 
                container.className = 'ace_line_group';
13011
 
                fragment.appendChild(container);
13012
 
            } else {
13013
 
                var lines = container.childNodes
13014
 
                while(lines.length)
13015
 
                    fragment.appendChild(lines[0]);
13016
 
            }
13017
 
 
13018
 
            row++;
13019
 
        }
13020
 
        return fragment;
13021
 
    };
13022
 
 
13023
 
    this.update = function(config) {
13024
 
        this.config = config;
13025
 
 
13026
 
        var html = [];
13027
 
        var firstRow = config.firstRow, lastRow = config.lastRow;
13028
 
 
13029
 
        var row = firstRow;
13030
 
        var foldLine = this.session.getNextFoldLine(row);
13031
 
        var foldStart = foldLine ? foldLine.start.row : Infinity;
13032
 
 
13033
 
        while (true) {
13034
 
            if (row > foldStart) {
13035
 
                row = foldLine.end.row+1;
13036
 
                foldLine = this.session.getNextFoldLine(row, foldLine);
13037
 
                foldStart = foldLine ? foldLine.start.row :Infinity;
13038
 
            }
13039
 
            if (row > lastRow)
13040
 
                break;
13041
 
 
13042
 
            if (this.$useLineGroups())
13043
 
                html.push("<div class='ace_line_group'>")
13044
 
 
13045
 
            this.$renderLine(html, row, false, row == foldStart ? foldLine : false);
13046
 
 
13047
 
            if (this.$useLineGroups())
13048
 
                html.push("</div>"); // end the line group
13049
 
 
13050
 
            row++;
13051
 
        }
13052
 
        this.element = dom.setInnerHtml(this.element, html.join(""));
13053
 
    };
13054
 
 
13055
 
    this.$textToken = {
13056
 
        "text": true,
13057
 
        "rparen": true,
13058
 
        "lparen": true
13059
 
    };
13060
 
 
13061
 
    this.$renderToken = function(stringBuilder, screenColumn, token, value) {
13062
 
        var self = this;
13063
 
        var replaceReg = /\t|&|<|( +)|([\x00-\x1f\x80-\xa0\u1680\u180E\u2000-\u200f\u2028\u2029\u202F\u205F\u3000\uFEFF])|[\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329-\u232A\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3000-\u303E\u3041-\u3096\u3099-\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u31BA\u31C0-\u31E3\u31F0-\u321E\u3220-\u3247\u3250-\u32FE\u3300-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6]/g;
13064
 
        var replaceFunc = function(c, a, b, tabIdx, idx4) {
13065
 
            if (a) {
13066
 
                return self.showInvisibles ?
13067
 
                    "<span class='ace_invisible'>" + lang.stringRepeat(self.SPACE_CHAR, c.length) + "</span>" :
13068
 
                    lang.stringRepeat("\xa0", c.length);
13069
 
            } else if (c == "&") {
13070
 
                return "&#38;";
13071
 
            } else if (c == "<") {
13072
 
                return "&#60;";
13073
 
            } else if (c == "\t") {
13074
 
                var tabSize = self.session.getScreenTabSize(screenColumn + tabIdx);
13075
 
                screenColumn += tabSize - 1;
13076
 
                return self.$tabStrings[tabSize];
13077
 
            } else if (c == "\u3000") {
13078
 
                var classToUse = self.showInvisibles ? "ace_cjk ace_invisible" : "ace_cjk";
13079
 
                var space = self.showInvisibles ? self.SPACE_CHAR : "";
13080
 
                screenColumn += 1;
13081
 
                return "<span class='" + classToUse + "' style='width:" +
13082
 
                    (self.config.characterWidth * 2) +
13083
 
                    "px'>" + space + "</span>";
13084
 
            } else if (b) {
13085
 
                return "<span class='ace_invisible ace_invalid'>" + self.SPACE_CHAR + "</span>";
13086
 
            } else {
13087
 
                screenColumn += 1;
13088
 
                return "<span class='ace_cjk' style='width:" +
13089
 
                    (self.config.characterWidth * 2) +
13090
 
                    "px'>" + c + "</span>";
13091
 
            }
13092
 
        };
13093
 
 
13094
 
        var output = value.replace(replaceReg, replaceFunc);
13095
 
 
13096
 
        if (!this.$textToken[token.type]) {
13097
 
            var classes = "ace_" + token.type.replace(/\./g, " ace_");
13098
 
            var style = "";
13099
 
            if (token.type == "fold")
13100
 
                style = " style='width:" + (token.value.length * this.config.characterWidth) + "px;' ";
13101
 
            stringBuilder.push("<span class='", classes, "'", style, ">", output, "</span>");
13102
 
        }
13103
 
        else {
13104
 
            stringBuilder.push(output);
13105
 
        }
13106
 
        return screenColumn + value.length;
13107
 
    };
13108
 
 
13109
 
    this.renderIndentGuide = function(stringBuilder, value) {
13110
 
        var cols = value.search(this.$indentGuideRe);
13111
 
        if (cols <= 0)
13112
 
            return value;
13113
 
        if (value[0] == " ") {
13114
 
            cols -= cols % this.tabSize;
13115
 
            stringBuilder.push(lang.stringRepeat(this.$tabStrings[" "], cols/this.tabSize));
13116
 
            return value.substr(cols);
13117
 
        } else if (value[0] == "\t") {
13118
 
            stringBuilder.push(lang.stringRepeat(this.$tabStrings["\t"], cols));
13119
 
            return value.substr(cols);
13120
 
        }
13121
 
        return value;
13122
 
    };
13123
 
 
13124
 
    this.$renderWrappedLine = function(stringBuilder, tokens, splits, onlyContents) {
13125
 
        var chars = 0;
13126
 
        var split = 0;
13127
 
        var splitChars = splits[0];
13128
 
        var screenColumn = 0;
13129
 
 
13130
 
        for (var i = 0; i < tokens.length; i++) {
13131
 
            var token = tokens[i];
13132
 
            var value = token.value;
13133
 
            if (i == 0 && this.displayIndentGuides) {
13134
 
                chars = value.length;
13135
 
                value = this.renderIndentGuide(stringBuilder, value);
13136
 
                if (!value)
13137
 
                    continue;
13138
 
                chars -= value.length;
13139
 
            }
13140
 
 
13141
 
            if (chars + value.length < splitChars) {
13142
 
                screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
13143
 
                chars += value.length;
13144
 
            } else {
13145
 
                while (chars + value.length >= splitChars) {
13146
 
                    screenColumn = this.$renderToken(
13147
 
                        stringBuilder, screenColumn,
13148
 
                        token, value.substring(0, splitChars - chars)
13149
 
                    );
13150
 
                    value = value.substring(splitChars - chars);
13151
 
                    chars = splitChars;
13152
 
 
13153
 
                    if (!onlyContents) {
13154
 
                        stringBuilder.push("</div>",
13155
 
                            "<div class='ace_line' style='height:",
13156
 
                            this.config.lineHeight, "px'>"
13157
 
                        );
13158
 
                    }
13159
 
 
13160
 
                    split ++;
13161
 
                    screenColumn = 0;
13162
 
                    splitChars = splits[split] || Number.MAX_VALUE;
13163
 
                }
13164
 
                if (value.length != 0) {
13165
 
                    chars += value.length;
13166
 
                    screenColumn = this.$renderToken(
13167
 
                        stringBuilder, screenColumn, token, value
13168
 
                    );
13169
 
                }
13170
 
            }
13171
 
        }
13172
 
    };
13173
 
 
13174
 
    this.$renderSimpleLine = function(stringBuilder, tokens) {
13175
 
        var screenColumn = 0;
13176
 
        var token = tokens[0];
13177
 
        var value = token.value;
13178
 
        if (this.displayIndentGuides)
13179
 
            value = this.renderIndentGuide(stringBuilder, value);
13180
 
        if (value)
13181
 
            screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
13182
 
        for (var i = 1; i < tokens.length; i++) {
13183
 
            token = tokens[i];
13184
 
            value = token.value;
13185
 
            screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
13186
 
        }
13187
 
    };
13188
 
    this.$renderLine = function(stringBuilder, row, onlyContents, foldLine) {
13189
 
        if (!foldLine && foldLine != false)
13190
 
            foldLine = this.session.getFoldLine(row);
13191
 
 
13192
 
        if (foldLine)
13193
 
            var tokens = this.$getFoldLineTokens(row, foldLine);
13194
 
        else
13195
 
            var tokens = this.session.getTokens(row);
13196
 
 
13197
 
 
13198
 
        if (!onlyContents) {
13199
 
            stringBuilder.push(
13200
 
                "<div class='ace_line' style='height:", this.config.lineHeight, "px'>"
13201
 
            );
13202
 
        }
13203
 
 
13204
 
        if (tokens.length) {
13205
 
            var splits = this.session.getRowSplitData(row);
13206
 
            if (splits && splits.length)
13207
 
                this.$renderWrappedLine(stringBuilder, tokens, splits, onlyContents);
13208
 
            else
13209
 
                this.$renderSimpleLine(stringBuilder, tokens);
13210
 
        }
13211
 
 
13212
 
        if (this.showInvisibles) {
13213
 
            if (foldLine)
13214
 
                row = foldLine.end.row
13215
 
 
13216
 
            stringBuilder.push(
13217
 
                "<span class='ace_invisible'>",
13218
 
                row == this.session.getLength() - 1 ? this.EOF_CHAR : this.EOL_CHAR,
13219
 
                "</span>"
13220
 
            );
13221
 
        }
13222
 
        if (!onlyContents)
13223
 
            stringBuilder.push("</div>");
13224
 
    };
13225
 
 
13226
 
    this.$getFoldLineTokens = function(row, foldLine) {
13227
 
        var session = this.session;
13228
 
        var renderTokens = [];
13229
 
 
13230
 
        function addTokens(tokens, from, to) {
13231
 
            var idx = 0, col = 0;
13232
 
            while ((col + tokens[idx].value.length) < from) {
13233
 
                col += tokens[idx].value.length;
13234
 
                idx++;
13235
 
 
13236
 
                if (idx == tokens.length)
13237
 
                    return;
13238
 
            }
13239
 
            if (col != from) {
13240
 
                var value = tokens[idx].value.substring(from - col);
13241
 
                if (value.length > (to - from))
13242
 
                    value = value.substring(0, to - from);
13243
 
 
13244
 
                renderTokens.push({
13245
 
                    type: tokens[idx].type,
13246
 
                    value: value
13247
 
                });
13248
 
 
13249
 
                col = from + value.length;
13250
 
                idx += 1;
13251
 
            }
13252
 
 
13253
 
            while (col < to && idx < tokens.length) {
13254
 
                var value = tokens[idx].value;
13255
 
                if (value.length + col > to) {
13256
 
                    renderTokens.push({
13257
 
                        type: tokens[idx].type,
13258
 
                        value: value.substring(0, to - col)
13259
 
                    });
13260
 
                } else
13261
 
                    renderTokens.push(tokens[idx]);
13262
 
                col += value.length;
13263
 
                idx += 1;
13264
 
            }
13265
 
        }
13266
 
 
13267
 
        var tokens = session.getTokens(row);
13268
 
        foldLine.walk(function(placeholder, row, column, lastColumn, isNewRow) {
13269
 
            if (placeholder != null) {
13270
 
                renderTokens.push({
13271
 
                    type: "fold",
13272
 
                    value: placeholder
13273
 
                });
13274
 
            } else {
13275
 
                if (isNewRow)
13276
 
                    tokens = session.getTokens(row);
13277
 
 
13278
 
                if (tokens.length)
13279
 
                    addTokens(tokens, lastColumn, column);
13280
 
            }
13281
 
        }, foldLine.end.row, this.session.getLine(foldLine.end.row).length);
13282
 
 
13283
 
        return renderTokens;
13284
 
    };
13285
 
 
13286
 
    this.$useLineGroups = function() {
13287
 
        return this.session.getUseWrapMode();
13288
 
    };
13289
 
 
13290
 
    this.destroy = function() {
13291
 
        clearInterval(this.$pollSizeChangesTimer);
13292
 
        if (this.$measureNode)
13293
 
            this.$measureNode.parentNode.removeChild(this.$measureNode);
13294
 
        delete this.$measureNode;
13295
 
    };
13296
 
 
13297
 
}).call(Text.prototype);
13298
 
 
13299
 
exports.Text = Text;
13300
 
 
13301
 
});
13302
 
 
13303
 
define('ace/layer/cursor', ['require', 'exports', 'module' , 'ace/lib/dom'], function(require, exports, module) {
13304
 
 
13305
 
 
13306
 
var dom = require("../lib/dom");
13307
 
 
13308
 
var Cursor = function(parentEl) {
13309
 
    this.element = dom.createElement("div");
13310
 
    this.element.className = "ace_layer ace_cursor-layer";
13311
 
    parentEl.appendChild(this.element);
13312
 
 
13313
 
    this.isVisible = false;
13314
 
    this.isBlinking = true;
13315
 
    this.blinkInterval = 1000;
13316
 
    this.smoothBlinking = false;
13317
 
 
13318
 
    this.cursors = [];
13319
 
    this.cursor = this.addCursor();
13320
 
    dom.addCssClass(this.element, "ace_hidden-cursors");
13321
 
};
13322
 
 
13323
 
(function() {
13324
 
 
13325
 
    this.$padding = 0;
13326
 
    this.setPadding = function(padding) {
13327
 
        this.$padding = padding;
13328
 
    };
13329
 
 
13330
 
    this.setSession = function(session) {
13331
 
        this.session = session;
13332
 
    };
13333
 
 
13334
 
    this.setBlinking = function(blinking) {
13335
 
        if (blinking != this.isBlinking){
13336
 
            this.isBlinking = blinking;
13337
 
            this.restartTimer();
13338
 
        }
13339
 
    };
13340
 
 
13341
 
    this.setBlinkInterval = function(blinkInterval) {
13342
 
        if (blinkInterval != this.blinkInterval){
13343
 
            this.blinkInterval = blinkInterval;
13344
 
            this.restartTimer();
13345
 
        }
13346
 
    };
13347
 
 
13348
 
    this.setSmoothBlinking = function(smoothBlinking) {
13349
 
        if (smoothBlinking != this.smoothBlinking) {
13350
 
            this.smoothBlinking = smoothBlinking;
13351
 
            if (smoothBlinking)
13352
 
                dom.addCssClass(this.element, "ace_smooth-blinking");
13353
 
            else
13354
 
                dom.removeCssClass(this.element, "ace_smooth-blinking");
13355
 
            this.restartTimer();
13356
 
        }
13357
 
    };
13358
 
 
13359
 
    this.addCursor = function() {
13360
 
        var el = dom.createElement("div");
13361
 
        el.className = "ace_cursor";
13362
 
        this.element.appendChild(el);
13363
 
        this.cursors.push(el);
13364
 
        return el;
13365
 
    };
13366
 
 
13367
 
    this.removeCursor = function() {
13368
 
        if (this.cursors.length > 1) {
13369
 
            var el = this.cursors.pop();
13370
 
            el.parentNode.removeChild(el);
13371
 
            return el;
13372
 
        }
13373
 
    };
13374
 
 
13375
 
    this.hideCursor = function() {
13376
 
        this.isVisible = false;
13377
 
        dom.addCssClass(this.element, "ace_hidden-cursors");
13378
 
        this.restartTimer();
13379
 
    };
13380
 
 
13381
 
    this.showCursor = function() {
13382
 
        this.isVisible = true;
13383
 
        dom.removeCssClass(this.element, "ace_hidden-cursors");
13384
 
        this.restartTimer();
13385
 
    };
13386
 
 
13387
 
    this.restartTimer = function() {
13388
 
        clearInterval(this.intervalId);
13389
 
        clearTimeout(this.timeoutId);
13390
 
        if (this.smoothBlinking)
13391
 
            dom.removeCssClass(this.element, "ace_smooth-blinking");
13392
 
        for (var i = this.cursors.length; i--; )
13393
 
            this.cursors[i].style.opacity = "";
13394
 
 
13395
 
        if (!this.isBlinking || !this.blinkInterval || !this.isVisible)
13396
 
            return;
13397
 
 
13398
 
        if (this.smoothBlinking)
13399
 
            setTimeout(function(){
13400
 
                dom.addCssClass(this.element, "ace_smooth-blinking");
13401
 
            }.bind(this));
13402
 
 
13403
 
        var blink = function(){
13404
 
            this.timeoutId = setTimeout(function() {
13405
 
                for (var i = this.cursors.length; i--; ) {
13406
 
                    this.cursors[i].style.opacity = 0;
13407
 
                }
13408
 
            }.bind(this), 0.6 * this.blinkInterval);
13409
 
        }.bind(this);
13410
 
 
13411
 
        this.intervalId = setInterval(function() {
13412
 
            for (var i = this.cursors.length; i--; ) {
13413
 
                this.cursors[i].style.opacity = "";
13414
 
            }
13415
 
            blink();
13416
 
        }.bind(this), this.blinkInterval);
13417
 
 
13418
 
        blink();
13419
 
    };
13420
 
 
13421
 
    this.getPixelPosition = function(position, onScreen) {
13422
 
        if (!this.config || !this.session)
13423
 
            return {left : 0, top : 0};
13424
 
 
13425
 
        if (!position)
13426
 
            position = this.session.selection.getCursor();
13427
 
        var pos = this.session.documentToScreenPosition(position);
13428
 
        var cursorLeft = this.$padding + pos.column * this.config.characterWidth;
13429
 
        var cursorTop = (pos.row - (onScreen ? this.config.firstRowScreen : 0)) *
13430
 
            this.config.lineHeight;
13431
 
 
13432
 
        return {left : cursorLeft, top : cursorTop};
13433
 
    };
13434
 
 
13435
 
    this.update = function(config) {
13436
 
        this.config = config;
13437
 
 
13438
 
        var selections = this.session.$selectionMarkers;
13439
 
        var i = 0, cursorIndex = 0;
13440
 
 
13441
 
        if (selections === undefined || selections.length === 0){
13442
 
            selections = [{cursor: null}];
13443
 
        }
13444
 
 
13445
 
        for (var i = 0, n = selections.length; i < n; i++) {
13446
 
            var pixelPos = this.getPixelPosition(selections[i].cursor, true);
13447
 
            if ((pixelPos.top > config.height + config.offset ||
13448
 
                 pixelPos.top < -config.offset) && i > 1) {
13449
 
                continue;
13450
 
            }
13451
 
 
13452
 
            var style = (this.cursors[cursorIndex++] || this.addCursor()).style;
13453
 
 
13454
 
            style.left = pixelPos.left + "px";
13455
 
            style.top = pixelPos.top + "px";
13456
 
            style.width = config.characterWidth + "px";
13457
 
            style.height = config.lineHeight + "px";
13458
 
        }
13459
 
        while (this.cursors.length > cursorIndex)
13460
 
            this.removeCursor();
13461
 
 
13462
 
        var overwrite = this.session.getOverwrite();
13463
 
        this.$setOverwrite(overwrite);
13464
 
        this.$pixelPos = pixelPos;
13465
 
        this.restartTimer();
13466
 
    };
13467
 
 
13468
 
    this.$setOverwrite = function(overwrite) {
13469
 
        if (overwrite != this.overwrite) {
13470
 
            this.overwrite = overwrite;
13471
 
            if (overwrite)
13472
 
                dom.addCssClass(this.element, "ace_overwrite-cursors");
13473
 
            else
13474
 
                dom.removeCssClass(this.element, "ace_overwrite-cursors");
13475
 
        }
13476
 
    };
13477
 
 
13478
 
    this.destroy = function() {
13479
 
        clearInterval(this.intervalId);
13480
 
        clearTimeout(this.timeoutId);
13481
 
    };
13482
 
 
13483
 
}).call(Cursor.prototype);
13484
 
 
13485
 
exports.Cursor = Cursor;
13486
 
 
13487
 
});
13488
 
 
13489
 
define('ace/scrollbar', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/dom', 'ace/lib/event', 'ace/lib/event_emitter'], function(require, exports, module) {
13490
 
 
13491
 
 
13492
 
var oop = require("./lib/oop");
13493
 
var dom = require("./lib/dom");
13494
 
var event = require("./lib/event");
13495
 
var EventEmitter = require("./lib/event_emitter").EventEmitter;
13496
 
var ScrollBar = function(parent) {
13497
 
    this.element = dom.createElement("div");
13498
 
    this.element.className = "ace_scrollbar";
13499
 
 
13500
 
    this.inner = dom.createElement("div");
13501
 
    this.inner.className = "ace_scrollbar-inner";
13502
 
    this.element.appendChild(this.inner);
13503
 
 
13504
 
    parent.appendChild(this.element);
13505
 
    this.width = dom.scrollbarWidth(parent.ownerDocument);
13506
 
    this.element.style.width = (this.width || 15) + 5 + "px";
13507
 
 
13508
 
    event.addListener(this.element, "scroll", this.onScroll.bind(this));
13509
 
};
13510
 
 
13511
 
(function() {
13512
 
    oop.implement(this, EventEmitter);
13513
 
    this.onScroll = function() {
13514
 
        if (!this.skipEvent) {
13515
 
            this.scrollTop = this.element.scrollTop;
13516
 
            this._emit("scroll", {data: this.scrollTop});
13517
 
        }
13518
 
        this.skipEvent = false;
13519
 
    };
13520
 
    this.getWidth = function() {
13521
 
        return this.width;
13522
 
    };
13523
 
    this.setHeight = function(height) {
13524
 
        this.element.style.height = height + "px";
13525
 
    };
13526
 
    this.setInnerHeight = function(height) {
13527
 
        this.inner.style.height = height + "px";
13528
 
    };
13529
 
    this.setScrollTop = function(scrollTop) {
13530
 
        if (this.scrollTop != scrollTop) {
13531
 
            this.skipEvent = true;
13532
 
            this.scrollTop = this.element.scrollTop = scrollTop;
13533
 
        }
13534
 
    };
13535
 
 
13536
 
}).call(ScrollBar.prototype);
13537
 
 
13538
 
exports.ScrollBar = ScrollBar;
13539
 
});
13540
 
 
13541
 
define('ace/renderloop', ['require', 'exports', 'module' , 'ace/lib/event'], function(require, exports, module) {
13542
 
 
13543
 
 
13544
 
var event = require("./lib/event");
13545
 
 
13546
 
 
13547
 
var RenderLoop = function(onRender, win) {
13548
 
    this.onRender = onRender;
13549
 
    this.pending = false;
13550
 
    this.changes = 0;
13551
 
    this.window = win || window;
13552
 
};
13553
 
 
13554
 
(function() {
13555
 
 
13556
 
 
13557
 
    this.schedule = function(change) {
13558
 
        this.changes = this.changes | change;
13559
 
        if (!this.pending) {
13560
 
            this.pending = true;
13561
 
            var _self = this;
13562
 
            event.nextFrame(function() {
13563
 
                _self.pending = false;
13564
 
                var changes;
13565
 
                while (changes = _self.changes) {
13566
 
                    _self.changes = 0;
13567
 
                    _self.onRender(changes);
13568
 
                }
13569
 
            }, this.window);
13570
 
        }
13571
 
    };
13572
 
 
13573
 
}).call(RenderLoop.prototype);
13574
 
 
13575
 
exports.RenderLoop = RenderLoop;
13576
 
});
13577
 
 
13578
 
define('ace/multi_select', ['require', 'exports', 'module' , 'ace/range_list', 'ace/range', 'ace/selection', 'ace/mouse/multi_select_handler', 'ace/lib/event', 'ace/lib/lang', 'ace/commands/multi_select_commands', 'ace/search', 'ace/edit_session', 'ace/editor'], function(require, exports, module) {
13579
 
 
13580
 
var RangeList = require("./range_list").RangeList;
13581
 
var Range = require("./range").Range;
13582
 
var Selection = require("./selection").Selection;
13583
 
var onMouseDown = require("./mouse/multi_select_handler").onMouseDown;
13584
 
var event = require("./lib/event");
13585
 
var lang = require("./lib/lang");
13586
 
var commands = require("./commands/multi_select_commands");
13587
 
exports.commands = commands.defaultCommands.concat(commands.multiSelectCommands);
13588
 
var Search = require("./search").Search;
13589
 
var search = new Search();
13590
 
 
13591
 
function find(session, needle, dir) {
13592
 
    search.$options.wrap = true;
13593
 
    search.$options.needle = needle;
13594
 
    search.$options.backwards = dir == -1;
13595
 
    return search.find(session);
13596
 
}
13597
 
var EditSession = require("./edit_session").EditSession;
13598
 
(function() {
13599
 
    this.getSelectionMarkers = function() {
13600
 
        return this.$selectionMarkers;
13601
 
    };
13602
 
}).call(EditSession.prototype);
13603
 
(function() {
13604
 
    this.ranges = null;
13605
 
    this.rangeList = null;
13606
 
    this.addRange = function(range, $blockChangeEvents) {
13607
 
        if (!range)
13608
 
            return;
13609
 
 
13610
 
        if (!this.inMultiSelectMode && this.rangeCount == 0) {
13611
 
            var oldRange = this.toOrientedRange();
13612
 
            this.rangeList.add(oldRange);
13613
 
            this.rangeList.add(range);
13614
 
            if (this.rangeList.ranges.length != 2) {
13615
 
                this.rangeList.removeAll();
13616
 
                return $blockChangeEvents || this.fromOrientedRange(range);
13617
 
            }
13618
 
            this.rangeList.removeAll();
13619
 
            this.rangeList.add(oldRange);
13620
 
            this.$onAddRange(oldRange);
13621
 
        }
13622
 
 
13623
 
        if (!range.cursor)
13624
 
            range.cursor = range.end;
13625
 
 
13626
 
        var removed = this.rangeList.add(range);
13627
 
 
13628
 
        this.$onAddRange(range);
13629
 
 
13630
 
        if (removed.length)
13631
 
            this.$onRemoveRange(removed);
13632
 
 
13633
 
        if (this.rangeCount > 1 && !this.inMultiSelectMode) {
13634
 
            this._emit("multiSelect");
13635
 
            this.inMultiSelectMode = true;
13636
 
            this.session.$undoSelect = false;
13637
 
            this.rangeList.attach(this.session);
13638
 
        }
13639
 
 
13640
 
        return $blockChangeEvents || this.fromOrientedRange(range);
13641
 
    };
13642
 
 
13643
 
    this.toSingleRange = function(range) {
13644
 
        range = range || this.ranges[0];
13645
 
        var removed = this.rangeList.removeAll();
13646
 
        if (removed.length)
13647
 
            this.$onRemoveRange(removed);
13648
 
 
13649
 
        range && this.fromOrientedRange(range);
13650
 
    };
13651
 
    this.substractPoint = function(pos) {
13652
 
        var removed = this.rangeList.substractPoint(pos);
13653
 
        if (removed) {
13654
 
            this.$onRemoveRange(removed);
13655
 
            return removed[0];
13656
 
        }
13657
 
    };
13658
 
    this.mergeOverlappingRanges = function() {
13659
 
        var removed = this.rangeList.merge();
13660
 
        if (removed.length)
13661
 
            this.$onRemoveRange(removed);
13662
 
        else if(this.ranges[0])
13663
 
            this.fromOrientedRange(this.ranges[0]);
13664
 
    };
13665
 
 
13666
 
    this.$onAddRange = function(range) {
13667
 
        this.rangeCount = this.rangeList.ranges.length;
13668
 
        this.ranges.unshift(range);
13669
 
        this._emit("addRange", {range: range});
13670
 
    };
13671
 
 
13672
 
    this.$onRemoveRange = function(removed) {
13673
 
        this.rangeCount = this.rangeList.ranges.length;
13674
 
        if (this.rangeCount == 1 && this.inMultiSelectMode) {
13675
 
            var lastRange = this.rangeList.ranges.pop();
13676
 
            removed.push(lastRange);
13677
 
            this.rangeCount = 0;
13678
 
        }
13679
 
 
13680
 
        for (var i = removed.length; i--; ) {
13681
 
            var index = this.ranges.indexOf(removed[i]);
13682
 
            this.ranges.splice(index, 1);
13683
 
        }
13684
 
 
13685
 
        this._emit("removeRange", {ranges: removed});
13686
 
 
13687
 
        if (this.rangeCount == 0 && this.inMultiSelectMode) {
13688
 
            this.inMultiSelectMode = false;
13689
 
            this._emit("singleSelect");
13690
 
            this.session.$undoSelect = true;
13691
 
            this.rangeList.detach(this.session);
13692
 
        }
13693
 
 
13694
 
        lastRange = lastRange || this.ranges[0];
13695
 
        if (lastRange && !lastRange.isEqual(this.getRange()))
13696
 
            this.fromOrientedRange(lastRange);
13697
 
    };
13698
 
    this.$initRangeList = function() {
13699
 
        if (this.rangeList)
13700
 
            return;
13701
 
 
13702
 
        this.rangeList = new RangeList();
13703
 
        this.ranges = [];
13704
 
        this.rangeCount = 0;
13705
 
    };
13706
 
    this.getAllRanges = function() {
13707
 
        return this.rangeList.ranges.concat();
13708
 
    };
13709
 
 
13710
 
    this.splitIntoLines = function () {
13711
 
        if (this.rangeCount > 1) {
13712
 
            var ranges = this.rangeList.ranges;
13713
 
            var lastRange = ranges[ranges.length - 1];
13714
 
            var range = Range.fromPoints(ranges[0].start, lastRange.end);
13715
 
 
13716
 
            this.toSingleRange();
13717
 
            this.setSelectionRange(range, lastRange.cursor == lastRange.start);
13718
 
        } else {
13719
 
            var range = this.getRange();
13720
 
            var isBackwards = this.isBackwards();
13721
 
            var startRow = range.start.row;
13722
 
            var endRow = range.end.row;
13723
 
            if (startRow == endRow) {
13724
 
                if (isBackwards)
13725
 
                    var start = range.end, end = range.start;
13726
 
                else
13727
 
                    var start = range.start, end = range.end;
13728
 
                
13729
 
                this.addRange(Range.fromPoints(end, end));
13730
 
                this.addRange(Range.fromPoints(start, start));
13731
 
                return;
13732
 
            }
13733
 
 
13734
 
            var rectSel = [];
13735
 
            var r = this.getLineRange(startRow, true);
13736
 
            r.start.column = range.start.column;
13737
 
            rectSel.push(r);
13738
 
 
13739
 
            for (var i = startRow + 1; i < endRow; i++)
13740
 
                rectSel.push(this.getLineRange(i, true));
13741
 
 
13742
 
            r = this.getLineRange(endRow, true);
13743
 
            r.end.column = range.end.column;
13744
 
            rectSel.push(r);
13745
 
 
13746
 
            rectSel.forEach(this.addRange, this);
13747
 
        }
13748
 
    };
13749
 
    this.toggleBlockSelection = function () {
13750
 
        if (this.rangeCount > 1) {
13751
 
            var ranges = this.rangeList.ranges;
13752
 
            var lastRange = ranges[ranges.length - 1];
13753
 
            var range = Range.fromPoints(ranges[0].start, lastRange.end);
13754
 
 
13755
 
            this.toSingleRange();
13756
 
            this.setSelectionRange(range, lastRange.cursor == lastRange.start);
13757
 
        } else {
13758
 
            var cursor = this.session.documentToScreenPosition(this.selectionLead);
13759
 
            var anchor = this.session.documentToScreenPosition(this.selectionAnchor);
13760
 
 
13761
 
            var rectSel = this.rectangularRangeBlock(cursor, anchor);
13762
 
            rectSel.forEach(this.addRange, this);
13763
 
        }
13764
 
    };
13765
 
    this.rectangularRangeBlock = function(screenCursor, screenAnchor, includeEmptyLines) {
13766
 
        var rectSel = [];
13767
 
 
13768
 
        var xBackwards = screenCursor.column < screenAnchor.column;
13769
 
        if (xBackwards) {
13770
 
            var startColumn = screenCursor.column;
13771
 
            var endColumn = screenAnchor.column;
13772
 
        } else {
13773
 
            var startColumn = screenAnchor.column;
13774
 
            var endColumn = screenCursor.column;
13775
 
        }
13776
 
 
13777
 
        var yBackwards = screenCursor.row < screenAnchor.row;
13778
 
        if (yBackwards) {
13779
 
            var startRow = screenCursor.row;
13780
 
            var endRow = screenAnchor.row;
13781
 
        } else {
13782
 
            var startRow = screenAnchor.row;
13783
 
            var endRow = screenCursor.row;
13784
 
        }
13785
 
 
13786
 
        if (startColumn < 0)
13787
 
            startColumn = 0;
13788
 
        if (startRow < 0)
13789
 
            startRow = 0;
13790
 
 
13791
 
        if (startRow == endRow)
13792
 
            includeEmptyLines = true;
13793
 
 
13794
 
        for (var row = startRow; row <= endRow; row++) {
13795
 
            var range = Range.fromPoints(
13796
 
                this.session.screenToDocumentPosition(row, startColumn),
13797
 
                this.session.screenToDocumentPosition(row, endColumn)
13798
 
            );
13799
 
            if (range.isEmpty()) {
13800
 
                if (docEnd && isSamePoint(range.end, docEnd))
13801
 
                    break;
13802
 
                var docEnd = range.end;
13803
 
            }
13804
 
            range.cursor = xBackwards ? range.start : range.end;
13805
 
            rectSel.push(range);
13806
 
        }
13807
 
 
13808
 
        if (yBackwards)
13809
 
            rectSel.reverse();
13810
 
 
13811
 
        if (!includeEmptyLines) {
13812
 
            var end = rectSel.length - 1;
13813
 
            while (rectSel[end].isEmpty() && end > 0)
13814
 
                end--;
13815
 
            if (end > 0) {
13816
 
                var start = 0;
13817
 
                while (rectSel[start].isEmpty())
13818
 
                    start++;
13819
 
            }
13820
 
            for (var i = end; i >= start; i--) {
13821
 
                if (rectSel[i].isEmpty())
13822
 
                    rectSel.splice(i, 1);
13823
 
            }
13824
 
        }
13825
 
 
13826
 
        return rectSel;
13827
 
    };
13828
 
}).call(Selection.prototype);
13829
 
var Editor = require("./editor").Editor;
13830
 
(function() {
13831
 
    this.updateSelectionMarkers = function() {
13832
 
        this.renderer.updateCursor();
13833
 
        this.renderer.updateBackMarkers();
13834
 
    };
13835
 
    this.addSelectionMarker = function(orientedRange) {
13836
 
        if (!orientedRange.cursor)
13837
 
            orientedRange.cursor = orientedRange.end;
13838
 
 
13839
 
        var style = this.getSelectionStyle();
13840
 
        orientedRange.marker = this.session.addMarker(orientedRange, "ace_selection", style);
13841
 
 
13842
 
        this.session.$selectionMarkers.push(orientedRange);
13843
 
        this.session.selectionMarkerCount = this.session.$selectionMarkers.length;
13844
 
        return orientedRange;
13845
 
    };
13846
 
    this.removeSelectionMarker = function(range) {
13847
 
        if (!range.marker)
13848
 
            return;
13849
 
        this.session.removeMarker(range.marker);
13850
 
        var index = this.session.$selectionMarkers.indexOf(range);
13851
 
        if (index != -1)
13852
 
            this.session.$selectionMarkers.splice(index, 1);
13853
 
        this.session.selectionMarkerCount = this.session.$selectionMarkers.length;
13854
 
    };
13855
 
 
13856
 
    this.removeSelectionMarkers = function(ranges) {
13857
 
        var markerList = this.session.$selectionMarkers;
13858
 
        for (var i = ranges.length; i--; ) {
13859
 
            var range = ranges[i];
13860
 
            if (!range.marker)
13861
 
                continue;
13862
 
            this.session.removeMarker(range.marker);
13863
 
            var index = markerList.indexOf(range);
13864
 
            if (index != -1)
13865
 
                markerList.splice(index, 1);
13866
 
        }
13867
 
        this.session.selectionMarkerCount = markerList.length;
13868
 
    };
13869
 
 
13870
 
    this.$onAddRange = function(e) {
13871
 
        this.addSelectionMarker(e.range);
13872
 
        this.renderer.updateCursor();
13873
 
        this.renderer.updateBackMarkers();
13874
 
    };
13875
 
 
13876
 
    this.$onRemoveRange = function(e) {
13877
 
        this.removeSelectionMarkers(e.ranges);
13878
 
        this.renderer.updateCursor();
13879
 
        this.renderer.updateBackMarkers();
13880
 
    };
13881
 
 
13882
 
    this.$onMultiSelect = function(e) {
13883
 
        if (this.inMultiSelectMode)
13884
 
            return;
13885
 
        this.inMultiSelectMode = true;
13886
 
 
13887
 
        this.setStyle("ace_multiselect");
13888
 
        this.keyBinding.addKeyboardHandler(commands.keyboardHandler);
13889
 
        this.commands.on("exec", this.$onMultiSelectExec);
13890
 
 
13891
 
        this.renderer.updateCursor();
13892
 
        this.renderer.updateBackMarkers();
13893
 
    };
13894
 
 
13895
 
    this.$onSingleSelect = function(e) {
13896
 
        if (this.session.multiSelect.inVirtualMode)
13897
 
            return;
13898
 
        this.inMultiSelectMode = false;
13899
 
 
13900
 
        this.unsetStyle("ace_multiselect");
13901
 
        this.keyBinding.removeKeyboardHandler(commands.keyboardHandler);
13902
 
 
13903
 
        this.commands.removeEventListener("exec", this.$onMultiSelectExec);
13904
 
        this.renderer.updateCursor();
13905
 
        this.renderer.updateBackMarkers();
13906
 
    };
13907
 
 
13908
 
    this.$onMultiSelectExec = function(e) {
13909
 
        var command = e.command;
13910
 
        var editor = e.editor;
13911
 
        if (!editor.multiSelect)
13912
 
            return;
13913
 
        if (!command.multiSelectAction) {
13914
 
            command.exec(editor, e.args || {});
13915
 
            editor.multiSelect.addRange(editor.multiSelect.toOrientedRange());
13916
 
            editor.multiSelect.mergeOverlappingRanges();
13917
 
        } else if (command.multiSelectAction == "forEach") {
13918
 
            editor.forEachSelection(command, e.args);
13919
 
        } else if (command.multiSelectAction == "forEachLine") {
13920
 
            editor.forEachSelection(command, e.args, true);
13921
 
        } else if (command.multiSelectAction == "single") {
13922
 
            editor.exitMultiSelectMode();
13923
 
            command.exec(editor, e.args || {});
13924
 
        } else {
13925
 
            command.multiSelectAction(editor, e.args || {});
13926
 
        }
13927
 
        e.preventDefault();
13928
 
    }; 
13929
 
    this.forEachSelection = function(cmd, args, $byLines) {
13930
 
        if (this.inVirtualSelectionMode)
13931
 
            return;
13932
 
 
13933
 
        var session = this.session;
13934
 
        var selection = this.selection;
13935
 
        var rangeList = selection.rangeList;
13936
 
 
13937
 
        var reg = selection._eventRegistry;
13938
 
        selection._eventRegistry = {};
13939
 
 
13940
 
        var tmpSel = new Selection(session);
13941
 
        this.inVirtualSelectionMode = true;
13942
 
        for (var i = rangeList.ranges.length; i--;) {
13943
 
            if ($byLines) {
13944
 
                while (i > 0 && rangeList.ranges[i].start.row == rangeList.ranges[i - 1].end.row)
13945
 
                    i--;
13946
 
            }
13947
 
            tmpSel.fromOrientedRange(rangeList.ranges[i]);
13948
 
            this.selection = session.selection = tmpSel;
13949
 
            cmd.exec(this, args || {});
13950
 
            tmpSel.toOrientedRange(rangeList.ranges[i]);
13951
 
        }
13952
 
        tmpSel.detach();
13953
 
 
13954
 
        this.selection = session.selection = selection;
13955
 
        this.inVirtualSelectionMode = false;
13956
 
        selection._eventRegistry = reg;
13957
 
        selection.mergeOverlappingRanges();
13958
 
 
13959
 
        this.onCursorChange();
13960
 
        this.onSelectionChange();
13961
 
    };
13962
 
    this.exitMultiSelectMode = function() {
13963
 
        if (this.inVirtualSelectionMode)
13964
 
            return;
13965
 
        this.multiSelect.toSingleRange();
13966
 
    };
13967
 
 
13968
 
    this.getCopyText = function() {
13969
 
        var text = "";
13970
 
        if (this.inMultiSelectMode) {
13971
 
            var ranges = this.multiSelect.rangeList.ranges;
13972
 
            text = [];
13973
 
            for (var i = 0; i < ranges.length; i++) {
13974
 
                text.push(this.session.getTextRange(ranges[i]));
13975
 
            }
13976
 
            text = text.join(this.session.getDocument().getNewLineCharacter());
13977
 
        } else if (!this.selection.isEmpty()) {
13978
 
            text = this.session.getTextRange(this.getSelectionRange());
13979
 
        }
13980
 
 
13981
 
        return text;
13982
 
    };
13983
 
    this.onPaste = function(text) {
13984
 
        if (this.$readOnly)
13985
 
            return;
13986
 
 
13987
 
        this._signal("paste", text);
13988
 
        if (!this.inMultiSelectMode || this.inVirtualSelectionMode)
13989
 
            return this.insert(text);
13990
 
 
13991
 
        var lines = text.split(/\r\n|\r|\n/);
13992
 
        var ranges = this.selection.rangeList.ranges;
13993
 
 
13994
 
        if (lines.length > ranges.length || (lines.length <= 2 || !lines[1]))
13995
 
            return this.commands.exec("insertstring", this, text);
13996
 
 
13997
 
        for (var i = ranges.length; i--; ) {
13998
 
            var range = ranges[i];
13999
 
            if (!range.isEmpty())
14000
 
                this.session.remove(range);
14001
 
 
14002
 
            this.session.insert(range.start, lines[i]);
14003
 
        }
14004
 
    };
14005
 
    this.findAll = function(needle, options, additive) {
14006
 
        options = options || {};
14007
 
        options.needle = needle || options.needle;
14008
 
        this.$search.set(options);
14009
 
 
14010
 
        var ranges = this.$search.findAll(this.session);
14011
 
        if (!ranges.length)
14012
 
            return 0;
14013
 
 
14014
 
        this.$blockScrolling += 1;
14015
 
        var selection = this.multiSelect;
14016
 
 
14017
 
        if (!additive)
14018
 
            selection.toSingleRange(ranges[0]);
14019
 
 
14020
 
        for (var i = ranges.length; i--; )
14021
 
            selection.addRange(ranges[i], true);
14022
 
 
14023
 
        this.$blockScrolling -= 1;
14024
 
 
14025
 
        return ranges.length;
14026
 
    };
14027
 
    this.selectMoreLines = function(dir, skip) {
14028
 
        var range = this.selection.toOrientedRange();
14029
 
        var isBackwards = range.cursor == range.end;
14030
 
 
14031
 
        var screenLead = this.session.documentToScreenPosition(range.cursor);
14032
 
        if (this.selection.$desiredColumn)
14033
 
            screenLead.column = this.selection.$desiredColumn;
14034
 
 
14035
 
        var lead = this.session.screenToDocumentPosition(screenLead.row + dir, screenLead.column);
14036
 
 
14037
 
        if (!range.isEmpty()) {
14038
 
            var screenAnchor = this.session.documentToScreenPosition(isBackwards ? range.end : range.start);
14039
 
            var anchor = this.session.screenToDocumentPosition(screenAnchor.row + dir, screenAnchor.column);
14040
 
        } else {
14041
 
            var anchor = lead;
14042
 
        }
14043
 
 
14044
 
        if (isBackwards) {
14045
 
            var newRange = Range.fromPoints(lead, anchor);
14046
 
            newRange.cursor = newRange.start;
14047
 
        } else {
14048
 
            var newRange = Range.fromPoints(anchor, lead);
14049
 
            newRange.cursor = newRange.end;
14050
 
        }
14051
 
 
14052
 
        newRange.desiredColumn = screenLead.column;
14053
 
        if (!this.selection.inMultiSelectMode) {
14054
 
            this.selection.addRange(range);
14055
 
        } else {
14056
 
            if (skip)
14057
 
                var toRemove = range.cursor;
14058
 
        }
14059
 
 
14060
 
        this.selection.addRange(newRange);
14061
 
        if (toRemove)
14062
 
            this.selection.substractPoint(toRemove);
14063
 
    };
14064
 
    this.transposeSelections = function(dir) {
14065
 
        var session = this.session;
14066
 
        var sel = session.multiSelect;
14067
 
        var all = sel.ranges;
14068
 
 
14069
 
        for (var i = all.length; i--; ) {
14070
 
            var range = all[i];
14071
 
            if (range.isEmpty()) {
14072
 
                var tmp = session.getWordRange(range.start.row, range.start.column);
14073
 
                range.start.row = tmp.start.row;
14074
 
                range.start.column = tmp.start.column;
14075
 
                range.end.row = tmp.end.row;
14076
 
                range.end.column = tmp.end.column;
14077
 
            }
14078
 
        }
14079
 
        sel.mergeOverlappingRanges();
14080
 
 
14081
 
        var words = [];
14082
 
        for (var i = all.length; i--; ) {
14083
 
            var range = all[i];
14084
 
            words.unshift(session.getTextRange(range));
14085
 
        }
14086
 
 
14087
 
        if (dir < 0)
14088
 
            words.unshift(words.pop());
14089
 
        else
14090
 
            words.push(words.shift());
14091
 
 
14092
 
        for (var i = all.length; i--; ) {
14093
 
            var range = all[i];
14094
 
            var tmp = range.clone();
14095
 
            session.replace(range, words[i]);
14096
 
            range.start.row = tmp.start.row;
14097
 
            range.start.column = tmp.start.column;
14098
 
        }
14099
 
    };
14100
 
    this.selectMore = function(dir, skip) {
14101
 
        var session = this.session;
14102
 
        var sel = session.multiSelect;
14103
 
 
14104
 
        var range = sel.toOrientedRange();
14105
 
        if (range.isEmpty()) {
14106
 
            var range = session.getWordRange(range.start.row, range.start.column);
14107
 
            range.cursor = range.end;
14108
 
            this.multiSelect.addRange(range);
14109
 
        }
14110
 
        var needle = session.getTextRange(range);
14111
 
 
14112
 
        var newRange = find(session, needle, dir);
14113
 
        if (newRange) {
14114
 
            newRange.cursor = dir == -1 ? newRange.start : newRange.end;
14115
 
            this.multiSelect.addRange(newRange);
14116
 
        }
14117
 
        if (skip)
14118
 
            this.multiSelect.substractPoint(range.cursor);
14119
 
    };
14120
 
    this.alignCursors = function() {
14121
 
        var session = this.session;
14122
 
        var sel = session.multiSelect;
14123
 
        var ranges = sel.ranges;
14124
 
 
14125
 
        if (!ranges.length) {
14126
 
            var range = this.selection.getRange();
14127
 
            var fr = range.start.row, lr = range.end.row;
14128
 
            var lines = this.session.doc.removeLines(fr, lr);
14129
 
            lines = this.$reAlignText(lines);
14130
 
            this.session.doc.insertLines(fr, lines);
14131
 
            range.start.column = 0;
14132
 
            range.end.column = lines[lines.length - 1].length;
14133
 
            this.selection.setRange(range);
14134
 
        } else {
14135
 
            var row = -1;
14136
 
            var sameRowRanges = ranges.filter(function(r) {
14137
 
                if (r.cursor.row == row)
14138
 
                    return true;
14139
 
                row = r.cursor.row;
14140
 
            });
14141
 
            sel.$onRemoveRange(sameRowRanges);
14142
 
 
14143
 
            var maxCol = 0;
14144
 
            var minSpace = Infinity;
14145
 
            var spaceOffsets = ranges.map(function(r) {
14146
 
                var p = r.cursor;
14147
 
                var line = session.getLine(p.row);
14148
 
                var spaceOffset = line.substr(p.column).search(/\S/g);
14149
 
                if (spaceOffset == -1)
14150
 
                    spaceOffset = 0;
14151
 
 
14152
 
                if (p.column > maxCol)
14153
 
                    maxCol = p.column;
14154
 
                if (spaceOffset < minSpace)
14155
 
                    minSpace = spaceOffset;
14156
 
                return spaceOffset;
14157
 
            });
14158
 
            ranges.forEach(function(r, i) {
14159
 
                var p = r.cursor;
14160
 
                var l = maxCol - p.column;
14161
 
                var d = spaceOffsets[i] - minSpace;
14162
 
                if (l > d)
14163
 
                    session.insert(p, lang.stringRepeat(" ", l - d));
14164
 
                else
14165
 
                    session.remove(new Range(p.row, p.column, p.row, p.column - l + d));
14166
 
 
14167
 
                r.start.column = r.end.column = maxCol;
14168
 
                r.start.row = r.end.row = p.row;
14169
 
                r.cursor = r.end;
14170
 
            });
14171
 
            sel.fromOrientedRange(ranges[0]);
14172
 
            this.renderer.updateCursor();
14173
 
            this.renderer.updateBackMarkers();
14174
 
        }
14175
 
    };
14176
 
 
14177
 
    this.$reAlignText = function(lines) {
14178
 
        var isLeftAligned = true, isRightAligned = true;
14179
 
        var startW, textW, endW;
14180
 
 
14181
 
        return lines.map(function(line) {
14182
 
            var m = line.match(/(\s*)(.*?)(\s*)([=:].*)/);
14183
 
            if (!m)
14184
 
                return [line];
14185
 
 
14186
 
            if (startW == null) {
14187
 
                startW = m[1].length;
14188
 
                textW = m[2].length;
14189
 
                endW = m[3].length;
14190
 
                return m;
14191
 
            }
14192
 
 
14193
 
            if (startW + textW + endW != m[1].length + m[2].length + m[3].length)
14194
 
                isRightAligned = false;
14195
 
            if (startW != m[1].length)
14196
 
                isLeftAligned = false;
14197
 
 
14198
 
            if (startW > m[1].length)
14199
 
                startW = m[1].length;
14200
 
            if (textW < m[2].length)
14201
 
                textW = m[2].length;
14202
 
            if (endW > m[3].length)
14203
 
                endW = m[3].length;
14204
 
 
14205
 
            return m;
14206
 
        }).map(isLeftAligned ? isRightAligned ? alignRight : alignLeft : unAlign);
14207
 
 
14208
 
        function spaces(n) {
14209
 
            return lang.stringRepeat(" ", n);
14210
 
        }
14211
 
 
14212
 
        function alignLeft(m) {
14213
 
            return !m[2] ? m[0] : spaces(startW) + m[2]
14214
 
                + spaces(textW - m[2].length + endW)
14215
 
                + m[4].replace(/^([=:])\s+/, "$1 ")
14216
 
        }
14217
 
        function alignRight(m) {
14218
 
            return !m[2] ? m[0] : spaces(startW + textW - m[2].length) + m[2]
14219
 
                + spaces(endW, " ")
14220
 
                + m[4].replace(/^([=:])\s+/, "$1 ")
14221
 
        }
14222
 
        function unAlign(m) {
14223
 
            return !m[2] ? m[0] : spaces(startW) + m[2]
14224
 
                + spaces(endW)
14225
 
                + m[4].replace(/^([=:])\s+/, "$1 ")
14226
 
        }
14227
 
    }
14228
 
}).call(Editor.prototype);
14229
 
 
14230
 
 
14231
 
function isSamePoint(p1, p2) {
14232
 
    return p1.row == p2.row && p1.column == p2.column;
14233
 
}
14234
 
exports.onSessionChange = function(e) {
14235
 
    var session = e.session;
14236
 
    if (!session.multiSelect) {
14237
 
        session.$selectionMarkers = [];
14238
 
        session.selection.$initRangeList();
14239
 
        session.multiSelect = session.selection;
14240
 
    }
14241
 
    this.multiSelect = session.multiSelect;
14242
 
 
14243
 
    var oldSession = e.oldSession;
14244
 
    if (oldSession) {
14245
 
        if (oldSession.multiSelect && oldSession.multiSelect.editor == this)
14246
 
            oldSession.multiSelect.editor = null;
14247
 
 
14248
 
        session.multiSelect.removeEventListener("addRange", this.$onAddRange);
14249
 
        session.multiSelect.removeEventListener("removeRange", this.$onRemoveRange);
14250
 
        session.multiSelect.removeEventListener("multiSelect", this.$onMultiSelect);
14251
 
        session.multiSelect.removeEventListener("singleSelect", this.$onSingleSelect);
14252
 
    }
14253
 
 
14254
 
    session.multiSelect.on("addRange", this.$onAddRange);
14255
 
    session.multiSelect.on("removeRange", this.$onRemoveRange);
14256
 
    session.multiSelect.on("multiSelect", this.$onMultiSelect);
14257
 
    session.multiSelect.on("singleSelect", this.$onSingleSelect);
14258
 
 
14259
 
    if (this.inMultiSelectMode != session.selection.inMultiSelectMode) {
14260
 
        if (session.selection.inMultiSelectMode)
14261
 
            this.$onMultiSelect();
14262
 
        else
14263
 
            this.$onSingleSelect();
14264
 
    }
14265
 
};
14266
 
function MultiSelect(editor) {
14267
 
    editor.$onAddRange = editor.$onAddRange.bind(editor);
14268
 
    editor.$onRemoveRange = editor.$onRemoveRange.bind(editor);
14269
 
    editor.$onMultiSelect = editor.$onMultiSelect.bind(editor);
14270
 
    editor.$onSingleSelect = editor.$onSingleSelect.bind(editor);
14271
 
 
14272
 
    exports.onSessionChange.call(editor, editor);
14273
 
    editor.on("changeSession", exports.onSessionChange.bind(editor));
14274
 
 
14275
 
    editor.on("mousedown", onMouseDown);
14276
 
    editor.commands.addCommands(commands.defaultCommands);
14277
 
 
14278
 
    addAltCursorListeners(editor);
14279
 
}
14280
 
 
14281
 
function addAltCursorListeners(editor){
14282
 
    var el = editor.textInput.getElement();
14283
 
    var altCursor = false;
14284
 
    var contentEl = editor.renderer.content;
14285
 
    event.addListener(el, "keydown", function(e) {
14286
 
        if (e.keyCode == 18 && !(e.ctrlKey || e.shiftKey || e.metaKey)) {
14287
 
            if (!altCursor) {
14288
 
                contentEl.style.cursor = "crosshair";
14289
 
                altCursor = true;
14290
 
            }
14291
 
        } else if (altCursor) {
14292
 
            contentEl.style.cursor = "";
14293
 
        }
14294
 
    });
14295
 
 
14296
 
    event.addListener(el, "keyup", reset);
14297
 
    event.addListener(el, "blur", reset);
14298
 
    function reset() {
14299
 
        if (altCursor) {
14300
 
            contentEl.style.cursor = "";
14301
 
            altCursor = false;
14302
 
        }
14303
 
    }
14304
 
}
14305
 
 
14306
 
exports.MultiSelect = MultiSelect;
14307
 
 
14308
 
});
14309
 
 
14310
 
define('ace/mouse/multi_select_handler', ['require', 'exports', 'module' , 'ace/lib/event'], function(require, exports, module) {
14311
 
 
14312
 
var event = require("../lib/event");
14313
 
function isSamePoint(p1, p2) {
14314
 
    return p1.row == p2.row && p1.column == p2.column;
14315
 
}
14316
 
 
14317
 
function onMouseDown(e) {
14318
 
    var ev = e.domEvent;
14319
 
    var alt = ev.altKey;
14320
 
    var shift = ev.shiftKey;
14321
 
    var ctrl = e.getAccelKey();
14322
 
    var button = e.getButton();
14323
 
 
14324
 
    if (e.editor.inMultiSelectMode && button == 2) {
14325
 
        e.editor.textInput.onContextMenu(e.domEvent);
14326
 
        return;
14327
 
    }
14328
 
    
14329
 
    if (!ctrl && !alt) {
14330
 
        if (button == 0 && e.editor.inMultiSelectMode)
14331
 
            e.editor.exitMultiSelectMode();
14332
 
        return;
14333
 
    }
14334
 
 
14335
 
    var editor = e.editor;
14336
 
    var selection = editor.selection;
14337
 
    var isMultiSelect = editor.inMultiSelectMode;
14338
 
    var pos = e.getDocumentPosition();
14339
 
    var cursor = selection.getCursor();
14340
 
    var inSelection = e.inSelection() || (selection.isEmpty() && isSamePoint(pos, cursor));
14341
 
 
14342
 
 
14343
 
    var mouseX = e.x, mouseY = e.y;
14344
 
    var onMouseSelection = function(e) {
14345
 
        mouseX = e.clientX;
14346
 
        mouseY = e.clientY;
14347
 
    };
14348
 
 
14349
 
    var blockSelect = function() {
14350
 
        var newCursor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
14351
 
        var cursor = session.screenToDocumentPosition(newCursor.row, newCursor.column);
14352
 
 
14353
 
        if (isSamePoint(screenCursor, newCursor)
14354
 
            && isSamePoint(cursor, selection.selectionLead))
14355
 
            return;
14356
 
        screenCursor = newCursor;
14357
 
 
14358
 
        editor.selection.moveCursorToPosition(cursor);
14359
 
        editor.selection.clearSelection();
14360
 
        editor.renderer.scrollCursorIntoView();
14361
 
 
14362
 
        editor.removeSelectionMarkers(rectSel);
14363
 
        rectSel = selection.rectangularRangeBlock(screenCursor, screenAnchor);
14364
 
        rectSel.forEach(editor.addSelectionMarker, editor);
14365
 
        editor.updateSelectionMarkers();
14366
 
    };
14367
 
    
14368
 
    var session = editor.session;
14369
 
    var screenAnchor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
14370
 
    var screenCursor = screenAnchor;
14371
 
 
14372
 
    
14373
 
 
14374
 
    if (ctrl && !shift && !alt && button == 0) {
14375
 
        if (!isMultiSelect && inSelection)
14376
 
            return; // dragging
14377
 
 
14378
 
        if (!isMultiSelect) {
14379
 
            var range = selection.toOrientedRange();
14380
 
            editor.addSelectionMarker(range);
14381
 
        }
14382
 
 
14383
 
        var oldRange = selection.rangeList.rangeAtPoint(pos);
14384
 
 
14385
 
        event.capture(editor.container, function(){}, function() {
14386
 
            var tmpSel = selection.toOrientedRange();
14387
 
 
14388
 
            if (oldRange && tmpSel.isEmpty() && isSamePoint(oldRange.cursor, tmpSel.cursor))
14389
 
                selection.substractPoint(tmpSel.cursor);
14390
 
            else {
14391
 
                if (range) {
14392
 
                    editor.removeSelectionMarker(range);
14393
 
                    selection.addRange(range);
14394
 
                }
14395
 
                selection.addRange(tmpSel);
14396
 
            }
14397
 
        });
14398
 
 
14399
 
    } else if (alt && button == 0) {
14400
 
        e.stop();
14401
 
 
14402
 
        if (isMultiSelect && !ctrl)
14403
 
            selection.toSingleRange();
14404
 
        else if (!isMultiSelect && ctrl)
14405
 
            selection.addRange();
14406
 
 
14407
 
        var rectSel = [];
14408
 
        if (shift) {
14409
 
            screenAnchor = session.documentToScreenPosition(selection.lead);
14410
 
            blockSelect();
14411
 
        } else {
14412
 
            selection.moveCursorToPosition(pos);
14413
 
            selection.clearSelection();
14414
 
        }
14415
 
 
14416
 
 
14417
 
        var onMouseSelectionEnd = function(e) {
14418
 
            clearInterval(timerId);
14419
 
            editor.removeSelectionMarkers(rectSel);
14420
 
            for (var i = 0; i < rectSel.length; i++)
14421
 
                selection.addRange(rectSel[i]);
14422
 
        };
14423
 
 
14424
 
        var onSelectionInterval = blockSelect;
14425
 
 
14426
 
        event.capture(editor.container, onMouseSelection, onMouseSelectionEnd);
14427
 
        var timerId = setInterval(function() {onSelectionInterval();}, 20);
14428
 
 
14429
 
        return e.preventDefault();
14430
 
    }
14431
 
}
14432
 
 
14433
 
 
14434
 
exports.onMouseDown = onMouseDown;
14435
 
 
14436
 
});
14437
 
 
14438
 
define('ace/commands/multi_select_commands', ['require', 'exports', 'module' , 'ace/keyboard/hash_handler'], function(require, exports, module) {
14439
 
exports.defaultCommands = [{
14440
 
    name: "addCursorAbove",
14441
 
    exec: function(editor) { editor.selectMoreLines(-1); },
14442
 
    bindKey: {win: "Ctrl-Alt-Up", mac: "Ctrl-Alt-Up"},
14443
 
    readonly: true
14444
 
}, {
14445
 
    name: "addCursorBelow",
14446
 
    exec: function(editor) { editor.selectMoreLines(1); },
14447
 
    bindKey: {win: "Ctrl-Alt-Down", mac: "Ctrl-Alt-Down"},
14448
 
    readonly: true
14449
 
}, {
14450
 
    name: "addCursorAboveSkipCurrent",
14451
 
    exec: function(editor) { editor.selectMoreLines(-1, true); },
14452
 
    bindKey: {win: "Ctrl-Alt-Shift-Up", mac: "Ctrl-Alt-Shift-Up"},
14453
 
    readonly: true
14454
 
}, {
14455
 
    name: "addCursorBelowSkipCurrent",
14456
 
    exec: function(editor) { editor.selectMoreLines(1, true); },
14457
 
    bindKey: {win: "Ctrl-Alt-Shift-Down", mac: "Ctrl-Alt-Shift-Down"},
14458
 
    readonly: true
14459
 
}, {
14460
 
    name: "selectMoreBefore",
14461
 
    exec: function(editor) { editor.selectMore(-1); },
14462
 
    bindKey: {win: "Ctrl-Alt-Left", mac: "Ctrl-Alt-Left"},
14463
 
    readonly: true
14464
 
}, {
14465
 
    name: "selectMoreAfter",
14466
 
    exec: function(editor) { editor.selectMore(1); },
14467
 
    bindKey: {win: "Ctrl-Alt-Right", mac: "Ctrl-Alt-Right"},
14468
 
    readonly: true
14469
 
}, {
14470
 
    name: "selectNextBefore",
14471
 
    exec: function(editor) { editor.selectMore(-1, true); },
14472
 
    bindKey: {win: "Ctrl-Alt-Shift-Left", mac: "Ctrl-Alt-Shift-Left"},
14473
 
    readonly: true
14474
 
}, {
14475
 
    name: "selectNextAfter",
14476
 
    exec: function(editor) { editor.selectMore(1, true); },
14477
 
    bindKey: {win: "Ctrl-Alt-Shift-Right", mac: "Ctrl-Alt-Shift-Right"},
14478
 
    readonly: true
14479
 
}, {
14480
 
    name: "splitIntoLines",
14481
 
    exec: function(editor) { editor.multiSelect.splitIntoLines(); },
14482
 
    bindKey: {win: "Ctrl-Alt-L", mac: "Ctrl-Alt-L"},
14483
 
    readonly: true
14484
 
}, {
14485
 
    name: "alignCursors",
14486
 
    exec: function(editor) { editor.alignCursors(); },
14487
 
    bindKey: {win: "Ctrl-Alt-A", mac: "Ctrl-Alt-A"}
14488
 
}];
14489
 
exports.multiSelectCommands = [{
14490
 
    name: "singleSelection",
14491
 
    bindKey: "esc",
14492
 
    exec: function(editor) { editor.exitMultiSelectMode(); },
14493
 
    readonly: true,
14494
 
    isAvailable: function(editor) {return editor && editor.inMultiSelectMode}
14495
 
}];
14496
 
 
14497
 
var HashHandler = require("../keyboard/hash_handler").HashHandler;
14498
 
exports.keyboardHandler = new HashHandler(exports.multiSelectCommands);
14499
 
 
14500
 
});
14501
 
 
14502
 
define('ace/worker/worker_client', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter', 'ace/config'], function(require, exports, module) {
14503
 
 
14504
 
 
14505
 
var oop = require("../lib/oop");
14506
 
var EventEmitter = require("../lib/event_emitter").EventEmitter;
14507
 
var config = require("../config");
14508
 
 
14509
 
var WorkerClient = function(topLevelNamespaces, mod, classname) {
14510
 
    this.changeListener = this.changeListener.bind(this);
14511
 
    this.onMessage = this.onMessage.bind(this);
14512
 
    this.onError = this.onError.bind(this);
14513
 
 
14514
 
    var workerUrl;
14515
 
    if (config.get("packaged")) {
14516
 
        workerUrl = config.moduleUrl(mod, "worker");
14517
 
    } else {
14518
 
        var normalizePath = this.$normalizePath;
14519
 
        if (typeof require.supports !== "undefined" && require.supports.indexOf("ucjs2-pinf-0") >= 0) {
14520
 
            workerUrl = require.nameToUrl("ace/worker/worker_sourcemint");
14521
 
        } else {
14522
 
            if (require.nameToUrl && !require.toUrl)
14523
 
                require.toUrl = require.nameToUrl;
14524
 
            workerUrl = normalizePath(require.toUrl("ace/worker/worker", null, "_"));
14525
 
        }
14526
 
 
14527
 
        var tlns = {};
14528
 
        topLevelNamespaces.forEach(function(ns) {
14529
 
            tlns[ns] = normalizePath(require.toUrl(ns, null, "_").replace(/.js(\?.*)?$/, ""));
14530
 
        });
14531
 
    }
14532
 
 
14533
 
    this.$worker = new Worker(workerUrl);
14534
 
    this.$worker.postMessage({
14535
 
        init : true,
14536
 
        tlns: tlns,
14537
 
        module: mod,
14538
 
        classname: classname
14539
 
    });
14540
 
 
14541
 
    this.callbackId = 1;
14542
 
    this.callbacks = {};
14543
 
 
14544
 
    this.$worker.onerror = this.onError;
14545
 
    this.$worker.onmessage = this.onMessage;
14546
 
};
14547
 
 
14548
 
(function(){
14549
 
 
14550
 
    oop.implement(this, EventEmitter);
14551
 
 
14552
 
    this.onError = function(e) {
14553
 
        window.console && console.log && console.log(e);
14554
 
        throw e;
14555
 
    };
14556
 
 
14557
 
    this.onMessage = function(e) {
14558
 
        var msg = e.data;
14559
 
        switch(msg.type) {
14560
 
            case "log":
14561
 
                window.console && console.log && console.log.apply(console, msg.data);
14562
 
                break;
14563
 
 
14564
 
            case "event":
14565
 
                this._emit(msg.name, {data: msg.data});
14566
 
                break;
14567
 
 
14568
 
            case "call":
14569
 
                var callback = this.callbacks[msg.id];
14570
 
                if (callback) {
14571
 
                    callback(msg.data);
14572
 
                    delete this.callbacks[msg.id];
14573
 
                }
14574
 
                break;
14575
 
        }
14576
 
    };
14577
 
 
14578
 
    this.$normalizePath = function(path) {
14579
 
        if (!location.host) // needed for file:// protocol
14580
 
            return path;
14581
 
        path = path.replace(/^[a-z]+:\/\/[^\/]+/, ""); // Remove domain name and rebuild it
14582
 
        path = location.protocol + "//" + location.host
14583
 
            + (path.charAt(0) == "/" ? "" : location.pathname.replace(/\/[^\/]*$/, ""))
14584
 
            + "/" + path.replace(/^[\/]+/, "");
14585
 
        return path;
14586
 
    };
14587
 
 
14588
 
    this.terminate = function() {
14589
 
        this._emit("terminate", {});
14590
 
        this.$worker.terminate();
14591
 
        this.$worker = null;
14592
 
        this.$doc.removeEventListener("change", this.changeListener);
14593
 
        this.$doc = null;
14594
 
    };
14595
 
 
14596
 
    this.send = function(cmd, args) {
14597
 
        this.$worker.postMessage({command: cmd, args: args});
14598
 
    };
14599
 
 
14600
 
    this.call = function(cmd, args, callback) {
14601
 
        if (callback) {
14602
 
            var id = this.callbackId++;
14603
 
            this.callbacks[id] = callback;
14604
 
            args.push(id);
14605
 
        }
14606
 
        this.send(cmd, args);
14607
 
    };
14608
 
 
14609
 
    this.emit = function(event, data) {
14610
 
        try {
14611
 
            this.$worker.postMessage({event: event, data: {data: data.data}});
14612
 
        }
14613
 
        catch(ex) {}
14614
 
    };
14615
 
 
14616
 
    this.attachToDocument = function(doc) {
14617
 
        if(this.$doc)
14618
 
            this.terminate();
14619
 
 
14620
 
        this.$doc = doc;
14621
 
        this.call("setValue", [doc.getValue()]);
14622
 
        doc.on("change", this.changeListener);
14623
 
    };
14624
 
 
14625
 
    this.changeListener = function(e) {
14626
 
        e.range = {
14627
 
            start: e.data.range.start,
14628
 
            end: e.data.range.end
14629
 
        };
14630
 
        this.emit("change", e);
14631
 
    };
14632
 
 
14633
 
}).call(WorkerClient.prototype);
14634
 
 
14635
 
 
14636
 
var UIWorkerClient = function(topLevelNamespaces, mod, classname) {
14637
 
    this.changeListener = this.changeListener.bind(this);
14638
 
    this.callbackId = 1;
14639
 
    this.callbacks = {};
14640
 
    this.messageBuffer = [];
14641
 
 
14642
 
    var main = null;
14643
 
    var sender = Object.create(EventEmitter);
14644
 
    var _self = this;
14645
 
 
14646
 
    this.$worker = {}
14647
 
    this.$worker.terminate = function() {};
14648
 
    this.$worker.postMessage = function(e) {
14649
 
        _self.messageBuffer.push(e);
14650
 
        main && setTimeout(processNext);
14651
 
    };
14652
 
 
14653
 
    var processNext = function() {
14654
 
        var msg = _self.messageBuffer.shift();
14655
 
        if (msg.command)
14656
 
            main[msg.command].apply(main, msg.args);
14657
 
        else if (msg.event)
14658
 
            sender._emit(msg.event, msg.data);
14659
 
    };
14660
 
 
14661
 
    sender.postMessage = function(msg) {
14662
 
        _self.onMessage({data: msg});
14663
 
    };
14664
 
    sender.callback = function(data, callbackId) {
14665
 
        this.postMessage({type: "call", id: callbackId, data: data});
14666
 
    };
14667
 
    sender.emit = function(name, data) {
14668
 
        this.postMessage({type: "event", name: name, data: data});
14669
 
    };
14670
 
 
14671
 
    config.loadModule(["worker", mod], function(Main) {
14672
 
        main = new Main[classname](sender);
14673
 
        while (_self.messageBuffer.length)
14674
 
            processNext();
14675
 
    });
14676
 
};
14677
 
 
14678
 
UIWorkerClient.prototype = WorkerClient.prototype;
14679
 
 
14680
 
exports.UIWorkerClient = UIWorkerClient;
14681
 
exports.WorkerClient = WorkerClient;
14682
 
 
14683
 
});
14684
 
define('ace/placeholder', ['require', 'exports', 'module' , 'ace/range', 'ace/lib/event_emitter', 'ace/lib/oop'], function(require, exports, module) {
14685
 
 
14686
 
 
14687
 
var Range = require("./range").Range;
14688
 
var EventEmitter = require("./lib/event_emitter").EventEmitter;
14689
 
var oop = require("./lib/oop");
14690
 
 
14691
 
var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) {
14692
 
    var _self = this;
14693
 
    this.length = length;
14694
 
    this.session = session;
14695
 
    this.doc = session.getDocument();
14696
 
    this.mainClass = mainClass;
14697
 
    this.othersClass = othersClass;
14698
 
    this.$onUpdate = this.onUpdate.bind(this);
14699
 
    this.doc.on("change", this.$onUpdate);
14700
 
    this.$others = others;
14701
 
    
14702
 
    this.$onCursorChange = function() {
14703
 
        setTimeout(function() {
14704
 
            _self.onCursorChange();
14705
 
        });
14706
 
    };
14707
 
    
14708
 
    this.$pos = pos;
14709
 
    var undoStack = session.getUndoManager().$undoStack || session.getUndoManager().$undostack || {length: -1};
14710
 
    this.$undoStackDepth =  undoStack.length;
14711
 
    this.setup();
14712
 
 
14713
 
    session.selection.on("changeCursor", this.$onCursorChange);
14714
 
};
14715
 
 
14716
 
(function() {
14717
 
 
14718
 
    oop.implement(this, EventEmitter);
14719
 
    this.setup = function() {
14720
 
        var _self = this;
14721
 
        var doc = this.doc;
14722
 
        var session = this.session;
14723
 
        var pos = this.$pos;
14724
 
 
14725
 
        this.pos = doc.createAnchor(pos.row, pos.column);
14726
 
        this.markerId = session.addMarker(new Range(pos.row, pos.column, pos.row, pos.column + this.length), this.mainClass, null, false);
14727
 
        this.pos.on("change", function(event) {
14728
 
            session.removeMarker(_self.markerId);
14729
 
            _self.markerId = session.addMarker(new Range(event.value.row, event.value.column, event.value.row, event.value.column+_self.length), _self.mainClass, null, false);
14730
 
        });
14731
 
        this.others = [];
14732
 
        this.$others.forEach(function(other) {
14733
 
            var anchor = doc.createAnchor(other.row, other.column);
14734
 
            _self.others.push(anchor);
14735
 
        });
14736
 
        session.setUndoSelect(false);
14737
 
    };
14738
 
    this.showOtherMarkers = function() {
14739
 
        if(this.othersActive) return;
14740
 
        var session = this.session;
14741
 
        var _self = this;
14742
 
        this.othersActive = true;
14743
 
        this.others.forEach(function(anchor) {
14744
 
            anchor.markerId = session.addMarker(new Range(anchor.row, anchor.column, anchor.row, anchor.column+_self.length), _self.othersClass, null, false);
14745
 
            anchor.on("change", function(event) {
14746
 
                session.removeMarker(anchor.markerId);
14747
 
                anchor.markerId = session.addMarker(new Range(event.value.row, event.value.column, event.value.row, event.value.column+_self.length), _self.othersClass, null, false);
14748
 
            });
14749
 
        });
14750
 
    };
14751
 
    this.hideOtherMarkers = function() {
14752
 
        if(!this.othersActive) return;
14753
 
        this.othersActive = false;
14754
 
        for (var i = 0; i < this.others.length; i++) {
14755
 
            this.session.removeMarker(this.others[i].markerId);
14756
 
        }
14757
 
    };
14758
 
    this.onUpdate = function(event) {
14759
 
        var delta = event.data;
14760
 
        var range = delta.range;
14761
 
        if(range.start.row !== range.end.row) return;
14762
 
        if(range.start.row !== this.pos.row) return;
14763
 
        if (this.$updating) return;
14764
 
        this.$updating = true;
14765
 
        var lengthDiff = delta.action === "insertText" ? range.end.column - range.start.column : range.start.column - range.end.column;
14766
 
        
14767
 
        if(range.start.column >= this.pos.column && range.start.column <= this.pos.column + this.length + 1) {
14768
 
            var distanceFromStart = range.start.column - this.pos.column;
14769
 
            this.length += lengthDiff;
14770
 
            if(!this.session.$fromUndo) {
14771
 
                if(delta.action === "insertText") {
14772
 
                    for (var i = this.others.length - 1; i >= 0; i--) {
14773
 
                        var otherPos = this.others[i];
14774
 
                        var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart};
14775
 
                        if(otherPos.row === range.start.row && range.start.column < otherPos.column)
14776
 
                            newPos.column += lengthDiff;
14777
 
                        this.doc.insert(newPos, delta.text);
14778
 
                    }
14779
 
                } else if(delta.action === "removeText") {
14780
 
                    for (var i = this.others.length - 1; i >= 0; i--) {
14781
 
                        var otherPos = this.others[i];
14782
 
                        var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart};
14783
 
                        if(otherPos.row === range.start.row && range.start.column < otherPos.column)
14784
 
                            newPos.column += lengthDiff;
14785
 
                        this.doc.remove(new Range(newPos.row, newPos.column, newPos.row, newPos.column - lengthDiff));
14786
 
                    }
14787
 
                }
14788
 
                if(range.start.column === this.pos.column && delta.action === "insertText") {
14789
 
                    setTimeout(function() {
14790
 
                        this.pos.setPosition(this.pos.row, this.pos.column - lengthDiff);
14791
 
                        for (var i = 0; i < this.others.length; i++) {
14792
 
                            var other = this.others[i];
14793
 
                            var newPos = {row: other.row, column: other.column - lengthDiff};
14794
 
                            if(other.row === range.start.row && range.start.column < other.column)
14795
 
                                newPos.column += lengthDiff;
14796
 
                            other.setPosition(newPos.row, newPos.column);
14797
 
                        }
14798
 
                    }.bind(this), 0);
14799
 
                }
14800
 
                else if(range.start.column === this.pos.column && delta.action === "removeText") {
14801
 
                    setTimeout(function() {
14802
 
                        for (var i = 0; i < this.others.length; i++) {
14803
 
                            var other = this.others[i];
14804
 
                            if(other.row === range.start.row && range.start.column < other.column) {
14805
 
                                other.setPosition(other.row, other.column - lengthDiff);
14806
 
                            }
14807
 
                        }
14808
 
                    }.bind(this), 0);
14809
 
                }
14810
 
            }
14811
 
            this.pos._emit("change", {value: this.pos});
14812
 
            for (var i = 0; i < this.others.length; i++) {
14813
 
                this.others[i]._emit("change", {value: this.others[i]});
14814
 
            }
14815
 
        }
14816
 
        this.$updating = false;
14817
 
    };
14818
 
 
14819
 
    this.onCursorChange = function(event) {
14820
 
        if (this.$updating) return;
14821
 
        var pos = this.session.selection.getCursor();
14822
 
        if(pos.row === this.pos.row && pos.column >= this.pos.column && pos.column <= this.pos.column + this.length) {
14823
 
            this.showOtherMarkers();
14824
 
            this._emit("cursorEnter", event);
14825
 
        } else {
14826
 
            this.hideOtherMarkers();
14827
 
            this._emit("cursorLeave", event);
14828
 
        }
14829
 
    };    
14830
 
    this.detach = function() {
14831
 
        this.session.removeMarker(this.markerId);
14832
 
        this.hideOtherMarkers();
14833
 
        this.doc.removeEventListener("change", this.$onUpdate);
14834
 
        this.session.selection.removeEventListener("changeCursor", this.$onCursorChange);
14835
 
        this.pos.detach();
14836
 
        for (var i = 0; i < this.others.length; i++) {
14837
 
            this.others[i].detach();
14838
 
        }
14839
 
        this.session.setUndoSelect(true);
14840
 
    };
14841
 
    this.cancel = function() {
14842
 
        if(this.$undoStackDepth === -1)
14843
 
            throw Error("Canceling placeholders only supported with undo manager attached to session.");
14844
 
        var undoManager = this.session.getUndoManager();
14845
 
        var undosRequired = (undoManager.$undoStack || undoManager.$undostack).length - this.$undoStackDepth;
14846
 
        for (var i = 0; i < undosRequired; i++) {
14847
 
            undoManager.undo(true);
14848
 
        }
14849
 
    };
14850
 
}).call(PlaceHolder.prototype);
14851
 
 
14852
 
 
14853
 
exports.PlaceHolder = PlaceHolder;
14854
 
});
14855
 
 
14856
 
define('ace/mode/folding/fold_mode', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
14857
 
 
14858
 
 
14859
 
var Range = require("../../range").Range;
14860
 
 
14861
 
var FoldMode = exports.FoldMode = function() {};
14862
 
 
14863
 
(function() {
14864
 
 
14865
 
    this.foldingStartMarker = null;
14866
 
    this.foldingStopMarker = null;
14867
 
    this.getFoldWidget = function(session, foldStyle, row) {
14868
 
        var line = session.getLine(row);
14869
 
        if (this.foldingStartMarker.test(line))
14870
 
            return "start";
14871
 
        if (foldStyle == "markbeginend"
14872
 
                && this.foldingStopMarker
14873
 
                && this.foldingStopMarker.test(line))
14874
 
            return "end";
14875
 
        return "";
14876
 
    };
14877
 
 
14878
 
    this.getFoldWidgetRange = function(session, foldStyle, row) {
14879
 
        return null;
14880
 
    };
14881
 
 
14882
 
    this.indentationBlock = function(session, row, column) {
14883
 
        var re = /\S/;
14884
 
        var line = session.getLine(row);
14885
 
        var startLevel = line.search(re);
14886
 
        if (startLevel == -1)
14887
 
            return;
14888
 
 
14889
 
        var startColumn = column || line.length;
14890
 
        var maxRow = session.getLength();
14891
 
        var startRow = row;
14892
 
        var endRow = row;
14893
 
 
14894
 
        while (++row < maxRow) {
14895
 
            var level = session.getLine(row).search(re);
14896
 
 
14897
 
            if (level == -1)
14898
 
                continue;
14899
 
 
14900
 
            if (level <= startLevel)
14901
 
                break;
14902
 
 
14903
 
            endRow = row;
14904
 
        }
14905
 
 
14906
 
        if (endRow > startRow) {
14907
 
            var endColumn = session.getLine(endRow).length;
14908
 
            return new Range(startRow, startColumn, endRow, endColumn);
14909
 
        }
14910
 
    };
14911
 
 
14912
 
    this.openingBracketBlock = function(session, bracket, row, column, typeRe) {
14913
 
        var start = {row: row, column: column + 1};
14914
 
        var end = session.$findClosingBracket(bracket, start, typeRe);
14915
 
        if (!end)
14916
 
            return;
14917
 
 
14918
 
        var fw = session.foldWidgets[end.row];
14919
 
        if (fw == null)
14920
 
            fw = this.getFoldWidget(session, end.row);
14921
 
 
14922
 
        if (fw == "start" && end.row > start.row) {
14923
 
            end.row --;
14924
 
            end.column = session.getLine(end.row).length;
14925
 
        }
14926
 
        return Range.fromPoints(start, end);
14927
 
    };
14928
 
 
14929
 
    this.closingBracketBlock = function(session, bracket, row, column, typeRe) {
14930
 
        var end = {row: row, column: column};
14931
 
        var start = session.$findOpeningBracket(bracket, end);
14932
 
 
14933
 
        if (!start)
14934
 
            return;
14935
 
 
14936
 
        start.column++;
14937
 
        end.column--;
14938
 
 
14939
 
        return  Range.fromPoints(start, end);
14940
 
    };
14941
 
}).call(FoldMode.prototype);
14942
 
 
14943
 
});
14944
 
 
14945
 
define('ace/theme/textmate', ['require', 'exports', 'module' , 'ace/lib/dom'], function(require, exports, module) {
14946
 
 
14947
 
 
14948
 
exports.isDark = false;
14949
 
exports.cssClass = "ace-tm";
14950
 
exports.cssText = ".ace-tm .ace_gutter {\
14951
 
background: #f0f0f0;\
14952
 
color: #333;\
14953
 
}\
14954
 
.ace-tm .ace_print-margin {\
14955
 
width: 1px;\
14956
 
background: #e8e8e8;\
14957
 
}\
14958
 
.ace-tm .ace_fold {\
14959
 
background-color: #6B72E6;\
14960
 
}\
14961
 
.ace-tm .ace_scroller {\
14962
 
background-color: #FFFFFF;\
14963
 
}\
14964
 
.ace-tm .ace_cursor {\
14965
 
border-left: 2px solid black;\
14966
 
}\
14967
 
.ace-tm .ace_overwrite-cursors .ace_cursor {\
14968
 
border-left: 0px;\
14969
 
border-bottom: 1px solid black;\
14970
 
}\
14971
 
.ace-tm .ace_invisible {\
14972
 
color: rgb(191, 191, 191);\
14973
 
}\
14974
 
.ace-tm .ace_storage,\
14975
 
.ace-tm .ace_keyword {\
14976
 
color: blue;\
14977
 
}\
14978
 
.ace-tm .ace_constant {\
14979
 
color: rgb(197, 6, 11);\
14980
 
}\
14981
 
.ace-tm .ace_constant.ace_buildin {\
14982
 
color: rgb(88, 72, 246);\
14983
 
}\
14984
 
.ace-tm .ace_constant.ace_language {\
14985
 
color: rgb(88, 92, 246);\
14986
 
}\
14987
 
.ace-tm .ace_constant.ace_library {\
14988
 
color: rgb(6, 150, 14);\
14989
 
}\
14990
 
.ace-tm .ace_invalid {\
14991
 
background-color: rgba(255, 0, 0, 0.1);\
14992
 
color: red;\
14993
 
}\
14994
 
.ace-tm .ace_support.ace_function {\
14995
 
color: rgb(60, 76, 114);\
14996
 
}\
14997
 
.ace-tm .ace_support.ace_constant {\
14998
 
color: rgb(6, 150, 14);\
14999
 
}\
15000
 
.ace-tm .ace_support.ace_type,\
15001
 
.ace-tm .ace_support.ace_class {\
15002
 
color: rgb(109, 121, 222);\
15003
 
}\
15004
 
.ace-tm .ace_keyword.ace_operator {\
15005
 
color: rgb(104, 118, 135);\
15006
 
}\
15007
 
.ace-tm .ace_string {\
15008
 
color: rgb(3, 106, 7);\
15009
 
}\
15010
 
.ace-tm .ace_comment {\
15011
 
color: rgb(76, 136, 107);\
15012
 
}\
15013
 
.ace-tm .ace_comment.ace_doc {\
15014
 
color: rgb(0, 102, 255);\
15015
 
}\
15016
 
.ace-tm .ace_comment.ace_doc.ace_tag {\
15017
 
color: rgb(128, 159, 191);\
15018
 
}\
15019
 
.ace-tm .ace_constant.ace_numeric {\
15020
 
color: rgb(0, 0, 205);\
15021
 
}\
15022
 
.ace-tm .ace_variable {\
15023
 
color: rgb(49, 132, 149);\
15024
 
}\
15025
 
.ace-tm .ace_xml-pe {\
15026
 
color: rgb(104, 104, 91);\
15027
 
}\
15028
 
.ace-tm .ace_entity.ace_name.ace_function {\
15029
 
color: #0000A2;\
15030
 
}\
15031
 
.ace-tm .ace_markup.ace_heading {\
15032
 
color: rgb(12, 7, 255);\
15033
 
}\
15034
 
.ace-tm .ace_markup.ace_list {\
15035
 
color:rgb(185, 6, 144);\
15036
 
}\
15037
 
.ace-tm .ace_meta.ace_tag {\
15038
 
color:rgb(0, 22, 142);\
15039
 
}\
15040
 
.ace-tm .ace_string.ace_regex {\
15041
 
color: rgb(255, 0, 0)\
15042
 
}\
15043
 
.ace-tm .ace_marker-layer .ace_selection {\
15044
 
background: rgb(181, 213, 255);\
15045
 
}\
15046
 
.ace-tm.ace_multiselect .ace_selection.ace_start {\
15047
 
box-shadow: 0 0 3px 0px white;\
15048
 
border-radius: 2px;\
15049
 
}\
15050
 
.ace-tm .ace_marker-layer .ace_step {\
15051
 
background: rgb(252, 255, 0);\
15052
 
}\
15053
 
.ace-tm .ace_marker-layer .ace_stack {\
15054
 
background: rgb(164, 229, 101);\
15055
 
}\
15056
 
.ace-tm .ace_marker-layer .ace_bracket {\
15057
 
margin: -1px 0 0 -1px;\
15058
 
border: 1px solid rgb(192, 192, 192);\
15059
 
}\
15060
 
.ace-tm .ace_marker-layer .ace_active-line {\
15061
 
background: rgba(0, 0, 0, 0.07);\
15062
 
}\
15063
 
.ace-tm .ace_gutter-active-line {\
15064
 
background-color : #dcdcdc;\
15065
 
}\
15066
 
.ace-tm .ace_marker-layer .ace_selected-word {\
15067
 
background: rgb(250, 250, 255);\
15068
 
border: 1px solid rgb(200, 200, 250);\
15069
 
}\
15070
 
.ace-tm .ace_indent-guide {\
15071
 
background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\
15072
 
}\
15073
 
";
15074
 
 
15075
 
var dom = require("../lib/dom");
15076
 
dom.importCssString(exports.cssText, exports.cssClass);
15077
 
});
15078
 
;
15079
 
            (function() {
15080
 
                window.require(["ace/ace"], function(a) {
15081
 
                    a && a.config.init();
15082
 
                    if (!window.ace)
15083
 
                        window.ace = {};
15084
 
                    for (var key in a) if (a.hasOwnProperty(key))
15085
 
                        ace[key] = a[key];
15086
 
                });
15087
 
            })();
15088
 
        
 
 
b'\\ No newline at end of file'