Projekt

Obecné

Profil

Stáhnout (103 KB) Statistiky
| Větev: | Tag: | Revize:
1
"no use strict";
2
!(function(window) {
3
if (typeof window.window != "undefined" && window.document)
4
    return;
5
if (window.require && window.define)
6
    return;
7

    
8
if (!window.console) {
9
    window.console = function() {
10
        var msgs = Array.prototype.slice.call(arguments, 0);
11
        postMessage({type: "log", data: msgs});
12
    };
13
    window.console.error =
14
    window.console.warn = 
15
    window.console.log =
16
    window.console.trace = window.console;
17
}
18
window.window = window;
19
window.ace = window;
20

    
21
window.onerror = function(message, file, line, col, err) {
22
    postMessage({type: "error", data: {
23
        message: message,
24
        data: err.data,
25
        file: file,
26
        line: line, 
27
        col: col,
28
        stack: err.stack
29
    }});
30
};
31

    
32
window.normalizeModule = function(parentId, moduleName) {
33
    // normalize plugin requires
34
    if (moduleName.indexOf("!") !== -1) {
35
        var chunks = moduleName.split("!");
36
        return window.normalizeModule(parentId, chunks[0]) + "!" + window.normalizeModule(parentId, chunks[1]);
37
    }
38
    // normalize relative requires
39
    if (moduleName.charAt(0) == ".") {
40
        var base = parentId.split("/").slice(0, -1).join("/");
41
        moduleName = (base ? base + "/" : "") + moduleName;
42
        
43
        while (moduleName.indexOf(".") !== -1 && previous != moduleName) {
44
            var previous = moduleName;
45
            moduleName = moduleName.replace(/^\.\//, "").replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, "");
46
        }
47
    }
48
    
49
    return moduleName;
50
};
51

    
52
window.require = function require(parentId, id) {
53
    if (!id) {
54
        id = parentId;
55
        parentId = null;
56
    }
57
    if (!id.charAt)
58
        throw new Error("worker.js require() accepts only (parentId, id) as arguments");
59

    
60
    id = window.normalizeModule(parentId, id);
61

    
62
    var module = window.require.modules[id];
63
    if (module) {
64
        if (!module.initialized) {
65
            module.initialized = true;
66
            module.exports = module.factory().exports;
67
        }
68
        return module.exports;
69
    }
70
   
71
    if (!window.require.tlns)
72
        return console.log("unable to load " + id);
73
    
74
    var path = resolveModuleId(id, window.require.tlns);
75
    if (path.slice(-3) != ".js") path += ".js";
76
    
77
    window.require.id = id;
78
    window.require.modules[id] = {}; // prevent infinite loop on broken modules
79
    importScripts(path);
80
    return window.require(parentId, id);
81
};
82
function resolveModuleId(id, paths) {
83
    var testPath = id, tail = "";
84
    while (testPath) {
85
        var alias = paths[testPath];
86
        if (typeof alias == "string") {
87
            return alias + tail;
88
        } else if (alias) {
89
            return  alias.location.replace(/\/*$/, "/") + (tail || alias.main || alias.name);
90
        } else if (alias === false) {
91
            return "";
92
        }
93
        var i = testPath.lastIndexOf("/");
94
        if (i === -1) break;
95
        tail = testPath.substr(i) + tail;
96
        testPath = testPath.slice(0, i);
97
    }
98
    return id;
99
}
100
window.require.modules = {};
101
window.require.tlns = {};
102

    
103
window.define = function(id, deps, factory) {
104
    if (arguments.length == 2) {
105
        factory = deps;
106
        if (typeof id != "string") {
107
            deps = id;
108
            id = window.require.id;
109
        }
110
    } else if (arguments.length == 1) {
111
        factory = id;
112
        deps = [];
113
        id = window.require.id;
114
    }
115
    
116
    if (typeof factory != "function") {
117
        window.require.modules[id] = {
118
            exports: factory,
119
            initialized: true
120
        };
121
        return;
122
    }
123

    
124
    if (!deps.length)
125
        // If there is no dependencies, we inject "require", "exports" and
126
        // "module" as dependencies, to provide CommonJS compatibility.
127
        deps = ["require", "exports", "module"];
128

    
129
    var req = function(childId) {
130
        return window.require(id, childId);
131
    };
132

    
133
    window.require.modules[id] = {
134
        exports: {},
135
        factory: function() {
136
            var module = this;
137
            var returnExports = factory.apply(this, deps.slice(0, factory.length).map(function(dep) {
138
                switch (dep) {
139
                    // Because "require", "exports" and "module" aren't actual
140
                    // dependencies, we must handle them seperately.
141
                    case "require": return req;
142
                    case "exports": return module.exports;
143
                    case "module":  return module;
144
                    // But for all other dependencies, we can just go ahead and
145
                    // require them.
146
                    default:        return req(dep);
147
                }
148
            }));
149
            if (returnExports)
150
                module.exports = returnExports;
151
            return module;
152
        }
153
    };
154
};
155
window.define.amd = {};
156
require.tlns = {};
157
window.initBaseUrls  = function initBaseUrls(topLevelNamespaces) {
158
    for (var i in topLevelNamespaces)
159
        require.tlns[i] = topLevelNamespaces[i];
160
};
161

    
162
window.initSender = function initSender() {
163

    
164
    var EventEmitter = window.require("ace/lib/event_emitter").EventEmitter;
165
    var oop = window.require("ace/lib/oop");
166
    
167
    var Sender = function() {};
168
    
169
    (function() {
170
        
171
        oop.implement(this, EventEmitter);
172
                
173
        this.callback = function(data, callbackId) {
174
            postMessage({
175
                type: "call",
176
                id: callbackId,
177
                data: data
178
            });
179
        };
180
    
181
        this.emit = function(name, data) {
182
            postMessage({
183
                type: "event",
184
                name: name,
185
                data: data
186
            });
187
        };
188
        
189
    }).call(Sender.prototype);
190
    
191
    return new Sender();
192
};
193

    
194
var main = window.main = null;
195
var sender = window.sender = null;
196

    
197
window.onmessage = function(e) {
198
    var msg = e.data;
199
    if (msg.event && sender) {
200
        sender._signal(msg.event, msg.data);
201
    }
202
    else if (msg.command) {
203
        if (main[msg.command])
204
            main[msg.command].apply(main, msg.args);
205
        else if (window[msg.command])
206
            window[msg.command].apply(window, msg.args);
207
        else
208
            throw new Error("Unknown command:" + msg.command);
209
    }
210
    else if (msg.init) {
211
        window.initBaseUrls(msg.tlns);
212
        require("ace/lib/es5-shim");
213
        sender = window.sender = window.initSender();
214
        var clazz = require(msg.module)[msg.classname];
215
        main = window.main = new clazz(sender);
216
    }
217
};
218
})(this);
219

    
220
ace.define("ace/lib/oop",[], function(require, exports, module) {
221
"use strict";
222

    
223
exports.inherits = function(ctor, superCtor) {
224
    ctor.super_ = superCtor;
225
    ctor.prototype = Object.create(superCtor.prototype, {
226
        constructor: {
227
            value: ctor,
228
            enumerable: false,
229
            writable: true,
230
            configurable: true
231
        }
232
    });
233
};
234

    
235
exports.mixin = function(obj, mixin) {
236
    for (var key in mixin) {
237
        obj[key] = mixin[key];
238
    }
239
    return obj;
240
};
241

    
242
exports.implement = function(proto, mixin) {
243
    exports.mixin(proto, mixin);
244
};
245

    
246
});
247

    
248
ace.define("ace/range",[], function(require, exports, module) {
249
"use strict";
250
var comparePoints = function(p1, p2) {
251
    return p1.row - p2.row || p1.column - p2.column;
252
};
253
var Range = function(startRow, startColumn, endRow, endColumn) {
254
    this.start = {
255
        row: startRow,
256
        column: startColumn
257
    };
258

    
259
    this.end = {
260
        row: endRow,
261
        column: endColumn
262
    };
263
};
264

    
265
(function() {
266
    this.isEqual = function(range) {
267
        return this.start.row === range.start.row &&
268
            this.end.row === range.end.row &&
269
            this.start.column === range.start.column &&
270
            this.end.column === range.end.column;
271
    };
272
    this.toString = function() {
273
        return ("Range: [" + this.start.row + "/" + this.start.column +
274
            "] -> [" + this.end.row + "/" + this.end.column + "]");
275
    };
276

    
277
    this.contains = function(row, column) {
278
        return this.compare(row, column) == 0;
279
    };
280
    this.compareRange = function(range) {
281
        var cmp,
282
            end = range.end,
283
            start = range.start;
284

    
285
        cmp = this.compare(end.row, end.column);
286
        if (cmp == 1) {
287
            cmp = this.compare(start.row, start.column);
288
            if (cmp == 1) {
289
                return 2;
290
            } else if (cmp == 0) {
291
                return 1;
292
            } else {
293
                return 0;
294
            }
295
        } else if (cmp == -1) {
296
            return -2;
297
        } else {
298
            cmp = this.compare(start.row, start.column);
299
            if (cmp == -1) {
300
                return -1;
301
            } else if (cmp == 1) {
302
                return 42;
303
            } else {
304
                return 0;
305
            }
306
        }
307
    };
308
    this.comparePoint = function(p) {
309
        return this.compare(p.row, p.column);
310
    };
311
    this.containsRange = function(range) {
312
        return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
313
    };
314
    this.intersects = function(range) {
315
        var cmp = this.compareRange(range);
316
        return (cmp == -1 || cmp == 0 || cmp == 1);
317
    };
318
    this.isEnd = function(row, column) {
319
        return this.end.row == row && this.end.column == column;
320
    };
321
    this.isStart = function(row, column) {
322
        return this.start.row == row && this.start.column == column;
323
    };
324
    this.setStart = function(row, column) {
325
        if (typeof row == "object") {
326
            this.start.column = row.column;
327
            this.start.row = row.row;
328
        } else {
329
            this.start.row = row;
330
            this.start.column = column;
331
        }
332
    };
333
    this.setEnd = function(row, column) {
334
        if (typeof row == "object") {
335
            this.end.column = row.column;
336
            this.end.row = row.row;
337
        } else {
338
            this.end.row = row;
339
            this.end.column = column;
340
        }
341
    };
342
    this.inside = function(row, column) {
343
        if (this.compare(row, column) == 0) {
344
            if (this.isEnd(row, column) || this.isStart(row, column)) {
345
                return false;
346
            } else {
347
                return true;
348
            }
349
        }
350
        return false;
351
    };
352
    this.insideStart = function(row, column) {
353
        if (this.compare(row, column) == 0) {
354
            if (this.isEnd(row, column)) {
355
                return false;
356
            } else {
357
                return true;
358
            }
359
        }
360
        return false;
361
    };
362
    this.insideEnd = function(row, column) {
363
        if (this.compare(row, column) == 0) {
364
            if (this.isStart(row, column)) {
365
                return false;
366
            } else {
367
                return true;
368
            }
369
        }
370
        return false;
371
    };
372
    this.compare = function(row, column) {
373
        if (!this.isMultiLine()) {
374
            if (row === this.start.row) {
375
                return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0);
376
            }
377
        }
378

    
379
        if (row < this.start.row)
380
            return -1;
381

    
382
        if (row > this.end.row)
383
            return 1;
384

    
385
        if (this.start.row === row)
386
            return column >= this.start.column ? 0 : -1;
387

    
388
        if (this.end.row === row)
389
            return column <= this.end.column ? 0 : 1;
390

    
391
        return 0;
392
    };
393
    this.compareStart = function(row, column) {
394
        if (this.start.row == row && this.start.column == column) {
395
            return -1;
396
        } else {
397
            return this.compare(row, column);
398
        }
399
    };
400
    this.compareEnd = function(row, column) {
401
        if (this.end.row == row && this.end.column == column) {
402
            return 1;
403
        } else {
404
            return this.compare(row, column);
405
        }
406
    };
407
    this.compareInside = function(row, column) {
408
        if (this.end.row == row && this.end.column == column) {
409
            return 1;
410
        } else if (this.start.row == row && this.start.column == column) {
411
            return -1;
412
        } else {
413
            return this.compare(row, column);
414
        }
415
    };
416
    this.clipRows = function(firstRow, lastRow) {
417
        if (this.end.row > lastRow)
418
            var end = {row: lastRow + 1, column: 0};
419
        else if (this.end.row < firstRow)
420
            var end = {row: firstRow, column: 0};
421

    
422
        if (this.start.row > lastRow)
423
            var start = {row: lastRow + 1, column: 0};
424
        else if (this.start.row < firstRow)
425
            var start = {row: firstRow, column: 0};
426

    
427
        return Range.fromPoints(start || this.start, end || this.end);
428
    };
429
    this.extend = function(row, column) {
430
        var cmp = this.compare(row, column);
431

    
432
        if (cmp == 0)
433
            return this;
434
        else if (cmp == -1)
435
            var start = {row: row, column: column};
436
        else
437
            var end = {row: row, column: column};
438

    
439
        return Range.fromPoints(start || this.start, end || this.end);
440
    };
441

    
442
    this.isEmpty = function() {
443
        return (this.start.row === this.end.row && this.start.column === this.end.column);
444
    };
445
    this.isMultiLine = function() {
446
        return (this.start.row !== this.end.row);
447
    };
448
    this.clone = function() {
449
        return Range.fromPoints(this.start, this.end);
450
    };
451
    this.collapseRows = function() {
452
        if (this.end.column == 0)
453
            return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0);
454
        else
455
            return new Range(this.start.row, 0, this.end.row, 0);
456
    };
457
    this.toScreenRange = function(session) {
458
        var screenPosStart = session.documentToScreenPosition(this.start);
459
        var screenPosEnd = session.documentToScreenPosition(this.end);
460

    
461
        return new Range(
462
            screenPosStart.row, screenPosStart.column,
463
            screenPosEnd.row, screenPosEnd.column
464
        );
465
    };
466
    this.moveBy = function(row, column) {
467
        this.start.row += row;
468
        this.start.column += column;
469
        this.end.row += row;
470
        this.end.column += column;
471
    };
472

    
473
}).call(Range.prototype);
474
Range.fromPoints = function(start, end) {
475
    return new Range(start.row, start.column, end.row, end.column);
476
};
477
Range.comparePoints = comparePoints;
478

    
479
Range.comparePoints = function(p1, p2) {
480
    return p1.row - p2.row || p1.column - p2.column;
481
};
482

    
483

    
484
exports.Range = Range;
485
});
486

    
487
ace.define("ace/apply_delta",[], function(require, exports, module) {
488
"use strict";
489

    
490
function throwDeltaError(delta, errorText){
491
    console.log("Invalid Delta:", delta);
492
    throw "Invalid Delta: " + errorText;
493
}
494

    
495
function positionInDocument(docLines, position) {
496
    return position.row    >= 0 && position.row    <  docLines.length &&
497
           position.column >= 0 && position.column <= docLines[position.row].length;
498
}
499

    
500
function validateDelta(docLines, delta) {
501
    if (delta.action != "insert" && delta.action != "remove")
502
        throwDeltaError(delta, "delta.action must be 'insert' or 'remove'");
503
    if (!(delta.lines instanceof Array))
504
        throwDeltaError(delta, "delta.lines must be an Array");
505
    if (!delta.start || !delta.end)
506
       throwDeltaError(delta, "delta.start/end must be an present");
507
    var start = delta.start;
508
    if (!positionInDocument(docLines, delta.start))
509
        throwDeltaError(delta, "delta.start must be contained in document");
510
    var end = delta.end;
511
    if (delta.action == "remove" && !positionInDocument(docLines, end))
512
        throwDeltaError(delta, "delta.end must contained in document for 'remove' actions");
513
    var numRangeRows = end.row - start.row;
514
    var numRangeLastLineChars = (end.column - (numRangeRows == 0 ? start.column : 0));
515
    if (numRangeRows != delta.lines.length - 1 || delta.lines[numRangeRows].length != numRangeLastLineChars)
516
        throwDeltaError(delta, "delta.range must match delta lines");
517
}
518

    
519
exports.applyDelta = function(docLines, delta, doNotValidate) {
520
    
521
    var row = delta.start.row;
522
    var startColumn = delta.start.column;
523
    var line = docLines[row] || "";
524
    switch (delta.action) {
525
        case "insert":
526
            var lines = delta.lines;
527
            if (lines.length === 1) {
528
                docLines[row] = line.substring(0, startColumn) + delta.lines[0] + line.substring(startColumn);
529
            } else {
530
                var args = [row, 1].concat(delta.lines);
531
                docLines.splice.apply(docLines, args);
532
                docLines[row] = line.substring(0, startColumn) + docLines[row];
533
                docLines[row + delta.lines.length - 1] += line.substring(startColumn);
534
            }
535
            break;
536
        case "remove":
537
            var endColumn = delta.end.column;
538
            var endRow = delta.end.row;
539
            if (row === endRow) {
540
                docLines[row] = line.substring(0, startColumn) + line.substring(endColumn);
541
            } else {
542
                docLines.splice(
543
                    row, endRow - row + 1,
544
                    line.substring(0, startColumn) + docLines[endRow].substring(endColumn)
545
                );
546
            }
547
            break;
548
    }
549
};
550
});
551

    
552
ace.define("ace/lib/event_emitter",[], function(require, exports, module) {
553
"use strict";
554

    
555
var EventEmitter = {};
556
var stopPropagation = function() { this.propagationStopped = true; };
557
var preventDefault = function() { this.defaultPrevented = true; };
558

    
559
EventEmitter._emit =
560
EventEmitter._dispatchEvent = function(eventName, e) {
561
    this._eventRegistry || (this._eventRegistry = {});
562
    this._defaultHandlers || (this._defaultHandlers = {});
563

    
564
    var listeners = this._eventRegistry[eventName] || [];
565
    var defaultHandler = this._defaultHandlers[eventName];
566
    if (!listeners.length && !defaultHandler)
567
        return;
568

    
569
    if (typeof e != "object" || !e)
570
        e = {};
571

    
572
    if (!e.type)
573
        e.type = eventName;
574
    if (!e.stopPropagation)
575
        e.stopPropagation = stopPropagation;
576
    if (!e.preventDefault)
577
        e.preventDefault = preventDefault;
578

    
579
    listeners = listeners.slice();
580
    for (var i=0; i<listeners.length; i++) {
581
        listeners[i](e, this);
582
        if (e.propagationStopped)
583
            break;
584
    }
585
    
586
    if (defaultHandler && !e.defaultPrevented)
587
        return defaultHandler(e, this);
588
};
589

    
590

    
591
EventEmitter._signal = function(eventName, e) {
592
    var listeners = (this._eventRegistry || {})[eventName];
593
    if (!listeners)
594
        return;
595
    listeners = listeners.slice();
596
    for (var i=0; i<listeners.length; i++)
597
        listeners[i](e, this);
598
};
599

    
600
EventEmitter.once = function(eventName, callback) {
601
    var _self = this;
602
    this.on(eventName, function newCallback() {
603
        _self.off(eventName, newCallback);
604
        callback.apply(null, arguments);
605
    });
606
    if (!callback) {
607
        return new Promise(function(resolve) {
608
            callback = resolve;
609
        });
610
    }
611
};
612

    
613

    
614
EventEmitter.setDefaultHandler = function(eventName, callback) {
615
    var handlers = this._defaultHandlers;
616
    if (!handlers)
617
        handlers = this._defaultHandlers = {_disabled_: {}};
618
    
619
    if (handlers[eventName]) {
620
        var old = handlers[eventName];
621
        var disabled = handlers._disabled_[eventName];
622
        if (!disabled)
623
            handlers._disabled_[eventName] = disabled = [];
624
        disabled.push(old);
625
        var i = disabled.indexOf(callback);
626
        if (i != -1) 
627
            disabled.splice(i, 1);
628
    }
629
    handlers[eventName] = callback;
630
};
631
EventEmitter.removeDefaultHandler = function(eventName, callback) {
632
    var handlers = this._defaultHandlers;
633
    if (!handlers)
634
        return;
635
    var disabled = handlers._disabled_[eventName];
636
    
637
    if (handlers[eventName] == callback) {
638
        if (disabled)
639
            this.setDefaultHandler(eventName, disabled.pop());
640
    } else if (disabled) {
641
        var i = disabled.indexOf(callback);
642
        if (i != -1)
643
            disabled.splice(i, 1);
644
    }
645
};
646

    
647
EventEmitter.on =
648
EventEmitter.addEventListener = function(eventName, callback, capturing) {
649
    this._eventRegistry = this._eventRegistry || {};
650

    
651
    var listeners = this._eventRegistry[eventName];
652
    if (!listeners)
653
        listeners = this._eventRegistry[eventName] = [];
654

    
655
    if (listeners.indexOf(callback) == -1)
656
        listeners[capturing ? "unshift" : "push"](callback);
657
    return callback;
658
};
659

    
660
EventEmitter.off =
661
EventEmitter.removeListener =
662
EventEmitter.removeEventListener = function(eventName, callback) {
663
    this._eventRegistry = this._eventRegistry || {};
664

    
665
    var listeners = this._eventRegistry[eventName];
666
    if (!listeners)
667
        return;
668

    
669
    var index = listeners.indexOf(callback);
670
    if (index !== -1)
671
        listeners.splice(index, 1);
672
};
673

    
674
EventEmitter.removeAllListeners = function(eventName) {
675
    if (!eventName) this._eventRegistry = this._defaultHandlers = undefined;
676
    if (this._eventRegistry) this._eventRegistry[eventName] = undefined;
677
    if (this._defaultHandlers) this._defaultHandlers[eventName] = undefined;
678
};
679

    
680
exports.EventEmitter = EventEmitter;
681

    
682
});
683

    
684
ace.define("ace/anchor",[], function(require, exports, module) {
685
"use strict";
686

    
687
var oop = require("./lib/oop");
688
var EventEmitter = require("./lib/event_emitter").EventEmitter;
689

    
690
var Anchor = exports.Anchor = function(doc, row, column) {
691
    this.$onChange = this.onChange.bind(this);
692
    this.attach(doc);
693
    
694
    if (typeof column == "undefined")
695
        this.setPosition(row.row, row.column);
696
    else
697
        this.setPosition(row, column);
698
};
699

    
700
(function() {
701

    
702
    oop.implement(this, EventEmitter);
703
    this.getPosition = function() {
704
        return this.$clipPositionToDocument(this.row, this.column);
705
    };
706
    this.getDocument = function() {
707
        return this.document;
708
    };
709
    this.$insertRight = false;
710
    this.onChange = function(delta) {
711
        if (delta.start.row == delta.end.row && delta.start.row != this.row)
712
            return;
713

    
714
        if (delta.start.row > this.row)
715
            return;
716
            
717
        var point = $getTransformedPoint(delta, {row: this.row, column: this.column}, this.$insertRight);
718
        this.setPosition(point.row, point.column, true);
719
    };
720
    
721
    function $pointsInOrder(point1, point2, equalPointsInOrder) {
722
        var bColIsAfter = equalPointsInOrder ? point1.column <= point2.column : point1.column < point2.column;
723
        return (point1.row < point2.row) || (point1.row == point2.row && bColIsAfter);
724
    }
725
            
726
    function $getTransformedPoint(delta, point, moveIfEqual) {
727
        var deltaIsInsert = delta.action == "insert";
728
        var deltaRowShift = (deltaIsInsert ? 1 : -1) * (delta.end.row    - delta.start.row);
729
        var deltaColShift = (deltaIsInsert ? 1 : -1) * (delta.end.column - delta.start.column);
730
        var deltaStart = delta.start;
731
        var deltaEnd = deltaIsInsert ? deltaStart : delta.end; // Collapse insert range.
732
        if ($pointsInOrder(point, deltaStart, moveIfEqual)) {
733
            return {
734
                row: point.row,
735
                column: point.column
736
            };
737
        }
738
        if ($pointsInOrder(deltaEnd, point, !moveIfEqual)) {
739
            return {
740
                row: point.row + deltaRowShift,
741
                column: point.column + (point.row == deltaEnd.row ? deltaColShift : 0)
742
            };
743
        }
744
        
745
        return {
746
            row: deltaStart.row,
747
            column: deltaStart.column
748
        };
749
    }
750
    this.setPosition = function(row, column, noClip) {
751
        var pos;
752
        if (noClip) {
753
            pos = {
754
                row: row,
755
                column: column
756
            };
757
        } else {
758
            pos = this.$clipPositionToDocument(row, column);
759
        }
760

    
761
        if (this.row == pos.row && this.column == pos.column)
762
            return;
763

    
764
        var old = {
765
            row: this.row,
766
            column: this.column
767
        };
768

    
769
        this.row = pos.row;
770
        this.column = pos.column;
771
        this._signal("change", {
772
            old: old,
773
            value: pos
774
        });
775
    };
776
    this.detach = function() {
777
        this.document.off("change", this.$onChange);
778
    };
779
    this.attach = function(doc) {
780
        this.document = doc || this.document;
781
        this.document.on("change", this.$onChange);
782
    };
783
    this.$clipPositionToDocument = function(row, column) {
784
        var pos = {};
785

    
786
        if (row >= this.document.getLength()) {
787
            pos.row = Math.max(0, this.document.getLength() - 1);
788
            pos.column = this.document.getLine(pos.row).length;
789
        }
790
        else if (row < 0) {
791
            pos.row = 0;
792
            pos.column = 0;
793
        }
794
        else {
795
            pos.row = row;
796
            pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column));
797
        }
798

    
799
        if (column < 0)
800
            pos.column = 0;
801

    
802
        return pos;
803
    };
804

    
805
}).call(Anchor.prototype);
806

    
807
});
808

    
809
ace.define("ace/document",[], function(require, exports, module) {
810
"use strict";
811

    
812
var oop = require("./lib/oop");
813
var applyDelta = require("./apply_delta").applyDelta;
814
var EventEmitter = require("./lib/event_emitter").EventEmitter;
815
var Range = require("./range").Range;
816
var Anchor = require("./anchor").Anchor;
817

    
818
var Document = function(textOrLines) {
819
    this.$lines = [""];
820
    if (textOrLines.length === 0) {
821
        this.$lines = [""];
822
    } else if (Array.isArray(textOrLines)) {
823
        this.insertMergedLines({row: 0, column: 0}, textOrLines);
824
    } else {
825
        this.insert({row: 0, column:0}, textOrLines);
826
    }
827
};
828

    
829
(function() {
830

    
831
    oop.implement(this, EventEmitter);
832
    this.setValue = function(text) {
833
        var len = this.getLength() - 1;
834
        this.remove(new Range(0, 0, len, this.getLine(len).length));
835
        this.insert({row: 0, column: 0}, text);
836
    };
837
    this.getValue = function() {
838
        return this.getAllLines().join(this.getNewLineCharacter());
839
    };
840
    this.createAnchor = function(row, column) {
841
        return new Anchor(this, row, column);
842
    };
843
    if ("aaa".split(/a/).length === 0) {
844
        this.$split = function(text) {
845
            return text.replace(/\r\n|\r/g, "\n").split("\n");
846
        };
847
    } else {
848
        this.$split = function(text) {
849
            return text.split(/\r\n|\r|\n/);
850
        };
851
    }
852

    
853

    
854
    this.$detectNewLine = function(text) {
855
        var match = text.match(/^.*?(\r\n|\r|\n)/m);
856
        this.$autoNewLine = match ? match[1] : "\n";
857
        this._signal("changeNewLineMode");
858
    };
859
    this.getNewLineCharacter = function() {
860
        switch (this.$newLineMode) {
861
          case "windows":
862
            return "\r\n";
863
          case "unix":
864
            return "\n";
865
          default:
866
            return this.$autoNewLine || "\n";
867
        }
868
    };
869

    
870
    this.$autoNewLine = "";
871
    this.$newLineMode = "auto";
872
    this.setNewLineMode = function(newLineMode) {
873
        if (this.$newLineMode === newLineMode)
874
            return;
875

    
876
        this.$newLineMode = newLineMode;
877
        this._signal("changeNewLineMode");
878
    };
879
    this.getNewLineMode = function() {
880
        return this.$newLineMode;
881
    };
882
    this.isNewLine = function(text) {
883
        return (text == "\r\n" || text == "\r" || text == "\n");
884
    };
885
    this.getLine = function(row) {
886
        return this.$lines[row] || "";
887
    };
888
    this.getLines = function(firstRow, lastRow) {
889
        return this.$lines.slice(firstRow, lastRow + 1);
890
    };
891
    this.getAllLines = function() {
892
        return this.getLines(0, this.getLength());
893
    };
894
    this.getLength = function() {
895
        return this.$lines.length;
896
    };
897
    this.getTextRange = function(range) {
898
        return this.getLinesForRange(range).join(this.getNewLineCharacter());
899
    };
900
    this.getLinesForRange = function(range) {
901
        var lines;
902
        if (range.start.row === range.end.row) {
903
            lines = [this.getLine(range.start.row).substring(range.start.column, range.end.column)];
904
        } else {
905
            lines = this.getLines(range.start.row, range.end.row);
906
            lines[0] = (lines[0] || "").substring(range.start.column);
907
            var l = lines.length - 1;
908
            if (range.end.row - range.start.row == l)
909
                lines[l] = lines[l].substring(0, range.end.column);
910
        }
911
        return lines;
912
    };
913
    this.insertLines = function(row, lines) {
914
        console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead.");
915
        return this.insertFullLines(row, lines);
916
    };
917
    this.removeLines = function(firstRow, lastRow) {
918
        console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead.");
919
        return this.removeFullLines(firstRow, lastRow);
920
    };
921
    this.insertNewLine = function(position) {
922
        console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead.");
923
        return this.insertMergedLines(position, ["", ""]);
924
    };
925
    this.insert = function(position, text) {
926
        if (this.getLength() <= 1)
927
            this.$detectNewLine(text);
928
        
929
        return this.insertMergedLines(position, this.$split(text));
930
    };
931
    this.insertInLine = function(position, text) {
932
        var start = this.clippedPos(position.row, position.column);
933
        var end = this.pos(position.row, position.column + text.length);
934
        
935
        this.applyDelta({
936
            start: start,
937
            end: end,
938
            action: "insert",
939
            lines: [text]
940
        }, true);
941
        
942
        return this.clonePos(end);
943
    };
944
    
945
    this.clippedPos = function(row, column) {
946
        var length = this.getLength();
947
        if (row === undefined) {
948
            row = length;
949
        } else if (row < 0) {
950
            row = 0;
951
        } else if (row >= length) {
952
            row = length - 1;
953
            column = undefined;
954
        }
955
        var line = this.getLine(row);
956
        if (column == undefined)
957
            column = line.length;
958
        column = Math.min(Math.max(column, 0), line.length);
959
        return {row: row, column: column};
960
    };
961
    
962
    this.clonePos = function(pos) {
963
        return {row: pos.row, column: pos.column};
964
    };
965
    
966
    this.pos = function(row, column) {
967
        return {row: row, column: column};
968
    };
969
    
970
    this.$clipPosition = function(position) {
971
        var length = this.getLength();
972
        if (position.row >= length) {
973
            position.row = Math.max(0, length - 1);
974
            position.column = this.getLine(length - 1).length;
975
        } else {
976
            position.row = Math.max(0, position.row);
977
            position.column = Math.min(Math.max(position.column, 0), this.getLine(position.row).length);
978
        }
979
        return position;
980
    };
981
    this.insertFullLines = function(row, lines) {
982
        row = Math.min(Math.max(row, 0), this.getLength());
983
        var column = 0;
984
        if (row < this.getLength()) {
985
            lines = lines.concat([""]);
986
            column = 0;
987
        } else {
988
            lines = [""].concat(lines);
989
            row--;
990
            column = this.$lines[row].length;
991
        }
992
        this.insertMergedLines({row: row, column: column}, lines);
993
    };    
994
    this.insertMergedLines = function(position, lines) {
995
        var start = this.clippedPos(position.row, position.column);
996
        var end = {
997
            row: start.row + lines.length - 1,
998
            column: (lines.length == 1 ? start.column : 0) + lines[lines.length - 1].length
999
        };
1000
        
1001
        this.applyDelta({
1002
            start: start,
1003
            end: end,
1004
            action: "insert",
1005
            lines: lines
1006
        });
1007
        
1008
        return this.clonePos(end);
1009
    };
1010
    this.remove = function(range) {
1011
        var start = this.clippedPos(range.start.row, range.start.column);
1012
        var end = this.clippedPos(range.end.row, range.end.column);
1013
        this.applyDelta({
1014
            start: start,
1015
            end: end,
1016
            action: "remove",
1017
            lines: this.getLinesForRange({start: start, end: end})
1018
        });
1019
        return this.clonePos(start);
1020
    };
1021
    this.removeInLine = function(row, startColumn, endColumn) {
1022
        var start = this.clippedPos(row, startColumn);
1023
        var end = this.clippedPos(row, endColumn);
1024
        
1025
        this.applyDelta({
1026
            start: start,
1027
            end: end,
1028
            action: "remove",
1029
            lines: this.getLinesForRange({start: start, end: end})
1030
        }, true);
1031
        
1032
        return this.clonePos(start);
1033
    };
1034
    this.removeFullLines = function(firstRow, lastRow) {
1035
        firstRow = Math.min(Math.max(0, firstRow), this.getLength() - 1);
1036
        lastRow  = Math.min(Math.max(0, lastRow ), this.getLength() - 1);
1037
        var deleteFirstNewLine = lastRow == this.getLength() - 1 && firstRow > 0;
1038
        var deleteLastNewLine  = lastRow  < this.getLength() - 1;
1039
        var startRow = ( deleteFirstNewLine ? firstRow - 1                  : firstRow                    );
1040
        var startCol = ( deleteFirstNewLine ? this.getLine(startRow).length : 0                           );
1041
        var endRow   = ( deleteLastNewLine  ? lastRow + 1                   : lastRow                     );
1042
        var endCol   = ( deleteLastNewLine  ? 0                             : this.getLine(endRow).length ); 
1043
        var range = new Range(startRow, startCol, endRow, endCol);
1044
        var deletedLines = this.$lines.slice(firstRow, lastRow + 1);
1045
        
1046
        this.applyDelta({
1047
            start: range.start,
1048
            end: range.end,
1049
            action: "remove",
1050
            lines: this.getLinesForRange(range)
1051
        });
1052
        return deletedLines;
1053
    };
1054
    this.removeNewLine = function(row) {
1055
        if (row < this.getLength() - 1 && row >= 0) {
1056
            this.applyDelta({
1057
                start: this.pos(row, this.getLine(row).length),
1058
                end: this.pos(row + 1, 0),
1059
                action: "remove",
1060
                lines: ["", ""]
1061
            });
1062
        }
1063
    };
1064
    this.replace = function(range, text) {
1065
        if (!(range instanceof Range))
1066
            range = Range.fromPoints(range.start, range.end);
1067
        if (text.length === 0 && range.isEmpty())
1068
            return range.start;
1069
        if (text == this.getTextRange(range))
1070
            return range.end;
1071

    
1072
        this.remove(range);
1073
        var end;
1074
        if (text) {
1075
            end = this.insert(range.start, text);
1076
        }
1077
        else {
1078
            end = range.start;
1079
        }
1080
        
1081
        return end;
1082
    };
1083
    this.applyDeltas = function(deltas) {
1084
        for (var i=0; i<deltas.length; i++) {
1085
            this.applyDelta(deltas[i]);
1086
        }
1087
    };
1088
    this.revertDeltas = function(deltas) {
1089
        for (var i=deltas.length-1; i>=0; i--) {
1090
            this.revertDelta(deltas[i]);
1091
        }
1092
    };
1093
    this.applyDelta = function(delta, doNotValidate) {
1094
        var isInsert = delta.action == "insert";
1095
        if (isInsert ? delta.lines.length <= 1 && !delta.lines[0]
1096
            : !Range.comparePoints(delta.start, delta.end)) {
1097
            return;
1098
        }
1099
        
1100
        if (isInsert && delta.lines.length > 20000) {
1101
            this.$splitAndapplyLargeDelta(delta, 20000);
1102
        }
1103
        else {
1104
            applyDelta(this.$lines, delta, doNotValidate);
1105
            this._signal("change", delta);
1106
        }
1107
    };
1108
    
1109
    this.$safeApplyDelta = function(delta) {
1110
        var docLength = this.$lines.length;
1111
        if (
1112
            delta.action == "remove" && delta.start.row < docLength && delta.end.row < docLength
1113
            || delta.action == "insert" && delta.start.row <= docLength
1114
        ) {
1115
            this.applyDelta(delta);
1116
        }
1117
    };
1118
    
1119
    this.$splitAndapplyLargeDelta = function(delta, MAX) {
1120
        var lines = delta.lines;
1121
        var l = lines.length - MAX + 1;
1122
        var row = delta.start.row; 
1123
        var column = delta.start.column;
1124
        for (var from = 0, to = 0; from < l; from = to) {
1125
            to += MAX - 1;
1126
            var chunk = lines.slice(from, to);
1127
            chunk.push("");
1128
            this.applyDelta({
1129
                start: this.pos(row + from, column),
1130
                end: this.pos(row + to, column = 0),
1131
                action: delta.action,
1132
                lines: chunk
1133
            }, true);
1134
        }
1135
        delta.lines = lines.slice(from);
1136
        delta.start.row = row + from;
1137
        delta.start.column = column;
1138
        this.applyDelta(delta, true);
1139
    };
1140
    this.revertDelta = function(delta) {
1141
        this.$safeApplyDelta({
1142
            start: this.clonePos(delta.start),
1143
            end: this.clonePos(delta.end),
1144
            action: (delta.action == "insert" ? "remove" : "insert"),
1145
            lines: delta.lines.slice()
1146
        });
1147
    };
1148
    this.indexToPosition = function(index, startRow) {
1149
        var lines = this.$lines || this.getAllLines();
1150
        var newlineLength = this.getNewLineCharacter().length;
1151
        for (var i = startRow || 0, l = lines.length; i < l; i++) {
1152
            index -= lines[i].length + newlineLength;
1153
            if (index < 0)
1154
                return {row: i, column: index + lines[i].length + newlineLength};
1155
        }
1156
        return {row: l-1, column: index + lines[l-1].length + newlineLength};
1157
    };
1158
    this.positionToIndex = function(pos, startRow) {
1159
        var lines = this.$lines || this.getAllLines();
1160
        var newlineLength = this.getNewLineCharacter().length;
1161
        var index = 0;
1162
        var row = Math.min(pos.row, lines.length);
1163
        for (var i = startRow || 0; i < row; ++i)
1164
            index += lines[i].length + newlineLength;
1165

    
1166
        return index + pos.column;
1167
    };
1168

    
1169
}).call(Document.prototype);
1170

    
1171
exports.Document = Document;
1172
});
1173

    
1174
ace.define("ace/lib/lang",[], function(require, exports, module) {
1175
"use strict";
1176

    
1177
exports.last = function(a) {
1178
    return a[a.length - 1];
1179
};
1180

    
1181
exports.stringReverse = function(string) {
1182
    return string.split("").reverse().join("");
1183
};
1184

    
1185
exports.stringRepeat = function (string, count) {
1186
    var result = '';
1187
    while (count > 0) {
1188
        if (count & 1)
1189
            result += string;
1190

    
1191
        if (count >>= 1)
1192
            string += string;
1193
    }
1194
    return result;
1195
};
1196

    
1197
var trimBeginRegexp = /^\s\s*/;
1198
var trimEndRegexp = /\s\s*$/;
1199

    
1200
exports.stringTrimLeft = function (string) {
1201
    return string.replace(trimBeginRegexp, '');
1202
};
1203

    
1204
exports.stringTrimRight = function (string) {
1205
    return string.replace(trimEndRegexp, '');
1206
};
1207

    
1208
exports.copyObject = function(obj) {
1209
    var copy = {};
1210
    for (var key in obj) {
1211
        copy[key] = obj[key];
1212
    }
1213
    return copy;
1214
};
1215

    
1216
exports.copyArray = function(array){
1217
    var copy = [];
1218
    for (var i=0, l=array.length; i<l; i++) {
1219
        if (array[i] && typeof array[i] == "object")
1220
            copy[i] = this.copyObject(array[i]);
1221
        else 
1222
            copy[i] = array[i];
1223
    }
1224
    return copy;
1225
};
1226

    
1227
exports.deepCopy = function deepCopy(obj) {
1228
    if (typeof obj !== "object" || !obj)
1229
        return obj;
1230
    var copy;
1231
    if (Array.isArray(obj)) {
1232
        copy = [];
1233
        for (var key = 0; key < obj.length; key++) {
1234
            copy[key] = deepCopy(obj[key]);
1235
        }
1236
        return copy;
1237
    }
1238
    if (Object.prototype.toString.call(obj) !== "[object Object]")
1239
        return obj;
1240
    
1241
    copy = {};
1242
    for (var key in obj)
1243
        copy[key] = deepCopy(obj[key]);
1244
    return copy;
1245
};
1246

    
1247
exports.arrayToMap = function(arr) {
1248
    var map = {};
1249
    for (var i=0; i<arr.length; i++) {
1250
        map[arr[i]] = 1;
1251
    }
1252
    return map;
1253

    
1254
};
1255

    
1256
exports.createMap = function(props) {
1257
    var map = Object.create(null);
1258
    for (var i in props) {
1259
        map[i] = props[i];
1260
    }
1261
    return map;
1262
};
1263
exports.arrayRemove = function(array, value) {
1264
  for (var i = 0; i <= array.length; i++) {
1265
    if (value === array[i]) {
1266
      array.splice(i, 1);
1267
    }
1268
  }
1269
};
1270

    
1271
exports.escapeRegExp = function(str) {
1272
    return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
1273
};
1274

    
1275
exports.escapeHTML = function(str) {
1276
    return ("" + str).replace(/&/g, "&#38;").replace(/"/g, "&#34;").replace(/'/g, "&#39;").replace(/</g, "&#60;");
1277
};
1278

    
1279
exports.getMatchOffsets = function(string, regExp) {
1280
    var matches = [];
1281

    
1282
    string.replace(regExp, function(str) {
1283
        matches.push({
1284
            offset: arguments[arguments.length-2],
1285
            length: str.length
1286
        });
1287
    });
1288

    
1289
    return matches;
1290
};
1291
exports.deferredCall = function(fcn) {
1292
    var timer = null;
1293
    var callback = function() {
1294
        timer = null;
1295
        fcn();
1296
    };
1297

    
1298
    var deferred = function(timeout) {
1299
        deferred.cancel();
1300
        timer = setTimeout(callback, timeout || 0);
1301
        return deferred;
1302
    };
1303

    
1304
    deferred.schedule = deferred;
1305

    
1306
    deferred.call = function() {
1307
        this.cancel();
1308
        fcn();
1309
        return deferred;
1310
    };
1311

    
1312
    deferred.cancel = function() {
1313
        clearTimeout(timer);
1314
        timer = null;
1315
        return deferred;
1316
    };
1317
    
1318
    deferred.isPending = function() {
1319
        return timer;
1320
    };
1321

    
1322
    return deferred;
1323
};
1324

    
1325

    
1326
exports.delayedCall = function(fcn, defaultTimeout) {
1327
    var timer = null;
1328
    var callback = function() {
1329
        timer = null;
1330
        fcn();
1331
    };
1332

    
1333
    var _self = function(timeout) {
1334
        if (timer == null)
1335
            timer = setTimeout(callback, timeout || defaultTimeout);
1336
    };
1337

    
1338
    _self.delay = function(timeout) {
1339
        timer && clearTimeout(timer);
1340
        timer = setTimeout(callback, timeout || defaultTimeout);
1341
    };
1342
    _self.schedule = _self;
1343

    
1344
    _self.call = function() {
1345
        this.cancel();
1346
        fcn();
1347
    };
1348

    
1349
    _self.cancel = function() {
1350
        timer && clearTimeout(timer);
1351
        timer = null;
1352
    };
1353

    
1354
    _self.isPending = function() {
1355
        return timer;
1356
    };
1357

    
1358
    return _self;
1359
};
1360
});
1361

    
1362
ace.define("ace/worker/mirror",[], function(require, exports, module) {
1363
"use strict";
1364

    
1365
var Range = require("../range").Range;
1366
var Document = require("../document").Document;
1367
var lang = require("../lib/lang");
1368
    
1369
var Mirror = exports.Mirror = function(sender) {
1370
    this.sender = sender;
1371
    var doc = this.doc = new Document("");
1372
    
1373
    var deferredUpdate = this.deferredUpdate = lang.delayedCall(this.onUpdate.bind(this));
1374
    
1375
    var _self = this;
1376
    sender.on("change", function(e) {
1377
        var data = e.data;
1378
        if (data[0].start) {
1379
            doc.applyDeltas(data);
1380
        } else {
1381
            for (var i = 0; i < data.length; i += 2) {
1382
                if (Array.isArray(data[i+1])) {
1383
                    var d = {action: "insert", start: data[i], lines: data[i+1]};
1384
                } else {
1385
                    var d = {action: "remove", start: data[i], end: data[i+1]};
1386
                }
1387
                doc.applyDelta(d, true);
1388
            }
1389
        }
1390
        if (_self.$timeout)
1391
            return deferredUpdate.schedule(_self.$timeout);
1392
        _self.onUpdate();
1393
    });
1394
};
1395

    
1396
(function() {
1397
    
1398
    this.$timeout = 500;
1399
    
1400
    this.setTimeout = function(timeout) {
1401
        this.$timeout = timeout;
1402
    };
1403
    
1404
    this.setValue = function(value) {
1405
        this.doc.setValue(value);
1406
        this.deferredUpdate.schedule(this.$timeout);
1407
    };
1408
    
1409
    this.getValue = function(callbackId) {
1410
        this.sender.callback(this.doc.getValue(), callbackId);
1411
    };
1412
    
1413
    this.onUpdate = function() {
1414
    };
1415
    
1416
    this.isPending = function() {
1417
        return this.deferredUpdate.isPending();
1418
    };
1419
    
1420
}).call(Mirror.prototype);
1421

    
1422
});
1423

    
1424
ace.define("ace/mode/lua/luaparse",[], function(require, exports, module) {
1425

    
1426
(function (root, name, factory) {
1427
   factory(exports)
1428
}(this, 'luaparse', function (exports) {
1429
  'use strict';
1430

    
1431
  exports.version = '0.1.4';
1432

    
1433
  var input, options, length;
1434
  var defaultOptions = exports.defaultOptions = {
1435
      wait: false
1436
    , comments: true
1437
    , scope: false
1438
    , locations: false
1439
    , ranges: false
1440
  };
1441

    
1442
  var EOF = 1, StringLiteral = 2, Keyword = 4, Identifier = 8
1443
    , NumericLiteral = 16, Punctuator = 32, BooleanLiteral = 64
1444
    , NilLiteral = 128, VarargLiteral = 256;
1445

    
1446
  exports.tokenTypes = { EOF: EOF, StringLiteral: StringLiteral
1447
    , Keyword: Keyword, Identifier: Identifier, NumericLiteral: NumericLiteral
1448
    , Punctuator: Punctuator, BooleanLiteral: BooleanLiteral
1449
    , NilLiteral: NilLiteral, VarargLiteral: VarargLiteral
1450
  };
1451

    
1452
  var errors = exports.errors = {
1453
      unexpected: 'Unexpected %1 \'%2\' near \'%3\''
1454
    , expected: '\'%1\' expected near \'%2\''
1455
    , expectedToken: '%1 expected near \'%2\''
1456
    , unfinishedString: 'unfinished string near \'%1\''
1457
    , malformedNumber: 'malformed number near \'%1\''
1458
  };
1459

    
1460
  var ast = exports.ast = {
1461
      labelStatement: function(label) {
1462
      return {
1463
          type: 'LabelStatement'
1464
        , label: label
1465
      };
1466
    }
1467

    
1468
    , breakStatement: function() {
1469
      return {
1470
          type: 'BreakStatement'
1471
      };
1472
    }
1473

    
1474
    , gotoStatement: function(label) {
1475
      return {
1476
          type: 'GotoStatement'
1477
        , label: label
1478
      };
1479
    }
1480

    
1481
    , returnStatement: function(args) {
1482
      return {
1483
          type: 'ReturnStatement'
1484
        , 'arguments': args
1485
      };
1486
    }
1487

    
1488
    , ifStatement: function(clauses) {
1489
      return {
1490
          type: 'IfStatement'
1491
        , clauses: clauses
1492
      };
1493
    }
1494
    , ifClause: function(condition, body) {
1495
      return {
1496
          type: 'IfClause'
1497
        , condition: condition
1498
        , body: body
1499
      };
1500
    }
1501
    , elseifClause: function(condition, body) {
1502
      return {
1503
          type: 'ElseifClause'
1504
        , condition: condition
1505
        , body: body
1506
      };
1507
    }
1508
    , elseClause: function(body) {
1509
      return {
1510
          type: 'ElseClause'
1511
        , body: body
1512
      };
1513
    }
1514

    
1515
    , whileStatement: function(condition, body) {
1516
      return {
1517
          type: 'WhileStatement'
1518
        , condition: condition
1519
        , body: body
1520
      };
1521
    }
1522

    
1523
    , doStatement: function(body) {
1524
      return {
1525
          type: 'DoStatement'
1526
        , body: body
1527
      };
1528
    }
1529

    
1530
    , repeatStatement: function(condition, body) {
1531
      return {
1532
          type: 'RepeatStatement'
1533
        , condition: condition
1534
        , body: body
1535
      };
1536
    }
1537

    
1538
    , localStatement: function(variables, init) {
1539
      return {
1540
          type: 'LocalStatement'
1541
        , variables: variables
1542
        , init: init
1543
      };
1544
    }
1545

    
1546
    , assignmentStatement: function(variables, init) {
1547
      return {
1548
          type: 'AssignmentStatement'
1549
        , variables: variables
1550
        , init: init
1551
      };
1552
    }
1553

    
1554
    , callStatement: function(expression) {
1555
      return {
1556
          type: 'CallStatement'
1557
        , expression: expression
1558
      };
1559
    }
1560

    
1561
    , functionStatement: function(identifier, parameters, isLocal, body) {
1562
      return {
1563
          type: 'FunctionDeclaration'
1564
        , identifier: identifier
1565
        , isLocal: isLocal
1566
        , parameters: parameters
1567
        , body: body
1568
      };
1569
    }
1570

    
1571
    , forNumericStatement: function(variable, start, end, step, body) {
1572
      return {
1573
          type: 'ForNumericStatement'
1574
        , variable: variable
1575
        , start: start
1576
        , end: end
1577
        , step: step
1578
        , body: body
1579
      };
1580
    }
1581

    
1582
    , forGenericStatement: function(variables, iterators, body) {
1583
      return {
1584
          type: 'ForGenericStatement'
1585
        , variables: variables
1586
        , iterators: iterators
1587
        , body: body
1588
      };
1589
    }
1590

    
1591
    , chunk: function(body) {
1592
      return {
1593
          type: 'Chunk'
1594
        , body: body
1595
      };
1596
    }
1597

    
1598
    , identifier: function(name) {
1599
      return {
1600
          type: 'Identifier'
1601
        , name: name
1602
      };
1603
    }
1604

    
1605
    , literal: function(type, value, raw) {
1606
      type = (type === StringLiteral) ? 'StringLiteral'
1607
        : (type === NumericLiteral) ? 'NumericLiteral'
1608
        : (type === BooleanLiteral) ? 'BooleanLiteral'
1609
        : (type === NilLiteral) ? 'NilLiteral'
1610
        : 'VarargLiteral';
1611

    
1612
      return {
1613
          type: type
1614
        , value: value
1615
        , raw: raw
1616
      };
1617
    }
1618

    
1619
    , tableKey: function(key, value) {
1620
      return {
1621
          type: 'TableKey'
1622
        , key: key
1623
        , value: value
1624
      };
1625
    }
1626
    , tableKeyString: function(key, value) {
1627
      return {
1628
          type: 'TableKeyString'
1629
        , key: key
1630
        , value: value
1631
      };
1632
    }
1633
    , tableValue: function(value) {
1634
      return {
1635
          type: 'TableValue'
1636
        , value: value
1637
      };
1638
    }
1639

    
1640

    
1641
    , tableConstructorExpression: function(fields) {
1642
      return {
1643
          type: 'TableConstructorExpression'
1644
        , fields: fields
1645
      };
1646
    }
1647
    , binaryExpression: function(operator, left, right) {
1648
      var type = ('and' === operator || 'or' === operator) ?
1649
        'LogicalExpression' :
1650
        'BinaryExpression';
1651

    
1652
      return {
1653
          type: type
1654
        , operator: operator
1655
        , left: left
1656
        , right: right
1657
      };
1658
    }
1659
    , unaryExpression: function(operator, argument) {
1660
      return {
1661
          type: 'UnaryExpression'
1662
        , operator: operator
1663
        , argument: argument
1664
      };
1665
    }
1666
    , memberExpression: function(base, indexer, identifier) {
1667
      return {
1668
          type: 'MemberExpression'
1669
        , indexer: indexer
1670
        , identifier: identifier
1671
        , base: base
1672
      };
1673
    }
1674

    
1675
    , indexExpression: function(base, index) {
1676
      return {
1677
          type: 'IndexExpression'
1678
        , base: base
1679
        , index: index
1680
      };
1681
    }
1682

    
1683
    , callExpression: function(base, args) {
1684
      return {
1685
          type: 'CallExpression'
1686
        , base: base
1687
        , 'arguments': args
1688
      };
1689
    }
1690

    
1691
    , tableCallExpression: function(base, args) {
1692
      return {
1693
          type: 'TableCallExpression'
1694
        , base: base
1695
        , 'arguments': args
1696
      };
1697
    }
1698

    
1699
    , stringCallExpression: function(base, argument) {
1700
      return {
1701
          type: 'StringCallExpression'
1702
        , base: base
1703
        , argument: argument
1704
      };
1705
    }
1706

    
1707
    , comment: function(value, raw) {
1708
      return {
1709
          type: 'Comment'
1710
        , value: value
1711
        , raw: raw
1712
      };
1713
    }
1714
  };
1715

    
1716
  function finishNode(node) {
1717
    if (trackLocations) {
1718
      var location = locations.pop();
1719
      location.complete();
1720
      if (options.locations) node.loc = location.loc;
1721
      if (options.ranges) node.range = location.range;
1722
    }
1723
    return node;
1724
  }
1725

    
1726
  var slice = Array.prototype.slice
1727
    , toString = Object.prototype.toString
1728
    , indexOf = function indexOf(array, element) {
1729
      for (var i = 0, length = array.length; i < length; i++) {
1730
        if (array[i] === element) return i;
1731
      }
1732
      return -1;
1733
    };
1734

    
1735
  function indexOfObject(array, property, element) {
1736
    for (var i = 0, length = array.length; i < length; i++) {
1737
      if (array[i][property] === element) return i;
1738
    }
1739
    return -1;
1740
  }
1741

    
1742
  function sprintf(format) {
1743
    var args = slice.call(arguments, 1);
1744
    format = format.replace(/%(\d)/g, function (match, index) {
1745
      return '' + args[index - 1] || '';
1746
    });
1747
    return format;
1748
  }
1749

    
1750
  function extend() {
1751
    var args = slice.call(arguments)
1752
      , dest = {}
1753
      , src, prop;
1754

    
1755
    for (var i = 0, length = args.length; i < length; i++) {
1756
      src = args[i];
1757
      for (prop in src) if (src.hasOwnProperty(prop)) {
1758
        dest[prop] = src[prop];
1759
      }
1760
    }
1761
    return dest;
1762
  }
1763

    
1764
  function raise(token) {
1765
    var message = sprintf.apply(null, slice.call(arguments, 1))
1766
      , error, col;
1767

    
1768
    if ('undefined' !== typeof token.line) {
1769
      col = token.range[0] - token.lineStart;
1770
      error = new SyntaxError(sprintf('[%1:%2] %3', token.line, col, message));
1771
      error.line = token.line;
1772
      error.index = token.range[0];
1773
      error.column = col;
1774
    } else {
1775
      col = index - lineStart + 1;
1776
      error = new SyntaxError(sprintf('[%1:%2] %3', line, col, message));
1777
      error.index = index;
1778
      error.line = line;
1779
      error.column = col;
1780
    }
1781
    throw error;
1782
  }
1783

    
1784
  function raiseUnexpectedToken(type, token) {
1785
    raise(token, errors.expectedToken, type, token.value);
1786
  }
1787

    
1788
  function unexpected(found, near) {
1789
    if ('undefined' === typeof near) near = lookahead.value;
1790
    if ('undefined' !== typeof found.type) {
1791
      var type;
1792
      switch (found.type) {
1793
        case StringLiteral:   type = 'string';      break;
1794
        case Keyword:         type = 'keyword';     break;
1795
        case Identifier:      type = 'identifier';  break;
1796
        case NumericLiteral:  type = 'number';      break;
1797
        case Punctuator:      type = 'symbol';      break;
1798
        case BooleanLiteral:  type = 'boolean';     break;
1799
        case NilLiteral:
1800
          return raise(found, errors.unexpected, 'symbol', 'nil', near);
1801
      }
1802
      return raise(found, errors.unexpected, type, found.value, near);
1803
    }
1804
    return raise(found, errors.unexpected, 'symbol', found, near);
1805
  }
1806

    
1807
  var index
1808
    , token
1809
    , previousToken
1810
    , lookahead
1811
    , comments
1812
    , tokenStart
1813
    , line
1814
    , lineStart;
1815

    
1816
  exports.lex = lex;
1817

    
1818
  function lex() {
1819
    skipWhiteSpace();
1820
    while (45 === input.charCodeAt(index) &&
1821
           45 === input.charCodeAt(index + 1)) {
1822
      scanComment();
1823
      skipWhiteSpace();
1824
    }
1825
    if (index >= length) return {
1826
        type : EOF
1827
      , value: '<eof>'
1828
      , line: line
1829
      , lineStart: lineStart
1830
      , range: [index, index]
1831
    };
1832

    
1833
    var charCode = input.charCodeAt(index)
1834
      , next = input.charCodeAt(index + 1);
1835
    tokenStart = index;
1836
    if (isIdentifierStart(charCode)) return scanIdentifierOrKeyword();
1837

    
1838
    switch (charCode) {
1839
      case 39: case 34: // '"
1840
        return scanStringLiteral();
1841
      case 48: case 49: case 50: case 51: case 52: case 53:
1842
      case 54: case 55: case 56: case 57:
1843
        return scanNumericLiteral();
1844

    
1845
      case 46: // .
1846
        if (isDecDigit(next)) return scanNumericLiteral();
1847
        if (46 === next) {
1848
          if (46 === input.charCodeAt(index + 2)) return scanVarargLiteral();
1849
          return scanPunctuator('..');
1850
        }
1851
        return scanPunctuator('.');
1852

    
1853
      case 61: // =
1854
        if (61 === next) return scanPunctuator('==');
1855
        return scanPunctuator('=');
1856

    
1857
      case 62: // >
1858
        if (61 === next) return scanPunctuator('>=');
1859
        return scanPunctuator('>');
1860

    
1861
      case 60: // <
1862
        if (61 === next) return scanPunctuator('<=');
1863
        return scanPunctuator('<');
1864

    
1865
      case 126: // ~
1866
        if (61 === next) return scanPunctuator('~=');
1867
        return scanPunctuator('~');
1868

    
1869
      case 58: // :
1870
        if (58 === next) return scanPunctuator('::');
1871
        return scanPunctuator(':');
1872

    
1873
      case 91: // [
1874
        if (91 === next || 61 === next) return scanLongStringLiteral();
1875
        return scanPunctuator('[');
1876
      case 42: case 47: case 94: case 37: case 44: case 123: case 125:
1877
      case 93: case 40: case 41: case 59: case 35: case 45: case 43: case 38: case 124:
1878
        return scanPunctuator(input.charAt(index));
1879
    }
1880

    
1881
    return unexpected(input.charAt(index));
1882
  }
1883

    
1884
  function skipWhiteSpace() {
1885
    while (index < length) {
1886
      var charCode = input.charCodeAt(index);
1887
      if (isWhiteSpace(charCode)) {
1888
        index++;
1889
      } else if (isLineTerminator(charCode)) {
1890
        line++;
1891
        lineStart = ++index;
1892
      } else {
1893
        break;
1894
      }
1895
    }
1896
  }
1897

    
1898
  function scanIdentifierOrKeyword() {
1899
    var value, type;
1900
    while (isIdentifierPart(input.charCodeAt(++index)));
1901
    value = input.slice(tokenStart, index);
1902
    if (isKeyword(value)) {
1903
      type = Keyword;
1904
    } else if ('true' === value || 'false' === value) {
1905
      type = BooleanLiteral;
1906
      value = ('true' === value);
1907
    } else if ('nil' === value) {
1908
      type = NilLiteral;
1909
      value = null;
1910
    } else {
1911
      type = Identifier;
1912
    }
1913

    
1914
    return {
1915
        type: type
1916
      , value: value
1917
      , line: line
1918
      , lineStart: lineStart
1919
      , range: [tokenStart, index]
1920
    };
1921
  }
1922

    
1923
  function scanPunctuator(value) {
1924
    index += value.length;
1925
    return {
1926
        type: Punctuator
1927
      , value: value
1928
      , line: line
1929
      , lineStart: lineStart
1930
      , range: [tokenStart, index]
1931
    };
1932
  }
1933

    
1934
  function scanVarargLiteral() {
1935
    index += 3;
1936
    return {
1937
        type: VarargLiteral
1938
      , value: '...'
1939
      , line: line
1940
      , lineStart: lineStart
1941
      , range: [tokenStart, index]
1942
    };
1943
  }
1944

    
1945
  function scanStringLiteral() {
1946
    var delimiter = input.charCodeAt(index++)
1947
      , stringStart = index
1948
      , string = ''
1949
      , charCode;
1950

    
1951
    while (index < length) {
1952
      charCode = input.charCodeAt(index++);
1953
      if (delimiter === charCode) break;
1954
      if (92 === charCode) { // \
1955
        string += input.slice(stringStart, index - 1) + readEscapeSequence();
1956
        stringStart = index;
1957
      }
1958
      else if (index >= length || isLineTerminator(charCode)) {
1959
        string += input.slice(stringStart, index - 1);
1960
        raise({}, errors.unfinishedString, string + String.fromCharCode(charCode));
1961
      }
1962
    }
1963
    string += input.slice(stringStart, index - 1);
1964

    
1965
    return {
1966
        type: StringLiteral
1967
      , value: string
1968
      , line: line
1969
      , lineStart: lineStart
1970
      , range: [tokenStart, index]
1971
    };
1972
  }
1973

    
1974
  function scanLongStringLiteral() {
1975
    var string = readLongString();
1976
    if (false === string) raise(token, errors.expected, '[', token.value);
1977

    
1978
    return {
1979
        type: StringLiteral
1980
      , value: string
1981
      , line: line
1982
      , lineStart: lineStart
1983
      , range: [tokenStart, index]
1984
    };
1985
  }
1986

    
1987
  function scanNumericLiteral() {
1988
    var character = input.charAt(index)
1989
      , next = input.charAt(index + 1);
1990

    
1991
    var value = ('0' === character && 'xX'.indexOf(next || null) >= 0) ?
1992
      readHexLiteral() : readDecLiteral();
1993

    
1994
    return {
1995
        type: NumericLiteral
1996
      , value: value
1997
      , line: line
1998
      , lineStart: lineStart
1999
      , range: [tokenStart, index]
2000
    };
2001
  }
2002

    
2003
  function readHexLiteral() {
2004
    var fraction = 0 // defaults to 0 as it gets summed
2005
      , binaryExponent = 1 // defaults to 1 as it gets multiplied
2006
      , binarySign = 1 // positive
2007
      , digit, fractionStart, exponentStart, digitStart;
2008

    
2009
    digitStart = index += 2; // Skip 0x part
2010
    if (!isHexDigit(input.charCodeAt(index)))
2011
      raise({}, errors.malformedNumber, input.slice(tokenStart, index));
2012

    
2013
    while (isHexDigit(input.charCodeAt(index))) index++;
2014
    digit = parseInt(input.slice(digitStart, index), 16);
2015
    if ('.' === input.charAt(index)) {
2016
      fractionStart = ++index;
2017

    
2018
      while (isHexDigit(input.charCodeAt(index))) index++;
2019
      fraction = input.slice(fractionStart, index);
2020
      fraction = (fractionStart === index) ? 0
2021
        : parseInt(fraction, 16) / Math.pow(16, index - fractionStart);
2022
    }
2023
    if ('pP'.indexOf(input.charAt(index) || null) >= 0) {
2024
      index++;
2025
      if ('+-'.indexOf(input.charAt(index) || null) >= 0)
2026
        binarySign = ('+' === input.charAt(index++)) ? 1 : -1;
2027

    
2028
      exponentStart = index;
2029
      if (!isDecDigit(input.charCodeAt(index)))
2030
        raise({}, errors.malformedNumber, input.slice(tokenStart, index));
2031

    
2032
      while (isDecDigit(input.charCodeAt(index))) index++;
2033
      binaryExponent = input.slice(exponentStart, index);
2034
      binaryExponent = Math.pow(2, binaryExponent * binarySign);
2035
    }
2036

    
2037
    return (digit + fraction) * binaryExponent;
2038
  }
2039

    
2040
  function readDecLiteral() {
2041
    while (isDecDigit(input.charCodeAt(index))) index++;
2042
    if ('.' === input.charAt(index)) {
2043
      index++;
2044
      while (isDecDigit(input.charCodeAt(index))) index++;
2045
    }
2046
    if ('eE'.indexOf(input.charAt(index) || null) >= 0) {
2047
      index++;
2048
      if ('+-'.indexOf(input.charAt(index) || null) >= 0) index++;
2049
      if (!isDecDigit(input.charCodeAt(index)))
2050
        raise({}, errors.malformedNumber, input.slice(tokenStart, index));
2051

    
2052
      while (isDecDigit(input.charCodeAt(index))) index++;
2053
    }
2054

    
2055
    return parseFloat(input.slice(tokenStart, index));
2056
  }
2057

    
2058
  function readEscapeSequence() {
2059
    var sequenceStart = index;
2060
    switch (input.charAt(index)) {
2061
      case 'n': index++; return '\n';
2062
      case 'r': index++; return '\r';
2063
      case 't': index++; return '\t';
2064
      case 'v': index++; return '\x0B';
2065
      case 'b': index++; return '\b';
2066
      case 'f': index++; return '\f';
2067
      case 'z': index++; skipWhiteSpace(); return '';
2068
      case 'x':
2069
        if (isHexDigit(input.charCodeAt(index + 1)) &&
2070
            isHexDigit(input.charCodeAt(index + 2))) {
2071
          index += 3;
2072
          return '\\' + input.slice(sequenceStart, index);
2073
        }
2074
        return '\\' + input.charAt(index++);
2075
      default:
2076
        if (isDecDigit(input.charCodeAt(index))) {
2077
          while (isDecDigit(input.charCodeAt(++index)));
2078
          return '\\' + input.slice(sequenceStart, index);
2079
        }
2080
        return input.charAt(index++);
2081
    }
2082
  }
2083

    
2084
  function scanComment() {
2085
    tokenStart = index;
2086
    index += 2; // --
2087

    
2088
    var character = input.charAt(index)
2089
      , content = ''
2090
      , isLong = false
2091
      , commentStart = index
2092
      , lineStartComment = lineStart
2093
      , lineComment = line;
2094

    
2095
    if ('[' === character) {
2096
      content = readLongString();
2097
      if (false === content) content = character;
2098
      else isLong = true;
2099
    }
2100
    if (!isLong) {
2101
      while (index < length) {
2102
        if (isLineTerminator(input.charCodeAt(index))) break;
2103
        index++;
2104
      }
2105
      if (options.comments) content = input.slice(commentStart, index);
2106
    }
2107

    
2108
    if (options.comments) {
2109
      var node = ast.comment(content, input.slice(tokenStart, index));
2110
      if (options.locations) {
2111
        node.loc = {
2112
            start: { line: lineComment, column: tokenStart - lineStartComment }
2113
          , end: { line: line, column: index - lineStart }
2114
        };
2115
      }
2116
      if (options.ranges) {
2117
        node.range = [tokenStart, index];
2118
      }
2119
      comments.push(node);
2120
    }
2121
  }
2122

    
2123
  function readLongString() {
2124
    var level = 0
2125
      , content = ''
2126
      , terminator = false
2127
      , character, stringStart;
2128

    
2129
    index++; // [
2130
    while ('=' === input.charAt(index + level)) level++;
2131
    if ('[' !== input.charAt(index + level)) return false;
2132

    
2133
    index += level + 1;
2134
    if (isLineTerminator(input.charCodeAt(index))) {
2135
      line++;
2136
      lineStart = index++;
2137
    }
2138

    
2139
    stringStart = index;
2140
    while (index < length) {
2141
      character = input.charAt(index++);
2142
      if (isLineTerminator(character.charCodeAt(0))) {
2143
        line++;
2144
        lineStart = index;
2145
      }
2146
      if (']' === character) {
2147
        terminator = true;
2148
        for (var i = 0; i < level; i++) {
2149
          if ('=' !== input.charAt(index + i)) terminator = false;
2150
        }
2151
        if (']' !== input.charAt(index + level)) terminator = false;
2152
      }
2153
      if (terminator) break;
2154
    }
2155
    content += input.slice(stringStart, index - 1);
2156
    index += level + 1;
2157

    
2158
    return content;
2159
  }
2160

    
2161
  function next() {
2162
    previousToken = token;
2163
    token = lookahead;
2164
    lookahead = lex();
2165
  }
2166

    
2167
  function consume(value) {
2168
    if (value === token.value) {
2169
      next();
2170
      return true;
2171
    }
2172
    return false;
2173
  }
2174

    
2175
  function expect(value) {
2176
    if (value === token.value) next();
2177
    else raise(token, errors.expected, value, token.value);
2178
  }
2179

    
2180
  function isWhiteSpace(charCode) {
2181
    return 9 === charCode || 32 === charCode || 0xB === charCode || 0xC === charCode;
2182
  }
2183

    
2184
  function isLineTerminator(charCode) {
2185
    return 10 === charCode || 13 === charCode;
2186
  }
2187

    
2188
  function isDecDigit(charCode) {
2189
    return charCode >= 48 && charCode <= 57;
2190
  }
2191

    
2192
  function isHexDigit(charCode) {
2193
    return (charCode >= 48 && charCode <= 57) || (charCode >= 97 && charCode <= 102) || (charCode >= 65 && charCode <= 70);
2194
  }
2195

    
2196
  function isIdentifierStart(charCode) {
2197
    return (charCode >= 65 && charCode <= 90) || (charCode >= 97 && charCode <= 122) || 95 === charCode;
2198
  }
2199

    
2200
  function isIdentifierPart(charCode) {
2201
    return (charCode >= 65 && charCode <= 90) || (charCode >= 97 && charCode <= 122) || 95 === charCode || (charCode >= 48 && charCode <= 57);
2202
  }
2203

    
2204
  function isKeyword(id) {
2205
    switch (id.length) {
2206
      case 2:
2207
        return 'do' === id || 'if' === id || 'in' === id || 'or' === id;
2208
      case 3:
2209
        return 'and' === id || 'end' === id || 'for' === id || 'not' === id;
2210
      case 4:
2211
        return 'else' === id || 'goto' === id || 'then' === id;
2212
      case 5:
2213
        return 'break' === id || 'local' === id || 'until' === id || 'while' === id;
2214
      case 6:
2215
        return 'elseif' === id || 'repeat' === id || 'return' === id;
2216
      case 8:
2217
        return 'function' === id;
2218
    }
2219
    return false;
2220
  }
2221

    
2222
  function isUnary(token) {
2223
    if (Punctuator === token.type) return '#-~'.indexOf(token.value) >= 0;
2224
    if (Keyword === token.type) return 'not' === token.value;
2225
    return false;
2226
  }
2227
  function isCallExpression(expression) {
2228
    switch (expression.type) {
2229
      case 'CallExpression':
2230
      case 'TableCallExpression':
2231
      case 'StringCallExpression':
2232
        return true;
2233
    }
2234
    return false;
2235
  }
2236

    
2237
  function isBlockFollow(token) {
2238
    if (EOF === token.type) return true;
2239
    if (Keyword !== token.type) return false;
2240
    switch (token.value) {
2241
      case 'else': case 'elseif':
2242
      case 'end': case 'until':
2243
        return true;
2244
      default:
2245
        return false;
2246
    }
2247
  }
2248
  var scopes
2249
    , scopeDepth
2250
    , globals;
2251
  function createScope() {
2252
    scopes.push(Array.apply(null, scopes[scopeDepth++]));
2253
  }
2254
  function exitScope() {
2255
    scopes.pop();
2256
    scopeDepth--;
2257
  }
2258
  function scopeIdentifierName(name) {
2259
    if (-1 !== indexOf(scopes[scopeDepth], name)) return;
2260
    scopes[scopeDepth].push(name);
2261
  }
2262
  function scopeIdentifier(node) {
2263
    scopeIdentifierName(node.name);
2264
    attachScope(node, true);
2265
  }
2266
  function attachScope(node, isLocal) {
2267
    if (!isLocal && -1 === indexOfObject(globals, 'name', node.name))
2268
      globals.push(node);
2269

    
2270
    node.isLocal = isLocal;
2271
  }
2272
  function scopeHasName(name) {
2273
    return (-1 !== indexOf(scopes[scopeDepth], name));
2274
  }
2275

    
2276
  var locations = []
2277
    , trackLocations;
2278

    
2279
  function createLocationMarker() {
2280
    return new Marker(token);
2281
  }
2282

    
2283
  function Marker(token) {
2284
    if (options.locations) {
2285
      this.loc = {
2286
          start: {
2287
            line: token.line
2288
          , column: token.range[0] - token.lineStart
2289
        }
2290
        , end: {
2291
            line: 0
2292
          , column: 0
2293
        }
2294
      };
2295
    }
2296
    if (options.ranges) this.range = [token.range[0], 0];
2297
  }
2298
  Marker.prototype.complete = function() {
2299
    if (options.locations) {
2300
      this.loc.end.line = previousToken.line;
2301
      this.loc.end.column = previousToken.range[1] - previousToken.lineStart;
2302
    }
2303
    if (options.ranges) {
2304
      this.range[1] = previousToken.range[1];
2305
    }
2306
  };
2307
  function markLocation() {
2308
    if (trackLocations) locations.push(createLocationMarker());
2309
  }
2310
  function pushLocation(marker) {
2311
    if (trackLocations) locations.push(marker);
2312
  }
2313

    
2314
  function parseChunk() {
2315
    next();
2316
    markLocation();
2317
    var body = parseBlock();
2318
    if (EOF !== token.type) unexpected(token);
2319
    if (trackLocations && !body.length) previousToken = token;
2320
    return finishNode(ast.chunk(body));
2321
  }
2322

    
2323
  function parseBlock(terminator) {
2324
    var block = []
2325
      , statement;
2326
    if (options.scope) createScope();
2327

    
2328
    while (!isBlockFollow(token)) {
2329
      if ('return' === token.value) {
2330
        block.push(parseStatement());
2331
        break;
2332
      }
2333
      statement = parseStatement();
2334
      if (statement) block.push(statement);
2335
    }
2336

    
2337
    if (options.scope) exitScope();
2338
    return block;
2339
  }
2340

    
2341
  function parseStatement() {
2342
    markLocation();
2343
    if (Keyword === token.type) {
2344
      switch (token.value) {
2345
        case 'local':    next(); return parseLocalStatement();
2346
        case 'if':       next(); return parseIfStatement();
2347
        case 'return':   next(); return parseReturnStatement();
2348
        case 'function': next();
2349
          var name = parseFunctionName();
2350
          return parseFunctionDeclaration(name);
2351
        case 'while':    next(); return parseWhileStatement();
2352
        case 'for':      next(); return parseForStatement();
2353
        case 'repeat':   next(); return parseRepeatStatement();
2354
        case 'break':    next(); return parseBreakStatement();
2355
        case 'do':       next(); return parseDoStatement();
2356
        case 'goto':     next(); return parseGotoStatement();
2357
      }
2358
    }
2359

    
2360
    if (Punctuator === token.type) {
2361
      if (consume('::')) return parseLabelStatement();
2362
    }
2363
    if (trackLocations) locations.pop();
2364
    if (consume(';')) return;
2365

    
2366
    return parseAssignmentOrCallStatement();
2367
  }
2368

    
2369
  function parseLabelStatement() {
2370
    var name = token.value
2371
      , label = parseIdentifier();
2372

    
2373
    if (options.scope) {
2374
      scopeIdentifierName('::' + name + '::');
2375
      attachScope(label, true);
2376
    }
2377

    
2378
    expect('::');
2379
    return finishNode(ast.labelStatement(label));
2380
  }
2381

    
2382
  function parseBreakStatement() {
2383
    return finishNode(ast.breakStatement());
2384
  }
2385

    
2386
  function parseGotoStatement() {
2387
    var name = token.value
2388
      , label = parseIdentifier();
2389

    
2390
    if (options.scope) label.isLabel = scopeHasName('::' + name + '::');
2391
    return finishNode(ast.gotoStatement(label));
2392
  }
2393

    
2394
  function parseDoStatement() {
2395
    var body = parseBlock();
2396
    expect('end');
2397
    return finishNode(ast.doStatement(body));
2398
  }
2399

    
2400
  function parseWhileStatement() {
2401
    var condition = parseExpectedExpression();
2402
    expect('do');
2403
    var body = parseBlock();
2404
    expect('end');
2405
    return finishNode(ast.whileStatement(condition, body));
2406
  }
2407

    
2408
  function parseRepeatStatement() {
2409
    var body = parseBlock();
2410
    expect('until');
2411
    var condition = parseExpectedExpression();
2412
    return finishNode(ast.repeatStatement(condition, body));
2413
  }
2414

    
2415
  function parseReturnStatement() {
2416
    var expressions = [];
2417

    
2418
    if ('end' !== token.value) {
2419
      var expression = parseExpression();
2420
      if (null != expression) expressions.push(expression);
2421
      while (consume(',')) {
2422
        expression = parseExpectedExpression();
2423
        expressions.push(expression);
2424
      }
2425
      consume(';'); // grammar tells us ; is optional here.
2426
    }
2427
    return finishNode(ast.returnStatement(expressions));
2428
  }
2429

    
2430
  function parseIfStatement() {
2431
    var clauses = []
2432
      , condition
2433
      , body
2434
      , marker;
2435
    if (trackLocations) {
2436
      marker = locations[locations.length - 1];
2437
      locations.push(marker);
2438
    }
2439
    condition = parseExpectedExpression();
2440
    expect('then');
2441
    body = parseBlock();
2442
    clauses.push(finishNode(ast.ifClause(condition, body)));
2443

    
2444
    if (trackLocations) marker = createLocationMarker();
2445
    while (consume('elseif')) {
2446
      pushLocation(marker);
2447
      condition = parseExpectedExpression();
2448
      expect('then');
2449
      body = parseBlock();
2450
      clauses.push(finishNode(ast.elseifClause(condition, body)));
2451
      if (trackLocations) marker = createLocationMarker();
2452
    }
2453

    
2454
    if (consume('else')) {
2455
      if (trackLocations) {
2456
        marker = new Marker(previousToken);
2457
        locations.push(marker);
2458
      }
2459
      body = parseBlock();
2460
      clauses.push(finishNode(ast.elseClause(body)));
2461
    }
2462

    
2463
    expect('end');
2464
    return finishNode(ast.ifStatement(clauses));
2465
  }
2466

    
2467
  function parseForStatement() {
2468
    var variable = parseIdentifier()
2469
      , body;
2470
    if (options.scope) scopeIdentifier(variable);
2471
    if (consume('=')) {
2472
      var start = parseExpectedExpression();
2473
      expect(',');
2474
      var end = parseExpectedExpression();
2475
      var step = consume(',') ? parseExpectedExpression() : null;
2476

    
2477
      expect('do');
2478
      body = parseBlock();
2479
      expect('end');
2480

    
2481
      return finishNode(ast.forNumericStatement(variable, start, end, step, body));
2482
    }
2483
    else {
2484
      var variables = [variable];
2485
      while (consume(',')) {
2486
        variable = parseIdentifier();
2487
        if (options.scope) scopeIdentifier(variable);
2488
        variables.push(variable);
2489
      }
2490
      expect('in');
2491
      var iterators = [];
2492
      do {
2493
        var expression = parseExpectedExpression();
2494
        iterators.push(expression);
2495
      } while (consume(','));
2496

    
2497
      expect('do');
2498
      body = parseBlock();
2499
      expect('end');
2500

    
2501
      return finishNode(ast.forGenericStatement(variables, iterators, body));
2502
    }
2503
  }
2504

    
2505
  function parseLocalStatement() {
2506
    var name;
2507

    
2508
    if (Identifier === token.type) {
2509
      var variables = []
2510
        , init = [];
2511

    
2512
      do {
2513
        name = parseIdentifier();
2514

    
2515
        variables.push(name);
2516
      } while (consume(','));
2517

    
2518
      if (consume('=')) {
2519
        do {
2520
          var expression = parseExpectedExpression();
2521
          init.push(expression);
2522
        } while (consume(','));
2523
      }
2524
      if (options.scope) {
2525
        for (var i = 0, l = variables.length; i < l; i++) {
2526
          scopeIdentifier(variables[i]);
2527
        }
2528
      }
2529

    
2530
      return finishNode(ast.localStatement(variables, init));
2531
    }
2532
    if (consume('function')) {
2533
      name = parseIdentifier();
2534
      if (options.scope) scopeIdentifier(name);
2535
      return parseFunctionDeclaration(name, true);
2536
    } else {
2537
      raiseUnexpectedToken('<name>', token);
2538
    }
2539
  }
2540

    
2541
  function parseAssignmentOrCallStatement() {
2542
    var previous = token
2543
      , expression, marker;
2544

    
2545
    if (trackLocations) marker = createLocationMarker();
2546
    expression = parsePrefixExpression();
2547

    
2548
    if (null == expression) return unexpected(token);
2549
    if (',='.indexOf(token.value) >= 0) {
2550
      var variables = [expression]
2551
        , init = []
2552
        , exp;
2553

    
2554
      while (consume(',')) {
2555
        exp = parsePrefixExpression();
2556
        if (null == exp) raiseUnexpectedToken('<expression>', token);
2557
        variables.push(exp);
2558
      }
2559
      expect('=');
2560
      do {
2561
        exp = parseExpectedExpression();
2562
        init.push(exp);
2563
      } while (consume(','));
2564

    
2565
      pushLocation(marker);
2566
      return finishNode(ast.assignmentStatement(variables, init));
2567
    }
2568
    if (isCallExpression(expression)) {
2569
      pushLocation(marker);
2570
      return finishNode(ast.callStatement(expression));
2571
    }
2572
    return unexpected(previous);
2573
  }
2574

    
2575
  function parseIdentifier() {
2576
    markLocation();
2577
    var identifier = token.value;
2578
    if (Identifier !== token.type) raiseUnexpectedToken('<name>', token);
2579
    next();
2580
    return finishNode(ast.identifier(identifier));
2581
  }
2582

    
2583
  function parseFunctionDeclaration(name, isLocal) {
2584
    var parameters = [];
2585
    expect('(');
2586
    if (!consume(')')) {
2587
      while (true) {
2588
        if (Identifier === token.type) {
2589
          var parameter = parseIdentifier();
2590
          if (options.scope) scopeIdentifier(parameter);
2591

    
2592
          parameters.push(parameter);
2593

    
2594
          if (consume(',')) continue;
2595
          else if (consume(')')) break;
2596
        }
2597
        else if (VarargLiteral === token.type) {
2598
          parameters.push(parsePrimaryExpression());
2599
          expect(')');
2600
          break;
2601
        } else {
2602
          raiseUnexpectedToken('<name> or \'...\'', token);
2603
        }
2604
      }
2605
    }
2606

    
2607
    var body = parseBlock();
2608
    expect('end');
2609

    
2610
    isLocal = isLocal || false;
2611
    return finishNode(ast.functionStatement(name, parameters, isLocal, body));
2612
  }
2613

    
2614
  function parseFunctionName() {
2615
    var base, name, marker;
2616

    
2617
    if (trackLocations) marker = createLocationMarker();
2618
    base = parseIdentifier();
2619

    
2620
    if (options.scope) attachScope(base, false);
2621

    
2622
    while (consume('.')) {
2623
      pushLocation(marker);
2624
      name = parseIdentifier();
2625
      if (options.scope) attachScope(name, false);
2626
      base = finishNode(ast.memberExpression(base, '.', name));
2627
    }
2628

    
2629
    if (consume(':')) {
2630
      pushLocation(marker);
2631
      name = parseIdentifier();
2632
      if (options.scope) attachScope(name, false);
2633
      base = finishNode(ast.memberExpression(base, ':', name));
2634
    }
2635

    
2636
    return base;
2637
  }
2638

    
2639
  function parseTableConstructor() {
2640
    var fields = []
2641
      , key, value;
2642

    
2643
    while (true) {
2644
      markLocation();
2645
      if (Punctuator === token.type && consume('[')) {
2646
        key = parseExpectedExpression();
2647
        expect(']');
2648
        expect('=');
2649
        value = parseExpectedExpression();
2650
        fields.push(finishNode(ast.tableKey(key, value)));
2651
      } else if (Identifier === token.type) {
2652
        key = parseExpectedExpression();
2653
        if (consume('=')) {
2654
          value = parseExpectedExpression();
2655
          fields.push(finishNode(ast.tableKeyString(key, value)));
2656
        } else {
2657
          fields.push(finishNode(ast.tableValue(key)));
2658
        }
2659
      } else {
2660
        if (null == (value = parseExpression())) {
2661
          locations.pop();
2662
          break;
2663
        }
2664
        fields.push(finishNode(ast.tableValue(value)));
2665
      }
2666
      if (',;'.indexOf(token.value) >= 0) {
2667
        next();
2668
        continue;
2669
      }
2670
      if ('}' === token.value) break;
2671
    }
2672
    expect('}');
2673
    return finishNode(ast.tableConstructorExpression(fields));
2674
  }
2675

    
2676
  function parseExpression() {
2677
    var expression = parseSubExpression(0);
2678
    return expression;
2679
  }
2680

    
2681
  function parseExpectedExpression() {
2682
    var expression = parseExpression();
2683
    if (null == expression) raiseUnexpectedToken('<expression>', token);
2684
    else return expression;
2685
  }
2686

    
2687
  function binaryPrecedence(operator) {
2688
    var charCode = operator.charCodeAt(0)
2689
      , length = operator.length;
2690

    
2691
    if (1 === length) {
2692
      switch (charCode) {
2693
        case 94: return 10; // ^
2694
        case 42: case 47: case 37: return 7; // * / %
2695
        case 43: case 45: return 6; // + -
2696
        case 60: case 62: return 3; // < >
2697
        case 38: case 124: return 7; // & |
2698
      }
2699
    } else if (2 === length) {
2700
      switch (charCode) {
2701
        case 46: return 5; // ..
2702
        case 60: case 62: case 61: case 126: return 3; // <= >= == ~=
2703
        case 111: return 1; // or
2704
      }
2705
    } else if (97 === charCode && 'and' === operator) return 2;
2706
    return 0;
2707
  }
2708

    
2709
  function parseSubExpression(minPrecedence) {
2710
    var operator = token.value
2711
      , expression, marker;
2712

    
2713
    if (trackLocations) marker = createLocationMarker();
2714
    if (isUnary(token)) {
2715
      markLocation();
2716
      next();
2717
      var argument = parseSubExpression(8);
2718
      if (argument == null) raiseUnexpectedToken('<expression>', token);
2719
      expression = finishNode(ast.unaryExpression(operator, argument));
2720
    }
2721
    if (null == expression) {
2722
      expression = parsePrimaryExpression();
2723
      if (null == expression) {
2724
        expression = parsePrefixExpression();
2725
      }
2726
    }
2727
    if (null == expression) return null;
2728

    
2729
    var precedence;
2730
    while (true) {
2731
      operator = token.value;
2732

    
2733
      precedence = (Punctuator === token.type || Keyword === token.type) ?
2734
        binaryPrecedence(operator) : 0;
2735

    
2736
      if (precedence === 0 || precedence <= minPrecedence) break;
2737
      if ('^' === operator || '..' === operator) precedence--;
2738
      next();
2739
      var right = parseSubExpression(precedence);
2740
      if (null == right) raiseUnexpectedToken('<expression>', token);
2741
      if (trackLocations) locations.push(marker);
2742
      expression = finishNode(ast.binaryExpression(operator, expression, right));
2743

    
2744
    }
2745
    return expression;
2746
  }
2747

    
2748
  function parsePrefixExpression() {
2749
    var base, name, marker
2750
      , isLocal;
2751

    
2752
    if (trackLocations) marker = createLocationMarker();
2753
    if (Identifier === token.type) {
2754
      name = token.value;
2755
      base = parseIdentifier();
2756
      if (options.scope) attachScope(base, isLocal = scopeHasName(name));
2757
    } else if (consume('(')) {
2758
      base = parseExpectedExpression();
2759
      expect(')');
2760
      if (options.scope) isLocal = base.isLocal;
2761
    } else {
2762
      return null;
2763
    }
2764
    var expression, identifier;
2765
    while (true) {
2766
      if (Punctuator === token.type) {
2767
        switch (token.value) {
2768
          case '[':
2769
            pushLocation(marker);
2770
            next();
2771
            expression = parseExpectedExpression();
2772
            base = finishNode(ast.indexExpression(base, expression));
2773
            expect(']');
2774
            break;
2775
          case '.':
2776
            pushLocation(marker);
2777
            next();
2778
            identifier = parseIdentifier();
2779
            if (options.scope) attachScope(identifier, isLocal);
2780
            base = finishNode(ast.memberExpression(base, '.', identifier));
2781
            break;
2782
          case ':':
2783
            pushLocation(marker);
2784
            next();
2785
            identifier = parseIdentifier();
2786
            if (options.scope) attachScope(identifier, isLocal);
2787
            base = finishNode(ast.memberExpression(base, ':', identifier));
2788
            pushLocation(marker);
2789
            base = parseCallExpression(base);
2790
            break;
2791
          case '(': case '{': // args
2792
            pushLocation(marker);
2793
            base = parseCallExpression(base);
2794
            break;
2795
          default:
2796
            return base;
2797
        }
2798
      } else if (StringLiteral === token.type) {
2799
        pushLocation(marker);
2800
        base = parseCallExpression(base);
2801
      } else {
2802
        break;
2803
      }
2804
    }
2805

    
2806
    return base;
2807
  }
2808

    
2809
  function parseCallExpression(base) {
2810
    if (Punctuator === token.type) {
2811
      switch (token.value) {
2812
        case '(':
2813
          next();
2814
          var expressions = [];
2815
          var expression = parseExpression();
2816
          if (null != expression) expressions.push(expression);
2817
          while (consume(',')) {
2818
            expression = parseExpectedExpression();
2819
            expressions.push(expression);
2820
          }
2821

    
2822
          expect(')');
2823
          return finishNode(ast.callExpression(base, expressions));
2824

    
2825
        case '{':
2826
          markLocation();
2827
          next();
2828
          var table = parseTableConstructor();
2829
          return finishNode(ast.tableCallExpression(base, table));
2830
      }
2831
    } else if (StringLiteral === token.type) {
2832
      return finishNode(ast.stringCallExpression(base, parsePrimaryExpression()));
2833
    }
2834

    
2835
    raiseUnexpectedToken('function arguments', token);
2836
  }
2837

    
2838
  function parsePrimaryExpression() {
2839
    var literals = StringLiteral | NumericLiteral | BooleanLiteral | NilLiteral | VarargLiteral
2840
      , value = token.value
2841
      , type = token.type
2842
      , marker;
2843

    
2844
    if (trackLocations) marker = createLocationMarker();
2845

    
2846
    if (type & literals) {
2847
      pushLocation(marker);
2848
      var raw = input.slice(token.range[0], token.range[1]);
2849
      next();
2850
      return finishNode(ast.literal(type, value, raw));
2851
    } else if (Keyword === type && 'function' === value) {
2852
      pushLocation(marker);
2853
      next();
2854
      return parseFunctionDeclaration(null);
2855
    } else if (consume('{')) {
2856
      pushLocation(marker);
2857
      return parseTableConstructor();
2858
    }
2859
  }
2860

    
2861
  exports.parse = parse;
2862

    
2863
  function parse(_input, _options) {
2864
    if ('undefined' === typeof _options && 'object' === typeof _input) {
2865
      _options = _input;
2866
      _input = undefined;
2867
    }
2868
    if (!_options) _options = {};
2869

    
2870
    input = _input || '';
2871
    options = extend(defaultOptions, _options);
2872
    index = 0;
2873
    line = 1;
2874
    lineStart = 0;
2875
    length = input.length;
2876
    scopes = [[]];
2877
    scopeDepth = 0;
2878
    globals = [];
2879
    locations = [];
2880

    
2881
    if (options.comments) comments = [];
2882
    if (!options.wait) return end();
2883
    return exports;
2884
  }
2885
  exports.write = write;
2886

    
2887
  function write(_input) {
2888
    input += String(_input);
2889
    length = input.length;
2890
    return exports;
2891
  }
2892
  exports.end = end;
2893

    
2894
  function end(_input) {
2895
    if ('undefined' !== typeof _input) write(_input);
2896

    
2897
    length = input.length;
2898
    trackLocations = options.locations || options.ranges;
2899
    lookahead = lex();
2900

    
2901
    var chunk = parseChunk();
2902
    if (options.comments) chunk.comments = comments;
2903
    if (options.scope) chunk.globals = globals;
2904

    
2905
    if (locations.length > 0)
2906
      throw new Error('Location tracking failed. This is most likely a bug in luaparse');
2907

    
2908
    return chunk;
2909
  }
2910

    
2911
}));
2912

    
2913
});
2914

    
2915
ace.define("ace/mode/lua_worker",[], function(require, exports, module) {
2916
"use strict";
2917

    
2918
var oop = require("../lib/oop");
2919
var Mirror = require("../worker/mirror").Mirror;
2920
var luaparse = require("../mode/lua/luaparse");
2921

    
2922
var Worker = exports.Worker = function(sender) {
2923
    Mirror.call(this, sender);
2924
    this.setTimeout(500);
2925
};
2926

    
2927
oop.inherits(Worker, Mirror);
2928

    
2929
(function() {
2930

    
2931
    this.onUpdate = function() {
2932
        var value = this.doc.getValue();
2933
        var errors = [];
2934
        try {
2935
            luaparse.parse(value);
2936
        } catch(e) {
2937
            if (e instanceof SyntaxError) {
2938
                errors.push({
2939
                    row: e.line - 1,
2940
                    column: e.column,
2941
                    text: e.message,
2942
                    type: "error"
2943
                });
2944
            }
2945
        }
2946
        this.sender.emit("annotate", errors);
2947
    };
2948

    
2949
}).call(Worker.prototype);
2950

    
2951
});
2952

    
2953
ace.define("ace/lib/es5-shim",[], function(require, exports, module) {
2954

    
2955
function Empty() {}
2956

    
2957
if (!Function.prototype.bind) {
2958
    Function.prototype.bind = function bind(that) { // .length is 1
2959
        var target = this;
2960
        if (typeof target != "function") {
2961
            throw new TypeError("Function.prototype.bind called on incompatible " + target);
2962
        }
2963
        var args = slice.call(arguments, 1); // for normal call
2964
        var bound = function () {
2965

    
2966
            if (this instanceof bound) {
2967

    
2968
                var result = target.apply(
2969
                    this,
2970
                    args.concat(slice.call(arguments))
2971
                );
2972
                if (Object(result) === result) {
2973
                    return result;
2974
                }
2975
                return this;
2976

    
2977
            } else {
2978
                return target.apply(
2979
                    that,
2980
                    args.concat(slice.call(arguments))
2981
                );
2982

    
2983
            }
2984

    
2985
        };
2986
        if(target.prototype) {
2987
            Empty.prototype = target.prototype;
2988
            bound.prototype = new Empty();
2989
            Empty.prototype = null;
2990
        }
2991
        return bound;
2992
    };
2993
}
2994
var call = Function.prototype.call;
2995
var prototypeOfArray = Array.prototype;
2996
var prototypeOfObject = Object.prototype;
2997
var slice = prototypeOfArray.slice;
2998
var _toString = call.bind(prototypeOfObject.toString);
2999
var owns = call.bind(prototypeOfObject.hasOwnProperty);
3000
var defineGetter;
3001
var defineSetter;
3002
var lookupGetter;
3003
var lookupSetter;
3004
var supportsAccessors;
3005
if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
3006
    defineGetter = call.bind(prototypeOfObject.__defineGetter__);
3007
    defineSetter = call.bind(prototypeOfObject.__defineSetter__);
3008
    lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
3009
    lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
3010
}
3011
if ([1,2].splice(0).length != 2) {
3012
    if(function() { // test IE < 9 to splice bug - see issue #138
3013
        function makeArray(l) {
3014
            var a = new Array(l+2);
3015
            a[0] = a[1] = 0;
3016
            return a;
3017
        }
3018
        var array = [], lengthBefore;
3019
        
3020
        array.splice.apply(array, makeArray(20));
3021
        array.splice.apply(array, makeArray(26));
3022

    
3023
        lengthBefore = array.length; //46
3024
        array.splice(5, 0, "XXX"); // add one element
3025

    
3026
        lengthBefore + 1 == array.length
3027

    
3028
        if (lengthBefore + 1 == array.length) {
3029
            return true;// has right splice implementation without bugs
3030
        }
3031
    }()) {//IE 6/7
3032
        var array_splice = Array.prototype.splice;
3033
        Array.prototype.splice = function(start, deleteCount) {
3034
            if (!arguments.length) {
3035
                return [];
3036
            } else {
3037
                return array_splice.apply(this, [
3038
                    start === void 0 ? 0 : start,
3039
                    deleteCount === void 0 ? (this.length - start) : deleteCount
3040
                ].concat(slice.call(arguments, 2)))
3041
            }
3042
        };
3043
    } else {//IE8
3044
        Array.prototype.splice = function(pos, removeCount){
3045
            var length = this.length;
3046
            if (pos > 0) {
3047
                if (pos > length)
3048
                    pos = length;
3049
            } else if (pos == void 0) {
3050
                pos = 0;
3051
            } else if (pos < 0) {
3052
                pos = Math.max(length + pos, 0);
3053
            }
3054

    
3055
            if (!(pos+removeCount < length))
3056
                removeCount = length - pos;
3057

    
3058
            var removed = this.slice(pos, pos+removeCount);
3059
            var insert = slice.call(arguments, 2);
3060
            var add = insert.length;            
3061
            if (pos === length) {
3062
                if (add) {
3063
                    this.push.apply(this, insert);
3064
                }
3065
            } else {
3066
                var remove = Math.min(removeCount, length - pos);
3067
                var tailOldPos = pos + remove;
3068
                var tailNewPos = tailOldPos + add - remove;
3069
                var tailCount = length - tailOldPos;
3070
                var lengthAfterRemove = length - remove;
3071

    
3072
                if (tailNewPos < tailOldPos) { // case A
3073
                    for (var i = 0; i < tailCount; ++i) {
3074
                        this[tailNewPos+i] = this[tailOldPos+i];
3075
                    }
3076
                } else if (tailNewPos > tailOldPos) { // case B
3077
                    for (i = tailCount; i--; ) {
3078
                        this[tailNewPos+i] = this[tailOldPos+i];
3079
                    }
3080
                } // else, add == remove (nothing to do)
3081

    
3082
                if (add && pos === lengthAfterRemove) {
3083
                    this.length = lengthAfterRemove; // truncate array
3084
                    this.push.apply(this, insert);
3085
                } else {
3086
                    this.length = lengthAfterRemove + add; // reserves space
3087
                    for (i = 0; i < add; ++i) {
3088
                        this[pos+i] = insert[i];
3089
                    }
3090
                }
3091
            }
3092
            return removed;
3093
        };
3094
    }
3095
}
3096
if (!Array.isArray) {
3097
    Array.isArray = function isArray(obj) {
3098
        return _toString(obj) == "[object Array]";
3099
    };
3100
}
3101
var boxedString = Object("a"),
3102
    splitString = boxedString[0] != "a" || !(0 in boxedString);
3103

    
3104
if (!Array.prototype.forEach) {
3105
    Array.prototype.forEach = function forEach(fun /*, thisp*/) {
3106
        var object = toObject(this),
3107
            self = splitString && _toString(this) == "[object String]" ?
3108
                this.split("") :
3109
                object,
3110
            thisp = arguments[1],
3111
            i = -1,
3112
            length = self.length >>> 0;
3113
        if (_toString(fun) != "[object Function]") {
3114
            throw new TypeError(); // TODO message
3115
        }
3116

    
3117
        while (++i < length) {
3118
            if (i in self) {
3119
                fun.call(thisp, self[i], i, object);
3120
            }
3121
        }
3122
    };
3123
}
3124
if (!Array.prototype.map) {
3125
    Array.prototype.map = function map(fun /*, thisp*/) {
3126
        var object = toObject(this),
3127
            self = splitString && _toString(this) == "[object String]" ?
3128
                this.split("") :
3129
                object,
3130
            length = self.length >>> 0,
3131
            result = Array(length),
3132
            thisp = arguments[1];
3133
        if (_toString(fun) != "[object Function]") {
3134
            throw new TypeError(fun + " is not a function");
3135
        }
3136

    
3137
        for (var i = 0; i < length; i++) {
3138
            if (i in self)
3139
                result[i] = fun.call(thisp, self[i], i, object);
3140
        }
3141
        return result;
3142
    };
3143
}
3144
if (!Array.prototype.filter) {
3145
    Array.prototype.filter = function filter(fun /*, thisp */) {
3146
        var object = toObject(this),
3147
            self = splitString && _toString(this) == "[object String]" ?
3148
                this.split("") :
3149
                    object,
3150
            length = self.length >>> 0,
3151
            result = [],
3152
            value,
3153
            thisp = arguments[1];
3154
        if (_toString(fun) != "[object Function]") {
3155
            throw new TypeError(fun + " is not a function");
3156
        }
3157

    
3158
        for (var i = 0; i < length; i++) {
3159
            if (i in self) {
3160
                value = self[i];
3161
                if (fun.call(thisp, value, i, object)) {
3162
                    result.push(value);
3163
                }
3164
            }
3165
        }
3166
        return result;
3167
    };
3168
}
3169
if (!Array.prototype.every) {
3170
    Array.prototype.every = function every(fun /*, thisp */) {
3171
        var object = toObject(this),
3172
            self = splitString && _toString(this) == "[object String]" ?
3173
                this.split("") :
3174
                object,
3175
            length = self.length >>> 0,
3176
            thisp = arguments[1];
3177
        if (_toString(fun) != "[object Function]") {
3178
            throw new TypeError(fun + " is not a function");
3179
        }
3180

    
3181
        for (var i = 0; i < length; i++) {
3182
            if (i in self && !fun.call(thisp, self[i], i, object)) {
3183
                return false;
3184
            }
3185
        }
3186
        return true;
3187
    };
3188
}
3189
if (!Array.prototype.some) {
3190
    Array.prototype.some = function some(fun /*, thisp */) {
3191
        var object = toObject(this),
3192
            self = splitString && _toString(this) == "[object String]" ?
3193
                this.split("") :
3194
                object,
3195
            length = self.length >>> 0,
3196
            thisp = arguments[1];
3197
        if (_toString(fun) != "[object Function]") {
3198
            throw new TypeError(fun + " is not a function");
3199
        }
3200

    
3201
        for (var i = 0; i < length; i++) {
3202
            if (i in self && fun.call(thisp, self[i], i, object)) {
3203
                return true;
3204
            }
3205
        }
3206
        return false;
3207
    };
3208
}
3209
if (!Array.prototype.reduce) {
3210
    Array.prototype.reduce = function reduce(fun /*, initial*/) {
3211
        var object = toObject(this),
3212
            self = splitString && _toString(this) == "[object String]" ?
3213
                this.split("") :
3214
                object,
3215
            length = self.length >>> 0;
3216
        if (_toString(fun) != "[object Function]") {
3217
            throw new TypeError(fun + " is not a function");
3218
        }
3219
        if (!length && arguments.length == 1) {
3220
            throw new TypeError("reduce of empty array with no initial value");
3221
        }
3222

    
3223
        var i = 0;
3224
        var result;
3225
        if (arguments.length >= 2) {
3226
            result = arguments[1];
3227
        } else {
3228
            do {
3229
                if (i in self) {
3230
                    result = self[i++];
3231
                    break;
3232
                }
3233
                if (++i >= length) {
3234
                    throw new TypeError("reduce of empty array with no initial value");
3235
                }
3236
            } while (true);
3237
        }
3238

    
3239
        for (; i < length; i++) {
3240
            if (i in self) {
3241
                result = fun.call(void 0, result, self[i], i, object);
3242
            }
3243
        }
3244

    
3245
        return result;
3246
    };
3247
}
3248
if (!Array.prototype.reduceRight) {
3249
    Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
3250
        var object = toObject(this),
3251
            self = splitString && _toString(this) == "[object String]" ?
3252
                this.split("") :
3253
                object,
3254
            length = self.length >>> 0;
3255
        if (_toString(fun) != "[object Function]") {
3256
            throw new TypeError(fun + " is not a function");
3257
        }
3258
        if (!length && arguments.length == 1) {
3259
            throw new TypeError("reduceRight of empty array with no initial value");
3260
        }
3261

    
3262
        var result, i = length - 1;
3263
        if (arguments.length >= 2) {
3264
            result = arguments[1];
3265
        } else {
3266
            do {
3267
                if (i in self) {
3268
                    result = self[i--];
3269
                    break;
3270
                }
3271
                if (--i < 0) {
3272
                    throw new TypeError("reduceRight of empty array with no initial value");
3273
                }
3274
            } while (true);
3275
        }
3276

    
3277
        do {
3278
            if (i in this) {
3279
                result = fun.call(void 0, result, self[i], i, object);
3280
            }
3281
        } while (i--);
3282

    
3283
        return result;
3284
    };
3285
}
3286
if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) {
3287
    Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
3288
        var self = splitString && _toString(this) == "[object String]" ?
3289
                this.split("") :
3290
                toObject(this),
3291
            length = self.length >>> 0;
3292

    
3293
        if (!length) {
3294
            return -1;
3295
        }
3296

    
3297
        var i = 0;
3298
        if (arguments.length > 1) {
3299
            i = toInteger(arguments[1]);
3300
        }
3301
        i = i >= 0 ? i : Math.max(0, length + i);
3302
        for (; i < length; i++) {
3303
            if (i in self && self[i] === sought) {
3304
                return i;
3305
            }
3306
        }
3307
        return -1;
3308
    };
3309
}
3310
if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) {
3311
    Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
3312
        var self = splitString && _toString(this) == "[object String]" ?
3313
                this.split("") :
3314
                toObject(this),
3315
            length = self.length >>> 0;
3316

    
3317
        if (!length) {
3318
            return -1;
3319
        }
3320
        var i = length - 1;
3321
        if (arguments.length > 1) {
3322
            i = Math.min(i, toInteger(arguments[1]));
3323
        }
3324
        i = i >= 0 ? i : length - Math.abs(i);
3325
        for (; i >= 0; i--) {
3326
            if (i in self && sought === self[i]) {
3327
                return i;
3328
            }
3329
        }
3330
        return -1;
3331
    };
3332
}
3333
if (!Object.getPrototypeOf) {
3334
    Object.getPrototypeOf = function getPrototypeOf(object) {
3335
        return object.__proto__ || (
3336
            object.constructor ?
3337
            object.constructor.prototype :
3338
            prototypeOfObject
3339
        );
3340
    };
3341
}
3342
if (!Object.getOwnPropertyDescriptor) {
3343
    var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " +
3344
                         "non-object: ";
3345
    Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
3346
        if ((typeof object != "object" && typeof object != "function") || object === null)
3347
            throw new TypeError(ERR_NON_OBJECT + object);
3348
        if (!owns(object, property))
3349
            return;
3350

    
3351
        var descriptor, getter, setter;
3352
        descriptor =  { enumerable: true, configurable: true };
3353
        if (supportsAccessors) {
3354
            var prototype = object.__proto__;
3355
            object.__proto__ = prototypeOfObject;
3356

    
3357
            var getter = lookupGetter(object, property);
3358
            var setter = lookupSetter(object, property);
3359
            object.__proto__ = prototype;
3360

    
3361
            if (getter || setter) {
3362
                if (getter) descriptor.get = getter;
3363
                if (setter) descriptor.set = setter;
3364
                return descriptor;
3365
            }
3366
        }
3367
        descriptor.value = object[property];
3368
        return descriptor;
3369
    };
3370
}
3371
if (!Object.getOwnPropertyNames) {
3372
    Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
3373
        return Object.keys(object);
3374
    };
3375
}
3376
if (!Object.create) {
3377
    var createEmpty;
3378
    if (Object.prototype.__proto__ === null) {
3379
        createEmpty = function () {
3380
            return { "__proto__": null };
3381
        };
3382
    } else {
3383
        createEmpty = function () {
3384
            var empty = {};
3385
            for (var i in empty)
3386
                empty[i] = null;
3387
            empty.constructor =
3388
            empty.hasOwnProperty =
3389
            empty.propertyIsEnumerable =
3390
            empty.isPrototypeOf =
3391
            empty.toLocaleString =
3392
            empty.toString =
3393
            empty.valueOf =
3394
            empty.__proto__ = null;
3395
            return empty;
3396
        }
3397
    }
3398

    
3399
    Object.create = function create(prototype, properties) {
3400
        var object;
3401
        if (prototype === null) {
3402
            object = createEmpty();
3403
        } else {
3404
            if (typeof prototype != "object")
3405
                throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'");
3406
            var Type = function () {};
3407
            Type.prototype = prototype;
3408
            object = new Type();
3409
            object.__proto__ = prototype;
3410
        }
3411
        if (properties !== void 0)
3412
            Object.defineProperties(object, properties);
3413
        return object;
3414
    };
3415
}
3416

    
3417
function doesDefinePropertyWork(object) {
3418
    try {
3419
        Object.defineProperty(object, "sentinel", {});
3420
        return "sentinel" in object;
3421
    } catch (exception) {
3422
    }
3423
}
3424
if (Object.defineProperty) {
3425
    var definePropertyWorksOnObject = doesDefinePropertyWork({});
3426
    var definePropertyWorksOnDom = typeof document == "undefined" ||
3427
        doesDefinePropertyWork(document.createElement("div"));
3428
    if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
3429
        var definePropertyFallback = Object.defineProperty;
3430
    }
