Projekt

Obecné

Profil

Stáhnout (337 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/javascript/jshint",[], function(require, exports, module) {
1425
module.exports = (function outer (modules, cache, entry) {
1426
    var previousRequire = typeof require == "function" && require;
1427
    function newRequire(name, jumped){
1428
        if(!cache[name]) {
1429
            if(!modules[name]) {
1430
                var currentRequire = typeof require == "function" && require;
1431
                if (!jumped && currentRequire) return currentRequire(name, true);
1432
                if (previousRequire) return previousRequire(name, true);
1433
                var err = new Error('Cannot find module \'' + name + '\'');
1434
                err.code = 'MODULE_NOT_FOUND';
1435
                throw err;
1436
            }
1437
            var m = cache[name] = {exports:{}};
1438
            modules[name][0].call(m.exports, function(x){
1439
                var id = modules[name][1][x];
1440
                return newRequire(id ? id : x);
1441
            },m,m.exports,outer,modules,cache,entry);
1442
        }
1443
        return cache[name].exports;
1444
    }
1445
    for(var i=0;i<entry.length;i++) newRequire(entry[i]);
1446
    return newRequire(entry[0]);
1447
})
1448
({"/node_modules/browserify/node_modules/events/events.js":[function(_dereq_,module,exports){
1449

    
1450
function EventEmitter() {
1451
  this._events = this._events || {};
1452
  this._maxListeners = this._maxListeners || undefined;
1453
}
1454
module.exports = EventEmitter;
1455
EventEmitter.EventEmitter = EventEmitter;
1456

    
1457
EventEmitter.prototype._events = undefined;
1458
EventEmitter.prototype._maxListeners = undefined;
1459
EventEmitter.defaultMaxListeners = 10;
1460
EventEmitter.prototype.setMaxListeners = function(n) {
1461
  if (!isNumber(n) || n < 0 || isNaN(n))
1462
    throw TypeError('n must be a positive number');
1463
  this._maxListeners = n;
1464
  return this;
1465
};
1466

    
1467
EventEmitter.prototype.emit = function(type) {
1468
  var er, handler, len, args, i, listeners;
1469

    
1470
  if (!this._events)
1471
    this._events = {};
1472
  if (type === 'error') {
1473
    if (!this._events.error ||
1474
        (isObject(this._events.error) && !this._events.error.length)) {
1475
      er = arguments[1];
1476
      if (er instanceof Error) {
1477
        throw er; // Unhandled 'error' event
1478
      }
1479
      throw TypeError('Uncaught, unspecified "error" event.');
1480
    }
1481
  }
1482

    
1483
  handler = this._events[type];
1484

    
1485
  if (isUndefined(handler))
1486
    return false;
1487

    
1488
  if (isFunction(handler)) {
1489
    switch (arguments.length) {
1490
      case 1:
1491
        handler.call(this);
1492
        break;
1493
      case 2:
1494
        handler.call(this, arguments[1]);
1495
        break;
1496
      case 3:
1497
        handler.call(this, arguments[1], arguments[2]);
1498
        break;
1499
      default:
1500
        len = arguments.length;
1501
        args = new Array(len - 1);
1502
        for (i = 1; i < len; i++)
1503
          args[i - 1] = arguments[i];
1504
        handler.apply(this, args);
1505
    }
1506
  } else if (isObject(handler)) {
1507
    len = arguments.length;
1508
    args = new Array(len - 1);
1509
    for (i = 1; i < len; i++)
1510
      args[i - 1] = arguments[i];
1511

    
1512
    listeners = handler.slice();
1513
    len = listeners.length;
1514
    for (i = 0; i < len; i++)
1515
      listeners[i].apply(this, args);
1516
  }
1517

    
1518
  return true;
1519
};
1520

    
1521
EventEmitter.prototype.addListener = function(type, listener) {
1522
  var m;
1523

    
1524
  if (!isFunction(listener))
1525
    throw TypeError('listener must be a function');
1526

    
1527
  if (!this._events)
1528
    this._events = {};
1529
  if (this._events.newListener)
1530
    this.emit('newListener', type,
1531
              isFunction(listener.listener) ?
1532
              listener.listener : listener);
1533

    
1534
  if (!this._events[type])
1535
    this._events[type] = listener;
1536
  else if (isObject(this._events[type]))
1537
    this._events[type].push(listener);
1538
  else
1539
    this._events[type] = [this._events[type], listener];
1540
  if (isObject(this._events[type]) && !this._events[type].warned) {
1541
    var m;
1542
    if (!isUndefined(this._maxListeners)) {
1543
      m = this._maxListeners;
1544
    } else {
1545
      m = EventEmitter.defaultMaxListeners;
1546
    }
1547

    
1548
    if (m && m > 0 && this._events[type].length > m) {
1549
      this._events[type].warned = true;
1550
      console.error('(node) warning: possible EventEmitter memory ' +
1551
                    'leak detected. %d listeners added. ' +
1552
                    'Use emitter.setMaxListeners() to increase limit.',
1553
                    this._events[type].length);
1554
      if (typeof console.trace === 'function') {
1555
        console.trace();
1556
      }
1557
    }
1558
  }
1559

    
1560
  return this;
1561
};
1562

    
1563
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
1564

    
1565
EventEmitter.prototype.once = function(type, listener) {
1566
  if (!isFunction(listener))
1567
    throw TypeError('listener must be a function');
1568

    
1569
  var fired = false;
1570

    
1571
  function g() {
1572
    this.removeListener(type, g);
1573

    
1574
    if (!fired) {
1575
      fired = true;
1576
      listener.apply(this, arguments);
1577
    }
1578
  }
1579

    
1580
  g.listener = listener;
1581
  this.on(type, g);
1582

    
1583
  return this;
1584
};
1585
EventEmitter.prototype.removeListener = function(type, listener) {
1586
  var list, position, length, i;
1587

    
1588
  if (!isFunction(listener))
1589
    throw TypeError('listener must be a function');
1590

    
1591
  if (!this._events || !this._events[type])
1592
    return this;
1593

    
1594
  list = this._events[type];
1595
  length = list.length;
1596
  position = -1;
1597

    
1598
  if (list === listener ||
1599
      (isFunction(list.listener) && list.listener === listener)) {
1600
    delete this._events[type];
1601
    if (this._events.removeListener)
1602
      this.emit('removeListener', type, listener);
1603

    
1604
  } else if (isObject(list)) {
1605
    for (i = length; i-- > 0;) {
1606
      if (list[i] === listener ||
1607
          (list[i].listener && list[i].listener === listener)) {
1608
        position = i;
1609
        break;
1610
      }
1611
    }
1612

    
1613
    if (position < 0)
1614
      return this;
1615

    
1616
    if (list.length === 1) {
1617
      list.length = 0;
1618
      delete this._events[type];
1619
    } else {
1620
      list.splice(position, 1);
1621
    }
1622

    
1623
    if (this._events.removeListener)
1624
      this.emit('removeListener', type, listener);
1625
  }
1626

    
1627
  return this;
1628
};
1629

    
1630
EventEmitter.prototype.removeAllListeners = function(type) {
1631
  var key, listeners;
1632

    
1633
  if (!this._events)
1634
    return this;
1635
  if (!this._events.removeListener) {
1636
    if (arguments.length === 0)
1637
      this._events = {};
1638
    else if (this._events[type])
1639
      delete this._events[type];
1640
    return this;
1641
  }
1642
  if (arguments.length === 0) {
1643
    for (key in this._events) {
1644
      if (key === 'removeListener') continue;
1645
      this.removeAllListeners(key);
1646
    }
1647
    this.removeAllListeners('removeListener');
1648
    this._events = {};
1649
    return this;
1650
  }
1651

    
1652
  listeners = this._events[type];
1653

    
1654
  if (isFunction(listeners)) {
1655
    this.removeListener(type, listeners);
1656
  } else {
1657
    while (listeners.length)
1658
      this.removeListener(type, listeners[listeners.length - 1]);
1659
  }
1660
  delete this._events[type];
1661

    
1662
  return this;
1663
};
1664

    
1665
EventEmitter.prototype.listeners = function(type) {
1666
  var ret;
1667
  if (!this._events || !this._events[type])
1668
    ret = [];
1669
  else if (isFunction(this._events[type]))
1670
    ret = [this._events[type]];
1671
  else
1672
    ret = this._events[type].slice();
1673
  return ret;
1674
};
1675

    
1676
EventEmitter.listenerCount = function(emitter, type) {
1677
  var ret;
1678
  if (!emitter._events || !emitter._events[type])
1679
    ret = 0;
1680
  else if (isFunction(emitter._events[type]))
1681
    ret = 1;
1682
  else
1683
    ret = emitter._events[type].length;
1684
  return ret;
1685
};
1686

    
1687
function isFunction(arg) {
1688
  return typeof arg === 'function';
1689
}
1690

    
1691
function isNumber(arg) {
1692
  return typeof arg === 'number';
1693
}
1694

    
1695
function isObject(arg) {
1696
  return typeof arg === 'object' && arg !== null;
1697
}
1698

    
1699
function isUndefined(arg) {
1700
  return arg === void 0;
1701
}
1702

    
1703
},{}],"/node_modules/jshint/data/ascii-identifier-data.js":[function(_dereq_,module,exports){
1704
var identifierStartTable = [];
1705

    
1706
for (var i = 0; i < 128; i++) {
1707
  identifierStartTable[i] =
1708
    i === 36 ||           // $
1709
    i >= 65 && i <= 90 || // A-Z
1710
    i === 95 ||           // _
1711
    i >= 97 && i <= 122;  // a-z
1712
}
1713

    
1714
var identifierPartTable = [];
1715

    
1716
for (var i = 0; i < 128; i++) {
1717
  identifierPartTable[i] =
1718
    identifierStartTable[i] || // $, _, A-Z, a-z
1719
    i >= 48 && i <= 57;        // 0-9
1720
}
1721

    
1722
module.exports = {
1723
  asciiIdentifierStartTable: identifierStartTable,
1724
  asciiIdentifierPartTable: identifierPartTable
1725
};
1726

    
1727
},{}],"/node_modules/jshint/lodash.js":[function(_dereq_,module,exports){
1728
(function (global){
1729
;(function() {
1730

    
1731
  var undefined;
1732

    
1733
  var VERSION = '3.7.0';
1734

    
1735
  var FUNC_ERROR_TEXT = 'Expected a function';
1736

    
1737
  var argsTag = '[object Arguments]',
1738
      arrayTag = '[object Array]',
1739
      boolTag = '[object Boolean]',
1740
      dateTag = '[object Date]',
1741
      errorTag = '[object Error]',
1742
      funcTag = '[object Function]',
1743
      mapTag = '[object Map]',
1744
      numberTag = '[object Number]',
1745
      objectTag = '[object Object]',
1746
      regexpTag = '[object RegExp]',
1747
      setTag = '[object Set]',
1748
      stringTag = '[object String]',
1749
      weakMapTag = '[object WeakMap]';
1750

    
1751
  var arrayBufferTag = '[object ArrayBuffer]',
1752
      float32Tag = '[object Float32Array]',
1753
      float64Tag = '[object Float64Array]',
1754
      int8Tag = '[object Int8Array]',
1755
      int16Tag = '[object Int16Array]',
1756
      int32Tag = '[object Int32Array]',
1757
      uint8Tag = '[object Uint8Array]',
1758
      uint8ClampedTag = '[object Uint8ClampedArray]',
1759
      uint16Tag = '[object Uint16Array]',
1760
      uint32Tag = '[object Uint32Array]';
1761

    
1762
  var reIsDeepProp = /\.|\[(?:[^[\]]+|(["'])(?:(?!\1)[^\n\\]|\\.)*?)\1\]/,
1763
      reIsPlainProp = /^\w*$/,
1764
      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g;
1765

    
1766
  var reRegExpChars = /[.*+?^${}()|[\]\/\\]/g,
1767
      reHasRegExpChars = RegExp(reRegExpChars.source);
1768

    
1769
  var reEscapeChar = /\\(\\)?/g;
1770

    
1771
  var reFlags = /\w*$/;
1772

    
1773
  var reIsHostCtor = /^\[object .+?Constructor\]$/;
1774

    
1775
  var typedArrayTags = {};
1776
  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
1777
  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
1778
  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
1779
  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
1780
  typedArrayTags[uint32Tag] = true;
1781
  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
1782
  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
1783
  typedArrayTags[dateTag] = typedArrayTags[errorTag] =
1784
  typedArrayTags[funcTag] = typedArrayTags[mapTag] =
1785
  typedArrayTags[numberTag] = typedArrayTags[objectTag] =
1786
  typedArrayTags[regexpTag] = typedArrayTags[setTag] =
1787
  typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
1788

    
1789
  var cloneableTags = {};
1790
  cloneableTags[argsTag] = cloneableTags[arrayTag] =
1791
  cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
1792
  cloneableTags[dateTag] = cloneableTags[float32Tag] =
1793
  cloneableTags[float64Tag] = cloneableTags[int8Tag] =
1794
  cloneableTags[int16Tag] = cloneableTags[int32Tag] =
1795
  cloneableTags[numberTag] = cloneableTags[objectTag] =
1796
  cloneableTags[regexpTag] = cloneableTags[stringTag] =
1797
  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
1798
  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
1799
  cloneableTags[errorTag] = cloneableTags[funcTag] =
1800
  cloneableTags[mapTag] = cloneableTags[setTag] =
1801
  cloneableTags[weakMapTag] = false;
1802

    
1803
  var objectTypes = {
1804
    'function': true,
1805
    'object': true
1806
  };
1807

    
1808
  var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
1809

    
1810
  var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
1811

    
1812
  var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global;
1813

    
1814
  var freeSelf = objectTypes[typeof self] && self && self.Object && self;
1815

    
1816
  var freeWindow = objectTypes[typeof window] && window && window.Object && window;
1817

    
1818
  var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
1819

    
1820
  var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this;
1821

    
1822
  function baseFindIndex(array, predicate, fromRight) {
1823
    var length = array.length,
1824
        index = fromRight ? length : -1;
1825

    
1826
    while ((fromRight ? index-- : ++index < length)) {
1827
      if (predicate(array[index], index, array)) {
1828
        return index;
1829
      }
1830
    }
1831
    return -1;
1832
  }
1833

    
1834
  function baseIndexOf(array, value, fromIndex) {
1835
    if (value !== value) {
1836
      return indexOfNaN(array, fromIndex);
1837
    }
1838
    var index = fromIndex - 1,
1839
        length = array.length;
1840

    
1841
    while (++index < length) {
1842
      if (array[index] === value) {
1843
        return index;
1844
      }
1845
    }
1846
    return -1;
1847
  }
1848

    
1849
  function baseIsFunction(value) {
1850
    return typeof value == 'function' || false;
1851
  }
1852

    
1853
  function baseToString(value) {
1854
    if (typeof value == 'string') {
1855
      return value;
1856
    }
1857
    return value == null ? '' : (value + '');
1858
  }
1859

    
1860
  function indexOfNaN(array, fromIndex, fromRight) {
1861
    var length = array.length,
1862
        index = fromIndex + (fromRight ? 0 : -1);
1863

    
1864
    while ((fromRight ? index-- : ++index < length)) {
1865
      var other = array[index];
1866
      if (other !== other) {
1867
        return index;
1868
      }
1869
    }
1870
    return -1;
1871
  }
1872

    
1873
  function isObjectLike(value) {
1874
    return !!value && typeof value == 'object';
1875
  }
1876

    
1877
  var arrayProto = Array.prototype,
1878
      objectProto = Object.prototype;
1879

    
1880
  var fnToString = Function.prototype.toString;
1881

    
1882
  var hasOwnProperty = objectProto.hasOwnProperty;
1883

    
1884
  var objToString = objectProto.toString;
1885

    
1886
  var reIsNative = RegExp('^' +
1887
    escapeRegExp(objToString)
1888
    .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
1889
  );
1890

    
1891
  var ArrayBuffer = isNative(ArrayBuffer = root.ArrayBuffer) && ArrayBuffer,
1892
      bufferSlice = isNative(bufferSlice = ArrayBuffer && new ArrayBuffer(0).slice) && bufferSlice,
1893
      floor = Math.floor,
1894
      getOwnPropertySymbols = isNative(getOwnPropertySymbols = Object.getOwnPropertySymbols) && getOwnPropertySymbols,
1895
      getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
1896
      push = arrayProto.push,
1897
      preventExtensions = isNative(Object.preventExtensions = Object.preventExtensions) && preventExtensions,
1898
      propertyIsEnumerable = objectProto.propertyIsEnumerable,
1899
      Uint8Array = isNative(Uint8Array = root.Uint8Array) && Uint8Array;
1900

    
1901
  var Float64Array = (function() {
1902
    try {
1903
      var func = isNative(func = root.Float64Array) && func,
1904
          result = new func(new ArrayBuffer(10), 0, 1) && func;
1905
    } catch(e) {}
1906
    return result;
1907
  }());
1908

    
1909
  var nativeAssign = (function() {
1910
    var object = { '1': 0 },
1911
        func = preventExtensions && isNative(func = Object.assign) && func;
1912

    
1913
    try { func(preventExtensions(object), 'xo'); } catch(e) {}
1914
    return !object[1] && func;
1915
  }());
1916

    
1917
  var nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray,
1918
      nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
1919
      nativeMax = Math.max,
1920
      nativeMin = Math.min;
1921

    
1922
  var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY;
1923

    
1924
  var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1,
1925
      MAX_ARRAY_INDEX =  MAX_ARRAY_LENGTH - 1,
1926
      HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
1927

    
1928
  var FLOAT64_BYTES_PER_ELEMENT = Float64Array ? Float64Array.BYTES_PER_ELEMENT : 0;
1929

    
1930
  var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
1931

    
1932
  function lodash() {
1933
  }
1934

    
1935
  var support = lodash.support = {};
1936

    
1937
  (function(x) {
1938
    var Ctor = function() { this.x = x; },
1939
        object = { '0': x, 'length': x },
1940
        props = [];
1941

    
1942
    Ctor.prototype = { 'valueOf': x, 'y': x };
1943
    for (var key in new Ctor) { props.push(key); }
1944

    
1945
    support.funcDecomp = /\bthis\b/.test(function() { return this; });
1946

    
1947
    support.funcNames = typeof Function.name == 'string';
1948

    
1949
    try {
1950
      support.nonEnumArgs = !propertyIsEnumerable.call(arguments, 1);
1951
    } catch(e) {
1952
      support.nonEnumArgs = true;
1953
    }
1954
  }(1, 0));
1955

    
1956
  function arrayCopy(source, array) {
1957
    var index = -1,
1958
        length = source.length;
1959

    
1960
    array || (array = Array(length));
1961
    while (++index < length) {
1962
      array[index] = source[index];
1963
    }
1964
    return array;
1965
  }
1966

    
1967
  function arrayEach(array, iteratee) {
1968
    var index = -1,
1969
        length = array.length;
1970

    
1971
    while (++index < length) {
1972
      if (iteratee(array[index], index, array) === false) {
1973
        break;
1974
      }
1975
    }
1976
    return array;
1977
  }
1978

    
1979
  function arrayFilter(array, predicate) {
1980
    var index = -1,
1981
        length = array.length,
1982
        resIndex = -1,
1983
        result = [];
1984

    
1985
    while (++index < length) {
1986
      var value = array[index];
1987
      if (predicate(value, index, array)) {
1988
        result[++resIndex] = value;
1989
      }
1990
    }
1991
    return result;
1992
  }
1993

    
1994
  function arrayMap(array, iteratee) {
1995
    var index = -1,
1996
        length = array.length,
1997
        result = Array(length);
1998

    
1999
    while (++index < length) {
2000
      result[index] = iteratee(array[index], index, array);
2001
    }
2002
    return result;
2003
  }
2004

    
2005
  function arrayMax(array) {
2006
    var index = -1,
2007
        length = array.length,
2008
        result = NEGATIVE_INFINITY;
2009

    
2010
    while (++index < length) {
2011
      var value = array[index];
2012
      if (value > result) {
2013
        result = value;
2014
      }
2015
    }
2016
    return result;
2017
  }
2018

    
2019
  function arraySome(array, predicate) {
2020
    var index = -1,
2021
        length = array.length;
2022

    
2023
    while (++index < length) {
2024
      if (predicate(array[index], index, array)) {
2025
        return true;
2026
      }
2027
    }
2028
    return false;
2029
  }
2030

    
2031
  function assignWith(object, source, customizer) {
2032
    var props = keys(source);
2033
    push.apply(props, getSymbols(source));
2034

    
2035
    var index = -1,
2036
        length = props.length;
2037

    
2038
    while (++index < length) {
2039
      var key = props[index],
2040
          value = object[key],
2041
          result = customizer(value, source[key], key, object, source);
2042

    
2043
      if ((result === result ? (result !== value) : (value === value)) ||
2044
          (value === undefined && !(key in object))) {
2045
        object[key] = result;
2046
      }
2047
    }
2048
    return object;
2049
  }
2050

    
2051
  var baseAssign = nativeAssign || function(object, source) {
2052
    return source == null
2053
      ? object
2054
      : baseCopy(source, getSymbols(source), baseCopy(source, keys(source), object));
2055
  };
2056

    
2057
  function baseCopy(source, props, object) {
2058
    object || (object = {});
2059

    
2060
    var index = -1,
2061
        length = props.length;
2062

    
2063
    while (++index < length) {
2064
      var key = props[index];
2065
      object[key] = source[key];
2066
    }
2067
    return object;
2068
  }
2069

    
2070
  function baseCallback(func, thisArg, argCount) {
2071
    var type = typeof func;
2072
    if (type == 'function') {
2073
      return thisArg === undefined
2074
        ? func
2075
        : bindCallback(func, thisArg, argCount);
2076
    }
2077
    if (func == null) {
2078
      return identity;
2079
    }
2080
    if (type == 'object') {
2081
      return baseMatches(func);
2082
    }
2083
    return thisArg === undefined
2084
      ? property(func)
2085
      : baseMatchesProperty(func, thisArg);
2086
  }
2087

    
2088
  function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {
2089
    var result;
2090
    if (customizer) {
2091
      result = object ? customizer(value, key, object) : customizer(value);
2092
    }
2093
    if (result !== undefined) {
2094
      return result;
2095
    }
2096
    if (!isObject(value)) {
2097
      return value;
2098
    }
2099
    var isArr = isArray(value);
2100
    if (isArr) {
2101
      result = initCloneArray(value);
2102
      if (!isDeep) {
2103
        return arrayCopy(value, result);
2104
      }
2105
    } else {
2106
      var tag = objToString.call(value),
2107
          isFunc = tag == funcTag;
2108

    
2109
      if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
2110
        result = initCloneObject(isFunc ? {} : value);
2111
        if (!isDeep) {
2112
          return baseAssign(result, value);
2113
        }
2114
      } else {
2115
        return cloneableTags[tag]
2116
          ? initCloneByTag(value, tag, isDeep)
2117
          : (object ? value : {});
2118
      }
2119
    }
2120
    stackA || (stackA = []);
2121
    stackB || (stackB = []);
2122

    
2123
    var length = stackA.length;
2124
    while (length--) {
2125
      if (stackA[length] == value) {
2126
        return stackB[length];
2127
      }
2128
    }
2129
    stackA.push(value);
2130
    stackB.push(result);
2131

    
2132
    (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
2133
      result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB);
2134
    });
2135
    return result;
2136
  }
2137

    
2138
  var baseEach = createBaseEach(baseForOwn);
2139

    
2140
  function baseFilter(collection, predicate) {
2141
    var result = [];
2142
    baseEach(collection, function(value, index, collection) {
2143
      if (predicate(value, index, collection)) {
2144
        result.push(value);
2145
      }
2146
    });
2147
    return result;
2148
  }
2149

    
2150
  var baseFor = createBaseFor();
2151

    
2152
  function baseForIn(object, iteratee) {
2153
    return baseFor(object, iteratee, keysIn);
2154
  }
2155

    
2156
  function baseForOwn(object, iteratee) {
2157
    return baseFor(object, iteratee, keys);
2158
  }
2159

    
2160
  function baseGet(object, path, pathKey) {
2161
    if (object == null) {
2162
      return;
2163
    }
2164
    if (pathKey !== undefined && pathKey in toObject(object)) {
2165
      path = [pathKey];
2166
    }
2167
    var index = -1,
2168
        length = path.length;
2169

    
2170
    while (object != null && ++index < length) {
2171
      var result = object = object[path[index]];
2172
    }
2173
    return result;
2174
  }
2175

    
2176
  function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) {
2177
    if (value === other) {
2178
      return value !== 0 || (1 / value == 1 / other);
2179
    }
2180
    var valType = typeof value,
2181
        othType = typeof other;
2182

    
2183
    if ((valType != 'function' && valType != 'object' && othType != 'function' && othType != 'object') ||
2184
        value == null || other == null) {
2185
      return value !== value && other !== other;
2186
    }
2187
    return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB);
2188
  }
2189

    
2190
  function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
2191
    var objIsArr = isArray(object),
2192
        othIsArr = isArray(other),
2193
        objTag = arrayTag,
2194
        othTag = arrayTag;
2195

    
2196
    if (!objIsArr) {
2197
      objTag = objToString.call(object);
2198
      if (objTag == argsTag) {
2199
        objTag = objectTag;
2200
      } else if (objTag != objectTag) {
2201
        objIsArr = isTypedArray(object);
2202
      }
2203
    }
2204
    if (!othIsArr) {
2205
      othTag = objToString.call(other);
2206
      if (othTag == argsTag) {
2207
        othTag = objectTag;
2208
      } else if (othTag != objectTag) {
2209
        othIsArr = isTypedArray(other);
2210
      }
2211
    }
2212
    var objIsObj = objTag == objectTag,
2213
        othIsObj = othTag == objectTag,
2214
        isSameTag = objTag == othTag;
2215

    
2216
    if (isSameTag && !(objIsArr || objIsObj)) {
2217
      return equalByTag(object, other, objTag);
2218
    }
2219
    if (!isLoose) {
2220
      var valWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
2221
          othWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
2222

    
2223
      if (valWrapped || othWrapped) {
2224
        return equalFunc(valWrapped ? object.value() : object, othWrapped ? other.value() : other, customizer, isLoose, stackA, stackB);
2225
      }
2226
    }
2227
    if (!isSameTag) {
2228
      return false;
2229
    }
2230
    stackA || (stackA = []);
2231
    stackB || (stackB = []);
2232

    
2233
    var length = stackA.length;
2234
    while (length--) {
2235
      if (stackA[length] == object) {
2236
        return stackB[length] == other;
2237
      }
2238
    }
2239
    stackA.push(object);
2240
    stackB.push(other);
2241

    
2242
    var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB);
2243

    
2244
    stackA.pop();
2245
    stackB.pop();
2246

    
2247
    return result;
2248
  }
2249

    
2250
  function baseIsMatch(object, props, values, strictCompareFlags, customizer) {
2251
    var index = -1,
2252
        length = props.length,
2253
        noCustomizer = !customizer;
2254

    
2255
    while (++index < length) {
2256
      if ((noCustomizer && strictCompareFlags[index])
2257
            ? values[index] !== object[props[index]]
2258
            : !(props[index] in object)
2259
          ) {
2260
        return false;
2261
      }
2262
    }
2263
    index = -1;
2264
    while (++index < length) {
2265
      var key = props[index],
2266
          objValue = object[key],
2267
          srcValue = values[index];
2268

    
2269
      if (noCustomizer && strictCompareFlags[index]) {
2270
        var result = objValue !== undefined || (key in object);
2271
      } else {
2272
        result = customizer ? customizer(objValue, srcValue, key) : undefined;
2273
        if (result === undefined) {
2274
          result = baseIsEqual(srcValue, objValue, customizer, true);
2275
        }
2276
      }
2277
      if (!result) {
2278
        return false;
2279
      }
2280
    }
2281
    return true;
2282
  }
2283

    
2284
  function baseMatches(source) {
2285
    var props = keys(source),
2286
        length = props.length;
2287

    
2288
    if (!length) {
2289
      return constant(true);
2290
    }
2291
    if (length == 1) {
2292
      var key = props[0],
2293
          value = source[key];
2294

    
2295
      if (isStrictComparable(value)) {
2296
        return function(object) {
2297
          if (object == null) {
2298
            return false;
2299
          }
2300
          return object[key] === value && (value !== undefined || (key in toObject(object)));
2301
        };
2302
      }
2303
    }
2304
    var values = Array(length),
2305
        strictCompareFlags = Array(length);
2306

    
2307
    while (length--) {
2308
      value = source[props[length]];
2309
      values[length] = value;
2310
      strictCompareFlags[length] = isStrictComparable(value);
2311
    }
2312
    return function(object) {
2313
      return object != null && baseIsMatch(toObject(object), props, values, strictCompareFlags);
2314
    };
2315
  }
2316

    
2317
  function baseMatchesProperty(path, value) {
2318
    var isArr = isArray(path),
2319
        isCommon = isKey(path) && isStrictComparable(value),
2320
        pathKey = (path + '');
2321

    
2322
    path = toPath(path);
2323
    return function(object) {
2324
      if (object == null) {
2325
        return false;
2326
      }
2327
      var key = pathKey;
2328
      object = toObject(object);
2329
      if ((isArr || !isCommon) && !(key in object)) {
2330
        object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
2331
        if (object == null) {
2332
          return false;
2333
        }
2334
        key = last(path);
2335
        object = toObject(object);
2336
      }
2337
      return object[key] === value
2338
        ? (value !== undefined || (key in object))
2339
        : baseIsEqual(value, object[key], null, true);
2340
    };
2341
  }
2342

    
2343
  function baseMerge(object, source, customizer, stackA, stackB) {
2344
    if (!isObject(object)) {
2345
      return object;
2346
    }
2347
    var isSrcArr = isLength(source.length) && (isArray(source) || isTypedArray(source));
2348
    if (!isSrcArr) {
2349
      var props = keys(source);
2350
      push.apply(props, getSymbols(source));
2351
    }
2352
    arrayEach(props || source, function(srcValue, key) {
2353
      if (props) {
2354
        key = srcValue;
2355
        srcValue = source[key];
2356
      }
2357
      if (isObjectLike(srcValue)) {
2358
        stackA || (stackA = []);
2359
        stackB || (stackB = []);
2360
        baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB);
2361
      }
2362
      else {
2363
        var value = object[key],
2364
            result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
2365
            isCommon = result === undefined;
2366

    
2367
        if (isCommon) {
2368
          result = srcValue;
2369
        }
2370
        if ((isSrcArr || result !== undefined) &&
2371
            (isCommon || (result === result ? (result !== value) : (value === value)))) {
2372
          object[key] = result;
2373
        }
2374
      }
2375
    });
2376
    return object;
2377
  }
2378

    
2379
  function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) {
2380
    var length = stackA.length,
2381
        srcValue = source[key];
2382

    
2383
    while (length--) {
2384
      if (stackA[length] == srcValue) {
2385
        object[key] = stackB[length];
2386
        return;
2387
      }
2388
    }
2389
    var value = object[key],
2390
        result = customizer ? customizer(value, srcValue, key, object, source) : undefined,
2391
        isCommon = result === undefined;
2392

    
2393
    if (isCommon) {
2394
      result = srcValue;
2395
      if (isLength(srcValue.length) && (isArray(srcValue) || isTypedArray(srcValue))) {
2396
        result = isArray(value)
2397
          ? value
2398
          : (getLength(value) ? arrayCopy(value) : []);
2399
      }
2400
      else if (isPlainObject(srcValue) || isArguments(srcValue)) {
2401
        result = isArguments(value)
2402
          ? toPlainObject(value)
2403
          : (isPlainObject(value) ? value : {});
2404
      }
2405
      else {
2406
        isCommon = false;
2407
      }
2408
    }
2409
    stackA.push(srcValue);
2410
    stackB.push(result);
2411

    
2412
    if (isCommon) {
2413
      object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB);
2414
    } else if (result === result ? (result !== value) : (value === value)) {
2415
      object[key] = result;
2416
    }
2417
  }
2418

    
2419
  function baseProperty(key) {
2420
    return function(object) {
2421
      return object == null ? undefined : object[key];
2422
    };
2423
  }
2424

    
2425
  function basePropertyDeep(path) {
2426
    var pathKey = (path + '');
2427
    path = toPath(path);
2428
    return function(object) {
2429
      return baseGet(object, path, pathKey);
2430
    };
2431
  }
2432

    
2433
  function baseSlice(array, start, end) {
2434
    var index = -1,
2435
        length = array.length;
2436

    
2437
    start = start == null ? 0 : (+start || 0);
2438
    if (start < 0) {
2439
      start = -start > length ? 0 : (length + start);
2440
    }
2441
    end = (end === undefined || end > length) ? length : (+end || 0);
2442
    if (end < 0) {
2443
      end += length;
2444
    }
2445
    length = start > end ? 0 : ((end - start) >>> 0);
2446
    start >>>= 0;
2447

    
2448
    var result = Array(length);
2449
    while (++index < length) {
2450
      result[index] = array[index + start];
2451
    }
2452
    return result;
2453
  }
2454

    
2455
  function baseSome(collection, predicate) {
2456
    var result;
2457

    
2458
    baseEach(collection, function(value, index, collection) {
2459
      result = predicate(value, index, collection);
2460
      return !result;
2461
    });
2462
    return !!result;
2463
  }
2464

    
2465
  function baseValues(object, props) {
2466
    var index = -1,
2467
        length = props.length,
2468
        result = Array(length);
2469

    
2470
    while (++index < length) {
2471
      result[index] = object[props[index]];
2472
    }
2473
    return result;
2474
  }
2475

    
2476
  function binaryIndex(array, value, retHighest) {
2477
    var low = 0,
2478
        high = array ? array.length : low;
2479

    
2480
    if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
2481
      while (low < high) {
2482
        var mid = (low + high) >>> 1,
2483
            computed = array[mid];
2484

    
2485
        if (retHighest ? (computed <= value) : (computed < value)) {
2486
          low = mid + 1;
2487
        } else {
2488
          high = mid;
2489
        }
2490
      }
2491
      return high;
2492
    }
2493
    return binaryIndexBy(array, value, identity, retHighest);
2494
  }
2495

    
2496
  function binaryIndexBy(array, value, iteratee, retHighest) {
2497
    value = iteratee(value);
2498

    
2499
    var low = 0,
2500
        high = array ? array.length : 0,
2501
        valIsNaN = value !== value,
2502
        valIsUndef = value === undefined;
2503

    
2504
    while (low < high) {
2505
      var mid = floor((low + high) / 2),
2506
          computed = iteratee(array[mid]),
2507
          isReflexive = computed === computed;
2508

    
2509
      if (valIsNaN) {
2510
        var setLow = isReflexive || retHighest;
2511
      } else if (valIsUndef) {
2512
        setLow = isReflexive && (retHighest || computed !== undefined);
2513
      } else {
2514
        setLow = retHighest ? (computed <= value) : (computed < value);
2515
      }
2516
      if (setLow) {
2517
        low = mid + 1;
2518
      } else {
2519
        high = mid;
2520
      }
2521
    }
2522
    return nativeMin(high, MAX_ARRAY_INDEX);
2523
  }
2524

    
2525
  function bindCallback(func, thisArg, argCount) {
2526
    if (typeof func != 'function') {
2527
      return identity;
2528
    }
2529
    if (thisArg === undefined) {
2530
      return func;
2531
    }
2532
    switch (argCount) {
2533
      case 1: return function(value) {
2534
        return func.call(thisArg, value);
2535
      };
2536
      case 3: return function(value, index, collection) {
2537
        return func.call(thisArg, value, index, collection);
2538
      };
2539
      case 4: return function(accumulator, value, index, collection) {
2540
        return func.call(thisArg, accumulator, value, index, collection);
2541
      };
2542
      case 5: return function(value, other, key, object, source) {
2543
        return func.call(thisArg, value, other, key, object, source);
2544
      };
2545
    }
2546
    return function() {
2547
      return func.apply(thisArg, arguments);
2548
    };
2549
  }
2550

    
2551
  function bufferClone(buffer) {
2552
    return bufferSlice.call(buffer, 0);
2553
  }
2554
  if (!bufferSlice) {
2555
    bufferClone = !(ArrayBuffer && Uint8Array) ? constant(null) : function(buffer) {
2556
      var byteLength = buffer.byteLength,
2557
          floatLength = Float64Array ? floor(byteLength / FLOAT64_BYTES_PER_ELEMENT) : 0,
2558
          offset = floatLength * FLOAT64_BYTES_PER_ELEMENT,
2559
          result = new ArrayBuffer(byteLength);
2560

    
2561
      if (floatLength) {
2562
        var view = new Float64Array(result, 0, floatLength);
2563
        view.set(new Float64Array(buffer, 0, floatLength));
2564
      }
2565
      if (byteLength != offset) {
2566
        view = new Uint8Array(result, offset);
2567
        view.set(new Uint8Array(buffer, offset));
2568
      }
2569
      return result;
2570
    };
2571
  }
2572

    
2573
  function createAssigner(assigner) {
2574
    return restParam(function(object, sources) {
2575
      var index = -1,
2576
          length = object == null ? 0 : sources.length,
2577
          customizer = length > 2 && sources[length - 2],
2578
          guard = length > 2 && sources[2],
2579
          thisArg = length > 1 && sources[length - 1];
2580

    
2581
      if (typeof customizer == 'function') {
2582
        customizer = bindCallback(customizer, thisArg, 5);
2583
        length -= 2;
2584
      } else {
2585
        customizer = typeof thisArg == 'function' ? thisArg : null;
2586
        length -= (customizer ? 1 : 0);
2587
      }
2588
      if (guard && isIterateeCall(sources[0], sources[1], guard)) {
2589
        customizer = length < 3 ? null : customizer;
2590
        length = 1;
2591
      }
2592
      while (++index < length) {
2593
        var source = sources[index];
2594
        if (source) {
2595
          assigner(object, source, customizer);
2596
        }
2597
      }
2598
      return object;
2599
    });
2600
  }
2601

    
2602
  function createBaseEach(eachFunc, fromRight) {
2603
    return function(collection, iteratee) {
2604
      var length = collection ? getLength(collection) : 0;
2605
      if (!isLength(length)) {
2606
        return eachFunc(collection, iteratee);
2607
      }
2608
      var index = fromRight ? length : -1,
2609
          iterable = toObject(collection);
2610

    
2611
      while ((fromRight ? index-- : ++index < length)) {
2612
        if (iteratee(iterable[index], index, iterable) === false) {
2613
          break;
2614
        }
2615
      }
2616
      return collection;
2617
    };
2618
  }
2619

    
2620
  function createBaseFor(fromRight) {
2621
    return function(object, iteratee, keysFunc) {
2622
      var iterable = toObject(object),
2623
          props = keysFunc(object),
2624
          length = props.length,
2625
          index = fromRight ? length : -1;
2626

    
2627
      while ((fromRight ? index-- : ++index < length)) {
2628
        var key = props[index];
2629
        if (iteratee(iterable[key], key, iterable) === false) {
2630
          break;
2631
        }
2632
      }
2633
      return object;
2634
    };
2635
  }
2636

    
2637
  function createFindIndex(fromRight) {
2638
    return function(array, predicate, thisArg) {
2639
      if (!(array && array.length)) {
2640
        return -1;
2641
      }
2642
      predicate = getCallback(predicate, thisArg, 3);
2643
      return baseFindIndex(array, predicate, fromRight);
2644
    };
2645
  }
2646

    
2647
  function createForEach(arrayFunc, eachFunc) {
2648
    return function(collection, iteratee, thisArg) {
2649
      return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))
2650
        ? arrayFunc(collection, iteratee)
2651
        : eachFunc(collection, bindCallback(iteratee, thisArg, 3));
2652
    };
2653
  }
2654

    
2655
  function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) {
2656
    var index = -1,
2657
        arrLength = array.length,
2658
        othLength = other.length,
2659
        result = true;
2660

    
2661
    if (arrLength != othLength && !(isLoose && othLength > arrLength)) {
2662
      return false;
2663
    }
2664
    while (result && ++index < arrLength) {
2665
      var arrValue = array[index],
2666
          othValue = other[index];
2667

    
2668
      result = undefined;
2669
      if (customizer) {
2670
        result = isLoose
2671
          ? customizer(othValue, arrValue, index)
2672
          : customizer(arrValue, othValue, index);
2673
      }
2674
      if (result === undefined) {
2675
        if (isLoose) {
2676
          var othIndex = othLength;
2677
          while (othIndex--) {
2678
            othValue = other[othIndex];
2679
            result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);
2680
            if (result) {
2681
              break;
2682
            }
2683
          }
2684
        } else {
2685
          result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);
2686
        }
2687
      }
2688
    }
2689
    return !!result;
2690
  }
2691

    
2692
  function equalByTag(object, other, tag) {
2693
    switch (tag) {
2694
      case boolTag:
2695
      case dateTag:
2696
        return +object == +other;
2697

    
2698
      case errorTag:
2699
        return object.name == other.name && object.message == other.message;
2700

    
2701
      case numberTag:
2702
        return (object != +object)
2703
          ? other != +other
2704
          : (object == 0 ? ((1 / object) == (1 / other)) : object == +other);
2705

    
2706
      case regexpTag:
2707
      case stringTag:
2708
        return object == (other + '');
2709
    }
2710
    return false;
2711
  }
2712

    
2713
  function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
2714
    var objProps = keys(object),
2715
        objLength = objProps.length,
2716
        othProps = keys(other),
2717
        othLength = othProps.length;
2718

    
2719
    if (objLength != othLength && !isLoose) {
2720
      return false;
2721
    }
2722
    var skipCtor = isLoose,
2723
        index = -1;
2724

    
2725
    while (++index < objLength) {
2726
      var key = objProps[index],
2727
          result = isLoose ? key in other : hasOwnProperty.call(other, key);
2728

    
2729
      if (result) {
2730
        var objValue = object[key],
2731
            othValue = other[key];
2732

    
2733
        result = undefined;
2734
        if (customizer) {
2735
          result = isLoose
2736
            ? customizer(othValue, objValue, key)
2737
            : customizer(objValue, othValue, key);
2738
        }
2739
        if (result === undefined) {
2740
          result = (objValue && objValue === othValue) || equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB);
2741
        }
2742
      }
2743
      if (!result) {
2744
        return false;
2745
      }
2746
      skipCtor || (skipCtor = key == 'constructor');
2747
    }
2748
    if (!skipCtor) {
2749
      var objCtor = object.constructor,
2750
          othCtor = other.constructor;
2751

    
2752
      if (objCtor != othCtor &&
2753
          ('constructor' in object && 'constructor' in other) &&
2754
          !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
2755
            typeof othCtor == 'function' && othCtor instanceof othCtor)) {
2756
        return false;
2757
      }
2758
    }
2759
    return true;
2760
  }
2761

    
2762
  function getCallback(func, thisArg, argCount) {
2763
    var result = lodash.callback || callback;
2764
    result = result === callback ? baseCallback : result;
2765
    return argCount ? result(func, thisArg, argCount) : result;
2766
  }
2767

    
2768
  function getIndexOf(collection, target, fromIndex) {
2769
    var result = lodash.indexOf || indexOf;
2770
    result = result === indexOf ? baseIndexOf : result;
2771
    return collection ? result(collection, target, fromIndex) : result;
2772
  }
2773

    
2774
  var getLength = baseProperty('length');
2775

    
2776
  var getSymbols = !getOwnPropertySymbols ? constant([]) : function(object) {
2777
    return getOwnPropertySymbols(toObject(object));
2778
  };
2779

    
2780
  function initCloneArray(array) {
2781
    var length = array.length,
2782
        result = new array.constructor(length);
2783

    
2784
    if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
2785
      result.index = array.index;
2786
      result.input = array.input;
2787
    }
2788
    return result;
2789
  }
2790

    
2791
  function initCloneObject(object) {
2792
    var Ctor = object.constructor;
2793
    if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) {
2794
      Ctor = Object;
2795
    }
2796
    return new Ctor;
2797
  }
2798

    
2799
  function initCloneByTag(object, tag, isDeep) {
2800
    var Ctor = object.constructor;
2801
    switch (tag) {
2802
      case arrayBufferTag:
2803
        return bufferClone(object);
2804

    
2805
      case boolTag:
2806
      case dateTag:
2807
        return new Ctor(+object);
2808

    
2809
      case float32Tag: case float64Tag:
2810
      case int8Tag: case int16Tag: case int32Tag:
2811
      case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
2812
        var buffer = object.buffer;
2813
        return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length);
2814

    
2815
      case numberTag:
2816
      case stringTag:
2817
        return new Ctor(object);
2818

    
2819
      case regexpTag:
2820
        var result = new Ctor(object.source, reFlags.exec(object));
2821
        result.lastIndex = object.lastIndex;
2822
    }
2823
    return result;
2824
  }
2825

    
2826
  function isIndex(value, length) {
2827
    value = +value;
2828
    length = length == null ? MAX_SAFE_INTEGER : length;
2829
    return value > -1 && value % 1 == 0 && value < length;
2830
  }
2831

    
2832
  function isIterateeCall(value, index, object) {
2833
    if (!isObject(object)) {
2834
      return false;
2835
    }
2836
    var type = typeof index;
2837
    if (type == 'number') {
2838
      var length = getLength(object),
2839
          prereq = isLength(length) && isIndex(index, length);
2840
    } else {
2841
      prereq = type == 'string' && index in object;
2842
    }
2843
    if (prereq) {
2844
      var other = object[index];
2845
      return value === value ? (value === other) : (other !== other);
2846
    }
2847
    return false;
2848
  }
2849

    
2850
  function isKey(value, object) {
2851
    var type = typeof value;
2852
    if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') {
2853
      return true;
2854
    }
2855
    if (isArray(value)) {
2856
      return false;
2857
    }
2858
    var result = !reIsDeepProp.test(value);
2859
    return result || (object != null && value in toObject(object));
2860
  }
2861

    
2862
  function isLength(value) {
2863
    return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
2864
  }
2865

    
2866
  function isStrictComparable(value) {
2867
    return value === value && (value === 0 ? ((1 / value) > 0) : !isObject(value));
2868
  }
2869

    
2870
  function shimIsPlainObject(value) {
2871
    var Ctor,
2872
        support = lodash.support;
2873

    
2874
    if (!(isObjectLike(value) && objToString.call(value) == objectTag) ||
2875
        (!hasOwnProperty.call(value, 'constructor') &&
2876
          (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {
2877
      return false;
2878
    }
2879
    var result;
2880
    baseForIn(value, function(subValue, key) {
2881
      result = key;
2882
    });
2883
    return result === undefined || hasOwnProperty.call(value, result);
2884
  }
2885

    
2886
  function shimKeys(object) {
2887
    var props = keysIn(object),
2888
        propsLength = props.length,
2889
        length = propsLength && object.length,
2890
        support = lodash.support;
2891

    
2892
    var allowIndexes = length && isLength(length) &&
2893
      (isArray(object) || (support.nonEnumArgs && isArguments(object)));
2894

    
2895
    var index = -1,
2896
        result = [];
2897

    
2898
    while (++index < propsLength) {
2899
      var key = props[index];
2900
      if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
2901
        result.push(key);
2902
      }
2903
    }
2904
    return result;
2905
  }
2906

    
2907
  function toObject(value) {
2908
    return isObject(value) ? value : Object(value);
2909
  }
2910

    
2911
  function toPath(value) {
2912
    if (isArray(value)) {
2913
      return value;
2914
    }
2915
    var result = [];
2916
    baseToString(value).replace(rePropName, function(match, number, quote, string) {
2917
      result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
2918
    });
2919
    return result;
2920
  }
2921

    
2922
  var findLastIndex = createFindIndex(true);
2923

    
2924
  function indexOf(array, value, fromIndex) {
2925
    var length = array ? array.length : 0;
2926
    if (!length) {
2927
      return -1;
2928
    }
2929
    if (typeof fromIndex == 'number') {
2930
      fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex;
2931
    } else if (fromIndex) {
2932
      var index = binaryIndex(array, value),
2933
          other = array[index];
2934

    
2935
      if (value === value ? (value === other) : (other !== other)) {
2936
        return index;
2937
      }
2938
      return -1;
2939
    }
2940
    return baseIndexOf(array, value, fromIndex || 0);
2941
  }
2942

    
2943
  function last(array) {
2944
    var length = array ? array.length : 0;
2945
    return length ? array[length - 1] : undefined;
2946
  }
2947

    
2948
  function slice(array, start, end) {
2949
    var length = array ? array.length : 0;
2950
    if (!length) {
2951
      return [];
2952
    }
2953
    if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
2954
      start = 0;
2955
      end = length;
2956
    }
2957
    return baseSlice(array, start, end);
2958
  }
2959

    
2960
  function unzip(array) {
2961
    var index = -1,
2962
        length = (array && array.length && arrayMax(arrayMap(array, getLength))) >>> 0,
2963
        result = Array(length);
2964

    
2965
    while (++index < length) {
2966
      result[index] = arrayMap(array, baseProperty(index));
2967
    }
2968
    return result;
2969
  }
2970

    
2971
  var zip = restParam(unzip);
2972

    
2973
  var forEach = createForEach(arrayEach, baseEach);
2974

    
2975
  function includes(collection, target, fromIndex, guard) {
2976
    var length = collection ? getLength(collection) : 0;
2977
    if (!isLength(length)) {
2978
      collection = values(collection);
2979
      length = collection.length;
2980
    }
2981
    if (!length) {
2982
      return false;
2983
    }
2984
    if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) {
2985
      fromIndex = 0;
2986
    } else {
2987
      fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0);
2988
    }
2989
    return (typeof collection == 'string' || !isArray(collection) && isString(collection))
2990
      ? (fromIndex < length && collection.indexOf(target, fromIndex) > -1)
2991
      : (getIndexOf(collection, target, fromIndex) > -1);
2992
  }
2993

    
2994
  function reject(collection, predicate, thisArg) {
2995
    var func = isArray(collection) ? arrayFilter : baseFilter;
2996
    predicate = getCallback(predicate, thisArg, 3);
2997
    return func(collection, function(value, index, collection) {
2998
      return !predicate(value, index, collection);
2999
    });
3000
  }
3001

    
3002
  function some(collection, predicate, thisArg) {
3003
    var func = isArray(collection) ? arraySome : baseSome;
3004
    if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
3005
      predicate = null;
3006
    }
3007
    if (typeof predicate != 'function' || thisArg !== undefined) {
3008
      predicate = getCallback(predicate, thisArg, 3);
3009
    }
3010
    return func(collection, predicate);
3011
  }
3012

    
3013
  function restParam(func, start) {
3014
    if (typeof func != 'function') {
3015
      throw new TypeError(FUNC_ERROR_TEXT);
3016
    }
3017
    start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
3018
    return function() {
3019
      var args = arguments,
3020
          index = -1,
3021
          length = nativeMax(args.length - start, 0),
3022
          rest = Array(length);
3023

    
3024
      while (++index < length) {
3025
        rest[index] = args[start + index];
3026
      }
3027
      switch (start) {
3028
        case 0: return func.call(this, rest);
3029
        case 1: return func.call(this, args[0], rest);
3030
        case 2: return func.call(this, args[0], args[1], rest);
3031
      }
3032
      var otherArgs = Array(start + 1);
3033
      index = -1;
3034
      while (++index < start) {
3035
        otherArgs[index] = args[index];
3036
      }
3037
      otherArgs[start] = rest;
3038
      return func.apply(this, otherArgs);
3039
    };
3040
  }
3041

    
3042
  function clone(value, isDeep, customizer, thisArg) {
3043
    if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) {
3044
      isDeep = false;
3045
    }
3046
    else if (typeof isDeep == 'function') {
3047
      thisArg = customizer;
3048
      customizer = isDeep;
3049
      isDeep = false;
3050
    }
3051
    customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 1);
3052
    return baseClone(value, isDeep, customizer);
3053
  }
3054

    
3055
  function isArguments(value) {
3056
    var length = isObjectLike(value) ? value.length : undefined;
3057
    return isLength(length) && objToString.call(value) == argsTag;
3058
  }
3059

    
3060
  var isArray = nativeIsArray || function(value) {
3061
    return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
3062
  };
3063

    
3064
  function isEmpty(value) {
3065
    if (value == null) {
3066
      return true;
3067
    }
3068
    var length = getLength(value);
3069
    if (isLength(length) && (isArray(value) || isString(value) || isArguments(value) ||
3070
        (isObjectLike(value) && isFunction(value.splice)))) {
3071
      return !length;
3072
    }
3073
    return !keys(value).length;
3074
  }
3075

    
3076
  var isFunction = !(baseIsFunction(/x/) || (Uint8Array && !baseIsFunction(Uint8Array))) ? baseIsFunction : function(value) {
3077
    return objToString.call(value) == funcTag;
3078
  };
3079

    
3080
  function isObject(value) {
3081
    var type = typeof value;
3082
    return type == 'function' || (!!value && type == 'object');
3083
  }
3084

    
3085
  function isNative(value) {
3086
    if (value == null) {
3087
      return false;
3088
    }
3089
    if (objToString.call(value) == funcTag) {
3090
      return reIsNative.test(fnToString.call(value));
3091
    }
3092
    return isObjectLike(value) && reIsHostCtor.test(value);
3093
  }
3094

    
3095
  function isNumber(value) {
3096
    return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag);
3097
  }
3098

    
3099
  var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
3100
    if (!(value && objToString.call(value) == objectTag)) {
3101
      return false;
3102
    }
3103
    var valueOf = value.valueOf,
3104
        objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
3105

    
3106
    return objProto
3107
      ? (value == objProto || getPrototypeOf(value) == objProto)
3108
      : shimIsPlainObject(value);
3109
  };
3110

    
3111
  function isString(value) {
3112
    return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);
3113
  }
3114

    
3115
  function isTypedArray(value) {
3116
    return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
3117
  }
3118

    
3119
  function toPlainObject(value) {
3120
    return baseCopy(value, keysIn(value));
3121
  }
3122

    
3123
  var assign = createAssigner(function(object, source, customizer) {
3124
    return customizer
3125
      ? assignWith(object, source, customizer)
3126
      : baseAssign(object, source);
3127
  });
3128

    
3129
  function has(object, path) {
3130
    if (object == null) {
3131
      return false;
3132
    }
3133
    var result = hasOwnProperty.call(object, path);
3134
    if (!result && !isKey(path)) {
3135
      path = toPath(path);
3136
      object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
3137
      path = last(path);
3138
      result = object != null && hasOwnProperty.call(object, path);
3139
    }
3140
    return result;
3141
  }
3142

    
3143
  var keys = !nativeKeys ? shimKeys : function(object) {
3144
    if (object) {
3145
      var Ctor = object.constructor,
3146
          length = object.length;
3147
    }
3148
    if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
3149
        (typeof object != 'function' && isLength(length))) {
3150
      return shimKeys(object);
3151
    }
3152
    return isObject(object) ? nativeKeys(object) : [];
3153
  };
3154

    
3155
  function keysIn(object) {
3156
    if (object == null) {
3157
      return [];
3158
    }
3159
    if (!isObject(object)) {
3160
      object = Object(object);
3161
    }
3162
    var length = object.length;
3163
    length = (length && isLength(length) &&
3164
      (isArray(object) || (support.nonEnumArgs && isArguments(object))) && length) || 0;
3165

    
3166
    var Ctor = object.constructor,
3167
        index = -1,
3168
        isProto = typeof Ctor == 'function' && Ctor.prototype === object,
3169
        result = Array(length),
3170
        skipIndexes = length > 0;
3171

    
3172
    while (++index < length) {
3173
      result[index] = (index + '');
3174
    }
3175
    for (var key in object) {
3176
      if (!(skipIndexes && isIndex(key, length)) &&
3177
          !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
3178
        result.push(key);
3179
      }
3180
    }
3181
    return result;
3182
  }
3183

    
3184
  var merge = createAssigner(baseMerge);
3185

    
3186
  function values(object) {
3187
    return baseValues(object, keys(object));
3188
  }
3189

    
3190
  function escapeRegExp(string) {
3191
    string = baseToString(string);
3192
    return (string && reHasRegExpChars.test(string))
3193
      ? string.replace(reRegExpChars, '\\$&')
3194
      : string;
3195
  }
3196

    
3197
  function callback(func, thisArg, guard) {
3198
    if (guard && isIterateeCall(func, thisArg, guard)) {
3199
      thisArg = null;
3200
    }
3201
    return baseCallback(func, thisArg);
3202
  }
3203

    
3204
  function constant(value) {
3205
    return function() {
3206
      return value;
3207
    };
3208
  }
3209

    
3210
  function identity(value) {
3211
    return value;
3212
  }
3213

    
3214
  function property(path) {
3215
    return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
3216
  }
3217
  lodash.assign = assign;
3218
  lodash.callback = callback;
3219
  lodash.constant = constant;
3220
  lodash.forEach = forEach;
3221
  lodash.keys = keys;
3222
  lodash.keysIn = keysIn;
3223
  lodash.merge = merge;
3224
  lodash.property = property;
3225
  lodash.reject = reject;
3226
  lodash.restParam = restParam;
3227
  lodash.slice = slice;
3228
  lodash.toPlainObject = toPlainObject;
3229
  lodash.unzip = unzip;
3230
  lodash.values = values;
3231
  lodash.zip = zip;
3232

    
3233
  lodash.each = forEach;
3234
  lodash.extend = assign;
3235
  lodash.iteratee = callback;
3236
  lodash.clone = clone;
3237
  lodash.escapeRegExp = escapeRegExp;
3238
  lodash.findLastIndex = findLastIndex;
3239
  lodash.has = has;
3240
  lodash.identity = identity;
3241
  lodash.includes = includes;
3242
  lodash.indexOf = indexOf;
3243
  lodash.isArguments = isArguments;
3244
  lodash.isArray = isArray;
3245
  lodash.isEmpty = isEmpty;
3246
  lodash.isFunction = isFunction;
3247
  lodash.isNative = isNative;
3248
  lodash.isNumber = isNumber;
3249
  lodash.isObject = isObject;
3250
  lodash.isPlainObject = isPlainObject;
3251
  lodash.isString = isString;
3252
  lodash.isTypedArray = isTypedArray;
3253
  lodash.last = last;
3254
  lodash.some = some;
3255

    
3256
  lodash.any = some;
3257
  lodash.contains = includes;
3258
  lodash.include = includes;
3259

    
3260
  lodash.VERSION = VERSION;
3261
  if (freeExports && freeModule) {
3262
    if (moduleExports) {
3263
      (freeModule.exports = lodash)._ = lodash;
3264
    }
3265
    else {
3266
      freeExports._ = lodash;
3267
    }
3268
  }
3269
  else {
3270
    root._ = lodash;
3271
  }
3272
}.call(this));
3273

    
3274
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
3275
},{}],"/node_modules/jshint/src/jshint.js":[function(_dereq_,module,exports){
3276

    
3277
var _            = _dereq_("../lodash");
3278
var events       = _dereq_("events");
3279
var vars         = _dereq_("./vars.js");
3280
var messages     = _dereq_("./messages.js");
3281
var Lexer        = _dereq_("./lex.js").Lexer;
3282
var reg          = _dereq_("./reg.js");
3283
var state        = _dereq_("./state.js").state;
3284
var style        = _dereq_("./style.js");
3285
var options      = _dereq_("./options.js");
3286
var scopeManager = _dereq_("./scope-manager.js");
3287

    
3288
var JSHINT = (function() {
3289
  "use strict";
3290

    
3291
  var api, // Extension API
3292
    bang = {
3293
      "<"  : true,
3294
      "<=" : true,
3295
      "==" : true,
3296
      "===": true,
3297
      "!==": true,
3298
      "!=" : true,
3299
      ">"  : true,
3300
      ">=" : true,
3301
      "+"  : true,
3302
      "-"  : true,
3303
      "*"  : true,
3304
      "/"  : true,
3305
      "%"  : true
3306
    },
3307

    
3308
    declared, // Globals that were declared using /*global ... */ syntax.
3309

    
3310
    functionicity = [
3311
      "closure", "exception", "global", "label",
3312
      "outer", "unused", "var"
3313
    ],
3314

    
3315
    functions, // All of the functions
3316

    
3317
    inblock,
3318
    indent,
3319
    lookahead,
3320
    lex,
3321
    member,
3322
    membersOnly,
3323
    predefined,    // Global variables defined by option
3324

    
3325
    stack,
3326
    urls,
3327

    
3328
    extraModules = [],
3329
    emitter = new events.EventEmitter();
3330

    
3331
  function checkOption(name, t) {
3332
    name = name.trim();
3333

    
3334
    if (/^[+-]W\d{3}$/g.test(name)) {
3335
      return true;
3336
    }
3337

    
3338
    if (options.validNames.indexOf(name) === -1) {
3339
      if (t.type !== "jslint" && !_.has(options.removed, name)) {
3340
        error("E001", t, name);
3341
        return false;
3342
      }
3343
    }
3344

    
3345
    return true;
3346
  }
3347

    
3348
  function isString(obj) {
3349
    return Object.prototype.toString.call(obj) === "[object String]";
3350
  }
3351

    
3352
  function isIdentifier(tkn, value) {
3353
    if (!tkn)
3354
      return false;
3355

    
3356
    if (!tkn.identifier || tkn.value !== value)
3357
      return false;
3358

    
3359
    return true;
3360
  }
3361

    
3362
  function isReserved(token) {
3363
    if (!token.reserved) {
3364
      return false;
3365
    }
3366
    var meta = token.meta;
3367

    
3368
    if (meta && meta.isFutureReservedWord && state.inES5()) {
3369
      if (!meta.es5) {
3370
        return false;
3371
      }
3372
      if (meta.strictOnly) {
3373
        if (!state.option.strict && !state.isStrict()) {
3374
          return false;
3375
        }
3376
      }
3377

    
3378
      if (token.isProperty) {
3379
        return false;
3380
      }
3381
    }
3382

    
3383
    return true;
3384
  }
3385

    
3386
  function supplant(str, data) {
3387
    return str.replace(/\{([^{}]*)\}/g, function(a, b) {
3388
      var r = data[b];
3389
      return typeof r === "string" || typeof r === "number" ? r : a;
3390
    });
3391
  }
3392

    
3393
  function combine(dest, src) {
3394
    Object.keys(src).forEach(function(name) {
3395
      if (_.has(JSHINT.blacklist, name)) return;
3396
      dest[name] = src[name];
3397
    });
3398
  }
3399

    
3400
  function processenforceall() {
3401
    if (state.option.enforceall) {
3402
      for (var enforceopt in options.bool.enforcing) {
3403
        if (state.option[enforceopt] === undefined &&
3404
            !options.noenforceall[enforceopt]) {
3405
          state.option[enforceopt] = true;
3406
        }
3407
      }
3408
      for (var relaxopt in options.bool.relaxing) {
3409
        if (state.option[relaxopt] === undefined) {
3410
          state.option[relaxopt] = false;
3411
        }
3412
      }
3413
    }
3414
  }
3415

    
3416
  function assume() {
3417
    processenforceall();
3418
    if (!state.option.esversion && !state.option.moz) {
3419
      if (state.option.es3) {
3420
        state.option.esversion = 3;
3421
      } else if (state.option.esnext) {
3422
        state.option.esversion = 6;
3423
      } else {
3424
        state.option.esversion = 5;
3425
      }
3426
    }
3427

    
3428
    if (state.inES5()) {
3429
      combine(predefined, vars.ecmaIdentifiers[5]);
3430
    }
3431

    
3432
    if (state.inES6()) {
3433
      combine(predefined, vars.ecmaIdentifiers[6]);
3434
    }
3435

    
3436
    if (state.option.module) {
3437
      if (state.option.strict === true) {
3438
        state.option.strict = "global";
3439
      }
3440
      if (!state.inES6()) {
3441
        warning("W134", state.tokens.next, "module", 6);
3442
      }
3443
    }
3444

    
3445
    if (state.option.couch) {
3446
      combine(predefined, vars.couch);
3447
    }
3448

    
3449
    if (state.option.qunit) {
3450
      combine(predefined, vars.qunit);
3451
    }
3452

    
3453
    if (state.option.rhino) {
3454
      combine(predefined, vars.rhino);
3455
    }
3456

    
3457
    if (state.option.shelljs) {
3458
      combine(predefined, vars.shelljs);
3459
      combine(predefined, vars.node);
3460
    }
3461
    if (state.option.typed) {
3462
      combine(predefined, vars.typed);
3463
    }
3464

    
3465
    if (state.option.phantom) {
3466
      combine(predefined, vars.phantom);
3467
      if (state.option.strict === true) {
3468
        state.option.strict = "global";
3469
      }
3470
    }
3471

    
3472
    if (state.option.prototypejs) {
3473
      combine(predefined, vars.prototypejs);
3474
    }
3475

    
3476
    if (state.option.node) {
3477
      combine(predefined, vars.node);
3478
      combine(predefined, vars.typed);
3479
      if (state.option.strict === true) {
3480
        state.option.strict = "global";
3481
      }
3482
    }
3483

    
3484
    if (state.option.devel) {
3485
      combine(predefined, vars.devel);
3486
    }
3487

    
3488
    if (state.option.dojo) {
3489
      combine(predefined, vars.dojo);
3490
    }
3491

    
3492
    if (state.option.browser) {
3493
      combine(predefined, vars.browser);
3494
      combine(predefined, vars.typed);
3495
    }
3496

    
3497
    if (state.option.browserify) {
3498
      combine(predefined, vars.browser);
3499
      combine(predefined, vars.typed);
3500
      combine(predefined, vars.browserify);
3501
      if (state.option.strict === true) {
3502
        state.option.strict = "global";
3503
      }
3504
    }
3505

    
3506
    if (state.option.nonstandard) {
3507
      combine(predefined, vars.nonstandard);
3508
    }
3509

    
3510
    if (state.option.jasmine) {
3511
      combine(predefined, vars.jasmine);
3512
    }
3513

    
3514
    if (state.option.jquery) {
3515
      combine(predefined, vars.jquery);
3516
    }
3517

    
3518
    if (state.option.mootools) {
3519
      combine(predefined, vars.mootools);
3520
    }
3521

    
3522
    if (state.option.worker) {
3523
      combine(predefined, vars.worker);
3524
    }
3525

    
3526
    if (state.option.wsh) {
3527
      combine(predefined, vars.wsh);
3528
    }
3529

    
3530
    if (state.option.globalstrict && state.option.strict !== false) {
3531
      state.option.strict = "global";
3532
    }
3533

    
3534
    if (state.option.yui) {
3535
      combine(predefined, vars.yui);
3536
    }
3537

    
3538
    if (state.option.mocha) {
3539
      combine(predefined, vars.mocha);
3540
    }
3541
  }
3542
  function quit(code, line, chr) {
3543
    var percentage = Math.floor((line / state.lines.length) * 100);
3544
    var message = messages.errors[code].desc;
3545

    
3546
    throw {
3547
      name: "JSHintError",
3548
      line: line,
3549
      character: chr,
3550
      message: message + " (" + percentage + "% scanned).",
3551
      raw: message,
3552
      code: code
3553
    };
3554
  }
3555

    
3556
  function removeIgnoredMessages() {
3557
    var ignored = state.ignoredLines;
3558

    
3559
    if (_.isEmpty(ignored)) return;
3560
    JSHINT.errors = _.reject(JSHINT.errors, function(err) { return ignored[err.line] });
3561
  }
3562

    
3563
  function warning(code, t, a, b, c, d) {
3564
    var ch, l, w, msg;
3565

    
3566
    if (/^W\d{3}$/.test(code)) {
3567
      if (state.ignored[code])
3568
        return;
3569

    
3570
      msg = messages.warnings[code];
3571
    } else if (/E\d{3}/.test(code)) {
3572
      msg = messages.errors[code];
3573
    } else if (/I\d{3}/.test(code)) {
3574
      msg = messages.info[code];
3575
    }
3576

    
3577
    t = t || state.tokens.next || {};
3578
    if (t.id === "(end)") {  // `~
3579
      t = state.tokens.curr;
3580
    }
3581

    
3582
    l = t.line || 0;
3583
    ch = t.from || 0;
3584

    
3585
    w = {
3586
      id: "(error)",
3587
      raw: msg.desc,
3588
      code: msg.code,
3589
      evidence: state.lines[l - 1] || "",
3590
      line: l,
3591
      character: ch,
3592
      scope: JSHINT.scope,
3593
      a: a,
3594
      b: b,
3595
      c: c,
3596
      d: d
3597
    };
3598

    
3599
    w.reason = supplant(msg.desc, w);
3600
    JSHINT.errors.push(w);
3601

    
3602
    removeIgnoredMessages();
3603

    
3604
    if (JSHINT.errors.length >= state.option.maxerr)
3605
      quit("E043", l, ch);
3606

    
3607
    return w;
3608
  }
3609

    
3610
  function warningAt(m, l, ch, a, b, c, d) {
3611
    return warning(m, {
3612
      line: l,
3613
      from: ch
3614
    }, a, b, c, d);
3615
  }
3616

    
3617
  function error(m, t, a, b, c, d) {
3618
    warning(m, t, a, b, c, d);
3619
  }
3620

    
3621
  function errorAt(m, l, ch, a, b, c, d) {
3622
    return error(m, {
3623
      line: l,
3624
      from: ch
3625
    }, a, b, c, d);
3626
  }
3627
  function addInternalSrc(elem, src) {
3628
    var i;
3629
    i = {
3630
      id: "(internal)",
3631
      elem: elem,
3632
      value: src
3633
    };
3634
    JSHINT.internals.push(i);
3635
    return i;
3636
  }
3637

    
3638
  function doOption() {
3639
    var nt = state.tokens.next;
3640
    var body = nt.body.match(/(-\s+)?[^\s,:]+(?:\s*:\s*(-\s+)?[^\s,]+)?/g) || [];
3641

    
3642
    var predef = {};
3643
    if (nt.type === "globals") {
3644
      body.forEach(function(g, idx) {
3645
        g = g.split(":");
3646
        var key = (g[0] || "").trim();
3647
        var val = (g[1] || "").trim();
3648

    
3649
        if (key === "-" || !key.length) {
3650
          if (idx > 0 && idx === body.length - 1) {
3651
            return;
3652
          }
3653
          error("E002", nt);
3654
          return;
3655
        }
3656

    
3657
        if (key.charAt(0) === "-") {
3658
          key = key.slice(1);
3659
          val = false;
3660

    
3661
          JSHINT.blacklist[key] = key;
3662
          delete predefined[key];
3663
        } else {
3664
          predef[key] = (val === "true");
3665
        }
3666
      });
3667

    
3668
      combine(predefined, predef);
3669

    
3670
      for (var key in predef) {
3671
        if (_.has(predef, key)) {
3672
          declared[key] = nt;
3673
        }
3674
      }
3675
    }
3676

    
3677
    if (nt.type === "exported") {
3678
      body.forEach(function(e, idx) {
3679
        if (!e.length) {
3680
          if (idx > 0 && idx === body.length - 1) {
3681
            return;
3682
          }
3683
          error("E002", nt);
3684
          return;
3685
        }
3686

    
3687
        state.funct["(scope)"].addExported(e);
3688
      });
3689
    }
3690

    
3691
    if (nt.type === "members") {
3692
      membersOnly = membersOnly || {};
3693

    
3694
      body.forEach(function(m) {
3695
        var ch1 = m.charAt(0);
3696
        var ch2 = m.charAt(m.length - 1);
3697

    
3698
        if (ch1 === ch2 && (ch1 === "\"" || ch1 === "'")) {
3699
          m = m
3700
            .substr(1, m.length - 2)
3701
            .replace("\\\"", "\"");
3702
        }
3703

    
3704
        membersOnly[m] = false;
3705
      });
3706
    }
3707

    
3708
    var numvals = [
3709
      "maxstatements",
3710
      "maxparams",
3711
      "maxdepth",
3712
      "maxcomplexity",
3713
      "maxerr",
3714
      "maxlen",
3715
      "indent"
3716
    ];
3717

    
3718
    if (nt.type === "jshint" || nt.type === "jslint") {
3719
      body.forEach(function(g) {
3720
        g = g.split(":");
3721
        var key = (g[0] || "").trim();
3722
        var val = (g[1] || "").trim();
3723

    
3724
        if (!checkOption(key, nt)) {
3725
          return;
3726
        }
3727

    
3728
        if (numvals.indexOf(key) >= 0) {
3729
          if (val !== "false") {
3730
            val = +val;
3731

    
3732
            if (typeof val !== "number" || !isFinite(val) || val <= 0 || Math.floor(val) !== val) {
3733
              error("E032", nt, g[1].trim());
3734
              return;
3735
            }
3736

    
3737
            state.option[key] = val;
3738
          } else {
3739
            state.option[key] = key === "indent" ? 4 : false;
3740
          }
3741

    
3742
          return;
3743
        }
3744

    
3745
        if (key === "validthis") {
3746

    
3747
          if (state.funct["(global)"])
3748
            return void error("E009");
3749

    
3750
          if (val !== "true" && val !== "false")
3751
            return void error("E002", nt);
3752

    
3753
          state.option.validthis = (val === "true");
3754
          return;
3755
        }
3756

    
3757
        if (key === "quotmark") {
3758
          switch (val) {
3759
          case "true":
3760
          case "false":
3761
            state.option.quotmark = (val === "true");
3762
            break;
3763
          case "double":
3764
          case "single":
3765
            state.option.quotmark = val;
3766
            break;
3767
          default:
3768
            error("E002", nt);
3769
          }
3770
          return;
3771
        }
3772

    
3773
        if (key === "shadow") {
3774
          switch (val) {
3775
          case "true":
3776
            state.option.shadow = true;
3777
            break;
3778
          case "outer":
3779
            state.option.shadow = "outer";
3780
            break;
3781
          case "false":
3782
          case "inner":
3783
            state.option.shadow = "inner";
3784
            break;
3785
          default:
3786
            error("E002", nt);
3787
          }
3788
          return;
3789
        }
3790

    
3791
        if (key === "unused") {
3792
          switch (val) {
3793
          case "true":
3794
            state.option.unused = true;
3795
            break;
3796
          case "false":
3797
            state.option.unused = false;
3798
            break;
3799
          case "vars":
3800
          case "strict":
3801
            state.option.unused = val;
3802
            break;
3803
          default:
3804
            error("E002", nt);
3805
          }
3806
          return;
3807
        }
3808

    
3809
        if (key === "latedef") {
3810
          switch (val) {
3811
          case "true":
3812
            state.option.latedef = true;
3813
            break;
3814
          case "false":
3815
            state.option.latedef = false;
3816
            break;
3817
          case "nofunc":
3818
            state.option.latedef = "nofunc";
3819
            break;
3820
          default:
3821
            error("E002", nt);
3822
          }
3823
          return;
3824
        }
3825

    
3826
        if (key === "ignore") {
3827
          switch (val) {
3828
          case "line":
3829
            state.ignoredLines[nt.line] = true;
3830
            removeIgnoredMessages();
3831
            break;
3832
          default:
3833
            error("E002", nt);
3834
          }
3835
          return;
3836
        }
3837

    
3838
        if (key === "strict") {
3839
          switch (val) {
3840
          case "true":
3841
            state.option.strict = true;
3842
            break;
3843
          case "false":
3844
            state.option.strict = false;
3845
            break;
3846
          case "func":
3847
          case "global":
3848
          case "implied":
3849
            state.option.strict = val;
3850
            break;
3851
          default:
3852
            error("E002", nt);
3853
          }
3854
          return;
3855
        }
3856

    
3857
        if (key === "module") {
3858
          if (!hasParsedCode(state.funct)) {
3859
            error("E055", state.tokens.next, "module");
3860
          }
3861
        }
3862
        var esversions = {
3863
          es3   : 3,
3864
          es5   : 5,
3865
          esnext: 6
3866
        };
3867
        if (_.has(esversions, key)) {
3868
          switch (val) {
3869
          case "true":
3870
            state.option.moz = false;
3871
            state.option.esversion = esversions[key];
3872
            break;
3873
          case "false":
3874
            if (!state.option.moz) {
3875
              state.option.esversion = 5;
3876
            }
3877
            break;
3878
          default:
3879
            error("E002", nt);
3880
          }
3881
          return;
3882
        }
3883

    
3884
        if (key === "esversion") {
3885
          switch (val) {
3886
          case "5":
3887
            if (state.inES5(true)) {
3888
              warning("I003");
3889
            }
3890
          case "3":
3891
          case "6":
3892
            state.option.moz = false;
3893
            state.option.esversion = +val;
3894
            break;
3895
          case "2015":
3896
            state.option.moz = false;
3897
            state.option.esversion = 6;
3898
            break;
3899
          default:
3900
            error("E002", nt);
3901
          }
3902
          if (!hasParsedCode(state.funct)) {
3903
            error("E055", state.tokens.next, "esversion");
3904
          }
3905
          return;
3906
        }
3907

    
3908
        var match = /^([+-])(W\d{3})$/g.exec(key);
3909
        if (match) {
3910
          state.ignored[match[2]] = (match[1] === "-");
3911
          return;
3912
        }
3913

    
3914
        var tn;
3915
        if (val === "true" || val === "false") {
3916
          if (nt.type === "jslint") {
3917
            tn = options.renamed[key] || key;
3918
            state.option[tn] = (val === "true");
3919

    
3920
            if (options.inverted[tn] !== undefined) {
3921
              state.option[tn] = !state.option[tn];
3922
            }
3923
          } else {
3924
            state.option[key] = (val === "true");
3925
          }
3926

    
3927
          if (key === "newcap") {
3928
            state.option["(explicitNewcap)"] = true;
3929
          }
3930
          return;
3931
        }
3932

    
3933
        error("E002", nt);
3934
      });
3935

    
3936
      assume();
3937
    }
3938
  }
3939

    
3940
  function peek(p) {
3941
    var i = p || 0, j = lookahead.length, t;
3942

    
3943
    if (i < j) {
3944
      return lookahead[i];
3945
    }
3946

    
3947
    while (j <= i) {
3948
      t = lookahead[j];
3949
      if (!t) {
3950
        t = lookahead[j] = lex.token();
3951
      }
3952
      j += 1;
3953
    }
3954
    if (!t && state.tokens.next.id === "(end)") {
3955
      return state.tokens.next;
3956
    }
3957

    
3958
    return t;
3959
  }
3960

    
3961
  function peekIgnoreEOL() {
3962
    var i = 0;
3963
    var t;
3964
    do {
3965
      t = peek(i++);
3966
    } while (t.id === "(endline)");
3967
    return t;
3968
  }
3969

    
3970
  function advance(id, t) {
3971

    
3972
    switch (state.tokens.curr.id) {
3973
    case "(number)":
3974
      if (state.tokens.next.id === ".") {
3975
        warning("W005", state.tokens.curr);
3976
      }
3977
      break;
3978
    case "-":
3979
      if (state.tokens.next.id === "-" || state.tokens.next.id === "--") {
3980
        warning("W006");
3981
      }
3982
      break;
3983
    case "+":
3984
      if (state.tokens.next.id === "+" || state.tokens.next.id === "++") {
3985
        warning("W007");
3986
      }
3987
      break;
3988
    }
3989

    
3990
    if (id && state.tokens.next.id !== id) {
3991
      if (t) {
3992
        if (state.tokens.next.id === "(end)") {
3993
          error("E019", t, t.id);
3994
        } else {
3995
          error("E020", state.tokens.next, id, t.id, t.line, state.tokens.next.value);
3996
        }
3997
      } else if (state.tokens.next.type !== "(identifier)" || state.tokens.next.value !== id) {
3998
        warning("W116", state.tokens.next, id, state.tokens.next.value);
3999
      }
4000
    }
4001

    
4002
    state.tokens.prev = state.tokens.curr;
4003
    state.tokens.curr = state.tokens.next;
4004
    for (;;) {
4005
      state.tokens.next = lookahead.shift() || lex.token();
4006

    
4007
      if (!state.tokens.next) { // No more tokens left, give up
4008
        quit("E041", state.tokens.curr.line);
4009
      }
4010

    
4011
      if (state.tokens.next.id === "(end)" || state.tokens.next.id === "(error)") {
4012
        return;
4013
      }
4014

    
4015
      if (state.tokens.next.check) {
4016
        state.tokens.next.check();
4017
      }
4018

    
4019
      if (state.tokens.next.isSpecial) {
4020
        if (state.tokens.next.type === "falls through") {
4021
          state.tokens.curr.caseFallsThrough = true;
4022
        } else {
4023
          doOption();
4024
        }
4025
      } else {
4026
        if (state.tokens.next.id !== "(endline)") {
4027
          break;
4028
        }
4029
      }
4030
    }
4031
  }
4032

    
4033
  function isInfix(token) {
4034
    return token.infix || (!token.identifier && !token.template && !!token.led);
4035
  }
4036

    
4037
  function isEndOfExpr() {
4038
    var curr = state.tokens.curr;
4039
    var next = state.tokens.next;
4040
    if (next.id === ";" || next.id === "}" || next.id === ":") {
4041
      return true;
4042
    }
4043
    if (isInfix(next) === isInfix(curr) || (curr.id === "yield" && state.inMoz())) {
4044
      return curr.line !== startLine(next);
4045
    }
4046
    return false;
4047
  }
4048

    
4049
  function isBeginOfExpr(prev) {
4050
    return !prev.left && prev.arity !== "unary";
4051
  }
4052

    
4053
  function expression(rbp, initial) {
4054
    var left, isArray = false, isObject = false, isLetExpr = false;
4055

    
4056
    state.nameStack.push();
4057
    if (!initial && state.tokens.next.value === "let" && peek(0).value === "(") {
4058
      if (!state.inMoz()) {
4059
        warning("W118", state.tokens.next, "let expressions");
4060
      }
4061
      isLetExpr = true;
4062
      state.funct["(scope)"].stack();
4063
      advance("let");
4064
      advance("(");
4065
      state.tokens.prev.fud();
4066
      advance(")");
4067
    }
4068

    
4069
    if (state.tokens.next.id === "(end)")
4070
      error("E006", state.tokens.curr);
4071

    
4072
    var isDangerous =
4073
      state.option.asi &&
4074
      state.tokens.prev.line !== startLine(state.tokens.curr) &&
4075
      _.contains(["]", ")"], state.tokens.prev.id) &&
4076
      _.contains(["[", "("], state.tokens.curr.id);
4077

    
4078
    if (isDangerous)
4079
      warning("W014", state.tokens.curr, state.tokens.curr.id);
4080

    
4081
    advance();
4082

    
4083
    if (initial) {
4084
      state.funct["(verb)"] = state.tokens.curr.value;
4085
      state.tokens.curr.beginsStmt = true;
4086
    }
4087

    
4088
    if (initial === true && state.tokens.curr.fud) {
4089
      left = state.tokens.curr.fud();
4090
    } else {
4091
      if (state.tokens.curr.nud) {
4092
        left = state.tokens.curr.nud();
4093
      } else {
4094
        error("E030", state.tokens.curr, state.tokens.curr.id);
4095
      }
4096
      while ((rbp < state.tokens.next.lbp || state.tokens.next.type === "(template)") &&
4097
              !isEndOfExpr()) {
4098
        isArray = state.tokens.curr.value === "Array";
4099
        isObject = state.tokens.curr.value === "Object";
4100
        if (left && (left.value || (left.first && left.first.value))) {
4101
          if (left.value !== "new" ||
4102
            (left.first && left.first.value && left.first.value === ".")) {
4103
            isArray = false;
4104
            if (left.value !== state.tokens.curr.value) {
4105
              isObject = false;
4106
            }
4107
          }
4108
        }
4109

    
4110
        advance();
4111

    
4112
        if (isArray && state.tokens.curr.id === "(" && state.tokens.next.id === ")") {
4113
          warning("W009", state.tokens.curr);
4114
        }
4115

    
4116
        if (isObject && state.tokens.curr.id === "(" && state.tokens.next.id === ")") {
4117
          warning("W010", state.tokens.curr);
4118
        }
4119

    
4120
        if (left && state.tokens.curr.led) {
4121
          left = state.tokens.curr.led(left);
4122
        } else {
4123
          error("E033", state.tokens.curr, state.tokens.curr.id);
4124
        }
4125
      }
4126
    }
4127
    if (isLetExpr) {
4128
      state.funct["(scope)"].unstack();
4129
    }
4130

    
4131
    state.nameStack.pop();
4132

    
4133
    return left;
4134
  }
4135

    
4136
  function startLine(token) {
4137
    return token.startLine || token.line;
4138
  }
4139

    
4140
  function nobreaknonadjacent(left, right) {
4141
    left = left || state.tokens.curr;
4142
    right = right || state.tokens.next;
4143
    if (!state.option.laxbreak && left.line !== startLine(right)) {
4144
      warning("W014", right, right.value);
4145
    }
4146
  }
4147

    
4148
  function nolinebreak(t) {
4149
    t = t || state.tokens.curr;
4150
    if (t.line !== startLine(state.tokens.next)) {
4151
      warning("E022", t, t.value);
4152
    }
4153
  }
4154

    
4155
  function nobreakcomma(left, right) {
4156
    if (left.line !== startLine(right)) {
4157
      if (!state.option.laxcomma) {
4158
        if (comma.first) {
4159
          warning("I001");
4160
          comma.first = false;
4161
        }
4162
        warning("W014", left, right.value);
4163
      }
4164
    }
4165
  }
4166

    
4167
  function comma(opts) {
4168
    opts = opts || {};
4169

    
4170
    if (!opts.peek) {
4171
      nobreakcomma(state.tokens.curr, state.tokens.next);
4172
      advance(",");
4173
    } else {
4174
      nobreakcomma(state.tokens.prev, state.tokens.curr);
4175
    }
4176

    
4177
    if (state.tokens.next.identifier && !(opts.property && state.inES5())) {
4178
      switch (state.tokens.next.value) {
4179
      case "break":
4180
      case "case":
4181
      case "catch":
4182
      case "continue":
4183
      case "default":
4184
      case "do":
4185
      case "else":
4186
      case "finally":
4187
      case "for":
4188
      case "if":
4189
      case "in":
4190
      case "instanceof":
4191
      case "return":
4192
      case "switch":
4193
      case "throw":
4194
      case "try":
4195
      case "var":
4196
      case "let":
4197
      case "while":
4198
      case "with":
4199
        error("E024", state.tokens.next, state.tokens.next.value);
4200
        return false;
4201
      }
4202
    }
4203

    
4204
    if (state.tokens.next.type === "(punctuator)") {
4205
      switch (state.tokens.next.value) {
4206
      case "}":
4207
      case "]":
4208
      case ",":
4209
        if (opts.allowTrailing) {
4210
          return true;
4211
        }
4212
      case ")":
4213
        error("E024", state.tokens.next, state.tokens.next.value);
4214
        return false;
4215
      }
4216
    }
4217
    return true;
4218
  }
4219

    
4220
  function symbol(s, p) {
4221
    var x = state.syntax[s];
4222
    if (!x || typeof x !== "object") {
4223
      state.syntax[s] = x = {
4224
        id: s,
4225
        lbp: p,
4226
        value: s
4227
      };
4228
    }
4229
    return x;
4230
  }
4231

    
4232
  function delim(s) {
4233
    var x = symbol(s, 0);
4234
    x.delim = true;
4235
    return x;
4236
  }
4237

    
4238
  function stmt(s, f) {
4239
    var x = delim(s);
4240
    x.identifier = x.reserved = true;
4241
    x.fud = f;
4242
    return x;
4243
  }
4244

    
4245
  function blockstmt(s, f) {
4246
    var x = stmt(s, f);
4247
    x.block = true;
4248
    return x;
4249
  }
4250

    
4251
  function reserveName(x) {
4252
    var c = x.id.charAt(0);
4253
    if ((c >= "a" && c <= "z") || (c >= "A" && c <= "Z")) {
4254
      x.identifier = x.reserved = true;
4255
    }
4256
    return x;
4257
  }
4258

    
4259
  function prefix(s, f) {
4260
    var x = symbol(s, 150);
4261
    reserveName(x);
4262

    
4263
    x.nud = (typeof f === "function") ? f : function() {
4264
      this.arity = "unary";
4265
      this.right = expression(150);
4266

    
4267
      if (this.id === "++" || this.id === "--") {
4268
        if (state.option.plusplus) {
4269
          warning("W016", this, this.id);
4270
        } else if (this.right && (!this.right.identifier || isReserved(this.right)) &&
4271
            this.right.id !== "." && this.right.id !== "[") {
4272
          warning("W017", this);
4273
        }
4274

    
4275
        if (this.right && this.right.isMetaProperty) {
4276
          error("E031", this);
4277
        } else if (this.right && this.right.identifier) {
4278
          state.funct["(scope)"].block.modify(this.right.value, this);
4279
        }
4280
      }
4281

    
4282
      return this;
4283
    };
4284

    
4285
    return x;
4286
  }
4287

    
4288
  function type(s, f) {
4289
    var x = delim(s);
4290
    x.type = s;
4291
    x.nud = f;
4292
    return x;
4293
  }
4294

    
4295
  function reserve(name, func) {
4296
    var x = type(name, func);
4297
    x.identifier = true;
4298
    x.reserved = true;
4299
    return x;
4300
  }
4301

    
4302
  function FutureReservedWord(name, meta) {
4303
    var x = type(name, (meta && meta.nud) || function() {
4304
      return this;
4305
    });
4306

    
4307
    meta = meta || {};
4308
    meta.isFutureReservedWord = true;
4309

    
4310
    x.value = name;
4311
    x.identifier = true;
4312
    x.reserved = true;
4313
    x.meta = meta;
4314

    
4315
    return x;
4316
  }
4317

    
4318
  function reservevar(s, v) {
4319
    return reserve(s, function() {
4320
      if (typeof v === "function") {
4321
        v(this);
4322
      }
4323
      return this;
4324
    });
4325
  }
4326

    
4327
  function infix(s, f, p, w) {
4328
    var x = symbol(s, p);
4329
    reserveName(x);
4330
    x.infix = true;
4331
    x.led = function(left) {
4332
      if (!w) {
4333
        nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
4334
      }
4335
      if ((s === "in" || s === "instanceof") && left.id === "!") {
4336
        warning("W018", left, "!");
4337
      }
4338
      if (typeof f === "function") {
4339
        return f(left, this);
4340
      } else {
4341
        this.left = left;
4342
        this.right = expression(p);
4343
        return this;
4344
      }
4345
    };
4346
    return x;
4347
  }
4348

    
4349
  function application(s) {
4350
    var x = symbol(s, 42);
4351

    
4352
    x.led = function(left) {
4353
      nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
4354

    
4355
      this.left = left;
4356
      this.right = doFunction({ type: "arrow", loneArg: left });
4357
      return this;
4358
    };
4359
    return x;
4360
  }
4361

    
4362
  function relation(s, f) {
4363
    var x = symbol(s, 100);
4364

    
4365
    x.led = function(left) {
4366
      nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
4367
      this.left = left;
4368
      var right = this.right = expression(100);
4369

    
4370
      if (isIdentifier(left, "NaN") || isIdentifier(right, "NaN")) {
4371
        warning("W019", this);
4372
      } else if (f) {
4373
        f.apply(this, [left, right]);
4374
      }
4375

    
4376
      if (!left || !right) {
4377
        quit("E041", state.tokens.curr.line);
4378
      }
4379

    
4380
      if (left.id === "!") {
4381
        warning("W018", left, "!");
4382
      }
4383

    
4384
      if (right.id === "!") {
4385
        warning("W018", right, "!");
4386
      }
4387

    
4388
      return this;
4389
    };
4390
    return x;
4391
  }
4392

    
4393
  function isPoorRelation(node) {
4394
    return node &&
4395
        ((node.type === "(number)" && +node.value === 0) ||
4396
         (node.type === "(string)" && node.value === "") ||
4397
         (node.type === "null" && !state.option.eqnull) ||
4398
        node.type === "true" ||
4399
        node.type === "false" ||
4400
        node.type === "undefined");
4401
  }
4402

    
4403
  var typeofValues = {};
4404
  typeofValues.legacy = [
4405
    "xml",
4406
    "unknown"
4407
  ];
4408
  typeofValues.es3 = [
4409
    "undefined", "boolean", "number", "string", "function", "object",
4410
  ];
4411
  typeofValues.es3 = typeofValues.es3.concat(typeofValues.legacy);
4412
  typeofValues.es6 = typeofValues.es3.concat("symbol");
4413
  function isTypoTypeof(left, right, state) {
4414
    var values;
4415

    
4416
    if (state.option.notypeof)
4417
      return false;
4418

    
4419
    if (!left || !right)
4420
      return false;
4421

    
4422
    values = state.inES6() ? typeofValues.es6 : typeofValues.es3;
4423

    
4424
    if (right.type === "(identifier)" && right.value === "typeof" && left.type === "(string)")
4425
      return !_.contains(values, left.value);
4426

    
4427
    return false;
4428
  }
4429

    
4430
  function isGlobalEval(left, state) {
4431
    var isGlobal = false;
4432
    if (left.type === "this" && state.funct["(context)"] === null) {
4433
      isGlobal = true;
4434
    }
4435
    else if (left.type === "(identifier)") {
4436
      if (state.option.node && left.value === "global") {
4437
        isGlobal = true;
4438
      }
4439

    
4440
      else if (state.option.browser && (left.value === "window" || left.value === "document")) {
4441
        isGlobal = true;
4442
      }
4443
    }
4444

    
4445
    return isGlobal;
4446
  }
4447

    
4448
  function findNativePrototype(left) {
4449
    var natives = [
4450
      "Array", "ArrayBuffer", "Boolean", "Collator", "DataView", "Date",
4451
      "DateTimeFormat", "Error", "EvalError", "Float32Array", "Float64Array",
4452
      "Function", "Infinity", "Intl", "Int16Array", "Int32Array", "Int8Array",
4453
      "Iterator", "Number", "NumberFormat", "Object", "RangeError",
4454
      "ReferenceError", "RegExp", "StopIteration", "String", "SyntaxError",
4455
      "TypeError", "Uint16Array", "Uint32Array", "Uint8Array", "Uint8ClampedArray",
4456
      "URIError"
4457
    ];
4458

    
4459
    function walkPrototype(obj) {
4460
      if (typeof obj !== "object") return;
4461
      return obj.right === "prototype" ? obj : walkPrototype(obj.left);
4462
    }
4463

    
4464
    function walkNative(obj) {
4465
      while (!obj.identifier && typeof obj.left === "object")
4466
        obj = obj.left;
4467

    
4468
      if (obj.identifier && natives.indexOf(obj.value) >= 0)
4469
        return obj.value;
4470
    }
4471

    
4472
    var prototype = walkPrototype(left);
4473
    if (prototype) return walkNative(prototype);
4474
  }
4475
  function checkLeftSideAssign(left, assignToken, options) {
4476

    
4477
    var allowDestructuring = options && options.allowDestructuring;
4478

    
4479
    assignToken = assignToken || left;
4480

    
4481
    if (state.option.freeze) {
4482
      var nativeObject = findNativePrototype(left);
4483
      if (nativeObject)
4484
        warning("W121", left, nativeObject);
4485
    }
4486

    
4487
    if (left.identifier && !left.isMetaProperty) {
4488
      state.funct["(scope)"].block.reassign(left.value, left);
4489
    }
4490

    
4491
    if (left.id === ".") {
4492
      if (!left.left || left.left.value === "arguments" && !state.isStrict()) {
4493
        warning("E031", assignToken);
4494
      }
4495

    
4496
      state.nameStack.set(state.tokens.prev);
4497
      return true;
4498
    } else if (left.id === "{" || left.id === "[") {
4499
      if (allowDestructuring && state.tokens.curr.left.destructAssign) {
4500
        state.tokens.curr.left.destructAssign.forEach(function(t) {
4501
          if (t.id) {
4502
            state.funct["(scope)"].block.modify(t.id, t.token);
4503
          }
4504
        });
4505
      } else {
4506
        if (left.id === "{" || !left.left) {
4507
          warning("E031", assignToken);
4508
        } else if (left.left.value === "arguments" && !state.isStrict()) {
4509
          warning("E031", assignToken);
4510
        }
4511
      }
4512

    
4513
      if (left.id === "[") {
4514
        state.nameStack.set(left.right);
4515
      }
4516

    
4517
      return true;
4518
    } else if (left.isMetaProperty) {
4519
      error("E031", assignToken);
4520
      return true;
4521
    } else if (left.identifier && !isReserved(left)) {
4522
      if (state.funct["(scope)"].labeltype(left.value) === "exception") {
4523
        warning("W022", left);
4524
      }
4525
      state.nameStack.set(left);
4526
      return true;
4527
    }
4528

    
4529
    if (left === state.syntax["function"]) {
4530
      warning("W023", state.tokens.curr);
4531
    }
4532

    
4533
    return false;
4534
  }
4535

    
4536
  function assignop(s, f, p) {
4537
    var x = infix(s, typeof f === "function" ? f : function(left, that) {
4538
      that.left = left;
4539

    
4540
      if (left && checkLeftSideAssign(left, that, { allowDestructuring: true })) {
4541
        that.right = expression(10);
4542
        return that;
4543
      }
4544

    
4545
      error("E031", that);
4546
    }, p);
4547

    
4548
    x.exps = true;
4549
    x.assign = true;
4550
    return x;
4551
  }
4552

    
4553

    
4554
  function bitwise(s, f, p) {
4555
    var x = symbol(s, p);
4556
    reserveName(x);
4557
    x.led = (typeof f === "function") ? f : function(left) {
4558
      if (state.option.bitwise) {
4559
        warning("W016", this, this.id);
4560
      }
4561
      this.left = left;
4562
      this.right = expression(p);
4563
      return this;
4564
    };
4565
    return x;
4566
  }
4567

    
4568
  function bitwiseassignop(s) {
4569
    return assignop(s, function(left, that) {
4570
      if (state.option.bitwise) {
4571
        warning("W016", that, that.id);
4572
      }
4573

    
4574
      if (left && checkLeftSideAssign(left, that)) {
4575
        that.right = expression(10);
4576
        return that;
4577
      }
4578
      error("E031", that);
4579
    }, 20);
4580
  }
4581

    
4582
  function suffix(s) {
4583
    var x = symbol(s, 150);
4584

    
4585
    x.led = function(left) {
4586
      if (state.option.plusplus) {
4587
        warning("W016", this, this.id);
4588
      } else if ((!left.identifier || isReserved(left)) && left.id !== "." && left.id !== "[") {
4589
        warning("W017", this);
4590
      }
4591

    
4592
      if (left.isMetaProperty) {
4593
        error("E031", this);
4594
      } else if (left && left.identifier) {
4595
        state.funct["(scope)"].block.modify(left.value, left);
4596
      }
4597

    
4598
      this.left = left;
4599
      return this;
4600
    };
4601
    return x;
4602
  }
4603

    
4604
  function optionalidentifier(fnparam, prop, preserve) {
4605
    if (!state.tokens.next.identifier) {
4606
      return;
4607
    }
4608

    
4609
    if (!preserve) {
4610
      advance();
4611
    }
4612

    
4613
    var curr = state.tokens.curr;
4614
    var val  = state.tokens.curr.value;
4615

    
4616
    if (!isReserved(curr)) {
4617
      return val;
4618
    }
4619

    
4620
    if (prop) {
4621
      if (state.inES5()) {
4622
        return val;
4623
      }
4624
    }
4625

    
4626
    if (fnparam && val === "undefined") {
4627
      return val;
4628
    }
4629

    
4630
    warning("W024", state.tokens.curr, state.tokens.curr.id);
4631
    return val;
4632
  }
4633
  function identifier(fnparam, prop) {
4634
    var i = optionalidentifier(fnparam, prop, false);
4635
    if (i) {
4636
      return i;
4637
    }
4638
    if (state.tokens.next.value === "...") {
4639
      if (!state.inES6(true)) {
4640
        warning("W119", state.tokens.next, "spread/rest operator", "6");
4641
      }
4642
      advance();
4643

    
4644
      if (checkPunctuator(state.tokens.next, "...")) {
4645
        warning("E024", state.tokens.next, "...");
4646
        while (checkPunctuator(state.tokens.next, "...")) {
4647
          advance();
4648
        }
4649
      }
4650

    
4651
      if (!state.tokens.next.identifier) {
4652
        warning("E024", state.tokens.curr, "...");
4653
        return;
4654
      }
4655

    
4656
      return identifier(fnparam, prop);
4657
    } else {
4658
      error("E030", state.tokens.next, state.tokens.next.value);
4659
      if (state.tokens.next.id !== ";") {
4660
        advance();
4661
      }
4662
    }
4663
  }
4664

    
4665

    
4666
  function reachable(controlToken) {
4667
    var i = 0, t;
4668
    if (state.tokens.next.id !== ";" || controlToken.inBracelessBlock) {
4669
      return;
4670
    }
4671
    for (;;) {
4672
      do {
4673
        t = peek(i);
4674
        i += 1;
4675
      } while (t.id !== "(end)" && t.id === "(comment)");
4676

    
4677
      if (t.reach) {
4678
        return;
4679
      }
4680
      if (t.id !== "(endline)") {
4681
        if (t.id === "function") {
4682
          if (state.option.latedef === true) {
4683
            warning("W026", t);
4684
          }
4685
          break;
4686
        }
4687

    
4688
        warning("W027", t, t.value, controlToken.value);
4689
        break;
4690
      }
4691
    }
4692
  }
4693

    
4694
  function parseFinalSemicolon() {
4695
    if (state.tokens.next.id !== ";") {
4696
      if (state.tokens.next.isUnclosed) return advance();
4697

    
4698
      var sameLine = startLine(state.tokens.next) === state.tokens.curr.line &&
4699
                     state.tokens.next.id !== "(end)";
4700
      var blockEnd = checkPunctuator(state.tokens.next, "}");
4701

    
4702
      if (sameLine && !blockEnd) {
4703
        errorAt("E058", state.tokens.curr.line, state.tokens.curr.character);
4704
      } else if (!state.option.asi) {
4705
        if ((blockEnd && !state.option.lastsemic) || !sameLine) {
4706
          warningAt("W033", state.tokens.curr.line, state.tokens.curr.character);
4707
        }
4708
      }
4709
    } else {
4710
      advance(";");
4711
    }
4712
  }
4713

    
4714
  function statement() {
4715
    var i = indent, r, t = state.tokens.next, hasOwnScope = false;
4716

    
4717
    if (t.id === ";") {
4718
      advance(";");
4719
      return;
4720
    }
4721
    var res = isReserved(t);
4722

    
4723
    if (res && t.meta && t.meta.isFutureReservedWord && peek().id === ":") {
4724
      warning("W024", t, t.id);
4725
      res = false;
4726
    }
4727

    
4728
    if (t.identifier && !res && peek().id === ":") {
4729
      advance();
4730
      advance(":");
4731

    
4732
      hasOwnScope = true;
4733
      state.funct["(scope)"].stack();
4734
      state.funct["(scope)"].block.addBreakLabel(t.value, { token: state.tokens.curr });
4735

    
4736
      if (!state.tokens.next.labelled && state.tokens.next.value !== "{") {
4737
        warning("W028", state.tokens.next, t.value, state.tokens.next.value);
4738
      }
4739

    
4740
      state.tokens.next.label = t.value;
4741
      t = state.tokens.next;
4742
    }
4743

    
4744
    if (t.id === "{") {
4745
      var iscase = (state.funct["(verb)"] === "case" && state.tokens.curr.value === ":");
4746
      block(true, true, false, false, iscase);
4747
      return;
4748
    }
4749

    
4750
    r = expression(0, true);
4751

    
4752
    if (r && !(r.identifier && r.value === "function") &&
4753
        !(r.type === "(punctuator)" && r.left &&
4754
          r.left.identifier && r.left.value === "function")) {
4755
      if (!state.isStrict() &&
4756
          state.option.strict === "global") {
4757
        warning("E007");
4758
      }
4759
    }
4760

    
4761
    if (!t.block) {
4762
      if (!state.option.expr && (!r || !r.exps)) {
4763
        warning("W030", state.tokens.curr);
4764
      } else if (state.option.nonew && r && r.left && r.id === "(" && r.left.id === "new") {
4765
        warning("W031", t);
4766
      }
4767
      parseFinalSemicolon();
4768
    }
4769

    
4770
    indent = i;
4771
    if (hasOwnScope) {
4772
      state.funct["(scope)"].unstack();
4773
    }
4774
    return r;
4775
  }
4776

    
4777

    
4778
  function statements() {
4779
    var a = [], p;
4780

    
4781
    while (!state.tokens.next.reach && state.tokens.next.id !== "(end)") {
4782
      if (state.tokens.next.id === ";") {
4783
        p = peek();
4784

    
4785
        if (!p || (p.id !== "(" && p.id !== "[")) {
4786
          warning("W032");
4787
        }
4788

    
4789
        advance(";");
4790
      } else {
4791
        a.push(statement());
4792
      }
4793
    }
4794
    return a;
4795
  }
4796
  function directives() {
4797
    var i, p, pn;
4798

    
4799
    while (state.tokens.next.id === "(string)") {
4800
      p = peek(0);
4801
      if (p.id === "(endline)") {
4802
        i = 1;
4803
        do {
4804
          pn = peek(i++);
4805
        } while (pn.id === "(endline)");
4806
        if (pn.id === ";") {
4807
          p = pn;
4808
        } else if (pn.value === "[" || pn.value === ".") {
4809
          break;
4810
        } else if (!state.option.asi || pn.value === "(") {
4811
          warning("W033", state.tokens.next);
4812
        }
4813
      } else if (p.id === "." || p.id === "[") {
4814
        break;
4815
      } else if (p.id !== ";") {
4816
        warning("W033", p);
4817
      }
4818

    
4819
      advance();
4820
      var directive = state.tokens.curr.value;
4821
      if (state.directive[directive] ||
4822
          (directive === "use strict" && state.option.strict === "implied")) {
4823
        warning("W034", state.tokens.curr, directive);
4824
      }
4825
      state.directive[directive] = true;
4826

    
4827
      if (p.id === ";") {
4828
        advance(";");
4829
      }
4830
    }
4831

    
4832
    if (state.isStrict()) {
4833
      if (!state.option["(explicitNewcap)"]) {
4834
        state.option.newcap = true;
4835
      }
4836
      state.option.undef = true;
4837
    }
4838
  }
4839
  function block(ordinary, stmt, isfunc, isfatarrow, iscase) {
4840
    var a,
4841
      b = inblock,
4842
      old_indent = indent,
4843
      m,
4844
      t,
4845
      line,
4846
      d;
4847

    
4848
    inblock = ordinary;
4849

    
4850
    t = state.tokens.next;
4851

    
4852
    var metrics = state.funct["(metrics)"];
4853
    metrics.nestedBlockDepth += 1;
4854
    metrics.verifyMaxNestedBlockDepthPerFunction();
4855

    
4856
    if (state.tokens.next.id === "{") {
4857
      advance("{");
4858
      state.funct["(scope)"].stack();
4859

    
4860
      line = state.tokens.curr.line;
4861
      if (state.tokens.next.id !== "}") {
4862
        indent += state.option.indent;
4863
        while (!ordinary && state.tokens.next.from > indent) {
4864
          indent += state.option.indent;
4865
        }
4866

    
4867
        if (isfunc) {
4868
          m = {};
4869
          for (d in state.directive) {
4870
            if (_.has(state.directive, d)) {
4871
              m[d] = state.directive[d];
4872
            }
4873
          }
4874
          directives();
4875

    
4876
          if (state.option.strict && state.funct["(context)"]["(global)"]) {
4877
            if (!m["use strict"] && !state.isStrict()) {
4878
              warning("E007");
4879
            }
4880
          }
4881
        }
4882

    
4883
        a = statements();
4884

    
4885
        metrics.statementCount += a.length;
4886

    
4887
        indent -= state.option.indent;
4888
      }
4889

    
4890
      advance("}", t);
4891

    
4892
      if (isfunc) {
4893
        state.funct["(scope)"].validateParams();
4894
        if (m) {
4895
          state.directive = m;
4896
        }
4897
      }
4898

    
4899
      state.funct["(scope)"].unstack();
4900

    
4901
      indent = old_indent;
4902
    } else if (!ordinary) {
4903
      if (isfunc) {
4904
        state.funct["(scope)"].stack();
4905

    
4906
        m = {};
4907
        if (stmt && !isfatarrow && !state.inMoz()) {
4908
          error("W118", state.tokens.curr, "function closure expressions");
4909
        }
4910

    
4911
        if (!stmt) {
4912
          for (d in state.directive) {
4913
            if (_.has(state.directive, d)) {
4914
              m[d] = state.directive[d];
4915
            }
4916
          }
4917
        }
4918
        expression(10);
4919

    
4920
        if (state.option.strict && state.funct["(context)"]["(global)"]) {
4921
          if (!m["use strict"] && !state.isStrict()) {
4922
            warning("E007");
4923
          }
4924
        }
4925

    
4926
        state.funct["(scope)"].unstack();
4927
      } else {
4928
        error("E021", state.tokens.next, "{", state.tokens.next.value);
4929
      }
4930
    } else {
4931
      state.funct["(noblockscopedvar)"] = state.tokens.next.id !== "for";
4932
      state.funct["(scope)"].stack();
4933

    
4934
      if (!stmt || state.option.curly) {
4935
        warning("W116", state.tokens.next, "{", state.tokens.next.value);
4936
      }
4937

    
4938
      state.tokens.next.inBracelessBlock = true;
4939
      indent += state.option.indent;
4940
      a = [statement()];
4941
      indent -= state.option.indent;
4942

    
4943
      state.funct["(scope)"].unstack();
4944
      delete state.funct["(noblockscopedvar)"];
4945
    }
4946
    switch (state.funct["(verb)"]) {
4947
    case "break":
4948
    case "continue":
4949
    case "return":
4950
    case "throw":
4951
      if (iscase) {
4952
        break;
4953
      }
4954
    default:
4955
      state.funct["(verb)"] = null;
4956
    }
4957

    
4958
    inblock = b;
4959
    if (ordinary && state.option.noempty && (!a || a.length === 0)) {
4960
      warning("W035", state.tokens.prev);
4961
    }
4962
    metrics.nestedBlockDepth -= 1;
4963
    return a;
4964
  }
4965

    
4966

    
4967
  function countMember(m) {
4968
    if (membersOnly && typeof membersOnly[m] !== "boolean") {
4969
      warning("W036", state.tokens.curr, m);
4970
    }
4971
    if (typeof member[m] === "number") {
4972
      member[m] += 1;
4973
    } else {
4974
      member[m] = 1;
4975
    }
4976
  }
4977

    
4978
  type("(number)", function() {
4979
    return this;
4980
  });
4981

    
4982
  type("(string)", function() {
4983
    return this;
4984
  });
4985

    
4986
  state.syntax["(identifier)"] = {
4987
    type: "(identifier)",
4988
    lbp: 0,
4989
    identifier: true,
4990

    
4991
    nud: function() {
4992
      var v = this.value;
4993
      if (state.tokens.next.id === "=>") {
4994
        return this;
4995
      }
4996

    
4997
      if (!state.funct["(comparray)"].check(v)) {
4998
        state.funct["(scope)"].block.use(v, state.tokens.curr);
4999
      }
5000
      return this;
5001
    },
5002

    
5003
    led: function() {
5004
      error("E033", state.tokens.next, state.tokens.next.value);
5005
    }
5006
  };
5007

    
5008
  var baseTemplateSyntax = {
5009
    lbp: 0,
5010
    identifier: false,
5011
    template: true,
5012
  };
5013
  state.syntax["(template)"] = _.extend({
5014
    type: "(template)",
5015
    nud: doTemplateLiteral,
5016
    led: doTemplateLiteral,
5017
    noSubst: false
5018
  }, baseTemplateSyntax);
5019

    
5020
  state.syntax["(template middle)"] = _.extend({
5021
    type: "(template middle)",
5022
    middle: true,
5023
    noSubst: false
5024
  }, baseTemplateSyntax);
5025

    
5026
  state.syntax["(template tail)"] = _.extend({
5027
    type: "(template tail)",
5028
    tail: true,
5029
    noSubst: false
5030
  }, baseTemplateSyntax);
5031

    
5032
  state.syntax["(no subst template)"] = _.extend({
5033
    type: "(template)",
5034
    nud: doTemplateLiteral,
5035
    led: doTemplateLiteral,
5036
    noSubst: true,
5037
    tail: true // mark as tail, since it's always the last component
5038
  }, baseTemplateSyntax);
5039

    
5040
  type("(regexp)", function() {
5041
    return this;
5042
  });
5043

    
5044
  delim("(endline)");
5045
  delim("(begin)");
5046
  delim("(end)").reach = true;
5047
  delim("(error)").reach = true;
5048
  delim("}").reach = true;
5049
  delim(")");
5050
  delim("]");
5051
  delim("\"").reach = true;
5052
  delim("'").reach = true;
5053
  delim(";");
5054
  delim(":").reach = true;
5055
  delim("#");
5056

    
5057
  reserve("else");
5058
  reserve("case").reach = true;
5059
  reserve("catch");
5060
  reserve("default").reach = true;
5061
  reserve("finally");
5062
  reservevar("arguments", function(x) {
5063
    if (state.isStrict() && state.funct["(global)"]) {
5064
      warning("E008", x);
5065
    }
5066
  });
5067
  reservevar("eval");
5068
  reservevar("false");
5069
  reservevar("Infinity");
5070
  reservevar("null");
5071
  reservevar("this", function(x) {
5072
    if (state.isStrict() && !isMethod() &&
5073
        !state.option.validthis && ((state.funct["(statement)"] &&
5074
        state.funct["(name)"].charAt(0) > "Z") || state.funct["(global)"])) {
5075
      warning("W040", x);
5076
    }
5077
  });
5078
  reservevar("true");
5079
  reservevar("undefined");
5080

    
5081
  assignop("=", "assign", 20);
5082
  assignop("+=", "assignadd", 20);
5083
  assignop("-=", "assignsub", 20);
5084
  assignop("*=", "assignmult", 20);
5085
  assignop("/=", "assigndiv", 20).nud = function() {
5086
    error("E014");
5087
  };
5088
  assignop("%=", "assignmod", 20);
5089

    
5090
  bitwiseassignop("&=");
5091
  bitwiseassignop("|=");
5092
  bitwiseassignop("^=");
5093
  bitwiseassignop("<<=");
5094
  bitwiseassignop(">>=");
5095
  bitwiseassignop(">>>=");
5096
  infix(",", function(left, that) {
5097
    var expr;
5098
    that.exprs = [left];
5099

    
5100
    if (state.option.nocomma) {
5101
      warning("W127");
5102
    }
5103

    
5104
    if (!comma({ peek: true })) {
5105
      return that;
5106
    }
5107
    while (true) {
5108
      if (!(expr = expression(10))) {
5109
        break;
5110
      }
5111
      that.exprs.push(expr);
5112
      if (state.tokens.next.value !== "," || !comma()) {
5113
        break;
5114
      }
5115
    }
5116
    return that;
5117
  }, 10, true);
5118

    
5119
  infix("?", function(left, that) {
5120
    increaseComplexityCount();
5121
    that.left = left;
5122
    that.right = expression(10);
5123
    advance(":");
5124
    that["else"] = expression(10);
5125
    return that;
5126
  }, 30);
5127

    
5128
  var orPrecendence = 40;
5129
  infix("||", function(left, that) {
5130
    increaseComplexityCount();
5131
    that.left = left;
5132
    that.right = expression(orPrecendence);
5133
    return that;
5134
  }, orPrecendence);
5135
  infix("&&", "and", 50);
5136
  bitwise("|", "bitor", 70);
5137
  bitwise("^", "bitxor", 80);
5138
  bitwise("&", "bitand", 90);
5139
  relation("==", function(left, right) {
5140
    var eqnull = state.option.eqnull &&
5141
      ((left && left.value) === "null" || (right && right.value) === "null");
5142

    
5143
    switch (true) {
5144
      case !eqnull && state.option.eqeqeq:
5145
        this.from = this.character;
5146
        warning("W116", this, "===", "==");
5147
        break;
5148
      case isPoorRelation(left):
5149
        warning("W041", this, "===", left.value);
5150
        break;
5151
      case isPoorRelation(right):
5152
        warning("W041", this, "===", right.value);
5153
        break;
5154
      case isTypoTypeof(right, left, state):
5155
        warning("W122", this, right.value);
5156
        break;
5157
      case isTypoTypeof(left, right, state):
5158
        warning("W122", this, left.value);
5159
        break;
5160
    }
5161

    
5162
    return this;
5163
  });
5164
  relation("===", function(left, right) {
5165
    if (isTypoTypeof(right, left, state)) {
5166
      warning("W122", this, right.value);
5167
    } else if (isTypoTypeof(left, right, state)) {
5168
      warning("W122", this, left.value);
5169
    }
5170
    return this;
5171
  });
5172
  relation("!=", function(left, right) {
5173
    var eqnull = state.option.eqnull &&
5174
        ((left && left.value) === "null" || (right && right.value) === "null");
5175

    
5176
    if (!eqnull && state.option.eqeqeq) {
5177
      this.from = this.character;
5178
      warning("W116", this, "!==", "!=");
5179
    } else if (isPoorRelation(left)) {
5180
      warning("W041", this, "!==", left.value);
5181
    } else if (isPoorRelation(right)) {
5182
      warning("W041", this, "!==", right.value);
5183
    } else if (isTypoTypeof(right, left, state)) {
5184
      warning("W122", this, right.value);
5185
    } else if (isTypoTypeof(left, right, state)) {
5186
      warning("W122", this, left.value);
5187
    }
5188
    return this;
5189
  });
5190
  relation("!==", function(left, right) {
5191
    if (isTypoTypeof(right, left, state)) {
5192
      warning("W122", this, right.value);
5193
    } else if (isTypoTypeof(left, right, state)) {
5194
      warning("W122", this, left.value);
5195
    }
5196
    return this;
5197
  });
5198
  relation("<");
5199
  relation(">");
5200
  relation("<=");
5201
  relation(">=");
5202
  bitwise("<<", "shiftleft", 120);
5203
  bitwise(">>", "shiftright", 120);
5204
  bitwise(">>>", "shiftrightunsigned", 120);
5205
  infix("in", "in", 120);
5206
  infix("instanceof", "instanceof", 120);
5207
  infix("+", function(left, that) {
5208
    var right;
5209
    that.left = left;
5210
    that.right = right = expression(130);
5211

    
5212
    if (left && right && left.id === "(string)" && right.id === "(string)") {
5213
      left.value += right.value;
5214
      left.character = right.character;
5215
      if (!state.option.scripturl && reg.javascriptURL.test(left.value)) {
5216
        warning("W050", left);
5217
      }
5218
      return left;
5219
    }
5220

    
5221
    return that;
5222
  }, 130);
5223
  prefix("+", "num");
5224
  prefix("+++", function() {
5225
    warning("W007");
5226
    this.arity = "unary";
5227
    this.right = expression(150);
5228
    return this;
5229
  });
5230
  infix("+++", function(left) {
5231
    warning("W007");
5232
    this.left = left;
5233
    this.right = expression(130);
5234
    return this;
5235
  }, 130);
5236
  infix("-", "sub", 130);
5237
  prefix("-", "neg");
5238
  prefix("---", function() {
5239
    warning("W006");
5240
    this.arity = "unary";
5241
    this.right = expression(150);
5242
    return this;
5243
  });
5244
  infix("---", function(left) {
5245
    warning("W006");
5246
    this.left = left;
5247
    this.right = expression(130);
5248
    return this;
5249
  }, 130);
5250
  infix("*", "mult", 140);
5251
  infix("/", "div", 140);
5252
  infix("%", "mod", 140);
5253

    
5254
  suffix("++");
5255
  prefix("++", "preinc");
5256
  state.syntax["++"].exps = true;
5257

    
5258
  suffix("--");
5259
  prefix("--", "predec");
5260
  state.syntax["--"].exps = true;
5261
  prefix("delete", function() {
5262
    var p = expression(10);
5263
    if (!p) {
5264
      return this;
5265
    }
5266

    
5267
    if (p.id !== "." && p.id !== "[") {
5268
      warning("W051");
5269
    }
5270
    this.first = p;
5271
    if (p.identifier && !state.isStrict()) {
5272
      p.forgiveUndef = true;
5273
    }
5274
    return this;
5275
  }).exps = true;
5276

    
5277
  prefix("~", function() {
5278
    if (state.option.bitwise) {
5279
      warning("W016", this, "~");
5280
    }
5281
    this.arity = "unary";
5282
    this.right = expression(150);
5283
    return this;
5284
  });
5285

    
5286
  prefix("...", function() {
5287
    if (!state.inES6(true)) {
5288
      warning("W119", this, "spread/rest operator", "6");
5289
    }
5290
    if (!state.tokens.next.identifier &&
5291
        state.tokens.next.type !== "(string)" &&
5292
          !checkPunctuators(state.tokens.next, ["[", "("])) {
5293

    
5294
      error("E030", state.tokens.next, state.tokens.next.value);
5295
    }
5296
    expression(150);
5297
    return this;
5298
  });
5299

    
5300
  prefix("!", function() {
5301
    this.arity = "unary";
5302
    this.right = expression(150);
5303

    
5304
    if (!this.right) { // '!' followed by nothing? Give up.
5305
      quit("E041", this.line || 0);
5306
    }
5307

    
5308
    if (bang[this.right.id] === true) {
5309
      warning("W018", this, "!");
5310
    }
5311
    return this;
5312
  });
5313

    
5314
  prefix("typeof", (function() {
5315
    var p = expression(150);
5316
    this.first = this.right = p;
5317

    
5318
    if (!p) { // 'typeof' followed by nothing? Give up.
5319
      quit("E041", this.line || 0, this.character || 0);
5320
    }
5321
    if (p.identifier) {
5322
      p.forgiveUndef = true;
5323
    }
5324
    return this;
5325
  }));
5326
  prefix("new", function() {
5327
    var mp = metaProperty("target", function() {
5328
      if (!state.inES6(true)) {
5329
        warning("W119", state.tokens.prev, "new.target", "6");
5330
      }
5331
      var inFunction, c = state.funct;
5332
      while (c) {
5333
        inFunction = !c["(global)"];
5334
        if (!c["(arrow)"]) { break; }
5335
        c = c["(context)"];
5336
      }
5337
      if (!inFunction) {
5338
        warning("W136", state.tokens.prev, "new.target");
5339
      }
5340
    });
5341
    if (mp) { return mp; }
5342

    
5343
    var c = expression(155), i;
5344
    if (c && c.id !== "function") {
5345
      if (c.identifier) {
5346
        c["new"] = true;
5347
        switch (c.value) {
5348
        case "Number":
5349
        case "String":
5350
        case "Boolean":
5351
        case "Math":
5352
        case "JSON":
5353
          warning("W053", state.tokens.prev, c.value);
5354
          break;
5355
        case "Symbol":
5356
          if (state.inES6()) {
5357
            warning("W053", state.tokens.prev, c.value);
5358
          }
5359
          break;
5360
        case "Function":
5361
          if (!state.option.evil) {
5362
            warning("W054");
5363
          }
5364
          break;
5365
        case "Date":
5366
        case "RegExp":
5367
        case "this":
5368
          break;
5369
        default:
5370
          if (c.id !== "function") {
5371
            i = c.value.substr(0, 1);
5372
            if (state.option.newcap && (i < "A" || i > "Z") &&
5373
              !state.funct["(scope)"].isPredefined(c.value)) {
5374
              warning("W055", state.tokens.curr);
5375
            }
5376
          }
5377
        }
5378
      } else {
5379
        if (c.id !== "." && c.id !== "[" && c.id !== "(") {
5380
          warning("W056", state.tokens.curr);
5381
        }
5382
      }
5383
    } else {
5384
      if (!state.option.supernew)
5385
        warning("W057", this);
5386
    }
5387
    if (state.tokens.next.id !== "(" && !state.option.supernew) {
5388
      warning("W058", state.tokens.curr, state.tokens.curr.value);
5389
    }
5390
    this.first = this.right = c;
5391
    return this;
5392
  });
5393
  state.syntax["new"].exps = true;
5394

    
5395
  prefix("void").exps = true;
5396

    
5397
  infix(".", function(left, that) {
5398
    var m = identifier(false, true);
5399

    
5400
    if (typeof m === "string") {
5401
      countMember(m);
5402
    }
5403

    
5404
    that.left = left;
5405
    that.right = m;
5406

    
5407
    if (m && m === "hasOwnProperty" && state.tokens.next.value === "=") {
5408
      warning("W001");
5409
    }
5410

    
5411
    if (left && left.value === "arguments" && (m === "callee" || m === "caller")) {
5412
      if (state.option.noarg)
5413
        warning("W059", left, m);
5414
      else if (state.isStrict())
5415
        error("E008");
5416
    } else if (!state.option.evil && left && left.value === "document" &&
5417
        (m === "write" || m === "writeln")) {
5418
      warning("W060", left);
5419
    }
5420

    
5421
    if (!state.option.evil && (m === "eval" || m === "execScript")) {
5422
      if (isGlobalEval(left, state)) {
5423
        warning("W061");
5424
      }
5425
    }
5426

    
5427
    return that;
5428
  }, 160, true);
5429

    
5430
  infix("(", function(left, that) {
5431
    if (state.option.immed && left && !left.immed && left.id === "function") {
5432
      warning("W062");
5433
    }
5434

    
5435
    var n = 0;
5436
    var p = [];
5437

    
5438
    if (left) {
5439
      if (left.type === "(identifier)") {
5440
        if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) {
5441
          if ("Array Number String Boolean Date Object Error Symbol".indexOf(left.value) === -1) {
5442
            if (left.value === "Math") {
5443
              warning("W063", left);
5444
            } else if (state.option.newcap) {
5445
              warning("W064", left);
5446
            }
5447
          }
5448
        }
5449
      }
5450
    }
5451

    
5452
    if (state.tokens.next.id !== ")") {
5453
      for (;;) {
5454
        p[p.length] = expression(10);
5455
        n += 1;
5456
        if (state.tokens.next.id !== ",") {
5457
          break;
5458
        }
5459
        comma();
5460
      }
5461
    }
5462

    
5463
    advance(")");
5464

    
5465
    if (typeof left === "object") {
5466
      if (!state.inES5() && left.value === "parseInt" && n === 1) {
5467
        warning("W065", state.tokens.curr);
5468
      }
5469
      if (!state.option.evil) {
5470
        if (left.value === "eval" || left.value === "Function" ||
5471
            left.value === "execScript") {
5472
          warning("W061", left);
5473

    
5474
          if (p[0] && [0].id === "(string)") {
5475
            addInternalSrc(left, p[0].value);
5476
          }
5477
        } else if (p[0] && p[0].id === "(string)" &&
5478
             (left.value === "setTimeout" ||
5479
            left.value === "setInterval")) {
5480
          warning("W066", left);
5481
          addInternalSrc(left, p[0].value);
5482
        } else if (p[0] && p[0].id === "(string)" &&
5483
             left.value === "." &&
5484
             left.left.value === "window" &&
5485
             (left.right === "setTimeout" ||
5486
            left.right === "setInterval")) {
5487
          warning("W066", left);
5488
          addInternalSrc(left, p[0].value);
5489
        }
5490
      }
5491
      if (!left.identifier && left.id !== "." && left.id !== "[" && left.id !== "=>" &&
5492
          left.id !== "(" && left.id !== "&&" && left.id !== "||" && left.id !== "?" &&
5493
          !(state.inES6() && left["(name)"])) {
5494
        warning("W067", that);
5495
      }
5496
    }
5497

    
5498
    that.left = left;
5499
    return that;
5500
  }, 155, true).exps = true;
5501

    
5502
  prefix("(", function() {
5503
    var pn = state.tokens.next, pn1, i = -1;
5504
    var ret, triggerFnExpr, first, last;
5505
    var parens = 1;
5506
    var opening = state.tokens.curr;
5507
    var preceeding = state.tokens.prev;
5508
    var isNecessary = !state.option.singleGroups;
5509

    
5510
    do {
5511
      if (pn.value === "(") {
5512
        parens += 1;
5513
      } else if (pn.value === ")") {
5514
        parens -= 1;
5515
      }
5516

    
5517
      i += 1;
5518
      pn1 = pn;
5519
      pn = peek(i);
5520
    } while (!(parens === 0 && pn1.value === ")") && pn.value !== ";" && pn.type !== "(end)");
5521

    
5522
    if (state.tokens.next.id === "function") {
5523
      triggerFnExpr = state.tokens.next.immed = true;
5524
    }
5525
    if (pn.value === "=>") {
5526
      return doFunction({ type: "arrow", parsedOpening: true });
5527
    }
5528

    
5529
    var exprs = [];
5530

    
5531
    if (state.tokens.next.id !== ")") {
5532
      for (;;) {
5533
        exprs.push(expression(10));
5534

    
5535
        if (state.tokens.next.id !== ",") {
5536
          break;
5537
        }
5538

    
5539
        if (state.option.nocomma) {
5540
          warning("W127");
5541
        }
5542

    
5543
        comma();
5544
      }
5545
    }
5546

    
5547
    advance(")", this);
5548
    if (state.option.immed && exprs[0] && exprs[0].id === "function") {
5549
      if (state.tokens.next.id !== "(" &&
5550
        state.tokens.next.id !== "." && state.tokens.next.id !== "[") {
5551
        warning("W068", this);
5552
      }
5553
    }
5554

    
5555
    if (!exprs.length) {
5556
      return;
5557
    }
5558
    if (exprs.length > 1) {
5559
      ret = Object.create(state.syntax[","]);
5560
      ret.exprs = exprs;
5561

    
5562
      first = exprs[0];
5563
      last = exprs[exprs.length - 1];
5564

    
5565
      if (!isNecessary) {
5566
        isNecessary = preceeding.assign || preceeding.delim;
5567
      }
5568
    } else {
5569
      ret = first = last = exprs[0];
5570

    
5571
      if (!isNecessary) {
5572
        isNecessary =
5573
          (opening.beginsStmt && (ret.id === "{" || triggerFnExpr || isFunctor(ret))) ||
5574
          (triggerFnExpr &&
5575
            (!isEndOfExpr() || state.tokens.prev.id !== "}")) ||
5576
          (isFunctor(ret) && !isEndOfExpr()) ||
5577
          (ret.id === "{" && preceeding.id === "=>") ||
5578
          (ret.type === "(number)" &&
5579
            checkPunctuator(pn, ".") && /^\d+$/.test(ret.value));
5580
      }
5581
    }
5582

    
5583
    if (ret) {
5584
      if (!isNecessary && (first.left || first.right || ret.exprs)) {
5585
        isNecessary =
5586
          (!isBeginOfExpr(preceeding) && first.lbp <= preceeding.lbp) ||
5587
          (!isEndOfExpr() && last.lbp < state.tokens.next.lbp);
5588
      }
5589

    
5590
      if (!isNecessary) {
5591
        warning("W126", opening);
5592
      }
5593

    
5594
      ret.paren = true;
5595
    }
5596

    
5597
    return ret;
5598
  });
5599

    
5600
  application("=>");
5601

    
5602
  infix("[", function(left, that) {
5603
    var e = expression(10), s;
5604
    if (e && e.type === "(string)") {
5605
      if (!state.option.evil && (e.value === "eval" || e.value === "execScript")) {
5606
        if (isGlobalEval(left, state)) {
5607
          warning("W061");
5608
        }
5609
      }
5610

    
5611
      countMember(e.value);
5612
      if (!state.option.sub && reg.identifier.test(e.value)) {
5613
        s = state.syntax[e.value];
5614
        if (!s || !isReserved(s)) {
5615
          warning("W069", state.tokens.prev, e.value);
5616
        }
5617
      }
5618
    }
5619
    advance("]", that);
5620

    
5621
    if (e && e.value === "hasOwnProperty" && state.tokens.next.value === "=") {
5622
      warning("W001");
5623
    }
5624

    
5625
    that.left = left;
5626
    that.right = e;
5627
    return that;
5628
  }, 160, true);
5629

    
5630
  function comprehensiveArrayExpression() {
5631
    var res = {};
5632
    res.exps = true;
5633
    state.funct["(comparray)"].stack();
5634
    var reversed = false;
5635
    if (state.tokens.next.value !== "for") {
5636
      reversed = true;
5637
      if (!state.inMoz()) {
5638
        warning("W116", state.tokens.next, "for", state.tokens.next.value);
5639
      }
5640
      state.funct["(comparray)"].setState("use");
5641
      res.right = expression(10);
5642
    }
5643

    
5644
    advance("for");
5645
    if (state.tokens.next.value === "each") {
5646
      advance("each");
5647
      if (!state.inMoz()) {
5648
        warning("W118", state.tokens.curr, "for each");
5649
      }
5650
    }
5651
    advance("(");
5652
    state.funct["(comparray)"].setState("define");
5653
    res.left = expression(130);
5654
    if (_.contains(["in", "of"], state.tokens.next.value)) {
5655
      advance();
5656
    } else {
5657
      error("E045", state.tokens.curr);
5658
    }
5659
    state.funct["(comparray)"].setState("generate");
5660
    expression(10);
5661

    
5662
    advance(")");
5663
    if (state.tokens.next.value === "if") {
5664
      advance("if");
5665
      advance("(");
5666
      state.funct["(comparray)"].setState("filter");
5667
      res.filter = expression(10);
5668
      advance(")");
5669
    }
5670

    
5671
    if (!reversed) {
5672
      state.funct["(comparray)"].setState("use");
5673
      res.right = expression(10);
5674
    }
5675

    
5676
    advance("]");
5677
    state.funct["(comparray)"].unstack();
5678
    return res;
5679
  }
5680

    
5681
  prefix("[", function() {
5682
    var blocktype = lookupBlockType();
5683
    if (blocktype.isCompArray) {
5684
      if (!state.option.esnext && !state.inMoz()) {
5685
        warning("W118", state.tokens.curr, "array comprehension");
5686
      }
5687
      return comprehensiveArrayExpression();
5688
    } else if (blocktype.isDestAssign) {
5689
      this.destructAssign = destructuringPattern({ openingParsed: true, assignment: true });
5690
      return this;
5691
    }
5692
    var b = state.tokens.curr.line !== startLine(state.tokens.next);
5693
    this.first = [];
5694
    if (b) {
5695
      indent += state.option.indent;
5696
      if (state.tokens.next.from === indent + state.option.indent) {
5697
        indent += state.option.indent;
5698
      }
5699
    }
5700
    while (state.tokens.next.id !== "(end)") {
5701
      while (state.tokens.next.id === ",") {
5702
        if (!state.option.elision) {
5703
          if (!state.inES5()) {
5704
            warning("W070");
5705
          } else {
5706
            warning("W128");
5707
            do {
5708
              advance(",");
5709
            } while (state.tokens.next.id === ",");
5710
            continue;
5711
          }
5712
        }
5713
        advance(",");
5714
      }
5715

    
5716
      if (state.tokens.next.id === "]") {
5717
        break;
5718
      }
5719

    
5720
      this.first.push(expression(10));
5721
      if (state.tokens.next.id === ",") {
5722
        comma({ allowTrailing: true });
5723
        if (state.tokens.next.id === "]" && !state.inES5()) {
5724
          warning("W070", state.tokens.curr);
5725
          break;
5726
        }
5727
      } else {
5728
        break;
5729
      }
5730
    }
5731
    if (b) {
5732
      indent -= state.option.indent;
5733
    }
5734
    advance("]", this);
5735
    return this;
5736
  });
5737

    
5738

    
5739
  function isMethod() {
5740
    return state.funct["(statement)"] && state.funct["(statement)"].type === "class" ||
5741
           state.funct["(context)"] && state.funct["(context)"]["(verb)"] === "class";
5742
  }
5743

    
5744

    
5745
  function isPropertyName(token) {
5746
    return token.identifier || token.id === "(string)" || token.id === "(number)";
5747
  }
5748

    
5749

    
5750
  function propertyName(preserveOrToken) {
5751
    var id;
5752
    var preserve = true;
5753
    if (typeof preserveOrToken === "object") {
5754
      id = preserveOrToken;
5755
    } else {
5756
      preserve = preserveOrToken;
5757
      id = optionalidentifier(false, true, preserve);
5758
    }
5759

    
5760
    if (!id) {
5761
      if (state.tokens.next.id === "(string)") {
5762
        id = state.tokens.next.value;
5763
        if (!preserve) {
5764
          advance();
5765
        }
5766
      } else if (state.tokens.next.id === "(number)") {
5767
        id = state.tokens.next.value.toString();
5768
        if (!preserve) {
5769
          advance();
5770
        }
5771
      }
5772
    } else if (typeof id === "object") {
5773
      if (id.id === "(string)" || id.id === "(identifier)") id = id.value;
5774
      else if (id.id === "(number)") id = id.value.toString();
5775
    }
5776

    
5777
    if (id === "hasOwnProperty") {
5778
      warning("W001");
5779
    }
5780

    
5781
    return id;
5782
  }
5783
  function functionparams(options) {
5784
    var next;
5785
    var paramsIds = [];
5786
    var ident;
5787
    var tokens = [];
5788
    var t;
5789
    var pastDefault = false;
5790
    var pastRest = false;
5791
    var arity = 0;
5792
    var loneArg = options && options.loneArg;
5793

    
5794
    if (loneArg && loneArg.identifier === true) {
5795
      state.funct["(scope)"].addParam(loneArg.value, loneArg);
5796
      return { arity: 1, params: [ loneArg.value ] };
5797
    }
5798

    
5799
    next = state.tokens.next;
5800

    
5801
    if (!options || !options.parsedOpening) {
5802
      advance("(");
5803
    }
5804

    
5805
    if (state.tokens.next.id === ")") {
5806
      advance(")");
5807
      return;
5808
    }
5809

    
5810
    function addParam(addParamArgs) {
5811
      state.funct["(scope)"].addParam.apply(state.funct["(scope)"], addParamArgs);
5812
    }
5813

    
5814
    for (;;) {
5815
      arity++;
5816
      var currentParams = [];
5817

    
5818
      if (_.contains(["{", "["], state.tokens.next.id)) {
5819
        tokens = destructuringPattern();
5820
        for (t in tokens) {
5821
          t = tokens[t];
5822
          if (t.id) {
5823
            paramsIds.push(t.id);
5824
            currentParams.push([t.id, t.token]);
5825
          }
5826
        }
5827
      } else {
5828
        if (checkPunctuator(state.tokens.next, "...")) pastRest = true;
5829
        ident = identifier(true);
5830
        if (ident) {
5831
          paramsIds.push(ident);
5832
          currentParams.push([ident, state.tokens.curr]);
5833
        } else {
5834
          while (!checkPunctuators(state.tokens.next, [",", ")"])) advance();
5835
        }
5836
      }
5837
      if (pastDefault) {
5838
        if (state.tokens.next.id !== "=") {
5839
          error("W138", state.tokens.current);
5840
        }
5841
      }
5842
      if (state.tokens.next.id === "=") {
5843
        if (!state.inES6()) {
5844
          warning("W119", state.tokens.next, "default parameters", "6");
5845
        }
5846
        advance("=");
5847
        pastDefault = true;
5848
        expression(10);
5849
      }
5850
      currentParams.forEach(addParam);
5851

    
5852
      if (state.tokens.next.id === ",") {
5853
        if (pastRest) {
5854
          warning("W131", state.tokens.next);
5855
        }
5856
        comma();
5857
      } else {
5858
        advance(")", next);
5859
        return { arity: arity, params: paramsIds };
5860
      }
5861
    }
5862
  }
5863

    
5864
  function functor(name, token, overwrites) {
5865
    var funct = {
5866
      "(name)"      : name,
5867
      "(breakage)"  : 0,
5868
      "(loopage)"   : 0,
5869
      "(tokens)"    : {},
5870
      "(properties)": {},
5871

    
5872
      "(catch)"     : false,
5873
      "(global)"    : false,
5874

    
5875
      "(line)"      : null,
5876
      "(character)" : null,
5877
      "(metrics)"   : null,
5878
      "(statement)" : null,
5879
      "(context)"   : null,
5880
      "(scope)"     : null,
5881
      "(comparray)" : null,
5882
      "(generator)" : null,
5883
      "(arrow)"     : null,
5884
      "(params)"    : null
5885
    };
5886

    
5887
    if (token) {
5888
      _.extend(funct, {
5889
        "(line)"     : token.line,
5890
        "(character)": token.character,
5891
        "(metrics)"  : createMetrics(token)
5892
      });
5893
    }
5894

    
5895
    _.extend(funct, overwrites);
5896

    
5897
    if (funct["(context)"]) {
5898
      funct["(scope)"] = funct["(context)"]["(scope)"];
5899
      funct["(comparray)"]  = funct["(context)"]["(comparray)"];
5900
    }
5901

    
5902
    return funct;
5903
  }
5904

    
5905
  function isFunctor(token) {
5906
    return "(scope)" in token;
5907
  }
5908
  function hasParsedCode(funct) {
5909
    return funct["(global)"] && !funct["(verb)"];
5910
  }
5911

    
5912
  function doTemplateLiteral(left) {
5913
    var ctx = this.context;
5914
    var noSubst = this.noSubst;
5915
    var depth = this.depth;
5916

    
5917
    if (!noSubst) {
5918
      while (!end()) {
5919
        if (!state.tokens.next.template || state.tokens.next.depth > depth) {
5920
          expression(0); // should probably have different rbp?
5921
        } else {
5922
          advance();
5923
        }
5924
      }
5925
    }
5926

    
5927
    return {
5928
      id: "(template)",
5929
      type: "(template)",
5930
      tag: left
5931
    };
5932

    
5933
    function end() {
5934
      if (state.tokens.curr.template && state.tokens.curr.tail &&
5935
          state.tokens.curr.context === ctx) return true;
5936
      var complete = (state.tokens.next.template && state.tokens.next.tail &&
5937
                      state.tokens.next.context === ctx);
5938
      if (complete) advance();
5939
      return complete || state.tokens.next.isUnclosed;
5940
    }
5941
  }
5942
  function doFunction(options) {
5943
    var f, token, name, statement, classExprBinding, isGenerator, isArrow, ignoreLoopFunc;
5944
    var oldOption = state.option;
5945
    var oldIgnored = state.ignored;
5946

    
5947
    if (options) {
5948
      name = options.name;
5949
      statement = options.statement;
5950
      classExprBinding = options.classExprBinding;
5951
      isGenerator = options.type === "generator";
5952
      isArrow = options.type === "arrow";
5953
      ignoreLoopFunc = options.ignoreLoopFunc;
5954
    }
5955

    
5956
    state.option = Object.create(state.option);
5957
    state.ignored = Object.create(state.ignored);
5958

    
5959
    state.funct = functor(name || state.nameStack.infer(), state.tokens.next, {
5960
      "(statement)": statement,
5961
      "(context)":   state.funct,
5962
      "(arrow)":     isArrow,
5963
      "(generator)": isGenerator
5964
    });
5965

    
5966
    f = state.funct;
5967
    token = state.tokens.curr;
5968
    token.funct = state.funct;
5969

    
5970
    functions.push(state.funct);
5971
    state.funct["(scope)"].stack("functionouter");
5972
    var internallyAccessibleName = name || classExprBinding;
5973
    if (internallyAccessibleName) {
5974
      state.funct["(scope)"].block.add(internallyAccessibleName,
5975
        classExprBinding ? "class" : "function", state.tokens.curr, false);
5976
    }
5977
    state.funct["(scope)"].stack("functionparams");
5978

    
5979
    var paramsInfo = functionparams(options);
5980

    
5981
    if (paramsInfo) {
5982
      state.funct["(params)"] = paramsInfo.params;
5983
      state.funct["(metrics)"].arity = paramsInfo.arity;
5984
      state.funct["(metrics)"].verifyMaxParametersPerFunction();
5985
    } else {
5986
      state.funct["(metrics)"].arity = 0;
5987
    }
5988

    
5989
    if (isArrow) {
5990
      if (!state.inES6(true)) {
5991
        warning("W119", state.tokens.curr, "arrow function syntax (=>)", "6");
5992
      }
5993

    
5994
      if (!options.loneArg) {
5995
        advance("=>");
5996
      }
5997
    }
5998

    
5999
    block(false, true, true, isArrow);
6000

    
6001
    if (!state.option.noyield && isGenerator &&
6002
        state.funct["(generator)"] !== "yielded") {
6003
      warning("W124", state.tokens.curr);
6004
    }
6005

    
6006
    state.funct["(metrics)"].verifyMaxStatementsPerFunction();
6007
    state.funct["(metrics)"].verifyMaxComplexityPerFunction();
6008
    state.funct["(unusedOption)"] = state.option.unused;
6009
    state.option = oldOption;
6010
    state.ignored = oldIgnored;
6011
    state.funct["(last)"] = state.tokens.curr.line;
6012
    state.funct["(lastcharacter)"] = state.tokens.curr.character;
6013
    state.funct["(scope)"].unstack(); // also does usage and label checks
6014
    state.funct["(scope)"].unstack();
6015

    
6016
    state.funct = state.funct["(context)"];
6017

    
6018
    if (!ignoreLoopFunc && !state.option.loopfunc && state.funct["(loopage)"]) {
6019
      if (f["(isCapturing)"]) {
6020
        warning("W083", token);
6021
      }
6022
    }
6023

    
6024
    return f;
6025
  }
6026

    
6027
  function createMetrics(functionStartToken) {
6028
    return {
6029
      statementCount: 0,
6030
      nestedBlockDepth: -1,
6031
      ComplexityCount: 1,
6032
      arity: 0,
6033

    
6034
      verifyMaxStatementsPerFunction: function() {
6035
        if (state.option.maxstatements &&
6036
          this.statementCount > state.option.maxstatements) {
6037
          warning("W071", functionStartToken, this.statementCount);
6038
        }
6039
      },
6040

    
6041
      verifyMaxParametersPerFunction: function() {
6042
        if (_.isNumber(state.option.maxparams) &&
6043
          this.arity > state.option.maxparams) {
6044
          warning("W072", functionStartToken, this.arity);
6045
        }
6046
      },
6047

    
6048
      verifyMaxNestedBlockDepthPerFunction: function() {
6049
        if (state.option.maxdepth &&
6050
          this.nestedBlockDepth > 0 &&
6051
          this.nestedBlockDepth === state.option.maxdepth + 1) {
6052
          warning("W073", null, this.nestedBlockDepth);
6053
        }
6054
      },
6055

    
6056
      verifyMaxComplexityPerFunction: function() {
6057
        var max = state.option.maxcomplexity;
6058
        var cc = this.ComplexityCount;
6059
        if (max && cc > max) {
6060
          warning("W074", functionStartToken, cc);
6061
        }
6062
      }
6063
    };
6064
  }
6065

    
6066
  function increaseComplexityCount() {
6067
    state.funct["(metrics)"].ComplexityCount += 1;
6068
  }
6069

    
6070
  function checkCondAssignment(expr) {
6071
    var id, paren;
6072
    if (expr) {
6073
      id = expr.id;
6074
      paren = expr.paren;
6075
      if (id === "," && (expr = expr.exprs[expr.exprs.length - 1])) {
6076
        id = expr.id;
6077
        paren = paren || expr.paren;
6078
      }
6079
    }
6080
    switch (id) {
6081
    case "=":
6082
    case "+=":
6083
    case "-=":
6084
    case "*=":
6085
    case "%=":
6086
    case "&=":
6087
    case "|=":
6088
    case "^=":
6089
    case "/=":
6090
      if (!paren && !state.option.boss) {
6091
        warning("W084");
6092
      }
6093
    }
6094
  }
6095
  function checkProperties(props) {
6096
    if (state.inES5()) {
6097
      for (var name in props) {
6098
        if (props[name] && props[name].setterToken && !props[name].getterToken) {
6099
          warning("W078", props[name].setterToken);
6100
        }
6101
      }
6102
    }
6103
  }
6104

    
6105
  function metaProperty(name, c) {
6106
    if (checkPunctuator(state.tokens.next, ".")) {
6107
      var left = state.tokens.curr.id;
6108
      advance(".");
6109
      var id = identifier();
6110
      state.tokens.curr.isMetaProperty = true;
6111
      if (name !== id) {
6112
        error("E057", state.tokens.prev, left, id);
6113
      } else {
6114
        c();
6115
      }
6116
      return state.tokens.curr;
6117
    }
6118
  }
6119

    
6120
  (function(x) {
6121
    x.nud = function() {
6122
      var b, f, i, p, t, isGeneratorMethod = false, nextVal;
6123
      var props = Object.create(null); // All properties, including accessors
6124

    
6125
      b = state.tokens.curr.line !== startLine(state.tokens.next);
6126
      if (b) {
6127
        indent += state.option.indent;
6128
        if (state.tokens.next.from === indent + state.option.indent) {
6129
          indent += state.option.indent;
6130
        }
6131
      }
6132

    
6133
      var blocktype = lookupBlockType();
6134
      if (blocktype.isDestAssign) {
6135
        this.destructAssign = destructuringPattern({ openingParsed: true, assignment: true });
6136
        return this;
6137
      }
6138

    
6139
      for (;;) {
6140
        if (state.tokens.next.id === "}") {
6141
          break;
6142
        }
6143

    
6144
        nextVal = state.tokens.next.value;
6145
        if (state.tokens.next.identifier &&
6146
            (peekIgnoreEOL().id === "," || peekIgnoreEOL().id === "}")) {
6147
          if (!state.inES6()) {
6148
            warning("W104", state.tokens.next, "object short notation", "6");
6149
          }
6150
          i = propertyName(true);
6151
          saveProperty(props, i, state.tokens.next);
6152

    
6153
          expression(10);
6154

    
6155
        } else if (peek().id !== ":" && (nextVal === "get" || nextVal === "set")) {
6156
          advance(nextVal);
6157

    
6158
          if (!state.inES5()) {
6159
            error("E034");
6160
          }
6161

    
6162
          i = propertyName();
6163
          if (!i && !state.inES6()) {
6164
            error("E035");
6165
          }
6166
          if (i) {
6167
            saveAccessor(nextVal, props, i, state.tokens.curr);
6168
          }
6169

    
6170
          t = state.tokens.next;
6171
          f = doFunction();
6172
          p = f["(params)"];
6173
          if (nextVal === "get" && i && p) {
6174
            warning("W076", t, p[0], i);
6175
          } else if (nextVal === "set" && i && (!p || p.length !== 1)) {
6176
            warning("W077", t, i);
6177
          }
6178
        } else {
6179
          if (state.tokens.next.value === "*" && state.tokens.next.type === "(punctuator)") {
6180
            if (!state.inES6()) {
6181
              warning("W104", state.tokens.next, "generator functions", "6");
6182
            }
6183
            advance("*");
6184
            isGeneratorMethod = true;
6185
          } else {
6186
            isGeneratorMethod = false;
6187
          }
6188

    
6189
          if (state.tokens.next.id === "[") {
6190
            i = computedPropertyName();
6191
            state.nameStack.set(i);
6192
          } else {
6193
            state.nameStack.set(state.tokens.next);
6194
            i = propertyName();
6195
            saveProperty(props, i, state.tokens.next);
6196

    
6197
            if (typeof i !== "string") {
6198
              break;
6199
            }
6200
          }
6201

    
6202
          if (state.tokens.next.value === "(") {
6203
            if (!state.inES6()) {
6204
              warning("W104", state.tokens.curr, "concise methods", "6");
6205
            }
6206
            doFunction({ type: isGeneratorMethod ? "generator" : null });
6207
          } else {
6208
            advance(":");
6209
            expression(10);
6210
          }
6211
        }
6212

    
6213
        countMember(i);
6214

    
6215
        if (state.tokens.next.id === ",") {
6216
          comma({ allowTrailing: true, property: true });
6217
          if (state.tokens.next.id === ",") {
6218
            warning("W070", state.tokens.curr);
6219
          } else if (state.tokens.next.id === "}" && !state.inES5()) {
6220
            warning("W070", state.tokens.curr);
6221
          }
6222
        } else {
6223
          break;
6224
        }
6225
      }
6226
      if (b) {
6227
        indent -= state.option.indent;
6228
      }
6229
      advance("}", this);
6230

    
6231
      checkProperties(props);
6232

    
6233
      return this;
6234
    };
6235
    x.fud = function() {
6236
      error("E036", state.tokens.curr);
6237
    };
6238
  }(delim("{")));
6239

    
6240
  function destructuringPattern(options) {
6241
    var isAssignment = options && options.assignment;
6242

    
6243
    if (!state.inES6()) {
6244
      warning("W104", state.tokens.curr,
6245
        isAssignment ? "destructuring assignment" : "destructuring binding", "6");
6246
    }
6247

    
6248
    return destructuringPatternRecursive(options);
6249
  }
6250

    
6251
  function destructuringPatternRecursive(options) {
6252
    var ids;
6253
    var identifiers = [];
6254
    var openingParsed = options && options.openingParsed;
6255
    var isAssignment = options && options.assignment;
6256
    var recursiveOptions = isAssignment ? { assignment: isAssignment } : null;
6257
    var firstToken = openingParsed ? state.tokens.curr : state.tokens.next;
6258

    
6259
    var nextInnerDE = function() {
6260
      var ident;
6261
      if (checkPunctuators(state.tokens.next, ["[", "{"])) {
6262
        ids = destructuringPatternRecursive(recursiveOptions);
6263
        for (var id in ids) {
6264
          id = ids[id];
6265
          identifiers.push({ id: id.id, token: id.token });
6266
        }
6267
      } else if (checkPunctuator(state.tokens.next, ",")) {
6268
        identifiers.push({ id: null, token: state.tokens.curr });
6269
      } else if (checkPunctuator(state.tokens.next, "(")) {
6270
        advance("(");
6271
        nextInnerDE();
6272
        advance(")");
6273
      } else {
6274
        var is_rest = checkPunctuator(state.tokens.next, "...");
6275

    
6276
        if (isAssignment) {
6277
          var identifierToken = is_rest ? peek(0) : state.tokens.next;
6278
          if (!identifierToken.identifier) {
6279
            warning("E030", identifierToken, identifierToken.value);
6280
          }
6281
          var assignTarget = expression(155);
6282
          if (assignTarget) {
6283
            checkLeftSideAssign(assignTarget);
6284
            if (assignTarget.identifier) {
6285
              ident = assignTarget.value;
6286
            }
6287
          }
6288
        } else {
6289
          ident = identifier();
6290
        }
6291
        if (ident) {
6292
          identifiers.push({ id: ident, token: state.tokens.curr });
6293
        }
6294
        return is_rest;
6295
      }
6296
      return false;
6297
    };
6298
    var assignmentProperty = function() {
6299
      var id;
6300
      if (checkPunctuator(state.tokens.next, "[")) {
6301
        advance("[");
6302
        expression(10);
6303
        advance("]");
6304
        advance(":");
6305
        nextInnerDE();
6306
      } else if (state.tokens.next.id === "(string)" ||
6307
                 state.tokens.next.id === "(number)") {
6308
        advance();
6309
        advance(":");
6310
        nextInnerDE();
6311
      } else {
6312
        id = identifier();
6313
        if (checkPunctuator(state.tokens.next, ":")) {
6314
          advance(":");
6315
          nextInnerDE();
6316
        } else if (id) {
6317
          if (isAssignment) {
6318
            checkLeftSideAssign(state.tokens.curr);
6319
          }
6320
          identifiers.push({ id: id, token: state.tokens.curr });
6321
        }
6322
      }
6323
    };
6324
    if (checkPunctuator(firstToken, "[")) {
6325
      if (!openingParsed) {
6326
        advance("[");
6327
      }
6328
      if (checkPunctuator(state.tokens.next, "]")) {
6329
        warning("W137", state.tokens.curr);
6330
      }
6331
      var element_after_rest = false;
6332
      while (!checkPunctuator(state.tokens.next, "]")) {
6333
        if (nextInnerDE() && !element_after_rest &&
6334
            checkPunctuator(state.tokens.next, ",")) {
6335
          warning("W130", state.tokens.next);
6336
          element_after_rest = true;
6337
        }
6338
        if (checkPunctuator(state.tokens.next, "=")) {
6339
          if (checkPunctuator(state.tokens.prev, "...")) {
6340
            advance("]");
6341
          } else {
6342
            advance("=");
6343
          }
6344
          if (state.tokens.next.id === "undefined") {
6345
            warning("W080", state.tokens.prev, state.tokens.prev.value);
6346
          }
6347
          expression(10);
6348
        }
6349
        if (!checkPunctuator(state.tokens.next, "]")) {
6350
          advance(",");
6351
        }
6352
      }
6353
      advance("]");
6354
    } else if (checkPunctuator(firstToken, "{")) {
6355

    
6356
      if (!openingParsed) {
6357
        advance("{");
6358
      }
6359
      if (checkPunctuator(state.tokens.next, "}")) {
6360
        warning("W137", state.tokens.curr);
6361
      }
6362
      while (!checkPunctuator(state.tokens.next, "}")) {
6363
        assignmentProperty();
6364
        if (checkPunctuator(state.tokens.next, "=")) {
6365
          advance("=");
6366
          if (state.tokens.next.id === "undefined") {
6367
            warning("W080", state.tokens.prev, state.tokens.prev.value);
6368
          }
6369
          expression(10);
6370
        }
6371
        if (!checkPunctuator(state.tokens.next, "}")) {
6372
          advance(",");
6373
          if (checkPunctuator(state.tokens.next, "}")) {
6374
            break;
6375
          }
6376
        }
6377
      }
6378
      advance("}");
6379
    }
6380
    return identifiers;
6381
  }
6382

    
6383
  function destructuringPatternMatch(tokens, value) {
6384
    var first = value.first;
6385

    
6386
    if (!first)
6387
      return;
6388

    
6389
    _.zip(tokens, Array.isArray(first) ? first : [ first ]).forEach(function(val) {
6390
      var token = val[0];
6391
      var value = val[1];
6392

    
6393
      if (token && value)
6394
        token.first = value;
6395
      else if (token && token.first && !value)
6396
        warning("W080", token.first, token.first.value);
6397
    });
6398
  }
6399

    
6400
  function blockVariableStatement(type, statement, context) {
6401

    
6402
    var prefix = context && context.prefix;
6403
    var inexport = context && context.inexport;
6404
    var isLet = type === "let";
6405
    var isConst = type === "const";
6406
    var tokens, lone, value, letblock;
6407

    
6408
    if (!state.inES6()) {
6409
      warning("W104", state.tokens.curr, type, "6");
6410
    }
6411

    
6412
    if (isLet && state.tokens.next.value === "(") {
6413
      if (!state.inMoz()) {
6414
        warning("W118", state.tokens.next, "let block");
6415
      }
6416
      advance("(");
6417
      state.funct["(scope)"].stack();
6418
      letblock = true;
6419
    } else if (state.funct["(noblockscopedvar)"]) {
6420
      error("E048", state.tokens.curr, isConst ? "Const" : "Let");
6421
    }
6422

    
6423
    statement.first = [];
6424
    for (;;) {
6425
      var names = [];
6426
      if (_.contains(["{", "["], state.tokens.next.value)) {
6427
        tokens = destructuringPattern();
6428
        lone = false;
6429
      } else {
6430
        tokens = [ { id: identifier(), token: state.tokens.curr } ];
6431
        lone = true;
6432
      }
6433

    
6434
      if (!prefix && isConst && state.tokens.next.id !== "=") {
6435
        warning("E012", state.tokens.curr, state.tokens.curr.value);
6436
      }
6437

    
6438
      for (var t in tokens) {
6439
        if (tokens.hasOwnProperty(t)) {
6440
          t = tokens[t];
6441
          if (state.funct["(scope)"].block.isGlobal()) {
6442
            if (predefined[t.id] === false) {
6443
              warning("W079", t.token, t.id);
6444
            }
6445
          }
6446
          if (t.id && !state.funct["(noblockscopedvar)"]) {
6447
            state.funct["(scope)"].addlabel(t.id, {
6448
              type: type,
6449
              token: t.token });
6450
            names.push(t.token);
6451

    
6452
            if (lone && inexport) {
6453
              state.funct["(scope)"].setExported(t.token.value, t.token);
6454
            }
6455
          }
6456
        }
6457
      }
6458

    
6459
      if (state.tokens.next.id === "=") {
6460
        advance("=");
6461
        if (!prefix && state.tokens.next.id === "undefined") {
6462
          warning("W080", state.tokens.prev, state.tokens.prev.value);
6463
        }
6464
        if (!prefix && peek(0).id === "=" && state.tokens.next.identifier) {
6465
          warning("W120", state.tokens.next, state.tokens.next.value);
6466
        }
6467
        value = expression(prefix ? 120 : 10);
6468
        if (lone) {
6469
          tokens[0].first = value;
6470
        } else {
6471
          destructuringPatternMatch(names, value);
6472
        }
6473
      }
6474

    
6475
      statement.first = statement.first.concat(names);
6476

    
6477
      if (state.tokens.next.id !== ",") {
6478
        break;
6479
      }
6480
      comma();
6481
    }
6482
    if (letblock) {
6483
      advance(")");
6484
      block(true, true);
6485
      statement.block = true;
6486
      state.funct["(scope)"].unstack();
6487
    }
6488

    
6489
    return statement;
6490
  }
6491

    
6492
  var conststatement = stmt("const", function(context) {
6493
    return blockVariableStatement("const", this, context);
6494
  });
6495
  conststatement.exps = true;
6496

    
6497
  var letstatement = stmt("let", function(context) {
6498
    return blockVariableStatement("let", this, context);
6499
  });
6500
  letstatement.exps = true;
6501

    
6502
  var varstatement = stmt("var", function(context) {
6503
    var prefix = context && context.prefix;
6504
    var inexport = context && context.inexport;
6505
    var tokens, lone, value;
6506
    var implied = context && context.implied;
6507
    var report = !(context && context.ignore);
6508

    
6509
    this.first = [];
6510
    for (;;) {
6511
      var names = [];
6512
      if (_.contains(["{", "["], state.tokens.next.value)) {
6513
        tokens = destructuringPattern();
6514
        lone = false;
6515
      } else {
6516
        tokens = [ { id: identifier(), token: state.tokens.curr } ];
6517
        lone = true;
6518
      }
6519

    
6520
      if (!(prefix && implied) && report && state.option.varstmt) {
6521
        warning("W132", this);
6522
      }
6523

    
6524
      this.first = this.first.concat(names);
6525

    
6526
      for (var t in tokens) {
6527
        if (tokens.hasOwnProperty(t)) {
6528
          t = tokens[t];
6529
          if (!implied && state.funct["(global)"]) {
6530
            if (predefined[t.id] === false) {
6531
              warning("W079", t.token, t.id);
6532
            } else if (state.option.futurehostile === false) {
6533
              if ((!state.inES5() && vars.ecmaIdentifiers[5][t.id] === false) ||
6534
                (!state.inES6() && vars.ecmaIdentifiers[6][t.id] === false)) {
6535
                warning("W129", t.token, t.id);
6536
              }
6537
            }
6538
          }
6539
          if (t.id) {
6540
            if (implied === "for") {
6541

    
6542
              if (!state.funct["(scope)"].has(t.id)) {
6543
                if (report) warning("W088", t.token, t.id);
6544
              }
6545
              state.funct["(scope)"].block.use(t.id, t.token);
6546
            } else {
6547
              state.funct["(scope)"].addlabel(t.id, {
6548
                type: "var",
6549
                token: t.token });
6550

    
6551
              if (lone && inexport) {
6552
                state.funct["(scope)"].setExported(t.id, t.token);
6553
              }
6554
            }
6555
            names.push(t.token);
6556
          }
6557
        }
6558
      }
6559

    
6560
      if (state.tokens.next.id === "=") {
6561
        state.nameStack.set(state.tokens.curr);
6562

    
6563
        advance("=");
6564
        if (!prefix && report && !state.funct["(loopage)"] &&
6565
          state.tokens.next.id === "undefined") {
6566
          warning("W080", state.tokens.prev, state.tokens.prev.value);
6567
        }
6568
        if (peek(0).id === "=" && state.tokens.next.identifier) {
6569
          if (!prefix && report &&
6570
              !state.funct["(params)"] ||
6571
              state.funct["(params)"].indexOf(state.tokens.next.value) === -1) {
6572
            warning("W120", state.tokens.next, state.tokens.next.value);
6573
          }
6574
        }
6575
        value = expression(prefix ? 120 : 10);
6576
        if (lone) {
6577
          tokens[0].first = value;
6578
        } else {
6579
          destructuringPatternMatch(names, value);
6580
        }
6581
      }
6582

    
6583
      if (state.tokens.next.id !== ",") {
6584
        break;
6585
      }
6586
      comma();
6587
    }
6588

    
6589
    return this;
6590
  });
6591
  varstatement.exps = true;
6592

    
6593
  blockstmt("class", function() {
6594
    return classdef.call(this, true);
6595
  });
6596

    
6597
  function classdef(isStatement) {
6598
    if (!state.inES6()) {
6599
      warning("W104", state.tokens.curr, "class", "6");
6600
    }
6601
    if (isStatement) {
6602
      this.name = identifier();
6603

    
6604
      state.funct["(scope)"].addlabel(this.name, {
6605
        type: "class",
6606
        token: state.tokens.curr });
6607
    } else if (state.tokens.next.identifier && state.tokens.next.value !== "extends") {
6608
      this.name = identifier();
6609
      this.namedExpr = true;
6610
    } else {
6611
      this.name = state.nameStack.infer();
6612
    }
6613
    classtail(this);
6614
    return this;
6615
  }
6616

    
6617
  function classtail(c) {
6618
    var wasInClassBody = state.inClassBody;
6619
    if (state.tokens.next.value === "extends") {
6620
      advance("extends");
6621
      c.heritage = expression(10);
6622
    }
6623

    
6624
    state.inClassBody = true;
6625
    advance("{");
6626
    c.body = classbody(c);
6627
    advance("}");
6628
    state.inClassBody = wasInClassBody;
6629
  }
6630

    
6631
  function classbody(c) {
6632
    var name;
6633
    var isStatic;
6634
    var isGenerator;
6635
    var getset;
6636
    var props = Object.create(null);
6637
    var staticProps = Object.create(null);
6638
    var computed;
6639
    for (var i = 0; state.tokens.next.id !== "}"; ++i) {
6640
      name = state.tokens.next;
6641
      isStatic = false;
6642
      isGenerator = false;
6643
      getset = null;
6644
      if (name.id === ";") {
6645
        warning("W032");
6646
        advance(";");
6647
        continue;
6648
      }
6649

    
6650
      if (name.id === "*") {
6651
        isGenerator = true;
6652
        advance("*");
6653
        name = state.tokens.next;
6654
      }
6655
      if (name.id === "[") {
6656
        name = computedPropertyName();
6657
        computed = true;
6658
      } else if (isPropertyName(name)) {
6659
        advance();
6660
        computed = false;
6661
        if (name.identifier && name.value === "static") {
6662
          if (checkPunctuator(state.tokens.next, "*")) {
6663
            isGenerator = true;
6664
            advance("*");
6665
          }
6666
          if (isPropertyName(state.tokens.next) || state.tokens.next.id === "[") {
6667
            computed = state.tokens.next.id === "[";
6668
            isStatic = true;
6669
            name = state.tokens.next;
6670
            if (state.tokens.next.id === "[") {
6671
              name = computedPropertyName();
6672
            } else advance();
6673
          }
6674
        }
6675

    
6676
        if (name.identifier && (name.value === "get" || name.value === "set")) {
6677
          if (isPropertyName(state.tokens.next) || state.tokens.next.id === "[") {
6678
            computed = state.tokens.next.id === "[";
6679
            getset = name;
6680
            name = state.tokens.next;
6681
            if (state.tokens.next.id === "[") {
6682
              name = computedPropertyName();
6683
            } else advance();
6684
          }
6685
        }
6686
      } else {
6687
        warning("W052", state.tokens.next, state.tokens.next.value || state.tokens.next.type);
6688
        advance();
6689
        continue;
6690
      }
6691

    
6692
      if (!checkPunctuator(state.tokens.next, "(")) {
6693
        error("E054", state.tokens.next, state.tokens.next.value);
6694
        while (state.tokens.next.id !== "}" &&
6695
               !checkPunctuator(state.tokens.next, "(")) {
6696
          advance();
6697
        }
6698
        if (state.tokens.next.value !== "(") {
6699
          doFunction({ statement: c });
6700
        }
6701
      }
6702

    
6703
      if (!computed) {
6704
        if (getset) {
6705
          saveAccessor(
6706
            getset.value, isStatic ? staticProps : props, name.value, name, true, isStatic);
6707
        } else {
6708
          if (name.value === "constructor") {
6709
            state.nameStack.set(c);
6710
          } else {
6711
            state.nameStack.set(name);
6712
          }
6713
          saveProperty(isStatic ? staticProps : props, name.value, name, true, isStatic);
6714
        }
6715
      }
6716

    
6717
      if (getset && name.value === "constructor") {
6718
        var propDesc = getset.value === "get" ? "class getter method" : "class setter method";
6719
        error("E049", name, propDesc, "constructor");
6720
      } else if (name.value === "prototype") {
6721
        error("E049", name, "class method", "prototype");
6722
      }
6723

    
6724
      propertyName(name);
6725

    
6726
      doFunction({
6727
        statement: c,
6728
        type: isGenerator ? "generator" : null,
6729
        classExprBinding: c.namedExpr ? c.name : null
6730
      });
6731
    }
6732

    
6733
    checkProperties(props);
6734
  }
6735

    
6736
  blockstmt("function", function(context) {
6737
    var inexport = context && context.inexport;
6738
    var generator = false;
6739
    if (state.tokens.next.value === "*") {
6740
      advance("*");
6741
      if (state.inES6({ strict: true })) {
6742
        generator = true;
6743
      } else {
6744
        warning("W119", state.tokens.curr, "function*", "6");
6745
      }
6746
    }
6747
    if (inblock) {
6748
      warning("W082", state.tokens.curr);
6749
    }
6750
    var i = optionalidentifier();
6751

    
6752
    state.funct["(scope)"].addlabel(i, {
6753
      type: "function",
6754
      token: state.tokens.curr });
6755

    
6756
    if (i === undefined) {
6757
      warning("W025");
6758
    } else if (inexport) {
6759
      state.funct["(scope)"].setExported(i, state.tokens.prev);
6760
    }
6761

    
6762
    doFunction({
6763
      name: i,
6764
      statement: this,
6765
      type: generator ? "generator" : null,
6766
      ignoreLoopFunc: inblock // a declaration may already have warned
6767
    });
6768
    if (state.tokens.next.id === "(" && state.tokens.next.line === state.tokens.curr.line) {
6769
      error("E039");
6770
    }
6771
    return this;
6772
  });
6773

    
6774
  prefix("function", function() {
6775
    var generator = false;
6776

    
6777
    if (state.tokens.next.value === "*") {
6778
      if (!state.inES6()) {
6779
        warning("W119", state.tokens.curr, "function*", "6");
6780
      }
6781
      advance("*");
6782
      generator = true;
6783
    }
6784

    
6785
    var i = optionalidentifier();
6786
    doFunction({ name: i, type: generator ? "generator" : null });
6787
    return this;
6788
  });
6789

    
6790
  blockstmt("if", function() {
6791
    var t = state.tokens.next;
6792
    increaseComplexityCount();
6793
    state.condition = true;
6794
    advance("(");
6795
    var expr = expression(0);
6796
    checkCondAssignment(expr);
6797
    var forinifcheck = null;
6798
    if (state.option.forin && state.forinifcheckneeded) {
6799
      state.forinifcheckneeded = false; // We only need to analyze the first if inside the loop
6800
      forinifcheck = state.forinifchecks[state.forinifchecks.length - 1];
6801
      if (expr.type === "(punctuator)" && expr.value === "!") {
6802
        forinifcheck.type = "(negative)";
6803
      } else {
6804
        forinifcheck.type = "(positive)";
6805
      }
6806
    }
6807

    
6808
    advance(")", t);
6809
    state.condition = false;
6810
    var s = block(true, true);
6811
    if (forinifcheck && forinifcheck.type === "(negative)") {
6812
      if (s && s[0] && s[0].type === "(identifier)" && s[0].value === "continue") {
6813
        forinifcheck.type = "(negative-with-continue)";
6814
      }
6815
    }
6816

    
6817
    if (state.tokens.next.id === "else") {
6818
      advance("else");
6819
      if (state.tokens.next.id === "if" || state.tokens.next.id === "switch") {
6820
        statement();
6821
      } else {
6822
        block(true, true);
6823
      }
6824
    }
6825
    return this;
6826
  });
6827

    
6828
  blockstmt("try", function() {
6829
    var b;
6830

    
6831
    function doCatch() {
6832
      advance("catch");
6833
      advance("(");
6834

    
6835
      state.funct["(scope)"].stack("catchparams");
6836

    
6837
      if (checkPunctuators(state.tokens.next, ["[", "{"])) {
6838
        var tokens = destructuringPattern();
6839
        _.each(tokens, function(token) {
6840
          if (token.id) {
6841
            state.funct["(scope)"].addParam(token.id, token, "exception");
6842
          }
6843
        });
6844
      } else if (state.tokens.next.type !== "(identifier)") {
6845
        warning("E030", state.tokens.next, state.tokens.next.value);
6846
      } else {
6847
        state.funct["(scope)"].addParam(identifier(), state.tokens.curr, "exception");
6848
      }
6849

    
6850
      if (state.tokens.next.value === "if") {
6851
        if (!state.inMoz()) {
6852
          warning("W118", state.tokens.curr, "catch filter");
6853
        }
6854
        advance("if");
6855
        expression(0);
6856
      }
6857

    
6858
      advance(")");
6859

    
6860
      block(false);
6861

    
6862
      state.funct["(scope)"].unstack();
6863
    }
6864

    
6865
    block(true);
6866

    
6867
    while (state.tokens.next.id === "catch") {
6868
      increaseComplexityCount();
6869
      if (b && (!state.inMoz())) {
6870
        warning("W118", state.tokens.next, "multiple catch blocks");
6871
      }
6872
      doCatch();
6873
      b = true;
6874
    }
6875

    
6876
    if (state.tokens.next.id === "finally") {
6877
      advance("finally");
6878
      block(true);
6879
      return;
6880
    }
6881

    
6882
    if (!b) {
6883
      error("E021", state.tokens.next, "catch", state.tokens.next.value);
6884
    }
6885

    
6886
    return this;
6887
  });
6888

    
6889
  blockstmt("while", function() {
6890
    var t = state.tokens.next;
6891
    state.funct["(breakage)"] += 1;
6892
    state.funct["(loopage)"] += 1;
6893
    increaseComplexityCount();
6894
    advance("(");
6895
    checkCondAssignment(expression(0));
6896
    advance(")", t);
6897
    block(true, true);
6898
    state.funct["(breakage)"] -= 1;
6899
    state.funct["(loopage)"] -= 1;
6900
    return this;
6901
  }).labelled = true;
6902

    
6903
  blockstmt("with", function() {
6904
    var t = state.tokens.next;
6905
    if (state.isStrict()) {
6906
      error("E010", state.tokens.curr);
6907
    } else if (!state.option.withstmt) {
6908
      warning("W085", state.tokens.curr);
6909
    }
6910

    
6911
    advance("(");
6912
    expression(0);
6913
    advance(")", t);
6914
    block(true, true);
6915

    
6916
    return this;
6917
  });
6918

    
6919
  blockstmt("switch", function() {
6920
    var t = state.tokens.next;
6921
    var g = false;
6922
    var noindent = false;
6923

    
6924
    state.funct["(breakage)"] += 1;
6925
    advance("(");
6926
    checkCondAssignment(expression(0));
6927
    advance(")", t);
6928
    t = state.tokens.next;
6929
    advance("{");
6930

    
6931
    if (state.tokens.next.from === indent)
6932
      noindent = true;
6933

    
6934
    if (!noindent)
6935
      indent += state.option.indent;
6936

    
6937
    this.cases = [];
6938

    
6939
    for (;;) {
6940
      switch (state.tokens.next.id) {
6941
      case "case":
6942
        switch (state.funct["(verb)"]) {
6943
        case "yield":
6944
        case "break":
6945
        case "case":
6946
        case "continue":
6947
        case "return":
6948
        case "switch":
6949
        case "throw":
6950
          break;
6951
        default:
6952
          if (!state.tokens.curr.caseFallsThrough) {
6953
            warning("W086", state.tokens.curr, "case");
6954
          }
6955
        }
6956

    
6957
        advance("case");
6958
        this.cases.push(expression(0));
6959
        increaseComplexityCount();
6960
        g = true;
6961
        advance(":");
6962
        state.funct["(verb)"] = "case";
6963
        break;
6964
      case "default":
6965
        switch (state.funct["(verb)"]) {
6966
        case "yield":
6967
        case "break":
6968
        case "continue":
6969
        case "return":
6970
        case "throw":
6971
          break;
6972
        default:
6973
          if (this.cases.length) {
6974
            if (!state.tokens.curr.caseFallsThrough) {
6975
              warning("W086", state.tokens.curr, "default");
6976
            }
6977
          }
6978
        }
6979

    
6980
        advance("default");
6981
        g = true;
6982
        advance(":");
6983
        break;
6984
      case "}":
6985
        if (!noindent)
6986
          indent -= state.option.indent;
6987

    
6988
        advance("}", t);
6989
        state.funct["(breakage)"] -= 1;
6990
        state.funct["(verb)"] = undefined;
6991
        return;
6992
      case "(end)":
6993
        error("E023", state.tokens.next, "}");
6994
        return;
6995
      default:
6996
        indent += state.option.indent;
6997
        if (g) {
6998
          switch (state.tokens.curr.id) {
6999
          case ",":
7000
            error("E040");
7001
            return;
7002
          case ":":
7003
            g = false;
7004
            statements();
7005
            break;
7006
          default:
7007
            error("E025", state.tokens.curr);
7008
            return;
7009
          }
7010
        } else {
7011
          if (state.tokens.curr.id === ":") {
7012
            advance(":");
7013
            error("E024", state.tokens.curr, ":");
7014
            statements();
7015
          } else {
7016
            error("E021", state.tokens.next, "case", state.tokens.next.value);
7017
            return;
7018
          }
7019
        }
7020
        indent -= state.option.indent;
7021
      }
7022
    }
7023
    return this;
7024
  }).labelled = true;
7025

    
7026
  stmt("debugger", function() {
7027
    if (!state.option.debug) {
7028
      warning("W087", this);
7029
    }
7030
    return this;
7031
  }).exps = true;
7032

    
7033
  (function() {
7034
    var x = stmt("do", function() {
7035
      state.funct["(breakage)"] += 1;
7036
      state.funct["(loopage)"] += 1;
7037
      increaseComplexityCount();
7038

    
7039
      this.first = block(true, true);
7040
      advance("while");
7041
      var t = state.tokens.next;
7042
      advance("(");
7043
      checkCondAssignment(expression(0));
7044
      advance(")", t);
7045
      state.funct["(breakage)"] -= 1;
7046
      state.funct["(loopage)"] -= 1;
7047
      return this;
7048
    });
7049
    x.labelled = true;
7050
    x.exps = true;
7051
  }());
7052

    
7053
  blockstmt("for", function() {
7054
    var s, t = state.tokens.next;
7055
    var letscope = false;
7056
    var foreachtok = null;
7057

    
7058
    if (t.value === "each") {
7059
      foreachtok = t;
7060
      advance("each");
7061
      if (!state.inMoz()) {
7062
        warning("W118", state.tokens.curr, "for each");
7063
      }
7064
    }
7065

    
7066
    increaseComplexityCount();
7067
    advance("(");
7068
    var nextop; // contains the token of the "in" or "of" operator
7069
    var i = 0;
7070
    var inof = ["in", "of"];
7071
    var level = 0; // BindingPattern "level" --- level 0 === no BindingPattern
7072
    var comma; // First comma punctuator at level 0
7073
    var initializer; // First initializer at level 0
7074
    if (checkPunctuators(state.tokens.next, ["{", "["])) ++level;
7075
    do {
7076
      nextop = peek(i);
7077
      ++i;
7078
      if (checkPunctuators(nextop, ["{", "["])) ++level;
7079
      else if (checkPunctuators(nextop, ["}", "]"])) --level;
7080
      if (level < 0) break;
7081
      if (level === 0) {
7082
        if (!comma && checkPunctuator(nextop, ",")) comma = nextop;
7083
        else if (!initializer && checkPunctuator(nextop, "=")) initializer = nextop;
7084
      }
7085
    } while (level > 0 || !_.contains(inof, nextop.value) && nextop.value !== ";" &&
7086
    nextop.type !== "(end)"); // Is this a JSCS bug? This looks really weird.
7087
    if (_.contains(inof, nextop.value)) {
7088
      if (!state.inES6() && nextop.value === "of") {
7089
        warning("W104", nextop, "for of", "6");
7090
      }
7091

    
7092
      var ok = !(initializer || comma);
7093
      if (initializer) {
7094
        error("W133", comma, nextop.value, "initializer is forbidden");
7095
      }
7096

    
7097
      if (comma) {
7098
        error("W133", comma, nextop.value, "more than one ForBinding");
7099
      }
7100

    
7101
      if (state.tokens.next.id === "var") {
7102
        advance("var");
7103
        state.tokens.curr.fud({ prefix: true });
7104
      } else if (state.tokens.next.id === "let" || state.tokens.next.id === "const") {
7105
        advance(state.tokens.next.id);
7106
        letscope = true;
7107
        state.funct["(scope)"].stack();
7108
        state.tokens.curr.fud({ prefix: true });
7109
      } else {
7110
        Object.create(varstatement).fud({ prefix: true, implied: "for", ignore: !ok });
7111
      }
7112
      advance(nextop.value);
7113
      expression(20);
7114
      advance(")", t);
7115

    
7116
      if (nextop.value === "in" && state.option.forin) {
7117
        state.forinifcheckneeded = true;
7118

    
7119
        if (state.forinifchecks === undefined) {
7120
          state.forinifchecks = [];
7121
        }
7122
        state.forinifchecks.push({
7123
          type: "(none)"
7124
        });
7125
      }
7126

    
7127
      state.funct["(breakage)"] += 1;
7128
      state.funct["(loopage)"] += 1;
7129

    
7130
      s = block(true, true);
7131

    
7132
      if (nextop.value === "in" && state.option.forin) {
7133
        if (state.forinifchecks && state.forinifchecks.length > 0) {
7134
          var check = state.forinifchecks.pop();
7135

    
7136
          if (// No if statement or not the first statement in loop body
7137
              s && s.length > 0 && (typeof s[0] !== "object" || s[0].value !== "if") ||
7138
              check.type === "(positive)" && s.length > 1 ||
7139
              check.type === "(negative)") {
7140
            warning("W089", this);
7141
          }
7142
        }
7143
        state.forinifcheckneeded = false;
7144
      }
7145

    
7146
      state.funct["(breakage)"] -= 1;
7147
      state.funct["(loopage)"] -= 1;
7148
    } else {
7149
      if (foreachtok) {
7150
        error("E045", foreachtok);
7151
      }
7152
      if (state.tokens.next.id !== ";") {
7153
        if (state.tokens.next.id === "var") {
7154
          advance("var");
7155
          state.tokens.curr.fud();
7156
        } else if (state.tokens.next.id === "let") {
7157
          advance("let");
7158
          letscope = true;
7159
          state.funct["(scope)"].stack();
7160
          state.tokens.curr.fud();
7161
        } else {
7162
          for (;;) {
7163
            expression(0, "for");
7164
            if (state.tokens.next.id !== ",") {
7165
              break;
7166
            }
7167
            comma();
7168
          }
7169
        }
7170
      }
7171
      nolinebreak(state.tokens.curr);
7172
      advance(";");
7173
      state.funct["(loopage)"] += 1;
7174
      if (state.tokens.next.id !== ";") {
7175
        checkCondAssignment(expression(0));
7176
      }
7177
      nolinebreak(state.tokens.curr);
7178
      advance(";");
7179
      if (state.tokens.next.id === ";") {
7180
        error("E021", state.tokens.next, ")", ";");
7181
      }
7182
      if (state.tokens.next.id !== ")") {
7183
        for (;;) {
7184
          expression(0, "for");
7185
          if (state.tokens.next.id !== ",") {
7186
            break;
7187
          }
7188
          comma();
7189
        }
7190
      }
7191
      advance(")", t);
7192
      state.funct["(breakage)"] += 1;
7193
      block(true, true);
7194
      state.funct["(breakage)"] -= 1;
7195
      state.funct["(loopage)"] -= 1;
7196

    
7197
    }
7198
    if (letscope) {
7199
      state.funct["(scope)"].unstack();
7200
    }
7201
    return this;
7202
  }).labelled = true;
7203

    
7204

    
7205
  stmt("break", function() {
7206
    var v = state.tokens.next.value;
7207

    
7208
    if (!state.option.asi)
7209
      nolinebreak(this);
7210

    
7211
    if (state.tokens.next.id !== ";" && !state.tokens.next.reach &&
7212
        state.tokens.curr.line === startLine(state.tokens.next)) {
7213
      if (!state.funct["(scope)"].funct.hasBreakLabel(v)) {
7214
        warning("W090", state.tokens.next, v);
7215
      }
7216
      this.first = state.tokens.next;
7217
      advance();
7218
    } else {
7219
      if (state.funct["(breakage)"] === 0)
7220
        warning("W052", state.tokens.next, this.value);
7221
    }
7222

    
7223
    reachable(this);
7224

    
7225
    return this;
7226
  }).exps = true;
7227

    
7228

    
7229
  stmt("continue", function() {
7230
    var v = state.tokens.next.value;
7231

    
7232
    if (state.funct["(breakage)"] === 0)
7233
      warning("W052", state.tokens.next, this.value);
7234
    if (!state.funct["(loopage)"])
7235
      warning("W052", state.tokens.next, this.value);
7236

    
7237
    if (!state.option.asi)
7238
      nolinebreak(this);
7239

    
7240
    if (state.tokens.next.id !== ";" && !state.tokens.next.reach) {
7241
      if (state.tokens.curr.line === startLine(state.tokens.next)) {
7242
        if (!state.funct["(scope)"].funct.hasBreakLabel(v)) {
7243
          warning("W090", state.tokens.next, v);
7244
        }
7245
        this.first = state.tokens.next;
7246
        advance();
7247
      }
7248
    }
7249

    
7250
    reachable(this);
7251

    
7252
    return this;
7253
  }).exps = true;
7254

    
7255

    
7256
  stmt("return", function() {
7257
    if (this.line === startLine(state.tokens.next)) {
7258
      if (state.tokens.next.id !== ";" && !state.tokens.next.reach) {
7259
        this.first = expression(0);
7260

    
7261
        if (this.first &&
7262
            this.first.type === "(punctuator)" && this.first.value === "=" &&
7263
            !this.first.paren && !state.option.boss) {
7264
          warningAt("W093", this.first.line, this.first.character);
7265
        }
7266
      }
7267
    } else {
7268
      if (state.tokens.next.type === "(punctuator)" &&
7269
        ["[", "{", "+", "-"].indexOf(state.tokens.next.value) > -1) {
7270
        nolinebreak(this); // always warn (Line breaking error)
7271
      }
7272
    }
7273

    
7274
    reachable(this);
7275

    
7276
    return this;
7277
  }).exps = true;
7278

    
7279
  (function(x) {
7280
    x.exps = true;
7281
    x.lbp = 25;
7282
  }(prefix("yield", function() {
7283
    var prev = state.tokens.prev;
7284
    if (state.inES6(true) && !state.funct["(generator)"]) {
7285
      if (!("(catch)" === state.funct["(name)"] && state.funct["(context)"]["(generator)"])) {
7286
        error("E046", state.tokens.curr, "yield");
7287
      }
7288
    } else if (!state.inES6()) {
7289
      warning("W104", state.tokens.curr, "yield", "6");
7290
    }
7291
    state.funct["(generator)"] = "yielded";
7292
    var delegatingYield = false;
7293

    
7294
    if (state.tokens.next.value === "*") {
7295
      delegatingYield = true;
7296
      advance("*");
7297
    }
7298

    
7299
    if (this.line === startLine(state.tokens.next) || !state.inMoz()) {
7300
      if (delegatingYield ||
7301
          (state.tokens.next.id !== ";" && !state.option.asi &&
7302
           !state.tokens.next.reach && state.tokens.next.nud)) {
7303

    
7304
        nobreaknonadjacent(state.tokens.curr, state.tokens.next);
7305
        this.first = expression(10);
7306

    
7307
        if (this.first.type === "(punctuator)" && this.first.value === "=" &&
7308
            !this.first.paren && !state.option.boss) {
7309
          warningAt("W093", this.first.line, this.first.character);
7310
        }
7311
      }
7312

    
7313
      if (state.inMoz() && state.tokens.next.id !== ")" &&
7314
          (prev.lbp > 30 || (!prev.assign && !isEndOfExpr()) || prev.id === "yield")) {
7315
        error("E050", this);
7316
      }
7317
    } else if (!state.option.asi) {
7318
      nolinebreak(this); // always warn (Line breaking error)
7319
    }
7320
    return this;
7321
  })));
7322

    
7323

    
7324
  stmt("throw", function() {
7325
    nolinebreak(this);
7326
    this.first = expression(20);
7327

    
7328
    reachable(this);
7329

    
7330
    return this;
7331
  }).exps = true;
7332

    
7333
  stmt("import", function() {
7334
    if (!state.inES6()) {
7335
      warning("W119", state.tokens.curr, "import", "6");
7336
    }
7337

    
7338
    if (state.tokens.next.type === "(string)") {
7339
      advance("(string)");
7340
      return this;
7341
    }
7342

    
7343
    if (state.tokens.next.identifier) {
7344
      this.name = identifier();
7345
      state.funct["(scope)"].addlabel(this.name, {
7346
        type: "const",
7347
        token: state.tokens.curr });
7348

    
7349
      if (state.tokens.next.value === ",") {
7350
        advance(",");
7351
      } else {
7352
        advance("from");
7353
        advance("(string)");
7354
        return this;
7355
      }
7356
    }
7357

    
7358
    if (state.tokens.next.id === "*") {
7359
      advance("*");
7360
      advance("as");
7361
      if (state.tokens.next.identifier) {
7362
        this.name = identifier();
7363
        state.funct["(scope)"].addlabel(this.name, {
7364
          type: "const",
7365
          token: state.tokens.curr });
7366
      }
7367
    } else {
7368
      advance("{");
7369
      for (;;) {
7370
        if (state.tokens.next.value === "}") {
7371
          advance("}");
7372
          break;
7373
        }
7374
        var importName;
7375
        if (state.tokens.next.type === "default") {
7376
          importName = "default";
7377
          advance("default");
7378
        } else {
7379
          importName = identifier();
7380
        }
7381
        if (state.tokens.next.value === "as") {
7382
          advance("as");
7383
          importName = identifier();
7384
        }
7385
        state.funct["(scope)"].addlabel(importName, {
7386
          type: "const",
7387
          token: state.tokens.curr });
7388

    
7389
        if (state.tokens.next.value === ",") {
7390
          advance(",");
7391
        } else if (state.tokens.next.value === "}") {
7392
          advance("}");
7393
          break;
7394
        } else {
7395
          error("E024", state.tokens.next, state.tokens.next.value);
7396
          break;
7397
        }
7398
      }
7399
    }
7400
    advance("from");
7401
    advance("(string)");
7402
    return this;
7403
  }).exps = true;
7404

    
7405
  stmt("export", function() {
7406
    var ok = true;
7407
    var token;
7408
    var identifier;
7409

    
7410
    if (!state.inES6()) {
7411
      warning("W119", state.tokens.curr, "export", "6");
7412
      ok = false;
7413
    }
7414

    
7415
    if (!state.funct["(scope)"].block.isGlobal()) {
7416
      error("E053", state.tokens.curr);
7417
      ok = false;
7418
    }
7419

    
7420
    if (state.tokens.next.value === "*") {
7421
      advance("*");
7422
      advance("from");
7423
      advance("(string)");
7424
      return this;
7425
    }
7426

    
7427
    if (state.tokens.next.type === "default") {
7428
      state.nameStack.set(state.tokens.next);
7429
      advance("default");
7430
      var exportType = state.tokens.next.id;
7431
      if (exportType === "function" || exportType === "class") {
7432
        this.block = true;
7433
      }
7434

    
7435
      token = peek();
7436

    
7437
      expression(10);
7438

    
7439
      identifier = token.value;
7440

    
7441
      if (this.block) {
7442
        state.funct["(scope)"].addlabel(identifier, {
7443
          type: exportType,
7444
          token: token });
7445

    
7446
        state.funct["(scope)"].setExported(identifier, token);
7447
      }
7448

    
7449
      return this;
7450
    }
7451

    
7452
    if (state.tokens.next.value === "{") {
7453
      advance("{");
7454
      var exportedTokens = [];
7455
      for (;;) {
7456
        if (!state.tokens.next.identifier) {
7457
          error("E030", state.tokens.next, state.tokens.next.value);
7458
        }
7459
        advance();
7460

    
7461
        exportedTokens.push(state.tokens.curr);
7462

    
7463
        if (state.tokens.next.value === "as") {
7464
          advance("as");
7465
          if (!state.tokens.next.identifier) {
7466
            error("E030", state.tokens.next, state.tokens.next.value);
7467
          }
7468
          advance();
7469
        }
7470

    
7471
        if (state.tokens.next.value === ",") {
7472
          advance(",");
7473
        } else if (state.tokens.next.value === "}") {
7474
          advance("}");
7475
          break;
7476
        } else {
7477
          error("E024", state.tokens.next, state.tokens.next.value);
7478
          break;
7479
        }
7480
      }
7481
      if (state.tokens.next.value === "from") {
7482
        advance("from");
7483
        advance("(string)");
7484
      } else if (ok) {
7485
        exportedTokens.forEach(function(token) {
7486
          state.funct["(scope)"].setExported(token.value, token);
7487
        });
7488
      }
7489
      return this;
7490
    }
7491

    
7492
    if (state.tokens.next.id === "var") {
7493
      advance("var");
7494
      state.tokens.curr.fud({ inexport:true });
7495
    } else if (state.tokens.next.id === "let") {
7496
      advance("let");
7497
      state.tokens.curr.fud({ inexport:true });
7498
    } else if (state.tokens.next.id === "const") {
7499
      advance("const");
7500
      state.tokens.curr.fud({ inexport:true });
7501
    } else if (state.tokens.next.id === "function") {
7502
      this.block = true;
7503
      advance("function");
7504
      state.syntax["function"].fud({ inexport:true });
7505
    } else if (state.tokens.next.id === "class") {
7506
      this.block = true;
7507
      advance("class");
7508
      var classNameToken = state.tokens.next;
7509
      state.syntax["class"].fud();
7510
      state.funct["(scope)"].setExported(classNameToken.value, classNameToken);
7511
    } else {
7512
      error("E024", state.tokens.next, state.tokens.next.value);
7513
    }
7514

    
7515
    return this;
7516
  }).exps = true;
7517

    
7518
  FutureReservedWord("abstract");
7519
  FutureReservedWord("boolean");
7520
  FutureReservedWord("byte");
7521
  FutureReservedWord("char");
7522
  FutureReservedWord("class", { es5: true, nud: classdef });
7523
  FutureReservedWord("double");
7524
  FutureReservedWord("enum", { es5: true });
7525
  FutureReservedWord("export", { es5: true });
7526
  FutureReservedWord("extends", { es5: true });
7527
  FutureReservedWord("final");
7528
  FutureReservedWord("float");
7529
  FutureReservedWord("goto");
7530
  FutureReservedWord("implements", { es5: true, strictOnly: true });
7531
  FutureReservedWord("import", { es5: true });
7532
  FutureReservedWord("int");
7533
  FutureReservedWord("interface", { es5: true, strictOnly: true });
7534
  FutureReservedWord("long");
7535
  FutureReservedWord("native");
7536
  FutureReservedWord("package", { es5: true, strictOnly: true });
7537
  FutureReservedWord("private", { es5: true, strictOnly: true });
7538
  FutureReservedWord("protected", { es5: true, strictOnly: true });
7539
  FutureReservedWord("public", { es5: true, strictOnly: true });
7540
  FutureReservedWord("short");
7541
  FutureReservedWord("static", { es5: true, strictOnly: true });
7542
  FutureReservedWord("super", { es5: true });
7543
  FutureReservedWord("synchronized");
7544
  FutureReservedWord("transient");
7545
  FutureReservedWord("volatile");
7546

    
7547
  var lookupBlockType = function() {
7548
    var pn, pn1, prev;
7549
    var i = -1;
7550
    var bracketStack = 0;
7551
    var ret = {};
7552
    if (checkPunctuators(state.tokens.curr, ["[", "{"])) {
7553
      bracketStack += 1;
7554
    }
7555
    do {
7556
      prev = i === -1 ? state.tokens.curr : pn;
7557
      pn = i === -1 ? state.tokens.next : peek(i);
7558
      pn1 = peek(i + 1);
7559
      i = i + 1;
7560
      if (checkPunctuators(pn, ["[", "{"])) {
7561
        bracketStack += 1;
7562
      } else if (checkPunctuators(pn, ["]", "}"])) {
7563
        bracketStack -= 1;
7564
      }
7565
      if (bracketStack === 1 && pn.identifier && pn.value === "for" &&
7566
          !checkPunctuator(prev, ".")) {
7567
        ret.isCompArray = true;
7568
        ret.notJson = true;
7569
        break;
7570
      }
7571
      if (bracketStack === 0 && checkPunctuators(pn, ["}", "]"])) {
7572
        if (pn1.value === "=") {
7573
          ret.isDestAssign = true;
7574
          ret.notJson = true;
7575
          break;
7576
        } else if (pn1.value === ".") {
7577
          ret.notJson = true;
7578
          break;
7579
        }
7580
      }
7581
      if (checkPunctuator(pn, ";")) {
7582
        ret.isBlock = true;
7583
        ret.notJson = true;
7584
      }
7585
    } while (bracketStack > 0 && pn.id !== "(end)");
7586
    return ret;
7587
  };
7588

    
7589
  function saveProperty(props, name, tkn, isClass, isStatic) {
7590
    var msg = ["key", "class method", "static class method"];
7591
    msg = msg[(isClass || false) + (isStatic || false)];
7592
    if (tkn.identifier) {
7593
      name = tkn.value;
7594
    }
7595

    
7596
    if (props[name] && name !== "__proto__") {
7597
      warning("W075", state.tokens.next, msg, name);
7598
    } else {
7599
      props[name] = Object.create(null);
7600
    }
7601

    
7602
    props[name].basic = true;
7603
    props[name].basictkn = tkn;
7604
  }
7605
  function saveAccessor(accessorType, props, name, tkn, isClass, isStatic) {
7606
    var flagName = accessorType === "get" ? "getterToken" : "setterToken";
7607
    var msg = "";
7608

    
7609
    if (isClass) {
7610
      if (isStatic) {
7611
        msg += "static ";
7612
      }
7613
      msg += accessorType + "ter method";
7614
    } else {
7615
      msg = "key";
7616
    }
7617

    
7618
    state.tokens.curr.accessorType = accessorType;
7619
    state.nameStack.set(tkn);
7620

    
7621
    if (props[name]) {
7622
      if ((props[name].basic || props[name][flagName]) && name !== "__proto__") {
7623
        warning("W075", state.tokens.next, msg, name);
7624
      }
7625
    } else {
7626
      props[name] = Object.create(null);
7627
    }
7628

    
7629
    props[name][flagName] = tkn;
7630
  }
7631

    
7632
  function computedPropertyName() {
7633
    advance("[");
7634
    if (!state.inES6()) {
7635
      warning("W119", state.tokens.curr, "computed property names", "6");
7636
    }
7637
    var value = expression(10);
7638
    advance("]");
7639
    return value;
7640
  }
7641
  function checkPunctuators(token, values) {
7642
    if (token.type === "(punctuator)") {
7643
      return _.contains(values, token.value);
7644
    }
7645
    return false;
7646
  }
7647
  function checkPunctuator(token, value) {
7648
    return token.type === "(punctuator)" && token.value === value;
7649
  }
7650
  function destructuringAssignOrJsonValue() {
7651

    
7652
    var block = lookupBlockType();
7653
    if (block.notJson) {
7654
      if (!state.inES6() && block.isDestAssign) {
7655
        warning("W104", state.tokens.curr, "destructuring assignment", "6");
7656
      }
7657
      statements();
7658
    } else {
7659
      state.option.laxbreak = true;
7660
      state.jsonMode = true;
7661
      jsonValue();
7662
    }
7663
  }
7664

    
7665
  var arrayComprehension = function() {
7666
    var CompArray = function() {
7667
      this.mode = "use";
7668
      this.variables = [];
7669
    };
7670
    var _carrays = [];
7671
    var _current;
7672
    function declare(v) {
7673
      var l = _current.variables.filter(function(elt) {
7674
        if (elt.value === v) {
7675
          elt.undef = false;
7676
          return v;
7677
        }
7678
      }).length;
7679
      return l !== 0;
7680
    }
7681
    function use(v) {
7682
      var l = _current.variables.filter(function(elt) {
7683
        if (elt.value === v && !elt.undef) {
7684
          if (elt.unused === true) {
7685
            elt.unused = false;
7686
          }
7687
          return v;
7688
        }
7689
      }).length;
7690
      return (l === 0);
7691
    }
7692
    return { stack: function() {
7693
          _current = new CompArray();
7694
          _carrays.push(_current);
7695
        },
7696
        unstack: function() {
7697
          _current.variables.filter(function(v) {
7698
            if (v.unused)
7699
              warning("W098", v.token, v.raw_text || v.value);
7700
            if (v.undef)
7701
              state.funct["(scope)"].block.use(v.value, v.token);
7702
          });
7703
          _carrays.splice(-1, 1);
7704
          _current = _carrays[_carrays.length - 1];
7705
        },
7706
        setState: function(s) {
7707
          if (_.contains(["use", "define", "generate", "filter"], s))
7708
            _current.mode = s;
7709
        },
7710
        check: function(v) {
7711
          if (!_current) {
7712
            return;
7713
          }
7714
          if (_current && _current.mode === "use") {
7715
            if (use(v)) {
7716
              _current.variables.push({
7717
                funct: state.funct,
7718
                token: state.tokens.curr,
7719
                value: v,
7720
                undef: true,
7721
                unused: false
7722
              });
7723
            }
7724
            return true;
7725
          } else if (_current && _current.mode === "define") {
7726
            if (!declare(v)) {
7727
              _current.variables.push({
7728
                funct: state.funct,
7729
                token: state.tokens.curr,
7730
                value: v,
7731
                undef: false,
7732
                unused: true
7733
              });
7734
            }
7735
            return true;
7736
          } else if (_current && _current.mode === "generate") {
7737
            state.funct["(scope)"].block.use(v, state.tokens.curr);
7738
            return true;
7739
          } else if (_current && _current.mode === "filter") {
7740
            if (use(v)) {
7741
              state.funct["(scope)"].block.use(v, state.tokens.curr);
7742
            }
7743
            return true;
7744
          }
7745
          return false;
7746
        }
7747
        };
7748
  };
7749

    
7750
  function jsonValue() {
7751
    function jsonObject() {
7752
      var o = {}, t = state.tokens.next;
7753
      advance("{");
7754
      if (state.tokens.next.id !== "}") {
7755
        for (;;) {
7756
          if (state.tokens.next.id === "(end)") {
7757
            error("E026", state.tokens.next, t.line);
7758
          } else if (state.tokens.next.id === "}") {
7759
            warning("W094", state.tokens.curr);
7760
            break;
7761
          } else if (state.tokens.next.id === ",") {
7762
            error("E028", state.tokens.next);
7763
          } else if (state.tokens.next.id !== "(string)") {
7764
            warning("W095", state.tokens.next, state.tokens.next.value);
7765
          }
7766
          if (o[state.tokens.next.value] === true) {
7767
            warning("W075", state.tokens.next, "key", state.tokens.next.value);
7768
          } else if ((state.tokens.next.value === "__proto__" &&
7769
            !state.option.proto) || (state.tokens.next.value === "__iterator__" &&
7770
            !state.option.iterator)) {
7771
            warning("W096", state.tokens.next, state.tokens.next.value);
7772
          } else {
7773
            o[state.tokens.next.value] = true;
7774
          }
7775
          advance();
7776
          advance(":");
7777
          jsonValue();
7778
          if (state.tokens.next.id !== ",") {
7779
            break;
7780
          }
7781
          advance(",");
7782
        }
7783
      }
7784
      advance("}");
7785
    }
7786

    
7787
    function jsonArray() {
7788
      var t = state.tokens.next;
7789
      advance("[");
7790
      if (state.tokens.next.id !== "]") {
7791
        for (;;) {
7792
          if (state.tokens.next.id === "(end)") {
7793
            error("E027", state.tokens.next, t.line);
7794
          } else if (state.tokens.next.id === "]") {
7795
            warning("W094", state.tokens.curr);
7796
            break;
7797
          } else if (state.tokens.next.id === ",") {
7798
            error("E028", state.tokens.next);
7799
          }
7800
          jsonValue();
7801
          if (state.tokens.next.id !== ",") {
7802
            break;
7803
          }
7804
          advance(",");
7805
        }
7806
      }
7807
      advance("]");
7808
    }
7809

    
7810
    switch (state.tokens.next.id) {
7811
    case "{":
7812
      jsonObject();
7813
      break;
7814
    case "[":
7815
      jsonArray();
7816
      break;
7817
    case "true":
7818
    case "false":
7819
    case "null":
7820
    case "(number)":
7821
    case "(string)":
7822
      advance();
7823
      break;
7824
    case "-":
7825
      advance("-");
7826
      advance("(number)");
7827
      break;
7828
    default:
7829
      error("E003", state.tokens.next);
7830
    }
7831
  }
7832

    
7833
  var escapeRegex = function(str) {
7834
    return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
7835
  };
7836
  var itself = function(s, o, g) {
7837
    var i, k, x, reIgnoreStr, reIgnore;
7838
    var optionKeys;
7839
    var newOptionObj = {};
7840
    var newIgnoredObj = {};
7841

    
7842
    o = _.clone(o);
7843
    state.reset();
7844

    
7845
    if (o && o.scope) {
7846
      JSHINT.scope = o.scope;
7847
    } else {
7848
      JSHINT.errors = [];
7849
      JSHINT.undefs = [];
7850
      JSHINT.internals = [];
7851
      JSHINT.blacklist = {};
7852
      JSHINT.scope = "(main)";
7853
    }
7854

    
7855
    predefined = Object.create(null);
7856
    combine(predefined, vars.ecmaIdentifiers[3]);
7857
    combine(predefined, vars.reservedVars);
7858

    
7859
    combine(predefined, g || {});
7860

    
7861
    declared = Object.create(null);
7862
    var exported = Object.create(null); // Variables that live outside the current file
7863

    
7864
    function each(obj, cb) {
7865
      if (!obj)
7866
        return;
7867

    
7868
      if (!Array.isArray(obj) && typeof obj === "object")
7869
        obj = Object.keys(obj);
7870

    
7871
      obj.forEach(cb);
7872
    }
7873

    
7874
    if (o) {
7875
      each(o.predef || null, function(item) {
7876
        var slice, prop;
7877

    
7878
        if (item[0] === "-") {
7879
          slice = item.slice(1);
7880
          JSHINT.blacklist[slice] = slice;
7881
          delete predefined[slice];
7882
        } else {
7883
          prop = Object.getOwnPropertyDescriptor(o.predef, item);
7884
          predefined[item] = prop ? prop.value : false;
7885
        }
7886
      });
7887

    
7888
      each(o.exported || null, function(item) {
7889
        exported[item] = true;
7890
      });
7891

    
7892
      delete o.predef;
7893
      delete o.exported;
7894

    
7895
      optionKeys = Object.keys(o);
7896
      for (x = 0; x < optionKeys.length; x++) {
7897
        if (/^-W\d{3}$/g.test(optionKeys[x])) {
7898
          newIgnoredObj[optionKeys[x].slice(1)] = true;
7899
        } else {
7900
          var optionKey = optionKeys[x];
7901
          newOptionObj[optionKey] = o[optionKey];
7902
          if ((optionKey === "esversion" && o[optionKey] === 5) ||
7903
              (optionKey === "es5" && o[optionKey])) {
7904
            warning("I003");
7905
          }
7906

    
7907
          if (optionKeys[x] === "newcap" && o[optionKey] === false)
7908
            newOptionObj["(explicitNewcap)"] = true;
7909
        }
7910
      }
7911
    }
7912

    
7913
    state.option = newOptionObj;
7914
    state.ignored = newIgnoredObj;
7915

    
7916
    state.option.indent = state.option.indent || 4;
7917
    state.option.maxerr = state.option.maxerr || 50;
7918

    
7919
    indent = 1;
7920

    
7921
    var scopeManagerInst = scopeManager(state, predefined, exported, declared);
7922
    scopeManagerInst.on("warning", function(ev) {
7923
      warning.apply(null, [ ev.code, ev.token].concat(ev.data));
7924
    });
7925

    
7926
    scopeManagerInst.on("error", function(ev) {
7927
      error.apply(null, [ ev.code, ev.token ].concat(ev.data));
7928
    });
7929

    
7930
    state.funct = functor("(global)", null, {
7931
      "(global)"    : true,
7932
      "(scope)"     : scopeManagerInst,
7933
      "(comparray)" : arrayComprehension(),
7934
      "(metrics)"   : createMetrics(state.tokens.next)
7935
    });
7936

    
7937
    functions = [state.funct];
7938
    urls = [];
7939
    stack = null;
7940
    member = {};
7941
    membersOnly = null;
7942
    inblock = false;
7943
    lookahead = [];
7944

    
7945
    if (!isString(s) && !Array.isArray(s)) {
7946
      errorAt("E004", 0);
7947
      return false;
7948
    }
7949

    
7950
    api = {
7951
      get isJSON() {
7952
        return state.jsonMode;
7953
      },
7954

    
7955
      getOption: function(name) {
7956
        return state.option[name] || null;
7957
      },
7958

    
7959
      getCache: function(name) {
7960
        return state.cache[name];
7961
      },
7962

    
7963
      setCache: function(name, value) {
7964
        state.cache[name] = value;
7965
      },
7966

    
7967
      warn: function(code, data) {
7968
        warningAt.apply(null, [ code, data.line, data.char ].concat(data.data));
7969
      },
7970

    
7971
      on: function(names, listener) {
7972
        names.split(" ").forEach(function(name) {
7973
          emitter.on(name, listener);
7974
        }.bind(this));
7975
      }
7976
    };
7977

    
7978
    emitter.removeAllListeners();
7979
    (extraModules || []).forEach(function(func) {
7980
      func(api);
7981
    });
7982

    
7983
    state.tokens.prev = state.tokens.curr = state.tokens.next = state.syntax["(begin)"];
7984

    
7985
    if (o && o.ignoreDelimiters) {
7986

    
7987
      if (!Array.isArray(o.ignoreDelimiters)) {
7988
        o.ignoreDelimiters = [o.ignoreDelimiters];
7989
      }
7990

    
7991
      o.ignoreDelimiters.forEach(function(delimiterPair) {
7992
        if (!delimiterPair.start || !delimiterPair.end)
7993
            return;
7994

    
7995
        reIgnoreStr = escapeRegex(delimiterPair.start) +
7996
                      "[\\s\\S]*?" +
7997
                      escapeRegex(delimiterPair.end);
7998

    
7999
        reIgnore = new RegExp(reIgnoreStr, "ig");
8000

    
8001
        s = s.replace(reIgnore, function(match) {
8002
          return match.replace(/./g, " ");
8003
        });
8004
      });
8005
    }
8006

    
8007
    lex = new Lexer(s);
8008

    
8009
    lex.on("warning", function(ev) {
8010
      warningAt.apply(null, [ ev.code, ev.line, ev.character].concat(ev.data));
8011
    });
8012

    
8013
    lex.on("error", function(ev) {
8014
      errorAt.apply(null, [ ev.code, ev.line, ev.character ].concat(ev.data));
8015
    });
8016

    
8017
    lex.on("fatal", function(ev) {
8018
      quit("E041", ev.line, ev.from);
8019
    });
8020

    
8021
    lex.on("Identifier", function(ev) {
8022
      emitter.emit("Identifier", ev);
8023
    });
8024

    
8025
    lex.on("String", function(ev) {
8026
      emitter.emit("String", ev);
8027
    });
8028

    
8029
    lex.on("Number", function(ev) {
8030
      emitter.emit("Number", ev);
8031
    });
8032

    
8033
    lex.start();
8034
    for (var name in o) {
8035
      if (_.has(o, name)) {
8036
        checkOption(name, state.tokens.curr);
8037
      }
8038
    }
8039

    
8040
    assume();
8041
    combine(predefined, g || {});
8042
    comma.first = true;
8043

    
8044
    try {
8045
      advance();
8046
      switch (state.tokens.next.id) {
8047
      case "{":
8048
      case "[":
8049
        destructuringAssignOrJsonValue();
8050
        break;
8051
      default:
8052
        directives();
8053

    
8054
        if (state.directive["use strict"]) {
8055
          if (state.option.strict !== "global") {
8056
            warning("W097", state.tokens.prev);
8057
          }
8058
        }
8059

    
8060
        statements();
8061
      }
8062

    
8063
      if (state.tokens.next.id !== "(end)") {
8064
        quit("E041", state.tokens.curr.line);
8065
      }
8066

    
8067
      state.funct["(scope)"].unstack();
8068

    
8069
    } catch (err) {
8070
      if (err && err.name === "JSHintError") {
8071
        var nt = state.tokens.next || {};
8072
        JSHINT.errors.push({
8073
          scope     : "(main)",
8074
          raw       : err.raw,
8075
          code      : err.code,
8076
          reason    : err.message,
8077
          line      : err.line || nt.line,
8078
          character : err.character || nt.from
8079
        }, null);
8080
      } else {
8081
        throw err;
8082
      }
8083
    }
8084

    
8085
    if (JSHINT.scope === "(main)") {
8086
      o = o || {};
8087

    
8088
      for (i = 0; i < JSHINT.internals.length; i += 1) {
8089
        k = JSHINT.internals[i];
8090
        o.scope = k.elem;
8091
        itself(k.value, o, g);
8092
      }
8093
    }
8094

    
8095
    return JSHINT.errors.length === 0;
8096
  };
8097
  itself.addModule = function(func) {
8098
    extraModules.push(func);
8099
  };
8100

    
8101
  itself.addModule(style.register);
8102
  itself.data = function() {
8103
    var data = {
8104
      functions: [],
8105
      options: state.option
8106
    };
8107

    
8108
    var fu, f, i, j, n, globals;
8109

    
8110
    if (itself.errors.length) {
8111
      data.errors = itself.errors;
8112
    }
8113

    
8114
    if (state.jsonMode) {
8115
      data.json = true;
8116
    }
8117

    
8118
    var impliedGlobals = state.funct["(scope)"].getImpliedGlobals();
8119
    if (impliedGlobals.length > 0) {
8120
      data.implieds = impliedGlobals;
8121
    }
8122

    
8123
    if (urls.length > 0) {
8124
      data.urls = urls;
8125
    }
8126

    
8127
    globals = state.funct["(scope)"].getUsedOrDefinedGlobals();
8128
    if (globals.length > 0) {
8129
      data.globals = globals;
8130
    }
8131

    
8132
    for (i = 1; i < functions.length; i += 1) {
8133
      f = functions[i];
8134
      fu = {};
8135

    
8136
      for (j = 0; j < functionicity.length; j += 1) {
8137
        fu[functionicity[j]] = [];
8138
      }
8139

    
8140
      for (j = 0; j < functionicity.length; j += 1) {
8141
        if (fu[functionicity[j]].length === 0) {
8142
          delete fu[functionicity[j]];
8143
        }
8144
      }
8145

    
8146
      fu.name = f["(name)"];
8147
      fu.param = f["(params)"];
8148
      fu.line = f["(line)"];
8149
      fu.character = f["(character)"];
8150
      fu.last = f["(last)"];
8151
      fu.lastcharacter = f["(lastcharacter)"];
8152

    
8153
      fu.metrics = {
8154
        complexity: f["(metrics)"].ComplexityCount,
8155
        parameters: f["(metrics)"].arity,
8156
        statements: f["(metrics)"].statementCount
8157
      };
8158

    
8159
      data.functions.push(fu);
8160
    }
8161

    
8162
    var unuseds = state.funct["(scope)"].getUnuseds();
8163
    if (unuseds.length > 0) {
8164
      data.unused = unuseds;
8165
    }
8166

    
8167
    for (n in member) {
8168
      if (typeof member[n] === "number") {
8169
        data.member = member;
8170
        break;
8171
      }
8172
    }
8173

    
8174
    return data;
8175
  };
8176

    
8177
  itself.jshint = itself;
8178

    
8179
  return itself;
8180
}());
8181
if (typeof exports === "object" && exports) {
8182
  exports.JSHINT = JSHINT;
8183
}
8184

    
8185
},{"../lodash":"/node_modules/jshint/lodash.js","./lex.js":"/node_modules/jshint/src/lex.js","./messages.js":"/node_modules/jshint/src/messages.js","./options.js":"/node_modules/jshint/src/options.js","./reg.js":"/node_modules/jshint/src/reg.js","./scope-manager.js":"/node_modules/jshint/src/scope-manager.js","./state.js":"/node_modules/jshint/src/state.js","./style.js":"/node_modules/jshint/src/style.js","./vars.js":"/node_modules/jshint/src/vars.js","events":"/node_modules/browserify/node_modules/events/events.js"}],"/node_modules/jshint/src/lex.js":[function(_dereq_,module,exports){
8186

    
8187
"use strict";
8188

    
8189
var _      = _dereq_("../lodash");
8190
var events = _dereq_("events");
8191
var reg    = _dereq_("./reg.js");
8192
var state  = _dereq_("./state.js").state;
8193

    
8194
var unicodeData = _dereq_("../data/ascii-identifier-data.js");
8195
var asciiIdentifierStartTable = unicodeData.asciiIdentifierStartTable;
8196
var asciiIdentifierPartTable = unicodeData.asciiIdentifierPartTable;
8197

    
8198
var Token = {
8199
  Identifier: 1,
8200
  Punctuator: 2,
8201
  NumericLiteral: 3,
8202
  StringLiteral: 4,
8203
  Comment: 5,
8204
  Keyword: 6,
8205
  NullLiteral: 7,
8206
  BooleanLiteral: 8,
8207
  RegExp: 9,
8208
  TemplateHead: 10,
8209
  TemplateMiddle: 11,
8210
  TemplateTail: 12,
8211
  NoSubstTemplate: 13
8212
};
8213

    
8214
var Context = {
8215
  Block: 1,
8216
  Template: 2
8217
};
8218

    
8219
function asyncTrigger() {
8220
  var _checks = [];
8221

    
8222
  return {
8223
    push: function(fn) {
8224
      _checks.push(fn);
8225
    },
8226

    
8227
    check: function() {
8228
      for (var check = 0; check < _checks.length; ++check) {
8229
        _checks[check]();
8230
      }
8231

    
8232
      _checks.splice(0, _checks.length);
8233
    }
8234
  };
8235
}
8236
function Lexer(source) {
8237
  var lines = source;
8238

    
8239
  if (typeof lines === "string") {
8240
    lines = lines
8241
      .replace(/\r\n/g, "\n")
8242
      .replace(/\r/g, "\n")
8243
      .split("\n");
8244
  }
8245

    
8246
  if (lines[0] && lines[0].substr(0, 2) === "#!") {
8247
    if (lines[0].indexOf("node") !== -1) {
8248
      state.option.node = true;
8249
    }
8250
    lines[0] = "";
8251
  }
8252

    
8253
  this.emitter = new events.EventEmitter();
8254
  this.source = source;
8255
  this.setLines(lines);
8256
  this.prereg = true;
8257

    
8258
  this.line = 0;
8259
  this.char = 1;
8260
  this.from = 1;
8261
  this.input = "";
8262
  this.inComment = false;
8263
  this.context = [];
8264
  this.templateStarts = [];
8265

    
8266
  for (var i = 0; i < state.option.indent; i += 1) {
8267
    state.tab += " ";
8268
  }
8269
  this.ignoreLinterErrors = false;
8270
}
8271

    
8272
Lexer.prototype = {
8273
  _lines: [],
8274

    
8275
  inContext: function(ctxType) {
8276
    return this.context.length > 0 && this.context[this.context.length - 1].type === ctxType;
8277
  },
8278

    
8279
  pushContext: function(ctxType) {
8280
    this.context.push({ type: ctxType });
8281
  },
8282

    
8283
  popContext: function() {
8284
    return this.context.pop();
8285
  },
8286

    
8287
  isContext: function(context) {
8288
    return this.context.length > 0 && this.context[this.context.length - 1] === context;
8289
  },
8290

    
8291
  currentContext: function() {
8292
    return this.context.length > 0 && this.context[this.context.length - 1];
8293
  },
8294

    
8295
  getLines: function() {
8296
    this._lines = state.lines;
8297
    return this._lines;
8298
  },
8299

    
8300
  setLines: function(val) {
8301
    this._lines = val;
8302
    state.lines = this._lines;
8303
  },
8304
  peek: function(i) {
8305
    return this.input.charAt(i || 0);
8306
  },
8307
  skip: function(i) {
8308
    i = i || 1;
8309
    this.char += i;
8310
    this.input = this.input.slice(i);
8311
  },
8312
  on: function(names, listener) {
8313
    names.split(" ").forEach(function(name) {
8314
      this.emitter.on(name, listener);
8315
    }.bind(this));
8316
  },
8317
  trigger: function() {
8318
    this.emitter.emit.apply(this.emitter, Array.prototype.slice.call(arguments));
8319
  },
8320
  triggerAsync: function(type, args, checks, fn) {
8321
    checks.push(function() {
8322
      if (fn()) {
8323
        this.trigger(type, args);
8324
      }
8325
    }.bind(this));
8326
  },
8327
  scanPunctuator: function() {
8328
    var ch1 = this.peek();
8329
    var ch2, ch3, ch4;
8330

    
8331
    switch (ch1) {
8332
    case ".":
8333
      if ((/^[0-9]$/).test(this.peek(1))) {
8334
        return null;
8335
      }
8336
      if (this.peek(1) === "." && this.peek(2) === ".") {
8337
        return {
8338
          type: Token.Punctuator,
8339
          value: "..."
8340
        };
8341
      }
8342
    case "(":
8343
    case ")":
8344
    case ";":
8345
    case ",":
8346
    case "[":
8347
    case "]":
8348
    case ":":
8349
    case "~":
8350
    case "?":
8351
      return {
8352
        type: Token.Punctuator,
8353
        value: ch1
8354
      };
8355
    case "{":
8356
      this.pushContext(Context.Block);
8357
      return {
8358
        type: Token.Punctuator,
8359
        value: ch1
8360
      };
8361
    case "}":
8362
      if (this.inContext(Context.Block)) {
8363
        this.popContext();
8364
      }
8365
      return {
8366
        type: Token.Punctuator,
8367
        value: ch1
8368
      };
8369
    case "#":
8370
      return {
8371
        type: Token.Punctuator,
8372
        value: ch1
8373
      };
8374
    case "":
8375
      return null;
8376
    }
8377

    
8378
    ch2 = this.peek(1);
8379
    ch3 = this.peek(2);
8380
    ch4 = this.peek(3);
8381

    
8382
    if (ch1 === ">" && ch2 === ">" && ch3 === ">" && ch4 === "=") {
8383
      return {
8384
        type: Token.Punctuator,
8385
        value: ">>>="
8386
      };
8387
    }
8388

    
8389
    if (ch1 === "=" && ch2 === "=" && ch3 === "=") {
8390
      return {
8391
        type: Token.Punctuator,
8392
        value: "==="
8393
      };
8394
    }
8395

    
8396
    if (ch1 === "!" && ch2 === "=" && ch3 === "=") {
8397
      return {
8398
        type: Token.Punctuator,
8399
        value: "!=="
8400
      };
8401
    }
8402

    
8403
    if (ch1 === ">" && ch2 === ">" && ch3 === ">") {
8404
      return {
8405
        type: Token.Punctuator,
8406
        value: ">>>"
8407
      };
8408
    }
8409

    
8410
    if (ch1 === "<" && ch2 === "<" && ch3 === "=") {
8411
      return {
8412
        type: Token.Punctuator,
8413
        value: "<<="
8414
      };
8415
    }
8416

    
8417
    if (ch1 === ">" && ch2 === ">" && ch3 === "=") {
8418
      return {
8419
        type: Token.Punctuator,
8420
        value: ">>="
8421
      };
8422
    }
8423
    if (ch1 === "=" && ch2 === ">") {
8424
      return {
8425
        type: Token.Punctuator,
8426
        value: ch1 + ch2
8427
      };
8428
    }
8429
    if (ch1 === ch2 && ("+-<>&|".indexOf(ch1) >= 0)) {
8430
      return {
8431
        type: Token.Punctuator,
8432
        value: ch1 + ch2
8433
      };
8434
    }
8435

    
8436
    if ("<>=!+-*%&|^".indexOf(ch1) >= 0) {
8437
      if (ch2 === "=") {
8438
        return {
8439
          type: Token.Punctuator,
8440
          value: ch1 + ch2
8441
        };
8442
      }
8443

    
8444
      return {
8445
        type: Token.Punctuator,
8446
        value: ch1
8447
      };
8448
    }
8449

    
8450
    if (ch1 === "/") {
8451
      if (ch2 === "=") {
8452
        return {
8453
          type: Token.Punctuator,
8454
          value: "/="
8455
        };
8456
      }
8457

    
8458
      return {
8459
        type: Token.Punctuator,
8460
        value: "/"
8461
      };
8462
    }
8463

    
8464
    return null;
8465
  },
8466
  scanComments: function() {
8467
    var ch1 = this.peek();
8468
    var ch2 = this.peek(1);
8469
    var rest = this.input.substr(2);
8470
    var startLine = this.line;
8471
    var startChar = this.char;
8472
    var self = this;
8473

    
8474
    function commentToken(label, body, opt) {
8475
      var special = ["jshint", "jslint", "members", "member", "globals", "global", "exported"];
8476
      var isSpecial = false;
8477
      var value = label + body;
8478
      var commentType = "plain";
8479
      opt = opt || {};
8480

    
8481
      if (opt.isMultiline) {
8482
        value += "*/";
8483
      }
8484

    
8485
      body = body.replace(/\n/g, " ");
8486

    
8487
      if (label === "/*" && reg.fallsThrough.test(body)) {
8488
        isSpecial = true;
8489
        commentType = "falls through";
8490
      }
8491

    
8492
      special.forEach(function(str) {
8493
        if (isSpecial) {
8494
          return;
8495
        }
8496
        if (label === "//" && str !== "jshint") {
8497
          return;
8498
        }
8499

    
8500
        if (body.charAt(str.length) === " " && body.substr(0, str.length) === str) {
8501
          isSpecial = true;
8502
          label = label + str;
8503
          body = body.substr(str.length);
8504
        }
8505

    
8506
        if (!isSpecial && body.charAt(0) === " " && body.charAt(str.length + 1) === " " &&
8507
          body.substr(1, str.length) === str) {
8508
          isSpecial = true;
8509
          label = label + " " + str;
8510
          body = body.substr(str.length + 1);
8511
        }
8512

    
8513
        if (!isSpecial) {
8514
          return;
8515
        }
8516

    
8517
        switch (str) {
8518
        case "member":
8519
          commentType = "members";
8520
          break;
8521
        case "global":
8522
          commentType = "globals";
8523
          break;
8524
        default:
8525
          var options = body.split(":").map(function(v) {
8526
            return v.replace(/^\s+/, "").replace(/\s+$/, "");
8527
          });
8528

    
8529
          if (options.length === 2) {
8530
            switch (options[0]) {
8531
            case "ignore":
8532
              switch (options[1]) {
8533
              case "start":
8534
                self.ignoringLinterErrors = true;
8535
                isSpecial = false;
8536
                break;
8537
              case "end":
8538
                self.ignoringLinterErrors = false;
8539
                isSpecial = false;
8540
                break;
8541
              }
8542
            }
8543
          }
8544

    
8545
          commentType = str;
8546
        }
8547
      });
8548

    
8549
      return {
8550
        type: Token.Comment,
8551
        commentType: commentType,
8552
        value: value,
8553
        body: body,
8554
        isSpecial: isSpecial,
8555
        isMultiline: opt.isMultiline || false,
8556
        isMalformed: opt.isMalformed || false
8557
      };
8558
    }
8559
    if (ch1 === "*" && ch2 === "/") {
8560
      this.trigger("error", {
8561
        code: "E018",
8562
        line: startLine,
8563
        character: startChar
8564
      });
8565

    
8566
      this.skip(2);
8567
      return null;
8568
    }
8569
    if (ch1 !== "/" || (ch2 !== "*" && ch2 !== "/")) {
8570
      return null;
8571
    }
8572
    if (ch2 === "/") {
8573
      this.skip(this.input.length); // Skip to the EOL.
8574
      return commentToken("//", rest);
8575
    }
8576

    
8577
    var body = "";
8578
    if (ch2 === "*") {
8579
      this.inComment = true;
8580
      this.skip(2);
8581

    
8582
      while (this.peek() !== "*" || this.peek(1) !== "/") {
8583
        if (this.peek() === "") { // End of Line
8584
          body += "\n";
8585
          if (!this.nextLine()) {
8586
            this.trigger("error", {
8587
              code: "E017",
8588
              line: startLine,
8589
              character: startChar
8590
            });
8591

    
8592
            this.inComment = false;
8593
            return commentToken("/*", body, {
8594
              isMultiline: true,
8595
              isMalformed: true
8596
            });
8597
          }
8598
        } else {
8599
          body += this.peek();
8600
          this.skip();
8601
        }
8602
      }
8603

    
8604
      this.skip(2);
8605
      this.inComment = false;
8606
      return commentToken("/*", body, { isMultiline: true });
8607
    }
8608
  },
8609
  scanKeyword: function() {
8610
    var result = /^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(this.input);
8611
    var keywords = [
8612
      "if", "in", "do", "var", "for", "new",
8613
      "try", "let", "this", "else", "case",
8614
      "void", "with", "enum", "while", "break",
8615
      "catch", "throw", "const", "yield", "class",
8616
      "super", "return", "typeof", "delete",
8617
      "switch", "export", "import", "default",
8618
      "finally", "extends", "function", "continue",
8619
      "debugger", "instanceof"
8620
    ];
8621

    
8622
    if (result && keywords.indexOf(result[0]) >= 0) {
8623
      return {
8624
        type: Token.Keyword,
8625
        value: result[0]
8626
      };
8627
    }
8628

    
8629
    return null;
8630
  },
8631
  scanIdentifier: function() {
8632
    var id = "";
8633
    var index = 0;
8634
    var type, char;
8635

    
8636
    function isNonAsciiIdentifierStart(code) {
8637
      return code > 256;
8638
    }
8639

    
8640
    function isNonAsciiIdentifierPart(code) {
8641
      return code > 256;
8642
    }
8643

    
8644
    function isHexDigit(str) {
8645
      return (/^[0-9a-fA-F]$/).test(str);
8646
    }
8647

    
8648
    var readUnicodeEscapeSequence = function() {
8649
      index += 1;
8650

    
8651
      if (this.peek(index) !== "u") {
8652
        return null;
8653
      }
8654

    
8655
      var ch1 = this.peek(index + 1);
8656
      var ch2 = this.peek(index + 2);
8657
      var ch3 = this.peek(index + 3);
8658
      var ch4 = this.peek(index + 4);
8659
      var code;
8660

    
8661
      if (isHexDigit(ch1) && isHexDigit(ch2) && isHexDigit(ch3) && isHexDigit(ch4)) {
8662
        code = parseInt(ch1 + ch2 + ch3 + ch4, 16);
8663

    
8664
        if (asciiIdentifierPartTable[code] || isNonAsciiIdentifierPart(code)) {
8665
          index += 5;
8666
          return "\\u" + ch1 + ch2 + ch3 + ch4;
8667
        }
8668

    
8669
        return null;
8670
      }
8671

    
8672
      return null;
8673
    }.bind(this);
8674

    
8675
    var getIdentifierStart = function() {
8676
      var chr = this.peek(index);
8677
      var code = chr.charCodeAt(0);
8678

    
8679
      if (code === 92) {
8680
        return readUnicodeEscapeSequence();
8681
      }
8682

    
8683
      if (code < 128) {
8684
        if (asciiIdentifierStartTable[code]) {
8685
          index += 1;
8686
          return chr;
8687
        }
8688

    
8689
        return null;
8690
      }
8691

    
8692
      if (isNonAsciiIdentifierStart(code)) {
8693
        index += 1;
8694
        return chr;
8695
      }
8696

    
8697
      return null;
8698
    }.bind(this);
8699

    
8700
    var getIdentifierPart = function() {
8701
      var chr = this.peek(index);
8702
      var code = chr.charCodeAt(0);
8703

    
8704
      if (code === 92) {
8705
        return readUnicodeEscapeSequence();
8706
      }
8707

    
8708
      if (code < 128) {
8709
        if (asciiIdentifierPartTable[code]) {
8710
          index += 1;
8711
          return chr;
8712
        }
8713

    
8714
        return null;
8715
      }
8716

    
8717
      if (isNonAsciiIdentifierPart(code)) {
8718
        index += 1;
8719
        return chr;
8720
      }
8721

    
8722
      return null;
8723
    }.bind(this);
8724

    
8725
    function removeEscapeSequences(id) {
8726
      return id.replace(/\\u([0-9a-fA-F]{4})/g, function(m0, codepoint) {
8727
        return String.fromCharCode(parseInt(codepoint, 16));
8728
      });
8729
    }
8730

    
8731
    char = getIdentifierStart();
8732
    if (char === null) {
8733
      return null;
8734
    }
8735

    
8736
    id = char;
8737
    for (;;) {
8738
      char = getIdentifierPart();
8739

    
8740
      if (char === null) {
8741
        break;
8742
      }
8743

    
8744
      id += char;
8745
    }
8746

    
8747
    switch (id) {
8748
    case "true":
8749
    case "false":
8750
      type = Token.BooleanLiteral;
8751
      break;
8752
    case "null":
8753
      type = Token.NullLiteral;
8754
      break;
8755
    default:
8756
      type = Token.Identifier;
8757
    }
8758

    
8759
    return {
8760
      type: type,
8761
      value: removeEscapeSequences(id),
8762
      text: id,
8763
      tokenLength: id.length
8764
    };
8765
  },
8766
  scanNumericLiteral: function() {
8767
    var index = 0;
8768
    var value = "";
8769
    var length = this.input.length;
8770
    var char = this.peek(index);
8771
    var bad;
8772
    var isAllowedDigit = isDecimalDigit;
8773
    var base = 10;
8774
    var isLegacy = false;
8775

    
8776
    function isDecimalDigit(str) {
8777
      return (/^[0-9]$/).test(str);
8778
    }
8779

    
8780
    function isOctalDigit(str) {
8781
      return (/^[0-7]$/).test(str);
8782
    }
8783

    
8784
    function isBinaryDigit(str) {
8785
      return (/^[01]$/).test(str);
8786
    }
8787

    
8788
    function isHexDigit(str) {
8789
      return (/^[0-9a-fA-F]$/).test(str);
8790
    }
8791

    
8792
    function isIdentifierStart(ch) {
8793
      return (ch === "$") || (ch === "_") || (ch === "\\") ||
8794
        (ch >= "a" && ch <= "z") || (ch >= "A" && ch <= "Z");
8795
    }
8796

    
8797
    if (char !== "." && !isDecimalDigit(char)) {
8798
      return null;
8799
    }
8800

    
8801
    if (char !== ".") {
8802
      value = this.peek(index);
8803
      index += 1;
8804
      char = this.peek(index);
8805

    
8806
      if (value === "0") {
8807
        if (char === "x" || char === "X") {
8808
          isAllowedDigit = isHexDigit;
8809
          base = 16;
8810

    
8811
          index += 1;
8812
          value += char;
8813
        }
8814
        if (char === "o" || char === "O") {
8815
          isAllowedDigit = isOctalDigit;
8816
          base = 8;
8817

    
8818
          if (!state.inES6(true)) {
8819
            this.trigger("warning", {
8820
              code: "W119",
8821
              line: this.line,
8822
              character: this.char,
8823
              data: [ "Octal integer literal", "6" ]
8824
            });
8825
          }
8826

    
8827
          index += 1;
8828
          value += char;
8829
        }
8830
        if (char === "b" || char === "B") {
8831
          isAllowedDigit = isBinaryDigit;
8832
          base = 2;
8833

    
8834
          if (!state.inES6(true)) {
8835
            this.trigger("warning", {
8836
              code: "W119",
8837
              line: this.line,
8838
              character: this.char,
8839
              data: [ "Binary integer literal", "6" ]
8840
            });
8841
          }
8842

    
8843
          index += 1;
8844
          value += char;
8845
        }
8846
        if (isOctalDigit(char)) {
8847
          isAllowedDigit = isOctalDigit;
8848
          base = 8;
8849
          isLegacy = true;
8850
          bad = false;
8851

    
8852
          index += 1;
8853
          value += char;
8854
        }
8855

    
8856
        if (!isOctalDigit(char) && isDecimalDigit(char)) {
8857
          index += 1;
8858
          value += char;
8859
        }
8860
      }
8861

    
8862
      while (index < length) {
8863
        char = this.peek(index);
8864

    
8865
        if (isLegacy && isDecimalDigit(char)) {
8866
          bad = true;
8867
        } else if (!isAllowedDigit(char)) {
8868
          break;
8869
        }
8870
        value += char;
8871
        index += 1;
8872
      }
8873

    
8874
      if (isAllowedDigit !== isDecimalDigit) {
8875
        if (!isLegacy && value.length <= 2) { // 0x
8876
          return {
8877
            type: Token.NumericLiteral,
8878
            value: value,
8879
            isMalformed: true
8880
          };
8881
        }
8882

    
8883
        if (index < length) {
8884
          char = this.peek(index);
8885
          if (isIdentifierStart(char)) {
8886
            return null;
8887
          }
8888
        }
8889

    
8890
        return {
8891
          type: Token.NumericLiteral,
8892
          value: value,
8893
          base: base,
8894
          isLegacy: isLegacy,
8895
          isMalformed: false
8896
        };
8897
      }
8898
    }
8899

    
8900
    if (char === ".") {
8901
      value += char;
8902
      index += 1;
8903

    
8904
      while (index < length) {
8905
        char = this.peek(index);
8906
        if (!isDecimalDigit(char)) {
8907
          break;
8908
        }
8909
        value += char;
8910
        index += 1;
8911
      }
8912
    }
8913

    
8914
    if (char === "e" || char === "E") {
8915
      value += char;
8916
      index += 1;
8917
      char = this.peek(index);
8918

    
8919
      if (char === "+" || char === "-") {
8920
        value += this.peek(index);
8921
        index += 1;
8922
      }
8923

    
8924
      char = this.peek(index);
8925
      if (isDecimalDigit(char)) {
8926
        value += char;
8927
        index += 1;
8928

    
8929
        while (index < length) {
8930
          char = this.peek(index);
8931
          if (!isDecimalDigit(char)) {
8932
            break;
8933
          }
8934
          value += char;
8935
          index += 1;
8936
        }
8937
      } else {
8938
        return null;
8939
      }
8940
    }
8941

    
8942
    if (index < length) {
8943
      char = this.peek(index);
8944
      if (isIdentifierStart(char)) {
8945
        return null;
8946
      }
8947
    }
8948

    
8949
    return {
8950
      type: Token.NumericLiteral,
8951
      value: value,
8952
      base: base,
8953
      isMalformed: !isFinite(value)
8954
    };
8955
  },
8956
  scanEscapeSequence: function(checks) {
8957
    var allowNewLine = false;
8958
    var jump = 1;
8959
    this.skip();
8960
    var char = this.peek();
8961

    
8962
    switch (char) {
8963
    case "'":
8964
      this.triggerAsync("warning", {
8965
        code: "W114",
8966
        line: this.line,
8967
        character: this.char,
8968
        data: [ "\\'" ]
8969
      }, checks, function() {return state.jsonMode; });
8970
      break;
8971
    case "b":
8972
      char = "\\b";
8973
      break;
8974
    case "f":
8975
      char = "\\f";
8976
      break;
8977
    case "n":
8978
      char = "\\n";
8979
      break;
8980
    case "r":
8981
      char = "\\r";
8982
      break;
8983
    case "t":
8984
      char = "\\t";
8985
      break;
8986
    case "0":
8987
      char = "\\0";
8988
      var n = parseInt(this.peek(1), 10);
8989
      this.triggerAsync("warning", {
8990
        code: "W115",
8991
        line: this.line,
8992
        character: this.char
8993
      }, checks,
8994
      function() { return n >= 0 && n <= 7 && state.isStrict(); });
8995
      break;
8996
    case "u":
8997
      var hexCode = this.input.substr(1, 4);
8998
      var code = parseInt(hexCode, 16);
8999
      if (isNaN(code)) {
9000
        this.trigger("warning", {
9001
          code: "W052",
9002
          line: this.line,
9003
          character: this.char,
9004
          data: [ "u" + hexCode ]
9005
        });
9006
      }
9007
      char = String.fromCharCode(code);
9008
      jump = 5;
9009
      break;
9010
    case "v":
9011
      this.triggerAsync("warning", {
9012
        code: "W114",
9013
        line: this.line,
9014
        character: this.char,
9015
        data: [ "\\v" ]
9016
      }, checks, function() { return state.jsonMode; });
9017

    
9018
      char = "\v";
9019
      break;
9020
    case "x":
9021
      var  x = parseInt(this.input.substr(1, 2), 16);
9022

    
9023
      this.triggerAsync("warning", {
9024
        code: "W114",
9025
        line: this.line,
9026
        character: this.char,
9027
        data: [ "\\x-" ]
9028
      }, checks, function() { return state.jsonMode; });
9029

    
9030
      char = String.fromCharCode(x);
9031
      jump = 3;
9032
      break;
9033
    case "\\":
9034
      char = "\\\\";
9035
      break;
9036
    case "\"":
9037
      char = "\\\"";
9038
      break;
9039
    case "/":
9040
      break;
9041
    case "":
9042
      allowNewLine = true;
9043
      char = "";
9044
      break;
9045
    }
9046

    
9047
    return { char: char, jump: jump, allowNewLine: allowNewLine };
9048
  },
9049
  scanTemplateLiteral: function(checks) {
9050
    var tokenType;
9051
    var value = "";
9052
    var ch;
9053
    var startLine = this.line;
9054
    var startChar = this.char;
9055
    var depth = this.templateStarts.length;
9056

    
9057
    if (!state.inES6(true)) {
9058
      return null;
9059
    } else if (this.peek() === "`") {
9060
      tokenType = Token.TemplateHead;
9061
      this.templateStarts.push({ line: this.line, char: this.char });
9062
      depth = this.templateStarts.length;
9063
      this.skip(1);
9064
      this.pushContext(Context.Template);
9065
    } else if (this.inContext(Context.Template) && this.peek() === "}") {
9066
      tokenType = Token.TemplateMiddle;
9067
    } else {
9068
      return null;
9069
    }
9070

    
9071
    while (this.peek() !== "`") {
9072
      while ((ch = this.peek()) === "") {
9073
        value += "\n";
9074
        if (!this.nextLine()) {
9075
          var startPos = this.templateStarts.pop();
9076
          this.trigger("error", {
9077
            code: "E052",
9078
            line: startPos.line,
9079
            character: startPos.char
9080
          });
9081
          return {
9082
            type: tokenType,
9083
            value: value,
9084
            startLine: startLine,
9085
            startChar: startChar,
9086
            isUnclosed: true,
9087
            depth: depth,
9088
            context: this.popContext()
9089
          };
9090
        }
9091
      }
9092

    
9093
      if (ch === '$' && this.peek(1) === '{') {
9094
        value += '${';
9095
        this.skip(2);
9096
        return {
9097
          type: tokenType,
9098
          value: value,
9099
          startLine: startLine,
9100
          startChar: startChar,
9101
          isUnclosed: false,
9102
          depth: depth,
9103
          context: this.currentContext()
9104
        };
9105
      } else if (ch === '\\') {
9106
        var escape = this.scanEscapeSequence(checks);
9107
        value += escape.char;
9108
        this.skip(escape.jump);
9109
      } else if (ch !== '`') {
9110
        value += ch;
9111
        this.skip(1);
9112
      }
9113
    }
9114
    tokenType = tokenType === Token.TemplateHead ? Token.NoSubstTemplate : Token.TemplateTail;
9115
    this.skip(1);
9116
    this.templateStarts.pop();
9117

    
9118
    return {
9119
      type: tokenType,
9120
      value: value,
9121
      startLine: startLine,
9122
      startChar: startChar,
9123
      isUnclosed: false,
9124
      depth: depth,
9125
      context: this.popContext()
9126
    };
9127
  },
9128
  scanStringLiteral: function(checks) {
9129
    var quote = this.peek();
9130
    if (quote !== "\"" && quote !== "'") {
9131
      return null;
9132
    }
9133
    this.triggerAsync("warning", {
9134
      code: "W108",
9135
      line: this.line,
9136
      character: this.char // +1?
9137
    }, checks, function() { return state.jsonMode && quote !== "\""; });
9138

    
9139
    var value = "";
9140
    var startLine = this.line;
9141
    var startChar = this.char;
9142
    var allowNewLine = false;
9143

    
9144
    this.skip();
9145

    
9146
    while (this.peek() !== quote) {
9147
      if (this.peek() === "") { // End Of Line
9148

    
9149
        if (!allowNewLine) {
9150
          this.trigger("warning", {
9151
            code: "W112",
9152
            line: this.line,
9153
            character: this.char
9154
          });
9155
        } else {
9156
          allowNewLine = false;
9157

    
9158
          this.triggerAsync("warning", {
9159
            code: "W043",
9160
            line: this.line,
9161
            character: this.char
9162
          }, checks, function() { return !state.option.multistr; });
9163

    
9164
          this.triggerAsync("warning", {
9165
            code: "W042",
9166
            line: this.line,
9167
            character: this.char
9168
          }, checks, function() { return state.jsonMode && state.option.multistr; });
9169
        }
9170

    
9171
        if (!this.nextLine()) {
9172
          this.trigger("error", {
9173
            code: "E029",
9174
            line: startLine,
9175
            character: startChar
9176
          });
9177

    
9178
          return {
9179
            type: Token.StringLiteral,
9180
            value: value,
9181
            startLine: startLine,
9182
            startChar: startChar,
9183
            isUnclosed: true,
9184
            quote: quote
9185
          };
9186
        }
9187

    
9188
      } else { // Any character other than End Of Line
9189

    
9190
        allowNewLine = false;
9191
        var char = this.peek();
9192
        var jump = 1; // A length of a jump, after we're done
9193

    
9194
        if (char < " ") {
9195
          this.trigger("warning", {
9196
            code: "W113",
9197
            line: this.line,
9198
            character: this.char,
9199
            data: [ "<non-printable>" ]
9200
          });
9201
        }
9202
        if (char === "\\") {
9203
          var parsed = this.scanEscapeSequence(checks);
9204
          char = parsed.char;
9205
          jump = parsed.jump;
9206
          allowNewLine = parsed.allowNewLine;
9207
        }
9208

    
9209
        value += char;
9210
        this.skip(jump);
9211
      }
9212
    }
9213

    
9214
    this.skip();
9215
    return {
9216
      type: Token.StringLiteral,
9217
      value: value,
9218
      startLine: startLine,
9219
      startChar: startChar,
9220
      isUnclosed: false,
9221
      quote: quote
9222
    };
9223
  },
9224
  scanRegExp: function() {
9225
    var index = 0;
9226
    var length = this.input.length;
9227
    var char = this.peek();
9228
    var value = char;
9229
    var body = "";
9230
    var flags = [];
9231
    var malformed = false;
9232
    var isCharSet = false;
9233
    var terminated;
9234

    
9235
    var scanUnexpectedChars = function() {
9236
      if (char < " ") {
9237
        malformed = true;
9238
        this.trigger("warning", {
9239
          code: "W048",
9240
          line: this.line,
9241
          character: this.char
9242
        });
9243
      }
9244
      if (char === "<") {
9245
        malformed = true;
9246
        this.trigger("warning", {
9247
          code: "W049",
9248
          line: this.line,
9249
          character: this.char,
9250
          data: [ char ]
9251
        });
9252
      }
9253
    }.bind(this);
9254
    if (!this.prereg || char !== "/") {
9255
      return null;
9256
    }
9257

    
9258
    index += 1;
9259
    terminated = false;
9260

    
9261
    while (index < length) {
9262
      char = this.peek(index);
9263
      value += char;
9264
      body += char;
9265

    
9266
      if (isCharSet) {
9267
        if (char === "]") {
9268
          if (this.peek(index - 1) !== "\\" || this.peek(index - 2) === "\\") {
9269
            isCharSet = false;
9270
          }
9271
        }
9272

    
9273
        if (char === "\\") {
9274
          index += 1;
9275
          char = this.peek(index);
9276
          body += char;
9277
          value += char;
9278

    
9279
          scanUnexpectedChars();
9280
        }
9281

    
9282
        index += 1;
9283
        continue;
9284
      }
9285

    
9286
      if (char === "\\") {
9287
        index += 1;
9288
        char = this.peek(index);
9289
        body += char;
9290
        value += char;
9291

    
9292
        scanUnexpectedChars();
9293

    
9294
        if (char === "/") {
9295
          index += 1;
9296
          continue;
9297
        }
9298

    
9299
        if (char === "[") {
9300
          index += 1;
9301
          continue;
9302
        }
9303
      }
9304

    
9305
      if (char === "[") {
9306
        isCharSet = true;
9307
        index += 1;
9308
        continue;
9309
      }
9310

    
9311
      if (char === "/") {
9312
        body = body.substr(0, body.length - 1);
9313
        terminated = true;
9314
        index += 1;
9315
        break;
9316
      }
9317

    
9318
      index += 1;
9319
    }
9320

    
9321
    if (!terminated) {
9322
      this.trigger("error", {
9323
        code: "E015",
9324
        line: this.line,
9325
        character: this.from
9326
      });
9327

    
9328
      return void this.trigger("fatal", {
9329
        line: this.line,
9330
        from: this.from
9331
      });
9332
    }
9333

    
9334
    while (index < length) {
9335
      char = this.peek(index);
9336
      if (!/[gim]/.test(char)) {
9337
        break;
9338
      }
9339
      flags.push(char);
9340
      value += char;
9341
      index += 1;
9342
    }
9343

    
9344
    try {
9345
      new RegExp(body, flags.join(""));
9346
    } catch (err) {
9347
      malformed = true;
9348
      this.trigger("error", {
9349
        code: "E016",
9350
        line: this.line,
9351
        character: this.char,
9352
        data: [ err.message ] // Platform dependent!
9353
      });
9354
    }
9355

    
9356
    return {
9357
      type: Token.RegExp,
9358
      value: value,
9359
      flags: flags,
9360
      isMalformed: malformed
9361
    };
9362
  },
9363
  scanNonBreakingSpaces: function() {
9364
    return state.option.nonbsp ?
9365
      this.input.search(/(\u00A0)/) : -1;
9366
  },
9367
  scanUnsafeChars: function() {
9368
    return this.input.search(reg.unsafeChars);
9369
  },
9370
  next: function(checks) {
9371
    this.from = this.char;
9372
    var start;
9373
    if (/\s/.test(this.peek())) {
9374
      start = this.char;
9375

    
9376
      while (/\s/.test(this.peek())) {
9377
        this.from += 1;
9378
        this.skip();
9379
      }
9380
    }
9381

    
9382
    var match = this.scanComments() ||
9383
      this.scanStringLiteral(checks) ||
9384
      this.scanTemplateLiteral(checks);
9385

    
9386
    if (match) {
9387
      return match;
9388
    }
9389

    
9390
    match =
9391
      this.scanRegExp() ||
9392
      this.scanPunctuator() ||
9393
      this.scanKeyword() ||
9394
      this.scanIdentifier() ||
9395
      this.scanNumericLiteral();
9396

    
9397
    if (match) {
9398
      this.skip(match.tokenLength || match.value.length);
9399
      return match;
9400
    }
9401

    
9402
    return null;
9403
  },
9404
  nextLine: function() {
9405
    var char;
9406

    
9407
    if (this.line >= this.getLines().length) {
9408
      return false;
9409
    }
9410

    
9411
    this.input = this.getLines()[this.line];
9412
    this.line += 1;
9413
    this.char = 1;
9414
    this.from = 1;
9415

    
9416
    var inputTrimmed = this.input.trim();
9417

    
9418
    var startsWith = function() {
9419
      return _.some(arguments, function(prefix) {
9420
        return inputTrimmed.indexOf(prefix) === 0;
9421
      });
9422
    };
9423

    
9424
    var endsWith = function() {
9425
      return _.some(arguments, function(suffix) {
9426
        return inputTrimmed.indexOf(suffix, inputTrimmed.length - suffix.length) !== -1;
9427
      });
9428
    };
9429
    if (this.ignoringLinterErrors === true) {
9430
      if (!startsWith("/*", "//") && !(this.inComment && endsWith("*/"))) {
9431
        this.input = "";
9432
      }
9433
    }
9434

    
9435
    char = this.scanNonBreakingSpaces();
9436
    if (char >= 0) {
9437
      this.trigger("warning", { code: "W125", line: this.line, character: char + 1 });
9438
    }
9439

    
9440
    this.input = this.input.replace(/\t/g, state.tab);
9441
    char = this.scanUnsafeChars();
9442

    
9443
    if (char >= 0) {
9444
      this.trigger("warning", { code: "W100", line: this.line, character: char });
9445
    }
9446

    
9447
    if (!this.ignoringLinterErrors && state.option.maxlen &&
9448
      state.option.maxlen < this.input.length) {
9449
      var inComment = this.inComment ||
9450
        startsWith.call(inputTrimmed, "//") ||
9451
        startsWith.call(inputTrimmed, "/*");
9452

    
9453
      var shouldTriggerError = !inComment || !reg.maxlenException.test(inputTrimmed);
9454

    
9455
      if (shouldTriggerError) {
9456
        this.trigger("warning", { code: "W101", line: this.line, character: this.input.length });
9457
      }
9458
    }
9459

    
9460
    return true;
9461
  },
9462
  start: function() {
9463
    this.nextLine();
9464
  },
9465
  token: function() {
9466
    var checks = asyncTrigger();
9467
    var token;
9468

    
9469

    
9470
    function isReserved(token, isProperty) {
9471
      if (!token.reserved) {
9472
        return false;
9473
      }
9474
      var meta = token.meta;
9475

    
9476
      if (meta && meta.isFutureReservedWord && state.inES5()) {
9477
        if (!meta.es5) {
9478
          return false;
9479
        }
9480
        if (meta.strictOnly) {
9481
          if (!state.option.strict && !state.isStrict()) {
9482
            return false;
9483
          }
9484
        }
9485

    
9486
        if (isProperty) {
9487
          return false;
9488
        }
9489
      }
9490

    
9491
      return true;
9492
    }
9493
    var create = function(type, value, isProperty, token) {
9494
      var obj;
9495

    
9496
      if (type !== "(endline)" && type !== "(end)") {
9497
        this.prereg = false;
9498
      }
9499

    
9500
      if (type === "(punctuator)") {
9501
        switch (value) {
9502
        case ".":
9503
        case ")":
9504
        case "~":
9505
        case "#":
9506
        case "]":
9507
        case "++":
9508
        case "--":
9509
          this.prereg = false;
9510
          break;
9511
        default:
9512
          this.prereg = true;
9513
        }
9514

    
9515
        obj = Object.create(state.syntax[value] || state.syntax["(error)"]);
9516
      }
9517

    
9518
      if (type === "(identifier)") {
9519
        if (value === "return" || value === "case" || value === "typeof") {
9520
          this.prereg = true;
9521
        }
9522

    
9523
        if (_.has(state.syntax, value)) {
9524
          obj = Object.create(state.syntax[value] || state.syntax["(error)"]);
9525
          if (!isReserved(obj, isProperty && type === "(identifier)")) {
9526
            obj = null;
9527
          }
9528
        }
9529
      }
9530

    
9531
      if (!obj) {
9532
        obj = Object.create(state.syntax[type]);
9533
      }
9534

    
9535
      obj.identifier = (type === "(identifier)");
9536
      obj.type = obj.type || type;
9537
      obj.value = value;
9538
      obj.line = this.line;
9539
      obj.character = this.char;
9540
      obj.from = this.from;
9541
      if (obj.identifier && token) obj.raw_text = token.text || token.value;
9542
      if (token && token.startLine && token.startLine !== this.line) {
9543
        obj.startLine = token.startLine;
9544
      }
9545
      if (token && token.context) {
9546
        obj.context = token.context;
9547
      }
9548
      if (token && token.depth) {
9549
        obj.depth = token.depth;
9550
      }
9551
      if (token && token.isUnclosed) {
9552
        obj.isUnclosed = token.isUnclosed;
9553
      }
9554

    
9555
      if (isProperty && obj.identifier) {
9556
        obj.isProperty = isProperty;
9557
      }
9558

    
9559
      obj.check = checks.check;
9560

    
9561
      return obj;
9562
    }.bind(this);
9563

    
9564
    for (;;) {
9565
      if (!this.input.length) {
9566
        if (this.nextLine()) {
9567
          return create("(endline)", "");
9568
        }
9569

    
9570
        if (this.exhausted) {
9571
          return null;
9572
        }
9573

    
9574
        this.exhausted = true;
9575
        return create("(end)", "");
9576
      }
9577

    
9578
      token = this.next(checks);
9579

    
9580
      if (!token) {
9581
        if (this.input.length) {
9582
          this.trigger("error", {
9583
            code: "E024",
9584
            line: this.line,
9585
            character: this.char,
9586
            data: [ this.peek() ]
9587
          });
9588

    
9589
          this.input = "";
9590
        }
9591

    
9592
        continue;
9593
      }
9594

    
9595
      switch (token.type) {
9596
      case Token.StringLiteral:
9597
        this.triggerAsync("String", {
9598
          line: this.line,
9599
          char: this.char,
9600
          from: this.from,
9601
          startLine: token.startLine,
9602
          startChar: token.startChar,
9603
          value: token.value,
9604
          quote: token.quote
9605
        }, checks, function() { return true; });
9606

    
9607
        return create("(string)", token.value, null, token);
9608

    
9609
      case Token.TemplateHead:
9610
        this.trigger("TemplateHead", {
9611
          line: this.line,
9612
          char: this.char,
9613
          from: this.from,
9614
          startLine: token.startLine,
9615
          startChar: token.startChar,
9616
          value: token.value
9617
        });
9618
        return create("(template)", token.value, null, token);
9619

    
9620
      case Token.TemplateMiddle:
9621
        this.trigger("TemplateMiddle", {
9622
          line: this.line,
9623
          char: this.char,
9624
          from: this.from,
9625
          startLine: token.startLine,
9626
          startChar: token.startChar,
9627
          value: token.value
9628
        });
9629
        return create("(template middle)", token.value, null, token);
9630

    
9631
      case Token.TemplateTail:
9632
        this.trigger("TemplateTail", {
9633
          line: this.line,
9634
          char: this.char,
9635
          from: this.from,
9636
          startLine: token.startLine,
9637
          startChar: token.startChar,
9638
          value: token.value
9639
        });
9640
        return create("(template tail)", token.value, null, token);
9641

    
9642
      case Token.NoSubstTemplate:
9643
        this.trigger("NoSubstTemplate", {
9644
          line: this.line,
9645
          char: this.char,
9646
          from: this.from,
9647
          startLine: token.startLine,
9648
          startChar: token.startChar,
9649
          value: token.value
9650
        });
9651
        return create("(no subst template)", token.value, null, token);
9652

    
9653
      case Token.Identifier:
9654
        this.triggerAsync("Identifier", {
9655
          line: this.line,
9656
          char: this.char,
9657
          from: this.form,
9658
          name: token.value,
9659
          raw_name: token.text,
9660
          isProperty: state.tokens.curr.id === "."
9661
        }, checks, function() { return true; });
9662
      case Token.Keyword:
9663
      case Token.NullLiteral:
9664
      case Token.BooleanLiteral:
9665
        return create("(identifier)", token.value, state.tokens.curr.id === ".", token);
9666

    
9667
      case Token.NumericLiteral:
9668
        if (token.isMalformed) {
9669
          this.trigger("warning", {
9670
            code: "W045",
9671
            line: this.line,
9672
            character: this.char,
9673
            data: [ token.value ]
9674
          });
9675
        }
9676

    
9677
        this.triggerAsync("warning", {
9678
          code: "W114",
9679
          line: this.line,
9680
          character: this.char,
9681
          data: [ "0x-" ]
9682
        }, checks, function() { return token.base === 16 && state.jsonMode; });
9683

    
9684
        this.triggerAsync("warning", {
9685
          code: "W115",
9686
          line: this.line,
9687
          character: this.char
9688
        }, checks, function() {
9689
          return state.isStrict() && token.base === 8 && token.isLegacy;
9690
        });
9691

    
9692
        this.trigger("Number", {
9693
          line: this.line,
9694
          char: this.char,
9695
          from: this.from,
9696
          value: token.value,
9697
          base: token.base,
9698
          isMalformed: token.malformed
9699
        });
9700

    
9701
        return create("(number)", token.value);
9702

    
9703
      case Token.RegExp:
9704
        return create("(regexp)", token.value);
9705

    
9706
      case Token.Comment:
9707
        state.tokens.curr.comment = true;
9708

    
9709
        if (token.isSpecial) {
9710
          return {
9711
            id: '(comment)',
9712
            value: token.value,
9713
            body: token.body,
9714
            type: token.commentType,
9715
            isSpecial: token.isSpecial,
9716
            line: this.line,
9717
            character: this.char,
9718
            from: this.from
9719
          };
9720
        }
9721

    
9722
        break;
9723

    
9724
      case "":
9725
        break;
9726

    
9727
      default:
9728
        return create("(punctuator)", token.value);
9729
      }
9730
    }
9731
  }
9732
};
9733

    
9734
exports.Lexer = Lexer;
9735
exports.Context = Context;
9736

    
9737
},{"../data/ascii-identifier-data.js":"/node_modules/jshint/data/ascii-identifier-data.js","../lodash":"/node_modules/jshint/lodash.js","./reg.js":"/node_modules/jshint/src/reg.js","./state.js":"/node_modules/jshint/src/state.js","events":"/node_modules/browserify/node_modules/events/events.js"}],"/node_modules/jshint/src/messages.js":[function(_dereq_,module,exports){
9738
"use strict";
9739

    
9740
var _ = _dereq_("../lodash");
9741

    
9742
var errors = {
9743
  E001: "Bad option: '{a}'.",
9744
  E002: "Bad option value.",
9745
  E003: "Expected a JSON value.",
9746
  E004: "Input is neither a string nor an array of strings.",
9747
  E005: "Input is empty.",
9748
  E006: "Unexpected early end of program.",
9749
  E007: "Missing \"use strict\" statement.",
9750
  E008: "Strict violation.",
9751
  E009: "Option 'validthis' can't be used in a global scope.",
9752
  E010: "'with' is not allowed in strict mode.",
9753
  E011: "'{a}' has already been declared.",
9754
  E012: "const '{a}' is initialized to 'undefined'.",
9755
  E013: "Attempting to override '{a}' which is a constant.",
9756
  E014: "A regular expression literal can be confused with '/='.",
9757
  E015: "Unclosed regular expression.",
9758
  E016: "Invalid regular expression.",
9759
  E017: "Unclosed comment.",
9760
  E018: "Unbegun comment.",
9761
  E019: "Unmatched '{a}'.",
9762
  E020: "Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
9763
  E021: "Expected '{a}' and instead saw '{b}'.",
9764
  E022: "Line breaking error '{a}'.",
9765
  E023: "Missing '{a}'.",
9766
  E024: "Unexpected '{a}'.",
9767
  E025: "Missing ':' on a case clause.",
9768
  E026: "Missing '}' to match '{' from line {a}.",
9769
  E027: "Missing ']' to match '[' from line {a}.",
9770
  E028: "Illegal comma.",
9771
  E029: "Unclosed string.",
9772
  E030: "Expected an identifier and instead saw '{a}'.",
9773
  E031: "Bad assignment.", // FIXME: Rephrase
9774
  E032: "Expected a small integer or 'false' and instead saw '{a}'.",
9775
  E033: "Expected an operator and instead saw '{a}'.",
9776
  E034: "get/set are ES5 features.",
9777
  E035: "Missing property name.",
9778
  E036: "Expected to see a statement and instead saw a block.",
9779
  E037: null,
9780
  E038: null,
9781
  E039: "Function declarations are not invocable. Wrap the whole function invocation in parens.",
9782
  E040: "Each value should have its own case label.",
9783
  E041: "Unrecoverable syntax error.",
9784
  E042: "Stopping.",
9785
  E043: "Too many errors.",
9786
  E044: null,
9787
  E045: "Invalid for each loop.",
9788
  E046: "A yield statement shall be within a generator function (with syntax: `function*`)",
9789
  E047: null,
9790
  E048: "{a} declaration not directly within block.",
9791
  E049: "A {a} cannot be named '{b}'.",
9792
  E050: "Mozilla requires the yield expression to be parenthesized here.",
9793
  E051: null,
9794
  E052: "Unclosed template literal.",
9795
  E053: "Export declaration must be in global scope.",
9796
  E054: "Class properties must be methods. Expected '(' but instead saw '{a}'.",
9797
  E055: "The '{a}' option cannot be set after any executable code.",
9798
  E056: "'{a}' was used before it was declared, which is illegal for '{b}' variables.",
9799
  E057: "Invalid meta property: '{a}.{b}'.",
9800
  E058: "Missing semicolon."
9801
};
9802

    
9803
var warnings = {
9804
  W001: "'hasOwnProperty' is a really bad name.",
9805
  W002: "Value of '{a}' may be overwritten in IE 8 and earlier.",
9806
  W003: "'{a}' was used before it was defined.",
9807
  W004: "'{a}' is already defined.",
9808
  W005: "A dot following a number can be confused with a decimal point.",
9809
  W006: "Confusing minuses.",
9810
  W007: "Confusing plusses.",
9811
  W008: "A leading decimal point can be confused with a dot: '{a}'.",
9812
  W009: "The array literal notation [] is preferable.",
9813
  W010: "The object literal notation {} is preferable.",
9814
  W011: null,
9815
  W012: null,
9816
  W013: null,
9817
  W014: "Bad line breaking before '{a}'.",
9818
  W015: null,
9819
  W016: "Unexpected use of '{a}'.",
9820
  W017: "Bad operand.",
9821
  W018: "Confusing use of '{a}'.",
9822
  W019: "Use the isNaN function to compare with NaN.",
9823
  W020: "Read only.",
9824
  W021: "Reassignment of '{a}', which is is a {b}. " +
9825
    "Use 'var' or 'let' to declare bindings that may change.",
9826
  W022: "Do not assign to the exception parameter.",
9827
  W023: "Expected an identifier in an assignment and instead saw a function invocation.",
9828
  W024: "Expected an identifier and instead saw '{a}' (a reserved word).",
9829
  W025: "Missing name in function declaration.",
9830
  W026: "Inner functions should be listed at the top of the outer function.",
9831
  W027: "Unreachable '{a}' after '{b}'.",
9832
  W028: "Label '{a}' on {b} statement.",
9833
  W030: "Expected an assignment or function call and instead saw an expression.",
9834
  W031: "Do not use 'new' for side effects.",
9835
  W032: "Unnecessary semicolon.",
9836
  W033: "Missing semicolon.",
9837
  W034: "Unnecessary directive \"{a}\".",
9838
  W035: "Empty block.",
9839
  W036: "Unexpected /*member '{a}'.",
9840
  W037: "'{a}' is a statement label.",
9841
  W038: "'{a}' used out of scope.",
9842
  W039: "'{a}' is not allowed.",
9843
  W040: "Possible strict violation.",
9844
  W041: "Use '{a}' to compare with '{b}'.",
9845
  W042: "Avoid EOL escaping.",
9846
  W043: "Bad escaping of EOL. Use option multistr if needed.",
9847
  W044: "Bad or unnecessary escaping.", /* TODO(caitp): remove W044 */
9848
  W045: "Bad number '{a}'.",
9849
  W046: "Don't use extra leading zeros '{a}'.",
9850
  W047: "A trailing decimal point can be confused with a dot: '{a}'.",
9851
  W048: "Unexpected control character in regular expression.",
9852
  W049: "Unexpected escaped character '{a}' in regular expression.",
9853
  W050: "JavaScript URL.",
9854
  W051: "Variables should not be deleted.",
9855
  W052: "Unexpected '{a}'.",
9856
  W053: "Do not use {a} as a constructor.",
9857
  W054: "The Function constructor is a form of eval.",
9858
  W055: "A constructor name should start with an uppercase letter.",
9859
  W056: "Bad constructor.",
9860
  W057: "Weird construction. Is 'new' necessary?",
9861
  W058: "Missing '()' invoking a constructor.",
9862
  W059: "Avoid arguments.{a}.",
9863
  W060: "document.write can be a form of eval.",
9864
  W061: "eval can be harmful.",
9865
  W062: "Wrap an immediate function invocation in parens " +
9866
    "to assist the reader in understanding that the expression " +
9867
    "is the result of a function, and not the function itself.",
9868
  W063: "Math is not a function.",
9869
  W064: "Missing 'new' prefix when invoking a constructor.",
9870
  W065: "Missing radix parameter.",
9871
  W066: "Implied eval. Consider passing a function instead of a string.",
9872
  W067: "Bad invocation.",
9873
  W068: "Wrapping non-IIFE function literals in parens is unnecessary.",
9874
  W069: "['{a}'] is better written in dot notation.",
9875
  W070: "Extra comma. (it breaks older versions of IE)",
9876
  W071: "This function has too many statements. ({a})",
9877
  W072: "This function has too many parameters. ({a})",
9878
  W073: "Blocks are nested too deeply. ({a})",
9879
  W074: "This function's cyclomatic complexity is too high. ({a})",
9880
  W075: "Duplicate {a} '{b}'.",
9881
  W076: "Unexpected parameter '{a}' in get {b} function.",
9882
  W077: "Expected a single parameter in set {a} function.",
9883
  W078: "Setter is defined without getter.",
9884
  W079: "Redefinition of '{a}'.",
9885
  W080: "It's not necessary to initialize '{a}' to 'undefined'.",
9886
  W081: null,
9887
  W082: "Function declarations should not be placed in blocks. " +
9888
    "Use a function expression or move the statement to the top of " +
9889
    "the outer function.",
9890
  W083: "Don't make functions within a loop.",
9891
  W084: "Assignment in conditional expression",
9892
  W085: "Don't use 'with'.",
9893
  W086: "Expected a 'break' statement before '{a}'.",
9894
  W087: "Forgotten 'debugger' statement?",
9895
  W088: "Creating global 'for' variable. Should be 'for (var {a} ...'.",
9896
  W089: "The body of a for in should be wrapped in an if statement to filter " +
9897
    "unwanted properties from the prototype.",
9898
  W090: "'{a}' is not a statement label.",
9899
  W091: null,
9900
  W093: "Did you mean to return a conditional instead of an assignment?",
9901
  W094: "Unexpected comma.",
9902
  W095: "Expected a string and instead saw {a}.",
9903
  W096: "The '{a}' key may produce unexpected results.",
9904
  W097: "Use the function form of \"use strict\".",
9905
  W098: "'{a}' is defined but never used.",
9906
  W099: null,
9907
  W100: "This character may get silently deleted by one or more browsers.",
9908
  W101: "Line is too long.",
9909
  W102: null,
9910
  W103: "The '{a}' property is deprecated.",
9911
  W104: "'{a}' is available in ES{b} (use 'esversion: {b}') or Mozilla JS extensions (use moz).",
9912
  W105: "Unexpected {a} in '{b}'.",
9913
  W106: "Identifier '{a}' is not in camel case.",
9914
  W107: "Script URL.",
9915
  W108: "Strings must use doublequote.",
9916
  W109: "Strings must use singlequote.",
9917
  W110: "Mixed double and single quotes.",
9918
  W112: "Unclosed string.",
9919
  W113: "Control character in string: {a}.",
9920
  W114: "Avoid {a}.",
9921
  W115: "Octal literals are not allowed in strict mode.",
9922
  W116: "Expected '{a}' and instead saw '{b}'.",
9923
  W117: "'{a}' is not defined.",
9924
  W118: "'{a}' is only available in Mozilla JavaScript extensions (use moz option).",
9925
  W119: "'{a}' is only available in ES{b} (use 'esversion: {b}').",
9926
  W120: "You might be leaking a variable ({a}) here.",
9927
  W121: "Extending prototype of native object: '{a}'.",
9928
  W122: "Invalid typeof value '{a}'",
9929
  W123: "'{a}' is already defined in outer scope.",
9930
  W124: "A generator function shall contain a yield statement.",
9931
  W125: "This line contains non-breaking spaces: http://jshint.com/doc/options/#nonbsp",
9932
  W126: "Unnecessary grouping operator.",
9933
  W127: "Unexpected use of a comma operator.",
9934
  W128: "Empty array elements require elision=true.",
9935
  W129: "'{a}' is defined in a future version of JavaScript. Use a " +
9936
    "different variable name to avoid migration issues.",
9937
  W130: "Invalid element after rest element.",
9938
  W131: "Invalid parameter after rest parameter.",
9939
  W132: "`var` declarations are forbidden. Use `let` or `const` instead.",
9940
  W133: "Invalid for-{a} loop left-hand-side: {b}.",
9941
  W134: "The '{a}' option is only available when linting ECMAScript {b} code.",
9942
  W135: "{a} may not be supported by non-browser environments.",
9943
  W136: "'{a}' must be in function scope.",
9944
  W137: "Empty destructuring.",
9945
  W138: "Regular parameters should not come after default parameters."
9946
};
9947

    
9948
var info = {
9949
  I001: "Comma warnings can be turned off with 'laxcomma'.",
9950
  I002: null,
9951
  I003: "ES5 option is now set per default"
9952
};
9953

    
9954
exports.errors = {};
9955
exports.warnings = {};
9956
exports.info = {};
9957

    
9958
_.each(errors, function(desc, code) {
9959
  exports.errors[code] = { code: code, desc: desc };
9960
});
9961

    
9962
_.each(warnings, function(desc, code) {
9963
  exports.warnings[code] = { code: code, desc: desc };
9964
});
9965

    
9966
_.each(info, function(desc, code) {
9967
  exports.info[code] = { code: code, desc: desc };
9968
});
9969

    
9970
},{"../lodash":"/node_modules/jshint/lodash.js"}],"/node_modules/jshint/src/name-stack.js":[function(_dereq_,module,exports){
9971
"use strict";
9972

    
9973
function NameStack() {
9974
  this._stack = [];
9975
}
9976

    
9977
Object.defineProperty(NameStack.prototype, "length", {
9978
  get: function() {
9979
    return this._stack.length;
9980
  }
9981
});
9982
NameStack.prototype.push = function() {
9983
  this._stack.push(null);
9984
};
9985
NameStack.prototype.pop = function() {
9986
  this._stack.pop();
9987
};
9988
NameStack.prototype.set = function(token) {
9989
  this._stack[this.length - 1] = token;
9990
};
9991
NameStack.prototype.infer = function() {
9992
  var nameToken = this._stack[this.length - 1];
9993
  var prefix = "";
9994
  var type;
9995
  if (!nameToken || nameToken.type === "class") {
9996
    nameToken = this._stack[this.length - 2];
9997
  }
9998

    
9999
  if (!nameToken) {
10000
    return "(empty)";
10001
  }
10002

    
10003
  type = nameToken.type;
10004

    
10005
  if (type !== "(string)" && type !== "(number)" && type !== "(identifier)" && type !== "default") {
10006
    return "(expression)";
10007
  }
10008

    
10009
  if (nameToken.accessorType) {
10010
    prefix = nameToken.accessorType + " ";
10011
  }
10012

    
10013
  return prefix + nameToken.value;
10014
};
10015

    
10016
module.exports = NameStack;
10017

    
10018
},{}],"/node_modules/jshint/src/options.js":[function(_dereq_,module,exports){
10019
"use strict";
10020
exports.bool = {
10021
  enforcing: {
10022
    bitwise     : true,
10023
    freeze      : true,
10024
    camelcase   : true,
10025
    curly       : true,
10026
    eqeqeq      : true,
10027
    futurehostile: true,
10028
    notypeof    : true,
10029
    es3         : true,
10030
    es5         : true,
10031
    forin       : true,
10032
    funcscope   : true,
10033
    immed       : true,
10034
    iterator    : true,
10035
    newcap      : true,
10036
    noarg       : true,
10037
    nocomma     : true,
10038
    noempty     : true,
10039
    nonbsp      : true,
10040
    nonew       : true,
10041
    undef       : true,
10042
    singleGroups: false,
10043
    varstmt: false,
10044
    enforceall : false
10045
  },
10046
  relaxing: {
10047
    asi         : true,
10048
    multistr    : true,
10049
    debug       : true,
10050
    boss        : true,
10051
    evil        : true,
10052
    globalstrict: true,
10053
    plusplus    : true,
10054
    proto       : true,
10055
    scripturl   : true,
10056
    sub         : true,
10057
    supernew    : true,
10058
    laxbreak    : true,
10059
    laxcomma    : true,
10060
    validthis   : true,
10061
    withstmt    : true,
10062
    moz         : true,
10063
    noyield     : true,
10064
    eqnull      : true,
10065
    lastsemic   : true,
10066
    loopfunc    : true,
10067
    expr        : true,
10068
    esnext      : true,
10069
    elision     : true,
10070
  },
10071
  environments: {
10072
    mootools    : true,
10073
    couch       : true,
10074
    jasmine     : true,
10075
    jquery      : true,
10076
    node        : true,
10077
    qunit       : true,
10078
    rhino       : true,
10079
    shelljs     : true,
10080
    prototypejs : true,
10081
    yui         : true,
10082
    mocha       : true,
10083
    module      : true,
10084
    wsh         : true,
10085
    worker      : true,
10086
    nonstandard : true,
10087
    browser     : true,
10088
    browserify  : true,
10089
    devel       : true,
10090
    dojo        : true,
10091
    typed       : true,
10092
    phantom     : true
10093
  },
10094
  obsolete: {
10095
    onecase     : true, // if one case switch statements should be allowed
10096
    regexp      : true, // if the . should not be allowed in regexp literals
10097
    regexdash   : true  // if unescaped first/last dash (-) inside brackets
10098
  }
10099
};
10100
exports.val = {
10101
  maxlen       : false,
10102
  indent       : false,
10103
  maxerr       : false,
10104
  predef       : false,
10105
  globals      : false,
10106
  quotmark     : false,
10107

    
10108
  scope        : false,
10109
  maxstatements: false,
10110
  maxdepth     : false,
10111
  maxparams    : false,
10112
  maxcomplexity: false,
10113
  shadow       : false,
10114
  strict      : true,
10115
  unused       : true,
10116
  latedef      : false,
10117

    
10118
  ignore       : false, // start/end ignoring lines of code, bypassing the lexer
10119

    
10120
  ignoreDelimiters: false, // array of start/end delimiters used to ignore
10121
  esversion: 5
10122
};
10123
exports.inverted = {
10124
  bitwise : true,
10125
  forin   : true,
10126
  newcap  : true,
10127
  plusplus: true,
10128
  regexp  : true,
10129
  undef   : true,
10130
  eqeqeq  : true,
10131
  strict  : true
10132
};
10133

    
10134
exports.validNames = Object.keys(exports.val)
10135
  .concat(Object.keys(exports.bool.relaxing))
10136
  .concat(Object.keys(exports.bool.enforcing))
10137
  .concat(Object.keys(exports.bool.obsolete))
10138
  .concat(Object.keys(exports.bool.environments));
10139
exports.renamed = {
10140
  eqeq   : "eqeqeq",
10141
  windows: "wsh",
10142
  sloppy : "strict"
10143
};
10144

    
10145
exports.removed = {
10146
  nomen: true,
10147
  onevar: true,
10148
  passfail: true,
10149
  white: true,
10150
  gcl: true,
10151
  smarttabs: true,
10152
  trailing: true
10153
};
10154
exports.noenforceall = {
10155
  varstmt: true,
10156
  strict: true
10157
};
10158

    
10159
},{}],"/node_modules/jshint/src/reg.js":[function(_dereq_,module,exports){
10160

    
10161
"use strict";
10162
exports.unsafeString =
10163
  /@cc|<\/?|script|\]\s*\]|<\s*!|&lt/i;
10164
exports.unsafeChars =
10165
  /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
10166
exports.needEsc =
10167
  /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
10168

    
10169
exports.needEscGlobal =
10170
  /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
10171
exports.starSlash = /\*\//;
10172
exports.identifier = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/;
10173
exports.javascriptURL = /^(?:javascript|jscript|ecmascript|vbscript|livescript)\s*:/i;
10174
exports.fallsThrough = /^\s*falls?\sthrough\s*$/;
10175
exports.maxlenException = /^(?:(?:\/\/|\/\*|\*) ?)?[^ ]+$/;
10176

    
10177
},{}],"/node_modules/jshint/src/scope-manager.js":[function(_dereq_,module,exports){
10178
"use strict";
10179

    
10180
var _      = _dereq_("../lodash");
10181
var events = _dereq_("events");
10182
var marker = {};
10183
var scopeManager = function(state, predefined, exported, declared) {
10184

    
10185
  var _current;
10186
  var _scopeStack = [];
10187

    
10188
  function _newScope(type) {
10189
    _current = {
10190
      "(labels)": Object.create(null),
10191
      "(usages)": Object.create(null),
10192
      "(breakLabels)": Object.create(null),
10193
      "(parent)": _current,
10194
      "(type)": type,
10195
      "(params)": (type === "functionparams" || type === "catchparams") ? [] : null
10196
    };
10197
    _scopeStack.push(_current);
10198
  }
10199

    
10200
  _newScope("global");
10201
  _current["(predefined)"] = predefined;
10202

    
10203
  var _currentFunctBody = _current; // this is the block after the params = function
10204

    
10205
  var usedPredefinedAndGlobals = Object.create(null);
10206
  var impliedGlobals = Object.create(null);
10207
  var unuseds = [];
10208
  var emitter = new events.EventEmitter();
10209

    
10210
  function warning(code, token) {
10211
    emitter.emit("warning", {
10212
      code: code,
10213
      token: token,
10214
      data: _.slice(arguments, 2)
10215
    });
10216
  }
10217

    
10218
  function error(code, token) {
10219
    emitter.emit("warning", {
10220
      code: code,
10221
      token: token,
10222
      data: _.slice(arguments, 2)
10223
    });
10224
  }
10225

    
10226
  function _setupUsages(labelName) {
10227
    if (!_current["(usages)"][labelName]) {
10228
      _current["(usages)"][labelName] = {
10229
        "(modified)": [],
10230
        "(reassigned)": [],
10231
        "(tokens)": []
10232
      };
10233
    }
10234
  }
10235

    
10236
  var _getUnusedOption = function(unused_opt) {
10237
    if (unused_opt === undefined) {
10238
      unused_opt = state.option.unused;
10239
    }
10240

    
10241
    if (unused_opt === true) {
10242
      unused_opt = "last-param";
10243
    }
10244

    
10245
    return unused_opt;
10246
  };
10247

    
10248
  var _warnUnused = function(name, tkn, type, unused_opt) {
10249
    var line = tkn.line;
10250
    var chr  = tkn.from;
10251
    var raw_name = tkn.raw_text || name;
10252

    
10253
    unused_opt = _getUnusedOption(unused_opt);
10254

    
10255
    var warnable_types = {
10256
      "vars": ["var"],
10257
      "last-param": ["var", "param"],
10258
      "strict": ["var", "param", "last-param"]
10259
    };
10260

    
10261
    if (unused_opt) {
10262
      if (warnable_types[unused_opt] && warnable_types[unused_opt].indexOf(type) !== -1) {
10263
        warning("W098", { line: line, from: chr }, raw_name);
10264
      }
10265
    }
10266
    if (unused_opt || type === "var") {
10267
      unuseds.push({
10268
        name: name,
10269
        line: line,
10270
        character: chr
10271
      });
10272
    }
10273
  };
10274
  function _checkForUnused() {
10275
    if (_current["(type)"] === "functionparams") {
10276
      _checkParams();
10277
      return;
10278
    }
10279
    var curentLabels = _current["(labels)"];
10280
    for (var labelName in curentLabels) {
10281
      if (curentLabels[labelName]) {
10282
        if (curentLabels[labelName]["(type)"] !== "exception" &&
10283
          curentLabels[labelName]["(unused)"]) {
10284
          _warnUnused(labelName, curentLabels[labelName]["(token)"], "var");
10285
        }
10286
      }
10287
    }
10288
  }
10289
  function _checkParams() {
10290
    var params = _current["(params)"];
10291

    
10292
    if (!params) {
10293
      return;
10294
    }
10295

    
10296
    var param = params.pop();
10297
    var unused_opt;
10298

    
10299
    while (param) {
10300
      var label = _current["(labels)"][param];
10301

    
10302
      unused_opt = _getUnusedOption(state.funct["(unusedOption)"]);
10303
      if (param === "undefined")
10304
        return;
10305

    
10306
      if (label["(unused)"]) {
10307
        _warnUnused(param, label["(token)"], "param", state.funct["(unusedOption)"]);
10308
      } else if (unused_opt === "last-param") {
10309
        return;
10310
      }
10311

    
10312
      param = params.pop();
10313
    }
10314
  }
10315
  function _getLabel(labelName) {
10316
    for (var i = _scopeStack.length - 1 ; i >= 0; --i) {
10317
      var scopeLabels = _scopeStack[i]["(labels)"];
10318
      if (scopeLabels[labelName]) {
10319
        return scopeLabels;
10320
      }
10321
    }
10322
  }
10323

    
10324
  function usedSoFarInCurrentFunction(labelName) {
10325
    for (var i = _scopeStack.length - 1; i >= 0; i--) {
10326
      var current = _scopeStack[i];
10327
      if (current["(usages)"][labelName]) {
10328
        return current["(usages)"][labelName];
10329
      }
10330
      if (current === _currentFunctBody) {
10331
        break;
10332
      }
10333
    }
10334
    return false;
10335
  }
10336

    
10337
  function _checkOuterShadow(labelName, token) {
10338
    if (state.option.shadow !== "outer") {
10339
      return;
10340
    }
10341

    
10342
    var isGlobal = _currentFunctBody["(type)"] === "global",
10343
      isNewFunction = _current["(type)"] === "functionparams";
10344

    
10345
    var outsideCurrentFunction = !isGlobal;
10346
    for (var i = 0; i < _scopeStack.length; i++) {
10347
      var stackItem = _scopeStack[i];
10348

    
10349
      if (!isNewFunction && _scopeStack[i + 1] === _currentFunctBody) {
10350
        outsideCurrentFunction = false;
10351
      }
10352
      if (outsideCurrentFunction && stackItem["(labels)"][labelName]) {
10353
        warning("W123", token, labelName);
10354
      }
10355
      if (stackItem["(breakLabels)"][labelName]) {
10356
        warning("W123", token, labelName);
10357
      }
10358
    }
10359
  }
10360

    
10361
  function _latedefWarning(type, labelName, token) {
10362
    if (state.option.latedef) {
10363
      if ((state.option.latedef === true && type === "function") ||
10364
        type !== "function") {
10365
        warning("W003", token, labelName);
10366
      }
10367
    }
10368
  }
10369

    
10370
  var scopeManagerInst = {
10371

    
10372
    on: function(names, listener) {
10373
      names.split(" ").forEach(function(name) {
10374
        emitter.on(name, listener);
10375
      });
10376
    },
10377

    
10378
    isPredefined: function(labelName) {
10379
      return !this.has(labelName) && _.has(_scopeStack[0]["(predefined)"], labelName);
10380
    },
10381
    stack: function(type) {
10382
      var previousScope = _current;
10383
      _newScope(type);
10384

    
10385
      if (!type && previousScope["(type)"] === "functionparams") {
10386

    
10387
        _current["(isFuncBody)"] = true;
10388
        _current["(context)"] = _currentFunctBody;
10389
        _currentFunctBody = _current;
10390
      }
10391
    },
10392

    
10393
    unstack: function() {
10394
      var subScope = _scopeStack.length > 1 ? _scopeStack[_scopeStack.length - 2] : null;
10395
      var isUnstackingFunctionBody = _current === _currentFunctBody,
10396
        isUnstackingFunctionParams = _current["(type)"] === "functionparams",
10397
        isUnstackingFunctionOuter = _current["(type)"] === "functionouter";
10398

    
10399
      var i, j;
10400
      var currentUsages = _current["(usages)"];
10401
      var currentLabels = _current["(labels)"];
10402
      var usedLabelNameList = Object.keys(currentUsages);
10403

    
10404
      if (currentUsages.__proto__ && usedLabelNameList.indexOf("__proto__") === -1) {
10405
        usedLabelNameList.push("__proto__");
10406
      }
10407

    
10408
      for (i = 0; i < usedLabelNameList.length; i++) {
10409
        var usedLabelName = usedLabelNameList[i];
10410

    
10411
        var usage = currentUsages[usedLabelName];
10412
        var usedLabel = currentLabels[usedLabelName];
10413
        if (usedLabel) {
10414
          var usedLabelType = usedLabel["(type)"];
10415

    
10416
          if (usedLabel["(useOutsideOfScope)"] && !state.option.funcscope) {
10417
            var usedTokens = usage["(tokens)"];
10418
            if (usedTokens) {
10419
              for (j = 0; j < usedTokens.length; j++) {
10420
                if (usedLabel["(function)"] === usedTokens[j]["(function)"]) {
10421
                  error("W038", usedTokens[j], usedLabelName);
10422
                }
10423
              }
10424
            }
10425
          }
10426
          _current["(labels)"][usedLabelName]["(unused)"] = false;
10427
          if (usedLabelType === "const" && usage["(modified)"]) {
10428
            for (j = 0; j < usage["(modified)"].length; j++) {
10429
              error("E013", usage["(modified)"][j], usedLabelName);
10430
            }
10431
          }
10432
          if ((usedLabelType === "function" || usedLabelType === "class") &&
10433
              usage["(reassigned)"]) {
10434
            for (j = 0; j < usage["(reassigned)"].length; j++) {
10435
              error("W021", usage["(reassigned)"][j], usedLabelName, usedLabelType);
10436
            }
10437
          }
10438
          continue;
10439
        }
10440

    
10441
        if (isUnstackingFunctionOuter) {
10442
          state.funct["(isCapturing)"] = true;
10443
        }
10444

    
10445
        if (subScope) {
10446
          if (!subScope["(usages)"][usedLabelName]) {
10447
            subScope["(usages)"][usedLabelName] = usage;
10448
            if (isUnstackingFunctionBody) {
10449
              subScope["(usages)"][usedLabelName]["(onlyUsedSubFunction)"] = true;
10450
            }
10451
          } else {
10452
            var subScopeUsage = subScope["(usages)"][usedLabelName];
10453
            subScopeUsage["(modified)"] = subScopeUsage["(modified)"].concat(usage["(modified)"]);
10454
            subScopeUsage["(tokens)"] = subScopeUsage["(tokens)"].concat(usage["(tokens)"]);
10455
            subScopeUsage["(reassigned)"] =
10456
              subScopeUsage["(reassigned)"].concat(usage["(reassigned)"]);
10457
            subScopeUsage["(onlyUsedSubFunction)"] = false;
10458
          }
10459
        } else {
10460
          if (typeof _current["(predefined)"][usedLabelName] === "boolean") {
10461
            delete declared[usedLabelName];
10462
            usedPredefinedAndGlobals[usedLabelName] = marker;
10463
            if (_current["(predefined)"][usedLabelName] === false && usage["(reassigned)"]) {
10464
              for (j = 0; j < usage["(reassigned)"].length; j++) {
10465
                warning("W020", usage["(reassigned)"][j]);
10466
              }
10467
            }
10468
          }
10469
          else {
10470
            if (usage["(tokens)"]) {
10471
              for (j = 0; j < usage["(tokens)"].length; j++) {
10472
                var undefinedToken = usage["(tokens)"][j];
10473
                if (!undefinedToken.forgiveUndef) {
10474
                  if (state.option.undef && !undefinedToken.ignoreUndef) {
10475
                    warning("W117", undefinedToken, usedLabelName);
10476
                  }
10477
                  if (impliedGlobals[usedLabelName]) {
10478
                    impliedGlobals[usedLabelName].line.push(undefinedToken.line);
10479
                  } else {
10480
                    impliedGlobals[usedLabelName] = {
10481
                      name: usedLabelName,
10482
                      line: [undefinedToken.line]
10483
                    };
10484
                  }
10485
                }
10486
              }
10487
            }
10488
          }
10489
        }
10490
      }
10491
      if (!subScope) {
10492
        Object.keys(declared)
10493
          .forEach(function(labelNotUsed) {
10494
            _warnUnused(labelNotUsed, declared[labelNotUsed], "var");
10495
          });
10496
      }
10497
      if (subScope && !isUnstackingFunctionBody &&
10498
        !isUnstackingFunctionParams && !isUnstackingFunctionOuter) {
10499
        var labelNames = Object.keys(currentLabels);
10500
        for (i = 0; i < labelNames.length; i++) {
10501

    
10502
          var defLabelName = labelNames[i];
10503
          if (!currentLabels[defLabelName]["(blockscoped)"] &&
10504
            currentLabels[defLabelName]["(type)"] !== "exception" &&
10505
            !this.funct.has(defLabelName, { excludeCurrent: true })) {
10506
            subScope["(labels)"][defLabelName] = currentLabels[defLabelName];
10507
            if (_currentFunctBody["(type)"] !== "global") {
10508
              subScope["(labels)"][defLabelName]["(useOutsideOfScope)"] = true;
10509
            }
10510
            delete currentLabels[defLabelName];
10511
          }
10512
        }
10513
      }
10514

    
10515
      _checkForUnused();
10516

    
10517
      _scopeStack.pop();
10518
      if (isUnstackingFunctionBody) {
10519
        _currentFunctBody = _scopeStack[_.findLastIndex(_scopeStack, function(scope) {
10520
          return scope["(isFuncBody)"] || scope["(type)"] === "global";
10521
        })];
10522
      }
10523

    
10524
      _current = subScope;
10525
    },
10526
    addParam: function(labelName, token, type) {
10527
      type = type || "param";
10528

    
10529
      if (type === "exception") {
10530
        var previouslyDefinedLabelType = this.funct.labeltype(labelName);
10531
        if (previouslyDefinedLabelType && previouslyDefinedLabelType !== "exception") {
10532
          if (!state.option.node) {
10533
            warning("W002", state.tokens.next, labelName);
10534
          }
10535
        }
10536
      }
10537
      if (_.has(_current["(labels)"], labelName)) {
10538
        _current["(labels)"][labelName].duplicated = true;
10539
      } else {
10540
        _checkOuterShadow(labelName, token, type);
10541

    
10542
        _current["(labels)"][labelName] = {
10543
          "(type)" : type,
10544
          "(token)": token,
10545
          "(unused)": true };
10546

    
10547
        _current["(params)"].push(labelName);
10548
      }
10549

    
10550
      if (_.has(_current["(usages)"], labelName)) {
10551
        var usage = _current["(usages)"][labelName];
10552
        if (usage["(onlyUsedSubFunction)"]) {
10553
          _latedefWarning(type, labelName, token);
10554
        } else {
10555
          warning("E056", token, labelName, type);
10556
        }
10557
      }
10558
    },
10559

    
10560
    validateParams: function() {
10561
      if (_currentFunctBody["(type)"] === "global") {
10562
        return;
10563
      }
10564

    
10565
      var isStrict = state.isStrict();
10566
      var currentFunctParamScope = _currentFunctBody["(parent)"];
10567

    
10568
      if (!currentFunctParamScope["(params)"]) {
10569
        return;
10570
      }
10571

    
10572
      currentFunctParamScope["(params)"].forEach(function(labelName) {
10573
        var label = currentFunctParamScope["(labels)"][labelName];
10574

    
10575
        if (label && label.duplicated) {
10576
          if (isStrict) {
10577
            warning("E011", label["(token)"], labelName);
10578
          } else if (state.option.shadow !== true) {
10579
            warning("W004", label["(token)"], labelName);
10580
          }
10581
        }
10582
      });
10583
    },
10584

    
10585
    getUsedOrDefinedGlobals: function() {
10586
      var list = Object.keys(usedPredefinedAndGlobals);
10587
      if (usedPredefinedAndGlobals.__proto__ === marker &&
10588
        list.indexOf("__proto__") === -1) {
10589
        list.push("__proto__");
10590
      }
10591

    
10592
      return list;
10593
    },
10594
    getImpliedGlobals: function() {
10595
      var values = _.values(impliedGlobals);
10596
      var hasProto = false;
10597
      if (impliedGlobals.__proto__) {
10598
        hasProto = values.some(function(value) {
10599
          return value.name === "__proto__";
10600
        });
10601

    
10602
        if (!hasProto) {
10603
          values.push(impliedGlobals.__proto__);
10604
        }
10605
      }
10606

    
10607
      return values;
10608
    },
10609
    getUnuseds: function() {
10610
      return unuseds;
10611
    },
10612

    
10613
    has: function(labelName) {
10614
      return Boolean(_getLabel(labelName));
10615
    },
10616

    
10617
    labeltype: function(labelName) {
10618
      var scopeLabels = _getLabel(labelName);
10619
      if (scopeLabels) {
10620
        return scopeLabels[labelName]["(type)"];
10621
      }
10622
      return null;
10623
    },
10624
    addExported: function(labelName) {
10625
      var globalLabels = _scopeStack[0]["(labels)"];
10626
      if (_.has(declared, labelName)) {
10627
        delete declared[labelName];
10628
      } else if (_.has(globalLabels, labelName)) {
10629
        globalLabels[labelName]["(unused)"] = false;
10630
      } else {
10631
        for (var i = 1; i < _scopeStack.length; i++) {
10632
          var scope = _scopeStack[i];
10633
          if (!scope["(type)"]) {
10634
            if (_.has(scope["(labels)"], labelName) &&
10635
                !scope["(labels)"][labelName]["(blockscoped)"]) {
10636
              scope["(labels)"][labelName]["(unused)"] = false;
10637
              return;
10638
            }
10639
          } else {
10640
            break;
10641
          }
10642
        }
10643
        exported[labelName] = true;
10644
      }
10645
    },
10646
    setExported: function(labelName, token) {
10647
      this.block.use(labelName, token);
10648
    },
10649
    addlabel: function(labelName, opts) {
10650

    
10651
      var type  = opts.type;
10652
      var token = opts.token;
10653
      var isblockscoped = type === "let" || type === "const" || type === "class";
10654
      var isexported    = (isblockscoped ? _current : _currentFunctBody)["(type)"] === "global" &&
10655
                          _.has(exported, labelName);
10656
      _checkOuterShadow(labelName, token, type);
10657
      if (isblockscoped) {
10658

    
10659
        var declaredInCurrentScope = _current["(labels)"][labelName];
10660
        if (!declaredInCurrentScope && _current === _currentFunctBody &&
10661
          _current["(type)"] !== "global") {
10662
          declaredInCurrentScope = !!_currentFunctBody["(parent)"]["(labels)"][labelName];
10663
        }
10664
        if (!declaredInCurrentScope && _current["(usages)"][labelName]) {
10665
          var usage = _current["(usages)"][labelName];
10666
          if (usage["(onlyUsedSubFunction)"]) {
10667
            _latedefWarning(type, labelName, token);
10668
          } else {
10669
            warning("E056", token, labelName, type);
10670
          }
10671
        }
10672
        if (declaredInCurrentScope) {
10673
          warning("E011", token, labelName);
10674
        }
10675
        else if (state.option.shadow === "outer") {
10676
          if (scopeManagerInst.funct.has(labelName)) {
10677
            warning("W004", token, labelName);
10678
          }
10679
        }
10680

    
10681
        scopeManagerInst.block.add(labelName, type, token, !isexported);
10682

    
10683
      } else {
10684

    
10685
        var declaredInCurrentFunctionScope = scopeManagerInst.funct.has(labelName);
10686
        if (!declaredInCurrentFunctionScope && usedSoFarInCurrentFunction(labelName)) {
10687
          _latedefWarning(type, labelName, token);
10688
        }
10689
        if (scopeManagerInst.funct.has(labelName, { onlyBlockscoped: true })) {
10690
          warning("E011", token, labelName);
10691
        } else if (state.option.shadow !== true) {
10692
          if (declaredInCurrentFunctionScope && labelName !== "__proto__") {
10693
            if (_currentFunctBody["(type)"] !== "global") {
10694
              warning("W004", token, labelName);
10695
            }
10696
          }
10697
        }
10698

    
10699
        scopeManagerInst.funct.add(labelName, type, token, !isexported);
10700

    
10701
        if (_currentFunctBody["(type)"] === "global") {
10702
          usedPredefinedAndGlobals[labelName] = marker;
10703
        }
10704
      }
10705
    },
10706

    
10707
    funct: {
10708
      labeltype: function(labelName, options) {
10709
        var onlyBlockscoped = options && options.onlyBlockscoped;
10710
        var excludeParams = options && options.excludeParams;
10711
        var currentScopeIndex = _scopeStack.length - (options && options.excludeCurrent ? 2 : 1);
10712
        for (var i = currentScopeIndex; i >= 0; i--) {
10713
          var current = _scopeStack[i];
10714
          if (current["(labels)"][labelName] &&
10715
            (!onlyBlockscoped || current["(labels)"][labelName]["(blockscoped)"])) {
10716
            return current["(labels)"][labelName]["(type)"];
10717
          }
10718
          var scopeCheck = excludeParams ? _scopeStack[ i - 1 ] : current;
10719
          if (scopeCheck && scopeCheck["(type)"] === "functionparams") {
10720
            return null;
10721
          }
10722
        }
10723
        return null;
10724
      },
10725
      hasBreakLabel: function(labelName) {
10726
        for (var i = _scopeStack.length - 1; i >= 0; i--) {
10727
          var current = _scopeStack[i];
10728

    
10729
          if (current["(breakLabels)"][labelName]) {
10730
            return true;
10731
          }
10732
          if (current["(type)"] === "functionparams") {
10733
            return false;
10734
          }
10735
        }
10736
        return false;
10737
      },
10738
      has: function(labelName, options) {
10739
        return Boolean(this.labeltype(labelName, options));
10740
      },
10741
      add: function(labelName, type, tok, unused) {
10742
        _current["(labels)"][labelName] = {
10743
          "(type)" : type,
10744
          "(token)": tok,
10745
          "(blockscoped)": false,
10746
          "(function)": _currentFunctBody,
10747
          "(unused)": unused };
10748
      }
10749
    },
10750

    
10751
    block: {
10752
      isGlobal: function() {
10753
        return _current["(type)"] === "global";
10754
      },
10755

    
10756
      use: function(labelName, token) {
10757
        var paramScope = _currentFunctBody["(parent)"];
10758
        if (paramScope && paramScope["(labels)"][labelName] &&
10759
          paramScope["(labels)"][labelName]["(type)"] === "param") {
10760
          if (!scopeManagerInst.funct.has(labelName,
10761
                { excludeParams: true, onlyBlockscoped: true })) {
10762
            paramScope["(labels)"][labelName]["(unused)"] = false;
10763
          }
10764
        }
10765

    
10766
        if (token && (state.ignored.W117 || state.option.undef === false)) {
10767
          token.ignoreUndef = true;
10768
        }
10769

    
10770
        _setupUsages(labelName);
10771

    
10772
        if (token) {
10773
          token["(function)"] = _currentFunctBody;
10774
          _current["(usages)"][labelName]["(tokens)"].push(token);
10775
        }
10776
      },
10777

    
10778
      reassign: function(labelName, token) {
10779

    
10780
        this.modify(labelName, token);
10781

    
10782
        _current["(usages)"][labelName]["(reassigned)"].push(token);
10783
      },
10784

    
10785
      modify: function(labelName, token) {
10786

    
10787
        _setupUsages(labelName);
10788

    
10789
        _current["(usages)"][labelName]["(modified)"].push(token);
10790
      },
10791
      add: function(labelName, type, tok, unused) {
10792
        _current["(labels)"][labelName] = {
10793
          "(type)" : type,
10794
          "(token)": tok,
10795
          "(blockscoped)": true,
10796
          "(unused)": unused };
10797
      },
10798

    
10799
      addBreakLabel: function(labelName, opts) {
10800
        var token = opts.token;
10801
        if (scopeManagerInst.funct.hasBreakLabel(labelName)) {
10802
          warning("E011", token, labelName);
10803
        }
10804
        else if (state.option.shadow === "outer") {
10805
          if (scopeManagerInst.funct.has(labelName)) {
10806
            warning("W004", token, labelName);
10807
          } else {
10808
            _checkOuterShadow(labelName, token);
10809
          }
10810
        }
10811
        _current["(breakLabels)"][labelName] = token;
10812
      }
10813
    }
10814
  };
10815
  return scopeManagerInst;
10816
};
10817

    
10818
module.exports = scopeManager;
10819

    
10820
},{"../lodash":"/node_modules/jshint/lodash.js","events":"/node_modules/browserify/node_modules/events/events.js"}],"/node_modules/jshint/src/state.js":[function(_dereq_,module,exports){
10821
"use strict";
10822
var NameStack = _dereq_("./name-stack.js");
10823

    
10824
var state = {
10825
  syntax: {},
10826
  isStrict: function() {
10827
    return this.directive["use strict"] || this.inClassBody ||
10828
      this.option.module || this.option.strict === "implied";
10829
  },
10830

    
10831
  inMoz: function() {
10832
    return this.option.moz;
10833
  },
10834
  inES6: function() {
10835
    return this.option.moz || this.option.esversion >= 6;
10836
  },
10837
  inES5: function(strict) {
10838
    if (strict) {
10839
      return (!this.option.esversion || this.option.esversion === 5) && !this.option.moz;
10840
    }
10841
    return !this.option.esversion || this.option.esversion >= 5 || this.option.moz;
10842
  },
10843

    
10844

    
10845
  reset: function() {
10846
    this.tokens = {
10847
      prev: null,
10848
      next: null,
10849
      curr: null
10850
    };
10851

    
10852
    this.option = {};
10853
    this.funct = null;
10854
    this.ignored = {};
10855
    this.directive = {};
10856
    this.jsonMode = false;
10857
    this.jsonWarnings = [];
10858
    this.lines = [];
10859
    this.tab = "";
10860
    this.cache = {}; // Node.JS doesn't have Map. Sniff.
10861
    this.ignoredLines = {};
10862
    this.forinifcheckneeded = false;
10863
    this.nameStack = new NameStack();
10864
    this.inClassBody = false;
10865
  }
10866
};
10867

    
10868
exports.state = state;
10869

    
10870
},{"./name-stack.js":"/node_modules/jshint/src/name-stack.js"}],"/node_modules/jshint/src/style.js":[function(_dereq_,module,exports){
10871
"use strict";
10872

    
10873
exports.register = function(linter) {
10874

    
10875
  linter.on("Identifier", function style_scanProto(data) {
10876
    if (linter.getOption("proto")) {
10877
      return;
10878
    }
10879

    
10880
    if (data.name === "__proto__") {
10881
      linter.warn("W103", {
10882
        line: data.line,
10883
        char: data.char,
10884
        data: [ data.name, "6" ]
10885
      });
10886
    }
10887
  });
10888

    
10889
  linter.on("Identifier", function style_scanIterator(data) {
10890
    if (linter.getOption("iterator")) {
10891
      return;
10892
    }
10893

    
10894
    if (data.name === "__iterator__") {
10895
      linter.warn("W103", {
10896
        line: data.line,
10897
        char: data.char,
10898
        data: [ data.name ]
10899
      });
10900
    }
10901
  });
10902

    
10903
  linter.on("Identifier", function style_scanCamelCase(data) {
10904
    if (!linter.getOption("camelcase")) {
10905
      return;
10906
    }
10907

    
10908
    if (data.name.replace(/^_+|_+$/g, "").indexOf("_") > -1 && !data.name.match(/^[A-Z0-9_]*$/)) {
10909
      linter.warn("W106", {
10910
        line: data.line,
10911
        char: data.from,
10912
        data: [ data.name ]
10913
      });
10914
    }
10915
  });
10916

    
10917
  linter.on("String", function style_scanQuotes(data) {
10918
    var quotmark = linter.getOption("quotmark");
10919
    var code;
10920

    
10921
    if (!quotmark) {
10922
      return;
10923
    }
10924

    
10925
    if (quotmark === "single" && data.quote !== "'") {
10926
      code = "W109";
10927
    }
10928

    
10929
    if (quotmark === "double" && data.quote !== "\"") {
10930
      code = "W108";
10931
    }
10932

    
10933
    if (quotmark === true) {
10934
      if (!linter.getCache("quotmark")) {
10935
        linter.setCache("quotmark", data.quote);
10936
      }
10937

    
10938
      if (linter.getCache("quotmark") !== data.quote) {
10939
        code = "W110";
10940
      }
10941
    }
10942

    
10943
    if (code) {
10944
      linter.warn(code, {
10945
        line: data.line,
10946
        char: data.char,
10947
      });
10948
    }
10949
  });
10950

    
10951
  linter.on("Number", function style_scanNumbers(data) {
10952
    if (data.value.charAt(0) === ".") {
10953
      linter.warn("W008", {
10954
        line: data.line,
10955
        char: data.char,
10956
        data: [ data.value ]
10957
      });
10958
    }
10959

    
10960
    if (data.value.substr(data.value.length - 1) === ".") {
10961
      linter.warn("W047", {
10962
        line: data.line,
10963
        char: data.char,
10964
        data: [ data.value ]
10965
      });
10966
    }
10967

    
10968
    if (/^00+/.test(data.value)) {
10969
      linter.warn("W046", {
10970
        line: data.line,
10971
        char: data.char,
10972
        data: [ data.value ]
10973
      });
10974
    }
10975
  });
10976

    
10977
  linter.on("String", function style_scanJavaScriptURLs(data) {
10978
    var re = /^(?:javascript|jscript|ecmascript|vbscript|livescript)\s*:/i;
10979

    
10980
    if (linter.getOption("scripturl")) {
10981
      return;
10982
    }
10983

    
10984
    if (re.test(data.value)) {
10985
      linter.warn("W107", {
10986
        line: data.line,
10987
        char: data.char
10988
      });
10989
    }
10990
  });
10991
};
10992

    
10993
},{}],"/node_modules/jshint/src/vars.js":[function(_dereq_,module,exports){
10994

    
10995
"use strict";
10996

    
10997
exports.reservedVars = {
10998
  arguments : false,
10999
  NaN       : false
11000
};
11001

    
11002
exports.ecmaIdentifiers = {
11003
  3: {
11004
    Array              : false,
11005
    Boolean            : false,
11006
    Date               : false,
11007
    decodeURI          : false,
11008
    decodeURIComponent : false,
11009
    encodeURI          : false,
11010
    encodeURIComponent : false,
11011
    Error              : false,
11012
    "eval"             : false,
11013
    EvalError          : false,
11014
    Function           : false,
11015
    hasOwnProperty     : false,
11016
    isFinite           : false,
11017
    isNaN              : false,
11018
    Math               : false,
11019
    Number             : false,
11020
    Object             : false,
11021
    parseInt           : false,
11022
    parseFloat         : false,
11023
    RangeError         : false,
11024
    ReferenceError     : false,
11025
    RegExp             : false,
11026
    String             : false,
11027
    SyntaxError        : false,
11028
    TypeError          : false,
11029
    URIError           : false
11030
  },
11031
  5: {
11032
    JSON               : false
11033
  },
11034
  6: {
11035
    Map                : false,
11036
    Promise            : false,
11037
    Proxy              : false,
11038
    Reflect            : false,
11039
    Set                : false,
11040
    Symbol             : false,
11041
    WeakMap            : false,
11042
    WeakSet            : false
11043
  }
11044
};
11045

    
11046
exports.browser = {
11047
  Audio                : false,
11048
  Blob                 : false,
11049
  addEventListener     : false,
11050
  applicationCache     : false,
11051
  atob                 : false,
11052
  blur                 : false,
11053
  btoa                 : false,
11054
  cancelAnimationFrame : false,
11055
  CanvasGradient       : false,
11056
  CanvasPattern        : false,
11057
  CanvasRenderingContext2D: false,
11058
  CSS                  : false,
11059
  clearInterval        : false,
11060
  clearTimeout         : false,
11061
  close                : false,
11062
  closed               : false,
11063
  Comment              : false,
11064
  CustomEvent          : false,
11065
  DOMParser            : false,
11066
  defaultStatus        : false,
11067
  Document             : false,
11068
  document             : false,
11069
  DocumentFragment     : false,
11070
  Element              : false,
11071
  ElementTimeControl   : false,
11072
  Event                : false,
11073
  event                : false,
11074
  fetch                : false,
11075
  FileReader           : false,
11076
  FormData             : false,
11077
  focus                : false,
11078
  frames               : false,
11079
  getComputedStyle     : false,
11080
  HTMLElement          : false,
11081
  HTMLAnchorElement    : false,
11082
  HTMLBaseElement      : false,
11083
  HTMLBlockquoteElement: false,
11084
  HTMLBodyElement      : false,
11085
  HTMLBRElement        : false,
11086
  HTMLButtonElement    : false,
11087
  HTMLCanvasElement    : false,
11088
  HTMLCollection       : false,
11089
  HTMLDirectoryElement : false,
11090
  HTMLDivElement       : false,
11091
  HTMLDListElement     : false,
11092
  HTMLFieldSetElement  : false,
11093
  HTMLFontElement      : false,
11094
  HTMLFormElement      : false,
11095
  HTMLFrameElement     : false,
11096
  HTMLFrameSetElement  : false,
11097
  HTMLHeadElement      : false,
11098
  HTMLHeadingElement   : false,
11099
  HTMLHRElement        : false,
11100
  HTMLHtmlElement      : false,
11101
  HTMLIFrameElement    : false,
11102
  HTMLImageElement     : false,
11103
  HTMLInputElement     : false,
11104
  HTMLIsIndexElement   : false,
11105
  HTMLLabelElement     : false,
11106
  HTMLLayerElement     : false,
11107
  HTMLLegendElement    : false,
11108
  HTMLLIElement        : false,
11109
  HTMLLinkElement      : false,
11110
  HTMLMapElement       : false,
11111
  HTMLMenuElement      : false,
11112
  HTMLMetaElement      : false,
11113
  HTMLModElement       : false,
11114
  HTMLObjectElement    : false,
11115
  HTMLOListElement     : false,
11116
  HTMLOptGroupElement  : false,
11117
  HTMLOptionElement    : false,
11118
  HTMLParagraphElement : false,
11119
  HTMLParamElement     : false,
11120
  HTMLPreElement       : false,
11121
  HTMLQuoteElement     : false,
11122
  HTMLScriptElement    : false,
11123
  HTMLSelectElement    : false,
11124
  HTMLStyleElement     : false,
11125
  HTMLTableCaptionElement: false,
11126
  HTMLTableCellElement : false,
11127
  HTMLTableColElement  : false,
11128
  HTMLTableElement     : false,
11129
  HTMLTableRowElement  : false,
11130
  HTMLTableSectionElement: false,
11131
  HTMLTemplateElement  : false,
11132
  HTMLTextAreaElement  : false,
11133
  HTMLTitleElement     : false,
11134
  HTMLUListElement     : false,
11135
  HTMLVideoElement     : false,
11136
  history              : false,
11137
  Image                : false,
11138
  Intl                 : false,
11139
  length               : false,
11140
  localStorage         : false,
11141
  location             : false,
11142
  matchMedia           : false,
11143
  MessageChannel       : false,
11144
  MessageEvent         : false,
11145
  MessagePort          : false,
11146
  MouseEvent           : false,
11147
  moveBy               : false,
11148
  moveTo               : false,
11149
  MutationObserver     : false,
11150
  name                 : false,
11151
  Node                 : false,
11152
  NodeFilter           : false,
11153
  NodeList             : false,
11154
  Notification         : false,
11155
  navigator            : false,
11156
  onbeforeunload       : true,
11157
  onblur               : true,
11158
  onerror              : true,
11159
  onfocus              : true,
11160
  onload               : true,
11161
  onresize             : true,
11162
  onunload             : true,
11163
  open                 : false,
11164
  openDatabase         : false,
11165
  opener               : false,
11166
  Option               : false,
11167
  parent               : false,
11168
  performance          : false,
11169
  print                : false,
11170
  Range                : false,
11171
  requestAnimationFrame : false,
11172
  removeEventListener  : false,
11173
  resizeBy             : false,
11174
  resizeTo             : false,
11175
  screen               : false,
11176
  scroll               : false,
11177
  scrollBy             : false,
11178
  scrollTo             : false,
11179
  sessionStorage       : false,
11180
  setInterval          : false,
11181
  setTimeout           : false,
11182
  SharedWorker         : false,
11183
  status               : false,
11184
  SVGAElement          : false,
11185
  SVGAltGlyphDefElement: false,
11186
  SVGAltGlyphElement   : false,
11187
  SVGAltGlyphItemElement: false,
11188
  SVGAngle             : false,
11189
  SVGAnimateColorElement: false,
11190
  SVGAnimateElement    : false,
11191
  SVGAnimateMotionElement: false,
11192
  SVGAnimateTransformElement: false,
11193
  SVGAnimatedAngle     : false,
11194
  SVGAnimatedBoolean   : false,
11195
  SVGAnimatedEnumeration: false,
11196
  SVGAnimatedInteger   : false,
11197
  SVGAnimatedLength    : false,
11198
  SVGAnimatedLengthList: false,
11199
  SVGAnimatedNumber    : false,
11200
  SVGAnimatedNumberList: false,
11201
  SVGAnimatedPathData  : false,
11202
  SVGAnimatedPoints    : false,
11203
  SVGAnimatedPreserveAspectRatio: false,
11204
  SVGAnimatedRect      : false,
11205
  SVGAnimatedString    : false,
11206
  SVGAnimatedTransformList: false,
11207
  SVGAnimationElement  : false,
11208
  SVGCSSRule           : false,
11209
  SVGCircleElement     : false,
11210
  SVGClipPathElement   : false,
11211
  SVGColor             : false,
11212
  SVGColorProfileElement: false,
11213
  SVGColorProfileRule  : false,
11214
  SVGComponentTransferFunctionElement: false,
11215
  SVGCursorElement     : false,
11216
  SVGDefsElement       : false,
11217
  SVGDescElement       : false,
11218
  SVGDocument          : false,
11219
  SVGElement           : false,
11220
  SVGElementInstance   : false,
11221
  SVGElementInstanceList: false,
11222
  SVGEllipseElement    : false,
11223
  SVGExternalResourcesRequired: false,
11224
  SVGFEBlendElement    : false,
11225
  SVGFEColorMatrixElement: false,
11226
  SVGFEComponentTransferElement: false,
11227
  SVGFECompositeElement: false,
11228
  SVGFEConvolveMatrixElement: false,
11229
  SVGFEDiffuseLightingElement: false,
11230
  SVGFEDisplacementMapElement: false,
11231
  SVGFEDistantLightElement: false,
11232
  SVGFEFloodElement    : false,
11233
  SVGFEFuncAElement    : false,
11234
  SVGFEFuncBElement    : false,
11235
  SVGFEFuncGElement    : false,
11236
  SVGFEFuncRElement    : false,
11237
  SVGFEGaussianBlurElement: false,
11238
  SVGFEImageElement    : false,
11239
  SVGFEMergeElement    : false,
11240
  SVGFEMergeNodeElement: false,
11241
  SVGFEMorphologyElement: false,
11242
  SVGFEOffsetElement   : false,
11243
  SVGFEPointLightElement: false,
11244
  SVGFESpecularLightingElement: false,
11245
  SVGFESpotLightElement: false,
11246
  SVGFETileElement     : false,
11247
  SVGFETurbulenceElement: false,
11248
  SVGFilterElement     : false,
11249
  SVGFilterPrimitiveStandardAttributes: false,
11250
  SVGFitToViewBox      : false,
11251
  SVGFontElement       : false,
11252
  SVGFontFaceElement   : false,
11253
  SVGFontFaceFormatElement: false,
11254
  SVGFontFaceNameElement: false,
11255
  SVGFontFaceSrcElement: false,
11256
  SVGFontFaceUriElement: false,
11257
  SVGForeignObjectElement: false,
11258
  SVGGElement          : false,
11259
  SVGGlyphElement      : false,
11260
  SVGGlyphRefElement   : false,
11261
  SVGGradientElement   : false,
11262
  SVGHKernElement      : false,
11263
  SVGICCColor          : false,
11264
  SVGImageElement      : false,
11265
  SVGLangSpace         : false,
11266
  SVGLength            : false,
11267
  SVGLengthList        : false,
11268
  SVGLineElement       : false,
11269
  SVGLinearGradientElement: false,
11270
  SVGLocatable         : false,
11271
  SVGMPathElement      : false,
11272
  SVGMarkerElement     : false,
11273
  SVGMaskElement       : false,
11274
  SVGMatrix            : false,
11275
  SVGMetadataElement   : false,
11276
  SVGMissingGlyphElement: false,
11277
  SVGNumber            : false,
11278
  SVGNumberList        : false,
11279
  SVGPaint             : false,
11280
  SVGPathElement       : false,
11281
  SVGPathSeg           : false,
11282
  SVGPathSegArcAbs     : false,
11283
  SVGPathSegArcRel     : false,
11284
  SVGPathSegClosePath  : false,
11285
  SVGPathSegCurvetoCubicAbs: false,
11286
  SVGPathSegCurvetoCubicRel: false,
11287
  SVGPathSegCurvetoCubicSmoothAbs: false,
11288
  SVGPathSegCurvetoCubicSmoothRel: false,
11289
  SVGPathSegCurvetoQuadraticAbs: false,
11290
  SVGPathSegCurvetoQuadraticRel: false,
11291
  SVGPathSegCurvetoQuadraticSmoothAbs: false,
11292
  SVGPathSegCurvetoQuadraticSmoothRel: false,
11293
  SVGPathSegLinetoAbs  : false,
11294
  SVGPathSegLinetoHorizontalAbs: false,
11295
  SVGPathSegLinetoHorizontalRel: false,
11296
  SVGPathSegLinetoRel  : false,
11297
  SVGPathSegLinetoVerticalAbs: false,
11298
  SVGPathSegLinetoVerticalRel: false,
11299
  SVGPathSegList       : false,
11300
  SVGPathSegMovetoAbs  : false,
11301
  SVGPathSegMovetoRel  : false,
11302
  SVGPatternElement    : false,
11303
  SVGPoint             : false,
11304
  SVGPointList         : false,
11305
  SVGPolygonElement    : false,
11306
  SVGPolylineElement   : false,
11307
  SVGPreserveAspectRatio: false,
11308
  SVGRadialGradientElement: false,
11309
  SVGRect              : false,
11310
  SVGRectElement       : false,
11311
  SVGRenderingIntent   : false,
11312
  SVGSVGElement        : false,
11313
  SVGScriptElement     : false,
11314
  SVGSetElement        : false,
11315
  SVGStopElement       : false,
11316
  SVGStringList        : false,
11317
  SVGStylable          : false,
11318
  SVGStyleElement      : false,
11319
  SVGSwitchElement     : false,
11320
  SVGSymbolElement     : false,
11321
  SVGTRefElement       : false,
11322
  SVGTSpanElement      : false,
11323
  SVGTests             : false,
11324
  SVGTextContentElement: false,
11325
  SVGTextElement       : false,
11326
  SVGTextPathElement   : false,
11327
  SVGTextPositioningElement: false,
11328
  SVGTitleElement      : false,
11329
  SVGTransform         : false,
11330
  SVGTransformList     : false,
11331
  SVGTransformable     : false,
11332
  SVGURIReference      : false,
11333
  SVGUnitTypes         : false,
11334
  SVGUseElement        : false,
11335
  SVGVKernElement      : false,
11336
  SVGViewElement       : false,
11337
  SVGViewSpec          : false,
11338
  SVGZoomAndPan        : false,
11339
  Text                 : false,
11340
  TextDecoder          : false,
11341
  TextEncoder          : false,
11342
  TimeEvent            : false,
11343
  top                  : false,
11344
  URL                  : false,
11345
  WebGLActiveInfo      : false,
11346
  WebGLBuffer          : false,
11347
  WebGLContextEvent    : false,
11348
  WebGLFramebuffer     : false,
11349
  WebGLProgram         : false,
11350
  WebGLRenderbuffer    : false,
11351
  WebGLRenderingContext: false,
11352
  WebGLShader          : false,
11353
  WebGLShaderPrecisionFormat: false,
11354
  WebGLTexture         : false,
11355
  WebGLUniformLocation : false,
11356
  WebSocket            : false,
11357
  window               : false,
11358
  Window               : false,
11359
  Worker               : false,
11360
  XDomainRequest       : false,
11361
  XMLHttpRequest       : false,
11362
  XMLSerializer        : false,
11363
  XPathEvaluator       : false,
11364
  XPathException       : false,
11365
  XPathExpression      : false,
11366
  XPathNamespace       : false,
11367
  XPathNSResolver      : false,
11368
  XPathResult          : false
11369
};
11370

    
11371
exports.devel = {
11372
  alert  : false,
11373
  confirm: false,
11374
  console: false,
11375
  Debug  : false,
11376
  opera  : false,
11377
  prompt : false
11378
};
11379

    
11380
exports.worker = {
11381
  importScripts  : true,
11382
  postMessage    : true,
11383
  self           : true,
11384
  FileReaderSync : true
11385
};
11386
exports.nonstandard = {
11387
  escape  : false,
11388
  unescape: false
11389
};
11390

    
11391
exports.couch = {
11392
  "require" : false,
11393
  respond   : false,
11394
  getRow    : false,
11395
  emit      : false,
11396
  send      : false,
11397
  start     : false,
11398
  sum       : false,
11399
  log       : false,
11400
  exports   : false,
11401
  module    : false,
11402
  provides  : false
11403
};
11404

    
11405
exports.node = {
11406
  __filename    : false,
11407
  __dirname     : false,
11408
  GLOBAL        : false,
11409
  global        : false,
11410
  module        : false,
11411
  require       : false,
11412

    
11413
  Buffer        : true,
11414
  console       : true,
11415
  exports       : true,
11416
  process       : true,
11417
  setTimeout    : true,
11418
  clearTimeout  : true,
11419
  setInterval   : true,
11420
  clearInterval : true,
11421
  setImmediate  : true, // v0.9.1+
11422
  clearImmediate: true  // v0.9.1+
11423
};
11424

    
11425
exports.browserify = {
11426
  __filename    : false,
11427
  __dirname     : false,
11428
  global        : false,
11429
  module        : false,
11430
  require       : false,
11431
  Buffer        : true,
11432
  exports       : true,
11433
  process       : true
11434
};
11435

    
11436
exports.phantom = {
11437
  phantom      : true,
11438
  require      : true,
11439
  WebPage      : true,
11440
  console      : true, // in examples, but undocumented
11441
  exports      : true  // v1.7+
11442
};
11443

    
11444
exports.qunit = {
11445
  asyncTest      : false,
11446
  deepEqual      : false,
11447
  equal          : false,
11448
  expect         : false,
11449
  module         : false,
11450
  notDeepEqual   : false,
11451
  notEqual       : false,
11452
  notPropEqual   : false,
11453
  notStrictEqual : false,
11454
  ok             : false,
11455
  propEqual      : false,
11456
  QUnit          : false,
11457
  raises         : false,
11458
  start          : false,
11459
  stop           : false,
11460
  strictEqual    : false,
11461
  test           : false,
11462
  "throws"       : false
11463
};
11464

    
11465
exports.rhino = {
11466
  defineClass  : false,
11467
  deserialize  : false,
11468
  gc           : false,
11469
  help         : false,
11470
  importClass  : false,
11471
  importPackage: false,
11472
  "java"       : false,
11473
  load         : false,
11474
  loadClass    : false,
11475
  Packages     : false,
11476
  print        : false,
11477
  quit         : false,
11478
  readFile     : false,
11479
  readUrl      : false,
11480
  runCommand   : false,
11481
  seal         : false,
11482
  serialize    : false,
11483
  spawn        : false,
11484
  sync         : false,
11485
  toint32      : false,
11486
  version      : false
11487
};
11488

    
11489
exports.shelljs = {
11490
  target       : false,
11491
  echo         : false,
11492
  exit         : false,
11493
  cd           : false,
11494
  pwd          : false,
11495
  ls           : false,
11496
  find         : false,
11497
  cp           : false,
11498
  rm           : false,
11499
  mv           : false,
11500
  mkdir        : false,
11501
  test         : false,
11502
  cat          : false,
11503
  sed          : false,
11504
  grep         : false,
11505
  which        : false,
11506
  dirs         : false,
11507
  pushd        : false,
11508
  popd         : false,
11509
  env          : false,
11510
  exec         : false,
11511
  chmod        : false,
11512
  config       : false,
11513
  error        : false,
11514
  tempdir      : false
11515
};
11516

    
11517
exports.typed = {
11518
  ArrayBuffer         : false,
11519
  ArrayBufferView     : false,
11520
  DataView            : false,
11521
  Float32Array        : false,
11522
  Float64Array        : false,
11523
  Int16Array          : false,
11524
  Int32Array          : false,
11525
  Int8Array           : false,
11526
  Uint16Array         : false,
11527
  Uint32Array         : false,
11528
  Uint8Array          : false,
11529
  Uint8ClampedArray   : false
11530
};
11531

    
11532
exports.wsh = {
11533
  ActiveXObject            : true,
11534
  Enumerator               : true,
11535
  GetObject                : true,
11536
  ScriptEngine             : true,
11537
  ScriptEngineBuildVersion : true,
11538
  ScriptEngineMajorVersion : true,
11539
  ScriptEngineMinorVersion : true,
11540
  VBArray                  : true,
11541
  WSH                      : true,
11542
  WScript                  : true,
11543
  XDomainRequest           : true
11544
};
11545

    
11546
exports.dojo = {
11547
  dojo     : false,
11548
  dijit    : false,
11549
  dojox    : false,
11550
  define   : false,
11551
  "require": false
11552
};
11553

    
11554
exports.jquery = {
11555
  "$"    : false,
11556
  jQuery : false
11557
};
11558

    
11559
exports.mootools = {
11560
  "$"           : false,
11561
  "$$"          : false,
11562
  Asset         : false,
11563
  Browser       : false,
11564
  Chain         : false,
11565
  Class         : false,
11566
  Color         : false,
11567
  Cookie        : false,
11568
  Core          : false,
11569
  Document      : false,
11570
  DomReady      : false,
11571
  DOMEvent      : false,
11572
  DOMReady      : false,
11573
  Drag          : false,
11574
  Element       : false,
11575
  Elements      : false,
11576
  Event         : false,
11577
  Events        : false,
11578
  Fx            : false,
11579
  Group         : false,
11580
  Hash          : false,
11581
  HtmlTable     : false,
11582
  IFrame        : false,
11583
  IframeShim    : false,
11584
  InputValidator: false,
11585
  instanceOf    : false,
11586
  Keyboard      : false,
11587
  Locale        : false,
11588
  Mask          : false,
11589
  MooTools      : false,
11590
  Native        : false,
11591
  Options       : false,
11592
  OverText      : false,
11593
  Request       : false,
11594
  Scroller      : false,
11595
  Slick         : false,
11596
  Slider        : false,
11597
  Sortables     : false,
11598
  Spinner       : false,
11599
  Swiff         : false,
11600
  Tips          : false,
11601
  Type          : false,
11602
  typeOf        : false,
11603
  URI           : false,
11604
  Window        : false
11605
};
11606

    
11607
exports.prototypejs = {
11608
  "$"               : false,
11609
  "$$"              : false,
11610
  "$A"              : false,
11611
  "$F"              : false,
11612
  "$H"              : false,
11613
  "$R"              : false,
11614
  "$break"          : false,
11615
  "$continue"       : false,
11616
  "$w"              : false,
11617
  Abstract          : false,
11618
  Ajax              : false,
11619
  Class             : false,
11620
  Enumerable        : false,
11621
  Element           : false,
11622
  Event             : false,
11623
  Field             : false,
11624
  Form              : false,
11625
  Hash              : false,
11626
  Insertion         : false,
11627
  ObjectRange       : false,
11628
  PeriodicalExecuter: false,
11629
  Position          : false,
11630
  Prototype         : false,
11631
  Selector          : false,
11632
  Template          : false,
11633
  Toggle            : false,
11634
  Try               : false,
11635
  Autocompleter     : false,
11636
  Builder           : false,
11637
  Control           : false,
11638
  Draggable         : false,
11639
  Draggables        : false,
11640
  Droppables        : false,
11641
  Effect            : false,
11642
  Sortable          : false,
11643
  SortableObserver  : false,
11644
  Sound             : false,
11645
  Scriptaculous     : false
11646
};
11647

    
11648
exports.yui = {
11649
  YUI       : false,
11650
  Y         : false,
11651
  YUI_config: false
11652
};
11653

    
11654
exports.mocha = {
11655
  mocha       : false,
11656
  describe    : false,
11657
  xdescribe   : false,
11658
  it          : false,
11659
  xit         : false,
11660
  context     : false,
11661
  xcontext    : false,
11662
  before      : false,
11663
  after       : false,
11664
  beforeEach  : false,
11665
  afterEach   : false,
11666
  suite         : false,
11667
  test          : false,
11668
  setup         : false,
11669
  teardown      : false,
11670
  suiteSetup    : false,
11671
  suiteTeardown : false
11672
};
11673

    
11674
exports.jasmine = {
11675
  jasmine     : false,
11676
  describe    : false,
11677
  xdescribe   : false,
11678
  it          : false,
11679
  xit         : false,
11680
  beforeEach  : false,
11681
  afterEach   : false,
11682
  setFixtures : false,
11683
  loadFixtures: false,
11684
  spyOn       : false,
11685
  expect      : false,
11686
  runs        : false,
11687
  waitsFor    : false,
11688
  waits       : false,
11689
  beforeAll   : false,
11690
  afterAll    : false,
11691
  fail        : false,
11692
  fdescribe   : false,
11693
  fit         : false,
11694
  pending     : false
11695
};
11696

    
11697
},{}]},{},["/node_modules/jshint/src/jshint.js"]);
11698

    
11699
});
11700

    
11701
ace.define("ace/mode/javascript_worker",[], function(require, exports, module) {
11702
"use strict";
11703

    
11704
var oop = require("../lib/oop");
11705
var Mirror = require("../worker/mirror").Mirror;
11706
var lint = require("./javascript/jshint").JSHINT;
11707

    
11708
function startRegex(arr) {
11709
    return RegExp("^(" + arr.join("|") + ")");
11710
}
11711

    
11712
var disabledWarningsRe = startRegex([
11713
    "Bad for in variable '(.+)'.",
11714
    'Missing "use strict"'
11715
]);
11716
var errorsRe = startRegex([
11717
    "Unexpected",
11718
    "Expected ",
11719
    "Confusing (plus|minus)",
11720
    "\\{a\\} unterminated regular expression",
11721
    "Unclosed ",
11722
    "Unmatched ",
11723
    "Unbegun comment",
11724
    "Bad invocation",
11725
    "Missing space after",
11726
    "Missing operator at"
11727
]);
11728
var infoRe = startRegex([
11729
    "Expected an assignment",
11730
    "Bad escapement of EOL",
11731
    "Unexpected comma",
11732
    "Unexpected space",
11733
    "Missing radix parameter.",
11734
    "A leading decimal point can",
11735
    "\\['{a}'\\] is better written in dot notation.",
11736
    "'{a}' used out of scope"
11737
]);
11738

    
11739
var JavaScriptWorker = exports.JavaScriptWorker = function(sender) {
11740
    Mirror.call(this, sender);
11741
    this.setTimeout(500);
11742
    this.setOptions();
11743
};
11744

    
11745
oop.inherits(JavaScriptWorker, Mirror);
11746

    
11747
(function() {
11748
    this.setOptions = function(options) {
11749
        this.options = options || {
11750
            esnext: true,
11751
            moz: true,
11752
            devel: true,
11753
            browser: true,
11754
            node: true,
11755
            laxcomma: true,
11756
            laxbreak: true,
11757
            lastsemic: true,
11758
            onevar: false,
11759
            passfail: false,
11760
            maxerr: 100,
11761
            expr: true,
11762
            multistr: true,
11763
            globalstrict: true
11764
        };
11765
        this.doc.getValue() && this.deferredUpdate.schedule(100);
11766
    };
11767

    
11768
    this.changeOptions = function(newOptions) {
11769
        oop.mixin(this.options, newOptions);
11770
        this.doc.getValue() && this.deferredUpdate.schedule(100);
11771
    };
11772

    
11773
    this.isValidJS = function(str) {
11774
        try {
11775
            eval("throw 0;" + str);
11776
        } catch(e) {
11777
            if (e === 0)
11778
                return true;
11779
        }
11780
        return false;
11781
    };
11782

    
11783
    this.onUpdate = function() {
11784
        var value = this.doc.getValue();
11785
        value = value.replace(/^#!.*\n/, "\n");
11786
        if (!value)
11787
            return this.sender.emit("annotate", []);
11788

    
11789
        var errors = [];
11790
        var maxErrorLevel = this.isValidJS(value) ? "warning" : "error";
11791
        lint(value, this.options, this.options.globals);
11792
        var results = lint.errors;
11793

    
11794
        var errorAdded = false;
11795
        for (var i = 0; i < results.length; i++) {
11796
            var error = results[i];
11797
            if (!error)
11798
                continue;
11799
            var raw = error.raw;
11800
            var type = "warning";
11801

    
11802
            if (raw == "Missing semicolon.") {
11803
                var str = error.evidence.substr(error.character);
11804
                str = str.charAt(str.search(/\S/));
11805
                if (maxErrorLevel == "error" && str && /[\w\d{(['"]/.test(str)) {
11806
                    error.reason = 'Missing ";" before statement';
11807
                    type = "error";
11808
                } else {
11809
                    type = "info";
11810
                }
11811
            }
11812
            else if (disabledWarningsRe.test(raw)) {
11813
                continue;
11814
            }
11815
            else if (infoRe.test(raw)) {
11816
                type = "info";
11817
            }
11818
            else if (errorsRe.test(raw)) {
11819
                errorAdded  = true;
11820
                type = maxErrorLevel;
11821
            }
11822
            else if (raw == "'{a}' is not defined.") {
11823
                type = "warning";
11824
            }
11825
            else if (raw == "'{a}' is defined but never used.") {
11826
                type = "info";
11827
            }
11828

    
11829
            errors.push({
11830
                row: error.line-1,
11831
                column: error.character-1,
11832
                text: error.reason,
11833
                type: type,
11834
                raw: raw
11835
            });
11836

    
11837
            if (errorAdded) {
11838
            }
11839
        }
11840

    
11841
        this.sender.emit("annotate", errors);
11842
    };
11843

    
11844
}).call(JavaScriptWorker.prototype);
11845

    
11846
});
11847

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

    
11850
function Empty() {}
11851

    
11852
if (!Function.prototype.bind) {
11853
    Function.prototype.bind = function bind(that) { // .length is 1
11854
        var target = this;
11855
        if (typeof target != "function") {
11856
            throw new TypeError("Function.prototype.bind called on incompatible " + target);
11857
        }
11858
        var args = slice.call(arguments, 1); // for normal call
11859
        var bound = function () {
11860

    
11861
            if (this instanceof bound) {
11862

    
11863
                var result = target.apply(
11864
                    this,
11865
                    args.concat(slice.call(arguments))
11866
                );
11867
                if (Object(result) === result) {
11868
                    return result;
11869
                }
11870
                return this;
11871

    
11872
            } else {
11873
                return target.apply(
11874
                    that,
11875
                    args.concat(slice.call(arguments))
11876
                );
11877

    
11878
            }
11879

    
11880
        };
11881
        if(target.prototype) {
11882
            Empty.prototype = target.prototype;
11883
            bound.prototype = new Empty();
11884
            Empty.prototype = null;
11885
        }
11886
        return bound;
11887
    };
11888
}
11889
var call = Function.prototype.call;
11890
var prototypeOfArray = Array.prototype;
11891
var prototypeOfObject = Object.prototype;
11892
var slice = prototypeOfArray.slice;
11893
var _toString = call.bind(prototypeOfObject.toString);
11894
var owns = call.bind(prototypeOfObject.hasOwnProperty);
11895
var defineGetter;
11896
var defineSetter;
11897
var lookupGetter;
11898
var lookupSetter;
11899
var supportsAccessors;
11900
if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
11901
    defineGetter = call.bind(prototypeOfObject.__defineGetter__);
11902
    defineSetter = call.bind(prototypeOfObject.__defineSetter__);
11903
    lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
11904
    lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
11905
}
11906
if ([1,2].splice(0).length != 2) {
11907
    if(function() { // test IE < 9 to splice bug - see issue #138
11908
        function makeArray(l) {
11909
            var a = new Array(l+2);
11910
            a[0] = a[1] = 0;
11911
            return a;
11912
        }
11913
        var array = [], lengthBefore;
11914
        
11915
        array.splice.apply(array, makeArray(20));
11916
        array.splice.apply(array, makeArray(26));
11917

    
11918
        lengthBefore = array.length; //46
11919
        array.splice(5, 0, "XXX"); // add one element
11920

    
11921
        lengthBefore + 1 == array.length
11922

    
11923
        if (lengthBefore + 1 == array.length) {
11924
            return true;// has right splice implementation without bugs
11925
        }
11926
    }()) {//IE 6/7
11927
        var array_splice = Array.prototype.splice;
11928
        Array.prototype.splice = function(start, deleteCount) {
11929
            if (!arguments.length) {
11930
                return [];
11931
            } else {
11932
                return array_splice.apply(this, [
11933
                    start === void 0 ? 0 : start,
11934
                    deleteCount === void 0 ? (this.length - start) : deleteCount
11935
                ].concat(slice.call(arguments, 2)))
11936
            }
11937
        };
11938
    } else {//IE8
11939
        Array.prototype.splice = function(pos, removeCount){
11940
            var length = this.length;
11941
            if (pos > 0) {
11942
                if (pos > length)
11943
                    pos = length;
11944
            } else if (pos == void 0) {
11945
                pos = 0;
11946
            } else if (pos < 0) {
11947
                pos = Math.max(length + pos, 0);
11948
            }
11949

    
11950
            if (!(pos+removeCount < length))
11951
                removeCount = length - pos;
11952

    
11953
            var removed = this.slice(pos, pos+removeCount);
11954
            var insert = slice.call(arguments, 2);
11955
            var add = insert.length;            
11956
            if (pos === length) {
11957
                if (add) {
11958
                    this.push.apply(this, insert);
11959
                }
11960
            } else {
11961
                var remove = Math.min(removeCount, length - pos);
11962
                var tailOldPos = pos + remove;
11963
                var tailNewPos = tailOldPos + add - remove;
11964
                var tailCount = length - tailOldPos;
11965
                var lengthAfterRemove = length - remove;
11966

    
11967
                if (tailNewPos < tailOldPos) { // case A
11968
                    for (var i = 0; i < tailCount; ++i) {
11969
                        this[tailNewPos+i] = this[tailOldPos+i];
11970
                    }
11971
                } else if (tailNewPos > tailOldPos) { // case B
11972
                    for (i = tailCount; i--; ) {
11973
                        this[tailNewPos+i] = this[tailOldPos+i];
11974
                    }
11975
                } // else, add == remove (nothing to do)
11976

    
11977
                if (add && pos === lengthAfterRemove) {
11978
                    this.length = lengthAfterRemove; // truncate array
11979
                    this.push.apply(this, insert);
11980
                } else {
11981
                    this.length = lengthAfterRemove + add; // reserves space
11982
                    for (i = 0; i < add; ++i) {
11983
                        this[pos+i] = insert[i];
11984
                    }
11985
                }
11986
            }
11987
            return removed;
11988
        };
11989
    }
11990
}
11991
if (!Array.isArray) {
11992
    Array.isArray = function isArray(obj) {
11993
        return _toString(obj) == "[object Array]";
11994
    };
11995
}
11996
var boxedString = Object("a"),
11997
    splitString = boxedString[0] != "a" || !(0 in boxedString);
11998

    
11999
if (!Array.prototype.forEach) {
12000
    Array.prototype.forEach = function forEach(fun /*, thisp*/) {
12001
        var object = toObject(this),
12002
            self = splitString && _toString(this) == "[object String]" ?
12003
                this.split("") :
12004
                object,
12005
            thisp = arguments[1],
12006
            i = -1,
12007
            length = self.length >>> 0;
12008
        if (_toString(fun) != "[object Function]") {
12009
            throw new TypeError(); // TODO message
12010
        }
12011

    
12012
        while (++i < length) {
12013
            if (i in self) {
12014
                fun.call(thisp, self[i], i, object);
12015
            }
12016
        }
12017
    };
12018
}
12019
if (!Array.prototype.map) {
12020
    Array.prototype.map = function map(fun /*, thisp*/) {
12021
        var object = toObject(this),
12022
            self = splitString && _toString(this) == "[object String]" ?
12023
                this.split("") :
12024
                object,
12025
            length = self.length >>> 0,
12026
            result = Array(length),
12027
            thisp = arguments[1];
12028
        if (_toString(fun) != "[object Function]") {
12029
            throw new TypeError(fun + " is not a function");
12030
        }
12031

    
12032
        for (var i = 0; i < length; i++) {
12033
            if (i in self)
12034
                result[i] = fun.call(thisp, self[i], i, object);
12035
        }
12036
        return result;
12037
    };
12038
}
12039
if (!Array.prototype.filter) {
12040
    Array.prototype.filter = function filter(fun /*, thisp */) {
12041
        var object = toObject(this),
12042
            self = splitString && _toString(this) == "[object String]" ?
12043
                this.split("") :
12044
                    object,
12045
            length = self.length >>> 0,
12046
            result = [],
12047
            value,
12048
            thisp = arguments[1];
12049
        if (_toString(fun) != "[object Function]") {
12050
            throw new TypeError(fun + " is not a function");
12051
        }
12052

    
12053
        for (var i = 0; i < length; i++) {
12054
            if (i in self) {
12055
                value = self[i];
12056
                if (fun.call(thisp, value, i, object)) {
12057
                    result.push(value);
12058
                }
12059
            }
12060
        }
12061
        return result;
12062
    };
12063
}
12064
if (!Array.prototype.every) {
12065
    Array.prototype.every = function every(fun /*, thisp */) {
12066
        var object = toObject(this),
12067
            self = splitString && _toString(this) == "[object String]" ?
12068
                this.split("") :
12069
                object,
12070
            length = self.length >>> 0,
12071
            thisp = arguments[1];
12072
        if (_toString(fun) != "[object Function]") {
12073
            throw new TypeError(fun + " is not a function");
12074
        }
12075

    
12076
        for (var i = 0; i < length; i++) {
12077
            if (i in self && !fun.call(thisp, self[i], i, object)) {
12078
                return false;
12079
            }
12080
        }
12081
        return true;
12082
    };
12083
}
12084
if (!Array.prototype.some) {
12085
    Array.prototype.some = function some(fun /*, thisp */) {
12086
        var object = toObject(this),
12087
            self = splitString && _toString(this) == "[object String]" ?
12088
                this.split("") :
12089
                object,
12090
            length = self.length >>> 0,
12091
            thisp = arguments[1];
12092
        if (_toString(fun) != "[object Function]") {
12093
            throw new TypeError(fun + " is not a function");
12094
        }
12095

    
12096
        for (var i = 0; i < length; i++) {
12097
            if (i in self && fun.call(thisp, self[i], i, object)) {
12098
                return true;
12099
            }
12100
        }
12101
        return false;
12102
    };
12103
}
12104
if (!Array.prototype.reduce) {
12105
    Array.prototype.reduce = function reduce(fun /*, initial*/) {
12106
        var object = toObject(this),
12107
            self = splitString && _toString(this) == "[object String]" ?
12108
                this.split("") :
12109
                object,
12110
            length = self.length >>> 0;
12111
        if (_toString(fun) != "[object Function]") {
12112
            throw new TypeError(fun + " is not a function");
12113
        }
12114
        if (!length && arguments.length == 1) {
12115
            throw new TypeError("reduce of empty array with no initial value");
12116
        }
12117

    
12118
        var i = 0;
12119
        var result;
12120
        if (arguments.length >= 2) {
12121
            result = arguments[1];
12122
        } else {
12123
            do {
12124
                if (i in self) {
12125
                    result = self[i++];
12126
                    break;
12127
                }
12128
                if (++i >= length) {
12129
                    throw new TypeError("reduce of empty array with no initial value");
12130
                }
12131
            } while (true);
12132
        }
12133

    
12134
        for (; i < length; i++) {
12135
            if (i in self) {
12136
                result = fun.call(void 0, result, self[i], i, object);
12137
            }
12138
        }
12139

    
12140
        return result;
12141
    };
12142
}
12143
if (!Array.prototype.reduceRight) {
12144
    Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
12145
        var object = toObject(this),
12146
            self = splitString && _toString(this) == "[object String]" ?
12147
                this.split("") :
12148
                object,
12149
            length = self.length >>> 0;
12150
        if (_toString(fun) != "[object Function]") {
12151
            throw new TypeError(fun + " is not a function");
12152
        }
12153
        if (!length && arguments.length == 1) {
12154
            throw new TypeError("reduceRight of empty array with no initial value");
12155
        }
12156

    
12157
        var result, i = length - 1;
12158
        if (arguments.length >= 2) {
12159
            result = arguments[1];
12160
        } else {
12161
            do {
12162
                if (i in self) {
12163
                    result = self[i--];
12164
                    break;
12165
                }
12166
                if (--i < 0) {
12167
                    throw new TypeError("reduceRight of empty array with no initial value");
12168
                }
12169
            } while (true);
12170
        }
12171

    
12172
        do {
12173
            if (i in this) {
12174
                result = fun.call(void 0, result, self[i], i, object);
12175
            }
12176
        } while (i--);
12177

    
12178
        return result;
12179
    };
12180
}
12181
if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) {
12182
    Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
12183
        var self = splitString && _toString(this) == "[object String]" ?
12184
                this.split("") :
12185
                toObject(this),
12186
            length = self.length >>> 0;
12187

    
12188
        if (!length) {
12189
            return -1;
12190
        }
12191

    
12192
        var i = 0;
12193
        if (arguments.length > 1) {
12194
            i = toInteger(arguments[1]);
12195
        }
12196
        i = i >= 0 ? i : Math.max(0, length + i);
12197
        for (; i < length; i++) {
12198
            if (i in self && self[i] === sought) {
12199
                return i;
12200
            }
12201
        }
12202
        return -1;
12203
    };
12204
}
12205
if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) {
12206
    Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
12207
        var self = splitString && _toString(this) == "[object String]" ?
12208
                this.split("") :
12209
                toObject(this),
12210
            length = self.length >>> 0;
12211

    
12212
        if (!length) {
12213
            return -1;
12214
        }
12215
        var i = length - 1;
12216
        if (arguments.length > 1) {
12217
            i = Math.min(i, toInteger(arguments[1]));
12218
        }
12219
        i = i >= 0 ? i : length - Math.abs(i);
12220
        for (; i >= 0; i--) {
12221
            if (i in self && sought === self[i]) {
12222
                return i;
12223
            }
12224
        }
12225
        return -1;
12226
    };
12227
}
12228
if (!Object.getPrototypeOf) {
12229
    Object.getPrototypeOf = function getPrototypeOf(object) {
12230
        return object.__proto__ || (
12231
            object.constructor ?
12232
            object.constructor.prototype :
12233
            prototypeOfObject
12234
        );
12235
    };
12236
}
12237
if (!Object.getOwnPropertyDescriptor) {
12238
    var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " +
12239
                         "non-object: ";
12240
    Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
12241
        if ((typeof object != "object" && typeof object != "function") || object === null)
12242
            throw new TypeError(ERR_NON_OBJECT + object);
12243
        if (!owns(object, property))
12244
            return;
12245

    
12246
        var descriptor, getter, setter;
12247
        descriptor =  { enumerable: true, configurable: true };
12248
        if (supportsAccessors) {
12249
            var prototype = object.__proto__;
12250
            object.__proto__ = prototypeOfObject;
12251

    
12252
            var getter = lookupGetter(object, property);
12253
            var setter = lookupSetter(object, property);
12254
            object.__proto__ = prototype;
12255

    
12256
            if (getter || setter) {
12257
                if (getter) descriptor.get = getter;
12258
                if (setter) descriptor.set = setter;
12259
                return descriptor;
12260
            }
12261
        }
12262
        descriptor.value = object[property];
12263
        return descriptor;
12264
    };
12265
}
12266
if (!Object.getOwnPropertyNames) {
12267
    Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
12268
        return Object.keys(object);
12269
    };
12270
}
12271
if (!Object.create) {
12272
    var createEmpty;
12273
    if (Object.prototype.__proto__ === null) {
12274
        createEmpty = function () {
12275
            return { "__proto__": null };
12276
        };
12277
    } else {
12278
        createEmpty = function () {
12279
            var empty = {};
12280
            for (var i in empty)
12281
                empty[i] = null;
12282
            empty.constructor =
12283
            empty.hasOwnProperty =
12284
            empty.propertyIsEnumerable =
12285
            empty.isPrototypeOf =
12286
            empty.toLocaleString =
12287
            empty.toString =
12288
            empty.valueOf =
12289
            empty.__proto__ = null;
12290
            return empty;
12291
        }
12292
    }
12293

    
12294
    Object.create = function create(prototype, properties) {
12295
        var object;
12296
        if (prototype === null) {
12297
            object = createEmpty();
12298
        } else {
12299
            if (typeof prototype != "object")
12300
                throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'");
12301
            var Type = function () {};
12302
            Type.prototype = prototype;
12303
            object = new Type();
12304
            object.__proto__ = prototype;
12305
        }
12306
        if (properties !== void 0)
12307
            Object.defineProperties(object, properties);
12308
        return object;
12309
    };
12310
}
12311

    
12312
function doesDefinePropertyWork(object) {
12313
    try {
12314
        Object.defineProperty(object, "sentinel", {});
12315
        return "sentinel" in object;
12316
    } catch (exception) {
12317
    }
12318
}
12319
if (Object.defineProperty) {
12320
    var definePropertyWorksOnObject = doesDefinePropertyWork({});
12321
    var definePropertyWorksOnDom = typeof document == "undefined" ||
12322
        doesDefinePropertyWork(document.createElement("div"));
12323
    if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
12324
        var definePropertyFallback = Object.defineProperty;
12325
    }
12326
}
12327

    
12328
if (!Object.defineProperty || definePropertyFallback) {
12329
    var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
12330
    var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: "
12331
    var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " +
12332
                                      "on this javascript engine";
12333

    
12334
    Object.defineProperty = function defineProperty(object, property, descriptor) {
12335
        if ((typeof object != "object" && typeof object != "function") || object === null)
12336
            throw new TypeError(ERR_NON_OBJECT_TARGET + object);
12337
        if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null)
12338
            throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
12339
        if (definePropertyFallback) {
12340
            try {
12341
                return definePropertyFallback.call(Object, object, property, descriptor);
12342
            } catch (exception) {
12343
            }
12344
        }
12345
        if (owns(descriptor, "value")) {
12346

    
12347
            if (supportsAccessors && (lookupGetter(object, property) ||
12348
                                      lookupSetter(object, property)))
12349
            {
12350
                var prototype = object.__proto__;
12351
                object.__proto__ = prototypeOfObject;
12352
                delete object[property];
12353
                object[property] = descriptor.value;
12354
                object.__proto__ = prototype;
12355
            } else {
12356
                object[property] = descriptor.value;
12357
            }
12358
        } else {
12359
            if (!supportsAccessors)
12360
                throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
12361
            if (owns(descriptor, "get"))
12362
                defineGetter(object, property, descriptor.get);
12363
            if (owns(descriptor, "set"))
12364
                defineSetter(object, property, descriptor.set);
12365
        }
12366

    
12367
        return object;
12368
    };
12369
}
12370
if (!Object.defineProperties) {
12371
    Object.defineProperties = function defineProperties(object, properties) {
12372
        for (var property in properties) {
12373
            if (owns(properties, property))
12374
                Object.defineProperty(object, property, properties[property]);
12375
        }
12376
        return object;
12377
    };
12378
}
12379
if (!Object.seal) {
12380
    Object.seal = function seal(object) {
12381
        return object;
12382
    };
12383
}
12384
if (!Object.freeze) {
12385
    Object.freeze = function freeze(object) {
12386
        return object;
12387
    };
12388
}
12389
try {
12390
    Object.freeze(function () {});
12391
} catch (exception) {
12392
    Object.freeze = (function freeze(freezeObject) {
12393
        return function freeze(object) {
12394
            if (typeof object == "function") {
12395
                return object;
12396
            } else {
12397
                return freezeObject(object);
12398
            }
12399
        };
12400
    })(Object.freeze);
12401
}
12402
if (!Object.preventExtensions) {
12403
    Object.preventExtensions = function preventExtensions(object) {
12404
        return object;
12405
    };
12406
}
12407
if (!Object.isSealed) {
12408
    Object.isSealed = function isSealed(object) {
12409
        return false;
12410
    };
12411
}
12412
if (!Object.isFrozen) {
12413
    Object.isFrozen = function isFrozen(object) {
12414
        return false;
12415
    };
12416
}
12417
if (!Object.isExtensible) {
12418
    Object.isExtensible = function isExtensible(object) {
12419
        if (Object(object) === object) {
12420
            throw new TypeError(); // TODO message
12421
        }
12422
        var name = '';
12423
        while (owns(object, name)) {
12424
            name += '?';
12425
        }
12426
        object[name] = true;
12427
        var returnValue = owns(object, name);
12428
        delete object[name];
12429
        return returnValue;
12430
    };
12431
}
12432
if (!Object.keys) {
12433
    var hasDontEnumBug = true,
12434
        dontEnums = [
12435
            "toString",
12436
            "toLocaleString",
12437
            "valueOf",
12438
            "hasOwnProperty",
12439
            "isPrototypeOf",
12440
            "propertyIsEnumerable",
12441
            "constructor"
12442
        ],
12443
        dontEnumsLength = dontEnums.length;
12444

    
12445
    for (var key in {"toString": null}) {
12446
        hasDontEnumBug = false;
12447
    }
12448

    
12449
    Object.keys = function keys(object) {
12450

    
12451
        if (
12452
            (typeof object != "object" && typeof object != "function") ||
12453
            object === null
12454
        ) {
12455
            throw new TypeError("Object.keys called on a non-object");
12456
        }
12457

    
12458
        var keys = [];
12459
        for (var name in object) {
12460
            if (owns(object, name)) {
12461
                keys.push(name);
12462
            }
12463
        }
12464

    
12465
        if (hasDontEnumBug) {
12466
            for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
12467
                var dontEnum = dontEnums[i];
12468
                if (owns(object, dontEnum)) {
12469
                    keys.push(dontEnum);
12470
                }
12471
            }
12472
        }
12473
        return keys;
12474
    };
12475

    
12476
}
12477
if (!Date.now) {
12478
    Date.now = function now() {
12479
        return new Date().getTime();
12480
    };
12481
}
12482
var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003" +
12483
    "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
12484
    "\u2029\uFEFF";
12485
if (!String.prototype.trim) {
12486
    ws = "[" + ws + "]";
12487
    var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
12488
        trimEndRegexp = new RegExp(ws + ws + "*$");
12489
    String.prototype.trim = function trim() {
12490
        return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
12491
    };
12492
}
12493

    
12494
function toInteger(n) {
12495
    n = +n;
12496
    if (n !== n) { // isNaN
12497
        n = 0;
12498
    } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) {
12499
        n = (n > 0 || -1) * Math.floor(Math.abs(n));
12500
    }
12501
    return n;
12502
}
12503

    
12504
function isPrimitive(input) {
12505
    var type = typeof input;
12506
    return (
12507
        input === null ||
12508
        type === "undefined" ||
12509
        type === "boolean" ||
12510
        type === "number" ||
12511
        type === "string"
12512
    );
12513
}
12514

    
12515
function toPrimitive(input) {
12516
    var val, valueOf, toString;
12517
    if (isPrimitive(input)) {
12518
        return input;
12519
    }
12520
    valueOf = input.valueOf;
12521
    if (typeof valueOf === "function") {
12522
        val = valueOf.call(input);
12523
        if (isPrimitive(val)) {
12524
            return val;
12525
        }
12526
    }
12527
    toString = input.toString;
12528
    if (typeof toString === "function") {
12529
        val = toString.call(input);
12530
        if (isPrimitive(val)) {
12531
            return val;
12532
        }
12533
    }
12534
    throw new TypeError();
12535
}
12536
var toObject = function (o) {
12537
    if (o == null) { // this matches both null and undefined
12538
        throw new TypeError("can't convert "+o+" to object");
12539
    }
12540
    return Object(o);
12541
};
12542

    
12543
});
(239-239/244)