3431
}
3432

    
3433
if (!Object.defineProperty || definePropertyFallback) {
3434
    var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
3435
    var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: "
3436
    var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " +
3437
                                      "on this javascript engine";
3438

    
3439
    Object.defineProperty = function defineProperty(object, property, descriptor) {
3440
        if ((typeof object != "object" && typeof object != "function") || object === null)
3441
            throw new TypeError(ERR_NON_OBJECT_TARGET + object);
3442
        if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null)
3443
            throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
3444
        if (definePropertyFallback) {
3445
            try {
3446
                return definePropertyFallback.call(Object, object, property, descriptor);
3447
            } catch (exception) {
3448
            }
3449
        }
3450
        if (owns(descriptor, "value")) {
3451

    
3452
            if (supportsAccessors && (lookupGetter(object, property) ||
3453
                                      lookupSetter(object, property)))
3454
            {
3455
                var prototype = object.__proto__;
3456
                object.__proto__ = prototypeOfObject;
3457
                delete object[property];
3458
                object[property] = descriptor.value;
3459
                object.__proto__ = prototype;
3460
            } else {
3461
                object[property] = descriptor.value;
3462
            }
3463
        } else {
3464
            if (!supportsAccessors)
3465
                throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
3466
            if (owns(descriptor, "get"))
3467
                defineGetter(object, property, descriptor.get);
3468
            if (owns(descriptor, "set"))
3469
                defineSetter(object, property, descriptor.set);
3470
        }
3471

    
3472
        return object;
3473
    };
3474
}
3475
if (!Object.defineProperties) {
3476
    Object.defineProperties = function defineProperties(object, properties) {
3477
        for (var property in properties) {
3478
            if (owns(properties, property))
3479
                Object.defineProperty(object, property, properties[property]);
3480
        }
3481
        return object;
3482
    };
3483
}
3484
if (!Object.seal) {
3485
    Object.seal = function seal(object) {
3486
        return object;
3487
    };
3488
}
3489
if (!Object.freeze) {
3490
    Object.freeze = function freeze(object) {
3491
        return object;
3492
    };
3493
}
3494
try {
3495
    Object.freeze(function () {});
3496
} catch (exception) {
3497
    Object.freeze = (function freeze(freezeObject) {
3498
        return function freeze(object) {
3499
            if (typeof object == "function") {
3500
                return object;
3501
            } else {
3502
                return freezeObject(object);
3503
            }
3504
        };
3505
    })(Object.freeze);
3506
}
3507
if (!Object.preventExtensions) {
3508
    Object.preventExtensions = function preventExtensions(object) {
3509
        return object;
3510
    };
3511
}
3512
if (!Object.isSealed) {
3513
    Object.isSealed = function isSealed(object) {
3514
        return false;
3515
    };
3516
}
3517
if (!Object.isFrozen) {
3518
    Object.isFrozen = function isFrozen(object) {
3519
        return false;
3520
    };
3521
}
3522
if (!Object.isExtensible) {
3523
    Object.isExtensible = function isExtensible(object) {
3524
        if (Object(object) === object) {
3525
            throw new TypeError(); // TODO message
3526
        }
3527
        var name = '';
3528
        while (owns(object, name)) {
3529
            name += '?';
3530
        }
3531
        object[name] = true;
3532
        var returnValue = owns(object, name);
3533
        delete object[name];
3534
        return returnValue;
3535
    };
3536
}
3537
if (!Object.keys) {
3538
    var hasDontEnumBug = true,
3539
        dontEnums = [
3540
            "toString",
3541
            "toLocaleString",
3542
            "valueOf",
3543
            "hasOwnProperty",
3544
            "isPrototypeOf",
3545
            "propertyIsEnumerable",
3546
            "constructor"
3547
        ],
3548
        dontEnumsLength = dontEnums.length;
3549

    
3550
    for (var key in {"toString": null}) {
3551
        hasDontEnumBug = false;
3552
    }
3553

    
3554
    Object.keys = function keys(object) {
3555

    
3556
        if (
3557
            (typeof object != "object" && typeof object != "function") ||
3558
            object === null
3559
        ) {
3560
            throw new TypeError("Object.keys called on a non-object");
3561
        }
3562

    
3563
        var keys = [];
3564
        for (var name in object) {
3565
            if (owns(object, name)) {
3566
                keys.push(name);
3567
            }
3568
        }
3569

    
3570
        if (hasDontEnumBug) {
3571
            for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
3572
                var dontEnum = dontEnums[i];
3573
                if (owns(object, dontEnum)) {
3574
                    keys.push(dontEnum);
3575
                }
3576
            }
3577
        }
3578
        return keys;
3579
    };
3580

    
3581
}
3582
if (!Date.now) {
3583
    Date.now = function now() {
3584
        return new Date().getTime();
3585
    };
3586
}
3587
var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003" +
3588
    "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
3589
    "\u2029\uFEFF";
3590
if (!String.prototype.trim) {
3591
    ws = "[" + ws + "]";
3592
    var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
3593
        trimEndRegexp = new RegExp(ws + ws + "*$");
3594
    String.prototype.trim = function trim() {
3595
        return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
3596
    };
3597
}
3598

    
3599
function toInteger(n) {
3600
    n = +n;
3601
    if (n !== n) { // isNaN
3602
        n = 0;
3603
    } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) {
3604
        n = (n > 0 || -1) * Math.floor(Math.abs(n));
3605
    }
3606
    return n;
3607
}
3608

    
3609
function isPrimitive(input) {
3610
    var type = typeof input;
3611
    return (
3612
        input === null ||
3613
        type === "undefined" ||
3614
        type === "boolean" ||
3615
        type === "number" ||
3616
        type === "string"
3617
    );
3618
}
3619

    
3620
function toPrimitive(input) {
3621
    var val, valueOf, toString;
3622
    if (isPrimitive(input)) {
3623
        return input;
3624
    }
3625
    valueOf = input.valueOf;
3626
    if (typeof valueOf === "function") {
3627
        val = valueOf.call(input);
3628
        if (isPrimitive(val)) {
3629
            return val;
3630
        }
3631
    }
3632
    toString = input.toString;
3633
    if (typeof toString === "function") {
3634
        val = toString.call(input);
3635
        if (isPrimitive(val)) {
3636
            return val;
3637
        }
3638
    }
3639
    throw new TypeError();
3640
}
3641
var toObject = function (o) {
3642
    if (o == null) { // this matches both null and undefined
3643
        throw new TypeError("can't convert "+o+" to object");
3644
    }
3645
    return Object(o);
3646
};
3647

    
3648
});
(241-241/244)